getViewers()
+ {
+ return transaction;
+ }
+
+ public InventoryHolder getOwner()
+ {
+ return this.owner;
+ }
+
+ public void setMaxStackSize(int size)
+ {
+ maxStack = size;
+ }
+
+ public int getMaxStackSize()
+ {
+ return maxStack;
+ }
+
+ public boolean a(EntityHuman entityhuman)
+ {
+ return true;
+ }
+
+ public void startOpen()
+ {
+
+ }
+
+ public void f()
+ {
+
+ }
+
+ public void update()
+ {
+ enderChest.update();
+ }
+}
diff --git a/src/com/lishid/openinv/internal/v1_4_5/SpecialPlayerInventory.java b/src/com/lishid/openinv/internal/v1_4_5/SpecialPlayerInventory.java
new file mode 100644
index 0000000..5b81c4f
--- /dev/null
+++ b/src/com/lishid/openinv/internal/v1_4_5/SpecialPlayerInventory.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2011-2012 lishid. All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lishid.openinv.internal.v1_4_5;
+
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+
+import com.lishid.openinv.OpenInv;
+import com.lishid.openinv.internal.ISpecialPlayerInventory;
+
+//Volatile
+import net.minecraft.server.v1_4_5.*;
+import org.bukkit.craftbukkit.v1_4_5.entity.*;
+import org.bukkit.craftbukkit.v1_4_5.inventory.*;
+
+public class SpecialPlayerInventory extends PlayerInventory implements ISpecialPlayerInventory
+{
+ CraftPlayer owner;
+ public boolean playerOnline = false;
+ private ItemStack[] extra = new ItemStack[5];
+ private CraftInventory inventory = new CraftInventory(this);
+
+ public SpecialPlayerInventory(Player p, Boolean online)
+ {
+ super(((CraftPlayer) p).getHandle());
+ this.owner = ((CraftPlayer) p);
+ this.playerOnline = online;
+ this.items = player.inventory.items;
+ this.armor = player.inventory.armor;
+ }
+
+ @Override
+ public Inventory getBukkitInventory()
+ {
+ return inventory;
+ }
+
+ @Override
+ public void InventoryRemovalCheck()
+ {
+ if (transaction.isEmpty() && !playerOnline)
+ {
+ owner.saveData();
+ OpenInv.inventories.remove(owner.getName().toLowerCase());
+ }
+ }
+
+ @Override
+ public void PlayerGoOnline(Player player)
+ {
+ if (!playerOnline)
+ {
+ CraftPlayer p = (CraftPlayer) player;
+ p.getHandle().inventory.items = this.items;
+ p.getHandle().inventory.armor = this.armor;
+ p.saveData();
+ playerOnline = true;
+ }
+ }
+
+ @Override
+ public void PlayerGoOffline()
+ {
+ playerOnline = false;
+ }
+
+ @Override
+ public void onClose(CraftHumanEntity who)
+ {
+ super.onClose(who);
+ this.InventoryRemovalCheck();
+ }
+
+ @Override
+ public ItemStack[] getContents()
+ {
+ ItemStack[] C = new ItemStack[getSize()];
+ System.arraycopy(items, 0, C, 0, items.length);
+ System.arraycopy(items, 0, C, items.length, armor.length);
+ return C;
+ }
+
+ @Override
+ public int getSize()
+ {
+ return super.getSize() + 5;
+ }
+
+ @Override
+ public ItemStack getItem(int i)
+ {
+ ItemStack[] is = this.items;
+
+ if (i >= is.length)
+ {
+ i -= is.length;
+ is = this.armor;
+ }
+ else
+ {
+ i = getReversedItemSlotNum(i);
+ }
+
+ if (i >= is.length)
+ {
+ i -= is.length;
+ is = this.extra;
+ }
+ else if (is == this.armor)
+ {
+ i = getReversedArmorSlotNum(i);
+ }
+
+ return is[i];
+ }
+
+ @Override
+ public ItemStack splitStack(int i, int j)
+ {
+ ItemStack[] is = this.items;
+
+ if (i >= is.length)
+ {
+ i -= is.length;
+ is = this.armor;
+ }
+ else
+ {
+ i = getReversedItemSlotNum(i);
+ }
+
+ if (i >= is.length)
+ {
+ i -= is.length;
+ is = this.extra;
+ }
+ else if (is == this.armor)
+ {
+ i = getReversedArmorSlotNum(i);
+ }
+
+ if (is[i] != null)
+ {
+ ItemStack itemstack;
+
+ if (is[i].count <= j)
+ {
+ itemstack = is[i];
+ is[i] = null;
+ return itemstack;
+ }
+ else
+ {
+ itemstack = is[i].a(j);
+ if (is[i].count == 0)
+ {
+ is[i] = null;
+ }
+
+ return itemstack;
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ @Override
+ public ItemStack splitWithoutUpdate(int i)
+ {
+ ItemStack[] is = this.items;
+
+ if (i >= is.length)
+ {
+ i -= is.length;
+ is = this.armor;
+ }
+ else
+ {
+ i = getReversedItemSlotNum(i);
+ }
+
+ if (i >= is.length)
+ {
+ i -= is.length;
+ is = this.extra;
+ }
+ else if (is == this.armor)
+ {
+ i = getReversedArmorSlotNum(i);
+ }
+
+ if (is[i] != null)
+ {
+ ItemStack itemstack = is[i];
+
+ is[i] = null;
+ return itemstack;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ @Override
+ public void setItem(int i, ItemStack itemstack)
+ {
+ ItemStack[] is = this.items;
+
+ if (i >= is.length)
+ {
+ i -= is.length;
+ is = this.armor;
+ }
+ else
+ {
+ i = getReversedItemSlotNum(i);
+ }
+
+ if (i >= is.length)
+ {
+ i -= is.length;
+ is = this.extra;
+ }
+ else if (is == this.armor)
+ {
+ i = getReversedArmorSlotNum(i);
+ }
+
+ /*
+ *
+ * //Effects
+ * if(is == this.extra)
+ * {
+ * if(i == 0)
+ * {
+ * itemstack.setData(0);
+ * }
+ * }
+ */
+
+ is[i] = itemstack;
+ }
+
+ private int getReversedItemSlotNum(int i)
+ {
+ if (i >= 27)
+ return i - 27;
+ else
+ return i + 9;
+ }
+
+ private int getReversedArmorSlotNum(int i)
+ {
+ if (i == 0)
+ return 3;
+ if (i == 1)
+ return 2;
+ if (i == 2)
+ return 1;
+ if (i == 3)
+ return 0;
+ else
+ return i;
+ }
+
+ @Override
+ public String getName()
+ {
+ if (player.name.length() > 16)
+ {
+ return player.name.substring(0, 16);
+ }
+ return player.name;
+ }
+
+ @Override
+ public boolean a_(EntityHuman entityhuman)
+ {
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/src/lishid/openinv/utils/Metrics.java b/src/com/lishid/openinv/utils/Metrics.java
similarity index 96%
rename from src/lishid/openinv/utils/Metrics.java
rename to src/com/lishid/openinv/utils/Metrics.java
index ec915b1..7bcce5b 100644
--- a/src/lishid/openinv/utils/Metrics.java
+++ b/src/com/lishid/openinv/utils/Metrics.java
@@ -1,4 +1,4 @@
-package lishid.openinv.utils;
+package com.lishid.openinv.utils;
/*
* Copyright 2011 Tyler Blair. All rights reserved.
diff --git a/src/com/lishid/openinv/utils/UpdateManager.java b/src/com/lishid/openinv/utils/UpdateManager.java
new file mode 100644
index 0000000..e41f16f
--- /dev/null
+++ b/src/com/lishid/openinv/utils/UpdateManager.java
@@ -0,0 +1,33 @@
+package com.lishid.openinv.utils;
+
+import java.io.File;
+
+import com.lishid.openinv.OpenInv;
+import com.lishid.openinv.utils.Updater.UpdateResult;
+import com.lishid.openinv.utils.Updater.UpdateType;
+
+public class UpdateManager
+{
+ public Updater updater;
+
+ public void Initialize(OpenInv plugin, File file)
+ {
+ updater = new Updater(plugin, OpenInv.logger, "openinv", file);
+
+ // Create task to update
+ plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ // Check for updates
+ if (OpenInv.GetCheckForUpdates())
+ {
+ UpdateResult result = updater.update(UpdateType.DEFAULT);
+ if (result != UpdateResult.NO_UPDATE)
+ OpenInv.log(result.toString());
+ }
+ }
+ }, 0, 20 * 60 * 1000); // Update every once a while
+ }
+}
diff --git a/src/com/lishid/openinv/utils/Updater.java b/src/com/lishid/openinv/utils/Updater.java
new file mode 100644
index 0000000..7edc8f0
--- /dev/null
+++ b/src/com/lishid/openinv/utils/Updater.java
@@ -0,0 +1,571 @@
+package com.lishid.openinv.utils;
+
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.XMLEvent;
+
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.plugin.Plugin;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Check dev.bukkit.org to find updates for a given plugin, and download the updates if needed.
+ *
+ * VERY, VERY IMPORTANT: Because there are no standards for adding auto-update toggles in your plugin's config, this system provides NO CHECK WITH YOUR CONFIG to make sure the user has allowed
+ * auto-updating.
+ * It is a BUKKIT POLICY that you include a boolean value in your config that prevents the auto-updater from running AT ALL.
+ * If you fail to include this option in your config, your plugin will be REJECTED when you attempt to submit it to dev.bukkit.org.
+ *
+ * An example of a good configuration option would be something similar to 'auto-update: true' - if this value is set to false you may NOT run the auto-updater.
+ * If you are unsure about these rules, please read the plugin submission guidelines: http://goo.gl/8iU5l
+ *
+ * @author H31IX
+ */
+
+public class Updater
+{
+ // If the version number contains one of these, don't update.
+ private static final String[] noUpdateTag = { "test", "unstable" };
+
+ // Slugs will be appended to this to get to the project's RSS feed
+ private static final String DBOUrl = "http://dev.bukkit.org/server-mods/";
+ private static final int BYTE_SIZE = 1024; // Used for downloading files
+
+ private final Plugin plugin;
+ private final String slug;
+
+ private volatile long totalSize; // Holds the total size of the file
+ private volatile int sizeLine; // Used for detecting file size
+ private volatile int multiplier; // Used for determining when to broadcast download updates
+
+ private volatile URL url; // Connecting to RSS
+
+ private volatile String updateFolder = YamlConfiguration.loadConfiguration(new File("bukkit.yml")).getString("settings.update-folder"); // The folder that downloads will be placed in
+
+ // Used for determining the outcome of the update process
+ private volatile Updater.UpdateResult result = Updater.UpdateResult.SUCCESS;
+
+ // Whether to announce file downloads
+ private volatile boolean announce = false;
+
+ private volatile UpdateType type;
+ private volatile String versionTitle;
+ private volatile String versionLink;
+
+ private volatile String versionDownloaded = "";
+ private volatile File file;
+
+ // Used to announce progress
+ private volatile Logger logger;
+
+ // Strings for reading RSS
+ private static final String TITLE = "title";
+ private static final String LINK = "link";
+ private static final String ITEM = "item";
+
+ /**
+ * Gives the dev the result of the update process. Can be obtained by called getResult().
+ */
+ public enum UpdateResult
+ {
+ /**
+ * The updater found an update, and has readied it to be loaded the next time the server restarts/reloads.
+ */
+ SUCCESS(1, "The updater found an update, and has readied it to be loaded the next time the server restarts/reloads."),
+
+ /**
+ * The updater did not find an update, and nothing was downloaded.
+ */
+ NO_UPDATE(2, "The updater did not find an update, and nothing was downloaded."),
+
+ /**
+ * The updater found an update, but was unable to download it.
+ */
+ FAIL_DOWNLOAD(3, "The updater found an update, but was unable to download it."),
+
+ /**
+ * For some reason, the updater was unable to contact dev.bukkit.org to download the file.
+ */
+ FAIL_DBO(4, "For some reason, the updater was unable to contact dev.bukkit.org to download the file."),
+
+ /**
+ * When running the version check, the file on DBO did not contain the a version in the format 'vVersion' such as 'v1.0'.
+ */
+ FAIL_NOVERSION(5, "When running the version check, the file on DBO did not contain the a version in the format 'vVersion' such as 'v1.0'."),
+
+ /**
+ * The slug provided by the plugin running the updater was invalid and doesn't exist on DBO.
+ */
+ FAIL_BADSLUG(6, "The slug provided by the plugin running the updater was invalid and doesn't exist on DBO."),
+
+ /**
+ * The updater found an update, but because of the UpdateType being set to NO_DOWNLOAD, it wasn't downloaded.
+ */
+ UPDATE_AVAILABLE(7, "The updater found an update, but because of the UpdateType being set to NO_DOWNLOAD, it wasn't downloaded.");
+
+ private static final Map valueList = new HashMap();
+ private final int value;
+ private final String description;
+
+ private UpdateResult(int value, String description)
+ {
+ this.value = value;
+ this.description = description;
+ }
+
+ public int getValue()
+ {
+ return this.value;
+ }
+
+ public static Updater.UpdateResult getResult(int value)
+ {
+ return valueList.get(value);
+ }
+
+ @Override
+ public String toString()
+ {
+ return description;
+ }
+
+ static
+ {
+ for (Updater.UpdateResult result : Updater.UpdateResult.values())
+ {
+ valueList.put(result.value, result);
+ }
+ }
+ }
+
+ /**
+ * Allows the dev to specify the type of update that will be run.
+ */
+ public enum UpdateType
+ {
+ /**
+ * Run a version check, and then if the file is out of date, download the newest version.
+ */
+ DEFAULT(1),
+ /**
+ * Don't run a version check, just find the latest update and download it.
+ */
+ NO_VERSION_CHECK(2),
+ /**
+ * Get information about the version and the download size, but don't actually download anything.
+ */
+ NO_DOWNLOAD(3);
+
+ private static final Map valueList = new HashMap();
+ private final int value;
+
+ private UpdateType(int value)
+ {
+ this.value = value;
+ }
+
+ public int getValue()
+ {
+ return this.value;
+ }
+
+ public static Updater.UpdateType getResult(int value)
+ {
+ return valueList.get(value);
+ }
+
+ static
+ {
+ for (Updater.UpdateType result : Updater.UpdateType.values())
+ {
+ valueList.put(result.value, result);
+ }
+ }
+ }
+
+ /**
+ * Initialize the updater
+ *
+ * @param plugin
+ * The plugin that is checking for an update.
+ * @param slug
+ * The dev.bukkit.org slug of the project (http://dev.bukkit.org/server-mods/SLUG_IS_HERE)
+ * @param file
+ * The file that the plugin is running from, get this by doing this.getFile() from within your main class.
+ * @param permission
+ * Permission needed to read the output of the update process.
+ */
+ public Updater(Plugin plugin, Logger logger, String slug, File file)
+ {
+ // I hate NULL
+ Preconditions.checkNotNull(plugin, "plugin");
+ Preconditions.checkNotNull(logger, "logger");
+ Preconditions.checkNotNull(slug, "slug");
+ Preconditions.checkNotNull(file, "file");
+
+ this.plugin = plugin;
+ this.file = file;
+ this.slug = slug;
+ this.logger = logger;
+ }
+
+ /**
+ * Update the plugin.
+ *
+ * @param type
+ * Specify the type of update this will be. See {@link UpdateType}
+ * @return The result of the update process.
+ */
+ public synchronized UpdateResult update(UpdateType type)
+ {
+ this.type = type;
+
+ try
+ {
+ // Obtain the results of the project's file feed
+ url = null;
+ url = new URL(DBOUrl + slug + "/files.rss");
+ }
+ catch (MalformedURLException ex)
+ {
+ // The slug doesn't exist
+ logger.warning("The author of this plugin has misconfigured their Auto Update system");
+ logger.warning("The project slug added ('" + slug + "') is invalid, and does not exist on dev.bukkit.org");
+ result = Updater.UpdateResult.FAIL_BADSLUG; // Bad slug! Bad!
+ }
+ if (url != null)
+ {
+ // Obtain the results of the project's file feed
+ readFeed();
+ if (!versionTitle.equals(versionDownloaded) && versionCheck(versionTitle))
+ {
+ String fileLink = getFile(versionLink);
+ if (fileLink != null && type != UpdateType.NO_DOWNLOAD)
+ {
+ String name = file.getName();
+ saveFile(new File("plugins/" + updateFolder), name, fileLink);
+ versionDownloaded = versionTitle;
+ }
+ else
+ {
+ result = UpdateResult.UPDATE_AVAILABLE;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Get the result of the update process.
+ */
+ public Updater.UpdateResult getResult()
+ {
+ return result;
+ }
+
+ /**
+ * Get the total bytes of the file (can only be used after running a version check or a normal run).
+ */
+ public long getFileSize()
+ {
+ return totalSize;
+ }
+
+ /**
+ * Get the version string latest file avaliable online.
+ */
+ public String getLatestVersionString()
+ {
+ return versionTitle;
+ }
+
+ /**
+ * Save an update from dev.bukkit.org into the server's update folder.
+ */
+ private void saveFile(File folder, String file, String u)
+ {
+ if (!folder.exists())
+ {
+ folder.mkdir();
+ }
+ BufferedInputStream in = null;
+ FileOutputStream fout = null;
+ try
+ {
+ // Download the file
+ URL url = new URL(u);
+ int fileLength = url.openConnection().getContentLength();
+ in = new BufferedInputStream(url.openStream());
+ fout = new FileOutputStream(folder.getAbsolutePath() + "/" + file);
+
+ byte[] data = new byte[BYTE_SIZE];
+ int count;
+ if (announce)
+ logger.info("About to download a new update: " + versionTitle);
+ long downloaded = 0;
+ while ((count = in.read(data, 0, BYTE_SIZE)) != -1)
+ {
+ downloaded += count;
+ fout.write(data, 0, count);
+ int percent = (int) (downloaded * 100 / fileLength);
+ if (announce && (percent % 10 == 0))
+ {
+ logger.info("Downloading update: " + percent + "% of " + fileLength + " bytes.");
+ }
+ }
+
+ if (announce)
+ logger.info("Finished updating.");
+ }
+ catch (Exception ex)
+ {
+ logger.warning("The auto-updater tried to download a new update, but was unsuccessful.");
+ logger.log(Level.INFO, "Error message to submit as a ticket.", ex);
+ result = Updater.UpdateResult.FAIL_DOWNLOAD;
+ }
+ finally
+ {
+ try
+ {
+ if (in != null)
+ {
+ in.close();
+ }
+ if (fout != null)
+ {
+ fout.close();
+ }
+ }
+ catch (Exception ex)
+ {
+ }
+ }
+ }
+
+ /**
+ * Check if the name of a jar is one of the plugins currently installed, used for extracting the correct files out of a zip.
+ */
+ public boolean pluginFile(String name)
+ {
+ for (File file : new File("plugins").listFiles())
+ {
+ if (file.getName().equals(name))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Obtain the direct download file url from the file's page.
+ */
+ private String getFile(String link)
+ {
+ String download = null;
+ try
+ {
+ // Open a connection to the page
+ URL url = new URL(link);
+ URLConnection urlConn = url.openConnection();
+ InputStreamReader inStream = new InputStreamReader(urlConn.getInputStream());
+ BufferedReader buff = new BufferedReader(inStream);
+
+ int counter = 0;
+ String line;
+ while ((line = buff.readLine()) != null)
+ {
+ counter++;
+ // Search for the download link
+ if (line.contains(""))
+ {
+ // Get the raw link
+ download = line.split("Download")[0];
+ }
+ // Search for size
+ else if (line.contains("Size"))
+ {
+ sizeLine = counter + 1;
+ }
+ else if (counter == sizeLine)
+ {
+ String size = line.replaceAll("", "").replaceAll("", "");
+ multiplier = size.contains("MiB") ? 1048576 : 1024;
+ size = size.replace(" KiB", "").replace(" MiB", "");
+ totalSize = (long) (Double.parseDouble(size) * multiplier);
+ }
+ }
+ urlConn = null;
+ inStream = null;
+ buff.close();
+ buff = null;
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ logger.warning("The auto-updater tried to contact dev.bukkit.org, but was unsuccessful.");
+ result = Updater.UpdateResult.FAIL_DBO;
+ return null;
+ }
+ return download;
+ }
+
+ /**
+ * Check to see if the program should continue by evaluation whether the plugin is already updated, or shouldn't be updated
+ */
+ private boolean versionCheck(String title)
+ {
+ if (type != UpdateType.NO_VERSION_CHECK)
+ {
+ String[] parts = title.split(" ");
+ String version = plugin.getDescription().getVersion();
+
+ if (parts.length >= 2)
+ {
+ String remoteVersion = parts[1].split(" ")[0]; // Get the newest file's version number
+ int remVer = -1, curVer = 0;
+ try
+ {
+ remVer = calVer(remoteVersion);
+ curVer = calVer(version);
+ }
+ catch (NumberFormatException nfe)
+ {
+ remVer = -1;
+ }
+
+ if (hasTag(version) || version.equalsIgnoreCase(remoteVersion) || curVer >= remVer)
+ {
+ // We already have the latest version, or this build is tagged for no-update
+ result = Updater.UpdateResult.NO_UPDATE;
+ return false;
+ }
+ }
+ else
+ {
+ // The file's name did not contain the string 'vVersion'
+ logger.warning("The author of this plugin has misconfigured their Auto Update system");
+ logger.warning("Files uploaded to BukkitDev should contain the version number, seperated from the name by a 'v', such as PluginName v1.0");
+ logger.warning("Please notify the author (" + plugin.getDescription().getAuthors().get(0) + ") of this error.");
+ result = Updater.UpdateResult.FAIL_NOVERSION;
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Used to calculate the version string as an Integer
+ */
+ private Integer calVer(String s) throws NumberFormatException
+ {
+ if (s.contains("."))
+ {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++)
+ {
+ Character c = s.charAt(i);
+ if (Character.isLetterOrDigit(c))
+ {
+ sb.append(c);
+ }
+ }
+ return Integer.parseInt(sb.toString());
+ }
+ return Integer.parseInt(s);
+ }
+
+ /**
+ * Evaluate whether the version number is marked showing that it should not be updated by this program
+ */
+ private boolean hasTag(String version)
+ {
+ for (String string : noUpdateTag)
+ {
+ if (version.contains(string))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Part of RSS Reader by Vogella, modified by H31IX for use with Bukkit
+ */
+ private void readFeed()
+ {
+ try
+ {
+ // Set header values intial to the empty string
+ String title = "";
+ String link = "";
+ // First create a new XMLInputFactory
+ XMLInputFactory inputFactory = XMLInputFactory.newInstance();
+ // Setup a new eventReader
+ InputStream in = read();
+ XMLEventReader eventReader = inputFactory.createXMLEventReader(in);
+ // Read the XML document
+ while (eventReader.hasNext())
+ {
+ XMLEvent event = eventReader.nextEvent();
+ if (event.isStartElement())
+ {
+ if (event.asStartElement().getName().getLocalPart().equals(TITLE))
+ {
+ event = eventReader.nextEvent();
+ title = event.asCharacters().getData();
+ continue;
+ }
+ if (event.asStartElement().getName().getLocalPart().equals(LINK))
+ {
+ event = eventReader.nextEvent();
+ link = event.asCharacters().getData();
+ continue;
+ }
+ }
+ else if (event.isEndElement())
+ {
+ if (event.asEndElement().getName().getLocalPart().equals(ITEM))
+ {
+ // Store the title and link of the first entry we get - the first file on the list is all we need
+ versionTitle = title;
+ versionLink = link;
+ // All done, we don't need to know about older files.
+ break;
+ }
+ }
+ }
+ }
+ catch (XMLStreamException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Open the RSS feed
+ */
+ private InputStream read()
+ {
+ try
+ {
+ return url.openStream();
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/lishid/openinv/OpenInvPlayerListener.java b/src/lishid/openinv/OpenInvPlayerListener.java
deleted file mode 100644
index 1f4a070..0000000
--- a/src/lishid/openinv/OpenInvPlayerListener.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2011-2012 lishid. All rights reserved.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package lishid.openinv;
-
-import java.lang.reflect.Field;
-
-import lishid.openinv.utils.OpenInvEnderChest;
-import lishid.openinv.utils.OpenInvPlayerInventory;
-import lishid.openinv.utils.SilentContainerChest;
-import net.minecraft.server.Block;
-import net.minecraft.server.EntityPlayer;
-import net.minecraft.server.IInventory;
-import net.minecraft.server.InventoryLargeChest;
-import net.minecraft.server.Packet100OpenWindow;
-import net.minecraft.server.TileEntityChest;
-import net.minecraft.server.World;
-
-import org.bukkit.ChatColor;
-import org.bukkit.block.Chest;
-import org.bukkit.block.Sign;
-import org.bukkit.craftbukkit.entity.CraftPlayer;
-import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.EventPriority;
-import org.bukkit.event.Event.Result;
-import org.bukkit.event.Listener;
-import org.bukkit.event.block.Action;
-import org.bukkit.event.player.PlayerInteractEvent;
-import org.bukkit.event.player.PlayerJoinEvent;
-import org.bukkit.event.player.PlayerQuitEvent;
-
-public class OpenInvPlayerListener implements Listener
-{
- @EventHandler(priority = EventPriority.LOWEST)
- public void onPlayerJoin(PlayerJoinEvent event)
- {
- OpenInvPlayerInventory inventory = OpenInv.inventories.get(event.getPlayer().getName().toLowerCase());
-
- if (inventory != null)
- {
- inventory.PlayerGoOnline((CraftPlayer) event.getPlayer());
- }
-
- OpenInvEnderChest chest = OpenInv.enderChests.get(event.getPlayer().getName().toLowerCase());
-
- if (chest != null)
- {
- chest.PlayerGoOnline((CraftPlayer) event.getPlayer());
- }
- }
-
- @EventHandler(priority = EventPriority.MONITOR)
- public void onPlayerQuit(PlayerQuitEvent event)
- {
- OpenInvPlayerInventory inventory = OpenInv.inventories.get(event.getPlayer().getName().toLowerCase());
- if (inventory != null)
- {
- inventory.PlayerGoOffline();
- inventory.InventoryRemovalCheck();
- }
- OpenInvEnderChest chest = OpenInv.enderChests.get(event.getPlayer().getName().toLowerCase());
- if (chest != null)
- {
- chest.PlayerGoOffline();
- chest.InventoryRemovalCheck();
- }
- }
-
- @EventHandler(priority = EventPriority.MONITOR)
- public void onPlayerInteract(PlayerInteractEvent event)
- {
- if (event.getAction() == Action.RIGHT_CLICK_BLOCK && event.useInteractedBlock() == Result.DENY)
- return;
-
- if (event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getClickedBlock().getState() instanceof Chest)
- {
- boolean silentchest = false;
- boolean anychest = false;
- int x = event.getClickedBlock().getX();
- int y = event.getClickedBlock().getY();
- int z = event.getClickedBlock().getZ();
-
- if (event.getPlayer().hasPermission(Permissions.PERM_SILENT) && OpenInv.GetPlayerSilentChestStatus(event.getPlayer().getName()))
- {
- silentchest = true;
- }
-
- if (event.getPlayer().hasPermission(Permissions.PERM_ANYCHEST) && OpenInv.GetPlayerAnyChestStatus(event.getPlayer().getName()))
- {
- try
- {
- // FOR REFERENCE, LOOK AT net.minecraft.server.BlockChest
- EntityPlayer player = ((CraftPlayer) event.getPlayer()).getHandle();
- World world = player.world;
- // If block on top
- if (world.s(x, y + 1, z))
- anychest = true;
-
- // If block next to chest is chest and has a block on top
- if ((world.getTypeId(x - 1, y, z) == Block.CHEST.id) && (world.s(x - 1, y + 1, z)))
- anychest = true;
- if ((world.getTypeId(x + 1, y, z) == Block.CHEST.id) && (world.s(x + 1, y + 1, z)))
- anychest = true;
- if ((world.getTypeId(x, y, z - 1) == Block.CHEST.id) && (world.s(x, y + 1, z - 1)))
- anychest = true;
- if ((world.getTypeId(x, y, z + 1) == Block.CHEST.id) && (world.s(x, y + 1, z + 1)))
- anychest = true;
- }
- catch (Exception e)
- {
- event.getPlayer().sendMessage(ChatColor.RED + "Error while executing openinv. Unsupported CraftBukkit.");
- e.printStackTrace();
- }
- }
-
- // If the anychest or silentchest is active
- if (anychest || silentchest)
- {
- EntityPlayer player = ((CraftPlayer) event.getPlayer()).getHandle();
- World world = player.world;
- Object chest = (TileEntityChest) world.getTileEntity(x, y, z);
- if (chest == null)
- return;
-
- if (!anychest)
- {
- if (world.s(x, y + 1, z))
- return;
- if ((world.getTypeId(x - 1, y, z) == Block.CHEST.id) && (world.s(x - 1, y + 1, z)))
- return;
- if ((world.getTypeId(x + 1, y, z) == Block.CHEST.id) && (world.s(x + 1, y + 1, z)))
- return;
- if ((world.getTypeId(x, y, z - 1) == Block.CHEST.id) && (world.s(x, y + 1, z - 1)))
- return;
- if ((world.getTypeId(x, y, z + 1) == Block.CHEST.id) && (world.s(x, y + 1, z + 1)))
- return;
- }
-
- if (world.getTypeId(x - 1, y, z) == Block.CHEST.id)
- chest = new InventoryLargeChest("Large chest", (TileEntityChest) world.getTileEntity(x - 1, y, z), (IInventory) chest);
- if (world.getTypeId(x + 1, y, z) == Block.CHEST.id)
- chest = new InventoryLargeChest("Large chest", (IInventory) chest, (TileEntityChest) world.getTileEntity(x + 1, y, z));
- if (world.getTypeId(x, y, z - 1) == Block.CHEST.id)
- chest = new InventoryLargeChest("Large chest", (TileEntityChest) world.getTileEntity(x, y, z - 1), (IInventory) chest);
- if (world.getTypeId(x, y, z + 1) == Block.CHEST.id)
- chest = new InventoryLargeChest("Large chest", (IInventory) chest, (TileEntityChest) world.getTileEntity(x, y, z + 1));
-
- if (!silentchest)
- {
- player.openContainer((IInventory) chest);
- }
- else
- {
- try
- {
- int id = 0;
- try
- {
- Field windowID = player.getClass().getDeclaredField("containerCounter");
- windowID.setAccessible(true);
- id = windowID.getInt(player);
- id = id % 100 + 1;
- windowID.setInt(player, id);
- }
- catch (NoSuchFieldException e)
- {
- }
-
- player.netServerHandler.sendPacket(new Packet100OpenWindow(id, 0, ((IInventory) chest).getName(), ((IInventory) chest).getSize()));
- player.activeContainer = new SilentContainerChest(player.inventory, ((IInventory) chest));
- player.activeContainer.windowId = id;
- player.activeContainer.addSlotListener(player);
- // event.getPlayer().sendMessage("You are opening a chest silently.");
- event.setUseInteractedBlock(Result.DENY);
- event.setCancelled(true);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- event.getPlayer().sendMessage(ChatColor.RED + "Error while sending silent chest.");
- }
- }
-
- if (anychest)
- event.getPlayer().sendMessage("You are opening a blocked chest.");
- }
- }
-
- if (event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getClickedBlock().getState() instanceof Sign)
- {
- Player player = event.getPlayer();
- try
- {
- Sign sign = ((Sign) event.getClickedBlock().getState());
- if (player.hasPermission(Permissions.PERM_OPENINV) && sign.getLine(0).equalsIgnoreCase("[openinv]"))
- {
- String text = sign.getLine(1).trim() + sign.getLine(2).trim() + sign.getLine(3).trim();
- player.performCommand("openinv " + text);
- }
- }
- catch (Exception ex)
- {
- player.sendMessage("Internal Error.");
- ex.printStackTrace();
- }
- }
-
- if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK)
- {
- Player player = event.getPlayer();
-
- if (!(player.getItemInHand().getType().getId() == OpenInv.GetItemOpenInvItem()) || (!OpenInv.GetPlayerItemOpenInvStatus(player.getName())) || !player.hasPermission(Permissions.PERM_OPENINV))
- {
- return;
- }
-
- player.performCommand("openinv");
- }
- }
-}
\ No newline at end of file
diff --git a/src/plugin.yml b/src/plugin.yml
index f131328..2570f5e 100644
--- a/src/plugin.yml
+++ b/src/plugin.yml
@@ -1,8 +1,7 @@
name: OpenInv
-main: lishid.openinv.OpenInv
-version: 1.9.0
+main: com.lishid.openinv.OpenInv
+version: 1.9.2
author: lishid
-website: http://forums.bukkit.org/threads/15379/
description: >
This plugin allows you to open a player's inventory as a chest and interact with it in real time.
commands: