From 2e5444c26611e9b5c88bd10f0bc15ad89f9d12b7 Mon Sep 17 00:00:00 2001 From: Lennart <0p1q9o2w@hotmail.nl> Date: Thu, 6 Dec 2012 20:34:54 +0100 Subject: [PATCH] v1.0 dev 1 --- .gitattributes | 22 + .gitignore | 163 +++++ src/me/lenis0012/mr/MPlayer.java | 36 + src/me/lenis0012/mr/Marriage.java | 131 ++++ src/me/lenis0012/mr/Metrics.java | 632 ++++++++++++++++++ .../lenis0012/mr/commands/AcceptCommand.java | 41 ++ src/me/lenis0012/mr/commands/ChatCommand.java | 50 ++ .../lenis0012/mr/commands/DivorceCommand.java | 39 ++ src/me/lenis0012/mr/commands/GiftCommand.java | 45 ++ src/me/lenis0012/mr/commands/HomeCommand.java | 44 ++ src/me/lenis0012/mr/commands/InfoCommand.java | 34 + src/me/lenis0012/mr/commands/MarryCMD.java | 61 ++ .../lenis0012/mr/commands/MarryCommand.java | 53 ++ .../lenis0012/mr/commands/SethomeCommand.java | 60 ++ src/me/lenis0012/mr/commands/TpCommand.java | 41 ++ .../lenis0012/mr/listeners/ChatListener.java | 50 ++ src/plugin.yml | 8 + 17 files changed, 1510 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 src/me/lenis0012/mr/MPlayer.java create mode 100644 src/me/lenis0012/mr/Marriage.java create mode 100644 src/me/lenis0012/mr/Metrics.java create mode 100644 src/me/lenis0012/mr/commands/AcceptCommand.java create mode 100644 src/me/lenis0012/mr/commands/ChatCommand.java create mode 100644 src/me/lenis0012/mr/commands/DivorceCommand.java create mode 100644 src/me/lenis0012/mr/commands/GiftCommand.java create mode 100644 src/me/lenis0012/mr/commands/HomeCommand.java create mode 100644 src/me/lenis0012/mr/commands/InfoCommand.java create mode 100644 src/me/lenis0012/mr/commands/MarryCMD.java create mode 100644 src/me/lenis0012/mr/commands/MarryCommand.java create mode 100644 src/me/lenis0012/mr/commands/SethomeCommand.java create mode 100644 src/me/lenis0012/mr/commands/TpCommand.java create mode 100644 src/me/lenis0012/mr/listeners/ChatListener.java create mode 100644 src/plugin.yml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..412eeda --- /dev/null +++ b/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ebd21a --- /dev/null +++ b/.gitignore @@ -0,0 +1,163 @@ +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.vspscc +.builds +*.dotCover + +## TODO: If you have NuGet Package Restore enabled, uncomment this +#packages/ + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf + +# Visual Studio profiler +*.psess +*.vsp + +# ReSharper is a .NET coding add-in +_ReSharper* + +# Installshield output folder +[Ee]xpress + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish + +# Others +[Bb]in +[Oo]bj +sql +TestResults +*.Cache +ClientBin +stylecop.* +~$* +*.dbmdl +Generated_Code #added for RIA/Silverlight projects + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML + + + +############ +## Windows +############ + +# Windows image file caches +Thumbs.db + +# Folder config file +Desktop.ini + + +############# +## Python +############# + +*.py[co] + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg + +# Mac crap +.DS_Store diff --git a/src/me/lenis0012/mr/MPlayer.java b/src/me/lenis0012/mr/MPlayer.java new file mode 100644 index 0000000..85b9734 --- /dev/null +++ b/src/me/lenis0012/mr/MPlayer.java @@ -0,0 +1,36 @@ +package me.lenis0012.mr; + +import java.io.File; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; + +public class MPlayer +{ + private String name = null; + private FileConfiguration cfg; + private File file = null; + + public MPlayer(Player player) + { + this.name = player.getName(); + this.file = new File("plugins/Marriage/data.yml"); + this.cfg = YamlConfiguration.loadConfiguration(file); + } + + public boolean isMarried() + { + String par1Str = cfg.getString("Married." + name); + return par1Str != null && par1Str != ""; + } + + public String getPartner() + { + if(isMarried()) + { + String par1Str = cfg.getString("Married." + name); + return par1Str; + } + return ""; + } +} diff --git a/src/me/lenis0012/mr/Marriage.java b/src/me/lenis0012/mr/Marriage.java new file mode 100644 index 0000000..659e39d --- /dev/null +++ b/src/me/lenis0012/mr/Marriage.java @@ -0,0 +1,131 @@ +package me.lenis0012.mr; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; + +import me.lenis0012.mr.commands.MarryCMD; +import me.lenis0012.mr.listeners.ChatListener; + +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + +public class Marriage extends JavaPlugin +{ + private List partners = new ArrayList(); + private FileConfiguration customConfig = null; + private File customConfigFile = null; + public List chat = new ArrayList(); + + @Override + public void onEnable() + { + FileConfiguration config = this.getConfig(); + PluginManager pm = this.getServer().getPluginManager(); + + pm.registerEvents(new ChatListener(this), this); + getCommand("marry").setExecutor(new MarryCMD(this)); + + config.addDefault("settings.private-chat.format", "&a[Partner] &7{Player}&f: &a{Message}"); + config.options().copyDefaults(true); + this.saveConfig(); + + FileConfiguration cfg = this.getCustomConfig(); + cfg.addDefault("partners", partners); + cfg.options().copyDefaults(true); + this.saveCustomConfig(); + + try + { + Metrics metrics = new Metrics(this); + metrics.start(); + } catch(Exception e) + { + this.getLogger().info("[Marriage] Failed sending stats to mcstats.org"); + } + } + + public Player getPlayer(String name) + { + for(Player player : this.getServer().getOnlinePlayers()) + { + if(player.getName().toLowerCase().startsWith(name)) + { + return player; + } + } + + for(Player player : this.getServer().getOnlinePlayers()) + { + if(player.getName().toLowerCase().contains(name)) + { + return player; + } + } + + return null; + } + + public void reloadCustomConfig() + { + if (customConfigFile == null) + { + customConfigFile = new File(getDataFolder(), "data.yml"); + } + customConfig = YamlConfiguration.loadConfiguration(customConfigFile); + java.io.InputStream defConfigStream = this.getResource("data.yml"); + if (defConfigStream != null) { + YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream); + customConfig.setDefaults(defConfig); + } + } + + public FileConfiguration getCustomConfig() + { + if (customConfig == null) + { + this.reloadCustomConfig(); + } + return customConfig; + } + + public void saveCustomConfig() + { + if (customConfig == null || customConfigFile == null) + { + return; + } + try { + getCustomConfig().save(customConfigFile); + } catch (IOException ex) { + this.getLogger().log(Level.SEVERE, "Could not save config to " + customConfigFile, ex);} + } + + public String fixColors(String message) + { + message = message.replaceAll("&0", ChatColor.BLACK.toString()); + message = message.replaceAll("&1", ChatColor.DARK_BLUE.toString()); + message = message.replaceAll("&2", ChatColor.DARK_GREEN.toString()); + message = message.replaceAll("&3", ChatColor.DARK_AQUA.toString()); + message = message.replaceAll("&4", ChatColor.DARK_RED.toString()); + message = message.replaceAll("&5", ChatColor.DARK_PURPLE.toString()); + message = message.replaceAll("&6", ChatColor.GOLD.toString()); + message = message.replaceAll("&7", ChatColor.GRAY.toString()); + message = message.replaceAll("&8", ChatColor.DARK_GRAY.toString()); + message = message.replaceAll("&9", ChatColor.BLUE.toString()); + message = message.replaceAll("&a", ChatColor.GREEN.toString()); + message = message.replaceAll("&b", ChatColor.AQUA.toString()); + message = message.replaceAll("&c", ChatColor.RED.toString()); + message = message.replaceAll("&d", ChatColor.LIGHT_PURPLE.toString()); + message = message.replaceAll("&e", ChatColor.YELLOW.toString()); + message = message.replaceAll("&f", ChatColor.WHITE.toString()); + message = message.replaceAll("&r", ChatColor.WHITE.toString()); + return message; + } +} diff --git a/src/me/lenis0012/mr/Metrics.java b/src/me/lenis0012/mr/Metrics.java new file mode 100644 index 0000000..1d56a1b --- /dev/null +++ b/src/me/lenis0012/mr/Metrics.java @@ -0,0 +1,632 @@ +/* +* Copyright 2011 Tyler Blair. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are +* permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this list of +* conditions and the following disclaimer. +* +* 2. 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. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''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 AUTHOR 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 views and conclusions contained in the software and documentation are those of the +* authors and contributors and should not be interpreted as representing official policies, +* either expressed or implied, of anybody else. +*/ + +package me.lenis0012.mr; + +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; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.net.Proxy; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.UUID; +import java.util.logging.Level; + +/** +*

+* The metrics class obtains data about a plugin and submits statistics about it to the metrics backend. +*

+*

+* Public methods provided by this class: +*

+* +* Graph createGraph(String name);
+* void addCustomData(Metrics.Plotter plotter);
+* void start();
+*
+*/ +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://mcstats.org"; + + /** +* The url used to report a server's status +*/ + private static final String REPORT_URL = "/report/%s"; + + /** +* 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 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; + + /** +* 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 + configurationFile = getConfigFile(); + 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://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 The name of the graph +* @return Graph object created. Will never return NULL under normal circumstances unless bad parameters are given +*/ + public Graph createGraph(final String name) { + if (name == null) { + throw new IllegalArgumentException("Graph name cannot be null"); + } + + // Construct the graph object + 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 The name of the 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 The plotter to use to plot custom data +*/ + 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 boolean start() { + synchronized (optOutLock) { + // Did we opt out? + if (isOptOut()) { + return false; + } + + // 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 true if metrics should be opted out of it +*/ + public boolean isOptOut() { + synchronized(optOutLock) { + try { + // Reload the metrics file + configuration.load(getConfigFile()); + } 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; + } + } + } + + /** +* Gets the File object of the config file that should be used to store data such as the GUID and opt-out status +* +* @return the File object for the config file +*/ + public File getConfigFile() { + // I believe the easiest way to get the base folder (e.g craftbukkit set via -P) for plugins to use + // is to abuse the plugin object we already have + // plugin.getDataFolder() => base/plugins/PluginA/ + // pluginsFolder => base/plugins/ + // The base is not necessarily relative to the startup directory. + File pluginsFolder = plugin.getDataFolder().getParentFile(); + + // return => base/plugins/PluginMetrics/config.yml + return new File(new File(pluginsFolder, "PluginMetrics"), "config.yml"); + } + + /** +* Generic method that posts a plugin to the metrics website +*/ + 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 + final PluginDescriptionFile description = plugin.getDescription(); + + // Construct the post data + 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) { + 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) { + 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 + 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() + final String value = Integer.toString(plotter.getValue()); + + // Add it to the http post data :) + encodeDataPair(data, key, value); + } + } + } + + // Create the url + 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()) { + connection = url.openConnection(Proxy.NO_PROXY); + } else { + connection = url.openConnection(); + } + + connection.setDoOutput(true); + + // Write the data + final OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); + writer.write(data.toString()); + writer.flush(); + + // Now read the response + final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + final String response = reader.readLine(); + + // close resources + writer.close(); + reader.close(); + + 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) { + final Iterator iter = graphs.iterator(); + + while (iter.hasNext()) { + final Graph graph = iter.next(); + + for (Plotter plotter : graph.getPlotters()) { + plotter.reset(); + } + } + } + } + } + } + + /** +* Check if mineshafter is present. If it is, we need to bypass it to send POST requests +* +* @return true if mineshafter is installed on the server +*/ + private boolean isMineshafterPresent() { + try { + Class.forName("mineshafter.MineServer"); + return true; + } 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:

+* +* StringBuffer data = new StringBuffer(); +* data.append(encode("guid")).append('=').append(encode(guid)); +* encodeDataPair(data, "version", description.getVersion()); +* +* +* @param buffer the stringbuilder to append the data pair onto +* @param key the key value +* @param value the 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 the text to encode +* @return the encoded text, as UTF-8 +*/ + 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 { + + /** +* 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(final String name) { + this.name = name; + } + + /** +* Gets the graph's name +* +* @return the Graph's name +*/ + public String getName() { + return name; + } + + /** +* Add a plotter to the graph, which will be used to plot entries +* +* @param plotter the plotter to add to the graph +*/ + public void addPlotter(final Plotter plotter) { + plotters.add(plotter); + } + + /** +* Remove a plotter from the graph +* +* @param plotter the plotter to remove from the graph +*/ + public void removePlotter(final Plotter plotter) { + plotters.remove(plotter); + } + + /** +* Gets an unmodifiable set of the plotter objects in the graph +* +* @return an unmodifiable {@link Set} of the plotter objects +*/ + public Set getPlotters() { + return Collections.unmodifiableSet(plotters); + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(final Object object) { + if (!(object instanceof Graph)) { + return false; + } + + 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 { + + /** +* The plot's name +*/ + private final String name; + + /** +* Construct a plotter with the default plot name +*/ + public Plotter() { + this("Default"); + } + + /** +* Construct a plotter with a specific plot name +* +* @param name the name of the plotter to use, which will show up on the website +*/ + public Plotter(final String name) { + this.name = name; + } + + /** +* Get the current value for the plotted point. Since this function defers to an external function +* it may or may not return immediately thus cannot be guaranteed to be thread friendly or safe. +* This function can be called from any thread so care should be taken when accessing resources +* that need to be synchronized. +* +* @return the current value for the point to be plotted. +*/ + public abstract int getValue(); + + /** +* Get the column name for the plotted point +* +* @return the plotted point's column name +*/ + public String getColumnName() { + return name; + } + + /** +* Called after the website graphs have been updated +*/ + public void reset() { + } + + @Override + public int hashCode() { + return getColumnName().hashCode(); + } + + @Override + public boolean equals(final Object object) { + if (!(object instanceof Plotter)) { + return false; + } + + final Plotter plotter = (Plotter) object; + return plotter.name.equals(name) && plotter.getValue() == getValue(); + } + + } + +} diff --git a/src/me/lenis0012/mr/commands/AcceptCommand.java b/src/me/lenis0012/mr/commands/AcceptCommand.java new file mode 100644 index 0000000..0d3d508 --- /dev/null +++ b/src/me/lenis0012/mr/commands/AcceptCommand.java @@ -0,0 +1,41 @@ +package me.lenis0012.mr.commands; + +import java.util.List; +import me.lenis0012.mr.Marriage; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; + +public class AcceptCommand +{ + public static void Accept(Player player, Marriage plugin) + { + FileConfiguration cfg = plugin.getCustomConfig(); + + if(MarryCommand.req.containsKey(player.getName())) + { + Player op = plugin.getPlayer(MarryCommand.req.get(player.getName())); + if(op != null) + { + if(op.isOnline()) + { + String user = op.getName(); + String name = player.getName(); + Bukkit.getServer().broadcastMessage(ChatColor.GREEN + user + " has married with " + name); + cfg.set("Married." + name, user); + cfg.set("Married." + user, name); + List list = cfg.getStringList("partners"); + list.add(user); + cfg.set("partners", list); + plugin.saveCustomConfig(); + MarryCommand.req.remove(name); + return; + } + player.sendMessage(ChatColor.RED + "Player that requested you is not online"); + return; + } + } + player.sendMessage(ChatColor.RED + "You dont got a request!"); + } +} diff --git a/src/me/lenis0012/mr/commands/ChatCommand.java b/src/me/lenis0012/mr/commands/ChatCommand.java new file mode 100644 index 0000000..1f79ead --- /dev/null +++ b/src/me/lenis0012/mr/commands/ChatCommand.java @@ -0,0 +1,50 @@ +package me.lenis0012.mr.commands; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import me.lenis0012.mr.MPlayer; +import me.lenis0012.mr.Marriage; + +public class ChatCommand +{ + public static void perform(Player player, Marriage plugin) + { + MPlayer mp = new MPlayer(player); + if(!mp.isMarried()) + { + player.sendMessage(ChatColor.RED + "You dont have a partner."); + return; + } + Player op = Bukkit.getServer().getPlayer(mp.getPartner()); + if(op == null) + { + player.sendMessage(ChatColor.RED + "Your partner is not online"); + return; + } + if(!op.isOnline()) + { + player.sendMessage(ChatColor.RED + "Your partner is not online"); + return; + } + if(!player.hasPermission("marry.chat") && !player.hasPermission("marry.*")) + { + player.sendMessage(ChatColor.RED + "No permission."); + return; + } + + String user = player.getName(); + + if(plugin.chat.contains(user)) + { + plugin.chat.remove(user); + player.sendMessage(ChatColor.RED+"Left partner chat"); + } + else + { + plugin.chat.add(user); + player.sendMessage(ChatColor.GREEN+"Joined partner chat"); + } + } +} diff --git a/src/me/lenis0012/mr/commands/DivorceCommand.java b/src/me/lenis0012/mr/commands/DivorceCommand.java new file mode 100644 index 0000000..aafa009 --- /dev/null +++ b/src/me/lenis0012/mr/commands/DivorceCommand.java @@ -0,0 +1,39 @@ +package me.lenis0012.mr.commands; + +import java.util.List; + +import me.lenis0012.mr.MPlayer; +import me.lenis0012.mr.Marriage; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +public class DivorceCommand +{ + public static void perfrom(Player player, Marriage plugin) + { + MPlayer mp = new MPlayer(player); + if(!mp.isMarried()) + { + player.sendMessage(ChatColor.RED+"You are not married"); + return; + } + + String user = player.getName(); + String partner = mp.getPartner(); + + plugin.getCustomConfig().set("Married."+user, null); + plugin.getCustomConfig().set("Married."+partner, null); + plugin.getCustomConfig().set("home."+user, null); + plugin.getCustomConfig().set("home."+partner, null); + List list = plugin.getCustomConfig().getStringList("partners"); + if(list.contains(user)) + list.remove(user); + if(list.contains(partner)) + list.remove(partner); + plugin.getCustomConfig().set("partners", list); + plugin.saveCustomConfig(); + Bukkit.getServer().broadcastMessage(ChatColor.RED+user+" divorced with "+partner); + } +} diff --git a/src/me/lenis0012/mr/commands/GiftCommand.java b/src/me/lenis0012/mr/commands/GiftCommand.java new file mode 100644 index 0000000..3cc91f9 --- /dev/null +++ b/src/me/lenis0012/mr/commands/GiftCommand.java @@ -0,0 +1,45 @@ +package me.lenis0012.mr.commands; + +import me.lenis0012.mr.MPlayer; +import me.lenis0012.mr.Marriage; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class GiftCommand +{ + public static void perfom(Player player, Marriage plugin) + { + MPlayer mp = new MPlayer(player); + if(!mp.isMarried()) + { + player.sendMessage(ChatColor.RED + "You dont have a partner."); + return; + } + Player op = Bukkit.getServer().getPlayer(mp.getPartner()); + if(op == null) + { + player.sendMessage(ChatColor.RED + "Your partner is not online"); + return; + } + if(!op.isOnline()) + { + player.sendMessage(ChatColor.RED + "Your partner is not online"); + return; + } + if(!player.hasPermission("marry.gift") && !player.hasPermission("marry.*")) + { + player.sendMessage(ChatColor.RED + "No permission."); + return; + } + + player.sendMessage(ChatColor.GREEN + "Gift sended"); + ItemStack it = player.getItemInHand(); + String item = it.getType().toString().toLowerCase(); + op.sendMessage(ChatColor.GREEN + "You got a '"+item+"' from your partner"); + op.getInventory().addItem(it); + player.setItemInHand(null); + } +} diff --git a/src/me/lenis0012/mr/commands/HomeCommand.java b/src/me/lenis0012/mr/commands/HomeCommand.java new file mode 100644 index 0000000..bcb326a --- /dev/null +++ b/src/me/lenis0012/mr/commands/HomeCommand.java @@ -0,0 +1,44 @@ +package me.lenis0012.mr.commands; + +import me.lenis0012.mr.MPlayer; +import me.lenis0012.mr.Marriage; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; + +public class HomeCommand +{ + public static void perform(Player player, Marriage plugin) + { + MPlayer mp = new MPlayer(player); + if(!mp.isMarried()) + { + player.sendMessage(ChatColor.RED + "You dont have a partner."); + return; + } + String user = player.getName(); + if(!player.hasPermission("marry.home") && !player.hasPermission("marry.*")) + { + player.sendMessage(ChatColor.RED + "No permission."); + return; + } + if(plugin.getCustomConfig().getString("home."+user+".world") == null) + { + player.sendMessage(ChatColor.RED + "Home not set"); + return; + } + + World world = Bukkit.getServer().getWorld(plugin.getCustomConfig().getString("home."+user+".world")); + int x = plugin.getCustomConfig().getInt("home."+user+".x"); + int y = plugin.getCustomConfig().getInt("home."+user+".y"); + int z = plugin.getCustomConfig().getInt("home."+user+".z"); + float yaw = Float.valueOf(plugin.getCustomConfig().getString("home."+user+".yaw")); + float pitch = Float.valueOf(plugin.getCustomConfig().getString("home."+user+".pitch")); + Location home = new Location(world, x, y, z, yaw, pitch); + player.teleport(home); + player.sendMessage(ChatColor.GREEN+"Teleporing to home..."); + } +} diff --git a/src/me/lenis0012/mr/commands/InfoCommand.java b/src/me/lenis0012/mr/commands/InfoCommand.java new file mode 100644 index 0000000..9ba46f8 --- /dev/null +++ b/src/me/lenis0012/mr/commands/InfoCommand.java @@ -0,0 +1,34 @@ +package me.lenis0012.mr.commands; + +import me.lenis0012.mr.MPlayer; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +public class InfoCommand +{ + public static void showInfo(Player player) + { + ChatColor g = ChatColor.GRAY; + ChatColor l = ChatColor.GREEN; + ChatColor r = ChatColor.RED; + player.sendMessage(g +"==========-{"+l+" Marriage "+g+"}-=========="); + player.sendMessage(l+"/marry "+g+"- Marry a player"); + player.sendMessage(l+"/marry accept "+g+"- Accept a marriage request"); + player.sendMessage(l+"/marry divorce "+g+"- Divorce your partner"); + player.sendMessage(l+"/marry tp "+g+"- Teleport to your partner"); + player.sendMessage(l+"/marry gift "+g+"- Gift your partner the item in your hand"); + player.sendMessage(l+"/marry chat "+g+"- Private chat with your partner"); + player.sendMessage(l+"/marry sethome "+g+"- Set your marriage home"); + player.sendMessage(l+"/marry home "+g+"- Go to your marriage home"); + + MPlayer mp = new MPlayer(player); + if(mp.isMarried()) + { + player.sendMessage(g+"Married: "+l+mp.getPartner()); + }else + { + player.sendMessage(g+"Married: "+r+"No"); + } + } +} diff --git a/src/me/lenis0012/mr/commands/MarryCMD.java b/src/me/lenis0012/mr/commands/MarryCMD.java new file mode 100644 index 0000000..1611a6e --- /dev/null +++ b/src/me/lenis0012/mr/commands/MarryCMD.java @@ -0,0 +1,61 @@ +package me.lenis0012.mr.commands; + +import java.util.logging.Logger; + +import me.lenis0012.mr.Marriage; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class MarryCMD implements CommandExecutor +{ + private Marriage plugin; + public MarryCMD(Marriage i) { plugin = i; } + + @Override + public boolean onCommand(CommandSender sender, Command cmnd, String label, String[] args) + { + Logger log = plugin.getLogger(); + + Player player = null; + if(sender instanceof Player) + { + player = (Player)sender; + }else + { + log.info("Command only availeble as player."); + } + + if(args.length == 0) + InfoCommand.showInfo(player); + + else if(args[0].equalsIgnoreCase("accept")) + AcceptCommand.Accept(player, plugin); + + else if(args[0].equalsIgnoreCase("tp")) + TpCommand.perfrom(player, plugin); + + else if(args[0].equalsIgnoreCase("gift")) + GiftCommand.perfom(player, plugin); + + else if(args[0].equalsIgnoreCase("divorce")) + DivorceCommand.perfrom(player, plugin); + + else if(args[0].equalsIgnoreCase("chat")) + ChatCommand.perform(player, plugin); + + else if(args[0].equalsIgnoreCase("home")) + HomeCommand.perform(player, plugin); + + else if(args[0].equalsIgnoreCase("sethome")) + SethomeCommand.perform(player, plugin); + + else if(args.length == 1) + MarryCommand.request(player, args, plugin); + + return true; + } + +} diff --git a/src/me/lenis0012/mr/commands/MarryCommand.java b/src/me/lenis0012/mr/commands/MarryCommand.java new file mode 100644 index 0000000..c25752e --- /dev/null +++ b/src/me/lenis0012/mr/commands/MarryCommand.java @@ -0,0 +1,53 @@ +package me.lenis0012.mr.commands; + +import java.util.WeakHashMap; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import me.lenis0012.mr.MPlayer; +import me.lenis0012.mr.Marriage; + +public class MarryCommand +{ + public static WeakHashMap req = new WeakHashMap(); + + public static void request(Player player, String[] args, Marriage plugin) + { + Player op = plugin.getPlayer(args[0]); + if(op != null) + { + if(op.isOnline()) + { + MPlayer mp = new MPlayer(op); + MPlayer tp = new MPlayer(player); + if(!player.hasPermission("marry.marry") && !player.hasPermission("marry.*")) + { + player.sendMessage(ChatColor.RED + "No permission."); + return; + } + if(args[0].equals(player.getName())) + { + player.sendMessage(ChatColor.RED + "You may not marry yourself!"); + return; + } + if(mp.isMarried()) + { + player.sendMessage(ChatColor.RED + "You are already married."); + return; + } + if(tp.isMarried()) + { + player.sendMessage(ChatColor.RED + op.getName() + " is already married."); + return; + } + + player.sendMessage(ChatColor.GREEN + "Request sended."); + op.sendMessage(ChatColor.GREEN + player.getName() + " would like to marry with you."); + op.sendMessage(ChatColor.GREEN + "Type " + ChatColor.LIGHT_PURPLE + "/marry accept " + + ChatColor.GREEN + "to accept"); + req.put(op.getName(), player.getName()); + return; + } + } + player.sendMessage(ChatColor.RED+"Invalid player"); + } +} diff --git a/src/me/lenis0012/mr/commands/SethomeCommand.java b/src/me/lenis0012/mr/commands/SethomeCommand.java new file mode 100644 index 0000000..ece6616 --- /dev/null +++ b/src/me/lenis0012/mr/commands/SethomeCommand.java @@ -0,0 +1,60 @@ +package me.lenis0012.mr.commands; + +import me.lenis0012.mr.MPlayer; +import me.lenis0012.mr.Marriage; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +public class SethomeCommand +{ + public static void perform(Player player, Marriage plugin) + { + MPlayer mp = new MPlayer(player); + if(!mp.isMarried()) + { + player.sendMessage(ChatColor.RED + "You dont have a partner."); + return; + } + String user = player.getName(); + String partner = mp.getPartner(); + if(!player.hasPermission("marry.sethome") && !player.hasPermission("marry.*")) + { + player.sendMessage(ChatColor.RED + "No permission."); + return; + } + + Location loc = player.getLocation(); + int x = loc.getBlockX(); + int y = loc.getBlockY(); + int z = loc.getBlockZ(); + String yaw = String.valueOf(loc.getYaw()); + String pitch = String.valueOf(loc.getPitch()); + String world = loc.getWorld().getName(); + plugin.getCustomConfig().set("home."+user+".world", world); + plugin.getCustomConfig().set("home."+user+".x", x); + plugin.getCustomConfig().set("home."+user+".y", y); + plugin.getCustomConfig().set("home."+user+".z", z); + plugin.getCustomConfig().set("home."+user+".yaw", yaw); + plugin.getCustomConfig().set("home."+user+".pitch", pitch); + plugin.getCustomConfig().set("home."+partner+".world", world); + plugin.getCustomConfig().set("home."+partner+".x", x); + plugin.getCustomConfig().set("home."+partner+".y", y); + plugin.getCustomConfig().set("home."+partner+".z", z); + plugin.getCustomConfig().set("home."+partner+".yaw", yaw); + plugin.getCustomConfig().set("home."+partner+".pitch", pitch); + plugin.saveCustomConfig(); + + player.sendMessage(ChatColor.GREEN+"Home set"); + Player op = Bukkit.getPlayer(partner); + if(op != null) + { + if(op.isOnline()) + { + op.sendMessage(ChatColor.GREEN+"Your partner has set your home"); + } + } + } +} diff --git a/src/me/lenis0012/mr/commands/TpCommand.java b/src/me/lenis0012/mr/commands/TpCommand.java new file mode 100644 index 0000000..7b384f2 --- /dev/null +++ b/src/me/lenis0012/mr/commands/TpCommand.java @@ -0,0 +1,41 @@ +package me.lenis0012.mr.commands; + +import me.lenis0012.mr.MPlayer; +import me.lenis0012.mr.Marriage; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +public class TpCommand +{ + public static void perfrom(Player player, Marriage plugin) + { + MPlayer mp = new MPlayer(player); + if(!mp.isMarried()) + { + player.sendMessage(ChatColor.RED + "You dont have a partner."); + return; + } + Player op = Bukkit.getServer().getPlayer(mp.getPartner()); + if(op == null) + { + player.sendMessage(ChatColor.RED + "Your partner is not online"); + return; + } + if(!op.isOnline()) + { + player.sendMessage(ChatColor.RED + "Your partner is not online"); + return; + } + if(!player.hasPermission("marry.tp") && !player.hasPermission("marry.*")) + { + player.sendMessage(ChatColor.RED + "No permission."); + return; + } + + player.sendMessage(ChatColor.GREEN + "Teleporting..."); + op.sendMessage(ChatColor.GREEN + "Partner teleporting to you..."); + player.teleport(op.getLocation()); + } +} diff --git a/src/me/lenis0012/mr/listeners/ChatListener.java b/src/me/lenis0012/mr/listeners/ChatListener.java new file mode 100644 index 0000000..b317b3d --- /dev/null +++ b/src/me/lenis0012/mr/listeners/ChatListener.java @@ -0,0 +1,50 @@ +package me.lenis0012.mr.listeners; + +import me.lenis0012.mr.MPlayer; +import me.lenis0012.mr.Marriage; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +public class ChatListener implements Listener +{ + private Marriage plugin; + public ChatListener(Marriage i) { plugin = i; } + + @EventHandler (priority = EventPriority.LOWEST) + public void onPlayerChat(AsyncPlayerChatEvent event) + { + Player player = event.getPlayer(); + String pname = player.getName(); + MPlayer mp = new MPlayer(player); + + if(plugin.chat.contains(pname)) + { + Player partner = Bukkit.getServer().getPlayer(mp.getPartner()); + if(partner == null) + { + plugin.chat.remove(pname); + return; + } + if(!partner.isOnline()) + { + plugin.chat.remove(pname); + return; + } + + String message = event.getMessage(); + String format = plugin.getConfig().getString("settings.private-chat.format"); + format = format.replace("{Player}", pname); + format = format.replace("{Message}", message); + format = plugin.fixColors(format); + partner.sendMessage(format); + player.sendMessage(format); + plugin.getLogger().info("[Marriage] Chat: "+pname+": "+message); + event.setCancelled(true); + } + } +} diff --git a/src/plugin.yml b/src/plugin.yml new file mode 100644 index 0000000..51dd0f8 --- /dev/null +++ b/src/plugin.yml @@ -0,0 +1,8 @@ +name: Marriage +version: 1.0-DEV.1 +main: me.lenis0012.mr.Marriage +dev-url: http://dev.bukkit.org/server-mods/marriage-reloaded/ +commands: + marry: + description: Marriage main command. + usage: /marry \ No newline at end of file