# werewolf-plugin **Repository Path**: lylnspace/werewolf-plugin ## Basic Information - **Project Name**: werewolf-plugin - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-15 - **Last Updated**: 2026-10-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # werewolf-plugin · 狼人杀 TRSS-Yunzai 群聊狼人杀裁判插件。机器人担任法官:发牌、推进昼夜、结算死亡、判定胜负并记录战绩。 - 身份、夜间行动、狼队交流走私聊;白天发言和投票在群里进行。 - 群里不会出现任何身份信息,失败提示也不例外,详见[隐私设计](#隐私设计)。 - 共 17 种角色。房主可以在网页上自由配板,也可以直接用内置模板开局。 ## 安装 把 `werewolf-plugin` 目录放到 Yunzai 的 `plugins/` 下,重启云崽即可。 插件没有额外依赖,使用云崽自带的 `redis`、`express`、`yaml`。加载时会启动配板网页服务,默认端口 2778,见[配置](#配置)。 ## 快速开始 1. 群里发 `#狼人杀` 开房(默认目标 12 人),其他人发 `#加入` 入座。入座前请先私聊机器人一次,确保能收到私信。 2. 人数够了,房主任选一种方式开局: - `#开始`:机器人私聊房主一个配板网页,选好角色和数量,确认后立即发牌。 - `#模板开局`:按实际人数套用内置模板,直接发牌,不需要网页。 3. 每人私聊收到身份文字和卡面图。夜里按提示私聊机器人行动,所有需要行动的人完成后自动天亮。 4. 白天在群里自由发言。房主发 `#开始投票`,大家 `#投 N`,房主再发 `#结算` 公布结果。 5. 一方达成胜利条件后,机器人公布全场身份并记录战绩。房主或主人可以随时发 `#狼人杀结束` 终止对局。 普通局最少 4 人,无民局(`#狼人杀无民`)最少 6 人,不需要等满目标人数。 ## 配置 首次使用会生成 `config/config/web.yaml`: ```yaml host: "0.0.0.0" # 配板网页监听地址 port: 2778 # 监听端口 publicUrl: "" # 私聊链接中的对外地址 ``` - 网页由插件自己的 HTTP 服务提供,不占用云崽本体端口。修改 `host`、`port` 需要重启云崽;端口被占用时会直接报错提示。 - `publicUrl` 填房主手机能访问的地址,例如 `http://192.168.1.10:2778` 或 `https://example.com/bot/`。带路径前缀时,反向代理需要把该前缀转发到插件端口。留空则使用本机地址,只适合同机测试。修改后下次 `#开始` 立即生效,无需重启。 - 网页没有账号体系,只靠私聊链接里的一次性凭据鉴权。链接 20 分钟内有效,房主再次 `#开始` 会作废旧链接。凭据放在 URL 的 `#` 片段里,不会出现在请求和访问日志中。部署到公网建议套 HTTPS 反向代理。 - `#模板开局` 不依赖网页服务,网页不可用时可以用它开局。 ### 禁言模式 `config/config/game.yaml` 控制禁言模式,也可以在锅巴面板的“狼人杀”插件配置里修改(web.yaml 的三项也在那里): ```yaml muteGroups: [] # 白名单群号,机器人需要是这些群的管理员 muteNight: true # 夜晚全员禁言 muteVote: true # 投票阶段全员禁言 ``` 只有白名单群启用,其他群保持原玩法。白名单群内: - 入夜开启全员禁言,天亮进入发言阶段时解除。夜里死亡的猎人开枪期间保持禁言。 - `#开始投票` 开启全员禁言,并私聊每位投票人提示。投票改为私聊机器人 `#投 N` / `#改票 N` / `#弃票`,群里发送不生效。 - 群里只播报“N号 已投票 / 已改票”和进度,不播报投给谁;所有人投完会提醒房主结算。`#结算` 时公布完整票型。 - 房主可以私聊机器人发 `#结算`,群里发也可以。私聊结算只在白名单群生效。 - 首次平票进入 PK 时先解除禁言让平票者陈述,房主再 `#开始投票`,这一轮仍只能投平票者。 - 对局结束或 `#狼人杀结束` 时解除禁言。禁言或解除失败(机器人不是管理员、适配器不支持)会在群里提示,对局照常进行。 - 修改配置后下一次阶段切换生效,不需要重启。 ### 图片样式 锅巴面板 → 狼人杀 → 图片样式 → **投票与复盘图片样式**,可选择: | 样式 | 配置值 | 效果 | | --- | --- | --- | | 暗金战报(默认) | `dark` | 深绿暗金、大头像、竖向角色卡牌 | | 羊皮纸档案 | `paper` | 暖色纸纹、档案边框、双列角色卡牌 | | 浅色票单 | `light` | 浅底深字、列对齐票单、双列角色卡牌 | | 经典样式 | `classic` | 原版深色表格与双列身份列表 | 也可以直接修改 `config/config/game.yaml`: ```yaml reportStyle: dark ``` 保存后下次出图立即生效,无需重启。投票结果、终局身份揭晓、夜间行动和追加技能事件统一使用该样式;一条终局聊天记录内的全部页面保持同一种样式。 前三种样式在进行中的投票图里按被投玩家归拢票型,逐个显示投票人的头像、座号和昵称,弃票、未投与无效票单独列出。终局投票复盘继续逐人展示票型、真实身份和目标原生阵营,人数较多时自动分页。玩家圆桌图与私聊原始身份卡面不受此配置影响。 ## 指令 ### 房间 | 指令 | 说明 | | --- | --- | | `#狼人杀` / `#狼人杀N人` | 开房,默认目标 12 人。别名 `加入狼人杀`、`开启狼人杀` | | `#狼人杀无民` / `#狼人杀无民N人` | 开无民局,至少 6 人,网页里不能选平民 | | `#加入` / `#上桌` | 入座,仅开局前 | | `#退出` / `#离桌` | 退座,仅开局前 | | `#开始` | 房主获取配板网页链接(私聊) | | `#模板开局` | 房主按模板直接发牌。别名 `#开始模板`、`#自动开局` | | `#狼人杀结束` | 房主或主人强制结束,不记录战绩 | ### 夜间(私聊机器人) | 指令 | 角色 | 说明 | | --- | --- | --- | | `#刀 N` | 狼队 | 所有可刀的狼选择同一目标才锁定 | | 普通文字 | 狼队 | 转发给其他存活狼队友,附座位、昵称、QQ | | `#验 N` | 预言家 / 石像鬼 | 预言家查阵营,石像鬼查具体身份 | | `#救` / `#毒 N` / `#空` | 女巫 | 用解药、用毒药或不用药 | | `#守 N` | 守卫 | 守护一人 | | `#情侣 A B` | 丘比特 | 首夜连情侣,别名 `#连` | | `#魅惑 N` | 狼美人 | 每夜魅惑一人 | | `#狩猎 N` / `#空` | 猎魔人 | 第二夜起狩猎或放弃 | | `#摄梦 N` | 摄梦人 | 每夜必须选一人 | 夜间指令只能私聊发送。局内玩家在群里发这些指令不会执行,机器人只回复一句与身份无关的“请私聊”提示。 ### 白天(群里) | 指令 | 说明 | | --- | --- | | `#开始投票` / `#结束发言` | 房主或主人结束发言,进入投票 | | `#投 N` / `#改票 N` / `#弃票` | 投票、改票、弃票。[禁言模式](#禁言模式)群改为私聊机器人 | | `#结算` / `#结束投票` / `#计票` | 房主或主人计票,公布结果。禁言模式群房主也可私聊发送 | | `#自爆` | 狼人自爆 | | `#决斗 N` | 骑士决斗 | | `#开枪 N` / `#空` | 猎人或白狼王开枪、放弃,私聊和群里都可以 | ### 查询 | 指令 | 说明 | | --- | --- | | `#我的身份` / `#我的座位` | 私聊发送自己的座位、身份和卡面 | | `#玩家列表` | 圆桌座位图。群里只显示座位和存活状态;私聊额外标出自己的身份,狼人还能看到可见队友 | | `#卡牌列表` / `#卡牌 狼美人` | 角色图鉴,不需要开房。全部角色合并成一条聊天记录发送 | | `#规则` / `#狼人杀帮助` | 玩法简介 / 完整指令菜单 | | `#狼人杀战绩` | 个人总局数、胜率、身份分布 | ## 配板 ### 网页自选 - 卡牌总数必须等于入座人数,至少一名狼人阵营角色和一名神职。 - 狼人、平民、白痴可以选多张,其他角色每种最多一张。 - 不选平民时,自动按无民局(屠神)规则判定胜负。 - 配板期间仍可加入或退出。确认时会重新核对玩家名单;名单有变化时,网页会要求刷新后重新确认。 - 开始发身份之前出错,房间会恢复等待状态,可以用原链接重试;身份一旦开始发送,就不会再重复发牌。 ### 内置模板 `#模板开局` 按实际入座人数选模板。用 `#狼人杀无民` 开的房间使用无民模板。 | 人数 | 普通模板 | 无民模板 | | --- | --- | --- | | 6 | 狼人×2、预言家、平民×3 | 狼人、白狼王、预言家、女巫、猎人、骑士 | | 7 | 狼人×2、预言家、女巫、平民×3 | 狼人、白狼王、预言家、女巫、猎人、骑士、白痴 | | 8 | 狼人×2、预言家、女巫、猎人、平民×3 | 狼人×2、白狼王、预言家、女巫、猎人、骑士、守卫 | | 9 | 狼人×3、预言家、女巫、猎人、平民×3 | 8 人板 + 丘比特 | | 10 | 狼人×3、预言家、女巫、猎人、丘比特、平民×3 | 9 人板 + 白痴 | | 11 | 狼人×2、隐狼、预言家、女巫、猎人、白痴、守墓人、平民×3 | 狼人×3、白狼王、预言家、女巫、猎人、骑士、守卫、白痴、丘比特 | | 12 | 狼人×3、隐狼、预言家、女巫、猎人、白痴、守墓人、平民×3 | 11 人板 + 白痴 | - 表外人数动态配板:狼人约占 1/4;神职按预言家、女巫、猎人、白痴、守卫的顺序随人数加入;其余是平民。无民局再把平民依次换成丘比特、骑士、白狼王、白痴、守卫。 - 模板不包含狼美人、猎魔人、摄梦人、石像鬼、咒狐,要用这些角色请走网页配板。 ## 角色 | 角色 | 标识 | 阵营 | 网页上限 | 夜间行动 | | --- | --- | --- | --- | --- | | 平民 | `villager` | 好人 · 平民 | 不限 | 无 | | 预言家 | `seer` | 好人 · 神职 | 1 | 每晚必须 | | 女巫 | `witch` | 好人 · 神职 | 1 | 每晚必须 | | 猎人 | `hunter` | 好人 · 神职 | 1 | 无 | | 守卫 | `guard` | 好人 · 神职 | 1 | 每晚必须 | | 白痴 | `idiot` | 好人 · 神职 | 不限 | 无 | | 骑士 | `knight` | 好人 · 神职 | 1 | 无(白天决斗) | | 丘比特 | `cupid` | 好人 · 神职 | 1 | 仅首夜,必须 | | 守墓人 | `gravekeeper` | 好人 · 神职 | 1 | 无(自动收到信息) | | 猎魔人 | `demonHunter` | 好人 · 神职 | 1 | 第二夜起必须(可以 `#空`) | | 摄梦人 | `dreamSeer` | 好人 · 神职 | 1 | 每晚必须 | | 狼人 | `wolf` | 狼人 | 不限 | 每晚必须 | | 白狼王 | `whiteWolf` | 狼人 | 1 | 每晚必须 | | 狼美人 | `wolfBeauty` | 狼人 | 1 | 每晚必须(魅惑和刀) | | 隐狼 | `hiddenWolf` | 狼人 | 1 | 获得刀人能力后必须 | | 石像鬼 | `gargoyle` | 狼人 | 1 | 每晚必须(先验;获得刀人能力后还要刀) | | 咒狐 | `cursedFox` | 第三方 | 1 | 无 | - “必须”指不完成就不会天亮。 - 标识可以用于 `#卡牌 wolfBeauty` 这类查询。 - 无民模板人数较多时,可能出现多名守卫、骑士或白狼王,各自独立记录技能状态;网页选卡按上表限制数量。 ### 查验与判定对照 所有查验和判定都只看角色本身,不受情侣阵营影响。 | 角色 | 预言家查验 | 石像鬼查验 | 守墓人 | 骑士决斗、猎魔人狩猎 | | --- | --- | --- | --- | --- | | 狼人、白狼王、狼美人、石像鬼 | 狼人 | 具体角色 | 狼人 | 算狼:目标出局 | | 隐狼 | 好人 | 具体角色 | 狼人 | 算狼:目标出局 | | 咒狐 | 好人(咒狐天亮出局) | 具体角色(不会出局) | 好人 | 不算狼:发起者出局 | | 其他角色 | 好人 | 具体角色 | 好人 | 不算狼:发起者出局 | ### 好人阵营 #### 平民 - 没有技能,靠白天发言和投票找狼。 - 平民全部出局时狼人胜(屠民)。无民局里没有平民,不适用这一条。 #### 预言家 - 每晚必须私聊 `#验 N`,查验一名存活玩家,机器人立即私聊回复“好人”或“狼人”。 - 每晚只能验一次,验完不能再验,也不能空过。 - 隐狼显示为好人。咒狐也显示为好人,但被验的咒狐会在天亮时出局。 #### 女巫 - 解药、毒药各一瓶,用完不补。每晚都必须选 `#救`、`#毒 N` 或 `#空`;药用完后也要发 `#空`,否则不会天亮。 - 狼队锁刀后,机器人私聊告诉女巫当晚被刀的人。锁刀前只能 `#毒` 或 `#空`;锁刀前选了 `#空`,当晚就不能再用解药。 - 同一晚不能既救又毒。只有第一晚可以自救。选完不能更改。 - 毒药无视守卫和解药,被毒的人必死,被毒的猎人不能开枪。猎魔人免疫毒药:毒药照样消耗,女巫也不会知道没毒死。 - 解药救下的人如果当晚也被守卫守护,仍然死亡(同守同救死)。 #### 猎人 - 没有夜间行动。 - 夜里被狼刀死,或白天被放逐时,可以开枪带走一名存活玩家。被毒、被狩猎、殉情、被梦游带走、被狼美人连带、被白狼王枪杀时,都不能开枪。 - 能开枪时机器人会在群里公开猎人身份,并私聊提示 `#开枪 N` 或 `#空`。开枪不限时,猎人操作完游戏才继续,群里和私聊都可以发。 - 夜里死亡:先公布倒牌,再开枪,然后进入白天。白天被放逐:开枪后进入夜晚。如果出局时胜负已分,直接结算,不再开枪。 - 枪杀狼美人会触发魅惑连带;被枪杀的人如果有情侣,情侣殉情。 #### 守卫 - 每晚必须私聊 `#守 N`,守护一名存活玩家,可以守自己,不能空过。天亮前可以改守。 - 不能连续两晚守同一人;第一晚没有限制。 - 只挡狼刀,挡不住毒药、狩猎、摄梦致死和咒狐被验死亡。被守的人同晚又被女巫救,仍然死亡。 - 有多名守卫时,各自记录守护目标和上一晚记录,互不影响。 #### 白痴 - 没有夜间行动。 - 被放逐时翻牌免死,之后失去投票权,但仍然存活、可以发言,也仍算存活神职。之后再被放逐,依然免死。 - 只有放逐能触发免死。被刀、被毒、被狼美人连带都会正常出局,被连带时也来不及翻牌。 - 翻牌免死不算放逐,当晚守墓人收不到信息。 #### 骑士 - 没有夜间行动。白天(发言或投票阶段)在群里发 `#决斗 N`,每局一次,结果当场公开。 - 目标是狼人阵营角色(包括隐狼、石像鬼、狼美人):目标出局,本轮投票作废,直接进入夜晚。 - 目标不是狼人阵营(包括咒狐):骑士出局,白天继续,已经投的票保留。 - 被决斗出局的白狼王不能开枪,狼美人也不会触发魅惑连带。双方如果有情侣,情侣照常殉情。 - 被狼美人连带出局时,决斗机会随之失效。 #### 丘比特 - 第一晚必须私聊 `#情侣 A B`(别名 `#连`),把两名存活玩家连成情侣,可以包含自己。不连好不会天亮,之后的夜晚没有行动。 - 两名情侣各自收到私聊,只知道对方的座位号,不知道对方身份。 - 阵营跟随情侣:两人都是好人,情侣和丘比特都归好人;两人都是狼人,三人都归狼人;一好一狼(或连到咒狐),三人组成第三方情侣阵营。 - 任一名情侣以任何方式出局,另一名立即殉情,殉情者不能发动技能(例如猎人不能开枪)。丘比特本人出局不会触发殉情,除非他自己就是情侣之一。 - 丘比特归入狼人阵营后,也不参与狼队刀人和聊天,不出现在狼队名单里。 - 成为情侣不会改变原角色的技能和查验结果。例如狼人情侣照样和狼队一起刀人,被预言家验仍是狼人。 #### 守墓人 - 不用发指令。从第二晚起,入夜时机器人自动私聊告诉守墓人:前一天被放逐的人是“狼人”还是“好人”。 - 只记录投票放逐。被刀、被毒、被枪杀、自爆、决斗、殉情、被连带出局的人都不记录。前一天无人被放逐(PK 再平票、白痴翻牌等)时,当晚没有信息。 - 按角色判定:隐狼、狼美人、石像鬼算狼人,咒狐算好人。 - 发 `#查`、`#守墓`、`#空` 只会收到“无需操作”的提示。 #### 猎魔人 - 第一晚没有行动。从第二晚起,每晚必须私聊 `#狩猎 N` 选一名其他存活玩家,或 `#空` 放弃。选定后不能更改。 - 天亮结算:目标是狼人阵营角色(包括隐狼),目标出局;否则猎魔人自己出局(包括狩猎咒狐)。 - 守卫和解药挡不住狩猎,也挡不住反噬。梦游者免疫狩猎;猎魔人自己是梦游者时,也不会被反噬。 - 免疫毒药,但被狼刀会正常出局。 - 天亮只公布倒牌座位,不公布死因,猎魔人需要自己判断狩猎结果。 #### 摄梦人 - 每晚(包括第一晚)必须私聊 `#摄梦 N`,选一名其他存活玩家做梦游者。不能空过,选定后不能更改,梦游者不会收到通知。 - 梦游者免疫当晚所有夜间伤害:狼刀、毒药、狩猎和狩猎反噬。 - 连续两晚摄梦同一个人,这个人第二晚出局,守卫、解药都救不回来。中间换过人就重新计算。 - 摄梦人在夜里出局(包括殉情)时,当晚的梦游者一起出局。摄梦人白天出局不会带走任何人。 - 因梦游出局的猎人不能开枪。梦游不能抵消咒狐被验的死亡。 ### 狼人阵营 #### 狼人 - 开局私聊会告诉你狼队友的座位(白狼王会标出来)。隐狼和石像鬼不在名单里。 - 每晚必须私聊 `#刀 N`。所有能刀人的狼选同一目标才锁定;锁定前可以改刀,锁定后当晚不能再改。可以自刀或刀队友,但不能刀狼美人,也不能空刀。 - 有存活的石像鬼时,要等它查验完才能出刀。 - 每次出刀,机器人都会私聊通知其他能刀的队友;锁定时再通报全体,并私聊告诉女巫刀口。 - 夜里私聊机器人的普通文字,会转发给其他存活的狼人阵营角色(不含石像鬼),附带座位、昵称和 QQ。以 `#` `/` `!` `*` `%` 开头的消息视为其他插件的指令,不转发。 - 白天(发言或投票阶段)可以在群里发 `#自爆`:立即出局,本轮投票作废,直接进入夜晚。场上没有其他存活的狼人阵营角色时,不能自爆。 - 自爆失败时,群里只回复“指令未生效”,原因私聊本人。 #### 白狼王 - 夜里和普通狼人一样刀人、聊天,在狼队名单中会标出“白狼王”。 - 自爆时翻牌公开身份,可以私聊或群里发 `#开枪 N` 带走一人,或 `#空` 放弃。开枪不限时,之后进入夜晚。如果自爆当下胜负已分,直接结算。 - 只有自爆能开枪。被刀、被毒、被放逐、被决斗出局时都不能开枪。 - 被白狼王枪杀的人不能发动技能:猎人不能开枪,狼美人不会触发魅惑连带。情侣照常殉情。 #### 狼美人 - 每局最多一名。每晚必须完成两件事:私聊 `#魅惑 N` 魅惑一名其他存活玩家,再 `#刀 N` 参与狼队锁刀。 - 魅惑当晚不能更改,可以连续魅惑同一人,被魅惑者不会收到通知。魅惑一直有效,直到下一晚重新选择。 - 狼美人被放逐,或被猎人枪杀时,被魅惑者立即一起出局,不能发动技能(猎人不能开枪、白痴不能翻牌、骑士不能决斗)。连带出局在判定胜负之前结算。 - 被刀、被毒、被决斗、殉情、被白狼王枪杀时,不会带人出局。 - 不能自爆,狼队也不能把狼美人选为刀口。预言家验为狼人。 #### 隐狼 - 每局最多一名。隐狼知道狼队友是谁,狼队友不知道隐狼。 - 预言家验隐狼显示好人;石像鬼、守墓人、骑士决斗和猎魔人狩猎都把隐狼当作狼人。 - 能收到狼队聊天,但隐狼发的话不会转发给狼队,否则身份就暴露了。 - 狼人、白狼王、狼美人全部出局后,隐狼获得刀人能力,从那一晚起必须 `#刀 N`(可以自刀)。在此之前发 `#刀` 只会收到提示。 - 有刀人能力后才能收到刀口通知。不能自爆。 #### 石像鬼 - 每局最多一名,独立于狼队:不和狼队互认,不收也不发狼队聊天,收不到刀口通知。 - 每晚上半夜必须私聊 `#验 N`,查验一名其他存活玩家的具体角色。每晚一次,同一人不能重复验。结果只告诉石像鬼本人,查验必须私聊。 - 石像鬼查验完之前,狼队不能出刀。其他存活玩家都验过后,可以 `#空` 结束当晚查验。 - 其他狼人阵营角色(包括隐狼)全部出局后,石像鬼获得刀人能力:每晚先查验,再 `#刀 N`,可以自刀。 - 不能自爆。预言家验为狼人。 ### 第三方 #### 咒狐 - 独立阵营,不算好人、狼人、神职或平民。没有夜间行动。 - 免疫狼刀,被刀不会死。但会被毒杀、放逐、枪杀,也会被梦游连带、殉情带走。 - 被预言家查验时显示好人,但当晚天亮必定出局,守卫、解药、梦游都救不回来。石像鬼查验只看到“咒狐”,不会致死。 - 骑士决斗咒狐、猎魔人狩猎咒狐,都按“不是狼”处理,出局的是骑士或猎魔人。 - 好人或狼人达成胜利条件时,如果咒狐还活着,改为咒狐独自获胜。情侣阵营获胜时不会被咒狐取代。 ## 规则细节 ### 夜晚 - 夜晚不限时,必须行动的人全部完成后自动天亮。没完成时每 60 秒在群里匿名提醒一次未行动人数,不点名。 - 必须行动:可刀的狼、预言家、女巫、守卫、摄梦人、狼美人(魅惑和刀都要完成)、石像鬼、首夜的丘比特、第二夜起的猎魔人。平民、白痴、骑士、守墓人、咒狐不用操作。 - 先后顺序只有两条:存活的石像鬼查验完,狼队才能提交刀口;狼队锁刀后,女巫才能用解药。机器人会在锁刀后私聊女巫当晚的刀口。其余角色随时都可以行动。 - 预言家、女巫、摄梦人、猎魔人、狼美人、石像鬼选定后不能更改。守卫可以在天亮前改守,狼队可以在锁刀前改刀。 - 夜间指令只能私聊,在群里发不会生效。 ### 天亮结算 各种夜间伤害在天亮时一起结算: - 狼刀:被守卫守护或被女巫救下就不死;同一人被守护又被救则仍然死亡(同守同救死)。咒狐免疫狼刀。 - 毒药:无视守护和解药。猎魔人免疫毒药,但女巫的毒药照样消耗掉。 - 狩猎:目标是狼人阵营角色则目标出局,否则猎魔人自己出局。守护和解药挡不住狩猎。 - 梦游:梦游者当晚免疫以上所有伤害;但连续两晚被摄梦的同一人会出局。 - 咒狐被预言家查验,天亮必定出局,任何效果都救不回来。 - 连带出局最后结算:摄梦人夜里出局,会带走当晚的梦游者;情侣一方出局,另一方立即殉情。 - 天亮只公布倒牌座位,殉情的会标出来,其他死因都不公布。 ### 出局方式对照 | 出局方式 | 猎人能否开枪 | 狼美人是否带人 | 守墓人是否记录 | | --- | --- | --- | --- | | 夜里被狼刀 | 能 | 否 | 否 | | 白天被放逐 | 能 | 是 | 是 | | 被猎人枪杀 | — | 是 | 否 | | 被毒、被狩猎、梦游致死、咒狐被验 | 否 | 否 | 否 | | 自爆、被决斗、被白狼王枪杀 | 否 | 否 | 否 | | 殉情、被魅惑连带 | 否 | 否 | 否 | 任何方式出局都会让情侣殉情。 ### 白天 - 发言不限时,房主或主人发 `#开始投票` 后才能投票。存活且有投票权的玩家可以投票,不能投自己。 - `#结算` 时,弃票数达到或超过任一玩家的最高得票数,本轮无人出局,直接进入下一夜,PK 加赛也适用;未投票单独统计,不视为弃票。例如一人获 1 票、7 人弃票、1 人未投,本轮不放逐。弃票少于玩家最高票时,唯一最高票者被放逐;玩家首次平票进入 PK,加赛再平票无人出局。没有有效放逐票时也无人出局。 - 每次 `#结算` 自动向对局群发送一张票型图片,包含每人最终投票、投票人与目标头像、得票分布、弃票与未投票人数以及本轮结果。正常投票、PK 加赛分别出图;进行中的图片不公开隐藏身份与阵营。头像加载失败时使用座号占位;图片发送失败时保留原有文字计票,照常推进对局。 - 放逐结算:白痴翻牌免死,但失去投票权。狼美人被放逐时,被魅惑者一起出局,且不能发动技能。被放逐的猎人可以开枪。 ### 终局图片复盘 正常分出胜负后,机器人向对局群发送一条合并转发聊天记录,依次包含: - 结算总览:获胜阵营、玩家头像、角色卡面、全员真实身份、存活状态与出局原因。头像无法加载时使用座号占位。 - 每夜行动:各行动玩家的最终选择、查验反馈、狼队刀口与天亮出局结果。没有夜间操作的玩家不占行;空过会保留,守墓人的自动信息也会记录。 - 每轮投票:每人最终投给谁、得票分布、弃票、未投和 PK 结果,终局才附带真实身份与目标原生阵营。 - 追加技能事件:自爆、骑士决斗、猎人或白狼王开枪及连带出局。 记录随房间保存在 Redis,下一夜不会覆盖前夜记录。人数较多时终局图片自动分页,所有页面放在同一条聊天记录中;私聊触发的结算也发到对局群。单页渲染失败时在转发中使用该页文字,转发失败则回退一条文字复盘,不影响战绩与清场。强制结束不生成胜负复盘;更新前未记录的轮次不会补造。 - 开枪不限时,等猎人 `#开枪 N` 或 `#空` 后才继续。 - 守墓人在下一夜得知这次被放逐者是不是狼人阵营角色,隐狼也算狼。白痴翻牌免死或无人出局时,没有放逐记录。 - 狼人、白狼王可以在白天 `#自爆`,骑士可以在白天 `#决斗 N`,见对应角色说明。 ### 胜负 - 好人胜:狼人阵营全部出局。 - 狼人胜:好人阵营全部出局,或神职全部出局,或平民全部出局(屠边)。无民局只看神职是否全部出局。 - 情侣胜(第三方):存活的人全是情侣阵营,且至少 2 人(两名情侣,可以加上丘比特)。两名情侣都还活着时不走屠边判定,好人和狼人都要先把情侣淘汰。 - 咒狐:好人或狼人达成胜利时,如果咒狐还活着,改为咒狐独自获胜。情侣胜不会被咒狐取代。 - 战绩按当局最终阵营记录胜负。强制结束的对局不记录。 ## 隐私设计 - 身份、夜间行动、查验结果、狼队聊天都只走私聊。 - 群里发夜间指令不会执行,机器人统一回复“请私聊”,回复内容与身份和阶段都无关。已经翻牌的猎人、白狼王例外,可以在群里开枪。 - `#自爆`、`#决斗` 因身份原因失败时,群里只回复“指令未生效”,具体原因私聊本人,防止被人用失败提示试探身份。 - 群里的座位图和文字列表只显示座位和存活状态。天亮自动发送的列表也一样,即使是私聊行动触发的天亮。 - 机器人私聊时先走群临时会话,失败再走好友通道。 ## 已知限制 - 房主退座后仍保留房主权限(开局、推进投票、结束),这个权限不会转给其他玩家。房主离开群聊时,需要主人发 `#狼人杀结束` 后重新开房。 - 夜间提醒的计时器存在内存里,云崽重启后不再提醒;但对局状态在 redis 里,玩家行动完照样会结算。 - 房间 6 小时没有任何写入会自动过期。禁言中的房间过期不会自动解除禁言,需要管理员手动解除。 - 禁言模式下,夜晚和投票阶段不是管理员的房主、玩家无法在群里发言,`#自爆`、`#决斗`、`#狼人杀结束` 要等发言阶段再发(`#结算` 可私聊)。 ## 开发 ``` werewolf-plugin/ ├── index.js 加载 apps/ 下的插件类 ├── guoba.support.js 锅巴面板配置 ├── apps/ 指令入口,每个文件一个插件类 │ ├── room.js 建房、入座、开局、强制结束 │ ├── day.js 开始投票、投票、结算、自爆、决斗 │ ├── action.js 私聊夜间行动、开枪、狼队传话、私聊查询的路由 │ └── query.js 身份、座位、玩家列表、卡牌图鉴、规则、菜单、战绩 ├── lib/ │ ├── app.js 插件基类:对局群定位、群发 / 私聊、ctx、共用流程入口 │ ├── flow.js 阶段流转:发牌、入夜、天亮结算、白天、猎人开枪、结束 │ ├── views.js 身份图、玩家列表、票型图、整局复盘的渲染发送 │ ├── texts.js 规则与菜单文案 │ ├── recap.js 对局记录与复盘分页 │ ├── constants.js redis 键、角色表、阵营判定 │ ├── game.js 规则引擎:发牌、夜晚结算、连带出局、胜负(纯函数,不碰 redis) │ ├── night.js 夜间指令、行动提示、人齐判定 │ ├── day.js 计票、放逐、自爆、决斗 │ ├── chat.js 狼队夜间传话 │ ├── boards.js 内置模板与动态配板 │ ├── board-config.js 网页选卡校验与角色数量上限 │ ├── board-web.js 配板路由与一次性凭据 │ ├── board-server.js 独立 HTTP 服务 │ ├── config.js yaml 配置读写(首次复制默认配置,写回保留注释) │ ├── web-config.js web.yaml 读取 │ ├── mute.js game.yaml 禁言模式、全员禁言开关 │ ├── store.js redis 房间存取 │ ├── lock.js 每群串行锁、每玩家锁 │ ├── timers.js 夜间提醒计时器 │ ├── stats.js 战绩 │ ├── seating.js 圆桌座位布局 │ ├── role-guide.js 卡牌图鉴数据 │ └── role-art.js 卡面路径 ├── resources/ 配板网页、座位图、图鉴模板与卡面 └── tests/ node:test 测试 ``` 运行测试: ```bash cd plugins/werewolf-plugin npm test ``` 测试会模拟 `redis`、`plugin`、`segment` 和机器人收发,规则代码和指令入口都是真实执行的。 ### 约定 - 锁不可重入。入口函数用 `withRoomLock` 或 `RoomStore.update` 加锁;锁内调用的函数不得再加锁,直接把 room 传下去。 - `night.js`、`day.js`、`chat.js` 不直接收发消息或读写 redis,只通过注入的 `ctx`(`game`、`setRoom`、`say`、`whisper`、`enterNight`、`nextNightOrEnd`、`endGame`、`voteMode`、`syncMute`、`publishVote`)回调插件。 - `apps/` 只放指令入口:加锁、读房间,再交给 `lib/`。新增指令放到对应的 app;多个 app 都要用的流程放 `flow.js`,并在 `app.js` 的基类上暴露入口。 - `flow.js`、`views.js` 的函数第一个参数是插件实例(`WerewolfApp`),用它收发消息和渲染。私聊行动、网页开局时直接 `new WerewolfApp({}, e)` 当裁判引擎用。 - 凡是涉及身份的提示一律私聊;群里的回复不能因为身份不同而不同。 - 插件优先级为 1000,低于 earth-k-plugin 的 `^#玩(.*)`(1145),避免 `#玩家列表` 被抢。和其他插件指令冲突时可以调整。 ### 排查入口 | 症状 | 先看 | | --- | --- | | 夜间指令没反应 | `night.js` 里对应的角色函数,`apps/action.js` 的 `act` | | 夜晚一直不天亮 | `night.js` 的 `needsNightAction`、`nightAllActed` | | 投票或放逐结果不对 | `day.js` 的 `tallyVotes`、`settleVote`、`eliminateByVote` | | 胜负判定不对 | `game.js` 的 `baseWinner`、`checkWinner`,`constants.js` 的 `campOf` | | 私聊行动提示“未找到对局” | redis 键 `Yunzai:werewolf:user:room:`,`lib/app.js` 的 `resolveGroupId` | | 配板网页打不开 | `web.yaml` 的 `host`、`port`、`publicUrl`,以及端口在网络上是否可达 | | 并发覆盖或重复结算 | 入口是否加锁,锁内是否又重复加锁 |