nonebot-plugin-werewolf 1.1.1__py3-none-any.whl → 1.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nonebot_plugin_werewolf/__init__.py +1 -1
- nonebot_plugin_werewolf/_timeout.py +110 -0
- nonebot_plugin_werewolf/config.py +5 -4
- nonebot_plugin_werewolf/constant.py +1 -1
- nonebot_plugin_werewolf/exception.py +1 -1
- nonebot_plugin_werewolf/game.py +14 -12
- nonebot_plugin_werewolf/matchers.py +2 -3
- nonebot_plugin_werewolf/player.py +16 -9
- nonebot_plugin_werewolf/player_set.py +3 -3
- nonebot_plugin_werewolf/utils.py +0 -1
- {nonebot_plugin_werewolf-1.1.1.dist-info → nonebot_plugin_werewolf-1.1.2.dist-info}/METADATA +10 -6
- nonebot_plugin_werewolf-1.1.2.dist-info/RECORD +16 -0
- {nonebot_plugin_werewolf-1.1.1.dist-info → nonebot_plugin_werewolf-1.1.2.dist-info}/WHEEL +1 -1
- nonebot_plugin_werewolf-1.1.1.dist-info/RECORD +0 -15
- {nonebot_plugin_werewolf-1.1.1.dist-info → nonebot_plugin_werewolf-1.1.2.dist-info}/LICENSE +0 -0
- {nonebot_plugin_werewolf-1.1.1.dist-info → nonebot_plugin_werewolf-1.1.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,110 @@
|
|
1
|
+
import asyncio
|
2
|
+
import enum
|
3
|
+
import sys
|
4
|
+
from types import TracebackType
|
5
|
+
from typing import final
|
6
|
+
|
7
|
+
if sys.version_info >= (3, 11):
|
8
|
+
from asyncio.timeouts import timeout as timeout
|
9
|
+
|
10
|
+
else:
|
11
|
+
# ruff: noqa: S101
|
12
|
+
|
13
|
+
class _State(enum.Enum):
|
14
|
+
CREATED = "created"
|
15
|
+
ENTERED = "active"
|
16
|
+
EXPIRING = "expiring"
|
17
|
+
EXPIRED = "expired"
|
18
|
+
EXITED = "finished"
|
19
|
+
|
20
|
+
@final
|
21
|
+
class Timeout:
|
22
|
+
def __init__(self, when: float | None) -> None:
|
23
|
+
self._state = _State.CREATED
|
24
|
+
self._timeout_handler: asyncio.Handle | None = None
|
25
|
+
self._task: asyncio.Task | None = None
|
26
|
+
if when is not None:
|
27
|
+
when = asyncio.get_running_loop().time() + when
|
28
|
+
self._when = when
|
29
|
+
|
30
|
+
def when(self) -> float | None:
|
31
|
+
return self._when
|
32
|
+
|
33
|
+
def reschedule(self, when: float | None) -> None:
|
34
|
+
if self._state is not _State.ENTERED:
|
35
|
+
if self._state is _State.CREATED:
|
36
|
+
raise RuntimeError("Timeout has not been entered")
|
37
|
+
raise RuntimeError(
|
38
|
+
f"Cannot change state of {self._state.value} Timeout",
|
39
|
+
)
|
40
|
+
|
41
|
+
self._when = when
|
42
|
+
|
43
|
+
if self._timeout_handler is not None:
|
44
|
+
self._timeout_handler.cancel()
|
45
|
+
|
46
|
+
if when is None:
|
47
|
+
self._timeout_handler = None
|
48
|
+
else:
|
49
|
+
loop = asyncio.get_running_loop()
|
50
|
+
if when <= loop.time():
|
51
|
+
self._timeout_handler = loop.call_soon(self._on_timeout)
|
52
|
+
else:
|
53
|
+
self._timeout_handler = loop.call_at(when, self._on_timeout)
|
54
|
+
|
55
|
+
def expired(self) -> bool:
|
56
|
+
return self._state in (_State.EXPIRING, _State.EXPIRED)
|
57
|
+
|
58
|
+
def __repr__(self) -> str:
|
59
|
+
info = [""]
|
60
|
+
if self._state is _State.ENTERED:
|
61
|
+
when = round(self._when, 3) if self._when is not None else None
|
62
|
+
info.append(f"when={when}")
|
63
|
+
info_str = " ".join(info)
|
64
|
+
return f"<Timeout [{self._state.value}]{info_str}>"
|
65
|
+
|
66
|
+
async def __aenter__(self) -> "Timeout":
|
67
|
+
if self._state is not _State.CREATED:
|
68
|
+
raise RuntimeError("Timeout has already been entered")
|
69
|
+
task = asyncio.current_task()
|
70
|
+
if task is None:
|
71
|
+
raise RuntimeError("Timeout should be used inside a task")
|
72
|
+
self._state = _State.ENTERED
|
73
|
+
self._task = task
|
74
|
+
self.reschedule(self._when)
|
75
|
+
return self
|
76
|
+
|
77
|
+
async def __aexit__(
|
78
|
+
self,
|
79
|
+
exc_type: type[BaseException] | None,
|
80
|
+
exc_val: BaseException | None,
|
81
|
+
exc_tb: TracebackType | None,
|
82
|
+
) -> bool | None:
|
83
|
+
assert self._state in (_State.ENTERED, _State.EXPIRING)
|
84
|
+
|
85
|
+
if self._timeout_handler is not None:
|
86
|
+
self._timeout_handler.cancel()
|
87
|
+
self._timeout_handler = None
|
88
|
+
|
89
|
+
if self._state is _State.EXPIRING:
|
90
|
+
self._state = _State.EXPIRED
|
91
|
+
|
92
|
+
if exc_type is asyncio.CancelledError:
|
93
|
+
raise TimeoutError from exc_val
|
94
|
+
elif self._state is _State.ENTERED:
|
95
|
+
self._state = _State.EXITED
|
96
|
+
|
97
|
+
return None
|
98
|
+
|
99
|
+
def _on_timeout(self) -> None:
|
100
|
+
assert self._state is _State.ENTERED
|
101
|
+
assert self._task is not None
|
102
|
+
self._task.cancel()
|
103
|
+
self._state = _State.EXPIRING
|
104
|
+
self._timeout_handler = None
|
105
|
+
|
106
|
+
def timeout(delay: float | None) -> Timeout:
|
107
|
+
return Timeout(delay)
|
108
|
+
|
109
|
+
|
110
|
+
__all__ = ["timeout"]
|
@@ -1,8 +1,9 @@
|
|
1
|
-
from typing import Literal,
|
1
|
+
from typing import Literal, overload
|
2
2
|
|
3
3
|
from nonebot import get_plugin_config, logger
|
4
4
|
from nonebot.compat import PYDANTIC_V2
|
5
5
|
from pydantic import BaseModel, Field
|
6
|
+
from typing_extensions import Self
|
6
7
|
|
7
8
|
from .constant import (
|
8
9
|
Role,
|
@@ -47,7 +48,7 @@ class PluginConfig(BaseModel):
|
|
47
48
|
if isinstance(self.role_preset, list):
|
48
49
|
for preset in self.role_preset:
|
49
50
|
if preset[0] != sum(preset[1:]):
|
50
|
-
raise
|
51
|
+
raise ValueError(
|
51
52
|
"配置项 `role_preset` 错误: "
|
52
53
|
f"预设总人数为 {preset[0]}, 实际总人数为 {sum(preset[1:])} "
|
53
54
|
f"({', '.join(map(str, preset[1:]))})"
|
@@ -59,13 +60,13 @@ class PluginConfig(BaseModel):
|
|
59
60
|
|
60
61
|
min_length = max(i[0] for i in self.role_preset.values())
|
61
62
|
if len(self.werewolf_priority) < min_length:
|
62
|
-
raise
|
63
|
+
raise ValueError(
|
63
64
|
f"配置项 `werewolf_priority` 错误: 应至少为 {min_length} 项"
|
64
65
|
)
|
65
66
|
|
66
67
|
min_length = max(i[1] for i in self.role_preset.values())
|
67
68
|
if len(self.priesthood_proirity) < min_length:
|
68
|
-
raise
|
69
|
+
raise ValueError(
|
69
70
|
f"配置项 `priesthood_proirity` 错误: 应至少为 {min_length} 项"
|
70
71
|
)
|
71
72
|
|
@@ -52,7 +52,7 @@ class GameState:
|
|
52
52
|
killed: Player | None = None
|
53
53
|
shoot: tuple[Player, Player] | tuple[None, None] = (None, None)
|
54
54
|
antidote: set[Player] = dataclasses.field(default_factory=set)
|
55
|
-
poison: set[
|
55
|
+
poison: set[Player] = dataclasses.field(default_factory=set)
|
56
56
|
protected: set[Player] = dataclasses.field(default_factory=set)
|
57
57
|
|
58
58
|
|
nonebot_plugin_werewolf/game.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import asyncio
|
4
|
-
import asyncio.timeouts
|
5
4
|
import contextlib
|
6
5
|
import secrets
|
7
6
|
from typing import TYPE_CHECKING, NoReturn
|
@@ -9,9 +8,10 @@ from typing import TYPE_CHECKING, NoReturn
|
|
9
8
|
from nonebot.log import logger
|
10
9
|
from nonebot_plugin_alconna import At, Target, UniMessage
|
11
10
|
|
11
|
+
from ._timeout import timeout
|
12
12
|
from .config import config
|
13
13
|
from .constant import GameState, GameStatus, KillReason, Role, RoleGroup, role_name_conv
|
14
|
-
from .exception import
|
14
|
+
from .exception import GameFinished
|
15
15
|
from .player import Player
|
16
16
|
from .player_set import PlayerSet
|
17
17
|
from .utils import InputStore
|
@@ -112,16 +112,16 @@ class Game:
|
|
112
112
|
|
113
113
|
# 狼人数量大于其他职业数量
|
114
114
|
if w.size >= p.size:
|
115
|
-
raise
|
115
|
+
raise GameFinished(GameStatus.Werewolf)
|
116
116
|
# 屠边-村民/中立全灭
|
117
117
|
if not p.select(Role.Civilian, RoleGroup.Others).size:
|
118
|
-
raise
|
118
|
+
raise GameFinished(GameStatus.Werewolf)
|
119
119
|
# 屠边-神职全灭
|
120
120
|
if not p.exclude(Role.Civilian).size:
|
121
|
-
raise
|
121
|
+
raise GameFinished(GameStatus.Werewolf)
|
122
122
|
# 狼人全灭
|
123
123
|
if not w.size:
|
124
|
-
raise
|
124
|
+
raise GameFinished(GameStatus.GoodGuy)
|
125
125
|
|
126
126
|
def show_killed_players(self) -> str:
|
127
127
|
msg = ""
|
@@ -173,7 +173,7 @@ class Game:
|
|
173
173
|
break
|
174
174
|
|
175
175
|
with contextlib.suppress(TimeoutError):
|
176
|
-
async with
|
176
|
+
async with timeout(timeout_secs):
|
177
177
|
await asyncio.gather(*[wait(p) for p in players])
|
178
178
|
|
179
179
|
async def interact(
|
@@ -372,7 +372,7 @@ class Game:
|
|
372
372
|
|
373
373
|
# 狼人击杀目标
|
374
374
|
if (
|
375
|
-
(killed := self.state.killed) # 狼人未空刀
|
375
|
+
(killed := self.state.killed) is not None # 狼人未空刀
|
376
376
|
and killed not in self.state.protected # 守卫保护
|
377
377
|
and killed not in self.state.antidote # 女巫使用解药
|
378
378
|
):
|
@@ -383,10 +383,12 @@ class Game:
|
|
383
383
|
)
|
384
384
|
|
385
385
|
# 女巫操作目标
|
386
|
-
for witch
|
387
|
-
if
|
386
|
+
for witch in self.state.poison:
|
387
|
+
if witch.selected is None:
|
388
|
+
continue
|
389
|
+
if witch.selected not in self.state.protected: # 守卫未保护
|
388
390
|
# 女巫毒杀玩家
|
389
|
-
await
|
391
|
+
await witch.selected.kill(KillReason.Poison, witch)
|
390
392
|
|
391
393
|
day_count += 1
|
392
394
|
msg = UniMessage.text(f"『第{day_count}天』天亮了...\n")
|
@@ -456,7 +458,7 @@ class Game:
|
|
456
458
|
game_task.result()
|
457
459
|
except asyncio.CancelledError:
|
458
460
|
logger.warning(f"{self.group.id} 的狼人杀游戏进程被取消")
|
459
|
-
except
|
461
|
+
except GameFinished as result:
|
460
462
|
await self.handle_game_finish(result.status)
|
461
463
|
logger.info(f"{self.group.id} 的狼人杀游戏进程正常退出")
|
462
464
|
except Exception as err:
|
@@ -1,5 +1,3 @@
|
|
1
|
-
import asyncio
|
2
|
-
import asyncio.timeouts
|
3
1
|
from typing import Annotated
|
4
2
|
|
5
3
|
from nonebot import on_command, on_message
|
@@ -9,6 +7,7 @@ from nonebot.rule import to_me
|
|
9
7
|
from nonebot_plugin_alconna import MsgTarget, UniMessage, UniMsg
|
10
8
|
from nonebot_plugin_userinfo import EventUserInfo, UserInfo
|
11
9
|
|
10
|
+
from ._timeout import timeout
|
12
11
|
from .game import Game
|
13
12
|
from .ob11_ext import ob11_ext_enabled
|
14
13
|
from .utils import InputStore, is_group, prepare_game, rule_in_game, rule_not_in_game
|
@@ -52,7 +51,7 @@ async def handle_start(
|
|
52
51
|
players = {admin_id: admin_info.user_name}
|
53
52
|
|
54
53
|
try:
|
55
|
-
async with
|
54
|
+
async with timeout(5 * 60):
|
56
55
|
await prepare_game(event, players)
|
57
56
|
except FinishedException:
|
58
57
|
raise
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import asyncio
|
4
|
-
import
|
4
|
+
import weakref
|
5
5
|
from dataclasses import dataclass
|
6
6
|
from typing import TYPE_CHECKING, ClassVar, TypeVar, final
|
7
7
|
|
@@ -10,7 +10,7 @@ from nonebot_plugin_alconna.uniseg import Receipt, Target, UniMessage
|
|
10
10
|
from typing_extensions import override
|
11
11
|
|
12
12
|
from .constant import GameStatus, KillReason, Role, RoleGroup, role_name_conv
|
13
|
-
from .exception import
|
13
|
+
from .exception import GameFinished
|
14
14
|
from .utils import InputStore, check_index
|
15
15
|
|
16
16
|
if TYPE_CHECKING:
|
@@ -47,7 +47,7 @@ class Player:
|
|
47
47
|
role_group: ClassVar[RoleGroup]
|
48
48
|
|
49
49
|
bot: Bot
|
50
|
-
|
50
|
+
_game_ref: weakref.ReferenceType[Game]
|
51
51
|
user: Target
|
52
52
|
name: str
|
53
53
|
alive: bool = True
|
@@ -58,7 +58,7 @@ class Player:
|
|
58
58
|
@final
|
59
59
|
def __init__(self, bot: Bot, game: Game, user: Target, name: str) -> None:
|
60
60
|
self.bot = bot
|
61
|
-
self.
|
61
|
+
self._game_ref = weakref.ref(game)
|
62
62
|
self.user = user
|
63
63
|
self.name = name
|
64
64
|
self.killed = asyncio.Event()
|
@@ -81,6 +81,12 @@ class Player:
|
|
81
81
|
def __repr__(self) -> str:
|
82
82
|
return f"<{self.role_name}: user={self.name!r} alive={self.alive}>"
|
83
83
|
|
84
|
+
@property
|
85
|
+
def game(self) -> Game:
|
86
|
+
if game := self._game_ref():
|
87
|
+
return game
|
88
|
+
raise ValueError("Game not exist")
|
89
|
+
|
84
90
|
@property
|
85
91
|
def user_id(self) -> str:
|
86
92
|
return self.user.id
|
@@ -95,7 +101,7 @@ class Player:
|
|
95
101
|
logger.opt(colors=True).info(
|
96
102
|
f"<b><e>{self.game.group.id}</e></b> | "
|
97
103
|
f"[<b><m>{self.role_name}</m></b>] "
|
98
|
-
f"<y>{self.name}</y>(<e>{self.user_id}</e>) | "
|
104
|
+
f"<y>{self.name}</y>(<b><e>{self.user_id}</e></b>) | "
|
99
105
|
f"{text}",
|
100
106
|
)
|
101
107
|
|
@@ -325,6 +331,7 @@ class Witch(Player):
|
|
325
331
|
text = await self.receive_text()
|
326
332
|
if text == "1":
|
327
333
|
self.antidote = 0
|
334
|
+
self.selected = killed
|
328
335
|
self.game.state.antidote.add(killed)
|
329
336
|
await self.send(f"你对 {killed.name} 使用了解药,回合结束")
|
330
337
|
return True
|
@@ -362,9 +369,9 @@ class Witch(Player):
|
|
362
369
|
await self.send("输入错误: 请发送玩家编号或 “/stop”")
|
363
370
|
|
364
371
|
self.poison = 0
|
365
|
-
|
366
|
-
self.game.state.poison.add(
|
367
|
-
await self.send(f"当前回合选择对玩家 {
|
372
|
+
self.selected = players[selected]
|
373
|
+
self.game.state.poison.add(self)
|
374
|
+
await self.send(f"当前回合选择对玩家 {self.selected.name} 使用毒药\n回合结束")
|
368
375
|
|
369
376
|
|
370
377
|
@register_role(Role.Hunter, RoleGroup.GoodGuy)
|
@@ -446,7 +453,7 @@ class Joker(Player):
|
|
446
453
|
await super().kill(reason, *killers)
|
447
454
|
if reason == KillReason.Vote:
|
448
455
|
self.game.killed_players.append(self)
|
449
|
-
raise
|
456
|
+
raise GameFinished(GameStatus.Joker)
|
450
457
|
return True
|
451
458
|
|
452
459
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import asyncio
|
4
|
-
import asyncio.timeouts
|
5
4
|
from typing import TYPE_CHECKING
|
6
5
|
|
6
|
+
from ._timeout import timeout
|
7
7
|
from .player import Player
|
8
8
|
|
9
9
|
if TYPE_CHECKING:
|
@@ -54,13 +54,13 @@ class PlayerSet(set[Player]):
|
|
54
54
|
return sorted(self, key=lambda p: p.user_id)
|
55
55
|
|
56
56
|
async def interact(self, timeout_secs: float = 60) -> None:
|
57
|
-
async with
|
57
|
+
async with timeout(timeout_secs):
|
58
58
|
await asyncio.gather(*[p.interact() for p in self.alive()])
|
59
59
|
|
60
60
|
async def vote(self, timeout_secs: float = 60) -> dict[Player, list[Player]]:
|
61
61
|
async def vote(player: Player) -> tuple[Player, Player] | None:
|
62
62
|
try:
|
63
|
-
async with
|
63
|
+
async with timeout(timeout_secs):
|
64
64
|
return await player.vote(self)
|
65
65
|
except TimeoutError:
|
66
66
|
await player.send("投票超时,将视为弃票")
|
nonebot_plugin_werewolf/utils.py
CHANGED
{nonebot_plugin_werewolf-1.1.1.dist-info → nonebot_plugin_werewolf-1.1.2.dist-info}/METADATA
RENAMED
@@ -1,10 +1,10 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: nonebot-plugin-werewolf
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.2
|
4
4
|
Summary: 适用于 Nonebot2 的狼人杀插件
|
5
5
|
Author-email: wyf7685 <wyf7685@163.com>
|
6
6
|
License: MIT
|
7
|
-
Requires-Python: >=3.
|
7
|
+
Requires-Python: >=3.10
|
8
8
|
Description-Content-Type: text/markdown
|
9
9
|
License-File: LICENSE
|
10
10
|
Requires-Dist: nonebot2 >=2.3.3
|
@@ -14,7 +14,7 @@ Requires-Dist: nonebot-plugin-waiter >=0.7.1
|
|
14
14
|
|
15
15
|
<div align="center">
|
16
16
|
<a href="https://v2.nonebot.dev/store">
|
17
|
-
<img src="https://
|
17
|
+
<img src="https://raw.githubusercontent.com/wyf7685/wyf7685/main/assets/NoneBotPlugin.svg" width="300" alt="logo">
|
18
18
|
</a>
|
19
19
|
</div>
|
20
20
|
|
@@ -26,14 +26,14 @@ _✨ 简单的狼人杀插件 ✨_
|
|
26
26
|
|
27
27
|
[](./LICENSE)
|
28
28
|
[](https://pypi.python.org/pypi/nonebot-plugin-werewolf)
|
29
|
-
[](https://www.python.org/)
|
30
|
+
|
30
31
|
[](https://github.com/astral-sh/uv)
|
31
32
|
[](https://github.com/astral-sh/ruff)
|
32
33
|
[](https://pycqa.github.io/isort/)
|
33
34
|
[](https://github.com/psf/black)
|
34
35
|
[](https://github.com/Microsoft/pyright)
|
35
36
|
|
36
|
-
[](https://github.com/wyf7685/nonebot-plugin-werewolf/commits)
|
37
37
|
[](https://wakatime.com/badge/user/b097681b-c224-44ec-8e04-e1cf71744655/project/70a7f68d-5625-4989-9476-be6877408332)
|
38
38
|
[](https://results.pre-commit.ci/latest/github/wyf7685/nonebot-plugin-werewolf/master)
|
39
39
|
[](https://github.com/wyf7685/nonebot-plugin-werewolf/actions/workflows/pyright.yml)
|
@@ -52,7 +52,7 @@ _✨ 简单的狼人杀插件 ✨_
|
|
52
52
|
|
53
53
|
> [!note]
|
54
54
|
>
|
55
|
-
> 请确保 NoneBot2 使用的 Python 解释器版本 >=3.
|
55
|
+
> 请确保 NoneBot2 使用的 Python 解释器版本 >=3.10
|
56
56
|
|
57
57
|
<details open>
|
58
58
|
<summary>使用 nb-cli 安装</summary>
|
@@ -240,6 +240,10 @@ werewolf__priesthood_proirity=[11, 12, 13, 14, 15]
|
|
240
240
|
|
241
241
|
<!-- CHANGELOG -->
|
242
242
|
|
243
|
+
- 2024.09.18 v1.1.2
|
244
|
+
|
245
|
+
- 修改 Python 需求为 `>=3.10`
|
246
|
+
|
243
247
|
- 2024.09.11 v1.1.1
|
244
248
|
|
245
249
|
- 修改 Python 需求为 `>=3.11`
|
@@ -0,0 +1,16 @@
|
|
1
|
+
nonebot_plugin_werewolf/__init__.py,sha256=qCS-gVMiMZcF9yT3SIMe8np-wmKX2vGT5DxYJ2jRxgY,734
|
2
|
+
nonebot_plugin_werewolf/_timeout.py,sha256=MVkA5oMoxOTV8Luc0BH2QPP8wwz4Tr9CJjeYgiPu_O4,3649
|
3
|
+
nonebot_plugin_werewolf/config.py,sha256=a5dyF21_3T1o6AFrK6onIiwXUNyEwj5Yg-c7V9qoueI,2923
|
4
|
+
nonebot_plugin_werewolf/constant.py,sha256=gUApZs-N3DRSwV2_B05mPi6fCmynSzVZb28fgqdLX6E,1894
|
5
|
+
nonebot_plugin_werewolf/exception.py,sha256=YSwxeogIB0YJqH9MP1bgxojiu-I_xQE44XnSk5bC1AQ,400
|
6
|
+
nonebot_plugin_werewolf/game.py,sha256=FqYAs8CalCRUKoyPTpqvKK5iAelV9ZQ5EmefNo5wE9E,17459
|
7
|
+
nonebot_plugin_werewolf/matchers.py,sha256=Xnq1n4xobdr1T_8ilsQfXns_iEsNx_h_-aQ5jZwpWx0,2080
|
8
|
+
nonebot_plugin_werewolf/ob11_ext.py,sha256=P8uc3AdN5K5MzJaK80WDK85VKFg_CK5avDHu7ueMkho,2418
|
9
|
+
nonebot_plugin_werewolf/player.py,sha256=2jWlJOIWNK3JVVKNaqROfvKPRQfopDXv7KAXGtXNmh4,14973
|
10
|
+
nonebot_plugin_werewolf/player_set.py,sha256=7f4GHklp-wBGROddVqGUQAMeMzKlN2iec_w5UJQXvz0,2726
|
11
|
+
nonebot_plugin_werewolf/utils.py,sha256=LiNitH3UYNqXnCOOAzjKifVpJNhurIt4wYgWVBUW1Zo,6811
|
12
|
+
nonebot_plugin_werewolf-1.1.2.dist-info/LICENSE,sha256=B_WbEqjGr6GYVNfEJPY31T1Opik7OtgOkhRs4Ig3e2M,1064
|
13
|
+
nonebot_plugin_werewolf-1.1.2.dist-info/METADATA,sha256=0W7Nb6qqwJvW7xVdLHxM4643DuJ3YN9683owdDoUOhs,10363
|
14
|
+
nonebot_plugin_werewolf-1.1.2.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
15
|
+
nonebot_plugin_werewolf-1.1.2.dist-info/top_level.txt,sha256=wLTfg8sTKbH9lLT9LtU118C9cTspEBJareLsrYM52YA,24
|
16
|
+
nonebot_plugin_werewolf-1.1.2.dist-info/RECORD,,
|
@@ -1,15 +0,0 @@
|
|
1
|
-
nonebot_plugin_werewolf/__init__.py,sha256=I6lFyJgJ4Tz4t8gS2lrsx-7paN2h_PNoGjGR8ryvSeU,734
|
2
|
-
nonebot_plugin_werewolf/config.py,sha256=gl_ujiY-8fxQ5hN9_gjL1WpJJR5UOBIRBGofbLcQzaE,2900
|
3
|
-
nonebot_plugin_werewolf/constant.py,sha256=1XNTcTicil90WSviI2e33FX0LstWXl1aV2ugbhsDlIk,1909
|
4
|
-
nonebot_plugin_werewolf/exception.py,sha256=Ui8rB1sBg6_p8JHSvrjCpUaXJlgrM_9XsLJ09k8F1bg,391
|
5
|
-
nonebot_plugin_werewolf/game.py,sha256=Y9MQASaNdm2uuNw37IjdQEQzikWmbql_PWLHaL7lcB8,17414
|
6
|
-
nonebot_plugin_werewolf/matchers.py,sha256=5FioDfARlxTEibGL1JMKUMzmTzOwljjWKAJxBnyzaYs,2106
|
7
|
-
nonebot_plugin_werewolf/ob11_ext.py,sha256=P8uc3AdN5K5MzJaK80WDK85VKFg_CK5avDHu7ueMkho,2418
|
8
|
-
nonebot_plugin_werewolf/player.py,sha256=ifqTBfNepQY5FCY7hZoUA6DcObkcFEiNmKEeRkitJqY,14749
|
9
|
-
nonebot_plugin_werewolf/player_set.py,sha256=AI8v6KjH9ACtP4lvrd5IJfayan0qALmpTRLC3s_3DFw,2754
|
10
|
-
nonebot_plugin_werewolf/utils.py,sha256=l7oNSK471SV5CaB1eEVyZm10XSBFf_TwNotvb30U6vE,6835
|
11
|
-
nonebot_plugin_werewolf-1.1.1.dist-info/LICENSE,sha256=B_WbEqjGr6GYVNfEJPY31T1Opik7OtgOkhRs4Ig3e2M,1064
|
12
|
-
nonebot_plugin_werewolf-1.1.1.dist-info/METADATA,sha256=5ikh-mdZTIObaFs9w7qgzrgsx31lCxB5Ag--C8stl0g,10447
|
13
|
-
nonebot_plugin_werewolf-1.1.1.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
14
|
-
nonebot_plugin_werewolf-1.1.1.dist-info/top_level.txt,sha256=wLTfg8sTKbH9lLT9LtU118C9cTspEBJareLsrYM52YA,24
|
15
|
-
nonebot_plugin_werewolf-1.1.1.dist-info/RECORD,,
|
File without changes
|
{nonebot_plugin_werewolf-1.1.1.dist-info → nonebot_plugin_werewolf-1.1.2.dist-info}/top_level.txt
RENAMED
File without changes
|