news 2026/10/14 23:00:59

GIS(genshin-impact-script)按键录制与重放系统:replay 文件格式与 @input/@paste/@run/@sleep 标记完全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
GIS(genshin-impact-script)按键录制与重放系统:replay 文件格式与 @input/@paste/@run/@sleep 标记完全解析
  • 桌面应用
  • GUI 自动化
  • 计算机视觉

【免费下载链接】genshin-impact-script

原神脚本,包含自动钓鱼、自动拾取、自动跳过对话等多项实用功能。A Genshin Impact script includes many useful features such as automatic fishing, automatic item pickup, automatic dialogue skipping, etc.

项目地址:https://gitcode.com/gh_mirrors/ge/genshin-impact-script
点击查看免费下载

在 genshin-impact-script(下文简称 GIS)中,按键录制与重放是一项“可编程”的自动化能力:你只需像正常操作一样点击几下,脚本就能把动作原样保存为纯文本文件,之后再通过数字小键盘一键回放,甚至通过特殊标记实现打字、剪贴板粘贴、延时和跨录像跳转。本篇围绕官方文档 录像(recording) 展开,完整覆盖快捷键用法、replay 文件格式与全部@标记语义,并结合 source/recorder.coffee 与 source/replayer.coffee 的源码实现,解释延迟如何计算、鼠标位置以百分比落盘又如何被换算回屏幕坐标,帮助读者读懂录像文件、手写字幕式脚本,并排查录制/回放时的常见问题。

快速开始:录制、保存与回放的完整流程

GIS 为录制与回放提供了两组内建快捷键(完整键位见 doc/keymap.md):

| 按键 | 功能 | | - | - | |Ctrl + Numpad Dot| 开始/结束录像(Numpad Dot 即小键盘上的.键) | |Ctrl + Numpad 0~9| 回放对应的录像文件replay/0~9.txt|

操作流程非常简单:

  1. 按下Ctrl + Numpad Dot,进入录制状态,此时屏幕会弹出 “开始录制”(Start recording)提示;
  2. 随意按下若干其他按键(含鼠标按键);
  3. 再次按下Ctrl + Numpad Dot结束录制,脚本会把刚才的动作写入replay/0.txt,并提示 “结束录制”(End recording);
  4. 按下Ctrl + Numpad 0,即可重复播放这份录像。

replay/0~9.txt是十个内建的快捷入口,分别绑定到Ctrl + Numpad 0~9。需要特别说明的是:GIS 只会把录制结果写入replay/0.txt,如果你希望录制的动作绑定到其他小键盘数字上,只需把replay/0.txt的内容保存/复制为replay/N.txt即可。

replay 文件格式:一行一个动作

一份录制文件的内容通常长这样:

1000 esc:down 500 esc:up 1000 l-button:down 2%,94% 50 l-button:up 2%,94% 1000 l-button:down 60%,70% 50 l-button:up 60%,70% 15000 l-button:down 95%,91% 50 l-button:up 95%,91% 1000 l-button:down 58%,52% 50 l-button:up 58%,52% 1000 l-button:down 35%,58% 50 l-button:up 35%,58%

每一行代表一个动作,由空格分隔,包含三部分:

| 字段 | 含义 | 示例 | | - | - | - | | 时间 | 与上一个动作之间的等待时间,单位为毫秒 |1000| | 按键 |按键名:down或按键名:up,表示按下/松开 |esc:down、l-button:up| | 位置(可选) |x%,y%,鼠标按键动作时记录的鼠标位置,以窗口宽高的百分比表示 |60%,70%|

其中只有鼠标按键(l-button左键、m-button中键、r-button右键等)会附带位置信息,这是 RecorderG.record 中的行为:当记录的按键名包含l-button时,调用$.getPosition()取当前鼠标坐标,再除以窗口宽高换算为百分比(Math.round(x * 100 / Window2.bounds.width))。之所以存百分比而不是像素坐标,是为了让录像在不同分辨率/窗口大小下依然可用——回放时再由 PointG.w 和 PointG.h 按当时的Window2.bounds反算回像素坐标。

从源码还可以确认两个细节:

  • 动作时间是怎么算出来的:每次记录一个按键事件时,用当前时间戳减去上一动作的时间戳得到delay(见 RecorderG.record),因此录像保存的是“间隔”而非绝对时间轴;
  • 第一行固定 1000ms:RecorderG.save 在生成文本时会把第一行的delay强制改写为1e3(1000 毫秒)。从源码结构看,这样做的目的是给回放留出一秒“热身”缓冲,避免脚本启动瞬间动作就开始,来不及把焦点切回游戏。

录制器实现:哪些键会被记录、如何与回放互斥

录制器由 RecorderG 实现,它在init阶段(source/recorder.coffee#L33-L42)做了三件事:

  1. Native 'FileCreateDir, replay':确保replay目录存在;
  2. 监听Client的idle事件并触发stop——当脚本失去对游戏窗口的焦点时自动结束录制,避免在游戏外误录;
  3. 注册Ctrl + Numpad Dot作为开始/结束录制的切换键:未激活则start(),已激活则stop()。

开始录制时(RecorderG.start):

  • 若此时回放器Replayer.isActive为真,会发出提示音(Sound.beep 2)并直接返回,即录制与回放互斥,不能同时进行;
  • 遍历listKey白名单,为每个按键分别注册三种事件:record(裸键)、alt + key、ctrl + key。listKey覆盖的功能键、数字键、字母键、方向键与鼠标按键清单见 source/recorder.coffee#L15-L24,不在白名单内的按键不会被记录;
  • 事件走的是 KeyBinding 的startEvent/endEvent机制:按下时发出record:start、松开时发出record:end,录制器把它们分别记为key:down与key:up(source/recorder.coffee#L37-L38)。

停止录制时(RecorderG.stop)会注销全部按键事件、调用save()落盘并提示 “结束录制”。save()中还有一个小细节:如果录制列表为空($.length @list为 0),直接返回,不会覆盖已存在的replay/0.txt(source/recorder.coffee#L75)。

四个特殊标记:@input、@paste、@run、@sleep

除了“时间 按键 位置”这种普通行,录像还支持以@开头的特殊标记行。更复杂的录像内容可能是这样:

# start chat 1000 enter:down 50 enter:up 50 enter:down 50 enter:up # input @input hello 50 space:down 50 space:up @input world # send 50 enter:down 50 enter:up # exit 50 esc:down 50 esc:up

把上面这段保存为replay/9.txt,在游戏中按下Ctrl + Numpad 9,就能看到游戏聊天框输入并发送了hello world。

特殊标记目前共有四个(实现见 ReplayerG.asMark):

| 标记 | 语义 | 源码实现 | | - | - | - | |@input <text>| 直接发送一段文本,逐键打入 |Native 'Send, % value'(AHK 的Send,%表示按字面量发送,不做快捷键转义) | |@paste <text>| 把文本写入剪贴板,50ms 后模拟Ctrl + V粘贴,再 50ms 后清空剪贴板 |ClipBoard = value+ 两个 50ms 的Timer.add回调 | |@run <n>(别名@play <n>) | 跳转到另一份录像replay/<n>.txt继续执行,实现录像间组合/跳转 |@start value, callback| |@sleep <ms>| 延时指定毫秒后继续 |Timer.add n, callback|

注意两点:

  • 以#开头的行是注释,不会被解析和执行,且目前不支持行内注释;
  • @play是@run的同义别名,虽然 doc/recording.md 只列出了@run,但源码中 source/replayer.coffee#L39 同时接受@run和@play。

用 @run 实现录像组合

只需一个文件内容:

@run 9

保存为replay/0.txt,按下Ctrl + Numpad 0,就会执行与replay/9.txt完全一致的动作。这正是@run的价值:它可以把多份录像串起来,形成更复杂的“宏”脚本。

回放器实现:逐行动画与按键安全机制

回放由 ReplayerG 承担。ReplayerG.init 通过Client.useActive把十组Ctrl + Numpad 0~9快捷键的注册与注销和“脚本是否激活”绑定:游戏窗口激活时注册快捷键,同时用$.preventDefaultKey "ctrl + numpad-#{n}", true拦截这些组合,防止它们穿透到游戏;窗口失去焦点(idle)时自动stop()并解绑。

启动回放时(ReplayerG.start):

  1. 先stop()清除上一次未完成的回放;
  2. 若正在录制(Recorder.isActive),提示音后直接返回——与录制器的互斥逻辑呼应;
  3. 读取replay/<key>.txt,逐行解析:去首尾空白、跳过空行、跳过#注释行、把行内连续空白压缩为单个空格后按空格拆分为[时间, 按键, 位置]三元组;
  4. 调用next(list, 0)开始逐行执行,并提示 “开始回放”(Start replaying)。

逐行执行的核心是 ReplayerG.next:

  • 遇到@行:先用一个 50ms 的定时器再交给asMark处理,处理完回调next继续下一行——这个 50ms 的小停顿保证标记(如输入文本)有足够时间生效;
  • 普通行:delay至少取max(1, 数值),通过Timer.add @token, delay, ...等待后执行动作;@token为'replayer/next',是一个带 id 的定时器句柄,新动作会覆盖旧等待,而stop()时 Timer.remove 会清掉整个队列,实现“随时打断回放”;
  • 动作执行细节:
    • 若按键名包含l-button且带位置,先$.move Point.create(...),把鼠标移到换算后的屏幕坐标再按键,即文档中“位置信息(百分比)”的实际用途;
    • unless $.isKeyPreventedDefault key then $.press key:如果该按键已被脚本“劫持”(如Alt + F4、Ctrl + F5),就不向系统真实发送,避免误触发脚本自身功能;
    • if $.isKeyBound key then $.trigger key:如果该按键绑定了脚本内部功能,同时触发内部事件,让录像也能驱动脚本自身的逻辑(从源码结构看,这使得录像可以复现“长按 F 跳过对话”这类由脚本功能响应的操作)。

回放结束(动作队列耗尽或手动使窗口失焦)时会提示 “结束回放”(End replaying),文案见 data/dictionary/misc.yaml。

上手建议与适用前提

  • 录制内容想绑到其他数字:录制只会写replay/0.txt,需要手动另存为replay/N.txt才能用Ctrl + Numpad N调用;
  • 想要更精细的时间控制:所有普通行的时间都是毫秒整数,可以直接手改文件(如把50改成300)再回放;
  • 多文本输入优先用@input/@paste:相比逐键录制down/up,两者更稳定,其中@paste会先写入剪贴板再模拟粘贴,适合较长的文本;
  • 适用前提:回放快捷键仅在脚本激活(游戏窗口获得焦点)时生效,窗口失焦会中断回放并解绑快捷键;录制与回放互斥,正在进行回放时按下Ctrl + Numpad Dot只会听到提示音。

相关文件索引

| 文件 | 说明 | | - | - | | doc/recording.md | 官方“录像”文档(中文) | | doc/en/recording.md | 官方“录像”文档(英文) | | doc/keymap.md | 完整按键表,含录制/回放快捷键 | | source/recorder.coffee | 录制器 RecorderG 实现 | | source/replayer.coffee | 回放器 ReplayerG 与 @ 标记实现 | | source/key-binding.coffee | 按键事件注册/注销基础设施 | | source/timer.coffee | 带 id 的定时器,支撑逐行动画与打断 | | source/point.coffee | 百分比坐标与像素坐标的换算 |

  • 桌面应用
  • GUI 自动化
  • 计算机视觉

【免费下载链接】genshin-impact-script

原神脚本,包含自动钓鱼、自动拾取、自动跳过对话等多项实用功能。A Genshin Impact script includes many useful features such as automatic fishing, automatic item pickup, automatic dialogue skipping, etc.

项目地址:https://gitcode.com/gh_mirrors/ge/genshin-impact-script
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 23:00:36

CloudCompare十字标记清除指南:三种类型与快捷键解法

最近在整理一批点云数据时&#xff0c;被一个细节折腾了一下&#xff1a;CloudCompare 的 3D 视口里出现了一个十字准星&#xff0c;无论我怎么旋转视角它都悬在那里。刚开始我以为是自己误开了某个工具&#xff0c;后来才发现这和鼠标状态、视图显示都有关系。这篇文章我就把排…

作者头像 李华
网站建设 2026/10/14 23:00:24

2026论文降重工具实测盘点:从查重原理到AI改写正确用法

“2026权威盘点”这标题起得有点大&#xff0c;我其实不是权威&#xff0c;就是个被论文折磨过、也帮不少人改过论文的过来人。但我可以保证&#xff0c;下面写的每一句&#xff0c;都来自这几年跟查重系统、降重工具实打实搏斗出来的经验。2026年了&#xff0c;查重系统的算法…

作者头像 李华
网站建设 2026/10/14 23:00:15

QtCreator调用CCCoreLib常见链接错误解决方案

简介&#xff1a;本资源是面向三维点云开发者的CCCoreLib核心算法库完整编译成果包&#xff0c;专为在Qt Creator环境下快速集成CloudCompare底层能力而设计&#xff0c;适用于具备C基础与Qt开发经验的中高级开发者及科研人员。压缩包共102个文件&#xff0c;含63个头文件&…

作者头像 李华
网站建设 2026/10/14 22:59:22

森林冰火人单人版Java实现:Swing游戏循环与碰撞检测实战

简介&#xff1a;这是一份面向Java初学者与游戏开发爱好者的森林冰火人单人版小游戏源码&#xff0c;适合用来练习Swing/JavaFX界面搭建、键盘事件监听与游戏循环设计。压缩包共78个文件&#xff0c;以48张jpg与14张gif图片资源为主&#xff0c;用于角色、场景与动画素材&#…

作者头像 李华
网站建设 2026/10/14 22:58:55

加分二叉树本质是区间DP:从中序序列切分看最优根决策

1. 这道题不是考树&#xff0c;是考你怎么“切蛋糕”——从加法结构看区间DP的本质你打开这道题&#xff0c;第一眼看到“二叉树”&#xff0c;心里可能咯噔一下&#xff1a;中序遍历&#xff1f;左右子树递归&#xff1f;节点合并规则&#xff1f;别急&#xff0c;先放下树的表…

作者头像 李华
网站建设 2026/10/14 22:58:32

Flink动态配置热更新:基于BroadcastState的毫秒级规则变更方案

1. 项目概述&#xff1a;为什么Flink任务配置不能“改完就生效”&#xff1f;在某次数据平台升级中&#xff0c;我负责支撑一个实时风控场景的Flink作业集群——它要对每秒数万笔交易做毫秒级异常识别&#xff0c;规则引擎依赖外部配置中心下发的阈值、黑白名单和模型版本号。上…

作者头像 李华