nonebot-plugin-werewolf 1.1.7__tar.gz → 1.1.8__tar.gz

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.
Files changed (45) hide show
  1. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/PKG-INFO +17 -14
  2. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/README.md +15 -12
  3. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/__init__.py +1 -1
  4. nonebot_plugin_werewolf-1.1.8/nonebot_plugin_werewolf/config.py +103 -0
  5. nonebot_plugin_werewolf-1.1.8/nonebot_plugin_werewolf/constant.py +82 -0
  6. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/exception.py +2 -4
  7. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/game.py +154 -136
  8. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/matchers/__init__.py +1 -0
  9. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/matchers/depends.py +4 -4
  10. nonebot_plugin_werewolf-1.1.8/nonebot_plugin_werewolf/matchers/edit_behavior.py +205 -0
  11. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/matchers/edit_preset.py +11 -11
  12. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/matchers/message_in_game.py +3 -1
  13. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/matchers/poke/chronocat_poke.py +8 -5
  14. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/matchers/poke/ob11_poke.py +3 -3
  15. nonebot_plugin_werewolf-1.1.8/nonebot_plugin_werewolf/matchers/start_game.py +332 -0
  16. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/matchers/superuser_ops.py +3 -3
  17. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/models.py +31 -19
  18. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/player_set.py +10 -8
  19. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/players/__init__.py +1 -1
  20. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/players/can_shoot.py +15 -15
  21. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/players/civilian.py +1 -1
  22. nonebot_plugin_werewolf-1.1.8/nonebot_plugin_werewolf/players/guard.py +33 -0
  23. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/players/hunter.py +1 -1
  24. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/players/idiot.py +3 -3
  25. nonebot_plugin_werewolf-1.1.7/nonebot_plugin_werewolf/players/joker.py → nonebot_plugin_werewolf-1.1.8/nonebot_plugin_werewolf/players/jester.py +4 -5
  26. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/players/player.py +90 -28
  27. nonebot_plugin_werewolf-1.1.8/nonebot_plugin_werewolf/players/prophet.py +24 -0
  28. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/players/werewolf.py +46 -11
  29. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/players/witch.py +29 -12
  30. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/players/wolfking.py +1 -1
  31. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/utils.py +105 -6
  32. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf.egg-info/PKG-INFO +17 -14
  33. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf.egg-info/SOURCES.txt +2 -1
  34. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/pyproject.toml +21 -16
  35. nonebot_plugin_werewolf-1.1.7/nonebot_plugin_werewolf/config.py +0 -45
  36. nonebot_plugin_werewolf-1.1.7/nonebot_plugin_werewolf/constant.py +0 -74
  37. nonebot_plugin_werewolf-1.1.7/nonebot_plugin_werewolf/matchers/start_game.py +0 -294
  38. nonebot_plugin_werewolf-1.1.7/nonebot_plugin_werewolf/players/guard.py +0 -31
  39. nonebot_plugin_werewolf-1.1.7/nonebot_plugin_werewolf/players/prophet.py +0 -23
  40. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/LICENSE +0 -0
  41. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf/matchers/poke/__init__.py +0 -0
  42. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf.egg-info/dependency_links.txt +0 -0
  43. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf.egg-info/requires.txt +0 -0
  44. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/nonebot_plugin_werewolf.egg-info/top_level.txt +0 -0
  45. {nonebot_plugin_werewolf-1.1.7 → nonebot_plugin_werewolf-1.1.8}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: nonebot-plugin-werewolf
3
- Version: 1.1.7
3
+ Version: 1.1.8
4
4
  Summary: 适用于 Nonebot2 的狼人杀插件
5
5
  Author-email: wyf7685 <wyf7685@163.com>
6
6
  License: MIT
@@ -32,20 +32,13 @@ _✨ 简单的狼人杀插件 ✨_
32
32
  [![license](https://img.shields.io/github/license/wyf7685/nonebot-plugin-werewolf.svg)](./LICENSE)
33
33
  [![pypi](https://img.shields.io/pypi/v/nonebot-plugin-werewolf?logo=python&logoColor=edb641)](https://pypi.python.org/pypi/nonebot-plugin-werewolf)
34
34
  [![python](https://img.shields.io/badge/python-3.10+-blue?logo=python&logoColor=edb641)](https://www.python.org/)
35
-
36
- [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
37
35
  [![ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
38
- [![isort](https://img.shields.io/badge/%20imports-isort-%231674b1)](https://pycqa.github.io/isort/)
39
- [![black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
40
- [![pyright](https://img.shields.io/badge/types-pyright-797952.svg?logo=python&logoColor=edb641)](https://github.com/Microsoft/pyright)
41
36
 
42
37
  [![wakatime](https://wakatime.com/badge/user/b097681b-c224-44ec-8e04-e1cf71744655/project/70a7f68d-5625-4989-9476-be6877408332.svg)](https://wakatime.com/badge/user/b097681b-c224-44ec-8e04-e1cf71744655/project/70a7f68d-5625-4989-9476-be6877408332)
43
38
  [![pre-commit](https://results.pre-commit.ci/badge/github/wyf7685/nonebot-plugin-werewolf/master.svg)](https://results.pre-commit.ci/latest/github/wyf7685/nonebot-plugin-werewolf/master)
44
- [![pyright](https://github.com/wyf7685/nonebot-plugin-werewolf/actions/workflows/pyright.yml/badge.svg?branch=master&event=push)](https://github.com/wyf7685/nonebot-plugin-werewolf/actions/workflows/pyright.yml)
45
- [![publish](https://github.com/wyf7685/nonebot-plugin-werewolf/actions/workflows/pypi-publish.yml/badge.svg)](https://github.com/wyf7685/nonebot-plugin-werewolf/actions/workflows/pypi-publish.yml)
39
+ [![lint](https://github.com/wyf7685/nonebot-plugin-werewolf/actions/workflows/lint.yml/badge.svg?branch=master&event=push)](https://github.com/wyf7685/nonebot-plugin-werewolf/actions/workflows/lint.yml)
46
40
 
47
41
  <!-- https://github.com/lgc2333/nonebot-registry-badge -->
48
-
49
42
  [![NoneBot Registry](https://img.shields.io/endpoint?url=https%3A%2F%2Fnbbdg.lgc2333.top%2Fplugin%2Fnonebot-plugin-werewolf)](https://registry.nonebot.dev/plugin/nonebot-plugin-werewolf:nonebot_plugin_werewolf)
50
43
  [![Supported Adapters](https://img.shields.io/endpoint?url=https%3A%2F%2Fnbbdg.lgc2333.top%2Fplugin-adapters%2Fnonebot-plugin-werewolf)](https://registry.nonebot.dev/plugin/nonebot-plugin-werewolf:nonebot_plugin_werewolf)
51
44
 
@@ -108,10 +101,11 @@ _✨ 简单的狼人杀插件 ✨_
108
101
 
109
102
  在 nonebot2 项目的 `.env` 文件中添加如下配置:
110
103
 
111
- | 配置项 | 必填 | 默认值 | 说明 |
112
- | :-----------------------: | :---: | :-----: | :------------------------: |
113
- | `werewolf__enable_poke` | 否 | `True` | 是否使用戳一戳简化操作流程 |
114
- | `werewolf__enable_button` | 否 | `False` | 是否在交互中添加按钮 |
104
+ | 配置项 | 必填 | 默认值 | 说明 |
105
+ | :-----------------------: | :---: | :-----: | :--------------------------: |
106
+ | `werewolf__enable_poke` | 否 | `True` | 是否使用戳一戳简化操作流程 |
107
+ | `werewolf__enable_button` | 否 | `False` | 是否在交互中添加按钮 |
108
+ | `werewolf__stop_command` | 否 | `stop` | 修改游戏进程中的 `stop` 命令 |
115
109
 
116
110
  `werewolf__enable_poke` 仅在 `OneBot V11` 适配器 / `Satori/chronocat` 下生效
117
111
 
@@ -150,11 +144,14 @@ _✨ 简单的狼人杀插件 ✨_
150
144
  | `退出游戏` | 群员 | 否 | 群聊 | _[准备阶段]_ 玩家退出游戏 |
151
145
  | `中止游戏` | 超级用户 | 是 | 群聊 | _[游戏内]_ 超级用户强制中止游戏 |
152
146
  | `狼人杀预设` | 超级用户 | 否 | 任意 | _[游戏外]_ 超级用户编辑游戏预设 |
147
+ | `狼人杀配置` | 超级用户 | 否 | 任意 | _[游戏外]_ 超级用户编辑游戏配置 |
153
148
 
154
149
  - 发起游戏时添加 `restart`/`重开`, 可加载上一次游戏的玩家列表, 快速发起游戏。例: `werewolf restart`/`狼人杀 重开`
155
150
 
156
151
  - `狼人杀预设` 命令用法可通过 `狼人杀预设 --help` 获取,或参考 [游戏内容](#游戏内容) 部分的介绍
157
152
 
153
+ - `狼人杀配置` 命令用法可通过 `狼人杀预设 --help` 获取
154
+
158
155
  - 对于 `OneBot V11` 适配器和 `Satori` 适配器的 `chronocat`, 启用配置项 `werewolf__enable_poke` 后, 可以使用戳一戳代替 _准备阶段_ 的 `加入游戏` 操作 和 游戏内的 `stop` 命令
159
156
 
160
157
  - _其他交互参考游戏内提示_
@@ -242,6 +239,12 @@ _✨ 简单的狼人杀插件 ✨_
242
239
 
243
240
  <!-- CHANGELOG -->
244
241
 
242
+ - 2025.02.13 v1.1.8
243
+
244
+ - 优化交互按钮
245
+ - 新增命令 `狼人杀配置` 用于调整游戏行为
246
+ - 新增配置项 `werewolf__stop_command`
247
+
245
248
  - 2024.10.31 v1.1.7
246
249
 
247
250
  - *Bug fix*
@@ -13,20 +13,13 @@ _✨ 简单的狼人杀插件 ✨_
13
13
  [![license](https://img.shields.io/github/license/wyf7685/nonebot-plugin-werewolf.svg)](./LICENSE)
14
14
  [![pypi](https://img.shields.io/pypi/v/nonebot-plugin-werewolf?logo=python&logoColor=edb641)](https://pypi.python.org/pypi/nonebot-plugin-werewolf)
15
15
  [![python](https://img.shields.io/badge/python-3.10+-blue?logo=python&logoColor=edb641)](https://www.python.org/)
16
-
17
- [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
18
16
  [![ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
19
- [![isort](https://img.shields.io/badge/%20imports-isort-%231674b1)](https://pycqa.github.io/isort/)
20
- [![black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
21
- [![pyright](https://img.shields.io/badge/types-pyright-797952.svg?logo=python&logoColor=edb641)](https://github.com/Microsoft/pyright)
22
17
 
23
18
  [![wakatime](https://wakatime.com/badge/user/b097681b-c224-44ec-8e04-e1cf71744655/project/70a7f68d-5625-4989-9476-be6877408332.svg)](https://wakatime.com/badge/user/b097681b-c224-44ec-8e04-e1cf71744655/project/70a7f68d-5625-4989-9476-be6877408332)
24
19
  [![pre-commit](https://results.pre-commit.ci/badge/github/wyf7685/nonebot-plugin-werewolf/master.svg)](https://results.pre-commit.ci/latest/github/wyf7685/nonebot-plugin-werewolf/master)
25
- [![pyright](https://github.com/wyf7685/nonebot-plugin-werewolf/actions/workflows/pyright.yml/badge.svg?branch=master&event=push)](https://github.com/wyf7685/nonebot-plugin-werewolf/actions/workflows/pyright.yml)
26
- [![publish](https://github.com/wyf7685/nonebot-plugin-werewolf/actions/workflows/pypi-publish.yml/badge.svg)](https://github.com/wyf7685/nonebot-plugin-werewolf/actions/workflows/pypi-publish.yml)
20
+ [![lint](https://github.com/wyf7685/nonebot-plugin-werewolf/actions/workflows/lint.yml/badge.svg?branch=master&event=push)](https://github.com/wyf7685/nonebot-plugin-werewolf/actions/workflows/lint.yml)
27
21
 
28
22
  <!-- https://github.com/lgc2333/nonebot-registry-badge -->
29
-
30
23
  [![NoneBot Registry](https://img.shields.io/endpoint?url=https%3A%2F%2Fnbbdg.lgc2333.top%2Fplugin%2Fnonebot-plugin-werewolf)](https://registry.nonebot.dev/plugin/nonebot-plugin-werewolf:nonebot_plugin_werewolf)
31
24
  [![Supported Adapters](https://img.shields.io/endpoint?url=https%3A%2F%2Fnbbdg.lgc2333.top%2Fplugin-adapters%2Fnonebot-plugin-werewolf)](https://registry.nonebot.dev/plugin/nonebot-plugin-werewolf:nonebot_plugin_werewolf)
32
25
 
@@ -89,10 +82,11 @@ _✨ 简单的狼人杀插件 ✨_
89
82
 
90
83
  在 nonebot2 项目的 `.env` 文件中添加如下配置:
91
84
 
92
- | 配置项 | 必填 | 默认值 | 说明 |
93
- | :-----------------------: | :---: | :-----: | :------------------------: |
94
- | `werewolf__enable_poke` | 否 | `True` | 是否使用戳一戳简化操作流程 |
95
- | `werewolf__enable_button` | 否 | `False` | 是否在交互中添加按钮 |
85
+ | 配置项 | 必填 | 默认值 | 说明 |
86
+ | :-----------------------: | :---: | :-----: | :--------------------------: |
87
+ | `werewolf__enable_poke` | 否 | `True` | 是否使用戳一戳简化操作流程 |
88
+ | `werewolf__enable_button` | 否 | `False` | 是否在交互中添加按钮 |
89
+ | `werewolf__stop_command` | 否 | `stop` | 修改游戏进程中的 `stop` 命令 |
96
90
 
97
91
  `werewolf__enable_poke` 仅在 `OneBot V11` 适配器 / `Satori/chronocat` 下生效
98
92
 
@@ -131,11 +125,14 @@ _✨ 简单的狼人杀插件 ✨_
131
125
  | `退出游戏` | 群员 | 否 | 群聊 | _[准备阶段]_ 玩家退出游戏 |
132
126
  | `中止游戏` | 超级用户 | 是 | 群聊 | _[游戏内]_ 超级用户强制中止游戏 |
133
127
  | `狼人杀预设` | 超级用户 | 否 | 任意 | _[游戏外]_ 超级用户编辑游戏预设 |
128
+ | `狼人杀配置` | 超级用户 | 否 | 任意 | _[游戏外]_ 超级用户编辑游戏配置 |
134
129
 
135
130
  - 发起游戏时添加 `restart`/`重开`, 可加载上一次游戏的玩家列表, 快速发起游戏。例: `werewolf restart`/`狼人杀 重开`
136
131
 
137
132
  - `狼人杀预设` 命令用法可通过 `狼人杀预设 --help` 获取,或参考 [游戏内容](#游戏内容) 部分的介绍
138
133
 
134
+ - `狼人杀配置` 命令用法可通过 `狼人杀预设 --help` 获取
135
+
139
136
  - 对于 `OneBot V11` 适配器和 `Satori` 适配器的 `chronocat`, 启用配置项 `werewolf__enable_poke` 后, 可以使用戳一戳代替 _准备阶段_ 的 `加入游戏` 操作 和 游戏内的 `stop` 命令
140
137
 
141
138
  - _其他交互参考游戏内提示_
@@ -223,6 +220,12 @@ _✨ 简单的狼人杀插件 ✨_
223
220
 
224
221
  <!-- CHANGELOG -->
225
222
 
223
+ - 2025.02.13 v1.1.8
224
+
225
+ - 优化交互按钮
226
+ - 新增命令 `狼人杀配置` 用于调整游戏行为
227
+ - 新增配置项 `werewolf__stop_command`
228
+
226
229
  - 2024.10.31 v1.1.7
227
230
 
228
231
  - *Bug fix*
@@ -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.7"
13
+ __version__ = "1.1.8"
14
14
  __plugin_meta__ = PluginMetadata(
15
15
  name="狼人杀",
16
16
  description="适用于 Nonebot2 的狼人杀插件",
@@ -0,0 +1,103 @@
1
+ import json
2
+ from pathlib import Path
3
+ from typing import Any, ClassVar, Final
4
+ from typing_extensions import Self
5
+
6
+ import nonebot
7
+ from nonebot.compat import model_dump, type_validate_json
8
+ from nonebot_plugin_localstore import get_plugin_data_file
9
+ from pydantic import BaseModel, Field
10
+
11
+ from .constant import (
12
+ DEFAULT_PRIESTHOOD_PRIORITY,
13
+ DEFAULT_ROLE_PRESET,
14
+ DEFAULT_WEREWOLF_PRIORITY,
15
+ stop_command_prompt,
16
+ )
17
+ from .models import Role
18
+
19
+
20
+ class ConfigFile(BaseModel):
21
+ FILE: ClassVar[Path]
22
+ _cache: ClassVar[Self | None] = None
23
+
24
+ def __init_subclass__(cls, **kwargs: Any) -> None: # noqa: ANN401
25
+ super().__init_subclass__(**kwargs)
26
+ if not cls.FILE.exists():
27
+ cls().save()
28
+
29
+ @classmethod
30
+ def load(cls) -> Self:
31
+ return type_validate_json(cls, cls.FILE.read_text())
32
+
33
+ @classmethod
34
+ def get(cls, *, use_cache: bool = True) -> Self:
35
+ if cls._cache is None or not use_cache:
36
+ cls._cache = cls.load()
37
+ return cls._cache
38
+
39
+ def save(self) -> None:
40
+ self.FILE.write_text(json.dumps(model_dump(self)))
41
+ type(self)._cache = self # noqa: SLF001
42
+
43
+
44
+ class PresetData(ConfigFile):
45
+ FILE: ClassVar[Path] = get_plugin_data_file("preset.json")
46
+
47
+ role_preset: dict[int, tuple[int, int, int]] = DEFAULT_ROLE_PRESET.copy()
48
+ werewolf_priority: list[Role] = DEFAULT_WEREWOLF_PRIORITY.copy()
49
+ priesthood_proirity: list[Role] = DEFAULT_PRIESTHOOD_PRIORITY.copy()
50
+ jester_probability: float = Field(default=0.0, ge=0.0, le=1.0)
51
+
52
+
53
+ class GameBehavior(ConfigFile):
54
+ FILE: ClassVar[Path] = get_plugin_data_file("behavior.json")
55
+
56
+ show_roles_list_on_start: bool = False
57
+ speak_in_turn: bool = False
58
+ dead_channel_rate_limit: int = 8 # per minute
59
+
60
+ class _Timeout(BaseModel):
61
+ prepare: int = Field(default=5 * 60, ge=5 * 60)
62
+ speak: int = Field(default=60, ge=60)
63
+ group_speak: int = Field(default=120, ge=120)
64
+ interact: int = Field(default=60, ge=60)
65
+ vote: int = Field(default=60, ge=60)
66
+ werewolf: int = Field(default=120, ge=120)
67
+
68
+ @property
69
+ def speak_timeout_prompt(self) -> str:
70
+ return (
71
+ f"限时{self.speak / 60:.1f}分钟, "
72
+ f"发送 “{stop_command_prompt()}” 结束发言"
73
+ )
74
+
75
+ @property
76
+ def group_speak_timeout_prompt(self) -> str:
77
+ return (
78
+ f"限时{self.group_speak / 60:.1f}分钟, "
79
+ f"全员发送 “{stop_command_prompt()}” 结束发言"
80
+ )
81
+
82
+ timeout: Final[_Timeout] = _Timeout()
83
+
84
+
85
+ class PluginConfig(BaseModel):
86
+ enable_poke: bool = True
87
+ enable_button: bool = False
88
+ stop_command: str | set[str] = "stop"
89
+
90
+ def get_stop_command(self) -> list[str]:
91
+ return (
92
+ [self.stop_command]
93
+ if isinstance(self.stop_command, str)
94
+ else sorted(self.stop_command, key=len)
95
+ )
96
+
97
+
98
+ class Config(BaseModel):
99
+ werewolf: PluginConfig = PluginConfig()
100
+
101
+
102
+ config = nonebot.get_plugin_config(Config).werewolf
103
+ nonebot.logger.debug(f"加载插件配置: {config}")
@@ -0,0 +1,82 @@
1
+ import functools
2
+
3
+ import nonebot
4
+
5
+ from .models import GameStatus, KillReason, Role, RoleGroup
6
+
7
+ STOP_COMMAND = "{{stop}}"
8
+ COMMAND_START = next(
9
+ iter(sorted(nonebot.get_driver().config.command_start, key=len)), ""
10
+ )
11
+
12
+
13
+ @functools.cache
14
+ def stop_command_prompt() -> str:
15
+ from .config import config # circular import
16
+
17
+ return COMMAND_START + config.get_stop_command()[0]
18
+
19
+
20
+ ROLE_NAME_CONV: dict[Role | RoleGroup, str] = {
21
+ Role.WEREWOLF: "狼人",
22
+ Role.WOLFKING: "狼王",
23
+ Role.PROPHET: "预言家",
24
+ Role.WITCH: "女巫",
25
+ Role.HUNTER: "猎人",
26
+ Role.GUARD: "守卫",
27
+ Role.IDIOT: "白痴",
28
+ Role.JESTER: "小丑",
29
+ Role.CIVILIAN: "平民",
30
+ RoleGroup.WEREWOLF: "狼人",
31
+ RoleGroup.GOODGUY: "好人",
32
+ RoleGroup.OTHERS: "其他",
33
+ }
34
+
35
+ ROLE_EMOJI: dict[Role, str] = {
36
+ Role.WEREWOLF: "🐺",
37
+ Role.WOLFKING: "🐺👑",
38
+ Role.PROPHET: "🔮",
39
+ Role.WITCH: "🧙‍♀️",
40
+ Role.HUNTER: "🕵️",
41
+ Role.GUARD: "🛡️",
42
+ Role.IDIOT: "👨🏻‍🦲",
43
+ Role.JESTER: "🤡",
44
+ Role.CIVILIAN: "👨🏻‍🌾",
45
+ }
46
+
47
+ GAME_STATUS_CONV: dict[GameStatus, str] = {
48
+ GameStatus.GOODGUY: "好人",
49
+ GameStatus.WEREWOLF: "狼人",
50
+ GameStatus.JESTER: "小丑",
51
+ }
52
+
53
+ REPORT_TEXT: dict[KillReason, tuple[str, str]] = {
54
+ KillReason.WEREWOLF: ("🔪", "刀了"),
55
+ KillReason.POISON: ("🧪", "毒死"),
56
+ KillReason.SHOOT: ("🔫", "射杀"),
57
+ KillReason.VOTE: ("🗳️", "票出"),
58
+ }
59
+
60
+ DEFAULT_ROLE_PRESET: dict[int, tuple[int, int, int]] = {
61
+ # 总人数: (狼, 神, 民)
62
+ 6: (1, 2, 3),
63
+ 7: (2, 2, 3),
64
+ 8: (2, 3, 3),
65
+ 9: (2, 4, 3),
66
+ 10: (3, 4, 3),
67
+ 11: (3, 5, 3),
68
+ 12: (4, 5, 3),
69
+ }
70
+ DEFAULT_WEREWOLF_PRIORITY: list[Role] = [
71
+ Role.WEREWOLF,
72
+ Role.WEREWOLF,
73
+ Role.WOLFKING,
74
+ Role.WEREWOLF,
75
+ ]
76
+ DEFAULT_PRIESTHOOD_PRIORITY: list[Role] = [
77
+ Role.WITCH,
78
+ Role.PROPHET,
79
+ Role.HUNTER,
80
+ Role.GUARD,
81
+ Role.IDIOT,
82
+ ]
@@ -1,5 +1,3 @@
1
- from __future__ import annotations
2
-
3
1
  from typing import TYPE_CHECKING
4
2
 
5
3
  if TYPE_CHECKING:
@@ -13,7 +11,7 @@ class Error(Exception):
13
11
  class GameFinished(Error): # noqa: N818
14
12
  """游戏结束时抛出,无视游戏进程进入结算"""
15
13
 
16
- status: GameStatus
14
+ status: "GameStatus"
17
15
 
18
- def __init__(self, status: GameStatus) -> None:
16
+ def __init__(self, status: "GameStatus") -> None:
19
17
  self.status = status