Upstream merge

This commit is contained in:
MattBDev 2020-03-23 20:47:30 -04:00
parent 692caeea8a
commit e7df3177cc
17 changed files with 387 additions and 90 deletions

View File

@ -59,6 +59,7 @@ public abstract class LocalConfiguration {
protected BlockMask disallowedBlocksMask;
public int defaultChangeLimit = -1;
public int maxChangeLimit = -1;
public int defaultVerticalHeight = 256;
public int defaultMaxPolygonalPoints = -1;
public int maxPolygonalPoints = 20;
public int defaultMaxPolyhedronPoints = -1;

View File

@ -0,0 +1,94 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.argument;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Range;
import com.google.common.reflect.TypeToken;
import com.sk89q.worldedit.internal.annotation.Chunk3d;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import org.enginehub.piston.CommandManager;
import org.enginehub.piston.converter.ArgumentConverter;
import org.enginehub.piston.converter.ArgumentConverters;
import org.enginehub.piston.converter.ConversionResult;
import org.enginehub.piston.converter.FailedConversion;
import org.enginehub.piston.converter.SuccessfulConversion;
import org.enginehub.piston.inject.InjectedValueAccess;
import org.enginehub.piston.inject.Key;
import java.util.List;
import java.util.function.Function;
public class Chunk3dVectorConverter<C, T> implements ArgumentConverter<T> {
public static void register(CommandManager commandManager) {
CommaSeparatedValuesConverter<Integer> intConverter = CommaSeparatedValuesConverter.wrap(ArgumentConverters.get(TypeToken.of(int.class)));
commandManager.registerConverter(Key.of(BlockVector3.class, Chunk3d.class),
new Chunk3dVectorConverter<>(
intConverter,
Range.closed(2, 3),
cmps -> {
switch (cmps.size()) {
case 2:
return BlockVector3.at(cmps.get(0), 0, cmps.get(1));
case 3:
return BlockVector3.at(cmps.get(0), cmps.get(1), cmps.get(2));
}
throw new AssertionError("Expected 2 or 3 components");
},
"block vector with x,z or x,y,z"
));
}
private final ArgumentConverter<C> componentConverter;
private final Range<Integer> componentCount;
private final Function<List<C>, T> vectorConstructor;
private final String acceptableArguments;
private Chunk3dVectorConverter(ArgumentConverter<C> componentConverter,
Range<Integer> componentCount,
Function<List<C>, T> vectorConstructor,
String acceptableArguments) {
this.componentConverter = componentConverter;
this.componentCount = componentCount;
this.vectorConstructor = vectorConstructor;
this.acceptableArguments = acceptableArguments;
}
@Override
public Component describeAcceptableArguments() {
return TextComponent.of("any " + acceptableArguments);
}
@Override
public ConversionResult<T> convert(String argument, InjectedValueAccess context) {
ConversionResult<C> components = componentConverter.convert(argument, context);
if (!components.isSuccessful()) {
return components.failureAsAny();
}
if (!componentCount.contains(components.get().size())) {
return FailedConversion.from(new IllegalArgumentException(
"Must have " + componentCount + " vector components"));
}
T vector = vectorConstructor.apply(ImmutableList.copyOf(components.get()));
return SuccessfulConversion.fromSingle(vector);
}
}

View File

@ -0,0 +1,74 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.argument;
import com.google.common.reflect.TypeToken;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.internal.annotation.VertHeight;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import org.enginehub.piston.CommandManager;
import org.enginehub.piston.converter.ArgumentConverter;
import org.enginehub.piston.converter.ArgumentConverters;
import org.enginehub.piston.converter.ConversionResult;
import org.enginehub.piston.converter.SuccessfulConversion;
import org.enginehub.piston.inject.InjectedValueAccess;
import org.enginehub.piston.inject.Key;
/**
* Converter for handling default heights as the
* {@linkplain LocalConfiguration#defaultVerticalHeight currently configured
* height}.
*/
public class HeightConverter implements ArgumentConverter<Integer> {
/**
* The value that converts to the default vertical height.
*/
public static final String DEFAULT_VALUE = "default-vertical-height";
private static final ArgumentConverter<Integer> INT_CONVERTER =
ArgumentConverters.get(TypeToken.of(int.class));
public static void register(CommandManager commandManager) {
commandManager.registerConverter(Key.of(int.class, VertHeight.class),
new HeightConverter()
);
}
private HeightConverter() {
}
@Override
public Component describeAcceptableArguments() {
return TextComponent.of("Any integer");
}
@Override
public ConversionResult<Integer> convert(String argument, InjectedValueAccess context) {
if (DEFAULT_VALUE.equals(argument)) {
return SuccessfulConversion.fromSingle(
WorldEdit.getInstance().getConfiguration().defaultVerticalHeight
);
}
return INT_CONVERTER.convert(argument, context);
}
}

View File

@ -135,25 +135,6 @@ public interface ClipboardFormat {
}
default URL uploadPublic(final Clipboard clipboard, String category, String user) {
// summary
// blocks
HashMap<String, Object> map = new HashMap<>();
BlockVector3 dimensions = clipboard.getDimensions();
map.put("width", dimensions.getX());
map.put("height", dimensions.getY());
map.put("length", dimensions.getZ());
map.put("creator", user);
Gson gson = new Gson();
String json = gson.toJson(map);
return MainUtil.upload(Settings.IMP.WEB.ASSETS, false, json, category, null, new RunnableVal<OutputStream>() {
@Override
public void run(OutputStream value) {
write(value, clipboard);
}
});
}
default URL uploadAnonymous(final Clipboard clipboard) {
return MainUtil.upload(null, null, getPrimaryFileExtension(), new RunnableVal<OutputStream>() {
@Override

View File

@ -177,81 +177,70 @@ public class ClipboardFormats {
input = new URL(base, "uploads/" + input.substring(4) + "." + format.getPrimaryFileExtension()).toString();
}
if (input.startsWith("http")) {
if (!player.hasPermission("worldedit.schematic.load.asset")) {
if (message) player.print(Caption.of("fawe.error.no-perm", "worldedit.schematic.load.asset"));
return null;
}
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}").matcher(input).find() && !player.hasPermission("worldedit.schematic.load.other")) {
player.print(Caption.of("fawe.error.no-perm", "worldedit.schematic.load.other"));
return null;
}
File working = worldEdit.getWorkingDirectoryFile(config.saveDir);
File dir = Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS ? new File(working, player.getUniqueId().toString()) : working;
File f;
if (input.startsWith("#")) {
String[] extensions;
if (format != null) {
extensions = format.getFileExtensions().toArray(new String[0]);
} else {
extensions = ClipboardFormats.getFileExtensionArray();
}
f = player.openFileOpenDialog(extensions);
if (f == null || !f.exists()) {
if (message) player.printError("Schematic " + input + " does not exist! (" + f + ")");
return null;
}
URL url = new URL(input);
URL webInterface = new URL(Settings.IMP.WEB.ASSETS);
if (!url.getHost().equalsIgnoreCase(webInterface.getHost())) {
if (message) player.print(Caption.of("fawe.error.web.unauthorized", url));
return null;
}
return loadAllFromUrl(url);
} else {
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}").matcher(input).find() && !player.hasPermission("worldedit.schematic.load.other")) {
player.print(Caption.of("fawe.error.no-perm", "worldedit.schematic.load.other"));
if (message) player.print(Caption.of("fawe.error.no-perm", "worldedit.schematic.load.other"));
return null;
}
File working = worldEdit.getWorkingDirectoryFile(config.saveDir);
File dir = Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS ? new File(working, player.getUniqueId().toString()) : working;
File f;
if (input.startsWith("#")) {
String[] extensions;
if (format != null) {
extensions = format.getFileExtensions().toArray(new String[0]);
} else {
extensions = ClipboardFormats.getFileExtensionArray();
}
f = player.openFileOpenDialog(extensions);
if (f == null || !f.exists()) {
if (message) player.printError("Schematic " + input + " does not exist! (" + f + ")");
return null;
}
} else {
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}").matcher(input).find() && !player.hasPermission("worldedit.schematic.load.other")) {
if (message) player.print(Caption.of("fawe.error.no-perm", "worldedit.schematic.load.other"));
return null;
}
if (format == null && input.matches(".*\\.[\\w].*")) {
String extension = input.substring(input.lastIndexOf('.') + 1);
format = findByExtension(extension);
}
if (format == null && input.matches(".*\\.[\\w].*")) {
String extension = input.substring(input.lastIndexOf('.') + 1);
format = findByExtension(extension);
}
f = MainUtil.resolve(dir, input, format, true);
}
if (f == null || !f.exists()) {
if (!input.contains("../")) {
dir = worldEdit.getWorkingDirectoryFile(config.saveDir);
f = MainUtil.resolve(dir, input, format, true);
}
if (f == null || !f.exists()) {
if (!input.contains("../")) {
dir = worldEdit.getWorkingDirectoryFile(config.saveDir);
f = MainUtil.resolve(dir, input, format, true);
}
}
if (f == null || !f.exists() || !MainUtil.isInSubDirectory(working, f)) {
if (message) player.printError("Schematic " + input + " does not exist! (" + ((f != null) && f.exists()) + "|" + f + "|" + (f != null && !MainUtil.isInSubDirectory(working, f)) + ")");
return null;
}
if (format == null && f.isFile()) {
format = findByFile(f);
if (format == null) {
player.print(Caption.of("fawe.worldedit.clipboard.clipboard.invalid.format" , f.getName()));
return null;
}
}
if (!f.exists()) {
if (message) player.print(Caption.of("fawe.error.schematic.not.found" , input));
return null;
}
if (!f.isDirectory()) {
ByteSource source = Files.asByteSource(f);
URI uri = f.toURI();
return new MultiClipboardHolder(uri, new LazyClipboardHolder(f.toURI(), source, format, null));
}
URIClipboardHolder[] clipboards = loadAllFromDirectory(f);
if (clipboards.length < 1) {
if (message) player.print(Caption.of("fawe.error.schematic.not.found" , input));
return null;
}
return new MultiClipboardHolder(f.toURI(), clipboards);
}
if (f == null || !f.exists() || !MainUtil.isInSubDirectory(working, f)) {
if (message) player.printError("Schematic " + input + " does not exist! (" + ((f != null) && f.exists()) + "|" + f + "|" + (f != null && !MainUtil.isInSubDirectory(working, f)) + ")");
return null;
}
if (format == null && f.isFile()) {
format = findByFile(f);
if (format == null) {
player.print(Caption.of("fawe.worldedit.clipboard.clipboard.invalid.format" , f.getName()));
return null;
}
}
if (!f.exists()) {
if (message) player.print(Caption.of("fawe.error.schematic.not.found" , input));
return null;
}
if (!f.isDirectory()) {
ByteSource source = Files.asByteSource(f);
URI uri = f.toURI();
return new MultiClipboardHolder(uri, new LazyClipboardHolder(f.toURI(), source, format, null));
}
URIClipboardHolder[] clipboards = loadAllFromDirectory(f);
if (clipboards.length < 1) {
if (message) player.print(Caption.of("fawe.error.schematic.not.found" , input));
return null;
}
return new MultiClipboardHolder(f.toURI(), clipboards);
}
public static URIClipboardHolder[] loadAllFromDirectory(File dir) {

View File

@ -0,0 +1,41 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.internal.annotation;
import org.enginehub.piston.inject.InjectAnnotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that this value is for 3d-chunk compatibility.
*
* <p>
* For vectors, this means that the vector supports 2D & 3D inputs,
* with 2D getting a Y value of 0.
* </p>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@InjectAnnotation
public @interface Chunk3d {
}

View File

@ -0,0 +1,36 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.internal.annotation;
import org.enginehub.piston.inject.InjectAnnotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that this value is for holding the vertical height.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@InjectAnnotation
public @interface VertHeight {
}

View File

@ -0,0 +1,51 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.internal.util;
import net.royawesome.jlibnoise.MathHelper;
public class BiomeMath {
// From BiomeArray / BiomeContainer
public static final int HORIZONTAL_SECTION_COUNT = (int) Math.round(Math.log(16.0D) / Math.log(2.0D)) - 2;
public static final int VERTICAL_SECTION_COUNT = (int)Math.round(Math.log(256.0D) / Math.log(2.0D)) - 2;
public static final int HORIZONTAL_BIT_MASK = (1 << HORIZONTAL_SECTION_COUNT) - 1;
public static final int VERTICAL_BIT_MASK = (1 << VERTICAL_SECTION_COUNT) - 1;
private BiomeMath() {
}
/**
* Compute the index into the MC biome array.
*
* @param x the block x coordinate
* @param y the block y coordinate
* @param z the block z coordinate
* @return the index into the standard MC biome array
*/
public static int computeBiomeIndex(int x, int y, int z) {
int l = x & HORIZONTAL_BIT_MASK;
int m = MathHelper.clamp(y, 0, VERTICAL_BIT_MASK);
int n = z & HORIZONTAL_BIT_MASK;
return m << HORIZONTAL_SECTION_COUNT + HORIZONTAL_SECTION_COUNT
| n << HORIZONTAL_SECTION_COUNT
| l;
}
}

View File

@ -31,12 +31,12 @@ import java.util.List;
public final class Polygons {
private Polygons() {
}
/**
* Calculates the polygon shape of a cylinder which can then be used for e.g. intersection detection.
*
*
* @param center the center point of the cylinder
* @param radius the radius of the cylinder
* @param maxPoints max points to be used for the calculation
@ -60,5 +60,5 @@ public final class Polygons {
return points;
}
}

View File

@ -21,7 +21,10 @@ package com.sk89q.worldedit.world.biome;
/**
* Provides information about a biome.
*
* @deprecated This no longer returns useful information.
*/
@Deprecated
public interface BiomeData {
/**

View File

@ -28,7 +28,10 @@ import javax.annotation.Nullable;
/**
* Returns the name of a biome using a given {@code BiomeRegistry}.
*
* @deprecated for removal, appears to be unused
*/
@Deprecated
class BiomeName implements Function<BiomeType, String> {
private final BiomeRegistry registry;

View File

@ -35,7 +35,10 @@ import javax.annotation.Nullable;
/**
* Utility methods related to biomes.
*
* @deprecated Only method is being deprecated for removal.
*/
@Deprecated
public final class Biomes {
private Biomes() {
@ -48,7 +51,9 @@ public final class Biomes {
* @param name the name to test
* @param registry a biome registry
* @return a biome or null
* @deprecated This uses the outdated name system. Find names by comparing with their ID instead.
*/
@Deprecated
@Nullable
public static BiomeType findBiomeByName(Collection<BiomeType> biomes, String name, BiomeRegistry registry) {
checkNotNull(biomes);

View File

@ -21,7 +21,6 @@ package com.sk89q.worldedit.world.block;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.beta.ITileInput;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
@ -36,6 +35,7 @@ import com.sk89q.worldedit.world.registry.BlockMaterial;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import java.util.Map;
import java.util.Objects;
import javax.annotation.Nullable;
/**
@ -197,7 +197,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
/**
* Checks if the type is the same, and if the matched states are the same.
*
*
* @param o other block
* @return true if equal
*/

View File

@ -35,6 +35,7 @@ public interface BiomeRegistry {
* @param biome the biome
* @return a data object or null if information is not known
*/
@Deprecated
@Nullable
BiomeData getData(BiomeType biome);

View File

@ -40,6 +40,7 @@ public interface BlockRegistry {
* @param blockType the block
* @return The name, or null if it's unknown
*/
@Deprecated
@Nullable
String getName(BlockType blockType);

View File

@ -33,6 +33,7 @@ public interface ItemRegistry {
* @param itemType the item
* @return The name, or null if it's unknown
*/
@Deprecated
@Nullable
String getName(ItemType itemType);

View File

@ -40,6 +40,22 @@ public abstract class ChunkStore implements Closeable {
*/
public static final int CHUNK_SHIFTS = 4;
/**
* {@code >>} - to Y of 3D-chunk
* {@code <<} - from Y of 3D-chunk
*/
public static final int CHUNK_SHIFTS_Y = 8;
/**
* Convert a position to a 3D-chunk. Y is counted in steps of 256.
*
* @param position the position
* @return chunk coordinates
*/
public static BlockVector3 toChunk3d(BlockVector3 position) {
return position.shr(CHUNK_SHIFTS, CHUNK_SHIFTS_Y, CHUNK_SHIFTS);
}
/**
* Convert a position to a chunk.
*