Package ch.njol.skript

Source Code of ch.njol.skript.SkriptCommand

package ch.njol.skript;

import java.io.File;
import java.io.IOException;
import java.util.Collection;

import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.util.ChatPaginator;
import org.bukkit.util.ChatPaginator.ChatPage;
import org.eclipse.jdt.annotation.Nullable;

import ch.njol.skript.ScriptLoader.ScriptInfo;
import ch.njol.skript.Updater.UpdateState;
import ch.njol.skript.Updater.VersionInfo;
import ch.njol.skript.classes.Converter;
import ch.njol.skript.command.CommandHelp;
import ch.njol.skript.localization.ArgsMessage;
import ch.njol.skript.localization.Language;
import ch.njol.skript.localization.PluralizingArgsMessage;
import ch.njol.skript.log.RedirectingLogHandler;
import ch.njol.skript.log.SkriptLogger;
import ch.njol.skript.util.Color;
import ch.njol.skript.util.ExceptionUtils;
import ch.njol.skript.util.FileUtils;
import ch.njol.skript.util.Utils;
import ch.njol.util.StringUtils;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

/*
*   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
*
*/

/**
* @author Peter Güttinger
*/
public class SkriptCommand implements CommandExecutor {
  private final static String NODE = "skript command";
 
  // TODO /skript scripts show/list - lists all enabled and/or disabled scripts in the scripts folder and/or subfolders (maybe add a pattern [using * and **])
  // TODO document this command on the website
  private final static CommandHelp skriptCommandHelp = new CommandHelp("<gray>/<gold>skript", Color.LIGHT_CYAN, NODE + ".help")
      .add(new CommandHelp("reload", Color.DARK_RED)
          .add("all")
          .add("config")
          .add("aliases")
          .add("scripts")
          .add("<script>")
      ).add(new CommandHelp("enable", Color.DARK_RED)
          .add("all")
          .add("<script>")
      ).add(new CommandHelp("disable", Color.DARK_RED)
          .add("all")
          .add("<script>")
      ).add(new CommandHelp("update", Color.DARK_RED)
          .add("check")
          .add("changes")
          .add("download")
      //      ).add(new CommandHelp("variable", "Commands for modifying variables", ChatColor.DARK_RED)
//          .add("set", "Creates a new variable or changes an existing one")
//          .add("delete", "Deletes a variable")
//          .add("find", "Find variables")
      ).add("help");
 
  private final static ArgsMessage m_reloading = new ArgsMessage(NODE + ".reload.reloading");
 
  private final static void reloading(final CommandSender sender, String what, final Object... args) {
    what = args.length == 0 ? Language.get(NODE + ".reload." + what) : Language.format(NODE + ".reload." + what, args);
    Skript.info(sender, StringUtils.fixCapitalization(m_reloading.toString(what)));
  }
 
  private final static ArgsMessage m_reloaded = new ArgsMessage(NODE + ".reload.reloaded");
  private final static ArgsMessage m_reload_error = new ArgsMessage(NODE + ".reload.error");
 
  private final static ArgsMessage m_changes_title = new ArgsMessage(NODE + ".update.changes.title");
 
  private final static void reloaded(final CommandSender sender, final RedirectingLogHandler r, String what, final Object... args) {
    what = args.length == 0 ? Language.get(NODE + ".reload." + what) : PluralizingArgsMessage.format(Language.format(NODE + ".reload." + what, args));
    if (r.numErrors() == 0)
      Skript.info(sender, StringUtils.fixCapitalization(PluralizingArgsMessage.format(m_reloaded.toString(what))));
    else
      Skript.error(sender, StringUtils.fixCapitalization(PluralizingArgsMessage.format(m_reload_error.toString(what, r.numErrors()))));
  }
 
  private final static void info(final CommandSender sender, String what, final Object... args) {
    what = args.length == 0 ? Language.get(NODE + "." + what) : PluralizingArgsMessage.format(Language.format(NODE + "." + what, args));
    Skript.info(sender, StringUtils.fixCapitalization(what));
  }
 
  private final static void message(final CommandSender sender, String what, final Object... args) {
    what = args.length == 0 ? Language.get(NODE + "." + what) : PluralizingArgsMessage.format(Language.format(NODE + "." + what, args));
    Skript.message(sender, StringUtils.fixCapitalization(what));
  }
 
  private final static void error(final CommandSender sender, String what, final Object... args) {
    what = args.length == 0 ? Language.get(NODE + "." + what) : PluralizingArgsMessage.format(Language.format(NODE + "." + what, args));
    Skript.error(sender, StringUtils.fixCapitalization(what));
  }
 
  @Override
  @SuppressFBWarnings("REC_CATCH_EXCEPTION")
  public boolean onCommand(final @Nullable CommandSender sender, final @Nullable Command command, final @Nullable String label, final @Nullable String[] args) {
    if (sender == null || command == null || label == null || args == null)
      throw new IllegalArgumentException();
    if (!skriptCommandHelp.test(sender, args))
      return true;
    final RedirectingLogHandler r = SkriptLogger.startLogHandler(new RedirectingLogHandler(sender, ""));
    try {
      if (args[0].equalsIgnoreCase("reload")) {
        if (args[1].equalsIgnoreCase("all")) {
          reloading(sender, "config and scripts");
          Skript.reload();
          reloaded(sender, r, "config and scripts");
        } else if (args[1].equalsIgnoreCase("scripts")) {
          reloading(sender, "scripts");
          Skript.reloadScripts();
          reloaded(sender, r, "scripts");
        } else if (args[1].equalsIgnoreCase("config")) {
          reloading(sender, "main config");
          Skript.reloadMainConfig();
          reloaded(sender, r, "main config");
        } else if (args[1].equalsIgnoreCase("aliases")) {
          reloading(sender, "aliases");
          Skript.reloadAliases();
          reloaded(sender, r, "aliases");
        } else {
          final File f = getScriptFromArgs(sender, args, 1);
          if (f == null)
            return true;
          if (!f.isDirectory()) {
            if (f.getName().startsWith("-")) {
              info(sender, "reload.script disabled", f.getName().substring(1));
              return true;
            }
            reloading(sender, "script", f.getName());
            ScriptLoader.unloadScript(f);
            ScriptLoader.loadScripts(new File[] {f});
            reloaded(sender, r, "script", f.getName());
          } else {
            reloading(sender, "scripts in folder", f.getName());
            final int disabled = ScriptLoader.unloadScripts(f).files;
            final int enabled = ScriptLoader.loadScripts(f).files;
            if (Math.max(disabled, enabled) == 0)
              info(sender, "reload.empty folder", f.getName());
            else
              reloaded(sender, r, "x scripts in folder", f.getName(), Math.max(disabled, enabled));
          }
        }
      } else if (args[0].equalsIgnoreCase("enable")) {
        if (args[1].equals("all")) {
          try {
            info(sender, "enable.all.enabling");
            final File[] files = toggleScripts(new File(Skript.getInstance().getDataFolder(), Skript.SCRIPTSFOLDER), true).toArray(new File[0]);
            assert files != null;
            ScriptLoader.loadScripts(files);
            if (r.numErrors() == 0) {
              info(sender, "enable.all.enabled");
            } else {
              error(sender, "enable.all.error", r.numErrors());
            }
          } catch (final IOException e) {
            error(sender, "enable.all.io error", ExceptionUtils.toString(e));
          }
        } else {
          File f = getScriptFromArgs(sender, args, 1);
          if (f == null)
            return true;
          if (!f.isDirectory()) {
            if (!f.getName().startsWith("-")) {
              info(sender, "enable.single.already enabled", f.getName(), StringUtils.join(args, " ", 1, args.length));
              return true;
            }
           
            try {
              f = FileUtils.move(f, new File(f.getParentFile(), f.getName().substring(1)), false);
            } catch (final IOException e) {
              error(sender, "enable.single.io error", f.getName().substring(1), ExceptionUtils.toString(e));
              return true;
            }
           
            info(sender, "enable.single.enabling", f.getName());
            ScriptLoader.loadScripts(new File[] {f});
            if (r.numErrors() == 0) {
              info(sender, "enable.single.enabled", f.getName());
            } else {
              error(sender, "enable.single.error", f.getName(), r.numErrors());
            }
            return true;
          } else {
            final Collection<File> scripts;
            try {
              scripts = toggleScripts(f, true);
            } catch (final IOException e) {
              error(sender, "enable.folder.io error", f.getName(), ExceptionUtils.toString(e));
              return true;
            }
            if (scripts.isEmpty()) {
              info(sender, "enable.folder.empty", f.getName());
              return true;
            }
            info(sender, "enable.folder.enabling", f.getName(), scripts.size());
            final File[] ss = scripts.toArray(new File[scripts.size()]);
            assert ss != null;
            final ScriptInfo i = ScriptLoader.loadScripts(ss);
            assert i.files == scripts.size();
            if (r.numErrors() == 0) {
              info(sender, "enable.folder.enabled", f.getName(), i.files);
            } else {
              error(sender, "enable.folder.error", f.getName(), r.numErrors());
            }
            return true;
          }
        }
      } else if (args[0].equalsIgnoreCase("disable")) {
        if (args[1].equals("all")) {
          Skript.disableScripts();
          try {
            toggleScripts(new File(Skript.getInstance().getDataFolder(), Skript.SCRIPTSFOLDER), false);
            info(sender, "disable.all.disabled");
          } catch (final IOException e) {
            error(sender, "disable.all.io error", ExceptionUtils.toString(e));
          }
        } else {
          final File f = getScriptFromArgs(sender, args, 1);
          if (f == null) // TODO allow disabling deleted/renamed scripts
            return true;
          if (!f.isDirectory()) {
            if (f.getName().startsWith("-")) {
              info(sender, "disable.single.already disabled", f.getName().substring(1));
              return true;
            }
           
            ScriptLoader.unloadScript(f);
           
            try {
              FileUtils.move(f, new File(f.getParentFile(), "-" + f.getName()), false);
            } catch (final IOException e) {
              error(sender, "disable.single.io error", f.getName(), ExceptionUtils.toString(e));
              return true;
            }
            info(sender, "disable.single.disabled", f.getName());
            return true;
          } else {
            final Collection<File> scripts;
            try {
              scripts = toggleScripts(f, false);
            } catch (final IOException e) {
              error(sender, "disable.folder.io error", f.getName(), ExceptionUtils.toString(e));
              return true;
            }
            if (scripts.isEmpty()) {
              info(sender, "disable.folder.empty", f.getName());
              return true;
            }
           
            for (final File script : scripts)
              ScriptLoader.unloadScript(new File(script.getParentFile(), script.getName().substring(1)));
           
            info(sender, "disable.folder.disabled", f.getName(), scripts.size());
            return true;
          }
        }
      } else if (args[0].equalsIgnoreCase("update")) {
        Updater.stateLock.writeLock().lock();
        try {
          final UpdateState state = Updater.state;
          if (args[1].equals("check")) {
            switch (state) {
              case NOT_STARTED:
                Updater.check(sender, false, false);
                break;
              case CHECK_IN_PROGRESS:
                Skript.info(sender, "" + Updater.m_check_in_progress);
                break;
              case CHECK_ERROR:
                Updater.check(sender, false, false);
                break;
              case CHECKED_FOR_UPDATE:
                if (Updater.latest.get() == null)
                  Skript.info(sender, Skript.getVersion().isStable() ? "" + Updater.m_running_latest_version : "" + Updater.m_running_latest_version_beta);
                else
                  Skript.info(sender, "" + Updater.m_update_available);
                break;
              case DOWNLOAD_IN_PROGRESS:
                Skript.info(sender, "" + Updater.m_download_in_progress);
                break;
              case DOWNLOAD_ERROR:
                Skript.info(sender, "" + Updater.m_download_error);
                break;
              case DOWNLOADED:
                Skript.info(sender, "" + Updater.m_downloaded);
                break;
            }
          } else if (args[1].equalsIgnoreCase("changes")) {
            if (state == UpdateState.NOT_STARTED) {
              Skript.info(sender, "" + Updater.m_not_started);
            } else if (state == UpdateState.CHECK_IN_PROGRESS) {
              Skript.info(sender, "" + Updater.m_check_in_progress);
            } else if (state == UpdateState.CHECK_ERROR) {
              Skript.info(sender, "" + Updater.m_check_error);
            } else if (Updater.latest.get() == null) {
              Skript.info(sender, Skript.getVersion().isStable() ? "" + Updater.m_running_latest_version : "" + Updater.m_running_latest_version_beta);
//            } else if (args.length == 2 && Updater.infos.size() != 1) {
//              info(sender, "update.changes.multiple versions.title", Updater.infos.size(), Skript.getVersion());
//              String versions = Updater.infos.get(0).version.toString();
//              for (int i = Updater.infos.size() - 1; i >= 0; i--)
//                versions += ", " + Updater.infos.get(i).version.toString();
//              Skript.message(sender, "  " + versions);
//              message(sender, "update.changes.multiple versions.footer");
            } else {
//              VersionInfo info = null;
              int pageNum = 1;
//              if (Updater.infos.size() == 1) {
//                info = Updater.latest.get();
              if (args.length >= 3 && args[2].matches("\\d+")) {
                final String a2 = args[2];
                assert a2 != null;
                pageNum = Utils.parseInt(a2); // Eclipse complains about null here, not where args[2] is dereferenced above...
              }
//              } else {
//                final String version = args[2];
//                for (final VersionInfo i : Updater.infos) {
//                  if (i.version.toString().equals(version)) {
//                    info = i;
//                    break;
//                  }
//                }
//                if (info == null) {
//                  error(sender, "update.changes.invalid version", version);
//                  return true;
//                }
//                if (args.length >= 4 && args[3].matches("\\d+"))
//                  pageNum = Utils.parseInt(args[3]);
//              }
              final StringBuilder changes = new StringBuilder();
              for (final VersionInfo i : Updater.infos) {
                if (changes.length() != 0)
                  changes.append("\n");
                changes.append(Skript.SKRIPT_PREFIX + Utils.replaceEnglishChatStyles(m_changes_title.toString(i.version, i.date)));
                changes.append("\n");
                changes.append(i.changelog);
              }
              final ChatPage page = ChatPaginator.paginate(changes.toString(), pageNum, ChatPaginator.GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH, ChatPaginator.OPEN_CHAT_PAGE_HEIGHT - 2);
              sender.sendMessage(page.getLines());
              if (pageNum < page.getTotalPages())
                message(sender, "update.changes.next page", pageNum, page.getTotalPages(), pageNum + 1);
            }
          } else if (args[1].equalsIgnoreCase("download")) {
            switch (state) {
              case NOT_STARTED:
                Updater.check(sender, true, false);
                break;
              case CHECK_IN_PROGRESS:
                Skript.info(sender, "" + Updater.m_check_in_progress);
                break;
              case CHECK_ERROR:
                Updater.check(sender, true, false);
//                info(sender, Language.format("updater.check_error", updater.error));
                break;
              case CHECKED_FOR_UPDATE:
                if (Updater.latest.get() == null) {
                  Skript.info(sender, Skript.getVersion().isStable() ? "" + Updater.m_running_latest_version : "" + Updater.m_running_latest_version_beta);
                } else {
                  Updater.download(sender, false);
                }
                break;
              case DOWNLOAD_IN_PROGRESS:
                Skript.info(sender, "" + Updater.m_download_in_progress);
                break;
              case DOWNLOADED:
                Skript.info(sender, "" + Updater.m_downloaded);
                break;
              case DOWNLOAD_ERROR:
//                Skript.info(sender, "" + Updater.m_download_error);
                Updater.download(sender, false);
                break;
            }
          }
        } finally {
          Updater.stateLock.writeLock().unlock();
        }
      } else if (args[0].equalsIgnoreCase("help")) {
        skriptCommandHelp.showHelp(sender);
      }
    } catch (final Exception e) {
      Skript.exception(e, "Exception occurred in Skript's main command", "Used command: /" + label + " " + StringUtils.join(args, " "));
    } finally {
      r.stop();
    }
    return true;
  }
 
  private final static ArgsMessage m_invalid_script = new ArgsMessage(NODE + ".invalid script");
  private final static ArgsMessage m_invalid_folder = new ArgsMessage(NODE + ".invalid folder");
 
  @Nullable
  private static File getScriptFromArgs(final CommandSender sender, final String[] args, final int start) {
    String script = StringUtils.join(args, " ", start, args.length);
    final boolean isFolder = script.endsWith("/") || script.endsWith("\\");
    if (isFolder) {
      script = script.replace('/', File.separatorChar).replace('\\', File.separatorChar);
    } else if (!StringUtils.endsWithIgnoreCase(script, ".sk")) {
      script = script + ".sk";
    }
    if (script.startsWith("-"))
      script = script.substring(1);
    File f = new File(Skript.getInstance().getDataFolder(), Skript.SCRIPTSFOLDER + File.separator + script);
    if (!f.exists()) {
      f = new File(f.getParentFile(), "-" + f.getName());
      if (!f.exists()) {
        Skript.error(sender, (isFolder ? m_invalid_folder : m_invalid_script).toString(script));
        return null;
      }
    }
    return f;
  }
 
  private final static Collection<File> toggleScripts(final File folder, final boolean enable) throws IOException {
    return FileUtils.renameAll(folder, new Converter<String, String>() {
      @Override
      @Nullable
      public String convert(final String name) {
        if (StringUtils.endsWithIgnoreCase(name, ".sk") && name.startsWith("-") == enable)
          return enable ? name.substring(1) : "-" + name;
        return null;
      }
    });
  }
 
}
TOP

Related Classes of ch.njol.skript.SkriptCommand

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.