diff --git a/api/src/main/java/com/viaversion/viaversion/api/data/MappingData.java b/api/src/main/java/com/viaversion/viaversion/api/data/MappingData.java index e27a963e6..f813f5d68 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/data/MappingData.java +++ b/api/src/main/java/com/viaversion/viaversion/api/data/MappingData.java @@ -95,6 +95,8 @@ public interface MappingData { @Nullable Mappings getBlockMappings(); + @Nullable Mappings getBlockEntityMappings(); + @Nullable Mappings getBlockStateMappings(); @Nullable Mappings getSoundMappings(); diff --git a/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataBase.java b/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataBase.java index d7bad562f..98a85e6d5 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataBase.java +++ b/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataBase.java @@ -47,6 +47,7 @@ public class MappingDataBase implements MappingData { protected ParticleMappings particleMappings; protected Mappings blockMappings; protected Mappings blockStateMappings; + protected Mappings blockEntityMappings; protected Mappings soundMappings; protected Mappings statisticsMappings; protected Map> tags; @@ -71,6 +72,7 @@ public class MappingDataBase implements MappingData { blockMappings = loadFromObject(oldMappings, newMappings, diffmapping, "blocks"); blockStateMappings = loadFromObject(oldMappings, newMappings, diffmapping, "blockstates"); + blockEntityMappings = loadFromArray(oldMappings, newMappings, diffmapping, "blockentities"); soundMappings = loadFromArray(oldMappings, newMappings, diffmapping, "sounds"); statisticsMappings = loadFromArray(oldMappings, newMappings, diffmapping, "statistics"); @@ -169,6 +171,11 @@ public class MappingDataBase implements MappingData { return blockMappings; } + @Override + public @Nullable Mappings getBlockEntityMappings() { + return blockEntityMappings; + } + @Override public @Nullable Mappings getBlockStateMappings() { return blockStateMappings; diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/version/ProtocolVersion.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/version/ProtocolVersion.java index 0a7c91cf3..ddc6dfa6b 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/protocol/version/ProtocolVersion.java +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/version/ProtocolVersion.java @@ -78,7 +78,7 @@ public class ProtocolVersion { public static final ProtocolVersion v1_16_4 = register(754, "1.16.4/5", new VersionRange("1.16", 4, 5)); public static final ProtocolVersion v1_17 = register(755, "1.17"); public static final ProtocolVersion v1_17_1 = register(756, "1.17.1"); - public static final ProtocolVersion v1_18 = register(757, 48, "1.18"); + public static final ProtocolVersion v1_18 = register(757, 41, "1.18"); public static final ProtocolVersion unknown = register(-1, "UNKNOWN"); public static ProtocolVersion register(int version, String name) { diff --git a/api/src/main/java/com/viaversion/viaversion/api/type/types/version/ChunkSectionType1_18.java b/api/src/main/java/com/viaversion/viaversion/api/type/types/version/ChunkSectionType1_18.java index 01c9f3fc4..8415b2004 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/type/types/version/ChunkSectionType1_18.java +++ b/api/src/main/java/com/viaversion/viaversion/api/type/types/version/ChunkSectionType1_18.java @@ -101,6 +101,13 @@ public class ChunkSectionType1_18 extends Type { } private void writePalette(final ByteBuf buffer, final DataPalette palette) { + // Make sure this works for 1.17 chunk sections //TODO ? + if (palette.size() == 0) { + buffer.writeByte(GLOBAL_PALETTE); + Type.VAR_INT.writePrimitive(buffer, 0); + return; + } + int bitsPerValue = 0; while (palette.size() > 1 << bitsPerValue) { bitsPerValue += 1; diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_18to1_17_1/BlockEntityIds.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_18to1_17_1/BlockEntityIds.java new file mode 100644 index 000000000..70cf47bf4 --- /dev/null +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_18to1_17_1/BlockEntityIds.java @@ -0,0 +1,53 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2016-2021 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.viaversion.viaversion.protocols.protocol1_18to1_17_1; + +import com.viaversion.viaversion.api.Via; + +import java.util.Arrays; + +public final class BlockEntityIds { + + private static final int[] IDS = new int[14]; + + static { + // Only fills the ids that actually have block entity update packets sent + Arrays.fill(IDS, -1); + IDS[1] = 8; // Spawner + IDS[2] = 21; // Command block + IDS[3] = 13; // Beacon + IDS[4] = 14; // Skull + IDS[5] = 24; // Conduit + IDS[6] = 18; // Banner + IDS[7] = 19; // Structure block + IDS[8] = 20; // End gateway + IDS[9] = 7; // Sign + IDS[11] = 23; // Bed + IDS[12] = 30; // Jigsaw + IDS[13] = 31; // Campfire + } + + public static int newId(final int id) { + final int newId; + if (id < 0 || id > IDS.length || (newId = IDS[id]) == -1) { + Via.getPlatform().getLogger().warning("Received out of bounds block entity id: " + id); + return -1; + } + return newId; + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_18to1_17_1/Protocol1_18To1_17_1.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_18to1_17_1/Protocol1_18To1_17_1.java index 9e9f22b38..823e07375 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_18to1_17_1/Protocol1_18To1_17_1.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_18to1_17_1/Protocol1_18To1_17_1.java @@ -18,24 +18,23 @@ package com.viaversion.viaversion.protocols.protocol1_18to1_17_1; import com.viaversion.viaversion.api.connection.UserConnection; -import com.viaversion.viaversion.api.data.MappingData; -import com.viaversion.viaversion.api.data.MappingDataBase; +import com.viaversion.viaversion.api.minecraft.RegistryType; import com.viaversion.viaversion.api.minecraft.entities.Entity1_17Types; import com.viaversion.viaversion.api.protocol.AbstractProtocol; -import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper; -import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.data.entity.EntityTrackerBase; import com.viaversion.viaversion.protocols.protocol1_17_1to1_17.ClientboundPackets1_17_1; import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.ServerboundPackets1_17; +import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.data.MappingData; import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.packets.EntityPackets; import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.packets.WorldPackets; import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.storage.ChunkLightStorage; import com.viaversion.viaversion.rewriter.EntityRewriter; import com.viaversion.viaversion.rewriter.SoundRewriter; +import com.viaversion.viaversion.rewriter.TagRewriter; public final class Protocol1_18To1_17_1 extends AbstractProtocol { - public static final MappingData MAPPINGS = new MappingDataBase("1.17", "1.18"); + public static final MappingData MAPPINGS = new MappingData(); private final EntityRewriter entityRewriter = new EntityPackets(this); public Protocol1_18To1_17_1() { @@ -45,13 +44,9 @@ public final class Protocol1_18To1_17_1 extends AbstractProtocol. + */ +package com.viaversion.viaversion.protocols.protocol1_18to1_17_1.data; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.viaversion.viaversion.api.data.MappingDataBase; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import org.checkerframework.checker.nullness.qual.Nullable; + +public final class MappingData extends MappingDataBase { + + private final Object2IntMap blockEntityIds = new Object2IntOpenHashMap<>(); + + public MappingData() { + super("1.17", "1.18"); + blockEntityIds.defaultReturnValue(-1); + } + + @Override + protected void loadExtras(final JsonObject oldMappings, final JsonObject newMappings, @Nullable final JsonObject diffMappings) { + int i = 0; + for (final JsonElement element : newMappings.getAsJsonArray("blockentities")) { + final String id = element.getAsString(); + blockEntityIds.put(id, i++); + } + } + + public Object2IntMap blockEntityIds() { + return blockEntityIds; + } +} diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_18to1_17_1/packets/WorldPackets.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_18to1_17_1/packets/WorldPackets.java index 4f210287c..862faf909 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_18to1_17_1/packets/WorldPackets.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_18to1_17_1/packets/WorldPackets.java @@ -19,19 +19,26 @@ package com.viaversion.viaversion.protocols.protocol1_18to1_17_1.packets; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.NumberTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.data.entity.EntityTracker; import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity; import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntityImpl; import com.viaversion.viaversion.api.minecraft.chunks.Chunk; import com.viaversion.viaversion.api.minecraft.chunks.Chunk1_18; +import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; +import com.viaversion.viaversion.api.minecraft.chunks.ChunkSectionImpl; +import com.viaversion.viaversion.api.minecraft.chunks.DataPaletteImpl; +import com.viaversion.viaversion.api.minecraft.chunks.PaletteType; import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper; import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.protocols.protocol1_17_1to1_17.ClientboundPackets1_17_1; import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.types.Chunk1_17Type; +import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.BlockEntityIds; import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.Protocol1_18To1_17_1; import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.storage.ChunkLightStorage; import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.types.Chunk1_18Type; +import org.checkerframework.checker.nullness.qual.Nullable; import java.util.ArrayList; import java.util.List; @@ -39,6 +46,17 @@ import java.util.List; public final class WorldPackets { public static void register(final Protocol1_18To1_17_1 protocol) { + protocol.registerClientbound(ClientboundPackets1_17_1.BLOCK_ENTITY_DATA, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.POSITION1_14); + handler(wrapper -> { + final short id = wrapper.read(Type.UNSIGNED_BYTE); + wrapper.write(Type.VAR_INT, BlockEntityIds.newId(id)); + }); + } + }); + protocol.registerClientbound(ClientboundPackets1_17_1.UPDATE_LIGHT, new PacketRemapper() { @Override public void registerMap() { @@ -83,7 +101,7 @@ public final class WorldPackets { public void registerMap() { handler(wrapper -> { final EntityTracker tracker = protocol.getEntityRewriter().tracker(wrapper.user()); - Chunk chunk = wrapper.read(new Chunk1_17Type(tracker.currentWorldSectionHeight())); + final Chunk oldChunk = wrapper.read(new Chunk1_17Type(tracker.currentWorldSectionHeight())); /*for (int s = 0; s < chunk.getSections().length; s++) { ChunkSection section = chunk.getSections()[s]; if (section == null) continue; @@ -93,16 +111,50 @@ public final class WorldPackets { } }*/ - final List blockEntities = new ArrayList<>(chunk.getBlockEntities().size()); - for (final CompoundTag tag : chunk.getBlockEntities()) { + final List blockEntities = new ArrayList<>(oldChunk.getBlockEntities().size()); + for (final CompoundTag tag : oldChunk.getBlockEntities()) { final int x = ((NumberTag) tag.get("x")).asInt(); final int z = ((NumberTag) tag.get("z")).asInt(); + final byte packedXZ = (byte) ((x & 15) << 4 | (z & 15)); + final short y = ((NumberTag) tag.get("y")).asShort(); - final int typeId; //TODO :smolBoi: - blockEntities.add(new BlockEntityImpl((x & 15) << 4 | (z & 15), y, typeId, tag)); + final String id = ((StringTag) tag.get("id")).getValue(); + final int typeId = protocol.getMappingData().blockEntityIds().getInt(id.replace("minecraft:", "")); + if (typeId == -1) { + Via.getPlatform().getLogger().warning("Unknown block entity: " + id); + } + + blockEntities.add(new BlockEntityImpl(packedXZ, y, typeId, tag)); } - chunk = new Chunk1_18(chunk.getX(), chunk.getZ(), chunk.getSections(), chunk.getHeightMap(), blockEntities); + final int[] biomeData = oldChunk.getBiomeData(); + final ChunkSection[] sections = oldChunk.getSections(); + for (int i = 0; i < sections.length; i++) { + final ChunkSection section = sections[i]; + if (section == null) { + // There's no section mask anymore + final ChunkSectionImpl emptySection = new ChunkSectionImpl(false); + sections[i] = emptySection; + emptySection.setNonAirBlocksCount(0); + emptySection.addPalette(new DataPaletteImpl(PaletteType.BIOMES)); + continue; + } + + // Fill biome palette + final DataPaletteImpl biomePalette = new DataPaletteImpl(PaletteType.BIOMES); + //TODO + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + biomePalette.setValue(x, y, z, 0); + } + } + } + //TODO + section.addPalette(biomePalette); + } + + final Chunk chunk = new Chunk1_18(oldChunk.getX(), oldChunk.getZ(), oldChunk.getSections(), oldChunk.getHeightMap(), blockEntities); wrapper.write(new Chunk1_18Type(tracker.currentWorldSectionHeight()), chunk); // Get and remove light stored, there's only full chunk packets //TODO Only get, not remove if we find out people re-send full chunk packets without re-sending light @@ -114,6 +166,8 @@ public final class WorldPackets { return; } + lightStorage.addLoadedChunk(chunk.getX(), chunk.getZ()); + // Append light data to chunk packet wrapper.write(Type.BOOLEAN, light.trustEdges()); wrapper.write(Type.LONG_ARRAY_PRIMITIVE, light.skyLightMask()); diff --git a/common/src/main/resources/assets/viaversion/data/mapping-1.18.json b/common/src/main/resources/assets/viaversion/data/mapping-1.18.json index f5f884d52..a6c354b77 100644 --- a/common/src/main/resources/assets/viaversion/data/mapping-1.18.json +++ b/common/src/main/resources/assets/viaversion/data/mapping-1.18.json @@ -23630,5 +23630,41 @@ "wax_off", "electric_spark", "scrape" + ], + "blockentities": [ + "furnace", + "chest", + "trapped_chest", + "ender_chest", + "jukebox", + "dispenser", + "dropper", + "sign", + "mob_spawner", + "piston", + "brewing_stand", + "enchanting_table", + "end_portal", + "beacon", + "skull", + "daylight_detector", + "hopper", + "comparator", + "banner", + "structure_block", + "end_gateway", + "command_block", + "shulker_box", + "bed", + "conduit", + "barrel", + "smoker", + "blast_furnace", + "lectern", + "bell", + "jigsaw", + "campfire", + "beehive", + "sculk_sensor" ] } \ No newline at end of file