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 {
resolutionStrategy {
force 'com.google.guava:guava:21.0'
force 'org.ow2.asm:asm:6.0_BETA'
force 'commons-io:commons-io:2.4'
}
}
dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.4'
classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.7.5'
classpath 'org.ajoberstar:gradle-git:1.7.2'
classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.8.1'
}
}
plugins {
id 'net.minecrell.licenser' version '0.4.1' apply false
id "org.ajoberstar.grgit" version "2.3.0"
}
apply plugin: 'java'

View File

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

View File

@ -15,6 +15,7 @@
<allow pkg="com.google.gson"/>
<allow pkg="net.royawesome.jlibnoise"/>
<allow pkg="org.json.simple" />
<allow pkg="org.slf4j"/>
<subpackage name="util.yaml">
<allow pkg="org.yaml.snakeyaml"/>
@ -53,6 +54,7 @@
<allow pkg="org.lwjgl"/>
<allow pkg="io.netty.buffer"/>
<allow pkg="org.spongepowered.api" />
<allow pkg="com.mojang.brigadier" />
</subpackage>
<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
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -19,15 +19,25 @@
package com.sk89q.worldedit.bukkit;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Function;
import com.sk89q.worldedit.NotABlockException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.IBukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.SimpleBukkitAdapter;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
@ -37,6 +47,7 @@ import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.item.ItemType;
import org.bukkit.Material;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@ -122,6 +133,26 @@ public enum BukkitAdapter {
return getAdapter().adapt(gameMode);
}
/**
* Create a WorldEdit BiomeType from a Bukkit one.
*
* @param biome Bukkit Biome
* @return WorldEdit BiomeType
*/
public static BiomeType adapt(Biome biome) {
return getAdapter().adapt(biome);
}
public static Biome adapt(BiomeType biomeType) {
getAdapter().adapt(biomeType);
}
/**
* Create a WorldEdit EntityType from a Bukkit one.
*
* @param entityType Bukkit EntityType
* @return WorldEdit EntityType
*/
public static EntityType adapt(org.bukkit.entity.EntityType entityType) {
return getAdapter().adapt(entityType);
}
@ -146,6 +177,12 @@ public enum BukkitAdapter {
return getAdapter().adapt(material);
}
/**
* Create a Bukkit BlockData from a WorldEdit BlockStateHolder
*
* @param block The WorldEdit BlockStateHolder
* @return The Bukkit BlockData
*/
public static <B extends BlockStateHolder<B>> BlockData adapt(B block) {
return getAdapter().adapt(block);
}

View File

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

View File

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

View File

@ -19,8 +19,6 @@
package com.sk89q.worldedit.bukkit;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.bukkit.util.CommandInspector;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.extension.platform.Actor;
@ -29,12 +27,14 @@ import com.sk89q.worldedit.util.command.Description;
import com.sk89q.worldedit.util.command.Dispatcher;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.logging.Logger;
import static com.google.common.base.Preconditions.checkNotNull;
class BukkitCommandInspector implements CommandInspector {
private static final Logger logger = Logger.getLogger(BukkitCommandInspector.class.getCanonicalName());
private static final Logger logger = LoggerFactory.getLogger(BukkitCommandInspector.class);
private final WorldEditPlugin plugin;
private final Dispatcher dispatcher;
@ -51,7 +51,7 @@ class BukkitCommandInspector implements CommandInspector {
if (mapping != null) {
return mapping.getDescription().getDescription();
} else {
logger.warning("BukkitCommandInspector doesn't know how about the command '" + command + "'");
logger.warn("BukkitCommandInspector doesn't know how about the command '" + command + "'");
return "Help text not available";
}
}
@ -63,7 +63,7 @@ class BukkitCommandInspector implements CommandInspector {
Description description = mapping.getDescription();
return "Usage: " + description.getUsage() + (description.getHelp() != null ? "\n" + description.getHelp() : "");
} else {
logger.warning("BukkitCommandInspector doesn't know how about the command '" + command + "'");
logger.warn("BukkitCommandInspector doesn't know how about the command '" + command + "'");
return "Help text not available";
}
}
@ -76,7 +76,7 @@ class BukkitCommandInspector implements CommandInspector {
locals.put(Actor.class, plugin.wrapCommandSender(sender));
return mapping.getCallable().testPermission(locals);
} else {
logger.warning("BukkitCommandInspector doesn't know how about the command '" + command + "'");
logger.warn("BukkitCommandInspector doesn't know how about the command '" + command + "'");
return false;
}
}

View File

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

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) {
return getCategorisedByName(category.getId());
}
}
}

View File

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

View File

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

View File

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

View File

@ -19,6 +19,8 @@
package com.sk89q.worldedit.bukkit;
import com.bekvon.bukkit.residence.commands.message;
import com.bekvon.bukkit.residence.containers.cmd;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.bukkit.FaweBukkit;
import com.boydti.fawe.bukkit.adapter.v1_13_1.Spigot_v1_13_R2;
@ -34,32 +36,49 @@ import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplLoader;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.NoCapablePlatformException;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockCategory;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.FuzzyBlockState;
import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.item.ItemCategory;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Biome;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.*;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import static com.google.common.base.Preconditions.checkNotNull;
@ -70,7 +89,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
{
private static final Logger log = Logger.getLogger("FastAsyncWorldEdit");
private static final Logger log = LoggerFactory.getLogger(WorldEditPlugin.class);
public static final String CUI_PLUGIN_CHANNEL = "worldedit:cui";
private static WorldEditPlugin INSTANCE;
@ -139,13 +158,9 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
return CUI_PLUGIN_CHANNEL;
}
/**
* Called on plugin enable.
*/
@SuppressWarnings("AccessStaticViaInstance")
@Override
public void onEnable() {
rename();
public void onLoad() {
rename();
this.INSTANCE = this;
FaweBukkit imp = new FaweBukkit(this);
@ -163,6 +178,16 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
loadConfig(); // Load configuration
fail(() -> PermissionsResolverManager.initialize(INSTANCE), "Failed to initialize permissions resolver");
}
/**
* Called on plugin enable.
*/
@Override
public void onEnable() {
setupTags(); // these have to be done post-world since they rely on MC registries. the other ones just use Bukkit enums
PermissionsResolverManager.initialize(this); // Setup permission resolver
// Register CUI
fail(() -> {
@ -178,9 +203,6 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
// platforms to be worried about... at the current time of writing
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
// Setup the BukkitImplementationTester.
BukkitImplementationTester.getImplementation();
{ // Register 1.13 Material ids with LegacyMapper
LegacyMapper legacyMapper = LegacyMapper.getInstance();
for (Material m : Material.values()) {
@ -191,6 +213,20 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
}
}
private void setupTags() {
// Tags
try {
for (Tag<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() {
// {
// PluginDescriptionFile desc = getDescription();
@ -221,7 +257,7 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
}
}
{
Logger logger = getLogger();
java.util.logging.Logger logger = getLogger();
if (logger != null) {
try {
Field nameField = Logger.class.getDeclaredField("name");
@ -245,7 +281,7 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
e.printStackTrace();
}
}
log.log(Level.INFO, "Please restart the server if you have any plugins which depend on FAWE.");
log.info("Please restart the server if you have any plugins which depend on FAWE.");
}
}
@ -253,7 +289,7 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
try {
run.run();
} catch (Throwable e) {
log.log(Level.SEVERE, message);
log.error(message);
e.printStackTrace();
}
}
@ -264,7 +300,7 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "config-legacy.yml"), true), this);
config.load();
} catch (Throwable e) {
log.log(Level.SEVERE, "Failed to load config.yml");
log.error("Failed to load config.yml");
e.printStackTrace();
}
// Create schematics folder
@ -287,30 +323,30 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
try {
adapterLoader.addFromPath(getClass().getClassLoader());
} catch (IOException e) {
log.log(Level.WARNING, "Failed to search path for Bukkit adapters");
log.warn("Failed to search path for Bukkit adapters");
}
try {
adapterLoader.addFromJar(getFile());
} catch (IOException e) {
log.log(Level.WARNING, "Failed to search " + getFile() + " for Bukkit adapters", e);
log.warn("Failed to search " + getFile() + " for Bukkit adapters", e);
}
try {
bukkitAdapter = adapterLoader.loadAdapter();
log.log(Level.INFO, "Using " + bukkitAdapter.getClass().getCanonicalName() + " as the Bukkit adapter");
log.info("Using " + bukkitAdapter.getClass().getCanonicalName() + " as the Bukkit adapter");
} catch (AdapterLoadException e) {
try {
Platform platform = worldEdit.getPlatformManager().queryCapability(Capability.WORLD_EDITING);
if (platform instanceof BukkitServerInterface) {
log.log(Level.WARNING, e.getMessage());
log.warn(e.getMessage());
return;
} else {
log.log(Level.INFO, "WorldEdit could not find a Bukkit adapter for this MC version, " +
log.info("WorldEdit could not find a Bukkit adapter for this MC version, " +
"but it seems that you have another implementation of WorldEdit installed (" + platform.getPlatformName() + ") " +
"that handles the world editing.");
}
} catch (NoCapablePlatformException ignore) {}
log.log(Level.INFO, "WorldEdit could not find a Bukkit adapter for this MC version");
log.info("WorldEdit could not find a Bukkit adapter for this MC version");
}
}
@ -425,7 +461,7 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
EditSession editSession = WorldEdit.getInstance().getEditSessionFactory()
.getEditSession(wePlayer.getWorld(), session.getBlockChangeLimit(), blockBag, wePlayer);
editSession.enableQueue();
editSession.enableStandardMode();
return editSession;
}
@ -441,7 +477,7 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
LocalSession session = WorldEdit.getInstance().getSessionManager().get(wePlayer);
session.remember(editSession);
editSession.flushQueue();
editSession.flushSession();
WorldEdit.getInstance().flushBlockBag(wePlayer, editSession);
}

View File

@ -19,20 +19,18 @@
package com.sk89q.worldedit.bukkit.adapter;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.block.Biome;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
@ -45,26 +43,6 @@ import javax.annotation.Nullable;
*/
public interface BukkitImplAdapter<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.
*

View File

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

View File

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

View File

@ -13,6 +13,8 @@ dependencies {
compile 'com.google.code.gson:gson:2.8.0'
compile 'com.sk89q.lib:jlibnoise:1.0.0'
compile 'com.googlecode.json-simple:json-simple:1.1.1'
compile 'org.slf4j:slf4j-api:1.7.26'
//compile 'net.sf.trove4j:trove4j:3.0.3'
testCompile 'org.mockito:mockito-core:1.9.0-rc1'
// Fawe depends

View File

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

View File

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

View File

@ -28,18 +28,45 @@ import com.boydti.fawe.jnbt.anvil.MCAQueue;
import com.boydti.fawe.jnbt.anvil.MCAWorld;
import com.boydti.fawe.logging.LoggingChangeSet;
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
import com.boydti.fawe.object.*;
import com.boydti.fawe.object.FaweLimit;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.HasFaweQueue;
import com.boydti.fawe.object.HistoryExtent;
import com.boydti.fawe.object.NullChangeSet;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
import com.boydti.fawe.object.changeset.*;
import com.boydti.fawe.object.changeset.BlockBagChangeSet;
import com.boydti.fawe.object.changeset.CPUOptimizedChangeSet;
import com.boydti.fawe.object.changeset.DiskStorageHistory;
import com.boydti.fawe.object.changeset.FaweChangeSet;
import com.boydti.fawe.object.changeset.MemoryOptimizedHistory;
import com.boydti.fawe.object.collection.BlockVectorSet;
import com.boydti.fawe.object.collection.LocalBlockVectorSet;
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.object.extent.*;
import com.boydti.fawe.object.extent.FastWorldEditExtent;
import com.boydti.fawe.object.extent.FaweRegionExtent;
import com.boydti.fawe.object.extent.HeightBoundExtent;
import com.boydti.fawe.object.extent.MultiRegionExtent;
import com.boydti.fawe.object.extent.NullExtent;
import com.boydti.fawe.object.extent.ResettableExtent;
import com.boydti.fawe.object.extent.SingleRegionExtent;
import com.boydti.fawe.object.extent.SlowExtent;
import com.boydti.fawe.object.extent.SourceMaskExtent;
import com.boydti.fawe.object.extent.StripNBTExtent;
import com.boydti.fawe.object.function.SurfaceRegionFunction;
import com.boydti.fawe.object.mask.ResettableMask;
import com.boydti.fawe.object.pattern.ExistingPattern;
import com.boydti.fawe.object.progress.ChatProgressTracker;
import com.boydti.fawe.object.progress.DefaultProgressTracker;
import com.boydti.fawe.util.*;
import com.boydti.fawe.util.ExtentTraverser;
import com.boydti.fawe.util.MaskTraverser;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.MemUtil;
import com.boydti.fawe.util.Perm;
import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.wrappers.WorldWrapper;
import com.google.common.base.Supplier;
import com.sk89q.jnbt.CompoundTag;
@ -51,37 +78,79 @@ import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.ChangeSetExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.MaskingExtent;
import com.sk89q.worldedit.extent.cache.LastAccessExtentCache;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.extent.inventory.BlockBagExtent;
import com.sk89q.worldedit.extent.reorder.ChunkBatchingExtent;
import com.sk89q.worldedit.extent.reorder.MultiStageReorder;
import com.sk89q.worldedit.extent.validation.BlockChangeLimiter;
import com.sk89q.worldedit.extent.validation.DataValidatorExtent;
import com.sk89q.worldedit.extent.world.BlockQuirkExtent;
import com.sk89q.worldedit.extent.world.ChunkLoadingExtent;
import com.sk89q.worldedit.extent.world.FastModeExtent;
import com.sk89q.worldedit.extent.world.SurvivalModeExtent;
import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.RegionMaskingFilter;
import com.sk89q.worldedit.function.block.BlockDistributionCounter;
import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.block.Naturalizer;
import com.sk89q.worldedit.function.generator.ForestGenerator;
import com.sk89q.worldedit.function.generator.GardenPatchGenerator;
import com.sk89q.worldedit.function.mask.*;
import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.function.mask.BlockMaskBuilder;
import com.sk89q.worldedit.function.mask.BlockStateMask;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.function.mask.BoundedHeightMask;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.MaskIntersection;
import com.sk89q.worldedit.function.mask.MaskUnion;
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.mask.NoiseFilter2D;
import com.sk89q.worldedit.function.mask.RegionMask;
import com.sk89q.worldedit.function.operation.ChangeSetExecutor;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.WaterloggedRemover;
import com.sk89q.worldedit.function.util.RegionOffset;
import com.sk89q.worldedit.function.visitor.*;
import com.sk89q.worldedit.function.visitor.DirectionalVisitor;
import com.sk89q.worldedit.function.visitor.DownwardVisitor;
import com.sk89q.worldedit.function.visitor.FlatRegionVisitor;
import com.sk89q.worldedit.function.visitor.LayerVisitor;
import com.sk89q.worldedit.function.visitor.NonRisingVisitor;
import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.history.UndoContext;
import com.sk89q.worldedit.history.change.BlockChange;
import com.sk89q.worldedit.history.changeset.BlockOptimizedHistory;
import com.sk89q.worldedit.history.changeset.ChangeSet;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
import com.sk89q.worldedit.internal.expression.runtime.RValue;
import com.sk89q.worldedit.math.*;
import com.sk89q.worldedit.internal.expression.runtime.ExpressionTimeoutException;
import com.sk89q.worldedit.internal.expression.runtime.RValue;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MathUtils;
import com.sk89q.worldedit.math.MutableBlockVector2;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.math.Vector2;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.interpolation.Interpolation;
import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation;
import com.sk89q.worldedit.math.interpolation.Node;
import com.sk89q.worldedit.math.noise.RandomNoise;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.regions.*;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.EllipsoidRegion;
import com.sk89q.worldedit.regions.FlatRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.Regions;
import com.sk89q.worldedit.regions.shape.ArbitraryBiomeShape;
import com.sk89q.worldedit.regions.shape.ArbitraryShape;
import com.sk89q.worldedit.regions.shape.RegionShape;
@ -89,12 +158,18 @@ import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.util.collection.DoubleArrayList;
import com.sk89q.worldedit.util.eventbus.EventBus;
import com.sk89q.worldedit.world.NullWorld;
import com.sk89q.worldedit.world.SimpleWorld;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.*;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import com.sk89q.worldedit.world.weather.WeatherType;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -103,7 +178,9 @@ import java.util.concurrent.ThreadLocalRandom;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.regions.Regions.*;
import static com.sk89q.worldedit.regions.Regions.asFlatRegion;
import static com.sk89q.worldedit.regions.Regions.maximumBlockY;
import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
/**
* An {@link Extent} that handles history, {@link BlockBag}s, change limits,
@ -114,13 +191,8 @@ import static com.sk89q.worldedit.regions.Regions.*;
* using the {@link ChangeSetExtent}.</p>
*/
public class EditSession extends AbstractDelegateExtent implements HasFaweQueue, SimpleWorld, AutoCloseable {
/**
* Used by {@link EditSession#setBlock(BlockVector3, BlockStateHolder, Stage)} to
* determine which {@link Extent}s should be bypassed.
*/
public enum Stage {
BEFORE_HISTORY, BEFORE_REORDER, BEFORE_CHANGE
}
private static final Logger log = LoggerFactory.getLogger(EditSession.class);
private World world;
private String worldName;
@ -144,9 +216,14 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
private final int maxY;
public static final UUID CONSOLE = UUID.fromString("1-1-3-3-7");
public static final BaseBiome nullBiome = new BaseBiome(0);
public static final BlockState nullBlock = BlockTypes.AIR.getDefaultState();
public enum Stage {
BEFORE_HISTORY,
BEFORE_REORDER,
BEFORE_CHANGE
}
@Deprecated
public EditSession(@Nonnull World world, @Nullable FaweQueue queue, @Nullable FawePlayer player, @Nullable FaweLimit limit, @Nullable FaweChangeSet changeSet, @Nullable RegionWrapper[] allowedRegions, @Nullable Boolean autoQueue, @Nullable Boolean fastmode, @Nullable Boolean checkMemory, @Nullable Boolean combineStages, @Nullable BlockBag blockBag, @Nullable EventBus bus, @Nullable EditSessionEvent event) {
this(null, world, queue, player, limit, changeSet, allowedRegions, autoQueue, fastmode, checkMemory, combineStages, blockBag, bus, event);
@ -340,6 +417,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
this(WorldEdit.getInstance().getEventBus(), world, maxBlocks, blockBag, new EditSessionEvent(world, null, maxBlocks, null));
}
private ReorderMode reorderMode = ReorderMode.MULTI_STAGE;
private Mask oldMask;
/**
@ -370,6 +449,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
if (find != null && find.get() != null) {
find.get().setLimit(this.limit);
}
setReorderMode(this.reorderMode);
}
/**
@ -400,7 +481,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
}
/**
* The region extent restricts block placements to allowed regions
* The region extent restricts block placements to allowmaxYed regions
*
* @return FaweRegionExtent (may be null)
*/
@ -536,6 +617,29 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
return extent;
}
// pkg private for TracedEditSession only, may later become public API
boolean commitRequired() {
if (reorderExtent != null && reorderExtent.commitRequired()) {
return true;
}
if (chunkBatchingExtent != null && chunkBatchingExtent.commitRequired()) {
return true;
}
if (fastModeExtent != null && fastModeExtent.commitRequired()) {
return true;
}
return false;
}
/**
* Turns on specific features for a normal WorldEdit session, such as
* {@link #setBatchingChunks(boolean)
* chunk batching}.
*/
public void enableStandardMode() {
setBatchingChunks(true);
}
/**
* Get the world.
*
@ -610,6 +714,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* Returns queue status.
*
* @return whether the queue is enabled
* @deprecated Use {@link EditSession#getReorderMode()} with MULTI_STAGE instead.
*/
@Deprecated
public boolean isQueueEnabled() {
@ -618,6 +723,9 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
/**
* Queue certain types of block for better reproduction of those blocks.
*
* Uses {@link ReorderMode#MULTI_STAGE}
* @deprecated Use {@link EditSession#setReorderMode(ReorderMode)} with MULTI_STAGE instead.
*/
@Deprecated
public void enableQueue() {
@ -880,6 +988,27 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
return new HashMap<>();
}
/**
* Returns chunk batching status.
*
* @return whether chunk batching is enabled
*/
public boolean isBatchingChunks() {
return false;
}
/**
* Enable or disable chunk batching. Disabling will
* {@linkplain #flushSession() flush the session}.
*
* @param batchingChunks {@code true} to enable, {@code false} to disable
*/
public void setBatchingChunks(boolean batchingChunks) {
}
public void disableBuffering() {
}
/**
* Get the number of blocks changed, including repeated block changes.
* <p>
@ -892,18 +1021,18 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
}
@Override
public BaseBiome getBiome(final BlockVector2 position) {
public BiomeType getBiome(final BlockVector2 position) {
return this.extent.getBiome(position);
}
@Override
public boolean setBiome(final BlockVector2 position, final BaseBiome biome) {
public boolean setBiome(final BlockVector2 position, final BiomeType biome) {
this.changes++;
return this.extent.setBiome(position, biome);
}
@Override
public boolean setBiome(int x, int y, int z, BaseBiome biome) {
public boolean setBiome(int x, int y, int z, BiomeType biome) {
this.changes++;
return this.extent.setBiome(x, y, z, biome);
}
@ -968,8 +1097,24 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
return getBlockType(position.getBlockX(), position.getBlockY(), position.getBlockZ());
}
/**
* Returns the highest solid 'terrain' block.
*
* @param x the X coordinate
* @param z the Z coordinate
* @param minY minimal height
* @param maxY maximal height
* @param filter a mask of blocks to consider, or null to consider any solid (movement-blocking) block
* @return height of highest block found or 'minY'
*/
public int getHighestTerrainBlock(int x, int z, int minY, int maxY) {
return getHighestTerrainBlock(x, z, minY, maxY, null);
for (int y = maxY; y >= minY; --y) {
BlockVector3 pt = BlockVector3.at(x, y, z);
if (getBlock(pt).getBlockType().getMaterial().isMovementBlocker()) {
return y;
}
}
return minY;
}
/**
@ -985,9 +1130,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
public int getHighestTerrainBlock(int x, int z, int minY, int maxY, Mask filter) {
for (int y = maxY; y >= minY; --y) {
BlockVector3 pt = BlockVector3.at(x, y, z);
if (filter == null
? getBlock(pt).getBlockType().getMaterial().isMovementBlocker()
: filter.test(pt)) {
if (filter.test(pt)) {
return y;
}
}
@ -1033,6 +1176,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return whether the block changed
*/
public <B extends BlockStateHolder<B>> boolean rawSetBlock(BlockVector3 position, B block) {
this.changes++;
try {
return this.bypassAll.setBlock(position, block);
} catch (WorldEditException e) {
@ -1048,6 +1192,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return whether the block changed
*/
public <B extends BlockStateHolder<B>> boolean smartSetBlock(BlockVector3 position, B block) {
this.changes++;
try {
return setBlock(position, block, Stage.BEFORE_REORDER);
} catch (WorldEditException e) {
@ -1450,8 +1595,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int fillXZ(final BlockVector3 origin, BaseBlock block, double radius, int depth, boolean recursive) throws MaxChangedBlocksException {
return fillXZ(origin, (Pattern) block, radius, depth, recursive);
public <B extends BlockStateHolder<B>> int fillXZ(BlockVector3 origin, B block, double radius, int depth, boolean recursive) throws MaxChangedBlocksException {
return fillXZ(origin, new BlockPattern(block), radius, depth, recursive);
}
/**
* Fills an area recursively in the X/Z directions.
@ -1471,12 +1616,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
checkArgument(depth >= 1, "depth >= 1");
final MaskIntersection mask = new MaskIntersection(new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))), new BoundedHeightMask(Math.max(
(origin.getBlockY() - depth) + 1, getMinimumPoint().getBlockY()), Math.min(getMaximumPoint().getBlockY(), origin.getBlockY())), Masks.negate(new ExistingBlockMask(EditSession.this)));
// MaskIntersection mask = new MaskIntersection(
// new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))),
// new BoundedHeightMask(
// Math.max(origin.getBlockY() - depth + 1, 0),
// Math.min(getWorld().getMaxY(), origin.getBlockY())),
// Masks.negate(new ExistingBlockMask(this)));
// Want to replace blocks
BlockReplace replace = new BlockReplace(this, pattern);
@ -1588,6 +1727,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
public boolean hasExtraExtents() {
return wrapped || getMask() != null || getSourceMask() != null || history != null;
}
public int removeNear(BlockVector3 position, BlockType blockType, int apothem) throws MaxChangedBlocksException {
checkNotNull(position);
checkArgument(apothem >= 1, "apothem >= 1");
@ -1670,7 +1810,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public <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));
}
@ -1684,8 +1824,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int replaceBlocks(Region region, Set<BlockStateHolder> filter, Pattern pattern) throws MaxChangedBlocksException {
Mask mask = filter == null ? new ExistingBlockMask(this) : new BlockMaskBuilder().addBlocks(filter).build(this);
public int replaceBlocks(Region region, Set<BaseBlock> filter, Pattern pattern) throws MaxChangedBlocksException {
Mask mask = filter == null ? new ExistingBlockMask(this) : new BlockMask(this, filter);
return replaceBlocks(region, mask, pattern);
}
@ -1887,12 +2027,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
FlatRegionVisitor visitor = new FlatRegionVisitor(asFlatRegion(region), surface, this);
Operations.completeBlindly(visitor);
return this.changes = visitor.getAffected();
// BlockReplace replace = new BlockReplace(this, pattern);
// RegionOffset offset = new RegionOffset(BlockVector3.at(0, 1, 0), replace);
// GroundFunction ground = new GroundFunction(new ExistingBlockMask(this), offset);
// LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
// Operations.completeLegacy(visitor);
// return ground.getAffected();
}
/**
@ -2031,6 +2165,10 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int drainArea(final BlockVector3 origin, final double radius) {
return drainArea(origin, radius, false);
}
public int drainArea(final BlockVector3 origin, final double radius, boolean waterLogged) {
checkNotNull(origin);
checkArgument(radius >= 0, "radius >= 0 required");
Mask liquidMask;
@ -2053,20 +2191,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
// Around the origin in a 3x3 block
for (final BlockVector3 position : CuboidRegion.fromCenter(origin, 1)) {
// public int drainArea(BlockVector3 origin, double radius) throws MaxChangedBlocksException {
// checkNotNull(origin);
// checkArgument(radius >= 0, "radius >= 0 required");
//
// MaskIntersection mask = new MaskIntersection(
// new BoundedHeightMask(0, getWorld().getMaxY()),
// new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))),
// getWorld().createLiquidMask());
//
// BlockReplace replace = new BlockReplace(this, new BlockPattern(BlockTypes.AIR.getDefaultState()));
// RecursiveVisitor visitor = new RecursiveVisitor(mask, replace);
//
// // Around the origin in a 3x3 block
// for (BlockVector3 position : CuboidRegion.fromCenter(origin, 1)) {
if (mask.test(position)) {
visitor.visit(position);
}
@ -2349,7 +2473,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return number of blocks changed
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int makeSphere(final BlockVector3 pos, final Pattern block, final double radius, final boolean filled) {
public int makeSphere(BlockVector3 pos, Pattern block, double radius, boolean filled) {
return makeSphere(pos, block, radius, radius, radius, filled);
}
@ -2595,7 +2719,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
*/
public int green(final BlockVector3 position, final double radius) {
return this.green(position, radius, false);
}
}
public int green(BlockVector3 position, double radius, boolean onlyNormalDirt)
throws MaxChangedBlocksException {
int affected = 0;
@ -2619,6 +2744,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
for (int y = maxY; y >= 1; --y) {
BlockType block = getBlockType(x, y, z);
switch (block.getResource().toUpperCase()) {
// TODO onlyNormalDirt
case "DIRT":
this.setBlock(x, y, z, BlockTypes.GRASS_BLOCK.getDefaultState());
break loop;
@ -2629,26 +2755,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
if (block.getMaterial().isMovementBlocker()) {
break loop;
}
// for (int x = ox - ceilRadius; x <= ox + ceilRadius; ++x) {
// for (int z = oz - ceilRadius; z <= oz + ceilRadius; ++z) {
// if ((BlockVector3.at(x, oy, z)).distanceSq(position) > radiusSq) {
// continue;
// }
//
// for (int y = world.getMaxY(); y >= 1; --y) {
// final BlockVector3 pt = BlockVector3.at(x, y, z);
// final BlockState block = getBlock(pt);
//
// if (block.getBlockType() == BlockTypes.DIRT ||
// (!onlyNormalDirt && block.getBlockType() == BlockTypes.COARSE_DIRT)) {
// if (setBlock(pt, grass)) {
// ++affected;
// }
// break;
// } else if (block.getBlockType() == BlockTypes.WATER || block.getBlockType() == BlockTypes.LAVA) {
// break;
// } else if (block.getBlockType().getMaterial().isMovementBlocker()) {
// break;
}
}
}
@ -2727,48 +2833,39 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
} else if (type.getMaterial().isAir()) {
continue;
}
// public int makeForest(BlockVector3 basePosition, int size, double density, TreeGenerator.TreeType treeType) throws MaxChangedBlocksException {
// int affected = 0;
//
// for (int x = basePosition.getBlockX() - size; x <= basePosition.getBlockX()
// + size; ++x) {
// for (int z = basePosition.getBlockZ() - size; z <= basePosition.getBlockZ()
// + size; ++z) {
// // Don't want to be in the ground
// if (!getBlock(BlockVector3.at(x, basePosition.getBlockY(), z)).getBlockType().getMaterial().isAir()) {
// continue;
// }
// // The gods don't want a tree here
// if (Math.random() >= density) {
// continue;
// } // def 0.05
//
// for (int y = basePosition.getBlockY(); y >= basePosition.getBlockY() - 10; --y) {
// // Check if we hit the ground
// BlockType t = getBlock(BlockVector3.at(x, y, z)).getBlockType();
// if (t == BlockTypes.GRASS_BLOCK || t == BlockTypes.DIRT) {
// treeType.generate(this, BlockVector3.at(x, y + 1, z));
// ++affected;
// break;
// } else if (t == BlockTypes.SNOW) {
// setBlock(BlockVector3.at(x, y, z), BlockTypes.AIR.getDefaultState());
// } else if (!t.getMaterial().isAir()) { // Trees won't grow on this!
// break;
}
}
}
} catch (MaxChangedBlocksException ignore) {
}
} catch (MaxChangedBlocksException ignore) {}
return this.changes;
}
/**
* Makes a forest.
*
* @param region the region to generate trees in
* @param density between 0 and 1, inclusive
* @param treeType the tree type
* @return number of trees created
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int makeForest(Region region, double density, TreeGenerator.TreeType treeType) throws MaxChangedBlocksException {
ForestGenerator generator = new ForestGenerator(this, treeType);
GroundFunction ground = new GroundFunction(new ExistingBlockMask(this), generator);
LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
visitor.setMask(new NoiseFilter2D(new RandomNoise(), density));
Operations.completeLegacy(visitor);
return ground.getAffected();
}
/**
* Get the block distribution inside a region.
*
* @param region a region
* @return the results
*/
public List<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()];
if (region instanceof CuboidRegion) {
@ -2810,10 +2907,17 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
}
/**
* Get the block distribution (with data values) inside a region.
* Generate a shape for the given expression.
*
* @param region a region
* @return the results
* @param region the region to generate the shape in
* @param zero the coordinate origin for x/y/z variables
* @param unit the scale of the x/y/z/ variables
* @param pattern the default material to make the shape from
* @param expressionString the expression defining the shape
* @param hollow whether the shape should be hollow
* @return number of blocks changed
* @throws ExpressionException
* @throws MaxChangedBlocksException
*/
public List<Countable<BlockStateHolder>> getBlockDistributionWithData(final Region region) {
int[][] counter = new int[BlockTypes.size()][];
@ -2884,6 +2988,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
final WorldEditExpressionEnvironment environment = new WorldEditExpressionEnvironment(this, unit, zero);
expression.setEnvironment(environment);
final int[] timedOut = {0};
final ArbitraryShape shape = new ArbitraryShape(region) {
@Override
public BaseBlock getMaterial(final int x, final int y, final int z, final BaseBlock defaultMaterial) {
@ -2907,12 +3012,13 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
}
}
};
try {
return shape.generate(this, pattern, hollow);
} catch (WorldEditException e) {
throw new RuntimeException(e);
int changed = shape.generate(this, pattern, hollow);
if (timedOut[0] > 0) {
throw new ExpressionTimeoutException(
String.format("%d blocks changed. %d blocks took too long to evaluate (increase with //timeout).",
changed, timedOut[0]));
}
return changed;
}
public int deformRegion(final Region region, final Vector3 zero, final Vector3 unit, final String expressionString) throws ExpressionException, MaxChangedBlocksException {
@ -2926,18 +3032,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
final Vector3 zero2 = zero.add(0.5, 0.5, 0.5);
RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() {
// final DoubleArrayList<BlockVector3, BaseBlock> queue = new DoubleArrayList<>(false);
//
// for (BlockVector3 position : region) {
// // offset, scale
// final Vector3 scaled = position.subtract(zero).divide(unit);
//
// // transform
// expression.evaluate(scaled.getX(), scaled.getY(), scaled.getZ());
//
// final BlockVector3 sourcePosition = environment.toWorld(x.getValue(), y.getValue(), z.getValue());
private MutableBlockVector3 mutable = new MutableBlockVector3();
private MutableBlockVector3 mutable = new MutableBlockVector3();
@Override
public boolean apply(BlockVector3 position) throws WorldEditException {
@ -2956,18 +3051,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
} catch (EvaluationException e) {
throw new RuntimeException(e);
}
// // queue operation
// queue.put(position, material);
// }
//
// int affected = 0;
// for (Map.Entry<BlockVector3, BaseBlock> entry : queue) {
// BlockVector3 position = entry.getKey();
// BaseBlock material = entry.getValue();
//
// // set at new position
// if (setBlock(position, material)) {
// ++affected;
}
}, this);
Operations.completeBlindly(visitor);
@ -3249,9 +3332,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
return returnset;
}
public void recurseHollow(final Region region, final BlockVector3 origin, final Set<BlockVector3> outside) {
//TODO FIXME Optimize - avoid vector creation
final ArrayDeque<BlockVector3> queue = new ArrayDeque<>();
private void recurseHollow(Region region, BlockVector3 origin, Set<BlockVector3> outside) {
final BlockVectorSet queue = new BlockVectorSet<>();
queue.addLast(origin);
while (!queue.isEmpty()) {
@ -3272,10 +3354,10 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
for (BlockVector3 recurseDirection : recurseDirections) {
queue.addLast(current.add(recurseDirection));
}
} // while
}
}
public int makeBiomeShape(final Region region, final Vector3 zero, final Vector3 unit, final BaseBiome biomeType, final String expressionString, final boolean hollow) throws ExpressionException, MaxChangedBlocksException {
public int makeBiomeShape(final Region region, final Vector3 zero, final Vector3 unit, final BiomeType biomeType, final String expressionString, final boolean hollow) throws ExpressionException, MaxChangedBlocksException {
final Vector2 zero2D = zero.toVector2();
final Vector2 unit2D = unit.toVector2();
@ -3288,7 +3370,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
final ArbitraryBiomeShape shape = new ArbitraryBiomeShape(region) {
@Override
protected BaseBiome getBiome(final int x, final int z, final BaseBiome defaultBiomeType) {
protected BiomeType getBiome(final int x, final int z, final BiomeType defaultBiomeType) {
environment.setCurrentBlock(x, 0, z);
double scaledX = (x - zero2D.getX()) / unit2D.getX();
double scaledZ = (z - zero2D.getZ()) / unit2D.getZ();
@ -3305,8 +3387,13 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
}
}
};
return shape.generate(this, biomeType, hollow);
int changed = shape.generate(this, biomeType, hollow);
if (timedOut[0] > 0) {
throw new ExpressionTimeoutException(
String.format("%d blocks changed. %d blocks took too long to evaluate (increase time with //timeout)",
changed, timedOut[0]));
}
return changed;
}
private static final BlockVector3[] recurseDirections = {
Direction.NORTH.toBlockVector(),
@ -3374,7 +3461,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
}
}
public boolean regenerate(final Region region, final BaseBiome biome, final Long seed) {
public boolean regenerate(final Region region, final BiomeType biome, final Long seed) {
//TODO Optimize - avoid Vector2D creation (make mutable)
final FaweQueue queue = this.getQueue();
queue.setChangeTask(null);

View File

@ -152,21 +152,24 @@ public class EditSessionFactory {
@Override
public EditSession getEditSession(World world, int maxBlocks) {
return new EditSession(eventBus, world, maxBlocks, null, new EditSessionEvent(world, null, maxBlocks, null));
return getEditSession(world, maxBlocks, null, null);
}
@Override
public EditSession getEditSession(World world, int maxBlocks, Player player) {
return new EditSession(eventBus, world, maxBlocks, null, new EditSessionEvent(world, player, maxBlocks, null));
return getEditSession(world, maxBlocks, null, player);
}
@Override
public EditSession getEditSession(World world, int maxBlocks, BlockBag blockBag) {
return new EditSession(eventBus, world, maxBlocks, blockBag, new EditSessionEvent(world, null, maxBlocks, null));
return getEditSession(world, maxBlocks, blockBag, null);
}
@Override
public EditSession getEditSession(World world, int maxBlocks, BlockBag blockBag, Player player) {
if (WorldEdit.getInstance().getConfiguration().traceUnflushedSessions) {
return new TracedEditSession(eventBus, world, maxBlocks, blockBag, new EditSessionEvent(world, player, maxBlocks, null));
}
return new EditSession(eventBus, world, maxBlocks, blockBag, new EditSessionEvent(world, player, maxBlocks, null));
}

View File

@ -38,6 +38,7 @@ import java.util.Set;
public abstract class LocalConfiguration {
public boolean profile = false;
public boolean traceUnflushedSessions = false;
public Set<String> disallowedBlocks = new HashSet<>();
public int defaultChangeLimit = -1;
public int maxChangeLimit = -1;
@ -65,6 +66,8 @@ public abstract class LocalConfiguration {
public String navigationWand = "minecraft:compass";
public int navigationWandMaxDistance = 50;
public int scriptTimeout = 3000;
public int calculationTimeout = 100;
public int maxCalculationTimeout = 300;
public Set<String> allowedDataCycleBlocks = new HashSet<>();
public String saveDir = "schematics";
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.ItemTypes;
import com.sk89q.worldedit.world.snapshot.Snapshot;
import java.io.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Calendar;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicBoolean;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkNotNull;
@ -118,6 +123,7 @@ public class LocalSession implements TextureHolder {
private transient Tool[] tools = new Tool[ItemTypes.size()];
private transient int maxBlocksChanged = -1;
private transient int maxTimeoutTime;
private transient boolean useInventory;
private transient Snapshot snapshot;
private transient boolean hasCUISupport = false;
@ -830,6 +836,24 @@ public class LocalSession implements TextureHolder {
this.maxBlocksChanged = maxBlocksChanged;
}
/**
* Get the maximum time allowed for certain executions to run before cancelling them, such as expressions.
*
* @return timeout time, in milliseconds
*/
public int getTimeout() {
return maxTimeoutTime;
}
/**
* Set the maximum number of blocks that can be changed.
*
* @param timeout the time, in milliseconds, to limit certain executions to, or -1 to disable
*/
public void setTimeout(int timeout) {
this.maxTimeoutTime = timeout;
}
/**
* Checks whether the super pick axe is enabled.
*
@ -1260,7 +1284,7 @@ public class LocalSession implements TextureHolder {
String msg = e.getMessage();
if (msg != null && msg.length() > 256) msg = msg.substring(0, 256);
this.failedCuiAttempts++;
WorldEdit.logger.warning("Error while reading CUI init message for player " + uuid + ": " + msg);
WorldEdit.logger.warn("Error while reading CUI init message for player " + uuid + ": " + msg);
}
}
@ -1375,6 +1399,24 @@ public class LocalSession implements TextureHolder {
this.fastMode = fastMode;
}
/**
* Gets the reorder mode of the session.
*
* @return The reorder mode
*/
public EditSession.ReorderMode getReorderMode() {
return reorderMode;
}
/**
* Sets the reorder mode of the session.
*
* @param reorderMode The reorder mode
*/
public void setReorderMode(EditSession.ReorderMode reorderMode) {
this.reorderMode = reorderMode;
}
/**
* Get the mask.
*

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

View File

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

View File

@ -19,14 +19,13 @@
package com.sk89q.worldedit.blocks;
import com.sk89q.worldedit.world.block.BlockCategories;
import com.google.common.collect.Maps;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.Map;
/**
* Block-related utility methods.
@ -36,143 +35,6 @@ public final class Blocks {
private Blocks() {
}
/**
* HashSet for shouldPlaceLate.
*/
private static final Set<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.
*
@ -190,4 +52,28 @@ public final class Blocks {
return false;
}
/**
* Parses a string->string map to find the matching Property and values for the given BlockType.
*
* @param states the desired states and values
* @param type the block type to get properties and values for
* @return a property->value map
*/
public static Map<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.command.binding.Switch;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeData;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION;
import java.util.Set;
/**
* Implements biome-related commands such as "/biomelist".
@ -102,11 +104,11 @@ public class BiomeCommands extends MethodCommands {
}
BiomeRegistry biomeRegistry = getBiomeRegistry();
List<BaseBiome> biomes = biomeRegistry.getBiomes();
List<BiomeType> biomes = biomeRegistry.getBiomes();
int totalPages = biomes.size() / 19 + 1;
Message msg = BBC.BIOME_LIST_HEADER.m(page, totalPages);
String setBiome = Commands.getAlias(BiomeCommands.class, "/setbiome");
for (BaseBiome biome : biomes) {
for (BiomeType biome : biomes) {
if (offset > 0) {
offset--;
} else {
@ -150,12 +152,12 @@ public class BiomeCommands extends MethodCommands {
return;
}
BaseBiome biome = player.getWorld().getBiome(blockPosition.toBlockPoint().toBlockVector2());
biomes[biome.getId()]++;
BiomeType biome = player.getWorld().getBiome(blockPosition.toBlockPoint().toBlockVector2());
biomes[biome.getInternalId()]++;
size = 1;
} else if (args.hasFlag('p')) {
BaseBiome biome = player.getWorld().getBiome(player.getLocation().toBlockPoint().toBlockVector2());
biomes[biome.getId()]++;
BiomeType biome = player.getWorld().getBiome(player.getLocation().toBlockPoint().toBlockVector2());
biomes[biome.getInternalId()]++;
size = 1;
} else {
World world = player.getWorld();
@ -181,15 +183,15 @@ public class BiomeCommands extends MethodCommands {
BBC.BIOME_LIST_HEADER.send(player, 1, 1);
List<Countable<BaseBiome>> distribution = new ArrayList<>();
List<Countable<BiomeType>> distribution = new ArrayList<>();
for (int i = 0; i < biomes.length; i++) {
int count = biomes[i];
if (count != 0) {
distribution.add(new Countable<>(new BaseBiome(i), count));
distribution.add(new Countable<>(new BiomeType(i), count));
}
}
Collections.sort(distribution);
for (Countable<BaseBiome> c : distribution) {
for (Countable<BiomeType> c : distribution) {
BiomeData data = biomeRegistry.getData(c.getID());
String str = String.format("%-7s (%.3f%%) %s #%d",
String.valueOf(c.getAmount()),
@ -212,7 +214,7 @@ public class BiomeCommands extends MethodCommands {
)
@Logging(REGION)
@CommandPermissions("worldedit.biome.set")
public void setBiome(Player player, LocalSession session, EditSession editSession, BaseBiome target, @Switch('p') boolean atPosition) throws WorldEditException {
public void setBiome(Player player, LocalSession session, EditSession editSession, BiomeType target, @Switch('p') boolean atPosition) throws WorldEditException {
World world = player.getWorld();
Region region;
Mask mask = editSession.getMask();

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

View File

@ -21,7 +21,6 @@ package com.sk89q.worldedit.command;
import com.boydti.fawe.config.BBC;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.Logging;
import com.sk89q.worldedit.EditSession;
@ -106,7 +105,7 @@ public class ChunkCommands {
)
@CommandPermissions("worldedit.delchunks")
@Logging(REGION)
public void deleteChunks(Player player, LocalSession session, CommandContext args) throws WorldEditException {
public void deleteChunks(Player player, LocalSession session) throws WorldEditException {
player.print(BBC.getPrefix() + "Note that this command does not yet support the mcregion format.");
LocalConfiguration config = worldEdit.getConfiguration();

View File

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

View File

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

View File

@ -59,7 +59,7 @@ public class GeneralCommands {
max = 1
)
@CommandPermissions("worldedit.limit")
public void limit(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
public void limit(Player player, LocalSession session, CommandContext args) throws WorldEditException {
LocalConfiguration config = worldEdit.getConfiguration();
boolean mayDisable = player.hasPermission("worldedit.limit.unrestricted");
@ -74,13 +74,43 @@ public class GeneralCommands {
session.setBlockChangeLimit(limit);
if (limit != -1) {
player.print("Block change limit set to " + limit + ". (Use //limit -1 to go back to the default.)");
if (limit != config.defaultChangeLimit) {
player.print("Block change limit set to " + limit + ". (Use //limit to go back to the default.)");
} else {
player.print("Block change limit set to " + limit + ".");
}
}
@Command(
aliases = { "/timeout" },
usage = "[time]",
desc = "Modify evaluation timeout time.",
min = 0,
max = 1
)
@CommandPermissions("worldedit.timeout")
public void timeout(Player player, LocalSession session, CommandContext args) throws WorldEditException {
LocalConfiguration config = worldEdit.getConfiguration();
boolean mayDisable = player.hasPermission("worldedit.timeout.unrestricted");
int limit = args.argsLength() == 0 ? config.calculationTimeout : Math.max(-1, args.getInteger(0));
if (!mayDisable && config.maxCalculationTimeout > -1) {
if (limit > config.maxCalculationTimeout) {
player.printError("Your maximum allowable timeout is " + config.maxCalculationTimeout + " ms.");
return;
}
}
session.setTimeout(limit);
if (limit != config.calculationTimeout) {
player.print("Timeout time set to " + limit + " ms. (Use //timeout to go back to the default.)");
} else {
player.print("Timeout time set to " + limit + " ms.");
}
}
@Command(
aliases = { "/fast" },
usage = "[on|off]",
@ -89,7 +119,7 @@ public class GeneralCommands {
max = 1
)
@CommandPermissions("worldedit.fast")
public void fast(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
public void fast(Player player, LocalSession session, CommandContext args) throws WorldEditException {
String newState = args.getString(0, null);
if (session.hasFastMode()) {
@ -111,6 +141,41 @@ public class GeneralCommands {
}
}
@Command(
aliases = { "/drawsel" },
usage = "[on|off]",
desc = "Toggle drawing the current selection",
min = 0,
max = 1
)
@CommandPermissions("worldedit.drawsel")
public void drawSelection(Player player, LocalSession session, CommandContext args) throws WorldEditException {
if (!WorldEdit.getInstance().getConfiguration().serverSideCUI) {
throw new DisallowedUsageException("This functionality is disabled in the configuration!");
}
String newState = args.getString(0, null);
if (session.shouldUseServerCUI()) {
if ("on".equals(newState)) {
player.printError("Server CUI already enabled.");
return;
}
session.setUseServerCUI(false);
session.updateServerCUI(player);
player.print("Server CUI disabled.");
} else {
if ("off".equals(newState)) {
player.printError("Server CUI already disabled.");
return;
}
session.setUseServerCUI(true);
session.updateServerCUI(player);
player.print("Server CUI enabled. This only supports cuboid regions, with a maximum size of 32x32x32.");
}
}
@Command(
aliases = { "/gmask", "gmask" },
usage = "[mask]",
@ -119,7 +184,7 @@ public class GeneralCommands {
max = -1
)
@CommandPermissions("worldedit.global-mask")
public void gmask(Player player, LocalSession session, EditSession editSession, @Optional Mask mask) throws WorldEditException {
public void gmask(Player player, LocalSession session, @Optional Mask mask) throws WorldEditException {
if (mask == null) {
session.setMask((Mask) null);
player.print("Global mask disabled.");
@ -136,7 +201,7 @@ public class GeneralCommands {
min = 0,
max = 0
)
public void togglePlace(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
public void togglePlace(Player player, LocalSession session) throws WorldEditException {
if (session.togglePlacementPosition()) {
player.print("Now placing at pos #1.");

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

View File

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

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

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

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.util.MainUtil;
import com.boydti.fawe.util.chat.Message;
import com.google.common.collect.Multimap;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
@ -55,23 +56,30 @@ import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.command.binding.Switch;
import com.sk89q.worldedit.util.command.parametric.Optional;
import com.sk89q.worldedit.util.io.file.FilenameException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.*;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.Files;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.LongAdder;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import static com.boydti.fawe.util.ReflectionUtils.as;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Commands that work with schematic files.
@ -79,7 +87,12 @@ import static com.boydti.fawe.util.ReflectionUtils.as;
@Command(aliases = {"schematic", "schem", "/schematic", "/schem", "clipboard", "/clipboard"}, desc = "Commands that work with schematic files")
public class SchematicCommands extends MethodCommands {
private static final Logger log = Logger.getLogger(SchematicCommands.class.getCanonicalName());
/**
* 9 schematics per page fits in the MC chat window.
*/
private static final int SCHEMATICS_PER_PAGE = 9;
private static final Logger log = LoggerFactory.getLogger(SchematicCommands.class);
private final WorldEdit worldEdit;
/**
* Create a new instance.
@ -280,7 +293,7 @@ public class SchematicCommands extends MethodCommands {
@Command(aliases = {"save"}, usage = "[format] <filename>", desc = "Save a schematic into your clipboard", help = "The default format for 1.13 is schem")
@Deprecated
@CommandPermissions({"worldedit.clipboard.save", "worldedit.schematic.save", "worldedit.schematic.save.other"})
public void save(final Player player, final LocalSession session, @Optional("schem") final String formatName, String filename, @Switch('g') boolean global) throws CommandException, WorldEditException {
public void save(final Player player, final LocalSession session, @Optional("schem") final String formatName, String filename, @Switch('g') boolean global, @Switch('f') boolean allowOverwrite) throws CommandException, WorldEditException {
final LocalConfiguration config = this.worldEdit.getConfiguration();
final ClipboardFormat format = ClipboardFormats.findByAlias(formatName);
if (format == null) {
@ -324,6 +337,8 @@ public class SchematicCommands extends MethodCommands {
try {
if (!f.exists()) {
f.createNewFile();
} else if (!allowOverwrite) {
BBC.SCHEMATIC_MOVE_EXISTS.send(player, f.getName());
}
try (FileOutputStream fos = new FileOutputStream(f)) {
final ClipboardHolder holder = session.getClipboard();
@ -363,7 +378,7 @@ public class SchematicCommands extends MethodCommands {
} catch (IOException e) {
e.printStackTrace();
player.printError("Schematic could not written: " + e.getMessage());
log.log(Level.WARNING, "Failed to write a saved clipboard", e);
log.warn("Failed to write a saved clipboard", e);
}
}
@ -645,6 +660,4 @@ public class SchematicCommands extends MethodCommands {
}
});
}
}

View File

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

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

View File

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

View File

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

View File

@ -48,7 +48,7 @@ public class SuperPickaxeCommands {
max = 0
)
@CommandPermissions("worldedit.superpickaxe")
public void single(Player player, LocalSession session, CommandContext args) throws WorldEditException {
public void single(Player player, LocalSession session) throws WorldEditException {
session.setSuperPickaxe(new SinglePickaxe());
session.enableSuperPickAxe();

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

View File

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

View File

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

View File

@ -124,6 +124,31 @@ public class WorldEditCommands {
actor.print(BBC.getPrefix() + "Reloaded WorldEdit " + we.getVersion() + " and FAWE (" + Fawe.get().getVersion() + ")");
}
@Command(aliases = {"report"}, desc = "Writes a report on WorldEdit", flags = "p", max = 0)
@CommandPermissions({"worldedit.report"})
public void report(Actor actor, CommandContext args) throws WorldEditException {
ReportList report = new ReportList("Report");
report.add(new SystemInfoReport());
report.add(new ConfigReport());
String result = report.toString();
try {
File dest = new File(we.getWorkingDirectoryFile(we.getConfiguration().saveDir), "report.txt");
Files.write(result, dest, Charset.forName("UTF-8"));
actor.print("WorldEdit report written to " + dest.getAbsolutePath());
} catch (IOException e) {
actor.printError("Failed to write report: " + e.getMessage());
}
if (args.hasFlag('p')) {
actor.checkPermission("worldedit.report.pastebin");
ActorCallbackPaste.pastebin(
we.getSupervisor(), actor, result, "WorldEdit report: %s.report",
WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter()
);
}
}
@Command(
aliases = {"update"},
usage = "",
@ -252,7 +277,7 @@ public class WorldEditCommands {
min = 0,
max = 0
)
public void cui(Player player, LocalSession session, CommandContext args) throws WorldEditException {
public void cui(Player player, LocalSession session) throws WorldEditException {
session.setCUISupport(true);
session.dispatchCUISetup(player);
}

View File

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

View File

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

View File

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

View File

@ -25,13 +25,15 @@ import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.world.block.BlockState;
/**
* A mode that replaces one block.
*/
public class BlockReplacer implements DoubleActionBlockTool {
@ -58,7 +60,6 @@ public class BlockReplacer implements DoubleActionBlockTool {
if (bag != null) {
bag.flushChanges();
}
session.remember(editSession);
}
return true;

View File

@ -472,14 +472,6 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
MaskIntersection newMask = new MaskIntersection(existingMask);
newMask.add(mask);
editSession.setMask(newMask);
//=======
// try {
// brush.build(editSession, target.toBlockPoint(), material, size);
// } catch (MaxChangedBlocksException e) {
// player.printError("Max blocks change limit reached.");
// } finally {
// session.remember(editSession);
//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
}
}
Mask sourceMask = current.getSourceMask();

View File

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

View File

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

View File

@ -53,7 +53,6 @@ public class RecursivePickaxe implements BlockTool {
editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);
//<<<<<<< HEAD
final int radius = (int) range;
final BlockReplace replace = new BlockReplace(editSession, (editSession.nullBlock));
editSession.setMask((Mask) null);
@ -63,51 +62,6 @@ public class RecursivePickaxe implements BlockTool {
editSession.flushQueue();
session.remember(editSession);
//=======
// try {
// recurse(server, editSession, world, clicked.toBlockPoint(),
// clicked.toBlockPoint(), range, initialType, new HashSet<>());
// } catch (MaxChangedBlocksException e) {
// player.printError("Max blocks change limit reached.");
// } finally {
// session.remember(editSession);
// }
// }
//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
return true;
}
// private static void recurse(Platform server, EditSession editSession, World world, BlockVector3 pos,
// BlockVector3 origin, double size, BlockType initialType, Set<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()) {
return true;
}
final EditSession editSession = session.createEditSession(player);
try {
try (EditSession editSession = session.createEditSession(player)) {
editSession.getSurvivalExtent().setToolUse(config.superPickaxeDrop);
editSession.setBlock(blockPoint, BlockTypes.AIR.getDefaultState());
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
}
try {
if (editSession.setBlock(clicked.getBlockX(), clicked.getBlockY(), clicked.getBlockZ(), EditSession.nullBlock)) {
// TODO FIXME play effect
// world.playEffect(clicked, 2001, blockType);
}
} finally {
editSession.flushQueue();
session.remember(editSession);
}
return true;
}

View File

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

View File

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

View File

@ -21,12 +21,14 @@ package com.sk89q.worldedit.command.tool.brush;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class GravityBrush implements Brush {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,9 +20,6 @@
package com.sk89q.worldedit.event.extent;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.event.Cancellable;
import com.sk89q.worldedit.event.Event;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.Extent;

View File

@ -21,7 +21,6 @@ package com.sk89q.worldedit.extension.factory;
import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.extension.factory.parser.DefaultBlockParser;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;

View File

@ -55,14 +55,7 @@ public final class MaskFactory extends AbstractFactory<Mask> {
*/
public MaskFactory(WorldEdit worldEdit) {
super(worldEdit);
register(new ExistingMaskParser(worldEdit));
register(new SolidMaskParser(worldEdit));
register(new LazyRegionMaskParser(worldEdit));
register(new RegionMaskParser(worldEdit));
register(new BlockCategoryMaskParser(worldEdit));
register(new NoiseMaskParser(worldEdit));
register(new NegateMaskParser(worldEdit));
register(new DefaultMaskParser(worldEdit));
}
@ -90,7 +83,7 @@ public final class MaskFactory extends AbstractFactory<Mask> {
case 1:
return masks.get(0);
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.extension.factory.parser.pattern.BlockCategoryPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.ClipboardPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.DefaultPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.RandomPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.RandomStatePatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.SingleBlockPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.TypeOrStateApplyingPatternParser;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.registry.AbstractFactory;
@ -44,10 +45,6 @@ public final class PatternFactory extends AbstractFactory<Pattern> {
*/
public PatternFactory(WorldEdit worldEdit) {
super(worldEdit);
// register(new ClipboardPatternParser(worldEdit));
// register(new SingleBlockPatternParser(worldEdit));
// register(new RandomPatternParser(worldEdit));
register(new BlockCategoryPatternParser(worldEdit));
register(new DefaultPatternParser(worldEdit));
}

View File

@ -24,12 +24,6 @@ import com.boydti.fawe.jnbt.JSON2NBT;
import com.boydti.fawe.jnbt.NBTException;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.StringMan;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.NotABlockException;
import com.sk89q.worldedit.WorldEdit;

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.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.BlockCategoryMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.world.block.BlockCategories;
import com.sk89q.worldedit.session.request.RequestExtent;
import com.sk89q.worldedit.world.block.BlockCategory;
public class BlockCategoryMaskParser extends InputParser<Mask> {
@ -38,18 +36,16 @@ public class BlockCategoryMaskParser extends InputParser<Mask> {
@Override
public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
if (input.startsWith("##")) {
Extent extent = Request.request().getEditSession();
// This means it's a tag mask.
BlockCategory category = BlockCategories.get(input.substring(2).toLowerCase());
if (category == null) {
throw new InputParseException("Unrecognised tag '" + input.substring(2) + '\'');
} else {
return new BlockCategoryMask(extent, category);
}
if (!input.startsWith("##")) {
return null;
}
return null;
// This means it's a tag mask.
BlockCategory category = BlockCategory.REGISTRY.get(input.substring(2).toLowerCase());
if (category == null) {
throw new InputParseException("Unrecognised tag '" + input.substring(2) + '\'');
} else {
return new BlockCategoryMask(new RequestExtent(), category);
}
}
}

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

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

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.RandomPattern;
import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.world.block.BlockCategories;
import com.sk89q.worldedit.world.block.BlockCategory;
import com.sk89q.worldedit.world.block.BlockType;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class BlockCategoryPatternParser extends InputParser<Pattern> {
@ -46,17 +46,34 @@ public class BlockCategoryPatternParser extends InputParser<Pattern> {
@Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
if(!input.startsWith("##")) {
if (!input.startsWith("##")) {
return null;
}
BlockCategory category = BlockCategories.get(input.substring(2).toLowerCase());
String tag = input.substring(2).toLowerCase();
boolean anyState = false;
if (tag.startsWith("*")) {
tag = tag.substring(1);
anyState = true;
}
BlockCategory category = BlockCategory.REGISTRY.get(tag);
if (category == null) {
throw new InputParseException("Unknown block tag: " + input.substring(2));
throw new InputParseException("Unknown block tag: " + tag);
}
RandomPattern randomPattern = new RandomPattern();
for (BlockType blockType : category.getAll()) {
randomPattern.add(new BlockPattern(blockType.getDefaultState()), 1.0 / category.getAll().size());
Set<BlockType> blocks = category.getAll();
if (blocks.isEmpty()) {
throw new InputParseException("Block tag " + category.getId() + " had no blocks!");
}
if (anyState) {
blocks.stream().flatMap(blockType -> blockType.getAllStates().stream()).forEach(state ->
randomPattern.add(new BlockPattern(state), 1.0));
} else {
for (BlockType blockType : blocks) {
randomPattern.add(new BlockPattern(blockType.getDefaultState()), 1.0);
}
}
return randomPattern;

View File

@ -19,189 +19,68 @@
package com.sk89q.worldedit.extension.factory.parser.pattern;
import com.boydti.fawe.command.FaweParser;
import com.boydti.fawe.command.SuggestInputParseException;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.random.TrueRandom;
import com.boydti.fawe.util.StringMan;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.EmptyClipboardException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.PatternCommands;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.NoMatchException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.pattern.ClipboardPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.RandomPattern;
import com.sk89q.worldedit.internal.command.ActorAuthorizer;
import com.sk89q.worldedit.internal.command.WorldEditBinding;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.util.command.SimpleDispatcher;
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.session.ClipboardHolder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ClipboardPatternParser extends FaweParser<Pattern> {
private final Dispatcher dispatcher;
public class ClipboardPatternParser extends InputParser<Pattern> {
public ClipboardPatternParser(WorldEdit worldEdit) {
super(worldEdit);
this.dispatcher = new SimpleDispatcher();
this.register(new PatternCommands(worldEdit));
}
@Override
public Dispatcher getDispatcher() {
return dispatcher;
}
public void register(Object clazz) {
ParametricBuilder builder = new ParametricBuilder();
builder.setAuthorizer(new ActorAuthorizer());
builder.addBinding(new WorldEditBinding(worldEdit));
builder.registerMethodsAsCommands(dispatcher, clazz);
public List<String> getSuggestions() {
return Lists.newArrayList("#clipboard", "#copy");
}
@Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
if (input.isEmpty()) {
throw new SuggestInputParseException("No input provided", "", () -> Stream.concat(Stream.of("#", ",", "&"), BlockTypes.getNameSpaces().stream().map(n -> n + ":")).collect(Collectors.toList()));
}
List<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()) {
String[] offsetParts = input.split("@", 2);
if (!offsetParts[0].equalsIgnoreCase("#clipboard") && !offsetParts[0].equalsIgnoreCase("#copy")) {
return null;
} else if (patterns.size() == 1) {
return patterns.get(0);
}
LocalSession session = context.requireSession();
BlockVector3 offset = BlockVector3.ZERO;
if (offsetParts.length == 2) {
String coords = offsetParts[1];
if (coords.length() < 7 // min length of `[x,y,z]`
|| coords.charAt(0) != '[' || coords.charAt(coords.length() - 1) != ']') {
throw new InputParseException("Offset specified with @ but no offset given. Use '#copy@[x,y,z]'.");
}
String[] offsetSplit = coords.substring(1, coords.length() - 1).split(",");
if (offsetSplit.length != 3) {
throw new InputParseException("Clipboard offset needs x,y,z coordinates.");
}
offset = BlockVector3.at(
Integer.valueOf(offsetSplit[0]),
Integer.valueOf(offsetSplit[1]),
Integer.valueOf(offsetSplit[2])
);
}
if (session != null) {
try {
ClipboardHolder holder = session.getClipboard();
Clipboard clipboard = holder.getClipboard();
return new ClipboardPattern(clipboard, offset);
} catch (EmptyClipboardException e) {
throw new InputParseException("To use #clipboard, please first copy something to your clipboard");
}
} else {
RandomPattern random = new RandomPattern(new TrueRandom());
for (int i = 0; i < patterns.size(); i++) {
random.add(patterns.get(i), chances.get(i));
}
return random;
}
throw new InputParseException("No session is available, so no clipboard is available");
}
}
}

View File

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

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
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
String[] items = input.split(",");
if (items.length == 1) {
return new BlockPattern(worldEdit.getBlockFactory().parseFromInput(items[0], context));
} else {
return null;
}
return new BlockPattern(worldEdit.getBlockFactory().parseFromInput(input, context));
}
}

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;
import com.sk89q.worldedit.NotABlockException;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.internal.cui.CUIEvent;
@ -31,6 +31,7 @@ import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.TargetBlock;
import com.sk89q.worldedit.util.auth.AuthorizationException;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
@ -118,7 +119,6 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
final BlockVector3 pos = BlockVector3.at(x, y - 2, z);
final BlockStateHolder state = world.getBlock(pos);
setPosition(Vector3.at(x + 0.5, y - 2 + BlockTypeUtil.centralTopLimit(state), z + 0.5));
// setPosition(Vector3.at(x + 0.5, y - 2 + 1, z + 0.5));
}
return;

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

View File

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

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