Files
Shigure/README.md

295 lines
22 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Shigure
Shigure 是荒坂公司Arasaka Corporation开发的冲锋枪。有时人们只想把子弹全打出去在硝烟过后品味眼前的一片狼藉。
### 仓库已内置冬月电子Fuyutsuki Electronics的 Fuyutsui 插件源码,无需另行下载或手动安装。
# 免责声明 (Disclaimer)
1. **合规责任**
Shigure 仅供技术研究、学习交流和个人实验使用。下载、安装、复制、修改、分发或使用本软件前,用户应自行确认相关行为符合所在地法律法规,以及目标软件、游戏平台或服务提供商的用户协议、服务条款和社区规则。
2. **账号与处罚风险**
本软件可能涉及窗口状态读取、按键发送或自动化辅助流程。此类行为可能被游戏运营商、反作弊系统或相关服务提供商认定为违规,并导致账号限制、角色封禁、数据丢失、收益回收或其他处罚。用户应充分了解并自行承担全部风险,开发者不对由此产生的任何后果负责。
3. **无担保声明**
本项目基于 MIT License 开源发布,详见 [LICENSE](LICENSE)。软件按“原样”AS IS提供不对稳定性、准确性、完整性、安全性、兼容性、持续可用性或特定用途适用性作出任何明示或暗示保证。因使用或无法使用本软件导致的直接、间接、偶然、特殊或后续损失均由用户自行承担。
4. **商业使用与衍生版本**
MIT License 允许在遵守许可证条件的前提下复制、修改、分发和商业使用本软件。任何第三方对本软件或其衍生版本的运营、销售、推广、技术支持或其他商业利用,均由该第三方独立负责。开发者不代表、不授权或保证任何第三方产品、服务或运营活动,也不对第三方的违法行为、违反平台规则的行为或由此产生的后果负责。
但本声明不限制适用法律所规定的责任,也不构成对任何具体行为合法性的保证。
5. **使用即表示接受**
使用者应在使用前阅读并理解本免责声明及 MIT License。开始使用本软件表示使用者已获得必要授权并将自行承担使用本软件产生的风险但仅通过使用行为是否构成法律上的合同接受应以适用法律及实际使用场景为准。
## 项目简介
Shigure 是一个 Windows WinForms 桌面程序。它从目标窗口读取 Fuyutsui 绘制的像素状态,按职业 keymap 和模块规则选择按键,并在界面中展示状态、光环、技能、队伍、动态单位、逻辑结果和运行日志。
程序采用单实例运行再次启动时会提示“Shigure 已经在运行”,随后退出新实例。
当前版本:`1.2.1.20`
## 主要功能
- 扫描 510 格顶部状态行、左侧计数条和队伍治疗吸收数据。
- 按职业、专精、队伍类型和英雄天赋自动匹配模块,也可手动锁定符合条件的模块。
- 使用可视化编辑器维护规则、主/子条件、动态单位、数量字段、条件动态数值和公式动态数值。
- 以内置 `Fuyutsui/` 为权威源编辑职业配置与宏,并按 SHA-256 将插件部署到已运行游戏的 `Interface\AddOns\Fuyutsui`
- 支持 `switch``click``hold` 三种触发模式,以及除 `ALT` 外的键盘按键、`XBUTTON1``XBUTTON2`
## 界面
- 置顶浮动条:显示程序名、当前职业图标颜色和逻辑状态,提供 `开启/关闭``设置``✕` 按钮。窗口可拖动和缩放,显示后自动启动运行循环。
- `通用`:设置触发键和发送模式;从项目 Fuyutsui 更新配置并同步游戏插件;按实时环境选择模块,或按职业、专精、英雄天赋和队伍类型指定默认模块;从 GitHub 按需下载或更新技能/物品图标数据包。
- `配置`:直接编辑项目 `Fuyutsui/class/*.lua` 中的 `ClassBlocks`,包括状态、光环、冷却(技能冷却与当前专精物品冷却)和队伍字段;技能列表页可编辑 `Fuyutsui.spellsList` 中索引 1100 的法术 ID、索引和名称也可从技能数据库添加物品列表页编辑职业级 `Fuyutsui.itemsList``[itemId] = { index, name }`,允许同名、禁止同 ID并可从全量物品数据库添加。旧版稀疏索引格式只读需先迁移到 `states/auras/spells/items/group` 格式。
- `宏`:编辑项目 `Fuyutsui/core/classmacros.lua` 中各职业的动态宏、静态宏和特殊宏。动态宏每项占用 30 个团队点名槽位;特殊宏的技能名必须手工填写,不从宏正文解析,生成映射时固定为无目标、无宏条件。
- `模块`:新建、编辑、删除本地模块,维护作者、推荐天赋、匹配条件、动态字段和有序规则。规则支持拖拽、上移、下移、复制与插入。
- `状态`:分栏显示基础状态、`auras``spells` 和模块计算出的动态单位/数值。
- `队伍`:显示 `group` 中当前队伍成员及扫描字段摘要。
- `逻辑`:显示命中模块、目标、按键和调试值。
- `日志`:记录启动、停止、职业识别、模块匹配、逻辑状态、施放步骤、配置同步和异常。
- `关于`:显示产品、公司、版本、模块目录、配置目录、免责声明和 MIT 许可证。
触发键、发送模式、模块选择、默认模块、模块保存以及配置同步都会按需重启运行循环。窗口位置、大小、主界面横纵布局(两个方向分别保存窗口位置)、模块选择、按筛选条件保存的默认模块和表格列宽等 UI 状态保存在我的文档目录 `{MyDocuments}/Shigure/cache/window-state.json`;模块保存在 `{MyDocuments}/Shigure/module``cache/` 与模块数据都是本地数据,默认不提交到 Git。
## 环境要求
- Windows
- .NET 10 SDK
- 使用运行和插件部署功能时需要打开目标游戏窗口Fuyutsui 无需手动安装Shigure 会在启动或“更新配置”时部署项目内版本
## 运行
在仓库根目录执行:
```powershell
dotnet run --project .\Shigure.csproj
```
可选启动参数:
```powershell
dotnet run --project .\Shigure.csproj -- --toggle XBUTTON2 --mode switch --logic-ms 100 --render-ms 100
```
- `wow_process.txt`:每行一个目标进程名(可带或不带 `.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 所在目录运行,并从该目录读取 `Fuyutsui/``config/``keymap/``wow_process.txt`;模块从我的文档目录 `{MyDocuments}/Shigure/module` 读取UI 缓存写入 `{MyDocuments}/Shigure/cache`
## 构建
```powershell
dotnet build .\Shigure.csproj
```
应用图标为 `Assets\arasaka-icon.ico`。项目会把 `Fuyutsui/**``config/*.json``keymap/*.json``wow_process.txt` 复制到输出/发布目录;应用、职业、专精和少量程序专用图标作为嵌入资源打包。完整技能/物品图标库不随发布版分发,用户可在“设置 → 通用 → 下载数据包”中从 GitHub 最新正式 Release 下载到 `data\SpellIcons.shgpack`。缺少数据包时技能图标与添加技能的 spellId 联想保持关闭,但仍可手工编辑技能。仅技能旧包仍可加载技能;物品搜索库关闭,手工编辑物品保持可用。
## 项目结构
```text
Shigure.csproj 项目文件与构建资源配置
App\ 程序入口、启动参数和依赖组装
UI\ WinForms 主界面、配置/宏/模块编辑器和主题
Runtime\ 像素扫描、状态构建、运行循环和快照
Modules\ 模块模型、匹配、条件、公式和动态字段
Input\ keymap 读取、按键发送和 Win32 API
Infrastructure\ 配置服务、Lua 读写、Fuyutsui 转换和路径定位
Assets\ 应用图标、品牌资源、职业图和专精图
Fuyutsui\ 权威插件源码、配置/宏编辑源及游戏部署源
config\ 由 Fuyutsui 职业配置生成的扫描映射
keymap\ 由 Fuyutsui 职业宏生成的按键映射
module\ 模块示例模板(运行时模块保存在我的文档目录 `{MyDocuments}/Shigure/module`
SpellIconPackage\ 本地技能/物品图标数据包清单、构建与修复工具Git 忽略)
Tools\ 辅助脚本
```
`SpellIconPackage/` 中保存数据包源清单、本地构建工具和生成的
`SpellIcons.shgpack`;整个目录由 `.gitignore` 排除,不提交到仓库。完整包在 v1 技能索引后追加物品扩展段;仅技能旧包可被新版读取,此时只禁用物品搜索库。
## Fuyutsui 配置同步
项目目录中的 `Fuyutsui/` 是唯一权威源。`通用` 页的“更新配置”会读取:
- `Fuyutsui\class\*.lua``config/*.json`
- `Fuyutsui\core\classmacros.lua``keymap/*.json`
如果 EXE 所在目录的 `config/``keymap/` 缺失或文件不完整,启动 Shigure 时会先从上述 Fuyutsui 源文件自动补齐;新建 `config/` 时也会生成运行时必需的 `common.json`。转换完成后会刷新模块编辑器的字段/keymap 目录并重启运行循环,同时递归同步整个插件到当前游戏的 `Interface\AddOns\Fuyutsui`。启动 Shigure 时也会执行同一全量同步缺失文件会创建SHA-256 不同的文件会覆盖,相同文件会跳过,游戏目录中的额外文件会保留。
`配置` 页和 `宏` 页保存时先写入项目内 Lua、重新生成 config/keymap再只把当前修改的 Lua 文件部署到游戏目录。找不到游戏或目标文件不可写时,本地保存不会回滚;界面和日志会提示游戏同步未完成,可在游戏启动后再次点击“更新配置”。
### 插入法术与插入物品命令
游戏内可使用 `/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``510`;特殊值 `"bar"` 表示读取左侧计数条,并由 `bar` 指定段索引。
- `type`:字段类型,支持 `int``bool``string`
顶部状态行由 Fuyutsui 绘制为 510 个色块。Shigure 按两段颜色协议解码:`1``255` 使用 `(0, i / 255, b, 1)``256``510` 使用 `(1 / 255, (i - 255) / 255, b, 1)`,蓝色通道 `b` 是该 `step` 的原始值。左侧 `"bar"` 标记行使用独立计数条协议。
`common.json` 保存固定启动字段 `锚点``职业``专精`。其余文件按英文职业名命名,例如 `Warrior.json``Priest.json`,每个文件包含:
- `keymap`:该职业使用的 keymap 文件名。
- `一键法术`:状态中的本地技能索引到 spellId 的映射。
- `一键物品`:状态中的本地物品索引到 itemId 的映射。
- 以专精 ID 为键的对象,包含普通状态与物品字段,以及可选的 `auras``spells``group`
运行时先读取 `common.json` 确定职业和专精,再合并对应专精配置。`group.start` 是队伍数据起始列,`group.num` 是每名成员占用的列数;组内字段的 `step` 是相对偏移。
### `keymap` 与单位编号
每条 keymap 记录包含 `unit``技能``热键` 和可选的 `宏条件`。模块和 keymap 共用以下单位编号:
- `0`:无目标。
- `1``30`:队伍/团队槽位。
- `31`:玩家。
- `32`:当前目标。
- `33`:焦点。
- `34`:地面。
- `35`:鼠标指向。
当前映射版本为 `UnitMappingVersion = 3`。版本 1 模块会迁移旧的 `31/34` 含义;版本 2 模块中的 `36/37` 会迁移为 unit 0并分别补成 `channeling` / `nochanneling` 宏条件。
## 模块系统
模块以 `模块名.json` 保存在我的文档目录 `{MyDocuments}/Shigure/module`。名称不能重复;加载时会递归扫描子目录,以兼容旧版布局。模块页保存时会写入当前 Shigure 版本。模块的 `Version` 必须与当前软件版本完整一致才会参与依赖导入、模块选择和运行;版本不一致或为空的模块仍在编辑器列表中显示为红色,可在检查并显式保存后升级到当前版本。职业和专精均已指定时,模块还会携带该专精的 `ClassBlocks`、职业 `spellsList`,以及该职业的通用/专精动态宏、静态宏和特殊宏。
启动和“刷新模块”会把模块携带而本地缺少的配置与宏追加到项目 `Fuyutsui/`。光环、法术和技能列表都以 `spellId` 判断同一条目,不再按名称回退:光环任一 ID 重合即合并 ID 集合,`maxApps` 仅补本地空值;法术的布尔属性采用 true 补齐 false最大充能和施法次数仅补本地空值双方都有不同值时保留本地并提示冲突。技能列表同一 spellId 保留本地索引和名称,缺失 spellId 按模块快照追加,允许多个 spellId 共用同一索引。队伍依赖快照只为模块文件兼容保留,读取时不比较、不导入,也不修改本地队伍配置。发生新增后会自动重建 `config/keymap`、同步游戏插件并按需重启运行。导入前会按每项动态宏 30 个槽位、静态/特殊宏各 1 个槽位检查该职业所有受影响专精;合并结果超过 350 个槽位时,整个模块不会进入模块列表或运行时,本地 Lua 也不会被修改。模块文件仍保留在模块目录,清理宏后可刷新重试。
模块匹配字段:
- `ClassId`:职业 ID。
- `SpecId`:专精 ID。
- `PartyType``0` 为单人、`1-40` 为团队、`46` 为队伍。
- `HeroTalent`:英雄天赋 ID。
任一字段留空(界面显示 `任意 (*)`)即为通配。多个模块同时匹配时,优先选择具体匹配字段更多的模块,相同则按名称排序。`RecommendedTalent` 仅用于说明,不参与匹配。
模块文件示例:
```json
{
"Id": "戒律-20260730120000000",
"Name": "戒律",
"Author": "模块作者",
"RecommendedTalent": "推荐天赋代码或说明",
"Version": "1.2.1.17",
"UnitMappingVersion": 3,
"Enabled": true,
"Match": {
"ClassId": 5,
"SpecId": 1,
"PartyType": "46",
"HeroTalent": 1
},
"Units": [],
"Counts": [],
"ValueAdjustments": [],
"Rules": [
{
"Enabled": true,
"Condition": "生命值 < 50 && spells.17.cooldown == 0",
"Unit": 31,
"Spell": "真言术:盾",
"Hotkey": "",
"Step": "自保"
}
]
}
```
规则按顺序判断,第一条命中的规则会执行。普通动作的 `Spell` 保存并使用“技能”列中的技能或宏名称,不用 spellId 判断;运行时按名称、目标单位和宏条件查找 keymap 热键。填写 `Hotkey` 时会直接发送该键。技能下拉还包含以下特殊动作:
- `暂停`:命中后不发送按键,并停止继续匹配本轮后续规则。
- `自动插入法术`:读取状态字段 `插入法术`,按职业配置映射到当前可用技能。
- `自动插入物品`:读取状态字段 `插入物品`,按职业 `itemsList` 映射到当前可用物品宏。
- `一键法术`:读取状态字段 `一键辅助`,按职业配置映射到技能。
### 条件
支持的常见表达式:
- 状态:`生命值 < 50``战斗时间 > 0`
- 玩家光环:`auras.player.114255.value > 0`;层数使用 `.apps`
- 目标/焦点光环:`auras.target.harmful.55078.value > 0``auras.focus.helpful.12345.value > 0`
- 技能:`spells.633.cooldown == 0`;充能冷却和层数分别使用 `.chargeCooldown``.count`
- 队伍:`group.1.生命值 < 60`
- 列表:`目标类型 in (1, 2)``职业 not in (4, 9)`
- 组合:`生命值 < 50 && spells.633.cooldown == 0``目标类型 == 1 || 首领战 > 0`
- 布尔简写:`移动` 表示为真,`!移动` 表示为假。
- 空条件:始终命中。
`一键辅助``插入法术``施法技能``上个技能` 是技能列表索引状态。可视化编辑器为这些字段提供“技能图标 / 技能名称 / spellId”下拉并且只允许 `==``!=`;模块条件保存 spellId运行时按当前职业的 `spellsList` 把 spellId 转换为本地索引后再比较,因此模块不依赖来源职业文件中的索引分配。找不到 spellId 时,该条件行和所属规则行显示为红色,条件按不命中处理。
`插入物品` 是物品列表索引状态。可视化编辑器提供“物品图标 / 物品名称 / itemId”下拉并且只允许 `==``!=`;模块条件保存 itemId运行时按当前职业的 `itemsList` 把 itemId 转换为本地索引后再比较。找不到 itemId 时同样显示为红色,条件按不命中处理。
生成的 `config/*.json` 和运行时状态使用“范围 + spellId + 数值类型”的结构化键;字段节点中的 `displayName``spellId``scope``metric``spellIds` 仅用于显示及别名解析。多 ID 光环优先使用单值 `spellId`,否则使用最小有效 ID 作为规范键,其余 ID 映射到同一运行时值。普通条件、子条件、动态数值、公式、动态单位和人数统计均持久化 spellId缺失引用会保留原 ID、显示红色并按不命中处理。
字符串可以使用单引号或双引号。`true/yes/是``false/no/否``null/nil/空` 会转换为对应字面量。`&&` 的优先级高于 `||`,主表达式不支持括号嵌套。
规则还可添加多个“子条件”:主条件与子条件组是“且”关系,子条件之间是“或”关系,即 `主条件 && (子条件 1 || 子条件 2)`。这用于表达主编辑器无法用括号表示的逻辑。
可视化条件编辑器会按当前职业/专精提供状态、光环、冷却(技能/物品)和动态单位字段,并支持:
- 数字比较 `==``!=``>``>=``<``<=`
- 文本/数字列表比较 `in``not in`
- `延迟 (ms)`:限制同一规则两次实际发送的最小间隔。
- `逻辑延迟 (ms)`:发送后暂停逻辑扫描指定时间;触发键检测和界面刷新仍继续。
缺失或非数字字段参与大小比较时视为不命中,不会中断运行。
### 动态单位、数量与动态数值
这些字段按 `group` 状态每帧重新计算。多数动态选择与数量统计会跳过 `职责 == 0` 的单位;具体生命值过滤取决于字段类别。
- 动态单位:可按最低生命值、最高治疗吸收、职责、光环、光环值或驱散类型选择 `1``30` 的队伍槽位。最低生命值使用“扫描生命值减去治疗吸收”的结果,允许结果为 0 或负数,并在所有 `生命值 < 阈值` 的候选中取最低值。动态单位可在规则目标中直接使用,也可用裸名称判断是否成功解析。
- 数量字段:统计低于生命值阈值、高于治疗吸收阈值或带/不带指定光环的单位数,只能用于条件。其中低生命数量仍只统计 `0 < 生命值 < 阈值` 的单位。
- 条件动态数值:条件成立时对已有状态、光环、技能或动态字段加减一个整数。
- 公式动态数值:使用字段和算术表达式生成命名数值,支持 `+ - * /`、括号、一元正负号和 `int``round``floor``ceil``min``max`
动态单位和数量阈值既可使用固定值,也可引用其它动态数值。规则引用未解析出的动态目标时会跳过该规则,继续判断下一条。
模块 JSON 使用 `Units``Counts``ValueAdjustments` 保存这些定义;规则使用 `UnitName` 引用动态单位。名称不能是纯数字,不能包含 `.``$`,也不能与已有状态字段或其它动态名称冲突。
## 默认逻辑与 C# 扩展
如果没有匹配模块,`LogicRegistry` 会尝试使用按职业注册的 `IClassLogic`。当前没有注册项时会进入 `DefaultClassLogic`:仅当 `一键辅助 == 10` 且 keymap 中存在 `一键辅助` 时发送按键否则显示“C# 职业逻辑尚未迁移”。
通常应优先在 `模块` 页维护逻辑。确实需要复杂算法时,可实现 `IClassLogic` 并在 `LogicRegistry` 中按职业 ID 注册:
```csharp
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`。也可以创建匹配字段全部留空的通配模块,覆盖默认逻辑。