1
0
mirror of https://github.com/GeyserMC/Geyser.git synced 2025-12-19 14:59:27 +00:00

Fix block by Java key lookup (#5637)

* Fix block by Java key lookup, optimise hardcoded lookup a bit, clarify Javadocs

* Rename the registry too
This commit is contained in:
Eclipse
2025-07-01 12:33:37 +00:00
committed by GitHub
parent d7d819c282
commit 92d12bf7bc
8 changed files with 34 additions and 32 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_IDENTIFIER_TO_ID.get().getOrDefault(javaBlockId, Block.JAVA_AIR_ID)));
placeBlockSoundPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(BlockRegistries.JAVA_BLOCK_STATE_IDENTIFIER_TO_ID.get().getOrDefault(javaBlockId, Block.JAVA_AIR_ID)));
}
placeBlockSoundPacket.setIdentifier(":");
session.sendUpstreamPacket(placeBlockSoundPacket);

View File

@@ -76,9 +76,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_IDENTIFIER_TO_ID.getOrDefault(blockData.join(), org.geysermc.geyser.level.block.type.Block.JAVA_AIR_ID);
return BlockRegistries.JAVA_BLOCK_STATE_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); // TODO could just make this a BlockState lookup?
return BlockRegistries.JAVA_BLOCK_STATE_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

View File

@@ -78,9 +78,9 @@ public class BlockRegistries {
public static final ListRegistry<Block> JAVA_BLOCKS = ListRegistry.create(RegistryLoaders.empty(ArrayList::new));
/**
* A mapped registry containing the Java identifiers to IDs.
* A mapped registry containing the Java block state identifiers to IDs.
*/
public static final MappedRegistry<String, Integer, Object2IntMap<String>> JAVA_IDENTIFIER_TO_ID = MappedRegistry.create(RegistryLoaders.empty(Object2IntOpenHashMap::new));
public static final MappedRegistry<String, Integer, Object2IntMap<String>> JAVA_BLOCK_STATE_IDENTIFIER_TO_ID = MappedRegistry.create(RegistryLoaders.empty(Object2IntOpenHashMap::new));
/**
* A registry containing non-vanilla block IDS.

View File

@@ -262,7 +262,7 @@ public class MappingsReader_v1 extends MappingsReader {
.creativeCategory(creativeCategory)
.creativeGroup(creativeGroup);
if (BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().containsKey(identifier)) {
if (BlockRegistries.JAVA_BLOCK_STATE_IDENTIFIER_TO_ID.get().containsKey(identifier)) {
// There is only one Java block state to override
CustomBlockComponentsMapping componentsMapping = createCustomBlockComponentsMapping(node, identifier, name);
CustomBlockData blockData = customBlockDataBuilder
@@ -280,7 +280,7 @@ public class MappingsReader_v1 extends MappingsReader {
while (fields.hasNext()) {
Map.Entry<String, JsonNode> overrideEntry = fields.next();
String state = identifier + "[" + overrideEntry.getKey() + "]";
if (!BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().containsKey(state)) {
if (!BlockRegistries.JAVA_BLOCK_STATE_IDENTIFIER_TO_ID.get().containsKey(state)) {
throw new InvalidCustomMappingsFileException("Unknown Java block state: " + state + " for state_overrides.");
}
componentsMap.put(state, createCustomBlockComponentsMapping(overrideEntry.getValue(), state, name));
@@ -292,7 +292,7 @@ public class MappingsReader_v1 extends MappingsReader {
if (!onlyOverrideStates) {
// Create components for any remaining Java block states
BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().keySet()
BlockRegistries.JAVA_BLOCK_STATE_IDENTIFIER_TO_ID.get().keySet()
.stream()
.filter(s -> s.startsWith(identifier + "["))
.filter(Predicate.not(componentsMap::containsKey))
@@ -365,7 +365,7 @@ public class MappingsReader_v1 extends MappingsReader {
*/
private CustomBlockComponentsMapping createCustomBlockComponentsMapping(JsonNode node, String stateKey, String name) {
// This is needed to find the correct selection box for the given block
int id = BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(stateKey, -1);
int id = BlockRegistries.JAVA_BLOCK_STATE_IDENTIFIER_TO_ID.getOrDefault(stateKey, -1);
BoxComponent boxComponent = createBoxComponent(id);
BoxComponent extendedBoxComponent = createExtendedBoxComponent(id);
CustomBlockComponents.Builder builder = new GeyserCustomBlockComponents.Builder()

View File

@@ -421,7 +421,7 @@ public final class BlockRegistryPopulator {
javaRuntimeId++;
String javaId = javaBlockState.toString().intern();
BlockRegistries.JAVA_IDENTIFIER_TO_ID.register(javaId, javaRuntimeId);
BlockRegistries.JAVA_BLOCK_STATE_IDENTIFIER_TO_ID.register(javaId, javaRuntimeId);
}
BLOCKS_NBT = blocksNbt;
@@ -441,7 +441,7 @@ public final class BlockRegistryPopulator {
private static BitSet toBlockStateSet(ArrayNode node) {
BitSet blockStateSet = new BitSet(node.size());
for (JsonNode javaIdentifier : node) {
blockStateSet.set(BlockRegistries.JAVA_IDENTIFIER_TO_ID.get().getInt(javaIdentifier.textValue()));
blockStateSet.set(BlockRegistries.JAVA_BLOCK_STATE_IDENTIFIER_TO_ID.get().getInt(javaIdentifier.textValue()));
}
return blockStateSet;
}

View File

@@ -188,7 +188,7 @@ public class CustomBlockRegistryPopulator {
}
for(Map.Entry<String, CustomBlockState> entry : BLOCK_STATE_OVERRIDES_QUEUE.entrySet()) {
int id = BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(entry.getKey(), -1);
int id = BlockRegistries.JAVA_BLOCK_STATE_IDENTIFIER_TO_ID.getOrDefault(entry.getKey(), -1);
if (id == -1) {
GeyserImpl.getInstance().getLogger().warning("Custom block state override for Java Identifier: " +
entry.getKey() + " could not be registered as it is not a valid block state.");
@@ -212,7 +212,7 @@ public class CustomBlockRegistryPopulator {
CUSTOM_BLOCK_ITEM_OVERRIDES.put(block.javaIdentifier(), block.data());
}
block.states().forEach((javaIdentifier, customBlockState) -> {
int id = BlockRegistries.JAVA_IDENTIFIER_TO_ID.getOrDefault(javaIdentifier, -1);
int id = BlockRegistries.JAVA_BLOCK_STATE_IDENTIFIER_TO_ID.getOrDefault(javaIdentifier, -1);
blockStateOverrides.put(id, customBlockState.state());
BoxComponent extendedCollisionBox = customBlockState.extendedCollisionBox();
if (extendedCollisionBox != null) {
@@ -302,7 +302,7 @@ public class CustomBlockRegistryPopulator {
block.setJavaId(javaBlockState.stateGroupId());
BlockRegistries.JAVA_BLOCKS.registerWithAnyIndex(javaBlockState.stateGroupId(), block, Blocks.AIR);
BlockRegistries.JAVA_IDENTIFIER_TO_ID.register(javaId, stateRuntimeId);
BlockRegistries.JAVA_BLOCK_STATE_IDENTIFIER_TO_ID.register(javaId, stateRuntimeId);
BlockRegistries.NON_VANILLA_BLOCK_IDS.register(set -> set.set(stateRuntimeId));
// TODO register different collision types?

View File

@@ -64,15 +64,17 @@ public class JavaRegistries {
private static final List<JavaRegistryKey<?>> VALUES = new ArrayList<>();
public static final JavaRegistryKey<Block> BLOCK = createHardcoded("block", BlockRegistries.JAVA_BLOCKS,
Block::javaId, Block::javaIdentifier, key -> Optional.ofNullable(BlockRegistries.JAVA_IDENTIFIER_TO_ID.get(key.asString())).orElse(-1));
Block::javaId, Block::javaIdentifier, key -> BlockRegistries.JAVA_BLOCKS.get().stream()
.filter(block -> block.javaIdentifier().equals(key))
.findFirst());
public static final JavaRegistryKey<Item> ITEM = createHardcoded("item", Registries.JAVA_ITEMS,
Item::javaId, Item::javaKey, key -> Optional.ofNullable(Registries.JAVA_ITEM_IDENTIFIERS.get(key.asString())).map(Item::javaId).orElse(-1));
Item::javaId, Item::javaKey, key -> Optional.ofNullable(Registries.JAVA_ITEM_IDENTIFIERS.get(key.asString())));
public static JavaRegistryKey<EntityType> ENTITY_TYPE = createHardcoded("entity_type", Arrays.asList(EntityType.values()), EntityType::ordinal,
type -> MinecraftKey.key(type.name().toLowerCase(Locale.ROOT)), key -> {
try {
return EntityType.valueOf(key.value().toUpperCase(Locale.ROOT)).ordinal();
return Optional.of(EntityType.valueOf(key.value().toUpperCase(Locale.ROOT)));
} catch (IllegalArgumentException exception) {
return -1; // Non-existent entity type
return Optional.empty(); // Non-existent entity type
}
});
@@ -105,13 +107,13 @@ public class JavaRegistries {
}
private static <T> JavaRegistryKey<T> createHardcoded(String key, ListRegistry<T> registry, RegistryNetworkMapper<T> networkSerializer,
RegistryIdentifierMapper<T> identifierMapper, RegistryIdMapper idMapper) {
return createHardcoded(key, registry.get(), networkSerializer, identifierMapper, idMapper);
RegistryObjectIdentifierMapper<T> objectIdentifierMapper, RegistryIdentifierObjectMapper<T> identifierObjectMapper) {
return createHardcoded(key, registry.get(), networkSerializer, objectIdentifierMapper, identifierObjectMapper);
}
private static <T> JavaRegistryKey<T> createHardcoded(String key, List<T> registry, RegistryNetworkMapper<T> networkSerializer,
RegistryIdentifierMapper<T> identifierMapper, RegistryIdMapper idMapper) {
return create(key, new HardcodedLookup<>(registry, networkSerializer, identifierMapper, idMapper));
RegistryObjectIdentifierMapper<T> objectIdentifierMapper, RegistryIdentifierObjectMapper<T> identifierObjectMapper) {
return create(key, new HardcodedLookup<>(registry, networkSerializer, objectIdentifierMapper, identifierObjectMapper));
}
private static <T> JavaRegistryKey<T> create(String key) {
@@ -135,37 +137,37 @@ public class JavaRegistries {
}
@FunctionalInterface
interface RegistryIdentifierMapper<T> {
interface RegistryObjectIdentifierMapper<T> {
Key get(T object);
}
@FunctionalInterface
interface RegistryIdMapper {
interface RegistryIdentifierObjectMapper<T> {
int get(Key key);
Optional<T> get(Key key);
}
private record HardcodedLookup<T>(List<T> registry, RegistryNetworkMapper<T> networkMapper, RegistryIdentifierMapper<T> identifierMapper,
RegistryIdMapper idMapper) implements JavaRegistryKey.RegistryLookup<T> {
private record HardcodedLookup<T>(List<T> registry, RegistryNetworkMapper<T> networkMapper, RegistryObjectIdentifierMapper<T> objectIdentifierMapper,
RegistryIdentifierObjectMapper<T> identifierObjectMapper) implements JavaRegistryKey.RegistryLookup<T> {
@Override
public Optional<RegistryEntryData<T>> entry(GeyserSession session, JavaRegistryKey<T> registryKey, int networkId) {
return Optional.ofNullable(registry.get(networkId))
.map(value -> new RegistryEntryData<>(networkId, Objects.requireNonNull(identifierMapper.get(value)), value));
.map(value -> new RegistryEntryData<>(networkId, Objects.requireNonNull(objectIdentifierMapper.get(value)), value));
}
@Override
public Optional<RegistryEntryData<T>> entry(GeyserSession session, JavaRegistryKey<T> registryKey, Key key) {
int id = idMapper.get(key);
return Optional.ofNullable(registry.get(id)).map(value -> new RegistryEntryData<>(id, key, value));
Optional<T> object = identifierObjectMapper.get(key);
return object.map(value -> new RegistryEntryData<>(networkMapper.get(value), key, value));
}
@Override
public Optional<RegistryEntryData<T>> entry(GeyserSession session, JavaRegistryKey<T> registryKey, T object) {
int id = networkMapper.get(object);
return Optional.ofNullable(registry.get(id))
.map(value -> new RegistryEntryData<>(id, Objects.requireNonNull(identifierMapper.get(value)), value));
.map(value -> new RegistryEntryData<>(id, Objects.requireNonNull(objectIdentifierMapper.get(value)), value));
}
}

View File

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