Commits

Jenkins Builder  committed 600cdb5

Initial commit of godPowers 3.0

  • Participants

Comments (0)

Files changed (67)

File .DS_Store

Binary file added.

File godPowers/.DS_Store

Binary file added.

File godPowers/.classpath

+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="lib" path="/Volumes/JK&apos;S HDD 4/bukkit/bukkit api/bukkit-1.5.2-R0.1.jar"/>
+	<classpathentry kind="lib" path="/Volumes/JK&apos;S HDD 4/bukkit/server/craftbukkit-1.5.2-R0.1.jar"/>
+	<classpathentry kind="lib" path="/Volumes/JK&apos;S HDD 4/bukkit/bukkit api/Permissions.jar"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

File godPowers/.project

+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>godPowers</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

File godPowers/.settings/org.eclipse.jdt.core.prefs

+#Sun Jan 09 13:44:50 EST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6

File godPowers/bin/com/FriedTaco/taco/godPowers/BlessCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/DemiGodCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/DieCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/DupeCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/FusRoDAH.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/GaiaCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/GodPowersCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/HadesCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/HealCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/InfernoCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/Jesus$Raft.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/Jesus$RaftPiece.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/Jesus.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/JesusCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/MaimCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/Metrics$1.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/Metrics$Graph.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/Metrics$Plotter.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/Metrics.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/PlutusCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/PropertiesFile.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/SlayCommand$1.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/SlayCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/SuperJumpCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/Updater$UpdateResult.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/Updater$UpdateRunnable.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/Updater$UpdateType.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/Updater.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/VulcanCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/ZeusCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/godModeCommand.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/godPowers.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/godPowersEntityListener.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/godPowersPlayerListener$1.class

Binary file added.

File godPowers/bin/com/FriedTaco/taco/godPowers/godPowersPlayerListener.class

Binary file added.

File godPowers/config.yml

+

File godPowers/plugin.yml

+name: godPowers
+main: com.FriedTaco.taco.godPowers.godPowers
+version: 2.9
+author: Swift
+commands:
+    godmode:
+        description: Become invincible!
+        usage: /godMode
+    jesus:
+        description: You feel like you can walk on water.... Maybe even lava!
+        usage: /jesus
+    heal:
+        description: Heals you. Duh.
+        usage: /heal
+    die:
+        description: I wonder what this does! :o
+        usage: /die
+    slay:
+        description: Slay your enemies with just the press of a few keys!
+        usage: /slay
+    maim:
+        description: Beat those disobediant players within an inch of their lives!
+        usage: /maim
+    inferno:
+        description: Burn the ground behind you with the power of your fiery rage!
+        usage: /inferno
+    superjump:
+        description: Gain the ability to leap tall buildings in a single bound!
+        usage: /superjump
+    godmodeon:
+        description: Enable godmode (Temporary fix for conflict with Essentials).
+        usage: /godmodeon
+    godmodeoff:
+        description: Disable godmode (Temporary fix for conflict with Essentials).
+        usage: /godmodeoff
+    zeus:
+        description: Strike lightning were you're looking.
+        usage: /zeus
+    gaia:
+        description: Beautify the earth with every step you take.
+        usage: /gaia
+    godpowers:
+        description: Displays avaliable commands.
+        usage: /godpowers
+    vulcan:
+        description: Goodness gracious, great balls of fire!
+        usage: /vulcan
+    myballsareonfire:
+        description: See vulcan.
+        usage: /myballsareonfire
+    demigod:
+        description: Reduces damage by an adjustable rate.
+        usage: /demigod
+    hades:
+        description: Corrupts the world beneath your feet.
+        usage: /hades
+    bless:
+        description: Enchants all items in inv.
+        usage: /bless
+    fusrodah:
+        description: Puts knockback lvl 10 on held item.
+        usage: /fusrodah
+    plutus:
+        description: Puts wealth lvl 10 on held item.
+        usage: /plutus
+    dupe:
+        description: Duplicates the item in your hand
+        usage: /dupe <amount>
+permissions:
+    godpowers.*:
+        description: Gives access to all godpowers commands.
+        children:
+            godpowers.godmodeonlogin: true
+            godpowers.godmode: true
+            godpowers.jesus: true
+            godpowers.demigod: true
+            godpowers.die: true
+            godpowers.gaia: true
+            godpowers.hades: true
+            godpowers.heal: true
+            godpowers.inferno: true
+            godpowers.maim: true
+            godpowers.slay: true
+            godpowers.superjump: true
+            godpowers.vulcan: true
+            godpowers.zeus: true
+            godpowers.godtools: true
+            godpowers.bless: true
+            godpowers.fusrodah: true
+    godpowers.godmodeonlogin:
+        description: Allows godmode upon login.
+        default: op
+    godpowers.godmode:
+        description: Gives permission to relevant command.
+        default: op
+    godpowers.jesus:
+        description: Gives permission to relevant command.
+        default: op
+    godpowers.demigod:
+        description: Gives permission to relevant command.
+        default: op
+    godpowers.die:
+        description: Gives permission to relevant command.
+        default: op
+    godpowers.gaia:
+        description: Gives permission to relevant command.
+        default: op
+    godpowers.hades:
+        description: Gives permission to relevant command.
+        default: op
+    godpowers.heal:
+        description: Gives permission to relevant command.
+        default: op
+    godpowers.inferno:
+        description: Gives permission to relevant command.
+        default: op
+    godpowers.maim:
+        description: Gives permission to relevant command.
+        default: op
+    godpowers.slay:
+        description: Gives permission to relevant command.
+        default: op
+    godpowers.superjump:
+        description: Gives permission to relevant command.
+        default: op
+    godpowers.vulcan:
+        description: Gives permission to relevant command.
+        default: op
+    godpowers.zeus:
+        description: Gives permission to relevant command.
+        default: op
+    godpowers.godtools:
+        description: Gives permission to godtools.
+        default: op
+    godpowers.bless:
+        description: Gives permission to relevant command.
+        default: op
+    godpowers.fusrodah:
+        description: Gives permission to relevant command.
+        default: op
+    godpowers.dupe:
+        description: Gives permission to relevant command.
+        default: op
+    
+       

File godPowers/src/com/FriedTaco/taco/godPowers/BlessCommand.java

+package com.FriedTaco.taco.godPowers;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class BlessCommand implements CommandExecutor
+{
+	private Player player;
+	private final godPowers plugin;
+    public BlessCommand(godPowers instance) 
+    {
+        plugin = instance;
+    }
+
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
+    {
+    	String[] split = args;
+    	if(sender instanceof Player)
+    	{
+    		player = (Player) sender;
+    		if(player.hasPermission("godpowers.bless"))
+    		{
+    			if(split.length == 1)
+    			{
+    				Player player2 = plugin.getServer().getPlayer(split[0]);
+    				if(player2 != null){
+    					player.sendMessage(ChatColor.BLUE + "The gods have blessed the equipment of "+player2.getDisplayName());
+    					player2.sendMessage(ChatColor.BLUE + "The gods have blessed your equipment with their holy might!");
+        				plugin.bless(player2);	
+    				}else{
+    					player.sendMessage(ChatColor.BLUE + "This player cannot be blessed/is offline.");	
+    				}
+    				return true;
+    			}else 
+                if(split.length == 0)
+    			{
+    				player.sendMessage(ChatColor.BLUE + "The gods have blessed your equipment with their holy might!");
+    				plugin.bless(player);
+    				return true;
+    			}
+    			else
+    			{
+    				player.sendMessage(ChatColor.RED + "Incorrect syntax. Correct usage: '/bless or /bless <player>'");
+    				return true;
+    			}
+    		}
+    		else
+    		{
+    			player.sendMessage(ChatColor.DARK_RED + "The gods prevent you from using this command.");
+    		}
+    	}
+		return false;
+    }
+}

File godPowers/src/com/FriedTaco/taco/godPowers/DemiGodCommand.java

+package com.FriedTaco.taco.godPowers;
+
+//import org.bukkit.World;
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class DemiGodCommand implements CommandExecutor
+{
+	private Player player;
+	private final godPowers plugin;
+    public DemiGodCommand(godPowers instance) 
+    {
+        plugin = instance;
+    }
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
+    {
+    	String[] split = args;
+    	if(sender instanceof Player)
+    	{
+    		player = (Player) sender;
+    		if(player.hasPermission("godpowers.demigod"))
+    		{
+	    		if(split.length == 0)
+	    		{
+	    			if(plugin.DemiGod.contains(player.getName()))
+	    			{
+	    				plugin.DemiGod.remove(player.getName());
+	    				player.sendMessage(ChatColor.BLUE + "You have returned to being mortal.");
+	    				return true;
+	    			}
+	    			else
+	    			{
+	    				player.sendMessage(ChatColor.BLUE + "The gods have shared their might with you.");
+	    				player.sendMessage(ChatColor.BLUE + "You now feel as if fatal wounds are like mere scratches to you!");
+	    				plugin.DemiGod.add(player.getName());
+	    				player.setHealth(20);
+	    				return true;
+	        		}
+	    		}
+	    		else
+	    		{
+	    			Player targetPlayer = plugin.getServer().getPlayer(split[0]);
+	    			if(targetPlayer==null) 
+					{
+						player.sendMessage(ChatColor.RED + "The user "+split[0]+" does not exist or is not currently logged in.");
+					}
+	    			else if(targetPlayer == player)
+					{
+						player.sendMessage(ChatColor.RED + "Please use '/demigod' to make yourself a demigod.");
+	
+					}
+					else
+					{
+						if(plugin.DemiGod.contains(targetPlayer.getName()))
+	        			{
+	        				plugin.DemiGod.remove(targetPlayer.getName());
+	        				targetPlayer.sendMessage(ChatColor.BLUE + player.getName() + " has returned you to being mortal.");
+	        				player.sendMessage(ChatColor.BLUE + targetPlayer.getName() + " has been returned to being mortal.");
+	        			}
+	        			else
+	            		{
+	        				targetPlayer.sendMessage(ChatColor.BLUE + player.getName() + " has blessed you with god-like strength!");
+	        				targetPlayer.sendMessage(ChatColor.BLUE + "You now feel as if fatal wounds are like mere scratches to you!");
+	            			plugin.DemiGod.add(targetPlayer.getName());
+	            			targetPlayer.setHealth(20);
+	            			player.sendMessage(ChatColor.BLUE + targetPlayer.getName() + " is now a demigod.");
+	            		}
+					}
+					return true;
+	    		}
+    		}
+    		else
+    		{
+    			player.sendMessage(ChatColor.DARK_RED + "The gods prevent you from using this command.");
+    			return true;
+    		}
+    	}        
+        return false;
+    }
+}

File godPowers/src/com/FriedTaco/taco/godPowers/DieCommand.java

+package com.FriedTaco.taco.godPowers;
+
+//import org.bukkit.World;
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class DieCommand implements CommandExecutor
+{
+	private Player player;
+	private final godPowers plugin;
+    public DieCommand(godPowers instance) 
+    {
+        plugin = instance;
+    }
+
+	@Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
+    {
+    	if(sender instanceof Player)
+    	{
+    		player = (Player) sender;
+    		if(player.hasPermission("godpowers.die"))
+    		{
+    			if(plugin.godmodeEnabled.contains(player.getName()))
+    			{
+    				player.sendMessage(ChatColor.BLUE + "Your godly powers prevent you from death.");
+    				return true;
+    			}
+    			else
+    			{			
+    				player.setHealth(0);
+    				plugin.dropDeadItems(player);
+    				player.sendMessage("You have died.");
+    				return true;
+    			}
+    		}
+    		else
+    		{
+    			player.sendMessage(ChatColor.DARK_RED + "The gods prevent you from using this command.");
+    			return true;
+    		}
+    	}        
+        return false;
+    }
+}

File godPowers/src/com/FriedTaco/taco/godPowers/DupeCommand.java

+package com.FriedTaco.taco.godPowers;
+
+
+//import org.bukkit.World;
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+public class DupeCommand implements CommandExecutor
+{
+	private Player player;
+	private final godPowers plugin;
+    public DupeCommand(godPowers instance) 
+    {
+        plugin = instance;
+    }
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
+    {
+    	String[] split = args;
+    	if(sender instanceof Player)
+    	{
+    		player = (Player) sender;
+    		if(player.hasPermission("godpowers.dupe"))
+    		{
+    			if(split.length == 0){
+    				player.sendMessage(ChatColor.BLUE + "The gods have decided to multiply your items.");	
+    				int amount = 64;
+    			}else if(split.length == 1){
+    				if(player.getItemInHand().getTypeId() != 0){
+    					player.sendMessage(ChatColor.BLUE + "The gods have decided to multiply your items.");    	
+    				int amount = Integer.parseInt(split[0]);
+    				if(amount == 0){
+    					amount = 64;	
+    				}
+    				Inventory inv = player.getInventory();
+    				ItemStack item = player.getItemInHand();
+    				ItemStack newitem = new ItemStack(item.getType(),amount,(short)item.getDurability());
+    				newitem.setData(item.getData());
+    				newitem.setItemMeta(item.getItemMeta());
+    				newitem.addEnchantments(item.getEnchantments());
+    				newitem.setType(item.getType());
+    				newitem.setTypeId(item.getTypeId());  		
+    				inv.addItem(newitem);
+    				}else{
+    					player.sendMessage(ChatColor.DARK_RED + "The gods cannot multiply nothing.");	
+    				}
+    			}
+	    		return true;
+    		}
+    		else
+    		{
+    			player.sendMessage(ChatColor.DARK_RED + "The gods prevent you from using this command.");
+    			return true;
+    		}
+    	}        
+        return false;
+    }
+}
+

File godPowers/src/com/FriedTaco/taco/godPowers/FusRoDAH.java

+package com.FriedTaco.taco.godPowers;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+public class FusRoDAH implements CommandExecutor
+{
+	private Player player;
+	@SuppressWarnings("unused")
+	private final godPowers plugin;
+    public FusRoDAH(godPowers instance) 
+    {
+        plugin = instance;
+    }
+
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
+    {
+    	String[] split = args;
+    	if(sender instanceof Player)
+    	{
+    		player = (Player) sender;
+    		if(player.hasPermission("godpowers.fusrodah"))
+    		{
+    			if(split.length > 0)
+    			{
+    				player.sendMessage(ChatColor.RED + "Incorrect syntax. Correct usage: '/FusRoDah'");
+    				return true;
+    			}
+    			else
+    			{
+    				ItemStack i = player.getItemInHand();
+    				if(i != null && i.getTypeId() != 0)
+    				{
+    					player.sendMessage(ChatColor.DARK_RED + "Fus ro DAH!!");
+    					i.addUnsafeEnchantment(Enchantment.KNOCKBACK, 10);
+    				}
+    				else
+    				{
+    					player.sendMessage(ChatColor.RED + "You aren't holding anything.");
+    				}
+    				return true;
+    			}
+    		}
+    		else
+    		{
+    			player.sendMessage(ChatColor.DARK_RED + "The gods prevent you from using this command.");
+    		}
+    	}
+		return false;
+    }
+}

File godPowers/src/com/FriedTaco/taco/godPowers/GaiaCommand.java

+package com.FriedTaco.taco.godPowers;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class GaiaCommand implements CommandExecutor
+{
+	private Player player;
+	private final godPowers plugin;
+    public GaiaCommand(godPowers instance) 
+    {
+        plugin = instance;
+    }
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
+    {
+    	if(sender instanceof Player)
+    	{
+    		player = (Player) sender;
+    		if(player.hasPermission("godpowers.gaia"))
+    		{	
+				if(args.length == 0)
+				{
+					if(plugin.gaia.contains(player.getName()))
+					{
+						player.sendMessage(ChatColor.DARK_GREEN + "The earth no longer rejuvenates with your every step.");
+						plugin.gaia.remove(player.getName());
+					}
+					else
+					{
+						player.sendMessage(ChatColor.DARK_GREEN + "The essence of life spreads from you, rejuvenating the world around you.");
+						plugin.gaia.add(player.getName());
+					}
+					return true;
+				}
+				else
+				{
+					player.sendMessage(ChatColor.RED + "Incorrect syntax, use '/gaia'");
+					return true;
+				}
+    		}
+    		else
+    		{
+    			player.sendMessage(ChatColor.DARK_RED + "The gods prevent you from using this command.");
+    			return true;
+    		}
+    	}        
+        return false;
+    }
+}

File godPowers/src/com/FriedTaco/taco/godPowers/GodPowersCommand.java

+package com.FriedTaco.taco.godPowers;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class GodPowersCommand implements CommandExecutor
+{
+	private Player player;
+	private final godPowers plugin;
+    public GodPowersCommand(godPowers instance) 
+    {
+        plugin = instance;
+    }
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
+    {
+    	if(sender instanceof Player)
+    	{
+    		player = (Player) sender;	
+    			
+				if(args.length == 0)
+				{
+				player.sendMessage(ChatColor.DARK_AQUA+"About the "+ChatColor.DARK_GREEN+"godPowers"+ChatColor.DARK_AQUA+" Project:");		
+				player.sendMessage(ChatColor.GOLD+"godPowers is an "+ChatColor.RED+"Open Source"+ChatColor.GOLD+" plugin created in December 2011");	
+				player.sendMessage(ChatColor.GOLD+"by "+ChatColor.BLUE+"FriedTaco"+ChatColor.GOLD+". It is currently developed by "+ChatColor.BLUE+"Swift"+ChatColor.GOLD+".");
+				player.sendMessage(ChatColor.GOLD+"The goal is to provide a set of commands to give users powers based on greek mythology.");	
+				player.sendMessage(ChatColor.DARK_AQUA+"Tips:");	
+				player.sendMessage(ChatColor.GOLD+"- "+ChatColor.GREEN+"Use "+ChatColor.RED+"/godpowers commands"+ChatColor.GREEN+" to see all commands");
+				player.sendMessage(ChatColor.GOLD+"- "+ChatColor.GREEN+"Use "+ChatColor.RED+"/godpowers update"+ChatColor.GREEN+" to manually install updates");
+				player.sendMessage(ChatColor.DARK_AQUA+"Developers:");	
+				player.sendMessage(ChatColor.GOLD+"- "+ChatColor.GREEN+"SwiftDev"+ChatColor.BLUE+" (Developer)");	
+				player.sendMessage(ChatColor.GOLD+"- "+ChatColor.GREEN+"FriedTaco"+ChatColor.BLUE+" (Former Developer)");	
+				player.sendMessage(ChatColor.DARK_AQUA+"Useful Links:");	
+				player.sendMessage(ChatColor.GOLD+"- "+ChatColor.GREEN+"#godpowers @ irc.esper.net"+ChatColor.GOLD+" IRC Chat");	
+				player.sendMessage(ChatColor.GOLD+"- "+ChatColor.GREEN+"bit.ly/GodPowers"+ChatColor.GOLD+" Bukkit Plugin Page");
+				player.sendMessage(ChatColor.DARK_AQUA+"Donation Info:");	
+				player.sendMessage(ChatColor.GOLD+"- "+ChatColor.GREEN+"goldgamermc@gmail.com"+ChatColor.GOLD+" Paypal");	
+				}else if(args.length == 1){
+				if(args[0].equalsIgnoreCase("commands")){
+		    		if(player.hasPermission("godpowers.commands"))
+		    		{
+					player.sendMessage(ChatColor.BLUE + "You can use the following commands: (< > = Optional [ ] = Required)");
+					for(String s : plugin.list.keySet())
+						if(player.hasPermission("godpowers."+plugin.list.get(s)))
+								player.sendMessage(ChatColor.AQUA + "/" + s + " " + plugin.list.get(s));
+		    		}else
+		    		{
+		    			player.sendMessage("The gods prevent you from using this command.");
+		    			return true;
+		    		}
+				}
+				if(args[0].equalsIgnoreCase("update")){
+					Updater updater = new Updater(plugin, "godpowers", plugin.file, Updater.UpdateType.NO_DOWNLOAD, false);	
+					if(updater.getResult().equals(Updater.UpdateResult.NO_UPDATE)){
+						player.sendMessage(ChatColor.GREEN+"godPowers: "+ChatColor.GOLD+"There is currently no updates available.");		
+					}else if(updater.getResult().equals(Updater.UpdateResult.UPDATE_AVAILABLE)){
+						player.sendMessage(ChatColor.GREEN+"godPowers: "+ChatColor.GOLD+"There is currently an update available, downloading now...");	
+						Updater updater2 = new Updater(plugin, "godpowers", plugin.file, Updater.UpdateType.DEFAULT, true);	
+					}
+				}
+				}
+				else
+				{
+					player.sendMessage("Incorrect syntax. Use '/godpowers [commands/update]'");
+				}
+				return true;    		
+    	}        
+        return false;
+    }
+}

File godPowers/src/com/FriedTaco/taco/godPowers/HadesCommand.java

+package com.FriedTaco.taco.godPowers;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class HadesCommand implements CommandExecutor
+{
+	private Player player;
+	private final godPowers plugin;
+    public HadesCommand(godPowers instance) 
+    {
+        plugin = instance;
+    }
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
+    {
+    	if(sender instanceof Player)
+    	{
+    		player = (Player) sender;
+    		if(player.hasPermission("godpowers.hades"))
+    		{	
+				if(args.length == 0)
+				{
+					if(plugin.hades.contains(player.getName()))
+					{
+						player.sendMessage(ChatColor.DARK_RED + "You no longer corrupt the ground you walk on.");
+						plugin.hades.remove(player.getName());
+					}
+					else
+					{
+						player.sendMessage(ChatColor.DARK_RED + "The fires of the nether begin to corse through your veins.");
+						plugin.hades.add(player.getName());
+					}
+					return true;
+				}
+				else
+				{
+					player.sendMessage(ChatColor.RED + "Incorrect syntax, use '/hades'");
+					return true;
+				}
+    		}
+    		else
+    		{
+    			player.sendMessage(ChatColor.DARK_RED + "The gods prevent you from using this command.");
+    			return true;
+    		}
+    	}        
+        return false;
+    }
+}

File godPowers/src/com/FriedTaco/taco/godPowers/HealCommand.java

+package com.FriedTaco.taco.godPowers;
+
+//import org.bukkit.World;
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class HealCommand implements CommandExecutor
+{
+	private Player player;
+	private final godPowers plugin;
+    public HealCommand(godPowers instance) 
+    {
+        plugin = instance;
+    }
+
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
+    {
+    	String[] split = args;
+    	if(sender instanceof Player)
+    	{
+    		player = (Player) sender;
+    		if(player.hasPermission("godpowers.heal"))
+    		{
+	    		if(split.length==0)
+				{
+	        		player.sendMessage(ChatColor.BLUE + "Thou hath been healed! Huzzah!");
+	        		player.setHealth(20);
+	        		return true;
+				}
+	        	else
+	        	{
+	        		Player targetPlayer = plugin.getServer().getPlayer(split[0]);
+	        		if(targetPlayer==null) 
+					{
+						player.sendMessage(ChatColor.RED + "The user "+split[0]+" does not exist or is not currently logged in.");
+					}
+					if(targetPlayer == player)
+					{
+						player.sendMessage(ChatColor.RED + "To heal yourself, just type '/heal'");
+	
+					}
+					else
+					{
+						player.sendMessage(ChatColor.BLUE + targetPlayer.getName() + " has been healed.");
+						targetPlayer.sendMessage(ChatColor.BLUE + player.getName() + " has healed you! Huzzah!");	
+						targetPlayer.setHealth(20);
+					}
+					return true;
+	        	}
+    		}
+    		else
+    		{
+    			player.sendMessage(ChatColor.DARK_RED + "The gods prevent you from using this command.");
+     			return true;
+    		}
+    	}       
+        return false;
+    }
+}

File godPowers/src/com/FriedTaco/taco/godPowers/InfernoCommand.java

+package com.FriedTaco.taco.godPowers;
+
+//import org.bukkit.World;
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class InfernoCommand implements CommandExecutor
+{
+	private Player player;
+	private final godPowers plugin;
+    public InfernoCommand(godPowers instance) 
+    {
+        plugin = instance;
+    }
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
+    {
+    	if(sender instanceof Player)
+    	{
+    		player = (Player) sender;
+    		if(player.hasPermission("godpowers.inferno"))
+    		{   		
+	    		if(plugin.isInferno.contains(player.getName()))
+	    		{
+	    			plugin.isInferno.remove(player.getName());
+	    			player.sendMessage(ChatColor.BLUE + "You feel your firey rage suddenly subside.");
+	    		}
+	    		else
+	    		{
+	    			plugin.isInferno.add(player.getName());
+	    			player.sendMessage(ChatColor.DARK_RED + "You begin to become so angry that your firey rage causes the very ground beneath you to burn!");
+	    		}
+    		}
+    		else
+    		{
+    			player.sendMessage(ChatColor.RED + "The gods prevent you from using this command.");
+    			return true;
+    		}
+    		return true;
+    	}        
+        return false;
+    }
+}

File godPowers/src/com/FriedTaco/taco/godPowers/Jesus.java

+package com.FriedTaco.taco.godPowers;
+
+import java.util.Hashtable;
+import org.bukkit.block.Block;
+import org.bukkit.entity.Player;
+
+public class Jesus
+{
+	int[] raftX = new int[25];
+	int[] raftY = new int[25];
+	int[] raftZ = new int[25];
+	@SuppressWarnings("rawtypes")
+	public static Hashtable rafts = new Hashtable();
+	Player player;
+	public Jesus()
+	{
+	}
+	public class RaftPiece
+	{
+		public RaftPiece(int x, int y, int z)
+		{
+			this.x = x;
+			this.y = y;
+			this.z = z;
+			
+		}
+		int x,y,z,type = 0;
+		boolean made = false;
+		boolean destroyed = false;
+	}
+	public class Raft
+	{
+		public RaftPiece[] raft =
+		{
+				new RaftPiece(2, -1, 2),
+				new RaftPiece(2, -1, 1),
+				new RaftPiece(2, -1, 0),
+				new RaftPiece(2, -1, -1),
+				new RaftPiece(2, -1, -2),
+				new RaftPiece(1, -1, 2),
+				new RaftPiece(1, -1, 1),
+				new RaftPiece(1, -1, 0),
+				new RaftPiece(1, -1, -1),
+				new RaftPiece(1, -1, -2),
+				new RaftPiece(0, -1, 2),
+				new RaftPiece(0, -1, 1),
+				new RaftPiece(0, -1, 0),
+				new RaftPiece(0, -1, -1),
+				new RaftPiece(0, -1, -2),
+				new RaftPiece(-1, -1, 2),
+				new RaftPiece(-1, -1, 1),
+				new RaftPiece(-1, -1, 0),
+				new RaftPiece(-1, -1, -1),
+				new RaftPiece(-1, -1, -2),
+				new RaftPiece(-2, -1, 2),
+				new RaftPiece(-2, -1, 1),
+				new RaftPiece(-2, -1, 0),
+				new RaftPiece(-2, -1, -1),
+				new RaftPiece(-2, -1, -2)
+		};
+	
+	void makeJesusRaft(Player player)
+	{
+		for(int i = 0; i < raft.length; i++)
+		{
+			Block block = player.getWorld().getBlockAt(((int) player.getLocation().getX() + raft[i].x), ((int) player.getLocation().getY() + raft[i].y), ((int) player.getLocation().getZ() + raft[i].z));
+			if(block.getTypeId() == 8 || block.getTypeId() == 9) 
+			{
+				raftX[i] = (int) player.getLocation().getX()+raft[i].x;
+				raftY[i] = (int) player.getLocation().getY()+raft[i].y;
+				raftZ[i] = (int) player.getLocation().getZ()+raft[i].z;
+				raft[i].made = true;
+				block.setTypeId(79);
+			} 
+			else if(block.getTypeId() == 10 || block.getTypeId() == 11)
+			{
+				raftX[i] = (int) player.getLocation().getX()+raft[i].x;
+				raftY[i] = (int) player.getLocation().getY()+raft[i].y;
+				raftZ[i] = (int) player.getLocation().getZ()+raft[i].z;
+				raft[i].made = true;
+				block.setTypeId(49);
+			}
+			else 
+			{
+				raft[i].made = false;
+			}
+		}
+	}
+	void destroyJesusRaft(Player player)
+	{
+		for(int i = 0; i < raft.length; i++)
+		{
+			Block block = player.getWorld().getBlockAt(((int)raftX[i]), ((int)raftY[i]), ((int)raftZ[i]));
+			if(block.getTypeId() == 79)
+			{
+				block.setTypeId(8);
+			}
+			else if(block.getTypeId() == 49)
+			{
+				block.setTypeId(10);
+			}
+			if (raft[i].made)
+			{
+				raft[i].made = false;
+			}
+		}
+	}
+	}
+}

File godPowers/src/com/FriedTaco/taco/godPowers/JesusCommand.java

+package com.FriedTaco.taco.godPowers;
+
+//import org.bukkit.World;
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import com.FriedTaco.taco.godPowers.Jesus.Raft;
+
+public class JesusCommand implements CommandExecutor
+{
+	private Player player;
+	private final godPowers plugin;
+    public JesusCommand(godPowers instance) 
+    {
+        plugin = instance;
+    }
+
+	@SuppressWarnings("unchecked")
+	@Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
+    {
+    	if(sender instanceof Player)
+    	{
+    		player = (Player) sender;
+        	Raft r = (Raft)Jesus.rafts.get(player.getName());
+        	Jesus j = new Jesus();
+        	if(player.hasPermission("godpowers.jesus"))
+    		{
+				if (r == null)
+				{
+					player.sendMessage(ChatColor.BLUE + "You feel as if you can walk on water, just like Jesus!");
+					plugin.isJesus.add(player.getName());
+					Jesus.rafts.put(player.getName(), j.new Raft());
+					return true;
+				}
+				else
+				{
+					player.sendMessage(ChatColor.BLUE + "You feel your Jesus-like powers draining from you.");
+					Jesus.rafts.remove(player.getName());
+					plugin.isJesus.remove(player.getName());
+					r.destroyJesusRaft(player);
+					return true;
+				}
+    		}
+			else
+			{
+				player.sendMessage(ChatColor.DARK_RED + "The gods prevent you from using this command.");
+    			return true;
+			}
+    	}        
+        return false;
+    }
+}

File godPowers/src/com/FriedTaco/taco/godPowers/MaimCommand.java

+package com.FriedTaco.taco.godPowers;
+
+//import org.bukkit.World;
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class MaimCommand implements CommandExecutor
+{
+	private Player player;
+	private final godPowers plugin;
+    public MaimCommand(godPowers instance) 
+    {
+        plugin = instance;
+    }
+
+	@Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
+    {
+		String[] split = args;
+    	if(sender instanceof Player)
+    	{
+    		player = (Player) sender;
+    		if(player.hasPermission("godpowers.maim"))
+    		{
+	    		if(split.length == 1)
+				{
+					Player targetPlayer = plugin.getServer().getPlayer(split[0]);
+					if(targetPlayer==null) 
+					{
+						player.sendMessage(ChatColor.RED + "The user "+split[0]+" does not exist or is not currently logged in.");
+					}
+					else if(plugin.godmodeEnabled.contains(targetPlayer.getName()))
+					{
+						player.sendMessage(ChatColor.RED + "Fool! You cannot maim a god!");
+					}
+					else
+					{
+						targetPlayer.setHealth(2);
+						player.sendMessage(ChatColor.BLUE + "You viciously beat " + targetPlayer.getName() + " within an inch of thier life.");
+						targetPlayer.sendMessage(ChatColor.BLUE + player.getName() + " has beaten you within an inch of your life!");
+					}
+					return true;
+				}
+				else
+				{
+					player.sendMessage(ChatColor.RED + "Incorrect syntax, use '/maim [playerName]'");
+					return true;
+				}
+    		}
+    		else
+    		{
+    			player.sendMessage(ChatColor.DARK_RED + "The gods prevent you from using this command.");
+    			return true;
+    		}
+    	}        
+        return false;
+    }
+}

File godPowers/src/com/FriedTaco/taco/godPowers/Metrics.java

+/*
+ * Copyright 2011-2013 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 com.FriedTaco.taco.godPowers;
+
+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 org.bukkit.scheduler.BukkitTask;
+
+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;
+
+/**
+ * <p> The metrics class obtains data about a plugin and submits statistics about it to the metrics backend. </p> <p>
+ * Public methods provided by this class: </p>
+ * <code>
+ * Graph createGraph(String name); <br/>
+ * void addCustomData(BukkitMetrics.Plotter plotter); <br/>
+ * void start(); <br/>
+ * </code>
+ */
+public class Metrics {
+
+    /**
+     * The current revision number
+     */
+    private final static int REVISION = 6;
+    /**
+     * 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<Graph> graphs = Collections.synchronizedSet(new HashSet<Graph>());
+    /**
+     * 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;
+    /**
+     * Debug mode
+     */
+    private final boolean debug;
+    /**
+     * Lock for synchronization
+     */
+    private final Object optOutLock = new Object();
+    /**
+     * The scheduled task
+     */
+    private volatile BukkitTask task = null;
+
+    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());
+        configuration.addDefault("debug", false);
+
+        // 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");
+        debug = configuration.getBoolean("debug", false);
+    }
+
+    /**
+     * 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 BukkitMetrics 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 (task != null) {
+                return true;
+            }
+
+            // Begin hitting the server with glorious data
+            task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(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() && task != null) {
+                                task.cancel();
+                                task = null;
+                                // 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) {
+                        if (debug) {
+                            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) {
+                if (debug) {
+                    Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
+                }
+                return true;
+            } catch (InvalidConfigurationException ex) {
+                if (debug) {
+                    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 java.io.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 (task == null) {
+                start();
+            }
+        }
+    }
+
+    /**
+     * Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task.
+     *
+     * @throws java.io.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 (task != null) {
+                task.cancel();
+                task = null;
+            }
+        }
+    }
+
+    /**
+     * 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 {
+        // Server software specific section
+        PluginDescriptionFile description = plugin.getDescription();
+        String pluginName = description.getName();
+        boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled
+        String pluginVersion = description.getVersion();
+        String serverVersion = Bukkit.getVersion();
+        int playersOnline = Bukkit.getServer().getOnlinePlayers().length;
+
+        // END server software specific section -- all code below does not use any code outside of this class / Java
+
+        // Construct the post data
+        final StringBuilder data = new StringBuilder();
+
+        // The plugin's description file containg all of the plugin data such as name, version, author, etc
+        data.append(encode("guid")).append('=').append(encode(guid));
+        encodeDataPair(data, "version", pluginVersion);
+        encodeDataPair(data, "server", serverVersion);
+        encodeDataPair(data, "players", Integer.toString(playersOnline));
+        encodeDataPair(data, "revision", String.valueOf(REVISION));
+
+        // New data as of R6
+        String osname = System.getProperty("os.name");
+        String osarch = System.getProperty("os.arch");
+        String osversion = System.getProperty("os.version");
+        String java_version = System.getProperty("java.version");
+        int coreCount = Runtime.getRuntime().availableProcessors();
+
+        // normalize os arch .. amd64 -> x86_64
+        if (osarch.equals("amd64")) {
+            osarch = "x86_64";
+        }
+
+        encodeDataPair(data, "osname", osname);
+        encodeDataPair(data, "osarch", osarch);
+        encodeDataPair(data, "osversion", osversion);
+        encodeDataPair(data, "cores", Integer.toString(coreCount));
+        encodeDataPair(data, "online-mode", Boolean.toString(onlineMode));
+        encodeDataPair(data, "java_version", java_version);
+
+        // 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<Graph> 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(pluginName)));
+
+        // 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<Graph> 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;
+        }
+    }
+
+    /**
+     * <p>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:</p>
+     * <code>
+     * StringBuffer data = new StringBuffer();
+     * data.append(encode("guid")).append('=').append(encode(guid));
+     * encodeDataPair(data, "version", description.getVersion());
+     * </code>
+     *
+     * @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<Plotter> plotters = new LinkedHashSet<Plotter>();
+
+        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 <b>unmodifiable</b> set of the plotter objects in the graph
+         *
+         * @return an unmodifiable {@link java.util.Set} of the plotter objects
+         */
+        public Set<Plotter> 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 BukkitMetrics 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
+         */