/* * This file is part of Skript. * * Skript 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 3 of the License, or * (at your option) any later version. * * Skript 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 Skript. If not, see <http://www.gnu.org/licenses/>. * * * Copyright 2011-2014 Peter Güttinger * */ package ch.njol.skript; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Locale; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import ch.njol.skript.config.Config; import ch.njol.skript.config.EntryNode; import ch.njol.skript.config.InvalidNode; import ch.njol.skript.config.Node; import ch.njol.skript.config.SectionNode; import ch.njol.skript.config.VoidNode; import ch.njol.util.Pair; public class PlayerCommand implements CommandExecutor { public Config config = null; public Node node = null; public boolean answered = false; public boolean answer = false; private Thread waiting = null; @Override public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args) { if (!answered && args.length == 1 && (args[0].equalsIgnoreCase("y") || args[0].equalsIgnoreCase("n"))) { answer = args[0].equalsIgnoreCase("y"); answered = true; waiting.notify(); return true; } if (waiting != null && waiting.isAlive()) waiting.interrupt(); waiting = new Thread(new Runnable() { @Override public void run() { final ArrayList<Pair<String, String>> co = parseCommandOptions(args); final String action = args[0].toLowerCase(); final StringBuilder b = new StringBuilder(); for (int i = 1; i < args.length; i++) { if (args[i].startsWith("--")) break; b.append(b.length() == 0 ? "" : " "); b.append(args[i]); } final String actionParams = b.toString(); Verbosity v = Verbosity.LOW; answered = false; answer = false; boolean ok = false; boolean save = false; // --- FLAGS --- for (final Pair<String, String> p : co) { ok = false; if (p.first.equals("c") || p.first.equals("config")) { if (p.second.isEmpty() || p.second.equals("main")) { config = Skript.mainConfig; node = Skript.mainConfig.getMainNode(); sender.sendMessage("selectend main config"); ok = true; } if (!ok) { for (final Config c : Skript.configs) { if (c.getFileName().substring(0, c.getFileName().lastIndexOf(".cfg")).equalsIgnoreCase(p.second)) { config = c; ok = true; break; } } } if (!ok) { final File f = new File(Skript.skript.getDataFolder(), Skript.TRIGGERFILEFOLDER + File.pathSeparator + "-" + p.second + ".cfg"); if (f.exists()) { if (!answered) { sender.sendMessage(p.second + " is currently disabled and is therefore not loaded."); sender.sendMessage("Do you want to load it (this will not enable it)?"); } if (waitForAnswer()) { try { sender.sendMessage("loading..."); Skript.configs.add(config = new Config(f, true, ":")); node = config.getMainNode(); sender.sendMessage("loaded & selected " + f.getName()); } catch (final IOException e) { sender.sendMessage("unable to load " + f.getName()); } } ok = true; } } if (!ok) { if (!answered) sender.sendMessage("file not found. Do you want to create it?"); if (waitForAnswer()) { try { final File f = new File(Skript.skript.getDataFolder(), Skript.TRIGGERFILEFOLDER + File.pathSeparator + p.second); Skript.configs.add(config = new Config(f, true, ":")); node = config.getMainNode(); sender.sendMessage("created & selected " + f.getName()); } catch (final IOException e) { sender.sendMessage("file creation failed. bad filename?"); } } } } else if (p.first.equals("s") || p.first.equals("select")) { final Node n = node.getNode(p.second); if (n == null) sender.sendMessage("invalid node in '" + p.second + "'"); else node = n; } else if (p.first.equals("save")) { save = true; } else if (p.first.equals("a") || p.first.equals("accept")) { answered = true; answer = true; continue; } else if (p.first.matches("v+")) { v = Verbosity.values()[Math.max(p.first.length(), Verbosity.values().length - 1)]; } answered = false;// --a will only skip the question(s) of the next option or the main action if it's the last option. answer = false; } // --- ACTIONS --- if (action != null) { if (action.equals("e") || action.equals("enable") || action.equals("d") || action.equals("disable")) { final boolean enable = action.startsWith("e"); final String prefix = (enable ? "en" : "dis"); if (node.getParent() == null) { if (enable ^ !config.isEnabled()) { sender.sendMessage("file is already " + prefix + "abled"); return; } if (!answered) sender.sendMessage(prefix + "abling the file will rename the file on the disk. Do you want to continue?"); if (waitForAnswer()) { if (config.setEnabled(enable)) { sender.sendMessage("file " + prefix + "abled"); } else { if (new File(config.getFile(), enable ? config.getFileName().substring(1) : "-" + config.getFileName()).exists()) { sender.sendMessage("could not " + prefix + "able the file because a file with that name already exists"); } else { sender.sendMessage("could not " + prefix + "able the file."); } } } } else { if (node instanceof EntryNode) { node.rename(node.getName().startsWith("-") ? node.getName().substring(1) : "-" + node.getName()); sender.sendMessage("node " + prefix + "abled"); } } } else if (action.equals("s") || action.equals("save")) { save = true; } else if (action.equals("a") || action.equals("add") || action.equals("n") || action.equals("new")) { final String[] params = actionParams.split(":", 2); if (params.length < 2) { sender.sendMessage("usage: /s n key:value|group:"); return; } if (!(node instanceof SectionNode)) { sender.sendMessage("adding node to parent of selected node."); node = node.getParent(); } if (params[1].isEmpty()) { ((SectionNode) node).getNodeList().add(node = new SectionNode(params[0], (SectionNode) node)); } else { ((SectionNode) node).getNodeList().add(node = new EntryNode(params[0], params[1], (SectionNode) node)); } sender.sendMessage("created & selected " + params[0]); } else if (action.equals("r") || action.equals("rename")) { if (actionParams.isEmpty()) { sender.sendMessage("usage: /s r new name"); return; } final String oldname = node.getName(); node.rename(actionParams); sender.sendMessage("renamed " + oldname + " to " + node.getName()); } else if (action.equals("d") || action.equals("delete")) { if (!answered) sender.sendMessage("do you really want to delete this node?"); if (waitForAnswer()) { node.delete(); } } else if (action.equals("m") || action.equals("move")) { if (actionParams.isEmpty()) { sender.sendMessage("usage: /s m +move down|-move up|index to insert after|parent node"); } if (actionParams.matches("-[0-9]+")) { node.getParent().moveDelta(Integer.parseInt(actionParams)); } else if (actionParams.matches("\\+[0-9]+")) { node.getParent().moveDelta(Integer.parseInt(actionParams.substring(1))); } else if (actionParams.matches("[0-9]+")) { node.getParent().move(Integer.parseInt(actionParams)); } else { final Node n = node.getNode(actionParams, true); if (n == null) { sender.sendMessage("invalid path"); return; } if (!(n instanceof SectionNode)) { node.move((SectionNode) n); } else { node.move(n.getParent()); node.move(n.getParent().getNodeList().indexOf(n) + 1); } } } else if (action.equals("l") || action.equals("list")) { if (!(node instanceof SectionNode)) { sender.sendMessage("selected node is not a section, switching to parent node"); node = node.getParent(); } int page = 1; try { page = Math.min((int) Math.ceil(((SectionNode) node).getNodeList().size() / CommandHandler.linesPerPage), Math.max(1, Integer.parseInt(actionParams))); } catch (final NumberFormatException e) {} sender.sendMessage("&8== subnodes of " + node.getName() + " (page " + page + " of " + Math.ceil((((SectionNode) node).getNodeList().size() - (v.compareTo(Verbosity.HIGH) >= 0 ? ((SectionNode) node).getNumVoidNodes() : 0)) / CommandHandler.linesPerPage) + ")"); int j = 0; for (int i = (page - 1) * CommandHandler.linesPerPage; j < CommandHandler.linesPerPage; i++) { final Node n = ((SectionNode) node).getNodeList().get(i); if (v.compareTo(Verbosity.HIGH) >= 0 && n instanceof VoidNode) { continue; } j++; String s; if (n.isVoid()) { s = n.getOrig(); } else { s = n.getName(); if (v.compareTo(Verbosity.NORMAL) >= 0) { if (node instanceof EntryNode) s += ": " + ((EntryNode) n).getValue(); else if (node instanceof SectionNode) s += " [" + ((SectionNode) n).getNodeList().size() + " subnodes]"; } } sender.sendMessage("&7" + (i + 1 < 10 ? "0" : "") + (i + 1) + ":" + (n instanceof InvalidNode ? "&4" : "&0") + " " + s); } } } if (save) { try { config.save(); sender.sendMessage(config.getFileName() + " saved sucessfully"); } catch (final IOException e) { sender.sendMessage("error saving " + config.getFileName() + " (see server log)"); Skript.error("error saving " + config.getFileName() + ":"); e.printStackTrace(); } } answered = false; answer = false; waiting = null; } }); waiting.start(); return true; } private boolean waitForAnswer() { while (!answered) {// if --a this is already false try { Thread.currentThread().wait(); } catch (final InterruptedException e) { answered = false; answer = false; break; } } return answer; } private static ArrayList<Pair<String, String>> parseCommandOptions(final String[] args) { final ArrayList<Pair<String, String>> c = new ArrayList<Pair<String, String>>(); for (int i = 0; i < args.length; i++) { if (args[i].startsWith("--")) { String o = ""; final String s = args[i].substring(1).toLowerCase(); i++; while (i < args.length && !args[i].startsWith("--")) { o += (o.isEmpty() ? "" : " ") + args[i]; i++; } if (i == args.length) break; i--; c.add(new Pair<String, String>(s, o)); } } return c; } }