mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Merge branch 'master' into feature/extensions
This commit is contained in:
commit
4ae9bdf4b9
11 changed files with 71 additions and 64 deletions
|
@ -17,7 +17,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t
|
||||||
|
|
||||||
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here!
|
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here!
|
||||||
|
|
||||||
### Currently supporting Minecraft Bedrock 1.18.0 - 1.18.30 and Minecraft Java 1.18.2.
|
### Currently supporting Minecraft Bedrock 1.18.0 - 1.18.31 and Minecraft Java 1.18.2.
|
||||||
|
|
||||||
## Setting Up
|
## Setting Up
|
||||||
Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser.
|
Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser.
|
||||||
|
|
|
@ -66,6 +66,8 @@ public class DumpInfo {
|
||||||
|
|
||||||
private final DumpInfo.VersionInfo versionInfo;
|
private final DumpInfo.VersionInfo versionInfo;
|
||||||
private final int cpuCount;
|
private final int cpuCount;
|
||||||
|
private final Locale systemLocale;
|
||||||
|
private final String systemEncoding;
|
||||||
private Properties gitInfo;
|
private Properties gitInfo;
|
||||||
private final GeyserConfiguration config;
|
private final GeyserConfiguration config;
|
||||||
private final Floodgate floodgate;
|
private final Floodgate floodgate;
|
||||||
|
@ -81,6 +83,8 @@ public class DumpInfo {
|
||||||
this.versionInfo = new VersionInfo();
|
this.versionInfo = new VersionInfo();
|
||||||
|
|
||||||
this.cpuCount = Runtime.getRuntime().availableProcessors();
|
this.cpuCount = Runtime.getRuntime().availableProcessors();
|
||||||
|
this.systemLocale = Locale.getDefault();
|
||||||
|
this.systemEncoding = System.getProperty("file.encoding");
|
||||||
|
|
||||||
try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResource("git.properties")) {
|
try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResource("git.properties")) {
|
||||||
this.gitInfo = new Properties();
|
this.gitInfo = new Properties();
|
||||||
|
|
|
@ -51,6 +51,7 @@ public final class BlockStateValues {
|
||||||
private static final Int2ObjectMap<String> FLOWER_POT_VALUES = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<String> FLOWER_POT_VALUES = new Int2ObjectOpenHashMap<>();
|
||||||
private static final IntSet HORIZONTAL_FACING_JIGSAWS = new IntOpenHashSet();
|
private static final IntSet HORIZONTAL_FACING_JIGSAWS = new IntOpenHashSet();
|
||||||
private static final LecternHasBookMap LECTERN_BOOK_STATES = new LecternHasBookMap();
|
private static final LecternHasBookMap LECTERN_BOOK_STATES = new LecternHasBookMap();
|
||||||
|
private static final IntSet NON_WATER_CAULDRONS = new IntOpenHashSet();
|
||||||
private static final Int2IntMap NOTEBLOCK_PITCHES = new FixedInt2IntMap();
|
private static final Int2IntMap NOTEBLOCK_PITCHES = new FixedInt2IntMap();
|
||||||
private static final Int2BooleanMap PISTON_VALUES = new Int2BooleanOpenHashMap();
|
private static final Int2BooleanMap PISTON_VALUES = new Int2BooleanOpenHashMap();
|
||||||
private static final IntSet STICKY_PISTONS = new IntOpenHashSet();
|
private static final IntSet STICKY_PISTONS = new IntOpenHashSet();
|
||||||
|
@ -176,7 +177,7 @@ public final class BlockStateValues {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (javaId.startsWith("minecraft:water")) {
|
if (javaId.startsWith("minecraft:water") && !javaId.contains("cauldron")) {
|
||||||
String strLevel = javaId.substring(javaId.lastIndexOf("level=") + 6, javaId.length() - 1);
|
String strLevel = javaId.substring(javaId.lastIndexOf("level=") + 6, javaId.length() - 1);
|
||||||
int level = Integer.parseInt(strLevel);
|
int level = Integer.parseInt(strLevel);
|
||||||
WATER_LEVEL.put(javaBlockState, level);
|
WATER_LEVEL.put(javaBlockState, level);
|
||||||
|
@ -189,6 +190,11 @@ public final class BlockStateValues {
|
||||||
if (direction.isHorizontal()) {
|
if (direction.isHorizontal()) {
|
||||||
HORIZONTAL_FACING_JIGSAWS.add(javaBlockState);
|
HORIZONTAL_FACING_JIGSAWS.add(javaBlockState);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (javaId.contains("_cauldron") && !javaId.contains("water_")) {
|
||||||
|
NON_WATER_CAULDRONS.add(javaBlockState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +220,15 @@ public final class BlockStateValues {
|
||||||
return BED_COLORS.getOrDefault(state, (byte) -1);
|
return BED_COLORS.getOrDefault(state, (byte) -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Non-water cauldrons (since Bedrock 1.18.30) must have a block entity packet sent on chunk load to fix rendering issues.
|
||||||
|
*
|
||||||
|
* @return if this Java block state is a non-empty non-water cauldron
|
||||||
|
*/
|
||||||
|
public static boolean isCauldron(int state) {
|
||||||
|
return NON_WATER_CAULDRONS.contains(state);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The block state in Java and Bedrock both contain the conditional bit, however command block block entity tags
|
* The block state in Java and Bedrock both contain the conditional bit, however command block block entity tags
|
||||||
* in Bedrock need the conditional information.
|
* in Bedrock need the conditional information.
|
||||||
|
|
|
@ -62,7 +62,9 @@ public final class GameProtocol {
|
||||||
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v486.V486_CODEC.toBuilder()
|
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v486.V486_CODEC.toBuilder()
|
||||||
.minecraftVersion("1.18.10/1.18.12") // 1.18.11 is also supported, but was only on Switch and since that auto-updates it's not needed
|
.minecraftVersion("1.18.10/1.18.12") // 1.18.11 is also supported, but was only on Switch and since that auto-updates it's not needed
|
||||||
.build());
|
.build());
|
||||||
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC);
|
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder()
|
||||||
|
.minecraftVersion("1.18.30/1.18.31")
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -132,7 +132,6 @@ public class BlockRegistryPopulator {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new AssertionError("Unable to get blocks from runtime block states", e);
|
throw new AssertionError("Unable to get blocks from runtime block states", e);
|
||||||
}
|
}
|
||||||
Map<String, NbtMap> javaIdentifierToBedrockTag = new Object2ObjectOpenHashMap<>(blocksTag.size());
|
|
||||||
// New since 1.16.100 - find the block runtime ID by the order given to us in the block palette,
|
// New since 1.16.100 - find the block runtime ID by the order given to us in the block palette,
|
||||||
// as we no longer send a block palette
|
// as we no longer send a block palette
|
||||||
Object2IntMap<NbtMap> blockStateOrderedMap = new Object2IntOpenHashMap<>(blocksTag.size());
|
Object2IntMap<NbtMap> blockStateOrderedMap = new Object2IntOpenHashMap<>(blocksTag.size());
|
||||||
|
@ -202,10 +201,6 @@ public class BlockRegistryPopulator {
|
||||||
flowerPotBlocks.put(cleanJavaIdentifier.intern(), blocksTag.get(bedrockRuntimeId));
|
flowerPotBlocks.put(cleanJavaIdentifier.intern(), blocksTag.get(bedrockRuntimeId));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cleanJavaIdentifier.equals(entry.getValue().get("bedrock_identifier").asText())) {
|
|
||||||
javaIdentifierToBedrockTag.put(cleanJavaIdentifier.intern(), blocksTag.get(bedrockRuntimeId));
|
|
||||||
}
|
|
||||||
|
|
||||||
javaToBedrockBlocks[javaRuntimeId] = bedrockRuntimeId;
|
javaToBedrockBlocks[javaRuntimeId] = bedrockRuntimeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +235,6 @@ public class BlockRegistryPopulator {
|
||||||
|
|
||||||
BlockRegistries.BLOCKS.register(palette.getKey().valueInt(), builder.blockStateVersion(stateVersion)
|
BlockRegistries.BLOCKS.register(palette.getKey().valueInt(), builder.blockStateVersion(stateVersion)
|
||||||
.javaToBedrockBlocks(javaToBedrockBlocks)
|
.javaToBedrockBlocks(javaToBedrockBlocks)
|
||||||
.javaIdentifierToBedrockTag(javaIdentifierToBedrockTag)
|
|
||||||
.itemFrames(itemFrames)
|
.itemFrames(itemFrames)
|
||||||
.flowerPotBlocks(flowerPotBlocks)
|
.flowerPotBlocks(flowerPotBlocks)
|
||||||
.jigsawStateIds(jigsawStateIds)
|
.jigsawStateIds(jigsawStateIds)
|
||||||
|
|
|
@ -47,12 +47,6 @@ public class BlockMappings {
|
||||||
|
|
||||||
NbtList<NbtMap> bedrockBlockStates;
|
NbtList<NbtMap> bedrockBlockStates;
|
||||||
|
|
||||||
/**
|
|
||||||
* Contains a map of Java blocks to their respective Bedrock block tag, if the Java identifier is different from Bedrock.
|
|
||||||
* Required to fix villager trades with these blocks.
|
|
||||||
*/
|
|
||||||
Map<String, NbtMap> javaIdentifierToBedrockTag;
|
|
||||||
|
|
||||||
int commandBlockRuntimeId;
|
int commandBlockRuntimeId;
|
||||||
|
|
||||||
Object2IntMap<NbtMap> itemFrames;
|
Object2IntMap<NbtMap> itemFrames;
|
||||||
|
@ -74,13 +68,4 @@ public class BlockMappings {
|
||||||
public boolean isItemFrame(int bedrockBlockRuntimeId) {
|
public boolean isItemFrame(int bedrockBlockRuntimeId) {
|
||||||
return this.itemFrames.values().contains(bedrockBlockRuntimeId);
|
return this.itemFrames.values().contains(bedrockBlockRuntimeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param cleanJavaIdentifier the clean Java identifier of the block to look up
|
|
||||||
*
|
|
||||||
* @return the block tag of the block name mapped from Java to Bedrock.
|
|
||||||
*/
|
|
||||||
public NbtMap getBedrockBlockNbt(String cleanJavaIdentifier) {
|
|
||||||
return this.javaIdentifierToBedrockTag.get(cleanJavaIdentifier);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -126,11 +126,10 @@ public class BiomeTranslator {
|
||||||
storage = new BlockStorage(bitArray, bedrockPalette);
|
storage = new BlockStorage(bitArray, bedrockPalette);
|
||||||
} else {
|
} else {
|
||||||
storage = new BlockStorage(0);
|
storage = new BlockStorage(0);
|
||||||
BitArray bitArray = storage.getBitArray();
|
|
||||||
|
|
||||||
// Each section of biome corresponding to a chunk section contains 4 * 4 * 4 entries
|
// Each section of biome corresponding to a chunk section contains 4 * 4 * 4 entries
|
||||||
for (int i = 0; i < 64; i++) {
|
for (int i = 0; i < 64; i++) {
|
||||||
int javaId = biomeData.getPalette().idToState(biomeData.getStorage().get(i));
|
int javaId = palette.idToState(biomeData.getStorage().get(i));
|
||||||
int x = i & 3;
|
int x = i & 3;
|
||||||
int y = (i >> 4) & 3;
|
int y = (i >> 4) & 3;
|
||||||
int z = (i >> 2) & 3;
|
int z = (i >> 2) & 3;
|
||||||
|
@ -139,7 +138,9 @@ public class BiomeTranslator {
|
||||||
int idx = storage.idFor(biomeId);
|
int idx = storage.idFor(biomeId);
|
||||||
// Convert biome coordinates into block coordinates
|
// Convert biome coordinates into block coordinates
|
||||||
// Bedrock expects a full 4096 blocks
|
// Bedrock expects a full 4096 blocks
|
||||||
multiplyIdToStorage(bitArray, idx, x, y, z);
|
// Implementation note: storage.getBitArray() must be called and not stored - if the palette
|
||||||
|
// grows, then the instance can change
|
||||||
|
multiplyIdToStorage(storage.getBitArray(), idx, x, y, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return storage;
|
return storage;
|
||||||
|
|
|
@ -26,7 +26,10 @@
|
||||||
package org.geysermc.geyser.translator.level.block.entity;
|
package org.geysermc.geyser.translator.level.block.entity;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
|
import com.nukkitx.nbt.NbtList;
|
||||||
import com.nukkitx.nbt.NbtMap;
|
import com.nukkitx.nbt.NbtMap;
|
||||||
|
import com.nukkitx.nbt.NbtType;
|
||||||
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,6 +62,18 @@ public interface BedrockOnlyBlockEntity extends RequiresBlockState {
|
||||||
return FlowerPotBlockEntityTranslator.getTag(session, blockState, position);
|
return FlowerPotBlockEntityTranslator.getTag(session, blockState, position);
|
||||||
} else if (PistonBlockEntityTranslator.isBlock(blockState)) {
|
} else if (PistonBlockEntityTranslator.isBlock(blockState)) {
|
||||||
return PistonBlockEntityTranslator.getTag(blockState, position);
|
return PistonBlockEntityTranslator.getTag(blockState, position);
|
||||||
|
} else if (BlockStateValues.isCauldron(blockState)) {
|
||||||
|
// As of 1.18.30: this is required to make rendering not look weird on chunk load (lava and snow cauldrons look dim)
|
||||||
|
return NbtMap.builder()
|
||||||
|
.putString("id", "Cauldron")
|
||||||
|
.putByte("isMovable", (byte) 0)
|
||||||
|
.putShort("PotionId", (short) -1)
|
||||||
|
.putShort("PotionType", (short) -1)
|
||||||
|
.putList("Items", NbtType.END, NbtList.EMPTY)
|
||||||
|
.putInt("x", position.getX())
|
||||||
|
.putInt("y", position.getY())
|
||||||
|
.putInt("z", position.getZ())
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,12 +178,8 @@ public class JavaMerchantOffersTranslator extends PacketTranslator<ClientboundMe
|
||||||
builder.put("tag", tag);
|
builder.put("tag", tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
NbtMap blockTag = session.getBlockMappings().getBedrockBlockNbt(mapping.getJavaIdentifier());
|
// Implementation note: previously we added a block tag to fix some blocks (black concrete?) that wouldn't stack
|
||||||
if (blockTag != null) {
|
// after buying. This no longer seems to be an issue as of Bedrock 1.18.30, and including it breaks sugar canes.
|
||||||
// This fixes certain blocks being unable to stack after grabbing one
|
|
||||||
builder.putCompound("Block", blockTag);
|
|
||||||
builder.putShort("Damage", (short) 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||||
final List<NbtMap> bedrockBlockEntities = new ObjectArrayList<>(blockEntities.length);
|
final List<NbtMap> bedrockBlockEntities = new ObjectArrayList<>(blockEntities.length);
|
||||||
|
|
||||||
BitSet waterloggedPaletteIds = new BitSet();
|
BitSet waterloggedPaletteIds = new BitSet();
|
||||||
BitSet pistonOrFlowerPaletteIds = new BitSet();
|
BitSet bedrockOnlyBlockEntityIds = new BitSet();
|
||||||
|
|
||||||
BedrockDimension bedrockDimension = session.getChunkCache().getBedrockDimension();
|
BedrockDimension bedrockDimension = session.getChunkCache().getBedrockDimension();
|
||||||
int maxBedrockSectionY = (bedrockDimension.height() >> 4) - 1;
|
int maxBedrockSectionY = (bedrockDimension.height() >> 4) - 1;
|
||||||
|
@ -144,7 +144,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if block is piston or flower to see if we'll need to create additional block entities, as they're only block entities in Bedrock
|
// Check if block is piston or flower to see if we'll need to create additional block entities, as they're only block entities in Bedrock
|
||||||
if (BlockStateValues.getFlowerPotValues().containsKey(javaId) || BlockStateValues.getPistonValues().containsKey(javaId)) {
|
if (BlockStateValues.getFlowerPotValues().containsKey(javaId) || BlockStateValues.getPistonValues().containsKey(javaId) || BlockStateValues.isCauldron(javaId)) {
|
||||||
bedrockBlockEntities.add(BedrockOnlyBlockEntity.getTag(session,
|
bedrockBlockEntities.add(BedrockOnlyBlockEntity.getTag(session,
|
||||||
Vector3i.from((packet.getX() << 4) + (yzx & 0xF), ((sectionY + yOffset) << 4) + ((yzx >> 8) & 0xF), (packet.getZ() << 4) + ((yzx >> 4) & 0xF)),
|
Vector3i.from((packet.getX() << 4) + (yzx & 0xF), ((sectionY + yOffset) << 4) + ((yzx >> 8) & 0xF), (packet.getZ() << 4) + ((yzx >> 4) & 0xF)),
|
||||||
javaId
|
javaId
|
||||||
|
@ -173,7 +173,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||||
|
|
||||||
IntList bedrockPalette = new IntArrayList(javaPalette.size());
|
IntList bedrockPalette = new IntArrayList(javaPalette.size());
|
||||||
waterloggedPaletteIds.clear();
|
waterloggedPaletteIds.clear();
|
||||||
pistonOrFlowerPaletteIds.clear();
|
bedrockOnlyBlockEntityIds.clear();
|
||||||
|
|
||||||
// Iterate through palette and convert state IDs to Bedrock, doing some additional checks as we go
|
// Iterate through palette and convert state IDs to Bedrock, doing some additional checks as we go
|
||||||
for (int i = 0; i < javaPalette.size(); i++) {
|
for (int i = 0; i < javaPalette.size(); i++) {
|
||||||
|
@ -184,19 +184,19 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||||
waterloggedPaletteIds.set(i);
|
waterloggedPaletteIds.set(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if block is piston or flower to see if we'll need to create additional block entities, as they're only block entities in Bedrock
|
// Check if block is piston, flower or cauldron to see if we'll need to create additional block entities, as they're only block entities in Bedrock
|
||||||
if (BlockStateValues.getFlowerPotValues().containsKey(javaId) || BlockStateValues.getPistonValues().containsKey(javaId)) {
|
if (BlockStateValues.getFlowerPotValues().containsKey(javaId) || BlockStateValues.getPistonValues().containsKey(javaId) || BlockStateValues.isCauldron(javaId)) {
|
||||||
pistonOrFlowerPaletteIds.set(i);
|
bedrockOnlyBlockEntityIds.set(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Bedrock-exclusive block entities
|
// Add Bedrock-exclusive block entities
|
||||||
// We only if the palette contained any blocks that are Bedrock-exclusive block entities to avoid iterating through the whole block data
|
// We only if the palette contained any blocks that are Bedrock-exclusive block entities to avoid iterating through the whole block data
|
||||||
// for no reason, as most sections will not contain any pistons or flower pots
|
// for no reason, as most sections will not contain any pistons or flower pots
|
||||||
if (!pistonOrFlowerPaletteIds.isEmpty()) {
|
if (!bedrockOnlyBlockEntityIds.isEmpty()) {
|
||||||
for (int yzx = 0; yzx < BlockStorage.SIZE; yzx++) {
|
for (int yzx = 0; yzx < BlockStorage.SIZE; yzx++) {
|
||||||
int paletteId = javaData.get(yzx);
|
int paletteId = javaData.get(yzx);
|
||||||
if (pistonOrFlowerPaletteIds.get(paletteId)) {
|
if (bedrockOnlyBlockEntityIds.get(paletteId)) {
|
||||||
bedrockBlockEntities.add(BedrockOnlyBlockEntity.getTag(session,
|
bedrockBlockEntities.add(BedrockOnlyBlockEntity.getTag(session,
|
||||||
Vector3i.from((packet.getX() << 4) + (yzx & 0xF), ((sectionY + yOffset) << 4) + ((yzx >> 8) & 0xF), (packet.getZ() << 4) + ((yzx >> 4) & 0xF)),
|
Vector3i.from((packet.getX() << 4) + (yzx & 0xF), ((sectionY + yOffset) << 4) + ((yzx >> 8) & 0xF), (packet.getZ() << 4) + ((yzx >> 4) & 0xF)),
|
||||||
javaPalette.idToState(paletteId)
|
javaPalette.idToState(paletteId)
|
||||||
|
@ -233,9 +233,9 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||||
}
|
}
|
||||||
|
|
||||||
// V1 palette
|
// V1 palette
|
||||||
IntList layer1Palette = new IntArrayList(2);
|
IntList layer1Palette = IntList.of(
|
||||||
layer1Palette.add(session.getBlockMappings().getBedrockAirId()); // Air - see BlockStorage's constructor for more information
|
session.getBlockMappings().getBedrockAirId(), // Air - see BlockStorage's constructor for more information
|
||||||
layer1Palette.add(session.getBlockMappings().getBedrockWaterId());
|
session.getBlockMappings().getBedrockWaterId());
|
||||||
|
|
||||||
layers = new BlockStorage[]{ layer0, new BlockStorage(BitArrayVersion.V1.createArray(BlockStorage.SIZE, layer1Data), layer1Palette) };
|
layers = new BlockStorage[]{ layer0, new BlockStorage(BitArrayVersion.V1.createArray(BlockStorage.SIZE, layer1Data), layer1Palette) };
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,15 +30,15 @@ import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
import com.nukkitx.nbt.NbtMap;
|
import com.nukkitx.nbt.NbtMap;
|
||||||
import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket;
|
import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
import org.geysermc.geyser.registry.Registries;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.level.block.entity.BedrockOnlyBlockEntity;
|
import org.geysermc.geyser.translator.level.block.entity.BedrockOnlyBlockEntity;
|
||||||
import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
|
import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
|
||||||
import org.geysermc.geyser.translator.level.block.entity.FlowerPotBlockEntityTranslator;
|
import org.geysermc.geyser.translator.level.block.entity.FlowerPotBlockEntityTranslator;
|
||||||
import org.geysermc.geyser.registry.Registries;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.HashMap;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class BlockEntityUtils {
|
public class BlockEntityUtils {
|
||||||
|
@ -46,27 +46,22 @@ public class BlockEntityUtils {
|
||||||
* A list of all block entities that require the Java block state in order to fill out their block entity information.
|
* A list of all block entities that require the Java block state in order to fill out their block entity information.
|
||||||
* This list will be smaller with cache sections on as we don't need to double-cache data
|
* This list will be smaller with cache sections on as we don't need to double-cache data
|
||||||
*/
|
*/
|
||||||
public static final ObjectArrayList<BedrockOnlyBlockEntity> BEDROCK_ONLY_BLOCK_ENTITIES = new ObjectArrayList<>();
|
public static final List<BedrockOnlyBlockEntity> BEDROCK_ONLY_BLOCK_ENTITIES = List.of(
|
||||||
|
(BedrockOnlyBlockEntity) Registries.BLOCK_ENTITIES.get().get(BlockEntityType.CHEST),
|
||||||
|
new FlowerPotBlockEntityTranslator()
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains a list of irregular block entity name translations that can't be fit into the regex
|
* Contains a list of irregular block entity name translations that can't be fit into the regex
|
||||||
*/
|
*/
|
||||||
public static final Map<BlockEntityType, String> BLOCK_ENTITY_TRANSLATIONS = new HashMap<>() {
|
public static final Map<BlockEntityType, String> BLOCK_ENTITY_TRANSLATIONS = Map.of(
|
||||||
{
|
|
||||||
// Bedrock/Java differences
|
// Bedrock/Java differences
|
||||||
put(BlockEntityType.ENCHANTING_TABLE, "EnchantTable");
|
BlockEntityType.ENCHANTING_TABLE, "EnchantTable",
|
||||||
put(BlockEntityType.JIGSAW, "JigsawBlock");
|
BlockEntityType.JIGSAW, "JigsawBlock",
|
||||||
put(BlockEntityType.PISTON, "PistonArm");
|
BlockEntityType.PISTON, "PistonArm",
|
||||||
put(BlockEntityType.TRAPPED_CHEST, "Chest");
|
BlockEntityType.TRAPPED_CHEST, "Chest"
|
||||||
// There are some legacy IDs sent but as far as I can tell they are not needed for things to work properly
|
// There are some legacy IDs sent but as far as I can tell they are not needed for things to work properly
|
||||||
}
|
);
|
||||||
};
|
|
||||||
|
|
||||||
static {
|
|
||||||
// Seeing as there are only two - and, hopefully, will only ever be two - we can hardcode this
|
|
||||||
BEDROCK_ONLY_BLOCK_ENTITIES.add((BedrockOnlyBlockEntity) Registries.BLOCK_ENTITIES.get().get(BlockEntityType.CHEST));
|
|
||||||
BEDROCK_ONLY_BLOCK_ENTITIES.add(new FlowerPotBlockEntityTranslator());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getBedrockBlockEntityId(BlockEntityType type) {
|
public static String getBedrockBlockEntityId(BlockEntityType type) {
|
||||||
// These are the only exceptions when it comes to block entity ids
|
// These are the only exceptions when it comes to block entity ids
|
||||||
|
@ -77,9 +72,9 @@ public class BlockEntityUtils {
|
||||||
|
|
||||||
String id = type.name();
|
String id = type.name();
|
||||||
// Split at every space or capital letter - for the latter, some legacy Java block entity tags are the correct format already
|
// Split at every space or capital letter - for the latter, some legacy Java block entity tags are the correct format already
|
||||||
String[] words = id.split("_");;
|
String[] words = id.split("_");
|
||||||
for (int i = 0; i < words.length; i++) {
|
for (int i = 0; i < words.length; i++) {
|
||||||
words[i] = words[i].substring(0, 1).toUpperCase() + words[i].substring(1).toLowerCase();
|
words[i] = words[i].substring(0, 1).toUpperCase(Locale.ROOT) + words[i].substring(1).toLowerCase(Locale.ROOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return String.join("", words);
|
return String.join("", words);
|
||||||
|
|
Loading…
Reference in a new issue