Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-12-25 10:30:04 +01:00
Updated //help with colors and sub-command support.
Dieser Commit ist enthalten in:
Ursprung
d1f5beb961
Commit
1e2523ddcb
@ -19,9 +19,19 @@
|
||||
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.*;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.minecraft.util.commands.Logging;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.EntityType;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.LocalWorld.KillFlags;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
@ -29,16 +39,23 @@ import com.sk89q.worldedit.patterns.Pattern;
|
||||
import com.sk89q.worldedit.patterns.SingleBlockPattern;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.command.CommandCallable;
|
||||
import com.sk89q.worldedit.util.command.CommandMapping;
|
||||
import com.sk89q.worldedit.util.command.Description;
|
||||
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||
import com.sk89q.worldedit.util.command.PrimaryAliasComparator;
|
||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||
import com.sk89q.worldedit.util.formatting.Cmd;
|
||||
import com.sk89q.worldedit.util.formatting.ColorCodeBuilder;
|
||||
import com.sk89q.worldedit.util.formatting.CommandListBox;
|
||||
import com.sk89q.worldedit.util.formatting.Style;
|
||||
import com.sk89q.worldedit.util.formatting.StyledFragment;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT;
|
||||
|
||||
@ -497,59 +514,158 @@ public class UtilityCommands {
|
||||
help(args, we, actor);
|
||||
}
|
||||
|
||||
public static void help(CommandContext args, WorldEdit we, Actor actor) {
|
||||
final Dispatcher dispatcher = we.getPlatformManager().getCommandManager().getDispatcher();
|
||||
private static CommandMapping detectCommand(Dispatcher dispatcher, String command, boolean isRootLevel) {
|
||||
CommandMapping mapping;
|
||||
|
||||
if (args.argsLength() == 0) {
|
||||
SortedSet<String> commands = new TreeSet<String>(new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
final int ret = o1.replaceAll("/", "").compareToIgnoreCase(o2.replaceAll("/", ""));
|
||||
if (ret == 0) {
|
||||
return o1.compareToIgnoreCase(o2);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
});
|
||||
commands.addAll(dispatcher.getPrimaryAliases());
|
||||
// First try the command as entered
|
||||
mapping = dispatcher.get(command);
|
||||
if (mapping != null) {
|
||||
return mapping;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (String command : commands) {
|
||||
if (!first) {
|
||||
sb.append(", ");
|
||||
}
|
||||
|
||||
sb.append('/');
|
||||
sb.append(command);
|
||||
first = false;
|
||||
// Then if we're looking at root commands and the user didn't use
|
||||
// any slashes, let's try double slashes and then single slashes.
|
||||
// However, be aware that there exists different single slash
|
||||
// and double slash commands in WorldEdit
|
||||
if (isRootLevel && !command.contains("/")) {
|
||||
mapping = dispatcher.get("//" + command);
|
||||
if (mapping != null) {
|
||||
return mapping;
|
||||
}
|
||||
|
||||
actor.print(sb.toString());
|
||||
|
||||
return;
|
||||
mapping = dispatcher.get("/" + command);
|
||||
if (mapping != null) {
|
||||
return mapping;
|
||||
}
|
||||
}
|
||||
|
||||
String command = args.getJoinedStrings(0).toLowerCase().replaceAll("^/", "");
|
||||
CommandMapping mapping = dispatcher.get(command);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mapping == null) {
|
||||
actor.printError("Unknown command '" + command + "'.");
|
||||
return;
|
||||
public static void help(CommandContext args, WorldEdit we, Actor actor) {
|
||||
CommandCallable callable = we.getPlatformManager().getCommandManager().getDispatcher();
|
||||
|
||||
int page = 0;
|
||||
final int perPage = actor instanceof Player ? 8 : 20; // More pages for console
|
||||
int effectiveLength = args.argsLength();
|
||||
|
||||
// Detect page from args
|
||||
try {
|
||||
if (args.argsLength() > 0) {
|
||||
page = args.getInteger(args.argsLength() - 1);
|
||||
if (page <= 0) {
|
||||
page = 1;
|
||||
} else {
|
||||
page--;
|
||||
}
|
||||
|
||||
effectiveLength--;
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
|
||||
Description description = mapping.getDescription();
|
||||
boolean isRootLevel = true;
|
||||
List<String> visited = new ArrayList<String>();
|
||||
|
||||
if (description.getUsage() != null) {
|
||||
actor.printDebug("Usage: " + description.getUsage());
|
||||
// Drill down to the command
|
||||
for (int i = 0; i < effectiveLength; i++) {
|
||||
String command = args.getString(i);
|
||||
|
||||
if (callable 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);
|
||||
if (mapping != null) {
|
||||
callable = mapping.getCallable();
|
||||
} else {
|
||||
if (isRootLevel) {
|
||||
actor.printError(String.format("The command '%s' could not be found.", args.getString(i)));
|
||||
return;
|
||||
} else {
|
||||
actor.printError(String.format("The sub-command '%s' under '%s' could not be found.",
|
||||
command, Joiner.on(" ").join(visited)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
visited.add(args.getString(i));
|
||||
isRootLevel = false;
|
||||
} else {
|
||||
actor.printError(String.format("'%s' has no sub-commands. (Maybe '%s' is for a parameter?)",
|
||||
Joiner.on(" ").join(visited), command));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (description.getHelp() != null) {
|
||||
actor.print(description.getHelp());
|
||||
} else if (description.getShortDescription() != null) {
|
||||
actor.print(description.getShortDescription());
|
||||
// Create the message
|
||||
if (callable instanceof Dispatcher) {
|
||||
Dispatcher dispatcher = (Dispatcher) callable;
|
||||
|
||||
// Get a list of aliases
|
||||
List<CommandMapping> aliases = new ArrayList<CommandMapping>(dispatcher.getCommands());
|
||||
Collections.sort(aliases, PrimaryAliasComparator.INSTANCE);
|
||||
|
||||
// Calculate pagination
|
||||
int offset = perPage * page;
|
||||
int pageTotal = (int) Math.ceil(aliases.size() / (double) perPage);
|
||||
|
||||
// Box
|
||||
CommandListBox box = new CommandListBox(String.format("Help: page %d/%d ", page + 1, pageTotal));
|
||||
StyledFragment contents = box.getContents();
|
||||
StyledFragment tip = contents.createFragment(Style.GRAY);
|
||||
|
||||
if (offset >= aliases.size()) {
|
||||
tip.createFragment(Style.RED).append(String.format("There is no page %d (total number of pages is %d).", page + 1, pageTotal)).newLine();
|
||||
} else {
|
||||
List<CommandMapping> list = aliases.subList(offset, Math.min(offset + perPage, aliases.size()));
|
||||
|
||||
tip.append("Type ");
|
||||
tip.append(new Cmd().append("//help ").append("<command> [<page>]"));
|
||||
tip.append(" for more information.").newLine();
|
||||
|
||||
// Add each command
|
||||
for (CommandMapping mapping : list) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (isRootLevel) {
|
||||
builder.append("/");
|
||||
}
|
||||
if (!visited.isEmpty()) {
|
||||
builder.append(Joiner.on(" ").join(visited));
|
||||
builder.append(" ");
|
||||
}
|
||||
builder.append(mapping.getPrimaryAlias());
|
||||
box.appendCommand(builder.toString(), mapping.getDescription().getShortDescription());
|
||||
}
|
||||
}
|
||||
|
||||
actor.printRaw(ColorCodeBuilder.asColorCodes(box));
|
||||
} else {
|
||||
actor.print("No further help is available.");
|
||||
CommandListBox box = new CommandListBox(String.format("Help: %s", Joiner.on(" ").join(visited)));
|
||||
StyledFragment contents = box.getContents();
|
||||
|
||||
Description description = callable.getDescription();
|
||||
|
||||
if (description.getUsage() != null) {
|
||||
contents.createFragment(Style.YELLOW).append("Usage: ");
|
||||
contents.append(description.getUsage());
|
||||
} else {
|
||||
contents.createFragment(Style.GRAY).append("Usage information is not available.");
|
||||
}
|
||||
|
||||
contents.newLine();
|
||||
|
||||
if (description.getHelp() != null) {
|
||||
contents.createFragment(Style.YELLOW_DARK).append(description.getHelp());
|
||||
} else if (description.getShortDescription() != null) {
|
||||
contents.createFragment(Style.YELLOW_DARK).append(description.getShortDescription());
|
||||
} else {
|
||||
contents.createFragment(Style.GRAY).append("No further help is available.");
|
||||
}
|
||||
|
||||
actor.printRaw(ColorCodeBuilder.asColorCodes(box));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.util.command;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Compares the primary aliases of two {@link CommandMapping} using
|
||||
* {@link String#compareTo(String)}.
|
||||
*/
|
||||
public final class PrimaryAliasComparator implements Comparator<CommandMapping> {
|
||||
|
||||
/**
|
||||
* An instance of this class.
|
||||
*/
|
||||
public static final PrimaryAliasComparator INSTANCE = new PrimaryAliasComparator();
|
||||
|
||||
private PrimaryAliasComparator() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(CommandMapping o1, CommandMapping o2) {
|
||||
return o1.getPrimaryAlias().compareTo(o2.getPrimaryAlias());
|
||||
}
|
||||
|
||||
}
|
34
src/main/java/com/sk89q/worldedit/util/formatting/Cmd.java
Normale Datei
34
src/main/java/com/sk89q/worldedit/util/formatting/Cmd.java
Normale Datei
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.util.formatting;
|
||||
|
||||
/**
|
||||
* Represents a fragment representing a command that is to be typed.
|
||||
*/
|
||||
public class Cmd extends StyledFragment {
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*/
|
||||
public Cmd() {
|
||||
super(Style.CYAN);
|
||||
}
|
||||
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren