d:\projects\sf6_260122\docs\如何控制1p和2p的动作\SF6_Input_Control_Technical_Documentation.md 我是这么理解的,请你看看对不对,我们实际上找的是某个数据结构,而这个数据结构里存储着很多歌数据,以前我用ce找到过看似是输入的内存地址,但是修改这个值人物并不会起作用,可能是因为我找到的并不是代表最后输入的值。而可能是缓冲区也说不定。 d:\projects\sf6_260122\docs\如何控制1p和2p的动作\SF6_Input_Control_Technical_Documentation.md#L63-80 这些可能就是具体的数据结构实例的值,我们的插件是hook里其中一个属性或者方法对吧?那么我是不是可以直接用ce或者用c++找到真正的关键数据内存地址,写入是否就可以成功了呢?这样是否就可以绕考reframework?
filePath: d:\projects\sf6_260122\docs\如何控制1p和2p的动作\SF6_Input_Control_Technical_Documentation.md
你的理解非常到位!你之前的直觉和现在的推断都是正确的。
核心结论:是的,你可以绕过 REFramework#
你之前用 CE 修改数值没反应,以及现在提到的 input_data 缓冲区,正好切中了问题的要害。
1. 为什么之前用 CE 修改 pl_input_now 没反应?#
当你用 CE 找到 pl_input_now 的内存地址并修改它时,通常会发生这种情况:
- 你的修改:你把
pl_input_now改成了0x08(前进)。 - 游戏逻辑(下一帧):游戏的主循环运行,读取硬件手柄/键盘输入(比如没有任何输入,
0)。 - 覆盖:游戏代码执行类似
pl_input_now = hardware_input的指令,把你刚才改的0x08瞬间覆盖回了0。 - 动作判定:游戏根据
pl_input_now(现在是0) 来判定动作 -> 角色不动。
这就是为什么简单的内存修改(Write Memory)通常无法控制动作游戏的角色,除非你能锁定它(Freeze),但锁定的频率如果不比游戏刷新率高,或者锁定的时机不对,依然会被游戏逻辑覆盖。
2. 为什么 input_data 是关键?#
我们在 GeminiInputCore.lua 里发现的 "Buffer Only" (仅缓冲区) 模式之所以稳定,是因为:
- 机制:
input_data是一个输入队列(Ring Buffer/数组)。游戏逻辑不是只看这一瞬间的输入,而是会从这个队列里“取”未来的输入帧来执行。 - 时间差:如果你往这个队列的“未来”位置写入数据,游戏在随后的几帧里读取该位置时,就会读到你的指令。这比和游戏争抢
pl_input_now的控制权要可靠得多。
3. 如何用 CE / C++ 实现(脱离 REFramework)#
如果你想完全脱离 REFramework,用 C++ 或 CE 实现控制,你需要做以下两件事之一:
方案 A:模拟缓冲区写入(推荐,类似我们的插件逻辑)
- 寻找基址 (Base Address):
- 你需要找到
TrainingManager或cPlayer的静态基址(Static Pointer Chain)。REFramework 帮我们自动完成了这部分(sdk.get_managed_singleton),脱离它你需要自己逆向找到这个指针链。 - 路径大概是:
World->Level->TrainingManager->PLDatas->Player->cPlayer。
- 你需要找到
- 定位
input_data数组:- 在
cPlayer结构体中找到input_data的偏移量 (Offset)。 - 这是一个数组结构。你需要找到数组内容的起始地址。
- 在
- 写入操作:
- 用 C++ 或 CE 脚本,不断向这个数组的当前索引(及之后几个索引)写入你的按键值。
方案 B:代码注入/劫持 (Code Injection)
- 寻找指令:
- 找到写入
pl_input_now的那行汇编指令(比如mov [rax+120], rbx)。
- 找到写入
- Hook / Inline Patch:
- CE 做法:使用 "Auto Assembler" 脚本,将这行指令替换为你的代码。
- 逻辑:
// 伪代码 cmp [rax+player_index], 0 // 判断是不是P1 jne original_code // 如果不是P1,执行原逻辑 mov [rax+120], my_value // 强行写入你的值 jmp exit original_code: mov [rax+120], rbx // 原游戏逻辑 exit: - 这种方法最彻底,相当于你在底层截断了手柄信号,直接接管了神经。
下一步建议#
既然你对这方面感兴趣,我们可以验证一下 方案 A 的可行性。
- 获取偏移量:我可以帮你分析一下
cPlayer下input_data大概的偏移量是多少(虽然 REFramework 封装了名字,但我们可以通过 Lua 打印出具体的 offset)。 - CE 测试:
- 启动游戏和 REFramework(仅用于辅助定位)。
- 用 Lua 脚本打印出
cPlayer的内存地址。 - 在 CE 里跳转到这个地址,观察结构。
- 找到
input_data区域,尝试手动修改那里的数组值,看看角色是否动。 - 如果成功,记录下指针链,以后就可以不用 REFramework 了。
你想试试看 打印内存地址并在 CE 里观察验证 吗?我可以写一个小脚本,在控制台输出 cPlayer 和 input_data 的真实内存地址。