/** * bFundamentals 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.bFundamentals.player; import java.io.File; import java.io.FileNotFoundException; import java.util.Arrays; import java.util.HashMap; import java.util.logging.Level; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.inventory.PlayerInventory; import org.bukkit.plugin.messaging.Messenger; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.wrappers.WrappedChatComponent; import uk.codingbadgers.bFundamentals.bFundamentals; import uk.codingbadgers.bFundamentals.backup.BackupFactory; import uk.codingbadgers.bFundamentals.backup.PlayerBackup; import uk.codingbadgers.bFundamentals.message.Message; /** * The Basic Player class for all modules. */ public class FundamentalPlayer { protected Player m_player; protected HashMap<Class<? extends PlayerData>, PlayerData> m_playerData = new HashMap<Class<? extends PlayerData>, PlayerData>(); /** * Instantiates a new base player. * * @param player the bukkit player */ public FundamentalPlayer(Player player) { m_player = player; } /** * Gets the bukkit player associated to this FundamentalPlayer. * * @return the bukkit player * @see Player */ public Player getPlayer() { return m_player; } /** * Send message, will split at new line characters '\n' and send each part as a seperate message. * * @param msg the message to send */ public void sendMessage(String msg) { String[] messages = msg.split("\n"); for (String message : messages) { m_player.sendMessage(ChatColor.DARK_PURPLE + "[bFundamentals] " + ChatColor.RESET + message); } } /** * Send plugin message. * * @param channel the plugin channel * @param message the message, will be split up into separate messages with * header if the message is longer than 1024 bytes long * @return true if successful, false if channel was not registered */ public boolean sendClientMessage(String channel, String message) { byte[] bytes = message.getBytes(); if (!Bukkit.getMessenger().isOutgoingChannelRegistered(bFundamentals.getInstance(), channel)) { return false; } if (bytes.length > Messenger.MAX_MESSAGE_SIZE) { String header = "Client Message; length:" + Math.ceil((double) bytes.length / (double) Messenger.MAX_MESSAGE_SIZE); m_player.sendPluginMessage(bFundamentals.getInstance(), channel, header.getBytes()); while(true) { byte[] toSend = Arrays.copyOf(bytes, Messenger.MAX_MESSAGE_SIZE); m_player.sendPluginMessage(bFundamentals.getInstance(), channel, toSend); try { bytes = Arrays.copyOfRange(bytes, Messenger.MAX_MESSAGE_SIZE, bytes.length); } catch (Exception ex) { break; } } } else { m_player.sendPluginMessage(bFundamentals.getInstance(), channel, bytes); } return true; } /** * Gets the location of the player. * * @return the location */ public Location getLocation() { return m_player.getLocation(); } /** * Gets any player data of the given data ID. * * @param dataID the data type to lookup * @return the player data if it exists, else null. * @see PlayerData */ @SuppressWarnings("unchecked") public <T extends PlayerData> T getPlayerData(Class<? extends T> dataID) { return (T) m_playerData.get(dataID); } /** * Gets the player data for a given data id * * @param clazz the string representation of the datatype class * @return the player data if it exists, else null. * @see PlayerData * @throws ClassNotFoundException if the class cannot be located */ public PlayerData getPlayerdata(String clazz) throws ClassNotFoundException { return m_playerData.get(Class.forName(clazz)); } /** * Adds some player data, removing any old instances of the player data * * @param data the data to add to this player * @see PlayerData */ public void addPlayerData(PlayerData data) { final Class<? extends PlayerData> dataID = data.getClass(); removePlayerData(dataID); m_playerData.put(dataID, data); } /** * Removes any data with the given data id * * @param dataID the data type to remove * @see PlayerData */ public void removePlayerData(Class<?> dataID) { if (m_playerData.containsKey(dataID)) { m_playerData.remove(dataID); } } /** * Release any stored data about the player, called on leave. */ public void destroy() { m_playerData.clear(); m_player = null; } /** * Backup a player to a file based on their name in a given folder. * Do not clear the players inventory though. * * @param BackupFolder The folder the backup should be created in */ public PlayerBackup backupInventory(File backupFolder) { return backupInventory(backupFolder, false); } /** * Backup a player to a file based on their name in a given folder. * * @param BackupFolder The folder the backup should be created in * @param clearInv clear the players inventory after backing up */ public PlayerBackup backupInventory(File backupFolder, boolean clearInv) { File backupFile = new File(backupFolder + File.separator + m_player.getName() + ".json"); PlayerBackup backup = BackupFactory.createBackup(backupFile, m_player); // clear the inventory only if the backup was successful if (clearInv && backup != null) { clearInventory(true); } return backup; } /** * Restore a player to a backup from the given folder * * @param backupFolder The folder that the players backup resides in * @return true if successful and false otherwise */ public boolean restoreInventory(File restoreFolder) throws FileNotFoundException { clearInventory(true); File backupFile = new File(restoreFolder + File.separator + m_player.getName() + ".json"); if (!backupFile.exists()) { throw(new FileNotFoundException("A backup file could not be found for the player " + m_player.getName() + " in the folder " + restoreFolder.getAbsolutePath())); } PlayerBackup backup = BackupFactory.readBackup(backupFile); if (backup != null) { backup.restore(m_player); backup.deleteFile(); return true; } return false; } /** * Clear all items from a players inventory * * @param clearArmour Should we clear the players armour as well * @return true if successful and false otherwise */ public void clearInventory(boolean clearArmour) { PlayerInventory inventory = m_player.getInventory(); inventory.clear(); if (clearArmour) { inventory.setHelmet(null); inventory.setChestplate(null); inventory.setLeggings(null); inventory.setBoots(null); } } /** * Send a custom formated message to a player * * @param message the messge to send */ public void sendMessage(Message message) { String json = bFundamentals.getGsonInstance().toJson(message); if (bFundamentals.getConfigurationManager().isDebugEnabled()) { bFundamentals.log(Level.INFO, json); } try { PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.CHAT); packet.getChatComponents().write(0, WrappedChatComponent.fromJson(json)); ProtocolLibrary.getProtocolManager().sendServerPacket(this.m_player, packet); } catch (Exception ex) { throw new RuntimeException(ex); } } }