Java tutorial
/* * Copyright (C) 2016 Leonardosc * * 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 2 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package io.github.bktlib.command; import static io.github.bktlib.command.UsageTarget.IN_GAME; import static io.github.bktlib.command.UsageTarget.NOT_IN_GAME; import java.util.Arrays; import java.util.Map; import java.util.Optional; import java.util.Set; import com.google.common.base.Strings; import io.github.bktlib.command.tabcompleter.TabCompleter; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import io.github.bktlib.command.annotation.Command; import io.github.bktlib.command.args.CommandArgs; import javax.annotation.Nonnull; public abstract class CommandBase { private static final String NOT_ALLOWED_INGAME = "cEste comando nao pode ser usado in-game."; private static final String ONLY_ALLOWED_INGAME = "cEste comando so pode ser usado in-game."; Command commandAnnotation; TabCompleter tabCompleter; Map<String, CommandBase> subCommands; CommandBase(final Command annotation) { commandAnnotation = annotation; subCommands = Maps.newHashMap(); } protected CommandBase() { commandAnnotation = Preconditions.checkNotNull(getClass().getAnnotation(Command.class), "Missing 'Command' annotation"); subCommands = Maps.newHashMap(); } /** * @return Nome desse comando */ public String getName() { return commandAnnotation.name(); } /** * @return Um {@link Set} Contendo as 'aliases' desse comando */ public Set<String> getAliases() { return Sets.newHashSet(commandAnnotation.aliases()); } /** * @return Um {@link Set} Contendo os sub comandos desse comando */ public Set<CommandBase> getSubCommands() { return Sets.newHashSet(subCommands.values()); } /** * @return Retorna o {@link Command#usageTarget() UsageTarget} desse * comando. * @see UsageTarget */ public UsageTarget getUsageTarget() { return commandAnnotation.usageTarget(); } /** * @return A {@link Command#description() descrio} desse commando */ public Optional<String> getDescription() { return Optional.ofNullable(Strings.emptyToNull(commandAnnotation.description())); } /** * @return A {@link Command#permission() permisso} desse commando */ public Optional<String> getPermission() { return Optional.ofNullable(Strings.emptyToNull(commandAnnotation.permission())); } /** * @return A {@link Command#usage() usage} desse commando */ public Optional<String> getUsage() { return Optional.ofNullable(Strings.emptyToNull(commandAnnotation.usage())); } /** * Retorna a anotao {@link Command} desse comando, essa anotao * obrigatoria em todos os comandos. * * @return A anotao {@link Command} */ public Command getAnnotation() { return commandAnnotation; } /** * Esse mtodo chamado quando o comando executado. * * @param src A {@link CommandSource fonte} do comando, o jogador/coisa que * enviou esse comando. * @param args Os argumentos passados ao executar esse comando, por exeplo, * ao executar /give jogador DIAMOND 1, os argumentos seriam * {@literal {jogador, DIAMOND, 1}} * @return O {@link CommandResult} resultado da execuo do comando. * @see CommandSource * @see CommandResult */ public abstract CommandResult onExecute(@Nonnull CommandSource src, @Nonnull CommandArgs args); /** * Mtodo usado internamente para fazer verificaes, chamar sub comandos * etc. * <p> * Caso tudo ocorra como desejado ele ir chamar o mtodo * {@link #onExecute(CommandSource, CommandArgs)} */ void execute(final CommandSender sender, final String[] rawArgs) { final UsageTarget target = getUsageTarget(); if (target == IN_GAME && !(sender instanceof Player)) { sender.sendMessage(ONLY_ALLOWED_INGAME); } else if (target == NOT_IN_GAME && (sender instanceof Player)) { sender.sendMessage(NOT_ALLOWED_INGAME); } else { final CommandSource src = CommandSource.from(sender); try { if (rawArgs.length > 0) { final CommandBase subCmd = subCommands.get(rawArgs[0].toLowerCase()); if (subCmd != null) { subCmd.execute(sender, Arrays.copyOfRange(rawArgs, 1, rawArgs.length)); return; } } final CommandResult result = onExecute(src, CommandArgs.of(rawArgs)); if (result == null) { throw new RuntimeException("\'" + this + "' returned null result."); } if (result == CommandResult.success()) return; if (result == CommandResult.showUsage()) { final String msg = result.getType().getColor() + "Use: /" + getName() + " " + getUsage().orElse(""); sender.sendMessage(msg); return; } result.getMessage().ifPresent(sender::sendMessage); } catch (CommandException ex) { if (ex.getResult() == CommandResult.success()) return; ex.getResult().getMessage().ifPresent(sender::sendMessage); } } } @Override public String toString() { return Objects.toStringHelper(this).add("name", getName()).toString(); } }