Selective upstream merge

Signed-off-by: MattBDev <4009945+MattBDev@users.noreply.github.com>
This commit is contained in:
MattBDev 2019-06-04 11:48:30 -04:00
parent c73fc28847
commit 6c94cca15e
75 changed files with 1039 additions and 1182 deletions

View File

@ -83,6 +83,9 @@ public final class Spigot_v1_13_R2 extends CachedBukkitAdapter implements Bukkit
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
public Spigot_v1_13_R2() throws NoSuchFieldException, NoSuchMethodException { public Spigot_v1_13_R2() throws NoSuchFieldException, NoSuchMethodException {
// A simple test
CraftServer.class.cast(Bukkit.getServer());
// The list of tags on an NBTTagList // The list of tags on an NBTTagList
nbtListTagListField = NBTTagList.class.getDeclaredField("list"); nbtListTagListField = NBTTagList.class.getDeclaredField("list");
nbtListTagListField.setAccessible(true); nbtListTagListField.setAccessible(true);
@ -139,6 +142,7 @@ public final class Spigot_v1_13_R2 extends CachedBukkitAdapter implements Bukkit
@Nullable @Nullable
private static String getEntityId(Entity entity) { private static String getEntityId(Entity entity) {
MinecraftKey minecraftkey = EntityTypes.getName(entity.getBukkitEntity().getHandle().P()); MinecraftKey minecraftkey = EntityTypes.getName(entity.getBukkitEntity().getHandle().P());
return minecraftkey == null ? null : minecraftkey.toString(); return minecraftkey == null ? null : minecraftkey.toString();
} }

View File

@ -23,6 +23,7 @@ public final class ArrayWrapper<E> {
* *
* @param elements The elements of the array. * @param elements The elements of the array.
*/ */
@SafeVarargs
public ArrayWrapper(E... elements) { public ArrayWrapper(E... elements) {
setArray(elements); setArray(elements);
} }

View File

@ -12,27 +12,17 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayDeque; import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.logging.Level; import java.util.logging.Level;
import org.bukkit.Achievement;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.Statistic;
import org.bukkit.Statistic.Type;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.configuration.serialization.ConfigurationSerialization;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull;
import static com.boydti.fawe.bukkit.chat.TextualComponent.rawText; import static com.boydti.fawe.bukkit.chat.TextualComponent.rawText;
@ -271,162 +261,6 @@ public class FancyMessage implements JsonRepresentedObject, Cloneable, Iterable<
return this; return this;
} }
/**
* Set the behavior of the current editing component to display information about an achievement when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
*
* @param name The name of the achievement to display, excluding the "achievement." prefix.
* @return This builder instance.
*/
public FancyMessage achievementTooltip(final String name) {
onHover("show_achievement", new JsonString("achievement." + name));
return this;
}
/**
* Set the behavior of the current editing component to display information about an achievement when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
*
* @param which The achievement to display.
* @return This builder instance.
*/
public FancyMessage achievementTooltip(final Achievement which) {
try {
Object achievement = Reflection.getMethod(Reflection.getOBCClass("CraftStatistic"), "getNMSAchievement", Achievement.class).invoke(null, which);
return achievementTooltip((String) Reflection.getField(Reflection.getNMSClass("Achievement"), "name").get(achievement));
} catch (IllegalAccessException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
return this;
} catch (IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
return this;
} catch (InvocationTargetException e) {
Bukkit.getLogger().log(Level.WARNING, "A error has occurred during invoking of method.", e);
return this;
}
}
/**
* Set the behavior of the current editing component to display information about a parameterless statistic when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
*
* @param which The statistic to display.
* @return This builder instance.
* @throws IllegalArgumentException If the statistic requires a parameter which was not supplied.
*/
public FancyMessage statisticTooltip(final Statistic which) {
Type type = which.getType();
if (type != Type.UNTYPED) {
throw new IllegalArgumentException("That statistic requires an additional " + type + " parameter!");
}
try {
Object statistic = Reflection.getMethod(Reflection.getOBCClass("CraftStatistic"), "getNMSStatistic", Statistic.class).invoke(null, which);
return achievementTooltip((String) Reflection.getField(Reflection.getNMSClass("Statistic"), "name").get(statistic));
} catch (IllegalAccessException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
return this;
} catch (IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
return this;
} catch (InvocationTargetException e) {
Bukkit.getLogger().log(Level.WARNING, "A error has occurred during invoking of method.", e);
return this;
}
}
/**
* Set the behavior of the current editing component to display information about a statistic parameter with a material when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
*
* @param which The statistic to display.
* @param item The sole material parameter to the statistic.
* @return This builder instance.
* @throws IllegalArgumentException If the statistic requires a parameter which was not supplied, or was supplied a parameter that was not required.
*/
public FancyMessage statisticTooltip(final Statistic which, Material item) {
Type type = which.getType();
if (type == Type.UNTYPED) {
throw new IllegalArgumentException("That statistic needs no additional parameter!");
}
if ((type == Type.BLOCK && item.isBlock()) || type == Type.ENTITY) {
throw new IllegalArgumentException("Wrong parameter type for that statistic - needs " + type + "!");
}
try {
Object statistic = Reflection.getMethod(Reflection.getOBCClass("CraftStatistic"), "getMaterialStatistic", Statistic.class, Material.class).invoke(null, which, item);
return achievementTooltip((String) Reflection.getField(Reflection.getNMSClass("Statistic"), "name").get(statistic));
} catch (IllegalAccessException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
return this;
} catch (IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
return this;
} catch (InvocationTargetException e) {
Bukkit.getLogger().log(Level.WARNING, "A error has occurred during invoking of method.", e);
return this;
}
}
/**
* Set the behavior of the current editing component to display information about a statistic parameter with an entity type when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
*
* @param which The statistic to display.
* @param entity The sole entity type parameter to the statistic.
* @return This builder instance.
* @throws IllegalArgumentException If the statistic requires a parameter which was not supplied, or was supplied a parameter that was not required.
*/
public FancyMessage statisticTooltip(final Statistic which, EntityType entity) {
Type type = which.getType();
if (type == Type.UNTYPED) {
throw new IllegalArgumentException("That statistic needs no additional parameter!");
}
if (type != Type.ENTITY) {
throw new IllegalArgumentException("Wrong parameter type for that statistic - needs " + type + "!");
}
try {
Object statistic = Reflection.getMethod(Reflection.getOBCClass("CraftStatistic"), "getEntityStatistic", Statistic.class, EntityType.class).invoke(null, which, entity);
return achievementTooltip((String) Reflection.getField(Reflection.getNMSClass("Statistic"), "name").get(statistic));
} catch (IllegalAccessException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
return this;
} catch (IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
return this;
} catch (InvocationTargetException e) {
Bukkit.getLogger().log(Level.WARNING, "A error has occurred during invoking of method.", e);
return this;
}
}
/**
* Set the behavior of the current editing component to display information about an item when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
*
* @param itemJSON A string representing the JSON-serialized NBT data tag of an {@link ItemStack}.
* @return This builder instance.
*/
public FancyMessage itemTooltip(final String itemJSON) {
onHover("show_item", new JsonString(itemJSON)); // Seems a bit hacky, considering we have a JSON object as a parameter
return this;
}
/**
* Set the behavior of the current editing component to display information about an item when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
*
* @param itemStack The stack for which to display information.
* @return This builder instance.
*/
public FancyMessage itemTooltip(final ItemStack itemStack) {
try {
Object nmsItem = Reflection.getMethod(Reflection.getOBCClass("inventory.CraftItemStack"), "asNMSCopy", ItemStack.class).invoke(null, itemStack);
return itemTooltip(Reflection.getMethod(Reflection.getNMSClass("ItemStack"), "save", Reflection.getNMSClass("NBTTagCompound")).invoke(nmsItem, Reflection.getNMSClass("NBTTagCompound").newInstance()).toString());
} catch (Exception e) {
e.printStackTrace();
return this;
}
}
/** /**
* Set the behavior of the current editing component to display raw text when the client hovers over the text. * Set the behavior of the current editing component to display raw text when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p> * <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
@ -579,9 +413,7 @@ public class FancyMessage implements JsonRepresentedObject, Cloneable, Iterable<
* @return This builder instance. * @return This builder instance.
*/ */
public FancyMessage translationReplacements(final FancyMessage... replacements) { public FancyMessage translationReplacements(final FancyMessage... replacements) {
for (FancyMessage str : replacements) { Collections.addAll(latest().translationReplacements, replacements);
latest().translationReplacements.add(str);
}
dirty = true; dirty = true;
@ -873,6 +705,7 @@ public class FancyMessage implements JsonRepresentedObject, Cloneable, Iterable<
/** /**
* <b>Internally called method. Not for API consumption.</b> * <b>Internally called method. Not for API consumption.</b>
*/ */
@NotNull
public Iterator<MessagePart> iterator() { public Iterator<MessagePart> iterator() {
return messageParts.iterator(); return messageParts.iterator();
} }

View File

@ -1,7 +1,6 @@
package com.boydti.fawe.bukkit.chat; package com.boydti.fawe.bukkit.chat;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.gson.stream.JsonWriter; import com.google.gson.stream.JsonWriter;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
@ -75,48 +74,6 @@ public abstract class TextualComponent implements Cloneable {
throw new UnsupportedOperationException("This feature is only supported in snapshot releases."); throw new UnsupportedOperationException("This feature is only supported in snapshot releases.");
} }
/**
* Create a textual component representing a scoreboard value.
* The client will see their own score for the specified objective as the text represented by this component.
* <p>
* <b>This method is currently guaranteed to throw an {@code UnsupportedOperationException} as it is only supported on snapshot clients.</b>
* </p>
*
* @param scoreboardObjective The name of the objective for which to display the score.
* @return The text component representing the specified scoreboard score (for the viewing player), or {@code null} if an error occurs during
* JSON serialization.
*/
public static TextualComponent objectiveScore(String scoreboardObjective) {
return objectiveScore("*", scoreboardObjective);
}
/**
* Create a textual component representing a scoreboard value.
* The client will see the score of the specified player for the specified objective as the text represented by this component.
*
* <p><b>This method is currently guaranteed to throw an {@code UnsupportedOperationException}
* as it is only supported on snapshot clients.</b>
*
* @param playerName The name of the player whos score will be shown. If
* this string represents the single-character sequence
* "*", the viewing player's score will be displayed.
* Standard minecraft selectors (@a, @p, etc)
* are <em>not</em> supported.
* @param scoreboardObjective The name of the objective for
* which to display the score.
* @return The text component representing the specified scoreboard score
* for the specified player, or {@code null} if an error occurs during JSON serialization.
*/
public static TextualComponent objectiveScore(String playerName, String scoreboardObjective) {
throwUnsupportedSnapshot(); // Remove this line when the feature is released to non-snapshot versions, in addition to updating ALL THE
// OVERLOADS documentation accordingly
return new ComplexTextTypeComponent("score", ImmutableMap.<String, String>builder()
.put("name", playerName)
.put("objective", scoreboardObjective)
.build());
}
/** /**
* Create a textual component representing a player name, retrievable by using a standard minecraft selector. * Create a textual component representing a player name, retrievable by using a standard minecraft selector.
* The client will see the players or entities captured by the specified selector as the text represented by this component. * The client will see the players or entities captured by the specified selector as the text represented by this component.

View File

@ -14,11 +14,9 @@ import org.bukkit.plugin.Plugin;
public class FactionsFeature extends BukkitMaskManager implements Listener { public class FactionsFeature extends BukkitMaskManager implements Listener {
FaweBukkit plugin; FaweBukkit plugin;
private Plugin factions;
public FactionsFeature(final Plugin factionsPlugin, final FaweBukkit p3) { public FactionsFeature(final Plugin factionsPlugin, final FaweBukkit p3) {
super(factionsPlugin.getName()); super(factionsPlugin.getName());
this.factions = factionsPlugin;
this.plugin = p3; this.plugin = p3;
} }
@ -42,8 +40,7 @@ public class FactionsFeature extends BukkitMaskManager implements Listener {
} }
}; };
} }
} } else if (fac.getOnlinePlayers().contains(player)) {
else if (fac.getOnlinePlayers().contains(player)) {
if (!fac.getComparisonName().equals("wilderness")) { if (!fac.getComparisonName().equals("wilderness")) {
final Chunk chunk = loc.getChunk(); final Chunk chunk = loc.getChunk();
final Location pos1 = new Location(loc.getWorld(), chunk.getX() * 16, 0, chunk.getZ() * 16); final Location pos1 = new Location(loc.getWorld(), chunk.getX() * 16, 0, chunk.getZ() * 16);

View File

@ -26,14 +26,14 @@ import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
public class Worldguard extends BukkitMaskManager implements Listener { public class Worldguard extends BukkitMaskManager implements Listener {
WorldGuardPlugin worldguard; private WorldGuardPlugin worldguard;
FaweBukkit plugin; FaweBukkit plugin;
private WorldGuardPlugin getWorldGuard() { private WorldGuardPlugin getWorldGuard() {
final Plugin plugin = Bukkit.getPluginManager().getPlugin("WorldGuard"); final Plugin plugin = Bukkit.getPluginManager().getPlugin("WorldGuard");
// WorldGuard may not be loaded // WorldGuard may not be loaded
if ((plugin == null) || !(plugin instanceof WorldGuardPlugin)) { if (!(plugin instanceof WorldGuardPlugin)) {
return null; // Maybe you want throw an exception instead return null; // Maybe you want throw an exception instead
} }
@ -46,13 +46,13 @@ public class Worldguard extends BukkitMaskManager implements Listener {
this.plugin = p3; this.plugin = p3;
} }
public ProtectedRegion getRegion(final com.sk89q.worldguard.LocalPlayer player, final Location loc) { public ProtectedRegion getRegion(final LocalPlayer player, final Location location) {
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
if (container == null) { if (container == null) {
System.out.println("Region capability is not enabled for WorldGuard."); System.out.println("Region capability is not enabled for WorldGuard.");
return null; return null;
} }
RegionManager manager = container.get(FaweAPI.getWorld(loc.getWorld().getName())); RegionManager manager = container.get(FaweAPI.getWorld(location.getWorld().getName()));
if (manager == null) { if (manager == null) {
System.out.println("Region capability is not enabled for that world."); System.out.println("Region capability is not enabled for that world.");
return null; return null;
@ -61,7 +61,7 @@ public class Worldguard extends BukkitMaskManager implements Listener {
if (global != null && isAllowed(player, global)) { if (global != null && isAllowed(player, global)) {
return global; return global;
} }
final ApplicableRegionSet regions = manager.getApplicableRegions(BlockVector3.at(loc.getX(), loc.getY(), loc.getZ())); final ApplicableRegionSet regions = manager.getApplicableRegions(BlockVector3.at(location.getX(), location.getY(), location.getZ()));
for (final ProtectedRegion region : regions) { for (final ProtectedRegion region : regions) {
if (isAllowed(player, region)) { if (isAllowed(player, region)) {
return region; return region;
@ -71,7 +71,7 @@ public class Worldguard extends BukkitMaskManager implements Listener {
} }
public boolean isAllowed(LocalPlayer localplayer, ProtectedRegion region) { public boolean isAllowed(LocalPlayer localplayer, ProtectedRegion region) {
if (region.isOwner(localplayer) || region.isOwner(localplayer.getName())) { if (region.isOwner(localplayer) || region.isOwner(localplayer)) {
return true; return true;
} else if (region.getId().toLowerCase().equals(localplayer.getName().toLowerCase())) { } else if (region.getId().toLowerCase().equals(localplayer.getName().toLowerCase())) {
return true; return true;
@ -81,7 +81,7 @@ public class Worldguard extends BukkitMaskManager implements Listener {
return true; return true;
} }
if (localplayer.hasPermission("fawe.worldguard.member")) { if (localplayer.hasPermission("fawe.worldguard.member")) {
if (region.isMember(localplayer) || region.isMember(localplayer.getName())) { if (region.isMember(localplayer) || region.isMember(localplayer)) {
return true; return true;
} else if (region.isMember("*")) { } else if (region.isMember("*")) {
return true; return true;
@ -93,7 +93,7 @@ public class Worldguard extends BukkitMaskManager implements Listener {
@Override @Override
public FaweMask getMask(FawePlayer<Player> fp, MaskType type) { public FaweMask getMask(FawePlayer<Player> fp, MaskType type) {
final Player player = fp.parent; final Player player = fp.parent;
final com.sk89q.worldguard.LocalPlayer localplayer = this.worldguard.wrapPlayer(player); final LocalPlayer localplayer = this.worldguard.wrapPlayer(player);
final Location location = player.getLocation(); final Location location = player.getLocation();
final ProtectedRegion myregion = this.getRegion(localplayer, location); final ProtectedRegion myregion = this.getRegion(localplayer, location);
if (myregion != null) { if (myregion != null) {

View File

@ -15,19 +15,11 @@ public class BukkitReflectionUtils {
* prefix of minecraft classes * prefix of minecraft classes
*/ */
private static volatile String preClassM = null; private static volatile String preClassM = null;
/**
* boolean value, TRUE if server uses forge or MCPC+
*/
private static boolean forge = false;
/** /**
* check server version and class names * check server version and class names
*/ */
public static void init() { public static void init() {
if (Bukkit.getServer() != null) {
if (Bukkit.getVersion().contains("MCPC") || Bukkit.getVersion().contains("Forge")) {
forge = true;
}
final Server server = Bukkit.getServer(); final Server server = Bukkit.getServer();
final Class<?> bukkitServerClass = server.getClass(); final Class<?> bukkitServerClass = server.getClass();
String[] pas = bukkitServerClass.getName().split("\\."); String[] pas = bukkitServerClass.getName().split("\\.");
@ -44,20 +36,12 @@ public class BukkitReflectionUtils {
final String verM = pas[3]; final String verM = pas[3];
preClassM = "net.minecraft.server." + verM; preClassM = "net.minecraft.server." + verM;
} }
} catch (final Exception ignored) { } catch (final Exception e) {
MainUtil.handleError(ignored); MainUtil.handleError(e);
}
} }
} }
/**
* @return true if server has forge classes
*/
public static boolean isForge() {
return forge;
}
/** /**
* Get class for name. Replace {nms} to net.minecraft.server.V*. Replace {cb} to org.bukkit.craftbukkit.V*. Replace * Get class for name. Replace {nms} to net.minecraft.server.V*. Replace {cb} to org.bukkit.craftbukkit.V*. Replace
* {nm} to net.minecraft * {nm} to net.minecraft

View File

@ -61,7 +61,7 @@ public class ItemUtil {
Int2ObjectOpenHashMap<WeakReference<Tag>> map = hashToNMSTag.get(); Int2ObjectOpenHashMap<WeakReference<Tag>> map = hashToNMSTag.get();
if (map == null) { if (map == null) {
map = new Int2ObjectOpenHashMap<>(); map = new Int2ObjectOpenHashMap<>();
hashToNMSTag = new SoftReference(new Int2ObjectOpenHashMap<>(map)); hashToNMSTag = new SoftReference<>(new Int2ObjectOpenHashMap<>(map));
} }
WeakReference<Tag> nativeTagRef = map.get(nmsTag.hashCode()); WeakReference<Tag> nativeTagRef = map.get(nmsTag.hashCode());
if (nativeTagRef != null) { if (nativeTagRef != null) {

View File

@ -442,7 +442,7 @@ public class Fawe {
} }
public static boolean isMainThread() { public static boolean isMainThread() {
return INSTANCE != null ? INSTANCE.thread == Thread.currentThread() : true; return INSTANCE == null || INSTANCE.thread == Thread.currentThread();
} }
/** /**

View File

@ -75,7 +75,7 @@ public abstract class FaweParser<T> extends InputParser<T> {
} }
} }
} }
inputs.add(toParse.substring(last, toParse.length())); inputs.add(toParse.substring(last));
for (int i = 0; i < inputs.size(); i++) { for (int i = 0; i < inputs.size(); i++) {
String full = inputs.get(i); String full = inputs.get(i);
String command = full; String command = full;

View File

@ -41,7 +41,7 @@ public class JSystemFileChooser extends JFileChooser {
private static FilePane findFilePane(Container parent){ private static FilePane findFilePane(Container parent){
for(Component comp: parent.getComponents()){ for(Component comp: parent.getComponents()){
if(FilePane.class.isInstance(comp)){ if(comp instanceof FilePane){
return (FilePane)comp; return (FilePane)comp;
} }
if(comp instanceof Container){ if(comp instanceof Container){

View File

@ -227,14 +227,14 @@ public class SchematicStreamer extends NBTStreamer {
if (forwardType.hasProperty(PropertyKey.SHAPE) && forwardType.hasProperty(PropertyKey.FACING)) { if (forwardType.hasProperty(PropertyKey.SHAPE) && forwardType.hasProperty(PropertyKey.FACING)) {
Direction forwardFacing = (Direction) forwardBlock.getState(PropertyKey.FACING); Direction forwardFacing = (Direction) forwardBlock.getState(PropertyKey.FACING);
if (forwardFacing == left) { if (forwardFacing == left) {
BlockStateHolder rightBlock = fc.getBlock(x + right.getBlockX(), y + right.getBlockY(), z + right.getBlockZ()); BlockStateHolder rightBlock = fc.getBlock(x + right.toBlockVector().getBlockX(), y + right.toBlockVector().getBlockY(), z + right.toBlockVector().getBlockZ());
BlockType rightType = rightBlock.getBlockType(); BlockType rightType = rightBlock.getBlockType();
if (!rightType.hasProperty(PropertyKey.SHAPE) || rightBlock.getState(PropertyKey.FACING) != facing) { if (!rightType.hasProperty(PropertyKey.SHAPE) || rightBlock.getState(PropertyKey.FACING) != facing) {
fc.setBlock(x, y, z, block.with(PropertyKey.SHAPE, "inner_left")); fc.setBlock(x, y, z, block.with(PropertyKey.SHAPE, "inner_left"));
} }
return; return;
} else if (forwardFacing == right) { } else if (forwardFacing == right) {
BlockStateHolder leftBlock = fc.getBlock(x + left.getBlockX(), y + left.getBlockY(), z + left.getBlockZ()); BlockStateHolder leftBlock = fc.getBlock(x + left.toBlockVector().getBlockX(), y + left.toBlockVector().getBlockY(), z + left.toBlockVector().getBlockZ());
BlockType leftType = leftBlock.getBlockType(); BlockType leftType = leftBlock.getBlockType();
if (!leftType.hasProperty(PropertyKey.SHAPE) || leftBlock.getState(PropertyKey.FACING) != facing) { if (!leftType.hasProperty(PropertyKey.SHAPE) || leftBlock.getState(PropertyKey.FACING) != facing) {
fc.setBlock(x, y, z, block.with(PropertyKey.SHAPE, "inner_right")); fc.setBlock(x, y, z, block.with(PropertyKey.SHAPE, "inner_right"));
@ -248,14 +248,14 @@ public class SchematicStreamer extends NBTStreamer {
if (backwardsType.hasProperty(PropertyKey.SHAPE) && backwardsType.hasProperty(PropertyKey.FACING)) { if (backwardsType.hasProperty(PropertyKey.SHAPE) && backwardsType.hasProperty(PropertyKey.FACING)) {
Direction backwardsFacing = (Direction) backwardsBlock.getState(PropertyKey.FACING); Direction backwardsFacing = (Direction) backwardsBlock.getState(PropertyKey.FACING);
if (backwardsFacing == left) { if (backwardsFacing == left) {
BlockStateHolder rightBlock = fc.getBlock(x + right.getBlockX(), y + right.getBlockY(), z + right.getBlockZ()); BlockStateHolder rightBlock = fc.getBlock(x + right.toBlockVector().getBlockX(), y + right.toBlockVector().getBlockY(), z + right.toBlockVector().getBlockZ());
BlockType rightType = rightBlock.getBlockType(); BlockType rightType = rightBlock.getBlockType();
if (!rightType.hasProperty(PropertyKey.SHAPE) || rightBlock.getState(PropertyKey.FACING) != facing) { if (!rightType.hasProperty(PropertyKey.SHAPE) || rightBlock.getState(PropertyKey.FACING) != facing) {
fc.setBlock(x, y, z, block.with(PropertyKey.SHAPE, "outer_left")); fc.setBlock(x, y, z, block.with(PropertyKey.SHAPE, "outer_left"));
} }
return; return;
} else if (backwardsFacing == right) { } else if (backwardsFacing == right) {
BlockStateHolder leftBlock = fc.getBlock(x + left.getBlockX(), y + left.getBlockY(), z + left.getBlockZ()); BlockStateHolder leftBlock = fc.getBlock(x + left.toBlockVector().getBlockX(), y + left.toBlockVector().getBlockY(), z + left.toBlockVector().getBlockZ());
BlockType leftType = leftBlock.getBlockType(); BlockType leftType = leftBlock.getBlockType();
if (!leftType.hasProperty(PropertyKey.SHAPE) || leftBlock.getState(PropertyKey.FACING) != facing) { if (!leftType.hasProperty(PropertyKey.SHAPE) || leftBlock.getState(PropertyKey.FACING) != facing) {
fc.setBlock(x, y, z, block.with(PropertyKey.SHAPE, "outer_right")); fc.setBlock(x, y, z, block.with(PropertyKey.SHAPE, "outer_right"));

View File

@ -14,7 +14,6 @@ import java.util.concurrent.ForkJoinPool;
public class MCAFilter<T> extends IterableThreadLocal<T> { public class MCAFilter<T> extends IterableThreadLocal<T> {
public void withPool(ForkJoinPool pool, MCAQueue queue) { public void withPool(ForkJoinPool pool, MCAQueue queue) {
return;
} }
/** /**

View File

@ -621,8 +621,8 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
@Override @Override
public boolean supports(Capability capability) { public boolean supports(Capability capability) {
switch (capability) { if (capability == Capability.CHANGE_TASKS) {
case CHANGE_TASKS: return false; return false;
} }
return super.supports(capability); return super.supports(capability);
} }

View File

@ -108,9 +108,7 @@ public class WritableMCAChunk extends FaweChunk<Void> {
} }
out.writeNamedTag("InhabitedTime", inhabitedTime); out.writeNamedTag("InhabitedTime", inhabitedTime);
out.writeNamedTag("LastUpdate", lastUpdate); out.writeNamedTag("LastUpdate", lastUpdate);
if (biomes != null) {
out.writeNamedTag("Biomes", biomes); out.writeNamedTag("Biomes", biomes);
}
int len = 0; int len = 0;
for (boolean hasSection : hasSections) { for (boolean hasSection : hasSections) {
if (hasSection) len++; if (hasSection) len++;

View File

@ -98,7 +98,7 @@ public abstract class FawePlayer<T> extends Metadatable {
FakePlayer fake = new FakePlayer(actor.getName(), actor.getUniqueId(), actor); FakePlayer fake = new FakePlayer(actor.getName(), actor.getUniqueId(), actor);
return fake.toFawePlayer(); return fake.toFawePlayer();
} }
if (obj != null && obj.getClass().getName().contains("CraftPlayer") && !Fawe.imp().getPlatform().equals("bukkit")) { if (obj.getClass().getName().contains("CraftPlayer") && !Fawe.imp().getPlatform().equals("bukkit")) {
try { try {
Method methodGetHandle = obj.getClass().getDeclaredMethod("getHandle"); Method methodGetHandle = obj.getClass().getDeclaredMethod("getHandle");
obj = methodGetHandle.invoke(obj); obj = methodGetHandle.invoke(obj);
@ -206,7 +206,7 @@ public abstract class FawePlayer<T> extends Metadatable {
if (region != null) { if (region != null) {
BlockVector3 min = region.getMinimumPoint(); BlockVector3 min = region.getMinimumPoint();
BlockVector3 max = region.getMaximumPoint(); BlockVector3 max = region.getMaximumPoint();
long area = (long) ((max.getX() - min.getX()) * (max.getZ() - min.getZ() + 1)); long area = (max.getX() - min.getX()) * (max.getZ() - min.getZ() + 1);
if (area > 2 << 18) { if (area > 2 << 18) {
setConfirmTask(task, context, command); setConfirmTask(task, context, command);
BlockVector3 base = max.subtract(min).add(BlockVector3.ONE); BlockVector3 base = max.subtract(min).add(BlockVector3.ONE);
@ -220,7 +220,7 @@ public abstract class FawePlayer<T> extends Metadatable {
public synchronized boolean confirm() { public synchronized boolean confirm() {
Runnable confirm = deleteMeta("cmdConfirm"); Runnable confirm = deleteMeta("cmdConfirm");
if (!(confirm instanceof Runnable)) { if (confirm == null) {
return false; return false;
} }
queueAction(() -> { queueAction(() -> {
@ -341,7 +341,7 @@ public abstract class FawePlayer<T> extends Metadatable {
if (session.getClipboard() != null) { if (session.getClipboard() != null) {
return; return;
} }
} catch (EmptyClipboardException e) { } catch (EmptyClipboardException ignored) {
} }
if (player != null) { if (player != null) {
Clipboard clip = doc.toClipboard(); Clipboard clip = doc.toClipboard();

View File

@ -222,7 +222,7 @@ public class BrushSettings {
} }
public BrushSettings addPermissions(String... perms) { public BrushSettings addPermissions(String... perms) {
for (String perm : perms) permissions.add(perm); Collections.addAll(permissions, perms);
return this; return this;
} }

View File

@ -45,7 +45,7 @@ public class SweepBrush implements Brush, ResettableTool {
return; return;
} }
boolean newPos = this.position == null || !position.equals(this.position); boolean newPos = !position.equals(this.position);
this.position = position; this.position = position;
FawePlayer player = editSession.getPlayer(); FawePlayer player = editSession.getPlayer();
if (newPos) { if (newPos) {
@ -98,7 +98,6 @@ public class SweepBrush implements Brush, ResettableTool {
MutableVector3 last = new MutableVector3(0, 0, 0); MutableVector3 last = new MutableVector3(0, 0, 0);
for (double pos = 0D; pos <= 1D; pos += step) { for (double pos = 0D; pos <= 1D; pos += step) {
Vector3 gradient = interpol.get1stDerivative(pos); Vector3 gradient = interpol.get1stDerivative(pos);
if (last == null) last = new MutableVector3(interpol.get1stDerivative(pos));
double dist = MathMan.sqrtApprox(last.distanceSq(gradient)); double dist = MathMan.sqrtApprox(last.distanceSq(gradient));
last.mutX(gradient.getX()); last.mutX(gradient.getX());
last.mutY(gradient.getY()); last.mutY(gradient.getY());

View File

@ -2,7 +2,6 @@ package com.boydti.fawe.object.changeset;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweAPI; import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory; import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FaweChunk;
@ -14,9 +13,6 @@ import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockID;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.history.change.BlockChange; import com.sk89q.worldedit.history.change.BlockChange;
import com.sk89q.worldedit.history.change.Change; import com.sk89q.worldedit.history.change.Change;
@ -27,7 +23,8 @@ import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockID;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
@ -58,7 +55,7 @@ public abstract class FaweChangeSet implements ChangeSet {
public FaweChangeSet(String world) { public FaweChangeSet(String world) {
this.worldName = world; this.worldName = world;
this.mainThread = (Fawe.get() != null) ? Fawe.isMainThread() : true; this.mainThread = (Fawe.get() == null) || Fawe.isMainThread();
this.layers = FaweChunk.HEIGHT >> 4; this.layers = FaweChunk.HEIGHT >> 4;
} }
@ -85,15 +82,12 @@ public abstract class FaweChangeSet implements ChangeSet {
public boolean closeAsync() { public boolean closeAsync() {
waitingAsync.incrementAndGet(); waitingAsync.incrementAndGet();
TaskManager.IMP.async(new Runnable() { TaskManager.IMP.async(() -> {
@Override
public void run() {
waitingAsync.decrementAndGet(); waitingAsync.decrementAndGet();
synchronized (waitingAsync) { synchronized (waitingAsync) {
waitingAsync.notifyAll(); waitingAsync.notifyAll();
} }
close(); close();
}
}); });
return true; return true;
} }
@ -153,8 +147,6 @@ public abstract class FaweChangeSet implements ChangeSet {
public void delete() { public void delete() {
} }
;
public EditSession toEditSession(FawePlayer player) { public EditSession toEditSession(FawePlayer player) {
return toEditSession(player, null); return toEditSession(player, null);
} }
@ -258,9 +250,7 @@ public abstract class FaweChangeSet implements ChangeSet {
@Override @Override
public void run(final FaweChunk previous, final FaweChunk next) { public void run(final FaweChunk previous, final FaweChunk next) {
FaweChangeSet.this.waitingCombined.incrementAndGet(); FaweChangeSet.this.waitingCombined.incrementAndGet();
Runnable run = new Runnable() { Runnable run = () -> {
@Override
public void run() {
try { try {
int cx = previous.getX(); int cx = previous.getX();
int cz = previous.getZ(); int cz = previous.getZ();
@ -299,10 +289,7 @@ public abstract class FaweChangeSet implements ChangeSet {
for (int x = 0; x < 16; x++, index++) { for (int x = 0; x < 16; x++, index++) {
int xx = x + bx; int xx = x + bx;
int combinedIdCurrent = currentLayer[index]; int combinedIdCurrent = currentLayer[index];
switch (combinedIdCurrent) { if (combinedIdCurrent != 0) {
case 0:
continue;
default:
int combinedIdPrevious; int combinedIdPrevious;
if (previousLayer != null) { if (previousLayer != null) {
combinedIdPrevious = previousLayer[index]; combinedIdPrevious = previousLayer[index];
@ -367,7 +354,6 @@ public abstract class FaweChangeSet implements ChangeSet {
} }
} }
} }
}
}; };
if (mainThread) { if (mainThread) {
run.run(); run.run();

View File

@ -229,8 +229,8 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
// skip mode // skip mode
int mode = is.read(); int mode = is.read();
// origin // origin
int x = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + (is.read() << 0)); int x = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + is.read());
int z = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + (is.read() << 0)); int z = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + is.read());
setOrigin(x, z); setOrigin(x, z);
setupStreamDelegates(mode); setupStreamDelegates(mode);
} }
@ -328,7 +328,7 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
public void addBiomeChange(int x, int z, BiomeType from, BiomeType to) { public void addBiomeChange(int x, int z, BiomeType from, BiomeType to) {
blockSize++; blockSize++;
try { try {
OutputStream os = getBiomeOS(); FaweOutputStream os = getBiomeOS();
os.write((byte) (x >> 24)); os.write((byte) (x >> 24));
os.write((byte) (x >> 16)); os.write((byte) (x >> 16));
os.write((byte) (x >> 8)); os.write((byte) (x >> 8));
@ -337,8 +337,8 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
os.write((byte) (z >> 16)); os.write((byte) (z >> 16));
os.write((byte) (z >> 8)); os.write((byte) (z >> 8));
os.write((byte) (z)); os.write((byte) (z));
((FaweOutputStream) os).writeVarInt(from.getInternalId()); os.writeVarInt(from.getInternalId());
((FaweOutputStream) os).writeVarInt(to.getInternalId()); os.writeVarInt(to.getInternalId());
} catch (Throwable e) { } catch (Throwable e) {
MainUtil.handleError(e); MainUtil.handleError(e);
} }
@ -412,7 +412,7 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
change.z = posDel.readZ(is) + originZ; change.z = posDel.readZ(is) + originZ;
idDel.readCombined(is, change, dir); idDel.readCombined(is, change, dir);
return change; return change;
} catch (EOFException ignoreOEF) { } catch (EOFException ignored) {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
MainUtil.handleError(e); MainUtil.handleError(e);
@ -448,7 +448,7 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
} }
public Iterator<MutableBiomeChange> getBiomeIterator(final boolean dir) throws IOException { public Iterator<MutableBiomeChange> getBiomeIterator(final boolean dir) throws IOException {
final InputStream is = getBiomeIS(); final FaweInputStream is = getBiomeIS();
if (is == null) { if (is == null) {
return new ArrayList<MutableBiomeChange>().iterator(); return new ArrayList<MutableBiomeChange>().iterator();
} }
@ -460,14 +460,14 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
try { try {
int int1 = is.read(); int int1 = is.read();
if (int1 != -1) { if (int1 != -1) {
int x = ((int1 << 24) + (is.read() << 16) + (is.read() << 8) + (is.read() << 0)); int x = ((int1 << 24) + (is.read() << 16) + (is.read() << 8) + is.read());
int z = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + (is.read() << 0)); int z = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + is.read());
int from = ((FaweInputStream) is).readVarInt(); int from = is.readVarInt();
int to = ((FaweInputStream) is).readVarInt(); int to = is.readVarInt();
change.setBiome(x, z, from, to); change.setBiome(x, z, from, to);
return change; return change;
} }
} catch (EOFException ignoreOEF) { } catch (EOFException ignored) {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
MainUtil.handleError(e); MainUtil.handleError(e);
@ -516,9 +516,6 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
public Iterator<MutableFullBlockChange> getFullBlockIterator(BlockBag blockBag, int inventory, final boolean dir) throws IOException { public Iterator<MutableFullBlockChange> getFullBlockIterator(BlockBag blockBag, int inventory, final boolean dir) throws IOException {
final FaweInputStream is = new FaweInputStream(getBlockIS()); final FaweInputStream is = new FaweInputStream(getBlockIS());
if (is == null) {
return new ArrayList<MutableFullBlockChange>().iterator();
}
final MutableFullBlockChange change = new MutableFullBlockChange(blockBag, inventory, dir); final MutableFullBlockChange change = new MutableFullBlockChange(blockBag, inventory, dir);
return new Iterator<MutableFullBlockChange>() { return new Iterator<MutableFullBlockChange>() {
private MutableFullBlockChange last = read(); private MutableFullBlockChange last = read();
@ -530,7 +527,7 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
change.z = posDel.readZ(is) + originZ; change.z = posDel.readZ(is) + originZ;
idDel.readCombined(is, change, dir); idDel.readCombined(is, change, dir);
return change; return change;
} catch (EOFException ignoreOEF) { } catch (EOFException ignored) {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
MainUtil.handleError(e); MainUtil.handleError(e);
@ -576,10 +573,9 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
public MutableEntityChange read() { public MutableEntityChange read() {
try { try {
CompoundTag tag = (CompoundTag) is.readTag(); change.tag = (CompoundTag) is.readTag();
change.tag = tag;
return change; return change;
} catch (Exception ignoreOEF) { } catch (Exception ignored) {
} }
try { try {
is.close(); is.close();
@ -626,10 +622,9 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
public MutableTileChange read() { public MutableTileChange read() {
try { try {
CompoundTag tag = (CompoundTag) is.readTag(); change.tag = (CompoundTag) is.readTag();
change.tag = tag;
return change; return change;
} catch (Exception ignoreOEF) { } catch (Exception ignored) {
} }
try { try {
is.close(); is.close();

View File

@ -24,6 +24,7 @@ import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import sun.misc.Unsafe;
import java.io.Closeable; import java.io.Closeable;
import java.io.File; import java.io.File;
@ -209,7 +210,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
MainUtil.handleError(e); MainUtil.handleError(e);
} }
this.braf = new RandomAccessFile(file, "rw"); this.braf = new RandomAccessFile(file, "rw");
long volume = (long) width * (long) height * (long) length * 4l + (long) HEADER_SIZE; long volume = (long) width * (long) height * (long) length * 4L + (long) HEADER_SIZE;
braf.setLength(0); braf.setLength(0);
braf.setLength(volume); braf.setLength(volume);
if (width * height * length != 0) { if (width * height * length != 0) {
@ -243,7 +244,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
length = dimensions.getBlockZ(); length = dimensions.getBlockZ();
area = width * length; area = width * length;
volume = width * length * height; volume = width * length * height;
long size = width * height * length * 4l + HEADER_SIZE + (hasBiomes() ? area : 0); long size = width * height * length * 4L + HEADER_SIZE + (hasBiomes() ? area : 0);
if (braf.length() < size) { if (braf.length() < size) {
close(); close();
this.braf = new RandomAccessFile(file, "rw"); this.braf = new RandomAccessFile(file, "rw");
@ -505,7 +506,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
mbb.putInt(index, combined); mbb.putInt(index, combined);
boolean hasNbt = block instanceof BaseBlock && ((BaseBlock)block).hasNbtData(); boolean hasNbt = block instanceof BaseBlock && ((BaseBlock)block).hasNbtData();
if (hasNbt) { if (hasNbt) {
setTile(x, y, z, ((BaseBlock)block).getNbtData()); setTile(x, y, z, block.getNbtData());
} }
return true; return true;
} catch (Exception e) { } catch (Exception e) {
@ -520,13 +521,13 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
int combined = block.getInternalId(); int combined = block.getInternalId();
int index = (HEADER_SIZE) + (i << 2); int index = (HEADER_SIZE) + (i << 2);
mbb.putInt(index, combined); mbb.putInt(index, combined);
boolean hasNbt = block instanceof BaseBlock && ((BaseBlock)block).hasNbtData(); boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
if (hasNbt) { if (hasNbt) {
int y = i / area; int y = i / area;
int newI = (i - (y * area)); int newI = (i - (y * area));
int z = newI / width; int z = newI / width;
int x = newI - z * width; int x = newI - z * width;
setTile(x, y, z, ((BaseBlock)block).getNbtData()); setTile(x, y, z, block.getNbtData());
} }
return true; return true;
} catch (Exception e) { } catch (Exception e) {

View File

@ -2,8 +2,6 @@ package com.boydti.fawe.object.clipboard;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
@ -14,12 +12,13 @@ import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import javax.annotation.Nullable;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import javax.annotation.Nullable;
public class EmptyClipboard implements Clipboard { public class EmptyClipboard implements Clipboard {

View File

@ -77,7 +77,7 @@ public class ResizableClipboardBuilder extends MemoryOptimizedHistory {
int x = tileChange.tag.getInt("x"); int x = tileChange.tag.getInt("x");
int y = tileChange.tag.getInt("y"); int y = tileChange.tag.getInt("y");
int z = tileChange.tag.getInt("z"); int z = tileChange.tag.getInt("z");
clipboard.setTile(x, y, z, tileChange.tag); clipboard.setTile(BlockVector3.at(x,y,z), tileChange.tag);
} }
} }
} catch (WorldEditException e) { } catch (WorldEditException e) {

View File

@ -7,13 +7,9 @@ import com.sk89q.worldedit.math.MutableBlockVector3;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectIterator; import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.util.AbstractCollection; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection; import java.util.*;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
/** /**
* The BlockVectorSet is a Memory optimized Set for storing BlockVectors * The BlockVectorSet is a Memory optimized Set for storing BlockVectors
@ -35,16 +31,13 @@ public class BlockVectorSet extends AbstractCollection<BlockVector3> implements
public BlockVector3 get(int index) { public BlockVector3 get(int index) {
int count = 0; int count = 0;
ObjectIterator<Int2ObjectMap.Entry<LocalBlockVectorSet>> iter = localSets.int2ObjectEntrySet().iterator(); for (Int2ObjectMap.Entry<LocalBlockVectorSet> entry : localSets.int2ObjectEntrySet()) {
while (iter.hasNext()) {
Int2ObjectMap.Entry<LocalBlockVectorSet> entry = iter.next();
LocalBlockVectorSet set = entry.getValue(); LocalBlockVectorSet set = entry.getValue();
int size = set.size(); int size = set.size();
int newSize = count + size; int newSize = count + size;
if (newSize > index) { if (newSize > index) {
int localIndex = index - count; int localIndex = index - count;
MutableBlockVector3 pos = new MutableBlockVector3(set.getIndex(localIndex)); MutableBlockVector3 pos = new MutableBlockVector3(set.getIndex(localIndex));
if (pos != null) {
int pair = entry.getIntKey(); int pair = entry.getIntKey();
int cx = MathMan.unpairX(pair); int cx = MathMan.unpairX(pair);
int cz = MathMan.unpairY(pair); int cz = MathMan.unpairY(pair);
@ -52,7 +45,6 @@ public class BlockVectorSet extends AbstractCollection<BlockVector3> implements
pos.mutZ((cz << 11) + pos.getBlockZ()); pos.mutZ((cz << 11) + pos.getBlockZ());
return pos; return pos;
} }
}
count += newSize; count += newSize;
} }
return null; return null;
@ -83,11 +75,12 @@ public class BlockVectorSet extends AbstractCollection<BlockVector3> implements
return false; return false;
} }
@NotNull
@Override @Override
public Iterator<BlockVector3> iterator() { public Iterator<BlockVector3> iterator() {
final ObjectIterator<Int2ObjectMap.Entry<LocalBlockVectorSet>> entries = localSets.int2ObjectEntrySet().iterator(); final ObjectIterator<Int2ObjectMap.Entry<LocalBlockVectorSet>> entries = localSets.int2ObjectEntrySet().iterator();
if (!entries.hasNext()) { if (!entries.hasNext()) {
return new ArrayList<BlockVector3>().iterator(); return Collections.emptyIterator();
} }
return new Iterator<BlockVector3>() { return new Iterator<BlockVector3>() {
Int2ObjectMap.Entry<LocalBlockVectorSet> entry = entries.next(); Int2ObjectMap.Entry<LocalBlockVectorSet> entry = entries.next();
@ -182,7 +175,7 @@ public class BlockVectorSet extends AbstractCollection<BlockVector3> implements
} }
@Override @Override
public boolean retainAll(Collection<?> c) { public boolean retainAll(@NotNull Collection<?> c) {
Objects.requireNonNull(c); Objects.requireNonNull(c);
boolean modified = false; boolean modified = false;
Iterator it = iterator(); Iterator it = iterator();

View File

@ -6,6 +6,7 @@ import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
public class HeightBoundExtent extends FaweRegionExtent { public class HeightBoundExtent extends FaweRegionExtent {
@ -35,6 +36,6 @@ public class HeightBoundExtent extends FaweRegionExtent {
@Override @Override
public Collection<Region> getRegions() { public Collection<Region> getRegions() {
return Arrays.asList(new RegionWrapper(Integer.MIN_VALUE, Integer.MAX_VALUE, min, max, Integer.MIN_VALUE, Integer.MAX_VALUE)); return Collections.singletonList(new RegionWrapper(Integer.MIN_VALUE, Integer.MAX_VALUE, min, max, Integer.MIN_VALUE, Integer.MAX_VALUE));
} }
} }

View File

@ -5,6 +5,7 @@ import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
public class SingleRegionExtent extends FaweRegionExtent { public class SingleRegionExtent extends FaweRegionExtent {
@ -32,6 +33,6 @@ public class SingleRegionExtent extends FaweRegionExtent {
@Override @Override
public Collection<Region> getRegions() { public Collection<Region> getRegions() {
return Arrays.asList(region); return Collections.singletonList(region);
} }
} }

View File

@ -103,7 +103,7 @@ public abstract class DFSVisitor implements Operation {
BlockVector3 bv2 = BlockVector3.at(from.getX() + direction.x, from.getY() + direction.y, from.getZ() + direction.z); BlockVector3 bv2 = BlockVector3.at(from.getX() + direction.x, from.getY() + direction.y, from.getZ() + direction.z);
if (isVisitable(bv, bv2)) { if (isVisitable(bv, bv2)) {
adjacent = new Node(bv2.getBlockX(), bv2.getBlockY(), bv2.getBlockZ()); adjacent = new Node(bv2.getBlockX(), bv2.getBlockY(), bv2.getBlockZ());
if ((current.from == null || !adjacent.equals(current.from))) { if ((!adjacent.equals(current.from))) {
AtomicInteger adjacentCount = visited.get(adjacent); AtomicInteger adjacentCount = visited.get(adjacent);
if (adjacentCount == null) { if (adjacentCount == null) {
if (countAdd++ < maxBranch) { if (countAdd++ < maxBranch) {

View File

@ -8,6 +8,7 @@ import com.boydti.fawe.util.ExtentTraverser;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import org.jetbrains.annotations.NotNull;
import java.util.Iterator; import java.util.Iterator;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -27,18 +28,19 @@ public class FastChunkIterator implements Iterable<BlockVector2> {
} }
public FastChunkIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable HasFaweQueue editSession) { public FastChunkIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable HasFaweQueue editSession) {
this(iter, (FaweQueue) (editSession != null ? editSession.getQueue() : null)); this(iter, editSession != null ? editSession.getQueue() : null);
} }
public FastChunkIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable FaweQueue faweQueue) { public FastChunkIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable FaweQueue faweQueue) {
this.iterable = iter; this.iterable = iter;
this.queue = faweQueue != null && faweQueue instanceof MappedFaweQueue ? (MappedFaweQueue) faweQueue : null; this.queue = faweQueue instanceof MappedFaweQueue ? (MappedFaweQueue) faweQueue : null;
} }
public Iterable<? extends BlockVector2> getIterable() { public Iterable<? extends BlockVector2> getIterable() {
return iterable; return iterable;
} }
@NotNull
@Override @Override
public Iterator<BlockVector2> iterator() { public Iterator<BlockVector2> iterator() {
if (queue == null || Settings.IMP.QUEUE.PRELOAD_CHUNKS <= 1) { if (queue == null || Settings.IMP.QUEUE.PRELOAD_CHUNKS <= 1) {

View File

@ -44,9 +44,7 @@ public class FaweChunkManager extends ChunkManager {
@Override @Override
public void swap(final Location pos1, final Location pos2, final Location pos3, final Location pos4, final Runnable whenDone) { public void swap(final Location pos1, final Location pos2, final Location pos3, final Location pos4, final Runnable whenDone) {
TaskManager.IMP.async(new Runnable() { TaskManager.IMP.async(() -> {
@Override
public void run() {
synchronized (FaweChunkManager.class) { synchronized (FaweChunkManager.class) {
EditSession sessionA = new EditSessionBuilder(pos1.getWorld()).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build(); EditSession sessionA = new EditSessionBuilder(pos1.getWorld()).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build();
EditSession sessionB = new EditSessionBuilder(pos3.getWorld()).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build(); EditSession sessionB = new EditSessionBuilder(pos3.getWorld()).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build();
@ -64,15 +62,12 @@ public class FaweChunkManager extends ChunkManager {
} }
TaskManager.IMP.task(whenDone); TaskManager.IMP.task(whenDone);
} }
}
}); });
} }
@Override @Override
public boolean copyRegion(final Location pos1, final Location pos2, final Location pos3, final Runnable whenDone) { public boolean copyRegion(final Location pos1, final Location pos2, final Location pos3, final Runnable whenDone) {
TaskManager.IMP.async(new Runnable() { TaskManager.IMP.async(() -> {
@Override
public void run() {
synchronized (FaweChunkManager.class) { synchronized (FaweChunkManager.class) {
EditSession from = new EditSessionBuilder(pos1.getWorld()).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build(); EditSession from = new EditSessionBuilder(pos1.getWorld()).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build();
EditSession to = new EditSessionBuilder(pos3.getWorld()).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build(); EditSession to = new EditSessionBuilder(pos3.getWorld()).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build();
@ -86,16 +81,13 @@ public class FaweChunkManager extends ChunkManager {
} }
} }
TaskManager.IMP.task(whenDone); TaskManager.IMP.task(whenDone);
}
}); });
return true; return true;
} }
@Override @Override
public boolean regenerateRegion(final Location pos1, final Location pos2, boolean ignore, final Runnable whenDone) { public boolean regenerateRegion(final Location pos1, final Location pos2, boolean ignore, final Runnable whenDone) {
TaskManager.IMP.async(new Runnable() { TaskManager.IMP.async(() -> {
@Override
public void run() {
synchronized (FaweChunkManager.class) { synchronized (FaweChunkManager.class) {
EditSession editSession = new EditSessionBuilder(pos1.getWorld()).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build(); EditSession editSession = new EditSessionBuilder(pos1.getWorld()).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build();
World world = editSession.getWorld(); World world = editSession.getWorld();
@ -104,7 +96,6 @@ public class FaweChunkManager extends ChunkManager {
editSession.flushQueue(); editSession.flushQueue();
TaskManager.IMP.task(whenDone); TaskManager.IMP.task(whenDone);
} }
}
}); });
return true; return true;
} }

View File

@ -1,11 +1,8 @@
package com.boydti.fawe.regions.general.plot; package com.boydti.fawe.regions.general.plot;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.FaweOutputStream;
import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.clipboard.ReadOnlyClipboard; import com.boydti.fawe.object.clipboard.ReadOnlyClipboard;
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
import com.boydti.fawe.object.io.FastByteArraysInputStream;
import com.boydti.fawe.object.io.PGZIPOutputStream; import com.boydti.fawe.object.io.PGZIPOutputStream;
import com.boydti.fawe.util.EditSessionBuilder; import com.boydti.fawe.util.EditSessionBuilder;
import com.boydti.fawe.util.IOUtil; import com.boydti.fawe.util.IOUtil;
@ -22,15 +19,12 @@ import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.CompressedCompoundTag; import com.sk89q.jnbt.CompressedCompoundTag;
import com.sk89q.jnbt.CompressedSchematicTag; import com.sk89q.jnbt.CompressedSchematicTag;
import com.sk89q.jnbt.NBTOutputStream; import com.sk89q.jnbt.NBTOutputStream;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicWriter; import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicWriter;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import net.jpountz.lz4.LZ4BlockInputStream;
import net.jpountz.lz4.LZ4BlockOutputStream;
import java.io.BufferedOutputStream; import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -45,7 +39,6 @@ import java.net.URL;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.zip.GZIPInputStream;
public class FaweSchematicHandler extends SchematicHandler { public class FaweSchematicHandler extends SchematicHandler {
@Override @Override
@ -62,9 +55,7 @@ public class FaweSchematicHandler extends SchematicHandler {
@Override @Override
public void getCompoundTag(final String world, final Set<RegionWrapper> regions, final RunnableVal<CompoundTag> whenDone) { public void getCompoundTag(final String world, final Set<RegionWrapper> regions, final RunnableVal<CompoundTag> whenDone) {
TaskManager.IMP.async(new Runnable() { TaskManager.IMP.async(() -> {
@Override
public void run() {
Location[] corners = MainUtil.getCorners(world, regions); Location[] corners = MainUtil.getCorners(world, regions);
Location pos1 = corners[0]; Location pos1 = corners[0];
Location pos2 = corners[1]; Location pos2 = corners[1];
@ -80,7 +71,6 @@ public class FaweSchematicHandler extends SchematicHandler {
Clipboard holder = new BlockArrayClipboard(region, clipboard); Clipboard holder = new BlockArrayClipboard(region, clipboard);
CompressedSchematicTag tag = new CompressedSchematicTag(holder); CompressedSchematicTag tag = new CompressedSchematicTag(holder);
whenDone.run(tag); whenDone.run(tag);
}
}); });
} }
@ -109,7 +99,7 @@ public class FaweSchematicHandler extends SchematicHandler {
} else { } else {
try (OutputStream stream = new FileOutputStream(tmp); NBTOutputStream output = new NBTOutputStream(new PGZIPOutputStream(stream))) { try (OutputStream stream = new FileOutputStream(tmp); NBTOutputStream output = new NBTOutputStream(new PGZIPOutputStream(stream))) {
Map<String, com.sk89q.jnbt.Tag> map = tag.getValue(); Map<String, com.sk89q.jnbt.Tag> map = tag.getValue();
output.writeNamedTag("Schematic", map.containsKey("Schematic") ? map.get("Schematic") : tag); output.writeNamedTag("Schematic", map.getOrDefault("Schematic", tag));
} }
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
@ -136,7 +126,7 @@ public class FaweSchematicHandler extends SchematicHandler {
com.sk89q.jnbt.CompoundTag weTag = (com.sk89q.jnbt.CompoundTag) FaweCache.asTag(tag); com.sk89q.jnbt.CompoundTag weTag = (com.sk89q.jnbt.CompoundTag) FaweCache.asTag(tag);
try (NBTOutputStream nos = new NBTOutputStream(gzip)) { try (NBTOutputStream nos = new NBTOutputStream(gzip)) {
Map<String, com.sk89q.jnbt.Tag> map = weTag.getValue(); Map<String, com.sk89q.jnbt.Tag> map = weTag.getValue();
nos.writeNamedTag("Schematic", map.containsKey("Schematic") ? map.get("Schematic") : weTag); nos.writeNamedTag("Schematic", map.getOrDefault("Schematic", weTag));
} }
} }
} catch (IOException e) { } catch (IOException e) {

View File

@ -88,8 +88,7 @@ public class PlotTrim {
return false; return false;
} }
}); });
ArrayList<Plot> plots = new ArrayList<>(); ArrayList<Plot> plots = new ArrayList<>(PlotSquared.get().getPlots(area));
plots.addAll(PlotSquared.get().getPlots(area));
if (ExpireManager.IMP != null) { if (ExpireManager.IMP != null) {
plots.removeAll(ExpireManager.IMP.getPendingExpired()); plots.removeAll(ExpireManager.IMP.getPendingExpired());
} }

View File

@ -50,13 +50,11 @@ public final class BrushCache {
tool.setHolder(item); tool.setHolder(item);
brushCache.put(key, tool); brushCache.put(key, tool);
return tool; return tool;
} catch (Throwable ignore) { } catch (Exception throwable) {
ignore.printStackTrace(); throwable.printStackTrace();
Fawe.debug("Invalid brush for " + player + " holding " + item.getType() + ": " + json.getValue()); Fawe.debug("Invalid brush for " + player + " holding " + item.getType() + ": " + json.getValue());
if (item != null) {
item.setNbtData(null); item.setNbtData(null);
brushCache.remove(key); brushCache.remove(key);
}
} finally { } finally {
RECURSION.remove(); RECURSION.remove();
} }

View File

@ -77,7 +77,7 @@ public class CachedMathMan {
add = 0.0f; add = 0.0f;
} }
float invDiv = 1.0f / (((x < y) ? y : x) * INV_ATAN2_DIM_MINUS_1); float invDiv = 1.0f / ((Math.max(x, y)) * INV_ATAN2_DIM_MINUS_1);
int xi = (int) (x * invDiv); int xi = (int) (x * invDiv);
int yi = (int) (y * invDiv); int yi = (int) (y * invDiv);

View File

@ -26,7 +26,7 @@ public class ColorUtil {
: Float.parseFloat(color)); : Float.parseFloat(color));
switch (type) { switch (type) {
case PARSE_ALPHA: case PARSE_ALPHA:
return (c < 0f) ? 0f : ((c > 1f) ? 1f : c); return (c < 0f) ? 0f : (Math.min(c, 1f));
case PARSE_PERCENT: case PARSE_PERCENT:
return (c <= 0f) ? 0f : ((c >= 100f) ? 1f : (c / 100f)); return (c <= 0f) ? 0f : ((c >= 100f) ? 1f : (c / 100f));
case PARSE_COMPONENT: case PARSE_COMPONENT:

View File

@ -54,7 +54,7 @@ public class EditSessionBuilder {
public EditSessionBuilder(@Nonnull World world) { public EditSessionBuilder(@Nonnull World world) {
checkNotNull(world); checkNotNull(world);
this.world = world; this.world = world;
this.worldName = Fawe.imp().getWorldName(world); this.worldName = world.getName();
} }
public EditSessionBuilder(@Nonnull String worldName) { public EditSessionBuilder(@Nonnull String worldName) {

View File

@ -81,11 +81,11 @@ public class MathMan {
} }
public static int clamp(int check, int min, int max) { public static int clamp(int check, int min, int max) {
return check > max ? max : (check < min ? min : check); return check > max ? max : (Math.max(check, min));
} }
public static float clamp(float check, float min, float max) { public static float clamp(float check, float min, float max) {
return check > max ? max : (check < min ? min : check); return check > max ? max : (Math.max(check, min));
} }
public static double hypot(final double... pars) { public static double hypot(final double... pars) {
@ -104,7 +104,7 @@ public class MathMan {
return sum; return sum;
} }
public static final int wrap(int value, int min, int max) { public static int wrap(int value, int min, int max) {
if (max < min) { if (max < min) {
return value; return value;
} }

View File

@ -7,11 +7,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import sun.reflect.ConstructorAccessor; import sun.reflect.ConstructorAccessor;
import sun.reflect.FieldAccessor; import sun.reflect.FieldAccessor;
@ -126,7 +122,7 @@ public class ReflectionUtils {
Class<?>[] additionalTypes, Object[] additionalValues) throws Exception { Class<?>[] additionalTypes, Object[] additionalValues) throws Exception {
Object[] parms = new Object[additionalValues.length + 2]; Object[] parms = new Object[additionalValues.length + 2];
parms[0] = value; parms[0] = value;
parms[1] = Integer.valueOf(ordinal); parms[1] = ordinal;
System.arraycopy(additionalValues, 0, parms, 2, additionalValues.length); System.arraycopy(additionalValues, 0, parms, 2, additionalValues.length);
return enumClass.cast(getConstructorAccessor(enumClass, additionalTypes).newInstance(parms)); return enumClass.cast(getConstructorAccessor(enumClass, additionalTypes).newInstance(parms));
} }
@ -332,12 +328,12 @@ public class ReflectionUtils {
} }
public static Method[] sortMethods(Method[] methods) { public static Method[] sortMethods(Method[] methods) {
Arrays.sort(methods, (o1, o2) -> o1.getName().compareTo(o2.getName())); Arrays.sort(methods, Comparator.comparing(Method::getName));
return methods; return methods;
} }
public static Field[] sortFields(Field[] fields) { public static Field[] sortFields(Field[] fields) {
Arrays.sort(fields, (o1, o2) -> o1.getName().compareTo(o2.getName())); Arrays.sort(fields, Comparator.comparing(Field::getName));
return fields; return fields;
} }

View File

@ -293,15 +293,14 @@ public class GenerationCommands extends MethodCommands {
@Command( @Command(
aliases = {"pumpkins"}, aliases = {"pumpkins"},
usage = "[size=10] [density=0.02]", usage = "[size=10]",
desc = "Generate pumpkin patches", desc = "Generate pumpkin patches",
min = 0,
max = 2 max = 2
) )
@CommandPermissions("worldedit.generation.pumpkins") @CommandPermissions("worldedit.generation.pumpkins")
@Logging(POSITION) @Logging(POSITION)
public void pumpkins(Player player, LocalSession session, EditSession editSession, @Optional("10") int apothem, @Optional("0.02") double density) throws WorldEditException, ParameterException { public void pumpkins(Player player, LocalSession session, EditSession editSession, @Optional("10") int apothem) throws WorldEditException, ParameterException {
int affected = editSession.makePumpkinPatches(session.getPlacementPosition(player), apothem, density); int affected = editSession.makePumpkinPatches(session.getPlacementPosition(player), apothem);
BBC.COMMAND_PUMPKIN.send(player, affected); BBC.COMMAND_PUMPKIN.send(player, affected);
} }

View File

@ -9,22 +9,18 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.platform.CommandManager; import com.sk89q.worldedit.extension.platform.CommandManager;
import com.sk89q.worldedit.util.command.*; import com.sk89q.worldedit.util.command.*;
import com.sk89q.worldedit.util.command.parametric.AParametricCallable; import com.sk89q.worldedit.util.command.parametric.AParametricCallable;
import org.jetbrains.annotations.NotNull;
import java.util.*; import java.util.*;
public abstract class HelpBuilder implements Runnable { public abstract class HelpBuilder implements Runnable {
private final CommandCallable callable; private final CommandCallable callable;
private final CommandContext args; private final CommandContext args;
private final String prefix;
private final int perPage; private final int perPage;
public HelpBuilder(CommandCallable callable, CommandContext args, final String prefix, int perPage) { HelpBuilder(@NotNull CommandCallable callable, CommandContext args, int perPage) {
if (callable == null) {
callable = WorldEdit.getInstance().getPlatformManager().getCommandManager().getDispatcher();
}
this.callable = callable; this.callable = callable;
this.args = args; this.args = args;
this.prefix = prefix;
this.perPage = perPage; this.perPage = perPage;
} }
@ -33,7 +29,6 @@ public abstract class HelpBuilder implements Runnable {
try { try {
CommandCallable callable = this.callable; CommandCallable callable = this.callable;
int page = -1; int page = -1;
String category = null;
int effectiveLength = args.argsLength(); int effectiveLength = args.argsLength();
// Detect page from args // Detect page from args
@ -84,11 +79,7 @@ public abstract class HelpBuilder implements Runnable {
} }
group = group.replace("/", ""); group = group.replace("/", "");
group = StringMan.toProperCase(group); group = StringMan.toProperCase(group);
Map<CommandMapping, String> queue = grouped.get(group); Map<CommandMapping, String> queue = grouped.computeIfAbsent(group, k -> new LinkedHashMap<>());
if (queue == null) {
queue = new LinkedHashMap<>();
grouped.put(group, queue);
}
if (c instanceof Dispatcher) { if (c instanceof Dispatcher) {
for (CommandMapping m : ((Dispatcher) c).getCommands()) { for (CommandMapping m : ((Dispatcher) c).getCommands()) {
queue.put(m, mapping.getPrimaryAlias() + " "); queue.put(m, mapping.getPrimaryAlias() + " ");
@ -190,9 +181,7 @@ public abstract class HelpBuilder implements Runnable {
return; return;
} }
} }
// else aliases.sort(new PrimaryAliasComparator(CommandManager.COMMAND_CLEAN_PATTERN));
{
Collections.sort(aliases, new PrimaryAliasComparator(CommandManager.COMMAND_CLEAN_PATTERN));
// Calculate pagination // Calculate pagination
int offset = perPage * Math.max(0, page); int offset = perPage * Math.max(0, page);
@ -212,7 +201,6 @@ public abstract class HelpBuilder implements Runnable {
String visitedString = Joiner.on(" ").join(visited); String visitedString = Joiner.on(" ").join(visited);
displayCommands(commandMap, visitedString, page, pageTotal, effectiveLength); displayCommands(commandMap, visitedString, page, pageTotal, effectiveLength);
} }
}
} else { } else {
String cmd = (WorldEdit.getInstance().getConfiguration().noDoubleSlash ? "" : "/") + Joiner.on(" ").join(visited); String cmd = (WorldEdit.getInstance().getConfiguration().noDoubleSlash ? "" : "/") + Joiner.on(" ").join(visited);
displayUsage(callable, cmd); displayUsage(callable, cmd);

View File

@ -53,14 +53,11 @@ import com.sk89q.worldedit.command.util.CreatureButcher;
import com.sk89q.worldedit.command.util.EntityRemover; import com.sk89q.worldedit.command.util.EntityRemover;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.extension.factory.DefaultTransformParser; import com.sk89q.worldedit.extension.factory.DefaultTransformParser;
import com.sk89q.worldedit.extension.factory.parser.mask.DefaultMaskParser; import com.sk89q.worldedit.extension.factory.parser.mask.DefaultMaskParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.ClipboardPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.DefaultPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.DefaultPatternParser;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.CommandManager;
import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
@ -78,16 +75,12 @@ import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.CylinderRegion; import com.sk89q.worldedit.regions.CylinderRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.command.binding.Range; import com.sk89q.worldedit.util.command.binding.Range;
import com.sk89q.worldedit.session.SessionOwner;
import com.sk89q.worldedit.util.command.CommandCallable; import com.sk89q.worldedit.util.command.CommandCallable;
import com.sk89q.worldedit.util.command.CommandMapping; import com.sk89q.worldedit.util.command.CommandMapping;
import com.sk89q.worldedit.util.command.Dispatcher; import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.util.command.PrimaryAliasComparator;
import com.sk89q.worldedit.util.command.binding.Text; import com.sk89q.worldedit.util.command.binding.Text;
import com.sk89q.worldedit.util.command.parametric.Optional; import com.sk89q.worldedit.util.command.parametric.Optional;
import com.sk89q.worldedit.util.command.parametric.ParameterData;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
@ -96,7 +89,6 @@ import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.FileFilter; import java.io.FileFilter;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URI; import java.net.URI;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.*; import java.util.*;
@ -105,9 +97,6 @@ import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer; import java.util.function.Consumer;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT;
/** /**
* Utility commands. * Utility commands.
*/ */
@ -460,7 +449,7 @@ public class UtilityCommands extends MethodCommands {
we.checkMaxRadius(size); we.checkMaxRadius(size);
final boolean onlyNormalDirt = !args.hasFlag('f'); final boolean onlyNormalDirt = !args.hasFlag('f');
final int affected = editSession.green(session.getPlacementPosition(player), size); final int affected = editSession.green(session.getPlacementPosition(player), size, onlyNormalDirt);
BBC.VISITOR_BLOCK.send(player, affected); BBC.VISITOR_BLOCK.send(player, affected);
} }
@ -997,13 +986,13 @@ public class UtilityCommands extends MethodCommands {
} }
public static void help(CommandContext args, WorldEdit we, Actor actor) { public static void help(CommandContext args, WorldEdit we, Actor actor) {
help(args, we, actor, "/", null); help(args, we, actor, "/", we.getPlatformManager().getCommandManager().getDispatcher());
} }
public static void help(CommandContext args, WorldEdit we, Actor actor, String prefix, CommandCallable callable) { public static void help(CommandContext args, WorldEdit we, Actor actor, String prefix, CommandCallable callable) {
final int perPage = actor instanceof Player ? 12 : 20; // More pages for console final int perPage = actor instanceof Player ? 12 : 20; // More pages for console
HelpBuilder builder = new HelpBuilder(callable, args, prefix, perPage) { HelpBuilder builder = new HelpBuilder(callable, args, perPage) {
@Override @Override
public void displayFailure(String message) { public void displayFailure(String message) {
actor.printError(message); actor.printError(message);
@ -1023,7 +1012,7 @@ public class UtilityCommands extends MethodCommands {
String s1 = Commands.getAlias(UtilityCommands.class, "/help") + " " + entry.getKey(); String s1 = Commands.getAlias(UtilityCommands.class, "/help") + " " + entry.getKey();
String s2 = entry.getValue().size() + ""; String s2 = entry.getValue().size() + "";
msg.text(BBC.HELP_ITEM_ALLOWED, "&a" + s1, s2); msg.text(BBC.HELP_ITEM_ALLOWED, "&a" + s1, s2);
msg.tooltip(StringMan.join(entry.getValue().keySet(), ", ", cm -> cm.getPrimaryAlias())); msg.tooltip(StringMan.join(entry.getValue().keySet(), ", ", CommandMapping::getPrimaryAlias));
msg.command(s1); msg.command(s1);
msg.newline(); msg.newline();
} }

View File

@ -20,11 +20,7 @@
package com.sk89q.worldedit.command.composition; package com.sk89q.worldedit.command.composition;
import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.*;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.extent.FaweRegionExtent; import com.boydti.fawe.object.extent.FaweRegionExtent;
import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MainUtil;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
@ -36,8 +32,6 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException; import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.function.Contextual; import com.sk89q.worldedit.function.Contextual;
@ -53,14 +47,11 @@ import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.command.argument.CommandArgs; import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.composition.CommandExecutor; import com.sk89q.worldedit.util.command.composition.CommandExecutor;
import com.sk89q.worldedit.util.command.composition.SimpleCommand; import com.sk89q.worldedit.util.command.composition.SimpleCommand;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.List; import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
public class SelectionCommand extends SimpleCommand<Operation> { public class SelectionCommand extends SimpleCommand<Operation> {

View File

@ -82,7 +82,7 @@ public class ShapedBrushCommand extends SimpleCommand<Object> {
WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter().convert(e); WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter().convert(e);
} }
player.print(BBC.getPrefix() + "Set brush to " + factory); player.print("Set brush to " + factory);
return true; return true;
} }

View File

@ -37,7 +37,7 @@ public class CylinderBrush implements Brush {
@Override @Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException { public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
if (pattern == null) { if (pattern == null) {
pattern = (BlockTypes.COBBLESTONE.getDefaultState()); pattern = new BlockPattern(BlockTypes.COBBLESTONE.getDefaultState());
} }
editSession.makeCylinder(position, pattern, size, size, height, true); editSession.makeCylinder(position, pattern, size, size, height, true);
} }

View File

@ -192,7 +192,8 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
state = LegacyMapper.getInstance().getBlockFromLegacy(type.getLegacyCombinedId() >> 4, data); state = LegacyMapper.getInstance().getBlockFromLegacy(type.getLegacyCombinedId() >> 4, data);
} }
} }
} catch (NumberFormatException ignore) {} } catch (NumberFormatException e) {
}
} }
if (state == null) { if (state == null) {
@ -220,10 +221,10 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
throw new InputParseException("Your selection is not complete."); throw new InputParseException("Your selection is not complete.");
} }
state = world.getBlock(primaryPosition); state = world.getBlock(primaryPosition);
} else if (typeString.equalsIgnoreCase("hand")) { } else if ("hand".equalsIgnoreCase(typeString)) {
// Get the block type from the item in the user's hand. // Get the block type from the item in the user's hand.
state = getBlockInHand(context.requireActor(), HandSide.MAIN_HAND); state = getBlockInHand(context.requireActor(), HandSide.MAIN_HAND);
} else if (typeString.equalsIgnoreCase("offhand")) { } else if ("offhand".equalsIgnoreCase(typeString)) {
// Get the block type from the item in the user's off hand. // Get the block type from the item in the user's off hand.
state = getBlockInHand(context.requireActor(), HandSide.OFF_HAND); state = getBlockInHand(context.requireActor(), HandSide.OFF_HAND);
} else if (typeString.matches("slot[0-9]+")) { } else if (typeString.matches("slot[0-9]+")) {
@ -241,7 +242,7 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
BaseItem item = slottable.getItem(slot); BaseItem item = slottable.getItem(slot);
if (!item.getType().hasBlockType()) { if (!item.getType().hasBlockType()) {
throw new InputParseException(BBC.getPrefix() + "You're not holding a block!"); throw new InputParseException("You're not holding a block!");
} }
state = item.getType().getBlockType().getDefaultState(); state = item.getType().getBlockType().getDefaultState();
nbt = item.getNbtData(); nbt = item.getNbtData();
@ -249,7 +250,7 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
BlockType type = BlockTypes.parse(typeString.toLowerCase()); BlockType type = BlockTypes.parse(typeString.toLowerCase());
if (type != null) state = type.getDefaultState(); if (type != null) state = type.getDefaultState();
if (state == null) { if (state == null) {
throw new NoMatchException(BBC.getPrefix() + "Does not match a valid block type: '" + input + "'"); throw new NoMatchException("Does not match a valid block type: '" + input + "'");
} }
} }
if (nbt == null) nbt = state.getNbtData(); if (nbt == null) nbt = state.getNbtData();
@ -309,10 +310,9 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
break; break;
} }
} }
Platform capability = worldEdit.getPlatformManager().queryCapability(Capability.USER_COMMANDS); if (!worldEdit.getPlatformManager().queryCapability(Capability.USER_COMMANDS).isValidMobType(mobName)) {
if (!capability.isValidMobType(mobName)) {
final String finalMobName = mobName.toLowerCase(); final String finalMobName = mobName.toLowerCase();
throw new SuggestInputParseException(BBC.getPrefix() + "Unknown mob type '" + mobName + "'", mobName, () -> Stream.of(MobType.values()) throw new SuggestInputParseException("Unknown mob type '" + mobName + "'", mobName, () -> Stream.of(MobType.values())
.map(m -> m.getName().toLowerCase()) .map(m -> m.getName().toLowerCase())
.filter(s -> s.startsWith(finalMobName)) .filter(s -> s.startsWith(finalMobName))
.collect(Collectors.toList())); .collect(Collectors.toList()));

View File

@ -170,10 +170,8 @@ public final class CommandManager {
builder.setAuthorizer(new ActorAuthorizer()); builder.setAuthorizer(new ActorAuthorizer());
builder.setDefaultCompleter(new UserCommandCompleter(platformManager)); builder.setDefaultCompleter(new UserCommandCompleter(platformManager));
builder.addBinding(new WorldEditBinding(worldEdit)); builder.addBinding(new WorldEditBinding(worldEdit));
builder.addBinding(new PatternBinding(worldEdit), com.sk89q.worldedit.function.pattern.Pattern.class); builder.addBinding(new PatternBinding(worldEdit), com.sk89q.worldedit.function.pattern.Pattern.class);
builder.addBinding(new MaskBinding(worldEdit), com.sk89q.worldedit.function.mask.Mask.class); builder.addBinding(new MaskBinding(worldEdit), com.sk89q.worldedit.function.mask.Mask.class);
builder.addInvokeListener(new LegacyCommandsHandler()); builder.addInvokeListener(new LegacyCommandsHandler());
builder.addInvokeListener(new CommandLoggingHandler(worldEdit, commandLog)); builder.addInvokeListener(new CommandLoggingHandler(worldEdit, commandLog));
@ -371,7 +369,7 @@ public final class CommandManager {
setupDispatcher(); setupDispatcher();
} }
public void unregister() { void unregister() {
dynamicHandler.setHandler(null); dynamicHandler.setHandler(null);
} }
@ -401,8 +399,7 @@ public final class CommandManager {
public void handleCommandOnCurrentThread(CommandEvent event) { public void handleCommandOnCurrentThread(CommandEvent event) {
Actor actor = platformManager.createProxyActor(event.getActor()); Actor actor = platformManager.createProxyActor(event.getActor());
final String args = event.getArguments(); String[] split = commandDetection(event.getArguments().split(" "));
final String[] split = commandDetection(args.split(" "));
// No command found! // No command found!
if (!dispatcher.contains(split[0])) { if (!dispatcher.contains(split[0])) {
return; return;
@ -410,7 +407,7 @@ public final class CommandManager {
if (!actor.isPlayer()) { if (!actor.isPlayer()) {
actor = FakePlayer.wrap(actor.getName(), actor.getUniqueId(), actor); actor = FakePlayer.wrap(actor.getName(), actor.getUniqueId(), actor);
} }
final LocalSession session = worldEdit.getSessionManager().get(actor); LocalSession session = worldEdit.getSessionManager().get(actor);
Request.request().setSession(session); Request.request().setSession(session);
if (actor instanceof Entity) { if (actor instanceof Entity) {
Extent extent = ((Entity) actor).getExtent(); Extent extent = ((Entity) actor).getExtent();
@ -419,7 +416,8 @@ public final class CommandManager {
} }
} }
LocalConfiguration config = worldEdit.getConfiguration(); LocalConfiguration config = worldEdit.getConfiguration();
final CommandLocals locals = new CommandLocals();
CommandLocals locals = new CommandLocals();
final FawePlayer fp = FawePlayer.wrap(actor); final FawePlayer fp = FawePlayer.wrap(actor);
if (fp == null) { if (fp == null) {
throw new IllegalArgumentException("FAWE doesn't support: " + actor); throw new IllegalArgumentException("FAWE doesn't support: " + actor);
@ -430,7 +428,7 @@ public final class CommandManager {
if (actor instanceof Player) { if (actor instanceof Player) {
Player player = (Player) actor; Player player = (Player) actor;
Player unwrapped = LocationMaskedPlayerWrapper.unwrap(player); Player unwrapped = LocationMaskedPlayerWrapper.unwrap(player);
actor = new LocationMaskedPlayerWrapper((Player) unwrapped, player.getLocation(), true) { actor = new LocationMaskedPlayerWrapper(unwrapped, player.getLocation(), true) {
@Override @Override
public boolean hasPermission(String permission) { public boolean hasPermission(String permission) {
if (!super.hasPermission(permission)) { if (!super.hasPermission(permission)) {
@ -452,8 +450,7 @@ public final class CommandManager {
}; };
} }
locals.put(Actor.class, actor); locals.put(Actor.class, actor);
final Actor finalActor = actor; locals.put("arguments", event.getArguments());
locals.put("arguments", args);
ThrowableSupplier<Throwable> task = ThrowableSupplier<Throwable> task =
() -> dispatcher.call(Joiner.on(" ").join(split), locals, new String[0]); () -> dispatcher.call(Joiner.on(" ").join(split), locals, new String[0]);
@ -527,7 +524,6 @@ public final class CommandManager {
} }
} catch (Throwable e) { } catch (Throwable e) {
Exception faweException = FaweException.get(e); Exception faweException = FaweException.get(e);
String message = e.getMessage();
if (faweException != null) { if (faweException != null) {
BBC.WORLDEDIT_CANCEL_REASON.send(actor, faweException.getMessage()); BBC.WORLDEDIT_CANCEL_REASON.send(actor, faweException.getMessage());
} else { } else {
@ -541,7 +537,7 @@ public final class CommandManager {
editSession.flushQueue(); editSession.flushQueue();
worldEdit.flushBlockBag(locals.get(Actor.class), editSession); worldEdit.flushBlockBag(locals.get(Actor.class), editSession);
session.remember(editSession); session.remember(editSession);
final long time = System.currentTimeMillis() - start; long time = System.currentTimeMillis() - start;
if (time > 1000) { if (time > 1000) {
BBC.ACTION_COMPLETE.send(actor, (time / 1000d)); BBC.ACTION_COMPLETE.send(actor, (time / 1000d));
} }

View File

@ -43,8 +43,12 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BundledBlockData; import com.sk89q.worldedit.world.registry.BundledBlockData;
import java.util.List; import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
/**
* A base class for {@link Extent}s that merely passes extents onto another.
*/
public class AbstractDelegateExtent implements LightingExtent { public class AbstractDelegateExtent implements LightingExtent {
private transient final Extent extent; private transient final Extent extent;
protected MutableBlockVector3 mutable = new MutableBlockVector3(0, 0, 0); protected MutableBlockVector3 mutable = new MutableBlockVector3(0, 0, 0);
@ -264,8 +268,7 @@ public class AbstractDelegateExtent implements LightingExtent {
} }
@Override @Override
public @Nullable public @Nullable Operation commit() {
Operation commit() {
Operation ours = commitBefore(); Operation ours = commitBefore();
Operation other = null; Operation other = null;
if (extent != this) other = extent.commit(); if (extent != this) other = extent.commit();

View File

@ -40,11 +40,10 @@ import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull; import javax.annotation.Nullable;
/** /**
* Stores changes to a {@link ChangeSet}. * Stores changes to a {@link ChangeSet}.

View File

@ -30,16 +30,12 @@ import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* Requires that all mutating methods pass a given {@link Mask}. * Requires that all mutating methods pass a given {@link Mask}.
*/ */
public class MaskingExtent extends AbstractDelegateExtent { public class MaskingExtent extends AbstractDelegateExtent {
private Mask mask; private Mask mask;
// private MutableBlockVector3 mutable = new MutableBlockVector3();
/** /**
* Create a new instance. * Create a new instance.

View File

@ -34,10 +34,11 @@ import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import javax.annotation.Nullable;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import javax.annotation.Nullable;
/** /**
* An extent that returns air blocks for all blocks and does not * An extent that returns air blocks for all blocks and does not
* pass on any changes. * pass on any changes.

View File

@ -28,12 +28,6 @@ import com.boydti.fawe.object.extent.LightingExtent;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockState;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
@ -41,15 +35,18 @@ import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;
import javax.annotation.Nullable;
import java.io.Closeable; import java.io.Closeable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -63,9 +60,6 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
private BlockVector3 origin; private BlockVector3 origin;
public FaweClipboard IMP; public FaweClipboard IMP;
private BlockVector3 size; private BlockVector3 size;
private int mx;
private int my;
private int mz;
private BlockStateHolder[][][] blocks; private BlockStateHolder[][][] blocks;
private final List<ClipboardEntity> entities = new ArrayList<>(); private final List<ClipboardEntity> entities = new ArrayList<>();
@ -75,15 +69,12 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
this.size = getDimensions(); this.size = getDimensions();
this.IMP = Settings.IMP.CLIPBOARD.USE_DISK ? new DiskOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ()) : new MemoryOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ()); this.IMP = Settings.IMP.CLIPBOARD.USE_DISK ? new DiskOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ()) : new MemoryOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ());
this.origin = region.getMinimumPoint(); this.origin = region.getMinimumPoint();
this.mx = origin.getBlockX();
this.my = origin.getBlockY();
this.mz = origin.getBlockZ();
this.blocks = new BlockStateHolder[size.getBlockX()][size.getBlockY()][size.getBlockZ()]; this.blocks = new BlockStateHolder[size.getBlockX()][size.getBlockY()][size.getBlockZ()];
} }
/** /**
* Create a new instance. * Create a new instance.
* <p> *
* <p>The origin will be placed at the region's lowest minimum point.</p> * <p>The origin will be placed at the region's lowest minimum point.</p>
* *
* @param region the bounding region * @param region the bounding region
@ -94,9 +85,6 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
this.size = getDimensions(); this.size = getDimensions();
this.IMP = Settings.IMP.CLIPBOARD.USE_DISK ? new DiskOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ(), clipboardId) : new MemoryOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ()); this.IMP = Settings.IMP.CLIPBOARD.USE_DISK ? new DiskOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ(), clipboardId) : new MemoryOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ());
this.origin = region.getMinimumPoint(); this.origin = region.getMinimumPoint();
this.mx = origin.getBlockX();
this.my = origin.getBlockY();
this.mz = origin.getBlockZ();
this.blocks = new BlockStateHolder[size.getBlockX()][size.getBlockY()][size.getBlockZ()]; this.blocks = new BlockStateHolder[size.getBlockX()][size.getBlockY()][size.getBlockZ()];
} }
@ -105,9 +93,6 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
this.region = region.clone(); this.region = region.clone();
this.size = getDimensions(); this.size = getDimensions();
this.origin = region.getMinimumPoint(); this.origin = region.getMinimumPoint();
this.mx = origin.getBlockX();
this.my = origin.getBlockY();
this.mz = origin.getBlockZ();
this.IMP = clipboard; this.IMP = clipboard;
this.blocks = new BlockStateHolder[size.getBlockX()][size.getBlockY()][size.getBlockZ()]; this.blocks = new BlockStateHolder[size.getBlockX()][size.getBlockY()][size.getBlockZ()];
} }
@ -119,9 +104,6 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
this.size = getDimensions(); this.size = getDimensions();
this.IMP = fc; this.IMP = fc;
this.origin = region.getMinimumPoint(); this.origin = region.getMinimumPoint();
this.mx = origin.getBlockX();
this.my = origin.getBlockY();
this.mz = origin.getBlockZ();
this.blocks = new BlockStateHolder[size.getBlockX()][size.getBlockY()][size.getBlockZ()]; this.blocks = new BlockStateHolder[size.getBlockX()][size.getBlockY()][size.getBlockZ()];
} }
@ -196,12 +178,11 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
@Override @Override
public BlockState getBlock(BlockVector3 position) { public BlockState getBlock(BlockVector3 position) {
if (region.contains(position)) { if (region.contains(position)) {
int x = position.getBlockX() - mx; BlockVector3 v = position.subtract(region.getMinimumPoint());
int y = position.getBlockY() - my; return IMP.getBlock(v.getX(),v.getY(),v.getZ()).toImmutableState();
int z = position.getBlockZ() - mz;
return IMP.getBlock(x, y, z).toImmutableState();
} }
return EditSession.nullBlock;
return BlockTypes.AIR.getDefaultState();
} }
public BlockState getBlockAbs(int x, int y, int z) { public BlockState getBlockAbs(int x, int y, int z) {
@ -216,12 +197,11 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
@Override @Override
public BaseBlock getFullBlock(BlockVector3 position) { public BaseBlock getFullBlock(BlockVector3 position) {
if (region.contains(position)) { if (region.contains(position)) {
int x = position.getBlockX() - mx; BlockVector3 v = position.subtract(region.getMinimumPoint());
int y = position.getBlockY() - my; return IMP.getBlock(v.getX(),v.getY(),v.getZ());
int z = position.getBlockZ() - mz;
return IMP.getBlock(x, y, z);
} }
return EditSession.nullBlock.toBaseBlock();
return BlockTypes.AIR.getDefaultState().toBaseBlock();
} }
@Override @Override
@ -235,33 +215,28 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
return false; return false;
} }
public boolean setTile(int x, int y, int z, CompoundTag tag) { public boolean setTile(BlockVector3 position, CompoundTag tag) {
x -= mx; BlockVector3 v = position.subtract(region.getMinimumPoint());
y -= my; return IMP.setTile(v.getX(), v.getY(), v.getZ(), tag);
z -= mz;
return IMP.setTile(x, y, z, tag);
} }
@Override @Override
public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) throws WorldEditException { public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) throws WorldEditException {
x -= mx; BlockVector3 position = BlockVector3.at(x, y, z);
y -= my; BlockVector3 v = position.subtract(region.getMinimumPoint());
z -= mz; return IMP.setBlock(v.getX(), v.getY(), v.getZ(), block);
return IMP.setBlock(x, y, z, block);
} }
@Override @Override
public BiomeType getBiome(BlockVector2 position) { public BiomeType getBiome(BlockVector2 position) {
int x = position.getBlockX() - mx; BlockVector2 v = position.subtract(region.getMinimumPoint().toBlockVector2());
int z = position.getBlockZ() - mz; return IMP.getBiome(v.getX(), v.getZ());
return IMP.getBiome(x, z);
} }
@Override @Override
public boolean setBiome(BlockVector2 position, BiomeType biome) { public boolean setBiome(BlockVector2 position, BiomeType biome) {
int x = position.getBlockX() - mx; BlockVector2 v = position.subtract(region.getMinimumPoint().toBlockVector2());
int z = position.getBlockZ() - mz; IMP.setBiome(v.getX(), v.getZ(), biome);
IMP.setBiome(x, z, biome);
return true; return true;
} }

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.extent.clipboard; package com.sk89q.worldedit.extent.clipboard;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
@ -58,4 +59,15 @@ public interface Clipboard extends Extent {
*/ */
void setOrigin(BlockVector3 origin); void setOrigin(BlockVector3 origin);
/**
* Returns true if the clipboard has biome data. This can be checked since {@link Extent#getBiome(BlockVector2)}
* strongly suggests returning {@link com.sk89q.worldedit.world.biome.BiomeTypes.OCEAN} instead of {@code null}
* if biomes aren't present. However, it might not be desired to set areas to ocean if the clipboard is defaulting
* to ocean, instead of having biomes explicitly set.
*
* @return true if the clipboard has biome data set
*/
default boolean hasBiomes() {
return false;
}
} }

View File

@ -1,12 +1,28 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.extent.inventory; package com.sk89q.worldedit.extent.inventory;
import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.object.exception.FaweException;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
@ -52,9 +68,7 @@ public class BlockBagExtent extends AbstractDelegateExtent {
* *
* @return a block bag, which may be null if none is used * @return a block bag, which may be null if none is used
*/ */
public public @Nullable BlockBag getBlockBag() {
@Nullable
BlockBag getBlockBag() {
return blockBag; return blockBag;
} }
@ -93,33 +107,31 @@ public class BlockBagExtent extends AbstractDelegateExtent {
@Override @Override
public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) throws WorldEditException { public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) throws WorldEditException {
if (blockBag != null) { if (blockBag != null) {
BlockStateHolder lazyBlock = getExtent().getLazyBlock(x, y, z); BlockState existing = getExtent().getBlock(BlockVector3.at(x,y,z));
BlockType fromType = lazyBlock.getBlockType();
if(!block.getBlockType().equals(fromType)) { if (!block.getBlockType().equals(existing.getBlockType())) {
BlockType type = block.getBlockType(); if (!block.getBlockType().getMaterial().isAir()) {
if (!type.getMaterial().isAir()) {
try { try {
blockBag.fetchPlacedBlock(block.toImmutableState()); blockBag.fetchPlacedBlock(block.toImmutableState());
} catch (UnplaceableBlockException e) { } catch (UnplaceableBlockException e) {
throw new FaweException.FaweBlockBagException(); throw new FaweException.FaweBlockBagException();
} catch (BlockBagException e) { } catch (BlockBagException e) {
missingBlocks[type.getInternalId()]++; missingBlocks[block.getBlockType().getInternalId()]++;
throw new FaweException.FaweBlockBagException(); throw new FaweException.FaweBlockBagException();
} }
} }
if (mine) { if (mine) {
if (!fromType.getMaterial().isAir()) { if (!existing.getBlockType().getMaterial().isAir()) {
try { try {
blockBag.storeDroppedBlock(fromType.getDefaultState()); blockBag.storeDroppedBlock(existing);
} catch (BlockBagException ignored) { } catch (BlockBagException ignored) {
} }
} }
} }
} }
} }
return getExtent().setBlock(x, y, z, block);
}
return super.setBlock(x, y, z, block);
}
} }

View File

@ -1,3 +1,22 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.extent.transform; package com.sk89q.worldedit.extent.transform;
import com.boydti.fawe.object.extent.ResettableExtent; import com.boydti.fawe.object.extent.ResettableExtent;
@ -32,6 +51,7 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.util.Direction.*; import static com.sk89q.worldedit.util.Direction.*;
public class BlockTransformExtent extends ResettableExtent { public class BlockTransformExtent extends ResettableExtent {
@ -46,8 +66,14 @@ public class BlockTransformExtent extends ResettableExtent {
this(parent, new AffineTransform()); this(parent, new AffineTransform());
} }
public BlockTransformExtent(Extent parent, Transform transform) { /**
super(parent); * Create a new instance.
*
* @param extent the extent
*/
public BlockTransformExtent(Extent extent, Transform transform) {
super(extent);
checkNotNull(transform);
this.transform = transform; this.transform = transform;
this.transformInverse = this.transform.inverse(); this.transformInverse = this.transform.inverse();
cache(); cache();
@ -134,7 +160,7 @@ public class BlockTransformExtent extends ResettableExtent {
continue; continue;
default: default:
System.out.println("Unknown direction " + value); System.out.println("Unknown direction " + value);
result.add(0l); result.add(0L);
} }
} }
return adapt(result.toArray(new Long[0])); return adapt(result.toArray(new Long[0]));
@ -174,7 +200,7 @@ public class BlockTransformExtent extends ResettableExtent {
break; break;
default: default:
System.out.println("Unknown direction " + value); System.out.println("Unknown direction " + value);
directions.add(0l); directions.add(0L);
} }
} }
return adapt(directions.toArray(new Long[0])); return adapt(directions.toArray(new Long[0]));
@ -268,7 +294,7 @@ public class BlockTransformExtent extends ResettableExtent {
} }
} }
private static final BaseBlock transformBaseBlockNBT(BlockState transformed, CompoundTag tag, Transform transform) { private static BaseBlock transformBaseBlockNBT(BlockState transformed, CompoundTag tag, Transform transform) {
if (tag != null) { if (tag != null) {
if (tag.containsKey("Rot")) { if (tag.containsKey("Rot")) {
int rot = tag.asInt("Rot"); int rot = tag.asInt("Rot");
@ -321,7 +347,7 @@ public class BlockTransformExtent extends ResettableExtent {
newMaskedId = tmp.getInternalId(); newMaskedId = tmp.getInternalId();
} }
for (AbstractProperty property : (Collection<AbstractProperty>) (Collection) type.getProperties()) { for (AbstractProperty property : (List<AbstractProperty<?>>) type.getProperties()) {
if (isDirectional(property)) { if (isDirectional(property)) {
long[] directions = getDirections(property); long[] directions = getDirections(property);
if (directions != null) { if (directions != null) {
@ -358,7 +384,6 @@ public class BlockTransformExtent extends ResettableExtent {
BLOCK_ROTATION_BITMASK = new int[BlockTypes.size()]; BLOCK_ROTATION_BITMASK = new int[BlockTypes.size()];
BLOCK_TRANSFORM = new int[BlockTypes.size()][]; BLOCK_TRANSFORM = new int[BlockTypes.size()][];
BLOCK_TRANSFORM_INVERSE = new int[BlockTypes.size()][]; BLOCK_TRANSFORM_INVERSE = new int[BlockTypes.size()][];
outer:
for (int i = 0; i < BLOCK_TRANSFORM.length; i++) { for (int i = 0; i < BLOCK_TRANSFORM.length; i++) {
BLOCK_TRANSFORM[i] = ALL; BLOCK_TRANSFORM[i] = ALL;
BLOCK_TRANSFORM_INVERSE[i] = ALL; BLOCK_TRANSFORM_INVERSE[i] = ALL;
@ -392,7 +417,7 @@ public class BlockTransformExtent extends ResettableExtent {
cache(); cache();
} }
private final BlockState transform(BlockState state, int[][] transformArray, Transform transform) { private BlockState transform(BlockState state, int[][] transformArray, Transform transform) {
int typeId = state.getInternalBlockTypeId(); int typeId = state.getInternalBlockTypeId();
int[] arr = transformArray[typeId]; int[] arr = transformArray[typeId];
if (arr == ALL) { if (arr == ALL) {

View File

@ -1,10 +1,26 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.pattern; package com.sk89q.worldedit.function.pattern;
import java.io.Serializable; /**
* An abstract implementation for {@link Pattern}s.
public abstract class AbstractPattern implements Pattern, Serializable { */
public AbstractPattern() { public abstract class AbstractPattern implements Pattern {
}
} }

View File

@ -16,6 +16,7 @@
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.function.pattern; package com.sk89q.worldedit.function.pattern;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;

View File

@ -1,3 +1,22 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.pattern; package com.sk89q.worldedit.function.pattern;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;

View File

@ -26,7 +26,6 @@ import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockState;
/** /**
* Returns a {@link BlockStateHolder} for a given position. * Returns a {@link BlockStateHolder} for a given position.
@ -34,16 +33,6 @@ import com.sk89q.worldedit.world.block.BlockState;
@Link(clazz = UtilityCommands.class, value = "patterns") @Link(clazz = UtilityCommands.class, value = "patterns")
public interface Pattern { public interface Pattern {
// @Override
// default BaseBlock next(BlockVector3 position) {
// return new BaseBlock(apply(position));
// }
//
// @Override
// default BaseBlock next(int x, int y, int z) {
// return new BaseBlock(apply(BlockVector3.at(x, y, z)));
// }
/** /**
* Return a {@link BlockStateHolder} for the given position. * Return a {@link BlockStateHolder} for the given position.
* *

View File

@ -1,3 +1,22 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.pattern; package com.sk89q.worldedit.function.pattern;
import com.boydti.fawe.object.collection.RandomCollection; import com.boydti.fawe.object.collection.RandomCollection;
@ -39,7 +58,7 @@ public class RandomPattern extends AbstractPattern {
/** /**
* Add a pattern to the weight list of patterns. * Add a pattern to the weight list of patterns.
* <p> *
* <p>The probability for the pattern added is chance / max where max is * <p>The probability for the pattern added is chance / max where max is
* the sum of the probabilities of all added patterns.</p> * the sum of the probabilities of all added patterns.</p>
* *

View File

@ -95,4 +95,5 @@ public class RepeatingExtentPattern extends AbstractExtentPattern {
int z = (Math.abs((p.getZ() + offset.getZ())) % size.getBlockZ()) + origin.getZ(); int z = (Math.abs((p.getZ() + offset.getZ())) % size.getBlockZ()) + origin.getZ();
return getExtent().getFullBlock(mutable.setComponents(x, y, z)); return getExtent().getFullBlock(mutable.setComponents(x, y, z));
} }
} }

View File

@ -1,3 +1,22 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.visitor; package com.sk89q.worldedit.function.visitor;
import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.BBC;
@ -7,25 +26,20 @@ import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.HasFaweQueue; import com.boydti.fawe.object.HasFaweQueue;
import com.boydti.fawe.object.IntegerTrio; import com.boydti.fawe.object.IntegerTrio;
import com.boydti.fawe.object.collection.BlockVectorSet; import com.boydti.fawe.object.collection.BlockVectorSet;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.RunContext; import com.sk89q.worldedit.function.operation.RunContext;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector3; import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.util.Direction;
import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Queue;
import java.util.Set;
/** /**
* Performs a breadth-first search starting from points added with * Performs a breadth-first search starting from points added with
@ -63,26 +77,26 @@ public abstract class BreadthFirstSearch implements Operation {
} }
} }
} }
Collections.sort(list, new Comparator<BlockVector3>() { list.sort((o1, o2) -> (int) Math.signum(o1.lengthSq() - o2.lengthSq()));
@Override
public int compare(BlockVector3 o1, BlockVector3 o2) {
return (int) Math.signum(o1.lengthSq() - o2.lengthSq());
}
});
DIAGONAL_DIRECTIONS = list.toArray(new BlockVector3[list.size()]); DIAGONAL_DIRECTIONS = list.toArray(new BlockVector3[list.size()]);
} }
private final RegionFunction function; private final RegionFunction function;
private List<BlockVector3> directions = new ArrayList<>();
private BlockVectorSet visited; private BlockVectorSet visited;
private final MappedFaweQueue mFaweQueue; private final MappedFaweQueue mFaweQueue;
private BlockVectorSet queue; private BlockVectorSet queue;
private int currentDepth = 0; private int currentDepth = 0;
private final int maxDepth; private final int maxDepth;
private List<BlockVector3> directions = new ArrayList<>();
private int affected = 0; private int affected = 0;
private int maxBranch = Integer.MAX_VALUE; private int maxBranch = Integer.MAX_VALUE;
public BreadthFirstSearch(final RegionFunction function) { /**
* Create a new instance.
*
* @param function the function to apply to visited blocks
*/
public BreadthFirstSearch(RegionFunction function) {
this(function, Integer.MAX_VALUE); this(function, Integer.MAX_VALUE);
} }
@ -133,29 +147,44 @@ public abstract class BreadthFirstSearch implements Operation {
* Add the directions along the axes as directions to visit. * Add the directions along the axes as directions to visit.
*/ */
protected void addAxes() { protected void addAxes() {
directions.add(BlockVector3.at(0, -1, 0)); directions.add(BlockVector3.UNIT_MINUS_Y);
directions.add(BlockVector3.at(0, 1, 0)); directions.add(BlockVector3.UNIT_Y);
directions.add(BlockVector3.at(-1, 0, 0)); directions.add(BlockVector3.UNIT_MINUS_X);
directions.add(BlockVector3.at(1, 0, 0)); directions.add(BlockVector3.UNIT_X);
directions.add(BlockVector3.at(0, 0, -1)); directions.add(BlockVector3.UNIT_MINUS_Z);
directions.add(BlockVector3.at(0, 0, 1)); directions.add(BlockVector3.UNIT_Z);
} }
/** /**
* Add the diagonal directions as directions to visit. * Add the diagonal directions as directions to visit.
*/ */
protected void addDiagonal() { protected void addDiagonal() {
directions.add(BlockVector3.at(1, 0, 1)); directions.add(Direction.NORTHEAST.toBlockVector());
directions.add(BlockVector3.at(-1, 0, -1)); directions.add(Direction.SOUTHEAST.toBlockVector());
directions.add(BlockVector3.at(1, 0, -1)); directions.add(Direction.SOUTHWEST.toBlockVector());
directions.add(BlockVector3.at(-1, 0, 1)); directions.add(Direction.NORTHWEST.toBlockVector());
} }
public void visit(final BlockVector3 pos) { /**
if (!isVisited(pos)) { * Add the given location to the list of locations to visit, provided
isVisitable(pos, pos); // Ignore this, just to initialize mask on this point * that it has not been visited. The position passed to this method
queue.add(pos); * will still be visited even if it fails
visited.add(pos); * {@link #isVisitable(BlockVector3, BlockVector3)}.
*
* <p>This method should be used before the search begins, because if
* the position <em>does</em> fail the test, and the search has already
* visited it (because it is connected to another root point),
* the search will mark the position as "visited" and a call to this
* method will do nothing.</p>
*
* @param position the position
*/
public void visit(BlockVector3 position) {
if (!isVisited(position)) {
isVisitable(position, position); // Ignore this, just to initialize mask on this point
queue.add(position);
visited.add(position);
} }
} }
@ -217,9 +246,6 @@ public abstract class BreadthFirstSearch implements Operation {
@Override @Override
public Operation resume(RunContext run) throws WorldEditException { public Operation resume(RunContext run) throws WorldEditException {
MutableBlockVector3 mutable = new MutableBlockVector3();
// MutableBlockVector3 mutable2 = new MutableBlockVector3();
boolean shouldTrim = false;
IntegerTrio[] dirs = getIntDirections(); IntegerTrio[] dirs = getIntDirections();
BlockVectorSet tempQueue = new BlockVectorSet(); BlockVectorSet tempQueue = new BlockVectorSet();
BlockVectorSet chunkLoadSet = new BlockVectorSet(); BlockVectorSet chunkLoadSet = new BlockVectorSet();
@ -268,7 +294,6 @@ public abstract class BreadthFirstSearch implements Operation {
if (currentDepth == maxDepth) { if (currentDepth == maxDepth) {
break; break;
} }
int size = queue.size();
BlockVectorSet tmp = queue; BlockVectorSet tmp = queue;
queue = tempQueue; queue = tempQueue;
tmp.clear(); tmp.clear();

View File

@ -30,19 +30,16 @@ import com.sk89q.worldedit.math.BlockVector3;
import java.util.Collection; import java.util.Collection;
import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* Visits adjacent points on the same X-Z plane as long as the points * Visits adjacent points on the same X-Z plane as long as the points
* pass the given mask, and then executes the provided region * pass the given mask, and then executes the provided region
* function on the entire column. * function on the entire column.
* <p> *
* <p>This is used by {@code //fill}.</p> * <p>This is used by {@code //fill}.</p>
*/ */
public class DownwardVisitor extends RecursiveVisitor { public class DownwardVisitor extends RecursiveVisitor {
private final int baseY; private int baseY;
/** /**
* Create a new visitor. * Create a new visitor.
@ -58,15 +55,16 @@ public class DownwardVisitor extends RecursiveVisitor {
public DownwardVisitor(Mask mask, RegionFunction function, int baseY, int depth, HasFaweQueue hasFaweQueue) { public DownwardVisitor(Mask mask, RegionFunction function, int baseY, int depth, HasFaweQueue hasFaweQueue) {
super(mask, function, depth, hasFaweQueue); super(mask, function, depth, hasFaweQueue);
checkNotNull(mask); checkNotNull(mask);
this.baseY = baseY; this.baseY = baseY;
Collection<BlockVector3> directions = getDirections(); Collection<BlockVector3> directions = getDirections();
directions.clear(); directions.clear();
directions.add(BlockVector3.at(1, 0, 0)); directions.add(BlockVector3.UNIT_X);
directions.add(BlockVector3.at(-1, 0, 0)); directions.add(BlockVector3.UNIT_MINUS_X);
directions.add(BlockVector3.at(0, 0, 1)); directions.add(BlockVector3.UNIT_Z);
directions.add(BlockVector3.at(0, 0, -1)); directions.add(BlockVector3.UNIT_MINUS_Z);
directions.add(BlockVector3.at(0, -1, 0)); directions.add(BlockVector3.UNIT_MINUS_Y);
} }
@Override @Override
@ -74,6 +72,4 @@ public class DownwardVisitor extends RecursiveVisitor {
int fromY = from.getBlockY(); int fromY = from.getBlockY();
return (fromY == baseY || to.subtract(from).getBlockY() < 0) && super.isVisitable(from, to); return (fromY == baseY || to.subtract(from).getBlockY() < 0) && super.isVisitable(from, to);
} }
} }

View File

@ -35,6 +35,9 @@ public class BlockVector3 {
public static final BlockVector3 UNIT_X = new BlockVector3(1, 0, 0); public static final BlockVector3 UNIT_X = new BlockVector3(1, 0, 0);
public static final BlockVector3 UNIT_Y = new BlockVector3(0, 1, 0); public static final BlockVector3 UNIT_Y = new BlockVector3(0, 1, 0);
public static final BlockVector3 UNIT_Z = new BlockVector3(0, 0, 1); public static final BlockVector3 UNIT_Z = new BlockVector3(0, 0, 1);
public static final BlockVector3 UNIT_MINUS_X = new BlockVector3(-1, 0, 0);
public static final BlockVector3 UNIT_MINUS_Y = new BlockVector3(0, -1, 0);
public static final BlockVector3 UNIT_MINUS_Z = new BlockVector3(0, 0, -1);
public static final BlockVector3 ONE = new BlockVector3(1, 1, 1); public static final BlockVector3 ONE = new BlockVector3(1, 1, 1);
public static BlockVector3 at(double x, double y, double z) { public static BlockVector3 at(double x, double y, double z) {

View File

@ -1,29 +1,44 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.math.convolution; package com.sk89q.worldedit.math.convolution;
import com.boydti.fawe.object.visitor.Fast2DIterator; import com.boydti.fawe.object.visitor.Fast2DIterator;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.Regions; import com.sk89q.worldedit.regions.Regions;
import com.sk89q.worldedit.registry.state.PropertyGroup; import com.sk89q.worldedit.registry.state.PropertyGroup;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.Iterator; import java.util.Iterator;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import javax.annotation.Nullable;
/** /**
* Allows applications of Kernels onto the region's height map. * Allows applications of Kernels onto the region's height map.
* <p> *
* <p>Currently only used for smoothing (with a GaussianKernel)</p>. * <p>Currently only used for smoothing (with a GaussianKernel)</p>.
*/ */
public class HeightMap { public class HeightMap {
@ -68,12 +83,12 @@ public class HeightMap {
int minZ = region.getMinimumPoint().getBlockZ(); int minZ = region.getMinimumPoint().getBlockZ();
int maxY = region.getMaximumPoint().getBlockY(); int maxY = region.getMaximumPoint().getBlockY();
// Store current heightmap data
data = new int[width * height]; data = new int[width * height];
invalid = new boolean[data.length]; invalid = new boolean[data.length];
if (layers) { if (layers) {
BlockVector3 min = region.getMinimumPoint(); BlockVector3 min = region.getMinimumPoint();
BlockVector3 max = region.getMaximumPoint();
int bx = min.getBlockX(); int bx = min.getBlockX();
int bz = min.getBlockZ(); int bz = min.getBlockZ();
Iterable<BlockVector2> flat = Regions.asFlatRegion(region).asFlatRegion(); Iterable<BlockVector2> flat = Regions.asFlatRegion(region).asFlatRegion();
@ -133,6 +148,7 @@ public class HeightMap {
* @return number of blocks affected * @return number of blocks affected
* @throws MaxChangedBlocksException * @throws MaxChangedBlocksException
*/ */
public int applyFilter(HeightMapFilter filter, int iterations) throws MaxChangedBlocksException { public int applyFilter(HeightMapFilter filter, int iterations) throws MaxChangedBlocksException {
checkNotNull(filter); checkNotNull(filter);
@ -155,11 +171,11 @@ public class HeightMap {
int originZ = minY.getBlockZ(); int originZ = minY.getBlockZ();
int maxY = region.getMaximumPoint().getBlockY(); int maxY = region.getMaximumPoint().getBlockY();
BlockStateHolder fillerAir = EditSession.nullBlock; BlockStateHolder fillerAir = BlockTypes.AIR.getDefaultState();
int blocksChanged = 0; int blocksChanged = 0;
BlockStateHolder tmpBlock = EditSession.nullBlock; BlockStateHolder tmpBlock = BlockTypes.AIR.getDefaultState();
// Apply heightmap // Apply heightmap
int maxY4 = maxY << 4; int maxY4 = maxY << 4;
@ -233,12 +249,11 @@ public class HeightMap {
int originZ = minY.getBlockZ(); int originZ = minY.getBlockZ();
int maxY = region.getMaximumPoint().getBlockY(); int maxY = region.getMaximumPoint().getBlockY();
BlockStateHolder fillerAir = EditSession.nullBlock; BlockState fillerAir = BlockTypes.AIR.getDefaultState();
int blocksChanged = 0; int blocksChanged = 0;
BlockStateHolder tmpBlock = EditSession.nullBlock; BlockState tmpBlock = BlockTypes.AIR.getDefaultState();
// Apply heightmap // Apply heightmap
int index = 0; int index = 0;
for (int z = 0; z < height; ++z) { for (int z = 0; z < height; ++z) {
@ -248,20 +263,20 @@ public class HeightMap {
if (this.invalid != null && this.invalid[index]) continue; if (this.invalid != null && this.invalid[index]) continue;
int newHeight = Math.min(maxY, data[index]); int newHeight = Math.min(maxY, data[index]);
// Offset x,z to be 'real' coordinates
int xr = x + originX; int xr = x + originX;
// Depending on growing or shrinking we need to start at the bottom or top // Depending on growing or shrinking we need to start at the bottom or top
if (newHeight > curHeight) { if (newHeight > curHeight) {
// Set the top block of the column to be the same type (this might go wrong with rounding) // Set the top block of the column to be the same type (this might go wrong with rounding)
BlockStateHolder existing = session.getBlock(xr, curHeight, zr); BlockState existing = session.getBlock(BlockVector3.at(xr, curHeight, zr));
// Skip water/lava // Skip water/lava
if (existing.getBlockType().getMaterial().isMovementBlocker()) { if (existing.getBlockType() != BlockTypes.WATER && existing.getBlockType() != BlockTypes.LAVA) {
int y0 = newHeight - 1; int y0 = newHeight - 1;
for (int setY = y0, getY = curHeight - 1; setY >= curHeight; setY--, getY--) { for (int setY = y0, getY = curHeight - 1; setY >= curHeight; setY--, getY--) {
BlockStateHolder get = session.getBlock(xr, getY, zr); BlockState get = session.getBlock(xr, getY, zr);
if (get != EditSession.nullBlock) tmpBlock = get; if (get != BlockTypes.AIR.getDefaultState()) tmpBlock = get;
session.setBlock(xr, setY, zr, tmpBlock); session.setBlock(xr, setY, zr, tmpBlock);
++blocksChanged; ++blocksChanged;
} }
@ -282,9 +297,10 @@ public class HeightMap {
} }
} }
} }
// Drop trees to the floor -- TODO
return blocksChanged; return blocksChanged;
} }
} }

View File

@ -23,6 +23,7 @@ import com.sk89q.worldedit.util.Direction;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -63,7 +64,7 @@ public class DirectionalProperty extends AbstractProperty<Direction> {
@Nullable @Nullable
@Override @Override
public Direction getValueFor(final String string) { public Direction getValueFor(final String string) {
Direction direction = Direction.valueOf(string.toUpperCase()); Direction direction = Direction.valueOf(string.toUpperCase(Locale.ROOT));
if (!getValues().contains(direction)) { if (!getValues().contains(direction)) {
throw new IllegalArgumentException("Invalid direction value: " + string + ". Must be in " + getValues().toString()); throw new IllegalArgumentException("Invalid direction value: " + string + ". Must be in " + getValues().toString());
} }

View File

@ -67,9 +67,9 @@ public class IntegerProperty extends AbstractProperty<Integer> {
public Integer getValueFor(String string) { public Integer getValueFor(String string) {
try { try {
int val = Integer.parseInt(string); int val = Integer.parseInt(string);
// if (!getValues().contains(val)) { if (!getValues().contains(val)) {
// throw new IllegalArgumentException("Invalid int value: " + string + ". Must be in " + getValues().toString()); throw new IllegalArgumentException("Invalid int value: " + string + ". Must be in " + getValues().toString());
// } }
return val; return val;
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid int value: " + string + ". Not an int."); throw new IllegalArgumentException("Invalid int value: " + string + ". Not an int.");

View File

@ -64,8 +64,10 @@ public enum Direction {
; ;
private final Vector3 direction; private final Vector3 direction;
private final BlockVector3 blockVector; private final int flags;
private final int flags, left, right; private final int left;
private final int right;
private final BlockVector3 blockPoint;
private static HashMap<String, Direction> map = new HashMap<>(); private static HashMap<String, Direction> map = new HashMap<>();
@ -77,15 +79,15 @@ public enum Direction {
} }
Direction(Vector3 vector, int flags, int left, int right) { Direction(Vector3 vector, int flags, int left, int right) {
this.blockPoint = vector.toBlockPoint();
this.direction = vector.normalize(); this.direction = vector.normalize();
this.blockVector = BlockVector3.at(Math.signum(vector.getX()), Math.signum(vector.getY()), Math.signum(vector.getZ()));
this.flags = flags; this.flags = flags;
this.left = left; this.left = left;
this.right = right; this.right = right;
} }
public static Direction get(CharSequence sequence) { public static Direction get(CharSequence sequence) {
return map.get(sequence); return map.get((String)sequence);
} }
public Direction getLeft() { public Direction getLeft() {
@ -96,30 +98,6 @@ public enum Direction {
return right != -1 ? values()[right] : null; return right != -1 ? values()[right] : null;
} }
public double getX() {
return direction.getX();
}
public double getY() {
return direction.getY();
}
public double getZ() {
return direction.getZ();
}
public int getBlockX() {
return blockVector.getBlockX();
}
public int getBlockY() {
return blockVector.getBlockY();
}
public int getBlockZ() {
return blockVector.getBlockZ();
}
/** /**
* Return true if the direction is of a cardinal direction (north, west * Return true if the direction is of a cardinal direction (north, west
* east, and south). * east, and south).
@ -177,7 +155,7 @@ public enum Direction {
* @return the vector * @return the vector
*/ */
public BlockVector3 toBlockVector() { public BlockVector3 toBlockVector() {
return direction.toBlockPoint(); return blockPoint;
} }
/** /**
@ -332,3 +310,4 @@ public enum Direction {
} }
} }

View File

@ -20,10 +20,15 @@
package com.sk89q.worldedit.util; package com.sk89q.worldedit.util;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.SolidBlockMask;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import javax.annotation.Nullable;
/** /**
* This class uses an inefficient method to figure out what block a player * This class uses an inefficient method to figure out what block a player
* is looking towards. * is looking towards.
@ -33,7 +38,8 @@ import com.sk89q.worldedit.world.World;
*/ */
public class TargetBlock { public class TargetBlock {
private World world; private final World world;
private int maxDistance; private int maxDistance;
private double checkDistance, curDistance; private double checkDistance, curDistance;
private BlockVector3 targetPos = BlockVector3.ZERO; private BlockVector3 targetPos = BlockVector3.ZERO;
@ -41,6 +47,11 @@ public class TargetBlock {
private BlockVector3 prevPos = BlockVector3.ZERO; private BlockVector3 prevPos = BlockVector3.ZERO;
private Vector3 offset = Vector3.ZERO; private Vector3 offset = Vector3.ZERO;
// the mask which dictates when to stop a trace - defaults to stopping at non-air blocks
private Mask stopMask;
// the mask which dictates when to stop a solid block trace - default to BlockMaterial#isMovementBlocker
private Mask solidMask;
/** /**
* Constructor requiring a player, uses default values * Constructor requiring a player, uses default values
* *
@ -48,7 +59,10 @@ public class TargetBlock {
*/ */
public TargetBlock(Player player) { public TargetBlock(Player player) {
this.world = player.getWorld(); this.world = player.getWorld();
this.setValues(player.getLocation(), player.getLocation().getYaw(), player.getLocation().getPitch(), 300, 1.65, 0.2); this.setValues(player.getLocation().toVector(), player.getLocation().getYaw(), player.getLocation().getPitch(),
300, 1.65, 0.2);
this.stopMask = new ExistingBlockMask(world);
this.solidMask = new SolidBlockMask(world);
} }
/** /**
@ -60,7 +74,37 @@ public class TargetBlock {
*/ */
public TargetBlock(Player player, int maxDistance, double checkDistance) { public TargetBlock(Player player, int maxDistance, double checkDistance) {
this.world = player.getWorld(); this.world = player.getWorld();
this.setValues(player.getLocation(), player.getLocation().getYaw(), player.getLocation().getPitch(), maxDistance, 1.65, checkDistance); this.setValues(player.getLocation().toVector(), player.getLocation().getYaw(), player.getLocation().getPitch(), maxDistance, 1.65, checkDistance);
this.stopMask = new ExistingBlockMask(world);
this.solidMask = new SolidBlockMask(world);
}
/**
* Set the mask used for determine where to stop traces.
* Setting to null will restore the default.
*
* @param stopMask the mask used to stop traces
*/
public void setStopMask(@Nullable Mask stopMask) {
if (stopMask == null) {
this.stopMask = new ExistingBlockMask(world);
} else {
this.stopMask = stopMask;
}
}
/**
* Set the mask used for determine where to stop solid block traces.
* Setting to null will restore the default.
*
* @param solidMask the mask used to stop solid block traces
*/
public void setSolidMask(@Nullable Mask solidMask) {
if (solidMask == null) {
this.solidMask = new SolidBlockMask(world);
} else {
this.solidMask = solidMask;
}
} }
/** /**
@ -78,7 +122,7 @@ public class TargetBlock {
this.checkDistance = checkDistance; this.checkDistance = checkDistance;
this.curDistance = 0; this.curDistance = 0;
xRotation = (xRotation + 90) % 360; xRotation = (xRotation + 90) % 360;
yRotation = yRotation * -1; yRotation *= -1;
double h = (checkDistance * Math.cos(Math.toRadians(yRotation))); double h = (checkDistance * Math.cos(Math.toRadians(yRotation)));
@ -101,15 +145,15 @@ public class TargetBlock {
boolean searchForLastBlock = true; boolean searchForLastBlock = true;
Location lastBlock = null; Location lastBlock = null;
while (getNextBlock() != null) { while (getNextBlock() != null) {
if (world.getBlock(targetPos).getBlockType().getMaterial().isAir()) { if (stopMask.test(targetPos)) {
break;
} else {
if (searchForLastBlock) { if (searchForLastBlock) {
lastBlock = getCurrentBlock(); lastBlock = getCurrentBlock();
if (lastBlock.getBlockY() <= 0 || lastBlock.getBlockY() >= world.getMaxY()) { if (lastBlock.getBlockY() <= 0 || lastBlock.getBlockY() >= world.getMaxY()) {
searchForLastBlock = false; searchForLastBlock = false;
} }
} }
} else {
break;
} }
} }
Location currentBlock = getCurrentBlock(); Location currentBlock = getCurrentBlock();
@ -123,7 +167,8 @@ public class TargetBlock {
* @return Block * @return Block
*/ */
public Location getTargetBlock() { public Location getTargetBlock() {
while (getNextBlock() != null && world.getBlock(targetPos).getBlockType().getMaterial().isAir()) ; //noinspection StatementWithEmptyBody
while (getNextBlock() != null && !stopMask.test(targetPos)) ;
return getCurrentBlock(); return getCurrentBlock();
} }
@ -134,7 +179,8 @@ public class TargetBlock {
* @return Block * @return Block
*/ */
public Location getSolidTargetBlock() { public Location getSolidTargetBlock() {
while (getNextBlock() != null && !world.getBlock(targetPos).getBlockType().getMaterial().isMovementBlocker()) ; //noinspection StatementWithEmptyBody
while (getNextBlock() != null && !solidMask.test(targetPos)) ;
return getCurrentBlock(); return getCurrentBlock();
} }
@ -188,12 +234,17 @@ public class TargetBlock {
public Location getAnyTargetBlockFace() { public Location getAnyTargetBlockFace() {
getAnyTargetBlock(); getAnyTargetBlock();
return getCurrentBlock().setDirection(getCurrentBlock().subtract(getPreviousBlock())); Location current = getCurrentBlock();
if (current != null)
return current.setDirection(current.toVector().subtract(getPreviousBlock().toVector()));
else
return new Location(world, targetPos.toVector3(), Float.NaN, Float.NaN);
} }
public Location getTargetBlockFace() { public Location getTargetBlockFace() {
getAnyTargetBlock(); getTargetBlock();
return getCurrentBlock().setDirection(getCurrentBlock().subtract(getPreviousBlock())); if (getCurrentBlock() == null) return null;
return getCurrentBlock().setDirection(getCurrentBlock().toVector().subtract(getPreviousBlock().toVector()));
} }
} }

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.util; package com.sk89q.worldedit.util;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
@ -30,6 +31,7 @@ import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
@ -64,8 +66,8 @@ public class TreeGenerator {
} }
}, },
JUNGLE("Jungle tree", "jungle"), JUNGLE("Jungle tree", "jungle"),
SMALL_JUNGLE("Small jungle tree", "shortjungle", "smalljungle"), SMALL_JUNGLE("Small jungle tree", "smalljungle"),
SHORT_JUNGLE("Short jungle tree") { SHORT_JUNGLE("Short jungle tree", "shortjungle") {
@Override @Override
public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException { public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException {
return SMALL_JUNGLE.generate(editSession, pos); return SMALL_JUNGLE.generate(editSession, pos);
@ -113,22 +115,22 @@ public class TreeGenerator {
private static final Set<String> primaryAliases = Sets.newHashSet(); private static final Set<String> primaryAliases = Sets.newHashSet();
private final String name; private final String name;
private final String[] lookupKeys; public final ImmutableList<String> lookupKeys;
static { static {
for (TreeType type : EnumSet.allOf(TreeType.class)) { for (TreeType type : EnumSet.allOf(TreeType.class)) {
for (String key : type.lookupKeys) { for (String key : type.lookupKeys) {
lookup.put(key, type); lookup.put(key, type);
} }
if (type.lookupKeys.length > 0) { if (type.lookupKeys.size() > 0) {
primaryAliases.add(type.lookupKeys[0]); primaryAliases.add(type.lookupKeys.get(0));
} }
} }
} }
TreeType(String name, String... lookupKeys) { TreeType(String name, String... lookupKeys) {
this.name = name; this.name = name;
this.lookupKeys = lookupKeys; this.lookupKeys = ImmutableList.copyOf(lookupKeys);
} }
public static Set<String> getAliases() { public static Set<String> getAliases() {
@ -160,7 +162,7 @@ public class TreeGenerator {
*/ */
@Nullable @Nullable
public static TreeType lookup(String name) { public static TreeType lookup(String name) {
return lookup.get(name.toLowerCase()); return lookup.get(name.toLowerCase(Locale.ROOT));
} }
} }
@ -179,8 +181,8 @@ public class TreeGenerator {
int trunkHeight = (int) Math.floor(Math.random() * 2) + 3; int trunkHeight = (int) Math.floor(Math.random() * 2) + 3;
int height = (int) Math.floor(Math.random() * 5) + 8; int height = (int) Math.floor(Math.random() * 5) + 8;
BlockStateHolder logBlock = BlockTypes.OAK_LOG.getDefaultState(); BlockState logBlock = BlockTypes.OAK_LOG.getDefaultState();
BlockStateHolder leavesBlock = BlockTypes.OAK_LEAVES.getDefaultState(); BlockState leavesBlock = BlockTypes.OAK_LEAVES.getDefaultState();
// Create trunk // Create trunk
for (int i = 0; i < trunkHeight; ++i) { for (int i = 0; i < trunkHeight; ++i) {

View File

@ -23,6 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Function; import com.google.common.base.Function;
import java.util.Locale;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -60,7 +61,7 @@ public class LevenshteinDistance implements Function<String, Integer> {
checkNotNull(baseString); checkNotNull(baseString);
this.caseSensitive = caseSensitive; this.caseSensitive = caseSensitive;
this.replacePattern = replacePattern; this.replacePattern = replacePattern;
baseString = caseSensitive ? baseString : baseString.toLowerCase(); baseString = caseSensitive ? baseString : baseString.toLowerCase(Locale.ROOT);
baseString = replacePattern != null ? replacePattern.matcher(baseString).replaceAll("") : baseString; baseString = replacePattern != null ? replacePattern.matcher(baseString).replaceAll("") : baseString;
this.baseString = baseString; this.baseString = baseString;
} }
@ -79,7 +80,7 @@ public class LevenshteinDistance implements Function<String, Integer> {
if (caseSensitive) { if (caseSensitive) {
return distance(baseString, input); return distance(baseString, input);
} else { } else {
return distance(baseString, input.toLowerCase()); return distance(baseString, input.toLowerCase(Locale.ROOT));
} }
} }

View File

@ -19,9 +19,15 @@
package com.sk89q.worldedit.util.logging; package com.sk89q.worldedit.util.logging;
import javax.annotation.Nullable;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.logging.*; import java.util.logging.Filter;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;
import java.util.logging.StreamHandler;
import javax.annotation.Nullable;
/** /**
* A {@link StreamHandler} delegate that allows for the swap and disable of * A {@link StreamHandler} delegate that allows for the swap and disable of

View File

@ -39,7 +39,7 @@ public class EngineHubPaste implements Paster {
return Pasters.getExecutor().submit(new PasteTask(content)); return Pasters.getExecutor().submit(new PasteTask(content));
} }
private final class PasteTask implements Callable<URL> { private static final class PasteTask implements Callable<URL> {
private final String content; private final String content;
private PasteTask(String content) { private PasteTask(String content) {
@ -50,7 +50,7 @@ public class EngineHubPaste implements Paster {
public URL call() throws IOException, InterruptedException { public URL call() throws IOException, InterruptedException {
HttpRequest.Form form = HttpRequest.Form.create(); HttpRequest.Form form = HttpRequest.Form.create();
form.add("content", content); form.add("content", content);
form.add("from", "worldguard"); form.add("from", "enginehub");
URL url = HttpRequest.url("http://paste.enginehub.org/paste"); URL url = HttpRequest.url("http://paste.enginehub.org/paste");
String result = HttpRequest.post(url) String result = HttpRequest.post(url)

View File

@ -21,7 +21,6 @@ package com.sk89q.worldedit.util.report;
public interface Report { public interface Report {
String getTitle(); String getTitle();
} }

View File

@ -38,10 +38,7 @@ import com.sk89q.worldedit.registry.state.PropertyKey;
import com.sk89q.worldedit.world.registry.BlockMaterial; import com.sk89q.worldedit.world.registry.BlockMaterial;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Arrays; import java.util.*;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -124,7 +121,7 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
String input = key.toString(); String input = key.toString();
throw new SuggestInputParseException("Does not match a valid block type: " + input, input, () -> Stream.of(BlockTypes.values) throw new SuggestInputParseException("Does not match a valid block type: " + input, input, () -> Stream.of(BlockTypes.values)
.filter(b -> StringMan.blockStateMatches(input, b.getId())) .filter(b -> StringMan.blockStateMatches(input, b.getId()))
.map(e1 -> e1.getId()) .map(BlockType::getId)
.sorted(StringMan.blockStateComparator(input)) .sorted(StringMan.blockStateComparator(input))
.collect(Collectors.toList()) .collect(Collectors.toList())
); );
@ -181,12 +178,12 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
BlockType finalType = type; BlockType finalType = type;
throw new SuggestInputParseException("Invalid property " + charSequence + ":" + input + " for type " + type, input, () -> throw new SuggestInputParseException("Invalid property " + charSequence + ":" + input + " for type " + type, input, () ->
finalType.getProperties().stream() finalType.getProperties().stream()
.map(p -> p.getName()) .map(Property::getName)
.filter(p -> StringMan.blockStateMatches(input, p)) .filter(p -> StringMan.blockStateMatches(input, p))
.sorted(StringMan.blockStateComparator(input)) .sorted(StringMan.blockStateComparator(input))
.collect(Collectors.toList())); .collect(Collectors.toList()));
} else { } else {
throw new SuggestInputParseException("No operator for " + state, "", () -> Arrays.asList("=")); throw new SuggestInputParseException("No operator for " + state, "", () -> Collections.singletonList("="));
} }
} }
property = null; property = null;
@ -211,6 +208,11 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
return getBlockType().withPropertyId(propertyId); return getBlockType().withPropertyId(propertyId);
} }
@Override
public BlockType getBlockType() {
return this.blockType;
}
@Override @Override
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
return extent.setBlock(set, this); return extent.setBlock(set, this);
@ -259,6 +261,14 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
} }
} }
@Override
public final Map<Property<?>, Object> getStates() {
BlockType type = this.getBlockType();
// Lazily initialize the map
Map<? extends Property, Object> map = Maps.asMap(type.getPropertiesSet(), (Function<Property, Object>) this::getState);
return (Map<Property<?>, Object>) map;
}
@Override @Override
public final <V> V getState(final Property<V> property) { public final <V> V getState(final Property<V> property) {
try { try {
@ -269,19 +279,9 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
} }
} }
@Deprecated
@Override @Override
public final <V> V getState(final PropertyKey key) { public BlockState toImmutableState() {
return getState(getBlockType().getProperty(key)); return this;
}
@Override
@Deprecated
public final Map<Property<?>, Object> getStates() {
BlockType type = this.getBlockType();
// Lazily initialize the map
Map<? extends Property, Object> map = Maps.asMap(type.getPropertiesSet(), (Function<Property, Object>) input -> getState(input));
return (Map<Property<?>, Object>) map;
} }
@Override @Override
@ -289,6 +289,12 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
return this.emptyBaseBlock; return this.emptyBaseBlock;
} }
@Deprecated
@Override
public final <V> V getState(final PropertyKey key) {
return getState(getBlockType().getProperty(key));
}
@Override @Override
public BaseBlock toBaseBlock(CompoundTag compoundTag) { public BaseBlock toBaseBlock(CompoundTag compoundTag) {
if (compoundTag == null) { if (compoundTag == null) {
@ -297,11 +303,6 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
return new BaseBlock(this, compoundTag); return new BaseBlock(this, compoundTag);
} }
@Override
public BlockType getBlockType() {
return this.blockType;
}
@Override @Override
public boolean equalsFuzzy(BlockStateHolder<?> o) { public boolean equalsFuzzy(BlockStateHolder<?> o) {
if (o.getClass() == BlockState.class) { if (o.getClass() == BlockState.class) {
@ -310,11 +311,6 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
return o.equalsFuzzy(this); return o.equalsFuzzy(this);
} }
@Override
public BlockState toImmutableState() {
return this;
}
@Override @Override
public int getInternalId() { public int getInternalId() {
return internalId; return internalId;
@ -326,10 +322,8 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
if (blockType == BlockTypes.__RESERVED__) { if (blockType == BlockTypes.__RESERVED__) {
return this.material = blockType.getMaterial(); return this.material = blockType.getMaterial();
} }
if (this.material == null) {
this.material = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this); this.material = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this);
} }
}
return material; return material;
} }

View File

@ -19,41 +19,31 @@
package com.sk89q.worldedit.world.block; package com.sk89q.worldedit.world.block;
import static com.google.common.base.Preconditions.checkArgument;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.command.SuggestInputParseException; import com.boydti.fawe.command.SuggestInputParseException;
import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.ReflectionUtils;
import com.boydti.fawe.util.StringMan; import com.boydti.fawe.util.StringMan;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.SingleBlockTypeMask;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.AbstractProperty; import com.sk89q.worldedit.registry.state.AbstractProperty;
import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.registry.state.PropertyKey; import com.sk89q.worldedit.registry.state.PropertyKey;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.registry.BlockMaterial; import com.sk89q.worldedit.world.registry.BlockMaterial;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import com.sk89q.worldedit.world.registry.LegacyMapper; import com.sk89q.worldedit.world.registry.LegacyMapper;
import it.unimi.dsi.fastutil.ints.IntCollections;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.*; import java.util.ArrayList;
import java.util.function.Function; import java.util.Arrays;
import java.util.function.IntPredicate; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**