Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-28 00:50:20 +01:00
You can connect now. Command translation doesn't work though.
Dieser Commit ist enthalten in:
Ursprung
ebcb82c7e7
Commit
08c15a86ec
@ -37,7 +37,7 @@ import java.util.Map;
|
|||||||
public final class GeyserDirtyMetadata {
|
public final class GeyserDirtyMetadata {
|
||||||
private final Map<EntityDataType<?>, Object> metadata = new Object2ObjectLinkedOpenHashMap<>();
|
private final Map<EntityDataType<?>, Object> metadata = new Object2ObjectLinkedOpenHashMap<>();
|
||||||
|
|
||||||
public void put(EntityDataType<?> entityData, Object value) {
|
public <T> void put(EntityDataType<T> entityData, T value) {
|
||||||
metadata.put(entityData, value);
|
metadata.put(entityData, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ public class BoatEntity extends Entity {
|
|||||||
super(session, entityId, geyserId, uuid, definition, position.add(0d, definition.offset(), 0d), motion, yaw + 90, 0, yaw + 90);
|
super(session, entityId, geyserId, uuid, definition, position.add(0d, definition.offset(), 0d), motion, yaw + 90, 0, yaw + 90);
|
||||||
|
|
||||||
// Required to be able to move on land 1.16.200+ or apply gravity not in the water 1.16.100+
|
// Required to be able to move on land 1.16.200+ or apply gravity not in the water 1.16.100+
|
||||||
dirtyMetadata.put(EntityDataTypes.IS_BUOYANT, (byte) 1);
|
dirtyMetadata.put(EntityDataTypes.IS_BUOYANT, true);
|
||||||
dirtyMetadata.put(EntityDataTypes.BUOYANCY_DATA, BUOYANCY_DATA);
|
dirtyMetadata.put(EntityDataTypes.BUOYANCY_DATA, BUOYANCY_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ public class CommandBlockMinecartEntity extends DefaultBlockMinecartEntity {
|
|||||||
dirtyMetadata.put(EntityDataTypes.CONTAINER_TYPE, (byte) 16);
|
dirtyMetadata.put(EntityDataTypes.CONTAINER_TYPE, (byte) 16);
|
||||||
dirtyMetadata.put(EntityDataTypes.CONTAINER_SIZE, 1);
|
dirtyMetadata.put(EntityDataTypes.CONTAINER_SIZE, 1);
|
||||||
// Required, or else the client does not bother to send a packet back with the new information
|
// Required, or else the client does not bother to send a packet back with the new information
|
||||||
dirtyMetadata.put(EntityDataTypes.COMMAND_BLOCK_ENABLED, (byte) 1);
|
dirtyMetadata.put(EntityDataTypes.COMMAND_BLOCK_ENABLED, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,7 +62,7 @@ public class ThrownPotionEntity extends ThrowableItemEntity {
|
|||||||
if (potionTag instanceof StringTag) {
|
if (potionTag instanceof StringTag) {
|
||||||
Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue());
|
Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue());
|
||||||
if (potion != null) {
|
if (potion != null) {
|
||||||
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, potion.getBedrockId());
|
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, (int) potion.getBedrockId());
|
||||||
setFlag(EntityFlag.ENCHANTED, !NON_ENCHANTED_POTIONS.contains(potion));
|
setFlag(EntityFlag.ENCHANTED, !NON_ENCHANTED_POTIONS.contains(potion));
|
||||||
} else {
|
} else {
|
||||||
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0);
|
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0);
|
||||||
|
@ -47,13 +47,13 @@ public class TippedArrowEntity extends AbstractArrowEntity {
|
|||||||
int potionColor = entityMetadata.getPrimitiveValue();
|
int potionColor = entityMetadata.getPrimitiveValue();
|
||||||
// -1 means no color
|
// -1 means no color
|
||||||
if (potionColor == -1) {
|
if (potionColor == -1) {
|
||||||
dirtyMetadata.put(EntityDataTypes.CUSTOM_DISPLAY, 0);
|
dirtyMetadata.put(EntityDataTypes.CUSTOM_DISPLAY, (byte) 0);
|
||||||
} else {
|
} else {
|
||||||
TippedArrowPotion potion = TippedArrowPotion.getByJavaColor(potionColor);
|
TippedArrowPotion potion = TippedArrowPotion.getByJavaColor(potionColor);
|
||||||
if (potion != null && potion.getJavaColor() != -1) {
|
if (potion != null && potion.getJavaColor() != -1) {
|
||||||
dirtyMetadata.put(EntityDataTypes.CUSTOM_DISPLAY, (byte) potion.getBedrockId());
|
dirtyMetadata.put(EntityDataTypes.CUSTOM_DISPLAY, (byte) potion.getBedrockId());
|
||||||
} else {
|
} else {
|
||||||
dirtyMetadata.put(EntityDataTypes.CUSTOM_DISPLAY, 0);
|
dirtyMetadata.put(EntityDataTypes.CUSTOM_DISPLAY, (byte) 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ public class ShulkerEntity extends GolemEntity {
|
|||||||
|
|
||||||
public void setAttachedFace(EntityMetadata<Direction, ?> entityMetadata) {
|
public void setAttachedFace(EntityMetadata<Direction, ?> entityMetadata) {
|
||||||
Direction direction = entityMetadata.getValue();
|
Direction direction = entityMetadata.getValue();
|
||||||
dirtyMetadata.put(EntityDataTypes.SHULKER_ATTACH_FACE, (byte) direction.ordinal());
|
dirtyMetadata.put(EntityDataTypes.SHULKER_ATTACH_FACE, direction.ordinal());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setShulkerHeight(ByteEntityMetadata entityMetadata) {
|
public void setShulkerHeight(ByteEntityMetadata entityMetadata) {
|
||||||
@ -56,7 +56,7 @@ public class ShulkerEntity extends GolemEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setShulkerColor(ByteEntityMetadata entityMetadata) {
|
public void setShulkerColor(ByteEntityMetadata entityMetadata) {
|
||||||
byte color = ((ByteEntityMetadata) entityMetadata).getPrimitiveValue();
|
byte color = entityMetadata.getPrimitiveValue();
|
||||||
if (color == 16) {
|
if (color == 16) {
|
||||||
// 16 is default on both editions
|
// 16 is default on both editions
|
||||||
dirtyMetadata.put(EntityDataTypes.VARIANT, 16);
|
dirtyMetadata.put(EntityDataTypes.VARIANT, 16);
|
||||||
|
@ -288,7 +288,7 @@ public class PlayerEntity extends LivingEntity {
|
|||||||
ParrotEntity parrot = new ParrotEntity(session, 0, session.getEntityCache().getNextEntityId().incrementAndGet(),
|
ParrotEntity parrot = new ParrotEntity(session, 0, session.getEntityCache().getNextEntityId().incrementAndGet(),
|
||||||
null, EntityDefinitions.PARROT, position, motion, getYaw(), getPitch(), getHeadYaw());
|
null, EntityDefinitions.PARROT, position, motion, getYaw(), getPitch(), getHeadYaw());
|
||||||
parrot.spawnEntity();
|
parrot.spawnEntity();
|
||||||
parrot.getDirtyMetadata().put(EntityDataTypes.VARIANT, tag.get("Variant").getValue());
|
parrot.getDirtyMetadata().put(EntityDataTypes.VARIANT, (Integer) tag.get("Variant").getValue());
|
||||||
// Different position whether the parrot is left or right
|
// Different position whether the parrot is left or right
|
||||||
float offset = isLeft ? 0.4f : -0.4f;
|
float offset = isLeft ? 0.4f : -0.4f;
|
||||||
parrot.getDirtyMetadata().put(EntityDataTypes.SEAT_OFFSET, Vector3f.from(offset, -0.22, -0.1));
|
parrot.getDirtyMetadata().put(EntityDataTypes.SEAT_OFFSET, Vector3f.from(offset, -0.22, -0.1));
|
||||||
|
@ -244,9 +244,9 @@ public class SessionPlayerEntity extends PlayerEntity {
|
|||||||
if (pos != null) {
|
if (pos != null) {
|
||||||
dirtyMetadata.put(EntityDataTypes.PLAYER_LAST_DEATH_POS, pos.getPosition());
|
dirtyMetadata.put(EntityDataTypes.PLAYER_LAST_DEATH_POS, pos.getPosition());
|
||||||
dirtyMetadata.put(EntityDataTypes.PLAYER_LAST_DEATH_DIMENSION, DimensionUtils.javaToBedrock(pos.getDimension()));
|
dirtyMetadata.put(EntityDataTypes.PLAYER_LAST_DEATH_DIMENSION, DimensionUtils.javaToBedrock(pos.getDimension()));
|
||||||
dirtyMetadata.put(EntityDataTypes.PLAYER_HAS_DIED, (byte) 1);
|
dirtyMetadata.put(EntityDataTypes.PLAYER_HAS_DIED, true);
|
||||||
} else {
|
} else {
|
||||||
dirtyMetadata.put(EntityDataTypes.PLAYER_HAS_DIED, (byte) 0);
|
dirtyMetadata.put(EntityDataTypes.PLAYER_HAS_DIED, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,9 +92,10 @@ public class GeyserItemStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ItemData getItemData(GeyserSession session) {
|
public ItemData getItemData(GeyserSession session) {
|
||||||
ItemData itemData = ItemTranslator.translateToBedrock(session, getItemStack());
|
ItemData.Builder itemData = ItemTranslator.translateToBedrock(session, javaId, amount, nbt);
|
||||||
itemData.setNetId(getNetId());
|
itemData.netId(getNetId());
|
||||||
return itemData;
|
itemData.usingNetId(true);
|
||||||
|
return itemData.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemMapping getMapping(GeyserSession session) {
|
public ItemMapping getMapping(GeyserSession session) {
|
||||||
|
@ -28,8 +28,6 @@ package org.geysermc.geyser.network;
|
|||||||
import io.netty.channel.DefaultEventLoopGroup;
|
import io.netty.channel.DefaultEventLoopGroup;
|
||||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||||
import org.cloudburstmc.protocol.bedrock.BedrockServerSession;
|
import org.cloudburstmc.protocol.bedrock.BedrockServerSession;
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.v554.Bedrock_v554;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.PacketCompressionAlgorithm;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.netty.initializer.BedrockServerInitializer;
|
import org.cloudburstmc.protocol.bedrock.netty.initializer.BedrockServerInitializer;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
@ -72,14 +70,9 @@ public class GeyserServerInitializer extends BedrockServerInitializer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initSession(@Nonnull BedrockServerSession bedrockServerSession) {
|
public void initSession(@Nonnull BedrockServerSession bedrockServerSession) {
|
||||||
System.out.println("init session");
|
|
||||||
try {
|
try {
|
||||||
bedrockServerSession.setCodec(Bedrock_v554.CODEC); // Has the RequestNetworkSettingsPacket
|
|
||||||
bedrockServerSession.setLogging(true);
|
bedrockServerSession.setLogging(true);
|
||||||
bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(this.geyser, new GeyserSession(this.geyser, bedrockServerSession, this.eventLoopGroup.next())));
|
bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(this.geyser, new GeyserSession(this.geyser, bedrockServerSession, this.eventLoopGroup.next())));
|
||||||
bedrockServerSession.setCompression(PacketCompressionAlgorithm.ZLIB);
|
|
||||||
bedrockServerSession.setCompressionLevel(this.geyser.getConfig().getBedrock().getCompressionLevel());
|
|
||||||
// Set the packet codec to default just in case we need to send disconnect packets.
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
// Error must be caught or it will be swallowed
|
// Error must be caught or it will be swallowed
|
||||||
this.geyser.getLogger().error("Error occurred while initializing player!", e);
|
this.geyser.getLogger().error("Error occurred while initializing player!", e);
|
||||||
|
@ -73,7 +73,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private PacketSignal translateAndDefault(BedrockPacket packet) {
|
private PacketSignal translateAndDefault(BedrockPacket packet) {
|
||||||
return Registries.BEDROCK_PACKET_TRANSLATORS.translate(packet.getClass(), packet, session) ? PacketSignal.HANDLED : PacketSignal.UNHANDLED;
|
Registries.BEDROCK_PACKET_TRANSLATORS.translate(packet.getClass(), packet, session);
|
||||||
|
return PacketSignal.HANDLED; // PacketSignal.UNHANDLED will log a WARN publicly
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -109,6 +110,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
} else if (BedrockDisconnectReasons.TIMEOUT.equals(reason)) {
|
} else if (BedrockDisconnectReasons.TIMEOUT.equals(reason)) {
|
||||||
this.session.getUpstream().getSession().setDisconnectReason(GeyserLocale.getLocaleStringLog("geyser.network.disconnect.timed_out"));
|
this.session.getUpstream().getSession().setDisconnectReason(GeyserLocale.getLocaleStringLog("geyser.network.disconnect.timed_out"));
|
||||||
}
|
}
|
||||||
|
this.session.disconnect(this.session.getUpstream().getSession().getDisconnectReason());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -128,6 +130,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
session.sendUpstreamPacketImmediately(responsePacket);
|
session.sendUpstreamPacketImmediately(responsePacket);
|
||||||
|
|
||||||
session.getUpstream().getSession().setCompression(algorithm);
|
session.getUpstream().getSession().setCompression(algorithm);
|
||||||
|
session.getUpstream().getSession().setCompressionLevel(this.geyser.getConfig().getBedrock().getCompressionLevel());
|
||||||
return PacketSignal.HANDLED;
|
return PacketSignal.HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,6 +142,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
return PacketSignal.HANDLED;
|
return PacketSignal.HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// session.getUpstream().getSession().getCodec() == null
|
||||||
|
|
||||||
if (!newProtocol) {
|
if (!newProtocol) {
|
||||||
if (!setCorrectCodec(loginPacket.getProtocolVersion())) { // REMOVE WHEN ONLY 1.19.30 IS SUPPORTED OR 1.20
|
if (!setCorrectCodec(loginPacket.getProtocolVersion())) { // REMOVE WHEN ONLY 1.19.30 IS SUPPORTED OR 1.20
|
||||||
return PacketSignal.HANDLED;
|
return PacketSignal.HANDLED;
|
||||||
|
@ -27,9 +27,7 @@ package org.geysermc.geyser.registry;
|
|||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundTabListPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundTabListPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLightUpdatePacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLightUpdatePacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
|
|
||||||
import io.netty.channel.EventLoop;
|
import io.netty.channel.EventLoop;
|
||||||
import org.geysermc.common.PlatformType;
|
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.registry.loader.RegistryLoaders;
|
import org.geysermc.geyser.registry.loader.RegistryLoaders;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
@ -68,9 +66,10 @@ public class PacketTranslatorRegistry<T> extends AbstractMappedRegistry<Class<?
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if ((GeyserImpl.getInstance().getPlatformType() != PlatformType.STANDALONE || !(packet instanceof BedrockPacket)) && !IGNORED_PACKETS.contains(clazz)) {
|
if (GeyserImpl.getInstance().getConfig().isDebugMode()) {
|
||||||
// Other debug logs already take care of Bedrock packets for us if on standalone
|
if (!IGNORED_PACKETS.contains(clazz)) {
|
||||||
GeyserImpl.getInstance().getLogger().debug("Could not find packet for " + (packet.toString().length() > 25 ? packet.getClass().getSimpleName() : packet));
|
GeyserImpl.getInstance().getLogger().debug("Could not find packet for " + (packet.toString().length() > 25 ? packet.getClass().getSimpleName() : packet));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -28,22 +28,13 @@ package org.geysermc.geyser.registry.populator;
|
|||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import org.cloudburstmc.nbt.NBTInputStream;
|
|
||||||
import org.cloudburstmc.nbt.NbtList;
|
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
|
||||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
|
||||||
import org.cloudburstmc.nbt.NbtType;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
import it.unimi.dsi.fastutil.objects.*;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
|
import org.cloudburstmc.nbt.*;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectIntPair;
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.v544.Bedrock_v544;
|
import org.cloudburstmc.protocol.bedrock.codec.v544.Bedrock_v544;
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.v560.Bedrock_v560;
|
import org.cloudburstmc.protocol.bedrock.codec.v560.Bedrock_v560;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition;
|
import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.defintions.SimpleBlockDefinition;
|
|
||||||
import org.cloudburstmc.protocol.common.SimpleDefinitionRegistry;
|
import org.cloudburstmc.protocol.common.SimpleDefinitionRegistry;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
@ -51,6 +42,7 @@ import org.geysermc.geyser.level.physics.PistonBehavior;
|
|||||||
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.registry.type.BlockMappings;
|
import org.geysermc.geyser.registry.type.BlockMappings;
|
||||||
|
import org.geysermc.geyser.registry.type.GeyserBedrockBlock;
|
||||||
import org.geysermc.geyser.util.BlockUtils;
|
import org.geysermc.geyser.util.BlockUtils;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
@ -93,7 +85,7 @@ public final class BlockRegistryPopulator {
|
|||||||
}
|
}
|
||||||
// New since 1.16.100 - find the block runtime ID by the order given to us in the block palette,
|
// New since 1.16.100 - find the block runtime ID by the order given to us in the block palette,
|
||||||
// as we no longer send a block palette
|
// as we no longer send a block palette
|
||||||
Object2ObjectMap<NbtMap, BlockDefinition> blockStateOrderedMap = new Object2ObjectOpenHashMap<>(blocksTag.size());
|
Object2ObjectMap<NbtMap, GeyserBedrockBlock> blockStateOrderedMap = new Object2ObjectOpenHashMap<>(blocksTag.size());
|
||||||
|
|
||||||
int stateVersion = -1;
|
int stateVersion = -1;
|
||||||
for (int i = 0; i < blocksTag.size(); i++) {
|
for (int i = 0; i < blocksTag.size(); i++) {
|
||||||
@ -103,14 +95,15 @@ public final class BlockRegistryPopulator {
|
|||||||
if (blockStateOrderedMap.containsKey(tag)) {
|
if (blockStateOrderedMap.containsKey(tag)) {
|
||||||
throw new AssertionError("Duplicate block states in Bedrock palette: " + tag);
|
throw new AssertionError("Duplicate block states in Bedrock palette: " + tag);
|
||||||
}
|
}
|
||||||
blockStateOrderedMap.put(tag, new SimpleBlockDefinition(tag.getString("name"), i, tag));
|
GeyserBedrockBlock block = new GeyserBedrockBlock(i, tag);
|
||||||
|
blockStateOrderedMap.put(tag, block);
|
||||||
if (stateVersion == -1) {
|
if (stateVersion == -1) {
|
||||||
stateVersion = tag.getInt("version");
|
stateVersion = tag.getInt("version");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int javaRuntimeId = -1;
|
int javaRuntimeId = -1;
|
||||||
|
|
||||||
BlockDefinition airDefinition = null;
|
GeyserBedrockBlock airDefinition = null;
|
||||||
BlockDefinition commandBlockDefinition = null;
|
BlockDefinition commandBlockDefinition = null;
|
||||||
BlockDefinition waterDefinition = null;
|
BlockDefinition waterDefinition = null;
|
||||||
BlockDefinition movingBlockDefinition = null;
|
BlockDefinition movingBlockDefinition = null;
|
||||||
@ -118,7 +111,7 @@ public final class BlockRegistryPopulator {
|
|||||||
|
|
||||||
BiFunction<String, NbtMapBuilder, String> stateMapper = blockMappers.getOrDefault(palette.getKey(), emptyMapper);
|
BiFunction<String, NbtMapBuilder, String> stateMapper = blockMappers.getOrDefault(palette.getKey(), emptyMapper);
|
||||||
|
|
||||||
BlockDefinition[] javaToBedrockBlocks = new BlockDefinition[BLOCKS_JSON.size()];
|
GeyserBedrockBlock[] javaToBedrockBlocks = new GeyserBedrockBlock[BLOCKS_JSON.size()];
|
||||||
SimpleDefinitionRegistry.Builder<BlockDefinition> registry = SimpleDefinitionRegistry.builder();
|
SimpleDefinitionRegistry.Builder<BlockDefinition> registry = SimpleDefinitionRegistry.builder();
|
||||||
|
|
||||||
Map<String, NbtMap> flowerPotBlocks = new Object2ObjectOpenHashMap<>();
|
Map<String, NbtMap> flowerPotBlocks = new Object2ObjectOpenHashMap<>();
|
||||||
@ -132,7 +125,7 @@ public final class BlockRegistryPopulator {
|
|||||||
Map.Entry<String, JsonNode> entry = blocksIterator.next();
|
Map.Entry<String, JsonNode> entry = blocksIterator.next();
|
||||||
String javaId = entry.getKey();
|
String javaId = entry.getKey();
|
||||||
|
|
||||||
BlockDefinition bedrockDefinition = blockStateOrderedMap.get(buildBedrockState(entry.getValue(), stateVersion, stateMapper));
|
GeyserBedrockBlock bedrockDefinition = blockStateOrderedMap.get(buildBedrockState(entry.getValue(), stateVersion, stateMapper));
|
||||||
if (bedrockDefinition == null) {
|
if (bedrockDefinition == null) {
|
||||||
throw new RuntimeException("Unable to find " + javaId + " Bedrock BlockDefinition! Built NBT tag: \n" +
|
throw new RuntimeException("Unable to find " + javaId + " Bedrock BlockDefinition! Built NBT tag: \n" +
|
||||||
buildBedrockState(entry.getValue(), stateVersion, stateMapper));
|
buildBedrockState(entry.getValue(), stateVersion, stateMapper));
|
||||||
|
@ -34,7 +34,6 @@ import org.geysermc.geyser.GeyserBootstrap;
|
|||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.registry.BlockRegistries;
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
import org.geysermc.geyser.registry.type.BlockMappings;
|
import org.geysermc.geyser.registry.type.BlockMappings;
|
||||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -80,7 +79,7 @@ public class CreativeItemRegistryPopulator {
|
|||||||
private static ItemData.Builder createItemData(JsonNode itemNode, BlockMappings blockMappings, Map<String, ItemDefinition> definitions) {
|
private static ItemData.Builder createItemData(JsonNode itemNode, BlockMappings blockMappings, Map<String, ItemDefinition> definitions) {
|
||||||
int count = 1;
|
int count = 1;
|
||||||
int damage = 0;
|
int damage = 0;
|
||||||
int blockRuntimeId = 0;
|
int bedrockBlockRuntimeId = 0;
|
||||||
NbtMap tag = null;
|
NbtMap tag = null;
|
||||||
JsonNode damageNode = itemNode.get("damage");
|
JsonNode damageNode = itemNode.get("damage");
|
||||||
if (damageNode != null) {
|
if (damageNode != null) {
|
||||||
@ -94,7 +93,7 @@ public class CreativeItemRegistryPopulator {
|
|||||||
|
|
||||||
JsonNode blockRuntimeIdNode = itemNode.get("blockRuntimeId");
|
JsonNode blockRuntimeIdNode = itemNode.get("blockRuntimeId");
|
||||||
if (blockRuntimeIdNode != null) {
|
if (blockRuntimeIdNode != null) {
|
||||||
blockRuntimeId = blockRuntimeIdNode.asInt();
|
bedrockBlockRuntimeId = blockRuntimeIdNode.asInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode nbtNode = itemNode.get("nbt_b64");
|
JsonNode nbtNode = itemNode.get("nbt_b64");
|
||||||
@ -126,6 +125,6 @@ public class CreativeItemRegistryPopulator {
|
|||||||
.damage(damage)
|
.damage(damage)
|
||||||
.count(count)
|
.count(count)
|
||||||
.tag(tag)
|
.tag(tag)
|
||||||
.blockDefinition(blockMappings.getBedrockBlock(blockRuntimeId));
|
.blockDefinition(blockMappings.getDefinitionRegistry().getDefinition(bedrockBlockRuntimeId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
|||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.collect.MultimapBuilder;
|
import com.google.common.collect.MultimapBuilder;
|
||||||
import it.unimi.dsi.fastutil.Pair;
|
import it.unimi.dsi.fastutil.Pair;
|
||||||
|
import it.unimi.dsi.fastutil.objects.*;
|
||||||
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;
|
||||||
@ -37,15 +38,10 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.v544.Bedrock_v544;
|
import org.cloudburstmc.protocol.bedrock.codec.v544.Bedrock_v544;
|
||||||
import org.cloudburstmc.protocol.bedrock.codec.v560.Bedrock_v560;
|
import org.cloudburstmc.protocol.bedrock.codec.v560.Bedrock_v560;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition;
|
import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ComponentItemData;
|
import org.cloudburstmc.protocol.bedrock.data.inventory.ComponentItemData;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||||
@ -141,7 +137,7 @@ public class ItemRegistryPopulator {
|
|||||||
registry.add(definition);
|
registry.add(definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object2IntMap<String> bedrockBlockIdOverrides = new Object2IntOpenHashMap<>();
|
Object2ObjectMap<String, BlockDefinition> bedrockBlockIdOverrides = new Object2ObjectOpenHashMap<>();
|
||||||
Object2IntMap<String> blacklistedIdentifiers = new Object2IntOpenHashMap<>();
|
Object2IntMap<String> blacklistedIdentifiers = new Object2IntOpenHashMap<>();
|
||||||
|
|
||||||
List<ItemDefinition> boats = new ObjectArrayList<>();
|
List<ItemDefinition> boats = new ObjectArrayList<>();
|
||||||
@ -157,7 +153,7 @@ public class ItemRegistryPopulator {
|
|||||||
|
|
||||||
AtomicInteger creativeNetId = new AtomicInteger();
|
AtomicInteger creativeNetId = new AtomicInteger();
|
||||||
CreativeItemRegistryPopulator.populate(palette, definitions, itemBuilder -> {
|
CreativeItemRegistryPopulator.populate(palette, definitions, itemBuilder -> {
|
||||||
ItemData item = itemBuilder.netId(creativeNetId.getAndIncrement()).build();
|
ItemData item = itemBuilder.netId(creativeNetId.incrementAndGet()).build();
|
||||||
creativeItems.add(item);
|
creativeItems.add(item);
|
||||||
|
|
||||||
if (item.getBlockDefinition() != null) {
|
if (item.getBlockDefinition() != null) {
|
||||||
@ -166,12 +162,12 @@ public class ItemRegistryPopulator {
|
|||||||
// Add override for item mapping, unless it already exists... then we know multiple states can exist
|
// Add override for item mapping, unless it already exists... then we know multiple states can exist
|
||||||
if (!blacklistedIdentifiers.containsKey(identifier)) {
|
if (!blacklistedIdentifiers.containsKey(identifier)) {
|
||||||
if (bedrockBlockIdOverrides.containsKey(identifier)) {
|
if (bedrockBlockIdOverrides.containsKey(identifier)) {
|
||||||
bedrockBlockIdOverrides.removeInt(identifier);
|
bedrockBlockIdOverrides.remove(identifier);
|
||||||
// Save this as a blacklist, but also as knowledge of what the block state name should be
|
// Save this as a blacklist, but also as knowledge of what the block state name should be
|
||||||
blacklistedIdentifiers.put(identifier, item.getBlockDefinition().getRuntimeId());
|
blacklistedIdentifiers.put(identifier, item.getBlockDefinition().getRuntimeId());
|
||||||
} else {
|
} else {
|
||||||
// Unless there's multiple possibilities for this one state, let this be
|
// Unless there's multiple possibilities for this one state, let this be
|
||||||
bedrockBlockIdOverrides.put(identifier, item.getBlockDefinition().getRuntimeId());
|
bedrockBlockIdOverrides.put(identifier, item.getBlockDefinition());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,19 +217,19 @@ public class ItemRegistryPopulator {
|
|||||||
|
|
||||||
int stackSize = mappingItem.getStackSize();
|
int stackSize = mappingItem.getStackSize();
|
||||||
|
|
||||||
int bedrockBlockId = -1;
|
BlockDefinition bedrockBlock = null;
|
||||||
Integer firstBlockRuntimeId = entry.getValue().getFirstBlockRuntimeId();
|
Integer firstBlockRuntimeId = entry.getValue().getFirstBlockRuntimeId();
|
||||||
if (firstBlockRuntimeId != null) {
|
if (firstBlockRuntimeId != null) {
|
||||||
int blockIdOverride = bedrockBlockIdOverrides.getOrDefault(bedrockIdentifier, -1);
|
BlockDefinition blockOverride = bedrockBlockIdOverrides.get(bedrockIdentifier);
|
||||||
if (blockIdOverride != -1) {
|
if (blockOverride != null) {
|
||||||
// Straight from BDS is our best chance of getting an item that doesn't run into issues
|
// Straight from BDS is our best chance of getting an item that doesn't run into issues
|
||||||
bedrockBlockId = blockIdOverride;
|
bedrockBlock = blockOverride;
|
||||||
} else {
|
} else {
|
||||||
// Try to get an example block runtime ID from the creative contents packet, for Bedrock identifier obtaining
|
// Try to get an example block runtime ID from the creative contents packet, for Bedrock identifier obtaining
|
||||||
int aValidBedrockBlockId = blacklistedIdentifiers.getOrDefault(bedrockIdentifier, -1);
|
int aValidBedrockBlockId = blacklistedIdentifiers.getOrDefault(bedrockIdentifier, -1);
|
||||||
if (aValidBedrockBlockId == -1) {
|
if (aValidBedrockBlockId == -1) {
|
||||||
// Fallback
|
// Fallback
|
||||||
bedrockBlockId = blockMappings.getBedrockBlockId(firstBlockRuntimeId);
|
bedrockBlock = blockMappings.getBedrockBlock(firstBlockRuntimeId);
|
||||||
} else {
|
} else {
|
||||||
// As of 1.16.220, every item requires a block runtime ID attached to it.
|
// As of 1.16.220, every item requires a block runtime ID attached to it.
|
||||||
// This is mostly for identifying different blocks with the same item ID - wool, slabs, some walls.
|
// This is mostly for identifying different blocks with the same item ID - wool, slabs, some walls.
|
||||||
@ -247,8 +243,8 @@ public class ItemRegistryPopulator {
|
|||||||
// and the last, if relevant. We then iterate over all those values and get their Bedrock equivalents
|
// and the last, if relevant. We then iterate over all those values and get their Bedrock equivalents
|
||||||
Integer lastBlockRuntimeId = entry.getValue().getLastBlockRuntimeId() == null ? firstBlockRuntimeId : entry.getValue().getLastBlockRuntimeId();
|
Integer lastBlockRuntimeId = entry.getValue().getLastBlockRuntimeId() == null ? firstBlockRuntimeId : entry.getValue().getLastBlockRuntimeId();
|
||||||
for (int i = firstBlockRuntimeId; i <= lastBlockRuntimeId; i++) {
|
for (int i = firstBlockRuntimeId; i <= lastBlockRuntimeId; i++) {
|
||||||
int bedrockBlockRuntimeId = blockMappings.getBedrockBlockId(i);
|
GeyserBedrockBlock bedrockBlockRuntimeId = blockMappings.getBedrockBlock(i);
|
||||||
NbtMap blockTag = blockMappings.getBedrockBlockPalette().get(bedrockBlockRuntimeId);
|
NbtMap blockTag = bedrockBlockRuntimeId.getState();
|
||||||
String bedrockName = blockTag.getString("name");
|
String bedrockName = blockTag.getString("name");
|
||||||
if (!bedrockName.equals(correctBedrockIdentifier)) {
|
if (!bedrockName.equals(correctBedrockIdentifier)) {
|
||||||
continue;
|
continue;
|
||||||
@ -259,7 +255,7 @@ public class ItemRegistryPopulator {
|
|||||||
firstPass = false;
|
firstPass = false;
|
||||||
if (states.size() == 0) {
|
if (states.size() == 0) {
|
||||||
// No need to iterate and find all block states - this is the one, as there can't be any others
|
// No need to iterate and find all block states - this is the one, as there can't be any others
|
||||||
bedrockBlockId = bedrockBlockRuntimeId;
|
bedrockBlock = bedrockBlockRuntimeId;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
requiredBlockStatesBuilder.putAll(states);
|
requiredBlockStatesBuilder.putAll(states);
|
||||||
@ -282,7 +278,7 @@ public class ItemRegistryPopulator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NbtMap requiredBlockStates = requiredBlockStatesBuilder.build();
|
NbtMap requiredBlockStates = requiredBlockStatesBuilder.build();
|
||||||
if (bedrockBlockId == -1) {
|
if (bedrockBlock == null) {
|
||||||
int i = -1;
|
int i = -1;
|
||||||
// We need to loop around again (we can't cache the block tags above) because Bedrock can include states that we don't have a pairing for
|
// We need to loop around again (we can't cache the block tags above) because Bedrock can include states that we don't have a pairing for
|
||||||
// in it's "preferred" block state - I.E. the first matching block state in the list
|
// in it's "preferred" block state - I.E. the first matching block state in the list
|
||||||
@ -299,12 +295,12 @@ public class ItemRegistryPopulator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (valid) {
|
if (valid) {
|
||||||
bedrockBlockId = i;
|
bedrockBlock = blockMappings.getDefinitionRegistry().getDefinition(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bedrockBlockId == -1) {
|
if (bedrockBlock == null) {
|
||||||
throw new RuntimeException("Could not find a block match for " + entry.getKey());
|
throw new RuntimeException("Could not find a block match for " + entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -328,7 +324,7 @@ public class ItemRegistryPopulator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (valid) {
|
if (valid) {
|
||||||
creativeItems.set(j, itemData.toBuilder().blockDefinition(blockMappings.getBedrockBlock(bedrockBlockId)).build());
|
creativeItems.set(j, itemData.toBuilder().blockDefinition(bedrockBlock).build());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -343,7 +339,7 @@ public class ItemRegistryPopulator {
|
|||||||
.bedrockIdentifier(bedrockIdentifier.intern())
|
.bedrockIdentifier(bedrockIdentifier.intern())
|
||||||
.bedrockDefinition(definition)
|
.bedrockDefinition(definition)
|
||||||
.bedrockData(mappingItem.getBedrockData())
|
.bedrockData(mappingItem.getBedrockData())
|
||||||
.bedrockBlockDefinition(blockMappings.getBedrockBlock(bedrockBlockId))
|
.bedrockBlockDefinition(bedrockBlock)
|
||||||
.stackSize(stackSize)
|
.stackSize(stackSize)
|
||||||
.maxDamage(mappingItem.getMaxDamage())
|
.maxDamage(mappingItem.getMaxDamage())
|
||||||
.hasSuspiciousStewEffect(mappingItem.isHasSuspiciousStewEffect());
|
.hasSuspiciousStewEffect(mappingItem.isHasSuspiciousStewEffect());
|
||||||
@ -364,7 +360,7 @@ public class ItemRegistryPopulator {
|
|||||||
|
|
||||||
if (javaOnlyItems.contains(javaIdentifier)) {
|
if (javaOnlyItems.contains(javaIdentifier)) {
|
||||||
// These items don't exist on Bedrock, so set up a variable that indicates they should have custom names
|
// These items don't exist on Bedrock, so set up a variable that indicates they should have custom names
|
||||||
mappingBuilder = mappingBuilder.translationString((bedrockBlockId != -1 ? "block." : "item.") + entry.getKey().replace(":", "."));
|
mappingBuilder = mappingBuilder.translationString((bedrockBlock != null ? "block." : "item.") + entry.getKey().replace(":", "."));
|
||||||
GeyserImpl.getInstance().getLogger().debug("Adding " + entry.getKey() + " as an item that needs to be translated.");
|
GeyserImpl.getInstance().getLogger().debug("Adding " + entry.getKey() + " as an item that needs to be translated.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,6 @@ import lombok.Value;
|
|||||||
import org.cloudburstmc.nbt.NbtList;
|
import org.cloudburstmc.nbt.NbtList;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition;
|
import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.defintions.SimpleBlockDefinition;
|
|
||||||
import org.cloudburstmc.protocol.common.DefinitionRegistry;
|
import org.cloudburstmc.protocol.common.DefinitionRegistry;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -39,13 +38,13 @@ import java.util.Set;
|
|||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public class BlockMappings {
|
public class BlockMappings {
|
||||||
BlockDefinition bedrockAir;
|
GeyserBedrockBlock bedrockAir;
|
||||||
BlockDefinition bedrockWater;
|
BlockDefinition bedrockWater;
|
||||||
BlockDefinition bedrockMovingBlock;
|
BlockDefinition bedrockMovingBlock;
|
||||||
|
|
||||||
int blockStateVersion;
|
int blockStateVersion;
|
||||||
|
|
||||||
BlockDefinition[] javaToBedrockBlocks;
|
GeyserBedrockBlock[] javaToBedrockBlocks;
|
||||||
DefinitionRegistry<BlockDefinition> definitionRegistry;
|
DefinitionRegistry<BlockDefinition> definitionRegistry;
|
||||||
|
|
||||||
NbtList<NbtMap> bedrockBlockPalette;
|
NbtList<NbtMap> bedrockBlockPalette;
|
||||||
@ -57,18 +56,15 @@ public class BlockMappings {
|
|||||||
|
|
||||||
Set<BlockDefinition> jigsawStates;
|
Set<BlockDefinition> jigsawStates;
|
||||||
|
|
||||||
public int getBedrockBlockId(int state) {
|
public int getBedrockBlockId(int javaState) {
|
||||||
if (state < 0 || state >= this.javaToBedrockBlocks.length) {
|
return getBedrockBlock(javaState).getRuntimeId();
|
||||||
return bedrockAir.getRuntimeId();
|
|
||||||
}
|
|
||||||
return this.javaToBedrockBlocks[state].getRuntimeId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockDefinition getBedrockBlock(int state) {
|
public GeyserBedrockBlock getBedrockBlock(int javaState) {
|
||||||
if (state < 0 || state >= this.javaToBedrockBlocks.length) {
|
if (javaState < 0 || javaState >= this.javaToBedrockBlocks.length) {
|
||||||
return bedrockAir;
|
return bedrockAir;
|
||||||
}
|
}
|
||||||
return this.javaToBedrockBlocks[state];
|
return this.javaToBedrockBlocks[javaState];
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockDefinition getItemFrame(NbtMap tag) {
|
public BlockDefinition getItemFrame(NbtMap tag) {
|
||||||
@ -76,7 +72,7 @@ public class BlockMappings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isItemFrame(BlockDefinition definition) {
|
public boolean isItemFrame(BlockDefinition definition) {
|
||||||
if (definition instanceof SimpleBlockDefinition def) {
|
if (definition instanceof GeyserBedrockBlock def) {
|
||||||
return this.itemFrames.containsKey(def.getState());
|
return this.itemFrames.containsKey(def.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2022 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.type;
|
||||||
|
|
||||||
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition;
|
||||||
|
|
||||||
|
public class GeyserBedrockBlock implements BlockDefinition {
|
||||||
|
private final int runtimeId;
|
||||||
|
private final NbtMap state;
|
||||||
|
|
||||||
|
public GeyserBedrockBlock(int runtimeId, NbtMap state) {
|
||||||
|
this.runtimeId = runtimeId;
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRuntimeId() {
|
||||||
|
return runtimeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NbtMap getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "GeyserBedrockBlock{" + state.getString("name") + "}";
|
||||||
|
}
|
||||||
|
}
|
@ -89,19 +89,11 @@ import org.cloudburstmc.math.vector.Vector3f;
|
|||||||
import org.cloudburstmc.math.vector.Vector3i;
|
import org.cloudburstmc.math.vector.Vector3i;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.protocol.bedrock.BedrockServerSession;
|
import org.cloudburstmc.protocol.bedrock.BedrockServerSession;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.Ability;
|
import org.cloudburstmc.protocol.bedrock.data.*;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.AbilityLayer;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.AttributeData;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.AuthoritativeMovementMode;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.ChatRestrictionLevel;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.GamePublishSetting;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.GameRuleData;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.GameType;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.PlayerPermission;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission;
|
import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.*;
|
import org.cloudburstmc.protocol.bedrock.packet.*;
|
||||||
|
import org.cloudburstmc.protocol.common.util.OptionalBoolean;
|
||||||
import org.geysermc.api.util.BedrockPlatform;
|
import org.geysermc.api.util.BedrockPlatform;
|
||||||
import org.geysermc.api.util.InputMode;
|
import org.geysermc.api.util.InputMode;
|
||||||
import org.geysermc.api.util.UiProfile;
|
import org.geysermc.api.util.UiProfile;
|
||||||
@ -879,14 +871,13 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
downstream = new LocalSession(this.remoteServer.address(), this.remoteServer.port(),
|
downstream = new LocalSession(this.remoteServer.address(), this.remoteServer.port(),
|
||||||
geyser.getBootstrap().getSocketAddress(), upstream.getAddress().getAddress().getHostAddress(),
|
geyser.getBootstrap().getSocketAddress(), upstream.getAddress().getAddress().getHostAddress(),
|
||||||
this.protocol, this.protocol.createHelper());
|
this.protocol, this.protocol.createHelper());
|
||||||
|
this.downstream = new DownstreamSession(downstream);
|
||||||
} else {
|
} else {
|
||||||
downstream = new TcpClientSession(this.remoteServer.address(), this.remoteServer.port(), this.protocol);
|
downstream = new TcpClientSession(this.remoteServer.address(), this.remoteServer.port(), this.protocol);
|
||||||
|
this.downstream = new DownstreamSession(downstream);
|
||||||
disableSrvResolving();
|
disableSrvResolving();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap in DownstreamSession
|
|
||||||
this.downstream = new DownstreamSession(downstream);
|
|
||||||
|
|
||||||
if (geyser.getConfig().getRemote().isUseProxyProtocol()) {
|
if (geyser.getConfig().getRemote().isUseProxyProtocol()) {
|
||||||
downstream.setFlag(BuiltinFlags.ENABLE_CLIENT_PROXY_PROTOCOL, true);
|
downstream.setFlag(BuiltinFlags.ENABLE_CLIENT_PROXY_PROTOCOL, true);
|
||||||
downstream.setFlag(BuiltinFlags.CLIENT_PROXIED_ADDRESS, upstream.getAddress());
|
downstream.setFlag(BuiltinFlags.CLIENT_PROXIED_ADDRESS, upstream.getAddress());
|
||||||
@ -1473,6 +1464,10 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
startGamePacket.setUsingMsaGamertagsOnly(false);
|
startGamePacket.setUsingMsaGamertagsOnly(false);
|
||||||
startGamePacket.setFromWorldTemplate(false);
|
startGamePacket.setFromWorldTemplate(false);
|
||||||
startGamePacket.setWorldTemplateOptionLocked(false);
|
startGamePacket.setWorldTemplateOptionLocked(false);
|
||||||
|
startGamePacket.setSpawnBiomeType(SpawnBiomeType.DEFAULT);
|
||||||
|
startGamePacket.setCustomBiomeName("");
|
||||||
|
startGamePacket.setEducationProductionId("");
|
||||||
|
startGamePacket.setForceExperimentalGameplay(OptionalBoolean.empty());
|
||||||
|
|
||||||
String serverName = geyser.getConfig().getBedrock().serverName();
|
String serverName = geyser.getConfig().getBedrock().serverName();
|
||||||
startGamePacket.setLevelId(serverName);
|
startGamePacket.setLevelId(serverName);
|
||||||
|
@ -147,6 +147,16 @@ public abstract class ItemTranslator {
|
|||||||
return itemStack;
|
return itemStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static ItemData.Builder translateToBedrock(GeyserSession session, int javaId, int count, CompoundTag tag) {
|
||||||
|
ItemMapping bedrockItem = session.getItemMappings().getMapping(javaId);
|
||||||
|
if (bedrockItem == ItemMapping.AIR) {
|
||||||
|
session.getGeyser().getLogger().debug("ItemMapping returned air: " + javaId);
|
||||||
|
return ItemData.builder();
|
||||||
|
}
|
||||||
|
return translateToBedrock(session, bedrockItem, count, tag);
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static ItemData translateToBedrock(GeyserSession session, ItemStack stack) {
|
public static ItemData translateToBedrock(GeyserSession session, ItemStack stack) {
|
||||||
if (stack == null) {
|
if (stack == null) {
|
||||||
@ -154,38 +164,43 @@ public abstract class ItemTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ItemMapping bedrockItem = session.getItemMappings().getMapping(stack);
|
ItemMapping bedrockItem = session.getItemMappings().getMapping(stack);
|
||||||
if (bedrockItem == null) {
|
if (bedrockItem == ItemMapping.AIR) {
|
||||||
session.getGeyser().getLogger().debug("No matching ItemMapping for " + stack);
|
session.getGeyser().getLogger().debug("ItemMapping returned air: " + stack);
|
||||||
return ItemData.AIR;
|
return ItemData.AIR;
|
||||||
}
|
}
|
||||||
|
return translateToBedrock(session, bedrockItem, stack.getAmount(), stack.getNbt())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
CompoundTag nbt = stack.getNbt() != null ? stack.getNbt().clone() : null;
|
@Nonnull
|
||||||
|
private static ItemData.Builder translateToBedrock(GeyserSession session, ItemMapping mapping, int count, CompoundTag tag) {
|
||||||
|
CompoundTag nbt = tag != null ? tag.clone() : null;
|
||||||
|
|
||||||
// This is a fallback for maps with no nbt
|
// This is a fallback for maps with no nbt
|
||||||
if (nbt == null && bedrockItem.getJavaIdentifier().equals("minecraft:filled_map")) {
|
if (nbt == null && mapping.getJavaIdentifier().equals("minecraft:filled_map")) {
|
||||||
nbt = new CompoundTag("");
|
nbt = new CompoundTag("");
|
||||||
nbt.put(new IntTag("map", 0));
|
nbt.put(new IntTag("map", 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nbt != null) {
|
if (nbt != null) {
|
||||||
for (NbtItemStackTranslator translator : NBT_TRANSLATORS) {
|
for (NbtItemStackTranslator translator : NBT_TRANSLATORS) {
|
||||||
if (translator.acceptItem(bedrockItem)) {
|
if (translator.acceptItem(mapping)) {
|
||||||
translator.translateToBedrock(session, nbt, bedrockItem);
|
translator.translateToBedrock(session, nbt, mapping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nbt = translateDisplayProperties(session, nbt, bedrockItem);
|
nbt = translateDisplayProperties(session, nbt, mapping);
|
||||||
if (session.isAdvancedTooltips()) {
|
if (session.isAdvancedTooltips()) {
|
||||||
nbt = addAdvancedTooltips(nbt, bedrockItem, session.locale());
|
nbt = addAdvancedTooltips(nbt, mapping, session.locale());
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack itemStack = new ItemStack(stack.getId(), stack.getAmount(), nbt);
|
ItemStack itemStack = new ItemStack(mapping.getJavaId(), count, nbt);
|
||||||
|
|
||||||
ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.getOrDefault(bedrockItem.getJavaId(), DEFAULT_TRANSLATOR);
|
ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.getOrDefault(mapping.getJavaId(), DEFAULT_TRANSLATOR);
|
||||||
ItemData.Builder builder = itemStackTranslator.translateToBedrock(itemStack, bedrockItem, session.getItemMappings());
|
ItemData.Builder builder = itemStackTranslator.translateToBedrock(itemStack, mapping, session.getItemMappings());
|
||||||
if (bedrockItem.isBlock()) {
|
if (mapping.isBlock()) {
|
||||||
builder.blockDefinition(bedrockItem.getBedrockBlockDefinition());
|
builder.blockDefinition(mapping.getBedrockBlockDefinition());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nbt != null) {
|
if (nbt != null) {
|
||||||
@ -202,7 +217,7 @@ public abstract class ItemTranslator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.build();
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CompoundTag addAdvancedTooltips(CompoundTag nbt, ItemMapping mapping, String language) {
|
private static CompoundTag addAdvancedTooltips(CompoundTag nbt, ItemMapping mapping, String language) {
|
||||||
|
@ -109,7 +109,7 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
|
|||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, ClientboundCommandsPacket packet) {
|
public void translate(GeyserSession session, ClientboundCommandsPacket packet) {
|
||||||
// Don't send command suggestions if they are disabled
|
// Don't send command suggestions if they are disabled
|
||||||
if (!session.getGeyser().getConfig().isCommandSuggestions()) {
|
if (!session.getGeyser().getConfig().isCommandSuggestions() || true) {
|
||||||
session.getGeyser().getLogger().debug("Not sending translated command suggestions as they are disabled.");
|
session.getGeyser().getLogger().debug("Not sending translated command suggestions as they are disabled.");
|
||||||
|
|
||||||
// Send an empty packet so Bedrock doesn't override /help with its own, built-in help command.
|
// Send an empty packet so Bedrock doesn't override /help with its own, built-in help command.
|
||||||
|
@ -301,6 +301,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
|||||||
|
|
||||||
// Allocate output buffer
|
// Allocate output buffer
|
||||||
byteBuf = ByteBufAllocator.DEFAULT.buffer(size);
|
byteBuf = ByteBufAllocator.DEFAULT.buffer(size);
|
||||||
|
byteBuf.retain();
|
||||||
for (int i = 0; i < sectionCount; i++) {
|
for (int i = 0; i < sectionCount; i++) {
|
||||||
GeyserChunkSection section = sections[i];
|
GeyserChunkSection section = sections[i];
|
||||||
if (section != null) {
|
if (section != null) {
|
||||||
@ -349,7 +350,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
|||||||
levelChunkPacket.setCachingEnabled(false);
|
levelChunkPacket.setCachingEnabled(false);
|
||||||
levelChunkPacket.setChunkX(packet.getX());
|
levelChunkPacket.setChunkX(packet.getX());
|
||||||
levelChunkPacket.setChunkZ(packet.getZ());
|
levelChunkPacket.setChunkZ(packet.getZ());
|
||||||
levelChunkPacket.setData(byteBuf);
|
levelChunkPacket.setData(byteBuf.retain());
|
||||||
session.sendUpstreamPacket(levelChunkPacket);
|
session.sendUpstreamPacket(levelChunkPacket);
|
||||||
|
|
||||||
for (Map.Entry<Vector3i, ItemFrameEntity> entry : session.getItemFrameCache().entrySet()) {
|
for (Map.Entry<Vector3i, ItemFrameEntity> entry : session.getItemFrameCache().entrySet()) {
|
||||||
|
@ -25,17 +25,17 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.util;
|
package org.geysermc.geyser.util;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntLists;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
import org.cloudburstmc.math.vector.Vector2i;
|
import org.cloudburstmc.math.vector.Vector2i;
|
||||||
import org.cloudburstmc.math.vector.Vector3i;
|
import org.cloudburstmc.math.vector.Vector3i;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition;
|
import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.LevelChunkPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.LevelChunkPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket;
|
import org.cloudburstmc.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntLists;
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
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.JavaDimension;
|
import org.geysermc.geyser.level.JavaDimension;
|
||||||
@ -181,18 +181,18 @@ public class ChunkUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
byteBuf.writeByte(0); // Border blocks - Edu edition only
|
byteBuf.writeByte(0); // Border blocks - Edu edition only
|
||||||
|
|
||||||
|
LevelChunkPacket data = new LevelChunkPacket();
|
||||||
|
data.setChunkX(chunkX);
|
||||||
|
data.setChunkZ(chunkZ);
|
||||||
|
data.setSubChunksLength(0);
|
||||||
|
data.setData(byteBuf.retain());
|
||||||
|
data.setCachingEnabled(false);
|
||||||
|
session.sendUpstreamPacket(data);
|
||||||
} finally {
|
} finally {
|
||||||
byteBuf.release();
|
byteBuf.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
LevelChunkPacket data = new LevelChunkPacket();
|
|
||||||
data.setChunkX(chunkX);
|
|
||||||
data.setChunkZ(chunkZ);
|
|
||||||
data.setSubChunksLength(0);
|
|
||||||
data.setData(byteBuf);
|
|
||||||
data.setCachingEnabled(false);
|
|
||||||
session.sendUpstreamPacket(data);
|
|
||||||
|
|
||||||
if (forceUpdate) {
|
if (forceUpdate) {
|
||||||
Vector3i pos = Vector3i.from(chunkX << 4, 80, chunkZ << 4);
|
Vector3i pos = Vector3i.from(chunkX << 4, 80, chunkZ << 4);
|
||||||
UpdateBlockPacket blockPacket = new UpdateBlockPacket();
|
UpdateBlockPacket blockPacket = new UpdateBlockPacket();
|
||||||
|
@ -54,7 +54,6 @@ import org.geysermc.geyser.text.ChatColor;
|
|||||||
import org.geysermc.geyser.text.GeyserLocale;
|
import org.geysermc.geyser.text.GeyserLocale;
|
||||||
|
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.KeyPairGenerator;
|
import java.security.KeyPairGenerator;
|
||||||
@ -192,12 +191,13 @@ public class LoginEncryptionUtils {
|
|||||||
KeyPair serverKeyPair = generator.generateKeyPair();
|
KeyPair serverKeyPair = generator.generateKeyPair();
|
||||||
|
|
||||||
byte[] token = EncryptionUtils.generateRandomToken();
|
byte[] token = EncryptionUtils.generateRandomToken();
|
||||||
SecretKey encryptionKey = EncryptionUtils.getSecretKey(serverKeyPair.getPrivate(), key, token);
|
|
||||||
session.getUpstream().getSession().enableEncryption(encryptionKey);
|
|
||||||
|
|
||||||
ServerToClientHandshakePacket packet = new ServerToClientHandshakePacket();
|
ServerToClientHandshakePacket packet = new ServerToClientHandshakePacket();
|
||||||
packet.setJwt(EncryptionUtils.createHandshakeJwt(serverKeyPair, token).serialize());
|
packet.setJwt(EncryptionUtils.createHandshakeJwt(serverKeyPair, token).serialize());
|
||||||
session.sendUpstreamPacketImmediately(packet);
|
session.sendUpstreamPacketImmediately(packet);
|
||||||
|
|
||||||
|
SecretKey encryptionKey = EncryptionUtils.getSecretKey(serverKeyPair.getPrivate(), key, token);
|
||||||
|
session.getUpstream().getSession().enableEncryption(encryptionKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sendEncryptionFailedMessage(GeyserImpl geyser) {
|
private static void sendEncryptionFailedMessage(GeyserImpl geyser) {
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren