diff --git a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java index ce788751b..c9f52df46 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java @@ -9,25 +9,14 @@ import com.boydti.fawe.object.number.MutableLong; import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.ReflectionUtils; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.IntTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.NBTConstants; -import com.sk89q.jnbt.NBTInputStream; -import com.sk89q.jnbt.NBTOutputStream; -import com.sk89q.jnbt.Tag; +import com.sk89q.jnbt.*; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; + +import java.io.DataOutput; +import java.io.DataOutputStream; import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.function.BiConsumer; public class MCAChunk extends FaweChunk { @@ -88,9 +77,6 @@ public class MCAChunk extends FaweChunk { } public void write(NBTOutputStream nbtOut) throws IOException { - - - nbtOut.writeNamedTagName("", NBTConstants.TYPE_COMPOUND); nbtOut.writeLazyCompoundTag("Level", out -> { out.writeNamedTag("V", (byte) 1); @@ -107,7 +93,7 @@ public class MCAChunk extends FaweChunk { out.writeNamedEmptyList("TileEntities"); } else { out.writeNamedTag("TileEntities", new ListTag(CompoundTag.class, - new ArrayList<>(tiles.values()))); + new ArrayList<>(tiles.values()))); } out.writeNamedTag("InhabitedTime", inhabitedTime); out.writeNamedTag("LastUpdate", lastUpdate); @@ -116,9 +102,12 @@ public class MCAChunk extends FaweChunk { } out.writeNamedTag("HeightMap", heightMap); out.writeNamedTagName("Sections", NBTConstants.TYPE_LIST); - nbtOut.writeByte(NBTConstants.TYPE_COMPOUND); - int len = (int) Arrays.stream(ids).filter(Objects::nonNull).count(); - nbtOut.writeInt(len); + nbtOut.getOutputStream().writeByte(NBTConstants.TYPE_COMPOUND); + int len = 0; + for (int[] id : ids) { + if (id != null) len++; + } + nbtOut.getOutputStream().writeInt(len); for (int layer = 0; layer < ids.length; layer++) { int[] idLayer = ids[layer]; if (idLayer == null) { @@ -436,9 +425,9 @@ public class MCAChunk extends FaweChunk { blockLight = new byte[16][]; NBTStreamer streamer = new NBTStreamer(nis); streamer.addReader(".Level.InhabitedTime", - (BiConsumer) (index, value) -> inhabitedTime = value); + (BiConsumer) (index, value) -> inhabitedTime = value); streamer.addReader(".Level.LastUpdate", - (BiConsumer) (index, value) -> lastUpdate = value); + (BiConsumer) (index, value) -> lastUpdate = value); streamer.addReader(".Level.Sections.#", (BiConsumer) (index, tag) -> { int layer = tag.getByte("Y"); ids[layer] = tag.getIntArray("Blocks"); @@ -446,31 +435,31 @@ public class MCAChunk extends FaweChunk { blockLight[layer] = tag.getByteArray("BlockLight"); }); streamer.addReader(".Level.TileEntities.#", - (BiConsumer) (index, tile) -> { - int x1 = tile.getInt("x") & 15; - int y = tile.getInt("y"); - int z1 = tile.getInt("z") & 15; - short pair = MathMan.tripleBlockCoord(x1, y, z1); - tiles.put(pair, tile); - }); + (BiConsumer) (index, tile) -> { + int x1 = tile.getInt("x") & 15; + int y = tile.getInt("y"); + int z1 = tile.getInt("z") & 15; + short pair = MathMan.tripleBlockCoord(x1, y, z1); + tiles.put(pair, tile); + }); streamer.addReader(".Level.Entities.#", - (BiConsumer) (index, entityTag) -> { - if (entities == null) { - entities = new HashMap<>(); - } - long least = entityTag.getLong("UUIDLeast"); - long most = entityTag.getLong("UUIDMost"); - entities.put(new UUID(most, least), entityTag); - }); + (BiConsumer) (index, entityTag) -> { + if (entities == null) { + entities = new HashMap<>(); + } + long least = entityTag.getLong("UUIDLeast"); + long most = entityTag.getLong("UUIDMost"); + entities.put(new UUID(most, least), entityTag); + }); streamer.addReader(".Level.Biomes", - (BiConsumer) (index, value) -> biomes = value); + (BiConsumer) (index, value) -> biomes = value); streamer.addReader(".Level.HeightMap", - (BiConsumer) (index, value) -> heightMap = value); + (BiConsumer) (index, value) -> heightMap = value); if (readPos) { streamer.addReader(".Level.xPos", - (BiConsumer) (index, value) -> MCAChunk.this.setLoc(getParent(), value, getZ())); + (BiConsumer) (index, value) -> MCAChunk.this.setLoc(getParent(), value, getZ())); streamer.addReader(".Level.zPos", - (BiConsumer) (index, value) -> MCAChunk.this.setLoc(getParent(), getX(), value)); + (BiConsumer) (index, value) -> MCAChunk.this.setLoc(getParent(), getX(), value)); } streamer.readFully(); } @@ -610,14 +599,14 @@ public class MCAChunk extends FaweChunk { public BiomeType[] getBiomeArray() { BiomeType[] arr = new BiomeType[256]; for (int i = 0; i < arr.length; i++) { - arr[i] = BiomeTypes.register(biomes[i]); + arr[i] = BiomeTypes.get(biomes[i]); } return arr; } @Override public BiomeType getBiomeType(int x, int z) { - return BiomeTypes.register(biomes[(x & 15) + ((z & 15) << 4)]); + return BiomeTypes.get(biomes[(x & 15) + ((z & 15) << 4)]); } @Override @@ -804,4 +793,4 @@ public class MCAChunk extends FaweChunk { public FaweChunk call() { throw new UnsupportedOperationException("Not supported"); } -} +} \ No newline at end of file diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/FaweTimer.java b/worldedit-core/src/main/java/com/boydti/fawe/util/FaweTimer.java index dd785ffac..4b4a1b8f1 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/util/FaweTimer.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/util/FaweTimer.java @@ -41,7 +41,8 @@ public class FaweTimer implements Runnable { if (tick < lastGetTPSTick + tickInterval) { return lastGetTPSValue; } - double total = Arrays.stream(history).sum(); + double total = 0; + for (double v : history) total += v; lastGetTPSValue = total / history.length; lastGetTPSTick = tick; return lastGetTPSValue; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java index c2abe3036..f99a689eb 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java @@ -408,7 +408,6 @@ public class PlatformManager { } try { - Tool tool = session.getTool(player.getItemInHand(HandSide.MAIN_HAND).getType()); switch (event.getInputType()) { case PRIMARY: { if (getConfiguration().navigationWandMaxDistance > 0 && player.getItemInHand(HandSide.MAIN_HAND).getType().getId().equals(getConfiguration().navigationWand)) { @@ -426,7 +425,7 @@ public class PlatformManager { event.setCancelled(true); return; } - + Tool tool = session.getTool(player); if (tool instanceof DoubleActionTraceTool && tool.canUse(player)) { FawePlayer fp = FawePlayer.wrap(player); fp.runAsyncIfFree(() -> reset((DoubleActionTraceTool) tool).actSecondary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session)); @@ -450,7 +449,7 @@ public class PlatformManager { event.setCancelled(true); return; } - + Tool tool = session.getTool(player); if (tool instanceof TraceTool && tool.canUse(player)) { FawePlayer fp = FawePlayer.wrap(player); //todo this needs to be fixed so the event is canceled after actPrimary is used and returns true diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java index fca8d982c..0bb4c426d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java @@ -62,7 +62,9 @@ import java.util.Map; /** * Reads schematic files that are compatible with MCEdit and other editors. + * @deprecated Use SchematicStreamer */ +@Deprecated public class MCEditSchematicReader extends NBTSchematicReader { private static final Logger log = LoggerFactory.getLogger(MCEditSchematicReader.class); @@ -355,6 +357,10 @@ public class MCEditSchematicReader extends NBTSchematicReader { private String convertBlockEntityId(String id) { switch (id) { + case "Chest": + return "chest"; + case "Sign": + return "sign"; case "Cauldron": return "brewing_stand"; case "Control": diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java index 4c752cb91..460769fa5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java @@ -125,49 +125,22 @@ public class SpongeSchematicReader extends NBTSchematicReader { } } - private Clipboard reader(UUID uuid) throws IOException { - NamedTag rootTag = inputStream.readNamedTag(); - if (!rootTag.getName().equals("Schematic")) { - throw new IOException("Tag 'Schematic' does not exist or is not first"); - } - CompoundTag schematicTag = (CompoundTag) rootTag.getTag(); - - // Check - Map schematic = schematicTag.getValue(); - - int version = requireTag(schematic, "Version", IntTag.class).getValue(); - final Platform platform = WorldEdit.getInstance().getPlatformManager() - .queryCapability(Capability.WORLD_EDITING); - int liveDataVersion = platform.getDataVersion(); - - if (version == 1) { - dataVersion = 1631; // this is a relatively safe assumption unless someone imports a schematic from 1.12, e.g. sponge 7.1- - fixer = platform.getDataFixer(); - return readVersion1(uuid); - } else if (version == 2) { - dataVersion = requireTag(schematic, "DataVersion", IntTag.class).getValue(); - if (dataVersion > liveDataVersion) { - log.warn("Schematic was made in a newer Minecraft version ({} > {}). Data may be incompatible.", - dataVersion, liveDataVersion); - } else if (dataVersion < liveDataVersion) { - fixer = platform.getDataFixer(); - if (fixer != null) { - log.info("Schematic was made in an older Minecraft version ({} < {}), will attempt DFU.", - dataVersion, liveDataVersion); - } else { - log.info("Schematic was made in an older Minecraft version ({} < {}), but DFU is not available. Data may be incompatible.", - dataVersion, liveDataVersion); - } - } - - BlockArrayClipboard clip = readVersion1(uuid); - return readVersion2(clip, schematicTag); - } - - throw new IOException("This schematic version is currently not supported"); + private String fix(String palettePart) { + if (fixer == null || dataVersion == -1) return palettePart; + return fixer.fixUp(DataFixer.FixTypes.BLOCK_STATE, palettePart, dataVersion); } - private BlockArrayClipboard readVersion1(UUID uuid) throws IOException { + private CompoundTag fixBlockEntity(CompoundTag tag) { + if (fixer == null || dataVersion == -1) return tag; + return fixer.fixUp(DataFixer.FixTypes.BLOCK_ENTITY, tag, dataVersion); + } + + private CompoundTag fixEntity(CompoundTag tag) { + if (fixer == null || dataVersion == -1) return tag; + return fixer.fixUp(DataFixer.FixTypes.ENTITY, tag, dataVersion); + } + + private Clipboard reader(UUID uuid) throws IOException { width = height = length = offsetX = offsetY = offsetZ = Integer.MIN_VALUE; final BlockArrayClipboard clipboard = new BlockArrayClipboard(new CuboidRegion(BlockVector3.at(0, 0, 0), BlockVector3.at(0, 0, 0)), fc); @@ -176,6 +149,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { NBTStreamer streamer = new NBTStreamer(inputStream); + streamer.addReader("Schematic.DataVersion", (BiConsumer) (i, v) -> dataVersion = v); streamer.addReader("Schematic.Width", (BiConsumer) (i, v) -> width = v); streamer.addReader("Schematic.Height", (BiConsumer) (i, v) -> height = v); streamer.addReader("Schematic.Length", (BiConsumer) (i, v) -> length = v); @@ -188,7 +162,8 @@ public class SpongeSchematicReader extends NBTSchematicReader { for (Map.Entry entry : v.entrySet()) { BlockState state = null; try { - state = BlockState.get(entry.getKey()); + String palettePart = fix(entry.getKey()); + state = BlockState.get(palettePart); } catch (InputParseException e) { e.printStackTrace(); } @@ -196,6 +171,9 @@ public class SpongeSchematicReader extends NBTSchematicReader { palette[index] = (char) state.getOrdinal(); } }); + + /// readBiomes + streamer.addReader("Schematic.BlockData.#", new NBTStreamer.LazyReader() { @Override public void accept(Integer arrayLen, DataInputStream dis) { @@ -224,21 +202,40 @@ public class SpongeSchematicReader extends NBTSchematicReader { int x = pos[0]; int y = pos[1]; int z = pos[2]; + Map values = value.getValue(); + Tag id = values.get("Id"); + if (id != null) { + values.put("x", new IntTag(x)); + values.put("y", new IntTag(y)); + values.put("z", new IntTag(z)); + values.put("id", id); + } + values.remove("Id"); + values.remove("Pos"); + value = fixBlockEntity(value); fc.setTile(x, y, z, value); }); streamer.addReader("Schematic.Entities.#", (BiConsumer) (index, compound) -> { if (fc == null) { setupClipboard(0, uuid); } - String id = compound.getString("id"); - if (id.isEmpty()) { - return; + Map value = compound.getValue(); + StringTag id = (StringTag) value.get("Id"); + if (id == null) { + id = (StringTag) value.get("id"); + if (id == null) { + return; + } + } else { + value.put("id", id); + value.remove("Id"); } + ListTag positionTag = compound.getListTag("Pos"); ListTag directionTag = compound.getListTag("Rotation"); - EntityType type = EntityTypes.parse(id); + EntityType type = EntityTypes.parse(id.getValue()); if (type != null) { - compound.getValue().put("Id", new StringTag(type.getId())); + compound = fixEntity(compound); BaseEntity state = new BaseEntity(type, compound); fc.createEntity(clipboard, positionTag.asDouble(0), positionTag.asDouble(1), positionTag.asDouble(2), (float) directionTag.asDouble(0), (float) directionTag.asDouble(1), state); } else { @@ -274,7 +271,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { try (FaweInputStream fis = new FaweInputStream(new LZ4BlockInputStream(new FastByteArraysInputStream(biomesOut.toByteArrays())))) { int volume = width * length; for (int index = 0; index < volume; index++) { - fc.setBiome(index, BiomeTypes.register(fis.read())); + fc.setBiome(index, BiomeTypes.get(fis.read())); } } } @@ -283,17 +280,6 @@ public class SpongeSchematicReader extends NBTSchematicReader { return clipboard; } - private Clipboard readVersion2(BlockArrayClipboard version1, CompoundTag schematicTag) throws IOException { - Map schematic = schematicTag.getValue(); - if (schematic.containsKey("BiomeData")) { - readBiomes(version1, schematic); - } - if (schematic.containsKey("Entities")) { - readEntities(version1, schematic); - } - return version1; - } - private void readBiomes(BlockArrayClipboard clipboard, Map schematic) throws IOException { ByteArrayTag dataTag = requireTag(schematic, "BiomeData", ByteArrayTag.class); IntTag maxTag = requireTag(schematic, "BiomePaletteMax", IntTag.class); @@ -309,7 +295,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { if (fixer != null) { key = fixer.fixUp(DataFixer.FixTypes.BIOME, key, dataVersion); } - BiomeType biome = BiomeTypes.register(key); + BiomeType biome = BiomeTypes.get(key); if (biome == null) { log.warn("Unknown biome type :" + key + " in palette. Are you missing a mod or using a schematic made in a newer version of Minecraft?"); @@ -352,37 +338,6 @@ public class SpongeSchematicReader extends NBTSchematicReader { } } - private void readEntities(BlockArrayClipboard clipboard, Map schematic) throws IOException { - List entList = requireTag(schematic, "Entities", ListTag.class).getValue(); - if (entList.isEmpty()) { - return; - } - for (Tag et : entList) { - if (!(et instanceof CompoundTag)) { - continue; - } - CompoundTag entityTag = (CompoundTag) et; - Map tags = entityTag.getValue(); - String id = requireTag(tags, "Id", StringTag.class).getValue(); - entityTag = entityTag.createBuilder().putString("id", id).remove("Id").build(); - - if (fixer != null) { - entityTag = fixer.fixUp(DataFixer.FixTypes.ENTITY, entityTag, dataVersion); - } - - EntityType entityType = EntityTypes.get(id); - if (entityType != null) { - Location location = NBTConversions.toLocation(clipboard, - requireTag(tags, "Pos", ListTag.class), - requireTag(tags, "Rotation", ListTag.class)); - BaseEntity state = new BaseEntity(entityType, entityTag); - clipboard.createEntity(location, state); - } else { - log.warn("Unknown entity when pasting schematic: " + id); - } - } - } - @Override public void close() throws IOException { inputStream.close(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java index a1a67b615..72313a09b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java @@ -25,8 +25,10 @@ import com.boydti.fawe.util.IOUtil; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.collect.Maps; import com.sk89q.jnbt.*; +import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.math.BlockVector2; @@ -107,7 +109,8 @@ public class SpongeSchematicWriter implements ClipboardWriter { final DataOutput rawStream = outputStream.getOutputStream(); outputStream.writeLazyCompoundTag("Schematic", out -> { - out.writeNamedTag("Version", 1); + out.writeNamedTag("DataVersion", WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion()); + out.writeNamedTag("Version", CURRENT_VERSION); out.writeNamedTag("Width", (short) width); out.writeNamedTag("Height", (short) height); out.writeNamedTag("Length", (short) length); @@ -224,6 +227,11 @@ public class SpongeSchematicWriter implements ClipboardWriter { out.writeNamedEmptyList("TileEntities"); } + if (clipboard.hasBiomes()) { + writeBiomes(clipboard, out); + } + + TODO optimize List entities = new ArrayList<>(); for (Entity entity : clipboard.getEntities()) { BaseEntity state = entity.getState(); @@ -238,7 +246,8 @@ public class SpongeSchematicWriter implements ClipboardWriter { } // Store our location data, overwriting any - values.put("id", new StringTag(state.getType().getId())); + values.remove("id"); + values.put("Id", new StringTag(state.getType().getId())); values.put("Pos", writeVector(entity.getLocation())); values.put("Rotation", writeRotation(entity.getLocation())); @@ -251,20 +260,11 @@ public class SpongeSchematicWriter implements ClipboardWriter { } else { out.writeNamedTag("Entities", new ListTag(CompoundTag.class, entities)); } - - // version 2 stuff - if (clipboard.hasBiomes()) { - writeBiomes(clipboard, out); - } - - if (!clipboard.getEntities().isEmpty()) { - writeEntities(clipboard, out); - } - }); } private void writeBiomes(Clipboard clipboard, NBTOutputStream schematic) throws IOException { + TODO optimize BlockVector3 min = clipboard.getMinimumPoint(); int width = clipboard.getRegion().getWidth(); int length = clipboard.getRegion().getLength(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java index 00e9c8d91..0533c4f77 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java @@ -94,11 +94,19 @@ public class BlockTransformExtent extends ResettableExtent { } private static long[] adapt(Direction... dirs) { - return Arrays.stream(dirs).mapToLong(dir -> 1L << dir.ordinal()).toArray(); + long[] arr = new long[dirs.length]; + for (int i = 0; i < arr.length; i++) { + arr[i] = 1L << dirs[i].ordinal(); + } + return arr; } private static long[] adapt(Long... dirs) { - return Arrays.stream(dirs).mapToLong(dir -> dir).toArray(); + long[] arr = new long[dirs.length]; + for (int i = 0; i < arr.length; i++) { + arr[i] = dirs[i]; + } + return arr; } private static long[] getDirections(AbstractProperty property) { @@ -506,37 +514,4 @@ public class BlockTransformExtent extends ResettableExtent { public boolean setBlock(int x, int y, int z, BlockStateHolder block) throws WorldEditException { return super.setBlock(x, y, z, transformInverse(block)); } - - /** - * Get the new value with the transformed direction. - * - * @param allowedStates the allowed states - * @param transform the transform - * @param oldDirection the old direction to transform - * @return a new state or null if none could be found - */ - @Nullable - private static Vector3 getNewStateValue(List allowedStates, Transform transform, Vector3 oldDirection) { - Vector3 newDirection = transform.apply(oldDirection).subtract(transform.apply(Vector3.ZERO)).normalize(); - Vector3 newValue = null; - double closest = -2; - boolean found = false; - - for (Direction v : allowedStates) { - double dot = v.toVector().normalize().dot(newDirection); - if (dot >= closest) { - closest = dot; - newValue = v.toVector(); - found = true; - } - } - - if (found) { - return newValue; - } else { - return null; - } - } - - } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/CombinedRegionFunction.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/CombinedRegionFunction.java index 3e5ba674d..f6f24051f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/CombinedRegionFunction.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/CombinedRegionFunction.java @@ -34,7 +34,7 @@ import java.util.List; */ public class CombinedRegionFunction implements RegionFunction { - private final List functions = new ArrayList<>(); + private RegionFunction[] functions; /** * Create a combined region function. @@ -49,7 +49,7 @@ public class CombinedRegionFunction implements RegionFunction { */ public CombinedRegionFunction(Collection functions) { checkNotNull(functions); - this.functions.addAll(functions); + this.functions = functions.toArray(new RegionFunction[functions.size()]); } /** @@ -58,7 +58,7 @@ public class CombinedRegionFunction implements RegionFunction { * @param function an array of functions to match */ public CombinedRegionFunction(RegionFunction... function) { - this(Arrays.asList(checkNotNull(function))); + this.functions = function; } public static CombinedRegionFunction combine(RegionFunction function, RegionFunction add) { @@ -82,7 +82,9 @@ public class CombinedRegionFunction implements RegionFunction { */ public void add(Collection functions) { checkNotNull(functions); - this.functions.addAll(functions); + ArrayList functionsList = new ArrayList<>(Arrays.asList(this.functions)); + functionsList.addAll(functions); + this.functions = functionsList.toArray(new RegionFunction[functionsList.size()]); } /** @@ -98,11 +100,9 @@ public class CombinedRegionFunction implements RegionFunction { public boolean apply(BlockVector3 position) throws WorldEditException { boolean ret = false; for (RegionFunction function : functions) { - if (function.apply(position)) { - ret = true; - } + ret |= (function.apply(position)); } return ret; } -} +} \ No newline at end of file diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java index 2242e83a7..929863bc5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java @@ -80,14 +80,7 @@ public class Naturalizer implements LayerFunction { } private boolean naturalize(BlockVector3 position, int depth) throws WorldEditException { - BlockState block = editSession.getBlock(position); - BlockState targetBlock = getTargetBlock(depth); - - if (block.equalsFuzzy(targetBlock)) { - return false; - } - - return editSession.setBlock(position, targetBlock); + return editSession.setBlock(position, getTargetBlock(depth)); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockTypeMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockTypeMask.java index 3126aa0a7..e2eceacde 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockTypeMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockTypeMask.java @@ -110,7 +110,7 @@ public class BlockTypeMask extends AbstractExtentMask { @Override public boolean test(BlockVector3 vector) { - return types[getExtent().getBlock(vector).getInternalId()]; + return types[getExtent().getBlock(vector).getBlockType().getInternalId()]; } @Nullable diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SingleBlockTypeMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SingleBlockTypeMask.java index 47d5a460a..ac85fe3d6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SingleBlockTypeMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SingleBlockTypeMask.java @@ -15,7 +15,7 @@ public class SingleBlockTypeMask extends AbstractExtentMask { @Override public boolean test(BlockVector3 vector) { - return getExtent().getBlock(vector).getInternalId() == internalId; + return getExtent().getBlock(vector).getBlockType().getInternalId() == internalId; } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/BackwardsExtentBlockCopy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/BackwardsExtentBlockCopy.java index cafda10f5..8daa51819 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/BackwardsExtentBlockCopy.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/BackwardsExtentBlockCopy.java @@ -3,12 +3,15 @@ package com.sk89q.worldedit.function.operation; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.math.MutableBlockVector3; +import com.sk89q.worldedit.math.MutableVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.transform.Transform; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import java.util.List; +import java.util.Vector; public class BackwardsExtentBlockCopy implements Operation { private final Region region; @@ -16,7 +19,8 @@ public class BackwardsExtentBlockCopy implements Operation { private final RegionFunction function; private final BlockVector3 origin; -// private Vector mutable = new MutableBlockVector3(); + private MutableBlockVector3 mutBV3 = new MutableBlockVector3(); + private MutableVector3 mutV3 = new MutableVector3(); BackwardsExtentBlockCopy(Region region, BlockVector3 origin, Transform transform, RegionFunction function) { this.region = region; @@ -56,7 +60,14 @@ public class BackwardsExtentBlockCopy implements Operation { } private BlockVector3 transform(Transform transform, BlockVector3 pt) { - return transform.apply(Vector3.at(pt.getBlockX() - origin.getBlockX(), pt.getBlockY() - origin.getBlockY(), pt.getBlockZ() - origin.getBlockZ())).toBlockPoint().add(origin.getBlockX(), origin.getBlockY(), origin.getBlockZ()); + mutV3.mutX(((pt.getBlockX() - origin.getBlockX()))); + mutV3.mutY(((pt.getBlockY() - origin.getBlockY()))); + mutV3.mutZ(((pt.getBlockZ() - origin.getBlockZ()))); + Vector3 tmp = transform.apply(mutV3); + mutBV3.mutX((tmp.getBlockX() + origin.getBlockX())); + mutBV3.mutY((tmp.getBlockY() + origin.getBlockY())); + mutBV3.mutZ((tmp.getBlockZ() + origin.getBlockZ())); + return mutBV3; } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java index d8c4eee74..c2e4af23c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java @@ -75,7 +75,7 @@ public class ForwardExtentCopy implements Operation { private int repetitions = 1; private Mask sourceMask = Masks.alwaysTrue(); private boolean removingEntities; - private boolean copyingEntities = true; // default to true for backwards compatibility, sort of + private boolean copyingEntities = true; // default to true for backwards compatibility, sort of // No, it's not for compatibility, it makes sense for entities to be copied and people will get annoyed if it doesn't private boolean copyingBiomes; private RegionFunction sourceFunction = null; private Transform transform = new Identity(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/Operations.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/Operations.java index f1317501b..34bb3f080 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/Operations.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/Operations.java @@ -27,6 +27,8 @@ import com.sk89q.worldedit.WorldEditException; */ public final class Operations { + private static final RunContext context = new RunContext(); + private Operations() { } @@ -38,7 +40,7 @@ public final class Operations { */ public static void complete(Operation op) throws WorldEditException { while (op != null) { - op = op.resume(new RunContext()); + op = op.resume(context); } } @@ -52,7 +54,7 @@ public final class Operations { public static void completeLegacy(Operation op) throws MaxChangedBlocksException { while (op != null) { try { - op = op.resume(new RunContext()); + op = op.resume(context); } catch (MaxChangedBlocksException e) { throw e; } catch (WorldEditException e) { @@ -71,7 +73,7 @@ public final class Operations { public static void completeBlindly(Operation op) { while (op != null) { try { - op = op.resume(new RunContext()); + op = op.resume(context); } catch (WorldEditException e) { throw new RuntimeException(e); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java index 14f09b94b..2c000c668 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java @@ -19,7 +19,9 @@ package com.sk89q.worldedit.function.pattern; +import com.sk89q.minecraft.util.commands.Link; import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.command.UtilityCommands; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; @@ -28,6 +30,7 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; /** * Returns a {@link BlockStateHolder} for a given position. */ +@Link(clazz = UtilityCommands.class, value = "patterns") public interface Pattern { /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/WaterloggedRemover.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/WaterloggedRemover.java index 51f8c0f67..b321b8e65 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/WaterloggedRemover.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/WaterloggedRemover.java @@ -20,28 +20,60 @@ package com.sk89q.worldedit.function.pattern; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.function.mask.BlockMaskBuilder; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.registry.state.Property; +import com.sk89q.worldedit.registry.state.PropertyKey; import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; +import java.lang.ref.SoftReference; +import java.util.Map; +import java.util.function.BiPredicate; +import java.util.function.Predicate; + /** * Removes the waterlogged state from blocks if possible. If not possible, returns air. */ public class WaterloggedRemover extends AbstractExtentPattern { + private static SoftReference cache = new SoftReference<>(null); + + private synchronized BlockState[] getRemap() { + BlockState[] remap = this.cache.get(); + if (remap != null) return remap; + this.cache = new SoftReference<>(remap = new BlockState[BlockTypes.states.length]); + + // init + for (int i = 0; i < remap.length; i++) { + BlockState state = remap[i]; + BlockType type = state.getBlockType(); + if (!type.hasProperty(PropertyKey.WATERLOGGED)) { + continue; + } + if (state.getState(PropertyKey.WATERLOGGED) == Boolean.TRUE) { + remap[i] = state.with(PropertyKey.WATERLOGGED, false); + } + } + return remap; + } + + private final BlockState[] remap; + public WaterloggedRemover(Extent extent) { super(extent); + this.remap = getRemap(); } @Override public BaseBlock apply(BlockVector3 position) { BaseBlock block = getExtent().getFullBlock(position); - @SuppressWarnings("unchecked") - Property prop = (Property) block.getBlockType().getPropertyMap().getOrDefault("waterlogged", null); - if (prop != null) { - return block.with(prop, false); + BlockState newState = remap[block.getOrdinal()]; + if (newState != null) { + return newState.toBaseBlock(block.getNbtData()); } return BlockTypes.AIR.getDefaultState().toBaseBlock(); } -} +} \ No newline at end of file diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/RegionVisitor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/RegionVisitor.java index be01a3c59..01bdae460 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/RegionVisitor.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/RegionVisitor.java @@ -39,7 +39,9 @@ import java.util.List; /** * Utility class to apply region functions to {@link com.sk89q.worldedit.regions.Region}. + * @deprecated let the queue iterate, not the region function which lacks any kind of optimizations / parallelism */ +@Deprecated public class RegionVisitor implements Operation { public final Region region; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java index d5f2bbf9e..f47fd7f60 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.math; +import com.google.common.collect.ComparisonChain; import com.sk89q.worldedit.math.transform.AffineTransform; import java.util.Comparator; @@ -47,26 +48,18 @@ public class BlockVector2 { * cdef * */ - public static final Comparator COMPARING_GRID_ARRANGEMENT = - Comparator.comparingInt(BlockVector2::getZ).thenComparingInt(BlockVector2::getX); + public static final Comparator COMPARING_GRID_ARRANGEMENT = (a, b) -> { + return ComparisonChain.start() + .compare(a.getBlockZ(), b.getBlockZ()) + .compare(a.getBlockX(), b.getBlockX()) + .result(); + }; public static BlockVector2 at(double x, double z) { return at((int) Math.floor(x), (int) Math.floor(z)); } public static BlockVector2 at(int x, int z) { - switch (x) { - case 0: - if (z == 0) { - return ZERO; - } - break; - case 1: - if (z == 1) { - return ONE; - } - break; - } return new BlockVector2(x, z); } @@ -349,27 +342,6 @@ public class BlockVector2 { return divide(n, n); } - /** - * Shift all components right. - * - * @param x the value to shift x by - * @param z the value to shift z by - * @return a new vector - */ - public BlockVector2 shr(int x, int z) { - return at(this.x >> x, this.z >> z); - } - - /** - * Shift all components right by {@code n}. - * - * @param n the value to shift by - * @return a new vector - */ - public BlockVector2 shr(int n) { - return shr(n, n); - } - /** * Get the length of the vector. * @@ -519,8 +491,8 @@ public class BlockVector2 { */ public BlockVector2 getMinimum(BlockVector2 v2) { return new BlockVector2( - Math.min(x, v2.x), - Math.min(z, v2.z) + Math.min(x, v2.x), + Math.min(z, v2.z) ); } @@ -532,8 +504,8 @@ public class BlockVector2 { */ public BlockVector2 getMaximum(BlockVector2 v2) { return new BlockVector2( - Math.max(x, v2.x), - Math.max(z, v2.z) + Math.max(x, v2.x), + Math.max(z, v2.z) ); } @@ -599,4 +571,5 @@ public class BlockVector2 { public String toString() { return "(" + x + ", " + z + ")"; } -} + +} \ No newline at end of file diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java index 4641f8327..0feae6ca3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java @@ -44,20 +44,6 @@ public class BlockVector3 { } public static BlockVector3 at(int x, int y, int z) { - // switch for efficiency on typical cases - // in MC y is rarely 0/1 on selections - switch (y) { - case 0: - if (x == 0 && z == 0) { - return ZERO; - } - break; - case 1: - if (x == 1 && z == 1) { - return ONE; - } - break; - } return new BlockVector3(x, y, z); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java index 6bbf93d70..b7a76e4ef 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java @@ -33,19 +33,6 @@ public class Vector2 { public static final Vector2 ONE = new Vector2(1, 1); public static Vector2 at(double x, double z) { - int xTrunc = (int) x; - switch (xTrunc) { - case 0: - if (x == 0 && z == 0) { - return ZERO; - } - break; - case 1: - if (x == 1 && z == 1) { - return ONE; - } - break; - } return new Vector2(x, z); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java index ec0bf21bf..cee4b8c56 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java @@ -39,21 +39,6 @@ public class Vector3 { public static final Vector3 ONE = new Vector3(1, 1, 1); public static Vector3 at(double x, double y, double z) { - // switch for efficiency on typical cases - // in MC y is rarely 0/1 on selections - int yTrunc = (int) y; - switch (yTrunc) { - case 0: - if (x == 0 && y == 0 && z == 0) { - return ZERO; - } - break; - case 1: - if (x == 1 && y == 1 && z == 1) { - return ONE; - } - break; - } return new Vector3(x, y, z); } @@ -651,9 +636,9 @@ public class Vector3 { @Override public String toString() { - String x = "" + getX(); - String y = "" + getY(); - String z = "" + getZ(); + String x = (getX() == getBlockX() ? "" + getBlockX() : "" + getX()); + String y = (getY() == getBlockY() ? "" + getBlockY() : "" + getY()); + String z = (getZ() == getBlockZ() ? "" + getBlockZ() : "" + getZ()); return "(" + x + ", " + y + ", " + z + ")"; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java index 79a4984c3..44b180483 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java @@ -65,7 +65,7 @@ public class BiomeType implements RegistryItem, Keyed { @Override public int hashCode() { - return this.id.hashCode(); + return this.internalId; // stop changing this } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java index 88db98d1e..677db5424 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java @@ -280,11 +280,7 @@ public class BaseBlock implements BlockStateHolder, TileEntityBlock { @Override public int hashCode() { - int ret = toImmutableState().hashCode() << 3; - if (hasNbtData()) { - ret += getNbtData().hashCode(); - } - return ret; + return blockState.hashCode(); // stop changing this } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java index d25bd6bce..ad81aeaad 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java @@ -280,17 +280,16 @@ public class BlockState implements BlockStateHolder, FawePattern { @Override public boolean equalsFuzzy(BlockStateHolder o) { - if (null == o) { - return false; - } if (this == o) { // Added a reference equality check for speediness return true; } - if (o.getClass() == BlockState.class) { return o.getOrdinal() == this.getOrdinal(); } + if (null == o) { + return false; + } return o.equalsFuzzy(this); } 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 cfd32e8db..55eff879c 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 @@ -99,6 +99,18 @@ public class BlockType implements FawePattern, Keyed { } } + public BlockState withProperties(String properties) { // + int id = getInternalId(); + for (String keyPair : properties.split(",")) { + String[] split = keyPair.split("="); + String name = split[0]; + String value = split[1]; + AbstractProperty btp = settings.propertiesMap.get(name); + id = btp.modify(id, btp.getValueFor(value)); + } + return withStateId(id); + } + @Deprecated public BlockState withPropertyId(int propertyId) { if (settings.stateOrdinals == null) return settings.defaultState; @@ -140,11 +152,7 @@ public class BlockType implements FawePattern, Keyed { * @return The property */ public Property getProperty(String name) { - // Assume it works, CCE later at runtime if not. - @SuppressWarnings("unchecked") - Property property = (Property) getPropertyMap().get(name); - checkArgument(property != null, "%s has no property named %s", this, name); - return property; + return (Property) this.settings.propertiesMap.get(name); // stop changing this (performance) } public boolean hasProperty(PropertyKey key) { @@ -269,12 +277,12 @@ public class BlockType implements FawePattern, Keyed { @Override public int hashCode() { - return this.id.hashCode(); + return settings.internalId; // stop changing this to WEs bad hashcode } @Override public boolean equals(Object obj) { - return obj instanceof BlockType && this.id.equals(((BlockType) obj).id); + return obj == this; // stop changing this to a shitty string comparison } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityTypes.java index eccc116f1..9d0709940 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityTypes.java @@ -20,6 +20,7 @@ package com.sk89q.worldedit.world.entity; import javax.annotation.Nullable; +import java.util.Locale; public class EntityTypes { @@ -133,71 +134,113 @@ public class EntityTypes { return EntityType.REGISTRY.get(id); } - public static EntityType parse(String id) { + private static String convertEntityId(String id) { if (id.startsWith("minecraft:")) id = id.substring(10); - switch (id) { - case "FallingSand": return EntityTypes.FALLING_BLOCK; - case "FireworksRocketEntity": return EntityTypes.FIREWORK_ROCKET; - case "LavaSlime": return EntityTypes.MAGMA_CUBE; - case "MinecartChest": return EntityTypes.CHEST_MINECART; - case "MinecartCommandBlock": return EntityTypes.COMMAND_BLOCK_MINECART; - case "MinecartFurnace": return EntityTypes.FURNACE_MINECART; - case "MinecartHopper": return EntityTypes.HOPPER_MINECART; - case "MinecartRideable": return EntityTypes.MINECART; - case "MinecartSpawner": return EntityTypes.SPAWNER_MINECART; - case "MinecartTNT": return EntityTypes.TNT_MINECART; - case "MushroomCow": return EntityTypes.MOOSHROOM; - case "PigZombie": return EntityTypes.ZOMBIE_PIGMAN; - case "PrimedTnt": return EntityTypes.TNT; - case "SnowMan": return EntityTypes.SNOW_GOLEM; - case "ThrownEgg": return EntityTypes.EGG; - case "ThrownEnderpearl": return EntityTypes.ENDER_PEARL; - case "ThrownExpBottle": return EntityTypes.EXPERIENCE_BOTTLE; - case "ThrownPotion": return EntityTypes.POTION; - case "WitherBoss": return EntityTypes.WITHER; - case "XPOrb": return EntityTypes.EXPERIENCE_ORB; - default: + switch(id) { + case "AreaEffectCloud": return "area_effect_cloud"; + case "ArmorStand": return "armor_stand"; + case "CaveSpider": return "cave_spider"; + case "MinecartChest": return "chest_minecart"; + case "DragonFireball": return "dragon_fireball"; + case "ThrownEgg": return "egg"; + case "EnderDragon": return "ender_dragon"; + case "ThrownEnderpearl": return "ender_pearl"; + case "FallingSand": return "falling_block"; + case "FireworksRocketEntity": return "fireworks_rocket"; + case "MinecartFurnace": return "furnace_minecart"; + case "MinecartHopper": return "hopper_minecart"; + case "EntityHorse": return "horse"; + case "ItemFrame": return "item_frame"; + case "LeashKnot": return "leash_knot"; + case "LightningBolt": return "lightning_bolt"; + case "LavaSlime": return "magma_cube"; + case "MinecartRideable": return "minecart"; + case "MushroomCow": return "mooshroom"; + case "Ozelot": return "ocelot"; + case "PolarBear": return "polar_bear"; + case "ThrownPotion": return "potion"; + case "ShulkerBullet": return "shulker_bullet"; + case "SmallFireball": return "small_fireball"; + case "MinecartSpawner": return "spawner_minecart"; + case "SpectralArrow": return "spectral_arrow"; + case "PrimedTnt": return "tnt"; + case "MinecartTNT": return "tnt_minecart"; + case "VillagerGolem": return "villager_golem"; + case "WitherBoss": return "wither"; + case "WitherSkull": return "wither_skull"; + case "PigZombie": return "zombie_pigman"; + case "XPOrb": return "experience_orb"; + case "ThrownExpBottle": return "experience_bottle"; + case "EyeOfEnderSignal": return "eye_of_ender"; + case "EnderCrystal": return "end_crystal"; + case "MinecartCommandBlock": return "command_block_minecart"; + case "SnowMan": return "snow_golem"; + case "areaeffectcloud": return "area_effect_cloud"; + case "armorstand": return "armor_stand"; + case "cavespider": return "cave_spider"; + case "minecartchest": return "chest_minecart"; + case "dragonfireball": return "dragon_fireball"; + case "thrownegg": return "egg"; + case "enderdragon": return "ender_dragon"; + case "thrownenderpearl": return "ender_pearl"; + case "fallingsand": return "falling_block"; + case "fireworksrocketentity": return "fireworks_rocket"; + case "minecartfurnace": return "furnace_minecart"; + case "minecarthopper": return "hopper_minecart"; + case "entityhorse": return "horse"; + case "itemframe": return "item_frame"; + case "leashknot": return "leash_knot"; + case "lightningbolt": return "lightning_bolt"; + case "lavaslime": return "magma_cube"; + case "minecartrideable": return "minecart"; + case "mushroomcow": return "mooshroom"; + case "ozelot": return "ocelot"; + case "polarbear": return "polar_bear"; + case "thrownpotion": return "potion"; + case "shulkerbullet": return "shulker_bullet"; + case "smallfireball": return "small_fireball"; + case "minecartspawner": return "spawner_minecart"; + case "spectralarrow": return "spectral_arrow"; + case "primedtnt": return "tnt"; + case "minecarttnt": return "tnt_minecart"; + case "villagergolem": return "villager_golem"; + case "witherboss": return "wither"; + case "witherskull": return "wither_skull"; + case "pigzombie": return "zombie_pigman"; + case "xporb": + case "xp_orb": + return "experience_orb"; + case "thrownexpbottle": + case "xp_bottle": + return "experience_bottle"; + case "eyeofendersignal": + case "eye_of_ender_signal": + return "eye_of_ender"; + case "endercrystal": + case "ender_crystal": + return "end_crystal"; + case "fireworks_rocket": return "firework_rocket"; + case "minecartcommandblock": + case "commandblock_minecart": + return "command_block_minecart"; + case "snowman": + return "snow_golem"; + case "villager_golem": return "iron_golem"; + case "evocation_fangs": return "evoker_fangs"; + case "evocation_illager": return "evoker"; + case "vindication_illager": return "vindicator"; + case "illusion_illager": return "illusioner"; + default: { if (Character.isUpperCase(id.charAt(0))) { - StringBuilder result = new StringBuilder(); - for (int i = 0; i < id.length(); i++) { - char c = id.charAt(i); - if (Character.isUpperCase(c)) { - c = Character.toLowerCase(c); - if (i != 0) result.append('_'); - } - result.append(c); - } - return parse(result.toString()); - } - switch (id.toLowerCase()) { - case "xp_orb": - return EntityTypes.EXPERIENCE_ORB; - case "xp_bottle": - return EntityTypes.EXPERIENCE_BOTTLE; - case "eye_of_ender_signal": - return EntityTypes.EYE_OF_ENDER; - case "ender_crystal": - return EntityTypes.END_CRYSTAL; - case "fireworks_rocket": - return EntityTypes.FIREWORK_ROCKET; - case "commandblock_minecart": - return EntityTypes.COMMAND_BLOCK_MINECART; - case "snowman": - return EntityTypes.SNOW_GOLEM; - case "villager_golem": - return EntityTypes.IRON_GOLEM; - case "evocation_fangs": - return EntityTypes.EVOKER_FANGS; - case "evocation_illager": - return EntityTypes.EVOKER; - case "vindication_illager": - return EntityTypes.VINDICATOR; - case "illusion_illager": - return EntityTypes.ILLUSIONER; - default: - return get(id); + return convertEntityId(id.toLowerCase(Locale.ROOT)); } + return id; + } } } + public static EntityType parse(String id) { + return get(convertEntityId(id)); + } + }