mirror of
https://github.com/EngineHub/WorldEdit.git
synced 2025-03-01 13:36:46 +08:00
Merge branch 'version/7.2.x'
This commit is contained in:
commit
b079da7db0
@ -1,3 +1,14 @@
|
|||||||
|
7.2.15
|
||||||
|
- [Forge] Fix a bug preventing Forge clients lacking WorldEdit from joining Forge servers with WorldEdit in some cases
|
||||||
|
- [Forge] Added Console and CommandBlock support
|
||||||
|
- [Fabric] Added Console and CommandBlock support
|
||||||
|
- [Sponge] Added CommandBlock support
|
||||||
|
- Update to 1.20 & 1.20.1
|
||||||
|
- Fixed extend select mode being lost after using `//paste -s`, `//paste -n`, and `//cli selectworld`
|
||||||
|
- Fixed convex selection type not correctly clearing selection within WECUI protocol
|
||||||
|
- Fixed an edge case where API usages of the BlockMap type can lead to multiple values at one location
|
||||||
|
- Fixed a bug breaking the `round` expression function
|
||||||
|
|
||||||
7.2.14
|
7.2.14
|
||||||
- Update to 1.19.4
|
- Update to 1.19.4
|
||||||
- Fixed some data values not being returned correctly in expression query functions
|
- Fixed some data values not being returned correctly in expression query functions
|
||||||
|
@ -210,8 +210,8 @@ public PaperweightAdapter() throws NoSuchFieldException, NoSuchMethodException {
|
|||||||
CraftServer.class.cast(Bukkit.getServer());
|
CraftServer.class.cast(Bukkit.getServer());
|
||||||
|
|
||||||
int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion();
|
int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion();
|
||||||
if (dataVersion != 3463) {
|
if (dataVersion != 3463 && dataVersion != 3465) {
|
||||||
throw new UnsupportedClassVersionError("Not 1.20!");
|
throw new UnsupportedClassVersionError("Not 1.20(.1)!");
|
||||||
}
|
}
|
||||||
|
|
||||||
serverWorldsField = CraftServer.class.getDeclaredField("worlds");
|
serverWorldsField = CraftServer.class.getDeclaredField("worlds");
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
"api"(project(":worldedit-libs:bukkit"))
|
"api"(project(":worldedit-libs:bukkit"))
|
||||||
// Technically this is api, but everyone should already have some form of the bukkit API
|
// Technically this is api, but everyone should already have some form of the bukkit API
|
||||||
// Avoid pulling in another one, especially one so outdated.
|
// Avoid pulling in another one, especially one so outdated.
|
||||||
"localImplementation"("org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT") {
|
"localImplementation"("org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT") {
|
||||||
exclude("junit", "junit")
|
exclude("junit", "junit")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +52,7 @@
|
|||||||
"localImplementation"("org.apache.logging.log4j:log4j-api")
|
"localImplementation"("org.apache.logging.log4j:log4j-api")
|
||||||
|
|
||||||
"compileOnly"("org.jetbrains:annotations:20.1.0")
|
"compileOnly"("org.jetbrains:annotations:20.1.0")
|
||||||
"compileOnly"("io.papermc.paper:paper-api:1.17-R0.1-SNAPSHOT") {
|
"compileOnly"("io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT") {
|
||||||
exclude("org.slf4j", "slf4j-api")
|
exclude("org.slf4j", "slf4j-api")
|
||||||
exclude("junit", "junit")
|
exclude("junit", "junit")
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,8 @@
|
|||||||
package com.sk89q.worldedit.bukkit;
|
package com.sk89q.worldedit.bukkit;
|
||||||
|
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.extension.platform.AbstractNonPlayerActor;
|
import com.sk89q.worldedit.extension.platform.AbstractCommandBlockActor;
|
||||||
import com.sk89q.worldedit.extension.platform.Locatable;
|
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
|
||||||
import com.sk89q.worldedit.session.SessionKey;
|
import com.sk89q.worldedit.session.SessionKey;
|
||||||
import com.sk89q.worldedit.util.Location;
|
|
||||||
import com.sk89q.worldedit.util.auth.AuthorizationException;
|
import com.sk89q.worldedit.util.auth.AuthorizationException;
|
||||||
import com.sk89q.worldedit.util.formatting.WorldEditText;
|
import com.sk89q.worldedit.util.formatting.WorldEditText;
|
||||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||||
@ -42,22 +39,17 @@
|
|||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
public class BukkitBlockCommandSender extends AbstractNonPlayerActor implements Locatable {
|
public class BukkitBlockCommandSender extends AbstractCommandBlockActor {
|
||||||
|
|
||||||
private static final String UUID_PREFIX = "CMD";
|
|
||||||
|
|
||||||
private final BlockCommandSender sender;
|
private final BlockCommandSender sender;
|
||||||
private final WorldEditPlugin plugin;
|
private final WorldEditPlugin plugin;
|
||||||
private final Location location;
|
|
||||||
private final UUID uuid;
|
private final UUID uuid;
|
||||||
|
|
||||||
public BukkitBlockCommandSender(WorldEditPlugin plugin, BlockCommandSender sender) {
|
public BukkitBlockCommandSender(WorldEditPlugin plugin, BlockCommandSender sender) {
|
||||||
|
super(BukkitAdapter.adapt(checkNotNull(sender).getBlock().getLocation()));
|
||||||
checkNotNull(plugin);
|
checkNotNull(plugin);
|
||||||
checkNotNull(sender);
|
|
||||||
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.sender = sender;
|
this.sender = sender;
|
||||||
this.location = BukkitAdapter.adapt(sender.getBlock().getLocation());
|
|
||||||
this.uuid = UUID.nameUUIDFromBytes((UUID_PREFIX + sender.getName()).getBytes(StandardCharsets.UTF_8));
|
this.uuid = UUID.nameUUIDFromBytes((UUID_PREFIX + sender.getName()).getBytes(StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,21 +100,6 @@ public Locale getLocale() {
|
|||||||
return WorldEdit.getInstance().getConfiguration().defaultLocale;
|
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
|
@Override
|
||||||
public UUID getUniqueId() {
|
public UUID getUniqueId() {
|
||||||
return uuid;
|
return uuid;
|
||||||
|
@ -36,7 +36,6 @@
|
|||||||
public class BukkitConfiguration extends YAMLConfiguration {
|
public class BukkitConfiguration extends YAMLConfiguration {
|
||||||
|
|
||||||
public boolean noOpPermissions = false;
|
public boolean noOpPermissions = false;
|
||||||
public boolean commandBlockSupport = false;
|
|
||||||
public boolean unsupportedVersionEditing = false;
|
public boolean unsupportedVersionEditing = false;
|
||||||
@Unreported private final WorldEditPlugin plugin;
|
@Unreported private final WorldEditPlugin plugin;
|
||||||
|
|
||||||
@ -49,7 +48,6 @@ public BukkitConfiguration(YAMLProcessor config, WorldEditPlugin plugin) {
|
|||||||
public void load() {
|
public void load() {
|
||||||
super.load();
|
super.load();
|
||||||
noOpPermissions = config.getBoolean("no-op-permissions", false);
|
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(
|
unsupportedVersionEditing = "I accept that I will receive no support with this flag enabled.".equals(
|
||||||
config.getString("allow-editing-on-unsupported-versions", "false"));
|
config.getString("allow-editing-on-unsupported-versions", "false"));
|
||||||
if (unsupportedVersionEditing) {
|
if (unsupportedVersionEditing) {
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
import org.bukkit.permissions.PermissionAttachment;
|
import org.bukkit.permissions.PermissionAttachment;
|
||||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.bukkit.profile.PlayerProfile;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -144,6 +145,11 @@ public UUID getUniqueId() {
|
|||||||
return randomUuid;
|
return randomUuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlayerProfile getPlayerProfile() {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isBanned() {
|
public boolean isBanned() {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
@ -278,4 +284,9 @@ public void decrementStatistic(Statistic statistic, EntityType entityType, int a
|
|||||||
public void setStatistic(Statistic statistic, EntityType entityType, int newValue) {
|
public void setStatistic(Statistic statistic, EntityType entityType, int newValue) {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Location getLastDeathLocation() {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,20 @@
|
|||||||
package com.sk89q.worldedit.blocks;
|
package com.sk89q.worldedit.blocks;
|
||||||
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.jnbt.ListTag;
|
||||||
import com.sk89q.jnbt.StringTag;
|
import com.sk89q.jnbt.StringTag;
|
||||||
import com.sk89q.jnbt.Tag;
|
import com.sk89q.jnbt.Tag;
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Capability;
|
||||||
|
import com.sk89q.worldedit.internal.Constants;
|
||||||
import com.sk89q.worldedit.util.gson.GsonUtil;
|
import com.sk89q.worldedit.util.gson.GsonUtil;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a sign block.
|
* Represents a sign block.
|
||||||
@ -64,6 +70,11 @@ public SignBlock(BlockState blockState, String[] text) {
|
|||||||
this.text = text;
|
this.text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isLegacy() {
|
||||||
|
int dataVersion = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion();
|
||||||
|
return dataVersion < Constants.DATA_VERSION_MC_1_20;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the text.
|
* Get the text.
|
||||||
*
|
*
|
||||||
@ -100,10 +111,17 @@ public String getNbtId() {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public CompoundTag getNbtData() {
|
public CompoundTag getNbtData() {
|
||||||
Map<String, Tag<?, ?>> values = new HashMap<>();
|
Map<String, Tag<?, ?>> values = new HashMap<>();
|
||||||
values.put("Text1", new StringTag(text[0]));
|
if (isLegacy()) {
|
||||||
values.put("Text2", new StringTag(text[1]));
|
values.put("Text1", new StringTag(text[0]));
|
||||||
values.put("Text3", new StringTag(text[2]));
|
values.put("Text2", new StringTag(text[1]));
|
||||||
values.put("Text4", new StringTag(text[3]));
|
values.put("Text3", new StringTag(text[2]));
|
||||||
|
values.put("Text4", new StringTag(text[3]));
|
||||||
|
} else {
|
||||||
|
ListTag<?, ?> messages = new ListTag<>(StringTag.class, Arrays.stream(text).map(StringTag::new).collect(Collectors.toList()));
|
||||||
|
Map<String, Tag<?, ?>> frontTextTag = new HashMap<>();
|
||||||
|
frontTextTag.put("messages", messages);
|
||||||
|
values.put("front_text", new CompoundTag(frontTextTag));
|
||||||
|
}
|
||||||
return new CompoundTag(values);
|
return new CompoundTag(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,24 +143,33 @@ public void setNbtData(CompoundTag rootTag) {
|
|||||||
throw new RuntimeException(String.format("'%s' tile entity expected", getNbtId()));
|
throw new RuntimeException(String.format("'%s' tile entity expected", getNbtId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
t = values.get("Text1");
|
if (isLegacy()) {
|
||||||
if (t instanceof StringTag) {
|
t = values.get("Text1");
|
||||||
text[0] = ((StringTag) t).getValue();
|
if (t instanceof StringTag) {
|
||||||
}
|
text[0] = ((StringTag) t).getValue();
|
||||||
|
}
|
||||||
|
|
||||||
t = values.get("Text2");
|
t = values.get("Text2");
|
||||||
if (t instanceof StringTag) {
|
if (t instanceof StringTag) {
|
||||||
text[1] = ((StringTag) t).getValue();
|
text[1] = ((StringTag) t).getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
t = values.get("Text3");
|
t = values.get("Text3");
|
||||||
if (t instanceof StringTag) {
|
if (t instanceof StringTag) {
|
||||||
text[2] = ((StringTag) t).getValue();
|
text[2] = ((StringTag) t).getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
t = values.get("Text4");
|
t = values.get("Text4");
|
||||||
if (t instanceof StringTag) {
|
if (t instanceof StringTag) {
|
||||||
text[3] = ((StringTag) t).getValue();
|
text[3] = ((StringTag) t).getValue();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CompoundTag frontTextTag = (CompoundTag) values.get("front_text");
|
||||||
|
ListTag<?, ?> messagesTag = frontTextTag.getListTag("messages");
|
||||||
|
for (int i = 0; i < messagesTag.getValue().size(); i++) {
|
||||||
|
StringTag tag = (StringTag) messagesTag.getValue().get(i);
|
||||||
|
text[i] = tag.getValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +91,7 @@ public abstract class LocalConfiguration {
|
|||||||
public boolean allowSymlinks = false;
|
public boolean allowSymlinks = false;
|
||||||
public boolean serverSideCUI = true;
|
public boolean serverSideCUI = true;
|
||||||
public boolean extendedYLimit = false;
|
public boolean extendedYLimit = false;
|
||||||
|
public boolean commandBlockSupport = false;
|
||||||
public String defaultLocaleName = "default";
|
public String defaultLocaleName = "default";
|
||||||
public Locale defaultLocale = Locale.getDefault();
|
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 void load() {
|
|||||||
serverSideCUI = getBool("server-side-cui", serverSideCUI);
|
serverSideCUI = getBool("server-side-cui", serverSideCUI);
|
||||||
extendedYLimit = getBool("extended-y-limit", extendedYLimit);
|
extendedYLimit = getBool("extended-y-limit", extendedYLimit);
|
||||||
setDefaultLocaleName(getString("default-locale", defaultLocaleName));
|
setDefaultLocaleName(getString("default-locale", defaultLocaleName));
|
||||||
|
commandBlockSupport = getBool("command-block-support", commandBlockSupport);
|
||||||
|
|
||||||
LocalSession.MAX_HISTORY_SIZE = Math.max(15, getInt("history-size", 15));
|
LocalSession.MAX_HISTORY_SIZE = Math.max(15, getInt("history-size", 15));
|
||||||
|
|
||||||
|
@ -108,6 +108,9 @@ public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxCha
|
|||||||
return editSession.getWorld().generateTree(this, editSession, pos.subtract(0, 1, 0));
|
return editSession.getWorld().generateTree(this, editSession, pos.subtract(0, 1, 0));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
MANGROVE("Mangrove tree", "mangrove"),
|
||||||
|
TALL_MANGROVE("Tall mangrove tree", "tall_mangrove"),
|
||||||
|
CHERRY("Cherry blossom", "cherry"),
|
||||||
RANDOM("Random tree", "rand", "random") {
|
RANDOM("Random tree", "rand", "random") {
|
||||||
@Override
|
@Override
|
||||||
public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException {
|
public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException {
|
||||||
|
@ -129,6 +129,8 @@ public void load() {
|
|||||||
extendedYLimit = config.getBoolean("compat.extended-y-limit", false);
|
extendedYLimit = config.getBoolean("compat.extended-y-limit", false);
|
||||||
|
|
||||||
setDefaultLocaleName(config.getString("default-locale", defaultLocaleName));
|
setDefaultLocaleName(config.getString("default-locale", defaultLocaleName));
|
||||||
|
|
||||||
|
commandBlockSupport = config.getBoolean("command-block-support", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unload() {
|
public void unload() {
|
||||||
|
@ -35,8 +35,6 @@
|
|||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.internal.util.Substring;
|
import com.sk89q.worldedit.internal.util.Substring;
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
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.InjectedValueStore;
|
||||||
import org.enginehub.piston.inject.Key;
|
import org.enginehub.piston.inject.Key;
|
||||||
import org.enginehub.piston.inject.MapBackedValueStore;
|
import org.enginehub.piston.inject.MapBackedValueStore;
|
||||||
@ -46,7 +44,7 @@
|
|||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.function.Predicate;
|
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.argument;
|
||||||
import static net.minecraft.commands.Commands.literal;
|
import static net.minecraft.commands.Commands.literal;
|
||||||
|
|
||||||
@ -62,7 +60,7 @@ public static void register(CommandDispatcher<CommandSourceStack> dispatcher, or
|
|||||||
|
|
||||||
Command<CommandSourceStack> commandRunner = ctx -> {
|
Command<CommandSourceStack> commandRunner = ctx -> {
|
||||||
WorldEdit.getInstance().getEventBus().post(new com.sk89q.worldedit.event.platform.CommandEvent(
|
WorldEdit.getInstance().getEventBus().post(new com.sk89q.worldedit.event.platform.CommandEvent(
|
||||||
adaptPlayer(ctx.getSource().getPlayerOrException()),
|
adaptCommandSource(ctx.getSource()),
|
||||||
"/" + ctx.getInput()
|
"/" + ctx.getInput()
|
||||||
));
|
));
|
||||||
return 0;
|
return 0;
|
||||||
@ -82,12 +80,8 @@ public static void register(CommandDispatcher<CommandSourceStack> dispatcher, or
|
|||||||
|
|
||||||
private static Predicate<CommandSourceStack> requirementsFor(org.enginehub.piston.Command mapping) {
|
private static Predicate<CommandSourceStack> requirementsFor(org.enginehub.piston.Command mapping) {
|
||||||
return ctx -> {
|
return ctx -> {
|
||||||
final Entity entity = ctx.getEntity();
|
|
||||||
if (!(entity instanceof ServerPlayer)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
final Actor actor = FabricAdapter.adaptPlayer(((ServerPlayer) entity));
|
|
||||||
InjectedValueStore store = MapBackedValueStore.create();
|
InjectedValueStore store = MapBackedValueStore.create();
|
||||||
|
final Actor actor = FabricAdapter.adaptCommandSource(ctx);
|
||||||
store.injectValue(Key.of(Actor.class), context -> Optional.of(actor));
|
store.injectValue(Key.of(Actor.class), context -> Optional.of(actor));
|
||||||
return mapping.getCondition().satisfied(store);
|
return mapping.getCondition().satisfied(store);
|
||||||
};
|
};
|
||||||
@ -96,7 +90,7 @@ private static Predicate<CommandSourceStack> requirementsFor(org.enginehub.pisto
|
|||||||
private static CompletableFuture<Suggestions> suggest(CommandContext<CommandSourceStack> context,
|
private static CompletableFuture<Suggestions> suggest(CommandContext<CommandSourceStack> context,
|
||||||
SuggestionsBuilder builder) throws CommandSyntaxException {
|
SuggestionsBuilder builder) throws CommandSyntaxException {
|
||||||
CommandSuggestionEvent event = new CommandSuggestionEvent(
|
CommandSuggestionEvent event = new CommandSuggestionEvent(
|
||||||
FabricAdapter.adaptPlayer(context.getSource().getPlayerOrException()),
|
FabricAdapter.adaptCommandSource(context.getSource()),
|
||||||
builder.getInput()
|
builder.getInput()
|
||||||
);
|
);
|
||||||
WorldEdit.getInstance().getEventBus().post(event);
|
WorldEdit.getInstance().getEventBus().post(event);
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package com.sk89q.worldedit.fabric;
|
package com.sk89q.worldedit.fabric;
|
||||||
|
|
||||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
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.FabricTransmogrifier;
|
||||||
import com.sk89q.worldedit.fabric.internal.NBTConverter;
|
import com.sk89q.worldedit.fabric.internal.NBTConverter;
|
||||||
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
||||||
@ -37,6 +38,7 @@
|
|||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
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 net.minecraft.commands.CommandSourceStack;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
@ -44,6 +46,7 @@
|
|||||||
import net.minecraft.util.StringRepresentable;
|
import net.minecraft.util.StringRepresentable;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.BaseCommandBlock;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
@ -260,4 +263,22 @@ public static FabricPlayer adaptPlayer(ServerPlayer player) {
|
|||||||
checkNotNull(player);
|
checkNotNull(player);
|
||||||
return new FabricPlayer(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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -457,6 +457,9 @@ private List<CompletableFuture<ChunkAccess>> submitChunkLoadTasks(Region region,
|
|||||||
case WARPED_FUNGUS -> TreeFeatures.WARPED_FUNGUS;
|
case WARPED_FUNGUS -> TreeFeatures.WARPED_FUNGUS;
|
||||||
case CRIMSON_FUNGUS -> TreeFeatures.CRIMSON_FUNGUS;
|
case CRIMSON_FUNGUS -> TreeFeatures.CRIMSON_FUNGUS;
|
||||||
case CHORUS_PLANT -> EndFeatures.CHORUS_PLANT;
|
case CHORUS_PLANT -> EndFeatures.CHORUS_PLANT;
|
||||||
|
case MANGROVE -> TreeFeatures.MANGROVE;
|
||||||
|
case TALL_MANGROVE -> TreeFeatures.TALL_MANGROVE;
|
||||||
|
case CHERRY -> TreeFeatures.CHERRY;
|
||||||
case RANDOM -> createTreeFeatureGenerator(TreeType.values()[ThreadLocalRandom.current().nextInt(TreeType.values().length)]);
|
case RANDOM -> createTreeFeatureGenerator(TreeType.values()[ThreadLocalRandom.current().nextInt(TreeType.values().length)]);
|
||||||
default -> null;
|
default -> null;
|
||||||
};
|
};
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
accessWidener v2 named
|
accessWidener v2 named
|
||||||
accessible class net/minecraft/server/level/ServerChunkCache$MainThreadExecutor
|
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.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.internal.util.Substring;
|
import com.sk89q.worldedit.internal.util.Substring;
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
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.InjectedValueStore;
|
||||||
import org.enginehub.piston.inject.Key;
|
import org.enginehub.piston.inject.Key;
|
||||||
import org.enginehub.piston.inject.MapBackedValueStore;
|
import org.enginehub.piston.inject.MapBackedValueStore;
|
||||||
@ -77,11 +75,7 @@ public static void register(CommandDispatcher<CommandSourceStack> dispatcher, or
|
|||||||
|
|
||||||
private static Predicate<CommandSourceStack> requirementsFor(org.enginehub.piston.Command mapping) {
|
private static Predicate<CommandSourceStack> requirementsFor(org.enginehub.piston.Command mapping) {
|
||||||
return ctx -> {
|
return ctx -> {
|
||||||
final Entity entity = ctx.getEntity();
|
final Actor actor = ForgeAdapter.adaptCommandSource(ctx);
|
||||||
if (!(entity instanceof ServerPlayer)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
final Actor actor = ForgeAdapter.adaptPlayer(((ServerPlayer) entity));
|
|
||||||
InjectedValueStore store = MapBackedValueStore.create();
|
InjectedValueStore store = MapBackedValueStore.create();
|
||||||
store.injectValue(Key.of(Actor.class), context -> Optional.of(actor));
|
store.injectValue(Key.of(Actor.class), context -> Optional.of(actor));
|
||||||
return mapping.getCondition().satisfied(store);
|
return mapping.getCondition().satisfied(store);
|
||||||
@ -91,7 +85,7 @@ private static Predicate<CommandSourceStack> requirementsFor(org.enginehub.pisto
|
|||||||
private static CompletableFuture<Suggestions> suggest(CommandContext<CommandSourceStack> context,
|
private static CompletableFuture<Suggestions> suggest(CommandContext<CommandSourceStack> context,
|
||||||
SuggestionsBuilder builder) throws CommandSyntaxException {
|
SuggestionsBuilder builder) throws CommandSyntaxException {
|
||||||
CommandSuggestionEvent event = new CommandSuggestionEvent(
|
CommandSuggestionEvent event = new CommandSuggestionEvent(
|
||||||
ForgeAdapter.adaptPlayer(context.getSource().getPlayerOrException()),
|
ForgeAdapter.adaptCommandSource(context.getSource()),
|
||||||
builder.getInput()
|
builder.getInput()
|
||||||
);
|
);
|
||||||
WorldEdit.getInstance().getEventBus().post(event);
|
WorldEdit.getInstance().getEventBus().post(event);
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package com.sk89q.worldedit.forge;
|
package com.sk89q.worldedit.forge;
|
||||||
|
|
||||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
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.ForgeTransmogrifier;
|
||||||
import com.sk89q.worldedit.forge.internal.NBTConverter;
|
import com.sk89q.worldedit.forge.internal.NBTConverter;
|
||||||
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
||||||
@ -36,6 +37,7 @@
|
|||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
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 net.minecraft.commands.CommandSourceStack;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
@ -44,6 +46,7 @@
|
|||||||
import net.minecraft.util.StringRepresentable;
|
import net.minecraft.util.StringRepresentable;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.BaseCommandBlock;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||||
@ -247,4 +250,22 @@ public static ForgePlayer adaptPlayer(ServerPlayer player) {
|
|||||||
checkNotNull(player);
|
checkNotNull(player);
|
||||||
return new ForgePlayer(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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -442,6 +442,9 @@ private List<CompletableFuture<ChunkAccess>> submitChunkLoadTasks(Region region,
|
|||||||
case WARPED_FUNGUS -> TreeFeatures.WARPED_FUNGUS;
|
case WARPED_FUNGUS -> TreeFeatures.WARPED_FUNGUS;
|
||||||
case CRIMSON_FUNGUS -> TreeFeatures.CRIMSON_FUNGUS;
|
case CRIMSON_FUNGUS -> TreeFeatures.CRIMSON_FUNGUS;
|
||||||
case CHORUS_PLANT -> EndFeatures.CHORUS_PLANT;
|
case CHORUS_PLANT -> EndFeatures.CHORUS_PLANT;
|
||||||
|
case MANGROVE -> TreeFeatures.MANGROVE;
|
||||||
|
case TALL_MANGROVE -> TreeFeatures.TALL_MANGROVE;
|
||||||
|
case CHERRY -> TreeFeatures.CHERRY;
|
||||||
case RANDOM -> createTreeFeatureGenerator(TreeType.values()[ThreadLocalRandom.current().nextInt(TreeType.values().length)]);
|
case RANDOM -> createTreeFeatureGenerator(TreeType.values()[ThreadLocalRandom.current().nextInt(TreeType.values().length)]);
|
||||||
default -> null;
|
default -> null;
|
||||||
};
|
};
|
||||||
|
@ -89,6 +89,7 @@
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
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.forge.ForgeAdapter.adaptPlayer;
|
||||||
import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAME;
|
import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAME;
|
||||||
|
|
||||||
@ -332,10 +333,7 @@ public void onPlayerInteract(PlayerInteractEvent event) {
|
|||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onCommandEvent(CommandEvent event) throws CommandSyntaxException {
|
public void onCommandEvent(CommandEvent event) throws CommandSyntaxException {
|
||||||
ParseResults<CommandSourceStack> parseResults = event.getParseResults();
|
ParseResults<CommandSourceStack> parseResults = event.getParseResults();
|
||||||
if (!(parseResults.getContext().getSource().getEntity() instanceof ServerPlayer player)) {
|
if (parseResults.getContext().getSource().getEntity() instanceof ServerPlayer player && player.level().isClientSide) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (player.level().isClientSide) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (parseResults.getContext().getCommand() != CommandWrapper.FAKE_COMMAND) {
|
if (parseResults.getContext().getCommand() != CommandWrapper.FAKE_COMMAND) {
|
||||||
@ -343,7 +341,7 @@ public void onCommandEvent(CommandEvent event) throws CommandSyntaxException {
|
|||||||
}
|
}
|
||||||
event.setCanceled(true);
|
event.setCanceled(true);
|
||||||
WorldEdit.getInstance().getEventBus().post(new com.sk89q.worldedit.event.platform.CommandEvent(
|
WorldEdit.getInstance().getEventBus().post(new com.sk89q.worldedit.event.platform.CommandEvent(
|
||||||
adaptPlayer(parseResults.getContext().getSource().getPlayerOrException()),
|
adaptCommandSource(parseResults.getContext().getSource()),
|
||||||
"/" + parseResults.getReader().getString()
|
"/" + 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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -316,6 +316,9 @@ public boolean regenerate(Region region, Extent extent, RegenOptions options) {
|
|||||||
case WARPED_FUNGUS -> TreeFeatures.WARPED_FUNGUS;
|
case WARPED_FUNGUS -> TreeFeatures.WARPED_FUNGUS;
|
||||||
case CRIMSON_FUNGUS -> TreeFeatures.CRIMSON_FUNGUS;
|
case CRIMSON_FUNGUS -> TreeFeatures.CRIMSON_FUNGUS;
|
||||||
case CHORUS_PLANT -> EndFeatures.CHORUS_PLANT;
|
case CHORUS_PLANT -> EndFeatures.CHORUS_PLANT;
|
||||||
|
case MANGROVE -> TreeFeatures.MANGROVE;
|
||||||
|
case TALL_MANGROVE -> TreeFeatures.TALL_MANGROVE;
|
||||||
|
case CHERRY -> TreeFeatures.CHERRY;
|
||||||
case RANDOM -> createTreeFeatureGenerator(TreeGenerator.TreeType.values()[ThreadLocalRandom.current().nextInt(TreeGenerator.TreeType.values().length)]);
|
case RANDOM -> createTreeFeatureGenerator(TreeGenerator.TreeType.values()[ThreadLocalRandom.current().nextInt(TreeGenerator.TreeType.values().length)]);
|
||||||
default -> null;
|
default -> null;
|
||||||
};
|
};
|
||||||
|
@ -48,6 +48,8 @@
|
|||||||
import org.spongepowered.api.block.BlockSnapshot;
|
import org.spongepowered.api.block.BlockSnapshot;
|
||||||
import org.spongepowered.api.block.BlockType;
|
import org.spongepowered.api.block.BlockType;
|
||||||
import org.spongepowered.api.block.BlockTypes;
|
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.Command;
|
||||||
import org.spongepowered.api.command.CommandCause;
|
import org.spongepowered.api.command.CommandCause;
|
||||||
import org.spongepowered.api.command.CommandCompletion;
|
import org.spongepowered.api.command.CommandCompletion;
|
||||||
@ -67,6 +69,7 @@
|
|||||||
import org.spongepowered.api.event.network.ServerSideConnectionEvent;
|
import org.spongepowered.api.event.network.ServerSideConnectionEvent;
|
||||||
import org.spongepowered.api.registry.RegistryTypes;
|
import org.spongepowered.api.registry.RegistryTypes;
|
||||||
import org.spongepowered.api.scheduler.Task;
|
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.ServerLocation;
|
||||||
import org.spongepowered.api.world.server.ServerWorld;
|
import org.spongepowered.api.world.server.ServerWorld;
|
||||||
import org.spongepowered.math.vector.Vector3d;
|
import org.spongepowered.math.vector.Vector3d;
|
||||||
@ -376,6 +379,15 @@ public Actor wrapCommandCause(CommandCause cause) {
|
|||||||
if (rootCause instanceof ServerPlayer) {
|
if (rootCause instanceof ServerPlayer) {
|
||||||
return SpongeAdapter.adapt((ServerPlayer) rootCause);
|
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) {
|
if (rootCause instanceof Audience) {
|
||||||
return new SpongeCommandSender((Audience) rootCause);
|
return new SpongeCommandSender((Audience) rootCause);
|
||||||
}
|
}
|
||||||
|
@ -143,5 +143,7 @@ public void load() {
|
|||||||
|
|
||||||
extendedYLimit = node.node("compat", "extended-y-limit").getBoolean(false);
|
extendedYLimit = node.node("compat", "extended-y-limit").getBoolean(false);
|
||||||
setDefaultLocaleName(node.node("default-locale").getString(defaultLocaleName));
|
setDefaultLocaleName(node.node("default-locale").getString(defaultLocaleName));
|
||||||
|
|
||||||
|
commandBlockSupport = node.node("command-block-support").getBoolean(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user