waynebian01 c652c15fac Add ModuleEditorControl and StatusForm enhancements
- Implemented ModuleEditorControl with custom conditions grid and post adjustments handling.
- Added functionality for editing custom conditions and managing adjustment rows.
- Introduced StatusForm with a new Boss Numbers page, including filtering options for boss entries.
- Enhanced UI with dynamic filters for boss types, expansions, and instances.
2026-10-24 14:56:35 +08:00
…
…
…
…
…
…
…
…

Shigure

Shigure 是荒坂公司(Arasaka Corporation)开发的冲锋枪。有时人们只想把子弹全打出去,在硝烟过后品味眼前的一片狼藉。

仓库已内置冬月电子(Fuyutsuki Electronics)的 Fuyutsui 插件源码,无需另行下载或手动安装。

免责声明 (Disclaimer)

  1. 合规责任

    Shigure 仅供技术研究、学习交流和个人实验使用。下载、安装、复制、修改、分发或使用本软件前,用户应自行确认相关行为符合所在地法律法规,以及目标软件、游戏平台或服务提供商的用户协议、服务条款和社区规则。

  2. 账号与处罚风险

    本软件可能涉及窗口状态读取、按键发送或自动化辅助流程。此类行为可能被游戏运营商、反作弊系统或相关服务提供商认定为违规,并导致账号限制、角色封禁、数据丢失、收益回收或其他处罚。用户应充分了解并自行承担全部风险,开发者不对由此产生的任何后果负责。

  3. 无担保声明

    本项目基于 MIT License 开源发布,详见 LICENSE。软件按“原样”(AS IS)提供,不对稳定性、准确性、完整性、安全性、兼容性、持续可用性或特定用途适用性作出任何明示或暗示保证。因使用或无法使用本软件导致的直接、间接、偶然、特殊或后续损失,均由用户自行承担。

  4. 商业使用与衍生版本

    MIT License 允许在遵守许可证条件的前提下复制、修改、分发和商业使用本软件。任何第三方对本软件或其衍生版本的运营、销售、推广、技术支持或其他商业利用,均由该第三方独立负责。开发者不代表、不授权或保证任何第三方产品、服务或运营活动,也不对第三方的违法行为、违反平台规则的行为或由此产生的后果负责。
    但本声明不限制适用法律所规定的责任,也不构成对任何具体行为合法性的保证。

  5. 使用即表示接受

    使用者应在使用前阅读并理解本免责声明及 MIT License。开始使用本软件,表示使用者已获得必要授权,并将自行承担使用本软件产生的风险;但仅通过使用行为是否构成法律上的合同接受,应以适用法律及实际使用场景为准。

项目简介

Shigure 是一个 Windows WinForms 桌面程序。它从目标窗口读取 Fuyutsui 绘制的像素状态,按职业 keymap 和模块规则选择按键,并在界面中展示状态、光环、技能、队伍、动态单位、逻辑结果和运行日志。

程序采用单实例运行;再次启动时会提示“Shigure 已经在运行”,随后退出新实例。

当前版本:1.2.1.36

主要功能

  • 扫描最多 1020 格的顶部状态行和队伍治疗吸收数据;可选择支持窗口遮挡的 Windows 图形捕获(WGC)或原版屏幕截图。
  • 按职业、专精、队伍类型和英雄天赋自动匹配模块,也可手动锁定符合条件的模块。
  • 使用可视化编辑器维护规则、主/子条件、动态单位、数量字段、数值调整和公式动态数值;模块编辑区依次为「逻辑」「列表」「初次调整」「动态数值」「公式」「自定义」「最终调整」;列表独立维护数组,动态数值维护动态单位和数量统计,公式与自定义各自独立编辑。
  • 以对应版本的内置插件目录为权威源编辑职业配置与宏,并按 SHA-256 将插件部署到所选游戏目录及已运行游戏的 Interface\AddOns\{插件名}。
  • 支持 switch、click、hold 三种触发模式,以及除 ALT 外的键盘按键、XBUTTON1、XBUTTON2。

界面

  • 置顶浮动条:显示程序名、当前职业图标颜色和逻辑状态,提供 开启/关闭、设置、✕ 按钮。窗口可拖动和缩放,显示后自动启动运行循环。
  • 通用:顶部可手动选择 Retail Fuyutsui、Forever Shingen 的配置编辑界面,或让编辑界面自动跟随前台游戏;选择会保存到本机设置,不改变运行游戏与插件的绑定。游戏版本卡片还可分别选择正式服和无限服的游戏 .exe 文件作为固定插件部署目录,不限制文件名。还可设置触发键、发送模式和画面捕获方式;“性能”区域可分别调整画面扫描和模块规则计算的间隔;更新界面所选版本的配置并同步对应游戏;当前模块和默认模块设置始终对应运行中的游戏;从 GitHub 按需下载或更新技能/物品图标数据包。WGC 是默认方式,游戏窗口被其他窗口遮挡时仍可读取;窗口最小化或捕获停止时会暂停扫描。原版方式读取显示器实际画面,因此会受到遮挡影响。
  • 配置:直接编辑界面所选版本插件 class/*.lua 中的 ClassBlocks,包括状态、光环、冷却(技能冷却与当前专精物品冷却)和队伍字段;启用队伍时生命值与职责固定开启,驱散、职业可选;玩家、目标、焦点、首领1–5及姓名板光环可用“玩家施放”控制是否追加 PLAYER 筛选,首领1–5只配置敌对减益,未勾选(或 Lua 中省略 isPlayer)时为 false;技能列表页可编辑 spellsList 中的法术 ID、索引和名称(永久服索引 1–255,正式服 1–100),并显示只读的技能等级;同一永久服技能的不同等级共用索引,修改索引或名称会同步该技能组,也可从技能数据库添加;物品列表页编辑职业级 itemsList([itemId] = { index, name },允许同名、禁止同 ID),并可从全量物品数据库添加。旧版稀疏索引格式只读,需先迁移到 states/auras/spells/items/group 格式。
  • 替换技 位于配置页“冷却”后,正式服与永久服均支持,按当前专精(永久服按职业)编辑 ClassBlocks.override。表格包含名称、原始ID(0)、目标ID(1)~目标ID(5);同一专精内名称与原始 ID 均唯一,目标可留空且保留固定列号。每行占一个像素,未替换、未知目标或 API 不可用时返回 0,命中目标时返回 1–5。条件编辑器在“状态 → 替换技”下显示“名称 / 原始ID”,例如 override.206930 == 1;只填写目标ID(3) 时命中返回 3。“吸血鬼打击”“神圣军备”已从特殊状态中移除,统一使用替换技配置。保存与模块依赖快照均保留空位;模块导入按原始 ID 补缺,并按固定槽位补齐目标,冲突保留本地且提示,新增条目与本地名称重复时跳过并提示。Lua 示例:override = { [206930] = { name = "吸血鬼打击", overrideSpellID = { [1] = 433895 } } }。
  • 配置编辑器用“显示层数”“显示充能”“显示施法次数”勾选项决定是否分配计数像素;“显示充能”同时启用充能冷却格和充能数格。Lua 中 maxApps = true 表示显示光环层数,charge = true 同时显示充能冷却和充能数,castCount = true 表示显示施法次数;不再使用 maxCharge。队伍和姓名板光环的 maxApps 为 true 时,剩余时间格后紧邻增加一格层数像素,蓝通道以整数 0–255 编码层数;每个这样的光环为 40 个单位额外占用 40 格。队伍字段 auras.<spellId>.apps 和姓名板字段 nameplates.<槽位>.auras.<spellId>.apps 可用于普通数值条件;队友及敌人数量条件中的光环筛选仍使用剩余时间。队伍或姓名板布局超过主像素行 1020 格上限时会停用对应区域。
  • 队伍与姓名板状态列表按字段分列:队伍展示生命值、治疗吸收、职责、职业及五类驱散时间;姓名板展示生命值、距离、战斗、TTD、仇恨值、施法技能、施法(倒计时)。强化锁喉列仅在当前运行配置启用该字段时显示(正式服奇袭),切换职业、专精或关闭配置后自动隐藏;没有可见敌人时仍按配置保留该列。未配置或无数据的字段显示 -,光环及其余字段集中在末列。
  • 队伍「驱散」提供魔法、诅咒、疾病、中毒、流血五个独立勾选项。每个启用类型每人占一格,通过 AuraContainer 的 HARMFUL 槽检测全部该类减益,不受当前职业驱散能力限制;同类多个减益取最长剩余时间。像素和模块字段使用整数秒:无减益为 0,不足一秒为 1,超过 255 秒及永久减益为 255。对应字段为 魔法/诅咒/疾病/中毒/流血,可通过 group.<槽位>.魔法 或 动态单位名.魔法 引用。未启用的类型不生成字段,实时列表显示 -,已启用但没有减益显示 0。
  • Lua group.state 使用 dispelMagic/dispelCurse/dispelDisease/dispelPoison/dispelBleed 保存五类及其顺序。旧 dispel 开关在原位置展开为五类全选,兼容旧偏移配置及模块依赖快照;新保存只写五类字段。五类全选比旧单格增加 160 格(40 人),保存、迁移转换和依赖导入均检查完整主像素布局,超出 1020 格时拒绝写入和部署并保留原文件。
  • 姓名板 TTD(预计死亡秒数)由 Shigure 根据整数生命百分比计算:优先对最近 5 秒样本做线性回归,无法得到净掉血趋势时依次扩展到 10、15 秒;样本跨度至少 1 秒。掉血速度采用 2 秒时间常数的指数平滑,TTD 为当前生命百分比除以平滑速度并向上取整。暂时无法估算时最多沿用上次速度 3 秒,姓名板消失、死亡或扫描失败立即清空。姓名板状态页固定显示 TTD 列,没有估算时显示 null;未知 TTD 的模块条件不命中。目标、焦点和首领 TTD 共用映射姓名板的结果。
  • “特殊”状态中的“倒数”监听玩家倒计时事件:开始时显示剩余秒数并每秒减 1,取消或归零时显示 0。
  • 正式服“特殊”状态中的“强化锁喉”使用 AuraContainer 原生图标槽显示当前目标身上自己施放的锁喉减益(HARMFUL|PLAYER、703):强化锁喉图标 7195162 输出 1,普通锁喉图标 132297 输出 2,无自己的锁喉时输出 0。不枚举光环、不读取或比较保密图标 ID;默认奇袭配置已启用此字段。数值由替换图标的顶部横条绘制,Lua 状态 getter 仅提供 0 底色。
  • “姓名板”页提供可勾选的“仇恨值”,默认关闭。启用后每个姓名板追加一格(共 40 格),读取 UnitThreatSituation("player", unit):0=未坦克、1=仇恨高但未坦克、2=坦克但仇恨不稳、3=稳定坦克,返回 nil 时按 0 处理。可用 nameplates.<槽位>.仇恨值 或敌人数量/敌人平均血量筛选的“仇恨值”进行比较(例如 >= 2)。开关随配置和模块依赖保存,导入保留已有本地开关;旧状态字段“敌人数量”“敌人数-无仇恨”“敌人数-有仇恨”已移除,改用姓名板动态数量。
  • “目标”“焦点”以及可选的“首领1–5”状态可配置“施法技能”:相邻两格分别定位和显示 UnitCastingInfo 或 UnitChannelInfo 的原始 spellID,无施法时为 0。目标、焦点字段默认加入所有职业专精。姓名板页的同名开关默认关闭;勾选后为每个可见敌对姓名板槽位增加两格(40 槽共 80 格),提供 nameplates.<槽位>.施法技能。定位格编码索引与主色条容量,数据格以完整 RGB 编码 0–16777215,可直接用 == 123456 等数值条件比较。
  • Forever 的玩家“法力值”始终通过曲线输出百分比(0–100),不随普通值或秘密值切换成绝对法力。
  • “姓名板”页的“施法(倒计时)”开关默认关闭,与“施法技能”独立,正式服和永久服均支持。启用后每个槽位在施法技能数据格之后追加一格(共增加 40 格),提供 nameplates.<槽位>.施法(倒计时),优先读取普通施法,否则读取引导的剩余时间,无施法时为 0。整数单位为 0.1 秒(10 ≈ 1 秒),最大表示 25.5 秒;实时列显示原始整数。普通条件、敌人数量及敌人平均血量筛选均支持六种数值比较及公式动态数值,例如用 > 0 与 <= 10 筛选正在施法且剩余不超过约 1 秒的敌人。Lua nameplates.castCountdown 和模块依赖快照保存该开关,导入保留已有本地开关;关闭后不生成字段,已有筛选保留但依赖该字段的条件不命中。像素容量仍按 1020 格上限校验。
  • 正式服奇袭的“姓名板”页提供独立“强化锁喉”卡片,默认启用;Lua nameplates.improvedGarrote 省略时默认开启,明确 false 时关闭,其他专精及永久服不启用。每个姓名板在全部光环及层数字段后追加一格(总计增加 40 格),通过同一原生图标槽输出自己锁喉的 0=无、1=强化、2=普通。字段 nameplates.<槽位>.强化锁喉 可用于普通条件、敌人数量及敌人平均血量筛选,与 nameplates.<槽位>.auras.703.value 的剩余时间独立。开关随配置和模块依赖快照保存,导入保留本地已有开关;本地没有姓名板配置时才采用模块携带的开关。
  • 两个替换纹理位于 Retail/Interface/ICONS/:Ability_Rogue_Garrote.tga(普通,顶部 RGB 255,255,2)和 INV12_Ability_Rogue_Garrote_Empowered.tga(强化,顶部 RGB 255,255,1)。来源为 Clean Icons 12.1.0.69299-V5-1,尺寸为 128×128,视觉顶部第 0–3 行的不透明横条为 128×4,横条外内容保持源文件不变。原生 Texture 使用 TOP 锚点铺满色格,仅采样顶部横条内部的 2×2 区域(裁切坐标 63/128、65/128、1/128、3/128),以固定顶点颜色保留色格索引。实际截图颜色、资源覆盖和战斗安全性需在游戏内验证。
  • 打开 Shigure 时的正式服同步及“更新配置”的全量同步会将这两个纹理部署到游戏的 Interface/ICONS/(不是 AddOns),前提是已设置有效的正式服游戏路径或能检测到对应游戏进程。文件内容相同则跳过复制;启用/暂停切换不会额外触发同步。覆盖已有同名文件前,首次备份为 <文件名>.shigure-original,后续更新保留该备份;同步失败会显示具体文件和原因。替换会影响游戏内所有使用这些资源的位置,首次安装或纹理更新后必须完全退出并重新启动游戏。如需恢复,退出游戏后移走两个替换 TGA;若有备份,将 .shigure-original 文件恢复为原名,再启动游戏。
  • 宏:编辑界面所选版本插件 core/classmacros.lua 中各职业的职业级动态宏、静态宏和特殊宏。动态宏每项占用 40 个团队点名槽位;特殊宏的技能名必须手工填写,不从宏正文解析,生成映射时固定为无目标、无宏条件。
  • 模块:新建、编辑、删除本地模块,维护作者、推荐天赋、匹配条件、动态字段和有序规则。规则支持拖拽、上移、下移、复制与插入。
  • 状态:分栏显示基础状态、auras、spells 和模块计算出的动态单位/数值。
  • 队伍:显示 group 中当前队伍成员及扫描字段摘要。
  • 逻辑:显示命中模块、目标、按键和调试值。
  • 日志:记录启动、停止、职业识别、模块匹配、逻辑状态、施放步骤、配置同步和异常。
  • 关于:显示产品、公司、版本、模块目录、配置目录、免责声明和 MIT 许可证。

触发键、发送模式、画面捕获方式、性能间隔、模块选择、默认模块、模块保存以及配置同步都会按需重启运行循环。仅选择游戏程序路径不会触发重启或同步。窗口位置、大小、主界面横纵布局(两个方向分别保存窗口位置)、画面捕获方式、性能间隔、模块选择、游戏程序路径、按筛选条件保存的默认模块和表格列宽等 UI 状态保存在我的文档目录 {MyDocuments}/Shigure/cache/window-state.json;模块保存在 {MyDocuments}/Shigure/module。cache/ 与模块数据都是本地数据,默认不提交到 Git。

环境要求

  • Windows 10 版本 1903 或更高版本;WGC 会额外执行运行时支持检查
  • .NET 10 SDK
  • 运行扫描需要打开目标游戏窗口;插件部署可选择游戏程序路径,游戏未运行时也能在“更新配置”后安装内置插件

WGC 无黄色提示边框

Windows 的正式无边框捕获流程要求程序具有包身份、在包清单声明无边框能力,并由用户授权。Shigure 使用“外部位置(稀疏)MSIX”只提供身份,程序文件仍保留在普通可写目录,不改变现有配置和插件文件的读写方式。

开发机首次配置:

.\Packaging\New-DevelopmentCertificate.ps1
.\Packaging\Build-SparsePackage.ps1 `
  -CertificatePath .\artifacts\certificate\Shigure.Development.pfx `
  -CertificatePassword Shigure-Development-Only `
  -Register

需要安装 Windows SDK 的 MSIX Packaging Tools(MakeAppx.exe 与 SignTool.exe)。注册完成后,从脚本输出的 artifacts\sparse-package\publish\Shigure.exe 启动,并在 Windows 首次弹出的授权窗口中允许无边框捕获。开发证书仅供本机测试;正式发布必须使用主题为 CN=Arasaka Corporation 的可信代码签名证书。直接运行 dotnet run 没有包身份,系统仍可能显示黄色边框。

运行

在仓库根目录执行:

dotnet run --project .\Shigure.csproj

可选启动参数:

dotnet run --project .\Shigure.csproj -- --toggle XBUTTON2 --mode switch --logic-ms 100 --render-ms 100
  • game_profiles.json:为每个游戏版本指定插件。通用页所选游戏程序的完整路径决定运行版本,即使两套客户端都叫 Wow.exe 也能区分。程序选择 Windows Z 顺序中最靠前的已匹配可见窗口,游戏窗口改变后会切换运行所用插件、配置、键位和模块。缺少此文件时启动会报错。
  • --toggle:触发键,默认 XBUTTON2。
  • --mode:发送模式,支持 switch、click、hold。
  • --logic-ms:初始逻辑计算间隔,默认 100 ms,最小 50 ms;通用页保存的性能设置会在后续启动时覆盖它。
  • --render-ms:UI 刷新间隔,默认 100 ms,最小 100 ms。

发送模式:

  • switch:按一次开启,再按一次关闭。
  • click:每次按下只执行一轮逻辑。
  • hold:按住时运行,松开后停止。

程序会直接从当前 EXE 所在目录运行。Retail 文件集中在 Retail/(Fuyutsui/、config/、keymap/),Forever 文件集中在 Forever/(Shingen/、config/、keymap/)。Fuyutsui 模块位于 {MyDocuments}/Shigure/module,Shingen 模块位于 {MyDocuments}/Shigure/module-Shingen;UI 缓存位于 {MyDocuments}/Shigure/cache。

构建

dotnet build .\Shigure.csproj

应用图标为 Assets\arasaka-icon.ico。项目会把 Retail/**、Forever/** 及 game_profiles.json 复制到输出/发布目录;应用、职业、专精和少量程序专用图标作为嵌入资源打包。完整技能/物品图标库不随发布版分发,用户可在“设置 → 通用 → 下载数据包”中从 GitHub 最新正式 Release 下载到 data\SpellIcons.shgpack。缺少数据包时技能图标与添加技能的 spellId 联想保持关闭,但仍可手工编辑技能。仅技能旧包仍可加载技能;物品搜索库关闭,手工编辑物品保持可用。

SpellIcons.shgpack v2 同时包含 Retail 和 Forever 的独立技能、物品目录,图标按内容 SHA-256 去重。配置、宏、模块和编辑弹窗读取通用页选定的编辑版本;实时状态、光环和冷却读取当前运行版本,两者可以不同。ID、名称注册、搜索和图标缓存均按版本隔离。v1 旧包只属于 Retail,Forever 不会借用其中的数据;通用页会提示缺少 Forever,并显示两版构建号和记录数。缺少个别图标的记录仍保留名称与 ID,并显示占位图。下载失败或远端旧包缺少 Forever 时保留已安装的两版包。

v2 容器为 ZIP:manifest.json 记录格式版本、目录路径、构建、语言、来源和记录数;catalogs/Retail 与 catalogs/Forever 分别存放 spells.json、items.json;记录中的图标摘要引用共享的 icons/<sha256>.jpg。图标引用为空表示该记录缺图。读取时验证版本目录、记录顺序、图标引用和内容摘要,安装时在同目录替换并保留失败回退能力。

构建两版数据包

构建工具只依赖 Python 标准库。保留一份原始 Retail v1 包作为输入;工具将其内容完整导入,并从指定 Forever 构建的 Wago 客户端表获取技能/物品资料,中文名称缺失时回退到同构建英文名称。图标由 wowdev 文件名映射和 Wowhead Forever tooltip 定位,从 Wowhead 图标 CDN 获取。原始表、文件名映射和图标缓存在 artifacts/game-data/sources;生成包与来源/覆盖率/缺失图标报告位于输出目录,不纳入源码提交。

python .\Tools\Build-GameDataPackage.py --retail-package .\原始Retail包\SpellIcons.shgpack --forever-build 1.60.1.70235 --output .\artifacts\game-data\SpellIcons.shgpack

生成的包沿用 GitHub Release 资产名 SpellIcons.shgpack。本地使用时将它放入程序目录 data 后重新启动;也可先保存为 SpellIcons.shgpack.pending,启动时校验并应用。应用只读取离线包,不在查询时抓取网络资料。来源报告中的 Retail 构建号保持未知,除非原始包本身提供了可验证的来源;Forever 构建号与源表摘要明确记录。

缓存齐备后可加 --offline 重建,不再请求网络;缺少源表时构建失败,缺少个别图标时保留占位记录。工具同时输出 .report.json 和 .report.md。v2 包需要支持两版目录的新程序,发布时应同时提供对应程序版本。

项目结构

Shigure.csproj          项目文件与构建资源配置
App\                    程序入口、启动参数和依赖组装
UI\                     WinForms 主界面、配置/宏/模块编辑器和主题
Runtime\                像素扫描、状态构建、运行循环和快照
Modules\                模块模型、匹配、条件、公式和动态字段
Input\                  keymap 读取、按键发送和 Win32 API
Infrastructure\         配置服务、Lua 读写、Fuyutsui 转换和路径定位
Assets\                 应用图标、品牌资源、职业图和专精图
Retail\                 正式服文件:Fuyutsui 插件、config、keymap
Forever\                永久服文件:Shingen 插件、config、keymap
SpellIconPackage\       本地技能/物品图标数据包清单、构建与修复工具(Git 忽略)
Tools\                  辅助脚本

SpellIconPackage/ 中保存数据包源清单、本地构建工具和生成的 SpellIcons.shgpack;整个目录由 .gitignore 排除,不提交到仓库。完整包在 v1 技能索引后追加物品扩展段;仅技能旧包可被新版读取,此时只禁用物品搜索库。

游戏版本与配置同步

在 game_profiles.json 中按版本填写版本目录和插件目录名,例如(旧文件的 process 字段会被忽略,同版本的相同插件映射会合并):

{
  "profiles": [
    { "version": "Retail", "addon": "Fuyutsui" },
    { "version": "Forever", "addon": "Shingen" }
  ]
}

在通用页为“魔兽世界-正式服”和“魔兽世界-无限服”分别选择游戏程序。实际进程路径与无限服所选路径一致时,运行逻辑使用 Forever/Shingen/ 的配置、键位和模块;正式服对应 Retail/Fuyutsui/。完整路径规范化后忽略大小写比较,不按进程名或目录名称猜测版本。未选择、路径失效、进程路径无法读取或没有匹配窗口时等待游戏。两个版本不能选择同一路径;旧缓存中的路径若冲突,会提示并暂停版本识别和插件部署,直到重新选择。

通用页顶部可选择要编辑的版本,选择会保留到下次启动;按“自动”让编辑界面跟随已识别的运行版本。手动切换界面不会改变运行版本,也不会触发部署或重启。切换前如有未保存的配置、宏或模块,先保存或放弃修改;游戏窗口变化仍可切换运行版本。修改 game_profiles.json 后重启 Shigure。dotnet run --project .\Shigure.csproj -- --update-config 与 --update-keymap 会分别为两套插件生成 JSON。

项目中的插件目录是各自版本的权威源。通用 页的“更新配置”会读取界面所选版本:

  • Retail/Fuyutsui/class/*.lua → Retail/config/*.json
  • Retail/Fuyutsui/core/classmacros.lua → Retail/keymap/*.json
  • Forever/Shingen/class/*.lua → Forever/config/*.json
  • Forever/Shingen/core/classmacros.lua → Forever/keymap/*.json

如果运行版本目录的 config/ 或 keymap/ 缺失或文件不完整,启动 Shigure 时会先从对应插件源文件自动补齐;新建 config/ 时也会生成运行时必需的 common.json。手动保存或更新时使用界面所选版本,刷新对应模块编辑器的字段/keymap;仅当它也是运行版本时重启运行循环。选择游戏 .exe 时检查扩展名和文件是否存在,不限制文件名;现有路径缓存继续使用,重新选择后立即重新检查运行目标。仅选择路径不主动同步;如果因此识别到运行版本变化,则执行正常的版本激活与同步流程。

插件只同步到当前版本所选 exe 同级的 Interface/AddOns/插件名,不向父目录回溯,也不会把其他同名进程的目录加入部署目标。所选游戏未运行时仍可点击“更新配置”部署。路径未选择、失效或两个版本路径冲突时提示并跳过游戏部署,本地保存结果保留。部署只复制缺失或 SHA-256 不同的文件,保留游戏目录中的额外文件。

配置 页和 宏 页保存时先写入项目内 Lua、重新生成 config/keymap,再只把当前修改的 Lua 文件部署到游戏目录。找不到目标目录或目标文件不可写时,本地保存不会回滚;界面和日志会提示游戏同步未完成,可选择游戏程序路径后再次点击“更新配置”。

游戏内开关命令

正式服使用 /fu(或 /fuyutsui),永久服将下列命令前缀换为 /sh(或 /shingen)。

功能 命令 行为
爆发开关 /fu cd [on|off|秒数] 不带参数开启 15 秒,on 开启 3600 秒,off 或非正数关闭
次要爆发 /fu mcd [on|off|秒数] 与爆发开关相同,但独立计时;启用时快捷条优先显示绿色及其剩余时间
自定义模式 /fu custom x x 为 0–255 的整数,直接输出像素值 x / 255,运行时字段读取为整数 x
爆发药水开关 /fu potion [on|off] 不带参数切换开关,on 开启,off 关闭

两种爆发到期都会自动关闭,隐藏快捷条也不影响计时。快捷条进度以 15 秒封顶;次要爆发结束后恢复主爆发的红色进度。点击快捷条仍控制主爆发:左键 15 秒、右键关闭、中键 3600 秒。

配置页“配置开关”中可选择“次要爆发”和“自定义模式”,加入当前职业配置后供模块条件读取。原“AOE开关”“输出模式”及 /fu aoemode 已移除,已有模块条件需要改用当前字段。

插入法术与插入物品命令

游戏内可使用 /fu i 技能名称或spellId 临时写入“插入法术”状态。例如 /fu i 奥术洪流 保留按名称查询,/fu i 232633 则直接按 spellId 精确读取当前 Fuyutsui.spellsList 中的本地序号。该命令只检查 spellsList,不检查 ClassMacros,也不接受 target、player 等单位参数;成功后聊天框会显示技能名称、spellId 和本地序号。

同样可用 /fu t 物品名称或itemId 临时写入“插入物品”状态。例如 /fu t 鲁莽药水 按名称查询,/fu t 241288 则按 itemId 精确读取当前 Fuyutsui.itemsList 中的本地序号。该命令只检查 itemsList,不检查 ClassMacros;成功后聊天框会显示物品名称、itemId 和本地序号。模块规则中的 自动插入物品 会读取该状态并映射到 keymap 中的物品宏。

config 结构

config 描述如何把像素数据翻译成运行时状态。字段对象包含:

  • step:顶部状态行的列索引,支持 1~1020;旧配置中的特殊值 "bar" 仍可读取旧版左侧计数条。
  • type:字段类型,支持 int、bool、string。

顶部状态行由 Fuyutsui 绘制,容量按当前专精实际占用分档:默认 510 格,超过 510 升到 765,再超过 765 升到 1020(1020 是上限,再超出则停用姓名板)。每格宽为屏幕宽度除以「当前档位 + 1」。

Shigure 按四套颜色方案解码,红通道是方案序号、绿通道是套内序号、蓝通道 b 是该 step 的原始值:

step 红通道 绿通道
1~255 0 i / 255
256~510 1 / 255 (i - 255) / 255
511~765 2 / 255 (i - 510) / 255
766~1020 3 / 255 (i - 765) / 255

当前档位的最后一个数据格之后还有一格恒定纯红 (1, 0, 0, 1) 的终止色块;Shigure 扫到红色即结束本次主色条扫描,因此不需要知道插件当前用的是哪个档位。数据格的绿通道恒大于 0,不会与终止色块混淆。法术充能数与施法次数的 .count 格紧邻对应技能最后一个冷却格;旧计数条行不再绘制。治疗吸收网格启用时,Shigure 通过首槽前锚点定位网格。

“状态”分类中的“生物类型”读取当前目标 UnitCreatureType("target") 返回的类型 ID,使用与技能充能数相同的秘密值兼容绘制方式,蓝通道等效于 id / 255;运行时和模块条件读取整数 ID,无目标时为 0。Forever 的所有职业默认启用,Retail 可手动添加;在配置页删除该字段即可关闭,关闭后不占像素。

“状态”分类中的“等级”读取玩家 UnitLevel("player"),使用相同的整数像素绘制方式,蓝通道等效于 等级 / 255;运行时和模块条件读取整数等级。Forever 的所有职业默认启用,Retail 可手动添加;删除字段即可关闭,关闭后不占像素。

两版“状态”分类均可手动添加“自动射击”和“自动攻击”,分别读取 C_Spell.IsAutoRepeatSpell(5019) 与 C_Spell.IsCurrentSpell(6603) 的布尔结果。每个字段占一格,像素编码为 1/0,生成配置类型为 bool;默认不启用,删除字段后不占像素。

Forever 的“目标”分类提供“NPCID”,所有职业默认启用,运行时和模块条件使用 目标NPCID。它先检查 UnitGUID("target") 是否为秘密值:秘密值直接显示 0,不解析 GUID,也不保留上次的值;普通生物、载具或宠物 GUID 提取 NPCID,无目标、玩家目标或无效 GUID 显示 0。像素沿用“施法技能”的两格 RGB 编码,删除字段后回收两格;Retail 不提供此选项。

治疗吸收网格最多 40 条,每行 20 条、共两行。每条由前锚点、25 格条身和终点格组成;条身背景的绿通道为 1~25,终点格为 26,蓝通道标识单位。Shigure 读取白色填充右侧的第一格,以 (绿通道 - 1) × 4 得到 0~100 的治疗吸收百分比(每档 4%);填满时由终点格读出 100。插件将秘密吸收量及最大生命值直接交给 StatusBar,由游戏绘制填充。

Retail 的首领时间轴通过配置页“替换技”后的“时间轴”页签启停,所有职业、专精默认启用(timeline = true)。启用时在替换技之后、物品字段之前占用 15 格,关闭时不占像素,按剩余时间从短到长显示 5 个事件,同时间按事件 ID 排序,不足补零。每个事件依次占用技能 ID 定位格、秘密值 RGB 格和剩余时间格;秘密 spellID 沿用施法技能的原生格式化字形绘制。剩余时间按 秒数 × 10 四舍五入后写入蓝通道,最大为 255(25.5 秒),例如 9.5 秒为 95 / 255;归零后保留事件直到接口移除,不显示持续时间。“实时数据 → 时间轴”(位于姓名板下方)集中显示五个事件;模块条件可读取 时间轴1技能ID、时间轴1剩余时间 至 时间轴5技能ID、时间轴5剩余时间,剩余时间以秒为单位并支持小数。更新插件后需在游戏内 /reload。

条件编辑器的“时间轴”类型提供“时间轴1”至“时间轴5”和“任意时间轴”分类,每类均可选择 spellID 或“剩余时间”。固定槽条件继续保存原字段键;“任意时间轴”保存为 timeline.any.spellID 和 timeline.any.remaining,只比较 spellID 大于 0 的事件,并要求整条规则的主条件和命中的子条件由同一个事件满足。例如 timeline.any.spellID == 123 && timeline.any.remaining < 3 表示技能 123 自身的剩余时间小于 3 秒。空槽不参与匹配;无事件时任意时间轴比较为 false,但普通条件所在的“或”分支仍可独立命中。

两版均在“能量”后提供“区域”分类,包含“地图”“地下城”“团队副本”“首领战”“首领战难度”和“副本难度”:“地下城”和“团队副本”将 GetInstanceInfo() 的游戏副本 ID 按各版本 core/config.lua 的 dungeonIndex / raidIndex 转成各自编号,非对应类型或未配置时为 0。Forever 的独立列表按推荐等级排序;Retail 的独立列表按资料片从早到晚排序(150 个地下城、65 个团队副本),两类各自独立编号;模块数字数组分别读取当前版本 config/dungeons.json、config/raids.json。地图 为 C_Map.GetBestMapForUnit("player") 返回的界面地图 ID,不可用时为 0,使用两格 RGB 编码传递完整 ID。前三个字段在进入世界、区域变化和重建状态时刷新。副本技能参考页读取同一套 Retail 列表,Retail/spell_icons.json 的 instanceId、encounterId 分别使用游戏实例 ID、Encounter ID 关联新目录,界面显示副本类型、编号和副本内首领序号。旧模块中用于判断副本编号的“地图”或“副本”条件需改为“地下城”或“团队副本”,并使用对应列表中的编号。

“首领战难度”(原“难度”)读取 ENCOUNTER_START 的 difficultyID,首领战结束归零;“副本难度”读取 GetInstanceInfo() 的第三个返回值 difficultyID,随地图字段在进入世界、区域变化和重建状态时刷新,野外或无难度信息时为 0,不随首领战结束清零。两者均输出游戏原始难度 ID,不表示大秘境层数。旧 Lua 配置、模块依赖与条件里的“难度”继续对应“首领战难度”;配置保存后使用新名称。

“区域”还可添加“大秘境层数”“大秘境时间(分)”和“大秘境时间(秒)”,各占一个像素。层数读取当前已开启的挑战;时间使用游戏挑战计时器的已用时间,按完整分钟和分钟内秒数拆分(例如 12 分 34 秒输出 12、34,秒数为 0–59),层数和分钟最多输出 255。每次登录、重载界面或进入世界时读取一次,挑战开始时立即读取,之后每秒刷新;挑战完成或重置时三个字段立即归零,非挑战状态及相关 API 不可用时也显示 0。两版插件均支持,需在配置页选入所需字段并保存,更新插件后在游戏内 /reload。

“首领战”使用每个副本内从 1 开始的序号,非首领战、未配置及战斗结束时输出 0,须与“地下城”/“团队副本”条件组合。映射键是 Wago DungeonEncounter.ID,输出值不是游戏完整 ID,也不是旧全局首领编号;两版分别读取各自的 config/bosses.json 和 Lua bossID。详见 Retail 首领列表、Forever 首领列表。条件编辑器已选定副本时显示该副本首领名;未指定副本时仅显示副本内序号。首领数字数组同样保存副本内序号。“参考 → 首领”支持类型、版本(资料片)、副本三级联动筛选,条目数量随结果更新;同名副本按实例 ID 区分。旧模块的首领编号条件及首领数字数组需按新表更新。

common.json 保存固定启动字段 锚点、职业、专精。其余文件按英文职业名命名,例如 Warrior.json、Priest.json,每个文件包含:

  • keymap:该职业使用的 keymap 文件名。
  • 一键法术:状态中的本地技能索引到 spellId 的映射。
  • 一键物品:状态中的本地物品索引到 itemId 的映射。
  • 以专精 ID 为键的对象,包含普通状态与物品字段,以及可选的 auras、spells、group。

运行时先读取 common.json 确定职业和专精,再合并对应专精配置。group.start 是队伍数据起始列,group.num 是每名成员占用的列数;组内字段的 step 是相对偏移。 队伍配置可按专精勾选“职业”。勾选后插件为每名队友增加一个像素,写入与玩家职业相同的职业 ID(1–13);未勾选时不占像素。实时队伍页显示职业名称和 ID,模块的队友筛选可用职业 ==、!= 比较;没有采集到职业的成员不满足职业条件。

keymap 与单位编号

每条 keymap 记录包含 unit、技能、热键 和可选的 宏条件。模块和 keymap 共用以下单位编号:

  • 0:无目标。
  • 1~40:队伍/团队槽位。
  • 41:玩家。
  • 42:当前目标。
  • 43:焦点。
  • 44:地面。
  • 45:鼠标指向。
  • 46~50:首领 1~5。
  • 51~55:竞技场单位 arena1~arena5。

当前映射版本为 UnitMappingVersion = 4。版本 1 模块会迁移旧的 31/34 含义;版本 2 模块中的 36/37 会迁移为 unit 0,并分别补成 channeling / nochanneling 宏条件;版本 3 的保留单位 31~35 会迁移到 41~45。生成的 keymap 同样携带映射版本,确保新版团队槽 36/37 不会被当成旧宏条件。

像素状态中的“目标类型/焦点类型”会把 arena1~arena5 编码为 51~55,“其他单位”使用 56;友方仍在基础编号上加 100。

模块系统

宏快照和 keymap 现按职业级动态宏处理;左右修饰键共 26 组、44 个基础键,屏蔽 1 个不可用组合后总容量为 1143 个槽位。

模块宏导入同样按职业级列表合并;历史模块中的专精动态字段只作兼容迁移,牧师/圣骑士合并后写入职业宏,其他职业丢弃。

模块以 模块名.json 保存在我的文档目录 {MyDocuments}/Shigure/module。名称不能重复;加载时会递归扫描子目录,以兼容旧版布局。模块页保存时会写入当前 Shigure 版本。版本不一致或为空的模块仍可把有效的依赖快照导入本地配置和宏,但不会参与模块选择和运行;编辑器列表中显示为红色,可在检查并显式保存后升级到当前版本。职业和专精均已指定时,模块还会携带该专精的 ClassBlocks(包括姓名板配置)、职业 spellsList 与 itemsList,以及该职业的职业级动态宏、静态宏和特殊宏。

启动和“刷新模块”会把模块携带而本地缺少的配置与宏追加到当前版本的插件目录。光环、姓名板光环、法术和技能列表都以 spellId 判断同一条目,不再按名称回退:光环任一 ID 重合即合并 ID 集合,maxApps 仅补本地空值,isPlayer 不同时保留本地并提示冲突;本地尚未启用姓名板而模块带有姓名板配置时,会创建姓名板配置并导入其光环。法术的布尔属性采用 true 补齐 false;施法次数开关仅补本地空值,双方有差异时保留本地并提示冲突。技能列表快照不保存来源索引;同一 spellId 保留本地索引和名称,缺失 spellId 按模块快照追加,并自动分配当前职业 1–255 中最小的可用索引。索引已满时拒绝该模块依赖导入。物品冷却以 itemId 判断同一条目,isEquipped 用 true 补齐 false,空名称补齐,名称不同则保留本地并提示冲突;名称已被其他 itemId 占用或与状态字段重名则跳过追加。物品列表同一 itemId 保留本地索引和名称,缺失 itemId 按模块快照追加。队伍配置同样合并:保留本地字段顺序并追加缺少的状态字段,生命值与职责为必需字段;队伍光环按 spellId 合并 ID 集合和缺少的名称、maxApps,已有 maxApps 冲突时保留本地并提示。合并后的完整主像素布局(状态、光环、冷却、40 人队伍及姓名板)超过 1020 格时,拒绝该模块的全部配置和宏写入,并弹窗提示合并失败及所需格数。发生新增或补齐后会自动重建 config/keymap、同步游戏插件并按需重启运行。导入前会按每项动态宏 40 个槽位、静态/特殊宏各 1 个槽位检查职业级宏总容量;合并结果超过 1143 个槽位时,整个模块不会进入模块列表或运行时,本地 Lua 也不会被修改。模块文件仍保留在模块目录,调整配置或清理宏后可刷新重试。

模块匹配字段:

  • ClassId:职业 ID。
  • SpecId:专精 ID。
  • PartyType:0 为单人、1-40 为团队、46 为队伍。
  • HeroTalent:英雄天赋 ID。

任一字段留空(界面显示 任意 (*))即为通配。多个模块同时匹配时,优先选择具体匹配字段更多的模块,相同则按名称排序。RecommendedTalent 仅用于说明,不参与匹配。

模块文件示例:

{
  "Id": "戒律-20260730120000000",
  "Name": "戒律",
  "Author": "模块作者",
  "RecommendedTalent": "推荐天赋代码或说明",
  "Version": "1.2.1.36",
  "UnitMappingVersion": 4,
  "Enabled": true,
  "Match": {
    "ClassId": 5,
    "SpecId": 1,
    "PartyType": "46",
    "HeroTalent": 1
  },
  "Units": [],
  "Counts": [],
  "ValueAdjustments": [],
  "Rules": [
    {
      "Enabled": true,
      "Condition": "生命值 < 50 && spells.17.cooldown == 0",
      "Unit": 41,
      "Spell": "真言术:盾",
      "Hotkey": "",
      "Step": "自保"
    }
  ]
}

规则按顺序判断,第一条命中的规则会执行。普通动作的 Spell 保存并使用“技能”列中的技能或宏名称,不用 spellId 判断;运行时按名称、目标单位和宏条件查找 keymap 热键。填写 Hotkey 时会直接发送该键。技能下拉还包含以下特殊动作:

  • 暂停:命中后不发送按键,并停止继续匹配本轮后续规则。
  • 自动插入法术:读取状态字段 插入法术,按职业配置映射到当前可用技能。
  • 自动插入物品:读取状态字段 插入物品,按职业 itemsList 映射到当前可用物品宏。
  • 一键法术:读取状态字段 一键辅助,按职业配置映射到技能。

条件

声音识别与录制按键

在条件编辑器的 Shigure 类型中也可选择 音量识别,读取目标游戏程序当前音频会话的峰值,范围 0–100,保留小数。例如 音量识别 > 15.5、音量识别 <= 5;支持普通数值比较运算符。这里读取的是实时声音信号峰值,不是系统或游戏设置中的音量滑块数值。没有播放声音时为 0;读取失败时显示错误,相关条件按不命中处理。

音量识别按当前扫描的游戏窗口及其进程 ID 匹配音频会话,枚举所有活动播放设备,不受默认设备限制;同一目标进程有多个会话时取其中的最大峰值,其他进程的声音不会计入。实时“状态”页可查看 音量识别 的当前值,便于确定阈值。配合“技能 = 按键”,音量超过阈值时发送一次,回落后再次超过阈值才会再次发送。

声音文件统一放在 {MyDocuments}/Shigure/Sounds(Windows“文档/Shigure/Sounds”)。首次新建此目录时会放入三个钓鱼浮漂溅水样本 FishingBobber_ver2_1.ogg、FishingBobber_ver2_2.ogg、FishingBobber_ver2_3.ogg。音效下拉直接列出目录中的 WAV / OGG 完整文件名,包含扩展名,条件按这个文件名判断;不再使用“钓鱼上钩”分组名称。可直接把音效放入目录,或通过“导入音效…”复制不超过 5 秒、10 MB 的文件到该目录。改名后需在条件里重新选择名称;分享模块时也需要携带相应声音文件。

规则的“技能”选择 按键,点击“目标”格录制一个键盘按键、组合键或鼠标键,然后点击保存。条件命中时直接发送录制的按键,不需要配置职业宏或 keymap。普通条件持续成立时只发送一次,条件不成立后重新触发;声音条件每次识别到对应音效发送一次。发送失败不会把该规则标为已发送。复制、移动规则或重新打开模块都会保留录制结果。鼠标键发送使用发送时鼠标所在的位置,鼠标位置不包含在录制中。

例如:技能 = 按键、目标 = F、条件 = 声音识别 == "FishingBobber_ver2_1.ogg"。也可用“或”连接三个文件名以识别任一钓鱼变体。打开逻辑后,每次识别到所选音效发送一次 F。仍需有效游戏状态和已匹配的游戏窗口,按键遵循已有的触发模式、规则顺序及延迟设置。

声音识别使用默认播放设备的实时音频,通过短时频谱时序匹配在本地运行,不调用云端模型。只有当前模块包含已启用的声音条件且逻辑开启时才捕获音频;关闭逻辑或失去有效游戏状态会清空待处理事件。游戏需要通过默认播放设备出声;其它程序播放相同音效也会被识别,背景音乐和水声可能影响识别效果。音频设备不可用或音效文件缺失时,逻辑页会显示失败原因,普通规则仍可运行。

支持的常见表达式:

  • 状态:生命值 < 50、战斗时间 > 0。
  • 玩家光环:auras.player.114255.value > 0;层数使用 .apps。
  • 目标/焦点光环:auras.target.harmful.55078.value > 0、auras.focus.helpful.12345.value > 0。
  • 首领减益:auras.boss1.harmful.55078.value > 0(首领2–5分别使用 boss2–boss5)。
  • 技能:spells.633.cooldown == 0;充能冷却和层数分别使用 .chargeCooldown、.count。
  • 队伍:group.1.生命值 < 60。
  • 列表:目标类型 in (1, 2)、职业 not in (4, 9)。
  • 模块数组:在「动态数值 → 数组」中创建名称和数字列表,例如 数组1 = { [123] = true, [456] = true };条件可写 目标施法技能 in 数组1 或 焦点施法技能 not in 数组1。数组按模块保存,编辑数字时自动显示 SpellIcons.shgpack 中对应的法术图标和名称;找不到法术资料的数字仍可保存。
  • 敌人数量与敌人平均血量的筛选可选择姓名板“施法技能”(需在姓名板配置中启用)。可按原始 spellID 写 == 123456、!= 123456,或选择 in、not in 并引用本模块数组。无施法读数为 0;多个敌人按各自姓名板槽位独立匹配。
  • 组合:生命值 < 50 && spells.633.cooldown == 0、目标类型 == 1 || 首领战 > 0。
  • 字段间比较:无痛敌人 <= 有效敌人数量,比较符右侧除数字外还可以写另一个字段名。
  • 布尔简写:移动 表示为真,!移动 表示为假。
  • 空条件:始终命中。

一键辅助、插入法术、玩家分类的施法技能、上个技能 是技能列表索引状态。可视化编辑器为这些字段提供“技能图标 / 技能名称 / spellId”下拉;==、!= 与数组的 in、not in 均按 spellId 编写,运行时按当前职业的 spellsList 把 spellId 转换为本地索引后再比较,因此模块不依赖来源职业文件中的索引分配。找不到 spellId 时,单值条件按不命中处理。目标、焦点、首领和姓名板的施法技能直接返回原始 spellID,使用普通整数条件或模块数组。

永久服玩家状态 技能等级 返回当前读条或引导技能的 Rank(例如暗影箭 686 为 1、695 为 2,两者技能索引均为 3),未施法或技能未收录时为 0,结束、取消或打断后清零;瞬发技能不保留等级。由于同技能各等级共享索引,需要结合 施法技能 与 技能等级 条件区分施放等级。职业技能表使用 Wowhead Forever 数据,无数字等级的技能按 Rank = 1 保存。等级与共享索引随模块依赖快照保存,旧模块和缺少 Rank 的技能列表仍可读取;界面缺少等级时显示空白。数据来源、日期和收录统计见 Forever/reference/职业技能等级来源.json,更新脚本为 scripts/update_forever_spells.py,数据及生成配置的一致性可通过 python scripts/validate_forever_spells.py 校验。

插入物品 是物品列表索引状态。可视化编辑器提供“物品图标 / 物品名称 / itemId”下拉,并且只允许 ==、!=;模块条件保存 itemId,运行时按当前职业的 itemsList 把 itemId 转换为本地索引后再比较。找不到 itemId 时同样显示为红色,条件按不命中处理。

生成的 config/*.json 和运行时状态使用“范围 + spellId + 数值类型”的结构化键;字段节点中的 displayName、spellId、scope、metric 和 spellIds 仅用于显示及别名解析。多 ID 光环优先使用单值 spellId,否则使用最小有效 ID 作为规范键,其余 ID 映射到同一运行时值。普通条件、子条件、动态数值、公式、动态单位和人数统计均持久化 spellId;缺失引用会保留原 ID、显示红色并按不命中处理。

字符串可以使用单引号或双引号。true/yes/是、false/fu/否、null/nil/空 会转换为对应字面量。&& 的优先级高于 ||,主表达式不支持括号嵌套。

规则还可添加多个“子条件”:主条件与子条件组是“且”关系,子条件之间是“或”关系,即 主条件 && (子条件 1 || 子条件 2)。这用于表达主编辑器无法用括号表示的逻辑。

可视化条件编辑器会按当前职业/专精提供状态、光环、冷却(技能/物品)和动态单位字段,并支持:

  • 数字比较 ==、!=、>、>=、<、<=。
  • 文本/数字列表比较 in、not in。
  • 数值字段的「值」列既可手填数字,也可从下拉中选择动态单位的数量、生命值或动态数值作为比较对象;右侧写成未加引号、能解析出数值的字段名时按该字段的当前值比较,否则仍按字面量处理。
  • 延迟 (ms):限制同一规则两次实际发送的最小间隔。
  • 逻辑延迟 (ms):发送后暂停模块规则计算指定时间;画面扫描、触发键检测和界面刷新仍继续。
  • 延迟命中 (ms):规则轮到判断且命中后,等待指定时间再执行;每次实际发送成功后,重新计算下一次等待。等待期间默认停止本轮后续规则判断,设置“继续逻辑”则继续后面的判断;扫描、前面规则判断和界面刷新仍继续。条件失效且“持续命中”保护结束时取消等待,下次命中重新计时。发送失败或被发送限频拦住不重新计时;等待到期后仍须轮到本规则才执行。0 或未设置表示不等待。
  • 持续命中 (ms):整条规则的条件由命中变为不命中后,继续保持命中指定时长。计时从第一次检测到不命中开始;期间恢复命中会取消倒计时,下次不命中时重新计时。主条件与子条件组一起判断,0 或未设置时立即取消命中。例如设置 500 ms,条件短暂消失 200 ms 后恢复仍视为一直命中;连续不成立满 500 ms 后取消。设置了持续命中且未设置“继续逻辑”的规则,轮到执行或等待延迟命中后会锁定自身,保持命中期间其他规则(包括上方规则)不能抢占;取消命中后恢复从上到下判断。配合“按键”或声音动作,保持期间不会重复发送,也不会放行其他规则,取消后重新命中才再次发送。设置“继续逻辑”时仍允许其他规则执行,不锁定。持续命中与延迟命中独立计时,等待或执行命令不会延长保持时间。关闭逻辑、游戏状态失效或切换模块会清除保持与锁定状态。
  • 继续逻辑:本规则命中并发送后,或正在等待“延迟命中”时,继续判断后续规则;后续命中也可再发送,直到遇到未设置继续逻辑的命中规则或列表结束。

单击模式首次判断确定本次触发涉及的规则,延迟期间仅复查这些规则,每条最多执行一次;全部等待执行或取消后结束本次触发,不纳入后来新命中的规则。再次单击会取消旧批次并重新开始。关闭逻辑、松开按住键、游戏状态失效、切换模块或重启运行时都会清除等待。

缺失或非数字字段参与大小比较时视为不命中,不会中断运行。

动态单位、数量与动态数值

这些字段按 group 状态每帧重新计算。多数动态选择与数量统计会跳过 职责 == 0 的单位;具体生命值过滤取决于字段类别。

  • 队友单位:与队友数量共用条件组列表筛选有效队伍单位,再按「查找的单位」选出唯一槽位。目标字段为生命值/治疗吸收时可选最低或最高;职责为正序或倒序(按队伍槽位);五类驱散时间可分别选择最长或最短,只比较时间大于 0 的队友,并列取最小槽位,无匹配时不解析目标;光环可选最长、最短,或在拥有目标光环的队友中按队伍槽位正序、倒序,并须指定目标光环。可选「值名称」把所选单位的目标字段值暴露为同名数值条件字段。旧单位专用筛选字段不再迁移。队友单位可在规则目标中直接使用,也可用裸名称判断是否成功解析。
  • 队友数量:使用条件组列表筛选有效队伍单位。每组可选“全部满足”或“任一满足”,组与组之间按“且”组合;条件支持生命值、治疗吸收、职责、五类驱散时间、职业及配置中的队伍光环。职责和职业只允许 ==、!=,职业值从中文职业下拉选择;其它数值字段支持 ==、!=、>、<、>=、<=。生命值、治疗吸收、驱散时间和光环的右值可手填整数,也可从下拉菜单选择本阶段及之前可用的整数数值名称(不含公式和自定义),或填写其它动态字段名。例如 魔法 > 0 检测魔法减益,魔法 > 0 且 魔法 <= 5 筛选剩余不超过五秒的队友。关闭配置后已有驱散条件保留并标示“未配置”,相关条件不命中,目标不解析。禁用行及没有启用行的空组会被忽略。该字段只能用于条件。
  • 旧模块 驱散 == 类型(编号 1/2/3/4/11)加载时转为对应驱散时间 > 0,!= 类型 转为 == 0,保存后持久化;加载不会自动改写模块文件。旧「驱散 → 正序/倒序」继续按槽位选择,其余旧驱散引用使用兼容类型编号:按魔法、诅咒、疾病、中毒、流血顺序取首个存在类型,无则为 0,不额外占像素;新建编辑不再提供旧驱散字段;五类时间字段的旧名称“驱散魔法/驱散诅咒/驱散疾病/驱散中毒/驱散流血”仍作为兼容别名读取,界面与新配置统一使用短名称。
  • 敌人数量:使用与队友数量相同的条件组列表,支持生命值、距离、战斗及配置中的姓名板光环;姓名板启用“仇恨值”后可按 0–3 状态进行数值筛选,关闭时该条件不满足。正式服奇袭启用姓名板强化锁喉时,还可筛选“强化锁喉”,仅支持 == / !=,值选择 0=无锁喉、1=强化锁喉、2=普通锁喉;关闭或未配置该字段时依赖它的条件不满足。生命值、距离和光环的右值可手填整数,也可从下拉菜单选择本阶段及之前可用的整数数值名称(不含公式和自定义)。基础范围只包含存在且距离大于 0 的姓名板。光环 == 0 表示缺少、!= 0 表示拥有,其他比较仅在光环存在时判断,因此小于条件不会把缺少光环的单位统计进去。旧版专用数量筛选不再迁移或兼容。
  • 平均血量:可选择队友或敌人作为统计对象,并与数量字段共用条件组列表筛选候选。队友基础范围为职责不为 0 的队伍单位;敌人基础范围为存在且距离大于 0 的姓名板。筛选后对剩余单位的生命值取平均(四舍五入为整数),无匹配单位时为 0。旧版卡片筛选不再迁移。
  • 初次调整:在“字段”列选择已有状态、光环或技能字段,“调整方式”支持 +(加)、-(减)和 =(直接赋值),默认 +。“调整”可手填整数,选择 = 时也可从下拉选择“布尔值”:本行条件命中时赋值为 true,不命中时赋值为 false,空条件视为命中。使用 +、- 时隐藏布尔值下拉,只接受整数;从赋值切换到加减时,已有布尔值重置为 0。不能调整后续阶段生成的动态单位、数量统计、公式或自定义字段。旧模块中手填的 true、false 继续按原有条件赋值语义读取。赋值为 0 或 false 同样会执行。
  • 动态队友:初次调整的“类型”选择“动态队友”后,目标可选队伍槽位 1–40、“施法目标”或“队伍类型”;字段只提供配置「队伍」中启用的成员字段及光环时间/层数,调整方式和条件沿用数值调整。“队伍类型”在团队中使用自己的团队编号,小队 46 和单人 0 自动定位自己的槽位 1。目标未解析、编号越界、成员无效或字段未配置时跳过调整。初次调整的所有行在选人前执行,使本帧选人和数量统计使用新值。调整不能引用或修改后续生成的动态单位、数量统计、公式或自定义结果;旧模块中此类调整保留并标红,运行时跳过,修正或删除后才能保存。每行每帧最多执行一次,下一帧恢复扫描值,不跨帧累计。
  • 自定义字段:在“自定义”页输入名称和条件,赋值固定为只读的“布尔值”,没有下拉菜单。每帧进入自定义阶段时先重置为 false,再按行顺序将条件结果写为 true 或 false;空条件视为 true,同名多行由后面的行覆盖。条件可使用调整后的基础字段、动态单位及数量统计、公式和前面自定义行的结果。条件编辑器的“类型 → 自定义”集中提供这些字段的布尔比较;Shigure 类型保留程序内置字段。旧自建整数及固定 true/false 赋值统一按条件布尔值读取,保存时写为“布尔值”。
  • 最终调整:在自定义之后、逻辑判断之前按行执行,可再次调整初次调整后的基础字段、动态单位值名称、数量与平均血量、公式结果和自定义字段,也支持以动态单位为队友目标修改成员字段。数字支持 +、-、=;自定义字段仅支持 = 和布尔赋值,选择自定义目标时自动切换为“布尔值”。后面的调整行和逻辑读取更新后的结果;不会重新选人、统计或重算公式、自定义。下一帧重新从像素和各阶段生成的值开始,不跨帧累加。模块 JSON 的最终调整行使用 IsPostAdjustment: true,旧行缺省仍为初次调整。
  • 公式动态数值:使用字段和算术表达式生成命名数值,支持 + - * /、括号、一元正负号和 int、round、floor、ceil、min、max。

列表在模块启用时载入为共享只读缓存,逐帧复用,保存或重新加载模块后更新。模块每帧按「像素获取 → 初次调整 → 动态单位及数量统计 → 公式 → 自定义 → 最终调整 → 逻辑」执行;列表可供各阶段引用,后续阶段生成的字段不能被前面的阶段引用;最终调整可以引用全部前置阶段的计算结果。旧“自建”字段自动显示在“自定义”页,模块 JSON 格式保持兼容。

动态单位和数量阈值既可使用固定值,也可引用本阶段及之前可用的动态数值。规则引用未解析出的动态目标时会跳过该规则,继续判断下一条。

模块 JSON 使用 Units、Counts、ValueAdjustments 保存这些定义;规则使用 UnitName 引用动态单位。名称不能是纯数字,不能包含 . 或 $,也不能与已有状态字段或其它动态名称冲突。

默认逻辑与 C# 扩展

如果没有匹配模块,LogicRegistry 会尝试使用按职业注册的 IClassLogic。当前没有注册项时会进入 DefaultClassLogic:仅当 一键辅助 == 10 且 keymap 中存在 一键辅助 时发送按键,否则显示“C# 职业逻辑尚未迁移”。

通常应优先在 模块 页维护逻辑。确实需要复杂算法时,可实现 IClassLogic 并在 LogicRegistry 中按职业 ID 注册:

public sealed class PriestLogic : IClassLogic
{
    public LogicDecision Run(GameState state, string? specName)
    {
        var health = state.GetInt("生命值");
        return new LogicDecision(
            Hotkey: null,
            Step: $"当前生命值: {health}",
            UnitInfo: new Dictionary<string, object?>());
    }
}

职业逻辑可通过 GameState.GetInt(...)、GameState.GetBool(...)、state.Auras、state.Spells、state.Group 读取数据,并返回 LogicDecision。也可以创建匹配字段全部留空的通配模块,覆盖默认逻辑。

Description
魔兽世界外挂
Readme MIT 172 MiB
Languages
C# 59%
Lua 39.5%
Python 1.3%
PowerShell 0.2%