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 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) {