实战示例2:修复GMSv83窗口位置重置的问题
该例子是实战示例1的扩展,在示例1中我们说到可以通过图层的初始坐标或者宽高数据,在客户端内存中定位到相关位置。视频地址:https://www.bilibili.com/video/BV1NPFjeLE5N/
今天遇到了一个特殊的例子:所有游戏内的窗口如:好友栏、背包栏、任务提示栏等,原本都是可以保存位置的,但是把窗口放置在一些特殊区域(v83使用了高分辨率后扩展的部分),重启游戏这些窗口就会重置为默认位置了。这是很典型的每个窗口出现了相同的问题,是一个通用问题。所以我们就不要针对具体的某个窗口去找问题了。
我当时的第一反应就是:在正常情况下(800x600),游戏窗口是可以保存的,如果我把游戏窗口拖到屏幕之外,那么这个窗口保存在屏幕之外了,下次再打开岂不是找不到这个窗口了。
如果我是游戏开发者的话,我会怎么做?很显然,我会设置一个范围,如果窗口的x、y坐标超出这个范围了,就把窗口重置回默认位置。
所以,客户端里肯定存在这么一个看不见的范围,只要把这个范围找出来,就能定位到问题所在的代码了。
而找这个范围比较麻烦。不像看得见的图片可以直接测量,这个看不见的范围需要不停地拖动窗口去尝试,在哪些位置可以保存,哪些位置会重置。
但是我们可以初步判断他的范围,x 肯定是在 750~800 之间的。
因为在默认分辨率(800x600)下,我们是没有感知到这个问题的,而在使用了高分辨率后遇到了这个问题,说明这个 x 值肯定是靠近右侧边缘而不超过原来的最大宽度(800)的。
所以我们直接把任意窗口拖到 x=750 和 x=800 的位置,测试游戏重启时这些窗口是否会重置位置。(注意系统缩放问题,要重计算真实宽度)
事实也恰如我们的猜测,当 x=750 时,重启游戏窗口位置不会重置;x=800 时重置。
那么剩下的就是二分法查找了。
最后定位到分界线是 784 / 785
那我们直接在 ida 中搜这两个值就可以了。
最终找到的地址及修改
Memory::WriteInt(0x0049D218 + 1, m_nGameWidth - 16);// 窗口保存位置边界 x
Memory::WriteInt(0x0049D268 + 1, m_nGameHeight - 16);// 窗口保存位置边界 y
页:
[1]