From c43109bde52fd498903a15f3bd9f2ec936a599cd Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Sun, 17 Jun 2018 15:42:47 +1000 Subject: [PATCH] Start work on the new BaseBlock/BlockState split --- .../main/java/com/sk89q/util/ArrayUtil.java | 44 ------- .../java/com/sk89q/worldedit/EditSession.java | 15 --- .../java/com/sk89q/worldedit/WorldEdit.java | 111 ++--------------- .../worldedit/blocks/type/BlockState.java | 114 ++++++++++++++++++ .../worldedit/blocks/type/BlockType.java | 39 ++++++ .../worldedit/command/SelectionCommands.java | 67 ++++------ .../sk89q/worldedit/command/ToolCommands.java | 21 +++- .../worldedit/command/UtilityCommands.java | 9 +- .../worldedit/command/tool/AreaPickaxe.java | 4 +- .../worldedit/command/tool/BlockReplacer.java | 4 +- .../command/tool/FloatingTreeRemover.java | 2 +- .../worldedit/command/tool/FloodFillTool.java | 20 +-- .../command/tool/RecursivePickaxe.java | 2 +- .../worldedit/command/tool/SinglePickaxe.java | 8 +- .../scripting/CraftScriptContext.java | 41 +++---- .../sk89q/worldedit/world/AbstractWorld.java | 12 +- .../java/com/sk89q/worldedit/world/World.java | 5 +- .../world/registry/BundledBlockData.java | 5 +- .../registry/state/DirectionalState.java | 5 + .../world/registry/state/SimpleState.java | 13 +- 20 files changed, 273 insertions(+), 268 deletions(-) delete mode 100644 worldedit-core/src/main/java/com/sk89q/util/ArrayUtil.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/blocks/type/BlockState.java diff --git a/worldedit-core/src/main/java/com/sk89q/util/ArrayUtil.java b/worldedit-core/src/main/java/com/sk89q/util/ArrayUtil.java deleted file mode 100644 index 5593c2e75..000000000 --- a/worldedit-core/src/main/java/com/sk89q/util/ArrayUtil.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.util; - -public final class ArrayUtil { - - private ArrayUtil() { - } - - public static String[] removePortionOfArray(String[] array, int from, int to, String replace) { - String[] newArray = new String[from + array.length - to - (replace == null ? 1 : 0)]; - System.arraycopy(array, 0, newArray, 0, from); - if (replace != null) newArray[from] = replace; - System.arraycopy(array, to + 1, newArray, from + (replace == null ? 0 : 1), - array.length - to - 1); - return newArray; - } - - public static char[] removePortionOfArray(char[] array, int from, int to, Character replace) { - char[] newArray = new char[from + array.length - to - (replace == null ? 1 : 0)]; - System.arraycopy(array, 0, newArray, 0, from); - if (replace != null) newArray[from] = replace; - System.arraycopy(array, to + 1, newArray, from + (replace == null ? 0 : 1), - array.length - to - 1); - return newArray; - } -} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index 0537110fd..62d78e4d4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -599,21 +599,6 @@ public class EditSession implements Extent { return bypassNone.commit(); } - /** - * Count the number of blocks of a given list of types in a region. - * - * @param region the region - * @param searchIDs a list of IDs to search - * @return the number of found blocks - */ - public int countBlock(Region region, Set searchIDs) { - Set passOn = new HashSet<>(); - for (Integer i : searchIDs) { - passOn.add(new BaseBlock(i, -1)); - } - return countBlocks(region, passOn); - } - /** * Count the number of blocks of a list of types in a region. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java index 43471520d..52124861a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java @@ -19,12 +19,14 @@ package com.sk89q.worldedit; +import static com.sk89q.worldedit.event.platform.Interaction.HIT; +import static com.sk89q.worldedit.event.platform.Interaction.OPEN; + import com.sk89q.worldedit.CuboidClipboard.FlipDirection; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.entity.Player; -import com.sk89q.worldedit.event.extent.EditSessionEvent; import com.sk89q.worldedit.event.platform.BlockInteractEvent; import com.sk89q.worldedit.event.platform.InputType; import com.sk89q.worldedit.event.platform.PlayerInputEvent; @@ -32,7 +34,6 @@ import com.sk89q.worldedit.extension.factory.BlockFactory; import com.sk89q.worldedit.extension.factory.ItemFactory; import com.sk89q.worldedit.extension.factory.MaskFactory; import com.sk89q.worldedit.extension.factory.PatternFactory; -import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.PlatformManager; @@ -50,23 +51,19 @@ import com.sk89q.worldedit.util.io.file.FilenameResolutionException; import com.sk89q.worldedit.util.io.file.InvalidFilenameException; import com.sk89q.worldedit.util.logging.WorldEditPrefixHandler; import com.sk89q.worldedit.world.registry.BundledBlockData; +import com.sk89q.worldedit.world.registry.BundledItemData; -import javax.script.ScriptException; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.sk89q.worldedit.event.platform.Interaction.HIT; -import static com.sk89q.worldedit.event.platform.Interaction.OPEN; +import javax.script.ScriptException; /** * The entry point and container for a working implementation of WorldEdit. @@ -102,6 +99,7 @@ public class WorldEdit { WorldEditPrefixHandler.register("com.sk89q.worldedit"); getVersion(); BundledBlockData.getInstance(); // Load block registry + BundledItemData.getInstance(); // Load item registry } private WorldEdit() { @@ -191,78 +189,6 @@ public class WorldEdit { return sessions; } - /** - * @deprecated Use {@link #getBlockFactory()} and {@link BlockFactory#parseFromInput(String, ParserContext)} - */ - @Deprecated - public BaseBlock getBlock(Player player, String arg, boolean allAllowed) throws WorldEditException { - return getBlock(player, arg, allAllowed, false); - } - - /** - * @deprecated Use {@link #getBlockFactory()} and {@link BlockFactory#parseFromInput(String, ParserContext)} - */ - @Deprecated - public BaseBlock getBlock(Player player, String arg, boolean allAllowed, boolean allowNoData) throws WorldEditException { - ParserContext context = new ParserContext(); - context.setActor(player); - context.setWorld(player.getWorld()); - context.setSession(getSessionManager().get(player)); - context.setRestricted(!allAllowed); - context.setPreferringWildcard(allowNoData); - return getBlockFactory().parseFromInput(arg, context); - } - - /** - * @deprecated Use {@link #getBlockFactory()} and {@link BlockFactory#parseFromInput(String, ParserContext)} - */ - @Deprecated - public BaseBlock getBlock(Player player, String id) throws WorldEditException { - return getBlock(player, id, false); - } - - /** - * @deprecated Use {@link #getBlockFactory()} and {@link BlockFactory#parseFromListInput(String, ParserContext)} - */ - @Deprecated - public Set getBlocks(Player player, String list, boolean allAllowed, boolean allowNoData) throws WorldEditException { - String[] items = list.split(","); - Set blocks = new HashSet<>(); - for (String id : items) { - blocks.add(getBlock(player, id, allAllowed, allowNoData)); - } - return blocks; - } - - /** - * @deprecated Use {@link #getBlockFactory()} and {@link BlockFactory#parseFromInput(String, ParserContext)} - */ - @Deprecated - public Set getBlocks(Player player, String list, boolean allAllowed) throws WorldEditException { - return getBlocks(player, list, allAllowed, false); - } - - /** - * @deprecated Use {@link #getBlockFactory()} and {@link BlockFactory#parseFromListInput(String, ParserContext)} - */ - @Deprecated - public Set getBlocks(Player player, String list) throws WorldEditException { - return getBlocks(player, list, false); - } - - /** - * @deprecated Use {@link #getBlockFactory()} and {@link BlockFactory#parseFromListInput(String, ParserContext)} - */ - @Deprecated - public Set getBlockIDs(Player player, String list, boolean allBlocksAllowed) throws WorldEditException { - String[] items = list.split(","); - Set blocks = new HashSet<>(); - for (String s : items) { - blocks.add(getBlock(player, s, allBlocksAllowed).getType().getLegacyId()); - } - return blocks; - } - /** * Gets the path to a file. This method will check to see if the filename * has valid characters and has an extension. It also prevents directory @@ -641,7 +567,7 @@ public class WorldEdit { String filename = f.getPath(); int index = filename.lastIndexOf("."); - String ext = filename.substring(index + 1, filename.length()); + String ext = filename.substring(index + 1); if (!ext.equalsIgnoreCase("js")) { player.printError("Only .js scripts are currently supported"); @@ -677,7 +603,7 @@ public class WorldEdit { LocalSession session = getSessionManager().get(player); CraftScriptContext scriptContext = new CraftScriptContext(this, getServer(), getConfiguration(), session, player, args); - CraftScriptEngine engine = null; + CraftScriptEngine engine; try { engine = new RhinoCraftScriptEngine(); @@ -739,20 +665,6 @@ public class WorldEdit { return editSessionFactory; } - /** - * @deprecated EditSessionFactories are no longer used. Please register an {@link EditSessionEvent} event - * with the event bus in order to override or catch changes to the world - */ - @Deprecated - public void setEditSessionFactory(EditSessionFactory factory) { - checkNotNull(factory); - logger.severe("Got request to set EditSessionFactory of type " + - factory.getClass().getName() + " from " + factory.getClass().getPackage().getName() + - " but EditSessionFactories have been removed in favor of extending EditSession's extents.\n\n" + - "This may mean that any block logger / intercepters addons/plugins/mods that you have installed will not " + - "intercept WorldEdit's changes! Please notify the maintainer of the other addon about this."); - } - /** * Get the version. * @@ -782,11 +694,4 @@ public class WorldEdit { return version; } - /** - * @deprecated Declare your platform version with {@link Platform#getPlatformVersion()} - */ - @Deprecated - public static void setVersion(String version) { - } - } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/type/BlockState.java b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/type/BlockState.java new file mode 100644 index 000000000..306f15d27 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/type/BlockState.java @@ -0,0 +1,114 @@ +/* + * 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.blocks.type; + +import com.google.common.collect.ArrayTable; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Maps; +import com.google.common.collect.Table; +import com.sk89q.worldedit.world.registry.state.State; +import com.sk89q.worldedit.world.registry.state.value.SimpleStateValue; + +import java.util.HashMap; +import java.util.Map; + +/** + * An immutable class that represents the state a block can be in. + */ +public class BlockState { + + private final BlockType blockType; + private final Map, SimpleStateValue> values; + + // Neighbouring state table. + private Table, SimpleStateValue, BlockState> states; + + BlockState(BlockType blockType) { + this.blockType = blockType; + this.values = new HashMap<>(); + } + + public void populate(Map, SimpleStateValue>, BlockState> stateMap) { + final Table, SimpleStateValue, BlockState> states = HashBasedTable.create(); + + for(final Map.Entry, SimpleStateValue> entry : this.values.entrySet()) { + final State state = entry.getKey(); + + state.getValues().forEach(value -> { + if(value != entry.getValue()) { + states.put(state, value, stateMap.get(this.withValue(state, value))); + } + }); + } + + this.states = states.isEmpty() ? states : ArrayTable.create(states); + } + + private Map, SimpleStateValue> withValue(final State property, final SimpleStateValue value) { + final Map, SimpleStateValue> values = Maps.newHashMap(this.values); + values.put(property, value); + return values; + } + + /** + * Get the block type + * + * @return The type + */ + public BlockType getBlockType() { + return this.blockType; + } + + /** + * Returns a BlockState with the given state and value applied. + * + * @param state The state + * @param value The value + * @return The modified state, or same if could not be applied + */ + public BlockState with(State state, SimpleStateValue value) { + BlockState result = states.get(state, value); + return result == null ? this : result; + } + + /** + * Gets the value at the given state + * + * @param state The state + * @return The value + */ + public SimpleStateValue getState(State state) { + return this.values.get(state); + } + + /** + * Internal method used for creating the initial BlockState. + * + * Sets a value. DO NOT USE THIS. + * + * @param state The state + * @param value The value + * @return The blockstate, for chaining + */ + BlockState setState(State state, SimpleStateValue value) { + this.values.put(state, value); + return this; + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/type/BlockType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/type/BlockType.java index a61bf0317..a1afc2820 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/type/BlockType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/type/BlockType.java @@ -21,22 +21,61 @@ package com.sk89q.worldedit.blocks.type; import com.sk89q.worldedit.world.registry.BundledBlockData; +import java.util.function.Function; + public class BlockType { private String id; + private BlockState defaultState; public BlockType(String id) { + this(id, null); + } + + public BlockType(String id, Function values) { // If it has no namespace, assume minecraft. if (!id.contains(":")) { id = "minecraft:" + id; } this.id = id; + this.defaultState = new BlockState(this); + if (values != null) { + this.defaultState = values.apply(this.defaultState); + } } + /** + * Gets the ID of this block. + * + * @return The id + */ public String getId() { return this.id; } + /** + * Gets the name of this block, or the ID if the name cannot be found. + * + * @return The name, or ID + */ + public String getName() { + BundledBlockData.BlockEntry entry = BundledBlockData.getInstance().findById(this.id); + if (entry == null) { + return getId(); + } else { + return entry.localizedName; + } + } + + /** + * Gets the default state of this block type. + * + * @return The default state + */ + public BlockState getDefaultState() { + return this.defaultState; + } + /** * Gets the legacy ID. Needed for legacy reasons. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index 8c83bdcac..f5f60ca30 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -34,8 +34,8 @@ import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.regions.Region; @@ -624,26 +624,22 @@ public class SelectionCommands { aliases = { "/count" }, usage = "", desc = "Counts the number of a certain type of block", - flags = "d", min = 1, max = 1 ) @CommandPermissions("worldedit.analysis.count") public void count(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { - boolean useData = args.hasFlag('d'); - if (args.getString(0).contains(":")) { - useData = true; //override d flag, if they specified data they want it - } - if (useData) { - Set searchBlocks = we.getBlocks(player, args.getString(0), true); - int count = editSession.countBlocks(session.getSelection(player.getWorld()), searchBlocks); - player.print("Counted: " + count); - } else { - Set searchIDs = we.getBlockIDs(player, args.getString(0), true); - int count = editSession.countBlock(session.getSelection(player.getWorld()), searchIDs); - player.print("Counted: " + count); - } + ParserContext context = new ParserContext(); + context.setActor(player); + context.setExtent(player.getExtent()); + context.setWorld(player.getWorld()); + context.setSession(session); + context.setRestricted(false); + + Set searchBlocks = we.getBlockFactory().parseFromListInput(args.getString(0), context); + int count = editSession.countBlocks(session.getSelection(player.getWorld()), searchBlocks); + player.print("Counted: " + count); } @Command( @@ -662,49 +658,32 @@ public class SelectionCommands { public void distr(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException, CommandException { int size; - boolean useData = args.hasFlag('d'); - List> distribution = null; - List> distributionData = null; + List> distributionData; if (args.hasFlag('c')) { // TODO: Update for new clipboard throw new CommandException("Needs to be re-written again"); } else { - if (useData) { - distributionData = editSession.getBlockDistributionWithData(session.getSelection(player.getWorld())); - } else { - distribution = editSession.getBlockDistribution(session.getSelection(player.getWorld())); - } + distributionData = editSession.getBlockDistributionWithData(session.getSelection(player.getWorld())); size = session.getSelection(player.getWorld()).getArea(); } - if ((useData && distributionData.size() <= 0) - || (!useData && distribution.size() <= 0)) { // *Should* always be false + if (distributionData.size() <= 0) { // *Should* always be false player.printError("No blocks counted."); return; } player.print("# total blocks: " + size); - if (useData) { - for (Countable c : distributionData) { - String name = BlockType.fromID(c.getID().getId()).getName(); - String str = String.format("%-7s (%.3f%%) %s #%d:%d", - String.valueOf(c.getAmount()), - c.getAmount() / (double) size * 100, - name == null ? "Unknown" : name, - c.getID().getType(), c.getID().getData()); - player.print(str); - } - } else { - for (Countable c : distribution) { - BlockType block = BlockType.fromID(c.getID()); - String str = String.format("%-7s (%.3f%%) %s #%d", - String.valueOf(c.getAmount()), - c.getAmount() / (double) size * 100, - block == null ? "Unknown" : block.getName(), c.getID()); - player.print(str); - } + for (Countable c : distributionData) { + String name = c.getID().getType().getName(); + String str = String.format("%-7s (%.3f%%) %s #%s%s", + String.valueOf(c.getAmount()), + c.getAmount() / (double) size * 100, + name, + c.getID().getType().getId(), + c.getID().getStates()); + player.print(str); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java index 1c3a05d23..ffd9f89ee 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java @@ -100,7 +100,14 @@ public class ToolCommands { @CommandPermissions("worldedit.tool.replacer") public void repl(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { - BaseBlock targetBlock = we.getBlock(player, args.getString(0)); + ParserContext context = new ParserContext(); + context.setActor(player); + context.setWorld(player.getWorld()); + context.setSession(session); + context.setRestricted(true); + context.setPreferringWildcard(false); + + BaseBlock targetBlock = we.getBlockFactory().parseFromInput(args.getString(0), context); session.setTool(player.getItemInHand(), new BlockReplacer(targetBlock)); player.print("Block replacer tool bound to " + ItemType.toHeldName(player.getItemInHand()) + "."); @@ -189,8 +196,16 @@ public class ToolCommands { @CommandPermissions("worldedit.tool.lrbuild") public void longrangebuildtool(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { - BaseBlock secondary = we.getBlock(player, args.getString(0)); - BaseBlock primary = we.getBlock(player, args.getString(1)); + ParserContext context = new ParserContext(); + context.setActor(player); + context.setWorld(player.getWorld()); + context.setSession(session); + context.setRestricted(true); + context.setPreferringWildcard(false); + + BaseBlock secondary = we.getBlockFactory().parseFromInput(args.getString(0), context); + BaseBlock primary = we.getBlockFactory().parseFromInput(args.getString(1), context); + session.setTool(player.getItemInHand(), new LongRangeBuildTool(primary, secondary)); player.print("Long-range building tool bound to " + ItemType.toHeldName(player.getItemInHand()) + "."); player.print("Left-click set to " + ItemType.toName(secondary.getType().getLegacyId()) + "; right-click set to " diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index 08dc0dd6f..1e465df36 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -250,7 +250,14 @@ public class UtilityCommands { @Logging(PLACEMENT) public void removeNear(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { - BaseBlock block = we.getBlock(player, args.getString(0), true); + ParserContext context = new ParserContext(); + context.setActor(player); + context.setWorld(player.getWorld()); + context.setSession(session); + context.setRestricted(false); + context.setPreferringWildcard(false); + + BaseBlock block = we.getBlockFactory().parseFromInput(args.getString(0), context); int size = Math.max(1, args.getInteger(1, 50)); we.checkMaxRadius(size); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java index f33ffbbbe..7551309fe 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java @@ -50,7 +50,7 @@ public class AreaPickaxe implements BlockTool { int ox = clicked.getBlockX(); int oy = clicked.getBlockY(); int oz = clicked.getBlockZ(); - BlockType initialType = ((World) clicked.getExtent()).getBlock(clicked.toVector()).getType(); + BlockType initialType = clicked.getExtent().getBlock(clicked.toVector()).getType(); if (initialType == BlockTypes.AIR) { return true; @@ -72,7 +72,7 @@ public class AreaPickaxe implements BlockTool { continue; } - ((World) clicked.getExtent()).queueBlockBreakEffect(server, pos, initialType.getLegacyId(), clicked.toVector().distanceSq(pos)); + ((World) clicked.getExtent()).queueBlockBreakEffect(server, pos, initialType, clicked.toVector().distanceSq(pos)); editSession.setBlock(pos, air); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java index 61dc556f6..a329638b6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java @@ -26,7 +26,6 @@ import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extent.inventory.BlockBag; -import com.sk89q.worldedit.world.World; /** * A mode that replaces one block. @@ -66,10 +65,9 @@ public class BlockReplacer implements DoubleActionBlockTool { @Override public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) { - World world = (World) clicked.getExtent(); EditSession editSession = session.createEditSession(player); targetBlock = (editSession).getBlock(clicked.toVector()); - BlockType type = BlockType.fromID(targetBlock.getType().getLegacyId()); + BlockType type = targetBlock.getType().getLegacyType(); if (type != null) { player.print("Replacer tool switched to: " + type.getName()); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloatingTreeRemover.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloatingTreeRemover.java index 7d3bc9698..12e71f951 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloatingTreeRemover.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloatingTreeRemover.java @@ -102,7 +102,7 @@ public class FloatingTreeRemover implements BlockTool { return true; } - Vector[] recurseDirections = { + private Vector[] recurseDirections = { PlayerDirection.NORTH.vector(), PlayerDirection.EAST.vector(), PlayerDirection.SOUTH.vector(), diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloodFillTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloodFillTool.java index dd2a73d86..25ff56c84 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloodFillTool.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloodFillTool.java @@ -67,8 +67,8 @@ public class FloodFillTool implements BlockTool { EditSession editSession = session.createEditSession(player); try { - recurse(server, editSession, world, clicked.toVector().toBlockVector(), - clicked.toVector(), range, initialType.getLegacyId(), new HashSet<>()); + recurse(editSession, clicked.toVector().toBlockVector(), + clicked.toVector(), range, initialType, new HashSet<>()); } catch (MaxChangedBlocksException e) { player.printError("Max blocks change limit reached."); } finally { @@ -78,7 +78,7 @@ public class FloodFillTool implements BlockTool { return true; } - private void recurse(Platform server, EditSession editSession, World world, BlockVector pos, Vector origin, int size, int initialType, + private void recurse(EditSession editSession, BlockVector pos, Vector origin, int size, BlockType initialType, Set visited) throws MaxChangedBlocksException { if (origin.distance(pos) > size || visited.contains(pos)) { @@ -87,23 +87,23 @@ public class FloodFillTool implements BlockTool { visited.add(pos); - if (editSession.getBlock(pos).getType().getLegacyId() == initialType) { + if (editSession.getBlock(pos).getType() == initialType) { editSession.setBlock(pos, pattern.apply(pos)); } else { return; } - recurse(server, editSession, world, pos.add(1, 0, 0).toBlockVector(), + recurse(editSession, pos.add(1, 0, 0).toBlockVector(), origin, size, initialType, visited); - recurse(server, editSession, world, pos.add(-1, 0, 0).toBlockVector(), + recurse(editSession, pos.add(-1, 0, 0).toBlockVector(), origin, size, initialType, visited); - recurse(server, editSession, world, pos.add(0, 0, 1).toBlockVector(), + recurse(editSession, pos.add(0, 0, 1).toBlockVector(), origin, size, initialType, visited); - recurse(server, editSession, world, pos.add(0, 0, -1).toBlockVector(), + recurse(editSession, pos.add(0, 0, -1).toBlockVector(), origin, size, initialType, visited); - recurse(server, editSession, world, pos.add(0, 1, 0).toBlockVector(), + recurse(editSession, pos.add(0, 1, 0).toBlockVector(), origin, size, initialType, visited); - recurse(server, editSession, world, pos.add(0, -1, 0).toBlockVector(), + recurse(editSession, pos.add(0, -1, 0).toBlockVector(), origin, size, initialType, visited); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java index ee2182c68..eb5ec44dd 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java @@ -93,7 +93,7 @@ public class RecursivePickaxe implements BlockTool { return; } - world.queueBlockBreakEffect(server, pos, initialType.getLegacyId(), distanceSq); + world.queueBlockBreakEffect(server, pos, initialType, distanceSq); editSession.setBlock(pos, air); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java index 9b8bdb76d..edafb16c7 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java @@ -24,7 +24,7 @@ import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.blocks.BlockID; +import com.sk89q.worldedit.blocks.type.BlockType; import com.sk89q.worldedit.blocks.type.BlockTypes; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; @@ -44,8 +44,8 @@ public class SinglePickaxe implements BlockTool { @Override public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) { World world = (World) clicked.getExtent(); - final int blockType = world.getLazyBlock(clicked.toVector()).getId(); - if (blockType == BlockID.BEDROCK + final BlockType blockType = world.getLazyBlock(clicked.toVector()).getType(); + if (blockType == BlockTypes.BEDROCK && !player.canDestroyBedrock()) { return true; } @@ -61,7 +61,7 @@ public class SinglePickaxe implements BlockTool { editSession.flushQueue(); } - world.playEffect(clicked.toVector(), 2001, blockType); + world.playEffect(clicked.toVector(), 2001, blockType.getLegacyId()); return true; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java b/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java index 0c5753d6d..96dc8cc89 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java @@ -143,7 +143,7 @@ public class CraftScriptContext extends CraftScriptEnvironment { } /** - * Get an item ID from an item name or an item ID number. + * Get an item from an item name or an item ID number. * * @param input input to parse * @param allAllowed true to ignore blacklists @@ -152,7 +152,14 @@ public class CraftScriptContext extends CraftScriptEnvironment { * @throws DisallowedItemException */ public BaseBlock getBlock(String input, boolean allAllowed) throws WorldEditException { - return controller.getBlock(player, input, allAllowed); + ParserContext context = new ParserContext(); + context.setActor(player); + context.setWorld(player.getWorld()); + context.setSession(session); + context.setRestricted(!allAllowed); + context.setPreferringWildcard(false); + + return controller.getBlockFactory().parseFromListInput(input, context).stream().findFirst().orElse(null); } /** @@ -164,7 +171,7 @@ public class CraftScriptContext extends CraftScriptEnvironment { * @throws DisallowedItemException */ public BaseBlock getBlock(String id) throws WorldEditException { - return controller.getBlock(player, id, false); + return getBlock(id, false); } /** @@ -192,27 +199,13 @@ public class CraftScriptContext extends CraftScriptEnvironment { * @throws UnknownItemException * @throws DisallowedItemException */ - public Set getBlockIDs(String list, boolean allBlocksAllowed) throws WorldEditException { - return controller.getBlockIDs(player, list, allBlocksAllowed); - } - - /** - * Gets the path to a file. This method will check to see if the filename - * has valid characters and has an extension. It also prevents directory - * traversal exploits by checking the root directory and the file directory. - * On success, a {@code java.io.File} object will be returned. - * - *

Use this method if you need to read a file from a directory.

- * - * @param folder sub-directory to look in - * @param filename filename (user-submitted) - * @return a file - * @throws FilenameException - */ - @Deprecated - public File getSafeFile(String folder, String filename) throws FilenameException { - File dir = controller.getWorkingDirectoryFile(folder); - return controller.getSafeOpenFile(player, dir, filename, null, (String[]) null); + public Set getBlocks(String list, boolean allBlocksAllowed) throws WorldEditException { + ParserContext context = new ParserContext(); + context.setActor(player); + context.setWorld(player.getWorld()); + context.setSession(session); + context.setRestricted(!allBlocksAllowed); + return controller.getBlockFactory().parseFromListInput(list, context); } /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java index a3b248570..44ca7d2e8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java @@ -180,7 +180,7 @@ public abstract class AbstractWorld implements World { } @Override - public boolean queueBlockBreakEffect(Platform server, Vector position, int blockId, double priority) { + public boolean queueBlockBreakEffect(Platform server, Vector position, com.sk89q.worldedit.blocks.type.BlockType blockType, double priority) { if (taskId == -1) { taskId = server.schedule(0, 1, () -> { int max = Math.max(1, Math.min(30, effectQueue.size() / 3)); @@ -196,7 +196,7 @@ public abstract class AbstractWorld implements World { return false; } - effectQueue.offer(new QueuedEffect(position, blockId, priority)); + effectQueue.offer(new QueuedEffect(position, blockType, priority)); return true; } @@ -218,17 +218,17 @@ public abstract class AbstractWorld implements World { private class QueuedEffect implements Comparable { private final Vector position; - private final int blockId; + private final com.sk89q.worldedit.blocks.type.BlockType blockType; private final double priority; - private QueuedEffect(Vector position, int blockId, double priority) { + private QueuedEffect(Vector position, com.sk89q.worldedit.blocks.type.BlockType blockType, double priority) { this.position = position; - this.blockId = blockId; + this.blockType = blockType; this.priority = priority; } public void play() { - playEffect(position, 2001, blockId); + playEffect(position, 2001, blockType.getLegacyId()); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java index f92126eb0..229c3fa50 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java @@ -27,6 +27,7 @@ import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; +import com.sk89q.worldedit.blocks.type.BlockType; import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.mask.Mask; @@ -262,11 +263,11 @@ public interface World extends Extent { * * @param server the server * @param position the position - * @param blockId the block ID + * @param blockType the block type * @param priority the priority * @return true if the effect was played */ - boolean queueBlockBreakEffect(Platform server, Vector position, int blockId, double priority); + boolean queueBlockBreakEffect(Platform server, Vector position, BlockType blockType, double priority); /** * Get the data for blocks and so on for this world. diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockData.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockData.java index 846eba25c..99bd9cbb7 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockData.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockData.java @@ -98,7 +98,7 @@ public class BundledBlockData { * @return the entry, or null */ @Nullable - private BlockEntry findById(String id) { + public BlockEntry findById(String id) { // If it has no namespace, assume minecraft. if (!id.contains(":")) { id = "minecraft:" + id; @@ -190,10 +190,11 @@ public class BundledBlockData { return INSTANCE; } - private static class BlockEntry { + public static class BlockEntry { private int legacyId; private String id; private String unlocalizedName; + public String localizedName; private List aliases; private Map states = new HashMap<>(); private SimpleBlockMaterial material = new SimpleBlockMaterial(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/state/DirectionalState.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/state/DirectionalState.java index d4a578a67..0f9967c48 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/state/DirectionalState.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/state/DirectionalState.java @@ -21,6 +21,11 @@ package com.sk89q.worldedit.world.registry.state; import com.sk89q.worldedit.world.registry.state.value.DirectionalStateValue; +import java.util.List; + public class DirectionalState extends SimpleState { + public DirectionalState(List values) { + super(values); + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/state/SimpleState.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/state/SimpleState.java index a6c66bf1d..790e47bca 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/state/SimpleState.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/state/SimpleState.java @@ -21,17 +21,24 @@ package com.sk89q.worldedit.world.registry.state; import com.sk89q.worldedit.world.registry.state.value.SimpleStateValue; -import java.util.ArrayList; import java.util.Collections; import java.util.List; public class SimpleState implements State { - private List values = new ArrayList<>(); + private List values; + + /** + * Creates a state with values + * + * @param values The values + */ + public SimpleState(List values) { + this.values = values; + } @Override public List getValues() { return Collections.unmodifiableList(values); } - }