From 6309a32a3e03956431b4eec916304709a69c0146 Mon Sep 17 00:00:00 2001 From: Trever Fischer Date: Fri, 9 Nov 2012 12:02:05 -0500 Subject: [PATCH] Implement caminus vault API --- src/main/java/us/camin/JoinListener.java | 70 ++++++++++++++ src/main/java/us/camin/Plugin.java | 92 +++++++++++++++++++ src/main/java/us/camin/VaultCommand.java | 46 ++++++++++ .../java/us/camin/api/PlayerVaultSlot.java | 28 ++++++ src/main/java/us/camin/api/Server.java | 44 +++++++++ src/main/java/us/camin/api/ServerEvent.java | 2 + .../java/us/camin/api/VaultModifyEvent.java | 54 +++++++++++ src/main/resources/plugin.yml | 7 +- 8 files changed, 342 insertions(+), 1 deletion(-) create mode 100644 src/main/java/us/camin/VaultCommand.java create mode 100644 src/main/java/us/camin/api/PlayerVaultSlot.java create mode 100644 src/main/java/us/camin/api/VaultModifyEvent.java diff --git a/src/main/java/us/camin/JoinListener.java b/src/main/java/us/camin/JoinListener.java index 7f9ea4c..f1b553c 100644 --- a/src/main/java/us/camin/JoinListener.java +++ b/src/main/java/us/camin/JoinListener.java @@ -19,8 +19,11 @@ package us.camin; import java.util.logging.Logger; +import java.util.logging.Level; import org.bukkit.entity.Player; import org.bukkit.entity.Entity; +import org.bukkit.entity.Villager; +import org.bukkit.entity.LivingEntity; import org.bukkit.event.Listener; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerLoginEvent; @@ -28,12 +31,20 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerKickEvent; import org.bukkit.event.player.PlayerChatEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.weather.WeatherChangeEvent; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.entity.Arrow; import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.Inventory; import java.io.IOException; +import java.util.ArrayList; import us.camin.api.ValidationResponse; import us.camin.api.ClientEvent; @@ -101,6 +112,7 @@ public class JoinListener implements Listener { event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, resp.errorMessage); return; } + m_plugin.forgetVaultInventory(event.getPlayer()); } static public final String SESSION_METADATA_KEY = "caminus-session-id"; @@ -147,4 +159,62 @@ public class JoinListener implements Listener { m_plugin.sendEvent(evt); } } + + @EventHandler + public void onVaultmasterInteract(PlayerInteractEntityEvent event) { + System.out.println("Interacted with someone!"); + ArrayList vaultmasters = m_plugin.vaultmasters(); + Villager vaultmaster = null; + boolean found = false; + for(Villager v : vaultmasters) { + if (event.getRightClicked() == v) { + System.out.println("It was one of ours!"); + event.setCancelled(true); + found = true; + vaultmaster = v; + break; + } + } + if (!found) + return; + Inventory inv; + try { + inv = m_plugin.vaultInventory(event.getPlayer()); + } catch (IOException e) { + log.log(Level.SEVERE, "Couldn't fetch user's vault!", e); + event.getPlayer().sendMessage("Couldn't fetch your vault! api.camin.us might be down."); + return; + } + event.getPlayer().openInventory(inv); + } + + @EventHandler + public void onVaultmasterInventoryChange(InventoryCloseEvent event) { + Player p = (Player)event.getPlayer(); + try { + m_plugin.saveVault(p, m_plugin.vaultInventory(p)); + } catch (IOException e) { + log.log(Level.SEVERE, "Couldn't save user's vault!", e); + p.sendMessage("Your vault couldn't be saved to the server!"); + p.sendMessage("Your items are still held by the vaultmaster, but might vanish."); + } + } + + @EventHandler + public void onVaultmasterAttacked(EntityDamageEvent event) { + Entity target = event.getEntity(); + if (target instanceof Villager) { + Villager v = (Villager)target; + if (m_plugin.vaultmasters().contains(target)) { + if (event instanceof EntityDamageByEntityEvent) { + EntityDamageByEntityEvent e = (EntityDamageByEntityEvent)event; + if (e.getDamager() instanceof LivingEntity) { + v.setTarget((LivingEntity)e.getDamager()); + //Projectile weapon = v.launchProjectile(Arrow.class); + } + } + v.setHealth(v.getMaxHealth()); + } + } + } } diff --git a/src/main/java/us/camin/Plugin.java b/src/main/java/us/camin/Plugin.java index 6c15dfe..38e1ceb 100644 --- a/src/main/java/us/camin/Plugin.java +++ b/src/main/java/us/camin/Plugin.java @@ -28,15 +28,21 @@ import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.ServicePriority; import org.bukkit.plugin.ServicesManager; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.ChatColor; +import org.bukkit.entity.Villager; import net.milkbowl.vault.economy.Economy; import java.util.HashMap; +import java.util.ArrayList; import java.util.logging.Logger; import java.util.logging.Level; import java.io.IOException; +import java.util.ListIterator; import java.util.concurrent.Callable; import us.camin.api.Server; @@ -44,6 +50,8 @@ import us.camin.api.ServerEvent; import us.camin.api.BroadcastEvent; import us.camin.api.PlayerMessageEvent; import us.camin.api.ClientEvent; +import us.camin.api.VaultModifyEvent; +import us.camin.api.PlayerVaultSlot; import org.json.JSONException; public class Plugin extends JavaPlugin { @@ -53,7 +61,9 @@ public class Plugin extends JavaPlugin { private JoinListener m_listener; private MOTDCommand m_motdCommand; private VomitCommand m_vomitCommand; + private VaultCommand m_vaultCommand; private ServerEventPoller m_eventPoll; + private ArrayList m_vaultmasters; public Server api() { return m_api; @@ -63,6 +73,9 @@ public class Plugin extends JavaPlugin { log.info("[Caminus] Plugin disabled"); m_eventPoll.stop(); m_api = null; + for (Villager v : m_vaultmasters) { + v.remove(); + } } public void handleEvent(ServerEvent e) { @@ -82,6 +95,26 @@ public class Plugin extends JavaPlugin { return null; } }); + } else if (e instanceof VaultModifyEvent) { + final VaultModifyEvent evt = (VaultModifyEvent)(e); + getServer().getScheduler().callSyncMethod(this, new Callable() { + public Void call() { + Inventory inv; + try { + inv = vaultInventory(getServer().getPlayer(evt.player)); + } catch (IOException e) { + return null; + } + for (PlayerVaultSlot s : evt.contents) { + if (s.quantity == -1) { + inv.clear(s.position); + } else { + inv.setItem(s.position, new ItemStack(s.item, s.quantity, s.damage, s.data)); + } + } + return null; + } + }); } try { m_api.notifyEventHandled(e); @@ -102,7 +135,17 @@ public class Plugin extends JavaPlugin { } } + public void addVaultmaster(Villager v) { + m_vaultmasters.add(v); + } + + public ArrayList vaultmasters() { + return m_vaultmasters; + } + public void onEnable() { + m_vaultmasters = new ArrayList(); + m_vaultInventories = new HashMap(); PluginManager pm = this.getServer().getPluginManager(); m_listener = new JoinListener(this); Configuration conf = getConfig(); @@ -127,6 +170,9 @@ public class Plugin extends JavaPlugin { m_vomitCommand = new VomitCommand(this); getCommand("vomit").setExecutor(m_vomitCommand); + m_vaultCommand = new VaultCommand(this); + getCommand("vaultmaster").setExecutor(m_vaultCommand); + CommandExecutor economyCommand = new EconomyCommand(this); getCommand("balance").setExecutor(economyCommand); @@ -160,4 +206,50 @@ public class Plugin extends JavaPlugin { } } } + + private HashMap m_vaultInventories; + + public void saveVault(Player p, Inventory inv) throws IOException { + ListIterator items = inv.iterator(); + PlayerVaultSlot[] vault = new PlayerVaultSlot[inv.getSize()]; + int i = 0; + while(items.hasNext()) { + ItemStack item = items.next(); + PlayerVaultSlot slot = new PlayerVaultSlot(); + slot.position = i; + slot.quantity = -1; + if (item != null) { + slot.item = item.getTypeId(); + slot.quantity = item.getAmount(); + slot.damage = item.getDurability(); + slot.data = item.getData().getData(); + } + vault[i] = slot; + i++; + } + log.info("Saving "+vault.length+" items to vault for "+p.getName()); + try { + m_api.saveVault(p.getName(), vault); + } catch (JSONException e) { + throw new IOException(e); + } + } + + public void forgetVaultInventory(Player p) { + if (m_vaultInventories.containsKey(p.getName())) { + m_vaultInventories.remove(p.getName()); + } + } + + public Inventory vaultInventory(Player p) throws IOException { + if (!m_vaultInventories.containsKey(p.getName())) { + Inventory inv = p.getServer().createInventory(p, InventoryType.CHEST); + m_vaultInventories.put(p.getName(), inv); + PlayerVaultSlot[] vault = m_api.loadVault(p.getName()); + for(int i = 0;i. + */ + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Villager; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.Location; + +public class VaultCommand implements CommandExecutor { + private Plugin m_plugin; + + public VaultCommand(Plugin p) { + m_plugin = p; + } + + public boolean onCommand(CommandSender sender, Command command, String label, String[] split) { + if (sender.hasPermission("caminus.vaultmaster")) { + if (sender instanceof Player) { + Player p = (Player)sender; + Location loc = p.getLocation(); + Villager vaultmaster = (Villager)p.getWorld().spawnCreature(loc, EntityType.VILLAGER); + m_plugin.addVaultmaster(vaultmaster); + } + } + return true; + } +} diff --git a/src/main/java/us/camin/api/PlayerVaultSlot.java b/src/main/java/us/camin/api/PlayerVaultSlot.java new file mode 100644 index 0000000..5de44dc --- /dev/null +++ b/src/main/java/us/camin/api/PlayerVaultSlot.java @@ -0,0 +1,28 @@ +package us.camin.api; + +/* + This file is part of Caminus + + Caminus 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. + + Caminus 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 Caminus. If not, see . + */ + + +public class PlayerVaultSlot { + public int item; + public int quantity; + public int id; + public short damage; + public Byte data; + public int position; +} diff --git a/src/main/java/us/camin/api/Server.java b/src/main/java/us/camin/api/Server.java index 2599685..926db15 100644 --- a/src/main/java/us/camin/api/Server.java +++ b/src/main/java/us/camin/api/Server.java @@ -301,4 +301,48 @@ public class Server { } return resp; } + + public PlayerVaultSlot[] loadVault(String player) throws IOException { + log.info("Opening vault for "+player); + PlayerVaultSlot[] vault; + JSONObject jsonObj = get("server/vault/"+player); + try { + JSONArray items = jsonObj.getJSONArray("items"); + vault = new PlayerVaultSlot[items.length()]; + for(int i = 0;i params = new HashMap(); + params.put("contents", out.toString()); + put("server/vault/"+player, params); + } } diff --git a/src/main/java/us/camin/api/ServerEvent.java b/src/main/java/us/camin/api/ServerEvent.java index ef94d96..c5a5a21 100644 --- a/src/main/java/us/camin/api/ServerEvent.java +++ b/src/main/java/us/camin/api/ServerEvent.java @@ -47,6 +47,8 @@ public class ServerEvent { return BroadcastEvent.fromJSON(payload, id); } else if (type.equals("player-message")) { return PlayerMessageEvent.fromJSON(payload, id); + } else if (type.equals("vault-contents")) { + return VaultModifyEvent.fromJSON(payload, id); } else { log.log(Level.SEVERE, "Unhandled event type: "+type); return null; diff --git a/src/main/java/us/camin/api/VaultModifyEvent.java b/src/main/java/us/camin/api/VaultModifyEvent.java new file mode 100644 index 0000000..f64a0ef --- /dev/null +++ b/src/main/java/us/camin/api/VaultModifyEvent.java @@ -0,0 +1,54 @@ +package us.camin.api; + +/* + This file is part of Caminus + + Caminus 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. + + Caminus 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 Caminus. If not, see . + */ + +import org.json.JSONArray; +import org.json.JSONObject; +import org.json.JSONException; + +public class VaultModifyEvent extends ServerEvent { + public PlayerVaultSlot[] contents; + public String player; + public static VaultModifyEvent fromJSON(JSONObject obj, int id) { + VaultModifyEvent ret = new VaultModifyEvent(); + ret.player = obj.optString("player"); + JSONArray items; + try { + items = obj.getJSONArray("items"); + } catch (JSONException e) { + return null; + } + ret.contents = new PlayerVaultSlot[items.length()]; + for(int i = 0;i + vaultmaster: + description: Create a vaultmaster NPC at your current location. permissions: caminus.*: default: op @@ -23,6 +25,7 @@ permissions: caminus.whitelisted: true caminus.freedoorday: true caminus.vomit: true + caminus.vaultmaster: true caminus.freedoorday: default: false description: Enables free half door day @@ -32,4 +35,6 @@ permissions: caminus.whitelisted: default: op description: Allows user to bypass caminus API whitelisting - + caminus.vaultmaster: + default: op + description: Allows creation of vaultmasters, interfaces to the vault system.