1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-12-13 11:40:29 +00:00

Various improvements to command system

- Ensure usage is consistent
 - Allow computer selectors to return multiple values
 - Fix commands being marked as usable when it isn't
 - Add /computercraft turn-on, a counter to /computercraft shutdown
This commit is contained in:
SquidDev 2018-02-13 11:45:13 +00:00
parent 5ae38a3f18
commit 4c14431a3d
4 changed files with 80 additions and 40 deletions

View File

@ -1,6 +1,6 @@
package dan200.computercraft.shared.command;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.computer.Computer;
@ -40,8 +40,8 @@ public final class CommandComputerCraft extends CommandDelegate
root.register( new SubCommandBase(
"dump", "[id]", "Display the status of computers.", UserLevel.OWNER_OP,
"Display the status of all computers or specific information about one computer. You can either specify the computer's instance " +
"id (e.g. 123) or computer id (e.g #123)."
"Display the status of all computers or specific information about one computer. You can specify the " +
"computer's instance id (e.g. 123), computer id (e.g #123) or label (e.g. \"@My Computer\")."
)
{
@Override
@ -126,25 +126,25 @@ public final class CommandComputerCraft extends CommandDelegate
{
return arguments.size() == 1
? ComputerSelector.completeComputer( arguments.get( 0 ) )
: Collections.<String>emptyList();
: Collections.emptyList();
}
} );
root.register( new SubCommandBase(
"shutdown", "[ids...]", "Shutdown computers remotely.", UserLevel.OWNER_OP,
"Shutdown the listed computers or all if none are specified. You can either specify the computer's instance " +
"id (e.g. 123) or computer id (e.g #123)."
"Shutdown the listed computers or all if none are specified. You can specify the computer's instance id " +
"(e.g. 123), computer id (e.g #123) or label (e.g. \"@My Computer\")."
)
{
@Override
public void execute( @Nonnull CommandContext context, @Nonnull List<String> arguments ) throws CommandException
{
List<ServerComputer> computers = Lists.newArrayList();
Set<ServerComputer> computers = Sets.newHashSet();
if( arguments.size() > 0 )
{
for( String arg : arguments )
{
computers.add( ComputerSelector.getComputer( arg ) );
computers.addAll( ComputerSelector.getComputers( arg ) );
}
}
else
@ -166,7 +166,48 @@ public final class CommandComputerCraft extends CommandDelegate
public List<String> getCompletion( @Nonnull CommandContext context, @Nonnull List<String> arguments )
{
return arguments.size() == 0
? Collections.<String>emptyList()
? Collections.emptyList()
: ComputerSelector.completeComputer( arguments.get( arguments.size() - 1 ) );
}
} );
root.register( new SubCommandBase(
"turn-on", "ids...", "Turn computers on remotely.", UserLevel.OWNER_OP,
"Turn on the listed computers. You can specify the computer's instance id (e.g. 123), computer id (e.g #123) " +
"or label (e.g. \"@My Computer\")."
)
{
@Override
public void execute( @Nonnull CommandContext context, @Nonnull List<String> arguments ) throws CommandException
{
Set<ServerComputer> computers = Sets.newHashSet();
if( arguments.size() > 0 )
{
for( String arg : arguments )
{
computers.addAll( ComputerSelector.getComputers( arg ) );
}
}
else
{
computers.addAll( ComputerCraft.serverComputerRegistry.getComputers() );
}
int on = 0;
for( ServerComputer computer : computers )
{
if( !computer.isOn() ) on++;
computer.turnOn();
}
context.getSender().sendMessage( text( "Turned on " + on + " / " + computers.size() + " computers" ) );
}
@Nonnull
@Override
public List<String> getCompletion( @Nonnull CommandContext context, @Nonnull List<String> arguments )
{
return arguments.size() == 0
? Collections.emptyList()
: ComputerSelector.completeComputer( arguments.get( arguments.size() - 1 ) );
}
} );
@ -222,7 +263,7 @@ public final class CommandComputerCraft extends CommandDelegate
{
return arguments.size() == 1
? ComputerSelector.completeComputer( arguments.get( 0 ) )
: Collections.<String>emptyList();
: Collections.emptyList();
}
} );

View File

@ -12,7 +12,7 @@ import java.util.function.Predicate;
public final class ComputerSelector
{
private static ServerComputer getComputer( Predicate<ServerComputer> predicate, String kind ) throws CommandException
private static List<ServerComputer> getComputers( Predicate<ServerComputer> predicate, String selector ) throws CommandException
{
// We copy it to prevent concurrent modifications.
List<ServerComputer> computers = Lists.newArrayList( ComputerCraft.serverComputerRegistry.getComputers() );
@ -22,41 +22,40 @@ public final class ComputerSelector
if( predicate.test( searchComputer ) ) candidates.add( searchComputer );
}
if( candidates.size() == 0 )
if( candidates.isEmpty() )
{
throw new CommandException( "No such computer for " + kind );
}
else if( candidates.size() == 1 )
{
return candidates.get( 0 );
throw new CommandException( "No computer matching " + selector );
}
else
{
StringBuilder builder = new StringBuilder( "Multiple computers with " )
.append( kind ).append( " (instances " );
return candidates;
}
}
boolean first = true;
for( ServerComputer computer : candidates )
public static ServerComputer getComputer( String selector ) throws CommandException
{
List<ServerComputer> computers = getComputers( selector );
if( computers.size() == 1 )
{
return computers.get( 0 );
}
else
{
StringBuilder builder = new StringBuilder( "Multiple computers matching " )
.append( selector ).append( " (instances " );
for( int i = 0; i < computers.size(); i++ )
{
if( first )
{
first = false;
}
else
{
builder.append( ", " );
}
builder.append( computer.getInstanceID() );
if( i > 1 ) builder.append( ", " );
builder.append( computers.get( i ).getInstanceID() );
}
builder.append( ")" );
throw new CommandException( builder.toString() );
}
}
public static ServerComputer getComputer( String selector ) throws CommandException
public static List<ServerComputer> getComputers( String selector ) throws CommandException
{
if( selector.length() > 0 && selector.charAt( 0 ) == '#' )
{
@ -72,17 +71,17 @@ public final class ComputerSelector
throw new CommandException( "'" + selector + "' is not a valid number" );
}
return getComputer( x -> x.getID() == id, "id " + id );
return getComputers( x -> x.getID() == id, selector );
}
else if( selector.length() > 0 && selector.charAt( 0 ) == '@' )
{
String label = selector.substring( 1 );
return getComputer( x -> Objects.equals( label, x.getLabel() ), "label '" + label + "'" );
return getComputers( x -> Objects.equals( label, x.getLabel() ), selector );
}
else if( selector.length() > 0 && selector.charAt( 0 ) == '~' )
{
String familyName = selector.substring( 1 );
return getComputer( x -> x.getFamily().name().equalsIgnoreCase( familyName ), "family '" + familyName + "'" );
return getComputers( x -> x.getFamily().name().equalsIgnoreCase( familyName ), selector );
}
else
{
@ -103,7 +102,7 @@ public final class ComputerSelector
}
else
{
return computer;
return Collections.singletonList( computer );
}
}
}

View File

@ -36,7 +36,7 @@ public class CommandDelegate implements ICommand
@Override
public String getUsage( @Nonnull ICommandSender sender )
{
return "/" + command.getName() + " " + command.getUsage( new CommandContext( sender.getServer(), sender, command ) );
return new CommandContext( sender.getServer(), sender, command ).getFullUsage();
}
@Nonnull

View File

@ -86,7 +86,7 @@ public class CommandRoot implements ISubCommand
{
for( ISubCommand command : subCommands.values() )
{
if( command.checkPermission( context ) ) return true;
if( !(command instanceof SubCommandHelp) && command.checkPermission( context ) ) return true;
}
return false;
}
@ -108,7 +108,7 @@ public class CommandRoot implements ISubCommand
ISubCommand command = subCommands.get( arguments.get( 0 ) );
if( command == null || !command.checkPermission( context ) )
{
throw new CommandException( getName() + " " + getUsage( context ) );
throw new CommandException( context.getFullUsage() );
}
command.execute( context.enter( command ), arguments.subList( 1, arguments.size() ) );