Update BukkitImplLoader

This commit is contained in:
MattBDev 2020-08-24 21:20:18 -04:00
parent fd8cf1ebba
commit 75a18b9d5b
45 changed files with 5618 additions and 5626 deletions

View File

@ -3,18 +3,18 @@
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify
* under the terms of the GNU Lesser General Public License as published by the * it under the terms of the GNU General Public License as published by
* Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful,
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * but WITHOUT ANY WARRANTY; without even the implied warranty of
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.bukkit.adapter; package com.sk89q.worldedit.bukkit.adapter;
@ -47,15 +47,14 @@ public class BukkitImplLoader {
private static final String CLASS_SUFFIX = ".class"; private static final String CLASS_SUFFIX = ".class";
private static final String LOAD_ERROR_MESSAGE = private static final String LOAD_ERROR_MESSAGE =
"\n**********************************************\n" + "\n**********************************************\n"
"** This WorldEdit version does not fully support your version of Bukkit.\n" + + "** This WorldEdit version does not fully support your version of Bukkit.\n"
"**\n" + + "**\n" + "** When working with blocks or undoing, chests will be empty, signs\n"
"** When working with blocks or undoing, chests will be empty, signs\n" + + "** will be blank, and so on. There will be no support for entity\n"
"** will be blank, and so on. There will be no support for entity\n" + + "** and block property-related functions.\n"
"** and block property-related functions.\n" + + "**\n"
"**\n" + + "** Please see https://worldedit.enginehub.org/en/latest/faq/#bukkit-adapters\n"
"** Please see https://worldedit.enginehub.org/en/latest/faq/#bukkit-adapters\n" + + "**********************************************\n";
"**********************************************\n";
/** /**
* Create a new instance. * Create a new instance.
@ -97,7 +96,9 @@ public class BukkitImplLoader {
String className = jarEntry.getName().replaceAll("[/\\\\]+", "."); String className = jarEntry.getName().replaceAll("[/\\\\]+", ".");
if (!className.startsWith(SEARCH_PACKAGE_DOT) || jarEntry.isDirectory()) continue; if (!className.startsWith(SEARCH_PACKAGE_DOT) || jarEntry.isDirectory()) {
continue;
}
int beginIndex = 0; int beginIndex = 0;
int endIndex = className.length() - CLASS_SUFFIX.length(); int endIndex = className.length() - CLASS_SUFFIX.length();
@ -155,32 +156,23 @@ public class BukkitImplLoader {
*/ */
public BukkitImplAdapter loadAdapter() throws AdapterLoadException { public BukkitImplAdapter loadAdapter() throws AdapterLoadException {
for (String className : adapterCandidates) { for (String className : adapterCandidates) {
System.out.println("Candidate: " + className);
try { try {
Class<?> cls = Class.forName(className); Class<?> cls = Class.forName(className);
if (cls.isSynthetic()){ if (cls.isSynthetic()) {
System.out.println(className + " is synthetic, continuing");
continue; continue;
}else{
System.out.println(className + " is not synthetic");
} }
if (BukkitImplAdapter.class.isAssignableFrom(cls)) { if (BukkitImplAdapter.class.isAssignableFrom(cls)) {
System.out.println(className + " is assignable from BukkitImplAdapter, returning");
return (BukkitImplAdapter) cls.newInstance(); return (BukkitImplAdapter) cls.newInstance();
}else{
System.out.println(className + " is NOT assignable from BukkitImplAdapter, returning");
} }
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
log.warn("Failed to load the Bukkit adapter class '" + className + log.warn("Failed to load the Bukkit adapter class '" + className
"' that is not supposed to be missing", e); + "' that is not supposed to be missing", e);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
log.warn("Failed to load the Bukkit adapter class '" + className + log.warn("Failed to load the Bukkit adapter class '" + className
"' that is not supposed to be raising this error", e); + "' that is not supposed to be raising this error", e);
} catch (Throwable e) { } catch (Throwable e) {
if (className.equals(customCandidate)) { if (className.equals(customCandidate)) {
log.warn("Failed to load the Bukkit adapter class '" + className + "'", e); log.warn("Failed to load the Bukkit adapter class '" + className + "'", e);
}else{
log.warn(className + " is not custom candidate.", e);
} }
} }
} }

View File

@ -1,64 +1,64 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.jnbt; package com.sk89q.jnbt;
import java.util.Locale; import java.util.Locale;
/** /**
* The {@code TAG_Byte_Array} tag. * The {@code TAG_Byte_Array} tag.
*/ */
public final class ByteArrayTag extends Tag { public final class ByteArrayTag extends Tag {
@Override @Override
public int getTypeCode() { public int getTypeCode() {
return NBTConstants.TYPE_BYTE_ARRAY; return NBTConstants.TYPE_BYTE_ARRAY;
} }
private final byte[] value; private final byte[] value;
/** /**
* Creates the tag with an empty name. * Creates the tag with an empty name.
* *
* @param value the value of the tag * @param value the value of the tag
*/ */
public ByteArrayTag(byte[] value) { public ByteArrayTag(byte[] value) {
super(); super();
this.value = value; this.value = value;
} }
@Override @Override
public byte[] getValue() { public byte[] getValue() {
return value; return value;
} }
@Override @Override
public String toString() { public String toString() {
StringBuilder hex = new StringBuilder(); StringBuilder hex = new StringBuilder();
for (byte b : value) { for (byte b : value) {
String hexDigits = Integer.toHexString(b).toUpperCase(Locale.ROOT); String hexDigits = Integer.toHexString(b).toUpperCase(Locale.ROOT);
if (hexDigits.length() == 1) { if (hexDigits.length() == 1) {
hex.append("0"); hex.append("0");
} }
hex.append(hexDigits).append(" "); hex.append(hexDigits).append(" ");
} }
return "TAG_Byte_Array(" + hex + ")"; return "TAG_Byte_Array(" + hex + ")";
} }
} }

View File

@ -1,53 +1,53 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.jnbt; package com.sk89q.jnbt;
/** /**
* The {@code TAG_Byte} tag. * The {@code TAG_Byte} tag.
*/ */
public final class ByteTag extends NumberTag { public final class ByteTag extends NumberTag {
@Override @Override
public int getTypeCode() { public int getTypeCode() {
return NBTConstants.TYPE_BYTE; return NBTConstants.TYPE_BYTE;
} }
private final byte value; private final byte value;
/** /**
* Creates the tag with an empty name. * Creates the tag with an empty name.
* *
* @param value the value of the tag * @param value the value of the tag
*/ */
public ByteTag(byte value) { public ByteTag(byte value) {
super(); super();
this.value = value; this.value = value;
} }
@Override @Override
public Byte getValue() { public Byte getValue() {
return value; return value;
} }
@Override @Override
public String toString() { public String toString() {
return "TAG_Byte(" + value + ")"; return "TAG_Byte(" + value + ")";
} }
} }

View File

@ -1,53 +1,53 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.jnbt; package com.sk89q.jnbt;
/** /**
* The {@code TAG_Double} tag. * The {@code TAG_Double} tag.
*/ */
public final class DoubleTag extends NumberTag { public final class DoubleTag extends NumberTag {
@Override @Override
public int getTypeCode() { public int getTypeCode() {
return NBTConstants.TYPE_DOUBLE; return NBTConstants.TYPE_DOUBLE;
} }
private final double value; private final double value;
/** /**
* Creates the tag with an empty name. * Creates the tag with an empty name.
* *
* @param value the value of the tag * @param value the value of the tag
*/ */
public DoubleTag(double value) { public DoubleTag(double value) {
super(); super();
this.value = value; this.value = value;
} }
@Override @Override
public Double getValue() { public Double getValue() {
return value; return value;
} }
@Override @Override
public String toString() { public String toString() {
return "TAG_Double(" + value + ")"; return "TAG_Double(" + value + ")";
} }
} }

View File

@ -1,53 +1,53 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.jnbt; package com.sk89q.jnbt;
/** /**
* The {@code TAG_Float} tag. * The {@code TAG_Float} tag.
*/ */
public final class FloatTag extends NumberTag { public final class FloatTag extends NumberTag {
@Override @Override
public int getTypeCode() { public int getTypeCode() {
return NBTConstants.TYPE_FLOAT; return NBTConstants.TYPE_FLOAT;
} }
private final float value; private final float value;
/** /**
* Creates the tag with an empty name. * Creates the tag with an empty name.
* *
* @param value the value of the tag * @param value the value of the tag
*/ */
public FloatTag(float value) { public FloatTag(float value) {
super(); super();
this.value = value; this.value = value;
} }
@Override @Override
public Float getValue() { public Float getValue() {
return value; return value;
} }
@Override @Override
public String toString() { public String toString() {
return "TAG_Float(" + value + ")"; return "TAG_Float(" + value + ")";
} }
} }

View File

@ -1,53 +1,53 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.jnbt; package com.sk89q.jnbt;
/** /**
* The {@code TAG_Int} tag. * The {@code TAG_Int} tag.
*/ */
public final class IntTag extends NumberTag { public final class IntTag extends NumberTag {
@Override @Override
public int getTypeCode() { public int getTypeCode() {
return NBTConstants.TYPE_INT; return NBTConstants.TYPE_INT;
} }
private final int value; private final int value;
/** /**
* Creates the tag with an empty name. * Creates the tag with an empty name.
* *
* @param value the value of the tag * @param value the value of the tag
*/ */
public IntTag(int value) { public IntTag(int value) {
super(); super();
this.value = value; this.value = value;
} }
@Override @Override
public Integer getValue() { public Integer getValue() {
return value; return value;
} }
@Override @Override
public String toString() { public String toString() {
return "TAG_Int(" + value + ")"; return "TAG_Int(" + value + ")";
} }
} }

View File

@ -1,53 +1,53 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.jnbt; package com.sk89q.jnbt;
/** /**
* The {@code TAG_Long} tag. * The {@code TAG_Long} tag.
*/ */
public final class LongTag extends NumberTag { public final class LongTag extends NumberTag {
@Override @Override
public int getTypeCode() { public int getTypeCode() {
return NBTConstants.TYPE_LONG; return NBTConstants.TYPE_LONG;
} }
private final long value; private final long value;
/** /**
* Creates the tag with an empty name. * Creates the tag with an empty name.
* *
* @param value the value of the tag * @param value the value of the tag
*/ */
public LongTag(long value) { public LongTag(long value) {
super(); super();
this.value = value; this.value = value;
} }
@Override @Override
public Long getValue() { public Long getValue() {
return value; return value;
} }
@Override @Override
public String toString() { public String toString() {
return "TAG_Long(" + value + ")"; return "TAG_Long(" + value + ")";
} }
} }

View File

@ -1,93 +1,93 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.jnbt; package com.sk89q.jnbt;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
/** /**
* A class which holds constant values. * A class which holds constant values.
*/ */
public final class NBTConstants { public final class NBTConstants {
public static final Charset CHARSET = StandardCharsets.UTF_8; public static final Charset CHARSET = StandardCharsets.UTF_8;
public static final int TYPE_END = 0; public static final int TYPE_END = 0;
public static final int TYPE_BYTE = 1; public static final int TYPE_BYTE = 1;
public static final int TYPE_SHORT = 2; public static final int TYPE_SHORT = 2;
public static final int TYPE_INT = 3; public static final int TYPE_INT = 3;
public static final int TYPE_LONG = 4; public static final int TYPE_LONG = 4;
public static final int TYPE_FLOAT = 5; public static final int TYPE_FLOAT = 5;
public static final int TYPE_DOUBLE = 6; public static final int TYPE_DOUBLE = 6;
public static final int TYPE_BYTE_ARRAY = 7; public static final int TYPE_BYTE_ARRAY = 7;
public static final int TYPE_STRING = 8; public static final int TYPE_STRING = 8;
public static final int TYPE_LIST = 9; public static final int TYPE_LIST = 9;
public static final int TYPE_COMPOUND = 10; public static final int TYPE_COMPOUND = 10;
public static final int TYPE_INT_ARRAY = 11; public static final int TYPE_INT_ARRAY = 11;
public static final int TYPE_LONG_ARRAY = 12; public static final int TYPE_LONG_ARRAY = 12;
/** /**
* Default private constructor. * Default private constructor.
*/ */
private NBTConstants() { private NBTConstants() {
} }
/** /**
* Convert a type ID to its corresponding {@link Tag} class. * Convert a type ID to its corresponding {@link Tag} class.
* *
* @param id type ID * @param id type ID
* @return tag class * @return tag class
* @throws IllegalArgumentException thrown if the tag ID is not valid * @throws IllegalArgumentException thrown if the tag ID is not valid
*/ */
public static Class<? extends Tag> getClassFromType(int id) { public static Class<? extends Tag> getClassFromType(int id) {
switch (id) { switch (id) {
case TYPE_END: case TYPE_END:
return EndTag.class; return EndTag.class;
case TYPE_BYTE: case TYPE_BYTE:
return ByteTag.class; return ByteTag.class;
case TYPE_SHORT: case TYPE_SHORT:
return ShortTag.class; return ShortTag.class;
case TYPE_INT: case TYPE_INT:
return IntTag.class; return IntTag.class;
case TYPE_LONG: case TYPE_LONG:
return LongTag.class; return LongTag.class;
case TYPE_FLOAT: case TYPE_FLOAT:
return FloatTag.class; return FloatTag.class;
case TYPE_DOUBLE: case TYPE_DOUBLE:
return DoubleTag.class; return DoubleTag.class;
case TYPE_BYTE_ARRAY: case TYPE_BYTE_ARRAY:
return ByteArrayTag.class; return ByteArrayTag.class;
case TYPE_STRING: case TYPE_STRING:
return StringTag.class; return StringTag.class;
case TYPE_LIST: case TYPE_LIST:
return ListTag.class; return ListTag.class;
case TYPE_COMPOUND: case TYPE_COMPOUND:
return CompoundTag.class; return CompoundTag.class;
case TYPE_INT_ARRAY: case TYPE_INT_ARRAY:
return IntArrayTag.class; return IntArrayTag.class;
case TYPE_LONG_ARRAY: case TYPE_LONG_ARRAY:
return LongArrayTag.class; return LongArrayTag.class;
default: default:
throw new IllegalArgumentException("Unknown tag type ID of " + id); throw new IllegalArgumentException("Unknown tag type ID of " + id);
} }
} }
} }

View File

@ -1,195 +1,195 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.jnbt; package com.sk89q.jnbt;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.world.storage.InvalidFormatException; import com.sk89q.worldedit.world.storage.InvalidFormatException;
import java.util.Map; import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* A class which contains NBT-related utility methods. * A class which contains NBT-related utility methods.
* *
*/ */
public final class NBTUtils { public final class NBTUtils {
/** /**
* Default private constructor. * Default private constructor.
*/ */
private NBTUtils() { private NBTUtils() {
} }
/** /**
* Gets the type name of a tag. * Gets the type name of a tag.
* *
* @param clazz the tag class * @param clazz the tag class
* @return The type name. * @return The type name.
*/ */
public static String getTypeName(Class<? extends Tag> clazz) { public static String getTypeName(Class<? extends Tag> clazz) {
if (clazz.equals(ByteArrayTag.class)) { if (clazz.equals(ByteArrayTag.class)) {
return "TAG_Byte_Array"; return "TAG_Byte_Array";
} else if (clazz.equals(ByteTag.class)) { } else if (clazz.equals(ByteTag.class)) {
return "TAG_Byte"; return "TAG_Byte";
} else if (CompoundTag.class.isAssignableFrom(clazz)) { } else if (CompoundTag.class.isAssignableFrom(clazz)) {
return "TAG_Compound"; return "TAG_Compound";
} else if (clazz.equals(DoubleTag.class)) { } else if (clazz.equals(DoubleTag.class)) {
return "TAG_Double"; return "TAG_Double";
} else if (clazz.equals(EndTag.class)) { } else if (clazz.equals(EndTag.class)) {
return "TAG_End"; return "TAG_End";
} else if (clazz.equals(FloatTag.class)) { } else if (clazz.equals(FloatTag.class)) {
return "TAG_Float"; return "TAG_Float";
} else if (clazz.equals(IntTag.class)) { } else if (clazz.equals(IntTag.class)) {
return "TAG_Int"; return "TAG_Int";
} else if (clazz.equals(ListTag.class)) { } else if (clazz.equals(ListTag.class)) {
return "TAG_List"; return "TAG_List";
} else if (clazz.equals(LongTag.class)) { } else if (clazz.equals(LongTag.class)) {
return "TAG_Long"; return "TAG_Long";
} else if (clazz.equals(ShortTag.class)) { } else if (clazz.equals(ShortTag.class)) {
return "TAG_Short"; return "TAG_Short";
} else if (clazz.equals(StringTag.class)) { } else if (clazz.equals(StringTag.class)) {
return "TAG_String"; return "TAG_String";
} else if (clazz.equals(IntArrayTag.class)) { } else if (clazz.equals(IntArrayTag.class)) {
return "TAG_Int_Array"; return "TAG_Int_Array";
} else if (clazz.equals(LongArrayTag.class)) { } else if (clazz.equals(LongArrayTag.class)) {
return "TAG_Long_Array"; return "TAG_Long_Array";
} else { } else {
throw new IllegalArgumentException("Invalid tag class (" throw new IllegalArgumentException("Invalid tag class ("
+ clazz.getName() + ")."); + clazz.getName() + ").");
} }
} }
/** /**
* Gets the type code of a tag class. * Gets the type code of a tag class.
* *
* @param clazz the tag class * @param clazz the tag class
* @return The type code. * @return The type code.
* @throws IllegalArgumentException if the tag class is invalid. * @throws IllegalArgumentException if the tag class is invalid.
*/ */
public static int getTypeCode(Class<? extends Tag> clazz) { public static int getTypeCode(Class<? extends Tag> clazz) {
if (clazz.equals(ByteArrayTag.class)) { if (clazz.equals(ByteArrayTag.class)) {
return NBTConstants.TYPE_BYTE_ARRAY; return NBTConstants.TYPE_BYTE_ARRAY;
} else if (clazz.equals(ByteTag.class)) { } else if (clazz.equals(ByteTag.class)) {
return NBTConstants.TYPE_BYTE; return NBTConstants.TYPE_BYTE;
} else if (CompoundTag.class.isAssignableFrom(clazz)) { } else if (CompoundTag.class.isAssignableFrom(clazz)) {
return NBTConstants.TYPE_COMPOUND; return NBTConstants.TYPE_COMPOUND;
} else if (clazz.equals(DoubleTag.class)) { } else if (clazz.equals(DoubleTag.class)) {
return NBTConstants.TYPE_DOUBLE; return NBTConstants.TYPE_DOUBLE;
} else if (clazz.equals(EndTag.class)) { } else if (clazz.equals(EndTag.class)) {
return NBTConstants.TYPE_END; return NBTConstants.TYPE_END;
} else if (clazz.equals(FloatTag.class)) { } else if (clazz.equals(FloatTag.class)) {
return NBTConstants.TYPE_FLOAT; return NBTConstants.TYPE_FLOAT;
} else if (clazz.equals(IntTag.class)) { } else if (clazz.equals(IntTag.class)) {
return NBTConstants.TYPE_INT; return NBTConstants.TYPE_INT;
} else if (clazz.equals(ListTag.class)) { } else if (clazz.equals(ListTag.class)) {
return NBTConstants.TYPE_LIST; return NBTConstants.TYPE_LIST;
} else if (clazz.equals(LongTag.class)) { } else if (clazz.equals(LongTag.class)) {
return NBTConstants.TYPE_LONG; return NBTConstants.TYPE_LONG;
} else if (clazz.equals(ShortTag.class)) { } else if (clazz.equals(ShortTag.class)) {
return NBTConstants.TYPE_SHORT; return NBTConstants.TYPE_SHORT;
} else if (clazz.equals(StringTag.class)) { } else if (clazz.equals(StringTag.class)) {
return NBTConstants.TYPE_STRING; return NBTConstants.TYPE_STRING;
} else if (clazz.equals(IntArrayTag.class)) { } else if (clazz.equals(IntArrayTag.class)) {
return NBTConstants.TYPE_INT_ARRAY; return NBTConstants.TYPE_INT_ARRAY;
} else if (clazz.equals(LongArrayTag.class)) { } else if (clazz.equals(LongArrayTag.class)) {
return NBTConstants.TYPE_LONG_ARRAY; return NBTConstants.TYPE_LONG_ARRAY;
} else { } else {
throw new IllegalArgumentException("Invalid tag class (" throw new IllegalArgumentException("Invalid tag class ("
+ clazz.getName() + ")."); + clazz.getName() + ").");
} }
} }
/** /**
* Gets the class of a type of tag. * Gets the class of a type of tag.
* *
* @param type the type * @param type the type
* @return The class. * @return The class.
* @throws IllegalArgumentException if the tag type is invalid. * @throws IllegalArgumentException if the tag type is invalid.
*/ */
public static Class<? extends Tag> getTypeClass(int type) { public static Class<? extends Tag> getTypeClass(int type) {
switch (type) { switch (type) {
case NBTConstants.TYPE_END: case NBTConstants.TYPE_END:
return EndTag.class; return EndTag.class;
case NBTConstants.TYPE_BYTE: case NBTConstants.TYPE_BYTE:
return ByteTag.class; return ByteTag.class;
case NBTConstants.TYPE_SHORT: case NBTConstants.TYPE_SHORT:
return ShortTag.class; return ShortTag.class;
case NBTConstants.TYPE_INT: case NBTConstants.TYPE_INT:
return IntTag.class; return IntTag.class;
case NBTConstants.TYPE_LONG: case NBTConstants.TYPE_LONG:
return LongTag.class; return LongTag.class;
case NBTConstants.TYPE_FLOAT: case NBTConstants.TYPE_FLOAT:
return FloatTag.class; return FloatTag.class;
case NBTConstants.TYPE_DOUBLE: case NBTConstants.TYPE_DOUBLE:
return DoubleTag.class; return DoubleTag.class;
case NBTConstants.TYPE_BYTE_ARRAY: case NBTConstants.TYPE_BYTE_ARRAY:
return ByteArrayTag.class; return ByteArrayTag.class;
case NBTConstants.TYPE_STRING: case NBTConstants.TYPE_STRING:
return StringTag.class; return StringTag.class;
case NBTConstants.TYPE_LIST: case NBTConstants.TYPE_LIST:
return ListTag.class; return ListTag.class;
case NBTConstants.TYPE_COMPOUND: case NBTConstants.TYPE_COMPOUND:
return CompoundTag.class; return CompoundTag.class;
case NBTConstants.TYPE_INT_ARRAY: case NBTConstants.TYPE_INT_ARRAY:
return IntArrayTag.class; return IntArrayTag.class;
case NBTConstants.TYPE_LONG_ARRAY: case NBTConstants.TYPE_LONG_ARRAY:
return LongArrayTag.class; return LongArrayTag.class;
default: default:
throw new IllegalArgumentException("Invalid tag type : " + type throw new IllegalArgumentException("Invalid tag type : " + type
+ "."); + ".");
} }
} }
/** /**
* Read a vector from a list tag containing ideally three values: the * Read a vector from a list tag containing ideally three values: the
* X, Y, and Z components. * X, Y, and Z components.
* *
* <p>For values that are unavailable, their values will be 0.</p> * <p>For values that are unavailable, their values will be 0.</p>
* *
* @param listTag the list tag * @param listTag the list tag
* @return a vector * @return a vector
*/ */
public static Vector3 toVector(ListTag listTag) { public static Vector3 toVector(ListTag listTag) {
checkNotNull(listTag); checkNotNull(listTag);
return Vector3.at(listTag.asDouble(0), listTag.asDouble(1), listTag.asDouble(2)); return Vector3.at(listTag.asDouble(0), listTag.asDouble(1), listTag.asDouble(2));
} }
/** /**
* Get child tag of a NBT structure. * Get child tag of a NBT structure.
* *
* @param items the map to read from * @param items the map to read from
* @param key the key to look for * @param key the key to look for
* @param expected the expected NBT class type * @param expected the expected NBT class type
* @return child tag * @return child tag
* @throws InvalidFormatException if the format of the items is invalid * @throws InvalidFormatException if the format of the items is invalid
*/ */
public static <T extends Tag> T getChildTag(Map<String, Tag> items, String key, Class<T> expected) throws InvalidFormatException { public static <T extends Tag> T getChildTag(Map<String, Tag> items, String key, Class<T> expected) throws InvalidFormatException {
if (!items.containsKey(key)) { if (!items.containsKey(key)) {
throw new InvalidFormatException("Missing a \"" + key + "\" tag"); throw new InvalidFormatException("Missing a \"" + key + "\" tag");
} }
Tag tag = items.get(key); Tag tag = items.get(key);
if (!expected.isInstance(tag)) { if (!expected.isInstance(tag)) {
throw new InvalidFormatException(key + " tag is not of tag type " + expected.getName()); throw new InvalidFormatException(key + " tag is not of tag type " + expected.getName());
} }
return expected.cast(tag); return expected.cast(tag);
} }
} }

View File

@ -1,53 +1,53 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.jnbt; package com.sk89q.jnbt;
/** /**
* The {@code TAG_Short} tag. * The {@code TAG_Short} tag.
*/ */
public final class ShortTag extends NumberTag { public final class ShortTag extends NumberTag {
@Override @Override
public int getTypeCode() { public int getTypeCode() {
return NBTConstants.TYPE_SHORT; return NBTConstants.TYPE_SHORT;
} }
private final short value; private final short value;
/** /**
* Creates the tag with an empty name. * Creates the tag with an empty name.
* *
* @param value the value of the tag * @param value the value of the tag
*/ */
public ShortTag(short value) { public ShortTag(short value) {
super(); super();
this.value = value; this.value = value;
} }
@Override @Override
public Short getValue() { public Short getValue() {
return value; return value;
} }
@Override @Override
public String toString() { public String toString() {
return "TAG_Short(" + value + ")"; return "TAG_Short(" + value + ")";
} }
} }

View File

@ -1,57 +1,57 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.jnbt; package com.sk89q.jnbt;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* The {@code TAG_String} tag. * The {@code TAG_String} tag.
*/ */
public final class StringTag extends Tag { public final class StringTag extends Tag {
@Override @Override
public int getTypeCode() { public int getTypeCode() {
return NBTConstants.TYPE_STRING; return NBTConstants.TYPE_STRING;
} }
private final String value; private final String value;
/** /**
* Creates the tag with an empty name. * Creates the tag with an empty name.
* *
* @param value the value of the tag * @param value the value of the tag
*/ */
public StringTag(String value) { public StringTag(String value) {
super(); super();
checkNotNull(value); checkNotNull(value);
this.value = value; this.value = value;
} }
@Override @Override
public String getValue() { public String getValue() {
return value; return value;
} }
@Override @Override
public String toString() { public String toString() {
return "TAG_String(" + value + ")"; return "TAG_String(" + value + ")";
} }
} }

View File

@ -1,40 +1,40 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.jnbt; package com.sk89q.jnbt;
/** /**
* Represents a NBT tag. * Represents a NBT tag.
*/ */
public abstract class Tag { public abstract class Tag {
/** /**
* Gets the value of this tag. * Gets the value of this tag.
* *
* @return the value * @return the value
*/ */
public abstract Object getValue(); public abstract Object getValue();
public Object toRaw() { public Object toRaw() {
return getValue(); return getValue();
} }
public abstract int getTypeCode(); public abstract int getTypeCode();
} }

View File

@ -1,99 +1,99 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.minecraft.util.commands; package com.sk89q.minecraft.util.commands;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
/** /**
* This annotation indicates a command. Methods should be marked with this * This annotation indicates a command. Methods should be marked with this
* annotation to tell {@link CommandsManager} that the method is a command. * annotation to tell {@link CommandsManager} that the method is a command.
* Note that the method name can actually be anything. * Note that the method name can actually be anything.
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Command { public @interface Command {
/** /**
* A list of aliases for the command. The first alias is the most * A list of aliases for the command. The first alias is the most
* important -- it is the main name of the command. (The method name * important -- it is the main name of the command. (The method name
* is never used for anything). * is never used for anything).
* *
* @return Aliases for a command * @return Aliases for a command
*/ */
String[] aliases(); String[] aliases();
/** /**
* Usage instruction. Example text for usage could be * Usage instruction. Example text for usage could be
* {@code [-h harps] [name] [message]}. * {@code [-h harps] [name] [message]}.
* *
* @return Usage instructions for a command * @return Usage instructions for a command
*/ */
String usage() default ""; String usage() default "";
/** /**
* @return A short description for the command. * @return A short description for the command.
*/ */
String desc(); String desc();
/** /**
* The minimum number of arguments. This should be 0 or above. * The minimum number of arguments. This should be 0 or above.
* *
* @return the minimum number of arguments * @return the minimum number of arguments
*/ */
int min() default 0; int min() default 0;
/** /**
* The maximum number of arguments. Use -1 for an unlimited number * The maximum number of arguments. Use -1 for an unlimited number
* of arguments. * of arguments.
* *
* @return the maximum number of arguments * @return the maximum number of arguments
*/ */
int max() default -1; int max() default -1;
/** /**
* Flags allow special processing for flags such as -h in the command, * Flags allow special processing for flags such as -h in the command,
* allowing users to easily turn on a flag. This is a string with * allowing users to easily turn on a flag. This is a string with
* each character being a flag. Use A-Z and a-z as possible flags. * each character being a flag. Use A-Z and a-z as possible flags.
* Appending a flag with a : makes the flag character before a value flag, * Appending a flag with a : makes the flag character before a value flag,
* meaning that if it is given it must have a value * meaning that if it is given it must have a value
* *
* @return Flags matching a-zA-Z * @return Flags matching a-zA-Z
*/ */
String flags() default ""; String flags() default "";
/** /**
* @return A long description for the command. * @return A long description for the command.
*/ */
String help() default ""; String help() default "";
/** /**
* Get whether any flag can be used. * Get whether any flag can be used.
* *
* @return true if so * @return true if so
*/ */
boolean anyFlags() default false; boolean anyFlags() default false;
/** /**
* Should the command be queued * Should the command be queued
* @return true if so * @return true if so
*/ */
boolean queued() default true; boolean queued() default true;
} }

View File

@ -1,362 +1,362 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.minecraft.util.commands; package com.sk89q.minecraft.util.commands;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
public class CommandContext { public class CommandContext {
protected final String command; protected final String command;
protected final List<String> parsedArgs; protected final List<String> parsedArgs;
protected final List<Integer> originalArgIndices; protected final List<Integer> originalArgIndices;
protected final String[] originalArgs; protected final String[] originalArgs;
protected final Set<Character> booleanFlags = new HashSet<>(); protected final Set<Character> booleanFlags = new HashSet<>();
protected final Map<Character, String> valueFlags = new HashMap<>(); protected final Map<Character, String> valueFlags = new HashMap<>();
protected final SuggestionContext suggestionContext; protected final SuggestionContext suggestionContext;
protected final CommandLocals locals; protected final CommandLocals locals;
public static String[] split(String args) { public static String[] split(String args) {
return args.split(" ", -1); return args.split(" ", -1);
} }
public CommandContext(String args) throws CommandException { public CommandContext(String args) throws CommandException {
this(args.split(" ", -1), null); this(args.split(" ", -1), null);
} }
public CommandContext(String[] args) throws CommandException { public CommandContext(String[] args) throws CommandException {
this(args, null); this(args, null);
} }
public CommandContext(String args, Set<Character> valueFlags) throws CommandException { public CommandContext(String args, Set<Character> valueFlags) throws CommandException {
this(args.split(" ", -1), valueFlags); this(args.split(" ", -1), valueFlags);
} }
public CommandContext(String args, Set<Character> valueFlags, boolean allowHangingFlag) public CommandContext(String args, Set<Character> valueFlags, boolean allowHangingFlag)
throws CommandException { throws CommandException {
this(args.split(" ", -1), valueFlags, allowHangingFlag, new CommandLocals()); this(args.split(" ", -1), valueFlags, allowHangingFlag, new CommandLocals());
} }
public CommandContext(String[] args, Set<Character> valueFlags) throws CommandException { public CommandContext(String[] args, Set<Character> valueFlags) throws CommandException {
this(args, valueFlags, false, null); this(args, valueFlags, false, null);
} }
/** /**
* Parse the given array of arguments. * Parse the given array of arguments.
* *
* <p>Empty arguments are removed from the list of arguments.</p> * <p>Empty arguments are removed from the list of arguments.</p>
* *
* @param args an array with arguments * @param args an array with arguments
* @param valueFlags a set containing all value flags (pass null to disable value flag parsing) * @param valueFlags a set containing all value flags (pass null to disable value flag parsing)
* @param allowHangingFlag true if hanging flags are allowed * @param allowHangingFlag true if hanging flags are allowed
* @param locals the locals, null to create empty one * @param locals the locals, null to create empty one
* @throws CommandException thrown on a parsing error * @throws CommandException thrown on a parsing error
*/ */
public CommandContext(String[] args, Set<Character> valueFlags, boolean allowHangingFlag, CommandLocals locals) throws CommandException { public CommandContext(String[] args, Set<Character> valueFlags, boolean allowHangingFlag, CommandLocals locals) throws CommandException {
this(args, valueFlags, allowHangingFlag, locals, true); this(args, valueFlags, allowHangingFlag, locals, true);
} }
/** /**
* Parse the given array of arguments. * Parse the given array of arguments.
* *
* <p>Empty arguments are removed from the list of arguments.</p> * <p>Empty arguments are removed from the list of arguments.</p>
* *
* @param args an array with arguments * @param args an array with arguments
* @param valueFlags a set containing all value flags (pass null to disable value flag parsing) * @param valueFlags a set containing all value flags (pass null to disable value flag parsing)
* @param allowHangingFlag true if hanging flags are allowed * @param allowHangingFlag true if hanging flags are allowed
* @param locals the locals, null to create empty one * @param locals the locals, null to create empty one
* @param parseFlags where to parse flags * @param parseFlags where to parse flags
* @throws CommandException thrown on a parsing error * @throws CommandException thrown on a parsing error
*/ */
public CommandContext(String[] args, Set<Character> valueFlags, boolean allowHangingFlag, CommandLocals locals, boolean parseFlags) throws CommandException { public CommandContext(String[] args, Set<Character> valueFlags, boolean allowHangingFlag, CommandLocals locals, boolean parseFlags) throws CommandException {
if (valueFlags == null) { if (valueFlags == null) {
valueFlags = Collections.emptySet(); valueFlags = Collections.emptySet();
} }
originalArgs = args; originalArgs = args;
command = args[0]; command = args[0];
this.locals = locals != null ? locals : new CommandLocals(); this.locals = locals != null ? locals : new CommandLocals();
boolean isHanging = false; boolean isHanging = false;
SuggestionContext suggestionContext = SuggestionContext.hangingValue(); SuggestionContext suggestionContext = SuggestionContext.hangingValue();
// Eliminate empty args and combine multiword args first // Eliminate empty args and combine multiword args first
List<Integer> argIndexList = new ArrayList<>(args.length); List<Integer> argIndexList = new ArrayList<>(args.length);
List<String> argList = new ArrayList<>(args.length); List<String> argList = new ArrayList<>(args.length);
for (int i = 1; i < args.length; ++i) { for (int i = 1; i < args.length; ++i) {
isHanging = false; isHanging = false;
String arg = args[i]; String arg = args[i];
if (arg.isEmpty()) { if (arg.isEmpty()) {
isHanging = true; isHanging = true;
continue; continue;
} }
argIndexList.add(i); argIndexList.add(i);
switch (arg.charAt(0)) { switch (arg.charAt(0)) {
case '\'': case '\'':
case '"': case '"':
final StringBuilder build = new StringBuilder(); final StringBuilder build = new StringBuilder();
final char quotedChar = arg.charAt(0); final char quotedChar = arg.charAt(0);
int endIndex; int endIndex;
for (endIndex = i; endIndex < args.length; ++endIndex) { for (endIndex = i; endIndex < args.length; ++endIndex) {
final String arg2 = args[endIndex]; final String arg2 = args[endIndex];
if (arg2.charAt(arg2.length() - 1) == quotedChar && arg2.length() > 1) { if (arg2.charAt(arg2.length() - 1) == quotedChar && arg2.length() > 1) {
if (endIndex != i) build.append(' '); if (endIndex != i) build.append(' ');
build.append(arg2.substring(endIndex == i ? 1 : 0, arg2.length() - 1)); build.append(arg2.substring(endIndex == i ? 1 : 0, arg2.length() - 1));
break; break;
} else if (endIndex == i) { } else if (endIndex == i) {
build.append(arg2.substring(1)); build.append(arg2.substring(1));
} else { } else {
build.append(' ').append(arg2); build.append(' ').append(arg2);
} }
} }
if (endIndex < args.length) { if (endIndex < args.length) {
arg = build.toString(); arg = build.toString();
i = endIndex; i = endIndex;
} }
// In case there is an empty quoted string // In case there is an empty quoted string
if (arg.isEmpty()) { if (arg.isEmpty()) {
continue; continue;
} }
// else raise exception about hanging quotes? // else raise exception about hanging quotes?
} }
argList.add(arg); argList.add(arg);
} }
// Then flags // Then flags
this.originalArgIndices = new ArrayList<>(argIndexList.size()); this.originalArgIndices = new ArrayList<>(argIndexList.size());
this.parsedArgs = new ArrayList<>(argList.size()); this.parsedArgs = new ArrayList<>(argList.size());
if (parseFlags) { if (parseFlags) {
for (int nextArg = 0; nextArg < argList.size(); ) { for (int nextArg = 0; nextArg < argList.size(); ) {
// Fetch argument // Fetch argument
String arg = argList.get(nextArg++); String arg = argList.get(nextArg++);
suggestionContext = SuggestionContext.hangingValue(); suggestionContext = SuggestionContext.hangingValue();
// Not a flag? // Not a flag?
if (arg.charAt(0) != '-' || arg.length() == 1 || !arg.matches("^-[a-zA-Z\\?]+$")) { if (arg.charAt(0) != '-' || arg.length() == 1 || !arg.matches("^-[a-zA-Z\\?]+$")) {
if (!isHanging) { if (!isHanging) {
suggestionContext = SuggestionContext.lastValue(); suggestionContext = SuggestionContext.lastValue();
} }
originalArgIndices.add(argIndexList.get(nextArg - 1)); originalArgIndices.add(argIndexList.get(nextArg - 1));
parsedArgs.add(arg); parsedArgs.add(arg);
continue; continue;
} }
// Handle flag parsing terminator -- // Handle flag parsing terminator --
if (arg.equals("--")) { if (arg.equals("--")) {
while (nextArg < argList.size()) { while (nextArg < argList.size()) {
originalArgIndices.add(argIndexList.get(nextArg)); originalArgIndices.add(argIndexList.get(nextArg));
parsedArgs.add(argList.get(nextArg++)); parsedArgs.add(argList.get(nextArg++));
} }
break; break;
} }
// Go through the flag characters // Go through the flag characters
for (int i = 1; i < arg.length(); ++i) { for (int i = 1; i < arg.length(); ++i) {
char flagName = arg.charAt(i); char flagName = arg.charAt(i);
if (valueFlags.contains(flagName)) { if (valueFlags.contains(flagName)) {
if (this.valueFlags.containsKey(flagName)) { if (this.valueFlags.containsKey(flagName)) {
throw new CommandException("Value flag '" + flagName + "' already given"); throw new CommandException("Value flag '" + flagName + "' already given");
} }
if (nextArg >= argList.size()) { if (nextArg >= argList.size()) {
if (allowHangingFlag) { if (allowHangingFlag) {
suggestionContext = SuggestionContext.flag(flagName); suggestionContext = SuggestionContext.flag(flagName);
break; break;
} else { } else {
throw new CommandException("No value specified for the '-" + flagName + "' flag."); throw new CommandException("No value specified for the '-" + flagName + "' flag.");
} }
} }
// If it is a value flag, read another argument and add it // If it is a value flag, read another argument and add it
this.valueFlags.put(flagName, argList.get(nextArg++)); this.valueFlags.put(flagName, argList.get(nextArg++));
if (!isHanging) { if (!isHanging) {
suggestionContext = SuggestionContext.flag(flagName); suggestionContext = SuggestionContext.flag(flagName);
} }
} else { } else {
booleanFlags.add(flagName); booleanFlags.add(flagName);
} }
} }
} }
} else { } else {
for (int i = 0; i < argList.size(); i++) { for (int i = 0; i < argList.size(); i++) {
String arg = argList.get(i); String arg = argList.get(i);
originalArgIndices.add(argIndexList.get(i)); originalArgIndices.add(argIndexList.get(i));
parsedArgs.add(arg); parsedArgs.add(arg);
} }
} }
this.suggestionContext = suggestionContext; this.suggestionContext = suggestionContext;
} }
public SuggestionContext getSuggestionContext() { public SuggestionContext getSuggestionContext() {
return suggestionContext; return suggestionContext;
} }
public String getCommand() { public String getCommand() {
return command; return command;
} }
public boolean matches(String command) { public boolean matches(String command) {
return this.command.equalsIgnoreCase(command); return this.command.equalsIgnoreCase(command);
} }
public String getString(int index) { public String getString(int index) {
return parsedArgs.get(index); return parsedArgs.get(index);
} }
public String getString(int index, String def) { public String getString(int index, String def) {
return index < parsedArgs.size() ? parsedArgs.get(index) : def; return index < parsedArgs.size() ? parsedArgs.get(index) : def;
} }
public String getJoinedStrings(int initialIndex) { public String getJoinedStrings(int initialIndex) {
initialIndex = originalArgIndices.get(initialIndex); initialIndex = originalArgIndices.get(initialIndex);
StringBuilder buffer = new StringBuilder(originalArgs[initialIndex]); StringBuilder buffer = new StringBuilder(originalArgs[initialIndex]);
for (int i = initialIndex + 1; i < originalArgs.length; ++i) { for (int i = initialIndex + 1; i < originalArgs.length; ++i) {
buffer.append(" ").append(originalArgs[i]); buffer.append(" ").append(originalArgs[i]);
} }
return buffer.toString(); return buffer.toString();
} }
public String getRemainingString(int start) { public String getRemainingString(int start) {
return getString(start, parsedArgs.size() - 1); return getString(start, parsedArgs.size() - 1);
} }
public String getString(int start, int end) { public String getString(int start, int end) {
StringBuilder buffer = new StringBuilder(parsedArgs.get(start)); StringBuilder buffer = new StringBuilder(parsedArgs.get(start));
for (int i = start + 1; i < end + 1; ++i) { for (int i = start + 1; i < end + 1; ++i) {
buffer.append(" ").append(parsedArgs.get(i)); buffer.append(" ").append(parsedArgs.get(i));
} }
return buffer.toString(); return buffer.toString();
} }
public int getInteger(int index) throws NumberFormatException { public int getInteger(int index) throws NumberFormatException {
return Integer.parseInt(parsedArgs.get(index)); return Integer.parseInt(parsedArgs.get(index));
} }
public int getInteger(int index, int def) throws NumberFormatException { public int getInteger(int index, int def) throws NumberFormatException {
return index < parsedArgs.size() ? Integer.parseInt(parsedArgs.get(index)) : def; return index < parsedArgs.size() ? Integer.parseInt(parsedArgs.get(index)) : def;
} }
public double getDouble(int index) throws NumberFormatException { public double getDouble(int index) throws NumberFormatException {
return Double.parseDouble(parsedArgs.get(index)); return Double.parseDouble(parsedArgs.get(index));
} }
public double getDouble(int index, double def) throws NumberFormatException { public double getDouble(int index, double def) throws NumberFormatException {
return index < parsedArgs.size() ? Double.parseDouble(parsedArgs.get(index)) : def; return index < parsedArgs.size() ? Double.parseDouble(parsedArgs.get(index)) : def;
} }
public String[] getSlice(int index) { public String[] getSlice(int index) {
String[] slice = new String[originalArgs.length - index]; String[] slice = new String[originalArgs.length - index];
System.arraycopy(originalArgs, index, slice, 0, originalArgs.length - index); System.arraycopy(originalArgs, index, slice, 0, originalArgs.length - index);
return slice; return slice;
} }
public String[] getPaddedSlice(int index, int padding) { public String[] getPaddedSlice(int index, int padding) {
String[] slice = new String[originalArgs.length - index + padding]; String[] slice = new String[originalArgs.length - index + padding];
System.arraycopy(originalArgs, index, slice, padding, originalArgs.length - index); System.arraycopy(originalArgs, index, slice, padding, originalArgs.length - index);
return slice; return slice;
} }
public String[] getParsedSlice(int index) { public String[] getParsedSlice(int index) {
String[] slice = new String[parsedArgs.size() - index]; String[] slice = new String[parsedArgs.size() - index];
System.arraycopy(parsedArgs.toArray(new String[parsedArgs.size()]), index, slice, 0, parsedArgs.size() - index); System.arraycopy(parsedArgs.toArray(new String[parsedArgs.size()]), index, slice, 0, parsedArgs.size() - index);
return slice; return slice;
} }
public String[] getParsedPaddedSlice(int index, int padding) { public String[] getParsedPaddedSlice(int index, int padding) {
String[] slice = new String[parsedArgs.size() - index + padding]; String[] slice = new String[parsedArgs.size() - index + padding];
System.arraycopy(parsedArgs.toArray(new String[parsedArgs.size()]), index, slice, padding, parsedArgs.size() - index); System.arraycopy(parsedArgs.toArray(new String[parsedArgs.size()]), index, slice, padding, parsedArgs.size() - index);
return slice; return slice;
} }
public boolean hasFlag(char ch) { public boolean hasFlag(char ch) {
return booleanFlags.contains(ch) || valueFlags.containsKey(ch); return booleanFlags.contains(ch) || valueFlags.containsKey(ch);
} }
public Set<Character> getFlags() { public Set<Character> getFlags() {
return booleanFlags; return booleanFlags;
} }
public Map<Character, String> getValueFlags() { public Map<Character, String> getValueFlags() {
return valueFlags; return valueFlags;
} }
public String getFlag(char ch) { public String getFlag(char ch) {
return valueFlags.get(ch); return valueFlags.get(ch);
} }
public String getFlag(char ch, String def) { public String getFlag(char ch, String def) {
final String value = valueFlags.get(ch); final String value = valueFlags.get(ch);
if (value == null) { if (value == null) {
return def; return def;
} }
return value; return value;
} }
public int getFlagInteger(char ch) throws NumberFormatException { public int getFlagInteger(char ch) throws NumberFormatException {
return Integer.parseInt(valueFlags.get(ch)); return Integer.parseInt(valueFlags.get(ch));
} }
public int getFlagInteger(char ch, int def) throws NumberFormatException { public int getFlagInteger(char ch, int def) throws NumberFormatException {
final String value = valueFlags.get(ch); final String value = valueFlags.get(ch);
if (value == null) { if (value == null) {
return def; return def;
} }
return Integer.parseInt(value); return Integer.parseInt(value);
} }
public double getFlagDouble(char ch) throws NumberFormatException { public double getFlagDouble(char ch) throws NumberFormatException {
return Double.parseDouble(valueFlags.get(ch)); return Double.parseDouble(valueFlags.get(ch));
} }
public double getFlagDouble(char ch, double def) throws NumberFormatException { public double getFlagDouble(char ch, double def) throws NumberFormatException {
final String value = valueFlags.get(ch); final String value = valueFlags.get(ch);
if (value == null) { if (value == null) {
return def; return def;
} }
return Double.parseDouble(value); return Double.parseDouble(value);
} }
public int argsLength() { public int argsLength() {
return parsedArgs.size(); return parsedArgs.size();
} }
public CommandLocals getLocals() { public CommandLocals getLocals() {
return locals; return locals;
} }
} }

View File

@ -1,83 +1,83 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.minecraft.util.commands; package com.sk89q.minecraft.util.commands;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
public class CommandException extends Exception { public class CommandException extends Exception {
private List<String> commandStack = new ArrayList<>(); private List<String> commandStack = new ArrayList<>();
public CommandException() { public CommandException() {
super(); super();
} }
public CommandException(String message) { public CommandException(String message) {
super(message); super(message);
} }
public CommandException(String message, Throwable t) { public CommandException(String message, Throwable t) {
super(message, t); super(message, t);
} }
public CommandException(Throwable t) { public CommandException(Throwable t) {
super(t); super(t);
} }
public void prependStack(String name) { public void prependStack(String name) {
commandStack.add(name); commandStack.add(name);
} }
/** /**
* Gets the command that was called, which will include the sub-command * Gets the command that was called, which will include the sub-command
* (i.e. "/br sphere"). * (i.e. "/br sphere").
* *
* @param prefix the command shebang character (such as "/") -- may be empty * @param prefix the command shebang character (such as "/") -- may be empty
* @param spacedSuffix a suffix to put at the end (optional) -- may be null * @param spacedSuffix a suffix to put at the end (optional) -- may be null
* @return the command that was used * @return the command that was used
*/ */
public String getCommandUsed(String prefix, @Nullable String spacedSuffix) { public String getCommandUsed(String prefix, @Nullable String spacedSuffix) {
checkNotNull(prefix); checkNotNull(prefix);
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
if (prefix != null) { if (prefix != null) {
builder.append(prefix); builder.append(prefix);
} }
ListIterator<String> li = commandStack.listIterator(commandStack.size()); ListIterator<String> li = commandStack.listIterator(commandStack.size());
while (li.hasPrevious()) { while (li.hasPrevious()) {
if (li.previousIndex() != commandStack.size() - 1) { if (li.previousIndex() != commandStack.size() - 1) {
builder.append(" "); builder.append(" ");
} }
builder.append(li.previous()); builder.append(li.previous());
} }
if (spacedSuffix != null) { if (spacedSuffix != null) {
if (builder.length() > 0) { if (builder.length() > 0) {
builder.append(" "); builder.append(" ");
} }
builder.append(spacedSuffix); builder.append(spacedSuffix);
} }
return builder.toString().trim(); return builder.toString().trim();
} }
} }

View File

@ -1,39 +1,39 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.minecraft.util.commands; package com.sk89q.minecraft.util.commands;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
/** /**
* Indicates a list of permissions that should be checked. * Indicates a list of permissions that should be checked.
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface CommandPermissions { public @interface CommandPermissions {
/** /**
* A list of permissions. Only one permission has to be met * A list of permissions. Only one permission has to be met
* for the command to be permitted. * for the command to be permitted.
* *
* @return a list of permissions strings * @return a list of permissions strings
*/ */
String[] value(); String[] value();
} }

View File

@ -1,27 +1,27 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.minecraft.util.commands; package com.sk89q.minecraft.util.commands;
/** /**
* Thrown when not enough permissions are satisfied. * Thrown when not enough permissions are satisfied.
*/ */
public class CommandPermissionsException extends CommandException { public class CommandPermissionsException extends CommandException {
} }

View File

@ -1,34 +1,34 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.minecraft.util.commands; package com.sk89q.minecraft.util.commands;
public class CommandUsageException extends CommandException { public class CommandUsageException extends CommandException {
protected String usage; protected String usage;
public CommandUsageException(String message, String usage) { public CommandUsageException(String message, String usage) {
super(message); super(message);
this.usage = usage; this.usage = usage;
} }
public String getUsage() { public String getUsage() {
return usage; return usage;
} }
} }

View File

@ -1,31 +1,31 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.minecraft.util.commands; package com.sk89q.minecraft.util.commands;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
/** /**
* This annotation indicates that a command can be used from the console. * This annotation indicates that a command can be used from the console.
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Console { public @interface Console {
} }

View File

@ -1,40 +1,40 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.minecraft.util.commands; package com.sk89q.minecraft.util.commands;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
/** /**
* Constructs new instances. * Constructs new instances.
*/ */
public interface Injector { public interface Injector {
/** /**
* Constructs a new instance of the given class. * Constructs a new instance of the given class.
* *
* @param cls class * @param cls class
* @return object * @return object
* @throws IllegalAccessException thrown on injection fault * @throws IllegalAccessException thrown on injection fault
* @throws InstantiationException thrown on injection fault * @throws InstantiationException thrown on injection fault
* @throws InvocationTargetException thrown on injection fault * @throws InvocationTargetException thrown on injection fault
*/ */
Object getInstance(Class<?> cls) throws InvocationTargetException, IllegalAccessException, InstantiationException; Object getInstance(Class<?> cls) throws InvocationTargetException, IllegalAccessException, InstantiationException;
} }

View File

@ -1,28 +1,28 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.minecraft.util.commands; package com.sk89q.minecraft.util.commands;
public class MissingNestedCommandException extends CommandUsageException { public class MissingNestedCommandException extends CommandUsageException {
public MissingNestedCommandException(String message, String usage) { public MissingNestedCommandException(String message, String usage) {
super(message, usage); super(message, usage);
} }
} }

View File

@ -1,50 +1,50 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.minecraft.util.commands; package com.sk89q.minecraft.util.commands;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
/** /**
* Indicates a nested command. Mark methods with this annotation to tell * Indicates a nested command. Mark methods with this annotation to tell
* {@link CommandsManager} that a method is merely a shell for child * {@link CommandsManager} that a method is merely a shell for child
* commands. Note that the body of a method marked with this annotation * commands. Note that the body of a method marked with this annotation
* will never called. Additionally, not all fields of {@link Command} apply * will never called. Additionally, not all fields of {@link Command} apply
* when it is used in conjunction with this annotation, although both * when it is used in conjunction with this annotation, although both
* are still required. * are still required.
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface NestedCommand { public @interface NestedCommand {
/** /**
* A list of classes with the child commands. * A list of classes with the child commands.
* *
* @return a list of classes * @return a list of classes
*/ */
Class<?>[] value(); Class<?>[] value();
/** /**
* If set to true it will execute the body of the tagged method. * If set to true it will execute the body of the tagged method.
* *
* @return true to execute the body of the annotated method * @return true to execute the body of the annotated method
*/ */
boolean executeBody() default false; boolean executeBody() default false;
} }

View File

@ -1,24 +1,24 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.minecraft.util.commands; package com.sk89q.minecraft.util.commands;
public class UnhandledCommandException extends CommandException { public class UnhandledCommandException extends CommandException {
} }

View File

@ -1,28 +1,28 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.minecraft.util.commands; package com.sk89q.minecraft.util.commands;
public class WrappedCommandException extends CommandException { public class WrappedCommandException extends CommandException {
public WrappedCommandException(Throwable t) { public WrappedCommandException(Throwable t) {
super(t); super(t);
} }
} }

View File

@ -1,369 +1,369 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.util; package com.sk89q.util;
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.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
/** /**
* String utilities. * String utilities.
*/ */
public final class StringUtil { public final class StringUtil {
private StringUtil() { private StringUtil() {
} }
/** /**
* Trim a string if it is longer than a certain length. * Trim a string if it is longer than a certain length.
* *
* @param str the string * @param str the string
* @param len the length to trim to * @param len the length to trim to
* @return a new string * @return a new string
*/ */
public static String trimLength(String str, int len) { public static String trimLength(String str, int len) {
if (str.length() > len) { if (str.length() > len) {
return str.substring(0, len); return str.substring(0, len);
} }
return str; return str;
} }
/** /**
* Join an array of strings into a string. * Join an array of strings into a string.
* *
* @param str the string array * @param str the string array
* @param delimiter the delimiter * @param delimiter the delimiter
* @param initialIndex the initial index to start form * @param initialIndex the initial index to start form
* @return a new string * @return a new string
*/ */
public static String joinString(String[] str, String delimiter, int initialIndex) { public static String joinString(String[] str, String delimiter, int initialIndex) {
if (str.length == 0) { if (str.length == 0) {
return ""; return "";
} }
StringBuilder buffer = new StringBuilder(str[initialIndex]); StringBuilder buffer = new StringBuilder(str[initialIndex]);
for (int i = initialIndex + 1; i < str.length; ++i) { for (int i = initialIndex + 1; i < str.length; ++i) {
buffer.append(delimiter).append(str[i]); buffer.append(delimiter).append(str[i]);
} }
return buffer.toString(); return buffer.toString();
} }
/** /**
* Join an array of strings into a string. * Join an array of strings into a string.
* *
* @param str the string array * @param str the string array
* @param delimiter the delimiter * @param delimiter the delimiter
* @param initialIndex the initial index to start form * @param initialIndex the initial index to start form
* @param quote the character to put around each entry * @param quote the character to put around each entry
* @return a new string * @return a new string
*/ */
public static String joinQuotedString(String[] str, String delimiter, public static String joinQuotedString(String[] str, String delimiter,
int initialIndex, String quote) { int initialIndex, String quote) {
if (str.length == 0) { if (str.length == 0) {
return ""; return "";
} }
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
buffer.append(quote); buffer.append(quote);
buffer.append(str[initialIndex]); buffer.append(str[initialIndex]);
buffer.append(quote); buffer.append(quote);
for (int i = initialIndex + 1; i < str.length; ++i) { for (int i = initialIndex + 1; i < str.length; ++i) {
buffer.append(delimiter).append(quote).append(str[i]).append(quote); buffer.append(delimiter).append(quote).append(str[i]).append(quote);
} }
return buffer.toString(); return buffer.toString();
} }
/** /**
* Join an array of strings into a string. * Join an array of strings into a string.
* *
* @param str the string array * @param str the string array
* @param delimiter the delimiter * @param delimiter the delimiter
* @return a new string * @return a new string
*/ */
public static String joinString(String[] str, String delimiter) { public static String joinString(String[] str, String delimiter) {
return joinString(str, delimiter, 0); return joinString(str, delimiter, 0);
} }
/** /**
* Join an array of strings into a string. * Join an array of strings into a string.
* *
* @param str an array of objects * @param str an array of objects
* @param delimiter the delimiter * @param delimiter the delimiter
* @param initialIndex the initial index to start form * @param initialIndex the initial index to start form
* @return a new string * @return a new string
*/ */
public static String joinString(Object[] str, String delimiter, int initialIndex) { public static String joinString(Object[] str, String delimiter, int initialIndex) {
if (str.length == 0) { if (str.length == 0) {
return ""; return "";
} }
StringBuilder buffer = new StringBuilder(str[initialIndex].toString()); StringBuilder buffer = new StringBuilder(str[initialIndex].toString());
for (int i = initialIndex + 1; i < str.length; ++i) { for (int i = initialIndex + 1; i < str.length; ++i) {
buffer.append(delimiter).append(str[i]); buffer.append(delimiter).append(str[i]);
} }
return buffer.toString(); return buffer.toString();
} }
/** /**
* Join an array of strings into a string. * Join an array of strings into a string.
* *
* @param str a list of integers * @param str a list of integers
* @param delimiter the delimiter * @param delimiter the delimiter
* @param initialIndex the initial index to start form * @param initialIndex the initial index to start form
* @return a new string * @return a new string
*/ */
public static String joinString(int[] str, String delimiter, int initialIndex) { public static String joinString(int[] str, String delimiter, int initialIndex) {
if (str.length == 0) { if (str.length == 0) {
return ""; return "";
} }
StringBuilder buffer = new StringBuilder(Integer.toString(str[initialIndex])); StringBuilder buffer = new StringBuilder(Integer.toString(str[initialIndex]));
for (int i = initialIndex + 1; i < str.length; ++i) { for (int i = initialIndex + 1; i < str.length; ++i) {
buffer.append(delimiter).append(Integer.toString(str[i])); buffer.append(delimiter).append(Integer.toString(str[i]));
} }
return buffer.toString(); return buffer.toString();
} }
/** /**
* Join an list of strings into a string. * Join an list of strings into a string.
* *
* @param str a list of strings * @param str a list of strings
* @param delimiter the delimiter * @param delimiter the delimiter
* @param initialIndex the initial index to start form * @param initialIndex the initial index to start form
* @return a new string * @return a new string
*/ */
public static String joinString(Collection<?> str, String delimiter, int initialIndex) { public static String joinString(Collection<?> str, String delimiter, int initialIndex) {
if (str.isEmpty()) { if (str.isEmpty()) {
return ""; return "";
} }
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
int i = 0; int i = 0;
for (Object o : str) { for (Object o : str) {
if (i >= initialIndex) { if (i >= initialIndex) {
if (i > 0) { if (i > 0) {
buffer.append(delimiter); buffer.append(delimiter);
} }
buffer.append(o); buffer.append(o);
} }
++i; ++i;
} }
return buffer.toString(); return buffer.toString();
} }
/** /**
* <p>Find the Levenshtein distance between two Strings.</p> * <p>Find the Levenshtein distance between two Strings.</p>
* *
* <p>This is the number of changes needed to change one String into * <p>This is the number of changes needed to change one String into
* another, where each change is a single character modification (deletion, * another, where each change is a single character modification (deletion,
* insertion or substitution).</p> * insertion or substitution).</p>
* *
* <p>The previous implementation of the Levenshtein distance algorithm * <p>The previous implementation of the Levenshtein distance algorithm
* was from <a href="http://www.merriampark.com/ld.htm">http://www.merriampark.com/ld.htm</a></p> * was from <a href="http://www.merriampark.com/ld.htm">http://www.merriampark.com/ld.htm</a></p>
* *
* <p>Chas Emerick has written an implementation in Java, which avoids an OutOfMemoryError * <p>Chas Emerick has written an implementation in Java, which avoids an OutOfMemoryError
* which can occur when my Java implementation is used with very large strings.<br> * which can occur when my Java implementation is used with very large strings.<br>
* This implementation of the Levenshtein distance algorithm * This implementation of the Levenshtein distance algorithm
* is from <a href="http://www.merriampark.com/ldjava.htm">http://www.merriampark.com/ldjava.htm</a></p> * is from <a href="http://www.merriampark.com/ldjava.htm">http://www.merriampark.com/ldjava.htm</a></p>
* *
* <pre> * <pre>
* StringUtil.getLevenshteinDistance(null, *) = IllegalArgumentException * StringUtil.getLevenshteinDistance(null, *) = IllegalArgumentException
* StringUtil.getLevenshteinDistance(*, null) = IllegalArgumentException * StringUtil.getLevenshteinDistance(*, null) = IllegalArgumentException
* StringUtil.getLevenshteinDistance("","") = 0 * StringUtil.getLevenshteinDistance("","") = 0
* StringUtil.getLevenshteinDistance("","a") = 1 * StringUtil.getLevenshteinDistance("","a") = 1
* StringUtil.getLevenshteinDistance("aaapppp", "") = 7 * StringUtil.getLevenshteinDistance("aaapppp", "") = 7
* StringUtil.getLevenshteinDistance("frog", "fog") = 1 * StringUtil.getLevenshteinDistance("frog", "fog") = 1
* StringUtil.getLevenshteinDistance("fly", "ant") = 3 * StringUtil.getLevenshteinDistance("fly", "ant") = 3
* StringUtil.getLevenshteinDistance("elephant", "hippo") = 7 * StringUtil.getLevenshteinDistance("elephant", "hippo") = 7
* StringUtil.getLevenshteinDistance("hippo", "elephant") = 7 * StringUtil.getLevenshteinDistance("hippo", "elephant") = 7
* StringUtil.getLevenshteinDistance("hippo", "zzzzzzzz") = 8 * StringUtil.getLevenshteinDistance("hippo", "zzzzzzzz") = 8
* StringUtil.getLevenshteinDistance("hello", "hallo") = 1 * StringUtil.getLevenshteinDistance("hello", "hallo") = 1
* </pre> * </pre>
* *
* @param s the first String, must not be null * @param s the first String, must not be null
* @param t the second String, must not be null * @param t the second String, must not be null
* @return result distance * @return result distance
* @throws IllegalArgumentException if either String input {@code null} * @throws IllegalArgumentException if either String input {@code null}
*/ */
public static int getLevenshteinDistance(String s, String t) { public static int getLevenshteinDistance(String s, String t) {
if (s == null || t == null) { if (s == null || t == null) {
throw new IllegalArgumentException("Strings must not be null"); throw new IllegalArgumentException("Strings must not be null");
} }
/* /*
* The difference between this impl. and the previous is that, rather * The difference between this impl. and the previous is that, rather
* than creating and retaining a matrix of size s.length()+1 by * than creating and retaining a matrix of size s.length()+1 by
* t.length()+1, we maintain two single-dimensional arrays of length * t.length()+1, we maintain two single-dimensional arrays of length
* s.length()+1. The first, d, is the 'current working' distance array * s.length()+1. The first, d, is the 'current working' distance array
* that maintains the newest distance cost counts as we iterate through * that maintains the newest distance cost counts as we iterate through
* the characters of String s. Each time we increment the index of * the characters of String s. Each time we increment the index of
* String t we are comparing, d is copied to p, the second int[]. Doing * String t we are comparing, d is copied to p, the second int[]. Doing
* so allows us to retain the previous cost counts as required by the * so allows us to retain the previous cost counts as required by the
* algorithm (taking the minimum of the cost count to the left, up one, * algorithm (taking the minimum of the cost count to the left, up one,
* and diagonally up and to the left of the current cost count being * and diagonally up and to the left of the current cost count being
* calculated). (Note that the arrays aren't really copied anymore, just * calculated). (Note that the arrays aren't really copied anymore, just
* switched...this is clearly much better than cloning an array or doing * switched...this is clearly much better than cloning an array or doing
* a System.arraycopy() each time through the outer loop.) * a System.arraycopy() each time through the outer loop.)
* *
* Effectively, the difference between the two implementations is this * Effectively, the difference between the two implementations is this
* one does not cause an out of memory condition when calculating the LD * one does not cause an out of memory condition when calculating the LD
* over two very large strings. * over two very large strings.
*/ */
int n = s.length(); // length of s int n = s.length(); // length of s
int m = t.length(); // length of t int m = t.length(); // length of t
if (n == 0) { if (n == 0) {
return m; return m;
} else if (m == 0) { } else if (m == 0) {
return n; return n;
} }
int[] p = new int[n + 1]; // 'previous' cost array, horizontally int[] p = new int[n + 1]; // 'previous' cost array, horizontally
int[] d = new int[n + 1]; // cost array, horizontally int[] d = new int[n + 1]; // cost array, horizontally
int[] _d; // placeholder to assist in swapping p and d int[] _d; // placeholder to assist in swapping p and d
// indexes into strings s and t // indexes into strings s and t
int i; // iterates through s int i; // iterates through s
int j; // iterates through t int j; // iterates through t
char tj; // jth character of t char tj; // jth character of t
int cost; // cost int cost; // cost
for (i = 0; i <= n; ++i) { for (i = 0; i <= n; ++i) {
p[i] = i; p[i] = i;
} }
for (j = 1; j <= m; ++j) { for (j = 1; j <= m; ++j) {
tj = t.charAt(j - 1); tj = t.charAt(j - 1);
d[0] = j; d[0] = j;
for (i = 1; i <= n; ++i) { for (i = 1; i <= n; ++i) {
cost = s.charAt(i - 1) == tj ? 0 : 1; cost = s.charAt(i - 1) == tj ? 0 : 1;
// minimum of cell to the left+1, to the top+1, diagonally left // minimum of cell to the left+1, to the top+1, diagonally left
// and up +cost // and up +cost
d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1] d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1]
+ cost); + cost);
} }
// copy current distance counts to 'previous row' distance counts // copy current distance counts to 'previous row' distance counts
_d = p; _d = p;
p = d; p = d;
d = _d; d = _d;
} }
// our last action in the above loop was to switch d and p, so p now // our last action in the above loop was to switch d and p, so p now
// actually has the most recent cost counts // actually has the most recent cost counts
return p[n]; return p[n];
} }
public static <T extends Enum<?>> T lookup(Map<String, T> lookup, String name, boolean fuzzy) { public static <T extends Enum<?>> T lookup(Map<String, T> lookup, String name, boolean fuzzy) {
String testName = name.replaceAll("[ _]", "").toLowerCase(Locale.ROOT); String testName = name.replaceAll("[ _]", "").toLowerCase(Locale.ROOT);
T type = lookup.get(testName); T type = lookup.get(testName);
if (type != null) { if (type != null) {
return type; return type;
} }
if (!fuzzy) { if (!fuzzy) {
return null; return null;
} }
int minDist = -1; int minDist = -1;
for (Map.Entry<String, T> entry : lookup.entrySet()) { for (Map.Entry<String, T> entry : lookup.entrySet()) {
final String key = entry.getKey(); final String key = entry.getKey();
if (key.charAt(0) != testName.charAt(0)) { if (key.charAt(0) != testName.charAt(0)) {
continue; continue;
} }
int dist = getLevenshteinDistance(key, testName); int dist = getLevenshteinDistance(key, testName);
if ((dist < minDist || minDist == -1) && dist < 2) { if ((dist < minDist || minDist == -1) && dist < 2) {
minDist = dist; minDist = dist;
type = entry.getValue(); type = entry.getValue();
} }
} }
return type; return type;
} }
public static List<String> parseListInQuotes(String[] input, char delimiter, char quoteOpen, char quoteClose) { public static List<String> parseListInQuotes(String[] input, char delimiter, char quoteOpen, char quoteClose) {
return parseListInQuotes(input, delimiter, quoteOpen, quoteClose, false); return parseListInQuotes(input, delimiter, quoteOpen, quoteClose, false);
} }
public static List<String> parseListInQuotes(String[] input, char delimiter, char quoteOpen, public static List<String> parseListInQuotes(String[] input, char delimiter, char quoteOpen,
char quoteClose, boolean appendLeftover) { char quoteClose, boolean appendLeftover) {
List<String> parsableBlocks = new ArrayList<>(); List<String> parsableBlocks = new ArrayList<>();
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
for (String split : input) { for (String split : input) {
if (split.indexOf(quoteOpen) != -1 && split.indexOf(quoteClose) == -1) { if (split.indexOf(quoteOpen) != -1 && split.indexOf(quoteClose) == -1) {
buffer.append(split).append(delimiter); buffer.append(split).append(delimiter);
} else if (split.indexOf(quoteClose) != -1 && split.indexOf(quoteOpen) == -1) { } else if (split.indexOf(quoteClose) != -1 && split.indexOf(quoteOpen) == -1) {
buffer.append(split); buffer.append(split);
parsableBlocks.add(buffer.toString()); parsableBlocks.add(buffer.toString());
buffer = new StringBuilder(); buffer = new StringBuilder();
} else if (buffer.length() == 0) { } else if (buffer.length() == 0) {
parsableBlocks.add(split); parsableBlocks.add(split);
} else { } else {
buffer.append(split).append(delimiter); buffer.append(split).append(delimiter);
} }
} }
if (appendLeftover && buffer.length() != 0) { if (appendLeftover && buffer.length() != 0) {
parsableBlocks.add(buffer.delete(buffer.length() - 1, buffer.length()).toString()); parsableBlocks.add(buffer.delete(buffer.length() - 1, buffer.length()).toString());
} }
return parsableBlocks; return parsableBlocks;
} }
/** /**
* Splits a string respecting enclosing quotes. * Splits a string respecting enclosing quotes.
* *
* @param input the input to split. * @param input the input to split.
* @param delimiter the delimiter to split on. * @param delimiter the delimiter to split on.
* @param open the opening quote character. * @param open the opening quote character.
* @param close the closing quote character. * @param close the closing quote character.
* @return a list of split strings. * @return a list of split strings.
*/ */
public static List<String> split(String input, char delimiter, char open, char close) { public static List<String> split(String input, char delimiter, char open, char close) {
if (input.indexOf(open) == -1 && input.indexOf(close) == -1) { if (input.indexOf(open) == -1 && input.indexOf(close) == -1) {
return Arrays.asList(input.split(String.valueOf(delimiter))); return Arrays.asList(input.split(String.valueOf(delimiter)));
} }
int level = 0; int level = 0;
int begin = 0; int begin = 0;
List<String> split = new ArrayList<>(); List<String> split = new ArrayList<>();
for (int i = 0; i < input.length(); i++) { for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i); char c = input.charAt(i);
if (c == delimiter && level == 0) { if (c == delimiter && level == 0) {
split.add(input.substring(begin, i)); split.add(input.substring(begin, i));
begin = i + 1; begin = i + 1;
} else if (c == open) { } else if (c == open) {
level++; level++;
} else if (c == close) { } else if (c == close) {
level--; level--;
} }
} }
if (begin < input.length()) { if (begin < input.length()) {
split.add(input.substring(begin)); split.add(input.substring(begin));
} }
return split; return split;
} }
} }

View File

@ -1,52 +1,52 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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; package com.sk89q.worldedit;
/** /**
* Raised when an item is used when a block was expected. * Raised when an item is used when a block was expected.
*/ */
public class NotABlockException extends WorldEditException { public class NotABlockException extends WorldEditException {
/** /**
* Create a new instance. * Create a new instance.
*/ */
public NotABlockException() { public NotABlockException() {
super("This item is not a block."); super("This item is not a block.");
} }
/** /**
* Create a new instance. * Create a new instance.
* *
* @param input the input that was used * @param input the input that was used
*/ */
public NotABlockException(String input) { public NotABlockException(String input) {
super("The item '" + input + "' is not a block."); super("The item '" + input + "' is not a block.");
} }
/** /**
* Create a new instance. * Create a new instance.
* *
* @param input the input that was used * @param input the input that was used
*/ */
public NotABlockException(int input) { public NotABlockException(int input) {
super("The item with the ID " + input + " is not a block."); super("The item with the ID " + input + " is not a block.");
} }
} }

View File

@ -1,83 +1,83 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.blocks; package com.sk89q.worldedit.blocks;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemType;
/** /**
* Represents a stack of BaseItems. * Represents a stack of BaseItems.
* *
* <p>This class may be removed in the future.</p> * <p>This class may be removed in the future.</p>
*/ */
public class BaseItemStack extends BaseItem { public class BaseItemStack extends BaseItem {
private int amount = 1; private int amount = 1;
/** /**
* Construct the object with default stack size of one, with damage value of 0. * Construct the object with default stack size of one, with damage value of 0.
* *
* @param itemType The item type * @param itemType The item type
*/ */
public BaseItemStack(ItemType itemType) { public BaseItemStack(ItemType itemType) {
super(itemType); super(itemType);
} }
/** /**
* Construct the object. * Construct the object.
* *
* @param itemType The item type * @param itemType The item type
* @param amount amount in the stack * @param amount amount in the stack
*/ */
public BaseItemStack(ItemType itemType, int amount) { public BaseItemStack(ItemType itemType, int amount) {
super(itemType); super(itemType);
this.amount = amount; this.amount = amount;
} }
/** /**
* Construct the object. * Construct the object.
* *
* @param id The item type * @param id The item type
* @param tag Tag value * @param tag Tag value
* @param amount amount in the stack * @param amount amount in the stack
*/ */
public BaseItemStack(ItemType id, CompoundTag tag, int amount) { public BaseItemStack(ItemType id, CompoundTag tag, int amount) {
super(id, tag); super(id, tag);
this.amount = amount; this.amount = amount;
} }
/** /**
* Get the number of items in the stack. * Get the number of items in the stack.
* *
* @return the amount * @return the amount
*/ */
public int getAmount() { public int getAmount() {
return amount; return amount;
} }
/** /**
* Set the amount of items in the stack. * Set the amount of items in the stack.
* *
* @param amount the amount to set * @param amount the amount to set
*/ */
public void setAmount(int amount) { public void setAmount(int amount) {
this.amount = amount; this.amount = amount;
} }
} }

View File

@ -1,250 +1,250 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.regions; package com.sk89q.worldedit.regions;
import com.boydti.fawe.object.collection.BlockVectorSet; import com.boydti.fawe.object.collection.BlockVectorSet;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
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.regions.iterator.RegionIterator; import com.sk89q.worldedit.regions.iterator.RegionIterator;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.storage.ChunkStore; import com.sk89q.worldedit.world.storage.ChunkStore;
import java.util.AbstractSet; import java.util.AbstractSet;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
public abstract class AbstractRegion extends AbstractSet<BlockVector3> implements Region { public abstract class AbstractRegion extends AbstractSet<BlockVector3> implements Region {
protected World world; protected World world;
public AbstractRegion(World world) { public AbstractRegion(World world) {
this.world = world; this.world = world;
} }
@Override @Override
public int size() { public int size() {
return com.google.common.primitives.Ints.saturatedCast(getVolume()); return com.google.common.primitives.Ints.saturatedCast(getVolume());
} }
@Override @Override
public Vector3 getCenter() { public Vector3 getCenter() {
return getMinimumPoint().add(getMaximumPoint()).toVector3().divide(2); return getMinimumPoint().add(getMaximumPoint()).toVector3().divide(2);
} }
/** /**
* Get the iterator. * Get the iterator.
* *
* @return iterator of points inside the region * @return iterator of points inside the region
*/ */
@Override @Override
public Iterator<BlockVector3> iterator() { public Iterator<BlockVector3> iterator() {
return new RegionIterator(this); return new RegionIterator(this);
} }
@Override @Override
public World getWorld() { public World getWorld() {
return world; return world;
} }
@Override @Override
public void setWorld(World world) { public void setWorld(World world) {
this.world = world; this.world = world;
} }
@Override @Override
public void shift(BlockVector3 change) throws RegionOperationException { public void shift(BlockVector3 change) throws RegionOperationException {
expand(change); expand(change);
contract(change); contract(change);
} }
@Override @Override
public AbstractRegion clone() { public AbstractRegion clone() {
try { try {
return (AbstractRegion) super.clone(); return (AbstractRegion) super.clone();
} catch (CloneNotSupportedException exc) { } catch (CloneNotSupportedException exc) {
return null; return null;
} }
} }
@Override @Override
public List<BlockVector2> polygonize(int maxPoints) { public List<BlockVector2> polygonize(int maxPoints) {
if (maxPoints >= 0 && maxPoints < 4) { if (maxPoints >= 0 && maxPoints < 4) {
throw new IllegalArgumentException("Cannot polygonize an AbstractRegion with no overridden polygonize method into less than 4 points."); throw new IllegalArgumentException("Cannot polygonize an AbstractRegion with no overridden polygonize method into less than 4 points.");
} }
final BlockVector3 min = getMinimumPoint(); final BlockVector3 min = getMinimumPoint();
final BlockVector3 max = getMaximumPoint(); final BlockVector3 max = getMaximumPoint();
final List<BlockVector2> points = new ArrayList<>(4); final List<BlockVector2> points = new ArrayList<>(4);
points.add(BlockVector2.at(min.getX(), min.getZ())); points.add(BlockVector2.at(min.getX(), min.getZ()));
points.add(BlockVector2.at(min.getX(), max.getZ())); points.add(BlockVector2.at(min.getX(), max.getZ()));
points.add(BlockVector2.at(max.getX(), max.getZ())); points.add(BlockVector2.at(max.getX(), max.getZ()));
points.add(BlockVector2.at(max.getX(), min.getZ())); points.add(BlockVector2.at(max.getX(), min.getZ()));
return points; return points;
} }
@Override @Override
public long getVolume() { public long getVolume() {
BlockVector3 min = getMinimumPoint(); BlockVector3 min = getMinimumPoint();
BlockVector3 max = getMaximumPoint(); BlockVector3 max = getMaximumPoint();
return (max.getX() - min.getX() + 1L) return (max.getX() - min.getX() + 1L)
* (max.getY() - min.getY() + 1L) * (max.getY() - min.getY() + 1L)
* (max.getZ() - min.getZ() + 1L); * (max.getZ() - min.getZ() + 1L);
} }
/** /**
* Get X-size. * Get X-size.
* *
* @return width * @return width
*/ */
@Override @Override
public int getWidth() { public int getWidth() {
BlockVector3 min = getMinimumPoint(); BlockVector3 min = getMinimumPoint();
BlockVector3 max = getMaximumPoint(); BlockVector3 max = getMaximumPoint();
return max.getX() - min.getX() + 1; return max.getX() - min.getX() + 1;
} }
/** /**
* Get Y-size. * Get Y-size.
* *
* @return height * @return height
*/ */
@Override @Override
public int getHeight() { public int getHeight() {
BlockVector3 min = getMinimumPoint(); BlockVector3 min = getMinimumPoint();
BlockVector3 max = getMaximumPoint(); BlockVector3 max = getMaximumPoint();
return max.getY() - min.getY() + 1; return max.getY() - min.getY() + 1;
} }
/** /**
* Get Z-size. * Get Z-size.
* *
* @return length * @return length
*/ */
@Override @Override
public int getLength() { public int getLength() {
BlockVector3 min = getMinimumPoint(); BlockVector3 min = getMinimumPoint();
BlockVector3 max = getMaximumPoint(); BlockVector3 max = getMaximumPoint();
return max.getZ() - min.getZ() + 1; return max.getZ() - min.getZ() + 1;
} }
/** /**
* Get a list of chunks. * Get a list of chunks.
* *
* @return a set of chunks * @return a set of chunks
*/ */
@Override @Override
public Set<BlockVector2> getChunks() { public Set<BlockVector2> getChunks() {
final Set<BlockVector2> chunks = new HashSet<>(); final Set<BlockVector2> chunks = new HashSet<>();
final BlockVector3 minBlock = getMinimumPoint(); final BlockVector3 minBlock = getMinimumPoint();
final BlockVector3 maxBlock = getMaximumPoint(); final BlockVector3 maxBlock = getMaximumPoint();
final BlockVector2 min = BlockVector2.at(minBlock.getX() >> 4, minBlock.getZ() >> 4); final BlockVector2 min = BlockVector2.at(minBlock.getX() >> 4, minBlock.getZ() >> 4);
final BlockVector2 max = BlockVector2.at(maxBlock.getX() >> 4, maxBlock.getZ() >> 4); final BlockVector2 max = BlockVector2.at(maxBlock.getX() >> 4, maxBlock.getZ() >> 4);
for (int X = min.getBlockX(); X <= max.getBlockX(); ++X) { for (int X = min.getBlockX(); X <= max.getBlockX(); ++X) {
for (int Z = min.getBlockZ(); Z <= max.getBlockZ(); ++Z) { for (int Z = min.getBlockZ(); Z <= max.getBlockZ(); ++Z) {
if (containsChunk(X, Z)) { if (containsChunk(X, Z)) {
chunks.add(BlockVector2.at(X, Z)); chunks.add(BlockVector2.at(X, Z));
} }
} }
} }
return chunks; return chunks;
} }
@Override @Override
public Set<BlockVector3> getChunkCubes() { public Set<BlockVector3> getChunkCubes() {
final Set<BlockVector3> chunks = new BlockVectorSet(); final Set<BlockVector3> chunks = new BlockVectorSet();
final BlockVector3 min = getMinimumPoint(); final BlockVector3 min = getMinimumPoint();
final BlockVector3 max = getMaximumPoint(); final BlockVector3 max = getMaximumPoint();
for (int x = min.getBlockX(); x <= max.getBlockX(); ++x) { for (int x = min.getBlockX(); x <= max.getBlockX(); ++x) {
for (int y = min.getBlockY(); y <= max.getBlockY(); ++y) { for (int y = min.getBlockY(); y <= max.getBlockY(); ++y) {
for (int z = min.getBlockZ(); z <= max.getBlockZ(); ++z) { for (int z = min.getBlockZ(); z <= max.getBlockZ(); ++z) {
if (!contains(BlockVector3.at(x, y, z))) { if (!contains(BlockVector3.at(x, y, z))) {
continue; continue;
} }
chunks.add(BlockVector3.at( chunks.add(BlockVector3.at(
x >> ChunkStore.CHUNK_SHIFTS, x >> ChunkStore.CHUNK_SHIFTS,
y >> ChunkStore.CHUNK_SHIFTS, y >> ChunkStore.CHUNK_SHIFTS,
z >> ChunkStore.CHUNK_SHIFTS z >> ChunkStore.CHUNK_SHIFTS
)); ));
} }
} }
} }
return chunks; return chunks;
} }
// Sub-class utilities // Sub-class utilities
protected final int getWorldMinY() { protected final int getWorldMinY() {
return world == null ? 0 : world.getMinY(); return world == null ? 0 : world.getMinY();
} }
protected final int getWorldMaxY() { protected final int getWorldMaxY() {
return world == null ? 255 : world.getMaxY(); return world == null ? 255 : world.getMaxY();
} }
@Override @Override
public int hashCode() { public int hashCode() {
int worldHash = this.world == null ? 7 : this.world.hashCode(); int worldHash = this.world == null ? 7 : this.world.hashCode();
int result = worldHash ^ (worldHash >>> 32); int result = worldHash ^ (worldHash >>> 32);
result = 31 * result + this.getMinimumPoint().hashCode(); result = 31 * result + this.getMinimumPoint().hashCode();
result = 31 * result + this.getMaximumPoint().hashCode(); result = 31 * result + this.getMaximumPoint().hashCode();
result = (int) (31 * result + this.getVolume()); result = (int) (31 * result + this.getVolume());
return result; return result;
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (o == this) { if (o == this) {
return true; return true;
} }
if (!(o instanceof Region)) { if (!(o instanceof Region)) {
return false; return false;
} }
Region region = ((Region) o); Region region = ((Region) o);
if (Objects.equals(this.getWorld(), region.getWorld()) if (Objects.equals(this.getWorld(), region.getWorld())
&& this.getMinimumPoint().equals(region.getMinimumPoint()) && this.getMinimumPoint().equals(region.getMinimumPoint())
&& this.getMaximumPoint().equals(region.getMaximumPoint()) && this.getMaximumPoint().equals(region.getMaximumPoint())
&& this.getVolume() == region.getVolume()) { && this.getVolume() == region.getVolume()) {
return true; return true;
} }
return false; return false;
} }
} }

View File

@ -1,336 +1,336 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.regions; package com.sk89q.worldedit.regions;
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.regions.polyhedron.Edge; import com.sk89q.worldedit.regions.polyhedron.Edge;
import com.sk89q.worldedit.regions.polyhedron.Triangle; import com.sk89q.worldedit.regions.polyhedron.Triangle;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
public class ConvexPolyhedralRegion extends AbstractRegion { public class ConvexPolyhedralRegion extends AbstractRegion {
/** /**
* Vertices that are contained in the convex hull. * Vertices that are contained in the convex hull.
*/ */
private final Set<BlockVector3> vertices = new LinkedHashSet<>(); private final Set<BlockVector3> vertices = new LinkedHashSet<>();
/** /**
* Triangles that form the convex hull. * Triangles that form the convex hull.
*/ */
private final List<Triangle> triangles = new ArrayList<>(); private final List<Triangle> triangles = new ArrayList<>();
/** /**
* Vertices that are coplanar to the first 3 vertices. * Vertices that are coplanar to the first 3 vertices.
*/ */
private final Set<BlockVector3> vertexBacklog = new LinkedHashSet<>(); private final Set<BlockVector3> vertexBacklog = new LinkedHashSet<>();
/** /**
* Minimum point of the axis-aligned bounding box. * Minimum point of the axis-aligned bounding box.
*/ */
private BlockVector3 minimumPoint; private BlockVector3 minimumPoint;
/** /**
* Maximum point of the axis-aligned bounding box. * Maximum point of the axis-aligned bounding box.
*/ */
private BlockVector3 maximumPoint; private BlockVector3 maximumPoint;
/** /**
* Accumulator for the barycenter of the polyhedron. Divide by vertices.size() to get the actual center. * Accumulator for the barycenter of the polyhedron. Divide by vertices.size() to get the actual center.
*/ */
private BlockVector3 centerAccum = BlockVector3.ZERO; private BlockVector3 centerAccum = BlockVector3.ZERO;
/** /**
* The last triangle that caused a {@link #contains(BlockVector3)}} to classify a point as "outside". Used for optimization. * The last triangle that caused a {@link #contains(BlockVector3)}} to classify a point as "outside". Used for optimization.
*/ */
private Triangle lastTriangle; private Triangle lastTriangle;
/** /**
* Constructs an empty mesh, containing no vertices or triangles. * Constructs an empty mesh, containing no vertices or triangles.
* *
* @param world the world * @param world the world
*/ */
public ConvexPolyhedralRegion(@Nullable World world) { public ConvexPolyhedralRegion(@Nullable World world) {
super(world); super(world);
} }
/** /**
* Constructs an independent copy of the given region. * Constructs an independent copy of the given region.
* *
* @param region the region to copy * @param region the region to copy
*/ */
public ConvexPolyhedralRegion(ConvexPolyhedralRegion region) { public ConvexPolyhedralRegion(ConvexPolyhedralRegion region) {
this(region.world); this(region.world);
vertices.addAll(region.vertices); vertices.addAll(region.vertices);
triangles.addAll(region.triangles); triangles.addAll(region.triangles);
vertexBacklog.addAll(region.vertexBacklog); vertexBacklog.addAll(region.vertexBacklog);
minimumPoint = region.minimumPoint; minimumPoint = region.minimumPoint;
maximumPoint = region.maximumPoint; maximumPoint = region.maximumPoint;
centerAccum = region.centerAccum; centerAccum = region.centerAccum;
lastTriangle = region.lastTriangle; lastTriangle = region.lastTriangle;
} }
/** /**
* Clears the region, removing all vertices and triangles. * Clears the region, removing all vertices and triangles.
*/ */
public void clear() { public void clear() {
vertices.clear(); vertices.clear();
triangles.clear(); triangles.clear();
vertexBacklog.clear(); vertexBacklog.clear();
minimumPoint = null; minimumPoint = null;
maximumPoint = null; maximumPoint = null;
centerAccum = BlockVector3.ZERO; centerAccum = BlockVector3.ZERO;
lastTriangle = null; lastTriangle = null;
} }
/** /**
* Add a vertex to the region. * Add a vertex to the region.
* *
* @param vertex the vertex * @param vertex the vertex
* @return true, if something changed. * @return true, if something changed.
*/ */
public boolean addVertex(BlockVector3 vertex) { public boolean addVertex(BlockVector3 vertex) {
checkNotNull(vertex); checkNotNull(vertex);
lastTriangle = null; // Probably not necessary lastTriangle = null; // Probably not necessary
if (vertices.contains(vertex)) { if (vertices.contains(vertex)) {
return false; return false;
} }
Vector3 vertexD = vertex.toVector3(); Vector3 vertexD = vertex.toVector3();
if (vertices.size() == 3) { if (vertices.size() == 3) {
if (vertexBacklog.contains(vertex)) { if (vertexBacklog.contains(vertex)) {
return false; return false;
} }
if (containsRaw(vertexD)) { if (containsRaw(vertexD)) {
return vertexBacklog.add(vertex); return vertexBacklog.add(vertex);
} }
} }
vertices.add(vertex); vertices.add(vertex);
centerAccum = centerAccum.add(vertex); centerAccum = centerAccum.add(vertex);
if (minimumPoint == null) { if (minimumPoint == null) {
minimumPoint = maximumPoint = vertex; minimumPoint = maximumPoint = vertex;
} else { } else {
minimumPoint = minimumPoint.getMinimum(vertex); minimumPoint = minimumPoint.getMinimum(vertex);
maximumPoint = maximumPoint.getMaximum(vertex); maximumPoint = maximumPoint.getMaximum(vertex);
} }
switch (vertices.size()) { switch (vertices.size()) {
case 0: case 0:
case 1: case 1:
case 2: case 2:
// Incomplete, can't make a mesh yet // Incomplete, can't make a mesh yet
return true; return true;
case 3: case 3:
// Generate minimal mesh to start from // Generate minimal mesh to start from
final BlockVector3[] v = vertices.toArray(new BlockVector3[0]); final BlockVector3[] v = vertices.toArray(new BlockVector3[0]);
triangles.add((new Triangle(v[0].toVector3(), v[1].toVector3(), v[2].toVector3()))); triangles.add((new Triangle(v[0].toVector3(), v[1].toVector3(), v[2].toVector3())));
triangles.add((new Triangle(v[0].toVector3(), v[2].toVector3(), v[1].toVector3()))); triangles.add((new Triangle(v[0].toVector3(), v[2].toVector3(), v[1].toVector3())));
return true; return true;
default: default:
break; break;
} }
// Look for triangles that face the vertex and remove them // Look for triangles that face the vertex and remove them
final Set<Edge> borderEdges = new LinkedHashSet<>(); final Set<Edge> borderEdges = new LinkedHashSet<>();
for (Iterator<Triangle> it = triangles.iterator(); it.hasNext(); ) { for (Iterator<Triangle> it = triangles.iterator(); it.hasNext(); ) {
final Triangle triangle = it.next(); final Triangle triangle = it.next();
// If the triangle can't be seen, it's not relevant // If the triangle can't be seen, it's not relevant
if (!triangle.above(vertexD)) { if (!triangle.above(vertexD)) {
continue; continue;
} }
// Remove the triangle from the mesh // Remove the triangle from the mesh
it.remove(); it.remove();
// ...and remember its edges // ...and remember its edges
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
final Edge edge = triangle.getEdge(i); final Edge edge = triangle.getEdge(i);
if (borderEdges.remove(edge)) { if (borderEdges.remove(edge)) {
continue; continue;
} }
borderEdges.add(edge); borderEdges.add(edge);
} }
} }
// Add triangles between the remembered edges and the new vertex. // Add triangles between the remembered edges and the new vertex.
for (Edge edge : borderEdges) { for (Edge edge : borderEdges) {
triangles.add(edge.createTriangle(vertexD)); triangles.add(edge.createTriangle(vertexD));
} }
if (!vertexBacklog.isEmpty()) { if (!vertexBacklog.isEmpty()) {
// Remove the new vertex // Remove the new vertex
vertices.remove(vertex); vertices.remove(vertex);
// Clone, clear and work through the backlog // Clone, clear and work through the backlog
final List<BlockVector3> vertexBacklog2 = new ArrayList<>(vertexBacklog); final List<BlockVector3> vertexBacklog2 = new ArrayList<>(vertexBacklog);
vertexBacklog.clear(); vertexBacklog.clear();
for (BlockVector3 vertex2 : vertexBacklog2) { for (BlockVector3 vertex2 : vertexBacklog2) {
addVertex(vertex2); addVertex(vertex2);
} }
// Re-add the new vertex after the backlog. // Re-add the new vertex after the backlog.
vertices.add(vertex); vertices.add(vertex);
} }
return true; return true;
} }
public boolean isDefined() { public boolean isDefined() {
return !triangles.isEmpty(); return !triangles.isEmpty();
} }
@Override @Override
public BlockVector3 getMinimumPoint() { public BlockVector3 getMinimumPoint() {
return minimumPoint; return minimumPoint;
} }
@Override @Override
public BlockVector3 getMaximumPoint() { public BlockVector3 getMaximumPoint() {
return maximumPoint; return maximumPoint;
} }
@Override @Override
public Vector3 getCenter() { public Vector3 getCenter() {
return centerAccum.toVector3().divide(vertices.size()); return centerAccum.toVector3().divide(vertices.size());
} }
@Override @Override
public void expand(BlockVector3... changes) throws RegionOperationException { public void expand(BlockVector3... changes) throws RegionOperationException {
} }
@Override @Override
public void contract(BlockVector3... changes) throws RegionOperationException { public void contract(BlockVector3... changes) throws RegionOperationException {
} }
@Override @Override
public void shift(BlockVector3 change) throws RegionOperationException { public void shift(BlockVector3 change) throws RegionOperationException {
Vector3 vec = change.toVector3(); Vector3 vec = change.toVector3();
shiftCollection(vertices, change); shiftCollection(vertices, change);
shiftCollection(vertexBacklog, change); shiftCollection(vertexBacklog, change);
for (int i = 0; i < triangles.size(); ++i) { for (int i = 0; i < triangles.size(); ++i) {
final Triangle triangle = triangles.get(i); final Triangle triangle = triangles.get(i);
final Vector3 v0 = vec.add(triangle.getVertex(0)); final Vector3 v0 = vec.add(triangle.getVertex(0));
final Vector3 v1 = vec.add(triangle.getVertex(1)); final Vector3 v1 = vec.add(triangle.getVertex(1));
final Vector3 v2 = vec.add(triangle.getVertex(2)); final Vector3 v2 = vec.add(triangle.getVertex(2));
triangles.set(i, new Triangle(v0, v1, v2)); triangles.set(i, new Triangle(v0, v1, v2));
} }
minimumPoint = change.add(minimumPoint); minimumPoint = change.add(minimumPoint);
maximumPoint = change.add(maximumPoint); maximumPoint = change.add(maximumPoint);
centerAccum = change.multiply(vertices.size()).add(centerAccum); centerAccum = change.multiply(vertices.size()).add(centerAccum);
lastTriangle = null; lastTriangle = null;
} }
private static void shiftCollection(Collection<BlockVector3> collection, BlockVector3 change) { private static void shiftCollection(Collection<BlockVector3> collection, BlockVector3 change) {
final List<BlockVector3> tmp = new ArrayList<>(collection); final List<BlockVector3> tmp = new ArrayList<>(collection);
collection.clear(); collection.clear();
for (BlockVector3 vertex : tmp) { for (BlockVector3 vertex : tmp) {
collection.add(change.add(vertex)); collection.add(change.add(vertex));
} }
} }
@Override @Override
public boolean contains(BlockVector3 position) { public boolean contains(BlockVector3 position) {
if (!isDefined()) { if (!isDefined()) {
return false; return false;
} }
final BlockVector3 min = getMinimumPoint(); final BlockVector3 min = getMinimumPoint();
final BlockVector3 max = getMaximumPoint(); final BlockVector3 max = getMaximumPoint();
if (!position.containedWithin(min, max)) { if (!position.containedWithin(min, max)) {
return false; return false;
} }
return containsRaw(position.toVector3()); return containsRaw(position.toVector3());
} }
private boolean containsRaw(Vector3 pt) { private boolean containsRaw(Vector3 pt) {
if (lastTriangle != null && lastTriangle.above(pt)) { if (lastTriangle != null && lastTriangle.above(pt)) {
return false; return false;
} }
for (Triangle triangle : triangles) { for (Triangle triangle : triangles) {
if (lastTriangle == triangle) { if (lastTriangle == triangle) {
continue; continue;
} }
if (triangle.above(pt)) { if (triangle.above(pt)) {
lastTriangle = triangle; lastTriangle = triangle;
return false; return false;
} }
} }
return true; return true;
} }
public Collection<BlockVector3> getVertices() { public Collection<BlockVector3> getVertices() {
if (vertexBacklog.isEmpty()) { if (vertexBacklog.isEmpty()) {
return vertices; return vertices;
} }
final List<BlockVector3> ret = new ArrayList<>(vertices); final List<BlockVector3> ret = new ArrayList<>(vertices);
ret.addAll(vertexBacklog); ret.addAll(vertexBacklog);
return ret; return ret;
} }
public Collection<Triangle> getTriangles() { public Collection<Triangle> getTriangles() {
return triangles; return triangles;
} }
@Override @Override
public AbstractRegion clone() { public AbstractRegion clone() {
return new ConvexPolyhedralRegion(this); return new ConvexPolyhedralRegion(this);
} }
@Override @Override
public boolean containsEntireCuboid(int bx, int tx, int by, int ty, int bz, int tz) { public boolean containsEntireCuboid(int bx, int tx, int by, int ty, int bz, int tz) {
return false; return false;
} }
} }

View File

@ -1,430 +1,430 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.regions; package com.sk89q.worldedit.regions;
import com.boydti.fawe.beta.Filter; import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.IChunk; import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock; import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
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 com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector2; import com.sk89q.worldedit.math.Vector2;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.geom.Polygons; import com.sk89q.worldedit.math.geom.Polygons;
import com.sk89q.worldedit.regions.iterator.FlatRegion3DIterator; import com.sk89q.worldedit.regions.iterator.FlatRegion3DIterator;
import com.sk89q.worldedit.regions.iterator.FlatRegionIterator; import com.sk89q.worldedit.regions.iterator.FlatRegionIterator;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* Represents a cylindrical region. * Represents a cylindrical region.
*/ */
public class CylinderRegion extends AbstractRegion implements FlatRegion { public class CylinderRegion extends AbstractRegion implements FlatRegion {
private BlockVector2 center; private BlockVector2 center;
private Vector2 radius; private Vector2 radius;
private Vector2 radiusInverse; private Vector2 radiusInverse;
private int minY; private int minY;
private int maxY; private int maxY;
private boolean hasY = false; private boolean hasY = false;
/** /**
* Construct the region. * Construct the region.
*/ */
public CylinderRegion() { public CylinderRegion() {
this((World) null); this((World) null);
} }
/** /**
* Construct the region. * Construct the region.
* *
* @param world the world * @param world the world
*/ */
public CylinderRegion(World world) { public CylinderRegion(World world) {
this(world, BlockVector3.ZERO, Vector2.ZERO, 0, 0); this(world, BlockVector3.ZERO, Vector2.ZERO, 0, 0);
hasY = false; hasY = false;
} }
/** /**
* Construct the region. * Construct the region.
* *
* @param world the world * @param world the world
* @param center the center position * @param center the center position
* @param radius the radius along the X and Z axes * @param radius the radius along the X and Z axes
* @param minY the minimum Y, inclusive * @param minY the minimum Y, inclusive
* @param maxY the maximum Y, inclusive * @param maxY the maximum Y, inclusive
*/ */
public CylinderRegion(World world, BlockVector3 center, Vector2 radius, int minY, int maxY) { public CylinderRegion(World world, BlockVector3 center, Vector2 radius, int minY, int maxY) {
super(world); super(world);
setCenter(center.toBlockVector2()); setCenter(center.toBlockVector2());
setRadius(radius); setRadius(radius);
this.minY = minY; this.minY = minY;
this.maxY = maxY; this.maxY = maxY;
hasY = true; hasY = true;
} }
/** /**
* Construct the region. * Construct the region.
* *
* @param center the center position * @param center the center position
* @param radius the radius along the X and Z axes * @param radius the radius along the X and Z axes
* @param minY the minimum Y, inclusive * @param minY the minimum Y, inclusive
* @param maxY the maximum Y, inclusive * @param maxY the maximum Y, inclusive
*/ */
public CylinderRegion(BlockVector3 center, Vector2 radius, int minY, int maxY) { public CylinderRegion(BlockVector3 center, Vector2 radius, int minY, int maxY) {
super(null); super(null);
setCenter(center.toBlockVector2()); setCenter(center.toBlockVector2());
setRadius(radius); setRadius(radius);
this.minY = minY; this.minY = minY;
this.maxY = maxY; this.maxY = maxY;
hasY = true; hasY = true;
} }
public CylinderRegion(CylinderRegion region) { public CylinderRegion(CylinderRegion region) {
this(region.world, region.getCenter().toBlockPoint(), region.getRadius(), region.minY, region.maxY); this(region.world, region.getCenter().toBlockPoint(), region.getRadius(), region.minY, region.maxY);
hasY = region.hasY; hasY = region.hasY;
} }
@Override @Override
public Vector3 getCenter() { public Vector3 getCenter() {
return center.toVector3((maxY + minY) / 2); return center.toVector3((maxY + minY) / 2);
} }
/** /**
* Sets the main center point of the region. * Sets the main center point of the region.
* *
* @param center the center point * @param center the center point
*/ */
public void setCenter(BlockVector2 center) { public void setCenter(BlockVector2 center) {
this.center = center; this.center = center;
} }
/** /**
* Returns the radius of the cylinder. * Returns the radius of the cylinder.
* *
* @return the radius along the X and Z axes * @return the radius along the X and Z axes
*/ */
public Vector2 getRadius() { public Vector2 getRadius() {
return radius.subtract(0.5, 0.5); return radius.subtract(0.5, 0.5);
} }
/** /**
* Sets the radius of the cylinder. * Sets the radius of the cylinder.
* *
* @param radius the radius along the X and Z axes * @param radius the radius along the X and Z axes
*/ */
public void setRadius(Vector2 radius) { public void setRadius(Vector2 radius) {
this.radius = radius.add(0.5, 0.5); this.radius = radius.add(0.5, 0.5);
this.radiusInverse = Vector2.ONE.divide(radius); this.radiusInverse = Vector2.ONE.divide(radius);
} }
/** /**
* Extends the radius to be at least the given radius. * Extends the radius to be at least the given radius.
* *
* @param minRadius the minimum radius * @param minRadius the minimum radius
*/ */
public void extendRadius(Vector2 minRadius) { public void extendRadius(Vector2 minRadius) {
setRadius(minRadius.getMaximum(getRadius())); setRadius(minRadius.getMaximum(getRadius()));
} }
/** /**
* Set the minimum Y. * Set the minimum Y.
* *
* @param y the y * @param y the y
*/ */
public void setMinimumY(int y) { public void setMinimumY(int y) {
hasY = true; hasY = true;
minY = y; minY = y;
} }
/** /**
* Se the maximum Y. * Se the maximum Y.
* *
* @param y the y * @param y the y
*/ */
public void setMaximumY(int y) { public void setMaximumY(int y) {
hasY = true; hasY = true;
maxY = y; maxY = y;
} }
@Override @Override
public BlockVector3 getMinimumPoint() { public BlockVector3 getMinimumPoint() {
return center.toVector2().subtract(getRadius()).toVector3(minY).toBlockPoint(); return center.toVector2().subtract(getRadius()).toVector3(minY).toBlockPoint();
} }
@Override @Override
public BlockVector3 getMaximumPoint() { public BlockVector3 getMaximumPoint() {
return center.toVector2().add(getRadius()).toVector3(maxY).toBlockPoint(); return center.toVector2().add(getRadius()).toVector3(maxY).toBlockPoint();
} }
@Override @Override
public int getMaximumY() { public int getMaximumY() {
int worldMax = world != null ? world.getMaxY() - 1 : 255; int worldMax = world != null ? world.getMaxY() - 1 : 255;
if (maxY > worldMax) { if (maxY > worldMax) {
return maxY = worldMax; return maxY = worldMax;
} }
return maxY; return maxY;
} }
@Override @Override
public int getMinimumY() { public int getMinimumY() {
if (minY < 0) { if (minY < 0) {
return minY = 0; return minY = 0;
} }
return minY; return minY;
} }
private static final BigDecimal PI = BigDecimal.valueOf(Math.PI); private static final BigDecimal PI = BigDecimal.valueOf(Math.PI);
@Override @Override
public long getVolume() { public long getVolume() {
return BigDecimal.valueOf(radius.getX()) return BigDecimal.valueOf(radius.getX())
.multiply(BigDecimal.valueOf(radius.getZ())) .multiply(BigDecimal.valueOf(radius.getZ()))
.multiply(PI) .multiply(PI)
.multiply(BigDecimal.valueOf(getHeight())) .multiply(BigDecimal.valueOf(getHeight()))
.setScale(0, RoundingMode.FLOOR) .setScale(0, RoundingMode.FLOOR)
.longValue(); .longValue();
} }
@Override @Override
public int getWidth() { public int getWidth() {
return (int) (2 * radius.getX()); return (int) (2 * radius.getX());
} }
@Override @Override
public int getHeight() { public int getHeight() {
return maxY - minY + 1; return maxY - minY + 1;
} }
@Override @Override
public int getLength() { public int getLength() {
return (int) (2 * radius.getZ()); return (int) (2 * radius.getZ());
} }
private BlockVector2 calculateDiff2D(BlockVector3... changes) throws RegionOperationException { private BlockVector2 calculateDiff2D(BlockVector3... changes) throws RegionOperationException {
BlockVector2 diff = BlockVector2.ZERO; BlockVector2 diff = BlockVector2.ZERO;
for (BlockVector3 change : changes) { for (BlockVector3 change : changes) {
diff = diff.add(change.toBlockVector2()); diff = diff.add(change.toBlockVector2());
} }
if ((diff.getBlockX() & 1) + (diff.getBlockZ() & 1) != 0) { if ((diff.getBlockX() & 1) + (diff.getBlockZ() & 1) != 0) {
throw new RegionOperationException(TranslatableComponent.of("worldedit.selection.cylinder.error.even-horizontal")); throw new RegionOperationException(TranslatableComponent.of("worldedit.selection.cylinder.error.even-horizontal"));
} }
return diff.divide(2).floor(); return diff.divide(2).floor();
} }
private BlockVector2 calculateChanges2D(BlockVector3... changes) { private BlockVector2 calculateChanges2D(BlockVector3... changes) {
BlockVector2 total = BlockVector2.ZERO; BlockVector2 total = BlockVector2.ZERO;
for (BlockVector3 change : changes) { for (BlockVector3 change : changes) {
total = total.add(change.toBlockVector2().abs()); total = total.add(change.toBlockVector2().abs());
} }
return total.divide(2).floor(); return total.divide(2).floor();
} }
/** /**
* Expand the region. * Expand the region.
* Expand the region. * Expand the region.
* *
* @param changes array/arguments with multiple related changes * @param changes array/arguments with multiple related changes
*/ */
@Override @Override
public void expand(BlockVector3... changes) throws RegionOperationException { public void expand(BlockVector3... changes) throws RegionOperationException {
center = center.add(calculateDiff2D(changes)); center = center.add(calculateDiff2D(changes));
radius = radius.add(calculateChanges2D(changes).toVector2()); radius = radius.add(calculateChanges2D(changes).toVector2());
this.radiusInverse = Vector2.ONE.divide(radius); this.radiusInverse = Vector2.ONE.divide(radius);
for (BlockVector3 change : changes) { for (BlockVector3 change : changes) {
int changeY = change.getBlockY(); int changeY = change.getBlockY();
if (changeY > 0) { if (changeY > 0) {
maxY += changeY; maxY += changeY;
} else { } else {
minY += changeY; minY += changeY;
} }
} }
} }
/** /**
* Contract the region. * Contract the region.
* *
* @param changes array/arguments with multiple related changes * @param changes array/arguments with multiple related changes
* @throws RegionOperationException * @throws RegionOperationException
*/ */
@Override @Override
public void contract(BlockVector3... changes) throws RegionOperationException { public void contract(BlockVector3... changes) throws RegionOperationException {
center = center.subtract(calculateDiff2D(changes)); center = center.subtract(calculateDiff2D(changes));
Vector2 newRadius = radius.subtract(calculateChanges2D(changes).toVector2()); Vector2 newRadius = radius.subtract(calculateChanges2D(changes).toVector2());
radius = Vector2.at(1.5, 1.5).getMaximum(newRadius); radius = Vector2.at(1.5, 1.5).getMaximum(newRadius);
this.radiusInverse = Vector2.ONE.divide(radius); this.radiusInverse = Vector2.ONE.divide(radius);
for (BlockVector3 change : changes) { for (BlockVector3 change : changes) {
int height = maxY - minY; int height = maxY - minY;
int changeY = change.getBlockY(); int changeY = change.getBlockY();
if (changeY > 0) { if (changeY > 0) {
minY += Math.min(height, changeY); minY += Math.min(height, changeY);
} else { } else {
maxY += Math.max(-height, changeY); maxY += Math.max(-height, changeY);
} }
} }
} }
@Override @Override
public void shift(BlockVector3 change) throws RegionOperationException { public void shift(BlockVector3 change) throws RegionOperationException {
center = center.add(change.toBlockVector2()); center = center.add(change.toBlockVector2());
int changeY = change.getBlockY(); int changeY = change.getBlockY();
maxY += changeY; maxY += changeY;
minY += changeY; minY += changeY;
} }
/** /**
* Checks to see if a point is inside this region. * Checks to see if a point is inside this region.
*/ */
/* Slow and unnecessary /* Slow and unnecessary
@Override @Override
public boolean contains(BlockVector3 position) { public boolean contains(BlockVector3 position) {
final int blockY = position.getBlockY(); final int blockY = position.getBlockY();
if (blockY < minY || blockY > maxY) { if (blockY < minY || blockY > maxY) {
return false; return false;
} }
return position.toBlockVector2().subtract(center).toVector2().divide(radius).lengthSq() <= 1; return position.toBlockVector2().subtract(center).toVector2().divide(radius).lengthSq() <= 1;
} }
*/ */
/** /**
* Checks to see if a point is inside this region. * Checks to see if a point is inside this region.
*/ */
@Override @Override
public boolean contains(int x, int y, int z) { public boolean contains(int x, int y, int z) {
if (y < minY || y > maxY) { if (y < minY || y > maxY) {
return false; return false;
} }
return contains(x, z); return contains(x, z);
} }
@Override @Override
public boolean contains(int x, int z) { public boolean contains(int x, int z) {
double dx = Math.abs(x - center.getBlockX()) * radiusInverse.getX(); double dx = Math.abs(x - center.getBlockX()) * radiusInverse.getX();
double dz = Math.abs(z - center.getBlockZ()) * radiusInverse.getZ(); double dz = Math.abs(z - center.getBlockZ()) * radiusInverse.getZ();
return dx * dx + dz * dz <= 1; return dx * dx + dz * dz <= 1;
} }
@Override @Override
public boolean contains(BlockVector3 position) { public boolean contains(BlockVector3 position) {
return contains(position.getX(), position.getY(), position.getZ()); return contains(position.getX(), position.getY(), position.getZ());
} }
/** /**
* Sets the height of the cylinder to fit the specified Y. * Sets the height of the cylinder to fit the specified Y.
* *
* @param y the y value * @param y the y value
* @return true if the area was expanded * @return true if the area was expanded
*/ */
public boolean setY(int y) { public boolean setY(int y) {
if (!hasY) { if (!hasY) {
minY = y; minY = y;
maxY = y; maxY = y;
hasY = true; hasY = true;
return true; return true;
} else if (y < minY) { } else if (y < minY) {
minY = y; minY = y;
return true; return true;
} else if (y > maxY) { } else if (y > maxY) {
maxY = y; maxY = y;
return true; return true;
} }
return false; return false;
} }
@Override @Override
public Iterator<BlockVector3> iterator() { public Iterator<BlockVector3> iterator() {
return new FlatRegion3DIterator(this); return new FlatRegion3DIterator(this);
} }
@Override @Override
public Iterable<BlockVector2> asFlatRegion() { public Iterable<BlockVector2> asFlatRegion() {
return () -> new FlatRegionIterator(CylinderRegion.this); return () -> new FlatRegionIterator(CylinderRegion.this);
} }
/** /**
* Returns string representation in the format. * Returns string representation in the format.
* "(centerX, centerZ) - (radiusX, radiusZ) - (minY, maxY)" * "(centerX, centerZ) - (radiusX, radiusZ) - (minY, maxY)"
* *
* @return string * @return string
*/ */
@Override @Override
public String toString() { public String toString() {
return center + " - " + radius + "(" + minY + ", " + maxY + ")"; return center + " - " + radius + "(" + minY + ", " + maxY + ")";
} }
@Override @Override
public CylinderRegion clone() { public CylinderRegion clone() {
return (CylinderRegion) super.clone(); return (CylinderRegion) super.clone();
} }
@Override @Override
public List<BlockVector2> polygonize(int maxPoints) { public List<BlockVector2> polygonize(int maxPoints) {
return Polygons.polygonizeCylinder(center, radius, maxPoints); return Polygons.polygonizeCylinder(center, radius, maxPoints);
} }
/** /**
* Return a new instance with the given center and radius in the X and Z * Return a new instance with the given center and radius in the X and Z
* axes with a Y that extends from the bottom of the extent to the top * axes with a Y that extends from the bottom of the extent to the top
* of the extent. * of the extent.
* *
* @param extent the extent * @param extent the extent
* @param center the center position * @param center the center position
* @param radius the radius in the X and Z axes * @param radius the radius in the X and Z axes
* @return a region * @return a region
*/ */
public static CylinderRegion createRadius(Extent extent, BlockVector3 center, double radius) { public static CylinderRegion createRadius(Extent extent, BlockVector3 center, double radius) {
checkNotNull(extent); checkNotNull(extent);
checkNotNull(center); checkNotNull(center);
Vector2 radiusVec = Vector2.at(radius, radius); Vector2 radiusVec = Vector2.at(radius, radius);
int minY = extent.getMinimumPoint().getBlockY(); int minY = extent.getMinimumPoint().getBlockY();
int maxY = extent.getMaximumPoint().getBlockY(); int maxY = extent.getMaximumPoint().getBlockY();
return new CylinderRegion(center, radiusVec, minY, maxY); return new CylinderRegion(center, radiusVec, minY, maxY);
} }
@Override @Override
public void filter(final IChunk chunk, final Filter filter, final ChunkFilterBlock block, public void filter(final IChunk chunk, final Filter filter, final ChunkFilterBlock block,
final IChunkGet get, final IChunkSet set, boolean full) { final IChunkGet get, final IChunkSet set, boolean full) {
int bcx = chunk.getX() >> 4; int bcx = chunk.getX() >> 4;
int bcz = chunk.getZ() >> 4; int bcz = chunk.getZ() >> 4;
int tcx = bcx + 15; int tcx = bcx + 15;
int tcz = bcz + 15; int tcz = bcz + 15;
if (contains(bcx, bcz) && contains(tcx, tcz)) { if (contains(bcx, bcz) && contains(tcx, tcz)) {
filter(chunk, filter, block, get, set, minY, maxY, full); filter(chunk, filter, block, get, set, minY, maxY, full);
return; return;
} }
super.filter(chunk, filter, block, get, set, full); super.filter(chunk, filter, block, get, set, full);
} }
} }

View File

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

View File

@ -1,90 +1,90 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.regions.polyhedron; package com.sk89q.worldedit.regions.polyhedron;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
public class Edge { public class Edge {
private final Vector3 start; private final Vector3 start;
private final Vector3 end; private final Vector3 end;
public Edge(Vector3 start, Vector3 end) { public Edge(Vector3 start, Vector3 end) {
checkNotNull(start); checkNotNull(start);
checkNotNull(end); checkNotNull(end);
this.start = start; this.start = start;
this.end = end; this.end = end;
} }
@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
if (!(other instanceof Edge)) { if (!(other instanceof Edge)) {
return false; return false;
} }
Edge otherEdge = (Edge) other; Edge otherEdge = (Edge) other;
if ((this.start == otherEdge.end) && (this.end == otherEdge.start)) { if ((this.start == otherEdge.end) && (this.end == otherEdge.start)) {
return true; return true;
} }
if ((this.end == otherEdge.end) && (this.start == otherEdge.start)) { if ((this.end == otherEdge.end) && (this.start == otherEdge.start)) {
return true; return true;
} }
return false; return false;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return start.hashCode() ^ end.hashCode(); return start.hashCode() ^ end.hashCode();
} }
@Override @Override
public String toString() { public String toString() {
return "(" + this.start + "," + this.end + ")"; return "(" + this.start + "," + this.end + ")";
} }
/** /**
* Create a triangle from { this.start, this.end, vertex } * Create a triangle from { this.start, this.end, vertex }
* *
* @param vertex the 3rd vertex for the triangle * @param vertex the 3rd vertex for the triangle
* @return a triangle * @return a triangle
*/ */
public Triangle createTriangle(Vector3 vertex) { public Triangle createTriangle(Vector3 vertex) {
checkNotNull(vertex); checkNotNull(vertex);
return new Triangle(this.start, this.end, vertex); return new Triangle(this.start, this.end, vertex);
} }
/** /**
* Create a triangle from { this.start, vertex, this.end }. * Create a triangle from { this.start, vertex, this.end }.
* *
* @param vertex the second vertex * @param vertex the second vertex
* @return a new triangle * @return a new triangle
*/ */
public Triangle createTriangle2(Vector3 vertex) { public Triangle createTriangle2(Vector3 vertex) {
checkNotNull(vertex); checkNotNull(vertex);
return new Triangle(this.start, vertex, this.end); return new Triangle(this.start, vertex, this.end);
} }
} }

View File

@ -1,113 +1,113 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.regions.polyhedron; package com.sk89q.worldedit.regions.polyhedron;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
public class Triangle { public class Triangle {
private String tag = "Triangle"; private String tag = "Triangle";
private final Vector3[] vertices; private final Vector3[] vertices;
private final Vector3 normal; private final Vector3 normal;
private final double maxDotProduct; private final double maxDotProduct;
/** /**
* Constructs a triangle with the given vertices (counter-clockwise). * Constructs a triangle with the given vertices (counter-clockwise).
* *
* @param v0 first vertex * @param v0 first vertex
* @param v1 second vertex * @param v1 second vertex
* @param v2 third vertex * @param v2 third vertex
*/ */
public Triangle(Vector3 v0, Vector3 v1, Vector3 v2) { public Triangle(Vector3 v0, Vector3 v1, Vector3 v2) {
checkNotNull(v0); checkNotNull(v0);
checkNotNull(v1); checkNotNull(v1);
checkNotNull(v2); checkNotNull(v2);
vertices = new Vector3[] { v0, v1, v2 }; vertices = new Vector3[] { v0, v1, v2 };
this.normal = v1.subtract(v0).cross(v2.subtract(v0)).normalize(); this.normal = v1.subtract(v0).cross(v2.subtract(v0)).normalize();
this.maxDotProduct = Math.max(Math.max(normal.dot(v0), normal.dot(v1)), normal.dot(v2)); this.maxDotProduct = Math.max(Math.max(normal.dot(v0), normal.dot(v1)), normal.dot(v2));
} }
/** /**
* Returns the triangle's vertex with the given index, counter-clockwise. * Returns the triangle's vertex with the given index, counter-clockwise.
* *
* @param index Vertex index. Valid input: 0..2 * @param index Vertex index. Valid input: 0..2
* @return a vertex * @return a vertex
*/ */
public Vector3 getVertex(int index) { public Vector3 getVertex(int index) {
return vertices[index]; return vertices[index];
} }
/** /**
* Returns the triangle's edge with the given index, counter-clockwise. * Returns the triangle's edge with the given index, counter-clockwise.
* *
* @param index Edge index. Valid input: 0..2 * @param index Edge index. Valid input: 0..2
* @return an edge * @return an edge
*/ */
public Edge getEdge(int index) { public Edge getEdge(int index) {
if (index == vertices.length - 1) { if (index == vertices.length - 1) {
return new Edge(vertices[index], vertices[0]); return new Edge(vertices[index], vertices[0]);
} }
return new Edge(vertices[index], vertices[index + 1]); return new Edge(vertices[index], vertices[index + 1]);
} }
/** /**
* Returns whether the given point is above the plane the triangle is in. * Returns whether the given point is above the plane the triangle is in.
* *
* @param pt the point to test * @param pt the point to test
* @return true if the point is below * @return true if the point is below
*/ */
public boolean below(Vector3 pt) { public boolean below(Vector3 pt) {
checkNotNull(pt); checkNotNull(pt);
return normal.dot(pt) < maxDotProduct; return normal.dot(pt) < maxDotProduct;
} }
/** /**
* Returns whether the given point is above the plane the triangle is in. * Returns whether the given point is above the plane the triangle is in.
* *
* @param pt the point to test * @param pt the point to test
* @return true if the point is above * @return true if the point is above
*/ */
public boolean above(Vector3 pt) { public boolean above(Vector3 pt) {
checkNotNull(pt); checkNotNull(pt);
return normal.dot(pt) > maxDotProduct; return normal.dot(pt) > maxDotProduct;
} }
/** /**
* Set the triangle's tag. * Set the triangle's tag.
* *
* @param tag the tag * @param tag the tag
* @return this object * @return this object
*/ */
public Triangle tag(String tag) { public Triangle tag(String tag) {
checkNotNull(tag); checkNotNull(tag);
this.tag = tag; this.tag = tag;
return this; return this;
} }
@Override @Override
public String toString() { public String toString() {
return tag + "(" + this.vertices[0] + "," + this.vertices[1] + "," + this.vertices[2] + ")"; return tag + "(" + this.vertices[0] + "," + this.vertices[1] + "," + this.vertices[2] + ")";
} }
} }

View File

@ -1,274 +1,274 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.scripting; package com.sk89q.worldedit.scripting;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.command.InsufficientArgumentsException; import com.sk89q.worldedit.command.InsufficientArgumentsException;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.DisallowedUsageException; import com.sk89q.worldedit.extension.input.DisallowedUsageException;
import com.sk89q.worldedit.extension.input.NoMatchException; import com.sk89q.worldedit.extension.input.NoMatchException;
import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.expression.invoke.ReturnException; import com.sk89q.worldedit.internal.expression.invoke.ReturnException;
import com.sk89q.worldedit.session.request.Request; import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.formatting.text.TextComponent; import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.io.file.FilenameException; import com.sk89q.worldedit.util.io.file.FilenameException;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import java.io.File; import java.io.File;
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.Set; import java.util.Set;
/** /**
* The context given to scripts. * The context given to scripts.
*/ */
public class CraftScriptContext extends CraftScriptEnvironment { public class CraftScriptContext extends CraftScriptEnvironment {
private final List<EditSession> editSessions = new ArrayList<>(); private final List<EditSession> editSessions = new ArrayList<>();
private final String[] args; private final String[] args;
public CraftScriptContext(WorldEdit controller, public CraftScriptContext(WorldEdit controller,
Platform server, LocalConfiguration config, Platform server, LocalConfiguration config,
LocalSession session, Player player, String[] args) { LocalSession session, Player player, String[] args) {
super(controller, server, config, session, player); super(controller, server, config, session, player);
this.args = args; this.args = args;
} }
/** /**
* Get an edit session. Every subsequent call returns a new edit session. * Get an edit session. Every subsequent call returns a new edit session.
* Usually you only need to use one edit session. * Usually you only need to use one edit session.
* *
* @return an edit session * @return an edit session
*/ */
public EditSession remember() { public EditSession remember() {
EditSession editSession = controller.getEditSessionFactory() EditSession editSession = controller.getEditSessionFactory()
.getEditSession(player.getWorld(), .getEditSession(player.getWorld(),
session.getBlockChangeLimit(), session.getBlockBag(player), player); session.getBlockChangeLimit(), session.getBlockBag(player), player);
Request.request().setEditSession(editSession); Request.request().setEditSession(editSession);
editSession.enableStandardMode(); editSession.enableStandardMode();
editSessions.add(editSession); editSessions.add(editSession);
return editSession; return editSession;
} }
/** /**
* Get the player. * Get the player.
* *
* @return the calling player * @return the calling player
*/ */
public Player getPlayer() { public Player getPlayer() {
return player; return player;
} }
/** /**
* Get the player's session. * Get the player's session.
* *
* @return a session * @return a session
*/ */
public LocalSession getSession() { public LocalSession getSession() {
return session; return session;
} }
/** /**
* Get the configuration for WorldEdit. * Get the configuration for WorldEdit.
* *
* @return the configuration * @return the configuration
*/ */
public LocalConfiguration getConfiguration() { public LocalConfiguration getConfiguration() {
return config; return config;
} }
/** /**
* Get a list of edit sessions that have been created. * Get a list of edit sessions that have been created.
* *
* @return a list of created {@code EditSession}s * @return a list of created {@code EditSession}s
*/ */
public List<EditSession> getEditSessions() { public List<EditSession> getEditSessions() {
return Collections.unmodifiableList(editSessions); return Collections.unmodifiableList(editSessions);
} }
/** /**
* Print a regular message to the user. * Print a regular message to the user.
* *
* @param message a message * @param message a message
*/ */
public void print(String message) { public void print(String message) {
player.printInfo(TextComponent.of(message)); player.printInfo(TextComponent.of(message));
} }
/** /**
* Print an error message to the user. * Print an error message to the user.
* *
* @param message a message * @param message a message
*/ */
public void error(String message) { public void error(String message) {
player.printError(TextComponent.of(message)); player.printError(TextComponent.of(message));
} }
/** /**
* Print a raw message to the user. * Print a raw message to the user.
* *
* @param message a message * @param message a message
*/ */
public void printRaw(String message) { public void printRaw(String message) {
player.print(TextComponent.of(message)); player.print(TextComponent.of(message));
} }
/** /**
* Checks to make sure that there are enough but not too many arguments. * Checks to make sure that there are enough but not too many arguments.
* *
* @param min a number of arguments * @param min a number of arguments
* @param max -1 for no maximum * @param max -1 for no maximum
* @param usage usage string * @param usage usage string
* @throws InsufficientArgumentsException if the arguments are not "sufficiently" good * @throws InsufficientArgumentsException if the arguments are not "sufficiently" good
*/ */
public void checkArgs(int min, int max, String usage) public void checkArgs(int min, int max, String usage)
throws InsufficientArgumentsException { throws InsufficientArgumentsException {
if (args.length <= min || (max != -1 && args.length - 1 > max)) { if (args.length <= min || (max != -1 && args.length - 1 > max)) {
throw new InsufficientArgumentsException(TranslatableComponent.of("worldedit.error.incorrect-usage", TextComponent.of(usage))); throw new InsufficientArgumentsException(TranslatableComponent.of("worldedit.error.incorrect-usage", TextComponent.of(usage)));
} }
} }
/** /**
* Immediately terminate execution of the script, but without a failure message. * Immediately terminate execution of the script, but without a failure message.
* *
* @implNote This exits by throwing an exception, which if caught will prevent * @implNote This exits by throwing an exception, which if caught will prevent
* the script from exiting * the script from exiting
*/ */
public void exit() { public void exit() {
throw new ReturnException(null); throw new ReturnException(null);
} }
/** /**
* Get an item from an item name or an item ID number. * Get an item from an item name or an item ID number.
* *
* @param input input to parse * @param input input to parse
* @param allAllowed true to ignore blacklists * @param allAllowed true to ignore blacklists
* @return a block * @return a block
* @throws NoMatchException if no block was found * @throws NoMatchException if no block was found
* @throws DisallowedUsageException if the block is disallowed * @throws DisallowedUsageException if the block is disallowed
*/ */
public BaseBlock getBlock(String input, boolean allAllowed) throws WorldEditException { public BaseBlock getBlock(String input, boolean allAllowed) throws WorldEditException {
ParserContext context = new ParserContext(); ParserContext context = new ParserContext();
context.setActor(player); context.setActor(player);
context.setWorld(player.getWorld()); context.setWorld(player.getWorld());
context.setSession(session); context.setSession(session);
context.setRestricted(!allAllowed); context.setRestricted(!allAllowed);
context.setPreferringWildcard(false); context.setPreferringWildcard(false);
return controller.getBlockFactory().parseFromListInput(input, context).stream().findFirst().orElse(null); return controller.getBlockFactory().parseFromListInput(input, context).stream().findFirst().orElse(null);
} }
/** /**
* Get a block. * Get a block.
* *
* @param id the type Id * @param id the type Id
* @return a block * @return a block
* @throws NoMatchException if no block was found * @throws NoMatchException if no block was found
* @throws DisallowedUsageException if the block is disallowed * @throws DisallowedUsageException if the block is disallowed
*/ */
public BaseBlock getBlock(String id) throws WorldEditException { public BaseBlock getBlock(String id) throws WorldEditException {
return getBlock(id, false); return getBlock(id, false);
} }
/** /**
* Get a list of blocks as a set. This returns a Pattern. * Get a list of blocks as a set. This returns a Pattern.
* *
* @param list the input * @param list the input
* @return pattern * @return pattern
* @throws NoMatchException if the pattern was invalid * @throws NoMatchException if the pattern was invalid
* @throws DisallowedUsageException if the block is disallowed * @throws DisallowedUsageException if the block is disallowed
*/ */
public Pattern getBlockPattern(String list) throws WorldEditException { public Pattern getBlockPattern(String list) throws WorldEditException {
ParserContext context = new ParserContext(); ParserContext context = new ParserContext();
context.setActor(player); context.setActor(player);
context.setWorld(player.getWorld()); context.setWorld(player.getWorld());
context.setSession(session); context.setSession(session);
return controller.getPatternFactory().parseFromInput(list, context); return controller.getPatternFactory().parseFromInput(list, context);
} }
/** /**
* Get a list of blocks as a set. * Get a list of blocks as a set.
* *
* @param list a list * @param list a list
* @param allBlocksAllowed true if all blocks are allowed * @param allBlocksAllowed true if all blocks are allowed
* @return set * @return set
* @throws NoMatchException if the blocks couldn't be found * @throws NoMatchException if the blocks couldn't be found
* @throws DisallowedUsageException if the block is disallowed * @throws DisallowedUsageException if the block is disallowed
*/ */
public Set<BaseBlock> getBlocks(String list, boolean allBlocksAllowed) throws WorldEditException { public Set<BaseBlock> getBlocks(String list, boolean allBlocksAllowed) throws WorldEditException {
ParserContext context = new ParserContext(); ParserContext context = new ParserContext();
context.setActor(player); context.setActor(player);
context.setWorld(player.getWorld()); context.setWorld(player.getWorld());
context.setSession(session); context.setSession(session);
context.setRestricted(!allBlocksAllowed); context.setRestricted(!allBlocksAllowed);
return controller.getBlockFactory().parseFromListInput(list, context); return controller.getBlockFactory().parseFromListInput(list, context);
} }
/** /**
* Gets the path to a file for opening. This method will check to see if the * Gets the path to a file for opening. This method will check to see if the
* filename has valid characters and has an extension. It also prevents * filename has valid characters and has an extension. It also prevents
* directory traversal exploits by checking the root directory and the file * directory traversal exploits by checking the root directory and the file
* directory. On success, a {@code java.io.File} object will be * directory. On success, a {@code java.io.File} object will be
* returned. * returned.
* *
* <p>Use this method if you need to read a file from a directory.</p> * <p>Use this method if you need to read a file from a directory.</p>
* *
* @param folder sub-directory to look in * @param folder sub-directory to look in
* @param filename filename (user-submitted) * @param filename filename (user-submitted)
* @param defaultExt default extension to append if there is none * @param defaultExt default extension to append if there is none
* @param exts list of extensions for file open dialog, null for no filter * @param exts list of extensions for file open dialog, null for no filter
* @return a file * @return a file
* @throws FilenameException if there is a problem with the name of the file * @throws FilenameException if there is a problem with the name of the file
*/ */
public File getSafeOpenFile(String folder, String filename, String defaultExt, String... exts) throws FilenameException { public File getSafeOpenFile(String folder, String filename, String defaultExt, String... exts) throws FilenameException {
File dir = controller.getWorkingDirectoryFile(folder); File dir = controller.getWorkingDirectoryFile(folder);
return controller.getSafeOpenFile(player, dir, filename, defaultExt, exts); return controller.getSafeOpenFile(player, dir, filename, defaultExt, exts);
} }
/** /**
* Gets the path to a file for saving. This method will check to see if the * Gets the path to a file for saving. This method will check to see if the
* filename has valid characters and has an extension. It also prevents * filename has valid characters and has an extension. It also prevents
* directory traversal exploits by checking the root directory and the file * directory traversal exploits by checking the root directory and the file
* directory. On success, a {@code java.io.File} object will be * directory. On success, a {@code java.io.File} object will be
* returned. * returned.
* *
* <p>Use this method if you need to read a file from a directory.</p> * <p>Use this method if you need to read a file from a directory.</p>
* *
* @param folder sub-directory to look in * @param folder sub-directory to look in
* @param filename filename (user-submitted) * @param filename filename (user-submitted)
* @param defaultExt default extension to append if there is none * @param defaultExt default extension to append if there is none
* @param exts list of extensions for file save dialog, null for no filter * @param exts list of extensions for file save dialog, null for no filter
* @return a file * @return a file
* @throws FilenameException if there is a problem with the name of the file * @throws FilenameException if there is a problem with the name of the file
*/ */
public File getSafeSaveFile(String folder, String filename, String defaultExt, String... exts) throws FilenameException { public File getSafeSaveFile(String folder, String filename, String defaultExt, String... exts) throws FilenameException {
File dir = controller.getWorkingDirectoryFile(folder); File dir = controller.getWorkingDirectoryFile(folder);
return controller.getSafeSaveFile(player, dir, filename, defaultExt, exts); return controller.getSafeSaveFile(player, dir, filename, defaultExt, exts);
} }
} }

View File

@ -1,32 +1,32 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.scripting; package com.sk89q.worldedit.scripting;
import java.util.Map; import java.util.Map;
import javax.script.ScriptException; import javax.script.ScriptException;
public interface CraftScriptEngine { public interface CraftScriptEngine {
void setTimeLimit(int milliseconds); void setTimeLimit(int milliseconds);
int getTimeLimit(); int getTimeLimit();
Object evaluate(String script, String filename, Map<String, Object> args) Object evaluate(String script, String filename, Map<String, Object> args)
throws ScriptException, Throwable; throws ScriptException, Throwable;
} }

View File

@ -1,44 +1,44 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.scripting; package com.sk89q.worldedit.scripting;
import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
public abstract class CraftScriptEnvironment { public abstract class CraftScriptEnvironment {
protected WorldEdit controller; protected WorldEdit controller;
protected Player player; protected Player player;
protected LocalConfiguration config; protected LocalConfiguration config;
protected LocalSession session; protected LocalSession session;
protected Platform server; protected Platform server;
public CraftScriptEnvironment(WorldEdit controller, Platform server, LocalConfiguration config, LocalSession session, Player player) { public CraftScriptEnvironment(WorldEdit controller, Platform server, LocalConfiguration config, LocalSession session, Player player) {
this.controller = controller; this.controller = controller;
this.player = player; this.player = player;
this.config = config; this.config = config;
this.server = server; this.server = server;
this.session = session; this.session = session;
} }
} }

View File

@ -1,77 +1,77 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.scripting; package com.sk89q.worldedit.scripting;
import org.mozilla.javascript.Callable; import org.mozilla.javascript.Callable;
import org.mozilla.javascript.Context; import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory; import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.Scriptable;
public class RhinoContextFactory extends ContextFactory { public class RhinoContextFactory extends ContextFactory {
protected int timeLimit; protected int timeLimit;
public RhinoContextFactory(int timeLimit) { public RhinoContextFactory(int timeLimit) {
this.timeLimit = timeLimit; this.timeLimit = timeLimit;
} }
@Override @Override
protected Context makeContext() { protected Context makeContext() {
RhinoContext cx = new RhinoContext(this); RhinoContext cx = new RhinoContext(this);
try { try {
// Try to set ES6 compat flag (since 1.7.7) // Try to set ES6 compat flag (since 1.7.7)
Context.class.getDeclaredField("VERSION_ES6"); Context.class.getDeclaredField("VERSION_ES6");
cx.setLanguageVersion(RhinoContext.VERSION_ES6); cx.setLanguageVersion(RhinoContext.VERSION_ES6);
} catch (NoSuchFieldException e) { } catch (NoSuchFieldException e) {
// best we can do, compatible with 1.7R2 that many people probably use // best we can do, compatible with 1.7R2 that many people probably use
cx.setLanguageVersion(Context.VERSION_1_7); cx.setLanguageVersion(Context.VERSION_1_7);
} }
cx.setInstructionObserverThreshold(10000); cx.setInstructionObserverThreshold(10000);
return cx; return cx;
} }
@Override @Override
protected void observeInstructionCount(Context cx, int instructionCount) { protected void observeInstructionCount(Context cx, int instructionCount) {
RhinoContext mcx = (RhinoContext) cx; RhinoContext mcx = (RhinoContext) cx;
long currentTime = System.currentTimeMillis(); long currentTime = System.currentTimeMillis();
if (currentTime - mcx.startTime > timeLimit) { if (currentTime - mcx.startTime > timeLimit) {
throw new Error("Script timed out (" + timeLimit + "ms)"); throw new Error("Script timed out (" + timeLimit + "ms)");
} }
} }
@Override @Override
protected Object doTopCall(Callable callable, Context cx, Scriptable scope, protected Object doTopCall(Callable callable, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args) { Scriptable thisObj, Object[] args) {
RhinoContext mcx = (RhinoContext) cx; RhinoContext mcx = (RhinoContext) cx;
mcx.startTime = System.currentTimeMillis(); mcx.startTime = System.currentTimeMillis();
return super.doTopCall(callable, cx, scope, thisObj, args); return super.doTopCall(callable, cx, scope, thisObj, args);
} }
private static class RhinoContext extends Context { private static class RhinoContext extends Context {
long startTime; long startTime;
private RhinoContext(ContextFactory factory) { private RhinoContext(ContextFactory factory) {
super(factory); super(factory);
} }
} }
} }

View File

@ -1,98 +1,98 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.scripting; package com.sk89q.worldedit.scripting;
import com.google.common.io.CharStreams; import com.google.common.io.CharStreams;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.scripting.compat.BabelScriptTranspiler; import com.sk89q.worldedit.scripting.compat.BabelScriptTranspiler;
import com.sk89q.worldedit.scripting.compat.ScriptTranspiler; import com.sk89q.worldedit.scripting.compat.ScriptTranspiler;
import org.mozilla.javascript.Context; import org.mozilla.javascript.Context;
import org.mozilla.javascript.ImporterTopLevel; import org.mozilla.javascript.ImporterTopLevel;
import org.mozilla.javascript.JavaScriptException; import org.mozilla.javascript.JavaScriptException;
import org.mozilla.javascript.RhinoException; import org.mozilla.javascript.RhinoException;
import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject; import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.WrappedException; import org.mozilla.javascript.WrappedException;
import java.io.StringReader; import java.io.StringReader;
import java.util.Map; import java.util.Map;
import javax.script.ScriptException; import javax.script.ScriptException;
public class RhinoCraftScriptEngine implements CraftScriptEngine { public class RhinoCraftScriptEngine implements CraftScriptEngine {
private static final ScriptTranspiler TRANSPILER = new BabelScriptTranspiler(); private static final ScriptTranspiler TRANSPILER = new BabelScriptTranspiler();
private int timeLimit; private int timeLimit;
@Override @Override
public void setTimeLimit(int milliseconds) { public void setTimeLimit(int milliseconds) {
timeLimit = milliseconds; timeLimit = milliseconds;
} }
@Override @Override
public int getTimeLimit() { public int getTimeLimit() {
return timeLimit; return timeLimit;
} }
@Override @Override
public Object evaluate(String script, String filename, Map<String, Object> args) public Object evaluate(String script, String filename, Map<String, Object> args)
throws ScriptException, Throwable { throws ScriptException, Throwable {
String transpiled = CharStreams.toString(TRANSPILER.transpile(new StringReader(script))); String transpiled = CharStreams.toString(TRANSPILER.transpile(new StringReader(script)));
RhinoContextFactory factory = new RhinoContextFactory(timeLimit); RhinoContextFactory factory = new RhinoContextFactory(timeLimit);
Context cx = factory.enterContext(); Context cx = factory.enterContext();
cx.setClassShutter(new MinecraftHidingClassShutter()); cx.setClassShutter(new MinecraftHidingClassShutter());
ScriptableObject scriptable = new ImporterTopLevel(cx); ScriptableObject scriptable = new ImporterTopLevel(cx);
Scriptable scope = cx.initStandardObjects(scriptable); Scriptable scope = cx.initStandardObjects(scriptable);
for (Map.Entry<String, Object> entry : args.entrySet()) { for (Map.Entry<String, Object> entry : args.entrySet()) {
ScriptableObject.putProperty(scope, entry.getKey(), ScriptableObject.putProperty(scope, entry.getKey(),
Context.javaToJS(entry.getValue(), scope)); Context.javaToJS(entry.getValue(), scope));
} }
try { try {
return cx.evaluateString(scope, transpiled, filename, 1, null); return cx.evaluateString(scope, transpiled, filename, 1, null);
} catch (Error e) { } catch (Error e) {
throw new ScriptException(e.getMessage()); throw new ScriptException(e.getMessage());
} catch (RhinoException e) { } catch (RhinoException e) {
if (e instanceof WrappedException) { if (e instanceof WrappedException) {
Throwable cause = e.getCause(); Throwable cause = e.getCause();
if (cause instanceof WorldEditException) { if (cause instanceof WorldEditException) {
throw cause; throw cause;
} }
} }
String msg; String msg;
int line = (line = e.lineNumber()) == 0 ? -1 : line; int line = (line = e.lineNumber()) == 0 ? -1 : line;
if (e instanceof JavaScriptException) { if (e instanceof JavaScriptException) {
msg = String.valueOf(((JavaScriptException) e).getValue()); msg = String.valueOf(((JavaScriptException) e).getValue());
} else { } else {
msg = e.getMessage(); msg = e.getMessage();
} }
ScriptException scriptException = ScriptException scriptException =
new ScriptException(msg, e.sourceName(), line); new ScriptException(msg, e.sourceName(), line);
scriptException.initCause(e); scriptException.initCause(e);
throw scriptException; throw scriptException;
} finally { } finally {
Context.exit(); Context.exit();
} }
} }
} }

View File

@ -1,96 +1,96 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.util; package com.sk89q.worldedit.util;
import com.sk89q.util.StringUtil; import com.sk89q.util.StringUtil;
import java.io.File; import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileFilter;
public final class FileDialogUtil { public final class FileDialogUtil {
private FileDialogUtil() { private FileDialogUtil() {
} }
public static File showSaveDialog(String[] exts) { public static File showSaveDialog(String[] exts) {
JFileChooser dialog = new JFileChooser(); JFileChooser dialog = new JFileChooser();
if (exts != null) { if (exts != null) {
dialog.setFileFilter(new ExtensionFilter(exts)); dialog.setFileFilter(new ExtensionFilter(exts));
} }
int returnVal = dialog.showSaveDialog(null); int returnVal = dialog.showSaveDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) { if (returnVal == JFileChooser.APPROVE_OPTION) {
return dialog.getSelectedFile(); return dialog.getSelectedFile();
} }
return null; return null;
} }
public static File showOpenDialog(String[] exts) { public static File showOpenDialog(String[] exts) {
JFileChooser dialog = new JFileChooser(); JFileChooser dialog = new JFileChooser();
if (exts != null) { if (exts != null) {
dialog.setFileFilter(new ExtensionFilter(exts)); dialog.setFileFilter(new ExtensionFilter(exts));
} }
int returnVal = dialog.showOpenDialog(null); int returnVal = dialog.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) { if (returnVal == JFileChooser.APPROVE_OPTION) {
return dialog.getSelectedFile(); return dialog.getSelectedFile();
} }
return null; return null;
} }
private static class ExtensionFilter extends FileFilter { private static class ExtensionFilter extends FileFilter {
private Set<String> exts; private Set<String> exts;
private String desc; private String desc;
private ExtensionFilter(String[] exts) { private ExtensionFilter(String[] exts) {
this.exts = new HashSet<>(Arrays.asList(exts)); this.exts = new HashSet<>(Arrays.asList(exts));
desc = StringUtil.joinString(exts, ","); desc = StringUtil.joinString(exts, ",");
} }
@Override @Override
public boolean accept(File f) { public boolean accept(File f) {
if (f.isDirectory()) { if (f.isDirectory()) {
return true; return true;
} }
String path = f.getPath(); String path = f.getPath();
int index = path.lastIndexOf('.'); int index = path.lastIndexOf('.');
if (index == -1 || index == path.length() - 1) { if (index == -1 || index == path.length() - 1) {
return false; return false;
} else { } else {
return exts.contains(path.substring(index + 1)); return exts.contains(path.substring(index + 1));
} }
} }
@Override @Override
public String getDescription() { public String getDescription() {
return desc; return desc;
} }
} }
} }

View File

@ -1,250 +1,250 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.util; package com.sk89q.worldedit.util;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.ExistingBlockMask; import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.SolidBlockMask; 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 javax.annotation.Nullable; 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.
* *
* <p>Originally written by toi. It was ported to WorldEdit and trimmed down by * <p>Originally written by toi. It was ported to WorldEdit and trimmed down by
* sk89q. Thanks to Raphfrk for optimization of toi's original class.</p> * sk89q. Thanks to Raphfrk for optimization of toi's original class.</p>
*/ */
public class TargetBlock { public class TargetBlock {
private final Extent world; private final Extent 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;
private Vector3 targetPosDouble = Vector3.ZERO; private Vector3 targetPosDouble = Vector3.ZERO;
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 // the mask which dictates when to stop a trace - defaults to stopping at non-air blocks
private Mask stopMask; private Mask stopMask;
// the mask which dictates when to stop a solid block trace - default to BlockMaterial#isMovementBlocker // the mask which dictates when to stop a solid block trace - default to BlockMaterial#isMovementBlocker
private Mask solidMask; private Mask solidMask;
/** /**
* Constructor requiring a player, uses default values * Constructor requiring a player, uses default values
* *
* @param player player to work with * @param player player to work with
*/ */
public TargetBlock(Player player) { public TargetBlock(Player player) {
this(player, 300, 0.2); this(player, 300, 0.2);
} }
/** /**
* Constructor requiring a player, max distance and a checking distance * Constructor requiring a player, max distance and a checking distance
* *
* @param player Player to work with * @param player Player to work with
* @param maxDistance how far it checks for blocks * @param maxDistance how far it checks for blocks
* @param checkDistance how often to check for blocks, the smaller the more precise * @param checkDistance how often to check for blocks, the smaller the more precise
*/ */
public TargetBlock(Player player, int maxDistance, double checkDistance) { public TargetBlock(Player player, int maxDistance, double checkDistance) {
this(player, player.getWorld(), maxDistance, checkDistance); this(player, player.getWorld(), maxDistance, checkDistance);
} }
public TargetBlock(Player player, Extent extent, int maxDistance, double checkDistance) { public TargetBlock(Player player, Extent extent, int maxDistance, double checkDistance) {
this.world = player.getWorld(); this.world = player.getWorld();
this.setValues(player.getLocation().toVector(), 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.stopMask = new ExistingBlockMask(world);
this.solidMask = new SolidBlockMask(world); this.solidMask = new SolidBlockMask(world);
} }
/** /**
* Set the mask used for determine where to stop traces. * Set the mask used for determine where to stop traces.
* Setting to null will restore the default. * Setting to null will restore the default.
* *
* @param stopMask the mask used to stop traces * @param stopMask the mask used to stop traces
*/ */
public void setStopMask(@Nullable Mask stopMask) { public void setStopMask(@Nullable Mask stopMask) {
if (stopMask == null) { if (stopMask == null) {
this.stopMask = new ExistingBlockMask(world); this.stopMask = new ExistingBlockMask(world);
} else { } else {
this.stopMask = stopMask; this.stopMask = stopMask;
} }
} }
/** /**
* Set the mask used for determine where to stop solid block traces. * Set the mask used for determine where to stop solid block traces.
* Setting to null will restore the default. * Setting to null will restore the default.
* *
* @param solidMask the mask used to stop solid block traces * @param solidMask the mask used to stop solid block traces
*/ */
public void setSolidMask(@Nullable Mask solidMask) { public void setSolidMask(@Nullable Mask solidMask) {
if (solidMask == null) { if (solidMask == null) {
this.solidMask = new SolidBlockMask(world); this.solidMask = new SolidBlockMask(world);
} else { } else {
this.solidMask = solidMask; this.solidMask = solidMask;
} }
} }
/** /**
* Set the values, all constructors uses this function * Set the values, all constructors uses this function
* *
* @param loc location of the view * @param loc location of the view
* @param xRotation the X rotation * @param xRotation the X rotation
* @param yRotation the Y rotation * @param yRotation the Y rotation
* @param maxDistance how far it checks for blocks * @param maxDistance how far it checks for blocks
* @param viewHeight where the view is positioned in y-axis * @param viewHeight where the view is positioned in y-axis
* @param checkDistance how often to check for blocks, the smaller the more precise * @param checkDistance how often to check for blocks, the smaller the more precise
*/ */
private void setValues(Vector3 loc, double xRotation, double yRotation, int maxDistance, double viewHeight, double checkDistance) { private void setValues(Vector3 loc, double xRotation, double yRotation, int maxDistance, double viewHeight, double checkDistance) {
this.maxDistance = maxDistance; this.maxDistance = maxDistance;
this.checkDistance = checkDistance; this.checkDistance = checkDistance;
this.curDistance = 0; this.curDistance = 0;
xRotation = (xRotation + 90) % 360; xRotation = (xRotation + 90) % 360;
yRotation *= -1; yRotation *= -1;
double h = (checkDistance * Math.cos(Math.toRadians(yRotation))); double h = (checkDistance * Math.cos(Math.toRadians(yRotation)));
offset = Vector3.at((h * Math.cos(Math.toRadians(xRotation))), offset = Vector3.at((h * Math.cos(Math.toRadians(xRotation))),
(checkDistance * Math.sin(Math.toRadians(yRotation))), (checkDistance * Math.sin(Math.toRadians(yRotation))),
(h * Math.sin(Math.toRadians(xRotation)))); (h * Math.sin(Math.toRadians(xRotation))));
targetPosDouble = loc.add(0, viewHeight, 0); targetPosDouble = loc.add(0, viewHeight, 0);
targetPos = targetPosDouble.toBlockPoint(); targetPos = targetPosDouble.toBlockPoint();
prevPos = targetPos; prevPos = targetPos;
} }
/** /**
* Returns any block at the sight. Returns null if out of range or if no * Returns any block at the sight. Returns null if out of range or if no
* viable target was found. Will try to return the last valid air block it finds. * viable target was found. Will try to return the last valid air block it finds.
* *
* @return Block * @return Block
*/ */
public Location getAnyTargetBlock() { public Location getAnyTargetBlock() {
boolean searchForLastBlock = true; boolean searchForLastBlock = true;
Location lastBlock = null; Location lastBlock = null;
while (getNextBlock() != null) { while (getNextBlock() != null) {
if (stopMask.test(world, targetPos)) { if (stopMask.test(world, targetPos)) {
break; break;
} else { } 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;
} }
} }
} }
} }
Location currentBlock = getCurrentBlock(); Location currentBlock = getCurrentBlock();
return (currentBlock != null ? currentBlock : lastBlock); return (currentBlock != null ? currentBlock : lastBlock);
} }
/** /**
* Returns the block at the sight. Returns null if out of range or if no * Returns the block at the sight. Returns null if out of range or if no
* viable target was found * viable target was found
* *
* @return Block * @return Block
*/ */
public Location getTargetBlock() { public Location getTargetBlock() {
//noinspection StatementWithEmptyBody //noinspection StatementWithEmptyBody
while (getNextBlock() != null && !stopMask.test(world, targetPos)) ; while (getNextBlock() != null && !stopMask.test(world, targetPos)) ;
return getCurrentBlock(); return getCurrentBlock();
} }
/** /**
* Returns the block at the sight. Returns null if out of range or if no * Returns the block at the sight. Returns null if out of range or if no
* viable target was found * viable target was found
* *
* @return Block * @return Block
*/ */
public Location getSolidTargetBlock() { public Location getSolidTargetBlock() {
//noinspection StatementWithEmptyBody //noinspection StatementWithEmptyBody
while (getNextBlock() != null && !solidMask.test(world, targetPos)) ; while (getNextBlock() != null && !solidMask.test(world, targetPos)) ;
return getCurrentBlock(); return getCurrentBlock();
} }
/** /**
* Get next block * Get next block
* *
* @return next block position * @return next block position
*/ */
public Location getNextBlock() { public Location getNextBlock() {
prevPos = targetPos; prevPos = targetPos;
do { do {
curDistance += checkDistance; curDistance += checkDistance;
targetPosDouble = offset.add(targetPosDouble.getX(), targetPosDouble = offset.add(targetPosDouble.getX(),
targetPosDouble.getY(), targetPosDouble.getY(),
targetPosDouble.getZ()); targetPosDouble.getZ());
targetPos = targetPosDouble.toBlockPoint(); targetPos = targetPosDouble.toBlockPoint();
} while (curDistance <= maxDistance } while (curDistance <= maxDistance
&& targetPos.getBlockX() == prevPos.getBlockX() && targetPos.getBlockX() == prevPos.getBlockX()
&& targetPos.getBlockY() == prevPos.getBlockY() && targetPos.getBlockY() == prevPos.getBlockY()
&& targetPos.getBlockZ() == prevPos.getBlockZ()); && targetPos.getBlockZ() == prevPos.getBlockZ());
if (curDistance > maxDistance) { if (curDistance > maxDistance) {
return null; return null;
} }
return new Location(world, targetPos.toVector3()); return new Location(world, targetPos.toVector3());
} }
/** /**
* Returns the current block along the line of vision * Returns the current block along the line of vision
* *
* @return block position * @return block position
*/ */
public Location getCurrentBlock() { public Location getCurrentBlock() {
if (curDistance > maxDistance) { if (curDistance > maxDistance) {
return null; return null;
} else { } else {
return new Location(world, targetPos.toVector3()); return new Location(world, targetPos.toVector3());
} }
} }
/** /**
* Returns the previous block in the aimed path * Returns the previous block in the aimed path
* *
* @return block position * @return block position
*/ */
public Location getPreviousBlock() { public Location getPreviousBlock() {
return new Location(world, prevPos.toVector3()); return new Location(world, prevPos.toVector3());
} }
public Location getAnyTargetBlockFace() { public Location getAnyTargetBlockFace() {
getAnyTargetBlock(); getAnyTargetBlock();
Location current = getCurrentBlock(); Location current = getCurrentBlock();
if (current != null) if (current != null)
return current.setDirection(current.toVector().subtract(getPreviousBlock().toVector())); return current.setDirection(current.toVector().subtract(getPreviousBlock().toVector()));
else else
return new Location(world, targetPos.toVector3(), Float.NaN, Float.NaN); return new Location(world, targetPos.toVector3(), Float.NaN, Float.NaN);
} }
public Location getTargetBlockFace() { public Location getTargetBlockFace() {
getTargetBlock(); getTargetBlock();
if (getCurrentBlock() == null) return null; if (getCurrentBlock() == null) return null;
return getCurrentBlock().setDirection(getCurrentBlock().toVector().subtract(getPreviousBlock().toVector())); return getCurrentBlock().setDirection(getCurrentBlock().toVector().subtract(getPreviousBlock().toVector()));
} }
} }

View File

@ -1,270 +1,270 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.util; package com.sk89q.worldedit.util;
import com.google.common.collect.ImmutableList; 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;
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;
import com.sk89q.worldedit.world.block.BlockTypes; 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.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;
import javax.annotation.Nullable; import javax.annotation.Nullable;
/** /**
* Tree generator. * Tree generator.
*/ */
public class TreeGenerator { public class TreeGenerator {
public enum TreeType { public enum TreeType {
TREE("Oak tree", "oak", "tree", "regular"), TREE("Oak tree", "oak", "tree", "regular"),
BIG_TREE("Large oak tree", "largeoak", "bigoak", "big", "bigtree"), BIG_TREE("Large oak tree", "largeoak", "bigoak", "big", "bigtree"),
REDWOOD("Spruce tree", "spruce", "redwood", "sequoia", "sequoioideae"), REDWOOD("Spruce tree", "spruce", "redwood", "sequoia", "sequoioideae"),
TALL_REDWOOD("Tall spruce tree", "tallspruce", "bigspruce", "tallredwood", "tallsequoia", "tallsequoioideae"), TALL_REDWOOD("Tall spruce tree", "tallspruce", "bigspruce", "tallredwood", "tallsequoia", "tallsequoioideae"),
MEGA_REDWOOD("Large spruce tree", "largespruce", "megaredwood"), MEGA_REDWOOD("Large spruce tree", "largespruce", "megaredwood"),
RANDOM_REDWOOD("Random spruce tree", "randspruce", "randredwood", "randomredwood", "anyredwood") { RANDOM_REDWOOD("Random spruce tree", "randspruce", "randredwood", "randomredwood", "anyredwood") {
@Override @Override
public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException { public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException {
TreeType[] choices = { REDWOOD, TALL_REDWOOD, MEGA_REDWOOD }; TreeType[] choices = { REDWOOD, TALL_REDWOOD, MEGA_REDWOOD };
return choices[TreeGenerator.RANDOM.nextInt(choices.length)].generate(editSession, pos); return choices[TreeGenerator.RANDOM.nextInt(choices.length)].generate(editSession, pos);
} }
}, },
BIRCH("Birch tree", "birch", "white", "whitebark"), BIRCH("Birch tree", "birch", "white", "whitebark"),
TALL_BIRCH("Tall birch tree", "tallbirch"), TALL_BIRCH("Tall birch tree", "tallbirch"),
RANDOM_BIRCH("Random birch tree", "randbirch", "randombirch") { RANDOM_BIRCH("Random birch tree", "randbirch", "randombirch") {
@Override @Override
public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException { public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException {
TreeType[] choices = { BIRCH, TALL_BIRCH }; TreeType[] choices = { BIRCH, TALL_BIRCH };
return choices[TreeGenerator.RANDOM.nextInt(choices.length)].generate(editSession, pos); return choices[TreeGenerator.RANDOM.nextInt(choices.length)].generate(editSession, pos);
} }
}, },
JUNGLE("Jungle tree", "jungle"), JUNGLE("Jungle tree", "jungle"),
SMALL_JUNGLE("Small jungle tree", "smalljungle"), SMALL_JUNGLE("Small jungle tree", "smalljungle"),
SHORT_JUNGLE("Short jungle tree", "shortjungle") { 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);
} }
}, },
RANDOM_JUNGLE("Random jungle tree", "randjungle", "randomjungle") { RANDOM_JUNGLE("Random jungle tree", "randjungle", "randomjungle") {
@Override @Override
public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException { public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException {
TreeType[] choices = { JUNGLE, SMALL_JUNGLE }; TreeType[] choices = { JUNGLE, SMALL_JUNGLE };
return choices[TreeGenerator.RANDOM.nextInt(choices.length)].generate(editSession, pos); return choices[TreeGenerator.RANDOM.nextInt(choices.length)].generate(editSession, pos);
} }
}, },
JUNGLE_BUSH("Jungle bush", "junglebush", "jungleshrub"), JUNGLE_BUSH("Jungle bush", "junglebush", "jungleshrub"),
RED_MUSHROOM("Red mushroom", "redmushroom", "redgiantmushroom"), RED_MUSHROOM("Red mushroom", "redmushroom", "redgiantmushroom"),
BROWN_MUSHROOM("Brown mushroom", "brownmushroom", "browngiantmushroom"), BROWN_MUSHROOM("Brown mushroom", "brownmushroom", "browngiantmushroom"),
RANDOM_MUSHROOM("Random mushroom", "randmushroom", "randommushroom") { RANDOM_MUSHROOM("Random mushroom", "randmushroom", "randommushroom") {
@Override @Override
public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException { public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException {
TreeType[] choices = { RED_MUSHROOM, BROWN_MUSHROOM }; TreeType[] choices = { RED_MUSHROOM, BROWN_MUSHROOM };
return choices[TreeGenerator.RANDOM.nextInt(choices.length)].generate(editSession, pos); return choices[TreeGenerator.RANDOM.nextInt(choices.length)].generate(editSession, pos);
} }
}, },
SWAMP("Swamp tree", "swamp", "swamptree"), SWAMP("Swamp tree", "swamp", "swamptree"),
ACACIA("Acacia tree", "acacia"), ACACIA("Acacia tree", "acacia"),
DARK_OAK("Dark oak tree", "darkoak"), DARK_OAK("Dark oak tree", "darkoak"),
PINE("Pine tree", "pine") { PINE("Pine tree", "pine") {
@Override @Override
public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException { public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException {
makePineTree(editSession, pos); makePineTree(editSession, pos);
return true; return true;
} }
}, },
RANDOM("Random tree", "rand", "random") { RANDOM("Random tree", "rand", "random") {
@Override @Override
public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException { public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException {
TreeType[] choices = TreeType.values(); TreeType[] choices = TreeType.values();
return choices[TreeGenerator.RANDOM.nextInt(choices.length)].generate(editSession, pos); return choices[TreeGenerator.RANDOM.nextInt(choices.length)].generate(editSession, pos);
} }
}; };
/** /**
* Stores a map of the names for fast access. * Stores a map of the names for fast access.
*/ */
private static final Map<String, TreeType> lookup = new HashMap<>(); private static final Map<String, TreeType> lookup = new HashMap<>();
private static final Set<String> primaryAliases = Sets.newHashSet(); private static final Set<String> primaryAliases = Sets.newHashSet();
private final String name; private final String name;
public final ImmutableList<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.size() > 0) { if (type.lookupKeys.size() > 0) {
primaryAliases.add(type.lookupKeys.get(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 = ImmutableList.copyOf(lookupKeys); this.lookupKeys = ImmutableList.copyOf(lookupKeys);
} }
public static Set<String> getAliases() { public static Set<String> getAliases() {
return Collections.unmodifiableSet(lookup.keySet()); return Collections.unmodifiableSet(lookup.keySet());
} }
public static Set<String> getPrimaryAliases() { public static Set<String> getPrimaryAliases() {
return Collections.unmodifiableSet(primaryAliases); return Collections.unmodifiableSet(primaryAliases);
} }
public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException { public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException {
return editSession.getWorld().generateTree(this, editSession, pos); return editSession.getWorld().generateTree(this, editSession, pos);
} }
/** /**
* Get user-friendly tree type name. * Get user-friendly tree type name.
* *
* @return a name * @return a name
*/ */
public String getName() { public String getName() {
return name; return name;
} }
/** /**
* Return type from name. May return null. * Return type from name. May return null.
* *
* @param name name to search * @param name name to search
* @return a tree type or null * @return a tree type or null
*/ */
@Nullable @Nullable
public static TreeType lookup(String name) { public static TreeType lookup(String name) {
return lookup.get(name.replace("_", "").toLowerCase(Locale.ROOT)); return lookup.get(name.replace("_", "").toLowerCase(Locale.ROOT));
} }
} }
private TreeGenerator() { private TreeGenerator() {
} }
private static final Random RANDOM = new Random(); private static final Random RANDOM = new Random();
/** /**
* Makes a terrible looking pine tree. * Makes a terrible looking pine tree.
* *
* @param basePosition the base position * @param basePosition the base position
*/ */
private static void makePineTree(EditSession editSession, BlockVector3 basePosition) private static void makePineTree(EditSession editSession, BlockVector3 basePosition)
throws MaxChangedBlocksException { throws MaxChangedBlocksException {
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;
BlockState logBlock = BlockTypes.OAK_LOG.getDefaultState(); BlockState logBlock = BlockTypes.OAK_LOG.getDefaultState();
BlockState 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) {
if (!setBlockIfAir(editSession, basePosition.add(0, i, 0), logBlock)) { if (!setBlockIfAir(editSession, basePosition.add(0, i, 0), logBlock)) {
return; return;
} }
} }
// Move up // Move up
basePosition = basePosition.add(0, trunkHeight, 0); basePosition = basePosition.add(0, trunkHeight, 0);
// Create tree + leaves // Create tree + leaves
for (int i = 0; i < height; ++i) { for (int i = 0; i < height; ++i) {
setBlockIfAir(editSession, basePosition.add(0, i, 0), logBlock); setBlockIfAir(editSession, basePosition.add(0, i, 0), logBlock);
// Less leaves at these levels // Less leaves at these levels
double chance = ((i == 0 || i == height - 1) ? 0.6 : 1); double chance = ((i == 0 || i == height - 1) ? 0.6 : 1);
// Inner leaves // Inner leaves
setChanceBlockIfAir(editSession, basePosition.add(-1, i, 0), leavesBlock, chance); setChanceBlockIfAir(editSession, basePosition.add(-1, i, 0), leavesBlock, chance);
setChanceBlockIfAir(editSession, basePosition.add(1, i, 0), leavesBlock, chance); setChanceBlockIfAir(editSession, basePosition.add(1, i, 0), leavesBlock, chance);
setChanceBlockIfAir(editSession, basePosition.add(0, i, -1), leavesBlock, chance); setChanceBlockIfAir(editSession, basePosition.add(0, i, -1), leavesBlock, chance);
setChanceBlockIfAir(editSession, basePosition.add(0, i, 1), leavesBlock, chance); setChanceBlockIfAir(editSession, basePosition.add(0, i, 1), leavesBlock, chance);
setChanceBlockIfAir(editSession, basePosition.add(1, i, 1), leavesBlock, chance); setChanceBlockIfAir(editSession, basePosition.add(1, i, 1), leavesBlock, chance);
setChanceBlockIfAir(editSession, basePosition.add(-1, i, 1), leavesBlock, chance); setChanceBlockIfAir(editSession, basePosition.add(-1, i, 1), leavesBlock, chance);
setChanceBlockIfAir(editSession, basePosition.add(1, i, -1), leavesBlock, chance); setChanceBlockIfAir(editSession, basePosition.add(1, i, -1), leavesBlock, chance);
setChanceBlockIfAir(editSession, basePosition.add(-1, i, -1), leavesBlock, chance); setChanceBlockIfAir(editSession, basePosition.add(-1, i, -1), leavesBlock, chance);
if (!(i == 0 || i == height - 1)) { if (!(i == 0 || i == height - 1)) {
for (int j = -2; j <= 2; ++j) { for (int j = -2; j <= 2; ++j) {
setChanceBlockIfAir(editSession, basePosition.add(-2, i, j), leavesBlock, 0.6); setChanceBlockIfAir(editSession, basePosition.add(-2, i, j), leavesBlock, 0.6);
} }
for (int j = -2; j <= 2; ++j) { for (int j = -2; j <= 2; ++j) {
setChanceBlockIfAir(editSession, basePosition.add(2, i, j), leavesBlock, 0.6); setChanceBlockIfAir(editSession, basePosition.add(2, i, j), leavesBlock, 0.6);
} }
for (int j = -2; j <= 2; ++j) { for (int j = -2; j <= 2; ++j) {
setChanceBlockIfAir(editSession, basePosition.add(j, i, -2), leavesBlock, 0.6); setChanceBlockIfAir(editSession, basePosition.add(j, i, -2), leavesBlock, 0.6);
} }
for (int j = -2; j <= 2; ++j) { for (int j = -2; j <= 2; ++j) {
setChanceBlockIfAir(editSession, basePosition.add(j, i, 2), leavesBlock, 0.6); setChanceBlockIfAir(editSession, basePosition.add(j, i, 2), leavesBlock, 0.6);
} }
} }
} }
setBlockIfAir(editSession, basePosition.add(0, height, 0), leavesBlock); setBlockIfAir(editSession, basePosition.add(0, height, 0), leavesBlock);
} }
/** /**
* Looks up a tree type. May return null if a tree type by that * Looks up a tree type. May return null if a tree type by that
* name is not found. * name is not found.
* *
* @param type the tree type * @param type the tree type
* @return a tree type or null * @return a tree type or null
*/ */
@Nullable @Nullable
public static TreeType lookup(String type) { public static TreeType lookup(String type) {
return TreeType.lookup(type); return TreeType.lookup(type);
} }
/** /**
* Set a block (only if a previous block was not there) if {@link Math#random()} * Set a block (only if a previous block was not there) if {@link Math#random()}
* returns a number less than the given probability. * returns a number less than the given probability.
* *
* @param position the position * @param position the position
* @param block the block * @param block the block
* @param probability a probability between 0 and 1, inclusive * @param probability a probability between 0 and 1, inclusive
* @return whether a block was changed * @return whether a block was changed
* @throws MaxChangedBlocksException thrown if too many blocks are changed * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
private static <B extends BlockStateHolder<B>> boolean setChanceBlockIfAir(EditSession session, BlockVector3 position, B block, double probability) private static <B extends BlockStateHolder<B>> boolean setChanceBlockIfAir(EditSession session, BlockVector3 position, B block, double probability)
throws MaxChangedBlocksException { throws MaxChangedBlocksException {
return Math.random() <= probability && setBlockIfAir(session, position, block); return Math.random() <= probability && setBlockIfAir(session, position, block);
} }
/** /**
* Set a block only if there's no block already there. * Set a block only if there's no block already there.
* *
* @param position the position * @param position the position
* @param block the block to set * @param block the block to set
* @return if block was changed * @return if block was changed
* @throws MaxChangedBlocksException thrown if too many blocks are changed * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
private static <B extends BlockStateHolder<B>> boolean setBlockIfAir(EditSession session, BlockVector3 position, B block) throws MaxChangedBlocksException { private static <B extends BlockStateHolder<B>> boolean setBlockIfAir(EditSession session, BlockVector3 position, B block) throws MaxChangedBlocksException {
return session.getBlock(position).getBlockType().getMaterial().isAir() && session.setBlock(position, block); return session.getBlock(position).getBlockType().getMaterial().isAir() && session.setBlock(position, block);
} }
} }

View File

@ -1,23 +1,23 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.util.io.file; package com.sk89q.worldedit.util.io.file;
import java.io.Closeable; import java.io.Closeable;
import java.nio.file.Path; import java.nio.file.Path;

View File

@ -1,23 +1,23 @@
/* /*
* WorldEdit, a Minecraft world manipulation toolkit * WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com> * Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors * Copyright (C) WorldEdit team and contributors
* *
* This program is free software: you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or * Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details. * for more details.
* *
* 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.util.io.file; package com.sk89q.worldedit.util.io.file;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;