mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-22 17:27:38 +00:00
This commit is contained in:
commit
637dc2df15
6
.github/workflows/codeql.yml
vendored
6
.github/workflows/codeql.yml
vendored
@ -27,10 +27,10 @@ jobs:
|
|||||||
cache: gradle
|
cache: gradle
|
||||||
java-version: 17
|
java-version: 17
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v3
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v2
|
uses: github/codeql-action/autobuild@v3
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v3
|
||||||
|
@ -34,7 +34,7 @@ logger.lifecycle("""
|
|||||||
*******************************************
|
*******************************************
|
||||||
""")
|
""")
|
||||||
|
|
||||||
var rootVersion by extra("2.8.4")
|
var rootVersion by extra("2.8.5")
|
||||||
var snapshot by extra("SNAPSHOT")
|
var snapshot by extra("SNAPSHOT")
|
||||||
var revision: String by extra("")
|
var revision: String by extra("")
|
||||||
var buildNumber by extra("")
|
var buildNumber by extra("")
|
||||||
|
@ -24,7 +24,7 @@ dependencies {
|
|||||||
implementation(gradleApi())
|
implementation(gradleApi())
|
||||||
implementation("org.ajoberstar.grgit:grgit-gradle:5.2.1")
|
implementation("org.ajoberstar.grgit:grgit-gradle:5.2.1")
|
||||||
implementation("com.github.johnrengelman:shadow:8.1.1")
|
implementation("com.github.johnrengelman:shadow:8.1.1")
|
||||||
implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.5.10")
|
implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.5.11")
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[versions]
|
[versions]
|
||||||
# Minecraft expectations
|
# Minecraft expectations
|
||||||
paper = "1.20.2-R0.1-SNAPSHOT"
|
paper = "1.20.4-R0.1-SNAPSHOT"
|
||||||
fastutil = "8.5.9"
|
fastutil = "8.5.9"
|
||||||
guava = "31.1-jre"
|
guava = "31.1-jre"
|
||||||
log4j = "2.19.0"
|
log4j = "2.19.0"
|
||||||
@ -14,16 +14,16 @@ mapmanager = "1.8.0-SNAPSHOT"
|
|||||||
griefprevention = "16.18.1"
|
griefprevention = "16.18.1"
|
||||||
griefdefender = "2.1.0-SNAPSHOT"
|
griefdefender = "2.1.0-SNAPSHOT"
|
||||||
residence = "4.5._13.1"
|
residence = "4.5._13.1"
|
||||||
towny = "0.100.0.8"
|
towny = "0.100.0.11"
|
||||||
plotsquared = "7.2.0"
|
plotsquared = "7.2.1"
|
||||||
|
|
||||||
# Third party
|
# Third party
|
||||||
bstats = "3.0.2"
|
bstats = "3.0.2"
|
||||||
sparsebitset = "1.3"
|
sparsebitset = "1.3"
|
||||||
parallelgzip = "1.0.5"
|
parallelgzip = "1.0.5"
|
||||||
adventure = "4.14.0"
|
adventure = "4.15.0"
|
||||||
adventure-bukkit = "4.3.1"
|
adventure-bukkit = "4.3.2"
|
||||||
checkerqual = "3.41.0"
|
checkerqual = "3.42.0"
|
||||||
truezip = "6.8.4"
|
truezip = "6.8.4"
|
||||||
auto-value = "1.10.4"
|
auto-value = "1.10.4"
|
||||||
findbugs = "3.0.2"
|
findbugs = "3.0.2"
|
||||||
|
@ -12,6 +12,6 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/
|
// https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/
|
||||||
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.4-R0.1-20231207.202833-1")
|
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.4-R0.1-20231221.211952-22")
|
||||||
compileOnly(libs.paperlib)
|
compileOnly(libs.paperlib)
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,7 @@ tasks.named<ShadowJar>("shadowJar") {
|
|||||||
include(dependency("org.lz4:lz4-java:1.8.0"))
|
include(dependency("org.lz4:lz4-java:1.8.0"))
|
||||||
}
|
}
|
||||||
relocate("net.kyori", "com.fastasyncworldedit.core.adventure") {
|
relocate("net.kyori", "com.fastasyncworldedit.core.adventure") {
|
||||||
include(dependency("net.kyori:adventure-nbt:4.14.0"))
|
include(dependency("net.kyori:adventure-nbt:4.15.0"))
|
||||||
}
|
}
|
||||||
relocate("com.zaxxer", "com.fastasyncworldedit.core.math") {
|
relocate("com.zaxxer", "com.fastasyncworldedit.core.math") {
|
||||||
include(dependency("com.zaxxer:SparseBitSet:1.3"))
|
include(dependency("com.zaxxer:SparseBitSet:1.3"))
|
||||||
|
@ -721,6 +721,13 @@ public class Settings extends Config {
|
|||||||
" - Requires clipboard.use-disk to be enabled"
|
" - Requires clipboard.use-disk to be enabled"
|
||||||
})
|
})
|
||||||
public boolean SAVE_CLIPBOARD_NBT_TO_DISK = true;
|
public boolean SAVE_CLIPBOARD_NBT_TO_DISK = true;
|
||||||
|
@Comment({
|
||||||
|
"Apply a file lock on the clipboard file (only relevant if clipboad.on-disk is enabled)",
|
||||||
|
" - Prevents other processes using the file whilst in use by FAWE",
|
||||||
|
" - This extends to other servers, useful if you have multiple servers using a unified clipboard folder",
|
||||||
|
" - May run into issues where a file lock is not correctly lifted"
|
||||||
|
})
|
||||||
|
public boolean LOCK_CLIPBOARD_FILE = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,12 +6,11 @@ import com.fastasyncworldedit.core.queue.IChunkGet;
|
|||||||
import com.fastasyncworldedit.core.queue.IChunkSet;
|
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||||
import com.fastasyncworldedit.core.regions.RegionWrapper;
|
import com.fastasyncworldedit.core.regions.RegionWrapper;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
public class HeightBoundExtent extends FaweRegionExtent {
|
public class HeightBoundExtent extends FaweRegionExtent {
|
||||||
|
|
||||||
@ -50,7 +49,8 @@ public class HeightBoundExtent extends FaweRegionExtent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||||
if (trimY(set, min, max, true) | trimNBT(set, this::contains)) {
|
BlockVector3 chunkPos = chunk.getChunkBlockCoord().withY(0);
|
||||||
|
if (trimY(set, min, max, true) | trimNBT(set, this::contains, pos -> this.contains(pos.add(chunkPos)))) {
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -305,22 +305,24 @@ public class DiskOptimizedClipboard extends LinearClipboard {
|
|||||||
private void init() throws IOException {
|
private void init() throws IOException {
|
||||||
if (this.fileChannel == null) {
|
if (this.fileChannel == null) {
|
||||||
this.fileChannel = braf.getChannel();
|
this.fileChannel = braf.getChannel();
|
||||||
try {
|
if (Settings.settings().CLIPBOARD.LOCK_CLIPBOARD_FILE) {
|
||||||
FileLock lock = this.fileChannel.lock();
|
try {
|
||||||
LOCK_HOLDER_CACHE.put(file.getName(), new LockHolder(lock));
|
FileLock lock = this.fileChannel.lock();
|
||||||
} catch (OverlappingFileLockException e) {
|
LOCK_HOLDER_CACHE.put(file.getName(), new LockHolder(lock));
|
||||||
LockHolder existing = LOCK_HOLDER_CACHE.get(file.getName());
|
} catch (OverlappingFileLockException e) {
|
||||||
if (existing != null) {
|
LockHolder existing = LOCK_HOLDER_CACHE.get(file.getName());
|
||||||
long ms = System.currentTimeMillis() - existing.lockHeldSince;
|
if (existing != null) {
|
||||||
LOGGER.error(
|
long ms = System.currentTimeMillis() - existing.lockHeldSince;
|
||||||
"Cannot lock clipboard file {} acquired by thread {}, {}ms ago",
|
LOGGER.error(
|
||||||
file.getName(),
|
"Cannot lock clipboard file {} acquired by thread {}, {}ms ago",
|
||||||
existing.thread,
|
file.getName(),
|
||||||
ms
|
existing.thread,
|
||||||
);
|
ms
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Rethrow to prevent clipboard access
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
// Rethrow to prevent clipboard access
|
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
this.byteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, braf.length());
|
this.byteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, braf.length());
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,9 @@ public interface IBatchProcessor {
|
|||||||
* Utility method to trim entity and blocks with a provided contains function.
|
* Utility method to trim entity and blocks with a provided contains function.
|
||||||
*
|
*
|
||||||
* @return false if chunk is empty of NBT
|
* @return false if chunk is empty of NBT
|
||||||
|
* @deprecated tiles are stored in chunk-normalised coordinate space and thus cannot use the same function as entities
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "2.8.4")
|
||||||
default boolean trimNBT(IChunkSet set, Function<BlockVector3, Boolean> contains) {
|
default boolean trimNBT(IChunkSet set, Function<BlockVector3, Boolean> contains) {
|
||||||
Set<CompoundTag> ents = set.getEntities();
|
Set<CompoundTag> ents = set.getEntities();
|
||||||
if (!ents.isEmpty()) {
|
if (!ents.isEmpty()) {
|
||||||
@ -169,6 +171,26 @@ public interface IBatchProcessor {
|
|||||||
return !tiles.isEmpty() || !ents.isEmpty();
|
return !tiles.isEmpty() || !ents.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility method to trim entity and blocks with a provided contains function.
|
||||||
|
*
|
||||||
|
* @return false if chunk is empty of NBT
|
||||||
|
* @since 2.8.4
|
||||||
|
*/
|
||||||
|
default boolean trimNBT(
|
||||||
|
IChunkSet set, Function<BlockVector3, Boolean> containsEntity, Function<BlockVector3, Boolean> containsTile
|
||||||
|
) {
|
||||||
|
Set<CompoundTag> ents = set.getEntities();
|
||||||
|
if (!ents.isEmpty()) {
|
||||||
|
ents.removeIf(ent -> !containsEntity.apply(ent.getEntityPosition().toBlockPoint()));
|
||||||
|
}
|
||||||
|
Map<BlockVector3, CompoundTag> tiles = set.getTiles();
|
||||||
|
if (!tiles.isEmpty()) {
|
||||||
|
tiles.entrySet().removeIf(blockVector3CompoundTagEntry -> !containsTile.apply(blockVector3CompoundTagEntry.getKey()));
|
||||||
|
}
|
||||||
|
return !tiles.isEmpty() || !ents.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Join two processors and return the result.
|
* Join two processors and return the result.
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.fastasyncworldedit.core.queue;
|
package com.fastasyncworldedit.core.queue;
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
|
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -33,6 +34,16 @@ public interface IChunk extends Trimable, IChunkGet, IChunkSet {
|
|||||||
*/
|
*/
|
||||||
int getZ();
|
int getZ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the minimum block coordinate of the chunk
|
||||||
|
*
|
||||||
|
* @return BlockVector3 of minimum block coordinate
|
||||||
|
* @since 2.8.4
|
||||||
|
*/
|
||||||
|
default BlockVector3 getChunkBlockCoord() {
|
||||||
|
return BlockVector3.at(getX() << 4, getMinY(), getZ() << 4);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the chunk is a delegate, returns its parent's root
|
* If the chunk is a delegate, returns its parent's root
|
||||||
*
|
*
|
||||||
|
@ -47,6 +47,7 @@ import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
|
|||||||
import com.sk89q.worldedit.command.util.Logging;
|
import com.sk89q.worldedit.command.util.Logging;
|
||||||
import com.sk89q.worldedit.command.util.annotation.Confirm;
|
import com.sk89q.worldedit.command.util.annotation.Confirm;
|
||||||
import com.sk89q.worldedit.command.util.annotation.Preload;
|
import com.sk89q.worldedit.command.util.annotation.Preload;
|
||||||
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
@ -70,6 +71,7 @@ import com.sk89q.worldedit.math.BlockVector3;
|
|||||||
import com.sk89q.worldedit.math.Vector3;
|
import com.sk89q.worldedit.math.Vector3;
|
||||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||||
import com.sk89q.worldedit.math.transform.Transform;
|
import com.sk89q.worldedit.math.transform.Transform;
|
||||||
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.regions.NullRegion;
|
import com.sk89q.worldedit.regions.NullRegion;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.regions.RegionIntersection;
|
import com.sk89q.worldedit.regions.RegionIntersection;
|
||||||
@ -351,7 +353,9 @@ public class ClipboardCommands {
|
|||||||
@Switch(name = 'e', desc = "Paste entities if available")
|
@Switch(name = 'e', desc = "Paste entities if available")
|
||||||
boolean pasteEntities,
|
boolean pasteEntities,
|
||||||
@Switch(name = 'b', desc = "Paste biomes if available")
|
@Switch(name = 'b', desc = "Paste biomes if available")
|
||||||
boolean pasteBiomes
|
boolean pasteBiomes,
|
||||||
|
@Switch(name = 'x', desc = "Remove existing entities in the affected region")
|
||||||
|
boolean removeEntities
|
||||||
) throws WorldEditException {
|
) throws WorldEditException {
|
||||||
ClipboardHolder holder = session.getClipboard();
|
ClipboardHolder holder = session.getClipboard();
|
||||||
final Clipboard clipboard = holder.getClipboard();
|
final Clipboard clipboard = holder.getClipboard();
|
||||||
@ -364,17 +368,22 @@ public class ClipboardCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Region region = clipboard.getRegion().clone();
|
Region region = clipboard.getRegion().clone();
|
||||||
if (selectPasted || onlySelect) {
|
if (selectPasted || onlySelect || removeEntities) {
|
||||||
BlockVector3 clipboardOffset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
|
BlockVector3 clipboardOffset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
|
||||||
BlockVector3 realTo = to.add(holder.getTransform().apply(clipboardOffset.toVector3()).toBlockPoint());
|
BlockVector3 realTo = to.add(holder.getTransform().apply(clipboardOffset.toVector3()).toBlockPoint());
|
||||||
BlockVector3 max = realTo.add(holder
|
BlockVector3 max = realTo.add(holder
|
||||||
.getTransform()
|
.getTransform()
|
||||||
.apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3())
|
.apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3())
|
||||||
.toBlockPoint());
|
.toBlockPoint());
|
||||||
RegionSelector selector = new CuboidRegionSelector(world, realTo, max);
|
if (removeEntities) {
|
||||||
session.setRegionSelector(world, selector);
|
editSession.getEntities(new CuboidRegion(realTo, max)).forEach(Entity::remove);
|
||||||
selector.learnChanges();
|
}
|
||||||
selector.explainRegionAdjust(actor, session);
|
if (selectPasted || onlySelect) {
|
||||||
|
RegionSelector selector = new CuboidRegionSelector(world, realTo, max);
|
||||||
|
session.setRegionSelector(world, selector);
|
||||||
|
selector.learnChanges();
|
||||||
|
selector.explainRegionAdjust(actor, session);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (onlySelect) {
|
if (onlySelect) {
|
||||||
actor.print(Caption.of("worldedit.paste.selected"));
|
actor.print(Caption.of("worldedit.paste.selected"));
|
||||||
@ -411,14 +420,19 @@ public class ClipboardCommands {
|
|||||||
boolean pasteBiomes,
|
boolean pasteBiomes,
|
||||||
@ArgFlag(name = 'm', desc = "Only paste blocks matching this mask")
|
@ArgFlag(name = 'm', desc = "Only paste blocks matching this mask")
|
||||||
@ClipboardMask
|
@ClipboardMask
|
||||||
Mask sourceMask
|
Mask sourceMask,
|
||||||
|
//FAWE start - entity removal
|
||||||
|
@Switch(name = 'x', desc = "Remove existing entities in the affected region")
|
||||||
|
boolean removeEntities
|
||||||
|
//FAWE end
|
||||||
|
|
||||||
) throws WorldEditException {
|
) throws WorldEditException {
|
||||||
|
|
||||||
ClipboardHolder holder = session.getClipboard();
|
ClipboardHolder holder = session.getClipboard();
|
||||||
//FAWE start - use place
|
//FAWE start - use place
|
||||||
if (holder.getTransform().isIdentity() && sourceMask == null) {
|
if (holder.getTransform().isIdentity() && sourceMask == null) {
|
||||||
place(actor, world, session, editSession, ignoreAirBlocks, atOrigin, selectPasted, onlySelect,
|
place(actor, world, session, editSession, ignoreAirBlocks, atOrigin, selectPasted, onlySelect,
|
||||||
pasteEntities, pasteBiomes
|
pasteEntities, pasteBiomes, removeEntities
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -445,21 +459,29 @@ public class ClipboardCommands {
|
|||||||
messages.addAll(Lists.newArrayList(operation.getStatusMessages()));
|
messages.addAll(Lists.newArrayList(operation.getStatusMessages()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectPasted || onlySelect) {
|
if (selectPasted || onlySelect || removeEntities) {
|
||||||
BlockVector3 clipboardOffset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
|
BlockVector3 clipboardOffset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
|
||||||
Vector3 realTo = to.toVector3().add(holder.getTransform().apply(clipboardOffset.toVector3()));
|
Vector3 realTo = to.toVector3().add(holder.getTransform().apply(clipboardOffset.toVector3()));
|
||||||
Vector3 max = realTo.add(holder
|
Vector3 max = realTo.add(holder
|
||||||
.getTransform()
|
.getTransform()
|
||||||
.apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3()));
|
.apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3()));
|
||||||
final CuboidRegionSelector selector;
|
|
||||||
if (session.getRegionSelector(world) instanceof ExtendingCuboidRegionSelector) {
|
// FAWE start - entity remova;l
|
||||||
selector = new ExtendingCuboidRegionSelector(world, realTo.toBlockPoint(), max.toBlockPoint());
|
if (removeEntities) {
|
||||||
} else {
|
editSession.getEntities(new CuboidRegion(realTo.toBlockPoint(), max.toBlockPoint())).forEach(Entity::remove);
|
||||||
selector = new CuboidRegionSelector(world, realTo.toBlockPoint(), max.toBlockPoint());
|
}
|
||||||
|
if (selectPasted || onlySelect) {
|
||||||
|
//FAWE end
|
||||||
|
final CuboidRegionSelector selector;
|
||||||
|
if (session.getRegionSelector(world) instanceof ExtendingCuboidRegionSelector) {
|
||||||
|
selector = new ExtendingCuboidRegionSelector(world, realTo.toBlockPoint(), max.toBlockPoint());
|
||||||
|
} else {
|
||||||
|
selector = new CuboidRegionSelector(world, realTo.toBlockPoint(), max.toBlockPoint());
|
||||||
|
}
|
||||||
|
session.setRegionSelector(world, selector);
|
||||||
|
selector.learnChanges();
|
||||||
|
selector.explainRegionAdjust(actor, session);
|
||||||
}
|
}
|
||||||
session.setRegionSelector(world, selector);
|
|
||||||
selector.learnChanges();
|
|
||||||
selector.explainRegionAdjust(actor, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onlySelect) {
|
if (onlySelect) {
|
||||||
|
@ -25,27 +25,34 @@ import com.fastasyncworldedit.core.extent.HistoryExtent;
|
|||||||
import com.fastasyncworldedit.core.extent.NullExtent;
|
import com.fastasyncworldedit.core.extent.NullExtent;
|
||||||
import com.fastasyncworldedit.core.history.changeset.AbstractChangeSet;
|
import com.fastasyncworldedit.core.history.changeset.AbstractChangeSet;
|
||||||
import com.fastasyncworldedit.core.internal.exception.FaweException;
|
import com.fastasyncworldedit.core.internal.exception.FaweException;
|
||||||
|
import com.fastasyncworldedit.core.queue.Filter;
|
||||||
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
import com.fastasyncworldedit.core.queue.IBatchProcessor;
|
||||||
import com.fastasyncworldedit.core.util.ExtentTraverser;
|
import com.fastasyncworldedit.core.util.ExtentTraverser;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
import com.sk89q.worldedit.entity.Entity;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
import com.sk89q.worldedit.extent.buffer.ForgetfulExtentBuffer;
|
import com.sk89q.worldedit.extent.buffer.ForgetfulExtentBuffer;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.operation.Operation;
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
import com.sk89q.worldedit.function.operation.OperationQueue;
|
import com.sk89q.worldedit.function.operation.OperationQueue;
|
||||||
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.util.Countable;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@ -168,6 +175,7 @@ public class AbstractDelegateExtent implements Extent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FAWE start
|
||||||
@Override
|
@Override
|
||||||
public boolean cancel() {
|
public boolean cancel() {
|
||||||
ExtentTraverser<Extent> traverser = new ExtentTraverser<>(this);
|
ExtentTraverser<Extent> traverser = new ExtentTraverser<>(this);
|
||||||
@ -188,7 +196,6 @@ public class AbstractDelegateExtent implements Extent {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//FAWE start
|
|
||||||
@Override
|
@Override
|
||||||
public void removeEntity(int x, int y, int z, UUID uuid) {
|
public void removeEntity(int x, int y, int z, UUID uuid) {
|
||||||
extent.removeEntity(x, y, z, uuid);
|
extent.removeEntity(x, y, z, uuid);
|
||||||
@ -225,11 +232,72 @@ public class AbstractDelegateExtent implements Extent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWorld() {
|
||||||
|
return extent.isWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Countable<BlockType>> getBlockDistribution(final Region region) {
|
||||||
|
return extent.getBlockDistribution(region);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Countable<BlockState>> getBlockDistributionWithData(final Region region) {
|
||||||
|
return extent.getBlockDistributionWithData(region);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxY() {
|
public int getMaxY() {
|
||||||
return extent.getMaxY();
|
return extent.getMaxY();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countBlocks(final Region region, final Set<BaseBlock> searchBlocks) {
|
||||||
|
return extent.countBlocks(region, searchBlocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countBlocks(final Region region, final Mask searchMask) {
|
||||||
|
return extent.countBlocks(region, searchMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <B extends BlockStateHolder<B>> int setBlocks(final Region region, final B block) throws MaxChangedBlocksException {
|
||||||
|
return extent.setBlocks(region, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int setBlocks(final Region region, final Pattern pattern) throws MaxChangedBlocksException {
|
||||||
|
return extent.setBlocks(region, pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <B extends BlockStateHolder<B>> int replaceBlocks(
|
||||||
|
final Region region,
|
||||||
|
final Set<BaseBlock> filter,
|
||||||
|
final B replacement
|
||||||
|
)
|
||||||
|
throws MaxChangedBlocksException {
|
||||||
|
return extent.replaceBlocks(region, filter, replacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int replaceBlocks(final Region region, final Set<BaseBlock> filter, final Pattern pattern) throws
|
||||||
|
MaxChangedBlocksException {
|
||||||
|
return extent.replaceBlocks(region, filter, pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int replaceBlocks(final Region region, final Mask mask, final Pattern pattern) throws MaxChangedBlocksException {
|
||||||
|
return extent.replaceBlocks(region, mask, pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int setBlocks(final Set<BlockVector3> vset, final Pattern pattern) {
|
||||||
|
return extent.setBlocks(vset, pattern);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinY() {
|
public int getMinY() {
|
||||||
return extent.getMinY();
|
return extent.getMinY();
|
||||||
@ -295,23 +363,29 @@ public class AbstractDelegateExtent implements Extent {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends Filter> T apply(final Region region, final T filter, final boolean full) {
|
||||||
|
return extent.apply(region, filter, full);
|
||||||
|
}
|
||||||
|
//FAWE end
|
||||||
|
|
||||||
protected Operation commitBefore() {
|
protected Operation commitBefore() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeType getBiome(BlockVector3 position) {
|
||||||
|
//FAWE start - switch top x,y,z
|
||||||
|
return extent.getBiomeType(position.getX(), position.getY(), position.getZ());
|
||||||
|
//FAWE end
|
||||||
|
}
|
||||||
|
|
||||||
|
//FAWE start
|
||||||
@Override
|
@Override
|
||||||
public BiomeType getBiomeType(int x, int y, int z) {
|
public BiomeType getBiomeType(int x, int y, int z) {
|
||||||
return extent.getBiomeType(x, y, z);
|
return extent.getBiomeType(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BiomeType getBiome(BlockVector3 position) {
|
|
||||||
return extent.getBiome(position);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
History
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getEmittedLight(int x, int y, int z) {
|
public int getEmittedLight(int x, int y, int z) {
|
||||||
return extent.getEmittedLight(x, y, z);
|
return extent.getEmittedLight(x, y, z);
|
||||||
@ -341,13 +415,17 @@ public class AbstractDelegateExtent implements Extent {
|
|||||||
new ExtentTraverser<>(this).setNext(new HistoryExtent(extent, changeSet));
|
new ExtentTraverser<>(this).setNext(new HistoryExtent(extent, changeSet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//FAWE end
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block)
|
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block)
|
||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
|
//FAWE start - switch to x,y,z
|
||||||
return extent.setBlock(position.getX(), position.getY(), position.getZ(), block);
|
return extent.setBlock(position.getX(), position.getY(), position.getZ(), block);
|
||||||
|
//FAWE end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FAWE start
|
||||||
@Override
|
@Override
|
||||||
public <T extends BlockStateHolder<T>> boolean setBlock(
|
public <T extends BlockStateHolder<T>> boolean setBlock(
|
||||||
int x, int y,
|
int x, int y,
|
||||||
@ -360,6 +438,7 @@ public class AbstractDelegateExtent implements Extent {
|
|||||||
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
|
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
|
||||||
return setBlock(x, y, z, getBlock(x, y, z).toBaseBlock(tile));
|
return setBlock(x, y, z, getBlock(x, y, z).toBaseBlock(tile));
|
||||||
}
|
}
|
||||||
|
//FAWE end
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean fullySupports3DBiomes() {
|
public boolean fullySupports3DBiomes() {
|
||||||
@ -367,13 +446,16 @@ public class AbstractDelegateExtent implements Extent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||||
return extent.setBiome(x, y, z, biome);
|
//FAWE start - switch to x,y,z
|
||||||
|
return extent.setBiome(position.getX(), position.getY(), position.getZ(), biome);
|
||||||
|
//FAWE end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FAWE start
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||||
return extent.setBiome(position.getX(), position.getY(), position.getZ(), biome);
|
return extent.setBiome(x, y, z, biome);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -22,7 +22,6 @@ package com.sk89q.worldedit.regions;
|
|||||||
import com.fastasyncworldedit.core.configuration.Settings;
|
import com.fastasyncworldedit.core.configuration.Settings;
|
||||||
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
|
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
|
||||||
import com.fastasyncworldedit.core.math.BlockVectorSet;
|
import com.fastasyncworldedit.core.math.BlockVectorSet;
|
||||||
import com.fastasyncworldedit.core.math.MutableBlockVector2;
|
|
||||||
import com.fastasyncworldedit.core.math.MutableBlockVector3;
|
import com.fastasyncworldedit.core.math.MutableBlockVector3;
|
||||||
import com.fastasyncworldedit.core.queue.Filter;
|
import com.fastasyncworldedit.core.queue.Filter;
|
||||||
import com.fastasyncworldedit.core.queue.IChunk;
|
import com.fastasyncworldedit.core.queue.IChunk;
|
||||||
@ -805,7 +804,8 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
|||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
trimY(set, minY, maxY, true);
|
trimY(set, minY, maxY, true);
|
||||||
trimNBT(set, this::contains);
|
BlockVector3 chunkPos = chunk.getChunkBlockCoord().withY(0);
|
||||||
|
trimNBT(set, this::contains, pos -> this.contains(pos.add(chunkPos)));
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
if (tx >= minX && bx <= maxX && tz >= minZ && bz <= maxZ) {
|
if (tx >= minX && bx <= maxX && tz >= minZ && bz <= maxZ) {
|
||||||
@ -868,8 +868,8 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
|||||||
}
|
}
|
||||||
set.setBlocks(layer, arr);
|
set.setBlocks(layer, arr);
|
||||||
}
|
}
|
||||||
|
final BlockVector3 chunkPos = BlockVector3.at(chunk.getX() << 4, 0, chunk.getZ() << 4);
|
||||||
trimNBT(set, this::contains);
|
trimNBT(set, this::contains, pos -> this.contains(pos.add(chunkPos)));
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -893,7 +893,8 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
trimY(set, minY, maxY, false);
|
trimY(set, minY, maxY, false);
|
||||||
trimNBT(set, this::contains);
|
BlockVector3 chunkPos = chunk.getChunkBlockCoord().withY(0);
|
||||||
|
trimNBT(set, this::contains, pos -> this.contains(pos.add(chunkPos)));
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
if (tx >= minX && bx <= maxX && tz >= minZ && bz <= maxZ) {
|
if (tx >= minX && bx <= maxX && tz >= minZ && bz <= maxZ) {
|
||||||
@ -943,7 +944,8 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
|||||||
}
|
}
|
||||||
set.setBlocks(layer, arr);
|
set.setBlocks(layer, arr);
|
||||||
}
|
}
|
||||||
trimNBT(set, bv3 -> !this.contains(bv3));
|
BlockVector3 chunkPos = chunk.getChunkBlockCoord().withY(0);
|
||||||
|
trimNBT(set, bv3 -> !this.contains(bv3), bv3 -> !this.contains(bv3.add(chunkPos)));
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
return set;
|
return set;
|
||||||
|
@ -425,7 +425,8 @@ public interface Region extends Iterable<BlockVector3>, Cloneable, IBatchProcess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (processExtra) {
|
if (processExtra) {
|
||||||
trimNBT(set, this::contains);
|
BlockVector3 chunkPos = chunk.getChunkBlockCoord().withY(0);
|
||||||
|
trimNBT(set, this::contains, pos -> this.contains(pos.add(chunkPos)));
|
||||||
}
|
}
|
||||||
return set;
|
return set;
|
||||||
} else {
|
} else {
|
||||||
@ -477,7 +478,8 @@ public interface Region extends Iterable<BlockVector3>, Cloneable, IBatchProcess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (processExtra) {
|
if (processExtra) {
|
||||||
trimNBT(set, bv3 -> !this.contains(bv3));
|
BlockVector3 chunkPos = chunk.getChunkBlockCoord().withY(0);
|
||||||
|
trimNBT(set, bv3 -> !this.contains(bv3), bv3 -> !this.contains(bv3.add(chunkPos)));
|
||||||
}
|
}
|
||||||
return set;
|
return set;
|
||||||
} else {
|
} else {
|
||||||
|
@ -178,9 +178,18 @@ public class BlockState implements BlockStateHolder<BlockState>, Pattern {
|
|||||||
String name = property.getName();
|
String name = property.getName();
|
||||||
|
|
||||||
charSequence.setSubstring(propStrStart + name.length() + 2, state.length() - 1);
|
charSequence.setSubstring(propStrStart + name.length() + 2, state.length() - 1);
|
||||||
int index = charSequence.length() <= 0 ? -1 : property.getIndexFor(charSequence);
|
try {
|
||||||
if (index != -1) {
|
int index = charSequence.length() <= 0 ? -1 : property.getIndexFor(charSequence);
|
||||||
return type.withPropertyId(index);
|
if (index != -1) {
|
||||||
|
return type.withPropertyId(index);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InputParseException(Caption.of(
|
||||||
|
"fawe.error.invalid-block-state-property",
|
||||||
|
TextComponent.of(charSequence.toString()),
|
||||||
|
TextComponent.of(name),
|
||||||
|
TextComponent.of(state)
|
||||||
|
), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int stateId;
|
int stateId;
|
||||||
@ -200,7 +209,17 @@ public class BlockState implements BlockStateHolder<BlockState>, Pattern {
|
|||||||
case ',': {
|
case ',': {
|
||||||
charSequence.setSubstring(last, i);
|
charSequence.setSubstring(last, i);
|
||||||
if (property != null) {
|
if (property != null) {
|
||||||
int index = property.getIndexFor(charSequence);
|
int index;
|
||||||
|
try {
|
||||||
|
index = property.getIndexFor(charSequence);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InputParseException(Caption.of(
|
||||||
|
"fawe.error.invalid-block-state-property",
|
||||||
|
TextComponent.of(charSequence.toString()),
|
||||||
|
TextComponent.of(property.getName()),
|
||||||
|
TextComponent.of(state)
|
||||||
|
), e);
|
||||||
|
}
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
throw SuggestInputParseException.of(charSequence.toString(), (List<Object>) property.getValues());
|
throw SuggestInputParseException.of(charSequence.toString(), (List<Object>) property.getValues());
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,7 @@
|
|||||||
"fawe.error.parser.invalid-data": "Invalid data: {0}",
|
"fawe.error.parser.invalid-data": "Invalid data: {0}",
|
||||||
"fawe.error.unsupported": "Unsupported!",
|
"fawe.error.unsupported": "Unsupported!",
|
||||||
"fawe.error.invalid-block-type": "Does not match a valid block type: {0}",
|
"fawe.error.invalid-block-type": "Does not match a valid block type: {0}",
|
||||||
|
"fawe.error.invalid-block-state-property": "Cannot parse value `{0}` for property `{1}`, block state: `{2}`",
|
||||||
"fawe.error.nbt.forbidden": "You are not allowed to use nbt. Lacking permission: {0}",
|
"fawe.error.nbt.forbidden": "You are not allowed to use nbt. Lacking permission: {0}",
|
||||||
"fawe.error.invalid-arguments": "Invalid amount of arguments. Expected: {0}",
|
"fawe.error.invalid-arguments": "Invalid amount of arguments. Expected: {0}",
|
||||||
"fawe.error.unrecognised-tag": "Unrecognised tag: {0} {1}",
|
"fawe.error.unrecognised-tag": "Unrecognised tag: {0} {1}",
|
||||||
|
Loading…
Reference in New Issue
Block a user