mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-12-28 07:20:28 +01:00
Block refactory
This commit is contained in:
parent
9bca012194
commit
cbaa9cd2a0
54 changed files with 3620 additions and 157 deletions
|
@ -34,6 +34,7 @@ import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
import org.geysermc.geyser.platform.spigot.world.manager.GeyserSpigotWorldManager;
|
import org.geysermc.geyser.platform.spigot.world.manager.GeyserSpigotWorldManager;
|
||||||
import org.geysermc.geyser.registry.BlockRegistries;
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
@ -59,7 +60,7 @@ public class GeyserSpigotBlockPlaceListener implements Listener {
|
||||||
event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ())));
|
event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ())));
|
||||||
} else {
|
} else {
|
||||||
String javaBlockId = event.getBlockPlaced().getBlockData().getAsString();
|
String javaBlockId = event.getBlockPlaced().getBlockData().getAsString();
|
||||||
placeBlockSoundPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getOrDefault(javaBlockId, BlockStateValues.JAVA_AIR_ID)));
|
placeBlockSoundPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getOrDefault(javaBlockId, Block.JAVA_AIR_ID)));
|
||||||
}
|
}
|
||||||
placeBlockSoundPacket.setIdentifier(":");
|
placeBlockSoundPacket.setIdentifier(":");
|
||||||
session.sendUpstreamPacket(placeBlockSoundPacket);
|
session.sendUpstreamPacket(placeBlockSoundPacket);
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.geysermc.geyser.adapters.WorldAdapter;
|
||||||
import org.geysermc.geyser.adapters.paper.PaperAdapters;
|
import org.geysermc.geyser.adapters.paper.PaperAdapters;
|
||||||
import org.geysermc.geyser.adapters.spigot.SpigotAdapters;
|
import org.geysermc.geyser.adapters.spigot.SpigotAdapters;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
|
||||||
public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager {
|
public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager {
|
||||||
|
@ -52,7 +53,7 @@ public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager {
|
||||||
public int getBlockAt(GeyserSession session, int x, int y, int z) {
|
public int getBlockAt(GeyserSession session, int x, int y, int z) {
|
||||||
Player player = Bukkit.getPlayer(session.getPlayerEntity().getUsername());
|
Player player = Bukkit.getPlayer(session.getPlayerEntity().getUsername());
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
return BlockStateValues.JAVA_AIR_ID;
|
return Block.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
return adapter.getBlockAt(player.getWorld(), x, y, z);
|
return adapter.getBlockAt(player.getWorld(), x, y, z);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,12 +70,12 @@ public class GeyserSpigotWorldManager extends WorldManager {
|
||||||
public int getBlockAt(GeyserSession session, int x, int y, int z) {
|
public int getBlockAt(GeyserSession session, int x, int y, int z) {
|
||||||
Player bukkitPlayer;
|
Player bukkitPlayer;
|
||||||
if ((bukkitPlayer = Bukkit.getPlayer(session.getPlayerEntity().getUsername())) == null) {
|
if ((bukkitPlayer = Bukkit.getPlayer(session.getPlayerEntity().getUsername())) == null) {
|
||||||
return BlockStateValues.JAVA_AIR_ID;
|
return org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
World world = bukkitPlayer.getWorld();
|
World world = bukkitPlayer.getWorld();
|
||||||
if (!world.isChunkLoaded(x >> 4, z >> 4)) {
|
if (!world.isChunkLoaded(x >> 4, z >> 4)) {
|
||||||
// If the chunk isn't loaded, how could we even be here?
|
// If the chunk isn't loaded, how could we even be here?
|
||||||
return BlockStateValues.JAVA_AIR_ID;
|
return org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getBlockNetworkId(world.getBlockAt(x, y, z));
|
return getBlockNetworkId(world.getBlockAt(x, y, z));
|
||||||
|
@ -86,9 +86,9 @@ public class GeyserSpigotWorldManager extends WorldManager {
|
||||||
// Terrible behavior, but this is basically what's always been happening behind the scenes anyway.
|
// Terrible behavior, but this is basically what's always been happening behind the scenes anyway.
|
||||||
CompletableFuture<String> blockData = new CompletableFuture<>();
|
CompletableFuture<String> blockData = new CompletableFuture<>();
|
||||||
Bukkit.getRegionScheduler().execute(this.plugin, block.getLocation(), () -> blockData.complete(block.getBlockData().getAsString()));
|
Bukkit.getRegionScheduler().execute(this.plugin, block.getLocation(), () -> blockData.complete(block.getBlockData().getAsString()));
|
||||||
return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(blockData.join(), BlockStateValues.JAVA_AIR_ID);
|
return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(blockData.join(), org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID);
|
||||||
}
|
}
|
||||||
return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(block.getBlockData().getAsString(), BlockStateValues.JAVA_AIR_ID);
|
return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(block.getBlockData().getAsString(), org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -69,6 +69,7 @@ import org.geysermc.geyser.event.GeyserEventBus;
|
||||||
import org.geysermc.geyser.extension.GeyserExtensionManager;
|
import org.geysermc.geyser.extension.GeyserExtensionManager;
|
||||||
import org.geysermc.geyser.impl.MinecraftVersionImpl;
|
import org.geysermc.geyser.impl.MinecraftVersionImpl;
|
||||||
import org.geysermc.geyser.level.WorldManager;
|
import org.geysermc.geyser.level.WorldManager;
|
||||||
|
import org.geysermc.geyser.level.block.Blocks;
|
||||||
import org.geysermc.geyser.network.GameProtocol;
|
import org.geysermc.geyser.network.GameProtocol;
|
||||||
import org.geysermc.geyser.network.netty.GeyserServer;
|
import org.geysermc.geyser.network.netty.GeyserServer;
|
||||||
import org.geysermc.geyser.registry.BlockRegistries;
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
|
@ -256,6 +257,18 @@ public class GeyserImpl implements GeyserApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
VersionCheckUtils.checkForOutdatedJava(logger);
|
VersionCheckUtils.checkForOutdatedJava(logger);
|
||||||
|
|
||||||
|
Blocks.VAULT.javaId();
|
||||||
|
for (int i = 0; i < BlockRegistries.JAVA_BLOCKS.get().length; i++) {
|
||||||
|
String cleanIdentifier = BlockRegistries.JAVA_BLOCKS.get(i).getCleanJavaIdentifier();
|
||||||
|
String newIdentifier = BlockRegistries.BLOCK_STATES.get(i).block().javaIdentifier();
|
||||||
|
if (!cleanIdentifier.equals(newIdentifier)) {
|
||||||
|
System.out.println("Check block " + BlockRegistries.BLOCK_STATES.get(i).block().javaIdentifier());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println(BlockRegistries.JAVA_BLOCKS.get().length);
|
||||||
|
System.out.println(BlockRegistries.BLOCK_STATES.get().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startInstance() {
|
private void startInstance() {
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.geysermc.erosion.util.BlockPositionIterator;
|
||||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
import org.geysermc.geyser.level.physics.BoundingBox;
|
import org.geysermc.geyser.level.physics.BoundingBox;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.collision.BlockCollision;
|
import org.geysermc.geyser.translator.collision.BlockCollision;
|
||||||
|
@ -162,7 +163,7 @@ public class FishingHookEntity extends ThrowableEntity {
|
||||||
*/
|
*/
|
||||||
protected boolean isInAir() {
|
protected boolean isInAir() {
|
||||||
int block = session.getGeyser().getWorldManager().getBlockAt(session, position.toInt());
|
int block = session.getGeyser().getWorldManager().getBlockAt(session, position.toInt());
|
||||||
return block == BlockStateValues.JAVA_AIR_ID;
|
return block == Block.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -43,6 +43,7 @@ import org.geysermc.erosion.packet.backendbound.BackendboundInitializePacket;
|
||||||
import org.geysermc.erosion.packet.backendbound.BackendboundPacket;
|
import org.geysermc.erosion.packet.backendbound.BackendboundPacket;
|
||||||
import org.geysermc.erosion.packet.geyserbound.*;
|
import org.geysermc.erosion.packet.geyserbound.*;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
import org.geysermc.geyser.level.physics.Direction;
|
import org.geysermc.geyser.level.physics.Direction;
|
||||||
import org.geysermc.geyser.network.GameProtocol;
|
import org.geysermc.geyser.network.GameProtocol;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
@ -119,7 +120,7 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke
|
||||||
}
|
}
|
||||||
CompletableFuture<Integer> future = this.asyncPendingLookups.remove(transactionId);
|
CompletableFuture<Integer> future = this.asyncPendingLookups.remove(transactionId);
|
||||||
if (future != null) {
|
if (future != null) {
|
||||||
future.complete(BlockStateValues.JAVA_AIR_ID);
|
future.complete(Block.JAVA_AIR_ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import it.unimi.dsi.fastutil.ints.*;
|
import it.unimi.dsi.fastutil.ints.*;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
import org.geysermc.geyser.level.physics.Direction;
|
import org.geysermc.geyser.level.physics.Direction;
|
||||||
import org.geysermc.geyser.level.physics.PistonBehavior;
|
import org.geysermc.geyser.level.physics.PistonBehavior;
|
||||||
import org.geysermc.geyser.registry.BlockRegistries;
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
|
@ -48,7 +49,6 @@ public final class BlockStateValues {
|
||||||
private static final Int2IntMap BANNER_COLORS = new FixedInt2IntMap();
|
private static final Int2IntMap BANNER_COLORS = new FixedInt2IntMap();
|
||||||
private static final Int2ByteMap BED_COLORS = new FixedInt2ByteMap();
|
private static final Int2ByteMap BED_COLORS = new FixedInt2ByteMap();
|
||||||
private static final Int2IntMap BRUSH_PROGRESS = new Int2IntOpenHashMap();
|
private static final Int2IntMap BRUSH_PROGRESS = new Int2IntOpenHashMap();
|
||||||
private static final Int2ByteMap COMMAND_BLOCK_VALUES = new Int2ByteOpenHashMap();
|
|
||||||
private static final Int2ObjectMap<DoubleChestValue> DOUBLE_CHEST_VALUES = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<DoubleChestValue> DOUBLE_CHEST_VALUES = new Int2ObjectOpenHashMap<>();
|
||||||
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();
|
||||||
|
@ -110,11 +110,6 @@ public final class BlockStateValues {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (javaId.contains("command_block")) {
|
|
||||||
COMMAND_BLOCK_VALUES.put(javaBlockState, javaId.contains("conditional=true") ? (byte) 1 : (byte) 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blockData.get("double_chest_position") != null) {
|
if (blockData.get("double_chest_position") != null) {
|
||||||
boolean isX = (blockData.get("x") != null);
|
boolean isX = (blockData.get("x") != null);
|
||||||
boolean isDirectionPositive = ((blockData.get("x") != null && blockData.get("x").asBoolean()) ||
|
boolean isDirectionPositive = ((blockData.get("x") != null && blockData.get("x").asBoolean()) ||
|
||||||
|
@ -277,16 +272,6 @@ public final class BlockStateValues {
|
||||||
return ALL_CAULDRONS.contains(state);
|
return ALL_CAULDRONS.contains(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The block state in Java and Bedrock both contain the conditional bit, however command block block entity tags
|
|
||||||
* in Bedrock need the conditional information.
|
|
||||||
*
|
|
||||||
* @return the list of all command blocks and if they are conditional (1 or 0)
|
|
||||||
*/
|
|
||||||
public static Int2ByteMap getCommandBlockValues() {
|
|
||||||
return COMMAND_BLOCK_VALUES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All double chest values are part of the block state in Java and part of the block entity tag in Bedrock.
|
* All double chest values are part of the block state in Java and part of the block entity tag in Bedrock.
|
||||||
* This gives the DoubleChestValue that can be calculated into the final tag.
|
* This gives the DoubleChestValue that can be calculated into the final tag.
|
||||||
|
@ -356,7 +341,7 @@ public final class BlockStateValues {
|
||||||
* @return Block state for the piston head
|
* @return Block state for the piston head
|
||||||
*/
|
*/
|
||||||
public static int getPistonHead(Direction direction) {
|
public static int getPistonHead(Direction direction) {
|
||||||
return PISTON_HEADS.getOrDefault(direction, BlockStateValues.JAVA_AIR_ID);
|
return PISTON_HEADS.getOrDefault(direction, Block.JAVA_AIR_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -420,7 +405,7 @@ public final class BlockStateValues {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean canPistonMoveBlock(int javaId, boolean isPushing) {
|
public static boolean canPistonMoveBlock(int javaId, boolean isPushing) {
|
||||||
if (javaId == JAVA_AIR_ID) {
|
if (javaId == Block.JAVA_AIR_ID) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Pistons can only be moved if they aren't extended
|
// Pistons can only be moved if they aren't extended
|
||||||
|
|
2820
core/src/main/java/org/geysermc/geyser/level/block/Blocks.java
Normal file
2820
core/src/main/java/org/geysermc/geyser/level/block/Blocks.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 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.geyser.level.block.property;
|
||||||
|
|
||||||
|
public enum ChestType {
|
||||||
|
SINGLE,
|
||||||
|
LEFT,
|
||||||
|
RIGHT;
|
||||||
|
|
||||||
|
public static final ChestType[] VALUES = values();
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 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.geyser.level.block.property;
|
||||||
|
|
||||||
|
import org.geysermc.geyser.level.physics.Axis;
|
||||||
|
import org.geysermc.geyser.level.physics.Direction;
|
||||||
|
|
||||||
|
public final class Properties {
|
||||||
|
public static final Property<Boolean> ATTACHED = Property.create("attached");
|
||||||
|
public static final Property<Boolean> BOTTOM = Property.create("bottom");
|
||||||
|
public static final Property<Boolean> CONDITIONAL = Property.create("conditional");
|
||||||
|
public static final Property<Boolean> DISARMED = Property.create("disarmed");
|
||||||
|
public static final Property<Boolean> DRAG = Property.create("drag");
|
||||||
|
public static final Property<Boolean> ENABLED = Property.create("enabled");
|
||||||
|
public static final Property<Boolean> EXTENDED = Property.create("extended");
|
||||||
|
public static final Property<Boolean> EYE = Property.create("eye");
|
||||||
|
public static final Property<Boolean> FALLING = Property.create("falling");
|
||||||
|
public static final Property<Boolean> HANGING = Property.create("hanging");
|
||||||
|
public static final Property<Boolean> HAS_BOTTLE_0 = Property.create("has_bottle_0");
|
||||||
|
public static final Property<Boolean> HAS_BOTTLE_1 = Property.create("has_bottle_1");
|
||||||
|
public static final Property<Boolean> HAS_BOTTLE_2 = Property.create("has_bottle_2");
|
||||||
|
public static final Property<Boolean> HAS_RECORD = Property.create("has_record");
|
||||||
|
public static final Property<Boolean> HAS_BOOK = Property.create("has_book");
|
||||||
|
public static final Property<Boolean> INVERTED = Property.create("inverted");
|
||||||
|
public static final Property<Boolean> IN_WALL = Property.create("in_wall");
|
||||||
|
public static final Property<Boolean> LIT = Property.create("lit");
|
||||||
|
public static final Property<Boolean> LOCKED = Property.create("locked");
|
||||||
|
public static final Property<Boolean> OCCUPIED = Property.create("occupied");
|
||||||
|
public static final Property<Boolean> OPEN = Property.create("open");
|
||||||
|
public static final Property<Boolean> PERSISTENT = Property.create("persistent");
|
||||||
|
public static final Property<Boolean> POWERED = Property.create("powered");
|
||||||
|
public static final Property<Boolean> SHORT = Property.create("short");
|
||||||
|
public static final Property<Boolean> SIGNAL_FIRE = Property.create("signal_fire");
|
||||||
|
public static final Property<Boolean> SNOWY = Property.create("snowy");
|
||||||
|
public static final Property<Boolean> TRIGGERED = Property.create("triggered");
|
||||||
|
public static final Property<Boolean> UNSTABLE = Property.create("unstable");
|
||||||
|
public static final Property<Boolean> WATERLOGGED = Property.create("waterlogged");
|
||||||
|
public static final Property<Boolean> BERRIES = Property.create("berries");
|
||||||
|
public static final Property<Boolean> BLOOM = Property.create("bloom");
|
||||||
|
public static final Property<Boolean> SHRIEKING = Property.create("shrieking");
|
||||||
|
public static final Property<Boolean> CAN_SUMMON = Property.create("can_summon");
|
||||||
|
public static final Property<Axis> HORIZONTAL_AXIS = Property.create("axis");
|
||||||
|
public static final Property<Axis> AXIS = Property.create("axis");
|
||||||
|
public static final Property<Boolean> UP = Property.create("up");
|
||||||
|
public static final Property<Boolean> DOWN = Property.create("down");
|
||||||
|
public static final Property<Boolean> NORTH = Property.create("north");
|
||||||
|
public static final Property<Boolean> EAST = Property.create("east");
|
||||||
|
public static final Property<Boolean> SOUTH = Property.create("south");
|
||||||
|
public static final Property<Boolean> WEST = Property.create("west");
|
||||||
|
public static final Property<Direction> FACING = Property.create("facing");
|
||||||
|
public static final Property<Direction> FACING_HOPPER = Property.create("facing");
|
||||||
|
public static final Property<Direction> HORIZONTAL_FACING = Property.create("facing");
|
||||||
|
public static final Property<Integer> FLOWER_AMOUNT = Property.create("flower_amount");
|
||||||
|
public static final Property<String> ORIENTATION = Property.create("orientation");
|
||||||
|
public static final Property<String> ATTACH_FACE = Property.create("face");
|
||||||
|
public static final Property<String> BELL_ATTACHMENT = Property.create("attachment");
|
||||||
|
public static final Property<String> EAST_WALL = Property.create("east");
|
||||||
|
public static final Property<String> NORTH_WALL = Property.create("north");
|
||||||
|
public static final Property<String> SOUTH_WALL = Property.create("south");
|
||||||
|
public static final Property<String> WEST_WALL = Property.create("west");
|
||||||
|
public static final Property<String> EAST_REDSTONE = Property.create("east");
|
||||||
|
public static final Property<String> NORTH_REDSTONE = Property.create("north");
|
||||||
|
public static final Property<String> SOUTH_REDSTONE = Property.create("south");
|
||||||
|
public static final Property<String> WEST_REDSTONE = Property.create("west");
|
||||||
|
public static final Property<String> DOUBLE_BLOCK_HALF = Property.create("half");
|
||||||
|
public static final Property<String> HALF = Property.create("half");
|
||||||
|
public static final Property<String> RAIL_SHAPE = Property.create("shape");
|
||||||
|
public static final Property<String> RAIL_SHAPE_STRAIGHT = Property.create("shape");
|
||||||
|
public static final Property<Integer> AGE_1 = Property.create("age");
|
||||||
|
public static final Property<Integer> AGE_2 = Property.create("age");
|
||||||
|
public static final Property<Integer> AGE_3 = Property.create("age");
|
||||||
|
public static final Property<Integer> AGE_4 = Property.create("age");
|
||||||
|
public static final Property<Integer> AGE_5 = Property.create("age");
|
||||||
|
public static final Property<Integer> AGE_7 = Property.create("age");
|
||||||
|
public static final Property<Integer> AGE_15 = Property.create("age");
|
||||||
|
public static final Property<Integer> AGE_25 = Property.create("age");
|
||||||
|
public static final Property<Integer> BITES = Property.create("bites");
|
||||||
|
public static final Property<Integer> CANDLES = Property.create("candles");
|
||||||
|
public static final Property<Integer> DELAY = Property.create("delay");
|
||||||
|
public static final Property<Integer> DISTANCE = Property.create("distance");
|
||||||
|
public static final Property<Integer> EGGS = Property.create("eggs");
|
||||||
|
public static final Property<Integer> HATCH = Property.create("hatch");
|
||||||
|
public static final Property<Integer> LAYERS = Property.create("layers");
|
||||||
|
public static final Property<Integer> LEVEL_CAULDRON = Property.create("level");
|
||||||
|
public static final Property<Integer> LEVEL_COMPOSTER = Property.create("level");
|
||||||
|
public static final Property<Integer> LEVEL_FLOWING = Property.create("level");
|
||||||
|
public static final Property<Integer> LEVEL_HONEY = Property.create("honey_level");
|
||||||
|
public static final Property<Integer> LEVEL = Property.create("level");
|
||||||
|
public static final Property<Integer> MOISTURE = Property.create("moisture");
|
||||||
|
public static final Property<Integer> NOTE = Property.create("note");
|
||||||
|
public static final Property<Integer> PICKLES = Property.create("pickles");
|
||||||
|
public static final Property<Integer> POWER = Property.create("power");
|
||||||
|
public static final Property<Integer> STAGE = Property.create("stage");
|
||||||
|
public static final Property<Integer> STABILITY_DISTANCE = Property.create("distance");
|
||||||
|
public static final Property<Integer> RESPAWN_ANCHOR_CHARGES = Property.create("charges");
|
||||||
|
public static final Property<Integer> ROTATION_16 = Property.create("rotation");
|
||||||
|
public static final Property<String> BED_PART = Property.create("part");
|
||||||
|
public static final Property<String> CHEST_TYPE = Property.create("type");
|
||||||
|
public static final Property<String> MODE_COMPARATOR = Property.create("mode");
|
||||||
|
public static final Property<String> DOOR_HINGE = Property.create("hinge");
|
||||||
|
public static final Property<String> NOTEBLOCK_INSTRUMENT = Property.create("instrument");
|
||||||
|
public static final Property<String> PISTON_TYPE = Property.create("type");
|
||||||
|
public static final Property<String> SLAB_TYPE = Property.create("type");
|
||||||
|
public static final Property<String> STAIRS_SHAPE = Property.create("shape");
|
||||||
|
public static final Property<String> STRUCTUREBLOCK_MODE = Property.create("mode");
|
||||||
|
public static final Property<String> BAMBOO_LEAVES = Property.create("leaves");
|
||||||
|
public static final Property<String> TILT = Property.create("tilt");
|
||||||
|
public static final Property<Direction> VERTICAL_DIRECTION = Property.create("vertical_direction");
|
||||||
|
public static final Property<String> DRIPSTONE_THICKNESS = Property.create("thickness");
|
||||||
|
public static final Property<String> SCULK_SENSOR_PHASE = Property.create("sculk_sensor_phase");
|
||||||
|
public static final Property<Boolean> CHISELED_BOOKSHELF_SLOT_0_OCCUPIED = Property.create("slot_0_occupied");
|
||||||
|
public static final Property<Boolean> CHISELED_BOOKSHELF_SLOT_1_OCCUPIED = Property.create("slot_1_occupied");
|
||||||
|
public static final Property<Boolean> CHISELED_BOOKSHELF_SLOT_2_OCCUPIED = Property.create("slot_2_occupied");
|
||||||
|
public static final Property<Boolean> CHISELED_BOOKSHELF_SLOT_3_OCCUPIED = Property.create("slot_3_occupied");
|
||||||
|
public static final Property<Boolean> CHISELED_BOOKSHELF_SLOT_4_OCCUPIED = Property.create("slot_4_occupied");
|
||||||
|
public static final Property<Boolean> CHISELED_BOOKSHELF_SLOT_5_OCCUPIED = Property.create("slot_5_occupied");
|
||||||
|
public static final Property<Integer> DUSTED = Property.create("dusted");
|
||||||
|
public static final Property<Boolean> CRACKED = Property.create("cracked");
|
||||||
|
public static final Property<Boolean> CRAFTING = Property.create("crafting");
|
||||||
|
public static final Property<String> TRIAL_SPAWNER_STATE = Property.create("trial_spawner_state");
|
||||||
|
public static final Property<String> VAULT_STATE = Property.create("vault_state");
|
||||||
|
public static final Property<Boolean> OMINOUS = Property.create("ominous");
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 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.geyser.level.block.property;
|
||||||
|
|
||||||
|
public class Property<T extends Comparable<T>> {
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public Property(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getSimpleName() + "[" + name + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Comparable<T>> Property<T> create(String name) {
|
||||||
|
return new Property<>(name);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 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.geyser.level.block.type;
|
||||||
|
|
||||||
|
public class BannerBlock extends Block {
|
||||||
|
private final int dyeColor;
|
||||||
|
|
||||||
|
public BannerBlock(String javaIdentifier, int dyeColor, Builder builder) {
|
||||||
|
super(javaIdentifier, builder);
|
||||||
|
this.dyeColor = dyeColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int dyeColor() {
|
||||||
|
return dyeColor;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 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.geyser.level.block.type;
|
||||||
|
|
||||||
|
public class BedBlock extends Block {
|
||||||
|
private final int dyeColor;
|
||||||
|
|
||||||
|
public BedBlock(String javaIdentifier, int dyeColor, Builder builder) {
|
||||||
|
super(javaIdentifier, builder);
|
||||||
|
this.dyeColor = dyeColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int dyeColor() {
|
||||||
|
return dyeColor;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 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.geyser.level.block.type;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.Pair;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
|
||||||
|
import org.geysermc.geyser.level.block.property.Property;
|
||||||
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
|
import org.geysermc.mcprotocollib.protocol.data.game.Identifier;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class Block {
|
||||||
|
public static final int JAVA_AIR_ID = 0;
|
||||||
|
|
||||||
|
private final String javaIdentifier;
|
||||||
|
private int javaId = -1;
|
||||||
|
|
||||||
|
public Block(String javaIdentifier, Builder builder) {
|
||||||
|
this.javaIdentifier = Identifier.formalize(javaIdentifier).intern();
|
||||||
|
builder.build(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String javaIdentifier() {
|
||||||
|
return javaIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int javaId() {
|
||||||
|
return javaId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJavaId(int javaId) {
|
||||||
|
if (this.javaId != -1) {
|
||||||
|
throw new RuntimeException("Block ID has already been set!");
|
||||||
|
}
|
||||||
|
this.javaId = javaId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Item{" +
|
||||||
|
"javaIdentifier='" + javaIdentifier + '\'' +
|
||||||
|
", javaId=" + javaId +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Builder {
|
||||||
|
private final Map<Property<?>, List<Comparable<?>>> states = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For states that we're just tracking for mirroring Java states.
|
||||||
|
*/
|
||||||
|
public Builder enumState(Property<String> property, String... values) {
|
||||||
|
states.put(property, List.of(values));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final <T extends Enum<T>> Builder enumState(Property<T> property, T... enums) {
|
||||||
|
states.put(property, List.of(enums));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder booleanState(Property<Boolean> property) {
|
||||||
|
states.put(property, List.of(Boolean.TRUE, Boolean.FALSE)); // Make this list a static constant if it'll survive past initialization
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder intState(Property<Integer> property, int low, int high) {
|
||||||
|
IntList list = new IntArrayList();
|
||||||
|
// There is a state for every number between the low and high.
|
||||||
|
for (int i = low; i <= high; i++) {
|
||||||
|
list.add(i);
|
||||||
|
}
|
||||||
|
states.put(property, List.copyOf(list)); // Boxing reasons for that copy I guess.
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void build(Block block) {
|
||||||
|
if (states.isEmpty()) {
|
||||||
|
BlockRegistries.BLOCK_STATES.get().add(new BlockState(block, BlockRegistries.BLOCK_STATES.get().size()));
|
||||||
|
} else {
|
||||||
|
// Think of this stream as another list containing, at the start, one empty list.
|
||||||
|
// It's two collections. Not a stream from the empty list.
|
||||||
|
Stream<List<Pair<Property<?>, Comparable<?>>>> stream = Stream.of(Collections.emptyList());
|
||||||
|
for (var state : this.states.entrySet()) {
|
||||||
|
// OK, so here's how I understand this works. Because this was staring at vanilla Java code trying
|
||||||
|
// to figure out exactly how it works so we don't have any discrepencies.
|
||||||
|
// For each existing pair in the list, a new list is created, adding one of the new values.
|
||||||
|
// Property up [true/false] would exist as true and false
|
||||||
|
// Both entries will get duplicated, adding down, true and false.
|
||||||
|
stream = stream.flatMap(aPreviousPropertiesList ->
|
||||||
|
// So the above is a list. It may be empty if this is the first property,
|
||||||
|
// or it may be populated if this is not the first property.
|
||||||
|
// We're about to create a new stream, each with a new list,
|
||||||
|
// for every previous property
|
||||||
|
state.getValue().stream().map(value -> {
|
||||||
|
var newProperties = new ArrayList<>(aPreviousPropertiesList);
|
||||||
|
newProperties.add(Pair.of(state.getKey(), value));
|
||||||
|
return newProperties;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we have a list of Pair<Property, Value>s. Each list is a block state!
|
||||||
|
// If we have two boolean properties: up [true/false] and down [true/false],
|
||||||
|
// We'll see [up=true,down=true], [up=false,down=true], [up=true,down=false], [up=false,down=false]
|
||||||
|
stream.forEach(properties -> {
|
||||||
|
Reference2ObjectMap<Property<?>, Comparable<?>> propertyMap = new Reference2ObjectArrayMap<>(properties.size());
|
||||||
|
for (int i = 0; i < properties.size(); i++) {
|
||||||
|
Pair<Property<?>, Comparable<?>> property = properties.get(i);
|
||||||
|
propertyMap.put(property.key(), property.value());
|
||||||
|
}
|
||||||
|
BlockRegistries.BLOCK_STATES.get().add(new BlockState(block, BlockRegistries.BLOCK_STATES.get().size(), propertyMap));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 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.geyser.level.block.type;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectMaps;
|
||||||
|
import org.geysermc.geyser.level.block.property.Property;
|
||||||
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
|
|
||||||
|
public final class BlockState {
|
||||||
|
private final Block block;
|
||||||
|
private final int javaId;
|
||||||
|
private final Reference2ObjectMap<Property<?>, Comparable<?>> states;
|
||||||
|
|
||||||
|
BlockState(Block block, int javaId) {
|
||||||
|
this(block, javaId, Reference2ObjectMaps.emptyMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockState(Block block, int javaId, Reference2ObjectMap<Property<?>, Comparable<?>> states) {
|
||||||
|
this.block = block;
|
||||||
|
this.javaId = javaId;
|
||||||
|
this.states = states;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends Comparable<T>> T getValue(Property<T> property) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (T) states.get(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block block() {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int javaId() {
|
||||||
|
return javaId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BlockState of(int javaId) {
|
||||||
|
return BlockRegistries.BLOCK_STATES.get(javaId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,6 +34,8 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
import org.geysermc.geyser.api.block.custom.CustomBlockData;
|
import org.geysermc.geyser.api.block.custom.CustomBlockData;
|
||||||
import org.geysermc.geyser.api.block.custom.CustomBlockState;
|
import org.geysermc.geyser.api.block.custom.CustomBlockState;
|
||||||
import org.geysermc.geyser.api.block.custom.nonvanilla.JavaBlockState;
|
import org.geysermc.geyser.api.block.custom.nonvanilla.JavaBlockState;
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.registry.loader.CollisionRegistryLoader;
|
import org.geysermc.geyser.registry.loader.CollisionRegistryLoader;
|
||||||
import org.geysermc.geyser.registry.loader.RegistryLoaders;
|
import org.geysermc.geyser.registry.loader.RegistryLoaders;
|
||||||
import org.geysermc.geyser.registry.populator.BlockRegistryPopulator;
|
import org.geysermc.geyser.registry.populator.BlockRegistryPopulator;
|
||||||
|
@ -44,8 +46,8 @@ import org.geysermc.geyser.registry.type.BlockMappings;
|
||||||
import org.geysermc.geyser.registry.type.CustomSkull;
|
import org.geysermc.geyser.registry.type.CustomSkull;
|
||||||
import org.geysermc.geyser.translator.collision.BlockCollision;
|
import org.geysermc.geyser.translator.collision.BlockCollision;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,6 +60,14 @@ public class BlockRegistries {
|
||||||
*/
|
*/
|
||||||
public static final VersionedRegistry<BlockMappings> BLOCKS = VersionedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new));
|
public static final VersionedRegistry<BlockMappings> BLOCKS = VersionedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A registry which stores Java IDs to Java {@link BlockState}s, each with their specific state differences and a link
|
||||||
|
* to the overarching block.
|
||||||
|
*/
|
||||||
|
public static final ListRegistry<BlockState> BLOCK_STATES = ListRegistry.create(RegistryLoaders.empty(ArrayList::new));
|
||||||
|
|
||||||
|
public static final ListRegistry<Block> JAVA_BLOCKS_TO_RENAME = ListRegistry.create(RegistryLoaders.empty(ArrayList::new));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mapped registry which stores Java to Bedrock block identifiers.
|
* A mapped registry which stores Java to Bedrock block identifiers.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 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.geyser.registry;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
import org.geysermc.geyser.registry.loader.RegistryLoader;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ListRegistry<M> extends Registry<List<M>> {
|
||||||
|
/**
|
||||||
|
* Creates a new instance of this class with the given input and
|
||||||
|
* {@link RegistryLoader}. The input specified is what the registry
|
||||||
|
* loader needs to take in.
|
||||||
|
*
|
||||||
|
* @param input the input
|
||||||
|
* @param registryLoader the registry loader
|
||||||
|
*/
|
||||||
|
protected <I> ListRegistry(I input, RegistryLoader<I, List<M>> registryLoader) {
|
||||||
|
super(input, registryLoader);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value registered by the given index.
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return the value registered by the given index.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public M get(int index) {
|
||||||
|
if (index >= this.mappings.size()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.mappings.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value registered by the given index or the default value
|
||||||
|
* specified if null.
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @param defaultValue the default value
|
||||||
|
* @return the value registered by the given key or the default value
|
||||||
|
* specified if null.
|
||||||
|
*/
|
||||||
|
public M getOrDefault(int index, M defaultValue) {
|
||||||
|
M value = this.get(index);
|
||||||
|
if (value == null) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a new value into this registry with the given index.
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @param value the value
|
||||||
|
* @return a new value into this registry with the given index.
|
||||||
|
*/
|
||||||
|
public M register(int index, M value) {
|
||||||
|
return this.mappings.set(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new array registry with the given {@link RegistryLoader}. The
|
||||||
|
* input type is not specified here, meaning the loader return type is either
|
||||||
|
* predefined, or the registry is populated at a later point.
|
||||||
|
*
|
||||||
|
* @param registryLoader the registry loader
|
||||||
|
* @param <I> the input type
|
||||||
|
* @param <M> the returned mappings type
|
||||||
|
* @return a new registry with the given RegistryLoader supplier
|
||||||
|
*/
|
||||||
|
public static <I, M> ListRegistry<M> create(RegistryLoader<I, List<M>> registryLoader) {
|
||||||
|
return new ListRegistry<M>(null, registryLoader);
|
||||||
|
}
|
||||||
|
}
|
|
@ -582,8 +582,6 @@ public final class BlockRegistryPopulator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockRegistries.CLEAN_JAVA_IDENTIFIERS.set(cleanIdentifiers.toArray(new String[0]));
|
|
||||||
|
|
||||||
BLOCKS_JSON = blocksJson;
|
BLOCKS_JSON = blocksJson;
|
||||||
|
|
||||||
JsonNode blockInteractionsJson;
|
JsonNode blockInteractionsJson;
|
||||||
|
|
|
@ -1592,9 +1592,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||||
startGamePacket.setRewindHistorySize(0);
|
startGamePacket.setRewindHistorySize(0);
|
||||||
startGamePacket.setServerAuthoritativeBlockBreaking(false);
|
startGamePacket.setServerAuthoritativeBlockBreaking(false);
|
||||||
|
|
||||||
// Entity properties for older versions
|
|
||||||
startGamePacket.getExperiments().add(new ExperimentData("upcoming_creator_features", true));
|
|
||||||
|
|
||||||
upstream.sendPacket(startGamePacket);
|
upstream.sendPacket(startGamePacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.session.cache;
|
package org.geysermc.geyser.session.cache;
|
||||||
|
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette;
|
import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
|
@ -92,11 +93,11 @@ public class ChunkCache {
|
||||||
|
|
||||||
DataPalette palette = chunk.sections()[(y - minY) >> 4];
|
DataPalette palette = chunk.sections()[(y - minY) >> 4];
|
||||||
if (palette == null) {
|
if (palette == null) {
|
||||||
if (block != BlockStateValues.JAVA_AIR_ID) {
|
if (block != Block.JAVA_AIR_ID) {
|
||||||
// A previously empty chunk, which is no longer empty as a block has been added to it
|
// A previously empty chunk, which is no longer empty as a block has been added to it
|
||||||
palette = DataPalette.createForChunk();
|
palette = DataPalette.createForChunk();
|
||||||
// Fixes the chunk assuming that all blocks is the `block` variable we are updating. /shrug
|
// Fixes the chunk assuming that all blocks is the `block` variable we are updating. /shrug
|
||||||
palette.getPalette().stateToId(BlockStateValues.JAVA_AIR_ID);
|
palette.getPalette().stateToId(Block.JAVA_AIR_ID);
|
||||||
chunk.sections()[(y - minY) >> 4] = palette;
|
chunk.sections()[(y - minY) >> 4] = palette;
|
||||||
} else {
|
} else {
|
||||||
// Nothing to update
|
// Nothing to update
|
||||||
|
@ -109,17 +110,17 @@ public class ChunkCache {
|
||||||
|
|
||||||
public int getBlockAt(int x, int y, int z) {
|
public int getBlockAt(int x, int y, int z) {
|
||||||
if (!cache) {
|
if (!cache) {
|
||||||
return BlockStateValues.JAVA_AIR_ID;
|
return Block.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
GeyserChunk column = this.getChunk(x >> 4, z >> 4);
|
GeyserChunk column = this.getChunk(x >> 4, z >> 4);
|
||||||
if (column == null) {
|
if (column == null) {
|
||||||
return BlockStateValues.JAVA_AIR_ID;
|
return Block.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y < minY || ((y - minY) >> 4) > column.sections().length - 1) {
|
if (y < minY || ((y - minY) >> 4) > column.sections().length - 1) {
|
||||||
// Y likely goes above or below the height limit of this world
|
// Y likely goes above or below the height limit of this world
|
||||||
return BlockStateValues.JAVA_AIR_ID;
|
return Block.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataPalette chunk = column.sections()[(y - minY) >> 4];
|
DataPalette chunk = column.sections()[(y - minY) >> 4];
|
||||||
|
@ -127,7 +128,7 @@ public class ChunkCache {
|
||||||
return chunk.get(x & 0xF, y & 0xF, z & 0xF);
|
return chunk.get(x & 0xF, y & 0xF, z & 0xF);
|
||||||
}
|
}
|
||||||
|
|
||||||
return BlockStateValues.JAVA_AIR_ID;
|
return Block.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeChunk(int chunkX, int chunkZ) {
|
public void removeChunk(int chunkX, int chunkZ) {
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.geysermc.geyser.inventory.BedrockContainerSlot;
|
||||||
import org.geysermc.geyser.inventory.Inventory;
|
import org.geysermc.geyser.inventory.Inventory;
|
||||||
import org.geysermc.geyser.inventory.holder.BlockInventoryHolder;
|
import org.geysermc.geyser.inventory.holder.BlockInventoryHolder;
|
||||||
import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater;
|
import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.registry.Registries;
|
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.BlockEntityTranslator;
|
import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
|
||||||
|
@ -58,7 +59,7 @@ public class ShulkerInventoryTranslator extends AbstractBlockInventoryTranslator
|
||||||
.putInt("z", position.getZ())
|
.putInt("z", position.getZ())
|
||||||
.putString("CustomName", inventory.getTitle());
|
.putString("CustomName", inventory.getTitle());
|
||||||
// Don't reset facing property
|
// Don't reset facing property
|
||||||
shulkerBoxTranslator.translateTag(session, tag, null, javaBlockState);
|
shulkerBoxTranslator.translateTag(session, tag, null, BlockState.of(javaBlockState));
|
||||||
|
|
||||||
BlockEntityDataPacket dataPacket = new BlockEntityDataPacket();
|
BlockEntityDataPacket dataPacket = new BlockEntityDataPacket();
|
||||||
dataPacket.setData(tag.build());
|
dataPacket.setData(tag.build());
|
||||||
|
|
|
@ -36,8 +36,7 @@ import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||||
import org.geysermc.geyser.inventory.Container;
|
import org.geysermc.geyser.inventory.Container;
|
||||||
import org.geysermc.geyser.inventory.Inventory;
|
import org.geysermc.geyser.inventory.Inventory;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.level.block.DoubleChestValue;
|
|
||||||
import org.geysermc.geyser.registry.BlockRegistries;
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
import org.geysermc.geyser.registry.type.BlockMapping;
|
import org.geysermc.geyser.registry.type.BlockMapping;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
@ -72,8 +71,8 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
|
||||||
.putString("CustomName", inventory.getTitle())
|
.putString("CustomName", inventory.getTitle())
|
||||||
.putString("id", "Chest");
|
.putString("id", "Chest");
|
||||||
|
|
||||||
DoubleChestValue chestValue = BlockStateValues.getDoubleChestValues().get(javaBlockId);
|
BlockState blockState = BlockState.of(javaBlockId);
|
||||||
DoubleChestBlockEntityTranslator.translateChestValue(tag, chestValue,
|
DoubleChestBlockEntityTranslator.translateChestValue(tag, blockState,
|
||||||
session.getLastInteractionBlockPosition().getX(), session.getLastInteractionBlockPosition().getZ());
|
session.getLastInteractionBlockPosition().getX(), session.getLastInteractionBlockPosition().getZ());
|
||||||
|
|
||||||
BlockEntityDataPacket dataPacket = new BlockEntityDataPacket();
|
BlockEntityDataPacket dataPacket = new BlockEntityDataPacket();
|
||||||
|
|
|
@ -30,7 +30,8 @@ import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
import org.cloudburstmc.nbt.NbtType;
|
import org.cloudburstmc.nbt.NbtType;
|
||||||
import org.geysermc.geyser.item.type.BannerItem;
|
import org.geysermc.geyser.item.type.BannerItem;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.type.BannerBlock;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||||
|
|
||||||
|
@ -39,10 +40,9 @@ import java.util.List;
|
||||||
@BlockEntity(type = BlockEntityType.BANNER)
|
@BlockEntity(type = BlockEntityType.BANNER)
|
||||||
public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, BlockState blockState) {
|
||||||
int bannerColor = BlockStateValues.getBannerColor(blockState);
|
if (blockState.block() instanceof BannerBlock banner) {
|
||||||
if (bannerColor != -1) {
|
bedrockNbt.putInt("Base", 15 - banner.dyeColor());
|
||||||
bedrockNbt.putInt("Base", 15 - bannerColor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (javaNbt == null) {
|
if (javaNbt == null) {
|
||||||
|
|
|
@ -27,13 +27,14 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||||
|
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||||
|
|
||||||
@BlockEntity(type = BlockEntityType.BEACON)
|
@BlockEntity(type = BlockEntityType.BEACON)
|
||||||
public class BeaconBlockEntityTranslator extends BlockEntityTranslator {
|
public class BeaconBlockEntityTranslator extends BlockEntityTranslator {
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) {
|
||||||
int primary = javaNbt.getInt("primary");
|
int primary = javaNbt.getInt("primary");
|
||||||
// The effects here generally map one-to-one Java <-> Bedrock. Only the newer ones get more complicated
|
// The effects here generally map one-to-one Java <-> Bedrock. Only the newer ones get more complicated
|
||||||
bedrockNbt.putInt("primary", primary == -1 ? 0 : primary);
|
bedrockNbt.putInt("primary", primary == -1 ? 0 : primary);
|
||||||
|
|
|
@ -27,19 +27,15 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||||
|
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.type.BedBlock;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||||
|
|
||||||
@BlockEntity(type = BlockEntityType.BED)
|
@BlockEntity(type = BlockEntityType.BED)
|
||||||
public class BedBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
public class BedBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) {
|
||||||
byte bedcolor = BlockStateValues.getBedColor(blockState);
|
bedrockNbt.putByte("color", (byte) (blockState.block() instanceof BedBlock bed ? bed.dyeColor() : 0));
|
||||||
// Just in case...
|
|
||||||
if (bedcolor == -1) {
|
|
||||||
bedcolor = 0;
|
|
||||||
}
|
|
||||||
bedrockNbt.putByte("color", bedcolor);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.cloudburstmc.nbt.NbtList;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtType;
|
import org.cloudburstmc.nbt.NbtType;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,7 +51,7 @@ public interface BedrockOnlyBlockEntity extends RequiresBlockState {
|
||||||
* @param blockState The Java block state.
|
* @param blockState The Java block state.
|
||||||
* @param position The Bedrock block position.
|
* @param position The Bedrock block position.
|
||||||
*/
|
*/
|
||||||
void updateBlock(GeyserSession session, int blockState, Vector3i position);
|
void updateBlock(GeyserSession session, BlockState blockState, Vector3i position);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the tag of the Bedrock-only block entity
|
* Get the tag of the Bedrock-only block entity
|
||||||
|
|
|
@ -28,6 +28,7 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.util.BlockEntityUtils;
|
import org.geysermc.geyser.util.BlockEntityUtils;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||||
|
@ -39,9 +40,9 @@ public abstract class BlockEntityTranslator {
|
||||||
protected BlockEntityTranslator() {
|
protected BlockEntityTranslator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState);
|
public abstract void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState);
|
||||||
|
|
||||||
public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, int blockState) {
|
public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, BlockState blockState) {
|
||||||
NbtMapBuilder tagBuilder = getConstantBedrockTag(type, x, y, z);
|
NbtMapBuilder tagBuilder = getConstantBedrockTag(type, x, y, z);
|
||||||
if (javaNbt != null || this instanceof RequiresBlockState) {
|
if (javaNbt != null || this instanceof RequiresBlockState) {
|
||||||
// Always process tags if the block state is part of the tag.
|
// Always process tags if the block state is part of the tag.
|
||||||
|
|
|
@ -29,7 +29,8 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
import org.geysermc.geyser.item.Items;
|
import org.geysermc.geyser.item.Items;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.property.Properties;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||||
|
@ -38,7 +39,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType
|
||||||
public class BrushableBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
public class BrushableBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, BlockState blockState) {
|
||||||
if (javaNbt == null) {
|
if (javaNbt == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -70,6 +71,6 @@ public class BrushableBlockEntityTranslator extends BlockEntityTranslator implem
|
||||||
// controls which side the item protrudes from
|
// controls which side the item protrudes from
|
||||||
bedrockNbt.putByte("brush_direction", hitDirection);
|
bedrockNbt.putByte("brush_direction", hitDirection);
|
||||||
// controls how much the item protrudes
|
// controls how much the item protrudes
|
||||||
bedrockNbt.putInt("brush_count", BlockStateValues.getBrushProgress(blockState));
|
bedrockNbt.putInt("brush_count", blockState.getValue(Properties.DUSTED));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
import org.cloudburstmc.nbt.NbtType;
|
import org.cloudburstmc.nbt.NbtType;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||||
|
@ -38,7 +39,7 @@ import java.util.List;
|
||||||
@BlockEntity(type = BlockEntityType.CAMPFIRE)
|
@BlockEntity(type = BlockEntityType.CAMPFIRE)
|
||||||
public class CampfireBlockEntityTranslator extends BlockEntityTranslator {
|
public class CampfireBlockEntityTranslator extends BlockEntityTranslator {
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) {
|
||||||
List<NbtMap> items = javaNbt.getList("Items", NbtType.COMPOUND);
|
List<NbtMap> items = javaNbt.getList("Items", NbtType.COMPOUND);
|
||||||
if (items != null) {
|
if (items != null) {
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
|
@ -27,7 +27,8 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||||
|
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.property.Properties;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||||
|
@ -35,12 +36,12 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType
|
||||||
@BlockEntity(type = BlockEntityType.COMMAND_BLOCK)
|
@BlockEntity(type = BlockEntityType.COMMAND_BLOCK)
|
||||||
public class CommandBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
public class CommandBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) {
|
||||||
if (javaNbt == null || javaNbt.size() < 5) {
|
if (javaNbt == null || javaNbt.size() < 5) {
|
||||||
return; // These values aren't here
|
return; // These values aren't here
|
||||||
}
|
}
|
||||||
// Java infers from the block state, but Bedrock needs it in the tag
|
// Java infers from the block state, but Bedrock needs it in the tag
|
||||||
bedrockNbt.putByte("conditionalMode", BlockStateValues.getCommandBlockValues().getOrDefault(blockState, (byte) 0));
|
bedrockNbt.putBoolean("conditionalMode", blockState.getValue(Properties.CONDITIONAL));
|
||||||
// Java and Bedrock values
|
// Java and Bedrock values
|
||||||
bedrockNbt.putByte("conditionMet", javaNbt.getByte("conditionMet"));
|
bedrockNbt.putByte("conditionMet", javaNbt.getByte("conditionMet"));
|
||||||
bedrockNbt.putByte("auto", javaNbt.getByte("auto"));
|
bedrockNbt.putByte("auto", javaNbt.getByte("auto"));
|
||||||
|
|
|
@ -28,6 +28,7 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
import org.cloudburstmc.nbt.NbtType;
|
import org.cloudburstmc.nbt.NbtType;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType
|
||||||
public class DecoratedPotBlockEntityTranslator extends BlockEntityTranslator {
|
public class DecoratedPotBlockEntityTranslator extends BlockEntityTranslator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) {
|
||||||
if (javaNbt == null) {
|
if (javaNbt == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,9 @@ import org.cloudburstmc.math.vector.Vector3i;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
import org.geysermc.geyser.level.block.DoubleChestValue;
|
import org.geysermc.geyser.level.block.property.Properties;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
|
import org.geysermc.geyser.level.physics.Direction;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.util.BlockEntityUtils;
|
import org.geysermc.geyser.util.BlockEntityUtils;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||||
|
@ -45,52 +47,40 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBlock(GeyserSession session, int blockState, Vector3i position) {
|
public void updateBlock(GeyserSession session, BlockState blockState, Vector3i position) {
|
||||||
NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(BlockEntityType.CHEST), position.getX(), position.getY(), position.getZ());
|
NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(BlockEntityType.CHEST), position.getX(), position.getY(), position.getZ());
|
||||||
translateTag(session, tagBuilder, null, blockState);
|
translateTag(session, tagBuilder, null, blockState);
|
||||||
BlockEntityUtils.updateBlockEntity(session, tagBuilder.build(), position);
|
BlockEntityUtils.updateBlockEntity(session, tagBuilder.build(), position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) {
|
||||||
DoubleChestValue chestValues = BlockStateValues.getDoubleChestValues().get(blockState);
|
int x = (int) bedrockNbt.get("x");
|
||||||
if (chestValues != null) {
|
int z = (int) bedrockNbt.get("z");
|
||||||
int x = (int) bedrockNbt.get("x");
|
translateChestValue(bedrockNbt, blockState, x, z);
|
||||||
int z = (int) bedrockNbt.get("z");
|
|
||||||
translateChestValue(bedrockNbt, chestValues, x, z);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add Bedrock block entity tags to a NbtMap based on Java properties
|
* Add Bedrock block entity tags to a NbtMap based on Java properties
|
||||||
*
|
*
|
||||||
* @param builder the NbtMapBuilder to apply properties to
|
* @param builder the NbtMapBuilder to apply properties to
|
||||||
* @param chestValues the position properties of this double chest
|
* @param state the BlockState of this double chest
|
||||||
* @param x the x position of this chest pair
|
* @param x the x position of this chest pair
|
||||||
* @param z the z position of this chest pair
|
* @param z the z position of this chest pair
|
||||||
*/
|
*/
|
||||||
public static void translateChestValue(NbtMapBuilder builder, DoubleChestValue chestValues, int x, int z) {
|
public static void translateChestValue(NbtMapBuilder builder, BlockState state, int x, int z) {
|
||||||
// Calculate the position of the other chest based on the Java block state
|
// Calculate the position of the other chest based on the Java block state
|
||||||
if (chestValues.isFacingEast()) {
|
Direction facing = state.getValue(Properties.HORIZONTAL_FACING);
|
||||||
if (chestValues.isDirectionPositive()) {
|
boolean isLeft = state.getValue(Properties.CHEST_TYPE).equals("left"); //TODO enum
|
||||||
// East
|
switch (facing) {
|
||||||
z = z + (chestValues.isLeft() ? 1 : -1);
|
case EAST -> z = z + (isLeft ? 1 : -1);
|
||||||
} else {
|
case WEST -> z = z + (isLeft ? -1 : 1);
|
||||||
// West
|
case SOUTH -> x = x + (isLeft ? -1 : 1);
|
||||||
z = z + (chestValues.isLeft() ? -1 : 1);
|
case NORTH -> x = x + (isLeft ? 1 : -1);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (chestValues.isDirectionPositive()) {
|
|
||||||
// South
|
|
||||||
x = x + (chestValues.isLeft() ? -1 : 1);
|
|
||||||
} else {
|
|
||||||
// North
|
|
||||||
x = x + (chestValues.isLeft() ? 1 : -1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
builder.putInt("pairx", x);
|
builder.putInt("pairx", x);
|
||||||
builder.putInt("pairz", z);
|
builder.putInt("pairz", z);
|
||||||
if (!chestValues.isLeft()) {
|
if (!isLeft) {
|
||||||
builder.putInt("pairlead", (byte) 1);
|
builder.putInt("pairlead", (byte) 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,11 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||||
|
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
|
||||||
public class EmptyBlockEntityTranslator extends BlockEntityTranslator {
|
public class EmptyBlockEntityTranslator extends BlockEntityTranslator {
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,13 +31,14 @@ import org.cloudburstmc.nbt.NbtList;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
import org.cloudburstmc.nbt.NbtType;
|
import org.cloudburstmc.nbt.NbtType;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||||
|
|
||||||
@BlockEntity(type = BlockEntityType.END_GATEWAY)
|
@BlockEntity(type = BlockEntityType.END_GATEWAY)
|
||||||
public class EndGatewayBlockEntityTranslator extends BlockEntityTranslator {
|
public class EndGatewayBlockEntityTranslator extends BlockEntityTranslator {
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) {
|
||||||
bedrockNbt.putInt("Age", (int) javaNbt.getLong("Age"));
|
bedrockNbt.putInt("Age", (int) javaNbt.getLong("Age"));
|
||||||
// Java sometimes does not provide this tag, but Bedrock crashes if it doesn't exist
|
// Java sometimes does not provide this tag, but Bedrock crashes if it doesn't exist
|
||||||
// Linked coordinates
|
// Linked coordinates
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.util.BlockEntityUtils;
|
import org.geysermc.geyser.util.BlockEntityUtils;
|
||||||
|
|
||||||
|
@ -75,12 +76,12 @@ public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBlock(GeyserSession session, int blockState, Vector3i position) {
|
public void updateBlock(GeyserSession session, BlockState blockState, Vector3i position) {
|
||||||
NbtMap tag = getTag(session, blockState, position);
|
NbtMap tag = getTag(session, blockState.javaId(), position);
|
||||||
BlockEntityUtils.updateBlockEntity(session, tag, position);
|
BlockEntityUtils.updateBlockEntity(session, tag, position);
|
||||||
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
||||||
updateBlockPacket.setDataLayer(0);
|
updateBlockPacket.setDataLayer(0);
|
||||||
updateBlockPacket.setDefinition(session.getBlockMappings().getBedrockBlock(blockState));
|
updateBlockPacket.setDefinition(session.getBlockMappings().getBedrockBlock(blockState.javaId()));
|
||||||
updateBlockPacket.setBlockPosition(position);
|
updateBlockPacket.setBlockPosition(position);
|
||||||
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS);
|
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS);
|
||||||
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK);
|
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK);
|
||||||
|
|
|
@ -29,13 +29,14 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||||
|
|
||||||
@BlockEntity(type = BlockEntityType.JIGSAW)
|
@BlockEntity(type = BlockEntityType.JIGSAW)
|
||||||
public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, BlockState blockState) {
|
||||||
if (javaNbt == null) {
|
if (javaNbt == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +47,7 @@ public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator impl
|
||||||
} else {
|
} else {
|
||||||
// Tag is not present in at least 1.14.4 Paper
|
// Tag is not present in at least 1.14.4 Paper
|
||||||
// Minecraft 1.18.1 deliberately has a fallback here, but not for any other value
|
// Minecraft 1.18.1 deliberately has a fallback here, but not for any other value
|
||||||
bedrockNbt.putString("joint", BlockStateValues.getHorizontalFacingJigsaws().contains(blockState) ? "aligned" : "rollable");
|
bedrockNbt.putString("joint", BlockStateValues.getHorizontalFacingJigsaws().contains(blockState.javaId()) ? "aligned" : "rollable"); // TODO
|
||||||
}
|
}
|
||||||
bedrockNbt.putString("name", javaNbt.getString("name"));
|
bedrockNbt.putString("name", javaNbt.getString("name"));
|
||||||
bedrockNbt.putString("target_pool", javaNbt.getString("target_pool"));
|
bedrockNbt.putString("target_pool", javaNbt.getString("target_pool"));
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.translator.level.block.entity;
|
package org.geysermc.geyser.translator.level.block.entity;
|
||||||
|
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType;
|
||||||
import org.cloudburstmc.math.vector.Vector3d;
|
import org.cloudburstmc.math.vector.Vector3d;
|
||||||
import org.cloudburstmc.math.vector.Vector3f;
|
import org.cloudburstmc.math.vector.Vector3f;
|
||||||
|
@ -222,10 +223,10 @@ public class PistonBlockEntity {
|
||||||
Vector3i blockInFront = position.add(orientation.getUnitVector());
|
Vector3i blockInFront = position.add(orientation.getUnitVector());
|
||||||
int blockId = session.getGeyser().getWorldManager().getBlockAt(session, blockInFront);
|
int blockId = session.getGeyser().getWorldManager().getBlockAt(session, blockInFront);
|
||||||
if (BlockStateValues.isPistonHead(blockId)) {
|
if (BlockStateValues.isPistonHead(blockId)) {
|
||||||
ChunkUtils.updateBlock(session, BlockStateValues.JAVA_AIR_ID, blockInFront);
|
ChunkUtils.updateBlock(session, Block.JAVA_AIR_ID, blockInFront);
|
||||||
} else if ((session.getGeyser().getPlatformType() == PlatformType.SPIGOT || session.getErosionHandler().isActive()) && blockId == BlockStateValues.JAVA_AIR_ID) {
|
} else if ((session.getGeyser().getPlatformType() == PlatformType.SPIGOT || session.getErosionHandler().isActive()) && blockId == Block.JAVA_AIR_ID) {
|
||||||
// Spigot removes the piston head from the cache, but we need to send the block update ourselves
|
// Spigot removes the piston head from the cache, but we need to send the block update ourselves
|
||||||
ChunkUtils.updateBlock(session, BlockStateValues.JAVA_AIR_ID, blockInFront);
|
ChunkUtils.updateBlock(session, Block.JAVA_AIR_ID, blockInFront);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,7 +256,7 @@ public class PistonBlockEntity {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int blockId = session.getGeyser().getWorldManager().getBlockAt(session, blockPos);
|
int blockId = session.getGeyser().getWorldManager().getBlockAt(session, blockPos);
|
||||||
if (blockId == BlockStateValues.JAVA_AIR_ID) {
|
if (blockId == Block.JAVA_AIR_ID) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (BlockStateValues.canPistonMoveBlock(blockId, action == PistonValueType.PUSHING)) {
|
if (BlockStateValues.canPistonMoveBlock(blockId, action == PistonValueType.PUSHING)) {
|
||||||
|
@ -278,7 +279,7 @@ public class PistonBlockEntity {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int adjacentBlockId = session.getGeyser().getWorldManager().getBlockAt(session, adjacentPos);
|
int adjacentBlockId = session.getGeyser().getWorldManager().getBlockAt(session, adjacentPos);
|
||||||
if (adjacentBlockId != BlockStateValues.JAVA_AIR_ID && BlockStateValues.isBlockAttached(blockId, adjacentBlockId) && BlockStateValues.canPistonMoveBlock(adjacentBlockId, false)) {
|
if (adjacentBlockId != Block.JAVA_AIR_ID && BlockStateValues.isBlockAttached(blockId, adjacentBlockId) && BlockStateValues.canPistonMoveBlock(adjacentBlockId, false)) {
|
||||||
// If it is another slime/honey block we need to check its adjacent blocks
|
// If it is another slime/honey block we need to check its adjacent blocks
|
||||||
if (BlockStateValues.isBlockSticky(adjacentBlockId)) {
|
if (BlockStateValues.isBlockSticky(adjacentBlockId)) {
|
||||||
blocksToCheck.add(adjacentPos);
|
blocksToCheck.add(adjacentPos);
|
||||||
|
@ -322,7 +323,7 @@ public class PistonBlockEntity {
|
||||||
*/
|
*/
|
||||||
private void removeBlocks() {
|
private void removeBlocks() {
|
||||||
for (Vector3i blockPos : attachedBlocks.keySet()) {
|
for (Vector3i blockPos : attachedBlocks.keySet()) {
|
||||||
ChunkUtils.updateBlock(session, BlockStateValues.JAVA_AIR_ID, blockPos);
|
ChunkUtils.updateBlock(session, Block.JAVA_AIR_ID, blockPos);
|
||||||
}
|
}
|
||||||
if (action != PistonValueType.PUSHING) {
|
if (action != PistonValueType.PUSHING) {
|
||||||
removePistonHead();
|
removePistonHead();
|
||||||
|
@ -560,7 +561,7 @@ public class PistonBlockEntity {
|
||||||
if (blockPos.equals(getPistonHeadPos())) {
|
if (blockPos.equals(getPistonHeadPos())) {
|
||||||
return BlockStateValues.getPistonHead(orientation);
|
return BlockStateValues.getPistonHead(orientation);
|
||||||
} else {
|
} else {
|
||||||
return attachedBlocks.getOrDefault(blockPos, BlockStateValues.JAVA_AIR_ID);
|
return attachedBlocks.getOrDefault(blockPos, Block.JAVA_AIR_ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,8 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.property.Properties;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.inventory.ShulkerInventoryTranslator;
|
import org.geysermc.geyser.translator.inventory.ShulkerInventoryTranslator;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||||
|
@ -40,12 +41,7 @@ public class ShulkerBoxBlockEntityTranslator extends BlockEntityTranslator imple
|
||||||
* where {@code tag} is passed as null.
|
* where {@code tag} is passed as null.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, BlockState blockState) {
|
||||||
byte direction = BlockStateValues.getShulkerBoxDirection(blockState);
|
bedrockNbt.putByte("facing", (byte) blockState.getValue(Properties.FACING).ordinal());
|
||||||
// Just in case...
|
|
||||||
if (direction == -1) {
|
|
||||||
direction = 1;
|
|
||||||
}
|
|
||||||
bedrockNbt.putByte("facing", direction);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
import org.cloudburstmc.nbt.NbtType;
|
import org.cloudburstmc.nbt.NbtType;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.text.ChatColor;
|
import org.geysermc.geyser.text.ChatColor;
|
||||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||||
|
@ -73,7 +74,7 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) {
|
||||||
bedrockNbt.putCompound("FrontText", translateSide(javaNbt.getCompound("front_text")));
|
bedrockNbt.putCompound("FrontText", translateSide(javaNbt.getCompound("front_text")));
|
||||||
bedrockNbt.putCompound("BackText", translateSide(javaNbt.getCompound("back_text")));
|
bedrockNbt.putCompound("BackText", translateSide(javaNbt.getCompound("back_text")));
|
||||||
bedrockNbt.putBoolean("IsWaxed", javaNbt.getBoolean("is_waxed"));
|
bedrockNbt.putBoolean("IsWaxed", javaNbt.getBoolean("is_waxed"));
|
||||||
|
|
|
@ -34,6 +34,8 @@ import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
|
import org.geysermc.geyser.level.block.property.Properties;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.session.cache.SkullCache;
|
import org.geysermc.geyser.session.cache.SkullCache;
|
||||||
import org.geysermc.geyser.skin.SkinProvider;
|
import org.geysermc.geyser.skin.SkinProvider;
|
||||||
|
@ -50,16 +52,19 @@ import java.util.concurrent.ExecutionException;
|
||||||
public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) {
|
||||||
byte skullVariant = BlockStateValues.getSkullVariant(blockState);
|
byte skullVariant = BlockStateValues.getSkullVariant(blockState.javaId()); // TODO
|
||||||
float rotation = BlockStateValues.getSkullRotation(blockState) * 22.5f;
|
|
||||||
// Just in case...
|
// Just in case...
|
||||||
if (skullVariant == -1) {
|
if (skullVariant == -1) {
|
||||||
skullVariant = 0;
|
skullVariant = 0;
|
||||||
}
|
}
|
||||||
bedrockNbt.putFloat("Rotation", rotation);
|
Integer rotation = blockState.getValue(Properties.ROTATION_16);
|
||||||
|
if (rotation != null) {
|
||||||
|
// Could be a wall skull block
|
||||||
|
bedrockNbt.putFloat("Rotation", rotation * 22.5f);
|
||||||
|
}
|
||||||
bedrockNbt.putByte("SkullType", skullVariant);
|
bedrockNbt.putByte("SkullType", skullVariant);
|
||||||
if (BlockStateValues.isSkullPowered(blockState)) {
|
if (blockState.getValue(Properties.POWERED)) {
|
||||||
bedrockNbt.putBoolean("MouthMoving", true);
|
bedrockNbt.putBoolean("MouthMoving", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||||
import org.geysermc.geyser.entity.EntityDefinition;
|
import org.geysermc.geyser.entity.EntityDefinition;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.registry.Registries;
|
import org.geysermc.geyser.registry.Registries;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||||
|
@ -40,7 +41,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType
|
||||||
public class SpawnerBlockEntityTranslator extends BlockEntityTranslator {
|
public class SpawnerBlockEntityTranslator extends BlockEntityTranslator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, int blockState) {
|
public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, BlockState blockState) {
|
||||||
if (javaNbt == null) {
|
if (javaNbt == null) {
|
||||||
return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState);
|
return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState);
|
||||||
}
|
}
|
||||||
|
@ -70,7 +71,7 @@ public class SpawnerBlockEntityTranslator extends BlockEntityTranslator {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) {
|
||||||
Object current;
|
Object current;
|
||||||
|
|
||||||
// TODO use primitive get and put methods
|
// TODO use primitive get and put methods
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror;
|
import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation;
|
import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.util.StructureBlockUtils;
|
import org.geysermc.geyser.util.StructureBlockUtils;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||||
|
@ -40,7 +41,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType
|
||||||
public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator {
|
public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, int blockState) {
|
public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, @Nullable NbtMap javaNbt, BlockState blockState) {
|
||||||
if (javaNbt == null) {
|
if (javaNbt == null) {
|
||||||
return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState);
|
return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState);
|
||||||
}
|
}
|
||||||
|
@ -73,7 +74,7 @@ public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) {
|
||||||
if (javaNbt.size() < 5) {
|
if (javaNbt.size() < 5) {
|
||||||
return; // These values aren't here
|
return; // These values aren't here
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ package org.geysermc.geyser.translator.level.block.entity;
|
||||||
|
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType
|
||||||
public class TrialSpawnerBlockEntityTranslator extends BlockEntityTranslator {
|
public class TrialSpawnerBlockEntityTranslator extends BlockEntityTranslator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, BlockState blockState) {
|
||||||
if (javaNbt == null) {
|
if (javaNbt == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.bedrock;
|
package org.geysermc.geyser.translator.protocol.bedrock;
|
||||||
|
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||||
import org.cloudburstmc.math.vector.Vector3i;
|
import org.cloudburstmc.math.vector.Vector3i;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.BlockPickRequestPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.BlockPickRequestPacket;
|
||||||
|
@ -48,7 +49,7 @@ public class BedrockBlockPickRequestTranslator extends PacketTranslator<BlockPic
|
||||||
int blockToPick = session.getGeyser().getWorldManager().getBlockAt(session, vector.getX(), vector.getY(), vector.getZ());
|
int blockToPick = session.getGeyser().getWorldManager().getBlockAt(session, vector.getX(), vector.getY(), vector.getZ());
|
||||||
|
|
||||||
// Block is air - chunk caching is probably off
|
// Block is air - chunk caching is probably off
|
||||||
if (blockToPick == BlockStateValues.JAVA_AIR_ID) {
|
if (blockToPick == Block.JAVA_AIR_ID) {
|
||||||
// Check for an item frame since the client thinks that's a block when it's an entity in Java
|
// Check for an item frame since the client thinks that's a block when it's an entity in Java
|
||||||
ItemFrameEntity entity = ItemFrameEntity.getItemFrameEntity(session, packet.getBlockPosition());
|
ItemFrameEntity entity = ItemFrameEntity.getItemFrameEntity(session, packet.getBlockPosition());
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
|
|
|
@ -57,6 +57,7 @@ import org.geysermc.geyser.item.type.BoatItem;
|
||||||
import org.geysermc.geyser.item.type.Item;
|
import org.geysermc.geyser.item.type.Item;
|
||||||
import org.geysermc.geyser.item.type.SpawnEggItem;
|
import org.geysermc.geyser.item.type.SpawnEggItem;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
import org.geysermc.geyser.registry.BlockRegistries;
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.session.cache.SkullCache;
|
import org.geysermc.geyser.session.cache.SkullCache;
|
||||||
|
@ -444,7 +445,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
||||||
session.getWorldCache().markPositionInSequence(packet.getBlockPosition());
|
session.getWorldCache().markPositionInSequence(packet.getBlockPosition());
|
||||||
// -1 means we don't know what block they're breaking
|
// -1 means we don't know what block they're breaking
|
||||||
if (blockState == -1) {
|
if (blockState == -1) {
|
||||||
blockState = BlockStateValues.JAVA_AIR_ID;
|
blockState = Block.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
LevelEventPacket blockBreakPacket = new LevelEventPacket();
|
LevelEventPacket blockBreakPacket = new LevelEventPacket();
|
||||||
|
|
|
@ -39,6 +39,7 @@ import org.geysermc.geyser.entity.type.ItemFrameEntity;
|
||||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
import org.geysermc.geyser.network.GameProtocol;
|
import org.geysermc.geyser.network.GameProtocol;
|
||||||
import org.geysermc.geyser.registry.BlockRegistries;
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
import org.geysermc.geyser.registry.type.BlockMapping;
|
import org.geysermc.geyser.registry.type.BlockMapping;
|
||||||
|
@ -197,7 +198,7 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
|
||||||
}
|
}
|
||||||
int breakingBlock = session.getBreakingBlock();
|
int breakingBlock = session.getBreakingBlock();
|
||||||
if (breakingBlock == -1) {
|
if (breakingBlock == -1) {
|
||||||
breakingBlock = BlockStateValues.JAVA_AIR_ID;
|
breakingBlock = Block.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3f vectorFloat = vector.toFloat();
|
Vector3f vectorFloat = vector.toFloat();
|
||||||
|
|
|
@ -33,7 +33,8 @@ import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation;
|
import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
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.RequiresBlockState;
|
import org.geysermc.geyser.translator.level.block.entity.RequiresBlockState;
|
||||||
|
@ -58,11 +59,11 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator<ClientboundB
|
||||||
BlockEntityTranslator translator = BlockEntityUtils.getBlockEntityTranslator(type);
|
BlockEntityTranslator translator = BlockEntityUtils.getBlockEntityTranslator(type);
|
||||||
// The Java block state is used in BlockEntityTranslator.translateTag() to make up for some inconsistencies
|
// The Java block state is used in BlockEntityTranslator.translateTag() to make up for some inconsistencies
|
||||||
// between Java block states and Bedrock block entity data
|
// between Java block states and Bedrock block entity data
|
||||||
int blockState;
|
BlockState blockState;
|
||||||
if (translator instanceof RequiresBlockState) {
|
if (translator instanceof RequiresBlockState) {
|
||||||
blockState = session.getGeyser().getWorldManager().getBlockAt(session, packet.getPosition());
|
blockState = BlockRegistries.BLOCK_STATES.get(session.getGeyser().getWorldManager().getBlockAt(session, packet.getPosition()));
|
||||||
} else {
|
} else {
|
||||||
blockState = BlockStateValues.JAVA_AIR_ID;
|
blockState = BlockRegistries.BLOCK_STATES.get(0); //TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3i position = packet.getPosition();
|
Vector3i position = packet.getPosition();
|
||||||
|
@ -71,7 +72,7 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator<ClientboundB
|
||||||
// Check for custom skulls.
|
// Check for custom skulls.
|
||||||
boolean hasCustomHeadBlock = false;
|
boolean hasCustomHeadBlock = false;
|
||||||
if (session.getPreferencesCache().showCustomSkulls() && packet.getNbt() != null && packet.getNbt().containsKey("profile")) {
|
if (session.getPreferencesCache().showCustomSkulls() && packet.getNbt() != null && packet.getNbt().containsKey("profile")) {
|
||||||
BlockDefinition blockDefinition = SkullBlockEntityTranslator.translateSkull(session, packet.getNbt(), position, blockState);
|
BlockDefinition blockDefinition = SkullBlockEntityTranslator.translateSkull(session, packet.getNbt(), position, blockState.javaId());
|
||||||
if (blockDefinition != null) {
|
if (blockDefinition != null) {
|
||||||
hasCustomHeadBlock = true;
|
hasCustomHeadBlock = true;
|
||||||
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.java.level;
|
package org.geysermc.geyser.translator.protocol.java.level;
|
||||||
|
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.*;
|
import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.*;
|
||||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundBlockEventPacket;
|
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundBlockEventPacket;
|
||||||
import org.cloudburstmc.math.vector.Vector3i;
|
import org.cloudburstmc.math.vector.Vector3i;
|
||||||
|
@ -82,7 +83,7 @@ public class JavaBlockEventTranslator extends PacketTranslator<ClientboundBlockE
|
||||||
if (action != PistonValueType.CANCELLED_MID_PUSH) {
|
if (action != PistonValueType.CANCELLED_MID_PUSH) {
|
||||||
Vector3i blockInFrontPos = position.add(direction.getUnitVector());
|
Vector3i blockInFrontPos = position.add(direction.getUnitVector());
|
||||||
int blockInFront = session.getGeyser().getWorldManager().getBlockAt(session, blockInFrontPos);
|
int blockInFront = session.getGeyser().getWorldManager().getBlockAt(session, blockInFrontPos);
|
||||||
if (blockInFront != BlockStateValues.JAVA_AIR_ID) {
|
if (blockInFront != Block.JAVA_AIR_ID) {
|
||||||
// Piston pulled something
|
// Piston pulled something
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.java.level;
|
package org.geysermc.geyser.translator.protocol.java.level;
|
||||||
|
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundExplodePacket;
|
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundExplodePacket;
|
||||||
import org.cloudburstmc.math.vector.Vector3f;
|
import org.cloudburstmc.math.vector.Vector3f;
|
||||||
import org.cloudburstmc.math.vector.Vector3i;
|
import org.cloudburstmc.math.vector.Vector3i;
|
||||||
|
@ -58,7 +59,7 @@ public class JavaExplodeTranslator extends PacketTranslator<ClientboundExplodePa
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Vector3i position : packet.getExploded()) {
|
for (Vector3i position : packet.getExploded()) {
|
||||||
Vector3i pos = Vector3i.from(packet.getX() + position.getX(), packet.getY() + position.getY(), packet.getZ() + position.getZ());
|
Vector3i pos = Vector3i.from(packet.getX() + position.getX(), packet.getY() + position.getY(), packet.getZ() + position.getZ());
|
||||||
ChunkUtils.updateBlock(session, BlockStateValues.JAVA_AIR_ID, pos);
|
ChunkUtils.updateBlock(session, Block.JAVA_AIR_ID, pos);
|
||||||
builder.putFloat("pos" + i + "x", pos.getX());
|
builder.putFloat("pos" + i + "x", pos.getX());
|
||||||
builder.putFloat("pos" + i + "y", pos.getY());
|
builder.putFloat("pos" + i + "y", pos.getY());
|
||||||
builder.putFloat("pos" + i + "z", pos.getZ());
|
builder.putFloat("pos" + i + "z", pos.getZ());
|
||||||
|
|
|
@ -42,6 +42,9 @@ import org.geysermc.erosion.util.LecternUtils;
|
||||||
import org.geysermc.geyser.entity.type.ItemFrameEntity;
|
import org.geysermc.geyser.entity.type.ItemFrameEntity;
|
||||||
import org.geysermc.geyser.level.BedrockDimension;
|
import org.geysermc.geyser.level.BedrockDimension;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
|
import org.geysermc.geyser.level.block.property.Properties;
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.level.chunk.BlockStorage;
|
import org.geysermc.geyser.level.chunk.BlockStorage;
|
||||||
import org.geysermc.geyser.level.chunk.GeyserChunkSection;
|
import org.geysermc.geyser.level.chunk.GeyserChunkSection;
|
||||||
import org.geysermc.geyser.level.chunk.bitarray.BitArray;
|
import org.geysermc.geyser.level.chunk.bitarray.BitArray;
|
||||||
|
@ -175,7 +178,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||||
// Extended collision blocks
|
// Extended collision blocks
|
||||||
if (useExtendedCollisions) {
|
if (useExtendedCollisions) {
|
||||||
if (EXTENDED_COLLISIONS_STORAGE.get().get(yzx, sectionY) != 0) {
|
if (EXTENDED_COLLISIONS_STORAGE.get().get(yzx, sectionY) != 0) {
|
||||||
if (javaId == BlockStateValues.JAVA_AIR_ID) {
|
if (javaId == Block.JAVA_AIR_ID) {
|
||||||
section.getBlockStorageArray()[0].setFullBlock(xzy, EXTENDED_COLLISIONS_STORAGE.get().get(yzx, sectionY));
|
section.getBlockStorageArray()[0].setFullBlock(xzy, EXTENDED_COLLISIONS_STORAGE.get().get(yzx, sectionY));
|
||||||
}
|
}
|
||||||
EXTENDED_COLLISIONS_STORAGE.get().set(yzx, 0, sectionY);
|
EXTENDED_COLLISIONS_STORAGE.get().set(yzx, 0, sectionY);
|
||||||
|
@ -238,7 +241,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||||
waterloggedPaletteIds.set(i);
|
waterloggedPaletteIds.set(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (javaId == BlockStateValues.JAVA_AIR_ID) {
|
if (javaId == Block.JAVA_AIR_ID) {
|
||||||
airPaletteId = i;
|
airPaletteId = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,9 +399,9 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||||
|
|
||||||
// Get the Java block state ID from block entity position
|
// Get the Java block state ID from block entity position
|
||||||
DataPalette section = javaChunks[(y >> 4) - yOffset];
|
DataPalette section = javaChunks[(y >> 4) - yOffset];
|
||||||
int blockState = section.get(x, y & 0xF, z);
|
BlockState blockState = BlockRegistries.BLOCK_STATES.get(section.get(x, y & 0xF, z));
|
||||||
|
|
||||||
if (type == BlockEntityType.LECTERN && BlockStateValues.getLecternBookStates().get(blockState)) {
|
if (type == BlockEntityType.LECTERN && blockState.getValue(Properties.HAS_BOOK)) {
|
||||||
// If getLecternBookStates is false, let's just treat it like a normal block entity
|
// If getLecternBookStates is false, let's just treat it like a normal block entity
|
||||||
// Fill in tag with a default value
|
// Fill in tag with a default value
|
||||||
NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(x + chunkBlockX, y, z + chunkBlockZ, 1);
|
NbtMapBuilder lecternTag = LecternUtils.getBaseLecternTag(x + chunkBlockX, y, z + chunkBlockZ, 1);
|
||||||
|
@ -419,7 +422,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||||
|
|
||||||
// Check for custom skulls
|
// Check for custom skulls
|
||||||
if (session.getPreferencesCache().showCustomSkulls() && type == BlockEntityType.SKULL && tag != null && tag.containsKey("profile")) {
|
if (session.getPreferencesCache().showCustomSkulls() && type == BlockEntityType.SKULL && tag != null && tag.containsKey("profile")) {
|
||||||
BlockDefinition blockDefinition = SkullBlockEntityTranslator.translateSkull(session, tag, Vector3i.from(x + chunkBlockX, y, z + chunkBlockZ), blockState);
|
BlockDefinition blockDefinition = SkullBlockEntityTranslator.translateSkull(session, tag, Vector3i.from(x + chunkBlockX, y, z + chunkBlockZ), blockState.javaId());
|
||||||
if (blockDefinition != null) {
|
if (blockDefinition != null) {
|
||||||
int bedrockSectionY = (y >> 4) - (bedrockDimension.minY() >> 4);
|
int bedrockSectionY = (y >> 4) - (bedrockDimension.minY() >> 4);
|
||||||
int subChunkIndex = (y >> 4) + (bedrockDimension.minY() >> 4);
|
int subChunkIndex = (y >> 4) + (bedrockDimension.minY() >> 4);
|
||||||
|
|
|
@ -41,6 +41,8 @@ import org.geysermc.geyser.entity.type.ItemFrameEntity;
|
||||||
import org.geysermc.geyser.level.BedrockDimension;
|
import org.geysermc.geyser.level.BedrockDimension;
|
||||||
import org.geysermc.geyser.level.JavaDimension;
|
import org.geysermc.geyser.level.JavaDimension;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
|
import org.geysermc.geyser.level.block.type.BlockState;
|
||||||
import org.geysermc.geyser.level.chunk.BlockStorage;
|
import org.geysermc.geyser.level.chunk.BlockStorage;
|
||||||
import org.geysermc.geyser.level.chunk.GeyserChunkSection;
|
import org.geysermc.geyser.level.chunk.GeyserChunkSection;
|
||||||
import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray;
|
import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray;
|
||||||
|
@ -50,8 +52,6 @@ import org.geysermc.geyser.session.cache.SkullCache;
|
||||||
import org.geysermc.geyser.text.GeyserLocale;
|
import org.geysermc.geyser.text.GeyserLocale;
|
||||||
import org.geysermc.geyser.translator.level.block.entity.BedrockOnlyBlockEntity;
|
import org.geysermc.geyser.translator.level.block.entity.BedrockOnlyBlockEntity;
|
||||||
|
|
||||||
import static org.geysermc.geyser.level.block.BlockStateValues.JAVA_AIR_ID;
|
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class ChunkUtils {
|
public class ChunkUtils {
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ public class ChunkUtils {
|
||||||
// Checks for item frames so they aren't tripped up and removed
|
// Checks for item frames so they aren't tripped up and removed
|
||||||
ItemFrameEntity itemFrameEntity = ItemFrameEntity.getItemFrameEntity(session, position);
|
ItemFrameEntity itemFrameEntity = ItemFrameEntity.getItemFrameEntity(session, position);
|
||||||
if (itemFrameEntity != null) {
|
if (itemFrameEntity != null) {
|
||||||
if (blockState == JAVA_AIR_ID) { // Item frame is still present and no block overrides that; refresh it
|
if (blockState == Block.JAVA_AIR_ID) { // Item frame is still present and no block overrides that; refresh it
|
||||||
itemFrameEntity.updateBlock(true);
|
itemFrameEntity.updateBlock(true);
|
||||||
// Still update the chunk cache with the new block if updateBlock is called
|
// Still update the chunk cache with the new block if updateBlock is called
|
||||||
return;
|
return;
|
||||||
|
@ -180,21 +180,21 @@ public class ChunkUtils {
|
||||||
BlockDefinition aboveBedrockExtendedCollisionDefinition = session.getBlockMappings().getExtendedCollisionBoxes().get(blockState);
|
BlockDefinition aboveBedrockExtendedCollisionDefinition = session.getBlockMappings().getExtendedCollisionBoxes().get(blockState);
|
||||||
int belowBlock = session.getGeyser().getWorldManager().getBlockAt(session, position.getX(), position.getY() - 1, position.getZ());
|
int belowBlock = session.getGeyser().getWorldManager().getBlockAt(session, position.getX(), position.getY() - 1, position.getZ());
|
||||||
BlockDefinition belowBedrockExtendedCollisionDefinition = session.getBlockMappings().getExtendedCollisionBoxes().get(belowBlock);
|
BlockDefinition belowBedrockExtendedCollisionDefinition = session.getBlockMappings().getExtendedCollisionBoxes().get(belowBlock);
|
||||||
if (belowBedrockExtendedCollisionDefinition != null && blockState == BlockStateValues.JAVA_AIR_ID) {
|
if (belowBedrockExtendedCollisionDefinition != null && blockState == Block.JAVA_AIR_ID) {
|
||||||
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
||||||
updateBlockPacket.setDataLayer(0);
|
updateBlockPacket.setDataLayer(0);
|
||||||
updateBlockPacket.setBlockPosition(position);
|
updateBlockPacket.setBlockPosition(position);
|
||||||
updateBlockPacket.setDefinition(belowBedrockExtendedCollisionDefinition);
|
updateBlockPacket.setDefinition(belowBedrockExtendedCollisionDefinition);
|
||||||
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK);
|
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK);
|
||||||
session.sendUpstreamPacket(updateBlockPacket);
|
session.sendUpstreamPacket(updateBlockPacket);
|
||||||
} else if (aboveBedrockExtendedCollisionDefinition != null && aboveBlock == BlockStateValues.JAVA_AIR_ID) {
|
} else if (aboveBedrockExtendedCollisionDefinition != null && aboveBlock == Block.JAVA_AIR_ID) {
|
||||||
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
||||||
updateBlockPacket.setDataLayer(0);
|
updateBlockPacket.setDataLayer(0);
|
||||||
updateBlockPacket.setBlockPosition(position.add(0, 1, 0));
|
updateBlockPacket.setBlockPosition(position.add(0, 1, 0));
|
||||||
updateBlockPacket.setDefinition(aboveBedrockExtendedCollisionDefinition);
|
updateBlockPacket.setDefinition(aboveBedrockExtendedCollisionDefinition);
|
||||||
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK);
|
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK);
|
||||||
session.sendUpstreamPacket(updateBlockPacket);
|
session.sendUpstreamPacket(updateBlockPacket);
|
||||||
} else if (aboveBlock == BlockStateValues.JAVA_AIR_ID) {
|
} else if (aboveBlock == Block.JAVA_AIR_ID) {
|
||||||
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
||||||
updateBlockPacket.setDataLayer(0);
|
updateBlockPacket.setDataLayer(0);
|
||||||
updateBlockPacket.setBlockPosition(position.add(0, 1, 0));
|
updateBlockPacket.setBlockPosition(position.add(0, 1, 0));
|
||||||
|
@ -211,7 +211,7 @@ public class ChunkUtils {
|
||||||
for (BedrockOnlyBlockEntity bedrockOnlyBlockEntity : BlockEntityUtils.BEDROCK_ONLY_BLOCK_ENTITIES) {
|
for (BedrockOnlyBlockEntity bedrockOnlyBlockEntity : BlockEntityUtils.BEDROCK_ONLY_BLOCK_ENTITIES) {
|
||||||
if (bedrockOnlyBlockEntity.isBlock(blockState)) {
|
if (bedrockOnlyBlockEntity.isBlock(blockState)) {
|
||||||
// Flower pots are block entities only in Bedrock and are not updated anywhere else like note blocks
|
// Flower pots are block entities only in Bedrock and are not updated anywhere else like note blocks
|
||||||
bedrockOnlyBlockEntity.updateBlock(session, blockState, position);
|
bedrockOnlyBlockEntity.updateBlock(session, BlockState.of(blockState), position); //TODO blockState
|
||||||
break; //No block will be a part of two classes
|
break; //No block will be a part of two classes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
import org.geysermc.geyser.registry.BlockRegistries;
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
import org.geysermc.geyser.registry.Registries;
|
import org.geysermc.geyser.registry.Registries;
|
||||||
import org.geysermc.geyser.registry.type.SoundMapping;
|
import org.geysermc.geyser.registry.type.SoundMapping;
|
||||||
|
@ -147,7 +148,7 @@ public final class SoundUtils {
|
||||||
soundPacket.setExtraData(soundMapping.getExtraData() + (int)(Math.round((Math.log10(pitch) / Math.log10(2)) * 12)) + 12);
|
soundPacket.setExtraData(soundMapping.getExtraData() + (int)(Math.round((Math.log10(pitch) / Math.log10(2)) * 12)) + 12);
|
||||||
} else if (sound == SoundEvent.PLACE && soundMapping.getExtraData() == -1) {
|
} else if (sound == SoundEvent.PLACE && soundMapping.getExtraData() == -1) {
|
||||||
if (!soundMapping.getIdentifier().equals(":")) {
|
if (!soundMapping.getIdentifier().equals(":")) {
|
||||||
int javaId = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getOrDefault(soundMapping.getIdentifier(), BlockStateValues.JAVA_AIR_ID);
|
int javaId = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getOrDefault(soundMapping.getIdentifier(), Block.JAVA_AIR_ID);
|
||||||
soundPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(javaId));
|
soundPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(javaId));
|
||||||
} else {
|
} else {
|
||||||
session.getGeyser().getLogger().debug("PLACE sound mapping identifier was invalid! Please report: " + soundMapping);
|
session.getGeyser().getLogger().debug("PLACE sound mapping identifier was invalid! Please report: " + soundMapping);
|
||||||
|
|
|
@ -29,6 +29,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
import org.geysermc.cumulus.form.SimpleForm;
|
import org.geysermc.cumulus.form.SimpleForm;
|
||||||
import org.geysermc.cumulus.util.FormImage;
|
import org.geysermc.cumulus.util.FormImage;
|
||||||
import org.geysermc.geyser.item.type.Item;
|
import org.geysermc.geyser.item.type.Item;
|
||||||
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
import org.geysermc.geyser.registry.BlockRegistries;
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
import org.geysermc.geyser.registry.Registries;
|
import org.geysermc.geyser.registry.Registries;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
@ -93,10 +94,10 @@ public class StatisticsUtils {
|
||||||
|
|
||||||
for (Object2IntMap.Entry<Statistic> entry : session.getStatistics().object2IntEntrySet()) {
|
for (Object2IntMap.Entry<Statistic> entry : session.getStatistics().object2IntEntrySet()) {
|
||||||
if (entry.getKey() instanceof BreakBlockStatistic statistic) {
|
if (entry.getKey() instanceof BreakBlockStatistic statistic) {
|
||||||
String identifier = BlockRegistries.CLEAN_JAVA_IDENTIFIERS.get(statistic.getId());
|
Block block = BlockRegistries.JAVA_BLOCKS_TO_RENAME.get(statistic.getId());
|
||||||
if (identifier != null) {
|
if (block != null) {
|
||||||
String block = identifier.replace("minecraft:", "block.minecraft.");
|
String identifier = block.javaIdentifier().replace("minecraft:", "block.minecraft.");
|
||||||
content.add(block + ": " + entry.getIntValue());
|
content.add(identifier + ": " + entry.getIntValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,7 @@ fastutil-int-byte-maps = { group = "com.nukkitx.fastutil", name = "fastutil-int-
|
||||||
fastutil-int-boolean-maps = { group = "com.nukkitx.fastutil", name = "fastutil-int-boolean-maps", version.ref = "fastutil" }
|
fastutil-int-boolean-maps = { group = "com.nukkitx.fastutil", name = "fastutil-int-boolean-maps", version.ref = "fastutil" }
|
||||||
fastutil-object-int-maps = { group = "com.nukkitx.fastutil", name = "fastutil-object-int-maps", version.ref = "fastutil" }
|
fastutil-object-int-maps = { group = "com.nukkitx.fastutil", name = "fastutil-object-int-maps", version.ref = "fastutil" }
|
||||||
fastutil-object-object-maps = { group = "com.nukkitx.fastutil", name = "fastutil-object-object-maps", version.ref = "fastutil" }
|
fastutil-object-object-maps = { group = "com.nukkitx.fastutil", name = "fastutil-object-object-maps", version.ref = "fastutil" }
|
||||||
|
fastutil-reference-object-maps = { group = "com.nukkitx.fastutil", name = "fastutil-reference-object-maps", version.ref = "fastutil" }
|
||||||
|
|
||||||
adventure-text-serializer-gson = { group = "net.kyori", name = "adventure-text-serializer-gson", version.ref = "adventure" } # Remove when we remove our Adventure bump
|
adventure-text-serializer-gson = { group = "net.kyori", name = "adventure-text-serializer-gson", version.ref = "adventure" } # Remove when we remove our Adventure bump
|
||||||
adventure-text-serializer-legacy = { group = "net.kyori", name = "adventure-text-serializer-legacy", version.ref = "adventure" }
|
adventure-text-serializer-legacy = { group = "net.kyori", name = "adventure-text-serializer-legacy", version.ref = "adventure" }
|
||||||
|
@ -142,7 +143,7 @@ blossom = { id = "net.kyori.blossom", version.ref = "blossom" }
|
||||||
|
|
||||||
[bundles]
|
[bundles]
|
||||||
jackson = [ "jackson-annotations", "jackson-core", "jackson-dataformat-yaml" ]
|
jackson = [ "jackson-annotations", "jackson-core", "jackson-dataformat-yaml" ]
|
||||||
fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps" ]
|
fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps", "fastutil-reference-object-maps" ]
|
||||||
adventure = [ "adventure-text-serializer-gson", "adventure-text-serializer-legacy", "adventure-text-serializer-plain" ]
|
adventure = [ "adventure-text-serializer-gson", "adventure-text-serializer-legacy", "adventure-text-serializer-plain" ]
|
||||||
log4j = [ "log4j-api", "log4j-core", "log4j-slf4j2-impl" ]
|
log4j = [ "log4j-api", "log4j-core", "log4j-slf4j2-impl" ]
|
||||||
jline = [ "jline-terminal", "jline-terminal-jna", "jline-reader" ]
|
jline = [ "jline-terminal", "jline-terminal-jna", "jline-reader" ]
|
||||||
|
|
Loading…
Reference in a new issue