mirror of
https://github.com/A-Minos/nonebot-plugin-tetris-stats.git
synced 2026-03-05 05:36:54 +08:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 026ceaec6c | |||
|
|
e80e1bcda3 | ||
|
|
72e9a2fd87 | ||
|
|
f0b1a1c4f5 | ||
| 0bc3b86820 | |||
|
|
57d0b15242 | ||
|
|
56fe45efcf | ||
| 13f005179f |
@@ -7,7 +7,7 @@ ci:
|
|||||||
autoupdate_commit_msg: ':arrow_up: auto update by pre-commit hooks'
|
autoupdate_commit_msg: ':arrow_up: auto update by pre-commit hooks'
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.11.6
|
rev: v0.11.11
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
args: [--fix, --exit-non-zero-on-fix]
|
args: [--fix, --exit-non-zero-on-fix]
|
||||||
|
|||||||
@@ -6,10 +6,8 @@ require_plugins = {
|
|||||||
'nonebot_plugin_apscheduler',
|
'nonebot_plugin_apscheduler',
|
||||||
'nonebot_plugin_localstore',
|
'nonebot_plugin_localstore',
|
||||||
'nonebot_plugin_orm',
|
'nonebot_plugin_orm',
|
||||||
'nonebot_plugin_session_orm',
|
'nonebot_plugin_uninfo',
|
||||||
'nonebot_plugin_session',
|
|
||||||
'nonebot_plugin_user',
|
'nonebot_plugin_user',
|
||||||
'nonebot_plugin_userinfo',
|
|
||||||
'nonebot_plugin_waiter',
|
'nonebot_plugin_waiter',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from nonebot import get_plugin_config
|
from nonebot import get_driver, get_plugin_config
|
||||||
from nonebot_plugin_localstore import get_plugin_cache_dir, get_plugin_data_dir
|
from nonebot_plugin_localstore import get_plugin_cache_dir, get_plugin_data_dir
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
@@ -26,3 +26,4 @@ class Config(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
config = get_plugin_config(Config)
|
config = get_plugin_config(Config)
|
||||||
|
global_config = get_driver().config
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
"""Create a new table
|
||||||
|
|
||||||
|
迁移 ID: 612d8b00d9ac
|
||||||
|
父迁移: 5a1b93948494
|
||||||
|
创建时间: 2025-05-26 04:49:29.664480
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from collections.abc import Sequence
|
||||||
|
|
||||||
|
revision: str = '612d8b00d9ac'
|
||||||
|
down_revision: str | Sequence[str] | None = '5a1b93948494'
|
||||||
|
branch_labels: str | Sequence[str] | None = None
|
||||||
|
depends_on: str | Sequence[str] | None = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(name: str = '') -> None:
|
||||||
|
if name:
|
||||||
|
return
|
||||||
|
op.create_table(
|
||||||
|
'nonebot_plugin_tetris_stats_triggerhistoricaldatav2',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('trigger_time', sa.DateTime(), nullable=False),
|
||||||
|
sa.Column('session_persist_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('game_platform', sa.String(length=32), nullable=False),
|
||||||
|
sa.Column('command_type', sa.String(length=16), nullable=False),
|
||||||
|
sa.Column('command_args', sa.JSON(), nullable=False),
|
||||||
|
sa.Column('finish_time', sa.DateTime(), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint('id', name=op.f('pk_nonebot_plugin_tetris_stats_triggerhistoricaldatav2')),
|
||||||
|
info={'bind_key': 'nonebot_plugin_tetris_stats'},
|
||||||
|
)
|
||||||
|
with op.batch_alter_table('nonebot_plugin_tetris_stats_triggerhistoricaldatav2', schema=None) as batch_op:
|
||||||
|
batch_op.create_index(
|
||||||
|
batch_op.f('ix_nonebot_plugin_tetris_stats_triggerhistoricaldatav2_command_type'),
|
||||||
|
['command_type'],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
batch_op.create_index(
|
||||||
|
batch_op.f('ix_nonebot_plugin_tetris_stats_triggerhistoricaldatav2_game_platform'),
|
||||||
|
['game_platform'],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade(name: str = '') -> None:
|
||||||
|
if name:
|
||||||
|
return
|
||||||
|
with op.batch_alter_table('nonebot_plugin_tetris_stats_triggerhistoricaldatav2', schema=None) as batch_op:
|
||||||
|
batch_op.drop_index(batch_op.f('ix_nonebot_plugin_tetris_stats_triggerhistoricaldatav2_game_platform'))
|
||||||
|
batch_op.drop_index(batch_op.f('ix_nonebot_plugin_tetris_stats_triggerhistoricaldatav2_command_type'))
|
||||||
|
|
||||||
|
op.drop_table('nonebot_plugin_tetris_stats_triggerhistoricaldatav2')
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
"""Migrate to uninfo
|
||||||
|
|
||||||
|
迁移 ID: 766cc7e75a62
|
||||||
|
父迁移: 612d8b00d9ac
|
||||||
|
创建时间: 2025-05-26 04:51:54.665200
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import math
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
from nonebot.log import logger
|
||||||
|
from rich.progress import BarColumn, Progress, SpinnerColumn, TaskProgressColumn, TextColumn
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
from sqlalchemy.ext.automap import automap_base
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from collections.abc import Sequence
|
||||||
|
|
||||||
|
revision: str = '766cc7e75a62'
|
||||||
|
down_revision: str | Sequence[str] | None = '612d8b00d9ac'
|
||||||
|
branch_labels: str | Sequence[str] | None = None
|
||||||
|
depends_on: str | Sequence[str] | None = None
|
||||||
|
|
||||||
|
|
||||||
|
def data_migrate() -> None:
|
||||||
|
conn = op.get_bind()
|
||||||
|
insp = inspect(conn)
|
||||||
|
table_names = insp.get_table_names()
|
||||||
|
if 'nonebot_plugin_tetris_stats_triggerhistoricaldata' not in table_names:
|
||||||
|
return
|
||||||
|
|
||||||
|
Base = automap_base() # noqa: N806
|
||||||
|
Base.prepare(autoload_with=conn)
|
||||||
|
TriggerHistoricalData = Base.classes.nonebot_plugin_tetris_stats_triggerhistoricaldata # noqa: N806
|
||||||
|
TriggerHistoricalDataV2 = Base.classes.nonebot_plugin_tetris_stats_triggerhistoricaldatav2 # noqa: N806
|
||||||
|
|
||||||
|
with Session(conn) as db_session:
|
||||||
|
count = db_session.query(TriggerHistoricalData).count()
|
||||||
|
if count == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
from nonebot_session_to_uninfo import check_tables, get_id_map # type: ignore[import-untyped]
|
||||||
|
except ImportError as err:
|
||||||
|
msg = '请安装 `nonebot-session-to-uninfo` 以迁移数据'
|
||||||
|
raise ValueError(msg) from err
|
||||||
|
|
||||||
|
check_tables()
|
||||||
|
|
||||||
|
migration_limit = 10000 # 每次迁移的数据量为 10000 条
|
||||||
|
last_id = -1
|
||||||
|
id_map: dict[int, int] = {}
|
||||||
|
|
||||||
|
logger.warning('tetris_stats: 正在迁移数据, 请不要关闭程序...')
|
||||||
|
|
||||||
|
with Progress(
|
||||||
|
SpinnerColumn(),
|
||||||
|
TextColumn('[progress.description]{task.description}'),
|
||||||
|
BarColumn(),
|
||||||
|
TaskProgressColumn(),
|
||||||
|
) as progress:
|
||||||
|
task = progress.add_task('迁移数据...', total=count)
|
||||||
|
|
||||||
|
for _ in range(math.ceil(count / migration_limit)):
|
||||||
|
records = (
|
||||||
|
db_session.query(TriggerHistoricalData)
|
||||||
|
.order_by(TriggerHistoricalData.id)
|
||||||
|
.where(TriggerHistoricalData.id > last_id)
|
||||||
|
.limit(migration_limit)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
last_id = records[-1].id
|
||||||
|
|
||||||
|
session_ids = [
|
||||||
|
record.session_persist_id for record in records if record.session_persist_id not in id_map
|
||||||
|
]
|
||||||
|
if session_ids:
|
||||||
|
id_map.update(get_id_map(session_ids))
|
||||||
|
|
||||||
|
db_session.add_all(
|
||||||
|
TriggerHistoricalDataV2(
|
||||||
|
id=record.id,
|
||||||
|
session_persist_id=id_map[record.session_persist_id],
|
||||||
|
trigger_time=record.trigger_time,
|
||||||
|
game_platform=record.game_platform,
|
||||||
|
command_type=record.command_type,
|
||||||
|
command_args=record.command_args,
|
||||||
|
finish_time=record.finish_time,
|
||||||
|
)
|
||||||
|
for record in records
|
||||||
|
)
|
||||||
|
|
||||||
|
progress.update(task, advance=len(records))
|
||||||
|
|
||||||
|
db_session.commit()
|
||||||
|
|
||||||
|
logger.success('tetris_stats: 数据迁移完成!')
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(name: str = '') -> None:
|
||||||
|
if name:
|
||||||
|
return
|
||||||
|
data_migrate()
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade(name: str = '') -> None:
|
||||||
|
if name:
|
||||||
|
return
|
||||||
@@ -12,7 +12,7 @@ from nonebot_plugin_user import User
|
|||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
|
|
||||||
from ..utils.typedefs import AllCommandType, BaseCommandType, GameType, TETRIOCommandType
|
from ..utils.typedefs import AllCommandType, BaseCommandType, GameType, TETRIOCommandType
|
||||||
from .models import Bind, TriggerHistoricalData
|
from .models import Bind, TriggerHistoricalDataV2
|
||||||
|
|
||||||
UTC = timezone.utc
|
UTC = timezone.utc
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ async def trigger(
|
|||||||
except FinishedException:
|
except FinishedException:
|
||||||
async with get_session() as session:
|
async with get_session() as session:
|
||||||
session.add(
|
session.add(
|
||||||
TriggerHistoricalData(
|
TriggerHistoricalDataV2(
|
||||||
trigger_time=trigger_time,
|
trigger_time=trigger_time,
|
||||||
session_persist_id=session_persist_id,
|
session_persist_id=session_persist_id,
|
||||||
game_platform=game_platform,
|
game_platform=game_platform,
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class Bind(MappedAsDataclass, Model):
|
|||||||
game_account: Mapped[str]
|
game_account: Mapped[str]
|
||||||
|
|
||||||
|
|
||||||
class TriggerHistoricalData(MappedAsDataclass, Model):
|
class TriggerHistoricalDataV2(MappedAsDataclass, Model):
|
||||||
id: Mapped[int] = mapped_column(init=False, primary_key=True)
|
id: Mapped[int] = mapped_column(init=False, primary_key=True)
|
||||||
trigger_time: Mapped[datetime] = mapped_column(DateTime)
|
trigger_time: Mapped[datetime] = mapped_column(DateTime)
|
||||||
session_persist_id: Mapped[int]
|
session_persist_id: Mapped[int]
|
||||||
|
|||||||
@@ -1,25 +1,93 @@
|
|||||||
from typing import TypeAlias
|
from datetime import datetime
|
||||||
|
from enum import IntEnum
|
||||||
|
from typing import Literal, TypeAlias
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
from ..base import FailedModel, SuccessModel
|
from ..base import FailedModel, SuccessModel
|
||||||
|
|
||||||
|
|
||||||
|
class RankType(IntEnum):
|
||||||
|
PERCENTILE = 1
|
||||||
|
ISSUE = 2
|
||||||
|
ZENITH = 3
|
||||||
|
PERCENTILELAX = 4
|
||||||
|
PERCENTILEVLAX = 5
|
||||||
|
PERCENTILEMLAX = 6
|
||||||
|
|
||||||
|
|
||||||
|
class ValueType(IntEnum):
|
||||||
|
NONE = 0
|
||||||
|
NUMBER = 1
|
||||||
|
TIME = 2
|
||||||
|
TIME_INV = 3
|
||||||
|
FLOOR = 4
|
||||||
|
ISSUE = 5
|
||||||
|
NUMBER_INV = 6
|
||||||
|
|
||||||
|
|
||||||
|
class ArType(IntEnum):
|
||||||
|
UNRANKED = 0
|
||||||
|
RANKED = 1
|
||||||
|
COMPETITIVE = 2
|
||||||
|
|
||||||
|
|
||||||
|
class Rank(IntEnum):
|
||||||
|
NONE = 0
|
||||||
|
BRONZE = 1
|
||||||
|
SILVER = 2
|
||||||
|
GOLD = 3
|
||||||
|
PLATINUM = 4
|
||||||
|
DIAMOND = 5
|
||||||
|
ISSUED = 100
|
||||||
|
|
||||||
|
|
||||||
|
class Ally(BaseModel):
|
||||||
|
id: str = Field(alias='_id')
|
||||||
|
username: str
|
||||||
|
role: Literal['anon', 'user', 'bot', 'halfmod', 'mod', 'admin', 'sysop', 'hidden', 'banned']
|
||||||
|
country: str | None = None
|
||||||
|
supporter: bool
|
||||||
|
avatar_revision: int | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class X(BaseModel):
|
||||||
|
ally: Ally | None = None
|
||||||
|
|
||||||
|
|
||||||
class Achievement(BaseModel):
|
class Achievement(BaseModel):
|
||||||
# 这**都是些啥
|
# 这**都是些啥
|
||||||
k: int
|
achievement_id: int = Field(alias='k')
|
||||||
o: int
|
category: str
|
||||||
rt: int
|
primary_name: str = Field(alias='name')
|
||||||
vt: int
|
objective: str = Field(alias='object')
|
||||||
|
flavor_text: str = Field(alias='desc')
|
||||||
|
order: int = Field(alias='o')
|
||||||
|
rank_type: RankType = Field(alias='rt')
|
||||||
|
value_type: ValueType = Field(alias='vt')
|
||||||
|
ar_type: ArType = Field(alias='art')
|
||||||
min: int
|
min: int
|
||||||
deci: int
|
deci: int
|
||||||
name: str
|
|
||||||
object: str
|
|
||||||
category: str
|
|
||||||
hidden: bool
|
hidden: bool
|
||||||
desc: str
|
nolb: bool
|
||||||
|
event: str | None = None
|
||||||
|
event_past: bool | None = None
|
||||||
|
disabled: bool | None = None
|
||||||
|
pair: bool | None = None
|
||||||
|
achieved_score: float | None = Field(None, alias='v')
|
||||||
|
a: float | None = None
|
||||||
|
t: datetime | None = None
|
||||||
|
pos: int | None = None
|
||||||
|
total: int | None = None
|
||||||
|
rank: Rank | None = None
|
||||||
|
x: X | None = None
|
||||||
n: str
|
n: str
|
||||||
stub: bool
|
|
||||||
|
tiebreak: int
|
||||||
|
notifypb: bool
|
||||||
|
id: str | None = Field(None, alias='_id')
|
||||||
|
progress: float | None = None
|
||||||
|
stub: bool | None = None
|
||||||
|
|
||||||
|
|
||||||
class AchievementsSuccessModel(SuccessModel):
|
class AchievementsSuccessModel(SuccessModel):
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
|
from secrets import choice
|
||||||
|
|
||||||
from arclet.alconna import Arg, ArgFlag
|
from arclet.alconna import Arg, ArgFlag
|
||||||
from nonebot_plugin_alconna import Args, Subcommand
|
from nonebot_plugin_alconna import Args, Subcommand
|
||||||
from nonebot_plugin_alconna.uniseg import UniMessage
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
from nonebot_plugin_orm import get_session
|
from nonebot_plugin_orm import get_session
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_uninfo import QryItrface, Uninfo
|
||||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
from nonebot_plugin_uninfo import User as UninfoUser
|
||||||
|
from nonebot_plugin_uninfo.orm import get_session_persist_id
|
||||||
from nonebot_plugin_user import User
|
from nonebot_plugin_user import User
|
||||||
from nonebot_plugin_userinfo import BotUserInfo, UserInfo
|
|
||||||
from yarl import URL
|
from yarl import URL
|
||||||
|
|
||||||
|
from ...config.config import global_config
|
||||||
from ...db import BindStatus, create_or_update_bind, trigger
|
from ...db import BindStatus, create_or_update_bind, trigger
|
||||||
from ...utils.host import HostPage, get_self_netloc
|
from ...utils.host import HostPage, get_self_netloc
|
||||||
from ...utils.image import get_avatar
|
from ...utils.image import get_avatar
|
||||||
@@ -44,7 +46,7 @@ alc.shortcut(
|
|||||||
|
|
||||||
|
|
||||||
@alc.assign('TETRIO.bind')
|
@alc.assign('TETRIO.bind')
|
||||||
async def _(nb_user: User, account: Player, event_session: EventSession, bot_info: UserInfo = BotUserInfo()): # noqa: B008
|
async def _(nb_user: User, account: Player, event_session: Uninfo, interface: QryItrface):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
@@ -77,8 +79,15 @@ async def _(nb_user: User, account: Player, event_session: EventSession, bot_inf
|
|||||||
name=user.name.upper(),
|
name=user.name.upper(),
|
||||||
),
|
),
|
||||||
bot=People(
|
bot=People(
|
||||||
avatar=await get_avatar(bot_info, 'Data URI', '../../static/logo/logo.svg'),
|
avatar=await get_avatar(
|
||||||
name=bot_info.user_name,
|
(
|
||||||
|
bot_user := await interface.get_user(event_session.self_id)
|
||||||
|
or UninfoUser(id=event_session.self_id)
|
||||||
|
),
|
||||||
|
'Data URI',
|
||||||
|
'../../static/logo/logo.svg',
|
||||||
|
),
|
||||||
|
name=bot_user.nick or bot_user.name or choice(list(global_config.nickname) or ['bot']),
|
||||||
),
|
),
|
||||||
prompt='io查我',
|
prompt='io查我',
|
||||||
lang=get_lang(),
|
lang=get_lang(),
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ from arclet.alconna import Arg
|
|||||||
from nonebot_plugin_alconna import Option, Subcommand
|
from nonebot_plugin_alconna import Option, Subcommand
|
||||||
from nonebot_plugin_alconna.uniseg import UniMessage
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
from nonebot_plugin_orm import async_scoped_session
|
from nonebot_plugin_orm import async_scoped_session
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_uninfo import Uninfo
|
||||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
from nonebot_plugin_uninfo.orm import get_session_persist_id
|
||||||
from nonebot_plugin_user import User
|
from nonebot_plugin_user import User
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ alc.shortcut(
|
|||||||
|
|
||||||
|
|
||||||
@alc.assign('TETRIO.config')
|
@alc.assign('TETRIO.config')
|
||||||
async def _(user: User, session: async_scoped_session, event_session: EventSession, template: Template):
|
async def _(user: User, session: async_scoped_session, event_session: Uninfo, template: Template):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from nonebot_plugin_alconna import Args, Option, Subcommand
|
from nonebot_plugin_alconna import Args, Option, Subcommand
|
||||||
from nonebot_plugin_alconna.uniseg import UniMessage
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_uninfo import Uninfo
|
||||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
from nonebot_plugin_uninfo.orm import get_session_persist_id
|
||||||
|
|
||||||
from ...db import trigger
|
from ...db import trigger
|
||||||
from ...utils.host import HostPage, get_self_netloc
|
from ...utils.host import HostPage, get_self_netloc
|
||||||
@@ -32,7 +32,7 @@ command.add(
|
|||||||
|
|
||||||
@alc.assign('TETRIO.list')
|
@alc.assign('TETRIO.list')
|
||||||
async def _(
|
async def _(
|
||||||
event_session: EventSession,
|
event_session: Uninfo,
|
||||||
max_tr: float | None = None,
|
max_tr: float | None = None,
|
||||||
min_tr: float | None = None,
|
min_tr: float | None = None,
|
||||||
limit: int | None = None,
|
limit: int | None = None,
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ from nonebot.matcher import Matcher
|
|||||||
from nonebot_plugin_alconna import Args, At, Option, Subcommand
|
from nonebot_plugin_alconna import Args, At, Option, Subcommand
|
||||||
from nonebot_plugin_alconna.uniseg import UniMessage
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
from nonebot_plugin_orm import get_session
|
from nonebot_plugin_orm import get_session
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_uninfo import Uninfo
|
||||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
from nonebot_plugin_uninfo.orm import get_session_persist_id
|
||||||
from nonebot_plugin_user import User as NBUser
|
from nonebot_plugin_user import User as NBUser
|
||||||
from nonebot_plugin_user import get_user
|
from nonebot_plugin_user import get_user
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
@@ -90,7 +90,7 @@ async def _( # noqa: PLR0913
|
|||||||
event: Event,
|
event: Event,
|
||||||
matcher: Matcher,
|
matcher: Matcher,
|
||||||
target: At | Me,
|
target: At | Me,
|
||||||
event_session: EventSession,
|
event_session: Uninfo,
|
||||||
template: Template | None = None,
|
template: Template | None = None,
|
||||||
):
|
):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
@@ -103,7 +103,7 @@ async def _( # noqa: PLR0913
|
|||||||
bind = await query_bind_info(
|
bind = await query_bind_info(
|
||||||
session=session,
|
session=session,
|
||||||
user=await get_user(
|
user=await get_user(
|
||||||
event_session.platform, target.target if isinstance(target, At) else event.get_user_id()
|
event_session.scope, target.target if isinstance(target, At) else event.get_user_id()
|
||||||
),
|
),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
)
|
)
|
||||||
@@ -120,7 +120,7 @@ async def _( # noqa: PLR0913
|
|||||||
|
|
||||||
|
|
||||||
@alc.assign('TETRIO.query')
|
@alc.assign('TETRIO.query')
|
||||||
async def _(user: NBUser, account: Player, event_session: EventSession, template: Template | None = None):
|
async def _(user: NBUser, account: Player, event_session: Uninfo, template: Template | None = None):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from ....utils.metrics import get_metrics
|
|||||||
from ....utils.render import render
|
from ....utils.render import render
|
||||||
from ....utils.render.schemas.base import Avatar
|
from ....utils.render.schemas.base import Avatar
|
||||||
from ....utils.render.schemas.v2.tetrio.user.info import (
|
from ....utils.render.schemas.v2.tetrio.user.info import (
|
||||||
|
Achievement,
|
||||||
Badge,
|
Badge,
|
||||||
Best,
|
Best,
|
||||||
Blitz,
|
Blitz,
|
||||||
@@ -33,7 +34,7 @@ from .tools import flow_to_history, handling_special_value
|
|||||||
async def make_query_image_v2(player: Player) -> bytes:
|
async def make_query_image_v2(player: Player) -> bytes:
|
||||||
(
|
(
|
||||||
(user, user_info, league, sprint, blitz, zen),
|
(user, user_info, league, sprint, blitz, zen),
|
||||||
(avatar_revision, banner_revision, leagueflow, zenith, zenithex),
|
(avatar_revision, banner_revision, leagueflow, zenith, zenithex, achievements),
|
||||||
) = await gather(
|
) = await gather(
|
||||||
gather(
|
gather(
|
||||||
player.user,
|
player.user,
|
||||||
@@ -49,6 +50,7 @@ async def make_query_image_v2(player: Player) -> bytes:
|
|||||||
player.get_leagueflow(),
|
player.get_leagueflow(),
|
||||||
player.get_summaries('zenith'),
|
player.get_summaries('zenith'),
|
||||||
player.get_summaries('zenithex'),
|
player.get_summaries('zenithex'),
|
||||||
|
player.get_summaries('achievements'),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
if sprint.data.record is not None:
|
if sprint.data.record is not None:
|
||||||
@@ -110,7 +112,20 @@ async def make_query_image_v2(player: Player) -> bytes:
|
|||||||
],
|
],
|
||||||
xp=user_info.data.xp,
|
xp=user_info.data.xp,
|
||||||
ar=user_info.data.ar,
|
ar=user_info.data.ar,
|
||||||
achievements=user_info.data.achievements,
|
achievements=[
|
||||||
|
Achievement(
|
||||||
|
key=i.achievement_id,
|
||||||
|
rank_type=i.rank_type,
|
||||||
|
ar_type=i.ar_type,
|
||||||
|
stub=i.stub,
|
||||||
|
rank=i.rank,
|
||||||
|
achieved_score=i.achieved_score,
|
||||||
|
pos=i.pos,
|
||||||
|
progress=i.progress,
|
||||||
|
total=i.total,
|
||||||
|
)
|
||||||
|
for i in achievements.data
|
||||||
|
],
|
||||||
playtime=play_time,
|
playtime=play_time,
|
||||||
join_at=user_info.data.ts,
|
join_at=user_info.data.ts,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ from datetime import timedelta
|
|||||||
from arclet.alconna import Arg
|
from arclet.alconna import Arg
|
||||||
from nonebot_plugin_alconna import Option, Subcommand, UniMessage
|
from nonebot_plugin_alconna import Option, Subcommand, UniMessage
|
||||||
from nonebot_plugin_orm import get_session
|
from nonebot_plugin_orm import get_session
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_uninfo import Uninfo
|
||||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
from nonebot_plugin_uninfo.orm import get_session_persist_id
|
||||||
from sqlalchemy import func, select
|
from sqlalchemy import func, select
|
||||||
from sqlalchemy.orm import selectinload
|
from sqlalchemy.orm import selectinload
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ command.add(
|
|||||||
|
|
||||||
|
|
||||||
@alc.assign('TETRIO.rank.all')
|
@alc.assign('TETRIO.rank.all')
|
||||||
async def _(event_session: EventSession, template: Template | None = None):
|
async def _(event_session: Uninfo, template: Template | None = None):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ from arclet.alconna import Arg
|
|||||||
from nonebot import get_driver
|
from nonebot import get_driver
|
||||||
from nonebot_plugin_alconna import Option, UniMessage
|
from nonebot_plugin_alconna import Option, UniMessage
|
||||||
from nonebot_plugin_orm import get_session
|
from nonebot_plugin_orm import get_session
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_uninfo import Uninfo
|
||||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
from nonebot_plugin_uninfo.orm import get_session_persist_id
|
||||||
from sqlalchemy import func, select
|
from sqlalchemy import func, select
|
||||||
from sqlalchemy.orm import selectinload
|
from sqlalchemy.orm import selectinload
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ command.add(Option('--detail', Arg('rank', ValidRank), alias=['-D']))
|
|||||||
|
|
||||||
|
|
||||||
@alc.assign('TETRIO.rank')
|
@alc.assign('TETRIO.rank')
|
||||||
async def _(rank: ValidRank, event_session: EventSession):
|
async def _(rank: ValidRank, event_session: Uninfo):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ from nonebot.matcher import Matcher
|
|||||||
from nonebot_plugin_alconna import At, Option
|
from nonebot_plugin_alconna import At, Option
|
||||||
from nonebot_plugin_alconna.uniseg import UniMessage
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
from nonebot_plugin_orm import get_session
|
from nonebot_plugin_orm import get_session
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_uninfo import Uninfo
|
||||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
from nonebot_plugin_uninfo.orm import get_session_persist_id
|
||||||
from nonebot_plugin_user import get_user
|
from nonebot_plugin_user import get_user
|
||||||
from yarl import URL
|
from yarl import URL
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ async def _(
|
|||||||
event: Event,
|
event: Event,
|
||||||
matcher: Matcher,
|
matcher: Matcher,
|
||||||
target: At | Me,
|
target: At | Me,
|
||||||
event_session: EventSession,
|
event_session: Uninfo,
|
||||||
):
|
):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
@@ -55,7 +55,7 @@ async def _(
|
|||||||
bind = await query_bind_info(
|
bind = await query_bind_info(
|
||||||
session=session,
|
session=session,
|
||||||
user=await get_user(
|
user=await get_user(
|
||||||
event_session.platform, target.target if isinstance(target, At) else event.get_user_id()
|
event_session.scope, target.target if isinstance(target, At) else event.get_user_id()
|
||||||
),
|
),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
)
|
)
|
||||||
@@ -68,7 +68,7 @@ async def _(
|
|||||||
|
|
||||||
|
|
||||||
@alc.assign('TETRIO.record.blitz')
|
@alc.assign('TETRIO.record.blitz')
|
||||||
async def _(account: Player, event_session: EventSession):
|
async def _(account: Player, event_session: Uninfo):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ from nonebot.matcher import Matcher
|
|||||||
from nonebot_plugin_alconna import At, Option
|
from nonebot_plugin_alconna import At, Option
|
||||||
from nonebot_plugin_alconna.uniseg import UniMessage
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
from nonebot_plugin_orm import get_session
|
from nonebot_plugin_orm import get_session
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_uninfo import Uninfo
|
||||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
from nonebot_plugin_uninfo.orm import get_session_persist_id
|
||||||
from nonebot_plugin_user import get_user
|
from nonebot_plugin_user import get_user
|
||||||
from yarl import URL
|
from yarl import URL
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ async def _(
|
|||||||
event: Event,
|
event: Event,
|
||||||
matcher: Matcher,
|
matcher: Matcher,
|
||||||
target: At | Me,
|
target: At | Me,
|
||||||
event_session: EventSession,
|
event_session: Uninfo,
|
||||||
):
|
):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
@@ -55,7 +55,7 @@ async def _(
|
|||||||
bind = await query_bind_info(
|
bind = await query_bind_info(
|
||||||
session=session,
|
session=session,
|
||||||
user=await get_user(
|
user=await get_user(
|
||||||
event_session.platform, target.target if isinstance(target, At) else event.get_user_id()
|
event_session.scope, target.target if isinstance(target, At) else event.get_user_id()
|
||||||
),
|
),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
)
|
)
|
||||||
@@ -68,7 +68,7 @@ async def _(
|
|||||||
|
|
||||||
|
|
||||||
@alc.assign('TETRIO.record.sprint')
|
@alc.assign('TETRIO.record.sprint')
|
||||||
async def _(account: Player, event_session: EventSession):
|
async def _(account: Player, event_session: Uninfo):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
|
from secrets import choice
|
||||||
|
|
||||||
from nonebot_plugin_alconna import Subcommand
|
from nonebot_plugin_alconna import Subcommand
|
||||||
from nonebot_plugin_alconna.uniseg import UniMessage
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
from nonebot_plugin_orm import get_session
|
from nonebot_plugin_orm import get_session
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_uninfo import QryItrface, Uninfo
|
||||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
from nonebot_plugin_uninfo import User as UninfoUser
|
||||||
|
from nonebot_plugin_uninfo.orm import get_session_persist_id
|
||||||
from nonebot_plugin_user import User
|
from nonebot_plugin_user import User
|
||||||
from nonebot_plugin_userinfo import BotUserInfo, UserInfo
|
|
||||||
from nonebot_plugin_waiter import suggest # type: ignore[import-untyped]
|
from nonebot_plugin_waiter import suggest # type: ignore[import-untyped]
|
||||||
from yarl import URL
|
from yarl import URL
|
||||||
|
|
||||||
|
from ...config.config import global_config
|
||||||
from ...db import query_bind_info, remove_bind, trigger
|
from ...db import query_bind_info, remove_bind, trigger
|
||||||
from ...utils.host import HostPage, get_self_netloc
|
from ...utils.host import HostPage, get_self_netloc
|
||||||
from ...utils.image import get_avatar
|
from ...utils.image import get_avatar
|
||||||
@@ -31,7 +33,7 @@ alc.shortcut(
|
|||||||
|
|
||||||
|
|
||||||
@alc.assign('TETRIO.unbind')
|
@alc.assign('TETRIO.unbind')
|
||||||
async def _(nb_user: User, event_session: EventSession, bot_info: UserInfo = BotUserInfo()): # noqa: B008
|
async def _(nb_user: User, event_session: Uninfo, interface: QryItrface):
|
||||||
async with (
|
async with (
|
||||||
trigger(
|
trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
@@ -65,8 +67,15 @@ async def _(nb_user: User, event_session: EventSession, bot_info: UserInfo = Bot
|
|||||||
name=user.name.upper(),
|
name=user.name.upper(),
|
||||||
),
|
),
|
||||||
bot=People(
|
bot=People(
|
||||||
avatar=await get_avatar(bot_info, 'Data URI', '../../static/logo/logo.svg'),
|
avatar=await get_avatar(
|
||||||
name=bot_info.user_name,
|
(
|
||||||
|
bot_user := await interface.get_user(event_session.self_id)
|
||||||
|
or UninfoUser(id=event_session.self_id)
|
||||||
|
),
|
||||||
|
'Data URI',
|
||||||
|
'../../static/logo/logo.svg',
|
||||||
|
),
|
||||||
|
name=bot_user.nick or bot_user.name or choice(list(global_config.nickname) or ['bot']),
|
||||||
),
|
),
|
||||||
prompt='io绑定{游戏ID}',
|
prompt='io绑定{游戏ID}',
|
||||||
lang=get_lang(),
|
lang=get_lang(),
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
|
from secrets import choice
|
||||||
|
|
||||||
from nonebot_plugin_alconna.uniseg import UniMessage
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
from nonebot_plugin_orm import get_session
|
from nonebot_plugin_orm import get_session
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_uninfo import QryItrface, Uninfo
|
||||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
from nonebot_plugin_uninfo import User as UninfoUser
|
||||||
|
from nonebot_plugin_uninfo.orm import get_session_persist_id
|
||||||
from nonebot_plugin_user import User
|
from nonebot_plugin_user import User
|
||||||
from nonebot_plugin_userinfo import BotUserInfo, EventUserInfo, UserInfo
|
|
||||||
|
|
||||||
|
from ...config.config import global_config
|
||||||
from ...db import BindStatus, create_or_update_bind, trigger
|
from ...db import BindStatus, create_or_update_bind, trigger
|
||||||
from ...utils.host import HostPage, get_self_netloc
|
from ...utils.host import HostPage, get_self_netloc
|
||||||
from ...utils.image import get_avatar
|
from ...utils.image import get_avatar
|
||||||
@@ -18,13 +21,7 @@ from .constant import GAME_TYPE
|
|||||||
|
|
||||||
|
|
||||||
@alc.assign('TOP.bind')
|
@alc.assign('TOP.bind')
|
||||||
async def _(
|
async def _(nb_user: User, account: Player, event_session: Uninfo, interface: QryItrface):
|
||||||
nb_user: User,
|
|
||||||
account: Player,
|
|
||||||
event_session: EventSession,
|
|
||||||
event_user_info: UserInfo = EventUserInfo(), # noqa: B008
|
|
||||||
bot_info: UserInfo = BotUserInfo(), # noqa: B008
|
|
||||||
):
|
|
||||||
async with trigger(
|
async with trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
@@ -47,12 +44,23 @@ async def _(
|
|||||||
platform=GAME_TYPE,
|
platform=GAME_TYPE,
|
||||||
type='unknown',
|
type='unknown',
|
||||||
user=People(
|
user=People(
|
||||||
avatar=await get_avatar(event_user_info, 'Data URI', None),
|
avatar=await get_avatar(
|
||||||
|
event_session.user,
|
||||||
|
'Data URI',
|
||||||
|
None,
|
||||||
|
),
|
||||||
name=user.user_name,
|
name=user.user_name,
|
||||||
),
|
),
|
||||||
bot=People(
|
bot=People(
|
||||||
avatar=await get_avatar(bot_info, 'Data URI', '../../static/logo/logo.svg'),
|
avatar=await get_avatar(
|
||||||
name=bot_info.user_name,
|
(
|
||||||
|
bot_user := await interface.get_user(event_session.self_id)
|
||||||
|
or UninfoUser(id=event_session.self_id)
|
||||||
|
),
|
||||||
|
'Data URI',
|
||||||
|
'../../static/logo/logo.svg',
|
||||||
|
),
|
||||||
|
name=bot_user.nick or bot_user.name or choice(list(global_config.nickname) or ['bot']),
|
||||||
),
|
),
|
||||||
prompt='top查我',
|
prompt='top查我',
|
||||||
lang=get_lang(),
|
lang=get_lang(),
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ from nonebot.matcher import Matcher
|
|||||||
from nonebot_plugin_alconna import At
|
from nonebot_plugin_alconna import At
|
||||||
from nonebot_plugin_alconna.uniseg import UniMessage
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
from nonebot_plugin_orm import get_session
|
from nonebot_plugin_orm import get_session
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_uninfo import Uninfo
|
||||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
from nonebot_plugin_uninfo.orm import get_session_persist_id
|
||||||
from nonebot_plugin_user import get_user
|
from nonebot_plugin_user import get_user
|
||||||
|
|
||||||
from ...db import query_bind_info, trigger
|
from ...db import query_bind_info, trigger
|
||||||
@@ -27,7 +27,7 @@ from .constant import GAME_TYPE
|
|||||||
|
|
||||||
|
|
||||||
@alc.assign('TOP.query')
|
@alc.assign('TOP.query')
|
||||||
async def _(event: Event, matcher: Matcher, target: At | Me, event_session: EventSession):
|
async def _(event: Event, matcher: Matcher, target: At | Me, event_session: Uninfo):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
@@ -38,7 +38,7 @@ async def _(event: Event, matcher: Matcher, target: At | Me, event_session: Even
|
|||||||
bind = await query_bind_info(
|
bind = await query_bind_info(
|
||||||
session=session,
|
session=session,
|
||||||
user=await get_user(
|
user=await get_user(
|
||||||
event_session.platform, target.target if isinstance(target, At) else event.get_user_id()
|
event_session.scope, target.target if isinstance(target, At) else event.get_user_id()
|
||||||
),
|
),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
)
|
)
|
||||||
@@ -51,7 +51,7 @@ async def _(event: Event, matcher: Matcher, target: At | Me, event_session: Even
|
|||||||
|
|
||||||
|
|
||||||
@alc.assign('TOP.query')
|
@alc.assign('TOP.query')
|
||||||
async def _(account: Player, event_session: EventSession):
|
async def _(account: Player, event_session: Uninfo):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
|
from secrets import choice
|
||||||
|
|
||||||
from nonebot_plugin_alconna.uniseg import UniMessage
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
from nonebot_plugin_orm import get_session
|
from nonebot_plugin_orm import get_session
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_uninfo import QryItrface, Uninfo
|
||||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
from nonebot_plugin_uninfo import User as UninfoUser
|
||||||
|
from nonebot_plugin_uninfo.orm import get_session_persist_id
|
||||||
from nonebot_plugin_user import User
|
from nonebot_plugin_user import User
|
||||||
from nonebot_plugin_userinfo import BotUserInfo, EventUserInfo, UserInfo
|
|
||||||
from nonebot_plugin_waiter import suggest # type: ignore[import-untyped]
|
from nonebot_plugin_waiter import suggest # type: ignore[import-untyped]
|
||||||
|
|
||||||
|
from ...config.config import global_config
|
||||||
from ...db import query_bind_info, remove_bind, trigger
|
from ...db import query_bind_info, remove_bind, trigger
|
||||||
from ...utils.host import HostPage, get_self_netloc
|
from ...utils.host import HostPage, get_self_netloc
|
||||||
from ...utils.image import get_avatar
|
from ...utils.image import get_avatar
|
||||||
@@ -21,9 +24,8 @@ from .constant import GAME_TYPE
|
|||||||
@alc.assign('TOP.unbind')
|
@alc.assign('TOP.unbind')
|
||||||
async def _(
|
async def _(
|
||||||
nb_user: User,
|
nb_user: User,
|
||||||
event_session: EventSession,
|
event_session: Uninfo,
|
||||||
event_user_info: UserInfo = EventUserInfo(), # noqa: B008
|
interface: QryItrface,
|
||||||
bot_info: UserInfo = BotUserInfo(), # noqa: B008
|
|
||||||
):
|
):
|
||||||
async with (
|
async with (
|
||||||
trigger(
|
trigger(
|
||||||
@@ -49,12 +51,23 @@ async def _(
|
|||||||
platform='TOP',
|
platform='TOP',
|
||||||
type='unlink',
|
type='unlink',
|
||||||
user=People(
|
user=People(
|
||||||
avatar=await get_avatar(event_user_info, 'Data URI', None),
|
avatar=await get_avatar(
|
||||||
|
event_session.user,
|
||||||
|
'Data URI',
|
||||||
|
None,
|
||||||
|
),
|
||||||
name=user.user_name,
|
name=user.user_name,
|
||||||
),
|
),
|
||||||
bot=People(
|
bot=People(
|
||||||
avatar=await get_avatar(bot_info, 'Data URI', '../../static/logo/logo.svg'),
|
avatar=await get_avatar(
|
||||||
name=bot_info.user_name,
|
(
|
||||||
|
bot_user := await interface.get_user(event_session.self_id)
|
||||||
|
or UninfoUser(id=event_session.self_id)
|
||||||
|
),
|
||||||
|
'Data URI',
|
||||||
|
'../../static/logo/logo.svg',
|
||||||
|
),
|
||||||
|
name=bot_user.nick or bot_user.name or choice(list(global_config.nickname) or ['bot']),
|
||||||
),
|
),
|
||||||
prompt='top绑定{游戏ID}',
|
prompt='top绑定{游戏ID}',
|
||||||
lang=get_lang(),
|
lang=get_lang(),
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
|
from secrets import choice
|
||||||
|
|
||||||
from nonebot_plugin_alconna.uniseg import UniMessage
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
from nonebot_plugin_orm import get_session
|
from nonebot_plugin_orm import get_session
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_uninfo import QryItrface, Uninfo
|
||||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
from nonebot_plugin_uninfo import User as UninfoUser
|
||||||
|
from nonebot_plugin_uninfo.orm import get_session_persist_id
|
||||||
from nonebot_plugin_user import User
|
from nonebot_plugin_user import User
|
||||||
from nonebot_plugin_userinfo import BotUserInfo, EventUserInfo, UserInfo
|
|
||||||
|
|
||||||
|
from ...config.config import global_config
|
||||||
from ...db import BindStatus, create_or_update_bind, trigger
|
from ...db import BindStatus, create_or_update_bind, trigger
|
||||||
from ...utils.host import HostPage, get_self_netloc
|
from ...utils.host import HostPage, get_self_netloc
|
||||||
from ...utils.image import get_avatar
|
from ...utils.image import get_avatar
|
||||||
@@ -21,9 +24,8 @@ from .constant import GAME_TYPE
|
|||||||
async def _(
|
async def _(
|
||||||
nb_user: User,
|
nb_user: User,
|
||||||
account: Player,
|
account: Player,
|
||||||
event_session: EventSession,
|
event_session: Uninfo,
|
||||||
event_user_info: UserInfo = EventUserInfo(), # noqa: B008
|
interface: QryItrface,
|
||||||
bot_info: UserInfo = BotUserInfo(), # noqa: B008
|
|
||||||
):
|
):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
@@ -48,11 +50,23 @@ async def _(
|
|||||||
platform=GAME_TYPE,
|
platform=GAME_TYPE,
|
||||||
type='unknown',
|
type='unknown',
|
||||||
user=People(
|
user=People(
|
||||||
avatar=await get_avatar(event_user_info, 'Data URI', None), name=user_info.data.name
|
avatar=await get_avatar(
|
||||||
|
event_session.user,
|
||||||
|
'Data URI',
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
name=user_info.data.name,
|
||||||
),
|
),
|
||||||
bot=People(
|
bot=People(
|
||||||
avatar=await get_avatar(bot_info, 'Data URI', '../../static/logo/logo.svg'),
|
avatar=await get_avatar(
|
||||||
name=bot_info.user_remark or bot_info.user_displayname or bot_info.user_name,
|
(
|
||||||
|
bot_user := await interface.get_user(event_session.self_id)
|
||||||
|
or UninfoUser(id=event_session.self_id)
|
||||||
|
),
|
||||||
|
'Data URI',
|
||||||
|
'../../static/logo/logo.svg',
|
||||||
|
),
|
||||||
|
name=bot_user.nick or bot_user.name or choice(list(global_config.nickname) or ['bot']),
|
||||||
),
|
),
|
||||||
prompt='茶服查我',
|
prompt='茶服查我',
|
||||||
lang=get_lang(),
|
lang=get_lang(),
|
||||||
|
|||||||
@@ -9,10 +9,9 @@ from nonebot.matcher import Matcher
|
|||||||
from nonebot_plugin_alconna import At
|
from nonebot_plugin_alconna import At
|
||||||
from nonebot_plugin_alconna.uniseg import UniMessage
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
from nonebot_plugin_orm import get_session
|
from nonebot_plugin_orm import get_session
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_uninfo import Uninfo, User
|
||||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
from nonebot_plugin_uninfo.orm import get_session_persist_id
|
||||||
from nonebot_plugin_user import get_user
|
from nonebot_plugin_user import get_user
|
||||||
from nonebot_plugin_userinfo import EventUserInfo, UserInfo
|
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
|
|
||||||
from ...db import query_bind_info, trigger
|
from ...db import query_bind_info, trigger
|
||||||
@@ -45,8 +44,7 @@ def add_special_handlers(
|
|||||||
async def _(
|
async def _(
|
||||||
event: Event,
|
event: Event,
|
||||||
target: At | Me,
|
target: At | Me,
|
||||||
event_session: EventSession,
|
event_session: Uninfo,
|
||||||
event_user_info: UserInfo = EventUserInfo(), # noqa: B008
|
|
||||||
):
|
):
|
||||||
if isinstance(event, match_event):
|
if isinstance(event, match_event):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
@@ -66,7 +64,9 @@ def add_special_handlers(
|
|||||||
if game_data is not None:
|
if game_data is not None:
|
||||||
await UniMessage.image(
|
await UniMessage.image(
|
||||||
raw=await make_query_image(
|
raw=await make_query_image(
|
||||||
user_info, game_data, None if isinstance(target, At) else event_user_info
|
user_info,
|
||||||
|
game_data,
|
||||||
|
None if isinstance(target, At) else event_session.user,
|
||||||
)
|
)
|
||||||
).finish()
|
).finish()
|
||||||
await make_query_text(user_info, game_data).finish()
|
await make_query_text(user_info, game_data).finish()
|
||||||
@@ -112,8 +112,7 @@ async def _(
|
|||||||
event: Event,
|
event: Event,
|
||||||
matcher: Matcher,
|
matcher: Matcher,
|
||||||
target: At | Me,
|
target: At | Me,
|
||||||
event_session: EventSession,
|
event_session: Uninfo,
|
||||||
event_user_info: UserInfo = EventUserInfo(), # noqa: B008
|
|
||||||
):
|
):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
@@ -125,7 +124,7 @@ async def _(
|
|||||||
bind = await query_bind_info(
|
bind = await query_bind_info(
|
||||||
session=session,
|
session=session,
|
||||||
user=await get_user(
|
user=await get_user(
|
||||||
event_session.platform, target.target if isinstance(target, At) else event.get_user_id()
|
event_session.scope, target.target if isinstance(target, At) else event.get_user_id()
|
||||||
),
|
),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
)
|
)
|
||||||
@@ -139,7 +138,9 @@ async def _(
|
|||||||
message
|
message
|
||||||
+ UniMessage.image(
|
+ UniMessage.image(
|
||||||
raw=await make_query_image(
|
raw=await make_query_image(
|
||||||
user_info, game_data, None if isinstance(target, At) else event_user_info
|
user_info,
|
||||||
|
game_data,
|
||||||
|
None if isinstance(target, At) else event_session.user,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
).finish()
|
).finish()
|
||||||
@@ -147,7 +148,7 @@ async def _(
|
|||||||
|
|
||||||
|
|
||||||
@alc.assign('TOS.query')
|
@alc.assign('TOS.query')
|
||||||
async def _(account: Player, event_session: EventSession):
|
async def _(account: Player, event_session: Uninfo):
|
||||||
async with trigger(
|
async with trigger(
|
||||||
session_persist_id=await get_session_persist_id(event_session),
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
game_platform=GAME_TYPE,
|
game_platform=GAME_TYPE,
|
||||||
@@ -250,7 +251,7 @@ async def get_historical_data(unique_identifier: str) -> list[HistoryData]:
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
async def make_query_image(user_info: UserInfoSuccess, game_data: GameData, event_user_info: UserInfo | None) -> bytes:
|
async def make_query_image(user_info: UserInfoSuccess, game_data: GameData, event_user_info: User | None) -> bytes:
|
||||||
metrics = game_data.metrics
|
metrics = game_data.metrics
|
||||||
sprint_value = (
|
sprint_value = (
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
|
from secrets import choice
|
||||||
|
|
||||||
from nonebot_plugin_alconna.uniseg import UniMessage
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
from nonebot_plugin_orm import get_session
|
from nonebot_plugin_orm import get_session
|
||||||
from nonebot_plugin_session import EventSession
|
from nonebot_plugin_uninfo import QryItrface, Uninfo
|
||||||
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
from nonebot_plugin_uninfo import User as UninfoUser
|
||||||
|
from nonebot_plugin_uninfo.orm import get_session_persist_id
|
||||||
from nonebot_plugin_user import User
|
from nonebot_plugin_user import User
|
||||||
from nonebot_plugin_userinfo import BotUserInfo, EventUserInfo, UserInfo
|
|
||||||
from nonebot_plugin_waiter import suggest # type: ignore[import-untyped]
|
from nonebot_plugin_waiter import suggest # type: ignore[import-untyped]
|
||||||
|
|
||||||
|
from ...config.config import global_config
|
||||||
from ...db import query_bind_info, remove_bind, trigger
|
from ...db import query_bind_info, remove_bind, trigger
|
||||||
from ...utils.host import HostPage, get_self_netloc
|
from ...utils.host import HostPage, get_self_netloc
|
||||||
from ...utils.image import get_avatar
|
from ...utils.image import get_avatar
|
||||||
from ...utils.lang import get_lang
|
from ...utils.lang import get_lang
|
||||||
from ...utils.render import Bind, render
|
from ...utils.render import Bind, render
|
||||||
from ...utils.render.avatar import get_avatar as get_random_avatar
|
|
||||||
from ...utils.render.schemas.base import People
|
from ...utils.render.schemas.base import People
|
||||||
from ...utils.screenshot import screenshot
|
from ...utils.screenshot import screenshot
|
||||||
from . import alc
|
from . import alc
|
||||||
@@ -22,9 +24,8 @@ from .constant import GAME_TYPE
|
|||||||
@alc.assign('TOP.unbind')
|
@alc.assign('TOP.unbind')
|
||||||
async def _(
|
async def _(
|
||||||
nb_user: User,
|
nb_user: User,
|
||||||
event_session: EventSession,
|
event_session: Uninfo,
|
||||||
event_user_info: UserInfo = EventUserInfo(), # noqa: B008
|
interface: QryItrface,
|
||||||
bot_info: UserInfo = BotUserInfo(), # noqa: B008
|
|
||||||
):
|
):
|
||||||
async with (
|
async with (
|
||||||
trigger(
|
trigger(
|
||||||
@@ -50,14 +51,19 @@ async def _(
|
|||||||
platform='TOS',
|
platform='TOS',
|
||||||
type='unlink',
|
type='unlink',
|
||||||
user=People(
|
user=People(
|
||||||
avatar=await get_avatar(event_user_info, 'Data URI', None)
|
avatar=await get_avatar(event_session.user, 'Data URI', None),
|
||||||
if event_user_info is not None
|
|
||||||
else get_random_avatar(user.teaid),
|
|
||||||
name=user.name,
|
name=user.name,
|
||||||
),
|
),
|
||||||
bot=People(
|
bot=People(
|
||||||
avatar=await get_avatar(bot_info, 'Data URI', '../../static/logo/logo.svg'),
|
avatar=await get_avatar(
|
||||||
name=bot_info.user_name,
|
(
|
||||||
|
bot_user := await interface.get_user(event_session.self_id)
|
||||||
|
or UninfoUser(id=event_session.self_id)
|
||||||
|
),
|
||||||
|
'Data URI',
|
||||||
|
'../../static/logo/logo.svg',
|
||||||
|
),
|
||||||
|
name=bot_user.nick or bot_user.name or choice(list(global_config.nickname) or ['bot']),
|
||||||
),
|
),
|
||||||
prompt='茶服绑定{游戏ID}',
|
prompt='茶服绑定{游戏ID}',
|
||||||
lang=get_lang(),
|
lang=get_lang(),
|
||||||
|
|||||||
@@ -2,16 +2,22 @@ from base64 import b64encode
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Literal, overload
|
from typing import Literal, overload
|
||||||
|
|
||||||
from nonebot_plugin_userinfo import UserInfo
|
from nonebot_plugin_uninfo import User
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
from yarl import URL
|
||||||
|
|
||||||
|
from ..config.config import config
|
||||||
|
from .request import Request
|
||||||
|
|
||||||
|
request = Request(config.tetris.proxy.main)
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
async def get_avatar(user: UserInfo, scheme: Literal['Data URI'], default: str | None) -> str:
|
async def get_avatar(user: User, scheme: Literal['Data URI'], default: str | None) -> str:
|
||||||
"""获取用户头像的指定格式
|
"""获取用户头像的指定格式
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
user (UserInfo): 要获取的用户
|
user (User): 要获取的用户
|
||||||
scheme (Literal['Data URI']): 格式
|
scheme (Literal['Data URI']): 格式
|
||||||
default (str | None): 获取不到时的默认值
|
default (str | None): 获取不到时的默认值
|
||||||
|
|
||||||
@@ -25,11 +31,11 @@ async def get_avatar(user: UserInfo, scheme: Literal['Data URI'], default: str |
|
|||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
async def get_avatar(user: UserInfo, scheme: Literal['bytes'], default: str | None) -> bytes:
|
async def get_avatar(user: User, scheme: Literal['bytes'], default: str | None) -> bytes:
|
||||||
"""获取用户头像的指定格式
|
"""获取用户头像的指定格式
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
user (UserInfo): 要获取的用户
|
user (User): 要获取的用户
|
||||||
scheme (Literal['bytes']): 格式
|
scheme (Literal['bytes']): 格式
|
||||||
default (str | None): 获取不到时的默认值
|
default (str | None): 获取不到时的默认值
|
||||||
|
|
||||||
@@ -38,20 +44,20 @@ async def get_avatar(user: UserInfo, scheme: Literal['bytes'], default: str | No
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
async def get_avatar(user: UserInfo, scheme: Literal['Data URI', 'bytes'], default: str | None) -> str | bytes:
|
async def get_avatar(user: User, scheme: Literal['Data URI', 'bytes'], default: str | None) -> str | bytes:
|
||||||
if user.user_avatar is None:
|
if user.avatar is None:
|
||||||
if default is None:
|
if default is None:
|
||||||
msg = "Can't get avatar"
|
msg = "Can't get avatar"
|
||||||
raise TypeError(msg)
|
raise TypeError(msg)
|
||||||
return default
|
return default
|
||||||
bot_avatar = await user.user_avatar.get_image()
|
avatar = await request.request(URL(user.avatar), is_json=False)
|
||||||
if scheme == 'Data URI':
|
if scheme == 'Data URI':
|
||||||
avatar_format = Image.open(BytesIO(bot_avatar)).format
|
avatar_format = Image.open(BytesIO(avatar)).format
|
||||||
if avatar_format is None:
|
if avatar_format is None:
|
||||||
msg = "Can't get avatar format"
|
msg = "Can't get avatar format"
|
||||||
raise TypeError(msg)
|
raise TypeError(msg)
|
||||||
return f'data:{Image.MIME[avatar_format]};base64,{b64encode(bot_avatar).decode()}'
|
return f'data:{Image.MIME[avatar_format]};base64,{b64encode(avatar).decode()}'
|
||||||
return bot_avatar
|
return avatar
|
||||||
|
|
||||||
|
|
||||||
def img_to_png(image: bytes) -> bytes:
|
def img_to_png(image: bytes) -> bytes:
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ from typing import Literal
|
|||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from .......games.tetrio.api.schemas.summaries.achievements import ArType, RankType
|
||||||
|
from .......games.tetrio.api.schemas.summaries.achievements import Rank as AchievementRank
|
||||||
from .......games.tetrio.api.typedefs import Rank
|
from .......games.tetrio.api.typedefs import Rank
|
||||||
from ......typedefs import Number
|
from ......typedefs import Number
|
||||||
from ....base import Avatar, Base, HistoryData
|
from ....base import Avatar, Base, HistoryData
|
||||||
@@ -15,6 +17,18 @@ class Badge(BaseModel):
|
|||||||
receive_at: datetime | None
|
receive_at: datetime | None
|
||||||
|
|
||||||
|
|
||||||
|
class Achievement(BaseModel):
|
||||||
|
key: int
|
||||||
|
rank_type: RankType
|
||||||
|
ar_type: ArType
|
||||||
|
stub: bool | None
|
||||||
|
rank: AchievementRank | None
|
||||||
|
achieved_score: float | None
|
||||||
|
pos: int | None
|
||||||
|
progress: float | None
|
||||||
|
total: int | None
|
||||||
|
|
||||||
|
|
||||||
class User(BaseModel):
|
class User(BaseModel):
|
||||||
id: str
|
id: str
|
||||||
name: str
|
name: str
|
||||||
@@ -37,7 +51,7 @@ class User(BaseModel):
|
|||||||
xp: Number
|
xp: Number
|
||||||
|
|
||||||
ar: Number
|
ar: Number
|
||||||
achievements: list[int]
|
achievements: list[Achievement]
|
||||||
|
|
||||||
playtime: str | None
|
playtime: str | None
|
||||||
join_at: datetime | None
|
join_at: datetime | None
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
#:schema https://json.schemastore.org/uv.json
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "nonebot-plugin-tetris-stats"
|
name = "nonebot-plugin-tetris-stats"
|
||||||
version = "1.8.2"
|
version = "1.9.0"
|
||||||
description = "一款基于 NoneBot2 的用于查询 Tetris 相关游戏数据的插件"
|
description = "一款基于 NoneBot2 的用于查询 Tetris 相关游戏数据的插件"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
authors = [{ name = "shoucandanghehe", email = "wallfjjd@gmail.com" }]
|
authors = [{ name = "shoucandanghehe", email = "wallfjjd@gmail.com" }]
|
||||||
@@ -19,11 +21,10 @@ dependencies = [
|
|||||||
"nonebot-plugin-apscheduler>=0.5.0",
|
"nonebot-plugin-apscheduler>=0.5.0",
|
||||||
"nonebot-plugin-localstore>=0.7.1",
|
"nonebot-plugin-localstore>=0.7.1",
|
||||||
"nonebot-plugin-orm>=0.7.6",
|
"nonebot-plugin-orm>=0.7.6",
|
||||||
"nonebot-plugin-session>=0.3.2",
|
"nonebot-plugin-uninfo>=0.7.4",
|
||||||
"nonebot-plugin-session-orm>=0.2.0",
|
|
||||||
"nonebot-plugin-user>=0.4.4",
|
"nonebot-plugin-user>=0.4.4",
|
||||||
"nonebot-plugin-userinfo>=0.2.6",
|
|
||||||
"nonebot-plugin-waiter>=0.8.0",
|
"nonebot-plugin-waiter>=0.8.0",
|
||||||
|
"nonebot-session-to-uninfo>=0.0.2",
|
||||||
"nonebot2[fastapi]>=2.3.3",
|
"nonebot2[fastapi]>=2.3.3",
|
||||||
"pandas>=2.2.3",
|
"pandas>=2.2.3",
|
||||||
"pillow>=11.0.0",
|
"pillow>=11.0.0",
|
||||||
@@ -160,7 +161,7 @@ defineConstant = { PYDANTIC_V2 = true }
|
|||||||
typeCheckingMode = "standard"
|
typeCheckingMode = "standard"
|
||||||
|
|
||||||
[tool.bumpversion]
|
[tool.bumpversion]
|
||||||
current_version = "1.8.2"
|
current_version = "1.9.0"
|
||||||
tag = true
|
tag = true
|
||||||
sign_tags = true
|
sign_tags = true
|
||||||
tag_name = "{new_version}"
|
tag_name = "{new_version}"
|
||||||
|
|||||||
Reference in New Issue
Block a user