Merge branch '1.16' into update-adapters

This commit is contained in:
N0tMyFaultOG 2020-09-02 17:41:08 +02:00
commit ec141ecb46
37 changed files with 2303 additions and 939 deletions

View File

@ -2,15 +2,15 @@ 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
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/>.

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@ fun Project.applyCommonConfiguration() {
artifact("/[organisation]/[revision]/artifact/[module].[ext]") artifact("/[organisation]/[revision]/artifact/[module].[ext]")
}} }}
} }
configurations.all { configurations.all {
resolutionStrategy { resolutionStrategy {
cacheChangingModulesFor(5, "MINUTES") cacheChangingModulesFor(5, "MINUTES")

View File

@ -393,6 +393,15 @@ public class AsyncBlock implements Block {
return this.getUnsafeBlock().rayTrace(arg0, arg1, arg2, arg3); return this.getUnsafeBlock().rayTrace(arg0, arg1, arg2, arg3);
} }
public boolean applyBoneMeal(@NotNull BlockFace face) {
throw new UnsupportedOperationException("FAWE does not support this method");
}
public String getTranslationKey() {
throw new UnsupportedOperationException("FAWE does not support this yet");
}
@NotNull @NotNull
@Override @Override
public BoundingBox getBoundingBox() { public BoundingBox getBoundingBox() {

View File

@ -1,3 +1,22 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.internal.util package com.sk89q.worldedit.internal.util
import com.sk89q.worldedit.util.formatting.WorldEditText import com.sk89q.worldedit.util.formatting.WorldEditText

View File

@ -25,9 +25,9 @@ import com.google.common.collect.ImmutableSet;
import com.sk89q.worldedit.UnknownDirectionException; import com.sk89q.worldedit.UnknownDirectionException;
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.Actor;
import com.sk89q.worldedit.internal.annotation.Direction; import com.sk89q.worldedit.internal.annotation.Direction;
import com.sk89q.worldedit.internal.annotation.MultiDirection; import com.sk89q.worldedit.internal.annotation.MultiDirection;
import com.sk89q.worldedit.internal.annotation.OptionalArg;
import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent; import com.sk89q.worldedit.util.formatting.text.TextComponent;
import org.enginehub.piston.CommandManager; import org.enginehub.piston.CommandManager;
@ -58,12 +58,12 @@ public abstract class AbstractDirectionConverter<D> implements ArgumentConverter
protected static <D> void register(CommandManager commandManager, AbstractDirectionConverter<D> converter, protected static <D> void register(CommandManager commandManager, AbstractDirectionConverter<D> converter,
Class<D> keyClass, boolean includeDiagonals) { Class<D> keyClass, boolean includeDiagonals) {
commandManager.registerConverter( commandManager.registerConverter(
Key.of(keyClass, direction(includeDiagonals)), Key.of(keyClass, direction(includeDiagonals)),
converter converter
); );
commandManager.registerConverter( commandManager.registerConverter(
Key.of(keyClass, multiDirection(includeDiagonals)), Key.of(keyClass, multiDirection(includeDiagonals)),
CommaSeparatedValuesConverter.wrap(converter) CommaSeparatedValuesConverter.wrap(converter)
); );
} }
@ -93,8 +93,8 @@ public abstract class AbstractDirectionConverter<D> implements ArgumentConverter
@Override @Override
public ConversionResult<D> convert(String argument, InjectedValueAccess context) { public ConversionResult<D> convert(String argument, InjectedValueAccess context) {
Player player = context.injectedValue(Key.of(Actor.class)) Player player = context.injectedValue(Key.of(Player.class, OptionalArg.class))
.filter(Player.class::isInstance).map(Player.class::cast).orElse(null); .orElse(null);
try { try {
return SuccessfulConversion.fromSingle(convertDirection(argument, player, includeDiagonals)); return SuccessfulConversion.fromSingle(convertDirection(argument, player, includeDiagonals));
} catch (Exception e) { } catch (Exception e) {

View File

@ -29,7 +29,7 @@ import javax.annotation.Nullable;
public final class DirectionVectorConverter extends AbstractDirectionConverter<BlockVector3> { public final class DirectionVectorConverter extends AbstractDirectionConverter<BlockVector3> {
private DirectionVectorConverter(WorldEdit worldEdit, boolean includeDiagonals) { public DirectionVectorConverter(WorldEdit worldEdit, boolean includeDiagonals) {
super(worldEdit, includeDiagonals); super(worldEdit, includeDiagonals);
} }

View File

@ -0,0 +1,76 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.argument;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.internal.annotation.Offset;
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.ConversionResult;
import org.enginehub.piston.inject.InjectedValueAccess;
import org.enginehub.piston.inject.Key;
import java.util.List;
public class OffsetConverter implements ArgumentConverter<BlockVector3> {
public static void register(WorldEdit worldEdit, CommandManager commandManager) {
commandManager.registerConverter(
Key.of(BlockVector3.class, Offset.class),
new OffsetConverter(worldEdit)
);
}
private final DirectionVectorConverter directionVectorConverter;
private final VectorConverter<Integer, BlockVector3> vectorConverter =
VectorConverter.BLOCK_VECTOR_3_CONVERTER;
private OffsetConverter(WorldEdit worldEdit) {
directionVectorConverter = new DirectionVectorConverter(worldEdit, true);
}
@Override
public Component describeAcceptableArguments() {
return TextComponent.builder()
.append(directionVectorConverter.describeAcceptableArguments())
.append(", or ")
.append(vectorConverter.describeAcceptableArguments())
.build();
}
@Override
public List<String> getSuggestions(String input, InjectedValueAccess context) {
return ImmutableList.copyOf(Iterables.concat(
directionVectorConverter.getSuggestions(input, context),
vectorConverter.getSuggestions(input, context)
));
}
@Override
public ConversionResult<BlockVector3> convert(String input, InjectedValueAccess context) {
return directionVectorConverter.convert(input, context)
.orElse(vectorConverter.convert(input, context));
}
}

View File

@ -40,12 +40,22 @@ import java.util.List;
import java.util.function.Function; import java.util.function.Function;
public class VectorConverter<C, T> implements ArgumentConverter<T> { public class VectorConverter<C, T> implements ArgumentConverter<T> {
private static final CommaSeparatedValuesConverter<Integer> INT_CONVERTER =
CommaSeparatedValuesConverter.wrap(ArgumentConverters.get(TypeToken.of(int.class)));
public static final VectorConverter<Integer, BlockVector3> BLOCK_VECTOR_3_CONVERTER = new VectorConverter<>(
INT_CONVERTER,
3,
cmps -> BlockVector3.at(cmps.get(0), cmps.get(1), cmps.get(2)),
"block vector with x, y, and z"
);
public static void register(CommandManager commandManager) { public static void register(CommandManager commandManager) {
CommaSeparatedValuesConverter<Integer> intConverter = CommaSeparatedValuesConverter.wrap(ArgumentConverters.get(TypeToken.of(int.class)));
CommaSeparatedValuesConverter<Double> doubleConverter = CommaSeparatedValuesConverter.wrap(ArgumentConverters.get(TypeToken.of(double.class))); CommaSeparatedValuesConverter<Double> doubleConverter = CommaSeparatedValuesConverter.wrap(ArgumentConverters.get(TypeToken.of(double.class)));
commandManager.registerConverter(Key.of(BlockVector2.class), commandManager.registerConverter(Key.of(BlockVector2.class),
new VectorConverter<>( new VectorConverter<>(
intConverter, INT_CONVERTER,
2, 2,
cmps -> BlockVector2.at(cmps.get(0), cmps.get(1)), cmps -> BlockVector2.at(cmps.get(0), cmps.get(1)),
"block vector with x and z" "block vector with x and z"
@ -57,13 +67,7 @@ public class VectorConverter<C, T> implements ArgumentConverter<T> {
cmps -> Vector2.at(cmps.get(0), cmps.get(1)), cmps -> Vector2.at(cmps.get(0), cmps.get(1)),
"vector with x and z" "vector with x and z"
)); ));
commandManager.registerConverter(Key.of(BlockVector3.class), commandManager.registerConverter(Key.of(BlockVector3.class), BLOCK_VECTOR_3_CONVERTER);
new VectorConverter<>(
intConverter,
3,
cmps -> BlockVector3.at(cmps.get(0), cmps.get(1), cmps.get(2)),
"block vector with x, y, and z"
));
commandManager.registerConverter(Key.of(Vector3.class), commandManager.registerConverter(Key.of(Vector3.class),
new VectorConverter<>( new VectorConverter<>(
doubleConverter, doubleConverter,

View File

@ -0,0 +1,85 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.tool;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import javax.annotation.Nullable;
public class StackTool implements BlockTool {
private final int range;
private final Mask mask;
public StackTool(int range, Mask mask) {
this.range = range;
this.mask = mask;
}
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
if (face == null) {
return false;
}
BlockBag bag = session.getBlockBag(player);
try (EditSession editSession = session.createEditSession(player)) {
BlockStateHolder<?> block = editSession.getFullBlock(clicked.toVector().toBlockPoint());
try {
editSession.disableBuffering();
BlockVector3 position = clicked.toVector().toBlockPoint();
for (int i = 0; i < range; i++) {
position = position.add(face.toBlockVector());
if (!mask.test(position)) {
break;
}
editSession.setBlock(position, block);
}
} catch (MaxChangedBlocksException ignored) {
} finally {
session.remember(editSession);
}
} finally {
if (bag != null) {
bag.flushChanges();
}
}
return true;
}
@Override
public boolean canUse(Actor actor) {
return actor.hasPermission("worldedit.tool.stack");
}
}

View File

@ -0,0 +1,113 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.extent;
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.collection.BlockMap;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Set;
import javax.annotation.Nullable;
/**
* An extent that can report back if an operation fails due to the extent(s) below it.
*
* <em>Internal use only.</em>
*/
public class TracingExtent extends AbstractDelegateExtent {
public enum Action {
SET_BLOCK,
SET_BIOME,
CREATE_ENTITY,
}
private final Set<BlockVector3> touchedLocations = Collections.newSetFromMap(BlockMap.create());
private final SetMultimap<BlockVector3, Action> failedActions = Multimaps.newSetMultimap(
BlockMap.create(), () -> EnumSet.noneOf(Action.class)
);
/**
* Create a new instance.
*
* @param extent the extent
*/
public TracingExtent(Extent extent) {
super(extent);
}
public boolean isActive() {
return !touchedLocations.isEmpty();
}
public Set<BlockVector3> getTouchedLocations() {
return Collections.unmodifiableSet(touchedLocations);
}
public SetMultimap<BlockVector3, Action> getFailedActions() {
return Multimaps.unmodifiableSetMultimap(failedActions);
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block) throws WorldEditException {
touchedLocations.add(location);
boolean result = super.setBlock(location, block);
if (!result) {
failedActions.put(location, Action.SET_BLOCK);
}
return result;
}
@Override
public boolean setBiome(BlockVector3 position, BiomeType biome) {
touchedLocations.add(position);
boolean result = super.setBiome(position, biome);
if (!result) {
failedActions.put(position, Action.SET_BIOME);
}
return result;
}
@Nullable
@Override
public Entity createEntity(Location location, BaseEntity entity) {
BlockVector3 blockVector3 = location.toVector().toBlockPoint();
touchedLocations.add(blockVector3);
Entity result = super.createEntity(location, entity);
if (result == null) {
failedActions.put(blockVector3, Action.CREATE_ENTITY);
}
return result;
}
@Override
public String toString() {
return "TracingExtent{delegate=" + getExtent() + "}";
}
}

View File

@ -39,7 +39,7 @@ import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.internal.Constants;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
@ -97,7 +97,7 @@ public class SpongeSchematicReader extends NBTSchematicReader {
int liveDataVersion = platform.getDataVersion(); int liveDataVersion = platform.getDataVersion();
if (schematicVersion == 1) { if (schematicVersion == 1) {
dataVersion = 1631; // this is a relatively safe assumption unless someone imports a schematic from 1.12, e.g. sponge 7.1- dataVersion = Constants.DATA_VERSION_MC_1_13_2; // this is a relatively safe assumption unless someone imports a schematic from 1.12, e.g. sponge 7.1-
fixer = platform.getDataFixer(); fixer = platform.getDataFixer();
return readVersion1(schematicTag); return readVersion1(schematicTag);
} else if (schematicVersion == 2) { } else if (schematicVersion == 2) {
@ -128,7 +128,7 @@ public class SpongeSchematicReader extends NBTSchematicReader {
CompoundTag schematicTag = getBaseTag(); CompoundTag schematicTag = getBaseTag();
Map<String, Tag> schematic = schematicTag.getValue(); Map<String, Tag> schematic = schematicTag.getValue();
if (schematicVersion == 1) { if (schematicVersion == 1) {
return OptionalInt.of(1631); return OptionalInt.of(Constants.DATA_VERSION_MC_1_13_2);
} else if (schematicVersion == 2) { } else if (schematicVersion == 2) {
return OptionalInt.of(requireTag(schematic, "DataVersion", IntTag.class).getValue()); return OptionalInt.of(requireTag(schematic, "DataVersion", IntTag.class).getValue());
} }
@ -322,7 +322,7 @@ public class SpongeSchematicReader extends NBTSchematicReader {
BiomeType biome = BiomeTypes.get(key); BiomeType biome = BiomeTypes.get(key);
if (biome == null) { if (biome == null) {
log.warn("Unknown biome type :" + key + log.warn("Unknown biome type :" + key +
" in palette. Are you missing a mod or using a schematic made in a newer version of Minecraft?"); " in palette. Are you missing a mod or using a schematic made in a newer version of Minecraft?");
} }
Tag idTag = palettePart.getValue(); Tag idTag = palettePart.getValue();
if (!(idTag instanceof IntTag)) { if (!(idTag instanceof IntTag)) {
@ -338,7 +338,7 @@ public class SpongeSchematicReader extends NBTSchematicReader {
int biomeJ = 0; int biomeJ = 0;
int bVal; int bVal;
int varIntLength; int varIntLength;
BlockVector2 min = clipboard.getMinimumPoint().toBlockVector2(); BlockVector3 min = clipboard.getMinimumPoint();
while (biomeJ < biomes.length) { while (biomeJ < biomes.length) {
bVal = 0; bVal = 0;
varIntLength = 0; varIntLength = 0;
@ -357,7 +357,9 @@ public class SpongeSchematicReader extends NBTSchematicReader {
int z = biomeIndex / width; int z = biomeIndex / width;
int x = biomeIndex % width; int x = biomeIndex % width;
BiomeType type = palette.get(bVal); BiomeType type = palette.get(bVal);
clipboard.setBiome(min.add(x, z), type); for (int y = 0; y < clipboard.getRegion().getHeight(); y++) {
clipboard.setBiome(min.add(x, y, z), type);
}
biomeIndex++; biomeIndex++;
} }
} }

View File

@ -0,0 +1,124 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.block;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.LayerFunction;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
public class SnowSimulator implements LayerFunction {
private final BlockState ice = BlockTypes.ICE.getDefaultState();
private final BlockState snow = BlockTypes.SNOW.getDefaultState();
private final BlockState snowBlock = BlockTypes.SNOW_BLOCK.getDefaultState();
private final Property<Integer> snowLayersProperty = BlockTypes.SNOW.getProperty("layers");
private final Property<Integer> waterLevelProperty = BlockTypes.WATER.getProperty("level");
private final Extent extent;
private final boolean stack;
private int affected;
public SnowSimulator(Extent extent, boolean stack) {
this.extent = extent;
this.stack = stack;
this.affected = 0;
}
public int getAffected() {
return this.affected;
}
@Override
public boolean isGround(BlockVector3 position) {
BlockState block = this.extent.getBlock(position);
// We're returning the first block we can place *on top of*
if (block.getBlockType().getMaterial().isAir() || (stack && block.getBlockType() == BlockTypes.SNOW)) {
return false;
}
// Unless it's water
if (block.getBlockType() == BlockTypes.WATER) {
return true;
}
// Can only place on full solid blocks
return block.getBlockType().getMaterial().isFullCube()
&& block.getBlockType().getMaterial().isSolid();
}
@Override
public boolean apply(BlockVector3 position, int depth) throws WorldEditException {
if (depth > 0) {
// We only care about the first layer.
return false;
}
BlockState block = this.extent.getBlock(position);
if (block.getBlockType() == BlockTypes.WATER) {
if (block.getState(waterLevelProperty) == 0) {
if (this.extent.setBlock(position, ice)) {
affected++;
}
}
return false;
}
// Can't put snow this far up
if (position.getBlockY() == this.extent.getMaximumPoint().getBlockY()) {
return false;
}
BlockVector3 abovePosition = position.add(0, 1, 0);
BlockState above = this.extent.getBlock(abovePosition);
// Can only replace air (or snow in stack mode)
if (!above.getBlockType().getMaterial().isAir() && (!stack || above.getBlockType() != BlockTypes.SNOW)) {
return false;
}
if (stack && above.getBlockType() == BlockTypes.SNOW) {
int currentHeight = above.getState(snowLayersProperty);
// We've hit the highest layer (If it doesn't contain current + 2 it means it's 1 away from full)
if (!snowLayersProperty.getValues().contains(currentHeight + 2)) {
if (this.extent.setBlock(abovePosition, snowBlock)) {
this.affected++;
}
} else {
if (this.extent.setBlock(abovePosition, above.with(snowLayersProperty, currentHeight + 1))) {
this.affected++;
}
}
return false;
}
if (this.extent.setBlock(abovePosition, snow)) {
this.affected++;
}
return false;
}
}

View File

@ -0,0 +1,65 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.factory;
import com.sk89q.worldedit.function.Contextual;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.LayerFunction;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.visitor.LayerVisitor;
import com.sk89q.worldedit.regions.FlatRegion;
import com.sk89q.worldedit.regions.NullRegion;
import com.sk89q.worldedit.regions.Regions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.util.GuavaUtil.firstNonNull;
public class ApplyLayer implements Contextual<Operation> {
private final FlatRegion region;
private final Contextual<? extends LayerFunction> function;
public ApplyLayer(Contextual<? extends LayerFunction> function) {
this(Regions.asFlatRegion(new NullRegion()), function);
}
public ApplyLayer(FlatRegion region, Contextual<? extends LayerFunction> function) {
checkNotNull(region, "region");
checkNotNull(function, "function");
this.region = region;
this.function = function;
}
@Override
public Operation createFromContext(EditContext context) {
FlatRegion localRegion = Regions.asFlatRegion(firstNonNull(context.getRegion(), region));
return new LayerVisitor(localRegion,
localRegion.getMinimumPoint().getY(),
localRegion.getMaximumPoint().getY(),
function.createFromContext(context));
}
@Override
public String toString() {
return "set " + function;
}
}

View File

@ -0,0 +1,59 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.factory;
import com.sk89q.worldedit.function.Contextual;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.regions.NullRegion;
import com.sk89q.worldedit.regions.Region;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.util.GuavaUtil.firstNonNull;
public class ApplyRegion implements Contextual<Operation> {
private final Region region;
private final Contextual<? extends RegionFunction> function;
public ApplyRegion(Contextual<? extends RegionFunction> function) {
this(new NullRegion(), function);
}
public ApplyRegion(Region region, Contextual<? extends RegionFunction> function) {
checkNotNull(region, "region");
checkNotNull(function, "function");
this.region = region;
this.function = function;
}
@Override
public Operation createFromContext(EditContext context) {
return new RegionVisitor(firstNonNull(context.getRegion(), region), function.createFromContext(context));
}
@Override
public String toString() {
return "set " + function;
}
}

View File

@ -0,0 +1,44 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.factory;
import com.sk89q.worldedit.function.Contextual;
import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.LayerFunction;
import com.sk89q.worldedit.function.block.SnowSimulator;
public class Snow implements Contextual<LayerFunction> {
private final boolean stack;
public Snow(boolean stack) {
this.stack = stack;
}
@Override
public LayerFunction createFromContext(EditContext context) {
return new SnowSimulator(context.getDestination(), this.stack);
}
@Override
public String toString() {
return "snow" + (this.stack ? " stacker" : "");
}
}

View File

@ -0,0 +1,96 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.history.change;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.history.UndoContext;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.biome.BiomeType;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Represents a biome change that may be undone or replayed.
*
* <p>This biome change does not have an {@link Extent} assigned to it because
* one will be taken from the passed {@link UndoContext}. If the context
* does not have an extent (it is null), cryptic errors may occur.</p>
*/
public class BiomeChange3D implements Change {
private final BlockVector3 position;
private final BiomeType previous;
private final BiomeType current;
/**
* Create a new biome change.
*
* @param position the position
* @param previous the previous biome
* @param current the current biome
*/
public BiomeChange3D(BlockVector3 position, BiomeType previous, BiomeType current) {
checkNotNull(position);
checkNotNull(previous);
checkNotNull(current);
this.position = position;
this.previous = previous;
this.current = current;
}
/**
* Get the position.
*
* @return the position
*/
public BlockVector3 getPosition() {
return position;
}
/**
* Get the previous biome.
*
* @return the previous biome
*/
public BiomeType getPrevious() {
return previous;
}
/**
* Get the current biome.
*
* @return the current biome
*/
public BiomeType getCurrent() {
return current;
}
@Override
public void undo(UndoContext context) throws WorldEditException {
checkNotNull(context.getExtent()).setBiome(position, previous);
}
@Override
public void redo(UndoContext context) throws WorldEditException {
checkNotNull(context.getExtent()).setBiome(position, current);
}
}

View File

@ -0,0 +1,38 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.internal.annotation;
import com.sk89q.worldedit.math.BlockVector3;
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;
/**
* Annotates a {@link BlockVector3} parameter to inject an offset.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@InjectAnnotation
public @interface Offset {
String FORWARD = "forward";
}

View File

@ -0,0 +1,38 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.internal.annotation;
import com.sk89q.worldedit.entity.Player;
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;
/**
* Annotates a parameter to indicate it as optional. This is really a bit of a hack, used to
* get a {@link Player} or {@code null} instead of throwing.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@InjectAnnotation
public @interface OptionalArg {
}

View File

@ -0,0 +1,102 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.world;
import com.google.auto.value.AutoValue;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.regions.Region;
import java.util.OptionalLong;
import javax.annotation.Nullable;
/**
* Regeneration options for {@link World#regenerate(Region, EditSession, RegenOptions)}.
*/
@AutoValue
public abstract class RegenOptions {
/**
* Creates a new options builder.
*
* @return the builder
*/
public static Builder builder() {
return new AutoValue_RegenOptions.Builder().seed(OptionalLong.empty()).regenBiomes(false);
}
@AutoValue.Builder
public abstract static class Builder {
/**
* Sets the seed to regenerate with. Defaults to {@code null}.
*
* <p>
* Use {@code null} to use the world's current seed.
* </p>
*
* @param seed the seed to regenerate with
* @return this builder
*/
public final Builder seed(@Nullable Long seed) {
return seed(seed == null ? OptionalLong.empty() : OptionalLong.of(seed));
}
// AV doesn't like us using @Nullable Long for some reason
abstract Builder seed(OptionalLong seed);
/**
* Turn on or off applying the biomes from the regenerated chunk. Defaults to {@code false}.
*
* @param regenBiomes {@code true} to apply biomes
* @return this builder
*/
public abstract Builder regenBiomes(boolean regenBiomes);
/**
* Build the options object.
*
* @return the options object
*/
public abstract RegenOptions build();
}
RegenOptions() {
}
/**
* The seed to regenerate with.
*
* <p>
* {@link OptionalLong#empty()} if the world's original seed should be used.
* </p>
*/
public abstract OptionalLong getSeed();
abstract boolean isRegenBiomes();
/**
* Whether biomes should be regenerated.
*/
public final boolean shouldRegenBiomes() {
return isRegenBiomes();
}
}

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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.world;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
/**
* Thrown if the world has been unloaded.
*/
public class WorldUnloadedException extends WorldEditException {
/**
* Create a new instance.
*/
public WorldUnloadedException() {
super(TranslatableComponent.of("worldedit.error.world-unloaded"));
}
}

View File

@ -41,7 +41,7 @@ import java.util.Map;
import javax.annotation.Nullable; import javax.annotation.Nullable;
/** /**
* The chunk format for Minecraft 1.13 and newer * The chunk format for Minecraft 1.13 to 1.15
*/ */
public class AnvilChunk13 implements Chunk { public class AnvilChunk13 implements Chunk {
@ -112,44 +112,48 @@ public class AnvilChunk13 implements Chunk {
} }
palette[paletteEntryId] = blockState; palette[paletteEntryId] = blockState;
} }
int paletteBits = 4;
while ((1 << paletteBits) < paletteSize) {
++paletteBits;
}
int paletteMask = (1 << paletteBits) - 1;
// parse block states // parse block states
long[] blockStatesSerialized = NBTUtils.getChildTag(sectionTag.getValue(), "BlockStates", LongArrayTag.class).getValue(); long[] blockStatesSerialized = NBTUtils.getChildTag(sectionTag.getValue(), "BlockStates", LongArrayTag.class).getValue();
int blocksPerChunkSection = 16 * 16 * 16; BlockState[] chunkSectionBlocks = new BlockState[16 * 16 * 16];
BlockState[] chunkSectionBlocks = new BlockState[blocksPerChunkSection];
blocks[y] = chunkSectionBlocks; blocks[y] = chunkSectionBlocks;
long currentSerializedValue = 0; readBlockStates(palette, blockStatesSerialized, chunkSectionBlocks);
int nextSerializedItem = 0; }
int remainingBits = 0; }
for (int blockPos = 0; blockPos < blocksPerChunkSection; blockPos++) {
int localBlockId; protected void readBlockStates(BlockState[] palette, long[] blockStatesSerialized, BlockState[] chunkSectionBlocks) throws InvalidFormatException {
if (remainingBits < paletteBits) { int paletteBits = 4;
int bitsNextLong = paletteBits - remainingBits; while ((1 << paletteBits) < palette.length) {
localBlockId = (int) currentSerializedValue; ++paletteBits;
if (nextSerializedItem >= blockStatesSerialized.length) { }
throw new InvalidFormatException("Too short block state table"); int paletteMask = (1 << paletteBits) - 1;
}
currentSerializedValue = blockStatesSerialized[nextSerializedItem++]; long currentSerializedValue = 0;
localBlockId |= (currentSerializedValue & ((1 << bitsNextLong) - 1)) << remainingBits; int nextSerializedItem = 0;
currentSerializedValue >>>= bitsNextLong; int remainingBits = 0;
remainingBits = 64 - bitsNextLong; for (int blockPos = 0; blockPos < chunkSectionBlocks.length; blockPos++) {
} else { int localBlockId;
localBlockId = (int) (currentSerializedValue & paletteMask); if (remainingBits < paletteBits) {
currentSerializedValue >>>= paletteBits; int bitsNextLong = paletteBits - remainingBits;
remainingBits -= paletteBits; localBlockId = (int) currentSerializedValue;
if (nextSerializedItem >= blockStatesSerialized.length) {
throw new InvalidFormatException("Too short block state table");
} }
if (localBlockId >= palette.length) { currentSerializedValue = blockStatesSerialized[nextSerializedItem++];
throw new InvalidFormatException("Invalid block state table entry: " + localBlockId); localBlockId |= (currentSerializedValue & ((1 << bitsNextLong) - 1)) << remainingBits;
} currentSerializedValue >>>= bitsNextLong;
chunkSectionBlocks[blockPos] = palette[localBlockId]; remainingBits = 64 - bitsNextLong;
} else {
localBlockId = (int) (currentSerializedValue & paletteMask);
currentSerializedValue >>>= paletteBits;
remainingBits -= paletteBits;
} }
if (localBlockId >= palette.length) {
throw new InvalidFormatException("Invalid block state table entry: " + localBlockId);
}
chunkSectionBlocks[blockPos] = palette[localBlockId];
} }
} }

View File

@ -0,0 +1,53 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.world.chunk;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.world.DataException;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.storage.InvalidFormatException;
/**
* The chunk format for Minecraft 1.16 and newer
*/
public class AnvilChunk16 extends AnvilChunk13 {
/**
* Construct the chunk with a compound tag.
*
* @param tag the tag to read
* @throws DataException on a data error
*/
public AnvilChunk16(CompoundTag tag) throws DataException {
super(tag);
}
@Override
protected void readBlockStates(BlockState[] palette, long[] blockStatesSerialized, BlockState[] chunkSectionBlocks) throws InvalidFormatException {
PackedIntArrayReader reader = new PackedIntArrayReader(blockStatesSerialized);
for (int blockPos = 0; blockPos < chunkSectionBlocks.length; blockPos++) {
int index = reader.get(blockPos);
if (index >= palette.length) {
throw new InvalidFormatException("Invalid block state table entry: " + index);
}
chunkSectionBlocks[blockPos] = palette[index];
}
}
}

View File

@ -0,0 +1,66 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.world.chunk;
import static com.google.common.base.Preconditions.checkElementIndex;
public class PackedIntArrayReader {
private static final int[] FACTORS = new int[64];
static {
FACTORS[0] = -1;
for (int i = 2; i <= 64; i++) {
FACTORS[i - 1] = (int) (Integer.toUnsignedLong(-1) / i);
}
}
private static final int SIZE = 4096;
private final long[] data;
private final int elementBits;
private final long maxValue;
private final int elementsPerLong;
private final int factor;
public PackedIntArrayReader(long[] data) {
this.data = data;
this.elementBits = data.length * 64 / 4096;
this.maxValue = (1L << elementBits) - 1L;
this.elementsPerLong = 64 / elementBits;
this.factor = FACTORS[elementsPerLong - 1];
int j = (SIZE + this.elementsPerLong - 1) / this.elementsPerLong;
if (j != data.length) {
throw new IllegalStateException("Invalid packed-int array provided, should be of length " + j);
}
}
public int get(int index) {
checkElementIndex(index, SIZE);
int i = this.adjustIndex(index);
long l = this.data[i];
int j = (index - i * this.elementsPerLong) * this.elementBits;
return (int) (l >> j & this.maxValue);
}
private int adjustIndex(int i) {
return (int) ((long) i * factor + factor >> 32);
}
}

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.world.item; package com.sk89q.worldedit.world.item;

View File

@ -25,10 +25,12 @@ import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.internal.Constants;
import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.DataException;
import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.DataFixer;
import com.sk89q.worldedit.world.chunk.AnvilChunk; import com.sk89q.worldedit.world.chunk.AnvilChunk;
import com.sk89q.worldedit.world.chunk.AnvilChunk13; import com.sk89q.worldedit.world.chunk.AnvilChunk13;
import com.sk89q.worldedit.world.chunk.AnvilChunk16;
import com.sk89q.worldedit.world.chunk.Chunk; import com.sk89q.worldedit.world.chunk.Chunk;
import com.sk89q.worldedit.world.chunk.OldChunk; import com.sk89q.worldedit.world.chunk.OldChunk;
@ -58,11 +60,6 @@ public class ChunkStoreHelper {
} }
} }
/**
* The DataVersion for Minecraft 1.13
*/
private static final int DATA_VERSION_MC_1_13 = 1519;
/** /**
* Convert a chunk NBT tag into a {@link Chunk} implementation. * Convert a chunk NBT tag into a {@link Chunk} implementation.
* *
@ -94,13 +91,17 @@ public class ChunkStoreHelper {
if (dataVersion == 0) dataVersion = -1; if (dataVersion == 0) dataVersion = -1;
final Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING); final Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING);
final int currentDataVersion = platform.getDataVersion(); final int currentDataVersion = platform.getDataVersion();
if (tag.getValue().containsKey("Sections") && dataVersion < currentDataVersion) { // only fix up MCA format, DFU doesn't support MCR chunks if (tag.getValue().containsKey("Sections") && dataVersion < currentDataVersion) { // only fix up MCA format, DFU doesn't support MCR chunks
final DataFixer dataFixer = platform.getDataFixer(); final DataFixer dataFixer = platform.getDataFixer();
if (dataFixer != null) { if (dataFixer != null) {
return new AnvilChunk13((CompoundTag) dataFixer.fixUp(DataFixer.FixTypes.CHUNK, rootTag, dataVersion).getValue().get("Level")); tag = (CompoundTag) dataFixer.fixUp(DataFixer.FixTypes.CHUNK, rootTag, dataVersion).getValue().get("Level");
dataVersion = currentDataVersion;
} }
} }
if (dataVersion >= DATA_VERSION_MC_1_13) { if (dataVersion >= Constants.DATA_VERSION_MC_1_16) {
return new AnvilChunk16(tag);
}
if (dataVersion >= Constants.DATA_VERSION_MC_1_13) {
return new AnvilChunk13(tag); return new AnvilChunk13(tag);
} }

View File

@ -0,0 +1,88 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.internal.util;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class DeprecationUtilTest {
public interface ModifiedApi {
@Deprecated
default boolean oldApi() {
return newApi();
}
@NonAbstractForCompatibility(
delegateName = "oldApi",
delegateParams = {}
)
default boolean newApi() {
DeprecationUtil.checkDelegatingOverride(getClass());
return oldApi();
}
}
public static class OldImpl implements ModifiedApi {
@SuppressWarnings("deprecation")
@Override
public boolean oldApi() {
return false;
}
}
public static class NewImpl implements ModifiedApi {
@Override
public boolean newApi() {
return true;
}
}
public static class NewBadImpl implements ModifiedApi {
}
@Test
void oldImpl() {
assertFalse(new OldImpl().oldApi());
assertFalse(new OldImpl().newApi());
}
@Test
void newImpl() {
assertTrue(new NewImpl().oldApi());
assertTrue(new NewImpl().newApi());
}
@Test
void newBadImpl() {
// regardless of which method is called, the message is the same
Exception ex = assertThrows(IllegalStateException.class, new NewBadImpl()::oldApi);
assertTrue(ex.getMessage().contains("must override"));
assertTrue(ex.getMessage().contains("ModifiedApi.newApi()"));
ex = assertThrows(IllegalStateException.class, new NewBadImpl()::newApi);
assertTrue(ex.getMessage().contains("must override"));
assertTrue(ex.getMessage().contains("ModifiedApi.newApi()"));
}
}

View File

@ -0,0 +1,42 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.fabric;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.source.BiomeArray;
/**
* Interface over a {@link BiomeArray} as a mutable object.
*/
public interface MutableBiomeArray {
/**
* Hook into the given biome array, to allow edits on it.
* @param biomeArray the biome array to edit
* @return the mutable interface to the biome array
*/
static MutableBiomeArray inject(BiomeArray biomeArray) {
// It's Mixin'd
return (MutableBiomeArray) biomeArray;
}
void setBiome(int x, int y, int z, Biome biome);
}

View File

@ -0,0 +1,43 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.fabric;
import net.minecraft.server.WorldGenerationProgressListener;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.chunk.ChunkStatus;
import javax.annotation.Nullable;
// For now, this does nothing, but might be useful later for regen progress communication.
class WorldEditGenListener implements WorldGenerationProgressListener {
@Override
public void start(ChunkPos spawnPos) {
}
@Override
public void setChunkStatus(ChunkPos pos, @Nullable ChunkStatus status) {
}
@Override
public void stop() {
}
}

View File

@ -0,0 +1,33 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.fabric.internal;
import net.minecraft.resource.ServerResourceManager;
import net.minecraft.world.World;
import java.nio.file.Path;
public interface ExtendedMinecraftServer {
Path getStoragePath(World world);
ServerResourceManager getServerResourceManager();
}

View File

@ -0,0 +1,26 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.fabric.internal;
public interface ExtendedPlayerEntity {
String getLanguage();
}

View File

@ -0,0 +1,32 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.fabric.mixin;
import net.minecraft.network.packet.c2s.play.ClientSettingsC2SPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ClientSettingsC2SPacket.class)
public interface AccessorClientSettingsC2SPacket {
@Accessor
String getLanguage();
}

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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.fabric.mixin;
import net.minecraft.world.SaveProperties;
import net.minecraft.world.gen.GeneratorOptions;
import net.minecraft.world.level.LevelProperties;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(LevelProperties.class)
public interface AccessorLevelProperties extends SaveProperties {
@Accessor
@Mutable
void setGeneratorOptions(GeneratorOptions options);
}

View File

@ -0,0 +1,42 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.fabric.mixin;
import com.mojang.datafixers.util.Either;
import net.minecraft.server.world.ChunkHolder;
import net.minecraft.server.world.ServerChunkManager;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkStatus;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
import java.util.concurrent.CompletableFuture;
@Mixin(ServerChunkManager.class)
public interface AccessorServerChunkManager {
@Invoker
CompletableFuture<Either<Chunk, ChunkHolder.Unloaded>> callGetChunkFuture(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create);
@Accessor
ServerChunkManager.MainThreadExecutor getMainThreadExecutor();
}

View File

@ -0,0 +1,39 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.fabric.mixin;
import com.sk89q.worldedit.fabric.MutableBiomeArray;
import com.sk89q.worldedit.internal.util.BiomeMath;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.source.BiomeArray;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(BiomeArray.class)
public abstract class MixinBiomeArray implements MutableBiomeArray {
@Shadow
private Biome[] data;
@Override
public void setBiome(int x, int y, int z, Biome biome) {
this.data[BiomeMath.computeBiomeIndex(x, y, z)] = biome;
}
}

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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.util.io.WorldEditResourceLoader;
import java.io.IOException;
import java.net.URL;
public class ForgeResourceLoader extends WorldEditResourceLoader {
public ForgeResourceLoader(WorldEdit worldEdit) {
super(worldEdit);
}
private static URL getResourceForgeHack(String location) throws IOException {
try {
return new URL("modjar://worldedit/" + location);
} catch (Exception e) {
throw new IOException("Could not find " + location);
}
}
@Override
public URL getRootResource(String pathName) throws IOException {
URL url = super.getRootResource(pathName);
if (url == null) {
return getResourceForgeHack(pathName);
}
return url;
}
}

View File

@ -0,0 +1,44 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.forge;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.chunk.ChunkStatus;
import net.minecraft.world.chunk.listener.IChunkStatusListener;
import javax.annotation.Nullable;
// For now, this does nothing, but might be useful later for regen progress communication.
class WorldEditGenListener implements IChunkStatusListener {
@Override
public void start(ChunkPos spawnPos) {
}
@Override
public void statusChanged(ChunkPos chunkPosition, @Nullable ChunkStatus newStatus) {
}
@Override
public void stop() {
}
}