nonebot-plugin-werewolf 1.1.9__py3-none-any.whl → 1.1.10__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.
@@ -10,7 +10,7 @@ from . import matchers as matchers
10
10
  from . import players as players
11
11
  from .config import Config
12
12
 
13
- __version__ = "1.1.9"
13
+ __version__ = "1.1.10"
14
14
  __plugin_meta__ = PluginMetadata(
15
15
  name="狼人杀",
16
16
  description="适用于 Nonebot2 的狼人杀插件",
@@ -1,7 +1,7 @@
1
1
  import contextlib
2
2
  import functools
3
3
  import secrets
4
- from collections import defaultdict
4
+ from collections import Counter
5
5
  from typing import NoReturn, final
6
6
  from typing_extensions import Self
7
7
 
@@ -162,11 +162,10 @@ class Game:
162
162
  self.state = GameState(0)
163
163
  self.killed_players = []
164
164
  self._player_map: dict[str, Player] = {}
165
+ self._shuffled: list[Player] = []
165
166
  self._scene = None
166
- self._finished = None
167
- self._task_group = None
168
- self._send_handler = _SendHandler()
169
- self._send_handler.update(group, bot)
167
+ self._finished = self._task_group = None
168
+ self._send_handler = _SendHandler(group, bot)
170
169
 
171
170
  @final
172
171
  @classmethod
@@ -185,6 +184,7 @@ class Game:
185
184
 
186
185
  self.players = await init_players(bot, self, players, interface)
187
186
  self._player_map |= {p.user_id: p for p in self.players}
187
+ self._shuffled = self.players.shuffled
188
188
 
189
189
  return self
190
190
 
@@ -258,12 +258,9 @@ class Game:
258
258
  )
259
259
 
260
260
  if self.behavior.show_roles_list_on_start:
261
- role_cnt: dict[Role, int] = defaultdict(lambda: 0)
262
- for role in sorted((p.role for p in self.players), key=lambda r: r.value):
263
- role_cnt[role] += 1
264
-
265
261
  msg.text("\n\n📚职业列表:\n")
266
- for role, cnt in role_cnt.items():
262
+ counter = Counter(p.role for p in self.players)
263
+ for role, cnt in sorted(counter.items(), key=lambda x: x[0].value):
267
264
  msg.text(f"- {ROLE_EMOJI[role]}{ROLE_NAME_CONV[role]}x{cnt}\n")
268
265
 
269
266
  async with anyio.create_task_group() as tg:
@@ -340,23 +337,24 @@ class Game:
340
337
  timeout = self.behavior.timeout
341
338
 
342
339
  if not self.behavior.speak_in_turn:
343
- speak_timeout = timeout.group_speak
344
340
  await self.send(
345
341
  f"💬接下来开始自由讨论\n{timeout.group_speak_timeout_prompt}",
346
342
  stop_btn_label="结束发言",
347
343
  )
348
- await self.wait_stop(*self.players.alive(), timeout_secs=speak_timeout)
344
+ await self.wait_stop(
345
+ *self.players.alive(),
346
+ timeout_secs=timeout.group_speak,
347
+ )
349
348
  else:
350
349
  await self.send("💬接下来开始轮流发言")
351
- speak_timeout = timeout.speak
352
- for player in self.players.alive().sorted:
350
+ for player in filter(lambda p: p.alive, self._shuffled):
353
351
  await self.send(
354
352
  UniMessage.text("💬")
355
353
  .at(player.user_id)
356
354
  .text(f"\n轮到你发言\n{timeout.speak_timeout_prompt}"),
357
355
  stop_btn_label="结束发言",
358
356
  )
359
- await self.wait_stop(player, timeout_secs=speak_timeout)
357
+ await self.wait_stop(player, timeout_secs=timeout.speak)
360
358
  await self.send("💬所有玩家发言结束")
361
359
 
362
360
  async def run_vote(self) -> None:
@@ -145,7 +145,10 @@ async def set_dead_chat(behavior: Behavior, limit: int) -> None:
145
145
  @edit_behavior.assign("werewolf_multi_select")
146
146
  async def set_werewolf_multi_select(behavior: Behavior, enabled: bool) -> None:
147
147
  behavior.werewolf_multi_select = enabled
148
- await finish(f"已{'启用' if enabled else '禁用'}狼人多选")
148
+ await finish(
149
+ f"已{'启用' if enabled else '禁用'}狼人多选\n"
150
+ "注: 狼人意见未统一时随机选择已选玩家"
151
+ )
149
152
 
150
153
 
151
154
  @edit_behavior.assign("timeout.prepare")
@@ -205,13 +208,14 @@ async def handle_default(behavior: Behavior) -> None:
205
208
  f"游戏开始发送职业列表: {'是' if behavior.show_roles_list_on_start else '否'}",
206
209
  f"白天讨论按顺序发言: {'是' if behavior.speak_in_turn else '否'}",
207
210
  f"死亡玩家发言转发限制: {behavior.dead_channel_rate_limit} 次/分钟",
211
+ f"狼人多选(意见未统一时随机选择已选玩家): {'是' if behavior.werewolf_multi_select else '否'}", # noqa: E501
208
212
  "",
209
213
  "超时时间设置:",
210
214
  f"准备阶段: {timeout.prepare} 秒",
211
215
  f"个人发言: {timeout.speak} 秒",
212
216
  f"集体发言: {timeout.group_speak} 秒",
213
- f"交互阶段: {timeout.interact} 秒",
214
217
  f"投票阶段: {timeout.vote} 秒",
218
+ f"交互阶段: {timeout.interact} 秒",
215
219
  f"狼人交互: {timeout.werewolf} 秒",
216
220
  ]
217
221
  await finish("\n".join(lines))
@@ -129,8 +129,7 @@ class Player:
129
129
  self.bot = bot
130
130
  self.killed = anyio.Event()
131
131
  self._member = None
132
- self._send_handler = _SendHandler()
133
- self._send_handler.update(self.__user, bot)
132
+ self._send_handler = _SendHandler(self.__user, bot)
134
133
 
135
134
  @final
136
135
  @override
@@ -190,11 +190,19 @@ def add_players_button(msg: str | UniMessage, players: "PlayerSet") -> UniMessag
190
190
 
191
191
  class SendHandler(abc.ABC, Generic[P]):
192
192
  bot: Bot
193
- target: Event | Target
193
+ target: Event | Target | None
194
194
  reply_to: bool | None = None
195
195
  last_msg: UniMessage | None = None
196
196
  last_receipt: Receipt | None = None
197
197
 
198
+ def __init__(
199
+ self,
200
+ target: Event | Target | None = None,
201
+ bot: Bot | None = None,
202
+ ) -> None:
203
+ self.bot = bot or current_bot.get()
204
+ self.target = target
205
+
198
206
  def update(self, target: Event | Target, bot: Bot | None = None) -> None:
199
207
  self.bot = bot or current_bot.get()
200
208
  self.target = target
@@ -210,6 +218,9 @@ class SendHandler(abc.ABC, Generic[P]):
210
218
  await last.edit(self.last_msg.exclude(Keyboard))
211
219
 
212
220
  async def _send(self, message: UniMessage) -> None:
221
+ if self.target is None:
222
+ raise RuntimeError("Target cannot be None when sending a message.")
223
+
213
224
  if not config.enable_button:
214
225
  message = message.exclude(Keyboard)
215
226
  receipt = await message.send(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nonebot-plugin-werewolf
3
- Version: 1.1.9
3
+ Version: 1.1.10
4
4
  Summary: 适用于 Nonebot2 的狼人杀插件
5
5
  Author-email: wyf7685 <wyf7685@163.com>
6
6
  License: MIT
@@ -240,6 +240,11 @@ _✨ 简单的狼人杀插件 ✨_
240
240
 
241
241
  <!-- CHANGELOG -->
242
242
 
243
+ - 2025.04.17 v1.1.10
244
+
245
+ - 添加狼人多选目标配置项显示
246
+ - 在游戏开始时打乱并固定轮流发言模式的发言顺序
247
+
243
248
  - 2025.04.15 v1.1.9
244
249
 
245
250
  - 添加游戏行为配置 `werewolf_multi_select`
@@ -1,15 +1,15 @@
1
- nonebot_plugin_werewolf/__init__.py,sha256=lDOYm3Z6UA_fFXiKT9cGweOiND3X-Y3RAiKB5iqpTVc,931
1
+ nonebot_plugin_werewolf/__init__.py,sha256=ed2tOFc-Q0Rw2OYZFmBVzu2NUKPtSwc2ioYVU0X-Ntk,932
2
2
  nonebot_plugin_werewolf/config.py,sha256=Dlng9cRvTf8dEPFngOobeV3S-TnrVrjs9Eqje8dH1wQ,3160
3
3
  nonebot_plugin_werewolf/constant.py,sha256=NVKMx4CI64hgftJJySa6VnK2K8ZBmGtrAyMxel3HS2o,2053
4
4
  nonebot_plugin_werewolf/exception.py,sha256=SP9RdzsREB6PtpRfhZjxqybtvO0aw48hpN9QMU9jDZY,366
5
- nonebot_plugin_werewolf/game.py,sha256=UL68ftCEgV9h34Xgw1sZPAUbyjIhFhGAdc70w8huWuQ,19438
5
+ nonebot_plugin_werewolf/game.py,sha256=iCduTjl33k-0Mk5MN57Qj-TfGtDKe96aBDvCiTU0AlU,19357
6
6
  nonebot_plugin_werewolf/models.py,sha256=PiQ-5_R-cUlHKWDa5G0bFnz7jv20200_kr449G9Jgjg,2300
7
- nonebot_plugin_werewolf/player.py,sha256=EzV_In8KmlZAx0GGV-Cj9qIJjIefIf7CXzlchCTJvFo,11259
7
+ nonebot_plugin_werewolf/player.py,sha256=1FPsvNkt9d5D2EH7vXCXmDabdcOOAGFcI4Ky9rUe99s,11223
8
8
  nonebot_plugin_werewolf/player_set.py,sha256=RF3aQXLZyUBPa0_G-Q48NUARictMRp6IV2WD-BKtNTQ,2913
9
- nonebot_plugin_werewolf/utils.py,sha256=bwbBLApPWis15_perT89Mmy33gAdaHR8fKJWVnDGh9E,6803
9
+ nonebot_plugin_werewolf/utils.py,sha256=gV01cdGJXdbnxDcm6PWEbFYcgL1sF4rA-y5XzrYwzvU,7122
10
10
  nonebot_plugin_werewolf/matchers/__init__.py,sha256=lQ9AZDEWgtbP-W8KWvjkEYc_UfTHSUwjaGdZ7PT3z0E,219
11
11
  nonebot_plugin_werewolf/matchers/depends.py,sha256=TITA2brcyHSavFA3K_HgqkoQtkwxdM8miyEKafcfZz4,1343
12
- nonebot_plugin_werewolf/matchers/edit_behavior.py,sha256=DaxMS9wcSyYpdhnHHXb0GqRgRNm6LNr5W1vbk-B63n4,7014
12
+ nonebot_plugin_werewolf/matchers/edit_behavior.py,sha256=hppkSB4CJ5FYuT5mWQZ3gwIurBVO_Zz2mBOUA-oV5tU,7231
13
13
  nonebot_plugin_werewolf/matchers/edit_preset.py,sha256=PXABbjhQM0DiKfEqjOMKtSrJs2fKoVh91iTJlVD3hKA,8089
14
14
  nonebot_plugin_werewolf/matchers/message_in_game.py,sha256=Lm9VqZcnAU023SJ6R8LH-3-tSp8KRtmOJ4x4dTZGb1o,969
15
15
  nonebot_plugin_werewolf/matchers/start_game.py,sha256=cFa9KzZ3zEri5Ras1ccFyZQWK8HPcs6KRNZr2ArsdsA,11956
@@ -28,8 +28,8 @@ nonebot_plugin_werewolf/players/shooter.py,sha256=1bWkqcSFX6Crynh3IrlI-2RGrNiP6d
28
28
  nonebot_plugin_werewolf/players/werewolf.py,sha256=7lAJT7FjEt42J04RNAXkfDDIN-1mQOej0NaIo0dEWMQ,5347
29
29
  nonebot_plugin_werewolf/players/witch.py,sha256=flugzsDkpYiMW-BQGvvqwcXHX_UGcsryAnyYKmh07l4,3049
30
30
  nonebot_plugin_werewolf/players/wolfking.py,sha256=CMZ5Tq74wupcRPjAzXHEF2Gts4z3thsD57q64uGp_-c,628
31
- nonebot_plugin_werewolf-1.1.9.dist-info/licenses/LICENSE,sha256=B_WbEqjGr6GYVNfEJPY31T1Opik7OtgOkhRs4Ig3e2M,1064
32
- nonebot_plugin_werewolf-1.1.9.dist-info/METADATA,sha256=ZL27XQ01QhEddypOZDVFVr5cRfB9WO5MUE19o7GA-jQ,11912
33
- nonebot_plugin_werewolf-1.1.9.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
34
- nonebot_plugin_werewolf-1.1.9.dist-info/top_level.txt,sha256=wLTfg8sTKbH9lLT9LtU118C9cTspEBJareLsrYM52YA,24
35
- nonebot_plugin_werewolf-1.1.9.dist-info/RECORD,,
31
+ nonebot_plugin_werewolf-1.1.10.dist-info/licenses/LICENSE,sha256=B_WbEqjGr6GYVNfEJPY31T1Opik7OtgOkhRs4Ig3e2M,1064
32
+ nonebot_plugin_werewolf-1.1.10.dist-info/METADATA,sha256=N3PDI77wVJA-Ps6i9K_KQjDW_Ldq1LPk8qzEFYSF41I,12051
33
+ nonebot_plugin_werewolf-1.1.10.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
34
+ nonebot_plugin_werewolf-1.1.10.dist-info/top_level.txt,sha256=wLTfg8sTKbH9lLT9LtU118C9cTspEBJareLsrYM52YA,24
35
+ nonebot_plugin_werewolf-1.1.10.dist-info/RECORD,,