Open bigsinger opened 2 months ago
联网模式改 text 段会有两个问题,一个是被反作弊扫描到;另一个是产生平行世界,除非把所有人的同时都改了。
联网模式改 text 段会有两个问题,一个是被反作弊扫描到;另一个是产生平行世界,除非把所有人的同时都改了。
如果在内存中找到存放箱子列表的地址呢?然后修改箱子数据的属性,是不是就可以实现?
参考这个文章:红色警戒2-尤里复仇之自动全图捡箱子,里面提到「所有箱子坐标」,应该能找到箱子的列表。
从下面的代码可以看出,esi应该是箱子对象相关,动态调试时给拦截下来看一下:
00481DE0 |. FF2495 C43348>jmp dword ptr [edx*4+4833C4]
00481DE7 |> 0FBF46 26 movsx eax, word ptr [esi+26]
00481DEB |. 0FBF4E 24 movsx ecx, word ptr [esi+24]
00481DEF |. 50 push eax
00481DF0 |. 51 push ecx
00481DF1 |. 68 80D08100 push 0081D080 ; crate at %d,%d contains poison gas\n
00481DF6 |. E8 E54AF8FF call 004068E0
如下地址不确定是否跟箱子数据有关,动态调试的时候看下:
00481A28 |. 8B0D 843DA800 mov ecx, dword ptr [A83D84]
00481A3F |. 8B15 38B2A800 mov edx, dword ptr [A8B238]
00481A95 |. A1 48E78900 mov eax, dword ptr [89E748]
00481D5B |. 8A83 C0EC8900 mov al, byte ptr [ebx+89ECC0]
联机有数据一致性要求,本地数据修改必须直接或者间接发送给所有玩家,保持多人游戏状态同步。自动捡箱子功能会把对单位的操作也发给别的玩家,没有不一致问题。对箱子内容的修改无法发送给别的玩家,会导致多客户端数据不一致,俗称平行世界…… 就拿你之前提的几个建议来举例,改 GUI,放大小地图不需要主动同步,配置进攻策略,工程师自动抢修,自动维修,巨炮有顺序攻击,巨炮自动转向都需要主动同步,有些同步可能调了接口引擎就自动发了数据,接口上面看不到但是网络数据上有。
倒也不是不可行,要看修改的时机。
猜想:
可以在触碰箱子的时候,修改箱子的处理效果函数,例如修改为升级效果,之后的逻辑不动,则发送数据到服务端的逻辑仍然是通的。 也即修改的操作在发送数据之前应该是可行的。
@AdjWang
看下这块代码,动态调试下看看时机和箱子属性。
00481A00 /$ 55 push ebp
00481A01 |. 8BEC mov ebp, esp
00481A03 |. 83E4 F8 and esp, FFFFFFF8
00481A06 |. 81EC 7C010000 sub esp, 17C
00481A0C |. 53 push ebx
00481A0D |. 56 push esi
00481A0E |. 57 push edi
00481A0F |. 8B7D 08 mov edi, dword ptr [ebp+8]
00481A12 |. 85FF test edi, edi
00481A14 |. 8BF1 mov esi, ecx
00481A16 |. 0F84 6D190000 je 00483389
00481A1C |. 8B46 44 mov eax, dword ptr [esi+44]
00481A1F |. 83F8 FF cmp eax, -1
00481A22 |. 0F84 61190000 je 00483389
00481A28 |. 8B0D 843DA800 mov ecx, dword ptr [A83D84]
00481A2E |. 8B1481 mov edx, dword ptr [ecx+eax*4]
00481A31 |. 8A9A AA020000 mov bl, byte ptr [edx+2AA]
00481A37 |. 84DB test bl, bl
00481A39 |. 0F84 4A190000 je 00483389
00481A3F |. 8B15 38B2A800 mov edx, dword ptr [A8B238]
00481A45 |. C64424 13 00 mov byte ptr [esp+13], 0
00481A4A |. 85D2 test edx, edx
00481A4C |. C74424 14 000>mov dword ptr [esp+14], 0
00481A54 |. 74 17 je short 00481A6D
00481A56 |. 8B97 1C020000 mov edx, dword ptr [edi+21C]
00481A5C |. 8B52 34 mov edx, dword ptr [edx+34]
00481A5F |. 8A9A A6010000 mov bl, byte ptr [edx+1A6]
00481A65 |. 84DB test bl, bl
00481A67 |. 0F85 1C190000 jnz 00483389
00481A6D |> 8B0481 mov eax, dword ptr [ecx+eax*4]
00481A70 |. 8A88 AB020000 mov cl, byte ptr [eax+2AB]
00481A76 |. 84C9 test cl, cl
00481A78 |. 74 4E je short 00481AC8
00481A7A |. 8B47 34 mov eax, dword ptr [edi+34]
00481A7D |. 85C0 test eax, eax
00481A7F |. 74 3A je short 00481ABB
00481A81 |. 0FBF4E 26 movsx ecx, word ptr [esi+26]
00481A85 |. 0FBF56 24 movsx edx, word ptr [esi+24]
00481A89 |. 51 push ecx
00481A8A |. 52 push edx
00481A8B |. 68 A4D08100 push 0081D0A4 ; springing trigger on crate at %d,%d\n
00481A90 |. E8 4B4EF8FF call 004068E0
从箱子生成到单位拾取箱子过程中,只有对单位的移动指令会发送给服务器,其他的都是计算出来的。发送到服务器的内容有限,事件类型定义在 https://github.com/Phobos-developers/YRpp/blob/phobos-dev/GeneralDefinitions.h#L1370
。
具体到这个例子,假如两个人在线上,双方的游戏配置共同的随机数种子,时钟就是游戏从开始时候累计的帧数,"在第1000帧随机生成升级箱子"这个事件是计算出来的,因为随机数和帧数计算结果一致,所以不发送网络数据双方也是同步的。
只有玩家输入的操作,比如建造、移动单位、攻击这些无法通过随机数和时钟计算得到的事件,才会发到服务器上。
@AdjWang 那就比较困惑了:
我大概理解下: 所有玩家拥有所有地图和所有单位的所有数据,各自客户端各自计算自己的,因为数据和算法一致,所以结果也是一致的,不会出现同步问题。
有点类似区块链的思想,每个客户端都在计算,都有全量数据。
如果按照这个思路的话,似乎如意宝箱就很难实现了,但是似乎强制修改数据有实现的可能,修改后锁死并同步出去,有机会可以将所有玩家的数据给刷回去。
我大概理解下: 所有玩家拥有所有地图和所有单位的所有数据,各自客户端各自计算自己的,因为数据和算法一致,所以结果也是一致的,不会出现同步问题。
有点类似区块链的思想,每个客户端都在计算,都有全量数据。
如果按照这个思路的话,似乎如意宝箱就很难实现了,但是似乎强制修改数据有实现的可能,修改后锁死并同步出去,有机会可以将所有玩家的数据给刷回去。
是这样的。
箱子目前是随机效果,可以实现一个如意宝箱的效果,就是想来啥来啥。这个目前在单机版已经实现了,可以用,代码如下:
其他捡箱子效果可以参考这个来设计。这样当缺钱的时候,就按下按键让所有捡箱子效果是金钱,当需要升级部队时按下某个按键让捡箱子效果都是升级,以此类推……
另:这个功能在联网对战中会卡死,不知道啥原因,有知道的吗?