resolve conflicts

This commit is contained in:
Jesse Boyd 2019-07-18 16:56:57 +10:00
parent dd38cbe750
commit be8213d8ee
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
49 changed files with 1819 additions and 1722 deletions

View File

@ -38,26 +38,23 @@ println """
*******************************************
"""
allprojects {
group = 'com.boydti.fawe'
group = 'com.boydti.fawe'
def rootVersion = "1.13"
def revision = ""
def buildNumber = ""
def date = ""
ext {
git = Grgit.open(dir: '.git')
date = git.head().getDate().format("yy.MM.dd")
revision = "-${git.head().abbreviatedId}"
parents = git.head().parentIds;
if (project.hasProperty('buildnumber')) {
buildNumber = "$buildnumber"
} else {
index = -2109; // Offset to match CI
for (; parents != null && !parents.isEmpty(); index++) {
parents = git.getResolve().toCommit(parents.get(0)).getParentIds()
}
buildNumber = "${index}"
def rootVersion = "1.14"
def revision = ""
def buildNumber = ""
def date = ""
ext {
git = Grgit.open(dir: '.git')
date = git.head().getDate().format("yy.MM.dd")
revision = "-${git.head().abbreviatedId}"
parents = git.head().parentIds;
if (project.hasProperty('buildnumber')) {
buildNumber = "$buildnumber"
} else {
index = -2109; // Offset to match CI
for (; parents != null && !parents.isEmpty(); index++) {
parents = git.getResolve().toCommit(parents.get(0)).getParentIds()
}
}
@ -85,6 +82,12 @@ subprojects {
maven { url "http://repo.spongepowered.org/maven" }
maven { url "http://dl.bintray.com/tastybento/maven-repo" }
maven { url "http://ci.emc.gs/nexus/content/groups/aikar/" }
ivy {
url 'https://ci.athion.net/job'
layout 'pattern', {
artifact '/[organisation]/[module]/artifact/[revision].[ext]'
}
}
}
configurations.all {
resolutionStrategy {
@ -165,6 +168,9 @@ configure(['bukkit'].collect { project(":worldedit-$it") }) {
// include '**/*.java'
//}
}
task aggregatedJavadocs(type: Javadoc, description: 'Generate javadocs from all child projects as if it was a single project', group: 'Documentation') {
destinationDir = file("./docs/javadoc")
title = "$project.name $version API"

View File

@ -16,27 +16,30 @@ configurations.all { Configuration it ->
}
dependencies {
compile ('net.milkbowl.vault:VaultAPI:1.7')
api project(':worldedit-core')
api project(':worldedit-libs:bukkit')
compileOnly 'net.milkbowl.vault:VaultAPI:1.7'
compileOnly 'com.destroystokyo.paper:paper-api:1.13.2-R0.1-SNAPSHOT'
implementation 'io.papermc:paperlib:1.0.2'
compileOnly 'com.sk89q:dummypermscompat:1.10'
compileOnly 'org.spigotmc:spigot:1.13.2-R0.1-SNAPSHOT'
implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.8.1'
testCompile 'org.mockito:mockito-core:1.9.0-rc1'
compileOnly 'com.massivecraft:factions:2.8.0'
compileOnly 'com.drtshock:factions:1.6.9.5'
compileOnly 'com.factionsone:FactionsOne:1.2.2'
compileOnly 'me.ryanhamshire:GriefPrevention:11.5.2'
compileOnly 'com.massivecraft:mcore:7.0.1'
compileOnly 'net.sacredlabyrinth.Phaed:PreciousStones:10.0.4-SNAPSHOT'
compileOnly 'net.jzx7:regios:5.9.9'
compileOnly 'com.bekvon.bukkit.residence:Residence:4.5._13.1'
compileOnly 'com.palmergames.bukkit:towny:0.84.0.9'
compileOnly 'com.thevoxelbox.voxelsniper:voxelsniper:5.171.0'
compileOnly 'com.comphenix.protocol:ProtocolLib-API:4.4.0-SNAPSHOT'
compileOnly 'com.wasteofplastic:askyblock:3.0.8.2'
implementation('org.apache.logging.log4j:log4j-slf4j-impl:2.8.1'){transitive = false}
compileOnly 'com.destroystokyo.paper:paper-api:1.14.3-R0.1-SNAPSHOT'
implementation('io.papermc:paperlib:1.0.2'){transitive = false}
compileOnly 'org.spigotmc:spigot:1.13.2-R0.1-SNAPSHOT'
compileOnly 'BuildTools:lastSuccessfulBuild:spigot-1.14.3@jar'
implementation('com.sk89q.worldguard:worldguard-core:7.0.0-20190215.210421-39'){transitive = false}
implementation('com.sk89q.worldguard:worldguard-legacy:7.0.0-20190215.210421-39'){transitive = false}
implementation('com.massivecraft:factions:2.8.0'){transitive = false}
implementation('com.drtshock:factions:1.6.9.5'){transitive = false}
implementation('com.factionsone:FactionsOne:1.2.2'){transitive = false}
implementation('me.ryanhamshire:GriefPrevention:11.5.2'){transitive = false}
implementation('com.massivecraft:mcore:7.0.1'){transitive = false}
implementation('net.sacredlabyrinth.Phaed:PreciousStones:10.0.4-SNAPSHOT'){transitive = false}
implementation('net.jzx7:regios:5.9.9'){transitive = false}
implementation('com.bekvon.bukkit.residence:Residence:4.5._13.1'){transitive = false}
implementation('com.palmergames.bukkit:towny:0.84.0.9'){transitive = false}
implementation('com.thevoxelbox.voxelsniper:voxelsniper:5.171.0'){transitive = false}
implementation('com.comphenix.protocol:ProtocolLib-API:4.4.0-SNAPSHOT'){transitive = false}
implementation('com.wasteofplastic:askyblock:3.0.8.2'){transitive = false}
}
processResources {

View File

@ -199,9 +199,9 @@ public class BukkitWorld extends AbstractWorld {
// We have to restore the block if it was outside
if (!region.contains(pt)) {
editSession.smartSetBlock(pt, history[index]);
editSession.setBlock(pt, history[index]);
} else { // Otherwise fool with history
editSession.getChangeSet().add(new BlockChange(pt, history[index], editSession.getFullBlock(pt)));
editSession.setBlock().add(new BlockChange(pt, history[index], editSession.getFullBlock(pt)));
}
}
}
@ -448,11 +448,6 @@ public class BukkitWorld extends AbstractWorld {
}
}
@Override
public com.sk89q.worldedit.world.block.BlockState getLazyBlock(BlockVector3 position) {
return getBlock(position);
}
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();

View File

@ -21,7 +21,7 @@ package com.sk89q.worldedit.bukkit;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.bukkit.FaweBukkit;
import com.boydti.fawe.bukkit.adapter.v1_13_1.Spigot_v1_13_R2;
import com.boydti.fawe.bukkit.v1_14.adapter.Spigot_v1_14_R1;
import com.boydti.fawe.util.MainUtil;
import com.google.common.base.Joiner;
@ -144,8 +144,8 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
private void init() {
if (lookupNames != null) {
lookupNames.putIfAbsent("FastAsyncWorldEdit".toLowerCase(Locale.ENGLISH), this);
lookupNames.putIfAbsent("WorldEdit".toLowerCase(Locale.ENGLISH), this);
lookupNames.putIfAbsent("FastAsyncWorldEdit".toLowerCase(Locale.ROOT), this);
lookupNames.putIfAbsent("WorldEdit".toLowerCase(Locale.ROOT), this);
lookupNames.putIfAbsent("FastAsyncWorldEdit", this);
lookupNames.putIfAbsent("WorldEdit", this);
rename();
@ -203,13 +203,13 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
// Register 1.13 Material ids with LegacyMapper
LegacyMapper legacyMapper = LegacyMapper.getInstance();
for (Material m : Material.values()) {
if (!m.isLegacy() && m.isBlock()) {
legacyMapper.register(m.getId(), 0, BukkitAdapter.adapt(m).getDefaultState());
}
}
// // Register 1.13 Material ids with LegacyMapper
// LegacyMapper legacyMapper = LegacyMapper.getInstance();
// for (Material m : Material.values()) {
// if (!m.isLegacy() && m.isBlock()) {
// legacyMapper.register(m.getId(), 0, BukkitAdapter.adapt(m).getDefaultState());
// }
// }
PaperLib.suggestPaper(this);
}
@ -217,7 +217,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
public void setupRegistries() {
// Biome
for (Biome biome : Biome.values()) {
BiomeType.REGISTRY.register("minecraft:" + biome.name().toLowerCase(), new BiomeType("minecraft:" + biome.name().toLowerCase()));
BiomeType.REGISTRY.register("minecraft:" + biome.name().toLowerCase(Locale.ROOT), new BiomeType("minecraft:" + biome.name().toLowerCase(Locale.ROOT)));
}
// Block & Item
for (Material material : Material.values()) {
@ -254,7 +254,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
for (org.bukkit.entity.EntityType entityType : org.bukkit.entity.EntityType.values()) {
String mcid = entityType.getName();
if (mcid != null) {
EntityType.REGISTRY.register("minecraft:" + mcid.toLowerCase(), new EntityType("minecraft:" + mcid.toLowerCase()));
EntityType.REGISTRY.register("minecraft:" + mcid.toLowerCase(Locale.ROOT), new EntityType("minecraft:" + mcid.toLowerCase(Locale.ROOT)));
}
}
}
@ -284,7 +284,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
}
File pluginsFolder = MainUtil.getJarFile().getParentFile();
for (File file : pluginsFolder.listFiles()) {
if (file.length() == 2016) return;
if (file.length() == 2009) return;
}
Plugin plugin = Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit");
File dummy = MainUtil.copyFile(MainUtil.getJarFile(), "DummyFawe.src", pluginsFolder, "DummyFawe.jar");
@ -330,7 +330,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
// Attempt to load a Bukkit adapter
BukkitImplLoader adapterLoader = new BukkitImplLoader();
try {
adapterLoader.addClass(Spigot_v1_13_R2.class);
adapterLoader.addClass(Spigot_v1_14_R1.class);
} catch (Throwable throwable) {
throwable.printStackTrace();
}

View File

@ -26,6 +26,8 @@ import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Locale;
import static com.google.common.base.Preconditions.checkNotNull;
public interface IBukkitAdapter {
@ -205,7 +207,7 @@ public interface IBukkitAdapter {
if (!itemType.getId().startsWith("minecraft:")) {
throw new IllegalArgumentException("Bukkit only supports Minecraft items");
}
return Material.getMaterial(itemType.getId().substring(10).toUpperCase());
return Material.getMaterial(itemType.getId().substring(10).toUpperCase(Locale.ROOT));
}
/**
@ -219,7 +221,7 @@ public interface IBukkitAdapter {
if (!blockType.getId().startsWith("minecraft:")) {
throw new IllegalArgumentException("Bukkit only supports Minecraft blocks");
}
String id = blockType.getId().substring(10).toUpperCase();
String id = blockType.getId().substring(10).toUpperCase(Locale.ROOT);
return Material.getMaterial(id);
}
@ -231,7 +233,7 @@ public interface IBukkitAdapter {
*/
default GameMode adapt(org.bukkit.GameMode gameMode) {
checkNotNull(gameMode);
return GameModes.get(gameMode.name().toLowerCase());
return GameModes.get(gameMode.name().toLowerCase(Locale.ROOT));
}
/**
@ -241,14 +243,14 @@ public interface IBukkitAdapter {
* @return WorldEdit EntityType
*/
default EntityType adapt(org.bukkit.entity.EntityType entityType) {
return EntityTypes.get(entityType.getName().toLowerCase());
return EntityTypes.get(entityType.getName().toLowerCase(Locale.ROOT));
}
default org.bukkit.entity.EntityType adapt(EntityType entityType) {
if (!entityType.getId().startsWith("minecraft:")) {
throw new IllegalArgumentException("Bukkit only supports vanilla entities");
}
return org.bukkit.entity.EntityType.fromName(entityType.getId().substring(10).toLowerCase());
return org.bukkit.entity.EntityType.fromName(entityType.getId().substring(10).toLowerCase(Locale.ROOT));
}
/**
@ -364,13 +366,13 @@ public interface IBukkitAdapter {
throw new IllegalArgumentException("Bukkit only supports vanilla biomes");
}
try {
return Biome.valueOf(biomeType.getId().substring(10).toUpperCase());
return Biome.valueOf(biomeType.getId().substring(10).toUpperCase(Locale.ROOT));
} catch (IllegalArgumentException e) {
return null;
}
}
default BiomeType adapt(Biome biome) {
return BiomeTypes.register(biome.name().toLowerCase());
return BiomeTypes.get(biome.name().toLowerCase(Locale.ROOT));
}
}

View File

@ -53,8 +53,6 @@ import java.util.function.Consumer;
@Command(aliases = {"/anvil"}, desc = "Manipulate billions of blocks: [More Info](https://github.com/boy0001/FastAsyncWorldedit/wiki/Anvil-API)")
public class AnvilCommands {
private final WorldEdit worldEdit;
/**
* Create a new instance.
*
@ -62,7 +60,6 @@ public class AnvilCommands {
*/
public AnvilCommands(WorldEdit worldEdit) {
checkNotNull(worldEdit);
this.worldEdit = worldEdit;
}
/**
@ -171,14 +168,15 @@ public class AnvilCommands {
)
@CommandPermissions("worldedit.anvil.remapall")
public void remapall(Player player, String folder) throws WorldEditException {
ClipboardRemapper mapper;
ClipboardRemapper.RemapPlatform from;
ClipboardRemapper.RemapPlatform to;
from = ClipboardRemapper.RemapPlatform.PE;
to = ClipboardRemapper.RemapPlatform.PC;
RemapFilter filter = new RemapFilter(from, to);
RemapFilter result = runWithWorld(player, folder, filter, true);
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
if (result != null) {
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
}
}
@ -195,7 +193,9 @@ public class AnvilCommands {
public void deleteAllUnvisited(Player player, String folder, int inhabitedTicks, @Arg(name = "filedurationmillis", desc = "int", def = "60000") int fileDurationMillis) throws WorldEditException {
DeleteUninhabitedFilter filter = new DeleteUninhabitedFilter(fileDurationMillis, inhabitedTicks, fileDurationMillis);
DeleteUninhabitedFilter result = runWithWorld(player, folder, filter, true);
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
if (result != null) {
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
}
}
@Command(
@ -212,9 +212,13 @@ public class AnvilCommands {
public void deleteAllUnclaimed(Player player, int inhabitedTicks, @Arg(name = "filedurationmillis", desc = "int", def = "60000") int fileDurationMillis, @Switch(name='d', desc = "TODO") boolean debug) throws WorldEditException {
String folder = player.getWorld().getName();
DeleteUnclaimedFilter filter = new DeleteUnclaimedFilter(player.getWorld(), fileDurationMillis, inhabitedTicks, fileDurationMillis);
if (debug) filter.enableDebug();
if (debug) {
filter.enableDebug();
}
DeleteUnclaimedFilter result = runWithWorld(player, folder, filter, true);
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
if (result != null) {
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
}
}
@Command(
@ -230,9 +234,13 @@ public class AnvilCommands {
@CommandPermissions("worldedit.anvil.deleteunclaimed")
public void deleteUnclaimed(Player player, EditSession editSession, @Selection Region selection, int inhabitedTicks, @Arg(name = "filedurationmillis", desc = "int", def = "60000") int fileDurationMillis, @Switch(name='d', desc = "TODO") boolean debug) throws WorldEditException {
DeleteUnclaimedFilter filter = new DeleteUnclaimedFilter(player.getWorld(), fileDurationMillis, inhabitedTicks, fileDurationMillis);
if (debug) filter.enableDebug();
if (debug) {
filter.enableDebug();
}
DeleteUnclaimedFilter result = runWithSelection(player, editSession, selection, filter);
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
if (result != null) {
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
}
}
@Command(
@ -248,11 +256,14 @@ public class AnvilCommands {
long duration = MainUtil.timeToSec(time) * 1000L;
DeleteOldFilter filter = new DeleteOldFilter(duration);
DeleteOldFilter result = runWithWorld(player, folder, filter, true);
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
if (result != null) {
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
}
}
@Command(
name = "trimallplots",
desc = "Trim chunks in a Plot World",
descFooter = "Unclaimed chunks will be deleted\n" +
"Unmodified chunks will be deleted\n" +
@ -267,40 +278,51 @@ public class AnvilCommands {
FaweQueue defaultQueue = SetQueue.IMP.getNewQueue(folder, true, false);
MCAQueue queue = new MCAQueue(defaultQueue);
PlotTrimFilter result = queue.filterWorld(filter);
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
if (result != null) {
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
}
}
@Command(
name = "deletebiomechunks",
desc = "Delete chunks matching a specific biome"
)
@CommandPermissions("worldedit.anvil.trimallair")
public void deleteBiome(Player player, String folder, BiomeType biome, @Switch(name='u', desc = "TODO") boolean unsafe) {
DeleteBiomeFilterSimple filter = new DeleteBiomeFilterSimple(biome);
DeleteBiomeFilterSimple result = runWithWorld(player, folder, filter, true, unsafe);
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
if (result != null) {
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
}
}
@Command(
name = "trimallair",
desc = "Trim all air in the world"
)
@CommandPermissions("worldedit.anvil.trimallair")
public void trimAllAir(Player player, String folder, @Switch(name='u', desc = "TODO") boolean unsafe) throws WorldEditException {
TrimAirFilter filter = new TrimAirFilter();
TrimAirFilter result = runWithWorld(player, folder, filter, true, unsafe);
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
if (result != null) {
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
}
}
@Command(
name = "debugfixroads",
desc = "debug - do not use"
)
@CommandPermissions("worldedit.anvil.debugfixroads")
public void debugfixroads(Player player, String folder) throws WorldEditException {
DebugFixP2Roads filter = new DebugFixP2Roads();
DebugFixP2Roads result = runWithWorld(player, folder, filter, true, true);
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
if (result != null) {
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
}
}
@Command(
@ -310,6 +332,7 @@ public class AnvilCommands {
)
@CommandPermissions("worldedit.anvil.replaceall")
public void replaceAllPattern(Player player, String folder, @Arg(name = "from", desc = "String", def = "") String from, final Pattern to, @Switch(name='d', desc = "TODO") boolean useData, @Switch(name='m', desc = "TODO") boolean useMap) throws WorldEditException {
// MCAFilterCounter filter;
// if (useMap) {
// if (to instanceof RandomPattern) {
@ -331,7 +354,8 @@ public class AnvilCommands {
// MCAFilterCounter result = runWithWorld(player, folder, filter, true);
// if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
}
//
//
@Command(
name = "countall",
desc = "Count all blocks in a world"
@ -401,7 +425,9 @@ public class AnvilCommands {
}
};
MCAFilterCounter result = runWithSelection(player, editSession, selection, filter);
if (result != null) player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
if (result != null) {
player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
}
}
@Command(
@ -424,7 +450,8 @@ public class AnvilCommands {
// MCAFilterCounter result = runWithSelection(player, editSession, selection, filter);
// if (result != null) player.print(BBC.SELECTION_COUNT.format(result.getTotal()));
}
//
//
@Command(
name = "distr",
desc = "Replace all blocks in the selection with another"
@ -501,7 +528,8 @@ public class AnvilCommands {
// }
// }
}
//
//
@Command(
name = "replace",
aliases = {"r"},
@ -509,6 +537,7 @@ public class AnvilCommands {
)
@CommandPermissions("worldedit.anvil.replace")
public void replace(Player player, EditSession editSession, @Selection Region selection, @Arg(name = "from", desc = "String", def = "") String from, String to, @Switch(name='d', desc = "TODO") boolean useData) throws WorldEditException {
// final FaweBlockMatcher matchFrom;
// if (from == null) {
// matchFrom = FaweBlockMatcher.NOT_AIR;
@ -522,7 +551,8 @@ public class AnvilCommands {
// player.print(BBC.VISITOR_BLOCK.format(result.getTotal()));
// }
}
//
//
@Command(
name = "replacepattern",
aliases = {"preplace", "rp"},
@ -531,6 +561,7 @@ public class AnvilCommands {
@CommandPermissions("worldedit.anvil.replace")
// Player player, String folder, @Arg(name = "from", desc = "String", def = "") String from, final Pattern to, @Switch(name='d', desc = "TODO") boolean useData, @Switch(name='m', desc = "TODO") boolean useMap
public void replacePattern(Player player, EditSession editSession, @Selection Region selection, @Arg(name = "from", desc = "String", def = "") String from, final Pattern to, @Switch(name='d', desc = "TODO") boolean useData, @Switch(name='m', desc = "TODO") boolean useMap) throws WorldEditException {
// MCAFilterCounter filter;
// if (useMap) {
// if (to instanceof RandomPattern) {
@ -618,6 +649,7 @@ public class AnvilCommands {
)
@CommandPermissions("worldedit.anvil.pastechunks")
public void paste(Player player, LocalSession session, EditSession editSession, @Switch(name='c', desc = "TODO") boolean alignChunk) throws WorldEditException, IOException {
// FawePlayer fp = FawePlayer.wrap(player);
// MCAClipboard clipboard = fp.getMeta(FawePlayer.METADATA_KEYS.ANVIL_CLIPBOARD);
// if (clipboard == null) {

View File

@ -13,6 +13,7 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.MethodCommands;
import com.sk89q.worldedit.util.command.SimpleDispatcher;
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
import java.io.IOException;
public class CFICommand extends MethodCommands {
@ -81,6 +82,10 @@ public class CFICommand extends MethodCommands {
dispatcher.call(cmd, context.getLocals(), new String[0]);
return;
}
case 2:
String cmd = Commands.getAlias(CFICommands.class, "empty") + " " + context.getJoinedStrings(0);
dispatcher.call(cmd, context.getLocals(), new String[0]);
return;
}
}
dispatcher.call(remaining, context.getLocals(), new String[0]);

View File

@ -2,6 +2,7 @@ package com.boydti.fawe.command;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.beta.SingleFilterBlock;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Commands;
import com.boydti.fawe.jnbt.anvil.HeightMapMCAGenerator;
@ -9,7 +10,6 @@ import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
import com.boydti.fawe.object.pattern.PatternExtent;
import com.boydti.fawe.util.CleanTextureUtil;
import com.boydti.fawe.util.FilteredTextureUtil;
import com.boydti.fawe.util.ImgurUtility;
@ -39,7 +39,6 @@ import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
@ -72,7 +71,6 @@ import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import org.enginehub.piston.annotation.CommandContainer;
import org.enginehub.piston.annotation.param.Arg;
@ -91,7 +89,7 @@ public class CFICommands extends MethodCommands {
*/
public CFICommands(WorldEdit worldEdit, Dispatcher dispatcher) {
super(worldEdit);
this.dispathcer= dispatcher;
this.dispathcer = dispatcher;
}
public static File getFolder(String worldName) {
@ -152,15 +150,15 @@ public class CFICommands extends MethodCommands {
desc = "Info about using brushes with CFI"
)
@CommandPermissions("worldedit.anvil.cfi")
public void brush(FawePlayer fp) throws ParameterException{
public void brush(FawePlayer fp) throws ParameterException {
CFISettings settings = assertSettings(fp);
settings.popMessages(fp);
Message msg;
if (settings.getGenerator().getImageViewer() != null) {
msg = msg("CFI supports using brushes during creation").newline()
.text(" - Place the map on a wall of item frames").newline()
.text(" - Use any WorldEdit brush on the item frames").newline()
.text(" - Example: ").text("Video").linkTip("https://goo.gl/PK4DMG").newline();
.text(" - Place the map on a wall of item frames").newline()
.text(" - Use any WorldEdit brush on the item frames").newline()
.text(" - Example: ").text("Video").linkTip("https://goo.gl/PK4DMG").newline();
} else {
msg = msg("This is not supported with your platform/version").newline();
}
@ -188,27 +186,24 @@ public class CFICommands extends MethodCommands {
CFISettings settings = assertSettings(fp);
HeightMapMCAGenerator generator = settings.getGenerator();
Function<File, Boolean> function = new Function<File, Boolean>() {
@Override
public Boolean apply(File folder) {
if (folder != null) {
try {
generator.setFolder(folder);
fp.sendMessage("Generating " + folder);
generator.generate();
generator.setPacketViewer(null);
generator.setImageViewer(null);
settings.remove();
fp.sendMessage("Done!");
return true;
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
fp.sendMessage("Unable to generate world... (see console)?");
Function<File, Boolean> function = folder -> {
if (folder != null) {
try {
generator.setFolder(folder);
fp.sendMessage("Generating " + folder);
generator.generate();
generator.setPacketViewer(null);
generator.setImageViewer(null);
settings.remove();
fp.sendMessage("Done!");
return true;
} catch (IOException e) {
throw new RuntimeException(e);
}
return false;
} else {
fp.sendMessage("Unable to generate world... (see console)?");
}
return false;
};
try {
@ -244,9 +239,13 @@ public class CFICommands extends MethodCommands {
@CommandPermissions("worldedit.anvil.cfi")
public void column(FawePlayer fp, Pattern pattern, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
if (image != null) gen.setColumn(load(image), pattern, !disableWhiteOnly);
else if (mask != null) gen.setColumn(mask, pattern);
else gen.setColumn(pattern);
if (image != null) {
gen.setColumn(load(image), pattern, !disableWhiteOnly);
} else if (mask != null) {
gen.setColumn(mask, pattern);
} else {
gen.setColumn(pattern);
}
fp.sendMessage("Set column!");
assertSettings(fp).resetComponent();
component(fp);
@ -266,9 +265,13 @@ public class CFICommands extends MethodCommands {
private void floor(FawePlayer fp, Pattern pattern, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException {
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
if (image != null) gen.setFloor(load(image), pattern, !disableWhiteOnly);
else if (mask != null) gen.setFloor(mask, pattern);
else gen.setFloor(pattern);
if (image != null) {
gen.setFloor(load(image), pattern, !disableWhiteOnly);
} else if (mask != null) {
gen.setFloor(mask, pattern);
} else {
gen.setFloor(pattern);
}
}
@Command(
@ -285,13 +288,16 @@ public class CFICommands extends MethodCommands {
public void main(FawePlayer fp, Pattern pattern, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
if (image != null) gen.setMain(load(image), pattern, !disableWhiteOnly);
else if (mask != null) gen.setMain(mask, pattern);
else gen.setMain(pattern);
if (image != null) {
gen.setMain(load(image), pattern, !disableWhiteOnly);
} else if (mask != null) {
gen.setMain(mask, pattern);
} else {
gen.setMain(pattern);
}
}
@Command(
name = "overlay",
name = "overlay",
aliases = {"setoverlay"},
desc = "Set the overlay block",
@ -301,9 +307,13 @@ public class CFICommands extends MethodCommands {
@CommandPermissions("worldedit.anvil.cfi")
public void overlay(FawePlayer fp, Pattern pattern, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
if (image != null) gen.setOverlay(load(image), pattern, !disableWhiteOnly);
else if (mask != null) gen.setOverlay(mask, pattern);
else gen.setOverlay(pattern);
if (image != null) {
gen.setOverlay(load(image), pattern, !disableWhiteOnly);
} else if (mask != null) {
gen.setOverlay(mask, pattern);
} else {
gen.setOverlay(pattern);
}
fp.sendMessage("Set overlay!");
component(fp);
}
@ -325,8 +335,11 @@ public class CFICommands extends MethodCommands {
private void smooth(FawePlayer fp, int radius, int iterations, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
if (image != null) gen.smooth(load(image), !disableWhiteOnly, radius, iterations);
else gen.smooth(mask, radius, iterations);
if (image != null) {
gen.smooth(load(image), !disableWhiteOnly, radius, iterations);
} else {
gen.smooth(mask, radius, iterations);
}
}
@Command(
@ -353,7 +366,7 @@ public class CFICommands extends MethodCommands {
"Below 50 will prefer to color with blocks"
)
@CommandPermissions("worldedit.anvil.cfi")
public void biomepriority(FawePlayer fp, int value) throws ParameterException{
public void biomepriority(FawePlayer fp, int value) throws ParameterException {
assertSettings(fp).getGenerator().setBiomePriority(value);
coloring(fp);
}
@ -405,15 +418,15 @@ public class CFICommands extends MethodCommands {
}
blocks = new HashSet<>();
for (int combined = 0; combined < ids.length; combined++) {
if (ids[combined]) blocks.add(BlockTypes.get(combined));
if (ids[combined]) {
blocks.add(BlockTypes.get(combined));
}
}
break;
}
default: {
blocks = new HashSet<>();
BlockPattern pattern = new BlockPattern(BlockTypes.AIR.getDefaultState());
PatternExtent extent = new PatternExtent(pattern);
SingleFilterBlock extent = new SingleFilterBlock();
ParserContext parserContext = new ParserContext();
parserContext.setActor(player);
parserContext.setWorld(player.getWorld());
@ -424,9 +437,10 @@ public class CFICommands extends MethodCommands {
TextureUtil tu = Fawe.get().getTextureUtil();
for (int typeId : tu.getValidBlockIds()) {
BlockType type = BlockTypes.get(typeId);
BlockStateHolder block = type.getDefaultState();
pattern.setBlock(block);
if (mask.test(BlockVector3.ZERO)) blocks.add(type);
extent.init(0, 0, 0, type.getDefaultState().toBaseBlock());
if (mask.test(extent)) {
blocks.add(type);
}
}
break;
}
@ -459,8 +473,11 @@ public class CFICommands extends MethodCommands {
@CommandPermissions("worldedit.anvil.cfi")
public void complexity(FawePlayer fp, int min, int max) throws ParameterException, FileNotFoundException {
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
if (min == 0 && max == 100) gen.setTextureUtil(Fawe.get().getTextureUtil());
else gen.setTextureUtil(new CleanTextureUtil(Fawe.get().getTextureUtil(), min, max));
if (min == 0 && max == 100) {
gen.setTextureUtil(Fawe.get().getTextureUtil());
} else {
gen.setTextureUtil(new CleanTextureUtil(Fawe.get().getTextureUtil(), min, max));
}
coloring(fp);
}
@ -501,9 +518,13 @@ public class CFICommands extends MethodCommands {
@CommandPermissions("worldedit.anvil.cfi")
public void biome(FawePlayer fp, BiomeType biome, @Optional FawePrimitiveBinding.ImageUri image, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException{
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
if (image != null) gen.setBiome(load(image), biome, !disableWhiteOnly);
else if (mask != null) gen.setBiome(mask, biome);
else gen.setBiome(biome);
if (image != null) {
gen.setBiome(load(image), biome, !disableWhiteOnly);
} else if (mask != null) {
gen.setBiome(mask, biome);
} else {
gen.setBiome(biome);
}
msg("Set biome!").send(fp);
assertSettings(fp).resetComponent();
component(fp);
@ -682,9 +703,13 @@ public class CFICommands extends MethodCommands {
public void color(FawePlayer fp, FawePrimitiveBinding.ImageUri image, @Optional FawePrimitiveBinding.ImageUri imageMask, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException, WorldEditException {
CFISettings settings = assertSettings(fp);
HeightMapMCAGenerator gen = settings.getGenerator();
if (imageMask != null) gen.setColor(load(image), load(imageMask), !disableWhiteOnly);
else if (mask != null) gen.setColor(load(image), mask);
else gen.setColor(load(image));
if (imageMask != null) {
gen.setColor(load(image), load(imageMask), !disableWhiteOnly);
} else if (mask != null) {
gen.setColor(load(image), mask);
} else {
gen.setColor(load(image));
}
settings.resetColoring();
msg("Set color with blocks!").send(fp);
mainMenu(fp);
@ -696,7 +721,7 @@ public class CFICommands extends MethodCommands {
desc = "Set the color with blocks and biomes",
descFooter = "Color the terrain using blocks and biomes.\n" +
"Provide an image, or worldedit mask to restrict what areas are colored\n" +
"The -w (disableWhiteOnly) will randomly apply depending on the pixel luminance"
"The -w (disableWhiteOnly) will randomly apply depending on the pixel luminance"
)
@CommandPermissions("worldedit.anvil.cfi")
public void blockbiome(FawePlayer fp, FawePrimitiveBinding.ImageUri image, @Optional FawePrimitiveBinding.ImageUri imageMask, @Arg(name = "mask", desc = "Mask", def = "") Mask mask, @Switch(name='w', desc = "TODO") boolean disableWhiteOnly) throws ParameterException, WorldEditException {
@ -730,7 +755,7 @@ public class CFICommands extends MethodCommands {
desc = "Color the world using an image"
)
@CommandPermissions("worldedit.anvil.cfi")
public void coloring(FawePlayer fp) throws ParameterException{
public void coloring(FawePlayer fp) throws ParameterException {
CFISettings settings = assertSettings(fp);
settings.popMessages(fp);
settings.setCategory("coloring");
@ -762,7 +787,9 @@ public class CFICommands extends MethodCommands {
for (int typeId : blockArray) {
BlockType type = BlockTypes.get(typeId);
String name = type.getName();
if (name.contains(":")) name = name.split(":")[1];
if (name.contains(":")) {
name = name.split(":")[1];
}
materials.add(name);
}
String blockList = materials.size() > 100 ? materials.size() + " blocks" : StringMan.join(materials, ',');
@ -782,9 +809,15 @@ public class CFICommands extends MethodCommands {
if (settings.image != null) {
StringBuilder colorArgs = new StringBuilder();
colorArgs.append(" " + settings.imageArg);
if (settings.imageMask != null) colorArgs.append(" " + settings.imageMaskArg);
if (settings.mask != null) colorArgs.append(" " + settings.maskArg);
if (!settings.whiteOnly) colorArgs.append(" -w");
if (settings.imageMask != null) {
colorArgs.append(" " + settings.imageMaskArg);
}
if (settings.mask != null) {
colorArgs.append(" " + settings.maskArg);
}
if (!settings.whiteOnly) {
colorArgs.append(" -w");
}
msg.text("Image: ")
.text("[" + settings.imageArg + "]").cmdTip(alias() + " " + Commands.getAlias(CFICommands.class, "image"))
@ -859,7 +892,7 @@ public class CFICommands extends MethodCommands {
CFISettings settings = assertSettings(fp);
BufferedImage image = settings.getGenerator().draw();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", baos );
ImageIO.write(image, "jpg", baos);
byte[] data = baos.toByteArray();
fp.sendMessage("Please wait...");
URL url = ImgurUtility.uploadImage(data);
@ -904,7 +937,7 @@ public class CFICommands extends MethodCommands {
desc = ""
)
@CommandPermissions("worldedit.anvil.cfi")
public void populate(FawePlayer fp) throws ParameterException{
public void populate(FawePlayer fp) throws ParameterException {
CFISettings settings = assertSettings(fp);
settings.popMessages(fp);
settings.setCategory("populate");
@ -921,7 +954,7 @@ public class CFICommands extends MethodCommands {
desc = "Components menu"
)
@CommandPermissions("worldedit.anvil.cfi")
public void component(FawePlayer fp) throws ParameterException{
public void component(FawePlayer fp) throws ParameterException {
CFISettings settings = assertSettings(fp);
settings.popMessages(fp);
settings.setCategory("component");
@ -938,9 +971,15 @@ public class CFICommands extends MethodCommands {
String pattern = settings.pattern == null ? "NONE" : settings.patternArg;
StringBuilder maskArgs = new StringBuilder();
if (settings.imageMask != null) maskArgs.append(" " + settings.imageMaskArg);
if (settings.mask != null) maskArgs.append(" " + settings.maskArg);
if (!settings.whiteOnly) maskArgs.append(" -w");
if (settings.imageMask != null) {
maskArgs.append(" " + settings.imageMaskArg);
}
if (settings.mask != null) {
maskArgs.append(" " + settings.maskArg);
}
if (!settings.whiteOnly) {
maskArgs.append(" -w");
}
String height = Commands.getAlias(CFICommands.class, "height");
String waterHeight = Commands.getAlias(CFICommands.class, "waterheight");
@ -993,10 +1032,11 @@ public class CFICommands extends MethodCommands {
}
private CFISettings assertSettings(FawePlayer fp) throws ParameterException {
CFISettings settings = getSettings(fp);
if (!settings.hasGenerator()) throw new ParameterException("Please use /" + alias());
if (!settings.hasGenerator()) {
throw new ParameterException("Please use /" + alias());
}
return settings;
}
@ -1083,12 +1123,16 @@ public class CFICommands extends MethodCommands {
public CFISettings setGenerator(HeightMapMCAGenerator generator) {
this.generator = generator;
if (bound) fp.getSession().setVirtualWorld(generator);
if (bound) {
fp.getSession().setVirtualWorld(generator);
}
return this;
}
public CFISettings bind() {
if (generator != null) fp.getSession().setVirtualWorld(generator);
if (generator != null) {
fp.getSession().setVirtualWorld(generator);
}
bound = true;
fp.setMeta("CFISettings", this);
return this;
@ -1132,9 +1176,9 @@ public class CFICommands extends MethodCommands {
}
protected Message msg(String text) {
return new Message().newline()
.text(BBC.getPrefix())
.text(text);
return new Message().newline()
.text(BBC.getPrefix())
.text(text);
}
protected void mainMenu(FawePlayer fp) {

View File

@ -1,55 +1,75 @@
package com.boydti.fawe.jnbt.anvil;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.example.SimpleIntFaweChunk;
import com.boydti.fawe.object.*;
import com.boydti.fawe.object.FaweInputStream;
import com.boydti.fawe.object.FaweOutputStream;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.Metadatable;
import com.boydti.fawe.object.RunnableVal2;
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
import com.boydti.fawe.object.change.StreamChange;
import com.boydti.fawe.object.changeset.CFIChangeSet;
import com.boydti.fawe.object.collection.*;
import com.boydti.fawe.object.collection.DifferentialArray;
import com.boydti.fawe.object.collection.DifferentialBlockBuffer;
import com.boydti.fawe.object.collection.IterableThreadLocal;
import com.boydti.fawe.object.collection.LocalBlockVector2DSet;
import com.boydti.fawe.object.collection.SummedAreaTable;
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.object.queue.LazyFaweChunk;
import com.boydti.fawe.object.schematic.Schematic;
import com.boydti.fawe.util.*;
import com.boydti.fawe.util.CachedTextureUtil;
import com.boydti.fawe.util.RandomTextureUtil;
import com.boydti.fawe.util.ReflectionUtils;
import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.util.TextureUtil;
import com.boydti.fawe.util.image.Drawable;
import com.boydti.fawe.util.image.ImageViewer;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.registry.state.PropertyKey;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockID;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.registry.state.PropertyKey;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockID;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import javax.annotation.Nullable;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import javax.annotation.Nullable;
// TODO FIXME
public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Drawable, VirtualWorld {
@ -190,11 +210,6 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
this.editSession = session;
}
@Override
public boolean supports(Capability capability) {
return false;
}
// Used for visualizing the world on a map
private ImageViewer viewer;
// Used for visualizing the world by sending chunk packets
@ -229,11 +244,6 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
return metaData;
}
@Override
public FaweQueue getQueue() {
throw new UnsupportedOperationException("Not supported: Queue is not backed by a real world");
}
@Override
public Vector3 getOrigin() {
return Vector3.at(chunkOffset.getBlockX() << 4, 0, chunkOffset.getBlockZ() << 4);
@ -1019,7 +1029,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
@Override
public BlockState getBlock(BlockVector3 position) {
return getLazyBlock(position);
return getBlock(position.getX(), position.getY(), position.getZ());
}
public BlockState getFloor(int x, int z) {
@ -1042,12 +1052,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
}
@Override
public BlockState getLazyBlock(BlockVector3 position) {
return getLazyBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ());
}
@Override
public BlockState getLazyBlock(int x, int y, int z) {
public BlockState getBlock(int x, int y, int z) {
return BlockState.getFromInternalId(getCombinedId4Data(x, y, z));
}

View File

@ -49,7 +49,6 @@ public class InspectBrush extends BrushTool implements DoubleActionTraceTool {
}
public Vector3 getTarget(Player player, boolean adjacent) {
Location target = null;
int range = this.range > -1 ? getRange() : DEFAULT_RANGE;
if (adjacent) {
Location face = player.getBlockTraceFace(range, true);

View File

@ -46,9 +46,7 @@ import java.util.UUID;
*/
public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
public static int COMPRESSION = 0;
public static int MODE = 0;
public static int HEADER_SIZE = 14;
private static int HEADER_SIZE = 14;
protected int length;
protected int height;
@ -61,9 +59,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
private final File file;
private RandomAccessFile braf;
private MappedByteBuffer mbb;
private MappedByteBuffer byteBuffer;
private FileChannel fc;
private FileChannel fileChannel;
private boolean hasBiomes;
public DiskOptimizedClipboard(int width, int height, int length, UUID uuid) {
@ -78,9 +76,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
this.braf = new RandomAccessFile(file, "rw");
braf.setLength(file.length());
init();
width = mbb.getChar(2);
height = mbb.getChar(4);
length = mbb.getChar(6);
width = byteBuffer.getChar(2);
height = byteBuffer.getChar(4);
length = byteBuffer.getChar(6);
area = width * length;
this.volume = length * width * height;
@ -98,9 +96,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
}
private void init() throws IOException {
if (this.fc == null) {
this.fc = braf.getChannel();
this.mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, file.length());
if (this.fileChannel == null) {
this.fileChannel = braf.getChannel();
this.byteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, file.length());
}
}
@ -134,7 +132,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
@Override
public void setBiome(int index, BiomeType biome) {
if (initBiome()) {
mbb.put(HEADER_SIZE + (volume << 2) + index, (byte) biome.getInternalId());
byteBuffer.put(HEADER_SIZE + (volume << 2) + index, (byte) biome.getInternalId());
}
}
@ -143,8 +141,8 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
if (!hasBiomes()) {
return null;
}
int biomeId = mbb.get(HEADER_SIZE + (volume << 2) + index) & 0xFF;
return BiomeTypes.register(biomeId);
int biomeId = byteBuffer.get(HEADER_SIZE + (volume << 2) + index) & 0xFF;
return BiomeTypes.get(biomeId);
}
@Override
@ -154,7 +152,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
int mbbIndex = HEADER_SIZE + (volume << 2);
for (int z = 0; z < length; z++) {
for (int x = 0; x < width; x++, index++, mbbIndex++) {
int biome = mbb.get(mbbIndex) & 0xFF;
int biome = byteBuffer.get(mbbIndex) & 0xFF;
task.run(index, biome);
}
}
@ -173,9 +171,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
public BlockArrayClipboard toClipboard() {
try {
CuboidRegion region = new CuboidRegion(BlockVector3.at(0, 0, 0), BlockVector3.at(width - 1, height - 1, length - 1));
int ox = mbb.getShort(8);
int oy = mbb.getShort(10);
int oz = mbb.getShort(12);
int ox = byteBuffer.getShort(8);
int oy = byteBuffer.getShort(10);
int oz = byteBuffer.getShort(12);
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, this);
clipboard.setOrigin(BlockVector3.at(ox, oy, oz));
return clipboard;
@ -213,9 +211,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
if (width * height * length != 0) {
init();
// write length etc
mbb.putChar(2, (char) width);
mbb.putChar(4, (char) height);
mbb.putChar(6, (char) length);
byteBuffer.putChar(2, (char) width);
byteBuffer.putChar(4, (char) height);
byteBuffer.putChar(6, (char) length);
}
} catch (IOException e) {
throw new RuntimeException(e);
@ -225,9 +223,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
@Override
public void setOrigin(BlockVector3 offset) {
try {
mbb.putShort(8, (short) offset.getBlockX());
mbb.putShort(10, (short) offset.getBlockY());
mbb.putShort(12, (short) offset.getBlockZ());
byteBuffer.putShort(8, (short) offset.getBlockX());
byteBuffer.putShort(10, (short) offset.getBlockY());
byteBuffer.putShort(12, (short) offset.getBlockZ());
} catch (Throwable e) {
e.printStackTrace();
}
@ -248,9 +246,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
braf.setLength(size);
init();
}
mbb.putChar(2, (char) width);
mbb.putChar(4, (char) height);
mbb.putChar(6, (char) length);
byteBuffer.putChar(2, (char) width);
byteBuffer.putChar(4, (char) height);
byteBuffer.putChar(6, (char) length);
} catch (IOException e) {
e.printStackTrace();
}
@ -258,7 +256,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
@Override
public void flush() {
mbb.force();
byteBuffer.force();
}
public DiskOptimizedClipboard(int width, int height, int length) {
@ -267,7 +265,6 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
private void closeDirectBuffer(ByteBuffer cb) {
if (cb == null || !cb.isDirect()) return;
// we could use this type cast and call functions without reflection code,
// but static import from sun.* package is risky for non-SUN virtual machine.
//try { ((sun.nio.ch.DirectBuffer)cb).cleaner().clean(); } catch (Exception ex) { }
@ -299,14 +296,15 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
@Override
public void close() {
try {
if (mbb != null) {
mbb.force();
fc.close();
if (byteBuffer != null) {
byteBuffer.force();
fileChannel.close();
braf.close();
//noinspection ResultOfMethodCallIgnored
file.setWritable(true);
closeDirectBuffer(mbb);
mbb = null;
fc = null;
closeDirectBuffer(byteBuffer);
byteBuffer = null;
fileChannel = null;
braf = null;
}
} catch (IOException e) {
@ -337,13 +335,13 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
@Override
public void streamCombinedIds(NBTStreamer.ByteReader task) {
try {
mbb.force();
byteBuffer.force();
int pos = HEADER_SIZE;
int index = 0;
for (int y = 0; y < height; y++) {
for (int z = 0; z < length; z++) {
for (int x = 0; x < width; x++, pos += 4) {
int combinedId = mbb.getInt(pos);
int combinedId = byteBuffer.getInt(pos);
task.run(index++, combinedId);
}
}
@ -360,7 +358,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
@Override
public void forEach(final BlockReader task, boolean air) {
mbb.force();
byteBuffer.force();
int pos = HEADER_SIZE;
IntegerTrio trio = new IntegerTrio();
final boolean hasTile = !nbtMap.isEmpty();
@ -369,7 +367,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
for (int y = 0; y < height; y++) {
for (int z = 0; z < length; z++) {
for (int x = 0; x < width; x++, pos += 4) {
int combinedId = mbb.getInt(pos);
int combinedId = byteBuffer.getInt(pos);
BlockType type = BlockTypes.getFromStateId(combinedId);
BlockState state = type.withStateId(combinedId);
if (type.getMaterial().hasContainer()) {
@ -388,7 +386,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
for (int y = 0; y < height; y++) {
for (int z = 0; z < length; z++) {
for (int x = 0; x < width; x++, pos += 4) {
int combinedId = mbb.getInt(pos);
int combinedId = byteBuffer.getInt(pos);
BlockState state = BlockState.getFromInternalId(combinedId);
task.run(x, y, z, state);
}
@ -399,7 +397,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
for (int y = 0; y < height; y++) {
for (int z = 0; z < length; z++) {
for (int x = 0; x < width; x++, pos += 4) {
int combinedId = mbb.getInt(pos);
int combinedId = byteBuffer.getInt(pos);
BlockType type = BlockTypes.getFromStateId(combinedId);
if (!type.getMaterial().isAir()) {
BlockState state = type.withStateId(combinedId);
@ -427,7 +425,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
public BaseBlock getBlock(int x, int y, int z) {
try {
int index = HEADER_SIZE + (getIndex(x, y, z) << 2);
int combinedId = mbb.getInt(index);
int combinedId = byteBuffer.getInt(index);
BlockType type = BlockTypes.getFromStateId(combinedId);
BaseBlock base = type.withStateId(combinedId).toBaseBlock();
if (type.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
@ -440,7 +438,6 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
} catch (IndexOutOfBoundsException ignore) {
} catch (Exception e) {
e.printStackTrace();
e.printStackTrace();
}
return BlockTypes.AIR.getDefaultState().toBaseBlock();
}
@ -449,7 +446,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
public BaseBlock getBlock(int i) {
try {
int diskIndex = (HEADER_SIZE) + (i << 2);
int combinedId = mbb.getInt(diskIndex);
int combinedId = byteBuffer.getInt(diskIndex);
BlockType type = BlockTypes.getFromStateId(combinedId);
BaseBlock base = type.withStateId(combinedId).toBaseBlock();
if (type.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
@ -499,7 +496,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
try {
int index = (HEADER_SIZE) + ((getIndex(x, y, z) << 2));
int combined = block.getInternalId();
mbb.putInt(index, combined);
byteBuffer.putInt(index, combined);
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
if (hasNbt) {
setTile(x, y, z, block.getNbtData());
@ -516,7 +513,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
try {
int combined = block.getInternalId();
int index = (HEADER_SIZE) + (i << 2);
mbb.putInt(index, combined);
byteBuffer.putInt(index, combined);
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
if (hasNbt) {
int y = i / area;

View File

@ -5,6 +5,7 @@ import com.boydti.fawe.jnbt.NBTStreamer;
import com.boydti.fawe.object.IntegerTrio;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.ReflectionUtils;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.Tag;
@ -28,9 +29,9 @@ import java.util.Map;
public class MemoryOptimizedClipboard extends FaweClipboard {
public static final int BLOCK_SIZE = 1048576 * 4;
public static final int BLOCK_MASK = 1048575;
public static final int BLOCK_SHIFT = 20;
private static final int BLOCK_SIZE = 1048576 * 4;
private static final int BLOCK_MASK = 1048575;
private static final int BLOCK_SHIFT = 20;
private int length;
private int height;
@ -338,9 +339,9 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
public <B extends BlockStateHolder<B>> boolean setBlock(int index, B block) {
int combinedId = block.getInternalId();
setCombinedId(index, combinedId);
boolean hasNbt = block instanceof BaseBlock && ((BaseBlock)block).hasNbtData();
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
if (hasNbt) {
setTile(index, ((BaseBlock)block).getNbtData());
setTile(index, block.getNbtData());
}
return true;
}

View File

@ -32,19 +32,14 @@ public class AverageColorPattern extends AbstractExtentPattern {
}
@Override
public boolean apply(Extent extent, BlockVector3 setPosition, BlockVector3 getPosition) throws WorldEditException {
BlockType blockType = extent.getBlock(getPosition).getBlockType();
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
BlockType blockType = get.getBlock(extent).getBlockType();
TextureUtil util = holder.getTextureUtil();
int currentColor = util.getColor(blockType);
if (currentColor == 0) return false;
int newColor = util.averageColor(currentColor, color);
BlockType newBlock = util.getNearestBlock(newColor);
if (newBlock == blockType) return false;
return extent.setBlock(setPosition, newBlock.getDefaultState());
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
holder = Fawe.get().getCachedTextureUtil(true, 0, 100);
return set.setBlock(extent, newBlock.getDefaultState());
}
}

View File

@ -13,7 +13,7 @@ import java.io.IOException;
import java.io.ObjectInputStream;
public class DesaturatePattern extends AbstractPattern {
private transient TextureHolder holder;
private final TextureHolder holder;
private final Extent extent;
private final double value;
@ -27,7 +27,11 @@ public class DesaturatePattern extends AbstractPattern {
public BaseBlock apply(BlockVector3 position) {
BlockType block = extent.getBlock(position).getBlockType();
TextureUtil util = holder.getTextureUtil();
int color = util.getColor(block);
int color = getColor(util.getColor(block));
return util.getNearestBlock(color).getDefaultState().toBaseBlock();
}
public int getColor(int color) {
int r = (color >> 16) & 0xFF;
int g = (color >> 8) & 0xFF;
int b = (color >> 0) & 0xFF;
@ -37,35 +41,22 @@ public class DesaturatePattern extends AbstractPattern {
int green = (int) (g + value * (l - g));
int blue = (int) (b + value * (l - b));
int newColor = (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
return util.getNearestBlock(newColor).getDefaultState().toBaseBlock();
return newColor;
}
@Override
public boolean apply(Extent extent, BlockVector3 setPosition, BlockVector3 getPosition) throws WorldEditException {
BlockType block = extent.getBlock(getPosition).getBlockType();
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
BlockType type = get.getBlock(extent).getBlockType();
TextureUtil util = holder.getTextureUtil();
int color = util.getColor(block);
int r = (color >> 16) & 0xFF;
int g = (color >> 8) & 0xFF;
int b = (color >> 0) & 0xFF;
int alpha = (color >> 24) & 0xFF;
double l = 0.3f * r + 0.6f * g + 0.1f * b;
int red = (int) (r + value * (l - r));
int green = (int) (g + value * (l - g));
int blue = (int) (b + value * (l - b));
int newColor = (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
int color = util.getColor(type);
int newColor = getColor(color);
if (newColor == color) {
return false;
}
BlockType newBlock = util.getNextNearestBlock(newColor);
if (block.equals(newBlock)) {
BlockType newType = util.getNextNearestBlock(newColor);
if (type.equals(newType)) {
return false;
}
return extent.setBlock(setPosition, newBlock.getDefaultState());
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
holder = Fawe.get().getCachedTextureUtil(true, 0, 100);
return set.setBlock(extent, newType.getDefaultState());
}
}

View File

@ -1,6 +1,7 @@
package com.boydti.fawe.object.pattern;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.beta.FilterBlock;
import com.boydti.fawe.util.TextureHolder;
import com.boydti.fawe.util.TextureUtil;
import com.sk89q.worldedit.WorldEditException;
@ -14,7 +15,7 @@ import java.io.IOException;
import java.io.ObjectInputStream;
public class SaturatePattern extends AbstractPattern {
private transient TextureHolder holder;
private final TextureHolder holder;
private final int color;
private final Extent extent;
@ -35,19 +36,14 @@ public class SaturatePattern extends AbstractPattern {
}
@Override
public boolean apply(Extent extent, BlockVector3 setPosition, BlockVector3 getPosition) throws WorldEditException {
BlockType block = extent.getBlock(getPosition).getBlockType();
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
BlockType block = get.getBlock(extent).getBlockType();
TextureUtil util = holder.getTextureUtil();
int currentColor = util.getColor(block);
if (currentColor == 0) return false;
int newColor = util.multiplyColor(currentColor, color);
BlockType newBlock = util.getNearestBlock(newColor);
if (newBlock.equals(block)) return false;
return extent.setBlock(setPosition, newBlock.getDefaultState());
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
holder = Fawe.get().getCachedTextureUtil(true, 0, 100);
return set.setBlock(extent, newBlock.getDefaultState());
}
}

View File

@ -2,17 +2,16 @@ package com.boydti.fawe.object.pattern;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.util.TextureUtil;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.AbstractPattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockType;
import java.io.IOException;
public class ShadePattern extends AbstractPattern {
private transient TextureUtil util;
private final TextureUtil util;
private final Extent extent;
private final boolean darken;
@ -29,8 +28,13 @@ public class ShadePattern extends AbstractPattern {
return (darken ? util.getDarkerBlock(block) : util.getLighterBlock(block)).getDefaultState().toBaseBlock();
}
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
util = Fawe.get().getCachedTextureUtil(true, 0, 100);
@Override
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
BlockType type = get.getBlock(extent).getBlockType();
BlockType newType = (darken ? util.getDarkerBlock(type) : util.getLighterBlock(type));
if (type != newType) {
return set.setBlock(extent, newType.getDefaultState());
}
return false;
}
}

View File

@ -2,21 +2,24 @@ package com.boydti.fawe.util;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
import com.boydti.fawe.object.FaweLimit;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.HistoryExtent;
import com.boydti.fawe.object.NullChangeSet;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.changeset.DiskStorageHistory;
import com.boydti.fawe.object.changeset.FaweChangeSet;
import com.boydti.fawe.object.changeset.MemoryOptimizedHistory;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.object.extent.NullExtent;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.event.extent.EditSessionEvent;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.eventbus.EventBus;
@ -26,10 +29,12 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.UUID;
import static com.google.common.base.Preconditions.checkNotNull;
public class EditSessionBuilder {
private World world;
private String worldName;
private FaweQueue queue;
private Extent extent;
private FawePlayer player;
private FaweLimit limit;
private FaweChangeSet changeSet;
@ -60,9 +65,17 @@ public class EditSessionBuilder {
public EditSessionBuilder(@Nonnull World world) {
checkNotNull(world);
this.world = world;
this.extent = world;
this.worldName = Fawe.imp().getWorldName(world);
}
public EditSessionBuilder(World world, String worldName) {
if (world == null && worldName == null) throw new NullPointerException("Both world and worldname cannot be null");
this.world = world;
this.extent = world;
this.worldName = worldName;
}
public EditSessionBuilder(@Nonnull String worldName) {
checkNotNull(worldName);
this.worldName = worldName;
@ -176,8 +189,8 @@ public class EditSessionBuilder {
return this;
}
public EditSessionBuilder queue(@Nullable FaweQueue queue) {
this.queue = queue;
public EditSessionBuilder extent(@Nullable Extent extent) {
this.extent = extent;
return this;
}
@ -191,10 +204,261 @@ public class EditSessionBuilder {
return this;
}
private boolean wrapped;
private AbstractDelegateExtent wrapExtent(final AbstractDelegateExtent extent, final EventBus eventBus, EditSessionEvent event, final EditSession.Stage stage) {
event = event.clone(stage);
event.setExtent(extent);
eventBus.post(event);
if (event.isCancelled()) {
return new NullExtent(extent, FaweException.MANUAL);
}
final Extent toReturn = event.getExtent();
if(toReturn instanceof com.sk89q.worldedit.extent.NullExtent) {
return new NullExtent(toReturn, FaweException.MANUAL);
}
if (!(toReturn instanceof AbstractDelegateExtent)) {
Fawe.debug("Extent " + toReturn + " must be AbstractDelegateExtent");
return extent;
}
if (toReturn != extent) {
String className = toReturn.getClass().getName().toLowerCase();
for (String allowed : Settings.IMP.EXTENT.ALLOWED_PLUGINS) {
if (className.contains(allowed.toLowerCase())) {
this.wrapped = true;
return (AbstractDelegateExtent) toReturn;
}
}
if (Settings.IMP.EXTENT.DEBUG) {
Fawe.debug("&cPotentially unsafe extent blocked: " + toReturn.getClass().getName());
Fawe.debug("&8 - &7For area restrictions, it is recommended to use the FaweAPI");
Fawe.debug("&8 - &7For block logging, it is recommended to use use BlocksHub");
Fawe.debug("&8 - &7To allow this plugin add it to the FAWE `allowed-plugins` list");
Fawe.debug("&8 - &7To hide this message set `debug` to false in the FAWE config.yml");
if (toReturn.getClass().getName().contains("CoreProtect")) {
Fawe.debug("Note on CoreProtect: ");
Fawe.debug(" - If you disable CP's WE logger (CP config) and this still shows, please update CP");
Fawe.debug(" - Use BlocksHub and set `debug` false in the FAWE config");
}
}
}
return extent;
}
private FaweChangeSet changeTask;
private int maxY;
private HistoryExtent history;
private AbstractDelegateExtent bypassHistory;
private AbstractDelegateExtent bypassAll;
public EditSessionBuilder compile() {
if (extent != null) return this;
wrapped = false;
if (world == null && !this.worldName.isEmpty()) {
world = FaweAPI.getWorld(this.worldName);
}
if (eventBus == null) {
eventBus = WorldEdit.getInstance().getEventBus();
}
if (event == null) {
event = new EditSessionEvent(world, player == null ? null : (player.getPlayer()), -1, null);
}
if (player == null && event.getActor() != null) {
player = FawePlayer.wrap(event.getActor());
}
if (limit == null) {
if (player == null) {
limit = FaweLimit.MAX;
} else {
limit = player.getLimit();
}
}
if (autoQueue == null) {
autoQueue = true;
}
if (fastmode == null) {
if (player == null) {
fastmode = !Settings.IMP.HISTORY.ENABLE_FOR_CONSOLE;
} else {
fastmode = player.getSession().hasFastMode();
}
}
if (checkMemory == null) {
checkMemory = player != null && !this.fastmode;
}
if (checkMemory) {
if (MemUtil.isMemoryLimitedSlow()) {
if (Perm.hasPermission(player, "worldedit.fast")) {
BBC.WORLDEDIT_OOM_ADMIN.send(player);
}
throw FaweException.LOW_MEMORY;
}
}
// this.originalLimit = limit;
this.blockBag = limit.INVENTORY_MODE != 0 ? blockBag : null;
// this.limit = limit.copy();
// if (queue == null) {
// boolean placeChunks = this.fastmode || this.limit.FAST_PLACEMENT;
// World unwrapped = WorldWrapper.unwrap(world);
// if (unwrapped instanceof FaweQueue) {
// queue = (FaweQueue) unwrapped;
// } else if (unwrapped instanceof MCAWorld) {
// queue = ((MCAWorld) unwrapped).getQueue();
// } else if (player != null && world.equals(player.getWorld())) {
// queue = player.getFaweQueue(placeChunks, autoQueue);
// } else {
// queue = SetQueue.IMP.getNewQueue(world, placeChunks, autoQueue);
// }
// }
// if (combineStages == null) {
// combineStages =
// // If it's enabled in the settings
// Settings.IMP.HISTORY.COMBINE_STAGES
// // If fast placement is disabled, it's slower to perform a copy on each chunk
// && this.limit.FAST_PLACEMENT
// // If the specific queue doesn't support it
// && queue.supports(FaweQueue.Capability.CHANGE_TASKS)
// // If the edit uses items from the inventory we can't use a delayed task
// && this.blockBag == null;
// }
// if (!Settings.IMP.QUEUE.PROGRESS.DISPLAY.equalsIgnoreCase("false") && player != null) {
// switch (Settings.IMP.QUEUE.PROGRESS.DISPLAY.toLowerCase()) {
// case "chat":
// this.queue.setProgressTask(new ChatProgressTracker(player));
// break;
// case "title":
// case "true":
// default:
// this.queue.setProgressTask(new DefaultProgressTracker(player));
// }
// }
// this.bypassAll = wrapExtent(new FastWorldEditExtent(world, queue), eventBus, event, EditSession.Stage.BEFORE_CHANGE);
// this.bypassHistory = (this.extent = wrapExtent(bypassAll, eventBus, event, EditSession.Stage.BEFORE_REORDER));
// if (!this.fastmode || changeSet != null) {
// if (changeSet == null) {
// if (Settings.IMP.HISTORY.USE_DISK) {
// UUID uuid = player == null ? EditSession.CONSOLE : player.getUUID();
// if (Settings.IMP.HISTORY.USE_DATABASE) {
// changeSet = new RollbackOptimizedHistory(world, uuid);
// } else {
// changeSet = new DiskStorageHistory(world, uuid);
// }
// } else if (combineStages && Settings.IMP.HISTORY.COMPRESSION_LEVEL == 0 && !(queue instanceof MCAQueue)) {
// changeSet = new CPUOptimizedChangeSet(world);
// } else {
// changeSet = new MemoryOptimizedHistory(world);
// }
// }
// if (this.limit.SPEED_REDUCTION > 0) {
// this.bypassHistory = new SlowExtent(this.bypassHistory, this.limit.SPEED_REDUCTION);
// }
// if (changeSet instanceof NullChangeSet && Fawe.imp().getBlocksHubApi() != null && player != null) {
// changeSet = LoggingChangeSet.wrap(player, changeSet);
// }
// if (!(changeSet instanceof NullChangeSet)) {
// if (!(changeSet instanceof LoggingChangeSet) && player != null && Fawe.imp().getBlocksHubApi() != null) {
// changeSet = LoggingChangeSet.wrap(player, changeSet);
// }
// if (this.blockBag != null) {
// changeSet = new BlockBagChangeSet(changeSet, blockBag, limit.INVENTORY_MODE == 1);
// }
// if (combineStages) {
// changeTask = changeSet;
// changeSet.addChangeTask(queue);
// } else {
// this.extent = (history = new HistoryExtent(bypassHistory, changeSet, queue));
//// if (this.blockBag != null) {
//// this.extent = new BlockBagExtent(this.extent, blockBag, limit.INVENTORY_MODE == 1);
//// }
// }
// }
// }
// if (allowedRegions == null) {
// if (player != null && !player.hasPermission("fawe.bypass") && !player.hasPermission("fawe.bypass.regions") && !(queue instanceof VirtualWorld)) {
// allowedRegions = player.getCurrentRegions();
// }
// }
// this.maxY = world == null ? 255 : world.getMaxY();
// if (allowedRegions != null) {
// if (allowedRegions.length == 0) {
// this.extent = new NullExtent(this.extent, FaweException.NO_REGION);
// } else {
// this.extent = new ProcessedWEExtent(this.extent, this.limit);
// if (allowedRegions.length == 1) {
// this.extent = new SingleRegionExtent(this.extent, this.limit, allowedRegions[0]);
// } else {
// this.extent = new MultiRegionExtent(this.extent, this.limit, allowedRegions);
// }
// }
// } else {
// this.extent = new HeightBoundExtent(this.extent, this.limit, 0, maxY);
// }
// if (this.limit.STRIP_NBT != null && !this.limit.STRIP_NBT.isEmpty()) {
// this.extent = new StripNBTExtent(this.extent, this.limit.STRIP_NBT);
// }
// this.extent = wrapExtent(this.extent, eventBus, event, EditSession.Stage.BEFORE_HISTORY);
// return this;
return this;
}
public EditSession build() {
if (eventBus == null) {
eventBus = WorldEdit.getInstance().getEventBus();
}
return new EditSession(worldName, world, queue, player, limit, changeSet, allowedRegions, autoQueue, fastmode, checkMemory, combineStages, blockBag, eventBus, event);
return new EditSession(this);
}
public Extent getExtent() {
return extent;
}
public World getWorld() {
return world;
}
public String getWorldName() {
return worldName;
}
public boolean isWrapped() {
return wrapped;
}
public boolean hasFastMode() {
return fastmode;
}
public HistoryExtent getHistory() {
return history;
}
public AbstractDelegateExtent getBypassHistory() {
return bypassHistory;
}
public AbstractDelegateExtent getBypassAll() {
return bypassAll;
}
public FaweLimit getLimit() {
return limit;
}
public FawePlayer getPlayer() {
return player;
}
public FaweChangeSet getChangeTask() {
return changeTask;
}
public BlockBag getBlockBag() {
return blockBag;
}
public int getMaxY() {
return maxY;
}
}

View File

@ -50,9 +50,8 @@ public final class NBTInputStream implements Closeable {
* from the specified input stream.
*
* @param is the input stream
* @throws IOException if an I/O error occurs
*/
public NBTInputStream(InputStream is) throws IOException {
public NBTInputStream(InputStream is) {
this.is = new DataInputStream(is);
}
@ -364,7 +363,7 @@ public final class NBTInputStream implements Closeable {
int toRead = Math.min(length << 2, buf.length);
is.readFully(buf, 0, toRead);
for (int i = 0; i < toRead; i += 4, index++) {
data[index] = ((buf[i + 0] & 0xFF) << 24) + ((buf[i + 1] & 0xFF) << 16) + ((buf[i + 2] & 0xFF) << 8) + (buf[i + 3] & 0xFF);
data[index] = ((buf[i] & 0xFF) << 24) + ((buf[i + 1] & 0xFF) << 16) + ((buf[i + 2] & 0xFF) << 8) + (buf[i + 3] & 0xFF);
}
length -= toRead;
}

View File

@ -38,6 +38,7 @@ import com.boydti.fawe.util.MaskTraverser;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
@ -91,6 +92,7 @@ import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* Clipboard commands.
*/
@ -123,20 +125,24 @@ public class ClipboardCommands {
Mask mask, CommandContext context) throws WorldEditException {
BlockVector3 min = region.getMinimumPoint();
BlockVector3 max = region.getMaximumPoint();
long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min.getZ() + 1));
FaweLimit limit = FawePlayer.wrap(player).getLimit();
if (volume >= limit.MAX_CHECKS) {
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
throw FaweException.MAX_CHECKS;
}
fp.checkConfirmationRegion(() -> {
session.setClipboard(null);
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, player.getUniqueId());
session.setClipboard(new ClipboardHolder(clipboard));
clipboard.setOrigin(session.getPlacementPosition(player));
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
copy.setCopyingEntities(!skipEntities);
copy.setCopyingBiomes(copyBiomes);
Mask sourceMask = editSession.getSourceMask();
if (sourceMask != null) {
new MaskTraverser(sourceMask).reset(editSession);
@ -204,12 +210,13 @@ public class ClipboardCommands {
long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min.getZ() + 1));
FaweLimit limit = FawePlayer.wrap(player).getLimit();
if (volume >= limit.MAX_CHECKS) {
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
throw FaweException.MAX_CHECKS;
}
if (volume >= limit.MAX_CHANGES) {
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHANGES);
throw FaweException.MAX_CHANGES;
}
session.setClipboard(null);
ReadOnlyClipboard lazyClipboard = new WorldCutClipboard(editSession, region, !skipEntities, copyBiomes);
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, lazyClipboard);
clipboard.setOrigin(session.getPlacementPosition(player));
@ -221,6 +228,7 @@ public class ClipboardCommands {
name = "/cut",
desc = "Cut the selection to the clipboard",
descFooter = "WARNING: Cutting and pasting entities cannot be undone!"
)
@CommandPermissions("worldedit.clipboard.cut")
@Logging(REGION)
@ -237,21 +245,24 @@ public class ClipboardCommands {
CommandContext context) throws WorldEditException {
BlockVector3 min = region.getMinimumPoint();
BlockVector3 max = region.getMaximumPoint();
long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min.getZ() + 1));
FaweLimit limit = FawePlayer.wrap(player).getLimit();
if (volume >= limit.MAX_CHECKS) {
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
throw FaweException.MAX_CHECKS;
}
if (volume >= limit.MAX_CHANGES) {
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHANGES);
throw FaweException.MAX_CHANGES;
}
fp.checkConfirmationRegion(() -> {
session.setClipboard(null);
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, player.getUniqueId());
clipboard.setOrigin(session.getPlacementPosition(player));
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
copy.setSourceFunction(new BlockReplace(editSession, leavePattern));
copy.setCopyingEntities(!skipEntities);
copy.setCopyingEntities(copyEntities);
copy.setRemovingEntities(true);
copy.setCopyingBiomes(copyBiomes);
Mask sourceMask = editSession.getSourceMask();
@ -413,6 +424,7 @@ public class ClipboardCommands {
@Command(
name = "/paste",
desc = "Paste the clipboard's contents"
)
@CommandPermissions("worldedit.clipboard.paste")
@Logging(PLACEMENT)
@ -481,6 +493,7 @@ public class ClipboardCommands {
name = "/place",
desc = "Place the clipboard's contents without applying transformations (e.g. rotate)"
)
@CommandPermissions("worldedit.clipboard.place")
@Logging(PLACEMENT)
public void place(Player player, LocalSession session, final EditSession editSession,
@ -551,6 +564,7 @@ public class ClipboardCommands {
public void flip(Player player, LocalSession session,
@Arg(desc = "The direction to flip, defaults to look direction.", def = Direction.AIM)
@Direction BlockVector3 direction) throws WorldEditException {
ClipboardHolder holder = session.getClipboard();
AffineTransform transform = new AffineTransform();
transform = transform.scale(direction.abs().multiply(-2).add(1, 1, 1).toVector3());
@ -563,7 +577,7 @@ public class ClipboardCommands {
desc = "Clear your clipboard"
)
@CommandPermissions("worldedit.clipboard.clear")
public void clearClipboard(Player player, LocalSession session) throws WorldEditException {
public void clearClipboard(Player player, LocalSession session, EditSession editSession) throws WorldEditException {
session.setClipboard(null);
BBC.CLIPBOARD_CLEARED.send(player);
}

View File

@ -205,6 +205,7 @@ public class PatternCommands extends MethodCommands {
" - Use to replace slabs or where the data values needs to be shifted instead of set"
)
public Pattern iddatamask(Actor actor, LocalSession session, Extent extent, @Range(min = 0, max = 15) int bitmask, Pattern pattern) {
return new IdDataMaskPattern(extent, pattern, bitmask);
}
@ -213,6 +214,7 @@ public class PatternCommands extends MethodCommands {
desc = "Only change the block id"
)
public Pattern id(Actor actor, LocalSession session, Extent extent, Pattern pattern) {
return new IdPattern(extent, pattern);
}
@ -221,6 +223,7 @@ public class PatternCommands extends MethodCommands {
desc = "Only change the block data"
)
public Pattern data(Actor actor, LocalSession session, Extent extent, Pattern pattern) {
return new DataPattern(extent, pattern);
}
@ -230,6 +233,7 @@ public class PatternCommands extends MethodCommands {
desc = "Set the biome"
)
public Pattern biome(Actor actor, LocalSession session, Extent extent, BiomeType biome) {
return new BiomePattern(extent, biome);
}
@ -239,6 +243,7 @@ public class PatternCommands extends MethodCommands {
desc = "Offset the pattern to where you click"
)
public Pattern relative(Actor actor, LocalSession session, Extent extent, Pattern pattern) {
return new RelativePattern(pattern);
}
@ -250,6 +255,7 @@ public class PatternCommands extends MethodCommands {
"Example: #!x[#!z[#~[#l3d[pattern]]]]"
)
public Pattern nox(Actor actor, LocalSession session, Extent extent, Pattern pattern) {
return new NoXPattern(pattern);
}
@ -259,6 +265,7 @@ public class PatternCommands extends MethodCommands {
desc = "The pattern will not be provided the y axis info"
)
public Pattern noy(Actor actor, LocalSession session, Extent extent, Pattern pattern) {
return new NoYPattern(pattern);
}
@ -268,6 +275,7 @@ public class PatternCommands extends MethodCommands {
desc = "The pattern will not be provided the z axis info"
)
public Pattern noz(Actor actor, LocalSession session, Extent extent, Pattern pattern) {
return new NoZPattern(pattern);
}
@ -285,6 +293,7 @@ public class PatternCommands extends MethodCommands {
desc = "Offset a pattern"
)
public Pattern offset(Actor actor, LocalSession session, double x, double y, double z, Pattern pattern) {
return new OffsetPattern(pattern, (int) x, (int) y, (int) z);
}
@ -293,6 +302,7 @@ public class PatternCommands extends MethodCommands {
desc = "Applies to only blocks on a surface. Selects a block from provided pattern with a given ranomized offset `[0, <distance>)`. e.g. Use `#existing` to randomly offset blocks in the world, or `#copy` to offset blocks in your clipboard"
)
public Pattern surfacespread(Actor actor, LocalSession session, double distance, Pattern pattern) {
return new SurfaceRandomOffsetPattern(pattern, (int) distance);
}
@ -301,6 +311,7 @@ public class PatternCommands extends MethodCommands {
desc = "Randomly spread solid blocks"
)
public Pattern solidspread(Actor actor, LocalSession session, double x, double y, double z, Pattern pattern) {
return new SolidRandomOffsetPattern(pattern, (int) x, (int) y, (int) z);
}
@ -310,6 +321,7 @@ public class PatternCommands extends MethodCommands {
desc = "Randomly spread blocks"
)
public Pattern spread(Actor actor, LocalSession session, double x, double y, double z, Pattern pattern) {
return new RandomOffsetPattern(pattern, (int) x, (int) y, (int) z);
}
@ -319,6 +331,7 @@ public class PatternCommands extends MethodCommands {
desc = "Sequentially set blocks from a list of patterns"
)
public Pattern linear(Actor actor, LocalSession session, Pattern other) {
if (other instanceof RandomPattern) {
Set<Pattern> patterns = ((RandomPattern) other).getPatterns();
return new LinearBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
@ -332,6 +345,7 @@ public class PatternCommands extends MethodCommands {
desc = "Use the x,y,z coordinate to pick a block from the list"
)
public Pattern linear3d(Actor actor, LocalSession session, Pattern other) {
if (other instanceof RandomPattern) {
Set<Pattern> patterns = ((RandomPattern) other).getPatterns();
return new Linear3DBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
@ -345,6 +359,7 @@ public class PatternCommands extends MethodCommands {
desc = "Use the x,z coordinate to pick a block from the list"
)
public Pattern linear2d(Actor actor, LocalSession session, Pattern other) {
if (other instanceof RandomPattern) {
Set<Pattern> patterns = ((RandomPattern) other).getPatterns();
return new Linear2DBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
@ -358,6 +373,7 @@ public class PatternCommands extends MethodCommands {
desc = "Expression pattern: http://wiki.sk89q.com/wiki/WorldEdit/Expression_syntax"
)
public Pattern expression(Actor actor, LocalSession session, Extent extent, String input) throws ExpressionException {
Expression exp = Expression.compile(input, "x", "y", "z");
WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment(extent, Vector3.ONE, Vector3.ZERO);
exp.setEnvironment(env);

View File

@ -29,7 +29,11 @@ import static com.sk89q.worldedit.regions.Regions.asFlatRegion;
import static com.sk89q.worldedit.regions.Regions.maximumBlockY;
import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.beta.filters.SetFilter;
import com.boydti.fawe.beta.implementation.QueueHandler;
import com.boydti.fawe.beta.filters.DistrFilter;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.example.NMSMappedFaweQueue;
import com.boydti.fawe.object.FaweLimit;
@ -54,6 +58,7 @@ import com.sk89q.worldedit.function.generator.FloraGenerator;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.NoiseFilter2D;
import com.sk89q.worldedit.function.mask.SolidBlockMask;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.visitor.LayerVisitor;
@ -76,9 +81,11 @@ import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.util.command.binding.Range;
import com.sk89q.worldedit.util.command.parametric.Optional;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.biome.Biomes;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import java.util.ArrayList;
@ -109,6 +116,43 @@ public class RegionCommands {
this.worldEdit = worldEdit;
}
@Command(
aliases = {"debugtest"},
usage = "",
desc = "debugtest",
help = "debugtest"
)
@CommandPermissions("fawe.admin.debug")
public void debugtest(Player player, @Selection Region region) throws WorldEditException {
QueueHandler queueHandler = Fawe.get().getQueueHandler();
World world = player.getWorld();
DistrFilter filter = new DistrFilter();
long start = System.currentTimeMillis();
queueHandler.apply(world, region, filter);
long diff = System.currentTimeMillis() - start;
System.out.println(diff);
}
@Command(
aliases = {"db2"},
usage = "",
desc = "db2",
help = "db2"
)
@CommandPermissions("fawe.admin.debug")
public void db2(Player player, @Selection Region region, String blockStr) throws WorldEditException {
QueueHandler queueHandler = Fawe.get().getQueueHandler();
World world = player.getWorld();
BlockState block = BlockState.get(blockStr);
SetFilter filter = new SetFilter(block);
long start = System.currentTimeMillis();
queueHandler.apply(world, region, filter);
long diff = System.currentTimeMillis() - start;
System.out.println(diff);
}
@Command(
name = "/fixlighting",
desc = "Get the light at a position"
@ -417,7 +461,7 @@ public class RegionCommands {
long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min.getZ() + 1));
FaweLimit limit = FawePlayer.wrap(player).getLimit();
if (volume >= limit.MAX_CHECKS) {
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
throw FaweException.MAX_CHECKS;
}
player.checkConfirmationRegion(() -> {
try {
@ -673,6 +717,7 @@ public class RegionCommands {
descFooter = "Hollows out the object contained in this selection.\n" +
"Optionally fills the hollowed out part with the given block.\n" +
"Thickness is measured in manhattan distance."
)
@CommandPermissions("worldedit.region.hollow")
@Logging(REGION)
@ -682,9 +727,11 @@ public class RegionCommands {
int thickness,
@Arg(desc = "The pattern of blocks to replace the hollowed area with", def = "air")
Pattern pattern,
CommandContext context) throws WorldEditException {
Mask finalMask = mask == null ? new SolidBlockMask(editSession) : mask;
player.checkConfirmationRegion(() -> {
int affected = editSession.hollowOutRegion(region, thickness, pattern);
int affected = editSession.hollowOutRegion(region, thickness, pattern, finalMask);
BBC.VISITOR_BLOCK.send(player, affected);
}, getArguments(context), region, context);
}

View File

@ -31,6 +31,7 @@ import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
import com.boydti.fawe.object.clipboard.URIClipboardHolder;
import com.boydti.fawe.object.clipboard.remap.ClipboardRemapper;
import com.boydti.fawe.object.schematic.StructureFormat;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.chat.Message;
import com.sk89q.minecraft.util.commands.CommandContext;
@ -80,6 +81,7 @@ import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.regex.Pattern;
import org.enginehub.piston.annotation.Command;
import org.enginehub.piston.annotation.CommandContainer;
@ -403,8 +405,8 @@ public class SchematicCommands {
}
if (new PlayerSaveClipboardEvent(player, clipboard, uri, f.toURI()).call()) {
try (ClipboardWriter writer = format.getWriter(fos)) {
if (writer instanceof StructureFormat) {
((StructureFormat) writer).write(target, player.getName());
if (writer instanceof MinecraftStructure) {
((MinecraftStructure) writer).write(target, player.getName());
} else {
writer.write(target);
}

View File

@ -27,6 +27,7 @@ import com.boydti.fawe.object.clipboard.URIClipboardHolder;
import com.boydti.fawe.object.mask.IdMask;
import com.boydti.fawe.object.regions.selector.FuzzyRegionSelector;
import com.boydti.fawe.object.regions.selector.PolyhedralRegionSelector;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
@ -490,7 +491,7 @@ public class SelectionCommands {
// TODO multi clipboard distribution
Clipboard clipboard = session.getClipboard().getClipboard(); // throws if missing
region = clipboard.getRegion();
editSession.setExtent(new AbstractDelegateExtent(clipboard));
new ExtentTraverser<AbstractDelegateExtent>(editSession).setNext(new AbstractDelegateExtent(clipboard));
} else {
region = session.getSelection(player.getWorld());
}
@ -499,6 +500,7 @@ public class SelectionCommands {
else
distribution = (List) editSession.getBlockDistribution(region);
if (distribution.isEmpty()) { // *Should* always be false
player.printError("No blocks counted.");
return;

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.command;
import static com.sk89q.worldedit.command.util.Logging.LogMode.PLACEMENT;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.DelegateConsumer;
@ -60,6 +61,7 @@ import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.visitor.EntityVisitor;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.math.BlockVector3;

View File

@ -75,6 +75,7 @@ public class WorldEditCommands {
FaweVersion fVer = Fawe.get().getVersion();
String fVerStr = fVer == null ? "unknown" : "-" + fVer.build;
actor.print("FastAsyncWorldEdit" + fVerStr + " created by Empire92");
if (fVer != null) {
actor.printDebug("----------- Platforms -----------");
FaweVersion version = Fawe.get().getVersion();

View File

@ -48,6 +48,7 @@ import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxBrushRadiusException;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
@ -643,15 +644,16 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
Brush brush = current.getBrush();
if (brush == null) return;
FawePlayer<Object> fp = FawePlayer.wrap(player);
EditSession editSession = new EditSessionBuilder(player.getWorld())
EditSessionBuilder builder = new EditSessionBuilder(player.getWorld())
.player(fp)
.allowedRegionsEverywhere()
.autoQueue(false)
.blockBag(null)
.changeSetNull()
.combineStages(false)
.build();
VisualExtent newVisualExtent = new VisualExtent(editSession.getExtent(), editSession.getQueue());
.combineStages(false);
EditSession editSession = builder.build();
VisualExtent newVisualExtent = new VisualExtent(builder.getExtent(), builder.getQueue());
BlockVector3 position = getPosition(editSession, player);
if (position != null) {
editSession.setExtent(newVisualExtent);

View File

@ -24,6 +24,7 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;
public class GravityBrush implements Brush {
@ -43,8 +44,8 @@ public class GravityBrush implements Brush {
for (int x = position.getBlockX() + size; x > position.getBlockX() - size; --x) {
for (int z = position.getBlockZ() + size; z > position.getBlockZ() - size; --z) {
int freeSpot = startCheckY;
for (int y = startCheckY; y <= endY; ++y) {
final BlockState block = editSession.getLazyBlock(x, y, z);
for (int y = startCheckY; y <= endY; y++) {
BlockStateHolder block = editSession.getBlock(x, y, z);
if (!block.getBlockType().getMaterial().isAir()) {
if (y != freeSpot) {
editSession.setBlock(x, y, z, BlockTypes.AIR.getDefaultState());

View File

@ -47,10 +47,8 @@ import javax.annotation.Nullable;
/**
* A base class for {@link Extent}s that merely passes extents onto another.
*/
public class AbstractDelegateExtent implements LightingExtent {
private transient final Extent extent;
protected MutableBlockVector3 mutable = new MutableBlockVector3(0, 0, 0);
public class AbstractDelegateExtent implements Extent, LightingExtent {
private final Extent extent;
/**
* Create a new instance.
@ -62,126 +60,18 @@ public class AbstractDelegateExtent implements LightingExtent {
this.extent = extent;
}
public int getSkyLight(int x, int y, int z) {
if (extent instanceof LightingExtent) {
return ((LightingExtent) extent).getSkyLight(x, y, z);
}
return 0;
}
@Override
public int getMaxY() {
return extent.getMaxY();
}
@Override
public int getBlockLight(int x, int y, int z) {
if (extent instanceof LightingExtent) {
return ((LightingExtent) extent).getBlockLight(x, y, z);
}
return getBrightness(x, y, z);
}
@Override
public int getOpacity(int x, int y, int z) {
if (extent instanceof LightingExtent) {
return ((LightingExtent) extent).getOpacity(x, y, z);
}
return getLazyBlock(x, y, z).getBlockType().getMaterial().getLightOpacity();
}
@Override
public int getLight(int x, int y, int z) {
if (extent instanceof LightingExtent) {
return ((LightingExtent) extent).getLight(x, y, z);
}
return 0;
}
@Override
public int getBrightness(int x, int y, int z) {
if (extent instanceof LightingExtent) {
return ((LightingExtent) extent).getBrightness(x, y, z);
}
return getLazyBlock(x, y, z).getBlockType().getMaterial().getLightValue();
}
/**
* Get the extent.
*
* @return the extent
*/
public Extent getExtent() {
public final Extent getExtent() {
return extent;
}
@Override
public BlockState getLazyBlock(int x, int y, int z) {
return extent.getLazyBlock(mutable.setComponents(x, y, z));
}
@Override
public BlockState getLazyBlock(BlockVector3 position) {
return extent.getLazyBlock(position);
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block) throws WorldEditException {
return setBlock(mutable.setComponents(x, y, z), block);
}
@Override
public BlockState getBlock(BlockVector3 position) {
return extent.getBlock(position);
}
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
return extent.getFullBlock(position);
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block) throws WorldEditException {
return extent.setBlock(location, block);
}
@Override
@Nullable
public Entity createEntity(Location location, BaseEntity entity) {
return extent.createEntity(location, entity);
}
@Override
public List<? extends Entity> getEntities() {
return extent.getEntities();
}
@Override
public List<? extends Entity> getEntities(Region region) {
return extent.getEntities(region);
}
@Override
public BiomeType getBiome(BlockVector2 position) {
return extent.getBiome(position);
}
@Override
public boolean setBiome(BlockVector2 position, BiomeType biome) {
return extent.setBiome(position, biome);
}
@Override
public boolean setBiome(int x, int y, int z, BiomeType biome) {
return extent.setBiome(x, y, z, biome);
}
@Override
public int getHighestTerrainBlock(int x, int z, int minY, int maxY) {
return extent.getHighestTerrainBlock(x, z, minY, maxY);
}
/*
Bounds
*/
@Override
public BlockVector3 getMinimumPoint() {
return extent.getMinimumPoint();
@ -192,78 +82,90 @@ public class AbstractDelegateExtent implements LightingExtent {
return extent.getMaximumPoint();
}
protected Operation commitBefore() {
return null;
@Override
public int getMaxY() {
return extent.getMaxY();
}
/*
Input + Output
*/
@Override
public BlockState getBlock(int x, int y, int z) {
return extent.getBlock(x, y, z);
}
@Override
public BaseBlock getFullBlock(int x, int y, int z) {
return extent.getFullBlock(x, y, z);
}
@Override
public BiomeType getBiomeType(int x, int z) {
return extent.getBiomeType(x, z);
}
@Override
public boolean setBiome(int x, int y, int z, BiomeType biome) {
return extent.setBiome(x, y, z, biome);
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block) throws WorldEditException {
return extent.setBlock(x, y, z, block);
}
/*
Light
*/
public int getSkyLight(int x, int y, int z) {
if (extent instanceof LightingExtent) {
return ((LightingExtent) extent).getSkyLight(x, y, z);
}
return 0;
}
public int getBlockLight(int x, int y, int z) {
if (extent instanceof LightingExtent) {
return ((LightingExtent) extent).getBlockLight(x, y, z);
}
return getBrightness(x, y, z);
}
public int getOpacity(int x, int y, int z) {
if (extent instanceof LightingExtent) {
return ((LightingExtent) extent).getOpacity(x, y, z);
}
return getBlock(x, y, z).getBlockType().getMaterial().getLightOpacity();
}
@Override
public int getLight(int x, int y, int z) {
if (extent instanceof LightingExtent) {
return ((LightingExtent) extent).getLight(x, y, z);
}
return 0;
}
public int getBrightness(int x, int y, int z) {
if (extent instanceof LightingExtent) {
return ((LightingExtent) extent).getBrightness(x, y, z);
}
return getBlock(x, y, z).getBlockType().getMaterial().getLightValue();
}
/*
Generic
*/
@Override
public String toString() {
return super.toString() + ":" + extent.toString();
}
@Override
public int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) {
return extent.getNearestSurfaceLayer(x, z, y, minY, maxY);
}
@Override
public int getHighestTerrainBlock(int x, int z, int minY, int maxY, Mask filter) {
return extent.getHighestTerrainBlock(x, z, minY, maxY, filter);
}
@Override
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, boolean ignoreAir) {
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, ignoreAir);
}
@Override
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) {
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY);
}
@Override
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax) {
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax);
}
@Override
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, Mask mask) {
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, mask);
}
@Override
public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, boolean ignoreAir) {
return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, ignoreAir);
}
@Override
public void addCaves(Region region) throws WorldEditException {
extent.addCaves(region);
}
@Override
public void generate(Region region, GenBase gen) throws WorldEditException {
extent.generate(region, gen);
}
@Override
public void spawnResource(Region region, Resource gen, int rarity, int frequency) throws WorldEditException {
extent.spawnResource(region, gen, rarity, frequency);
}
@Override
public boolean contains(BlockVector3 pt) {
return extent.contains(pt);
}
@Override
public void addOre(Region region, Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException {
extent.addOre(region, mask, material, size, frequency, rarity, minY, maxY);
}
@Override
public void addOres(Region region, Mask mask) throws WorldEditException {
extent.addOres(region, mask);
protected Operation commitBefore() {
return null;
}
@Override
@ -281,6 +183,4 @@ public class AbstractDelegateExtent implements LightingExtent {
return null;
}
}
}

View File

@ -22,6 +22,8 @@ package com.sk89q.worldedit.extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector2;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
@ -45,30 +47,13 @@ public interface InputExtent {
* @param position position of the block
* @return the block
*/
BlockState getBlock(BlockVector3 position);
default BlockState getBlock(BlockVector3 position) {
return getBlock(position.getX(), position.getY(), position.getZ());
}
/**
* Get a lazy, immutable snapshot of the block at the given location that only
* immediately contains information about the block's type (and metadata).
*
* <p>Further information (such as NBT data) will be available <strong>by the
* time of access</strong>. Therefore, it is not recommended that
* this method is used if the world is being simulated at the time of
* call. If the block needs to be stored for future use, then this method should
* definitely not be used. Moreover, the block that is returned is immutable (or
* should be), and therefore modifications should not be attempted on it. If a
* modifiable copy is required, then the block should be cloned.</p>
*
* <p>This method exists because it is sometimes important to inspect the block
* at a given location, but {@link #getBlock(BlockVector3)} may be too expensive in
* the underlying implementation. It is also not possible to implement
* caching if the returned object is mutable, so this methods allows caching
* implementations to be used.</p>
*
* @param position position of the block
* @return the block
*/
BlockState getLazyBlock(BlockVector3 position);
default BlockState getBlock(int x, int y, int z) {
return getBlock(MutableBlockVector3.get(x, y, z));
}
/**
* Get a immutable snapshot of the block at the given location.
@ -76,7 +61,13 @@ public interface InputExtent {
* @param position position of the block
* @return the block
*/
BaseBlock getFullBlock(BlockVector3 position);
default BaseBlock getFullBlock(BlockVector3 position) {
return getFullBlock(position.getX(), position.getY(), position.getZ());
}
default BaseBlock getFullBlock(int x, int y, int z) {
return getFullBlock(MutableBlockVector3.get(x, y, z));
}
/**
* Get the biome at the given location.
@ -87,6 +78,11 @@ public interface InputExtent {
* @param position the (x, z) location to check the biome at
* @return the biome at the location
*/
BiomeType getBiome(BlockVector2 position);
default BiomeType getBiome(BlockVector2 position) {
return getBiomeType(position.getX(), position.getZ());
}
default BiomeType getBiomeType(int x, int z) {
return getBiome(MutableBlockVector2.get(x, z));
}
}

View File

@ -73,16 +73,10 @@ public class NullExtent implements Extent {
return null;
}
@Override
public BlockState getBlock(BlockVector3 position) {
return BlockTypes.AIR.getDefaultState();
}
@Override
public BlockState getLazyBlock(BlockVector3 position) {
return BlockTypes.AIR.getDefaultState();
}
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
return getBlock(position).toBaseBlock();

View File

@ -199,9 +199,20 @@ public class SpongeSchematicReader extends NBTSchematicReader {
setupClipboard(0, uuid);
}
int[] pos = value.getIntArray("Pos");
int x = pos[0];
int y = pos[1];
int z = pos[2];
int x,y,z;
if (pos.length != 3) {
System.out.println("Invalid tile " + value);
if (!value.containsKey("x") || !value.containsKey("y") || !value.containsKey("z")) {
return;
}
x = value.getInt("x");
y = value.getInt("y");
z = value.getInt("z");
} else {
x = pos[0];
y = pos[1];
z = pos[2];
}
Map<String, Tag> values = value.getValue();
Tag id = values.get("Id");
if (id != null) {

View File

@ -51,6 +51,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
/**
@ -94,19 +95,11 @@ public class BlockTransformExtent extends ResettableExtent {
}
private static long[] adapt(Direction... dirs) {
long[] arr = new long[dirs.length];
for (int i = 0; i < arr.length; i++) {
arr[i] = 1L << dirs[i].ordinal();
}
return arr;
return Arrays.stream(dirs).mapToLong(dir -> 1L << dir.ordinal()).toArray();
}
private static long[] adapt(Long... dirs) {
long[] arr = new long[dirs.length];
for (int i = 0; i < arr.length; i++) {
arr[i] = dirs[i];
}
return arr;
return Arrays.stream(dirs).mapToLong(dir -> dir).toArray();
}
private static long[] getDirections(AbstractProperty property) {
@ -138,7 +131,7 @@ public class BlockTransformExtent extends ResettableExtent {
case FACING: {
List<Direction> directions = new ArrayList<>();
for (Object value : values) {
directions.add(Direction.valueOf(value.toString().toUpperCase()));
directions.add(Direction.valueOf(value.toString().toUpperCase(Locale.ROOT)));
}
return adapt(directions.toArray(new Direction[0]));
}
@ -220,9 +213,7 @@ public class BlockTransformExtent extends ResettableExtent {
}
private static long notIndex(long mask, int... indexes) {
for (int index : indexes) {
mask = mask | (1L << (index + values().length));
}
mask |= Arrays.stream(indexes).mapToLong(index -> (1L << (index + values().length))).reduce(0, (a, b) -> a | b);
return mask;
}
@ -344,10 +335,10 @@ public class BlockTransformExtent extends ResettableExtent {
Object southState = tmp.getState(PropertyKey.SOUTH);
Object westState = tmp.getState(PropertyKey.WEST);
tmp = tmp.with(PropertyKey.valueOf(newNorth.name().toUpperCase()), northState);
tmp = tmp.with(PropertyKey.valueOf(newEast.name().toUpperCase()), eastState);
tmp = tmp.with(PropertyKey.valueOf(newSouth.name().toUpperCase()), southState);
tmp = tmp.with(PropertyKey.valueOf(newWest.name().toUpperCase()), westState);
tmp = tmp.with(PropertyKey.valueOf(newNorth.name().toUpperCase(Locale.ROOT)), northState);
tmp = tmp.with(PropertyKey.valueOf(newEast.name().toUpperCase(Locale.ROOT)), eastState);
tmp = tmp.with(PropertyKey.valueOf(newSouth.name().toUpperCase(Locale.ROOT)), southState);
tmp = tmp.with(PropertyKey.valueOf(newWest.name().toUpperCase(Locale.ROOT)), westState);
newMaskedId = tmp.getInternalId();
}
@ -476,7 +467,7 @@ public class BlockTransformExtent extends ResettableExtent {
return BlockState.getFromInternalId(newMaskedId);
}
public final BaseBlock transform(BlockStateHolder block) {
public final BaseBlock transform(BlockStateHolder<BaseBlock> block) {
BlockState transformed = transform(block.toImmutableState());
if (block.hasNbtData()) {
return transformBaseBlockNBT(transformed, block.getNbtData(), transform);
@ -501,13 +492,8 @@ public class BlockTransformExtent extends ResettableExtent {
}
@Override
public BlockState getLazyBlock(int x, int y, int z) {
return transform(super.getLazyBlock(x, y, z));
}
@Override
public BlockState getLazyBlock(BlockVector3 position) {
return transform(super.getLazyBlock(position));
public BlockState getBlock(int x, int y, int z) {
return transform(super.getBlock(x, y, z));
}
@Override

View File

@ -19,256 +19,215 @@
package com.sk89q.worldedit.function.mask;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.object.collection.FastBitSet;
import com.boydti.fawe.util.StringMan;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.NullExtent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.AbstractProperty;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import java.util.function.Predicate;
/**
* A mask that checks whether blocks at the given positions are matched by
* a block in a list.
*
* <p>This mask checks for both an exact block type and state value match,
* respecting fuzzy status of the BlockState.</p>
* @deprecated use BlockMaskBuilder
*/
@Deprecated
public class BlockMask extends AbstractExtentMask {
private final long[][] bitSets;
protected final static long[] ALL = new long[0];
/**
* Create a new block mask.
*
* @param extent the extent
* @param blocks a list of blocks to match
*/
public BlockMask(Extent extent, Collection<BaseBlock> blocks) {
super(extent);
checkNotNull(blocks);
this.bitSets = new BlockMaskBuilder().addBlocks(blocks).optimize().getBits();
}
/**
* Create a new block mask.
*
* @param extent the extent
* @param block an array of blocks to match
*/
public BlockMask(Extent extent, BaseBlock... block) {
super(extent);
checkNotNull(block);
this.bitSets = new BlockMaskBuilder().addBlocks(block).optimize().getBits();
}
public class BlockMask extends ABlockMask {
private final boolean[] ordinals;
public BlockMask() {
super(NullExtent.INSTANCE);
this.bitSets = new long[BlockTypes.size()][];
this(new NullExtent());
}
protected BlockMask(Extent extent, long[][] bitSets) {
super(extent);
this.bitSets = bitSets;
public BlockMask(Extent extent) {
this(extent, new boolean[BlockTypes.states.length]);
}
public BlockMaskBuilder toBuilder() {
return new BlockMaskBuilder(this.bitSets);
public BlockMask(Extent extent, boolean[] ordinals) {
super(extent == null ? new NullExtent() : extent);
this.ordinals = ordinals;
}
/**
* @deprecated NBT not supported by this mask
*/
@Deprecated
public BlockMask(Extent extent, Collection<BaseBlock> blocks) {
this(extent);
add(blocks);
}
public BlockMask add(Predicate<BlockState> predicate) {
for (int i = 0; i < ordinals.length; i++) {
if (!ordinals[i]) {
BlockState state = BlockTypes.states[i];
if (state != null) ordinals[i] = predicate.test(state);
}
}
return this;
}
public BlockMask add(BlockState... states) {
addStates(Arrays.asList(states));
return this;
}
public BlockMask remove(BlockState... states) {
for (BlockState state : states) ordinals[state.getOrdinal()] = false;
return this;
}
public BlockMask clear() {
Arrays.fill(ordinals, false);
return this;
}
public boolean isEmpty() {
for (boolean value : ordinals) {
if (value) return false;
}
return true;
}
public BlockMask addStates(Collection<BlockState> states) {
for (BlockState state : states) ordinals[state.getOrdinal()] = true;
return this;
}
public BlockMask add(BlockType... types) {
addTypes(Arrays.asList(types));
return this;
}
public BlockMask addTypes(Collection<BlockType> types) {
for (BlockType type : types) {
for (BlockState state : type.getAllStates()) {
ordinals[state.getOrdinal()] = true;
}
}
return this;
}
/**
* @deprecated NBT not supported by this mask
*/
@Deprecated
public void add(Collection<BaseBlock> blocks) {
for (BaseBlock block : blocks) {
add(block.toBlockState());
}
}
@Override
public String toString() {
List<String> strings = new ArrayList<>();
for (int i = 0; i < bitSets.length; i++) {
if (bitSets[i] != null) {
long[] set = bitSets[i];
BlockType type = BlockTypes.get(i);
if (set == ALL) {
strings.add(type.getId());
} else {
for (BlockState state : type.getAllStates()) {
if (test(state)) {
strings.add(state.getAsString());
}
}
}
}
}
return StringMan.join(strings, ",");
public boolean test(BlockState state) {
return ordinals[state.getOrdinal()];
}
@Override
public Mask optimize() {
Map<Object, Integer> states = new HashMap<>();
int indexFound = -1;
{
int indexNull = -1;
int indexAll = -1;
for (int i = 0; i < bitSets.length; i++) {
long[] bs = bitSets[i];
if (bs == null) {
indexNull = i;
states.put(null, states.getOrDefault(null, 0) + 1);
} else if (bs.length == 0) {
indexAll = i;
states.put(ALL, states.getOrDefault(ALL, 0) + 1);
} else if (indexFound == -1) {
indexFound = i;
} else {
return this;
}
}
// Only types, no states
if (indexFound == -1) {
if (states.size() == 1) {
return states.keySet().iterator().next() == null ? Masks.alwaysFalse() : Masks.alwaysTrue();
}
if (states.get(ALL) == 1) return new SingleBlockTypeMask(getExtent(), BlockTypes.get(indexAll));
if (states.get(null) == 1)
return new SingleBlockTypeMask(getExtent(), BlockTypes.get(indexNull)).inverse();
boolean[] types = new boolean[BlockTypes.size()];
for (int i = 0; i < bitSets.length; i++) {
if (bitSets[i].length == 0) types[i] = true;
}
return new BlockTypeMask(getExtent(), types);
}
}
BlockType type = BlockTypes.get(indexFound);
Mask mask = getOptimizedMask(type, bitSets[indexFound]);
if (mask == null) { // Try with inverse
long[] newBitSet = bitSets[indexFound];
for (int i = 0; i < newBitSet.length; i++) newBitSet[i] = ~newBitSet[i];
mask = getOptimizedMask(type, bitSets[indexFound]);
if (mask != null) mask = mask.inverse();
}
return mask;
}
private Mask getOptimizedMask(BlockType type, long[] bitSet) {
boolean single = true;
int and = type.getInternalId();
List<? extends Property> properties = type.getProperties();
for (AbstractProperty prop : (List<AbstractProperty<?>>) type.getProperties()) {
List values = prop.getValues();
int numSet = 0;
for (int i = 0; i < values.size(); i++) {
int localI = i << prop.getBitOffset();
if (FastBitSet.get(bitSet, localI)) {
numSet++;
and |= prop.modify(and, i);
}
}
// Cannot optimize multiple property values - use current mask (null)
if (numSet != values.size() && numSet != 1) {
return null;
}
single = single && numSet == 1;
}
if (single)
return new SingleBlockStateMask(getExtent(), BlockState.getFromInternalId(and));
return new SingleBlockStateBitMask(getExtent(), and);
public boolean test(BlockVector3 vector) {
return ordinals[vector.getOrdinal(getExtent())];
}
@Override
public Mask and(Mask other) {
if (other instanceof BlockMask) {
long[][] otherBitSets = ((BlockMask) other).bitSets;
for (int i = 0; i < otherBitSets.length; i++) {
long[] otherBitSet = otherBitSets[i];
long[] bitSet = bitSets[i];
if (otherBitSet == null) bitSets[i] = null;
else if (otherBitSet.length == 0) continue;
else if (bitSet == null) continue;
else if (bitSet.length == 0) bitSets[i] = otherBitSet;
else for (int j = 0; j < otherBitSet.length; j++) bitSet[j] &= otherBitSet[j];
public Mask and(Mask mask) {
if (mask instanceof ABlockMask) {
ABlockMask other = (ABlockMask) mask;
for (int i = 0; i < ordinals.length; i++) {
if (ordinals[i]) {
ordinals[i] = other.test(BlockState.getFromOrdinal(i));
}
}
return this;
}
if (other instanceof SingleBlockStateMask) {
return new BlockMaskBuilder(bitSets).filter(((SingleBlockStateMask) other).getBlockState()).build(getExtent());
}
if (other instanceof SingleBlockTypeMask) {
return new BlockMaskBuilder(bitSets).filter(((SingleBlockTypeMask) other).getBlockType()).build(getExtent());
}
return null;
}
@Override
public Mask or(Mask other) {
if (other instanceof BlockMask) {
long[][] otherBitSets = ((BlockMask) other).bitSets;
for (int i = 0; i < otherBitSets.length; i++) {
long[] otherBitSet = otherBitSets[i];
long[] bitSet = bitSets[i];
if (otherBitSet == null) continue;
else if (otherBitSet.length == 0) bitSets[i] = ALL;
else if (bitSet == null) bitSets[i] = otherBitSet;
else if (bitSet.length == 0) continue;
else for (int j = 0; j < otherBitSet.length; j++) bitSet[j] |= otherBitSet[j];
public Mask or(Mask mask) {
if (mask instanceof ABlockMask) {
ABlockMask other = (ABlockMask) mask;
for (int i = 0; i < ordinals.length; i++) {
if (!ordinals[i]) {
ordinals[i] = other.test(BlockState.getFromOrdinal(i));
}
}
return this;
}
if (other instanceof SingleBlockStateMask) {
return new BlockMaskBuilder(bitSets).add(((SingleBlockStateMask) other).getBlockState()).build(getExtent());
return null;
}
@Override
public Mask optimize() {
int setStates = 0;
BlockState setState = null;
BlockState unsetState = null;
int totalStates = 0;
int setTypes = 0;
BlockType setType = null;
BlockType unsetType = null;
int totalTypes = 0;
for (BlockType type : BlockTypes.values) {
if (type != null) {
totalTypes++;
boolean hasAll = true;
boolean hasAny = false;
List<BlockState> all = type.getAllStates();
for (BlockState state : all) {
totalStates++;
hasAll &= test(state);
hasAny = true;
}
if (hasAll) {
setTypes++;
setType = type;
setStates += all.size();
setState = type.getDefaultState();
} else if (hasAny) {
for (BlockState state : all) {
if (test(state)) {
setStates++;
setState = state;
} else {
unsetState = state;
}
}
} else {
unsetType = type;
}
}
}
if (other instanceof SingleBlockTypeMask) {
return new BlockMaskBuilder(bitSets).add(((SingleBlockTypeMask) other).getBlockType()).build(getExtent());
if (setStates == 0) {
return Masks.alwaysFalse();
}
if (setStates == totalStates) {
return Masks.alwaysTrue();
}
if (setStates == 1) {
return new SingleBlockStateMask(getExtent(), setState);
}
if (setStates == totalStates - 1) {
return new InverseSingleBlockStateMask(getExtent(), unsetState);
}
if (setTypes == 1) {
return new SingleBlockTypeMask(getExtent(), setType);
}
if (setTypes == totalTypes - 1) {
return new InverseSingleBlockTypeMask(getExtent(), unsetType);
}
return null;
}
@Override
public Mask inverse() {
long[][] cloned = bitSets.clone();
for (int i = 0; i < cloned.length; i++) {
if (cloned[i] == null) cloned[i] = ALL;
else if (cloned[i] == ALL) cloned[i] = null;
else {
for (int j = 0; j < cloned[i].length; j++)
cloned[i][j] = ~cloned[i][j];
}
}
boolean[] cloned = ordinals.clone();
for (int i = 0; i < cloned.length; i++) cloned[i] = !cloned[i];
return new BlockMask(getExtent(), cloned);
}
public boolean test(BlockState block) {
long[] bitSet = bitSets[block.getInternalBlockTypeId()];
if (bitSet == null) return false;
if (bitSet.length == 0) return true;
return FastBitSet.get(bitSet, block.getInternalPropertiesId());
}
@Override
public boolean test(BlockVector3 vector) {
BlockStateHolder block = getExtent().getBlock(vector);
long[] bitSet = bitSets[block.getInternalBlockTypeId()];
if (bitSet == null) return false;
if (bitSet.length == 0) return true;
return FastBitSet.get(bitSet, block.getInternalPropertiesId());
}
@Nullable
@Override
public Mask2D toMask2D() {
return null;
}
}

View File

@ -10,6 +10,7 @@ import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.registry.state.AbstractProperty;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.registry.state.PropertyKey;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
@ -28,6 +29,8 @@ public class BlockMaskBuilder {
private static final Operator LESS_EQUAL = (a, b) -> a <= b;
private static final Operator NOT = (a, b) -> a != b;
private final static long[] ALL = new long[0];
private interface Operator {
boolean test(int left, int right);
}
@ -223,7 +226,7 @@ public class BlockMaskBuilder {
if (states == null) return false;
List values = prop.getValues();
int localI = index << prop.getBitOffset() >> BlockTypes.BIT_OFFSET;
return (states == BlockMask.ALL || FastBitSet.get(states, localI));
return (states == ALL || FastBitSet.get(states, localI));
}
private void suggest(String input, String property, Collection<BlockType> finalTypes) throws InputParseException {
@ -240,6 +243,7 @@ public class BlockMaskBuilder {
///// end internal /////
private long[][] bitSets;
private boolean[] ordinals;
private boolean optimizedStates = true;
@ -256,14 +260,23 @@ public class BlockMaskBuilder {
}
public BlockMaskBuilder addAll() {
Arrays.fill(bitSets, BlockMask.ALL);
optimizedStates = true;
for (int i = 0; i < bitSets.length; i++) {
bitSets[i] = ALL;
}
reset(true);
return this;
}
private void reset(boolean optimized) {
this.ordinals = null;
this.optimizedStates = optimized;
}
public BlockMaskBuilder clear() {
Arrays.fill(bitSets, null);
optimizedStates = true;
for (int i = 0; i < bitSets.length; i++) {
bitSets[i] = null;
}
reset(true);
return this;
}
@ -277,13 +290,13 @@ public class BlockMaskBuilder {
int i = type.getInternalId();
long[] states = bitSets[i];
if (states != null) {
if (states == BlockMask.ALL) {
if (states == ALL) {
bitSets[i] = states = FastBitSet.create(type.getMaxStateId() + 1);
Arrays.fill(states, -1);
}
int stateId = state.getInternalPropertiesId();
FastBitSet.clear(states, stateId);
optimizedStates = false;
reset(false);
}
return this;
}
@ -305,7 +318,7 @@ public class BlockMaskBuilder {
if (states != null) {
int stateId = state.getInternalPropertiesId();
boolean set = true;
if (states == BlockMask.ALL) {
if (states == ALL) {
bitSets[i] = states = FastBitSet.create(type.getMaxStateId() + 1);
} else {
set = FastBitSet.get(states, stateId);
@ -315,7 +328,7 @@ public class BlockMaskBuilder {
FastBitSet.set(states, stateId);
else
bitSets[i] = null;
optimizedStates = true;
reset(true);
}
return this;
}
@ -344,14 +357,14 @@ public class BlockMaskBuilder {
List values = prop.getValues();
for (int j = 0; j < values.size(); j++) {
int localI = j << prop.getBitOffset() >> BlockTypes.BIT_OFFSET;
if (states == BlockMask.ALL || FastBitSet.get(states, localI)) {
if (states == ALL || FastBitSet.get(states, localI)) {
if (!allowed.test(type, new AbstractMap.SimpleEntry(prop, values.get(j)))) {
if (states == BlockMask.ALL) {
if (states == ALL) {
bitSets[i] = states = FastBitSet.create(type.getMaxStateId() + 1);
FastBitSet.setAll(states);
}
FastBitSet.clear(states, localI);
optimizedStates = false;
reset(false);
}
}
}
@ -361,7 +374,7 @@ public class BlockMaskBuilder {
}
public BlockMaskBuilder add(BlockType type) {
bitSets[type.getInternalId()] = BlockMask.ALL;
bitSets[type.getInternalId()] = ALL;
return this;
}
@ -369,13 +382,13 @@ public class BlockMaskBuilder {
BlockType type = state.getBlockType();
int i = type.getInternalId();
long[] states = bitSets[i];
if (states != BlockMask.ALL) {
if (states != ALL) {
if (states == null) {
bitSets[i] = states = FastBitSet.create(type.getMaxStateId() + 1);
}
int stateId = state.getInternalPropertiesId();
FastBitSet.set(states, stateId);
optimizedStates = false;
reset(false);
}
return this;
}
@ -404,7 +417,7 @@ public class BlockMaskBuilder {
for (int i = 0; i < bitSets.length; i++) {
BlockType type = BlockTypes.get(i);
if (allow.test(type)) {
bitSets[i] = BlockMask.ALL;
bitSets[i] = ALL;
}
}
return this;
@ -413,7 +426,7 @@ public class BlockMaskBuilder {
public BlockMaskBuilder addAll(Predicate<BlockType> typePredicate, BiPredicate<BlockType, Map.Entry<Property<?>, ?>> propPredicate) {
for (int i = 0; i < bitSets.length; i++) {
long[] states = bitSets[i];
if (states == BlockMask.ALL) continue;
if (states == ALL) continue;
BlockType type = BlockTypes.get(i);
if (!typePredicate.test(type)) {
continue;
@ -428,7 +441,7 @@ public class BlockMaskBuilder {
bitSets[i] = states = FastBitSet.create(type.getMaxStateId() + 1);
}
FastBitSet.set(states, localI);
optimizedStates = false;
reset(false);
}
}
}
@ -440,7 +453,7 @@ public class BlockMaskBuilder {
public BlockMaskBuilder add(BlockType type, Property property, int index) {
AbstractProperty prop = (AbstractProperty) property;
long[] states = bitSets[type.getInternalId()];
if (states == BlockMask.ALL) return this;
if (states == ALL) return this;
List values = property.getValues();
int localI = index << prop.getBitOffset() >> BlockTypes.BIT_OFFSET;
@ -449,7 +462,7 @@ public class BlockMaskBuilder {
bitSets[type.getInternalId()] = states = FastBitSet.create(type.getMaxStateId() + 1);
}
set(type, states, property, index);
optimizedStates = false;
reset(false);
}
return this;
}
@ -460,13 +473,13 @@ public class BlockMaskBuilder {
if (states == null) return this;
List values = property.getValues();
int localI = index << prop.getBitOffset() >> BlockTypes.BIT_OFFSET;
if (states == BlockMask.ALL || FastBitSet.get(states, localI)) {
if (states == BlockMask.ALL) {
if (states == ALL || FastBitSet.get(states, localI)) {
if (states == ALL) {
bitSets[type.getInternalId()] = states = FastBitSet.create(type.getMaxStateId() + 1);
FastBitSet.setAll(states);
}
clear(type, states, property, index);
optimizedStates = false;
reset(false);
}
return this;
}
@ -512,7 +525,7 @@ public class BlockMaskBuilder {
if (!optimizedStates) {
for (int i = 0; i < bitSets.length; i++) {
long[] bitSet = bitSets[i];
if (bitSet == null || bitSet == BlockMask.ALL) continue;
if (bitSet == null || bitSet == ALL) continue;
BlockType type = BlockTypes.get(i);
int maxStateId = type.getMaxStateId();
if (maxStateId == 0) {
@ -520,7 +533,7 @@ public class BlockMaskBuilder {
bitSets[i] = null;
continue;
} else {
bitSets[i] = BlockMask.ALL;
bitSets[i] = ALL;
continue;
}
}
@ -535,19 +548,38 @@ public class BlockMaskBuilder {
}
}
if (set == 0) bitSets[i] = null;
else if (clear == 0) bitSets[i] = BlockMask.ALL;
else if (clear == 0) bitSets[i] = ALL;
}
optimizedStates = true;
reset(true);
}
return this;
}
protected long[][] getBits() {
return this.bitSets;
private boolean[] getOrdinals() {
if (ordinals == null) {
ordinals = new boolean[BlockTypes.states.length];
for (int i = 0; i < BlockTypes.values.length; i++) {
long[] bitSet = bitSets[i];
if (bitSet == null) continue;
BlockType type = BlockTypes.values[i];
if (bitSet == ALL) {
for (BlockState state : type.getAllStates()) {
ordinals[state.getOrdinal()] = true;
}
} else {
for (BlockState state : type.getAllStates()) {
if (FastBitSet.get(bitSet, state.getInternalPropertiesId())) {
ordinals[state.getOrdinal()] = true;
}
}
}
}
}
return ordinals;
}
public BlockMask build(Extent extent) {
optimize();
return new BlockMask(extent, bitSets);
return new BlockMask(extent, getOrdinals());
}
}

View File

@ -20,7 +20,6 @@
package com.sk89q.worldedit.function.mask;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockType;
@ -37,8 +36,12 @@ import java.util.Set;
*
* <p>This mask checks for ONLY the block type. If state should also be checked,
* use {@link BlockMask}.</p>
* @deprecated use BlockMaskBuilder
*/
public class BlockTypeMask extends AbstractExtentMask {
import static com.google.common.base.Preconditions.checkNotNull;
@Deprecated
public final class BlockTypeMask extends AbstractExtentMask {
private final boolean[] types;
@ -110,12 +113,11 @@ public class BlockTypeMask extends AbstractExtentMask {
@Override
public boolean test(BlockVector3 vector) {
return types[getExtent().getBlock(vector).getBlockType().getInternalId()];
return test(vector.getBlock(getExtent()).getBlockType());
}
@Nullable
@Override
public Mask2D toMask2D() {
return null;
public boolean test(BlockType block) {
return types[block.getInternalId()];
}
}

View File

@ -2,10 +2,11 @@ package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
public class SingleBlockTypeMask extends AbstractExtentMask {
public class SingleBlockTypeMask extends ABlockMask {
private final int internalId;
public SingleBlockTypeMask(Extent extent, BlockType type) {
@ -15,12 +16,17 @@ public class SingleBlockTypeMask extends AbstractExtentMask {
@Override
public boolean test(BlockVector3 vector) {
return getExtent().getBlock(vector).getBlockType().getInternalId() == internalId;
return test(vector.getBlock(getExtent()));
}
@Override
public final boolean test(BlockState state) {
return state.getBlockType().getInternalId() == internalId;
}
@Override
public Mask inverse() {
return new BlockMaskBuilder().add(BlockTypes.get(internalId)).build(getExtent()).inverse();
return new InverseSingleBlockTypeMask(getExtent(), BlockTypes.values[internalId]);
}
public BlockType getBlockType() {

View File

@ -27,10 +27,10 @@ import com.sk89q.worldedit.world.block.BlockTypes;
import javax.annotation.Nullable;
public class SolidBlockMask extends BlockTypeMask {
public class SolidBlockMask extends BlockMask {
public SolidBlockMask(Extent extent) {
super(extent, getTypes());
super(extent);
add(state -> state.getMaterial().isSolid());
}
@Override

View File

@ -22,11 +22,7 @@ package com.sk89q.worldedit.function.visitor;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.example.MappedFaweQueue;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.HasFaweQueue;
import com.boydti.fawe.object.IntegerTrio;
import com.boydti.fawe.object.collection.BlockVectorSet;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.RegionFunction;
@ -38,8 +34,11 @@ import com.sk89q.worldedit.util.Direction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Performs a breadth-first search starting from points added with
* {@link #visit(BlockVector3)}. The search continues
@ -81,13 +80,12 @@ public abstract class BreadthFirstSearch implements Operation {
}
private final RegionFunction function;
private BlockVectorSet queue;
private BlockVector3[] directions;
private BlockVectorSet visited;
private BlockVectorSet queue;
private int affected = 0;
private int currentDepth = 0;
private final int maxDepth;
private List<BlockVector3> directions = new ArrayList<>();
private final MappedFaweQueue mFaweQueue;
private int maxBranch = Integer.MAX_VALUE;
/**
@ -101,33 +99,20 @@ public abstract class BreadthFirstSearch implements Operation {
}
public BreadthFirstSearch(RegionFunction function, int maxDepth) {
this(function, maxDepth, null);
checkNotNull(function);
}
public BreadthFirstSearch(RegionFunction function, int maxDepth, HasFaweQueue faweQueue) {
checkNotNull(function);
FaweQueue fq = faweQueue != null ? faweQueue.getQueue() : null;
this.mFaweQueue = fq instanceof MappedFaweQueue ? (MappedFaweQueue) fq : null;
this.queue = new BlockVectorSet();
this.visited = new BlockVectorSet();
this.function = function;
this.directions.addAll(Arrays.asList(DEFAULT_DIRECTIONS));
this.directions = DEFAULT_DIRECTIONS;
this.maxDepth = maxDepth;
}
public void setDirections(List<BlockVector3> directions) {
public void setDirections(BlockVector3... directions) {
this.directions = directions;
}
private IntegerTrio[] getIntDirections() {
IntegerTrio[] array = new IntegerTrio[directions.size()];
for (int i = 0; i < array.length; i++) {
BlockVector3 dir = directions.get(i);
array[i] = new IntegerTrio(dir.getBlockX(), dir.getBlockY(), dir.getBlockZ());
}
return array;
public void setDirections(Collection<BlockVector3> directions) {
setDirections(directions.toArray(new BlockVector3[0]));
}
/**
@ -138,34 +123,36 @@ public abstract class BreadthFirstSearch implements Operation {
* unit vectors. An example of a valid direction is
* {@code BlockVector3.at(1, 0, 1)}.</p>
*
* <p>The list of directions can be cleared.</p>
*
* @return the list of directions
*/
protected Collection<BlockVector3> getDirections() {
return directions;
public Collection<BlockVector3> getDirections() {
return Arrays.asList(directions);
}
/**
* Add the directions along the axes as directions to visit.
*/
protected void addAxes() {
directions.add(BlockVector3.UNIT_MINUS_Y);
directions.add(BlockVector3.UNIT_Y);
directions.add(BlockVector3.UNIT_MINUS_X);
directions.add(BlockVector3.UNIT_X);
directions.add(BlockVector3.UNIT_MINUS_Z);
directions.add(BlockVector3.UNIT_Z);
public void addAxes() {
HashSet<BlockVector3> set = new HashSet<>(Arrays.asList(directions));
set.add(BlockVector3.UNIT_MINUS_Y);
set.add(BlockVector3.UNIT_Y);
set.add(BlockVector3.UNIT_MINUS_X);
set.add(BlockVector3.UNIT_X);
set.add(BlockVector3.UNIT_MINUS_Z);
set.add(BlockVector3.UNIT_Z);
setDirections(set);
}
/**
* Add the diagonal directions as directions to visit.
*/
protected void addDiagonal() {
directions.add(Direction.NORTHEAST.toBlockVector());
directions.add(Direction.SOUTHEAST.toBlockVector());
directions.add(Direction.SOUTHWEST.toBlockVector());
directions.add(Direction.NORTHWEST.toBlockVector());
public void addDiagonal() {
HashSet<BlockVector3> set = new HashSet<>(Arrays.asList(directions));
set.add(Direction.NORTHEAST.toBlockVector());
set.add(Direction.SOUTHEAST.toBlockVector());
set.add(Direction.SOUTHWEST.toBlockVector());
set.add(Direction.NORTHWEST.toBlockVector());
setDirections(set);
}
/**
@ -206,21 +193,6 @@ public abstract class BreadthFirstSearch implements Operation {
public void setMaxBranch(int maxBranch) {
this.maxBranch = maxBranch;
}
/**
* Try to visit the given 'to' location.
*
* @param from the origin block
* @param to the block under question
*/
private void visit(BlockVector3 from, BlockVector3 to) {
BlockVector3 blockVector = to;
if (!visited.contains(blockVector)) {
visited.add(blockVector);
if (isVisitable(from, to)) {
queue.add(blockVector);
}
}
}
/**
* Return whether the given 'to' block should be visited, starting from the
@ -244,42 +216,22 @@ public abstract class BreadthFirstSearch implements Operation {
@Override
public Operation resume(RunContext run) throws WorldEditException {
MutableBlockVector3 mutable = new MutableBlockVector3();
IntegerTrio[] dirs = getIntDirections();
// MutableBlockVector3 mutable2 = new MutableBlockVector3();
boolean shouldTrim = false;
BlockVector3[] dirs = directions;
BlockVectorSet tempQueue = new BlockVectorSet();
BlockVectorSet chunkLoadSet = new BlockVectorSet();
for (currentDepth = 0; !queue.isEmpty() && currentDepth <= maxDepth; currentDepth++) {
if (mFaweQueue != null && Settings.IMP.QUEUE.PRELOAD_CHUNKS > 1) {
int cx = Integer.MIN_VALUE;
int cz = Integer.MIN_VALUE;
for (BlockVector3 from : queue) {
for (IntegerTrio direction : dirs) {
int x = from.getBlockX() + direction.x;
int z = from.getBlockZ() + direction.z;
if (cx != (cx = x >> 4) || cz != (cz = z >> 4)) {
int y = from.getBlockY() + direction.y;
if (y < 0 || y >= 256) {
continue;
}
if (!visited.contains(x, y, z)) {
chunkLoadSet.add(cx, 0, cz);
}
}
}
}
for (BlockVector3 chunk : chunkLoadSet) {
mFaweQueue.queueChunkLoad(chunk.getBlockX(), chunk.getBlockZ());
}
}
for (BlockVector3 from : queue) {
if (function.apply(from)) affected++;
for (int i = 0, j = 0; i < dirs.length && j < maxBranch; i++) {
IntegerTrio direction = dirs[i];
int y = from.getBlockY() + direction.y;
BlockVector3 direction = dirs[i];
int y = from.getBlockY() + direction.getY();
if (y < 0 || y >= 256) {
continue;
}
int x = from.getBlockX() + direction.x;
int z = from.getBlockZ() + direction.z;
int x = from.getBlockX() + direction.getX();
int z = from.getBlockZ() + direction.getZ();
if (!visited.contains(x, y, z)) {
if (isVisitable(from, mutable.setComponents(x, y, z))) {
j++;

View File

@ -21,30 +21,36 @@ package com.sk89q.worldedit.math;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.collect.ComparisonChain;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import java.util.Comparator;
/**
* An immutable 3-dimensional vector.
*/
public class BlockVector3 {
public abstract class BlockVector3 {
public static final BlockVector3 ZERO = new BlockVector3(0, 0, 0);
public static final BlockVector3 UNIT_X = new BlockVector3(1, 0, 0);
public static final BlockVector3 UNIT_Y = new BlockVector3(0, 1, 0);
public static final BlockVector3 UNIT_Z = new BlockVector3(0, 0, 1);
public static final BlockVector3 UNIT_MINUS_X = new BlockVector3(-1, 0, 0);
public static final BlockVector3 UNIT_MINUS_Y = new BlockVector3(0, -1, 0);
public static final BlockVector3 UNIT_MINUS_Z = new BlockVector3(0, 0, -1);
public static final BlockVector3 ONE = new BlockVector3(1, 1, 1);
public static final BlockVector3 ZERO = BlockVector3.at(0, 0, 0);
public static final BlockVector3 UNIT_X = BlockVector3.at(1, 0, 0);
public static final BlockVector3 UNIT_Y = BlockVector3.at(0, 1, 0);
public static final BlockVector3 UNIT_Z = BlockVector3.at(0, 0, 1);
public static final BlockVector3 UNIT_MINUS_X = BlockVector3.at(-1, 0, 0);
public static final BlockVector3 UNIT_MINUS_Y = BlockVector3.at(0, -1, 0);
public static final BlockVector3 UNIT_MINUS_Z = BlockVector3.at(0, 0, -1);
public static final BlockVector3 ONE = BlockVector3.at(1, 1, 1);
public static BlockVector3 at(double x, double y, double z) {
return at((int) Math.floor(x), (int) Math.floor(y), (int) Math.floor(z));
}
public static BlockVector3 at(int x, int y, int z) {
return new BlockVector3(x, y, z);
return new BlockVector3Imp(x, y, z);
}
// thread-safe initialization idiom
@ -65,23 +71,6 @@ public class BlockVector3 {
return YzxOrderComparator.YZX_ORDER;
}
protected int x, y, z;
protected BlockVector3(){}
/**
* Construct an instance.
*
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
*/
protected BlockVector3(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public MutableBlockVector3 setComponents(double x, double y, double z) {
return new MutableBlockVector3((int) x, (int) y, (int) z);
}
@ -91,37 +80,71 @@ public class BlockVector3 {
}
public MutableBlockVector3 mutX(double x) {
return new MutableBlockVector3((int) x, y, z);
return new MutableBlockVector3((int) x, getY(), getZ());
}
public MutableBlockVector3 mutY(double y) {
return new MutableBlockVector3(x, (int) y, z);
return new MutableBlockVector3(getX(), (int) y, getZ());
}
public MutableBlockVector3 mutZ(double z) {
return new MutableBlockVector3(x, y, (int) z);
return new MutableBlockVector3(getX(), getY(), (int) z);
}
public MutableBlockVector3 mutX(int x) {
return new MutableBlockVector3(x, y, z);
return new MutableBlockVector3(x, getY(), getZ());
}
public MutableBlockVector3 mutY(int y) {
return new MutableBlockVector3(x, y, z);
return new MutableBlockVector3(getX(), y, getZ());
}
public MutableBlockVector3 mutZ(int z) {
return new MutableBlockVector3(x, y, z);
return new MutableBlockVector3(getX(), getY(), z);
}
public BlockVector3 toImmutable() {
return BlockVector3.at(getX(), getY(), getZ());
}
// /**
// * Get the BlockVector3 to the north<br>
// * Normal use you would use north(this),
// * To avoid constructing a new Vector, pass e.g. north(some MutableBlockVector3)
// * There is no gaurantee it will use this provided vector
// * @param orDefault the vector to use as the result<br>
// * @return BlockVector3
// */
// public BlockVector3 north(BlockVector3 orDefault) {
// return orDefault.setComponents(getX(), getY(), getZ() - 1);
// }
//
// public BlockVector3 east(BlockVector3 orDefault) {
// return orDefault.setComponents(getX() + 1, getY(), getZ());
// }
//
// public BlockVector3 south(BlockVector3 orDefault) {
// return orDefault.setComponents(getX(), getY(), getZ() + 1);
// }
//
// public BlockVector3 west(BlockVector3 orDefault) {
// return orDefault.setComponents(getX() - 1, getY(), getZ());
// }
//
// public BlockVector3 up(BlockVector3 orDefault) {
// return orDefault.setComponents(getX(), getY() + 1, getZ());
// }
//
// public BlockVector3 down(BlockVector3 orDefault) {
// return orDefault.setComponents(getX(), getY() - 1, getZ());
// }
/**
* Get the X coordinate.
*
* @return the x coordinate
*/
public int getX() {
return x;
}
public abstract int getX();
/**
* Get the X coordinate.
@ -129,7 +152,7 @@ public class BlockVector3 {
* @return the x coordinate
*/
public int getBlockX() {
return x;
return getX();
}
/**
@ -139,7 +162,7 @@ public class BlockVector3 {
* @return a new vector
*/
public BlockVector3 withX(int x) {
return BlockVector3.at(x, y, z);
return BlockVector3.at(x, getY(), getZ());
}
/**
@ -147,9 +170,7 @@ public class BlockVector3 {
*
* @return the y coordinate
*/
public int getY() {
return y;
}
public abstract int getY();
/**
* Get the Y coordinate.
@ -157,7 +178,7 @@ public class BlockVector3 {
* @return the y coordinate
*/
public int getBlockY() {
return y;
return getY();
}
/**
@ -167,7 +188,7 @@ public class BlockVector3 {
* @return a new vector
*/
public BlockVector3 withY(int y) {
return BlockVector3.at(x, y, z);
return BlockVector3.at(getX(), y, getZ());
}
/**
@ -175,9 +196,7 @@ public class BlockVector3 {
*
* @return the z coordinate
*/
public int getZ() {
return z;
}
public abstract int getZ();
/**
* Get the Z coordinate.
@ -185,7 +204,7 @@ public class BlockVector3 {
* @return the z coordinate
*/
public int getBlockZ() {
return z;
return getZ();
}
/**
@ -195,7 +214,7 @@ public class BlockVector3 {
* @return a new vector
*/
public BlockVector3 withZ(int z) {
return BlockVector3.at(x, y, z);
return BlockVector3.at(getX(), getY(), z);
}
/**
@ -205,7 +224,7 @@ public class BlockVector3 {
* @return a new vector
*/
public BlockVector3 add(BlockVector3 other) {
return add(other.x, other.y, other.z);
return add(other.getX(), other.getY(), other.getZ());
}
/**
@ -217,7 +236,7 @@ public class BlockVector3 {
* @return a new vector
*/
public BlockVector3 add(int x, int y, int z) {
return BlockVector3.at(this.x + x, this.y + y, this.z + z);
return BlockVector3.at(this.getX() + x, this.getY() + y, this.getZ() + z);
}
/**
@ -228,12 +247,12 @@ public class BlockVector3 {
* @return a new vector
*/
public BlockVector3 add(BlockVector3... others) {
int newX = x, newY = y, newZ = z;
int newX = getX(), newY = getY(), newZ = getZ();
for (BlockVector3 other : others) {
newX += other.x;
newY += other.y;
newZ += other.z;
newX += other.getX();
newY += other.getY();
newZ += other.getZ();
}
return BlockVector3.at(newX, newY, newZ);
@ -247,7 +266,7 @@ public class BlockVector3 {
* @return a new vector
*/
public BlockVector3 subtract(BlockVector3 other) {
return subtract(other.x, other.y, other.z);
return subtract(other.getX(), other.getY(), other.getZ());
}
/**
@ -260,7 +279,7 @@ public class BlockVector3 {
* @return a new vector
*/
public BlockVector3 subtract(int x, int y, int z) {
return BlockVector3.at(this.x - x, this.y - y, this.z - z);
return BlockVector3.at(this.getX() - x, this.getY() - y, this.getZ() - z);
}
/**
@ -271,12 +290,12 @@ public class BlockVector3 {
* @return a new vector
*/
public BlockVector3 subtract(BlockVector3... others) {
int newX = x, newY = y, newZ = z;
int newX = getX(), newY = getY(), newZ = getZ();
for (BlockVector3 other : others) {
newX -= other.x;
newY -= other.y;
newZ -= other.z;
newX -= other.getX();
newY -= other.getY();
newZ -= other.getZ();
}
return BlockVector3.at(newX, newY, newZ);
@ -289,7 +308,7 @@ public class BlockVector3 {
* @return a new vector
*/
public BlockVector3 multiply(BlockVector3 other) {
return multiply(other.x, other.y, other.z);
return multiply(other.getX(), other.getY(), other.getZ());
}
/**
@ -301,7 +320,7 @@ public class BlockVector3 {
* @return a new vector
*/
public BlockVector3 multiply(int x, int y, int z) {
return BlockVector3.at(this.x * x, this.y * y, this.z * z);
return BlockVector3.at(this.getX() * x, this.getY() * y, this.getZ() * z);
}
/**
@ -311,12 +330,12 @@ public class BlockVector3 {
* @return a new vector
*/
public BlockVector3 multiply(BlockVector3... others) {
int newX = x, newY = y, newZ = z;
int newX = getX(), newY = getY(), newZ = getZ();
for (BlockVector3 other : others) {
newX *= other.x;
newY *= other.y;
newZ *= other.z;
newX *= other.getX();
newY *= other.getY();
newZ *= other.getZ();
}
return BlockVector3.at(newX, newY, newZ);
@ -339,7 +358,7 @@ public class BlockVector3 {
* @return a new vector
*/
public BlockVector3 divide(BlockVector3 other) {
return divide(other.x, other.y, other.z);
return divide(other.getX(), other.getY(), other.getZ());
}
/**
@ -351,7 +370,7 @@ public class BlockVector3 {
* @return a new vector
*/
public BlockVector3 divide(int x, int y, int z) {
return BlockVector3.at(this.x / x, this.y / y, this.z / z);
return BlockVector3.at(this.getX() / x, this.getY() / y, this.getZ() / z);
}
/**
@ -423,7 +442,7 @@ public class BlockVector3 {
* @return length, squared
*/
public int lengthSq() {
return x * x + y * y + z * z;
return getX() * getX() + getY() * getY() + getZ() * getZ();
}
/**
@ -443,9 +462,9 @@ public class BlockVector3 {
* @return distance
*/
public int distanceSq(BlockVector3 other) {
int dx = other.x - x;
int dy = other.y - y;
int dz = other.z - z;
int dx = other.getX() - getX();
int dy = other.getY() - getY();
int dz = other.getZ() - getZ();
return dx * dx + dy * dy + dz * dz;
}
@ -457,9 +476,9 @@ public class BlockVector3 {
*/
public BlockVector3 normalize() {
double len = length();
double x = this.x / len;
double y = this.y / len;
double z = this.z / len;
double x = this.getX() / len;
double y = this.getY() / len;
double z = this.getZ() / len;
return BlockVector3.at(x, y, z);
}
@ -470,7 +489,7 @@ public class BlockVector3 {
* @return the dot product of this and the other vector
*/
public double dot(BlockVector3 other) {
return x * other.x + y * other.y + z * other.z;
return getX() * other.getX() + getY() * other.getY() + getZ() * other.getZ();
}
/**
@ -480,10 +499,10 @@ public class BlockVector3 {
* @return the cross product of this and the other vector
*/
public BlockVector3 cross(BlockVector3 other) {
return new BlockVector3(
y * other.z - z * other.y,
z * other.x - x * other.z,
x * other.y - y * other.x
return new BlockVector3Imp(
getY() * other.getZ() - getZ() * other.getY(),
getZ() * other.getX() - getX() * other.getZ(),
getX() * other.getY() - getY() * other.getX()
);
}
@ -495,7 +514,7 @@ public class BlockVector3 {
* @return true if the vector is contained
*/
public boolean containedWithin(BlockVector3 min, BlockVector3 max) {
return x >= min.x && x <= max.x && y >= min.y && y <= max.y && z >= min.z && z <= max.z;
return getX() >= min.getX() && getX() <= max.getX() && getY() >= min.getY() && getY() <= max.getY() && getZ() >= min.getZ() && getZ() <= max.getZ();
}
/**
@ -507,11 +526,11 @@ public class BlockVector3 {
*/
public BlockVector3 clampY(int min, int max) {
checkArgument(min <= max, "minimum cannot be greater than maximum");
if (y < min) {
return BlockVector3.at(x, min, z);
if (getY() < min) {
return BlockVector3.at(getX(), min, getZ());
}
if (y > max) {
return BlockVector3.at(x, max, z);
if (getY() > max) {
return BlockVector3.at(getX(), max, getZ());
}
return this;
}
@ -555,7 +574,7 @@ public class BlockVector3 {
* @return a new vector
*/
public BlockVector3 abs() {
return BlockVector3.at(Math.abs(x), Math.abs(y), Math.abs(z));
return BlockVector3.at(Math.abs(getX()), Math.abs(getY()), Math.abs(getZ()));
}
/**
@ -571,8 +590,8 @@ public class BlockVector3 {
*/
public BlockVector3 transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) {
angle = Math.toRadians(angle);
double x = this.x - aboutX;
double z = this.z - aboutZ;
double x = this.getX() - aboutX;
double z = this.getZ() - aboutZ;
double cos = Math.cos(angle);
double sin = Math.sin(angle);
double x2 = x * cos - z * sin;
@ -580,7 +599,7 @@ public class BlockVector3 {
return BlockVector3.at(
x2 + aboutX + translateX,
y,
getY(),
z2 + aboutZ + translateZ
);
}
@ -626,10 +645,10 @@ public class BlockVector3 {
* @return minimum
*/
public BlockVector3 getMinimum(BlockVector3 v2) {
return new BlockVector3(
Math.min(x, v2.x),
Math.min(y, v2.y),
Math.min(z, v2.z)
return new BlockVector3Imp(
Math.min(getX(), v2.getX()),
Math.min(getY(), v2.getY()),
Math.min(getZ(), v2.getZ())
);
}
@ -640,44 +659,110 @@ public class BlockVector3 {
* @return maximum
*/
public BlockVector3 getMaximum(BlockVector3 v2) {
return new BlockVector3(
Math.max(x, v2.x),
Math.max(y, v2.y),
Math.max(z, v2.z)
return new BlockVector3Imp(
Math.max(getX(), v2.getX()),
Math.max(getY(), v2.getY()),
Math.max(getZ(), v2.getZ())
);
}
/*
Methods for getting/setting blocks
Why are these methods here?
- Getting a block at a position requires various operations
(bounds checks, cache checks, ensuring loaded chunk, get ChunkSection, etc.)
- When iterating over a region, it will provide custom BlockVector3 positions
- These override the below set/get and avoid lookups (as the iterator shifts it to the chunk level)
*/
public boolean setOrdinal(Extent orDefault, int ordinal) {
return orDefault.setBlock(this, BlockState.getFromOrdinal(ordinal));
}
public boolean setBlock(Extent orDefault, BlockState state) {
return orDefault.setBlock(this, state);
}
public boolean setFullBlock(Extent orDefault, BaseBlock block) {
return orDefault.setBlock(this, block);
}
public boolean setBiome(Extent orDefault, BiomeType biome) {
return orDefault.setBiome(getX(), getY(), getZ(), biome);
}
public int getOrdinal(Extent orDefault) {
return getBlock(orDefault).getOrdinal();
}
public char getOrdinalChar(Extent orDefault) {
return (char) getOrdinal(orDefault);
}
public BlockState getBlock(Extent orDefault) {
return orDefault.getBlock(this);
}
public BaseBlock getFullBlock(Extent orDefault) {
return orDefault.getFullBlock(this);
}
public CompoundTag getNbtData(Extent orDefault) {
return orDefault.getFullBlock(getX(), getY(), getZ()).getNbtData();
}
public BlockState getOrdinalBelow(Extent orDefault) {
return orDefault.getBlock(getX(), getY() - 1, getZ());
}
public BlockState getStateAbove(Extent orDefault) {
return orDefault.getBlock(getX(), getY() + 1, getZ());
}
public BlockState getStateRelativeY(Extent orDefault, final int y) {
return orDefault.getBlock(getX(), getY() + y, getZ());
}
/*
Adapt
*/
/**
* Creates a 2D vector by dropping the Y component from this vector.
*
* @return a new {@link BlockVector2}
*/
public BlockVector2 toBlockVector2() {
return BlockVector2.at(x, z);
return BlockVector2.at(getX(), getZ());
}
public Vector3 toVector3() {
return Vector3.at(x, y, z);
return Vector3.at(getX(), getY(), getZ());
}
@Override
public boolean equals(Object obj) {
public final boolean equals(Object obj) {
if (!(obj instanceof BlockVector3)) {
return false;
}
BlockVector3 other = (BlockVector3) obj;
return other.x == this.x && other.y == this.y && other.z == this.z;
return equals((BlockVector3) obj);
}
public final boolean equals(BlockVector3 other) {
return other.getX() == this.getX() && other.getY() == this.getY() && other.getZ() == this.getZ();
}
@Override
public int hashCode() {
return (x ^ (z << 12)) ^ (y << 24);
return (getX() ^ (getZ() << 12)) ^ (getY() << 24);
}
@Override
public String toString() {
return "(" + x + ", " + y + ", " + z + ")";
return "(" + getX() + ", " + getY() + ", " + getZ() + ")";
}
}

View File

@ -1,9 +1,18 @@
package com.sk89q.worldedit.math;
import com.boydti.fawe.FaweCache;
public class MutableVector3 extends Vector3 {
public MutableVector3() {
}
public static MutableVector3 get(int x, int y, int z) {
return FaweCache.MUTABLE_VECTOR3.get().setComponents(x, y, z);
}
public static MutableVector3 get(double x, double y, double z) {
return FaweCache.MUTABLE_VECTOR3.get().setComponents(x, y, z);
}
public MutableVector3(double x, double y, double z) {
super(x, y, z);
@ -77,7 +86,4 @@ public class MutableVector3 extends Vector3 {
return this;
}
public double getY() {
return y;
}
}

View File

@ -22,6 +22,11 @@ package com.sk89q.worldedit.regions;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.beta.ChunkFilterBlock;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.collection.BlockVectorSet;
import com.sk89q.worldedit.math.BlockVector2;
@ -387,7 +392,6 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
return chunks;
}
@Override
public boolean contains(int x, int y, int z) {
return x >= this.minX && x <= this.maxX && z >= this.minZ && z <= this.maxZ && y >= this.minY && y <= this.maxY;
@ -398,14 +402,6 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
return x >= this.minX && x <= this.maxX && z >= this.minZ && z <= this.maxZ;
}
@Override
public boolean contains(BlockVector3 position) {
BlockVector3 min = getMinimumPoint();
BlockVector3 max = getMaximumPoint();
return position.containedWithin(min, max);
}
@Override
public Iterator<BlockVector3> iterator() {
if (Settings.IMP.HISTORY.COMPRESSION_LEVEL >= 9 || useOldIterator) {
@ -610,4 +606,51 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
BlockVector3 size = BlockVector3.ONE.multiply(apothem);
return new CuboidRegion(origin.subtract(size), origin.add(size));
}
@Override
public int getMinY() {
return minY;
}
@Override
public int getMaxY() {
return maxY;
}
@Override
public void filter(final IChunk chunk, final Filter filter, ChunkFilterBlock block, final IChunkGet get, final IChunkSet set) {
int X = chunk.getX();
int Z = chunk.getZ();
block = block.init(X, Z, get);
if ((minX + 15) >> 4 <= X && (maxX - 15) >> 4 >= X && (minZ + 15) >> 4 <= Z && (maxZ - 15) >> 4 >= Z) {
filter(chunk, filter, block, get, set, minY, maxY);
return;
}
int localMinX = Math.max(minX, X << 4) & 15;
int localMaxX = Math.min(maxX, 15 + X << 4) & 15;
int localMinZ = Math.max(minZ, Z << 4) & 15;
int localMaxZ = Math.min(maxZ, 15 + Z << 4) & 15;
int yStart = (minY & 15);
int yEnd = (maxY & 15);
int minSection = minY >> 4;
int maxSection = maxY >> 4;
if (minSection == maxSection) {
filter(chunk, filter, block, get, set, minSection, localMinX, yStart, localMinZ, localMaxX, yEnd, localMaxZ);
return;
}
if (yStart != 0) {
filter(chunk, filter, block, get, set, minSection, localMinX, yStart, localMinZ, localMaxX, 15, localMaxZ);
minSection++;
}
if (yEnd != 15) {
filter(chunk, filter, block, get, set, minSection, localMinX, 0, localMinZ, localMaxX, 15, localMaxZ);
maxSection--;
}
for (int layer = minSection; layer < maxSection; layer++) {
filter(chunk, filter, block, get, set, layer, localMinX, yStart, localMinZ, localMaxX, yEnd, localMaxZ);
}
}
}

View File

@ -21,6 +21,11 @@ package com.sk89q.worldedit.regions;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.beta.ChunkFilterBlock;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
@ -288,26 +293,22 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
minY += changeY;
}
/**
* Checks to see if a point is inside this region.
*/
@Override
public boolean contains(BlockVector3 position) {
final int blockY = position.getBlockY();
if (blockY < minY || blockY > maxY) {
public boolean contains(int x, int y, int z) {
if (y < minY || y > maxY) {
return false;
}
//todo the following lines can possibly be removed and replaced with upstream
int px = position.getBlockX();
int pz = position.getBlockZ();
return contains(x, z);
}
double dx = Math.abs(px - center.getBlockX()) * radiusInverse.getX();
double dz = Math.abs(pz - center.getBlockZ()) * radiusInverse.getZ();
@Override
public boolean contains(int x, int z) {
double dx = Math.abs(x - center.getBlockX()) * radiusInverse.getX();
double dz = Math.abs(z - center.getBlockZ()) * radiusInverse.getZ();
return dx * dx + dz * dz <= 1;
}
/**
* Sets the height of the cylinder to fit the specified Y.
*
@ -362,6 +363,16 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
return Polygons.polygonizeCylinder(center, radius, maxPoints);
}
@Override
public int getMinY() {
return minY;
}
@Override
public int getMaxY() {
return maxY;
}
/**
* Return a new instance with the given center and radius in the X and Z
* axes with a Y that extends from the bottom of the extent to the top
@ -381,4 +392,16 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
return new CylinderRegion(center, radiusVec, minY, maxY);
}
@Override
public void filter(final IChunk chunk, final Filter filter, final ChunkFilterBlock block, final IChunkGet get, final IChunkSet set) {
int bcx = chunk.getX() >> 4;
int bcz = chunk.getZ() >> 4;
int tcx = bcx + 15;
int tcz = bcz + 15;
if (contains(bcx, bcz) && contains(tcx, tcz)) {
filter(chunk, filter, block, get, set, minY, maxY);
return;
}
super.filter(chunk, filter, block, get, set);
}
}

View File

@ -19,6 +19,13 @@
package com.sk89q.worldedit.regions;
import com.boydti.fawe.beta.ChunkFilterBlock;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.util.MathMan;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
@ -44,6 +51,7 @@ public class EllipsoidRegion extends AbstractRegion {
private Vector3 radius;
private Vector3 radiusSqr;
private Vector3 inverseRadius;
private int radiusLengthSqr;
private boolean sphere;
@ -180,6 +188,12 @@ public class EllipsoidRegion extends AbstractRegion {
radiusSqr = radius.multiply(radius);
radiusLengthSqr = (int) radiusSqr.getX();
this.sphere = radius.getY() == radius.getX() && radius.getX() == radius.getZ();
if (radius.getY() == radius.getX() && radius.getX() == radius.getZ()) {
this.sphere = true;
} else {
this.sphere = false;
}
inverseRadius = Vector3.ONE.divide(radius);
}
@Override
@ -206,30 +220,50 @@ public class EllipsoidRegion extends AbstractRegion {
return chunks;
}
@Override
public boolean contains(int x, int y, int z) {
int cx = x - center.getBlockX();
int cx2 = cx * cx;
if (cx2 > radiusSqr.getBlockX()) {
return false;
}
int cz = z - center.getBlockZ();
int cz2 = cz * cz;
if (cz2 > radiusSqr.getBlockZ()) {
return false;
}
int cy = y - center.getBlockY();
int cy2 = cy * cy;
if (radiusSqr.getBlockY() < 255 && cy2 > radiusSqr.getBlockY()) {
return false;
}
if (sphere) {
return cx2 + cy2 + cz2 <= radiusLengthSqr;
}
double cxd = cx2 * inverseRadius.getX();
double cyd = cy2 * inverseRadius.getY();
double czd = cz2 * inverseRadius.getZ();
return cxd + cyd + czd <= 1;
}
@Override
public boolean contains(BlockVector3 position) {
int cx = position.getBlockX() - center.getBlockX();
public boolean contains(int x, int z) {
int cx = x - center.getBlockX();
int cx2 = cx * cx;
if (cx2 > radiusSqr.getBlockX()) {
return false;
}
int cz = position.getBlockZ() - center.getBlockZ();
int cz = z - center.getBlockZ();
int cz2 = cz * cz;
if (cz2 > radiusSqr.getBlockZ()) {
return false;
}
int cy = position.getBlockY() - center.getBlockY();
int cy2 = cy * cy;
if (radiusSqr.getBlockY() < 255 && cy2 > radiusSqr.getBlockY()) {
return false;
}
if (sphere) {
return cx2 + cy2 + cz2 <= radiusLengthSqr;
return cx2 + cz2 <= radiusLengthSqr;
}
double cxd = (double) cx / radius.getBlockX();
double cyd = (double) cy / radius.getBlockY();
double czd = (double) cz / radius.getBlockZ();
return cxd * cxd + cyd * cyd + czd * czd <= 1;
double cxd = cx2 * inverseRadius.getX();
double czd = cz2 * inverseRadius.getZ();
return cxd + czd <= 1;
}
/**
@ -252,4 +286,113 @@ public class EllipsoidRegion extends AbstractRegion {
return (EllipsoidRegion) super.clone();
}
private void filterSpherePartial(int y1, int y2, int bx, int bz, Filter filter, ChunkFilterBlock block, IChunkGet get, IChunkSet set) {
int sectionStart = y1 >> 4;
int sectionEnd = y2 >> 4;
}
private void filterSpherePartial(int layer, int y1, int y2, int bx, int bz, Filter filter, ChunkFilterBlock block, IChunkGet get, IChunkSet set) {
int cx = center.getBlockX();
int cy = center.getBlockY();
int cz = center.getBlockZ();
block.init(get, set, layer);
int by = layer << 4;
int diffY;
for (int y = y1, yy = by + y1; y <= y2; y++, yy++) {
diffY = cy - yy;
int remainderY = radiusLengthSqr - (diffY * diffY);
if (remainderY >= 0) {
for (int z = 0; z < 16; z++) {
int zz = z + bz;
int diffZ = cz - zz;
int remainderZ = remainderY - (diffZ * diffZ);
if (remainderZ >= 0) {
int diffX = MathMan.usqrt(remainderZ);
int minX = Math.max(0, cx - diffX - bx);
int maxX = Math.min(15, cx + diffX - bx);
if (minX != maxX) {
block.filter(filter, minX, y, z, maxX, y, z);
}
}
}
}
}
}
@Override
public void filter(IChunk chunk, Filter filter, ChunkFilterBlock block, IChunkGet get, IChunkSet set) {
// Check bounds
// This needs to be able to perform 50M blocks/sec otherwise it becomes a bottleneck
int cx = center.getBlockX();
int cz = center.getBlockZ();
int bx = chunk.getX() << 4;
int bz = chunk.getZ() << 4;
int tx = bx + 15;
int tz = bz + 15;
int cx1 = bx - cx;
int cx2 = tx - cx;
int cxMax, cxMin;
if (cx1 < cx2) {
cxMin = cx1;
cxMax = cx2;
} else {
cxMin = cx2;
cxMax = cx1;
}
int cxMin2 = cxMin * cxMin;
int cxMax2 = cxMax * cxMax;
int cz1 = bz - cz;
int cz2 = tz - cz;
int czMax, czMin;
if (cz1 < cz2) {
czMin = cz1;
czMax = cz2;
} else {
czMin = cz2;
czMax = cz1;
}
int czMin2 = czMin * czMin;
int czMax2 = czMax * czMax;
if (sphere) {
// Does not contain chunk
if (cxMin2 + czMin2 >= radiusLengthSqr) {
return;
}
int diffY2 = radiusLengthSqr - cxMax2 - czMax2;
// (shortcut) Contains all of certain layers
if (diffY2 >= 0) {
// Get the solid layers
int cy = center.getBlockY();
int diffYFull = MathMan.usqrt(diffY2);
int yBotFull = Math.max(0, cy - diffYFull);
int yTopFull = Math.min(255, cy + diffYFull);
// Set those layers
filter(chunk, filter, block, get, set, yBotFull, yTopFull);
// Fill the remaining layers
if (yBotFull != 0 || yTopFull != 255) {
int diffYPartial = MathMan.usqrt(radiusLengthSqr - cxMin * cxMin - czMin * czMin);
if (yBotFull != 0) {
int yBotPartial = Math.max(0, cy - diffYPartial);
filterSpherePartial(yBotPartial, yBotFull - 1, bx, bz, filter, block, get, set);
}
if (yTopFull != 255) {
int yTopPartial = Math.min(255, cy + diffYPartial);
filterSpherePartial(yTopFull + 1, yTopPartial - 1, bx, bz, filter, block, get, set);
}
}
}
} else {
super.filter(chunk, filter, block, get, set); // TODO optimize non spheres
}
}
}

View File

@ -20,17 +20,16 @@
package com.sk89q.worldedit.world;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
@ -69,7 +68,7 @@ public abstract class AbstractWorld implements World {
@Override
public Mask createLiquidMask() {
return new BlockTypeMask(this, BlockTypes.LAVA, BlockTypes.WATER);
return new BlockMask(this).add(BlockTypes.LAVA, BlockTypes.WATER);
}
@Override
@ -96,11 +95,6 @@ public abstract class AbstractWorld implements World {
return false;
}
@Override
public BlockState getLazyBlock(BlockVector3 position) {
return getBlock(position);
}
@Override
public boolean queueBlockBreakEffect(Platform server, BlockVector3 position, BlockType blockType, double priority) {
if (taskId == -1) {

View File

@ -26,9 +26,8 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
@ -41,6 +40,7 @@ import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.weather.WeatherType;
import com.sk89q.worldedit.world.weather.WeatherTypes;
import javax.annotation.Nullable;
import java.nio.file.Path;
/**
* An abstract implementation of {@link World}.
@ -59,12 +59,16 @@ public interface SimpleWorld extends World {
@Override
default BaseBlock getFullBlock(BlockVector3 position) {
return getLazyBlock(position).toBaseBlock();
return getBlock(position).toBaseBlock();
}
@Override
<B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 pt, B block) throws WorldEditException;
@Nullable @Override default Path getStoragePath() {
return null;
}
@Override
default int getMaxY() {
return getMaximumPoint().getBlockY();
@ -72,7 +76,7 @@ public interface SimpleWorld extends World {
@Override
default Mask createLiquidMask() {
return new BlockTypeMask(this, BlockTypes.LAVA, BlockTypes.WATER);
return new BlockMask(this).add(BlockTypes.LAVA, BlockTypes.WATER);
}
@Override
@ -115,11 +119,6 @@ public interface SimpleWorld extends World {
return BlockVector3.at(30000000, 255, 30000000);
}
@Override
default @Nullable Operation commit() {
return null;
}
@Override
default boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 position) throws MaxChangedBlocksException {

View File

@ -26,6 +26,7 @@ import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.TileEntityBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.ABlockMask;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.registry.state.PropertyKey;
@ -47,8 +48,8 @@ import java.util.Objects;
*/
public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
private BlockState blockState;
@Nullable protected CompoundTag nbtData;
private final BlockState blockState;
private final CompoundTag nbtData;
@Deprecated
public BaseBlock() {
@ -71,6 +72,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
*/
public BaseBlock(BlockState blockState) {
this.blockState = blockState;
nbtData = null;
}
/**
@ -181,7 +183,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
@Override
public void setNbtData(@Nullable CompoundTag nbtData) {
this.nbtData = nbtData;
throw new UnsupportedOperationException("Immutable");
}
/**
@ -233,13 +235,19 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
}
@Override
public BaseBlock toBaseBlock() {
public final char getOrdinalChar() {
return blockState.getOrdinalChar();
}
@Override
public final BaseBlock toBaseBlock() {
return this;
}
@Override
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
return extent.setBlock(set, this);
set.setFullBlock(extent, this);
return true;
}
@Override
@ -280,7 +288,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
@Override
public int hashCode() {
return blockState.hashCode(); // stop changing this
return getOrdinal();
}
@Override
@ -291,5 +299,4 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
return blockState.getAsString();
// }
}
}

View File

@ -19,14 +19,11 @@
package com.sk89q.worldedit.world.block;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.collect.ImmutableList;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.SingleBlockTypeMask;
import com.sk89q.worldedit.function.pattern.FawePattern;
import com.sk89q.worldedit.math.BlockVector3;
@ -38,13 +35,16 @@ import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkArgument;
public class BlockType implements FawePattern, Keyed {
private final String id;
@ -173,10 +173,15 @@ public class BlockType implements FawePattern, Keyed {
*
* @return The default state
*/
public BlockState getDefaultState() {
public final BlockState getDefaultState() {
return this.settings.defaultState;
}
/**
* @Deprecated use a Mask instead
* @return
*/
@Deprecated
public FuzzyBlockState getFuzzyMatcher() {
return new FuzzyBlockState(this);
}
@ -288,7 +293,7 @@ public class BlockType implements FawePattern, Keyed {
@Override
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
return extent.setBlock(set, this.getDefaultState());
return set.setBlock(extent, getDefaultState());
}
@Override
@ -296,7 +301,11 @@ public class BlockType implements FawePattern, Keyed {
return this.getDefaultState().toBaseBlock();
}
public Mask toMask(Extent extent) {
public SingleBlockTypeMask toMask() {
return toMask(null);
}
public SingleBlockTypeMask toMask(Extent extent) {
return new SingleBlockTypeMask(extent, this);
}

View File

@ -24,6 +24,7 @@ import com.sk89q.worldedit.world.registry.LegacyMapper;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Optional;
import java.util.Locale;
public final class ItemTypes {
@ -914,7 +915,7 @@ public final class ItemTypes {
@Nullable
public static ItemType parse(String input) {
input = input.toLowerCase();
input = input.toLowerCase(Locale.ROOT);
if (!Character.isAlphabetic(input.charAt(0))) {
try {
ItemType legacy = LegacyMapper.getInstance().getItemFromLegacy(input);