Skip to content

Commit

Permalink
[WIP] Cleanup Bukkit blockstate loading logic
Browse files Browse the repository at this point in the history
  • Loading branch information
me4502 committed Jul 7, 2024
1 parent f31c2e6 commit c202296
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
Expand All @@ -40,6 +41,7 @@
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.block.FuzzyBlockState;
import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.entity.EntityTypes;
import com.sk89q.worldedit.world.gamemode.GameMode;
Expand All @@ -66,6 +68,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import javax.annotation.Nullable;

import static com.google.common.base.Preconditions.checkNotNull;
Expand All @@ -82,6 +85,8 @@ private BukkitAdapter() {

static {
TO_BLOCK_CONTEXT.setRestricted(false);
TO_BLOCK_CONTEXT.setTryLegacy(false);
TO_BLOCK_CONTEXT.setPreferringWildcard(true);
}

/**
Expand Down Expand Up @@ -334,7 +339,7 @@ public static Entity adapt(org.bukkit.entity.Entity entity) {
*/
public static Material adapt(ItemType itemType) {
checkNotNull(itemType);
return Material.matchMaterial(itemType.id());
return Registry.MATERIAL.get(NamespacedKey.fromString(itemType.id()));
}

/**
Expand All @@ -345,7 +350,7 @@ public static Material adapt(ItemType itemType) {
*/
public static Material adapt(BlockType blockType) {
checkNotNull(blockType);
return Material.matchMaterial(blockType.id());
return Registry.MATERIAL.get(NamespacedKey.fromString(blockType.id()));
}

/**
Expand Down Expand Up @@ -439,7 +444,26 @@ public static ItemType asItemType(Material material) {
private static final Int2ObjectMap<BlockState> blockStateCache = Int2ObjectMaps.synchronize(
new Int2ObjectOpenHashMap<>()
);
private static final Map<String, BlockState> blockStateStringCache = new ConcurrentHashMap<>();

@SuppressWarnings({ "unchecked" })
private static final Function<String, BlockState> blockStateLoader = input -> {
try {
FuzzyBlockState state = (FuzzyBlockState) WorldEdit.getInstance().getBlockFactory().parseFromInput(
input, TO_BLOCK_CONTEXT
).toImmutableState();
// This manually applies the properties to the first state as we don't necessarily know what the default state
// is at this point. Given this can only ever have all states listed, this is fine.
BlockState defaultState = state.getBlockType().getAllStates().get(0);
for (Map.Entry<Property<?>, Object> propertyObjectEntry : state.getStates().entrySet()) {
//noinspection unchecked
defaultState = defaultState.with((Property<Object>) propertyObjectEntry.getKey(), propertyObjectEntry.getValue());
}
return defaultState;
} catch (InputParseException e) {
e.printStackTrace();
return null;
}
};

/**
* Create a WorldEdit BlockState from a Bukkit BlockData.
Expand All @@ -452,27 +476,12 @@ public static BlockState adapt(BlockData blockData) {

BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter == null) {
return blockStateStringCache.computeIfAbsent(blockData.getAsString(), input -> {
try {
return WorldEdit.getInstance().getBlockFactory().parseFromInput(input, TO_BLOCK_CONTEXT).toImmutableState();
} catch (InputParseException e) {
e.printStackTrace();
return null;
}
});
return blockStateLoader.apply(blockData.getAsString());
} else {
return blockStateCache.computeIfAbsent(
adapter.getInternalBlockStateId(blockData).orElseGet(
() -> blockData.getAsString().hashCode()
),
input -> {
try {
return WorldEdit.getInstance().getBlockFactory().parseFromInput(blockData.getAsString(), TO_BLOCK_CONTEXT).toImmutableState();
} catch (InputParseException e) {
e.printStackTrace();
return null;
}
});
adapter.getInternalBlockStateId(blockData).orElseGet(() -> blockData.getAsString().hashCode()),
input -> blockStateLoader.apply(blockData.getAsString())
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,19 @@
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
import com.sk89q.worldedit.event.platform.PlatformUnreadyEvent;
import com.sk89q.worldedit.event.platform.PlatformsRegisteredEvent;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.internal.anvil.ChunkDeleter;
import com.sk89q.worldedit.internal.command.CommandUtil;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.lifecycle.Lifecycled;
import com.sk89q.worldedit.util.lifecycle.SimpleLifecycled;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockCategory;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.FuzzyBlockState;
import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldedit.world.item.ItemCategory;
Expand Down Expand Up @@ -87,7 +82,6 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Level;

Expand Down Expand Up @@ -205,7 +199,6 @@ private void setupWorldData() {
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent(platform));
}

@SuppressWarnings({ "unchecked" })
private void initializeRegistries() {
// Biome
for (Biome biome : Biome.values()) {
Expand All @@ -216,31 +209,12 @@ private void initializeRegistries() {
}
// Block & Item
for (Material material : Material.values()) {
String key = material.getKey().toString();
if (material.isBlock()) {
BlockType.REGISTRY.register(material.getKey().toString(), new BlockType(material.getKey().toString(), blockState -> {
// TODO Use something way less hacky than this.
ParserContext context = new ParserContext();
context.setPreferringWildcard(true);
context.setTryLegacy(false);
context.setRestricted(false);
try {
FuzzyBlockState state = (FuzzyBlockState) WorldEdit.getInstance().getBlockFactory().parseFromInput(
BukkitAdapter.adapt(blockState.getBlockType()).createBlockData().getAsString(), context
).toImmutableState();
BlockState defaultState = blockState.getBlockType().getAllStates().get(0);
for (Map.Entry<Property<?>, Object> propertyObjectEntry : state.getStates().entrySet()) {
//noinspection unchecked
defaultState = defaultState.with((Property<Object>) propertyObjectEntry.getKey(), propertyObjectEntry.getValue());
}
return defaultState;
} catch (InputParseException e) {
getLogger().log(Level.WARNING, "Error loading block state for " + material.getKey(), e);
return blockState;
}
}));
BlockType.REGISTRY.register(key, new BlockType(key, blockState -> BukkitAdapter.adapt(BukkitAdapter.adapt(blockState.getBlockType()).createBlockData())));
}
if (material.isItem()) {
ItemType.REGISTRY.register(material.getKey().toString(), new ItemType(material.getKey().toString()));
ItemType.REGISTRY.register(key, new ItemType(key));
}
}
// Entity
Expand All @@ -265,10 +239,12 @@ private void initializeRegistries() {
private void setupTags() {
// Tags
for (Tag<Material> blockTag : Bukkit.getTags(Tag.REGISTRY_BLOCKS, Material.class)) {
BlockCategory.REGISTRY.register(blockTag.getKey().toString(), new BlockCategory(blockTag.getKey().toString()));
String key = blockTag.getKey().toString();
BlockCategory.REGISTRY.register(key, new BlockCategory(key));
}
for (Tag<Material> itemTag : Bukkit.getTags(Tag.REGISTRY_ITEMS, Material.class)) {
ItemCategory.REGISTRY.register(itemTag.getKey().toString(), new ItemCategory(itemTag.getKey().toString()));
String key = itemTag.getKey().toString();
ItemCategory.REGISTRY.register(key, new ItemCategory(key));
}
}

Expand Down

0 comments on commit c202296

Please sign in to comment.