package com.sk89q.commandbook; import com.sk89q.bukkit.util.DynamicPluginCommand; import com.sk89q.commandbook.commands.PaginatedResult; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.util.ReflectionUtil; import com.sk89q.util.yaml.YAMLFormat; import com.sk89q.util.yaml.YAMLProcessor; import com.zachsthings.libcomponents.ComponentInformation; import com.zachsthings.libcomponents.bukkit.BukkitComponent; import com.zachsthings.libcomponents.config.ConfigurationBase; import com.zachsthings.libcomponents.config.Setting; import org.bukkit.ChatColor; import org.bukkit.command.CommandMap; import org.bukkit.command.CommandSender; import org.bukkit.command.PluginCommand; import org.bukkit.command.SimpleCommandMap; import org.bukkit.command.defaults.VanillaCommand; import java.io.File; import java.io.IOException; import java.util.*; import static com.sk89q.commandbook.util.ChatUtil.replaceColorMacros; /** * Simple but very messy Help component. */ @ComponentInformation(friendlyName = "Help", desc = "Provides help on various command actions") public class HelpComponent extends BukkitComponent { private YAMLProcessor help; private final Map<String, String[]> messages = new HashMap<String, String[]>(); private LocalConfiguration config; @Override public void enable() { config = configure(new LocalConfiguration()); File helpFile = new File(CommandBook.inst().getDataFolder(), config.helpFile); if (!helpFile.getParentFile().exists() || !helpFile.getParentFile().isDirectory()) helpFile.getParentFile().mkdirs(); if (!helpFile.exists() || !helpFile.isFile()) try { helpFile.createNewFile(); } catch (IOException ignored) {} help = new YAMLProcessor(helpFile, true, YAMLFormat.EXTENDED); reloadMessages(); registerCommands(HelpCommands.class); } @Override public void reload() { super.reload(); reloadMessages(); configure(config); } private static class LocalConfiguration extends ConfigurationBase { @Setting("help-file") public String helpFile = "help.yml"; @Setting("command-help") public boolean commandHelp = true; } private static final String demoHelpMessage = "This is a component to provide help for servers\n" + "`r/help -c <commandname>`w gives help for a command\n" + "`r/help <topic>`w gives help for a topic from a list specified by the server admin."; private boolean reloadMessages() { try { help.load(); } catch (IOException e) { return false; } List<String> keys = help.getKeys("topics"); if (keys == null) { help.setProperty("topics.help", demoHelpMessage); keys = new ArrayList<String>(); keys.add("help"); help.save(); } for (String key : keys) { String information = help.getString("topics." + key); if (information != null && information.trim().length() != 0) { information = replaceColorMacros(information); String[] split = information.split("\\n"); for (int i = 0; i < split.length; i++) { split[i] = split[i].replaceAll("[\\r\\n]", ""); } messages.put(key.toLowerCase(), split); } } return true; } public void printTopics(CommandSender sender, String prefix) { StringBuilder sb = new StringBuilder(ChatColor.YELLOW.toString()); if (prefix != null && !prefix.isEmpty()) sb.append(prefix).append(" "); sb.append("Available options are: "); boolean first = true; int count = 0; for (String key : messages.keySet()) { if (!CommandBook.inst().hasPermission(sender, "commandbook.help.topic." + key)) { continue; } if (!first) { sb.append(ChatColor.YELLOW).append(", "); } sb.append(ChatColor.LIGHT_PURPLE).append(key); first = false; ++count; } if (count <= 0) { sender.sendMessage(ChatColor.YELLOW + "No available help options!"); } else { sender.sendMessage(sb.toString()); } } public org.bukkit.command.Command getCommand(String name) { CommandMap commandMap = ReflectionUtil.getField(CommandBook.server().getPluginManager(), "commandMap"); if (commandMap == null) { return null; } return commandMap.getCommand(name); } public Collection<org.bukkit.command.Command> getServerCommands() { CommandMap commandMap = ReflectionUtil.getField(CommandBook.server().getPluginManager(), "commandMap"); if (commandMap == null) { return Collections.emptySet(); } Set<org.bukkit.command.Command> cmds = new HashSet<org.bukkit.command.Command>(); cmds.addAll(((SimpleCommandMap)commandMap).getCommands()); return cmds; } public void printCommandHelp(CommandSender sender, org.bukkit.command.Command cmd) { sender.sendMessage(ChatColor.YELLOW + "Command: " + cmd.getName()); final String aliases = cmd.getAliases().toString().replaceAll("\\[(.*)\\]", "$1"); if (aliases.length() > 0) { sender.sendMessage(ChatColor.YELLOW + "Aliases: " + aliases); } sender.sendMessage(ChatColor.YELLOW + "Description: " + cmd.getDescription()); sender.sendMessage(ChatColor.YELLOW + "Usage: " + cmd.getUsage()); if (cmd instanceof PluginCommand) { sender.sendMessage(ChatColor.YELLOW + "Plugin: " + ((PluginCommand)cmd).getPlugin().getDescription().getName()); } else if (cmd instanceof DynamicPluginCommand) { sender.sendMessage(ChatColor.YELLOW + "Owner: " + ((DynamicPluginCommand) cmd).getOwner().getClass().getSimpleName()); } else if (cmd instanceof VanillaCommand) { sender.sendMessage(ChatColor.YELLOW + "Vanilla command"); } } public class HelpCommands { @Command(aliases = "help", usage = "[-p page] [topic]", desc = "Provides help for the server!", flags = "cp:", min = 0, max = 1) @CommandPermissions({"commandbook.help", "commandbook.help.command", "commandbook.help.topic"}) public void help(CommandContext args, CommandSender sender) throws CommandException { if (args.hasFlag('c')) { // Looking up command help if (!config.commandHelp) { throw new CommandException("Help for commands is not enabled!"); } if (args.argsLength() == 0) { Collection<org.bukkit.command.Command> serverCommands = getServerCommands(); for (Iterator<org.bukkit.command.Command> i = serverCommands.iterator(); i.hasNext();) { final String permission = i.next().getPermission(); if (!(permission == null || permission.length() == 0 || CommandBook.inst().hasPermission(sender, permission))) { i.remove(); } } new PaginatedResult<org.bukkit.command.Command>("Usage - Description") { @Override public String format(org.bukkit.command.Command entry) { return entry.getUsage() + " - " + entry.getDescription(); } }.display(sender, serverCommands, args.getFlagInteger('p', 1)); } else { org.bukkit.command.Command cmd = getCommand(args.getString(0)); if (cmd == null) { throw new CommandException("Unknown command '" + args.getString(0) + "'; no help available"); } else { CommandBook.inst().checkPermission(sender, "commandbook.help.command." + cmd.getName()); printCommandHelp(sender, cmd); } } } else if (args.argsLength() == 0) { printTopics(sender, "No help option specified."); } else { if (!messages.containsKey(args.getString(0).toLowerCase())) { printTopics(sender, "Unknown topic specified."); } else { String chosen = args.getString(0); CommandBook.inst().checkPermission(sender, "commandbook.help.topic." + chosen); String[] lines = messages.get(chosen.toLowerCase()); sender.sendMessage(ChatColor.YELLOW + "Help about " + chosen + ":"); for (String line : lines) { sender.sendMessage(ChatColor.AQUA + line.replaceAll(ChatColor.WHITE.toString(), ChatColor.AQUA.toString())); } } } } } }