First attempt at integrating Piston as the only command system

This commit is contained in:
Kenzie Togami
2019-04-15 01:21:15 -07:00
parent da35b3c174
commit 267ccf2298
28 changed files with 493 additions and 389 deletions

View File

@ -39,7 +39,7 @@ import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.CommandManager;
import com.sk89q.worldedit.extension.platform.PlatformCommandMananger;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.BlockPattern;
@ -67,6 +67,7 @@ import com.sk89q.worldedit.util.formatting.component.CommandUsageBox;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockTypes;
import org.enginehub.piston.CommandManager;
import java.util.ArrayList;
import java.util.List;
@ -598,7 +599,10 @@ public class UtilityCommands {
}
public static void help(CommandContext args, WorldEdit we, Actor actor) {
CommandCallable callable = we.getPlatformManager().getCommandManager().getDispatcher();
CommandManager manager = we.getPlatformManager().getPlatformCommandMananger().getCommandManager();
// TODO this will be implemented as a special utility in the manager
/*
int page = 0;
final int perPage = actor instanceof Player ? 8 : 20; // More pages for console
@ -626,15 +630,15 @@ public class UtilityCommands {
for (int i = 0; i < effectiveLength; i++) {
String command = args.getString(i);
if (callable instanceof Dispatcher) {
if (manager instanceof Dispatcher) {
// Chop off the beginning / if we're are the root level
if (isRootLevel && command.length() > 1 && command.charAt(0) == '/') {
command = command.substring(1);
}
CommandMapping mapping = detectCommand((Dispatcher) callable, command, isRootLevel);
CommandMapping mapping = detectCommand((Dispatcher) manager, command, isRootLevel);
if (mapping != null) {
callable = mapping.getCallable();
manager = mapping.getCallable();
} else {
if (isRootLevel) {
actor.printError(String.format("The command '%s' could not be found.", args.getString(i)));
@ -656,12 +660,12 @@ public class UtilityCommands {
}
// Create the message
if (callable instanceof Dispatcher) {
Dispatcher dispatcher = (Dispatcher) callable;
if (manager instanceof Dispatcher) {
Dispatcher dispatcher = (Dispatcher) manager;
// Get a list of aliases
List<CommandMapping> aliases = new ArrayList<>(dispatcher.getCommands());
aliases.sort(new PrimaryAliasComparator(CommandManager.COMMAND_CLEAN_PATTERN));
aliases.sort(new PrimaryAliasComparator(PlatformCommandMananger.COMMAND_CLEAN_PATTERN));
// Calculate pagination
int offset = perPage * page;
@ -698,9 +702,10 @@ public class UtilityCommands {
actor.printRaw(ColorCodeBuilder.asColorCodes(box));
} else {
CommandUsageBox box = new CommandUsageBox(callable, Joiner.on(" ").join(visited));
CommandUsageBox box = new CommandUsageBox(manager, Joiner.on(" ").join(visited));
actor.printRaw(ColorCodeBuilder.asColorCodes(box));
}
*/
}
}

View File

@ -113,7 +113,7 @@ public class WorldEditCommands {
actor.checkPermission("worldedit.report.pastebin");
ActorCallbackPaste.pastebin(
we.getSupervisor(), actor, result, "WorldEdit report: %s.report",
WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter()
WorldEdit.getInstance().getPlatformManager().getPlatformCommandMananger().getExceptionConverter()
);
}
}

View File

@ -0,0 +1,31 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.argument;
import org.enginehub.piston.InjectedValueAccess;
/**
* Key-interface for {@link InjectedValueAccess} for the String arguments.
*/
public interface Arguments {
String get();
}

View File

@ -0,0 +1,87 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.argument;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Player;
import java.util.concurrent.locks.StampedLock;
/**
* Lazily-created {@link EditSession}.
*/
public class EditSessionHolder {
private final StampedLock lock = new StampedLock();
private final WorldEdit worldEdit;
private final Player player;
public EditSessionHolder(WorldEdit worldEdit, Player player) {
this.worldEdit = worldEdit;
this.player = player;
}
private EditSession session;
/**
* Get the session, but does not create it if it doesn't exist.
*/
public EditSession getSession() {
long stamp = lock.tryOptimisticRead();
EditSession result = session;
if (!lock.validate(stamp)) {
stamp = lock.readLock();
try {
result = session;
} finally {
lock.unlockRead(stamp);
}
}
return result;
}
public EditSession getOrCreateSession() {
// use the already-generated result if possible
EditSession result = getSession();
if (result != null) {
return result;
}
// otherwise, acquire write lock
long stamp = lock.writeLock();
try {
// check session field again -- maybe another writer hit it in between
result = session;
if (result != null) {
return result;
}
// now we can do the actual creation
LocalSession localSession = worldEdit.getSessionManager().get(player);
EditSession editSession = localSession.createEditSession(player);
editSession.enableStandardMode();
localSession.tellVersion(player);
return session = editSession;
} finally {
lock.unlockWrite(stamp);
}
}
}

View File

@ -94,7 +94,7 @@ public class SelectionCommand extends SimpleCommand<Operation> {
return operation;
} catch (IncompleteRegionException e) {
WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter().convert(e);
WorldEdit.getInstance().getPlatformManager().getPlatformCommandMananger().getExceptionConverter().convert(e);
return null;
}
} else {

View File

@ -77,7 +77,7 @@ public class ShapedBrushCommand extends SimpleCommand<Object> {
tool.setFill(null);
tool.setBrush(new OperationFactoryBrush(factory, regionFactory, session), permission);
} catch (MaxBrushRadiusException | InvalidToolBindException e) {
WorldEdit.getInstance().getPlatformManager().getCommandManager().getExceptionConverter().convert(e);
WorldEdit.getInstance().getPlatformManager().getPlatformCommandMananger().getExceptionConverter().convert(e);
}
player.print("Set brush to " + factory);

View File

@ -34,15 +34,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
@NonnullByDefault
public class CommandPermissionsConditionGenerator implements CommandConditionGenerator {
private static final Key<Actor> ACTOR_KEY = Key.get(Actor.class);
@Override
public Command.Condition generateCondition(Method commandMethod) {
CommandPermissions annotation = commandMethod.getAnnotation(CommandPermissions.class);
checkNotNull(annotation, "Annotation is missing from commandMethod");
Set<String> permissions = ImmutableSet.copyOf(annotation.value());
return p -> p.injectedValue(ACTOR_KEY)
.map(actor -> permissions.stream().anyMatch(actor::hasPermission))
.orElse(false);
return new PermissionCondition(permissions);
}
}

View File

@ -22,9 +22,9 @@ package com.sk89q.worldedit.command.util;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.util.concurrent.FutureCallback;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.command.parametric.ExceptionConverter;
import org.enginehub.piston.exception.CommandException;
import javax.annotation.Nullable;

View File

@ -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 Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.util;
import com.google.inject.Key;
import com.sk89q.worldedit.extension.platform.Actor;
import org.enginehub.piston.Command;
import org.enginehub.piston.CommandParameters;
import java.util.Set;
public final class PermissionCondition implements Command.Condition {
private static final Key<Actor> ACTOR_KEY = Key.get(Actor.class);
private final Set<String> permissions;
PermissionCondition(Set<String> permissions) {
this.permissions = permissions;
}
public Set<String> getPermissions() {
return permissions;
}
@Override
public boolean satisfied(CommandParameters parameters) {
return parameters.injectedValue(ACTOR_KEY)
.map(actor -> permissions.stream().anyMatch(actor::hasPermission))
.orElse(false);
}
}