Shigure

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

它需要配合 冬月电子Fuyutsuki ElectronicsFuyutsui使用。

免责声明 (Disclaimer)

  1. 合规责任

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

  2. 账号与处罚风险

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

  3. 无担保声明

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

  4. 商业使用与衍生版本

    MIT License 允许在许可证范围内复制、修改、分发和再许可本软件,但任何组织或个人若将本软件或其衍生版本用于商业用途、付费服务、代练、外挂销售、打包分发或其他可能违反第三方服务条款的场景,应独立承担由此引发的法律纠纷、平台追责、知识产权争议、账号处罚和赔偿责任。原开发者不参与此类商业运营,也不承担连带责任。

  5. 使用即表示接受

    一旦开始使用本软件,即视为用户已阅读、理解并同意本免责声明及 MIT License 的全部内容。若不同意,请立即停止使用并删除本软件及其副本。

真实作用

Shigure 是一个 Windows WinForms 桌面程序,用于扫描目标窗口状态、根据职业 keymap 选择按键,并把实时状态、队伍信息、逻辑输出和运行日志集中显示在 UI 中。

当前版本:1.2.0.0

当前界面

  • 置顶浮动条:无边框小窗口,显示 Shigure 标题和逻辑状态,右侧有 开关(文字在 开启/关闭 间切换)、设置 三个按钮;窗口可拖动、可从边缘缩放,启动后会自动启动运行循环。
  • 设置窗口:点击 设置 打开,集中包含 通用模块状态队伍逻辑光环识别日志关于 八个页签。
  • 通用页:可设置触发键、发送模式和当前使用的模块。模块选择器会根据实时识别到的职业 / 专精 / 队伍类型 / 英雄天赋筛选可用模块,可保持自动选择最匹配模块,也可从符合条件的模块中手动指定一个。点击触发键按钮后按下目标键即可录入,支持键盘按键、XBUTTON1XBUTTON2,不支持 ALT
  • 模块页:左侧列出全部模块,右侧可新建、编辑、删除模块,并编辑模块名称、匹配条件(职业 / 专精 / 队伍类型 / 英雄天赋)和判断规则。这个页面只负责逻辑编辑;具体启用或选择哪个模块在“通用”页完成。规则表的“技能”“目标”列为下拉菜单(选项来自当前选中职业的 keymap“条件”列为只读点击后弹出可视化条件编辑器。页面内嵌“动态单位 / 数量字段”面板,可定义如“最低血量单位”这类按队伍状态实时解析的单位,供“目标”和“条件”引用。
  • 状态页:显示当前匹配的模块名以及扫描后构建出的状态字段,右侧并列显示 spells 技能状态。
  • 队伍页:显示 group 队伍成员摘要。
  • 逻辑页:显示模块或职业逻辑返回的诊断信息(命中条件、动作技能、动作按键等)。
  • 光环识别页:使用 Fuyutsui 提供的定位点截取光环区域,并通过 dHash + 模板匹配 识别图标;默认启用 250ms 实时扫描,手动缓存图片、刷新模板、打开模板目录,并在“识别结果 / 已有图标”之间切换查看和命名图标。启用识别后,已命名的识别光环会导入运行状态与光环列表,供模块条件引用;实时扫描不保存临时图标,手动扫描会保存未命名图标到 tmp 等待整理。
  • 日志页:记录启动、停止、职业识别、模块匹配、逻辑状态变化、步骤变化和异常信息。
  • 关于页:显示产品名、版本、运行目录、模块目录和配置文件路径。

触发键、发送模式的修改会立即重启运行循环。模块会保存到 module 文件夹,修改并保存后同样会重启运行循环以加载最新模块。窗口位置/大小、UI 状态(如规则表的列宽)会被缓存到 cache/window-state.json,下次启动时自动恢复。

运行环境

  • Windows
  • .NET 10 SDK

运行

在仓库根目录运行:

dotnet run --project .\Shigure.csproj

也可以传入启动参数:

dotnet run --project .\Shigure.csproj -- --window 魔兽世界 --toggle XBUTTON2 --mode switch --logic-ms 100 --render-ms 100

参数说明:

  • --window:目标窗口标题,默认 魔兽世界
  • --toggle:触发键,默认 XBUTTON2
  • --mode:发送模式,支持 switchclickhold
  • --logic-ms:逻辑循环间隔,默认 100,最小 50
  • --render-msUI 刷新间隔,默认 100,最小 100

发送模式:

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

构建

dotnet build .\Shigure.csproj

应用图标来自:

Assets\shigure-emblem-arasaka.ico

项目结构

Shigure.csproj          项目文件,复制 Assets/config/keymap/module 到输出目录
App\                    程序入口与启动参数解析
UI\                     WinForms 界面、编辑器、主题和 UI 缓存
Runtime\                扫描、状态构建、逻辑运行和运行时快照
Modules\                模块模型、存储、匹配、规则执行和字段目录
Input\                  keymap 读取、按键发送和 Win32 API 互操作
Infrastructure\         配置读取与 JSON 辅助方法
Assets\                 图标与品牌资源
keymap\                 各职业按键映射
module\                 UI 可编辑模块

配置文件

  • config/*.json:状态扫描配置和职业 keymap 引用,common.json 为公共配置,其余文件按职业名称命名。
  • keymap/*.json:职业按键映射,运行时按职业 ID 选择。
  • Assets/*.ico|*.png|*.svg:程序图标和品牌资源,构建时会复制到输出目录。
  • cache/window-state.jsonUI 缓存,保存置顶浮动条位置、设置窗口位置/大小和上次触发键。
  • tmp/:手动扫描保存的未命名图标,文件名为 dHash重复哈希会跳过。
  • auras/:手动命名后保存的光环模板图标,按职业 / 专精分类,例如 auras/7/2
  • AurasHash.json:光环名称索引,结构为中文名称映射到多个 dHash用于把模板 PNG 和识别名称关联起来。

config 结构

config 目录描述了如何把扫描到的像素数据翻译成状态字段。每个字段是一个对象:

  • step:在顶部行数据中的列索引;特殊值 "bar" 表示从左侧标记行数据读取,并配合 bar 字段指定段索引。
  • type:字段类型,支持 intboolstring

common.json 包含 锚点职业专精 等基础字段和一个 state 公共状态块;其余职业文件如 战士.json圣骑士.json 对应职业 ID每个职业文件下

  • keymap:该职业使用的 keymap 文件名。
  • 以专精 ID 为键(如 "1""2""3")的对象,包含该专精特有的字段、spells 技能块和可选的 group 队伍块。

运行时 ConfigService 会把 锚点/职业/专精/state 与当前 职业/专精 对应的配置合并,再由 StateBuilder 构建出 GameStategroup 块用 start(起始列)和 num(每个成员占用的列数)描述队伍成员数据的排布。

光环识别

光环识别用于补充 Fuyutsui 状态条以外的图标信息。插件在游戏内绘制定位点Shigure 根据定位点截取光环图标区域,再用 dHash 做候选筛选,并用模板匹配做二次确认。

  • 启用识别:默认开启,每 500ms 扫描一次,并把已命名的识别结果写入运行状态、状态页和模块条件可用字段;实时扫描只识别图标,不保存临时图标。
  • 手动扫描:立即扫描一次,适合调试定位点和模板,并把裁剪出的图标保存到 tmp/职业ID/专精ID
  • 刷新模板:重新读取 aurasAurasHash.json
  • 匹配距离:控制 dHash 允许的最大距离。数值越小越严格,误识别更少但可能漏识别;数值越大越宽松,能匹配更多相似图标但误识别风险更高。
  • 手动扫描识别到但未命名的图标会保存到 tmp,方便之后在“已有图标”中查看、排序和改名。
  • 在界面中保存名称后,图标会作为模板保存到 auras/职业ID/专精ID,并把中文名称与哈希写入 AurasHash.json

识别结果中的“距离”是当前图标 dHash 与模板 dHash 的汉明距离,越小越相似;“模板”表示命中的模板文件。模板数量变多会增加匹配耗时,但 dHash 会先过滤候选,正常按职业 / 专精分类后影响较小。

模块系统

模块用于把“识别到的角色环境”和“要执行的判断逻辑”拆成可编辑 JSON。运行时每轮识别到 职业专精队伍类型英雄天赋 后,会在 module 文件夹中寻找匹配模块。

匹配字段:

  • ClassId:职业 ID对应状态字段 职业
  • SpecId:专精 ID对应状态字段 专精
  • PartyType:队伍类型,对应状态字段 队伍类型。模块页使用下拉菜单:0 表示单人,1-40 表示团队,46 表示队伍。
  • HeroTalent:英雄天赋,对应状态字段 英雄天赋

字段留空(界面上选择 任意 (*))表示任意值。多个模块同时匹配时,程序会优先使用匹配字段更多的模块(Specificity 越大优先级越高),相同时按名称排序。 旧模块中 PartyType 如果保存为数字仍可读取;保存团队模块时会归一化写入 "1-40"

模块以 模块名.json 的形式平铺保存在 module 文件夹(文件名取自模块名称,因此模块名称不能重复)。加载时会递归扫描 module 下的所有子目录,旧版本保存在嵌套子文件夹中的模块文件仍可正常读取。

模块文件示例:

{
  "Id": "戒律-20260612100954681",
  "Name": "戒律",
  "Enabled": true,
  "Match": {
    "ClassId": 5,
    "SpecId": 1,
    "PartyType": "46",
    "HeroTalent": 1
  },
  "Rules": [
    {
      "Enabled": true,
      "Condition": "一键辅助 == 10",
      "Unit": 0,
      "Spell": "一键辅助",
      "Hotkey": "",
      "Step": ""
    }
  ]
}

Id 由界面在新建时自动生成(名称-时间戳),用于唯一标识模块。

规则按顺序判断,第一条命中的规则会执行。Spell 会通过当前职业 keymap 查找按键;如果填写了 Hotkey,则直接发送该按键(优先于 Spell)。Unit 表示技能对应的单位(默认为 0,即自身/当前单位)。

模块页规则表中“技能”和“目标”列为下拉菜单,选项取自当前选中职业的 keymap技能按名称去重keymap 中同名技能的多个 unit 条目只显示一次)。“目标”下拉跟随该行所选技能联动——只列出该技能在 keymap 中实际配置过的 unit(例如治疗技能可能有 1-30,而形态/自身技能往往只有 0),切换技能后非法的旧目标会被清空。职业选“任意 (*)”时回退读取 keymap/keymap.json。旧模块中不在 keymap 里的技能,或自定义技能下的目标值,会保留为额外下拉选项,不会丢失。

判断条件支持:

  • 状态字段:生命值 < 50战斗时间 > 0
  • 技能字段:spells.圣疗术 == 0
  • 队伍字段:group.1.生命值 < 60
  • 识别光环字段:ra.风暴打击 == 0ra.升腾 > 0。字段值为识别到的剩余时间 B;如果没识别到这个光环,值按 0 处理,因此 ra.光环名称 == 0 可用于判断光环不存在。
  • 组合条件:生命值 < 50 && spells.圣疗术 == 0目标类型 == 1 || 首领战 > 0
  • 布尔简写:直接写字段名表示“为真”,前面加 ! 表示“为假”,例如 战斗!移动
  • 条件留空表示始终命中。

字符串字面量可用单引号或双引号包裹;true/yes/是false/no/否null/nil/空 会被识别为对应的布尔值或空值。

可视化条件编辑器

模块页规则表的“条件”列为只读,单击单元格会弹出条件编辑窗口(在新行占位符上点击并保存后会自动追加一条规则)。窗口中每行是一个比较项:

  • 连接:第二行起可选 &&)或 ||),决定与上一行的组合方式。
  • 字段:下拉菜单,内容来自 config 目录并按模块当前选中的职业/专精过滤;技能字段以 技能: 名称 显示(保存为 spells.名称),识别光环字段可选择“光环识别”中已经获取的光环或直接输入名称(保存为 ra.名称)。原条件中不在目录里的字段(如 group.1.生命值 或手写字段)会保留为“自定义”项,不会丢失;选择“识别光环”时不会额外显示“自定义”。
  • 判断:数字字段提供 ==!=>>=<<=;布尔和字符串字段只提供 ==!=
  • 值:按字段类型自适应——数字字段用数字输入框,布尔字段用 是/否 下拉,字符串和自定义字段用文本框。
  • 每行末尾有删除按钮,底部有“添加条件”按钮和生成表达式的实时预览。

注意:表达式中 && 的优先级高于 ||(先算“且”再算“或”),编辑器按此语义把行序列分组,不支持括号嵌套。布尔简写(如 战斗!移动)在编辑器中会归一化为显式比较(战斗时间 > 0移动 == false),含义不变。关系比较(>< 等)遇到缺失或非数字的值(如未解析的动态单位字段)时视为“不命中”,不会报错中断。

动态单位与数量字段

模块页规则表上方有“动态单位 / 数量字段”面板。这些是按 group 队伍状态每帧实时解析的命名对象,逻辑移植自旧 Python 项目 utils.py,统一只统计 职责 != 0 的单位、生命值 0 视为死亡跳过、阈值表示只考虑 0 < 生命值 < 阈值

  • 动态单位(可作目标,也可在条件引用):解析为一个队伍槽位(1~30)。选择器类型包括——生命值最低按职责取首/末按职责且不带某光环带某光环(持续最久)带某驱散类型。选择 生命值最低 后,可在新的“光环筛选”下拉里继续选择 不筛选光环带任一光环不带某光环带某光环某光环值等于。参数(血量阈值、职责、光环、光环值、驱散类型等)按所选类型自适应显示,光环候选来自当前职业/专精的 group 字段,并排除 生命值职责驱散 这类基础字段。编辑弹窗在第二行显示“名称”,选择 生命值最低 时还会显示“值名称”:填了之后,该单位解析槽位的“生命值”会暴露成一个同名数值条件字段——如取名 最低血量 后条件可直接写 最低血量 < 50(等价于 单位名.生命值 < 50);单位未解析时该字段视为缺失(关系比较不命中)。
  • 数量字段(仅条件可用):解析为一个整数。类型包括 低于阈值的人数不带某光环且低血的人数拥有某光环的人数

定义后:

  • 在规则表“目标”列的下拉里会出现动态单位名,选它即表示“对运行时解析出的那个槽位施法”。运行时若该选择器没选中任何单位(如没人掉血),该规则会被跳过,继续判断下一条。
  • 在“条件”里可引用:裸 单位名(解析到槽位即为真,可用于存在性判断)、单位的“值名称”(数值,等于该单位的生命值)、以及数量名(如 低血量人数 >= 3)。这些会出现在可视化条件编辑器的字段下拉中;单位名.字段(如 最低血量单位.生命值 < 50)仍可手写,但不会展开进下拉列表。

模块 JSON 中以 UnitsCounts 数组保存(单位的值名称存为 HealthName,未填则省略),规则用 UnitName 字段引用动态单位(与原有数字 Unit 互斥)。旧模块没有这些键也能正常加载。名称与值名称不能为纯数字、不能含 .$,且不能与现有状态/队伍字段或其它单位/数量名重复。

默认逻辑

如果没有任何匹配的模块,程序会回退到 LogicRegistry.cs 中按职业 ID 注册的 C# 逻辑;若该职业也没有注册逻辑,则使用 DefaultClassLogic:当状态字段 一键辅助 == 10 且 keymap 中存在 一键辅助 时发送对应按键否则提示“C# 职业逻辑尚未迁移”。

你可以在 module 文件夹中放置一个匹配字段全部留空的模块作为通配模块,让它在任何职业下都能命中,从而替代上述默认逻辑。

迁移职业逻辑

如果逻辑可以用简单条件表达式描述,优先在 UI 的 模块 页维护;如果需要复杂算法,再迁移为 C# 职业逻辑。

新增 C# 职业逻辑时,建议新建一个实现 IClassLogic 的类:

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

然后在 LogicRegistry 中按职业 ID 注册:

_logicByClass[5] = new PriestLogic();

逻辑内可以通过 GameState.GetInt(...)GameState.GetBool(...)state.Spellsstate.Group 读取状态,并返回 LogicDecision

  • Hotkey:需要发送的按键;为空则不发送。
  • Step:当前逻辑步骤,会显示到 UI 和日志中。
  • UnitInfo:诊断信息,会显示在 逻辑 页。
  • ModuleName命中的模块名C# 逻辑通常留空,由模块逻辑填写)。
Description
魔兽世界外挂
Readme MIT 152 MiB
Languages
C# 67.7%
Lua 32.3%