container, final String search)
+ {
+ String found = null;
+ if (search == null)
+ {
+ return found;
+ }
+ final String lowerSearch = search.toLowerCase();
+ int delta = Integer.MAX_VALUE;
+ for (final File file : container)
+ {
+ final String filename = file.getName();
+ final String str = filename.substring(0, filename.length() - 4);
+ if (!str.toLowerCase().startsWith(lowerSearch))
+ {
+ continue;
+ }
+ final int curDelta = str.length() - lowerSearch.length();
+ if (curDelta < delta)
+ {
+ found = str;
+ delta = curDelta;
+ }
+ if (curDelta == 0)
+ {
+ break;
+ }
+
+ }
+ return found;
}
}
diff --git a/src/lishid/openinv/commands/SearchInvPluginCommand.java b/src/lishid/openinv/commands/SearchInvPluginCommand.java
index 63cc5f8..4bee2a8 100644
--- a/src/lishid/openinv/commands/SearchInvPluginCommand.java
+++ b/src/lishid/openinv/commands/SearchInvPluginCommand.java
@@ -25,55 +25,64 @@ import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-public class SearchInvPluginCommand implements CommandExecutor {
+public class SearchInvPluginCommand implements CommandExecutor
+{
private final OpenInv plugin;
- public SearchInvPluginCommand(OpenInv plugin) {
+
+ public SearchInvPluginCommand(OpenInv plugin)
+ {
this.plugin = plugin;
}
- public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-
- if(sender instanceof Player)
- {
- if (!sender.hasPermission("OpenInv.search")) {
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
+ {
+ if (sender instanceof Player)
+ {
+ if (!sender.hasPermission("OpenInv.search"))
+ {
sender.sendMessage(ChatColor.RED + "You do not have permission to access player inventories");
return true;
}
- }
-
-
- String PlayerList = "";
-
+ }
+
+ String PlayerList = "";
+
Material material = null;
int count = 1;
-
- if (args.length >= 1) {
+
+ if (args.length >= 1)
+ {
String[] gData = null;
gData = args[0].split(":");
material = Material.matchMaterial(gData[0]);
}
- if (args.length >= 2) {
- try {
+ if (args.length >= 2)
+ {
+ try
+ {
count = Integer.parseInt(args[1]);
- } catch (NumberFormatException ex) {
+ }
+ catch (NumberFormatException ex)
+ {
sender.sendMessage(ChatColor.RED + "'" + args[1] + "' is not a number!");
return false;
}
}
-
- if (material == null) {
+
+ if (material == null)
+ {
sender.sendMessage(ChatColor.RED + "Unknown item");
return false;
}
-
- for(Player templayer : plugin.getServer().getOnlinePlayers())
- {
- if(templayer.getInventory().contains(material, count))
- {
- PlayerList += templayer.getName() + " ";
- }
- }
-
+
+ for (Player templayer : plugin.getServer().getOnlinePlayers())
+ {
+ if (templayer.getInventory().contains(material, count))
+ {
+ PlayerList += templayer.getName() + " ";
+ }
+ }
+
sender.sendMessage("Players with the item " + material.toString() + ": " + PlayerList);
return true;
}
diff --git a/src/lishid/openinv/commands/SilentChestPluginCommand.java b/src/lishid/openinv/commands/SilentChestPluginCommand.java
index 71a25e7..62c7f3b 100644
--- a/src/lishid/openinv/commands/SilentChestPluginCommand.java
+++ b/src/lishid/openinv/commands/SilentChestPluginCommand.java
@@ -24,36 +24,40 @@ import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-public class SilentChestPluginCommand implements CommandExecutor {
- public SilentChestPluginCommand(OpenInv plugin) {
-
+public class SilentChestPluginCommand implements CommandExecutor
+{
+ public SilentChestPluginCommand(OpenInv plugin)
+ {
+
}
- public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
- if(!(sender instanceof Player))
- {
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
+ {
+ if (!(sender instanceof Player))
+ {
sender.sendMessage(ChatColor.RED + "You can't use this from the console.");
- return true;
- }
- if (!sender.hasPermission("OpenInv.silent")) {
+ return true;
+ }
+ if (!sender.hasPermission("OpenInv.silent"))
+ {
sender.sendMessage(ChatColor.RED + "You do not have permission to use silent chest.");
return true;
}
-
- if(args.length > 0)
- {
- if(args[0].equalsIgnoreCase("check"))
- {
- if(OpenInv.GetPlayerSilentChestStatus(sender.getName()))
- sender.sendMessage("SilentChest is ON.");
- else
- sender.sendMessage("SilentChest is OFF.");
- }
- }
-
- OpenInv.SetPlayerSilentChestStatus(sender.getName(), !OpenInv.GetPlayerSilentChestStatus(sender.getName()));
- sender.sendMessage("SilentChest is now " + (OpenInv.GetPlayerSilentChestStatus(sender.getName())?"On":"Off") + ".");
-
+
+ if (args.length > 0)
+ {
+ if (args[0].equalsIgnoreCase("check"))
+ {
+ if (OpenInv.GetPlayerSilentChestStatus(sender.getName()))
+ sender.sendMessage("SilentChest is ON.");
+ else
+ sender.sendMessage("SilentChest is OFF.");
+ }
+ }
+
+ OpenInv.SetPlayerSilentChestStatus(sender.getName(), !OpenInv.GetPlayerSilentChestStatus(sender.getName()));
+ sender.sendMessage("SilentChest is now " + (OpenInv.GetPlayerSilentChestStatus(sender.getName()) ? "On" : "Off") + ".");
+
return true;
}
}
diff --git a/src/lishid/openinv/commands/ToggleOpenInvPluginCommand.java b/src/lishid/openinv/commands/ToggleOpenInvPluginCommand.java
index 302b1c3..2eb1baf 100644
--- a/src/lishid/openinv/commands/ToggleOpenInvPluginCommand.java
+++ b/src/lishid/openinv/commands/ToggleOpenInvPluginCommand.java
@@ -25,40 +25,43 @@ import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-public class ToggleOpenInvPluginCommand implements CommandExecutor {
+public class ToggleOpenInvPluginCommand implements CommandExecutor
+{
- public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
- if(!(sender instanceof Player))
- {
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
+ {
+ if (!(sender instanceof Player))
+ {
sender.sendMessage(ChatColor.RED + "You can't use this from the console.");
- return true;
- }
- if (!sender.hasPermission("OpenInv.openinv")) {
+ return true;
+ }
+ if (!sender.hasPermission("OpenInv.openinv"))
+ {
sender.sendMessage(ChatColor.RED + "You do not have permission to access player inventories");
return true;
}
-
- Player player = (Player)sender;
- if(args.length > 0)
- {
- if(args[0].equalsIgnoreCase("check"))
- {
- if(OpenInv.GetPlayerItemOpenInvStatus(player.getName()))
- player.sendMessage("OpenInv with " + Material.getMaterial(OpenInv.GetItemOpenInvItem()).toString() + " is ON.");
- else
- player.sendMessage("OpenInv with " + Material.getMaterial(OpenInv.GetItemOpenInvItem()).toString() + " is OFF.");
- }
- }
- if(OpenInv.GetPlayerItemOpenInvStatus(player.getName()))
- {
- OpenInv.SetPlayerItemOpenInvStatus(player.getName(), false);
- player.sendMessage("OpenInv with " + Material.getMaterial(OpenInv.GetItemOpenInvItem()).toString() + " is OFF.");
- }
- else
- {
- OpenInv.SetPlayerItemOpenInvStatus(player.getName(), true);
- player.sendMessage("OpenInv with " + Material.getMaterial(OpenInv.GetItemOpenInvItem()).toString() + " is ON.");
- }
- return true;
+
+ Player player = (Player) sender;
+ if (args.length > 0)
+ {
+ if (args[0].equalsIgnoreCase("check"))
+ {
+ if (OpenInv.GetPlayerItemOpenInvStatus(player.getName()))
+ player.sendMessage("OpenInv with " + Material.getMaterial(OpenInv.GetItemOpenInvItem()).toString() + " is ON.");
+ else
+ player.sendMessage("OpenInv with " + Material.getMaterial(OpenInv.GetItemOpenInvItem()).toString() + " is OFF.");
+ }
+ }
+ if (OpenInv.GetPlayerItemOpenInvStatus(player.getName()))
+ {
+ OpenInv.SetPlayerItemOpenInvStatus(player.getName(), false);
+ player.sendMessage("OpenInv with " + Material.getMaterial(OpenInv.GetItemOpenInvItem()).toString() + " is OFF.");
+ }
+ else
+ {
+ OpenInv.SetPlayerItemOpenInvStatus(player.getName(), true);
+ player.sendMessage("OpenInv with " + Material.getMaterial(OpenInv.GetItemOpenInvItem()).toString() + " is ON.");
+ }
+ return true;
}
}
diff --git a/src/lishid/openinv/utils/Metrics.java b/src/lishid/openinv/utils/Metrics.java
index 364cc43..ec915b1 100644
--- a/src/lishid/openinv/utils/Metrics.java
+++ b/src/lishid/openinv/utils/Metrics.java
@@ -30,6 +30,7 @@ package lishid.openinv.utils;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
@@ -49,6 +50,7 @@ import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
+import java.util.logging.Level;
/**
*
@@ -63,430 +65,631 @@ import java.util.UUID;
* void start();
*
*/
-public class Metrics {
-
+public class Metrics
+{
+
/**
* The current revision number
*/
private final static int REVISION = 5;
-
+
/**
* The base url of the metrics domain
*/
- private static final String BASE_URL = "http://metrics.griefcraft.com";
-
+ private static final String BASE_URL = "http://mcstats.org";
+
/**
* The url used to report a server's status
*/
private static final String REPORT_URL = "/report/%s";
-
+
/**
* The file where guid and opt out is stored in
*/
private static final String CONFIG_FILE = "plugins/PluginMetrics/config.yml";
-
+
/**
* The separator to use for custom data. This MUST NOT change unless you are hosting your own
* version of metrics and want to change it.
*/
private static final String CUSTOM_DATA_SEPARATOR = "~~";
-
+
/**
* Interval of time to ping (in minutes)
*/
- private final static int PING_INTERVAL = 10;
-
+ private static final int PING_INTERVAL = 10;
+
/**
* The plugin this metrics submits for
*/
private final Plugin plugin;
-
+
/**
* All of the custom graphs to submit to metrics
*/
private final Set graphs = Collections.synchronizedSet(new HashSet());
-
+
/**
* The default graph, used for addCustomData when you don't want a specific graph
*/
private final Graph defaultGraph = new Graph("Default");
-
+
/**
* The plugin configuration file
*/
private final YamlConfiguration configuration;
-
+
+ /**
+ * The plugin configuration file
+ */
+ private final File configurationFile;
+
/**
* Unique server id
*/
private final String guid;
-
- public Metrics(Plugin plugin) throws IOException {
- if (plugin == null) {
+
+ /**
+ * Lock for synchronization
+ */
+ private final Object optOutLock = new Object();
+
+ /**
+ * Id of the scheduled task
+ */
+ private volatile int taskId = -1;
+
+ public Metrics(final Plugin plugin) throws IOException
+ {
+ if (plugin == null)
+ {
throw new IllegalArgumentException("Plugin cannot be null");
}
-
+
this.plugin = plugin;
-
+
// load the config
- File file = new File(CONFIG_FILE);
- configuration = YamlConfiguration.loadConfiguration(file);
-
+ configurationFile = new File(CONFIG_FILE);
+ configuration = YamlConfiguration.loadConfiguration(configurationFile);
+
// add some defaults
configuration.addDefault("opt-out", false);
configuration.addDefault("guid", UUID.randomUUID().toString());
-
+
// Do we need to create the file?
- if (configuration.get("guid", null) == null) {
- configuration.options().header("http://metrics.griefcraft.com").copyDefaults(true);
- configuration.save(file);
+ if (configuration.get("guid", null) == null)
+ {
+ configuration.options().header("http://mcstats.org").copyDefaults(true);
+ configuration.save(configurationFile);
}
-
+
// Load the guid then
guid = configuration.getString("guid");
}
-
+
/**
* Construct and create a Graph that can be used to separate specific plotters to their own graphs
* on the metrics website. Plotters can be added to the graph object returned.
- *
+ *
* @param name
* @return Graph object created. Will never return NULL under normal circumstances unless bad parameters are given
*/
- public Graph createGraph(String name) {
- if (name == null) {
+ public Graph createGraph(final String name)
+ {
+ if (name == null)
+ {
throw new IllegalArgumentException("Graph name cannot be null");
}
-
+
// Construct the graph object
- Graph graph = new Graph(name);
-
+ final Graph graph = new Graph(name);
+
// Now we can add our graph
graphs.add(graph);
-
+
// and return back
return graph;
}
-
+
+ /**
+ * Add a Graph object to Metrics that represents data for the plugin that should be sent to the backend
+ *
+ * @param graph
+ */
+ public void addGraph(final Graph graph)
+ {
+ if (graph == null)
+ {
+ throw new IllegalArgumentException("Graph cannot be null");
+ }
+
+ graphs.add(graph);
+ }
+
/**
* Adds a custom data plotter to the default graph
- *
+ *
* @param plotter
*/
- public void addCustomData(Plotter plotter) {
- if (plotter == null) {
+ public void addCustomData(final Plotter plotter)
+ {
+ if (plotter == null)
+ {
throw new IllegalArgumentException("Plotter cannot be null");
}
-
+
// Add the plotter to the graph o/
defaultGraph.addPlotter(plotter);
-
+
// Ensure the default graph is included in the submitted graphs
graphs.add(defaultGraph);
}
-
+
/**
* Start measuring statistics. This will immediately create an async repeating task as the plugin and send
* the initial data to the metrics backend, and then after that it will post in increments of
* PING_INTERVAL * 1200 ticks.
+ *
+ * @return True if statistics measuring is running, otherwise false.
*/
- public void start() {
- // Did we opt out?
- if (configuration.getBoolean("opt-out", false)) {
- return;
- }
-
- // Begin hitting the server with glorious data
- plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
- private boolean firstPost = true;
-
- public void run() {
- try {
- // We use the inverse of firstPost because if it is the first time we are posting,
- // it is not a interval ping, so it evaluates to FALSE
- // Each time thereafter it will evaluate to TRUE, i.e PING!
- postPlugin(!firstPost);
-
- // After the first post we set firstPost to false
- // Each post thereafter will be a ping
- firstPost = false;
- } catch (Exception e) {
- System.err.println("[Metrics] " + e.getMessage());
- }
+ public boolean start()
+ {
+ synchronized (optOutLock)
+ {
+ // Did we opt out?
+ if (isOptOut())
+ {
+ return false;
}
- }, 0, PING_INTERVAL * 1200);
+
+ // Is metrics already running?
+ if (taskId >= 0)
+ {
+ return true;
+ }
+
+ // Begin hitting the server with glorious data
+ taskId = plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable()
+ {
+
+ private boolean firstPost = true;
+
+ public void run()
+ {
+ try
+ {
+ // This has to be synchronized or it can collide with the disable method.
+ synchronized (optOutLock)
+ {
+ // Disable Task, if it is running and the server owner decided to opt-out
+ if (isOptOut() && taskId > 0)
+ {
+ plugin.getServer().getScheduler().cancelTask(taskId);
+ taskId = -1;
+ // Tell all plotters to stop gathering information.
+ for (Graph graph : graphs)
+ {
+ graph.onOptOut();
+ }
+ }
+ }
+
+ // We use the inverse of firstPost because if it is the first time we are posting,
+ // it is not a interval ping, so it evaluates to FALSE
+ // Each time thereafter it will evaluate to TRUE, i.e PING!
+ postPlugin(!firstPost);
+
+ // After the first post we set firstPost to false
+ // Each post thereafter will be a ping
+ firstPost = false;
+ }
+ catch (IOException e)
+ {
+ Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
+ }
+ }
+ }, 0, PING_INTERVAL * 1200);
+
+ return true;
+ }
}
-
+
+ /**
+ * Has the server owner denied plugin metrics?
+ *
+ * @return
+ */
+ public boolean isOptOut()
+ {
+ synchronized (optOutLock)
+ {
+ try
+ {
+ // Reload the metrics file
+ configuration.load(CONFIG_FILE);
+ }
+ catch (IOException ex)
+ {
+ Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
+ return true;
+ }
+ catch (InvalidConfigurationException ex)
+ {
+ Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
+ return true;
+ }
+ return configuration.getBoolean("opt-out", false);
+ }
+ }
+
+ /**
+ * Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task.
+ *
+ * @throws IOException
+ */
+ public void enable() throws IOException
+ {
+ // This has to be synchronized or it can collide with the check in the task.
+ synchronized (optOutLock)
+ {
+ // Check if the server owner has already set opt-out, if not, set it.
+ if (isOptOut())
+ {
+ configuration.set("opt-out", false);
+ configuration.save(configurationFile);
+ }
+
+ // Enable Task, if it is not running
+ if (taskId < 0)
+ {
+ start();
+ }
+ }
+ }
+
+ /**
+ * Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task.
+ *
+ * @throws IOException
+ */
+ public void disable() throws IOException
+ {
+ // This has to be synchronized or it can collide with the check in the task.
+ synchronized (optOutLock)
+ {
+ // Check if the server owner has already set opt-out, if not, set it.
+ if (!isOptOut())
+ {
+ configuration.set("opt-out", true);
+ configuration.save(configurationFile);
+ }
+
+ // Disable Task, if it is running
+ if (taskId > 0)
+ {
+ this.plugin.getServer().getScheduler().cancelTask(taskId);
+ taskId = -1;
+ }
+ }
+ }
+
/**
* Generic method that posts a plugin to the metrics website
*/
- private void postPlugin(boolean isPing) throws IOException {
+ private void postPlugin(final boolean isPing) throws IOException
+ {
// The plugin's description file containg all of the plugin data such as name, version, author, etc
- PluginDescriptionFile description = plugin.getDescription();
-
+ final PluginDescriptionFile description = plugin.getDescription();
+
// Construct the post data
- String data = encode("guid") + '=' + encode(guid)
- + encodeDataPair("version", description.getVersion())
- + encodeDataPair("server", Bukkit.getVersion())
- + encodeDataPair("players", Integer.toString(Bukkit.getServer().getOnlinePlayers().length))
- + encodeDataPair("revision", String.valueOf(REVISION));
-
+ final StringBuilder data = new StringBuilder();
+ data.append(encode("guid")).append('=').append(encode(guid));
+ encodeDataPair(data, "version", description.getVersion());
+ encodeDataPair(data, "server", Bukkit.getVersion());
+ encodeDataPair(data, "players", Integer.toString(Bukkit.getServer().getOnlinePlayers().length));
+ encodeDataPair(data, "revision", String.valueOf(REVISION));
+
// If we're pinging, append it
- if (isPing) {
- data += encodeDataPair("ping", "true");
+ if (isPing)
+ {
+ encodeDataPair(data, "ping", "true");
}
-
+
// Acquire a lock on the graphs, which lets us make the assumption we also lock everything
// inside of the graph (e.g plotters)
- synchronized (graphs) {
- Iterator iter = graphs.iterator();
-
- while (iter.hasNext()) {
- Graph graph = iter.next();
-
- // Because we have a lock on the graphs set already, it is reasonable to assume
- // that our lock transcends down to the individual plotters in the graphs also.
- // Because our methods are private, no one but us can reasonably access this list
- // without reflection so this is a safe assumption without adding more code.
- for (Plotter plotter : graph.getPlotters()) {
+ synchronized (graphs)
+ {
+ final Iterator iter = graphs.iterator();
+
+ while (iter.hasNext())
+ {
+ final Graph graph = iter.next();
+
+ for (Plotter plotter : graph.getPlotters())
+ {
// The key name to send to the metrics server
// The format is C-GRAPHNAME-PLOTTERNAME where separator - is defined at the top
// Legacy (R4) submitters use the format Custom%s, or CustomPLOTTERNAME
- String key = String.format("C%s%s%s%s", CUSTOM_DATA_SEPARATOR, graph.getName(), CUSTOM_DATA_SEPARATOR, plotter.getColumnName());
-
+ final String key = String.format("C%s%s%s%s", CUSTOM_DATA_SEPARATOR, graph.getName(), CUSTOM_DATA_SEPARATOR, plotter.getColumnName());
+
// The value to send, which for the foreseeable future is just the string
// value of plotter.getValue()
- String value = Integer.toString(plotter.getValue());
-
+ final String value = Integer.toString(plotter.getValue());
+
// Add it to the http post data :)
- data += encodeDataPair(key, value);
+ encodeDataPair(data, key, value);
}
}
}
-
+
// Create the url
- URL url = new URL(BASE_URL + String.format(REPORT_URL, description.getName()));
-
+ URL url = new URL(BASE_URL + String.format(REPORT_URL, encode(plugin.getDescription().getName())));
+
// Connect to the website
URLConnection connection;
-
+
// Mineshafter creates a socks proxy, so we can safely bypass it
// It does not reroute POST requests so we need to go around it
- if (isMineshafterPresent()) {
+ if (isMineshafterPresent())
+ {
connection = url.openConnection(Proxy.NO_PROXY);
- } else {
+ }
+ else
+ {
connection = url.openConnection();
}
-
+
connection.setDoOutput(true);
-
+
// Write the data
- OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
- writer.write(data);
+ final OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
+ writer.write(data.toString());
writer.flush();
-
+
// Now read the response
- BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
- String response = reader.readLine();
-
+ final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+ final String response = reader.readLine();
+
// close resources
writer.close();
reader.close();
-
- if (response.startsWith("ERR")) {
- throw new IOException(response); //Throw the exception
- } else {
+
+ if (response == null || response.startsWith("ERR"))
+ {
+ throw new IOException(response); // Throw the exception
+ }
+ else
+ {
// Is this the first update this hour?
- if (response.contains("OK This is your first update this hour")) {
- synchronized (graphs) {
- Iterator iter = graphs.iterator();
-
- while (iter.hasNext()) {
- Graph graph = iter.next();
-
- for (Plotter plotter : graph.getPlotters()) {
+ if (response.contains("OK This is your first update this hour"))
+ {
+ synchronized (graphs)
+ {
+ final Iterator iter = graphs.iterator();
+
+ while (iter.hasNext())
+ {
+ final Graph graph = iter.next();
+
+ for (Plotter plotter : graph.getPlotters())
+ {
plotter.reset();
}
}
}
}
}
- //if (response.startsWith("OK")) - We should get "OK" followed by an optional description if everything goes right
}
-
+
/**
* Check if mineshafter is present. If it is, we need to bypass it to send POST requests
- *
+ *
* @return
*/
- private boolean isMineshafterPresent() {
- try {
+ private boolean isMineshafterPresent()
+ {
+ try
+ {
Class.forName("mineshafter.MineServer");
return true;
- } catch (Exception e) {
+ }
+ catch (Exception e)
+ {
return false;
}
}
-
+
/**
- * Encode a key/value data pair to be used in a HTTP post request. This INCLUDES a & so the first
- * key/value pair MUST be included manually, e.g:
+ *
+ * Encode a key/value data pair to be used in a HTTP post request. This INCLUDES a & so the first key/value pair MUST be included manually, e.g:
+ *
*
- * String httpData = encode("guid") + '=' + encode("1234") + encodeDataPair("authors") + "..";
+ * StringBuffer data = new StringBuffer();
+ * data.append(encode("guid")).append('=').append(encode(guid));
+ * encodeDataPair(data, "version", description.getVersion());
*
- *
+ *
+ * @param buffer
* @param key
* @param value
* @return
*/
- private static String encodeDataPair(String key, String value) throws UnsupportedEncodingException {
- return '&' + encode(key) + '=' + encode(value);
+ private static void encodeDataPair(final StringBuilder buffer, final String key, final String value) throws UnsupportedEncodingException
+ {
+ buffer.append('&').append(encode(key)).append('=').append(encode(value));
}
-
+
/**
* Encode text as UTF-8
- *
+ *
* @param text
* @return
*/
- private static String encode(String text) throws UnsupportedEncodingException {
+ private static String encode(final String text) throws UnsupportedEncodingException
+ {
return URLEncoder.encode(text, "UTF-8");
}
-
+
/**
* Represents a custom graph on the website
*/
- public static class Graph {
-
+ public static class Graph
+ {
+
/**
* The graph's name, alphanumeric and spaces only :)
* If it does not comply to the above when submitted, it is rejected
*/
private final String name;
-
+
/**
* The set of plotters that are contained within this graph
*/
private final Set plotters = new LinkedHashSet();
-
- private Graph(String name) {
+
+ private Graph(final String name)
+ {
this.name = name;
}
-
+
/**
* Gets the graph's name
- *
+ *
* @return
*/
- public String getName() {
+ public String getName()
+ {
return name;
}
-
+
/**
* Add a plotter to the graph, which will be used to plot entries
- *
+ *
* @param plotter
*/
- public void addPlotter(Plotter plotter) {
+ public void addPlotter(final Plotter plotter)
+ {
plotters.add(plotter);
}
-
+
/**
* Remove a plotter from the graph
- *
+ *
* @param plotter
*/
- public void removePlotter(Plotter plotter) {
+ public void removePlotter(final Plotter plotter)
+ {
plotters.remove(plotter);
}
-
+
/**
* Gets an unmodifiable set of the plotter objects in the graph
- *
+ *
* @return
*/
- public Set getPlotters() {
+ public Set getPlotters()
+ {
return Collections.unmodifiableSet(plotters);
}
-
+
@Override
- public int hashCode() {
+ public int hashCode()
+ {
return name.hashCode();
}
-
+
@Override
- public boolean equals(Object object) {
- if (!(object instanceof Graph)) {
+ public boolean equals(final Object object)
+ {
+ if (!(object instanceof Graph))
+ {
return false;
}
-
- Graph graph = (Graph) object;
+
+ final Graph graph = (Graph) object;
return graph.name.equals(name);
}
-
+
+ /**
+ * Called when the server owner decides to opt-out of Metrics while the server is running.
+ */
+ protected void onOptOut()
+ {
+ }
+
}
-
+
/**
* Interface used to collect custom data for a plugin
*/
- public static abstract class Plotter {
-
+ public static abstract class Plotter
+ {
+
/**
* The plot's name
*/
private final String name;
-
+
/**
* Construct a plotter with the default plot name
*/
- public Plotter() {
+ public Plotter()
+ {
this("Default");
}
-
+
/**
* Construct a plotter with a specific plot name
- *
+ *
* @param name
*/
- public Plotter(String name) {
+ public Plotter(final String name)
+ {
this.name = name;
}
-
+
/**
* Get the current value for the plotted point
- *
+ *
* @return
*/
public abstract int getValue();
-
+
/**
* Get the column name for the plotted point
- *
+ *
* @return the plotted point's column name
*/
- public String getColumnName() {
+ public String getColumnName()
+ {
return name;
}
-
+
/**
* Called after the website graphs have been updated
*/
- public void reset() {
+ public void reset()
+ {
}
-
+
@Override
- public int hashCode() {
- return getColumnName().hashCode() + getValue();
+ public int hashCode()
+ {
+ return getColumnName().hashCode();
}
-
+
@Override
- public boolean equals(Object object) {
- if (!(object instanceof Plotter)) {
+ public boolean equals(final Object object)
+ {
+ if (!(object instanceof Plotter))
+ {
return false;
}
-
- Plotter plotter = (Plotter) object;
+
+ final Plotter plotter = (Plotter) object;
return plotter.name.equals(name) && plotter.getValue() == getValue();
}
+
}
+
}
\ No newline at end of file
diff --git a/src/lishid/openinv/utils/PlayerInventoryChest.java b/src/lishid/openinv/utils/OpenInvPlayerInventory.java
similarity index 59%
rename from src/lishid/openinv/utils/PlayerInventoryChest.java
rename to src/lishid/openinv/utils/OpenInvPlayerInventory.java
index 7eb1944..eaefc0d 100644
--- a/src/lishid/openinv/utils/PlayerInventoryChest.java
+++ b/src/lishid/openinv/utils/OpenInvPlayerInventory.java
@@ -16,39 +16,60 @@
package lishid.openinv.utils;
-import java.util.ArrayList;
-import java.util.List;
+import lishid.openinv.OpenInv;
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
-import org.bukkit.entity.HumanEntity;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.InventoryHolder;
+import org.bukkit.craftbukkit.entity.CraftPlayer;
-import lishid.openinv.commands.OpenInvPluginCommand;
import net.minecraft.server.EntityHuman;
-import net.minecraft.server.EntityPlayer;
-import net.minecraft.server.IInventory;
import net.minecraft.server.ItemStack;
import net.minecraft.server.PlayerInventory;
-public class PlayerInventoryChest implements IInventory
+public class OpenInvPlayerInventory extends PlayerInventory
{
- public boolean Offline = false;
- public Player Opener;
- EntityPlayer player;
- public Player Target;
- private ItemStack[] items = new ItemStack[36];
- private ItemStack[] armor = new ItemStack[4];
+ CraftPlayer owner;
+ public boolean playerOnline = false;
private ItemStack[] extra = new ItemStack[5];
- private int maxStack = MAX_STACK;
-
- public PlayerInventoryChest(PlayerInventory inventory, EntityPlayer entityplayer)
+
+ public OpenInvPlayerInventory(CraftPlayer p, boolean online)
{
- player = entityplayer;
- this.items = inventory.items;
- this.armor = inventory.armor;
+ super(p.getHandle());
+ this.owner = p;
+ this.items = player.inventory.items;
+ this.armor = player.inventory.armor;
}
-
+
+ public void onClose(CraftHumanEntity who)
+ {
+ super.onClose(who);
+ this.InventoryRemovalCheck();
+ }
+
+ public void InventoryRemovalCheck()
+ {
+ if (transaction.isEmpty() && !playerOnline)
+ {
+ owner.saveData();
+ OpenInv.inventories.remove(owner.getName().toLowerCase());
+ }
+ }
+
+ public void PlayerGoOnline(CraftPlayer p)
+ {
+ if(!playerOnline)
+ {
+ p.getHandle().inventory.items = this.items;
+ p.getHandle().inventory.armor = this.armor;
+ p.saveData();
+ playerOnline = true;
+ }
+ }
+
+ public void PlayerGoOffline()
+ {
+ playerOnline = false;
+ }
+
public ItemStack[] getContents()
{
ItemStack[] C = new ItemStack[getSize()];
@@ -56,16 +77,16 @@ public class PlayerInventoryChest implements IInventory
System.arraycopy(items, 0, C, items.length, armor.length);
return C;
}
-
+
public int getSize()
{
- return 45;
+ return super.getSize() + 5;
}
-
+
public ItemStack getItem(int i)
{
ItemStack[] is = this.items;
-
+
if (i >= is.length)
{
i -= is.length;
@@ -75,24 +96,24 @@ public class PlayerInventoryChest implements IInventory
{
i = getReversedItemSlotNum(i);
}
-
+
if (i >= is.length)
{
i -= is.length;
is = this.extra;
}
- else if(is == this.armor)
+ else if (is == this.armor)
{
i = getReversedArmorSlotNum(i);
}
-
+
return is[i];
}
-
+
public ItemStack splitStack(int i, int j)
{
ItemStack[] is = this.items;
-
+
if (i >= is.length)
{
i -= is.length;
@@ -102,21 +123,21 @@ public class PlayerInventoryChest implements IInventory
{
i = getReversedItemSlotNum(i);
}
-
+
if (i >= is.length)
{
i -= is.length;
is = this.extra;
}
- else if(is == this.armor)
+ else if (is == this.armor)
{
i = getReversedArmorSlotNum(i);
}
-
+
if (is[i] != null)
{
ItemStack itemstack;
-
+
if (is[i].count <= j)
{
itemstack = is[i];
@@ -130,7 +151,7 @@ public class PlayerInventoryChest implements IInventory
{
is[i] = null;
}
-
+
return itemstack;
}
}
@@ -139,10 +160,11 @@ public class PlayerInventoryChest implements IInventory
return null;
}
}
-
- public ItemStack splitWithoutUpdate(int i) {
+
+ public ItemStack splitWithoutUpdate(int i)
+ {
ItemStack[] is = this.items;
-
+
if (i >= is.length)
{
i -= is.length;
@@ -152,31 +174,34 @@ public class PlayerInventoryChest implements IInventory
{
i = getReversedItemSlotNum(i);
}
-
+
if (i >= is.length)
{
i -= is.length;
is = this.extra;
}
- else if(is == this.armor)
+ else if (is == this.armor)
{
i = getReversedArmorSlotNum(i);
}
- if (is[i] != null) {
+ if (is[i] != null)
+ {
ItemStack itemstack = is[i];
-
+
is[i] = null;
return itemstack;
- } else {
+ }
+ else
+ {
return null;
}
}
-
+
public void setItem(int i, ItemStack itemstack)
{
ItemStack[] is = this.items;
-
+
if (i >= is.length)
{
i -= is.length;
@@ -186,108 +211,65 @@ public class PlayerInventoryChest implements IInventory
{
i = getReversedItemSlotNum(i);
}
-
+
if (i >= is.length)
{
i -= is.length;
is = this.extra;
}
- else if(is == this.armor)
+ else if (is == this.armor)
{
i = getReversedArmorSlotNum(i);
}
/*
+ *
+ * //Effects
+ * if(is == this.extra)
+ * {
+ * if(i == 0)
+ * {
+ * itemstack.setData(0);
+ * }
+ * }
+ */
- //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;
+ 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;
+ if (i == 0)
+ return 3;
+ if (i == 1)
+ return 2;
+ if (i == 2)
+ return 1;
+ if (i == 3)
+ return 0;
+ else
+ return i;
}
-
+
public String getName()
{
- if (player.name.length() > 16) return player.name.substring(0, 16);
+ if (player.name.length() > 16)
+ {
+ return player.name.substring(0, 16);
+ }
return player.name;
}
-
- public int getMaxStackSize()
- {
- return maxStack;
- }
-
+
public boolean a(EntityHuman entityhuman)
{
return true;
}
-
- public void f()
- {
-
- }
-
- public void g()
- {
- try
- {
- PlayerInventoryChest inv = OpenInvPluginCommand.offlineInv.get(this.Target);
- if (inv != null)
- {
- this.Target.saveData();
- OpenInvPluginCommand.offlineInv.remove(this.Target);
- }
- }
- catch (Exception e)
- {}
- }
-
- public void update()
- {
-
- }
-
- public List transaction = new ArrayList();
-
- public void onOpen(CraftHumanEntity who) {
- transaction.add(who);
- }
-
- public void onClose(CraftHumanEntity who) {
- transaction.remove(who);
- }
-
- public List getViewers() {
- return transaction;
- }
-
- @Override
- public InventoryHolder getOwner() {
- return null;
- }
-
- @Override
- public void setMaxStackSize(int size) {
- maxStack = size;
- }
}
\ No newline at end of file
diff --git a/src/lishid/openinv/utils/SilentContainerChest.java b/src/lishid/openinv/utils/SilentContainerChest.java
index 6136144..8072a0f 100644
--- a/src/lishid/openinv/utils/SilentContainerChest.java
+++ b/src/lishid/openinv/utils/SilentContainerChest.java
@@ -20,17 +20,23 @@ import net.minecraft.server.ContainerChest;
import net.minecraft.server.EntityHuman;
import net.minecraft.server.IInventory;
-public class SilentContainerChest extends ContainerChest {
- public IInventory inv;
- public SilentContainerChest(IInventory i1, IInventory i2) {
- super(i1, i2);
- inv = i2;
- inv.g();//close signal
+public class SilentContainerChest extends ContainerChest
+{
+ public IInventory inv;
+
+ public SilentContainerChest(IInventory i1, IInventory i2)
+ {
+ super(i1, i2);
+ inv = i2;
+ // close signal
+ inv.g();
}
@Override
- public void a(EntityHuman paramEntityHuman) {
+ public void a(EntityHuman paramEntityHuman)
+ {
super.a(paramEntityHuman);
- inv.f();//open signal
+ // open signal
+ inv.f();
}
}
\ No newline at end of file
diff --git a/src/plugin.yml b/src/plugin.yml
index 5f1014b..3fc252d 100644
--- a/src/plugin.yml
+++ b/src/plugin.yml
@@ -1,6 +1,6 @@
name: OpenInv
main: lishid.openinv.OpenInv
-version: 1.8.4
+version: 1.8.5
author: lishid
website: http://forums.bukkit.org/threads/15379/
description: >