/* * This file is part of Libelula Minecraft Edition Project. * * Libelula Minecraft Edition 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. * * Libelula Minecraft Edition 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 Libelula Minecraft Edition. * If not, see <http://www.gnu.org/licenses/>. * */ package me.libelula.capturethewool; import java.io.File; import java.io.IOException; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.TreeSet; import java.util.concurrent.locks.ReentrantLock; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Color; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.LeatherArmorMeta; import org.bukkit.potion.PotionEffect; import org.kitteh.tag.TagAPI; /** * * @author Diego D'Onofrio <ddonofrio@member.fsf.org> * @version 1.0 * */ public class PlayerManager { private class PlayerOptions { boolean viewOthersSpectators; boolean viewOthersDeathMessages; boolean viewBlood; } private final Main plugin; private final File playersFile; private final YamlConfiguration playersConfig; private final TreeMap<String, PlayerOptions> playerOptions; private final TreeMap<String, TeamManager.TeamId> playerTeam; private final ReentrantLock _playerTeam_mutex; private final ItemStack helpBook; private final ItemStack joinMenuItem; private final TreeMap<String, Map.Entry<Long, String>> lastDamager; private final TreeSet<String> falseSpectators; public PlayerManager(Main plugin) { playersFile = new File(plugin.getDataFolder(), "players.yml"); playersConfig = new YamlConfiguration(); this.plugin = plugin; playerOptions = new TreeMap<>(); lastDamager = new TreeMap<>(); playerTeam = new TreeMap<>(); _playerTeam_mutex = new ReentrantLock(true); helpBook = plugin.lm.getHelpBook(); ItemStack menuItem = new ItemStack(Material.ENCHANTED_BOOK); ItemMeta im = menuItem.getItemMeta(); im.setDisplayName(plugin.lm.getText("help-menu-item.title")); menuItem.setItemMeta(im); joinMenuItem = menuItem; falseSpectators = new TreeSet<>(); } public void setFalseSpectator(Player player) { _playerTeam_mutex.lock(); try { falseSpectators.add(player.getName()); } finally { _playerTeam_mutex.unlock(); } } public void setLastDamager(Player player, Player damager) { Map.Entry<Long, String> entry = new AbstractMap.SimpleEntry<>(new Date().getTime(), damager.getName()); lastDamager.put(player.getName(), entry); } public String getLastDamager(Player player) { String ret = null; Map.Entry<Long, String> entry = lastDamager.remove(player.getName()); if (entry != null) { long upTo = new Date().getTime() - (1000 * 10); if (entry.getKey() > upTo) { ret = entry.getValue(); } } return ret; } public ItemStack getMenuItem() { return joinMenuItem; } public void load() { try { playersConfig.load(playersFile); } catch (IOException | InvalidConfigurationException ex) { plugin.getLogger().severe(ex.toString()); } for (String playerName : playersConfig.getKeys(false)) { PlayerOptions po = new PlayerOptions(); po.viewOthersSpectators = playersConfig.getBoolean(playerName + "." + "view.others-spectators"); po.viewOthersDeathMessages = playersConfig.getBoolean(playerName + "." + "view.others-deadMessages"); po.viewBlood = playersConfig.getBoolean(playerName + "." + "view.blood"); playerOptions.put(playerName, po); } } public boolean toggleSeeOthersSpectators(Player player) { PlayerOptions po = playerOptions.get(player.getName()); if (po != null) { po.viewOthersSpectators = !po.viewOthersSpectators; } else { po = new PlayerOptions(); po.viewOthersSpectators = !canSeeOthersSpectators(player); } playerOptions.put(player.getName(), po); updatePlayerList(player); return po.viewOthersSpectators; } public boolean toogleOthersDeathMessages(Player player) { PlayerOptions po = playerOptions.get(player.getName()); if (po != null) { po.viewOthersDeathMessages = !po.viewOthersDeathMessages; } else { po = new PlayerOptions(); po.viewOthersDeathMessages = !canSeeOthersDeathMessages(player); } playerOptions.put(player.getName(), po); return po.viewOthersDeathMessages; } public boolean canSeeOthersSpectators(Player player) { PlayerOptions po = playerOptions.get(player.getName()); return po == null || po.viewOthersSpectators; } public boolean canSeeOthersDeathMessages(Player player) { PlayerOptions po = playerOptions.get(player.getName()); return po == null || po.viewOthersDeathMessages; } public ChatColor getChatColor(Player player) { ChatColor cc = ChatColor.WHITE; TeamManager.TeamId teamId = playerTeam.get(player.getName()); if (teamId != null) { cc = plugin.tm.getChatColor(teamId); } return cc; } public void addPlayerTo(Player player, TeamManager.TeamId teamId) { _playerTeam_mutex.lock(); falseSpectators.remove(player.getName()); try { TeamManager.TeamId previousTeam = playerTeam.put(player.getName(), teamId); if (previousTeam != null) { plugin.tm.removeFromTeam(player, previousTeam); } plugin.tm.addToTeam(player, teamId); clearInventory(player); if (teamId != TeamManager.TeamId.SPECTATOR) { disguise(player, teamId); } else { setSpectator(player); } updatePlayerList(player); player.sendMessage(plugin.lm.getMessage("moved-to-" + teamId.name().toLowerCase())); } finally { _playerTeam_mutex.unlock(); } } public TeamManager.TeamId clearTeam(Player player) { TeamManager.TeamId teamId; _playerTeam_mutex.lock(); falseSpectators.remove(player.getName()); try { clearInventory(player); dress(player); teamId = playerTeam.remove(player.getName()); plugin.tm.removeFromTeam(player, teamId); } finally { _playerTeam_mutex.unlock(); } return teamId; } public TeamManager.TeamId getTeamId(Player player) { return playerTeam.get(player.getName()); } public boolean isSpectator(Player player) { boolean resp = false; TeamManager.TeamId teamId = playerTeam.get(player.getName()); if (teamId != null) { if (teamId != TeamManager.TeamId.SPECTATOR) { if (falseSpectators.contains(player.getName())) { resp = true; } } else { resp = true; } } return resp; } public void clearInventory(Player player) { ItemStack air = new ItemStack(Material.AIR); player.getInventory().clear(); player.getInventory().setBoots(air); player.getInventory().setChestplate(air); player.getInventory().setHelmet(air); player.getInventory().setLeggings(air); for (PotionEffect effect : player.getActivePotionEffects()) { player.removePotionEffect(effect.getType()); } player.setFireTicks(0); } public void dress(Player player) { player.setGameMode(GameMode.SURVIVAL); player.setHealth(20); player.setFoodLevel(20); player.setFireTicks(0); clearInventory(player); player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); } public void updatePlayerList(Player player) { boolean playerCanSeeOtherHidden = canSeeOthersSpectators(player); boolean playerIsSpect = isSpectator(player); TreeSet<Player> playersInGame = new TreeSet<>(new Tools.PlayerComparator()); playersInGame.addAll(player.getWorld().getPlayers()); for (Player other : playersInGame) { boolean otherIsSpectator = isSpectator(other); boolean canSeeOthersSpectators = canSeeOthersSpectators(other); if (playerIsSpect) { if (!otherIsSpectator) { other.hidePlayer(player); } else { if (canSeeOthersSpectators) { other.showPlayer(player); } else { other.hidePlayer(player); } } } else { other.showPlayer(player); } if (!otherIsSpectator) { player.showPlayer(other); } else { if (!playerIsSpect) { player.hidePlayer(other); } else { if (playerCanSeeOtherHidden) { player.showPlayer(other); } else { player.hidePlayer(other); } } } } } public void disguise(Player player, TeamManager.TeamId teamId) { LeatherArmorMeta leatherMeta; List<String> armourBrand = new ArrayList<>(); armourBrand.add(plugin.tm.armourBrandName); Color tshirtColor = plugin.tm.getTshirtColor(teamId); ChatColor teamChatColor = plugin.tm.getChatColor(teamId); String teamName = plugin.tm.getName(teamId); clearInventory(player); ItemStack tshirt = new ItemStack(Material.LEATHER_CHESTPLATE); leatherMeta = (LeatherArmorMeta) tshirt.getItemMeta(); leatherMeta.setColor(tshirtColor); leatherMeta.setDisplayName(teamChatColor + teamName); leatherMeta.setLore(armourBrand); tshirt.setItemMeta(leatherMeta); ItemStack boots = new ItemStack(Material.LEATHER_BOOTS); leatherMeta = (LeatherArmorMeta) boots.getItemMeta(); leatherMeta.setColor(tshirtColor); leatherMeta.setDisplayName(teamChatColor + teamName); leatherMeta.setLore(armourBrand); boots.setItemMeta(leatherMeta); ItemStack leggings = new ItemStack(Material.LEATHER_LEGGINGS); leatherMeta = (LeatherArmorMeta) leggings.getItemMeta(); leatherMeta.setColor(tshirtColor); leatherMeta.setDisplayName(teamChatColor + teamName); leatherMeta.setLore(armourBrand); leggings.setItemMeta(leatherMeta); ItemStack helmet = new ItemStack(Material.LEATHER_HELMET); leatherMeta = (LeatherArmorMeta) helmet.getItemMeta(); leatherMeta.setColor(tshirtColor); leatherMeta.setDisplayName(teamChatColor + teamName); leatherMeta.setLore(armourBrand); helmet.setItemMeta(leatherMeta); player.setDisplayName(teamChatColor + player.getName()); player.getInventory().setBoots(boots); player.getInventory().setChestplate(tshirt); player.getInventory().setLeggings(leggings); player.getInventory().setHelmet(helmet); player.setGameMode(GameMode.SURVIVAL); player.setFireTicks(0); updatePlayerList(player); try { TagAPI.refreshPlayer(player); } catch (Exception ex) { plugin.getLogger().warning(ex.toString()); } } private void setSpectator(Player player) { player.setHealth(20); player.setFoodLevel(20); plugin.pm.clearInventory(player); player.setGameMode(GameMode.ADVENTURE); player.setAllowFlight(true); player.getInventory().addItem(helpBook); player.getInventory().addItem(joinMenuItem); updatePlayerList(player); } }