/** * bCreative 1.2-SNAPSHOT * Copyright (C) 2013 CodingBadgers <plugins@mcbadgercraft.com> * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ package uk.codingbadgers.bcreative; import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.logging.Level; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerGameModeChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerPickupItemEvent; import uk.codingbadgers.bFundamentals.bFundamentals; import uk.codingbadgers.bFundamentals.module.Module; import uk.codingbadgers.bFundamentals.player.FundamentalPlayer; public class bCreative extends Module implements Listener { /** * The list of worlds that bCreative is active in */ private List<String> activeWorlds = null; /** * The list of black listed interact materials */ private List<Material> interactBlacklist = null; /** * A hashmap of the last item a player tried to pickup */ private HashMap<Player, Location> playersLastPickupItem = null; /** * A list of all players whom are currently processing gamemode events */ private List<String> playerProcessingGameModeEvent = null; /** * The folder that player backups will be saved in */ private File backupFolder = null; /* * Called when the module is enabled */ @Override @SuppressWarnings("deprecation") public void onEnable() { register(this); // Create the folder where backups will go backupFolder = new File(this.getDataFolder() + File.separator + "playerBackups"); if (!backupFolder.exists()) { backupFolder.mkdirs(); } // Load the config FileConfiguration config = getConfig(); config.addDefault("worlds", new ArrayList<String>()); config.addDefault("interact-blacklist", Arrays.asList("ENDER_CHEST", "CHEST")); config.options().copyDefaults(true); saveConfig(); activeWorlds = new ArrayList<String>(); List<String> configWorlds = config.getStringList("worlds"); for (String worldName : configWorlds) activeWorlds.add(worldName.toLowerCase()); log(Level.INFO, "bCreative is active in the following worlds:"); for (String worldName : activeWorlds) log(Level.INFO, " - " + worldName); interactBlacklist = new ArrayList<Material>(); for (String materialId : config.getStringList("interact-blacklist")) { try { int id = Integer.parseInt(materialId); Material interactMaterial = Material.getMaterial(id); if (interactMaterial != null) { interactBlacklist.add(interactMaterial); } } catch (NumberFormatException ex) { Material interactMaterial = Material.getMaterial(materialId); if (interactMaterial == null) { interactMaterial = Material.matchMaterial(materialId); } if (interactMaterial != null) { interactBlacklist.add(interactMaterial); } } } log(Level.INFO, "bCreative will block interaction with the following materials:"); for (Material material : interactBlacklist) log(Level.INFO, " - " + material.name()); playersLastPickupItem = new HashMap<Player, Location>(); playerProcessingGameModeEvent = new ArrayList<String>(); } /* * Called when the module is disabled */ @Override public void onDisable() { activeWorlds.clear(); interactBlacklist.clear(); playersLastPickupItem.clear(); playerProcessingGameModeEvent.clear(); } /* * Called when a player interacts with something */ @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { final Player player = event.getPlayer(); // If the player has the interact permission, let them do what they want if (hasPermission(player, "bcreative.player.interact")) { return; } // We only care about creative players if (player.getGameMode() != GameMode.CREATIVE) { return; } // We only care about right click events if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { return; } // Is the player in a world where bCreative is active? if (!activeWorlds.contains(player.getWorld().getName().toLowerCase())) { return; } // Is the interacted material in our blacklist? final Material material = event.getClickedBlock().getType(); if (!interactBlacklist.contains(material)) { return; } // Cancel the event as the material is on the blacklist event.setCancelled(true); sendMessage(getName(), player, "You cannot open '" + material.name() + "' whilst in creative mode."); } /* * Called when a player drops an item */ @EventHandler public void onPlayerItemDrop(PlayerDropItemEvent event) { final Player player = event.getPlayer(); // If the player has this permission let them drop items if (hasPermission(player, "bcreative.player.item.drop")) { return; } // We only care about creative mode if (player.getGameMode() != GameMode.CREATIVE) { return; } // See if they are in a world where bCreative is active if (!activeWorlds.contains(player.getWorld().getName().toLowerCase())) { return; } // Cancel the drop event event.setCancelled(true); sendMessage(getName(), player, "You cannot drop items whilst in creative mode."); } /* * Called when a player picks up an item */ @EventHandler public void onPlayerItemPickup(PlayerPickupItemEvent event) { final Player player = event.getPlayer(); // If the player has this permission, let them pick things up if (hasPermission(player, "bcreative.player.item.pickup")) { return; } // We only care about creative mode if (player.getGameMode() != GameMode.CREATIVE) { return; } // Is bCreative active in this world? if (!activeWorlds.contains(player.getWorld().getName().toLowerCase())) { return; } // Cancel the pickup event event.setCancelled(true); // Get the item and the last item the player tried to pickup final Item item = event.getItem(); final Location lastKnown = playersLastPickupItem.get(player); if (lastKnown == null || lastKnown.distanceSquared(item.getLocation()) > 25) { sendMessage(getName(), player, "You cannot pickup items whilst in creative mode."); sendMessage(getName(), player, "Item removed from world."); if (lastKnown != null) { playersLastPickupItem.remove(player); } playersLastPickupItem.put(player, item.getLocation()); } item.remove(); } /* * Called when a players gamemode changes */ @EventHandler public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) { final Player player = event.getPlayer(); // If the player has this permission let them keep their gamemode inventory if (hasPermission(player, "bcreative.player.keepinventory")) { return; } // We are already processing a player gamemode event for this player if (playerProcessingGameModeEvent.contains(player.getName())) { return; } playerProcessingGameModeEvent.add(player.getName()); final String oldGameMode = player.getGameMode().name(); final String newGameMode = event.getNewGameMode().name(); final File backupFolder = new File(this.backupFolder + File.separator + oldGameMode); final File restoreFolder = new File(this.backupFolder + File.separator + newGameMode); final FundamentalPlayer fundamentalPlayer = bFundamentals.Players.getPlayer(player); fundamentalPlayer.backupInventory(backupFolder, true); try { fundamentalPlayer.restoreInventory(restoreFolder); } catch (FileNotFoundException ex) {} sendMessage(getName(), player, "Your " + oldGameMode.toLowerCase() + " inventory has been backed up."); sendMessage(getName(), player, "When you go back into " + oldGameMode.toLowerCase() + " mode your inventory will be restored."); if (playersLastPickupItem.containsKey(player)) { playersLastPickupItem.remove(player); } playerProcessingGameModeEvent.remove(player.getName()); } }