PageRenderTime 41ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/worldguard-legacy/src/main/java/com/sk89q/worldguard/bukkit/commands/WorldGuardCommands.java

http://github.com/sk89q/worldguard
Java | 296 lines | 240 code | 36 blank | 20 comment | 32 complexity | e10661b790b9e27f56cd8398e8c92022 MD5 | raw file
  1. /*
  2. * WorldGuard, a suite of tools for Minecraft
  3. * Copyright (C) sk89q <http://www.sk89q.com>
  4. * Copyright (C) WorldGuard team and contributors
  5. *
  6. * This program is free software: you can redistribute it and/or modify it
  7. * under the terms of the GNU Lesser General Public License as published by the
  8. * Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
  14. * for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package com.sk89q.worldguard.bukkit.commands;
  20. import com.google.common.base.Predicate;
  21. import com.google.common.base.Predicates;
  22. import com.google.common.io.Files;
  23. import com.google.common.util.concurrent.FutureCallback;
  24. import com.google.common.util.concurrent.Futures;
  25. import com.google.common.util.concurrent.MoreExecutors;
  26. import com.sk89q.minecraft.util.commands.*;
  27. import com.sk89q.worldguard.bukkit.ConfigurationManager;
  28. import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
  29. import com.sk89q.worldguard.bukkit.util.logging.LoggerToChatHandler;
  30. import com.sk89q.worldguard.bukkit.util.report.*;
  31. import com.sk89q.worldguard.util.profiler.SamplerBuilder;
  32. import com.sk89q.worldguard.util.profiler.SamplerBuilder.Sampler;
  33. import com.sk89q.worldguard.util.profiler.ThreadIdFilter;
  34. import com.sk89q.worldguard.util.profiler.ThreadNameFilter;
  35. import com.sk89q.worldguard.util.report.ReportList;
  36. import com.sk89q.worldguard.util.report.SystemInfoReport;
  37. import com.sk89q.worldguard.util.task.Task;
  38. import com.sk89q.worldguard.util.task.TaskStateComparator;
  39. import org.bukkit.Bukkit;
  40. import org.bukkit.ChatColor;
  41. import org.bukkit.World;
  42. import org.bukkit.command.CommandSender;
  43. import org.bukkit.entity.Player;
  44. import javax.annotation.Nullable;
  45. import java.io.File;
  46. import java.io.IOException;
  47. import java.lang.management.ThreadInfo;
  48. import java.nio.charset.Charset;
  49. import java.util.Collections;
  50. import java.util.List;
  51. import java.util.concurrent.TimeUnit;
  52. import java.util.logging.Level;
  53. import java.util.logging.Logger;
  54. public class WorldGuardCommands {
  55. private static final Logger log = Logger.getLogger(WorldGuardCommands.class.getCanonicalName());
  56. private final WorldGuardPlugin plugin;
  57. @Nullable
  58. private Sampler activeSampler;
  59. public WorldGuardCommands(WorldGuardPlugin plugin) {
  60. this.plugin = plugin;
  61. }
  62. @Command(aliases = {"version"}, desc = "Get the WorldGuard version", max = 0)
  63. public void version(CommandContext args, CommandSender sender) throws CommandException {
  64. sender.sendMessage(ChatColor.YELLOW
  65. + "WorldGuard " + plugin.getDescription().getVersion());
  66. sender.sendMessage(ChatColor.YELLOW
  67. + "http://www.sk89q.com");
  68. }
  69. @Command(aliases = {"reload"}, desc = "Reload WorldGuard configuration", max = 0)
  70. @CommandPermissions({"worldguard.reload"})
  71. public void reload(CommandContext args, CommandSender sender) throws CommandException {
  72. // TODO: This is subject to a race condition, but at least other commands are not being processed concurrently
  73. List<Task<?>> tasks = plugin.getSupervisor().getTasks();
  74. if (!tasks.isEmpty()) {
  75. throw new CommandException("There are currently pending tasks. Use /wg running to monitor these tasks first.");
  76. }
  77. LoggerToChatHandler handler = null;
  78. Logger minecraftLogger = null;
  79. if (sender instanceof Player) {
  80. handler = new LoggerToChatHandler(sender);
  81. handler.setLevel(Level.ALL);
  82. minecraftLogger = Logger.getLogger("com.sk89q.worldguard");
  83. minecraftLogger.addHandler(handler);
  84. }
  85. try {
  86. ConfigurationManager config = plugin.getGlobalStateManager();
  87. config.unload();
  88. config.load();
  89. for (World world : Bukkit.getServer().getWorlds()) {
  90. config.get(world);
  91. }
  92. plugin.getRegionContainer().reload();
  93. // WGBukkit.cleanCache();
  94. sender.sendMessage("WorldGuard configuration reloaded.");
  95. } catch (Throwable t) {
  96. sender.sendMessage("Error while reloading: "
  97. + t.getMessage());
  98. } finally {
  99. if (minecraftLogger != null) {
  100. minecraftLogger.removeHandler(handler);
  101. }
  102. }
  103. }
  104. @Command(aliases = {"report"}, desc = "Writes a report on WorldGuard", flags = "p", max = 0)
  105. @CommandPermissions({"worldguard.report"})
  106. public void report(CommandContext args, final CommandSender sender) throws CommandException {
  107. ReportList report = new ReportList("Report");
  108. report.add(new SystemInfoReport());
  109. report.add(new ServerReport());
  110. report.add(new PluginReport());
  111. report.add(new SchedulerReport());
  112. report.add(new ServicesReport());
  113. report.add(new WorldReport());
  114. report.add(new PerformanceReport());
  115. report.add(new ConfigReport(plugin));
  116. String result = report.toString();
  117. try {
  118. File dest = new File(plugin.getDataFolder(), "report.txt");
  119. Files.write(result, dest, Charset.forName("UTF-8"));
  120. sender.sendMessage(ChatColor.YELLOW + "WorldGuard report written to " + dest.getAbsolutePath());
  121. } catch (IOException e) {
  122. throw new CommandException("Failed to write report: " + e.getMessage());
  123. }
  124. if (args.hasFlag('p')) {
  125. plugin.checkPermission(sender, "worldguard.report.pastebin");
  126. CommandUtils.pastebin(plugin, sender, result, "WorldGuard report: %s.report");
  127. }
  128. }
  129. @Command(aliases = {"profile"}, usage = "[<minutes>]",
  130. desc = "Profile the CPU usage of the server", min = 0, max = 1,
  131. flags = "t:p")
  132. @CommandPermissions("worldguard.profile")
  133. public void profile(final CommandContext args, final CommandSender sender) throws CommandException {
  134. Predicate<ThreadInfo> threadFilter;
  135. String threadName = args.getFlag('t');
  136. final boolean pastebin;
  137. if (args.hasFlag('p')) {
  138. plugin.checkPermission(sender, "worldguard.report.pastebin");
  139. pastebin = true;
  140. } else {
  141. pastebin = false;
  142. }
  143. if (threadName == null) {
  144. threadFilter = new ThreadIdFilter(Thread.currentThread().getId());
  145. } else if (threadName.equals("*")) {
  146. threadFilter = Predicates.alwaysTrue();
  147. } else {
  148. threadFilter = new ThreadNameFilter(threadName);
  149. }
  150. int minutes;
  151. if (args.argsLength() == 0) {
  152. minutes = 5;
  153. } else {
  154. minutes = args.getInteger(0);
  155. if (minutes < 1) {
  156. throw new CommandException("You must run the profile for at least 1 minute.");
  157. } else if (minutes > 10) {
  158. throw new CommandException("You can profile for, at maximum, 10 minutes.");
  159. }
  160. }
  161. Sampler sampler;
  162. synchronized (this) {
  163. if (activeSampler != null) {
  164. throw new CommandException("A profile is currently in progress! Please use /wg stopprofile to stop the current profile.");
  165. }
  166. SamplerBuilder builder = new SamplerBuilder();
  167. builder.setThreadFilter(threadFilter);
  168. builder.setRunTime(minutes, TimeUnit.MINUTES);
  169. sampler = activeSampler = builder.start();
  170. }
  171. AsyncCommandHelper.wrap(sampler.getFuture(), plugin, sender)
  172. .formatUsing(minutes)
  173. .registerWithSupervisor("Running CPU profiler for %d minute(s)...")
  174. .sendMessageAfterDelay("(Please wait... profiling for %d minute(s)...)")
  175. .thenTellErrorsOnly("CPU profiling failed.");
  176. sampler.getFuture().addListener(new Runnable() {
  177. @Override
  178. public void run() {
  179. synchronized (WorldGuardCommands.this) {
  180. activeSampler = null;
  181. }
  182. }
  183. }, MoreExecutors.sameThreadExecutor());
  184. Futures.addCallback(sampler.getFuture(), new FutureCallback<Sampler>() {
  185. @Override
  186. public void onSuccess(Sampler result) {
  187. String output = result.toString();
  188. try {
  189. File dest = new File(plugin.getDataFolder(), "profile.txt");
  190. Files.write(output, dest, Charset.forName("UTF-8"));
  191. sender.sendMessage(ChatColor.YELLOW + "CPU profiling data written to " + dest.getAbsolutePath());
  192. } catch (IOException e) {
  193. sender.sendMessage(ChatColor.RED + "Failed to write CPU profiling data: " + e.getMessage());
  194. }
  195. if (pastebin) {
  196. CommandUtils.pastebin(plugin, sender, output, "Profile result: %s.profile");
  197. }
  198. }
  199. @Override
  200. public void onFailure(Throwable throwable) {
  201. }
  202. });
  203. }
  204. @Command(aliases = {"stopprofile"}, usage = "",desc = "Stop a running profile", min = 0, max = 0)
  205. @CommandPermissions("worldguard.profile")
  206. public void stopProfile(CommandContext args, final CommandSender sender) throws CommandException {
  207. synchronized (this) {
  208. if (activeSampler == null) {
  209. throw new CommandException("No CPU profile is currently running.");
  210. }
  211. activeSampler.cancel();
  212. activeSampler = null;
  213. }
  214. sender.sendMessage("The running CPU profile has been stopped.");
  215. }
  216. @Command(aliases = {"flushstates", "clearstates"},
  217. usage = "[player]", desc = "Flush the state manager", max = 1)
  218. @CommandPermissions("worldguard.flushstates")
  219. public void flushStates(CommandContext args, CommandSender sender) throws CommandException {
  220. if (args.argsLength() == 0) {
  221. plugin.getSessionManager().resetAllStates();
  222. sender.sendMessage("Cleared all states.");
  223. } else {
  224. Player player = plugin.getServer().getPlayer(args.getString(0));
  225. if (player != null) {
  226. plugin.getSessionManager().resetState(player);
  227. sender.sendMessage("Cleared states for player \"" + player.getName() + "\".");
  228. }
  229. }
  230. }
  231. @Command(aliases = {"running", "queue"}, desc = "List running tasks", max = 0)
  232. @CommandPermissions("worldguard.running")
  233. public void listRunningTasks(CommandContext args, CommandSender sender) throws CommandException {
  234. List<Task<?>> tasks = plugin.getSupervisor().getTasks();
  235. if (!tasks.isEmpty()) {
  236. Collections.sort(tasks, new TaskStateComparator());
  237. StringBuilder builder = new StringBuilder();
  238. builder.append(ChatColor.GRAY);
  239. builder.append("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
  240. builder.append(" Running tasks ");
  241. builder.append("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
  242. builder.append("\n").append(ChatColor.GRAY).append("Note: Some 'running' tasks may be waiting to be start.");
  243. for (Task task : tasks) {
  244. builder.append("\n");
  245. builder.append(ChatColor.BLUE).append("(").append(task.getState().name()).append(") ");
  246. builder.append(ChatColor.YELLOW);
  247. builder.append(CommandUtils.getOwnerName(task.getOwner()));
  248. builder.append(": ");
  249. builder.append(ChatColor.WHITE);
  250. builder.append(task.getName());
  251. }
  252. sender.sendMessage(builder.toString());
  253. } else {
  254. sender.sendMessage(ChatColor.YELLOW + "There are currently no running tasks.");
  255. }
  256. }
  257. @Command(aliases = {"debug"}, desc = "Debugging commands")
  258. @NestedCommand({DebuggingCommands.class})
  259. public void debug(CommandContext args, CommandSender sender) {}
  260. }