mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Use an array for java blocks and replace rarely used map in BlockMappings
This commit is contained in:
parent
206368e448
commit
64b0788012
7 changed files with 185 additions and 26 deletions
|
@ -232,11 +232,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
if (packet.getActions().isEmpty()) {
|
||||
if (session.getOpPermissionLevel() >= 2 && session.getGameMode() == GameMode.CREATIVE) {
|
||||
// Otherwise insufficient permissions
|
||||
int blockState = session.getBlockMappings().getJavaBlockState(packet.getBlockRuntimeId());
|
||||
String blockName = BlockRegistries.JAVA_IDENTIFIERS.get().getOrDefault(blockState, "");
|
||||
// In the future this can be used for structure blocks too, however not all elements
|
||||
// are available in each GUI
|
||||
if (blockName.contains("jigsaw")) {
|
||||
if (session.getBlockMappings().getJigsawStateIds().contains(packet.getBlockRuntimeId())) {
|
||||
ContainerOpenPacket openPacket = new ContainerOpenPacket();
|
||||
openPacket.setBlockPosition(packet.getBlockPosition());
|
||||
openPacket.setId((byte) 1);
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021 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.connector.registry;
|
||||
|
||||
import org.geysermc.connector.registry.loader.RegistryLoader;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* An array registry that stores mappings as an array defined by {@link M}.
|
||||
* The M represents the value that is to be stored as part of this array.
|
||||
*
|
||||
* @param <M> the mapping type
|
||||
*/
|
||||
public class ArrayRegistry<M> extends Registry<M[]> {
|
||||
|
||||
/**
|
||||
* Creates a new array registry of this class with the given input and
|
||||
* {@link RegistryLoader}. The input specified is what the registry
|
||||
* loader needs to take in.
|
||||
*
|
||||
* @param input the input
|
||||
* @param registryLoader the registry loader
|
||||
*/
|
||||
protected <I> ArrayRegistry(I input, RegistryLoader<I, M[]> registryLoader) {
|
||||
super(input, registryLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value registered by the given index.
|
||||
*
|
||||
* @param index the index
|
||||
* @return the value registered by the given index.
|
||||
*/
|
||||
@Nullable
|
||||
public M get(int index) {
|
||||
if (index >= this.mappings.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.mappings[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value registered by the given index or the default value
|
||||
* specified if null.
|
||||
*
|
||||
* @param index the index
|
||||
* @param defaultValue the default value
|
||||
* @return the value registered by the given key or the default value
|
||||
* specified if null.
|
||||
*/
|
||||
public M getOrDefault(int index, M defaultValue) {
|
||||
M value = this.get(index);
|
||||
if (value == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new value into this registry with the given index.
|
||||
*
|
||||
* @param index the index
|
||||
* @param value the value
|
||||
* @return a new value into this registry with the given index.
|
||||
*/
|
||||
public M register(int index, M value) {
|
||||
return this.mappings[index] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new array registry with the given {@link RegistryLoader} supplier. The
|
||||
* input type is not specified here, meaning the loader return type is either
|
||||
* predefined, or the registry is populated at a later point.
|
||||
*
|
||||
* @param registryLoader the registry loader supplier
|
||||
* @param <I> the input type
|
||||
* @param <M> the returned mappings type
|
||||
* @return a new registry with the given RegistryLoader supplier
|
||||
*/
|
||||
public static <I, M> ArrayRegistry<M> create(Supplier<RegistryLoader<I, M[]>> registryLoader) {
|
||||
return new ArrayRegistry<>(null, registryLoader.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new array registry with the given {@link RegistryLoader} supplier
|
||||
* and input.
|
||||
*
|
||||
* @param input the input
|
||||
* @param registryLoader the registry loader supplier
|
||||
* @param <I> the input type
|
||||
* @param <M> the returned mappings type
|
||||
* @return a new registry with the given RegistryLoader supplier
|
||||
*/
|
||||
public static <I, M> ArrayRegistry<M> create(I input, Supplier<RegistryLoader<I, M[]>> registryLoader) {
|
||||
return new ArrayRegistry<>(input, registryLoader.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new array registry with the given {@link RegistryLoader}. The
|
||||
* input type is not specified here, meaning the loader return type is either
|
||||
* predefined, or the registry is populated at a later point.
|
||||
*
|
||||
* @param registryLoader the registry loader
|
||||
* @param <I> the input type
|
||||
* @param <M> the returned mappings type
|
||||
* @return a new registry with the given RegistryLoader supplier
|
||||
*/
|
||||
public static <I, M> ArrayRegistry<M> create(RegistryLoader<I, M[]> registryLoader) {
|
||||
return new ArrayRegistry<>(null, registryLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new array registry with the given {@link RegistryLoader} and input.
|
||||
*
|
||||
* @param input the input
|
||||
* @param registryLoader the registry loader
|
||||
* @param <I> the input type
|
||||
* @param <M> the returned mappings type
|
||||
* @return a new registry with the given RegistryLoader supplier
|
||||
*/
|
||||
public static <I, M> ArrayRegistry<M> create(I input, RegistryLoader<I, M[]> registryLoader) {
|
||||
return new ArrayRegistry<>(input, registryLoader);
|
||||
}
|
||||
}
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
package org.geysermc.connector.registry;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
|
@ -52,10 +51,10 @@ public class BlockRegistries {
|
|||
public static final SimpleMappedRegistry<String, String> JAVA_TO_BEDROCK_IDENTIFIERS = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new));
|
||||
|
||||
/**
|
||||
* A mapped registry which stores Java IDs to {@link BlockMapping}, containing miscellaneous information about
|
||||
* A registry which stores Java IDs to {@link BlockMapping}, containing miscellaneous information about
|
||||
* blocks and their behavior in many cases.
|
||||
*/
|
||||
public static final MappedRegistry<Integer, BlockMapping, Int2ObjectMap<BlockMapping>> JAVA_BLOCKS = MappedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new));
|
||||
public static final ArrayRegistry<BlockMapping> JAVA_BLOCKS = ArrayRegistry.create(RegistryLoaders.empty(() -> new BlockMapping[] {}));
|
||||
|
||||
/**
|
||||
* A (bi)mapped registry containing the Java IDs to identifiers.
|
||||
|
|
|
@ -64,7 +64,7 @@ import java.util.function.Consumer;
|
|||
* @param <M> the value being held by the registry
|
||||
*/
|
||||
public abstract class Registry<M> {
|
||||
protected final M mappings;
|
||||
protected M mappings;
|
||||
|
||||
/**
|
||||
* Creates a new instance of this class with the given input and
|
||||
|
@ -88,6 +88,17 @@ public abstract class Registry<M> {
|
|||
return this.mappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the underlying value held by this registry.
|
||||
* Clears any existing data associated with the previous
|
||||
* value.
|
||||
*
|
||||
* @param mappings the underlying value held by this registry
|
||||
*/
|
||||
public void set(M mappings) {
|
||||
this.mappings = mappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers what is specified in the given
|
||||
* {@link Consumer} into the underlying value.
|
||||
|
|
|
@ -75,12 +75,13 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader<String,
|
|||
throw new AssertionError("Unable to load collision data", e);
|
||||
}
|
||||
|
||||
Int2ObjectMap<BlockMapping> blockMap = BlockRegistries.JAVA_BLOCKS.get();
|
||||
BlockMapping[] blockMappings = BlockRegistries.JAVA_BLOCKS.get();
|
||||
|
||||
// Map of unique collisions to its instance
|
||||
Map<BlockCollision, BlockCollision> collisionInstances = new Object2ObjectOpenHashMap<>();
|
||||
for (Int2ObjectMap.Entry<BlockMapping> entry : blockMap.int2ObjectEntrySet()) {
|
||||
BlockCollision newCollision = instantiateCollision(entry.getValue(), annotationMap, collisionList);
|
||||
for (int i = 0; i < blockMappings.length; i++) {
|
||||
BlockMapping blockMapping = blockMappings[i];
|
||||
BlockCollision newCollision = instantiateCollision(blockMapping, annotationMap, collisionList);
|
||||
|
||||
if (newCollision != null) {
|
||||
// If there's an existing instance equal to this one, use that instead
|
||||
|
@ -92,7 +93,7 @@ public class CollisionRegistryLoader extends MultiResourceRegistryLoader<String,
|
|||
}
|
||||
}
|
||||
|
||||
collisions.put(entry.getIntKey(), newCollision);
|
||||
collisions.put(i, newCollision);
|
||||
}
|
||||
return collisions;
|
||||
}
|
||||
|
|
|
@ -30,10 +30,10 @@ import com.google.common.collect.ImmutableMap;
|
|||
import com.nukkitx.nbt.*;
|
||||
import com.nukkitx.protocol.bedrock.v440.Bedrock_v440;
|
||||
import com.nukkitx.protocol.bedrock.v448.Bedrock_v448;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
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;
|
||||
|
@ -140,11 +140,12 @@ public class BlockRegistryPopulator {
|
|||
BiFunction<String, NbtMapBuilder, String> stateMapper = STATE_MAPPER.getOrDefault(palette.getKey(), (i, s) -> null);
|
||||
|
||||
IntList javaToBedrockBlockMap = new IntArrayList();
|
||||
Int2IntMap bedrockToJavaBlockMap = new Int2IntOpenHashMap();
|
||||
|
||||
Map<String, NbtMap> flowerPotBlocks = new Object2ObjectOpenHashMap<>();
|
||||
Object2IntMap<NbtMap> itemFrames = new Object2IntOpenHashMap<>();
|
||||
|
||||
IntSet jigsawStateIds = new IntOpenHashSet();
|
||||
|
||||
BlockMappings.BlockMappingsBuilder builder = BlockMappings.builder();
|
||||
while (blocksIterator.hasNext()) {
|
||||
javaRuntimeId++;
|
||||
|
@ -169,15 +170,16 @@ public class BlockRegistryPopulator {
|
|||
break;
|
||||
}
|
||||
|
||||
if (javaId.contains("jigsaw")) {
|
||||
jigsawStateIds.add(bedrockRuntimeId);
|
||||
}
|
||||
|
||||
boolean waterlogged = entry.getKey().contains("waterlogged=true")
|
||||
|| javaId.contains("minecraft:bubble_column") || javaId.contains("minecraft:kelp") || javaId.contains("seagrass");
|
||||
|
||||
if (waterlogged) {
|
||||
bedrockToJavaBlockMap.putIfAbsent(bedrockRuntimeId | 1 << 31, javaRuntimeId);
|
||||
int finalJavaRuntimeId = javaRuntimeId;
|
||||
BlockRegistries.WATERLOGGED.register(set -> set.add(finalJavaRuntimeId));
|
||||
} else {
|
||||
bedrockToJavaBlockMap.putIfAbsent(bedrockRuntimeId, javaRuntimeId);
|
||||
}
|
||||
|
||||
String cleanJavaIdentifier = BlockUtils.getCleanIdentifier(entry.getKey());
|
||||
|
@ -221,10 +223,10 @@ public class BlockRegistryPopulator {
|
|||
BlockRegistries.BLOCKS.register(PALETTE_VERSIONS.getInt(palette.getKey()), builder.blockStateVersion(stateVersion)
|
||||
.emptyChunkSection(new ChunkSection(new BlockStorage[]{new BlockStorage(airRuntimeId)}))
|
||||
.javaToBedrockBlockMap(javaToBedrockBlockMap.toIntArray())
|
||||
.bedrockToJavaBlockMap(bedrockToJavaBlockMap)
|
||||
.javaIdentifierToBedrockTag(javaIdentifierToBedrockTag)
|
||||
.itemFrames(itemFrames)
|
||||
.flowerPotBlocks(flowerPotBlocks)
|
||||
.jigsawStateIds(jigsawStateIds)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
@ -239,6 +241,8 @@ public class BlockRegistryPopulator {
|
|||
throw new AssertionError("Unable to load Java block mappings", e);
|
||||
}
|
||||
|
||||
BlockRegistries.JAVA_BLOCKS.set(new BlockMapping[blocksJson.size()]); // Set array size to number of blockstates
|
||||
|
||||
Set<String> cleanIdentifiers = new HashSet<>();
|
||||
|
||||
int javaRuntimeId = -1;
|
||||
|
|
|
@ -27,7 +27,7 @@ package org.geysermc.connector.registry.type;
|
|||
|
||||
import com.nukkitx.nbt.NbtList;
|
||||
import com.nukkitx.nbt.NbtMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import lombok.Builder;
|
||||
import lombok.Value;
|
||||
|
@ -46,7 +46,6 @@ public class BlockMappings {
|
|||
ChunkSection emptyChunkSection;
|
||||
|
||||
int[] javaToBedrockBlockMap;
|
||||
Int2IntMap bedrockToJavaBlockMap;
|
||||
|
||||
NbtList<NbtMap> bedrockBlockStates;
|
||||
|
||||
|
@ -61,6 +60,8 @@ public class BlockMappings {
|
|||
Object2IntMap<NbtMap> itemFrames;
|
||||
Map<String, NbtMap> flowerPotBlocks;
|
||||
|
||||
IntSet jigsawStateIds;
|
||||
|
||||
public int getBedrockBlockId(int state) {
|
||||
if (state >= this.javaToBedrockBlockMap.length) {
|
||||
return bedrockAirId;
|
||||
|
@ -68,10 +69,6 @@ public class BlockMappings {
|
|||
return this.javaToBedrockBlockMap[state];
|
||||
}
|
||||
|
||||
public int getJavaBlockState(int bedrockId) {
|
||||
return this.bedrockToJavaBlockMap.get(bedrockId);
|
||||
}
|
||||
|
||||
public int getItemFrame(NbtMap tag) {
|
||||
return this.itemFrames.getOrDefault(tag, -1);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue