mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-12 10:38:34 +00:00
Feature/propagate diff and object cleanup (#1190)
* Feature/main/propagate diff annotations (#1187) * 25% done * More work * More work * 50% * More work * 75% * 100% & cleanup * Update adapters * Squish squash, applesauce commit275ba9bd84
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Sat Jul 17 01:10:20 2021 +0200 Update dependency com.comphenix.protocol:ProtocolLib to v4.7.0 (#1173) Co-authored-by: Renovate Bot <bot@renovateapp.com> commit9fd8984804
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Sat Jul 17 01:09:29 2021 +0200 Update dependency org.checkerframework:checker-qual to v3.16.0 (#1184) Co-authored-by: Renovate Bot <bot@renovateapp.com> commit861fb45e5c
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 19:07:02 2021 +0100 Fix #1075 commit420c45a29a
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 18:48:21 2021 +0100 Entity removal should be on the main thread as we're just passing through rather than doing chunk operations - Fixes #1164 - Not working: butcher/remove history commit4d4db7dcd0
Author: SirYwell <hannesgreule@outlook.de> Date: Fri Jul 16 17:52:44 2021 +0200 Make sure leaves category is loaded for heightmaps (fixes #1176) commitc98f6e4f37
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 10:44:52 2021 +0100 Do not allow generation commands to generate outside selection commit2485f5eccc
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 10:43:15 2021 +0100 EditSession needs to override some Extent methods to ensure block changes are correctly set through the various extents Fixes #1152 commitd9418ec8ae
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 09:52:44 2021 +0100 Undo part of41073bb1a0
Fixes #1178 * Update Upstream fb1fb84 Fixed typo and grammar * We don't support custom heights yet * Casing inconsistency * Address a few comments * Address comments * Don't refactor to AP classpath * Document annotation style * Refactoring & shade cleanup * Address a few comments * More work * Resolve comments not being resolved yet * Feature/main/propagate diff annotations (#1187) (#1194) * Remove beta package, fix history packages, move classes out of object package * Resolve comments not being resolved yet * Remove beta package, fix history packages, move classes out of object package Co-authored-by: NotMyFault <mc.cache@web.de> * brushes should be under brush * More refactoring - Filters/processors should be in the same place and are related to extents - Transforms are in `extent.transform` in upstream * Move history classes under history * Update adapters Co-authored-by: dordsor21 <dordsor21@gmail.com>
This commit is contained in:
@ -19,11 +19,11 @@
|
||||
|
||||
package com.sk89q.worldedit.extent;
|
||||
|
||||
import com.fastasyncworldedit.core.beta.IBatchProcessor;
|
||||
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.object.HistoryExtent;
|
||||
import com.fastasyncworldedit.core.object.changeset.AbstractChangeSet;
|
||||
import com.fastasyncworldedit.core.object.exception.FaweException;
|
||||
import com.fastasyncworldedit.core.extent.HistoryExtent;
|
||||
import com.fastasyncworldedit.core.history.changeset.AbstractChangeSet;
|
||||
import com.fastasyncworldedit.core.internal.exception.FaweException;
|
||||
import com.fastasyncworldedit.core.util.ExtentTraverser;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
@ -53,12 +53,15 @@ import static org.apache.logging.log4j.LogManager.getLogger;
|
||||
/**
|
||||
* A base class for {@link Extent}s that merely passes extents onto another.
|
||||
*/
|
||||
//FAWE start - made none abstract
|
||||
public class AbstractDelegateExtent implements Extent {
|
||||
//FAWE end
|
||||
|
||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||
|
||||
//Not safe for public usage
|
||||
//FAWE start - made public: Not safe for public usage
|
||||
public Extent extent;
|
||||
//FAWE end
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
@ -81,7 +84,9 @@ public class AbstractDelegateExtent implements Extent {
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
//FAWE start - return coordinates
|
||||
return extent.getBlock(position.getX(), position.getY(), position.getZ());
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -91,107 +96,23 @@ public class AbstractDelegateExtent implements Extent {
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
//FAWE start - return coordinates
|
||||
return extent.getFullBlock(position.getX(), position.getY(), position.getZ());
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
/*
|
||||
Queue based methods
|
||||
TODO NOT IMPLEMENTED: IQueueExtent and such need to implement these
|
||||
*/
|
||||
*/
|
||||
//FAWE end
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||
//FAWE start - return coordinates
|
||||
return extent.getFullBlock(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiomeType(int x, int y, int z) {
|
||||
return extent.getBiomeType(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(BlockVector3 position) {
|
||||
return extent.getBiome(position);
|
||||
}
|
||||
/*
|
||||
History
|
||||
*/
|
||||
|
||||
@Override
|
||||
public int getEmmittedLight(int x, int y, int z) {
|
||||
return extent.getEmmittedLight(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkyLight(int x, int y, int z) {
|
||||
return extent.getSkyLight(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBrightness(int x, int y, int z) {
|
||||
return extent.getBrightness(x, y, z);
|
||||
}
|
||||
|
||||
public void setChangeSet(AbstractChangeSet changeSet) {
|
||||
if (extent instanceof HistoryExtent) {
|
||||
HistoryExtent history = ((HistoryExtent) extent);
|
||||
if (changeSet == null) {
|
||||
new ExtentTraverser(this).setNext(history.getExtent());
|
||||
} else {
|
||||
history.setChangeSet(changeSet);
|
||||
}
|
||||
} else if (extent instanceof AbstractDelegateExtent) {
|
||||
((AbstractDelegateExtent) extent).setChangeSet(changeSet);
|
||||
} else if (changeSet != null) {
|
||||
new ExtentTraverser<>(this).setNext(new HistoryExtent(extent, changeSet));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block)
|
||||
throws WorldEditException {
|
||||
return extent.setBlock(position.getX(), position.getY(), position.getZ(), block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(int x, @Range(from = 0, to = 255) int y,
|
||||
int z, T block) throws WorldEditException {
|
||||
return extent.setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
|
||||
return setBlock(x, y, z, getBlock(x, y, z).toBaseBlock(tile));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fullySupports3DBiomes() {
|
||||
return extent.fullySupports3DBiomes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||
return extent.setBiome(x, y, z, biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||
return extent.setBiome(position.getX(), position.getY(), position.getZ(), biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockLight(int x, int y, int z, int value) {
|
||||
extent.setSkyLight(x, y, z, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyLight(int x, int y, int z, int value) {
|
||||
extent.setSkyLight(x, y, z, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + ":" + (extent == this ? "" : extent.toString());
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -220,6 +141,28 @@ public class AbstractDelegateExtent implements Extent {
|
||||
return extent.createEntity(location, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Operation commit() {
|
||||
Operation ours = commitBefore();
|
||||
Operation other = null;
|
||||
//FAWE start - implement extent
|
||||
if (extent != this) {
|
||||
other = extent.commit();
|
||||
}
|
||||
//FAWE end
|
||||
if (ours != null && other != null) {
|
||||
return new OperationQueue(ours, other);
|
||||
} else if (ours != null) {
|
||||
return ours;
|
||||
} else if (other != null) {
|
||||
return other;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
@Override
|
||||
public void removeEntity(int x, int y, int z, UUID uuid) {
|
||||
extent.removeEntity(x, y, z, uuid);
|
||||
@ -256,25 +199,6 @@ public class AbstractDelegateExtent implements Extent {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Operation commit() {
|
||||
Operation ours = commitBefore();
|
||||
Operation other = null;
|
||||
if (extent != this) {
|
||||
other = extent.commit();
|
||||
}
|
||||
if (ours != null && other != null) {
|
||||
return new OperationQueue(ours, other);
|
||||
} else if (ours != null) {
|
||||
return ours;
|
||||
} else if (other != null) {
|
||||
return other;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxY() {
|
||||
return extent.getMaxY();
|
||||
@ -343,4 +267,95 @@ public class AbstractDelegateExtent implements Extent {
|
||||
protected Operation commitBefore() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiomeType(int x, int y, int z) {
|
||||
return extent.getBiomeType(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(BlockVector3 position) {
|
||||
return extent.getBiome(position);
|
||||
}
|
||||
/*
|
||||
History
|
||||
*/
|
||||
|
||||
@Override
|
||||
public int getEmittedLight(int x, int y, int z) {
|
||||
return extent.getEmittedLight(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkyLight(int x, int y, int z) {
|
||||
return extent.getSkyLight(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBrightness(int x, int y, int z) {
|
||||
return extent.getBrightness(x, y, z);
|
||||
}
|
||||
|
||||
public void setChangeSet(AbstractChangeSet changeSet) {
|
||||
if (extent instanceof HistoryExtent) {
|
||||
HistoryExtent history = ((HistoryExtent) extent);
|
||||
if (changeSet == null) {
|
||||
new ExtentTraverser(this).setNext(history.getExtent());
|
||||
} else {
|
||||
history.setChangeSet(changeSet);
|
||||
}
|
||||
} else if (extent instanceof AbstractDelegateExtent) {
|
||||
((AbstractDelegateExtent) extent).setChangeSet(changeSet);
|
||||
} else if (changeSet != null) {
|
||||
new ExtentTraverser<>(this).setNext(new HistoryExtent(extent, changeSet));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block)
|
||||
throws WorldEditException {
|
||||
return extent.setBlock(position.getX(), position.getY(), position.getZ(), block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(int x, @Range(from = 0, to = 255) int y,
|
||||
int z, T block) throws WorldEditException {
|
||||
return extent.setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
|
||||
return setBlock(x, y, z, getBlock(x, y, z).toBaseBlock(tile));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fullySupports3DBiomes() {
|
||||
return extent.fullySupports3DBiomes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||
return extent.setBiome(x, y, z, biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||
return extent.setBiome(position.getX(), position.getY(), position.getZ(), biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockLight(int x, int y, int z, int value) {
|
||||
extent.setSkyLight(x, y, z, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyLight(int x, int y, int z, int value) {
|
||||
extent.setSkyLight(x, y, z, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + ":" + (extent == this ? "" : extent.toString());
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -20,15 +20,15 @@
|
||||
package com.sk89q.worldedit.extent;
|
||||
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.beta.Filter;
|
||||
import com.fastasyncworldedit.core.beta.IBatchProcessor;
|
||||
import com.fastasyncworldedit.core.beta.implementation.filter.block.ExtentFilterBlock;
|
||||
import com.fastasyncworldedit.core.beta.implementation.processors.ProcessorScope;
|
||||
import com.fastasyncworldedit.core.queue.Filter;
|
||||
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
||||
import com.fastasyncworldedit.core.extent.filter.block.ExtentFilterBlock;
|
||||
import com.fastasyncworldedit.core.extent.processor.ProcessorScope;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.object.changeset.AbstractChangeSet;
|
||||
import com.fastasyncworldedit.core.object.clipboard.WorldCopyClipboard;
|
||||
import com.fastasyncworldedit.core.object.exception.FaweException;
|
||||
import com.fastasyncworldedit.core.object.extent.NullExtent;
|
||||
import com.fastasyncworldedit.core.history.changeset.AbstractChangeSet;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.WorldCopyClipboard;
|
||||
import com.fastasyncworldedit.core.internal.exception.FaweException;
|
||||
import com.fastasyncworldedit.core.extent.NullExtent;
|
||||
import com.fastasyncworldedit.core.util.ExtentTraverser;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
@ -37,11 +37,11 @@ import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.RegionMaskingFilter;
|
||||
import com.sk89q.worldedit.function.block.BlockReplace;
|
||||
import com.sk89q.worldedit.function.generator.CavesGen;
|
||||
import com.sk89q.worldedit.function.generator.GenBase;
|
||||
import com.sk89q.worldedit.function.generator.OreGen;
|
||||
import com.sk89q.worldedit.function.generator.Resource;
|
||||
import com.sk89q.worldedit.function.generator.SchemGen;
|
||||
import com.fastasyncworldedit.core.function.generator.CavesGen;
|
||||
import com.fastasyncworldedit.core.function.generator.GenBase;
|
||||
import com.fastasyncworldedit.core.function.generator.OreGen;
|
||||
import com.fastasyncworldedit.core.function.generator.Resource;
|
||||
import com.fastasyncworldedit.core.function.generator.SchemGen;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
@ -53,11 +53,11 @@ import com.sk89q.worldedit.function.visitor.RegionVisitor;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.MathUtils;
|
||||
import com.sk89q.worldedit.math.MutableBlockVector3;
|
||||
import com.fastasyncworldedit.core.math.MutableBlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.registry.state.PropertyGroup;
|
||||
import com.fastasyncworldedit.core.registry.state.PropertyGroup;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.util.Countable;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
@ -147,6 +147,7 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
return null;
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
/**
|
||||
* Create an entity at the given location.
|
||||
*
|
||||
@ -741,4 +742,5 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -19,13 +19,13 @@
|
||||
|
||||
package com.sk89q.worldedit.extent;
|
||||
|
||||
import com.fastasyncworldedit.core.beta.implementation.lighting.HeightMapType;
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.internal.util.DeprecationUtil;
|
||||
import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.MutableBlockVector3;
|
||||
import com.fastasyncworldedit.core.math.MutableBlockVector3;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
@ -53,6 +53,7 @@ public interface InputExtent {
|
||||
return getBlock(position.getX(), position.getY(), position.getZ());
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
default BlockState getBlock(int x, int y, int z) {
|
||||
return getBlock(MutableBlockVector3.get(x, y, z));
|
||||
}
|
||||
@ -70,6 +71,7 @@ public interface InputExtent {
|
||||
default BaseBlock getFullBlock(int x, int y, int z) {
|
||||
return getFullBlock(MutableBlockVector3.get(x, y, z));
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
/**
|
||||
* Get the biome at the given location.
|
||||
@ -114,17 +116,18 @@ public interface InputExtent {
|
||||
return getBiome(position.toBlockVector2());
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
/**
|
||||
* Get the light level at the given location.
|
||||
*
|
||||
* @param position location
|
||||
* @return the light level at the location
|
||||
*/
|
||||
default int getEmmittedLight(BlockVector3 position) {
|
||||
return getEmmittedLight(position.getX(), position.getY(), position.getZ());
|
||||
default int getEmittedLight(BlockVector3 position) {
|
||||
return getEmittedLight(position.getX(), position.getY(), position.getZ());
|
||||
}
|
||||
|
||||
default int getEmmittedLight(int x, int y, int z) {
|
||||
default int getEmittedLight(int x, int y, int z) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -161,4 +164,5 @@ public interface InputExtent {
|
||||
default int[] getHeightMap(HeightMapType type) {
|
||||
return new int[256];
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -20,15 +20,15 @@
|
||||
package com.sk89q.worldedit.extent;
|
||||
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.beta.Filter;
|
||||
import com.fastasyncworldedit.core.beta.IBatchProcessor;
|
||||
import com.fastasyncworldedit.core.beta.IChunk;
|
||||
import com.fastasyncworldedit.core.beta.IChunkGet;
|
||||
import com.fastasyncworldedit.core.beta.IChunkSet;
|
||||
import com.fastasyncworldedit.core.beta.implementation.filter.block.CharFilterBlock;
|
||||
import com.fastasyncworldedit.core.beta.implementation.filter.block.ChunkFilterBlock;
|
||||
import com.fastasyncworldedit.core.beta.implementation.filter.block.FilterBlock;
|
||||
import com.fastasyncworldedit.core.beta.implementation.processors.ProcessorScope;
|
||||
import com.fastasyncworldedit.core.queue.Filter;
|
||||
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
||||
import com.fastasyncworldedit.core.queue.IChunk;
|
||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||
import com.fastasyncworldedit.core.extent.filter.block.CharFilterBlock;
|
||||
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
|
||||
import com.fastasyncworldedit.core.extent.filter.block.FilterBlock;
|
||||
import com.fastasyncworldedit.core.extent.processor.ProcessorScope;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
@ -47,7 +47,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
public class MaskingExtent extends AbstractDelegateExtent implements IBatchProcessor, Filter {
|
||||
|
||||
private Mask mask;
|
||||
//FAWE start
|
||||
private final LoadingCache<Long, ChunkFilterBlock> threadIdToFilter;
|
||||
//FAWE end
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
@ -59,15 +61,19 @@ public class MaskingExtent extends AbstractDelegateExtent implements IBatchProce
|
||||
super(extent);
|
||||
checkNotNull(mask);
|
||||
this.mask = mask;
|
||||
//FAWE start
|
||||
this.threadIdToFilter = FaweCache.IMP.createCache(() -> new CharFilterBlock(getExtent()));
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
private MaskingExtent(Extent extent, Mask mask, LoadingCache<Long, ChunkFilterBlock> threadIdToFilter) {
|
||||
super(extent);
|
||||
checkNotNull(mask);
|
||||
this.mask = mask;
|
||||
this.threadIdToFilter = threadIdToFilter;
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
/**
|
||||
* Get the mask.
|
||||
@ -88,6 +94,7 @@ public class MaskingExtent extends AbstractDelegateExtent implements IBatchProce
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
|
||||
return this.mask.test(location) && super.setBlock(location, block);
|
||||
@ -134,4 +141,5 @@ public class MaskingExtent extends AbstractDelegateExtent implements IBatchProce
|
||||
public ProcessorScope getScope() {
|
||||
return ProcessorScope.REMOVING_BLOCKS;
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -91,12 +91,6 @@ public class NullExtent implements Extent {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block)
|
||||
throws WorldEditException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fullySupports3DBiomes() {
|
||||
return false;
|
||||
@ -112,11 +106,19 @@ public class NullExtent implements Extent {
|
||||
return false;
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
@Override
|
||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block)
|
||||
throws WorldEditException {
|
||||
return false;
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Operation commit() {
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.extent;
|
||||
|
||||
import com.fastasyncworldedit.core.beta.implementation.lighting.HeightMapType;
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
@ -27,7 +27,7 @@ import com.sk89q.worldedit.internal.util.DeprecationUtil;
|
||||
import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.MutableBlockVector3;
|
||||
import com.fastasyncworldedit.core.math.MutableBlockVector3;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
@ -112,6 +112,7 @@ public interface OutputExtent {
|
||||
return setBiome(MutableBlockVector3.get(x, y, z), biome);
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
/**
|
||||
* Set the biome.
|
||||
*
|
||||
@ -159,6 +160,7 @@ public interface OutputExtent {
|
||||
default void setSkyLight(BlockVector3 position, int value) {
|
||||
setSkyLight(position.getX(), position.getY(), position.getZ(), value);
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
default void setSkyLight(int x, int y, int z, int value) {
|
||||
}
|
||||
|
@ -1,244 +0,0 @@
|
||||
package com.sk89q.worldedit.extent;
|
||||
|
||||
import com.fastasyncworldedit.core.beta.Filter;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.generator.GenBase;
|
||||
import com.sk89q.worldedit.function.generator.Resource;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.util.Countable;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class PassthroughExtent extends AbstractDelegateExtent {
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param extent the extent
|
||||
*/
|
||||
public PassthroughExtent(Extent extent) {
|
||||
super(extent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean regenerateChunk(int x, int z, @Nullable BiomeType type, @Nullable Long seed) {
|
||||
return getExtent().regenerateChunk(x, z, type, seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighestTerrainBlock(int x, int z, int minY, int maxY) {
|
||||
return getExtent().getHighestTerrainBlock(x, z, minY, maxY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighestTerrainBlock(int x, int z, int minY, int maxY, Mask filter) {
|
||||
return getExtent().getHighestTerrainBlock(x, z, minY, maxY, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) {
|
||||
return getExtent().getNearestSurfaceLayer(x, z, y, minY, maxY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, boolean ignoreAir) {
|
||||
return getExtent().getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, ignoreAir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) {
|
||||
return getExtent().getNearestSurfaceTerrainBlock(x, z, y, minY, maxY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax) {
|
||||
return getExtent().getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, Mask mask) {
|
||||
return getExtent().getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, mask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, boolean ignoreAir) {
|
||||
return getExtent().getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, ignoreAir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCaves(Region region) throws WorldEditException {
|
||||
getExtent().addCaves(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(Region region, GenBase gen) throws WorldEditException {
|
||||
getExtent().generate(region, gen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSchems(Region region, Mask mask, List<ClipboardHolder> clipboards, int rarity, boolean rotate) throws WorldEditException {
|
||||
getExtent().addSchems(region, mask, clipboards, rarity, rotate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnResource(Region region, Resource gen, int rarity, int frequency) throws WorldEditException {
|
||||
getExtent().spawnResource(region, gen, rarity, frequency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(BlockVector3 pt) {
|
||||
return getExtent().contains(pt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOre(Region region, Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException {
|
||||
getExtent().addOre(region, mask, material, size, frequency, rarity, minY, maxY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOres(Region region, Mask mask) throws WorldEditException {
|
||||
getExtent().addOres(region, mask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Countable<BlockType>> getBlockDistribution(Region region) {
|
||||
return getExtent().getBlockDistribution(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Countable<BlockState>> getBlockDistributionWithData(Region region) {
|
||||
return getExtent().getBlockDistributionWithData(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clipboard lazyCopy(Region region) {
|
||||
return getExtent().lazyCopy(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countBlocks(Region region, Set<BaseBlock> searchBlocks) {
|
||||
return getExtent().countBlocks(region, searchBlocks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countBlocks(Region region, Mask searchMask) {
|
||||
return getExtent().countBlocks(region, searchMask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> int setBlocks(Region region, B block) throws MaxChangedBlocksException {
|
||||
return getExtent().setBlocks(region, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
|
||||
return getExtent().setBlocks(region, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> int replaceBlocks(Region region, Set<BaseBlock> filter, B replacement) throws MaxChangedBlocksException {
|
||||
return getExtent().replaceBlocks(region, filter, replacement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int replaceBlocks(Region region, Set<BaseBlock> filter, Pattern pattern) throws MaxChangedBlocksException {
|
||||
return getExtent().replaceBlocks(region, filter, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException {
|
||||
return getExtent().replaceBlocks(region, mask, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int center(Region region, Pattern pattern) throws MaxChangedBlocksException {
|
||||
return getExtent().center(region, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setBlocks(Set<BlockVector3> vset, Pattern pattern) {
|
||||
return getExtent().setBlocks(vset, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
return getExtent().getBlock(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return getExtent().getFullBlock(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block) throws WorldEditException {
|
||||
return getExtent().setBlock(position, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
|
||||
return getExtent().setTile(x, y, z, tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||
return getExtent().setBiome(position, biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Operation commit() {
|
||||
return getExtent().commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel() {
|
||||
return getExtent().cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isQueueEnabled() {
|
||||
return getExtent().isQueueEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableQueue() {
|
||||
getExtent().enableQueue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableQueue() {
|
||||
getExtent().disableQueue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWorld() {
|
||||
return getExtent().isWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Filter> T apply(Region region, T filter, boolean full) {
|
||||
return getExtent().apply(region, filter, full);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Filter> T apply(Iterable<BlockVector3> positions, T filter) {
|
||||
return getExtent().apply(positions, filter);
|
||||
}
|
||||
}
|
@ -68,10 +68,12 @@ public class ForgetfulExtentBuffer extends AbstractDelegateExtent implements Pat
|
||||
this(delegate, Masks.alwaysTrue());
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
@Override
|
||||
public boolean isQueueEnabled() {
|
||||
return true;
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
/**
|
||||
* Create a new extent buffer that will buffer changes that meet the criteria
|
||||
@ -102,16 +104,19 @@ public class ForgetfulExtentBuffer extends AbstractDelegateExtent implements Pat
|
||||
max = max.getMaximum(location);
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
if (mask.test(location)) {
|
||||
buffer.put(location, block.toBaseBlock());
|
||||
return true;
|
||||
} else {
|
||||
return getExtent().setBlock(location, block);
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||
//FAWE start
|
||||
// Update minimum
|
||||
if (min == null) {
|
||||
min = position;
|
||||
@ -132,10 +137,12 @@ public class ForgetfulExtentBuffer extends AbstractDelegateExtent implements Pat
|
||||
} else {
|
||||
return getExtent().setBiome(position, biome);
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||
//FAWE start
|
||||
// Update minimum
|
||||
if (min == null) {
|
||||
min = BlockVector3.at(x, y, z);
|
||||
@ -156,6 +163,7 @@ public class ForgetfulExtentBuffer extends AbstractDelegateExtent implements Pat
|
||||
} else {
|
||||
return getExtent().setBiome(x, y, z, biome);
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,11 +25,11 @@ import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.visitor.Order;
|
||||
import com.fastasyncworldedit.core.function.visitor.Order;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.MutableBlockVector2;
|
||||
import com.sk89q.worldedit.math.OffsetBlockVector3;
|
||||
import com.fastasyncworldedit.core.math.MutableBlockVector2;
|
||||
import com.fastasyncworldedit.core.math.OffsetBlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
@ -53,6 +53,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
*/
|
||||
public class BlockArrayClipboard implements Clipboard {
|
||||
|
||||
//FAWE start
|
||||
private final Region region;
|
||||
private final BlockVector3 origin;
|
||||
private final Clipboard parent;
|
||||
@ -87,6 +88,7 @@ public class BlockArrayClipboard implements Clipboard {
|
||||
this.region = region.clone();
|
||||
this.origin = region.getMinimumPoint();
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
@Override
|
||||
public Region getRegion() {
|
||||
@ -139,14 +141,17 @@ public class BlockArrayClipboard implements Clipboard {
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block) throws WorldEditException {
|
||||
if (region.contains(position)) {
|
||||
//FAWE - get points
|
||||
final int x = position.getBlockX();
|
||||
final int y = position.getBlockY();
|
||||
final int z = position.getBlockZ();
|
||||
return setBlock(x, y, z, block);
|
||||
//FAWE end
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
||||
x -= origin.getX();
|
||||
@ -155,6 +160,7 @@ public class BlockArrayClipboard implements Clipboard {
|
||||
return getParent().setTile(x, y, z, tag);
|
||||
}
|
||||
|
||||
|
||||
public boolean setTile(BlockVector3 position, CompoundTag tag) {
|
||||
return setTile(position.getX(), position.getY(), position.getZ(), tag);
|
||||
}
|
||||
@ -293,6 +299,7 @@ public class BlockArrayClipboard implements Clipboard {
|
||||
OffsetBlockVector3 mutable = new OffsetBlockVector3(origin);
|
||||
return Iterators.transform(getParent().iterator(order), mutable::init);
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
@Override
|
||||
public BlockVector3 getDimensions() {
|
||||
@ -313,6 +320,7 @@ public class BlockArrayClipboard implements Clipboard {
|
||||
this.parent.close();
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
/**
|
||||
* Stores entity data.
|
||||
*/
|
||||
@ -384,4 +392,5 @@ public class BlockArrayClipboard implements Clipboard {
|
||||
return result != null;
|
||||
}
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -19,12 +19,12 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard;
|
||||
|
||||
import com.fastasyncworldedit.core.beta.Filter;
|
||||
import com.fastasyncworldedit.core.queue.Filter;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.object.clipboard.CPUOptimizedClipboard;
|
||||
import com.fastasyncworldedit.core.object.clipboard.DiskOptimizedClipboard;
|
||||
import com.fastasyncworldedit.core.object.clipboard.MemoryOptimizedClipboard;
|
||||
import com.fastasyncworldedit.core.object.clipboard.ReadOnlyClipboard;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.CPUOptimizedClipboard;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.DiskOptimizedClipboard;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.MemoryOptimizedClipboard;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.ReadOnlyClipboard;
|
||||
import com.fastasyncworldedit.core.util.EditSessionBuilder;
|
||||
import com.fastasyncworldedit.core.util.MaskTraverser;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
@ -38,7 +38,7 @@ import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.function.visitor.Order;
|
||||
import com.fastasyncworldedit.core.function.visitor.Order;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
@ -66,6 +66,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
*/
|
||||
public interface Clipboard extends Extent, Iterable<BlockVector3>, Closeable {
|
||||
|
||||
//FAWE start
|
||||
static Clipboard create(Region region) {
|
||||
checkNotNull(region);
|
||||
checkNotNull(region.getWorld(),
|
||||
@ -84,6 +85,7 @@ public interface Clipboard extends Extent, Iterable<BlockVector3>, Closeable {
|
||||
return new MemoryOptimizedClipboard(region);
|
||||
}
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
/**
|
||||
* Get the bounding region of this extent.
|
||||
@ -127,6 +129,7 @@ public interface Clipboard extends Extent, Iterable<BlockVector3>, Closeable {
|
||||
return false;
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
/**
|
||||
* Remove entity from clipboard.
|
||||
*/
|
||||
@ -358,4 +361,5 @@ public interface Clipboard extends Extent, Iterable<BlockVector3>, Closeable {
|
||||
}
|
||||
}
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -19,16 +19,18 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
import com.fastasyncworldedit.core.object.io.PGZIPOutputStream;
|
||||
import com.fastasyncworldedit.core.object.io.ResettableFileInputStream;
|
||||
import com.fastasyncworldedit.core.object.schematic.MinecraftStructure;
|
||||
import com.fastasyncworldedit.core.object.schematic.PNGWriter;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicReader;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicWriter;
|
||||
import com.fastasyncworldedit.core.internal.io.ResettableFileInputStream;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.io.schematic.MinecraftStructure;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.io.schematic.PNGWriter;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.jnbt.NamedTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import org.anarres.parallelgzip.ParallelGZIPOutputStream;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
@ -48,6 +50,7 @@ import java.util.zip.GZIPOutputStream;
|
||||
*/
|
||||
public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
|
||||
//FAWE start - register fast clipboard io
|
||||
FAST("fast", "fawe") {
|
||||
|
||||
@Override
|
||||
@ -68,11 +71,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
OutputStream gzip;
|
||||
if (outputStream instanceof PGZIPOutputStream || outputStream instanceof GZIPOutputStream) {
|
||||
if (outputStream instanceof ParallelGZIPOutputStream || outputStream instanceof GZIPOutputStream) {
|
||||
gzip = outputStream;
|
||||
} else {
|
||||
outputStream = new BufferedOutputStream(outputStream);
|
||||
gzip = new PGZIPOutputStream(outputStream);
|
||||
gzip = new ParallelGZIPOutputStream(outputStream);
|
||||
}
|
||||
NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip));
|
||||
return new FastSchematicWriter(nbtStream);
|
||||
@ -85,6 +88,7 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
}
|
||||
|
||||
},
|
||||
//FAWE end
|
||||
|
||||
/**
|
||||
* The Schematic format used by MCEdit.
|
||||
@ -104,7 +108,10 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
throw new IOException("The formats `.schematic`, `.mcedit` and `.mce` are discontinued on versions newer than 1.12 and superseded by the sponge schematic implementation known for `.schem` files.");
|
||||
//FAWE start - be a more helpful exception
|
||||
throw new IOException("The formats `.schematic`, `.mcedit` and `.mce` are discontinued on versions newer than" +
|
||||
"1.12 and superseded by the sponge schematic implementation known for `.schem` files.");
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -154,6 +161,7 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
}
|
||||
},
|
||||
|
||||
//FAWE start - recover schematics with bad entity data & register other clipboard formats
|
||||
BROKENENTITY("brokenentity", "legacyentity", "le", "be", "brokenentities", "legacyentities") {
|
||||
|
||||
@Override
|
||||
@ -176,11 +184,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
OutputStream gzip;
|
||||
if (outputStream instanceof PGZIPOutputStream || outputStream instanceof GZIPOutputStream) {
|
||||
if (outputStream instanceof ParallelGZIPOutputStream || outputStream instanceof GZIPOutputStream) {
|
||||
gzip = outputStream;
|
||||
} else {
|
||||
outputStream = new BufferedOutputStream(outputStream);
|
||||
gzip = new PGZIPOutputStream(outputStream);
|
||||
gzip = new ParallelGZIPOutputStream(outputStream);
|
||||
}
|
||||
NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip));
|
||||
FastSchematicWriter writer = new FastSchematicWriter(nbtStream);
|
||||
@ -215,7 +223,7 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
outputStream = new BufferedOutputStream(outputStream);
|
||||
OutputStream gzip = new PGZIPOutputStream(outputStream);
|
||||
OutputStream gzip = new ParallelGZIPOutputStream(outputStream);
|
||||
NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip));
|
||||
return new MinecraftStructure(nbtStream);
|
||||
}
|
||||
@ -252,6 +260,7 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
return "png";
|
||||
}
|
||||
};
|
||||
//FAWE end
|
||||
|
||||
private final ImmutableSet<String> aliases;
|
||||
|
||||
|
@ -19,14 +19,14 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
import com.fastasyncworldedit.core.object.RunnableVal;
|
||||
import com.fastasyncworldedit.core.object.clipboard.URIClipboardHolder;
|
||||
import com.fastasyncworldedit.core.object.io.PGZIPOutputStream;
|
||||
import com.fastasyncworldedit.core.util.task.RunnableVal;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.URIClipboardHolder;
|
||||
import com.fastasyncworldedit.core.util.MainUtil;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import org.anarres.parallelgzip.ParallelGZIPOutputStream;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@ -99,6 +99,7 @@ public interface ClipboardFormat {
|
||||
*/
|
||||
Set<String> getFileExtensions();
|
||||
|
||||
//FAWE start
|
||||
/**
|
||||
* Sets the actor's clipboard.
|
||||
* @param actor the actor
|
||||
@ -131,9 +132,8 @@ public interface ClipboardFormat {
|
||||
return getReader(stream).read();
|
||||
}
|
||||
|
||||
|
||||
default URL upload(final Clipboard clipboard) {
|
||||
return MainUtil.upload(null, null, getPrimaryFileExtension(), new RunnableVal<OutputStream>() {
|
||||
return MainUtil.upload(null, null, getPrimaryFileExtension(), new RunnableVal<>() {
|
||||
@Override
|
||||
public void run(OutputStream value) {
|
||||
write(value, clipboard);
|
||||
@ -143,7 +143,7 @@ public interface ClipboardFormat {
|
||||
|
||||
default void write(OutputStream value, Clipboard clipboard) {
|
||||
try {
|
||||
try (PGZIPOutputStream gzip = new PGZIPOutputStream(value)) {
|
||||
try (ParallelGZIPOutputStream gzip = new ParallelGZIPOutputStream(value)) {
|
||||
try (ClipboardWriter writer = getWriter(gzip)) {
|
||||
writer.write(clipboard);
|
||||
}
|
||||
@ -152,4 +152,5 @@ public interface ClipboardFormat {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -21,10 +21,10 @@ package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.object.clipboard.LazyClipboardHolder;
|
||||
import com.fastasyncworldedit.core.object.clipboard.MultiClipboardHolder;
|
||||
import com.fastasyncworldedit.core.object.clipboard.URIClipboardHolder;
|
||||
import com.fastasyncworldedit.core.object.io.FastByteArrayOutputStream;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.LazyClipboardHolder;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.MultiClipboardHolder;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.URIClipboardHolder;
|
||||
import com.fastasyncworldedit.core.internal.io.FastByteArrayOutputStream;
|
||||
import com.fastasyncworldedit.core.util.MainUtil;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
@ -126,26 +126,6 @@ public class ClipboardFormats {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the format using the given extension.
|
||||
*
|
||||
* @param extension the extension
|
||||
* @return the format, otherwise null if one cannot be detected
|
||||
*/
|
||||
@Nullable
|
||||
public static ClipboardFormat findByExtension(String extension) {
|
||||
checkNotNull(extension);
|
||||
|
||||
Collection<Entry<String, ClipboardFormat>> entries = getFileExtensionMap().entries();
|
||||
for (Map.Entry<String, ClipboardFormat> entry : entries) {
|
||||
if (entry.getKey().equalsIgnoreCase(extension)) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A mapping from extensions to formats.
|
||||
*
|
||||
@ -170,6 +150,27 @@ public class ClipboardFormats {
|
||||
private ClipboardFormats() {
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
/**
|
||||
* Detect the format using the given extension.
|
||||
*
|
||||
* @param extension the extension
|
||||
* @return the format, otherwise null if one cannot be detected
|
||||
*/
|
||||
@Nullable
|
||||
public static ClipboardFormat findByExtension(String extension) {
|
||||
checkNotNull(extension);
|
||||
|
||||
Collection<Entry<String, ClipboardFormat>> entries = getFileExtensionMap().entries();
|
||||
for (Map.Entry<String, ClipboardFormat> entry : entries) {
|
||||
if (entry.getKey().equalsIgnoreCase(extension)) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public static MultiClipboardHolder loadAllFromInput(Actor player, String input, ClipboardFormat format, boolean message) throws IOException {
|
||||
checkNotNull(player);
|
||||
checkNotNull(input);
|
||||
@ -325,4 +326,5 @@ public class ClipboardFormats {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
import com.fastasyncworldedit.core.object.clipboard.DiskOptimizedClipboard;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.DiskOptimizedClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
|
||||
@ -43,7 +43,9 @@ public interface ClipboardReader extends Closeable {
|
||||
* @throws IOException thrown on I/O error
|
||||
*/
|
||||
default Clipboard read() throws IOException {
|
||||
//FAWE start
|
||||
return read(UUID.randomUUID());
|
||||
//FAWe end
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,6 +57,7 @@ public interface ClipboardReader extends Closeable {
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
default Clipboard read(UUID uuid) throws IOException {
|
||||
return read(uuid, DiskOptimizedClipboard::new);
|
||||
}
|
||||
@ -62,4 +65,5 @@ public interface ClipboardReader extends Closeable {
|
||||
default Clipboard read(UUID uuid, Function<BlockVector3, Clipboard> createOutput) throws IOException {
|
||||
return read();
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ public interface ClipboardWriter extends Closeable {
|
||||
*/
|
||||
void write(Clipboard clipboard) throws IOException;
|
||||
|
||||
//FAWE start
|
||||
default Tag writeVector(Vector3 vector) {
|
||||
List<DoubleTag> list = new ArrayList<>();
|
||||
list.add(new DoubleTag(vector.getX()));
|
||||
@ -61,4 +62,5 @@ public interface ClipboardWriter extends Closeable {
|
||||
list.add(new FloatTag(location.getPitch()));
|
||||
return new ListTag(FloatTag.class, list);
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -1,424 +0,0 @@
|
||||
/*
|
||||
* 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.clipboard.io;
|
||||
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.jnbt.streamer.StreamDelegate;
|
||||
import com.fastasyncworldedit.core.jnbt.streamer.ValueReader;
|
||||
import com.fastasyncworldedit.core.object.FaweInputStream;
|
||||
import com.fastasyncworldedit.core.object.FaweOutputStream;
|
||||
import com.fastasyncworldedit.core.object.clipboard.LinearClipboard;
|
||||
import com.fastasyncworldedit.core.object.io.FastByteArrayOutputStream;
|
||||
import com.fastasyncworldedit.core.object.io.FastByteArraysInputStream;
|
||||
import com.sk89q.jnbt.AdventureNBTConverter;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.internal.Constants;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||
import com.sk89q.worldedit.world.DataFixer;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
import com.sk89q.worldedit.world.entity.EntityType;
|
||||
import com.sk89q.worldedit.world.entity.EntityTypes;
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Reads schematic files using the Sponge Schematic Specification.
|
||||
*/
|
||||
public class FastSchematicReader extends NBTSchematicReader {
|
||||
|
||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||
private final NBTInputStream inputStream;
|
||||
private DataFixer fixer;
|
||||
private int dataVersion = -1;
|
||||
private int version = -1;
|
||||
private int faweWritten = -1;
|
||||
|
||||
private FastByteArrayOutputStream blocksOut;
|
||||
private FaweOutputStream blocks;
|
||||
|
||||
private FastByteArrayOutputStream biomesOut;
|
||||
private FaweOutputStream biomes;
|
||||
|
||||
private List<Map<String, Object>> tiles;
|
||||
private List<Map<String, Object>> entities;
|
||||
|
||||
private int width;
|
||||
private int height;
|
||||
private int length;
|
||||
private int offsetX;
|
||||
private int offsetY;
|
||||
private int offsetZ;
|
||||
private char[] palette;
|
||||
private char[] biomePalette;
|
||||
private BlockVector3 min = BlockVector3.ZERO;
|
||||
private boolean brokenEntities = false;
|
||||
private boolean isWorldEdit = false;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param inputStream the input stream to read from
|
||||
*/
|
||||
public FastSchematicReader(NBTInputStream inputStream) {
|
||||
checkNotNull(inputStream);
|
||||
this.inputStream = inputStream;
|
||||
this.fixer = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataFixer();
|
||||
}
|
||||
|
||||
public void setBrokenEntities(boolean brokenEntities) {
|
||||
this.brokenEntities = brokenEntities;
|
||||
}
|
||||
|
||||
private String fix(String palettePart) {
|
||||
if (fixer == null || dataVersion == -1) {
|
||||
return palettePart;
|
||||
}
|
||||
return fixer.fixUp(DataFixer.FixTypes.BLOCK_STATE, palettePart, dataVersion);
|
||||
}
|
||||
|
||||
private CompoundBinaryTag fixBlockEntity(CompoundTag tag) {
|
||||
if (fixer == null || dataVersion == -1) {
|
||||
return tag.asBinaryTag();
|
||||
}
|
||||
return fixer.fixUp(DataFixer.FixTypes.BLOCK_ENTITY, tag.asBinaryTag(), dataVersion);
|
||||
}
|
||||
|
||||
private CompoundBinaryTag fixEntity(CompoundTag tag) {
|
||||
if (fixer == null || dataVersion == -1) {
|
||||
return tag.asBinaryTag();
|
||||
}
|
||||
return fixer.fixUp(DataFixer.FixTypes.ENTITY, tag.asBinaryTag(), dataVersion);
|
||||
}
|
||||
|
||||
private String fixBiome(String biomePalettePart) {
|
||||
if (fixer == null || dataVersion == -1) {
|
||||
return biomePalettePart;
|
||||
}
|
||||
return fixer.fixUp(DataFixer.FixTypes.BIOME, biomePalettePart, dataVersion);
|
||||
}
|
||||
|
||||
public StreamDelegate createVersionDelegate() {
|
||||
StreamDelegate root = new StreamDelegate();
|
||||
StreamDelegate schematic = root.add("Schematic");
|
||||
schematic.add("DataVersion").withInt((i, v) -> dataVersion = v);
|
||||
schematic.add("Version").withInt((i, v) -> {
|
||||
version = v;
|
||||
if (v == 1 && dataVersion == -1) { // DataVersion might not be present, assume 1.13.2
|
||||
dataVersion = Constants.DATA_VERSION_MC_1_13_2;
|
||||
}
|
||||
});
|
||||
return root;
|
||||
}
|
||||
|
||||
public StreamDelegate createDelegate() {
|
||||
StreamDelegate root = new StreamDelegate();
|
||||
StreamDelegate schematic = root.add("Schematic");
|
||||
schematic.add("Width").withInt((i, v) -> width = v);
|
||||
schematic.add("Height").withInt((i, v) -> height = v);
|
||||
schematic.add("Length").withInt((i, v) -> length = v);
|
||||
schematic.add("Offset").withValue((ValueReader<int[]>) (index, v) -> min = BlockVector3.at(v[0], v[1], v[2]));
|
||||
|
||||
StreamDelegate metadata = schematic.add("Metadata");
|
||||
metadata.add("WEOffsetX").withInt((i, v) -> offsetX = v);
|
||||
metadata.add("WEOffsetY").withInt((i, v) -> offsetY = v);
|
||||
metadata.add("WEOffsetZ").withInt((i, v) -> offsetZ = v);
|
||||
metadata.add("FAWEVersion").withInt((i, v) -> faweWritten = v);
|
||||
|
||||
StreamDelegate worldEditSection = metadata.add("WorldEdit");
|
||||
worldEditSection.withValue((ValueReader<String>) (index, v) -> isWorldEdit = true);
|
||||
|
||||
|
||||
StreamDelegate paletteDelegate = schematic.add("Palette");
|
||||
paletteDelegate.withValue((ValueReader<Map<String, Object>>) (ignore, v) -> {
|
||||
palette = new char[v.size()];
|
||||
for (Entry<String, Object> entry : v.entrySet()) {
|
||||
BlockState state;
|
||||
String palettePart = fix(entry.getKey());
|
||||
try {
|
||||
state = BlockState.get(palettePart);
|
||||
} catch (InputParseException ignored) {
|
||||
LOGGER.warn("Invalid BlockState in palette: " + palettePart + ". Block will be replaced with air.");
|
||||
state = BlockTypes.AIR.getDefaultState();
|
||||
}
|
||||
int index = (int) entry.getValue();
|
||||
palette[index] = (char) state.getOrdinal();
|
||||
}
|
||||
});
|
||||
StreamDelegate blockData = schematic.add("BlockData");
|
||||
blockData.withInfo((length, type) -> {
|
||||
blocksOut = new FastByteArrayOutputStream();
|
||||
blocks = new FaweOutputStream(new LZ4BlockOutputStream(blocksOut));
|
||||
});
|
||||
blockData.withInt((index, value) -> blocks.write(value));
|
||||
|
||||
StreamDelegate tilesDelegate = schematic.add("BlockEntities");
|
||||
tilesDelegate.withInfo((length, type) -> tiles = new ArrayList<>(length));
|
||||
tilesDelegate.withElem((ValueReader<Map<String, Object>>) (index, tile) -> tiles.add(tile));
|
||||
|
||||
// Keep this here so schematics created with FAWE before TileEntities was fixed to BlockEntities still work
|
||||
StreamDelegate compatTilesDelegate = schematic.add("TileEntities");
|
||||
compatTilesDelegate.withInfo((length, type) -> tiles = new ArrayList<>(length));
|
||||
compatTilesDelegate.withElem((ValueReader<Map<String, Object>>) (index, tile) -> tiles.add(tile));
|
||||
|
||||
StreamDelegate entitiesDelegate = schematic.add("Entities");
|
||||
entitiesDelegate.withInfo((length, type) -> entities = new ArrayList<>(length));
|
||||
entitiesDelegate.withElem((ValueReader<Map<String, Object>>) (index, entity) -> entities.add(entity));
|
||||
|
||||
StreamDelegate biomePaletteDelegate = schematic.add("BiomePalette");
|
||||
biomePaletteDelegate.withValue((ValueReader<Map<String, Object>>) (ignore, v) -> {
|
||||
biomePalette = new char[v.size()];
|
||||
for (Entry<String, Object> entry : v.entrySet()) {
|
||||
BiomeType biome = null;
|
||||
try {
|
||||
String biomePalettePart = fixBiome(entry.getKey());
|
||||
biome = BiomeTypes.get(biomePalettePart);
|
||||
} catch (InputParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
int index = (int) entry.getValue();
|
||||
biomePalette[index] = (char) biome.getInternalId();
|
||||
}
|
||||
});
|
||||
StreamDelegate biomeData = schematic.add("BiomeData");
|
||||
biomeData.withInfo((length, type) -> {
|
||||
biomesOut = new FastByteArrayOutputStream();
|
||||
biomes = new FaweOutputStream(new LZ4BlockOutputStream(biomesOut));
|
||||
});
|
||||
biomeData.withInt((index, value) -> biomes.write(value));
|
||||
return root;
|
||||
}
|
||||
|
||||
private BlockState getBlockState(int id) {
|
||||
return BlockTypesCache.states[palette[id]];
|
||||
}
|
||||
|
||||
private BiomeType getBiomeType(FaweInputStream fis) throws IOException {
|
||||
char biomeId = biomePalette[fis.readVarInt()];
|
||||
return BiomeTypes.get(biomeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clipboard read(UUID uuid, Function<BlockVector3, Clipboard> createOutput) throws IOException {
|
||||
StreamDelegate root = createDelegate();
|
||||
StreamDelegate versions = createVersionDelegate();
|
||||
inputStream.mark(Integer.MAX_VALUE);
|
||||
inputStream.readNamedTagLazy(versions);
|
||||
inputStream.reset();
|
||||
inputStream.readNamedTagLazy(root);
|
||||
|
||||
if (version != 1 && version != 2) {
|
||||
throw new IOException("This schematic version is not supported; Version: " + version + ", DataVersion: " + dataVersion + ". It's very likely your schematic has an invalid file extension, if the schematic has been created on a version lower than 1.13.2, the extension MUST be `.schematic`, elsewise the schematic can't be read properly.");
|
||||
}
|
||||
|
||||
if (blocks != null) {
|
||||
blocks.close();
|
||||
}
|
||||
if (biomes != null) {
|
||||
biomes.close();
|
||||
}
|
||||
blocks = null;
|
||||
biomes = null;
|
||||
|
||||
BlockVector3 dimensions = BlockVector3.at(width, height, length);
|
||||
BlockVector3 origin;
|
||||
if (offsetX != Integer.MIN_VALUE && offsetY != Integer.MIN_VALUE && offsetZ != Integer.MIN_VALUE) {
|
||||
origin = BlockVector3.at(-offsetX, -offsetY, -offsetZ);
|
||||
} else {
|
||||
origin = BlockVector3.ZERO;
|
||||
}
|
||||
|
||||
Clipboard clipboard = createOutput.apply(dimensions);
|
||||
|
||||
if (blocksOut != null && blocksOut.getSize() != 0) {
|
||||
try (FaweInputStream fis = new FaweInputStream(new LZ4BlockInputStream(new FastByteArraysInputStream(blocksOut.toByteArrays())))) {
|
||||
if (clipboard instanceof LinearClipboard) {
|
||||
LinearClipboard linear = (LinearClipboard) clipboard;
|
||||
int volume = width * height * length;
|
||||
if (palette.length < 128) {
|
||||
for (int index = 0; index < volume; index++) {
|
||||
int ordinal = fis.read();
|
||||
linear.setBlock(index, getBlockState(ordinal));
|
||||
}
|
||||
} else {
|
||||
for (int index = 0; index < volume; index++) {
|
||||
int ordinal = fis.readVarInt();
|
||||
linear.setBlock(index, getBlockState(ordinal));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (palette.length < 128) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int ordinal = fis.read();
|
||||
clipboard.setBlock(x, y, z, getBlockState(ordinal));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int ordinal = fis.readVarInt();
|
||||
clipboard.setBlock(x, y, z, getBlockState(ordinal));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (biomesOut != null && biomesOut.getSize() != 0) {
|
||||
try (FaweInputStream fis = new FaweInputStream(new LZ4BlockInputStream(new FastByteArraysInputStream(biomesOut.toByteArrays())))) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
BiomeType biome = getBiomeType(fis);
|
||||
for (int y = 0; y < height; y ++) {
|
||||
clipboard.setBiome(x, y, z, biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// tiles
|
||||
if (tiles != null && !tiles.isEmpty()) {
|
||||
for (Map<String, Object> tileRaw : tiles) {
|
||||
CompoundTag tile = FaweCache.IMP.asTag(tileRaw);
|
||||
|
||||
int[] pos = tile.getIntArray("Pos");
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
if (pos.length != 3) {
|
||||
if (!tile.containsKey("x") || !tile.containsKey("y") || !tile.containsKey("z")) {
|
||||
return null;
|
||||
}
|
||||
x = tile.getInt("x");
|
||||
y = tile.getInt("y");
|
||||
z = tile.getInt("z");
|
||||
} else {
|
||||
x = pos[0];
|
||||
y = pos[1];
|
||||
z = pos[2];
|
||||
}
|
||||
Map<String, Tag> values = new HashMap<>(tile.getValue());
|
||||
Tag id = values.get("Id");
|
||||
if (id != null) {
|
||||
values.put("x", new IntTag(x));
|
||||
values.put("y", new IntTag(y));
|
||||
values.put("z", new IntTag(z));
|
||||
values.put("id", id);
|
||||
}
|
||||
values.remove("Id");
|
||||
values.remove("Pos");
|
||||
|
||||
clipboard.setTile(x, y, z, (CompoundTag) AdventureNBTConverter.fromAdventure(fixBlockEntity(new CompoundTag(values))));
|
||||
}
|
||||
}
|
||||
|
||||
// entities
|
||||
if (entities != null && !entities.isEmpty()) {
|
||||
for (Map<String, Object> entRaw : entities) {
|
||||
Map<String, Tag> value = new HashMap<>(FaweCache.IMP.asTag(entRaw).getValue());
|
||||
StringTag id = (StringTag) value.get("Id");
|
||||
if (id == null) {
|
||||
id = (StringTag) value.get("id");
|
||||
if (id == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
value.put("id", id);
|
||||
value.remove("Id");
|
||||
|
||||
EntityType type = EntityTypes.parse(id.getValue());
|
||||
if (type != null) {
|
||||
final CompoundTag ent = (CompoundTag) AdventureNBTConverter.fromAdventure(fixEntity(new CompoundTag(value)));
|
||||
BaseEntity state = new BaseEntity(type, ent);
|
||||
Location loc = ent.getEntityLocation(clipboard);
|
||||
if (brokenEntities) {
|
||||
clipboard.createEntity(loc, state);
|
||||
continue;
|
||||
}
|
||||
if (!isWorldEdit && faweWritten == -1) {
|
||||
int locX = loc.getBlockX();
|
||||
int locY = loc.getBlockY();
|
||||
int locZ = loc.getBlockZ();
|
||||
BlockVector3 max = min.add(dimensions).subtract(BlockVector3.ONE);
|
||||
if (locX < min.getX() || locY < min.getY() || locZ < min.getZ()
|
||||
|| locX > max.getX() || locY > max.getY() || locZ > max.getZ()) {
|
||||
for (Entity e : clipboard.getEntities()) {
|
||||
clipboard.removeEntity(e);
|
||||
}
|
||||
LOGGER.error("Detected schematic entity outside clipboard region. FAWE will not load entities. "
|
||||
+ "Please try loading the schematic with the format \"legacyentity\"");
|
||||
break;
|
||||
}
|
||||
}
|
||||
clipboard.createEntity(loc.setPosition(loc.subtract(min.toVector3())), state);
|
||||
} else {
|
||||
LOGGER.debug("Invalid entity: " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
clipboard.setOrigin(origin);
|
||||
|
||||
if (!min.equals(BlockVector3.ZERO)) {
|
||||
clipboard = new BlockArrayClipboard(clipboard, min);
|
||||
}
|
||||
|
||||
return clipboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
inputStream.close();
|
||||
}
|
||||
}
|
@ -1,328 +0,0 @@
|
||||
/*
|
||||
* 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.clipboard.io;
|
||||
|
||||
import com.fastasyncworldedit.core.Fawe;
|
||||
import com.fastasyncworldedit.core.jnbt.streamer.IntValueReader;
|
||||
import com.fastasyncworldedit.core.object.FaweOutputStream;
|
||||
import com.fastasyncworldedit.core.util.IOUtil;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.IntArrayTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.NBTConstants;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.visitor.Order;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Writes schematic files using the Sponge schematic format.
|
||||
*/
|
||||
public class FastSchematicWriter implements ClipboardWriter {
|
||||
|
||||
private static final int CURRENT_VERSION = 2;
|
||||
|
||||
private static final int MAX_SIZE = Short.MAX_VALUE - Short.MIN_VALUE;
|
||||
private final NBTOutputStream outputStream;
|
||||
private boolean brokenEntities = false;
|
||||
|
||||
/**
|
||||
* Create a new schematic writer.
|
||||
*
|
||||
* @param outputStream the output stream to write to
|
||||
*/
|
||||
public FastSchematicWriter(NBTOutputStream outputStream) {
|
||||
checkNotNull(outputStream);
|
||||
this.outputStream = outputStream;
|
||||
}
|
||||
|
||||
public void setBrokenEntities(boolean brokenEntities) {
|
||||
this.brokenEntities = brokenEntities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Clipboard clipboard) throws IOException {
|
||||
// For now always write the latest version. Maybe provide support for earlier if more appear.
|
||||
write2(clipboard);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a version 2 schematic file.
|
||||
*
|
||||
* @param clipboard The clipboard
|
||||
*/
|
||||
private void write2(Clipboard clipboard) throws IOException {
|
||||
Region region = clipboard.getRegion();
|
||||
BlockVector3 origin = clipboard.getOrigin();
|
||||
BlockVector3 min = region.getMinimumPoint();
|
||||
BlockVector3 offset = min.subtract(origin);
|
||||
int width = region.getWidth();
|
||||
int height = region.getHeight();
|
||||
int length = region.getLength();
|
||||
|
||||
if (width > MAX_SIZE) {
|
||||
throw new IllegalArgumentException("Width of region too large for a .schematic");
|
||||
}
|
||||
if (height > MAX_SIZE) {
|
||||
throw new IllegalArgumentException("Height of region too large for a .schematic");
|
||||
}
|
||||
if (length > MAX_SIZE) {
|
||||
throw new IllegalArgumentException("Length of region too large for a .schematic");
|
||||
}
|
||||
|
||||
final DataOutput rawStream = outputStream.getOutputStream();
|
||||
outputStream.writeLazyCompoundTag("Schematic", out -> {
|
||||
out.writeNamedTag("DataVersion", WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion());
|
||||
out.writeNamedTag("Version", CURRENT_VERSION);
|
||||
out.writeNamedTag("Width", (short) width);
|
||||
out.writeNamedTag("Height", (short) height);
|
||||
out.writeNamedTag("Length", (short) length);
|
||||
|
||||
// The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin'
|
||||
out.writeNamedTag("Offset", new int[]{
|
||||
min.getBlockX(),
|
||||
min.getBlockY(),
|
||||
min.getBlockZ(),
|
||||
});
|
||||
|
||||
out.writeLazyCompoundTag("Metadata", out1 -> {
|
||||
out1.writeNamedTag("WEOffsetX", offset.getBlockX());
|
||||
out1.writeNamedTag("WEOffsetY", offset.getBlockY());
|
||||
out1.writeNamedTag("WEOffsetZ", offset.getBlockZ());
|
||||
out1.writeNamedTag("FAWEVersion", Fawe.get().getVersion().build);
|
||||
});
|
||||
|
||||
ByteArrayOutputStream blocksCompressed = new ByteArrayOutputStream();
|
||||
FaweOutputStream blocksOut = new FaweOutputStream(new DataOutputStream(new LZ4BlockOutputStream(blocksCompressed)));
|
||||
|
||||
ByteArrayOutputStream tilesCompressed = new ByteArrayOutputStream();
|
||||
NBTOutputStream tilesOut = new NBTOutputStream(new LZ4BlockOutputStream(tilesCompressed));
|
||||
|
||||
List<Integer> paletteList = new ArrayList<>();
|
||||
char[] palette = new char[BlockTypesCache.states.length];
|
||||
Arrays.fill(palette, Character.MAX_VALUE);
|
||||
int paletteMax = 0;
|
||||
int numTiles = 0;
|
||||
Clipboard finalClipboard;
|
||||
if (clipboard instanceof BlockArrayClipboard) {
|
||||
finalClipboard = ((BlockArrayClipboard) clipboard).getParent();
|
||||
} else {
|
||||
finalClipboard = clipboard;
|
||||
}
|
||||
Iterator<BlockVector3> iterator = finalClipboard.iterator(Order.YZX);
|
||||
while (iterator.hasNext()) {
|
||||
BlockVector3 pos = iterator.next();
|
||||
BaseBlock block = pos.getFullBlock(finalClipboard);
|
||||
CompoundTag nbt = block.getNbtData();
|
||||
if (nbt != null) {
|
||||
Map<String, Tag> values = new HashMap<>(nbt.getValue());
|
||||
|
||||
// Positions are kept in NBT, we don't want that.
|
||||
values.remove("x");
|
||||
values.remove("y");
|
||||
values.remove("z");
|
||||
values.put("Id", new StringTag(block.getNbtId()));
|
||||
|
||||
// Remove 'id' if it exists. We want 'Id'.
|
||||
// Do this after we get "getNbtId" cos otherwise "getNbtId" doesn't work.
|
||||
// Dum.
|
||||
values.remove("id");
|
||||
values.put("Pos", new IntArrayTag(new int[]{
|
||||
pos.getX(),
|
||||
pos.getY(),
|
||||
pos.getZ()
|
||||
}));
|
||||
numTiles++;
|
||||
|
||||
tilesOut.writeTagPayload(new CompoundTag(values));
|
||||
}
|
||||
|
||||
int ordinal = block.getOrdinal();
|
||||
if (ordinal == 0) {
|
||||
ordinal = 1;
|
||||
}
|
||||
char value = palette[ordinal];
|
||||
if (value == Character.MAX_VALUE) {
|
||||
int size = paletteMax++;
|
||||
palette[ordinal] = value = (char) size;
|
||||
paletteList.add(ordinal);
|
||||
}
|
||||
blocksOut.writeVarInt(value);
|
||||
}
|
||||
// close
|
||||
tilesOut.close();
|
||||
blocksOut.close();
|
||||
|
||||
out.writeNamedTag("PaletteMax", paletteMax);
|
||||
|
||||
out.writeLazyCompoundTag("Palette", out12 -> {
|
||||
for (int i = 0; i < paletteList.size(); i++) {
|
||||
int stateOrdinal = paletteList.get(i);
|
||||
BlockState state = BlockTypesCache.states[stateOrdinal];
|
||||
out12.writeNamedTag(state.getAsString(), i);
|
||||
}
|
||||
});
|
||||
|
||||
out.writeNamedTagName("BlockData", NBTConstants.TYPE_BYTE_ARRAY);
|
||||
rawStream.writeInt(blocksOut.size());
|
||||
try (LZ4BlockInputStream in = new LZ4BlockInputStream(new ByteArrayInputStream(blocksCompressed.toByteArray()))) {
|
||||
IOUtil.copy(in, rawStream);
|
||||
}
|
||||
|
||||
if (numTiles != 0) {
|
||||
out.writeNamedTagName("BlockEntities", NBTConstants.TYPE_LIST);
|
||||
rawStream.write(NBTConstants.TYPE_COMPOUND);
|
||||
rawStream.writeInt(numTiles);
|
||||
try (LZ4BlockInputStream in = new LZ4BlockInputStream(new ByteArrayInputStream(tilesCompressed.toByteArray()))) {
|
||||
IOUtil.copy(in, rawStream);
|
||||
}
|
||||
} else {
|
||||
out.writeNamedEmptyList("BlockEntities");
|
||||
}
|
||||
|
||||
if (finalClipboard.hasBiomes()) {
|
||||
writeBiomes(finalClipboard, out);
|
||||
}
|
||||
|
||||
List<Tag> entities = new ArrayList<>();
|
||||
for (Entity entity : finalClipboard.getEntities()) {
|
||||
BaseEntity state = entity.getState();
|
||||
|
||||
if (state != null) {
|
||||
Map<String, Tag> values = new HashMap<>();
|
||||
|
||||
// Put NBT provided data
|
||||
CompoundTag rawTag = state.getNbtData();
|
||||
if (rawTag != null) {
|
||||
values.putAll(rawTag.getValue());
|
||||
}
|
||||
|
||||
// Store our location data, overwriting any
|
||||
values.remove("id");
|
||||
Location loc = entity.getLocation();
|
||||
if (!brokenEntities) {
|
||||
loc = loc.setPosition(loc.add(min.toVector3()));
|
||||
}
|
||||
values.put("Id", new StringTag(state.getType().getId()));
|
||||
values.put("Pos", writeVector(loc));
|
||||
values.put("Rotation", writeRotation(entity.getLocation()));
|
||||
|
||||
CompoundTag entityTag = new CompoundTag(values);
|
||||
entities.add(entityTag);
|
||||
}
|
||||
}
|
||||
if (entities.isEmpty()) {
|
||||
out.writeNamedEmptyList("Entities");
|
||||
} else {
|
||||
out.writeNamedTag("Entities", new ListTag(CompoundTag.class, entities));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void writeBiomes(Clipboard clipboard, NBTOutputStream out) throws IOException {
|
||||
ByteArrayOutputStream biomesCompressed = new ByteArrayOutputStream();
|
||||
DataOutputStream biomesOut = new DataOutputStream(new LZ4BlockOutputStream(biomesCompressed));
|
||||
|
||||
List<Integer> paletteList = new ArrayList<>();
|
||||
int[] palette = new int[BiomeTypes.getMaxId() + 1];
|
||||
Arrays.fill(palette, Integer.MAX_VALUE);
|
||||
int[] paletteMax = {0};
|
||||
IntValueReader task = new IntValueReader() {
|
||||
@Override
|
||||
public void applyInt(int index, int ordinal) {
|
||||
try {
|
||||
int value = palette[ordinal];
|
||||
if (value == Integer.MAX_VALUE) {
|
||||
int size = paletteMax[0]++;
|
||||
palette[ordinal] = value = size;
|
||||
paletteList.add(ordinal);
|
||||
}
|
||||
IOUtil.writeVarInt(biomesOut, value);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
BlockVector3 min = clipboard.getMinimumPoint();
|
||||
int width = clipboard.getRegion().getWidth();
|
||||
int length = clipboard.getRegion().getLength();
|
||||
for (int z = 0, i = 0; z < length; z++) {
|
||||
int z0 = min.getBlockZ() + z;
|
||||
for (int x = 0; x < width; x++, i++) {
|
||||
int x0 = min.getBlockX() + x;
|
||||
BlockVector3 pt = BlockVector3.at(x0, min.getBlockY(), z0);
|
||||
BiomeType biome = clipboard.getBiome(pt);
|
||||
task.applyInt(i, biome.getInternalId());
|
||||
}
|
||||
}
|
||||
biomesOut.close();
|
||||
|
||||
out.writeNamedTag("BiomePaletteMax", paletteMax[0]);
|
||||
|
||||
out.writeLazyCompoundTag("BiomePalette", out12 -> {
|
||||
for (int i = 0; i < paletteList.size(); i++) {
|
||||
int ordinal = paletteList.get(i);
|
||||
BiomeType state = BiomeTypes.get(ordinal);
|
||||
out12.writeNamedTag(state.getId(), i);
|
||||
}
|
||||
});
|
||||
|
||||
out.writeNamedTagName("BiomeData", NBTConstants.TYPE_BYTE_ARRAY);
|
||||
out.writeInt(biomesOut.size());
|
||||
try (LZ4BlockInputStream in = new LZ4BlockInputStream(new ByteArrayInputStream(biomesCompressed.toByteArray()))) {
|
||||
IOUtil.copy(in, (DataOutput) out);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
outputStream.close();
|
||||
}
|
||||
}
|
@ -222,7 +222,9 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
||||
}
|
||||
|
||||
if (fixer != null && t != null) {
|
||||
//FAWE start
|
||||
t = (CompoundTag) AdventureNBTConverter.fromAdventure(fixer.fixUp(DataFixer.FixTypes.BLOCK_ENTITY, t.asBinaryTag(), -1));
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
BlockVector3 vec = BlockVector3.at(x, y, z);
|
||||
|
@ -26,7 +26,7 @@ import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Base class for NBT schematic readers
|
||||
* Base class for NBT schematic readers.
|
||||
*/
|
||||
public abstract class NBTSchematicReader implements ClipboardReader {
|
||||
|
||||
|
@ -125,7 +125,9 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
BlockArrayClipboard clip = readVersion1(schematicTag);
|
||||
return readVersion2(clip, schematicTag);
|
||||
}
|
||||
throw new IOException("This schematic version is not supported; Version: " + schematicVersion + ", DataVersion: " + dataVersion + ". It's very likely your schematic has an invalid file extension, if the schematic has been created on a version lower than 1.13.2, the extension MUST be `.schematic`, elsewise the schematic can't be read properly.");
|
||||
throw new IOException("This schematic version is not supported; Version: " + schematicVersion + ", DataVersion: " + dataVersion + "." +
|
||||
"It's very likely your schematic has an invalid file extension, if the schematic has been created on a version lower than" +
|
||||
"1.13.2, the extension MUST be `.schematic`, elsewise the schematic can't be read properly.");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -248,7 +250,10 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
values.remove("Id");
|
||||
values.remove("Pos");
|
||||
if (fixer != null) {
|
||||
tileEntity = ((CompoundTag) AdventureNBTConverter.fromAdventure(fixer.fixUp(DataFixer.FixTypes.BLOCK_ENTITY, new CompoundTag(values).asBinaryTag(), dataVersion))).getValue();
|
||||
//FAWE start
|
||||
tileEntity = ((CompoundTag) AdventureNBTConverter.fromAdventure(fixer.fixUp(DataFixer.FixTypes.BLOCK_ENTITY,
|
||||
new CompoundTag(values).asBinaryTag(), dataVersion))).getValue();
|
||||
//FAWE end
|
||||
} else {
|
||||
tileEntity = values;
|
||||
}
|
||||
@ -386,7 +391,9 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
entityTag = entityTag.createBuilder().putString("id", id).remove("Id").build();
|
||||
|
||||
if (fixer != null) {
|
||||
//FAWE start
|
||||
entityTag = (CompoundTag) AdventureNBTConverter.fromAdventure(fixer.fixUp(DataFixer.FixTypes.ENTITY, entityTag.asBinaryTag(), dataVersion));
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
EntityType entityType = EntityTypes.get(id);
|
||||
|
@ -39,8 +39,10 @@ import javax.annotation.Nullable;
|
||||
*/
|
||||
public class BlockBagExtent extends AbstractDelegateExtent {
|
||||
|
||||
//FAWE start
|
||||
private final boolean mine;
|
||||
private int[] missingBlocks = new int[BlockTypes.size()];
|
||||
//FAWE end
|
||||
private BlockBag blockBag;
|
||||
|
||||
/**
|
||||
@ -49,6 +51,7 @@ public class BlockBagExtent extends AbstractDelegateExtent {
|
||||
* @param extent the extent
|
||||
* @param blockBag the block bag
|
||||
*/
|
||||
//FAWE start
|
||||
public BlockBagExtent(Extent extent, @Nullable BlockBag blockBag) {
|
||||
this(extent, blockBag, false);
|
||||
}
|
||||
@ -58,6 +61,7 @@ public class BlockBagExtent extends AbstractDelegateExtent {
|
||||
this.blockBag = blockBag;
|
||||
this.mine = mine;
|
||||
}
|
||||
//FAWe end
|
||||
|
||||
/**
|
||||
* Get the block bag.
|
||||
@ -85,6 +89,7 @@ public class BlockBagExtent extends AbstractDelegateExtent {
|
||||
* @return a map of missing blocks
|
||||
*/
|
||||
public Map<BlockType, Integer> popMissing() {
|
||||
//FAWE start - Use an Array
|
||||
HashMap<BlockType, Integer> map = new HashMap<>();
|
||||
for (int i = 0; i < missingBlocks.length; i++) {
|
||||
int count = missingBlocks[i];
|
||||
@ -94,6 +99,7 @@ public class BlockBagExtent extends AbstractDelegateExtent {
|
||||
}
|
||||
Arrays.fill(missingBlocks, 0);
|
||||
return map;
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -111,10 +117,13 @@ public class BlockBagExtent extends AbstractDelegateExtent {
|
||||
} catch (UnplaceableBlockException e) {
|
||||
throw FaweCache.BLOCK_BAG;
|
||||
} catch (BlockBagException e) {
|
||||
//FAWE start - listen for internal ids
|
||||
missingBlocks[block.getBlockType().getInternalId()]++;
|
||||
throw FaweCache.BLOCK_BAG;
|
||||
//FAWE end
|
||||
}
|
||||
}
|
||||
//FAWE start
|
||||
if (mine) {
|
||||
if (!existing.getBlockType().getMaterial().isAir()) {
|
||||
try {
|
||||
@ -123,6 +132,7 @@ public class BlockBagExtent extends AbstractDelegateExtent {
|
||||
}
|
||||
}
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
return super.setBlock(x, y, z, block);
|
||||
|
@ -26,7 +26,7 @@ import com.sk89q.worldedit.world.block.BlockType;
|
||||
*/
|
||||
public class OutOfSpaceException extends BlockBagException {
|
||||
|
||||
private BlockType type;
|
||||
private final BlockType type;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
|
@ -1,17 +0,0 @@
|
||||
package com.sk89q.worldedit.extent.inventory;
|
||||
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
|
||||
public interface SlottableBlockBag {
|
||||
BaseItem getItem(int slot);
|
||||
|
||||
void setItem(int slot, BaseItem block);
|
||||
|
||||
default int size() {
|
||||
return 36;
|
||||
}
|
||||
|
||||
default int getSelectedSlot() {
|
||||
return -1;
|
||||
}
|
||||
}
|
@ -132,15 +132,19 @@ public class MultiStageReorder extends AbstractBufferingExtent implements Reorde
|
||||
BlockCategories.DOORS.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.FINAL));
|
||||
BlockCategories.BANNERS.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.FINAL));
|
||||
BlockCategories.SIGNS.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.FINAL));
|
||||
priorityMap.put(BlockTypes.SIGN, PlacementPriority.FINAL);
|
||||
priorityMap.put(BlockTypes.WALL_SIGN, PlacementPriority.FINAL);
|
||||
@SuppressWarnings("deprecation")
|
||||
BlockType sign = BlockTypes.SIGN;
|
||||
priorityMap.put(sign, PlacementPriority.FINAL);
|
||||
@SuppressWarnings("deprecation")
|
||||
BlockType wallSign = BlockTypes.WALL_SIGN;
|
||||
priorityMap.put(wallSign, PlacementPriority.FINAL);
|
||||
priorityMap.put(BlockTypes.CACTUS, PlacementPriority.FINAL);
|
||||
priorityMap.put(BlockTypes.SUGAR_CANE, PlacementPriority.FINAL);
|
||||
priorityMap.put(BlockTypes.PISTON_HEAD, PlacementPriority.FINAL);
|
||||
priorityMap.put(BlockTypes.MOVING_PISTON, PlacementPriority.FINAL);
|
||||
}
|
||||
|
||||
private Map<PlacementPriority, BlockMap<BaseBlock>> stages = new HashMap<>();
|
||||
private final Map<PlacementPriority, BlockMap<BaseBlock>> stages = new HashMap<>();
|
||||
|
||||
private boolean enabled;
|
||||
|
||||
@ -233,6 +237,8 @@ public class MultiStageReorder extends AbstractBufferingExtent implements Reorde
|
||||
case LAST:
|
||||
stages.get(PlacementPriority.CLEAR_LAST).put(location, replacement);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (block.getBlockType().getMaterial().isAir()) {
|
||||
|
@ -20,7 +20,7 @@
|
||||
package com.sk89q.worldedit.extent.transform;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.object.extent.ResettableExtent;
|
||||
import com.fastasyncworldedit.core.extent.ResettableExtent;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.sk89q.jnbt.ByteTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
@ -36,8 +36,8 @@ import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.registry.state.AbstractProperty;
|
||||
import com.sk89q.worldedit.registry.state.DirectionalProperty;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKeySet;
|
||||
import com.fastasyncworldedit.core.registry.state.PropertyKey;
|
||||
import com.fastasyncworldedit.core.registry.state.PropertyKeySet;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
@ -83,6 +83,7 @@ import static com.sk89q.worldedit.util.Direction.values;
|
||||
*/
|
||||
public class BlockTransformExtent extends ResettableExtent {
|
||||
|
||||
//FAWE start
|
||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||
|
||||
private static final Set<PropertyKey> directional = PropertyKeySet.of(
|
||||
@ -115,6 +116,7 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
public BlockTransformExtent(Extent parent) {
|
||||
this(parent, new AffineTransform());
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
@ -125,11 +127,14 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
super(extent);
|
||||
checkNotNull(transform);
|
||||
this.transform = transform;
|
||||
//FAWE start - cache this
|
||||
this.transformInverse = this.transform.inverse();
|
||||
cache();
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
|
||||
//FAWE start
|
||||
private static long combine(Direction... directions) {
|
||||
long mask = 0;
|
||||
for (Direction dir : directions) {
|
||||
@ -444,6 +449,7 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
}
|
||||
}
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
/**
|
||||
* Get the transform.
|
||||
@ -497,8 +503,10 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
|
||||
public void setTransform(Transform affine) {
|
||||
this.transform = affine;
|
||||
//FAWE start - cache this
|
||||
this.transformInverse = this.transform.inverse();
|
||||
cache();
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
/**
|
||||
@ -511,6 +519,7 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
* @return the same block
|
||||
*/
|
||||
public static <B extends BlockStateHolder<B>> B transform(@NotNull B block, @NotNull Transform transform) {
|
||||
//FAWE start - use own logic
|
||||
// performance critical
|
||||
BlockState state = block.toImmutableState();
|
||||
|
||||
@ -520,8 +529,10 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
return (B) transformBaseBlockNBT(transformed, block.getNbtData(), transform);
|
||||
}
|
||||
return (B) (block instanceof BaseBlock ? transformed.toBaseBlock() : transformed);
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
//FAWE start - use own logic
|
||||
private BlockState transform(BlockState state, int[][] transformArray, Transform transform) {
|
||||
int typeId = state.getInternalBlockTypeId();
|
||||
int[] arr = transformArray[typeId];
|
||||
@ -570,4 +581,5 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
private BlockState transformInverse(BlockState block) {
|
||||
return transform(block, BLOCK_TRANSFORM_INVERSE, transformInverse);
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ public class DataValidatorExtent extends AbstractDelegateExtent {
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
|
||||
final int y = location.getBlockY();
|
||||
final BlockType type = block.getBlockType();
|
||||
if (y < 0 || y > world.getMaxY()) {
|
||||
if (y < world.getMinY() || y > world.getMaxY()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3,18 +3,18 @@
|
||||
* 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
|
||||
* 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 Lesser General Public License
|
||||
* for more details.
|
||||
* 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 Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* 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.world;
|
||||
@ -45,6 +45,6 @@ public class BiomeQuirkExtent extends AbstractDelegateExtent {
|
||||
// Also place at Y = 0 for proper handling
|
||||
success = super.setBiome(position.withY(0), biome);
|
||||
}
|
||||
return success || super.setBiome(position, biome);
|
||||
return super.setBiome(position, biome) || success;
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
/**
|
||||
* Handles various quirks when setting blocks, such as ice turning
|
||||
* into water or containers dropping their contents.
|
||||
*
|
||||
* @deprecated Handled by the world entirely now
|
||||
*/
|
||||
@Deprecated
|
||||
public class BlockQuirkExtent extends AbstractDelegateExtent {
|
||||
|
||||
private final World world;
|
||||
|
@ -35,7 +35,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
public class ChunkLoadingExtent extends AbstractDelegateExtent {
|
||||
|
||||
private final World world;
|
||||
private boolean enabled;
|
||||
private final boolean enabled;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
|
@ -96,7 +96,9 @@ public class SurvivalModeExtent extends AbstractDelegateExtent {
|
||||
} else {
|
||||
// Can't be an inlined check due to inconsistent generic return type
|
||||
if (stripNbt) {
|
||||
//FAWE start - Use CompoundBinaryTag
|
||||
return super.setBlock(location, block.toBaseBlock((CompoundBinaryTag) null));
|
||||
//FAWE end
|
||||
} else {
|
||||
return super.setBlock(location, block);
|
||||
}
|
||||
|
Reference in New Issue
Block a user