/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.arkhamnetwork.playersync.struct; import com.arkhamnetwork.listeners.LogoutListener; import com.earth2me.essentials.User; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigDecimal; import java.nio.file.Files; import java.nio.file.Paths; import java.sql.SQLException; import java.util.Collection; import java.util.HashMap; import java.util.Map.Entry; import java.util.UUID; import lombok.Getter; import net.ess3.api.MaxMoneyException; import org.apache.commons.lang.SerializationException; import org.arkhamnetwork.playersync.PlayerSync; import org.arkhamnetwork.playersync.managers.SQLManager; import org.arkhamnetwork.playersync.utils.CompressionUtils; import org.arkhamnetwork.playersync.utils.FileUtils; import org.arkhamnetwork.playersync.utils.InventoryUtils; import org.arkhamnetwork.playersync.utils.LocationUtils; import org.arkhamnetwork.playersync.utils.LogicUtils; import org.arkhamnetwork.playersync.utils.PlayerUtils; import org.arkhamnetwork.playersync.utils.PotionEffectUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.potion.PotionEffect; import org.json.simple.parser.ParseException; /** * * @author devan_000 */ public final class PlayerSyncUser { private final PlayerSync plugin = PlayerSync.get(); @Getter private boolean grabbing = true; @Getter private boolean saving = false; @Getter private Player bukkitPlayer; @Getter private double exp = 0; @Getter private double health = 20; @Getter private double maxHealth = 20; @Getter private double foodLevel = 20; @Getter private Location location = plugin.getServer().getWorlds().get(0).getSpawnLocation(); @Getter private BigDecimal balance = new BigDecimal(0); @Getter private HashMap<String, Location> homes = new HashMap<>(); @Getter private HashMap<String, Long> kit_cooldowns = new HashMap<>(); private ItemStack[] cachedInventory = null; private ItemStack[] cachedArmor = null; private ItemStack[] cachedEnderchest = null; private PotionEffect[] cachedEffects = null; public PlayerSyncUser(UUID uuid, String userName) { try { if (!SQLManager.DB.databaseContainsUUID(uuid.toString())) { plugin.new_player_uuids.add(uuid.toString()); SQLManager.DB.addUserToDatabase(uuid.toString()); } downloadDataAsync(uuid, userName); } catch (SQLException | SerializationException | ParseException ex) { } } public void downloadDataAsync(final UUID uuid, final String userName) throws SerializationException, ParseException { try { grabbing = true; //Set there data as online SQLManager.DB.saveString("is_online", uuid.toString(), "true"); SQLManager.DB.saveString("online_server_address", uuid.toString(), (plugin.getServer().getIp() + ":" + plugin.getServer().getPort())); //Inventory cachedInventory = InventoryUtils.inventoryFromBytes(SQLManager.DB.getBytes("player_inventory", uuid.toString())); //Armor cachedArmor = InventoryUtils.inventoryFromBytes(SQLManager.DB.getBytes("player_armor", uuid.toString())); //Enderchest cachedEnderchest = InventoryUtils.inventoryFromBytes(SQLManager.DB.getBytes("player_enderchest", uuid.toString())); //Effects cachedEffects = PotionEffectUtils.effectsFromBytes(SQLManager.DB.getBytes("player_potioneffects", uuid.toString())); //Exp Level exp = ((float) SQLManager.DB.getDouble("player_explevel", uuid.toString())); //Health health = (SQLManager.DB.getDouble("player_health", uuid.toString())); //Max Health maxHealth = (SQLManager.DB.getDouble("player_maxhealth", uuid.toString())); //Food Level foodLevel = ((int) SQLManager.DB.getDouble("player_food", uuid.toString())); //Location (thx harry /s/s/s) location = LocationUtils.convertStringToLocation(SQLManager.DB.getString("player_location", uuid.toString()), true); // Get vault-supported balance. balance = new BigDecimal(SQLManager.DB.getDouble("player_balance", uuid.toString())); // Get a map of "home name" and their matching location. homes = LocationUtils.convertStringToHomeMap(SQLManager.DB.getString("player_homes", uuid.toString())); // Get all essential's kit cooldowns kit_cooldowns = LogicUtils.getKitCooldownsFromString(SQLManager.DB.getString("player_kit_cooldowns", uuid.toString())); //If they are not first time joining we create a player dat to prevent essentials from flipping. if (!plugin.new_player_uuids.contains(uuid.toString())) { try { File destination = new File(plugin.getServer().getWorlds().get(0).getName() + "/playerdata/" + uuid + ".dat"); if (destination.exists()) { destination.delete(); } destination.createNewFile(); InputStream in = plugin.getResource("template.dat"); try (OutputStream out = new FileOutputStream(destination)) { byte[] buffer = new byte[1024]; int bytesRead; //read from is to buffer while ((bytesRead = in.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } out.flush(); } } catch (IOException ex) { } } try { //Handle arkhamcolorchat downloading new File("plugins/ArkhamColorChat/users/" + userName + ".yml").delete(); FileUtils.saveBytesToFile(CompressionUtils.uncompress(SQLManager.DB.getBytes("arkhamcolorchat_datafile", uuid.toString())), new File("plugins/ArkhamColorChat/users/" + userName + ".yml")); } catch (SQLException err) { } try { //Handle marriage downloading new File("plugins/Marriage/playerdata/" + userName + ".yml").delete(); FileUtils.saveBytesToFile(CompressionUtils.uncompress(SQLManager.DB.getBytes("marriage_datafile", uuid.toString())), new File("plugins/Marriage/playerdata/" + userName + ".yml")); } catch (SQLException err) { } try { //Handle redeemmcmmo downloading new File("plugins/RedeemMCMMO/users/" + userName + ".yml").delete(); FileUtils.saveBytesToFile(CompressionUtils.uncompress(SQLManager.DB.getBytes("redeemmcmmo_datafile", uuid.toString())), new File("plugins/RedeemMCMMO/users/" + userName + ".yml")); } catch (SQLException err) { } try { //Handle users downloading new File("plugins/MagicCrates/users/" + userName + ".yml").delete(); FileUtils.saveBytesToFile(CompressionUtils.uncompress(SQLManager.DB.getBytes("magiccrates_datafile", uuid.toString())), new File("plugins/MagicCrates/Users/" + userName + ".yml")); } catch (SQLException err) { } } catch (SQLException ex) { ex.printStackTrace(); try { //Set there data as offline SQLManager.DB.saveString("is_online", uuid.toString(), "false"); SQLManager.DB.saveString("online_server_address", uuid.toString(), ""); } catch (SQLException ex1) { } grabbing = false; bukkitPlayer.setMetadata("no_save", new FixedMetadataValue(plugin, true)); plugin.getServer().getScheduler().runTask(plugin, new Runnable() { public void run() { bukkitPlayer.kickPlayer(ChatColor.RED + "An error was encountered while trying to load your permissions."); } }); return; } finally { grabbing = false; } } public void setPlayerDataSync(Player player) { this.bukkitPlayer = player; //Remove any lingering data bukkitPlayer.getInventory().clear(); bukkitPlayer.getInventory().setArmorContents(null); bukkitPlayer.getEnderChest().clear(); for (PotionEffect effect : player.getActivePotionEffects()) { player.removePotionEffect(effect.getType()); } bukkitPlayer.setExp(0); bukkitPlayer.setHealth(20); bukkitPlayer.setMaxHealth(20); bukkitPlayer.setFoodLevel(20); //Restore essentials user. try { User ess_usr = plugin.getEssentials().getUser(bukkitPlayer.getUniqueId()); // Setup balance. ess_usr.setMoney(balance); // Setup homes. for (Entry<String, Location> data : homes.entrySet()) { ess_usr.setHome(data.getKey(), data.getValue()); } // Setup kit cooldowns. for (Entry<String, Long> data : kit_cooldowns.entrySet()) { ess_usr.setKitTimestamp(data.getKey(), data.getValue()); } } catch (MaxMoneyException e) { } //Handle normal data if (cachedInventory != null) { bukkitPlayer.getInventory().setContents(cachedInventory); } if (cachedArmor != null) { bukkitPlayer.getInventory().setArmorContents(cachedArmor); } if (cachedEnderchest != null) { bukkitPlayer.getEnderChest().setContents(cachedEnderchest); } if (cachedEffects != null) { for (PotionEffect effect : cachedEffects) { bukkitPlayer.addPotionEffect(effect); } } bukkitPlayer.setExp((float) exp); bukkitPlayer.setHealth(health); bukkitPlayer.setMaxHealth(maxHealth); bukkitPlayer.setFoodLevel((int) foodLevel); //Handle world teleporting if (location != null && location.getWorld() != null) { bukkitPlayer.teleport(location); } else { bukkitPlayer.teleport(plugin.getServer().getWorlds().get(0).getSpawnLocation()); } } public static interface Callback { public void done(); } public void save(final String name, final UUID uuid, final ItemStack[] inventoryContents, final ItemStack[] armorContents, final ItemStack[] enderchestContents, final Collection<PotionEffect> effects, final float exp, final double health, final double maxHealth, final double food, final Location location) { save(name, uuid, inventoryContents, armorContents, enderchestContents, effects, exp, health, maxHealth, food, location, true, null); } public void save(final String name, final UUID uuid, final ItemStack[] inventoryContents, final ItemStack[] armorContents, final ItemStack[] enderchestContents, final Collection<PotionEffect> effects, final float exp, final double health, final double maxHealth, final double food, final Location location, final boolean GCFilesAsync) { save(name, uuid, inventoryContents, armorContents, enderchestContents, effects, exp, health, maxHealth, food, location, GCFilesAsync, null); } public void save(final String name, final UUID uuid, final ItemStack[] inventoryContents, final ItemStack[] armorContents, final ItemStack[] enderchestContents, final Collection<PotionEffect> effects, final float exp, final double health, final double maxHealth, final double food, final Location location, final boolean GCFilesAsync, final Callback callback) { if (saving || grabbing) { return; } saving = true; if (!PlayerSync.shutting_down) { plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() { public void run() { saveMethod(bukkitPlayer, name, uuid, inventoryContents, armorContents, enderchestContents, effects, exp, health, maxHealth, food, location, GCFilesAsync, callback); } }, 20L); } else { saveMethod(bukkitPlayer, name, uuid, inventoryContents, armorContents, enderchestContents, effects, exp, health, maxHealth, food, location, GCFilesAsync, callback); } } public void saveMethod(final Player player, final String name, final UUID uuid, final ItemStack[] inventoryContents, final ItemStack[] armorContents, final ItemStack[] enderchestContents, final Collection<PotionEffect> effects, final float exp, final double health, final double maxHealth, final double food, final Location location, final boolean GCFilesAsync, Callback callback) { try { try { LogoutListener.uploadEnchantTokens(player); } catch (Exception ex) { ex.printStackTrace(); } //Call API save methods. try { com.arkhamnetwork.ArkhamBags.listeners.LogoutListener.saveAllBagsToSQL(uuid.toString(), name); } catch (Exception ex) { ex.printStackTrace(); } //Inventory SQLManager.DB.saveBytes("player_inventory", uuid.toString(), InventoryUtils.inventoryToBytes(inventoryContents)); //Armor SQLManager.DB.saveBytes("player_armor", uuid.toString(), InventoryUtils.inventoryToBytes(armorContents)); //Enderchest SQLManager.DB.saveBytes("player_enderchest", uuid.toString(), InventoryUtils.inventoryToBytes(enderchestContents)); //Effects SQLManager.DB.saveBytes("player_potioneffects", uuid.toString(), PotionEffectUtils.effectsToBytes(effects)); //Exp SQLManager.DB.saveDouble("player_explevel", uuid.toString(), exp); //Health SQLManager.DB.saveDouble("player_health", uuid.toString(), health); //Max Health SQLManager.DB.saveDouble("player_maxhealth", uuid.toString(), maxHealth); //Food SQLManager.DB.saveDouble("player_food", uuid.toString(), food); //Location SQLManager.DB.saveString("player_location", uuid.toString(), LocationUtils.convertLocationToString(location)); //Balance SQLManager.DB.saveDouble("player_balance", uuid.toString(), plugin.getEconomy().getBalance(Bukkit.getOfflinePlayer(uuid))); User ess_usr = plugin.getEssentials().getUser(uuid); //Homes try { for (String h : ess_usr.getHomes()) { homes.put(h, ess_usr.getHome(h)); } } catch (Exception err) { // WTF essentials nice random catches. } SQLManager.DB.saveString("player_homes", uuid.toString(), LocationUtils.convertHomeMapToString(homes)); //Kits try { for (String kit : plugin.getEssentials().getSettings().getKits().getKeys(false)) { kit_cooldowns.put(kit, ess_usr.getKitTimestamp(kit)); } } catch (Exception err) { // WTF essentials nice random catches. } SQLManager.DB.saveString("player_kit_cooldowns", uuid.toString(), LogicUtils.getStringFromKitCooldowns(kit_cooldowns)); //Safeguard essentials. plugin.getEssentials().getUser(uuid).reset(); try { if (new File("plugins/ArkhamColorChat/users/" + name + ".yml").exists()) { //Save the arkhamcolorchat file SQLManager.DB.saveBytes("arkhamcolorchat_datafile", uuid.toString(), CompressionUtils.compress(Files.readAllBytes(Paths.get("plugins/ArkhamColorChat/users/" + name + ".yml")))); } } catch (IOException | SQLException ex) { } try { if (new File("plugins/Marriage/playerdata/" + name + ".yml").exists()) { //Save the marriage file SQLManager.DB.saveBytes("marriage_datafile", uuid.toString(), CompressionUtils.compress(Files.readAllBytes(Paths.get("plugins/Marriage/playerdata/" + name + ".yml")))); } } catch (IOException | SQLException ex) { } try { if (new File("plugins/RedeemMCMMO/users/" + name + ".yml").exists()) { //Handle redeemmcmmo file SQLManager.DB.saveBytes("redeemmcmmo_datafile", uuid.toString(), CompressionUtils.compress(Files.readAllBytes(Paths.get("plugins/RedeemMCMMO/users/" + name + ".yml")))); } } catch (IOException | SQLException ex) { } try { if (new File("plugins/MagicCrates/Users/" + name + ".yml").exists()) { //Handle magiccrates file SQLManager.DB.saveBytes("magiccrates_datafile", uuid.toString(), CompressionUtils.compress(Files.readAllBytes(Paths.get("plugins/MagicCrates/Users/" + name + ".yml")))); } } catch (IOException | SQLException ex) { } //Set there data as offline SQLManager.DB.saveString("is_online", uuid.toString(), "false"); SQLManager.DB.saveString("online_server_address", uuid.toString(), ""); plugin.users.remove(uuid); if (GCFilesAsync) { //Delete the old files //Delay this to prevent resaving. plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() { public void run() { PlayerUtils.deletePlayerdataASync(uuid, name); } }, 10L); } else { PlayerUtils.deletePlayerdataASync(uuid, name); } if (callback != null) { callback.done(); } } catch (SQLException ex) { try { //Set there data as offline SQLManager.DB.saveString("is_online", uuid.toString(), "false"); SQLManager.DB.saveString("online_server_address", uuid.toString(), ""); } catch (SQLException ex1) { saving = false; } saving = false; } finally { saving = false; } } public void saveSimple(final UUID uuid) { try { //Set there data as offline SQLManager.DB.saveString("is_online", uuid.toString(), "false"); SQLManager.DB.saveString("online_server_address", uuid.toString(), ""); } catch (SQLException ex) { } } }