Merge remote-tracking branch 'upstream/master' into breaking

This commit is contained in:
Jesse Boyd 2019-04-03 16:53:34 +11:00
commit f361619037
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
281 changed files with 5963 additions and 5444 deletions

View File

@ -8,20 +8,19 @@ buildscript {
configurations.all { configurations.all {
resolutionStrategy { resolutionStrategy {
force 'com.google.guava:guava:21.0' force 'commons-io:commons-io:2.4'
force 'org.ow2.asm:asm:6.0_BETA'
} }
} }
dependencies { dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.4' classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.4'
classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.7.5' classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.8.1'
classpath 'org.ajoberstar:gradle-git:1.7.2'
} }
} }
plugins { plugins {
id 'net.minecrell.licenser' version '0.4.1' apply false id 'net.minecrell.licenser' version '0.4.1' apply false
id "org.ajoberstar.grgit" version "2.3.0"
} }
apply plugin: 'java' apply plugin: 'java'

View File

@ -5,8 +5,9 @@
<module name="Checker"> <module name="Checker">
<!-- Tabs are strictly banned --> <!-- Tabs are strictly banned -->
<module name="FileTabCharacter"/> <module name="FileTabCharacter"/>
<module name="SuppressWarningsFilter" />
<module name="TreeWalker"> <module name="TreeWalker">
<module name="SuppressWarningsHolder" /> <!-- allows for @SuppressWarnings annotation -->
<!-- Important basics --> <!-- Important basics -->
<!-- <module name="PackageDeclaration"/> Unlikely that we would miss this in a PR --> <!-- <module name="PackageDeclaration"/> Unlikely that we would miss this in a PR -->
<module name="OuterTypeFilename"/> <!-- TypeName -> TypeName.java --> <module name="OuterTypeFilename"/> <!-- TypeName -> TypeName.java -->

View File

@ -15,6 +15,7 @@
<allow pkg="com.google.gson"/> <allow pkg="com.google.gson"/>
<allow pkg="net.royawesome.jlibnoise"/> <allow pkg="net.royawesome.jlibnoise"/>
<allow pkg="org.json.simple" /> <allow pkg="org.json.simple" />
<allow pkg="org.slf4j"/>
<subpackage name="util.yaml"> <subpackage name="util.yaml">
<allow pkg="org.yaml.snakeyaml"/> <allow pkg="org.yaml.snakeyaml"/>
@ -53,6 +54,7 @@
<allow pkg="org.lwjgl"/> <allow pkg="org.lwjgl"/>
<allow pkg="io.netty.buffer"/> <allow pkg="io.netty.buffer"/>
<allow pkg="org.spongepowered.api" /> <allow pkg="org.spongepowered.api" />
<allow pkg="com.mojang.brigadier" />
</subpackage> </subpackage>
<subpackage name="sponge"> <subpackage name="sponge">

4
gradle.properties Normal file
View File

@ -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

Binary file not shown.

View File

@ -1,6 +1,6 @@
#Mon Mar 25 18:59:14 EDT 2019 #Mon Mar 25 18:59:14 EDT 2019
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip

View File

@ -4,14 +4,17 @@ apply plugin: 'maven'
repositories { repositories {
maven { url "https://hub.spigotmc.org/nexus/content/groups/public" } 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 { dependencies {
compile project(':worldedit-core') compile project(':worldedit-core')
compile 'net.milkbowl.vault:VaultAPI:1.7' compile 'net.milkbowl.vault:VaultAPI:1.7'
compile 'com.sk89q:dummypermscompat:1.10' compile 'com.sk89q:dummypermscompat:1.10'
compile 'com.destroystokyo.paper:paper-api:1.13.2-R0.1-SNAPSHOT' 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' testCompile 'org.mockito:mockito-core:1.9.0-rc1'
compile 'com.massivecraft:factions:2.8.0' compile 'com.massivecraft:factions:2.8.0'
compile 'com.drtshock:factions:1.6.9.5' compile 'com.drtshock:factions:1.6.9.5'
@ -77,7 +80,10 @@ task copyFiles {
shadowJar { shadowJar {
dependencies { dependencies {
relocate "org.slf4j", "com.sk89q.worldedit.slf4j"
include(dependency(':worldedit-core')) 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" archiveName = "${parent.name}-${project.name.replaceAll("worldedit-", "")}-${parent.version}.jar"
destinationDir = file '../target' destinationDir = file '../target'

View File

@ -22,6 +22,8 @@ package com.sk89q.wepif;
import com.sk89q.util.yaml.YAMLProcessor; import com.sk89q.util.yaml.YAMLProcessor;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.Server; import org.bukkit.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
@ -32,12 +34,10 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
public class FlatFilePermissionsResolver implements PermissionsResolver { 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<String, Set<String>> userPermissionsCache; private Map<String, Set<String>> userPermissionsCache;
private Set<String> defaultPermissionsCache; private Set<String> defaultPermissionsCache;
@ -98,7 +98,7 @@ public class FlatFilePermissionsResolver implements PermissionsResolver {
} }
} }
} catch (IOException e) { } catch (IOException e) {
log.log(Level.WARNING, "Failed to load permissions", e); log.warn("Failed to load permissions", e);
} finally { } finally {
try { try {
if (buff != null) { if (buff != null) {
@ -164,7 +164,7 @@ public class FlatFilePermissionsResolver implements PermissionsResolver {
} }
} }
} catch (IOException e) { } catch (IOException e) {
log.log(Level.WARNING, "Failed to load permissions", e); log.warn("Failed to load permissions", e);
} finally { } finally {
try { try {
if (buff != null) { if (buff != null) {

View File

@ -28,13 +28,12 @@ import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.slf4j.Logger;
import java.util.logging.Level; import org.slf4j.LoggerFactory;
import java.util.logging.Logger;
public class NijiPermissionsResolver implements PermissionsResolver { 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 Server server;
private Permissions api; private Permissions api;
@ -84,7 +83,7 @@ public class NijiPermissionsResolver implements PermissionsResolver {
return api.Security.permission(player, permission); return api.Security.permission(player, permission);
} }
} catch (Throwable t) { } catch (Throwable t) {
log.log(Level.WARNING, "Failed to check permissions", t); log.warn("Failed to check permissions", t);
return false; return false;
} }
} }
@ -98,7 +97,7 @@ public class NijiPermissionsResolver implements PermissionsResolver {
return api.getHandler().has(server.getPlayerExact(name), permission); return api.getHandler().has(server.getPlayerExact(name), permission);
} }
} catch (Throwable t) { } catch (Throwable t) {
log.log(Level.WARNING, "Failed to check permissions", t); log.warn("Failed to check permissions", t);
return false; return false;
} }
} }
@ -115,7 +114,7 @@ public class NijiPermissionsResolver implements PermissionsResolver {
return api.Security.inGroup(name, group); return api.Security.inGroup(name, group);
} }
} catch (Throwable t) { } catch (Throwable t) {
log.log(Level.WARNING, "Failed to check groups", t); log.warn("Failed to check groups", t);
return false; return false;
} }
} }
@ -139,7 +138,7 @@ public class NijiPermissionsResolver implements PermissionsResolver {
return groups; return groups;
} }
} catch (Throwable t) { } catch (Throwable t) {
log.log(Level.WARNING, "Failed to get groups", t); log.warn("Failed to get groups", t);
return new String[0]; return new String[0];
} }
} }

View File

@ -27,6 +27,8 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent; import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -35,8 +37,6 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class PermissionsResolverManager implements PermissionsResolver { public class PermissionsResolverManager implements PermissionsResolver {
@ -85,7 +85,7 @@ public class PermissionsResolverManager implements PermissionsResolver {
private Server server; private Server server;
private PermissionsResolver permissionResolver; private PermissionsResolver permissionResolver;
private YAMLProcessor config; private YAMLProcessor config;
private Logger logger = Logger.getLogger(getClass().getCanonicalName()); private Logger logger = LoggerFactory.getLogger(getClass());
private List<Class<? extends PermissionsResolver>> enabledResolvers = new ArrayList<>(); private List<Class<? extends PermissionsResolver>> enabledResolvers = new ArrayList<>();
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -119,7 +119,7 @@ public class PermissionsResolverManager implements PermissionsResolver {
break; break;
} }
} catch (Throwable e) { } 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; continue;
} }
} }
@ -195,14 +195,14 @@ public class PermissionsResolverManager implements PermissionsResolver {
try { try {
file.createNewFile(); file.createNewFile();
} catch (IOException e) { } 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); config = new YAMLProcessor(file, false, YAMLFormat.EXTENDED);
try { try {
config.load(); config.load();
} catch (IOException e) { } catch (IOException e) {
logger.log(Level.WARNING, "Error loading WEPIF configuration", e); logger.warn("Error loading WEPIF configuration", e);
} }
List<String> keys = config.getKeys(null); List<String> keys = config.getKeys(null);
config.setHeader(CONFIG_HEADER); config.setHeader(CONFIG_HEADER);
@ -232,7 +232,7 @@ public class PermissionsResolverManager implements PermissionsResolver {
} catch (ClassNotFoundException e) {} } catch (ClassNotFoundException e) {}
if (next == null || !PermissionsResolver.class.isAssignableFrom(next)) { 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."); + nextName + ". Moving to disabled resolvers list.");
i.remove(); i.remove();
disabledResolvers.add(nextName); disabledResolvers.add(nextName);

View File

@ -35,6 +35,9 @@ public class VaultResolver implements PermissionsResolver {
return null; return null;
} }
RegisteredServiceProvider<Permission> rsp = server.getServicesManager().getRegistration(Permission.class); RegisteredServiceProvider<Permission> rsp = server.getServicesManager().getRegistration(Permission.class);
if (rsp == null) {
return null;
}
perms = rsp.getProvider(); perms = rsp.getProvider();
if (perms == null) { if (perms == null) {
return null; return null;

View File

@ -19,15 +19,25 @@
package com.sk89q.worldedit.bukkit; 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.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.IBukkitAdapter; import com.sk89q.worldedit.bukkit.adapter.IBukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.SimpleBukkitAdapter; import com.sk89q.worldedit.bukkit.adapter.SimpleBukkitAdapter;
import com.sk89q.worldedit.entity.Entity; 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.BlockVector3;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World; 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.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; 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 com.sk89q.worldedit.world.item.ItemType;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -122,6 +133,26 @@ public enum BukkitAdapter {
return getAdapter().adapt(gameMode); 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) { public static EntityType adapt(org.bukkit.entity.EntityType entityType) {
return getAdapter().adapt(entityType); return getAdapter().adapt(entityType);
} }
@ -146,6 +177,12 @@ public enum BukkitAdapter {
return getAdapter().adapt(material); return getAdapter().adapt(material);
} }
/**
* Create a Bukkit BlockData from a WorldEdit BlockStateHolder
*
* @param block The WorldEdit BlockStateHolder
* @return The Bukkit BlockData
*/
public static <B extends BlockStateHolder<B>> BlockData adapt(B block) { public static <B extends BlockStateHolder<B>> BlockData adapt(B block) {
return getAdapter().adapt(block); return getAdapter().adapt(block);
} }

View File

@ -19,16 +19,11 @@
package com.sk89q.worldedit.bukkit; 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.BiomeData;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.registry.BiomeRegistry; import com.sk89q.worldedit.world.registry.BiomeRegistry;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
/** /**
@ -41,35 +36,9 @@ class BukkitBiomeRegistry implements BiomeRegistry {
@Nullable @Nullable
@Override @Override
public BaseBiome createFromId(int id) { public BiomeData getData(BiomeType biome) {
return new BaseBiome(id); final Biome bukkitBiome = BukkitAdapter.adapt(biome);
} return bukkitBiome == null ? null : bukkitBiome::name;
@Override
public List<BaseBiome> getBiomes() {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
List<BaseBiome> 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;
}
} }
} }

View File

@ -49,4 +49,4 @@ public class BukkitBlockCategoryRegistry implements BlockCategoryRegistry {
public Set<BlockType> getAll(Category<BlockType> category) { public Set<BlockType> getAll(Category<BlockType> category) {
return getCategorisedByName(category.getId()); return getCategorisedByName(category.getId());
} }
} }

View File

@ -19,8 +19,6 @@
package com.sk89q.worldedit.bukkit; package com.sk89q.worldedit.bukkit;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.bukkit.util.CommandInspector; import com.sk89q.bukkit.util.CommandInspector;
import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.extension.platform.Actor; 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 com.sk89q.worldedit.util.command.Dispatcher;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; 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 { 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 WorldEditPlugin plugin;
private final Dispatcher dispatcher; private final Dispatcher dispatcher;
@ -51,7 +51,7 @@ class BukkitCommandInspector implements CommandInspector {
if (mapping != null) { if (mapping != null) {
return mapping.getDescription().getDescription(); return mapping.getDescription().getDescription();
} else { } 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"; return "Help text not available";
} }
} }
@ -63,7 +63,7 @@ class BukkitCommandInspector implements CommandInspector {
Description description = mapping.getDescription(); Description description = mapping.getDescription();
return "Usage: " + description.getUsage() + (description.getHelp() != null ? "\n" + description.getHelp() : ""); return "Usage: " + description.getUsage() + (description.getHelp() != null ? "\n" + description.getHelp() : "");
} else { } 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"; return "Help text not available";
} }
} }
@ -76,7 +76,7 @@ class BukkitCommandInspector implements CommandInspector {
locals.put(Actor.class, plugin.wrapCommandSender(sender)); locals.put(Actor.class, plugin.wrapCommandSender(sender));
return mapping.getCallable().testPermission(locals); return mapping.getCallable().testPermission(locals);
} else { } 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; return false;
} }
} }

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.bukkit;
import com.sk89q.util.yaml.YAMLProcessor; import com.sk89q.util.yaml.YAMLProcessor;
import com.sk89q.worldedit.util.YAMLConfiguration; import com.sk89q.worldedit.util.YAMLConfiguration;
import com.sk89q.worldedit.util.report.Unreported; import com.sk89q.worldedit.util.report.Unreported;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
@ -34,7 +35,7 @@ public class BukkitConfiguration extends YAMLConfiguration {
@Unreported private final WorldEditPlugin plugin; @Unreported private final WorldEditPlugin plugin;
public BukkitConfiguration(YAMLProcessor config, WorldEditPlugin plugin) { public BukkitConfiguration(YAMLProcessor config, WorldEditPlugin plugin) {
super(config, plugin.getLogger()); super(config, LoggerFactory.getLogger(plugin.getLogger().getName()));
this.plugin = plugin; this.plugin = plugin;
} }

View File

@ -1,91 +0,0 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@ -49,4 +49,4 @@ public class BukkitItemCategoryRegistry implements ItemCategoryRegistry {
public Set<ItemType> getAll(Category<ItemType> category) { public Set<ItemType> getAll(Category<ItemType> category) {
return getCategorisedByName(category.getId()); return getCategorisedByName(category.getId());
} }
} }

View File

@ -61,6 +61,10 @@ public class BukkitPlayer extends AbstractPlayerActor {
private Player player; private Player player;
private WorldEditPlugin plugin; private WorldEditPlugin plugin;
public BukkitPlayer(Player player) {
this(WorldEditPlugin.getInstance(), player);
}
public BukkitPlayer(WorldEditPlugin plugin, Player player) { public BukkitPlayer(WorldEditPlugin plugin, Player player) {
this.plugin = plugin; this.plugin = plugin;
this.player = player; this.player = player;

View File

@ -19,7 +19,11 @@
package com.sk89q.worldedit.bukkit; 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. * World data for the Bukkit platform.
@ -44,11 +48,6 @@ class BukkitRegistries extends BundledRegistries {
public BlockRegistry getBlockRegistry() { public BlockRegistry getBlockRegistry() {
return blockRegistry; return blockRegistry;
} }
@Override
public BlockCategoryRegistry getBlockCategoryRegistry() {
return blockCategoryRegistry;
}
@Override @Override
public BiomeRegistry getBiomeRegistry() { public BiomeRegistry getBiomeRegistry() {
@ -59,6 +58,11 @@ class BukkitRegistries extends BundledRegistries {
public ItemRegistry getItemRegistry() { public ItemRegistry getItemRegistry() {
return itemRegistry; return itemRegistry;
} }
@Override
public BlockCategoryRegistry getBlockCategoryRegistry() {
return blockCategoryRegistry;
}
@Override @Override
public ItemCategoryRegistry getItemCategoryRegistry() { public ItemCategoryRegistry getItemCategoryRegistry() {

View File

@ -18,7 +18,6 @@
package com.sk89q.worldedit.bukkit; package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException; 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.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator; import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.world.AbstractWorld; 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.block.BlockStateHolder;
import com.sk89q.worldedit.world.weather.WeatherType; import com.sk89q.worldedit.world.weather.WeatherType;
import com.sk89q.worldedit.world.weather.WeatherTypes; 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.Effect;
import org.bukkit.TreeType; import org.bukkit.TreeType;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.block.Chest; import org.bukkit.block.Chest;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.inventory.DoubleChestInventory; import org.bukkit.inventory.DoubleChestInventory;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.slf4j.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
@ -56,8 +56,6 @@ import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
public class BukkitWorld extends AbstractWorld { public class BukkitWorld extends AbstractWorld {
@ -118,9 +116,9 @@ public class BukkitWorld extends AbstractWorld {
return null; return null;
} }
} catch (Exception e) { } 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) { if (entity.getNbtData() != null) {
logger.warning(entity.getNbtData().toString()); logger.warn(entity.getNbtData().toString());
} }
e.printStackTrace(); e.printStackTrace();
return null; return null;
@ -183,7 +181,7 @@ public class BukkitWorld extends AbstractWorld {
try { try {
getWorld().regenerateChunk(chunk.getBlockX(), chunk.getBlockZ()); getWorld().regenerateChunk(chunk.getBlockX(), chunk.getBlockZ());
} catch (Throwable t) { } 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 // Then restore
@ -280,7 +278,7 @@ public class BukkitWorld extends AbstractWorld {
treeTypeMapping.put(TreeGenerator.TreeType.RANDOM_MUSHROOM, TreeType.BROWN_MUSHROOM); treeTypeMapping.put(TreeGenerator.TreeType.RANDOM_MUSHROOM, TreeType.BROWN_MUSHROOM);
for (TreeGenerator.TreeType type : TreeGenerator.TreeType.values()) { for (TreeGenerator.TreeType type : TreeGenerator.TreeType.values()) {
if (treeTypeMapping.get(type) == null) { if (treeTypeMapping.get(type) == null) {
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 { try {
return adapter.setBlock(BukkitAdapter.adapt(getWorld(), position), block, notifyAndLight); return adapter.setBlock(BukkitAdapter.adapt(getWorld(), position), block, notifyAndLight);
} catch (Exception e) { } catch (Exception e) {
if (block instanceof BaseBlock && ((BaseBlock)block).getNbtData() != null) { if (block instanceof BaseBlock && ((BaseBlock) block).getNbtData() != null) {
logger.warning("Tried to set a corrupt tile entity at " + position.toString()); logger.warn("Tried to set a corrupt tile entity at " + position.toString());
logger.warning(((BaseBlock)block).getNbtData().toString()); logger.warn(((BaseBlock) block).getNbtData().toString());
} }
e.printStackTrace(); e.printStackTrace();
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()); Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
@ -468,25 +466,13 @@ public class BukkitWorld extends AbstractWorld {
} }
@Override @Override
public BaseBiome getBiome(BlockVector2 position) { public BiomeType getBiome(BlockVector2 position) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); return BukkitAdapter.adapt(getWorld().getBiome(position.getBlockX(), position.getBlockZ()));
if (adapter != null) {
int id = adapter.getBiomeId(getWorld().getBiome(position.getBlockX(), position.getBlockZ()));
return new BaseBiome(id);
} else {
return new BaseBiome(0);
}
} }
@Override @Override
public boolean setBiome(BlockVector2 position, BaseBiome biome) { public boolean setBiome(BlockVector2 position, BiomeType biome) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); getWorld().setBiome(position.getBlockX(), position.getBlockZ(), BukkitAdapter.adapt(biome));
if (adapter != null) { return true;
Biome bukkitBiome = adapter.getBiome(biome.getId());
getWorld().setBiome(position.getBlockX(), position.getBlockZ(), bukkitBiome);
return true;
} else {
return false;
}
} }
} }

View File

@ -19,6 +19,8 @@
package com.sk89q.worldedit.bukkit; 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.Fawe;
import com.boydti.fawe.bukkit.FaweBukkit; import com.boydti.fawe.bukkit.FaweBukkit;
import com.boydti.fawe.bukkit.adapter.v1_13_1.Spigot_v1_13_R2; 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.bukkit.adapter.BukkitImplLoader;
import com.sk89q.worldedit.event.platform.CommandEvent; import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.PlatformReadyEvent; 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.Actor;
import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.NoCapablePlatformException; import com.sk89q.worldedit.extension.platform.NoCapablePlatformException;
import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag; 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 com.sk89q.worldedit.world.registry.LegacyMapper;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Biome;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.*; import org.bukkit.plugin.*;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader; import org.bukkit.plugin.java.JavaPluginLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable; 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.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import static com.google.common.base.Preconditions.checkNotNull; 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 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"; public static final String CUI_PLUGIN_CHANNEL = "worldedit:cui";
private static WorldEditPlugin INSTANCE; private static WorldEditPlugin INSTANCE;
@ -139,13 +158,9 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
return CUI_PLUGIN_CHANNEL; return CUI_PLUGIN_CHANNEL;
} }
/**
* Called on plugin enable.
*/
@SuppressWarnings("AccessStaticViaInstance")
@Override @Override
public void onEnable() { public void onLoad() {
rename(); rename();
this.INSTANCE = this; this.INSTANCE = this;
FaweBukkit imp = new FaweBukkit(this); FaweBukkit imp = new FaweBukkit(this);
@ -163,6 +178,16 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
loadConfig(); // Load configuration loadConfig(); // Load configuration
fail(() -> PermissionsResolverManager.initialize(INSTANCE), "Failed to initialize permissions resolver"); 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 // Register CUI
fail(() -> { fail(() -> {
@ -178,9 +203,6 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
// platforms to be worried about... at the current time of writing // platforms to be worried about... at the current time of writing
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent()); WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
// Setup the BukkitImplementationTester.
BukkitImplementationTester.getImplementation();
{ // Register 1.13 Material ids with LegacyMapper { // Register 1.13 Material ids with LegacyMapper
LegacyMapper legacyMapper = LegacyMapper.getInstance(); LegacyMapper legacyMapper = LegacyMapper.getInstance();
for (Material m : Material.values()) { for (Material m : Material.values()) {
@ -191,6 +213,20 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
} }
} }
private void setupTags() {
// Tags
try {
for (Tag<Material> blockTag : Bukkit.getTags(Tag.REGISTRY_BLOCKS, Material.class)) {
BlockCategory.REGISTRY.register(blockTag.getKey().toString(), new BlockCategory(blockTag.getKey().toString()));
}
for (Tag<Material> 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() { private void rename() {
// { // {
// PluginDescriptionFile desc = getDescription(); // 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) { if (logger != null) {
try { try {
Field nameField = Logger.class.getDeclaredField("name"); Field nameField = Logger.class.getDeclaredField("name");
@ -245,7 +281,7 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
e.printStackTrace(); 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 { try {
run.run(); run.run();
} catch (Throwable e) { } catch (Throwable e) {
log.log(Level.SEVERE, message); log.error(message);
e.printStackTrace(); 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 = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "config-legacy.yml"), true), this);
config.load(); config.load();
} catch (Throwable e) { } catch (Throwable e) {
log.log(Level.SEVERE, "Failed to load config.yml"); log.error("Failed to load config.yml");
e.printStackTrace(); e.printStackTrace();
} }
// Create schematics folder // Create schematics folder
@ -287,30 +323,30 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
try { try {
adapterLoader.addFromPath(getClass().getClassLoader()); adapterLoader.addFromPath(getClass().getClassLoader());
} catch (IOException e) { } catch (IOException e) {
log.log(Level.WARNING, "Failed to search path for Bukkit adapters"); log.warn("Failed to search path for Bukkit adapters");
} }
try { try {
adapterLoader.addFromJar(getFile()); adapterLoader.addFromJar(getFile());
} catch (IOException e) { } 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 { try {
bukkitAdapter = adapterLoader.loadAdapter(); 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) { } catch (AdapterLoadException e) {
try { try {
Platform platform = worldEdit.getPlatformManager().queryCapability(Capability.WORLD_EDITING); Platform platform = worldEdit.getPlatformManager().queryCapability(Capability.WORLD_EDITING);
if (platform instanceof BukkitServerInterface) { if (platform instanceof BukkitServerInterface) {
log.log(Level.WARNING, e.getMessage()); log.warn(e.getMessage());
return; return;
} else { } 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() + ") " + "but it seems that you have another implementation of WorldEdit installed (" + platform.getPlatformName() + ") " +
"that handles the world editing."); "that handles the world editing.");
} }
} catch (NoCapablePlatformException ignore) {} } 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() EditSession editSession = WorldEdit.getInstance().getEditSessionFactory()
.getEditSession(wePlayer.getWorld(), session.getBlockChangeLimit(), blockBag, wePlayer); .getEditSession(wePlayer.getWorld(), session.getBlockChangeLimit(), blockBag, wePlayer);
editSession.enableQueue(); editSession.enableStandardMode();
return editSession; return editSession;
} }
@ -441,7 +477,7 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
LocalSession session = WorldEdit.getInstance().getSessionManager().get(wePlayer); LocalSession session = WorldEdit.getInstance().getSessionManager().get(wePlayer);
session.remember(editSession); session.remember(editSession);
editSession.flushQueue(); editSession.flushSession();
WorldEdit.getInstance().flushBlockBag(wePlayer, editSession); WorldEdit.getInstance().flushBlockBag(wePlayer, editSession);
} }

View File

@ -19,20 +19,18 @@
package com.sk89q.worldedit.bukkit.adapter; 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.jnbt.CompoundTag;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BlockMaterial; import com.sk89q.worldedit.world.registry.BlockMaterial;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.Biome;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -45,26 +43,6 @@ import javax.annotation.Nullable;
*/ */
public interface BukkitImplAdapter<T> extends IBukkitAdapter { public interface BukkitImplAdapter<T> extends IBukkitAdapter {
/**
* Get the biome ID for the given biome.
*
* <p>Returns 0 if it is not known or it doesn't exist.</p>
*
* @param biome biome
* @return the biome ID
*/
int getBiomeId(Biome biome);
/**
* Get the biome ID for the given biome ID..
*
* <p>Returns {@link Biome#OCEAN} if it is not known or it doesn't exist.</p>
*
* @param id the biome ID
* @return the biome
*/
Biome getBiome(int id);
/** /**
* Get the block at the given location. * Get the block at the given location.
* *

View File

@ -20,6 +20,8 @@
package com.sk89q.worldedit.bukkit.adapter; package com.sk89q.worldedit.bukkit.adapter;
import com.sk89q.worldedit.util.io.Closer; import com.sk89q.worldedit.util.io.Closer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -29,15 +31,13 @@ import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
/** /**
* Loads Bukkit implementation adapters. * Loads Bukkit implementation adapters.
*/ */
public class BukkitImplLoader { 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<String> adapterCandidates = new ArrayList<>(); private final List<String> adapterCandidates = new ArrayList<>();
private String customCandidate; private String customCandidate;
@ -73,7 +73,7 @@ public class BukkitImplLoader {
if (className != null) { if (className != null) {
customCandidate = className; customCandidate = className;
adapterCandidates.add(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 { try {
Enumeration<JarEntry> entries = jar.entries(); Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) { while (entries.hasMoreElements()) {
JarEntry jarEntry = (JarEntry) entries.nextElement(); JarEntry jarEntry = entries.nextElement();
String className = jarEntry.getName().replaceAll("[/\\\\]+", "."); String className = jarEntry.getName().replaceAll("[/\\\\]+", ".");
@ -157,22 +157,23 @@ public class BukkitImplLoader {
for (String className : adapterCandidates) { for (String className : adapterCandidates) {
try { try {
Class<?> cls = Class.forName(className); Class<?> cls = Class.forName(className);
if (cls.isSynthetic()) continue;
if (BukkitImplAdapter.class.isAssignableFrom(cls)) { if (BukkitImplAdapter.class.isAssignableFrom(cls)) {
return (BukkitImplAdapter) cls.newInstance(); return (BukkitImplAdapter) cls.newInstance();
} else { } 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()); "' because it does not implement " + BukkitImplAdapter.class.getCanonicalName());
} }
} catch (ClassNotFoundException e) { } 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); "' that is not supposed to be missing", e);
} catch (IllegalAccessException 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); "' that is not supposed to be raising this error", e);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
if (className.equals(customCandidate)) { 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);
} }
} }
} }

View File

@ -17,7 +17,6 @@
# #
limits: limits:
allow-extra-data-values: false
max-blocks-changed: max-blocks-changed:
default: -1 default: -1
maximum: -1 maximum: -1
@ -77,9 +76,16 @@ history:
size: 15 size: 15
expiration: 10 expiration: 10
calculation:
timeout: 100
debugging:
trace-unflushed-sessions: false
wand-item: minecraft:wooden_axe wand-item: minecraft:wooden_axe
shell-save-type: shell-save-type:
no-double-slash: false no-double-slash: false
no-op-permissions: false no-op-permissions: false
debug: false debug: false
show-help-on-first-use: true show-help-on-first-use: true
server-side-cui: true

View File

@ -13,6 +13,8 @@ dependencies {
compile 'com.google.code.gson:gson:2.8.0' compile 'com.google.code.gson:gson:2.8.0'
compile 'com.sk89q.lib:jlibnoise:1.0.0' compile 'com.sk89q.lib:jlibnoise:1.0.0'
compile 'com.googlecode.json-simple:json-simple:1.1.1' 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' testCompile 'org.mockito:mockito-core:1.9.0-rc1'
// Fawe depends // Fawe depends

View File

@ -20,6 +20,8 @@
package com.sk89q.minecraft.util.commands; package com.sk89q.minecraft.util.commands;
import com.sk89q.util.StringUtil; import com.sk89q.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -30,8 +32,6 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/** /**
* Manager for handling commands. This allows you to easily process commands, * Manager for handling commands. This allows you to easily process commands,
@ -63,7 +63,7 @@ import java.util.logging.Logger;
public abstract class CommandsManager<T> { public abstract class CommandsManager<T> {
protected static final Logger logger = protected static final Logger logger =
Logger.getLogger(CommandsManager.class.getCanonicalName()); LoggerFactory.getLogger(CommandsManager.class);
/** /**
* Mapping of commands (including aliases) with a description. Root * Mapping of commands (including aliases) with a description. Root
@ -142,7 +142,7 @@ public abstract class CommandsManager<T> {
return registerMethods(cls, parent, obj); return registerMethods(cls, parent, obj);
} }
} catch (InvocationTargetException | InstantiationException | IllegalAccessException e) { } catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
logger.log(Level.SEVERE, "Failed to register commands", e); logger.error("Failed to register commands", e);
} }
return null; return null;
} }
@ -523,7 +523,7 @@ public abstract class CommandsManager<T> {
try { try {
method.invoke(instance, methodArgs); method.invoke(instance, methodArgs);
} catch (IllegalArgumentException | IllegalAccessException e) { } catch (IllegalArgumentException | IllegalAccessException e) {
logger.log(Level.SEVERE, "Failed to execute command", e); logger.error("Failed to execute command", e);
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
if (e.getCause() instanceof CommandException) { if (e.getCause() instanceof CommandException) {
throw (CommandException) e.getCause(); throw (CommandException) e.getCause();

View File

@ -19,14 +19,15 @@
package com.sk89q.minecraft.util.commands; package com.sk89q.minecraft.util.commands;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SimpleInjector implements Injector { 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 Object[] args;
private Class<?>[] argClasses; private Class<?>[] argClasses;
@ -45,7 +46,7 @@ public class SimpleInjector implements Injector {
ctr.setAccessible(true); ctr.setAccessible(true);
return ctr.newInstance(args); return ctr.newInstance(args);
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { } 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; return null;
} }
} }

View File

@ -28,18 +28,45 @@ import com.boydti.fawe.jnbt.anvil.MCAQueue;
import com.boydti.fawe.jnbt.anvil.MCAWorld; import com.boydti.fawe.jnbt.anvil.MCAWorld;
import com.boydti.fawe.logging.LoggingChangeSet; import com.boydti.fawe.logging.LoggingChangeSet;
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory; 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.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.collection.LocalBlockVectorSet;
import com.boydti.fawe.object.exception.FaweException; 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.function.SurfaceRegionFunction;
import com.boydti.fawe.object.mask.ResettableMask; import com.boydti.fawe.object.mask.ResettableMask;
import com.boydti.fawe.object.pattern.ExistingPattern; import com.boydti.fawe.object.pattern.ExistingPattern;
import com.boydti.fawe.object.progress.ChatProgressTracker; import com.boydti.fawe.object.progress.ChatProgressTracker;
import com.boydti.fawe.object.progress.DefaultProgressTracker; 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.boydti.fawe.wrappers.WorldWrapper;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.sk89q.jnbt.CompoundTag; 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.ChangeSetExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.MaskingExtent; 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.BlockBag;
import com.sk89q.worldedit.extent.inventory.BlockBagExtent; 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.extent.world.SurvivalModeExtent;
import com.sk89q.worldedit.function.GroundFunction; import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.RegionFunction; import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.RegionMaskingFilter; 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.BlockReplace;
import com.sk89q.worldedit.function.block.Naturalizer; 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.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.ChangeSetExecutor;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy; import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern; 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.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.UndoContext;
import com.sk89q.worldedit.history.change.BlockChange; 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.history.changeset.ChangeSet;
import com.sk89q.worldedit.internal.expression.Expression; import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException; import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
import com.sk89q.worldedit.internal.expression.runtime.RValue; 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.KochanekBartelsInterpolation;
import com.sk89q.worldedit.math.interpolation.Node; import com.sk89q.worldedit.math.interpolation.Node;
import com.sk89q.worldedit.math.noise.RandomNoise; import com.sk89q.worldedit.math.noise.RandomNoise;
import com.sk89q.worldedit.math.transform.AffineTransform; 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.ArbitraryBiomeShape;
import com.sk89q.worldedit.regions.shape.ArbitraryShape; import com.sk89q.worldedit.regions.shape.ArbitraryShape;
import com.sk89q.worldedit.regions.shape.RegionShape; 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.Countable;
import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.TreeGenerator; import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.util.collection.DoubleArrayList;
import com.sk89q.worldedit.util.eventbus.EventBus; import com.sk89q.worldedit.util.eventbus.EventBus;
import com.sk89q.worldedit.world.NullWorld;
import com.sk89q.worldedit.world.SimpleWorld; import com.sk89q.worldedit.world.SimpleWorld;
import com.sk89q.worldedit.world.World; 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.block.*;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import com.sk89q.worldedit.world.weather.WeatherType; 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.Nonnull;
import javax.annotation.Nullable; 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.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; 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, * 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}.</p> * using the {@link ChangeSetExtent}.</p>
*/ */
public class EditSession extends AbstractDelegateExtent implements HasFaweQueue, SimpleWorld, AutoCloseable { public class EditSession extends AbstractDelegateExtent implements HasFaweQueue, SimpleWorld, AutoCloseable {
/**
* Used by {@link EditSession#setBlock(BlockVector3, BlockStateHolder, Stage)} to private static final Logger log = LoggerFactory.getLogger(EditSession.class);
* determine which {@link Extent}s should be bypassed.
*/
public enum Stage {
BEFORE_HISTORY, BEFORE_REORDER, BEFORE_CHANGE
}
private World world; private World world;
private String worldName; private String worldName;
@ -144,9 +216,14 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
private final int maxY; private final int maxY;
public static final UUID CONSOLE = UUID.fromString("1-1-3-3-7"); 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 static final BlockState nullBlock = BlockTypes.AIR.getDefaultState();
public enum Stage {
BEFORE_HISTORY,
BEFORE_REORDER,
BEFORE_CHANGE
}
@Deprecated @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) { 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); 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)); this(WorldEdit.getInstance().getEventBus(), world, maxBlocks, blockBag, new EditSessionEvent(world, null, maxBlocks, null));
} }
private ReorderMode reorderMode = ReorderMode.MULTI_STAGE;
private Mask oldMask; private Mask oldMask;
/** /**
@ -370,6 +449,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
if (find != null && find.get() != null) { if (find != null && find.get() != null) {
find.get().setLimit(this.limit); 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) * @return FaweRegionExtent (may be null)
*/ */
@ -536,6 +617,29 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
return extent; 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. * Get the world.
* *
@ -610,6 +714,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* Returns queue status. * Returns queue status.
* *
* @return whether the queue is enabled * @return whether the queue is enabled
* @deprecated Use {@link EditSession#getReorderMode()} with MULTI_STAGE instead.
*/ */
@Deprecated @Deprecated
public boolean isQueueEnabled() { 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. * 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 @Deprecated
public void enableQueue() { public void enableQueue() {
@ -880,6 +988,27 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
return new HashMap<>(); 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. * Get the number of blocks changed, including repeated block changes.
* <p> * <p>
@ -892,18 +1021,18 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
} }
@Override @Override
public BaseBiome getBiome(final BlockVector2 position) { public BiomeType getBiome(final BlockVector2 position) {
return this.extent.getBiome(position); return this.extent.getBiome(position);
} }
@Override @Override
public boolean setBiome(final BlockVector2 position, final BaseBiome biome) { public boolean setBiome(final BlockVector2 position, final BiomeType biome) {
this.changes++; this.changes++;
return this.extent.setBiome(position, biome); return this.extent.setBiome(position, biome);
} }
@Override @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++; this.changes++;
return this.extent.setBiome(x, y, z, biome); 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()); 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) { 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) { public int getHighestTerrainBlock(int x, int z, int minY, int maxY, Mask filter) {
for (int y = maxY; y >= minY; --y) { for (int y = maxY; y >= minY; --y) {
BlockVector3 pt = BlockVector3.at(x, y, z); BlockVector3 pt = BlockVector3.at(x, y, z);
if (filter == null if (filter.test(pt)) {
? getBlock(pt).getBlockType().getMaterial().isMovementBlocker()
: filter.test(pt)) {
return y; return y;
} }
} }
@ -1033,6 +1176,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return whether the block changed * @return whether the block changed
*/ */
public <B extends BlockStateHolder<B>> boolean rawSetBlock(BlockVector3 position, B block) { public <B extends BlockStateHolder<B>> boolean rawSetBlock(BlockVector3 position, B block) {
this.changes++;
try { try {
return this.bypassAll.setBlock(position, block); return this.bypassAll.setBlock(position, block);
} catch (WorldEditException e) { } catch (WorldEditException e) {
@ -1048,6 +1192,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return whether the block changed * @return whether the block changed
*/ */
public <B extends BlockStateHolder<B>> boolean smartSetBlock(BlockVector3 position, B block) { public <B extends BlockStateHolder<B>> boolean smartSetBlock(BlockVector3 position, B block) {
this.changes++;
try { try {
return setBlock(position, block, Stage.BEFORE_REORDER); return setBlock(position, block, Stage.BEFORE_REORDER);
} catch (WorldEditException e) { } catch (WorldEditException e) {
@ -1450,8 +1595,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return number of blocks affected * @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed * @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 { public <B extends BlockStateHolder<B>> int fillXZ(BlockVector3 origin, B block, double radius, int depth, boolean recursive) throws MaxChangedBlocksException {
return fillXZ(origin, (Pattern) block, radius, depth, recursive); return fillXZ(origin, new BlockPattern(block), radius, depth, recursive);
} }
/** /**
* Fills an area recursively in the X/Z directions. * 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"); 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( 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))); (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 // Want to replace blocks
BlockReplace replace = new BlockReplace(this, pattern); BlockReplace replace = new BlockReplace(this, pattern);
@ -1588,6 +1727,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
public boolean hasExtraExtents() { public boolean hasExtraExtents() {
return wrapped || getMask() != null || getSourceMask() != null || history != null; return wrapped || getMask() != null || getSourceMask() != null || history != null;
} }
public int removeNear(BlockVector3 position, BlockType blockType, int apothem) throws MaxChangedBlocksException { public int removeNear(BlockVector3 position, BlockType blockType, int apothem) throws MaxChangedBlocksException {
checkNotNull(position); checkNotNull(position);
checkArgument(apothem >= 1, "apothem >= 1"); checkArgument(apothem >= 1, "apothem >= 1");
@ -1670,7 +1810,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return number of blocks affected * @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
public <B extends BlockStateHolder<B>> int replaceBlocks(Region region, Set<BlockStateHolder> filter, B replacement) throws MaxChangedBlocksException { public <B extends BlockStateHolder<B>> int replaceBlocks(Region region, Set<BaseBlock> filter, B replacement) throws MaxChangedBlocksException {
return replaceBlocks(region, filter, new BlockPattern(replacement)); return replaceBlocks(region, filter, new BlockPattern(replacement));
} }
@ -1684,8 +1824,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return number of blocks affected * @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
public int replaceBlocks(Region region, Set<BlockStateHolder> filter, Pattern pattern) throws MaxChangedBlocksException { public int replaceBlocks(Region region, Set<BaseBlock> filter, Pattern pattern) throws MaxChangedBlocksException {
Mask mask = filter == null ? new ExistingBlockMask(this) : new BlockMaskBuilder().addBlocks(filter).build(this); Mask mask = filter == null ? new ExistingBlockMask(this) : new BlockMask(this, filter);
return replaceBlocks(region, mask, pattern); return replaceBlocks(region, mask, pattern);
} }
@ -1887,12 +2027,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
FlatRegionVisitor visitor = new FlatRegionVisitor(asFlatRegion(region), surface, this); FlatRegionVisitor visitor = new FlatRegionVisitor(asFlatRegion(region), surface, this);
Operations.completeBlindly(visitor); Operations.completeBlindly(visitor);
return this.changes = visitor.getAffected(); 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 * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
public int drainArea(final BlockVector3 origin, final double radius) { 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); checkNotNull(origin);
checkArgument(radius >= 0, "radius >= 0 required"); checkArgument(radius >= 0, "radius >= 0 required");
Mask liquidMask; Mask liquidMask;
@ -2053,20 +2191,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
// Around the origin in a 3x3 block // Around the origin in a 3x3 block
for (final BlockVector3 position : CuboidRegion.fromCenter(origin, 1)) { 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)) { if (mask.test(position)) {
visitor.visit(position); visitor.visit(position);
} }
@ -2349,7 +2473,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return number of blocks changed * @return number of blocks changed
* @throws MaxChangedBlocksException thrown if too many blocks are 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); 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) { public int green(final BlockVector3 position, final double radius) {
return this.green(position, radius, false); return this.green(position, radius, false);
} }
public int green(BlockVector3 position, double radius, boolean onlyNormalDirt) public int green(BlockVector3 position, double radius, boolean onlyNormalDirt)
throws MaxChangedBlocksException { throws MaxChangedBlocksException {
int affected = 0; int affected = 0;
@ -2619,6 +2744,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
for (int y = maxY; y >= 1; --y) { for (int y = maxY; y >= 1; --y) {
BlockType block = getBlockType(x, y, z); BlockType block = getBlockType(x, y, z);
switch (block.getResource().toUpperCase()) { switch (block.getResource().toUpperCase()) {
// TODO onlyNormalDirt
case "DIRT": case "DIRT":
this.setBlock(x, y, z, BlockTypes.GRASS_BLOCK.getDefaultState()); this.setBlock(x, y, z, BlockTypes.GRASS_BLOCK.getDefaultState());
break loop; break loop;
@ -2629,26 +2755,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
if (block.getMaterial().isMovementBlocker()) { if (block.getMaterial().isMovementBlocker()) {
break loop; 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()) { } else if (type.getMaterial().isAir()) {
continue; 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; 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. * Get the block distribution inside a region.
* *
* @param region a region * @param region a region
* @return the results * @return the results
*/ */
public List<Countable<BlockType>> getBlockDistribution(final Region region) { public List<Countable<BlockState>> getBlockDistribution(Region region, boolean separateStates) {
if (separateStates) return getBlockDistributionWithData(region);
int[] counter = new int[BlockTypes.size()]; int[] counter = new int[BlockTypes.size()];
if (region instanceof CuboidRegion) { 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 * @param region the region to generate the shape in
* @return the results * @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<Countable<BlockStateHolder>> getBlockDistributionWithData(final Region region) { public List<Countable<BlockStateHolder>> getBlockDistributionWithData(final Region region) {
int[][] counter = new int[BlockTypes.size()][]; 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); final WorldEditExpressionEnvironment environment = new WorldEditExpressionEnvironment(this, unit, zero);
expression.setEnvironment(environment); expression.setEnvironment(environment);
final int[] timedOut = {0};
final ArbitraryShape shape = new ArbitraryShape(region) { final ArbitraryShape shape = new ArbitraryShape(region) {
@Override @Override
public BaseBlock getMaterial(final int x, final int y, final int z, final BaseBlock defaultMaterial) { 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,
} }
} }
}; };
int changed = shape.generate(this, pattern, hollow);
try { if (timedOut[0] > 0) {
return shape.generate(this, pattern, hollow); throw new ExpressionTimeoutException(
} catch (WorldEditException e) { String.format("%d blocks changed. %d blocks took too long to evaluate (increase with //timeout).",
throw new RuntimeException(e); changed, timedOut[0]));
} }
return changed;
} }
public int deformRegion(final Region region, final Vector3 zero, final Vector3 unit, final String expressionString) throws ExpressionException, MaxChangedBlocksException { 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); final Vector3 zero2 = zero.add(0.5, 0.5, 0.5);
RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() { RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() {
// final DoubleArrayList<BlockVector3, BaseBlock> queue = new DoubleArrayList<>(false); private MutableBlockVector3 mutable = new MutableBlockVector3();
//
// 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();
@Override @Override
public boolean apply(BlockVector3 position) throws WorldEditException { public boolean apply(BlockVector3 position) throws WorldEditException {
@ -2956,18 +3051,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
} catch (EvaluationException e) { } catch (EvaluationException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
// // queue operation
// queue.put(position, material);
// }
//
// int affected = 0;
// for (Map.Entry<BlockVector3, BaseBlock> entry : queue) {
// BlockVector3 position = entry.getKey();
// BaseBlock material = entry.getValue();
//
// // set at new position
// if (setBlock(position, material)) {
// ++affected;
} }
}, this); }, this);
Operations.completeBlindly(visitor); Operations.completeBlindly(visitor);
@ -3249,9 +3332,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
return returnset; return returnset;
} }
public void recurseHollow(final Region region, final BlockVector3 origin, final Set<BlockVector3> outside) { private void recurseHollow(Region region, BlockVector3 origin, Set<BlockVector3> outside) {
//TODO FIXME Optimize - avoid vector creation final BlockVectorSet queue = new BlockVectorSet<>();
final ArrayDeque<BlockVector3> queue = new ArrayDeque<>();
queue.addLast(origin); queue.addLast(origin);
while (!queue.isEmpty()) { while (!queue.isEmpty()) {
@ -3272,10 +3354,10 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
for (BlockVector3 recurseDirection : recurseDirections) { for (BlockVector3 recurseDirection : recurseDirections) {
queue.addLast(current.add(recurseDirection)); 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 zero2D = zero.toVector2();
final Vector2 unit2D = unit.toVector2(); final Vector2 unit2D = unit.toVector2();
@ -3288,7 +3370,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
final ArbitraryBiomeShape shape = new ArbitraryBiomeShape(region) { final ArbitraryBiomeShape shape = new ArbitraryBiomeShape(region) {
@Override @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); environment.setCurrentBlock(x, 0, z);
double scaledX = (x - zero2D.getX()) / unit2D.getX(); double scaledX = (x - zero2D.getX()) / unit2D.getX();
double scaledZ = (z - zero2D.getZ()) / unit2D.getZ(); double scaledZ = (z - zero2D.getZ()) / unit2D.getZ();
@ -3305,8 +3387,13 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
} }
} }
}; };
int changed = shape.generate(this, biomeType, hollow);
return 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 = { private static final BlockVector3[] recurseDirections = {
Direction.NORTH.toBlockVector(), 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) //TODO Optimize - avoid Vector2D creation (make mutable)
final FaweQueue queue = this.getQueue(); final FaweQueue queue = this.getQueue();
queue.setChangeTask(null); queue.setChangeTask(null);

View File

@ -152,21 +152,24 @@ public class EditSessionFactory {
@Override @Override
public EditSession getEditSession(World world, int maxBlocks) { 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 @Override
public EditSession getEditSession(World world, int maxBlocks, Player player) { 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 @Override
public EditSession getEditSession(World world, int maxBlocks, BlockBag blockBag) { 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 @Override
public EditSession getEditSession(World world, int maxBlocks, BlockBag blockBag, Player player) { 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)); return new EditSession(eventBus, world, maxBlocks, blockBag, new EditSessionEvent(world, player, maxBlocks, null));
} }

View File

@ -38,6 +38,7 @@ import java.util.Set;
public abstract class LocalConfiguration { public abstract class LocalConfiguration {
public boolean profile = false; public boolean profile = false;
public boolean traceUnflushedSessions = false;
public Set<String> disallowedBlocks = new HashSet<>(); public Set<String> disallowedBlocks = new HashSet<>();
public int defaultChangeLimit = -1; public int defaultChangeLimit = -1;
public int maxChangeLimit = -1; public int maxChangeLimit = -1;
@ -65,6 +66,8 @@ public abstract class LocalConfiguration {
public String navigationWand = "minecraft:compass"; public String navigationWand = "minecraft:compass";
public int navigationWandMaxDistance = 50; public int navigationWandMaxDistance = 50;
public int scriptTimeout = 3000; public int scriptTimeout = 3000;
public int calculationTimeout = 100;
public int maxCalculationTimeout = 300;
public Set<String> allowedDataCycleBlocks = new HashSet<>(); public Set<String> allowedDataCycleBlocks = new HashSet<>();
public String saveDir = "schematics"; public String saveDir = "schematics";
public String scriptsDir = "craftscripts"; public String scriptsDir = "craftscripts";

View File

@ -67,11 +67,16 @@ import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes; import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.snapshot.Snapshot; 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 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; 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 Tool[] tools = new Tool[ItemTypes.size()];
private transient int maxBlocksChanged = -1; private transient int maxBlocksChanged = -1;
private transient int maxTimeoutTime;
private transient boolean useInventory; private transient boolean useInventory;
private transient Snapshot snapshot; private transient Snapshot snapshot;
private transient boolean hasCUISupport = false; private transient boolean hasCUISupport = false;
@ -830,6 +836,24 @@ public class LocalSession implements TextureHolder {
this.maxBlocksChanged = maxBlocksChanged; 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. * Checks whether the super pick axe is enabled.
* *
@ -1260,7 +1284,7 @@ public class LocalSession implements TextureHolder {
String msg = e.getMessage(); String msg = e.getMessage();
if (msg != null && msg.length() > 256) msg = msg.substring(0, 256); if (msg != null && msg.length() > 256) msg = msg.substring(0, 256);
this.failedCuiAttempts++; 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; 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. * Get the mask.
* *

View File

@ -0,0 +1,45 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
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);
}
}
}

View File

@ -37,15 +37,11 @@ import com.sk89q.worldedit.extension.platform.PlatformManager;
import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.Pattern; 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.math.BlockVector3;
import com.sk89q.worldedit.scripting.CraftScriptContext; import com.sk89q.worldedit.scripting.CraftScriptContext;
import com.sk89q.worldedit.scripting.CraftScriptEngine; import com.sk89q.worldedit.scripting.CraftScriptEngine;
import com.sk89q.worldedit.scripting.RhinoCraftScriptEngine; import com.sk89q.worldedit.scripting.RhinoCraftScriptEngine;
import com.sk89q.worldedit.session.SessionManager; import com.sk89q.worldedit.session.SessionManager;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.eventbus.EventBus; 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.FilenameException;
import com.sk89q.worldedit.util.io.file.FilenameResolutionException; import com.sk89q.worldedit.util.io.file.FilenameResolutionException;
import com.sk89q.worldedit.util.io.file.InvalidFilenameException; 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.SimpleSupervisor;
import com.sk89q.worldedit.util.task.Supervisor; import com.sk89q.worldedit.util.task.Supervisor;
import com.sk89q.worldedit.world.block.BlockStateHolder; 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.BundledBlockData;
import com.sk89q.worldedit.world.registry.BundledItemData; import com.sk89q.worldedit.world.registry.BundledItemData;
import com.sk89q.worldedit.world.registry.LegacyMapper; import com.sk89q.worldedit.world.registry.LegacyMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.script.ScriptException; import javax.script.ScriptException;
@ -97,9 +94,9 @@ import static com.sk89q.worldedit.event.platform.Interaction.OPEN;
*/ */
public final class WorldEdit { 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 static String version;
private final EventBus eventBus = new EventBus(); private final EventBus eventBus = new EventBus();
@ -114,7 +111,6 @@ public final class WorldEdit {
private final PatternFactory patternFactory = new PatternFactory(this); private final PatternFactory patternFactory = new PatternFactory(this);
static { static {
WorldEditPrefixHandler.register("com.sk89q.worldedit");
getVersion(); getVersion();
} }
@ -670,16 +666,16 @@ public final class WorldEdit {
} catch (ScriptException e) { } catch (ScriptException e) {
player.printError("Failed to execute:"); player.printError("Failed to execute:");
player.printRaw(e.getMessage()); player.printRaw(e.getMessage());
logger.log(Level.WARNING, "Failed to execute script", e); logger.warn("Failed to execute script", e);
} catch (NumberFormatException | WorldEditException e) { } catch (NumberFormatException | WorldEditException e) {
throw e; throw e;
} catch (Throwable e) { } catch (Throwable e) {
player.printError("Failed to execute (see console):"); player.printError("Failed to execute (see console):");
player.printRaw(e.getClass().getCanonicalName()); player.printRaw(e.getClass().getCanonicalName());
logger.log(Level.WARNING, "Failed to execute script", e); logger.warn("Failed to execute script", e);
} finally { } finally {
for (EditSession editSession : scriptContext.getEditSessions()) { for (EditSession editSession : scriptContext.getEditSessions()) {
editSession.flushQueue(); editSession.flushSession();
session.remember(editSession); session.remember(editSession);
} }
} }

View File

@ -27,6 +27,8 @@ import com.sk89q.worldedit.world.item.ItemTypes;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* Represents an item, without an amount value. See {@link BaseItemStack} * Represents an item, without an amount value. See {@link BaseItemStack}
* for an instance with stack amount information. * for an instance with stack amount information.
@ -34,7 +36,7 @@ import javax.annotation.Nullable;
* <p>This class may be removed in the future.</p> * <p>This class may be removed in the future.</p>
*/ */
public class BaseItem implements NbtValued { public class BaseItem implements NbtValued {
private ItemType itemType; private ItemType itemType;
@Nullable @Nullable
private CompoundTag nbtData; private CompoundTag nbtData;
@ -45,6 +47,7 @@ public class BaseItem implements NbtValued {
* @param itemType Type of the item * @param itemType Type of the item
*/ */
public BaseItem(ItemType itemType) { public BaseItem(ItemType itemType) {
checkNotNull(itemType);
this.itemType = itemType; this.itemType = itemType;
} }
@ -54,7 +57,8 @@ public class BaseItem implements NbtValued {
* @param itemType Type of the item * @param itemType Type of the item
* @param tag NBT Compound tag * @param tag NBT Compound tag
*/ */
public BaseItem(ItemType itemType, CompoundTag tag) { public BaseItem(ItemType itemType, @Nullable CompoundTag tag) {
checkNotNull(itemType);
this.itemType = itemType; this.itemType = itemType;
this.nbtData = tag; this.nbtData = tag;
} }

View File

@ -19,14 +19,13 @@
package com.sk89q.worldedit.blocks; 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.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.Map;
import java.util.Set;
/** /**
* Block-related utility methods. * Block-related utility methods.
@ -36,143 +35,6 @@ public final class Blocks {
private Blocks() { private Blocks() {
} }
/**
* HashSet for shouldPlaceLate.
*/
private static final Set<BlockType> 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<BlockType> 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<BlockType> 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. * Checks whether a given block is in a list of base blocks.
* *
@ -190,4 +52,28 @@ public final class Blocks {
return false; 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<Property<Object>, Object> resolveProperties(Map<String, String> states, BlockType type) {
Map<String, ? extends Property<?>> existing = type.getPropertyMap();
Map<Property<Object>, Object> newMap = Maps.newHashMap();
states.forEach((key, value) -> {
@SuppressWarnings("unchecked")
Property<Object> prop = (Property<Object>) 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;
}
} }

View File

@ -53,15 +53,17 @@ import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.command.binding.Switch; import com.sk89q.worldedit.util.command.binding.Switch;
import com.sk89q.worldedit.world.World; 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.BiomeData;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.registry.BiomeRegistry; import com.sk89q.worldedit.world.registry.BiomeRegistry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION;
/** /**
* Implements biome-related commands such as "/biomelist". * Implements biome-related commands such as "/biomelist".
@ -102,11 +104,11 @@ public class BiomeCommands extends MethodCommands {
} }
BiomeRegistry biomeRegistry = getBiomeRegistry(); BiomeRegistry biomeRegistry = getBiomeRegistry();
List<BaseBiome> biomes = biomeRegistry.getBiomes(); List<BiomeType> biomes = biomeRegistry.getBiomes();
int totalPages = biomes.size() / 19 + 1; int totalPages = biomes.size() / 19 + 1;
Message msg = BBC.BIOME_LIST_HEADER.m(page, totalPages); Message msg = BBC.BIOME_LIST_HEADER.m(page, totalPages);
String setBiome = Commands.getAlias(BiomeCommands.class, "/setbiome"); String setBiome = Commands.getAlias(BiomeCommands.class, "/setbiome");
for (BaseBiome biome : biomes) { for (BiomeType biome : biomes) {
if (offset > 0) { if (offset > 0) {
offset--; offset--;
} else { } else {
@ -150,12 +152,12 @@ public class BiomeCommands extends MethodCommands {
return; return;
} }
BaseBiome biome = player.getWorld().getBiome(blockPosition.toBlockPoint().toBlockVector2()); BiomeType biome = player.getWorld().getBiome(blockPosition.toBlockPoint().toBlockVector2());
biomes[biome.getId()]++; biomes[biome.getInternalId()]++;
size = 1; size = 1;
} else if (args.hasFlag('p')) { } else if (args.hasFlag('p')) {
BaseBiome biome = player.getWorld().getBiome(player.getLocation().toBlockPoint().toBlockVector2()); BiomeType biome = player.getWorld().getBiome(player.getLocation().toBlockPoint().toBlockVector2());
biomes[biome.getId()]++; biomes[biome.getInternalId()]++;
size = 1; size = 1;
} else { } else {
World world = player.getWorld(); World world = player.getWorld();
@ -181,15 +183,15 @@ public class BiomeCommands extends MethodCommands {
BBC.BIOME_LIST_HEADER.send(player, 1, 1); BBC.BIOME_LIST_HEADER.send(player, 1, 1);
List<Countable<BaseBiome>> distribution = new ArrayList<>(); List<Countable<BiomeType>> distribution = new ArrayList<>();
for (int i = 0; i < biomes.length; i++) { for (int i = 0; i < biomes.length; i++) {
int count = biomes[i]; int count = biomes[i];
if (count != 0) { if (count != 0) {
distribution.add(new Countable<>(new BaseBiome(i), count)); distribution.add(new Countable<>(new BiomeType(i), count));
} }
} }
Collections.sort(distribution); Collections.sort(distribution);
for (Countable<BaseBiome> c : distribution) { for (Countable<BiomeType> c : distribution) {
BiomeData data = biomeRegistry.getData(c.getID()); BiomeData data = biomeRegistry.getData(c.getID());
String str = String.format("%-7s (%.3f%%) %s #%d", String str = String.format("%-7s (%.3f%%) %s #%d",
String.valueOf(c.getAmount()), String.valueOf(c.getAmount()),
@ -212,7 +214,7 @@ public class BiomeCommands extends MethodCommands {
) )
@Logging(REGION) @Logging(REGION)
@CommandPermissions("worldedit.biome.set") @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(); World world = player.getWorld();
Region region; Region region;
Mask mask = editSession.getMask(); Mask mask = editSession.getMask();

View File

@ -37,8 +37,6 @@ import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.Step; 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.EditSession;
import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
@ -633,7 +631,7 @@ public class BrushCommands extends BrushProcessor {
) )
@CommandPermissions("worldedit.brush.smooth") @CommandPermissions("worldedit.brush.smooth")
public BrushSettings smoothBrush(Player player, LocalSession session, EditSession editSession, 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); getWorldEdit().checkMaxBrushRadius(radius);
@ -642,7 +640,7 @@ public class BrushCommands extends BrushProcessor {
iterations = Math.min(limit.MAX_ITERATIONS, iterations); iterations = Math.min(limit.MAX_ITERATIONS, iterations);
return set(session, context, return set(session, context,
new SmoothBrush(iterations)) new SmoothBrush(iterations, mask))
.setSize(radius); .setSize(radius);
} }

View File

@ -21,7 +21,6 @@ package com.sk89q.worldedit.command;
import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.BBC;
import com.sk89q.minecraft.util.commands.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.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.Logging; import com.sk89q.minecraft.util.commands.Logging;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
@ -106,7 +105,7 @@ public class ChunkCommands {
) )
@CommandPermissions("worldedit.delchunks") @CommandPermissions("worldedit.delchunks")
@Logging(REGION) @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."); player.print(BBC.getPrefix() + "Note that this command does not yet support the mcregion format.");
LocalConfiguration config = worldEdit.getConfiguration(); LocalConfiguration config = worldEdit.getConfiguration();

View File

@ -579,7 +579,7 @@ public class ClipboardCommands extends MethodCommands {
max = 1 max = 1
) )
@CommandPermissions("worldedit.clipboard.flip") @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 { @Optional(Direction.AIM) @Direction BlockVector3 direction) throws WorldEditException {
ClipboardHolder holder = session.getClipboard(); ClipboardHolder holder = session.getClipboard();
AffineTransform transform = new AffineTransform(); AffineTransform transform = new AffineTransform();
@ -597,7 +597,7 @@ public class ClipboardCommands extends MethodCommands {
max = 0 max = 0
) )
@CommandPermissions("worldedit.clipboard.clear") @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); session.setClipboard(null);
BBC.CLIPBOARD_CLEARED.send(player); BBC.CLIPBOARD_CLEARED.send(player);
} }

View File

@ -26,8 +26,6 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.transform.BlockTransformExtent; import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy; import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operation; 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.Vector3;
import com.sk89q.worldedit.math.transform.AffineTransform; import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.math.transform.CombinedTransform; import com.sk89q.worldedit.math.transform.CombinedTransform;
@ -96,20 +94,18 @@ public class FlattenedClipboardTransform {
MutableVector3 newMinimum = new MutableVector3(corners[0]); MutableVector3 newMinimum = new MutableVector3(corners[0]);
MutableVector3 newMaximum = new MutableVector3(corners[0]); MutableVector3 newMaximum = new MutableVector3(corners[0]);
// MutableVector3 cbv = new MutableVector3();
for (int i = 1; i < corners.length; i++) { for (int i = 1; i < corners.length; i++) {
MutableVector3 cbv = new MutableVector3(corners[i]); Vector3 cbv = corners[i];
newMinimum = newMinimum.setComponents(newMinimum.getMinimum(cbv)); newMinimum = newMinimum.setComponents(newMinimum.getMinimum(cbv));
newMaximum = newMaximum.setComponents(newMaximum.getMaximum(cbv)); newMaximum = newMaximum.setComponents(newMaximum.getMaximum(cbv));
} }
// After transformation, the points may not really sit on a block, // After transformation, the points may not really sit on a block,
// so we should expand the region for edge cases // so we should expand the region for edge cases
newMinimum.mutX(Math.ceil(Math.floor(newMinimum.getX()))); newMinimum = newMinimum.floor();
newMinimum.mutY(Math.ceil(Math.floor(newMinimum.getY()))); newMaximum = newMaximum.ceil();
newMinimum.mutZ(Math.ceil(Math.floor(newMinimum.getZ())));
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());
} }
/** /**

View File

@ -59,7 +59,7 @@ public class GeneralCommands {
max = 1 max = 1
) )
@CommandPermissions("worldedit.limit") @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(); LocalConfiguration config = worldEdit.getConfiguration();
boolean mayDisable = player.hasPermission("worldedit.limit.unrestricted"); boolean mayDisable = player.hasPermission("worldedit.limit.unrestricted");
@ -74,13 +74,43 @@ public class GeneralCommands {
session.setBlockChangeLimit(limit); session.setBlockChangeLimit(limit);
if (limit != -1) { if (limit != config.defaultChangeLimit) {
player.print("Block change limit set to " + limit + ". (Use //limit -1 to go back to the default.)"); player.print("Block change limit set to " + limit + ". (Use //limit to go back to the default.)");
} else { } else {
player.print("Block change limit set to " + limit + "."); 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( @Command(
aliases = { "/fast" }, aliases = { "/fast" },
usage = "[on|off]", usage = "[on|off]",
@ -89,7 +119,7 @@ public class GeneralCommands {
max = 1 max = 1
) )
@CommandPermissions("worldedit.fast") @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); String newState = args.getString(0, null);
if (session.hasFastMode()) { 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( @Command(
aliases = { "/gmask", "gmask" }, aliases = { "/gmask", "gmask" },
usage = "[mask]", usage = "[mask]",
@ -119,7 +184,7 @@ public class GeneralCommands {
max = -1 max = -1
) )
@CommandPermissions("worldedit.global-mask") @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) { if (mask == null) {
session.setMask((Mask) null); session.setMask((Mask) null);
player.print("Global mask disabled."); player.print("Global mask disabled.");
@ -136,7 +201,7 @@ public class GeneralCommands {
min = 0, min = 0,
max = 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()) { if (session.togglePlacementPosition()) {
player.print("Now placing at pos #1."); player.print("Now placing at pos #1.");

View File

@ -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.Switch;
import com.sk89q.worldedit.util.command.binding.Text; import com.sk89q.worldedit.util.command.binding.Text;
import com.sk89q.worldedit.util.command.parametric.Optional; import com.sk89q.worldedit.util.command.parametric.Optional;
import com.sk89q.worldedit.util.command.parametric.ParameterException; import com.sk89q.worldedit.world.biome.BiomeType;
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;
/** /**
* Commands for the generation of shapes and other objects. * Commands for the generation of shapes and other objects.
@ -287,7 +275,7 @@ public class GenerationCommands extends MethodCommands {
@CommandPermissions("worldedit.generation.forest") @CommandPermissions("worldedit.generation.forest")
@Logging(POSITION) @Logging(POSITION)
@SuppressWarnings("deprecation") @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; density = density / 100;
int affected = editSession.makeForest(session.getPlacementPosition(player), size, density, type); int affected = editSession.makeForest(session.getPlacementPosition(player), size, density, type);
player.print(BBC.getPrefix() + affected + " trees created."); player.print(BBC.getPrefix() + affected + " trees created.");
@ -430,16 +418,16 @@ public class GenerationCommands extends MethodCommands {
min = 2, min = 2,
max = -1 max = -1
) )
@CommandPermissions({"worldedit.generation.shape", "worldedit.biome.set"}) @CommandPermissions("worldedit.generation.shape.biome")
@Logging(ALL) @Logging(ALL)
public void generateBiome(FawePlayer fp, Player player, LocalSession session, EditSession editSession, public void generateBiome(FawePlayer fp, Player player, LocalSession session, EditSession editSession,
@Selection Region region, @Selection Region region,
BaseBiome target, BiomeType target,
@Text String expression, @Text String expression,
@Switch('h') boolean hollow, @Switch('h') boolean hollow,
@Switch('r') boolean useRawCoords, @Switch('r') boolean useRawCoords,
@Switch('o') boolean offset, @Switch('o') boolean offset,
@Switch('c') boolean offsetCenter, CommandContext context) throws WorldEditException { @Switch('c') boolean offsetCenter) throws WorldEditException {
final Vector3 zero; final Vector3 zero;
Vector3 unit; Vector3 unit;

View File

@ -265,7 +265,6 @@ public class HistoryCommands extends MethodCommands {
) )
@CommandPermissions("worldedit.history.redo") @CommandPermissions("worldedit.history.redo")
public void redo(Player player, LocalSession session, CommandContext args) throws WorldEditException { public void redo(Player player, LocalSession session, CommandContext args) throws WorldEditException {
int times = Math.max(1, args.getInteger(0, 1)); int times = Math.max(1, args.getInteger(0, 1));
EditSession redone = null; EditSession redone = null;

View File

@ -27,7 +27,6 @@ import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.Logging; import com.sk89q.minecraft.util.commands.Logging;
import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
@ -134,7 +133,7 @@ public class NavigationCommands {
) )
@CommandPermissions("worldedit.navigation.ceiling") @CommandPermissions("worldedit.navigation.ceiling")
@Logging(POSITION) @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 ? final int clearance = args.argsLength() > 0 ?
Math.max(0, args.getInteger(0)) : 0; Math.max(0, args.getInteger(0)) : 0;
@ -155,7 +154,7 @@ public class NavigationCommands {
max = 0 max = 0
) )
@CommandPermissions("worldedit.navigation.thru.command") @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)) { if (player.passThroughForwardWall(6)) {
BBC.WHOOSH.send(player); BBC.WHOOSH.send(player);
} else { } else {
@ -207,7 +206,7 @@ public class NavigationCommands {
) )
@CommandPermissions("worldedit.navigation.up") @CommandPermissions("worldedit.navigation.up")
@Logging(POSITION) @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 int distance = args.getInteger(0);
final boolean alwaysGlass = getAlwaysGlass(args); final boolean alwaysGlass = getAlwaysGlass(args);

View File

@ -53,7 +53,6 @@ import com.sk89q.worldedit.function.visitor.LayerVisitor;
import com.sk89q.worldedit.internal.annotation.Direction; import com.sk89q.worldedit.internal.annotation.Direction;
import com.sk89q.worldedit.internal.annotation.Selection; import com.sk89q.worldedit.internal.annotation.Selection;
import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.convolution.GaussianKernel; 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.Switch;
import com.sk89q.worldedit.util.command.binding.Text; import com.sk89q.worldedit.util.command.binding.Text;
import com.sk89q.worldedit.util.command.parametric.Optional; 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.ArrayList;
import java.util.Iterator; import java.util.Iterator;
@ -454,20 +449,19 @@ public class RegionCommands extends MethodCommands {
} }
@Command( @Command(
aliases = {"/smooth"}, aliases = { "/smooth" },
usage = "[iterations]", usage = "[iterations] [filter]",
flags = "n", desc = "Smooth the elevation in the selection",
desc = "Smooth the elevation in the selection", help =
help = "Smooths the elevation in the selection.\n" +
"Smooths the elevation in the selection.\n" + "Optionally, restricts the height map to a set of blocks specified with mask syntax.\n" +
"The -n flag makes it only consider naturally occuring blocks.\n" + "For example, '//smooth 1 grass_block,dirt,stone' would only smooth natural surface terrain.",
"The -s flag makes it only consider snow.", min = 0,
min = 0, max = 2
max = 2
) )
@CommandPermissions("worldedit.region.smoothsnow") @CommandPermissions("worldedit.region.smoothsnow")
@Logging(REGION) @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 min = region.getMinimumPoint();
BlockVector3 max = region.getMaximumPoint(); 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)); 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(() -> { player.checkConfirmationRegion(() -> {
try { try {
HeightMap heightMap = new HeightMap(editSession, region, affectNatural, snow); HeightMap heightMap = new HeightMap(editSession, region, mask, snow);
HeightMapFilter filter = (HeightMapFilter) HeightMapFilter.class.getConstructors()[0].newInstance(GaussianKernel.class.getConstructors()[0].newInstance(5, 1)); HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1.0));
int affected = heightMap.applyFilter(filter, iterations); int affected = heightMap.applyFilter(filter, iterations);
BBC.VISITOR_BLOCK.send(player, affected); BBC.VISITOR_BLOCK.send(player, affected);
} catch (Throwable e) { } catch (Throwable e) {
@ -523,7 +517,7 @@ public class RegionCommands extends MethodCommands {
@Command( @Command(
aliases = {"/move"}, aliases = {"/move"},
usage = "[count] [direction] [leave-id]", usage = "[count] [direction] [leave-id]",
flags = "s", flags = "sbea",
desc = "Move the contents of the selection", desc = "Move the contents of the selection",
help = help =
"Moves the contents of the selection.\n" + "Moves the contents of the selection.\n" +
@ -707,10 +701,10 @@ public class RegionCommands extends MethodCommands {
Mask sourceMask = session.getSourceMask(); Mask sourceMask = session.getSourceMask();
session.setMask((Mask) null); session.setMask((Mask) null);
session.setSourceMask((Mask) null); session.setSourceMask((Mask) null);
BaseBiome biome = null; BiomeType biome = null;
if (context.argsLength() >= 1) { if (context.argsLength() >= 1) {
BiomeRegistry biomeRegistry = worldEdit.getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBiomeRegistry(); BiomeRegistry biomeRegistry = worldEdit.getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBiomeRegistry();
List<BaseBiome> knownBiomes = biomeRegistry.getBiomes(); List<BiomeType> knownBiomes = biomeRegistry.getBiomes();
biome = Biomes.findBiomeByName(knownBiomes, context.getString(0), biomeRegistry); biome = Biomes.findBiomeByName(knownBiomes, context.getString(0), biomeRegistry);
} }
Long seed = context.argsLength() != 2 || !MathMan.isInteger(context.getString(1)) ? null : Long.parseLong(context.getString(1)); 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") @CommandPermissions("worldedit.region.forest")
@Logging(REGION) @Logging(REGION)
public void forest(FawePlayer player, EditSession editSession, @Selection Region region, @Optional("tree") TreeType type, public void forest(Player player, EditSession editSession, @Selection Region region, @Optional("tree") TreeType type,
@Optional("5") @Range(min = 0, max = 100) double density, @Optional("5") @Range(min = 0, max = 100) double density) throws WorldEditException {
CommandContext context) throws WorldEditException { int affected = editSession.makeForest(region, density / 100, type);
player.checkConfirmationRegion(() -> { player.print(affected + " trees created.");
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);
} }
@Command( @Command(

View File

@ -32,6 +32,7 @@ import com.boydti.fawe.object.schematic.StructureFormat;
import com.boydti.fawe.object.schematic.visualizer.SchemVis; import com.boydti.fawe.object.schematic.visualizer.SchemVis;
import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.chat.Message; 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.Command;
import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException; 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.binding.Switch;
import com.sk89q.worldedit.util.command.parametric.Optional; import com.sk89q.worldedit.util.command.parametric.Optional;
import com.sk89q.worldedit.util.io.file.FilenameException; import com.sk89q.worldedit.util.io.file.FilenameException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable; import java.io.BufferedInputStream;
import java.io.*; 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.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL;
import java.nio.channels.Channels; import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.nio.file.Files; 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.concurrent.atomic.LongAdder;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.boydti.fawe.util.ReflectionUtils.as;
/** /**
* Commands that work with schematic files. * 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") @Command(aliases = {"schematic", "schem", "/schematic", "/schem", "clipboard", "/clipboard"}, desc = "Commands that work with schematic files")
public class SchematicCommands extends MethodCommands { 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. * Create a new instance.
@ -280,7 +293,7 @@ public class SchematicCommands extends MethodCommands {
@Command(aliases = {"save"}, usage = "[format] <filename>", desc = "Save a schematic into your clipboard", help = "The default format for 1.13 is schem") @Command(aliases = {"save"}, usage = "[format] <filename>", desc = "Save a schematic into your clipboard", help = "The default format for 1.13 is schem")
@Deprecated @Deprecated
@CommandPermissions({"worldedit.clipboard.save", "worldedit.schematic.save", "worldedit.schematic.save.other"}) @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 LocalConfiguration config = this.worldEdit.getConfiguration();
final ClipboardFormat format = ClipboardFormats.findByAlias(formatName); final ClipboardFormat format = ClipboardFormats.findByAlias(formatName);
if (format == null) { if (format == null) {
@ -324,6 +337,8 @@ public class SchematicCommands extends MethodCommands {
try { try {
if (!f.exists()) { if (!f.exists()) {
f.createNewFile(); f.createNewFile();
} else if (!allowOverwrite) {
BBC.SCHEMATIC_MOVE_EXISTS.send(player, f.getName());
} }
try (FileOutputStream fos = new FileOutputStream(f)) { try (FileOutputStream fos = new FileOutputStream(f)) {
final ClipboardHolder holder = session.getClipboard(); final ClipboardHolder holder = session.getClipboard();
@ -363,7 +378,7 @@ public class SchematicCommands extends MethodCommands {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
player.printError("Schematic could not written: " + e.getMessage()); 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 {
} }
}); });
} }
} }

View File

@ -192,8 +192,9 @@ public class ScriptingCommands {
@Command(aliases = {".s"}, usage = "[args...]", desc = "Execute last CraftScript", min = 0, max = -1) @Command(aliases = {".s"}, usage = "[args...]", desc = "Execute last CraftScript", min = 0, max = -1)
@CommandPermissions("worldedit.scripting.execute") @CommandPermissions("worldedit.scripting.execute")
@Logging(ALL) @Logging(ALL)
public void executeLast(final Player player, final LocalSession session, final CommandContext args) throws WorldEditException { public void executeLast(Player player, LocalSession session, CommandContext args) throws WorldEditException {
final String lastScript = session.getLastScript();
String lastScript = session.getLastScript();
if (!player.hasPermission("worldedit.scripting.execute." + lastScript)) { if (!player.hasPermission("worldedit.scripting.execute." + lastScript)) {
player.printError("You don't have permission to use that script."); player.printError("You don't have permission to use that script.");

View File

@ -42,6 +42,9 @@ import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.Mask; 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.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region; 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.StyledFragment;
import com.sk89q.worldedit.util.formatting.component.CommandListBox; import com.sk89q.worldedit.util.formatting.component.CommandListBox;
import com.sk89q.worldedit.world.World; 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.item.ItemTypes;
import com.sk89q.worldedit.world.storage.ChunkStore; import com.sk89q.worldedit.world.storage.ChunkStore;
import java.io.File; import java.io.File;
@ -96,8 +101,9 @@ public class SelectionCommands {
) )
@Logging(POSITION) @Logging(POSITION)
@CommandPermissions("worldedit.selection.pos") @CommandPermissions("worldedit.selection.pos")
public void pos1(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { public void pos1(Player player, LocalSession session, CommandContext args) throws WorldEditException {
BlockVector3 pos;
Location pos;
if (args.argsLength() == 1) { if (args.argsLength() == 1) {
if (args.getString(0).matches("-?\\d+,-?\\d+,-?\\d+")) { if (args.getString(0).matches("-?\\d+,-?\\d+,-?\\d+")) {
@ -128,8 +134,9 @@ public class SelectionCommands {
) )
@Logging(POSITION) @Logging(POSITION)
@CommandPermissions("worldedit.selection.pos") @CommandPermissions("worldedit.selection.pos")
public void pos2(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { public void pos2(Player player, LocalSession session, CommandContext args) throws WorldEditException {
BlockVector3 pos;
Location pos;
if (args.argsLength() == 1) { if (args.argsLength() == 1) {
if (args.getString(0).matches("-?\\d+,-?\\d+,-?\\d+")) { if (args.getString(0).matches("-?\\d+,-?\\d+,-?\\d+")) {
String[] coords = args.getString(0).split(","); String[] coords = args.getString(0).split(",");
@ -161,7 +168,7 @@ public class SelectionCommands {
max = 0 max = 0
) )
@CommandPermissions("worldedit.selection.hpos") @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(); BlockVector3 pos = player.getBlockTrace(300).toBlockPoint();
if (pos != null) { if (pos != null) {
@ -185,7 +192,7 @@ public class SelectionCommands {
max = 0 max = 0
) )
@CommandPermissions("worldedit.selection.hpos") @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(); BlockVector3 pos = player.getBlockTrace(300).toBlockPoint();
if (pos != null) { if (pos != null) {
@ -219,7 +226,7 @@ public class SelectionCommands {
) )
@Logging(POSITION) @Logging(POSITION)
@CommandPermissions("worldedit.selection.chunk") @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 min;
final BlockVector3 max; final BlockVector3 max;
final World world = player.getWorld(); final World world = player.getWorld();
@ -278,7 +285,7 @@ public class SelectionCommands {
max = 0 max = 0
) )
@CommandPermissions("worldedit.wand") @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)); player.giveItem(new BaseItemStack(ItemTypes.parse(we.getConfiguration().wandItem), 1));
BBC.SELECTION_WAND.send(player); BBC.SELECTION_WAND.send(player);
if (!FawePlayer.wrap(player).hasPermission("fawe.tips")) if (!FawePlayer.wrap(player).hasPermission("fawe.tips"))
@ -294,6 +301,7 @@ public class SelectionCommands {
) )
@CommandPermissions("worldedit.wand.toggle") @CommandPermissions("worldedit.wand.toggle")
public void toggleWand(Player player, LocalSession session, CommandContext args) throws WorldEditException { public void toggleWand(Player player, LocalSession session, CommandContext args) throws WorldEditException {
session.setToolControl(!session.isToolControlEnabled()); session.setToolControl(!session.isToolControlEnabled());
if (session.isToolControlEnabled()) { if (session.isToolControlEnabled()) {
@ -312,7 +320,8 @@ public class SelectionCommands {
) )
@Logging(REGION) @Logging(REGION)
@CommandPermissions("worldedit.selection.expand") @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 // Special syntax (//expand vert) to expand the selection between
// sky and bedrock. // sky and bedrock.
if (args.getString(0).equalsIgnoreCase("vert") || args.getString(0).equalsIgnoreCase("vertical")) { if (args.getString(0).equalsIgnoreCase("vert") || args.getString(0).equalsIgnoreCase("vertical")) {
@ -402,7 +411,7 @@ public class SelectionCommands {
) )
@Logging(REGION) @Logging(REGION)
@CommandPermissions("worldedit.selection.contract") @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<BlockVector3> dirs = new ArrayList<>(); List<BlockVector3> dirs = new ArrayList<>();
int change = args.getInteger(0); int change = args.getInteger(0);
@ -476,7 +485,7 @@ public class SelectionCommands {
) )
@Logging(REGION) @Logging(REGION)
@CommandPermissions("worldedit.selection.shift") @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<BlockVector3> dirs = new ArrayList<>(); List<BlockVector3> dirs = new ArrayList<>();
int change = args.getInteger(0); int change = args.getInteger(0);
@ -523,7 +532,7 @@ public class SelectionCommands {
) )
@Logging(REGION) @Logging(REGION)
@CommandPermissions("worldedit.selection.outset") @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 region = session.getSelection(player.getWorld());
region.expand(getChangesForEachDir(args)); region.expand(getChangesForEachDir(args));
session.getRegionSelector(player.getWorld()).learnChanges(); session.getRegionSelector(player.getWorld()).learnChanges();
@ -546,7 +555,7 @@ public class SelectionCommands {
) )
@Logging(REGION) @Logging(REGION)
@CommandPermissions("worldedit.selection.inset") @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 region = session.getSelection(player.getWorld());
region.contract(getChangesForEachDir(args)); region.contract(getChangesForEachDir(args));
session.getRegionSelector(player.getWorld()).learnChanges(); session.getRegionSelector(player.getWorld()).learnChanges();
@ -726,7 +735,7 @@ public class SelectionCommands {
min = 0, min = 0,
max = 1 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(); final World world = player.getWorld();
if (args.argsLength() == 0) { if (args.argsLength() == 0) {
session.getRegionSelector(world).clear(); session.getRegionSelector(world).clear();

View File

@ -39,7 +39,6 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
import java.util.List; import java.util.List;
import java.util.logging.Logger;
/** /**
* Snapshot commands. * Snapshot commands.
@ -47,7 +46,6 @@ import java.util.logging.Logger;
@Command(aliases = {"snapshot", "snap"}, desc = "List, load and view information related to snapshots") @Command(aliases = {"snapshot", "snap"}, desc = "List, load and view information related to snapshots")
public class SnapshotCommands { 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 static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
private final WorldEdit we; private final WorldEdit we;
@ -64,7 +62,7 @@ public class SnapshotCommands {
max = 1 max = 1
) )
@CommandPermissions("worldedit.snapshots.list") @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(); LocalConfiguration config = we.getConfiguration();
@ -93,10 +91,10 @@ public class SnapshotCommands {
File dir = config.snapshotRepo.getDirectory(); File dir = config.snapshotRepo.getDirectory();
try { try {
logger.info("WorldEdit found no snapshots: looked in: " WorldEdit.logger.info("WorldEdit found no snapshots: looked in: "
+ dir.getCanonicalPath()); + dir.getCanonicalPath());
} catch (IOException e) { } 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?): " + "(NON-RESOLVABLE PATH - does it exist?): "
+ dir.getPath()); + dir.getPath());
} }

View File

@ -39,7 +39,6 @@ import com.sk89q.worldedit.world.storage.ChunkStore;
import com.sk89q.worldedit.world.storage.MissingWorldException; import com.sk89q.worldedit.world.storage.MissingWorldException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.logging.Logger;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION; 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)") @Command(aliases = {}, desc = "[More Info](http://wiki.sk89q.com/wiki/WorldEdit/Snapshots)")
public class SnapshotUtilCommands { public class SnapshotUtilCommands {
private static final Logger logger = Logger.getLogger("Minecraft.WorldEdit");
private final WorldEdit we; private final WorldEdit we;
public SnapshotUtilCommands(WorldEdit we) { public SnapshotUtilCommands(WorldEdit we) {
@ -99,10 +96,10 @@ public class SnapshotUtilCommands {
File dir = config.snapshotRepo.getDirectory(); File dir = config.snapshotRepo.getDirectory();
try { try {
logger.info("FAWE found no snapshots: looked in: " WorldEdit.logger.info("FAWE found no snapshots: looked in: "
+ dir.getCanonicalPath()); + dir.getCanonicalPath());
} catch (IOException e) { } 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?): " + "(NON-RESOLVABLE PATH - does it exist?): "
+ dir.getPath()); + dir.getPath());
} }

View File

@ -48,7 +48,7 @@ public class SuperPickaxeCommands {
max = 0 max = 0
) )
@CommandPermissions("worldedit.superpickaxe") @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.setSuperPickaxe(new SinglePickaxe());
session.enableSuperPickAxe(); session.enableSuperPickAxe();

View File

@ -24,7 +24,6 @@ import com.boydti.fawe.object.brush.InspectBrush;
import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
@ -67,7 +66,7 @@ public class ToolCommands {
max = 0 max = 0
) )
@CommandPermissions("worldedit.tool.info") @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); session.setTool(new QueryTool(), player);
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND); BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
BBC.TOOL_INFO.send(player, itemStack.getType().getName()); BBC.TOOL_INFO.send(player, itemStack.getType().getName());
@ -123,7 +122,7 @@ public class ToolCommands {
max = 0 max = 0
) )
@CommandPermissions("worldedit.tool.data-cycler") @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); session.setTool(new BlockDataCyler(), player);
BBC.TOOL_CYCLER.send(player, player.getItemInHand(HandSide.MAIN_HAND).getType().getName()); BBC.TOOL_CYCLER.send(player, player.getItemInHand(HandSide.MAIN_HAND).getType().getName());

View File

@ -22,7 +22,9 @@ package com.sk89q.worldedit.command;
import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions; 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.entity.Player;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
@ -48,7 +50,7 @@ public class ToolUtilCommands {
max = 1 max = 1
) )
@CommandPermissions("worldedit.superpickaxe") @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); String newState = args.getString(0, null);
if (session.hasSuperPickAxe()) { if (session.hasSuperPickAxe()) {
@ -78,7 +80,7 @@ public class ToolUtilCommands {
max = -1 max = -1
) )
@CommandPermissions("worldedit.brush.options.mask") @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) { if (mask == null) {
session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setMask(null); session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setMask(null);
player.print("Brush mask disabled."); player.print("Brush mask disabled.");
@ -96,7 +98,7 @@ public class ToolUtilCommands {
max = 1 max = 1
) )
@CommandPermissions("worldedit.brush.options.material") @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); session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setFill(pattern);
player.print("Brush material set."); player.print("Brush material set.");
} }
@ -109,7 +111,7 @@ public class ToolUtilCommands {
max = 1 max = 1
) )
@CommandPermissions("worldedit.brush.options.range") @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); int range = args.getInteger(0);
session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setRange(range); session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setRange(range);
player.print("Brush range set."); player.print("Brush range set.");
@ -123,7 +125,9 @@ public class ToolUtilCommands {
max = 1 max = 1
) )
@CommandPermissions("worldedit.brush.options.size") @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); we.checkMaxBrushRadius(radius);
session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setSize(radius); session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setSize(radius);
player.print("Brush size set."); player.print("Brush size set.");

View File

@ -77,8 +77,12 @@ import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.CylinderRegion; import com.sk89q.worldedit.regions.CylinderRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.command.*;
import com.sk89q.worldedit.util.command.binding.Range; 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.binding.Text;
import com.sk89q.worldedit.util.command.parametric.Optional; import com.sk89q.worldedit.util.command.parametric.Optional;
import com.sk89q.worldedit.util.command.parametric.ParameterData; import com.sk89q.worldedit.util.command.parametric.ParameterData;
@ -283,28 +287,6 @@ public class UtilityCommands extends MethodCommands {
if (depth == -1) depth = Integer.MAX_VALUE; if (depth == -1) depth = Integer.MAX_VALUE;
int affected = editSession.fillXZ(pos, pattern, radius, (int) depth, true); int affected = editSession.fillXZ(pos, pattern, radius, (int) depth, true);
player.print(BBC.getPrefix() + affected + " block(s) have been created."); 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( @Command(
@ -435,8 +417,8 @@ public class UtilityCommands extends MethodCommands {
@CommandPermissions("worldedit.snow") @CommandPermissions("worldedit.snow")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void snow(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { 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; double size = args.argsLength() > 0 ? Math.max(1, args.getDouble(0)) : 10;
we.checkMaxRadius(size);
int affected = editSession.simulateSnow(session.getPlacementPosition(player), size); int affected = editSession.simulateSnow(session.getPlacementPosition(player), size);
player.print(BBC.getPrefix() + affected + " surfaces covered. Let it snow~"); player.print(BBC.getPrefix() + affected + " surfaces covered. Let it snow~");
@ -452,8 +434,8 @@ public class UtilityCommands extends MethodCommands {
@CommandPermissions("worldedit.thaw") @CommandPermissions("worldedit.thaw")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void thaw(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { 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; double size = args.argsLength() > 0 ? Math.max(1, args.getDouble(0)) : 10;
we.checkMaxRadius(size);
int affected = editSession.thaw(session.getPlacementPosition(player), size); int affected = editSession.thaw(session.getPlacementPosition(player), size);
player.print(BBC.getPrefix() + affected + " surfaces thawed."); player.print(BBC.getPrefix() + affected + " surfaces thawed.");
@ -463,6 +445,7 @@ public class UtilityCommands extends MethodCommands {
aliases = {"/green", "green"}, aliases = {"/green", "green"},
usage = "[radius]", usage = "[radius]",
desc = "Greens the area", desc = "Greens the area",
help = "Converts dirt to grass blocks. -f also converts coarse dirt.",
flags = "f", flags = "f",
min = 0, min = 0,
max = 1 max = 1
@ -470,8 +453,8 @@ public class UtilityCommands extends MethodCommands {
@CommandPermissions("worldedit.green") @CommandPermissions("worldedit.green")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void green(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { 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; final double size = args.argsLength() > 0 ? Math.max(1, args.getDouble(0)) : 10;
we.checkMaxRadius(size);
final boolean onlyNormalDirt = !args.hasFlag('f'); final boolean onlyNormalDirt = !args.hasFlag('f');
final int affected = editSession.green(session.getPlacementPosition(player), size); final int affected = editSession.green(session.getPlacementPosition(player), size);
@ -559,11 +542,7 @@ public class UtilityCommands extends MethodCommands {
List<? extends Entity> entities; List<? extends Entity> entities;
if (radius >= 0) { if (radius >= 0) {
CylinderRegion region = CylinderRegion.createRadius(editSession, center, radius); CylinderRegion region = CylinderRegion.createRadius(editSession, center, radius);
entities = editSession.getEntities(region);
} else { } else {
entities = editSession.getEntities();
}
visitors.add(new EntityVisitor(entities.iterator(), flags.createFunction()));
} else { } else {
Platform platform = worldEdit.getPlatformManager().queryCapability(Capability.WORLD_EDITING); Platform platform = worldEdit.getPlatformManager().queryCapability(Capability.WORLD_EDITING);
for (World world : platform.getWorlds()) { for (World world : platform.getWorlds()) {
@ -582,7 +561,7 @@ public class UtilityCommands extends MethodCommands {
if (editSession != null) { if (editSession != null) {
session.remember(editSession); session.remember(editSession);
editSession.flushQueue(); editSession.flushSession();
} }
} }
@ -642,7 +621,7 @@ public class UtilityCommands extends MethodCommands {
if (editSession != null) { if (editSession != null) {
session.remember(editSession); session.remember(editSession);
editSession.flushQueue(); editSession.flushSession();
} }
} }
@ -674,10 +653,10 @@ public class UtilityCommands extends MethodCommands {
actor.print(BBC.getPrefix() + "= " + result); actor.print(BBC.getPrefix() + "= " + result);
} catch (EvaluationException e) { } catch (EvaluationException e) {
actor.printError(String.format( 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) { } catch (ExpressionException e) {
actor.printError(String.format( actor.printError(String.format(
"'%s' could not be evaluated (error: %s)", input, e.getMessage())); "'%s' could not be parsed as a valid expression", input));
} }
} }

View File

@ -124,6 +124,31 @@ public class WorldEditCommands {
actor.print(BBC.getPrefix() + "Reloaded WorldEdit " + we.getVersion() + " and FAWE (" + Fawe.get().getVersion() + ")"); 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( @Command(
aliases = {"update"}, aliases = {"update"},
usage = "", usage = "",
@ -252,7 +277,7 @@ public class WorldEditCommands {
min = 0, min = 0,
max = 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.setCUISupport(true);
session.dispatchCUISetup(player); session.dispatchCUISetup(player);
} }

View File

@ -89,12 +89,14 @@ public class SelectionCommand extends SimpleCommand<Operation> {
LocalSession session = WorldEdit.getInstance().getSessionManager().get(player); LocalSession session = WorldEdit.getInstance().getSessionManager().get(player);
Region selection = session.getSelection(player.getWorld()); Region selection = session.getSelection(player.getWorld());
EditSession editSession = session.createEditSession(player); EditSession editSession = session.createEditSession(player);
editSession.enableQueue(); editSession.enableStandardMode();
locals.put(EditSession.class, editSession); locals.put(EditSession.class, editSession);
session.tellVersion(player); session.tellVersion(player);
EditContext editContext = new EditContext(); EditContext editContext = new EditContext();
editContext.setDestination(locals.get(EditSession.class)); editContext.setDestination(locals.get(EditSession.class));
editContext.setRegion(selection); editContext.setRegion(selection);
editContext.setSession(session);
Operation operation = operationFactory.createFromContext(editContext); Operation operation = operationFactory.createFromContext(editContext);
// Shortcut // Shortcut
if (selection instanceof CuboidRegion && editSession.hasFastMode() && operation instanceof RegionVisitor) { if (selection instanceof CuboidRegion && editSession.hasFastMode() && operation instanceof RegionVisitor) {

View File

@ -76,7 +76,8 @@ public class ShapedBrushCommand extends SimpleCommand<Object> {
WorldEdit.getInstance().checkMaxBrushRadius(radius); WorldEdit.getInstance().checkMaxBrushRadius(radius);
BrushTool tool = session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()); BrushTool tool = session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType());
tool.setSize(radius); 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) { } catch (MaxBrushRadiusException | InvalidToolBindException e) {
WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter().convert(e); WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter().convert(e);
} }

View File

@ -6,6 +6,9 @@ import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform; 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.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
@ -40,33 +43,21 @@ public class AreaPickaxe implements BlockTool {
return true; return true;
} }
EditSession editSession = session.createEditSession(player); try (EditSession editSession = session.createEditSession(player)) {
editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop); editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);
for (int x = ox - range; x <= ox + range; ++x) { for (int x = ox - range; x <= ox + range; ++x) {
for (int z = oz - range; z <= oz + range; ++z) { for (int z = oz - range; z <= oz + range; ++z) {
for (int y = oy + range; y >= oy - range; --y) { for (int y = oy + range; y >= oy - range; --y) {
if (initialType.equals(editSession.getLazyBlock(x, y, z))) { if (initialType.equals(editSession.getLazyBlock(x, y, z))) {
continue; 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()); editSession.setBlock(x, y, z, BlockTypes.AIR.getDefaultState());
} }
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
} finally {
session.remember(editSession);
} }
} }
editSession.flushQueue(); editSession.flushQueue();

View File

@ -25,13 +25,15 @@ import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag; 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 { public class BlockReplacer implements DoubleActionBlockTool {
@ -58,7 +60,6 @@ public class BlockReplacer implements DoubleActionBlockTool {
if (bag != null) { if (bag != null) {
bag.flushChanges(); bag.flushChanges();
} }
session.remember(editSession);
} }
return true; return true;

View File

@ -472,14 +472,6 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
MaskIntersection newMask = new MaskIntersection(existingMask); MaskIntersection newMask = new MaskIntersection(existingMask);
newMask.add(mask); newMask.add(mask);
editSession.setMask(newMask); 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(); Mask sourceMask = current.getSourceMask();

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.command.tool; package com.sk89q.worldedit.command.tool;
import com.boydti.fawe.object.collection.BlockVectorSet;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
@ -75,80 +76,26 @@ public class FloatingTreeRemover implements BlockTool {
player.printError("That's not a tree."); player.printError("That's not a tree.");
return true; return true;
} }
final EditSession editSession = session.createEditSession(player);
try /*(EditSession editSession = session.createEditSession(player))*/ {
final Set<BlockVector3> blockSet = bfs(world, clicked.toBlockPoint());
if (blockSet == null) {
player.printError("That's not a floating tree.");
return true;
}
for (BlockVector3 blockVector : blockSet) { try (EditSession editSession = session.createEditSession(player)) {
final BlockState otherState = editSession.getBlock(blockVector); try {
if (isTreeBlock(otherState.getBlockType())) { Pattern replace = BlockTypes.AIR;
editSession.setBlock(blockVector, BlockTypes.AIR.getDefaultState()); RecursiveVisitor visitor = new RecursiveVisitor(new BlockMask(editSession, logs, leaves), replace, 64, editSession);
} visitor.visit(pos);
} Operations.completeBlindly(visitor);
} catch (MaxChangedBlocksException e) { } finally {
player.printError("Max blocks change limit reached."); session.remember(editSession);
} finally { }
session.remember(editSession);
} }
return true; return true;
} }
private BlockVector3[] recurseDirections = { private BlockVector3[] recurseDirections = {
Direction.NORTH.toBlockVector(),
Direction.EAST.toBlockVector(), Direction.EAST.toBlockVector(),
Direction.SOUTH.toBlockVector(), Direction.SOUTH.toBlockVector(),
Direction.WEST.toBlockVector(), Direction.WEST.toBlockVector(),
Direction.UP.toBlockVector(), Direction.UP.toBlockVector(),
Direction.DOWN.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<BlockVector3> bfs(World world, BlockVector3 origin) throws MaxChangedBlocksException {
final Set<BlockVector3> visited = new HashSet<>();
final LinkedList<BlockVector3> 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;
}
} }

View File

@ -69,17 +69,16 @@ public class FloodFillTool implements BlockTool {
return true; return true;
} }
EditSession editSession = session.createEditSession(player); try (EditSession editSession = session.createEditSession(player)) {
try { try {
recurse(editSession, origin, origin, range, initialType, new HashSet<>()); TODO fillDirection (but replace)
} catch (MaxChangedBlocksException e) { recurse(editSession, origin, origin, range, initialType, new HashSet<>());
player.printError("Max blocks change limit reached."); } catch (MaxChangedBlocksException e) {
} finally { player.printError("Max blocks change limit reached.");
session.remember(editSession); } finally {
session.remember(editSession);
}
} }
editSession.flushQueue();
session.remember(editSession);
return true; return true;
} }

View File

@ -55,10 +55,8 @@ public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTo
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session) { public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
Location pos = getTargetFace(player); Location pos = getTargetFace(player);
if (pos == null) return false; if (pos == null) return false;
EditSession eS = session.createEditSession(player); try (EditSession eS = session.createEditSession(player)) {
try { BlockVector3 blockPoint = pos.toVector().toBlockPoint();
// eS.disableBuffering();
BlockVector3 blockPoint = pos.toBlockPoint();
BaseBlock applied = secondary.apply(blockPoint); BaseBlock applied = secondary.apply(blockPoint);
if (applied.getBlockType().getMaterial().isAir()) { if (applied.getBlockType().getMaterial().isAir()) {
eS.setBlock(blockPoint, secondary); eS.setBlock(blockPoint, secondary);
@ -74,12 +72,7 @@ public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTo
@Override @Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session) { public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session) {
Location pos = getTargetFace(player); try (EditSession eS = session.createEditSession(player)) {
if (pos == null) return false;
EditSession eS = session.createEditSession(player);
try {
// eS.disableBuffering();
BlockVector3 blockPoint = pos.toBlockPoint(); BlockVector3 blockPoint = pos.toBlockPoint();
BaseBlock applied = primary.apply(blockPoint); BaseBlock applied = primary.apply(blockPoint);
if (applied.getBlockType().getMaterial().isAir()) { if (applied.getBlockType().getMaterial().isAir()) {

View File

@ -53,7 +53,6 @@ public class RecursivePickaxe implements BlockTool {
editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop); editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);
//<<<<<<< HEAD
final int radius = (int) range; final int radius = (int) range;
final BlockReplace replace = new BlockReplace(editSession, (editSession.nullBlock)); final BlockReplace replace = new BlockReplace(editSession, (editSession.nullBlock));
editSession.setMask((Mask) null); editSession.setMask((Mask) null);
@ -63,51 +62,6 @@ public class RecursivePickaxe implements BlockTool {
editSession.flushQueue(); editSession.flushQueue();
session.remember(editSession); 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; return true;
} }
// private static void recurse(Platform server, EditSession editSession, World world, BlockVector3 pos,
// BlockVector3 origin, double size, BlockType initialType, Set<BlockVector3> 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);
// }
} }

View File

@ -50,24 +50,12 @@ public class SinglePickaxe implements BlockTool {
&& !player.canDestroyBedrock()) { && !player.canDestroyBedrock()) {
return true; return true;
} }
final EditSession editSession = session.createEditSession(player);
try { try (EditSession editSession = session.createEditSession(player)) {
editSession.getSurvivalExtent().setToolUse(config.superPickaxeDrop); editSession.getSurvivalExtent().setToolUse(config.superPickaxeDrop);
editSession.setBlock(blockPoint, BlockTypes.AIR.getDefaultState()); 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); session.remember(editSession);
} }
return true; return true;
} }

View File

@ -48,16 +48,15 @@ public class TreePlanter implements BlockTool {
@Override @Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked) { public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked) {
EditSession editSession = session.createEditSession(player); try (EditSession editSession = session.createEditSession(player)) {
try {
boolean successful = false; boolean successful = false;
for (int i = 0; i < 10; i++) {
if (treeType.generate(editSession, clicked.add(0, 1, 0).toBlockPoint())) { for (int i = 0; i < 10; i++) {
successful = true; if (treeType.generate(editSession, clicked.add(0, 1, 0).toBlockPoint())) {
break; successful = true;
} break;
} }
}
if (!successful) { if (!successful) {
player.printError("A tree can't go there."); player.printError("A tree can't go there.");

View File

@ -21,10 +21,10 @@ package com.sk89q.worldedit.command.tool.brush;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; 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.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern; 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 { public class CylinderBrush implements Brush {

View File

@ -21,12 +21,14 @@ package com.sk89q.worldedit.command.tool.brush;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; 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.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3; 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 { public class GravityBrush implements Brush {

View File

@ -24,6 +24,7 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
public class HollowCylinderBrush implements Brush { public class HollowCylinderBrush implements Brush {

View File

@ -24,6 +24,7 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
public class HollowSphereBrush implements Brush { public class HollowSphereBrush implements Brush {

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.command.tool.brush; package com.sk89q.worldedit.command.tool.brush;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.function.Contextual; import com.sk89q.worldedit.function.Contextual;
import com.sk89q.worldedit.function.EditContext; import com.sk89q.worldedit.function.EditContext;
@ -33,10 +34,16 @@ public class OperationFactoryBrush implements Brush {
private final Contextual<? extends Operation> operationFactory; private final Contextual<? extends Operation> operationFactory;
private final RegionFactory regionFactory; private final RegionFactory regionFactory;
private final LocalSession session;
public OperationFactoryBrush(Contextual<? extends Operation> operationFactory, RegionFactory regionFactory) { 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.operationFactory = operationFactory;
this.regionFactory = regionFactory; this.regionFactory = regionFactory;
this.session = session;
} }
@Override @Override
@ -45,6 +52,7 @@ public class OperationFactoryBrush implements Brush {
context.setDestination(editSession); context.setDestination(editSession);
context.setRegion(regionFactory.createCenteredAt(position, size)); context.setRegion(regionFactory.createCenteredAt(position, size));
context.setFill(pattern); context.setFill(pattern);
context.setSession(session);
Operation operation = operationFactory.createFromContext(context); Operation operation = operationFactory.createFromContext(context);
Operations.completeLegacy(operation); Operations.completeLegacy(operation);
} }

View File

@ -21,9 +21,10 @@ package com.sk89q.worldedit.command.tool.brush;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; 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.BlockVector3;
import com.sk89q.worldedit.math.Vector3; 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.GaussianKernel;
import com.sk89q.worldedit.math.convolution.HeightMap; import com.sk89q.worldedit.math.convolution.HeightMap;
import com.sk89q.worldedit.math.convolution.HeightMapFilter; 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.regions.Region;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import javax.annotation.Nullable;
public class SmoothBrush implements Brush { public class SmoothBrush implements Brush {
private final Mask mask;
private int iterations; private int iterations;
public SmoothBrush(int iterations) { public SmoothBrush(int iterations) {
this(iterations, null);
}
public SmoothBrush(int iterations, @Nullable Mask mask) {
this.iterations = iterations; this.iterations = iterations;
this.mask = mask;
} }
@Override @Override
@ -45,7 +54,7 @@ public class SmoothBrush implements Brush {
Location min = new Location(editSession.getWorld(), posDouble.subtract(size, size, size)); Location min = new Location(editSession.getWorld(), posDouble.subtract(size, size, size));
BlockVector3 max = posDouble.add(size, size + 10, size).toBlockPoint(); BlockVector3 max = posDouble.add(size, size + 10, size).toBlockPoint();
Region region = new CuboidRegion(editSession.getWorld(), min.toBlockPoint(), max); 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)); HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1.0));
heightMap.applyFilter(filter, iterations); heightMap.applyFilter(filter, iterations);
} }

View File

@ -21,9 +21,9 @@ package com.sk89q.worldedit.command.tool.brush;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
public class SphereBrush implements Brush { public class SphereBrush implements Brush {

View File

@ -20,9 +20,6 @@
package com.sk89q.worldedit.event.extent; package com.sk89q.worldedit.event.extent;
import com.sk89q.worldedit.EditSession; 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.event.Event;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;

View File

@ -21,7 +21,6 @@ package com.sk89q.worldedit.extension.factory;
import com.sk89q.util.StringUtil; import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.WorldEdit; 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.factory.parser.DefaultBlockParser;
import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.input.ParserContext;

View File

@ -55,14 +55,7 @@ public final class MaskFactory extends AbstractFactory<Mask> {
*/ */
public MaskFactory(WorldEdit worldEdit) { public MaskFactory(WorldEdit worldEdit) {
super(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 BlockCategoryMaskParser(worldEdit));
register(new NoiseMaskParser(worldEdit));
register(new NegateMaskParser(worldEdit));
register(new DefaultMaskParser(worldEdit)); register(new DefaultMaskParser(worldEdit));
} }
@ -90,7 +83,7 @@ public final class MaskFactory extends AbstractFactory<Mask> {
case 1: case 1:
return masks.get(0); return masks.get(0);
default: default:
return new MaskIntersection(masks); return new MaskIntersection(masks).optimize();
} }
} }

View File

@ -22,9 +22,10 @@ package com.sk89q.worldedit.extension.factory;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.factory.parser.pattern.BlockCategoryPatternParser; 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.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.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.SingleBlockPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.TypeOrStateApplyingPatternParser;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.registry.AbstractFactory; import com.sk89q.worldedit.internal.registry.AbstractFactory;
@ -44,10 +45,6 @@ public final class PatternFactory extends AbstractFactory<Pattern> {
*/ */
public PatternFactory(WorldEdit worldEdit) { public PatternFactory(WorldEdit worldEdit) {
super(worldEdit); super(worldEdit);
// register(new ClipboardPatternParser(worldEdit));
// register(new SingleBlockPatternParser(worldEdit));
// register(new RandomPatternParser(worldEdit));
register(new BlockCategoryPatternParser(worldEdit)); register(new BlockCategoryPatternParser(worldEdit));
register(new DefaultPatternParser(worldEdit)); register(new DefaultPatternParser(worldEdit));
} }

View File

@ -24,12 +24,6 @@ import com.boydti.fawe.jnbt.JSON2NBT;
import com.boydti.fawe.jnbt.NBTException; import com.boydti.fawe.jnbt.NBTException;
import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.StringMan; 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.IncompleteRegionException;
import com.sk89q.worldedit.NotABlockException; import com.sk89q.worldedit.NotABlockException;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;

View File

@ -0,0 +1,65 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
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<Mask> {
public BiomeMaskParser(WorldEdit worldEdit) {
super(worldEdit);
}
@Override
public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
if (!input.startsWith("$")) {
return null;
}
Set<BiomeType> biomes = new HashSet<>();
BiomeRegistry biomeRegistry = worldEdit.getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBiomeRegistry();
Collection<BiomeType> 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));
}
}

View File

@ -22,12 +22,10 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext; 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.BlockCategoryMask;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.internal.registry.InputParser; import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.session.request.Request; import com.sk89q.worldedit.session.request.RequestExtent;
import com.sk89q.worldedit.world.block.BlockCategories;
import com.sk89q.worldedit.world.block.BlockCategory; import com.sk89q.worldedit.world.block.BlockCategory;
public class BlockCategoryMaskParser extends InputParser<Mask> { public class BlockCategoryMaskParser extends InputParser<Mask> {
@ -38,18 +36,16 @@ public class BlockCategoryMaskParser extends InputParser<Mask> {
@Override @Override
public Mask parseFromInput(String input, ParserContext context) throws InputParseException { public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
if (input.startsWith("##")) { if (!input.startsWith("##")) {
Extent extent = Request.request().getEditSession(); return null;
// 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);
}
} }
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);
}
} }
} }

View File

@ -0,0 +1,53 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
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<Mask> {
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);
}
}
}

View File

@ -0,0 +1,59 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
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<Mask> {
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<BaseBlock> holders = worldEdit.getBlockFactory().parseFromListInput(component, tempContext);
if (holders.isEmpty()) {
return null;
}
return new BlockMask(new RequestExtent(), holders);
} catch (NoMatchException e) {
return null;
}
}
}

View File

@ -21,13 +21,11 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext; 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.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.internal.registry.SimpleInputParser; 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; import java.util.List;
@ -43,9 +41,7 @@ public class ExistingMaskParser extends SimpleInputParser<Mask> {
} }
@Override @Override
public Mask parseFromSimpleInput(String input, ParserContext context) throws InputParseException { public Mask parseFromSimpleInput(String input, ParserContext context) {
Extent extent = Request.request().getEditSession(); return new ExistingBlockMask(new RequestExtent());
return new ExistingBlockMask(extent);
} }
} }

View File

@ -0,0 +1,65 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
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<Mask> {
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());
}
}
}

View File

@ -0,0 +1,56 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
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<Mask> {
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));
}
}

View File

@ -21,13 +21,11 @@ package com.sk89q.worldedit.extension.factory.parser.mask;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext; 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.Mask;
import com.sk89q.worldedit.function.mask.SolidBlockMask; import com.sk89q.worldedit.function.mask.SolidBlockMask;
import com.sk89q.worldedit.internal.registry.SimpleInputParser; 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; import java.util.List;
@ -43,9 +41,7 @@ public class SolidMaskParser extends SimpleInputParser<Mask> {
} }
@Override @Override
public Mask parseFromSimpleInput(String input, ParserContext context) throws InputParseException { public Mask parseFromSimpleInput(String input, ParserContext context) {
Extent extent = Request.request().getEditSession(); return new SolidBlockMask(new RequestExtent());
return new SolidBlockMask(extent);
} }
} }

View File

@ -26,11 +26,11 @@ import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.RandomPattern; import com.sk89q.worldedit.function.pattern.RandomPattern;
import com.sk89q.worldedit.internal.registry.InputParser; 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.BlockCategory;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class BlockCategoryPatternParser extends InputParser<Pattern> { public class BlockCategoryPatternParser extends InputParser<Pattern> {
@ -46,17 +46,34 @@ public class BlockCategoryPatternParser extends InputParser<Pattern> {
@Override @Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException { public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
if(!input.startsWith("##")) { if (!input.startsWith("##")) {
return null; 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) { if (category == null) {
throw new InputParseException("Unknown block tag: " + input.substring(2)); throw new InputParseException("Unknown block tag: " + tag);
} }
RandomPattern randomPattern = new RandomPattern(); RandomPattern randomPattern = new RandomPattern();
for (BlockType blockType : category.getAll()) { Set<BlockType> blocks = category.getAll();
randomPattern.add(new BlockPattern(blockType.getDefaultState()), 1.0 / category.getAll().size()); 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; return randomPattern;

View File

@ -19,189 +19,68 @@
package com.sk89q.worldedit.extension.factory.parser.pattern; 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.google.common.collect.Lists;
import com.sk89q.worldedit.EmptyClipboardException; import com.sk89q.worldedit.EmptyClipboardException;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.PatternCommands;
import com.sk89q.worldedit.extension.input.InputParseException; 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.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.Pattern;
import com.sk89q.worldedit.function.pattern.RandomPattern; import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.internal.command.ActorAuthorizer; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.internal.command.WorldEditBinding; import com.sk89q.worldedit.session.ClipboardHolder;
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 java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ClipboardPatternParser extends FaweParser<Pattern> { public class ClipboardPatternParser extends InputParser<Pattern> {
private final Dispatcher dispatcher;
public ClipboardPatternParser(WorldEdit worldEdit) { public ClipboardPatternParser(WorldEdit worldEdit) {
super(worldEdit); super(worldEdit);
this.dispatcher = new SimpleDispatcher();
this.register(new PatternCommands(worldEdit));
} }
@Override @Override
public Dispatcher getDispatcher() { public List<String> getSuggestions() {
return dispatcher; return Lists.newArrayList("#clipboard", "#copy");
}
public void register(Object clazz) {
ParametricBuilder builder = new ParametricBuilder();
builder.setAuthorizer(new ActorAuthorizer());
builder.addBinding(new WorldEditBinding(worldEdit));
builder.registerMethodsAsCommands(dispatcher, clazz);
} }
@Override @Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException { public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
if (input.isEmpty()) { String[] offsetParts = input.split("@", 2);
throw new SuggestInputParseException("No input provided", "", () -> Stream.concat(Stream.of("#", ",", "&"), BlockTypes.getNameSpaces().stream().map(n -> n + ":")).collect(Collectors.toList())); if (!offsetParts[0].equalsIgnoreCase("#clipboard") && !offsetParts[0].equalsIgnoreCase("#copy")) {
}
List<Double> chances = new ArrayList<>();
List<Pattern> 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<ParseEntry, List<String>> 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<String> 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<String> 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()) {
return null; 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 { } else {
RandomPattern random = new RandomPattern(new TrueRandom()); throw new InputParseException("No session is available, so no clipboard is available");
for (int i = 0; i < patterns.size(); i++) { }
random.add(patterns.get(i), chances.get(i));
}
return random;
}
} }
} }

View File

@ -24,11 +24,11 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.factory.BlockFactory; import com.sk89q.worldedit.extension.factory.BlockFactory;
import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext; 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.Pattern;
import com.sk89q.worldedit.function.pattern.RandomPattern; import com.sk89q.worldedit.function.pattern.RandomPattern;
import com.sk89q.worldedit.internal.registry.InputParser; import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.world.block.BaseBlock;
import java.util.List;
public class RandomPatternParser extends InputParser<Pattern> { public class RandomPatternParser extends InputParser<Pattern> {
@ -38,14 +38,16 @@ public class RandomPatternParser extends InputParser<Pattern> {
@Override @Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException { public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
BlockFactory blockRegistry = worldEdit.getBlockFactory();
RandomPattern randomPattern = new RandomPattern(); RandomPattern randomPattern = new RandomPattern();
String[] splits = input.split(","); String[] splits = input.split(",");
for (String token : StringUtil.parseListInQuotes(splits, ',', '[', ']')) { List<String> patterns = StringUtil.parseListInQuotes(splits, ',', '[', ']');
BaseBlock block; if (patterns.size() == 1) {
return null; // let a 'single'-pattern parser handle it
}
for (String token : patterns) {
double chance; double chance;
Pattern innerPattern;
// Parse special percentage syntax // Parse special percentage syntax
if (token.matches("[0-9]+(\\.[0-9]*)?%.*")) { if (token.matches("[0-9]+(\\.[0-9]*)?%.*")) {
@ -55,14 +57,14 @@ public class RandomPatternParser extends InputParser<Pattern> {
throw new InputParseException("Missing the type after the % symbol for '" + input + "'"); throw new InputParseException("Missing the type after the % symbol for '" + input + "'");
} else { } else {
chance = Double.parseDouble(p[0]); chance = Double.parseDouble(p[0]);
block = blockRegistry.parseFromInput(p[1], context); innerPattern = worldEdit.getPatternFactory().parseFromInput(p[1], context);
} }
} else { } else {
chance = 1; chance = 1;
block = blockRegistry.parseFromInput(token, context); innerPattern = worldEdit.getPatternFactory().parseFromInput(token, context);
} }
randomPattern.add(block, chance); randomPattern.add(innerPattern, chance);
} }
return randomPattern; return randomPattern;

View File

@ -0,0 +1,56 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
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<Pattern> {
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
}
}
}

View File

@ -34,13 +34,7 @@ public class SingleBlockPatternParser extends InputParser<Pattern> {
@Override @Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException { public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
String[] items = input.split(","); return new BlockPattern(worldEdit.getBlockFactory().parseFromInput(input, context));
if (items.length == 1) {
return new BlockPattern(worldEdit.getBlockFactory().parseFromInput(items[0], context));
} else {
return null;
}
} }
} }

View File

@ -0,0 +1,79 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <http://www.gnu.org/licenses/>.
*/
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<Pattern> {
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<String, String> 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);
}
}
}
}

View File

@ -19,8 +19,8 @@
package com.sk89q.worldedit.extension.platform; package com.sk89q.worldedit.extension.platform;
import com.sk89q.worldedit.NotABlockException;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.internal.cui.CUIEvent; 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.Location;
import com.sk89q.worldedit.util.TargetBlock; import com.sk89q.worldedit.util.TargetBlock;
import com.sk89q.worldedit.util.auth.AuthorizationException; 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.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; 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 BlockVector3 pos = BlockVector3.at(x, y - 2, z);
final BlockStateHolder state = world.getBlock(pos); 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 + BlockTypeUtil.centralTopLimit(state), z + 0.5));
// setPosition(Vector3.at(x + 0.5, y - 2 + 1, z + 0.5));
} }
return; return;

View File

@ -43,9 +43,10 @@ import com.sk89q.worldedit.command.composition.ApplyCommand;
import com.sk89q.worldedit.command.composition.DeformCommand; import com.sk89q.worldedit.command.composition.DeformCommand;
import com.sk89q.worldedit.command.composition.PaintCommand; import com.sk89q.worldedit.command.composition.PaintCommand;
import com.sk89q.worldedit.command.composition.ShapedBrushCommand; 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.CommandEvent;
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent; 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;
import com.sk89q.worldedit.function.factory.Deform.Mode; import com.sk89q.worldedit.function.factory.Deform.Mode;
import com.sk89q.worldedit.internal.command.*; 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.eventbus.Subscribe;
import com.sk89q.worldedit.util.logging.DynamicStreamHandler; import com.sk89q.worldedit.util.logging.DynamicStreamHandler;
import com.sk89q.worldedit.util.logging.LogFormat; 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 javax.annotation.Nullable;
import java.io.File; import java.io.File;
@ -72,7 +76,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.logging.FileHandler; import java.util.logging.FileHandler;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static com.google.common.base.Preconditions.checkNotNull; 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 final class CommandManager {
public static final Pattern COMMAND_CLEAN_PATTERN = Pattern.compile("^[/]+"); public static final Pattern COMMAND_CLEAN_PATTERN = Pattern.compile("^[/]+");
private static final Logger log = Logger.getLogger(CommandManager.class.getCanonicalName()); private static final Logger log = LoggerFactory.getLogger(CommandManager.class);
private static final Logger commandLog = Logger.getLogger(CommandManager.class.getCanonicalName() + ".CommandLog"); 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 static final Pattern numberFormatExceptionPattern = Pattern.compile("^For input string: \"(.*)\"$");
private final WorldEdit worldEdit; private final WorldEdit worldEdit;
@ -297,7 +301,7 @@ public final class CommandManager {
} }
public void register(Platform platform) { 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; this.platform = null;
try { try {
@ -318,12 +322,12 @@ public final class CommandManager {
File file = new File(config.getWorkingDirectory(), path); File file = new File(config.getWorkingDirectory(), path);
commandLog.setLevel(Level.ALL); commandLog.setLevel(Level.ALL);
log.log(Level.INFO, "Logging WorldEdit commands to " + file.getAbsolutePath()); log.info("Logging WorldEdit commands to " + file.getAbsolutePath());
try { try {
dynamicHandler.setHandler(new FileHandler(file.getAbsolutePath(), true)); dynamicHandler.setHandler(new FileHandler(file.getAbsolutePath(), true));
} catch (IOException e) { } 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); actor = FakePlayer.wrap(actor.getName(), actor.getUniqueId(), actor);
} }
final LocalSession session = worldEdit.getSessionManager().get(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(); LocalConfiguration config = worldEdit.getConfiguration();
final CommandLocals locals = new CommandLocals(); final CommandLocals locals = new CommandLocals();
final FawePlayer fp = FawePlayer.wrap(actor); final FawePlayer fp = FawePlayer.wrap(actor);
@ -497,8 +508,8 @@ public final class CommandManager {
if (time > 1000) { if (time > 1000) {
BBC.ACTION_COMPLETE.send(actor, (time / 1000d)); BBC.ACTION_COMPLETE.send(actor, (time / 1000d));
} }
Request.reset();
} }
Request.reset();
} }
return null; return null;
} }
@ -552,7 +563,7 @@ public final class CommandManager {
return dispatcher; return dispatcher;
} }
public static Logger getLogger() { public static java.util.logging.Logger getLogger() {
return commandLog; return commandLog;
} }

View File

@ -28,14 +28,10 @@ import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.wrappers.LocationMaskedPlayerWrapper; import com.boydti.fawe.wrappers.LocationMaskedPlayerWrapper;
import com.boydti.fawe.wrappers.PlayerWrapper; import com.boydti.fawe.wrappers.PlayerWrapper;
import com.boydti.fawe.wrappers.WorldWrapper; 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.LocalConfiguration;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.tool.BlockTool; 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.DoubleActionTraceTool;
import com.sk89q.worldedit.command.tool.Tool; import com.sk89q.worldedit.command.tool.Tool;
import com.sk89q.worldedit.command.tool.TraceTool; 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.event.platform.*;
import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits; import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.RegionSelector; import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.session.request.Request; 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.util.eventbus.Subscribe;
import com.sk89q.worldedit.world.World; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.*; import java.util.ArrayList;
import java.util.Map.Entry; import java.util.EnumMap;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.Iterator;
import java.util.logging.Level; import java.util.List;
import java.util.logging.Logger; import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* Manages registered {@link Platform}s for WorldEdit. Platforms are * Manages registered {@link Platform}s for WorldEdit. Platforms are
* implementations of WorldEdit. * implementations of WorldEdit.
* <p>
* <p>This class is thread-safe.</p> * <p>This class is thread-safe.</p>
*/ */
public class PlatformManager { 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 WorldEdit worldEdit;
private final CommandManager commandManager; private final CommandManager commandManager;
@ -99,7 +93,7 @@ public class PlatformManager {
public synchronized void register(Platform platform) { public synchronized void register(Platform platform) {
checkNotNull(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 // Just add the platform to the list of platforms: we'll pick favorites
// once all the platforms have been loaded // once all the platforms have been loaded
@ -108,7 +102,7 @@ public class PlatformManager {
// Make sure that versions are in sync // Make sure that versions are in sync
if (firstSeenVersion != null) { if (firstSeenVersion != null) {
if (!firstSeenVersion.equals(platform.getVersion())) { 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.", "If these two versions are truly different, then you may run into unexpected crashes and errors.",
new Object[]{firstSeenVersion, platform.getVersion()}); new Object[]{firstSeenVersion, platform.getVersion()});
} }
@ -131,7 +125,7 @@ public class PlatformManager {
boolean removed = platforms.remove(platform); boolean removed = platforms.remove(platform);
if (removed) { if (removed) {
logger.log(Level.FINE, "Unregistering " + platform.getClass().getCanonicalName() + " from WorldEdit"); logger.info("Unregistering " + platform.getClass().getCanonicalName() + " from WorldEdit");
boolean choosePreferred = false; boolean choosePreferred = false;
@ -356,7 +350,6 @@ public class PlatformManager {
return; return;
} }
} }
//<<<<<<< HEAD
final Tool tool = session.getTool(playerActor); final Tool tool = session.getTool(playerActor);
if (tool != null && tool instanceof DoubleActionBlockTool) { if (tool != null && tool instanceof DoubleActionBlockTool) {
if (tool.canUse(playerActor)) { if (tool.canUse(playerActor)) {
@ -371,14 +364,6 @@ public class PlatformManager {
event.setCancelled(true); event.setCancelled(true);
return; 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) { } else if (event.getType() == Interaction.OPEN) {
if (session.isToolControlEnabled() && playerActor.getItemInHand(HandSide.MAIN_HAND).getType().getId().equals(getConfiguration().wandItem)) { if (session.isToolControlEnabled() && playerActor.getItemInHand(HandSide.MAIN_HAND).getType().getId().equals(getConfiguration().wandItem)) {
@ -402,7 +387,6 @@ public class PlatformManager {
return; return;
} }
//<<<<<<< HEAD
final Tool tool = session.getTool(playerActor); final Tool tool = session.getTool(playerActor);
if (tool != null && tool instanceof BlockTool) { if (tool != null && tool instanceof BlockTool) {
if (tool.canUse(playerActor)) { if (tool.canUse(playerActor)) {
@ -423,25 +407,10 @@ public class PlatformManager {
return; 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) { } catch (Throwable e) {
handleThrowable(e, actor); handleThrowable(e, actor);
@ -559,6 +528,8 @@ public class PlatformManager {
player.printRaw(e.getClass().getName() + ": " + e.getMessage()); player.printRaw(e.getClass().getName() + ": " + e.getMessage());
MainUtil.handleError(e); MainUtil.handleError(e);
} }
} finally {
Request.reset();
} }
} }

Some files were not shown because too many files have changed in this diff Show More