mirror of
https://github.com/EngineHub/WorldEdit.git
synced 2025-04-12 14:40:42 +08:00
Add Console/CommandBlock support to Fabric/Forge/Sponge (#2317)
* Add Console/CommandBlock support to Fabric/Forge * Hoist config option and add a common abstract class for command block actors * Apply to Sponge too
This commit is contained in:
parent
bb15dbcbc9
commit
40a203c3d2
@ -20,11 +20,8 @@
|
||||
package com.sk89q.worldedit.bukkit;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractNonPlayerActor;
|
||||
import com.sk89q.worldedit.extension.platform.Locatable;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractCommandBlockActor;
|
||||
import com.sk89q.worldedit.session.SessionKey;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.auth.AuthorizationException;
|
||||
import com.sk89q.worldedit.util.formatting.WorldEditText;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
@ -42,22 +39,17 @@ import java.util.UUID;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class BukkitBlockCommandSender extends AbstractNonPlayerActor implements Locatable {
|
||||
|
||||
private static final String UUID_PREFIX = "CMD";
|
||||
|
||||
public class BukkitBlockCommandSender extends AbstractCommandBlockActor {
|
||||
private final BlockCommandSender sender;
|
||||
private final WorldEditPlugin plugin;
|
||||
private final Location location;
|
||||
private final UUID uuid;
|
||||
|
||||
public BukkitBlockCommandSender(WorldEditPlugin plugin, BlockCommandSender sender) {
|
||||
super(BukkitAdapter.adapt(checkNotNull(sender).getBlock().getLocation()));
|
||||
checkNotNull(plugin);
|
||||
checkNotNull(sender);
|
||||
|
||||
this.plugin = plugin;
|
||||
this.sender = sender;
|
||||
this.location = BukkitAdapter.adapt(sender.getBlock().getLocation());
|
||||
this.uuid = UUID.nameUUIDFromBytes((UUID_PREFIX + sender.getName()).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@ -108,21 +100,6 @@ public class BukkitBlockCommandSender extends AbstractNonPlayerActor implements
|
||||
return WorldEdit.getInstance().getConfiguration().defaultLocale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLocation(Location location) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Extent getExtent() {
|
||||
return this.location.getExtent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return uuid;
|
||||
|
@ -34,7 +34,6 @@ import java.nio.file.Path;
|
||||
public class BukkitConfiguration extends YAMLConfiguration {
|
||||
|
||||
public boolean noOpPermissions = false;
|
||||
public boolean commandBlockSupport = false;
|
||||
public boolean unsupportedVersionEditing = false;
|
||||
@Unreported private final WorldEditPlugin plugin;
|
||||
|
||||
@ -47,7 +46,6 @@ public class BukkitConfiguration extends YAMLConfiguration {
|
||||
public void load() {
|
||||
super.load();
|
||||
noOpPermissions = config.getBoolean("no-op-permissions", false);
|
||||
commandBlockSupport = config.getBoolean("command-block-support", false);
|
||||
unsupportedVersionEditing = "I accept that I will receive no support with this flag enabled.".equals(
|
||||
config.getString("allow-editing-on-unsupported-versions", "false"));
|
||||
if (unsupportedVersionEditing) {
|
||||
|
@ -91,6 +91,7 @@ public abstract class LocalConfiguration {
|
||||
public boolean allowSymlinks = false;
|
||||
public boolean serverSideCUI = true;
|
||||
public boolean extendedYLimit = false;
|
||||
public boolean commandBlockSupport = false;
|
||||
public String defaultLocaleName = "default";
|
||||
public Locale defaultLocale = Locale.getDefault();
|
||||
|
||||
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.extension.platform;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
|
||||
public abstract class AbstractCommandBlockActor extends AbstractNonPlayerActor implements Locatable {
|
||||
protected static final String UUID_PREFIX = "CMD";
|
||||
|
||||
private final Location location;
|
||||
|
||||
public AbstractCommandBlockActor(Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLocation(Location location) {
|
||||
// Can't move a CommandBlock
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Extent getExtent() {
|
||||
return this.location.getExtent();
|
||||
}
|
||||
}
|
@ -133,6 +133,7 @@ public class PropertiesConfiguration extends LocalConfiguration {
|
||||
serverSideCUI = getBool("server-side-cui", serverSideCUI);
|
||||
extendedYLimit = getBool("extended-y-limit", extendedYLimit);
|
||||
setDefaultLocaleName(getString("default-locale", defaultLocaleName));
|
||||
commandBlockSupport = getBool("command-block-support", commandBlockSupport);
|
||||
|
||||
LocalSession.MAX_HISTORY_SIZE = Math.max(15, getInt("history-size", 15));
|
||||
|
||||
|
@ -129,6 +129,8 @@ public class YAMLConfiguration extends LocalConfiguration {
|
||||
extendedYLimit = config.getBoolean("compat.extended-y-limit", false);
|
||||
|
||||
setDefaultLocaleName(config.getString("default-locale", defaultLocaleName));
|
||||
|
||||
commandBlockSupport = config.getBoolean("command-block-support", false);
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
|
@ -35,8 +35,6 @@ import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.internal.util.Substring;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import org.enginehub.piston.inject.InjectedValueStore;
|
||||
import org.enginehub.piston.inject.Key;
|
||||
import org.enginehub.piston.inject.MapBackedValueStore;
|
||||
@ -46,7 +44,7 @@ import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static com.sk89q.worldedit.fabric.FabricAdapter.adaptPlayer;
|
||||
import static com.sk89q.worldedit.fabric.FabricAdapter.adaptCommandSource;
|
||||
import static net.minecraft.commands.Commands.argument;
|
||||
import static net.minecraft.commands.Commands.literal;
|
||||
|
||||
@ -62,7 +60,7 @@ public final class CommandWrapper {
|
||||
|
||||
Command<CommandSourceStack> commandRunner = ctx -> {
|
||||
WorldEdit.getInstance().getEventBus().post(new com.sk89q.worldedit.event.platform.CommandEvent(
|
||||
adaptPlayer(ctx.getSource().getPlayerOrException()),
|
||||
adaptCommandSource(ctx.getSource()),
|
||||
"/" + ctx.getInput()
|
||||
));
|
||||
return 0;
|
||||
@ -82,12 +80,8 @@ public final class CommandWrapper {
|
||||
|
||||
private static Predicate<CommandSourceStack> requirementsFor(org.enginehub.piston.Command mapping) {
|
||||
return ctx -> {
|
||||
final Entity entity = ctx.getEntity();
|
||||
if (!(entity instanceof ServerPlayer)) {
|
||||
return true;
|
||||
}
|
||||
final Actor actor = FabricAdapter.adaptPlayer(((ServerPlayer) entity));
|
||||
InjectedValueStore store = MapBackedValueStore.create();
|
||||
final Actor actor = FabricAdapter.adaptCommandSource(ctx);
|
||||
store.injectValue(Key.of(Actor.class), context -> Optional.of(actor));
|
||||
return mapping.getCondition().satisfied(store);
|
||||
};
|
||||
@ -96,7 +90,7 @@ public final class CommandWrapper {
|
||||
private static CompletableFuture<Suggestions> suggest(CommandContext<CommandSourceStack> context,
|
||||
SuggestionsBuilder builder) throws CommandSyntaxException {
|
||||
CommandSuggestionEvent event = new CommandSuggestionEvent(
|
||||
FabricAdapter.adaptPlayer(context.getSource().getPlayerOrException()),
|
||||
FabricAdapter.adaptCommandSource(context.getSource()),
|
||||
builder.getInput()
|
||||
);
|
||||
WorldEdit.getInstance().getEventBus().post(event);
|
||||
|
@ -22,6 +22,7 @@ package com.sk89q.worldedit.fabric;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.fabric.internal.FabricTransmogrifier;
|
||||
import com.sk89q.worldedit.fabric.internal.NBTConverter;
|
||||
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
||||
@ -37,15 +38,15 @@ import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.StringRepresentable;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BaseCommandBlock;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
@ -248,4 +249,22 @@ public final class FabricAdapter {
|
||||
checkNotNull(player);
|
||||
return new FabricPlayer(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the WorldEdit proxy for the given command source.
|
||||
*
|
||||
* @param commandSourceStack the command source
|
||||
* @return the WorldEdit actor
|
||||
*/
|
||||
public static Actor adaptCommandSource(CommandSourceStack commandSourceStack) {
|
||||
checkNotNull(commandSourceStack);
|
||||
if (commandSourceStack.isPlayer()) {
|
||||
return adaptPlayer(commandSourceStack.getPlayer());
|
||||
}
|
||||
if (FabricWorldEdit.inst.getConfig().commandBlockSupport && commandSourceStack.source instanceof BaseCommandBlock commandBlock) {
|
||||
return new FabricBlockCommandSender(commandBlock);
|
||||
}
|
||||
|
||||
return new FabricCommandSender(commandSourceStack);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* 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 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.fabric;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractCommandBlockActor;
|
||||
import com.sk89q.worldedit.session.SessionKey;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.auth.AuthorizationException;
|
||||
import com.sk89q.worldedit.util.formatting.WorldEditText;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.world.level.BaseCommandBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class FabricBlockCommandSender extends AbstractCommandBlockActor {
|
||||
private final BaseCommandBlock sender;
|
||||
private final UUID uuid;
|
||||
|
||||
public FabricBlockCommandSender(BaseCommandBlock sender) {
|
||||
super(new Location(FabricAdapter.adapt(checkNotNull(sender).getLevel()), FabricAdapter.adapt(sender.getPosition())));
|
||||
|
||||
this.sender = sender;
|
||||
this.uuid = UUID.nameUUIDFromBytes((UUID_PREFIX + sender.getName()).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return sender.getName().getString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printRaw(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
sendMessage(net.minecraft.network.chat.Component.literal(part));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printDebug(String msg) {
|
||||
sendColorized(msg, ChatFormatting.GRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void print(String msg) {
|
||||
sendColorized(msg, ChatFormatting.LIGHT_PURPLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printError(String msg) {
|
||||
sendColorized(msg, ChatFormatting.RED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(Component component) {
|
||||
sendMessage(net.minecraft.network.chat.Component.Serializer.fromJson(
|
||||
GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component, getLocale()))
|
||||
));
|
||||
}
|
||||
|
||||
private void sendColorized(String msg, ChatFormatting formatting) {
|
||||
for (String part : msg.split("\n")) {
|
||||
var component = net.minecraft.network.chat.Component.literal(part);
|
||||
component.withStyle(formatting);
|
||||
sendMessage(component);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMessage(net.minecraft.network.chat.Component textComponent) {
|
||||
this.sender.sendSystemMessage(textComponent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
return WorldEdit.getInstance().getConfiguration().defaultLocale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getGroups() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkPermission(String permission) throws AuthorizationException {
|
||||
if (!hasPermission(permission)) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String permission) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public BaseCommandBlock getSender() {
|
||||
return this.sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionKey getSessionKey() {
|
||||
return new SessionKey() {
|
||||
|
||||
private volatile boolean active = true;
|
||||
|
||||
private void updateActive() {
|
||||
BlockPos pos = new BlockPos((int) sender.getPosition().x, (int) sender.getPosition().y, (int) sender.getPosition().z);
|
||||
int chunkX = SectionPos.blockToSectionCoord(pos.getX());
|
||||
int chunkZ = SectionPos.blockToSectionCoord(pos.getZ());
|
||||
if (!sender.getLevel().getChunkSource().hasChunk(chunkX, chunkZ)) {
|
||||
active = false;
|
||||
return;
|
||||
}
|
||||
Block type = sender.getLevel().getBlockState(pos).getBlock();
|
||||
active = type == Blocks.COMMAND_BLOCK
|
||||
|| type == Blocks.CHAIN_COMMAND_BLOCK
|
||||
|| type == Blocks.REPEATING_COMMAND_BLOCK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return sender.getName().getString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
getSender().getLevel().getServer().execute(this::updateActive);
|
||||
return active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersistent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return uuid;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* 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 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.fabric;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractNonPlayerActor;
|
||||
import com.sk89q.worldedit.session.SessionKey;
|
||||
import com.sk89q.worldedit.util.formatting.WorldEditText;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class FabricCommandSender extends AbstractNonPlayerActor {
|
||||
|
||||
/**
|
||||
* One time generated ID.
|
||||
*/
|
||||
private static final UUID DEFAULT_ID = UUID.fromString("a233eb4b-4cab-42cd-9fd9-7e7b9a3f74be");
|
||||
|
||||
private final CommandSourceStack sender;
|
||||
|
||||
public FabricCommandSender(CommandSourceStack sender) {
|
||||
checkNotNull(sender);
|
||||
checkArgument(!sender.isPlayer(), "Cannot wrap a player");
|
||||
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return DEFAULT_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return sender.getTextName();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printRaw(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
sendMessage(net.minecraft.network.chat.Component.literal(part));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printDebug(String msg) {
|
||||
sendColorized(msg, ChatFormatting.GRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void print(String msg) {
|
||||
sendColorized(msg, ChatFormatting.LIGHT_PURPLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printError(String msg) {
|
||||
sendColorized(msg, ChatFormatting.RED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(Component component) {
|
||||
sendMessage(net.minecraft.network.chat.Component.Serializer.fromJson(
|
||||
GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component, getLocale()))
|
||||
));
|
||||
}
|
||||
|
||||
private void sendColorized(String msg, ChatFormatting formatting) {
|
||||
for (String part : msg.split("\n")) {
|
||||
var component = net.minecraft.network.chat.Component.literal(part);
|
||||
component.withStyle(formatting);
|
||||
sendMessage(component);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMessage(net.minecraft.network.chat.Component textComponent) {
|
||||
this.sender.sendSystemMessage(textComponent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getGroups() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String perm) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkPermission(String permission) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
return WorldEdit.getInstance().getConfiguration().defaultLocale;
|
||||
}
|
||||
|
||||
public CommandSourceStack getSender() {
|
||||
return this.sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionKey getSessionKey() {
|
||||
return new SessionKey() {
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
return sender.getTextName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersistent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return DEFAULT_ID;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
accessWidener v2 named
|
||||
accessible class net/minecraft/server/level/ServerChunkCache$MainThreadExecutor
|
||||
accessible field net/minecraft/commands/CommandSourceStack source Lnet/minecraft/commands/CommandSource;
|
@ -35,8 +35,6 @@ import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.internal.util.Substring;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import org.enginehub.piston.inject.InjectedValueStore;
|
||||
import org.enginehub.piston.inject.Key;
|
||||
import org.enginehub.piston.inject.MapBackedValueStore;
|
||||
@ -77,11 +75,7 @@ public final class CommandWrapper {
|
||||
|
||||
private static Predicate<CommandSourceStack> requirementsFor(org.enginehub.piston.Command mapping) {
|
||||
return ctx -> {
|
||||
final Entity entity = ctx.getEntity();
|
||||
if (!(entity instanceof ServerPlayer)) {
|
||||
return true;
|
||||
}
|
||||
final Actor actor = ForgeAdapter.adaptPlayer(((ServerPlayer) entity));
|
||||
final Actor actor = ForgeAdapter.adaptCommandSource(ctx);
|
||||
InjectedValueStore store = MapBackedValueStore.create();
|
||||
store.injectValue(Key.of(Actor.class), context -> Optional.of(actor));
|
||||
return mapping.getCondition().satisfied(store);
|
||||
@ -91,7 +85,7 @@ public final class CommandWrapper {
|
||||
private static CompletableFuture<Suggestions> suggest(CommandContext<CommandSourceStack> context,
|
||||
SuggestionsBuilder builder) throws CommandSyntaxException {
|
||||
CommandSuggestionEvent event = new CommandSuggestionEvent(
|
||||
ForgeAdapter.adaptPlayer(context.getSource().getPlayerOrException()),
|
||||
ForgeAdapter.adaptCommandSource(context.getSource()),
|
||||
builder.getInput()
|
||||
);
|
||||
WorldEdit.getInstance().getEventBus().post(event);
|
||||
|
@ -22,6 +22,7 @@ package com.sk89q.worldedit.forge;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.forge.internal.ForgeTransmogrifier;
|
||||
import com.sk89q.worldedit.forge.internal.NBTConverter;
|
||||
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
||||
@ -37,6 +38,7 @@ import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
@ -45,6 +47,7 @@ import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.StringRepresentable;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BaseCommandBlock;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
@ -243,4 +246,22 @@ public final class ForgeAdapter {
|
||||
checkNotNull(player);
|
||||
return new ForgePlayer(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the WorldEdit proxy for the given command source.
|
||||
*
|
||||
* @param commandSourceStack the command source
|
||||
* @return the WorldEdit actor
|
||||
*/
|
||||
public static Actor adaptCommandSource(CommandSourceStack commandSourceStack) {
|
||||
checkNotNull(commandSourceStack);
|
||||
if (commandSourceStack.isPlayer()) {
|
||||
return adaptPlayer(commandSourceStack.getPlayer());
|
||||
}
|
||||
if (ForgeWorldEdit.inst.getConfig().commandBlockSupport && commandSourceStack.source instanceof BaseCommandBlock commandBlock) {
|
||||
return new ForgeBlockCommandSender(commandBlock);
|
||||
}
|
||||
|
||||
return new ForgeCommandSender(commandSourceStack);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.forge;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractCommandBlockActor;
|
||||
import com.sk89q.worldedit.session.SessionKey;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.auth.AuthorizationException;
|
||||
import com.sk89q.worldedit.util.formatting.WorldEditText;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.world.level.BaseCommandBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraftforge.common.util.LogicalSidedProvider;
|
||||
import net.minecraftforge.fml.LogicalSide;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class ForgeBlockCommandSender extends AbstractCommandBlockActor {
|
||||
private final BaseCommandBlock sender;
|
||||
private final UUID uuid;
|
||||
|
||||
public ForgeBlockCommandSender(BaseCommandBlock sender) {
|
||||
super(new Location(ForgeAdapter.adapt(checkNotNull(sender).getLevel()), ForgeAdapter.adapt(sender.getPosition())));
|
||||
|
||||
this.sender = sender;
|
||||
this.uuid = UUID.nameUUIDFromBytes((UUID_PREFIX + sender.getName()).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return sender.getName().getString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printRaw(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
sendMessage(net.minecraft.network.chat.Component.literal(part));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printDebug(String msg) {
|
||||
sendColorized(msg, ChatFormatting.GRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void print(String msg) {
|
||||
sendColorized(msg, ChatFormatting.LIGHT_PURPLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printError(String msg) {
|
||||
sendColorized(msg, ChatFormatting.RED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(Component component) {
|
||||
sendMessage(net.minecraft.network.chat.Component.Serializer.fromJson(
|
||||
GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component, getLocale()))
|
||||
));
|
||||
}
|
||||
|
||||
private void sendColorized(String msg, ChatFormatting formatting) {
|
||||
for (String part : msg.split("\n")) {
|
||||
var component = net.minecraft.network.chat.Component.literal(part);
|
||||
component.withStyle(formatting);
|
||||
sendMessage(component);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMessage(net.minecraft.network.chat.Component textComponent) {
|
||||
this.sender.sendSystemMessage(textComponent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
return WorldEdit.getInstance().getConfiguration().defaultLocale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getGroups() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkPermission(String permission) throws AuthorizationException {
|
||||
if (!hasPermission(permission)) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String permission) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public BaseCommandBlock getSender() {
|
||||
return this.sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionKey getSessionKey() {
|
||||
return new SessionKey() {
|
||||
|
||||
private volatile boolean active = true;
|
||||
|
||||
private void updateActive() {
|
||||
BlockPos pos = new BlockPos((int) sender.getPosition().x, (int) sender.getPosition().y, (int) sender.getPosition().z);
|
||||
int chunkX = SectionPos.blockToSectionCoord(pos.getX());
|
||||
int chunkZ = SectionPos.blockToSectionCoord(pos.getZ());
|
||||
if (!sender.getLevel().getChunkSource().hasChunk(chunkX, chunkZ)) {
|
||||
active = false;
|
||||
return;
|
||||
}
|
||||
Block type = sender.getLevel().getBlockState(pos).getBlock();
|
||||
active = type == Blocks.COMMAND_BLOCK
|
||||
|| type == Blocks.CHAIN_COMMAND_BLOCK
|
||||
|| type == Blocks.REPEATING_COMMAND_BLOCK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return sender.getName().getString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
LogicalSidedProvider.WORKQUEUE.get(LogicalSide.SERVER).submitAsync(this::updateActive);
|
||||
return active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersistent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return uuid;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* 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 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.forge;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractNonPlayerActor;
|
||||
import com.sk89q.worldedit.session.SessionKey;
|
||||
import com.sk89q.worldedit.util.formatting.WorldEditText;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class ForgeCommandSender extends AbstractNonPlayerActor {
|
||||
|
||||
/**
|
||||
* One time generated ID.
|
||||
*/
|
||||
private static final UUID DEFAULT_ID = UUID.fromString("a233eb4b-4cab-42cd-9fd9-7e7b9a3f74be");
|
||||
|
||||
private final CommandSourceStack sender;
|
||||
|
||||
public ForgeCommandSender(CommandSourceStack sender) {
|
||||
checkNotNull(sender);
|
||||
checkArgument(!sender.isPlayer(), "Cannot wrap a player");
|
||||
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return DEFAULT_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return sender.getTextName();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printRaw(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
sendMessage(net.minecraft.network.chat.Component.literal(part));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printDebug(String msg) {
|
||||
sendColorized(msg, ChatFormatting.GRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void print(String msg) {
|
||||
sendColorized(msg, ChatFormatting.LIGHT_PURPLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printError(String msg) {
|
||||
sendColorized(msg, ChatFormatting.RED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(Component component) {
|
||||
sendMessage(net.minecraft.network.chat.Component.Serializer.fromJson(
|
||||
GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component, getLocale()))
|
||||
));
|
||||
}
|
||||
|
||||
private void sendColorized(String msg, ChatFormatting formatting) {
|
||||
for (String part : msg.split("\n")) {
|
||||
var component = net.minecraft.network.chat.Component.literal(part);
|
||||
component.withStyle(formatting);
|
||||
sendMessage(component);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMessage(net.minecraft.network.chat.Component textComponent) {
|
||||
this.sender.sendSystemMessage(textComponent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getGroups() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String perm) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkPermission(String permission) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
return WorldEdit.getInstance().getConfiguration().defaultLocale;
|
||||
}
|
||||
|
||||
public CommandSourceStack getSender() {
|
||||
return this.sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionKey getSessionKey() {
|
||||
return new SessionKey() {
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
return sender.getTextName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersistent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return DEFAULT_ID;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -87,6 +87,7 @@ import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.sk89q.worldedit.forge.ForgeAdapter.adaptCommandSource;
|
||||
import static com.sk89q.worldedit.forge.ForgeAdapter.adaptPlayer;
|
||||
import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAME;
|
||||
|
||||
@ -320,10 +321,7 @@ public class ForgeWorldEdit {
|
||||
@SubscribeEvent
|
||||
public void onCommandEvent(CommandEvent event) throws CommandSyntaxException {
|
||||
ParseResults<CommandSourceStack> parseResults = event.getParseResults();
|
||||
if (!(parseResults.getContext().getSource().getEntity() instanceof ServerPlayer player)) {
|
||||
return;
|
||||
}
|
||||
if (player.level().isClientSide) {
|
||||
if (parseResults.getContext().getSource().getEntity() instanceof ServerPlayer player && player.level().isClientSide) {
|
||||
return;
|
||||
}
|
||||
if (parseResults.getContext().getCommand() != CommandWrapper.FAKE_COMMAND) {
|
||||
@ -331,7 +329,7 @@ public class ForgeWorldEdit {
|
||||
}
|
||||
event.setCanceled(true);
|
||||
WorldEdit.getInstance().getEventBus().post(new com.sk89q.worldedit.event.platform.CommandEvent(
|
||||
adaptPlayer(parseResults.getContext().getSource().getPlayerOrException()),
|
||||
adaptCommandSource(parseResults.getContext().getSource()),
|
||||
"/" + parseResults.getReader().getString()
|
||||
));
|
||||
}
|
||||
|
@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.sponge;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractCommandBlockActor;
|
||||
import com.sk89q.worldedit.session.SessionKey;
|
||||
import com.sk89q.worldedit.util.auth.AuthorizationException;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.block.BlockState;
|
||||
import org.spongepowered.api.block.BlockType;
|
||||
import org.spongepowered.api.block.BlockTypes;
|
||||
import org.spongepowered.api.block.entity.CommandBlock;
|
||||
import org.spongepowered.api.data.Keys;
|
||||
import org.spongepowered.api.scheduler.Task;
|
||||
import org.spongepowered.api.util.Ticks;
|
||||
import org.spongepowered.math.vector.Vector3d;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class SpongeBlockCommandSender extends AbstractCommandBlockActor {
|
||||
private final SpongeWorldEdit worldEdit;
|
||||
private final CommandBlock sender;
|
||||
private final UUID uuid;
|
||||
|
||||
public SpongeBlockCommandSender(SpongeWorldEdit worldEdit, CommandBlock sender) {
|
||||
super(SpongeAdapter.adapt(checkNotNull(sender).serverLocation(), Vector3d.ZERO));
|
||||
checkNotNull(worldEdit);
|
||||
|
||||
this.worldEdit = worldEdit;
|
||||
this.sender = sender;
|
||||
this.uuid = UUID.nameUUIDFromBytes((UUID_PREFIX + sender.name()).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return sender.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printRaw(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
sendMessage(net.kyori.adventure.text.Component.text(part));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void print(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
print(TextComponent.of(part, TextColor.LIGHT_PURPLE));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printDebug(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
print(TextComponent.of(part, TextColor.GRAY));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printError(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
print(TextComponent.of(part, TextColor.RED));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(Component component) {
|
||||
sendMessage(SpongeTextAdapter.convert(component, getLocale()));
|
||||
}
|
||||
|
||||
private void sendMessage(net.kyori.adventure.text.Component textComponent) {
|
||||
this.sender.offer(Keys.LAST_COMMAND_OUTPUT, textComponent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
return WorldEdit.getInstance().getConfiguration().defaultLocale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getGroups() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkPermission(String permission) throws AuthorizationException {
|
||||
if (!hasPermission(permission)) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String permission) {
|
||||
return sender.hasPermission(permission);
|
||||
}
|
||||
|
||||
public CommandBlock getSender() {
|
||||
return this.sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionKey getSessionKey() {
|
||||
return new SessionKey() {
|
||||
|
||||
private volatile boolean active = true;
|
||||
|
||||
private void updateActive() {
|
||||
BlockState block = sender.block();
|
||||
if (!sender.serverLocation().world().isChunkLoadedAtBlock(sender.blockPosition(), false)) {
|
||||
active = false;
|
||||
return;
|
||||
}
|
||||
BlockType type = block.type();
|
||||
active = type == BlockTypes.COMMAND_BLOCK.get()
|
||||
|| type == BlockTypes.CHAIN_COMMAND_BLOCK.get()
|
||||
|| type == BlockTypes.REPEATING_COMMAND_BLOCK.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return sender.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
if (Sponge.server().onMainThread()) {
|
||||
// we can update eagerly
|
||||
updateActive();
|
||||
} else {
|
||||
// we should update it eventually
|
||||
Task task = Task.builder().delay(Ticks.zero()).plugin(worldEdit.getPluginContainer()).execute(this::updateActive).build();
|
||||
Sponge.server().scheduler().submit(task);
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersistent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return uuid;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -48,6 +48,8 @@ import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.block.BlockSnapshot;
|
||||
import org.spongepowered.api.block.BlockType;
|
||||
import org.spongepowered.api.block.BlockTypes;
|
||||
import org.spongepowered.api.block.entity.BlockEntity;
|
||||
import org.spongepowered.api.block.entity.CommandBlock;
|
||||
import org.spongepowered.api.command.Command;
|
||||
import org.spongepowered.api.command.CommandCause;
|
||||
import org.spongepowered.api.command.CommandCompletion;
|
||||
@ -67,6 +69,7 @@ import org.spongepowered.api.event.lifecycle.StoppingEngineEvent;
|
||||
import org.spongepowered.api.event.network.ServerSideConnectionEvent;
|
||||
import org.spongepowered.api.registry.RegistryTypes;
|
||||
import org.spongepowered.api.scheduler.Task;
|
||||
import org.spongepowered.api.world.LocatableBlock;
|
||||
import org.spongepowered.api.world.server.ServerLocation;
|
||||
import org.spongepowered.api.world.server.ServerWorld;
|
||||
import org.spongepowered.math.vector.Vector3d;
|
||||
@ -376,6 +379,15 @@ public class SpongeWorldEdit {
|
||||
if (rootCause instanceof ServerPlayer) {
|
||||
return SpongeAdapter.adapt((ServerPlayer) rootCause);
|
||||
}
|
||||
if (rootCause instanceof LocatableBlock locatableBlock) {
|
||||
Optional<? extends BlockEntity> optionalBlockEntity = locatableBlock.world().blockEntity(locatableBlock.blockPosition());
|
||||
if (optionalBlockEntity.isPresent()) {
|
||||
BlockEntity blockEntity = optionalBlockEntity.get();
|
||||
if (blockEntity instanceof CommandBlock commandBlock) {
|
||||
return new SpongeBlockCommandSender(this, commandBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rootCause instanceof Audience) {
|
||||
return new SpongeCommandSender((Audience) rootCause);
|
||||
}
|
||||
|
@ -139,9 +139,11 @@ public class ConfigurateConfiguration extends LocalConfiguration {
|
||||
initializeSnapshotConfiguration(snapshotsDir, experimentalSnapshots);
|
||||
|
||||
String type = node.node("shell-save-type").getString("").trim();
|
||||
shellSaveType = type.equals("") ? null : type;
|
||||
shellSaveType = type.isEmpty() ? null : type;
|
||||
|
||||
extendedYLimit = node.node("compat", "extended-y-limit").getBoolean(false);
|
||||
setDefaultLocaleName(node.node("default-locale").getString(defaultLocaleName));
|
||||
|
||||
commandBlockSupport = node.node("command-block-support").getBoolean(false);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user