Minecraft 20w48a 新內(nèi)容特性+代碼解析

這周的快照又來了!雖然上周沒有快照,但是感覺更新的東西不多,有可能是在討論地形生成吧。那么現(xiàn)在來看看這周的20w48a。
一.漏洞修復(fù)
1.MC-205454 收納袋復(fù)制
沒錯(cuò),這個(gè)復(fù)制它不復(fù)存在了,所以大家還是不要白嫖的好。由于這邊代碼太復(fù)雜(Mojang寫的太惡心)就不解析了。
2.MC-3615 流體透視
這個(gè)bug是遠(yuǎn)古bug,持續(xù)了200以上個(gè)版本,首次報(bào)告記錄在2012年(Mojang,真有你的,修個(gè)bug花了8年)。由于還是找不到改在哪里了,所以就不解析了(真應(yīng)該寫一個(gè)對(duì)比程序)。

3.MC-205041 皮革盔甲不能防止冰凍
?? MC-205069 創(chuàng)造模式不會(huì)冰凍
MC-205041應(yīng)該是上次快照忘加了,現(xiàn)在是正常的,而另一個(gè)和它原理一樣,就放到一起了。

皮革裝備都有一個(gè)標(biāo)簽:freeze_immune_wearables,這個(gè)標(biāo)簽代表了穿著它們不會(huì)受到冰凍。

同時(shí),增加了新的游戲規(guī)則“freezeDamage”決定是否有冰凍傷害。

二.收納袋存儲(chǔ)的修改
收納袋現(xiàn)在又有了新的修改。首先是在高級(jí)提示框的時(shí)候會(huì)出現(xiàn)“Fullness”的提示,它代表了收納袋內(nèi)有什么內(nèi)容物。

對(duì)于存儲(chǔ)物品方面,現(xiàn)在它能按裝入順序的倒序取出。這聽起來,...棧??

說說是怎么實(shí)現(xiàn)的吧:收納袋有一個(gè)NBT標(biāo)簽“Items”,是一個(gè)列表型的數(shù)據(jù),內(nèi)部存儲(chǔ)物品標(biāo)簽。列表數(shù)據(jù)具有順序,當(dāng)你添加一個(gè)物品,這個(gè)物品就被放到列表的第一格數(shù)據(jù);當(dāng)你拿出物品,第一格數(shù)據(jù)取出,刪除。這種方式遵循了LIFO(Last-In-First-Out)原則,所以就是一個(gè)棧。

當(dāng)你右鍵使用收納袋時(shí),上一個(gè)版本會(huì)直接把物品放到物品欄,現(xiàn)在則是直接丟出去(垃圾袋?)

代碼這里就簡(jiǎn)單了,就是調(diào)用了drop,和普通丟出物品沒兩樣。

三.滴水石錐
這是這個(gè)快照增加的兩種方塊其中之一,另一種“滴水石塊”暫時(shí)沒有用處,所以不在這里說了。

滴水石錐有三個(gè)屬性:TIP_DIRECTION(方向), THICKNESS(大?。? WATERLOGGED(含水)。方向有兩種:向上(成為石筍)或者向下(成為鐘乳石)。大小有5種:TIP、FRUSTUM,MIDDLE,BASE和形成石柱時(shí)才會(huì)出現(xiàn)的TIP_MERGE。
首先來說說它的方塊特性。
當(dāng)它是石筍時(shí),它會(huì)對(duì)落到上方的實(shí)體產(chǎn)生傷害。這個(gè)傷害實(shí)質(zhì)上是摔落傷害,通過覆蓋fallOn方法,將摔落距離乘以4倍,所以當(dāng)無(wú)盔甲、無(wú)效果、非免疫摔落傷害的實(shí)體從6格摔落會(huì)立刻暴斃(平常要24格)。

按照這個(gè)原理,我們可以知道跳躍提升效果(讓摔落距離減去等級(jí))、緩降效果(fallDistance強(qiáng)制置零)、保護(hù)附魔、摔落保護(hù)附魔對(duì)此都有保護(hù)效果。
說完了扎死,下面說說砸死,不過在此之前了解一下它的方塊生存條件。

當(dāng)鐘乳石沒有上方方塊,石筍沒有下方方塊,就會(huì)掉落。同時(shí),活塞推動(dòng)和三叉戟(有速度要求:至少要0.6m/tick,也就是12m/s)也會(huì)導(dǎo)致它掉落。

好了,回到鐘乳石,它在破壞上方方塊時(shí)會(huì)產(chǎn)生下落的鐘乳石方塊(FallingBlock)。這個(gè)操作發(fā)生于檢查的2tick之后,因?yàn)檎{(diào)用的是計(jì)劃刻。


當(dāng)2tick一到,計(jì)劃刻被調(diào)用,開始生成下落方塊,這里通過tick調(diào)用了spawnFallingStalactite這個(gè)方法。

然而這里出現(xiàn)了一個(gè)問題。當(dāng)你嘗試去擼掉連起來的第51格鐘乳石的時(shí)候,所有鐘乳石都不會(huì)掉下來;只有在敲掉第50格以下的才能掉落,這是為什么呢?

在scheduleStalactiteFallTicks這個(gè)方法里面我們看到了findTip這個(gè)方法,它返回null就不會(huì)執(zhí)行下落方塊生成,看來問題出現(xiàn)在這里。

從代碼中看出,尋找尖端只會(huì)調(diào)用50次,找不到就拉倒返回null,如果下方是石柱,也是返回null。所以你在第51格打掉就不會(huì)找到尖端,也就不會(huì)導(dǎo)致它整體掉落了。
鐘乳石還有另一個(gè)特性:滴水/巖漿
這個(gè)特性需要保證:鐘乳石只有一格,上方附著方塊的上方是水源/巖漿源

當(dāng)鐘乳石上方不具有巖漿源/水源方塊時(shí),它不會(huì)滴水/巖漿,只會(huì)呈現(xiàn)出虛假的粒子效果。
當(dāng)上方是水源,會(huì)產(chǎn)生滴水的粒子效果(和啥也沒有一樣);如果是巖漿源,則是滴巖漿的效果。


這段代碼看出:當(dāng)沒有流體源方塊時(shí),會(huì)有1/50的概率產(chǎn)生粒子效果;當(dāng)有流體源方塊,滴落粒子效果是3/25觸發(fā)。

這個(gè)方法能看出為什么能產(chǎn)生不同的粒子效果。
介紹完表面功夫,下面說說真功夫。
首先,滴入煉藥鍋流體是隨機(jī)刻觸發(fā),所以randomTickSpeed有效(不像某細(xì)雪)。下面這個(gè)是隨機(jī)刻的代碼。

調(diào)用的方法maybeFillCauldron就是填充煉藥鍋用的,代碼如下:

這段代碼解讀起來是這樣的:首先是條件判定,前面已經(jīng)說過了。之后是判斷流體類型,如果是水,那么有0.29296875的機(jī)會(huì)滴落填充下方;如果是巖漿,就是0.17578125的機(jī)會(huì)。判斷要滴落之后,尋找下方煉藥鍋,這里只會(huì)尋找十格以內(nèi)的煉藥鍋,多了也不去找。之后發(fā)送更新,在計(jì)劃刻50+相距高度后進(jìn)行填充煉藥鍋。

最后,關(guān)于滴水石錐的方塊偏移可能有人已經(jīng)發(fā)現(xiàn)它和草差不多,這是因?yàn)樗鼈冇昧讼嗨频姆绞綄?shí)現(xiàn)了方塊的偏移:getOffestType。普通方塊返回的都是“NONE”,而滴水石錐是“XZ”,草是“XYZ”。這些參數(shù)在BlockState里面解析成為方塊的偏移,具體代碼如下:

這段代碼就不解析了,主要是在Vec3創(chuàng)建那里的代碼比較重要:可以看到無(wú)論是XZ還是XYZ類型的偏移都用了同一種算法,所以方塊的偏移是一樣的。
這個(gè)偏移在反推方塊位置有一些用處,比如pack.png的種子尋找就用了這個(gè)。

那么到這里代碼解析就結(jié)束了,期待下一次的快照!

代碼:Mojang官方混淆表+反混淆+反編譯
反混淆器:MCDynamicExchanger beta 6(正在開發(fā))
beta 5 版本在GitHub上可用,網(wǎng)址https://github.com/Nickid2018/MCDynamicExchanger
反編譯器:Eclipse插件, FernFlower/CFK
文章中若有錯(cuò)誤請(qǐng)大家指出,我將修改專欄。