mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Small optimizations and BlockStateValues reduction
This commit is contained in:
parent
f489fd3b98
commit
db166ad8de
12 changed files with 97 additions and 65 deletions
|
@ -41,6 +41,7 @@ import org.bukkit.event.block.BlockPistonRetractEvent;
|
|||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
import org.geysermc.geyser.level.physics.Direction;
|
||||
import org.geysermc.geyser.platform.spigot.world.manager.GeyserSpigotWorldManager;
|
||||
|
@ -120,7 +121,7 @@ public class GeyserPistonListener implements Listener {
|
|||
|
||||
int pistonBlockId = worldManager.getBlockNetworkId(event.getBlock());
|
||||
// event.getDirection() is unreliable
|
||||
Direction orientation = BlockStateValues.getPistonOrientation(pistonBlockId);
|
||||
Direction orientation = BlockState.of(pistonBlockId).getValue(Properties.FACING);
|
||||
|
||||
session.executeInEventLoop(() -> {
|
||||
PistonCache pistonCache = session.getPistonCache();
|
||||
|
|
|
@ -42,7 +42,6 @@ import org.geysermc.erosion.bukkit.SchedulerUtils;
|
|||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.level.GameRule;
|
||||
import org.geysermc.geyser.level.WorldManager;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.BlockEntityUtils;
|
||||
|
@ -88,7 +87,7 @@ public class GeyserSpigotWorldManager extends WorldManager {
|
|||
Bukkit.getRegionScheduler().execute(this.plugin, block.getLocation(), () -> blockData.complete(block.getBlockData().getAsString()));
|
||||
return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(blockData.join(), org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID);
|
||||
}
|
||||
return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(block.getBlockData().getAsString(), org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID);
|
||||
return BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(block.getBlockData().getAsString(), org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID); // TODO could just make this a BlockState lookup?
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -44,6 +44,7 @@ import org.geysermc.erosion.packet.backendbound.BackendboundInitializePacket;
|
|||
import org.geysermc.erosion.packet.backendbound.BackendboundPacket;
|
||||
import org.geysermc.erosion.packet.geyserbound.*;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
import org.geysermc.geyser.level.physics.Direction;
|
||||
|
@ -148,7 +149,7 @@ public final class GeyserboundPacketHandlerImpl extends AbstractGeyserboundPacke
|
|||
|
||||
@Override
|
||||
public void handlePistonEvent(GeyserboundPistonEventPacket packet) {
|
||||
Direction orientation = BlockStateValues.getPistonOrientation(packet.getBlockId());
|
||||
Direction orientation = BlockState.of(packet.getBlockId()).getValue(Properties.FACING);
|
||||
Vector3i position = packet.getPos();
|
||||
boolean isExtend = packet.isExtend();
|
||||
|
||||
|
|
|
@ -25,7 +25,10 @@
|
|||
|
||||
package org.geysermc.geyser.level.block;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
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 org.geysermc.geyser.level.block.property.Properties;
|
||||
|
@ -36,16 +39,11 @@ import org.geysermc.geyser.level.physics.Direction;
|
|||
import org.geysermc.geyser.level.physics.PistonBehavior;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Used for block entities if the Java block state contains Bedrock block information.
|
||||
*/
|
||||
public final class BlockStateValues {
|
||||
private static final IntSet HORIZONTAL_FACING_JIGSAWS = new IntOpenHashSet();
|
||||
private static final IntSet STICKY_PISTONS = new IntOpenHashSet();
|
||||
private static final Object2IntMap<Direction> PISTON_HEADS = new Object2IntOpenHashMap<>();
|
||||
private static final Int2ObjectMap<Direction> PISTON_ORIENTATION = new Int2ObjectOpenHashMap<>();
|
||||
private static final IntSet ALL_PISTON_HEADS = new IntOpenHashSet();
|
||||
private static final Int2IntMap WATER_LEVEL = new Int2IntOpenHashMap();
|
||||
|
||||
|
@ -61,10 +59,6 @@ public final class BlockStateValues {
|
|||
*/
|
||||
public static void storeBlockStateValues(String javaId, int javaBlockState) {
|
||||
if (javaId.contains("piston[")) { // minecraft:moving_piston, minecraft:sticky_piston, minecraft:piston
|
||||
if (javaId.contains("sticky")) {
|
||||
STICKY_PISTONS.add(javaBlockState);
|
||||
}
|
||||
PISTON_ORIENTATION.put(javaBlockState, getBlockDirection(javaId));
|
||||
return;
|
||||
} else if (javaId.startsWith("minecraft:piston_head")) {
|
||||
ALL_PISTON_HEADS.add(javaBlockState);
|
||||
|
@ -78,27 +72,7 @@ public final class BlockStateValues {
|
|||
String strLevel = javaId.substring(javaId.lastIndexOf("level=") + 6, javaId.length() - 1);
|
||||
int level = Integer.parseInt(strLevel);
|
||||
WATER_LEVEL.put(javaBlockState, level);
|
||||
return;
|
||||
}
|
||||
|
||||
if (javaId.startsWith("minecraft:jigsaw[orientation=")) {
|
||||
String blockStateData = javaId.substring(javaId.indexOf("orientation=") + "orientation=".length(), javaId.lastIndexOf('_'));
|
||||
Direction direction = Direction.valueOf(blockStateData.toUpperCase(Locale.ROOT));
|
||||
if (direction.isHorizontal()) {
|
||||
HORIZONTAL_FACING_JIGSAWS.add(javaBlockState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a set of all forward-facing jigsaws, to use as a fallback if NBT is missing.
|
||||
*/
|
||||
public static IntSet getHorizontalFacingJigsaws() {
|
||||
return HORIZONTAL_FACING_JIGSAWS;
|
||||
}
|
||||
|
||||
public static boolean isStickyPiston(int blockState) {
|
||||
return STICKY_PISTONS.contains(blockState);
|
||||
}
|
||||
|
||||
public static boolean isPistonHead(int state) {
|
||||
|
@ -116,17 +90,6 @@ public final class BlockStateValues {
|
|||
return PISTON_HEADS.getOrDefault(direction, Block.JAVA_AIR_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used in GeyserPistonEvents.java and accepts minecraft:piston,
|
||||
* minecraft:sticky_piston, and minecraft:moving_piston.
|
||||
*
|
||||
* @param state The block state of the piston base
|
||||
* @return The direction in which the piston faces
|
||||
*/
|
||||
public static Direction getPistonOrientation(int state) {
|
||||
return PISTON_ORIENTATION.get(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a block sticks to other blocks
|
||||
* (Slime and honey blocks)
|
||||
|
|
|
@ -27,6 +27,7 @@ package org.geysermc.geyser.level.block;
|
|||
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.level.block.property.ChestType;
|
||||
import org.geysermc.geyser.level.block.property.FrontAndTop;
|
||||
import org.geysermc.geyser.level.block.type.*;
|
||||
import org.geysermc.geyser.level.physics.Axis;
|
||||
import org.geysermc.geyser.level.physics.Direction;
|
||||
|
@ -2169,7 +2170,7 @@ public final class Blocks {
|
|||
public static final Block STRUCTURE_BLOCK = register(new Block("structure_block", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f)
|
||||
.enumState(STRUCTUREBLOCK_MODE, "save", "load", "corner", "data")));
|
||||
public static final Block JIGSAW = register(new Block("jigsaw", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(-1.0f)
|
||||
.enumState(ORIENTATION, "down_east", "down_north", "down_south", "down_west", "up_east", "up_north", "up_south", "up_west", "west_up", "east_up", "north_up", "south_up")));
|
||||
.enumState(ORIENTATION, FrontAndTop.VALUES)));
|
||||
public static final Block COMPOSTER = register(new Block("composter", builder().destroyTime(0.6f)
|
||||
.intState(LEVEL_COMPOSTER, 0, 8)));
|
||||
public static final Block TARGET = register(new Block("target", builder().destroyTime(0.5f)
|
||||
|
@ -2799,7 +2800,7 @@ public final class Blocks {
|
|||
.booleanState(WATERLOGGED)));
|
||||
public static final Block CRAFTER = register(new Block("crafter", builder().setBlockEntity().destroyTime(1.5f)
|
||||
.booleanState(CRAFTING)
|
||||
.enumState(ORIENTATION, "down_east", "down_north", "down_south", "down_west", "up_east", "up_north", "up_south", "up_west", "west_up", "east_up", "north_up", "south_up")
|
||||
.enumState(ORIENTATION, FrontAndTop.VALUES)
|
||||
.booleanState(TRIGGERED)));
|
||||
public static final Block TRIAL_SPAWNER = register(new Block("trial_spawner", builder().setBlockEntity().requiresCorrectToolForDrops().destroyTime(50.0f)
|
||||
.booleanState(OMINOUS)
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.level.block.property;
|
||||
|
||||
import org.geysermc.geyser.level.physics.Direction;
|
||||
|
||||
public enum FrontAndTop {
|
||||
DOWN_EAST(Direction.DOWN),
|
||||
DOWN_NORTH(Direction.DOWN),
|
||||
DOWN_SOUTH(Direction.DOWN),
|
||||
DOWN_WEST(Direction.DOWN),
|
||||
UP_EAST(Direction.UP),
|
||||
UP_NORTH(Direction.UP),
|
||||
UP_SOUTH(Direction.UP),
|
||||
UP_WEST(Direction.UP),
|
||||
WEST_UP(Direction.WEST),
|
||||
EAST_UP(Direction.EAST),
|
||||
NORTH_UP(Direction.NORTH),
|
||||
SOUTH_UP(Direction.SOUTH);
|
||||
|
||||
private final boolean horizontal;
|
||||
|
||||
FrontAndTop(Direction front) {
|
||||
this.horizontal = front.isHorizontal();
|
||||
}
|
||||
|
||||
public boolean isHorizontal() {
|
||||
return horizontal;
|
||||
}
|
||||
|
||||
public static final FrontAndTop[] VALUES = values();
|
||||
}
|
|
@ -74,7 +74,7 @@ public final class Properties {
|
|||
public static final Property<Direction> FACING_HOPPER = Property.create("facing");
|
||||
public static final Property<Direction> HORIZONTAL_FACING = Property.create("facing");
|
||||
public static final Property<Integer> FLOWER_AMOUNT = Property.create("flower_amount");
|
||||
public static final Property<String> ORIENTATION = Property.create("orientation");
|
||||
public static final Property<FrontAndTop> ORIENTATION = Property.create("orientation");
|
||||
public static final Property<String> ATTACH_FACE = Property.create("face");
|
||||
public static final Property<String> BELL_ATTACHMENT = Property.create("attachment");
|
||||
public static final Property<String> EAST_WALL = Property.create("east");
|
||||
|
|
|
@ -28,10 +28,13 @@ package org.geysermc.geyser.registry;
|
|||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.registry.loader.RegistryLoader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ListRegistry<M> extends Registry<List<M>> {
|
||||
private boolean frozen = false;
|
||||
|
||||
/**
|
||||
* Creates a new instance of this class with the given input and
|
||||
* {@link RegistryLoader}. The input specified is what the registry
|
||||
|
@ -85,9 +88,24 @@ public class ListRegistry<M> extends Registry<List<M>> {
|
|||
* @return a new value into this registry with the given index.
|
||||
*/
|
||||
public M register(int index, M value) {
|
||||
if (this.frozen) {
|
||||
throw new IllegalStateException("Registry should not be modified after frozen!");
|
||||
}
|
||||
return this.mappings.set(index, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark this registry as unsuitable for new additions. The backing list will then be optimized for storage.
|
||||
*/
|
||||
public void freeze() {
|
||||
if (!this.frozen) {
|
||||
this.frozen = true;
|
||||
if (this.mappings instanceof ArrayList<M> arrayList) {
|
||||
arrayList.trimToSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new array registry with the given {@link RegistryLoader}. The
|
||||
* input type is not specified here, meaning the loader return type is either
|
||||
|
|
|
@ -77,7 +77,7 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader<String,
|
|||
}
|
||||
|
||||
List<BlockState> blockStates = BlockRegistries.BLOCK_STATES.get();
|
||||
List<BlockCollision> collisions = new ObjectArrayList<>(blockStates.size());
|
||||
var collisions = new ObjectArrayList<BlockCollision>(blockStates.size());
|
||||
|
||||
// Map of unique collisions to its instance
|
||||
Map<BlockCollision, BlockCollision> collisionInstances = new Object2ObjectOpenHashMap<>();
|
||||
|
@ -102,6 +102,7 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader<String,
|
|||
|
||||
collisions.add(newCollision);
|
||||
}
|
||||
collisions.trim();
|
||||
return collisions;
|
||||
}
|
||||
|
||||
|
|
|
@ -440,15 +440,8 @@ public final class BlockRegistryPopulator {
|
|||
|
||||
BlockStateValues.storeBlockStateValues(javaId, javaRuntimeId);
|
||||
|
||||
//String cleanJavaIdentifier = javaBlockState.block().javaIdentifier().toString();
|
||||
//String bedrockIdentifier = entry.getValue().get("bedrock_identifier").asText();
|
||||
|
||||
BlockRegistries.JAVA_IDENTIFIER_TO_ID.register(javaId, javaRuntimeId);
|
||||
|
||||
// Keeping this here since this is currently unchanged between versions
|
||||
// It's possible to only have this store differences in names, but the key set of all Java names is used in sending command suggestions
|
||||
//BlockRegistries.JAVA_TO_BEDROCK_IDENTIFIERS.register(cleanJavaIdentifier.intern(), bedrockIdentifier.intern());
|
||||
|
||||
if ("minecraft:water[level=0]".equals(javaId)) {
|
||||
waterRuntimeId = javaRuntimeId;
|
||||
}
|
||||
|
@ -467,8 +460,6 @@ public final class BlockRegistryPopulator {
|
|||
throw new RuntimeException("Duplicate runtime ID " + javaBlockState.javaId() + " for non vanilla Java block state " + javaBlockState.identifier());
|
||||
}
|
||||
|
||||
CustomBlockState customBlockState = BlockRegistries.NON_VANILLA_BLOCK_STATE_OVERRIDES.get().get(javaBlockState);
|
||||
|
||||
String javaId = javaBlockState.identifier();
|
||||
int stateRuntimeId = javaBlockState.javaId();
|
||||
String pistonBehavior = javaBlockState.pistonBehavior();
|
||||
|
@ -517,6 +508,8 @@ public final class BlockRegistryPopulator {
|
|||
|
||||
BlockRegistries.INTERACTIVE.set(toBlockStateSet((ArrayNode) blockInteractionsJson.get("always_consumes")));
|
||||
BlockRegistries.INTERACTIVE_MAY_BUILD.set(toBlockStateSet((ArrayNode) blockInteractionsJson.get("requires_may_build")));
|
||||
|
||||
BlockRegistries.BLOCK_STATES.freeze();
|
||||
}
|
||||
|
||||
private static BitSet toBlockStateSet(ArrayNode node) {
|
||||
|
|
|
@ -28,7 +28,7 @@ package org.geysermc.geyser.translator.level.block.entity;
|
|||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
|
@ -47,7 +47,7 @@ public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator impl
|
|||
} else {
|
||||
// Tag is not present in at least 1.14.4 Paper
|
||||
// Minecraft 1.18.1 deliberately has a fallback here, but not for any other value
|
||||
bedrockNbt.putString("joint", BlockStateValues.getHorizontalFacingJigsaws().contains(blockState.javaId()) ? "aligned" : "rollable"); // TODO
|
||||
bedrockNbt.putString("joint", blockState.getValue(Properties.ORIENTATION).isHorizontal() ? "aligned" : "rollable");
|
||||
}
|
||||
bedrockNbt.putString("name", javaNbt.getString("name"));
|
||||
bedrockNbt.putString("target_pool", javaNbt.getString("target_pool"));
|
||||
|
|
|
@ -31,7 +31,7 @@ import org.cloudburstmc.nbt.NbtMapBuilder;
|
|||
import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BlockEventPacket;
|
||||
import org.geysermc.geyser.api.util.PlatformType;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
|
@ -78,8 +78,8 @@ public class JavaBlockEventTranslator extends PacketTranslator<ClientboundBlockE
|
|||
// Retracting sticky pistons is an exception, since the event is not called on Spigot from 1.13.2 - 1.17.1
|
||||
// See https://github.com/PaperMC/Paper/blob/6fa1983e9ce177a4a412d5b950fd978620174777/patches/server/0304-Fire-BlockPistonRetractEvent-for-all-empty-pistons.patch
|
||||
if (action == PistonValueType.PULLING || action == PistonValueType.CANCELLED_MID_PUSH) {
|
||||
int pistonBlock = session.getGeyser().getWorldManager().getBlockAt(session, position);
|
||||
if (!BlockStateValues.isStickyPiston(pistonBlock)) {
|
||||
BlockState pistonBlock = session.getGeyser().getWorldManager().blockAt(session, position);
|
||||
if (!pistonBlock.is(Blocks.STICKY_PISTON)) {
|
||||
return;
|
||||
}
|
||||
if (action != PistonValueType.CANCELLED_MID_PUSH) {
|
||||
|
@ -97,8 +97,8 @@ public class JavaBlockEventTranslator extends PacketTranslator<ClientboundBlockE
|
|||
}
|
||||
} else {
|
||||
PistonBlockEntity blockEntity = pistonCache.getPistons().computeIfAbsent(position, pos -> {
|
||||
int blockId = session.getGeyser().getWorldManager().getBlockAt(session, position);
|
||||
boolean sticky = BlockStateValues.isStickyPiston(blockId);
|
||||
BlockState state = session.getGeyser().getWorldManager().blockAt(session, position);
|
||||
boolean sticky = state.is(Blocks.STICKY_PISTON);
|
||||
boolean extended = action != PistonValueType.PUSHING;
|
||||
return new PistonBlockEntity(session, pos, direction, sticky, extended);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue