最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

pvzclass是如何實(shí)現(xiàn)的?pvzclass源代碼初步分析(8)Creaters

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

PVZ.h給了pvzclass修改、監(jiān)控游戲內(nèi)多種對(duì)象,乃至直接刪除它們的能力。

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

強(qiáng)烈建議在閱讀本篇前先閱讀第4篇和第5篇的內(nèi)容。

注:本文以2021.8.11更新的版本為準(zhǔn)。

Creaters.h

雖然名叫"Creaters",但這份文件包含的命名空間卻并不帶's',而是"Creater"。

該命名空間下包含三個(gè)部分:常用函數(shù)、宏定義、函數(shù)聲明。

常用函數(shù)包括 makeshort() 和 xytorc()?兩個(gè)工具函數(shù)。

前者的作用看代碼就知道了,是將兩個(gè)8字節(jié)的數(shù)拼成一個(gè)16字節(jié)的數(shù):

這個(gè)函數(shù)主要用于將匯編命令宏(通常是多個(gè)8字節(jié)的數(shù))轉(zhuǎn)換為 WriteMemory() 能識(shí)別的整數(shù)型變量。

xytorc()?的作用則是將行列轉(zhuǎn)換為PVZ內(nèi)部的xy坐標(biāo)。

代碼也很簡(jiǎn)單,判斷是否為六行場(chǎng)景,根據(jù)對(duì)應(yīng)公式轉(zhuǎn)換。

宏定義部分的代碼比較擠,除了PI以外都不能一眼看出其作用。

但仔細(xì)觀察,就會(huì)發(fā)現(xiàn)它們的共同之處:

看來(lái)這些宏和 Asmfuntions.h 中某一段宏的作用一樣,都是應(yīng)用INVOKE宏而已。

剩下的則是函數(shù)聲明,以及結(jié)構(gòu)體 VaseCreateInfo 的定義。

函數(shù)的具體定義在 Creaters.cpp?中可以看到。

VaseCreateInfo 可以存儲(chǔ)罐子的所在行列、外觀、類(lèi)型和內(nèi)容物。

這個(gè)東西的存在純粹是因?yàn)?CreateVase() 的第一聲明太過(guò)繁雜(參數(shù)有7個(gè),單個(gè)聲明就占了250字符左右),不簡(jiǎn)潔。

如果沒(méi)有接觸過(guò)2021.8.10更新,以及這之后的版本的 pvzclass ,可能會(huì)對(duì)部分函數(shù)的類(lèi)型感到陌生:

這SPT<>是何方神圣?

這是2021.8.10更新的重要內(nèi)容之一:引入C++11的 std::shared_ptr?和 std::make_shared?等四個(gè)內(nèi)容,換下了以前版本 pvzclass?絕大部分C指針和?new 。相關(guān)的宏定義在 PVZ.h 中:

據(jù)貢獻(xiàn)者 theflysong (github名)的說(shuō)法,這是為了避免內(nèi)存泄漏。

如果你并不了解 std::shared_ptr?和 std::make_shared ,你可以近似認(rèn)為 std::shared_ptr?是一個(gè)加強(qiáng)版的指針,而 std::make_shared?則是其專(zhuān)屬的 new 。

?std::unique_ptr?和?std::make_unique?或許是類(lèi)似的,但這次更新只是加入了它們,并沒(méi)有具體應(yīng)用。

回到 Creaters?本身。既然有了前面的宏定義,那么函數(shù)的原理基本已經(jīng)確定了:代碼注入。

下面解讀兩個(gè)特殊的代碼注入。

Creaters.cpp 中幾個(gè)特殊的代碼注入

CreateZombie()

CreateZombie()?中注入代碼前對(duì)PVZ本體的程序做了一些 WriteMemory() ,這些代碼可以幫助?CreateZombie()? 獲取到原本被直接拋棄的僵尸對(duì)象內(nèi)存地址。

但是 CreateZombie() 結(jié)束后,這些改變并沒(méi)有被還原。(實(shí)際上影響不大,不會(huì)導(dǎo)致PVZ出現(xiàn)任何問(wèn)題)

AsmInit()

在 Creaters.h?中,CreateProjectile() ,?__CreatePortal() ,?CreatePortal()?三個(gè)函數(shù)的聲明前有同一句注釋?zhuān)?br>

原因很簡(jiǎn)單,AsmInit()?可以將上述三個(gè)函數(shù)需要的匯編代碼先行注入,并將代碼需要的部分參數(shù)設(shè)置好。

以上為 CreateProjectile()?的一個(gè)聲明。

這個(gè)函數(shù)并沒(méi)有進(jìn)行代碼注入,卻有一個(gè) CreateThread() ,顯然應(yīng)該有誰(shuí)提前注入了代碼。

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

__CreatePortal()?也有類(lèi)似的情況。

AsmInit()?將兩段代碼分別注入到了 Variable+16?和 Variable+200?的位置,設(shè)置的參數(shù)也與Variable直接相關(guān)。這意味著只要一次AsmInit(),就可以自由使用上面的三個(gè)函數(shù)。

但同時(shí),如果亂動(dòng) Variable,AsmInit()?就會(huì)失去其效用,其他函數(shù)也可能會(huì)產(chǎn)生意想不到的問(wèn)題。

當(dāng)初天青在教程中有意不說(shuō) Variable?的作用,或許就是防止有人亂用吧。

下一期將解讀 Extension.h?和 utils.h?兩個(gè)頭文件的代碼。

pvzclass是如何實(shí)現(xiàn)的?pvzclass源代碼初步分析(8)Creaters的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
瑞安市| 杂多县| 福州市| 宁城县| 富宁县| 陆良县| 台山市| 东台市| 湘潭县| 济宁市| 金堂县| 青州市| 长垣县| 嘉兴市| 西平县| 敖汉旗| 东安县| 怀宁县| 鲁山县| 襄垣县| 双柏县| 安庆市| 盐城市| 海口市| 镇赉县| 永寿县| 柘荣县| 铜陵市| 来凤县| 阳原县| 江永县| 锦屏县| 额济纳旗| 贡嘎县| 萍乡市| 潢川县| 湟中县| 抚松县| 漯河市| 马尔康县| 辛集市|