geforkt von Mirrors/FastAsyncWorldEdit
Merge branch '1.15' of https://github.com/IntellectualSites/FastAsyncWorldEdit-1.13 into 1.15
Dieser Commit ist enthalten in:
Commit
34d40cb856
@ -12,6 +12,7 @@ FAWE is a fork of WorldEdit that has huge speed and memory improvements and cons
|
|||||||
* [Discord](https://discord.gg/KxkjDVg)
|
* [Discord](https://discord.gg/KxkjDVg)
|
||||||
* [Wiki](https://github.com/IntellectualSites/FastAsyncWorldEdit-1.13/wiki)
|
* [Wiki](https://github.com/IntellectualSites/FastAsyncWorldEdit-1.13/wiki)
|
||||||
* [Report Issue](https://github.com/IntellectualSites/FastAsyncWorldEdit-1.13/issues)
|
* [Report Issue](https://github.com/IntellectualSites/FastAsyncWorldEdit-1.13/issues)
|
||||||
|
* [Crowdin](https://intellectualsites.crowdin.com/fastasyncworldedit)
|
||||||
|
|
||||||
## Downloads
|
## Downloads
|
||||||
### 1.13+
|
### 1.13+
|
||||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binäre Datei nicht angezeigt.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.4-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
29
gradlew
vendored
29
gradlew
vendored
@ -154,19 +154,19 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
|||||||
else
|
else
|
||||||
eval `echo args$i`="\"$arg\""
|
eval `echo args$i`="\"$arg\""
|
||||||
fi
|
fi
|
||||||
i=$((i+1))
|
i=`expr $i + 1`
|
||||||
done
|
done
|
||||||
case $i in
|
case $i in
|
||||||
(0) set -- ;;
|
0) set -- ;;
|
||||||
(1) set -- "$args0" ;;
|
1) set -- "$args0" ;;
|
||||||
(2) set -- "$args0" "$args1" ;;
|
2) set -- "$args0" "$args1" ;;
|
||||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -175,14 +175,9 @@ save () {
|
|||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
echo " "
|
echo " "
|
||||||
}
|
}
|
||||||
APP_ARGS=$(save "$@")
|
APP_ARGS=`save "$@"`
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
|
||||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
exec "$JAVACMD" "$@"
|
||||||
|
3
gradlew.bat
vendored
3
gradlew.bat
vendored
@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
|||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
|
@ -1,18 +1,23 @@
|
|||||||
package com.boydti.fawe.bukkit.adapter;
|
package com.boydti.fawe.bukkit.adapter;
|
||||||
|
|
||||||
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.world.block.BlockID;
|
import com.sk89q.worldedit.world.block.BlockID;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class NMSAdapter {
|
public class NMSAdapter {
|
||||||
public static int createPalette(int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy,
|
public static int createPalette(int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy,
|
||||||
int[] num_palette_buffer, char[] set, Map<BlockVector3, Integer> ticking_blocks) {
|
int[] num_palette_buffer, char[] set, Map<BlockVector3, Integer> ticking_blocks, boolean fastmode) {
|
||||||
int air = 0;
|
int air = 0;
|
||||||
int num_palette = 0;
|
int num_palette = 0;
|
||||||
|
char lastOrdinal = BlockID.__RESERVED__;
|
||||||
|
boolean lastticking = false;
|
||||||
|
boolean tick_placed = Settings.IMP.EXPERIMENTAL.ALLOW_TICK_PLACED;
|
||||||
for (int i = 0; i < 4096; i++) {
|
for (int i = 0; i < 4096; i++) {
|
||||||
char ordinal = set[i];
|
char ordinal = set[i];
|
||||||
switch (ordinal) {
|
switch (ordinal) {
|
||||||
@ -24,11 +29,22 @@ public class NMSAdapter {
|
|||||||
air++;
|
air++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BlockState state = BlockState.getFromOrdinal(ordinal);
|
if (!fastmode && !tick_placed) {
|
||||||
if (state.getMaterial().isTicksRandomly()) {
|
boolean ticking;
|
||||||
ticking_blocks.put(BlockVector3.at(i & 15, (i >> 8) & 15, (i >> 4) & 15),
|
if (ordinal != lastOrdinal) {
|
||||||
WorldEditPlugin.getInstance().getBukkitImplAdapter()
|
ticking = BlockTypesCache.ticking[ordinal];
|
||||||
.getInternalBlockStateId(state).orElse(0));
|
lastOrdinal = ordinal;
|
||||||
|
lastticking = ticking;
|
||||||
|
} else {
|
||||||
|
ticking = lastticking;
|
||||||
|
}
|
||||||
|
if (ticking) {
|
||||||
|
BlockState state = BlockState.getFromOrdinal(ordinal);
|
||||||
|
ticking_blocks
|
||||||
|
.put(BlockVector3.at(i & 15, (i >> 8) & 15, (i >> 4) & 15),
|
||||||
|
WorldEditPlugin.getInstance().getBukkitImplAdapter()
|
||||||
|
.getInternalBlockStateId(state).orElse(0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int palette = blockToPalette[ordinal];
|
int palette = blockToPalette[ordinal];
|
||||||
@ -45,10 +61,14 @@ public class NMSAdapter {
|
|||||||
|
|
||||||
public static int createPalette(int layer, int[] blockToPalette, int[] paletteToBlock,
|
public static int createPalette(int layer, int[] blockToPalette, int[] paletteToBlock,
|
||||||
int[] blocksCopy, int[] num_palette_buffer, Function<Integer, char[]> get, char[] set,
|
int[] blocksCopy, int[] num_palette_buffer, Function<Integer, char[]> get, char[] set,
|
||||||
Map<BlockVector3, Integer> ticking_blocks) {
|
Map<BlockVector3, Integer> ticking_blocks, boolean fastmode) {
|
||||||
int air = 0;
|
int air = 0;
|
||||||
int num_palette = 0;
|
int num_palette = 0;
|
||||||
char[] getArr = null;
|
char[] getArr = null;
|
||||||
|
char lastOrdinal = BlockID.__RESERVED__;
|
||||||
|
boolean lastticking = false;
|
||||||
|
boolean tick_placed = Settings.IMP.EXPERIMENTAL.ALLOW_TICK_PLACED;
|
||||||
|
boolean tick_existing = Settings.IMP.EXPERIMENTAL.ALLOW_TICK_EXISTING;
|
||||||
for (int i = 0; i < 4096; i++) {
|
for (int i = 0; i < 4096; i++) {
|
||||||
char ordinal = set[i];
|
char ordinal = set[i];
|
||||||
switch (ordinal) {
|
switch (ordinal) {
|
||||||
@ -65,6 +85,24 @@ public class NMSAdapter {
|
|||||||
case BlockID.VOID_AIR:
|
case BlockID.VOID_AIR:
|
||||||
air++;
|
air++;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
if (!fastmode && !tick_placed && tick_existing) {
|
||||||
|
boolean ticking;
|
||||||
|
if (ordinal != lastOrdinal) {
|
||||||
|
ticking = BlockTypesCache.ticking[ordinal];
|
||||||
|
lastOrdinal = ordinal;
|
||||||
|
lastticking = ticking;
|
||||||
|
} else {
|
||||||
|
ticking = lastticking;
|
||||||
|
}
|
||||||
|
if (ticking) {
|
||||||
|
BlockState state = BlockState.getFromOrdinal(ordinal);
|
||||||
|
ticking_blocks
|
||||||
|
.put(BlockVector3.at(i & 15, (i >> 8) & 15, (i >> 4) & 15),
|
||||||
|
WorldEditPlugin.getInstance().getBukkitImplAdapter()
|
||||||
|
.getInternalBlockStateId(state).orElse(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
set[i] = ordinal;
|
set[i] = ordinal;
|
||||||
break;
|
break;
|
||||||
@ -75,11 +113,21 @@ public class NMSAdapter {
|
|||||||
air++;
|
air++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
BlockState state = BlockState.getFromOrdinal(ordinal);
|
if (!fastmode && tick_placed) {
|
||||||
if (state.getMaterial().isTicksRandomly()) {
|
boolean ticking;
|
||||||
ticking_blocks.put(BlockVector3.at(i & 15, (i >> 8) & 15, (i >> 4) & 15),
|
if (ordinal != lastOrdinal) {
|
||||||
WorldEditPlugin.getInstance().getBukkitImplAdapter()
|
ticking = BlockTypesCache.ticking[ordinal];
|
||||||
.getInternalBlockStateId(state).orElse(0));
|
lastOrdinal = ordinal;
|
||||||
|
lastticking = ticking;
|
||||||
|
} else {
|
||||||
|
ticking = lastticking;
|
||||||
|
}
|
||||||
|
if (ticking) {
|
||||||
|
BlockState state = BlockState.getFromOrdinal(ordinal);
|
||||||
|
ticking_blocks.put(BlockVector3.at(i & 15, (i >> 8) & 15, (i >> 4) & 15),
|
||||||
|
WorldEditPlugin.getInstance().getBukkitImplAdapter()
|
||||||
|
.getInternalBlockStateId(state).orElse(0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int palette = blockToPalette[ordinal];
|
int palette = blockToPalette[ordinal];
|
||||||
if (palette == Integer.MAX_VALUE) {
|
if (palette == Integer.MAX_VALUE) {
|
||||||
|
@ -199,11 +199,11 @@ public final class BukkitAdapter_1_14 extends NMSAdapter {
|
|||||||
/*
|
/*
|
||||||
NMS conversion
|
NMS conversion
|
||||||
*/
|
*/
|
||||||
public static ChunkSection newChunkSection(final int layer, final char[] blocks) {
|
public static ChunkSection newChunkSection(final int layer, final char[] blocks, boolean fastmode) {
|
||||||
return newChunkSection(layer, null, blocks);
|
return newChunkSection(layer, null, blocks, fastmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set) {
|
public static ChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set, boolean fastmode) {
|
||||||
if (set == null) {
|
if (set == null) {
|
||||||
return newChunkSection(layer);
|
return newChunkSection(layer);
|
||||||
}
|
}
|
||||||
@ -216,9 +216,9 @@ public final class BukkitAdapter_1_14 extends NMSAdapter {
|
|||||||
Map<BlockVector3, Integer> ticking_blocks = new HashMap<>();
|
Map<BlockVector3, Integer> ticking_blocks = new HashMap<>();
|
||||||
int air;
|
int air;
|
||||||
if (get == null) {
|
if (get == null) {
|
||||||
air = createPalette(blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, set, ticking_blocks);
|
air = createPalette(blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, set, ticking_blocks, fastmode);
|
||||||
} else {
|
} else {
|
||||||
air = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, get, set, ticking_blocks);
|
air = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, get, set, ticking_blocks, fastmode);
|
||||||
}
|
}
|
||||||
int num_palette = num_palette_buffer[0];
|
int num_palette = num_palette_buffer[0];
|
||||||
// BlockStates
|
// BlockStates
|
||||||
|
@ -5,10 +5,12 @@ import static org.slf4j.LoggerFactory.getLogger;
|
|||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
|
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
||||||
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
||||||
import com.boydti.fawe.bukkit.adapter.mc1_14.nbt.LazyCompoundTag_1_14;
|
import com.boydti.fawe.bukkit.adapter.mc1_14.nbt.LazyCompoundTag_1_14;
|
||||||
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.collection.AdaptedMap;
|
import com.boydti.fawe.object.collection.AdaptedMap;
|
||||||
import com.boydti.fawe.object.collection.BitArray;
|
import com.boydti.fawe.object.collection.BitArray;
|
||||||
import com.google.common.base.Suppliers;
|
import com.google.common.base.Suppliers;
|
||||||
@ -227,6 +229,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
|||||||
try {
|
try {
|
||||||
WorldServer nmsWorld = world;
|
WorldServer nmsWorld = world;
|
||||||
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
|
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
|
||||||
|
boolean fastmode = set.isFastMode() && Settings.IMP.QUEUE.NO_TICK_FASTMODE;
|
||||||
|
|
||||||
// Remove existing tiles
|
// Remove existing tiles
|
||||||
{
|
{
|
||||||
@ -262,7 +265,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
|||||||
ChunkSection newSection;
|
ChunkSection newSection;
|
||||||
ChunkSection existingSection = sections[layer];
|
ChunkSection existingSection = sections[layer];
|
||||||
if (existingSection == null) {
|
if (existingSection == null) {
|
||||||
newSection = BukkitAdapter_1_14.newChunkSection(layer, setArr);
|
newSection = BukkitAdapter_1_14.newChunkSection(layer, setArr, fastmode);
|
||||||
if (BukkitAdapter_1_14.setSectionAtomic(sections, null, newSection, layer)) {
|
if (BukkitAdapter_1_14.setSectionAtomic(sections, null, newSection, layer)) {
|
||||||
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
|
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
|
||||||
continue;
|
continue;
|
||||||
@ -274,6 +277,10 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ensure that the server doesn't try to tick the chunksection while we're editing it.
|
||||||
|
BukkitAdapter_1_14.fieldTickingBlockCount.set(existingSection, (short) 0);
|
||||||
|
|
||||||
DelegateLock lock = BukkitAdapter_1_14.applyLock(existingSection);
|
DelegateLock lock = BukkitAdapter_1_14.applyLock(existingSection);
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
@ -290,7 +297,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
|||||||
} else if (lock.isModified()) {
|
} else if (lock.isModified()) {
|
||||||
this.reset(layer);
|
this.reset(layer);
|
||||||
}
|
}
|
||||||
newSection = BukkitAdapter_1_14.newChunkSection(layer, this::load, setArr);
|
newSection = BukkitAdapter_1_14.newChunkSection(layer, this::load, setArr, fastmode);
|
||||||
if (!BukkitAdapter_1_14.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
if (!BukkitAdapter_1_14.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
||||||
System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer);
|
System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer);
|
||||||
continue;
|
continue;
|
||||||
@ -620,7 +627,37 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
|||||||
if (aggressive) {
|
if (aggressive) {
|
||||||
sections = null;
|
sections = null;
|
||||||
nmsChunk = null;
|
nmsChunk = null;
|
||||||
|
return super.trim(true);
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ChunkSection existing = getSections()[i];
|
||||||
|
try {
|
||||||
|
final DataPaletteBlock<IBlockData> blocksExisting = existing.getBlocks();
|
||||||
|
|
||||||
|
final DataPalette<IBlockData> palette = (DataPalette<IBlockData>) BukkitAdapter_1_14.fieldPalette.get(blocksExisting);
|
||||||
|
int paletteSize;
|
||||||
|
|
||||||
|
if (palette instanceof DataPaletteLinear) {
|
||||||
|
paletteSize = ((DataPaletteLinear<IBlockData>) palette).b();
|
||||||
|
} else if (palette instanceof DataPaletteHash) {
|
||||||
|
paletteSize = ((DataPaletteHash<IBlockData>) palette).b();
|
||||||
|
} else {
|
||||||
|
super.trim(false, i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (paletteSize == 1) {
|
||||||
|
//If the cached palette size is 1 then no blocks can have been changed i.e. do not need to update these chunks.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
super.trim(false, i);
|
||||||
|
} catch (IllegalAccessException ignored) {
|
||||||
|
super.trim(false, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return super.trim(aggressive);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,11 +186,11 @@ public final class BukkitAdapter_1_15 extends NMSAdapter {
|
|||||||
/*
|
/*
|
||||||
NMS conversion
|
NMS conversion
|
||||||
*/
|
*/
|
||||||
public static ChunkSection newChunkSection(final int layer, final char[] blocks) {
|
public static ChunkSection newChunkSection(final int layer, final char[] blocks, boolean fastmode) {
|
||||||
return newChunkSection(layer, null, blocks);
|
return newChunkSection(layer, null, blocks, fastmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set) {
|
public static ChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set, boolean fastmode) {
|
||||||
if (set == null) {
|
if (set == null) {
|
||||||
return newChunkSection(layer);
|
return newChunkSection(layer);
|
||||||
}
|
}
|
||||||
@ -203,9 +203,9 @@ public final class BukkitAdapter_1_15 extends NMSAdapter {
|
|||||||
Map<BlockVector3, Integer> ticking_blocks = new HashMap<>();
|
Map<BlockVector3, Integer> ticking_blocks = new HashMap<>();
|
||||||
int air;
|
int air;
|
||||||
if (get == null) {
|
if (get == null) {
|
||||||
air = createPalette(blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, set, ticking_blocks);
|
air = createPalette(blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, set, ticking_blocks, fastmode);
|
||||||
} else {
|
} else {
|
||||||
air = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, get, set, ticking_blocks);
|
air = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, get, set, ticking_blocks, fastmode);
|
||||||
}
|
}
|
||||||
int num_palette = num_palette_buffer[0];
|
int num_palette = num_palette_buffer[0];
|
||||||
// BlockStates
|
// BlockStates
|
||||||
|
@ -5,10 +5,12 @@ import static org.slf4j.LoggerFactory.getLogger;
|
|||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
|
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
||||||
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
||||||
import com.boydti.fawe.bukkit.adapter.mc1_15.nbt.LazyCompoundTag_1_15;
|
import com.boydti.fawe.bukkit.adapter.mc1_15.nbt.LazyCompoundTag_1_15;
|
||||||
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.collection.AdaptedMap;
|
import com.boydti.fawe.object.collection.AdaptedMap;
|
||||||
import com.boydti.fawe.object.collection.BitArray;
|
import com.boydti.fawe.object.collection.BitArray;
|
||||||
import com.google.common.base.Suppliers;
|
import com.google.common.base.Suppliers;
|
||||||
@ -235,6 +237,7 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks {
|
|||||||
try {
|
try {
|
||||||
WorldServer nmsWorld = world;
|
WorldServer nmsWorld = world;
|
||||||
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
|
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
|
||||||
|
boolean fastmode = set.isFastMode() && Settings.IMP.QUEUE.NO_TICK_FASTMODE;
|
||||||
|
|
||||||
// Remove existing tiles
|
// Remove existing tiles
|
||||||
{
|
{
|
||||||
@ -270,7 +273,7 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks {
|
|||||||
ChunkSection newSection;
|
ChunkSection newSection;
|
||||||
ChunkSection existingSection = sections[layer];
|
ChunkSection existingSection = sections[layer];
|
||||||
if (existingSection == null) {
|
if (existingSection == null) {
|
||||||
newSection = BukkitAdapter_1_15.newChunkSection(layer, setArr);
|
newSection = BukkitAdapter_1_15.newChunkSection(layer, setArr, fastmode);
|
||||||
if (BukkitAdapter_1_15.setSectionAtomic(sections, null, newSection, layer)) {
|
if (BukkitAdapter_1_15.setSectionAtomic(sections, null, newSection, layer)) {
|
||||||
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
|
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
|
||||||
continue;
|
continue;
|
||||||
@ -282,6 +285,10 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ensure that the server doesn't try to tick the chunksection while we're editing it.
|
||||||
|
BukkitAdapter_1_15.fieldTickingBlockCount.set(existingSection, (short) 0);
|
||||||
|
|
||||||
DelegateLock lock = BukkitAdapter_1_15.applyLock(existingSection);
|
DelegateLock lock = BukkitAdapter_1_15.applyLock(existingSection);
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
@ -298,7 +305,7 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks {
|
|||||||
} else if (lock.isModified()) {
|
} else if (lock.isModified()) {
|
||||||
this.reset(layer);
|
this.reset(layer);
|
||||||
}
|
}
|
||||||
newSection = BukkitAdapter_1_15.newChunkSection(layer, this::load, setArr);
|
newSection = BukkitAdapter_1_15.newChunkSection(layer, this::load, setArr, fastmode);
|
||||||
if (!BukkitAdapter_1_15.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
if (!BukkitAdapter_1_15.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
||||||
System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer);
|
System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer);
|
||||||
continue;
|
continue;
|
||||||
@ -640,7 +647,37 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks {
|
|||||||
if (aggressive) {
|
if (aggressive) {
|
||||||
sections = null;
|
sections = null;
|
||||||
nmsChunk = null;
|
nmsChunk = null;
|
||||||
|
return super.trim(true);
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ChunkSection existing = getSections()[i];
|
||||||
|
try {
|
||||||
|
final DataPaletteBlock<IBlockData> blocksExisting = existing.getBlocks();
|
||||||
|
|
||||||
|
final DataPalette<IBlockData> palette = (DataPalette<IBlockData>) BukkitAdapter_1_15.fieldPalette.get(blocksExisting);
|
||||||
|
int paletteSize;
|
||||||
|
|
||||||
|
if (palette instanceof DataPaletteLinear) {
|
||||||
|
paletteSize = ((DataPaletteLinear<IBlockData>) palette).b();
|
||||||
|
} else if (palette instanceof DataPaletteHash) {
|
||||||
|
paletteSize = ((DataPaletteHash<IBlockData>) palette).b();
|
||||||
|
} else {
|
||||||
|
super.trim(false, i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (paletteSize == 1) {
|
||||||
|
//If the cached palette size is 1 then no blocks can have been changed i.e. do not need to update these chunks.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
super.trim(false, i);
|
||||||
|
} catch (IllegalAccessException ignored) {
|
||||||
|
super.trim(false, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return super.trim(aggressive);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,11 +187,11 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
|
|||||||
/*
|
/*
|
||||||
NMS conversion
|
NMS conversion
|
||||||
*/
|
*/
|
||||||
public static ChunkSection newChunkSection(final int layer, final char[] blocks) {
|
public static ChunkSection newChunkSection(final int layer, final char[] blocks, boolean fastmode) {
|
||||||
return newChunkSection(layer, null, blocks);
|
return newChunkSection(layer, null, blocks, fastmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set) {
|
public static ChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set, boolean fastmode) {
|
||||||
if (set == null) {
|
if (set == null) {
|
||||||
return newChunkSection(layer);
|
return newChunkSection(layer);
|
||||||
}
|
}
|
||||||
@ -205,10 +205,10 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
|
|||||||
int air;
|
int air;
|
||||||
if (get == null) {
|
if (get == null) {
|
||||||
air = createPalette(blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer,
|
air = createPalette(blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer,
|
||||||
set, ticking_blocks);
|
set, ticking_blocks, fastmode);
|
||||||
} else {
|
} else {
|
||||||
air = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy,
|
air = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy,
|
||||||
num_palette_buffer, get, set, ticking_blocks);
|
num_palette_buffer, get, set, ticking_blocks, fastmode);
|
||||||
}
|
}
|
||||||
int num_palette = num_palette_buffer[0];
|
int num_palette = num_palette_buffer[0];
|
||||||
// BlockStates
|
// BlockStates
|
||||||
@ -251,10 +251,11 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
|
|||||||
fieldPalette.set(dataPaletteBlocks, palette);
|
fieldPalette.set(dataPaletteBlocks, palette);
|
||||||
fieldSize.set(dataPaletteBlocks, bitsPerEntry);
|
fieldSize.set(dataPaletteBlocks, bitsPerEntry);
|
||||||
setCount(ticking_blocks.size(), 4096 - air, section);
|
setCount(ticking_blocks.size(), 4096 - air, section);
|
||||||
ticking_blocks.forEach((pos, ordinal) -> {
|
if (!fastmode) {
|
||||||
section.setType(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ(),
|
ticking_blocks.forEach((pos, ordinal) -> section
|
||||||
Block.getByCombinedId(ordinal));
|
.setType(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ(),
|
||||||
});
|
Block.getByCombinedId(ordinal)));
|
||||||
|
}
|
||||||
} catch (final IllegalAccessException | NoSuchFieldException e) {
|
} catch (final IllegalAccessException | NoSuchFieldException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,12 @@ package com.boydti.fawe.bukkit.adapter.mc1_15_2;
|
|||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
|
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
||||||
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
||||||
import com.boydti.fawe.bukkit.adapter.mc1_15_2.nbt.LazyCompoundTag_1_15_2;
|
import com.boydti.fawe.bukkit.adapter.mc1_15_2.nbt.LazyCompoundTag_1_15_2;
|
||||||
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.collection.AdaptedMap;
|
import com.boydti.fawe.object.collection.AdaptedMap;
|
||||||
import com.boydti.fawe.object.collection.BitArray;
|
import com.boydti.fawe.object.collection.BitArray;
|
||||||
import com.google.common.base.Suppliers;
|
import com.google.common.base.Suppliers;
|
||||||
@ -242,6 +244,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
try {
|
try {
|
||||||
WorldServer nmsWorld = world;
|
WorldServer nmsWorld = world;
|
||||||
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
|
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
|
||||||
|
boolean fastmode = set.isFastMode() && Settings.IMP.QUEUE.NO_TICK_FASTMODE;
|
||||||
|
|
||||||
// Remove existing tiles
|
// Remove existing tiles
|
||||||
{
|
{
|
||||||
@ -282,7 +285,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
ChunkSection newSection;
|
ChunkSection newSection;
|
||||||
ChunkSection existingSection = sections[layer];
|
ChunkSection existingSection = sections[layer];
|
||||||
if (existingSection == null) {
|
if (existingSection == null) {
|
||||||
newSection = BukkitAdapter_1_15_2.newChunkSection(layer, setArr);
|
newSection = BukkitAdapter_1_15_2.newChunkSection(layer, setArr, fastmode);
|
||||||
if (BukkitAdapter_1_15_2.setSectionAtomic(sections, null, newSection, layer)) {
|
if (BukkitAdapter_1_15_2.setSectionAtomic(sections, null, newSection, layer)) {
|
||||||
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
|
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
|
||||||
continue;
|
continue;
|
||||||
@ -294,7 +297,11 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BukkitAdapter_1_15_2.fieldTickingBlockCount.set(existingSection, (short) 0);
|
||||||
|
|
||||||
|
//ensure that the server doesn't try to tick the chunksection while we're editing it.
|
||||||
DelegateLock lock = BukkitAdapter_1_15_2.applyLock(existingSection);
|
DelegateLock lock = BukkitAdapter_1_15_2.applyLock(existingSection);
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
lock.untilFree();
|
lock.untilFree();
|
||||||
@ -310,7 +317,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
} else if (lock.isModified()) {
|
} else if (lock.isModified()) {
|
||||||
this.reset(layer);
|
this.reset(layer);
|
||||||
}
|
}
|
||||||
newSection = BukkitAdapter_1_15_2.newChunkSection(layer, this::load, setArr);
|
newSection = BukkitAdapter_1_15_2.newChunkSection(layer, this::load, setArr, fastmode);
|
||||||
if (!BukkitAdapter_1_15_2.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
if (!BukkitAdapter_1_15_2.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
||||||
System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer);
|
System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer);
|
||||||
continue;
|
continue;
|
||||||
@ -644,7 +651,37 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
if (aggressive) {
|
if (aggressive) {
|
||||||
sections = null;
|
sections = null;
|
||||||
nmsChunk = null;
|
nmsChunk = null;
|
||||||
|
return super.trim(true);
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ChunkSection existing = getSections()[i];
|
||||||
|
try {
|
||||||
|
final DataPaletteBlock<IBlockData> blocksExisting = existing.getBlocks();
|
||||||
|
|
||||||
|
final DataPalette<IBlockData> palette = (DataPalette<IBlockData>) BukkitAdapter_1_15_2.fieldPalette.get(blocksExisting);
|
||||||
|
int paletteSize;
|
||||||
|
|
||||||
|
if (palette instanceof DataPaletteLinear) {
|
||||||
|
paletteSize = ((DataPaletteLinear<IBlockData>) palette).b();
|
||||||
|
} else if (palette instanceof DataPaletteHash) {
|
||||||
|
paletteSize = ((DataPaletteHash<IBlockData>) palette).b();
|
||||||
|
} else {
|
||||||
|
super.trim(false, i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (paletteSize == 1) {
|
||||||
|
//If the cached palette size is 1 then no blocks can have been changed i.e. do not need to update these chunks.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
super.trim(false, i);
|
||||||
|
} catch (IllegalAccessException ignored) {
|
||||||
|
super.trim(false, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return super.trim(aggressive);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ import org.bukkit.entity.Item;
|
|||||||
import org.bukkit.entity.LightningStrike;
|
import org.bukkit.entity.LightningStrike;
|
||||||
import org.bukkit.entity.LivingEntity;
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.generator.BlockPopulator;
|
import org.bukkit.generator.BlockPopulator;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@ -649,6 +650,11 @@ public class AsyncWorld extends PassthroughExtent implements World {
|
|||||||
return TaskManager.IMP.sync(() -> parent.spawn(location, clazz, function));
|
return TaskManager.IMP.sync(() -> parent.spawn(location, clazz, function));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends Entity> @NotNull T spawn(@NotNull Location location, @NotNull Class<T> clazz, @Nullable Consumer<T> function, CreatureSpawnEvent.@NotNull SpawnReason reason) throws IllegalArgumentException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FallingBlock spawnFallingBlock(Location location, MaterialData data) throws IllegalArgumentException {
|
public FallingBlock spawnFallingBlock(Location location, MaterialData data) throws IllegalArgumentException {
|
||||||
return TaskManager.IMP.sync(() -> parent.spawnFallingBlock(location, data));
|
return TaskManager.IMP.sync(() -> parent.spawnFallingBlock(location, data));
|
||||||
@ -1053,6 +1059,21 @@ public class AsyncWorld extends PassthroughExtent implements World {
|
|||||||
return parent.getViewDistance();
|
return parent.getViewDistance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setViewDistance(int viewDistance) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNoTickViewDistance() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNoTickViewDistance(int viewDistance) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RayTraceResult rayTrace(Location arg0, Vector arg1, double arg2, FluidCollisionMode arg3, boolean arg4,
|
public RayTraceResult rayTrace(Location arg0, Vector arg1, double arg2, FluidCollisionMode arg3, boolean arg4,
|
||||||
double arg5, Predicate<Entity> arg6) {
|
double arg5, Predicate<Entity> arg6) {
|
||||||
@ -1174,6 +1195,11 @@ public class AsyncWorld extends PassthroughExtent implements World {
|
|||||||
return parent.getChunkAtAsync(arg0, arg1, arg2);
|
return parent.getChunkAtAsync(arg0, arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull CompletableFuture<Chunk> getChunkAtAsync(int x, int z, boolean gen, boolean urgent) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDayTime() {
|
public boolean isDayTime() {
|
||||||
return parent.isDayTime();
|
return parent.isDayTime();
|
||||||
|
@ -145,4 +145,9 @@ public class CombinedBlocks implements IBlocks {
|
|||||||
public boolean trim(boolean aggressive) {
|
public boolean trim(boolean aggressive) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,8 @@ public interface IBlocks extends Trimable {
|
|||||||
.map(layer -> (1 << layer)).sum();
|
.map(layer -> (1 << layer)).sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean trim(boolean aggressive, int layer);
|
||||||
|
|
||||||
IBlocks reset();
|
IBlocks reset();
|
||||||
|
|
||||||
default byte[] toByteArray(boolean full) {
|
default byte[] toByteArray(boolean full) {
|
||||||
|
@ -3,14 +3,12 @@ package com.boydti.fawe.beta;
|
|||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.extent.OutputExtent;
|
import com.sk89q.worldedit.extent.OutputExtent;
|
||||||
import com.sk89q.worldedit.function.operation.Operation;
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import java.util.Map;
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for setting blocks
|
* Interface for setting blocks
|
||||||
@ -42,6 +40,13 @@ public interface IChunkSet extends IBlocks, OutputExtent {
|
|||||||
return getBiomes() != null;
|
return getBiomes() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default boolean isFastMode() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//default to avoid tricky child classes. We only need it in a few cases anyway.
|
||||||
|
default void setFastMode(boolean fastMode){}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
IChunkSet reset();
|
IChunkSet reset();
|
||||||
|
|
||||||
|
@ -82,6 +82,10 @@ public interface IQueueExtent<T extends IChunk> extends Flushable, Trimable, ICh
|
|||||||
return BlockVector3.at(30000000, FaweCache.IMP.WORLD_MAX_Y, 30000000);
|
return BlockVector3.at(30000000, FaweCache.IMP.WORLD_MAX_Y, 30000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setFastMode(boolean fastMode);
|
||||||
|
|
||||||
|
boolean isFastMode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new root IChunk object<br> - Full chunks will be reused, so a more optimized chunk
|
* Create a new root IChunk object<br> - Full chunks will be reused, so a more optimized chunk
|
||||||
* can be returned in that case<br> - Don't wrap the chunk, that should be done in {@link
|
* can be returned in that case<br> - Don't wrap the chunk, that should be done in {@link
|
||||||
@ -143,6 +147,7 @@ public interface IQueueExtent<T extends IChunk> extends Flushable, Trimable, ICh
|
|||||||
T chunk = this.getOrCreateChunk(chunkX, chunkZ);
|
T chunk = this.getOrCreateChunk(chunkX, chunkZ);
|
||||||
// Initialize
|
// Initialize
|
||||||
chunk.init(this, chunkX, chunkZ);
|
chunk.init(this, chunkX, chunkZ);
|
||||||
|
chunk.setFastMode(isFastMode());
|
||||||
|
|
||||||
T newChunk = filter.applyChunk(chunk, region);
|
T newChunk = filter.applyChunk(chunk, region);
|
||||||
if (newChunk != null) {
|
if (newChunk != null) {
|
||||||
|
@ -153,4 +153,9 @@ public class BitSetBlocks implements IChunkSet {
|
|||||||
public boolean trim(boolean aggressive) {
|
public boolean trim(boolean aggressive) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,17 @@ public abstract class CharBlocks implements IBlocks {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
|
boolean result = true;
|
||||||
|
if (sections[layer] == EMPTY && blocks[layer] != null) {
|
||||||
|
blocks[layer] = null;
|
||||||
|
} else {
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IChunkSet reset() {
|
public IChunkSet reset() {
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
|
@ -25,6 +25,13 @@ public abstract class CharGetBlocks extends CharBlocks implements IChunkGet {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
|
sections[layer] = EMPTY;
|
||||||
|
blocks[layer] = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IChunkSet reset() {
|
public IChunkSet reset() {
|
||||||
super.reset();
|
super.reset();
|
||||||
|
@ -34,6 +34,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
public BlockVector3ChunkMap<CompoundTag> tiles;
|
public BlockVector3ChunkMap<CompoundTag> tiles;
|
||||||
public HashSet<CompoundTag> entities;
|
public HashSet<CompoundTag> entities;
|
||||||
public HashSet<UUID> entityRemoves;
|
public HashSet<UUID> entityRemoves;
|
||||||
|
private boolean fastMode = false;
|
||||||
|
|
||||||
private CharSetBlocks() {}
|
private CharSetBlocks() {}
|
||||||
|
|
||||||
@ -131,6 +132,16 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
entityRemoves.add(uuid);
|
entityRemoves.add(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFastMode(boolean fastMode) {
|
||||||
|
this.fastMode = fastMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFastMode() {
|
||||||
|
return fastMode;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
if (biomes != null) {
|
if (biomes != null) {
|
||||||
|
@ -85,6 +85,11 @@ public class FallbackChunkGet implements IChunkGet {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Future<T>> T call(IChunkSet set, Runnable finalize) {
|
public <T extends Future<T>> T call(IChunkSet set, Runnable finalize) {
|
||||||
for (int layer = 0; layer < 16; layer++) {
|
for (int layer = 0; layer < 16; layer++) {
|
||||||
|
@ -50,6 +50,10 @@ object NullChunkGet : IChunkGet {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun trim(aggressive: Boolean, layer: Int): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
override fun <T : Future<T>> call(set: IChunkSet, finalize: Runnable): T? {
|
override fun <T : Future<T>> call(set: IChunkSet, finalize: Runnable): T? {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
private IQueueExtent<? extends IChunk> extent; // the parent queue extent which has this chunk
|
private IQueueExtent<? extends IChunk> extent; // the parent queue extent which has this chunk
|
||||||
private int chunkX;
|
private int chunkX;
|
||||||
private int chunkZ;
|
private int chunkZ;
|
||||||
|
private boolean fastmode;
|
||||||
|
|
||||||
private ChunkHolder() {
|
private ChunkHolder() {
|
||||||
this.delegate = NULL;
|
this.delegate = NULL;
|
||||||
@ -100,6 +101,16 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
return getOrCreateGet().load(layer);
|
return getOrCreateGet().load(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFastMode() {
|
||||||
|
return fastmode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFastMode(boolean fastmode) {
|
||||||
|
this.fastmode = fastmode;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag getEntity(UUID uuid) {
|
public CompoundTag getEntity(UUID uuid) {
|
||||||
return delegate.get(this).getEntity(uuid);
|
return delegate.get(this).getEntity(uuid);
|
||||||
@ -313,6 +324,7 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
public void filterBlocks(Filter filter, ChunkFilterBlock block, @Nullable Region region, boolean full) {
|
public void filterBlocks(Filter filter, ChunkFilterBlock block, @Nullable Region region, boolean full) {
|
||||||
final IChunkGet get = getOrCreateGet();
|
final IChunkGet get = getOrCreateGet();
|
||||||
final IChunkSet set = getOrCreateSet();
|
final IChunkSet set = getOrCreateSet();
|
||||||
|
set.setFastMode(fastmode);
|
||||||
try {
|
try {
|
||||||
block.filter(this, get, set, filter, region, full);
|
block.filter(this, get, set, filter, region, full);
|
||||||
} finally {
|
} finally {
|
||||||
@ -344,6 +356,11 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
|
return this.trim(aggressive);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return chunkSet == null || chunkSet.isEmpty();
|
return chunkSet == null || chunkSet.isEmpty();
|
||||||
|
@ -117,5 +117,9 @@ object NullChunk : IQueueChunk<Nothing> {
|
|||||||
override fun trim(aggressive: Boolean): Boolean {
|
override fun trim(aggressive: Boolean): Boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun trim(aggressive: Boolean, layer: Int): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import com.boydti.fawe.beta.IBatchProcessor;
|
|||||||
import com.boydti.fawe.beta.IChunk;
|
import com.boydti.fawe.beta.IChunk;
|
||||||
import com.boydti.fawe.beta.IChunkGet;
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
|
||||||
|
|
||||||
public class BatchProcessorHolder implements IBatchProcessorHolder {
|
public class BatchProcessorHolder implements IBatchProcessorHolder {
|
||||||
private IBatchProcessor processor = EmptyBatchProcessor.INSTANCE;
|
private IBatchProcessor processor = EmptyBatchProcessor.INSTANCE;
|
||||||
|
@ -44,12 +44,14 @@ public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrap
|
|||||||
private final QueueHandler handler;
|
private final QueueHandler handler;
|
||||||
private final BatchProcessorHolder processor;
|
private final BatchProcessorHolder processor;
|
||||||
private int changes;
|
private int changes;
|
||||||
|
private final boolean fastmode;
|
||||||
|
|
||||||
public ParallelQueueExtent(QueueHandler handler, World world) {
|
public ParallelQueueExtent(QueueHandler handler, World world, boolean fastmode) {
|
||||||
super(handler.getQueue(world, new BatchProcessorHolder()));
|
super(handler.getQueue(world, new BatchProcessorHolder()));
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
this.processor = (BatchProcessorHolder) getExtent().getProcessor();
|
this.processor = (BatchProcessorHolder) getExtent().getProcessor();
|
||||||
|
this.fastmode = fastmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -94,6 +96,7 @@ public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrap
|
|||||||
final Filter newFilter = filter.fork();
|
final Filter newFilter = filter.fork();
|
||||||
// Create a chunk that we will reuse/reset for each operation
|
// Create a chunk that we will reuse/reset for each operation
|
||||||
final IQueueExtent<IQueueChunk> queue = getNewQueue();
|
final IQueueExtent<IQueueChunk> queue = getNewQueue();
|
||||||
|
queue.setFastMode(fastmode);
|
||||||
synchronized (queue) {
|
synchronized (queue) {
|
||||||
ChunkFilterBlock block = null;
|
ChunkFilterBlock block = null;
|
||||||
|
|
||||||
@ -162,7 +165,8 @@ public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrap
|
|||||||
@Override
|
@Override
|
||||||
public int replaceBlocks(Region region, Mask mask, Pattern pattern)
|
public int replaceBlocks(Region region, Mask mask, Pattern pattern)
|
||||||
throws MaxChangedBlocksException {
|
throws MaxChangedBlocksException {
|
||||||
return this.changes = apply(region, mask.toFilter(pattern), false).getBlocksApplied();
|
boolean full = mask.replacesAir();
|
||||||
|
return this.changes = apply(region, mask.toFilter(pattern), full).getBlocksApplied();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -49,6 +49,8 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
|
|||||||
|
|
||||||
private boolean enabledQueue = true;
|
private boolean enabledQueue = true;
|
||||||
|
|
||||||
|
private boolean fastmode = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safety check to ensure that the thread being used matches the one being initialized on. - Can
|
* Safety check to ensure that the thread being used matches the one being initialized on. - Can
|
||||||
* be removed later
|
* be removed later
|
||||||
@ -80,6 +82,16 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
|
|||||||
return cacheSet.get(chunkX, chunkZ);
|
return cacheSet.get(chunkX, chunkZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFastMode(boolean fastmode) {
|
||||||
|
this.fastmode = fastmode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFastMode() {
|
||||||
|
return fastmode;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the queue.
|
* Resets the queue.
|
||||||
*/
|
*/
|
||||||
|
@ -309,6 +309,11 @@ public class Settings extends Config {
|
|||||||
})
|
})
|
||||||
public int DISCARD_AFTER_MS = 60000;
|
public int DISCARD_AFTER_MS = 60000;
|
||||||
|
|
||||||
|
@Comment({
|
||||||
|
"When using fastmode also do not bother to fix existing ticking blocks"
|
||||||
|
})
|
||||||
|
public boolean NO_TICK_FASTMODE = true;
|
||||||
|
|
||||||
public static class PROGRESS {
|
public static class PROGRESS {
|
||||||
@Comment({"Display constant titles about the progress of a user's edit",
|
@Comment({"Display constant titles about the progress of a user's edit",
|
||||||
" - false = disabled",
|
" - false = disabled",
|
||||||
@ -369,6 +374,18 @@ public class Settings extends Config {
|
|||||||
"Other experimental features"
|
"Other experimental features"
|
||||||
})
|
})
|
||||||
public boolean OTHER = false;
|
public boolean OTHER = false;
|
||||||
|
|
||||||
|
@Comment({
|
||||||
|
"Allow blocks placed by WorldEdit to tick. This could cause the big lags.",
|
||||||
|
"This has no effect on existing blocks one way or the other."
|
||||||
|
})
|
||||||
|
public boolean ALLOW_TICK_PLACED = false;
|
||||||
|
|
||||||
|
@Comment({
|
||||||
|
"Force re-ticking of existing blocks not edited by FAWE.",
|
||||||
|
"This will increase time taken slightly."
|
||||||
|
})
|
||||||
|
public boolean ALLOW_TICK_EXISTING = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class WEB {
|
public static class WEB {
|
||||||
|
@ -549,6 +549,11 @@ public class MCAChunk implements IChunk {
|
|||||||
return isEmpty();
|
return isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
|
return hasSection(layer);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag getEntity(UUID uuid) {
|
public CompoundTag getEntity(UUID uuid) {
|
||||||
return this.entities.get(uuid);
|
return this.entities.get(uuid);
|
||||||
|
@ -184,7 +184,11 @@ public class CPUOptimizedClipboard extends LinearClipboard {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <B extends BlockStateHolder<B>> boolean setBlock(int index, B block) {
|
public <B extends BlockStateHolder<B>> boolean setBlock(int index, B block) {
|
||||||
states[index] = block.getOrdinalChar();
|
char ordinal = block.getOrdinalChar();
|
||||||
|
if (ordinal == 0) {
|
||||||
|
ordinal = 1;
|
||||||
|
}
|
||||||
|
states[index] = ordinal;
|
||||||
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
|
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
|
||||||
if (hasNbt) {
|
if (hasNbt) {
|
||||||
setTile(index, block.getNbtData());
|
setTile(index, block.getNbtData());
|
||||||
|
@ -388,6 +388,9 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable
|
|||||||
try {
|
try {
|
||||||
int index = HEADER_SIZE + (getIndex(x, y, z) << 1);
|
int index = HEADER_SIZE + (getIndex(x, y, z) << 1);
|
||||||
char ordinal = block.getOrdinalChar();
|
char ordinal = block.getOrdinalChar();
|
||||||
|
if (ordinal == 0) {
|
||||||
|
ordinal = 1;
|
||||||
|
}
|
||||||
byteBuffer.putChar(index, ordinal);
|
byteBuffer.putChar(index, ordinal);
|
||||||
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
|
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
|
||||||
if (hasNbt) {
|
if (hasNbt) {
|
||||||
|
@ -263,6 +263,9 @@ public class MemoryOptimizedClipboard extends LinearClipboard {
|
|||||||
@Override
|
@Override
|
||||||
public <B extends BlockStateHolder<B>> boolean setBlock(int index, B block) {
|
public <B extends BlockStateHolder<B>> boolean setBlock(int index, B block) {
|
||||||
int ordinal = block.getOrdinal();
|
int ordinal = block.getOrdinal();
|
||||||
|
if (ordinal == 0) {
|
||||||
|
ordinal = 1;
|
||||||
|
}
|
||||||
setOrdinal(index, ordinal);
|
setOrdinal(index, ordinal);
|
||||||
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
|
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
|
||||||
if (hasNbt) {
|
if (hasNbt) {
|
||||||
|
@ -296,7 +296,7 @@ public class EditSessionBuilder {
|
|||||||
if (unwrapped instanceof IQueueExtent) {
|
if (unwrapped instanceof IQueueExtent) {
|
||||||
extent = queue = (IQueueExtent) unwrapped;
|
extent = queue = (IQueueExtent) unwrapped;
|
||||||
} else if (Settings.IMP.QUEUE.PARALLEL_THREADS > 1 && threaded) {
|
} else if (Settings.IMP.QUEUE.PARALLEL_THREADS > 1 && threaded) {
|
||||||
ParallelQueueExtent parallel = new ParallelQueueExtent(Fawe.get().getQueueHandler(), world);
|
ParallelQueueExtent parallel = new ParallelQueueExtent(Fawe.get().getQueueHandler(), world, fastmode);
|
||||||
queue = parallel.getExtent();
|
queue = parallel.getExtent();
|
||||||
extent = parallel;
|
extent = parallel;
|
||||||
} else {
|
} else {
|
||||||
|
@ -72,6 +72,7 @@ import com.sk89q.worldedit.session.ClipboardHolder;
|
|||||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||||
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
||||||
|
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import org.enginehub.piston.annotation.Command;
|
import org.enginehub.piston.annotation.Command;
|
||||||
import org.enginehub.piston.annotation.CommandContainer;
|
import org.enginehub.piston.annotation.CommandContainer;
|
||||||
@ -366,7 +367,7 @@ public class ClipboardCommands {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
player.print(Caption.of("fawe.web.download.link" , urlText));
|
player.print(Caption.of("fawe.web.download.link" , urlText).clickEvent(ClickEvent.openUrl(urlText)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,8 +134,8 @@ public class GenerationCommands {
|
|||||||
@Arg(desc = "TODO", def = "100") int threshold, @Arg(desc = "BlockVector2", def = "") BlockVector2 dimensions) throws WorldEditException, IOException {
|
@Arg(desc = "TODO", def = "100") int threshold, @Arg(desc = "BlockVector2", def = "") BlockVector2 dimensions) throws WorldEditException, IOException {
|
||||||
TextureUtil tu = Fawe.get().getCachedTextureUtil(randomize, 0, threshold);
|
TextureUtil tu = Fawe.get().getCachedTextureUtil(randomize, 0, threshold);
|
||||||
URL url = new URL(argStr);
|
URL url = new URL(argStr);
|
||||||
if (!url.getHost().equalsIgnoreCase("i.imgur.com") && !url.getHost().equalsIgnoreCase("empcraft.com")) {
|
if (!url.getHost().equalsIgnoreCase("i.imgur.com")) {
|
||||||
throw new IOException("Only i.imgur.com or empcraft.com/ui links are allowed!");
|
throw new IOException("Only i.imgur.com links are allowed!");
|
||||||
}
|
}
|
||||||
BufferedImage image = MainUtil.readImage(url);
|
BufferedImage image = MainUtil.readImage(url);
|
||||||
if (dimensions != null) {
|
if (dimensions != null) {
|
||||||
|
@ -212,6 +212,7 @@ public class SchematicCommands {
|
|||||||
}
|
}
|
||||||
UUID uuid = UUID.fromString(filename.substring(4));
|
UUID uuid = UUID.fromString(filename.substring(4));
|
||||||
URL webUrl = new URL(Settings.IMP.WEB.URL);
|
URL webUrl = new URL(Settings.IMP.WEB.URL);
|
||||||
|
format = ClipboardFormats.findByAlias(formatName);
|
||||||
URL url = new URL(webUrl, "uploads/" + uuid + "." + format.getPrimaryFileExtension());
|
URL url = new URL(webUrl, "uploads/" + uuid + "." + format.getPrimaryFileExtension());
|
||||||
ReadableByteChannel byteChannel = Channels.newChannel(url.openStream());
|
ReadableByteChannel byteChannel = Channels.newChannel(url.openStream());
|
||||||
in = Channels.newInputStream(byteChannel);
|
in = Channels.newInputStream(byteChannel);
|
||||||
|
@ -364,6 +364,12 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
|
|||||||
}
|
}
|
||||||
state = fuzzyBuilder.build();
|
state = fuzzyBuilder.build();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (Map.Entry<Property<?>, Object> blockState : blockStates.entrySet()) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Property<Object> objProp = (Property<Object>) blockState.getKey();
|
||||||
|
state = state.with(objProp, blockState.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// this should be impossible but IntelliJ isn't that smart
|
// this should be impossible but IntelliJ isn't that smart
|
||||||
|
@ -223,11 +223,13 @@ public class FastSchematicReader extends NBTSchematicReader {
|
|||||||
int volume = width * height * length;
|
int volume = width * height * length;
|
||||||
if (palette.length < 128) {
|
if (palette.length < 128) {
|
||||||
for (int index = 0; index < volume; index++) {
|
for (int index = 0; index < volume; index++) {
|
||||||
linear.setBlock(index, getBlockState(fis.read()));
|
int ordinal = fis.read();
|
||||||
|
linear.setBlock(index, getBlockState(ordinal));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int index = 0; index < volume; index++) {
|
for (int index = 0; index < volume; index++) {
|
||||||
linear.setBlock(index, getBlockState(fis.readVarInt()));
|
int ordinal = fis.readVarInt();
|
||||||
|
linear.setBlock(index, getBlockState(ordinal));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -235,7 +237,8 @@ public class FastSchematicReader extends NBTSchematicReader {
|
|||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
for (int z = 0; z < length; z++) {
|
for (int z = 0; z < length; z++) {
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
clipboard.setBlock(x, y, z, getBlockState(fis.read()));
|
int ordinal = fis.read();
|
||||||
|
clipboard.setBlock(x, y, z, getBlockState(ordinal));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -243,7 +246,8 @@ public class FastSchematicReader extends NBTSchematicReader {
|
|||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
for (int z = 0; z < length; z++) {
|
for (int z = 0; z < length; z++) {
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
clipboard.setBlock(x, y, z, getBlockState(fis.readVarInt()));
|
int ordinal = fis.readVarInt();
|
||||||
|
clipboard.setBlock(x, y, z, getBlockState(ordinal));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ package com.sk89q.worldedit.extent.clipboard.io;
|
|||||||
|
|
||||||
import com.boydti.fawe.jnbt.streamer.IntValueReader;
|
import com.boydti.fawe.jnbt.streamer.IntValueReader;
|
||||||
import com.boydti.fawe.object.FaweOutputStream;
|
import com.boydti.fawe.object.FaweOutputStream;
|
||||||
import com.boydti.fawe.object.clipboard.LinearClipboard;
|
|
||||||
import com.boydti.fawe.util.IOUtil;
|
import com.boydti.fawe.util.IOUtil;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
@ -45,7 +44,6 @@ import com.sk89q.worldedit.world.biome.BiomeType;
|
|||||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||||
import net.jpountz.lz4.LZ4BlockOutputStream;
|
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||||
@ -181,6 +179,9 @@ public class FastSchematicWriter implements ClipboardWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ordinal = block.getOrdinal();
|
int ordinal = block.getOrdinal();
|
||||||
|
if (ordinal == 0) {
|
||||||
|
ordinal = 1;
|
||||||
|
}
|
||||||
char value = palette[ordinal];
|
char value = palette[ordinal];
|
||||||
if (value == Character.MAX_VALUE) {
|
if (value == Character.MAX_VALUE) {
|
||||||
int size = paletteMax++;
|
int size = paletteMax++;
|
||||||
|
@ -189,7 +189,15 @@ public class BlockMask extends ABlockMask {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Extent extent, BlockVector3 vector) {
|
public boolean test(Extent extent, BlockVector3 vector) {
|
||||||
return ordinals[vector.getOrdinal(extent)];
|
int test = vector.getOrdinal(extent);
|
||||||
|
return ordinals[test] || replacesAir() && test == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replacesAir() {
|
||||||
|
return ordinals[BlockTypes.AIR.getDefaultState().getOrdinal()]
|
||||||
|
|| ordinals[BlockTypes.CAVE_AIR.getDefaultState().getOrdinal()]
|
||||||
|
|| ordinals[BlockTypes.VOID_AIR.getDefaultState().getOrdinal()];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,6 +26,8 @@ import com.sk89q.worldedit.math.BlockVector3;
|
|||||||
import com.sk89q.worldedit.registry.state.Property;
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockType;
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
@ -65,6 +67,11 @@ public class BlockStateMask extends AbstractExtentMask {
|
|||||||
.allMatch(entry -> block.getState(entry.getKey()) == entry.getValue());
|
.allMatch(entry -> block.getState(entry.getKey()) == entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replacesAir() {
|
||||||
|
return test(BlockTypes.AIR.getDefaultState()) || test(BlockTypes.CAVE_AIR.getDefaultState()) || test(BlockTypes.VOID_AIR.getDefaultState());
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public Mask2D toMask2D() {
|
public Mask2D toMask2D() {
|
||||||
|
@ -43,6 +43,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
public class BlockTypeMask extends AbstractExtentMask {
|
public class BlockTypeMask extends AbstractExtentMask {
|
||||||
|
|
||||||
private final boolean[] types;
|
private final boolean[] types;
|
||||||
|
private boolean hasAir;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new block mask.
|
* Create a new block mask.
|
||||||
@ -63,7 +64,9 @@ public class BlockTypeMask extends AbstractExtentMask {
|
|||||||
public BlockTypeMask(Extent extent, @NotNull BlockType... block) {
|
public BlockTypeMask(Extent extent, @NotNull BlockType... block) {
|
||||||
super(extent);
|
super(extent);
|
||||||
this.types = new boolean[BlockTypes.size()];
|
this.types = new boolean[BlockTypes.size()];
|
||||||
for (BlockType type : block) this.types[type.getInternalId()] = true;
|
for (BlockType type : block) {
|
||||||
|
add(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,9 +79,6 @@ public class BlockTypeMask extends AbstractExtentMask {
|
|||||||
for (BlockType type : blocks) {
|
for (BlockType type : blocks) {
|
||||||
add(type);
|
add(type);
|
||||||
}
|
}
|
||||||
for (BlockType type : blocks) {
|
|
||||||
this.types[type.getInternalId()] = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,6 +88,9 @@ public class BlockTypeMask extends AbstractExtentMask {
|
|||||||
*/
|
*/
|
||||||
public void add(@NotNull BlockType... block) {
|
public void add(@NotNull BlockType... block) {
|
||||||
for (BlockType type : block) {
|
for (BlockType type : block) {
|
||||||
|
if (!hasAir && (type == BlockTypes.AIR || type == BlockTypes.CAVE_AIR || type == BlockTypes.VOID_AIR)) {
|
||||||
|
hasAir = true;
|
||||||
|
}
|
||||||
this.types[type.getInternalId()] = true;
|
this.types[type.getInternalId()] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,6 +113,11 @@ public class BlockTypeMask extends AbstractExtentMask {
|
|||||||
return test(vector.getBlock(extent).getBlockType());
|
return test(vector.getBlock(extent).getBlockType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replacesAir() {
|
||||||
|
return hasAir;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean test(BlockType block) {
|
public boolean test(BlockType block) {
|
||||||
return types[block.getInternalId()];
|
return types[block.getInternalId()];
|
||||||
}
|
}
|
||||||
|
@ -123,4 +123,8 @@ public interface Mask {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default boolean replacesAir() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,11 @@ public class OffsetMask extends AbstractMask {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Extent extent, BlockVector3 pos) {
|
public boolean test(Extent extent, BlockVector3 pos) {
|
||||||
return getMask().test(extent, pos);
|
BlockVector3 testPos = pos.add(offset);
|
||||||
|
if (testPos.getBlockY() < 0 || testPos.getBlockY() > 255) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return getMask().test(extent, pos.add(offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
package com.sk89q.worldedit.function.mask;
|
package com.sk89q.worldedit.function.mask;
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
|
||||||
|
|
||||||
public class SingleBlockStateMask extends ABlockMask {
|
public class SingleBlockStateMask extends ABlockMask {
|
||||||
private final char ordinal;
|
private final char ordinal;
|
||||||
|
private final boolean isAir;
|
||||||
|
|
||||||
public BlockState getBlockState() {
|
public BlockState getBlockState() {
|
||||||
return BlockState.getFromOrdinal(ordinal);
|
return BlockState.getFromOrdinal(ordinal);
|
||||||
@ -15,12 +14,14 @@ public class SingleBlockStateMask extends ABlockMask {
|
|||||||
|
|
||||||
public SingleBlockStateMask(Extent extent, BlockState state) {
|
public SingleBlockStateMask(Extent extent, BlockState state) {
|
||||||
super(extent);
|
super(extent);
|
||||||
|
isAir = state.isAir();
|
||||||
this.ordinal = state.getOrdinalChar();
|
this.ordinal = state.getOrdinalChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Extent extent, BlockVector3 vector) {
|
public boolean test(Extent extent, BlockVector3 vector) {
|
||||||
return ordinal == vector.getOrdinal(extent);
|
int test = vector.getOrdinal(extent);
|
||||||
|
return ordinal == test || isAir && test == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -33,6 +34,11 @@ public class SingleBlockStateMask extends ABlockMask {
|
|||||||
return new InverseSingleBlockStateMask(getExtent(), BlockState.getFromOrdinal(ordinal));
|
return new InverseSingleBlockStateMask(getExtent(), BlockState.getFromOrdinal(ordinal));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replacesAir() {
|
||||||
|
return isAir;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mask tryCombine(Mask mask) {
|
public Mask tryCombine(Mask mask) {
|
||||||
if (mask instanceof ABlockMask) {
|
if (mask instanceof ABlockMask) {
|
||||||
|
@ -8,10 +8,12 @@ import com.sk89q.worldedit.world.block.BlockTypesCache;
|
|||||||
|
|
||||||
public class SingleBlockTypeMask extends ABlockMask {
|
public class SingleBlockTypeMask extends ABlockMask {
|
||||||
private final int internalId;
|
private final int internalId;
|
||||||
|
private final boolean isAir;
|
||||||
|
|
||||||
public SingleBlockTypeMask(Extent extent, BlockType type) {
|
public SingleBlockTypeMask(Extent extent, BlockType type) {
|
||||||
super(extent);
|
super(extent);
|
||||||
this.internalId = type.getInternalId();
|
isAir = type == BlockTypes.AIR || type == BlockTypes.CAVE_AIR || type == BlockTypes.VOID_AIR;
|
||||||
|
this.internalId = type.getInternalId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -27,4 +29,9 @@ public class SingleBlockTypeMask extends ABlockMask {
|
|||||||
public BlockType getBlockType() {
|
public BlockType getBlockType() {
|
||||||
return BlockTypes.get(internalId);
|
return BlockTypes.get(internalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replacesAir() {
|
||||||
|
return isAir;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.sk89q.worldedit.world.block;
|
package com.sk89q.worldedit.world.block;
|
||||||
|
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
|
import com.google.common.primitives.Booleans;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.extension.platform.Capability;
|
import com.sk89q.worldedit.extension.platform.Capability;
|
||||||
import com.sk89q.worldedit.extension.platform.Platform;
|
import com.sk89q.worldedit.extension.platform.Platform;
|
||||||
@ -166,12 +167,14 @@ public class BlockTypesCache {
|
|||||||
|
|
||||||
public static final BlockType[] values;
|
public static final BlockType[] values;
|
||||||
public static final BlockState[] states;
|
public static final BlockState[] states;
|
||||||
|
public static final boolean[] ticking;
|
||||||
|
|
||||||
protected static final Set<String> $NAMESPACES = new LinkedHashSet<>();
|
protected static final Set<String> $NAMESPACES = new LinkedHashSet<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
ArrayList<BlockState> stateList = new ArrayList<>();
|
ArrayList<BlockState> stateList = new ArrayList<>();
|
||||||
|
ArrayList<Boolean> tickList = new ArrayList<>();
|
||||||
|
|
||||||
Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS);
|
Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS);
|
||||||
Registries registries = platform.getRegistries();
|
Registries registries = platform.getRegistries();
|
||||||
@ -202,7 +205,7 @@ public class BlockTypesCache {
|
|||||||
if (values[internalId] != null) {
|
if (values[internalId] != null) {
|
||||||
throw new IllegalStateException("Invalid duplicate id for " + field.getName());
|
throw new IllegalStateException("Invalid duplicate id for " + field.getName());
|
||||||
}
|
}
|
||||||
BlockType type = register(defaultState, internalId, stateList);
|
BlockType type = register(defaultState, internalId, stateList, tickList);
|
||||||
// Note: Throws IndexOutOfBoundsError if nothing is registered and blocksMap is empty
|
// Note: Throws IndexOutOfBoundsError if nothing is registered and blocksMap is empty
|
||||||
values[internalId] = type;
|
values[internalId] = type;
|
||||||
}
|
}
|
||||||
@ -214,7 +217,7 @@ public class BlockTypesCache {
|
|||||||
String defaultState = entry.getValue();
|
String defaultState = entry.getValue();
|
||||||
// Skip already registered ids
|
// Skip already registered ids
|
||||||
for (; values[internalId] != null; internalId++);
|
for (; values[internalId] != null; internalId++);
|
||||||
BlockType type = register(defaultState, internalId, stateList);
|
BlockType type = register(defaultState, internalId, stateList, tickList);
|
||||||
values[internalId] = type;
|
values[internalId] = type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,7 +226,7 @@ public class BlockTypesCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
states = stateList.toArray(new BlockState[stateList.size()]);
|
states = stateList.toArray(new BlockState[stateList.size()]);
|
||||||
|
ticking = Booleans.toArray(tickList);
|
||||||
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -231,12 +234,14 @@ public class BlockTypesCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BlockType register(final String id, int internalId, List<BlockState> states) {
|
private static BlockType register(final String id, int internalId, List<BlockState> states, List<Boolean> tickList) {
|
||||||
// Get the enum name (remove namespace if minecraft:)
|
// Get the enum name (remove namespace if minecraft:)
|
||||||
int propStart = id.indexOf('[');
|
int propStart = id.indexOf('[');
|
||||||
String typeName = id.substring(0, propStart == -1 ? id.length() : propStart);
|
String typeName = id.substring(0, propStart == -1 ? id.length() : propStart);
|
||||||
String enumName = (typeName.startsWith("minecraft:") ? typeName.substring(10) : typeName).toUpperCase(Locale.ROOT);
|
String enumName = (typeName.startsWith("minecraft:") ? typeName.substring(10) : typeName).toUpperCase(Locale.ROOT);
|
||||||
|
int oldsize = states.size();
|
||||||
BlockType existing = new BlockType(id, internalId, states);
|
BlockType existing = new BlockType(id, internalId, states);
|
||||||
|
tickList.addAll(Collections.nCopies(states.size() - oldsize, existing.getMaterial().isTicksRandomly()));
|
||||||
// register states
|
// register states
|
||||||
BlockType.REGISTRY.register(typeName, existing);
|
BlockType.REGISTRY.register(typeName, existing);
|
||||||
String nameSpace = typeName.substring(0, typeName.indexOf(':'));
|
String nameSpace = typeName.substring(0, typeName.indexOf(':'));
|
||||||
|
@ -72,10 +72,10 @@
|
|||||||
"fawe.worldedit.history.command.history.clear": "History cleared",
|
"fawe.worldedit.history.command.history.clear": "History cleared",
|
||||||
"fawe.worldedit.history.command.redo.error": "Nothing left to redo. (See also `/inspect` and `/frb`)",
|
"fawe.worldedit.history.command.redo.error": "Nothing left to redo. (See also `/inspect` and `/frb`)",
|
||||||
"fawe.worldedit.history.command.history.other.error": "Unable to find session for {0}.",
|
"fawe.worldedit.history.command.history.other.error": "Unable to find session for {0}.",
|
||||||
"fawe.worldedit.history.command.redo.success": "Redo successful{0}.",
|
"fawe.worldedit.history.command.redo.success": "Redo successful {0}.",
|
||||||
"fawe.worldedit.history.command.undo.error": "Nothing left to undo. (See also `/inspect` and `/frb`)",
|
"fawe.worldedit.history.command.undo.error": "Nothing left to undo. (See also `/inspect` and `/frb`)",
|
||||||
"fawe.worldedit.history.command.undo.disabled": "Undo disabled, use: //fast",
|
"fawe.worldedit.history.command.undo.disabled": "Undo disabled, use: //fast",
|
||||||
"fawe.worldedit.history.command.undo.success": "Undo successful{0}.",
|
"fawe.worldedit.history.command.undo.success": "Undo successful {0}.",
|
||||||
|
|
||||||
"fawe.worldedit.operation.operation": "Operation queued ({0})",
|
"fawe.worldedit.operation.operation": "Operation queued ({0})",
|
||||||
|
|
||||||
@ -97,7 +97,7 @@
|
|||||||
"fawe.worldedit.selection.selection.shift": "Region shifted",
|
"fawe.worldedit.selection.selection.shift": "Region shifted",
|
||||||
"fawe.worldedit.selection.selection.cleared": "Selection cleared",
|
"fawe.worldedit.selection.selection.cleared": "Selection cleared",
|
||||||
|
|
||||||
"fawe.worldedit.anvil.world.is.loaded": "The world shouldn't be in use when executing. Unload the world, or use use -f to override (save first)",
|
"fawe.worldedit.anvil.world.is.loaded": "The world shouldn't be in use when executing. Unload the world, or use -f to override (save first)",
|
||||||
|
|
||||||
"fawe.worldedit.brush.brush.reset": "Reset your brush. (SHIFT + Click)",
|
"fawe.worldedit.brush.brush.reset": "Reset your brush. (SHIFT + Click)",
|
||||||
"fawe.worldedit.brush.brush.none": "You aren't holding a brush!",
|
"fawe.worldedit.brush.brush.none": "You aren't holding a brush!",
|
||||||
@ -238,7 +238,7 @@
|
|||||||
|
|
||||||
"fawe.error.command.syntax": "Usage: {0}",
|
"fawe.error.command.syntax": "Usage: {0}",
|
||||||
"fawe.error.no-perm": "You are lacking the permission node: {0}",
|
"fawe.error.no-perm": "You are lacking the permission node: {0}",
|
||||||
"fawe.error.block.not.allowed": "You are not allowed to use",
|
"fawe.error.block.not.allowed": "You are not allowed to use: {0}",
|
||||||
"fawe.error.setting.disable": "Lacking setting: {0}",
|
"fawe.error.setting.disable": "Lacking setting: {0}",
|
||||||
"fawe.error.brush.not.found": "Available brushes: {0}",
|
"fawe.error.brush.not.found": "Available brushes: {0}",
|
||||||
"fawe.error.brush.incompatible": "Brush not compatible with this version",
|
"fawe.error.brush.incompatible": "Brush not compatible with this version",
|
||||||
@ -373,7 +373,7 @@
|
|||||||
"worldedit.limit.set": "Block change limit set to {0}.",
|
"worldedit.limit.set": "Block change limit set to {0}.",
|
||||||
"worldedit.limit.return-to-default": "(Use //limit to go back to the default.)",
|
"worldedit.limit.return-to-default": "(Use //limit to go back to the default.)",
|
||||||
"worldedit.timeout.too-high": "Your maximum allowable timeout is {0}ms.",
|
"worldedit.timeout.too-high": "Your maximum allowable timeout is {0}ms.",
|
||||||
"worldedit.timeout.set": "Timeout time set to {0} ms.",
|
"worldedit.timeout.set": "Timeout time set to {0}ms.",
|
||||||
"worldedit.timeout.return-to-default": " (Use //timeout to go back to the default.)",
|
"worldedit.timeout.return-to-default": " (Use //timeout to go back to the default.)",
|
||||||
"worldedit.fast.disabled": "Fast mode disabled.",
|
"worldedit.fast.disabled": "Fast mode disabled.",
|
||||||
"worldedit.fast.enabled": "Fast mode enabled. Lighting in the affected chunks may be wrong and/or you may need to rejoin to see changes.",
|
"worldedit.fast.enabled": "Fast mode enabled. Lighting in the affected chunks may be wrong and/or you may need to rejoin to see changes.",
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren