PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/worldguard-legacy/src/main/java/com/sk89q/worldguard/bukkit/listener/WorldGuardPlayerListener.java

https://gitlab.com/igserfurtmcschulserver/CustomWorldGuard
Java | 472 lines | 365 code | 61 blank | 46 comment | 116 complexity | 86927618a71c1d50fafc3ddd8f5c0a17 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.listener;
  20. import com.sk89q.worldedit.blocks.BlockID;
  21. import com.sk89q.worldguard.LocalPlayer;
  22. import com.sk89q.worldguard.bukkit.BukkitUtil;
  23. import com.sk89q.worldguard.bukkit.ConfigurationManager;
  24. import com.sk89q.worldguard.bukkit.WorldConfiguration;
  25. import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
  26. import com.sk89q.worldguard.bukkit.event.player.ProcessPlayerEvent;
  27. import com.sk89q.worldguard.bukkit.util.Events;
  28. import com.sk89q.worldguard.protection.ApplicableRegionSet;
  29. import com.sk89q.worldguard.protection.flags.DefaultFlag;
  30. import com.sk89q.worldguard.protection.managers.RegionManager;
  31. import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
  32. import com.sk89q.worldguard.protection.regions.ProtectedRegion;
  33. import com.sk89q.worldguard.session.MoveType;
  34. import com.sk89q.worldguard.session.Session;
  35. import com.sk89q.worldguard.session.handler.GameModeFlag;
  36. import com.sk89q.worldguard.util.command.CommandFilter;
  37. import org.bukkit.ChatColor;
  38. import org.bukkit.GameMode;
  39. import org.bukkit.Location;
  40. import org.bukkit.TravelAgent;
  41. import org.bukkit.World;
  42. import org.bukkit.block.Block;
  43. import org.bukkit.entity.Entity;
  44. import org.bukkit.entity.Player;
  45. import org.bukkit.event.EventHandler;
  46. import org.bukkit.event.EventPriority;
  47. import org.bukkit.event.Listener;
  48. import org.bukkit.event.block.Action;
  49. import org.bukkit.event.player.AsyncPlayerChatEvent;
  50. import org.bukkit.event.player.PlayerCommandPreprocessEvent;
  51. import org.bukkit.event.player.PlayerGameModeChangeEvent;
  52. import org.bukkit.event.player.PlayerInteractEvent;
  53. import org.bukkit.event.player.PlayerItemHeldEvent;
  54. import org.bukkit.event.player.PlayerJoinEvent;
  55. import org.bukkit.event.player.PlayerLoginEvent;
  56. import org.bukkit.event.player.PlayerPortalEvent;
  57. import org.bukkit.event.player.PlayerRespawnEvent;
  58. import org.bukkit.event.player.PlayerTeleportEvent;
  59. import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
  60. import org.bukkit.inventory.ItemStack;
  61. import org.bukkit.plugin.PluginManager;
  62. import javax.annotation.Nullable;
  63. import java.util.Iterator;
  64. import java.util.Set;
  65. import java.util.logging.Logger;
  66. import java.util.regex.Pattern;
  67. /**
  68. * Handles all events thrown in relation to a player.
  69. */
  70. public class WorldGuardPlayerListener implements Listener {
  71. private static final Logger log = Logger.getLogger(WorldGuardPlayerListener.class.getCanonicalName());
  72. private static final Pattern opPattern = Pattern.compile("^/(?:bukkit:)?op(?:\\s.*)?$", Pattern.CASE_INSENSITIVE);
  73. private WorldGuardPlugin plugin;
  74. /**
  75. * Construct the object;
  76. *
  77. * @param plugin
  78. */
  79. public WorldGuardPlayerListener(WorldGuardPlugin plugin) {
  80. this.plugin = plugin;
  81. }
  82. /**
  83. * Register events.
  84. */
  85. public void registerEvents() {
  86. PluginManager pm = plugin.getServer().getPluginManager();
  87. pm.registerEvents(this, plugin);
  88. }
  89. @EventHandler
  90. public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) {
  91. Player player = event.getPlayer();
  92. WorldConfiguration wcfg = plugin.getGlobalStateManager().get(player.getWorld());
  93. Session session = plugin.getSessionManager().getIfPresent(player);
  94. if (session != null) {
  95. GameModeFlag handler = session.getHandler(GameModeFlag.class);
  96. if (handler != null && wcfg.useRegions && !plugin.getGlobalRegionManager().hasBypass(player, player.getWorld())) {
  97. GameMode expected = handler.getSetGameMode();
  98. if (handler.getOriginalGameMode() != null && expected != null && expected != event.getNewGameMode()) {
  99. log.info("Game mode change on " + player.getName() + " has been blocked due to the region GAMEMODE flag");
  100. event.setCancelled(true);
  101. }
  102. }
  103. }
  104. }
  105. @EventHandler
  106. public void onPlayerJoin(PlayerJoinEvent event) {
  107. Player player = event.getPlayer();
  108. World world = player.getWorld();
  109. ConfigurationManager cfg = plugin.getGlobalStateManager();
  110. WorldConfiguration wcfg = cfg.get(world);
  111. if (cfg.activityHaltToggle) {
  112. player.sendMessage(ChatColor.YELLOW
  113. + "Intensive server activity has been HALTED.");
  114. int removed = 0;
  115. for (Entity entity : world.getEntities()) {
  116. if (BukkitUtil.isIntensiveEntity(entity)) {
  117. entity.remove();
  118. removed++;
  119. }
  120. }
  121. if (removed > 10) {
  122. log.info("Halt-Act: " + removed + " entities (>10) auto-removed from "
  123. + player.getWorld().toString());
  124. }
  125. }
  126. if (wcfg.fireSpreadDisableToggle) {
  127. player.sendMessage(ChatColor.YELLOW
  128. + "Fire spread is currently globally disabled for this world.");
  129. }
  130. Events.fire(new ProcessPlayerEvent(player));
  131. plugin.getSessionManager().get(player); // Initializes a session
  132. }
  133. @EventHandler(ignoreCancelled = true)
  134. public void onPlayerChat(AsyncPlayerChatEvent event) {
  135. Player player = event.getPlayer();
  136. WorldConfiguration wcfg = plugin.getGlobalStateManager().get(player.getWorld());
  137. if (wcfg.useRegions) {
  138. if (!plugin.getGlobalRegionManager().allows(DefaultFlag.SEND_CHAT, player.getLocation())) {
  139. player.sendMessage(ChatColor.RED + "You don't have permission to chat in this region!");
  140. event.setCancelled(true);
  141. return;
  142. }
  143. for (Iterator<Player> i = event.getRecipients().iterator(); i.hasNext();) {
  144. if (!plugin.getGlobalRegionManager().allows(DefaultFlag.RECEIVE_CHAT, i.next().getLocation())) {
  145. i.remove();
  146. }
  147. }
  148. if (event.getRecipients().size() == 0) {
  149. event.setCancelled(true);
  150. }
  151. }
  152. }
  153. @EventHandler(ignoreCancelled = true)
  154. public void onPlayerLogin(PlayerLoginEvent event) {
  155. Player player = event.getPlayer();
  156. ConfigurationManager cfg = plugin.getGlobalStateManager();
  157. String hostKey = cfg.hostKeys.get(player.getName().toLowerCase());
  158. if (hostKey != null) {
  159. String hostname = event.getHostname();
  160. int colonIndex = hostname.indexOf(':');
  161. if (colonIndex != -1) {
  162. hostname = hostname.substring(0, colonIndex);
  163. }
  164. if (!hostname.equals(hostKey)) {
  165. event.disallow(PlayerLoginEvent.Result.KICK_OTHER,
  166. "You did not join with the valid host key!");
  167. log.warning("WorldGuard host key check: " +
  168. player.getName() + " joined with '" + hostname +
  169. "' but '" + hostKey + "' was expected. Kicked!");
  170. return;
  171. }
  172. }
  173. if (cfg.deopOnJoin) {
  174. player.setOp(false);
  175. }
  176. }
  177. @EventHandler(priority = EventPriority.HIGH)
  178. public void onPlayerInteract(PlayerInteractEvent event) {
  179. Player player = event.getPlayer();
  180. World world = player.getWorld();
  181. if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
  182. handleBlockRightClick(event);
  183. } else if (event.getAction() == Action.PHYSICAL) {
  184. handlePhysicalInteract(event);
  185. }
  186. ConfigurationManager cfg = plugin.getGlobalStateManager();
  187. WorldConfiguration wcfg = cfg.get(world);
  188. if (wcfg.removeInfiniteStacks
  189. && !plugin.hasPermission(player, "worldguard.override.infinite-stack")) {
  190. int slot = player.getInventory().getHeldItemSlot();
  191. ItemStack heldItem = player.getInventory().getItem(slot);
  192. if (heldItem != null && heldItem.getAmount() < 0) {
  193. player.getInventory().setItem(slot, null);
  194. player.sendMessage(ChatColor.RED + "Infinite stack removed.");
  195. }
  196. }
  197. }
  198. /**
  199. * Called when a player right clicks a block.
  200. *
  201. * @param event Thrown event
  202. */
  203. private void handleBlockRightClick(PlayerInteractEvent event) {
  204. if (event.isCancelled()) {
  205. return;
  206. }
  207. Block block = event.getClickedBlock();
  208. World world = block.getWorld();
  209. int type = block.getTypeId();
  210. Player player = event.getPlayer();
  211. @Nullable ItemStack item = event.getItem();
  212. ConfigurationManager cfg = plugin.getGlobalStateManager();
  213. WorldConfiguration wcfg = cfg.get(world);
  214. // Infinite stack removal
  215. if ((type == BlockID.CHEST
  216. || type == BlockID.JUKEBOX
  217. || type == BlockID.DISPENSER
  218. || type == BlockID.FURNACE
  219. || type == BlockID.BURNING_FURNACE
  220. || type == BlockID.BREWING_STAND
  221. || type == BlockID.ENCHANTMENT_TABLE)
  222. && wcfg.removeInfiniteStacks
  223. && !plugin.hasPermission(player, "worldguard.override.infinite-stack")) {
  224. for (int slot = 0; slot < 40; slot++) {
  225. ItemStack heldItem = player.getInventory().getItem(slot);
  226. if (heldItem != null && heldItem.getAmount() < 0) {
  227. player.getInventory().setItem(slot, null);
  228. player.sendMessage(ChatColor.RED + "Infinite stack in slot #" + slot + " removed.");
  229. }
  230. }
  231. }
  232. if (wcfg.useRegions) {
  233. //Block placedIn = block.getRelative(event.getBlockFace());
  234. ApplicableRegionSet set = plugin.getRegionContainer().createQuery().getApplicableRegions(block.getLocation());
  235. //ApplicableRegionSet placedInSet = plugin.getRegionContainer().createQuery().getApplicableRegions(placedIn.getLocation());
  236. LocalPlayer localPlayer = plugin.wrapPlayer(player);
  237. if (item != null && item.getTypeId() == wcfg.regionWand && plugin.hasPermission(player, "worldguard.region.wand")) {
  238. if (set.size() > 0) {
  239. player.sendMessage(ChatColor.YELLOW + "Can you build? "
  240. + (set.canBuild(localPlayer) ? "Yes" : "No"));
  241. StringBuilder str = new StringBuilder();
  242. for (Iterator<ProtectedRegion> it = set.iterator(); it.hasNext();) {
  243. str.append(it.next().getId());
  244. if (it.hasNext()) {
  245. str.append(", ");
  246. }
  247. }
  248. player.sendMessage(ChatColor.YELLOW + "Applicable regions: " + str.toString());
  249. } else {
  250. player.sendMessage(ChatColor.YELLOW + "WorldGuard: No defined regions here!");
  251. }
  252. event.setCancelled(true);
  253. }
  254. }
  255. }
  256. /**
  257. * Called when a player steps on a pressure plate or tramples crops.
  258. *
  259. * @param event Thrown event
  260. */
  261. private void handlePhysicalInteract(PlayerInteractEvent event) {
  262. if (event.isCancelled()) return;
  263. Player player = event.getPlayer();
  264. Block block = event.getClickedBlock(); //not actually clicked but whatever
  265. //int type = block.getTypeId();
  266. World world = player.getWorld();
  267. ConfigurationManager cfg = plugin.getGlobalStateManager();
  268. WorldConfiguration wcfg = cfg.get(world);
  269. if (block.getTypeId() == BlockID.SOIL && wcfg.disablePlayerCropTrampling) {
  270. event.setCancelled(true);
  271. return;
  272. }
  273. }
  274. @EventHandler(priority = EventPriority.HIGHEST)
  275. public void onPlayerRespawn(PlayerRespawnEvent event) {
  276. Player player = event.getPlayer();
  277. Location location = player.getLocation();
  278. ConfigurationManager cfg = plugin.getGlobalStateManager();
  279. WorldConfiguration wcfg = cfg.get(player.getWorld());
  280. if (wcfg.useRegions) {
  281. ApplicableRegionSet set = plugin.getRegionContainer().createQuery().getApplicableRegions(location);
  282. LocalPlayer localPlayer = plugin.wrapPlayer(player);
  283. com.sk89q.worldedit.Location spawn = set.getFlag(DefaultFlag.SPAWN_LOC, localPlayer);
  284. if (spawn != null) {
  285. event.setRespawnLocation(com.sk89q.worldedit.bukkit.BukkitUtil.toLocation(spawn));
  286. }
  287. }
  288. }
  289. @EventHandler(priority = EventPriority.HIGH)
  290. public void onItemHeldChange(PlayerItemHeldEvent event) {
  291. Player player = event.getPlayer();
  292. ConfigurationManager cfg = plugin.getGlobalStateManager();
  293. WorldConfiguration wcfg = cfg.get(player.getWorld());
  294. if (wcfg.removeInfiniteStacks
  295. && !plugin.hasPermission(player, "worldguard.override.infinite-stack")) {
  296. int newSlot = event.getNewSlot();
  297. ItemStack heldItem = player.getInventory().getItem(newSlot);
  298. if (heldItem != null && heldItem.getAmount() < 0) {
  299. player.getInventory().setItem(newSlot, null);
  300. player.sendMessage(ChatColor.RED + "Infinite stack removed.");
  301. }
  302. }
  303. }
  304. @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
  305. public void onPlayerTeleport(PlayerTeleportEvent event) {
  306. World world = event.getFrom().getWorld();
  307. Player player = event.getPlayer();
  308. ConfigurationManager cfg = plugin.getGlobalStateManager();
  309. WorldConfiguration wcfg = cfg.get(world);
  310. if (wcfg.useRegions) {
  311. ApplicableRegionSet set = plugin.getRegionContainer().createQuery().getApplicableRegions(event.getTo());
  312. ApplicableRegionSet setFrom = plugin.getRegionContainer().createQuery().getApplicableRegions(event.getFrom());
  313. LocalPlayer localPlayer = plugin.wrapPlayer(player);
  314. if (cfg.usePlayerTeleports) {
  315. if (null != plugin.getSessionManager().get(player).testMoveTo(player, event.getTo(), MoveType.TELEPORT)) {
  316. event.setCancelled(true);
  317. return;
  318. }
  319. }
  320. if (event.getCause() == TeleportCause.ENDER_PEARL) {
  321. if (!plugin.getGlobalRegionManager().hasBypass(localPlayer, world)
  322. && !(set.allows(DefaultFlag.ENDERPEARL, localPlayer)
  323. && setFrom.allows(DefaultFlag.ENDERPEARL, localPlayer))) {
  324. player.sendMessage(ChatColor.DARK_RED + "You're not allowed to go there.");
  325. event.setCancelled(true);
  326. return;
  327. }
  328. }
  329. try {
  330. if (event.getCause() == TeleportCause.CHORUS_FRUIT) {
  331. if (!plugin.getGlobalRegionManager().hasBypass(localPlayer, world)) {
  332. boolean allowFrom = setFrom.allows(DefaultFlag.CHORUS_TELEPORT, localPlayer);
  333. boolean allowTo = set.allows(DefaultFlag.CHORUS_TELEPORT, localPlayer);
  334. if (!allowFrom || !allowTo) {
  335. player.sendMessage(ChatColor.DARK_RED + "You're not allowed to teleport " +
  336. (!allowFrom ? "from here." : "there."));
  337. event.setCancelled(true);
  338. return;
  339. }
  340. }
  341. }
  342. } catch (NoSuchFieldError ignored) {}
  343. }
  344. }
  345. @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH)
  346. public void onPlayerPortal(PlayerPortalEvent event) {
  347. if (event.getTo() == null) { // apparently this counts as a cancelled event, implementation specific though
  348. return;
  349. }
  350. ConfigurationManager cfg = plugin.getGlobalStateManager();
  351. WorldConfiguration wcfg = cfg.get(event.getTo().getWorld());
  352. if (!wcfg.regionNetherPortalProtection) return;
  353. if (event.getCause() != TeleportCause.NETHER_PORTAL) {
  354. return;
  355. }
  356. if (!event.useTravelAgent()) { // either end travel (even though we checked cause) or another plugin is fucking with us, shouldn't create a portal though
  357. return;
  358. }
  359. TravelAgent pta = event.getPortalTravelAgent();
  360. if (pta == null) { // possible, but shouldn't create a portal
  361. return;
  362. }
  363. if (pta.findPortal(event.getTo()) != null) {
  364. return; // portal exists...it shouldn't make a new one
  365. }
  366. // HOPEFULLY covered everything the server can throw at us...proceed protection checking
  367. // a lot of that is implementation specific though
  368. // hackily estimate the area that could be effected by this event, since the server refuses to tell us
  369. int radius = pta.getCreationRadius();
  370. Location min = event.getTo().clone().subtract(radius, radius, radius);
  371. Location max = event.getTo().clone().add(radius, radius, radius);
  372. World world = event.getTo().getWorld();
  373. ProtectedRegion check = new ProtectedCuboidRegion("__portalcheck__", BukkitUtil.toVector(min.getBlock()), BukkitUtil.toVector(max.getBlock()));
  374. if (wcfg.useRegions && !plugin.getGlobalRegionManager().hasBypass(event.getPlayer(), world)) {
  375. RegionManager mgr = plugin.getRegionContainer().get(event.getTo().getWorld());
  376. if (mgr == null) return;
  377. ApplicableRegionSet set = mgr.getApplicableRegions(check);
  378. if (!set.testState(plugin.wrapPlayer(event.getPlayer()), DefaultFlag.BUILD)) {
  379. event.getPlayer().sendMessage(ChatColor.RED + "Destination is in a protected area.");
  380. event.setCancelled(true);
  381. return;
  382. }
  383. }
  384. }
  385. @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
  386. public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
  387. Player player = event.getPlayer();
  388. LocalPlayer localPlayer = plugin.wrapPlayer(player);
  389. World world = player.getWorld();
  390. ConfigurationManager cfg = plugin.getGlobalStateManager();
  391. WorldConfiguration wcfg = cfg.get(world);
  392. if (wcfg.useRegions && !plugin.getGlobalRegionManager().hasBypass(player, world)) {
  393. ApplicableRegionSet set = plugin.getRegionContainer().createQuery().getApplicableRegions(player.getLocation());
  394. Set<String> allowedCommands = set.queryValue(localPlayer, DefaultFlag.ALLOWED_CMDS);
  395. Set<String> blockedCommands = set.queryValue(localPlayer, DefaultFlag.BLOCKED_CMDS);
  396. CommandFilter test = new CommandFilter(allowedCommands, blockedCommands);
  397. if (!test.apply(event.getMessage())) {
  398. player.sendMessage(ChatColor.RED + event.getMessage() + " is not allowed in this area.");
  399. event.setCancelled(true);
  400. return;
  401. }
  402. }
  403. if (cfg.blockInGameOp) {
  404. if (opPattern.matcher(event.getMessage()).matches()) {
  405. player.sendMessage(ChatColor.RED + "/op can only be used in console (as set by a WG setting).");
  406. event.setCancelled(true);
  407. return;
  408. }
  409. }
  410. }
  411. }