Merge pull request #429 from sk89q/bugfix/config-no-plat-dependency

Make block states lazy, fix forge for new block API
This commit is contained in:
Matthew Miller 2018-10-07 18:21:30 +10:00 committed by GitHub
commit 88f22f2e59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 412 additions and 30 deletions

View File

@ -51,6 +51,11 @@ public abstract class AbstractProperty<T> implements Property<T> {
this.name = name; this.name = name;
} }
@Override
public String toString() {
return getClass().getSimpleName() + "{name=" + name + "}";
}
@Override @Override
public int hashCode() { public int hashCode() {
return name.hashCode(); return name.hashCode();

View File

@ -19,6 +19,8 @@
package com.sk89q.worldedit.world.block; 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.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
@ -34,7 +36,9 @@ import com.sk89q.worldedit.world.registry.LegacyMapper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -42,11 +46,12 @@ public class BlockType {
public static final NamespacedRegistry<BlockType> REGISTRY = new NamespacedRegistry<>("block type"); public static final NamespacedRegistry<BlockType> REGISTRY = new NamespacedRegistry<>("block type");
private String id; private final String id;
private BlockState defaultState; private final Function<BlockState, BlockState> values;
private Map<String, ? extends Property> properties; private final AtomicReference<BlockState> defaultState = new AtomicReference<>();
private BlockMaterial blockMaterial; private final AtomicReference<Map<String, ? extends Property>> properties = new AtomicReference<>();
private Map<Map<Property<?>, Object>, BlockState> blockStatesMap; private final AtomicReference<BlockMaterial> blockMaterial = new AtomicReference<>();
private final AtomicReference<Map<Map<Property<?>, Object>, BlockState>> blockStatesMap = new AtomicReference<>();
public BlockType(String id) { public BlockType(String id) {
this(id, null); this(id, null);
@ -58,11 +63,27 @@ public class BlockType {
id = "minecraft:" + id; id = "minecraft:" + id;
} }
this.id = id; this.id = id;
this.blockStatesMap = BlockState.generateStateMap(this); this.values = values;
this.defaultState = new ArrayList<>(this.blockStatesMap.values()).get(0); }
if (values != null) {
this.defaultState = values.apply(this.defaultState); private <T> T updateField(AtomicReference<T> field, Supplier<T> 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<Map<Property<?>, Object>, BlockState> getBlockStatesMap() {
return updateField(blockStatesMap, () -> BlockState.generateStateMap(this));
} }
/** /**
@ -94,11 +115,8 @@ public class BlockType {
* @return The properties map * @return The properties map
*/ */
public Map<String, ? extends Property> getPropertyMap() { public Map<String, ? extends Property> getPropertyMap() {
if (properties == null) { return updateField(properties, () -> ImmutableMap.copyOf(WorldEdit.getInstance().getPlatformManager()
properties = ImmutableMap.copyOf(WorldEdit.getInstance().getPlatformManager() .queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getProperties(this)));
.queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getProperties(this));
}
return this.properties;
} }
/** /**
@ -117,7 +135,9 @@ public class BlockType {
* @return The property * @return The property
*/ */
public <V> Property<V> getProperty(String name) { public <V> Property<V> getProperty(String name) {
return getPropertyMap().get(name); Property<V> property = getPropertyMap().get(name);
checkArgument(property != null, "%s has no property named %s", this, name);
return property;
} }
/** /**
@ -126,7 +146,13 @@ public class BlockType {
* @return The default state * @return The default state
*/ */
public BlockState getDefaultState() { public BlockState getDefaultState() {
return this.defaultState; return updateField(defaultState, () -> {
BlockState defaultState = new ArrayList<>(getBlockStatesMap().values()).get(0);
if (values != null) {
defaultState = values.apply(defaultState);
}
return defaultState;
});
} }
/** /**
@ -135,7 +161,18 @@ public class BlockType {
* @return All possible states * @return All possible states
*/ */
public List<BlockState> getAllStates() { public List<BlockState> getAllStates() {
return ImmutableList.copyOf(this.blockStatesMap.values()); 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<Property<?>, Object> key) {
BlockState state = getBlockStatesMap().get(key);
checkArgument(state != null, "%s has no state for %s", this, key);
return state;
} }
/** /**
@ -163,10 +200,8 @@ public class BlockType {
* @return The material * @return The material
*/ */
public BlockMaterial getMaterial() { public BlockMaterial getMaterial() {
if (this.blockMaterial == null) { return updateField(blockMaterial, () -> WorldEdit.getInstance().getPlatformManager()
this.blockMaterial = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this); .queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this));
}
return this.blockMaterial;
} }
/** /**

View File

@ -13,6 +13,11 @@ buildscript {
apply plugin: 'net.minecraftforge.gradle.forge' apply plugin: 'net.minecraftforge.gradle.forge'
configurations.all {
resolutionStrategy {
force 'org.ow2.asm:asm:5.2'
}
}
dependencies { dependencies {
compile project(':worldedit-core') compile project(':worldedit-core')

View File

@ -19,13 +19,27 @@
package com.sk89q.worldedit.forge; package com.sk89q.worldedit.forge;
import com.google.common.collect.ImmutableList;
import com.sk89q.worldedit.Vector; 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.util.Direction;
import com.sk89q.worldedit.world.World; 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.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import java.util.stream.Collectors;
final class ForgeAdapter { final class ForgeAdapter {
private 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) { public static BlockPos toBlockPos(Vector vector) {
return new BlockPos(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ()); 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);
}
} }

View File

@ -0,0 +1,94 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
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();
}
}

View File

@ -0,0 +1,58 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
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<Material, ForgeBlockMaterial> 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<String, ? extends Property<?>> getProperties(BlockType blockType) {
Map<String, Property<?>> map = new TreeMap<>();
Collection<IProperty<?>> propertyKeys = Block.getBlockFromName(blockType.getId())
.getDefaultState()
.getPropertyKeys();
for (IProperty<?> key : propertyKeys) {
map.put(key.getName(), ForgeAdapter.adaptProperty(key));
}
return map;
}
}

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.forge; package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.world.registry.BiomeRegistry; 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.BundledRegistries;
import com.sk89q.worldedit.world.registry.ItemRegistry; import com.sk89q.worldedit.world.registry.ItemRegistry;
@ -29,9 +30,15 @@ import com.sk89q.worldedit.world.registry.ItemRegistry;
class ForgeRegistries extends BundledRegistries { class ForgeRegistries extends BundledRegistries {
private static final ForgeRegistries INSTANCE = new ForgeRegistries(); private static final ForgeRegistries INSTANCE = new ForgeRegistries();
private final BlockRegistry blockRegistry = new ForgeBlockRegistry();
private final BiomeRegistry biomeRegistry = new ForgeBiomeRegistry(); private final BiomeRegistry biomeRegistry = new ForgeBiomeRegistry();
private final ItemRegistry itemRegistry = new ForgeItemRegistry(); private final ItemRegistry itemRegistry = new ForgeItemRegistry();
@Override
public BlockRegistry getBlockRegistry() {
return blockRegistry;
}
@Override @Override
public BiomeRegistry getBiomeRegistry() { public BiomeRegistry getBiomeRegistry() {
return biomeRegistry; return biomeRegistry;

View File

@ -30,7 +30,6 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.BaseEntity; 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.internal.Constants;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.TreeGenerator.TreeType; import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.AbstractWorld;
import com.sk89q.worldedit.world.biome.BaseBiome; 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.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; 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.item.ItemTypes;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import com.sk89q.worldedit.world.weather.WeatherType; import com.sk89q.worldedit.world.weather.WeatherType;
import com.sk89q.worldedit.world.weather.WeatherTypes; 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.BlockOldLeaf;
import net.minecraft.block.BlockOldLog; import net.minecraft.block.BlockOldLog;
import net.minecraft.block.BlockPlanks; 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.block.state.IBlockState;
import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityList;
import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.item.EntityItem;
@ -66,7 +71,9 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -95,8 +102,11 @@ import net.minecraftforge.common.DimensionManager;
import java.io.File; import java.io.File;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.TreeMap;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -173,7 +183,11 @@ public class ForgeWorld extends AbstractWorld {
Chunk chunk = world.getChunkFromChunkCoords(x >> 4, z >> 4); Chunk chunk = world.getChunkFromChunkCoords(x >> 4, z >> 4);
BlockPos pos = new BlockPos(x, y, z); BlockPos pos = new BlockPos(x, y, z);
IBlockState old = chunk.getBlockState(pos); 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<Property<?>, Object> states = block.getStates();
newState = applyProperties(mcBlock.getBlockState(), newState, states);
IBlockState successState = chunk.setBlockState(pos, newState); IBlockState successState = chunk.setBlockState(pos, newState);
boolean successful = successState != null; boolean successful = successState != null;
@ -199,6 +213,29 @@ public class ForgeWorld extends AbstractWorld {
return successful; 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<Property<?>, Object> states) {
for (Map.Entry<Property<?>, 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 @Override
public int getBlockLightLevel(Vector position) { public int getBlockLightLevel(Vector position) {
checkNotNull(position); checkNotNull(position);
@ -429,9 +466,24 @@ public class ForgeWorld extends AbstractWorld {
public BlockState getBlock(Vector position) { public BlockState getBlock(Vector position) {
World world = getWorld(); World world = getWorld();
BlockPos pos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()); 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<Property<?>, Object> adaptProperties(BlockType block, Map<IProperty<?>, Comparable<?>> mcProps) {
Map<Property<?>, Object> props = new TreeMap<>(Comparator.comparing(Property::getName));
for (Map.Entry<IProperty<?>, 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 @Override

View File

@ -38,6 +38,7 @@ import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.CommandEvent; import net.minecraftforge.event.CommandEvent;
@ -125,12 +126,18 @@ public class ForgeWorldEdit {
this.provider = new ForgePermissionsProvider.VanillaPermissionsProvider(platform); this.provider = new ForgePermissionsProvider.VanillaPermissionsProvider(platform);
} }
for (Block block : Block.REGISTRY) { for (ResourceLocation name : Block.REGISTRY.getKeys()) {
BlockTypes.register(new BlockType(Block.REGISTRY.getNameForObject(block).toString())); String nameStr = name.toString();
if (!BlockType.REGISTRY.keySet().contains(nameStr)) {
BlockTypes.register(new BlockType(nameStr));
}
} }
for (Item item : Item.REGISTRY) { for (ResourceLocation name : Item.REGISTRY.getKeys()) {
ItemTypes.register(new ItemType(Item.REGISTRY.getNameForObject(item).toString())); String nameStr = name.toString();
if (!ItemType.REGISTRY.keySet().contains(nameStr)) {
ItemTypes.register(new ItemType(nameStr));
}
} }
} }

View File

@ -0,0 +1,72 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
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<T extends Comparable<T>> implements Property<T> {
private final IProperty<T> property;
private final List<T> values;
public IPropertyAdapter(IProperty<T> property) {
this.property = property;
this.values = ImmutableList.copyOf(property.getAllowedValues());
}
@Override
public String getName() {
return property.getName();
}
@Override
public List<T> getValues() {
return values;
}
@Override
public T getValueFor(String string) throws IllegalArgumentException {
Optional<T> 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());
}
}