Copy paste/merge FAWE classes to this WorldEdit fork

- so certain people can look at the diff and complain about my sloppy code :(

Signed-off-by: Jesse Boyd <jessepaleg@gmail.com>
This commit is contained in:
Jesse Boyd
2018-08-13 00:03:07 +10:00
parent a920c77cb8
commit a629d15c74
994 changed files with 117583 additions and 10745 deletions

View File

@ -22,7 +22,16 @@ package com.sk89q.worldedit.extension.platform;
import com.sk89q.worldedit.PlayerDirection;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.internal.cui.CUIEvent;
@ -30,13 +39,6 @@ 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.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import java.io.File;
@ -102,7 +104,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
byte free = 0;
while (y <= world.getMaximumPoint().getBlockY() + 2) {
while (y <= world.getMinimumPoint().getBlockY() + 2) {
if (!world.getBlock(new Vector(x, y, z)).getBlockType().getMaterial().isMovementBlocker()) {
++free;
} else {
@ -111,7 +113,9 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
if (free == 2) {
if (y - 1 != origY) {
setPosition(new Vector(x + 0.5, y - 2 + 1, z + 0.5));
final Vector pos = new Vector(x, y - 2, z);
final BlockStateHolder state = world.getBlock(pos);
setPosition(new Vector(x + 0.5, y - 2 + BlockType.centralTopLimit(state), z + 0.5));
}
return;
@ -130,9 +134,9 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
while (y >= 0) {
final Vector pos = new Vector(x, y, z);
final BlockState id = world.getBlock(pos);
final BlockStateHolder id = world.getBlock(pos);
if (id.getBlockType().getMaterial().isMovementBlocker()) {
setPosition(new Vector(x + 0.5, y + 1, z + 0.5));
setPosition(new Vector(x + 0.5, y + BlockType.centralTopLimit(id), z + 0.5));
return;
}
@ -175,7 +179,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
return false;
}
setPosition(platform.add(0.5, 1, 0.5));
setPosition(platform.add(0.5, BlockType.centralTopLimit(block), 0.5));
return true;
}
}
@ -215,7 +219,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
// Don't want to end up in lava
if (type != BlockTypes.AIR && type != BlockTypes.LAVA) {
// Found a block!
setPosition(platform.add(0.5, 1, 0.5));
setPosition(platform.add(0.5, BlockType.centralTopLimit(block), 0.5));
return true;
}
@ -297,25 +301,25 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
@Override
public void floatAt(int x, int y, int z, boolean alwaysGlass) {
try {
Vector spot = new Vector(x, y - 1, z);
if (!getLocation().getExtent().getBlock(spot).getBlockType().getMaterial().isMovementBlocker()) {
getLocation().getExtent().setBlock(spot, BlockTypes.GLASS.getDefaultState());
Vector spot = new Vector(x, y - 1, z);
if (!getLocation().getExtent().getBlock(spot).getBlockType().getMaterial().isMovementBlocker()) {
try {
getLocation().getExtent().setBlock(new Vector(x, y - 1, z), BlockTypes.GLASS.getDefaultState());
} catch (WorldEditException e) {
e.printStackTrace();
}
} catch (WorldEditException e) {
e.printStackTrace();
}
setPosition(new Vector(x + 0.5, y, z + 0.5));
}
@Override
public Location getBlockIn() {
return getLocation().setPosition(getLocation().toVector().toBlockVector());
return getLocation();
}
@Override
public Location getBlockOn() {
return getLocation().setPosition(getLocation().setY(getLocation().getY() - 1).toVector().toBlockVector());
return getLocation().setY(getLocation().getY() - 1);
}
@Override
@ -367,9 +371,9 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
public BaseBlock getBlockInHand(HandSide handSide) throws WorldEditException {
final ItemType typeId = getItemInHand(handSide).getType();
if (typeId.hasBlockType()) {
return typeId.getBlockType().getDefaultState().toBaseBlock();
return new BaseBlock(typeId.getBlockType());
} else {
return BlockTypes.AIR.getDefaultState().toBaseBlock();
return new BaseBlock(BlockTypes.AIR);
}
}
@ -496,4 +500,4 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
return false;
}
}
}

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.extension.platform;
import com.sk89q.worldedit.entity.metadata.Metadatable;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import com.sk89q.worldedit.session.SessionOwner;
import com.sk89q.worldedit.util.Identifiable;

View File

@ -19,77 +19,68 @@
package com.sk89q.worldedit.extension.platform;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.util.command.composition.LegacyCommandAdapter.adapt;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.command.AnvilCommands;
import com.boydti.fawe.command.CFICommand;
import com.boydti.fawe.command.MaskBinding;
import com.boydti.fawe.command.PatternBinding;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.util.StringMan;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.util.chat.UsageMessage;
import com.boydti.fawe.wrappers.FakePlayer;
import com.boydti.fawe.wrappers.LocationMaskedPlayerWrapper;
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.BiomeCommands;
import com.sk89q.worldedit.command.BrushCommands;
import com.sk89q.worldedit.command.ChunkCommands;
import com.sk89q.worldedit.command.ClipboardCommands;
import com.sk89q.worldedit.command.GeneralCommands;
import com.sk89q.worldedit.command.GenerationCommands;
import com.sk89q.worldedit.command.HistoryCommands;
import com.sk89q.worldedit.command.NavigationCommands;
import com.sk89q.worldedit.command.RegionCommands;
import com.sk89q.worldedit.command.SchematicCommands;
import com.sk89q.worldedit.command.ScriptingCommands;
import com.sk89q.worldedit.command.SelectionCommands;
import com.sk89q.worldedit.command.SnapshotCommands;
import com.sk89q.worldedit.command.SnapshotUtilCommands;
import com.sk89q.worldedit.command.SuperPickaxeCommands;
import com.sk89q.worldedit.command.ToolCommands;
import com.sk89q.worldedit.command.ToolUtilCommands;
import com.sk89q.worldedit.command.UtilityCommands;
import com.sk89q.worldedit.command.WorldEditCommands;
import com.sk89q.minecraft.util.commands.*;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.command.*;
import com.sk89q.worldedit.command.argument.ReplaceParser;
import com.sk89q.worldedit.command.argument.TreeGeneratorParser;
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.SelectionCommand;
import com.sk89q.worldedit.command.composition.ShapedBrushCommand;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
import com.sk89q.worldedit.function.factory.Deform;
import com.sk89q.worldedit.function.factory.Deform.Mode;
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.internal.command.*;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.auth.AuthorizationException;
import com.sk89q.worldedit.util.command.CommandCallable;
import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.util.command.InvalidUsageException;
import com.sk89q.worldedit.util.command.composition.ProvidedValue;
import com.sk89q.worldedit.util.command.fluent.CommandGraph;
import com.sk89q.worldedit.util.command.fluent.DispatcherNode;
import com.sk89q.worldedit.util.command.parametric.ExceptionConverter;
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.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
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;
import static com.sk89q.worldedit.util.command.composition.LegacyCommandAdapter.adapt;
/**
* Handles the registration and invocation of commands.
*
* <p>
* <p>This class is primarily for internal usage.</p>
*/
public final class CommandManager {
@ -101,18 +92,27 @@ public final class CommandManager {
private final WorldEdit worldEdit;
private final PlatformManager platformManager;
private final Dispatcher dispatcher;
private volatile Dispatcher dispatcher;
private volatile Platform platform;
private final DynamicStreamHandler dynamicHandler = new DynamicStreamHandler();
private final ExceptionConverter exceptionConverter;
private ParametricBuilder builder;
private Map<Object, String[]> methodMap;
private Map<CommandCallable, String[][]> commandMap;
private static CommandManager INSTANCE;
/**
* Create a new instance.
*
* @param worldEdit the WorldEdit instance
*/
CommandManager(final WorldEdit worldEdit, PlatformManager platformManager) {
public CommandManager(final WorldEdit worldEdit, PlatformManager platformManager) {
checkNotNull(worldEdit);
checkNotNull(platformManager);
INSTANCE = this;
this.worldEdit = worldEdit;
this.platformManager = platformManager;
this.exceptionConverter = new WorldEditExceptionConverter(worldEdit);
@ -122,73 +122,178 @@ public final class CommandManager {
// Setup the logger
commandLog.addHandler(dynamicHandler);
dynamicHandler.setFormatter(new LogFormat());
// Set up the commands manager
ParametricBuilder builder = new ParametricBuilder();
builder = new ParametricBuilder();
builder.setAuthorizer(new ActorAuthorizer());
builder.setDefaultCompleter(new UserCommandCompleter(platformManager));
builder.addBinding(new WorldEditBinding(worldEdit));
builder.addBinding(new PatternBinding(worldEdit), com.sk89q.worldedit.function.pattern.Pattern.class);
builder.addBinding(new MaskBinding(worldEdit), com.sk89q.worldedit.function.mask.Mask.class);
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))
.register(adapt(new SelectionCommand(new ApplyCommand(new ReplaceParser(), "Set all blocks within selection"), "worldedit.region.set")), "/set")
.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))
.register(adapt(new ShapedBrushCommand(new DeformCommand(), "worldedit.brush.deform")), "deform")
.register(adapt(new ShapedBrushCommand(new ApplyCommand(new ReplaceParser(), "Set all blocks within region"), "worldedit.brush.set")), "set")
.register(adapt(new ShapedBrushCommand(new PaintCommand(), "worldedit.brush.paint")), "paint")
.register(adapt(new ShapedBrushCommand(new ApplyCommand(), "worldedit.brush.apply")), "apply")
.register(adapt(new ShapedBrushCommand(new PaintCommand(new TreeGeneratorParser("treeType")), "worldedit.brush.forest")), "forest")
.register(adapt(new ShapedBrushCommand(ProvidedValue.create(new Deform("y-=1", Mode.RAW_COORD), "Raise one block"), "worldedit.brush.raise")), "raise")
.register(adapt(new ShapedBrushCommand(ProvidedValue.create(new Deform("y+=1", Mode.RAW_COORD), "Lower one block"), "worldedit.brush.lower")), "lower")
.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();
this.methodMap = new ConcurrentHashMap<>();
this.commandMap = new ConcurrentHashMap<>();
try {
Class.forName("com.intellectualcrafters.plot.PS");
CFICommand cfi = new CFICommand(worldEdit, builder);
registerCommands(cfi);
} catch (ClassNotFoundException e) {}
}
/**
* Register all the methods in the class as commands<br>
* - You should try to register commands during startup
*
* @param clazz The class containing all the commands
*/
public void registerCommands(Object clazz) {
registerCommands(clazz, new String[0]);
}
/**
* Create a command with the provided aliases and register all methods of the class as sub commands.<br>
* - You should try to register commands during startup
*
* @param clazz The class containing all the sub command methods
* @param aliases The aliases to give the command
*/
public void registerCommands(Object clazz, String... aliases) {
if (platform != null) {
if (aliases.length == 0) {
builder.registerMethodsAsCommands(dispatcher, clazz);
} else {
DispatcherNode graph = new CommandGraph().builder(builder).commands();
graph = graph.registerMethods(clazz);
dispatcher.registerCommand(graph.graph().getDispatcher(), aliases);
}
platform.registerCommands(dispatcher);
} else {
methodMap.put(clazz, aliases);
}
}
/**
* Create a command with the provided aliases and register all methods of the class as sub commands.<br>
* - You should try to register commands during startup
*
* @param clazz The class containing all the sub command methods
* @param aliases The aliases to give the command
*/
public void registerCommands(Object clazz, Object processor, String... aliases) {
if (platform != null) {
if (aliases.length == 0) {
builder.registerMethodsAsCommands(dispatcher, clazz);
} else {
DispatcherNode graph = new CommandGraph().builder(builder).commands();
graph = graph.registerMethods(clazz);
dispatcher.registerCommand(graph.graph().getDispatcher(), aliases);
}
platform.registerCommands(dispatcher);
} else {
methodMap.put(clazz, aliases);
}
}
public void registerCommand(String[] aliases, Command command, CommandCallable callable) {
if (platform != null) {
if (aliases.length == 0) {
dispatcher.registerCommand(callable, command.aliases());
} else {
DispatcherNode graph = new CommandGraph().builder(builder).commands();
graph = graph.register(callable, command.aliases());
dispatcher.registerCommand(graph.graph().getDispatcher(), aliases);
}
platform.registerCommands(dispatcher);
} else {
commandMap.putIfAbsent(callable, new String[][] {aliases, command.aliases()});
}
}
public ParametricBuilder getBuilder() {
return builder;
}
/**
* Initialize the dispatcher
*/
public void setupDispatcher() {
DispatcherNode graph = new CommandGraph().builder(builder).commands();
for (Map.Entry<Object, String[]> entry : methodMap.entrySet()) {
// add command
String[] aliases = entry.getValue();
if (aliases.length == 0) {
graph = graph.registerMethods(entry.getKey());
} else {
graph = graph.group(aliases).registerMethods(entry.getKey()).parent();
}
}
for (Map.Entry<CommandCallable, String[][]> entry : commandMap.entrySet()) {
String[][] aliases = entry.getValue();
CommandCallable callable = entry.getKey();
if (aliases[0].length == 0) {
graph = graph.register(callable, aliases[1]);
} else {
graph = graph.group(aliases[0]).register(callable, aliases[1]).parent();
}
}
dispatcher = graph
.group("/anvil")
.describeAs("Anvil command")
.registerMethods(new AnvilCommands(worldEdit)).parent()
.registerMethods(new BiomeCommands(worldEdit))
.registerMethods(new ChunkCommands(worldEdit))
.registerMethods(new ClipboardCommands(worldEdit))
.registerMethods(new OptionsCommands(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 BrushOptionsCommands(worldEdit))
.registerMethods(new ToolCommands(worldEdit))
.registerMethods(new UtilityCommands(worldEdit))
.registerSubMethods(new WorldEditCommands(worldEdit))
.registerSubMethods(new SchematicCommands(worldEdit))
.registerSubMethods(new SnapshotCommands(worldEdit))
.groupAndDescribe(BrushCommands.class)
.registerMethods(new BrushCommands(worldEdit))
.registerMethods(new ToolCommands(worldEdit))
.registerMethods(new BrushOptionsCommands(worldEdit))
.register(adapt(new ShapedBrushCommand(new DeformCommand(), "worldedit.brush.deform")), "deform")
.register(adapt(new ShapedBrushCommand(new ApplyCommand(new ReplaceParser(), "Set all blocks within region"), "worldedit.brush.set")), "set")
.register(adapt(new ShapedBrushCommand(new PaintCommand(), "worldedit.brush.paint")), "paint")
.register(adapt(new ShapedBrushCommand(new ApplyCommand(), "worldedit.brush.apply")), "apply")
.register(adapt(new ShapedBrushCommand(new PaintCommand(new TreeGeneratorParser("treeType")), "worldedit.brush.forest")), "forest")
.register(adapt(new ShapedBrushCommand(ProvidedValue.create(new Deform("y-=1", Mode.RAW_COORD), "Raise one block"), "worldedit.brush.raise")), "raise")
.register(adapt(new ShapedBrushCommand(ProvidedValue.create(new Deform("y+=1", Mode.RAW_COORD), "Lower one block"), "worldedit.brush.lower")), "lower")
.parent()
.group("superpickaxe", "pickaxe", "sp").describeAs("Super-pickaxe commands")
.registerMethods(new SuperPickaxeCommands(worldEdit))
.parent().graph().getDispatcher();
if (platform != null) {
platform.registerCommands(dispatcher);
}
}
public static CommandManager getInstance() {
return INSTANCE;
}
public ExceptionConverter getExceptionConverter() {
return exceptionConverter;
}
void register(Platform platform) {
public void register(Platform platform) {
log.log(Level.FINE, "Registering commands with " + platform.getClass().getCanonicalName());
LocalConfiguration config = platform.getConfiguration();
@ -210,14 +315,13 @@ public final class CommandManager {
} catch (IOException e) {
log.log(Level.WARNING, "Could not use command log file " + path + ": " + e.getMessage());
}
dynamicHandler.setFormatter(new LogFormat(config.logFormat));
}
platform.registerCommands(dispatcher);
this.platform = platform;
setupDispatcher();
}
void unregister() {
public void unregister() {
dynamicHandler.setHandler(null);
}
@ -245,97 +349,153 @@ public final class CommandManager {
return split;
}
@Subscribe
public void handleCommand(CommandEvent event) {
Request.reset();
public void handleCommandOnCurrentThread(final CommandEvent event) {
Actor actor = platformManager.createProxyActor(event.getActor());
String[] split = commandDetection(event.getArguments().split(" "));
final String args = event.getArguments();
final String[] split = commandDetection(args.split(" "));
// No command found!
if (!dispatcher.contains(split[0])) {
return;
}
LocalSession session = worldEdit.getSessionManager().get(actor);
if (!actor.isPlayer()) {
actor = FakePlayer.wrap(actor.getName(), actor.getUniqueId(), actor);
}
final LocalSession session = worldEdit.getSessionManager().get(actor);
LocalConfiguration config = worldEdit.getConfiguration();
final CommandLocals locals = new CommandLocals();
final FawePlayer fp = FawePlayer.wrap(actor);
if (fp == null) {
throw new IllegalArgumentException("FAWE doesn't support: " + actor);
}
final Set<String> failedPermissions = new LinkedHashSet<>();
if (actor instanceof Player) {
Player player = (Player) actor;
Player unwrapped = LocationMaskedPlayerWrapper.unwrap(player);
actor = new LocationMaskedPlayerWrapper((Player) unwrapped, player.getLocation(), true) {
@Override
public boolean hasPermission(String permission) {
if (!super.hasPermission(permission)) {
failedPermissions.add(permission);
return false;
}
return true;
}
CommandLocals locals = new CommandLocals();
@Override
public void checkPermission(String permission) throws AuthorizationException {
try {
super.checkPermission(permission);
} catch (AuthorizationException e) {
failedPermissions.add(permission);
throw e;
}
}
};
}
Request.reset();
locals.put(Actor.class, actor);
locals.put("arguments", event.getArguments());
final Actor finalActor = actor;
locals.put("arguments", args);
long start = System.currentTimeMillis();
try {
// This is a bit of a hack, since the call method can only throw CommandExceptions
// everything needs to be wrapped at least once. Which means to handle all WorldEdit
// exceptions without writing a hook into every dispatcher, we need to unwrap these
// exceptions and rethrow their converted form, if their is one.
try {
dispatcher.call(Joiner.on(" ").join(split), locals, new String[0]);
Object result = dispatcher.call(Joiner.on(" ").join(split), locals, new String[0]);
} catch (Throwable t) {
// Use the exception converter to convert the exception if any of its causes
// can be converted, otherwise throw the original exception
Throwable next = t;
do {
exceptionConverter.convert(next);
exceptionConverter.convert(next);
while (next.getCause() != null) {
next = next.getCause();
} while (next != null);
throw t;
exceptionConverter.convert(next);
}
throw next;
}
} catch (CommandPermissionsException e) {
actor.printError("You are not permitted to do that. Are you in the right mode?");
BBC.NO_PERM.send(finalActor, StringMan.join(failedPermissions, " "));
} catch (InvalidUsageException e) {
if (e.isFullHelpSuggested()) {
actor.printRaw(ColorCodeBuilder.asColorCodes(new CommandUsageBox(e.getCommand(), e.getCommandUsed("/", ""), locals)));
CommandCallable cmd = e.getCommand();
if (cmd instanceof Dispatcher) {
try {
CommandContext context = new CommandContext(("ignoreThis " + Joiner.on(" ").join(split)).split(" "), new HashSet<>(), false, locals);
UtilityCommands.help(context, worldEdit, actor);
} catch (CommandException e1) {
e1.printStackTrace();
}
} else {
new UsageMessage(cmd, e.getCommandUsed((WorldEdit.getInstance().getConfiguration().noDoubleSlash ? "" : "/"), ""), locals).send(fp);
}
String message = e.getMessage();
if (message != null) {
actor.printError(message);
finalActor.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("/"));
finalActor.printRaw(BBC.getPrefix() + (message != null ? message : "The command was not used properly (no more help available)."));
BBC.COMMAND_SYNTAX.send(finalActor, 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);
actor.printError("An unknown FAWE error has occurred! Please see console.");
log.log(Level.SEVERE, "An unknown FAWE error occurred", e);
}
} catch (Throwable e) {
Exception faweException = FaweException.get(e);
String message = e.getMessage();
if (faweException != null) {
BBC.WORLDEDIT_CANCEL_REASON.send(finalActor, faweException.getMessage());
} else {
finalActor.printError("There was an error handling a FAWE command: [See console]");
finalActor.printRaw(e.getClass().getName() + ": " + e.getMessage());
log.log(Level.SEVERE, "An unexpected error occurred while handling a FAWE command", e);
}
} finally {
EditSession editSession = locals.get(EditSession.class);
final 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(finalActor, editSession);
session.remember(editSession);
final long time = System.currentTimeMillis() - start;
if (time > 1000) {
BBC.ACTION_COMPLETE.send(finalActor, (time / 1000d));
}
worldEdit.flushBlockBag(actor, editSession);
Request.reset();
}
}
}
event.setCancelled(true);
@Subscribe
public void handleCommand(CommandEvent event) {
Request.reset();
Actor actor = event.getActor();
if (actor instanceof Player) {
actor = LocationMaskedPlayerWrapper.wrap((Player) actor);
}
String args = event.getArguments();
CommandEvent finalEvent = new CommandEvent(actor, args);
final FawePlayer<Object> fp = FawePlayer.wrap(actor);
TaskManager.IMP.taskNow(new Runnable() {
@Override
public void run() {
if (!fp.runAction(new Runnable() {
@Override
public void run() {
handleCommandOnCurrentThread(finalEvent);
}
}, false, true)) {
BBC.WORLDEDIT_COMMAND_LIMIT.send(fp);
}
finalEvent.setCancelled(true);
}
}, Fawe.isMainThread());
}
@Subscribe
@ -343,7 +503,6 @@ public final class CommandManager {
try {
CommandLocals locals = new CommandLocals();
locals.put(Actor.class, event.getActor());
locals.put("arguments", event.getArguments());
event.setSuggestions(dispatcher.getSuggestions(event.getArguments(), locals));
} catch (CommandException e) {
event.getActor().printError(e.getMessage());
@ -363,4 +522,7 @@ public final class CommandManager {
return commandLog;
}
}
public static Class<?> inject() {
return CommandManager.class;
}
}

View File

@ -25,11 +25,10 @@ import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.registry.Registries;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
/**
* Represents a platform that WorldEdit has been implemented for.
*

View File

@ -19,47 +19,41 @@
package com.sk89q.worldedit.extension.platform;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.object.pattern.PatternTraverser;
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.*;
import com.sk89q.worldedit.Vector;
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;
import com.sk89q.worldedit.command.tool.*;
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.event.platform.*;
import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
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 java.util.ArrayList;
import java.util.EnumMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
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 javax.annotation.Nullable;
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 {
@ -68,8 +62,8 @@ public class PlatformManager {
private final WorldEdit worldEdit;
private final CommandManager commandManager;
private final List<Platform> platforms = new ArrayList<>();
private final Map<Capability, Platform> preferences = new EnumMap<>(Capability.class);
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();
@ -107,7 +101,7 @@ public class PlatformManager {
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() });
new Object[]{firstSeenVersion, platform.getVersion()});
}
} else {
firstSeenVersion = platform.getVersion();
@ -116,7 +110,7 @@ public class PlatformManager {
/**
* Unregister a platform from WorldEdit.
*
* <p>
* <p>If the platform has been chosen for any capabilities, then a new
* platform will be found.</p>
*
@ -165,7 +159,7 @@ public class PlatformManager {
if (platform != null) {
return platform;
} else {
if (preferences.isEmpty()) {
if (preferences.isEmpty() && !platforms.isEmpty()) {
return platforms.get(0); // Use the first available if preferences have not been decided yet.
}
throw new NoCapablePlatformException("No platform was found supporting " + capability.name());
@ -214,13 +208,13 @@ public class PlatformManager {
/**
* Get a list of loaded platforms.
*
* <p>
* <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<>(platforms);
return new ArrayList<Platform>(platforms);
}
/**
@ -232,6 +226,7 @@ public class PlatformManager {
*/
public World getWorldForEditing(World base) {
checkNotNull(base);
base = WorldWrapper.unwrap(base);
World match = queryCapability(Capability.WORLD_EDITING).matchWorld(base);
return match != null ? match : base;
}
@ -249,18 +244,8 @@ public class PlatformManager {
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()));
FawePlayer fp = FawePlayer.wrap(player);
return (T) fp.createProxy();
} else {
return base;
}
@ -277,7 +262,7 @@ public class PlatformManager {
/**
* Get the current configuration.
*
* <p>
* <p>If no platform has been registered yet, then a default configuration
* will be returned.</p>
*
@ -295,161 +280,249 @@ public class PlatformManager {
}
}
private <T extends Tool> T reset(T tool) {
new PatternTraverser(tool).reset(null);
return tool;
}
@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());
Request.reset();
final Actor actor = createProxyActor(event.getCause());
try {
final Location location = event.getLocation();
final Vector vector = location.toVector();
Location location = event.getLocation();
Vector vector = location.toVector();
// At this time, only handle interaction from players
if (actor instanceof Player) {
final LocalSession session = worldEdit.getSessionManager().get(actor);
Player playerActor = (Player) actor;
// 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(HandSide.MAIN_HAND).getType().getId().equals(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;
VirtualWorld virtual = session.getVirtualWorld();
if (virtual != null) {
virtual.handleBlockInteract(playerActor, vector, event);
if (event.isCancelled()) 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;
}
}
if (event.getType() == Interaction.HIT) {
if (session.isToolControlEnabled() && playerActor.getItemInHand(HandSide.MAIN_HAND).getType().equals(getConfiguration().wandItem)) {
FawePlayer<?> fp = FawePlayer.wrap(playerActor);
if (!actor.hasPermission("worldedit.selection.pos")) {
return;
}
final RegionSelector selector = session.getRegionSelector(playerActor.getWorld());
final Player player = new LocationMaskedPlayerWrapper(PlayerWrapper.wrap((Player) actor), ((Player) actor).getLocation());
fp.runAction(new Runnable() {
@Override
public void run() {
if (selector.selectPrimary(location.toVector(), ActorSelectorLimits.forActor(player))) {
selector.explainPrimarySelection(actor, session, vector);
}
}
}, false, true);
Tool tool = session.getTool(player.getItemInHand(HandSide.MAIN_HAND).getType());
if (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(HandSide.MAIN_HAND).getType().getId().equals(getConfiguration().wandItem)) {
if (!session.isToolControlEnabled()) {
return;
}
if (!actor.hasPermission("worldedit.selection.pos")) {
return;
if (session.hasSuperPickAxe() && playerActor.isHoldingPickAxe()) {
final BlockTool superPickaxe = session.getSuperPickaxe();
if (superPickaxe != null && superPickaxe.canUse(playerActor)) {
FawePlayer<?> fp = FawePlayer.wrap(playerActor);
final Player player = new LocationMaskedPlayerWrapper(PlayerWrapper.wrap((Player) actor), ((Player) actor).getLocation());
fp.runAction(new Runnable() {
@Override
public void run() {
reset(superPickaxe).actPrimary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session, location);
}
}, false, true);
event.setCancelled(true);
return;
}
}
RegionSelector selector = session.getRegionSelector(player.getWorld());
if (selector.selectSecondary(vector, ActorSelectorLimits.forActor(player))) {
selector.explainSecondarySelection(actor, session, vector);
final Tool tool = session.getTool(playerActor);
if (tool != null && tool instanceof DoubleActionBlockTool) {
if (tool.canUse(playerActor)) {
FawePlayer<?> fp = FawePlayer.wrap(playerActor);
final Player player = new LocationMaskedPlayerWrapper(PlayerWrapper.wrap((Player) actor), ((Player) actor).getLocation());
fp.runAction(new Runnable() {
@Override
public void run() {
reset(((DoubleActionBlockTool) tool)).actSecondary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session, location);
}
}, false, true);
event.setCancelled(true);
return;
}
}
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);
} else if (event.getType() == Interaction.OPEN) {
if (session.isToolControlEnabled() && playerActor.getItemInHand(HandSide.MAIN_HAND).getType().equals(getConfiguration().wandItem)) {
FawePlayer<?> fp = FawePlayer.wrap(playerActor);
if (!actor.hasPermission("worldedit.selection.pos")) {
return;
}
if (fp.checkAction()) {
final RegionSelector selector = session.getRegionSelector(playerActor.getWorld());
final Player player = new LocationMaskedPlayerWrapper(PlayerWrapper.wrap((Player) actor), ((Player) actor).getLocation());
fp.runAction(new Runnable() {
@Override
public void run() {
if (selector.selectSecondary(vector, ActorSelectorLimits.forActor(player))) {
selector.explainSecondarySelection(actor, session, vector);
}
}
}, false, true);
}
event.setCancelled(true);
return;
}
final Tool tool = session.getTool(playerActor);
if (tool != null && tool instanceof BlockTool) {
if (tool.canUse(playerActor)) {
FawePlayer<?> fp = FawePlayer.wrap(playerActor);
if (fp.checkAction()) {
final Player player = new LocationMaskedPlayerWrapper(PlayerWrapper.wrap((Player) actor), ((Player) actor).getLocation());
fp.runAction(new Runnable() {
@Override
public void run() {
if (tool instanceof BrushTool) {
((BlockTool) tool).actPrimary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session, location);
} else {
reset((BlockTool) tool).actPrimary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session, location);
}
}
}, false, true);
event.setCancelled(true);
return;
}
}
}
}
}
} catch (Throwable e) {
handleThrowable(e, actor);
}
}
public void handleThrowable(Throwable e, Actor actor) {
FaweException faweException = FaweException.get(e);
if (faweException != null) {
BBC.WORLDEDIT_CANCEL_REASON.send(actor, faweException.getMessage());
} else {
actor.printError("Please report this error: [See console]");
actor.printRaw(e.getClass().getName() + ": " + e.getMessage());
MainUtil.handleError(e);
}
}
@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());
Player actor = createProxyActor(event.getPlayer());
final Player player = new LocationMaskedPlayerWrapper(PlayerWrapper.wrap(actor), actor.getLocation(), true);
final LocalSession session = worldEdit.getSessionManager().get(player);
switch (event.getInputType()) {
case PRIMARY: {
if (player.getItemInHand(HandSide.MAIN_HAND).getType().getId().equals(getConfiguration().navigationWand)) {
if (getConfiguration().navigationWandMaxDistance <= 0) {
return;
}
VirtualWorld virtual = session.getVirtualWorld();
if (virtual != null) {
virtual.handlePlayerInput(player, event);
if (event.isCancelled()) return;
}
if (!player.hasPermission("worldedit.navigation.jumpto.tool")) {
return;
}
try {
switch (event.getInputType()) {
case PRIMARY: {
if (player.getItemInHand(HandSide.MAIN_HAND).getType().equals(getConfiguration().navigationWand)) {
if (getConfiguration().navigationWandMaxDistance <= 0) {
return;
}
Location pos = player.getSolidBlockTrace(getConfiguration().navigationWandMaxDistance);
if (pos != null) {
player.findFreePosition(pos);
} else {
player.printError("No block in sight (or too far)!");
}
if (!player.hasPermission("worldedit.navigation.jumpto.tool")) {
return;
}
event.setCancelled(true);
return;
}
Location pos = player.getSolidBlockTrace(getConfiguration().navigationWandMaxDistance);
if (pos != null) {
player.findFreePosition(pos);
} else {
BBC.NO_BLOCK.send(player);
}
LocalSession session = worldEdit.getSessionManager().get(player);
Tool tool = session.getTool(player.getItemInHand(HandSide.MAIN_HAND).getType());
if (tool instanceof DoubleActionTraceTool) {
if (tool.canUse(player)) {
((DoubleActionTraceTool) tool).actSecondary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session);
event.setCancelled(true);
return;
}
final Tool tool = session.getTool(player);
if (tool != null && tool instanceof DoubleActionTraceTool) {
if (tool.canUse(player)) {
FawePlayer<?> fp = FawePlayer.wrap(player);
fp.runAsyncIfFree(new Runnable() {
@Override
public void run() {
reset((DoubleActionTraceTool) tool).actSecondary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session);
}
});
event.setCancelled(true);
return;
}
}
break;
}
break;
case SECONDARY: {
if (player.getItemInHand(HandSide.MAIN_HAND).getType().equals(getConfiguration().navigationWand)) {
if (getConfiguration().navigationWandMaxDistance <= 0) {
return;
}
if (!player.hasPermission("worldedit.navigation.thru.tool")) {
return;
}
if (!player.passThroughForwardWall(40)) {
BBC.NAVIGATION_WAND_ERROR.send(player);
}
event.setCancelled(true);
return;
}
final Tool tool = session.getTool(player);
if (tool != null && tool instanceof TraceTool) {
if (tool.canUse(player)) {
FawePlayer<?> fp = FawePlayer.wrap(player);
fp.runAction(new Runnable() {
@Override
public void run() {
reset((TraceTool) tool).actPrimary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session);
}
}, false, true);
event.setCancelled(true);
return;
}
}
break;
}
}
case SECONDARY: {
if (player.getItemInHand(HandSide.MAIN_HAND).getType().getId().equals(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(HandSide.MAIN_HAND).getType());
if (tool instanceof TraceTool) {
if (tool.canUse(player)) {
((TraceTool) tool).actPrimary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session);
event.setCancelled(true);
return;
}
}
break;
} catch (Throwable e) {
FaweException faweException = FaweException.get(e);
if (faweException != null) {
BBC.WORLDEDIT_CANCEL_REASON.send(player, faweException.getMessage());
} else {
player.printError("Please report this error: [See console]");
player.printRaw(e.getClass().getName() + ": " + e.getMessage());
MainUtil.handleError(e);
}
}
}
public static Class<?> inject() {
return PlatformManager.class;
}
}
}

View File

@ -19,9 +19,10 @@
package com.sk89q.worldedit.extension.platform;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Player;
@ -33,18 +34,21 @@ import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.gamemode.GameMode;
import java.util.UUID;
import javax.annotation.Nullable;
class PlayerProxy extends AbstractPlayerActor {
import java.util.UUID;
import static com.google.common.base.Preconditions.checkNotNull;
public class PlayerProxy extends AbstractPlayerActor {
private final Player basePlayer;
private final Actor permActor;
private final Actor cuiActor;
private final World world;
private Vector offset = Vector.ZERO;
PlayerProxy(Player basePlayer, Actor permActor, Actor cuiActor, World world) {
public PlayerProxy(Player basePlayer, Actor permActor, Actor cuiActor, World world) {
checkNotNull(basePlayer);
checkNotNull(permActor);
checkNotNull(cuiActor);
@ -55,6 +59,16 @@ class PlayerProxy extends AbstractPlayerActor {
this.world = world;
}
public void setOffset(Vector position) {
this.offset = position;
}
@Override
public BaseBlock getBlockInHand(HandSide handSide) throws WorldEditException {
return basePlayer.getBlockInHand(handSide);
}
@Override
public UUID getUniqueId() {
return basePlayer.getUniqueId();
@ -82,12 +96,13 @@ class PlayerProxy extends AbstractPlayerActor {
@Override
public BaseEntity getState() {
throw new UnsupportedOperationException("Can't getState() on a player");
throw new UnsupportedOperationException("Can't withPropertyId() on a player");
}
@Override
public Location getLocation() {
return basePlayer.getLocation();
Location loc = this.basePlayer.getLocation();
return new Location(loc.getExtent(), loc.toVector().add(offset), loc.getDirection());
}
@Override
@ -155,4 +170,4 @@ class PlayerProxy extends AbstractPlayerActor {
public void setGameMode(GameMode gameMode) {
basePlayer.setGameMode(gameMode);
}
}
}