3
0
Mirror von https://github.com/IntellectualSites/FastAsyncWorldEdit.git synchronisiert 2024-10-02 03:40:06 +02:00

Merge branch 'main' into feat/feature-placement

Dieser Commit ist enthalten in:
dordsor21 2024-03-27 16:33:32 +00:00
Commit 3eecb36e18
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 1E53E88969FFCF0B
43 geänderte Dateien mit 426 neuen und 85 gelöschten Zeilen

Datei anzeigen

@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Label conflicting PRs - name: Label conflicting PRs
uses: eps1lon/actions-label-merge-conflict@v2.1.0 uses: eps1lon/actions-label-merge-conflict@v3.0.0
with: with:
dirtyLabel: "unresolved-merge-conflict" dirtyLabel: "unresolved-merge-conflict"
repoToken: "${{ secrets.GITHUB_TOKEN }}" repoToken: "${{ secrets.GITHUB_TOKEN }}"

Datei anzeigen

@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT"
griefprevention = "17.0.0" griefprevention = "17.0.0"
griefdefender = "2.1.0-SNAPSHOT" griefdefender = "2.1.0-SNAPSHOT"
residence = "4.5._13.1" residence = "4.5._13.1"
towny = "0.100.1.20" towny = "0.100.1.23"
plotsquared = "7.3.6" plotsquared = "7.3.6"
# Third party # Third party

Binäre Datei nicht angezeigt.

Datei anzeigen

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

Datei anzeigen

@ -12,6 +12,6 @@ repositories {
dependencies { dependencies {
// url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.4-R0.1-20240106.182028-62") the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.4-R0.1-20240325.123556-143")
compileOnly(libs.paperlib) compileOnly(libs.paperlib)
} }

Datei anzeigen

@ -2,18 +2,15 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R3;
import com.google.common.base.Suppliers; import com.google.common.base.Suppliers;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.util.ReflectionUtil;
import com.sk89q.worldedit.bukkit.adapter.Refraction;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R3.nbt.PaperweightLazyCompoundTag; import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R3.nbt.PaperweightLazyCompoundTag;
import com.sk89q.worldedit.world.registry.BlockMaterial; import com.sk89q.worldedit.world.registry.BlockMaterial;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.level.EmptyBlockGetter; import net.minecraft.world.level.EmptyBlockGetter;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.LiquidBlock;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.level.material.PushReaction; import net.minecraft.world.level.material.PushReaction;
import org.bukkit.craftbukkit.v1_20_R3.block.data.CraftBlockData; import org.bukkit.craftbukkit.v1_20_R3.block.data.CraftBlockData;
@ -21,7 +18,6 @@ public class PaperweightBlockMaterial implements BlockMaterial {
private final Block block; private final Block block;
private final BlockState blockState; private final BlockState blockState;
private final boolean isTranslucent;
private final CraftBlockData craftBlockData; private final CraftBlockData craftBlockData;
private final org.bukkit.Material craftMaterial; private final org.bukkit.Material craftMaterial;
private final int opacity; private final int opacity;
@ -36,11 +32,6 @@ public class PaperweightBlockMaterial implements BlockMaterial {
this.blockState = blockState; this.blockState = blockState;
this.craftBlockData = CraftBlockData.fromData(blockState); this.craftBlockData = CraftBlockData.fromData(blockState);
this.craftMaterial = craftBlockData.getMaterial(); this.craftMaterial = craftBlockData.getMaterial();
BlockBehaviour.Properties blockInfo = ReflectionUtil.getField(BlockBehaviour.class, block,
Refraction.pickName("properties", "aP"));
this.isTranslucent = !(boolean) ReflectionUtil.getField(BlockBehaviour.Properties.class, blockInfo,
Refraction.pickName("canOcclude", "n")
);
opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO); opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity( BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity(
BlockPos.ZERO, BlockPos.ZERO,
@ -75,7 +66,7 @@ public class PaperweightBlockMaterial implements BlockMaterial {
@Override @Override
public boolean isOpaque() { public boolean isOpaque() {
return blockState.isOpaque(); return blockState.canOcclude();
} }
@Override @Override
@ -85,14 +76,13 @@ public class PaperweightBlockMaterial implements BlockMaterial {
@Override @Override
public boolean isLiquid() { public boolean isLiquid() {
// TODO: Better check ? return !blockState.getFluidState().is(Fluids.EMPTY);
return block instanceof LiquidBlock;
} }
@Override @Override
public boolean isSolid() { public boolean isSolid() {
// TODO: Replace // No access to world -> EmptyBlockGetter
return blockState.isSolid(); return blockState.isSolidRender(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
} }
@Override @Override
@ -158,7 +148,7 @@ public class PaperweightBlockMaterial implements BlockMaterial {
@Override @Override
public boolean isTranslucent() { public boolean isTranslucent() {
return isTranslucent; return !blockState.canOcclude();
} }
@Override @Override

Datei anzeigen

@ -329,12 +329,12 @@ public class BukkitWorld extends AbstractWorld {
treeTypeMapping.put(TreeGenerator.TreeType.RANDOM_MUSHROOM, TreeType.BROWN_MUSHROOM); treeTypeMapping.put(TreeGenerator.TreeType.RANDOM_MUSHROOM, TreeType.BROWN_MUSHROOM);
for (TreeGenerator.TreeType type : TreeGenerator.TreeType.values()) { for (TreeGenerator.TreeType type : TreeGenerator.TreeType.values()) {
if (treeTypeMapping.get(type) == null) { if (treeTypeMapping.get(type) == null) {
LOGGER.error("No TreeType mapping for TreeGenerator.TreeType." + type);
//FAWE start //FAWE start
LOGGER.info("No TreeType mapping for TreeGenerator.TreeType." + type);
LOGGER.info("The above message is displayed because your FAWE version is newer than {}" + LOGGER.info("The above message is displayed because your FAWE version is newer than {}" +
" and contains features of future minecraft versions which do not exist in {} hence the tree type" + " and contains features of future minecraft versions which do not exist in {} hence the tree type" +
"{} is not available. This is not an error. This version will work on your version of Minecraft." + " {} is not available. This is not an error. This version of FAWE will work on your version of " +
"This is an informative message only.", Bukkit.getVersion(), Bukkit.getVersion(), type); " Minecraft. This is an informative message only.", Bukkit.getVersion(), Bukkit.getVersion(), type);
//FAWE end //FAWE end
} }
} }

Datei anzeigen

@ -53,7 +53,7 @@ public class HeightBrush implements Brush {
try { try {
heightMap = ScalableHeightMap.fromPNG(stream); heightMap = ScalableHeightMap.fromPNG(stream);
} catch (IOException e) { } catch (IOException e) {
throw new FaweException(Caption.of("fawe.worldedit.brush.brush.height.invalid")); throw new FaweException(Caption.of("fawe.worldedit.brush.brush.height.invalid", e.getMessage()));
} }
} else if (clipboard != null) { } else if (clipboard != null) {
heightMap = ScalableHeightMap.fromClipboard(clipboard, minY, maxY); heightMap = ScalableHeightMap.fromClipboard(clipboard, minY, maxY);

Datei anzeigen

@ -2,7 +2,7 @@ package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser; import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.Linear2DBlockPattern; import com.fastasyncworldedit.core.math.random.Linear2DRandom;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper; import com.sk89q.worldedit.command.util.SuggestionHelper;
@ -14,7 +14,6 @@ import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.Set;
import java.util.stream.Stream; import java.util.stream.Stream;
public class Linear2DPatternParser extends RichParser<Pattern> { public class Linear2DPatternParser extends RichParser<Pattern> {
@ -59,9 +58,8 @@ public class Linear2DPatternParser extends RichParser<Pattern> {
zScale = Integer.parseInt(arguments[2]); zScale = Integer.parseInt(arguments[2]);
Preconditions.checkArgument(zScale != 0); Preconditions.checkArgument(zScale != 0);
} }
if (inner instanceof RandomPattern) { if (inner instanceof RandomPattern rp) {
Set<Pattern> patterns = ((RandomPattern) inner).getPatterns(); return new RandomPattern(new Linear2DRandom(xScale, zScale), rp);
return new Linear2DBlockPattern(patterns.toArray(new Pattern[0]), xScale, zScale);
} }
throw new InputParseException(TextComponent.of("Pattern " + inner.getClass().getSimpleName() throw new InputParseException(TextComponent.of("Pattern " + inner.getClass().getSimpleName()
+ " cannot be used with " + getPrefix())); + " cannot be used with " + getPrefix()));

Datei anzeigen

@ -2,7 +2,7 @@ package com.fastasyncworldedit.core.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.RichParser; import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
import com.fastasyncworldedit.core.function.pattern.Linear3DBlockPattern; import com.fastasyncworldedit.core.math.random.Linear3DRandom;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper; import com.sk89q.worldedit.command.util.SuggestionHelper;
@ -14,7 +14,6 @@ import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.Set;
import java.util.stream.Stream; import java.util.stream.Stream;
public class Linear3DPatternParser extends RichParser<Pattern> { public class Linear3DPatternParser extends RichParser<Pattern> {
@ -64,9 +63,8 @@ public class Linear3DPatternParser extends RichParser<Pattern> {
zScale = Integer.parseInt(arguments[3]); zScale = Integer.parseInt(arguments[3]);
Preconditions.checkArgument(zScale != 0); Preconditions.checkArgument(zScale != 0);
} }
if (inner instanceof RandomPattern) { if (inner instanceof RandomPattern rp) {
Set<Pattern> patterns = ((RandomPattern) inner).getPatterns(); return new RandomPattern(new Linear3DRandom(xScale, yScale, zScale), rp);
return new Linear3DBlockPattern(patterns.toArray(new Pattern[0]), xScale, yScale, zScale);
} }
throw new InputParseException(TextComponent.of("Pattern " + inner.getClass().getSimpleName() throw new InputParseException(TextComponent.of("Pattern " + inner.getClass().getSimpleName()
+ " cannot be used with " + getPrefix())); + " cannot be used with " + getPrefix()));

Datei anzeigen

@ -19,12 +19,9 @@ import org.apache.logging.log4j.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -80,28 +77,18 @@ public class MultiBatchProcessor implements IBatchProcessor {
@Override @Override
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) { public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
Map<Integer, Set<IBatchProcessor>> ordered = new HashMap<>(); Map<Integer, List<IBatchProcessor>> ordered = new HashMap<>();
IChunkSet chunkSet = set; IChunkSet chunkSet = set;
for (IBatchProcessor processor : processors) { for (IBatchProcessor processor : processors) {
if (processor.getScope() != ProcessorScope.ADDING_BLOCKS) { if (processor.getScope() != ProcessorScope.ADDING_BLOCKS) {
ordered.merge( ordered.computeIfAbsent(processor.getScope().intValue(), k -> new ArrayList<>())
processor.getScope().intValue(), .add(processor);
new HashSet<>(Collections.singleton(processor)),
(existing, theNew) -> {
existing.add(processor);
return existing;
}
);
continue; continue;
} }
chunkSet = processSet(processor, chunk, get, chunkSet); chunkSet = processSet(processor, chunk, get, chunkSet);
} }
if (ordered.size() > 0) { if (!ordered.isEmpty()) {
for (int i = 1; i <= 4; i++) { for (List<IBatchProcessor> processors : ordered.values()) {
Set<IBatchProcessor> processors = ordered.get(i);
if (processors == null) {
continue;
}
for (IBatchProcessor processor : processors) { for (IBatchProcessor processor : processors) {
chunkSet = processSet(processor, chunk, get, chunkSet); chunkSet = processSet(processor, chunk, get, chunkSet);
if (chunkSet == null) { if (chunkSet == null) {

Datei anzeigen

@ -1,6 +1,7 @@
package com.fastasyncworldedit.core.function.pattern; package com.fastasyncworldedit.core.function.pattern;
import com.sk89q.worldedit.function.pattern.AbstractPattern; import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.expression.EvaluationException; import com.sk89q.worldedit.internal.expression.EvaluationException;
import com.sk89q.worldedit.internal.expression.Expression; import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.internal.expression.ExpressionException;
@ -57,4 +58,9 @@ public class ExpressionPattern extends AbstractPattern {
} }
} }
@Override
public Pattern fork() {
return new ExpressionPattern(this.expression.clone());
}
} }

Datei anzeigen

@ -7,8 +7,15 @@ import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import java.util.Arrays;
import static java.lang.Math.floorDiv; import static java.lang.Math.floorDiv;
/**
* @deprecated replaced by {@link com.sk89q.worldedit.function.pattern.RandomPattern}
* combined with {@link com.fastasyncworldedit.core.math.random.Linear2DRandom}.
*/
@Deprecated(forRemoval = true, since = "TODO")
public class Linear2DBlockPattern extends AbstractPattern { public class Linear2DBlockPattern extends AbstractPattern {
private final Pattern[] patternsArray; private final Pattern[] patternsArray;
@ -47,4 +54,10 @@ public class Linear2DBlockPattern extends AbstractPattern {
return patternsArray[index].apply(extent, get, set); return patternsArray[index].apply(extent, get, set);
} }
@Override
public Pattern fork() {
final Pattern[] forked = Arrays.stream(this.patternsArray).map(Pattern::fork).toArray(Pattern[]::new);
return new Linear2DBlockPattern(forked, this.xScale, this.zScale);
}
} }

Datei anzeigen

@ -7,8 +7,15 @@ import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import java.util.Arrays;
import static java.lang.Math.floorDiv; import static java.lang.Math.floorDiv;
/**
* @deprecated replaced by {@link com.sk89q.worldedit.function.pattern.RandomPattern}
* combined with {@link com.fastasyncworldedit.core.math.random.Linear3DRandom}.
*/
@Deprecated(forRemoval = true, since = "TODO")
public class Linear3DBlockPattern extends AbstractPattern { public class Linear3DBlockPattern extends AbstractPattern {
private final Pattern[] patternsArray; private final Pattern[] patternsArray;
@ -51,4 +58,10 @@ public class Linear3DBlockPattern extends AbstractPattern {
return patternsArray[index].apply(extent, get, set); return patternsArray[index].apply(extent, get, set);
} }
@Override
public Pattern fork() {
final Pattern[] forked = Arrays.stream(this.patternsArray).map(Pattern::fork).toArray(Pattern[]::new);
return new Linear3DBlockPattern(forked, this.xScale, this.yScale, this.zScale);
}
} }

Datei anzeigen

@ -1,5 +1,6 @@
package com.fastasyncworldedit.core.function.pattern; package com.fastasyncworldedit.core.function.pattern;
import com.fastasyncworldedit.core.queue.Filter;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern; import com.sk89q.worldedit.function.pattern.AbstractPattern;
@ -7,6 +8,8 @@ import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import java.util.Arrays;
public class LinearBlockPattern extends AbstractPattern implements ResettablePattern { public class LinearBlockPattern extends AbstractPattern implements ResettablePattern {
private final Pattern[] patternsArray; private final Pattern[] patternsArray;
@ -15,7 +18,7 @@ public class LinearBlockPattern extends AbstractPattern implements ResettablePat
/** /**
* Create a new {@link Pattern} instance * Create a new {@link Pattern} instance
* *
* @param patterns array of patterns to linearly choose from based on x/z coordinates * @param patterns array of patterns to linearly choose from
*/ */
public LinearBlockPattern(Pattern[] patterns) { public LinearBlockPattern(Pattern[] patterns) {
this.patternsArray = patterns; this.patternsArray = patterns;
@ -23,18 +26,14 @@ public class LinearBlockPattern extends AbstractPattern implements ResettablePat
@Override @Override
public BaseBlock applyBlock(BlockVector3 position) { public BaseBlock applyBlock(BlockVector3 position) {
if (index == patternsArray.length) { index = (index + 1) % patternsArray.length;
index = 0; return patternsArray[index].applyBlock(position);
}
return patternsArray[index++].applyBlock(position);
} }
@Override @Override
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
if (index == patternsArray.length) { index = (index + 1) % patternsArray.length;
index = 0; return patternsArray[index].apply(extent, get, set);
}
return patternsArray[index++].apply(extent, get, set);
} }
@Override @Override
@ -42,4 +41,10 @@ public class LinearBlockPattern extends AbstractPattern implements ResettablePat
index = 0; index = 0;
} }
@Override
public Pattern fork() {
final Pattern[] forked = Arrays.stream(this.patternsArray).map(Pattern::fork).toArray(Pattern[]::new);
return new LinearBlockPattern(forked);
}
} }

Datei anzeigen

@ -43,4 +43,9 @@ public class MaskedPattern extends AbstractPattern {
return secondary.apply(extent, get, set); return secondary.apply(extent, get, set);
} }
@Override
public Pattern fork() {
return new MaskedPattern(this.mask.copy(), this.primary.fork(), this.secondary.fork());
}
} }

Datei anzeigen

@ -36,4 +36,9 @@ public class NoXPattern extends AbstractPattern {
return pattern.apply(extent, mutable, set); return pattern.apply(extent, mutable, set);
} }
@Override
public Pattern fork() {
return new NoXPattern(this.pattern.fork());
}
} }

Datei anzeigen

@ -36,4 +36,9 @@ public class NoYPattern extends AbstractPattern {
return pattern.apply(extent, mutable, set); return pattern.apply(extent, mutable, set);
} }
@Override
public Pattern fork() {
return new NoYPattern(this.pattern.fork());
}
} }

Datei anzeigen

@ -1,6 +1,7 @@
package com.fastasyncworldedit.core.function.pattern; package com.fastasyncworldedit.core.function.pattern;
import com.fastasyncworldedit.core.math.MutableBlockVector3; import com.fastasyncworldedit.core.math.MutableBlockVector3;
import com.fastasyncworldedit.core.queue.Filter;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern; import com.sk89q.worldedit.function.pattern.AbstractPattern;
@ -36,4 +37,9 @@ public class NoZPattern extends AbstractPattern {
return pattern.apply(extent, mutable, set); return pattern.apply(extent, mutable, set);
} }
@Override
public Pattern fork() {
return new NoZPattern(this.pattern.fork());
}
} }

Datei anzeigen

@ -60,4 +60,9 @@ public class OffsetPattern extends AbstractPattern {
return pattern.apply(extent, get, mutable); return pattern.apply(extent, get, mutable);
} }
@Override
public Pattern fork() {
return new OffsetPattern(this.pattern.fork(), this.dx, this.dy, this.dz, this.minY, this.maxY);
}
} }

Datei anzeigen

@ -72,4 +72,9 @@ public class RandomOffsetPattern extends AbstractPattern {
return pattern.apply(extent, get, mutable); return pattern.apply(extent, get, mutable);
} }
@Override
public Pattern fork() {
return new RandomOffsetPattern(this.pattern.fork(), this.dx, this.dy, this.dz, this.minY, this.maxY);
}
} }

Datei anzeigen

@ -63,4 +63,11 @@ public class RelativePattern extends AbstractPattern implements ResettablePatter
origin = null; origin = null;
} }
@Override
public Pattern fork() {
RelativePattern forked = new RelativePattern(this.pattern.fork(), this.minY, this.maxY);
forked.origin = this.origin; // maintain origin for forks
return forked;
}
} }

Datei anzeigen

@ -94,4 +94,9 @@ public class SolidRandomOffsetPattern extends AbstractPattern {
return pattern.apply(extent, get, set); return pattern.apply(extent, get, set);
} }
@Override
public Pattern fork() {
return new SolidRandomOffsetPattern(this.pattern.fork(), this.dx, this.dy, this.dz, this.minY, this.maxY);
}
} }

Datei anzeigen

@ -129,4 +129,9 @@ public class SurfaceRandomOffsetPattern extends AbstractPattern {
return !block.getBlockType().getMaterial().isMovementBlocker(); return !block.getBlockType().getMaterial().isMovementBlocker();
} }
@Override
public Pattern fork() {
return new SurfaceRandomOffsetPattern(this.pattern.fork(), this.moves, this.minY, this.maxY);
}
} }

Datei anzeigen

@ -0,0 +1,50 @@
package com.fastasyncworldedit.core.math.random;
import static com.fastasyncworldedit.core.math.random.Linear3DRandom.doubleDiv;
import static java.lang.Math.floorDiv;
/**
* A {@link SimpleRandom} that deterministically maps coordinates
* to values.
* @since TODO
*/
public class Linear2DRandom implements SimpleRandom {
private final int xScale;
private final int zScale;
/**
* Creates a new {@link Linear2DRandom} instance
*
* @param xScale the scale applied to the x component of a coordinate
* @param zScale the scale applied to the z component of a coordinate
*/
public Linear2DRandom(final int xScale, final int zScale) {
this.xScale = xScale;
this.zScale = zScale;
}
@Override
public double nextDouble(final int x, final int y, final int z) {
return nextDouble(x, y, z, 1d);
}
@Override
public double nextDouble(final int x, final int y, final int z, double bound) {
double index = (doubleDiv(x, this.xScale) + doubleDiv(z, this.zScale)) % bound;
if (index < 0) {
index += bound;
}
return index;
}
@Override
public int nextInt(final int x, final int y, final int z, final int bound) {
int index = (floorDiv(x, this.xScale) + floorDiv(z, this.zScale)) % bound;
if (index < 0) {
index += bound;
}
return index;
}
}

Datei anzeigen

@ -0,0 +1,58 @@
package com.fastasyncworldedit.core.math.random;
import static java.lang.Math.floorDiv;
/**
* A {@link SimpleRandom} that deterministically maps coordinates
* to values.
* @since TODO
*/
public class Linear3DRandom implements SimpleRandom {
private final int xScale;
private final int yScale;
private final int zScale;
/**
* Creates a new {@link Linear3DRandom} instance
*
* @param xScale the scale applied to the x component of a coordinate
* @param yScale the scale applied to the y component of a coordinate
* @param zScale the scale applied to the z component of a coordinate
*/
public Linear3DRandom(final int xScale, final int yScale, final int zScale) {
this.xScale = xScale;
this.yScale = yScale;
this.zScale = zScale;
}
@Override
public double nextDouble(final int x, final int y, final int z) {
return nextDouble(x, y, z, 1d);
}
@Override
public double nextDouble(final int x, final int y, final int z, double bound) {
double index = (doubleDiv(x, this.xScale) + doubleDiv(y, this.yScale) + doubleDiv(z, this.zScale)) % bound;
if (index < 0) {
index += bound;
}
return index;
}
// used to avoid explicit conversion at call site
static double doubleDiv(double dividend, double divisor) {
// add a minimal value to avoid too many integral values hitting the exact weight of an entry in SimpleRandomCollection
return Math.nextUp(dividend) / divisor;
}
@Override
public int nextInt(final int x, final int y, final int z, final int bound) {
int index = (floorDiv(x, this.xScale) + floorDiv(y, this.yScale) + floorDiv(z, this.zScale)) % bound;
if (index < 0) {
index += bound;
}
return index;
}
}

Datei anzeigen

@ -13,6 +13,20 @@ public interface SimpleRandom {
*/ */
double nextDouble(int x, int y, int z); double nextDouble(int x, int y, int z);
/**
* Generate a random double from three integer components.
* The generated value is between 0 (inclusive) and {@code bound} (exclusive).
*
* @param x the first component
* @param y the second component
* @param z the third component
* @param bound upper bound (exclusive)
* @return a double between 0 (inclusive) and {@code bound} (exclusive)
*/
default double nextDouble(int x, int y, int z, double bound) {
return nextDouble(x, y, z) * bound;
}
/** /**
* Generate a random integer from three integer components. * Generate a random integer from three integer components.
* The generated value is between 0 (inclusive) and 1 (exclusive) * The generated value is between 0 (inclusive) and 1 (exclusive)
@ -24,8 +38,8 @@ public interface SimpleRandom {
* @return a random integer between 0 (inclusive) and {@code bound} (exclusive) * @return a random integer between 0 (inclusive) and {@code bound} (exclusive)
*/ */
default int nextInt(int x, int y, int z, int bound) { default int nextInt(int x, int y, int z, int bound) {
double val = nextDouble(x, y, z); double val = nextDouble(x, y, z, bound);
return (int) (val * bound); return (int) val;
} }
} }

Datei anzeigen

@ -51,11 +51,10 @@ public class ExtentTraverser<T extends Extent> {
return last; return last;
} }
@SuppressWarnings("unchecked")
@Nullable @Nullable
public <U> U findAndGet(Class<U> clazz) { public <U extends Extent> U findAndGet(Class<U> clazz) {
ExtentTraverser<Extent> traverser = find(clazz); ExtentTraverser<U> traverser = find(clazz);
return (traverser != null) ? (U) traverser.get() : null; return (traverser != null) ? traverser.get() : null;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

Datei anzeigen

@ -38,6 +38,9 @@ import org.apache.logging.log4j.Logger;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream; import java.io.BufferedOutputStream;
@ -56,6 +59,9 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.channels.Channels; import java.nio.channels.Channels;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
@ -70,6 +76,7 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -91,6 +98,10 @@ import static java.lang.System.arraycopy;
public class MainUtil { public class MainUtil {
private static final Logger LOGGER = LogManagerCompat.getLogger(); private static final Logger LOGGER = LogManagerCompat.getLogger();
private static final String CURL_USER_AGENT = "curl/8.1.1";
private static final HttpClient HTTP_CLIENT = HttpClient.newBuilder()
.followRedirects(HttpClient.Redirect.NORMAL)
.build();
public static List<String> filter(String prefix, List<String> suggestions) { public static List<String> filter(String prefix, List<String> suggestions) {
if (prefix.isEmpty()) { if (prefix.isEmpty()) {
@ -519,12 +530,53 @@ public class MainUtil {
return destFile; return destFile;
} }
public static BufferedImage readImage(InputStream in) throws IOException { public static BufferedImage readImage(InputStream stream) throws IOException {
return MainUtil.toRGB(ImageIO.read(in)); final ImageInputStream imageStream = ImageIO.createImageInputStream(stream);
if (imageStream == null) {
throw new IOException("Can't find suitable ImageInputStream");
}
Iterator<ImageReader> iter = ImageIO.getImageReaders(imageStream);
if (!iter.hasNext()) {
throw new IOException("Could not get image reader from stream.");
}
ImageReader reader = iter.next();
ImageReadParam param = reader.getDefaultReadParam();
reader.setInput(imageStream, true, true);
BufferedImage bi;
try {
bi = reader.read(0, param);
} finally {
reader.dispose();
stream.close();
imageStream.close();
}
return MainUtil.toRGB(bi);
} }
public static BufferedImage readImage(URL url) throws IOException { public static BufferedImage readImage(URL url) throws IOException {
return readImage(url.openStream()); try {
final URI uri = url.toURI();
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(uri).GET();
if (uri.getHost().equalsIgnoreCase("i.imgur.com")) {
requestBuilder = requestBuilder.setHeader("User-Agent", CURL_USER_AGENT);
}
final HttpResponse<InputStream> response = HTTP_CLIENT.send(
requestBuilder.build(),
HttpResponse.BodyHandlers.ofInputStream()
);
try (final InputStream body = response.body()) {
if (response.statusCode() > 299) {
throw new IOException("Expected 2xx as response code, but received " + response.statusCode());
}
return readImage(body);
}
} catch (InterruptedException e) {
throw new IOException("request was interrupted", e);
} catch (URISyntaxException e) {
throw new IOException("failed to parse url to uri reference", e);
}
} }
public static BufferedImage readImage(File file) throws IOException { public static BufferedImage readImage(File file) throws IOException {

Datei anzeigen

@ -36,7 +36,7 @@ public class SimpleRandomCollection<E> extends RandomCollection<E> {
@Override @Override
public E next(int x, int y, int z) { public E next(int x, int y, int z) {
return map.ceilingEntry(getRandom().nextDouble(x, y, z) * this.total).getValue(); return map.ceilingEntry(getRandom().nextDouble(x, y, z, this.total)).getValue();
} }
} }

Datei anzeigen

@ -1,4 +1,4 @@
package com.sk89q.worldedit.util.gson; package com.fastasyncworldedit.core.util.gson;
import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer; import com.google.gson.JsonDeserializer;

Datei anzeigen

@ -0,0 +1,33 @@
package com.fastasyncworldedit.core.util.gson;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.regions.selector.RegionSelectorType;
import java.lang.reflect.Type;
public class RegionSelectorAdapter implements JsonDeserializer<RegionSelector>, JsonSerializer<RegionSelector> {
@Override
public RegionSelector deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
RegionSelectorType regionType = RegionSelectorType.valueOf(json.getAsString());
return regionType.createSelector();
}
@Override
public JsonElement serialize(RegionSelector selector, Type type, JsonSerializationContext context) {
RegionSelectorType regionType = RegionSelectorType.getForSelector(selector);
// Cannot nicely deserialize Fuzzy region type
if (regionType == null || regionType == RegionSelectorType.FUZZY) {
return null;
}
return new JsonPrimitive(regionType.toString());
}
}

Datei anzeigen

@ -125,7 +125,9 @@ public class LocalSession implements TextureHolder {
private transient int cuiVersion = CUI_VERSION_UNINITIALIZED; private transient int cuiVersion = CUI_VERSION_UNINITIALIZED;
// Session related // Session related
private transient RegionSelector selector = new CuboidRegionSelector(); //FAWE start - allow saving to session store
private RegionSelector selector = new CuboidRegionSelector();
//FAWE end
private transient boolean placeAtPos1 = false; private transient boolean placeAtPos1 = false;
//FAWE start //FAWE start
private final transient List<Object> history = Collections.synchronizedList(new LinkedList<>() { private final transient List<Object> history = Collections.synchronizedList(new LinkedList<>() {
@ -771,6 +773,7 @@ public class LocalSession implements TextureHolder {
checkNotNull(selector); checkNotNull(selector);
selector.setWorld(world); selector.setWorld(world);
this.selector = selector; this.selector = selector;
setDirty();
if (hasWorldOverride() && !world.equals(getWorldOverride())) { if (hasWorldOverride() && !world.equals(getWorldOverride())) {
setWorldOverride(null); setWorldOverride(null);
} }

Datei anzeigen

@ -755,13 +755,7 @@ public class SelectionCommands {
} }
if (setDefaultSelector) { if (setDefaultSelector) {
RegionSelectorType found = null; RegionSelectorType found = RegionSelectorType.getForSelector(newSelector);
for (RegionSelectorType type : RegionSelectorType.values()) {
if (type.getSelectorClass() == newSelector.getClass()) {
found = type;
break;
}
}
if (found != null) { if (found != null) {
session.setDefaultRegionSelector(found); session.setDefaultRegionSelector(found);

Datei anzeigen

@ -64,6 +64,7 @@ import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.entity.EntityTypes; import com.sk89q.worldedit.world.entity.EntityTypes;
import com.sk89q.worldedit.world.registry.LegacyMapper; import com.sk89q.worldedit.world.registry.LegacyMapper;
import javax.annotation.Nonnull;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
@ -337,9 +338,10 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
return SuggestionHelper.getBlockPropertySuggestions(blockType, props); return SuggestionHelper.getBlockPropertySuggestions(blockType, props);
} }
@Nonnull
private BaseBlock parseLogic(String input, ParserContext context) throws InputParseException { private BaseBlock parseLogic(String input, ParserContext context) throws InputParseException {
//FAWE start //FAWE start
String[] blockAndExtraData = input.trim().split("\\|"); String[] blockAndExtraData = input.trim().split("(?<!^)\\|");
blockAndExtraData[0] = woolMapper(blockAndExtraData[0]); blockAndExtraData[0] = woolMapper(blockAndExtraData[0]);
Map<Property<?>, Object> blockStates = new HashMap<>(); Map<Property<?>, Object> blockStates = new HashMap<>();
//FAWE end //FAWE end

Datei anzeigen

@ -235,4 +235,11 @@ public class ForgetfulExtentBuffer extends AbstractDelegateExtent implements Pat
}; };
} }
//FAWE - stateful pattern
@Override
public Pattern fork() {
return new ForgetfulExtentBuffer(extent, mask.copy());
}
//FAWE end
} }

Datei anzeigen

@ -25,6 +25,8 @@ import com.sk89q.worldedit.extent.buffer.ExtentBuffer;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import java.util.Arrays;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
/** /**
@ -64,4 +66,12 @@ public class ExtentBufferedCompositePattern extends AbstractExtentPattern {
return lastBlock; return lastBlock;
} }
//FAWE - stateful pattern
@Override
public Pattern fork() {
final Pattern[] forkedPatterns = Arrays.stream(patterns).map(Pattern::fork).toArray(Pattern[]::new);
return new ExtentBufferedCompositePattern(getExtent(), forkedPatterns);
}
//FAWE end
} }

Datei anzeigen

@ -59,6 +59,11 @@ public interface Pattern extends Filter {
apply(block, block, block); apply(block, block, block);
} }
@Override
default Pattern fork() { // covariant return type
return this;
}
//FAWE end //FAWE end
/** /**

Datei anzeigen

@ -67,6 +67,13 @@ public class RandomPattern extends AbstractPattern {
this.collection = RandomCollection.of(weights, random); this.collection = RandomCollection.of(weights, random);
this.patterns = parent.patterns; this.patterns = parent.patterns;
} }
private RandomPattern(SimpleRandom random, Map<Pattern, Double> weights) {
this.random = random;
this.weights = weights;
this.collection = RandomCollection.of(weights, random);
this.patterns = new LinkedHashSet<>(weights.keySet());
}
//FAWE end //FAWE end
/** /**
@ -107,6 +114,14 @@ public class RandomPattern extends AbstractPattern {
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
return collection.next(get.getBlockX(), get.getBlockY(), get.getBlockZ()).apply(extent, get, set); return collection.next(get.getBlockX(), get.getBlockY(), get.getBlockZ()).apply(extent, get, set);
} }
@Override
public Pattern fork() {
final LinkedHashMap<Pattern, Double> newWeights = new LinkedHashMap<>();
this.weights.forEach((p, w) -> newWeights.put(p.fork(), w));
return new RandomPattern(this.random, newWeights);
}
//FAWE end //FAWE end
} }

Datei anzeigen

@ -29,13 +29,16 @@ import com.sk89q.worldedit.world.block.BlockType;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import static com.sk89q.worldedit.blocks.Blocks.resolveProperties; import static com.sk89q.worldedit.blocks.Blocks.resolveProperties;
public class StateApplyingPattern extends AbstractExtentPattern { public class StateApplyingPattern extends AbstractExtentPattern {
private final Map<String, String> states; private final Map<String, String> states;
private final Map<BlockType, Map<Property<Object>, Object>> cache = Maps.newHashMap(); //FAWE - avoid race conditions
private final Map<BlockType, Map<Property<Object>, Object>> cache = new ConcurrentHashMap<>();
//FAWE end
public StateApplyingPattern(Extent extent, Map<String, String> statesToSet) { public StateApplyingPattern(Extent extent, Map<String, String> statesToSet) {
super(extent); super(extent);

Datei anzeigen

@ -19,8 +19,14 @@
package com.sk89q.worldedit.regions.selector; package com.sk89q.worldedit.regions.selector;
import com.fastasyncworldedit.core.regions.selector.FuzzyRegionSelector;
import com.fastasyncworldedit.core.regions.selector.PolyhedralRegionSelector;
import com.sk89q.worldedit.regions.RegionSelector; import com.sk89q.worldedit.regions.RegionSelector;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
/** /**
* An enum of default region selector types. * An enum of default region selector types.
*/ */
@ -32,7 +38,21 @@ public enum RegionSelectorType {
SPHERE(SphereRegionSelector.class), SPHERE(SphereRegionSelector.class),
ELLIPSOID(EllipsoidRegionSelector.class), ELLIPSOID(EllipsoidRegionSelector.class),
POLYGON(Polygonal2DRegionSelector.class), POLYGON(Polygonal2DRegionSelector.class),
CONVEX_POLYHEDRON(ConvexPolyhedralRegionSelector.class); CONVEX_POLYHEDRON(ConvexPolyhedralRegionSelector.class),
//FAWE start
POLYHEDRAL(PolyhedralRegionSelector.class),
FUZZY(FuzzyRegionSelector.class);
//FAWE end
//FAWE start
private static final Map<Class<? extends RegionSelector>, RegionSelectorType> VALUE_MAP = new HashMap<>();
static {
for (RegionSelectorType type : values()) {
VALUE_MAP.put(type.getSelectorClass(), type);
}
}
//FAWE end
private final Class<? extends RegionSelector> selectorClass; private final Class<? extends RegionSelector> selectorClass;
@ -40,6 +60,19 @@ public enum RegionSelectorType {
this.selectorClass = selectorClass; this.selectorClass = selectorClass;
} }
//FAWE start
/**
* Get a {@link RegionSelectorType} for the given {@link RegionSelector}
*
* @param selector Region selector to get type enum for
* @since TODO
*/
@Nullable
public static RegionSelectorType getForSelector(RegionSelector selector) {
return VALUE_MAP.get(selector.getClass());
}
//FAWE end
/** /**
* Get the selector class. * Get the selector class.
* *

Datei anzeigen

@ -85,7 +85,7 @@ public class WorldEditExpressionEnvironment implements ExpressionEnvironment {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
public int getBlockDataRel(double x, double y, double z) { public int getBlockDataRel(double x, double y, double z) {
return extent.getBlock(toWorld(x, y, z)).getBlockType().getLegacyCombinedId() & 0xF; return extent.getBlock(toWorldRel(x, y, z).toBlockPoint()).getBlockType().getLegacyCombinedId() & 0xF;
} }
//FAWE start //FAWE start

Datei anzeigen

@ -19,12 +19,14 @@
package com.sk89q.worldedit.util.gson; package com.sk89q.worldedit.util.gson;
import com.fastasyncworldedit.core.util.gson.ItemTypeAdapter;
import com.fastasyncworldedit.core.util.gson.RegionSelectorAdapter;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
/** /**
* Utility methods for Google's GSON library. * Utility methods for Google's GSON library.
@ -43,7 +45,10 @@ public final class GsonUtil {
GsonBuilder gsonBuilder = new GsonBuilder(); GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Vector3.class, new VectorAdapter()); gsonBuilder.registerTypeAdapter(Vector3.class, new VectorAdapter());
gsonBuilder.registerTypeAdapter(BlockVector3.class, new BlockVectorAdapter()); gsonBuilder.registerTypeAdapter(BlockVector3.class, new BlockVectorAdapter());
//FAWE start
gsonBuilder.registerTypeAdapter(RegionSelector.class, new RegionSelectorAdapter());
gsonBuilder.registerTypeAdapter(ItemType.class, new ItemTypeAdapter()); gsonBuilder.registerTypeAdapter(ItemType.class, new ItemTypeAdapter());
//FAWE end
return gsonBuilder; return gsonBuilder;
} }