mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-04 03:56:41 +00:00
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:
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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) {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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() {
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user