欢迎光临散文网 会员登陆 & 注册

pvzclass是如何实现的?pvzclass源代码初步分析(8)Creaters

2021-08-12 17:44 作者:__W1thoutD0ubt  | 我要投稿

PVZ.h给了pvzclass修改、监控游戏内多种对象,乃至直接删除它们的能力。

但是生成新的对象,就必须用到pvzclass的另一部分——Creaters(.h/.cpp)。

强烈建议在阅读本篇前先阅读第4篇和第5篇的内容

注:本文以2021.8.11更新的版本为准。

Creaters.h

虽然名叫"Creaters",但这份文件包含的命名空间却并不带's',而是"Creater"。

该命名空间下包含三个部分:常用函数、宏定义、函数声明。

常用函数包括 makeshort() 和 xytorc() 两个工具函数。

前者的作用看代码就知道了,是将两个8字节的数拼成一个16字节的数:

这个函数主要用于将汇编命令宏(通常是多个8字节的数)转换为 WriteMemory() 能识别的整数型变量。

xytorc() 的作用则是将行列转换为PVZ内部的xy坐标。

代码也很简单,判断是否为六行场景,根据对应公式转换。

宏定义部分的代码比较挤,除了PI以外都不能一眼看出其作用。

但仔细观察,就会发现它们的共同之处:

看来这些宏和 Asmfuntions.h 中某一段宏的作用一样,都是应用INVOKE宏而已。

剩下的则是函数声明,以及结构体 VaseCreateInfo 的定义。

函数的具体定义在 Creaters.cpp 中可以看到。

VaseCreateInfo 可以存储罐子的所在行列、外观、类型和内容物。

这个东西的存在纯粹是因为 CreateVase() 的第一声明太过繁杂(参数有7个,单个声明就占了250字符左右),不简洁。

如果没有接触过2021.8.10更新,以及这之后的版本的 pvzclass ,可能会对部分函数的类型感到陌生:

这SPT<>是何方神圣?

这是2021.8.10更新的重要内容之一:引入C++11的 std::shared_ptr 和 std::make_shared 等四个内容,换下了以前版本 pvzclass 绝大部分C指针和 new 。相关的宏定义在 PVZ.h 中:

据贡献者 theflysong (github名)的说法,这是为了避免内存泄漏。

如果你并不了解 std::shared_ptr 和 std::make_shared ,你可以近似认为 std::shared_ptr 是一个加强版的指针,而 std::make_shared 则是其专属的 new 。

 std::unique_ptr 和 std::make_unique 或许是类似的,但这次更新只是加入了它们,并没有具体应用。

回到 Creaters 本身。既然有了前面的宏定义,那么函数的原理基本已经确定了:代码注入。

下面解读两个特殊的代码注入。

Creaters.cpp 中几个特殊的代码注入

CreateZombie()

CreateZombie() 中注入代码前对PVZ本体的程序做了一些 WriteMemory() ,这些代码可以帮助 CreateZombie()  获取到原本被直接抛弃的僵尸对象内存地址。

但是 CreateZombie() 结束后,这些改变并没有被还原。(实际上影响不大,不会导致PVZ出现任何问题)

AsmInit()

在 Creaters.h 中,CreateProjectile() , __CreatePortal() , CreatePortal() 三个函数的声明前有同一句注释:

原因很简单,AsmInit() 可以将上述三个函数需要的汇编代码先行注入,并将代码需要的部分参数设置好。

以上为 CreateProjectile() 的一个声明。

这个函数并没有进行代码注入,却有一个 CreateThread() ,显然应该有谁提前注入了代码。

完成这一工作的正是 AsmInit()。

__CreatePortal() 也有类似的情况。

AsmInit() 将两段代码分别注入到了 Variable+16 和 Variable+200 的位置,设置的参数也与Variable直接相关。这意味着只要一次AsmInit(),就可以自由使用上面的三个函数。

但同时,如果乱动 Variable,AsmInit() 就会失去其效用,其他函数也可能会产生意想不到的问题。

当初天青在教程中有意不说 Variable 的作用,或许就是防止有人乱用吧。

下一期将解读 Extension.h 和 utils.h 两个头文件的代码。

pvzclass是如何实现的?pvzclass源代码初步分析(8)Creaters的评论 (共 条)

分享到微博请遵守国家法律