Switch to Gradle. Use git log --follow for history.

This converts the project into a multi-module Gradle build.

By default, Git does not show history past a rename, so use git log
--follow to see further history.
This commit is contained in:
sk89q
2014-11-14 11:27:39 -08:00
parent 44559cde68
commit 7192780251
714 changed files with 333 additions and 834 deletions

View File

@ -0,0 +1,42 @@
/*
* 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.platform;
import com.sk89q.worldedit.world.World;
import java.util.Collections;
import java.util.List;
/**
* An abstract implementation of {@link Platform}.
*/
public abstract class AbstractPlatform implements Platform {
@Override
public int schedule(long delay, long period, Runnable task) {
return -1;
}
@Override
public List<? extends World> getWorlds() {
return Collections.emptyList();
}
}

View File

@ -0,0 +1,494 @@
/*
* 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.platform;
import com.sk89q.worldedit.util.auth.AuthorizationException;
import com.sk89q.worldedit.BlockWorldVector;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.NotABlockException;
import com.sk89q.worldedit.PlayerDirection;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.WorldVector;
import com.sk89q.worldedit.WorldVectorFace;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.blocks.ItemID;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import com.sk89q.worldedit.util.TargetBlock;
import com.sk89q.worldedit.world.World;
import java.io.File;
/**
* An abstract implementation of both a {@link Actor} and a {@link Player}
* that is intended for implementations of WorldEdit to use to wrap
* players that make use of WorldEdit.
*/
public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
@Override
public final Extent getExtent() {
return getWorld();
}
/**
* Returns direction according to rotation. May return null.
*
* @param rot yaw
* @return the direction
*/
private static PlayerDirection getDirection(double rot) {
if (0 <= rot && rot < 22.5) {
return PlayerDirection.SOUTH;
} else if (22.5 <= rot && rot < 67.5) {
return PlayerDirection.SOUTH_WEST;
} else if (67.5 <= rot && rot < 112.5) {
return PlayerDirection.WEST;
} else if (112.5 <= rot && rot < 157.5) {
return PlayerDirection.NORTH_WEST;
} else if (157.5 <= rot && rot < 202.5) {
return PlayerDirection.NORTH;
} else if (202.5 <= rot && rot < 247.5) {
return PlayerDirection.NORTH_EAST;
} else if (247.5 <= rot && rot < 292.5) {
return PlayerDirection.EAST;
} else if (292.5 <= rot && rot < 337.5) {
return PlayerDirection.SOUTH_EAST;
} else if (337.5 <= rot && rot < 360.0) {
return PlayerDirection.SOUTH;
} else {
return null;
}
}
@Override
public boolean isHoldingPickAxe() {
int item = getItemInHand();
return item == ItemID.IRON_PICK
|| item == ItemID.WOOD_PICKAXE
|| item == ItemID.STONE_PICKAXE
|| item == ItemID.DIAMOND_PICKAXE
|| item == ItemID.GOLD_PICKAXE;
}
@Override
public void findFreePosition(WorldVector searchPos) {
World world = searchPos.getWorld();
int x = searchPos.getBlockX();
int y = Math.max(0, searchPos.getBlockY());
int origY = y;
int z = searchPos.getBlockZ();
byte free = 0;
while (y <= world.getMaxY() + 2) {
if (BlockType.canPassThrough(world.getBlock(new Vector(x, y, z)))) {
++free;
} else {
free = 0;
}
if (free == 2) {
if (y - 1 != origY) {
final Vector pos = new Vector(x, y - 2, z);
final int id = world.getBlockType(pos);
final int data = world.getBlockData(pos);
setPosition(new Vector(x + 0.5, y - 2 + BlockType.centralTopLimit(id, data), z + 0.5));
}
return;
}
++y;
}
}
@Override
public void setOnGround(WorldVector searchPos) {
World world = searchPos.getWorld();
int x = searchPos.getBlockX();
int y = Math.max(0, searchPos.getBlockY());
int z = searchPos.getBlockZ();
while (y >= 0) {
final Vector pos = new Vector(x, y, z);
final int id = world.getBlockType(pos);
final int data = world.getBlockData(pos);
if (!BlockType.canPassThrough(id, data)) {
setPosition(new Vector(x + 0.5, y + BlockType.centralTopLimit(id, data), z + 0.5));
return;
}
--y;
}
}
@Override
public void findFreePosition() {
findFreePosition(getBlockIn());
}
@Override
public boolean ascendLevel() {
final WorldVector pos = getBlockIn();
final int x = pos.getBlockX();
int y = Math.max(0, pos.getBlockY());
final int z = pos.getBlockZ();
final World world = pos.getWorld();
byte free = 0;
byte spots = 0;
while (y <= world.getMaxY() + 2) {
if (BlockType.canPassThrough(world.getBlock(new Vector(x, y, z)))) {
++free;
} else {
free = 0;
}
if (free == 2) {
++spots;
if (spots == 2) {
final Vector platform = new Vector(x, y - 2, z);
final BaseBlock block = world.getBlock(platform);
final int type = block.getId();
// Don't get put in lava!
if (type == BlockID.LAVA || type == BlockID.STATIONARY_LAVA) {
return false;
}
setPosition(platform.add(0.5, BlockType.centralTopLimit(block), 0.5));
return true;
}
}
++y;
}
return false;
}
@Override
public boolean descendLevel() {
final WorldVector pos = getBlockIn();
final int x = pos.getBlockX();
int y = Math.max(0, pos.getBlockY() - 1);
final int z = pos.getBlockZ();
final World world = pos.getWorld();
byte free = 0;
while (y >= 1) {
if (BlockType.canPassThrough(world.getBlock(new Vector(x, y, z)))) {
++free;
} else {
free = 0;
}
if (free == 2) {
// So we've found a spot, but we have to drop the player
// lightly and also check to see if there's something to
// stand upon
while (y >= 0) {
final Vector platform = new Vector(x, y, z);
final BaseBlock block = world.getBlock(platform);
final int type = block.getId();
// Don't want to end up in lava
if (type != BlockID.AIR && type != BlockID.LAVA && type != BlockID.STATIONARY_LAVA) {
// Found a block!
setPosition(platform.add(0.5, BlockType.centralTopLimit(block), 0.5));
return true;
}
--y;
}
return false;
}
--y;
}
return false;
}
@Override
public boolean ascendToCeiling(int clearance) {
return ascendToCeiling(clearance, true);
}
@Override
public boolean ascendToCeiling(int clearance, boolean alwaysGlass) {
Vector pos = getBlockIn();
int x = pos.getBlockX();
int initialY = Math.max(0, pos.getBlockY());
int y = Math.max(0, pos.getBlockY() + 2);
int z = pos.getBlockZ();
World world = getPosition().getWorld();
// No free space above
if (world.getBlockType(new Vector(x, y, z)) != 0) {
return false;
}
while (y <= world.getMaxY()) {
// Found a ceiling!
if (!BlockType.canPassThrough(world.getBlock(new Vector(x, y, z)))) {
int platformY = Math.max(initialY, y - 3 - clearance);
floatAt(x, platformY + 1, z, alwaysGlass);
return true;
}
++y;
}
return false;
}
@Override
public boolean ascendUpwards(int distance) {
return ascendUpwards(distance, true);
}
@Override
public boolean ascendUpwards(int distance, boolean alwaysGlass) {
final Vector pos = getBlockIn();
final int x = pos.getBlockX();
final int initialY = Math.max(0, pos.getBlockY());
int y = Math.max(0, pos.getBlockY() + 1);
final int z = pos.getBlockZ();
final int maxY = Math.min(getWorld().getMaxY() + 1, initialY + distance);
final World world = getPosition().getWorld();
while (y <= world.getMaxY() + 2) {
if (!BlockType.canPassThrough(world.getBlock(new Vector(x, y, z)))) {
break; // Hit something
} else if (y > maxY + 1) {
break;
} else if (y == maxY + 1) {
floatAt(x, y - 1, z, alwaysGlass);
return true;
}
++y;
}
return false;
}
@Override
public void floatAt(int x, int y, int z, boolean alwaysGlass) {
getPosition().getWorld().setBlockType(new Vector(x, y - 1, z), BlockID.GLASS);
setPosition(new Vector(x + 0.5, y, z + 0.5));
}
@Override
public WorldVector getBlockIn() {
WorldVector pos = getPosition();
return WorldVector.toBlockPoint(pos.getWorld(), pos.getX(),
pos.getY(), pos.getZ());
}
@Override
public WorldVector getBlockOn() {
WorldVector pos = getPosition();
return WorldVector.toBlockPoint(pos.getWorld(), pos.getX(),
pos.getY() - 1, pos.getZ());
}
@Override
public WorldVector getBlockTrace(int range, boolean useLastBlock) {
TargetBlock tb = new TargetBlock(this, range, 0.2);
return (useLastBlock ? tb.getAnyTargetBlock() : tb.getTargetBlock());
}
@Override
public WorldVectorFace getBlockTraceFace(int range, boolean useLastBlock) {
TargetBlock tb = new TargetBlock(this, range, 0.2);
return (useLastBlock ? tb.getAnyTargetBlockFace() : tb.getTargetBlockFace());
}
@Override
public WorldVector getBlockTrace(int range) {
return getBlockTrace(range, false);
}
@Override
public WorldVector getSolidBlockTrace(int range) {
TargetBlock tb = new TargetBlock(this, range, 0.2);
return tb.getSolidTargetBlock();
}
@Override
public PlayerDirection getCardinalDirection() {
return getCardinalDirection(0);
}
@Override
public PlayerDirection getCardinalDirection(int yawOffset) {
if (getPitch() > 67.5) {
return PlayerDirection.DOWN;
}
if (getPitch() < -67.5) {
return PlayerDirection.UP;
}
// From hey0's code
double rot = (getYaw() + yawOffset) % 360; //let's use real yaw now
if (rot < 0) {
rot += 360.0;
}
return getDirection(rot);
}
@Override
public BaseBlock getBlockInHand() throws WorldEditException {
final int typeId = getItemInHand();
if (!getWorld().isValidBlockType(typeId)) {
throw new NotABlockException(typeId);
}
return new BaseBlock(typeId);
}
/**
* Get the player's view yaw.
*
* @return yaw
*/
@Override
public boolean passThroughForwardWall(int range) {
int searchDist = 0;
TargetBlock hitBlox = new TargetBlock(this, range, 0.2);
World world = getPosition().getWorld();
BlockWorldVector block;
boolean firstBlock = true;
int freeToFind = 2;
boolean inFree = false;
while ((block = hitBlox.getNextBlock()) != null) {
boolean free = BlockType.canPassThrough(world.getBlock(block));
if (firstBlock) {
firstBlock = false;
if (!free) {
--freeToFind;
continue;
}
}
++searchDist;
if (searchDist > 20) {
return false;
}
if (inFree != free) {
if (free) {
--freeToFind;
}
}
if (freeToFind == 0) {
setOnGround(block);
return true;
}
inFree = free;
}
return false;
}
@Override
public void setPosition(Vector pos) {
setPosition(pos, (float) getPitch(), (float) getYaw());
}
@Override
public File openFileOpenDialog(String[] extensions) {
printError("File dialogs are not supported in your environment.");
return null;
}
@Override
public File openFileSaveDialog(String[] extensions) {
printError("File dialogs are not supported in your environment.");
return null;
}
@Override
public boolean canDestroyBedrock() {
return hasPermission("worldedit.override.bedrock");
}
@Override
public void dispatchCUIEvent(CUIEvent event) {
}
@Override
public boolean equals(Object other) {
if (!(other instanceof LocalPlayer)) {
return false;
}
LocalPlayer other2 = (LocalPlayer) other;
return other2.getName().equals(getName());
}
@Override
public int hashCode() {
return getName().hashCode();
}
@Override
public void checkPermission(String permission) throws AuthorizationException {
if (!hasPermission(permission)) {
throw new AuthorizationException();
}
}
@Override
public boolean isPlayer() {
return true;
}
@Override
public boolean hasCreativeMode() {
return false;
}
@SuppressWarnings("CloneDoesntCallSuperClone")
@Override
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("Not supported");
}
@Override
public boolean remove() {
return false;
}
}

View File

@ -0,0 +1,106 @@
/*
* 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.platform;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import com.sk89q.worldedit.session.SessionOwner;
import com.sk89q.worldedit.util.Identifiable;
import com.sk89q.worldedit.util.auth.Subject;
import java.io.File;
/**
* An object that can perform actions in WorldEdit.
*/
public interface Actor extends Identifiable, SessionOwner, Subject {
/**
* Get the name of the actor.
*
* @return String
*/
String getName();
/**
* Print a message.
*
* @param msg The message text
*/
void printRaw(String msg);
/**
* Print a WorldEdit message.
*
* @param msg The message text
*/
void printDebug(String msg);
/**
* Print a WorldEdit message.
*
* @param msg The message text
*/
void print(String msg);
/**
* Print a WorldEdit error.
*
* @param msg The error message text
*/
void printError(String msg);
/**
* Returns true if the actor can destroy bedrock.
*
* @return true if bedrock can be broken by the actor
*/
boolean canDestroyBedrock();
/**
* Return whether this actor is a player.
*
* @return true if a player
*/
boolean isPlayer();
/**
* Open a file open dialog.
*
* @param extensions null to allow all
* @return the selected file or null if something went wrong
*/
File openFileOpenDialog(String[] extensions);
/**
* Open a file save dialog.
*
* @param extensions null to allow all
* @return the selected file or null if something went wrong
*/
File openFileSaveDialog(String[] extensions);
/**
* Send a CUI event.
*
* @param event the event
*/
void dispatchCUIEvent(CUIEvent event);
}

View File

@ -0,0 +1,86 @@
/*
* 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.platform;
/**
* A collection of capabilities that a {@link Platform} may support.
*/
public enum Capability {
/**
* The capability of registering game hooks to catch events such as
* a player clicking a block.
*/
GAME_HOOKS {
@Override
void initialize(PlatformManager platformManager, Platform platform) {
platform.registerGameHooks();
}
@Override
void unload(PlatformManager platformManager, Platform platform) {
}
},
/**
* The capability of providing configuration.
*/
CONFIGURATION,
/**
* The capability of handling user commands entered in chat or console.
*/
USER_COMMANDS {
@Override
void initialize(PlatformManager platformManager, Platform platform) {
platformManager.getCommandManager().register(platform);
}
@Override
void unload(PlatformManager platformManager, Platform platform) {
platformManager.getCommandManager().unregister();
}
},
/**
* The capability of a platform to assess whether a given
* {@link Actor} has sufficient authorization to perform a task.
*/
PERMISSIONS,
/**
* The capability of a platform to dispatch WorldEditCUI events.
*/
WORLDEDIT_CUI,
/**
* The capability of a platform to perform modifications to a world.
*/
WORLD_EDITING;
void initialize(PlatformManager platformManager, Platform platform) {
}
void unload(PlatformManager platformManager, Platform platform) {
}
}

View File

@ -0,0 +1,304 @@
/*
* 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.platform;
import com.google.common.base.Joiner;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
import com.sk89q.minecraft.util.commands.WrappedCommandException;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.*;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
import com.sk89q.worldedit.internal.command.ActorAuthorizer;
import com.sk89q.worldedit.internal.command.CommandLoggingHandler;
import com.sk89q.worldedit.internal.command.UserCommandCompleter;
import com.sk89q.worldedit.internal.command.WorldEditBinding;
import com.sk89q.worldedit.internal.command.WorldEditExceptionConverter;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.util.command.InvalidUsageException;
import com.sk89q.worldedit.util.command.fluent.CommandGraph;
import com.sk89q.worldedit.util.command.parametric.LegacyCommandsHandler;
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
import com.sk89q.worldedit.util.eventbus.Subscribe;
import com.sk89q.worldedit.util.formatting.ColorCodeBuilder;
import com.sk89q.worldedit.util.formatting.component.CommandUsageBox;
import com.sk89q.worldedit.util.logging.DynamicStreamHandler;
import com.sk89q.worldedit.util.logging.LogFormat;
import java.io.File;
import java.io.IOException;
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;
/**
* Handles the registration and invocation of commands.
*
* <p>This class is primarily for internal usage.</p>
*/
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 java.util.regex.Pattern numberFormatExceptionPattern = java.util.regex.Pattern.compile("^For input string: \"(.*)\"$");
private final WorldEdit worldEdit;
private final PlatformManager platformManager;
private final Dispatcher dispatcher;
private final DynamicStreamHandler dynamicHandler = new DynamicStreamHandler();
/**
* Create a new instance.
*
* @param worldEdit the WorldEdit instance
*/
CommandManager(final WorldEdit worldEdit, PlatformManager platformManager) {
checkNotNull(worldEdit);
checkNotNull(platformManager);
this.worldEdit = worldEdit;
this.platformManager = platformManager;
// Register this instance for command events
worldEdit.getEventBus().register(this);
// Setup the logger
commandLog.addHandler(dynamicHandler);
dynamicHandler.setFormatter(new LogFormat());
// Set up the commands manager
ParametricBuilder builder = new ParametricBuilder();
builder.setAuthorizer(new ActorAuthorizer());
builder.setDefaultCompleter(new UserCommandCompleter(platformManager));
builder.addBinding(new WorldEditBinding(worldEdit));
builder.addExceptionConverter(new WorldEditExceptionConverter(worldEdit));
builder.addInvokeListener(new LegacyCommandsHandler());
builder.addInvokeListener(new CommandLoggingHandler(worldEdit, commandLog));
dispatcher = new CommandGraph()
.builder(builder)
.commands()
.registerMethods(new BiomeCommands(worldEdit))
.registerMethods(new ChunkCommands(worldEdit))
.registerMethods(new ClipboardCommands(worldEdit))
.registerMethods(new GeneralCommands(worldEdit))
.registerMethods(new GenerationCommands(worldEdit))
.registerMethods(new HistoryCommands(worldEdit))
.registerMethods(new NavigationCommands(worldEdit))
.registerMethods(new RegionCommands(worldEdit))
.registerMethods(new ScriptingCommands(worldEdit))
.registerMethods(new SelectionCommands(worldEdit))
.registerMethods(new SnapshotUtilCommands(worldEdit))
.registerMethods(new ToolUtilCommands(worldEdit))
.registerMethods(new ToolCommands(worldEdit))
.registerMethods(new UtilityCommands(worldEdit))
.group("worldedit", "we")
.describeAs("WorldEdit commands")
.registerMethods(new WorldEditCommands(worldEdit))
.parent()
.group("schematic", "schem", "/schematic", "/schem")
.describeAs("Schematic commands for saving/loading areas")
.registerMethods(new SchematicCommands(worldEdit))
.parent()
.group("snapshot", "snap")
.describeAs("Schematic commands for saving/loading areas")
.registerMethods(new SnapshotCommands(worldEdit))
.parent()
.group("brush", "br")
.describeAs("Brushing commands")
.registerMethods(new BrushCommands(worldEdit))
.parent()
.group("superpickaxe", "pickaxe", "sp")
.describeAs("Super-pickaxe commands")
.registerMethods(new SuperPickaxeCommands(worldEdit))
.parent()
.group("tool")
.describeAs("Bind functions to held items")
.registerMethods(new ToolCommands(worldEdit))
.parent()
.graph()
.getDispatcher();
}
void register(Platform platform) {
log.log(Level.FINE, "Registering commands with " + platform.getClass().getCanonicalName());
LocalConfiguration config = platform.getConfiguration();
boolean logging = config.logCommands;
String path = config.logFile;
// Register log
if (!logging || path.isEmpty()) {
dynamicHandler.setHandler(null);
commandLog.setLevel(Level.OFF);
} else {
File file = new File(config.getWorkingDirectory(), path);
commandLog.setLevel(Level.ALL);
log.log(Level.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());
}
}
platform.registerCommands(dispatcher);
}
void unregister() {
dynamicHandler.setHandler(null);
}
public String[] commandDetection(String[] split) {
// Quick script shortcut
if (split[0].matches("^[^/].*\\.js$")) {
String[] newSplit = new String[split.length + 1];
System.arraycopy(split, 0, newSplit, 1, split.length);
newSplit[0] = "cs";
newSplit[1] = newSplit[1];
split = newSplit;
}
String searchCmd = split[0].toLowerCase();
// Try to detect the command
if (!dispatcher.contains(searchCmd)) {
if (worldEdit.getConfiguration().noDoubleSlash && dispatcher.contains("/" + searchCmd)) {
split[0] = "/" + split[0];
} else if (searchCmd.length() >= 2 && searchCmd.charAt(0) == '/' && dispatcher.contains(searchCmd.substring(1))) {
split[0] = split[0].substring(1);
}
}
return split;
}
@Subscribe
public void handleCommand(CommandEvent event) {
Request.reset();
Actor actor = platformManager.createProxyActor(event.getActor());
String[] split = commandDetection(event.getArguments().split(" "));
// No command found!
if (!dispatcher.contains(split[0])) {
return;
}
LocalSession session = worldEdit.getSessionManager().get(actor);
LocalConfiguration config = worldEdit.getConfiguration();
CommandLocals locals = new CommandLocals();
locals.put(Actor.class, actor);
long start = System.currentTimeMillis();
try {
dispatcher.call(Joiner.on(" ").join(split), locals, new String[0]);
} catch (CommandPermissionsException e) {
actor.printError("You don't have permission to do this.");
} catch (InvalidUsageException e) {
if (e.isFullHelpSuggested()) {
actor.printRaw(ColorCodeBuilder.asColorCodes(new CommandUsageBox(e.getCommand(), e.getCommandUsed("/", ""), locals)));
String message = e.getMessage();
if (message != null) {
actor.printError(message);
}
} else {
String message = e.getMessage();
actor.printError(message != null ? message : "The command was not used properly (no more help available).");
actor.printError("Usage: " + e.getSimpleUsageString("/"));
}
} catch (WrappedCommandException e) {
Throwable t = e.getCause();
actor.printError("Please report this error: [See console]");
actor.printRaw(t.getClass().getName() + ": " + t.getMessage());
log.log(Level.SEVERE, "An unexpected error while handling a WorldEdit command", t);
} catch (CommandException e) {
String message = e.getMessage();
if (message != null) {
actor.printError(e.getMessage());
} else {
actor.printError("An unknown error has occurred! Please see console.");
log.log(Level.SEVERE, "An unknown error occurred", e);
}
} finally {
EditSession editSession = locals.get(EditSession.class);
if (editSession != null) {
session.remember(editSession);
editSession.flushQueue();
if (config.profile) {
long time = System.currentTimeMillis() - start;
int changed = editSession.getBlockChangeCount();
if (time > 0) {
double throughput = changed / (time / 1000.0);
actor.printDebug((time / 1000.0) + "s elapsed (history: "
+ changed + " changed; "
+ Math.round(throughput) + " blocks/sec).");
} else {
actor.printDebug((time / 1000.0) + "s elapsed.");
}
}
worldEdit.flushBlockBag(actor, editSession);
}
}
event.setCancelled(true);
}
@Subscribe
public void handleCommandSuggestion(CommandSuggestionEvent event) {
try {
CommandLocals locals = new CommandLocals();
locals.put(Actor.class, event.getActor());
event.setSuggestions(dispatcher.getSuggestions(event.getArguments(), locals));
} catch (CommandException e) {
event.getActor().printError(e.getMessage());
}
}
/**
* Get the command dispatcher instance.
*
* @return the command dispatcher
*/
public Dispatcher getDispatcher() {
return dispatcher;
}
public static Logger getLogger() {
return commandLog;
}
}

View File

@ -0,0 +1,36 @@
/*
* 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.platform;
import java.util.Collection;
/**
* Implements a platform with multiple connected users.
*/
public interface MultiUserPlatform extends Platform {
/**
* Get a list of connected users.
*
* @return a list of connected users
*/
Collection<Actor> getConnectedUsers();
}

View File

@ -0,0 +1,42 @@
/*
* 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.platform;
/**
* Thrown when no capable platform is found.
*/
public class NoCapablePlatformException extends RuntimeException {
public NoCapablePlatformException() {
}
public NoCapablePlatformException(String message) {
super(message);
}
public NoCapablePlatformException(String message, Throwable cause) {
super(message, cause);
}
public NoCapablePlatformException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,153 @@
/*
* 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.platform;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.world.World;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
/**
* Represents a platform that WorldEdit has been implemented for.
*
* <p>It is strongly recommended that implementations extend from
* {@link AbstractPlatform}.</p>
*/
public interface Platform {
/**
* Resolves an item name to its ID.
*
* @param name The name to look up
* @return The id that corresponds to the name, or -1 if no such ID exists
*/
int resolveItem(String name);
/**
* Checks if a mob type is valid.
*
* @param type The mob type name to check
* @return Whether the name is a valid mod bype
*/
boolean isValidMobType(String type);
/**
* Reload WorldEdit configuration.
*/
void reload();
/**
* Schedules the given {@code task} to be invoked once every
* {@code period} ticks after an initial delay of {@code delay} ticks.
*
* @param delay Delay in server ticks before executing first repeat
* @param period Period in server ticks of the task
* @param task Task to be executed
* @return Task id number (-1 if scheduling failed)
*/
int schedule(long delay, long period, Runnable task);
/**
* Get a list of available or loaded worlds.
*
* @return a list of worlds
*/
List<? extends World> getWorlds();
/**
* Create a duplicate of the given player.
*
* <p>The given player may have been provided by a different platform.</p>
*
* @param player the player to match
* @return a matched player, otherwise null
*/
@Nullable Player matchPlayer(Player player);
/**
* Create a duplicate of the given world.
*
* <p>The given world may have been provided by a different platform.</p>
*
* @param world the world to match
* @return a matched world, otherwise null
*/
@Nullable World matchWorld(World world);
/**
* Register the commands contained within the given command dispatcher.
*
* @param dispatcher the dispatcher
*/
void registerCommands(Dispatcher dispatcher);
/**
* Register game hooks.
*/
void registerGameHooks();
/**
* Get the configuration from this platform.
*
* @return the configuration
*/
LocalConfiguration getConfiguration();
/**
* Get the version of WorldEdit that this platform provides.
*
* <p>This version should match WorldEdit releases because it may be
* checked to match.</p>
*
* @return the version
*/
String getVersion();
/**
* Get a friendly name of the platform.
*
* <p>The name can be anything (reasonable). An example name may be
* "Bukkit" or "Forge".</p>
*
* @return the platform name
*/
String getPlatformName();
/**
* Get the version of the platform, which can be anything.
*
* @return the platform version
*/
String getPlatformVersion();
/**
* Get a map of advertised capabilities of this platform, where each key
* in the given map is a supported capability and the respective value
* indicates the preference for this platform for that given capability.
*
* @return a map of capabilities
*/
Map<Capability, Preference> getCapabilities();
}

View File

@ -0,0 +1,466 @@
/*
* 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.platform;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.ServerInterface;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldVector;
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;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.platform.BlockInteractEvent;
import com.sk89q.worldedit.event.platform.ConfigurationLoadEvent;
import com.sk89q.worldedit.event.platform.Interaction;
import com.sk89q.worldedit.event.platform.PlatformInitializeEvent;
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
import com.sk89q.worldedit.event.platform.PlayerInputEvent;
import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
import com.sk89q.worldedit.internal.ServerInterfaceAdapter;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.eventbus.Subscribe;
import com.sk89q.worldedit.world.World;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Manages registered {@link Platform}s for WorldEdit. Platforms are
* implementations of WorldEdit.
*
* <p>This class is thread-safe.</p>
*/
public class PlatformManager {
private static final Logger logger = Logger.getLogger(PlatformManager.class.getCanonicalName());
private final WorldEdit worldEdit;
private final CommandManager commandManager;
private final List<Platform> platforms = new ArrayList<Platform>();
private final Map<Capability, Platform> preferences = new EnumMap<Capability, Platform>(Capability.class);
private @Nullable String firstSeenVersion;
private final AtomicBoolean initialized = new AtomicBoolean();
private final AtomicBoolean configured = new AtomicBoolean();
/**
* Create a new platform manager.
*
* @param worldEdit the WorldEdit instance
*/
public PlatformManager(WorldEdit worldEdit) {
checkNotNull(worldEdit);
this.worldEdit = worldEdit;
this.commandManager = new CommandManager(worldEdit, this);
// Register this instance for events
worldEdit.getEventBus().register(this);
}
/**
* Register a platform with WorldEdit.
*
* @param platform the platform
*/
public synchronized void register(Platform platform) {
checkNotNull(platform);
logger.log(Level.FINE, "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
platforms.add(platform);
// 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}). " +
"If these two versions are truly different, then you may run into unexpected crashes and errors.",
new Object[]{ firstSeenVersion, platform.getVersion() });
}
} else {
firstSeenVersion = platform.getVersion();
}
}
/**
* Unregister a platform from WorldEdit.
*
* <p>If the platform has been chosen for any capabilities, then a new
* platform will be found.</p>
*
* @param platform the platform
*/
public synchronized boolean unregister(Platform platform) {
checkNotNull(platform);
boolean removed = platforms.remove(platform);
if (removed) {
logger.log(Level.FINE, "Unregistering " + platform.getClass().getCanonicalName() + " from WorldEdit");
boolean choosePreferred = false;
// Check whether this platform was chosen to be the preferred one
// for any capability and be sure to remove it
Iterator<Entry<Capability, Platform>> it = preferences.entrySet().iterator();
while (it.hasNext()) {
Entry<Capability, Platform> entry = it.next();
if (entry.getValue().equals(platform)) {
entry.getKey().unload(this, entry.getValue());
it.remove();
choosePreferred = true; // Have to choose new favorites
}
}
if (choosePreferred) {
choosePreferred();
}
}
return removed;
}
/**
* Get the preferred platform for handling a certain capability. Returns
* null if none is available.
*
* @param capability the capability
* @return the platform
* @throws NoCapablePlatformException thrown if no platform is capable
*/
public synchronized Platform queryCapability(Capability capability) throws NoCapablePlatformException {
Platform platform = preferences.get(checkNotNull(capability));
if (platform != null) {
return platform;
} else {
throw new NoCapablePlatformException("No platform was found supporting " + capability.name());
}
}
/**
* Choose preferred platforms and perform necessary initialization.
*/
private synchronized void choosePreferred() {
for (Capability capability : Capability.values()) {
Platform preferred = findMostPreferred(capability);
if (preferred != null) {
preferences.put(capability, preferred);
capability.initialize(this, preferred);
}
}
// Fire configuration event
if (preferences.containsKey(Capability.CONFIGURATION) && configured.compareAndSet(false, true)) {
worldEdit.getEventBus().post(new ConfigurationLoadEvent(queryCapability(Capability.CONFIGURATION).getConfiguration()));
}
}
/**
* Find the most preferred platform for a given capability from the list of
* platforms. This does not use the map of preferred platforms.
*
* @param capability the capability
* @return the most preferred platform, or null if no platform was found
*/
private synchronized @Nullable Platform findMostPreferred(Capability capability) {
Platform preferred = null;
Preference highest = null;
for (Platform platform : platforms) {
Preference preference = platform.getCapabilities().get(capability);
if (preference != null && (highest == null || preference.isPreferredOver(highest))) {
preferred = platform;
highest = preference;
}
}
return preferred;
}
/**
* Get a list of loaded platforms.
*
* <p>The returned list is a copy of the original and is mutable.</p>
*
* @return a list of platforms
*/
public synchronized List<Platform> getPlatforms() {
return new ArrayList<Platform>(platforms);
}
/**
* Given a world, possibly return the same world but using a different
* platform preferred for world editing operations.
*
* @param base the world to match
* @return the preferred world, if one was found, otherwise the given world
*/
public World getWorldForEditing(World base) {
checkNotNull(base);
World match = queryCapability(Capability.WORLD_EDITING).matchWorld(base);
return match != null ? match : base;
}
/**
* Given an actor, return a new one that may use a different platform
* for permissions and world editing.
*
* @param base the base actor to match
* @return a new delegate actor
*/
@SuppressWarnings("unchecked")
public <T extends Actor> T createProxyActor(T base) {
checkNotNull(base);
if (base instanceof Player) {
Player player = (Player) base;
Player permActor = queryCapability(Capability.PERMISSIONS).matchPlayer(player);
if (permActor == null) {
permActor = player;
}
Player cuiActor = queryCapability(Capability.WORLDEDIT_CUI).matchPlayer(player);
if (cuiActor == null) {
cuiActor = player;
}
return (T) new PlayerProxy(player, permActor, cuiActor, getWorldForEditing(player.getWorld()));
} else {
return base;
}
}
/**
* Get the command manager.
*
* @return the command manager
*/
public CommandManager getCommandManager() {
return commandManager;
}
/**
* Get the current configuration.
*
* <p>If no platform has been registered yet, then a default configuration
* will be returned.</p>
*
* @return the configuration
*/
public LocalConfiguration getConfiguration() {
return queryCapability(Capability.CONFIGURATION).getConfiguration();
}
/**
* Return a legacy {@link ServerInterface}.
*
* @return a {@link ServerInterface}
* @throws IllegalStateException if no platform has been registered
*/
@SuppressWarnings("deprecation")
public ServerInterface getServerInterface() throws IllegalStateException {
return ServerInterfaceAdapter.adapt(queryCapability(Capability.USER_COMMANDS));
}
@Subscribe
public void handlePlatformReady(PlatformReadyEvent event) {
choosePreferred();
if (initialized.compareAndSet(false, true)) {
worldEdit.getEventBus().post(new PlatformInitializeEvent());
}
}
@SuppressWarnings("deprecation")
@Subscribe
public void handleBlockInteract(BlockInteractEvent event) {
// Create a proxy actor with a potentially different world for
// making changes to the world
Actor actor = createProxyActor(event.getCause());
Location location = event.getLocation();
Vector vector = location.toVector();
// At this time, only handle interaction from players
if (actor instanceof Player) {
Player player = (Player) actor;
LocalSession session = worldEdit.getSessionManager().get(actor);
if (event.getType() == Interaction.HIT) {
if (player.getItemInHand() == getConfiguration().wandItem) {
if (!session.isToolControlEnabled()) {
return;
}
if (!actor.hasPermission("worldedit.selection.pos")) {
return;
}
RegionSelector selector = session.getRegionSelector(player.getWorld());
if (selector.selectPrimary(location.toVector(), ActorSelectorLimits.forActor(player))) {
selector.explainPrimarySelection(actor, session, vector);
}
event.setCancelled(true);
return;
}
if (player.isHoldingPickAxe() && session.hasSuperPickAxe()) {
final BlockTool superPickaxe = session.getSuperPickaxe();
if (superPickaxe != null && superPickaxe.canUse(player)) {
event.setCancelled(superPickaxe.actPrimary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session, location));
return;
}
}
Tool tool = session.getTool(player.getItemInHand());
if (tool != null && tool instanceof DoubleActionBlockTool) {
if (tool.canUse(player)) {
((DoubleActionBlockTool) tool).actSecondary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session, location);
event.setCancelled(true);
}
}
} else if (event.getType() == Interaction.OPEN) {
if (player.getItemInHand() == getConfiguration().wandItem) {
if (!session.isToolControlEnabled()) {
return;
}
if (!actor.hasPermission("worldedit.selection.pos")) {
return;
}
RegionSelector selector = session.getRegionSelector(player.getWorld());
if (selector.selectSecondary(vector, ActorSelectorLimits.forActor(player))) {
selector.explainSecondarySelection(actor, session, vector);
}
event.setCancelled(true);
return;
}
Tool tool = session.getTool(player.getItemInHand());
if (tool != null && tool instanceof BlockTool) {
if (tool.canUse(player)) {
((BlockTool) tool).actPrimary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session, location);
event.setCancelled(true);
}
}
}
}
}
@SuppressWarnings("deprecation")
@Subscribe
public void handlePlayerInput(PlayerInputEvent event) {
// Create a proxy actor with a potentially different world for
// making changes to the world
Player player = createProxyActor(event.getPlayer());
switch (event.getInputType()) {
case PRIMARY: {
if (player.getItemInHand() == getConfiguration().navigationWand) {
if (getConfiguration().navigationWandMaxDistance <= 0) {
return;
}
if (!player.hasPermission("worldedit.navigation.jumpto.tool")) {
return;
}
WorldVector pos = player.getSolidBlockTrace(getConfiguration().navigationWandMaxDistance);
if (pos != null) {
player.findFreePosition(pos);
} else {
player.printError("No block in sight (or too far)!");
}
event.setCancelled(true);
return;
}
LocalSession session = worldEdit.getSessionManager().get(player);
Tool tool = session.getTool(player.getItemInHand());
if (tool != null && tool instanceof DoubleActionTraceTool) {
if (tool.canUse(player)) {
((DoubleActionTraceTool) tool).actSecondary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session);
event.setCancelled(true);
return;
}
}
break;
}
case SECONDARY: {
if (player.getItemInHand() == getConfiguration().navigationWand) {
if (getConfiguration().navigationWandMaxDistance <= 0) {
return;
}
if (!player.hasPermission("worldedit.navigation.thru.tool")) {
return;
}
if (!player.passThroughForwardWall(40)) {
player.printError("Nothing to pass through!");
}
event.setCancelled(true);
return;
}
LocalSession session = worldEdit.getSessionManager().get(player);
Tool tool = session.getTool(player.getItemInHand());
if (tool != null && tool instanceof TraceTool) {
if (tool.canUse(player)) {
((TraceTool) tool).actPrimary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session);
event.setCancelled(true);
return;
}
}
break;
}
}
}
}

View File

@ -0,0 +1,161 @@
/*
* 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.platform;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldVector;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import com.sk89q.worldedit.session.SessionKey;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import javax.annotation.Nullable;
import java.util.UUID;
import static com.google.common.base.Preconditions.checkNotNull;
class PlayerProxy extends AbstractPlayerActor {
private final Player basePlayer;
private final Actor permActor;
private final Actor cuiActor;
private final World world;
PlayerProxy(Player basePlayer, Actor permActor, Actor cuiActor, World world) {
checkNotNull(basePlayer);
checkNotNull(permActor);
checkNotNull(cuiActor);
checkNotNull(world);
this.basePlayer = basePlayer;
this.permActor = permActor;
this.cuiActor = cuiActor;
this.world = world;
}
@Override
public UUID getUniqueId() {
return basePlayer.getUniqueId();
}
@Override
public int getItemInHand() {
return basePlayer.getItemInHand();
}
@Override
public void giveItem(int type, int amount) {
basePlayer.giveItem(type, amount);
}
@Override
public BlockBag getInventoryBlockBag() {
return basePlayer.getInventoryBlockBag();
}
@Override
public String getName() {
return basePlayer.getName();
}
@Override
public BaseEntity getState() {
throw new UnsupportedOperationException("Can't getState() on a player");
}
@Override
public Location getLocation() {
return basePlayer.getLocation();
}
@Override
public WorldVector getPosition() {
return basePlayer.getPosition();
}
@Override
public double getPitch() {
return basePlayer.getPitch();
}
@Override
public double getYaw() {
return basePlayer.getYaw();
}
@Override
public void setPosition(Vector pos, float pitch, float yaw) {
basePlayer.setPosition(pos, pitch, yaw);
}
@Override
public World getWorld() {
return world;
}
@Override
public void printRaw(String msg) {
basePlayer.printRaw(msg);
}
@Override
public void printDebug(String msg) {
basePlayer.printDebug(msg);
}
@Override
public void print(String msg) {
basePlayer.print(msg);
}
@Override
public void printError(String msg) {
basePlayer.printError(msg);
}
@Override
public String[] getGroups() {
return permActor.getGroups();
}
@Override
public boolean hasPermission(String perm) {
return permActor.hasPermission(perm);
}
@Override
public void dispatchCUIEvent(CUIEvent event) {
cuiActor.dispatchCUIEvent(event);
}
@Nullable
@Override
public <T> T getFacet(Class<? extends T> cls) {
return basePlayer.getFacet(cls);
}
@Override
public SessionKey getSessionKey() {
return basePlayer.getSessionKey();
}
}

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.platform;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Indicates the preference of a platform for a particular
* {@link Capability}.
*/
public enum Preference {
/**
* Indicates that the platform should be preferred for a given capability.
*/
PREFERRED,
/**
* Indicates that preference for a platform is neutral for a given
* capability.
*/
NORMAL,
/**
* Indicates that there should not be a preference for the platform for
* a given capability.
*/
PREFER_OTHERS;
/**
* Returns whether this given preference is preferred over the given
* other preference.
*
* @param other the other preference
* @return true if this preference is greater
*/
public boolean isPreferredOver(Preference other) {
checkNotNull(other);
return ordinal() < other.ordinal();
}
}

View File

@ -0,0 +1,85 @@
/*
* 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.platform.permission;
import com.google.common.base.Optional;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.regions.selector.limit.SelectorLimits;
import static com.google.common.base.Preconditions.checkNotNull;
public class ActorSelectorLimits implements SelectorLimits {
private final LocalConfiguration configuration;
private final Actor actor;
public ActorSelectorLimits(LocalConfiguration configuration, Actor actor) {
checkNotNull(configuration);
checkNotNull(actor);
this.configuration = configuration;
this.actor = actor;
}
@Override
public Optional<Integer> getPolygonVertexLimit() {
int limit;
if (actor.hasPermission(OverridePermissions.NO_LIMITS) || configuration.maxPolygonalPoints < 0) {
limit = configuration.defaultMaxPolygonalPoints;
} else if (configuration.defaultMaxPolygonalPoints < 0) {
limit = configuration.maxPolygonalPoints;
} else {
limit = Math.min(configuration.defaultMaxPolygonalPoints, configuration.maxPolygonalPoints);
}
if (limit > 0) {
return Optional.of(limit);
} else {
return Optional.absent();
}
}
@Override
public Optional<Integer> getPolyhedronVertexLimit() {
int limit;
if (actor.hasPermission(OverridePermissions.NO_LIMITS) || configuration.maxPolyhedronPoints < 0) {
limit = configuration.defaultMaxPolyhedronPoints;
} else if (configuration.defaultMaxPolyhedronPoints < 0) {
limit = configuration.maxPolyhedronPoints;
} else {
limit = Math.min(configuration.defaultMaxPolyhedronPoints, configuration.maxPolyhedronPoints);
}
if (limit > 0) {
return Optional.of(limit);
} else {
return Optional.absent();
}
}
public static ActorSelectorLimits forActor(Actor actor) {
return new ActorSelectorLimits(WorldEdit.getInstance().getConfiguration(), actor);
}
}

View File

@ -0,0 +1,32 @@
/*
* 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.platform.permission;
/**
* Standard override permissions.
*/
public final class OverridePermissions {
public static final String NO_LIMITS = "worldedit.limit.unrestricted";
private OverridePermissions() {
}
}