diff --git a/MobArena.jar b/MobArena.jar index 532713b..b9a363f 100644 Binary files a/MobArena.jar and b/MobArena.jar differ diff --git a/resources/plugin.yml b/resources/plugin.yml index 5ace138..1e0ba2e 100644 --- a/resources/plugin.yml +++ b/resources/plugin.yml @@ -1,6 +1,6 @@ name: MobArena main: com.garbagemule.MobArena.MobArena -version: 0.93.4 +version: 0.93.5 softdepend: [Permissions,MultiVerse,XcraftGate,Towny] commands: ma: @@ -17,3 +17,99 @@ commands: /mobarena leave - Leave the arena. /mobarena notready - List of players who aren't ready. /mobarena spectate - Warp to the spectator area. +permissions: + mobarena.use.*: + description: Gives access to usage commands + default: true + children: + mobarena.use.join: true + mobarena.use.spec: true + mobarena.use.leave: true + mobarena.use.join: + default: true + mobarena.use.spec: + default: true + mobarena.use.leave: + default: true + + mobarena.admin.*: + description: Gives access to admin commands + default: op + children: + mobarena.admin.enable: true + mobarena.admin.kick: true + mobarena.admin.restore: true + mobarena.admin.force.end: true + mobarena.admin.force.start: true + mobarena.admin.config.reload: true + mobarena.admin.enable: + default: false + mobarena.admin.kick: + default: false + mobarena.admin.restore: + default: false + mobarena.admin.force.end: + default: false + mobarena.admin.force.start: + default: false + mobarena.admin.config.reload: + default: false + + mobarena.setup.*: + description: Gives access to setup commands + default: op + children: + mobarena.setup.arena: true + mobarena.setup.setarena: true + mobarena.setup.addarena: true + mobarena.setup.delarena: true + mobarena.setup.protect: true + mobarena.setup.editarena: true + mobarena.setup.setregion: true + mobarena.setup.expandregion: true + mobarena.setup.showregion: true + mobarena.setup.setlobbyregion: true + mobarena.setup.expandlobbyregion: true + mobarena.setup.setwarp: true + mobarena.setup.spawnpoints: true + mobarena.setup.addspawn: true + mobarena.setup.delspawn: true + mobarena.setup.checkdata: true + mobarena.setup.autogenerate: true + mobarena.setup.autodegenerate: true + mobarena.setup.arena: + default: false + mobarena.setup.setarena: + default: false + mobarena.setup.addarena: + default: false + mobarena.setup.delarena: + default: false + mobarena.setup.protect: + default: false + mobarena.setup.editarena: + default: false + mobarena.setup.setregion: + default: false + mobarena.setup.expandregion: + default: false + mobarena.setup.showregion: + default: false + mobarena.setup.setlobbyregion: + default: false + mobarena.setup.expandlobbyregion: + default: false + mobarena.setup.setwarp: + default: false + mobarena.setup.spawnpoints: + default: false + mobarena.setup.addspawn: + default: false + mobarena.setup.delspawn: + default: false + mobarena.setup.checkdata: + default: false + mobarena.setup.autogenerate: + default: false + mobarena.setup.autodegenerate: + default: false \ No newline at end of file diff --git a/src/com/garbagemule/ArenaPlugin/Arena.java b/src/com/garbagemule/ArenaPlugin/Arena.java deleted file mode 100644 index 883ee9f..0000000 --- a/src/com/garbagemule/ArenaPlugin/Arena.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.garbagemule.ArenaPlugin; - -import org.bukkit.entity.Player; - -public interface Arena -{ - /** - * Start the arena session. - * This method should warp all players to their respective warp points, start all - * needed timers, clear/populate all sets and lists, and flag all booleans. - */ - public void startArena(); - - /** - * Stop the arena session. - * Distribute rewards, clean up arena floor and reset everything to how it was before - * the arena session was started. - */ - public void endArena(); - - /** - * Force the arena to start. - * If some players are ready, this method will force all non-ready players to leave, - * and the arena will start with only the currently ready players. - * @return true, if the arena was successfully started, false otherwise - */ - public boolean forceStart(); - - /** - * Force the arena to end. - * Returns all players to their entry locations, distributes rewards, cleans the arena - * floor, as well as all lists, sets and maps. Calling this method will return the - * arena to the state it would be in right after MobArena has loaded. - * @return true, if the session was successfully ended. - */ - public boolean forceEnd(); - - /** - * Player joins the arena/lobby. - * The player should either enter with an empty inventory, or have their inventory - * stored upon entering, such that the classes in the lobby/arena will be the only - * means of equipment. The player's previous location and health is also stored. - * @param p A player - * @precondition Calling canJoin(p) for the given player must return true. - */ - public void playerJoin(Player p); - - /** - * Player leaves the arena or lobby. - * Upon leaving, the player will have their inventory restored (if it was stored - * on join), as well as their health. They will be completely discarded/cleared from - * the arena, such that they no longer reside in any collections. - * @param p A player - * @precondition Calling canLeave(p) for the given player must return true. - */ - public void playerLeave(Player p); - - /** - * Player joins the spectator area. - * The player takes a spectator role, meaning they cannot participate in the arena - * in any way. The player's location and health is stored upon spectating, and of - * course restored upon leaving. - * @param p A player - * @precondition Calling canSpec(p) for the given player must return true. - */ - public void playerSpec(Player p); - - /** - * Player dies in the arena. - */ - public void playerDeath(Player p); - - /** - * Player signals that they are ready. - */ - public void playerReady(Player p); - - /** - * Check if a player can join the arena. - * @param p A player - * @return true, if the player is eligible to join the arena. - */ - public boolean canJoin(Player p); - - /** - * Check if a player can leave the arena. - * @param p A player - * @return true, if the player is eligible to leave the arena. - */ - public boolean canLeave(Player p); - - /** - * Check if a player can spectate the arena. - * @param p A player - * @return true, if the player is eligible for spectating. - */ - public boolean canSpec(Player p); - - /** - * Check if the arena is enabled. - * @return true, if the arena is enabled. - */ - public boolean isEnabled(); - - /** - * Check if the arena is set up and ready for use. - * @return true, if the arena is ready for use. - */ - public boolean isSetup(); - - /** - * Check if the arena is running. - * @return true, if the arena is running. - */ - public boolean isRunning(); -} diff --git a/src/com/garbagemule/ArenaPlugin/ArenaPlugin.java b/src/com/garbagemule/ArenaPlugin/ArenaPlugin.java deleted file mode 100644 index b751cb4..0000000 --- a/src/com/garbagemule/ArenaPlugin/ArenaPlugin.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.garbagemule.ArenaPlugin; - -public interface ArenaPlugin -{ - public Master getMaster(); -} diff --git a/src/com/garbagemule/ArenaPlugin/Master.java b/src/com/garbagemule/ArenaPlugin/Master.java deleted file mode 100644 index 6a66c99..0000000 --- a/src/com/garbagemule/ArenaPlugin/Master.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.garbagemule.ArenaPlugin; - -import java.util.List; - -import org.bukkit.entity.Player; - -public interface Master -{ - //public List getArenas(); - - //public List getEnabledArenas(); - - //public List getPermittedArenas(Player p); - - -} diff --git a/src/com/garbagemule/MobArena/AbstractArena.java b/src/com/garbagemule/MobArena/AbstractArena.java deleted file mode 100644 index f9d7670..0000000 --- a/src/com/garbagemule/MobArena/AbstractArena.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.garbagemule.MobArena; - -import java.util.Map; -import java.util.Set; - -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.Player; - -import com.garbagemule.ArenaPlugin.ArenaPlugin; - -public abstract class AbstractArena implements ArenaInterface -{ - private String name; - private World world; - private ArenaPlugin plugin; - - private boolean enabled, setup, running; - private Set arenaPlayers, lobbyPlayers, readyPlayers, specPlayers; - private Map playerClassMap; - private Map locations; - private Map healths; - - public AbstractArena(String name, World world, ArenaPlugin plugin) - { - if (world == null) - throw new NullPointerException("[" + plugin.getClass().getSimpleName() + "] ERROR! World for arena '" + name + "' does not exist!"); - - this.name = name; - this.world = world; - this.plugin = plugin; - } - - public abstract void startArena(); - - public abstract void endArena(); - - public abstract boolean forceStart(); - - public abstract boolean forceEnd(); -/* - public void playerJoin(Player p) - { - storePlayerData(p, p.getLocation()); - MAUtils.sitPets(p); - p.setHealth(20); - movePlayerToLobby(p); - } -*/ - /* - public void playerLeave(Player p) - { - if (arenaPlayers.contains(p) || lobbyPlayers.contains(p)) - finishArenaPlayer(p); - - movePlayerToEntry(p); - discardPlayer(p); - - // End arena if possible. - endArena(); - }*/ - - - public abstract void playerSpec(Player p); - - public abstract void playerDeath(Player p); - - public abstract void playerReady(Player p); - - public abstract boolean canJoin(Player p); - - public abstract boolean canLeave(Player p); - - public abstract boolean canSpec(Player p); - - public boolean isEnabled() - { - return enabled; - } - - public boolean isSetup() - { - return setup; - } - - public boolean isRunning() - { - return running; - } - - public void storePlayerData(Player p, Location loc) - { - // TODO: Get this sorted out - //plugin.getAM().arenaMap.put(p, this); - - if (!locations.containsKey(p)) - locations.put(p, loc); - - if (!healths.containsKey(p)) - healths.put(p, p.getHealth()); - } - - public abstract void movePlayerToLobby(Player p); - - public abstract void movePlayerToSpec(Player p); - - public void movePlayerToEntry(Player p) - { - Location entry = locations.get(p); - if (entry == null) return; - - p.teleport(entry); - } - - public abstract void restoreInvAndGiveRewards(final Player p); -} diff --git a/src/com/garbagemule/MobArena/Arena.java b/src/com/garbagemule/MobArena/Arena.java index ad168c9..cd4d630 100644 --- a/src/com/garbagemule/MobArena/Arena.java +++ b/src/com/garbagemule/MobArena/Arena.java @@ -6,7 +6,6 @@ import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -478,7 +477,7 @@ public class Arena } public void restoreInvAndGiveRewards(final Player p) - { + { final List rewards = log != null && log.players.get(p) != null ? log.players.get(p).rewards : new LinkedList(); final boolean hadRewards = rewardedPlayers.contains(p); @@ -486,10 +485,7 @@ public class Arena new Runnable() { public void run() - { - if (!p.isOnline()) - return; - + { if (!emptyInvJoin) MAUtils.restoreInventory(p); @@ -503,6 +499,21 @@ public class Arena }); } + public void restoreInvAndGiveRewardz(final Player p, List rewards, boolean hadRewards) + { + if (!p.isOnline()) + return; + + if (!emptyInvJoin) + MAUtils.restoreInventory(p); + + if (hadRewards) + return; + + MAUtils.giveRewards(p, rewards, plugin); + if (running) + rewardedPlayers.add(p);} + public void storePlayerData(Player p, Location loc) { plugin.getAM().arenaMap.put(p, this); @@ -1035,10 +1046,8 @@ public class Arena List result = new ArrayList(spawnpoints.size()); for (Map.Entry entry : spawnpoints.entrySet()) - { - if (entry.getKey().matches("^*boss*$")) continue; - result.add(entry.getValue()); - } + if (!entry.getKey().matches("^*boss*$")) + result.add(entry.getValue()); return !result.isEmpty() ? result : new ArrayList(spawnpoints.values()); } @@ -1107,6 +1116,11 @@ public class Arena return tmp; } + public Set getPets() + { + return pets; + } + public void resetIdleTimer() { if (maxIdleTime <= 0 || !running) diff --git a/src/com/garbagemule/MobArena/ArenaInterface.java b/src/com/garbagemule/MobArena/ArenaInterface.java deleted file mode 100644 index d10255b..0000000 --- a/src/com/garbagemule/MobArena/ArenaInterface.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.garbagemule.MobArena; - -import org.bukkit.entity.Player; - -public interface ArenaInterface -{ - /** - * Start the arena session. - * This method should warp all players to their respective warp points, start all - * needed timers, clear/populate all sets and lists, and flag all booleans. - */ - public void startArena(); - - /** - * Stop the arena session. - * Distribute rewards, clean up arena floor and reset everything to how it was before - * the arena session was started. - */ - public void endArena(); - - /** - * Force the arena to start. - * If some players are ready, this method will force all non-ready players to leave, - * and the arena will start with only the currently ready players. - * @return true, if the arena was successfully started, false otherwise - */ - public boolean forceStart(); - - /** - * Force the arena to end. - * Returns all players to their entry locations, distributes rewards, cleans the arena - * floor, as well as all lists, sets and maps. Calling this method will return the - * arena to the state it would be in right after MobArena has loaded. - * @return true, if the session was successfully ended. - */ - public boolean forceEnd(); - - /** - * Player joins the arena/lobby. - * The player should either enter with an empty inventory, or have their inventory - * stored upon entering, such that the classes in the lobby/arena will be the only - * means of equipment. The player's previous location and health is also stored. - * @param p A player - * @precondition Calling canJoin(p) for the given player must return true. - */ - public void playerJoin(Player p); - - /** - * Player leaves the arena or lobby. - * Upon leaving, the player will have their inventory restored (if it was stored - * on join), as well as their health. They will be completely discarded/cleared from - * the arena, such that they no longer reside in any collections. - * @param p A player - * @precondition Calling canLeave(p) for the given player must return true. - */ - public void playerLeave(Player p); - - /** - * Player joins the spectator area. - * The player takes a spectator role, meaning they cannot participate in the arena - * in any way. The player's location and health is stored upon spectating, and of - * course restored upon leaving. - * @param p A player - * @precondition Calling canSpec(p) for the given player must return true. - */ - public void playerSpec(Player p); - - /** - * Player dies in the arena. - */ - public void playerDeath(Player p); - - /** - * Player signals that they are ready. - */ - public void playerReady(Player p); - - /** - * Check if a player can join the arena. - * @param p A player - * @return true, if the player is eligible to join the arena. - */ - public boolean canJoin(Player p); - - /** - * Check if a player can leave the arena. - * @param p A player - * @return true, if the player is eligible to leave the arena. - */ - public boolean canLeave(Player p); - - /** - * Check if a player can spectate the arena. - * @param p A player - * @return true, if the player is eligible for spectating. - */ - public boolean canSpec(Player p); - - /** - * Check if the arena is enabled. - * @return true, if the arena is enabled. - */ - public boolean isEnabled(); - - /** - * Check if the arena is set up and ready for use. - * @return true, if the arena is ready for use. - */ - public boolean isSetup(); - - /** - * Check if the arena is running. - * @return true, if the arena is running. - */ - public boolean isRunning(); -} diff --git a/src/com/garbagemule/MobArena/ArenaMaster.java b/src/com/garbagemule/MobArena/ArenaMaster.java index fd16e62..6050c98 100644 --- a/src/com/garbagemule/MobArena/ArenaMaster.java +++ b/src/com/garbagemule/MobArena/ArenaMaster.java @@ -392,4 +392,9 @@ public class ArenaMaster implements Master public void updateClasses() { update(false, true, false); } public void updateArenas() { update(false, false, true); } public void updateAll() { update(true, true, true); } + + public Map getArenaMap() + { + return null;//arenaMap; + } } diff --git a/src/com/garbagemule/MobArena/Arenaz.java b/src/com/garbagemule/MobArena/Arenaz.java deleted file mode 100644 index ac63e9f..0000000 --- a/src/com/garbagemule/MobArena/Arenaz.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.garbagemule.MobArena; - -import org.bukkit.entity.Player; - -public interface Arenaz -{ - /** - * Start the arena session. - * This method should warp all players to their respective warp points, start all - * needed timers, clear/populate all sets and lists, and flag all booleans. - */ - public void startArena(); - - /** - * Stop the arena session. - * Distribute rewards, clean up arena floor and reset everything to how it was before - * the arena session was started, false otherwise - */ - public void endArena(); - - /** - * Force the arena to start. - * If some players are ready, this method will force all non-ready players to leave, - * and the arena will start with only the currently ready players. - * @return true, if the arena was successfully started, false otherwise - */ - public boolean forceStart(); - - /** - * Force the arena to end. - * Returns all players to their entry locations, distributes rewards, cleans the arena - * floor, as well as all lists, sets and maps. Calling this method will return the - * arena to the state it would be in right after MobArena has loaded. - * @return true, if the session was successfully ended. - */ - public boolean forceEnd(); - - /** - * Player joins the arena/lobby. - * @param p A player - * @precondition Calling canJoin(p) for the given player must return true. - */ - public void playerJoin(Player p); - - /** - * Player leaves the arena or lobby. - * @param p A player - * @precondition Calling canLeave(p) for the given player must return true. - */ - public void playerLeave(Player p); - - /** - * Player joins the spectator area. - * @param p A player - * @precondition Calling canSpec(p) for the given player must return true. - */ - public void playerSpec(Player p); - - /** - * Player dies in the arena. - */ - public void playerDeath(Player p); - - /** - * Player signals that they are ready. - */ - public void playerReady(Player p); - - /** - * Check if a player can join the arena. - * @param p A player - * @return true, if the player is eligible to join the arena. - */ - public boolean canJoin(Player p); - - /** - * Check if a player can leave the arena. - * @param p A player - * @return true, if the player is eligible to leave the arena. - */ - public boolean canLeave(Player p); - - /** - * Check if a player can spectate the arena. - * @param p A player - * @return true, if the player is eligible for spectating. - */ - public boolean canSpec(Player p); - - /** - * Check if the arena is enabled. - * @return true, if the arena is enabled. - */ - public boolean isEnabled(); - - /** - * Check if the arena is set up and ready for use. - * @return true, if the arena is ready for use. - */ - public boolean isSetup(); - - /** - * Check if the arena is running. - * @return true, if the arena is running. - */ - public boolean isRunning(); -} diff --git a/src/com/garbagemule/MobArena/Lobby.java b/src/com/garbagemule/MobArena/Lobby.java deleted file mode 100644 index 8ff1601..0000000 --- a/src/com/garbagemule/MobArena/Lobby.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.garbagemule.MobArena; - -import org.bukkit.Location; -import org.bukkit.entity.Player; - -public class Lobby -{ - protected Arena arena; - protected ArenaMaster am; - protected Location warp, l1, l2; - - public Lobby(Arena arena) - { - this.arena = arena; - } - public Lobby() - { - this(null); - } - - public void playerJoin(Player p) - { - p.teleport(warp); - } -} diff --git a/src/com/garbagemule/MobArena/MAArena.java b/src/com/garbagemule/MobArena/MAArena.java deleted file mode 100644 index a61b028..0000000 --- a/src/com/garbagemule/MobArena/MAArena.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.garbagemule.MobArena; - -public class MAArena -{ - -} diff --git a/src/com/garbagemule/MobArena/MAUtils.java b/src/com/garbagemule/MobArena/MAUtils.java index 13ddc69..b3d9f25 100644 --- a/src/com/garbagemule/MobArena/MAUtils.java +++ b/src/com/garbagemule/MobArena/MAUtils.java @@ -7,6 +7,7 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -39,6 +40,13 @@ import org.bukkit.util.config.Configuration; import com.garbagemule.MobArena.MAMessages.Msg; import com.garbagemule.MobArena.util.EntityPosition; import com.garbagemule.MobArena.util.InventoryItem; +import com.garbagemule.MobArena.util.jnbt.ByteTag; +import com.garbagemule.MobArena.util.jnbt.CompoundTag; +import com.garbagemule.MobArena.util.jnbt.ListTag; +import com.garbagemule.MobArena.util.jnbt.NBTInputStream; +import com.garbagemule.MobArena.util.jnbt.NBTOutputStream; +import com.garbagemule.MobArena.util.jnbt.ShortTag; +import com.garbagemule.MobArena.util.jnbt.Tag; public class MAUtils { @@ -337,8 +345,7 @@ public class MAUtils INVENTORY AND REWARD METHODS // ///////////////////////////////////////////////////////////////////// */ - - /* Clears the players inventory and armor slots. */ + public static PlayerInventory clearInventory(Player p) { PlayerInventory inv = p.getInventory(); @@ -362,18 +369,18 @@ public class MAUtils return false; // Grab the inventory contents. - ItemStack[] armor = p.getInventory().getArmorContents(); ItemStack[] items = p.getInventory().getContents(); + ItemStack[] armor = p.getInventory().getArmorContents(); try { backupFile.createNewFile(); - InventoryItem[] inv = new InventoryItem[armor.length + items.length]; - for (int i = 0; i < armor.length; i++) - inv[i] = InventoryItem.parseItemStack(armor[i]); + InventoryItem[] inv = new InventoryItem[items.length + armor.length]; for (int i = 0; i < items.length; i++) - inv[armor.length + i] = InventoryItem.parseItemStack(items[i]); + inv[i] = InventoryItem.parseItemStack(items[i]); + for (int i = 0; i < armor.length; i++) + inv[i + items.length] = InventoryItem.parseItemStack(armor[i]); FileOutputStream fos = new FileOutputStream(backupFile); ObjectOutputStream oos = new ObjectOutputStream(fos); @@ -392,6 +399,33 @@ public class MAUtils } public static boolean restoreInventory(Player p) + { + // Grab the items from the MobArena .inv file + ItemStack[] stacks = getInventoryFile(p); + + // If the player isn't online, hack the playerName.dat file + if (!p.isOnline()) + return writeInventoryData(p, stacks); + + // Otherwise, restore the inventory directly + ItemStack[] items = new ItemStack[stacks.length-4]; + ItemStack[] armor = new ItemStack[4]; + + for (int i = 0; i < stacks.length - 4; i++) + items[i] = stacks[i]; + for (int i = 0; i < 4; i++) + armor[i] = stacks[stacks.length - 4 + i]; + + // Restore the inventory. + PlayerInventory inv = p.getInventory(); + inv.setArmorContents(armor); + for (int i = 0; i < items.length; i++) + inv.setItem(i, items[i]); + + return true; + } + + public static ItemStack[] getInventoryFile(Player p) { String invPath = "plugins" + sep + "MobArena" + sep + "inventories"; File backupFile = new File(invPath + sep + p.getName() + ".inv"); @@ -400,35 +434,104 @@ public class MAUtils { // If the backup-file couldn't be found, return. if (!backupFile.exists()) - return false; + return null; // Grab the MAInventoryItem array from the backup-file. FileInputStream fis = new FileInputStream(backupFile); ObjectInputStream ois = new ObjectInputStream(fis); InventoryItem[] fromFile = (InventoryItem[]) ois.readObject(); ois.close(); - - // Split that shit. - ItemStack[] armor = new ItemStack[4]; - ItemStack[] items = new ItemStack[fromFile.length-4]; - - for (int i = 0; i < 4; i++) - armor[i] = InventoryItem.toItemStack(fromFile[i]); - for (int i = 4; i < fromFile.length; i++) - items[i - 4] = InventoryItem.toItemStack(fromFile[i]); - - // Restore the inventory. - PlayerInventory inv = p.getInventory(); - inv.setArmorContents(armor); - for (int i = 0; i < items.length; i++) - inv.setItem(i, items[i]); - /* - for (ItemStack stack : items) - if (stack != null) - inv.addItem(stack); - */ - // Remove the backup-file. + + // Delete the file backupFile.delete(); + + return InventoryItem.toItemStacks(fromFile); + } + catch (Exception e) + { + e.printStackTrace(); + MobArena.warning("Could not restore inventory for " + p.getName()); + return null; + } + } + + public static ItemStack[] readInventoryData(Player p) + { + // Grab the data dir /players/ + File playerDir = new File(Bukkit.getServer().getWorlds().get(0).getName(), "players"); + + try + { + NBTInputStream in = new NBTInputStream(new FileInputStream(new File(playerDir, p.getName() + ".dat"))); + CompoundTag tag = (CompoundTag) in.readTag(); + in.close(); + + ListTag inventory = (ListTag) tag.getValue().get("Inventory"); + + ItemStack[] stacks = new ItemStack[40]; + for (int i = 0; i < inventory.getValue().size(); i++) + { + CompoundTag item = (CompoundTag) inventory.getValue().get(i); + byte count = ((ByteTag) item.getValue().get("Count")).getValue(); + byte slot = ((ByteTag) item.getValue().get("Slot")).getValue(); + short damage = ((ShortTag) item.getValue().get("Damage")).getValue(); + short id = ((ShortTag) item.getValue().get("id")).getValue(); + stacks[slot < 36 ? slot : 36 + 103-slot] = new ItemStack(id, count, damage); + } + return stacks; + } + catch (Exception e) + { + e.printStackTrace(); + MobArena.warning("Could not restore inventory for " + p.getName()); + return null; + } + } + + public static boolean writeInventoryData(Player p, ItemStack[] stacks) + { + // Abort if stacks is null + if (stacks == null) return false; + + // Grab the data dir /players/ + File playerDir = new File(Bukkit.getServer().getWorlds().get(0).getName(), "players"); + + try + { + NBTInputStream in = new NBTInputStream(new FileInputStream(new File(playerDir, p.getName() + ".dat"))); + CompoundTag tag = (CompoundTag) in.readTag(); + in.close(); + + ArrayList tagList = new ArrayList(); + + for (int i = 0; i < stacks.length; i++) + { + if (stacks[i] == null) continue; + + ByteTag count = new ByteTag("Count", (byte) stacks[i].getAmount()); + ByteTag slot = new ByteTag("Slot", (byte) (i < 36 ? i : 104-(stacks.length-i))); + ShortTag damage = new ShortTag("Damage", stacks[i].getDurability()); + ShortTag id = new ShortTag("id", (short) stacks[i].getTypeId()); + + HashMap tagMap = new HashMap(); + tagMap.put("Count", count); + tagMap.put("Slot", slot); + tagMap.put("Damage", damage); + tagMap.put("id", id); + + tagList.add(new CompoundTag("", tagMap)); + } + + ListTag inventory = new ListTag("Inventory", CompoundTag.class, tagList); + + HashMap tagCompound = new HashMap(tag.getValue()); + tagCompound.put("Inventory", inventory); + tag = new CompoundTag("Player", tagCompound); + + NBTOutputStream out = new NBTOutputStream(new FileOutputStream(new File(playerDir, p.getName() + ".dat"))); + out.writeTag(tag); + out.close(); + return true; } catch (Exception e) { @@ -436,8 +539,6 @@ public class MAUtils MobArena.warning("Could not restore inventory for " + p.getName()); return false; } - - return true; } /* Checks if all inventory and armor slots are empty. */ @@ -465,6 +566,25 @@ public class MAUtils if (stacks == null) return; + if (!p.isOnline()) + { + ItemStack[] items = readInventoryData(p); + int currentSlot = 0; + for (ItemStack stack : stacks) + { + while (currentSlot < items.length && items[currentSlot] != null) + currentSlot++; + + if (currentSlot >= items.length) + break; + + items[currentSlot] = stack; + } + + writeInventoryData(p, items); + return; + } + PlayerInventory inv = p.getInventory(); for (ItemStack stack : stacks) { diff --git a/src/com/garbagemule/MobArena/MobArena.java b/src/com/garbagemule/MobArena/MobArena.java index 62a239b..5b12dea 100644 --- a/src/com/garbagemule/MobArena/MobArena.java +++ b/src/com/garbagemule/MobArena/MobArena.java @@ -49,7 +49,7 @@ public class MobArena extends JavaPlugin implements ArenaPlugin public static Random random = new Random(); public void onEnable() - { + { // Description file and data folders desc = getDescription(); dir = getDataFolder(); diff --git a/src/com/garbagemule/MobArena/util/InventoryItem.java b/src/com/garbagemule/MobArena/util/InventoryItem.java index 160bf84..38f2757 100644 --- a/src/com/garbagemule/MobArena/util/InventoryItem.java +++ b/src/com/garbagemule/MobArena/util/InventoryItem.java @@ -64,6 +64,16 @@ public class InventoryItem implements Serializable return item.toItemStack(); } + public static ItemStack[] toItemStacks(InventoryItem[] items) + { + ItemStack[] result = new ItemStack[items.length]; + + for (int i = 0; i < items.length; i++) + result[i] = items[i].toItemStack(); + + return result; + } + /** * Static method for converting an ItemStack to an InventoryItems. * @param stack The ItemStack to convert diff --git a/src/com/garbagemule/MobArena/util/MAInventoryItem.java b/src/com/garbagemule/MobArena/util/MAInventoryItem.java deleted file mode 100644 index db100ea..0000000 --- a/src/com/garbagemule/MobArena/util/MAInventoryItem.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.garbagemule.MobArena.util; - -import java.io.Serializable; - -public class MAInventoryItem implements Serializable -{ - private static final long serialVersionUID = 739709220350581510L; - private int typeId; - private int amount; - private short durability; - - public MAInventoryItem(int typeId, int amount, short durability) - { - this.typeId = typeId; - this.amount = amount; - this.durability = durability; - } - - public int getTypeId() { return typeId; } - public int getAmount() { return amount; } - public short getDurability() { return durability; } -} diff --git a/src/com/garbagemule/MobArena/util/WaveUtils.java b/src/com/garbagemule/MobArena/util/WaveUtils.java index f9c53a3..9a79049 100644 --- a/src/com/garbagemule/MobArena/util/WaveUtils.java +++ b/src/com/garbagemule/MobArena/util/WaveUtils.java @@ -24,7 +24,7 @@ public class WaveUtils */ public static List getValidSpawnpoints(Arena arena, Collection players) { - long start = System.nanoTime(); + //long start = System.nanoTime(); List result = new ArrayList(); double x1 = Double.NaN, y1 = Double.NaN, z1 = Double.NaN, // Bottom @@ -232,6 +232,13 @@ public class WaveUtils MobArena.warning("Missing 'frequency'-node in " + path); wellDefined = false; } + // OPTIONAL: Wave + int wave = config.getInt(path + "wave", 0); + if (wave < 0) + { + MobArena.warning("'wave' must be greater than 0 in " + path); + wellDefined = false; + } } else if (branch == WaveBranch.SINGLE) { @@ -242,6 +249,11 @@ public class WaveUtils MobArena.warning("Missing 'wave'-node in " + path); wellDefined = false; } + else if (wave < 0) + { + MobArena.warning("'wave' must be greater than 0 in " + path); + wellDefined = false; + } } else wellDefined = false; diff --git a/src/com/garbagemule/MobArena/util/jnbt/ByteArrayTag.java b/src/com/garbagemule/MobArena/util/jnbt/ByteArrayTag.java new file mode 100644 index 0000000..219d1a4 --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/ByteArrayTag.java @@ -0,0 +1,81 @@ +package com.garbagemule.MobArena.util.jnbt; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * The TAG_Byte_Array tag. + * @author Graham Edgecombe + * + */ +public final class ByteArrayTag extends Tag { + + /** + * The value. + */ + private final byte[] value; + + /** + * Creates the tag. + * @param name The name. + * @param value The value. + */ + public ByteArrayTag(String name, byte[] value) { + super(name); + this.value = value; + } + + @Override + public byte[] getValue() { + return value; + } + + @Override + public String toString() { + StringBuilder hex = new StringBuilder(); + for(byte b : value) { + String hexDigits = Integer.toHexString(b).toUpperCase(); + if(hexDigits.length() == 1) { + hex.append("0"); + } + hex.append(hexDigits).append(" "); + } + String name = getName(); + String append = ""; + if(name != null && !name.equals("")) { + append = "(\"" + this.getName() + "\")"; + } + return "TAG_Byte_Array" + append + ": " + hex.toString(); + } + +} diff --git a/src/com/garbagemule/MobArena/util/jnbt/ByteTag.java b/src/com/garbagemule/MobArena/util/jnbt/ByteTag.java new file mode 100644 index 0000000..b03463d --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/ByteTag.java @@ -0,0 +1,73 @@ +package com.garbagemule.MobArena.util.jnbt; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * The TAG_Byte tag. + * @author Graham Edgecombe + * + */ +public final class ByteTag extends Tag { + + /** + * The value. + */ + private final byte value; + + /** + * Creates the tag. + * @param name The name. + * @param value The value. + */ + public ByteTag(String name, byte value) { + super(name); + this.value = value; + } + + @Override + public Byte getValue() { + return value; + } + + @Override + public String toString() { + String name = getName(); + String append = ""; + if(name != null && !name.equals("")) { + append = "(\"" + this.getName() + "\")"; + } + return "TAG_Byte" + append + ": " + value; + } + +} diff --git a/src/com/garbagemule/MobArena/util/jnbt/CompoundTag.java b/src/com/garbagemule/MobArena/util/jnbt/CompoundTag.java new file mode 100644 index 0000000..3b59a9c --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/CompoundTag.java @@ -0,0 +1,82 @@ +package com.garbagemule.MobArena.util.jnbt; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.Collections; +import java.util.Map; + +/** + * The TAG_Compound tag. + * @author Graham Edgecombe + * + */ +public final class CompoundTag extends Tag { + + /** + * The value. + */ + private final Map value; + + /** + * Creates the tag. + * @param name The name. + * @param value The value. + */ + public CompoundTag(String name, Map value) { + super(name); + this.value = Collections.unmodifiableMap(value); + } + + @Override + public Map getValue() { + return value; + } + + @Override + public String toString() { + String name = getName(); + String append = ""; + if(name != null && !name.equals("")) { + append = "(\"" + this.getName() + "\")"; + } + StringBuilder bldr = new StringBuilder(); + bldr.append("TAG_Compound" + append + ": " + value.size() + " entries\r\n{\r\n"); + for(Map.Entry entry : value.entrySet()) { + bldr.append(" " + entry.getValue().toString().replaceAll("\r\n", "\r\n ") + "\r\n"); + } + bldr.append("}"); + return bldr.toString(); + } + +} diff --git a/src/com/garbagemule/MobArena/util/jnbt/DoubleTag.java b/src/com/garbagemule/MobArena/util/jnbt/DoubleTag.java new file mode 100644 index 0000000..f46dfc3 --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/DoubleTag.java @@ -0,0 +1,73 @@ +package com.garbagemule.MobArena.util.jnbt; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * The TAG_Double tag. + * @author Graham Edgecombe + * + */ +public final class DoubleTag extends Tag { + + /** + * The value. + */ + private final double value; + + /** + * Creates the tag. + * @param name The name. + * @param value The value. + */ + public DoubleTag(String name, double value) { + super(name); + this.value = value; + } + + @Override + public Double getValue() { + return value; + } + + @Override + public String toString() { + String name = getName(); + String append = ""; + if(name != null && !name.equals("")) { + append = "(\"" + this.getName() + "\")"; + } + return "TAG_Double" + append + ": " + value; + } + +} diff --git a/src/com/garbagemule/MobArena/util/jnbt/EndTag.java b/src/com/garbagemule/MobArena/util/jnbt/EndTag.java new file mode 100644 index 0000000..e9ff5fe --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/EndTag.java @@ -0,0 +1,60 @@ +package com.garbagemule.MobArena.util.jnbt; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * The TAG_End tag. + * @author Graham Edgecombe + * + */ +public final class EndTag extends Tag { + + /** + * Creates the tag. + */ + public EndTag() { + super(""); + } + + @Override + public Object getValue() { + return null; + } + + @Override + public String toString() { + return "TAG_End"; + } + +} diff --git a/src/com/garbagemule/MobArena/util/jnbt/FloatTag.java b/src/com/garbagemule/MobArena/util/jnbt/FloatTag.java new file mode 100644 index 0000000..7ff0ad5 --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/FloatTag.java @@ -0,0 +1,73 @@ +package com.garbagemule.MobArena.util.jnbt; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * The TAG_Float tag. + * @author Graham Edgecombe + * + */ +public final class FloatTag extends Tag { + + /** + * The value. + */ + private final float value; + + /** + * Creates the tag. + * @param name The name. + * @param value The value. + */ + public FloatTag(String name, float value) { + super(name); + this.value = value; + } + + @Override + public Float getValue() { + return value; + } + + @Override + public String toString() { + String name = getName(); + String append = ""; + if(name != null && !name.equals("")) { + append = "(\"" + this.getName() + "\")"; + } + return "TAG_Float" + append + ": " + value; + } + +} diff --git a/src/com/garbagemule/MobArena/util/jnbt/IntTag.java b/src/com/garbagemule/MobArena/util/jnbt/IntTag.java new file mode 100644 index 0000000..f728a43 --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/IntTag.java @@ -0,0 +1,73 @@ +package com.garbagemule.MobArena.util.jnbt; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * The TAG_Int tag. + * @author Graham Edgecombe + * + */ +public final class IntTag extends Tag { + + /** + * The value. + */ + private final int value; + + /** + * Creates the tag. + * @param name The name. + * @param value The value. + */ + public IntTag(String name, int value) { + super(name); + this.value = value; + } + + @Override + public Integer getValue() { + return value; + } + + @Override + public String toString() { + String name = getName(); + String append = ""; + if(name != null && !name.equals("")) { + append = "(\"" + this.getName() + "\")"; + } + return "TAG_Int" + append + ": " + value; + } + +} diff --git a/src/com/garbagemule/MobArena/util/jnbt/ListTag.java b/src/com/garbagemule/MobArena/util/jnbt/ListTag.java new file mode 100644 index 0000000..e5b6a18 --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/ListTag.java @@ -0,0 +1,97 @@ +package com.garbagemule.MobArena.util.jnbt; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.Collections; +import java.util.List; + +/** + * The TAG_List tag. + * @author Graham Edgecombe + * + */ +public final class ListTag extends Tag { + + /** + * The type. + */ + private final Class type; + + /** + * The value. + */ + private final List value; + + /** + * Creates the tag. + * @param name The name. + * @param type The type of item in the list. + * @param value The value. + */ + public ListTag(String name, Class type, List value) { + super(name); + this.type = type; + this.value = Collections.unmodifiableList(value); + } + + /** + * Gets the type of item in this list. + * @return The type of item in this list. + */ + public Class getType() { + return type; + } + + @Override + public List getValue() { + return value; + } + + @Override + public String toString() { + String name = getName(); + String append = ""; + if(name != null && !name.equals("")) { + append = "(\"" + this.getName() + "\")"; + } + StringBuilder bldr = new StringBuilder(); + bldr.append("TAG_List" + append + ": " + value.size() + " entries of type " + NBTUtils.getTypeName(type) + "\r\n{\r\n"); + for(Tag t : value) { + bldr.append(" " + t.toString().replaceAll("\r\n", "\r\n ") + "\r\n"); + } + bldr.append("}"); + return bldr.toString(); + } + +} diff --git a/src/com/garbagemule/MobArena/util/jnbt/LongTag.java b/src/com/garbagemule/MobArena/util/jnbt/LongTag.java new file mode 100644 index 0000000..14aa856 --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/LongTag.java @@ -0,0 +1,73 @@ +package com.garbagemule.MobArena.util.jnbt; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * The TAG_Long tag. + * @author Graham Edgecombe + * + */ +public final class LongTag extends Tag { + + /** + * The value. + */ + private final long value; + + /** + * Creates the tag. + * @param name The name. + * @param value The value. + */ + public LongTag(String name, long value) { + super(name); + this.value = value; + } + + @Override + public Long getValue() { + return value; + } + + @Override + public String toString() { + String name = getName(); + String append = ""; + if(name != null && !name.equals("")) { + append = "(\"" + this.getName() + "\")"; + } + return "TAG_Long" + append + ": " + value; + } + +} diff --git a/src/com/garbagemule/MobArena/util/jnbt/NBTConstants.java b/src/com/garbagemule/MobArena/util/jnbt/NBTConstants.java new file mode 100644 index 0000000..b03c11c --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/NBTConstants.java @@ -0,0 +1,72 @@ +package com.garbagemule.MobArena.util.jnbt; + +import java.nio.charset.Charset; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * A class which holds constant values. + * @author Graham Edgecombe + * + */ +public final class NBTConstants { + + /** + * The character set used by NBT (UTF-8). + */ + public static final Charset CHARSET = Charset.forName("UTF-8"); + + /** + * Tag type constants. + */ + public static final int TYPE_END = 0, + TYPE_BYTE = 1, + TYPE_SHORT = 2, + TYPE_INT = 3, + TYPE_LONG = 4, + TYPE_FLOAT = 5, + TYPE_DOUBLE = 6, + TYPE_BYTE_ARRAY = 7, + TYPE_STRING = 8, + TYPE_LIST = 9, + TYPE_COMPOUND = 10; + + /** + * Default private constructor. + */ + private NBTConstants() { + + } + +} diff --git a/src/com/garbagemule/MobArena/util/jnbt/NBTInputStream.java b/src/com/garbagemule/MobArena/util/jnbt/NBTInputStream.java new file mode 100644 index 0000000..6446dde --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/NBTInputStream.java @@ -0,0 +1,179 @@ +package com.garbagemule.MobArena.util.jnbt; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +import java.io.Closeable; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.zip.GZIPInputStream; + +/** + *

This class reads NBT, or + * Named Binary Tag streams, and produces an object graph of + * subclasses of the Tag object.

+ * + *

The NBT format was created by Markus Persson, and the specification may + * be found at + * http://www.minecraft.net/docs/NBT.txt.

+ * @author Graham Edgecombe + * + */ +public final class NBTInputStream implements Closeable { + + /** + * The data input stream. + */ + private final DataInputStream is; + + /** + * Creates a new NBTInputStream, which will source its data + * from the specified input stream. + * @param is The input stream. + * @throws IOException if an I/O error occurs. + */ + public NBTInputStream(InputStream is) throws IOException { + this.is = new DataInputStream(new GZIPInputStream(is)); + } + + /** + * Reads an NBT tag from the stream. + * @return The tag that was read. + * @throws IOException if an I/O error occurs. + */ + public Tag readTag() throws IOException { + return readTag(0); + } + + /** + * Reads an NBT from the stream. + * @param depth The depth of this tag. + * @return The tag that was read. + * @throws IOException if an I/O error occurs. + */ + private Tag readTag(int depth) throws IOException { + int type = is.readByte() & 0xFF; + + String name; + if(type != NBTConstants.TYPE_END) { + int nameLength = is.readShort() & 0xFFFF; + byte[] nameBytes = new byte[nameLength]; + is.readFully(nameBytes); + name = new String(nameBytes, NBTConstants.CHARSET); + } else { + name = ""; + } + + return readTagPayload(type, name, depth); + } + + /** + * Reads the payload of a tag, given the name and type. + * @param type The type. + * @param name The name. + * @param depth The depth. + * @return The tag. + * @throws IOException if an I/O error occurs. + */ + private Tag readTagPayload(int type, String name, int depth) throws IOException { + switch(type) { + case NBTConstants.TYPE_END: + if(depth == 0) { + throw new IOException("TAG_End found without a TAG_Compound/TAG_List tag preceding it."); + } else { + return new EndTag(); + } + case NBTConstants.TYPE_BYTE: + return new ByteTag(name, is.readByte()); + case NBTConstants.TYPE_SHORT: + return new ShortTag(name, is.readShort()); + case NBTConstants.TYPE_INT: + return new IntTag(name, is.readInt()); + case NBTConstants.TYPE_LONG: + return new LongTag(name, is.readLong()); + case NBTConstants.TYPE_FLOAT: + return new FloatTag(name, is.readFloat()); + case NBTConstants.TYPE_DOUBLE: + return new DoubleTag(name, is.readDouble()); + case NBTConstants.TYPE_BYTE_ARRAY: + int length = is.readInt(); + byte[] bytes = new byte[length]; + is.readFully(bytes); + return new ByteArrayTag(name, bytes); + case NBTConstants.TYPE_STRING: + length = is.readShort(); + bytes = new byte[length]; + is.readFully(bytes); + return new StringTag(name, new String(bytes, NBTConstants.CHARSET)); + case NBTConstants.TYPE_LIST: + int childType = is.readByte(); + length = is.readInt(); + + List tagList = new ArrayList(); + for(int i = 0; i < length; i++) { + Tag tag = readTagPayload(childType, "", depth + 1); + if(tag instanceof EndTag) { + throw new IOException("TAG_End not permitted in a list."); + } + tagList.add(tag); + } + + return new ListTag(name, NBTUtils.getTypeClass(childType), tagList); + case NBTConstants.TYPE_COMPOUND: + Map tagMap = new HashMap(); + while(true) { + Tag tag = readTag(depth + 1); + if(tag instanceof EndTag) { + break; + } else { + tagMap.put(tag.getName(), tag); + } + } + + return new CompoundTag(name, tagMap); + default: + throw new IOException("Invalid tag type: " + type + "."); + } + } + + @Override + public void close() throws IOException { + is.close(); + } + +} diff --git a/src/com/garbagemule/MobArena/util/jnbt/NBTOutputStream.java b/src/com/garbagemule/MobArena/util/jnbt/NBTOutputStream.java new file mode 100644 index 0000000..7ddbf27 --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/NBTOutputStream.java @@ -0,0 +1,257 @@ +package com.garbagemule.MobArena.util.jnbt; + +import java.io.Closeable; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; +import java.util.zip.GZIPOutputStream; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + *

This class writes NBT, or + * Named Binary Tag Tag objects to an underlying + * OutputStream.

+ * + *

The NBT format was created by Markus Persson, and the specification may + * be found at + * http://www.minecraft.net/docs/NBT.txt.

+ * @author Graham Edgecombe + * + */ +public final class NBTOutputStream implements Closeable { + + /** + * The output stream. + */ + private final DataOutputStream os; + + /** + * Creates a new NBTOutputStream, which will write data to the + * specified underlying output stream. + * @param os The output stream. + * @throws IOException if an I/O error occurs. + */ + public NBTOutputStream(OutputStream os) throws IOException { + this.os = new DataOutputStream(new GZIPOutputStream(os)); + } + + /** + * Writes a tag. + * @param tag The tag to write. + * @throws IOException if an I/O error occurs. + */ + public void writeTag(Tag tag) throws IOException { + int type = NBTUtils.getTypeCode(tag.getClass()); + String name = tag.getName(); + byte[] nameBytes = name.getBytes(NBTConstants.CHARSET); + + os.writeByte(type); + os.writeShort(nameBytes.length); + os.write(nameBytes); + + if(type == NBTConstants.TYPE_END) { + throw new IOException("Named TAG_End not permitted."); + } + + writeTagPayload(tag); + } + + /** + * Writes tag payload. + * @param tag The tag. + * @throws IOException if an I/O error occurs. + */ + private void writeTagPayload(Tag tag) throws IOException { + int type = NBTUtils.getTypeCode(tag.getClass()); + switch(type) { + case NBTConstants.TYPE_END: + writeEndTagPayload((EndTag) tag); + break; + case NBTConstants.TYPE_BYTE: + writeByteTagPayload((ByteTag) tag); + break; + case NBTConstants.TYPE_SHORT: + writeShortTagPayload((ShortTag) tag); + break; + case NBTConstants.TYPE_INT: + writeIntTagPayload((IntTag) tag); + break; + case NBTConstants.TYPE_LONG: + writeLongTagPayload((LongTag) tag); + break; + case NBTConstants.TYPE_FLOAT: + writeFloatTagPayload((FloatTag) tag); + break; + case NBTConstants.TYPE_DOUBLE: + writeDoubleTagPayload((DoubleTag) tag); + break; + case NBTConstants.TYPE_BYTE_ARRAY: + writeByteArrayTagPayload((ByteArrayTag) tag); + break; + case NBTConstants.TYPE_STRING: + writeStringTagPayload((StringTag) tag); + break; + case NBTConstants.TYPE_LIST: + writeListTagPayload((ListTag) tag); + break; + case NBTConstants.TYPE_COMPOUND: + writeCompoundTagPayload((CompoundTag) tag); + break; + default: + throw new IOException("Invalid tag type: " + type + "."); + } + } + + /** + * Writes a TAG_Byte tag. + * @param tag The tag. + * @throws IOException if an I/O error occurs. + */ + private void writeByteTagPayload(ByteTag tag) throws IOException { + os.writeByte(tag.getValue()); + } + + /** + * Writes a TAG_Byte_Array tag. + * @param tag The tag. + * @throws IOException if an I/O error occurs. + */ + private void writeByteArrayTagPayload(ByteArrayTag tag) throws IOException { + byte[] bytes = tag.getValue(); + os.writeInt(bytes.length); + os.write(bytes); + } + + /** + * Writes a TAG_Compound tag. + * @param tag The tag. + * @throws IOException if an I/O error occurs. + */ + private void writeCompoundTagPayload(CompoundTag tag) throws IOException { + for(Tag childTag : tag.getValue().values()) { + writeTag(childTag); + } + os.writeByte((byte) 0); // end tag - better way? + } + + /** + * Writes a TAG_List tag. + * @param tag The tag. + * @throws IOException if an I/O error occurs. + */ + private void writeListTagPayload(ListTag tag) throws IOException { + Class clazz = tag.getType(); + List tags = tag.getValue(); + int size = tags.size(); + + os.writeByte(NBTUtils.getTypeCode(clazz)); + os.writeInt(size); + for(int i = 0; i < size; i++) { + writeTagPayload(tags.get(i)); + } + } + + /** + * Writes a TAG_String tag. + * @param tag The tag. + * @throws IOException if an I/O error occurs. + */ + private void writeStringTagPayload(StringTag tag) throws IOException { + byte[] bytes = tag.getValue().getBytes(NBTConstants.CHARSET); + os.writeShort(bytes.length); + os.write(bytes); + } + + /** + * Writes a TAG_Double tag. + * @param tag The tag. + * @throws IOException if an I/O error occurs. + */ + private void writeDoubleTagPayload(DoubleTag tag) throws IOException { + os.writeDouble(tag.getValue()); + } + + /** + * Writes a TAG_Float tag. + * @param tag The tag. + * @throws IOException if an I/O error occurs. + */ + private void writeFloatTagPayload(FloatTag tag) throws IOException { + os.writeFloat(tag.getValue()); + } + + /** + * Writes a TAG_Long tag. + * @param tag The tag. + * @throws IOException if an I/O error occurs. + */ + private void writeLongTagPayload(LongTag tag) throws IOException { + os.writeLong(tag.getValue()); + } + + /** + * Writes a TAG_Int tag. + * @param tag The tag. + * @throws IOException if an I/O error occurs. + */ + private void writeIntTagPayload(IntTag tag) throws IOException { + os.writeInt(tag.getValue()); + } + + /** + * Writes a TAG_Short tag. + * @param tag The tag. + * @throws IOException if an I/O error occurs. + */ + private void writeShortTagPayload(ShortTag tag) throws IOException { + os.writeShort(tag.getValue()); + } + + /** + * Writes a TAG_Empty tag. + * @param tag The tag. + * @throws IOException if an I/O error occurs. + */ + private void writeEndTagPayload(EndTag tag) { + /* empty */ + } + + @Override + public void close() throws IOException { + os.close(); + } + +} diff --git a/src/com/garbagemule/MobArena/util/jnbt/NBTUtils.java b/src/com/garbagemule/MobArena/util/jnbt/NBTUtils.java new file mode 100644 index 0000000..ce97632 --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/NBTUtils.java @@ -0,0 +1,152 @@ +package com.garbagemule.MobArena.util.jnbt; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * A class which contains NBT-related utility methods. + * @author Graham Edgecombe + * + */ +public final class NBTUtils { + + /** + * Gets the type name of a tag. + * @param clazz The tag class. + * @return The type name. + */ + public static String getTypeName(Class clazz) { + if(clazz.equals(ByteArrayTag.class)) { + return "TAG_Byte_Array"; + } else if(clazz.equals(ByteTag.class)) { + return "TAG_Byte"; + } else if(clazz.equals(CompoundTag.class)) { + return "TAG_Compound"; + } else if(clazz.equals(DoubleTag.class)) { + return "TAG_Double"; + } else if(clazz.equals(EndTag.class)) { + return "TAG_End"; + } else if(clazz.equals(FloatTag.class)) { + return "TAG_Float"; + } else if(clazz.equals(IntTag.class)) { + return "TAG_Int"; + } else if(clazz.equals(ListTag.class)) { + return "TAG_List"; + } else if(clazz.equals(LongTag.class)) { + return "TAG_Long"; + } else if(clazz.equals(ShortTag.class)) { + return "TAG_Short"; + } else if(clazz.equals(StringTag.class)) { + return "TAG_String"; + } else { + throw new IllegalArgumentException("Invalid tag classs (" + clazz.getName() + ")."); + } + } + + /** + * Gets the type code of a tag class. + * @param clazz The tag class. + * @return The type code. + * @throws IllegalArgumentException if the tag class is invalid. + */ + public static int getTypeCode(Class clazz) { + if(clazz.equals(ByteArrayTag.class)) { + return NBTConstants.TYPE_BYTE_ARRAY; + } else if(clazz.equals(ByteTag.class)) { + return NBTConstants.TYPE_BYTE; + } else if(clazz.equals(CompoundTag.class)) { + return NBTConstants.TYPE_COMPOUND; + } else if(clazz.equals(DoubleTag.class)) { + return NBTConstants.TYPE_DOUBLE; + } else if(clazz.equals(EndTag.class)) { + return NBTConstants.TYPE_END; + } else if(clazz.equals(FloatTag.class)) { + return NBTConstants.TYPE_FLOAT; + } else if(clazz.equals(IntTag.class)) { + return NBTConstants.TYPE_INT; + } else if(clazz.equals(ListTag.class)) { + return NBTConstants.TYPE_LIST; + } else if(clazz.equals(LongTag.class)) { + return NBTConstants.TYPE_LONG; + } else if(clazz.equals(ShortTag.class)) { + return NBTConstants.TYPE_SHORT; + } else if(clazz.equals(StringTag.class)) { + return NBTConstants.TYPE_STRING; + } else { + throw new IllegalArgumentException("Invalid tag classs (" + clazz.getName() + ")."); + } + } + + /** + * Gets the class of a type of tag. + * @param type The type. + * @return The class. + * @throws IllegalArgumentException if the tag type is invalid. + */ + public static Class getTypeClass(int type) { + switch(type) { + case NBTConstants.TYPE_END: + return EndTag.class; + case NBTConstants.TYPE_BYTE: + return ByteTag.class; + case NBTConstants.TYPE_SHORT: + return ShortTag.class; + case NBTConstants.TYPE_INT: + return IntTag.class; + case NBTConstants.TYPE_LONG: + return LongTag.class; + case NBTConstants.TYPE_FLOAT: + return FloatTag.class; + case NBTConstants.TYPE_DOUBLE: + return DoubleTag.class; + case NBTConstants.TYPE_BYTE_ARRAY: + return ByteArrayTag.class; + case NBTConstants.TYPE_STRING: + return StringTag.class; + case NBTConstants.TYPE_LIST: + return ListTag.class; + case NBTConstants.TYPE_COMPOUND: + return CompoundTag.class; + default: + throw new IllegalArgumentException("Invalid tag type : " + type + "."); + } + } + + /** + * Default private constructor. + */ + private NBTUtils() { + + } + +} diff --git a/src/com/garbagemule/MobArena/util/jnbt/ShortTag.java b/src/com/garbagemule/MobArena/util/jnbt/ShortTag.java new file mode 100644 index 0000000..d94386b --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/ShortTag.java @@ -0,0 +1,73 @@ +package com.garbagemule.MobArena.util.jnbt; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * The TAG_Short tag. + * @author Graham Edgecombe + * + */ +public final class ShortTag extends Tag { + + /** + * The value. + */ + private final short value; + + /** + * Creates the tag. + * @param name The name. + * @param value The value. + */ + public ShortTag(String name, short value) { + super(name); + this.value = value; + } + + @Override + public Short getValue() { + return value; + } + + @Override + public String toString() { + String name = getName(); + String append = ""; + if(name != null && !name.equals("")) { + append = "(\"" + this.getName() + "\")"; + } + return "TAG_Short" + append + ": " + value; + } + +} diff --git a/src/com/garbagemule/MobArena/util/jnbt/StringTag.java b/src/com/garbagemule/MobArena/util/jnbt/StringTag.java new file mode 100644 index 0000000..a894c8b --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/StringTag.java @@ -0,0 +1,73 @@ +package com.garbagemule.MobArena.util.jnbt; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * The TAG_String tag. + * @author Graham Edgecombe + * + */ +public final class StringTag extends Tag { + + /** + * The value. + */ + private final String value; + + /** + * Creates the tag. + * @param name The name. + * @param value The value. + */ + public StringTag(String name, String value) { + super(name); + this.value = value; + } + + @Override + public String getValue() { + return value; + } + + @Override + public String toString() { + String name = getName(); + String append = ""; + if(name != null && !name.equals("")) { + append = "(\"" + this.getName() + "\")"; + } + return "TAG_String" + append + ": " + value; + } + +} diff --git a/src/com/garbagemule/MobArena/util/jnbt/Tag.java b/src/com/garbagemule/MobArena/util/jnbt/Tag.java new file mode 100644 index 0000000..19a5daf --- /dev/null +++ b/src/com/garbagemule/MobArena/util/jnbt/Tag.java @@ -0,0 +1,70 @@ +package com.garbagemule.MobArena.util.jnbt; + +/* + * JNBT License + * + * Copyright (c) 2010 Graham Edgecombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the JNBT team nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * Represents a single NBT tag. + * @author Graham Edgecombe + * + */ +public abstract class Tag { + + /** + * The name of this tag. + */ + private final String name; + + /** + * Creates the tag with the specified name. + * @param name The name. + */ + public Tag(String name) { + this.name = name; + } + + /** + * Gets the name of this tag. + * @return The name of this tag. + */ + public final String getName() { + return name; + } + + /** + * Gets the value of this tag. + * @return The value of this tag. + */ + public abstract Object getValue(); + +}