Optimizations and regression fix

This commit is contained in:
Camotoy 2023-04-06 21:47:37 -04:00
parent 8083f70435
commit b6113dfd31
22 changed files with 114 additions and 297 deletions

View file

@ -59,7 +59,7 @@ public class GeyserSpigotBlockPlaceListener implements Listener {
event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ())));
} else {
String javaBlockId = event.getBlockPlaced().getBlockData().getAsString();
placeBlockSoundPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(BlockRegistries.JAVA_IDENTIFIERS.get().getOrDefault(javaBlockId, BlockStateValues.JAVA_AIR_ID)));
placeBlockSoundPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getOrDefault(javaBlockId, BlockStateValues.JAVA_AIR_ID)));
}
placeBlockSoundPacket.setIdentifier(":");
session.sendUpstreamPacket(placeBlockSoundPacket);

View file

@ -82,9 +82,9 @@ public class GeyserSpigotWorldManager extends WorldManager {
// Terrible behavior, but this is basically what's always been happening behind the scenes anyway.
CompletableFuture<String> blockData = new CompletableFuture<>();
Bukkit.getRegionScheduler().execute(this.plugin, block.getLocation(), () -> blockData.complete(block.getBlockData().getAsString()));
return BlockRegistries.JAVA_IDENTIFIERS.getOrDefault(blockData.join(), BlockStateValues.JAVA_AIR_ID);
return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(blockData.join(), BlockStateValues.JAVA_AIR_ID);
}
return BlockRegistries.JAVA_IDENTIFIERS.getOrDefault(block.getBlockData().getAsString(), BlockStateValues.JAVA_AIR_ID);
return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(block.getBlockData().getAsString(), BlockStateValues.JAVA_AIR_ID);
}
@Override

View file

@ -31,7 +31,6 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.steveice10.packetlib.tcp.TcpSession;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.kqueue.KQueue;
import io.netty.util.NettyRuntime;
import io.netty.util.concurrent.DefaultThreadFactory;
import io.netty.util.internal.SystemPropertyUtil;
@ -312,21 +311,22 @@ public class GeyserImpl implements GeyserApi {
}
if (shouldStartListener) {
try {
this.geyserServer = new GeyserServer(this, bedrockThreadCount);
this.geyserServer.bind(new InetSocketAddress(config.getBedrock().address(), config.getBedrock().port()));
logger.info(GeyserLocale.getLocaleStringLog("geyser.core.start", config.getBedrock().address(),
String.valueOf(config.getBedrock().port())));
} catch (Throwable t) {
String address = config.getBedrock().address();
int port = config.getBedrock().port();
logger.severe(GeyserLocale.getLocaleStringLog("geyser.core.fail", address, String.valueOf(port)));
if (!"0.0.0.0".equals(address)) {
logger.info(Component.text("Suggestion: try setting `address` under `bedrock` in the Geyser config back to 0.0.0.0", NamedTextColor.GREEN));
logger.info(Component.text("Then, restart this server.", NamedTextColor.GREEN));
}
}
this.geyserServer = new GeyserServer(this, bedrockThreadCount);
this.geyserServer.bind(new InetSocketAddress(config.getBedrock().address(), config.getBedrock().port()))
.whenComplete((avoid, throwable) -> {
if (throwable == null) {
logger.info(GeyserLocale.getLocaleStringLog("geyser.core.start", config.getBedrock().address(),
String.valueOf(config.getBedrock().port())));
} else {
String address = config.getBedrock().address();
int port = config.getBedrock().port();
logger.severe(GeyserLocale.getLocaleStringLog("geyser.core.fail", address, String.valueOf(port)));
if (!"0.0.0.0".equals(address)) {
logger.info(Component.text("Suggestion: try setting `address` under `bedrock` in the Geyser config back to 0.0.0.0", NamedTextColor.GREEN));
logger.info(Component.text("Then, restart this server.", NamedTextColor.GREEN));
}
}
}).join();
}
if (config.getRemote().authType() == AuthType.FLOODGATE) {

View file

@ -56,7 +56,6 @@ import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.AttributeUtils;
import org.geysermc.geyser.util.ChunkUtils;
import org.geysermc.geyser.util.InteractionResult;
import java.util.*;
@ -127,17 +126,8 @@ public class LivingEntity extends Entity {
if (optionalPos.isPresent()) {
Vector3i bedPosition = optionalPos.get();
dirtyMetadata.put(EntityDataTypes.BED_POSITION, bedPosition);
int bed = session.getGeyser().getWorldManager().getBlockAt(session, bedPosition);
// Bed has to be updated, or else player is floating in the air
ChunkUtils.updateBlock(session, bed, bedPosition);
// Indicate that the player should enter the sleep cycle
// Has to be a byte or it does not work
// (Bed position is what actually triggers sleep - "pose" is only optional)
dirtyMetadata.put(EntityDataTypes.PLAYER_FLAGS, (byte) 2);
return bedPosition;
} else {
// Player is no longer sleeping
dirtyMetadata.put(EntityDataTypes.PLAYER_FLAGS, (byte) 0);
return null;
}
}

View file

@ -27,14 +27,15 @@ package org.geysermc.geyser.entity.type.living.merchant;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.VillagerData;
import lombok.Getter;
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket;
import lombok.Getter;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.registry.type.BlockMapping;
import org.geysermc.geyser.session.GeyserSession;
import java.util.Optional;
@ -117,7 +118,7 @@ public class VillagerEntity extends AbstractMerchantEntity {
// The bed block
int blockId = session.getGeyser().getWorldManager().getBlockAt(session, bedPosition);
String fullIdentifier = BlockRegistries.JAVA_IDENTIFIERS.get().get(blockId);
String fullIdentifier = BlockRegistries.JAVA_BLOCKS.getOrDefault(blockId, BlockMapping.AIR).getJavaIdentifier();
// Set the correct position offset and rotation when sleeping
int bedRotation = 0;

View file

@ -38,20 +38,12 @@ import lombok.Setter;
import net.kyori.adventure.text.Component;
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.protocol.bedrock.data.Ability;
import org.cloudburstmc.protocol.bedrock.data.AbilityLayer;
import org.cloudburstmc.protocol.bedrock.data.AttributeData;
import org.cloudburstmc.protocol.bedrock.data.GameType;
import org.cloudburstmc.protocol.bedrock.data.PlayerPermission;
import org.cloudburstmc.protocol.bedrock.data.*;
import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData;
import org.cloudburstmc.protocol.bedrock.packet.AddPlayerPacket;
import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket;
import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket;
import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket;
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
import org.cloudburstmc.protocol.bedrock.packet.*;
import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.entity.type.Entity;
import org.geysermc.geyser.entity.type.LivingEntity;
@ -62,6 +54,7 @@ import org.geysermc.geyser.scoreboard.Team;
import org.geysermc.geyser.scoreboard.UpdateType;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.geyser.util.ChunkUtils;
import javax.annotation.Nullable;
import java.util.Collections;
@ -248,8 +241,25 @@ public class PlayerEntity extends LivingEntity {
@Override
public Vector3i setBedPosition(EntityMetadata<Optional<Vector3i>, ?> entityMetadata) {
bedPosition = super.setBedPosition(entityMetadata);
// Fixes https://github.com/GeyserMC/Geyser/issues/3595 on vanilla 1.19.3 servers - did not happen on Paper
entityMetadata.getValue().ifPresent(pos -> this.setPosition(pos.toFloat()));
if (bedPosition != null) {
// Required to sync position of entity to bed
// Fixes https://github.com/GeyserMC/Geyser/issues/3595 on vanilla 1.19.3 servers - did not happen on Paper
this.setPosition(bedPosition.toFloat());
// TODO evaluate if needed
int bed = session.getGeyser().getWorldManager().getBlockAt(session, bedPosition);
// Bed has to be updated, or else player is floating in the air
ChunkUtils.updateBlock(session, bed, bedPosition);
// Indicate that the player should enter the sleep cycle
// Has to be a byte or it does not work
// (Bed position is what actually triggers sleep - "pose" is only optional)
dirtyMetadata.put(EntityDataTypes.PLAYER_FLAGS, (byte) 2);
} else {
// Player is no longer sleeping
dirtyMetadata.put(EntityDataTypes.PLAYER_FLAGS, (byte) 0);
return null;
}
return bedPosition;
}

View file

@ -35,6 +35,7 @@ import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
import org.geysermc.geyser.inventory.Container;
import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.registry.type.BlockMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
import org.geysermc.geyser.util.BlockUtils;
@ -57,7 +58,7 @@ public class BlockInventoryHolder extends InventoryHolder {
private final Set<String> validBlocks;
public BlockInventoryHolder(String javaBlockIdentifier, ContainerType containerType, String... validBlocks) {
this.defaultJavaBlockState = BlockRegistries.JAVA_IDENTIFIERS.get(javaBlockIdentifier);
this.defaultJavaBlockState = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt(javaBlockIdentifier);
this.containerType = containerType;
if (validBlocks != null) {
Set<String> validBlocksTemp = new HashSet<>(validBlocks.length + 1);
@ -77,7 +78,7 @@ public class BlockInventoryHolder extends InventoryHolder {
if (checkInteractionPosition(session)) {
// Then, check to see if the interacted block is valid for this inventory by ensuring the block state identifier is valid
int javaBlockId = session.getGeyser().getWorldManager().getBlockAt(session, session.getLastInteractionBlockPosition());
String[] javaBlockString = BlockRegistries.JAVA_IDENTIFIERS.get().getOrDefault(javaBlockId, "minecraft:air").split("\\[");
String[] javaBlockString = BlockRegistries.JAVA_BLOCKS.getOrDefault(javaBlockId, BlockMapping.AIR).getJavaIdentifier().split("\\[");
if (isValidBlock(javaBlockString)) {
// We can safely use this block
inventory.setHolderPosition(session.getLastInteractionBlockPosition());

View file

@ -468,7 +468,7 @@ public final class BlockStateValues {
*/
public static double getWaterHeight(int state) {
int waterLevel = BlockStateValues.getWaterLevel(state);
if (BlockRegistries.WATERLOGGED.get().contains(state)) {
if (BlockRegistries.WATERLOGGED.get().get(state)) {
waterLevel = 0;
}
if (waterLevel >= 0) {

View file

@ -27,7 +27,6 @@ package org.geysermc.geyser.network.netty;
import com.github.steveice10.packetlib.helper.TransportHelper;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.Epoll;
@ -54,7 +53,8 @@ import org.geysermc.geyser.translator.text.MessageTranslator;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.function.Function;
import java.util.concurrent.CompletableFuture;
import java.util.function.IntFunction;
public final class GeyserServer {
private static final boolean PRINT_DEBUG_PINGS = Boolean.parseBoolean(System.getProperty("Geyser.PrintPingsInDebugMode", "true"));
@ -76,7 +76,6 @@ public final class GeyserServer {
private final ServerBootstrap bootstrap;
private ChannelFuture future;
private Channel channel;
public GeyserServer(GeyserImpl geyser, int threadCount) {
this.geyser = geyser;
@ -85,12 +84,19 @@ public final class GeyserServer {
this.bootstrap = this.createBootstrap(this.group);
}
public void bind(InetSocketAddress address) {
this.future = this.bootstrap.bind(address).syncUninterruptibly();
this.channel = this.future.channel();
public CompletableFuture<Void> bind(InetSocketAddress address) {
CompletableFuture<Void> future = new CompletableFuture<>();
this.future = this.bootstrap.bind(address).addListener(bindResult -> {
if (bindResult.cause() != null) {
future.completeExceptionally(bindResult.cause());
return;
}
future.complete(null);
});
// Add our ping handler
this.channel.pipeline().addAfter(RakServerOfflineHandler.NAME, RakPingHandler.NAME, new RakPingHandler(this));
this.future.channel().pipeline().addAfter(RakServerOfflineHandler.NAME, RakPingHandler.NAME, new RakPingHandler(this));
return future;
}
public void shutdown() {
@ -219,6 +225,6 @@ public final class GeyserServer {
return new Transport(NioDatagramChannel.class, NioEventLoopGroup::new);
}
private record Transport(Class<? extends DatagramChannel> datagramChannel, Function<Integer, EventLoopGroup> eventLoopGroupFactory) {
private record Transport(Class<? extends DatagramChannel> datagramChannel, IntFunction<EventLoopGroup> eventLoopGroupFactory) {
}
}

View file

@ -26,14 +26,15 @@
package org.geysermc.geyser.registry;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
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.Object2ObjectOpenHashMap;
import org.geysermc.geyser.registry.loader.RegistryLoaders;
import org.geysermc.geyser.registry.populator.BlockRegistryPopulator;
import org.geysermc.geyser.registry.type.BlockMapping;
import org.geysermc.geyser.registry.type.BlockMappings;
import org.geysermc.geyser.util.collection.Object2IntBiMap;
import java.util.BitSet;
/**
* Holds all the block registries in Geyser.
@ -54,33 +55,33 @@ public class BlockRegistries {
* A registry which stores Java IDs to {@link BlockMapping}, containing miscellaneous information about
* blocks and their behavior in many cases.
*/
public static final ArrayRegistry<BlockMapping> JAVA_BLOCKS = ArrayRegistry.create(RegistryLoaders.empty(() -> new BlockMapping[] {}));
public static final ArrayRegistry<BlockMapping> JAVA_BLOCKS = ArrayRegistry.create(RegistryLoaders.uninitialized());
/**
* A (bi)mapped registry containing the Java IDs to identifiers.
* A mapped registry containing the Java identifiers to IDs.
*/
public static final MappedRegistry<String, Integer, Object2IntBiMap<String>> JAVA_IDENTIFIERS = MappedRegistry.create(RegistryLoaders.empty(Object2IntBiMap::new));
public static final MappedRegistry<String, Integer, Object2IntMap<String>> JAVA_IDENTIFIER_TO_ID = MappedRegistry.create(RegistryLoaders.empty(Object2IntOpenHashMap::new));
/**
* A registry which stores unique Java IDs to its clean identifier
* This is used in the statistics form.
*/
public static final ArrayRegistry<String> CLEAN_JAVA_IDENTIFIERS = ArrayRegistry.create(RegistryLoaders.empty(() -> new String[] {}));
public static final ArrayRegistry<String> CLEAN_JAVA_IDENTIFIERS = ArrayRegistry.create(RegistryLoaders.uninitialized());
/**
* A registry containing all the waterlogged blockstates.
*/
public static final SimpleRegistry<IntSet> WATERLOGGED = SimpleRegistry.create(RegistryLoaders.empty(IntOpenHashSet::new));
public static final SimpleRegistry<BitSet> WATERLOGGED = SimpleRegistry.create(RegistryLoaders.empty(BitSet::new));
/**
* A registry containing all blockstates which are always interactive.
*/
public static final SimpleRegistry<IntSet> INTERACTIVE = SimpleRegistry.create(RegistryLoaders.empty(IntOpenHashSet::new));
public static final SimpleRegistry<BitSet> INTERACTIVE = SimpleRegistry.create(RegistryLoaders.uninitialized());
/**
* A registry containing all blockstates which are interactive if the player has the may build permission.
*/
public static final SimpleRegistry<IntSet> INTERACTIVE_MAY_BUILD = SimpleRegistry.create(RegistryLoaders.empty(IntOpenHashSet::new));
public static final SimpleRegistry<BitSet> INTERACTIVE_MAY_BUILD = SimpleRegistry.create(RegistryLoaders.uninitialized());
static {
BlockRegistryPopulator.populate();

View file

@ -25,12 +25,14 @@
package org.geysermc.geyser.registry.loader;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.function.Supplier;
/**
* Holds common {@link RegistryLoader}s or utility methods surrounding them.
*/
public class RegistryLoaders {
public final class RegistryLoaders {
/**
* The {@link RegistryLoader} responsible for loading NBT.
*/
@ -44,7 +46,18 @@ public class RegistryLoaders {
* @param <V> the value
* @return a RegistryLoader wrapping the given Supplier
*/
public static <V> RegistryLoader<Object, V> empty(Supplier<V> supplier) {
public static <V> RegistryLoader<Object, V> empty(@NonNull Supplier<V> supplier) {
return input -> supplier.get();
}
/**
* @param <V> the value
* @return a RegistryLoader that is yet to contain a value.
*/
public static <V> RegistryLoader<Object, V> uninitialized() {
return input -> null;
}
private RegistryLoaders() {
}
}

View file

@ -28,8 +28,6 @@ package org.geysermc.geyser.registry.populator;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.google.common.collect.ImmutableMap;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.objects.*;
import org.cloudburstmc.nbt.*;
import org.cloudburstmc.protocol.bedrock.codec.v544.Bedrock_v544;
@ -160,7 +158,7 @@ public final class BlockRegistryPopulator {
if (waterlogged) {
int finalJavaRuntimeId = javaRuntimeId;
BlockRegistries.WATERLOGGED.register(set -> set.add(finalJavaRuntimeId));
BlockRegistries.WATERLOGGED.register(set -> set.set(finalJavaRuntimeId));
}
String cleanJavaIdentifier = BlockUtils.getCleanIdentifier(entry.getKey());
@ -296,7 +294,7 @@ public final class BlockRegistryPopulator {
builder.javaIdentifier(javaId);
builder.javaBlockId(uniqueJavaId);
BlockRegistries.JAVA_IDENTIFIERS.register(javaId, javaRuntimeId);
BlockRegistries.JAVA_IDENTIFIER_TO_ID.register(javaId, javaRuntimeId);
BlockRegistries.JAVA_BLOCKS.register(javaRuntimeId, builder.build());
// Keeping this here since this is currently unchanged between versions
@ -375,10 +373,10 @@ public final class BlockRegistryPopulator {
BlockRegistries.INTERACTIVE_MAY_BUILD.set(toBlockStateSet((ArrayNode) blockInteractionsJson.get("requires_may_build")));
}
private static IntSet toBlockStateSet(ArrayNode node) {
IntSet blockStateSet = new IntOpenHashSet(node.size());
private static BitSet toBlockStateSet(ArrayNode node) {
BitSet blockStateSet = new BitSet(node.size());
for (JsonNode javaIdentifier : node) {
blockStateSet.add(BlockRegistries.JAVA_IDENTIFIERS.get().getInt(javaIdentifier.textValue()));
blockStateSet.set(BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt(javaIdentifier.textValue()));
}
return blockStateSet;
}
@ -392,8 +390,9 @@ public final class BlockRegistryPopulator {
NbtMapBuilder statesBuilder = NbtMap.builder();
// check for states
if (node.has("bedrock_states")) {
Iterator<Map.Entry<String, JsonNode>> statesIterator = node.get("bedrock_states").fields();
JsonNode states = node.get("bedrock_states");
if (states != null) {
Iterator<Map.Entry<String, JsonNode>> statesIterator = states.fields();
while (statesIterator.hasNext()) {
Map.Entry<String, JsonNode> stateEntry = statesIterator.next();

View file

@ -39,6 +39,7 @@ import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.level.block.DoubleChestValue;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.registry.type.BlockMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.level.block.entity.DoubleChestBlockEntityTranslator;
import org.geysermc.geyser.util.InventoryUtils;
@ -48,7 +49,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
public DoubleChestInventoryTranslator(int size) {
super(size, 54);
this.defaultJavaBlockState = BlockRegistries.JAVA_IDENTIFIERS.get("minecraft:chest[facing=north,type=single,waterlogged=false]");
this.defaultJavaBlockState = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt("minecraft:chest[facing=north,type=single,waterlogged=false]");
}
@Override
@ -56,7 +57,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
// See BlockInventoryHolder - same concept there except we're also dealing with a specific block state
if (session.getLastInteractionPlayerPosition().equals(session.getPlayerEntity().getPosition())) {
int javaBlockId = session.getGeyser().getWorldManager().getBlockAt(session, session.getLastInteractionBlockPosition());
String[] javaBlockString = BlockRegistries.JAVA_IDENTIFIERS.get().getOrDefault(javaBlockId, "minecraft:air").split("\\[");
String[] javaBlockString = BlockRegistries.JAVA_BLOCKS.getOrDefault(javaBlockId, BlockMapping.AIR).getJavaIdentifier().split("\\[");
if (javaBlockString.length > 1 && (javaBlockString[0].equals("minecraft:chest") || javaBlockString[0].equals("minecraft:trapped_chest"))
&& !javaBlockString[1].contains("type=single")) {
inventory.setHolderPosition(session.getLastInteractionBlockPosition());

View file

@ -32,15 +32,9 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction;
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemOnPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.*;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.cloudburstmc.math.vector.Vector3d;
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.math.vector.Vector3i;
@ -50,7 +44,6 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.cloudburstmc.protocol.bedrock.data.inventory.transaction.InventoryActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.transaction.InventorySource;
import org.cloudburstmc.protocol.bedrock.data.inventory.transaction.LegacySetItemSlotData;
import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket;
import org.cloudburstmc.protocol.bedrock.packet.InventoryTransactionPacket;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
@ -506,7 +499,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
UpdateBlockPacket updateWaterPacket = new UpdateBlockPacket();
updateWaterPacket.setDataLayer(1);
updateWaterPacket.setBlockPosition(blockPos);
updateWaterPacket.setDefinition(BlockRegistries.WATERLOGGED.get().contains(javaBlockState) ? session.getBlockMappings().getBedrockWater() : session.getBlockMappings().getBedrockAir());
updateWaterPacket.setDefinition(BlockRegistries.WATERLOGGED.get().get(javaBlockState) ? session.getBlockMappings().getBedrockWater() : session.getBlockMappings().getBedrockAir());
updateWaterPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY);
session.sendUpstreamPacket(updateWaterPacket);
@ -553,12 +546,12 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
}
// Check if the player is interacting with a block
if (!session.isSneaking()) {
if (BlockRegistries.INTERACTIVE.get().contains(blockState)) {
if (BlockRegistries.INTERACTIVE.get().get(blockState)) {
return false;
}
boolean mayBuild = session.getGameMode() == GameMode.SURVIVAL || session.getGameMode() == GameMode.CREATIVE;
if (mayBuild && BlockRegistries.INTERACTIVE_MAY_BUILD.get().contains(blockState)) {
if (mayBuild && BlockRegistries.INTERACTIVE_MAY_BUILD.get().get(blockState)) {
return false;
}
}

View file

@ -51,6 +51,7 @@ import org.geysermc.geyser.entity.type.ItemFrameEntity;
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.registry.type.BlockMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
@ -163,7 +164,7 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
// Account for fire - the client likes to hit the block behind.
Vector3i fireBlockPos = BlockUtils.getBlockPosition(vector, packet.getFace());
int blockUp = session.getGeyser().getWorldManager().getBlockAt(session, fireBlockPos);
String identifier = BlockRegistries.JAVA_IDENTIFIERS.get().get(blockUp);
String identifier = BlockRegistries.JAVA_BLOCKS.getOrDefault(blockUp, BlockMapping.AIR).getJavaIdentifier();
if (identifier.startsWith("minecraft:fire") || identifier.startsWith("minecraft:soul_fire")) {
ServerboundPlayerActionPacket startBreakingPacket = new ServerboundPlayerActionPacket(PlayerAction.START_DIGGING, fireBlockPos,
Direction.VALUES[packet.getFace()], session.getWorldCache().nextPredictionSequence());

View file

@ -31,6 +31,7 @@ import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.registry.type.BlockMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
@ -99,7 +100,7 @@ public class JavaBlockUpdateTranslator extends PacketTranslator<ClientboundBlock
|| lastInteractPos.getZ() != packet.getEntry().getPosition().getZ())) {
return;
}
String identifier = BlockRegistries.JAVA_IDENTIFIERS.get().get(packet.getEntry().getBlock());
String identifier = BlockRegistries.JAVA_BLOCKS.getOrDefault(packet.getEntry().getBlock(), BlockMapping.AIR).getJavaIdentifier();
session.setInteracting(false);
BlockSoundInteractionTranslator.handleBlockInteraction(session, lastInteractPos.toFloat(), identifier);
}

View file

@ -138,7 +138,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
int xzy = indexYZXtoXZY(yzx);
section.getBlockStorageArray()[0].setFullBlock(xzy, bedrockId);
if (BlockRegistries.WATERLOGGED.get().contains(javaId)) {
if (BlockRegistries.WATERLOGGED.get().get(javaId)) {
section.getBlockStorageArray()[1].setFullBlock(xzy, session.getBlockMappings().getBedrockWater().getRuntimeId());
}
@ -160,7 +160,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
int bedrockId = session.getBlockMappings().getBedrockBlockId(javaId);
BlockStorage blockStorage = new BlockStorage(SingletonBitArray.INSTANCE, IntLists.singleton(bedrockId));
if (BlockRegistries.WATERLOGGED.get().contains(javaId)) {
if (BlockRegistries.WATERLOGGED.get().get(javaId)) {
BlockStorage waterlogged = new BlockStorage(SingletonBitArray.INSTANCE, IntLists.singleton(session.getBlockMappings().getBedrockWater()));
sections[bedrockSectionY] = new GeyserChunkSection(new BlockStorage[] {blockStorage, waterlogged});
} else {
@ -179,7 +179,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
int javaId = javaPalette.idToState(i);
bedrockPalette.add(session.getBlockMappings().getBedrockBlockId(javaId));
if (BlockRegistries.WATERLOGGED.get().contains(javaId)) {
if (BlockRegistries.WATERLOGGED.get().get(javaId)) {
waterloggedPaletteIds.set(i);
}

View file

@ -44,7 +44,7 @@ public class GrassPathInteractionTranslator implements BlockSoundInteractionTran
levelSoundEventPacket.setRelativeVolumeDisabled(false);
levelSoundEventPacket.setIdentifier(":");
levelSoundEventPacket.setSound(SoundEvent.ITEM_USE_ON);
levelSoundEventPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(BlockRegistries.JAVA_IDENTIFIERS.get(identifier)));
levelSoundEventPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt(identifier)));
session.sendUpstreamPacket(levelSoundEventPacket);
}
}

View file

@ -44,7 +44,7 @@ public class HoeInteractionTranslator implements BlockSoundInteractionTranslator
levelSoundEventPacket.setRelativeVolumeDisabled(false);
levelSoundEventPacket.setIdentifier(":");
levelSoundEventPacket.setSound(SoundEvent.ITEM_USE_ON);
levelSoundEventPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(BlockRegistries.JAVA_IDENTIFIERS.get(identifier)));
levelSoundEventPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt(identifier)));
session.sendUpstreamPacket(levelSoundEventPacket);
}
}

View file

@ -150,7 +150,7 @@ public class ChunkUtils {
UpdateBlockPacket waterPacket = new UpdateBlockPacket();
waterPacket.setDataLayer(1);
waterPacket.setBlockPosition(position);
if (BlockRegistries.WATERLOGGED.get().contains(blockState)) {
if (BlockRegistries.WATERLOGGED.get().get(blockState)) {
waterPacket.setDefinition(session.getBlockMappings().getBedrockWater());
} else {
waterPacket.setDefinition(session.getBlockMappings().getBedrockAir());

View file

@ -154,7 +154,7 @@ public final class SoundUtils {
soundPacket.setExtraData(soundMapping.getExtraData() + (int)(Math.round((Math.log10(pitch) / Math.log10(2)) * 12)) + 12);
} else if (sound == SoundEvent.PLACE && soundMapping.getExtraData() == -1) {
if (!soundMapping.getIdentifier().equals(":")) {
int javaId = BlockRegistries.JAVA_IDENTIFIERS.getOrDefault(soundMapping.getIdentifier(), BlockStateValues.JAVA_AIR_ID);
int javaId = BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getOrDefault(soundMapping.getIdentifier(), BlockStateValues.JAVA_AIR_ID);
soundPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(javaId));
} else {
session.getGeyser().getLogger().debug("PLACE sound mapping identifier was invalid! Please report: " + soundMapping);

View file

@ -1,200 +0,0 @@
/*
* 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.util.collection;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntCollection;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectSet;
import it.unimi.dsi.fastutil.objects.ObjectSets;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.Objects;
/**
* A primitive int BiMap implementation built around fastutil to
* reduce boxing and the memory footprint. Protocol has a
* {@link org.cloudburstmc.protocol.common.util.Int2ObjectBiMap} class, but it
* does not extend the Map interface making it difficult to utilize
* it in for loops and the registry system.
*
* @param <T> the value
*/
public class Object2IntBiMap<T> implements Object2IntMap<T> {
private final Object2IntMap<T> forwards;
private final Int2ObjectMap<T> backwards;
public Object2IntBiMap() {
this(16);
}
public Object2IntBiMap(int expected) {
this(expected, 0.75F);
}
public Object2IntBiMap(T defaultForwardsValue) {
this(16, 0.75F, defaultForwardsValue, -1);
}
public Object2IntBiMap(int expected, float loadFactor) {
this(expected, loadFactor, -1);
}
public Object2IntBiMap(int expected, float loadFactor, int defaultBackwardsValue) {
this(expected, loadFactor, null, defaultBackwardsValue);
}
public Object2IntBiMap(int expected, float loadFactor, T defaultForwardsValue, int defaultBackwardsValue) {
this.forwards = new Object2IntOpenHashMap<>(expected, loadFactor);
this.backwards = new Int2ObjectOpenHashMap<>(expected, loadFactor);
this.forwards.defaultReturnValue(defaultBackwardsValue);
this.backwards.defaultReturnValue(defaultForwardsValue);
}
@Override
public int size() {
return this.forwards.size();
}
@Override
public boolean isEmpty() {
return this.forwards.isEmpty();
}
@Override
public int getInt(Object o) {
return this.forwards.getInt(o);
}
public T get(int key) {
return this.backwards.get(key);
}
@Override
public int getOrDefault(Object key, int defaultValue) {
return this.forwards.getOrDefault(key, defaultValue);
}
public T getOrDefault(int key, T defaultValue) {
return this.backwards.getOrDefault(key, defaultValue);
}
@Override
public void defaultReturnValue(int i) {
this.forwards.defaultReturnValue(i);
}
public void defaultReturnValue(T v) {
this.backwards.defaultReturnValue(v);
}
@Override
public int defaultReturnValue() {
return this.forwards.defaultReturnValue();
}
public T backwardsDefaultReturnValue() {
return this.backwards.defaultReturnValue();
}
@Override
public ObjectSet<Entry<T>> object2IntEntrySet() {
return ObjectSets.unmodifiable(this.forwards.object2IntEntrySet());
}
public ObjectSet<Int2ObjectMap.Entry<T>> int2ObjectEntrySet() {
return ObjectSets.unmodifiable(this.backwards.int2ObjectEntrySet());
}
@Override
public ObjectSet<T> keySet() {
return this.forwards.keySet();
}
@Override
public IntCollection values() {
return this.forwards.values();
}
@Override
public boolean containsKey(Object o) {
return this.forwards.containsKey(o);
}
@Override
public boolean containsValue(int i) {
return this.backwards.containsKey(i);
}
@Override
public int put(T key, int value) {
this.backwards.put(value, key);
return this.forwards.put(key, value);
}
@Override
public void putAll(@NotNull Map<? extends T, ? extends Integer> m) {
this.forwards.putAll(m);
for (Map.Entry<? extends T, ? extends Integer> entry : m.entrySet()) {
this.backwards.put((int) entry.getValue(), entry.getKey());
}
}
@Override
public int removeInt(Object key) {
if (!this.forwards.containsKey(key)) {
return this.defaultReturnValue();
}
int value = this.forwards.getInt(key);
if (!this.backwards.containsKey(value)) {
return this.defaultReturnValue();
};
this.backwards.remove(value);
return this.forwards.removeInt(key);
}
@Override
public int hashCode() {
return this.forwards.hashCode();
}
@Override
public String toString() {
return this.forwards.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Object2IntBiMap<?> that = (Object2IntBiMap<?>) o;
return Objects.equals(this.forwards, that.forwards) && Objects.equals(this.backwards, that.backwards);
}
}