Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-08 17:20:20 +01:00
Actually fix signs and start on campfire/container translators
Since signs are not sent as block (tile) entities in chunks when it comes to later Minecraft versions, caching and sending the signs after the chunk packet has been sent was the only way to fix this. Sign data sending has intentionally been delayed in JavaUpdateTileEntityTranslator in the event that a chunk takes a long time to send and the block entity data is sent first.
Dieser Commit ist enthalten in:
Ursprung
e1ba1fa3e8
Commit
da8bd8a659
@ -46,6 +46,7 @@ import lombok.Getter;
|
||||
import org.geysermc.connector.network.translators.bedrock.*;
|
||||
import org.geysermc.connector.network.translators.block.BlockTranslator;
|
||||
import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator;
|
||||
import org.geysermc.connector.network.translators.block.entity.ContainerBlockEntityTranslator;
|
||||
import org.geysermc.connector.network.translators.block.entity.EmptyBlockEntityTranslator;
|
||||
import org.geysermc.connector.network.translators.block.entity.SignBlockEntityTranslator;
|
||||
import org.geysermc.connector.network.translators.inventory.GenericInventoryTranslator;
|
||||
@ -174,8 +175,9 @@ public class TranslatorsInit {
|
||||
}
|
||||
|
||||
private static void registerBlockEntityTranslators() {
|
||||
blockEntityTranslators.put("Empty", new EmptyBlockEntityTranslator());
|
||||
blockEntityTranslators.put("Sign", new SignBlockEntityTranslator());
|
||||
blockEntityTranslators.put("Empty", new EmptyBlockEntityTranslator("empty", "Empty"));
|
||||
blockEntityTranslators.put("Sign", new SignBlockEntityTranslator("minecraft:sign", "Sign"));
|
||||
blockEntityTranslators.put("Campfire", new ContainerBlockEntityTranslator("minecraft:campfire", "Campfire"));
|
||||
}
|
||||
|
||||
private static void registerInventoryTranslators() {
|
||||
|
@ -30,43 +30,48 @@ import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.nukkitx.nbt.CompoundTagBuilder;
|
||||
import com.nukkitx.nbt.tag.Tag;
|
||||
import org.geysermc.connector.utils.BlockEntityUtils;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@AllArgsConstructor
|
||||
public abstract class BlockEntityTranslator {
|
||||
|
||||
protected String javaId;
|
||||
protected String bedrockId;
|
||||
|
||||
public abstract List<Tag<?>> translateTag(CompoundTag tag);
|
||||
|
||||
public abstract CompoundTag getDefaultJavaTag(int x, int y, int z);
|
||||
|
||||
public abstract com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z);
|
||||
|
||||
public com.nukkitx.nbt.tag.CompoundTag getBlockEntityTag(CompoundTag tag, String id) {
|
||||
public com.nukkitx.nbt.tag.CompoundTag getBlockEntityTag(CompoundTag tag) {
|
||||
int x = Integer.parseInt(String.valueOf(tag.getValue().get("x").getValue()));
|
||||
int y = Integer.parseInt(String.valueOf(tag.getValue().get("y").getValue()));
|
||||
int z = Integer.parseInt(String.valueOf(tag.getValue().get("z").getValue()));
|
||||
|
||||
CompoundTagBuilder tagBuilder = getConstantBedrockTag(id, x, y, z).toBuilder();
|
||||
CompoundTagBuilder tagBuilder = getConstantBedrockTag(x, y, z).toBuilder();
|
||||
translateTag(tag).forEach(tagBuilder::tag);
|
||||
return tagBuilder.buildRootTag();
|
||||
}
|
||||
|
||||
protected CompoundTag getConstantJavaTag(String id, int x, int y, int z) {
|
||||
protected CompoundTag getConstantJavaTag(int x, int y, int z) {
|
||||
CompoundTag tag = new CompoundTag("");
|
||||
tag.put(new IntTag("x", x));
|
||||
tag.put(new IntTag("y", y));
|
||||
tag.put(new IntTag("z", z));
|
||||
tag.put(new StringTag("id", id));
|
||||
tag.put(new StringTag("id", javaId));
|
||||
return tag;
|
||||
}
|
||||
|
||||
protected com.nukkitx.nbt.tag.CompoundTag getConstantBedrockTag(String id, int x, int y, int z) {
|
||||
protected com.nukkitx.nbt.tag.CompoundTag getConstantBedrockTag(int x, int y, int z) {
|
||||
CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder()
|
||||
.intTag("x", x)
|
||||
.intTag("y", y)
|
||||
.intTag("z", z)
|
||||
.stringTag("id", id);
|
||||
.stringTag("id", bedrockId);
|
||||
return tagBuilder.buildRootTag();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2019 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.connector.network.translators.block.entity;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||
import com.nukkitx.nbt.CompoundTagBuilder;
|
||||
import com.nukkitx.nbt.tag.IntArrayTag;
|
||||
import com.nukkitx.nbt.tag.Tag;
|
||||
|
||||
import org.geysermc.connector.network.translators.TranslatorsInit;
|
||||
import org.geysermc.connector.network.translators.item.ItemEntry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class ContainerBlockEntityTranslator extends BlockEntityTranslator {
|
||||
|
||||
public ContainerBlockEntityTranslator(String javaId, String bedrockId) {
|
||||
super(javaId, bedrockId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Tag<?>> translateTag(CompoundTag tag) {
|
||||
List<Tag<?>> tags = new ArrayList<>();
|
||||
ListTag items = tag.get("Items");
|
||||
List<com.nukkitx.nbt.tag.CompoundTag> tagsList = new ArrayList<>();
|
||||
for (com.github.steveice10.opennbt.tag.builtin.Tag itemTag : items.getValue()) {
|
||||
tagsList.add(getItem((CompoundTag) itemTag));
|
||||
}
|
||||
|
||||
int[] fakeCookingTime = new int[4];
|
||||
Arrays.fill(fakeCookingTime, 3);
|
||||
|
||||
com.nukkitx.nbt.tag.ListTag<com.nukkitx.nbt.tag.CompoundTag> bedrockItems =
|
||||
new com.nukkitx.nbt.tag.ListTag<>("Items", com.nukkitx.nbt.tag.CompoundTag.class, tagsList);
|
||||
tags.add(bedrockItems);
|
||||
|
||||
tags.add(new IntArrayTag("CookingTimes", fakeCookingTime));
|
||||
tags.add(new IntArrayTag("CookingTotalTimes", fakeCookingTime));
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getDefaultJavaTag(int x, int y, int z) {
|
||||
CompoundTag tag = getConstantJavaTag(x, y, z);
|
||||
tag.put(new ListTag("Items"));
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) {
|
||||
CompoundTagBuilder tagBuilder = getConstantBedrockTag(x, y, z).toBuilder();
|
||||
tagBuilder.listTag("Items", com.nukkitx.nbt.tag.CompoundTag.class, new ArrayList<>());
|
||||
return tagBuilder.buildRootTag();
|
||||
}
|
||||
|
||||
protected com.nukkitx.nbt.tag.CompoundTag getItem(CompoundTag tag) {
|
||||
ItemEntry entry = TranslatorsInit.getItemTranslator().getItemEntry((String) tag.get("id").getValue());
|
||||
CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder()
|
||||
.shortTag("id", (short) entry.getBedrockId())
|
||||
.byteTag("Count", (byte) tag.get("Count").getValue())
|
||||
.shortTag("Damage", (short) entry.getBedrockData())
|
||||
.byteTag("Slot", (byte) tag.get("Slot").getValue())
|
||||
.tag(CompoundTagBuilder.builder().build("tag"));
|
||||
return tagBuilder.buildRootTag();
|
||||
}
|
||||
}
|
@ -33,6 +33,10 @@ import java.util.List;
|
||||
|
||||
public class EmptyBlockEntityTranslator extends BlockEntityTranslator {
|
||||
|
||||
public EmptyBlockEntityTranslator(String javaId, String bedrockId) {
|
||||
super(javaId, bedrockId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Tag<?>> translateTag(CompoundTag tag) {
|
||||
return new ArrayList<>();
|
||||
@ -40,11 +44,11 @@ public class EmptyBlockEntityTranslator extends BlockEntityTranslator {
|
||||
|
||||
@Override
|
||||
public CompoundTag getDefaultJavaTag(int x, int y, int z) {
|
||||
return getConstantJavaTag("empty", x, y, z);
|
||||
return getConstantJavaTag(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) {
|
||||
return getConstantBedrockTag("Empty", x, y, z);
|
||||
return getConstantBedrockTag(x, y, z);
|
||||
}
|
||||
}
|
||||
|
@ -28,9 +28,9 @@ package org.geysermc.connector.network.translators.block.entity;
|
||||
import com.github.steveice10.mc.protocol.data.message.Message;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.nukkitx.nbt.CompoundTagBuilder;
|
||||
import com.nukkitx.nbt.tag.ByteTag;
|
||||
import com.nukkitx.nbt.tag.StringTag;
|
||||
import com.nukkitx.nbt.tag.Tag;
|
||||
|
||||
import org.geysermc.connector.utils.MessageUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -38,6 +38,10 @@ import java.util.List;
|
||||
|
||||
public class SignBlockEntityTranslator extends BlockEntityTranslator {
|
||||
|
||||
public SignBlockEntityTranslator(String javaId, String bedrockId) {
|
||||
super(javaId, bedrockId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Tag<?>> translateTag(CompoundTag tag) {
|
||||
List<Tag<?>> tags = new ArrayList<>();
|
||||
@ -53,13 +57,12 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator {
|
||||
+ "\n" + MessageUtils.getBedrockMessage(Message.fromString(line4))
|
||||
));
|
||||
|
||||
tags.add(new ByteTag("isMovable", (byte) 0));
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getDefaultJavaTag(int x, int y, int z) {
|
||||
CompoundTag tag = getConstantJavaTag("minecraft:sign", x, y, z);
|
||||
CompoundTag tag = getConstantJavaTag(x, y, z);
|
||||
tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text1", "{\"text\":\"\"}"));
|
||||
tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text2", "{\"text\":\"\"}"));
|
||||
tag.put(new com.github.steveice10.opennbt.tag.builtin.StringTag("Text3", "{\"text\":\"\"}"));
|
||||
@ -69,9 +72,8 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator {
|
||||
|
||||
@Override
|
||||
public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(int x, int y, int z) {
|
||||
CompoundTagBuilder tagBuilder = getConstantBedrockTag("Sign", x, y, z).toBuilder();
|
||||
CompoundTagBuilder tagBuilder = getConstantBedrockTag(x, y, z).toBuilder();
|
||||
tagBuilder.stringTag("Text", "");
|
||||
tagBuilder.byteTag("isMovable", (byte) 0);
|
||||
return tagBuilder.buildRootTag();
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ import com.github.steveice10.opennbt.tag.builtin.ShortTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.nukkitx.protocol.bedrock.data.ItemData;
|
||||
|
||||
import org.geysermc.connector.console.GeyserLogger;
|
||||
import org.geysermc.connector.utils.MessageUtils;
|
||||
import org.geysermc.connector.utils.Toolbox;
|
||||
@ -52,6 +53,8 @@ import java.util.Map;
|
||||
|
||||
public class ItemTranslator {
|
||||
|
||||
private Map<String, ItemEntry> javaIdentifierMap = new HashMap<>();
|
||||
|
||||
public ItemStack translateToJava(ItemData data) {
|
||||
ItemEntry javaItem = getItem(data);
|
||||
|
||||
@ -89,6 +92,11 @@ public class ItemTranslator {
|
||||
return ItemEntry.AIR;
|
||||
}
|
||||
|
||||
public ItemEntry getItemEntry(String javaIdentifier) {
|
||||
return javaIdentifierMap.computeIfAbsent(javaIdentifier, key -> Toolbox.ITEM_ENTRIES.values()
|
||||
.stream().filter(itemEntry -> itemEntry.getJavaIdentifier().equals(key)).findFirst().orElse(null));
|
||||
}
|
||||
|
||||
private CompoundTag translateToJavaNBT(com.nukkitx.nbt.tag.CompoundTag tag) {
|
||||
CompoundTag javaTag = new CompoundTag(tag.getName());
|
||||
Map<String, Tag> javaValue = javaTag.getValue();
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.geysermc.connector.network.translators.java.world;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerChunkDataPacket;
|
||||
import com.nukkitx.math.vector.Vector2i;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
@ -9,9 +11,13 @@ import com.nukkitx.nbt.tag.CompoundTag;
|
||||
import com.nukkitx.network.VarInts;
|
||||
import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
|
||||
import org.geysermc.api.Geyser;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
@ -22,7 +28,6 @@ public class JavaChunkDataTranslator extends PacketTranslator<ServerChunkDataPac
|
||||
|
||||
@Override
|
||||
public void translate(ServerChunkDataPacket packet, GeyserSession session) {
|
||||
// Not sure if this is safe or not, however without this the client usually times out
|
||||
Geyser.getConnector().getGeneralThreadPool().execute(() -> {
|
||||
Vector2i chunkPos = session.getLastChunkPosition();
|
||||
Vector3f position = session.getPlayerEntity().getPosition();
|
||||
@ -33,7 +38,6 @@ public class JavaChunkDataTranslator extends PacketTranslator<ServerChunkDataPac
|
||||
chunkPublisherUpdatePacket.setPosition(position.toInt());
|
||||
chunkPublisherUpdatePacket.setRadius(session.getRenderDistance() << 4);
|
||||
session.getUpstream().sendPacket(chunkPublisherUpdatePacket);
|
||||
|
||||
session.setLastChunkPosition(newChunkPos);
|
||||
}
|
||||
|
||||
@ -75,6 +79,16 @@ public class JavaChunkDataTranslator extends PacketTranslator<ServerChunkDataPac
|
||||
levelChunkPacket.setChunkZ(packet.getColumn().getZ());
|
||||
levelChunkPacket.setData(payload);
|
||||
session.getUpstream().sendPacket(levelChunkPacket);
|
||||
|
||||
// Signs have to be sent after the chunk since in later versions they aren't included in the block entities
|
||||
for (Int2ObjectMap.Entry<CompoundTag> blockEntityEntry : chunkData.signs.int2ObjectEntrySet()) {
|
||||
int x = blockEntityEntry.getValue().getAsInt("x");
|
||||
int y = blockEntityEntry.getValue().getAsInt("y");
|
||||
int z = blockEntityEntry.getValue().getAsInt("z");
|
||||
|
||||
ChunkUtils.updateBlock(session, new BlockState(blockEntityEntry.getIntKey()), new Position(x, y, z));
|
||||
}
|
||||
chunkData.signs.clear();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
@ -26,26 +26,29 @@
|
||||
package org.geysermc.connector.network.translators.java.world;
|
||||
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateTileEntityPacket;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket;
|
||||
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator;
|
||||
import org.geysermc.connector.utils.BlockEntityUtils;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class JavaUpdateTileEntityTranslator extends PacketTranslator<ServerUpdateTileEntityPacket> {
|
||||
|
||||
@Override
|
||||
public void translate(ServerUpdateTileEntityPacket packet, GeyserSession session) {
|
||||
BlockEntityDataPacket blockEntityPacket = new BlockEntityDataPacket();
|
||||
blockEntityPacket.setBlockPosition(Vector3i.from(packet.getPosition().getX(),
|
||||
packet.getPosition().getY(),
|
||||
packet.getPosition().getZ())
|
||||
);
|
||||
|
||||
String id = BlockEntityUtils.getBedrockBlockEntityId(packet.getType().name());
|
||||
BlockEntityTranslator translator = BlockEntityUtils.getBlockEntityTranslator(id);
|
||||
blockEntityPacket.setData(translator.getBlockEntityTag(packet.getNbt(), id));
|
||||
session.getUpstream().sendPacket(blockEntityPacket);
|
||||
if (id.equalsIgnoreCase("Sign")) {
|
||||
// Delay so chunks can finish sending
|
||||
session.getConnector().getGeneralThreadPool().schedule(() ->
|
||||
BlockEntityUtils.updateBlockEntity(session, translator.getBlockEntityTag(packet.getNbt()), packet.getPosition()),
|
||||
5,
|
||||
TimeUnit.SECONDS
|
||||
);
|
||||
} else {
|
||||
BlockEntityUtils.updateBlockEntity(session, translator.getBlockEntityTag(packet.getNbt()), packet.getPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
package org.geysermc.connector.utils;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket;
|
||||
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.TranslatorsInit;
|
||||
import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator;
|
||||
|
||||
@ -10,8 +15,9 @@ public class BlockEntityUtils {
|
||||
if (id.contains("piston_head"))
|
||||
return "PistonArm";
|
||||
|
||||
id = id.replace("minecraft:", "");
|
||||
id = id.replace("_", " ");
|
||||
id = id.toLowerCase()
|
||||
.replace("minecraft:", "")
|
||||
.replace("_", " ");
|
||||
String[] words = id.split(" ");
|
||||
for (int i = 0; i < words.length; i++) {
|
||||
words[i] = words[i].substring(0, 1).toUpperCase() + words[i].substring(1).toLowerCase();
|
||||
@ -29,4 +35,11 @@ public class BlockEntityUtils {
|
||||
|
||||
return blockEntityTranslator;
|
||||
}
|
||||
|
||||
public static void updateBlockEntity(GeyserSession session, com.nukkitx.nbt.tag.CompoundTag blockEntity, Position position) {
|
||||
BlockEntityDataPacket blockEntityPacket = new BlockEntityDataPacket();
|
||||
blockEntityPacket.setBlockPosition(Vector3i.from(position.getX(), position.getY(), position.getZ()));
|
||||
blockEntityPacket.setData(blockEntity);
|
||||
session.getUpstream().sendPacket(blockEntityPacket);
|
||||
}
|
||||
}
|
||||
|
@ -3,35 +3,31 @@ package org.geysermc.connector.utils;
|
||||
import com.github.steveice10.mc.protocol.data.game.chunk.Chunk;
|
||||
import com.github.steveice10.mc.protocol.data.game.chunk.Column;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||
import com.github.steveice10.mc.protocol.data.game.world.block.BlockChangeRecord;
|
||||
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import org.geysermc.connector.console.GeyserLogger;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
import org.geysermc.connector.console.GeyserLogger;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.TranslatorsInit;
|
||||
import org.geysermc.connector.network.translators.block.BlockEntry;
|
||||
import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator;
|
||||
import org.geysermc.connector.network.translators.block.entity.SignBlockEntityTranslator;
|
||||
import org.geysermc.connector.world.chunk.ChunkPosition;
|
||||
import org.geysermc.connector.world.chunk.ChunkSection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class ChunkUtils {
|
||||
|
||||
public static ChunkData translateToBedrock(Column column) {
|
||||
ChunkData chunkData = new ChunkData();
|
||||
|
||||
Chunk[] chunks = column.getChunks();
|
||||
int chunkSectionCount = chunks.length;
|
||||
chunkData.sections = new ChunkSection[chunkSectionCount];
|
||||
chunkData.sections = new ChunkSection[chunks.length];
|
||||
|
||||
List<CompoundTag> blockEntities = new ArrayList<>(Arrays.asList(column.getTileEntities()));
|
||||
for (int chunkY = 0; chunkY < chunkSectionCount; chunkY++) {
|
||||
CompoundTag[] blockEntities = column.getTileEntities();
|
||||
for (int chunkY = 0; chunkY < chunks.length; chunkY++) {
|
||||
chunkData.sections[chunkY] = new ChunkSection();
|
||||
Chunk chunk = chunks[chunkY];
|
||||
|
||||
@ -39,15 +35,17 @@ public class ChunkUtils {
|
||||
continue;
|
||||
|
||||
ChunkSection section = chunkData.sections[chunkY];
|
||||
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
BlockState blockState = chunk.get(x, y, z);
|
||||
BlockEntry block = TranslatorsInit.getBlockTranslator().getBlockEntry(blockState);
|
||||
|
||||
section.getBlockStorageArray()[0].setFullBlock(ChunkSection.blockPosition(x, y, z),
|
||||
block.getBedrockRuntimeId());
|
||||
if (block.getJavaIdentifier().contains("sign[")) {
|
||||
Position pos = new ChunkPosition(column.getX(), column.getZ()).getBlock(x, (chunkY << 4) + y, z);
|
||||
chunkData.signs.put(block.getJavaId(), TranslatorsInit.getBlockEntityTranslators().get("Sign").getDefaultBedrockTag(pos.getX(), pos.getY(), pos.getZ()));
|
||||
} else {
|
||||
section.getBlockStorageArray()[0].setFullBlock(ChunkSection.blockPosition(x, y, z), block.getBedrockRuntimeId());
|
||||
}
|
||||
|
||||
if (block.isWaterlogged()) {
|
||||
BlockEntry water = TranslatorsInit.getBlockTranslator().getBlockEntry("minecraft:water[level=0]");
|
||||
@ -58,17 +56,20 @@ public class ChunkUtils {
|
||||
}
|
||||
}
|
||||
|
||||
List<com.nukkitx.nbt.tag.CompoundTag> bedrockBlockEntities = new ArrayList<>();
|
||||
for (CompoundTag tag : blockEntities) {
|
||||
Tag idTag = tag.get("id");
|
||||
if (idTag == null && !tag.contains("Sign")) {
|
||||
com.nukkitx.nbt.tag.CompoundTag[] bedrockBlockEntities = new com.nukkitx.nbt.tag.CompoundTag[blockEntities.length];
|
||||
for (int i = 0; i < bedrockBlockEntities.length; i++) {
|
||||
CompoundTag tag = blockEntities[i];
|
||||
String tagName;
|
||||
if (!tag.contains("id")) {
|
||||
GeyserLogger.DEFAULT.debug("Got tag with no id: " + tag.getValue());
|
||||
continue;
|
||||
tagName = "Empty";
|
||||
} else {
|
||||
tagName = (String) tag.get("id").getValue();
|
||||
}
|
||||
|
||||
String id = idTag == null ? "Sign" : BlockEntityUtils.getBedrockBlockEntityId((String) idTag.getValue());
|
||||
String id = BlockEntityUtils.getBedrockBlockEntityId(tagName);
|
||||
BlockEntityTranslator blockEntityTranslator = BlockEntityUtils.getBlockEntityTranslator(id);
|
||||
bedrockBlockEntities.add(blockEntityTranslator.getBlockEntityTag(tag, id));
|
||||
bedrockBlockEntities[i] = blockEntityTranslator.getBlockEntityTag(tag);
|
||||
}
|
||||
|
||||
chunkData.blockEntities = bedrockBlockEntities;
|
||||
@ -102,6 +103,8 @@ public class ChunkUtils {
|
||||
public ChunkSection[] sections;
|
||||
|
||||
public byte[] biomes = new byte[256];
|
||||
public List<com.nukkitx.nbt.tag.CompoundTag> blockEntities = new ArrayList<>();
|
||||
public com.nukkitx.nbt.tag.CompoundTag[] blockEntities = new com.nukkitx.nbt.tag.CompoundTag[0];
|
||||
|
||||
public Int2ObjectMap<com.nukkitx.nbt.tag.CompoundTag> signs = new Int2ObjectOpenHashMap<>();
|
||||
}
|
||||
}
|
||||
|
@ -18,17 +18,9 @@ public class ChunkPosition {
|
||||
}
|
||||
|
||||
public Position getChunkBlock(int x, int y, int z) {
|
||||
int chunkX = x % 16;
|
||||
int chunkY = y % 16;
|
||||
int chunkZ = z % 16;
|
||||
|
||||
if (chunkX < 0)
|
||||
chunkX = -chunkX;
|
||||
if (chunkY < 0)
|
||||
chunkY = -chunkY;
|
||||
if (chunkZ < 0)
|
||||
chunkZ = -chunkZ;
|
||||
|
||||
int chunkX = x & 15;
|
||||
int chunkY = y & 15;
|
||||
int chunkZ = z & 15;
|
||||
return new Position(chunkX, chunkY, chunkZ);
|
||||
}
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren