mirror of
https://github.com/A-Minos/nonebot-plugin-tetris-stats.git
synced 2026-03-05 05:36:54 +08:00
@@ -10,6 +10,7 @@ require_plugins = {
|
|||||||
'nonebot_plugin_session',
|
'nonebot_plugin_session',
|
||||||
'nonebot_plugin_user',
|
'nonebot_plugin_user',
|
||||||
'nonebot_plugin_userinfo',
|
'nonebot_plugin_userinfo',
|
||||||
|
'nonebot_plugin_waiter',
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in require_plugins:
|
for i in require_plugins:
|
||||||
|
|||||||
@@ -63,6 +63,23 @@ async def create_or_update_bind(
|
|||||||
return status
|
return status
|
||||||
|
|
||||||
|
|
||||||
|
async def remove_bind(
|
||||||
|
session: AsyncSession,
|
||||||
|
user: User,
|
||||||
|
game_platform: GameType,
|
||||||
|
) -> bool:
|
||||||
|
bind = await query_bind_info(
|
||||||
|
session=session,
|
||||||
|
user=user,
|
||||||
|
game_platform=game_platform,
|
||||||
|
)
|
||||||
|
if bind is not None:
|
||||||
|
await session.delete(bind)
|
||||||
|
await session.commit()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
T = TypeVar('T', 'TETRIOHistoricalData', 'TOPHistoricalData', 'TOSHistoricalData')
|
T = TypeVar('T', 'TETRIOHistoricalData', 'TOPHistoricalData', 'TOSHistoricalData')
|
||||||
|
|
||||||
lock = Lock()
|
lock = Lock()
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ command = Subcommand(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
from . import bind, config, list, query, rank, record # noqa: A004, E402
|
from . import bind, config, list, query, rank, record, unbind # noqa: A004, E402
|
||||||
|
|
||||||
main_command.add(command)
|
main_command.add(command)
|
||||||
|
|
||||||
@@ -35,4 +35,5 @@ __all__ = [
|
|||||||
'query',
|
'query',
|
||||||
'rank',
|
'rank',
|
||||||
'record',
|
'record',
|
||||||
|
'unbind',
|
||||||
]
|
]
|
||||||
|
|||||||
75
nonebot_plugin_tetris_stats/games/tetrio/unbind.py
Normal file
75
nonebot_plugin_tetris_stats/games/tetrio/unbind.py
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
from hashlib import md5
|
||||||
|
|
||||||
|
from nonebot_plugin_alconna import Subcommand
|
||||||
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
|
from nonebot_plugin_orm import get_session
|
||||||
|
from nonebot_plugin_session import EventSession
|
||||||
|
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
||||||
|
from nonebot_plugin_user import User
|
||||||
|
from nonebot_plugin_userinfo import BotUserInfo, UserInfo
|
||||||
|
from nonebot_plugin_waiter import suggest # type: ignore[import-untyped]
|
||||||
|
from yarl import URL
|
||||||
|
|
||||||
|
from ...db import query_bind_info, remove_bind, trigger
|
||||||
|
from ...utils.host import HostPage, get_self_netloc
|
||||||
|
from ...utils.image import get_avatar
|
||||||
|
from ...utils.render import Bind, render
|
||||||
|
from ...utils.render.schemas.base import Avatar, People
|
||||||
|
from ...utils.screenshot import screenshot
|
||||||
|
from . import alc, command
|
||||||
|
from .api import Player
|
||||||
|
from .constant import GAME_TYPE
|
||||||
|
|
||||||
|
command.add(Subcommand('unbind', help_text='解除绑定 TETR.IO 账号'))
|
||||||
|
|
||||||
|
alc.shortcut(
|
||||||
|
'(?i:io)(?i:解除绑定|解绑|unbind)',
|
||||||
|
command='tstats TETR.IO unbind',
|
||||||
|
humanized='io解绑',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@alc.assign('TETRIO.unbind')
|
||||||
|
async def _(nb_user: User, event_session: EventSession, bot_info: UserInfo = BotUserInfo()): # noqa: B008
|
||||||
|
async with (
|
||||||
|
trigger(
|
||||||
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
|
game_platform=GAME_TYPE,
|
||||||
|
command_type='unbind',
|
||||||
|
command_args=[],
|
||||||
|
),
|
||||||
|
get_session() as session,
|
||||||
|
):
|
||||||
|
if (bind := await query_bind_info(session=session, user=nb_user, game_platform=GAME_TYPE)) is None:
|
||||||
|
await UniMessage('您还未绑定 TETR.IO 账号').finish()
|
||||||
|
resp = await suggest('您确定要解绑吗?', ['是', '否'])
|
||||||
|
if resp is None or resp.extract_plain_text() == '否':
|
||||||
|
return
|
||||||
|
player = Player(user_id=bind.game_account, trust=True)
|
||||||
|
user = await player.user
|
||||||
|
netloc = get_self_netloc()
|
||||||
|
async with HostPage(
|
||||||
|
await render(
|
||||||
|
'v1/binding',
|
||||||
|
Bind(
|
||||||
|
platform='TETR.IO',
|
||||||
|
status='unlink',
|
||||||
|
user=People(
|
||||||
|
avatar=str(
|
||||||
|
URL(f'http://{netloc}/host/resource/tetrio/avatars/{user.ID}')
|
||||||
|
% {'revision': avatar_revision}
|
||||||
|
)
|
||||||
|
if (avatar_revision := (await player.avatar_revision)) is not None and avatar_revision != 0
|
||||||
|
else Avatar(type='identicon', hash=md5(user.ID.encode()).hexdigest()), # noqa: S324
|
||||||
|
name=user.name.upper(),
|
||||||
|
),
|
||||||
|
bot=People(
|
||||||
|
avatar=await get_avatar(bot_info, 'Data URI', '../../static/logo/logo.svg'),
|
||||||
|
name=bot_info.user_name,
|
||||||
|
),
|
||||||
|
command='io绑定{游戏ID}',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
) as page_hash:
|
||||||
|
await UniMessage.image(raw=await screenshot(f'http://{netloc}/host/{page_hash}.html')).send()
|
||||||
|
await remove_bind(session=session, user=nb_user, game_platform=GAME_TYPE)
|
||||||
@@ -29,6 +29,10 @@ command.add(
|
|||||||
),
|
),
|
||||||
help_text='绑定 TOP 账号',
|
help_text='绑定 TOP 账号',
|
||||||
),
|
),
|
||||||
|
Subcommand(
|
||||||
|
'unbind',
|
||||||
|
help_text='解除绑定 TOP 账号',
|
||||||
|
),
|
||||||
Subcommand(
|
Subcommand(
|
||||||
'query',
|
'query',
|
||||||
Args(
|
Args(
|
||||||
@@ -51,9 +55,22 @@ command.add(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
alc.shortcut('(?i:top)(?i:绑定|绑|bind)', {'command': 'tstats TOP bind', 'humanized': 'top绑定'})
|
alc.shortcut(
|
||||||
alc.shortcut('(?i:top)(?i:查询|查|query|stats)', {'command': 'tstats TOP query', 'humanized': 'top查'})
|
'(?i:top)(?i:绑定|绑|bind)',
|
||||||
|
command='tstats TOP bind',
|
||||||
|
humanized='top绑定',
|
||||||
|
)
|
||||||
|
alc.shortcut(
|
||||||
|
'(?i:top)(?i:解除绑定|解绑|unbind)',
|
||||||
|
command='tstats TOP unbind',
|
||||||
|
humanized='top解绑',
|
||||||
|
)
|
||||||
|
alc.shortcut(
|
||||||
|
'(?i:top)(?i:查询|查|query|stats)',
|
||||||
|
command='tstats TOP query',
|
||||||
|
humanized='top查',
|
||||||
|
)
|
||||||
|
|
||||||
add_block_handlers(alc.assign('TOP.query'))
|
add_block_handlers(alc.assign('TOP.query'))
|
||||||
|
|
||||||
from . import bind, query # noqa: E402, F401
|
from . import bind, query, unbind # noqa: E402, F401
|
||||||
|
|||||||
63
nonebot_plugin_tetris_stats/games/top/unbind.py
Normal file
63
nonebot_plugin_tetris_stats/games/top/unbind.py
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
|
from nonebot_plugin_orm import get_session
|
||||||
|
from nonebot_plugin_session import EventSession
|
||||||
|
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
||||||
|
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 ...db import query_bind_info, remove_bind, trigger
|
||||||
|
from ...utils.host import HostPage, get_self_netloc
|
||||||
|
from ...utils.image import get_avatar
|
||||||
|
from ...utils.render import Bind, render
|
||||||
|
from ...utils.render.schemas.base import People
|
||||||
|
from ...utils.screenshot import screenshot
|
||||||
|
from . import alc
|
||||||
|
from .api import Player
|
||||||
|
from .constant import GAME_TYPE
|
||||||
|
|
||||||
|
|
||||||
|
@alc.assign('TOP.unbind')
|
||||||
|
async def _(
|
||||||
|
nb_user: User,
|
||||||
|
event_session: EventSession,
|
||||||
|
event_user_info: UserInfo = EventUserInfo(), # noqa: B008
|
||||||
|
bot_info: UserInfo = BotUserInfo(), # noqa: B008
|
||||||
|
):
|
||||||
|
async with (
|
||||||
|
trigger(
|
||||||
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
|
game_platform=GAME_TYPE,
|
||||||
|
command_type='unbind',
|
||||||
|
command_args=[],
|
||||||
|
),
|
||||||
|
get_session() as session,
|
||||||
|
):
|
||||||
|
if (bind := await query_bind_info(session=session, user=nb_user, game_platform=GAME_TYPE)) is None:
|
||||||
|
await UniMessage('您还未绑定 TOP 账号').finish()
|
||||||
|
resp = await suggest('您确定要解绑吗?', ['是', '否'])
|
||||||
|
if resp is None or resp.extract_plain_text() == '否':
|
||||||
|
return
|
||||||
|
player = Player(user_name=bind.game_account, trust=True)
|
||||||
|
user = await player.user
|
||||||
|
netloc = get_self_netloc()
|
||||||
|
async with HostPage(
|
||||||
|
await render(
|
||||||
|
'v1/binding',
|
||||||
|
Bind(
|
||||||
|
platform='TOP',
|
||||||
|
status='unlink',
|
||||||
|
user=People(
|
||||||
|
avatar=await get_avatar(event_user_info, 'Data URI', None),
|
||||||
|
name=user.user_name,
|
||||||
|
),
|
||||||
|
bot=People(
|
||||||
|
avatar=await get_avatar(bot_info, 'Data URI', '../../static/logo/logo.svg'),
|
||||||
|
name=bot_info.user_name,
|
||||||
|
),
|
||||||
|
command='top绑定{游戏ID}',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
) as page_hash:
|
||||||
|
await UniMessage.image(raw=await screenshot(f'http://{netloc}/host/{page_hash}.html')).send()
|
||||||
|
await remove_bind(session=session, user=nb_user, game_platform=GAME_TYPE)
|
||||||
@@ -34,6 +34,10 @@ command.add(
|
|||||||
),
|
),
|
||||||
help_text='绑定 茶服 账号',
|
help_text='绑定 茶服 账号',
|
||||||
),
|
),
|
||||||
|
Subcommand(
|
||||||
|
'unbind',
|
||||||
|
help_text='解除绑定 TOS 账号',
|
||||||
|
),
|
||||||
Subcommand(
|
Subcommand(
|
||||||
'query',
|
'query',
|
||||||
Args(
|
Args(
|
||||||
@@ -56,9 +60,22 @@ command.add(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
alc.shortcut('(?i:tos|茶服)(?i:绑定|绑|bind)', {'command': 'tstats TOS bind', 'humanized': '茶服绑定'})
|
alc.shortcut(
|
||||||
alc.shortcut('(?i:tos|茶服)(?i:查询|查|query|stats)', {'command': 'tstats TOS query', 'humanized': '茶服查'})
|
'(?i:tos|茶服)(?i:绑定|绑|bind)',
|
||||||
|
command='tstats TOS bind',
|
||||||
|
humanized='茶服绑定',
|
||||||
|
)
|
||||||
|
alc.shortcut(
|
||||||
|
'(?i:tos|茶服)(?i:解除绑定|解绑|unbind)',
|
||||||
|
command='tstats TOS unbind',
|
||||||
|
humanized='茶服解绑',
|
||||||
|
)
|
||||||
|
alc.shortcut(
|
||||||
|
'(?i:tos|茶服)(?i:查询|查|query|stats)',
|
||||||
|
command='tstats TOS query',
|
||||||
|
humanized='茶服查',
|
||||||
|
)
|
||||||
|
|
||||||
add_block_handlers(alc.assign('TOS.query'))
|
add_block_handlers(alc.assign('TOS.query'))
|
||||||
|
|
||||||
from . import bind, query # noqa: E402, F401
|
from . import bind, query, unbind # noqa: E402, F401
|
||||||
|
|||||||
66
nonebot_plugin_tetris_stats/games/tos/unbind.py
Normal file
66
nonebot_plugin_tetris_stats/games/tos/unbind.py
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
|
from nonebot_plugin_orm import get_session
|
||||||
|
from nonebot_plugin_session import EventSession
|
||||||
|
from nonebot_plugin_session_orm import get_session_persist_id # type: ignore[import-untyped]
|
||||||
|
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 ...db import query_bind_info, remove_bind, trigger
|
||||||
|
from ...utils.host import HostPage, get_self_netloc
|
||||||
|
from ...utils.image import get_avatar
|
||||||
|
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.screenshot import screenshot
|
||||||
|
from . import alc
|
||||||
|
from .api import Player
|
||||||
|
from .constant import GAME_TYPE
|
||||||
|
|
||||||
|
|
||||||
|
@alc.assign('TOP.unbind')
|
||||||
|
async def _(
|
||||||
|
nb_user: User,
|
||||||
|
event_session: EventSession,
|
||||||
|
event_user_info: UserInfo = EventUserInfo(), # noqa: B008
|
||||||
|
bot_info: UserInfo = BotUserInfo(), # noqa: B008
|
||||||
|
):
|
||||||
|
async with (
|
||||||
|
trigger(
|
||||||
|
session_persist_id=await get_session_persist_id(event_session),
|
||||||
|
game_platform=GAME_TYPE,
|
||||||
|
command_type='unbind',
|
||||||
|
command_args=[],
|
||||||
|
),
|
||||||
|
get_session() as session,
|
||||||
|
):
|
||||||
|
if (bind := await query_bind_info(session=session, user=nb_user, game_platform=GAME_TYPE)) is None:
|
||||||
|
await UniMessage('您还未绑定 TOP 账号').finish()
|
||||||
|
resp = await suggest('您确定要解绑吗?', ['是', '否'])
|
||||||
|
if resp is None or resp.extract_plain_text() == '否':
|
||||||
|
return
|
||||||
|
player = Player(user_name=bind.game_account, trust=True)
|
||||||
|
user = await player.user
|
||||||
|
netloc = get_self_netloc()
|
||||||
|
async with HostPage(
|
||||||
|
await render(
|
||||||
|
'v1/binding',
|
||||||
|
Bind(
|
||||||
|
platform='TOS',
|
||||||
|
status='unlink',
|
||||||
|
user=People(
|
||||||
|
avatar=await get_avatar(event_user_info, 'Data URI', None)
|
||||||
|
if event_user_info is not None
|
||||||
|
else get_random_avatar(user.teaid),
|
||||||
|
name=user.name,
|
||||||
|
),
|
||||||
|
bot=People(
|
||||||
|
avatar=await get_avatar(bot_info, 'Data URI', '../../static/logo/logo.svg'),
|
||||||
|
name=bot_info.user_name,
|
||||||
|
),
|
||||||
|
command='茶服绑定{游戏ID}',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
) as page_hash:
|
||||||
|
await UniMessage.image(raw=await screenshot(f'http://{netloc}/host/{page_hash}.html')).send()
|
||||||
|
await remove_bind(session=session, user=nb_user, game_platform=GAME_TYPE)
|
||||||
@@ -2,7 +2,7 @@ from typing import Literal, TypeAlias
|
|||||||
|
|
||||||
Number: TypeAlias = float | int
|
Number: TypeAlias = float | int
|
||||||
GameType: TypeAlias = Literal['IO', 'TOP', 'TOS']
|
GameType: TypeAlias = Literal['IO', 'TOP', 'TOS']
|
||||||
BaseCommandType: TypeAlias = Literal['bind', 'query']
|
BaseCommandType: TypeAlias = Literal['bind', 'unbind', 'query']
|
||||||
TETRIOCommandType: TypeAlias = BaseCommandType | Literal['rank', 'config', 'list', 'record']
|
TETRIOCommandType: TypeAlias = BaseCommandType | Literal['rank', 'config', 'list', 'record']
|
||||||
AllCommandType: TypeAlias = BaseCommandType | TETRIOCommandType
|
AllCommandType: TypeAlias = BaseCommandType | TETRIOCommandType
|
||||||
Me: TypeAlias = Literal[
|
Me: TypeAlias = Literal[
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ dependencies = [
|
|||||||
"nonebot-plugin-session-orm>=0.2.0",
|
"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-userinfo>=0.2.6",
|
||||||
|
"nonebot-plugin-waiter>=0.8.0",
|
||||||
"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",
|
||||||
|
|||||||
8
uv.lock
generated
8
uv.lock
generated
@@ -1818,7 +1818,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nonebot-plugin-tetris-stats"
|
name = "nonebot-plugin-tetris-stats"
|
||||||
version = "1.6.2"
|
version = "1.6.3"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "aiocache" },
|
{ name = "aiocache" },
|
||||||
@@ -1837,6 +1837,7 @@ dependencies = [
|
|||||||
{ name = "nonebot-plugin-session-orm" },
|
{ name = "nonebot-plugin-session-orm" },
|
||||||
{ name = "nonebot-plugin-user" },
|
{ name = "nonebot-plugin-user" },
|
||||||
{ name = "nonebot-plugin-userinfo" },
|
{ name = "nonebot-plugin-userinfo" },
|
||||||
|
{ name = "nonebot-plugin-waiter" },
|
||||||
{ name = "nonebot2", extra = ["fastapi"] },
|
{ name = "nonebot2", extra = ["fastapi"] },
|
||||||
{ name = "pandas" },
|
{ name = "pandas" },
|
||||||
{ name = "pillow" },
|
{ name = "pillow" },
|
||||||
@@ -1845,7 +1846,7 @@ dependencies = [
|
|||||||
{ name = "yarl" },
|
{ name = "yarl" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependency-groups]
|
[package.dev-dependencies]
|
||||||
debug = [
|
debug = [
|
||||||
{ name = "matplotlib" },
|
{ name = "matplotlib" },
|
||||||
{ name = "memory-profiler" },
|
{ name = "memory-profiler" },
|
||||||
@@ -1898,6 +1899,7 @@ requires-dist = [
|
|||||||
{ name = "nonebot-plugin-session-orm", specifier = ">=0.2.0" },
|
{ name = "nonebot-plugin-session-orm", specifier = ">=0.2.0" },
|
||||||
{ name = "nonebot-plugin-user", specifier = ">=0.4.4" },
|
{ name = "nonebot-plugin-user", specifier = ">=0.4.4" },
|
||||||
{ name = "nonebot-plugin-userinfo", specifier = ">=0.2.6" },
|
{ name = "nonebot-plugin-userinfo", specifier = ">=0.2.6" },
|
||||||
|
{ name = "nonebot-plugin-waiter", specifier = ">=0.8.0" },
|
||||||
{ name = "nonebot2", extras = ["fastapi"], specifier = ">=2.3.3" },
|
{ name = "nonebot2", extras = ["fastapi"], specifier = ">=2.3.3" },
|
||||||
{ name = "pandas", specifier = ">=2.2.3" },
|
{ name = "pandas", specifier = ">=2.2.3" },
|
||||||
{ name = "pillow", specifier = ">=11.0.0" },
|
{ name = "pillow", specifier = ">=11.0.0" },
|
||||||
@@ -1906,7 +1908,7 @@ requires-dist = [
|
|||||||
{ name = "yarl", specifier = ">=1.16.0" },
|
{ name = "yarl", specifier = ">=1.16.0" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.metadata.dependency-groups]
|
[package.metadata.requires-dev]
|
||||||
debug = [
|
debug = [
|
||||||
{ name = "matplotlib", specifier = ">=3.9.2" },
|
{ name = "matplotlib", specifier = ">=3.9.2" },
|
||||||
{ name = "memory-profiler", specifier = ">=0.61.0" },
|
{ name = "memory-profiler", specifier = ">=0.61.0" },
|
||||||
|
|||||||
Reference in New Issue
Block a user