From 9cd5755d0abdf1cc749a270800254d84af8dcf87 Mon Sep 17 00:00:00 2001 From: Vaquxine Date: Mon, 25 May 2015 20:09:09 -0500 Subject: [PATCH] Add CachedVaults Only writes vaults to file on server shutdown or player quit, rather than every inventory close event. Also caches for read() events. --- .../drtshock/playervaults/PlayerVaults.java | 4 ++ .../playervaults/listeners/Listeners.java | 23 +++++++-- .../vaultmanagement/CachedVaults.java | 48 +++++++++++++++++++ .../vaultmanagement/CachedVaultsMap.java | 16 +++++++ .../vaultmanagement/UUIDVaultManager.java | 37 ++++++++++---- 5 files changed, 115 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/drtshock/playervaults/vaultmanagement/CachedVaults.java create mode 100644 src/main/java/com/drtshock/playervaults/vaultmanagement/CachedVaultsMap.java diff --git a/src/main/java/com/drtshock/playervaults/PlayerVaults.java b/src/main/java/com/drtshock/playervaults/PlayerVaults.java index 17c641f..23c3f7c 100644 --- a/src/main/java/com/drtshock/playervaults/PlayerVaults.java +++ b/src/main/java/com/drtshock/playervaults/PlayerVaults.java @@ -99,6 +99,9 @@ public class PlayerVaults extends JavaPlugin { @Override public void onDisable() { for (Player player : Bukkit.getOnlinePlayers()) { + UUIDVaultManager.getInstance().getCachedVaults().flushVaultCacheToFile(player.getUniqueId()); + UUIDVaultManager.getInstance().getCachedVaults().deleteVaultCache(player.getUniqueId()); + if (this.inVault.containsKey(player.getName())) { Inventory inventory = player.getOpenInventory().getTopInventory(); if (inventory.getViewers().size() == 1) { @@ -117,6 +120,7 @@ public class PlayerVaults extends JavaPlugin { player.closeInventory(); } + saveSignsFile(); } diff --git a/src/main/java/com/drtshock/playervaults/listeners/Listeners.java b/src/main/java/com/drtshock/playervaults/listeners/Listeners.java index 0bafa21..80f5110 100644 --- a/src/main/java/com/drtshock/playervaults/listeners/Listeners.java +++ b/src/main/java/com/drtshock/playervaults/listeners/Listeners.java @@ -21,6 +21,7 @@ import com.drtshock.playervaults.util.Lang; import com.drtshock.playervaults.vaultmanagement.UUIDVaultManager; import com.drtshock.playervaults.vaultmanagement.VaultOperations; import com.drtshock.playervaults.vaultmanagement.VaultViewInfo; + import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.Sign; @@ -56,10 +57,17 @@ public class Listeners implements Listener { Inventory inv = player.getOpenInventory().getTopInventory(); if (inv.getViewers().size() == 1) { VaultViewInfo info = PlayerVaults.getInstance().getInVault().get(player.getUniqueId().toString()); - try { - vm.saveVault(inv, info.getHolderUUID(), info.getNumber()); - } catch (IOException e) { - // ignore + if(Bukkit.isPrimaryThread() && player.getUniqueId().equals(info.getHolderUUID())){ + // Running in main thread, and it's the player's own vault. So we can just cache this until logout. + UUIDVaultManager.getInstance().getCachedVaults().setCachedVault(info.getHolderUUID(), info.getNumber(), inv); + } else { + try { + // Cache and save. + UUIDVaultManager.getInstance().getCachedVaults().setCachedVault(info.getHolderUUID(), info.getNumber(), inv); + vm.saveVault(inv, info.getHolderUUID(), info.getNumber()); + } catch (IOException e) { + // ignore + } } PlayerVaults.getInstance().getOpenInventories().remove(info.toString()); @@ -69,6 +77,10 @@ public class Listeners implements Listener { } } + public void flushVaultCache(Player player){ + UUIDVaultManager.getInstance().getCachedVaults().flushVaultCacheToFile(player.getUniqueId()); + } + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onTeleport(PlayerTeleportEvent event) { saveVault(event.getPlayer()); @@ -77,6 +89,7 @@ public class Listeners implements Listener { @EventHandler(priority = EventPriority.HIGH) public void onQuit(PlayerQuitEvent event) { saveVault(event.getPlayer()); + flushVaultCache(event.getPlayer()); } @EventHandler(priority = EventPriority.HIGH) @@ -245,7 +258,7 @@ public class Listeners implements Listener { int num = info.getNumber(); String title = Lang.VAULT_TITLE.toString().replace("%number", String.valueOf(num)).replace("%p", info.getHolder()); if ((event.getClickedInventory().getTitle().equalsIgnoreCase(title) || event.isShiftClick()) && event.getCurrentItem() != null) { - if (PlayerVaults.getInstance().isBlockedMaterial(event.getCurrentItem().getType())) { + if (event.getCurrentItem() != null && PlayerVaults.getInstance().isBlockedMaterial(event.getCurrentItem().getType())) { event.setCancelled(true); player.sendMessage(Lang.TITLE.toString() + Lang.BLOCKED_ITEM.toString().replace("%m", event.getCurrentItem().getType().name())); } diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/CachedVaults.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/CachedVaults.java new file mode 100644 index 0000000..93919f8 --- /dev/null +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/CachedVaults.java @@ -0,0 +1,48 @@ +package com.drtshock.playervaults.vaultmanagement; + +import java.io.IOException; +import java.util.HashMap; +import java.util.UUID; + +import org.bukkit.inventory.Inventory; + +@SuppressWarnings("serial") +public class CachedVaults extends HashMap { + public void setCachedVault(UUID playerUUID, int id, Inventory inventory){ + CachedVaultsMap vaultCacheMap = this.containsKey(playerUUID) ? this.get(playerUUID) : new CachedVaultsMap(); + vaultCacheMap.setCachedVault(id, inventory); + this.put(playerUUID, vaultCacheMap); + } + + public Inventory getCachedVault(UUID playerUUID, int id){ + return this.containsKey(playerUUID) ? this.get(playerUUID).getCachedVault(id) : null; + } + + public boolean hasVaultCached(UUID playerUUID, int id){ + return this.containsKey(playerUUID) && this.get(playerUUID).getCachedVault(id) != null; + } + + public void clearVaultCache(UUID playerUUID){ + if(this.containsKey(playerUUID)){ + this.get(playerUUID).clear(); + } + } + + public void deleteVaultCache(UUID playerUUID){ + this.remove(playerUUID); + } + + public void flushVaultCacheToFile(UUID playerUUID){ + if(this.containsKey(playerUUID)){ + for(java.util.Map.Entry data : this.get(playerUUID).entrySet()){ + try { + UUIDVaultManager.getInstance().saveVault(data.getValue(), playerUUID, data.getKey()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + this.deleteVaultCache(playerUUID); + } + } +} diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/CachedVaultsMap.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/CachedVaultsMap.java new file mode 100644 index 0000000..16c77b4 --- /dev/null +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/CachedVaultsMap.java @@ -0,0 +1,16 @@ +package com.drtshock.playervaults.vaultmanagement; + +import java.util.HashMap; + +import org.bukkit.inventory.Inventory; + +@SuppressWarnings("serial") +public class CachedVaultsMap extends HashMap { + public void setCachedVault(int id, Inventory inventory){ + this.put(id, inventory); + } + + public Inventory getCachedVault(int id){ + return this.containsKey(id) ? this.get(id) : null; + } +} diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java index 642cf30..6112fe8 100644 --- a/src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java @@ -1,7 +1,12 @@ package com.drtshock.playervaults.vaultmanagement; -import com.drtshock.playervaults.PlayerVaults; -import com.drtshock.playervaults.util.Lang; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; @@ -10,11 +15,8 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; +import com.drtshock.playervaults.PlayerVaults; +import com.drtshock.playervaults.util.Lang; /** * Class to handle vault operations with new UUIDs. @@ -22,13 +24,19 @@ import java.util.UUID; public class UUIDVaultManager { private static UUIDVaultManager instance; + private static CachedVaults cachedVaults; public UUIDVaultManager() { instance = this; + cachedVaults = new CachedVaults(); } private final File directory = PlayerVaults.getInstance().getVaultData(); + public CachedVaults getCachedVaults(){ + return cachedVaults; + } + /** * Saves the inventory to the specified player and vault number. * @@ -65,6 +73,10 @@ public class UUIDVaultManager { * @param number The vault number. */ public Inventory loadOwnVault(Player player, int number, int size) { + if(cachedVaults.hasVaultCached(player.getUniqueId(), number)){ + return cachedVaults.getCachedVault(player.getUniqueId(), number); + } + if (size % 9 != 0) { size = 54; } @@ -96,6 +108,7 @@ public class UUIDVaultManager { PlayerVaults.getInstance().getOpenInventories().put(info.toString(), inv); } + cachedVaults.setCachedVault(player.getUniqueId(), number, inv); return inv; } @@ -106,6 +119,10 @@ public class UUIDVaultManager { * @param number The vault number. */ public Inventory loadOtherVault(UUID holder, int number, int size) { + if(cachedVaults.hasVaultCached(holder, number)){ + return cachedVaults.getCachedVault(holder, number); + } + if (size % 9 != 0) { size = 54; } @@ -128,6 +145,8 @@ public class UUIDVaultManager { } PlayerVaults.getInstance().getOpenInventories().put(info.toString(), inv); } + + cachedVaults.setCachedVault(holder, number, inv); return inv; } @@ -193,10 +212,12 @@ public class UUIDVaultManager { * @throws IOException Uh oh! */ public void deleteVault(CommandSender sender, UUID holder, int number) throws IOException { - File file = new File(directory, holder.toString() + ".yml"); + File file = new File(directory, holder.toString() + ".yml"); if (!file.exists()) { return; } + + cachedVaults.clearVaultCache(holder); FileConfiguration playerFile = YamlConfiguration.loadConfiguration(file); if (file.exists()) {