From 79a41210982c92dfaf49ea5bb4602ef81398bc03 Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Thu, 4 Oct 2018 20:29:40 +1000 Subject: [PATCH 1/4] Return null if the material is null. --- .../com/sk89q/worldedit/bukkit/BukkitBlockRegistry.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBlockRegistry.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBlockRegistry.java index 88e4784d4..31db0f83d 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBlockRegistry.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBlockRegistry.java @@ -38,8 +38,11 @@ public class BukkitBlockRegistry extends BundledBlockRegistry { @Nullable @Override public BlockMaterial getMaterial(BlockType blockType) { - return materialMap.computeIfAbsent(BukkitAdapter.adapt(blockType), - material -> new BukkitBlockMaterial(BukkitBlockRegistry.super.getMaterial(blockType), material)); + Material mat = BukkitAdapter.adapt(blockType); + if (mat == null) { + return null; + } + return materialMap.computeIfAbsent(mat, material -> new BukkitBlockMaterial(BukkitBlockRegistry.super.getMaterial(blockType), material)); } @Nullable From d0ea5121f21920b468e40554299463a3f3f291a8 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Thu, 4 Oct 2018 17:18:01 -0700 Subject: [PATCH 2/4] Make some BlockType fields lazy, to avoid early Platform dependencies --- .../worldedit/world/block/BlockType.java | 70 +++++++++++++------ 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java index 3378353c6..7ab125e95 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java @@ -19,6 +19,8 @@ package com.sk89q.worldedit.world.block; +import static com.google.common.base.Preconditions.checkArgument; + import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.sk89q.worldedit.WorldEdit; @@ -34,7 +36,9 @@ import com.sk89q.worldedit.world.registry.LegacyMapper; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; +import java.util.function.Supplier; import javax.annotation.Nullable; @@ -42,11 +46,12 @@ public class BlockType { public static final NamespacedRegistry REGISTRY = new NamespacedRegistry<>("block type"); - private String id; - private BlockState defaultState; - private Map properties; - private BlockMaterial blockMaterial; - private Map, Object>, BlockState> blockStatesMap; + private final String id; + private final Function values; + private final AtomicReference defaultState = new AtomicReference<>(); + private final AtomicReference> properties = new AtomicReference<>(); + private final AtomicReference blockMaterial = new AtomicReference<>(); + private final AtomicReference, Object>, BlockState>> blockStatesMap = new AtomicReference<>(); public BlockType(String id) { this(id, null); @@ -58,11 +63,37 @@ public class BlockType { id = "minecraft:" + id; } this.id = id; - this.blockStatesMap = BlockState.generateStateMap(this); - this.defaultState = new ArrayList<>(this.blockStatesMap.values()).get(0); - if (values != null) { - this.defaultState = values.apply(this.defaultState); + this.values = values; + } + + private T updateField(AtomicReference field, Supplier value) { + T result = field.get(); + if (result == null) { + // swap in new value, if someone doesn't beat us + T update = value.get(); + if (field.compareAndSet(null, update)) { + // use ours + result = update; + } else { + // update to real value + result = field.get(); + } } + return result; + } + + private Map, Object>, BlockState> getBlockStatesMap() { + return updateField(blockStatesMap, () -> BlockState.generateStateMap(this)); + } + + private BlockState getDefaultStateMemoized() { + return updateField(defaultState, () -> { + BlockState defaultState = new ArrayList<>(getBlockStatesMap().values()).get(0); + if (values != null) { + defaultState = values.apply(defaultState); + } + return defaultState; + }); } /** @@ -94,11 +125,8 @@ public class BlockType { * @return The properties map */ public Map getPropertyMap() { - if (properties == null) { - properties = ImmutableMap.copyOf(WorldEdit.getInstance().getPlatformManager() - .queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getProperties(this)); - } - return this.properties; + return updateField(properties, () -> ImmutableMap.copyOf(WorldEdit.getInstance().getPlatformManager() + .queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getProperties(this))); } /** @@ -117,7 +145,9 @@ public class BlockType { * @return The property */ public Property getProperty(String name) { - return getPropertyMap().get(name); + Property property = getPropertyMap().get(name); + checkArgument(property != null, "%s has no property named %s", this, name); + return property; } /** @@ -126,7 +156,7 @@ public class BlockType { * @return The default state */ public BlockState getDefaultState() { - return this.defaultState; + return getDefaultStateMemoized(); } /** @@ -135,7 +165,7 @@ public class BlockType { * @return All possible states */ public List getAllStates() { - return ImmutableList.copyOf(this.blockStatesMap.values()); + return ImmutableList.copyOf(getBlockStatesMap().values()); } /** @@ -163,10 +193,8 @@ public class BlockType { * @return The material */ public BlockMaterial getMaterial() { - if (this.blockMaterial == null) { - this.blockMaterial = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this); - } - return this.blockMaterial; + return updateField(blockMaterial, () -> WorldEdit.getInstance().getPlatformManager() + .queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this)); } /** From ef2c07ca249b2e88e4944210563ea887c59a7892 Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Thu, 4 Oct 2018 17:18:43 -0700 Subject: [PATCH 3/4] Update forge for new block API --- .../registry/state/AbstractProperty.java | 5 + .../worldedit/world/block/BlockType.java | 11 +++ worldedit-forge/build.gradle | 5 + .../sk89q/worldedit/forge/ForgeAdapter.java | 47 ++++++++++ .../worldedit/forge/ForgeBlockMaterial.java | 94 +++++++++++++++++++ .../worldedit/forge/ForgeBlockRegistry.java | 58 ++++++++++++ .../worldedit/forge/ForgeRegistries.java | 7 ++ .../com/sk89q/worldedit/forge/ForgeWorld.java | 62 +++++++++++- .../sk89q/worldedit/forge/ForgeWorldEdit.java | 15 ++- .../worldedit/forge/IPropertyAdapter.java | 72 ++++++++++++++ 10 files changed, 367 insertions(+), 9 deletions(-) create mode 100644 worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockMaterial.java create mode 100644 worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockRegistry.java create mode 100644 worldedit-forge/src/main/java/com/sk89q/worldedit/forge/IPropertyAdapter.java diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/state/AbstractProperty.java b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/state/AbstractProperty.java index 75e0765c4..594361c4c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/state/AbstractProperty.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/state/AbstractProperty.java @@ -51,6 +51,11 @@ public abstract class AbstractProperty implements Property { this.name = name; } + @Override + public String toString() { + return getClass().getSimpleName() + "{name=" + name + "}"; + } + @Override public int hashCode() { return name.hashCode(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java index 7ab125e95..8bebc7c46 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java @@ -168,6 +168,17 @@ public class BlockType { return ImmutableList.copyOf(getBlockStatesMap().values()); } + /** + * Gets a state of this BlockType with the given properties. + * + * @return The state, if it exists + */ + public BlockState getState(Map, Object> key) { + BlockState state = getBlockStatesMap().get(key); + checkArgument(state != null, "%s has no state for %s", this, key); + return state; + } + /** * Gets whether this block type has an item representation. * diff --git a/worldedit-forge/build.gradle b/worldedit-forge/build.gradle index f5c6e0f7d..b558a41ea 100644 --- a/worldedit-forge/build.gradle +++ b/worldedit-forge/build.gradle @@ -13,6 +13,11 @@ buildscript { apply plugin: 'net.minecraftforge.gradle.forge' +configurations.all { + resolutionStrategy { + force 'org.ow2.asm:asm:5.2' + } +} dependencies { compile project(':worldedit-core') diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeAdapter.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeAdapter.java index 59df06287..18311a5c5 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeAdapter.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeAdapter.java @@ -19,13 +19,27 @@ package com.sk89q.worldedit.forge; +import com.google.common.collect.ImmutableList; import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.registry.state.BooleanProperty; +import com.sk89q.worldedit.registry.state.DirectionalProperty; +import com.sk89q.worldedit.registry.state.EnumProperty; +import com.sk89q.worldedit.registry.state.IntegerProperty; +import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.world.World; + +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyBool; +import net.minecraft.block.properties.PropertyDirection; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.properties.PropertyInteger; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import java.util.stream.Collectors; + final class ForgeAdapter { private ForgeAdapter() { @@ -60,8 +74,41 @@ final class ForgeAdapter { } } + public static Direction adaptEnumFacing(EnumFacing face) { + switch (face) { + case NORTH: return Direction.NORTH; + case SOUTH: return Direction.SOUTH; + case WEST: return Direction.WEST; + case EAST: return Direction.EAST; + case DOWN: return Direction.DOWN; + case UP: + default: + return Direction.UP; + } + } + public static BlockPos toBlockPos(Vector vector) { return new BlockPos(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ()); } + public static Property adaptProperty(IProperty property) { + if (property instanceof PropertyBool) { + return new BooleanProperty(property.getName(), ImmutableList.copyOf(((PropertyBool) property).getAllowedValues())); + } + if (property instanceof PropertyInteger) { + return new IntegerProperty(property.getName(), ImmutableList.copyOf(((PropertyInteger) property).getAllowedValues())); + } + if (property instanceof PropertyDirection) { + return new DirectionalProperty(property.getName(), ((PropertyDirection) property).getAllowedValues().stream() + .map(ForgeAdapter::adaptEnumFacing) + .collect(Collectors.toList())); + } + if (property instanceof PropertyEnum) { + return new EnumProperty(property.getName(), ((PropertyEnum) property).getAllowedValues().stream() + .map(e -> e.getName()) + .collect(Collectors.toList())); + } + return new IPropertyAdapter<>(property); + } + } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockMaterial.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockMaterial.java new file mode 100644 index 000000000..9d98f39ef --- /dev/null +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockMaterial.java @@ -0,0 +1,94 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.forge; + +import com.sk89q.worldedit.world.registry.BlockMaterial; +import com.sk89q.worldedit.world.registry.PassthroughBlockMaterial; + +import net.minecraft.block.material.EnumPushReaction; +import net.minecraft.block.material.Material; + +import javax.annotation.Nullable; + +/** + * Forge block material that pulls as much info as possible from the Minecraft + * Material, and passes the rest to another implementation, typically the + * bundled block info. + */ +public class ForgeBlockMaterial extends PassthroughBlockMaterial { + + private final Material delegate; + + public ForgeBlockMaterial(Material delegate, @Nullable BlockMaterial secondary) { + super(secondary); + this.delegate = delegate; + } + + @Override + public boolean isAir() { + return delegate == Material.AIR || super.isAir(); + } + + @Override + public boolean isOpaque() { + return delegate.isOpaque(); + } + + @Override + public boolean isLiquid() { + return delegate.isLiquid(); + } + + @Override + public boolean isSolid() { + return delegate.isSolid(); + } + + @Override + public boolean isFragileWhenPushed() { + return delegate.getMobilityFlag() == EnumPushReaction.DESTROY; + } + + @Override + public boolean isUnpushable() { + return delegate.getMobilityFlag() == EnumPushReaction.BLOCK; + } + + @Override + public boolean isMovementBlocker() { + return delegate.blocksMovement(); + } + + @Override + public boolean isBurnable() { + return delegate.getCanBurn(); + } + + @Override + public boolean isToolRequired() { + return !delegate.isToolNotRequired(); + } + + @Override + public boolean isReplacedDuringPlacement() { + return delegate.isReplaceable(); + } + +} diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockRegistry.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockRegistry.java new file mode 100644 index 000000000..a2d59715a --- /dev/null +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockRegistry.java @@ -0,0 +1,58 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.forge; + +import com.sk89q.worldedit.registry.state.Property; +import com.sk89q.worldedit.world.block.BlockType; +import com.sk89q.worldedit.world.registry.BlockMaterial; +import com.sk89q.worldedit.world.registry.BundledBlockRegistry; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.IProperty; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +public class ForgeBlockRegistry extends BundledBlockRegistry { + + private Map materialMap = new HashMap<>(); + + @Override + public BlockMaterial getMaterial(BlockType blockType) { + return materialMap.computeIfAbsent(Block.getBlockFromName(blockType.getId()).getDefaultState().getMaterial(), + m -> new ForgeBlockMaterial(m, super.getMaterial(blockType))); + } + + @Override + public Map> getProperties(BlockType blockType) { + Map> map = new TreeMap<>(); + Collection> propertyKeys = Block.getBlockFromName(blockType.getId()) + .getDefaultState() + .getPropertyKeys(); + for (IProperty key : propertyKeys) { + map.put(key.getName(), ForgeAdapter.adaptProperty(key)); + } + return map; + } + +} diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeRegistries.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeRegistries.java index 7b8737fd8..27b6f36df 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeRegistries.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeRegistries.java @@ -20,6 +20,7 @@ package com.sk89q.worldedit.forge; import com.sk89q.worldedit.world.registry.BiomeRegistry; +import com.sk89q.worldedit.world.registry.BlockRegistry; import com.sk89q.worldedit.world.registry.BundledRegistries; import com.sk89q.worldedit.world.registry.ItemRegistry; @@ -29,9 +30,15 @@ import com.sk89q.worldedit.world.registry.ItemRegistry; class ForgeRegistries extends BundledRegistries { private static final ForgeRegistries INSTANCE = new ForgeRegistries(); + private final BlockRegistry blockRegistry = new ForgeBlockRegistry(); private final BiomeRegistry biomeRegistry = new ForgeBiomeRegistry(); private final ItemRegistry itemRegistry = new ForgeItemRegistry(); + @Override + public BlockRegistry getBlockRegistry() { + return blockRegistry; + } + @Override public BiomeRegistry getBiomeRegistry() { return biomeRegistry; diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java index 676c77b50..abd4e8151 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java @@ -30,7 +30,6 @@ import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.entity.BaseEntity; @@ -38,15 +37,17 @@ import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.internal.Constants; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.TreeGenerator.TreeType; import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.biome.BaseBiome; +import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; +import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.item.ItemTypes; -import com.sk89q.worldedit.world.registry.LegacyMapper; import com.sk89q.worldedit.world.weather.WeatherType; import com.sk89q.worldedit.world.weather.WeatherTypes; @@ -55,6 +56,10 @@ import net.minecraft.block.BlockLeaves; import net.minecraft.block.BlockOldLeaf; import net.minecraft.block.BlockOldLog; import net.minecraft.block.BlockPlanks; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyDirection; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityList; import net.minecraft.entity.item.EntityItem; @@ -66,7 +71,9 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.server.MinecraftServer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; +import net.minecraft.util.IStringSerializable; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -95,8 +102,11 @@ import net.minecraftforge.common.DimensionManager; import java.io.File; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import java.util.Map; import java.util.Random; +import java.util.TreeMap; import javax.annotation.Nullable; @@ -173,7 +183,11 @@ public class ForgeWorld extends AbstractWorld { Chunk chunk = world.getChunkFromChunkCoords(x >> 4, z >> 4); BlockPos pos = new BlockPos(x, y, z); IBlockState old = chunk.getBlockState(pos); - IBlockState newState = Block.getBlockById(block.getBlockType().getLegacyId()).getDefaultState(); // TODO .getStateFromMeta(block.getData()); + Block mcBlock = Block.getBlockFromName(block.getBlockType().getId()); + IBlockState newState = mcBlock.getDefaultState(); + @SuppressWarnings("unchecked") + Map, Object> states = block.getStates(); + newState = applyProperties(mcBlock.getBlockState(), newState, states); IBlockState successState = chunk.setBlockState(pos, newState); boolean successful = successState != null; @@ -199,6 +213,29 @@ public class ForgeWorld extends AbstractWorld { return successful; } + // Can't get the "Object" to be right for withProperty w/o this + @SuppressWarnings({ "rawtypes", "unchecked" }) + private IBlockState applyProperties(BlockStateContainer stateContainer, IBlockState newState, Map, Object> states) { + for (Map.Entry, Object> state : states.entrySet()) { + + IProperty property = stateContainer.getProperty(state.getKey().getName()); + Comparable value = (Comparable) state.getValue(); + // we may need to adapt this value, depending on the source prop + if (property instanceof PropertyDirection) { + Direction dir = (Direction) value; + value = ForgeAdapter.adapt(dir); + } else if (property instanceof PropertyEnum) { + String enumName = (String) value; + value = ((PropertyEnum) property).parseValue((String) value).or(() -> { + throw new IllegalStateException("Enum property " + property.getName() + " does not contain " + enumName); + }); + } + + newState = newState.withProperty(property, value); + } + return newState; + } + @Override public int getBlockLightLevel(Vector position) { checkNotNull(position); @@ -429,9 +466,24 @@ public class ForgeWorld extends AbstractWorld { public BlockState getBlock(Vector position) { World world = getWorld(); BlockPos pos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()); - IBlockState state = world.getBlockState(pos); + IBlockState mcState = world.getBlockState(pos); - return LegacyMapper.getInstance().getBlockFromLegacy(Block.getIdFromBlock(state.getBlock()), state.getBlock().getMetaFromState(state)); + BlockType blockType = BlockType.REGISTRY.get(Block.REGISTRY.getNameForObject(mcState.getBlock()).toString()); + return blockType.getState(adaptProperties(blockType, mcState.getProperties())); + } + + private Map, Object> adaptProperties(BlockType block, Map, Comparable> mcProps) { + Map, Object> props = new TreeMap<>(Comparator.comparing(Property::getName)); + for (Map.Entry, Comparable> prop : mcProps.entrySet()) { + Object value = prop.getValue(); + if (prop.getKey() instanceof PropertyDirection) { + value = ForgeAdapter.adaptEnumFacing((EnumFacing) value); + } else if (prop.getKey() instanceof PropertyEnum) { + value = ((IStringSerializable) value).getName(); + } + props.put(block.getProperty(prop.getKey().getName()), value); + } + return props; } @Override diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java index 963f2f748..d37b60f4e 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java @@ -38,6 +38,7 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.CommandEvent; @@ -125,12 +126,18 @@ public class ForgeWorldEdit { this.provider = new ForgePermissionsProvider.VanillaPermissionsProvider(platform); } - for (Block block : Block.REGISTRY) { - BlockTypes.register(new BlockType(Block.REGISTRY.getNameForObject(block).toString())); + for (ResourceLocation name : Block.REGISTRY.getKeys()) { + String nameStr = name.toString(); + if (!BlockType.REGISTRY.keySet().contains(nameStr)) { + BlockTypes.register(new BlockType(nameStr)); + } } - for (Item item : Item.REGISTRY) { - ItemTypes.register(new ItemType(Item.REGISTRY.getNameForObject(item).toString())); + for (ResourceLocation name : Item.REGISTRY.getKeys()) { + String nameStr = name.toString(); + if (!ItemType.REGISTRY.keySet().contains(nameStr)) { + ItemTypes.register(new ItemType(nameStr)); + } } } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/IPropertyAdapter.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/IPropertyAdapter.java new file mode 100644 index 000000000..0ac900a55 --- /dev/null +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/IPropertyAdapter.java @@ -0,0 +1,72 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.forge; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; +import com.sk89q.worldedit.registry.state.Property; + +import net.minecraft.block.properties.IProperty; + +import java.util.List; + +class IPropertyAdapter> implements Property { + + private final IProperty property; + private final List values; + + public IPropertyAdapter(IProperty property) { + this.property = property; + this.values = ImmutableList.copyOf(property.getAllowedValues()); + } + + @Override + public String getName() { + return property.getName(); + } + + @Override + public List getValues() { + return values; + } + + @Override + public T getValueFor(String string) throws IllegalArgumentException { + Optional val = property.parseValue(string); + checkArgument(val.isPresent(), "%s has no value for %s", getName(), string); + return val.get(); + } + + @Override + public int hashCode() { + return getName().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Property)) { + return false; + } + return getName().equals(((Property) obj).getName()); + } + +} From ff877ec03b8cb3fd19b532be56ab4a6152bfa8fd Mon Sep 17 00:00:00 2001 From: Kenzie Togami Date: Thu, 4 Oct 2018 17:20:07 -0700 Subject: [PATCH 4/4] Make BlockType#getDefaultState like other fields --- .../sk89q/worldedit/world/block/BlockType.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java index 8bebc7c46..feee8baed 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java @@ -86,16 +86,6 @@ public class BlockType { return updateField(blockStatesMap, () -> BlockState.generateStateMap(this)); } - private BlockState getDefaultStateMemoized() { - return updateField(defaultState, () -> { - BlockState defaultState = new ArrayList<>(getBlockStatesMap().values()).get(0); - if (values != null) { - defaultState = values.apply(defaultState); - } - return defaultState; - }); - } - /** * Gets the ID of this block. * @@ -156,7 +146,13 @@ public class BlockType { * @return The default state */ public BlockState getDefaultState() { - return getDefaultStateMemoized(); + return updateField(defaultState, () -> { + BlockState defaultState = new ArrayList<>(getBlockStatesMap().values()).get(0); + if (values != null) { + defaultState = values.apply(defaultState); + } + return defaultState; + }); } /**