diff --git a/build.gradle b/build.gradle
index ac4274c38..aa32d780a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,20 +8,19 @@ buildscript {
configurations.all {
resolutionStrategy {
- force 'com.google.guava:guava:21.0'
- force 'org.ow2.asm:asm:6.0_BETA'
+ force 'commons-io:commons-io:2.4'
}
}
dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.4'
- classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.7.5'
- classpath 'org.ajoberstar:gradle-git:1.7.2'
+ classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.8.1'
}
}
plugins {
id 'net.minecrell.licenser' version '0.4.1' apply false
+ id "org.ajoberstar.grgit" version "2.3.0"
}
apply plugin: 'java'
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
index 7872f45bc..a2d043d73 100644
--- a/config/checkstyle/checkstyle.xml
+++ b/config/checkstyle/checkstyle.xml
@@ -5,8 +5,9 @@
-
+
+
diff --git a/config/checkstyle/import-control.xml b/config/checkstyle/import-control.xml
index eedd07857..28ccad1e4 100644
--- a/config/checkstyle/import-control.xml
+++ b/config/checkstyle/import-control.xml
@@ -15,6 +15,7 @@
+
@@ -53,6 +54,7 @@
+
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 000000000..878bf1f7e
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,4 @@
+# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
+# This is required to provide enough memory for the Minecraft decompilation process.
+org.gradle.jvmargs=-Xmx3G
+org.gradle.daemon=false
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 29953ea14..0d4a95168 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index db93606ed..6cbc54326 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Mon Mar 25 18:59:14 EDT 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
diff --git a/worldedit-bukkit/build.gradle b/worldedit-bukkit/build.gradle
index acefe8c9b..a0214fa9b 100644
--- a/worldedit-bukkit/build.gradle
+++ b/worldedit-bukkit/build.gradle
@@ -4,14 +4,17 @@ apply plugin: 'maven'
repositories {
maven { url "https://hub.spigotmc.org/nexus/content/groups/public" }
+ maven { url "https://repo.codemc.org/repository/maven-public" }
+ maven { url 'https://papermc.io/repo/repository/maven-public/' }
}
dependencies {
compile project(':worldedit-core')
+
compile 'net.milkbowl.vault:VaultAPI:1.7'
compile 'com.sk89q:dummypermscompat:1.10'
compile 'com.destroystokyo.paper:paper-api:1.13.2-R0.1-SNAPSHOT'
- compile 'org.spigotmc:spigot:1.13.2-R0.1-SNAPSHOT'
+ compile 'org.slf4j:slf4j-jdk14:1.7.26'
testCompile 'org.mockito:mockito-core:1.9.0-rc1'
compile 'com.massivecraft:factions:2.8.0'
compile 'com.drtshock:factions:1.6.9.5'
@@ -77,7 +80,10 @@ task copyFiles {
shadowJar {
dependencies {
+ relocate "org.slf4j", "com.sk89q.worldedit.slf4j"
include(dependency(':worldedit-core'))
+ include(dependency('org.slf4j:slf4j-api'))
+ include(dependency("org.slf4j:slf4j-jdk14"))
}
archiveName = "${parent.name}-${project.name.replaceAll("worldedit-", "")}-${parent.version}.jar"
destinationDir = file '../target'
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/wepif/FlatFilePermissionsResolver.java b/worldedit-bukkit/src/main/java/com/sk89q/wepif/FlatFilePermissionsResolver.java
index 3f2324596..9b5229cf3 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/wepif/FlatFilePermissionsResolver.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/wepif/FlatFilePermissionsResolver.java
@@ -22,6 +22,8 @@ package com.sk89q.wepif;
import com.sk89q.util.yaml.YAMLProcessor;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.File;
@@ -32,12 +34,10 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
public class FlatFilePermissionsResolver implements PermissionsResolver {
- private static final Logger log = Logger.getLogger(FlatFilePermissionsResolver.class.getCanonicalName());
+ private static final Logger log = LoggerFactory.getLogger(FlatFilePermissionsResolver.class);
private Map> userPermissionsCache;
private Set defaultPermissionsCache;
@@ -98,7 +98,7 @@ public class FlatFilePermissionsResolver implements PermissionsResolver {
}
}
} catch (IOException e) {
- log.log(Level.WARNING, "Failed to load permissions", e);
+ log.warn("Failed to load permissions", e);
} finally {
try {
if (buff != null) {
@@ -164,7 +164,7 @@ public class FlatFilePermissionsResolver implements PermissionsResolver {
}
}
} catch (IOException e) {
- log.log(Level.WARNING, "Failed to load permissions", e);
+ log.warn("Failed to load permissions", e);
} finally {
try {
if (buff != null) {
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/wepif/NijiPermissionsResolver.java b/worldedit-bukkit/src/main/java/com/sk89q/wepif/NijiPermissionsResolver.java
index fe23bfa46..ef12e2ff4 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/wepif/NijiPermissionsResolver.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/wepif/NijiPermissionsResolver.java
@@ -28,13 +28,12 @@ import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class NijiPermissionsResolver implements PermissionsResolver {
- private static final Logger log = Logger.getLogger(NijiPermissionsResolver.class.getCanonicalName());
+ private static final Logger log = LoggerFactory.getLogger(NijiPermissionsResolver.class);
private Server server;
private Permissions api;
@@ -84,7 +83,7 @@ public class NijiPermissionsResolver implements PermissionsResolver {
return api.Security.permission(player, permission);
}
} catch (Throwable t) {
- log.log(Level.WARNING, "Failed to check permissions", t);
+ log.warn("Failed to check permissions", t);
return false;
}
}
@@ -98,7 +97,7 @@ public class NijiPermissionsResolver implements PermissionsResolver {
return api.getHandler().has(server.getPlayerExact(name), permission);
}
} catch (Throwable t) {
- log.log(Level.WARNING, "Failed to check permissions", t);
+ log.warn("Failed to check permissions", t);
return false;
}
}
@@ -115,7 +114,7 @@ public class NijiPermissionsResolver implements PermissionsResolver {
return api.Security.inGroup(name, group);
}
} catch (Throwable t) {
- log.log(Level.WARNING, "Failed to check groups", t);
+ log.warn("Failed to check groups", t);
return false;
}
}
@@ -139,7 +138,7 @@ public class NijiPermissionsResolver implements PermissionsResolver {
return groups;
}
} catch (Throwable t) {
- log.log(Level.WARNING, "Failed to get groups", t);
+ log.warn("Failed to get groups", t);
return new String[0];
}
}
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/wepif/PermissionsResolverManager.java b/worldedit-bukkit/src/main/java/com/sk89q/wepif/PermissionsResolverManager.java
index 4775d86c4..6514912a8 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/wepif/PermissionsResolverManager.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/wepif/PermissionsResolverManager.java
@@ -27,6 +27,8 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.plugin.Plugin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
@@ -35,8 +37,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
public class PermissionsResolverManager implements PermissionsResolver {
@@ -85,7 +85,7 @@ public class PermissionsResolverManager implements PermissionsResolver {
private Server server;
private PermissionsResolver permissionResolver;
private YAMLProcessor config;
- private Logger logger = Logger.getLogger(getClass().getCanonicalName());
+ private Logger logger = LoggerFactory.getLogger(getClass());
private List> enabledResolvers = new ArrayList<>();
@SuppressWarnings("unchecked")
@@ -119,7 +119,7 @@ public class PermissionsResolverManager implements PermissionsResolver {
break;
}
} catch (Throwable e) {
- logger.log(Level.WARNING, "Error in factory method for " + resolverClass.getSimpleName(), e);
+ logger.warn("Error in factory method for " + resolverClass.getSimpleName(), e);
continue;
}
}
@@ -195,14 +195,14 @@ public class PermissionsResolverManager implements PermissionsResolver {
try {
file.createNewFile();
} catch (IOException e) {
- logger.log(Level.WARNING, "Failed to create new configuration file", e);
+ logger.warn("Failed to create new configuration file", e);
}
}
config = new YAMLProcessor(file, false, YAMLFormat.EXTENDED);
try {
config.load();
} catch (IOException e) {
- logger.log(Level.WARNING, "Error loading WEPIF configuration", e);
+ logger.warn("Error loading WEPIF configuration", e);
}
List keys = config.getKeys(null);
config.setHeader(CONFIG_HEADER);
@@ -232,7 +232,7 @@ public class PermissionsResolverManager implements PermissionsResolver {
} catch (ClassNotFoundException e) {}
if (next == null || !PermissionsResolver.class.isAssignableFrom(next)) {
- logger.warning("WEPIF: Invalid or unknown class found in enabled resolvers: "
+ logger.warn("WEPIF: Invalid or unknown class found in enabled resolvers: "
+ nextName + ". Moving to disabled resolvers list.");
i.remove();
disabledResolvers.add(nextName);
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/wepif/VaultResolver.java b/worldedit-bukkit/src/main/java/com/sk89q/wepif/VaultResolver.java
index a97017ceb..a918d601a 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/wepif/VaultResolver.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/wepif/VaultResolver.java
@@ -35,6 +35,9 @@ public class VaultResolver implements PermissionsResolver {
return null;
}
RegisteredServiceProvider rsp = server.getServicesManager().getRegistration(Permission.class);
+ if (rsp == null) {
+ return null;
+ }
perms = rsp.getProvider();
if (perms == null) {
return null;
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java
index e68587283..a7dbf4b24 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java
@@ -19,15 +19,25 @@
package com.sk89q.worldedit.bukkit;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Function;
+import com.sk89q.worldedit.NotABlockException;
+import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.IBukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.SimpleBukkitAdapter;
import com.sk89q.worldedit.entity.Entity;
+import com.sk89q.worldedit.extension.input.InputParseException;
+import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.util.Location;
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.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
@@ -37,6 +47,7 @@ import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.item.ItemType;
import org.bukkit.Material;
+import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@@ -122,6 +133,26 @@ public enum BukkitAdapter {
return getAdapter().adapt(gameMode);
}
+ /**
+ * Create a WorldEdit BiomeType from a Bukkit one.
+ *
+ * @param biome Bukkit Biome
+ * @return WorldEdit BiomeType
+ */
+ public static BiomeType adapt(Biome biome) {
+ return getAdapter().adapt(biome);
+ }
+
+ public static Biome adapt(BiomeType biomeType) {
+ getAdapter().adapt(biomeType);
+ }
+
+ /**
+ * Create a WorldEdit EntityType from a Bukkit one.
+ *
+ * @param entityType Bukkit EntityType
+ * @return WorldEdit EntityType
+ */
public static EntityType adapt(org.bukkit.entity.EntityType entityType) {
return getAdapter().adapt(entityType);
}
@@ -146,6 +177,12 @@ public enum BukkitAdapter {
return getAdapter().adapt(material);
}
+ /**
+ * Create a Bukkit BlockData from a WorldEdit BlockStateHolder
+ *
+ * @param block The WorldEdit BlockStateHolder
+ * @return The Bukkit BlockData
+ */
public static > BlockData adapt(B block) {
return getAdapter().adapt(block);
}
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java
index cb0fea4de..27474678f 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java
@@ -19,16 +19,11 @@
package com.sk89q.worldedit.bukkit;
-import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
-import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.biome.BiomeData;
+import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import org.bukkit.block.Biome;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
import javax.annotation.Nullable;
/**
@@ -41,35 +36,9 @@ class BukkitBiomeRegistry implements BiomeRegistry {
@Nullable
@Override
- public BaseBiome createFromId(int id) {
- return new BaseBiome(id);
- }
-
- @Override
- public List getBiomes() {
- BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
- if (adapter != null) {
- List biomes = new ArrayList<>();
- for (Biome biome : Biome.values()) {
- int biomeId = adapter.getBiomeId(biome);
- biomes.add(new BaseBiome(biomeId));
- }
- return biomes;
- } else {
- return Collections.emptyList();
- }
- }
-
- @Nullable
- @Override
- public BiomeData getData(BaseBiome biome) {
- BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
- if (adapter != null) {
- final Biome bukkitBiome = adapter.getBiome(biome.getId());
- return bukkitBiome::name;
- } else {
- return null;
- }
+ public BiomeData getData(BiomeType biome) {
+ final Biome bukkitBiome = BukkitAdapter.adapt(biome);
+ return bukkitBiome == null ? null : bukkitBiome::name;
}
}
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBlockCategoryRegistry.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBlockCategoryRegistry.java
index 24cbe0f6b..cecec0691 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBlockCategoryRegistry.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBlockCategoryRegistry.java
@@ -49,4 +49,4 @@ public class BukkitBlockCategoryRegistry implements BlockCategoryRegistry {
public Set getAll(Category category) {
return getCategorisedByName(category.getId());
}
-}
\ No newline at end of file
+}
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandInspector.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandInspector.java
index b392c50ac..fa3f2917f 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandInspector.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandInspector.java
@@ -19,8 +19,6 @@
package com.sk89q.worldedit.bukkit;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.sk89q.bukkit.util.CommandInspector;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.extension.platform.Actor;
@@ -29,12 +27,14 @@ import com.sk89q.worldedit.util.command.Description;
import com.sk89q.worldedit.util.command.Dispatcher;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import java.util.logging.Logger;
+import static com.google.common.base.Preconditions.checkNotNull;
class BukkitCommandInspector implements CommandInspector {
- private static final Logger logger = Logger.getLogger(BukkitCommandInspector.class.getCanonicalName());
+ private static final Logger logger = LoggerFactory.getLogger(BukkitCommandInspector.class);
private final WorldEditPlugin plugin;
private final Dispatcher dispatcher;
@@ -51,7 +51,7 @@ class BukkitCommandInspector implements CommandInspector {
if (mapping != null) {
return mapping.getDescription().getDescription();
} else {
- logger.warning("BukkitCommandInspector doesn't know how about the command '" + command + "'");
+ logger.warn("BukkitCommandInspector doesn't know how about the command '" + command + "'");
return "Help text not available";
}
}
@@ -63,7 +63,7 @@ class BukkitCommandInspector implements CommandInspector {
Description description = mapping.getDescription();
return "Usage: " + description.getUsage() + (description.getHelp() != null ? "\n" + description.getHelp() : "");
} else {
- logger.warning("BukkitCommandInspector doesn't know how about the command '" + command + "'");
+ logger.warn("BukkitCommandInspector doesn't know how about the command '" + command + "'");
return "Help text not available";
}
}
@@ -76,7 +76,7 @@ class BukkitCommandInspector implements CommandInspector {
locals.put(Actor.class, plugin.wrapCommandSender(sender));
return mapping.getCallable().testPermission(locals);
} else {
- logger.warning("BukkitCommandInspector doesn't know how about the command '" + command + "'");
+ logger.warn("BukkitCommandInspector doesn't know how about the command '" + command + "'");
return false;
}
}
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitConfiguration.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitConfiguration.java
index 494a464ea..96c755083 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitConfiguration.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitConfiguration.java
@@ -22,6 +22,7 @@ package com.sk89q.worldedit.bukkit;
import com.sk89q.util.yaml.YAMLProcessor;
import com.sk89q.worldedit.util.YAMLConfiguration;
import com.sk89q.worldedit.util.report.Unreported;
+import org.slf4j.LoggerFactory;
import java.io.File;
@@ -34,7 +35,7 @@ public class BukkitConfiguration extends YAMLConfiguration {
@Unreported private final WorldEditPlugin plugin;
public BukkitConfiguration(YAMLProcessor config, WorldEditPlugin plugin) {
- super(config, plugin.getLogger());
+ super(config, LoggerFactory.getLogger(plugin.getLogger().getName()));
this.plugin = plugin;
}
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitImplementationTester.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitImplementationTester.java
deleted file mode 100644
index 1345f6a81..000000000
--- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitImplementationTester.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.bukkit;
-
-/**
- * Adds methods to test if different API methods are possible based on implementation.
- */
-public class BukkitImplementationTester {
-
- private BukkitImplementationTester() {
- }
-
- /**
- * Known Bukkit implementations
- */
- public enum BukkitImplementation {
- CRAFTBUKKIT,
- SPIGOT,
- PAPER,
- }
-
- private static final String implementationMessage = "************************************************" +
- "* Note: PaperMC (https://papermc.io/) is *" +
- "* recommended for optimal performance with *" +
- "* WorldEdit, WorldGuard, or CraftBook. *" +
- "************************************************";
-
- private static BukkitImplementation implementation;
-
- /**
- * Gets the implementation currently in use on the server.
- *
- * @return The server implementation
- */
- public static BukkitImplementation getImplementation() {
- if (implementation == null) {
- try {
- Class.forName("com.destroystokyo.paper.PaperConfig");
- implementation = BukkitImplementation.PAPER;
- } catch (Exception e) {
- try {
- Class.forName("org.spigotmc.SpigotConfig");
- implementation = BukkitImplementation.SPIGOT;
- } catch (Exception e2) {
- implementation = BukkitImplementation.CRAFTBUKKIT;
- }
- }
-
- if (implementation != BukkitImplementation.PAPER) {
-// Bukkit.getServer().getConsoleSender().sendMessage(implementationMessage); // TODO Decide if good idea.
- }
- }
-
- return implementation;
- }
-
- /**
- * Check if this implementation is compatible with Spigot APIs
- *
- * @return If compatible with Spigot APIs
- */
- public static boolean isSpigotCompatible() {
- return getImplementation() == BukkitImplementation.SPIGOT || getImplementation() == BukkitImplementation.PAPER;
- }
-
- /**
- * Check if this implementation is compatible with Paper APIs
- *
- * @return If compatible with Paper APIs
- */
- public static boolean isPaperCompatible() {
- return getImplementation() == BukkitImplementation.PAPER;
- }
-}
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitItemCategoryRegistry.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitItemCategoryRegistry.java
index b5291b4e1..c75c56eb2 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitItemCategoryRegistry.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitItemCategoryRegistry.java
@@ -49,4 +49,4 @@ public class BukkitItemCategoryRegistry implements ItemCategoryRegistry {
public Set getAll(Category category) {
return getCategorisedByName(category.getId());
}
-}
\ No newline at end of file
+}
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java
index b3674e986..94b616f7b 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java
@@ -61,6 +61,10 @@ public class BukkitPlayer extends AbstractPlayerActor {
private Player player;
private WorldEditPlugin plugin;
+ public BukkitPlayer(Player player) {
+ this(WorldEditPlugin.getInstance(), player);
+ }
+
public BukkitPlayer(WorldEditPlugin plugin, Player player) {
this.plugin = plugin;
this.player = player;
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitRegistries.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitRegistries.java
index 962d10d01..12f485bf5 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitRegistries.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitRegistries.java
@@ -19,7 +19,11 @@
package com.sk89q.worldedit.bukkit;
-import com.sk89q.worldedit.world.registry.*;
+import com.sk89q.worldedit.world.registry.BiomeRegistry;
+import com.sk89q.worldedit.world.registry.BlockCategoryRegistry;
+import com.sk89q.worldedit.world.registry.BlockRegistry;
+import com.sk89q.worldedit.world.registry.BundledRegistries;
+import com.sk89q.worldedit.world.registry.ItemCategoryRegistry;
/**
* World data for the Bukkit platform.
@@ -44,11 +48,6 @@ class BukkitRegistries extends BundledRegistries {
public BlockRegistry getBlockRegistry() {
return blockRegistry;
}
-
- @Override
- public BlockCategoryRegistry getBlockCategoryRegistry() {
- return blockCategoryRegistry;
- }
@Override
public BiomeRegistry getBiomeRegistry() {
@@ -59,6 +58,11 @@ class BukkitRegistries extends BundledRegistries {
public ItemRegistry getItemRegistry() {
return itemRegistry;
}
+
+ @Override
+ public BlockCategoryRegistry getBlockCategoryRegistry() {
+ return blockCategoryRegistry;
+ }
@Override
public ItemCategoryRegistry getItemCategoryRegistry() {
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java
index a199b6069..ca94366da 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java
@@ -18,7 +18,6 @@
package com.sk89q.worldedit.bukkit;
-
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
@@ -33,7 +32,8 @@ import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.world.AbstractWorld;
-import com.sk89q.worldedit.world.biome.BaseBiome;
+import com.sk89q.worldedit.world.biome.BiomeType;
+import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.weather.WeatherType;
import com.sk89q.worldedit.world.weather.WeatherTypes;
@@ -41,13 +41,13 @@ import com.sk89q.worldedit.world.weather.WeatherTypes;
import org.bukkit.Effect;
import org.bukkit.TreeType;
import org.bukkit.World;
-import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Chest;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.DoubleChestInventory;
import org.bukkit.inventory.Inventory;
+import org.slf4j.Logger;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
@@ -56,8 +56,6 @@ import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import static com.google.common.base.Preconditions.checkNotNull;
public class BukkitWorld extends AbstractWorld {
@@ -118,9 +116,9 @@ public class BukkitWorld extends AbstractWorld {
return null;
}
} catch (Exception e) {
- logger.warning("Corrupt entity found when creating: " + entity.getType().getId());
+ logger.warn("Corrupt entity found when creating: " + entity.getType().getId());
if (entity.getNbtData() != null) {
- logger.warning(entity.getNbtData().toString());
+ logger.warn(entity.getNbtData().toString());
}
e.printStackTrace();
return null;
@@ -183,7 +181,7 @@ public class BukkitWorld extends AbstractWorld {
try {
getWorld().regenerateChunk(chunk.getBlockX(), chunk.getBlockZ());
} catch (Throwable t) {
- logger.log(Level.WARNING, "Chunk generation via Bukkit raised an error", t);
+ logger.warn("Chunk generation via Bukkit raised an error", t);
}
// Then restore
@@ -280,7 +278,7 @@ public class BukkitWorld extends AbstractWorld {
treeTypeMapping.put(TreeGenerator.TreeType.RANDOM_MUSHROOM, TreeType.BROWN_MUSHROOM);
for (TreeGenerator.TreeType type : TreeGenerator.TreeType.values()) {
if (treeTypeMapping.get(type) == null) {
- WorldEdit.logger.severe("No TreeType mapping for TreeGenerator.TreeType." + type);
+ WorldEdit.logger.error("No TreeType mapping for TreeGenerator.TreeType." + type);
}
}
}
@@ -425,9 +423,9 @@ public class BukkitWorld extends AbstractWorld {
try {
return adapter.setBlock(BukkitAdapter.adapt(getWorld(), position), block, notifyAndLight);
} catch (Exception e) {
- if (block instanceof BaseBlock && ((BaseBlock)block).getNbtData() != null) {
- logger.warning("Tried to set a corrupt tile entity at " + position.toString());
- logger.warning(((BaseBlock)block).getNbtData().toString());
+ if (block instanceof BaseBlock && ((BaseBlock) block).getNbtData() != null) {
+ logger.warn("Tried to set a corrupt tile entity at " + position.toString());
+ logger.warn(((BaseBlock) block).getNbtData().toString());
}
e.printStackTrace();
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
@@ -468,25 +466,13 @@ public class BukkitWorld extends AbstractWorld {
}
@Override
- public BaseBiome getBiome(BlockVector2 position) {
- BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
- if (adapter != null) {
- int id = adapter.getBiomeId(getWorld().getBiome(position.getBlockX(), position.getBlockZ()));
- return new BaseBiome(id);
- } else {
- return new BaseBiome(0);
- }
+ public BiomeType getBiome(BlockVector2 position) {
+ return BukkitAdapter.adapt(getWorld().getBiome(position.getBlockX(), position.getBlockZ()));
}
@Override
- public boolean setBiome(BlockVector2 position, BaseBiome biome) {
- BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
- if (adapter != null) {
- Biome bukkitBiome = adapter.getBiome(biome.getId());
- getWorld().setBiome(position.getBlockX(), position.getBlockZ(), bukkitBiome);
- return true;
- } else {
- return false;
- }
+ public boolean setBiome(BlockVector2 position, BiomeType biome) {
+ getWorld().setBiome(position.getBlockX(), position.getBlockZ(), BukkitAdapter.adapt(biome));
+ return true;
}
}
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java
index 78f8c8091..b49d9dc96 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java
@@ -19,6 +19,8 @@
package com.sk89q.worldedit.bukkit;
+import com.bekvon.bukkit.residence.commands.message;
+import com.bekvon.bukkit.residence.containers.cmd;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.bukkit.FaweBukkit;
import com.boydti.fawe.bukkit.adapter.v1_13_1.Spigot_v1_13_R2;
@@ -34,32 +36,49 @@ import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplLoader;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
+import com.sk89q.worldedit.extension.input.InputParseException;
+import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.NoCapablePlatformException;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag;
+import com.sk89q.worldedit.registry.state.Property;
+import com.sk89q.worldedit.world.biome.BiomeType;
+import com.sk89q.worldedit.world.block.BlockCategory;
+import com.sk89q.worldedit.world.block.BlockState;
+import com.sk89q.worldedit.world.block.BlockType;
+import com.sk89q.worldedit.world.block.FuzzyBlockState;
+import com.sk89q.worldedit.world.entity.EntityType;
+import com.sk89q.worldedit.world.item.ItemCategory;
+import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.LegacyMapper;
+import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.Material;
+import org.bukkit.Tag;
+import org.bukkit.block.Biome;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.*;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
-import java.io.*;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.Field;
-import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarFile;
import java.util.logging.Level;
-import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -70,7 +89,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
{
- private static final Logger log = Logger.getLogger("FastAsyncWorldEdit");
+ private static final Logger log = LoggerFactory.getLogger(WorldEditPlugin.class);
public static final String CUI_PLUGIN_CHANNEL = "worldedit:cui";
private static WorldEditPlugin INSTANCE;
@@ -139,13 +158,9 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
return CUI_PLUGIN_CHANNEL;
}
- /**
- * Called on plugin enable.
- */
- @SuppressWarnings("AccessStaticViaInstance")
@Override
- public void onEnable() {
- rename();
+ public void onLoad() {
+ rename();
this.INSTANCE = this;
FaweBukkit imp = new FaweBukkit(this);
@@ -163,6 +178,16 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
loadConfig(); // Load configuration
fail(() -> PermissionsResolverManager.initialize(INSTANCE), "Failed to initialize permissions resolver");
+ }
+
+ /**
+ * Called on plugin enable.
+ */
+ @Override
+ public void onEnable() {
+ setupTags(); // these have to be done post-world since they rely on MC registries. the other ones just use Bukkit enums
+
+ PermissionsResolverManager.initialize(this); // Setup permission resolver
// Register CUI
fail(() -> {
@@ -178,9 +203,6 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
// platforms to be worried about... at the current time of writing
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
- // Setup the BukkitImplementationTester.
- BukkitImplementationTester.getImplementation();
-
{ // Register 1.13 Material ids with LegacyMapper
LegacyMapper legacyMapper = LegacyMapper.getInstance();
for (Material m : Material.values()) {
@@ -191,6 +213,20 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
}
}
+ private void setupTags() {
+ // Tags
+ try {
+ for (Tag blockTag : Bukkit.getTags(Tag.REGISTRY_BLOCKS, Material.class)) {
+ BlockCategory.REGISTRY.register(blockTag.getKey().toString(), new BlockCategory(blockTag.getKey().toString()));
+ }
+ for (Tag itemTag : Bukkit.getTags(Tag.REGISTRY_ITEMS, Material.class)) {
+ ItemCategory.REGISTRY.register(itemTag.getKey().toString(), new ItemCategory(itemTag.getKey().toString()));
+ }
+ } catch (NoSuchMethodError e) {
+ getLogger().warning("The version of Spigot/Paper you are using doesn't support Tags. The usage of tags with WorldEdit will not work until you update.");
+ }
+ }
+
private void rename() {
// {
// PluginDescriptionFile desc = getDescription();
@@ -221,7 +257,7 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
}
}
{
- Logger logger = getLogger();
+ java.util.logging.Logger logger = getLogger();
if (logger != null) {
try {
Field nameField = Logger.class.getDeclaredField("name");
@@ -245,7 +281,7 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
e.printStackTrace();
}
}
- log.log(Level.INFO, "Please restart the server if you have any plugins which depend on FAWE.");
+ log.info("Please restart the server if you have any plugins which depend on FAWE.");
}
}
@@ -253,7 +289,7 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
try {
run.run();
} catch (Throwable e) {
- log.log(Level.SEVERE, message);
+ log.error(message);
e.printStackTrace();
}
}
@@ -264,7 +300,7 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "config-legacy.yml"), true), this);
config.load();
} catch (Throwable e) {
- log.log(Level.SEVERE, "Failed to load config.yml");
+ log.error("Failed to load config.yml");
e.printStackTrace();
}
// Create schematics folder
@@ -287,30 +323,30 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
try {
adapterLoader.addFromPath(getClass().getClassLoader());
} catch (IOException e) {
- log.log(Level.WARNING, "Failed to search path for Bukkit adapters");
+ log.warn("Failed to search path for Bukkit adapters");
}
try {
adapterLoader.addFromJar(getFile());
} catch (IOException e) {
- log.log(Level.WARNING, "Failed to search " + getFile() + " for Bukkit adapters", e);
+ log.warn("Failed to search " + getFile() + " for Bukkit adapters", e);
}
try {
bukkitAdapter = adapterLoader.loadAdapter();
- log.log(Level.INFO, "Using " + bukkitAdapter.getClass().getCanonicalName() + " as the Bukkit adapter");
+ log.info("Using " + bukkitAdapter.getClass().getCanonicalName() + " as the Bukkit adapter");
} catch (AdapterLoadException e) {
try {
Platform platform = worldEdit.getPlatformManager().queryCapability(Capability.WORLD_EDITING);
if (platform instanceof BukkitServerInterface) {
- log.log(Level.WARNING, e.getMessage());
+ log.warn(e.getMessage());
return;
} else {
- log.log(Level.INFO, "WorldEdit could not find a Bukkit adapter for this MC version, " +
+ log.info("WorldEdit could not find a Bukkit adapter for this MC version, " +
"but it seems that you have another implementation of WorldEdit installed (" + platform.getPlatformName() + ") " +
"that handles the world editing.");
}
} catch (NoCapablePlatformException ignore) {}
- log.log(Level.INFO, "WorldEdit could not find a Bukkit adapter for this MC version");
+ log.info("WorldEdit could not find a Bukkit adapter for this MC version");
}
}
@@ -425,7 +461,7 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
EditSession editSession = WorldEdit.getInstance().getEditSessionFactory()
.getEditSession(wePlayer.getWorld(), session.getBlockChangeLimit(), blockBag, wePlayer);
- editSession.enableQueue();
+ editSession.enableStandardMode();
return editSession;
}
@@ -441,7 +477,7 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
LocalSession session = WorldEdit.getInstance().getSessionManager().get(wePlayer);
session.remember(editSession);
- editSession.flushQueue();
+ editSession.flushSession();
WorldEdit.getInstance().flushBlockBag(wePlayer, editSession);
}
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java
index 33c2e51e0..b8af14175 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java
@@ -19,20 +19,18 @@
package com.sk89q.worldedit.bukkit.adapter;
-import com.sk89q.jnbt.Tag;
-import com.sk89q.worldedit.world.block.BaseBlock;
-import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.math.BlockVector3;
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.registry.BlockMaterial;
import org.bukkit.Chunk;
import org.bukkit.Location;
-import org.bukkit.block.Biome;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
@@ -45,26 +43,6 @@ import javax.annotation.Nullable;
*/
public interface BukkitImplAdapter extends IBukkitAdapter {
- /**
- * Get the biome ID for the given biome.
- *
- * Returns 0 if it is not known or it doesn't exist.
- *
- * @param biome biome
- * @return the biome ID
- */
- int getBiomeId(Biome biome);
-
- /**
- * Get the biome ID for the given biome ID..
- *
- * Returns {@link Biome#OCEAN} if it is not known or it doesn't exist.
- *
- * @param id the biome ID
- * @return the biome
- */
- Biome getBiome(int id);
-
/**
* Get the block at the given location.
*
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplLoader.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplLoader.java
index 9d65cf46b..8d99181d6 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplLoader.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplLoader.java
@@ -20,6 +20,8 @@
package com.sk89q.worldedit.bukkit.adapter;
import com.sk89q.worldedit.util.io.Closer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
@@ -29,15 +31,13 @@ import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
-import java.util.logging.Level;
-import java.util.logging.Logger;
/**
* Loads Bukkit implementation adapters.
*/
public class BukkitImplLoader {
- private static final Logger log = Logger.getLogger(BukkitImplLoader.class.getCanonicalName());
+ private static final Logger log = LoggerFactory.getLogger(BukkitImplLoader.class);
private final List adapterCandidates = new ArrayList<>();
private String customCandidate;
@@ -73,7 +73,7 @@ public class BukkitImplLoader {
if (className != null) {
customCandidate = className;
adapterCandidates.add(className);
- log.log(Level.INFO, "-Dworldedit.bukkit.adapter used to add " + className + " to the list of available Bukkit adapters");
+ log.info("-Dworldedit.bukkit.adapter used to add " + className + " to the list of available Bukkit adapters");
}
}
@@ -93,7 +93,7 @@ public class BukkitImplLoader {
try {
Enumeration entries = jar.entries();
while (entries.hasMoreElements()) {
- JarEntry jarEntry = (JarEntry) entries.nextElement();
+ JarEntry jarEntry = entries.nextElement();
String className = jarEntry.getName().replaceAll("[/\\\\]+", ".");
@@ -157,22 +157,23 @@ public class BukkitImplLoader {
for (String className : adapterCandidates) {
try {
Class> cls = Class.forName(className);
+ if (cls.isSynthetic()) continue;
if (BukkitImplAdapter.class.isAssignableFrom(cls)) {
return (BukkitImplAdapter) cls.newInstance();
} else {
- log.log(Level.WARNING, "Failed to load the Bukkit adapter class '" + className +
+ log.warn("Failed to load the Bukkit adapter class '" + className +
"' because it does not implement " + BukkitImplAdapter.class.getCanonicalName());
}
} catch (ClassNotFoundException e) {
- log.log(Level.WARNING, "Failed to load the Bukkit adapter class '" + className +
+ log.warn("Failed to load the Bukkit adapter class '" + className +
"' that is not supposed to be missing", e);
} catch (IllegalAccessException e) {
- log.log(Level.WARNING, "Failed to load the Bukkit adapter class '" + className +
+ log.warn("Failed to load the Bukkit adapter class '" + className +
"' that is not supposed to be raising this error", e);
} catch (Throwable e) {
e.printStackTrace();
if (className.equals(customCandidate)) {
- log.log(Level.WARNING, "Failed to load the Bukkit adapter class '" + className + "'", e);
+ log.warn("Failed to load the Bukkit adapter class '" + className + "'", e);
}
}
}
diff --git a/worldedit-bukkit/src/main/resources/com/sk89q/worldedit/bukkit/adapter/impl/Spigot_v1_13_R1$1.class b/worldedit-bukkit/src/main/resources/com/sk89q/worldedit/bukkit/adapter/impl/Spigot_v1_13_R1$1.class
new file mode 100644
index 000000000..efa78dacc
Binary files /dev/null and b/worldedit-bukkit/src/main/resources/com/sk89q/worldedit/bukkit/adapter/impl/Spigot_v1_13_R1$1.class differ
diff --git a/worldedit-bukkit/src/main/resources/com/sk89q/worldedit/bukkit/adapter/impl/Spigot_v1_13_R2$1.class b/worldedit-bukkit/src/main/resources/com/sk89q/worldedit/bukkit/adapter/impl/Spigot_v1_13_R2$1.class
new file mode 100644
index 000000000..97a809b53
Binary files /dev/null and b/worldedit-bukkit/src/main/resources/com/sk89q/worldedit/bukkit/adapter/impl/Spigot_v1_13_R2$1.class differ
diff --git a/worldedit-bukkit/src/main/resources/com/sk89q/worldedit/bukkit/adapter/impl/Spigot_v1_13_R2_2$1.class b/worldedit-bukkit/src/main/resources/com/sk89q/worldedit/bukkit/adapter/impl/Spigot_v1_13_R2_2$1.class
new file mode 100644
index 000000000..e294143a7
Binary files /dev/null and b/worldedit-bukkit/src/main/resources/com/sk89q/worldedit/bukkit/adapter/impl/Spigot_v1_13_R2_2$1.class differ
diff --git a/worldedit-bukkit/src/main/resources/com/sk89q/worldedit/bukkit/adapter/impl/Spigot_v1_13_R2_2.class b/worldedit-bukkit/src/main/resources/com/sk89q/worldedit/bukkit/adapter/impl/Spigot_v1_13_R2_2.class
new file mode 100644
index 000000000..5377fe96c
Binary files /dev/null and b/worldedit-bukkit/src/main/resources/com/sk89q/worldedit/bukkit/adapter/impl/Spigot_v1_13_R2_2.class differ
diff --git a/worldedit-bukkit/src/main/resources/defaults/config-legacy.yml b/worldedit-bukkit/src/main/resources/defaults/config-legacy.yml
index 4b8d14715..624b7dc7d 100644
--- a/worldedit-bukkit/src/main/resources/defaults/config-legacy.yml
+++ b/worldedit-bukkit/src/main/resources/defaults/config-legacy.yml
@@ -17,7 +17,6 @@
#
limits:
- allow-extra-data-values: false
max-blocks-changed:
default: -1
maximum: -1
@@ -77,9 +76,16 @@ history:
size: 15
expiration: 10
+calculation:
+ timeout: 100
+
+debugging:
+ trace-unflushed-sessions: false
+
wand-item: minecraft:wooden_axe
shell-save-type:
no-double-slash: false
no-op-permissions: false
debug: false
show-help-on-first-use: true
+server-side-cui: true
diff --git a/worldedit-core/build.gradle b/worldedit-core/build.gradle
index 89a595b92..6ac2c5455 100644
--- a/worldedit-core/build.gradle
+++ b/worldedit-core/build.gradle
@@ -13,6 +13,8 @@ dependencies {
compile 'com.google.code.gson:gson:2.8.0'
compile 'com.sk89q.lib:jlibnoise:1.0.0'
compile 'com.googlecode.json-simple:json-simple:1.1.1'
+ compile 'org.slf4j:slf4j-api:1.7.26'
+ //compile 'net.sf.trove4j:trove4j:3.0.3'
testCompile 'org.mockito:mockito-core:1.9.0-rc1'
// Fawe depends
diff --git a/worldedit-core/src/main/java/com/sk89q/minecraft/util/commands/CommandsManager.java b/worldedit-core/src/main/java/com/sk89q/minecraft/util/commands/CommandsManager.java
index a8f49678b..df3b0806b 100644
--- a/worldedit-core/src/main/java/com/sk89q/minecraft/util/commands/CommandsManager.java
+++ b/worldedit-core/src/main/java/com/sk89q/minecraft/util/commands/CommandsManager.java
@@ -20,6 +20,8 @@
package com.sk89q.minecraft.util.commands;
import com.sk89q.util.StringUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -30,8 +32,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
/**
* Manager for handling commands. This allows you to easily process commands,
@@ -63,7 +63,7 @@ import java.util.logging.Logger;
public abstract class CommandsManager {
protected static final Logger logger =
- Logger.getLogger(CommandsManager.class.getCanonicalName());
+ LoggerFactory.getLogger(CommandsManager.class);
/**
* Mapping of commands (including aliases) with a description. Root
@@ -142,7 +142,7 @@ public abstract class CommandsManager {
return registerMethods(cls, parent, obj);
}
} catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
- logger.log(Level.SEVERE, "Failed to register commands", e);
+ logger.error("Failed to register commands", e);
}
return null;
}
@@ -523,7 +523,7 @@ public abstract class CommandsManager {
try {
method.invoke(instance, methodArgs);
} catch (IllegalArgumentException | IllegalAccessException e) {
- logger.log(Level.SEVERE, "Failed to execute command", e);
+ logger.error("Failed to execute command", e);
} catch (InvocationTargetException e) {
if (e.getCause() instanceof CommandException) {
throw (CommandException) e.getCause();
diff --git a/worldedit-core/src/main/java/com/sk89q/minecraft/util/commands/SimpleInjector.java b/worldedit-core/src/main/java/com/sk89q/minecraft/util/commands/SimpleInjector.java
index eb6097512..652c69a5d 100644
--- a/worldedit-core/src/main/java/com/sk89q/minecraft/util/commands/SimpleInjector.java
+++ b/worldedit-core/src/main/java/com/sk89q/minecraft/util/commands/SimpleInjector.java
@@ -19,14 +19,15 @@
package com.sk89q.minecraft.util.commands;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
public class SimpleInjector implements Injector {
- private static final Logger log = Logger.getLogger(SimpleInjector.class.getCanonicalName());
+ private static final Logger log = LoggerFactory.getLogger(SimpleInjector.class);
private Object[] args;
private Class>[] argClasses;
@@ -45,7 +46,7 @@ public class SimpleInjector implements Injector {
ctr.setAccessible(true);
return ctr.newInstance(args);
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
- log.log(Level.SEVERE, "Error initializing commands class " + clazz, e);
+ log.error("Error initializing commands class " + clazz, e);
return null;
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
index 452fbe70d..b1779c154 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -28,18 +28,45 @@ import com.boydti.fawe.jnbt.anvil.MCAQueue;
import com.boydti.fawe.jnbt.anvil.MCAWorld;
import com.boydti.fawe.logging.LoggingChangeSet;
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
-import com.boydti.fawe.object.*;
+import com.boydti.fawe.object.FaweLimit;
+import com.boydti.fawe.object.FawePlayer;
+import com.boydti.fawe.object.FaweQueue;
+import com.boydti.fawe.object.HasFaweQueue;
+import com.boydti.fawe.object.HistoryExtent;
+import com.boydti.fawe.object.NullChangeSet;
+import com.boydti.fawe.object.RegionWrapper;
+import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
-import com.boydti.fawe.object.changeset.*;
+import com.boydti.fawe.object.changeset.BlockBagChangeSet;
+import com.boydti.fawe.object.changeset.CPUOptimizedChangeSet;
+import com.boydti.fawe.object.changeset.DiskStorageHistory;
+import com.boydti.fawe.object.changeset.FaweChangeSet;
+import com.boydti.fawe.object.changeset.MemoryOptimizedHistory;
+import com.boydti.fawe.object.collection.BlockVectorSet;
import com.boydti.fawe.object.collection.LocalBlockVectorSet;
import com.boydti.fawe.object.exception.FaweException;
-import com.boydti.fawe.object.extent.*;
+import com.boydti.fawe.object.extent.FastWorldEditExtent;
+import com.boydti.fawe.object.extent.FaweRegionExtent;
+import com.boydti.fawe.object.extent.HeightBoundExtent;
+import com.boydti.fawe.object.extent.MultiRegionExtent;
+import com.boydti.fawe.object.extent.NullExtent;
+import com.boydti.fawe.object.extent.ResettableExtent;
+import com.boydti.fawe.object.extent.SingleRegionExtent;
+import com.boydti.fawe.object.extent.SlowExtent;
+import com.boydti.fawe.object.extent.SourceMaskExtent;
+import com.boydti.fawe.object.extent.StripNBTExtent;
import com.boydti.fawe.object.function.SurfaceRegionFunction;
import com.boydti.fawe.object.mask.ResettableMask;
import com.boydti.fawe.object.pattern.ExistingPattern;
import com.boydti.fawe.object.progress.ChatProgressTracker;
import com.boydti.fawe.object.progress.DefaultProgressTracker;
-import com.boydti.fawe.util.*;
+import com.boydti.fawe.util.ExtentTraverser;
+import com.boydti.fawe.util.MaskTraverser;
+import com.boydti.fawe.util.MathMan;
+import com.boydti.fawe.util.MemUtil;
+import com.boydti.fawe.util.Perm;
+import com.boydti.fawe.util.SetQueue;
+import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.wrappers.WorldWrapper;
import com.google.common.base.Supplier;
import com.sk89q.jnbt.CompoundTag;
@@ -51,37 +78,79 @@ import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.ChangeSetExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.MaskingExtent;
+import com.sk89q.worldedit.extent.cache.LastAccessExtentCache;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.extent.inventory.BlockBagExtent;
+import com.sk89q.worldedit.extent.reorder.ChunkBatchingExtent;
+import com.sk89q.worldedit.extent.reorder.MultiStageReorder;
+import com.sk89q.worldedit.extent.validation.BlockChangeLimiter;
+import com.sk89q.worldedit.extent.validation.DataValidatorExtent;
+import com.sk89q.worldedit.extent.world.BlockQuirkExtent;
+import com.sk89q.worldedit.extent.world.ChunkLoadingExtent;
+import com.sk89q.worldedit.extent.world.FastModeExtent;
import com.sk89q.worldedit.extent.world.SurvivalModeExtent;
import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.RegionMaskingFilter;
+import com.sk89q.worldedit.function.block.BlockDistributionCounter;
import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.block.Naturalizer;
+import com.sk89q.worldedit.function.generator.ForestGenerator;
import com.sk89q.worldedit.function.generator.GardenPatchGenerator;
-import com.sk89q.worldedit.function.mask.*;
+import com.sk89q.worldedit.function.mask.BlockMask;
+import com.sk89q.worldedit.function.mask.BlockMaskBuilder;
+import com.sk89q.worldedit.function.mask.BlockStateMask;
+import com.sk89q.worldedit.function.mask.BlockTypeMask;
+import com.sk89q.worldedit.function.mask.BoundedHeightMask;
+import com.sk89q.worldedit.function.mask.ExistingBlockMask;
+import com.sk89q.worldedit.function.mask.Mask;
+import com.sk89q.worldedit.function.mask.MaskIntersection;
+import com.sk89q.worldedit.function.mask.MaskUnion;
+import com.sk89q.worldedit.function.mask.Masks;
+import com.sk89q.worldedit.function.mask.NoiseFilter2D;
+import com.sk89q.worldedit.function.mask.RegionMask;
import com.sk89q.worldedit.function.operation.ChangeSetExecutor;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
+import com.sk89q.worldedit.function.pattern.WaterloggedRemover;
import com.sk89q.worldedit.function.util.RegionOffset;
-import com.sk89q.worldedit.function.visitor.*;
+import com.sk89q.worldedit.function.visitor.DirectionalVisitor;
+import com.sk89q.worldedit.function.visitor.DownwardVisitor;
+import com.sk89q.worldedit.function.visitor.FlatRegionVisitor;
+import com.sk89q.worldedit.function.visitor.LayerVisitor;
+import com.sk89q.worldedit.function.visitor.NonRisingVisitor;
+import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
+import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.history.UndoContext;
import com.sk89q.worldedit.history.change.BlockChange;
+import com.sk89q.worldedit.history.changeset.BlockOptimizedHistory;
import com.sk89q.worldedit.history.changeset.ChangeSet;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
import com.sk89q.worldedit.internal.expression.runtime.RValue;
-import com.sk89q.worldedit.math.*;
+import com.sk89q.worldedit.internal.expression.runtime.ExpressionTimeoutException;
+import com.sk89q.worldedit.internal.expression.runtime.RValue;
+import com.sk89q.worldedit.math.BlockVector2;
+import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.math.MathUtils;
+import com.sk89q.worldedit.math.MutableBlockVector2;
+import com.sk89q.worldedit.math.MutableBlockVector3;
+import com.sk89q.worldedit.math.Vector2;
+import com.sk89q.worldedit.math.Vector3;
+import com.sk89q.worldedit.math.interpolation.Interpolation;
import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation;
import com.sk89q.worldedit.math.interpolation.Node;
import com.sk89q.worldedit.math.noise.RandomNoise;
import com.sk89q.worldedit.math.transform.AffineTransform;
-import com.sk89q.worldedit.regions.*;
+import com.sk89q.worldedit.regions.CuboidRegion;
+import com.sk89q.worldedit.regions.EllipsoidRegion;
+import com.sk89q.worldedit.regions.FlatRegion;
+import com.sk89q.worldedit.regions.Region;
+import com.sk89q.worldedit.regions.Regions;
import com.sk89q.worldedit.regions.shape.ArbitraryBiomeShape;
import com.sk89q.worldedit.regions.shape.ArbitraryShape;
import com.sk89q.worldedit.regions.shape.RegionShape;
@@ -89,12 +158,18 @@ import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.TreeGenerator;
+import com.sk89q.worldedit.util.collection.DoubleArrayList;
import com.sk89q.worldedit.util.eventbus.EventBus;
+import com.sk89q.worldedit.world.NullWorld;
import com.sk89q.worldedit.world.SimpleWorld;
import com.sk89q.worldedit.world.World;
-import com.sk89q.worldedit.world.biome.BaseBiome;
+import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.*;
+import com.sk89q.worldedit.world.registry.LegacyMapper;
import com.sk89q.worldedit.world.weather.WeatherType;
+import javafx.stage.Stage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -103,7 +178,9 @@ import java.util.concurrent.ThreadLocalRandom;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.sk89q.worldedit.regions.Regions.*;
+import static com.sk89q.worldedit.regions.Regions.asFlatRegion;
+import static com.sk89q.worldedit.regions.Regions.maximumBlockY;
+import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
/**
* An {@link Extent} that handles history, {@link BlockBag}s, change limits,
@@ -114,13 +191,8 @@ import static com.sk89q.worldedit.regions.Regions.*;
* using the {@link ChangeSetExtent}.
*/
public class EditSession extends AbstractDelegateExtent implements HasFaweQueue, SimpleWorld, AutoCloseable {
- /**
- * Used by {@link EditSession#setBlock(BlockVector3, BlockStateHolder, Stage)} to
- * determine which {@link Extent}s should be bypassed.
- */
- public enum Stage {
- BEFORE_HISTORY, BEFORE_REORDER, BEFORE_CHANGE
- }
+
+ private static final Logger log = LoggerFactory.getLogger(EditSession.class);
private World world;
private String worldName;
@@ -144,9 +216,14 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
private final int maxY;
public static final UUID CONSOLE = UUID.fromString("1-1-3-3-7");
- public static final BaseBiome nullBiome = new BaseBiome(0);
public static final BlockState nullBlock = BlockTypes.AIR.getDefaultState();
+ public enum Stage {
+ BEFORE_HISTORY,
+ BEFORE_REORDER,
+ BEFORE_CHANGE
+ }
+
@Deprecated
public EditSession(@Nonnull World world, @Nullable FaweQueue queue, @Nullable FawePlayer player, @Nullable FaweLimit limit, @Nullable FaweChangeSet changeSet, @Nullable RegionWrapper[] allowedRegions, @Nullable Boolean autoQueue, @Nullable Boolean fastmode, @Nullable Boolean checkMemory, @Nullable Boolean combineStages, @Nullable BlockBag blockBag, @Nullable EventBus bus, @Nullable EditSessionEvent event) {
this(null, world, queue, player, limit, changeSet, allowedRegions, autoQueue, fastmode, checkMemory, combineStages, blockBag, bus, event);
@@ -340,6 +417,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
this(WorldEdit.getInstance().getEventBus(), world, maxBlocks, blockBag, new EditSessionEvent(world, null, maxBlocks, null));
}
+ private ReorderMode reorderMode = ReorderMode.MULTI_STAGE;
+
private Mask oldMask;
/**
@@ -370,6 +449,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
if (find != null && find.get() != null) {
find.get().setLimit(this.limit);
}
+
+ setReorderMode(this.reorderMode);
}
/**
@@ -400,7 +481,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
}
/**
- * The region extent restricts block placements to allowed regions
+ * The region extent restricts block placements to allowmaxYed regions
*
* @return FaweRegionExtent (may be null)
*/
@@ -536,6 +617,29 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
return extent;
}
+ // pkg private for TracedEditSession only, may later become public API
+ boolean commitRequired() {
+ if (reorderExtent != null && reorderExtent.commitRequired()) {
+ return true;
+ }
+ if (chunkBatchingExtent != null && chunkBatchingExtent.commitRequired()) {
+ return true;
+ }
+ if (fastModeExtent != null && fastModeExtent.commitRequired()) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Turns on specific features for a normal WorldEdit session, such as
+ * {@link #setBatchingChunks(boolean)
+ * chunk batching}.
+ */
+ public void enableStandardMode() {
+ setBatchingChunks(true);
+ }
+
/**
* Get the world.
*
@@ -610,6 +714,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* Returns queue status.
*
* @return whether the queue is enabled
+ * @deprecated Use {@link EditSession#getReorderMode()} with MULTI_STAGE instead.
*/
@Deprecated
public boolean isQueueEnabled() {
@@ -618,6 +723,9 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
/**
* Queue certain types of block for better reproduction of those blocks.
+ *
+ * Uses {@link ReorderMode#MULTI_STAGE}
+ * @deprecated Use {@link EditSession#setReorderMode(ReorderMode)} with MULTI_STAGE instead.
*/
@Deprecated
public void enableQueue() {
@@ -880,6 +988,27 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
return new HashMap<>();
}
+ /**
+ * Returns chunk batching status.
+ *
+ * @return whether chunk batching is enabled
+ */
+ public boolean isBatchingChunks() {
+ return false;
+ }
+
+ /**
+ * Enable or disable chunk batching. Disabling will
+ * {@linkplain #flushSession() flush the session}.
+ *
+ * @param batchingChunks {@code true} to enable, {@code false} to disable
+ */
+ public void setBatchingChunks(boolean batchingChunks) {
+ }
+
+ public void disableBuffering() {
+ }
+
/**
* Get the number of blocks changed, including repeated block changes.
*
@@ -892,18 +1021,18 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
}
@Override
- public BaseBiome getBiome(final BlockVector2 position) {
+ public BiomeType getBiome(final BlockVector2 position) {
return this.extent.getBiome(position);
}
@Override
- public boolean setBiome(final BlockVector2 position, final BaseBiome biome) {
+ public boolean setBiome(final BlockVector2 position, final BiomeType biome) {
this.changes++;
return this.extent.setBiome(position, biome);
}
@Override
- public boolean setBiome(int x, int y, int z, BaseBiome biome) {
+ public boolean setBiome(int x, int y, int z, BiomeType biome) {
this.changes++;
return this.extent.setBiome(x, y, z, biome);
}
@@ -968,8 +1097,24 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
return getBlockType(position.getBlockX(), position.getBlockY(), position.getBlockZ());
}
+ /**
+ * Returns the highest solid 'terrain' block.
+ *
+ * @param x the X coordinate
+ * @param z the Z coordinate
+ * @param minY minimal height
+ * @param maxY maximal height
+ * @param filter a mask of blocks to consider, or null to consider any solid (movement-blocking) block
+ * @return height of highest block found or 'minY'
+ */
public int getHighestTerrainBlock(int x, int z, int minY, int maxY) {
- return getHighestTerrainBlock(x, z, minY, maxY, null);
+ for (int y = maxY; y >= minY; --y) {
+ BlockVector3 pt = BlockVector3.at(x, y, z);
+ if (getBlock(pt).getBlockType().getMaterial().isMovementBlocker()) {
+ return y;
+ }
+ }
+ return minY;
}
/**
@@ -985,9 +1130,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
public int getHighestTerrainBlock(int x, int z, int minY, int maxY, Mask filter) {
for (int y = maxY; y >= minY; --y) {
BlockVector3 pt = BlockVector3.at(x, y, z);
- if (filter == null
- ? getBlock(pt).getBlockType().getMaterial().isMovementBlocker()
- : filter.test(pt)) {
+ if (filter.test(pt)) {
return y;
}
}
@@ -1033,6 +1176,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return whether the block changed
*/
public > boolean rawSetBlock(BlockVector3 position, B block) {
+ this.changes++;
try {
return this.bypassAll.setBlock(position, block);
} catch (WorldEditException e) {
@@ -1048,6 +1192,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return whether the block changed
*/
public > boolean smartSetBlock(BlockVector3 position, B block) {
+ this.changes++;
try {
return setBlock(position, block, Stage.BEFORE_REORDER);
} catch (WorldEditException e) {
@@ -1450,8 +1595,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int fillXZ(final BlockVector3 origin, BaseBlock block, double radius, int depth, boolean recursive) throws MaxChangedBlocksException {
- return fillXZ(origin, (Pattern) block, radius, depth, recursive);
+ public > int fillXZ(BlockVector3 origin, B block, double radius, int depth, boolean recursive) throws MaxChangedBlocksException {
+ return fillXZ(origin, new BlockPattern(block), radius, depth, recursive);
}
/**
* Fills an area recursively in the X/Z directions.
@@ -1471,12 +1616,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
checkArgument(depth >= 1, "depth >= 1");
final MaskIntersection mask = new MaskIntersection(new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))), new BoundedHeightMask(Math.max(
(origin.getBlockY() - depth) + 1, getMinimumPoint().getBlockY()), Math.min(getMaximumPoint().getBlockY(), origin.getBlockY())), Masks.negate(new ExistingBlockMask(EditSession.this)));
-// MaskIntersection mask = new MaskIntersection(
-// new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))),
-// new BoundedHeightMask(
-// Math.max(origin.getBlockY() - depth + 1, 0),
-// Math.min(getWorld().getMaxY(), origin.getBlockY())),
-// Masks.negate(new ExistingBlockMask(this)));
// Want to replace blocks
BlockReplace replace = new BlockReplace(this, pattern);
@@ -1588,6 +1727,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
public boolean hasExtraExtents() {
return wrapped || getMask() != null || getSourceMask() != null || history != null;
}
+
public int removeNear(BlockVector3 position, BlockType blockType, int apothem) throws MaxChangedBlocksException {
checkNotNull(position);
checkArgument(apothem >= 1, "apothem >= 1");
@@ -1670,7 +1810,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public > int replaceBlocks(Region region, Set filter, B replacement) throws MaxChangedBlocksException {
+ public > int replaceBlocks(Region region, Set filter, B replacement) throws MaxChangedBlocksException {
return replaceBlocks(region, filter, new BlockPattern(replacement));
}
@@ -1684,8 +1824,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int replaceBlocks(Region region, Set filter, Pattern pattern) throws MaxChangedBlocksException {
- Mask mask = filter == null ? new ExistingBlockMask(this) : new BlockMaskBuilder().addBlocks(filter).build(this);
+ public int replaceBlocks(Region region, Set filter, Pattern pattern) throws MaxChangedBlocksException {
+ Mask mask = filter == null ? new ExistingBlockMask(this) : new BlockMask(this, filter);
return replaceBlocks(region, mask, pattern);
}
@@ -1887,12 +2027,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
FlatRegionVisitor visitor = new FlatRegionVisitor(asFlatRegion(region), surface, this);
Operations.completeBlindly(visitor);
return this.changes = visitor.getAffected();
-// BlockReplace replace = new BlockReplace(this, pattern);
-// RegionOffset offset = new RegionOffset(BlockVector3.at(0, 1, 0), replace);
-// GroundFunction ground = new GroundFunction(new ExistingBlockMask(this), offset);
-// LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
-// Operations.completeLegacy(visitor);
-// return ground.getAffected();
}
/**
@@ -2031,6 +2165,10 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int drainArea(final BlockVector3 origin, final double radius) {
+ return drainArea(origin, radius, false);
+ }
+
+ public int drainArea(final BlockVector3 origin, final double radius, boolean waterLogged) {
checkNotNull(origin);
checkArgument(radius >= 0, "radius >= 0 required");
Mask liquidMask;
@@ -2053,20 +2191,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
// Around the origin in a 3x3 block
for (final BlockVector3 position : CuboidRegion.fromCenter(origin, 1)) {
-// public int drainArea(BlockVector3 origin, double radius) throws MaxChangedBlocksException {
-// checkNotNull(origin);
-// checkArgument(radius >= 0, "radius >= 0 required");
-//
-// MaskIntersection mask = new MaskIntersection(
-// new BoundedHeightMask(0, getWorld().getMaxY()),
-// new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))),
-// getWorld().createLiquidMask());
-//
-// BlockReplace replace = new BlockReplace(this, new BlockPattern(BlockTypes.AIR.getDefaultState()));
-// RecursiveVisitor visitor = new RecursiveVisitor(mask, replace);
-//
-// // Around the origin in a 3x3 block
-// for (BlockVector3 position : CuboidRegion.fromCenter(origin, 1)) {
if (mask.test(position)) {
visitor.visit(position);
}
@@ -2349,7 +2473,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return number of blocks changed
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int makeSphere(final BlockVector3 pos, final Pattern block, final double radius, final boolean filled) {
+ public int makeSphere(BlockVector3 pos, Pattern block, double radius, boolean filled) {
return makeSphere(pos, block, radius, radius, radius, filled);
}
@@ -2595,7 +2719,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
*/
public int green(final BlockVector3 position, final double radius) {
return this.green(position, radius, false);
-}
+ }
+
public int green(BlockVector3 position, double radius, boolean onlyNormalDirt)
throws MaxChangedBlocksException {
int affected = 0;
@@ -2619,6 +2744,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
for (int y = maxY; y >= 1; --y) {
BlockType block = getBlockType(x, y, z);
switch (block.getResource().toUpperCase()) {
+ // TODO onlyNormalDirt
case "DIRT":
this.setBlock(x, y, z, BlockTypes.GRASS_BLOCK.getDefaultState());
break loop;
@@ -2629,26 +2755,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
if (block.getMaterial().isMovementBlocker()) {
break loop;
}
-// for (int x = ox - ceilRadius; x <= ox + ceilRadius; ++x) {
-// for (int z = oz - ceilRadius; z <= oz + ceilRadius; ++z) {
-// if ((BlockVector3.at(x, oy, z)).distanceSq(position) > radiusSq) {
-// continue;
-// }
-//
-// for (int y = world.getMaxY(); y >= 1; --y) {
-// final BlockVector3 pt = BlockVector3.at(x, y, z);
-// final BlockState block = getBlock(pt);
-//
-// if (block.getBlockType() == BlockTypes.DIRT ||
-// (!onlyNormalDirt && block.getBlockType() == BlockTypes.COARSE_DIRT)) {
-// if (setBlock(pt, grass)) {
-// ++affected;
-// }
-// break;
-// } else if (block.getBlockType() == BlockTypes.WATER || block.getBlockType() == BlockTypes.LAVA) {
-// break;
-// } else if (block.getBlockType().getMaterial().isMovementBlocker()) {
-// break;
}
}
}
@@ -2727,48 +2833,39 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
} else if (type.getMaterial().isAir()) {
continue;
}
-// public int makeForest(BlockVector3 basePosition, int size, double density, TreeGenerator.TreeType treeType) throws MaxChangedBlocksException {
-// int affected = 0;
-//
-// for (int x = basePosition.getBlockX() - size; x <= basePosition.getBlockX()
-// + size; ++x) {
-// for (int z = basePosition.getBlockZ() - size; z <= basePosition.getBlockZ()
-// + size; ++z) {
-// // Don't want to be in the ground
-// if (!getBlock(BlockVector3.at(x, basePosition.getBlockY(), z)).getBlockType().getMaterial().isAir()) {
-// continue;
-// }
-// // The gods don't want a tree here
-// if (Math.random() >= density) {
-// continue;
-// } // def 0.05
-//
-// for (int y = basePosition.getBlockY(); y >= basePosition.getBlockY() - 10; --y) {
-// // Check if we hit the ground
-// BlockType t = getBlock(BlockVector3.at(x, y, z)).getBlockType();
-// if (t == BlockTypes.GRASS_BLOCK || t == BlockTypes.DIRT) {
-// treeType.generate(this, BlockVector3.at(x, y + 1, z));
-// ++affected;
-// break;
-// } else if (t == BlockTypes.SNOW) {
-// setBlock(BlockVector3.at(x, y, z), BlockTypes.AIR.getDefaultState());
-// } else if (!t.getMaterial().isAir()) { // Trees won't grow on this!
-// break;
}
}
}
- } catch (MaxChangedBlocksException ignore) {
- }
+ } catch (MaxChangedBlocksException ignore) {}
return this.changes;
}
+ /**
+ * Makes a forest.
+ *
+ * @param region the region to generate trees in
+ * @param density between 0 and 1, inclusive
+ * @param treeType the tree type
+ * @return number of trees created
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
+ */
+ public int makeForest(Region region, double density, TreeGenerator.TreeType treeType) throws MaxChangedBlocksException {
+ ForestGenerator generator = new ForestGenerator(this, treeType);
+ GroundFunction ground = new GroundFunction(new ExistingBlockMask(this), generator);
+ LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
+ visitor.setMask(new NoiseFilter2D(new RandomNoise(), density));
+ Operations.completeLegacy(visitor);
+ return ground.getAffected();
+ }
+
/**
* Get the block distribution inside a region.
*
* @param region a region
* @return the results
*/
- public List> getBlockDistribution(final Region region) {
+ public List> getBlockDistribution(Region region, boolean separateStates) {
+ if (separateStates) return getBlockDistributionWithData(region);
int[] counter = new int[BlockTypes.size()];
if (region instanceof CuboidRegion) {
@@ -2810,10 +2907,17 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
}
/**
- * Get the block distribution (with data values) inside a region.
+ * Generate a shape for the given expression.
*
- * @param region a region
- * @return the results
+ * @param region the region to generate the shape in
+ * @param zero the coordinate origin for x/y/z variables
+ * @param unit the scale of the x/y/z/ variables
+ * @param pattern the default material to make the shape from
+ * @param expressionString the expression defining the shape
+ * @param hollow whether the shape should be hollow
+ * @return number of blocks changed
+ * @throws ExpressionException
+ * @throws MaxChangedBlocksException
*/
public List> getBlockDistributionWithData(final Region region) {
int[][] counter = new int[BlockTypes.size()][];
@@ -2884,6 +2988,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
final WorldEditExpressionEnvironment environment = new WorldEditExpressionEnvironment(this, unit, zero);
expression.setEnvironment(environment);
+ final int[] timedOut = {0};
final ArbitraryShape shape = new ArbitraryShape(region) {
@Override
public BaseBlock getMaterial(final int x, final int y, final int z, final BaseBlock defaultMaterial) {
@@ -2907,12 +3012,13 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
}
}
};
-
- try {
- return shape.generate(this, pattern, hollow);
- } catch (WorldEditException e) {
- throw new RuntimeException(e);
+ int changed = shape.generate(this, pattern, hollow);
+ if (timedOut[0] > 0) {
+ throw new ExpressionTimeoutException(
+ String.format("%d blocks changed. %d blocks took too long to evaluate (increase with //timeout).",
+ changed, timedOut[0]));
}
+ return changed;
}
public int deformRegion(final Region region, final Vector3 zero, final Vector3 unit, final String expressionString) throws ExpressionException, MaxChangedBlocksException {
@@ -2926,18 +3032,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
final Vector3 zero2 = zero.add(0.5, 0.5, 0.5);
RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() {
-// final DoubleArrayList queue = new DoubleArrayList<>(false);
-//
-// for (BlockVector3 position : region) {
-// // offset, scale
-// final Vector3 scaled = position.subtract(zero).divide(unit);
-//
-// // transform
-// expression.evaluate(scaled.getX(), scaled.getY(), scaled.getZ());
-//
-// final BlockVector3 sourcePosition = environment.toWorld(x.getValue(), y.getValue(), z.getValue());
-
- private MutableBlockVector3 mutable = new MutableBlockVector3();
+ private MutableBlockVector3 mutable = new MutableBlockVector3();
@Override
public boolean apply(BlockVector3 position) throws WorldEditException {
@@ -2956,18 +3051,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
} catch (EvaluationException e) {
throw new RuntimeException(e);
}
-// // queue operation
-// queue.put(position, material);
-// }
-//
-// int affected = 0;
-// for (Map.Entry entry : queue) {
-// BlockVector3 position = entry.getKey();
-// BaseBlock material = entry.getValue();
-//
-// // set at new position
-// if (setBlock(position, material)) {
-// ++affected;
}
}, this);
Operations.completeBlindly(visitor);
@@ -3249,9 +3332,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
return returnset;
}
- public void recurseHollow(final Region region, final BlockVector3 origin, final Set outside) {
- //TODO FIXME Optimize - avoid vector creation
- final ArrayDeque queue = new ArrayDeque<>();
+ private void recurseHollow(Region region, BlockVector3 origin, Set outside) {
+ final BlockVectorSet queue = new BlockVectorSet<>();
queue.addLast(origin);
while (!queue.isEmpty()) {
@@ -3272,10 +3354,10 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
for (BlockVector3 recurseDirection : recurseDirections) {
queue.addLast(current.add(recurseDirection));
}
- } // while
+ }
}
- public int makeBiomeShape(final Region region, final Vector3 zero, final Vector3 unit, final BaseBiome biomeType, final String expressionString, final boolean hollow) throws ExpressionException, MaxChangedBlocksException {
+ public int makeBiomeShape(final Region region, final Vector3 zero, final Vector3 unit, final BiomeType biomeType, final String expressionString, final boolean hollow) throws ExpressionException, MaxChangedBlocksException {
final Vector2 zero2D = zero.toVector2();
final Vector2 unit2D = unit.toVector2();
@@ -3288,7 +3370,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
final ArbitraryBiomeShape shape = new ArbitraryBiomeShape(region) {
@Override
- protected BaseBiome getBiome(final int x, final int z, final BaseBiome defaultBiomeType) {
+ protected BiomeType getBiome(final int x, final int z, final BiomeType defaultBiomeType) {
environment.setCurrentBlock(x, 0, z);
double scaledX = (x - zero2D.getX()) / unit2D.getX();
double scaledZ = (z - zero2D.getZ()) / unit2D.getZ();
@@ -3305,8 +3387,13 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
}
}
};
-
- return shape.generate(this, biomeType, hollow);
+ int changed = shape.generate(this, biomeType, hollow);
+ if (timedOut[0] > 0) {
+ throw new ExpressionTimeoutException(
+ String.format("%d blocks changed. %d blocks took too long to evaluate (increase time with //timeout)",
+ changed, timedOut[0]));
+ }
+ return changed;
}
private static final BlockVector3[] recurseDirections = {
Direction.NORTH.toBlockVector(),
@@ -3374,7 +3461,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
}
}
- public boolean regenerate(final Region region, final BaseBiome biome, final Long seed) {
+ public boolean regenerate(final Region region, final BiomeType biome, final Long seed) {
//TODO Optimize - avoid Vector2D creation (make mutable)
final FaweQueue queue = this.getQueue();
queue.setChangeTask(null);
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSessionFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSessionFactory.java
index 094da742e..9b288271f 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSessionFactory.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSessionFactory.java
@@ -152,21 +152,24 @@ public class EditSessionFactory {
@Override
public EditSession getEditSession(World world, int maxBlocks) {
- return new EditSession(eventBus, world, maxBlocks, null, new EditSessionEvent(world, null, maxBlocks, null));
+ return getEditSession(world, maxBlocks, null, null);
}
@Override
public EditSession getEditSession(World world, int maxBlocks, Player player) {
- return new EditSession(eventBus, world, maxBlocks, null, new EditSessionEvent(world, player, maxBlocks, null));
+ return getEditSession(world, maxBlocks, null, player);
}
@Override
public EditSession getEditSession(World world, int maxBlocks, BlockBag blockBag) {
- return new EditSession(eventBus, world, maxBlocks, blockBag, new EditSessionEvent(world, null, maxBlocks, null));
+ return getEditSession(world, maxBlocks, blockBag, null);
}
@Override
public EditSession getEditSession(World world, int maxBlocks, BlockBag blockBag, Player player) {
+ if (WorldEdit.getInstance().getConfiguration().traceUnflushedSessions) {
+ return new TracedEditSession(eventBus, world, maxBlocks, blockBag, new EditSessionEvent(world, player, maxBlocks, null));
+ }
return new EditSession(eventBus, world, maxBlocks, blockBag, new EditSessionEvent(world, player, maxBlocks, null));
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java
index d1902be8b..d88f23e4b 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java
@@ -38,6 +38,7 @@ import java.util.Set;
public abstract class LocalConfiguration {
public boolean profile = false;
+ public boolean traceUnflushedSessions = false;
public Set disallowedBlocks = new HashSet<>();
public int defaultChangeLimit = -1;
public int maxChangeLimit = -1;
@@ -65,6 +66,8 @@ public abstract class LocalConfiguration {
public String navigationWand = "minecraft:compass";
public int navigationWandMaxDistance = 50;
public int scriptTimeout = 3000;
+ public int calculationTimeout = 100;
+ public int maxCalculationTimeout = 300;
public Set allowedDataCycleBlocks = new HashSet<>();
public String saveDir = "schematics";
public String scriptsDir = "craftscripts";
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java
index a4cefa188..a1a56f980 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java
@@ -67,11 +67,16 @@ import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.snapshot.Snapshot;
-import java.io.*;
-import java.util.*;
-import java.util.concurrent.atomic.AtomicBoolean;
-import javax.annotation.Nonnull;
+
import javax.annotation.Nullable;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -118,6 +123,7 @@ public class LocalSession implements TextureHolder {
private transient Tool[] tools = new Tool[ItemTypes.size()];
private transient int maxBlocksChanged = -1;
+ private transient int maxTimeoutTime;
private transient boolean useInventory;
private transient Snapshot snapshot;
private transient boolean hasCUISupport = false;
@@ -830,6 +836,24 @@ public class LocalSession implements TextureHolder {
this.maxBlocksChanged = maxBlocksChanged;
}
+ /**
+ * Get the maximum time allowed for certain executions to run before cancelling them, such as expressions.
+ *
+ * @return timeout time, in milliseconds
+ */
+ public int getTimeout() {
+ return maxTimeoutTime;
+ }
+
+ /**
+ * Set the maximum number of blocks that can be changed.
+ *
+ * @param timeout the time, in milliseconds, to limit certain executions to, or -1 to disable
+ */
+ public void setTimeout(int timeout) {
+ this.maxTimeoutTime = timeout;
+ }
+
/**
* Checks whether the super pick axe is enabled.
*
@@ -1260,7 +1284,7 @@ public class LocalSession implements TextureHolder {
String msg = e.getMessage();
if (msg != null && msg.length() > 256) msg = msg.substring(0, 256);
this.failedCuiAttempts++;
- WorldEdit.logger.warning("Error while reading CUI init message for player " + uuid + ": " + msg);
+ WorldEdit.logger.warn("Error while reading CUI init message for player " + uuid + ": " + msg);
}
}
@@ -1375,6 +1399,24 @@ public class LocalSession implements TextureHolder {
this.fastMode = fastMode;
}
+ /**
+ * Gets the reorder mode of the session.
+ *
+ * @return The reorder mode
+ */
+ public EditSession.ReorderMode getReorderMode() {
+ return reorderMode;
+ }
+
+ /**
+ * Sets the reorder mode of the session.
+ *
+ * @param reorderMode The reorder mode
+ */
+ public void setReorderMode(EditSession.ReorderMode reorderMode) {
+ this.reorderMode = reorderMode;
+ }
+
/**
* Get the mask.
*
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/TracedEditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/TracedEditSession.java
new file mode 100644
index 000000000..9832d084d
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/TracedEditSession.java
@@ -0,0 +1,45 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit;
+
+import com.sk89q.worldedit.event.extent.EditSessionEvent;
+import com.sk89q.worldedit.extent.inventory.BlockBag;
+import com.sk89q.worldedit.util.eventbus.EventBus;
+import com.sk89q.worldedit.world.World;
+
+public class TracedEditSession extends EditSession {
+
+ TracedEditSession(EventBus eventBus, World world, int maxBlocks, BlockBag blockBag, EditSessionEvent event) {
+ super(eventBus, world, maxBlocks, blockBag, event);
+ }
+
+ private final Throwable stacktrace = new Throwable("Creation trace.");
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+
+ if (commitRequired()) {
+ WorldEdit.logger.warn("####### LEFTOVER BUFFER BLOCKS DETECTED #######");
+ WorldEdit.logger.warn("This means that some code did not flush their EditSession.");
+ WorldEdit.logger.warn("Here is a stacktrace from the creation of this EditSession:", stacktrace);
+ }
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java
index 3ec352d07..2404d8f2a 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java
@@ -37,15 +37,11 @@ import com.sk89q.worldedit.extension.platform.PlatformManager;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.Pattern;
-import com.sk89q.worldedit.internal.expression.Expression;
-import com.sk89q.worldedit.internal.expression.runtime.Constant;
-import com.sk89q.worldedit.internal.expression.runtime.RValue;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.scripting.CraftScriptContext;
import com.sk89q.worldedit.scripting.CraftScriptEngine;
import com.sk89q.worldedit.scripting.RhinoCraftScriptEngine;
import com.sk89q.worldedit.session.SessionManager;
-import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.eventbus.EventBus;
@@ -53,7 +49,6 @@ import com.sk89q.worldedit.util.io.file.FileSelectionAbortedException;
import com.sk89q.worldedit.util.io.file.FilenameException;
import com.sk89q.worldedit.util.io.file.FilenameResolutionException;
import com.sk89q.worldedit.util.io.file.InvalidFilenameException;
-import com.sk89q.worldedit.util.logging.WorldEditPrefixHandler;
import com.sk89q.worldedit.util.task.SimpleSupervisor;
import com.sk89q.worldedit.util.task.Supervisor;
import com.sk89q.worldedit.world.block.BlockStateHolder;
@@ -61,6 +56,8 @@ import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import com.sk89q.worldedit.world.registry.BundledItemData;
import com.sk89q.worldedit.world.registry.LegacyMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import javax.script.ScriptException;
@@ -97,9 +94,9 @@ import static com.sk89q.worldedit.event.platform.Interaction.OPEN;
*/
public final class WorldEdit {
- public static final Logger logger = Logger.getLogger(WorldEdit.class.getCanonicalName());
+ public static final Logger logger = LoggerFactory.getLogger(WorldEdit.class);
- private final static WorldEdit instance = new WorldEdit();
+ private static final WorldEdit instance = new WorldEdit();
private static String version;
private final EventBus eventBus = new EventBus();
@@ -114,7 +111,6 @@ public final class WorldEdit {
private final PatternFactory patternFactory = new PatternFactory(this);
static {
- WorldEditPrefixHandler.register("com.sk89q.worldedit");
getVersion();
}
@@ -670,16 +666,16 @@ public final class WorldEdit {
} catch (ScriptException e) {
player.printError("Failed to execute:");
player.printRaw(e.getMessage());
- logger.log(Level.WARNING, "Failed to execute script", e);
+ logger.warn("Failed to execute script", e);
} catch (NumberFormatException | WorldEditException e) {
throw e;
} catch (Throwable e) {
player.printError("Failed to execute (see console):");
player.printRaw(e.getClass().getCanonicalName());
- logger.log(Level.WARNING, "Failed to execute script", e);
+ logger.warn("Failed to execute script", e);
} finally {
for (EditSession editSession : scriptContext.getEditSessions()) {
- editSession.flushQueue();
+ editSession.flushSession();
session.remember(editSession);
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java
index 47283f582..c4dc6dac8 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java
@@ -27,6 +27,8 @@ import com.sk89q.worldedit.world.item.ItemTypes;
import javax.annotation.Nullable;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* Represents an item, without an amount value. See {@link BaseItemStack}
* for an instance with stack amount information.
@@ -34,7 +36,7 @@ import javax.annotation.Nullable;
* This class may be removed in the future.
*/
public class BaseItem implements NbtValued {
-
+
private ItemType itemType;
@Nullable
private CompoundTag nbtData;
@@ -45,6 +47,7 @@ public class BaseItem implements NbtValued {
* @param itemType Type of the item
*/
public BaseItem(ItemType itemType) {
+ checkNotNull(itemType);
this.itemType = itemType;
}
@@ -54,7 +57,8 @@ public class BaseItem implements NbtValued {
* @param itemType Type of the item
* @param tag NBT Compound tag
*/
- public BaseItem(ItemType itemType, CompoundTag tag) {
+ public BaseItem(ItemType itemType, @Nullable CompoundTag tag) {
+ checkNotNull(itemType);
this.itemType = itemType;
this.nbtData = tag;
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/Blocks.java b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/Blocks.java
index 83ebddc85..1f65c6a19 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/Blocks.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/Blocks.java
@@ -19,14 +19,13 @@
package com.sk89q.worldedit.blocks;
-import com.sk89q.worldedit.world.block.BlockCategories;
+import com.google.common.collect.Maps;
+import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
-import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.Map;
/**
* Block-related utility methods.
@@ -36,143 +35,6 @@ public final class Blocks {
private Blocks() {
}
- /**
- * HashSet for shouldPlaceLate.
- */
- private static final Set shouldPlaceLate = new HashSet<>();
- static {
- shouldPlaceLate.add(BlockTypes.WATER);
- shouldPlaceLate.add(BlockTypes.LAVA);
- shouldPlaceLate.add(BlockTypes.GRAVEL);
- shouldPlaceLate.add(BlockTypes.SAND);
- }
- /**
- * Checks to see whether a block should be placed in the final queue.
- *
- * This applies to blocks that can be attached to other blocks that have an attachment.
- *
- * @param type the type of the block
- * @return whether the block is in the late queue
- */
- public static boolean shouldPlaceLate(BlockType type) {
- return shouldPlaceLate.contains(type);
- }
-
- /**
- * HashSet for shouldPlaceLast.
- */
- private static final Set shouldPlaceLast = new HashSet<>();
- static {
- shouldPlaceLast.addAll(BlockCategories.SAPLINGS.getAll());
- shouldPlaceLast.addAll(BlockCategories.FLOWER_POTS.getAll());
- shouldPlaceLast.addAll(BlockCategories.BUTTONS.getAll());
- shouldPlaceLast.addAll(BlockCategories.ANVIL.getAll()); // becomes relevant with asynchronous placement
- shouldPlaceLast.addAll(BlockCategories.WOODEN_PRESSURE_PLATES.getAll());
- shouldPlaceLast.addAll(BlockCategories.CARPETS.getAll());
- shouldPlaceLast.addAll(BlockCategories.RAILS.getAll());
- shouldPlaceLast.add(BlockTypes.BLACK_BED);
- shouldPlaceLast.add(BlockTypes.BLUE_BED);
- shouldPlaceLast.add(BlockTypes.BROWN_BED);
- shouldPlaceLast.add(BlockTypes.CYAN_BED);
- shouldPlaceLast.add(BlockTypes.GRAY_BED);
- shouldPlaceLast.add(BlockTypes.GREEN_BED);
- shouldPlaceLast.add(BlockTypes.LIGHT_BLUE_BED);
- shouldPlaceLast.add(BlockTypes.LIGHT_GRAY_BED);
- shouldPlaceLast.add(BlockTypes.LIME_BED);
- shouldPlaceLast.add(BlockTypes.MAGENTA_BED);
- shouldPlaceLast.add(BlockTypes.ORANGE_BED);
- shouldPlaceLast.add(BlockTypes.PINK_BED);
- shouldPlaceLast.add(BlockTypes.PURPLE_BED);
- shouldPlaceLast.add(BlockTypes.RED_BED);
- shouldPlaceLast.add(BlockTypes.WHITE_BED);
- shouldPlaceLast.add(BlockTypes.YELLOW_BED);
- shouldPlaceLast.add(BlockTypes.GRASS);
- shouldPlaceLast.add(BlockTypes.TALL_GRASS);
- shouldPlaceLast.add(BlockTypes.ROSE_BUSH);
- shouldPlaceLast.add(BlockTypes.DANDELION);
- shouldPlaceLast.add(BlockTypes.BROWN_MUSHROOM);
- shouldPlaceLast.add(BlockTypes.RED_MUSHROOM);
- shouldPlaceLast.add(BlockTypes.FERN);
- shouldPlaceLast.add(BlockTypes.LARGE_FERN);
- shouldPlaceLast.add(BlockTypes.OXEYE_DAISY);
- shouldPlaceLast.add(BlockTypes.AZURE_BLUET);
- shouldPlaceLast.add(BlockTypes.TORCH);
- shouldPlaceLast.add(BlockTypes.WALL_TORCH);
- shouldPlaceLast.add(BlockTypes.FIRE);
- shouldPlaceLast.add(BlockTypes.REDSTONE_WIRE);
- shouldPlaceLast.add(BlockTypes.CARROTS);
- shouldPlaceLast.add(BlockTypes.POTATOES);
- shouldPlaceLast.add(BlockTypes.WHEAT);
- shouldPlaceLast.add(BlockTypes.BEETROOTS);
- shouldPlaceLast.add(BlockTypes.COCOA);
- shouldPlaceLast.add(BlockTypes.LADDER);
- shouldPlaceLast.add(BlockTypes.LEVER);
- shouldPlaceLast.add(BlockTypes.REDSTONE_TORCH);
- shouldPlaceLast.add(BlockTypes.REDSTONE_WALL_TORCH);
- shouldPlaceLast.add(BlockTypes.SNOW);
- shouldPlaceLast.add(BlockTypes.NETHER_PORTAL);
- shouldPlaceLast.add(BlockTypes.END_PORTAL);
- shouldPlaceLast.add(BlockTypes.REPEATER);
- shouldPlaceLast.add(BlockTypes.VINE);
- shouldPlaceLast.add(BlockTypes.LILY_PAD);
- shouldPlaceLast.add(BlockTypes.NETHER_WART);
- shouldPlaceLast.add(BlockTypes.PISTON);
- shouldPlaceLast.add(BlockTypes.STICKY_PISTON);
- shouldPlaceLast.add(BlockTypes.TRIPWIRE_HOOK);
- shouldPlaceLast.add(BlockTypes.TRIPWIRE);
- shouldPlaceLast.add(BlockTypes.STONE_PRESSURE_PLATE);
- shouldPlaceLast.add(BlockTypes.HEAVY_WEIGHTED_PRESSURE_PLATE);
- shouldPlaceLast.add(BlockTypes.LIGHT_WEIGHTED_PRESSURE_PLATE);
- shouldPlaceLast.add(BlockTypes.COMPARATOR);
- shouldPlaceLast.add(BlockTypes.IRON_TRAPDOOR);
- shouldPlaceLast.add(BlockTypes.ACACIA_TRAPDOOR);
- shouldPlaceLast.add(BlockTypes.BIRCH_TRAPDOOR);
- shouldPlaceLast.add(BlockTypes.DARK_OAK_TRAPDOOR);
- shouldPlaceLast.add(BlockTypes.JUNGLE_TRAPDOOR);
- shouldPlaceLast.add(BlockTypes.OAK_TRAPDOOR);
- shouldPlaceLast.add(BlockTypes.SPRUCE_TRAPDOOR);
- shouldPlaceLast.add(BlockTypes.DAYLIGHT_DETECTOR);
- }
-
- /**
- * Checks to see whether a block should be placed last (when reordering
- * blocks that are placed).
- *
- * @param type the block type
- * @return true if the block should be placed last
- */
- public static boolean shouldPlaceLast(BlockType type) {
- return shouldPlaceLast.contains(type);
- }
-
- /**
- * HashSet for shouldPlaceLast.
- */
- private static final Set shouldPlaceFinal = new HashSet<>();
- static {
- shouldPlaceFinal.addAll(BlockCategories.DOORS.getAll());
- shouldPlaceFinal.addAll(BlockCategories.BANNERS.getAll());
- shouldPlaceFinal.add(BlockTypes.SIGN);
- shouldPlaceFinal.add(BlockTypes.WALL_SIGN);
- shouldPlaceFinal.add(BlockTypes.CACTUS);
- shouldPlaceFinal.add(BlockTypes.SUGAR_CANE);
- shouldPlaceFinal.add(BlockTypes.CAKE);
- shouldPlaceFinal.add(BlockTypes.PISTON_HEAD);
- shouldPlaceFinal.add(BlockTypes.MOVING_PISTON);
- }
-
- /**
- * Checks to see whether a block should be placed in the final queue.
- *
- * This applies to blocks that can be attached to other blocks that have an attachment.
- *
- * @param type the type of the block
- * @return whether the block is in the final queue
- */
- public static boolean shouldPlaceFinal(BlockType type) {
- return shouldPlaceFinal.contains(type);
- }
-
/**
* Checks whether a given block is in a list of base blocks.
*
@@ -190,4 +52,28 @@ public final class Blocks {
return false;
}
+ /**
+ * Parses a string->string map to find the matching Property and values for the given BlockType.
+ *
+ * @param states the desired states and values
+ * @param type the block type to get properties and values for
+ * @return a property->value map
+ */
+ public static Map, Object> resolveProperties(Map states, BlockType type) {
+ Map> existing = type.getPropertyMap();
+ Map, Object> newMap = Maps.newHashMap();
+ states.forEach((key, value) -> {
+ @SuppressWarnings("unchecked")
+ Property prop = (Property) existing.get(key);
+ if (prop == null) return;
+ Object val = null;
+ try {
+ val = prop.getValueFor(value);
+ } catch (IllegalArgumentException ignored) {
+ }
+ if (val == null) return;
+ newMap.put(prop, val);
+ });
+ return newMap;
+ }
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java
index 8c14f4614..2bffb1ac6 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java
@@ -53,15 +53,17 @@ import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.command.binding.Switch;
import com.sk89q.worldedit.world.World;
-import com.sk89q.worldedit.world.biome.BaseBiome;
+import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeData;
+import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
+
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
-
-
-import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION;
+import java.util.Set;
/**
* Implements biome-related commands such as "/biomelist".
@@ -102,11 +104,11 @@ public class BiomeCommands extends MethodCommands {
}
BiomeRegistry biomeRegistry = getBiomeRegistry();
- List biomes = biomeRegistry.getBiomes();
+ List biomes = biomeRegistry.getBiomes();
int totalPages = biomes.size() / 19 + 1;
Message msg = BBC.BIOME_LIST_HEADER.m(page, totalPages);
String setBiome = Commands.getAlias(BiomeCommands.class, "/setbiome");
- for (BaseBiome biome : biomes) {
+ for (BiomeType biome : biomes) {
if (offset > 0) {
offset--;
} else {
@@ -150,12 +152,12 @@ public class BiomeCommands extends MethodCommands {
return;
}
- BaseBiome biome = player.getWorld().getBiome(blockPosition.toBlockPoint().toBlockVector2());
- biomes[biome.getId()]++;
+ BiomeType biome = player.getWorld().getBiome(blockPosition.toBlockPoint().toBlockVector2());
+ biomes[biome.getInternalId()]++;
size = 1;
} else if (args.hasFlag('p')) {
- BaseBiome biome = player.getWorld().getBiome(player.getLocation().toBlockPoint().toBlockVector2());
- biomes[biome.getId()]++;
+ BiomeType biome = player.getWorld().getBiome(player.getLocation().toBlockPoint().toBlockVector2());
+ biomes[biome.getInternalId()]++;
size = 1;
} else {
World world = player.getWorld();
@@ -181,15 +183,15 @@ public class BiomeCommands extends MethodCommands {
BBC.BIOME_LIST_HEADER.send(player, 1, 1);
- List> distribution = new ArrayList<>();
+ List> distribution = new ArrayList<>();
for (int i = 0; i < biomes.length; i++) {
int count = biomes[i];
if (count != 0) {
- distribution.add(new Countable<>(new BaseBiome(i), count));
+ distribution.add(new Countable<>(new BiomeType(i), count));
}
}
Collections.sort(distribution);
- for (Countable c : distribution) {
+ for (Countable c : distribution) {
BiomeData data = biomeRegistry.getData(c.getID());
String str = String.format("%-7s (%.3f%%) %s #%d",
String.valueOf(c.getAmount()),
@@ -212,7 +214,7 @@ public class BiomeCommands extends MethodCommands {
)
@Logging(REGION)
@CommandPermissions("worldedit.biome.set")
- public void setBiome(Player player, LocalSession session, EditSession editSession, BaseBiome target, @Switch('p') boolean atPosition) throws WorldEditException {
+ public void setBiome(Player player, LocalSession session, EditSession editSession, BiomeType target, @Switch('p') boolean atPosition) throws WorldEditException {
World world = player.getWorld();
Region region;
Mask mask = editSession.getMask();
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java
index 030395cb1..9559d35e1 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java
@@ -37,8 +37,6 @@ import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.Step;
-import com.sk89q.worldedit.*;
-import com.sk89q.worldedit.command.tool.brush.*;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
@@ -633,7 +631,7 @@ public class BrushCommands extends BrushProcessor {
)
@CommandPermissions("worldedit.brush.smooth")
public BrushSettings smoothBrush(Player player, LocalSession session, EditSession editSession,
- @Optional("2") Expression radius, @Optional("4") int iterations, CommandContext context) throws WorldEditException {
+ @Optional("2") Expression radius, @Optional("4") int iterations, @Optional Mask mask, CommandContext context) throws WorldEditException {
getWorldEdit().checkMaxBrushRadius(radius);
@@ -642,7 +640,7 @@ public class BrushCommands extends BrushProcessor {
iterations = Math.min(limit.MAX_ITERATIONS, iterations);
return set(session, context,
- new SmoothBrush(iterations))
+ new SmoothBrush(iterations, mask))
.setSize(radius);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java
index 542aef756..91c4c9684 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java
@@ -21,7 +21,6 @@ package com.sk89q.worldedit.command;
import com.boydti.fawe.config.BBC;
import com.sk89q.minecraft.util.commands.Command;
-import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.Logging;
import com.sk89q.worldedit.EditSession;
@@ -106,7 +105,7 @@ public class ChunkCommands {
)
@CommandPermissions("worldedit.delchunks")
@Logging(REGION)
- public void deleteChunks(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+ public void deleteChunks(Player player, LocalSession session) throws WorldEditException {
player.print(BBC.getPrefix() + "Note that this command does not yet support the mcregion format.");
LocalConfiguration config = worldEdit.getConfiguration();
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java
index d5e63ba85..b8fe7c06f 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java
@@ -579,7 +579,7 @@ public class ClipboardCommands extends MethodCommands {
max = 1
)
@CommandPermissions("worldedit.clipboard.flip")
- public void flip(Player player, LocalSession session, EditSession editSession,
+ public void flip(Player player, LocalSession session,
@Optional(Direction.AIM) @Direction BlockVector3 direction) throws WorldEditException {
ClipboardHolder holder = session.getClipboard();
AffineTransform transform = new AffineTransform();
@@ -597,7 +597,7 @@ public class ClipboardCommands extends MethodCommands {
max = 0
)
@CommandPermissions("worldedit.clipboard.clear")
- public void clearClipboard(Player player, LocalSession session, EditSession editSession) throws WorldEditException {
+ public void clearClipboard(Player player, LocalSession session) throws WorldEditException {
session.setClipboard(null);
BBC.CLIPBOARD_CLEARED.send(player);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/FlattenedClipboardTransform.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/FlattenedClipboardTransform.java
index 01784ee81..83780a342 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/FlattenedClipboardTransform.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/FlattenedClipboardTransform.java
@@ -26,8 +26,6 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operation;
-import com.sk89q.worldedit.math.BlockVector3;
-import com.sk89q.worldedit.math.MutableVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.math.transform.CombinedTransform;
@@ -96,20 +94,18 @@ public class FlattenedClipboardTransform {
MutableVector3 newMinimum = new MutableVector3(corners[0]);
MutableVector3 newMaximum = new MutableVector3(corners[0]);
-// MutableVector3 cbv = new MutableVector3();
for (int i = 1; i < corners.length; i++) {
- MutableVector3 cbv = new MutableVector3(corners[i]);
+ Vector3 cbv = corners[i];
newMinimum = newMinimum.setComponents(newMinimum.getMinimum(cbv));
newMaximum = newMaximum.setComponents(newMaximum.getMaximum(cbv));
}
// After transformation, the points may not really sit on a block,
// so we should expand the region for edge cases
- newMinimum.mutX(Math.ceil(Math.floor(newMinimum.getX())));
- newMinimum.mutY(Math.ceil(Math.floor(newMinimum.getY())));
- newMinimum.mutZ(Math.ceil(Math.floor(newMinimum.getZ())));
+ newMinimum = newMinimum.floor();
+ newMaximum = newMaximum.ceil();
- return new CuboidRegion(BlockVector3.at(newMinimum.getX(), newMinimum.getY(), newMinimum.getZ()), BlockVector3.at(newMaximum.getX(), newMaximum.getY(), newMaximum.getZ()));
+ return new CuboidRegion(newMinimum.toBlockPoint(), newMaximum.toBlockPoint());
}
/**
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java
index c2754a935..acb8e4970 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java
@@ -59,7 +59,7 @@ public class GeneralCommands {
max = 1
)
@CommandPermissions("worldedit.limit")
- public void limit(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
+ public void limit(Player player, LocalSession session, CommandContext args) throws WorldEditException {
LocalConfiguration config = worldEdit.getConfiguration();
boolean mayDisable = player.hasPermission("worldedit.limit.unrestricted");
@@ -74,13 +74,43 @@ public class GeneralCommands {
session.setBlockChangeLimit(limit);
- if (limit != -1) {
- player.print("Block change limit set to " + limit + ". (Use //limit -1 to go back to the default.)");
+ if (limit != config.defaultChangeLimit) {
+ player.print("Block change limit set to " + limit + ". (Use //limit to go back to the default.)");
} else {
player.print("Block change limit set to " + limit + ".");
}
}
+ @Command(
+ aliases = { "/timeout" },
+ usage = "[time]",
+ desc = "Modify evaluation timeout time.",
+ min = 0,
+ max = 1
+ )
+ @CommandPermissions("worldedit.timeout")
+ public void timeout(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+
+ LocalConfiguration config = worldEdit.getConfiguration();
+ boolean mayDisable = player.hasPermission("worldedit.timeout.unrestricted");
+
+ int limit = args.argsLength() == 0 ? config.calculationTimeout : Math.max(-1, args.getInteger(0));
+ if (!mayDisable && config.maxCalculationTimeout > -1) {
+ if (limit > config.maxCalculationTimeout) {
+ player.printError("Your maximum allowable timeout is " + config.maxCalculationTimeout + " ms.");
+ return;
+ }
+ }
+
+ session.setTimeout(limit);
+
+ if (limit != config.calculationTimeout) {
+ player.print("Timeout time set to " + limit + " ms. (Use //timeout to go back to the default.)");
+ } else {
+ player.print("Timeout time set to " + limit + " ms.");
+ }
+ }
+
@Command(
aliases = { "/fast" },
usage = "[on|off]",
@@ -89,7 +119,7 @@ public class GeneralCommands {
max = 1
)
@CommandPermissions("worldedit.fast")
- public void fast(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
+ public void fast(Player player, LocalSession session, CommandContext args) throws WorldEditException {
String newState = args.getString(0, null);
if (session.hasFastMode()) {
@@ -111,6 +141,41 @@ public class GeneralCommands {
}
}
+ @Command(
+ aliases = { "/drawsel" },
+ usage = "[on|off]",
+ desc = "Toggle drawing the current selection",
+ min = 0,
+ max = 1
+ )
+ @CommandPermissions("worldedit.drawsel")
+ public void drawSelection(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+
+ if (!WorldEdit.getInstance().getConfiguration().serverSideCUI) {
+ throw new DisallowedUsageException("This functionality is disabled in the configuration!");
+ }
+ String newState = args.getString(0, null);
+ if (session.shouldUseServerCUI()) {
+ if ("on".equals(newState)) {
+ player.printError("Server CUI already enabled.");
+ return;
+ }
+
+ session.setUseServerCUI(false);
+ session.updateServerCUI(player);
+ player.print("Server CUI disabled.");
+ } else {
+ if ("off".equals(newState)) {
+ player.printError("Server CUI already disabled.");
+ return;
+ }
+
+ session.setUseServerCUI(true);
+ session.updateServerCUI(player);
+ player.print("Server CUI enabled. This only supports cuboid regions, with a maximum size of 32x32x32.");
+ }
+ }
+
@Command(
aliases = { "/gmask", "gmask" },
usage = "[mask]",
@@ -119,7 +184,7 @@ public class GeneralCommands {
max = -1
)
@CommandPermissions("worldedit.global-mask")
- public void gmask(Player player, LocalSession session, EditSession editSession, @Optional Mask mask) throws WorldEditException {
+ public void gmask(Player player, LocalSession session, @Optional Mask mask) throws WorldEditException {
if (mask == null) {
session.setMask((Mask) null);
player.print("Global mask disabled.");
@@ -136,7 +201,7 @@ public class GeneralCommands {
min = 0,
max = 0
)
- public void togglePlace(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
+ public void togglePlace(Player player, LocalSession session) throws WorldEditException {
if (session.togglePlacementPosition()) {
player.print("Now placing at pos #1.");
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java
index 3e76b61c4..de77d60bb 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java
@@ -54,19 +54,7 @@ import com.sk89q.worldedit.util.command.binding.Range;
import com.sk89q.worldedit.util.command.binding.Switch;
import com.sk89q.worldedit.util.command.binding.Text;
import com.sk89q.worldedit.util.command.parametric.Optional;
-import com.sk89q.worldedit.util.command.parametric.ParameterException;
-import com.sk89q.worldedit.world.biome.BaseBiome;
-import com.sk89q.worldedit.world.block.BlockType;
-
-import java.awt.RenderingHints;
-import java.awt.image.BufferedImage;
-import java.io.IOException;
-import java.net.URL;
-
-
-import static com.sk89q.minecraft.util.commands.Logging.LogMode.ALL;
-import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT;
-import static com.sk89q.minecraft.util.commands.Logging.LogMode.POSITION;
+import com.sk89q.worldedit.world.biome.BiomeType;
/**
* Commands for the generation of shapes and other objects.
@@ -287,7 +275,7 @@ public class GenerationCommands extends MethodCommands {
@CommandPermissions("worldedit.generation.forest")
@Logging(POSITION)
@SuppressWarnings("deprecation")
- public void forestGen(Player player, LocalSession session, EditSession editSession, @Optional("10") int size, @Optional("tree") TreeType type, @Optional("5") double density) throws WorldEditException, ParameterException {
+ public void forestGen(Player player, LocalSession session, EditSession editSession, @Optional("10") int size, @Optional("tree") TreeType type, @Optional("5") @Range(min = 0, max = 100) double density) throws WorldEditException, ParameterException {
density = density / 100;
int affected = editSession.makeForest(session.getPlacementPosition(player), size, density, type);
player.print(BBC.getPrefix() + affected + " trees created.");
@@ -430,16 +418,16 @@ public class GenerationCommands extends MethodCommands {
min = 2,
max = -1
)
- @CommandPermissions({"worldedit.generation.shape", "worldedit.biome.set"})
+ @CommandPermissions("worldedit.generation.shape.biome")
@Logging(ALL)
public void generateBiome(FawePlayer fp, Player player, LocalSession session, EditSession editSession,
@Selection Region region,
- BaseBiome target,
+ BiomeType target,
@Text String expression,
@Switch('h') boolean hollow,
@Switch('r') boolean useRawCoords,
@Switch('o') boolean offset,
- @Switch('c') boolean offsetCenter, CommandContext context) throws WorldEditException {
+ @Switch('c') boolean offsetCenter) throws WorldEditException {
final Vector3 zero;
Vector3 unit;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java
index af5716eb4..a545e2513 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java
@@ -265,7 +265,6 @@ public class HistoryCommands extends MethodCommands {
)
@CommandPermissions("worldedit.history.redo")
public void redo(Player player, LocalSession session, CommandContext args) throws WorldEditException {
-
int times = Math.max(1, args.getInteger(0, 1));
EditSession redone = null;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/NavigationCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/NavigationCommands.java
index af2d20284..91c0c29a3 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/NavigationCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/NavigationCommands.java
@@ -27,7 +27,6 @@ import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.Logging;
import com.sk89q.worldedit.LocalConfiguration;
-import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Player;
@@ -134,7 +133,7 @@ public class NavigationCommands {
)
@CommandPermissions("worldedit.navigation.ceiling")
@Logging(POSITION)
- public void ceiling(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+ public void ceiling(Player player, CommandContext args) throws WorldEditException {
final int clearance = args.argsLength() > 0 ?
Math.max(0, args.getInteger(0)) : 0;
@@ -155,7 +154,7 @@ public class NavigationCommands {
max = 0
)
@CommandPermissions("worldedit.navigation.thru.command")
- public void thru(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+ public void thru(Player player) throws WorldEditException {
if (player.passThroughForwardWall(6)) {
BBC.WHOOSH.send(player);
} else {
@@ -207,7 +206,7 @@ public class NavigationCommands {
)
@CommandPermissions("worldedit.navigation.up")
@Logging(POSITION)
- public void up(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+ public void up(Player player, CommandContext args) throws WorldEditException {
final int distance = args.getInteger(0);
final boolean alwaysGlass = getAlwaysGlass(args);
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java
index 64d3f250c..5d6774da6 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java
@@ -53,7 +53,6 @@ import com.sk89q.worldedit.function.visitor.LayerVisitor;
import com.sk89q.worldedit.internal.annotation.Direction;
import com.sk89q.worldedit.internal.annotation.Selection;
import com.sk89q.worldedit.internal.expression.ExpressionException;
-import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.convolution.GaussianKernel;
@@ -67,10 +66,6 @@ import com.sk89q.worldedit.util.command.binding.Range;
import com.sk89q.worldedit.util.command.binding.Switch;
import com.sk89q.worldedit.util.command.binding.Text;
import com.sk89q.worldedit.util.command.parametric.Optional;
-import com.sk89q.worldedit.world.biome.BaseBiome;
-import com.sk89q.worldedit.world.biome.Biomes;
-import com.sk89q.worldedit.world.block.BlockStateHolder;
-import com.sk89q.worldedit.world.registry.BiomeRegistry;
import java.util.ArrayList;
import java.util.Iterator;
@@ -454,20 +449,19 @@ public class RegionCommands extends MethodCommands {
}
@Command(
- aliases = {"/smooth"},
- usage = "[iterations]",
- flags = "n",
- desc = "Smooth the elevation in the selection",
- help =
- "Smooths the elevation in the selection.\n" +
- "The -n flag makes it only consider naturally occuring blocks.\n" +
- "The -s flag makes it only consider snow.",
- min = 0,
- max = 2
+ aliases = { "/smooth" },
+ usage = "[iterations] [filter]",
+ desc = "Smooth the elevation in the selection",
+ help =
+ "Smooths the elevation in the selection.\n" +
+ "Optionally, restricts the height map to a set of blocks specified with mask syntax.\n" +
+ "For example, '//smooth 1 grass_block,dirt,stone' would only smooth natural surface terrain.",
+ min = 0,
+ max = 2
)
@CommandPermissions("worldedit.region.smoothsnow")
@Logging(REGION)
- public void smooth(FawePlayer player, EditSession editSession, @Selection Region region, @Optional("1") int iterations, @Switch('n') boolean affectNatural, @Switch('s') boolean snow, CommandContext context) throws WorldEditException {
+ public void smooth(FawePlayer player, EditSession editSession, @Selection Region region, @Optional("1") int iterations, @Optional Mask mask, @Switch('s') boolean snow, 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));
@@ -477,8 +471,8 @@ public class RegionCommands extends MethodCommands {
}
player.checkConfirmationRegion(() -> {
try {
- HeightMap heightMap = new HeightMap(editSession, region, affectNatural, snow);
- HeightMapFilter filter = (HeightMapFilter) HeightMapFilter.class.getConstructors()[0].newInstance(GaussianKernel.class.getConstructors()[0].newInstance(5, 1));
+ HeightMap heightMap = new HeightMap(editSession, region, mask, snow);
+ HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1.0));
int affected = heightMap.applyFilter(filter, iterations);
BBC.VISITOR_BLOCK.send(player, affected);
} catch (Throwable e) {
@@ -523,7 +517,7 @@ public class RegionCommands extends MethodCommands {
@Command(
aliases = {"/move"},
usage = "[count] [direction] [leave-id]",
- flags = "s",
+ flags = "sbea",
desc = "Move the contents of the selection",
help =
"Moves the contents of the selection.\n" +
@@ -707,10 +701,10 @@ public class RegionCommands extends MethodCommands {
Mask sourceMask = session.getSourceMask();
session.setMask((Mask) null);
session.setSourceMask((Mask) null);
- BaseBiome biome = null;
+ BiomeType biome = null;
if (context.argsLength() >= 1) {
BiomeRegistry biomeRegistry = worldEdit.getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBiomeRegistry();
- List knownBiomes = biomeRegistry.getBiomes();
+ List knownBiomes = biomeRegistry.getBiomes();
biome = Biomes.findBiomeByName(knownBiomes, context.getString(0), biomeRegistry);
}
Long seed = context.argsLength() != 2 || !MathMan.isInteger(context.getString(1)) ? null : Long.parseLong(context.getString(1));
@@ -766,19 +760,10 @@ public class RegionCommands extends MethodCommands {
)
@CommandPermissions("worldedit.region.forest")
@Logging(REGION)
- public void forest(FawePlayer player, EditSession editSession, @Selection Region region, @Optional("tree") TreeType type,
- @Optional("5") @Range(min = 0, max = 100) double density,
- CommandContext context) throws WorldEditException {
- player.checkConfirmationRegion(() -> {
- ForestGenerator generator = new ForestGenerator(editSession, type);
- GroundFunction ground = new GroundFunction(new ExistingBlockMask(editSession), generator);
- LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
- visitor.setMask(new NoiseFilter2D(new RandomNoise(), density / 100));
- Operations.completeLegacy(visitor);
-
- BBC.COMMAND_TREE.send(player, ground.getAffected());
- }, getArguments(context), region, context);
-
+ public void forest(Player player, EditSession editSession, @Selection Region region, @Optional("tree") TreeType type,
+ @Optional("5") @Range(min = 0, max = 100) double density) throws WorldEditException {
+ int affected = editSession.makeForest(region, density / 100, type);
+ player.print(affected + " trees created.");
}
@Command(
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java
index 2ce053148..1392e22af 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java
@@ -32,6 +32,7 @@ import com.boydti.fawe.object.schematic.StructureFormat;
import com.boydti.fawe.object.schematic.visualizer.SchemVis;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.chat.Message;
+import com.google.common.collect.Multimap;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
@@ -55,23 +56,30 @@ import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.command.binding.Switch;
import com.sk89q.worldedit.util.command.parametric.Optional;
import com.sk89q.worldedit.util.io.file.FilenameException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
-import java.io.*;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
-import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.Files;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
import java.util.concurrent.atomic.LongAdder;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import java.util.regex.Pattern;
-
-import static com.boydti.fawe.util.ReflectionUtils.as;
+import static com.google.common.base.Preconditions.checkNotNull;
/**
* Commands that work with schematic files.
@@ -79,7 +87,12 @@ import static com.boydti.fawe.util.ReflectionUtils.as;
@Command(aliases = {"schematic", "schem", "/schematic", "/schem", "clipboard", "/clipboard"}, desc = "Commands that work with schematic files")
public class SchematicCommands extends MethodCommands {
- private static final Logger log = Logger.getLogger(SchematicCommands.class.getCanonicalName());
+ /**
+ * 9 schematics per page fits in the MC chat window.
+ */
+ private static final int SCHEMATICS_PER_PAGE = 9;
+ private static final Logger log = LoggerFactory.getLogger(SchematicCommands.class);
+ private final WorldEdit worldEdit;
/**
* Create a new instance.
@@ -280,7 +293,7 @@ public class SchematicCommands extends MethodCommands {
@Command(aliases = {"save"}, usage = "[format] ", desc = "Save a schematic into your clipboard", help = "The default format for 1.13 is schem")
@Deprecated
@CommandPermissions({"worldedit.clipboard.save", "worldedit.schematic.save", "worldedit.schematic.save.other"})
- public void save(final Player player, final LocalSession session, @Optional("schem") final String formatName, String filename, @Switch('g') boolean global) throws CommandException, WorldEditException {
+ public void save(final Player player, final LocalSession session, @Optional("schem") final String formatName, String filename, @Switch('g') boolean global, @Switch('f') boolean allowOverwrite) throws CommandException, WorldEditException {
final LocalConfiguration config = this.worldEdit.getConfiguration();
final ClipboardFormat format = ClipboardFormats.findByAlias(formatName);
if (format == null) {
@@ -324,6 +337,8 @@ public class SchematicCommands extends MethodCommands {
try {
if (!f.exists()) {
f.createNewFile();
+ } else if (!allowOverwrite) {
+ BBC.SCHEMATIC_MOVE_EXISTS.send(player, f.getName());
}
try (FileOutputStream fos = new FileOutputStream(f)) {
final ClipboardHolder holder = session.getClipboard();
@@ -363,7 +378,7 @@ public class SchematicCommands extends MethodCommands {
} catch (IOException e) {
e.printStackTrace();
player.printError("Schematic could not written: " + e.getMessage());
- log.log(Level.WARNING, "Failed to write a saved clipboard", e);
+ log.warn("Failed to write a saved clipboard", e);
}
}
@@ -645,6 +660,4 @@ public class SchematicCommands extends MethodCommands {
}
});
}
-
-
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ScriptingCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ScriptingCommands.java
index a8e9e911f..602a019c9 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ScriptingCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ScriptingCommands.java
@@ -192,8 +192,9 @@ public class ScriptingCommands {
@Command(aliases = {".s"}, usage = "[args...]", desc = "Execute last CraftScript", min = 0, max = -1)
@CommandPermissions("worldedit.scripting.execute")
@Logging(ALL)
- public void executeLast(final Player player, final LocalSession session, final CommandContext args) throws WorldEditException {
- final String lastScript = session.getLastScript();
+ public void executeLast(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+
+ String lastScript = session.getLastScript();
if (!player.hasPermission("worldedit.scripting.execute." + lastScript)) {
player.printError("You don't have permission to use that script.");
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java
index c00ac21f0..40669c6bc 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java
@@ -42,6 +42,9 @@ import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.Mask;
+import com.sk89q.worldedit.function.block.BlockDistributionCounter;
+import com.sk89q.worldedit.function.operation.Operations;
+import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
@@ -63,6 +66,8 @@ import com.sk89q.worldedit.util.formatting.Style;
import com.sk89q.worldedit.util.formatting.StyledFragment;
import com.sk89q.worldedit.util.formatting.component.CommandListBox;
import com.sk89q.worldedit.world.World;
+import com.sk89q.worldedit.world.block.BaseBlock;
+import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.storage.ChunkStore;
import java.io.File;
@@ -96,8 +101,9 @@ public class SelectionCommands {
)
@Logging(POSITION)
@CommandPermissions("worldedit.selection.pos")
- public void pos1(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
- BlockVector3 pos;
+ public void pos1(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+
+ Location pos;
if (args.argsLength() == 1) {
if (args.getString(0).matches("-?\\d+,-?\\d+,-?\\d+")) {
@@ -128,8 +134,9 @@ public class SelectionCommands {
)
@Logging(POSITION)
@CommandPermissions("worldedit.selection.pos")
- public void pos2(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
- BlockVector3 pos;
+ public void pos2(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+
+ Location pos;
if (args.argsLength() == 1) {
if (args.getString(0).matches("-?\\d+,-?\\d+,-?\\d+")) {
String[] coords = args.getString(0).split(",");
@@ -161,7 +168,7 @@ public class SelectionCommands {
max = 0
)
@CommandPermissions("worldedit.selection.hpos")
- public void hpos1(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
+ public void hpos1(Player player, LocalSession session, CommandContext args) throws WorldEditException {
BlockVector3 pos = player.getBlockTrace(300).toBlockPoint();
if (pos != null) {
@@ -185,7 +192,7 @@ public class SelectionCommands {
max = 0
)
@CommandPermissions("worldedit.selection.hpos")
- public void hpos2(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
+ public void hpos2(Player player, LocalSession session, CommandContext args) throws WorldEditException {
BlockVector3 pos = player.getBlockTrace(300).toBlockPoint();
if (pos != null) {
@@ -219,7 +226,7 @@ public class SelectionCommands {
)
@Logging(POSITION)
@CommandPermissions("worldedit.selection.chunk")
- public void chunk(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
+ public void chunk(Player player, LocalSession session, CommandContext args) throws WorldEditException {
final BlockVector3 min;
final BlockVector3 max;
final World world = player.getWorld();
@@ -278,7 +285,7 @@ public class SelectionCommands {
max = 0
)
@CommandPermissions("worldedit.wand")
- public void wand(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
+ public void wand(Player player) throws WorldEditException {
player.giveItem(new BaseItemStack(ItemTypes.parse(we.getConfiguration().wandItem), 1));
BBC.SELECTION_WAND.send(player);
if (!FawePlayer.wrap(player).hasPermission("fawe.tips"))
@@ -294,6 +301,7 @@ public class SelectionCommands {
)
@CommandPermissions("worldedit.wand.toggle")
public void toggleWand(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+
session.setToolControl(!session.isToolControlEnabled());
if (session.isToolControlEnabled()) {
@@ -312,7 +320,8 @@ public class SelectionCommands {
)
@Logging(REGION)
@CommandPermissions("worldedit.selection.expand")
- public void expand(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
+ public void expand(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+
// Special syntax (//expand vert) to expand the selection between
// sky and bedrock.
if (args.getString(0).equalsIgnoreCase("vert") || args.getString(0).equalsIgnoreCase("vertical")) {
@@ -402,7 +411,7 @@ public class SelectionCommands {
)
@Logging(REGION)
@CommandPermissions("worldedit.selection.contract")
- public void contract(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
+ public void contract(Player player, LocalSession session, CommandContext args) throws WorldEditException {
List dirs = new ArrayList<>();
int change = args.getInteger(0);
@@ -476,7 +485,7 @@ public class SelectionCommands {
)
@Logging(REGION)
@CommandPermissions("worldedit.selection.shift")
- public void shift(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
+ public void shift(Player player, LocalSession session, CommandContext args) throws WorldEditException {
List dirs = new ArrayList<>();
int change = args.getInteger(0);
@@ -523,7 +532,7 @@ public class SelectionCommands {
)
@Logging(REGION)
@CommandPermissions("worldedit.selection.outset")
- public void outset(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
+ public void outset(Player player, LocalSession session, CommandContext args) throws WorldEditException {
Region region = session.getSelection(player.getWorld());
region.expand(getChangesForEachDir(args));
session.getRegionSelector(player.getWorld()).learnChanges();
@@ -546,7 +555,7 @@ public class SelectionCommands {
)
@Logging(REGION)
@CommandPermissions("worldedit.selection.inset")
- public void inset(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
+ public void inset(Player player, LocalSession session, CommandContext args) throws WorldEditException {
Region region = session.getSelection(player.getWorld());
region.contract(getChangesForEachDir(args));
session.getRegionSelector(player.getWorld()).learnChanges();
@@ -726,7 +735,7 @@ public class SelectionCommands {
min = 0,
max = 1
)
- public void select(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
+ public void select(Player player, LocalSession session, CommandContext args) throws WorldEditException {
final World world = player.getWorld();
if (args.argsLength() == 0) {
session.getRegionSelector(world).clear();
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SnapshotCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SnapshotCommands.java
index 0a433ac82..ad87b11ec 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SnapshotCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SnapshotCommands.java
@@ -39,7 +39,6 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
-import java.util.logging.Logger;
/**
* Snapshot commands.
@@ -47,7 +46,6 @@ import java.util.logging.Logger;
@Command(aliases = {"snapshot", "snap"}, desc = "List, load and view information related to snapshots")
public class SnapshotCommands {
- private static final Logger logger = Logger.getLogger("Minecraft.WorldEdit");
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
private final WorldEdit we;
@@ -64,7 +62,7 @@ public class SnapshotCommands {
max = 1
)
@CommandPermissions("worldedit.snapshots.list")
- public void list(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+ public void list(Player player, CommandContext args) throws WorldEditException {
LocalConfiguration config = we.getConfiguration();
@@ -93,10 +91,10 @@ public class SnapshotCommands {
File dir = config.snapshotRepo.getDirectory();
try {
- logger.info("WorldEdit found no snapshots: looked in: "
+ WorldEdit.logger.info("WorldEdit found no snapshots: looked in: "
+ dir.getCanonicalPath());
} catch (IOException e) {
- logger.info("WorldEdit found no snapshots: looked in "
+ WorldEdit.logger.info("WorldEdit found no snapshots: looked in "
+ "(NON-RESOLVABLE PATH - does it exist?): "
+ dir.getPath());
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SnapshotUtilCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SnapshotUtilCommands.java
index 53df86c15..1224926fd 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SnapshotUtilCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SnapshotUtilCommands.java
@@ -39,7 +39,6 @@ import com.sk89q.worldedit.world.storage.ChunkStore;
import com.sk89q.worldedit.world.storage.MissingWorldException;
import java.io.File;
import java.io.IOException;
-import java.util.logging.Logger;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION;
@@ -47,8 +46,6 @@ import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION;
@Command(aliases = {}, desc = "[More Info](http://wiki.sk89q.com/wiki/WorldEdit/Snapshots)")
public class SnapshotUtilCommands {
- private static final Logger logger = Logger.getLogger("Minecraft.WorldEdit");
-
private final WorldEdit we;
public SnapshotUtilCommands(WorldEdit we) {
@@ -99,10 +96,10 @@ public class SnapshotUtilCommands {
File dir = config.snapshotRepo.getDirectory();
try {
- logger.info("FAWE found no snapshots: looked in: "
+ WorldEdit.logger.info("FAWE found no snapshots: looked in: "
+ dir.getCanonicalPath());
} catch (IOException e) {
- logger.info("FAWE found no snapshots: looked in "
+ WorldEdit.logger.info("FAWE found no snapshots: looked in "
+ "(NON-RESOLVABLE PATH - does it exist?): "
+ dir.getPath());
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SuperPickaxeCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SuperPickaxeCommands.java
index 71387fbf4..ce5f0054f 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SuperPickaxeCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SuperPickaxeCommands.java
@@ -48,7 +48,7 @@ public class SuperPickaxeCommands {
max = 0
)
@CommandPermissions("worldedit.superpickaxe")
- public void single(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+ public void single(Player player, LocalSession session) throws WorldEditException {
session.setSuperPickaxe(new SinglePickaxe());
session.enableSuperPickAxe();
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java
index 3056036fc..8e756271b 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java
@@ -24,7 +24,6 @@ import com.boydti.fawe.object.brush.InspectBrush;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions;
-import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
@@ -67,7 +66,7 @@ public class ToolCommands {
max = 0
)
@CommandPermissions("worldedit.tool.info")
- public void info(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+ public void info(Player player, LocalSession session) throws WorldEditException {
session.setTool(new QueryTool(), player);
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
BBC.TOOL_INFO.send(player, itemStack.getType().getName());
@@ -123,7 +122,7 @@ public class ToolCommands {
max = 0
)
@CommandPermissions("worldedit.tool.data-cycler")
- public void cycler(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+ public void cycler(Player player, LocalSession session) throws WorldEditException {
session.setTool(new BlockDataCyler(), player);
BBC.TOOL_CYCLER.send(player, player.getItemInHand(HandSide.MAIN_HAND).getType().getName());
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java
index 1c1d715fe..0da33de8a 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java
@@ -22,7 +22,9 @@ package com.sk89q.worldedit.command;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions;
-import com.sk89q.worldedit.*;
+import com.sk89q.worldedit.LocalSession;
+import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.Pattern;
@@ -48,7 +50,7 @@ public class ToolUtilCommands {
max = 1
)
@CommandPermissions("worldedit.superpickaxe")
- public void togglePickaxe(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
+ public void togglePickaxe(Player player, LocalSession session, CommandContext args) throws WorldEditException {
String newState = args.getString(0, null);
if (session.hasSuperPickAxe()) {
@@ -78,7 +80,7 @@ public class ToolUtilCommands {
max = -1
)
@CommandPermissions("worldedit.brush.options.mask")
- public void mask(Player player, LocalSession session, EditSession editSession, @Optional Mask mask) throws WorldEditException {
+ public void mask(Player player, LocalSession session, @Optional Mask mask) throws WorldEditException {
if (mask == null) {
session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setMask(null);
player.print("Brush mask disabled.");
@@ -96,7 +98,7 @@ public class ToolUtilCommands {
max = 1
)
@CommandPermissions("worldedit.brush.options.material")
- public void material(Player player, LocalSession session, EditSession editSession, Pattern pattern) throws WorldEditException {
+ public void material(Player player, LocalSession session, Pattern pattern) throws WorldEditException {
session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setFill(pattern);
player.print("Brush material set.");
}
@@ -109,7 +111,7 @@ public class ToolUtilCommands {
max = 1
)
@CommandPermissions("worldedit.brush.options.range")
- public void range(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
+ public void range(Player player, LocalSession session, CommandContext args) throws WorldEditException {
int range = args.getInteger(0);
session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setRange(range);
player.print("Brush range set.");
@@ -123,7 +125,9 @@ public class ToolUtilCommands {
max = 1
)
@CommandPermissions("worldedit.brush.options.size")
- public void size(Player player, LocalSession session, EditSession editSession, Expression radius) throws WorldEditException {
+ public void size(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+
+ int radius = args.getInteger(0);
we.checkMaxBrushRadius(radius);
session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setSize(radius);
player.print("Brush size set.");
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java
index ad3314995..d111b86f8 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java
@@ -77,8 +77,12 @@ import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.CylinderRegion;
import com.sk89q.worldedit.regions.Region;
-import com.sk89q.worldedit.util.command.*;
import com.sk89q.worldedit.util.command.binding.Range;
+import com.sk89q.worldedit.session.SessionOwner;
+import com.sk89q.worldedit.util.command.CommandCallable;
+import com.sk89q.worldedit.util.command.CommandMapping;
+import com.sk89q.worldedit.util.command.Dispatcher;
+import com.sk89q.worldedit.util.command.PrimaryAliasComparator;
import com.sk89q.worldedit.util.command.binding.Text;
import com.sk89q.worldedit.util.command.parametric.Optional;
import com.sk89q.worldedit.util.command.parametric.ParameterData;
@@ -283,28 +287,6 @@ public class UtilityCommands extends MethodCommands {
if (depth == -1) depth = Integer.MAX_VALUE;
int affected = editSession.fillXZ(pos, pattern, radius, (int) depth, true);
player.print(BBC.getPrefix() + affected + " block(s) have been created.");
-//=======
-// public void fillr(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
-//
-// ParserContext context = new ParserContext();
-// context.setActor(player);
-// context.setWorld(player.getWorld());
-// context.setSession(session);
-// Pattern pattern = we.getPatternFactory().parseFromInput(args.getString(0), context);
-//
-// double radius = Math.max(1, args.getDouble(1));
-// we.checkMaxRadius(radius);
-// int depth = args.argsLength() > 2 ? Math.max(1, args.getInteger(2)) : Integer.MAX_VALUE;
-//
-// BlockVector3 pos = session.getPlacementPosition(player);
-// int affected = 0;
-// if (pattern instanceof BlockPattern) {
-// affected = editSession.fillXZ(pos, ((BlockPattern) pattern).getBlock(), radius, depth, true);
-// } else {
-// affected = editSession.fillXZ(pos, pattern, radius, depth, true);
-// }
-// player.print(affected + " block(s) have been created.");
-//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
}
@Command(
@@ -435,8 +417,8 @@ public class UtilityCommands extends MethodCommands {
@CommandPermissions("worldedit.snow")
@Logging(PLACEMENT)
public void snow(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
-
double size = args.argsLength() > 0 ? Math.max(1, args.getDouble(0)) : 10;
+ we.checkMaxRadius(size);
int affected = editSession.simulateSnow(session.getPlacementPosition(player), size);
player.print(BBC.getPrefix() + affected + " surfaces covered. Let it snow~");
@@ -452,8 +434,8 @@ public class UtilityCommands extends MethodCommands {
@CommandPermissions("worldedit.thaw")
@Logging(PLACEMENT)
public void thaw(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
-
double size = args.argsLength() > 0 ? Math.max(1, args.getDouble(0)) : 10;
+ we.checkMaxRadius(size);
int affected = editSession.thaw(session.getPlacementPosition(player), size);
player.print(BBC.getPrefix() + affected + " surfaces thawed.");
@@ -463,6 +445,7 @@ public class UtilityCommands extends MethodCommands {
aliases = {"/green", "green"},
usage = "[radius]",
desc = "Greens the area",
+ help = "Converts dirt to grass blocks. -f also converts coarse dirt.",
flags = "f",
min = 0,
max = 1
@@ -470,8 +453,8 @@ public class UtilityCommands extends MethodCommands {
@CommandPermissions("worldedit.green")
@Logging(PLACEMENT)
public void green(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
-
final double size = args.argsLength() > 0 ? Math.max(1, args.getDouble(0)) : 10;
+ we.checkMaxRadius(size);
final boolean onlyNormalDirt = !args.hasFlag('f');
final int affected = editSession.green(session.getPlacementPosition(player), size);
@@ -559,11 +542,7 @@ public class UtilityCommands extends MethodCommands {
List extends Entity> entities;
if (radius >= 0) {
CylinderRegion region = CylinderRegion.createRadius(editSession, center, radius);
- entities = editSession.getEntities(region);
} else {
- entities = editSession.getEntities();
- }
- visitors.add(new EntityVisitor(entities.iterator(), flags.createFunction()));
} else {
Platform platform = worldEdit.getPlatformManager().queryCapability(Capability.WORLD_EDITING);
for (World world : platform.getWorlds()) {
@@ -582,7 +561,7 @@ public class UtilityCommands extends MethodCommands {
if (editSession != null) {
session.remember(editSession);
- editSession.flushQueue();
+ editSession.flushSession();
}
}
@@ -642,7 +621,7 @@ public class UtilityCommands extends MethodCommands {
if (editSession != null) {
session.remember(editSession);
- editSession.flushQueue();
+ editSession.flushSession();
}
}
@@ -674,10 +653,10 @@ public class UtilityCommands extends MethodCommands {
actor.print(BBC.getPrefix() + "= " + result);
} catch (EvaluationException e) {
actor.printError(String.format(
- "'%s' could not be parsed as a valid expression", input));
+ "'%s' could not be evaluated (error: %s)", input, e.getMessage()));
} catch (ExpressionException e) {
actor.printError(String.format(
- "'%s' could not be evaluated (error: %s)", input, e.getMessage()));
+ "'%s' could not be parsed as a valid expression", input));
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java
index 301640c03..67c4e6a21 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java
@@ -124,6 +124,31 @@ public class WorldEditCommands {
actor.print(BBC.getPrefix() + "Reloaded WorldEdit " + we.getVersion() + " and FAWE (" + Fawe.get().getVersion() + ")");
}
+ @Command(aliases = {"report"}, desc = "Writes a report on WorldEdit", flags = "p", max = 0)
+ @CommandPermissions({"worldedit.report"})
+ public void report(Actor actor, CommandContext args) throws WorldEditException {
+ ReportList report = new ReportList("Report");
+ report.add(new SystemInfoReport());
+ report.add(new ConfigReport());
+ String result = report.toString();
+
+ try {
+ File dest = new File(we.getWorkingDirectoryFile(we.getConfiguration().saveDir), "report.txt");
+ Files.write(result, dest, Charset.forName("UTF-8"));
+ actor.print("WorldEdit report written to " + dest.getAbsolutePath());
+ } catch (IOException e) {
+ actor.printError("Failed to write report: " + e.getMessage());
+ }
+
+ if (args.hasFlag('p')) {
+ actor.checkPermission("worldedit.report.pastebin");
+ ActorCallbackPaste.pastebin(
+ we.getSupervisor(), actor, result, "WorldEdit report: %s.report",
+ WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter()
+ );
+ }
+ }
+
@Command(
aliases = {"update"},
usage = "",
@@ -252,7 +277,7 @@ public class WorldEditCommands {
min = 0,
max = 0
)
- public void cui(Player player, LocalSession session, CommandContext args) throws WorldEditException {
+ public void cui(Player player, LocalSession session) throws WorldEditException {
session.setCUISupport(true);
session.dispatchCUISetup(player);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/composition/SelectionCommand.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/composition/SelectionCommand.java
index 645d1f232..e1425c3e1 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/composition/SelectionCommand.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/composition/SelectionCommand.java
@@ -89,12 +89,14 @@ public class SelectionCommand extends SimpleCommand {
LocalSession session = WorldEdit.getInstance().getSessionManager().get(player);
Region selection = session.getSelection(player.getWorld());
EditSession editSession = session.createEditSession(player);
- editSession.enableQueue();
+ editSession.enableStandardMode();
locals.put(EditSession.class, editSession);
session.tellVersion(player);
EditContext editContext = new EditContext();
editContext.setDestination(locals.get(EditSession.class));
editContext.setRegion(selection);
+ editContext.setSession(session);
+
Operation operation = operationFactory.createFromContext(editContext);
// Shortcut
if (selection instanceof CuboidRegion && editSession.hasFastMode() && operation instanceof RegionVisitor) {
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/composition/ShapedBrushCommand.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/composition/ShapedBrushCommand.java
index 35a8734b6..f22fceb4e 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/composition/ShapedBrushCommand.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/composition/ShapedBrushCommand.java
@@ -76,7 +76,8 @@ public class ShapedBrushCommand extends SimpleCommand {
WorldEdit.getInstance().checkMaxBrushRadius(radius);
BrushTool tool = session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType());
tool.setSize(radius);
- tool.setBrush(new OperationFactoryBrush(factory, regionFactory), permission);
+ tool.setFill(null);
+ tool.setBrush(new OperationFactoryBrush(factory, regionFactory, session), permission);
} catch (MaxBrushRadiusException | InvalidToolBindException e) {
WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter().convert(e);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java
index 58abbcd0d..ac1d0de52 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java
@@ -6,6 +6,9 @@ import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
+import com.sk89q.worldedit.MaxChangedBlocksException;
+import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
@@ -40,33 +43,21 @@ public class AreaPickaxe implements BlockTool {
return true;
}
- EditSession editSession = session.createEditSession(player);
- editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);
+ try (EditSession editSession = session.createEditSession(player)) {
+ editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);
for (int x = ox - range; x <= ox + range; ++x) {
for (int z = oz - range; z <= oz + range; ++z) {
for (int y = oy + range; y >= oy - range; --y) {
if (initialType.equals(editSession.getLazyBlock(x, y, z))) {
continue;
-// try (EditSession editSession = session.createEditSession(player)) {
-// editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);
-//
-// try {
-// for (int x = ox - range; x <= ox + range; ++x) {
-// for (int y = oy - range; y <= oy + range; ++y) {
-// for (int z = oz - range; z <= oz + range; ++z) {
-// BlockVector3 pos = new BlockVector3(x, y, z);
-// if (editSession.getBlock(pos).getBlockType() != initialType) {
-// continue;
-// }
-//
-// ((World) clicked.getExtent()).queueBlockBreakEffect(server, pos, initialType, clicked.toBlockPoint().distanceSq(pos));
-//
-// editSession.setBlock(pos, BlockTypes.AIR.getDefaultState());
-// }
}
editSession.setBlock(x, y, z, BlockTypes.AIR.getDefaultState());
}
+ } catch (MaxChangedBlocksException e) {
+ player.printError("Max blocks change limit reached.");
+ } finally {
+ session.remember(editSession);
}
}
editSession.flushQueue();
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java
index 0a7b63e6c..ba2ef06f8 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java
@@ -25,13 +25,15 @@ import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
+import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag;
+import com.sk89q.worldedit.function.pattern.BlockPattern;
+import com.sk89q.worldedit.world.block.BlockState;
/**
- * A mode that replaces one block.
*/
public class BlockReplacer implements DoubleActionBlockTool {
@@ -58,7 +60,6 @@ public class BlockReplacer implements DoubleActionBlockTool {
if (bag != null) {
bag.flushChanges();
}
- session.remember(editSession);
}
return true;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java
index 221d71eb5..269d9b7b5 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java
@@ -472,14 +472,6 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
MaskIntersection newMask = new MaskIntersection(existingMask);
newMask.add(mask);
editSession.setMask(newMask);
-//=======
-// try {
-// brush.build(editSession, target.toBlockPoint(), material, size);
-// } catch (MaxChangedBlocksException e) {
-// player.printError("Max blocks change limit reached.");
-// } finally {
-// session.remember(editSession);
-//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
}
}
Mask sourceMask = current.getSourceMask();
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloatingTreeRemover.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloatingTreeRemover.java
index aa3d91b7f..3d12dc1d7 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloatingTreeRemover.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloatingTreeRemover.java
@@ -19,6 +19,7 @@
package com.sk89q.worldedit.command.tool;
+import com.boydti.fawe.object.collection.BlockVectorSet;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
@@ -75,80 +76,26 @@ public class FloatingTreeRemover implements BlockTool {
player.printError("That's not a tree.");
return true;
}
- final EditSession editSession = session.createEditSession(player);
- try /*(EditSession editSession = session.createEditSession(player))*/ {
- final Set blockSet = bfs(world, clicked.toBlockPoint());
- if (blockSet == null) {
- player.printError("That's not a floating tree.");
- return true;
- }
- for (BlockVector3 blockVector : blockSet) {
- final BlockState otherState = editSession.getBlock(blockVector);
- if (isTreeBlock(otherState.getBlockType())) {
- editSession.setBlock(blockVector, BlockTypes.AIR.getDefaultState());
- }
- }
- } catch (MaxChangedBlocksException e) {
- player.printError("Max blocks change limit reached.");
- } finally {
- session.remember(editSession);
+ try (EditSession editSession = session.createEditSession(player)) {
+ try {
+ Pattern replace = BlockTypes.AIR;
+ RecursiveVisitor visitor = new RecursiveVisitor(new BlockMask(editSession, logs, leaves), replace, 64, editSession);
+ visitor.visit(pos);
+ Operations.completeBlindly(visitor);
+ } finally {
+ session.remember(editSession);
+ }
}
return true;
}
private BlockVector3[] recurseDirections = {
- Direction.NORTH.toBlockVector(),
Direction.EAST.toBlockVector(),
Direction.SOUTH.toBlockVector(),
Direction.WEST.toBlockVector(),
Direction.UP.toBlockVector(),
Direction.DOWN.toBlockVector(),
};
-
- /**
- * Helper method.
- *
- * @param world the world that contains the tree
- * @param origin any point contained in the floating tree
- * @return a set containing all blocks in the tree/shroom or null if this is not a floating tree/shroom.
- */
- private Set bfs(World world, BlockVector3 origin) throws MaxChangedBlocksException {
- final Set visited = new HashSet<>();
- final LinkedList queue = new LinkedList<>();
-
- queue.addLast(origin);
- visited.add(origin);
-
- while (!queue.isEmpty()) {
- final BlockVector3 current = queue.removeFirst();
- for (BlockVector3 recurseDirection : recurseDirections) {
- final BlockVector3 next = current.add(recurseDirection);
- if (origin.distanceSq(next) > rangeSq) {
- // Maximum range exceeded => stop walking
- continue;
- }
-
- if (visited.add(next)) {
- BlockState state = world.getBlock(next);
- if (state.getBlockType().getMaterial().isAir() || state.getBlockType() == BlockTypes.SNOW) {
- continue;
- }
- if (isTreeBlock(state.getBlockType())) {
- queue.addLast(next);
- } else {
- // we hit something solid - evaluate where we came from
- final BlockType currentType = world.getBlock(current).getBlockType();
- if (!BlockCategories.LEAVES.contains(currentType) && currentType != BlockTypes.VINE) {
- // log/shroom touching a wall/the ground => this is not a floating tree, bail out
- return null;
- }
- }
- }
- }
- }
-
- return visited;
- }
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloodFillTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloodFillTool.java
index ee08812ad..541e9056f 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloodFillTool.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloodFillTool.java
@@ -69,17 +69,16 @@ public class FloodFillTool implements BlockTool {
return true;
}
- EditSession editSession = session.createEditSession(player);
- try {
- recurse(editSession, origin, origin, range, initialType, new HashSet<>());
- } catch (MaxChangedBlocksException e) {
- player.printError("Max blocks change limit reached.");
- } finally {
- session.remember(editSession);
+ try (EditSession editSession = session.createEditSession(player)) {
+ try {
+ TODO fillDirection (but replace)
+ recurse(editSession, origin, origin, range, initialType, new HashSet<>());
+ } catch (MaxChangedBlocksException e) {
+ player.printError("Max blocks change limit reached.");
+ } finally {
+ session.remember(editSession);
+ }
}
-
- editSession.flushQueue();
- session.remember(editSession);
return true;
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/LongRangeBuildTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/LongRangeBuildTool.java
index 4137e1efd..b902a39b8 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/LongRangeBuildTool.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/LongRangeBuildTool.java
@@ -55,10 +55,8 @@ public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTo
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
Location pos = getTargetFace(player);
if (pos == null) return false;
- EditSession eS = session.createEditSession(player);
- try {
-// eS.disableBuffering();
- BlockVector3 blockPoint = pos.toBlockPoint();
+ try (EditSession eS = session.createEditSession(player)) {
+ BlockVector3 blockPoint = pos.toVector().toBlockPoint();
BaseBlock applied = secondary.apply(blockPoint);
if (applied.getBlockType().getMaterial().isAir()) {
eS.setBlock(blockPoint, secondary);
@@ -74,12 +72,7 @@ public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTo
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
- Location pos = getTargetFace(player);
- if (pos == null) return false;
- EditSession eS = session.createEditSession(player);
-
- try {
-// eS.disableBuffering();
+ try (EditSession eS = session.createEditSession(player)) {
BlockVector3 blockPoint = pos.toBlockPoint();
BaseBlock applied = primary.apply(blockPoint);
if (applied.getBlockType().getMaterial().isAir()) {
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java
index f794882d7..be256f239 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java
@@ -53,7 +53,6 @@ public class RecursivePickaxe implements BlockTool {
editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);
-//<<<<<<< HEAD
final int radius = (int) range;
final BlockReplace replace = new BlockReplace(editSession, (editSession.nullBlock));
editSession.setMask((Mask) null);
@@ -63,51 +62,6 @@ public class RecursivePickaxe implements BlockTool {
editSession.flushQueue();
session.remember(editSession);
-//=======
-// try {
-// recurse(server, editSession, world, clicked.toBlockPoint(),
-// clicked.toBlockPoint(), range, initialType, new HashSet<>());
-// } catch (MaxChangedBlocksException e) {
-// player.printError("Max blocks change limit reached.");
-// } finally {
-// session.remember(editSession);
-// }
-// }
-//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
-
return true;
}
-
-// private static void recurse(Platform server, EditSession editSession, World world, BlockVector3 pos,
-// BlockVector3 origin, double size, BlockType initialType, Set visited) throws MaxChangedBlocksException {
-//
-// final double distanceSq = origin.distanceSq(pos);
-// if (distanceSq > size*size || visited.contains(pos)) {
-// return;
-// }
-//
-// visited.add(pos);
-//
-// if (editSession.getBlock(pos).getBlockType() != initialType) {
-// return;
-// }
-//
-// world.queueBlockBreakEffect(server, pos, initialType, distanceSq);
-//
-// editSession.setBlock(pos, BlockTypes.AIR.getDefaultState());
-//
-// recurse(server, editSession, world, pos.add(1, 0, 0),
-// origin, size, initialType, visited);
-// recurse(server, editSession, world, pos.add(-1, 0, 0),
-// origin, size, initialType, visited);
-// recurse(server, editSession, world, pos.add(0, 0, 1),
-// origin, size, initialType, visited);
-// recurse(server, editSession, world, pos.add(0, 0, -1),
-// origin, size, initialType, visited);
-// recurse(server, editSession, world, pos.add(0, 1, 0),
-// origin, size, initialType, visited);
-// recurse(server, editSession, world, pos.add(0, -1, 0),
-// origin, size, initialType, visited);
-// }
-
}
\ No newline at end of file
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java
index 9ac871ad3..2d865550b 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java
@@ -50,24 +50,12 @@ public class SinglePickaxe implements BlockTool {
&& !player.canDestroyBedrock()) {
return true;
}
- final EditSession editSession = session.createEditSession(player);
- try {
+
+ try (EditSession editSession = session.createEditSession(player)) {
editSession.getSurvivalExtent().setToolUse(config.superPickaxeDrop);
editSession.setBlock(blockPoint, BlockTypes.AIR.getDefaultState());
- } catch (MaxChangedBlocksException e) {
- player.printError("Max blocks change limit reached.");
- }
-
- try {
- if (editSession.setBlock(clicked.getBlockX(), clicked.getBlockY(), clicked.getBlockZ(), EditSession.nullBlock)) {
- // TODO FIXME play effect
-// world.playEffect(clicked, 2001, blockType);
- }
- } finally {
- editSession.flushQueue();
session.remember(editSession);
}
-
return true;
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/TreePlanter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/TreePlanter.java
index 41353b0ad..2eafbb4d5 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/TreePlanter.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/TreePlanter.java
@@ -48,16 +48,15 @@ public class TreePlanter implements BlockTool {
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked) {
- EditSession editSession = session.createEditSession(player);
-
- try {
+ try (EditSession editSession = session.createEditSession(player)) {
boolean successful = false;
- for (int i = 0; i < 10; i++) {
- if (treeType.generate(editSession, clicked.add(0, 1, 0).toBlockPoint())) {
- successful = true;
- break;
- }
+
+ for (int i = 0; i < 10; i++) {
+ if (treeType.generate(editSession, clicked.add(0, 1, 0).toBlockPoint())) {
+ successful = true;
+ break;
}
+ }
if (!successful) {
player.printError("A tree can't go there.");
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/CylinderBrush.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/CylinderBrush.java
index cfebeaf17..12a663ed3 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/CylinderBrush.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/CylinderBrush.java
@@ -21,10 +21,10 @@ package com.sk89q.worldedit.command.tool.brush;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
-import com.sk89q.worldedit.math.BlockVector3;
-import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
+import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.world.block.BlockTypes;
public class CylinderBrush implements Brush {
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java
index 2c67b3fdc..aaafefdc7 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java
@@ -21,12 +21,14 @@ package com.sk89q.worldedit.command.tool.brush;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
-
-import com.sk89q.worldedit.function.mask.Mask;
-import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
-import com.sk89q.worldedit.world.block.BlockStateHolder;
+import com.sk89q.worldedit.world.block.BlockState;
+import com.sk89q.worldedit.world.block.BlockTypes;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
public class GravityBrush implements Brush {
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/HollowCylinderBrush.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/HollowCylinderBrush.java
index 54247c107..ed7b23d55 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/HollowCylinderBrush.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/HollowCylinderBrush.java
@@ -24,6 +24,7 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
+import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockTypes;
public class HollowCylinderBrush implements Brush {
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/HollowSphereBrush.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/HollowSphereBrush.java
index 9763a621a..e76173174 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/HollowSphereBrush.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/HollowSphereBrush.java
@@ -24,6 +24,7 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
+import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockTypes;
public class HollowSphereBrush implements Brush {
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/OperationFactoryBrush.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/OperationFactoryBrush.java
index 6a323f14b..1d7c5e7ce 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/OperationFactoryBrush.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/OperationFactoryBrush.java
@@ -20,6 +20,7 @@
package com.sk89q.worldedit.command.tool.brush;
import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.function.Contextual;
import com.sk89q.worldedit.function.EditContext;
@@ -33,10 +34,16 @@ public class OperationFactoryBrush implements Brush {
private final Contextual extends Operation> operationFactory;
private final RegionFactory regionFactory;
+ private final LocalSession session;
public OperationFactoryBrush(Contextual extends Operation> operationFactory, RegionFactory regionFactory) {
+ this(operationFactory, regionFactory, null);
+ }
+
+ public OperationFactoryBrush(Contextual extends Operation> operationFactory, RegionFactory regionFactory, LocalSession session) {
this.operationFactory = operationFactory;
this.regionFactory = regionFactory;
+ this.session = session;
}
@Override
@@ -45,6 +52,7 @@ public class OperationFactoryBrush implements Brush {
context.setDestination(editSession);
context.setRegion(regionFactory.createCenteredAt(position, size));
context.setFill(pattern);
+ context.setSession(session);
Operation operation = operationFactory.createFromContext(context);
Operations.completeLegacy(operation);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/SmoothBrush.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/SmoothBrush.java
index a2c2750b6..66a73112b 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/SmoothBrush.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/SmoothBrush.java
@@ -21,9 +21,10 @@ package com.sk89q.worldedit.command.tool.brush;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
+import com.sk89q.worldedit.function.mask.Mask;
+import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
-import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.convolution.GaussianKernel;
import com.sk89q.worldedit.math.convolution.HeightMap;
import com.sk89q.worldedit.math.convolution.HeightMapFilter;
@@ -31,12 +32,20 @@ import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
+import javax.annotation.Nullable;
+
public class SmoothBrush implements Brush {
+ private final Mask mask;
private int iterations;
public SmoothBrush(int iterations) {
+ this(iterations, null);
+ }
+
+ public SmoothBrush(int iterations, @Nullable Mask mask) {
this.iterations = iterations;
+ this.mask = mask;
}
@Override
@@ -45,7 +54,7 @@ public class SmoothBrush implements Brush {
Location min = new Location(editSession.getWorld(), posDouble.subtract(size, size, size));
BlockVector3 max = posDouble.add(size, size + 10, size).toBlockPoint();
Region region = new CuboidRegion(editSession.getWorld(), min.toBlockPoint(), max);
- HeightMap heightMap = new HeightMap(editSession, region);
+ HeightMap heightMap = new HeightMap(editSession, region, mask);
HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1.0));
heightMap.applyFilter(filter, iterations);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/SphereBrush.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/SphereBrush.java
index 7c38382de..d8028f2ae 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/SphereBrush.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/SphereBrush.java
@@ -21,9 +21,9 @@ package com.sk89q.worldedit.command.tool.brush;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
+import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockTypes;
public class SphereBrush implements Brush {
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/event/extent/EditSessionEvent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/event/extent/EditSessionEvent.java
index e6364bbec..c58ae7ce1 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/event/extent/EditSessionEvent.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/event/extent/EditSessionEvent.java
@@ -20,9 +20,6 @@
package com.sk89q.worldedit.event.extent;
import com.sk89q.worldedit.EditSession;
-
-import com.sk89q.worldedit.world.block.BlockState;
-import com.sk89q.worldedit.event.Cancellable;
import com.sk89q.worldedit.event.Event;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.Extent;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java
index 8ee07c223..235f0ae3e 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java
@@ -21,7 +21,6 @@ package com.sk89q.worldedit.extension.factory;
import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.WorldEdit;
-import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.extension.factory.parser.DefaultBlockParser;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java
index 0f9f04fde..cc326cc46 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java
@@ -55,14 +55,7 @@ public final class MaskFactory extends AbstractFactory {
*/
public MaskFactory(WorldEdit worldEdit) {
super(worldEdit);
-
- register(new ExistingMaskParser(worldEdit));
- register(new SolidMaskParser(worldEdit));
- register(new LazyRegionMaskParser(worldEdit));
- register(new RegionMaskParser(worldEdit));
register(new BlockCategoryMaskParser(worldEdit));
- register(new NoiseMaskParser(worldEdit));
- register(new NegateMaskParser(worldEdit));
register(new DefaultMaskParser(worldEdit));
}
@@ -90,7 +83,7 @@ public final class MaskFactory extends AbstractFactory {
case 1:
return masks.get(0);
default:
- return new MaskIntersection(masks);
+ return new MaskIntersection(masks).optimize();
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java
index 7b93c0d61..c9d43f011 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java
@@ -22,9 +22,10 @@ package com.sk89q.worldedit.extension.factory;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.factory.parser.pattern.BlockCategoryPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.ClipboardPatternParser;
-import com.sk89q.worldedit.extension.factory.parser.pattern.DefaultPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.RandomPatternParser;
+import com.sk89q.worldedit.extension.factory.parser.pattern.RandomStatePatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.SingleBlockPatternParser;
+import com.sk89q.worldedit.extension.factory.parser.pattern.TypeOrStateApplyingPatternParser;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.registry.AbstractFactory;
@@ -44,10 +45,6 @@ public final class PatternFactory extends AbstractFactory {
*/
public PatternFactory(WorldEdit worldEdit) {
super(worldEdit);
-
-// register(new ClipboardPatternParser(worldEdit));
-// register(new SingleBlockPatternParser(worldEdit));
-// register(new RandomPatternParser(worldEdit));
register(new BlockCategoryPatternParser(worldEdit));
register(new DefaultPatternParser(worldEdit));
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java
index 904c67d95..0f346352c 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java
@@ -24,12 +24,6 @@ import com.boydti.fawe.jnbt.JSON2NBT;
import com.boydti.fawe.jnbt.NBTException;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.StringMan;
-import com.sk89q.jnbt.CompoundTag;
-import com.sk89q.worldedit.*;
-
-import com.sk89q.worldedit.extension.platform.Platform;
-import com.sk89q.worldedit.world.block.BlockState;
-import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.NotABlockException;
import com.sk89q.worldedit.WorldEdit;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BiomeMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BiomeMaskParser.java
new file mode 100644
index 000000000..11b8bb54c
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BiomeMaskParser.java
@@ -0,0 +1,65 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.extension.factory.parser.mask;
+
+import com.google.common.base.Splitter;
+import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.extension.input.InputParseException;
+import com.sk89q.worldedit.extension.input.ParserContext;
+import com.sk89q.worldedit.extension.platform.Capability;
+import com.sk89q.worldedit.function.mask.BiomeMask2D;
+import com.sk89q.worldedit.function.mask.Mask;
+import com.sk89q.worldedit.function.mask.Masks;
+import com.sk89q.worldedit.internal.registry.InputParser;
+import com.sk89q.worldedit.session.request.RequestExtent;
+import com.sk89q.worldedit.world.biome.BiomeType;
+import com.sk89q.worldedit.world.biome.Biomes;
+import com.sk89q.worldedit.world.registry.BiomeRegistry;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+public class BiomeMaskParser extends InputParser {
+
+ public BiomeMaskParser(WorldEdit worldEdit) {
+ super(worldEdit);
+ }
+
+ @Override
+ public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
+ if (!input.startsWith("$")) {
+ return null;
+ }
+
+ Set biomes = new HashSet<>();
+ BiomeRegistry biomeRegistry = worldEdit.getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBiomeRegistry();
+ Collection knownBiomes = BiomeType.REGISTRY.values();
+ for (String biomeName : Splitter.on(",").split(input.substring(1))) {
+ BiomeType biome = Biomes.findBiomeByName(knownBiomes, biomeName, biomeRegistry);
+ if (biome == null) {
+ throw new InputParseException("Unknown biome '" + biomeName + '\'');
+ }
+ biomes.add(biome);
+ }
+
+ return Masks.asMask(new BiomeMask2D(new RequestExtent(), biomes));
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlockCategoryMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlockCategoryMaskParser.java
index 478ba22e6..ec3c65b5c 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlockCategoryMaskParser.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlockCategoryMaskParser.java
@@ -22,12 +22,10 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
-import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.BlockCategoryMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.internal.registry.InputParser;
-import com.sk89q.worldedit.session.request.Request;
-import com.sk89q.worldedit.world.block.BlockCategories;
+import com.sk89q.worldedit.session.request.RequestExtent;
import com.sk89q.worldedit.world.block.BlockCategory;
public class BlockCategoryMaskParser extends InputParser {
@@ -38,18 +36,16 @@ public class BlockCategoryMaskParser extends InputParser {
@Override
public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
- if (input.startsWith("##")) {
- Extent extent = Request.request().getEditSession();
-
- // This means it's a tag mask.
- BlockCategory category = BlockCategories.get(input.substring(2).toLowerCase());
- if (category == null) {
- throw new InputParseException("Unrecognised tag '" + input.substring(2) + '\'');
- } else {
- return new BlockCategoryMask(extent, category);
- }
+ if (!input.startsWith("##")) {
+ return null;
}
- return null;
+ // This means it's a tag mask.
+ BlockCategory category = BlockCategory.REGISTRY.get(input.substring(2).toLowerCase());
+ if (category == null) {
+ throw new InputParseException("Unrecognised tag '" + input.substring(2) + '\'');
+ } else {
+ return new BlockCategoryMask(new RequestExtent(), category);
+ }
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlockStateMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlockStateMaskParser.java
new file mode 100644
index 000000000..0a2bd6e56
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlockStateMaskParser.java
@@ -0,0 +1,53 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.extension.factory.parser.mask;
+
+import com.google.common.base.Splitter;
+import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.extension.input.InputParseException;
+import com.sk89q.worldedit.extension.input.ParserContext;
+import com.sk89q.worldedit.function.mask.BlockStateMask;
+import com.sk89q.worldedit.function.mask.Mask;
+import com.sk89q.worldedit.internal.registry.InputParser;
+import com.sk89q.worldedit.session.request.RequestExtent;
+
+public class BlockStateMaskParser extends InputParser {
+
+ public BlockStateMaskParser(WorldEdit worldEdit) {
+ super(worldEdit);
+ }
+
+ @Override
+ public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
+ if (!(input.startsWith("^[") || input.startsWith("^=[")) || !input.endsWith("]")) {
+ return null;
+ }
+
+ boolean strict = input.charAt(1) == '=';
+ String states = input.substring(2 + (strict ? 1 : 0), input.length() - 1);
+ try {
+ return new BlockStateMask(new RequestExtent(),
+ Splitter.on(',').omitEmptyStrings().trimResults().withKeyValueSeparator('=').split(states),
+ strict);
+ } catch (Exception e) {
+ throw new InputParseException("Invalid states.", e);
+ }
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlocksMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlocksMaskParser.java
new file mode 100644
index 000000000..e67a7e8b1
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlocksMaskParser.java
@@ -0,0 +1,59 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.extension.factory.parser.mask;
+
+import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.extension.input.InputParseException;
+import com.sk89q.worldedit.extension.input.NoMatchException;
+import com.sk89q.worldedit.extension.input.ParserContext;
+import com.sk89q.worldedit.function.mask.BlockMask;
+import com.sk89q.worldedit.function.mask.Mask;
+import com.sk89q.worldedit.internal.registry.InputParser;
+import com.sk89q.worldedit.session.request.RequestExtent;
+import com.sk89q.worldedit.world.block.BaseBlock;
+
+import java.util.Set;
+
+/**
+ * Parses mask input strings.
+ */
+public class BlocksMaskParser extends InputParser {
+
+ public BlocksMaskParser(WorldEdit worldEdit) {
+ super(worldEdit);
+ }
+
+ @Override
+ public Mask parseFromInput(String component, ParserContext context) throws InputParseException {
+ ParserContext tempContext = new ParserContext(context);
+ tempContext.setRestricted(false);
+ tempContext.setPreferringWildcard(true);
+ try {
+ Set holders = worldEdit.getBlockFactory().parseFromListInput(component, tempContext);
+ if (holders.isEmpty()) {
+ return null;
+ }
+ return new BlockMask(new RequestExtent(), holders);
+ } catch (NoMatchException e) {
+ return null;
+ }
+ }
+
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ExistingMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ExistingMaskParser.java
index a1dea6f48..5249d47ad 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ExistingMaskParser.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ExistingMaskParser.java
@@ -21,13 +21,11 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.WorldEdit;
-import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
-import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
-import com.sk89q.worldedit.session.request.Request;
+import com.sk89q.worldedit.session.request.RequestExtent;
import java.util.List;
@@ -43,9 +41,7 @@ public class ExistingMaskParser extends SimpleInputParser {
}
@Override
- public Mask parseFromSimpleInput(String input, ParserContext context) throws InputParseException {
- Extent extent = Request.request().getEditSession();
-
- return new ExistingBlockMask(extent);
+ public Mask parseFromSimpleInput(String input, ParserContext context) {
+ return new ExistingBlockMask(new RequestExtent());
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ExpressionMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ExpressionMaskParser.java
new file mode 100644
index 000000000..4e254109c
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ExpressionMaskParser.java
@@ -0,0 +1,65 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.extension.factory.parser.mask;
+
+import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.extension.input.InputParseException;
+import com.sk89q.worldedit.extension.input.ParserContext;
+import com.sk89q.worldedit.function.mask.ExpressionMask;
+import com.sk89q.worldedit.function.mask.Mask;
+import com.sk89q.worldedit.internal.expression.Expression;
+import com.sk89q.worldedit.internal.expression.ExpressionException;
+import com.sk89q.worldedit.internal.registry.InputParser;
+import com.sk89q.worldedit.math.Vector3;
+import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
+import com.sk89q.worldedit.session.SessionOwner;
+import com.sk89q.worldedit.session.request.Request;
+import com.sk89q.worldedit.session.request.RequestExtent;
+
+import java.util.function.IntSupplier;
+
+public class ExpressionMaskParser extends InputParser {
+
+ public ExpressionMaskParser(WorldEdit worldEdit) {
+ super(worldEdit);
+ }
+
+ @Override
+ public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
+ if (!input.startsWith("=")) {
+ return null;
+ }
+
+ try {
+ Expression exp = Expression.compile(input.substring(1), "x", "y", "z");
+ WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment(
+ new RequestExtent(), Vector3.ONE, Vector3.ZERO);
+ exp.setEnvironment(env);
+ if (context.getActor() instanceof SessionOwner) {
+ SessionOwner owner = (SessionOwner) context.getActor();
+ IntSupplier timeout = () -> WorldEdit.getInstance().getSessionManager().get(owner).getTimeout();
+ return new ExpressionMask(exp, timeout);
+ }
+ return new ExpressionMask(exp);
+ } catch (ExpressionException e) {
+ throw new InputParseException("Invalid expression: " + e.getMessage());
+ }
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/OffsetMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/OffsetMaskParser.java
new file mode 100644
index 000000000..ab4882e00
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/OffsetMaskParser.java
@@ -0,0 +1,56 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.extension.factory.parser.mask;
+
+import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.extension.input.InputParseException;
+import com.sk89q.worldedit.extension.input.ParserContext;
+import com.sk89q.worldedit.function.mask.ExistingBlockMask;
+import com.sk89q.worldedit.function.mask.Mask;
+import com.sk89q.worldedit.function.mask.MaskIntersection;
+import com.sk89q.worldedit.function.mask.Masks;
+import com.sk89q.worldedit.function.mask.OffsetMask;
+import com.sk89q.worldedit.internal.registry.InputParser;
+import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.session.request.RequestExtent;
+
+public class OffsetMaskParser extends InputParser {
+
+ public OffsetMaskParser(WorldEdit worldEdit) {
+ super(worldEdit);
+ }
+
+ @Override
+ public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
+ final char firstChar = input.charAt(0);
+ if (firstChar != '>' && firstChar != '<') {
+ return null;
+ }
+
+ Mask submask;
+ if (input.length() > 1) {
+ submask = worldEdit.getMaskFactory().parseFromInput(input.substring(1), context);
+ } else {
+ submask = new ExistingBlockMask(new RequestExtent());
+ }
+ OffsetMask offsetMask = new OffsetMask(submask, BlockVector3.at(0, firstChar == '>' ? -1 : 1, 0));
+ return new MaskIntersection(offsetMask, Masks.negate(submask));
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/SolidMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/SolidMaskParser.java
index 84df2fec8..44e2f07a2 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/SolidMaskParser.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/SolidMaskParser.java
@@ -21,13 +21,11 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.WorldEdit;
-import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
-import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.SolidBlockMask;
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
-import com.sk89q.worldedit.session.request.Request;
+import com.sk89q.worldedit.session.request.RequestExtent;
import java.util.List;
@@ -43,9 +41,7 @@ public class SolidMaskParser extends SimpleInputParser {
}
@Override
- public Mask parseFromSimpleInput(String input, ParserContext context) throws InputParseException {
- Extent extent = Request.request().getEditSession();
-
- return new SolidBlockMask(extent);
+ public Mask parseFromSimpleInput(String input, ParserContext context) {
+ return new SolidBlockMask(new RequestExtent());
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java
index 3b89b3cef..b2e9672f5 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java
@@ -26,11 +26,11 @@ import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.RandomPattern;
import com.sk89q.worldedit.internal.registry.InputParser;
-import com.sk89q.worldedit.world.block.BlockCategories;
import com.sk89q.worldedit.world.block.BlockCategory;
import com.sk89q.worldedit.world.block.BlockType;
import java.util.List;
+import java.util.Set;
import java.util.stream.Collectors;
public class BlockCategoryPatternParser extends InputParser {
@@ -46,17 +46,34 @@ public class BlockCategoryPatternParser extends InputParser {
@Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
- if(!input.startsWith("##")) {
+ if (!input.startsWith("##")) {
return null;
}
- BlockCategory category = BlockCategories.get(input.substring(2).toLowerCase());
+ String tag = input.substring(2).toLowerCase();
+ boolean anyState = false;
+ if (tag.startsWith("*")) {
+ tag = tag.substring(1);
+ anyState = true;
+ }
+
+ BlockCategory category = BlockCategory.REGISTRY.get(tag);
if (category == null) {
- throw new InputParseException("Unknown block tag: " + input.substring(2));
+ throw new InputParseException("Unknown block tag: " + tag);
}
RandomPattern randomPattern = new RandomPattern();
- for (BlockType blockType : category.getAll()) {
- randomPattern.add(new BlockPattern(blockType.getDefaultState()), 1.0 / category.getAll().size());
+ Set blocks = category.getAll();
+ if (blocks.isEmpty()) {
+ throw new InputParseException("Block tag " + category.getId() + " had no blocks!");
+ }
+
+ if (anyState) {
+ blocks.stream().flatMap(blockType -> blockType.getAllStates().stream()).forEach(state ->
+ randomPattern.add(new BlockPattern(state), 1.0));
+ } else {
+ for (BlockType blockType : blocks) {
+ randomPattern.add(new BlockPattern(blockType.getDefaultState()), 1.0);
+ }
}
return randomPattern;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/ClipboardPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/ClipboardPatternParser.java
index 720bf8956..1aee6c2a6 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/ClipboardPatternParser.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/ClipboardPatternParser.java
@@ -19,189 +19,68 @@
package com.sk89q.worldedit.extension.factory.parser.pattern;
-import com.boydti.fawe.command.FaweParser;
-import com.boydti.fawe.command.SuggestInputParseException;
-import com.boydti.fawe.config.BBC;
-import com.boydti.fawe.object.random.TrueRandom;
-import com.boydti.fawe.util.StringMan;
-import com.sk89q.minecraft.util.commands.CommandException;
-import com.sk89q.minecraft.util.commands.CommandLocals;
-
import com.google.common.collect.Lists;
import com.sk89q.worldedit.EmptyClipboardException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
-import com.sk89q.worldedit.command.PatternCommands;
import com.sk89q.worldedit.extension.input.InputParseException;
-import com.sk89q.worldedit.extension.input.NoMatchException;
import com.sk89q.worldedit.extension.input.ParserContext;
-import com.sk89q.worldedit.extension.platform.Actor;
+import com.sk89q.worldedit.extent.clipboard.Clipboard;
+import com.sk89q.worldedit.function.pattern.ClipboardPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
-import com.sk89q.worldedit.function.pattern.RandomPattern;
-import com.sk89q.worldedit.internal.command.ActorAuthorizer;
-import com.sk89q.worldedit.internal.command.WorldEditBinding;
-import com.sk89q.worldedit.internal.expression.Expression;
-import com.sk89q.worldedit.internal.expression.ExpressionException;
-import com.sk89q.worldedit.util.command.Dispatcher;
-import com.sk89q.worldedit.util.command.SimpleDispatcher;
-import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
-import com.sk89q.worldedit.world.block.BlockTypes;
+import com.sk89q.worldedit.internal.registry.InputParser;
+import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.session.ClipboardHolder;
-import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-public class ClipboardPatternParser extends FaweParser {
- private final Dispatcher dispatcher;
+public class ClipboardPatternParser extends InputParser {
public ClipboardPatternParser(WorldEdit worldEdit) {
super(worldEdit);
- this.dispatcher = new SimpleDispatcher();
- this.register(new PatternCommands(worldEdit));
}
@Override
- public Dispatcher getDispatcher() {
- return dispatcher;
- }
-
- public void register(Object clazz) {
- ParametricBuilder builder = new ParametricBuilder();
- builder.setAuthorizer(new ActorAuthorizer());
- builder.addBinding(new WorldEditBinding(worldEdit));
- builder.registerMethodsAsCommands(dispatcher, clazz);
+ public List getSuggestions() {
+ return Lists.newArrayList("#clipboard", "#copy");
}
@Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
- if (input.isEmpty()) {
- throw new SuggestInputParseException("No input provided", "", () -> Stream.concat(Stream.of("#", ",", "&"), BlockTypes.getNameSpaces().stream().map(n -> n + ":")).collect(Collectors.toList()));
- }
- List chances = new ArrayList<>();
- List patterns = new ArrayList<>();
- final CommandLocals locals = new CommandLocals();
- Actor actor = context != null ? context.getActor() : null;
- if (actor != null) {
- locals.put(Actor.class, actor);
- }
- try {
- for (Map.Entry> entry : parse(input)) {
- ParseEntry pe = entry.getKey();
- final String command = pe.input;
- String full = pe.full;
- Pattern pattern = null;
- double chance = 1;
- if (command.isEmpty()) {
- pattern = parseFromInput(StringMan.join(entry.getValue(), ','), context);
- } else if (dispatcher.get(command) == null) {
- // Legacy patterns
- char char0 = command.charAt(0);
- boolean charMask = input.length() > 1 && input.charAt(1) != '[';
- if (charMask && input.charAt(0) == '=') {
- return parseFromInput(char0 + "[" + input.substring(1) + "]", context);
- }
- if (char0 == '#') {
- throw new SuggestInputParseException(new NoMatchException("Unknown pattern: " + full + ", See: //patterns"), full,
- () -> {
- if (full.length() == 1) return new ArrayList<>(dispatcher.getPrimaryAliases());
- return dispatcher.getAliases().stream().filter(
- s -> s.startsWith(command.toLowerCase())
- ).collect(Collectors.toList());
- }
- );
- }
-
-
- if (charMask) {
- switch (char0) {
- case '$': {
- String value = command.substring(1) + ((entry.getValue().isEmpty()) ? "" : "[" + StringMan.join(entry.getValue(), "][") + "]");
- if (value.contains(":")) {
- if (value.charAt(0) == ':') value.replaceFirst(":", "");
- value = value.replaceAll(":", "][");
- }
- pattern = parseFromInput(char0 + "[" + value + "]", context);
- break;
- }
- }
- }
- if (pattern == null) {
- if (command.startsWith("[")) {
- int end = command.lastIndexOf(']');
- pattern = parseFromInput(command.substring(1, end == -1 ? command.length() : end), context);
- } else {
- int percentIndex = command.indexOf('%');
- if (percentIndex != -1) { // Legacy percent pattern
- chance = Expression.compile(command.substring(0, percentIndex)).evaluate();
- String value = command.substring(percentIndex + 1);
- if (!entry.getValue().isEmpty()) {
- if (!value.isEmpty()) value += " ";
- value += StringMan.join(entry.getValue(), " ");
- }
- pattern = parseFromInput(value, context);
- } else { // legacy block pattern
- try {
- pattern = worldEdit.getBlockFactory().parseFromInput(pe.full, context);
- } catch (NoMatchException e) {
- throw new NoMatchException(e.getMessage() + " See: //patterns");
- }
- }
- }
- }
- } else {
- List args = entry.getValue();
- String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " "));
- try {
- pattern = (Pattern) dispatcher.call(command + cmdArgs, locals, new String[0]);
- } catch (SuggestInputParseException rethrow) {
- throw rethrow;
- } catch (Throwable e) {
- throw SuggestInputParseException.of(e, full, () -> {
- try {
- List suggestions = dispatcher.get(command).getCallable().getSuggestions(cmdArgs, locals);
- if (suggestions.size() <= 2) {
- for (int i = 0; i < suggestions.size(); i++) {
- String suggestion = suggestions.get(i);
- if (suggestion.indexOf(' ') != 0) {
- String[] split = suggestion.split(" ");
- suggestion = BBC.color("[" + StringMan.join(split, "][") + "]");
- suggestions.set(i, suggestion);
- }
- }
- }
- return suggestions;
- } catch (CommandException e1) {
- throw new InputParseException(e1.getMessage());
- } catch (Throwable e2) {
- e2.printStackTrace();
- throw new InputParseException(e2.getMessage());
- }
- });
- }
- }
- if (pattern != null) {
- patterns.add(pattern);
- chances.add(chance);
- }
- }
- } catch (InputParseException rethrow) {
- throw rethrow;
- } catch (Throwable e) {
- e.printStackTrace();
- throw new InputParseException(e.getMessage(), e);
- }
- if (patterns.isEmpty()) {
+ String[] offsetParts = input.split("@", 2);
+ if (!offsetParts[0].equalsIgnoreCase("#clipboard") && !offsetParts[0].equalsIgnoreCase("#copy")) {
return null;
- } else if (patterns.size() == 1) {
- return patterns.get(0);
+ }
+ LocalSession session = context.requireSession();
+
+ BlockVector3 offset = BlockVector3.ZERO;
+ if (offsetParts.length == 2) {
+ String coords = offsetParts[1];
+ if (coords.length() < 7 // min length of `[x,y,z]`
+ || coords.charAt(0) != '[' || coords.charAt(coords.length() - 1) != ']') {
+ throw new InputParseException("Offset specified with @ but no offset given. Use '#copy@[x,y,z]'.");
+ }
+ String[] offsetSplit = coords.substring(1, coords.length() - 1).split(",");
+ if (offsetSplit.length != 3) {
+ throw new InputParseException("Clipboard offset needs x,y,z coordinates.");
+ }
+ offset = BlockVector3.at(
+ Integer.valueOf(offsetSplit[0]),
+ Integer.valueOf(offsetSplit[1]),
+ Integer.valueOf(offsetSplit[2])
+ );
+ }
+
+ if (session != null) {
+ try {
+ ClipboardHolder holder = session.getClipboard();
+ Clipboard clipboard = holder.getClipboard();
+ return new ClipboardPattern(clipboard, offset);
+ } catch (EmptyClipboardException e) {
+ throw new InputParseException("To use #clipboard, please first copy something to your clipboard");
+ }
} else {
- RandomPattern random = new RandomPattern(new TrueRandom());
- for (int i = 0; i < patterns.size(); i++) {
- random.add(patterns.get(i), chances.get(i));
- }
- return random;
- }
+ throw new InputParseException("No session is available, so no clipboard is available");
+ }
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomPatternParser.java
index f9a05c9e3..a836c1615 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomPatternParser.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomPatternParser.java
@@ -24,11 +24,11 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.factory.BlockFactory;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
-import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.RandomPattern;
import com.sk89q.worldedit.internal.registry.InputParser;
-import com.sk89q.worldedit.world.block.BaseBlock;
+
+import java.util.List;
public class RandomPatternParser extends InputParser {
@@ -38,14 +38,16 @@ public class RandomPatternParser extends InputParser {
@Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
- BlockFactory blockRegistry = worldEdit.getBlockFactory();
RandomPattern randomPattern = new RandomPattern();
String[] splits = input.split(",");
- for (String token : StringUtil.parseListInQuotes(splits, ',', '[', ']')) {
- BaseBlock block;
-
+ List patterns = StringUtil.parseListInQuotes(splits, ',', '[', ']');
+ if (patterns.size() == 1) {
+ return null; // let a 'single'-pattern parser handle it
+ }
+ for (String token : patterns) {
double chance;
+ Pattern innerPattern;
// Parse special percentage syntax
if (token.matches("[0-9]+(\\.[0-9]*)?%.*")) {
@@ -55,14 +57,14 @@ public class RandomPatternParser extends InputParser {
throw new InputParseException("Missing the type after the % symbol for '" + input + "'");
} else {
chance = Double.parseDouble(p[0]);
- block = blockRegistry.parseFromInput(p[1], context);
+ innerPattern = worldEdit.getPatternFactory().parseFromInput(p[1], context);
}
} else {
chance = 1;
- block = blockRegistry.parseFromInput(token, context);
+ innerPattern = worldEdit.getPatternFactory().parseFromInput(token, context);
}
- randomPattern.add(block, chance);
+ randomPattern.add(innerPattern, chance);
}
return randomPattern;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomStatePatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomStatePatternParser.java
new file mode 100644
index 000000000..27423f59e
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomStatePatternParser.java
@@ -0,0 +1,56 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.extension.factory.parser.pattern;
+
+import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.extension.input.InputParseException;
+import com.sk89q.worldedit.extension.input.ParserContext;
+import com.sk89q.worldedit.function.pattern.BlockPattern;
+import com.sk89q.worldedit.function.pattern.Pattern;
+import com.sk89q.worldedit.function.pattern.RandomStatePattern;
+import com.sk89q.worldedit.internal.registry.InputParser;
+import com.sk89q.worldedit.world.block.BaseBlock;
+import com.sk89q.worldedit.world.block.FuzzyBlockState;
+
+public class RandomStatePatternParser extends InputParser {
+ public RandomStatePatternParser(WorldEdit worldEdit) {
+ super(worldEdit);
+ }
+
+ @Override
+ public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
+ if (!input.startsWith("*")) {
+ return null;
+ }
+
+ boolean wasFuzzy = context.isPreferringWildcard();
+ context.setPreferringWildcard(true);
+ BaseBlock block = worldEdit.getBlockFactory().parseFromInput(input.substring(1), context);
+ context.setPreferringWildcard(wasFuzzy);
+ if (block.getStates().size() == block.getBlockType().getPropertyMap().size()) {
+ // they requested random with *, but didn't leave any states empty - simplify
+ return new BlockPattern(block);
+ } else if (block.toImmutableState() instanceof FuzzyBlockState) {
+ return new RandomStatePattern((FuzzyBlockState) block.toImmutableState());
+ } else {
+ return null; // only should happen if parseLogic changes
+ }
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/SingleBlockPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/SingleBlockPatternParser.java
index 960983780..e71530a2e 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/SingleBlockPatternParser.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/SingleBlockPatternParser.java
@@ -34,13 +34,7 @@ public class SingleBlockPatternParser extends InputParser {
@Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
- String[] items = input.split(",");
-
- if (items.length == 1) {
- return new BlockPattern(worldEdit.getBlockFactory().parseFromInput(items[0], context));
- } else {
- return null;
- }
+ return new BlockPattern(worldEdit.getBlockFactory().parseFromInput(input, context));
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/TypeOrStateApplyingPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/TypeOrStateApplyingPatternParser.java
new file mode 100644
index 000000000..db0ee8c38
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/TypeOrStateApplyingPatternParser.java
@@ -0,0 +1,79 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.extension.factory.parser.pattern;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.extension.input.InputParseException;
+import com.sk89q.worldedit.extension.input.ParserContext;
+import com.sk89q.worldedit.extent.Extent;
+import com.sk89q.worldedit.extent.buffer.ExtentBuffer;
+import com.sk89q.worldedit.function.pattern.ExtentBufferedCompositePattern;
+import com.sk89q.worldedit.function.pattern.Pattern;
+import com.sk89q.worldedit.function.pattern.StateApplyingPattern;
+import com.sk89q.worldedit.function.pattern.TypeApplyingPattern;
+import com.sk89q.worldedit.internal.registry.InputParser;
+import com.sk89q.worldedit.world.block.BlockState;
+
+import java.util.Map;
+import java.util.Set;
+
+
+public class TypeOrStateApplyingPatternParser extends InputParser {
+
+ public TypeOrStateApplyingPatternParser(WorldEdit worldEdit) {
+ super(worldEdit);
+ }
+
+ @Override
+ public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
+ if (!input.startsWith("^")) {
+ return null;
+ }
+ Extent extent = context.requireExtent();
+ input = input.substring(1);
+
+ String[] parts = input.split("\\[", 2);
+ String type = parts[0];
+
+ if (parts.length == 1) {
+ return new TypeApplyingPattern(extent,
+ worldEdit.getBlockFactory().parseFromInput(type, context).getBlockType().getDefaultState());
+ } else {
+ // states given
+ if (!parts[1].endsWith("]")) throw new InputParseException("Invalid state format.");
+ Map statesToSet = Splitter.on(',')
+ .omitEmptyStrings().trimResults().withKeyValueSeparator('=')
+ .split(parts[1].substring(0, parts[1].length() - 1));
+ if (type.isEmpty()) {
+ return new StateApplyingPattern(extent, statesToSet);
+ } else {
+ Extent buffer = new ExtentBuffer(extent);
+ Pattern typeApplier = new TypeApplyingPattern(buffer,
+ worldEdit.getBlockFactory().parseFromInput(type, context).getBlockType().getDefaultState());
+ Pattern stateApplier = new StateApplyingPattern(buffer, statesToSet);
+ return new ExtentBufferedCompositePattern(buffer, typeApplier, stateApplier);
+ }
+ }
+ }
+
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java
index 66fb43d85..8992ac465 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java
@@ -19,8 +19,8 @@
package com.sk89q.worldedit.extension.platform;
+import com.sk89q.worldedit.NotABlockException;
import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.internal.cui.CUIEvent;
@@ -31,6 +31,7 @@ import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.TargetBlock;
import com.sk89q.worldedit.util.auth.AuthorizationException;
+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;
@@ -118,7 +119,6 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
final BlockVector3 pos = BlockVector3.at(x, y - 2, z);
final BlockStateHolder state = world.getBlock(pos);
setPosition(Vector3.at(x + 0.5, y - 2 + BlockTypeUtil.centralTopLimit(state), z + 0.5));
-// setPosition(Vector3.at(x + 0.5, y - 2 + 1, z + 0.5));
}
return;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java
index 8ecbef23c..4a65ccd30 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java
@@ -43,9 +43,10 @@ import com.sk89q.worldedit.command.composition.ApplyCommand;
import com.sk89q.worldedit.command.composition.DeformCommand;
import com.sk89q.worldedit.command.composition.PaintCommand;
import com.sk89q.worldedit.command.composition.ShapedBrushCommand;
-import com.sk89q.worldedit.entity.Player;
+import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
+import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.factory.Deform;
import com.sk89q.worldedit.function.factory.Deform.Mode;
import com.sk89q.worldedit.internal.command.*;
@@ -60,6 +61,9 @@ import com.sk89q.worldedit.util.command.parametric.*;
import com.sk89q.worldedit.util.eventbus.Subscribe;
import com.sk89q.worldedit.util.logging.DynamicStreamHandler;
import com.sk89q.worldedit.util.logging.LogFormat;
+import com.sk89q.worldedit.world.World;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.File;
@@ -72,7 +76,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import java.util.logging.FileHandler;
import java.util.logging.Level;
-import java.util.logging.Logger;
import java.util.regex.Pattern;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -86,8 +89,9 @@ import static com.sk89q.worldedit.util.command.composition.LegacyCommandAdapter.
public final class CommandManager {
public static final Pattern COMMAND_CLEAN_PATTERN = Pattern.compile("^[/]+");
- private static final Logger log = Logger.getLogger(CommandManager.class.getCanonicalName());
- private static final Logger commandLog = Logger.getLogger(CommandManager.class.getCanonicalName() + ".CommandLog");
+ private static final Logger log = LoggerFactory.getLogger(CommandManager.class);
+ private static final java.util.logging.Logger commandLog =
+ java.util.logging.Logger.getLogger(CommandManager.class.getCanonicalName() + ".CommandLog");
private static final Pattern numberFormatExceptionPattern = Pattern.compile("^For input string: \"(.*)\"$");
private final WorldEdit worldEdit;
@@ -297,7 +301,7 @@ public final class CommandManager {
}
public void register(Platform platform) {
- log.log(Level.FINE, "Registering commands with " + platform.getClass().getCanonicalName());
+ log.info("Registering commands with " + platform.getClass().getCanonicalName());
this.platform = null;
try {
@@ -318,12 +322,12 @@ public final class CommandManager {
File file = new File(config.getWorkingDirectory(), path);
commandLog.setLevel(Level.ALL);
- log.log(Level.INFO, "Logging WorldEdit commands to " + file.getAbsolutePath());
+ log.info("Logging WorldEdit commands to " + file.getAbsolutePath());
try {
dynamicHandler.setHandler(new FileHandler(file.getAbsolutePath(), true));
} catch (IOException e) {
- log.log(Level.WARNING, "Could not use command log file " + path + ": " + e.getMessage());
+ log.warn("Could not use command log file " + path + ": " + e.getMessage());
}
}
@@ -371,6 +375,13 @@ public final class CommandManager {
actor = FakePlayer.wrap(actor.getName(), actor.getUniqueId(), actor);
}
final LocalSession session = worldEdit.getSessionManager().get(actor);
+ Request.request().setSession(session);
+ if (actor instanceof Entity) {
+ Extent extent = ((Entity) actor).getExtent();
+ if (extent instanceof World) {
+ Request.request().setWorld(((World) extent));
+ }
+ }
LocalConfiguration config = worldEdit.getConfiguration();
final CommandLocals locals = new CommandLocals();
final FawePlayer fp = FawePlayer.wrap(actor);
@@ -497,8 +508,8 @@ public final class CommandManager {
if (time > 1000) {
BBC.ACTION_COMPLETE.send(actor, (time / 1000d));
}
- Request.reset();
}
+ Request.reset();
}
return null;
}
@@ -552,7 +563,7 @@ public final class CommandManager {
return dispatcher;
}
- public static Logger getLogger() {
+ public static java.util.logging.Logger getLogger() {
return commandLog;
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java
index 38f4654cd..b0cd5c41d 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java
@@ -28,14 +28,10 @@ import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.wrappers.LocationMaskedPlayerWrapper;
import com.boydti.fawe.wrappers.PlayerWrapper;
import com.boydti.fawe.wrappers.WorldWrapper;
-import com.sk89q.worldedit.command.tool.*;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.tool.BlockTool;
-import com.sk89q.worldedit.command.tool.DoubleActionBlockTool;
import com.sk89q.worldedit.command.tool.DoubleActionTraceTool;
import com.sk89q.worldedit.command.tool.Tool;
import com.sk89q.worldedit.command.tool.TraceTool;
@@ -43,31 +39,29 @@ import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.platform.*;
import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.session.request.Request;
-import com.sk89q.worldedit.util.HandSide;
-import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.eventbus.Subscribe;
-import com.sk89q.worldedit.world.World;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Manages registered {@link Platform}s for WorldEdit. Platforms are
* implementations of WorldEdit.
- *
*
This class is thread-safe.
*/
public class PlatformManager {
- private static final Logger logger = Logger.getLogger(PlatformManager.class.getCanonicalName());
+ private static final Logger logger = LoggerFactory.getLogger(PlatformManager.class);
private final WorldEdit worldEdit;
private final CommandManager commandManager;
@@ -99,7 +93,7 @@ public class PlatformManager {
public synchronized void register(Platform platform) {
checkNotNull(platform);
- logger.log(Level.FINE, "Got request to register " + platform.getClass() + " with WorldEdit [" + super.toString() + "]");
+ logger.info("Got request to register " + platform.getClass() + " with WorldEdit [" + super.toString() + "]");
// Just add the platform to the list of platforms: we'll pick favorites
// once all the platforms have been loaded
@@ -108,7 +102,7 @@ public class PlatformManager {
// Make sure that versions are in sync
if (firstSeenVersion != null) {
if (!firstSeenVersion.equals(platform.getVersion())) {
- logger.log(Level.WARNING, "Multiple ports of WorldEdit are installed but they report different versions ({0} and {1}). " +
+ logger.warn("Multiple ports of WorldEdit are installed but they report different versions ({0} and {1}). " +
"If these two versions are truly different, then you may run into unexpected crashes and errors.",
new Object[]{firstSeenVersion, platform.getVersion()});
}
@@ -131,7 +125,7 @@ public class PlatformManager {
boolean removed = platforms.remove(platform);
if (removed) {
- logger.log(Level.FINE, "Unregistering " + platform.getClass().getCanonicalName() + " from WorldEdit");
+ logger.info("Unregistering " + platform.getClass().getCanonicalName() + " from WorldEdit");
boolean choosePreferred = false;
@@ -356,7 +350,6 @@ public class PlatformManager {
return;
}
}
-//<<<<<<< HEAD
final Tool tool = session.getTool(playerActor);
if (tool != null && tool instanceof DoubleActionBlockTool) {
if (tool.canUse(playerActor)) {
@@ -371,14 +364,6 @@ public class PlatformManager {
event.setCancelled(true);
return;
}
-//=======
-//
-// RegionSelector selector = session.getRegionSelector(player.getWorld());
-//
-// BlockVector3 blockPoint = vector.toBlockPoint();
-// if (selector.selectPrimary(blockPoint, ActorSelectorLimits.forActor(player))) {
-// selector.explainPrimarySelection(actor, session, blockPoint);
-//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
}
} else if (event.getType() == Interaction.OPEN) {
if (session.isToolControlEnabled() && playerActor.getItemInHand(HandSide.MAIN_HAND).getType().getId().equals(getConfiguration().wandItem)) {
@@ -402,7 +387,6 @@ public class PlatformManager {
return;
}
-//<<<<<<< HEAD
final Tool tool = session.getTool(playerActor);
if (tool != null && tool instanceof BlockTool) {
if (tool.canUse(playerActor)) {
@@ -423,25 +407,10 @@ public class PlatformManager {
return;
}
}
-//=======
-// RegionSelector selector = session.getRegionSelector(player.getWorld());
-// BlockVector3 blockPoint = vector.toBlockPoint();
-// if (selector.selectSecondary(blockPoint, ActorSelectorLimits.forActor(player))) {
-// selector.explainSecondarySelection(actor, session, blockPoint);
-// }
-//
-// event.setCancelled(true);
-// return;
-// }
-//
-// Tool tool = session.getTool(player.getItemInHand(HandSide.MAIN_HAND).getType());
-// if (tool instanceof BlockTool) {
-// if (tool.canUse(player)) {
-// ((BlockTool) tool).actPrimary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session, location);
-// event.setCancelled(true);
-//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
}
}
+ } finally {
+ Request.reset();
}
} catch (Throwable e) {
handleThrowable(e, actor);
@@ -559,6 +528,8 @@ public class PlatformManager {
player.printRaw(e.getClass().getName() + ": " + e.getMessage());
MainUtil.handleError(e);
}
+ } finally {
+ Request.reset();
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java
index 1aa31fdd8..a366b42df 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java
@@ -22,11 +22,9 @@ package com.sk89q.worldedit.extent;
import com.boydti.fawe.jnbt.anvil.generator.GenBase;
import com.boydti.fawe.jnbt.anvil.generator.Resource;
import com.boydti.fawe.object.extent.LightingExtent;
-import com.sk89q.worldedit.WorldEditException;
-
-import com.sk89q.worldedit.world.block.BlockState;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.world.block.BaseBlock;
+
+import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.function.mask.Mask;
@@ -38,16 +36,13 @@ import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
-import com.sk89q.worldedit.world.biome.BaseBiome;
+import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import java.util.List;
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;
@@ -126,10 +121,7 @@ public class AbstractDelegateExtent implements LightingExtent {
@Override
public BlockState getLazyBlock(int x, int y, int z) {
-// mutable.mutX(x);
-// mutable.mutY(y);
-// mutable.mutZ(z);
- return extent.getLazyBlock(BlockVector3.at(x, y, z));
+ return extent.getLazyBlock(mutable.setComponents(x, y, z));
}
@Override
@@ -139,20 +131,22 @@ public class AbstractDelegateExtent implements LightingExtent {
@Override
public > boolean setBlock(int x, int y, int z, T block) throws WorldEditException {
-// mutable.mutX(x);
-// mutable.mutY(y);
-// mutable.mutZ(z);
- return setBlock(BlockVector3.at(x, y, z), block);
+ return setBlock(mutable.setComponents(x, y, z), block);
+ }
+
+ public BlockState getBlock(BlockVector3 position) {
+ return extent.getBlock(position);
+ }
+
+ @Override
+ public BaseBlock getFullBlock(BlockVector3 position) {
+ return extent.getFullBlock(position);
}
@Override
public > boolean setBlock(BlockVector3 location, T block) throws WorldEditException {
return extent.setBlock(location, block);
}
-
- public BlockState getBlock(BlockVector3 position) {
- return extent.getBlock(position);
- }
@Override
@Nullable
@@ -171,17 +165,17 @@ public class AbstractDelegateExtent implements LightingExtent {
}
@Override
- public BaseBiome getBiome(BlockVector2 position) {
+ public BiomeType getBiome(BlockVector2 position) {
return extent.getBiome(position);
}
@Override
- public boolean setBiome(BlockVector2 position, BaseBiome biome) {
+ public boolean setBiome(BlockVector2 position, BiomeType biome) {
return extent.setBiome(position, biome);
}
@Override
- public boolean setBiome(int x, int y, int z, BaseBiome biome) {
+ public boolean setBiome(int x, int y, int z, BiomeType biome) {
return extent.setBiome(x, y, z, biome);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java
index a53638f3b..284cf044a 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java
@@ -25,7 +25,6 @@ import com.sk89q.worldedit.world.block.BlockState;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.history.change.BiomeChange;
@@ -37,9 +36,7 @@ import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
-
-import javax.annotation.Nullable;
-import com.sk89q.worldedit.world.biome.BaseBiome;
+import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder;
@@ -69,15 +66,15 @@ public class ChangeSetExtent extends AbstractDelegateExtent {
@Override
public > boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
- BlockStateHolder previous = getBlock(location);
+ BaseBlock previous = getFullBlock(location);
changeSet.add(new BlockChange(location, previous, block));
return super.setBlock(location, block);
}
@Override
- public boolean setBiome(BlockVector2 position, BaseBiome biome) {
- BaseBiome previous = getBiome(position);
- changeSet.add(new BiomeChange(position, previous, new BaseBiome(biome)));
+ public boolean setBiome(BlockVector2 position, BiomeType biome) {
+ BiomeType previous = getBiome(position);
+ changeSet.add(new BiomeChange(position, previous, biome));
return super.setBiome(position, biome);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java
index cca0e4075..0a5a951e0 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java
@@ -22,25 +22,12 @@ package com.sk89q.worldedit.extent;
import com.boydti.fawe.jnbt.anvil.generator.*;
import com.boydti.fawe.object.PseudoRandom;
import com.boydti.fawe.object.clipboard.WorldCopyClipboard;
-import com.sk89q.worldedit.*;
-
-import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
-import com.sk89q.worldedit.regions.CuboidRegion;
-import com.sk89q.worldedit.util.Countable;
-import com.sk89q.worldedit.world.block.*;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
-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.registry.state.PropertyGroup;
-import com.sk89q.worldedit.session.ClipboardHolder;
-import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
-import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
-import com.sk89q.worldedit.world.biome.BaseBiome;
+import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockState;
import javax.annotation.Nullable;
@@ -134,7 +121,7 @@ public interface Extent extends InputExtent, OutputExtent {
return setBlock(BlockVector3.at(x, y, z), state);
}
- default boolean setBiome(int x, int y, int z, BaseBiome biome) {
+ default boolean setBiome(int x, int y, int z, BiomeType biome) {
return setBiome(BlockVector2.at(x, z), biome);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java
index 34a0994fa..8ce3dc1fa 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java
@@ -19,12 +19,12 @@
package com.sk89q.worldedit.extent;
-import com.sk89q.worldedit.world.block.BlockState;
-import com.sk89q.worldedit.world.block.BaseBlock;
+import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
-import com.sk89q.worldedit.world.biome.BaseBiome;
-import com.sk89q.worldedit.world.block.BlockType;
+import com.sk89q.worldedit.world.biome.BiomeType;
+import com.sk89q.worldedit.world.block.BaseBlock;
+import com.sk89q.worldedit.world.block.BlockState;
/**
* Provides the current state of blocks, entities, and so on.
@@ -91,6 +91,6 @@ public interface InputExtent {
* @param position the (x, z) location to check the biome at
* @return the biome at the location
*/
- BaseBiome getBiome(BlockVector2 position);
+ BiomeType getBiome(BlockVector2 position);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java
index 787073d21..4fd83e2da 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java
@@ -25,8 +25,6 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.function.mask.Mask;
-import com.sk89q.worldedit.world.biome.BaseBiome;
-import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockStateHolder;
@@ -78,12 +76,12 @@ public class MaskingExtent extends AbstractDelegateExtent {
}
@Override
- public boolean setBiome(BlockVector2 position, BaseBiome biome) {
+ public boolean setBiome(BlockVector2 position, BiomeType biome) {
return mask.test(position.toBlockVector3()) && super.setBiome(position, biome);
}
@Override
- public boolean setBiome(int x, int y, int z, BaseBiome biome) {
+ public boolean setBiome(int x, int y, int z, BiomeType biome) {
return mask.test(BlockVector3.at(x, y, z)) && super.setBiome(x, y, z, biome);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/NullExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/NullExtent.java
index 074bf9dff..ec4c276a7 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/NullExtent.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/NullExtent.java
@@ -20,16 +20,6 @@
package com.sk89q.worldedit.extent;
import com.sk89q.worldedit.WorldEditException;
-
-import com.sk89q.worldedit.world.block.BlockState;
-import com.sk89q.worldedit.blocks.LazyBlock;
-import com.sk89q.worldedit.world.block.BlockState;
-import com.sk89q.worldedit.world.block.BlockStateHolder;
-import com.sk89q.worldedit.world.block.BlockTypes;
-import com.sk89q.worldedit.world.block.BaseBlock;
-import com.sk89q.worldedit.entity.BaseEntity;
-import com.sk89q.worldedit.entity.Entity;
-import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.function.operation.Operation;
@@ -37,8 +27,9 @@ import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
-import com.sk89q.worldedit.regions.Region;
-import com.sk89q.worldedit.world.biome.BaseBiome;
+import com.sk89q.worldedit.world.biome.BiomeType;
+import com.sk89q.worldedit.world.biome.BiomeTypes;
+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.BlockTypes;
@@ -53,8 +44,6 @@ import java.util.List;
*/
public class NullExtent implements Extent {
- private final BlockVector3 nullPoint = BlockVector3.at(0, 0, 0);
-
public static final NullExtent INSTANCE = new NullExtent();
@Override
@@ -93,29 +82,22 @@ public class NullExtent implements Extent {
}
@Override
-
public BaseBlock getFullBlock(BlockVector3 position) {
return getBlock(position).toBaseBlock();
}
- @Nullable
@Override
- public BaseBiome getBiome(BlockVector2 position) {
- return null;
+ public BiomeType getBiome(BlockVector2 position) {
+ return BiomeTypes.THE_VOID;
}
@Override
public > boolean setBlock(BlockVector3 position, B block) throws WorldEditException {
return false;
}
-
- @Override
- public > boolean setBlock(int x, int y, int z, B block) throws WorldEditException {
- return false;
- }
@Override
- public boolean setBiome(BlockVector2 position, BaseBiome biome) {
+ public boolean setBiome(BlockVector2 position, BiomeType biome) {
return false;
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java
index 18f7f1675..53351e0b0 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java
@@ -23,7 +23,7 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
-import com.sk89q.worldedit.world.biome.BaseBiome;
+import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import javax.annotation.Nullable;
@@ -50,7 +50,7 @@ public interface OutputExtent {
* @return true if the block was successfully set (return value may not be accurate)
* @throws WorldEditException thrown on an error
*/
- > boolean setBlock(BlockVector3 position, T block) throws WorldEditException;
+ > boolean setBlock(BlockVector3 position, T block) throws WorldEditException;
/**
* Set the biome.
@@ -59,7 +59,7 @@ public interface OutputExtent {
* @param biome the biome to set to
* @return true if the biome was successfully set (return value may not be accurate)
*/
- boolean setBiome(BlockVector2 position, BaseBiome biome);
+ boolean setBiome(BlockVector2 position, BiomeType biome);
/**
* Return an {@link Operation} that should be called to tie up loose ends
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ExtentBuffer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ExtentBuffer.java
new file mode 100644
index 000000000..562f094e5
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ExtentBuffer.java
@@ -0,0 +1,97 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.extent.buffer;
+
+import com.google.common.collect.Maps;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.extent.AbstractDelegateExtent;
+import com.sk89q.worldedit.extent.Extent;
+import com.sk89q.worldedit.function.mask.Mask;
+import com.sk89q.worldedit.function.mask.Masks;
+import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.world.block.BaseBlock;
+import com.sk89q.worldedit.world.block.BlockState;
+import com.sk89q.worldedit.world.block.BlockStateHolder;
+
+import java.util.Map;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Buffers changes to an {@link Extent} and allows retrieval of the changed blocks,
+ * without modifying the underlying extent.
+ */
+public class ExtentBuffer extends AbstractDelegateExtent {
+
+ private final Map buffer = Maps.newHashMap();
+ private final Mask mask;
+
+ /**
+ * Create a new extent buffer that will buffer every change.
+ *
+ * @param delegate the delegate extent for {@link Extent#getBlock(BlockVector3)}, etc. calls
+ */
+ public ExtentBuffer(Extent delegate) {
+ this(delegate, Masks.alwaysTrue());
+ }
+
+ /**
+ * Create a new extent buffer that will buffer changes that meet the criteria
+ * of the given mask.
+ *
+ * @param delegate the delegate extent for {@link Extent#getBlock(BlockVector3)}, etc. calls
+ * @param mask the mask
+ */
+ public ExtentBuffer(Extent delegate, Mask mask) {
+ super(delegate);
+ checkNotNull(delegate);
+ checkNotNull(mask);
+ this.mask = mask;
+ }
+
+ @Override
+ public BlockState getBlock(BlockVector3 position) {
+ if (mask.test(position)) {
+ return getOrDefault(position).toImmutableState();
+ }
+ return super.getBlock(position);
+ }
+
+ @Override
+ public BaseBlock getFullBlock(BlockVector3 position) {
+ if (mask.test(position)) {
+ return getOrDefault(position);
+ }
+ return super.getFullBlock(position);
+ }
+
+ private BaseBlock getOrDefault(BlockVector3 position) {
+ return buffer.computeIfAbsent(position, (pos -> getExtent().getFullBlock(pos)));
+ }
+
+ @Override
+ public > boolean setBlock(BlockVector3 location, T block) throws WorldEditException {
+ if (mask.test(location)) {
+ buffer.put(location, block.toBaseBlock());
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java
index 3c1ffa4f5..7b98adbd0 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java
@@ -40,7 +40,6 @@ import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
-import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import java.io.Closeable;
@@ -138,7 +137,7 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
@Override
public Region getRegion() {
- return region.clone();
+ return region;
}
public void setRegion(Region region) {
@@ -209,20 +208,9 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
}
@Override
-//<<<<<<< HEAD
public BlockState getLazyBlock(BlockVector3 position) {
return getBlock(position);
}
-//=======
-// public BaseBlock getFullBlock(BlockVector3 position) {
-// if (region.contains(position)) {
-// BlockVector3 v = position.subtract(region.getMinimumPoint());
-// BlockStateHolder block = blocks[v.getBlockX()][v.getBlockY()][v.getBlockZ()];
-// if (block != null) {
-// return block.toBaseBlock();
-// }
-// }
-//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
@@ -262,17 +250,17 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
}
@Override
- public BaseBiome getBiome(BlockVector2 position) {
+ public BiomeType getBiome(BlockVector2 position) {
int x = position.getBlockX() - mx;
int z = position.getBlockZ() - mz;
return IMP.getBiome(x, z);
}
@Override
- public boolean setBiome(BlockVector2 position, BaseBiome biome) {
+ public boolean setBiome(BlockVector2 position, BiomeType biome) {
int x = position.getBlockX() - mx;
int z = position.getBlockZ() - mz;
- IMP.setBiome(x, z, biome.getId());
+ IMP.setBiome(x, z, biome);
return true;
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java
index e2598b3f8..4336a16f3 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java
@@ -58,7 +58,7 @@ import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
-import javax.annotation.Nullable;
+import static com.google.common.base.Preconditions.checkNotNull;
public class ClipboardFormats {
@@ -74,7 +74,7 @@ public class ClipboardFormats {
ClipboardFormat old = aliasMap.put(lowKey, format);
if (old != null) {
aliasMap.put(lowKey, old);
- WorldEdit.logger.warning(format.getClass().getName() + " cannot override existing alias '" + lowKey + "' used by " + old.getClass().getName());
+ WorldEdit.logger.warn(format.getClass().getName() + " cannot override existing alias '" + lowKey + "' used by " + old.getClass().getName());
}
}
for (String ext : format.getFileExtensions()) {
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java
index 94b67a3db..00e52e902 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java
@@ -19,8 +19,6 @@
package com.sk89q.worldedit.extent.clipboard.io;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.sk89q.jnbt.ByteArrayTag;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.IntTag;
@@ -46,14 +44,16 @@ import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.entity.EntityTypes;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import com.sk89q.worldedit.world.storage.NBTConversions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+
+import static com.google.common.base.Preconditions.checkNotNull;
/**
* Reads schematic files that are compatible with MCEdit and other editors.
@@ -67,7 +67,7 @@ public class MCEditSchematicReader extends NBTSchematicReader {
// TODO Add a handler for skulls, flower pots, note blocks, etc.
}
- private static final Logger log = Logger.getLogger(MCEditSchematicReader.class.getCanonicalName());
+ private static final Logger log = LoggerFactory.getLogger(MCEditSchematicReader.class);
private final NBTInputStream inputStream;
/**
@@ -231,15 +231,15 @@ public class MCEditSchematicReader extends NBTSchematicReader {
clipboard.setBlock(region.getMinimumPoint().add(pt), state);
}
} else {
- log.warning("Unknown block when pasting schematic: " + blocks[index] + ":" + blockData[index] + ". Please report this issue.");
+ log.warn("Unknown block when pasting schematic: " + blocks[index] + ":" + blockData[index] + ". Please report this issue.");
}
} catch (WorldEditException e) {
switch (failedBlockSets) {
case 0:
- log.log(Level.WARNING, "Failed to set block on a Clipboard", e);
+ log.warn("Failed to set block on a Clipboard", e);
break;
case 1:
- log.log(Level.WARNING, "Failed to set block on a Clipboard (again) -- no more messages will be logged", e);
+ log.warn("Failed to set block on a Clipboard (again) -- no more messages will be logged", e);
break;
default:
}
@@ -254,9 +254,8 @@ public class MCEditSchematicReader extends NBTSchematicReader {
// Entities
// ====================================================================
- try {
- List entityTags = requireTag(schematic, "Entities", ListTag.class).getValue();
-
+ List entityTags = getTag(schematic, "Entities", ListTag.class).getValue();
+ if (entityTags != null) {
for (Tag tag : entityTags) {
if (tag instanceof CompoundTag) {
CompoundTag compound = (CompoundTag) tag;
@@ -269,12 +268,11 @@ public class MCEditSchematicReader extends NBTSchematicReader {
BaseEntity state = new BaseEntity(entityType, compound);
clipboard.createEntity(location, state);
} else {
- log.warning("Unknown entity when pasting schematic: " + id.toLowerCase());
+ log.warn("Unknown entity when pasting schematic: " + id.toLowerCase());
}
}
}
}
- } catch (IOException ignored) { // No entities? No problem
}
return clipboard;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/NBTSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/NBTSchematicReader.java
index 424dffcc6..12f1f1b41 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/NBTSchematicReader.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/NBTSchematicReader.java
@@ -46,9 +46,7 @@ public abstract class NBTSchematicReader implements ClipboardReader {
}
@Nullable
- protected static T getTag(CompoundTag tag, Class expected, String key) {
- Map items = tag.getValue();
-
+ protected static T getTag(Map items, String key, Class expected) {
if (!items.containsKey(key)) {
return null;
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java
index a7661ed9b..1aa22a9e5 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java
@@ -86,7 +86,7 @@ public class SpongeSchematicReader extends NBTSchematicReader {
// If NBT Compat handlers are needed - add them here.
}
- private static final Logger log = Logger.getLogger(SpongeSchematicReader.class.getCanonicalName());
+ private static final Logger log = LoggerFactory.getLogger(SpongeSchematicReader.class);
private final NBTInputStream inputStream;
/**
@@ -108,12 +108,7 @@ public class SpongeSchematicReader extends NBTSchematicReader {
public Clipboard read(UUID uuid) throws IOException {
return readVersion1(uuid);
}
-// private Clipboard readVersion1(Map schematic) throws IOException {
-// BlockVector3 origin;
-// Region region;
-//
-// Map metadata = requireTag(schematic, "Metadata", CompoundTag.class).getValue();
-// }
+
private int width, height, length;
private int offsetX, offsetY, offsetZ;
private char[] palette;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java
index 6a2686483..b8f6082c4 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java
@@ -72,6 +72,10 @@ public class ChunkBatchingExtent extends AbstractDelegateExtent {
this.enabled = enabled;
}
+ public boolean commitRequired() {
+ return enabled;
+ }
+
@Override
public > boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
if (!enabled) {
@@ -84,7 +88,7 @@ public class ChunkBatchingExtent extends AbstractDelegateExtent {
@Override
protected Operation commitBefore() {
- if (!enabled) {
+ if (!commitRequired()) {
return null;
}
return new Operation() {
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java
index 918a03fbf..845444ef8 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java
@@ -20,43 +20,136 @@
package com.sk89q.worldedit.extent.reorder;
import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.blocks.Blocks;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.OperationQueue;
-import com.sk89q.worldedit.function.operation.RunContext;
import com.sk89q.worldedit.function.operation.SetLocatedBlocks;
import com.sk89q.worldedit.math.BlockVector3;
-import com.sk89q.worldedit.registry.state.Property;
-import com.sk89q.worldedit.util.LocatedBlock;
import com.sk89q.worldedit.util.collection.LocatedBlockList;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockCategories;
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.Deque;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Set;
/**
* Re-orders blocks into several stages.
*/
public class MultiStageReorder extends AbstractDelegateExtent implements ReorderingExtent {
- private static final int STAGE_COUNT = 4;
+ private static final Map priorityMap = new HashMap<>();
- private List stages = new ArrayList<>();
+ static {
+ // Late
+ priorityMap.put(BlockTypes.WATER, PlacementPriority.LATE);
+ priorityMap.put(BlockTypes.LAVA, PlacementPriority.LATE);
+ priorityMap.put(BlockTypes.SAND, PlacementPriority.LATE);
+ priorityMap.put(BlockTypes.GRAVEL, PlacementPriority.LATE);
+
+ // Late
+ BlockCategories.SAPLINGS.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.LAST));
+ BlockCategories.FLOWER_POTS.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.LAST));
+ BlockCategories.BUTTONS.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.LAST));
+ BlockCategories.ANVIL.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.LAST));
+ BlockCategories.WOODEN_PRESSURE_PLATES.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.LAST));
+ BlockCategories.CARPETS.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.LAST));
+ BlockCategories.RAILS.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.LAST));
+ priorityMap.put(BlockTypes.BLACK_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.BLUE_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.BROWN_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.CYAN_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.GRAY_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.GREEN_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.LIGHT_BLUE_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.LIGHT_GRAY_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.LIME_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.MAGENTA_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.ORANGE_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.PINK_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.PURPLE_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.RED_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.WHITE_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.YELLOW_BED, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.GRASS, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.TALL_GRASS, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.ROSE_BUSH, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.DANDELION, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.BROWN_MUSHROOM, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.RED_MUSHROOM, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.FERN, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.LARGE_FERN, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.OXEYE_DAISY, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.AZURE_BLUET, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.TORCH, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.WALL_TORCH, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.FIRE, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.REDSTONE_WIRE, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.CARROTS, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.POTATOES, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.WHEAT, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.BEETROOTS, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.COCOA, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.LADDER, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.LEVER, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.REDSTONE_TORCH, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.REDSTONE_WALL_TORCH, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.SNOW, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.NETHER_PORTAL, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.END_PORTAL, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.REPEATER, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.VINE, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.LILY_PAD, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.NETHER_WART, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.PISTON, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.STICKY_PISTON, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.TRIPWIRE_HOOK, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.TRIPWIRE, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.STONE_PRESSURE_PLATE, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.HEAVY_WEIGHTED_PRESSURE_PLATE, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.LIGHT_WEIGHTED_PRESSURE_PLATE, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.COMPARATOR, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.IRON_TRAPDOOR, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.ACACIA_TRAPDOOR, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.BIRCH_TRAPDOOR, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.DARK_OAK_TRAPDOOR, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.JUNGLE_TRAPDOOR, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.OAK_TRAPDOOR, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.SPRUCE_TRAPDOOR, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.DAYLIGHT_DETECTOR, PlacementPriority.LAST);
+ priorityMap.put(BlockTypes.CAKE, PlacementPriority.LAST);
+
+ // Final
+ BlockCategories.DOORS.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.FINAL));
+ BlockCategories.BANNERS.getAll().forEach(type -> priorityMap.put(type, PlacementPriority.FINAL));
+ priorityMap.put(BlockTypes.SIGN, PlacementPriority.FINAL);
+ priorityMap.put(BlockTypes.WALL_SIGN, PlacementPriority.FINAL);
+ priorityMap.put(BlockTypes.CACTUS, PlacementPriority.FINAL);
+ priorityMap.put(BlockTypes.SUGAR_CANE, PlacementPriority.FINAL);
+ priorityMap.put(BlockTypes.PISTON_HEAD, PlacementPriority.FINAL);
+ priorityMap.put(BlockTypes.MOVING_PISTON, PlacementPriority.FINAL);
+ }
+
+ private Map stages = new HashMap<>();
private boolean enabled;
+ public enum PlacementPriority {
+ CLEAR_FINAL,
+ CLEAR_LAST,
+ CLEAR_LATE,
+ FIRST,
+ LATE,
+ LAST,
+ FINAL
+ }
+
/**
* Create a new instance when the re-ordering is enabled.
*
@@ -75,9 +168,8 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
public MultiStageReorder(Extent extent, boolean enabled) {
super(extent);
this.enabled = enabled;
-
- for (int i = 0; i < STAGE_COUNT; ++i) {
- stages.add(new LocatedBlockList());
+ for (PlacementPriority priority : PlacementPriority.values()) {
+ stages.put(priority, new LocatedBlockList());
}
}
@@ -100,7 +192,7 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
}
public boolean commitRequired() {
- return stages.stream().anyMatch(stage -> stage.size() > 0);
+ return enabled;
}
/**
@@ -109,18 +201,8 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
* @param block The block
* @return The priority
*/
- public > int getPlacementPriority(B block) {
- if (Blocks.shouldPlaceLate(block.getBlockType())) {
- return 1;
- } else if (Blocks.shouldPlaceLast(block.getBlockType())) {
- // Place torches, etc. last
- return 2;
- } else if (Blocks.shouldPlaceFinal(block.getBlockType())) {
- // Place signs, reed, etc even later
- return 3;
- } else {
- return 0;
- }
+ private > PlacementPriority getPlacementPriority(B block) {
+ return priorityMap.getOrDefault(block.getBlockType(), PlacementPriority.FIRST);
}
@Override
@@ -130,13 +212,28 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
}
BlockState existing = getBlock(location);
- int priority = getPlacementPriority(block);
- int srcPriority = getPlacementPriority(existing);
+ PlacementPriority priority = getPlacementPriority(block);
+ PlacementPriority srcPriority = getPlacementPriority(existing);
- if (srcPriority == 1 || srcPriority == 2) {
- // Destroy torches, etc. first
- super.setBlock(location, BlockTypes.AIR.getDefaultState());
- return super.setBlock(location, block);
+ if (srcPriority != PlacementPriority.FIRST) {
+ BaseBlock replacement = (block.getBlockType().getMaterial().isAir() ? block : BlockTypes.AIR.getDefaultState()).toBaseBlock();
+
+ switch (srcPriority) {
+ case FINAL:
+ stages.get(PlacementPriority.CLEAR_FINAL).add(location, replacement);
+ break;
+ case LATE:
+ stages.get(PlacementPriority.CLEAR_LATE).add(location, replacement);
+ break;
+ case LAST:
+ stages.get(PlacementPriority.CLEAR_LAST).add(location, replacement);
+ break;
+ }
+ }
+
+ if (block.getBlockType().getMaterial().isAir()) {
+ return !existing.equalsFuzzy(block);
+ }
}
stages.get(priority).add(location, block);
@@ -145,104 +242,14 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
@Override
public Operation commitBefore() {
+ if (!commitRequired()) {
+ return null;
+ }
List operations = new ArrayList<>();
- for (int i = 0; i < stages.size() - 1; ++i) {
- operations.add(new SetLocatedBlocks(getExtent(), stages.get(i)));
+ for (PlacementPriority priority : PlacementPriority.values()) {
+ operations.add(new SetLocatedBlocks(getExtent(), stages.get(priority)));
}
- operations.add(new FinalStageCommitter());
return new OperationQueue(operations);
}
-
- private class FinalStageCommitter implements Operation {
- private Extent extent = getExtent();
-
- private final Set blocks = new HashSet<>();
- private final Map blockTypes = new HashMap<>();
-
- public FinalStageCommitter() {
- for (LocatedBlock entry : stages.get(stages.size() - 1)) {
- final BlockVector3 pt = entry.getLocation();
- blocks.add(pt);
- blockTypes.put(pt, entry.getBlock());
- }
- }
-
- @Override
- public Operation resume(RunContext run) throws WorldEditException {
- while (!blocks.isEmpty()) {
- BlockVector3 current = blocks.iterator().next();
- if (!blocks.contains(current)) {
- continue;
- }
-
- final Deque walked = new LinkedList<>();
-
- while (true) {
- walked.addFirst(current);
-
- assert (blockTypes.containsKey(current));
-
- final BlockStateHolder blockStateHolder = blockTypes.get(current);
-
- if (BlockCategories.DOORS.contains(blockStateHolder.getBlockType())) {
- Property halfProperty = blockStateHolder.getBlockType().getProperty("half");
- if (blockStateHolder.getState(halfProperty).equals("lower")) {
- // Deal with lower door halves being attached to the floor AND the upper half
- BlockVector3 upperBlock = current.add(0, 1, 0);
- if (blocks.contains(upperBlock) && !walked.contains(upperBlock)) {
- walked.addFirst(upperBlock);
- }
- }
- } else if (BlockCategories.RAILS.contains(blockStateHolder.getBlockType())) {
- BlockVector3 lowerBlock = current.add(0, -1, 0);
- if (blocks.contains(lowerBlock) && !walked.contains(lowerBlock)) {
- walked.addFirst(lowerBlock);
- }
- }
-
- if (!blockStateHolder.getBlockType().getMaterial().isFragileWhenPushed()) {
- // Block is not attached to anything => we can place it
- break;
- }
-
-// current = current.add(attachment.vector()).toBlockVector();
-//
-// if (!blocks.contains(current)) {
-// // We ran outside the remaining set => assume we can place blocks on this
-// break;
-// }
-//
- if (walked.contains(current)) {
- // Cycle detected => This will most likely go wrong, but there's nothing we can do about it.
- break;
- }
- }
-
- for (BlockVector3 pt : walked) {
- extent.setBlock(pt, blockTypes.get(pt));
- blocks.remove(pt);
- }
- }
-
- if (blocks.isEmpty()) {
- for (LocatedBlockList stage : stages) {
- stage.clear();
- }
- return null;
- }
-
- return this;
- }
-
- @Override
- public void cancel() {
- }
-
- @Override
- public void addStatusMessages(List messages) {
- }
-
- }
-
-}
\ No newline at end of file
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java
index 93a526377..0d7e4393c 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java
@@ -41,13 +41,12 @@ import com.sk89q.worldedit.registry.state.EnumProperty;
import com.sk89q.worldedit.registry.state.IntegerProperty;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Direction;
-import com.sk89q.worldedit.world.biome.BaseBiome;
+import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalInt;
@@ -62,7 +61,7 @@ import javax.annotation.Nullable;
*/
public class BlockTransformExtent extends ResettableExtent {
- private Transform transform;
+ private final Transform transform;
public BlockTransformExtent(Extent parent) {
@@ -121,7 +120,7 @@ public class BlockTransformExtent extends ResettableExtent {
@Override
public BlockState getBlock(BlockVector3 position) {
- return transformBlock(super.getBlock(position), false).toImmutableState();
+ return transformBlock(super.getBlock(position), false);
}
@Override
@@ -142,6 +141,7 @@ public class BlockTransformExtent extends ResettableExtent {
private static final Set directionNames = Sets.newHashSet("north", "south", "east", "west");
+ private static final Set directionNames = Sets.newHashSet("north", "south", "east", "west");
/**
* Transform the given block using the given transform.
@@ -155,6 +155,7 @@ public class BlockTransformExtent extends ResettableExtent {
public static > B transform(B block, Transform transform) {
checkNotNull(block);
checkNotNull(transform);
+
B result = block;
List extends Property>> properties = block.getBlockType().getProperties();
@@ -240,6 +241,7 @@ public class BlockTransformExtent extends ResettableExtent {
result = result.with(block.getBlockType().getProperty(directionName), directionalProperties.contains(directionName));
}
}
+
return result;
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/BlockChangeLimiter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/BlockChangeLimiter.java
index 637ccd821..7e89fa721 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/BlockChangeLimiter.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/BlockChangeLimiter.java
@@ -22,10 +22,10 @@ package com.sk89q.worldedit.extent.validation;
import static com.google.common.base.Preconditions.checkArgument;
import com.sk89q.worldedit.MaxChangedBlocksException;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
+import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockStateHolder;
/**
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/DataValidatorExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/DataValidatorExtent.java
index 9bc9aaf43..63ca586e6 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/DataValidatorExtent.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/DataValidatorExtent.java
@@ -21,10 +21,10 @@ package com.sk89q.worldedit.extent.validation;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
+import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/BlockQuirkExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/BlockQuirkExtent.java
index 9631f53ae..50f2a9a30 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/BlockQuirkExtent.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/BlockQuirkExtent.java
@@ -21,10 +21,10 @@ package com.sk89q.worldedit.extent.world;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
+import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/ChunkLoadingExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/ChunkLoadingExtent.java
index 31ff6f840..de5ae4378 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/ChunkLoadingExtent.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/ChunkLoadingExtent.java
@@ -21,10 +21,10 @@ package com.sk89q.worldedit.extent.world;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
+import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockStateHolder;
@@ -62,7 +62,6 @@ public class ChunkLoadingExtent extends AbstractDelegateExtent {
@Override
public > boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
- world.checkLoadedChunk(location);
if (enabled) {
world.checkLoadedChunk(location);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/FastModeExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/FastModeExtent.java
index a83a4c615..54d72df19 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/FastModeExtent.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/FastModeExtent.java
@@ -21,12 +21,12 @@ package com.sk89q.worldedit.extent.world;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector2;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.RunContext;
+import com.sk89q.worldedit.math.BlockVector2;
+import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;
@@ -104,7 +104,7 @@ public class FastModeExtent extends AbstractDelegateExtent {
dirtyChunks.add(BlockVector2.at(location.getBlockX() >> 4, location.getBlockZ() >> 4));
if (world.setBlock(location, block, false)) {
- if (postEditSimulation) {
+ if (!enabled && postEditSimulation) {
positions.add(location);
}
return true;
@@ -117,11 +117,14 @@ public class FastModeExtent extends AbstractDelegateExtent {
}
public boolean commitRequired() {
- return !dirtyChunks.isEmpty() || !positions.isEmpty();
+ return enabled || postEditSimulation;
}
@Override
protected Operation commitBefore() {
+ if (!commitRequired()) {
+ return null;
+ }
return new Operation() {
@Override
public Operation resume(RunContext run) throws WorldEditException {
@@ -129,7 +132,7 @@ public class FastModeExtent extends AbstractDelegateExtent {
world.fixAfterFastMode(dirtyChunks);
}
- if (postEditSimulation) {
+ if (!enabled && postEditSimulation) {
Iterator positionIterator = positions.iterator();
while (run.shouldContinue() && positionIterator.hasNext()) {
BlockVector3 position = positionIterator.next();
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/EditContext.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/EditContext.java
index 07c1515ba..b26f8d74f 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/EditContext.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/EditContext.java
@@ -21,6 +21,7 @@ package com.sk89q.worldedit.function;
import static com.google.common.base.Preconditions.checkNotNull;
+import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.regions.Region;
@@ -32,6 +33,7 @@ public class EditContext {
private Extent destination;
@Nullable private Region region;
@Nullable private Pattern fill;
+ @Nullable private LocalSession session;
public Extent getDestination() {
return destination;
@@ -60,4 +62,12 @@ public class EditContext {
this.fill = fill;
}
+ @Nullable
+ public LocalSession getSession() {
+ return session;
+ }
+
+ public void setSession(@Nullable LocalSession session) {
+ this.session = session;
+ }
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/FlatRegionMaskingFilter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/FlatRegionMaskingFilter.java
index acafd1f61..961a5721d 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/FlatRegionMaskingFilter.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/FlatRegionMaskingFilter.java
@@ -21,9 +21,9 @@ package com.sk89q.worldedit.function;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.mask.Mask2D;
+import com.sk89q.worldedit.math.BlockVector2;
/**
* Passes calls to {@link #apply(BlockVector2)} to the
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/GroundFunction.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/GroundFunction.java
index 630952678..d3162ff13 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/GroundFunction.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/GroundFunction.java
@@ -21,9 +21,9 @@ package com.sk89q.worldedit.function;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.mask.Mask;
+import com.sk89q.worldedit.math.BlockVector3;
/**
* Applies a {@link RegionFunction} to the first ground block.
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/RegionMaskingFilter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/RegionMaskingFilter.java
index 9feb385b5..cea580d8b 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/RegionMaskingFilter.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/RegionMaskingFilter.java
@@ -21,9 +21,9 @@ package com.sk89q.worldedit.function;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.mask.Mask;
+import com.sk89q.worldedit.math.BlockVector3;
/**
* Passes calls to {@link #apply(BlockVector3)} to the
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/biome/BiomeReplace.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/biome/BiomeReplace.java
index 500408700..efa53f45a 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/biome/BiomeReplace.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/biome/BiomeReplace.java
@@ -21,11 +21,11 @@ package com.sk89q.worldedit.function.biome;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.FlatRegionFunction;
-import com.sk89q.worldedit.world.biome.BaseBiome;
+import com.sk89q.worldedit.math.BlockVector2;
+import com.sk89q.worldedit.world.biome.BiomeType;
/**
* Replaces the biome at the locations that this function is applied to.
@@ -33,7 +33,7 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
public class BiomeReplace implements FlatRegionFunction {
private final Extent extent;
- private BaseBiome biome;
+ private BiomeType biome;
/**
* Create a new instance.
@@ -41,7 +41,7 @@ public class BiomeReplace implements FlatRegionFunction {
* @param extent an extent
* @param biome a biome
*/
- public BiomeReplace(Extent extent, BaseBiome biome) {
+ public BiomeReplace(Extent extent, BiomeType biome) {
checkNotNull(extent);
checkNotNull(biome);
this.extent = extent;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java
index b6581203e..eec8a1ed3 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java
@@ -26,9 +26,6 @@ import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
-import com.sk89q.worldedit.world.block.BaseBlock;
-
-import static com.google.common.base.Preconditions.checkNotNull;
/**
* Replaces blocks with a given pattern.
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java
index 34a4671c9..8fb81e669 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java
@@ -28,7 +28,6 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.jnbt.CompoundTagBuilder;
import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.internal.helper.MCDirections;
@@ -37,13 +36,9 @@ import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Direction.Flag;
-import com.sk89q.worldedit.world.block.BlockStateHolder;
-
-import java.util.Map;
-
import static com.google.common.base.Preconditions.checkNotNull;
-//import com.sk89q.worldedit.world.block.BaseBlock;
+import com.sk89q.worldedit.world.block.BaseBlock;
/**
* Copies blocks from one extent to another.
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java
index 14d3124b4..30f55258a 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java
@@ -29,11 +29,11 @@ import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.function.LayerFunction;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.function.mask.Mask;
-
-import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockTypes;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* Makes a layer of grass on top, three layers of dirt below, and smooth stone
* only below that for all layers that originally consist of grass, dirt,
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/entity/ExtentEntityCopy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/entity/ExtentEntityCopy.java
index fca42f721..643f4593e 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/entity/ExtentEntityCopy.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/entity/ExtentEntityCopy.java
@@ -26,6 +26,7 @@ import com.sk89q.jnbt.FloatTag;
import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.Tag;
+import com.sk89q.jnbt.CompoundTagBuilder;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
@@ -101,19 +102,6 @@ public class ExtentEntityCopy implements EntityFunction {
Location newLocation;
Location location = entity.getLocation();
-//<<<<<<< HEAD
-// Vector pivot = from.round().add(0.5, 0.5, 0.5);
-// Vector newPosition = transform.apply(location.subtract(pivot));
-// Vector newDirection;
-// if (transform.isIdentity()) {
-// newDirection = entity.getLocation().getDirection();
-// newLocation = new Location(destination, newPosition.add(to.round().add(0.5, 0.5, 0.5)), newDirection);
-// } else {
-// newDirection = new Vector(transform.apply(location.getDirection())).subtract(transform.apply(Vector.ZERO)).normalize();
-// newLocation = new Location(destination, newPosition.add(to.round().add(0.5, 0.5, 0.5)), newDirection);
-// state = transformNbtData(state);
-// }
-//=======
Vector3 pivot = from.round().add(0.5, 0.5, 0.5);
Vector3 newPosition = transform.apply(location.subtract(pivot));
Vector3 newDirection;
@@ -123,9 +111,7 @@ public class ExtentEntityCopy implements EntityFunction {
: transform.apply(location.getDirection()).subtract(transform.apply(Vector3.ZERO)).normalize();
newLocation = new Location(destination, newPosition.add(to.round().add(0.5, 0.5, 0.5)), newDirection);
- // Some entities store their position data in NBT
state = transformNbtData(state);
-//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
boolean success = destination.createEntity(newLocation, state) != null;
@@ -163,14 +149,9 @@ public class ExtentEntityCopy implements EntityFunction {
boolean hasFacing = tag.containsKey("Facing");
if (hasTilePosition) {
-//<<<<<<< HEAD
changed = true;
-// Vector tilePosition = new Vector(tag.asInt("TileX"), tag.asInt("TileY"), tag.asInt("TileZ"));
-// Vector newTilePosition = transform.apply(tilePosition.subtract(from)).add(to);
-//=======
Vector3 tilePosition = Vector3.at(tag.asInt("TileX"), tag.asInt("TileY"), tag.asInt("TileZ"));
BlockVector3 newTilePosition = transform.apply(tilePosition.subtract(from)).add(to).toBlockPoint();
-//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
values.put("TileX", new IntTag(newTilePosition.getBlockX()));
values.put("TileY", new IntTag(newTilePosition.getBlockY()));
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/Deform.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/Deform.java
index ac52933be..8793ae00d 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/Deform.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/Deform.java
@@ -23,6 +23,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.util.GuavaUtil.firstNonNull;
import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.LocalSession;
+import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.NullExtent;
@@ -147,7 +149,9 @@ public class Deform implements Contextual {
unit = Vector3.ONE;
}
- return new DeformOperation(context.getDestination(), region, zero, unit, expression);
+ LocalSession session = context.getSession();
+ return new DeformOperation(context.getDestination(), region, zero, unit, expression,
+ session == null ? WorldEdit.getInstance().getConfiguration().calculationTimeout : session.getTimeout());
}
private static final class DeformOperation implements Operation {
@@ -156,6 +160,7 @@ public class Deform implements Contextual {
private final Vector3 zero;
private final Vector3 unit;
private final String expression;
+ private final int timeout;
private DeformOperation(Extent destination, Region region, Vector3 zero, Vector3 unit, String expression) {
this.destination = destination;
@@ -163,6 +168,7 @@ public class Deform implements Contextual {
this.zero = zero;
this.unit = unit;
this.expression = expression;
+ this.timeout = timeout;
}
@Override
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/FloraGenerator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/FloraGenerator.java
index e1ab41b03..602c07f56 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/FloraGenerator.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/FloraGenerator.java
@@ -20,7 +20,6 @@
package com.sk89q.worldedit.function.generator;
import com.sk89q.worldedit.EditSession;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.pattern.BlockPattern;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/ForestGenerator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/ForestGenerator.java
index e0332d550..f6ddf7086 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/ForestGenerator.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/ForestGenerator.java
@@ -20,9 +20,9 @@
package com.sk89q.worldedit.function.generator;
import com.sk89q.worldedit.EditSession;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.RegionFunction;
+import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
@@ -58,11 +58,14 @@ public class ForestGenerator implements RegionFunction {
return true;
} else if (t == BlockTypes.TALL_GRASS || t == BlockTypes.DEAD_BUSH || t == BlockTypes.POPPY || t == BlockTypes.DANDELION) { // TODO: This list needs to be moved
editSession.setBlock(position, BlockTypes.AIR.getDefaultState());
- treeType.generate(editSession, position);
- return true;
- } else if (t == BlockTypes.SNOW) {
- editSession.setBlock(position, BlockTypes.AIR.getDefaultState());
- return false;
+ // and then trick the generator here by directly setting into the world
+ editSession.getWorld().setBlock(position, BlockTypes.AIR.getDefaultState());
+ // so that now the generator can generate the tree
+ boolean success = treeType.generate(editSession, position);
+ if (!success) {
+ editSession.setBlock(position, block); // restore on failure
+ }
+ return success;
} else { // Trees won't grow on this!
return false;
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/GardenPatchGenerator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/GardenPatchGenerator.java
index 0cc3266df..cec89ca16 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/GardenPatchGenerator.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/generator/GardenPatchGenerator.java
@@ -21,11 +21,11 @@ package com.sk89q.worldedit.function.generator;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.pattern.BlockPattern;
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;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask2D.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask2D.java
index c590a211a..633159acb 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask2D.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask2D.java
@@ -21,9 +21,9 @@ package com.sk89q.worldedit.function.mask;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.extent.Extent;
-import com.sk89q.worldedit.world.biome.BaseBiome;
+import com.sk89q.worldedit.math.BlockVector2;
+import com.sk89q.worldedit.world.biome.BiomeType;
import java.util.Arrays;
import java.util.Collection;
@@ -36,7 +36,7 @@ import java.util.Set;
public class BiomeMask2D extends AbstractMask2D {
private final Extent extent;
- private final Set biomes = new HashSet<>();
+ private final Set biomes = new HashSet<>();
/**
* Create a new biome mask.
@@ -44,7 +44,7 @@ public class BiomeMask2D extends AbstractMask2D {
* @param extent the extent
* @param biomes a list of biomes to match
*/
- public BiomeMask2D(Extent extent, Collection biomes) {
+ public BiomeMask2D(Extent extent, Collection biomes) {
checkNotNull(extent);
checkNotNull(biomes);
this.extent = extent;
@@ -57,7 +57,7 @@ public class BiomeMask2D extends AbstractMask2D {
* @param extent the extent
* @param biome an array of biomes to match
*/
- public BiomeMask2D(Extent extent, BaseBiome... biome) {
+ public BiomeMask2D(Extent extent, BiomeType... biome) {
this(extent, Arrays.asList(checkNotNull(biome)));
}
@@ -66,7 +66,7 @@ public class BiomeMask2D extends AbstractMask2D {
*
* @param biomes a list of biomes
*/
- public void add(Collection biomes) {
+ public void add(Collection biomes) {
checkNotNull(biomes);
this.biomes.addAll(biomes);
}
@@ -76,7 +76,7 @@ public class BiomeMask2D extends AbstractMask2D {
*
* @param biome an array of biomes
*/
- public void add(BaseBiome... biome) {
+ public void add(BiomeType... biome) {
add(Arrays.asList(checkNotNull(biome)));
}
@@ -85,13 +85,13 @@ public class BiomeMask2D extends AbstractMask2D {
*
* @return a list of biomes
*/
- public Collection getBiomes() {
+ public Collection getBiomes() {
return biomes;
}
@Override
public boolean test(BlockVector2 vector) {
- BaseBiome biome = extent.getBiome(vector);
+ BiomeType biome = extent.getBiome(vector);
return biomes.contains(biome);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java
index c3530fd47..4100ca98c 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java
@@ -129,12 +129,6 @@ public class BlockMask extends AbstractExtentMask {
return mask;
}
}
-// public boolean test(BlockVector3 vector) {
-// BlockStateHolder block = getExtent().getBlock(vector);
-// for (BlockStateHolder testBlock : blocks) {
-// if (testBlock.equalsFuzzy(block)) {
-// return true;
-
private Mask getOptimizedMask(BlockType type, long[] bitSet) {
boolean single = true;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockStateMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockStateMask.java
new file mode 100644
index 000000000..69e47039d
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockStateMask.java
@@ -0,0 +1,70 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.function.mask;
+
+import com.google.common.collect.Maps;
+import com.sk89q.worldedit.blocks.Blocks;
+import com.sk89q.worldedit.extent.Extent;
+import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.registry.state.Property;
+import com.sk89q.worldedit.world.block.BlockState;
+import com.sk89q.worldedit.world.block.BlockType;
+
+import javax.annotation.Nullable;
+import java.util.Map;
+
+public class BlockStateMask extends AbstractExtentMask {
+
+ private final Map states;
+ private final boolean strict;
+ private Map, Object>> cache = Maps.newHashMap();
+
+ /**
+ * Creates a mask that checks if a given block has the desired properties set to the desired value.
+ *
+ * @param extent the extent to get blocks from
+ * @param states the desired states (property -> value) that a block should have to match the mask
+ * @param strict true to only match blocks that have all properties and values, false to also match blocks that
+ * do not have the properties (but only fail blocks with the properties but wrong values)
+ */
+ public BlockStateMask(Extent extent, Map states, boolean strict) {
+ super(extent);
+ this.states = states;
+ this.strict = strict;
+ }
+
+ @Override
+ public boolean test(BlockVector3 vector) {
+ BlockState block = getExtent().getBlock(vector);
+ final Map, Object> checkProps = cache
+ .computeIfAbsent(block.getBlockType(), (b -> Blocks.resolveProperties(states, b)));
+ if (strict && checkProps.isEmpty()) {
+ return false;
+ }
+ return checkProps.entrySet().stream()
+ .allMatch(entry -> block.getState(entry.getKey()) == entry.getValue());
+ }
+
+ @Nullable
+ @Override
+ public Mask2D toMask2D() {
+ return null;
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java
index 4c2b44ce9..ac4d24452 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java
@@ -19,8 +19,8 @@
package com.sk89q.worldedit.function.mask;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.extent.Extent;
+import com.sk89q.worldedit.math.BlockVector3;
import javax.annotation.Nullable;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask.java
index 2c4017559..52e0f345d 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask.java
@@ -21,13 +21,15 @@ package com.sk89q.worldedit.function.mask;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
+import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
import javax.annotation.Nullable;
+import java.util.function.IntSupplier;
/**
* A mask that evaluates an expression.
@@ -38,6 +40,7 @@ import javax.annotation.Nullable;
public class ExpressionMask extends AbstractMask {
private final Expression expression;
+ private final IntSupplier timeout;
/**
* Create a new instance.
@@ -46,8 +49,7 @@ public class ExpressionMask extends AbstractMask {
* @throws ExpressionException thrown if there is an error with the expression
*/
public ExpressionMask(String expression) throws ExpressionException {
- checkNotNull(expression);
- this.expression = Expression.compile(expression, "x", "y", "z");
+ this(Expression.compile(checkNotNull(expression), "x", "y", "z"));
}
/**
@@ -56,8 +58,13 @@ public class ExpressionMask extends AbstractMask {
* @param expression the expression
*/
public ExpressionMask(Expression expression) {
+ this(expression, null);
+ }
+
+ public ExpressionMask(Expression expression, @Nullable IntSupplier timeout) {
checkNotNull(expression);
this.expression = expression;
+ this.timeout = timeout;
}
@Override
@@ -75,7 +82,7 @@ public class ExpressionMask extends AbstractMask {
@Nullable
@Override
public Mask2D toMask2D() {
- return new ExpressionMask2D(expression);
+ return new ExpressionMask2D(expression, timeout);
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask2D.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask2D.java
index 0afefab0c..0f4d9b198 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask2D.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask2D.java
@@ -21,14 +21,19 @@ package com.sk89q.worldedit.function.mask;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector2;
+import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
+import com.sk89q.worldedit.math.BlockVector2;
+
+import javax.annotation.Nullable;
+import java.util.function.IntSupplier;
public class ExpressionMask2D extends AbstractMask2D {
private final Expression expression;
+ private final IntSupplier timeout;
/**
* Create a new instance.
@@ -37,8 +42,7 @@ public class ExpressionMask2D extends AbstractMask2D {
* @throws ExpressionException thrown if there is an error with the expression
*/
public ExpressionMask2D(String expression) throws ExpressionException {
- checkNotNull(expression);
- this.expression = Expression.compile(expression, "x", "z");
+ this(Expression.compile(checkNotNull(expression), "x", "z"));
}
/**
@@ -47,14 +51,23 @@ public class ExpressionMask2D extends AbstractMask2D {
* @param expression the expression
*/
public ExpressionMask2D(Expression expression) {
+ this(expression, null);
+ }
+
+ public ExpressionMask2D(Expression expression, @Nullable IntSupplier timeout) {
checkNotNull(expression);
this.expression = expression;
+ this.timeout = timeout;
}
@Override
public boolean test(BlockVector2 vector) {
try {
- return expression.evaluate(vector.getX(), 0, vector.getZ()) > 0;
+ if (timeout != null) {
+ return expression.evaluate(vector.getX(), 0, vector.getZ()) > 0;
+ } else {
+ return expression.evaluate(new double[]{vector.getX(), 0, vector.getZ()}, timeout.getAsInt()) > 0;
+ }
} catch (EvaluationException e) {
return false;
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java
index 9321ec5cd..f89d67c8e 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java
@@ -21,8 +21,6 @@ package com.sk89q.worldedit.function.mask;
import com.google.common.base.Function;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.sk89q.worldedit.math.BlockVector3;
import javax.annotation.Nullable;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Masks.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Masks.java
index 4279d2fde..1a70e02b2 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Masks.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Masks.java
@@ -55,33 +55,6 @@ public final class Masks {
//<<<<<<< HEAD
public static Mask negate(final Mask finalMask) {
return finalMask.inverse();
-//=======
-// public static Mask negate(final Mask mask) {
-// if (mask instanceof AlwaysTrue) {
-// return ALWAYS_FALSE;
-// } else if (mask instanceof AlwaysFalse) {
-// return ALWAYS_TRUE;
-// }
-//
-// checkNotNull(mask);
-// return new AbstractMask() {
-// @Override
-// public boolean test(BlockVector3 vector) {
-// return !mask.test(vector);
-// }
-//
-// @Nullable
-// @Override
-// public Mask2D toMask2D() {
-// Mask2D mask2d = mask.toMask2D();
-// if (mask2d != null) {
-// return negate(mask2d);
-// } else {
-// return null;
-// }
-// }
-// };
-//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
}
/**
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java
index 8ba70fc5d..19afced40 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java
@@ -1,6 +1,5 @@
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;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/BlockMapEntryPlacer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/BlockMapEntryPlacer.java
deleted file mode 100644
index 44e33a3af..000000000
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/BlockMapEntryPlacer.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.function.operation;
-
-import com.sk89q.worldedit.WorldEditException;
-
-import com.sk89q.worldedit.world.block.BlockState;
-import com.sk89q.worldedit.world.block.BaseBlock;
-import com.sk89q.worldedit.extent.Extent;
-import com.sk89q.worldedit.world.block.BlockStateHolder;
-import com.sk89q.worldedit.world.block.BlockState;
-import com.sk89q.worldedit.extent.Extent;
-import com.sk89q.worldedit.math.BlockVector3;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Sets block from an iterator of {@link Map.Entry} containing a
- * {@link BlockVector} as the key and a {@link BaseBlock} as the value.
- */
-public class BlockMapEntryPlacer implements Operation {
-
- private final Extent extent;
- private final Iterator> iterator;
-
- /**
- * Create a new instance.
- *
- * @param extent the extent to set the blocks on
- * @param iterator the iterator
- */
- public BlockMapEntryPlacer(Extent extent, Iterator> iterator) {
- checkNotNull(extent);
- checkNotNull(iterator);
- this.extent = extent;
- this.iterator = iterator;
- }
-
- @Override
- public Operation resume(RunContext run) throws WorldEditException {
- while (iterator.hasNext()) {
- Map.Entry entry = iterator.next();
- extent.setBlock(entry.getKey(), entry.getValue());
- }
-
- return null;
- }
-
- @Override
- public void cancel() {
- }
-
- @Override
- public void addStatusMessages(List messages) {
- }
-
-}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/SetLocatedBlocks.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/SetLocatedBlocks.java
index cf644af7a..1e418bb04 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/SetLocatedBlocks.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/SetLocatedBlocks.java
@@ -53,4 +53,4 @@ public class SetLocatedBlocks implements Operation {
public void addStatusMessages(List messages) {
}
-}
\ No newline at end of file
+}
diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/gui/GuiHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/AbstractExtentPattern.java
similarity index 56%
rename from worldedit-forge/src/main/java/com/sk89q/worldedit/forge/gui/GuiHandler.java
rename to worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/AbstractExtentPattern.java
index d88b97379..de18b4802 100644
--- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/gui/GuiHandler.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/AbstractExtentPattern.java
@@ -17,29 +17,23 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.forge.gui;
+package com.sk89q.worldedit.function.pattern;
-import net.minecraft.entity.player.EntityPlayer;
-import net.minecraft.world.World;
-import net.minecraftforge.fml.common.network.IGuiHandler;
+import com.sk89q.worldedit.extent.Extent;
-public class GuiHandler implements IGuiHandler {
+import static com.google.common.base.Preconditions.checkNotNull;
- public static final int REFERENCE_ID = 0;
+public abstract class AbstractExtentPattern extends AbstractPattern implements ExtentPattern {
- @Override
- public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
- return null;
+ private final Extent extent;
+
+ public AbstractExtentPattern(Extent extent) {
+ this.extent = extent;
+ checkNotNull(extent);
}
@Override
- public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
- switch (id) {
- case REFERENCE_ID:
- return new GuiReferenceCard();
- }
-
- return null;
+ public Extent getExtent() {
+ return extent;
}
-
-}
\ No newline at end of file
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ClipboardPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ClipboardPattern.java
index cbfa5dbf6..e686f454d 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ClipboardPattern.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ClipboardPattern.java
@@ -1,25 +1,12 @@
package com.sk89q.worldedit.function.pattern;
-
-import com.sk89q.worldedit.world.block.BlockState;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.math.BlockVector3;
-import com.sk89q.worldedit.world.block.BaseBlock;
-
-
-import static com.google.common.base.Preconditions.checkNotNull;
/**
* A pattern that reads from {@link Clipboard}.
*/
-public class ClipboardPattern extends AbstractPattern {
-
- private final Clipboard clipboard;
- private final int sx, sy, sz;
- private final BlockVector3 min;
-// private final BlockVector3 size;
+public class ClipboardPattern extends RepeatingExtentPattern {
/**
* Create a new clipboard pattern.
@@ -27,25 +14,16 @@ public class ClipboardPattern extends AbstractPattern {
* @param clipboard the clipboard
*/
public ClipboardPattern(Clipboard clipboard) {
- checkNotNull(clipboard);
- this.clipboard = clipboard;
- BlockVector3 size = clipboard.getMaximumPoint().subtract(clipboard.getMinimumPoint()).add(1, 1, 1);
- this.sx = size.getBlockX();
- this.sy = size.getBlockY();
- this.sz = size.getBlockZ();
- this.min = clipboard.getMinimumPoint();
+ this(clipboard, BlockVector3.ZERO);
}
- @Override
- public BaseBlock apply(BlockVector3 position) {
- int xp = position.getBlockX() % sx;
- int yp = position.getBlockY() % sy;
- int zp = position.getBlockZ() % sz;
- if (xp < 0) xp += sx;
- if (yp < 0) yp += sy;
- if (zp < 0) zp += sz;
- return clipboard.getFullBlock(BlockVector3.at(min.getX() + xp, min.getY() + yp, min.getZ() + zp));
+ /**
+ * Create a new clipboard pattern.
+ *
+ * @param clipboard the clipboard
+ * @param offset the offset
+ */
+ public ClipboardPattern(Clipboard clipboard, BlockVector3 offset) {
+ super(clipboard, clipboard.getMinimumPoint(), offset);
}
-
-
-}
\ No newline at end of file
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ExtentBufferedCompositePattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ExtentBufferedCompositePattern.java
new file mode 100644
index 000000000..b95351e3f
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ExtentBufferedCompositePattern.java
@@ -0,0 +1,66 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.function.pattern;
+
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.extent.Extent;
+import com.sk89q.worldedit.extent.buffer.ExtentBuffer;
+import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.world.block.BaseBlock;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * A pattern that composes multiple patterns consecutively, ensuring that changes from one
+ * pattern are realized by the subsequent one(s). For best results, use an {@link ExtentBuffer}
+ * to avoid changing blocks in an underlying extent (e.g. the world).
+ */
+public class ExtentBufferedCompositePattern extends AbstractExtentPattern {
+
+ private final Pattern[] patterns;
+
+ /**
+ * Construct a new instance of this pattern.
+ *
+ * Note that all patterns passed which are ExtentPatterns should use the same extent as the one
+ * passed to this constructor, or block changes may not be realized by those patterns.
+ *
+ * @param extent the extent to buffer changes to
+ * @param patterns the patterns to apply, in order
+ */
+ public ExtentBufferedCompositePattern(Extent extent, Pattern... patterns) {
+ super(extent);
+ checkArgument(patterns.length != 0, "patterns cannot be empty");
+ this.patterns = patterns;
+ }
+
+ @Override
+ public BaseBlock apply(BlockVector3 position) {
+ BaseBlock lastBlock = null;
+ for (Pattern pattern : patterns) {
+ lastBlock = pattern.apply(position);
+ try {
+ getExtent().setBlock(position, lastBlock);
+ } catch (WorldEditException ignored) { // buffer doesn't throw
+ }
+ }
+ return lastBlock;
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ExtentPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ExtentPattern.java
new file mode 100644
index 000000000..c0dec41ee
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ExtentPattern.java
@@ -0,0 +1,32 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.function.pattern;
+
+import com.sk89q.worldedit.extent.Extent;
+
+public interface ExtentPattern extends Pattern {
+
+ /**
+ * Get the extent associated with this pattern.
+ *
+ * @return the extent for this pattern
+ */
+ public Extent getExtent();
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java
index a2419df27..a91354fe2 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java
@@ -19,14 +19,6 @@
package com.sk89q.worldedit.function.pattern;
-import com.sk89q.minecraft.util.commands.Link;
-import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.world.block.BaseBlock;
-import com.sk89q.worldedit.world.block.BlockState;
-import com.sk89q.worldedit.command.UtilityCommands;
-import com.sk89q.worldedit.extent.Extent;
-import com.sk89q.worldedit.extent.NullExtent;
-import com.sk89q.worldedit.internal.expression.runtime.Return;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java
index 2acf60bf0..18b7b8033 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java
@@ -12,12 +12,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-
-
import static com.google.common.base.Preconditions.checkNotNull;
/**
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomStatePattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomStatePattern.java
new file mode 100644
index 000000000..f2e2870a9
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomStatePattern.java
@@ -0,0 +1,45 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.function.pattern;
+
+import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.world.block.BaseBlock;
+import com.sk89q.worldedit.world.block.BlockState;
+import com.sk89q.worldedit.world.block.FuzzyBlockState;
+
+import java.util.List;
+import java.util.Random;
+import java.util.stream.Collectors;
+
+public class RandomStatePattern implements Pattern {
+
+ private final Random rand = new Random();
+ private final List blocks;
+
+ public RandomStatePattern(FuzzyBlockState state) {
+ blocks = state.getBlockType().getAllStates().stream().filter(state::equalsFuzzy)
+ .map(BlockState::toBaseBlock).collect(Collectors.toList());
+ }
+
+ @Override
+ public BaseBlock apply(BlockVector3 position) {
+ return blocks.get(rand.nextInt(blocks.size()));
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RepeatingExtentPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RepeatingExtentPattern.java
index d7b799840..28d6362aa 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RepeatingExtentPattern.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RepeatingExtentPattern.java
@@ -28,9 +28,10 @@ import com.sk89q.worldedit.world.block.BaseBlock;
/**
* Returns the blocks from {@link Extent}, repeating when out of bounds.
*/
-public class RepeatingExtentPattern extends AbstractPattern {
+public class RepeatingExtentPattern extends AbstractExtentPattern {
- private Extent extent;
+ private final BlockVector3 size;
+ private BlockVector3 origin;
private BlockVector3 offset;
/**
@@ -39,28 +40,11 @@ public class RepeatingExtentPattern extends AbstractPattern {
* @param extent the extent
* @param offset the offset
*/
- public RepeatingExtentPattern(Extent extent, BlockVector3 offset) {
- setExtent(extent);
+ public RepeatingExtentPattern(Extent extent, BlockVector3 origin, BlockVector3 offset) {
+ super(extent);
+ setOrigin(origin);
setOffset(offset);
- }
-
- /**
- * Get the extent.
- *
- * @return the extent
- */
- public Extent getExtent() {
- return extent;
- }
-
- /**
- * Set the extent.
- *
- * @param extent the extent
- */
- public void setExtent(Extent extent) {
- checkNotNull(extent);
- this.extent = extent;
+ size = extent.getMaximumPoint().subtract(extent.getMinimumPoint()).add(1, 1, 1);
}
/**
@@ -82,13 +66,31 @@ public class RepeatingExtentPattern extends AbstractPattern {
this.offset = offset;
}
+ /**
+ * Get the origin.
+ *
+ * @return the origin
+ */
+ public BlockVector3 getOrigin() {
+ return origin;
+ }
+
+ /**
+ * Set the origin.
+ *
+ * @param origin the origin
+ */
+ public void setOrigin(BlockVector3 origin) {
+ checkNotNull(origin);
+ this.origin = origin;
+ }
+
@Override
public BaseBlock apply(BlockVector3 position) {
BlockVector3 base = position.add(offset);
- BlockVector3 size = extent.getMaximumPoint().subtract(extent.getMinimumPoint()).add(1, 1, 1);
- int x = base.getBlockX() % size.getBlockX();
- int y = base.getBlockY() % size.getBlockY();
- int z = base.getBlockZ() % size.getBlockZ();
- return extent.getFullBlock(BlockVector3.at(x, y, z));
+ int x = Math.abs(base.getBlockX()) % size.getBlockX();
+ int y = Math.abs(base.getBlockY()) % size.getBlockY();
+ int z = Math.abs(base.getBlockZ()) % size.getBlockZ();
+ return getExtent().getFullBlock(BlockVector3.at(x, y, z).add(origin));
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/StateApplyingPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/StateApplyingPattern.java
new file mode 100644
index 000000000..1ed40bffb
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/StateApplyingPattern.java
@@ -0,0 +1,54 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.function.pattern;
+
+import com.google.common.collect.Maps;
+import com.sk89q.worldedit.extent.Extent;
+import com.sk89q.worldedit.math.BlockVector3;
+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.BlockType;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import static com.sk89q.worldedit.blocks.Blocks.resolveProperties;
+
+public class StateApplyingPattern extends AbstractExtentPattern {
+
+ private final Map states;
+ private Map, Object>> cache = Maps.newHashMap();
+
+ public StateApplyingPattern(Extent extent, Map statesToSet) {
+ super(extent);
+ this.states = statesToSet;
+ }
+
+ @Override
+ public BaseBlock apply(BlockVector3 position) {
+ BlockState block = getExtent().getBlock(position);
+ for (Entry, Object> entry : cache
+ .computeIfAbsent(block.getBlockType(), (b -> resolveProperties(states, b))).entrySet()) {
+ block = block.with(entry.getKey(), entry.getValue());
+ }
+ return block.toBaseBlock();
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/TypeApplyingPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/TypeApplyingPattern.java
new file mode 100644
index 000000000..dc9951805
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/TypeApplyingPattern.java
@@ -0,0 +1,52 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.function.pattern;
+
+import com.sk89q.worldedit.extent.Extent;
+import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.registry.state.Property;
+import com.sk89q.worldedit.world.block.BaseBlock;
+import com.sk89q.worldedit.world.block.BlockState;
+
+import java.util.Map.Entry;
+
+/**
+ * Applies a block type while retaining all possible states.
+ */
+public class TypeApplyingPattern extends AbstractExtentPattern {
+ private final BlockState blockState;
+
+ public TypeApplyingPattern(Extent extent, BlockState blockState) {
+ super(extent);
+ this.blockState = blockState;
+ }
+
+ @Override
+ public BaseBlock apply(BlockVector3 position) {
+ BlockState oldBlock = getExtent().getBlock(position);
+ BlockState newBlock = blockState;
+ for (Entry, Object> entry : oldBlock.getStates().entrySet()) {
+ @SuppressWarnings("unchecked")
+ Property prop = (Property) entry.getKey();
+ newBlock = newBlock.with(prop, entry.getValue());
+ }
+ return newBlock.toBaseBlock();
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/WaterloggedRemover.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/WaterloggedRemover.java
new file mode 100644
index 000000000..51f8c0f67
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/WaterloggedRemover.java
@@ -0,0 +1,47 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.function.pattern;
+
+import com.sk89q.worldedit.extent.Extent;
+import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.registry.state.Property;
+import com.sk89q.worldedit.world.block.BaseBlock;
+import com.sk89q.worldedit.world.block.BlockTypes;
+
+/**
+ * Removes the waterlogged state from blocks if possible. If not possible, returns air.
+ */
+public class WaterloggedRemover extends AbstractExtentPattern {
+
+ public WaterloggedRemover(Extent extent) {
+ super(extent);
+ }
+
+ @Override
+ public BaseBlock apply(BlockVector3 position) {
+ BaseBlock block = getExtent().getFullBlock(position);
+ @SuppressWarnings("unchecked")
+ Property prop = (Property) block.getBlockType().getPropertyMap().getOrDefault("waterlogged", null);
+ if (prop != null) {
+ return block.with(prop, false);
+ }
+ return BlockTypes.AIR.getDefaultState().toBaseBlock();
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/util/FlatRegionOffset.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/util/FlatRegionOffset.java
index b53b75619..9682ff378 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/util/FlatRegionOffset.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/util/FlatRegionOffset.java
@@ -21,9 +21,9 @@ package com.sk89q.worldedit.function.util;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.FlatRegionFunction;
+import com.sk89q.worldedit.math.BlockVector2;
/**
* Offsets the position parameter by adding a given offset vector.
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/util/RegionOffset.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/util/RegionOffset.java
index a9e123fcf..7ac57da1f 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/util/RegionOffset.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/util/RegionOffset.java
@@ -21,9 +21,9 @@ package com.sk89q.worldedit.function.util;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.RegionFunction;
+import com.sk89q.worldedit.math.BlockVector3;
/**
* Offsets the position parameter by adding a given offset vector.
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java
index b31ea0d85..859110b77 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java
@@ -264,17 +264,6 @@ public abstract class BreadthFirstSearch implements Operation {
}
}
}
-//=======
-// BlockVector3 position;
-//
-// while ((position = queue.poll()) != null) {
-// if (function.apply(position)) {
-// affected++;
-// }
-//
-// for (BlockVector3 dir : directions) {
-// visit(position, position.add(dir));
-//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
}
if (currentDepth == maxDepth) {
break;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/FlatRegionVisitor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/FlatRegionVisitor.java
index 5d86ad0c9..cc1b15c8c 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/FlatRegionVisitor.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/FlatRegionVisitor.java
@@ -32,7 +32,6 @@ import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.operation.RunContext;
import com.sk89q.worldedit.math.BlockVector2;
-import com.sk89q.worldedit.math.Vector2;
import com.sk89q.worldedit.regions.FlatRegion;
import java.util.List;
@@ -81,7 +80,6 @@ public class FlatRegionVisitor implements Operation {
}
@Override
-//<<<<<<< HEAD
public Operation resume(final RunContext run) throws WorldEditException {
if (this.queue != null) {
for (final BlockVector2 pt : new Fast2DIterator(this.iterator, queue)) {
@@ -90,12 +88,6 @@ public class FlatRegionVisitor implements Operation {
} else {
for (final BlockVector2 pt : this.iterator) {
if (this.function.apply(pt)) affected++;
-//=======
-// public Operation resume(RunContext run) throws WorldEditException {
-// for (BlockVector2 pt : flatRegion.asFlatRegion()) {
-// if (function.apply(pt)) {
-// affected++;
-//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
}
}
return null;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
index 7293d2b26..586d27d0f 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
@@ -103,7 +103,7 @@ public class LayerVisitor implements Operation {
// Abort if we are underground
if (function.isGround(column.toBlockVector3(maxY + 1))) {
- return null;
+ continue;
}
boolean found = false;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java
index be44fb32b..72c294441 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java
@@ -26,9 +26,6 @@ import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector3;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
/**
* An implementation of an {@link BreadthFirstSearch} that uses a mask to
* determine where a block should be visited.
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BiomeChange.java b/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BiomeChange.java
index 133f38f7f..f8c0ef597 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BiomeChange.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BiomeChange.java
@@ -25,7 +25,7 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.history.UndoContext;
import com.sk89q.worldedit.math.BlockVector2;
-import com.sk89q.worldedit.world.biome.BaseBiome;
+import com.sk89q.worldedit.world.biome.BiomeType;
/**
* Represents a biome change that may be undone or replayed.
@@ -37,8 +37,8 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
public class BiomeChange implements Change {
private final BlockVector2 position;
- private final BaseBiome previous;
- private final BaseBiome current;
+ private final BiomeType previous;
+ private final BiomeType current;
/**
* Create a new biome change.
@@ -47,7 +47,7 @@ public class BiomeChange implements Change {
* @param previous the previous biome
* @param current the current biome
*/
- public BiomeChange(BlockVector2 position, BaseBiome previous, BaseBiome current) {
+ public BiomeChange(BlockVector2 position, BiomeType previous, BiomeType current) {
checkNotNull(position);
checkNotNull(previous);
checkNotNull(current);
@@ -70,7 +70,7 @@ public class BiomeChange implements Change {
*
* @return the previous biome
*/
- public BaseBiome getPrevious() {
+ public BiomeType getPrevious() {
return previous;
}
@@ -79,7 +79,7 @@ public class BiomeChange implements Change {
*
* @return the current biome
*/
- public BaseBiome getCurrent() {
+ public BiomeType getCurrent() {
return current;
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BlockChange.java b/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BlockChange.java
index d4613b277..ce7c26926 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BlockChange.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BlockChange.java
@@ -21,10 +21,10 @@ package com.sk89q.worldedit.history.change;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.history.UndoContext;
+import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/CommandLoggingHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/CommandLoggingHandler.java
index 256f891ec..ed65dc8fb 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/CommandLoggingHandler.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/CommandLoggingHandler.java
@@ -19,17 +19,15 @@
package com.sk89q.worldedit.internal.command;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.Logging;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
-import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
+import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.util.command.parametric.AbstractInvokeListener;
import com.sk89q.worldedit.util.command.parametric.InvokeHandler;
import com.sk89q.worldedit.util.command.parametric.ParameterData;
@@ -40,6 +38,8 @@ import java.lang.reflect.Method;
import java.util.logging.Handler;
import java.util.logging.Logger;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* Logs called commands to a logger.
*/
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java
index ead5cd02b..937a9d79a 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java
@@ -27,9 +27,6 @@ import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.UnknownDirectionException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
-
-import com.sk89q.worldedit.world.block.BlockState;
-import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.NoMatchException;
@@ -51,15 +48,15 @@ import com.sk89q.worldedit.util.command.parametric.BindingHelper;
import com.sk89q.worldedit.util.command.parametric.BindingMatch;
import com.sk89q.worldedit.util.command.parametric.ParameterException;
import com.sk89q.worldedit.world.World;
-import com.sk89q.worldedit.world.biome.BaseBiome;
+import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.Biomes;
+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.registry.BiomeRegistry;
-import java.util.Arrays;
-import java.util.List;
+import java.util.Collection;
/**
* Binds standard WorldEdit classes such as {@link Player} and {@link LocalSession}.
@@ -107,7 +104,7 @@ public class WorldEditBinding {
Player sender = getPlayer(context);
LocalSession session = worldEdit.getSessionManager().get(sender);
EditSession editSession = session.createEditSession(sender);
- editSession.enableQueue();
+ editSession.enableStandardMode();
context.getContext().getLocals().put(EditSession.class, editSession);
session.tellVersion(sender);
return editSession;
@@ -338,7 +335,8 @@ public BaseBlock getBaseBlock(ArgumentStack context) throws ParameterException,
return type;
} else {
throw new ParameterException(
- String.format("Can't recognize tree type '%s' -- choose from: %s", input, Arrays.toString(TreeType.values())));
+ String.format("Can't recognize tree type '%s' -- choose from: %s", input,
+ TreeType.getPrimaryAliases()));
}
} else {
return TreeType.TREE;
@@ -346,24 +344,26 @@ public BaseBlock getBaseBlock(ArgumentStack context) throws ParameterException,
}
/**
- * Gets an {@link BaseBiome} from a {@link ArgumentStack}.
+ * Gets an {@link BiomeType} from a {@link ArgumentStack}.
*
* @param context the context
* @return a pattern
* @throws ParameterException on error
* @throws WorldEditException on error
*/
- @BindingMatch(type = BaseBiome.class,
- behavior = BindingBehavior.CONSUMES,
- consumedCount = 1)
- public BaseBiome getBiomeType(ArgumentStack context) throws ParameterException, WorldEditException {
+ @BindingMatch(type = BiomeType.class,
+ behavior = BindingBehavior.CONSUMES,
+ consumedCount = 1)
+ public BiomeType getBiomeType(ArgumentStack context) throws ParameterException, WorldEditException {
String input = context.next();
if (input != null) {
- if (MathMan.isInteger(input)) return new BaseBiome(Integer.parseInt(input));
+
+ if (MathMan.isInteger(input)) return new BiomeType(Integer.parseInt(input)); TODO FIXME
+
BiomeRegistry biomeRegistry = WorldEdit.getInstance().getPlatformManager()
.queryCapability(Capability.GAME_HOOKS).getRegistries().getBiomeRegistry();
- List knownBiomes = biomeRegistry.getBiomes();
- BaseBiome biome = Biomes.findBiomeByName(knownBiomes, input, biomeRegistry);
+ Collection knownBiomes = BiomeType.REGISTRY.values();
+ BiomeType biome = Biomes.findBiomeByName(knownBiomes, input, biomeRegistry);
if (biome != null) {
return biome;
} else {
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Expression.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Expression.java
index 17460fc1f..3237eb686 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Expression.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Expression.java
@@ -19,12 +19,15 @@
package com.sk89q.worldedit.internal.expression;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.internal.expression.lexer.Lexer;
import com.sk89q.worldedit.internal.expression.lexer.tokens.Token;
import com.sk89q.worldedit.internal.expression.parser.Parser;
import com.sk89q.worldedit.internal.expression.runtime.Constant;
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
import com.sk89q.worldedit.internal.expression.runtime.ExpressionEnvironment;
+import com.sk89q.worldedit.internal.expression.runtime.ExpressionTimeoutException;
import com.sk89q.worldedit.internal.expression.runtime.Functions;
import com.sk89q.worldedit.internal.expression.runtime.RValue;
import com.sk89q.worldedit.internal.expression.runtime.ReturnException;
@@ -33,6 +36,12 @@ import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
/**
* Compiles and evaluates expressions.
@@ -68,6 +77,11 @@ import java.util.Map;
public class Expression {
private static final ThreadLocal> instance = ThreadLocal.withInitial(ArrayDeque::new);
+ private static final ExecutorService evalThread = Executors.newCachedThreadPool(
+ new ThreadFactoryBuilder()
+ .setDaemon(true)
+ .setNameFormat("worldedit-expression-eval-%d")
+ .build());
private final Map variables = new HashMap<>();
private final String[] variableNames;
@@ -119,10 +133,55 @@ public class Expression {
var.value = values[i];
}
pushInstance();
+ return evaluate(values, WorldEdit.getInstance().getConfiguration().calculationTimeout);
+ }
+
+ public double evaluate(double[] values, int timeout) throws EvaluationException {
+ for (int i = 0; i < values.length; ++i) {
+ final String variableName = variableNames[i];
+ final RValue invokable = variables.get(variableName);
+ if (!(invokable instanceof Variable)) {
+ throw new EvaluationException(invokable.getPosition(), "Tried to assign constant " + variableName + ".");
+ }
+
+ ((Variable) invokable).value = values[i];
+ }
try {
- return root.getValue();
+ if (timeout < 0) {
+ return evaluateRoot();
+ }
+ return evaluateRootTimed(timeout);
} catch (ReturnException e) {
return e.getValue();
+ } // other evaluation exceptions are thrown out of this method
+ }
+
+ private double evaluateRootTimed(int timeout) throws EvaluationException {
+ Future result = evalThread.submit(this::evaluateRoot);
+ try {
+ return result.get(timeout, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(e);
+ } catch (TimeoutException e) {
+ result.cancel(true);
+ throw new ExpressionTimeoutException("Calculations exceeded time limit.");
+ } catch (ExecutionException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof EvaluationException) {
+ throw (EvaluationException) cause;
+ }
+ if (cause instanceof RuntimeException) {
+ throw (RuntimeException) cause;
+ }
+ throw new RuntimeException(cause);
+ }
+ }
+
+ private Double evaluateRoot() throws EvaluationException {
+ pushInstance();
+ try {
+ return root.getValue();
} finally {
popInstance();
}
diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/CommonProxy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/ExpressionTimeoutException.java
similarity index 73%
rename from worldedit-forge/src/main/java/com/sk89q/worldedit/forge/CommonProxy.java
rename to worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/ExpressionTimeoutException.java
index 18a7de68f..ce7d55140 100644
--- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/CommonProxy.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/ExpressionTimeoutException.java
@@ -17,15 +17,13 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.forge;
+package com.sk89q.worldedit.internal.expression.runtime;
-import com.sk89q.worldedit.forge.gui.GuiHandler;
-import net.minecraftforge.fml.common.network.NetworkRegistry;
-
-public class CommonProxy {
-
- public void registerHandlers() {
- NetworkRegistry.INSTANCE.registerGuiHandler(ForgeWorldEdit.inst, new GuiHandler());
+/**
+ * Thrown when an evaluation exceeds the timeout time.
+ */
+public class ExpressionTimeoutException extends EvaluationException {
+ public ExpressionTimeoutException(String message) {
+ super(-1, message);
}
-
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/For.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/For.java
index 3250da3ed..e660daacd 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/For.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/For.java
@@ -29,10 +29,9 @@ public class For extends Node {
throw new EvaluationException(this.getPosition(), "Loop exceeded 256 iterations.");
}
- if(Thread.currentThread().isInterrupted()){
+ if(Thread.interrupted()){
throw new EvaluationException(this.getPosition(), "Thread has been interrupted.");
}
-
++iterations;
try {
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/SimpleFor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/SimpleFor.java
index 0faf0c3eb..1576c3484 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/SimpleFor.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/SimpleFor.java
@@ -53,8 +53,8 @@ public class SimpleFor extends Node {
if (iterations > 256) {
throw new EvaluationException(getPosition(), "Loop exceeded 256 iterations.");
}
- if(Thread.currentThread().isInterrupted()){
- throw new EvaluationException(this.getPosition(), "Thread has been interrupted.");
+ if (Thread.interrupted()) {
+ throw new EvaluationException(getPosition(), "Calculations exceeded time limit.");
}
++iterations;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/While.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/While.java
index 5eb3ed5f6..5da3dae01 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/While.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/While.java
@@ -49,8 +49,8 @@ public class While extends Node {
if (iterations > 256) {
throw new EvaluationException(getPosition(), "Loop exceeded 256 iterations.");
}
- if(Thread.currentThread().isInterrupted()){
- throw new EvaluationException(this.getPosition(), "Thread has been interrupted.");
+ if (Thread.interrupted()) {
+ throw new EvaluationException(getPosition(), "Calculations exceeded time limit.");
}
++iterations;
@@ -69,8 +69,8 @@ public class While extends Node {
if (iterations > 256) {
throw new EvaluationException(getPosition(), "Loop exceeded 256 iterations.");
}
- if(Thread.currentThread().isInterrupted()){
- throw new EvaluationException(this.getPosition(), "Thread has been interrupted.");
+ if (Thread.interrupted()) {
+ throw new EvaluationException(getPosition(), "Calculations exceeded time limit.");
}
++iterations;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/InputParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/InputParser.java
index ee40fa3b9..c96a1d183 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/InputParser.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/InputParser.java
@@ -24,6 +24,7 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
+import java.util.Collections;
import java.util.List;
/**
@@ -48,6 +49,6 @@ public abstract class InputParser {
* @return a list of suggestions
*/
public List getSuggestions() {
- return Lists.newArrayList();
+ return Collections.emptyList();
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java
index 1950ff9e2..001fe15ce 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java
@@ -485,7 +485,7 @@ public class Vector2 {
}
Vector2 other = (Vector2) obj;
- return other.getX() == this.getX() && other.getZ() == this.getZ();
+ return other.x == this.x && other.z == this.z;
}
@@ -496,7 +496,7 @@ public class Vector2 {
@Override
public String toString() {
- return "(" + getX() + ", " + getZ() + ")";
+ return "(" + x + ", " + z + ")";
}
}
\ No newline at end of file
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java
index 172a75687..275dff135 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java
@@ -622,13 +622,12 @@ public class Vector3 {
@Override
public boolean equals(Object obj) {
- if (obj == this) return true;
if (!(obj instanceof Vector3)) {
return false;
}
Vector3 other = (Vector3) obj;
- return other.getX() == this.getX() && other.getZ() == this.getZ() && other.getY() == this.getY();
+ return other.x == this.x && other.y == this.y && other.z == this.z;
}
@Override
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java
index 34f757b44..f3cb35c9b 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java
@@ -5,6 +5,7 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.math.BlockVector2;
+import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BlockState;
@@ -18,6 +19,8 @@ import java.util.Iterator;
import static com.google.common.base.Preconditions.checkNotNull;
+import javax.annotation.Nullable;
+
/**
* Allows applications of Kernels onto the region's height map.
*
@@ -44,11 +47,11 @@ public class HeightMap {
this(session, region, false);
}
- public HeightMap(EditSession session, Region region, boolean naturalOnly) {
- this(session, region, naturalOnly, false);
+ public HeightMap(EditSession session, Region region, Mask mask) {
+ this(session, region, mask, false);
}
- public HeightMap(EditSession session, Region region, boolean naturalOnly, boolean layers) {
+ public HeightMap(EditSession session, Region region, Mask mask, boolean layers) {
checkNotNull(session);
checkNotNull(region);
@@ -80,35 +83,27 @@ public class HeightMap {
BlockVector2 pos = iter.next();
int x = pos.getBlockX();
int z = pos.getBlockZ();
- layer = session.getNearestSurfaceLayer(x, z, (layer + 7) >> 3, 0, maxY);
+ layer = session.getNearestSurfaceLayer(x, z, (layer + 7) >> 3, 0, maxY, mask);
data[(z - bz) * width + (x - bx)] = layer;
}
} else {
// Store current heightmap data
int index = 0;
- if (naturalOnly) {
- for (int z = 0; z < height; ++z) {
- for (int x = 0; x < width; ++x, index++) {
- data[index] = session.getHighestTerrainBlock(x + minX, z + minZ, minY, maxY);
- }
- }
- } else {
- int yTmp = 255;
- for (int z = 0; z < height; ++z) {
- for (int x = 0; x < width; ++x, index++) {
- yTmp = session.getNearestSurfaceTerrainBlock(x + minX, z + minZ, yTmp, minY, maxY, Integer.MIN_VALUE, Integer.MAX_VALUE);
- switch (yTmp) {
- case Integer.MIN_VALUE:
- yTmp = minY;
- invalid[index] = true;
- break;
- case Integer.MAX_VALUE:
- yTmp = maxY;
- invalid[index] = true;
- break;
- }
- data[index] = yTmp;
+ int yTmp = 255;
+ for (int z = 0; z < height; ++z) {
+ for (int x = 0; x < width; ++x, index++) {
+ yTmp = session.getNearestSurfaceTerrainBlock(x + minX, z + minZ, yTmp, minY, maxY, Integer.MIN_VALUE, Integer.MAX_VALUE, mask);
+ switch (yTmp) {
+ case Integer.MIN_VALUE:
+ yTmp = minY;
+ invalid[index] = true;
+ break;
+ case Integer.MAX_VALUE:
+ yTmp = maxY;
+ invalid[index] = true;
+ break;
}
+ data[index] = yTmp;
}
}
}
@@ -180,7 +175,6 @@ public class HeightMap {
// Depending on growing or shrinking we need to start at the bottom or top
if (newHeight > curHeight) {
// Set the top block of the column to be the same type (this might go wrong with rounding)
-//<<<<<<< HEAD
BlockStateHolder existing = session.getBlock(xr, curBlock, zr);
// Skip water/lava
@@ -200,34 +194,13 @@ public class HeightMap {
} else {
existing = PropertyGroup.LEVEL.set(existing, 15);
session.setBlock(xr, newBlock, zr, existing);
-
-//=======
-// BlockState existing = session.getBlock(BlockVector3.at(xr, curHeight, zr));
-//
-// // Skip water/lava
-// if (existing.getBlockType() != BlockTypes.WATER && existing.getBlockType() != BlockTypes.LAVA) {
-// session.setBlock(BlockVector3.at(xr, newHeight, zr), existing);
-// ++blocksChanged;
-//
-// // Grow -- start from 1 below top replacing airblocks
-// for (int y = newHeight - 1 - originY; y >= 0; --y) {
-// int copyFrom = (int) (y * scale);
-// session.setBlock(BlockVector3.at(xr, originY + y, zr), session.getBlock(BlockVector3.at(xr, originY + copyFrom, zr)));
-//>>>>>>> 2c8b2fe0... Move vectors to static creators, for caching
++blocksChanged;
}
}
} else if (curHeight > newHeight) {
-//<<<<<<< HEAD
// Fill rest with air
for (int y = newBlock + 1; y <= ((curHeight + 15) >> 4); ++y) {
session.setBlock(xr, y, zr, fillerAir);
-//=======
-// // Shrink -- start from bottom
-// for (int y = 0; y < newHeight - originY; ++y) {
-// int copyFrom = (int) (y * scale);
-// session.setBlock(BlockVector3.at(xr, originY + y, zr), session.getBlock(BlockVector3.at(xr, originY + copyFrom, zr)));
-//>>>>>>> 2c8b2fe0... Move vectors to static creators, for caching
++blocksChanged;
}
// Set the top block of the column to be the same type
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/interpolation/ReparametrisingInterpolation.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/interpolation/ReparametrisingInterpolation.java
index 29a3ee5ee..23680f2bc 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/interpolation/ReparametrisingInterpolation.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/interpolation/ReparametrisingInterpolation.java
@@ -21,14 +21,15 @@
package com.sk89q.worldedit.math.interpolation;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.sk89q.worldedit.math.Vector3;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Map.Entry;
import java.util.TreeMap;
-import java.util.logging.Logger;
+
+import static com.google.common.base.Preconditions.checkNotNull;
/**
* Reparametrises another interpolation function by arc length.
@@ -38,7 +39,7 @@ import java.util.logging.Logger;
*/
public class ReparametrisingInterpolation implements Interpolation {
- private static final Logger log = Logger.getLogger(ReparametrisingInterpolation.class.getCanonicalName());
+ private static final Logger log = LoggerFactory.getLogger(ReparametrisingInterpolation.class);
private final Interpolation baseInterpolation;
private double totalArcLength;
@@ -102,7 +103,7 @@ public class ReparametrisingInterpolation implements Interpolation {
Entry ceilingEntry = cache.ceilingEntry(arc);
if (ceilingEntry == null) {
- log.warning("Error in arcToParameter: no ceiling entry for " + arc + " found!");
+ log.warn("Error in arcToParameter: no ceiling entry for " + arc + " found!");
return 0;
}
final double rightArc = ceilingEntry.getKey();
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/transform/AffineTransform.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/transform/AffineTransform.java
index 5223ca718..e31f3cd86 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/transform/AffineTransform.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/transform/AffineTransform.java
@@ -3,9 +3,9 @@ package com.sk89q.worldedit.math.transform;
import java.io.IOException;
import java.io.Serializable;
+import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MathUtils;
-import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.math.Vector3;
/**
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java
index 521f23c62..66b3028e5 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java
@@ -19,7 +19,6 @@
package com.sk89q.worldedit.regions;
-import com.sk89q.worldedit.*;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java
index 5ead3a841..77bd47f7e 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java
@@ -346,16 +346,10 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
};
}
-//<<<<<<< HEAD
@Override
public int size() {
return size;
}
-//=======
-// for (int x = min.getBlockX() >> ChunkStore.CHUNK_SHIFTS; x <= max.getBlockX() >> ChunkStore.CHUNK_SHIFTS; ++x) {
-// for (int z = min.getBlockZ() >> ChunkStore.CHUNK_SHIFTS; z <= max.getBlockZ() >> ChunkStore.CHUNK_SHIFTS; ++z) {
-// chunks.add(BlockVector2.at(x, z));
-//>>>>>>> 2c8b2fe0... Move vectors to static creators, for caching
@Override
@@ -394,27 +388,9 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
}
-// private int ly = Integer.MIN_VALUE;
-// private int lz = Integer.MIN_VALUE;
-// private boolean lr, lry, lrz;
-
@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;
-// if (z != lz) {
-// lz = z;
-// lrz = z >= this.minZ && z <= this.maxZ;
-// if (y != ly) {
-// ly = y;
-// lry = y >= this.minY && y <= this.maxY;
-// }
-// lr = lrz && lry;
-// } else if (y != ly) {
-// ly = y;
-// lry = y >= this.minY && y <= this.maxY;
-// lr = lrz && lry;
-// }
-// return lr && (x >= this.minX && x <= this.maxX);
}
@Override
@@ -467,7 +443,6 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
@Override
public BlockVector3 next() {
-//<<<<<<< HEAD
mutable.mutX(x);
mutable.mutY(y);
mutable.mutZ(z);
@@ -503,17 +478,6 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
} else {
x = cbx;
z = cbz;
-//=======
-// if (!hasNext()) throw new NoSuchElementException();
-// BlockVector3 answer = BlockVector3.at(nextX, nextY, nextZ);
-// if (++nextX > max.getBlockX()) {
-// nextX = min.getBlockX();
-// if (++nextY > max.getBlockY()) {
-// nextY = min.getBlockY();
-// if (++nextZ > max.getBlockZ()) {
-// nextX = Integer.MIN_VALUE;
-//>>>>>>> 2c8b2fe0... Move vectors to static creators, for caching
- }
} else {
x = cbx;
}
@@ -540,16 +504,10 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
}
@Override
-//<<<<<<< HEAD
public BlockVector3 next() {
mutable.mutX(nextX);
mutable.mutY(nextY);
mutable.mutZ(nextZ);
-//=======
-// public BlockVector2 next() {
-// if (!hasNext()) throw new NoSuchElementException();
-// BlockVector2 answer = BlockVector2.at(nextX, nextZ);
-//>>>>>>> 2c8b2fe0... Move vectors to static creators, for caching
if (++nextX > max.getBlockX()) {
nextX = min.getBlockX();
if (++nextZ > max.getBlockZ()) {
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java
index 9524874f2..90892ed12 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java
@@ -105,7 +105,7 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
hasY = region.hasY;
}
- @Override
+ @Override
public Vector3 getCenter() {
return center.toVector3((maxY + minY) / 2);
}
@@ -306,7 +306,6 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
double dz = Math.abs(pz - center.getBlockZ()) * radiusInverse.getZ();
return dx * dx + dz * dz <= 1;
-// return position.subtract(center).toVector2().divide(radius).lengthSq() <= 1;
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java
index f7c209a14..415f92244 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java
@@ -117,10 +117,10 @@ public class EllipsoidRegion extends AbstractRegion {
return diff.divide(2).floor();
}
- private BlockVector3 calculateChanges(BlockVector3... changes) {
- BlockVector3 total = BlockVector3.ZERO;
+ private Vector3 calculateChanges(BlockVector3... changes) {
+ Vector3 total = Vector3.ZERO;
for (BlockVector3 change : changes) {
- total = total.add(change.abs());
+ total = total.add(change.abs().toVector3());
}
return total.divide(2).floor();
@@ -135,8 +135,8 @@ public class EllipsoidRegion extends AbstractRegion {
@Override
public void contract(BlockVector3... changes) throws RegionOperationException {
center = center.subtract(calculateDiff(changes));
- Vector3 newRadius = radius.subtract(calculateChanges(changes).toVector3());
- setRadius(Vector3.at(1.5, 1.5, 1.5).getMaximum(newRadius));
+ Vector3 newRadius = radius.subtract(calculateChanges(changes));
+ radius = Vector3.at(1.5, 1.5, 1.5).getMaximum(newRadius);
}
@Override
@@ -214,31 +214,29 @@ public class EllipsoidRegion extends AbstractRegion {
}
@Override
-// public boolean contains(Vector position) {
-// int cx = position.getBlockX() - center.getBlockX();
-// int cx2 = cx * cx;
-// if (cx2 > radiusSqr.getBlockX()) {
-// return false;
-// }
-// int cz = position.getBlockZ() - 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;
-// }
-// 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;
- public boolean contains(BlockVector3 position) {
- return position.subtract(center).divide(radius.toBlockPoint()).lengthSq() <= 1;
+ public boolean contains(BlockVector3 position) {
+ int cx = position.getBlockX() - center.getBlockX();
+ int cx2 = cx * cx;
+ if (cx2 > radiusSqr.getBlockX()) {
+ return false;
+ }
+ int cz = position.getBlockZ() - 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;
+ }
+ 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;
}
/**
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/NullRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/NullRegion.java
index 570f0a80d..de2a3dea0 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/NullRegion.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/NullRegion.java
@@ -19,7 +19,6 @@
package com.sk89q.worldedit.regions;
-import com.sk89q.worldedit.*;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java
index 96d0bfa63..8c4c75a48 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java
@@ -108,7 +108,6 @@ public interface Region extends Iterable, Cloneable {
*/
void shift(BlockVector3 change) throws RegionOperationException;
-
default boolean contains(int x, int y, int z) {
return contains(BlockVector3.at(x, y, z));
}
@@ -128,6 +127,12 @@ public interface Region extends Iterable, Cloneable {
* @param position the position
* @return true if contained
*/
+ /**
+ * Returns true based on whether the region contains the point.
+ *
+ * @param position the position
+ * @return true if contained
+ */
boolean contains(BlockVector3 position);
/**
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegion3DIterator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegion3DIterator.java
index 0a61610b3..6a7a06780 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegion3DIterator.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegion3DIterator.java
@@ -21,8 +21,8 @@ package com.sk89q.worldedit.regions.iterator;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.BlockVector2;
+import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.FlatRegion;
import java.util.Iterator;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegionIterator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegionIterator.java
index 1c28566f4..8bd0a48dc 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegionIterator.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegionIterator.java
@@ -21,11 +21,12 @@ package com.sk89q.worldedit.regions.iterator;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.BlockVector2;
+import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import java.util.Iterator;
+import java.util.NoSuchElementException;
public class FlatRegionIterator implements Iterator {
@@ -72,7 +73,7 @@ public class FlatRegionIterator implements Iterator {
@Override
public BlockVector2 next() {
if (!hasNext()) {
- throw new java.util.NoSuchElementException();
+ throw new NoSuchElementException();
}
BlockVector2 answer = BlockVector2.at(nextX, nextZ);
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java
index afe54c996..aa6f48da3 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java
@@ -174,7 +174,6 @@ public class CylinderRegionSelector implements RegionSelector, CUIRegion {
@Override
public void explainPrimarySelection(Actor player, LocalSession session, BlockVector3 pos) {
BBC.SELECTOR_CENTER.send(player, pos, 0);
-
session.describeCUI(player);
}
@@ -182,7 +181,7 @@ public class CylinderRegionSelector implements RegionSelector, CUIRegion {
public void explainSecondarySelection(Actor player, LocalSession session, BlockVector3 pos) {
Vector3 center = region.getCenter();
- if (!center.equals(BlockVector3.ZERO)) {
+ if (!center.equals(Vector3.ZERO)) {
BBC.SELECTOR_RADIUS.send(player, NUMBER_FORMAT.format(region.getRadius().getX()) + "/" + NUMBER_FORMAT.format(region.getRadius().getZ()), region.getArea());
} else {
BBC.SELECTION_WAND.send(player);
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryBiomeShape.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryBiomeShape.java
index 0ebdc7393..de1324852 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryBiomeShape.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryBiomeShape.java
@@ -24,7 +24,8 @@ import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.FlatRegion;
import com.sk89q.worldedit.regions.Region;
-import com.sk89q.worldedit.world.biome.BaseBiome;
+import com.sk89q.worldedit.world.biome.BiomeType;
+import com.sk89q.worldedit.world.biome.BiomeTypes;
/**
* Generates solid and hollow shapes according to materials returned by the
@@ -54,10 +55,10 @@ public abstract class ArbitraryBiomeShape {
cacheOffsetX = min.getBlockX() - 1;
cacheOffsetZ = min.getBlockZ() - 1;
- cacheSizeX = (int) (max.getX() - cacheOffsetX + 2);
- cacheSizeZ = (int) (max.getZ() - cacheOffsetZ + 2);
+ cacheSizeX = max.getX() - cacheOffsetX + 2;
+ cacheSizeZ = max.getZ() - cacheOffsetZ + 2;
- cache = new BaseBiome[cacheSizeX * cacheSizeZ];
+ cache = new BiomeType[cacheSizeX * cacheSizeZ];
}
protected Iterable getExtent() {
@@ -71,7 +72,7 @@ public abstract class ArbitraryBiomeShape {
* OUTSIDE = outside
* else = inside
*/
- private final BaseBiome[] cache;
+ private final BiomeType[] cache;
/**
* Override this function to specify the shape to generate.
@@ -81,17 +82,17 @@ public abstract class ArbitraryBiomeShape {
* @param defaultBaseBiome The default biome for the current column.
* @return material to place or null to not place anything.
*/
- protected abstract BaseBiome getBiome(int x, int z, BaseBiome defaultBaseBiome);
+ protected abstract BiomeType getBiome(int x, int z, BiomeType defaultBaseBiome);
- private BaseBiome getBiomeCached(int x, int z, BaseBiome baseBiome) {
+ private BiomeType getBiomeCached(int x, int z, BiomeType baseBiome) {
final int index = (z - cacheOffsetZ) + (x - cacheOffsetX) * cacheSizeZ;
- final BaseBiome cacheEntry = cache[index];
+ final BiomeType cacheEntry = cache[index];
if (cacheEntry == null) {// unknown, fetch material
- final BaseBiome material = getBiome(x, z, baseBiome);
+ final BiomeType material = getBiome(x, z, baseBiome);
if (material == null) {
// outside
- cache[index] = OUTSIDE;
+ cache[index] = BiomeTypes.THE_VOID;
return null;
}
@@ -99,7 +100,7 @@ public abstract class ArbitraryBiomeShape {
return material;
}
- if (cacheEntry == OUTSIDE) {
+ if (cacheEntry == BiomeTypes.THE_VOID) {
// outside
return null;
}
@@ -107,16 +108,16 @@ public abstract class ArbitraryBiomeShape {
return cacheEntry;
}
- private boolean isInsideCached(int x, int z, BaseBiome baseBiome) {
+ private boolean isInsideCached(int x, int z, BiomeType baseBiome) {
final int index = (z - cacheOffsetZ) + (x - cacheOffsetX) * cacheSizeZ;
- final BaseBiome cacheEntry = cache[index];
+ final BiomeType cacheEntry = cache[index];
if (cacheEntry == null) {
// unknown block, meaning they must be outside the extent at this stage, but might still be inside the shape
return getBiomeCached(x, z, baseBiome) != null;
}
- return cacheEntry != OUTSIDE;
+ return cacheEntry != BiomeTypes.THE_VOID;
}
/**
@@ -127,7 +128,7 @@ public abstract class ArbitraryBiomeShape {
* @param hollow Specifies whether to generate a hollow shape.
* @return number of affected blocks.
*/
- public int generate(EditSession editSession, BaseBiome baseBiome, boolean hollow) {
+ public int generate(EditSession editSession, BiomeType baseBiome, boolean hollow) {
int affected = 0;
for (BlockVector2 position : getExtent()) {
@@ -135,8 +136,8 @@ public abstract class ArbitraryBiomeShape {
int z = position.getBlockZ();
if (!hollow) {
- final BaseBiome material = getBiome(x, z, baseBiome);
- if (material != null && material != OUTSIDE) {
+ final BiomeType material = getBiome(x, z, baseBiome);
+ if (material != null && material != BiomeTypes.THE_VOID) {
editSession.getWorld().setBiome(position, material);
++affected;
}
@@ -144,7 +145,7 @@ public abstract class ArbitraryBiomeShape {
continue;
}
- final BaseBiome material = getBiomeCached(x, z, baseBiome);
+ final BiomeType material = getBiomeCached(x, z, baseBiome);
if (material == null) {
continue;
}
@@ -180,16 +181,4 @@ public abstract class ArbitraryBiomeShape {
return affected;
}
- private static final BaseBiome OUTSIDE = new BaseBiome(0) {
- @Override
- public int hashCode() {
- return 0;
- }
-
- @Override
- public boolean equals(Object o) {
- return this == o;
- }
- };
-
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryShape.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryShape.java
index 142fbb481..b9eed1bee 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryShape.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryShape.java
@@ -34,8 +34,36 @@ public abstract class ArbitraryShape {
protected final Region extent;
+ private int cacheOffsetX;
+ private int cacheOffsetY;
+ private int cacheOffsetZ;
+ private int cacheSizeX;
+ private int cacheSizeY;
+ private int cacheSizeZ;
+
+ /**
+ * Cache entires:
+ * 0 = unknown
+ * -1 = outside
+ * 1 = inside
+ */
+ private final byte[] cache;
+
public ArbitraryShape(Region extent) {
this.extent = extent;
+
+ BlockVector3 min = extent.getMinimumPoint();
+ BlockVector3 max = extent.getMaximumPoint();
+
+ cacheOffsetX = min.getBlockX() - 1;
+ cacheOffsetY = min.getBlockY() - 1;
+ cacheOffsetZ = min.getBlockZ() - 1;
+
+ cacheSizeX = max.getX() - cacheOffsetX + 2;
+ cacheSizeY = max.getY() - cacheOffsetY + 2;
+ cacheSizeZ = max.getZ() - cacheOffsetZ + 2;
+
+ cache = new byte[cacheSizeX * cacheSizeY * cacheSizeZ];
}
protected Region getExtent() {
@@ -81,6 +109,40 @@ public abstract class ArbitraryShape {
BaseBlock material = getMaterial(x, y, z, pattern.apply(position));
if (material == null) {
+ final int index = (y - cacheOffsetY) + (z - cacheOffsetZ) * cacheSizeY + (x - cacheOffsetX) * cacheSizeY * cacheSizeZ;
+ cache[index] = -1;
+ continue;
+ }
+
+ boolean draw = false;
+ do {
+ if (!isInsideCached(x + 1, y, z, pattern)) {
+ draw = true;
+ break;
+ }
+ if (!isInsideCached(x - 1, y, z, pattern)) {
+ draw = true;
+ break;
+ }
+ if (!isInsideCached(x, y, z + 1, pattern)) {
+ draw = true;
+ break;
+ }
+ if (!isInsideCached(x, y, z - 1, pattern)) {
+ draw = true;
+ break;
+ }
+ if (!isInsideCached(x, y + 1, z, pattern)) {
+ draw = true;
+ break;
+ }
+ if (!isInsideCached(x, y - 1, z, pattern)) {
+ draw = true;
+ break;
+ }
+ } while (false);
+
+ if (!draw) {
continue;
}
@@ -92,4 +154,27 @@ public abstract class ArbitraryShape {
return affected;
}
+ private boolean isInsideCached(int x, int y, int z, Pattern pattern) {
+ final int index = (y - cacheOffsetY) + (z - cacheOffsetZ) * cacheSizeY + (x - cacheOffsetX) * cacheSizeY * cacheSizeZ;
+
+ switch (cache[index]) {
+ case 0:
+ BaseBlock mat = getMaterial(x, y, z, pattern.apply(BlockVector3.at(x, y, z)));
+ if (mat == null) {
+ cache[index] = -1;
+ return false;
+ }
+ cache[index] = 1;
+ return true;
+
+ case -1:
+ // outside
+ return false;
+
+ default:
+ // inside
+ return true;
+ }
+ }
+
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java b/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java
index 1307508f5..e97e7ebf6 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java
@@ -28,6 +28,7 @@ import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.function.pattern.Pattern;
+import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.io.file.FilenameException;
import com.sk89q.worldedit.world.block.BaseBlock;
@@ -62,7 +63,8 @@ public class CraftScriptContext extends CraftScriptEnvironment {
EditSession editSession = controller.getEditSessionFactory()
.getEditSession(player.getWorld(),
session.getBlockChangeLimit(), session.getBlockBag(player), player);
- editSession.enableQueue();
+ Request.request().setEditSession(editSession);
+ editSession.enableStandardMode();
editSessions.add(editSession);
return editSession;
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/session/SessionManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/session/SessionManager.java
index 5339db01d..4e5edd5f2 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/session/SessionManager.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/session/SessionManager.java
@@ -19,7 +19,8 @@
package com.sk89q.worldedit.session;
-import com.boydti.fawe.object.collection.SoftHashMap;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.sk89q.worldedit.LocalConfiguration;
@@ -27,50 +28,46 @@ import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.platform.ConfigurationLoadEvent;
+import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.session.storage.JsonFileSessionStore;
import com.sk89q.worldedit.session.storage.SessionStore;
import com.sk89q.worldedit.session.storage.VoidStore;
import com.sk89q.worldedit.util.concurrency.EvenMoreExecutors;
import com.sk89q.worldedit.util.eventbus.Subscribe;
import com.sk89q.worldedit.world.gamemode.GameModes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
-import java.lang.ref.Reference;
-import java.lang.ref.SoftReference;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Timer;
+import java.util.TimerTask;
import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.annotation.Nullable;
-
+import java.util.concurrent.Callable;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Session manager for WorldEdit.
- *
+ *
*
Get a reference to one from {@link WorldEdit}.
- *
+ *
*
While this class is thread-safe, the returned session may not be.
*/
public class SessionManager {
- @Deprecated
- public static int EXPIRATION_GRACE = 600000;
-
+ public static int EXPIRATION_GRACE = 0;
+ private static final int FLUSH_PERIOD = 1000 * 60;
private static final ListeningExecutorService executorService = MoreExecutors.listeningDecorator(EvenMoreExecutors.newBoundedCachedThreadPool(0, 1, 5));
- private static final Logger log = Logger.getLogger(SessionManager.class.getCanonicalName());
+ private static final Logger log = LoggerFactory.getLogger(SessionManager.class);
private final Timer timer = new Timer();
private final WorldEdit worldEdit;
- private final Map sessions = new ConcurrentHashMap<>(8, 0.9f, 1);
- private final Map> softSessions = new SoftHashMap<>();
-
+ private final Map sessions = new HashMap<>();
private SessionStore store = new VoidStore();
- private File path;
/**
* Create a new session manager.
@@ -82,6 +79,7 @@ public class SessionManager {
this.worldEdit = worldEdit;
worldEdit.getEventBus().register(this);
+ timer.schedule(new SessionTracker(), FLUSH_PERIOD, FLUSH_PERIOD);
}
/**
@@ -92,7 +90,7 @@ public class SessionManager {
*/
public synchronized boolean contains(SessionOwner owner) {
checkNotNull(owner);
- return sessions.containsKey(getKey(owner)) || softSessions.containsKey(owner);
+ return sessions.containsKey(getKey(owner));
}
/**
@@ -110,24 +108,7 @@ public class SessionManager {
return holder.session;
}
}
- Iterator>> iter = softSessions.entrySet().iterator();
- while (iter.hasNext()) {
- Map.Entry> entry = iter.next();
- UUID key = entry.getKey();
- SessionHolder holder = entry.getValue().get();
- if (holder == null) {
- iter.remove();
- continue;
- }
- String test = holder.key.getName();
- if (test != null && name.equals(test)) {
-// if (holder.key.isActive()) {
- iter.remove();
- sessions.put(key, holder);
-// }
- return holder.session;
- }
- }
+
return null;
}
@@ -141,24 +122,12 @@ public class SessionManager {
@Nullable
public synchronized LocalSession getIfPresent(SessionOwner owner) {
checkNotNull(owner);
- UUID key = getKey(owner);
- SessionHolder stored = sessions.get(key);
+ SessionHolder stored = sessions.get(getKey(owner));
if (stored != null) {
return stored.session;
} else {
- Reference reference = softSessions.get(key);
- if (reference != null) {
- stored = reference.get();
- if (stored != null) {
-// if (stored.key.isActive()) {
- softSessions.remove(key);
- sessions.put(key, stored);
-// }
- return stored.session;
- }
- }
+ return null;
}
- return null;
}
/**
@@ -179,36 +148,26 @@ public class SessionManager {
try {
session = store.load(getKey(sessionKey));
session.postLoad();
- } catch (Throwable e) {
- log.log(Level.WARNING, "Failed to load saved session", e);
+ } catch (IOException e) {
+ log.warn("Failed to load saved session", e);
session = new LocalSession();
}
+ Request.request().setSession(session);
session.setConfiguration(config);
session.setBlockChangeLimit(config.defaultChangeLimit);
+ session.setTimeout(config.calculationTimeout);
+ // Remember the session regardless of if it's currently active or not.
+ // And have the SessionTracker FLUSH inactive sessions.
sessions.put(getKey(owner), new SessionHolder(sessionKey, session));
}
- // Set the limit on the number of blocks that an operation can
- // change at once, or don't if the owner has an override or there
- // is no limit. There is also a default limit
- int currentChangeLimit = session.getBlockChangeLimit();
-
- if (!owner.hasPermission("worldedit.limit.unrestricted") && config.maxChangeLimit > -1) {
- // If the default limit is infinite but there is a maximum
- // limit, make sure to not have it be overridden
- if (config.defaultChangeLimit < 0) {
- if (currentChangeLimit < 0 || currentChangeLimit > config.maxChangeLimit) {
- session.setBlockChangeLimit(config.maxChangeLimit);
- }
- } else {
- // Bound the change limit
- int maxChangeLimit = config.maxChangeLimit;
- if (currentChangeLimit == -1 || currentChangeLimit > maxChangeLimit) {
- session.setBlockChangeLimit(maxChangeLimit);
- }
- }
+ if (shouldBoundLimit(owner, "worldedit.limit.unrestricted", session.getBlockChangeLimit(), config.maxChangeLimit)) {
+ session.setBlockChangeLimit(config.maxChangeLimit);
+ }
+ if (shouldBoundLimit(owner, "worldedit.timeout.unrestricted", session.getTimeout(), config.maxCalculationTimeout)) {
+ session.setTimeout(config.maxCalculationTimeout);
}
// Have the session use inventory if it's enabled and the owner
@@ -221,27 +180,49 @@ public class SessionManager {
return session;
}
- private void save(SessionHolder holder) {
- SessionKey key = holder.key;
- holder.session.setClipboard(null);
- if (key.isPersistent()) {
- try {
- if (holder.session.compareAndResetDirty()) {
- if (holder.session.save()) {
- store.save(getKey(key), holder.session);
- } else if (path != null) {
- File file = new File(path, getKey(key) + ".json");
- if (file.exists()) {
- if (!file.delete()) {
- file.deleteOnExit();
- }
- }
+ private boolean shouldBoundLimit(SessionOwner owner, String permission, int currentLimit, int maxLimit) {
+ if (maxLimit > -1) { // if max is finite
+ return (currentLimit < 0 || currentLimit > maxLimit) // make sure current is finite and less than max
+ && !owner.hasPermission(permission); // unless user has unlimited permission
+ }
+ return false;
+ }
+
+ /**
+ * Save a map of sessions to disk.
+ *
+ * @param sessions a map of sessions to save
+ * @return a future that completes on save or error
+ */
+ private ListenableFuture> commit(final Map sessions) {
+ checkNotNull(sessions);
+
+ if (sessions.isEmpty()) {
+ return Futures.immediateFuture(sessions);
+ }
+
+ return executorService.submit((Callable) () -> {
+ Exception exception = null;
+
+ for (Map.Entry entry : sessions.entrySet()) {
+ SessionKey key = entry.getKey();
+
+ if (key.isPersistent()) {
+ try {
+ store.save(getKey(key), entry.getValue());
+ } catch (IOException e) {
+ log.warn("Failed to write session for UUID " + getKey(key), e);
+ exception = e;
}
}
- } catch (IOException e) {
- log.log(Level.WARNING, "Failed to write session for UUID " + getKey(key), e);
}
- }
+
+ if (exception != null) {
+ throw exception;
+ }
+
+ return sessions;
+ });
}
/**
@@ -277,44 +258,65 @@ public class SessionManager {
*/
public synchronized void remove(SessionOwner owner) {
checkNotNull(owner);
- SessionHolder session = sessions.remove(getKey(owner));
- if (session != null) {
- save(session);
- }
+ sessions.remove(getKey(owner));
}
- public synchronized void forget(SessionOwner owner) {
- checkNotNull(owner);
- UUID key = getKey(owner);
- SessionHolder holder = sessions.remove(key);
- if (holder != null) {
- softSessions.put(key, new SoftReference(holder));
- save(holder);
- }
+ /**
+ * Called to unload this session manager.
+ */
+ public synchronized void unload() {
+ clear();
}
/**
* Remove all sessions.
*/
public synchronized void clear() {
- for (Map.Entry entry : sessions.entrySet()) {
- save(entry.getValue());
- }
+ saveChangedSessions();
sessions.clear();
}
+ private synchronized void saveChangedSessions() {
+ long now = System.currentTimeMillis();
+ Iterator it = sessions.values().iterator();
+ Map saveQueue = new HashMap<>();
+
+ while (it.hasNext()) {
+ SessionHolder stored = it.next();
+ if (stored.key.isActive()) {
+ stored.lastActive = now;
+
+ if (stored.session.compareAndResetDirty()) {
+ // Don't save unless player disconnects
+// saveQueue.put(stored.key, stored.session);
+ }
+ } else {
+ if (now - stored.lastActive > EXPIRATION_GRACE) {
+ if (stored.session.compareAndResetDirty()) {
+ saveQueue.put(stored.key, stored.session);
+ }
+
+ it.remove();
+ }
+ }
+ }
+
+ if (!saveQueue.isEmpty()) {
+ commit(saveQueue);
+ }
+ }
+
@Subscribe
public void onConfigurationLoad(ConfigurationLoadEvent event) {
LocalConfiguration config = event.getConfiguration();
File dir = new File(config.getWorkingDirectory(), "sessions");
store = new JsonFileSessionStore(dir);
- this.path = dir;
}
/**
* Stores the owner of a session, the session, and the last active time.
*/
- private static class SessionHolder {
+ private static final class SessionHolder {
private final SessionKey key;
private final LocalSession session;
private long lastActive = System.currentTimeMillis();
@@ -325,7 +327,17 @@ public class SessionManager {
}
}
-
-
+ /**
+ * Removes inactive sessions after they have been inactive for a period
+ * of time. Commits them as well.
+ */
+ private class SessionTracker extends TimerTask {
+ @Override
+ public void run() {
+ synchronized (SessionManager.this) {
+ saveChangedSessions();
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/Request.java b/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/Request.java
index ef26a05f1..e0786b03e 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/Request.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/Request.java
@@ -34,21 +34,12 @@ public final class Request {
private static final ThreadLocal threadLocal = ThreadLocal.withInitial(Request::new);
- private
- @Nullable
- World world;
- private
- @Nullable
- Actor actor;
- private
- @Nullable
- LocalSession session;
- private
- @Nullable
- EditSession editSession;
- private
- @Nullable
- Extent extent;
+ private @Nullable World world;
+ private @Nullable Actor actor;
+ private @Nullable LocalSession session;
+ private @Nullable EditSession editSession;
+ private @Nullable Extent extent;
+ private boolean valid;
private Request() {
}
@@ -148,8 +139,20 @@ public final class Request {
* Reset the current request and clear all fields.
*/
public static void reset() {
+ request().invalidate();
threadLocal.remove();
}
+ /**
+ * Check if the current request object is still valid. Invalid requests may contain outdated values.
+ *
+ * @return true if the request is valid
+ */
+ public boolean isValid() {
+ return valid;
+ }
+ private void invalidate() {
+ valid = false;
+ }
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/RequestExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/RequestExtent.java
new file mode 100644
index 000000000..dc5aac815
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/RequestExtent.java
@@ -0,0 +1,109 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.session.request;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.entity.BaseEntity;
+import com.sk89q.worldedit.entity.Entity;
+import com.sk89q.worldedit.extent.Extent;
+import com.sk89q.worldedit.function.operation.Operation;
+import com.sk89q.worldedit.math.BlockVector2;
+import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.regions.Region;
+import com.sk89q.worldedit.util.Location;
+import com.sk89q.worldedit.world.biome.BiomeType;
+import com.sk89q.worldedit.world.block.BaseBlock;
+import com.sk89q.worldedit.world.block.BlockState;
+import com.sk89q.worldedit.world.block.BlockStateHolder;
+
+import javax.annotation.Nullable;
+import java.util.List;
+
+public class RequestExtent implements Extent {
+
+ private Request request;
+
+ protected Extent getExtent() {
+ if (request == null || !request.isValid()) {
+ request = Request.request();
+ }
+ return request.getEditSession();
+ }
+
+ @Override
+ public BlockVector3 getMinimumPoint() {
+ return getExtent().getMinimumPoint();
+ }
+
+ @Override
+ public BlockVector3 getMaximumPoint() {
+ return getExtent().getMaximumPoint();
+ }
+
+ @Override
+ public List extends Entity> getEntities(Region region) {
+ return getExtent().getEntities(region);
+ }
+
+ @Override
+ public List extends Entity> getEntities() {
+ return getExtent().getEntities();
+ }
+
+ @Override
+ @Nullable
+ public Entity createEntity(Location location, BaseEntity entity) {
+ return getExtent().createEntity(location, entity);
+ }
+
+ @Override
+ public BlockState getBlock(BlockVector3 position) {
+ return getExtent().getBlock(position);
+ }
+
+ @Override
+ public BaseBlock getFullBlock(BlockVector3 position) {
+ return getExtent().getFullBlock(position);
+ }
+
+ @Override
+ public BiomeType getBiome(BlockVector2 position) {
+ return getExtent().getBiome(position);
+ }
+
+ @Override
+ public > boolean setBlock(BlockVector3 position, T block) throws WorldEditException {
+ return getExtent().setBlock(position, block);
+ }
+
+ @Override
+ public boolean setBiome(BlockVector2 position, BiomeType biome) {
+ return getExtent().setBiome(position, biome);
+ }
+
+ @Override
+ @Nullable
+ public Operation commit() {
+ Operation commit = getExtent().commit();
+ request = null;
+ return commit;
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/RequestSelection.java b/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/RequestSelection.java
index 70d8d2baf..9e37e4da0 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/RequestSelection.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/session/request/RequestSelection.java
@@ -19,10 +19,10 @@
package com.sk89q.worldedit.session.request;
-import com.sk89q.worldedit.math.BlockVector3;
-import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
+import com.sk89q.worldedit.math.BlockVector2;
+import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.NullRegion;
import com.sk89q.worldedit.regions.Region;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/session/storage/JsonFileSessionStore.java b/worldedit-core/src/main/java/com/sk89q/worldedit/session/storage/JsonFileSessionStore.java
index d7b2a9893..ad8e422bf 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/session/storage/JsonFileSessionStore.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/session/storage/JsonFileSessionStore.java
@@ -19,8 +19,6 @@
package com.sk89q.worldedit.session.storage;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonIOException;
@@ -28,6 +26,8 @@ import com.google.gson.JsonParseException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.util.gson.GsonUtil;
import com.sk89q.worldedit.util.io.Closer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.BufferedWriter;
@@ -37,8 +37,8 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.UUID;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+
+import static com.google.common.base.Preconditions.checkNotNull;
/**
* Stores sessions as JSON files in a directory.
@@ -47,7 +47,7 @@ import java.util.logging.Logger;
*/
public class JsonFileSessionStore implements SessionStore {
- private static final Logger log = Logger.getLogger(JsonFileSessionStore.class.getCanonicalName());
+ private static final Logger log = LoggerFactory.getLogger(JsonFileSessionStore.class);
private final Gson gson;
private final File dir;
@@ -61,7 +61,7 @@ public class JsonFileSessionStore implements SessionStore {
if (!dir.isDirectory()) {
if (!dir.mkdirs()) {
- log.log(Level.WARNING, "Failed to create directory '" + dir.getPath() + "' for sessions");
+ log.warn("Failed to create directory '" + dir.getPath() + "' for sessions");
}
}
@@ -111,12 +111,12 @@ public class JsonFileSessionStore implements SessionStore {
if (finalFile.exists()) {
if (!finalFile.delete()) {
- log.log(Level.WARNING, "Failed to delete " + finalFile.getPath() + " so the .tmp file can replace it");
+ log.warn("Failed to delete " + finalFile.getPath() + " so the .tmp file can replace it");
}
}
if (!tempFile.renameTo(finalFile)) {
- log.log(Level.WARNING, "Failed to rename temporary session file to " + finalFile.getPath());
+ log.warn("Failed to rename temporary session file to " + finalFile.getPath());
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/Location.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/Location.java
index 35e228b93..5d3aa84e4 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/Location.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/Location.java
@@ -208,6 +208,9 @@ public class Location extends Vector3 {
* @return the direction vector
*/
public Vector3 getDirection() {
+ if (Float.isNaN(getYaw()) && Float.isNaN(getPitch())) {
+ return Vector3.ZERO;
+ }
double yaw = Math.toRadians(this.getYaw());
double pitch = Math.toRadians(this.getPitch());
double xz = Math.cos(pitch);
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java
index 18a8cc806..12513b97d 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java
@@ -1,283 +1,282 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-// $Id$
-
-package com.sk89q.worldedit.util;
-
-import com.google.common.collect.Lists;
-import com.sk89q.util.StringUtil;
-import com.sk89q.worldedit.LocalConfiguration;
-import com.sk89q.worldedit.LocalSession;
-import com.sk89q.worldedit.world.block.BlockTypes;
-import com.sk89q.worldedit.world.item.ItemTypes;
-import com.sk89q.worldedit.world.registry.LegacyMapper;
-import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Properties;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.stream.Collectors;
-
-/**
- * Simple LocalConfiguration that loads settings using
- * {@code java.util.Properties}.
- */
-public class PropertiesConfiguration extends LocalConfiguration {
-
- private static final Logger log = Logger.getLogger(PropertiesConfiguration.class.getCanonicalName());
-
- protected Properties properties;
- protected File path;
-
- /**
- * Construct the object. The configuration isn't loaded yet.
- *
- * @param path the path tot he configuration
- */
- public PropertiesConfiguration(File path) {
- this.path = path;
-
- properties = new Properties();
- }
-
- @Override
- public void load() {
- try (InputStream stream = new FileInputStream(path)) {
- properties.load(stream);
- } catch (FileNotFoundException ignored) {
- } catch (IOException e) {
- log.log(Level.WARNING, "Failed to read configuration", e);
- }
-
- loadExtra();
-
- profile = getBool("profile", profile);
-
- disallowedBlocks =
- new HashSet<>(getStringSet("limits.disallowed-blocks", getDefaultDisallowedBlocks()));
- allowedDataCycleBlocks =
- new HashSet<>(getStringSet("limits.allowed-data-cycle-blocks", null));
- defaultChangeLimit = getInt("default-max-changed-blocks", defaultChangeLimit);
- maxChangeLimit = getInt("max-changed-blocks", maxChangeLimit);
- defaultMaxPolygonalPoints = getInt("default-max-polygon-points", defaultMaxPolygonalPoints);
- maxPolygonalPoints = getInt("max-polygon-points", maxPolygonalPoints);
- defaultMaxPolyhedronPoints = getInt("default-max-polyhedron-points", defaultMaxPolyhedronPoints);
- maxPolyhedronPoints = getInt("max-polyhedron-points", maxPolyhedronPoints);
- shellSaveType = getString("shell-save-type", shellSaveType);
- maxRadius = getInt("max-radius", maxRadius);
- maxSuperPickaxeSize = getInt("max-super-pickaxe-size", maxSuperPickaxeSize);
- maxBrushRadius = getInt("max-brush-radius", maxBrushRadius);
- logCommands = getBool("log-commands", logCommands);
- logFile = getString("log-file", logFile);
- logFormat = getString("log-format", logFormat);
- registerHelp = getBool("register-help", registerHelp);
- wandItem = getString("wand-item", wandItem);
- try {
- wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).getId();
- } catch (Throwable e) {}
- superPickaxeDrop = getBool("super-pickaxe-drop-items", superPickaxeDrop);
- superPickaxeManyDrop = getBool("super-pickaxe-many-drop-items", superPickaxeManyDrop);
- noDoubleSlash = getBool("no-double-slash", noDoubleSlash);
- useInventory = getBool("use-inventory", useInventory);
- useInventoryOverride = getBool("use-inventory-override", useInventoryOverride);
- useInventoryCreativeOverride = getBool("use-inventory-creative-override", useInventoryCreativeOverride);
- navigationWand = getString("nav-wand-item", navigationWand);
- try {
- navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).getId();
- } catch (Throwable e) {}
- navigationWandMaxDistance = getInt("nav-wand-distance", navigationWandMaxDistance);
- navigationUseGlass = getBool("nav-use-glass", navigationUseGlass);
- scriptTimeout = getInt("scripting-timeout", scriptTimeout);
- saveDir = getString("schematic-save-dir", saveDir);
- scriptsDir = getString("craftscript-dir", scriptsDir);
- butcherDefaultRadius = getInt("butcher-default-radius", butcherDefaultRadius);
- butcherMaxRadius = getInt("butcher-max-radius", butcherMaxRadius);
- allowSymlinks = getBool("allow-symbolic-links", allowSymlinks);
-
- LocalSession.MAX_HISTORY_SIZE = Math.max(15, getInt("history-size", 15));
-
- String snapshotsDir = getString("snapshots-dir", "");
- if (!snapshotsDir.isEmpty()) {
- snapshotRepo = new SnapshotRepository(snapshotsDir);
- }
-
- path.getParentFile().mkdirs();
- try (OutputStream output = new FileOutputStream(path)) {
- properties.store(output, "Don't put comments; they get removed");
- } catch (IOException e) {
- log.log(Level.WARNING, "Failed to write configuration", e);
- }
- }
-
- /**
- * Called to load extra configuration.
- */
- protected void loadExtra() {
- }
-
- /**
- * Get a string value.
- *
- * @param key the key
- * @param def the default value
- * @return the value
- */
- protected String getString(String key, String def) {
- if (def == null) {
- def = "";
- }
- String val = properties.getProperty(key);
- if (val == null) {
- properties.setProperty(key, def);
- return def;
- } else {
- return val;
- }
- }
-
- /**
- * Get a boolean value.
- *
- * @param key the key
- * @param def the default value
- * @return the value
- */
- protected boolean getBool(String key, boolean def) {
- String val = properties.getProperty(key);
- if (val == null) {
- properties.setProperty(key, def ? "true" : "false");
- return def;
- } else {
- return val.equalsIgnoreCase("true")
- || val.equals("1");
- }
- }
-
- /**
- * Get an integer value.
- *
- * @param key the key
- * @param def the default value
- * @return the value
- */
- protected int getInt(String key, int def) {
- String val = properties.getProperty(key);
- if (val == null) {
- properties.setProperty(key, String.valueOf(def));
- return def;
- } else {
- try {
- return Integer.parseInt(val);
- } catch (NumberFormatException e) {
- properties.setProperty(key, String.valueOf(def));
- return def;
- }
- }
- }
-
- /**
- * Get a double value.
- *
- * @param key the key
- * @param def the default value
- * @return the value
- */
- protected double getDouble(String key, double def) {
- String val = properties.getProperty(key);
- if (val == null) {
- properties.setProperty(key, String.valueOf(def));
- return def;
- } else {
- try {
- return Double.parseDouble(val);
- } catch (NumberFormatException e) {
- properties.setProperty(key, String.valueOf(def));
- return def;
- }
- }
- }
-
- /**
- * Get a double value.
- *
- * @param key the key
- * @param def the default value
- * @return the value
- */
- protected Set getIntSet(String key, int[] def) {
- String val = properties.getProperty(key);
- if (val == null) {
- properties.setProperty(key, StringUtil.joinString(def, ",", 0));
- Set set = new HashSet<>();
- for (int i : def) {
- set.add(i);
- }
- return set;
- } else {
- Set set = new HashSet<>();
- String[] parts = val.split(",");
- for (String part : parts) {
- try {
- int v = Integer.parseInt(part.trim());
- set.add(v);
- } catch (NumberFormatException ignored) {
- }
- }
- return set;
- }
- }
-
- /**
- * Get a String set.
- *
- * @param key the key
- * @param def the default value
- * @return the value
- */
- protected Set getStringSet(String key, String[] def) {
- String val = properties.getProperty(key);
- if (val == null) {
- properties.setProperty(key, StringUtil.joinString(def, ",", 0));
- return new HashSet<>(Arrays.asList(def));
- } else {
- Set set = new HashSet<>();
- String[] parts = val.split(",");
- for (String part : parts) {
- try {
- String v = part.trim();
- set.add(v);
- } catch (NumberFormatException ignored) {
- }
- }
- return set;
- }
- }
-
-}
\ No newline at end of file
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+// $Id$
+
+package com.sk89q.worldedit.util;
+
+import com.sk89q.util.StringUtil;
+import com.sk89q.worldedit.LocalConfiguration;
+import com.sk89q.worldedit.LocalSession;
+import com.sk89q.worldedit.util.report.Unreported;
+import com.sk89q.worldedit.world.registry.LegacyMapper;
+import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
+/**
+ * Simple LocalConfiguration that loads settings using
+ * {@code java.util.Properties}.
+ */
+public class PropertiesConfiguration extends LocalConfiguration {
+
+ @Unreported private static final Logger log = LoggerFactory.getLogger(PropertiesConfiguration.class);
+
+ @Unreported protected Properties properties;
+ @Unreported protected File path;
+
+ /**
+ * Construct the object. The configuration isn't loaded yet.
+ *
+ * @param path the path tot he configuration
+ */
+ public PropertiesConfiguration(File path) {
+ this.path = path;
+
+ properties = new Properties();
+ }
+
+ @Override
+ public void load() {
+ try (InputStream stream = new FileInputStream(path)) {
+ properties.load(stream);
+ } catch (FileNotFoundException ignored) {
+ } catch (IOException e) {
+ log.warn("Failed to read configuration", e);
+ }
+
+ loadExtra();
+
+ profile = getBool("profile", profile);
+ traceUnflushedSessions = getBool("trace-unflushed-sessions", traceUnflushedSessions);
+ disallowedBlocks = getStringSet("disallowed-blocks", getDefaultDisallowedBlocks());
+ defaultChangeLimit = getInt("default-max-changed-blocks", defaultChangeLimit);
+ maxChangeLimit = getInt("max-changed-blocks", maxChangeLimit);
+ defaultMaxPolygonalPoints = getInt("default-max-polygon-points", defaultMaxPolygonalPoints);
+ maxPolygonalPoints = getInt("max-polygon-points", maxPolygonalPoints);
+ defaultMaxPolyhedronPoints = getInt("default-max-polyhedron-points", defaultMaxPolyhedronPoints);
+ maxPolyhedronPoints = getInt("max-polyhedron-points", maxPolyhedronPoints);
+ shellSaveType = getString("shell-save-type", shellSaveType);
+ maxRadius = getInt("max-radius", maxRadius);
+ maxSuperPickaxeSize = getInt("max-super-pickaxe-size", maxSuperPickaxeSize);
+ maxBrushRadius = getInt("max-brush-radius", maxBrushRadius);
+ logCommands = getBool("log-commands", logCommands);
+ logFile = getString("log-file", logFile);
+ logFormat = getString("log-format", logFormat);
+ registerHelp = getBool("register-help", registerHelp);
+ wandItem = getString("wand-item", wandItem);
+ try {
+ wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).getId();
+ } catch (Throwable e) {
+ }
+ superPickaxeDrop = getBool("super-pickaxe-drop-items", superPickaxeDrop);
+ superPickaxeManyDrop = getBool("super-pickaxe-many-drop-items", superPickaxeManyDrop);
+ noDoubleSlash = getBool("no-double-slash", noDoubleSlash);
+ useInventory = getBool("use-inventory", useInventory);
+ useInventoryOverride = getBool("use-inventory-override", useInventoryOverride);
+ useInventoryCreativeOverride = getBool("use-inventory-creative-override", useInventoryCreativeOverride);
+ navigationWand = getString("nav-wand-item", navigationWand);
+ try {
+ navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).getId();
+ } catch (Throwable e) {
+ }
+ navigationWandMaxDistance = getInt("nav-wand-distance", navigationWandMaxDistance);
+ navigationUseGlass = getBool("nav-use-glass", navigationUseGlass);
+ scriptTimeout = getInt("scripting-timeout", scriptTimeout);
+ calculationTimeout = getInt("calculation-timeout", calculationTimeout);
+ maxCalculationTimeout = getInt("max-calculation-timeout", maxCalculationTimeout);
+ saveDir = getString("schematic-save-dir", saveDir);
+ scriptsDir = getString("craftscript-dir", scriptsDir);
+ butcherDefaultRadius = getInt("butcher-default-radius", butcherDefaultRadius);
+ butcherMaxRadius = getInt("butcher-max-radius", butcherMaxRadius);
+ allowSymlinks = getBool("allow-symbolic-links", allowSymlinks);
+ serverSideCUI = getBool("server-side-cui", serverSideCUI);
+
+ LocalSession.MAX_HISTORY_SIZE = Math.max(15, getInt("history-size", 15));
+
+ String snapshotsDir = getString("snapshots-dir", "");
+ if (!snapshotsDir.isEmpty()) {
+ snapshotRepo = new SnapshotRepository(snapshotsDir);
+ }
+
+ path.getParentFile().mkdirs();
+ try (OutputStream output = new FileOutputStream(path)) {
+ properties.store(output, "Don't put comments; they get removed");
+ } catch (IOException e) {
+ log.warn("Failed to write configuration", e);
+ }
+ }
+
+ /**
+ * Called to load extra configuration.
+ */
+ protected void loadExtra() {
+ }
+
+ /**
+ * Get a string value.
+ *
+ * @param key the key
+ * @param def the default value
+ * @return the value
+ */
+ protected String getString(String key, String def) {
+ if (def == null) {
+ def = "";
+ }
+ String val = properties.getProperty(key);
+ if (val == null) {
+ properties.setProperty(key, def);
+ return def;
+ } else {
+ return val;
+ }
+ }
+
+ /**
+ * Get a boolean value.
+ *
+ * @param key the key
+ * @param def the default value
+ * @return the value
+ */
+ protected boolean getBool(String key, boolean def) {
+ String val = properties.getProperty(key);
+ if (val == null) {
+ properties.setProperty(key, def ? "true" : "false");
+ return def;
+ } else {
+ return val.equalsIgnoreCase("true")
+ || val.equals("1");
+ }
+ }
+
+ /**
+ * Get an integer value.
+ *
+ * @param key the key
+ * @param def the default value
+ * @return the value
+ */
+ protected int getInt(String key, int def) {
+ String val = properties.getProperty(key);
+ if (val == null) {
+ properties.setProperty(key, String.valueOf(def));
+ return def;
+ } else {
+ try {
+ return Integer.parseInt(val);
+ } catch (NumberFormatException e) {
+ properties.setProperty(key, String.valueOf(def));
+ return def;
+ }
+ }
+ }
+
+ /**
+ * Get a double value.
+ *
+ * @param key the key
+ * @param def the default value
+ * @return the value
+ */
+ protected double getDouble(String key, double def) {
+ String val = properties.getProperty(key);
+ if (val == null) {
+ properties.setProperty(key, String.valueOf(def));
+ return def;
+ } else {
+ try {
+ return Double.parseDouble(val);
+ } catch (NumberFormatException e) {
+ properties.setProperty(key, String.valueOf(def));
+ return def;
+ }
+ }
+ }
+
+ /**
+ * Get a double value.
+ *
+ * @param key the key
+ * @param def the default value
+ * @return the value
+ */
+ protected Set getIntSet(String key, int[] def) {
+ String val = properties.getProperty(key);
+ if (val == null) {
+ properties.setProperty(key, StringUtil.joinString(def, ",", 0));
+ Set set = new HashSet<>();
+ for (int i : def) {
+ set.add(i);
+ }
+ return set;
+ } else {
+ Set set = new HashSet<>();
+ String[] parts = val.split(",");
+ for (String part : parts) {
+ try {
+ int v = Integer.parseInt(part.trim());
+ set.add(v);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ return set;
+ }
+ }
+
+ /**
+ * Get a String set.
+ *
+ * @param key the key
+ * @param def the default value
+ * @return the value
+ */
+ protected Set getStringSet(String key, String[] def) {
+ String val = properties.getProperty(key);
+ if (val == null) {
+ properties.setProperty(key, StringUtil.joinString(def, ",", 0));
+ return new HashSet<>(Arrays.asList(def));
+ } else {
+ Set set = new HashSet<>();
+ String[] parts = val.split(",");
+ for (String part : parts) {
+ try {
+ String v = part.trim();
+ set.add(v);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ return set;
+ }
+ }
+
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java
index fba4fc67e..5a657584d 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java
@@ -26,11 +26,10 @@ import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.session.SessionManager;
import com.sk89q.worldedit.util.report.Unreported;
import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
+import org.slf4j.Logger;
import java.io.IOException;
import java.util.HashSet;
-import java.util.logging.Level;
-import java.util.logging.Logger;
/**
* A less simple implementation of {@link LocalConfiguration}
@@ -51,10 +50,11 @@ public class YAMLConfiguration extends LocalConfiguration {
try {
config.load();
} catch (IOException e) {
- logger.log(Level.WARNING, "Error loading WorldEdit configuration", e);
+ logger.warn("Error loading WorldEdit configuration", e);
}
profile = config.getBoolean("debug", profile);
+ traceUnflushedSessions = config.getBoolean("debugging.trace-unflushed-sessions", traceUnflushedSessions);
wandItem = convertLegacyItem(config.getString("wand-item", wandItem));
defaultChangeLimit = Math.max(-1, config.getInt(
@@ -79,8 +79,7 @@ public class YAMLConfiguration extends LocalConfiguration {
butcherMaxRadius = Math.max(-1, config.getInt("limits.butcher-radius.maximum", butcherMaxRadius));
disallowedBlocks = new HashSet<>(config.getStringList("limits.disallowed-blocks", Lists.newArrayList(getDefaultDisallowedBlocks())));
- allowedDataCycleBlocks =
- new HashSet<>(config.getStringList("limits.allowed-data-cycle-blocks", null));
+ allowedDataCycleBlocks = new HashSet<>(config.getStringList("limits.allowed-data-cycle-blocks", null));
registerHelp = config.getBoolean("register-help", true);
logCommands = config.getBoolean("logging.log-commands", logCommands);
@@ -107,6 +106,9 @@ public class YAMLConfiguration extends LocalConfiguration {
scriptTimeout = config.getInt("scripting.timeout", scriptTimeout);
scriptsDir = config.getString("scripting.dir", scriptsDir);
+ calculationTimeout = config.getInt("calculation.timeout", calculationTimeout);
+ maxCalculationTimeout = config.getInt("calculation.max-timeout", maxCalculationTimeout);
+
saveDir = config.getString("saving.dir", saveDir);
allowSymlinks = config.getBoolean("files.allow-symbolic-links", false);
@@ -114,6 +116,7 @@ public class YAMLConfiguration extends LocalConfiguration {
SessionManager.EXPIRATION_GRACE = config.getInt("history.expiration", 10) * 60 * 1000;
showHelpInfo = config.getBoolean("show-help-on-first-use", true);
+ serverSideCUI = config.getBoolean("server-side-cui", true);
String snapshotsDir = config.getString("snapshots.directory", "");
if (!snapshotsDir.isEmpty()) {
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/FastListIterator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/FastListIterator.java
deleted file mode 100644
index 3182502f6..000000000
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/FastListIterator.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.util.collection;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-/**
- * A fast iterator for lists that uses an internal index integer
- * and caches the size of the list. The size of the list cannot change
- * during iteration and {@link Iterator#remove()} is not supported.
- *
- * The iterator in Java, at least in older Java versions, is very slow,
- * causing a significant amount of time in operations in WorldEdit
- * being spent on {@link Iterator#hasNext()}. In contrast, the iterator
- * implemented by this class is very quick, as long as
- * {@link List#get(int)} is fast.
- *
- * @param the element
- */
-public class FastListIterator implements Iterator {
-
- private final List list;
- private int index;
- private final int size;
- private final int increment;
-
- /**
- * Create a new fast iterator.
- *
- * @param list the list
- * @param index the index to start from
- * @param size the size of the list
- * @param increment the increment amount (i.e. 1 or -1)
- */
- private FastListIterator(List list, int index, int size, int increment) {
- checkNotNull(list);
- checkArgument(size >= 0, "size >= 0 required");
- checkArgument(index >= 0, "index >= 0 required");
- this.list = list;
- this.index = index;
- this.size = size;
- this.increment = increment;
- }
-
- @Override
- public boolean hasNext() {
- return index >= 0 && index < size;
- }
-
- @Override
- public E next() {
- if (hasNext()) {
- E entry = list.get(index);
- index += increment;
- return entry;
- } else {
- throw new NoSuchElementException();
- }
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("Not supported");
- }
-
- /**
- * Create a new forward iterator for the given list.
- *
- * @param list the list
- * @param the element
- * @return an iterator
- */
- public static Iterator forwardIterator(List list) {
- return new FastListIterator<>(list, 0, list.size(), 1);
- }
-
- /**
- * Create a new reverse iterator for the given list.
- *
- * @param list the list
- * @param the element
- * @return an iterator
- */
- public static Iterator reverseIterator(List list) {
- if (!list.isEmpty()) {
- return new FastListIterator<>(list, list.size() - 1, list.size(), -1);
- } else {
- return new FastListIterator<>(list, 0, 0, -1);
- }
- }
-
-}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/TupleArrayList.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/TupleArrayList.java
deleted file mode 100644
index 8247607f1..000000000
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/TupleArrayList.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.util.collection;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * An {@link ArrayList} that takes {@link Map.Entry}-like tuples. This class
- * exists for legacy reasons.
- *
- * @param the first type in the tuple
- * @param the second type in the tuple
- */
-public class TupleArrayList extends ArrayList> {
-
- /**
- * Add an item to the list.
- *
- * @param a the 'key'
- * @param b the 'value'
- */
- public void put(A a, B b) {
- add(new Tuple<>(a, b));
- }
-
- /**
- * Return an entry iterator that traverses in the reverse direction.
- *
- * @param reverse true to return the reverse iterator
- * @return an entry iterator
- */
- public Iterator> iterator(boolean reverse) {
- return reverse ? reverseIterator() : iterator();
- }
-
- @Override
- public Iterator> iterator() {
- return FastListIterator.forwardIterator(this);
- }
-
- /**
- * Return an entry iterator that traverses in the reverse direction.
- *
- * @return an entry iterator
- */
- public Iterator> reverseIterator() {
- return FastListIterator.reverseIterator(this);
- }
-
- private static class Tuple implements Map.Entry {
- private A key;
- private B value;
-
- private Tuple(A key, B value) {
- this.key = key;
- this.value = value;
- }
-
- @Override
- public A getKey() {
- return key;
- }
-
- @Override
- public B getValue() {
- return value;
- }
-
- @Override
- public B setValue(B value) {
- throw new UnsupportedOperationException();
- }
- }
-
-}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/eventbus/EventBus.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/eventbus/EventBus.java
index d8cbe8b20..d97c090ea 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/eventbus/EventBus.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/eventbus/EventBus.java
@@ -19,13 +19,13 @@
package com.sk89q.worldedit.util.eventbus;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
import com.google.common.eventbus.DeadEvent;
import com.sk89q.worldedit.internal.annotation.RequiresNewerGuava;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
@@ -36,8 +36,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+
+import static com.google.common.base.Preconditions.checkNotNull;
/**
* Dispatches events to listeners, and provides ways for listeners to register
@@ -53,7 +53,7 @@ import java.util.logging.Logger;
*/
public class EventBus {
- private final Logger logger = Logger.getLogger(EventBus.class.getCanonicalName());
+ private final Logger logger = LoggerFactory.getLogger(EventBus.class);
private final SetMultimap, EventHandler> handlersByType =
Multimaps.newSetMultimap(new HashMap<>(), this::newHandlerSet);
@@ -186,8 +186,7 @@ public class EventBus {
try {
handler.handleEvent(event);
} catch (InvocationTargetException e) {
- logger.log(Level.SEVERE,
- "Could not dispatch event: " + event + " to handler " + handler, e);
+ logger.error("Could not dispatch event: " + event + " to handler " + handler, e);
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/io/Closer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/io/Closer.java
index 26ef6a0f9..1b7aceda3 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/io/Closer.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/io/Closer.java
@@ -19,23 +19,23 @@
package com.sk89q.worldedit.util.io;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Throwables;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayDeque;
import java.util.Deque;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import java.util.zip.ZipFile;
+import static com.google.common.base.Preconditions.checkNotNull;
+
public final class Closer implements Closeable {
- private static final Logger logger = Logger.getLogger(Closer.class.getCanonicalName());
+ private static final Logger logger = LoggerFactory.getLogger(Closer.class);
/**
* The suppressor implementation to use for the current Java version.
@@ -218,7 +218,7 @@ public final class Closer implements Closeable {
@Override
public void suppress(Object closeable, Throwable thrown, Throwable suppressed) {
// log to the same place as Closeables
- logger.log(Level.WARNING, "Suppressing exception thrown when closing " + closeable, suppressed);
+ logger.warn("Suppressing exception thrown when closing " + closeable, suppressed);
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/ActorCallbackPaste.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/ActorCallbackPaste.java
index e87e440bf..e95a45bf9 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/ActorCallbackPaste.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/ActorCallbackPaste.java
@@ -26,14 +26,14 @@ import com.sk89q.worldedit.command.util.AsyncCommandHelper;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.command.parametric.ExceptionConverter;
import com.sk89q.worldedit.util.task.Supervisor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.net.URL;
-import java.util.logging.Level;
-import java.util.logging.Logger;
public class ActorCallbackPaste {
- private static final Logger LOGGER = Logger.getLogger(ActorCallbackPaste.class.getSimpleName());
+ private static final Logger LOGGER = LoggerFactory.getLogger(ActorCallbackPaste.class);
private ActorCallbackPaste() {
}
@@ -47,7 +47,7 @@ public class ActorCallbackPaste {
* @param content The content
* @param successMessage The message, formatted with {@link String#format(String, Object...)} on success
*/
-public static void pastebin(Supervisor supervisor, final Actor sender, String content, final String successMessage, final ExceptionConverter exceptionConverter) {
+ public static void pastebin(Supervisor supervisor, final Actor sender, String content, final String successMessage, final ExceptionConverter exceptionConverter) {
ListenableFuture future = new IncendoPaste("fastasyncworldedit").paste(content);
AsyncCommandHelper.wrap(future, supervisor, sender, exceptionConverter)
@@ -62,7 +62,7 @@ public static void pastebin(Supervisor supervisor, final Actor sender, String co
@Override
public void onFailure(Throwable throwable) {
- LOGGER.log(Level.WARNING, "Failed to submit pastebin", throwable);
+ LOGGER.warn("Failed to submit pastebin", throwable);
sender.printError("Failed to submit to a pastebin. Please see console for the error.");
}
});
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/report/ShallowObjectReport.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/report/ShallowObjectReport.java
index bb4abb1f3..18085bc0b 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/report/ShallowObjectReport.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/report/ShallowObjectReport.java
@@ -19,16 +19,17 @@
package com.sk89q.worldedit.util.report;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import static com.google.common.base.Preconditions.checkNotNull;
public class ShallowObjectReport extends DataReport {
- private static final Logger log = Logger.getLogger(ShallowObjectReport.class.getCanonicalName());
+ private static final Logger log = LoggerFactory.getLogger(ShallowObjectReport.class);
public ShallowObjectReport(String title, Object object) {
super(title);
@@ -52,7 +53,7 @@ public class ShallowObjectReport extends DataReport {
Object value = field.get(object);
append(field.getName(), String.valueOf(value));
} catch (IllegalAccessException e) {
- log.log(Level.WARNING, "Failed to get value of '" + field.getName() + "' on " + type);
+ log.warn("Failed to get value of '" + field.getName() + "' on " + type);
}
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/task/progress/ProgressIterator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/task/progress/ProgressIterator.java
index 447838922..11eb34f32 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/task/progress/ProgressIterator.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/task/progress/ProgressIterator.java
@@ -83,7 +83,7 @@ public class ProgressIterator implements Iterator, ProgressObservable {
* @return an instance
*/
public static ProgressIterator create(Iterator iterator, int count) {
- return new ProgressIterator<>(iterator, count);
+ return new ProgressIterator(iterator, count);
}
/**
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java
index 80aaa726b..cc5b4be68 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java
@@ -93,7 +93,7 @@ public abstract class AbstractWorld implements World {
@Override
public BlockState getLazyBlock(BlockVector3 position) {
- return new BaseBlock(getBlock(position)).toImmutableState();
+ return getBlock(position);
}
@Override
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java
index f21e1660f..fa27b3d17 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java
@@ -33,11 +33,14 @@ import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
-import com.sk89q.worldedit.world.biome.BaseBiome;
+import com.sk89q.worldedit.world.biome.BiomeType;
+import com.sk89q.worldedit.world.biome.BiomeTypes;
+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.BlockTypes;
import com.sk89q.worldedit.world.weather.WeatherType;
+import com.sk89q.worldedit.world.weather.WeatherTypes;
import javax.annotation.Nullable;
import java.util.Collections;
@@ -80,12 +83,12 @@ public class NullWorld extends AbstractWorld {
}
@Override
- public BaseBiome getBiome(BlockVector2 position) {
- return null;
+ public BiomeType getBiome(BlockVector2 position) {
+ return BiomeTypes.THE_VOID;
}
@Override
- public boolean setBiome(BlockVector2 position, BaseBiome biome) {
+ public boolean setBiome(BlockVector2 position, BiomeType biome) {
return false;
}
@@ -109,7 +112,7 @@ public class NullWorld extends AbstractWorld {
@Override
public WeatherType getWeather() {
- return null;
+ return WeatherTypes.CLEAR;
}
@Override
@@ -136,7 +139,6 @@ public class NullWorld extends AbstractWorld {
}
@Override
-//<<<<<<< HEAD
public BlockState getLazyBlock(BlockVector3 position) {
return getBlock(position);
}
@@ -145,10 +147,6 @@ public class NullWorld extends AbstractWorld {
public BaseBlock getFullBlock(BlockVector3 position) {
return getBlock(position).toBaseBlock();
}
-//=======
-// public BaseBlock getFullBlock(BlockVector3 position) {
-// return getBlock(position).toBaseBlock();
-//>>>>>>> 399e0ad5... Refactor vector system to be cleaner }
@Override
public List getEntities(Region region) {
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BaseBiome.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BaseBiome.java
deleted file mode 100644
index 5bf051706..000000000
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BaseBiome.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.world.biome;
-
-import com.sk89q.minecraft.util.commands.Link;
-import com.sk89q.worldedit.command.BiomeCommands;
-
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Basic storage object to represent a given biome.
- */
-@Link(clazz = BiomeCommands.class, value = "biomelist")
-public class BaseBiome {
-
- private int id;
-
- /**
- * Create a new biome with the given biome ID.
- *
- * @param id the biome ID
- */
- public BaseBiome(int id) {
- this.id = id;
- }
-
- /**
- * Create a clone of the given biome.
- *
- * @param biome the biome to clone
- */
- public BaseBiome(BaseBiome biome) {
- checkNotNull(biome);
- this.id = biome.getId();
- }
-
- /**
- * Get the biome ID.
- *
- * @return the biome ID
- */
- public int getId() {
- return id;
- }
-
- /**
- * Set the biome id.
- *
- * @param id the biome ID
- */
- public void setId(int id) {
- this.id = id;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- BaseBiome baseBiome = (BaseBiome) o;
-
- return id == baseBiome.id;
- }
-
- @Override
- public int hashCode() {
- return id;
- }
-}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeName.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeName.java
index 45018ed41..83c3faa58 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeName.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeName.java
@@ -29,7 +29,7 @@ import javax.annotation.Nullable;
/**
* Returns the name of a biome using a given {@code BiomeRegistry}.
*/
-class BiomeName implements Function {
+class BiomeName implements Function {
private final BiomeRegistry registry;
@@ -45,7 +45,7 @@ class BiomeName implements Function {
@Nullable
@Override
- public String apply(BaseBiome input) {
+ public String apply(BiomeType input) {
BiomeData data = registry.getData(input);
if (data != null) {
return data.getName();
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/logging/WorldEditPrefixHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java
similarity index 52%
rename from worldedit-core/src/main/java/com/sk89q/worldedit/util/logging/WorldEditPrefixHandler.java
rename to worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java
index f2c8a0754..7dc155253 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/logging/WorldEditPrefixHandler.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java
@@ -17,43 +17,44 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.util.logging;
+package com.sk89q.worldedit.world.biome;
-import java.util.logging.Handler;
-import java.util.logging.LogRecord;
-import java.util.logging.Logger;
+import com.sk89q.worldedit.registry.NamespacedRegistry;
/**
- * Adds a WorldEdit prefix to WorldEdit's logger messages using a handler.
+ * All the types of biomes in the game.
*/
-public final class WorldEditPrefixHandler extends Handler {
+public class BiomeType {
- private WorldEditPrefixHandler() {
- }
+ public static final NamespacedRegistry REGISTRY = new NamespacedRegistry<>("biome type");
- @Override
- public void publish(LogRecord record) {
- String message = record.getMessage();
- if (!message.startsWith("WorldEdit: ") && !message.startsWith("[WorldEdit] ")) {
- record.setMessage("[WorldEdit] " + message);
- }
- }
+ private String id;
- @Override
- public void flush() {
- }
-
- @Override
- public void close() throws SecurityException {
+ public BiomeType(String id) {
+ this.id = id;
}
/**
- * Add the handler to the following logger name.
+ * Gets the ID of this biome.
*
- * @param name the logger name
+ * @return The id
*/
- public static void register(String name) {
- Logger.getLogger(name).addHandler(new WorldEditPrefixHandler());
+ public String getId() {
+ return this.id;
}
+ @Override
+ public String toString() {
+ return getId();
+ }
+
+ @Override
+ public int hashCode() {
+ return this.id.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof BiomeType && this.id.equals(((BiomeType) obj).id);
+ }
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java
new file mode 100644
index 000000000..a9d07a5fc
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java
@@ -0,0 +1,117 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.world.biome;
+
+import javax.annotation.Nullable;
+
+/**
+ * Stores a list of common Biome String IDs.
+ */
+public class BiomeTypes {
+
+ @Nullable public static final BiomeType BADLANDS = get("minecraft:badlands");
+ @Nullable public static final BiomeType BADLANDS_PLATEAU = get("minecraft:badlands_plateau");
+ @Nullable public static final BiomeType BEACH = get("minecraft:beach");
+ @Nullable public static final BiomeType BIRCH_FOREST = get("minecraft:birch_forest");
+ @Nullable public static final BiomeType BIRCH_FOREST_HILLS = get("minecraft:birch_forest_hills");
+ @Nullable public static final BiomeType COLD_OCEAN = get("minecraft:cold_ocean");
+ @Nullable public static final BiomeType DARK_FOREST = get("minecraft:dark_forest");
+ @Nullable public static final BiomeType DARK_FOREST_HILLS = get("minecraft:dark_forest_hills");
+ @Nullable public static final BiomeType DEEP_COLD_OCEAN = get("minecraft:deep_cold_ocean");
+ @Nullable public static final BiomeType DEEP_FROZEN_OCEAN = get("minecraft:deep_frozen_ocean");
+ @Nullable public static final BiomeType DEEP_LUKEWARM_OCEAN = get("minecraft:deep_lukewarm_ocean");
+ @Nullable public static final BiomeType DEEP_OCEAN = get("minecraft:deep_ocean");
+ @Nullable public static final BiomeType DEEP_WARM_OCEAN = get("minecraft:deep_warm_ocean");
+ @Nullable public static final BiomeType DESERT = get("minecraft:desert");
+ @Nullable public static final BiomeType DESERT_HILLS = get("minecraft:desert_hills");
+ @Nullable public static final BiomeType DESERT_LAKES = get("minecraft:desert_lakes");
+ @Nullable public static final BiomeType END_BARRENS = get("minecraft:end_barrens");
+ @Nullable public static final BiomeType END_HIGHLANDS = get("minecraft:end_highlands");
+ @Nullable public static final BiomeType END_MIDLANDS = get("minecraft:end_midlands");
+ @Nullable public static final BiomeType ERODED_BADLANDS = get("minecraft:eroded_badlands");
+ @Nullable public static final BiomeType FLOWER_FOREST = get("minecraft:flower_forest");
+ @Nullable public static final BiomeType FOREST = get("minecraft:forest");
+ @Nullable public static final BiomeType FROZEN_OCEAN = get("minecraft:frozen_ocean");
+ @Nullable public static final BiomeType FROZEN_RIVER = get("minecraft:frozen_river");
+ @Nullable public static final BiomeType GIANT_SPRUCE_TAIGA = get("minecraft:giant_spruce_taiga");
+ @Nullable public static final BiomeType GIANT_SPRUCE_TAIGA_HILLS = get("minecraft:giant_spruce_taiga_hills");
+ @Nullable public static final BiomeType GIANT_TREE_TAIGA = get("minecraft:giant_tree_taiga");
+ @Nullable public static final BiomeType GIANT_TREE_TAIGA_HILLS = get("minecraft:giant_tree_taiga_hills");
+ @Nullable public static final BiomeType GRAVELLY_MOUNTAINS = get("minecraft:gravelly_mountains");
+ @Nullable public static final BiomeType ICE_SPIKES = get("minecraft:ice_spikes");
+ @Nullable public static final BiomeType JUNGLE = get("minecraft:jungle");
+ @Nullable public static final BiomeType JUNGLE_EDGE = get("minecraft:jungle_edge");
+ @Nullable public static final BiomeType JUNGLE_HILLS = get("minecraft:jungle_hills");
+ @Nullable public static final BiomeType LUKEWARM_OCEAN = get("minecraft:lukewarm_ocean");
+ @Nullable public static final BiomeType MODIFIED_BADLANDS_PLATEAU = get("minecraft:modified_badlands_plateau");
+ @Nullable public static final BiomeType MODIFIED_GRAVELLY_MOUNTAINS = get("minecraft:modified_gravelly_mountains");
+ @Nullable public static final BiomeType MODIFIED_JUNGLE = get("minecraft:modified_jungle");
+ @Nullable public static final BiomeType MODIFIED_JUNGLE_EDGE = get("minecraft:modified_jungle_edge");
+ @Nullable public static final BiomeType MODIFIED_WOODED_BADLANDS_PLATEAU = get("minecraft:modified_wooded_badlands_plateau");
+ @Nullable public static final BiomeType MOUNTAIN_EDGE = get("minecraft:mountain_edge");
+ @Nullable public static final BiomeType MOUNTAINS = get("minecraft:mountains");
+ @Nullable public static final BiomeType MUSHROOM_FIELD_SHORE = get("minecraft:mushroom_field_shore");
+ @Nullable public static final BiomeType MUSHROOM_FIELDS = get("minecraft:mushroom_fields");
+ @Nullable public static final BiomeType NETHER = get("minecraft:nether");
+ @Nullable public static final BiomeType OCEAN = get("minecraft:ocean");
+ @Nullable public static final BiomeType PLAINS = get("minecraft:plains");
+ @Nullable public static final BiomeType RIVER = get("minecraft:river");
+ @Nullable public static final BiomeType SAVANNA = get("minecraft:savanna");
+ @Nullable public static final BiomeType SAVANNA_PLATEAU = get("minecraft:savanna_plateau");
+ @Nullable public static final BiomeType SHATTERED_SAVANNA = get("minecraft:shattered_savanna");
+ @Nullable public static final BiomeType SHATTERED_SAVANNA_PLATEAU = get("minecraft:shattered_savanna_plateau");
+ @Nullable public static final BiomeType SMALL_END_ISLANDS = get("minecraft:small_end_islands");
+ @Nullable public static final BiomeType SNOWY_BEACH = get("minecraft:snowy_beach");
+ @Nullable public static final BiomeType SNOWY_MOUNTAINS = get("minecraft:snowy_mountains");
+ @Nullable public static final BiomeType SNOWY_TAIGA = get("minecraft:snowy_taiga");
+ @Nullable public static final BiomeType SNOWY_TAIGA_HILLS = get("minecraft:snowy_taiga_hills");
+ @Nullable public static final BiomeType SNOWY_TAIGA_MOUNTAINS = get("minecraft:snowy_taiga_mountains");
+ @Nullable public static final BiomeType SNOWY_TUNDRA = get("minecraft:snowy_tundra");
+ @Nullable public static final BiomeType STONE_SHORE = get("minecraft:stone_shore");
+ @Nullable public static final BiomeType SUNFLOWER_PLAINS = get("minecraft:sunflower_plains");
+ @Nullable public static final BiomeType SWAMP = get("minecraft:swamp");
+ @Nullable public static final BiomeType SWAMP_HILLS = get("minecraft:swamp_hills");
+ @Nullable public static final BiomeType TAIGA = get("minecraft:taiga");
+ @Nullable public static final BiomeType TAIGA_HILLS = get("minecraft:taiga_hills");
+ @Nullable public static final BiomeType TAIGA_MOUNTAINS = get("minecraft:taiga_mountains");
+ @Nullable public static final BiomeType TALL_BIRCH_FOREST = get("minecraft:tall_birch_forest");
+ @Nullable public static final BiomeType TALL_BIRCH_HILLS = get("minecraft:tall_birch_hills");
+ @Nullable public static final BiomeType THE_END = get("minecraft:the_end");
+ @Nullable public static final BiomeType THE_VOID = get("minecraft:the_void");
+ @Nullable public static final BiomeType WARM_OCEAN = get("minecraft:warm_ocean");
+ @Nullable public static final BiomeType WOODED_BADLANDS_PLATEAU = get("minecraft:wooded_badlands_plateau");
+ @Nullable public static final BiomeType WOODED_HILLS = get("minecraft:wooded_hills");
+ @Nullable public static final BiomeType WOODED_MOUNTAINS = get("minecraft:wooded_mountains");
+
+ private BiomeTypes() {
+ }
+
+ private static BiomeType register(final String id) {
+ return register(new BiomeType(id));
+ }
+
+ public static BiomeType register(final BiomeType biome) {
+ return BiomeType.REGISTRY.register(biome.getId(), biome);
+ }
+
+ public static @Nullable BiomeType get(final String id) {
+ return BiomeType.REGISTRY.get(id);
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/Biomes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/Biomes.java
index 0282227db..8c73ddf01 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/Biomes.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/Biomes.java
@@ -50,17 +50,17 @@ public final class Biomes {
* @return a biome or null
*/
@Nullable
- public static BaseBiome findBiomeByName(Collection biomes, String name, BiomeRegistry registry) {
+ public static BiomeType findBiomeByName(Collection biomes, String name, BiomeRegistry registry) {
checkNotNull(biomes);
checkNotNull(name);
checkNotNull(registry);
Function compare = new LevenshteinDistance(name, false, LevenshteinDistance.STANDARD_CHARS);
- WeightedChoice chooser = new WeightedChoice<>(Functions.compose(compare::apply, new BiomeName(registry)), 0);
- for (BaseBiome biome : biomes) {
+ WeightedChoice chooser = new WeightedChoice<>(Functions.compose(compare::apply, new BiomeName(registry)), 0);
+ for (BiomeType biome : biomes) {
chooser.consider(biome);
}
- Optional> choice = chooser.getChoice();
+ Optional> choice = chooser.getChoice();
if (choice.isPresent() && choice.get().getScore() <= 1) {
return choice.get().getValue();
} else {
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java
index 31b424422..61caf1561 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java
@@ -223,11 +223,7 @@ public class BaseBlock implements BlockStateHolder, TileEntityBlock {
@Override
public int hashCode() {
- int ret = toImmutableState().hashCode() << 3;
- if (hasNbtData()) {
- ret += getNbtData().hashCode();
- }
- return ret;
+ return getOrdinal();
}
@Override
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockCategories.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockCategories.java
index d60c96985..28c3385d5 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockCategories.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockCategories.java
@@ -19,58 +19,52 @@
package com.sk89q.worldedit.world.block;
-import javax.annotation.Nullable;
-
/**
* Stores a list of categories of Block Types.
*/
public final class BlockCategories {
- public static final BlockCategory ACACIA_LOGS = register("minecraft:acacia_logs");
- public static final BlockCategory ANVIL = register("minecraft:anvil");
- public static final BlockCategory BANNERS = register("minecraft:banners");
- public static final BlockCategory BIRCH_LOGS = register("minecraft:birch_logs");
- public static final BlockCategory BUTTONS = register("minecraft:buttons");
- public static final BlockCategory CARPETS = register("minecraft:carpets");
- public static final BlockCategory CORAL = register("minecraft:coral");
- public static final BlockCategory CORAL_PLANTS = register("minecraft:coral_plants");
- public static final BlockCategory DARK_OAK_LOGS = register("minecraft:dark_oak_logs");
- public static final BlockCategory DOORS = register("minecraft:doors");
- public static final BlockCategory ENDERMAN_HOLDABLE = register("minecraft:enderman_holdable");
- public static final BlockCategory FLOWER_POTS = register("minecraft:flower_pots");
- public static final BlockCategory ICE = register("minecraft:ice");
- public static final BlockCategory JUNGLE_LOGS = register("minecraft:jungle_logs");
- public static final BlockCategory LEAVES = register("minecraft:leaves");
- public static final BlockCategory LOGS = register("minecraft:logs");
- public static final BlockCategory OAK_LOGS = register("minecraft:oak_logs");
- public static final BlockCategory PLANKS = register("minecraft:planks");
- public static final BlockCategory RAILS = register("minecraft:rails");
- public static final BlockCategory SAND = register("minecraft:sand");
- public static final BlockCategory SAPLINGS = register("minecraft:saplings");
- public static final BlockCategory SLABS = register("minecraft:slabs");
- public static final BlockCategory SPRUCE_LOGS = register("minecraft:spruce_logs");
- public static final BlockCategory STAIRS = register("minecraft:stairs");
- public static final BlockCategory STONE_BRICKS = register("minecraft:stone_bricks");
- public static final BlockCategory VALID_SPAWN = register("minecraft:valid_spawn");
- public static final BlockCategory WOODEN_BUTTONS = register("minecraft:wooden_buttons");
- public static final BlockCategory WOODEN_DOORS = register("minecraft:wooden_doors");
- public static final BlockCategory WOODEN_PRESSURE_PLATES = register("minecraft:wooden_pressure_plates");
- public static final BlockCategory WOODEN_SLABS = register("minecraft:wooden_slabs");
- public static final BlockCategory WOODEN_STAIRS = register("minecraft:wooden_stairs");
- public static final BlockCategory WOOL = register("minecraft:wool");
+ public static final BlockCategory ACACIA_LOGS = get("minecraft:acacia_logs");
+ public static final BlockCategory ANVIL = get("minecraft:anvil");
+ public static final BlockCategory BANNERS = get("minecraft:banners");
+ public static final BlockCategory BIRCH_LOGS = get("minecraft:birch_logs");
+ public static final BlockCategory BUTTONS = get("minecraft:buttons");
+ public static final BlockCategory CARPETS = get("minecraft:carpets");
+ public static final BlockCategory CORALS = get("minecraft:corals");
+ public static final BlockCategory CORAL_BLOCKS = get("minecraft:coral_blocks");
+ public static final BlockCategory DARK_OAK_LOGS = get("minecraft:dark_oak_logs");
+ public static final BlockCategory DOORS = get("minecraft:doors");
+ public static final BlockCategory ENDERMAN_HOLDABLE = get("minecraft:enderman_holdable");
+ public static final BlockCategory FLOWER_POTS = get("minecraft:flower_pots");
+ public static final BlockCategory ICE = get("minecraft:ice");
+ public static final BlockCategory JUNGLE_LOGS = get("minecraft:jungle_logs");
+ public static final BlockCategory LEAVES = get("minecraft:leaves");
+ public static final BlockCategory LOGS = get("minecraft:logs");
+ public static final BlockCategory OAK_LOGS = get("minecraft:oak_logs");
+ public static final BlockCategory PLANKS = get("minecraft:planks");
+ public static final BlockCategory RAILS = get("minecraft:rails");
+ public static final BlockCategory SAND = get("minecraft:sand");
+ public static final BlockCategory SAPLINGS = get("minecraft:saplings");
+ public static final BlockCategory SLABS = get("minecraft:slabs");
+ public static final BlockCategory SPRUCE_LOGS = get("minecraft:spruce_logs");
+ public static final BlockCategory STAIRS = get("minecraft:stairs");
+ public static final BlockCategory STONE_BRICKS = get("minecraft:stone_bricks");
+ public static final BlockCategory VALID_SPAWN = get("minecraft:valid_spawn");
+ public static final BlockCategory WOODEN_BUTTONS = get("minecraft:wooden_buttons");
+ public static final BlockCategory WOODEN_DOORS = get("minecraft:wooden_doors");
+ public static final BlockCategory WOODEN_PRESSURE_PLATES = get("minecraft:wooden_pressure_plates");
+ public static final BlockCategory WOODEN_SLABS = get("minecraft:wooden_slabs");
+ public static final BlockCategory WOODEN_STAIRS = get("minecraft:wooden_stairs");
+ public static final BlockCategory WOOL = get("minecraft:wool");
private BlockCategories() {
}
- private static BlockCategory register(final String id) {
- return register(new BlockCategory(id));
- }
-
- public static BlockCategory register(final BlockCategory tag) {
- return BlockCategory.REGISTRY.register(tag.getId(), tag);
- }
-
- public static @Nullable BlockCategory get(final String id) {
- return BlockCategory.REGISTRY.get(id);
+ private static BlockCategory get(final String id) {
+ BlockCategory blockCategory = BlockCategory.REGISTRY.get(id);
+ if (blockCategory == null) {
+ return new BlockCategory(id);
+ }
+ return blockCategory;
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java
index f007ad5db..a0dc34982 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java
@@ -22,8 +22,11 @@ package com.sk89q.worldedit.world.block;
import com.boydti.fawe.command.SuggestInputParseException;
import com.boydti.fawe.object.string.MutableCharSequence;
import com.google.common.base.Function;
+import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import com.google.common.collect.Table;
import com.sk89q.jnbt.CompoundTag;
+import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extent.Extent;
@@ -314,15 +317,10 @@ public class BlockState implements BlockStateHolder {
return this.blockType;
}
- @Override
- public int hashCode() {
- return getOrdinal();
- }
-
@Override
public boolean equalsFuzzy(BlockStateHolder> o) {
if (this == o) {
- // Added a reference equality check for
+ // Added a reference equality check for speediness
return true;
}
if (!getBlockType().equals(o.getBlockType())) {
@@ -359,8 +357,8 @@ public class BlockState implements BlockStateHolder {
}
@Override
- public String toString() {
- return getAsString();
+ public BaseBlock toBaseBlock() {
+ return this.emptyBaseBlock;
}
@Override
@@ -375,9 +373,27 @@ public class BlockState implements BlockStateHolder