Minecraft 21w08a-21w11a代碼簡(jiǎn)析

這么多次版本更新都沒(méi)法快照代碼解析,那么今天都發(fā)出來(lái)吧!
版本文件對(duì)比表:
21w06a->21w07a https://paste.ubuntu.com/p/GYDNmJW6N7/
21w07a->21w08b https://paste.ubuntu.com/p/cZcxZ9KN4V/
21w08b->21w10a https://paste.ubuntu.com/p/bKRD2vF8cc/
21w10a->21w11a https://paste.ubuntu.com/p/YJZQWkhvmf/
一.銅塊去蠟去銹
銅塊在21w11a中能夠被斧子去蠟和去銹。

首先是去蠟,現(xiàn)在斧子能把帶蠟的銅塊變?yōu)椴粠灥淖兎N,在此期間消耗1耐久度(無(wú)耐久附魔)。
去銹也類(lèi)似,不過(guò)只能將銅塊恢復(fù)到上一銹蝕階段,也消耗1耐久度(無(wú)耐久附魔)
public InteractionResult useOn(UseOnContext useOnContext) {
Level level = useOnContext.getLevel();
BlockPos blockPos = useOnContext.getClickedPos();
Player player2 = useOnContext.getPlayer();
BlockState blockState = level.getBlockState(blockPos);
Optional
在被閃電劈中后,銅塊也能被清除銹蝕,它的實(shí)現(xiàn)如下:

首先選擇判定點(diǎn):判斷閃電是不是劈到了避雷針,如果是,那么判定點(diǎn)為避雷針的附著方塊;如果不是,則判定點(diǎn)就是閃電劈中的位置。
接下來(lái),判斷判定點(diǎn)位置上是不是未涂蠟銅塊,如果是,將這一塊銅塊直接還原到普通未銹蝕銅塊,并進(jìn)行接下來(lái)的操作;如果不是,則停止判定。
private static void clearCopperOnLightningStrike(Level level, BlockPos blockPos) {
// 閃電劈下時(shí)判定
BlockPos blockPos2;
BlockState blockState;
BlockState blockState2 = level.getBlockState(blockPos);
if (blockState2.is(Blocks.LIGHTNING_ROD)) {
blockPos2 = blockPos
.relative(((Direction) blockState2.getValue((Property) LightningRodBlock.FACING)).getOpposite());
blockState = level.getBlockState(blockPos2);
} else {
blockPos2 = blockPos;
blockState = blockState2;
}
if (!(blockState.getBlock() instanceof WeatheringCopper)) {
return;
}
level.setBlockAndUpdate(blockPos2, WeatheringCopper.getFirst((BlockState) level.getBlockState(blockPos2)));
BlockPos.MutableBlockPos mutableBlockPos = blockPos.mutable();
int n = level.random.nextInt(3) + 3;
for (int i = 0; i < n; ++i) {
int n2 = level.random.nextInt(8) + 1;
LightningBolt.randomWalkCleaningCopper(level, blockPos2, mutableBlockPos, n2);
}
}
在修改了判定點(diǎn)方塊后,系統(tǒng)將執(zhí)行3-5次旁邊銅塊的除銹。每次都會(huì)在判定游走點(diǎn)周?chē)?x3x3范圍內(nèi)隨機(jī)選取10個(gè)方塊,如果選中的方塊不是銅塊及其變種,則跳過(guò);如果是,則將這個(gè)銅塊清理回到上一階段,并重新設(shè)置游走點(diǎn)為原先的判定點(diǎn),如果這10個(gè)方塊都不是銅類(lèi)方塊,則游走停止,不再繼續(xù),這個(gè)過(guò)程重復(fù)1-8次。
不好理解?下面是一個(gè)形象化的小栗子:
在閃電之中,誕生了3-5個(gè)神奇的人類(lèi)。他們腳踩著閃電劈下的方塊或者劈中的避雷針下面的方塊。它們誕生時(shí)擁有1-8格體力,供他們"游走"。在閃電徹底除掉方塊的銹蝕之后,他們開(kāi)始隨機(jī)的向前走。他們每一個(gè)人每走一步都會(huì)在他們周?chē)?x3x3的方塊范圍內(nèi)找10個(gè)方塊(包括自己踩的),如果找到了沒(méi)有蠟的銅塊,他們就會(huì)跳上這個(gè)方塊,除去這個(gè)銅塊的一層銹(如果有的話);如果沒(méi)有找到,就原地歇息一下,什么都不干。無(wú)論他們這一步有沒(méi)有成功的游走,都會(huì)消耗1體力。當(dāng)他們走完了所有體力,他們就會(huì)消失。
根據(jù)這個(gè)原理,我們可以知道為了讓閃電清除掉一片銅銹,我們必須要保證銅塊相連或相鄰(3x3x3范圍內(nèi)有別的銅塊)。如果我們只放了一個(gè)單獨(dú)的銅塊,但是3x3x3內(nèi)沒(méi)有其它銅塊,那么,即使你在其他很近的位置上放置銅塊,閃電也無(wú)法清除它們的銹,因?yàn)榕卸c(diǎn)無(wú)法移動(dòng)到除原先判定點(diǎn)的位置。同樣,根據(jù)這個(gè)原理,我們可以知道一次閃電最多可以清除41個(gè)方塊(起始點(diǎn)還原回銅塊,其他都只清除到上一階段),最遠(yuǎn)也能清除8個(gè)方塊。
private static void randomWalkCleaningCopper(Level level, BlockPos blockPos,
BlockPos.MutableBlockPos mutableBlockPos, int n) {
// 隨機(jī)行進(jìn)清除
Optional
二.垂滴葉的“漲水”特性
這個(gè)版本中有不少bug(特性),這就是一個(gè)。

這個(gè)特性是:當(dāng)你在催熟含水的垂滴葉柄的時(shí)候,水會(huì)“漲”上來(lái)。

下面是特性的原理:當(dāng)催熟垂滴葉柄的時(shí)候,系統(tǒng)會(huì)去尋找垂滴葉柄頂端的大型垂滴葉,如果沒(méi)有,則催熟不成功;如果有的話,先讀取現(xiàn)在催熟的方塊的流體狀態(tài),然后會(huì)用這個(gè)流體狀態(tài)去放置新的垂滴葉柄!所以導(dǎo)致了水被“頂”了起來(lái)。下面就是詳細(xì)的代碼:
public void performBonemeal(ServerLevel serverLevel, Random random, BlockPos blockPos, BlockState blockState) {
Optional optional = BlockUtil.getTopConnectedBlock((BlockGetter) serverLevel, (BlockPos) blockPos,
(Block) blockState.getBlock(), (Direction) Direction.UP, (Block) Blocks.BIG_DRIPLEAF);
if (!optional.isPresent()) {
return;
}
BlockPos blockPos2 = (BlockPos) optional.get();
BlockPos blockPos3 = blockPos2.above();
FluidState fluidState = serverLevel.getFluidState(blockPos3);
Direction direction = (Direction) blockState.getValue((Property) FACING);
BigDripleafStemBlock.place((LevelAccessor) serverLevel, blockPos2, blockState.getFluidState(), direction);
BigDripleafBlock.place((LevelAccessor) serverLevel, (BlockPos) blockPos3, (FluidState) fluidState,
(Direction) direction);
}
三.F3+L保存性能分析數(shù)據(jù)
這是一個(gè)對(duì)于模組開(kāi)發(fā)者的福利(?),這個(gè)新功能的代碼net.minecraft.client.profiling里面,它記錄的有JVM信息、FPS信息、渲染區(qū)塊數(shù)量、待上傳區(qū)塊數(shù)量、其他渲染信息等。和debug命令差不多,只是沒(méi)有了各種實(shí)體運(yùn)算方塊運(yùn)算的數(shù)據(jù),主要都是客戶(hù)端的渲染信息。

(由于CFK反編譯器在此處無(wú)法翻譯lambda表達(dá)式,就不放出源碼了)
四.網(wǎng)絡(luò)系統(tǒng)的暗改(可能?)
在21w08a的時(shí)候,network包的文件都被修改了一回,就像下面一樣:
(21w07a)
public ClientboundAddEntityPacket(int n, UUID uUID, double d, double d2, double d3, float f, float f2,
EntityType entityType, int n2, Vec3 vec3) {
this.id = n;
this.uuid = uUID;
this.x = d;
this.y = d2;
this.z = d3;
this.xRot = Mth.floor((float) (f * 256.0f / 360.0f));
this.yRot = Mth.floor((float) (f2 * 256.0f / 360.0f));
this.type = entityType;
this.data = n2;
this.xa = (int) (Mth.clamp((double) vec3.x, (double) -3.9, (double) 3.9) * 8000.0);
this.ya = (int) (Mth.clamp((double) vec3.y, (double) -3.9, (double) 3.9) * 8000.0);
this.za = (int) (Mth.clamp((double) vec3.z, (double) -3.9, (double) 3.9) * 8000.0);
}
public void read(FriendlyByteBuf friendlyByteBuf) throws IOException {
this.id = friendlyByteBuf.readVarInt();
this.uuid = friendlyByteBuf.readUUID();
this.type = (EntityType) Registry.ENTITY_TYPE.byId(friendlyByteBuf.readVarInt());
this.x = friendlyByteBuf.readDouble();
this.y = friendlyByteBuf.readDouble();
this.z = friendlyByteBuf.readDouble();
this.xRot = friendlyByteBuf.readByte();
this.yRot = friendlyByteBuf.readByte();
this.data = friendlyByteBuf.readInt();
this.xa = friendlyByteBuf.readShort();
this.ya = friendlyByteBuf.readShort();
this.za = friendlyByteBuf.readShort();
}
(21w11a)
public ClientboundAddEntityPacket(FriendlyByteBuf friendlyByteBuf) {
this.id = friendlyByteBuf.readVarInt();
this.uuid = friendlyByteBuf.readUUID();
this.type = (EntityType) Registry.ENTITY_TYPE.byId(friendlyByteBuf.readVarInt());
this.x = friendlyByteBuf.readDouble();
this.y = friendlyByteBuf.readDouble();
this.z = friendlyByteBuf.readDouble();
this.xRot = friendlyByteBuf.readByte();
this.yRot = friendlyByteBuf.readByte();
this.data = friendlyByteBuf.readInt();
this.xa = friendlyByteBuf.readShort();
this.ya = friendlyByteBuf.readShort();
this.za = friendlyByteBuf.readShort();
}
可以看到,在21w08a后構(gòu)造函數(shù)和read方法就整合到一起了,這也許代表了MC網(wǎng)絡(luò)系統(tǒng)即將優(yōu)化?(也許想多了)

代碼源:21w11a,以Mojang Name反混淆
反混淆器:MCDynamicExchanger(beta6)
[項(xiàng)目地址 https://github.com/Nickid2018/MCDynamicExchanger]
如果專(zhuān)欄中有問(wèn)題,歡迎在評(píng)論區(qū)指出。