From 9bb70ad3353b60f6e81aaddde74066557c0e1221 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Fri, 27 Jun 2014 13:14:44 -0700
Subject: [PATCH] Updated events to choose the best platform for certain tasks.
---
.../worldedit/bukkit/BukkitCommandSender.java | 3 +-
.../sk89q/worldedit/bukkit/BukkitPlayer.java | 2 +-
.../bukkit/BukkitServerInterface.java | 24 ++++
.../sk89q/worldedit/bukkit/BukkitWorld.java | 12 +-
.../worldedit/bukkit/WorldEditPlugin.java | 2 +-
.../sk89q/worldedit/forge/ForgePlatform.java | 31 +++++
.../sk89q/worldedit/forge/ForgePlayer.java | 1 -
.../com/sk89q/worldedit/forge/ForgeWorld.java | 16 ++-
.../java/com/sk89q/worldedit/LocalPlayer.java | 9 --
.../platform/AbstractPlayerActor.java | 13 --
.../extension/platform/Platform.java | 22 +++
.../extension/platform/PlatformManager.java | 48 ++++++-
.../extension/platform/PlayerProxy.java | 125 ++++++++++++++++++
.../internal/ServerInterfaceAdapter.java | 14 ++
14 files changed, 282 insertions(+), 40 deletions(-)
create mode 100644 src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java
diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java
index e2067fd90..08d4e1342 100644
--- a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java
+++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java
@@ -29,8 +29,7 @@ public class BukkitCommandSender extends LocalPlayer {
private CommandSender sender;
private WorldEditPlugin plugin;
- public BukkitCommandSender(WorldEditPlugin plugin, ServerInterface server, CommandSender sender) {
- super(server);
+ public BukkitCommandSender(WorldEditPlugin plugin, CommandSender sender) {
this.plugin = plugin;
this.sender = sender;
}
diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java
index 1499cd09f..637c7c7e8 100644
--- a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java
+++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java
@@ -41,7 +41,6 @@ public class BukkitPlayer extends LocalPlayer {
private WorldEditPlugin plugin;
public BukkitPlayer(WorldEditPlugin plugin, ServerInterface server, Player player) {
- super(server);
this.plugin = plugin;
this.player = player;
}
@@ -52,6 +51,7 @@ public class BukkitPlayer extends LocalPlayer {
return itemStack != null ? itemStack.getTypeId() : 0;
}
+ @Override
public BaseBlock getBlockInHand() throws WorldEditException {
ItemStack itemStack = player.getItemInHand();
return BukkitUtil.toBlock(getWorld(), itemStack);
diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java
index fdfecd950..03f4510d3 100644
--- a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java
+++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java
@@ -25,6 +25,7 @@ import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.CommandsManager;
import com.sk89q.worldedit.*;
+import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Preference;
import org.bukkit.Bukkit;
@@ -33,6 +34,7 @@ import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.EntityType;
+import javax.annotation.Nullable;
import java.lang.reflect.Method;
import java.util.*;
@@ -93,6 +95,28 @@ public class BukkitServerInterface extends ServerInterface {
return ret;
}
+ @Nullable
+ @Override
+ public Player matchPlayer(Player player) {
+ if (player instanceof BukkitPlayer) {
+ return player;
+ } else {
+ org.bukkit.entity.Player bukkitPlayer = server.getPlayerExact(player.getName());
+ return bukkitPlayer != null ? new BukkitPlayer(plugin, this, bukkitPlayer) : null;
+ }
+ }
+
+ @Nullable
+ @Override
+ public com.sk89q.worldedit.world.World matchWorld(com.sk89q.worldedit.world.World world) {
+ if (world instanceof BukkitWorld) {
+ return world;
+ } else {
+ World bukkitWorld = server.getWorld(world.getName());
+ return bukkitWorld != null ? new BukkitWorld(bukkitWorld) : null;
+ }
+ }
+
@Override
public void onCommandRegistration(List commands, CommandsManager manager) {
List toRegister = new ArrayList();
diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorld.java
index ea784545e..3f32fefda 100644
--- a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorld.java
+++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorld.java
@@ -1110,13 +1110,15 @@ public class BukkitWorld extends LocalWorld {
@Override
public boolean equals(Object other) {
- World world = getWorld();
-
- if (!(other instanceof BukkitWorld)) {
+ if (other == null) {
+ return false;
+ } else if ((other instanceof BukkitWorld)) {
+ return ((BukkitWorld) other).getWorld().equals(getWorld());
+ } else if (other instanceof com.sk89q.worldedit.world.World) {
+ return ((com.sk89q.worldedit.world.World) other).getName().equals(getName());
+ } else {
return false;
}
-
- return ((BukkitWorld) other).getWorld().equals(world);
}
@Override
diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java
index 03d4383dc..e63c1ad80 100644
--- a/src/bukkit/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java
+++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java
@@ -339,7 +339,7 @@ public class WorldEditPlugin extends JavaPlugin {
return wrapPlayer((Player) sender);
}
- return new BukkitCommandSender(this, this.server, sender);
+ return new BukkitCommandSender(this, sender);
}
/**
diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgePlatform.java b/src/forge/java/com/sk89q/worldedit/forge/ForgePlatform.java
index 0e15f1ca8..d983c5885 100644
--- a/src/forge/java/com/sk89q/worldedit/forge/ForgePlatform.java
+++ b/src/forge/java/com/sk89q/worldedit/forge/ForgePlatform.java
@@ -23,19 +23,23 @@ import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.worldedit.BiomeTypes;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.ServerInterface;
+import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Preference;
+import com.sk89q.worldedit.world.World;
import cpw.mods.fml.common.FMLCommonHandler;
import net.minecraft.command.CommandBase;
import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender;
import net.minecraft.command.ServerCommandManager;
import net.minecraft.entity.EntityList;
+import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager;
+import javax.annotation.Nullable;
import java.util.*;
class ForgePlatform extends ServerInterface {
@@ -101,6 +105,33 @@ class ForgePlatform extends ServerInterface {
return ret;
}
+ @Nullable
+ @Override
+ public Player matchPlayer(Player player) {
+ if (player instanceof ForgePlayer) {
+ return player;
+ } else {
+ EntityPlayerMP entity = server.getConfigurationManager().getPlayerForUsername(player.getName());
+ return entity != null ? new ForgePlayer(entity) : null;
+ }
+ }
+
+ @Nullable
+ @Override
+ public World matchWorld(World world) {
+ if (world instanceof ForgeWorld) {
+ return world;
+ } else {
+ for (WorldServer ws : DimensionManager.getWorlds()) {
+ if (ws.getWorldInfo().getWorldName().equals(world.getName())) {
+ return new ForgeWorld(ws);
+ }
+ }
+
+ return null;
+ }
+ }
+
@Override
public void onCommandRegistration(List commands) {
if (server == null) return;
diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java b/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java
index a3d441385..21978c270 100644
--- a/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java
+++ b/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java
@@ -38,7 +38,6 @@ public class ForgePlayer extends LocalPlayer {
private EntityPlayerMP player;
protected ForgePlayer(EntityPlayerMP player) {
- super((ServerInterface) ForgeWorldEdit.inst.getPlatform());
this.player = player;
}
diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeWorld.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeWorld.java
index 2f64a1f82..9271a1ce2 100644
--- a/src/forge/java/com/sk89q/worldedit/forge/ForgeWorld.java
+++ b/src/forge/java/com/sk89q/worldedit/forge/ForgeWorld.java
@@ -107,7 +107,7 @@ public class ForgeWorld extends AbstractWorld {
@Override
public String getName() {
- return getWorld().provider.getDimensionName();
+ return getWorld().getWorldInfo().getWorldName();
}
@Override
@@ -459,11 +459,15 @@ public class ForgeWorld extends AbstractWorld {
@Override
public boolean equals(Object o) {
- if ((o instanceof ForgeWorld)) {
- ForgeWorld other = ((ForgeWorld) o);
- World otherWorld = other.worldRef.get();
- World thisWorld = other.worldRef.get();
- return otherWorld != null && thisWorld != null && otherWorld.equals(thisWorld);
+ if (o == null) {
+ return false;
+ } else if ((o instanceof ForgeWorld)) {
+ ForgeWorld other = ((ForgeWorld) o);
+ World otherWorld = other.worldRef.get();
+ World thisWorld = other.worldRef.get();
+ return otherWorld != null && thisWorld != null && otherWorld.equals(thisWorld);
+ } else if (o instanceof com.sk89q.worldedit.world.World) {
+ return ((com.sk89q.worldedit.world.World) o).getName().equals(getName());
} else {
return false;
}
diff --git a/src/main/java/com/sk89q/worldedit/LocalPlayer.java b/src/main/java/com/sk89q/worldedit/LocalPlayer.java
index c284c3ffb..49c7e28bc 100644
--- a/src/main/java/com/sk89q/worldedit/LocalPlayer.java
+++ b/src/main/java/com/sk89q/worldedit/LocalPlayer.java
@@ -31,13 +31,4 @@ import com.sk89q.worldedit.extension.platform.Actor;
@Deprecated
public abstract class LocalPlayer extends AbstractPlayerActor {
- /**
- * Construct the object.
- *
- * @param server A reference to the server this player is on
- */
- protected LocalPlayer(ServerInterface server) {
- super(server);
- }
-
}
diff --git a/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java b/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java
index 2e00f5e7c..9e4c9843c 100644
--- a/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java
+++ b/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java
@@ -40,19 +40,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/
public abstract class AbstractPlayerActor implements Actor, Player {
- private final Platform platform;
-
- /**
- * Create a new instance.
- *
- * @param platform the platform
- */
- protected AbstractPlayerActor(Platform platform) {
- checkNotNull(platform);
-
- this.platform = platform;
- }
-
/**
* Returns direction according to rotation. May return null.
*
diff --git a/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java b/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java
index 5fcfa4941..b4f542599 100644
--- a/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java
+++ b/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java
@@ -24,8 +24,10 @@ import com.sk89q.minecraft.util.commands.CommandsManager;
import com.sk89q.worldedit.BiomeTypes;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalPlayer;
+import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.world.World;
+import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
@@ -78,6 +80,26 @@ public interface Platform {
List extends World> getWorlds();
+ /**
+ * Create a duplicate of the given player.
+ *
+ * The given player may have been provided by a different platform.
+ *
+ * @param player the player to match
+ * @return a matched player, otherwise null
+ */
+ @Nullable Player matchPlayer(Player player);
+
+ /**
+ * Create a duplicate of the given world.
+ *
+ * The given world may have been provided by a different platform.
+ *
+ * @param world the world to match
+ * @return a matched world, otherwise null
+ */
+ @Nullable World matchWorld(World world);
+
@Deprecated
void onCommandRegistration(List commands);
diff --git a/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java b/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java
index 7c04b8168..518bbb9f8 100644
--- a/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java
+++ b/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java
@@ -31,6 +31,7 @@ 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.*;
@@ -207,6 +208,44 @@ public class PlatformManager {
return new ArrayList(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 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;
+ }
+
+ return (T) new PlayerProxy(player, permActor, getWorldForEditing(base.getWorld()));
+ } else {
+ return base;
+ }
+ }
+
/**
* Get the command manager.
*
@@ -247,7 +286,10 @@ public class PlatformManager {
@SuppressWarnings("deprecation")
@Subscribe
public void handleBlockInteract(BlockInteractEvent event) {
- Actor actor = event.getCause();
+ // 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();
@@ -335,7 +377,9 @@ public class PlatformManager {
@SuppressWarnings("deprecation")
@Subscribe
public void handlePlayerInput(PlayerInputEvent event) {
- Player player = event.getPlayer();
+ // 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: {
diff --git a/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java b/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java
new file mode 100644
index 000000000..ce14651be
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java
@@ -0,0 +1,125 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 .
+ */
+
+package com.sk89q.worldedit.extension.platform;
+
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.WorldVector;
+import com.sk89q.worldedit.entity.Player;
+import com.sk89q.worldedit.extent.inventory.BlockBag;
+import com.sk89q.worldedit.util.Location;
+import com.sk89q.worldedit.world.World;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+class PlayerProxy extends AbstractPlayerActor {
+
+ private final Player basePlayer;
+ private final Actor permActor;
+ private final World world;
+
+ PlayerProxy(Player basePlayer, Actor permActor, World world) {
+ checkNotNull(basePlayer);
+ checkNotNull(permActor);
+ checkNotNull(world);
+ this.basePlayer = basePlayer;
+ this.permActor = permActor;
+ this.world = world;
+ }
+
+ @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 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);
+ }
+}
diff --git a/src/main/java/com/sk89q/worldedit/internal/ServerInterfaceAdapter.java b/src/main/java/com/sk89q/worldedit/internal/ServerInterfaceAdapter.java
index 96cac54b3..ab582847f 100644
--- a/src/main/java/com/sk89q/worldedit/internal/ServerInterfaceAdapter.java
+++ b/src/main/java/com/sk89q/worldedit/internal/ServerInterfaceAdapter.java
@@ -25,11 +25,13 @@ import com.sk89q.worldedit.BiomeTypes;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.ServerInterface;
+import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extension.platform.Preference;
import com.sk89q.worldedit.world.World;
+import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
@@ -82,6 +84,18 @@ public class ServerInterfaceAdapter extends ServerInterface {
return platform.getWorlds();
}
+ @Nullable
+ @Override
+ public Player matchPlayer(Player player) {
+ return platform.matchPlayer(player);
+ }
+
+ @Nullable
+ @Override
+ public World matchWorld(World world) {
+ return platform.matchWorld(world);
+ }
+
@Override
@Deprecated
public void onCommandRegistration(List commands) {