nonebot-plugin-werewolf 1.1.3__py3-none-any.whl → 1.1.5__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 +2 -1
- nonebot_plugin_werewolf/constant.py +23 -1
- nonebot_plugin_werewolf/game.py +172 -113
- nonebot_plugin_werewolf/matchers/depends.py +38 -0
- nonebot_plugin_werewolf/matchers/message_in_game.py +14 -4
- nonebot_plugin_werewolf/matchers/poke/__init__.py +8 -0
- nonebot_plugin_werewolf/matchers/poke/chronocat_poke.py +117 -0
- nonebot_plugin_werewolf/matchers/{ob11_ext.py → poke/ob11_poke.py} +21 -19
- nonebot_plugin_werewolf/matchers/start_game.py +161 -15
- nonebot_plugin_werewolf/player_set.py +33 -34
- nonebot_plugin_werewolf/players/can_shoot.py +12 -18
- nonebot_plugin_werewolf/players/civilian.py +2 -2
- nonebot_plugin_werewolf/players/guard.py +15 -22
- nonebot_plugin_werewolf/players/hunter.py +2 -2
- nonebot_plugin_werewolf/players/idiot.py +3 -3
- nonebot_plugin_werewolf/players/joker.py +2 -2
- nonebot_plugin_werewolf/players/player.py +137 -65
- nonebot_plugin_werewolf/players/prophet.py +7 -15
- nonebot_plugin_werewolf/players/werewolf.py +51 -29
- nonebot_plugin_werewolf/players/witch.py +32 -38
- nonebot_plugin_werewolf/players/wolfking.py +2 -2
- nonebot_plugin_werewolf/utils.py +56 -190
- {nonebot_plugin_werewolf-1.1.3.dist-info → nonebot_plugin_werewolf-1.1.5.dist-info}/METADATA +14 -2
- nonebot_plugin_werewolf-1.1.5.dist-info/RECORD +31 -0
- {nonebot_plugin_werewolf-1.1.3.dist-info → nonebot_plugin_werewolf-1.1.5.dist-info}/WHEEL +1 -1
- nonebot_plugin_werewolf/_timeout.py +0 -110
- nonebot_plugin_werewolf-1.1.3.dist-info/RECORD +0 -29
- {nonebot_plugin_werewolf-1.1.3.dist-info → nonebot_plugin_werewolf-1.1.5.dist-info}/LICENSE +0 -0
- {nonebot_plugin_werewolf-1.1.3.dist-info → nonebot_plugin_werewolf-1.1.5.dist-info}/top_level.txt +0 -0
nonebot_plugin_werewolf/utils.py
CHANGED
@@ -1,18 +1,16 @@
|
|
1
|
-
import
|
2
|
-
import itertools
|
3
|
-
import re
|
1
|
+
import functools
|
4
2
|
from collections import defaultdict
|
5
|
-
from typing import Any, ClassVar
|
3
|
+
from typing import TYPE_CHECKING, Any, ClassVar, TypeVar
|
6
4
|
|
7
|
-
import
|
8
|
-
|
9
|
-
from
|
10
|
-
from nonebot.rule import to_me
|
11
|
-
from nonebot.utils import escape_tag
|
12
|
-
from nonebot_plugin_alconna import MsgTarget, Target, UniMessage, UniMsg
|
13
|
-
from nonebot_plugin_uninfo import Uninfo
|
5
|
+
import anyio
|
6
|
+
from nonebot_plugin_alconna import UniMessage
|
7
|
+
from nonebot_plugin_uninfo import Session
|
14
8
|
|
15
|
-
|
9
|
+
if TYPE_CHECKING:
|
10
|
+
from .player_set import PlayerSet
|
11
|
+
from .players import Player
|
12
|
+
|
13
|
+
T = TypeVar("T")
|
16
14
|
|
17
15
|
|
18
16
|
def check_index(text: str, arrlen: int) -> int | None:
|
@@ -23,198 +21,66 @@ def check_index(text: str, arrlen: int) -> int | None:
|
|
23
21
|
return None
|
24
22
|
|
25
23
|
|
26
|
-
|
27
|
-
|
28
|
-
futures: ClassVar[dict[str, asyncio.Future[UniMessage]]] = {}
|
29
|
-
clear_handle: ClassVar[dict[str, asyncio.Handle]] = {}
|
30
|
-
|
31
|
-
@classmethod
|
32
|
-
def clear_lock(cls, key: str) -> None:
|
33
|
-
if key in cls.locks and not cls.locks[key].locked():
|
34
|
-
del cls.locks[key]
|
35
|
-
if key in cls.clear_handle:
|
36
|
-
del cls.clear_handle[key]
|
37
|
-
|
38
|
-
@classmethod
|
39
|
-
async def fetch(cls, user_id: str, group_id: str | None = None) -> UniMessage[Any]:
|
40
|
-
key = f"{group_id}_{user_id}"
|
41
|
-
async with cls.locks[key]:
|
42
|
-
cls.futures[key] = fut = asyncio.get_event_loop().create_future()
|
43
|
-
try:
|
44
|
-
return await fut
|
45
|
-
finally:
|
46
|
-
del cls.futures[key]
|
47
|
-
if key in cls.clear_handle:
|
48
|
-
cls.clear_handle[key].cancel()
|
49
|
-
loop = asyncio.get_event_loop()
|
50
|
-
cls.clear_handle[key] = loop.call_later(120, cls.clear_lock, key)
|
24
|
+
def link(text: str, url: str | None) -> str:
|
25
|
+
return text if url is None else f"\u001b]8;;{url}\u0007{text}\u001b]8;;\u0007"
|
51
26
|
|
52
|
-
@classmethod
|
53
|
-
def put(cls, msg: UniMessage, user_id: str, group_id: str | None = None) -> None:
|
54
|
-
key = f"{group_id}_{user_id}"
|
55
|
-
if (future := cls.futures.get(key)) and not future.cancelled():
|
56
|
-
future.set_result(msg)
|
57
27
|
|
28
|
+
def extract_session_member_nick(session: Session) -> str | None:
|
29
|
+
return (
|
30
|
+
(session.member and session.member.nick)
|
31
|
+
or session.user.nick
|
32
|
+
or session.user.name
|
33
|
+
)
|
58
34
|
|
59
|
-
def user_in_game(self_id: str, user_id: str, group_id: str | None) -> bool:
|
60
|
-
from .game import Game
|
61
35
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
for p in itertools.chain(*[g.players for g in Game.running_games])
|
66
|
-
)
|
36
|
+
class _InputTask:
|
37
|
+
_event: anyio.Event
|
38
|
+
_msg: UniMessage
|
67
39
|
|
68
|
-
def
|
69
|
-
|
40
|
+
def __init__(self) -> None:
|
41
|
+
self._event = anyio.Event()
|
70
42
|
|
71
|
-
|
72
|
-
|
43
|
+
def set(self, msg: UniMessage) -> None:
|
44
|
+
self._msg = msg
|
45
|
+
self._event.set()
|
73
46
|
|
74
|
-
|
47
|
+
async def wait(self) -> UniMessage:
|
48
|
+
await self._event.wait()
|
49
|
+
return self._msg
|
75
50
|
|
76
51
|
|
77
|
-
|
78
|
-
|
52
|
+
class InputStore:
|
53
|
+
locks: ClassVar[dict[str, anyio.Lock]] = defaultdict(anyio.Lock)
|
54
|
+
tasks: ClassVar[dict[str, _InputTask]] = {}
|
79
55
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
56
|
+
@classmethod
|
57
|
+
async def fetch(cls, user_id: str, group_id: str | None = None) -> UniMessage[Any]:
|
58
|
+
key = f"{group_id}_{user_id}"
|
59
|
+
async with cls.locks[key]:
|
60
|
+
cls.tasks[key] = task = _InputTask()
|
61
|
+
return await task.wait()
|
85
62
|
|
63
|
+
@classmethod
|
64
|
+
def put(cls, msg: UniMessage, user_id: str, group_id: str | None = None) -> None:
|
65
|
+
key = f"{group_id}_{user_id}"
|
66
|
+
if task := cls.tasks.pop(key, None):
|
67
|
+
task.set(msg)
|
86
68
|
|
87
|
-
|
88
|
-
|
69
|
+
@classmethod
|
70
|
+
def cleanup(cls, players: list[str], group_id: str) -> None:
|
71
|
+
for key in (f"{g}_{p}" for p in players for g in (group_id, None)):
|
72
|
+
if key in cls.locks:
|
73
|
+
del cls.locks[key]
|
74
|
+
if key in cls.tasks:
|
75
|
+
del cls.tasks[key]
|
89
76
|
|
90
77
|
|
91
|
-
|
92
|
-
|
78
|
+
@functools.cache
|
79
|
+
def cached_player_set() -> type["PlayerSet"]:
|
80
|
+
from .player_set import PlayerSet
|
93
81
|
|
82
|
+
return PlayerSet
|
94
83
|
|
95
|
-
async def _prepare_game_receive(
|
96
|
-
queue: asyncio.Queue[tuple[str, str, str]],
|
97
|
-
event: Event,
|
98
|
-
group: Target,
|
99
|
-
) -> None:
|
100
|
-
async def same_group(target: MsgTarget) -> bool:
|
101
|
-
return group.verify(target)
|
102
84
|
|
103
|
-
|
104
|
-
|
105
|
-
keep_session=False,
|
106
|
-
rule=to_me() & same_group & rule_not_in_game,
|
107
|
-
)
|
108
|
-
def wait(
|
109
|
-
event: Event,
|
110
|
-
msg: UniMsg,
|
111
|
-
session: Uninfo,
|
112
|
-
) -> tuple[str, str, str]:
|
113
|
-
user_id = event.get_user_id()
|
114
|
-
name = session.user.nick or session.user.name or user_id
|
115
|
-
if session.member:
|
116
|
-
name = session.member.nick or name
|
117
|
-
return (
|
118
|
-
user_id,
|
119
|
-
msg.extract_plain_text().strip(),
|
120
|
-
name,
|
121
|
-
)
|
122
|
-
|
123
|
-
async for user, text, name in wait(default=(None, "", "")):
|
124
|
-
if user is None:
|
125
|
-
continue
|
126
|
-
await queue.put((user, text, re.sub(r"[\u2066-\u2069]", "", name)))
|
127
|
-
|
128
|
-
|
129
|
-
async def _prepare_game_handle(
|
130
|
-
queue: asyncio.Queue[tuple[str, str, str]],
|
131
|
-
players: dict[str, str],
|
132
|
-
admin_id: str,
|
133
|
-
) -> None:
|
134
|
-
logger = nonebot.logger.opt(colors=True)
|
135
|
-
|
136
|
-
while True:
|
137
|
-
user, text, name = await queue.get()
|
138
|
-
msg = UniMessage.at(user).text("\n")
|
139
|
-
colored = f"<y>{escape_tag(name)}</y>(<c>{escape_tag(user)}</c>)"
|
140
|
-
|
141
|
-
match (text, user == admin_id):
|
142
|
-
case ("开始游戏", True):
|
143
|
-
player_num = len(players)
|
144
|
-
role_preset = config.get_role_preset()
|
145
|
-
if player_num < min(role_preset):
|
146
|
-
await (
|
147
|
-
msg.text(f"⚠️游戏至少需要 {min(role_preset)} 人, ")
|
148
|
-
.text(f"当前已有 {player_num} 人")
|
149
|
-
.send()
|
150
|
-
)
|
151
|
-
elif player_num > max(role_preset):
|
152
|
-
await (
|
153
|
-
msg.text(f"⚠️游戏最多需要 {max(role_preset)} 人, ")
|
154
|
-
.text(f"当前已有 {player_num} 人")
|
155
|
-
.send()
|
156
|
-
)
|
157
|
-
elif player_num not in role_preset:
|
158
|
-
await (
|
159
|
-
msg.text(f"⚠️不存在总人数为 {player_num} 的预设, ")
|
160
|
-
.text("无法开始游戏")
|
161
|
-
.send()
|
162
|
-
)
|
163
|
-
else:
|
164
|
-
await msg.text("✏️游戏即将开始...").send()
|
165
|
-
logger.info(f"游戏发起者 {colored} 开始游戏")
|
166
|
-
return
|
167
|
-
|
168
|
-
case ("开始游戏", False):
|
169
|
-
await msg.text("⚠️只有游戏发起者可以开始游戏").send()
|
170
|
-
|
171
|
-
case ("结束游戏", True):
|
172
|
-
logger.info(f"游戏发起者 {colored} 结束游戏")
|
173
|
-
await msg.text("ℹ️已结束当前游戏").finish()
|
174
|
-
|
175
|
-
case ("结束游戏", False):
|
176
|
-
await msg.text("⚠️只有游戏发起者可以结束游戏").send()
|
177
|
-
|
178
|
-
case ("加入游戏", True):
|
179
|
-
await msg.text("ℹ️游戏发起者已经加入游戏了").send()
|
180
|
-
|
181
|
-
case ("加入游戏", False):
|
182
|
-
if user not in players:
|
183
|
-
players[user] = name
|
184
|
-
logger.info(f"玩家 {colored} 加入游戏")
|
185
|
-
await msg.text("✅成功加入游戏").send()
|
186
|
-
else:
|
187
|
-
await msg.text("ℹ️你已经加入游戏了").send()
|
188
|
-
|
189
|
-
case ("退出游戏", True):
|
190
|
-
await msg.text("ℹ️游戏发起者无法退出游戏").send()
|
191
|
-
|
192
|
-
case ("退出游戏", False):
|
193
|
-
if user in players:
|
194
|
-
del players[user]
|
195
|
-
logger.info(f"玩家 {colored} 退出游戏")
|
196
|
-
await msg.text("✅成功退出游戏").send()
|
197
|
-
else:
|
198
|
-
await msg.text("ℹ️你还没有加入游戏").send()
|
199
|
-
|
200
|
-
case ("当前玩家", _):
|
201
|
-
msg.text("✨当前玩家:\n")
|
202
|
-
for idx, name in enumerate(players.values(), 1):
|
203
|
-
msg.text(f"\n{idx}. {name}")
|
204
|
-
await msg.send()
|
205
|
-
|
206
|
-
|
207
|
-
async def prepare_game(event: Event, players: dict[str, str]) -> None:
|
208
|
-
from .game import Game
|
209
|
-
|
210
|
-
group = UniMessage.get_target(event)
|
211
|
-
Game.starting_games[group] = players
|
212
|
-
|
213
|
-
queue: asyncio.Queue[tuple[str, str, str]] = asyncio.Queue()
|
214
|
-
task_receive = asyncio.create_task(_prepare_game_receive(queue, event, group))
|
215
|
-
|
216
|
-
try:
|
217
|
-
await _prepare_game_handle(queue, players, event.get_user_id())
|
218
|
-
finally:
|
219
|
-
task_receive.cancel()
|
220
|
-
del Game.starting_games[group]
|
85
|
+
def as_player_set(*player: "Player") -> "PlayerSet":
|
86
|
+
return cached_player_set()(player)
|
{nonebot_plugin_werewolf-1.1.3.dist-info → nonebot_plugin_werewolf-1.1.5.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: nonebot-plugin-werewolf
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.5
|
4
4
|
Summary: 适用于 Nonebot2 的狼人杀插件
|
5
5
|
Author-email: wyf7685 <wyf7685@163.com>
|
6
6
|
License: MIT
|
@@ -14,6 +14,7 @@ Requires-Dist: nonebot2 >=2.3.3
|
|
14
14
|
Requires-Dist: nonebot-plugin-alconna >=0.52.1
|
15
15
|
Requires-Dist: nonebot-plugin-uninfo >=0.4.0
|
16
16
|
Requires-Dist: nonebot-plugin-waiter >=0.7.1
|
17
|
+
Requires-Dist: anyio >=4.6.0
|
17
18
|
|
18
19
|
<div align="center">
|
19
20
|
<a href="https://v2.nonebot.dev/store">
|
@@ -42,6 +43,7 @@ _✨ 简单的狼人杀插件 ✨_
|
|
42
43
|
[](https://github.com/wyf7685/nonebot-plugin-werewolf/actions/workflows/pyright.yml)
|
43
44
|
[](https://github.com/wyf7685/nonebot-plugin-werewolf/actions/workflows/pypi-publish.yml)
|
44
45
|
|
46
|
+
<!-- https://github.com/lgc2333/nonebot-registry-badge -->
|
45
47
|
[](https://registry.nonebot.dev/plugin/nonebot-plugin-werewolf:nonebot_plugin_werewolf)
|
46
48
|
[](https://registry.nonebot.dev/plugin/nonebot-plugin-werewolf:nonebot_plugin_werewolf)
|
47
49
|
|
@@ -148,7 +150,7 @@ _✨ 简单的狼人杀插件 ✨_
|
|
148
150
|
|
149
151
|
_其他交互参考游戏内提示_
|
150
152
|
|
151
|
-
对于 `OneBot V11`
|
153
|
+
对于 `OneBot V11` 适配器和 `Satori` 适配器的 `chronocat`, 启用配置项 `werewolf__enable_poke` 后, 可以使用戳一戳代替 _准备阶段_ 的 `加入游戏` 操作 和 游戏内的 `stop` 命令
|
152
154
|
|
153
155
|
### 游戏内容
|
154
156
|
|
@@ -236,6 +238,10 @@ werewolf__priesthood_proirity=[11, 12, 13, 14, 15]
|
|
236
238
|
|
237
239
|
</details>
|
238
240
|
|
241
|
+
### 已知问题
|
242
|
+
|
243
|
+
- 截止 chronocat v0.2.19, 调用 [`guild.member.get`](https://github.com/chrononeko/chronocat/blob/8558ad9ff4319395d86abbfda22136939bf66780/packages/engine-chronocat-api/src/api/guild/member/get.ts) / [`user.get`](https://github.com/chrononeko/chronocat/blob/8558ad9ff4319395d86abbfda22136939bf66780/packages/engine-chronocat-api/src/api/user/get.ts) 均无法获取用户名,这将导致在交互过程中的玩家名显示为用户ID
|
244
|
+
|
239
245
|
## 📝 更新日志
|
240
246
|
|
241
247
|
<details>
|
@@ -243,6 +249,12 @@ werewolf__priesthood_proirity=[11, 12, 13, 14, 15]
|
|
243
249
|
|
244
250
|
<!-- CHANGELOG -->
|
245
251
|
|
252
|
+
- 2024.10.23 v1.1.5
|
253
|
+
|
254
|
+
- 添加对 chronocat:poke 的支持
|
255
|
+
- 游戏内 stop 命令使用 COMMAND_START
|
256
|
+
- 使用 `anyio` 重写并发逻辑
|
257
|
+
|
246
258
|
- 2024.10.06 v1.1.3
|
247
259
|
|
248
260
|
- 使用 `RF-Tar-Railt/nonebot-plugin-uninfo` 获取用户数据
|
@@ -0,0 +1,31 @@
|
|
1
|
+
nonebot_plugin_werewolf/__init__.py,sha256=v65nKZbsbmaJPR0o2ZrXuumUvCuEOvDVtVmw65CyVn8,894
|
2
|
+
nonebot_plugin_werewolf/config.py,sha256=FKQDkb57ujcBYJZX-sLgxWmTVqSeR7T1ywphp7GOCcE,2803
|
3
|
+
nonebot_plugin_werewolf/constant.py,sha256=d4Awy96YBe_AJoAZyd_6Wojo0qi2BTVM_LW-nDbsxQE,2902
|
4
|
+
nonebot_plugin_werewolf/exception.py,sha256=YSwxeogIB0YJqH9MP1bgxojiu-I_xQE44XnSk5bC1AQ,400
|
5
|
+
nonebot_plugin_werewolf/game.py,sha256=yUfJtLWH7--TRPnofAGfrUkUvd_3VW1J9j8zhTrN9hc,19106
|
6
|
+
nonebot_plugin_werewolf/player_set.py,sha256=J5KFWSugpu1Zd_gToqa-Gweoikj8kppLpckVjl-4XH0,2540
|
7
|
+
nonebot_plugin_werewolf/utils.py,sha256=6uFwgf4LAI1SZ_qH6I2ilHt2vbs6NfTj5YhMvC4GacE,2279
|
8
|
+
nonebot_plugin_werewolf/matchers/__init__.py,sha256=_MwAZsXlpBLXyzHWqNLTQdMWw9z_O01L5Yo02dzGC9I,88
|
9
|
+
nonebot_plugin_werewolf/matchers/depends.py,sha256=6JFLxQDgRjStbMkpoWe1tYZHs0wVfsyn4KikKNpgx0Q,1160
|
10
|
+
nonebot_plugin_werewolf/matchers/message_in_game.py,sha256=YkphERN2efaB0VdU3oTCvvYptrqDaKFKUb9moUyqIpY,780
|
11
|
+
nonebot_plugin_werewolf/matchers/start_game.py,sha256=ZNO2ypV8kMlImR0fZVhg0ZI8mrOsW3I-eioT6Lhf2Cw,7427
|
12
|
+
nonebot_plugin_werewolf/matchers/poke/__init__.py,sha256=gYysvGjztN3iDQpX6v5nkPT195FXnk7fqP9kzByTES0,220
|
13
|
+
nonebot_plugin_werewolf/matchers/poke/chronocat_poke.py,sha256=SrFN8dQELFVDR5US9sOcE2gaOnH7AFiRVVK2RNa-Y5o,4023
|
14
|
+
nonebot_plugin_werewolf/matchers/poke/ob11_poke.py,sha256=LROxtbauw4xbB8UKglsx6b6hkKWs_17HmgK4NTXW1HY,2640
|
15
|
+
nonebot_plugin_werewolf/players/__init__.py,sha256=djAI5XxR2I-XvnH-lVqX_YCHB_AiT-6jdmwFE1ffN_0,379
|
16
|
+
nonebot_plugin_werewolf/players/can_shoot.py,sha256=e9QtRUNxNZ9n3MxX7o0bUmQLLPDazTOZky3F_2m6UhM,1813
|
17
|
+
nonebot_plugin_werewolf/players/civilian.py,sha256=TbrIxjG4g74C9Cd_F3OskuM-ksKUkOLiE6OgPqmo0pA,157
|
18
|
+
nonebot_plugin_werewolf/players/guard.py,sha256=T2L7f0Dcx6jjlOrGcHUQxy9RawszvP6AKaI8Lz9nItI,1112
|
19
|
+
nonebot_plugin_werewolf/players/hunter.py,sha256=NaJNjngKCHC8RI1YsYI5XtVyFq9JP5U1ywOTbjjUHq4,195
|
20
|
+
nonebot_plugin_werewolf/players/idiot.py,sha256=Tpjf7RPW1dJ3J4ajr5HWcIustHO-h6PNicum4SiofDE,1433
|
21
|
+
nonebot_plugin_werewolf/players/joker.py,sha256=J_t-IPKjyHWq8azxFdN_cmJhbgoDcokiMLf-pMXQInE,691
|
22
|
+
nonebot_plugin_werewolf/players/player.py,sha256=JUCev-3jnAqApNR-cFaHRHkQVIgBfn5HhHhLq8OGWgw,6954
|
23
|
+
nonebot_plugin_werewolf/players/prophet.py,sha256=VQa4RJUbLpG9ntB055ORl09oEAmZ1uOUi4P4q_P_9TY,897
|
24
|
+
nonebot_plugin_werewolf/players/werewolf.py,sha256=MZOsHWNnKvh_fxKMEIWqa_yJIYHVjA1fM5W3jkg_CtU,3433
|
25
|
+
nonebot_plugin_werewolf/players/witch.py,sha256=XDCVSXhUA9afh0iCdxV8Shfc1YGDkXYhu1h0v1xpbmg,2340
|
26
|
+
nonebot_plugin_werewolf/players/wolfking.py,sha256=oBC5JW0UULDkthurDBvHRNo3rqArm-zQ_1jSuyeHpQU,440
|
27
|
+
nonebot_plugin_werewolf-1.1.5.dist-info/LICENSE,sha256=B_WbEqjGr6GYVNfEJPY31T1Opik7OtgOkhRs4Ig3e2M,1064
|
28
|
+
nonebot_plugin_werewolf-1.1.5.dist-info/METADATA,sha256=j-vwRZiK1lobgZ10-X30Upf6Vuo1ZYMraWgQvStKjvI,11435
|
29
|
+
nonebot_plugin_werewolf-1.1.5.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
30
|
+
nonebot_plugin_werewolf-1.1.5.dist-info/top_level.txt,sha256=wLTfg8sTKbH9lLT9LtU118C9cTspEBJareLsrYM52YA,24
|
31
|
+
nonebot_plugin_werewolf-1.1.5.dist-info/RECORD,,
|
@@ -1,110 +0,0 @@
|
|
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,29 +0,0 @@
|
|
1
|
-
nonebot_plugin_werewolf/__init__.py,sha256=Im_u8hP6N6qA2SwnNSGu1MsewLoyHUa3v0Paj1yC3T0,862
|
2
|
-
nonebot_plugin_werewolf/_timeout.py,sha256=MVkA5oMoxOTV8Luc0BH2QPP8wwz4Tr9CJjeYgiPu_O4,3649
|
3
|
-
nonebot_plugin_werewolf/config.py,sha256=FKQDkb57ujcBYJZX-sLgxWmTVqSeR7T1ywphp7GOCcE,2803
|
4
|
-
nonebot_plugin_werewolf/constant.py,sha256=-S-KjlrSc_wJwsXCkQOMFVqyu4RwR4GLXIRZEp_0mlI,2300
|
5
|
-
nonebot_plugin_werewolf/exception.py,sha256=YSwxeogIB0YJqH9MP1bgxojiu-I_xQE44XnSk5bC1AQ,400
|
6
|
-
nonebot_plugin_werewolf/game.py,sha256=LWxn2OCnkTAF8NdLt1BQzyAtyUfk477xisCf5mbfK_E,17376
|
7
|
-
nonebot_plugin_werewolf/player_set.py,sha256=BlK7wHv_9YrCINMAPWL36TLkRjAiI_GXSHlZySVemoo,2777
|
8
|
-
nonebot_plugin_werewolf/utils.py,sha256=50bJGhJU7b9kQEqmc2V8-5wYkukilDtchZBSBKcwwq4,7633
|
9
|
-
nonebot_plugin_werewolf/matchers/__init__.py,sha256=_MwAZsXlpBLXyzHWqNLTQdMWw9z_O01L5Yo02dzGC9I,88
|
10
|
-
nonebot_plugin_werewolf/matchers/message_in_game.py,sha256=hpQCaNaxCikma8DJTJLCttP5B1vBWlqMDEukSqfPlRk,452
|
11
|
-
nonebot_plugin_werewolf/matchers/ob11_ext.py,sha256=TGhI4yWfb5N3K9hXkI8k8Rs6cMVXDwp05cXtu3a-_jU,2597
|
12
|
-
nonebot_plugin_werewolf/matchers/start_game.py,sha256=DZPQ88hiobuJejIbKsIc8ZcoKDw7wcjawWfTC3wjIto,1884
|
13
|
-
nonebot_plugin_werewolf/players/__init__.py,sha256=djAI5XxR2I-XvnH-lVqX_YCHB_AiT-6jdmwFE1ffN_0,379
|
14
|
-
nonebot_plugin_werewolf/players/can_shoot.py,sha256=6u_luXfNOWO0svTpb78h74HcG65kh1GZyFPJFYNuOG0,2068
|
15
|
-
nonebot_plugin_werewolf/players/civilian.py,sha256=6iKEWRRWDGq1qgVZZZ9pX7kBVpMN-yfxeLq9hIp17hU,165
|
16
|
-
nonebot_plugin_werewolf/players/guard.py,sha256=pDH66q-KoU5oRD-tn542x3siXv9BM824-KRxsVb0Gvk,1408
|
17
|
-
nonebot_plugin_werewolf/players/hunter.py,sha256=nqYGCVppd4mdCPhFHZbjbbNvZfyCNT0bZ3raQFXmELA,203
|
18
|
-
nonebot_plugin_werewolf/players/idiot.py,sha256=7-BTsYUSOcs5rPOJx1hsHPOWcmGcv2rSO8IfUGPdqEE,1456
|
19
|
-
nonebot_plugin_werewolf/players/joker.py,sha256=uUK6EuoOWd8_35yvBTkM14XCplOFwFCRsbhR7bjeiD8,699
|
20
|
-
nonebot_plugin_werewolf/players/player.py,sha256=ejEjbsrIKpUJql3-qLMFsZY_jGFtQ3OTjcN1lFZ4yKo,4697
|
21
|
-
nonebot_plugin_werewolf/players/prophet.py,sha256=nh8eB9T9LMBiqNgnqE-ygAFiYvTZS8bGUKYsNBPm8F0,1078
|
22
|
-
nonebot_plugin_werewolf/players/werewolf.py,sha256=kyZjwijEGG0EkP80VOlu8HFzReg33v8a-o670fZN_xI,2560
|
23
|
-
nonebot_plugin_werewolf/players/witch.py,sha256=P1odgjFc9kAIUxmlz9aV69aYzl76OVcsQQGhigmRTgc,2571
|
24
|
-
nonebot_plugin_werewolf/players/wolfking.py,sha256=hgxOugrIOF6wC5wKcjflPuQ2K4d99eWpF9E69ishbsg,440
|
25
|
-
nonebot_plugin_werewolf-1.1.3.dist-info/LICENSE,sha256=B_WbEqjGr6GYVNfEJPY31T1Opik7OtgOkhRs4Ig3e2M,1064
|
26
|
-
nonebot_plugin_werewolf-1.1.3.dist-info/METADATA,sha256=uLZxheMxeLRL70cOrpZtr1Nqy2gP1sAIFNiiNtkEwi4,10707
|
27
|
-
nonebot_plugin_werewolf-1.1.3.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
28
|
-
nonebot_plugin_werewolf-1.1.3.dist-info/top_level.txt,sha256=wLTfg8sTKbH9lLT9LtU118C9cTspEBJareLsrYM52YA,24
|
29
|
-
nonebot_plugin_werewolf-1.1.3.dist-info/RECORD,,
|
File without changes
|
{nonebot_plugin_werewolf-1.1.3.dist-info → nonebot_plugin_werewolf-1.1.5.dist-info}/top_level.txt
RENAMED
File without changes
|