mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-04 03:56:41 +00:00
This commit is contained in:
@ -365,6 +365,18 @@ public class Fawe {
|
||||
Settings.settings().QUEUE.PARALLEL_THREADS
|
||||
);
|
||||
}
|
||||
if (Settings.settings().HISTORY.DELETE_DISK_ON_LOGOUT && Settings.settings().HISTORY.USE_DATABASE) {
|
||||
LOGGER.warn("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
LOGGER.warn("!!! !!!");
|
||||
LOGGER.warn("!!! Using history database whilst deleting disk history! !!!");
|
||||
LOGGER.warn("!!! You will not be able to rollback edits after a user logs !!!");
|
||||
LOGGER.warn("!!! out, recommended to disable delete-disk-on-logout if you !!!");
|
||||
LOGGER.warn("!!! you want to have full history rollback functionality. !!!");
|
||||
LOGGER.warn("!!! Disable use-database if you do not need to have rollback !!!");
|
||||
LOGGER.warn("!!! functionality and wish to disable this warning. !!!");
|
||||
LOGGER.warn("!!! !!!");
|
||||
LOGGER.warn("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
}
|
||||
try {
|
||||
byte[] in = new byte[0];
|
||||
byte[] compressed = LZ4Factory.fastestJavaInstance().fastCompressor().compress(in);
|
||||
|
@ -192,17 +192,22 @@ public enum FaweCache implements Trimable {
|
||||
Type.OUTSIDE_REGION
|
||||
);
|
||||
public static final FaweException MAX_CHECKS = new FaweException(
|
||||
Caption.of("fawe.cancel.reason.max" + ".checks"),
|
||||
Caption.of("fawe.cancel.reason.max.checks"),
|
||||
Type.MAX_CHECKS,
|
||||
true
|
||||
);
|
||||
public static final FaweException MAX_FAILS = new FaweException(
|
||||
Caption.of("fawe.cancel.reason.max.fails"),
|
||||
Type.MAX_CHECKS,
|
||||
true
|
||||
);
|
||||
public static final FaweException MAX_CHANGES = new FaweException(
|
||||
Caption.of("fawe.cancel.reason.max" + ".changes"),
|
||||
Caption.of("fawe.cancel.reason.max.changes"),
|
||||
Type.MAX_CHANGES,
|
||||
false
|
||||
);
|
||||
public static final FaweException LOW_MEMORY = new FaweException(
|
||||
Caption.of("fawe.cancel.reason.low" + ".memory"),
|
||||
Caption.of("fawe.cancel.reason.low.memory"),
|
||||
Type.LOW_MEMORY,
|
||||
false
|
||||
);
|
||||
|
@ -123,29 +123,31 @@ public class Settings extends Config {
|
||||
limit.MAX_ACTIONS,
|
||||
newLimit.MAX_ACTIONS != -1 ? newLimit.MAX_ACTIONS : Integer.MAX_VALUE
|
||||
);
|
||||
limit.MAX_CHANGES = Math.max(
|
||||
limit.MAX_CHANGES,
|
||||
limit.MAX_CHANGES.set(Math.max(
|
||||
limit.MAX_CHANGES.get(),
|
||||
newLimit.MAX_CHANGES != -1 ? newLimit.MAX_CHANGES : Long.MAX_VALUE
|
||||
);
|
||||
limit.MAX_BLOCKSTATES = Math.max(
|
||||
limit.MAX_BLOCKSTATES,
|
||||
));
|
||||
limit.MAX_BLOCKSTATES.set(Math.max(
|
||||
limit.MAX_BLOCKSTATES.get(),
|
||||
newLimit.MAX_BLOCKSTATES != -1 ? newLimit.MAX_BLOCKSTATES : Integer.MAX_VALUE
|
||||
);
|
||||
limit.MAX_CHECKS = Math.max(
|
||||
limit.MAX_CHECKS,
|
||||
));
|
||||
limit.MAX_CHECKS.set(Math.max(
|
||||
limit.MAX_CHECKS.get(),
|
||||
newLimit.MAX_CHECKS != -1 ? newLimit.MAX_CHECKS : Long.MAX_VALUE
|
||||
);
|
||||
limit.MAX_ENTITIES = Math.max(
|
||||
limit.MAX_ENTITIES,
|
||||
));
|
||||
limit.MAX_ENTITIES.set(Math.max(
|
||||
limit.MAX_ENTITIES.get(),
|
||||
newLimit.MAX_ENTITIES != -1 ? newLimit.MAX_ENTITIES : Integer.MAX_VALUE
|
||||
);
|
||||
limit.MAX_FAILS = Math.max(limit.MAX_FAILS, newLimit.MAX_FAILS != -1 ? newLimit.MAX_FAILS : Integer.MAX_VALUE);
|
||||
limit.MAX_ITERATIONS = Math.max(
|
||||
limit.MAX_ITERATIONS, newLimit.MAX_ITERATIONS != -1 ? newLimit.MAX_ITERATIONS : Integer.MAX_VALUE);
|
||||
limit.MAX_RADIUS = Math.max(
|
||||
limit.MAX_RADIUS,
|
||||
newLimit.MAX_RADIUS != -1 ? newLimit.MAX_RADIUS : Integer.MAX_VALUE
|
||||
);
|
||||
));
|
||||
limit.MAX_FAILS.set(Math.max(
|
||||
limit.MAX_FAILS.get(),
|
||||
newLimit.MAX_FAILS != -1 ? newLimit.MAX_FAILS : Integer.MAX_VALUE
|
||||
));
|
||||
limit.MAX_ITERATIONS.set(Math.max(
|
||||
limit.MAX_ITERATIONS.get(),
|
||||
newLimit.MAX_ITERATIONS != -1 ? newLimit.MAX_ITERATIONS : Integer.MAX_VALUE
|
||||
));
|
||||
limit.MAX_RADIUS = Math.max(limit.MAX_RADIUS, newLimit.MAX_RADIUS != -1 ? newLimit.MAX_RADIUS : Integer.MAX_VALUE);
|
||||
limit.MAX_SUPER_PICKAXE_SIZE = Math.max(
|
||||
limit.MAX_SUPER_PICKAXE_SIZE,
|
||||
newLimit.MAX_SUPER_PICKAXE_SIZE != -1 ? newLimit.MAX_SUPER_PICKAXE_SIZE : Integer.MAX_VALUE
|
||||
@ -622,6 +624,13 @@ public class Settings extends Config {
|
||||
})
|
||||
public static class EXPERIMENTAL {
|
||||
|
||||
@Comment({
|
||||
"Undo operation batch size",
|
||||
" - The size defines the number of changes read at once.",
|
||||
" - Larger numbers might reduce overhead but increase latency for edits with only few changes.",
|
||||
" - 0 means undo operations are not batched."})
|
||||
public int UNDO_BATCH_SIZE = 128;
|
||||
|
||||
@Comment({
|
||||
"[UNSAFE] Directly modify the region files. (OBSOLETE - USE ANVIL COMMANDS)",
|
||||
" - IMPROPER USE CAN CAUSE WORLD CORRUPTION!",
|
||||
@ -668,6 +677,11 @@ public class Settings extends Config {
|
||||
})
|
||||
public boolean ALLOW_TICK_FLUIDS = false;
|
||||
|
||||
@Comment({
|
||||
"Whether FAWE should use the incubator Vector API to accelerate some operations"
|
||||
})
|
||||
public boolean USE_VECTOR_API = false;
|
||||
|
||||
}
|
||||
|
||||
@Comment({"Web/HTTP connection related settings"})
|
||||
|
@ -19,9 +19,9 @@ public class AdjacentMaskParser extends RichParser<Mask> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0) {
|
||||
return worldEdit.getMaskFactory().getSuggestions(argumentInput).stream();
|
||||
return worldEdit.getMaskFactory().getSuggestions(argumentInput, context).stream();
|
||||
} else if (index == 1 || index == 2) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public class AngleMaskParser extends RichParser<Mask> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0 || index == 1) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput).flatMap(s -> Stream.of(s, s + "d"));
|
||||
} else if (index > 1 && index <= 1 + flags.length) {
|
||||
|
@ -18,9 +18,9 @@ public class BesideMaskParser extends RichParser<Mask> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(final String argumentInput, final int index) {
|
||||
protected Stream<String> getSuggestions(final String argumentInput, final int index, ParserContext context) {
|
||||
if (index == 0) {
|
||||
return worldEdit.getMaskFactory().getSuggestions(argumentInput).stream();
|
||||
return worldEdit.getMaskFactory().getSuggestions(argumentInput, context).stream();
|
||||
} else if (index == 1 || index == 2) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public class ExtremaMaskParser extends RichParser<Mask> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0 || index == 1) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput).flatMap(s -> Stream.of(s, s + "d"));
|
||||
} else if (index > 1 && index <= 1 + flags.length) {
|
||||
|
@ -22,7 +22,7 @@ public class ROCAngleMaskParser extends RichParser<Mask> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0 || index == 1) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput).flatMap(s -> Stream.of(s, s + "d"));
|
||||
} else if (index > 1 && index <= 1 + flags.length) {
|
||||
|
@ -18,7 +18,7 @@ public class RadiusMaskParser extends RichParser<Mask> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0 || index == 1) {
|
||||
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
|
||||
}
|
||||
|
@ -24,12 +24,12 @@ public class RichOffsetMaskParser extends RichParser<Mask> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index < 3) {
|
||||
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
|
||||
}
|
||||
if (index == 3) {
|
||||
return worldEdit.getMaskFactory().getSuggestions(argumentInput).stream();
|
||||
return worldEdit.getMaskFactory().getSuggestions(argumentInput, context).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ public class SimplexMaskParser extends RichParser<Mask> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index < 3) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ public class SurfaceAngleMaskParser extends RichParser<Mask> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index <= 2) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class AngleColorPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
public Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index != 0) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class AverageColorPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
public Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index > 4) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class BiomePatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0) {
|
||||
return BiomeType.REGISTRY.getSuggestions(argumentInput);
|
||||
}
|
||||
|
@ -26,9 +26,9 @@ public class BufferedPattern2DParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0) {
|
||||
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -26,9 +26,9 @@ public class BufferedPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0) {
|
||||
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public class ColorPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
public Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index > 4) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class DesaturatePatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
public Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
|
||||
}
|
||||
|
@ -28,9 +28,9 @@ public class Linear2DPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
return switch (index) {
|
||||
case 0 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
case 0 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
case 1, 2 -> SuggestionHelper.suggestPositiveIntegers(argumentInput);
|
||||
default -> Stream.empty();
|
||||
};
|
||||
|
@ -28,9 +28,9 @@ public class Linear3DPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
return switch (index) {
|
||||
case 0 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
case 0 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
case 1, 2, 3 -> SuggestionHelper.suggestPositiveIntegers(argumentInput);
|
||||
default -> Stream.empty();
|
||||
};
|
||||
|
@ -28,9 +28,9 @@ public class LinearPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
return switch (index) {
|
||||
case 0 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
case 0 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
case 1, 2, 3 -> SuggestionHelper.suggestPositiveIntegers(argumentInput);
|
||||
default -> Stream.empty();
|
||||
};
|
||||
|
@ -25,10 +25,10 @@ public class MaskedPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
return switch (index) {
|
||||
case 0 -> this.worldEdit.getMaskFactory().getSuggestions(argumentInput).stream();
|
||||
case 1, 2 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
case 0 -> this.worldEdit.getMaskFactory().getSuggestions(argumentInput, context).stream();
|
||||
case 1, 2 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
default -> Stream.empty();
|
||||
};
|
||||
}
|
||||
|
@ -24,9 +24,9 @@ public class NoXPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
public Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0) {
|
||||
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -24,9 +24,9 @@ public class NoYPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
public Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0) {
|
||||
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -24,9 +24,9 @@ public class NoZPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
public Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0) {
|
||||
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -36,12 +36,12 @@ public abstract class NoisePatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
|
||||
}
|
||||
if (index == 1) {
|
||||
return worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
return worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -25,9 +25,9 @@ public class OffsetPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
return switch (index) {
|
||||
case 0 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
case 0 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
case 1, 2, 3 -> SuggestionHelper.suggestPositiveIntegers(argumentInput);
|
||||
default -> Stream.empty();
|
||||
};
|
||||
|
@ -4,6 +4,7 @@ import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.MultiClipboardHolder;
|
||||
import com.fastasyncworldedit.core.function.pattern.RandomFullClipboardPattern;
|
||||
import com.google.common.base.Function;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
@ -33,7 +34,7 @@ public class RandomFullClipboardPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
if (argumentInput.equals("#") || argumentInput.equals("#c")) {
|
||||
|
@ -25,9 +25,9 @@ public class RandomOffsetPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
return switch (index) {
|
||||
case 0 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
case 0 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
case 1, 2, 3 -> SuggestionHelper.suggestPositiveIntegers(argumentInput);
|
||||
default -> Stream.empty();
|
||||
};
|
||||
|
@ -24,9 +24,9 @@ public class RelativePatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
public Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0) {
|
||||
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class SaturatePatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
public Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index > 3) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -25,9 +25,9 @@ public class SolidRandomOffsetPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
return switch (index) {
|
||||
case 0 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
case 0 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
case 1, 2, 3 -> SuggestionHelper.suggestPositiveIntegers(argumentInput);
|
||||
default -> Stream.empty();
|
||||
};
|
||||
|
@ -25,9 +25,9 @@ public class SurfaceRandomOffsetPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
return switch (index) {
|
||||
case 0 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
case 0 -> this.worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
case 1 -> SuggestionHelper.suggestPositiveIntegers(argumentInput);
|
||||
default -> Stream.empty();
|
||||
};
|
||||
|
@ -28,7 +28,7 @@ public class TypeSwapPatternParser extends RichParser<Pattern> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
public Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index > 2) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -23,9 +23,9 @@ public class Linear3DTransformParser extends RichParser<ResettableExtent> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0) {
|
||||
return worldEdit.getTransformFactory().getSuggestions(argumentInput).stream();
|
||||
return worldEdit.getTransformFactory().getSuggestions(argumentInput, context).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -23,9 +23,9 @@ public class LinearTransformParser extends RichParser<ResettableExtent> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0) {
|
||||
return worldEdit.getTransformFactory().getSuggestions(argumentInput).stream();
|
||||
return worldEdit.getTransformFactory().getSuggestions(argumentInput, context).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -26,11 +26,11 @@ public class OffsetTransformParser extends RichParser<ResettableExtent> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index < 3) {
|
||||
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
|
||||
} else if (index == 3) {
|
||||
return worldEdit.getTransformFactory().getSuggestions(argumentInput).stream();
|
||||
return worldEdit.getTransformFactory().getSuggestions(argumentInput, context).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -24,11 +24,11 @@ public class PatternTransformParser extends RichParser<ResettableExtent> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index == 0) {
|
||||
return worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
return worldEdit.getPatternFactory().getSuggestions(argumentInput, context).stream();
|
||||
} else if (index == 1) {
|
||||
return worldEdit.getTransformFactory().getSuggestions(argumentInput).stream();
|
||||
return worldEdit.getTransformFactory().getSuggestions(argumentInput, context).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -25,12 +25,12 @@ public class RotateTransformParser extends RichParser<ResettableExtent> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index < 3) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
|
||||
}
|
||||
if (index == 3) {
|
||||
return worldEdit.getTransformFactory().getSuggestions(argumentInput).stream();
|
||||
return worldEdit.getTransformFactory().getSuggestions(argumentInput, context).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -24,11 +24,11 @@ public class ScaleTransformParser extends RichParser<ResettableExtent> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index < 3) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
|
||||
} else if (index == 3) {
|
||||
return worldEdit.getTransformFactory().getSuggestions(argumentInput).stream();
|
||||
return worldEdit.getTransformFactory().getSuggestions(argumentInput, context).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -24,11 +24,11 @@ public class SpreadTransformParser extends RichParser<ResettableExtent> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index, ParserContext context) {
|
||||
if (index < 3) {
|
||||
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
|
||||
} else if (index == 3) {
|
||||
return worldEdit.getTransformFactory().getSuggestions(argumentInput).stream();
|
||||
return worldEdit.getTransformFactory().getSuggestions(argumentInput, context).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package com.fastasyncworldedit.core.extension.platform.binding;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
|
||||
public record EditSessionHolder(EditSession session) {
|
||||
|
||||
}
|
@ -3,7 +3,11 @@ package com.fastasyncworldedit.core.extension.platform.binding;
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.database.DBHandler;
|
||||
import com.fastasyncworldedit.core.database.RollbackDatabase;
|
||||
import com.fastasyncworldedit.core.extent.LimitExtent;
|
||||
import com.fastasyncworldedit.core.extent.processor.ExtentBatchProcessorHolder;
|
||||
import com.fastasyncworldedit.core.internal.exception.FaweException;
|
||||
import com.fastasyncworldedit.core.regions.FaweMaskManager;
|
||||
import com.fastasyncworldedit.core.util.ExtentTraverser;
|
||||
import com.fastasyncworldedit.core.util.TextureUtil;
|
||||
import com.fastasyncworldedit.core.util.image.ImageUtil;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
@ -11,6 +15,7 @@ import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.argument.Arguments;
|
||||
import com.sk89q.worldedit.command.util.annotation.AllowedRegion;
|
||||
import com.sk89q.worldedit.command.util.annotation.SynchronousSettingExpected;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
@ -25,6 +30,7 @@ import org.enginehub.piston.inject.Key;
|
||||
import org.enginehub.piston.util.ValueProvider;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.util.Optional;
|
||||
|
||||
@ -52,11 +58,33 @@ public class ProvideBindings extends Bindings {
|
||||
|
||||
@Binding
|
||||
public EditSession editSession(LocalSession localSession, Actor actor, InjectedValueAccess context) {
|
||||
Method commandMethod =
|
||||
context.injectedValue(Key.of(InjectedValueStore.class)).get().injectedValue(Key.of(Method.class)).get();
|
||||
|
||||
Arguments arguments = context.injectedValue(Key.of(Arguments.class)).orElse(null);
|
||||
String command = arguments == null ? null : arguments.get();
|
||||
EditSession editSession = localSession.createEditSession(actor, command);
|
||||
editSession.enableStandardMode();
|
||||
Request.request().setEditSession(editSession);
|
||||
boolean synchronousSetting = commandMethod.getAnnotation(SynchronousSettingExpected.class) != null;
|
||||
EditSessionHolder holder = context.injectedValue(Key.of(EditSessionHolder.class)).orElse(null);
|
||||
EditSession editSession = holder != null ? holder.session() : null;
|
||||
if (editSession == null) {
|
||||
editSession = localSession.createEditSession(actor, command);
|
||||
editSession.enableStandardMode();
|
||||
} else {
|
||||
LimitExtent limitExtent = new ExtentTraverser<>(editSession).findAndGet(LimitExtent.class);
|
||||
if (limitExtent != null) {
|
||||
limitExtent.setProcessing(!synchronousSetting);
|
||||
if (!synchronousSetting) {
|
||||
ExtentBatchProcessorHolder processorHolder = new ExtentTraverser<>(editSession).findAndGet(
|
||||
ExtentBatchProcessorHolder.class);
|
||||
if (processorHolder != null) {
|
||||
processorHolder.addProcessor(limitExtent);
|
||||
} else {
|
||||
throw new FaweException(Caption.of("fawe.error.no-process-non-synchronous-edit"));
|
||||
}
|
||||
}
|
||||
}
|
||||
Request.request().setEditSession(editSession);
|
||||
}
|
||||
return editSession;
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package com.fastasyncworldedit.core.extent;
|
||||
|
||||
import com.fastasyncworldedit.core.history.changeset.AbstractChangeSet;
|
||||
import com.fastasyncworldedit.core.math.MutableBlockVector3;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
@ -74,7 +75,7 @@ public class HistoryExtent extends AbstractDelegateExtent {
|
||||
public Entity createEntity(Location location, BaseEntity state) {
|
||||
final Entity entity = super.createEntity(location, state);
|
||||
if (state != null) {
|
||||
this.changeSet.addEntityCreate(state.getNbtData());
|
||||
this.changeSet.addEntityCreate(FaweCompoundTag.of(state.getNbt()));
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
@ -84,7 +85,7 @@ public class HistoryExtent extends AbstractDelegateExtent {
|
||||
public Entity createEntity(Location location, BaseEntity state, UUID uuid) {
|
||||
final Entity entity = super.createEntity(location, state, uuid);
|
||||
if (state != null) {
|
||||
this.changeSet.addEntityCreate(state.getNbtData());
|
||||
this.changeSet.addEntityCreate(FaweCompoundTag.of(state.getNbt()));
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
@ -154,11 +155,10 @@ public class HistoryExtent extends AbstractDelegateExtent {
|
||||
|
||||
@Override
|
||||
public boolean remove() {
|
||||
final Location location = this.entity.getLocation();
|
||||
final BaseEntity state = this.entity.getState();
|
||||
final boolean success = this.entity.remove();
|
||||
if (state != null && success) {
|
||||
HistoryExtent.this.changeSet.addEntityRemove(state.getNbtData());
|
||||
HistoryExtent.this.changeSet.addEntityRemove(FaweCompoundTag.of(state.getNbt()));
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -1,11 +1,15 @@
|
||||
package com.fastasyncworldedit.core.extent;
|
||||
|
||||
import com.fastasyncworldedit.core.extent.filter.block.ExtentFilterBlock;
|
||||
import com.fastasyncworldedit.core.function.generator.GenBase;
|
||||
import com.fastasyncworldedit.core.function.generator.Resource;
|
||||
import com.fastasyncworldedit.core.extent.processor.ProcessorScope;
|
||||
import com.fastasyncworldedit.core.internal.exception.FaweException;
|
||||
import com.fastasyncworldedit.core.limit.FaweLimit;
|
||||
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.util.ExtentTraverser;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
@ -17,7 +21,6 @@ import com.sk89q.worldedit.function.mask.Mask;
|
||||
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.util.Location;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
@ -37,18 +40,22 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class LimitExtent extends AbstractDelegateExtent {
|
||||
public class LimitExtent extends AbstractDelegateExtent implements IBatchProcessor {
|
||||
|
||||
private final FaweLimit limit;
|
||||
private final boolean[] faweExceptionReasonsUsed = new boolean[FaweException.Type.values().length];
|
||||
private final Consumer<Component> onErrorMessage;
|
||||
private final int chunk_size;
|
||||
private boolean processing;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param extent the extent
|
||||
* @param limit the limit
|
||||
* @deprecated Use {@link LimitExtent#LimitExtent(Extent, FaweLimit, Consumer, boolean)}
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "TODO")
|
||||
public LimitExtent(Extent extent, FaweLimit limit) {
|
||||
this(extent, limit, c -> {
|
||||
});
|
||||
@ -60,11 +67,33 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
* @param extent the extent
|
||||
* @param limit the limit
|
||||
* @param onErrorMessage consumer to handle a component generated by exceptions
|
||||
* @deprecated Use {@link LimitExtent#LimitExtent(Extent, FaweLimit, Consumer, boolean)}
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "TODO")
|
||||
public LimitExtent(Extent extent, FaweLimit limit, Consumer<Component> onErrorMessage) {
|
||||
this(extent, limit, onErrorMessage, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param extent the extent
|
||||
* @param limit the limit
|
||||
* @param onErrorMessage consumer to handle a component generated by exceptions
|
||||
* @param processing if this limit extent is expected to be processing
|
||||
* @since TODO
|
||||
*/
|
||||
public LimitExtent(
|
||||
Extent extent,
|
||||
FaweLimit limit,
|
||||
Consumer<Component> onErrorMessage,
|
||||
boolean processing
|
||||
) {
|
||||
super(extent);
|
||||
this.limit = limit;
|
||||
this.onErrorMessage = onErrorMessage;
|
||||
this.chunk_size = 16 * 16 * (extent.getMaxY() - extent.getMinY());
|
||||
this.processing = processing;
|
||||
}
|
||||
|
||||
private void handleException(FaweException e) {
|
||||
@ -81,7 +110,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public List<? extends Entity> getEntities(Region region) {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
try {
|
||||
return super.getEntities(region);
|
||||
return extent.getEntities(region);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return Collections.emptyList();
|
||||
@ -92,7 +121,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public List<? extends Entity> getEntities() {
|
||||
limit.THROW_MAX_CHECKS();
|
||||
try {
|
||||
return super.getEntities();
|
||||
return extent.getEntities();
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return Collections.emptyList();
|
||||
@ -105,7 +134,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
limit.THROW_MAX_CHANGES();
|
||||
limit.THROW_MAX_ENTITIES();
|
||||
try {
|
||||
return super.createEntity(location, entity);
|
||||
return extent.createEntity(location, entity);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return null;
|
||||
@ -118,7 +147,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
limit.THROW_MAX_CHANGES();
|
||||
limit.THROW_MAX_ENTITIES();
|
||||
try {
|
||||
return super.createEntity(location, entity, uuid);
|
||||
return extent.createEntity(location, entity, uuid);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return null;
|
||||
@ -130,7 +159,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
limit.THROW_MAX_CHANGES();
|
||||
limit.THROW_MAX_ENTITIES();
|
||||
try {
|
||||
super.removeEntity(x, y, z, uuid);
|
||||
extent.removeEntity(x, y, z, uuid);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
}
|
||||
@ -138,9 +167,9 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
|
||||
@Override
|
||||
public boolean regenerateChunk(int x, int z, @Nullable BiomeType type, @Nullable Long seed) {
|
||||
limit.THROW_MAX_CHANGES(Character.MAX_VALUE);
|
||||
limit.THROW_MAX_CHANGES(chunk_size);
|
||||
try {
|
||||
return super.regenerateChunk(x, z, type, seed);
|
||||
return extent.regenerateChunk(x, z, type, seed);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return false;
|
||||
@ -151,7 +180,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public int getHighestTerrainBlock(int x, int z, int minY, int maxY) {
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getHighestTerrainBlock(x, z, minY, maxY);
|
||||
return extent.getHighestTerrainBlock(x, z, minY, maxY);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return minY;
|
||||
@ -162,7 +191,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public int getHighestTerrainBlock(int x, int z, int minY, int maxY, Mask filter) {
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getHighestTerrainBlock(x, z, minY, maxY, filter);
|
||||
return extent.getHighestTerrainBlock(x, z, minY, maxY, filter);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return minY;
|
||||
@ -173,7 +202,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) {
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getNearestSurfaceLayer(x, z, y, minY, maxY);
|
||||
return extent.getNearestSurfaceLayer(x, z, y, minY, maxY);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return minY;
|
||||
@ -184,7 +213,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, boolean ignoreAir) {
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, ignoreAir);
|
||||
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, ignoreAir);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return minY;
|
||||
@ -195,7 +224,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) {
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY);
|
||||
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return minY;
|
||||
@ -206,7 +235,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax) {
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax);
|
||||
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return minY;
|
||||
@ -217,7 +246,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, Mask mask) {
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, mask);
|
||||
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, mask);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return minY;
|
||||
@ -237,91 +266,47 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
) {
|
||||
limit.THROW_MAX_CHECKS(maxY - minY + 1);
|
||||
try {
|
||||
return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, ignoreAir);
|
||||
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, ignoreAir);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return minY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCaves(Region region) throws WorldEditException {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
super.addCaves(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(Region region, GenBase gen) throws WorldEditException {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
super.generate(region, gen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSchems(Region region, Mask mask, List<ClipboardHolder> clipboards, int rarity, boolean rotate) throws
|
||||
WorldEditException {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
super.addSchems(region, mask, clipboards, rarity, rotate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnResource(Region region, Resource gen, int rarity, int frequency) throws WorldEditException {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
super.spawnResource(region, gen, rarity, frequency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOre(Region region, Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws
|
||||
WorldEditException {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
super.addOre(region, mask, material, size, frequency, rarity, minY, maxY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOres(Region region, Mask mask) throws WorldEditException {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
super.addOres(region, mask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Countable<BlockType>> getBlockDistribution(Region region) {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
return super.getBlockDistribution(region);
|
||||
return extent.getBlockDistribution(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Countable<BlockState>> getBlockDistributionWithData(Region region) {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
return super.getBlockDistributionWithData(region);
|
||||
return extent.getBlockDistributionWithData(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countBlocks(Region region, Set<BaseBlock> searchBlocks) {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
return super.countBlocks(region, searchBlocks);
|
||||
return extent.countBlocks(region, searchBlocks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countBlocks(Region region, Mask searchMask) {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
return super.countBlocks(region, searchMask);
|
||||
return extent.countBlocks(region, searchMask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> int setBlocks(Region region, B block) throws MaxChangedBlocksException {
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
return super.setBlocks(region, block);
|
||||
return extent.setBlocks(region, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
return super.setBlocks(region, pattern);
|
||||
return extent.setBlocks(region, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -329,41 +314,34 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
MaxChangedBlocksException {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
return super.replaceBlocks(region, filter, replacement);
|
||||
return extent.replaceBlocks(region, filter, replacement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int replaceBlocks(Region region, Set<BaseBlock> filter, Pattern pattern) throws MaxChangedBlocksException {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
return super.replaceBlocks(region, filter, pattern);
|
||||
return extent.replaceBlocks(region, filter, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
return super.replaceBlocks(region, mask, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int center(Region region, Pattern pattern) throws MaxChangedBlocksException {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
return super.center(region, pattern);
|
||||
return extent.replaceBlocks(region, mask, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setBlocks(Set<BlockVector3> vset, Pattern pattern) {
|
||||
limit.THROW_MAX_CHANGES(vset.size());
|
||||
return super.setBlocks(vset, pattern);
|
||||
return extent.setBlocks(vset, pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Filter> T apply(Region region, T filter, boolean full) {
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
return super.apply(region, filter, full);
|
||||
return extent.apply(region, filter, full);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -393,14 +371,14 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
}
|
||||
limit.THROW_MAX_CHECKS(size);
|
||||
limit.THROW_MAX_CHANGES(size);
|
||||
return super.apply(positions, filter);
|
||||
return extent.apply(positions, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
limit.THROW_MAX_CHECKS();
|
||||
try {
|
||||
return super.getBlock(position);
|
||||
return extent.getBlock(position);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return BlockTypes.AIR.getDefaultState();
|
||||
@ -411,7 +389,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public BlockState getBlock(int x, int y, int z) {
|
||||
limit.THROW_MAX_CHECKS();
|
||||
try {
|
||||
return super.getBlock(x, y, z);
|
||||
return extent.getBlock(x, y, z);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return BlockTypes.AIR.getDefaultState();
|
||||
@ -422,7 +400,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
limit.THROW_MAX_CHECKS();
|
||||
try {
|
||||
return super.getFullBlock(position);
|
||||
return extent.getFullBlock(position);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return BlockTypes.AIR.getDefaultState().toBaseBlock();
|
||||
@ -433,7 +411,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||
limit.THROW_MAX_CHECKS();
|
||||
try {
|
||||
return super.getFullBlock(x, y, z);
|
||||
return extent.getFullBlock(x, y, z);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return BlockTypes.AIR.getDefaultState().toBaseBlock();
|
||||
@ -444,7 +422,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public BiomeType getBiome(BlockVector3 position) {
|
||||
limit.THROW_MAX_CHECKS();
|
||||
try {
|
||||
return super.getBiome(position);
|
||||
return extent.getBiome(position);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return BiomeTypes.FOREST;
|
||||
@ -455,7 +433,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public BiomeType getBiomeType(int x, int y, int z) {
|
||||
limit.THROW_MAX_CHECKS();
|
||||
try {
|
||||
return super.getBiomeType(x, y, z);
|
||||
return extent.getBiomeType(x, y, z);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return BiomeTypes.FOREST;
|
||||
@ -470,7 +448,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
limit.THROW_MAX_BLOCKSTATES();
|
||||
}
|
||||
try {
|
||||
return super.setBlock(position, block);
|
||||
return extent.setBlock(position, block);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return false;
|
||||
@ -484,7 +462,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
limit.THROW_MAX_BLOCKSTATES();
|
||||
}
|
||||
try {
|
||||
return super.setBlock(x, y, z, block);
|
||||
return extent.setBlock(x, y, z, block);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return false;
|
||||
@ -494,9 +472,9 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
|
||||
limit.THROW_MAX_CHANGES();
|
||||
limit.MAX_BLOCKSTATES();
|
||||
limit.THROW_MAX_BLOCKSTATES();
|
||||
try {
|
||||
return super.setTile(x, y, z, tile);
|
||||
return extent.setTile(x, y, z, tile);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return false;
|
||||
@ -507,7 +485,7 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||
limit.THROW_MAX_CHANGES();
|
||||
try {
|
||||
return super.setBiome(position, biome);
|
||||
return extent.setBiome(position, biome);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return false;
|
||||
@ -518,11 +496,41 @@ public class LimitExtent extends AbstractDelegateExtent {
|
||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||
limit.THROW_MAX_CHANGES();
|
||||
try {
|
||||
return super.setBiome(x, y, z, biome);
|
||||
return extent.setBiome(x, y, z, biome);
|
||||
} catch (FaweException e) {
|
||||
handleException(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setProcessing(boolean processing) {
|
||||
this.processing = processing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||
if (!processing) {
|
||||
return set;
|
||||
}
|
||||
int tiles = set.tiles().size();
|
||||
int ents = set.entities().size() + set.getEntityRemoves().size();
|
||||
limit.THROW_MAX_CHANGES(tiles + ents);
|
||||
limit.THROW_MAX_BLOCKSTATES(tiles);
|
||||
limit.THROW_MAX_ENTITIES(ents);
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Extent construct(final Extent child) {
|
||||
if (extent != child) {
|
||||
new ExtentTraverser<Extent>(this).setNext(child);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessorScope getScope() {
|
||||
return ProcessorScope.READING_SET_BLOCKS;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,14 +2,12 @@ package com.fastasyncworldedit.core.extent;
|
||||
|
||||
import com.fastasyncworldedit.core.extent.processor.ProcessorScope;
|
||||
import com.fastasyncworldedit.core.math.BlockVector3ChunkMap;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
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.util.ExtentTraverser;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
@ -20,16 +18,17 @@ import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.NbtValued;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import org.enginehub.linbus.tree.LinCompoundTag;
|
||||
import org.enginehub.linbus.tree.LinTag;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class StripNBTExtent extends AbstractDelegateExtent implements IBatchProcessor {
|
||||
@ -75,79 +74,82 @@ public class StripNBTExtent extends AbstractDelegateExtent implements IBatchProc
|
||||
if (!(block instanceof BaseBlock localBlock)) {
|
||||
return block;
|
||||
}
|
||||
if (!localBlock.hasNbtData()) {
|
||||
final LinCompoundTag nbt = localBlock.getNbt();
|
||||
if (nbt == null) {
|
||||
return block;
|
||||
}
|
||||
CompoundTag nbt = localBlock.getNbtData();
|
||||
Map<String, Tag<?, ?>> value = new HashMap<>(nbt.getValue());
|
||||
LinCompoundTag.Builder nbtBuilder = nbt.toBuilder();
|
||||
for (String key : strip) {
|
||||
value.remove(key);
|
||||
nbtBuilder.remove(key);
|
||||
}
|
||||
return (B) localBlock.toBaseBlock(new CompoundTag(value));
|
||||
return (B) localBlock.toBaseBlock(nbtBuilder.build());
|
||||
}
|
||||
|
||||
public <T extends NbtValued> T stripEntityNBT(T entity) {
|
||||
if (!entity.hasNbtData()) {
|
||||
LinCompoundTag nbt = entity.getNbt();
|
||||
if (nbt == null) {
|
||||
return entity;
|
||||
}
|
||||
CompoundTag nbt = entity.getNbtData();
|
||||
Map<String, Tag<?, ?>> value = new HashMap<>(nbt.getValue());
|
||||
LinCompoundTag.Builder nbtBuilder = nbt.toBuilder();
|
||||
for (String key : strip) {
|
||||
value.remove(key);
|
||||
nbtBuilder.remove(key);
|
||||
}
|
||||
entity.setNbtData(new CompoundTag(value));
|
||||
entity.setNbt(nbtBuilder.build());
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) {
|
||||
Map<BlockVector3, CompoundTag> tiles = set.getTiles();
|
||||
Set<CompoundTag> entities = set.getEntities();
|
||||
Map<BlockVector3, FaweCompoundTag> tiles = set.tiles();
|
||||
Collection<FaweCompoundTag> entities = set.entities();
|
||||
if (tiles.isEmpty() && entities.isEmpty()) {
|
||||
return set;
|
||||
}
|
||||
boolean isBv3ChunkMap = tiles instanceof BlockVector3ChunkMap;
|
||||
for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) {
|
||||
ImmutableMap.Builder<String, Tag<?, ?>> map = ImmutableMap.builder();
|
||||
final AtomicBoolean isStripped = new AtomicBoolean(false);
|
||||
entry.getValue().getValue().forEach((k, v) -> {
|
||||
if (strip.contains(k.toLowerCase())) {
|
||||
isStripped.set(true);
|
||||
} else {
|
||||
map.put(k, v);
|
||||
}
|
||||
});
|
||||
if (isStripped.get()) {
|
||||
for (final var entry : tiles.entrySet()) {
|
||||
FaweCompoundTag original = entry.getValue();
|
||||
FaweCompoundTag result = stripNbt(original);
|
||||
if (original != result) {
|
||||
if (isBv3ChunkMap) {
|
||||
// Replace existing value with stripped value
|
||||
tiles.put(entry.getKey(), new CompoundTag(map.build()));
|
||||
tiles.put(entry.getKey(), result);
|
||||
} else {
|
||||
entry.setValue(new CompoundTag(map.build()));
|
||||
entry.setValue(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
Set<CompoundTag> stripped = new HashSet<>();
|
||||
Iterator<CompoundTag> iterator = entities.iterator();
|
||||
Set<FaweCompoundTag> stripped = new HashSet<>();
|
||||
Iterator<FaweCompoundTag> iterator = entities.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
CompoundTag entity = iterator.next();
|
||||
ImmutableMap.Builder<String, Tag<?, ?>> map = ImmutableMap.builder();
|
||||
final AtomicBoolean isStripped = new AtomicBoolean(false);
|
||||
entity.getValue().forEach((k, v) -> {
|
||||
if (strip.contains(k.toUpperCase(Locale.ROOT))) {
|
||||
isStripped.set(true);
|
||||
} else {
|
||||
map.put(k, v);
|
||||
}
|
||||
});
|
||||
if (isStripped.get()) {
|
||||
FaweCompoundTag original = iterator.next();
|
||||
FaweCompoundTag result = stripNbt(original);
|
||||
if (original != result) {
|
||||
iterator.remove();
|
||||
stripped.add(new CompoundTag(map.build()));
|
||||
stripped.add(result);
|
||||
}
|
||||
}
|
||||
set.getEntities().addAll(stripped);
|
||||
// this relies on entities.addAll(...) not throwing an exception if empty+unmodifiable (=> stripped is empty too)
|
||||
entities.addAll(stripped);
|
||||
return set;
|
||||
}
|
||||
|
||||
private FaweCompoundTag stripNbt(
|
||||
FaweCompoundTag compoundTag
|
||||
) {
|
||||
LinCompoundTag.Builder builder = LinCompoundTag.builder();
|
||||
boolean stripped = false;
|
||||
for (var entry : compoundTag.linTag().value().entrySet()) {
|
||||
String k = entry.getKey();
|
||||
LinTag<?> v = entry.getValue();
|
||||
if (strip.contains(k.toLowerCase(Locale.ROOT))) {
|
||||
stripped = true;
|
||||
} else {
|
||||
builder.put(k, v);
|
||||
}
|
||||
}
|
||||
return stripped ? FaweCompoundTag.of(builder.build()) : compoundTag;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Extent construct(final Extent child) {
|
||||
|
@ -2,9 +2,11 @@ package com.fastasyncworldedit.core.extent.clipboard;
|
||||
|
||||
import com.fastasyncworldedit.core.jnbt.streamer.IntValueReader;
|
||||
import com.fastasyncworldedit.core.math.IntTriple;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
@ -175,6 +177,12 @@ public class CPUOptimizedClipboard extends LinearClipboard {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tile(final int x, final int y, final int z, final FaweCompoundTag tile) throws WorldEditException {
|
||||
// TODO replace
|
||||
return setTile(x, y, z, new CompoundTag(tile.linTag()));
|
||||
}
|
||||
|
||||
private boolean setTile(int index, CompoundTag tag) {
|
||||
final Map<String, Tag<?, ?>> values = new HashMap<>(tag.getValue());
|
||||
values.remove("x");
|
||||
|
@ -6,15 +6,18 @@ import com.fastasyncworldedit.core.internal.exception.FaweClipboardVersionMismat
|
||||
import com.fastasyncworldedit.core.internal.io.ByteBufferInputStream;
|
||||
import com.fastasyncworldedit.core.jnbt.streamer.IntValueReader;
|
||||
import com.fastasyncworldedit.core.math.IntTriple;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.util.MainUtil;
|
||||
import com.fastasyncworldedit.core.util.NbtUtils;
|
||||
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.DoubleTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
@ -28,6 +31,8 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.enginehub.linbus.tree.LinCompoundTag;
|
||||
import org.enginehub.linbus.tree.LinTagType;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
@ -64,7 +69,7 @@ public class DiskOptimizedClipboard extends LinearClipboard {
|
||||
private static final int VERSION_2_HEADER_SIZE = 27; // Header size of "version 2" i.e. when NBT/entities could be saved
|
||||
private static final Map<String, LockHolder> LOCK_HOLDER_CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
private final HashMap<IntTriple, CompoundTag> nbtMap;
|
||||
private final HashMap<IntTriple, FaweCompoundTag> nbtMap;
|
||||
private final File file;
|
||||
private final int headerSize;
|
||||
|
||||
@ -248,12 +253,12 @@ public class DiskOptimizedClipboard extends LinearClipboard {
|
||||
try (NBTInputStream nbtIS = new NBTInputStream(MainUtil.getCompressedIS(new ByteBufferInputStream(tmp)))) {
|
||||
Iterator<CompoundTag> iter = nbtIS.toIterator();
|
||||
while (nbtCount > 0 && iter.hasNext()) { // TileEntities are stored "before" entities
|
||||
CompoundTag tag = iter.next();
|
||||
int x = tag.getInt("x");
|
||||
int y = tag.getInt("y");
|
||||
int z = tag.getInt("z");
|
||||
LinCompoundTag tag = iter.next().toLinTag();
|
||||
int x = tag.getTag("x", LinTagType.intTag()).valueAsInt();
|
||||
int y = tag.getTag("y", LinTagType.intTag()).valueAsInt();
|
||||
int z = tag.getTag("z", LinTagType.intTag()).valueAsInt();
|
||||
IntTriple pos = new IntTriple(x, y, z);
|
||||
nbtMap.put(pos, tag);
|
||||
nbtMap.put(pos, FaweCompoundTag.of(tag));
|
||||
nbtCount--;
|
||||
}
|
||||
while (entitiesCount > 0 && iter.hasNext()) {
|
||||
@ -559,8 +564,8 @@ public class DiskOptimizedClipboard extends LinearClipboard {
|
||||
))) {
|
||||
if (!nbtMap.isEmpty()) {
|
||||
try {
|
||||
for (CompoundTag tag : nbtMap.values()) {
|
||||
nbtOS.writeTag(tag);
|
||||
for (FaweCompoundTag tag : nbtMap.values()) {
|
||||
nbtOS.writeTag(new CompoundTag(tag.linTag()));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -638,7 +643,7 @@ public class DiskOptimizedClipboard extends LinearClipboard {
|
||||
|
||||
@Override
|
||||
public Collection<CompoundTag> getTileEntities() {
|
||||
return nbtMap.values();
|
||||
return Collections2.transform(nbtMap.values(), fct -> new CompoundTag(fct.linTag()));
|
||||
}
|
||||
|
||||
public int getIndex(int x, int y, int z) {
|
||||
@ -656,10 +661,10 @@ public class DiskOptimizedClipboard extends LinearClipboard {
|
||||
|
||||
private BaseBlock toBaseBlock(BlockState state, int i) {
|
||||
if (state.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
|
||||
CompoundTag nbt;
|
||||
FaweCompoundTag nbt;
|
||||
if (nbtMap.size() < 4) {
|
||||
nbt = null;
|
||||
for (Map.Entry<IntTriple, CompoundTag> entry : nbtMap.entrySet()) {
|
||||
for (Map.Entry<IntTriple, FaweCompoundTag> entry : nbtMap.entrySet()) {
|
||||
IntTriple key = entry.getKey();
|
||||
int index = getIndex(key.x(), key.y(), key.z());
|
||||
if (index == i) {
|
||||
@ -674,15 +679,15 @@ public class DiskOptimizedClipboard extends LinearClipboard {
|
||||
int x = newI - z * getWidth();
|
||||
nbt = nbtMap.get(new IntTriple(x, y, z));
|
||||
}
|
||||
return state.toBaseBlock(nbt);
|
||||
return state.toBaseBlock(nbt == null ? null : nbt.linTag());
|
||||
}
|
||||
return state.toBaseBlock();
|
||||
}
|
||||
|
||||
private BaseBlock toBaseBlock(BlockState state, int x, int y, int z) {
|
||||
if (state.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
|
||||
CompoundTag nbt = nbtMap.get(new IntTriple(x, y, z));
|
||||
return state.toBaseBlock(nbt);
|
||||
FaweCompoundTag nbt = nbtMap.get(new IntTriple(x, y, z));
|
||||
return state.toBaseBlock(nbt == null ? null : nbt.linTag());
|
||||
}
|
||||
return state.toBaseBlock();
|
||||
}
|
||||
@ -709,12 +714,8 @@ public class DiskOptimizedClipboard extends LinearClipboard {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
||||
final Map<String, Tag<?, ?>> values = new HashMap<>(tag.getValue());
|
||||
values.put("x", new IntTag(x));
|
||||
values.put("y", new IntTag(y));
|
||||
values.put("z", new IntTag(z));
|
||||
nbtMap.put(new IntTriple(x, y, z), new CompoundTag(values));
|
||||
public boolean tile(final int x, final int y, final int z, final FaweCompoundTag tile) throws WorldEditException {
|
||||
nbtMap.put(new IntTriple(x, y, z), NbtUtils.withPosition(tile, x, y, z));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.fastasyncworldedit.core.extent.clipboard;
|
||||
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
@ -84,7 +84,8 @@ public final class EmptyClipboard implements Clipboard {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean setTile(int x, int y, int z, @Nonnull CompoundTag tile) throws WorldEditException {
|
||||
@Override
|
||||
public boolean tile(final int x, final int y, final int z, final FaweCompoundTag tile) throws WorldEditException {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,10 @@ public abstract class LinearClipboard extends SimpleClipboard {
|
||||
*/
|
||||
public abstract void streamBiomes(IntValueReader task);
|
||||
|
||||
/**
|
||||
* @deprecated will be removed as it is unused and uses outdated types
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "TODO")
|
||||
public abstract Collection<CompoundTag> getTileEntities();
|
||||
|
||||
@Override
|
||||
|
@ -3,10 +3,12 @@ package com.fastasyncworldedit.core.extent.clipboard;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.jnbt.streamer.IntValueReader;
|
||||
import com.fastasyncworldedit.core.math.IntTriple;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.util.MainUtil;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
@ -262,6 +264,12 @@ public class MemoryOptimizedClipboard extends LinearClipboard {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tile(final int x, final int y, final int z, final FaweCompoundTag tile) throws WorldEditException {
|
||||
// TODO replace
|
||||
return setTile(x, y, z, new CompoundTag(tile.linTag()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) {
|
||||
return setBlock(getIndex(x, y, z), block);
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.fastasyncworldedit.core.extent.clipboard;
|
||||
|
||||
import com.fastasyncworldedit.core.Fawe;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
@ -106,7 +106,7 @@ public abstract class ReadOnlyClipboard extends SimpleClipboard {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
||||
public boolean tile(int x, int y, int z, FaweCompoundTag tag) {
|
||||
throw new UnsupportedOperationException("Clipboard is immutable");
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,9 @@ public class ResizableClipboardBuilder extends MemoryOptimizedHistory {
|
||||
}
|
||||
|
||||
public Clipboard build() {
|
||||
if (longSize() == 0) {
|
||||
return EmptyClipboard.getInstance();
|
||||
}
|
||||
BlockVector3 pos1 = BlockVector3.at(minX, minY, minZ);
|
||||
BlockVector3 pos2 = BlockVector3.at(maxX, maxY, maxZ);
|
||||
CuboidRegion region = new CuboidRegion(pos1, pos2);
|
||||
|
@ -5,6 +5,7 @@ import com.fastasyncworldedit.core.extent.clipboard.SimpleClipboard;
|
||||
import com.fastasyncworldedit.core.internal.io.ResettableFileInputStream;
|
||||
import com.fastasyncworldedit.core.internal.io.VarIntStreamIterator;
|
||||
import com.fastasyncworldedit.core.math.MutableBlockVector3;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.util.IOUtil;
|
||||
import com.fastasyncworldedit.core.util.MathMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
@ -40,6 +41,8 @@ import org.apache.logging.log4j.Logger;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.enginehub.linbus.tree.LinCompoundTag;
|
||||
import org.enginehub.linbus.tree.LinIntArrayTag;
|
||||
import org.enginehub.linbus.tree.LinTagType;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
@ -87,6 +90,7 @@ public class FastSchematicReaderV3 implements ClipboardReader {
|
||||
|
||||
private VersionedDataFixer dataFixer;
|
||||
private BlockVector3 offset;
|
||||
private BlockVector3 origin = BlockVector3.ZERO;
|
||||
private BlockState[] blockPalette;
|
||||
private BiomeType[] biomePalette;
|
||||
private int dataVersion = -1;
|
||||
@ -136,6 +140,24 @@ public class FastSchematicReaderV3 implements ClipboardReader {
|
||||
this.dataVersion = this.dataInputStream.readInt();
|
||||
this.dataFixer = ReaderUtil.getVersionedDataFixer(this.dataVersion, platform, platform.getDataVersion());
|
||||
}
|
||||
case "Metadata" -> {
|
||||
LinCompoundTag metadataCompoundTag =
|
||||
(LinCompoundTag) this.nbtInputStream.readTagPayload(NBTConstants.TYPE_COMPOUND, 0).toLinTag();
|
||||
|
||||
LinCompoundTag worldEditTag = metadataCompoundTag.findTag("WorldEdit", LinTagType.compoundTag());
|
||||
if (worldEditTag != null) { // allowed to be optional
|
||||
LinIntArrayTag originTag = worldEditTag.findTag("Origin", LinTagType.intArrayTag());
|
||||
if (originTag != null) { // allowed to be optional
|
||||
int[] parts = originTag.value();
|
||||
|
||||
if (parts.length != 3) {
|
||||
throw new IOException("`Metadata > WorldEdit > Origin` int array length is invalid.");
|
||||
}
|
||||
|
||||
this.origin = BlockVector3.at(parts[0], parts[1], parts[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
case "Offset" -> {
|
||||
this.dataInputStream.skipNBytes(4); // Array Length field (4 byte int)
|
||||
this.offset = BlockVector3.at(
|
||||
@ -172,7 +194,7 @@ public class FastSchematicReaderV3 implements ClipboardReader {
|
||||
|
||||
clipboard.setOrigin(this.offset.multiply(-1));
|
||||
if (clipboard instanceof SimpleClipboard simpleClipboard && !this.offset.equals(BlockVector3.ZERO)) {
|
||||
clipboard = new BlockArrayClipboard(simpleClipboard, this.offset);
|
||||
clipboard = new BlockArrayClipboard(simpleClipboard, this.offset.add(this.origin));
|
||||
}
|
||||
return clipboard;
|
||||
}
|
||||
@ -626,12 +648,11 @@ public class FastSchematicReaderV3 implements ClipboardReader {
|
||||
}
|
||||
|
||||
private EntityTransformer provideTileEntityTransformer(Clipboard clipboard) {
|
||||
//noinspection deprecation
|
||||
return (x, y, z, id, tag) -> clipboard.setTile(
|
||||
return (x, y, z, id, tag) -> clipboard.tile(
|
||||
MathMan.roundInt(x + clipboard.getMinimumPoint().x()),
|
||||
MathMan.roundInt(y + clipboard.getMinimumPoint().y()),
|
||||
MathMan.roundInt(z + clipboard.getMinimumPoint().z()),
|
||||
new CompoundTag(tag)
|
||||
FaweCompoundTag.of(tag)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
package com.fastasyncworldedit.core.extent.filter;
|
||||
|
||||
import com.fastasyncworldedit.core.extent.filter.block.FilterBlock;
|
||||
import com.fastasyncworldedit.core.internal.simd.VectorizedFilter;
|
||||
import jdk.incubator.vector.ShortVector;
|
||||
|
||||
public class CountFilter extends ForkedFilter<CountFilter> {
|
||||
public class CountFilter extends ForkedFilter<CountFilter> implements VectorizedFilter {
|
||||
|
||||
private int total;
|
||||
|
||||
@ -33,4 +35,10 @@ public class CountFilter extends ForkedFilter<CountFilter> {
|
||||
return total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShortVector applyVector(final ShortVector get, final ShortVector set) {
|
||||
total += set.length();
|
||||
return set;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,37 +1,92 @@
|
||||
package com.fastasyncworldedit.core.extent.filter;
|
||||
|
||||
import com.fastasyncworldedit.core.extent.filter.block.DelegateFilter;
|
||||
import com.fastasyncworldedit.core.extent.filter.block.FilterBlock;
|
||||
import com.fastasyncworldedit.core.internal.simd.VectorizedFilter;
|
||||
import com.fastasyncworldedit.core.queue.Filter;
|
||||
import com.fastasyncworldedit.core.queue.IChunk;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import jdk.incubator.vector.ShortVector;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Filter which links two Filters together for single-filter-input operations.
|
||||
* Filter which links two Filters together for single-filter-input operations. Left filter is operated first.
|
||||
*
|
||||
* @param <T> Parent which extends Filter
|
||||
* @param <S> Child which extends Filter
|
||||
* @param <L> Left filter
|
||||
* @param <R> Right filter
|
||||
*/
|
||||
public final class LinkedFilter<T extends Filter, S extends Filter> extends DelegateFilter<T> {
|
||||
public sealed class LinkedFilter<L extends Filter, R extends Filter> implements Filter {
|
||||
|
||||
private final S child;
|
||||
private final L left;
|
||||
private final R right;
|
||||
|
||||
public LinkedFilter(T parent, S child) {
|
||||
super(parent);
|
||||
this.child = child;
|
||||
public LinkedFilter(L left, R right) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public S getChild() {
|
||||
return this.child;
|
||||
@SuppressWarnings({"unchecked", "rawtypes"}) // we defeated the type system
|
||||
public static <L extends Filter, R extends Filter> LinkedFilter<? extends L, ? extends R> of(L left, R right) {
|
||||
if (left instanceof VectorizedFilter l && right instanceof VectorizedFilter r) {
|
||||
return new VectorizedLinkedFilter(l, r);
|
||||
}
|
||||
return new LinkedFilter<>(left, right);
|
||||
}
|
||||
|
||||
public L getLeft() {
|
||||
return this.left;
|
||||
}
|
||||
|
||||
public R getRight() {
|
||||
return this.right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IChunk> T applyChunk(T chunk, @Nullable Region region) {
|
||||
chunk = getLeft().applyChunk(chunk, region);
|
||||
return getRight().applyChunk(chunk, region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyBlock(FilterBlock block) {
|
||||
this.getParent().applyBlock(block);
|
||||
this.getChild().applyBlock(block);
|
||||
getLeft().applyBlock(block);
|
||||
getRight().applyBlock(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinkedFilter<LinkedFilter<T, S>, Filter> newInstance(Filter other) {
|
||||
return new LinkedFilter<>(this, other);
|
||||
public void finishChunk(IChunk chunk) {
|
||||
getLeft().finishChunk(chunk);
|
||||
getRight().finishChunk(chunk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter fork() {
|
||||
return new LinkedFilter<>(getLeft().fork(), getRight().fork());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void join() {
|
||||
getLeft().join();
|
||||
getRight().join();
|
||||
}
|
||||
|
||||
private final static class VectorizedLinkedFilter<L extends VectorizedFilter, R extends VectorizedFilter>
|
||||
extends LinkedFilter<L, R> implements VectorizedFilter {
|
||||
|
||||
public VectorizedLinkedFilter(final L left, final R right) {
|
||||
super(left, right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShortVector applyVector(final ShortVector get, final ShortVector set) {
|
||||
ShortVector res = getLeft().applyVector(get, set);
|
||||
return getRight().applyVector(get, res);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter fork() {
|
||||
return new VectorizedLinkedFilter<>((L) getLeft().fork(), (R) getRight().fork());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,10 +2,17 @@ package com.fastasyncworldedit.core.extent.filter;
|
||||
|
||||
import com.fastasyncworldedit.core.extent.filter.block.DelegateFilter;
|
||||
import com.fastasyncworldedit.core.extent.filter.block.FilterBlock;
|
||||
import com.fastasyncworldedit.core.internal.simd.SimdSupport;
|
||||
import com.fastasyncworldedit.core.internal.simd.VectorizedFilter;
|
||||
import com.fastasyncworldedit.core.internal.simd.VectorizedMask;
|
||||
import com.fastasyncworldedit.core.queue.Filter;
|
||||
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import jdk.incubator.vector.ShortVector;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
@ -15,8 +22,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
*/
|
||||
public class MaskFilter<T extends Filter> extends DelegateFilter<T> {
|
||||
|
||||
private final Mask mask;
|
||||
private final AtomicInteger changes;
|
||||
final Mask mask;
|
||||
final AtomicInteger changes;
|
||||
|
||||
public MaskFilter(T other, Mask root) {
|
||||
this(other, root, new AtomicInteger());
|
||||
@ -60,4 +67,45 @@ public class MaskFilter<T extends Filter> extends DelegateFilter<T> {
|
||||
return new MaskFilter<>(getParent().fork(), mask.copy(), changes);
|
||||
}
|
||||
|
||||
public static class VectorizedMaskFilter<T extends VectorizedFilter> extends MaskFilter<T> implements VectorizedFilter {
|
||||
|
||||
private final VectorizedMask vectorizedMask;
|
||||
|
||||
public VectorizedMaskFilter(final T other, final Mask root) {
|
||||
super(other, root);
|
||||
this.vectorizedMask = Objects.requireNonNull(SimdSupport.vectorizedTargetMask(root), "invalid vectorizable mask");
|
||||
}
|
||||
|
||||
public VectorizedMaskFilter(final T other, final Mask root, AtomicInteger changes) {
|
||||
super(other, root, changes);
|
||||
this.vectorizedMask = Objects.requireNonNull(SimdSupport.vectorizedTargetMask(root), "invalid vectorizable mask");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShortVector applyVector(final ShortVector get, final ShortVector set) {
|
||||
final T parent = getParent();
|
||||
VectorMask<Short> masked = vectorizedMask.compareVector(set, get);
|
||||
ShortVector res = parent.applyVector(get, set);
|
||||
res = set.blend(res, masked);
|
||||
VectorMask<Short> changed = res.compare(VectorOperators.NE, set);
|
||||
changes.getAndAdd(changed.trueCount());
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaskFilter<?> newInstance(final Filter other) {
|
||||
if (other instanceof VectorizedFilter o) {
|
||||
return new VectorizedMaskFilter<>(o, mask);
|
||||
}
|
||||
return super.newInstance(other);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Filter fork() {
|
||||
return new VectorizedMaskFilter<>((T) getParent().fork(), mask.copy(), changes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.fastasyncworldedit.core.extent.filter.block;
|
||||
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
@ -105,6 +106,11 @@ public class ArrayFilterBlock extends AbstractExtentFilterBlock {
|
||||
return getExtent().setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tile(final int x, final int y, final int z, final FaweCompoundTag tile) throws WorldEditException {
|
||||
return false; // class is unused + deprecated, do not care about impl
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||
return getExtent().setBiome(x, y, z, biome);
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.fastasyncworldedit.core.extent.filter.block;
|
||||
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.queue.Filter;
|
||||
import com.fastasyncworldedit.core.queue.FilterBlockMask;
|
||||
import com.fastasyncworldedit.core.queue.IBlocks;
|
||||
@ -8,11 +9,11 @@ import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||
import com.fastasyncworldedit.core.queue.implementation.Flood;
|
||||
import com.fastasyncworldedit.core.queue.implementation.blocks.CharGetBlocks;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.concurrency.LazyReference;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
@ -20,12 +21,15 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
import org.enginehub.linbus.tree.LinCompoundTag;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.sk89q.worldedit.world.block.BlockTypesCache.states;
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
public class CharFilterBlock extends ChunkFilterBlock {
|
||||
|
||||
private static final SetDelegate FULL = (block, value) -> block.setArr[block.index] = value;
|
||||
@ -35,10 +39,10 @@ public class CharFilterBlock extends ChunkFilterBlock {
|
||||
private int minLayer;
|
||||
private CharGetBlocks get;
|
||||
private IChunkSet set;
|
||||
private char[] getArr;
|
||||
protected char[] getArr;
|
||||
@Nullable
|
||||
private char[] setArr;
|
||||
private SetDelegate delegate;
|
||||
protected char[] setArr;
|
||||
protected SetDelegate delegate;
|
||||
// local
|
||||
private int layer;
|
||||
private int index;
|
||||
@ -169,7 +173,7 @@ public class CharFilterBlock extends ChunkFilterBlock {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized final void filter(Filter filter) {
|
||||
public synchronized void filter(Filter filter) {
|
||||
for (y = 0, index = 0; y < 16; y++) {
|
||||
for (z = 0; z < 16; z++) {
|
||||
for (x = 0; x < 16; x++, index++) {
|
||||
@ -259,8 +263,8 @@ public class CharFilterBlock extends ChunkFilterBlock {
|
||||
final BlockState state = getBlock();
|
||||
final BlockMaterial material = state.getMaterial();
|
||||
if (material.hasContainer()) {
|
||||
final CompoundTag tag = get.getTile(x, y + yy, z);
|
||||
return state.toBaseBlock(tag);
|
||||
final FaweCompoundTag tag = get.tile(x, y + yy, z);
|
||||
return state.toBaseBlock(tag == null ? null : tag.linTag());
|
||||
}
|
||||
return state.toBaseBlock();
|
||||
}
|
||||
@ -268,16 +272,28 @@ public class CharFilterBlock extends ChunkFilterBlock {
|
||||
@Override
|
||||
public void setFullBlock(BaseBlock block) {
|
||||
delegate.set(this, block.getOrdinalChar());
|
||||
final CompoundTag nbt = block.getNbtData();
|
||||
final LazyReference<LinCompoundTag> nbt = block.getNbtReference();
|
||||
if (nbt != null) { // TODO optimize check via ImmutableBaseBlock
|
||||
set.setTile(x, yy + y, z, nbt);
|
||||
set.tile(x, yy + y, z, FaweCompoundTag.of(nbt));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final CompoundTag getNbtData() {
|
||||
return get.getTile(x, y + yy, z);
|
||||
public @Nullable LinCompoundTag getNbt() {
|
||||
final FaweCompoundTag tile = get.tile(x, y + yy, z);
|
||||
if (tile == null) {
|
||||
return null;
|
||||
}
|
||||
return tile.linTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNbt(@Nullable final LinCompoundTag nbtData) {
|
||||
if (nbtData != null) {
|
||||
set.tile(x, y + yy, z, FaweCompoundTag.of(nbtData));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
NORTH(Vector3.at(0, 0, -1), Flag.CARDINAL, 3, 1),
|
||||
EAST(Vector3.at(1, 0, 0), Flag.CARDINAL, 0, 2),
|
||||
@ -286,9 +302,9 @@ public class CharFilterBlock extends ChunkFilterBlock {
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void setNbtData(CompoundTag tag) {
|
||||
if (tag != null) {
|
||||
set.setTile(x, y + yy, z, tag);
|
||||
public void setNbtReference(@Nullable final LazyReference<LinCompoundTag> nbtData) {
|
||||
if (nbtData != null) {
|
||||
set.tile(x, y + yy, z, FaweCompoundTag.of(nbtData));
|
||||
}
|
||||
}
|
||||
|
||||
@ -380,7 +396,7 @@ public class CharFilterBlock extends ChunkFilterBlock {
|
||||
}
|
||||
|
||||
//Set delegate
|
||||
private SetDelegate initSet() {
|
||||
protected final SetDelegate initSet() {
|
||||
setArr = set.load(layer);
|
||||
return delegate = FULL;
|
||||
}
|
||||
@ -412,7 +428,8 @@ public class CharFilterBlock extends ChunkFilterBlock {
|
||||
return getExtent().setBiome(x, y, z, biome);
|
||||
}
|
||||
|
||||
private interface SetDelegate {
|
||||
@ApiStatus.Internal
|
||||
protected interface SetDelegate {
|
||||
|
||||
void set(@Nonnull CharFilterBlock block, char value);
|
||||
|
||||
|
@ -83,12 +83,20 @@ public abstract class ChunkFilterBlock extends AbstractExtentFilterBlock {
|
||||
/**
|
||||
* Filter a chunk with a region / filter.
|
||||
*/
|
||||
public synchronized final IChunkSet filter(IChunk chunk, IChunkGet get, IChunkSet set, Filter filter, Region region, boolean full) {
|
||||
public synchronized final IChunkSet filter(
|
||||
IChunk chunk,
|
||||
IChunkGet get,
|
||||
IChunkSet set,
|
||||
Filter filter,
|
||||
Region region,
|
||||
boolean full
|
||||
) {
|
||||
if (region != null) {
|
||||
region.filter(chunk, filter, this, get, set, full);
|
||||
} else {
|
||||
for (int layer = get.getMinSectionPosition(); layer <= get.getMaxSectionPosition(); layer++) {
|
||||
if ((!full && !get.hasSection(layer)) || !filter.appliesLayer(chunk, layer)) {
|
||||
//if ((!full && !get.hasSection(layer)) || !filter.appliesLayer(chunk, layer)) {
|
||||
if (!full && !get.hasSection(layer)) {
|
||||
continue;
|
||||
}
|
||||
initLayer(get, set, layer);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.fastasyncworldedit.core.extent.filter.block;
|
||||
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.TileEntityBlock;
|
||||
@ -35,17 +36,6 @@ public abstract class FilterBlock extends BlockVector3 implements Extent, TileEn
|
||||
|
||||
public abstract BiomeType getBiome();
|
||||
|
||||
@Override
|
||||
public abstract CompoundTag getNbtData();
|
||||
|
||||
@Override
|
||||
public abstract void setNbtData(@Nullable CompoundTag nbtData);
|
||||
|
||||
@Override
|
||||
public boolean hasNbtData() {
|
||||
return getNbtData() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector3 getMinimumPoint() {
|
||||
return getExtent().getMinimumPoint();
|
||||
@ -61,10 +51,9 @@ public abstract class FilterBlock extends BlockVector3 implements Extent, TileEn
|
||||
return getExtent().getBlock(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
|
||||
return getExtent().setTile(x, y, z, tile);
|
||||
public boolean tile(final int x, final int y, final int z, final FaweCompoundTag tile) throws WorldEditException {
|
||||
return getExtent().tile(x, y, z, tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -26,7 +26,7 @@ public abstract class ABlockMask extends AbstractExtentMask {
|
||||
|
||||
@Override
|
||||
public boolean test(BlockVector3 vector) {
|
||||
return test(getExtent().getBlock(vector));
|
||||
return test(vector.getBlock(getExtent()));
|
||||
}
|
||||
|
||||
public abstract boolean test(BlockState state);
|
||||
|
@ -16,9 +16,9 @@ public class DataMask extends AbstractExtentMask implements ResettableMask {
|
||||
@Override
|
||||
public boolean test(BlockVector3 vector) {
|
||||
if (data != -1) {
|
||||
return getExtent().getBlock(vector).getInternalPropertiesId() == data;
|
||||
return vector.getBlock(getExtent()).getInternalPropertiesId() == data;
|
||||
} else {
|
||||
data = getExtent().getBlock(vector).getInternalPropertiesId();
|
||||
data = vector.getBlock(getExtent()).getInternalPropertiesId();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,9 @@ public class IdMask extends AbstractExtentMask implements ResettableMask {
|
||||
|
||||
@Override
|
||||
public boolean test(BlockVector3 vector) {
|
||||
return test(getExtent(), vector);
|
||||
int blockID = vector.getBlock(getExtent()).getInternalBlockTypeId();
|
||||
int testId = id.compareAndExchange(-1, blockID);
|
||||
return blockID == testId || testId == -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -30,7 +30,7 @@ public class SingleBlockStateMask extends ABlockMask {
|
||||
|
||||
@Override
|
||||
public boolean test(BlockVector3 vector) {
|
||||
int test = getExtent().getBlock(vector).getOrdinal();
|
||||
int test = vector.getBlock(getExtent()).getOrdinal();
|
||||
return ordinal == test || isAir && test == 0;
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ public class SplatterBrushMask extends AbstractExtentMask {
|
||||
double dist = vector.distanceSq(position);
|
||||
synchronized (placed) {
|
||||
if (dist < size2 && !placed.contains(vector) && ThreadLocalRandom.current().nextInt(5) < 2 && surface.test(vector)) {
|
||||
placed.add(vector);
|
||||
placed.add(vector.toImmutable());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,65 @@
|
||||
package com.fastasyncworldedit.core.history.change;
|
||||
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @since 2.11.2
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public interface ChangePopulator<C extends Change> {
|
||||
|
||||
static <C extends Change> ChangePopulator<C> empty() {
|
||||
class Empty implements ChangePopulator<C> {
|
||||
private static final Empty EMPTY = new Empty();
|
||||
|
||||
@Override
|
||||
public @NotNull C create() {
|
||||
throw new UnsupportedOperationException("empty");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable C populate(@NotNull final C change) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable C updateOrCreate(@Nullable final Change change) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accepts(final Change change) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return Empty.EMPTY;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
default @NotNull C update(@Nullable Change before) {
|
||||
if (accepts(before)) {
|
||||
return (C) before;
|
||||
}
|
||||
return create();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
C create();
|
||||
|
||||
@Nullable
|
||||
default C updateOrCreate(@Nullable Change change) {
|
||||
C u = update(change);
|
||||
return populate(u);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
C populate(@NotNull C change);
|
||||
|
||||
@Contract("null->false")
|
||||
boolean accepts(Change change);
|
||||
|
||||
}
|
@ -4,11 +4,12 @@ import com.fastasyncworldedit.core.Fawe;
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.extent.HistoryExtent;
|
||||
import com.fastasyncworldedit.core.extent.processor.ProcessorScope;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
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.util.MainUtil;
|
||||
import com.fastasyncworldedit.core.util.NbtUtils;
|
||||
import com.fastasyncworldedit.core.util.TaskManager;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
@ -32,8 +33,12 @@ import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.enginehub.linbus.tree.LinCompoundTag;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@ -122,37 +127,38 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
||||
int bx = chunk.getX() << 4;
|
||||
int bz = chunk.getZ() << 4;
|
||||
|
||||
Map<BlockVector3, CompoundTag> tilesFrom = get.getTiles();
|
||||
Map<BlockVector3, CompoundTag> tilesTo = set.getTiles();
|
||||
Map<BlockVector3, FaweCompoundTag> tilesFrom = get.tiles();
|
||||
Map<BlockVector3, FaweCompoundTag> tilesTo = set.tiles();
|
||||
if (!tilesFrom.isEmpty()) {
|
||||
for (Map.Entry<BlockVector3, CompoundTag> entry : tilesFrom.entrySet()) {
|
||||
for (Map.Entry<BlockVector3, FaweCompoundTag> entry : tilesFrom.entrySet()) {
|
||||
BlockVector3 pos = entry.getKey();
|
||||
BlockState fromBlock = get.getBlock(pos.x() & 15, pos.y(), pos.z() & 15);
|
||||
BlockState toBlock = set.getBlock(pos.x() & 15, pos.y(), pos.z() & 15);
|
||||
if (fromBlock != toBlock || tilesTo.containsKey(pos)) {
|
||||
addTileRemove(MainUtil.setPosition(entry.getValue(), entry.getKey().x(), entry.getKey().y(),
|
||||
entry.getKey().z()));
|
||||
addTileRemove(NbtUtils.withPosition(entry.getValue(), entry.getKey().x(), entry.getKey().y(),
|
||||
entry.getKey().z()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tilesTo.isEmpty()) {
|
||||
for (Map.Entry<BlockVector3, CompoundTag> entry : tilesTo.entrySet()) {
|
||||
for (Map.Entry<BlockVector3, FaweCompoundTag> entry : tilesTo.entrySet()) {
|
||||
BlockVector3 pos = entry.getKey();
|
||||
addTileCreate(MainUtil.setPosition(entry.getValue(), pos.x() + bx, pos.y(), pos.z() + bz));
|
||||
addTileCreate(NbtUtils.withPosition(entry.getValue(), pos.x() + bx, pos.y(), pos.z() + bz));
|
||||
}
|
||||
}
|
||||
Set<UUID> entRemoves = set.getEntityRemoves();
|
||||
if (!entRemoves.isEmpty()) {
|
||||
for (UUID uuid : entRemoves) {
|
||||
CompoundTag found = get.getEntity(uuid);
|
||||
FaweCompoundTag found = get.entity(uuid);
|
||||
if (found != null) {
|
||||
addEntityRemove(found);
|
||||
}
|
||||
}
|
||||
}
|
||||
Set<CompoundTag> ents = set.getEntities();
|
||||
Collection<FaweCompoundTag> ents = set.entities();
|
||||
if (!ents.isEmpty()) {
|
||||
for (CompoundTag tag : ents) {
|
||||
for (FaweCompoundTag tag : ents) {
|
||||
addEntityCreate(tag);
|
||||
}
|
||||
}
|
||||
@ -203,9 +209,9 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
||||
BiomeType[] biomeSection = biomes[layer - set.getMinSectionPosition()];
|
||||
int index = 0;
|
||||
int yy = layer << 4;
|
||||
for (int y = 0; y < 16; y+= 4) {
|
||||
for (int z = 0; z < 16; z+= 4) {
|
||||
for (int x = 0; x < 16; x+= 4, index++) {
|
||||
for (int y = 0; y < 16; y += 4) {
|
||||
for (int z = 0; z < 16; z += 4) {
|
||||
for (int x = 0; x < 16; x += 4, index++) {
|
||||
BiomeType newBiome = biomeSection[index];
|
||||
if (newBiome != null) {
|
||||
BiomeType oldBiome = get.getBiomeType(x, yy + y, z);
|
||||
@ -236,13 +242,62 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
||||
return ProcessorScope.READING_SET_BLOCKS;
|
||||
}
|
||||
|
||||
public abstract void addTileCreate(CompoundTag tag);
|
||||
@Deprecated(forRemoval = true, since = "2.11.2")
|
||||
public void addTileCreate(CompoundTag tag) {
|
||||
addTileCreate(adapt(tag));
|
||||
}
|
||||
|
||||
public abstract void addTileRemove(CompoundTag tag);
|
||||
@SuppressWarnings({"deprecation"})
|
||||
private static @Nonnull FaweCompoundTag adapt(CompoundTag tag) {
|
||||
return FaweCompoundTag.of(tag.toLinTag());
|
||||
}
|
||||
|
||||
public abstract void addEntityRemove(CompoundTag tag);
|
||||
/**
|
||||
* Creates a tile/block entity create change to this change set.
|
||||
*
|
||||
* @param tag the tile/block entity to add.
|
||||
* @since 2.11.2
|
||||
*/
|
||||
public abstract void addTileCreate(FaweCompoundTag tag);
|
||||
|
||||
public abstract void addEntityCreate(CompoundTag tag);
|
||||
@Deprecated(forRemoval = true, since = "2.11.2")
|
||||
public void addTileRemove(CompoundTag tag) {
|
||||
addTileRemove(adapt(tag));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a tile/block entity remove change to this change set.
|
||||
*
|
||||
* @param tag the tile/block entity to remove.
|
||||
* @since 2.11.2
|
||||
*/
|
||||
public abstract void addTileRemove(FaweCompoundTag tag);
|
||||
|
||||
@Deprecated(forRemoval = true, since = "2.11.2")
|
||||
public void addEntityRemove(CompoundTag tag) {
|
||||
addEntityRemove(adapt(tag));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an entity remove change to this change set.
|
||||
*
|
||||
* @param tag the entity to remove.
|
||||
* @since 2.11.2
|
||||
*/
|
||||
public abstract void addEntityRemove(FaweCompoundTag tag);
|
||||
|
||||
@Deprecated(forRemoval = true, since = "2.11.2")
|
||||
public void addEntityCreate(CompoundTag tag) {
|
||||
addEntityCreate(adapt(tag));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an entity create change to this change set.
|
||||
*
|
||||
* @param tag the entity to add.
|
||||
* @since 2.11.2
|
||||
*/
|
||||
public abstract void addEntityCreate(FaweCompoundTag tag);
|
||||
|
||||
public abstract void addBiomeChange(int x, int y, int z, BiomeType from, BiomeType to);
|
||||
|
||||
@ -250,6 +305,13 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
||||
return getIterator(redo);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a coordinator to exchange sets of changes between a producer and a consumer}
|
||||
* @since 2.11.2
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public abstract ChangeExchangeCoordinator getCoordinatedChanges(BlockBag blockBag, int mode, boolean dir);
|
||||
|
||||
public abstract Iterator<Change> getIterator(boolean redo);
|
||||
|
||||
public EditSession toEditSession(Actor actor) {
|
||||
@ -272,13 +334,15 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
||||
}
|
||||
|
||||
public void add(EntityCreate change) {
|
||||
CompoundTag tag = change.state.getNbtData();
|
||||
addEntityCreate(MainUtil.setEntityInfo(tag, change.getEntity()));
|
||||
LinCompoundTag tag = change.state.getNbt();
|
||||
assert tag != null;
|
||||
addEntityCreate(FaweCompoundTag.of(NbtUtils.withEntityInfo(tag, change.getEntity())));
|
||||
}
|
||||
|
||||
public void add(EntityRemove change) {
|
||||
CompoundTag tag = change.state.getNbtData();
|
||||
addEntityRemove(MainUtil.setEntityInfo(tag, change.getEntity()));
|
||||
LinCompoundTag tag = change.state.getNbt();
|
||||
assert tag != null;
|
||||
addEntityRemove(FaweCompoundTag.of(NbtUtils.withEntityInfo(tag, change.getEntity())));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -296,9 +360,9 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
||||
|
||||
public void add(BlockChange change) {
|
||||
try {
|
||||
BlockVector3 loc = change.getPosition();
|
||||
BlockVector3 loc = change.position();
|
||||
BaseBlock from = change.previous();
|
||||
BaseBlock to = change.getCurrent();
|
||||
BaseBlock to = change.current();
|
||||
add(loc, from, to);
|
||||
} catch (Exception e) {
|
||||
LOGGER.catching(e);
|
||||
@ -318,31 +382,28 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
||||
|
||||
public void add(int x, int y, int z, BaseBlock from, BaseBlock to) {
|
||||
try {
|
||||
if (from.hasNbtData()) {
|
||||
CompoundTag nbt = from.getNbtData();
|
||||
assert nbt != null;
|
||||
addTileRemove(MainUtil.setPosition(nbt, x, y, z));
|
||||
LinCompoundTag nbt = from.getNbt();
|
||||
if (nbt != null) {
|
||||
addTileRemove(FaweCompoundTag.of(NbtUtils.withPosition(nbt, x, y, z)));
|
||||
}
|
||||
if (to.hasNbtData()) {
|
||||
CompoundTag nbt = to.getNbtData();
|
||||
assert nbt != null;
|
||||
addTileCreate(MainUtil.setPosition(nbt, x, y, z));
|
||||
nbt = to.getNbt();
|
||||
if (nbt != null) {
|
||||
addTileCreate(FaweCompoundTag.of(NbtUtils.withPosition(nbt, x, y, z)));
|
||||
}
|
||||
int combinedFrom = from.getOrdinal();
|
||||
int combinedTo = to.getOrdinal();
|
||||
add(x, y, z, combinedFrom, combinedTo);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
LOGGER.catching(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void add(int x, int y, int z, int combinedFrom, BaseBlock to) {
|
||||
try {
|
||||
if (to.hasNbtData()) {
|
||||
CompoundTag nbt = to.getNbtData();
|
||||
assert nbt != null;
|
||||
addTileCreate(MainUtil.setPosition(nbt, x, y, z));
|
||||
LinCompoundTag nbt = to.getNbt();
|
||||
if (nbt != null) {
|
||||
addTileCreate(FaweCompoundTag.of(NbtUtils.withPosition(nbt, x, y, z)));
|
||||
}
|
||||
int combinedTo = to.getInternalId();
|
||||
add(x, y, z, combinedFrom, combinedTo);
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.fastasyncworldedit.core.history.changeset;
|
||||
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
@ -46,26 +46,6 @@ public class AbstractDelegateChangeSet extends AbstractChangeSet {
|
||||
parent.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTileCreate(CompoundTag tag) {
|
||||
parent.addTileCreate(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTileRemove(CompoundTag tag) {
|
||||
parent.addTileRemove(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntityRemove(CompoundTag tag) {
|
||||
parent.addEntityRemove(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntityCreate(CompoundTag tag) {
|
||||
parent.addEntityCreate(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBiomeChange(int x, int y, int z, BiomeType from, BiomeType to) {
|
||||
parent.addBiomeChange(x, y, z, from, to);
|
||||
@ -76,6 +56,11 @@ public class AbstractDelegateChangeSet extends AbstractChangeSet {
|
||||
return parent.getIterator(blockBag, mode, redo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChangeExchangeCoordinator getCoordinatedChanges(final BlockBag blockBag, final int mode, final boolean dir) {
|
||||
return parent.getCoordinatedChanges(blockBag, mode, dir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Change> getIterator(boolean redo) {
|
||||
return parent.getIterator(redo);
|
||||
@ -141,6 +126,26 @@ public class AbstractDelegateChangeSet extends AbstractChangeSet {
|
||||
return parent.forwardIterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTileCreate(final FaweCompoundTag tag) {
|
||||
parent.addTileCreate(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTileRemove(final FaweCompoundTag tag) {
|
||||
parent.addTileRemove(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntityRemove(final FaweCompoundTag tag) {
|
||||
parent.addEntityRemove(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntityCreate(final FaweCompoundTag tag) {
|
||||
parent.addEntityCreate(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
parent.close();
|
||||
|
@ -1,8 +1,6 @@
|
||||
package com.fastasyncworldedit.core.history.changeset;
|
||||
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBagException;
|
||||
import com.sk89q.worldedit.extent.inventory.UnplaceableBlockException;
|
||||
@ -109,13 +107,4 @@ public class BlockBagChangeSet extends AbstractDelegateChangeSet {
|
||||
super.add(x, y, z, combinedFrom, combinedTo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTileCreate(CompoundTag nbt) {
|
||||
if (nbt.containsKey("items")) {
|
||||
Map<String, Tag<?, ?>> map = new HashMap<>(nbt.getValue());
|
||||
map.remove("items");
|
||||
}
|
||||
super.addTileCreate(nbt);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
package com.fastasyncworldedit.core.history.changeset;
|
||||
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.concurrent.Exchanger;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* @since 2.11.2
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public class ChangeExchangeCoordinator implements AutoCloseable {
|
||||
|
||||
private static final Thread.Builder.OfVirtual UNDO_VIRTUAL_THREAD_BUILDER = Thread.ofVirtual()
|
||||
.name("FAWE undo", 0);
|
||||
private final Exchanger<Change[]> exchanger;
|
||||
private final BiConsumer<Exchanger<Change[]>, Change[]> runnerTask;
|
||||
private boolean started = false;
|
||||
private Thread runner;
|
||||
|
||||
public ChangeExchangeCoordinator(BiConsumer<Exchanger<Change[]>, Change[]> runner) {
|
||||
this.runnerTask = runner;
|
||||
this.exchanger = new Exchanger<>();
|
||||
}
|
||||
|
||||
public Change[] take(Change[] consumed) {
|
||||
if (!this.started) {
|
||||
this.started = true;
|
||||
final int length = consumed.length;
|
||||
this.runner = UNDO_VIRTUAL_THREAD_BUILDER
|
||||
.start(() -> this.runnerTask.accept(this.exchanger, new Change[length]));
|
||||
}
|
||||
try {
|
||||
// Allow a reasonable timeout in case of weirdness
|
||||
return exchanger.exchange(consumed, 30, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException | TimeoutException e) {
|
||||
this.runner.interrupt();
|
||||
Thread.currentThread().interrupt();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (this.runner != null) {
|
||||
this.runner.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package com.fastasyncworldedit.core.history.changeset;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.history.change.ChangePopulator;
|
||||
import com.fastasyncworldedit.core.history.change.MutableBiomeChange;
|
||||
import com.fastasyncworldedit.core.history.change.MutableBlockChange;
|
||||
import com.fastasyncworldedit.core.history.change.MutableEntityChange;
|
||||
@ -9,6 +10,7 @@ import com.fastasyncworldedit.core.history.change.MutableTileChange;
|
||||
import com.fastasyncworldedit.core.internal.exception.FaweSmallEditUnsupportedException;
|
||||
import com.fastasyncworldedit.core.internal.io.FaweInputStream;
|
||||
import com.fastasyncworldedit.core.internal.io.FaweOutputStream;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.util.MainUtil;
|
||||
import com.fastasyncworldedit.core.util.MathMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
@ -20,15 +22,22 @@ import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.Exchanger;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* FAWE stream ChangeSet offering support for extended-height worlds
|
||||
@ -390,56 +399,44 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTileCreate(CompoundTag tag) {
|
||||
if (tag == null) {
|
||||
return;
|
||||
}
|
||||
public void addTileCreate(final FaweCompoundTag tag) {
|
||||
blockSize++;
|
||||
try {
|
||||
NBTOutputStream nbtos = getTileCreateOS();
|
||||
nbtos.writeTag(tag);
|
||||
nbtos.writeTag(new CompoundTag(tag.linTag()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTileRemove(CompoundTag tag) {
|
||||
if (tag == null) {
|
||||
return;
|
||||
}
|
||||
public void addTileRemove(final FaweCompoundTag tag) {
|
||||
blockSize++;
|
||||
try {
|
||||
NBTOutputStream nbtos = getTileRemoveOS();
|
||||
nbtos.writeTag(tag);
|
||||
nbtos.writeTag(new CompoundTag(tag.linTag()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntityRemove(CompoundTag tag) {
|
||||
if (tag == null) {
|
||||
return;
|
||||
}
|
||||
public void addEntityRemove(final FaweCompoundTag tag) {
|
||||
blockSize++;
|
||||
try {
|
||||
NBTOutputStream nbtos = getEntityRemoveOS();
|
||||
nbtos.writeTag(tag);
|
||||
nbtos.writeTag(new CompoundTag(tag.linTag()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntityCreate(CompoundTag tag) {
|
||||
if (tag == null) {
|
||||
return;
|
||||
}
|
||||
public void addEntityCreate(final FaweCompoundTag tag) {
|
||||
blockSize++;
|
||||
try {
|
||||
NBTOutputStream nbtos = getEntityCreateOS();
|
||||
nbtos.writeTag(tag);
|
||||
nbtos.writeTag(new CompoundTag(tag.linTag()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -711,6 +708,284 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChangeExchangeCoordinator getCoordinatedChanges(BlockBag blockBag, int mode, boolean dir) {
|
||||
try {
|
||||
return coordinatedChanges(blockBag, mode, dir);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ChangeExchangeCoordinator coordinatedChanges(final BlockBag blockBag, final int mode, boolean dir) throws IOException {
|
||||
close();
|
||||
var tileCreate = tileChangePopulator(getTileCreateIS(), true);
|
||||
var tileRemove = tileChangePopulator(getTileRemoveIS(), false);
|
||||
|
||||
var entityCreate = entityChangePopulator(getEntityCreateIS(), true);
|
||||
var entityRemove = entityChangePopulator(getEntityRemoveIS(), false);
|
||||
|
||||
var blockChange = blockBag != null && mode > 0 ? fullBlockChangePopulator(blockBag, mode, dir) : blockChangePopulator(dir);
|
||||
|
||||
var biomeChange = biomeChangePopulator(dir);
|
||||
|
||||
Queue<ChangePopulator<?>> populators = new ArrayDeque<>(List.of(
|
||||
tileCreate,
|
||||
tileRemove,
|
||||
entityCreate,
|
||||
entityRemove,
|
||||
blockChange,
|
||||
biomeChange
|
||||
));
|
||||
BiConsumer<Exchanger<Change[]>, Change[]> task = (exchanger, array) -> {
|
||||
while (fillArray(array, populators)) {
|
||||
try {
|
||||
array = exchanger.exchange(array);
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
return new ChangeExchangeCoordinator(task);
|
||||
}
|
||||
|
||||
private boolean fillArray(Change[] changes, Queue<ChangePopulator<?>> populators) {
|
||||
ChangePopulator<?> populator = populators.peek();
|
||||
if (populator == null) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < changes.length; i++) {
|
||||
Change change = changes[i];
|
||||
do {
|
||||
change = populator.updateOrCreate(change);
|
||||
if (change == null) {
|
||||
populators.remove();
|
||||
populator = populators.peek();
|
||||
if (populator == null) {
|
||||
changes[i] = null; // mark end
|
||||
return true; // still needs to consume the elements of the current round
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
changes[i] = change;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static abstract class CompoundTagPopulator<C extends Change> implements ChangePopulator<C> {
|
||||
private final NBTInputStream inputStream;
|
||||
|
||||
private CompoundTagPopulator(final NBTInputStream stream) {
|
||||
inputStream = stream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable C populate(final @NotNull C change) {
|
||||
try {
|
||||
write(change, (CompoundTag) inputStream.readTag());
|
||||
return change;
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected abstract void write(C change, CompoundTag tag);
|
||||
}
|
||||
|
||||
private ChangePopulator<MutableTileChange> tileChangePopulator(NBTInputStream is, boolean create) {
|
||||
if (is == null) {
|
||||
return ChangePopulator.empty();
|
||||
}
|
||||
class Populator extends CompoundTagPopulator<MutableTileChange> {
|
||||
|
||||
private Populator() {
|
||||
super(is);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull MutableTileChange create() {
|
||||
return new MutableTileChange(null, create);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void write(final MutableTileChange change, final CompoundTag tag) {
|
||||
change.tag = tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accepts(final Change change) {
|
||||
return change instanceof MutableTileChange;
|
||||
}
|
||||
|
||||
}
|
||||
return new Populator();
|
||||
}
|
||||
private ChangePopulator<MutableEntityChange> entityChangePopulator(NBTInputStream is, boolean create) {
|
||||
if (is == null) {
|
||||
return ChangePopulator.empty();
|
||||
}
|
||||
class Populator extends CompoundTagPopulator<MutableEntityChange> {
|
||||
|
||||
private Populator() {
|
||||
super(is);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull MutableEntityChange create() {
|
||||
return new MutableEntityChange(null, create);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void write(final MutableEntityChange change, final CompoundTag tag) {
|
||||
change.tag = tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accepts(final Change change) {
|
||||
return change instanceof MutableTileChange;
|
||||
}
|
||||
|
||||
}
|
||||
return new Populator();
|
||||
}
|
||||
|
||||
private ChangePopulator<MutableFullBlockChange> fullBlockChangePopulator(BlockBag blockBag, int mode, boolean dir) throws
|
||||
IOException {
|
||||
final FaweInputStream is = getBlockIS();
|
||||
if (is == null) {
|
||||
return ChangePopulator.empty();
|
||||
}
|
||||
class Populator implements ChangePopulator<MutableFullBlockChange> {
|
||||
|
||||
@Override
|
||||
public @NotNull MutableFullBlockChange create() {
|
||||
return new MutableFullBlockChange(blockBag, mode, dir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable MutableFullBlockChange populate(@NotNull final MutableFullBlockChange change) {
|
||||
try {
|
||||
change.x = posDel.readX(is) + originX;
|
||||
change.y = posDel.readY(is);
|
||||
change.z = posDel.readZ(is) + originZ;
|
||||
idDel.readCombined(is, change);
|
||||
return change;
|
||||
} catch (EOFException ignored) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accepts(final Change change) {
|
||||
return change instanceof MutableFullBlockChange;
|
||||
}
|
||||
|
||||
}
|
||||
return new Populator();
|
||||
|
||||
}
|
||||
|
||||
private ChangePopulator<MutableBlockChange> blockChangePopulator(boolean dir) throws IOException {
|
||||
final FaweInputStream is = getBlockIS();
|
||||
if (is == null) {
|
||||
return ChangePopulator.empty();
|
||||
}
|
||||
class Populator implements ChangePopulator<MutableBlockChange> {
|
||||
|
||||
@Override
|
||||
public @NotNull MutableBlockChange create() {
|
||||
return new MutableBlockChange(0, 0, 0, BlockTypes.AIR.getInternalId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable MutableBlockChange populate(@NotNull final MutableBlockChange change) {
|
||||
try {
|
||||
change.x = posDel.readX(is) + originX;
|
||||
change.y = posDel.readY(is);
|
||||
change.z = posDel.readZ(is) + originZ;
|
||||
idDel.readCombined(is, change, dir);
|
||||
return change;
|
||||
} catch (EOFException ignored) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accepts(final Change change) {
|
||||
return change instanceof MutableBlockChange;
|
||||
}
|
||||
|
||||
}
|
||||
return new Populator();
|
||||
}
|
||||
|
||||
private ChangePopulator<MutableBiomeChange> biomeChangePopulator(boolean dir) throws IOException {
|
||||
final FaweInputStream is = getBiomeIS();
|
||||
if (is == null) {
|
||||
return ChangePopulator.empty();
|
||||
}
|
||||
class Populator implements ChangePopulator<MutableBiomeChange> {
|
||||
|
||||
@Override
|
||||
public @NotNull MutableBiomeChange create() {
|
||||
return new MutableBiomeChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable MutableBiomeChange populate(@NotNull final MutableBiomeChange change) {
|
||||
try {
|
||||
int int1 = is.read();
|
||||
if (int1 != -1) {
|
||||
int x = ((int1 << 24) + (is.read() << 16) + (is.read() << 8) + is.read()) << 2;
|
||||
int z = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + is.read()) << 2;
|
||||
int y = (is.read() - 128) << 2;
|
||||
int from = is.readVarInt();
|
||||
int to = is.readVarInt();
|
||||
change.setBiome(x, y, z, from, to);
|
||||
return change;
|
||||
}
|
||||
} catch (EOFException ignored) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accepts(final Change change) {
|
||||
return change instanceof MutableBiomeChange;
|
||||
}
|
||||
|
||||
}
|
||||
return new Populator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Change> getIterator(final boolean dir) {
|
||||
try {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.fastasyncworldedit.core.history.changeset;
|
||||
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
@ -25,22 +25,22 @@ public class NullChangeSet extends AbstractChangeSet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void addTileCreate(CompoundTag tag) {
|
||||
public void addTileCreate(final FaweCompoundTag tag) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void addTileRemove(CompoundTag tag) {
|
||||
public void addTileRemove(final FaweCompoundTag tag) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void addEntityRemove(CompoundTag tag) {
|
||||
public void addEntityRemove(final FaweCompoundTag tag) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void addEntityCreate(CompoundTag tag) {
|
||||
public void addEntityCreate(final FaweCompoundTag tag) {
|
||||
|
||||
}
|
||||
|
||||
@ -54,6 +54,17 @@ public class NullChangeSet extends AbstractChangeSet {
|
||||
return getIterator(redo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChangeExchangeCoordinator getCoordinatedChanges(final BlockBag blockBag, final int mode, final boolean dir) {
|
||||
return new ChangeExchangeCoordinator(((exchanger, changes) -> {
|
||||
try {
|
||||
exchanger.exchange(null);
|
||||
} catch (InterruptedException ignored) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Iterator<Change> getIterator(boolean undo) {
|
||||
return Collections.emptyIterator();
|
||||
|
@ -0,0 +1,115 @@
|
||||
package com.fastasyncworldedit.core.internal.simd;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.extent.filter.block.DelegateFilter;
|
||||
import com.fastasyncworldedit.core.function.mask.InverseMask;
|
||||
import com.fastasyncworldedit.core.function.mask.SingleBlockStateMask;
|
||||
import com.fastasyncworldedit.core.queue.Filter;
|
||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||
import com.sk89q.worldedit.function.mask.InverseSingleBlockStateMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
import jdk.incubator.vector.ShortVector;
|
||||
import jdk.incubator.vector.VectorOperators;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class SimdSupport {
|
||||
|
||||
private static final boolean VECTOR_API_PRESENT;
|
||||
|
||||
static {
|
||||
boolean vectorApiPresent = false;
|
||||
try {
|
||||
Class.forName("jdk.incubator.vector.Vector");
|
||||
vectorApiPresent = true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
VECTOR_API_PRESENT = vectorApiPresent;
|
||||
if (!VECTOR_API_PRESENT && Settings.settings().EXPERIMENTAL.USE_VECTOR_API) {
|
||||
LogManagerCompat.getLogger()
|
||||
.warn("FAWE use-vector-api is enabled but --add-modules=jdk.incubator.vector is not set.");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean useVectorApi() {
|
||||
return VECTOR_API_PRESENT && Settings.settings().EXPERIMENTAL.USE_VECTOR_API;
|
||||
}
|
||||
|
||||
public static @Nullable VectorizedMask vectorizedTargetMask(Mask mask) {
|
||||
if (!useVectorApi()) {
|
||||
return null;
|
||||
}
|
||||
return switch (mask) {
|
||||
case SingleBlockStateMask single -> vectorizedTargetMask(single.getBlockState().getOrdinalChar());
|
||||
case InverseSingleBlockStateMask inverse -> vectorizedTargetMaskInverse(inverse.getBlockState().getOrdinalChar());
|
||||
case ExistingBlockMask ignored -> vectorizedTargetMaskNonAir();
|
||||
case InverseMask inverse -> {
|
||||
final VectorizedMask base = vectorizedTargetMask(inverse.inverse());
|
||||
if (base == null) {
|
||||
yield null;
|
||||
}
|
||||
yield (set, get) -> base.compareVector(set, get).not();
|
||||
}
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private static VectorizedMask vectorizedTargetMaskNonAir() {
|
||||
// everything > VOID_AIR is not air
|
||||
return (set, get) -> get.compare(VectorOperators.UNSIGNED_GT, BlockTypesCache.ReservedIDs.VOID_AIR);
|
||||
}
|
||||
|
||||
private static VectorizedMask vectorizedTargetMask(char ordinal) {
|
||||
return (set, get) -> get.compare(VectorOperators.EQ, (short) ordinal);
|
||||
}
|
||||
|
||||
private static VectorizedMask vectorizedTargetMaskInverse(char ordinal) {
|
||||
return (set, get) -> get.compare(VectorOperators.NE, (short) ordinal);
|
||||
}
|
||||
|
||||
public static @Nullable VectorizedFilter vectorizedPattern(Pattern pattern) {
|
||||
if (!useVectorApi()) {
|
||||
return null;
|
||||
}
|
||||
return switch (pattern) {
|
||||
case BaseBlock block -> {
|
||||
if (block.getNbtReference() == null) {
|
||||
yield new VectorizedPattern<>(block, block.getOrdinalChar());
|
||||
}
|
||||
yield null;
|
||||
}
|
||||
case BlockStateHolder<?> blockStateHolder -> new VectorizedPattern<>(
|
||||
blockStateHolder,
|
||||
blockStateHolder.getOrdinalChar()
|
||||
);
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private static final class VectorizedPattern<T extends Filter> extends DelegateFilter<T> implements VectorizedFilter {
|
||||
|
||||
private final char ordinal;
|
||||
|
||||
public VectorizedPattern(final T parent, char ordinal) {
|
||||
super(parent);
|
||||
this.ordinal = ordinal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShortVector applyVector(final ShortVector get, final ShortVector set) {
|
||||
return ShortVector.broadcast(ShortVector.SPECIES_PREFERRED, ordinal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter newInstance(final Filter other) {
|
||||
return new VectorizedPattern<>(other, ordinal);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.fastasyncworldedit.core.internal.simd;
|
||||
|
||||
import com.fastasyncworldedit.core.extent.filter.block.CharFilterBlock;
|
||||
import com.fastasyncworldedit.core.queue.Filter;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import jdk.incubator.vector.ShortVector;
|
||||
import jdk.incubator.vector.VectorSpecies;
|
||||
|
||||
public class VectorizedCharFilterBlock extends CharFilterBlock {
|
||||
|
||||
public VectorizedCharFilterBlock(final Extent extent) {
|
||||
super(extent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void filter(final Filter filter) {
|
||||
if (!(filter instanceof VectorizedFilter vecFilter)) {
|
||||
throw new IllegalStateException("Unexpected VectorizedCharFilterBlock " + filter);
|
||||
}
|
||||
final VectorSpecies<Short> species = ShortVector.SPECIES_PREFERRED;
|
||||
initSet(); // set array is null before
|
||||
char[] setArr = this.setArr;
|
||||
assert setArr != null;
|
||||
char[] getArr = this.getArr;
|
||||
// assume setArr.length == getArr.length == 4096
|
||||
for (int i = 0; i < 4096; i += species.length()) {
|
||||
ShortVector set = ShortVector.fromCharArray(species, setArr, i);
|
||||
ShortVector get = ShortVector.fromCharArray(species, getArr, i);
|
||||
ShortVector res = vecFilter.applyVector(get, set);
|
||||
res.intoCharArray(setArr, i);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.fastasyncworldedit.core.internal.simd;
|
||||
|
||||
import com.fastasyncworldedit.core.queue.Filter;
|
||||
import jdk.incubator.vector.ShortVector;
|
||||
|
||||
public interface VectorizedFilter extends Filter {
|
||||
ShortVector applyVector(ShortVector get, ShortVector set);
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.fastasyncworldedit.core.internal.simd;
|
||||
|
||||
import com.fastasyncworldedit.core.queue.IChunk;
|
||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||
import jdk.incubator.vector.ShortVector;
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorSpecies;
|
||||
|
||||
public interface VectorizedMask {
|
||||
|
||||
default void processChunks(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||
for (int layer = get.getMinSectionPosition(); layer <= get.getMaxSectionPosition(); layer++) {
|
||||
final char[] sectionSet = set.loadIfPresent(layer);
|
||||
if (sectionSet == null) {
|
||||
continue;
|
||||
}
|
||||
final char[] sectionGet = get.load(layer);
|
||||
processSection(layer, sectionSet, sectionGet);
|
||||
}
|
||||
}
|
||||
|
||||
default void processSection(int layer, char[] set, char[] get) {
|
||||
final VectorSpecies<Short> species = ShortVector.SPECIES_PREFERRED;
|
||||
// assume that set.length % species.elementSize() == 0
|
||||
for (int i = 0; i < set.length; i += species.length()) {
|
||||
ShortVector vectorSet = ShortVector.fromCharArray(species, set, i);
|
||||
ShortVector vectorGet = ShortVector.fromCharArray(species, get, i);
|
||||
vectorSet = processVector(vectorSet, vectorGet);
|
||||
vectorSet.intoCharArray(set, i);
|
||||
}
|
||||
}
|
||||
|
||||
default ShortVector processVector(ShortVector set, ShortVector get) {
|
||||
return set.blend(0, compareVector(set, get).not());
|
||||
}
|
||||
|
||||
VectorMask<Short> compareVector(ShortVector set, ShortVector get);
|
||||
|
||||
}
|
@ -5,16 +5,18 @@ import com.fastasyncworldedit.core.configuration.Settings;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class FaweLimit {
|
||||
|
||||
public int MAX_ACTIONS = 0;
|
||||
public long MAX_CHANGES = 0;
|
||||
public int MAX_FAILS = 0;
|
||||
public long MAX_CHECKS = 0;
|
||||
public int MAX_ITERATIONS = 0;
|
||||
public int MAX_BLOCKSTATES = 0;
|
||||
public int MAX_ENTITIES = 0;
|
||||
public AtomicLong MAX_CHANGES = new AtomicLong();
|
||||
public AtomicInteger MAX_FAILS = new AtomicInteger();
|
||||
public AtomicLong MAX_CHECKS = new AtomicLong();
|
||||
public AtomicInteger MAX_ITERATIONS = new AtomicInteger();
|
||||
public AtomicInteger MAX_BLOCKSTATES = new AtomicInteger();
|
||||
public AtomicInteger MAX_ENTITIES = new AtomicInteger();
|
||||
public int MAX_HISTORY = 0;
|
||||
public int SCHEM_FILE_SIZE_LIMIT = 0;
|
||||
public int SCHEM_FILE_NUM_LIMIT = 0;
|
||||
@ -112,12 +114,12 @@ public class FaweLimit {
|
||||
MAX.SPEED_REDUCTION = 0;
|
||||
MAX.INVENTORY_MODE = 0;
|
||||
MAX.MAX_ACTIONS = 1;
|
||||
MAX.MAX_CHANGES = Long.MAX_VALUE;
|
||||
MAX.MAX_FAILS = Integer.MAX_VALUE;
|
||||
MAX.MAX_CHECKS = Long.MAX_VALUE;
|
||||
MAX.MAX_ITERATIONS = Integer.MAX_VALUE;
|
||||
MAX.MAX_BLOCKSTATES = Integer.MAX_VALUE;
|
||||
MAX.MAX_ENTITIES = Integer.MAX_VALUE;
|
||||
MAX.MAX_CHANGES = new AtomicLong(Long.MAX_VALUE);
|
||||
MAX.MAX_FAILS = new AtomicInteger(Integer.MAX_VALUE);
|
||||
MAX.MAX_CHECKS = new AtomicLong(Long.MAX_VALUE);
|
||||
MAX.MAX_ITERATIONS = new AtomicInteger(Integer.MAX_VALUE);
|
||||
MAX.MAX_BLOCKSTATES = new AtomicInteger(Integer.MAX_VALUE);
|
||||
MAX.MAX_ENTITIES = new AtomicInteger(Integer.MAX_VALUE);
|
||||
MAX.MAX_HISTORY = Integer.MAX_VALUE;
|
||||
MAX.SCHEM_FILE_NUM_LIMIT = Integer.MAX_VALUE;
|
||||
MAX.SCHEM_FILE_SIZE_LIMIT = Integer.MAX_VALUE;
|
||||
@ -138,120 +140,144 @@ public class FaweLimit {
|
||||
}
|
||||
|
||||
public boolean MAX_CHANGES() {
|
||||
return MAX_CHANGES-- > 0;
|
||||
return MAX_CHANGES.decrementAndGet() < 0;
|
||||
}
|
||||
|
||||
public boolean MAX_FAILS() {
|
||||
return MAX_FAILS-- > 0;
|
||||
return MAX_FAILS.decrementAndGet() < 0;
|
||||
}
|
||||
|
||||
public boolean MAX_CHECKS() {
|
||||
return MAX_CHECKS-- > 0;
|
||||
return MAX_CHECKS.decrementAndGet() < 0;
|
||||
}
|
||||
|
||||
public boolean MAX_ITERATIONS() {
|
||||
return MAX_ITERATIONS-- > 0;
|
||||
return MAX_ITERATIONS.decrementAndGet() < 0;
|
||||
}
|
||||
|
||||
public boolean MAX_BLOCKSTATES() {
|
||||
return MAX_BLOCKSTATES-- > 0;
|
||||
return MAX_BLOCKSTATES.decrementAndGet() < 0;
|
||||
}
|
||||
|
||||
public boolean MAX_ENTITIES() {
|
||||
return MAX_ENTITIES-- > 0;
|
||||
return MAX_ENTITIES.decrementAndGet() < 0;
|
||||
}
|
||||
|
||||
public void THROW_MAX_CHANGES() {
|
||||
if (MAX_CHANGES-- <= 0) {
|
||||
if (MAX_CHANGES.decrementAndGet() < 0) {
|
||||
throw FaweCache.MAX_CHANGES;
|
||||
}
|
||||
}
|
||||
|
||||
public void THROW_MAX_FAILS() {
|
||||
if (MAX_FAILS-- <= 0) {
|
||||
throw FaweCache.MAX_CHECKS;
|
||||
if (MAX_FAILS.decrementAndGet() < 0) {
|
||||
throw FaweCache.MAX_FAILS;
|
||||
}
|
||||
}
|
||||
|
||||
public void THROW_MAX_CHECKS() {
|
||||
if (MAX_CHECKS-- <= 0) {
|
||||
if (MAX_CHECKS.decrementAndGet() < 0) {
|
||||
throw FaweCache.MAX_CHECKS;
|
||||
}
|
||||
}
|
||||
|
||||
public void THROW_MAX_ITERATIONS() {
|
||||
if (MAX_ITERATIONS-- <= 0) {
|
||||
if (MAX_ITERATIONS.decrementAndGet() < 0) {
|
||||
throw FaweCache.MAX_ITERATIONS;
|
||||
}
|
||||
}
|
||||
|
||||
public void THROW_MAX_BLOCKSTATES() {
|
||||
if (MAX_BLOCKSTATES-- <= 0) {
|
||||
if (MAX_BLOCKSTATES.decrementAndGet() < 0) {
|
||||
throw FaweCache.MAX_TILES;
|
||||
}
|
||||
}
|
||||
|
||||
public void THROW_MAX_ENTITIES() {
|
||||
if (MAX_ENTITIES-- <= 0) {
|
||||
if (MAX_ENTITIES.decrementAndGet() < 0) {
|
||||
throw FaweCache.MAX_ENTITIES;
|
||||
}
|
||||
}
|
||||
|
||||
public void THROW_MAX_CHANGES(int amt) {
|
||||
if ((MAX_CHANGES -= amt) <= 0) {
|
||||
if (amt == 0) {
|
||||
return;
|
||||
}
|
||||
if (MAX_CHANGES.addAndGet(-amt) < 0) {
|
||||
throw FaweCache.MAX_CHANGES;
|
||||
}
|
||||
}
|
||||
|
||||
public void THROW_MAX_CHANGES(long amt) {
|
||||
if ((MAX_CHANGES -= amt) <= 0) {
|
||||
if (amt == 0) {
|
||||
return;
|
||||
}
|
||||
if (MAX_CHANGES.addAndGet(-amt) < 0) {
|
||||
throw FaweCache.MAX_CHANGES;
|
||||
}
|
||||
}
|
||||
|
||||
public void THROW_MAX_FAILS(int amt) {
|
||||
if ((MAX_FAILS -= amt) <= 0) {
|
||||
throw FaweCache.MAX_CHECKS;
|
||||
if (amt == 0) {
|
||||
return;
|
||||
}
|
||||
if (MAX_FAILS.addAndGet(-amt) < 0) {
|
||||
throw FaweCache.MAX_FAILS;
|
||||
}
|
||||
}
|
||||
|
||||
public void THROW_MAX_CHECKS(int amt) {
|
||||
if ((MAX_CHECKS -= amt) <= 0) {
|
||||
if (amt == 0) {
|
||||
return;
|
||||
}
|
||||
if (MAX_CHECKS.addAndGet(-amt) < 0) {
|
||||
throw FaweCache.MAX_CHECKS;
|
||||
}
|
||||
}
|
||||
|
||||
public void THROW_MAX_CHECKS(long amt) {
|
||||
if ((MAX_CHECKS -= amt) <= 0) {
|
||||
if (amt == 0) {
|
||||
return;
|
||||
}
|
||||
if (MAX_CHECKS.addAndGet(-amt) < 0) {
|
||||
throw FaweCache.MAX_CHECKS;
|
||||
}
|
||||
}
|
||||
|
||||
public void THROW_MAX_ITERATIONS(int amt) {
|
||||
if ((MAX_ITERATIONS -= amt) <= 0) {
|
||||
if (amt == 0) {
|
||||
return;
|
||||
}
|
||||
if (MAX_ITERATIONS.addAndGet(-amt) < 0) {
|
||||
throw FaweCache.MAX_ITERATIONS;
|
||||
}
|
||||
}
|
||||
|
||||
public void THROW_MAX_BLOCKSTATES(int amt) {
|
||||
if ((MAX_BLOCKSTATES -= amt) <= 0) {
|
||||
if (amt == 0) {
|
||||
return;
|
||||
}
|
||||
if (MAX_BLOCKSTATES.addAndGet(-amt) < 0) {
|
||||
throw FaweCache.MAX_TILES;
|
||||
}
|
||||
}
|
||||
|
||||
public void THROW_MAX_ENTITIES(int amt) {
|
||||
if ((MAX_ENTITIES -= amt) <= 0) {
|
||||
if (amt == 0) {
|
||||
return;
|
||||
}
|
||||
if (MAX_ENTITIES.addAndGet(-amt) < 0) {
|
||||
throw FaweCache.MAX_ENTITIES;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUnlimited() {
|
||||
return MAX_CHANGES == Long.MAX_VALUE
|
||||
&& MAX_FAILS == Integer.MAX_VALUE
|
||||
&& MAX_CHECKS == Long.MAX_VALUE
|
||||
&& MAX_ITERATIONS == Integer.MAX_VALUE
|
||||
&& MAX_BLOCKSTATES == Integer.MAX_VALUE
|
||||
&& MAX_ENTITIES == Integer.MAX_VALUE
|
||||
return MAX_CHANGES.get() == Long.MAX_VALUE
|
||||
&& MAX_FAILS.get() == Integer.MAX_VALUE
|
||||
&& MAX_CHECKS.get() == Long.MAX_VALUE
|
||||
&& MAX_ITERATIONS.get() == Integer.MAX_VALUE
|
||||
&& MAX_BLOCKSTATES.get() == Integer.MAX_VALUE
|
||||
&& MAX_ENTITIES.get() == Integer.MAX_VALUE
|
||||
&& MAX_HISTORY == Integer.MAX_VALUE
|
||||
&& SCHEM_FILE_SIZE_LIMIT == Integer.MAX_VALUE
|
||||
&& SCHEM_FILE_NUM_LIMIT == Integer.MAX_VALUE
|
||||
@ -270,14 +296,30 @@ public class FaweLimit {
|
||||
&& MAX_BUTCHER_RADIUS == Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an {@link FaweLimit} representing the amount of a limit used from a given "original" limit
|
||||
*
|
||||
* @since TODO
|
||||
*/
|
||||
public FaweLimit getLimitUsed(FaweLimit originalLimit) {
|
||||
FaweLimit newLimit = new FaweLimit();
|
||||
newLimit.MAX_CHANGES = new AtomicLong(originalLimit.MAX_CHANGES.get() - this.MAX_CHANGES.get());
|
||||
newLimit.MAX_FAILS = new AtomicInteger(originalLimit.MAX_FAILS.get() - this.MAX_FAILS.get());
|
||||
newLimit.MAX_CHECKS = new AtomicLong(originalLimit.MAX_CHECKS.get() - this.MAX_CHECKS.get());
|
||||
newLimit.MAX_ITERATIONS = new AtomicInteger(originalLimit.MAX_ITERATIONS.get() - this.MAX_ITERATIONS.get());
|
||||
newLimit.MAX_BLOCKSTATES = new AtomicInteger(originalLimit.MAX_BLOCKSTATES.get() - this.MAX_BLOCKSTATES.get());
|
||||
newLimit.MAX_ENTITIES = new AtomicInteger(originalLimit.MAX_ENTITIES.get() - this.MAX_ENTITIES.get());
|
||||
return newLimit;
|
||||
}
|
||||
|
||||
public void set(FaweLimit limit) {
|
||||
MAX_ACTIONS = limit.MAX_ACTIONS;
|
||||
MAX_CHANGES = limit.MAX_CHANGES;
|
||||
MAX_BLOCKSTATES = limit.MAX_BLOCKSTATES;
|
||||
MAX_CHECKS = limit.MAX_CHECKS;
|
||||
MAX_ENTITIES = limit.MAX_ENTITIES;
|
||||
MAX_FAILS = limit.MAX_FAILS;
|
||||
MAX_ITERATIONS = limit.MAX_ITERATIONS;
|
||||
MAX_CHANGES.set(limit.MAX_CHANGES.get());
|
||||
MAX_FAILS.set(limit.MAX_FAILS.get());
|
||||
MAX_CHECKS.set(limit.MAX_CHECKS.get());
|
||||
MAX_ITERATIONS.set(limit.MAX_ITERATIONS.get());
|
||||
MAX_BLOCKSTATES.set(limit.MAX_BLOCKSTATES.get());
|
||||
MAX_ENTITIES.set(limit.MAX_ENTITIES.get());
|
||||
MAX_HISTORY = limit.MAX_HISTORY;
|
||||
SCHEM_FILE_NUM_LIMIT = limit.SCHEM_FILE_NUM_LIMIT;
|
||||
SCHEM_FILE_SIZE_LIMIT = limit.SCHEM_FILE_SIZE_LIMIT;
|
||||
|
@ -4,7 +4,9 @@ public record IntPair(int x, int z) {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (x << 16) | (z & 0xFFFF);
|
||||
int i = 1664525 * x + 1013904223;
|
||||
int j = 1664525 * (z ^ -559038737) + 1013904223;
|
||||
return i ^ j;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,7 @@
|
||||
package com.fastasyncworldedit.core.nbt;
|
||||
|
||||
import org.enginehub.linbus.tree.LinCompoundTag;
|
||||
|
||||
record EagerFaweCompoundTag(LinCompoundTag linTag) implements FaweCompoundTag {
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.fastasyncworldedit.core.nbt;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.sk89q.worldedit.util.concurrency.LazyReference;
|
||||
import org.enginehub.linbus.tree.LinCompoundTag;
|
||||
|
||||
/**
|
||||
* A wrapper around compound tags, potentially lazily transformed.
|
||||
* @since 2.11.2
|
||||
*/
|
||||
public sealed interface FaweCompoundTag permits EagerFaweCompoundTag, LazyFaweCompoundTag {
|
||||
|
||||
/**
|
||||
* {@return a lazy compound component backed by a lazy reference}
|
||||
* @param lazyReference the lazy reference to the actual compound tag
|
||||
*/
|
||||
static FaweCompoundTag of(LazyReference<? extends LinCompoundTag> lazyReference) {
|
||||
return new LazyFaweCompoundTag(lazyReference::getValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a lazy compound component backed by a supplier}
|
||||
* Invocations to the supplier are memoized.
|
||||
* @param supplier the supplier for the actual compound tag
|
||||
*/
|
||||
static FaweCompoundTag of(Supplier<? extends LinCompoundTag> supplier) {
|
||||
return new LazyFaweCompoundTag(Suppliers.memoize(supplier));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a direct reference tho the given compound tag}
|
||||
* @param linCompoundTag the tag to wrap
|
||||
*/
|
||||
static FaweCompoundTag of(LinCompoundTag linCompoundTag) {
|
||||
return new EagerFaweCompoundTag(linCompoundTag);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the underlying tag}
|
||||
*/
|
||||
LinCompoundTag linTag();
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.fastasyncworldedit.core.nbt;
|
||||
|
||||
import org.enginehub.linbus.tree.LinCompoundTag;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
record LazyFaweCompoundTag(Supplier<? extends LinCompoundTag> linTagSupplier) implements FaweCompoundTag {
|
||||
|
||||
@Override
|
||||
public LinCompoundTag linTag() {
|
||||
return this.linTagSupplier().get();
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ package com.fastasyncworldedit.core.queue;
|
||||
import com.fastasyncworldedit.core.extent.filter.block.FilterBlock;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
@ -10,30 +11,29 @@ import javax.annotation.Nullable;
|
||||
*/
|
||||
public interface Filter {
|
||||
|
||||
/**
|
||||
* Checks whether a chunk should be read.
|
||||
*
|
||||
* @param chunkX the x coordinate in the chunk
|
||||
* @param chunkZ the z coordinate in the chunk
|
||||
*/
|
||||
default boolean appliesChunk(
|
||||
int chunkX,
|
||||
int chunkZ
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
// /**
|
||||
// * Checks whether a chunk should be read.
|
||||
// *
|
||||
// * @param chunkX the x coordinate in the chunk
|
||||
// * @param chunkZ the z coordinate in the chunk
|
||||
// */
|
||||
// default boolean appliesChunk(
|
||||
// int chunkX,
|
||||
// int chunkZ
|
||||
// ) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Do something with the IChunk<br> - Return null if you don't want to filter blocks<br> -
|
||||
* Return the chunk if you do want to filter blocks<br>
|
||||
* Do something with the IChunk<br>
|
||||
*/
|
||||
default <T extends IChunk> T applyChunk(T chunk, @Nullable Region region) {
|
||||
default @Nonnull <T extends IChunk> T applyChunk(T chunk, @Nullable Region region) {
|
||||
return chunk;
|
||||
}
|
||||
|
||||
default boolean appliesLayer(IChunk chunk, int layer) {
|
||||
return true;
|
||||
}
|
||||
// default boolean appliesLayer(IChunk chunk, int layer) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Make changes to the block here<br> - e.g., block.setId(...)<br> - Note: Performance is
|
||||
|
@ -3,15 +3,16 @@ package com.fastasyncworldedit.core.queue;
|
||||
import com.fastasyncworldedit.core.extent.processor.EmptyBatchProcessor;
|
||||
import com.fastasyncworldedit.core.extent.processor.MultiBatchProcessor;
|
||||
import com.fastasyncworldedit.core.extent.processor.ProcessorScope;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.util.NbtUtils;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Function;
|
||||
@ -50,7 +51,7 @@ public interface IBatchProcessor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this processor into an Extent based processor instead of a queue batch based on.
|
||||
* Convert this processor into an Extent based processor instead of a queue batch based one.
|
||||
*/
|
||||
@Nullable
|
||||
Extent construct(Extent child);
|
||||
@ -62,40 +63,41 @@ public interface IBatchProcessor {
|
||||
* @return false if chunk is empty of blocks
|
||||
*/
|
||||
default boolean trimY(IChunkSet set, int minY, int maxY, final boolean keepInsideRange) {
|
||||
int minLayer = (minY - 1) >> 4;
|
||||
int maxLayer = (maxY + 1) >> 4;
|
||||
int minLayer = minY >> 4;
|
||||
int maxLayer = maxY >> 4;
|
||||
if (keepInsideRange) {
|
||||
for (int layer = set.getMinSectionPosition(); layer <= minLayer; layer++) {
|
||||
if (set.hasSection(layer)) {
|
||||
if (layer == minLayer) {
|
||||
char[] arr = set.loadIfPresent(layer);
|
||||
if (arr != null) {
|
||||
int index = (minY & 15) << 8;
|
||||
for (int i = 0; i < index; i++) {
|
||||
arr[i] = BlockTypesCache.ReservedIDs.__RESERVED__;
|
||||
}
|
||||
set.setBlocks(layer, arr);
|
||||
}
|
||||
} else {
|
||||
set.setBlocks(layer, null);
|
||||
for (int layer = set.getMinSectionPosition(); layer <= set.getMaxSectionPosition(); layer++) {
|
||||
if (!set.hasSection(layer)) {
|
||||
continue;
|
||||
}
|
||||
// wipe all data from chunk layers above or below the max / min layer
|
||||
if (layer < minLayer || layer > maxLayer) {
|
||||
set.setBlocks(layer, null);
|
||||
continue;
|
||||
}
|
||||
// if chunk layer / section is fully enclosed by minY to maxY, keep as is
|
||||
if (layer > minLayer && layer < maxLayer) {
|
||||
continue;
|
||||
}
|
||||
char[] blocks = set.loadIfPresent(layer);
|
||||
if (blocks == null) {
|
||||
continue;
|
||||
}
|
||||
// When on the minimum layer (as defined by minY), remove blocks up to minY (exclusive)
|
||||
if (layer == minLayer) {
|
||||
int index = (minY & 15) << 8;
|
||||
for (int i = 0; i < index; i++) {
|
||||
blocks[i] = BlockTypesCache.ReservedIDs.__RESERVED__;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int layer = maxLayer; layer <= set.getMaxSectionPosition(); layer++) {
|
||||
if (set.hasSection(layer)) {
|
||||
if (layer == maxLayer) {
|
||||
char[] arr = set.loadIfPresent(layer);
|
||||
if (arr != null) {
|
||||
int index = ((maxY + 1) & 15) << 8;
|
||||
for (int i = index; i < arr.length; i++) {
|
||||
arr[i] = BlockTypesCache.ReservedIDs.__RESERVED__;
|
||||
}
|
||||
set.setBlocks(layer, arr);
|
||||
}
|
||||
} else {
|
||||
set.setBlocks(layer, null);
|
||||
// When on the maximum layer (as defined by maxY), remove blocks above maxY (exclusive)
|
||||
if (layer == maxLayer) {
|
||||
int index = ((maxY & 15) + 1) << 8;
|
||||
for (int i = index; i < blocks.length; i++) {
|
||||
blocks[i] = BlockTypesCache.ReservedIDs.__RESERVED__;
|
||||
}
|
||||
}
|
||||
set.setBlocks(layer, blocks);
|
||||
}
|
||||
try {
|
||||
int layer = (minY - 15) >> 4;
|
||||
@ -155,11 +157,11 @@ public interface IBatchProcessor {
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "2.8.4")
|
||||
default boolean trimNBT(IChunkSet set, Function<BlockVector3, Boolean> contains) {
|
||||
Set<CompoundTag> ents = set.getEntities();
|
||||
Collection<FaweCompoundTag> ents = set.entities();
|
||||
if (!ents.isEmpty()) {
|
||||
ents.removeIf(ent -> !contains.apply(ent.getEntityPosition().toBlockPoint()));
|
||||
ents.removeIf(ent -> !contains.apply(NbtUtils.entityPosition(ent).toBlockPoint()));
|
||||
}
|
||||
Map<BlockVector3, CompoundTag> tiles = set.getTiles();
|
||||
Map<BlockVector3, FaweCompoundTag> tiles = set.tiles();
|
||||
if (!tiles.isEmpty()) {
|
||||
tiles.entrySet().removeIf(blockVector3CompoundTagEntry -> !contains
|
||||
.apply(blockVector3CompoundTagEntry.getKey()));
|
||||
@ -176,11 +178,11 @@ public interface IBatchProcessor {
|
||||
default boolean trimNBT(
|
||||
IChunkSet set, Function<BlockVector3, Boolean> containsEntity, Function<BlockVector3, Boolean> containsTile
|
||||
) {
|
||||
Set<CompoundTag> ents = set.getEntities();
|
||||
Collection<FaweCompoundTag> ents = set.entities();
|
||||
if (!ents.isEmpty()) {
|
||||
ents.removeIf(ent -> !containsEntity.apply(ent.getEntityPosition().toBlockPoint()));
|
||||
ents.removeIf(ent -> !containsEntity.apply(NbtUtils.entityPosition(ent).toBlockPoint()));
|
||||
}
|
||||
Map<BlockVector3, CompoundTag> tiles = set.getTiles();
|
||||
Map<BlockVector3, FaweCompoundTag> tiles = set.tiles();
|
||||
if (!tiles.isEmpty()) {
|
||||
tiles.entrySet().removeIf(blockVector3CompoundTagEntry -> !containsTile.apply(blockVector3CompoundTagEntry.getKey()));
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package com.fastasyncworldedit.core.queue;
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.internal.io.FastByteArrayOutputStream;
|
||||
import com.fastasyncworldedit.core.internal.io.FaweOutputStream;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.util.collection.AdaptedMap;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
@ -12,10 +14,13 @@ import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
import com.sk89q.worldedit.world.registry.BlockRegistry;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
@ -54,11 +59,38 @@ public interface IBlocks extends Trimable {
|
||||
|
||||
BlockState getBlock(int x, int y, int z);
|
||||
|
||||
Map<BlockVector3, CompoundTag> getTiles();
|
||||
@Deprecated(forRemoval = true, since = "2.11.2")
|
||||
default Map<BlockVector3, CompoundTag> getTiles() {
|
||||
return AdaptedMap.values(tiles(), ct -> FaweCompoundTag.of(ct.toLinTag()), IBlocks::toCompoundTag);
|
||||
}
|
||||
|
||||
CompoundTag getTile(int x, int y, int z);
|
||||
Map<BlockVector3, FaweCompoundTag> tiles();
|
||||
|
||||
Set<CompoundTag> getEntities();
|
||||
@Deprecated(forRemoval = true, since = "2.11.2")
|
||||
default CompoundTag getTile(int x, int y, int z) {
|
||||
final FaweCompoundTag tile = tile(x, y, z);
|
||||
if (tile == null) {
|
||||
return null;
|
||||
}
|
||||
return toCompoundTag(tile);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation"})
|
||||
private static @Nonnull CompoundTag toCompoundTag(FaweCompoundTag tile) {
|
||||
return new CompoundTag(tile.linTag());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
FaweCompoundTag tile(int x, int y, int z);
|
||||
|
||||
@Deprecated(forRemoval = true, since = "2.11.2")
|
||||
default Set<CompoundTag> getEntities() {
|
||||
return entities().stream()
|
||||
.map(IBlocks::toCompoundTag)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
Collection<FaweCompoundTag> entities();
|
||||
|
||||
BiomeType getBiomeType(int x, int y, int z);
|
||||
|
||||
|
@ -1,11 +1,7 @@
|
||||
package com.fastasyncworldedit.core.queue;
|
||||
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.DoubleTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.NBTUtils;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.util.NbtUtils;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
@ -16,6 +12,12 @@ 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 org.enginehub.linbus.tree.LinCompoundTag;
|
||||
import org.enginehub.linbus.tree.LinDoubleTag;
|
||||
import org.enginehub.linbus.tree.LinListTag;
|
||||
import org.enginehub.linbus.tree.LinStringTag;
|
||||
import org.enginehub.linbus.tree.LinTag;
|
||||
import org.enginehub.linbus.tree.LinTagType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -39,9 +41,9 @@ public interface IChunkExtent<T extends IChunk> extends Extent {
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
|
||||
default boolean tile(int x, int y, int z, FaweCompoundTag tile) throws WorldEditException {
|
||||
final IChunk chunk = getOrCreateChunk(x >> 4, z >> 4);
|
||||
return chunk.setTile(x & 15, y, z & 15, tile);
|
||||
return chunk.tile(x & 15, y, z & 15, tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -124,19 +126,19 @@ public interface IChunkExtent<T extends IChunk> extends Extent {
|
||||
@Override
|
||||
default Entity createEntity(Location location, BaseEntity entity, UUID uuid) {
|
||||
final IChunk chunk = getOrCreateChunk(location.getBlockX() >> 4, location.getBlockZ() >> 4);
|
||||
Map<String, Tag<?, ?>> map = new HashMap<>(entity.getNbtData().getValue()); //do not modify original entity data
|
||||
map.put("Id", new StringTag(entity.getType().getName()));
|
||||
Map<String, LinTag<?>> map = new HashMap<>(entity.getNbt().value()); //do not modify original entity data
|
||||
map.put("Id", LinStringTag.of(entity.getType().getName()));
|
||||
|
||||
//Set pos
|
||||
List<DoubleTag> posList = new ArrayList<>();
|
||||
posList.add(new DoubleTag(location.x()));
|
||||
posList.add(new DoubleTag(location.y()));
|
||||
posList.add(new DoubleTag(location.z()));
|
||||
map.put("Pos", new ListTag(DoubleTag.class, posList));
|
||||
List<LinDoubleTag> posList = new ArrayList<>();
|
||||
posList.add(LinDoubleTag.of(location.x()));
|
||||
posList.add(LinDoubleTag.of(location.y()));
|
||||
posList.add(LinDoubleTag.of(location.z()));
|
||||
map.put("Pos", LinListTag.of(LinTagType.doubleTag(), posList));
|
||||
|
||||
NBTUtils.addUUIDToMap(map, uuid);
|
||||
NbtUtils.addUUIDToMap(map, uuid);
|
||||
|
||||
chunk.setEntity(new CompoundTag(map));
|
||||
chunk.entity(FaweCompoundTag.of(LinCompoundTag.of(map)));
|
||||
return new IChunkEntity(this, location, uuid, entity);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.fastasyncworldedit.core.queue;
|
||||
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.extent.InputExtent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
@ -46,7 +47,26 @@ public interface IChunkGet extends IBlocks, Trimable, InputExtent, ITileInput {
|
||||
|
||||
<T extends Future<T>> T call(IChunkSet set, Runnable finalize);
|
||||
|
||||
CompoundTag getEntity(UUID uuid);
|
||||
@Deprecated(forRemoval = true, since = "2.11.2")
|
||||
default CompoundTag getEntity(UUID uuid) {
|
||||
final FaweCompoundTag entity = entity(uuid);
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
return new CompoundTag(entity.linTag());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the compound tag describing the entity with the given UUID, if any}
|
||||
* @param uuid the uuid of the entity
|
||||
*/
|
||||
@Nullable FaweCompoundTag entity(UUID uuid);
|
||||
|
||||
@Override
|
||||
@Deprecated(forRemoval = true, since = "2.11.2")
|
||||
default CompoundTag getTile(int x, int y, int z) {
|
||||
return IBlocks.super.getTile(x, y, z);
|
||||
}
|
||||
|
||||
boolean isCreateCopy();
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
package com.fastasyncworldedit.core.queue;
|
||||
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.OutputExtent;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
@ -36,7 +38,12 @@ public interface IChunkSet extends IBlocks, OutputExtent {
|
||||
boolean isEmpty();
|
||||
|
||||
@Override
|
||||
boolean setTile(int x, int y, int z, CompoundTag tile);
|
||||
@Deprecated(forRemoval = true, since = "2.11.2")
|
||||
default boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
|
||||
return tile(x, y, z, FaweCompoundTag.of(tile.toLinTag()));
|
||||
}
|
||||
|
||||
boolean tile(int x, int y, int z, FaweCompoundTag tag);
|
||||
|
||||
@Override
|
||||
void setBlockLight(int x, int y, int z, int value);
|
||||
@ -53,7 +60,12 @@ public interface IChunkSet extends IBlocks, OutputExtent {
|
||||
|
||||
void setFullBright(int layer);
|
||||
|
||||
void setEntity(CompoundTag tag);
|
||||
@Deprecated(forRemoval = true, since = "2.11.2")
|
||||
default void setEntity(CompoundTag tag) {
|
||||
entity(FaweCompoundTag.of(tag::toLinTag));
|
||||
}
|
||||
|
||||
void entity(FaweCompoundTag tag);
|
||||
|
||||
void removeEntity(UUID uuid);
|
||||
|
||||
|
@ -9,21 +9,11 @@ public interface IDelegateFilter extends Filter {
|
||||
|
||||
Filter getParent();
|
||||
|
||||
@Override
|
||||
default boolean appliesChunk(int chunkX, int chunkZ) {
|
||||
return getParent().appliesChunk(chunkX, chunkZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
default <V extends IChunk> V applyChunk(V chunk, @Nullable Region region) {
|
||||
return getParent().applyChunk(chunk, region);
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean appliesLayer(IChunk chunk, int layer) {
|
||||
return getParent().appliesLayer(chunk, layer);
|
||||
}
|
||||
|
||||
@Override
|
||||
default void applyBlock(FilterBlock block) {
|
||||
getParent().applyBlock(block);
|
||||
|
@ -2,6 +2,9 @@ package com.fastasyncworldedit.core.queue;
|
||||
|
||||
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
|
||||
import com.fastasyncworldedit.core.extent.processor.IBatchProcessorHolder;
|
||||
import com.fastasyncworldedit.core.internal.simd.SimdSupport;
|
||||
import com.fastasyncworldedit.core.internal.simd.VectorizedCharFilterBlock;
|
||||
import com.fastasyncworldedit.core.internal.simd.VectorizedFilter;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
@ -137,16 +140,20 @@ public interface IQueueExtent<T extends IChunk> extends Flushable, Trimable, ICh
|
||||
int chunkZ,
|
||||
boolean full
|
||||
) {
|
||||
if (!filter.appliesChunk(chunkX, chunkZ)) {
|
||||
return block;
|
||||
}
|
||||
// if (!filter.appliesChunk(chunkX, chunkZ)) {
|
||||
// return block;
|
||||
// }
|
||||
T chunk = this.getOrCreateChunk(chunkX, chunkZ);
|
||||
|
||||
T newChunk = filter.applyChunk(chunk, region);
|
||||
if (newChunk != null) {
|
||||
chunk = newChunk;
|
||||
if (block == null) {
|
||||
block = this.createFilterBlock();
|
||||
if (SimdSupport.useVectorApi() && filter instanceof VectorizedFilter) {
|
||||
block = new VectorizedCharFilterBlock(this);
|
||||
} else {
|
||||
block = this.createFilterBlock();
|
||||
}
|
||||
}
|
||||
block.initChunk(chunkX, chunkZ);
|
||||
chunk.filterBlocks(filter, block, region, full);
|
||||
|
@ -2,6 +2,7 @@ package com.fastasyncworldedit.core.queue;
|
||||
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
|
||||
@Deprecated(forRemoval = true, since = "2.11.2")
|
||||
public interface ITileInput {
|
||||
|
||||
CompoundTag getTile(int x, int y, int z);
|
||||
|
@ -14,6 +14,8 @@ import com.fastasyncworldedit.core.extent.processor.BatchProcessorHolder;
|
||||
import com.fastasyncworldedit.core.extent.processor.MultiBatchProcessor;
|
||||
import com.fastasyncworldedit.core.function.mask.BlockMaskBuilder;
|
||||
import com.fastasyncworldedit.core.internal.exception.FaweException;
|
||||
import com.fastasyncworldedit.core.internal.simd.SimdSupport;
|
||||
import com.fastasyncworldedit.core.internal.simd.VectorizedFilter;
|
||||
import com.fastasyncworldedit.core.queue.Filter;
|
||||
import com.fastasyncworldedit.core.queue.IQueueChunk;
|
||||
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
||||
@ -28,7 +30,6 @@ import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Countable;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
@ -223,7 +224,9 @@ public class ParallelQueueExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
|
||||
return this.changes = apply(region, new LinkedFilter<>(pattern, new CountFilter()), true).getChild().getTotal();
|
||||
VectorizedFilter vectorizedPattern = SimdSupport.vectorizedPattern(pattern);
|
||||
var filter = LinkedFilter.of(vectorizedPattern == null ? pattern : vectorizedPattern, new CountFilter());
|
||||
return this.changes = apply(region, filter, true).getRight().getTotal();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2,9 +2,9 @@ package com.fastasyncworldedit.core.queue.implementation.blocks;
|
||||
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||
import com.fastasyncworldedit.core.util.collection.MemBlockSet;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
@ -13,6 +13,7 @@ import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -74,7 +75,7 @@ public class BitSetBlocks implements IChunkSet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tile) {
|
||||
public boolean tile(final int x, final int y, final int z, final FaweCompoundTag tag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -107,7 +108,7 @@ public class BitSetBlocks implements IChunkSet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntity(CompoundTag tag) {
|
||||
public void entity(final FaweCompoundTag tag) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -181,18 +182,18 @@ public class BitSetBlocks implements IChunkSet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<BlockVector3, CompoundTag> getTiles() {
|
||||
public Map<BlockVector3, FaweCompoundTag> tiles() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getTile(int x, int y, int z) {
|
||||
public @Nullable FaweCompoundTag tile(final int x, final int y, final int z) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<CompoundTag> getEntities() {
|
||||
return Collections.emptySet();
|
||||
public Collection<FaweCompoundTag> entities() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.fastasyncworldedit.core.queue.implementation.blocks;
|
||||
|
||||
import com.fastasyncworldedit.core.queue.IBlocks;
|
||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
@ -20,7 +21,7 @@ public abstract class CharGetBlocks extends CharBlocks implements IChunkGet {
|
||||
@Override
|
||||
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||
BlockState state = BlockTypesCache.states[get(x, y, z)];
|
||||
return state.toBaseBlock(this, x, y, z);
|
||||
return state.toBaseBlock((IBlocks) this, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -4,16 +4,18 @@ import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.fastasyncworldedit.core.math.BlockVector3ChunkMap;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||
import com.fastasyncworldedit.core.queue.Pool;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashSet;
|
||||
@ -36,8 +38,8 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
||||
public BiomeType[][] biomes;
|
||||
public char[][] light;
|
||||
public char[][] skyLight;
|
||||
public BlockVector3ChunkMap<CompoundTag> tiles;
|
||||
public HashSet<CompoundTag> entities;
|
||||
public BlockVector3ChunkMap<FaweCompoundTag> tiles;
|
||||
public HashSet<FaweCompoundTag> entities;
|
||||
public HashSet<UUID> entityRemoves;
|
||||
public EnumMap<HeightMapType, int[]> heightMaps;
|
||||
private boolean fastMode = false;
|
||||
@ -71,17 +73,17 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<BlockVector3, CompoundTag> getTiles() {
|
||||
public Map<BlockVector3, FaweCompoundTag> tiles() {
|
||||
return tiles == null ? Collections.emptyMap() : tiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getTile(int x, int y, int z) {
|
||||
public @Nullable FaweCompoundTag tile(final int x, final int y, final int z) {
|
||||
return tiles == null ? null : tiles.get(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<CompoundTag> getEntities() {
|
||||
public Collection<FaweCompoundTag> entities() {
|
||||
return entities == null ? Collections.emptySet() : entities;
|
||||
}
|
||||
|
||||
@ -132,12 +134,12 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tile) {
|
||||
public boolean tile(final int x, final int y, final int z, final FaweCompoundTag tag) {
|
||||
if (tiles == null) {
|
||||
tiles = new BlockVector3ChunkMap<>();
|
||||
}
|
||||
updateSectionIndexRange(y >> 4);
|
||||
tiles.put(x, y, z, tile);
|
||||
tiles.put(x, y, z, tag);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -259,7 +261,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntity(CompoundTag tag) {
|
||||
public void entity(final FaweCompoundTag tag) {
|
||||
if (entities == null) {
|
||||
entities = new HashSet<>();
|
||||
}
|
||||
|
@ -2,10 +2,10 @@ package com.fastasyncworldedit.core.queue.implementation.blocks;
|
||||
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.queue.IBlocks;
|
||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
@ -15,9 +15,9 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
@ -48,24 +48,19 @@ public final class NullChunkGet implements IChunkGet {
|
||||
return BlockTypes.AIR.getDefaultState();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Map<BlockVector3, CompoundTag> getTiles() {
|
||||
@Override
|
||||
public Map<BlockVector3, FaweCompoundTag> tiles() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CompoundTag getTile(int x, int y, int z) {
|
||||
@Override
|
||||
public @Nullable FaweCompoundTag tile(final int x, final int y, final int z) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Set<CompoundTag> getEntities() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CompoundTag getEntity(@Nonnull UUID uuid) {
|
||||
return null;
|
||||
@Override
|
||||
public Collection<FaweCompoundTag> entities() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -123,6 +118,11 @@ public final class NullChunkGet implements IChunkGet {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable FaweCompoundTag entity(final UUID uuid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public char[] load(int layer) {
|
||||
return FaweCache.INSTANCE.EMPTY_CHAR_4096;
|
||||
|
@ -4,9 +4,9 @@ import com.fastasyncworldedit.core.Fawe;
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.fastasyncworldedit.core.math.BlockVector3ChunkMap;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.queue.IBlocks;
|
||||
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
@ -17,6 +17,7 @@ import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
@ -44,8 +45,8 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks {
|
||||
private BiomeType[][] biomes;
|
||||
private char[][] light;
|
||||
private char[][] skyLight;
|
||||
private BlockVector3ChunkMap<CompoundTag> tiles;
|
||||
private HashSet<CompoundTag> entities;
|
||||
private BlockVector3ChunkMap<FaweCompoundTag> tiles;
|
||||
private HashSet<FaweCompoundTag> entities;
|
||||
private HashSet<UUID> entityRemoves;
|
||||
private Map<HeightMapType, int[]> heightMaps;
|
||||
private boolean fastMode;
|
||||
@ -64,8 +65,8 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks {
|
||||
int sectionCount,
|
||||
char[][] light,
|
||||
char[][] skyLight,
|
||||
BlockVector3ChunkMap<CompoundTag> tiles,
|
||||
HashSet<CompoundTag> entities,
|
||||
BlockVector3ChunkMap<FaweCompoundTag> tiles,
|
||||
HashSet<FaweCompoundTag> entities,
|
||||
HashSet<UUID> entityRemoves,
|
||||
Map<HeightMapType, int[]> heightMaps,
|
||||
char defaultOrdinal,
|
||||
@ -116,18 +117,18 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<BlockVector3, CompoundTag> getTiles() {
|
||||
public Map<BlockVector3, FaweCompoundTag> tiles() {
|
||||
return tiles == null ? Collections.emptyMap() : tiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getTile(int x, int y, int z) {
|
||||
public @Nullable FaweCompoundTag tile(final int x, final int y, final int z) {
|
||||
return tiles == null ? null : tiles.get(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<CompoundTag> getEntities() {
|
||||
return entities == null ? Collections.emptySet() : entities;
|
||||
public Collection<FaweCompoundTag> entities() {
|
||||
return entities == null ? Collections.emptyList() : entities;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -268,12 +269,12 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tile) {
|
||||
public boolean tile(final int x, final int y, final int z, final FaweCompoundTag tag) {
|
||||
updateSectionIndexRange(y >> 4);
|
||||
if (tiles == null) {
|
||||
tiles = new BlockVector3ChunkMap<>();
|
||||
}
|
||||
tiles.put(x, y, z, tile);
|
||||
tiles.put(x, y, z, tag);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -358,7 +359,7 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntity(CompoundTag tag) {
|
||||
public void entity(final FaweCompoundTag tag) {
|
||||
if (entities == null) {
|
||||
entities = new HashSet<>();
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.fastasyncworldedit.core.queue.implementation.chunk;
|
||||
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
|
||||
import com.fastasyncworldedit.core.extent.processor.EmptyBatchProcessor;
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.queue.Filter;
|
||||
import com.fastasyncworldedit.core.queue.IChunk;
|
||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||
@ -11,7 +12,6 @@ import com.fastasyncworldedit.core.queue.IQueueChunk;
|
||||
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
||||
import com.fastasyncworldedit.core.queue.implementation.ParallelQueueExtent;
|
||||
import com.fastasyncworldedit.core.util.MemUtil;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
@ -22,6 +22,7 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@ -76,18 +77,8 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
||||
return delegate.set(this).setTile(x, y, z, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getTile(int x, int y, int z) {
|
||||
return delegate.set(this).getTile(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntity(CompoundTag tag) {
|
||||
delegate.set(this).setEntity(tag);
|
||||
public void entity(final FaweCompoundTag tag) {
|
||||
delegate.set(this).entity(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -163,11 +154,6 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
||||
return isInit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getEntity(UUID uuid) {
|
||||
return delegate.get(this).getEntity(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCreateCopy(boolean createCopy) {
|
||||
this.createCopy = createCopy;
|
||||
@ -879,16 +865,6 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public Map<BlockVector3, CompoundTag> getTiles() {
|
||||
return delegate.get(this).getTiles();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<CompoundTag> getEntities() {
|
||||
return delegate.get(this).getEntities();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSection(int layer) {
|
||||
return chunkExisting != null && chunkExisting.hasSection(layer);
|
||||
@ -946,6 +922,11 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
||||
return chunkSet == null || chunkSet.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tile(final int x, final int y, final int z, final FaweCompoundTag tag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create the existing part of this chunk.
|
||||
*/
|
||||
@ -1093,6 +1074,21 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
||||
return delegate.getBlock(this, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<BlockVector3, FaweCompoundTag> tiles() {
|
||||
return delegate.get(this).tiles();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable FaweCompoundTag tile(final int x, final int y, final int z) {
|
||||
return delegate.get(this).tile(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<FaweCompoundTag> entities() {
|
||||
return delegate.get(this).entities();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||
return delegate.getFullBlock(this, x, y, z);
|
||||
@ -1158,6 +1154,11 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
||||
return delegate.getHeightMap(this, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable FaweCompoundTag entity(final UUID uuid) {
|
||||
return delegate.get(this).entity(uuid);
|
||||
}
|
||||
|
||||
public interface IBlockDelegate {
|
||||
|
||||
<C extends Future<C>> IChunkGet get(ChunkHolder<C> chunk);
|
||||
|
@ -2,10 +2,10 @@ package com.fastasyncworldedit.core.queue.implementation.chunk;
|
||||
|
||||
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.fastasyncworldedit.core.nbt.FaweCompoundTag;
|
||||
import com.fastasyncworldedit.core.queue.Filter;
|
||||
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||
import com.fastasyncworldedit.core.queue.IQueueChunk;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
@ -16,6 +16,7 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -53,13 +54,11 @@ public final class NullChunk implements IQueueChunk {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean setTile(int x, int y, int z, @Nonnull CompoundTag tag) {
|
||||
@Override
|
||||
public boolean tile(final int x, final int y, final int z, final FaweCompoundTag tag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setEntity(@Nonnull CompoundTag tag) {
|
||||
}
|
||||
|
||||
public void removeEntity(@Nonnull UUID uuid) {
|
||||
}
|
||||
|
||||
@ -112,6 +111,10 @@ public final class NullChunk implements IQueueChunk {
|
||||
public void setFullBright(int layer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entity(final FaweCompoundTag tag) {
|
||||
}
|
||||
|
||||
public void removeSectionLighting(int layer, boolean sky) {
|
||||
}
|
||||
|
||||
@ -147,25 +150,26 @@ public final class NullChunk implements IQueueChunk {
|
||||
return BlockTypes.__RESERVED__.getDefaultState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<BlockVector3, FaweCompoundTag> tiles() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable FaweCompoundTag tile(final int x, final int y, final int z) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<FaweCompoundTag> entities() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||
return BlockTypes.__RESERVED__.getDefaultState().toBaseBlock();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Map<BlockVector3, CompoundTag> getTiles() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CompoundTag getTile(int x, int y, int z) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Set<CompoundTag> getEntities() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public char[] load(int layer) {
|
||||
@ -178,11 +182,6 @@ public final class NullChunk implements IQueueChunk {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CompoundTag getEntity(@Nonnull UUID uuid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCreateCopy(boolean createCopy) {
|
||||
return -1;
|
||||
@ -230,6 +229,11 @@ public final class NullChunk implements IQueueChunk {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable FaweCompoundTag entity(final UUID uuid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean trim(boolean aggressive) {
|
||||
return true;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user