PageRenderTime 55ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://gitlab.com/igserfurtmcschulserver/CustomWorldGuard
Java | 220 lines | 131 code | 29 blank | 60 comment | 19 complexity | 6315b6e9d4f813b27c452fb8a8aed656 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.sk89q.minecraft.util.commands.*;
  21. import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
  22. import com.sk89q.worldguard.bukkit.event.debug.*;
  23. import com.sk89q.worldguard.util.report.CancelReport;
  24. import org.bukkit.Bukkit;
  25. import org.bukkit.ChatColor;
  26. import org.bukkit.Material;
  27. import org.bukkit.block.Block;
  28. import org.bukkit.block.BlockFace;
  29. import org.bukkit.command.CommandSender;
  30. import org.bukkit.command.ConsoleCommandSender;
  31. import org.bukkit.entity.Entity;
  32. import org.bukkit.entity.Player;
  33. import org.bukkit.event.Event;
  34. import org.bukkit.event.block.Action;
  35. import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
  36. import org.bukkit.util.BlockIterator;
  37. import java.util.logging.Logger;
  38. public class DebuggingCommands {
  39. private static final Logger log = Logger.getLogger(DebuggingCommands.class.getCanonicalName());
  40. private static final int MAX_TRACE_DISTANCE = 20;
  41. private final WorldGuardPlugin plugin;
  42. /**
  43. * Create a new instance.
  44. *
  45. * @param plugin The plugin instance
  46. */
  47. public DebuggingCommands(WorldGuardPlugin plugin) {
  48. this.plugin = plugin;
  49. }
  50. @Command(aliases = {"testbreak"}, usage = "[player]", desc = "Simulate a block break", min = 1, max = 1, flags = "ts")
  51. @CommandPermissions("worldguard.debug.event")
  52. public void fireBreakEvent(CommandContext args, final CommandSender sender) throws CommandException {
  53. Player target = plugin.matchSinglePlayer(sender, args.getString(0));
  54. Block block = traceBlock(sender, target, args.hasFlag('t'));
  55. sender.sendMessage(ChatColor.AQUA + "Testing BLOCK BREAK at " + ChatColor.DARK_AQUA + block);
  56. LoggingBlockBreakEvent event = new LoggingBlockBreakEvent(block, target);
  57. testEvent(sender, target, event, args.hasFlag('s'));
  58. }
  59. @Command(aliases = {"testplace"}, usage = "[player]", desc = "Simulate a block place", min = 1, max = 1, flags = "ts")
  60. @CommandPermissions("worldguard.debug.event")
  61. public void firePlaceEvent(CommandContext args, final CommandSender sender) throws CommandException {
  62. Player target = plugin.matchSinglePlayer(sender, args.getString(0));
  63. Block block = traceBlock(sender, target, args.hasFlag('t'));
  64. sender.sendMessage(ChatColor.AQUA + "Testing BLOCK PLACE at " + ChatColor.DARK_AQUA + block);
  65. LoggingBlockPlaceEvent event = new LoggingBlockPlaceEvent(block, block.getState(), block.getRelative(BlockFace.DOWN), target.getItemInHand(), target, true);
  66. testEvent(sender, target, event, args.hasFlag('s'));
  67. }
  68. @Command(aliases = {"testinteract"}, usage = "[player]", desc = "Simulate a block interact", min = 1, max = 1, flags = "ts")
  69. @CommandPermissions("worldguard.debug.event")
  70. public void fireInteractEvent(CommandContext args, final CommandSender sender) throws CommandException {
  71. Player target = plugin.matchSinglePlayer(sender, args.getString(0));
  72. Block block = traceBlock(sender, target, args.hasFlag('t'));
  73. sender.sendMessage(ChatColor.AQUA + "Testing BLOCK INTERACT at " + ChatColor.DARK_AQUA + block);
  74. LoggingPlayerInteractEvent event = new LoggingPlayerInteractEvent(target, Action.RIGHT_CLICK_BLOCK, target.getItemInHand(), block, BlockFace.SOUTH);
  75. testEvent(sender, target, event, args.hasFlag('s'));
  76. }
  77. @Command(aliases = {"testdamage"}, usage = "[player]", desc = "Simulate an entity damage", min = 1, max = 1, flags = "ts")
  78. @CommandPermissions("worldguard.debug.event")
  79. public void fireDamageEvent(CommandContext args, final CommandSender sender) throws CommandException {
  80. Player target = plugin.matchSinglePlayer(sender, args.getString(0));
  81. Entity entity = traceEntity(sender, target, args.hasFlag('t'));
  82. sender.sendMessage(ChatColor.AQUA + "Testing ENTITY DAMAGE on " + ChatColor.DARK_AQUA + entity);
  83. LoggingEntityDamageByEntityEvent event = new LoggingEntityDamageByEntityEvent(target, entity, DamageCause.ENTITY_ATTACK, 1);
  84. testEvent(sender, target, event, args.hasFlag('s'));
  85. }
  86. /**
  87. * Simulate an event and print its report.
  88. *
  89. * @param receiver The receiver of the messages
  90. * @param target The target
  91. * @param event The event
  92. * @param stacktraceMode Whether stack traces should be generated and posted
  93. * @param <T> The type of event
  94. */
  95. private <T extends Event & CancelLogging> void testEvent(CommandSender receiver, Player target, T event, boolean stacktraceMode) throws CommandPermissionsException {
  96. boolean isConsole = receiver instanceof ConsoleCommandSender;
  97. if (!receiver.equals(target)) {
  98. if (!isConsole) {
  99. log.info(receiver.getName() + " is simulating an event on " + target.getName());
  100. }
  101. target.sendMessage(
  102. ChatColor.RED + "(Please ignore any messages that may immediately follow.)");
  103. }
  104. Bukkit.getPluginManager().callEvent(event);
  105. int start = new Exception().getStackTrace().length;
  106. CancelReport report = new CancelReport(event, event.getCancels(), start);
  107. report.setDetectingPlugin(!stacktraceMode);
  108. String result = report.toString();
  109. if (stacktraceMode) {
  110. receiver.sendMessage(ChatColor.GRAY + "The report was printed to console.");
  111. log.info("Event report for " + receiver.getName() + ":\n\n" + result);
  112. plugin.checkPermission(receiver, "worldguard.debug.pastebin");
  113. CommandUtils.pastebin(plugin, receiver, result, "Event debugging report: %s.txt");
  114. } else {
  115. receiver.sendMessage(result.replaceAll("(?m)^", ChatColor.AQUA.toString()));
  116. if (result.length() >= 500 && !isConsole) {
  117. receiver.sendMessage(ChatColor.GRAY + "The report was also printed to console.");
  118. log.info("Event report for " + receiver.getName() + ":\n\n" + result);
  119. }
  120. }
  121. }
  122. /**
  123. * Get the source of the test.
  124. *
  125. * @param sender The message sender
  126. * @param target The provided target
  127. * @param fromTarget Whether the source should be the target
  128. * @return The source
  129. * @throws CommandException Thrown if a condition is not met
  130. */
  131. private Player getSource(CommandSender sender, Player target, boolean fromTarget) throws CommandException {
  132. if (fromTarget) {
  133. return target;
  134. } else {
  135. if (sender instanceof Player) {
  136. return (Player) sender;
  137. } else {
  138. throw new CommandException(
  139. "If this command is not to be used in-game, use -t to run the test from the viewpoint of the given player rather than yourself.");
  140. }
  141. }
  142. }
  143. /**
  144. * Find the first non-air block in a ray trace.
  145. *
  146. * @param sender The sender
  147. * @param target The target
  148. * @param fromTarget Whether the trace should originate from the target
  149. * @return The block found
  150. * @throws CommandException Throw on an incorrect parameter
  151. */
  152. private Block traceBlock(CommandSender sender, Player target, boolean fromTarget) throws CommandException {
  153. Player source = getSource(sender, target, fromTarget);
  154. BlockIterator it = new BlockIterator(source);
  155. int i = 0;
  156. while (it.hasNext() && i < MAX_TRACE_DISTANCE) {
  157. Block block = it.next();
  158. if (block.getType() != Material.AIR) {
  159. return block;
  160. }
  161. i++;
  162. }
  163. throw new CommandException("Not currently looking at a block that is close enough.");
  164. }
  165. /**
  166. * Find the first nearby entity in a ray trace.
  167. *
  168. * @param sender The sender
  169. * @param target The target
  170. * @param fromTarget Whether the trace should originate from the target
  171. * @return The entity found
  172. * @throws CommandException Throw on an incorrect parameter
  173. */
  174. private Entity traceEntity(CommandSender sender, Player target, boolean fromTarget) throws CommandException {
  175. Player source = getSource(sender, target, fromTarget);
  176. BlockIterator it = new BlockIterator(source);
  177. int i = 0;
  178. while (it.hasNext() && i < MAX_TRACE_DISTANCE) {
  179. Block block = it.next();
  180. // A very in-accurate and slow search
  181. Entity[] entities = block.getChunk().getEntities();
  182. for (Entity entity : entities) {
  183. if (!entity.equals(target) && entity.getLocation().distanceSquared(block.getLocation()) < 10) {
  184. return entity;
  185. }
  186. }
  187. i++;
  188. }
  189. throw new CommandException("Not currently looking at an entity that is close enough.");
  190. }
  191. }