geforkt von Mirrors/FastAsyncWorldEdit
Merge pull request #420 from sk89q/server-side-cui
Added a server side version of WorldEditCUI with limited functionality
Dieser Commit ist enthalten in:
Commit
d3b3d57041
@ -22,6 +22,7 @@ package com.sk89q.worldedit.bukkit;
|
|||||||
import com.sk89q.util.StringUtil;
|
import com.sk89q.util.StringUtil;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
@ -31,6 +32,8 @@ import com.sk89q.worldedit.internal.cui.CUIEvent;
|
|||||||
import com.sk89q.worldedit.session.SessionKey;
|
import com.sk89q.worldedit.session.SessionKey;
|
||||||
import com.sk89q.worldedit.util.HandSide;
|
import com.sk89q.worldedit.util.HandSide;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
import com.sk89q.worldedit.world.gamemode.GameMode;
|
import com.sk89q.worldedit.world.gamemode.GameMode;
|
||||||
import com.sk89q.worldedit.world.gamemode.GameModes;
|
import com.sk89q.worldedit.world.gamemode.GameModes;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -239,4 +242,22 @@ public class BukkitPlayer extends AbstractPlayerActor {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendFakeBlock(Vector pos, BlockStateHolder block) {
|
||||||
|
Location loc = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
if (block == null) {
|
||||||
|
player.sendBlockChange(loc, player.getWorld().getBlockAt(loc).getBlockData());
|
||||||
|
} else {
|
||||||
|
player.sendBlockChange(loc, BukkitAdapter.adapt(block));
|
||||||
|
if (block instanceof BaseBlock && ((BaseBlock) block).hasNbtData()) {
|
||||||
|
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
||||||
|
if (adapter != null) {
|
||||||
|
adapter.sendFakeNBT(player, pos, ((BaseBlock) block).getNbtData());
|
||||||
|
if (block.getBlockType() == BlockTypes.STRUCTURE_BLOCK) {
|
||||||
|
adapter.sendFakeOP(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
|
|||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
WorldEdit worldEdit = WorldEdit.getInstance();
|
WorldEdit worldEdit = WorldEdit.getInstance();
|
||||||
worldEdit.getSessionManager().clear();
|
worldEdit.getSessionManager().unload();
|
||||||
worldEdit.getPlatformManager().unregister(server);
|
worldEdit.getPlatformManager().unregister(server);
|
||||||
if (config != null) {
|
if (config != null) {
|
||||||
config.unload();
|
config.unload();
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.bukkit.adapter;
|
package com.sk89q.worldedit.bukkit.adapter;
|
||||||
|
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
import com.sk89q.worldedit.registry.state.Property;
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
@ -27,6 +29,7 @@ import com.sk89q.worldedit.world.block.BlockType;
|
|||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -101,4 +104,21 @@ public interface BukkitImplAdapter {
|
|||||||
* @return The properties map
|
* @return The properties map
|
||||||
*/
|
*/
|
||||||
Map<String, ? extends Property> getProperties(BlockType blockType);
|
Map<String, ? extends Property> getProperties(BlockType blockType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the given NBT data to the player.
|
||||||
|
*
|
||||||
|
* @param player The player
|
||||||
|
* @param pos The position
|
||||||
|
* @param nbtData The NBT Data
|
||||||
|
*/
|
||||||
|
void sendFakeNBT(Player player, Vector pos, CompoundTag nbtData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the client think it has operator status.
|
||||||
|
* This does not give them any operator capabilities.
|
||||||
|
*
|
||||||
|
* @param player The player
|
||||||
|
*/
|
||||||
|
void sendFakeOP(Player player);
|
||||||
}
|
}
|
||||||
|
Binäre Datei nicht angezeigt.
@ -143,3 +143,4 @@ no-double-slash: false
|
|||||||
no-op-permissions: false
|
no-op-permissions: false
|
||||||
debug: false
|
debug: false
|
||||||
show-help-on-first-use: true
|
show-help-on-first-use: true
|
||||||
|
server-side-cui: true
|
@ -134,6 +134,7 @@ public abstract class LocalConfiguration {
|
|||||||
public int butcherDefaultRadius = -1;
|
public int butcherDefaultRadius = -1;
|
||||||
public int butcherMaxRadius = -1;
|
public int butcherMaxRadius = -1;
|
||||||
public boolean allowSymlinks = false;
|
public boolean allowSymlinks = false;
|
||||||
|
public boolean serverSideCUI = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the configuration.
|
* Load the configuration.
|
||||||
|
@ -25,6 +25,8 @@ import com.sk89q.jchronic.Chronic;
|
|||||||
import com.sk89q.jchronic.Options;
|
import com.sk89q.jchronic.Options;
|
||||||
import com.sk89q.jchronic.utils.Span;
|
import com.sk89q.jchronic.utils.Span;
|
||||||
import com.sk89q.jchronic.utils.Time;
|
import com.sk89q.jchronic.utils.Time;
|
||||||
|
import com.sk89q.jnbt.IntTag;
|
||||||
|
import com.sk89q.jnbt.Tag;
|
||||||
import com.sk89q.worldedit.command.tool.BlockTool;
|
import com.sk89q.worldedit.command.tool.BlockTool;
|
||||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||||
import com.sk89q.worldedit.command.tool.InvalidToolBindException;
|
import com.sk89q.worldedit.command.tool.InvalidToolBindException;
|
||||||
@ -37,6 +39,7 @@ import com.sk89q.worldedit.function.mask.Mask;
|
|||||||
import com.sk89q.worldedit.internal.cui.CUIEvent;
|
import com.sk89q.worldedit.internal.cui.CUIEvent;
|
||||||
import com.sk89q.worldedit.internal.cui.CUIRegion;
|
import com.sk89q.worldedit.internal.cui.CUIRegion;
|
||||||
import com.sk89q.worldedit.internal.cui.SelectionShapeEvent;
|
import com.sk89q.worldedit.internal.cui.SelectionShapeEvent;
|
||||||
|
import com.sk89q.worldedit.internal.cui.ServerCUIHandler;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.regions.RegionSelector;
|
import com.sk89q.worldedit.regions.RegionSelector;
|
||||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||||
@ -44,6 +47,7 @@ import com.sk89q.worldedit.regions.selector.RegionSelectorType;
|
|||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
import com.sk89q.worldedit.session.request.Request;
|
import com.sk89q.worldedit.session.request.Request;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.item.ItemType;
|
import com.sk89q.worldedit.world.item.ItemType;
|
||||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||||
import com.sk89q.worldedit.world.snapshot.Snapshot;
|
import com.sk89q.worldedit.world.snapshot.Snapshot;
|
||||||
@ -87,10 +91,12 @@ public class LocalSession {
|
|||||||
private transient boolean fastMode = false;
|
private transient boolean fastMode = false;
|
||||||
private transient Mask mask;
|
private transient Mask mask;
|
||||||
private transient TimeZone timezone = TimeZone.getDefault();
|
private transient TimeZone timezone = TimeZone.getDefault();
|
||||||
|
private transient Vector cuiTemporaryBlock;
|
||||||
|
|
||||||
// Saved properties
|
// Saved properties
|
||||||
private String lastScript;
|
private String lastScript;
|
||||||
private RegionSelectorType defaultSelector;
|
private RegionSelectorType defaultSelector;
|
||||||
|
private boolean useServerCUI = false; // Save this to not annoy players.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct the object.
|
* Construct the object.
|
||||||
@ -612,6 +618,59 @@ public class LocalSession {
|
|||||||
public void tellVersion(Actor player) {
|
public void tellVersion(Actor player) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean shouldUseServerCUI() {
|
||||||
|
return this.useServerCUI;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUseServerCUI(boolean useServerCUI) {
|
||||||
|
this.useServerCUI = useServerCUI;
|
||||||
|
setDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update server-side WorldEdit CUI.
|
||||||
|
*
|
||||||
|
* @param actor The player
|
||||||
|
*/
|
||||||
|
public void updateServerCUI(Actor actor) {
|
||||||
|
if (!actor.isPlayer()) {
|
||||||
|
return; // This is for players only.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config.serverSideCUI) {
|
||||||
|
return; // Disabled in config.
|
||||||
|
}
|
||||||
|
|
||||||
|
Player player = (Player) actor;
|
||||||
|
|
||||||
|
if (!useServerCUI || hasCUISupport) {
|
||||||
|
if (cuiTemporaryBlock != null) {
|
||||||
|
player.sendFakeBlock(cuiTemporaryBlock, null);
|
||||||
|
cuiTemporaryBlock = null;
|
||||||
|
}
|
||||||
|
return; // If it's not enabled, ignore this.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the old block.
|
||||||
|
if (cuiTemporaryBlock != null) {
|
||||||
|
player.sendFakeBlock(cuiTemporaryBlock, null);
|
||||||
|
cuiTemporaryBlock = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseBlock block = ServerCUIHandler.createStructureBlock(player);
|
||||||
|
if (block != null) {
|
||||||
|
// If it's null, we don't need to do anything. The old was already removed.
|
||||||
|
Map<String, Tag> tags = block.getNbtData().getValue();
|
||||||
|
cuiTemporaryBlock = new Vector(
|
||||||
|
((IntTag) tags.get("x")).getValue(),
|
||||||
|
((IntTag) tags.get("y")).getValue(),
|
||||||
|
((IntTag) tags.get("z")).getValue()
|
||||||
|
);
|
||||||
|
|
||||||
|
player.sendFakeBlock(cuiTemporaryBlock, block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatch a CUI event but only if the actor has CUI support.
|
* Dispatch a CUI event but only if the actor has CUI support.
|
||||||
*
|
*
|
||||||
@ -624,6 +683,8 @@ public class LocalSession {
|
|||||||
|
|
||||||
if (hasCUISupport) {
|
if (hasCUISupport) {
|
||||||
actor.dispatchCUIEvent(event);
|
actor.dispatchCUIEvent(event);
|
||||||
|
} else if (useServerCUI) {
|
||||||
|
updateServerCUI(actor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -647,6 +708,9 @@ public class LocalSession {
|
|||||||
checkNotNull(actor);
|
checkNotNull(actor);
|
||||||
|
|
||||||
if (!hasCUISupport) {
|
if (!hasCUISupport) {
|
||||||
|
if (useServerCUI) {
|
||||||
|
updateServerCUI(actor);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ import com.sk89q.worldedit.LocalSession;
|
|||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.entity.Player;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
|
import com.sk89q.worldedit.extension.input.DisallowedUsageException;
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||||
@ -114,6 +115,41 @@ public class GeneralCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Command(
|
||||||
|
aliases = { "/drawsel" },
|
||||||
|
usage = "[on|off]",
|
||||||
|
desc = "Toggle drawing the current selection",
|
||||||
|
min = 0,
|
||||||
|
max = 1
|
||||||
|
)
|
||||||
|
@CommandPermissions("worldedit.drawsel")
|
||||||
|
public void drawSelection(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||||
|
|
||||||
|
if (!WorldEdit.getInstance().getConfiguration().serverSideCUI) {
|
||||||
|
throw new DisallowedUsageException("This functionality is disabled in the configuration!");
|
||||||
|
}
|
||||||
|
String newState = args.getString(0, null);
|
||||||
|
if (session.shouldUseServerCUI()) {
|
||||||
|
if ("on".equals(newState)) {
|
||||||
|
player.printError("Server CUI already enabled.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
session.setUseServerCUI(false);
|
||||||
|
session.updateServerCUI(player);
|
||||||
|
player.print("Server CUI disabled.");
|
||||||
|
} else {
|
||||||
|
if ("off".equals(newState)) {
|
||||||
|
player.printError("Server CUI already disabled.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
session.setUseServerCUI(true);
|
||||||
|
session.updateServerCUI(player);
|
||||||
|
player.print("Server CUI enabled. This only supports cuboid regions, with a maximum size of 32x32x32.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "/gmask", "gmask" },
|
aliases = { "/gmask", "gmask" },
|
||||||
usage = "[mask]",
|
usage = "[mask]",
|
||||||
|
@ -29,8 +29,11 @@ import com.sk89q.worldedit.extent.inventory.BlockBag;
|
|||||||
import com.sk89q.worldedit.util.HandSide;
|
import com.sk89q.worldedit.util.HandSide;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import com.sk89q.worldedit.world.gamemode.GameMode;
|
import com.sk89q.worldedit.world.gamemode.GameMode;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a player
|
* Represents a player
|
||||||
*/
|
*/
|
||||||
@ -262,4 +265,15 @@ public interface Player extends Entity, Actor {
|
|||||||
*/
|
*/
|
||||||
void setPosition(Vector pos);
|
void setPosition(Vector pos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a fake block to the client.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This block isn't real.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param pos The position of the block
|
||||||
|
* @param block The block to send, null to reset
|
||||||
|
*/
|
||||||
|
void sendFakeBlock(Vector pos, @Nullable BlockStateHolder block);
|
||||||
}
|
}
|
||||||
|
@ -498,4 +498,8 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendFakeBlock(Vector pos, BlockStateHolder block) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import com.sk89q.worldedit.session.SessionKey;
|
|||||||
import com.sk89q.worldedit.util.HandSide;
|
import com.sk89q.worldedit.util.HandSide;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import com.sk89q.worldedit.world.gamemode.GameMode;
|
import com.sk89q.worldedit.world.gamemode.GameMode;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -155,4 +156,9 @@ class PlayerProxy extends AbstractPlayerActor {
|
|||||||
public void setGameMode(GameMode gameMode) {
|
public void setGameMode(GameMode gameMode) {
|
||||||
basePlayer.setGameMode(gameMode);
|
basePlayer.setGameMode(gameMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendFakeBlock(Vector pos, BlockStateHolder block) {
|
||||||
|
basePlayer.sendFakeBlock(pos, block);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* WorldEdit, a Minecraft world manipulation toolkit
|
||||||
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (C) WorldEdit team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.internal.cui;
|
||||||
|
|
||||||
|
import com.sk89q.jnbt.ByteTag;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.jnbt.IntTag;
|
||||||
|
import com.sk89q.jnbt.StringTag;
|
||||||
|
import com.sk89q.jnbt.Tag;
|
||||||
|
import com.sk89q.worldedit.IncompleteRegionException;
|
||||||
|
import com.sk89q.worldedit.LocalSession;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
|
import com.sk89q.worldedit.entity.Player;
|
||||||
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
|
import com.sk89q.worldedit.regions.RegionSelector;
|
||||||
|
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles creation of server-side CUI systems.
|
||||||
|
*/
|
||||||
|
public class ServerCUIHandler {
|
||||||
|
|
||||||
|
private ServerCUIHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a structure block that shows the region.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Null symbolises removal of the CUI.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param player The player to create the structure block for.
|
||||||
|
* @return The structure block, or null
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static BaseBlock createStructureBlock(Player player) {
|
||||||
|
LocalSession session = WorldEdit.getInstance().getSessionManager().get(player);
|
||||||
|
RegionSelector regionSelector = session.getRegionSelector(player.getWorld());
|
||||||
|
|
||||||
|
int posX, posY, posZ;
|
||||||
|
int width, height, length;
|
||||||
|
|
||||||
|
if (regionSelector instanceof CuboidRegionSelector) {
|
||||||
|
if (regionSelector.isDefined()) {
|
||||||
|
try {
|
||||||
|
CuboidRegion region = ((CuboidRegionSelector) regionSelector).getRegion();
|
||||||
|
|
||||||
|
posX = region.getMinimumPoint().getBlockX();
|
||||||
|
posY = region.getMinimumPoint().getBlockY();
|
||||||
|
posZ = region.getMinimumPoint().getBlockZ();
|
||||||
|
|
||||||
|
width = region.getWidth();
|
||||||
|
height = region.getHeight();
|
||||||
|
length = region.getLength();
|
||||||
|
} catch (IncompleteRegionException e) {
|
||||||
|
// This will never happen.
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CuboidRegion region = ((CuboidRegionSelector) regionSelector).getIncompleteRegion();
|
||||||
|
Vector point;
|
||||||
|
if (region.getPos1() != null) {
|
||||||
|
point = region.getPos1();
|
||||||
|
} else if (region.getPos2() != null) {
|
||||||
|
point = region.getPos2();
|
||||||
|
} else {
|
||||||
|
// No more selection
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just select the point.
|
||||||
|
posX = point.getBlockX();
|
||||||
|
posY = point.getBlockY();
|
||||||
|
posZ = point.getBlockZ();
|
||||||
|
width = 1;
|
||||||
|
height = 1;
|
||||||
|
length = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We only support cuboid regions right now.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width > 32 || length > 32 || height > 32) {
|
||||||
|
// Structure blocks have a limit of 32x32x32
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Borrowed this math from FAWE
|
||||||
|
double rotX = player.getLocation().getYaw();
|
||||||
|
double rotY = player.getLocation().getPitch();
|
||||||
|
double xz = Math.cos(Math.toRadians(rotY));
|
||||||
|
int x = (int) (player.getLocation().getX() - (-xz * Math.sin(Math.toRadians(rotX))) * 12);
|
||||||
|
int z = (int) (player.getLocation().getZ() - (xz * Math.cos(Math.toRadians(rotX))) * 12);
|
||||||
|
int y = Math.max(0, Math.min(Math.min(255, posY + 32), posY + 3));
|
||||||
|
|
||||||
|
Map<String, Tag> structureTag = new HashMap<>();
|
||||||
|
|
||||||
|
posX -= x;
|
||||||
|
posY -= y;
|
||||||
|
posZ -= z;
|
||||||
|
|
||||||
|
if (Math.abs(posX) > 32 || Math.abs(posY) > 32 || Math.abs(posZ) > 32) {
|
||||||
|
// Structure blocks have a limit
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
structureTag.put("name", new StringTag("worldedit:" + player.getName()));
|
||||||
|
structureTag.put("author", new StringTag(player.getName()));
|
||||||
|
structureTag.put("metadata", new StringTag(""));
|
||||||
|
structureTag.put("x", new IntTag(x));
|
||||||
|
structureTag.put("y", new IntTag(y));
|
||||||
|
structureTag.put("z", new IntTag(z));
|
||||||
|
structureTag.put("posX", new IntTag(posX));
|
||||||
|
structureTag.put("posY", new IntTag(posY));
|
||||||
|
structureTag.put("posZ", new IntTag(posZ));
|
||||||
|
structureTag.put("sizeX", new IntTag(width));
|
||||||
|
structureTag.put("sizeY", new IntTag(height));
|
||||||
|
structureTag.put("sizeZ", new IntTag(length));
|
||||||
|
structureTag.put("rotation", new StringTag("NONE"));
|
||||||
|
structureTag.put("mirror", new StringTag("NONE"));
|
||||||
|
structureTag.put("mode", new StringTag("SAVE"));
|
||||||
|
structureTag.put("ignoreEntities", new ByteTag((byte) 1));
|
||||||
|
structureTag.put("showboundingbox", new ByteTag((byte) 1));
|
||||||
|
structureTag.put("id", new StringTag(BlockTypes.STRUCTURE_BLOCK.getId()));
|
||||||
|
|
||||||
|
return BlockTypes.STRUCTURE_BLOCK.getDefaultState().toBaseBlock(new CompoundTag(structureTag));
|
||||||
|
}
|
||||||
|
}
|
@ -266,13 +266,50 @@ public class SessionManager {
|
|||||||
sessions.remove(getKey(owner));
|
sessions.remove(getKey(owner));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to unload this session manager.
|
||||||
|
*/
|
||||||
|
public synchronized void unload() {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all sessions.
|
* Remove all sessions.
|
||||||
*/
|
*/
|
||||||
public synchronized void clear() {
|
public synchronized void clear() {
|
||||||
|
saveChangedSessions();
|
||||||
sessions.clear();
|
sessions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized void saveChangedSessions() {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
Iterator<SessionHolder> it = sessions.values().iterator();
|
||||||
|
Map<SessionKey, LocalSession> saveQueue = new HashMap<>();
|
||||||
|
|
||||||
|
while (it.hasNext()) {
|
||||||
|
SessionHolder stored = it.next();
|
||||||
|
if (stored.key.isActive()) {
|
||||||
|
stored.lastActive = now;
|
||||||
|
|
||||||
|
if (stored.session.compareAndResetDirty()) {
|
||||||
|
saveQueue.put(stored.key, stored.session);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (now - stored.lastActive > EXPIRATION_GRACE) {
|
||||||
|
if (stored.session.compareAndResetDirty()) {
|
||||||
|
saveQueue.put(stored.key, stored.session);
|
||||||
|
}
|
||||||
|
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!saveQueue.isEmpty()) {
|
||||||
|
commit(saveQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onConfigurationLoad(ConfigurationLoadEvent event) {
|
public void onConfigurationLoad(ConfigurationLoadEvent event) {
|
||||||
LocalConfiguration config = event.getConfiguration();
|
LocalConfiguration config = event.getConfiguration();
|
||||||
@ -302,32 +339,7 @@ public class SessionManager {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
synchronized (SessionManager.this) {
|
synchronized (SessionManager.this) {
|
||||||
long now = System.currentTimeMillis();
|
saveChangedSessions();
|
||||||
Iterator<SessionHolder> it = sessions.values().iterator();
|
|
||||||
Map<SessionKey, LocalSession> saveQueue = new HashMap<>();
|
|
||||||
|
|
||||||
while (it.hasNext()) {
|
|
||||||
SessionHolder stored = it.next();
|
|
||||||
if (stored.key.isActive()) {
|
|
||||||
stored.lastActive = now;
|
|
||||||
|
|
||||||
if (stored.session.compareAndResetDirty()) {
|
|
||||||
saveQueue.put(stored.key, stored.session);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (now - stored.lastActive > EXPIRATION_GRACE) {
|
|
||||||
if (stored.session.compareAndResetDirty()) {
|
|
||||||
saveQueue.put(stored.key, stored.session);
|
|
||||||
}
|
|
||||||
|
|
||||||
it.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!saveQueue.isEmpty()) {
|
|
||||||
commit(saveQueue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,7 @@ public class PropertiesConfiguration extends LocalConfiguration {
|
|||||||
butcherDefaultRadius = getInt("butcher-default-radius", butcherDefaultRadius);
|
butcherDefaultRadius = getInt("butcher-default-radius", butcherDefaultRadius);
|
||||||
butcherMaxRadius = getInt("butcher-max-radius", butcherMaxRadius);
|
butcherMaxRadius = getInt("butcher-max-radius", butcherMaxRadius);
|
||||||
allowSymlinks = getBool("allow-symbolic-links", allowSymlinks);
|
allowSymlinks = getBool("allow-symbolic-links", allowSymlinks);
|
||||||
|
serverSideCUI = getBool("server-side-cui", serverSideCUI);
|
||||||
|
|
||||||
LocalSession.MAX_HISTORY_SIZE = Math.max(15, getInt("history-size", 15));
|
LocalSession.MAX_HISTORY_SIZE = Math.max(15, getInt("history-size", 15));
|
||||||
|
|
||||||
|
@ -112,6 +112,7 @@ public class YAMLConfiguration extends LocalConfiguration {
|
|||||||
SessionManager.EXPIRATION_GRACE = config.getInt("history.expiration", 10) * 60 * 1000;
|
SessionManager.EXPIRATION_GRACE = config.getInt("history.expiration", 10) * 60 * 1000;
|
||||||
|
|
||||||
showHelpInfo = config.getBoolean("show-help-on-first-use", true);
|
showHelpInfo = config.getBoolean("show-help-on-first-use", true);
|
||||||
|
serverSideCUI = config.getBoolean("server-side-cui", true);
|
||||||
|
|
||||||
String snapshotsDir = config.getString("snapshots.directory", "");
|
String snapshotsDir = config.getString("snapshots.directory", "");
|
||||||
if (!snapshotsDir.isEmpty()) {
|
if (!snapshotsDir.isEmpty()) {
|
||||||
|
@ -29,6 +29,8 @@ import com.sk89q.worldedit.internal.cui.CUIEvent;
|
|||||||
import com.sk89q.worldedit.session.SessionKey;
|
import com.sk89q.worldedit.session.SessionKey;
|
||||||
import com.sk89q.worldedit.util.HandSide;
|
import com.sk89q.worldedit.util.HandSide;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
@ -36,7 +38,9 @@ import net.minecraft.item.Item;
|
|||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraft.network.play.server.SPacketCustomPayload;
|
import net.minecraft.network.play.server.SPacketCustomPayload;
|
||||||
|
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.text.TextComponentString;
|
import net.minecraft.util.text.TextComponentString;
|
||||||
import net.minecraft.util.text.TextFormatting;
|
import net.minecraft.util.text.TextFormatting;
|
||||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||||
@ -164,6 +168,24 @@ public class ForgePlayer extends AbstractPlayerActor {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendFakeBlock(Vector pos, BlockStateHolder block) {
|
||||||
|
BlockPos loc = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
|
||||||
|
if (block == null) {
|
||||||
|
// TODO
|
||||||
|
// player.sendBlockChange(loc, player.getWorld().getBlockAt(loc).getBlockData());
|
||||||
|
} else {
|
||||||
|
// TODO
|
||||||
|
// player.sendBlockChange(loc, BukkitAdapter.adapt(block));
|
||||||
|
if (block instanceof BaseBlock && ((BaseBlock) block).hasNbtData()) {
|
||||||
|
player.connection.sendPacket(new SPacketUpdateTileEntity(
|
||||||
|
new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()), 7,
|
||||||
|
NBTConverter.toNative(((BaseBlock) block).getNbtData()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SessionKey getSessionKey() {
|
public SessionKey getSessionKey() {
|
||||||
return new SessionKeyImpl(player.getUniqueID(), player.getName());
|
return new SessionKeyImpl(player.getUniqueID(), player.getName());
|
||||||
|
@ -136,7 +136,9 @@ public class ForgeWorldEdit {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void serverStopping(FMLServerStoppingEvent event) {
|
public void serverStopping(FMLServerStoppingEvent event) {
|
||||||
WorldEdit.getInstance().getPlatformManager().unregister(platform);
|
WorldEdit worldEdit = WorldEdit.getInstance();
|
||||||
|
worldEdit.getSessionManager().unload();
|
||||||
|
worldEdit.getPlatformManager().unregister(platform);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
@ -30,6 +30,7 @@ import com.sk89q.worldedit.internal.cui.CUIEvent;
|
|||||||
import com.sk89q.worldedit.session.SessionKey;
|
import com.sk89q.worldedit.session.SessionKey;
|
||||||
import com.sk89q.worldedit.util.HandSide;
|
import com.sk89q.worldedit.util.HandSide;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import com.sk89q.worldedit.world.gamemode.GameMode;
|
import com.sk89q.worldedit.world.gamemode.GameMode;
|
||||||
import com.sk89q.worldedit.world.gamemode.GameModes;
|
import com.sk89q.worldedit.world.gamemode.GameModes;
|
||||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||||
@ -183,6 +184,23 @@ public class SpongePlayer extends AbstractPlayerActor {
|
|||||||
gameMode.getId()).get());
|
gameMode.getId()).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendFakeBlock(Vector pos, BlockStateHolder block) {
|
||||||
|
org.spongepowered.api.world.Location<World> loc = player.getWorld().getLocation(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
if (block == null) {
|
||||||
|
player.sendBlockChange(loc.getBlockPosition(), loc.getBlock());
|
||||||
|
} else {
|
||||||
|
// TODO
|
||||||
|
// player.sendBlockChange(loc, BukkitAdapter.adapt(block));
|
||||||
|
// if (block instanceof BaseBlock && ((BaseBlock) block).hasNbtData()) {
|
||||||
|
// BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
||||||
|
// if (adapter != null) {
|
||||||
|
// adapter.sendFakeNBT(player, pos, ((BaseBlock) block).getNbtData());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SessionKey getSessionKey() {
|
public SessionKey getSessionKey() {
|
||||||
return new SessionKeyImpl(player.getUniqueId(), player.getName());
|
return new SessionKeyImpl(player.getUniqueId(), player.getName());
|
||||||
|
@ -147,7 +147,9 @@ public class SpongeWorldEdit {
|
|||||||
|
|
||||||
@Listener
|
@Listener
|
||||||
public void serverStopping(GameStoppingServerEvent event) {
|
public void serverStopping(GameStoppingServerEvent event) {
|
||||||
WorldEdit.getInstance().getPlatformManager().unregister(platform);
|
WorldEdit worldEdit = WorldEdit.getInstance();
|
||||||
|
worldEdit.getSessionManager().unload();
|
||||||
|
worldEdit.getPlatformManager().unregister(platform);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listener
|
@Listener
|
||||||
|
@ -120,6 +120,7 @@ public class ConfigurateConfiguration extends LocalConfiguration {
|
|||||||
SessionManager.EXPIRATION_GRACE = node.getNode("history", "expiration").getInt(10) * 60 * 1000;
|
SessionManager.EXPIRATION_GRACE = node.getNode("history", "expiration").getInt(10) * 60 * 1000;
|
||||||
|
|
||||||
showHelpInfo = node.getNode("show-help-on-first-use").getBoolean(true);
|
showHelpInfo = node.getNode("show-help-on-first-use").getBoolean(true);
|
||||||
|
serverSideCUI = node.getNode("server-side-cui").getBoolean(true);
|
||||||
|
|
||||||
String snapshotsDir = node.getNode("snapshots", "directory").getString("");
|
String snapshotsDir = node.getNode("snapshots", "directory").getString("");
|
||||||
if (!snapshotsDir.isEmpty()) {
|
if (!snapshotsDir.isEmpty()) {
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren