From 6c505c8c02b9b15848c6b307a4aa19102341efa7 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Mon, 6 Mar 2017 03:19:14 +1100 Subject: [PATCH] Clean up brushes --- .../com/boydti/fawe/bukkit/FaweBukkit.java | 1 + .../sk89q/worldedit/bukkit/BukkitPlayer.java | 280 ++++++++++ core/src/main/java/com/boydti/fawe/Fawe.java | 4 + .../fawe/object/brush/AbstractBrush.java | 20 + .../fawe/object/brush/BrushSettings.java | 1 - .../boydti/fawe/object/brush/CircleBrush.java | 5 +- .../fawe/object/brush/CommandBrush.java | 5 +- .../fawe/object/brush/CopyPastaBrush.java | 7 +- .../fawe/object/brush/FlattenBrush.java | 7 +- .../boydti/fawe/object/brush/HeightBrush.java | 11 +- .../fawe/object/brush/RecurseBrush.java | 7 +- .../boydti/fawe/object/brush/SplineBrush.java | 9 +- .../object/brush/scroll/ScrollAction.java | 10 +- .../fawe/object/brush/scroll/ScrollMask.java | 2 +- .../object/brush/scroll/ScrollPattern.java | 2 +- .../fawe/object/brush/scroll/ScrollRange.java | 4 +- .../fawe/object/brush/scroll/ScrollSize.java | 4 +- .../object/brush/scroll/ScrollTarget.java | 4 +- .../serializer/BaseBlockSerializer.java | 30 ++ .../serializer/BlockVectorSerializer.java | 36 ++ .../serializer/EditSessionSerializer.java | 30 ++ .../object/serializer/InheritedExclusion.java | 50 ++ .../object/serializer/JsonSerializable.java | 10 + .../serializer/LocalSessionSerializer.java | 28 + .../object/serializer/PlayerSerializer.java | 25 + .../com/sk89q/worldedit/LocalSession.java | 2 +- .../worldedit/command/BrushCommands.java | 18 +- .../worldedit/command/tool/BrushTool.java | 80 +-- .../command/tool/brush/GravityBrush.java | 4 +- .../extension/factory/DefaultBlockParser.java | 7 +- .../platform/AbstractPlayerActor.java | 492 ++++++++++++++++++ .../extension/platform/PlayerProxy.java | 133 +++++ .../sk89q/worldedit/forge/ForgePlayer.java | 9 +- .../sk89q/worldedit/forge/ForgePlayer.java | 9 +- .../sk89q/worldedit/forge/ForgePlayer.java | 16 +- .../sk89q/worldedit/forge/ForgePlayer.java | 17 +- .../sk89q/worldedit/forge/ForgePlayer.java | 10 + .../boydti/fawe/nukkit/core/NukkitPlayer.java | 5 +- .../com/boydti/fawe/sponge/FaweSponge.java | 1 + .../sk89q/worldedit/sponge/SpongePlayer.java | 233 +++++++++ 40 files changed, 1522 insertions(+), 106 deletions(-) create mode 100644 bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java create mode 100644 core/src/main/java/com/boydti/fawe/object/brush/AbstractBrush.java create mode 100644 core/src/main/java/com/boydti/fawe/object/serializer/BaseBlockSerializer.java create mode 100644 core/src/main/java/com/boydti/fawe/object/serializer/BlockVectorSerializer.java create mode 100644 core/src/main/java/com/boydti/fawe/object/serializer/EditSessionSerializer.java create mode 100644 core/src/main/java/com/boydti/fawe/object/serializer/InheritedExclusion.java create mode 100644 core/src/main/java/com/boydti/fawe/object/serializer/JsonSerializable.java create mode 100644 core/src/main/java/com/boydti/fawe/object/serializer/LocalSessionSerializer.java create mode 100644 core/src/main/java/com/boydti/fawe/object/serializer/PlayerSerializer.java create mode 100644 core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java create mode 100644 core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java create mode 100644 sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java index 6fce129f..10e3cfb6 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java @@ -70,6 +70,7 @@ public class FaweBukkit implements IFawe, Listener { try { Fawe.set(this); setupInjector(); + com.sk89q.worldedit.bukkit.BukkitPlayer.inject(); new BrushListener(plugin); if (Bukkit.getVersion().contains("git-Spigot")) { debug("====== USE PAPER ======"); diff --git a/bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java new file mode 100644 index 00000000..281c328f --- /dev/null +++ b/bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -0,0 +1,280 @@ +/* + * 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.bukkit; + +import com.boydti.fawe.FaweCache; +import com.sk89q.util.StringUtil; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.ServerInterface; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.WorldVector; +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.blocks.SkullBlock; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.internal.cui.CUIEvent; +import com.sk89q.worldedit.session.SessionKey; +import java.util.UUID; +import javax.annotation.Nullable; +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.material.Dye; + +public class BukkitPlayer extends LocalPlayer { + + private Player player; + private WorldEditPlugin plugin; + + public BukkitPlayer(WorldEditPlugin plugin, ServerInterface server, Player player) { + this.plugin = plugin; + this.player = player; + } + + @Override + public UUID getUniqueId() { + return player.getUniqueId(); + } + + @Override + public int getItemInHand() { + ItemStack itemStack = player.getItemInHand(); + return itemStack != null ? itemStack.getTypeId() : 0; + } + + @Override + public BaseBlock getBlockInHand() throws WorldEditException { + ItemStack itemStack = player.getItemInHand(); + if (itemStack == null) { + return EditSession.nullBlock; + } + final int typeId = itemStack.getTypeId(); + switch (typeId) { + case ItemID.INK_SACK: + final Dye materialData = (Dye) itemStack.getData(); + if (materialData.getColor() == DyeColor.BROWN) { + return FaweCache.getBlock(BlockID.COCOA_PLANT, 0); + } + break; + + case ItemID.HEAD: + return new SkullBlock(0, (byte) itemStack.getDurability()); + + default: + final BaseBlock baseBlock = BlockType.getBlockForItem(typeId, itemStack.getDurability()); + if (baseBlock != null) { + return baseBlock; + } + break; + } + return FaweCache.getBlock(typeId, itemStack.getType().getMaxDurability() != 0 ? 0 : Math.max(0, itemStack.getDurability())); + } + + @Override + public String getName() { + return player.getName(); + } + + @Override + public WorldVector getPosition() { + Location loc = player.getLocation(); + return new WorldVector(BukkitUtil.getLocalWorld(loc.getWorld()), + loc.getX(), loc.getY(), loc.getZ()); + } + + @Override + public double getPitch() { + return player.getLocation().getPitch(); + } + + @Override + public double getYaw() { + return player.getLocation().getYaw(); + } + + @Override + public void giveItem(int type, int amt) { + player.getInventory().addItem(new ItemStack(type, amt)); + } + + @Override + public void printRaw(String msg) { + for (String part : msg.split("\n")) { + player.sendMessage(part); + } + } + + @Override + public void print(String msg) { + for (String part : msg.split("\n")) { + player.sendMessage("\u00A7d" + part); + } + } + + @Override + public void printDebug(String msg) { + for (String part : msg.split("\n")) { + player.sendMessage("\u00A77" + part); + } + } + + @Override + public void printError(String msg) { + for (String part : msg.split("\n")) { + player.sendMessage("\u00A7c" + part); + } + } + + @Override + public void setPosition(Vector pos, float pitch, float yaw) { + player.teleport(new Location(player.getWorld(), pos.getX(), pos.getY(), + pos.getZ(), yaw, pitch)); + } + + @Override + public String[] getGroups() { + return plugin.getPermissionsResolver().getGroups(player); + } + + @Override + public BlockBag getInventoryBlockBag() { + return new BukkitPlayerBlockBag(player); + } + + @Override + public boolean hasPermission(String perm) { + return (!plugin.getLocalConfiguration().noOpPermissions && player.isOp()) + || plugin.getPermissionsResolver().hasPermission( + player.getWorld().getName(), player, perm); + } + + @Override + public LocalWorld getWorld() { + return BukkitUtil.getLocalWorld(player.getWorld()); + } + + @Override + public void dispatchCUIEvent(CUIEvent event) { + String[] params = event.getParameters(); + String send = event.getTypeId(); + if (params.length > 0) { + send = send + "|" + StringUtil.joinString(params, "|"); + } + player.sendPluginMessage(plugin, WorldEditPlugin.CUI_PLUGIN_CHANNEL, send.getBytes(CUIChannelListener.UTF_8_CHARSET)); + } + + public Player getPlayer() { + return player; + } + + @Override + public boolean hasCreativeMode() { + return player.getGameMode() == GameMode.CREATIVE; + } + + @Override + public void floatAt(int x, int y, int z, boolean alwaysGlass) { + if (alwaysGlass || !player.getAllowFlight()) { + super.floatAt(x, y, z, alwaysGlass); + return; + } + + setPosition(new Vector(x + 0.5, y, z + 0.5)); + player.setFlying(true); + } + + @Override + public BaseEntity getState() { + throw new UnsupportedOperationException("Cannot create a state from this object"); + } + + @Override + public com.sk89q.worldedit.util.Location getLocation() { + Location nativeLocation = player.getLocation(); + Vector position = BukkitUtil.toVector(nativeLocation); + return new com.sk89q.worldedit.util.Location( + getWorld(), + position, + nativeLocation.getYaw(), + nativeLocation.getPitch()); + } + + @Nullable + @Override + public T getFacet(Class cls) { + return null; + } + + @Override + public SessionKey getSessionKey() { + return new SessionKeyImpl(this.player.getUniqueId(), player.getName()); + } + + private static class SessionKeyImpl implements SessionKey { + // If not static, this will leak a reference + + private final UUID uuid; + private final String name; + + private SessionKeyImpl(UUID uuid, String name) { + this.uuid = uuid; + this.name = name; + } + + @Override + public UUID getUniqueId() { + return uuid; + } + + @Nullable + @Override + public String getName() { + return name; + } + + @Override + public boolean isActive() { + // This is a thread safe call on CraftBukkit because it uses a + // CopyOnWrite list for the list of players, but the Bukkit + // specification doesn't require thread safety (though the + // spec is extremely incomplete) + return Bukkit.getServer().getPlayerExact(name) != null; + } + + @Override + public boolean isPersistent() { + return true; + } + + } + + public static Class inject() { + return BukkitPlayer.class; + } +} \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/Fawe.java b/core/src/main/java/com/boydti/fawe/Fawe.java index 58b7e370..cbbf509e 100644 --- a/core/src/main/java/com/boydti/fawe/Fawe.java +++ b/core/src/main/java/com/boydti/fawe/Fawe.java @@ -59,8 +59,10 @@ import com.sk89q.worldedit.event.extent.EditSessionEvent; import com.sk89q.worldedit.extension.factory.DefaultBlockParser; import com.sk89q.worldedit.extension.factory.DefaultMaskParser; import com.sk89q.worldedit.extension.factory.HashTagPatternParser; +import com.sk89q.worldedit.extension.platform.AbstractPlayerActor; import com.sk89q.worldedit.extension.platform.CommandManager; import com.sk89q.worldedit.extension.platform.PlatformManager; +import com.sk89q.worldedit.extension.platform.PlayerProxy; import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; @@ -374,6 +376,8 @@ public class Fawe { EditSessionEvent.inject(); // Add EditSession to event (API) LocalSession.inject(); // Add remember order / queue flushing / Optimizations for disk / brush visualization SessionManager.inject(); // Faster custom session saving + Memory improvements + PlayerProxy.inject(); // Fixes getBlockInHand not being extended + AbstractPlayerActor.inject(); // Don't use exception for getBlockInHand control flow Request.inject(); // Custom pattern extent // Commands BiomeCommands.inject(); // Translations + Optimizations diff --git a/core/src/main/java/com/boydti/fawe/object/brush/AbstractBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/AbstractBrush.java new file mode 100644 index 00000000..910450f3 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/brush/AbstractBrush.java @@ -0,0 +1,20 @@ +package com.boydti.fawe.object.brush; + +import com.sk89q.worldedit.command.tool.BrushTool; +import com.sk89q.worldedit.command.tool.brush.Brush; + +public abstract class AbstractBrush implements Brush { + private BrushTool tool; + + public AbstractBrush(BrushTool tool) { + this.tool = tool; + } + + public void setTool(BrushTool tool) { + this.tool = tool; + } + + public BrushTool getTool() { + return tool; + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/brush/BrushSettings.java b/core/src/main/java/com/boydti/fawe/object/brush/BrushSettings.java index 38a84cc8..9b5e1fc0 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/BrushSettings.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/BrushSettings.java @@ -8,7 +8,6 @@ import com.sk89q.worldedit.function.pattern.Pattern; public class BrushSettings { public Brush brush = null; - public Mask mask = null; public Mask sourceMask = null; public ResettableExtent transform = null; diff --git a/core/src/main/java/com/boydti/fawe/object/brush/CircleBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/CircleBrush.java index 11a454da..8b9a8a99 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/CircleBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/CircleBrush.java @@ -4,7 +4,6 @@ import com.boydti.fawe.wrappers.LocationMaskedPlayerWrapper; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.command.tool.BrushTool; import com.sk89q.worldedit.command.tool.brush.Brush; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.function.pattern.Pattern; @@ -12,10 +11,8 @@ import com.sk89q.worldedit.math.transform.AffineTransform; public class CircleBrush implements Brush { private final Player player; - private final BrushTool tool; - public CircleBrush(BrushTool tool, Player player) { - this.tool = tool; + public CircleBrush(Player player) { this.player = LocationMaskedPlayerWrapper.unwrap(player); } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/CommandBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/CommandBrush.java index c80f4fa2..eb38d109 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/CommandBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/CommandBrush.java @@ -8,7 +8,6 @@ import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldVectorFace; -import com.sk89q.worldedit.command.tool.BrushTool; import com.sk89q.worldedit.command.tool.brush.Brush; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.event.platform.CommandEvent; @@ -21,12 +20,10 @@ public class CommandBrush implements Brush { private final String command; private final int radius; - private final BrushTool tool; - public CommandBrush(BrushTool tool, String command, double radius) { + public CommandBrush(String command, double radius) { this.command = command; this.radius = (int) radius; - this.tool = tool; } @Override diff --git a/core/src/main/java/com/boydti/fawe/object/brush/CopyPastaBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/CopyPastaBrush.java index c50d7068..32c2305f 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/CopyPastaBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/CopyPastaBrush.java @@ -12,7 +12,6 @@ import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.command.tool.BrushTool; import com.sk89q.worldedit.command.tool.brush.Brush; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.function.mask.Mask; @@ -27,12 +26,10 @@ import com.sk89q.worldedit.session.ClipboardHolder; public class CopyPastaBrush implements Brush, ResettableTool { - private final BrushTool tool; private final LocalSession session; private final boolean randomRotate; - public CopyPastaBrush(BrushTool tool, LocalSession session, boolean randomRotate) { - this.tool = tool; + public CopyPastaBrush(LocalSession session, boolean randomRotate) { session.setClipboard(null); this.session = session; this.randomRotate = randomRotate; @@ -52,7 +49,7 @@ public class CopyPastaBrush implements Brush, ResettableTool { if (editSession.getExtent() instanceof VisualExtent) { return; } - Mask mask = tool.getMask(); + Mask mask = editSession.getMask(); if (mask == null) { mask = Masks.alwaysTrue(); } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/FlattenBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/FlattenBrush.java index ddc66722..a31b8583 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/FlattenBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/FlattenBrush.java @@ -4,7 +4,6 @@ import com.boydti.fawe.object.brush.heightmap.ScalableHeightMap; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.command.tool.BrushTool; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Masks; @@ -13,14 +12,14 @@ import java.io.InputStream; public class FlattenBrush extends HeightBrush { - public FlattenBrush(InputStream stream, int rotation, double yscale, BrushTool tool, Clipboard clipboard, ScalableHeightMap.Shape shape) { - super(stream, rotation, yscale, tool, clipboard, shape); + public FlattenBrush(InputStream stream, int rotation, double yscale, Clipboard clipboard, ScalableHeightMap.Shape shape) { + super(stream, rotation, yscale, clipboard, shape); } @Override public void build(EditSession editSession, Vector position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException { int size = (int) sizeDouble; - Mask mask = tool.getMask(); + Mask mask = editSession.getMask(); if (mask == Masks.alwaysTrue() || mask == Masks.alwaysTrue2D()) { mask = null; } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/HeightBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/HeightBrush.java index 8708ed79..b0772b0b 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/HeightBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/HeightBrush.java @@ -6,7 +6,6 @@ import com.boydti.fawe.object.exception.FaweException; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.command.tool.BrushTool; import com.sk89q.worldedit.command.tool.brush.Brush; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.function.mask.Mask; @@ -20,13 +19,12 @@ public class HeightBrush implements Brush { public final ScalableHeightMap heightMap; public final int rotation; public final double yscale; - public final BrushTool tool; - public HeightBrush(InputStream stream, int rotation, double yscale, BrushTool tool, Clipboard clipboard) { - this(stream, rotation, yscale, tool, clipboard, ScalableHeightMap.Shape.CONE); + public HeightBrush(InputStream stream, int rotation, double yscale, Clipboard clipboard) { + this(stream, rotation, yscale, clipboard, ScalableHeightMap.Shape.CONE); } - public HeightBrush(InputStream stream, int rotation, double yscale, BrushTool tool, Clipboard clipboard, ScalableHeightMap.Shape shape) { + public HeightBrush(InputStream stream, int rotation, double yscale, Clipboard clipboard, ScalableHeightMap.Shape shape) { this.rotation = (rotation / 90) % 4; this.yscale = yscale; if (stream != null) { @@ -40,13 +38,12 @@ public class HeightBrush implements Brush { } else { heightMap = ScalableHeightMap.fromShape(shape); } - this.tool = tool; } @Override public void build(EditSession editSession, Vector position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException { int size = (int) sizeDouble; - Mask mask = tool.getMask(); + Mask mask = editSession.getMask(); if (mask == Masks.alwaysTrue() || mask == Masks.alwaysTrue2D()) { mask = null; } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/RecurseBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/RecurseBrush.java index 58453c43..4c9bdfa5 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/RecurseBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/RecurseBrush.java @@ -6,7 +6,6 @@ import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.command.tool.BrushTool; import com.sk89q.worldedit.command.tool.brush.Brush; import com.sk89q.worldedit.function.block.BlockReplace; import com.sk89q.worldedit.function.mask.Mask; @@ -17,17 +16,15 @@ import com.sk89q.worldedit.function.visitor.RecursiveVisitor; public class RecurseBrush implements Brush { - private final BrushTool tool; private final boolean dfs; - public RecurseBrush(BrushTool tool, boolean dfs) { - this.tool = tool; + public RecurseBrush(boolean dfs) { this.dfs = dfs; } @Override public void build(final EditSession editSession, final Vector position, Pattern to, double size) throws MaxChangedBlocksException { - Mask mask = tool.getMask(); + Mask mask = editSession.getMask(); if (mask == null) { mask = Masks.alwaysTrue(); } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/SplineBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/SplineBrush.java index 5bffdf85..1074c7fb 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/SplineBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/SplineBrush.java @@ -10,7 +10,6 @@ import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.command.tool.BrushTool; import com.sk89q.worldedit.command.tool.brush.Brush; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.function.RegionFunction; @@ -33,13 +32,11 @@ public class SplineBrush implements Brush { private ArrayList> positionSets; private int numSplines; - private final BrushTool tool; private final LocalSession session; private final Player player; private Vector position; - public SplineBrush(Player player, LocalSession session, BrushTool tool) { - this.tool = tool; + public SplineBrush(Player player, LocalSession session) { this.session = session; this.player = player; this.positionSets = new ArrayList<>(); @@ -47,7 +44,7 @@ public class SplineBrush implements Brush { @Override public void build(EditSession editSession, final Vector position, Pattern pattern, double size) throws MaxChangedBlocksException { - Mask mask = tool.getMask(); + Mask mask = editSession.getMask(); if (mask == null) { mask = new IdMask(editSession); } else { @@ -65,7 +62,7 @@ public class SplineBrush implements Brush { throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS); } final ArrayList points = new ArrayList<>(); - if (tool.getSize() > 0) { + if (size > 0) { DFSRecursiveVisitor visitor = new DFSRecursiveVisitor(mask, new RegionFunction() { @Override public boolean apply(Vector p) throws WorldEditException { diff --git a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollAction.java b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollAction.java index 704078c1..371554ba 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollAction.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollAction.java @@ -3,9 +3,17 @@ package com.boydti.fawe.object.brush.scroll; import com.sk89q.worldedit.command.tool.BrushTool; public abstract class ScrollAction implements ScrollTool { - public final BrushTool tool; + private BrushTool tool; public ScrollAction(BrushTool tool) { this.tool = tool; } + + public void setTool(BrushTool tool) { + this.tool = tool; + } + + public BrushTool getTool() { + return tool; + } } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollMask.java b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollMask.java index b2777e55..8ebfeaf6 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollMask.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollMask.java @@ -18,7 +18,7 @@ public class ScrollMask extends ScrollAction { @Override public boolean increment(Player player, int amount) { if (masks.length > 1) { - tool.setMask(masks[MathMan.wrap(index += amount, 0, masks.length - 1)]); + getTool().setMask(masks[MathMan.wrap(index += amount, 0, masks.length - 1)]); return true; } return false; diff --git a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollPattern.java b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollPattern.java index f5536b9c..8ab209fb 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollPattern.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollPattern.java @@ -18,7 +18,7 @@ public class ScrollPattern extends ScrollAction { @Override public boolean increment(Player player, int amount) { if (patterns.length > 1) { - tool.setFill(patterns[MathMan.wrap(index += amount, 0, patterns.length - 1)]); + getTool().setFill(patterns[MathMan.wrap(index += amount, 0, patterns.length - 1)]); return true; } return false; diff --git a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollRange.java b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollRange.java index d491b9c4..d673a3c1 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollRange.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollRange.java @@ -13,8 +13,8 @@ public class ScrollRange extends ScrollAction { @Override public boolean increment(Player player, int amount) { int max = WorldEdit.getInstance().getConfiguration().maxBrushRadius; - int newSize = MathMan.wrap(tool.getRange() + amount, (int) (tool.getSize() + 1), max); - tool.setRange(newSize); + int newSize = MathMan.wrap(getTool().getRange() + amount, (int) (getTool().getSize() + 1), max); + getTool().setRange(newSize); return true; } } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollSize.java b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollSize.java index 78b0e9f0..7cf03f14 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollSize.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollSize.java @@ -12,8 +12,8 @@ public class ScrollSize extends ScrollAction { @Override public boolean increment(Player player, int amount) { int max = WorldEdit.getInstance().getConfiguration().maxRadius; - double newSize = Math.max(0, Math.min(max, tool.getSize() + amount)); - tool.setSize(newSize); + double newSize = Math.max(0, Math.min(max, getTool().getSize() + amount)); + getTool().setSize(newSize); return true; } } diff --git a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollTarget.java b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollTarget.java index da68eb74..d4771b1b 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollTarget.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/scroll/ScrollTarget.java @@ -12,11 +12,11 @@ public class ScrollTarget extends ScrollAction { @Override public boolean increment(Player player, int amount) { - TargetMode mode = tool.getTargetMode(); + TargetMode mode = getTool().getTargetMode(); int index = mode.ordinal() + amount; TargetMode[] modes = TargetMode.values(); TargetMode newMode = modes[MathMan.wrap(index, 0, modes.length - 1)]; - tool.setTargetMode(newMode); + getTool().setTargetMode(newMode); return true; } } diff --git a/core/src/main/java/com/boydti/fawe/object/serializer/BaseBlockSerializer.java b/core/src/main/java/com/boydti/fawe/object/serializer/BaseBlockSerializer.java new file mode 100644 index 00000000..25e333ce --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/serializer/BaseBlockSerializer.java @@ -0,0 +1,30 @@ +package com.boydti.fawe.object.serializer; + +import com.boydti.fawe.FaweCache; +import com.google.gson.JsonArray; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.sk89q.worldedit.blocks.BaseBlock; +import java.lang.reflect.Type; + +public class BaseBlockSerializer extends JsonSerializable { + @Override + public BaseBlock deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + JsonArray jsonArray = json.getAsJsonArray(); + if (jsonArray.size() != 2) { + throw new JsonParseException("Expected array of 3 length for Vector"); + } + return FaweCache.getBlock(jsonArray.get(0).getAsInt(), jsonArray.get(1).getAsInt()); + } + + @Override + public JsonElement serialize(BaseBlock src, Type typeOfSrc, JsonSerializationContext context) { + JsonArray array = new JsonArray(); + array.add(new JsonPrimitive(src.getId())); + array.add(new JsonPrimitive(src.getData())); + return array; + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/serializer/BlockVectorSerializer.java b/core/src/main/java/com/boydti/fawe/object/serializer/BlockVectorSerializer.java new file mode 100644 index 00000000..48527250 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/serializer/BlockVectorSerializer.java @@ -0,0 +1,36 @@ +package com.boydti.fawe.object.serializer; + +import com.google.gson.JsonArray; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.sk89q.worldedit.MutableBlockVector; +import com.sk89q.worldedit.Vector; +import java.lang.reflect.Type; + +public class BlockVectorSerializer extends JsonSerializable { + + @Override + public JsonElement serialize(Vector src, Type typeOfSrc, JsonSerializationContext context) { + JsonArray array = new JsonArray(); + array.add(new JsonPrimitive(src.getBlockX())); + array.add(new JsonPrimitive(src.getBlockY())); + array.add(new JsonPrimitive(src.getBlockZ())); + return array; + } + + + @Override + public Vector deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + JsonArray jsonArray = json.getAsJsonArray(); + if (jsonArray.size() != 3) { + throw new JsonParseException("Expected array of 3 length for Vector"); + } + int x = jsonArray.get(0).getAsInt(); + int y = jsonArray.get(1).getAsInt(); + int z = jsonArray.get(2).getAsInt(); + return new MutableBlockVector(x, y, z); + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/serializer/EditSessionSerializer.java b/core/src/main/java/com/boydti/fawe/object/serializer/EditSessionSerializer.java new file mode 100644 index 00000000..ff614864 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/serializer/EditSessionSerializer.java @@ -0,0 +1,30 @@ +package com.boydti.fawe.object.serializer; + +import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.util.EditSessionBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.entity.Player; +import java.lang.reflect.Type; + +public class EditSessionSerializer extends JsonSerializable { + + private final Player player; + + public EditSessionSerializer(Player player) { + this.player = player; + } + + @Override + public EditSession deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + return new EditSessionBuilder(player.getWorld()).player(FawePlayer.wrap(player)).build(); + } + + @Override + public JsonElement serialize(EditSession src, Type typeOfSrc, JsonSerializationContext context) { + return null; + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/serializer/InheritedExclusion.java b/core/src/main/java/com/boydti/fawe/object/serializer/InheritedExclusion.java new file mode 100644 index 00000000..b06f33a5 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/serializer/InheritedExclusion.java @@ -0,0 +1,50 @@ +package com.boydti.fawe.object.serializer; + +import com.google.gson.ExclusionStrategy; +import com.google.gson.FieldAttributes; +import java.lang.reflect.Field; + +public class InheritedExclusion implements ExclusionStrategy { + public boolean shouldSkipClass(Class arg0) + { + return false; + } + + public boolean shouldSkipField(FieldAttributes fieldAttributes) + { + String fieldName = fieldAttributes.getName(); + Class theClass = fieldAttributes.getDeclaringClass(); + + return isFieldInSuperclass(theClass, fieldName); + } + + private boolean isFieldInSuperclass(Class subclass, String fieldName) + { + Class superclass = subclass.getSuperclass(); + Field field; + + while(superclass != null) + { + field = getField(superclass, fieldName); + + if(field != null) + return true; + + superclass = superclass.getSuperclass(); + } + + return false; + } + + private Field getField(Class theClass, String fieldName) + { + try + { + return theClass.getDeclaredField(fieldName); + } + catch(Exception e) + { + return null; + } + } +} \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/object/serializer/JsonSerializable.java b/core/src/main/java/com/boydti/fawe/object/serializer/JsonSerializable.java new file mode 100644 index 00000000..da44aa27 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/serializer/JsonSerializable.java @@ -0,0 +1,10 @@ +package com.boydti.fawe.object.serializer; + +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonSerializer; + +public abstract class JsonSerializable implements JsonSerializer, JsonDeserializer { + + public JsonSerializable() { + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/serializer/LocalSessionSerializer.java b/core/src/main/java/com/boydti/fawe/object/serializer/LocalSessionSerializer.java new file mode 100644 index 00000000..9e4022dc --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/serializer/LocalSessionSerializer.java @@ -0,0 +1,28 @@ +package com.boydti.fawe.object.serializer; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.entity.Player; +import java.lang.reflect.Type; + +public class LocalSessionSerializer extends JsonSerializable { + private final Player player; + + public LocalSessionSerializer(Player player) { + this.player = player; + } + + @Override + public LocalSession deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + return WorldEdit.getInstance().getSessionManager().get(player); + } + + @Override + public JsonElement serialize(LocalSession src, Type typeOfSrc, JsonSerializationContext context) { + return null; + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/serializer/PlayerSerializer.java b/core/src/main/java/com/boydti/fawe/object/serializer/PlayerSerializer.java new file mode 100644 index 00000000..177a4a14 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/serializer/PlayerSerializer.java @@ -0,0 +1,25 @@ +package com.boydti.fawe.object.serializer; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.sk89q.worldedit.entity.Player; +import java.lang.reflect.Type; + +public class PlayerSerializer extends JsonSerializable { + private final Player player; + + public PlayerSerializer(Player player) { + this.player = player; + } + @Override + public Player deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + return player; + } + + @Override + public JsonElement serialize(Player src, Type typeOfSrc, JsonSerializationContext context) { + return null; + } +} diff --git a/core/src/main/java/com/sk89q/worldedit/LocalSession.java b/core/src/main/java/com/sk89q/worldedit/LocalSession.java index 2d2ce9af..c8e22a9e 100644 --- a/core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -975,7 +975,7 @@ public class LocalSession { } try { BaseBlock block = player.getBlockInHand(); - return getTool(block.getId(), block.getType()); + return getTool(block.getId(), block.getData()); } catch (WorldEditException e) { e.printStackTrace(); return null; diff --git a/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index 7b2f497d..6394db85 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -403,7 +403,7 @@ public class BrushCommands { BrushTool tool = session.getBrushTool(player); tool.setSize(radius); tool.setFill(fill); - tool.setBrush(new CircleBrush(tool, player), "worldedit.brush.circle", player); + tool.setBrush(new CircleBrush(player), "worldedit.brush.circle", player); player.print(BBC.getPrefix() + BBC.BRUSH_CIRCLE.f(radius)); } @@ -421,7 +421,7 @@ public class BrushCommands { worldEdit.checkMaxBrushRadius(radius); BrushTool tool = session.getBrushTool(player); tool.setSize(radius); - tool.setBrush(new RecurseBrush(tool, depthFirst), "worldedit.brush.recursive", player); + tool.setBrush(new RecurseBrush(depthFirst), "worldedit.brush.recursive", player); tool.setMask(new IdMask(editSession)); tool.setFill(fill); player.print(BBC.getPrefix() + BBC.BRUSH_RECURSIVE.f(radius)); @@ -464,7 +464,7 @@ public class BrushCommands { BrushTool tool = session.getBrushTool(player); tool.setFill(fill); tool.setSize(radius); - tool.setBrush(new SplineBrush(player, session, tool), "worldedit.brush.spline", player); + tool.setBrush(new SplineBrush(player, session), "worldedit.brush.spline", player); player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE.f(radius)); } @@ -735,15 +735,15 @@ public class BrushCommands { tool.setSize(radius); if (flat) { try { - tool.setBrush(new FlattenBrush(stream, rotation, yscale, tool, filename.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null, shape), "worldedit.brush.height", player); + tool.setBrush(new FlattenBrush(stream, rotation, yscale, filename.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null, shape), "worldedit.brush.height", player); } catch (EmptyClipboardException ignore) { - tool.setBrush(new FlattenBrush(stream, rotation, yscale, tool, null, shape), "worldedit.brush.height", player); + tool.setBrush(new FlattenBrush(stream, rotation, yscale, null, shape), "worldedit.brush.height", player); } } else { try { - tool.setBrush(new HeightBrush(stream, rotation, yscale, tool, filename.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null), "worldedit.brush.height", player); + tool.setBrush(new HeightBrush(stream, rotation, yscale, filename.equalsIgnoreCase("#clipboard") ? session.getClipboard().getClipboard() : null), "worldedit.brush.height", player); } catch (EmptyClipboardException ignore) { - tool.setBrush(new HeightBrush(stream, rotation, yscale, tool, null), "worldedit.brush.height", player); + tool.setBrush(new HeightBrush(stream, rotation, yscale, null), "worldedit.brush.height", player); } } player.print(BBC.getPrefix() + BBC.BRUSH_HEIGHT.f(radius)); @@ -767,7 +767,7 @@ public class BrushCommands { worldEdit.checkMaxBrushRadius(radius); BrushTool tool = session.getBrushTool(player); tool.setSize(radius); - tool.setBrush(new CopyPastaBrush(tool, session, rotate), "worldedit.brush.copy", player); + tool.setBrush(new CopyPastaBrush(session, rotate), "worldedit.brush.copy", player); player.print(BBC.getPrefix() + BBC.BRUSH_COPY.f(radius)); } @@ -784,7 +784,7 @@ public class BrushCommands { public void command(Player player, LocalSession session, @Optional("5") double radius, CommandContext args) throws WorldEditException { BrushTool tool = session.getBrushTool(player); String cmd = args.getJoinedStrings(1); - tool.setBrush(new CommandBrush(tool, cmd, radius), "worldedit.brush.copy", player); + tool.setBrush(new CommandBrush(cmd, radius), "worldedit.brush.copy", player); player.print(BBC.getPrefix() + BBC.BRUSH_COMMAND.f(cmd)); } diff --git a/core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java b/core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java index cabc0a92..101e1065 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java +++ b/core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java @@ -50,10 +50,13 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool private VisualMode visualMode = VisualMode.NONE; private TargetMode targetMode = TargetMode.TARGET_BLOCK_RANGE; - private BrushSettings context = new BrushSettings(); + private transient BrushSettings context = new BrushSettings(); private BrushSettings primary = context; private BrushSettings secondary = context; + private transient VisualExtent visualExtent; + private transient Lock lock = new ReentrantLock(); + /** * Construct the tool. * @@ -61,19 +64,31 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool */ public BrushTool(String permission) { checkNotNull(permission); - this.context.permission = permission; + this.getContext().permission = permission; + } + + public BrushSettings getContext() { + BrushSettings tmp = context; + if (tmp == null) { + context = tmp = primary; + } + return tmp; + } + + public void setContext(BrushSettings context) { + this.context = context; } @Override public boolean canUse(Actor player) { if (primary == secondary) { - return player.hasPermission(context.permission); + return player.hasPermission(getContext().permission); } return player.hasPermission(primary.permission) && player.hasPermission(secondary.permission); } public ResettableExtent getTransform() { - return context.transform; + return getContext().transform; } public BrushSettings getPrimary() { @@ -95,7 +110,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool } public void setTransform(ResettableExtent transform) { - this.context.transform = transform; + this.getContext().transform = transform; } /** @@ -104,7 +119,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool * @return the filter */ public Mask getMask() { - return context.mask; + return getContext().mask; } /** @@ -113,7 +128,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool * @return the filter */ public Mask getSourceMask() { - return context.sourceMask; + return getContext().sourceMask; } /** @@ -122,7 +137,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool * @param filter the filter to set */ public void setMask(Mask filter) { - this.context.mask = filter; + this.getContext().mask = filter; } /** @@ -131,7 +146,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool * @param filter the filter to set */ public void setSourceMask(Mask filter) { - this.context.sourceMask = filter; + this.getContext().sourceMask = filter; } /** @@ -146,7 +161,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool public void setBrush(Brush brush, String permission, Player player) { if (player != null) clear(player); - BrushSettings current = context; + BrushSettings current = getContext(); current.brush = brush; current.permission = permission; } @@ -157,7 +172,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool * @return the current brush */ public Brush getBrush() { - return context.brush; + return getContext().brush; } /** @@ -166,7 +181,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool * @param material the material */ public void setFill(@Nullable Pattern material) { - this.context.material = material; + this.getContext().material = material; } /** @@ -175,7 +190,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool * @return the material */ @Nullable public Pattern getMaterial() { - return context.material; + return getContext().material; } /** @@ -184,7 +199,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool * @return a radius */ public double getSize() { - return context.size; + return getContext().size; } /** @@ -193,7 +208,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool * @param radius a radius */ public void setSize(double radius) { - this.context.size = radius; + this.getContext().size = radius; } /** @@ -253,14 +268,14 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool public boolean act(BrushAction action, Platform server, LocalConfiguration config, Player player, LocalSession session) { switch (action) { case PRIMARY: - context = primary; + setContext(primary); break; case SECONDARY: - context = secondary; + setContext(secondary); break; } - BrushSettings current = context; + BrushSettings current = getContext(); EditSession editSession = session.createEditSession(player); Vector target = getPosition(editSession, player); @@ -330,7 +345,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool } public void setScrollAction(ScrollAction scrollAction) { - this.context.scrollAction = scrollAction; + this.getContext().scrollAction = scrollAction; } public void setTargetMode(TargetMode targetMode) { @@ -351,18 +366,22 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool @Override public boolean increment(Player player, int amount) { - BrushSettings current = context; + BrushSettings current = getContext(); ScrollAction tmp = current.scrollAction; - if (tmp != null && tmp.increment(player, amount)) { - if (visualMode != VisualMode.NONE) { - try { - queueVisualization(FawePlayer.wrap(player)); - } catch (Throwable e) { - WorldEdit.getInstance().getPlatformManager().handleThrowable(e, player); + if (tmp != null) { + tmp.setTool(this); + if (tmp.increment(player, amount)) { + if (visualMode != VisualMode.NONE) { + try { + queueVisualization(FawePlayer.wrap(player)); + } catch (Throwable e) { + WorldEdit.getInstance().getPlatformManager().handleThrowable(e, player); + } } + return true; } - return true; - } else if (visualMode != VisualMode.NONE) { + } + if (visualMode != VisualMode.NONE) { clear(player); } return false; @@ -397,7 +416,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool break; } case OUTLINE: { - BrushSettings current = context; + BrushSettings current = getContext(); current.brush.build(editSession, position, current.material, current.size); break; } @@ -427,7 +446,4 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool } return false; } - - private VisualExtent visualExtent; - private Lock lock = new ReentrantLock(); } diff --git a/core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java b/core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java index ede143b9..808d8cf8 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java +++ b/core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java @@ -31,16 +31,14 @@ import com.sk89q.worldedit.function.pattern.Pattern; public class GravityBrush implements Brush { private final boolean fullHeight; - private final BrushTool tool; public GravityBrush(boolean fullHeight, BrushTool tool) { this.fullHeight = fullHeight; - this.tool = tool; } @Override public void build(EditSession editSession, Vector position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException { - Mask mask = tool.getMask(); + Mask mask = editSession.getMask(); if (mask == Masks.alwaysTrue() || mask == Masks.alwaysTrue2D()) { mask = null; } diff --git a/core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultBlockParser.java b/core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultBlockParser.java index b33f46f3..3255509f 100644 --- a/core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultBlockParser.java +++ b/core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultBlockParser.java @@ -63,7 +63,12 @@ public class DefaultBlockParser extends InputParser { private static BaseBlock getBlockInHand(Actor actor) throws InputParseException { if (actor instanceof Player) { try { - return ((Player) actor).getBlockInHand(); + BaseBlock block = ((Player) actor).getBlockInHand(); + if(((Player) actor).getWorld().isValidBlockType(block.getId())) { + return block; + } else { + throw new InputParseException("You're not holding a block!"); + } } catch (NotABlockException e) { throw new InputParseException("You're not holding a block!"); } catch (WorldEditException e) { diff --git a/core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java b/core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java new file mode 100644 index 00000000..4a8ce300 --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java @@ -0,0 +1,492 @@ +/* + * 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.BlockWorldVector; +import com.sk89q.worldedit.LocalPlayer; +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.util.auth.AuthorizationException; +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(); + 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; + } + + public static Class inject() { + return AbstractPlayerActor.class; + } +} diff --git a/core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java b/core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java new file mode 100644 index 00000000..2292cfbf --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java @@ -0,0 +1,133 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by Fernflower decompiler) +// + +package com.sk89q.worldedit.extension.platform; + +import com.google.common.base.Preconditions; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.WorldVector; +import com.sk89q.worldedit.blocks.BaseBlock; +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 java.util.UUID; +import javax.annotation.Nullable; + +public class PlayerProxy extends AbstractPlayerActor { + private final Player basePlayer; + private final Actor permActor; + private final Actor cuiActor; + private final World world; + + public PlayerProxy(Player basePlayer, Actor permActor, Actor cuiActor, World world) { + Preconditions.checkNotNull(basePlayer); + Preconditions.checkNotNull(permActor); + Preconditions.checkNotNull(cuiActor); + Preconditions.checkNotNull(world); + this.basePlayer = basePlayer; + this.permActor = permActor; + this.cuiActor = cuiActor; + this.world = world; + } + + public UUID getUniqueId() { + return this.basePlayer.getUniqueId(); + } + + public int getItemInHand() { + return this.basePlayer.getItemInHand(); + } + + @Override + public BaseBlock getBlockInHand() throws WorldEditException { + return this.basePlayer.getBlockInHand(); + } + + public void giveItem(int type, int amount) { + this.basePlayer.giveItem(type, amount); + } + + public BlockBag getInventoryBlockBag() { + return this.basePlayer.getInventoryBlockBag(); + } + + public String getName() { + return this.basePlayer.getName(); + } + + public BaseEntity getState() { + throw new UnsupportedOperationException("Can\'t getState() on a player"); + } + + public Location getLocation() { + return this.basePlayer.getLocation(); + } + + public WorldVector getPosition() { + return this.basePlayer.getPosition(); + } + + public double getPitch() { + return this.basePlayer.getPitch(); + } + + public double getYaw() { + return this.basePlayer.getYaw(); + } + + public void setPosition(Vector pos, float pitch, float yaw) { + this.basePlayer.setPosition(pos, pitch, yaw); + } + + public World getWorld() { + return this.world; + } + + public void printRaw(String msg) { + this.basePlayer.printRaw(msg); + } + + public void printDebug(String msg) { + this.basePlayer.printDebug(msg); + } + + public void print(String msg) { + this.basePlayer.print(msg); + } + + public void printError(String msg) { + this.basePlayer.printError(msg); + } + + public String[] getGroups() { + return this.permActor.getGroups(); + } + + public boolean hasPermission(String perm) { + return this.permActor.hasPermission(perm); + } + + public void dispatchCUIEvent(CUIEvent event) { + this.cuiActor.dispatchCUIEvent(event); + } + + @Nullable + public T getFacet(Class cls) { + return this.basePlayer.getFacet(cls); + } + + public SessionKey getSessionKey() { + return this.basePlayer.getSessionKey(); + } + + public static Class inject() { + return PlayerProxy.class; + } +} diff --git a/forge110/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java b/forge110/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java index 597f7343..fd3267db 100644 --- a/forge110/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java +++ b/forge110/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java @@ -21,8 +21,10 @@ package com.sk89q.worldedit.forge; import com.boydti.fawe.forge.ForgePlayerBlockBag; import com.sk89q.util.StringUtil; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldVector; +import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extension.platform.AbstractPlayerActor; import com.sk89q.worldedit.extent.inventory.BlockBag; @@ -30,7 +32,6 @@ import com.sk89q.worldedit.internal.LocalWorldAdapter; import com.sk89q.worldedit.internal.cui.CUIEvent; import com.sk89q.worldedit.session.SessionKey; import com.sk89q.worldedit.util.Location; - import io.netty.buffer.Unpooled; import java.util.UUID; import javax.annotation.Nullable; @@ -65,6 +66,12 @@ public class ForgePlayer extends AbstractPlayerActor { return is == null ? 0 : Item.getIdFromItem(is.getItem()); } + @Override + public BaseBlock getBlockInHand() { + ItemStack is = this.player.getHeldItem(EnumHand.MAIN_HAND); + return is == null ? EditSession.nullBlock : new BaseBlock(Item.getIdFromItem(is.getItem()), is.isItemStackDamageable() ? 0 : is.getItemDamage()); + } + @Override public String getName() { return this.player.getName(); diff --git a/forge111/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java b/forge111/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java index 2d214382..9a13da4d 100644 --- a/forge111/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java +++ b/forge111/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java @@ -21,8 +21,10 @@ package com.sk89q.worldedit.forge; import com.boydti.fawe.forge.ForgePlayerBlockBag; import com.sk89q.util.StringUtil; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldVector; +import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extension.platform.AbstractPlayerActor; import com.sk89q.worldedit.extent.inventory.BlockBag; @@ -30,7 +32,6 @@ import com.sk89q.worldedit.internal.LocalWorldAdapter; import com.sk89q.worldedit.internal.cui.CUIEvent; import com.sk89q.worldedit.session.SessionKey; import com.sk89q.worldedit.util.Location; - import io.netty.buffer.Unpooled; import java.util.UUID; import javax.annotation.Nullable; @@ -63,6 +64,12 @@ public class ForgePlayer extends AbstractPlayerActor { return is == null ? 0 : Item.getIdFromItem(is.getItem()); } + @Override + public BaseBlock getBlockInHand() { + ItemStack is = this.player.getHeldItem(EnumHand.MAIN_HAND); + return is == null ? EditSession.nullBlock : new BaseBlock(Item.getIdFromItem(is.getItem()), is.isItemStackDamageable() ? 0 : is.getItemDamage()); + } + @Override public String getName() { return this.player.getName(); diff --git a/forge1710/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java b/forge1710/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java index d2ae2890..67b2b91d 100644 --- a/forge1710/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java +++ b/forge1710/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java @@ -21,8 +21,10 @@ package com.sk89q.worldedit.forge; import com.boydti.fawe.forge.ForgePlayerBlockBag; import com.sk89q.util.StringUtil; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldVector; +import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extension.platform.AbstractPlayerActor; import com.sk89q.worldedit.extent.inventory.BlockBag; @@ -30,17 +32,14 @@ import com.sk89q.worldedit.internal.LocalWorldAdapter; import com.sk89q.worldedit.internal.cui.CUIEvent; import com.sk89q.worldedit.session.SessionKey; import com.sk89q.worldedit.util.Location; - +import java.util.UUID; +import javax.annotation.Nullable; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.network.play.server.S3FPacketCustomPayload; import net.minecraft.util.ChatComponentText; -import javax.annotation.Nullable; - -import java.util.UUID; - public class ForgePlayer extends AbstractPlayerActor { private final ForgePlatform platform; @@ -63,6 +62,13 @@ public class ForgePlayer extends AbstractPlayerActor { return is == null ? 0 : Item.getIdFromItem(is.getItem()); } + @Override + public BaseBlock getBlockInHand() { + ItemStack is = this.player.getCurrentEquippedItem(); + return is == null ? EditSession.nullBlock : new BaseBlock(Item.getIdFromItem(is.getItem()), is.isItemStackDamageable() ? 0 : is.getItemDamage()); + } + + @Override public String getName() { return this.player.getCommandSenderName(); diff --git a/forge189/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java b/forge189/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java index ee00a4f4..f299f14c 100644 --- a/forge189/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java +++ b/forge189/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java @@ -21,8 +21,10 @@ package com.sk89q.worldedit.forge; import com.boydti.fawe.forge.ForgePlayerBlockBag; import com.sk89q.util.StringUtil; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldVector; +import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extension.platform.AbstractPlayerActor; import com.sk89q.worldedit.extent.inventory.BlockBag; @@ -30,20 +32,17 @@ import com.sk89q.worldedit.internal.LocalWorldAdapter; import com.sk89q.worldedit.internal.cui.CUIEvent; import com.sk89q.worldedit.session.SessionKey; import com.sk89q.worldedit.util.Location; - +import io.netty.buffer.Unpooled; +import java.util.UUID; +import javax.annotation.Nullable; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import net.minecraft.network.play.server.S3FPacketCustomPayload; import net.minecraft.util.ChatComponentText; -import io.netty.buffer.Unpooled; import net.minecraft.util.EnumChatFormatting; -import javax.annotation.Nullable; - -import java.util.UUID; - public class ForgePlayer extends AbstractPlayerActor { private final ForgePlatform platform; @@ -66,6 +65,12 @@ public class ForgePlayer extends AbstractPlayerActor { return is == null ? 0 : Item.getIdFromItem(is.getItem()); } + @Override + public BaseBlock getBlockInHand() { + ItemStack is = this.player.getCurrentEquippedItem(); + return is == null ? EditSession.nullBlock : new BaseBlock(Item.getIdFromItem(is.getItem()), is.isItemStackDamageable() ? 0 : is.getItemDamage()); + } + @Override public String getName() { return this.player.getName(); diff --git a/forge194/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java b/forge194/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java index 597f7343..5d648286 100644 --- a/forge194/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java +++ b/forge194/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java @@ -19,10 +19,13 @@ package com.sk89q.worldedit.forge; +import com.boydti.fawe.FaweCache; import com.boydti.fawe.forge.ForgePlayerBlockBag; import com.sk89q.util.StringUtil; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldVector; +import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extension.platform.AbstractPlayerActor; import com.sk89q.worldedit.extent.inventory.BlockBag; @@ -65,6 +68,13 @@ public class ForgePlayer extends AbstractPlayerActor { return is == null ? 0 : Item.getIdFromItem(is.getItem()); } + @Override + public BaseBlock getBlockInHand() { + ItemStack is = this.player.getHeldItem(EnumHand.MAIN_HAND); + return is == null ? EditSession.nullBlock : new BaseBlock(Item.getIdFromItem(is.getItem()), is.isItemStackDamageable() ? 0 : is.getItemDamage()); + } + + @Override public String getName() { return this.player.getName(); diff --git a/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitPlayer.java b/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitPlayer.java index 6a1a12fb..ee62603b 100644 --- a/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitPlayer.java +++ b/nukkit/src/main/java/com/boydti/fawe/nukkit/core/NukkitPlayer.java @@ -23,6 +23,7 @@ import cn.nukkit.Player; import cn.nukkit.inventory.PlayerInventory; import cn.nukkit.item.Item; import cn.nukkit.level.Location; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; @@ -63,9 +64,9 @@ public class NukkitPlayer extends LocalPlayer { PlayerInventory inv = player.getInventory(); Item itemStack = inv.getItemInHand(); if (itemStack == null) { - return new BaseBlock(0, 0); + return EditSession.nullBlock; } - return new BaseBlock(itemStack.getId(), itemStack.getDamage()); + return new BaseBlock(itemStack.getId(), itemStack.getMaxDurability() != 0 ? 0 : itemStack.getDamage()); } @Override diff --git a/sponge/src/main/java/com/boydti/fawe/sponge/FaweSponge.java b/sponge/src/main/java/com/boydti/fawe/sponge/FaweSponge.java index c03546a2..51ca18cf 100644 --- a/sponge/src/main/java/com/boydti/fawe/sponge/FaweSponge.java +++ b/sponge/src/main/java/com/boydti/fawe/sponge/FaweSponge.java @@ -36,6 +36,7 @@ public class FaweSponge implements IFawe { try { Fawe.set(this); Fawe.setupInjector(); + com.sk89q.worldedit.sponge.SpongePlayer.inject(); } catch (final Throwable e) { MainUtil.handleError(e); } diff --git a/sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java b/sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java new file mode 100644 index 00000000..6edc0edb --- /dev/null +++ b/sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java @@ -0,0 +1,233 @@ +/* + * 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.sponge; + +import com.flowpowered.math.vector.Vector3d; +import com.sk89q.util.StringUtil; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.WorldVector; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.extension.platform.AbstractPlayerActor; +import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.internal.LocalWorldAdapter; +import com.sk89q.worldedit.internal.cui.CUIEvent; +import com.sk89q.worldedit.session.SessionKey; +import com.sk89q.worldedit.util.Location; +import org.spongepowered.api.data.type.HandTypes; +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.item.inventory.ItemStack; +import org.spongepowered.api.text.Text; +import org.spongepowered.api.text.format.TextColor; +import org.spongepowered.api.text.format.TextColors; +import org.spongepowered.api.text.serializer.TextSerializers; +import org.spongepowered.api.world.World; + +import javax.annotation.Nullable; +import java.nio.charset.StandardCharsets; +import java.util.Optional; +import java.util.UUID; + +public class SpongePlayer extends AbstractPlayerActor { + + private final Player player; + + public SpongePlayer(SpongePlatform platform, Player player) { + this.player = player; + ThreadSafeCache.getInstance().getOnlineIds().add(getUniqueId()); + } + + @Override + public UUID getUniqueId() { + return player.getUniqueId(); + } + + @Override + public int getItemInHand() { + Optional is = this.player.getItemInHand(HandTypes.MAIN_HAND); + return is.isPresent() ? SpongeWorldEdit.inst().getAdapter().resolve(is.get().getItem()) : 0; + } + + @Override + public BaseBlock getBlockInHand() throws WorldEditException { + return new BaseBlock(getItemInHand(), 0); + } + + @Override + public String getName() { + return this.player.getName(); + } + + @Override + public BaseEntity getState() { + throw new UnsupportedOperationException("Cannot create a state from this object"); + } + + @Override + public Location getLocation() { + org.spongepowered.api.world.Location entityLoc = this.player.getLocation(); + Vector3d entityRot = this.player.getRotation(); + + return SpongeWorldEdit.inst().getAdapter().adapt(entityLoc, entityRot); + } + + @Override + public WorldVector getPosition() { + Vector3d pos = this.player.getLocation().getPosition(); + return new WorldVector(LocalWorldAdapter.adapt(SpongeWorldEdit.inst().getAdapter().getWorld(this.player.getWorld())), pos.getX(), pos.getY(), pos.getZ()); + } + + @Override + public com.sk89q.worldedit.world.World getWorld() { + return SpongeWorldEdit.inst().getAdapter().getWorld(player.getWorld()); + } + + @Override + public double getPitch() { + return getLocation().getPitch(); + } + + @Override + public double getYaw() { + return getLocation().getYaw(); + } + + @Override + public void giveItem(int type, int amt) { + this.player.getInventory().offer(ItemStack.of(SpongeWorldEdit.inst().getAdapter().resolveItem(type), amt)); + } + + @Override + public void dispatchCUIEvent(CUIEvent event) { + String[] params = event.getParameters(); + String send = event.getTypeId(); + if (params.length > 0) { + send = send + "|" + StringUtil.joinString(params, "|"); + } + + String finalData = send; + CUIChannelHandler.getActiveChannel().sendTo(player, buffer -> buffer.writeBytes(finalData.getBytes(StandardCharsets.UTF_8))); + } + + @Override + public void printRaw(String msg) { + for (String part : msg.split("\n")) { + this.player.sendMessage(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(part)); + } + } + + @Override + public void printDebug(String msg) { + sendColorized(msg, TextColors.GRAY); + } + + @Override + public void print(String msg) { + sendColorized(msg, TextColors.LIGHT_PURPLE); + } + + @Override + public void printError(String msg) { + sendColorized(msg, TextColors.RED); + } + + private void sendColorized(String msg, TextColor formatting) { + for (String part : msg.split("\n")) { + this.player.sendMessage(Text.of(formatting, TextSerializers.LEGACY_FORMATTING_CODE.deserialize(part))); + } + } + + @Override + public void setPosition(Vector pos, float pitch, float yaw) { + org.spongepowered.api.world.Location loc = new org.spongepowered.api.world.Location<>( + this.player.getWorld(), pos.getX(), pos.getY(), pos.getZ() + ); + + this.player.setLocationAndRotation(loc, new Vector3d(pitch, yaw, 0)); + } + + @Override + public String[] getGroups() { + return SpongeWorldEdit.inst().getPermissionsProvider().getGroups(this.player); + } + + @Override + public BlockBag getInventoryBlockBag() { + return null; + } + + @Override + public boolean hasPermission(String perm) { + return SpongeWorldEdit.inst().getPermissionsProvider().hasPermission(player, perm); + } + + @Nullable + @Override + public T getFacet(Class cls) { + return null; + } + + @Override + public SessionKey getSessionKey() { + return new SessionKeyImpl(player.getUniqueId(), player.getName()); + } + + private static class SessionKeyImpl implements SessionKey { + // If not static, this will leak a reference + + private final UUID uuid; + private final String name; + + private SessionKeyImpl(UUID uuid, String name) { + this.uuid = uuid; + this.name = name; + } + + @Override + public UUID getUniqueId() { + return uuid; + } + + @Nullable + @Override + public String getName() { + return name; + } + + @Override + public boolean isActive() { + // We can't directly check if the player is online because + // the list of players is not thread safe + return ThreadSafeCache.getInstance().getOnlineIds().contains(uuid); + } + + @Override + public boolean isPersistent() { + return true; + } + + } + + public static Class inject() { + return SpongePlayer.class; + } + +} \ No newline at end of file