war3小助手


前段时间在09平台打dota omg,被平台的匹配机制搞到了。我一个胜率50不到的菜鸡,经常给我在对面匹配几个70+,80+胜率大佬,自己这边又都是50不到。这种局实在不想打了,就想做一个工具来检测这种情况,在进入房间时发现高胜率的时候就退出匹配。

整体设计

整个系统需要以下几个模块:

  1. 游戏阶段检测: 负责检测游戏当前的阶段,包括是否处于房间中、游戏中或者游戏未启动状态。

  2. 玩家昵称获取: 负责获取房间内玩家的昵称信息。

  3. 玩家胜率查询: 负责查询玩家昵称对应的游戏胜率以及局数信息。

  4. GUI界面展示: 负责通过用户界面展示当前房间内玩家的胜率信息。

  5. 高胜率玩家警告: 当系统检测到高胜率玩家时,负责主动向玩家发送警告信息。

获取玩家昵称的方案

确定如何读取房间内玩家的昵称是关键问题,我考虑了三种方案:

  1. 抓取网络包: 这种方案通过监控网络包,从中解析出玩家昵称。然而,这需要在程序运行期间对网络一直进行监控,可能会对原有通信造成一定影响。因此,我暂时放弃了这个方案,但我相信如果有需要,也可以尝试解决这个问题。

  2. 读取war3进程的内存: 这个方案通过读取游戏进程的内存,从对应的地址中解析出玩家昵称。考虑到我需要通过检测进程内容来确定游戏程序的运行状态,而且读取玩家的昵称也是顺带的事情,所以最终我选择了这个方案。

  3. orc识别: 这个方案需要在进入房间后进行orc识别,从识别结果中读取玩家昵称。然而,orc识别需要有特定时机来识别,如果采用用户主动触发识别,则需要占用快捷键;如果采用被动识别,则需要不断截图、不断识别,且不一定能准确识别到玩家昵称。因此,我首先放弃了这个方案。

语言选择

在语言选择方面,最初我使用了Python来编写这个工具,但后来放弃了这个选择。主要原因是,想要读取其他进程内的数据需要通过Windows的UAC进行提权。虽然Python可以申请管理员权限提权,但在尝试过PyInstaller和Nuitka两种工具对Python程序进行打包时遇到了问题。打包后的Python程序可以提权,显示拥有管理员权限,但在申请Windows的sedebug权限时却一直失败,导致无法访问其他程序内存,有懂的读者可以说说解决方案,我搜索了很久也没找到为啥。因此,我决定改用C#来编写Windows程序,毕竟在Windows平台上编写程序,C#看起来更专业。
windows下申请uac权限

游戏阶段检测

对于检测游戏阶段,其实还是比较容易的。只需要尝试搜索windows现有的进程中有没有war3.exe, 没有这个进程就是未启动。在房间中的话,可以搜到进程,并且在对应的内存地址存有玩家的昵称。在游戏中就直接笼统的判定,游戏已启动,但是没有检测到房间内的玩家名称地址偏移内存在合法名称。
游戏房间内

获取昵称的内存地址

要获取房间内玩家的昵称,首先需要确定玩家昵称存储的内存地址。这需要使用一个工具,比如Cheat Engine。通过该工具,可以查找玩家昵称存储的内存地址。需要注意的是,找到的地址通常不是直接的内存地址,特别是对于字符串,通常是动态申请的内存地址来存储字符串,每次重启程序直接内存地址都会变化。因此,需要通过查找访问直接内存地址的代码所使用的间接地址来定位。而这个间接地址也可能是一个动态变化的地址,因此需要找到存储间接地址的间接地址,并存储对应的偏移。最终找到的静态地址通常是一个DLL文件加上一个偏移地址的组合。 不过这个过程比较曲折,复杂的游戏指针层数往往非常高,这时候就可以考虑使用指针地图法来寻找多级地址偏移。

获取玩家胜率

要通过昵称查找玩家的胜率,只需要访问平台官网,通过查询战绩的接口找到对应的API地址即可。通过查看robots协议,确定可以使用爬虫通过API地址来查询战绩。为了减少平台的压力,我把战绩存入数据库,不会重复查找一个玩家的战绩。毕竟,玩家的战绩变化相对缓慢,特别是游戏局数较多的玩家。当然,何时更新玩家的战绩可以稍后再考虑。毕竟因为查询频率较低(一局游戏就10个玩家,持续大概30分钟),直接不存储到数据库也是可行的。

显示玩家胜率

最后,GUI界面可以简陋一些,直接通过现有的C#组件在Visual Studio里拼凑即可。对于遇到高胜率玩家的门槛,可以自行设定。最后,通过Windows Toast来直接发送通知,提醒用户离开房间。这样,玩家就不必一直盯着我们的GUI界面,只需在需要时切出去查看胜率。
最终界面
其实还有一个更加优雅的方案,就是直接修改war3的内存地址,将玩家的胜率显示在游戏内部。然而,这种操作存在一些问题:首先,内存地址可能不准确,修改到未知的区域可能导致程序崩溃;其次,不清楚这个地址是否还有其他用处,可能会导致一些数据与其他玩家不一致的问题,进而被主机踢出游戏;最后,该内存地址可能被用于反作弊检测,导致玩家掉线。

后记

查看胜率好像也没有啥用,打不过还是打不过,只能躲一些高胜率的,终究是菜了🥵。


文章作者: 青椒
版权声明: 本笔记所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 青椒 !
 上一篇
SpaceSniffer导出sns文件存储格式分析 SpaceSniffer导出sns文件存储格式分析
在处理大型软件系统时,我们经常需要分析系统运行时的内存分布,了解哪些数据结构占用了大量内存。虽然可以通过数值进行观察,但这并不直观。这时,我想到了SpaceSniffer这款软件。SpaceSniffer主要用于磁盘空间的管理和可视化,它
2024-04-30 青椒
下一篇 
我的服务器居然变巨慢? 我的服务器居然变巨慢?
今天在使用自己的网页时,忽然发现自己的服务器访问网页资源变得极其之慢,以致于不能正常使用。于是便开始排查原因。结果就是多数时候遇到的“就这?” 首先,我需要确定是网络问题还是CPU负载问题,于是我通过netstat和top命令进行了确认
2023-03-11 青椒
  目录