l4d2帮助帮助指令
- 在 json 文件设置的前缀指令,例如设置"云",则指令 云 输出组服务器,云 1 输出 1 号服务器
- 通过 SourceBans++ 获取服务器的 ban 信息,自动导入ip
- l4 图片开启/关闭 超管指令 可以修改输出单图是否为图片输出
- l4 查找用户 在已知服务器中查找
- l4 工坊下载 提供创意工坊 id 下载到服务器和群聊
/云 等组查询输出的服务器列表(HTML)图支持自定义背景。/云1 这类具体服查询不受影响,固定使用深蓝灰纯色背景。
<l4_path>/custom_backgrounds/ ← 放任意张图即可;插件会随机抽一张
<l4_path> 默认为 data/L4D2(即 <l4_path>/custom_backgrounds/ = data/L4D2/custom_backgrounds/);如要换位置,在 .env 里改:
L4_PATH=/path/to/your/data使用步骤:
- 找到
<l4_path>/custom_backgrounds/(默认data/L4D2/custom_backgrounds/,与云.json等组文件同级); - 把你想要的背景图放入该目录,支持
.jpg/.jpeg/.png格式,可放多张; - 完成。下一次查询即会使用新背景。
目录会在插件启动时自动创建,无需手动建。
查找顺序:
/云(服务器列表):从<l4_path>/custom_backgrounds/所有图片中随机抽一张;目录为空时回退到内置background.jpg/云1(单服务器卡):固定使用深蓝灰纯色背景(#496D89),不加载任何图片
选择规则:
- 目录中有多张图时,每次查询随机抽取一张;
- 想只用某张图,把其余图片删掉或移走;
- 替换同名图片会按文件修改时间自动重新加载,无需重启;
- 建议尺寸:宽幅横图(如 1920×1080),列表图会按高度铺满并横向平铺。
以下提到的方法 任选其一 即可
[推荐] 使用 nb-cli 安装
在 nonebot2 项目的根目录下打开命令行, 输入以下指令即可安装nb plugin install nonebot-plugin-l4d2-server使用包管理器安装
在 nonebot2 项目的插件目录下, 打开命令行, 根据你使用的包管理器, 输入相应的安装命令pip
pip install nonebot-plugin-l4d2-serverpdm
pdm add nonebot-plugin-l4d2-serverpoetry
poetry add nonebot-plugin-l4d2-serverconda
conda install nonebot-plugin-l4d2-server本插件出图走 nonebot-plugin-htmlrender → Playwright,需要 Chromium 内核。
直接 pip / pdm / poetry add 装出来的 playwright 不会自动下载浏览器,
启动时会报 Executable doesn't exist ... chrome-win64/chrome.exe 这类错。
按你的包管理器二选一:
# uv(推荐,nonebot2 社区主流)
uv tool install playwright
uv run playwright install --with-deps chromium
# 或 pipx(隔离环境装全局命令)
pipx install playwright
pipx run playwright install --with-deps chromium
# 或直接 pip
pip install playwright
playwright install --with-deps chromium如果你用
uv跑 bot(即uv run启动 bot 进程),第一次启动 bot 自己会调playwright install chromium,无需上面手工步骤;切到其他用户 / 全局 python 时才需要手动装。htmlrender
0.7+拆成了 provider 架构并强依赖nonebot-plugin-filehost, 0.6.x 仍提供html_to_pic。本插件pyproject.toml锁定>=0.6.0,<0.7, 升级前先看#104。
- 求生服务器-本地多路径操作(传地图等)
- 批量查询指定 ip 服务器状态和玩家
- 组查询(如
云)默认只列有人的服务器,云全列出全部(含没人 / 不在线);上百台自动拆成多张图 - connect 指令直接呼出服务器信息
- 根据用户名,在已知服务器搜索玩家信息
- 服务器订阅 / 收藏 + 定时推送(v1.4.0):上线 / 离线 / 玩家数突变时自动通知群
- 单服 CRUD 指令(v1.4.0):不用手动编辑 JSON
- 创意工坊批量并发下载(v1.4.0):流式写入 + 进度回报
| 指令 | 别名 | 权限 | 用途 |
|---|---|---|---|
l4收藏 <组> <id> |
l4fav、l4_favorite |
— | 在群聊触发,自动记住本群为推送目标 |
l4取关 <组> <id> |
l4unfav、l4_unfavorite |
— | 取消本群订阅(不影响其他群) |
l4收藏列表 |
l4favlist、l4_list_favorites |
— | 列出本群订阅 |
l4通知目标 <组> <id> <群号> |
l4notifytarget |
SUPERUSER | 把订阅的推送目标改成别的群 |
l4添加服务器 <组> host:port |
l4_add_server、l4addserver |
SUPERUSER | 新增单服到指定组 |
l4删除服务器 <组> <id或ip> |
l4_del_server、l4delserver |
SUPERUSER | 删除组内单服 |
l4修改服务器 <组> <id> <新ip> |
l4_edit_server、l4editserver |
SUPERUSER | 改单服 ip |
l4查看组 <组> |
l4showgroup、l4列服务器 |
SUPERUSER | 列组成员 + 在线状态 |
l4创意工坊 id1,id2 id3 |
— | l4_permission_set |
批量并发下载(逗号/空格/换行分隔) |
v1.4.0 起,默认用 nonebot-plugin-localstore 自动生成插件同名数据目录,
典型路径:./data/nonebot_plugin_l4d2_server/l4d2/(受 LOCALSTORE_USE_CWD
和 l4_localstore_subdir 影响)。首次启动时若新目录为空且旧的
./data/L4D2/ 仍有内容,会一次性复制过去(旧目录保留以便手动清理)。
不想用 localstore:在 .env 里设 L4_USE_LOCALSTORE=false,回到老的
相对 l4_path 模式。
新增 .env 字段:
# 路径
L4_USE_LOCALSTORE=true # 是否走 localstore 自动路径
L4_LOCALSTORE_SUBDIR=l4d2 # localstore 下的子目录名
# A2S 性能
L4_A2S_CONCURRENCY=8 # 同时最多几台服务器在查(信号量上限)
L4_A2S_TIMEOUT=2.5 # 单次 ainfo / aplayers 超时秒
L4_A2S_CACHE_TTL=15 # 结果缓存秒;0=不缓存
# 订阅 / 巡检
L4_FAVORITE_CHECK_INTERVAL=300 # 巡检间隔秒(≥30)
L4_FAVORITE_PLAYER_DELTA=5 # 玩家数变化超过此值才推送
# 工坊
L4_WORKSHOP_CONCURRENCY=3 # 批量下载并发上限(1~8)
# 出图
L4_IMAGE_PAGE_SIZE=30 # 组查询每张图最多几台服,超出自动分多张发送(1~200)
L4_RENDER_TIMEOUT=15 # 单页出图超时秒;超时 / 浏览器崩溃时改用简易图
L4_NAME_STRIP_PATTERN='^Anne云服#\d+' # 列表里去掉的服务器名前缀(正则),默认只匹配 Anne 云服:Anne云服#57[普通药役] → [普通药役];留空不处理
# 屏蔽
L4_BLOCK_KEYWORDS='["广告", "外挂|cheat"]' # 关键词正则列表(不区分大小写),见下文「屏蔽与关键词」
L4_BLOCK_BUILTIN_WORDS=false # 启用内置中文敏感词库(约 2100 词,命中的词打码成 *,默认关闭)在 .env 里用 JSON 列表配置正则,不区分大小写:
L4_BLOCK_KEYWORDS='["广告", "外挂|cheat"]'- 服务器名命中:整台服务器不出现在
云/云全/l4全服/l4查找/l4查人/tj/zl/kl的结果里;云5、connect <ip>这类单服查询只回「该服务器已被屏蔽」。 - 玩家名命中:只隐藏这个玩家(列表卡片、单服查询、查人),服务器照常显示,人数仍按 A2S 上报;
tj/zl/kl的判断仍按真实玩家列表。 - 非法正则会记一条警告并跳过,不影响其它关键词。收藏推送和历史记录不受影响。
过滤在 services/blocklist.py,接在 A2S 结果和输出之间。
和上面的关键词不同,敏感词库只打码不隐藏:服务器名、玩家名里命中的词替换成 *(如 出售按摩棒 → 出售***),服务器和玩家照常显示。几千到几万个词的词表难免混着常用词,打码比整台隐藏温和。
- 内置词库:
.env设L4_BLOCK_BUILTIN_WORDS=true打开。收录 konsheng/Sensitive-lexicon(MIT)的政治、反动、暴恐、涉枪涉爆、色情、贪腐等 8 个分类,约 2100 个词,已删掉和 L4D2 用语、常见昵称冲突的词;来源、删改和没收录的分类见nonebot_plugin_l4d2_server/block_words/README.md。 - 自定义词表:把
.txt放到<data_dir>/block_words/(启动时自动创建),每行一个词,#开头是注释,发l4刷新生效。不管内置词库开没开都会加载。 - 少于 2 个字的词不加载;中文按子串匹配,纯字母数字的词(如
xjp)按整词匹配,不会误伤SirPlease这种英文名;全角字符按半角算。不在线服的占位名「服务器无响应」不打码。
同一仓库的 GFW补充词库、零时-Tencent 等大词表包含手枪、冲锋枪、炸弹、电击器、燃烧瓶、嗑药、服务器等 L4D2 常用词,直接放进
block_words/会把正常的服务器名和玩家名打码,建议先删掉这些词再用。
- SourceBans 自动同步:定时拉 SourceBans banlist 落到本地
<data_dir>/blocklist.json。注意 A2S 只返回玩家名,拿不到 SteamID, 只能按名字匹配被封玩家。 - 本地 JSON 黑名单:管理员
l4黑名单 add <ip>写入<data_dir>/blocklist.json;查询结果按黑名单过滤。 - SourceMod HTTP 聊天镜像:服务器装 SM 插件暴露 HTTP 接口, 机器人拉聊天记录后正则匹配违规词,命中后通过 RCON 自动 kick。
这几种如要实现,可以复用 services/blocklist.py 的过滤入口;
consts.BLOCKLIST_FILENAME 已预留给本地黑名单文件。
服务器组文件存放位置:
<data_dir>/<组名>.json。<data_dir>默认data/L4D2;开启 localstore 后变为<localstore>/nonebot_plugin_l4d2_server/l4d2/。 旧版<data_dir>/l4d2/子目录与<data_dir>/l4d2.json单文件 都会在启动时自动迁移。
收藏相关数据:
<data_dir>/favorites.json— 收藏条目列表<data_dir>/notify_state.json— 上次推送状态(避免抖动刷屏)
l4_enable = True
"""是否全局启用求生功能"""
l4_image = False
"""是否启用图片"""
l4_connect = True
"""是否在查服命令后加入connect ip"""
l4_use_localstore = True
"""是否走 nonebot-plugin-localstore 自动生成插件同名数据目录"""
l4_localstore_subdir = "l4d2"
"""localstore 下的子目录名"""
l4_path = "data/L4D2"
"""l4_use_localstore=False 时使用的相对路径"""
l4_players = 4
"""查询总图的时候展示的用户数量"""
l4_style = "default"
"""图片风格,可选包括以下
- 简洁
l4_a2s_concurrency = 8
"""A2S 并发上限(信号量)"""
l4_a2s_timeout = 2.5
"""A2S 单次超时秒"""
l4_a2s_cache_ttl = 15
"""A2S 结果缓存秒;0=不缓存"""
l4_favorite_check_interval = 300
"""收藏巡检间隔秒"""
l4_favorite_player_delta = 5
"""玩家数变化超过此值才推送"""
l4_workshop_concurrency = 3
"""创意工坊批量下载并发上限"""- 服务器组指令(
云、云1等)规则层拒绝非数字后缀:之前输入云云会被解析为「组云+ args=云」然后静默退出,现在直接在 nonebot 规则层拒绝,不会进入 handler,也不会被本插件拦截后续处理。云1/云12仍正常触发单服查询; - 单服务器查询(
云1)合并图片与connect host:port文本:图片和connect host:port文本作为一条合并消息发出(受l4_connect配置控制),方便直接点链接加入服务器; - 单服务器卡(
云1)长内容自动换行:服务器名、地图名、connect IP 等超出 380px 卡片宽度时,会按像素宽度自动换行展示,图片高度随行数自动撑高; - 服务器列表(
云)地图名溢出处理:.map-nameCSS 增加text-overflow: ellipsis,超长地图名以省略号截断,不再撑破卡片; - 查服背景图按渲染类型拆分目录(后续调整):
/云(服务器列表)从<l4_path>/custom_backgrounds/根目录的所有图片中随机抽一张,目录为空时回退到内置background.jpg;/云1(单服务器卡)固定使用深蓝灰纯色,不加载任何图片。详见「自定义服务器列表背景图片」; - 数据路径统一从
l4_path派生:组文件、sb_pages、自定义背景图、迁移脚本都跟着l4_path配置走,不再各自写死相对路径。.env里改L4_PATH一处即生效,不用再管 bot 启动 CWD。
- localstore 路径:默认用
nonebot-plugin-localstore自动生成 插件同名数据目录;可通过L4_USE_LOCALSTORE=false退回旧路径。 - A2S 性能:批量查询加
asyncio.Semaphore上限 (l4_a2s_concurrency),单次超时可配(l4_a2s_timeout), 结果缓存l4_a2s_cache_ttl秒(deepcopy 防止下游 mutate); SourceBansrefresh_all_pages改并发。 - 收藏 / 订阅:新增
l4收藏/l4取关/l4收藏列表/l4通知目标;scheduler 周期巡检(l4_favorite_check_interval), 上线 / 离线 / 玩家数突变时按群推送。 - 单服 CRUD:新增
l4添加服务器/l4删除服务器/l4修改服务器/l4查看组,ID 稳定不再重排。 - 创意工坊批量:
l4创意工坊 123,456 789并发下载 (l4_workshop_concurrency),流式写入 + 进度回报。 tj/zl/kl注册时序 bug:改为在_on_startup内调用register_picker_handlers(),避免导入时registry.commands还没填。- 统一异常类型:
services/errors.py提供L4Error/L4ServerUnreachableError/L4TimeoutError/L4InvalidInputError/L4NotFoundError/L4HTTPError, 后续 handler 收敛except L4Error。 http_helpers.save_url_to_filedead code 修复; 新增stream_download流式下载接口。http_helpers.STREAM_CHUNK_SIZE/STREAM_TIMEOUT新常量。
- anne 部分,已移植到这里,通过 core 插件调用
- 如果您有发现 BUG 或者更好的建议,欢迎提 Issue & Pr
- 如果本插件对你有帮助,不要忘了点个 Star~
- 本项目仅供学习使用,请勿用于商业用途
- 更新日志
- GPL-3.0 License ©@Agnes4m
-
nonebot2- 聊天机器人的基础框架
-
饼干 - 指导 nonebot2 框架的函数使用
-
wuyi - 指导 pil 作图
-
感谢以下服主大力支持
- Michaela's | 机器人功能测试反馈
- 东 | 提供 docker 部署方法等建议 | 电信服 anne 游戏群
- 迷茫 | 催命更新 byd
- ArcPav | 积极反馈 bug,提供改进思路

