浏览代码

In this version death messages are working, and theres more of them too.

nossr50 14 年之前
父节点
当前提交
aee77c068d
共有 7 个文件被更改,包括 2153 次插入10 次删除
  1. 46 10
      TODO
  2. 34 0
      vMinecraft.java
  3. 53 0
      vMinecraftAnnouncements.java
  4. 545 0
      vMinecraftChat.java
  5. 873 0
      vMinecraftCommands.java
  6. 227 0
      vMinecraftSettings.java
  7. 375 0
      vMinecraftUsers.java

+ 46 - 10
TODO

@@ -1,11 +1,47 @@
-TODO:
-Fix existing bugs in /promote and /demote
-Add toggles to all features
-If vminecraft.properties doesn't exist make it be written and include default settings
-Refine messages when admins use commands --Ready for testing
-Change loading to happen when the plugin loads instead of having to wait for a player to speak
-Change everything else in settings to be a string like rules instead of booleans
+Vminecraft b8 Todo:
+	+ ^r for rainbow color code
+	+ Finish work on the flat file system
+	+ Antigriefs <Nos> Working on this, waiting for hMod to fix player health
+	+ Allow players to nickname themselves or others
+	+ vminecraft Help
+		* Specialized help message for vminecraft
+			? /vhelp?
+	+ Time manipulation <Cere> Working on this
+		* Have time changes not be instant but move the sky faster
+			to get to the time entered
+		* Loop through specific times of the day and then rewind
+			ex: Sunrise to sunset, mid-morning to noon
+	+ Aliasing Commands (Global Aliases and Personal Aliases) <Cere>
+	+ Recode Messaging
+		* Reply Feature
+		* Personal Muting
+	+ Different types of /slay
+		* /slay fire to burn them to death
+		* /slay drown to drown them
+		* /slay boil to burn them with lava
+	? Overload /modify
+		<Cere> We talked about potentially doing this and I think
+		I would like to now to add in further functionality and
+		further limit what features of /modify groups can access
+		<Nos> We should definitely add suffixes to /modify at least
 
 
-Ideas:
-Mass teleport command
-A personal muting system for players
+DONE
+        + Fixed death messages and ezModo
+	+ Quick recode of /me to use the new getName function
+	+ /a to toggle admin chat
+	+ Code was organized
+	+ Aliasing was added
+	+ Playerlist is now colorful and awesome
+	+ Random death messages
+	+ Suicide command
+	+ Heal Command
+	+ Colored Prefixes
+	+ Color Codes only removed when actual colors are specified
+		* Allows use of ^ for emotes and whatever else they
+			might be needed for.
+	+ Multi Line color fix
+		* Now we can have color on multiple lines without
+			crashing the client
+		* Also does not cut words in half
+
+Notes: Let's try to to finish as much of this list as possible tomorrow and push for a b8 release soon :P

+ 34 - 0
vMinecraft.java

@@ -0,0 +1,34 @@
+import java.util.logging.Logger;
+
+//=====================================================================
+//Class:	vMinecraftPlugin
+//Use:		Starts the plugin
+//Author:	nossr50, TrapAlice, cerevisiae
+//=====================================================================
+public class vMinecraft extends Plugin {
+    static final vMinecraftListener listener = new vMinecraftListener();
+    protected static final Logger log = Logger.getLogger("Minecraft");
+    
+	public void enable() {
+		vMinecraftSettings.getInstance().loadSettings();
+                vMinecraftUsers.getInstance().loadUsers();
+		vMinecraftCommands.loadCommands();
+
+    }
+
+    public void disable() {
+        //And remove the commands here.
+    }
+
+    public void initialize() {
+        //Here we add the hook we're going to use. In this case it's the arm swing event.
+        etc.getLoader().addListener(PluginLoader.Hook.CHAT, listener, this, PluginListener.Priority.MEDIUM);
+        etc.getLoader().addListener(PluginLoader.Hook.LOGIN, listener, this, PluginListener.Priority.MEDIUM);
+        etc.getLoader().addListener(PluginLoader.Hook.COMMAND, listener, this, PluginListener.Priority.HIGH);
+        etc.getLoader().addListener(PluginLoader.Hook.IGNITE, listener, this, PluginListener.Priority.HIGH);
+        etc.getLoader().addListener(PluginLoader.Hook.DAMAGE, listener, this, PluginListener.Priority.MEDIUM);
+        etc.getLoader().addListener(PluginLoader.Hook.EXPLODE, listener, this, PluginListener.Priority.HIGH);
+        etc.getLoader().addListener(PluginLoader.Hook.HEALTH_CHANGE, listener, this, PluginListener.Priority.MEDIUM);
+        }
+    }
+

+ 53 - 0
vMinecraftAnnouncements.java

@@ -0,0 +1,53 @@
+//=====================================================================
+//Class:	vMinecraftAnnouncements
+//Use:		Encapsulates all announcements broadcast when commands are
+//			run
+//Author:	nossr50, TrapAlice, cerevisiae
+//=====================================================================
+public class vMinecraftAnnouncements {
+
+	//=====================================================================
+	//Function:	onCommand
+	//Input:	Player player: The player calling the command
+	//			String[] split: The arguments
+	//Output:	boolean: If the user has access to the command
+	//					 and it is enabled
+	//Use:		Checks if /kick, /ban, /ipban, and /time are run and
+	//			displays a global message
+	//=====================================================================
+	public boolean onCommand(Player player, String[] split) {
+		if(!player.canUseCommand(split[0])) {
+			return false;
+		}
+		//Only run if the global message feature is enabled
+		if(vMinecraftSettings.getInstance().globalmessages())
+		{
+			//Global messages that should only parse when a command can be successful
+			if(split[0].equalsIgnoreCase("/kick")) {
+				Player playerTarget = etc.getServer().matchPlayer(split[1]);
+				if (playerTarget != null && !playerTarget.hasControlOver(player)) {
+					vMinecraftChat.gmsg(player, player.getColor()+player.getName()+Colors.Blue+" has kicked "+Colors.Red+playerTarget.getColor()+playerTarget.getName());
+				}
+			}
+			if(split[0].equalsIgnoreCase("/ban")) {
+				Player playerTarget = etc.getServer().matchPlayer(split[1]);
+				if (playerTarget != null && !playerTarget.hasControlOver(player)) {
+					vMinecraftChat.gmsg(player, player.getColor()+player.getName()+Colors.Blue+" has banned "+Colors.Red+playerTarget.getColor()+playerTarget.getName());
+				}
+			}
+			if(split[0].equalsIgnoreCase("/ipban")) {
+				Player playerTarget = etc.getServer().matchPlayer(split[1]);
+				if (playerTarget != null && !playerTarget.hasControlOver(player)) {
+					vMinecraftChat.gmsg(player, player.getColor()+player.getName()+Colors.Blue+" has IP banned "+Colors.Red+playerTarget.getColor()+playerTarget.getName());
+				}
+			}
+			if(split[0].equalsIgnoreCase("/time")) {
+				if (split.length <= 2) {
+					vMinecraftChat.gmsg(player, Colors.Blue+"Time changes thanks to "+player.getColor()+player.getName());
+				}
+			}
+		}
+	    
+		return true;
+	}
+}

+ 545 - 0
vMinecraftChat.java

@@ -0,0 +1,545 @@
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+//=====================================================================
+//Class:	vMinecraftChat
+//Use:		Encapsulates all chat commands added by this mod
+//Author:	nossr50, TrapAlice, cerevisiae
+//=====================================================================
+public class vMinecraftChat {
+    protected static final Logger log = Logger.getLogger("Minecraft");
+
+	//=====================================================================
+	//Function:	gmsg
+	//Input:	String msg: The message to be broadcast to all players
+	//Output:	None 
+	//Use:		Outputs a message to everybody
+	//=====================================================================
+    public static void gmsg(Player sender, String msg){
+        for (Player receiver : etc.getServer().getPlayerList()) {
+            if (receiver != null) {
+                sendMessage(sender, receiver, msg);
+            }
+        }
+    }
+
+	//=====================================================================
+	//Function:	sendMessage
+	//Input:	String msg: The message to be broadcast to all players
+	//Output:	None 
+	//Use:		Outputs a message to everybody
+	//=====================================================================
+    public static void sendMessage(Player sender, Player receiver, String msg){
+    	String[] message = applyColors(wordWrap(msg));
+    	for(String out : message)
+    		receiver.sendMessage(out + " ");
+    }
+
+	//=====================================================================
+	//Function:	wordWrap
+	//Input:	String msg: The message to be wrapped
+	//Output:	String[]: The array of substrings 
+	//Use:		Cuts the message apart into whole words short enough to fit
+    //			on one line
+	//=====================================================================
+    public static String[] wordWrap(String msg){
+    	//Split each word apart
+    	ArrayList<String> split = new ArrayList<String>();
+    	for(String in : msg.split(" "))
+    		split.add(in);
+    	
+    	//Create an arraylist for the output
+    	ArrayList<String> out = new ArrayList<String>();
+    	//While i is less than the length of the array of words
+    	while(!split.isEmpty()){
+    		int len = 0;
+        	
+        	//Create an arraylist to hold individual words
+        	ArrayList<String> words = new ArrayList<String>();
+
+    		//Loop through the words finding their length and increasing
+    		//j, the end point for the sub string
+    		while(len <= 316 && !split.isEmpty())
+    		{
+    			int wordLength = msgLength(split.get(0)) + 4;
+    			
+    			//If a word is too long for a line
+    			if(wordLength > 316)
+    			{
+        			String[] tempArray = wordCut(len, split.remove(0));
+        			words.add(tempArray[0]);
+        			split.add(tempArray[1]);
+    			}
+
+    			//If the word is not too long to fit
+    			len += wordLength;
+    			if( len < 316)
+    				words.add(split.remove(0));
+    		}
+    		//Merge them and add them to the output array.
+    		out.add( etc.combineSplit(0,
+    				words.toArray(new String[out.size()]), " ") );
+    	}
+    	//Convert to an array and return
+    	return out.toArray(new String[out.size()]);
+    }
+    
+	//=====================================================================
+	//Function:	msgLength
+	//Input:	String str: The string to find the length of
+	//Output:	int: The length on the screen of a string
+	//Use:		Finds the length on the screen of a string. Ignores colors.
+	//=====================================================================
+    private static int msgLength(String str){
+		int length = 0;
+		//Loop through all the characters, skipping any color characters
+		//and their following color codes
+		for(int x = 0; x<str.length(); x++)
+		{
+			int len = charLength(str.charAt(x));
+			if( len > 0)
+				length += len;
+			else
+				x++;
+		}
+		return length;
+    }
+    
+	//=====================================================================
+	//Function:	wordCut
+	//Input:	String str: The string to find the length of
+	//Output:	String[]: The cut up word
+	//Use:		Cuts apart a word that is too long to fit on one line
+	//=====================================================================
+    private static String[] wordCut(int lengthBefore, String str){
+		int length = lengthBefore;
+		//Loop through all the characters, skipping any color characters
+		//and their following color codes
+		String[] output = new String[2];
+		int x = 0;
+		while(length < 316 && x < str.length())
+		{
+			int len = charLength(str.charAt(x));
+			if( len > 0)
+				length += len;
+			x++;
+		}
+		//Add the substring to the output after cutting it
+		output[0] = str.substring(0, x);
+		//Add the last of the string to the output.
+		output[1] = str.substring(x);
+		return output;
+    }
+    
+	//=====================================================================
+	//Function:	charLength
+	//Input:	char x: The character to find the length of.
+	//Output:	int: The length of the character
+	//Use:		Finds the visual length of the character on the screen.
+	//=====================================================================
+    private static int charLength(char x)
+    {
+    	if("i;,.:|!".indexOf(x) != -1)
+			return 2;
+		else if("l'".indexOf(x) != -1)
+			return 3;
+		else if("tI[]".indexOf(x) != -1)
+			return 4;
+		else if("kf{}<>\"*()".indexOf(x) != -1)
+			return 5;
+		else if("hequcbrownxjmpsvazydgTHEQUCKBROWNFXJMPSVLAZYDG1234567890#\\/?$%-=_+&".indexOf(x) != -1)
+			return 6;
+		else if("@~".indexOf(x) != -1)
+			return 7;
+		else if(x==' ')
+			return 4;
+		else
+			return -1;
+    }
+
+	//=====================================================================
+	//Function:	rainbow
+	//Input:	String msg: The string to colorify
+	//Output:	String: The rainbowed result
+	//Use:		Rainbowifies a string;
+	//=====================================================================
+    public static String rainbow(String msg){
+    	String temp = "";
+    	//The array of colors to use
+		String[] rainbow = new String[] {Colors.Red, Colors.Rose, Colors.Gold,
+				Colors.Yellow, Colors.LightGreen, Colors.Green, Colors.Blue,
+				Colors.Navy, Colors.DarkPurple, Colors.Purple, Colors.LightPurple};
+		int counter=0;
+		//Loop through the message applying the colors
+		for(int x=0; x<msg.length(); x++)
+		{
+			temp+=rainbow[counter]+msg.charAt(x);
+			
+			if(msg.charAt(x)!=' ') counter++;
+			if(counter==rainbow.length) counter = 0;
+		}
+		return temp;
+    }
+	//=====================================================================
+	//Function:	getName
+	//Input:	Player player: The player to get name as color
+	//Output:	String: The name colored 
+	//Use:		Returns the colored name;
+	//=====================================================================
+    public static String getName(Player player){
+    	
+    	//Get the prefix
+    	String playerPrefix = player.getPrefix();
+    	
+    	//Add the name
+    	String output = player.getName();
+    	
+    	//Add the color if there is one
+    	if(player.getColor() != null && player.getColor() != "")
+    		output = player.getColor().substring(0,2) + output;
+    	//Add the prefix if there is one
+    	if(playerPrefix != null && !playerPrefix.isEmpty())
+    		output = applyColors(playerPrefix.substring(1)) + output;
+    	
+    	//Return the name
+        return output;
+    }
+    
+	//=====================================================================
+	//Function:	colorChange
+	//Input:	char colour: The color code to find the color for
+	//Output:	String: The color that the code identified 
+	//Use:		Finds a color giving a color code
+	//=====================================================================
+	public static String colorChange(char colour)
+	{
+		String color = "";
+		switch(colour)
+		{
+			case '0':
+				color = Colors.Black;
+				break;
+			case '1':
+				color = Colors.Navy;
+				break;
+			case '2':
+				color = Colors.Green;
+				break;
+			case '3':
+				color = Colors.Blue;
+				break;
+			case '4':
+				color = Colors.Red;
+				break;
+			case '5':
+				color = Colors.Purple;
+				break;
+			case '6':
+				color = Colors.Gold;
+					break;
+			case '7':
+				color = Colors.LightGray;
+				break;
+			case '8':
+				color = Colors.Gray;
+				break;
+			case '9':
+				color = Colors.DarkPurple;
+				break;
+			case 'a':
+				color = Colors.LightGreen;
+				break;
+			case 'b':
+				color = Colors.LightBlue;
+				break;
+			case 'c':
+				color = Colors.Rose;
+				break;
+			case 'd':
+				color = Colors.LightPurple;
+				break;
+			case 'e':
+				color = Colors.Yellow;
+				break;
+			case 'f':
+				color = Colors.White;
+				break;
+			case 'A':
+				color = Colors.LightGreen;
+				break;
+			case 'B':
+				color = Colors.LightBlue;
+				break;
+			case 'C':
+				color = Colors.Rose;
+				break;
+			case 'D':
+				color = Colors.LightPurple;
+				break;
+			case 'E':
+				color = Colors.Yellow;
+				break;
+			case 'F':
+				color = Colors.White;
+				break;
+			case 'R':
+				color = "~";
+				break;
+			case 'r':
+				color = "~";
+				break;
+			default:
+				color = null;
+				break;
+		}
+		return color;
+	}
+	  
+	//=====================================================================
+	//Function:	adminChat
+	//Input:	Player player: The player talking
+    //			String message: The message to apply the effect to
+	//Output:	boolean: If this feature is enabled
+	//Use:		Sends messages only to admins
+	//=====================================================================
+	public static boolean adminChat(Player player, String message){
+		
+		//Check if the player can use this feature
+		if(player.isAdmin() || player.canUseCommand("/adminchat"))
+		{
+			//Special formatting for adminchat {Username}
+	        String adminchat = Colors.DarkPurple + "{" + getName(player)
+	        +  Colors.DarkPurple +"}" + Colors.White + " ";
+	        
+	        //Cut off the @ prefix
+	        if(message.startsWith("@"))
+	        	message = message.substring(1, message.length());
+	        
+	        //Get the player from the playerlist to send the message to.
+			for (Player p: etc.getServer().getPlayerList()) {
+				
+				//If p is not null
+				if (p != null) {
+					
+					//And if p is an admin or has access to adminchat send message
+					if (p.isAdmin() || (p.canUseCommand("/adminchat"))) {
+						sendMessage(player, p, adminchat + message);
+					}
+				}
+			}
+
+		    //So you can read adminchat from the server console
+			log.log(Level.INFO, "@" + "<" + getName(player)
+					+  Colors.White +"> " + message); 
+			return true;
+		}
+		return false;
+	}
+
+	//=====================================================================
+	//Function:	quote
+	//Input:	Player player: The player talking
+    //			String message: The message to apply the effect to
+	//Output:	boolean: If this feature is enabled
+	//Use:		Displays a message as a quote
+	//=====================================================================
+	public static boolean quote(Player player, String message)
+	{
+		//Format the name
+		String playerName = Colors.White + "<" + getName(player)
+				+ Colors.White + "> ";
+		if(vMinecraftSettings.getInstance().greentext()) {
+			//Log the chat
+			log.log(Level.INFO, "<"+player.getName()+"> " +message);
+
+			//Output the message
+			gmsg(player, playerName + Colors.LightGreen + message);
+			return true;
+		}
+		return false;
+	}
+
+	//=====================================================================
+	//Function:	rage
+	//Input:	Player player: The player talking
+    //			String message: The message to apply the effect to
+	//Output:	boolean: If this feature is enabled
+	//Use:		Displays a message in red
+	//=====================================================================
+	public static boolean rage(Player player, String message)
+	{
+		//Format the name
+		String playerName = Colors.White + "<"
+				+ getName(player) + Colors.White +"> ";
+		if (vMinecraftSettings.getInstance().FFF()) {
+			log.log(Level.INFO, "<"+player.getName()+"> "+message);
+			
+			//Output the message
+			gmsg(player, playerName + Colors.Red +  message);
+			return true;
+		}
+		return false;
+	}
+    
+    //=====================================================================
+	//Function:	quakeColors
+	//Input:	Player player: The player talking
+    //			String message: The message to apply the effect to
+	//Output:	boolean: If this feature is enabled
+	//Use:		Displays a message in red
+	//=====================================================================
+	public static boolean quakeColors(Player player, String message)
+	{
+		//Format the name
+		String playerName = Colors.White + "<"
+				+ getName(player) + Colors.White +"> ";
+		if(vMinecraftSettings.getInstance().quakeColors()) {
+
+			//Log the chat
+			log.log(Level.INFO, "<"+player.getName()+"> "+message);
+			
+			//Output the message
+			gmsg(player, playerName + message);
+
+			//Loop through the string finding the color codes and inserting them
+			return true;
+		}
+		return false;
+	}
+    
+	//=====================================================================
+	//Function:	emote
+	//Input:	Player player: The player talking
+    //          	String message: The message to apply the effect to
+	//Output:	boolean: If this feature is enabled
+	//Use:		/me but with our custom colors applied
+	//=====================================================================
+        public static boolean emote(Player player, String message)
+        {
+			gmsg(player, "* " + getName(player) + " " + Colors.White + message);
+            return true;
+        }
+
+    
+    //=====================================================================
+	//Function:	applyColors
+	//Input:	String[] message: The lines to be colored
+	//Output:	String[]: The lines, but colorful
+	//Use:		Colors each line
+	//=====================================================================
+	public static String[] applyColors(String[] message)
+	{
+		if(message != null && message[0] != null && !message[0].isEmpty()){
+			//The color to start the line with
+			String recentColor = Colors.White;
+			
+			//Go through each line
+			int counter = 0;
+			for(String msg: message)
+			{	
+				//Start the line with the most recent color
+				String temp = recentColor;
+				
+				//Loop through looking for a color code
+				for(int x = 0; x< msg.length(); x++)
+				{
+					//If the char is a ^ or �
+					if(msg.charAt(x) == '^' || msg.charAt(x) == Colors.White.charAt(0))
+					{
+						if(x != msg.length() - 1)
+						{
+							//If the following character is a color code
+							if(vMinecraftChat.colorChange(msg.charAt(x+1)) != null)
+							{
+								//Set the most recent color to the new color
+								recentColor = vMinecraftChat.colorChange(msg.charAt(x+1));
+								//Add the color
+								temp += recentColor;
+								//Skip these chars
+								x++;
+							//Otherwise ignore it.
+							} else {
+								temp += msg.charAt(x);
+							}
+						//Insert the character
+						} else {
+							temp += msg.charAt(x);
+						}
+					} else {
+						temp += msg.charAt(x);
+					}
+				}
+				//Replace the message with the colorful message
+				message[counter] = temp;
+				counter++;
+			}
+		}
+		return message;
+	}
+
+	//=====================================================================
+	//Function:	applyColors
+	//Input:	String message: The line to be colored
+	//Output:	String: The line, but colorful
+	//Use:		Colors a line
+	//=====================================================================
+	public static String applyColors(String message)
+	{
+		return applyColors(message, Colors.White);
+	}
+
+	//=====================================================================
+	//Function:	applyColors
+	//Input:	String message: The line to be colored
+	//			String color: The color to start the line with
+	//Output:	String: The line, but colorful
+	//Use:		Colors a line
+	//=====================================================================
+	public static String applyColors(String message, String color)
+	{
+		if(message != null && !message.isEmpty())
+		{
+			//The color to start the line with
+			if(color == null)
+				 color = Colors.White;
+			
+			//Start the line with the most recent color
+			String temp = color;
+			
+			//Loop through looking for a color code
+			for(int x = 0; x< message.length(); x++)
+			{
+				//If the char is a ^ or '�'
+				if(message.charAt(x) == '^' || message.charAt(x) == Colors.White.charAt(0))
+				{
+					if(x != message.length() - 1)
+					{
+						//If the following character is a color code
+						if(vMinecraftChat.colorChange(message.charAt(x+1)) != null)
+						{
+							//Set the most recent color to the new color
+							color = vMinecraftChat.colorChange(message.charAt(x+1));
+							//Add the color
+							temp += color;
+							//Skip these chars
+							x++;
+						//Otherwise ignore it.
+						} else {
+							temp += message.charAt(x);
+						}
+					//Insert the character
+					} else {
+						temp += message.charAt(x);
+					}
+					//Insert the character
+				} else {
+					temp += message.charAt(x);
+				}
+		
+			}
+			message = temp;
+		}
+		return message;
+	}
+}

+ 873 - 0
vMinecraftCommands.java

@@ -0,0 +1,873 @@
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+//=====================================================================
+//Class:	vMinecraftCommands
+//Use:		Encapsulates all commands added by this mod
+//Author:	nos, trapalice, cerevisiae
+//=====================================================================
+public class vMinecraftCommands{
+
+	//Log output
+    protected static final Logger log = Logger.getLogger("Minecraft");
+    static final int EXIT_FAIL = 0,
+    		  		 EXIT_SUCCESS = 1,
+    		  		 EXIT_CONTINUE = 2;
+    
+    //The list of commands for vMinecraft
+    public static commandList cl = new commandList();
+
+	//=====================================================================
+	//Function:	loadCommands
+	//Input:	None
+	//Output:	None
+	//Use:		Imports all the commands into the command list
+	//=====================================================================
+    public static void loadCommands(){
+		//If we had commands we would add them here.
+        cl.register("/tp", "teleport");
+        cl.register("/masstp", "masstp", "Teleports those with lower permissions to you");
+        cl.register("/reload", "reload");
+        cl.register("/rules", "rules", "Displays the rules");
+        cl.register("/fabulous", "fabulous", "makes text SUUUPER");
+        cl.register("/whois", "whois", "/whois [user]");
+        cl.register("/who", "who");
+        cl.register("/say", "say");
+        cl.register("/slay", "slay", "Kill target player");
+        cl.register("/ezmodo", "invuln", "Toggle invulnerability");
+        cl.register("/ezlist", "ezlist", "List invulnerable players");
+        cl.register("/heal", "heal", "heal yourself or other players");
+        cl.register("/suicide", "suicide", "kill yourself... you loser");
+        cl.register("/a", "adminChatToggle", "toggle admin chat for every message");
+        cl.register("/modify", "modifySplit");
+        cl.register("/me", "me");
+        cl.registerAlias("/playerlist", "/who");
+        cl.registerAlias("/wrists", "/suicide");
+        cl.registerAlias("/ci", "/clearinventory");
+    }
+    //=====================================================================
+	//Function:	me (/me)
+	//Input:	Player player: The player using the command
+	//Output:	int: Exit Code
+	//Use:		The player uses this to emote, but now its colorful.
+	//=====================================================================
+    public static int me(Player player, String[] args)
+    {
+        String str = etc.combineSplit(0, args, " ");
+        if (args.length < 1) {return EXIT_FAIL;}
+        vMinecraftChat.emote(player, str);
+        return EXIT_SUCCESS;
+    }
+    
+	//=====================================================================
+	//Function:	adminChatToggle (/a)
+	//Input:	Player player: The player using the command
+	//Output:	int: Exit Code
+	//Use:		Toggles the player into admin chat. Every message they
+        //              send will be piped to admin chat.
+	//=====================================================================
+    public static int adminChatToggle(Player player, String[] args)
+	{
+	    if(vMinecraftSettings.getInstance().adminChatToggle())
+	    {
+			//If the player is already toggled for admin chat, remove them
+			if (vMinecraftSettings.getInstance().isAdminToggled(player.getName())) {
+	                    player.sendMessage(Colors.Red + "Admin Chat Toggle = off");
+	                    vMinecraftSettings.getInstance().removeAdminToggled(player.getName());
+			//Otherwise include them
+		} else {
+	                player.sendMessage(Colors.Blue + "Admin Chat Toggled on");
+	                vMinecraftSettings.getInstance().addAdminToggled(player.getName());
+			}
+	       return EXIT_SUCCESS;		
+	    }
+	    return EXIT_FAIL;
+	}
+	//=====================================================================
+	//Function:	heal (/heal)
+	//Input:	Player player: The player using the command
+    //			String[] args: The arguments for the command. Should be a
+    //						   player name or blank
+	//Output:	int: Exit Code
+	//Use:		Heals yourself or a specified player.
+	//=====================================================================
+    public static int heal(Player player, String[] args)
+    {
+        if(vMinecraftSettings.getInstance().cmdHeal())
+        {
+        	//If a target wasn't specified, heal the user.
+            if (args.length < 1){
+            	player.setHealth(20);
+            	player.sendMessage("Your health is restored");
+            //If a target was specified, try to find them and then heal them
+            //Otherwise report the error
+            } else if (args.length > 0){
+            	Player playerTarget = etc.getServer().matchPlayer(args[0]);
+            		
+            	if (playerTarget != null){
+            		playerTarget.setHealth(20);
+            		player.sendMessage(Colors.Blue + "You have healed " + vMinecraftChat.getName(playerTarget));
+            		playerTarget.sendMessage(Colors.Blue + "You have been healed by " + vMinecraftChat.getName(player));
+            	}
+            	else if (playerTarget == null){
+            		player.sendMessage(Colors.Rose + "Couldn't find that player");
+            	}
+            }
+    		return EXIT_SUCCESS;
+        }
+        return EXIT_FAIL;
+	}
+
+	//=====================================================================
+	//Function:	suicide (/suicide, /wrists)
+	//Input:	Player player: The player using the command
+    //			String[] args: Ignored
+	//Output:	int: Exit Code
+	//Use:		Kills yourself
+	//=====================================================================
+    public static int suicide(Player player, String[] args)
+    {
+        if(vMinecraftSettings.getInstance().cmdSuicide())
+        {
+        	//Set your health to 0. Not much to it.
+            player.setHealth(0);
+            return EXIT_SUCCESS;
+        }
+        return EXIT_FAIL;
+    }
+    
+	//=====================================================================
+	//Function:	teleport (/tp)
+	//Input:	Player player: The player using the command
+    //			String[] args: The arguments for the command. Should be a
+    //						   player name
+	//Output:	int: Exit Code
+	//Use:		Teleports the user to another player
+	//=====================================================================
+	public static int teleport(Player player, String[] args)
+	{
+		//Get if the command is enabled
+		if(vMinecraftSettings.getInstance().cmdTp())
+		{
+			//Make sure a player has been specified and return an error if not
+			if (args.length < 1) {
+				player.sendMessage(Colors.Rose + "Correct usage is: /tp [player]");
+			} else {
+
+				//Find the player by name
+				Player playerTarget = etc.getServer().matchPlayer(args[0]);
+				
+				//Target player isn't found
+				if(playerTarget == null)
+					player.sendMessage(Colors.Rose + "Can't find user "
+							+ args[0] + ".");
+				//If it's you, return witty message
+				else if (player.getName().equalsIgnoreCase(args[0]))
+					player.sendMessage(Colors.Rose + "You're already here!");
+					
+				//If the player is higher rank than you, inform the user
+				else if (!player.hasControlOver(playerTarget))
+					player.sendMessage(Colors.Red +
+							"That player has higher permissions than you.");
+				
+				//If the player exists transport the user to the player
+				else {
+					log.log(Level.INFO, player.getName() + " teleported to " +
+							playerTarget.getName());
+					player.teleportTo(playerTarget);
+					
+				//Otherwise inform the user that the player doesn't exist
+				}
+			}
+			return EXIT_SUCCESS;
+		}
+		return EXIT_FAIL;
+	}
+    
+	//=====================================================================
+	//Function:	masstp (/masstp)
+	//Input:	Player player: The player using the command
+    //			String[] args: Should be empty or is ignored
+	//Output:	int: Exit Code
+	//Use:		Teleports all players to the user
+	//=====================================================================
+	public static int masstp(Player player, String[] args)
+	{
+		//If the command is enabled
+		if(vMinecraftSettings.getInstance().cmdMasstp()) {
+			//Go through all players and move them to the user
+			for (Player p : etc.getServer().getPlayerList()) {
+				if (!p.hasControlOver(player)) {
+					p.teleportTo(player);
+				}
+			}
+			//Inform the user that the command has executed successfully
+			player.sendMessage(Colors.Blue+"Summoning successful.");
+			
+			return EXIT_SUCCESS;
+		}
+		return EXIT_FAIL;
+	}
+    
+	//=====================================================================
+	//Function:	tphere (/tphere)
+	//Input:	Player player: The player using the command
+    //			String[] args: The arguments for the command. Should be a
+    //						   player name
+	//Output:	int: Exit Code
+	//Use:		Teleports the user to another player
+	//=====================================================================
+	public static int tphere(Player player, String[] args)
+	{
+		//Check if the command is enabled.
+		if (vMinecraftSettings.getInstance().cmdTphere()) {
+			//Make sure a player is specified
+			if (args.length < 1) {
+				player.sendMessage(Colors.Rose + "Correct usage is: /tphere [player]");
+			} else {
+				//Get the player by name
+				Player playerTarget = etc.getServer().matchPlayer(args[0]);
+				
+				//If the target doesn't exist
+				if(playerTarget == null)
+					player.sendMessage(Colors.Rose + "Can't find user " + args[0] + ".");
+				//If the player has a higher rank than the user, return error
+				else if (!player.hasControlOver(playerTarget)) 
+					player.sendMessage(Colors.Red + "That player has higher permissions than you.");
+				//If the user teleports themselves, mock them
+				else if (player.getName().equalsIgnoreCase(args[0])) 
+					player.sendMessage(Colors.Rose + "Wow look at that! You teleported yourself to yourself!");
+				//If the target exists, teleport them to the user
+				 else {
+					log.log(Level.INFO, player.getName() + " teleported " + player.getName() + " to their self.");
+					playerTarget.teleportTo(player);
+				}
+			}
+			return EXIT_SUCCESS;
+		}
+		return EXIT_FAIL;
+	}
+    
+	//=====================================================================
+	//Function:	reload (/reload)
+	//Input:	Player player: The player using the command
+    //			String[] args: Ignored
+	//Output:	int: Exit Code
+	//Use:		Reloads the settings for vMinecraft
+	//=====================================================================
+	public static int reload(Player player, String[] args)
+	{
+		vMinecraftSettings.getInstance().loadSettings();
+		return EXIT_FAIL;
+	}
+
+	//=====================================================================
+	//Function:	rules (/rules)
+	//Input:	Player player: The player using the command
+    //			String[] args: Ignored
+	//Output:	int: Exit Code
+	//Use:		Lists the rules
+	//=====================================================================
+	public static int rules(Player player, String[] args)
+	{
+		//If the rules exist
+		if(vMinecraftSettings.getInstance().cmdRules()
+				&& vMinecraftSettings.getInstance().getRules().length > 0) {
+			
+			//Apply QuakeCode Colors to the rules
+			String[] rules = vMinecraftChat.applyColors(
+					vMinecraftSettings.getInstance().getRules());
+			//Display them
+			for (String str : rules ) {
+				if(!str.isEmpty())
+					player.sendMessage(Colors.Blue + str);
+				else
+					player.sendMessage(Colors.Blue + "!!!The Rules Have Not Been Set!!!");
+			}
+			return EXIT_SUCCESS;
+		}
+		return EXIT_FAIL;
+	}
+
+	//=====================================================================
+	//Function:	fabulous (/fabulous)
+	//Input:	Player player: The player using the command
+    //			String[] args: The message to apply the effect to
+	//Output:	int: Exit Code
+	//Use:		Makes the text rainbow colored
+	//=====================================================================
+	public static int fabulous(Player player, String[] args)
+	{
+		//If the command is enabled
+		if(vMinecraftSettings.getInstance().cmdFabulous()) {
+			
+			//Format the name
+			String playerName = Colors.White + "<"
+					+ vMinecraftChat.getName(player) + Colors.White +"> ";
+			//Make sure a message has been specified
+			if (args.length < 1) {return EXIT_FAIL;}
+			String str  = " ";
+			
+			//Merge the message again
+			str = etc.combineSplit(0, args, " ");
+			
+			//Output for server
+			log.log(Level.INFO, player.getName()+" fabulously said \""+ str+"\"");
+			
+			//Prepend the player name and cut into lines.
+			vMinecraftChat.gmsg(player, playerName + vMinecraftChat.rainbow(str));
+
+			return EXIT_SUCCESS;
+		}
+		return EXIT_FAIL;
+	}
+
+	//=====================================================================
+	//Function:	whois (/whois)
+	//Input:	Player player: The player using the command
+    //			String[] args: The player to find info on
+	//Output:	int: Exit Code
+	//Use:		Displays information about the player specified
+	//=====================================================================
+	public static int whois(Player player, String[] args)
+	{
+		//If the command is enabled
+		if (vMinecraftSettings.getInstance().cmdWhoIs()) {
+			//If a player is specified
+			if (args.length < 1) 
+				player.sendMessage(Colors.Rose + "Usage is /whois [player]");
+			else {
+				//Get the player by name
+				Player playerTarget = etc.getServer().matchPlayer(args[0]);
+				
+				//If the player exists
+				if (playerTarget != null){
+
+					//Displaying the information
+					player.sendMessage(Colors.Blue + "Whois results for " +
+							vMinecraftChat.getName(playerTarget));
+					//Group
+					for(String group: playerTarget.getGroups())
+					player.sendMessage(Colors.Blue + "Groups: " + group);
+					//Admin
+					player.sendMessage(Colors.Blue+"Admin: " +
+							String.valueOf(playerTarget.isAdmin()));
+					//IP
+					player.sendMessage(Colors.Blue+"IP: " + playerTarget.getIP());
+					//Restrictions
+					player.sendMessage(Colors.Blue+"Can ignore restrictions: " +
+							String.valueOf(playerTarget.canIgnoreRestrictions()));
+
+				//Give the user an error if the player doesn't exist
+				} else {
+					player.sendMessage(Colors.Rose+"Player not found.");
+				}
+			}
+			return EXIT_SUCCESS;
+		}
+		return EXIT_SUCCESS;
+	}
+
+	//=====================================================================
+	//Function:	who (/who)
+	//Input:	Player player: The player using the command
+    //			String[] args: Ignored
+	//Output:	int: Exit Code
+	//Use:		Displays the connected players
+	//=====================================================================
+	public static int who(Player player, String[] args)
+	{
+		//If the command is enabled
+		if (vMinecraftSettings.getInstance().cmdWho()) {
+			//Loop through all players counting them and adding to the list
+			int count=0;
+			String tempList = "";
+			for( Player p : etc.getServer().getPlayerList())
+			{
+				if(p != null){
+					if(count == 0)
+						tempList += vMinecraftChat.getName(p);
+					else
+						tempList += Colors.White + ", " + vMinecraftChat.getName(p);
+					count++;
+				}
+			}
+			//Get the max players from the config
+			PropertiesFile server = new PropertiesFile("server.properties");
+			try {
+				server.load();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			int maxPlayers = server.getInt("max-players");
+			
+			//Output the player list
+			vMinecraftChat.sendMessage(player, player, Colors.Rose + "Player List ("
+					+ count + "/" + maxPlayers +"): " + tempList);
+			
+			return EXIT_SUCCESS;
+		}
+		return EXIT_FAIL;
+	}
+
+	//=====================================================================
+	//Function:	say (/say)
+	//Input:	Player player: The player using the command
+    //			String[] args: The message to apply the effect to
+	//Output:	int: Exit Code
+	//Use:		Announces the message to all players
+	//=====================================================================
+	public static int say(Player player, String[] args)
+	{
+		//If the command is enabled
+		if (vMinecraftSettings.getInstance().cmdSay()) {   
+			//Make sure a message is supplied or output an error
+			if (args.length < 1) {
+				player.sendMessage(Colors.Rose + "Usage is /say [message]");
+			}
+			//Display the message globally
+			vMinecraftChat.gmsg(player, Colors.Yellow + etc.combineSplit(0, args, " "));
+			return EXIT_SUCCESS;
+		}
+		return EXIT_FAIL;
+	}
+
+	//=====================================================================
+	//Function:	slay (/slay)
+	//Input:	Player player: The player using the command
+    //			String[] args: The target for the command
+	//Output:	int: Exit Code
+	//Use:		Kill the target player
+	//=====================================================================
+	public static int slay(Player player, String[] args)
+	{
+		//Check if the command is enabled
+		if(vMinecraftSettings.getInstance().cmdEzModo()) {
+			//Get the player by name
+			Player playerTarget = etc.getServer().matchPlayer(args[0]);
+			//If the player doesn't exist don't run
+			if(playerTarget == null)
+				return EXIT_FAIL;
+			//If the player isn't invulnerable kill them
+			if (!vMinecraftSettings.getInstance().isEzModo(playerTarget.getName())) {
+				playerTarget.setHealth(0);
+				vMinecraftChat.gmsg(player, vMinecraftChat.getName(player)
+						+ Colors.LightBlue + " has slain "
+						+ vMinecraftChat.getName(playerTarget));
+			//Otherwise output error to the user
+			} else {
+				player.sendMessage(Colors.Rose + "That player is currently in ezmodo! Hahahaha");
+			}
+			return EXIT_SUCCESS;
+		}
+		return EXIT_FAIL;
+	}
+
+	//=====================================================================
+	//Function:	invuln (/ezmodo)
+	//Input:	Player player: The player using the command
+    //			String[] args: The target for the command
+	//Output:	int: Exit Code
+	//Use:		Kill the target player
+	//=====================================================================
+	public static int invuln(Player player, String[] args)
+	{
+		//If the command is enabled
+		if (vMinecraftSettings.getInstance().cmdEzModo()) {
+			//If the player is already invulnerable, turn ezmodo off.
+			if (vMinecraftSettings.getInstance().isEzModo(player.getName())) {
+				player.sendMessage(Colors.Red + "ezmodo = off");
+				vMinecraftSettings.getInstance().removeEzModo(player.getName());
+			//Otherwise make them invulnerable
+			} else {
+				player.sendMessage(Colors.LightBlue + "eh- maji? ezmodo!?");
+				player.sendMessage(Colors.Rose + "kimo-i");
+				player.sendMessage(Colors.LightBlue + "Easy Mode ga yurusareru no wa shougakusei made dayo ne");
+				player.sendMessage(Colors.Red + "**Laughter**");
+				vMinecraftSettings.getInstance().addEzModo(player.getName());
+			}
+            return EXIT_SUCCESS;
+		}
+		return EXIT_FAIL;
+	}
+
+	//=====================================================================
+	//Function:	ezlist (/ezlist)
+	//Input:	Player player: The player using the command
+    //			String[] args: Ignored
+	//Output:	int: Exit Code
+	//Use:		List all invulnerable players
+	//=====================================================================
+	public static int ezlist(Player player, String[] args)
+	{
+		//If the feature is enabled list the players
+        if(vMinecraftSettings.getInstance().cmdEzModo()) {
+            player.sendMessage("Ezmodo: " + vMinecraftSettings.getInstance().ezModoList());
+            return EXIT_SUCCESS;
+        }
+        return EXIT_FAIL;
+	}
+
+	//=====================================================================
+	//Function:	modifySplit (/modify)
+	//Input:	Player player: The player using the command
+    //			String[] args: Player, Command, Arguments
+	//Output:	int: Exit Code
+	//Use:		List all invulnerable players
+	//=====================================================================
+	public static int modifySplit(Player player, String[] args)
+	{
+		//Exploit fix for people giving themselves commands
+		if(args[1].equals("commands"))
+			return EXIT_FAIL;
+		return EXIT_CONTINUE;
+	}
+
+	//=====================================================================
+	//Function:	Time Reverse
+	//Input:	long time: The time to reverse to.
+	//Output:	int: Exit Code
+	//Use:		List all invulnerable players
+	//=====================================================================
+	public static int timeReverse(long tarTime)
+	{
+		long curTime = etc.getServer().getRelativeTime();
+		//if(cur)
+		return EXIT_SUCCESS;
+	}
+
+	//=====================================================================
+	//Function:	privateMessage(/msg)
+	//Input:	long time: The time to reverse to.
+	//Output:	int: Exit Code
+	//Use:		List all invulnerable players
+	//=====================================================================
+	public static int privateMessage(Player player, String[] message)
+	{
+		long curTime = etc.getServer().getRelativeTime();
+		//if(cur)
+		return EXIT_SUCCESS;
+	}
+}
+
+//=====================================================================
+//Class:	commandList
+//Use:		The list of commands that will be checked for
+//Author:	cerevisiae
+//=====================================================================
+class commandList {
+	command[] commands;
+  protected static final Logger log = Logger.getLogger("Minecraft");
+  static final int EXIT_FAIL = 0,
+				   EXIT_SUCCESS = 1,
+				   EXIT_CONTINUE = 2;
+  
+	//=====================================================================
+	//Function:	commandList
+	//Input:	None
+	//Output:	None
+	//Use:		Initialize the array of commands
+	//=====================================================================
+	public commandList(){
+		commands = new command[0];
+	}
+
+	//=====================================================================
+	//Function:	register
+	//Input:	String name: The name of the command
+	//			String func: The function to be called
+	//Output:	boolean: Whether the command was input successfully or not
+	//Use:		Registers a command to the command list for checking later
+	//=====================================================================
+	public boolean register(String name, String func){
+		
+		//If the command list isn't empty
+		if(commands.length > 0)
+		{
+			//Check to make sure the command doesn't already exist
+			for(int i = 0; i < commands.length; i++)
+				if(commands[i].getName().equalsIgnoreCase(name))
+					return false;
+			
+			//Create a new temp array
+			command[] temp = new command[commands.length + 1];
+			//Copy the old command list over
+			System.arraycopy(commands, 0, temp, 0, commands.length);
+			//Set commands to equal the new array
+			commands = temp;
+		} else {
+			commands = new command[1];
+		}
+
+		//Add the new function to the list
+		commands[commands.length - 1] = new command(name, func);
+		
+		//exit successfully
+		return true;
+	}
+
+	//=====================================================================
+	//Function:	register
+	//Input:	String name: The name of the command
+	//			String func: The function to be called
+	//			String info: The information for the command to put in help
+	//Output:	boolean: Whether the command was input successfully or not
+	//Use:		Registers a command to the command list for checking later
+	//=====================================================================
+	public boolean register(String name, String func, String info){
+		//Add to the /help list
+		etc.getInstance().addCommand(name, info);
+		
+		//Finish registering
+		return register(name, func);
+	}
+	
+	//=====================================================================
+	//Function:	register
+	//Input:	String name: The name of the command
+	//			String func: The function to be called
+	//Output:	boolean: Whether the command was input successfully or not
+	//Use:		Registers a command to the command list for checking later
+	//=====================================================================
+	public boolean registerAlias(String name, String com, String[] args){
+		
+		//If the command list isn't empty
+		if(commands.length > 0)
+		{
+			//Check to make sure the command doesn't already exist
+			for(int i = 0; i < commands.length; i++)
+				if(commands[i].getName().equalsIgnoreCase(name))
+					return false;
+			
+			//Create a new temp array
+			command[] temp = new command[commands.length + 1];
+			//Copy the old command list over
+			System.arraycopy(commands, 0, temp, 0, commands.length);
+			//Set commands to equal the new array
+			commands = temp;
+		} else {
+			commands = new command[1];
+		}
+
+		//Add the new function to the list
+		commands[commands.length - 1] = new commandRef(name, com, args);
+		
+		//exit successfully
+		return true;
+	}
+	
+	//=====================================================================
+	//Function:	register
+	//Input:	String name: The name of the command
+	//			String func: The function to be called
+	//Output:	boolean: Whether the command was input successfully or not
+	//Use:		Registers a command to the command list for checking later
+	//=====================================================================
+	public boolean registerAlias(String name, String com){
+		
+		//If the command list isn't empty
+		if(commands.length > 0)
+		{
+			//Check to make sure the command doesn't already exist
+			for(int i = 0; i < commands.length; i++)
+				if(commands[i].getName().equalsIgnoreCase(name))
+					return false;
+			
+			//Create a new temp array
+			command[] temp = new command[commands.length + 1];
+			//Copy the old command list over
+			System.arraycopy(commands, 0, temp, 0, commands.length);
+			//Set commands to equal the new array
+			commands = temp;
+		} else {
+			commands = new command[1];
+		}
+		
+		//Add the new function to the list
+		commands[commands.length - 1] = new commandRef(name, com);
+		
+		//exit successfully
+		return true;
+	}
+
+	//=====================================================================
+	//Function:	call
+	//Input:	String name: The name of the command to be run
+	//Output:	boolean: If the command was called successfully
+	//Use:		Attempts to call a command
+	//=====================================================================
+	public int call(String name, Player player, String[] arg){
+		//Make sure the user has access to the command
+		if(!player.canUseCommand(name)) {
+			return EXIT_FAIL;
+		}
+		//Search for the command
+		for(command cmd : commands)
+		{
+			//When found
+			if(cmd.getName().equalsIgnoreCase(name))
+			{
+				try {
+					//Call the command and return results
+					return cmd.call(player, arg);
+				} catch (SecurityException e) {
+					log.log(Level.SEVERE, "Exception while running command", e);
+				} catch (IllegalArgumentException e) {
+					log.log(Level.SEVERE, "The Command Entered Doesn't Exist", e);
+					return EXIT_FAIL;
+				}
+			}
+		}
+		
+		//Something went wrong
+		return EXIT_FAIL;
+	}
+	
+	
+	
+	//=====================================================================
+	//Class:	command
+	//Use:		The specific command
+	//Author:	cerevisiae
+	//=====================================================================
+	private class command
+	{
+		private String commandName;
+		private String function;
+
+		//=====================================================================
+		//Function:	command
+		//Input:	None
+		//Output:	None
+		//Use:		Initialize the command
+		//=====================================================================
+		public command(String name, String func){
+			commandName = name;
+			function = func;
+		}
+
+
+		//=====================================================================
+		//Function:	getName
+		//Input:	None
+		//Output:	String: The command name
+		//Use:		Returns the command name
+		//=====================================================================
+		public String getName(){return commandName;}
+
+
+		//=====================================================================
+		//Function:	call
+		//Input:	String[] arg: The arguments for the command
+		//Output:	boolean: If the command was called successfully
+		//Use:		Attempts to call the command
+		//=====================================================================
+		int call(Player player, String[] arg)
+		{
+			
+				Method m;
+				try {
+					m = vMinecraftCommands.class.getMethod(function, Player.class, String[].class);
+					m.setAccessible(true);
+					return (Integer) m.invoke(null, player, arg);
+				} catch (SecurityException e) {
+					e.printStackTrace();
+				} catch (NoSuchMethodException e) {
+					e.printStackTrace();
+				} catch (IllegalArgumentException e) {
+					e.printStackTrace();
+				} catch (IllegalAccessException e) {
+					e.printStackTrace();
+				} catch (InvocationTargetException e) {
+					e.printStackTrace();
+				}
+				return 1;
+		}
+	}
+	
+	//=====================================================================
+	//Class:	commandRef
+	//Use:		A command referencing another command
+	//Author:	cerevisiae
+	//=====================================================================
+	private class commandRef extends command
+	{
+		private String reference;
+		private String[] args;
+
+		//=====================================================================
+		//Function:	command
+		//Input:	String name: The command name
+		//			String com: The command to run
+		//			String[] arg: the arguments to apply
+		//Output:	None
+		//Use:		Initialize the command
+		//=====================================================================
+		public commandRef(String name, String com, String[] arg){
+			super(name, "");
+			reference = com;
+			args = arg;
+		}
+
+		//=====================================================================
+		//Function:	command
+		//Input:	String name: The command name
+		//			String com: The command to run
+		//Output:	None
+		//Use:		Initialize the command
+		//=====================================================================
+		public commandRef(String name, String com){
+			super(name, "");
+			reference = com;
+			args = null;
+		}
+
+
+		//=====================================================================
+		//Function:	call
+		//Input:	String[] arg: The arguments for the command
+		//Output:	boolean: If the command was called successfully
+		//Use:		Attempts to call the command
+		//=====================================================================
+		int call(Player player, String[] arg)
+		{
+			if(args != null) {
+				String[] temp = new String[args.length];
+				System.arraycopy(args, 0, temp, 0, args.length);
+				//Insert the arguments into the pre-set arguments
+				int lastSet = 0,
+					argCount = 0;
+				for(String argument : temp)
+				{
+					if(argument.startsWith("%"))
+					{
+						int argNum = Integer.parseInt(argument.substring(1));
+						if( argNum < arg.length )
+						{
+							temp[lastSet] = arg[argNum];
+							argCount++;
+						}
+					}
+					lastSet++;
+				}
+				//Append the rest of the arguments to the argument array
+				if(lastSet < temp.length + arg.length - argCount)
+				{
+					String[] temp2 = new String[temp.length + arg.length - argCount];
+					System.arraycopy(temp, 0, temp2, 0, temp.length);
+					System.arraycopy(arg, argCount, temp2,
+						temp.length, arg.length - argCount);
+					temp = temp2;
+				}
+				
+			//Call the referenced command
+				player.command(reference + " " + etc.combineSplit(0, temp, " "));
+			} else
+				player.command(reference);
+			return EXIT_SUCCESS;
+		}
+	}
+}

+ 227 - 0
vMinecraftSettings.java

@@ -0,0 +1,227 @@
+import java.io.*;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+//=====================================================================
+//Class:	vminecraftSettings
+//Use:		Controls the settings for vminecraft
+//Author:	nossr50, TrapAlice, cerevisiae
+//=====================================================================
+public class vMinecraftSettings {
+	//private final static Object syncLock = new Object();
+	protected static final Logger log = Logger.getLogger("Minecraft");
+	private static volatile vMinecraftSettings instance;
+
+
+	//The feature settings
+	static boolean toggle			= true,
+				   adminChat		= false,
+				   greentext		= false,
+				   FFF				= false,
+				   quakeColors		= false,
+				   cmdFabulous		= false,
+				   cmdPromote		= false,
+				   cmdDemote		= false,
+				   cmdWhoIs			= false,
+				   cmdRules			= false,
+				   cmdMasstp		= false,
+				   cmdTp			= false,
+				   cmdTphere		= false,
+				   globalmessages	= false,
+				   cmdSay			= false,
+				   cmdWho			= false,
+				   stopFire			= false,
+				   stopTnt			= false,
+				   cmdHeal  = false,
+				   cmdSuicide = false,
+				   cmdAdminToggle = false,
+				   cmdEzModo		= false;
+	//An array of players currently in ezmodo
+	static ArrayList<String> ezModo = new ArrayList<String>();
+        //An array of players currently toggled for admin chat
+        static ArrayList<String> adminChatList = new ArrayList<String>();
+
+	
+	private PropertiesFile properties;
+	String file = "vminecraft.properties";
+	public String rules[] = new String[0];
+        public static String deathMessages[] = new String[0];
+
+	//=====================================================================
+	//Function:	loadSettings
+	//Input:	None
+	//Output:	None
+	//Use:		Loads the settings from the properties
+	//=====================================================================
+	public void loadSettings()
+	{
+		File theDir = new File("vminecraft.properties");
+		if(!theDir.exists()){
+			String location = "vminecraft.properties";
+			properties = new PropertiesFile("vminecraft.properties");
+			FileWriter writer = null;
+			try {
+				writer = new FileWriter(location);
+				writer.write("#This plugin is modular\r\n");
+				writer.write("#Turn any features you don't want to false and they won't be running\r\n");
+				writer.write("#If you edit this file and save it, then use /reload it will reload the settings\r\n");
+				writer.write("greentext=true\r\n");
+				writer.write("quakeColors=true\r\n");
+				writer.write("cmdTphere=true\r\n");
+				writer.write("cmdFabulous=true\r\n");
+				writer.write("cmdWhoIs=true\r\n");
+				writer.write("cmdWho=true\r\n");
+				writer.write("cmdPromote=true\r\n");
+				writer.write("cmdDemote=true\r\n");
+				writer.write("cmdMasstp=true\r\n");
+				writer.write("cmdSay=true\r\n");
+				writer.write("cmdTp=true\r\n");
+				writer.write("cmdRules=true\r\n");
+				writer.write("cmdSuicide=true\r\n");
+				writer.write("cmdAdminToggle=true\r\n");
+				writer.write("globalmessages=true\r\n");
+				writer.write("FFF=true\r\n");
+				writer.write("adminchat=true\r\n");
+				writer.write("cmdEzModo=true\r\n");
+				writer.write("#Adding player names to this list will have them start off in ezmodo\r\n");
+				writer.write("ezModo=\r\n");
+				writer.write("#The health ezmodo people will have while in ezmodo. Don't set to 0\r\n");
+				writer.write("ezHealth=30\r\n");
+				writer.write("stopFire=false\r\n");
+				writer.write("stopTnt=false\r\n");
+				writer.write("rules=Rules@#1: No griefing@#2: No griefing\r\n");
+				writer.write("#Death messages, seperate them by comma. All death messages start with the player name and a space.\r\n");
+				writer.write("deathMessages=is no more,died horribly,went peacefully\r\n");
+			} catch (Exception e) {
+				log.log(Level.SEVERE, "Exception while creating " + location, e);
+			} finally {
+				try {
+					if (writer != null) {
+						writer.close();
+					}
+				} catch (IOException e) {
+					log.log(Level.SEVERE, "Exception while closing writer for " + location, e);
+				}
+			}
+
+		} else {
+			properties = new PropertiesFile("vminecraft.properties");
+			try {
+				properties.load();
+			} catch (IOException e) {
+				log.log(Level.SEVERE, "Exception while loading vminecraft.properties", e);
+			}
+		}
+
+		try {
+			adminChat = properties.getBoolean("adminchat",true);
+			greentext = properties.getBoolean("greentext",true);
+			FFF = properties.getBoolean("FFF",true);
+			quakeColors = properties.getBoolean("quakeColors",true);
+			cmdFabulous = properties.getBoolean("cmdFabulous",true);
+			cmdPromote = properties.getBoolean("cmdPromote",true);
+			cmdDemote = properties.getBoolean("cmdDemote",true);
+			cmdWhoIs = properties.getBoolean("cmdWhoIs",true);
+			cmdWho = properties.getBoolean("cmdWho",true);
+			cmdRules = properties.getBoolean("cmdRules",true);
+			cmdTp = properties.getBoolean("cmdTp",true);
+			cmdMasstp = properties.getBoolean("cmdMasstp",true);
+			cmdTphere = properties.getBoolean("cmdTphere",true);
+			cmdSuicide = properties.getBoolean("cmdSuicide", true);
+			cmdHeal = properties.getBoolean("cmdHeal",true);
+			cmdAdminToggle = properties.getBoolean("cmdAdminToggle", true);
+			globalmessages = properties.getBoolean("globalmessages",true);
+			cmdSay = properties.getBoolean("cmdSay",true);
+			cmdEzModo = properties.getBoolean("cmdEzModo",true);
+			stopFire = properties.getBoolean("stopFire",true);
+			stopTnt = properties.getBoolean("stopTNT",true);
+			rules = properties.getString("rules", "").split("@");
+			deathMessages = properties.getString("deathmessages", "").split(",");
+			
+			String[] tempEz = properties.getString("ezModo").split(",");
+			ezModo = new ArrayList<String>();
+			for(String ezName : tempEz)
+				ezModo.add(ezName);
+			
+
+			
+			log.log(Level.INFO, "vminecraft plugin successfully loaded");
+
+		}
+		catch (Exception e)
+		{
+			log.log(Level.SEVERE, "vminecraft Error: ERROR LOADING PROPERTIES FILE");
+		}
+	}
+
+	//=====================================================================
+	//Function:	adminchat, greentext, FFF, quakeColors, cmdFabulous,
+	//			cmdPromote, cmdDemote, cmdWhoIs, cmdTp, cmdTphere, cmdSay
+	//			cmdRules, globalmessages, cmdMasstp, cmdEzModo
+	//Input:	None
+	//Output:	Boolan: If the feature is enabled
+	//Use:		Returns if the feature is enabled
+	//=====================================================================
+	public boolean adminchat() {return adminChat;}
+        public boolean adminChatToggle() {return cmdAdminToggle;}
+	public boolean greentext() {return greentext;}
+	public boolean FFF() {return FFF;}
+	public boolean quakeColors() {return quakeColors;}
+	public boolean cmdFabulous() {return cmdFabulous;}
+	public boolean cmdPromote() {return cmdPromote;}
+	public boolean cmdDemote() {return cmdDemote;}
+	public boolean cmdWhoIs() {return cmdWhoIs;}
+	public boolean cmdTp() {return cmdTp;}
+	public boolean cmdTphere() {return cmdTphere;}
+	public boolean cmdSay() {return cmdSay;}
+	public boolean cmdRules() {return cmdRules;}
+	public boolean globalmessages() {return globalmessages;}
+	public boolean cmdMasstp() {return cmdMasstp;}
+	public boolean cmdWho() {return cmdWho;}
+	public boolean stopFire() {return stopFire;}
+	public boolean stopTnt() {return stopTnt;}
+        public boolean cmdSuicide() {return cmdSuicide;}
+        public boolean cmdHeal() {return cmdHeal;}
+	
+	//EzModo methods
+    public boolean cmdEzModo() {return cmdEzModo;}
+	public boolean isEzModo(String playerName) {return ezModo.contains(playerName);}
+        public boolean isAdminToggled(String playerName) {return adminChatList.contains(playerName);}
+	public void removeEzModo(String playerName) {ezModo.remove(ezModo.indexOf(playerName));}
+        public void removeAdminToggled(String playerName) {adminChatList.remove(adminChatList.indexOf(playerName));}
+	public void addEzModo(String playerName) {ezModo.add(playerName);}
+        public void addAdminToggled(String playerName) {adminChatList.add(playerName);}
+	public String ezModoList() {return ezModo.toString();}
+	
+    //Random death message method
+    public static String randomDeathMsg() {
+    	if (deathMessages == null) {
+    		return "died";
+    	}
+    	return deathMessages[ (int) (Math.random() * deathMessages.length)];
+	}
+	
+	//=====================================================================
+	//Function:	getInstance
+	//Input:	None
+	//Output:	vminecraftSettings: The instance of the settings
+	//Use:		Returns the instance of the settings
+	//=====================================================================
+	public static vMinecraftSettings getInstance() {
+		if (instance == null) {
+			instance = new vMinecraftSettings();
+		}
+		return instance;	
+	}
+
+	//=====================================================================
+	//Function:	getRules
+	//Input:	None
+	//Output:	String[]: The list of rules
+	//Use:		Gets the array containing the rules
+	//=====================================================================
+	public String[] getRules() {
+		return rules;
+	}
+
+}

+ 375 - 0
vMinecraftUsers.java

@@ -0,0 +1,375 @@
+import java.io.*;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.Scanner;
+
+public class vMinecraftUsers {
+    private static volatile vMinecraftUsers instance;
+    protected static final Logger log = Logger.getLogger("Minecraft");
+    String file = "vminecraftusers.txt";
+    private PropertiesFile properties;
+    String location = "vminecraftusers.txt";
+    
+    ArrayList<PlayerList> players = new ArrayList<PlayerList>();
+    
+    
+    public void loadUsers(){
+        File theDir = new File("vminecraftusers.txt");
+		if(!theDir.exists()){
+			properties = new PropertiesFile("vminecraftusers.txt");
+			FileWriter writer = null;
+			try {
+				writer = new FileWriter(location);
+				writer.write("#Storage place for user information\r\n");
+                                writer.write("#username:nickname:suffix:tag:ignore,list,names:alias,commands,here\r\n");
+			} catch (Exception e) {
+				log.log(Level.SEVERE, "Exception while creating " + location, e);
+			} finally {
+				try {
+					if (writer != null) {
+						writer.close();
+					}
+				} catch (IOException e) {
+					log.log(Level.SEVERE, "Exception while closing writer for " + location, e);
+				}
+			}
+
+		} else {
+			properties = new PropertiesFile("vminecraftusers.txt");
+			try {
+				properties.load();
+			} catch (IOException e) {
+				log.log(Level.SEVERE, "Exception while loading vminecraftusers.txt", e);
+			}
+		}
+    }
+        public boolean doesPlayerExist(String player) {
+        try {
+            Scanner scanner = new Scanner(new File(location));
+            while (scanner.hasNextLine()) {
+                String line = scanner.nextLine();
+                if (line.startsWith("#") || line.equals("") || line.startsWith("")) {
+                    continue;
+                }
+                String[] split = line.split(":");
+                if (!split[0].equalsIgnoreCase(player)) {
+                    continue;
+                }
+                return true;
+            }
+            scanner.close();
+        } catch (Exception e) {
+            log.log(Level.SEVERE, "Exception while reading " + location + " (Are you sure you formatted it correctly?)", e);
+        }
+        return false;
+    }
+    public static void addUser(Player player){
+        FileWriter writer = null;
+        String location = "vminecraftusers.txt";
+        String playerName = player.getName();
+        if (!vMinecraftUsers.getInstance().doesPlayerExist(playerName)){ //Check to see if the player exists before writing
+        try {
+            BufferedWriter bw = new BufferedWriter(new FileWriter(location, true));
+            bw.append(player.getName()+":::::\r");
+            bw.newLine();
+            bw.close();
+        } catch (Exception e) {
+            log.log(Level.SEVERE, "Exception while trying to add user with BufferedWriter to " + location, e);
+		} finally {
+			try {
+				if (writer != null) {
+					writer.close();
+				}
+			} catch (IOException e) {
+				log.log(Level.SEVERE, "Exception while closing BufferedWriter to " + location, e);
+			}
+		}
+    }
+    }
+    public static vMinecraftUsers getInstance() {
+		if (instance == null) {
+			instance = new vMinecraftUsers();
+		}
+		return instance;
+	}
+    public static void getRow(){
+
+    }
+}
+
+//=====================================================================
+//Class:	PlayerList
+//Use:		Encapsulates the player list
+//Author:	cerevisiae
+//=====================================================================
+class PlayerList
+{       
+	ArrayList<PlayerProfile> players;
+	
+	//=====================================================================
+	//Function:	PlayerList
+	//Input:	Player player: The player to create a profile object for
+	//Output:	none
+	//Use:		Initializes the ArrayList
+	//=====================================================================
+	public PlayerList() { players = new ArrayList<PlayerProfile>(); }
+
+	//=====================================================================
+	//Function:	addPlayer
+	//Input:	Player player: The player to add
+	//Output:	None
+	//Use:		Add a profile of the specified player
+	//=====================================================================
+	public void addPlayer(Player player)
+	{
+		players.add(new PlayerProfile(player));
+	}
+
+	//=====================================================================
+	//Function:	removePlayer
+	//Input:	Player player: The player to remove
+	//Output:	None
+	//Use:		Remove the profile of the specified player
+	//=====================================================================
+	public void removePlayer(Player player)
+	{
+		players.remove(findProfile(player));
+	}
+
+	//=====================================================================
+	//Function:	findProfile
+	//Input:	Player player: The player to find's profile
+	//Output:	PlayerProfile: The profile of the specified player
+	//Use:		Get the profile for the specified player
+	//=====================================================================
+	private PlayerProfile findProfile(Player player)
+	{
+		for(PlayerProfile ply : players)
+		{
+			if(ply.getPlayer().equals(player))
+				return ply;
+		}
+		return null;
+	}
+	
+	//=====================================================================
+	//Class:	PlayerProfile
+	//Use:		Encapsulates all commands for player options
+	//Author:	cerevisiae
+	//=====================================================================
+	class PlayerProfile
+	{
+	    protected final Logger log = Logger.getLogger("Minecraft");
+		private Player playerName;
+		private String nickName;
+		private String tag;
+                private String suffix;
+		private ArrayList<Player> ignoreList;
+		private commandList aliasList;
+		
+	    static final int EXIT_FAIL		= 0,
+			 			 EXIT_SUCCESS	= 1,
+			 			 EXIT_CONTINUE	= 2;
+
+		//=====================================================================
+		//Function:	PlayerProfile
+		//Input:	Player player: The player to create a profile object for
+		//Output:	none
+		//Use:		Loads settings for the player or creates them if they don't
+		//			exist.
+		//=====================================================================
+		public PlayerProfile(Player player)
+		{
+                        //Declare things
+			ignoreList = new ArrayList<Player>();
+            aliasList = new commandList();
+            nickName = new String();
+            tag = new String();
+            suffix = new String();
+            String location = "vminecraftusers.txt";
+            //Try to apply what we can
+            try {
+                Scanner scanner = new Scanner(new File(location));
+                while (scanner.hasNextLine()) {
+	                String line = scanner.nextLine();
+	                if (line.startsWith("#") || line.equals("") || line.startsWith("")) {
+	                    continue;
+	                }
+	                String[] split = line.split(":");
+	                if (!split[0].equalsIgnoreCase(player.getName())) {
+	                    continue;
+	                }
+	                nickName = (split[1].split(",").toString());
+	
+	                if (split.length >= 4) {
+	                    tag = (split[3]);
+	                }
+	                
+	                //Add all the ignored people to the player's ignore list
+	                if (split.length >= 5) {
+	                	for(String name : split[4].split(","))
+	                		ignoreList.add(etc.getServer().getPlayer(name));
+	                }
+	                if (split.length >= 6) {
+	                	//Loop through all the aliases
+	                	for(String alias : split[5].split(","))
+	                	{
+	                		//Break apart the two parts of the alias
+	                		String[] parts = alias.split("@");
+	                		if(parts.length > 1)
+	                		{
+	                			//Get the arguments for the alias if there are any
+	                			String[] command = parts[1].split(" ");
+	                			String[] args = null;
+	                			if(command.length > 1)
+	                				System.arraycopy(command, 1, args, 0, command.length - 2);
+	                			
+	                			//Register the alias to the player's aliasList
+	                			aliasList.registerAlias(parts[0], command[0], args);
+	                		}
+	                	}
+	                }
+	            }
+	            scanner.close();
+	        } catch (Exception e) {
+	            log.log(Level.SEVERE, "Exception while reading " + location + " (Are you sure you formatted it correctly?)", e);
+	        }
+		}
+		
+        //=====================================================================
+        // Function:    save
+        // Input:       none
+        // Output:      None
+        // Use:         Writes current values of PlayerProfile to disk
+		//				Call this function to save current values
+        //=====================================================================
+        public void save(){
+            try {
+                String location = "vminecraftusers.txt";
+                BufferedWriter bw = new BufferedWriter(new FileWriter(location, true));
+                Scanner scanner = new Scanner(new File(location));
+                while (scanner.hasNextLine()) {
+	                String line = scanner.nextLine();
+	                if (line.startsWith("#") || line.equals("") || line.startsWith("")) {
+	                    continue;
+	                }
+	                String[] split = line.split(":");
+	                if (!split[0].equalsIgnoreCase(playerName.toString())) {
+	                    continue;
+	                }
+	                bw.write(playerName + ":" + nickName + ":" + suffix + ":" + tag + ":" + ignoreList + ":" + aliasList);
+	            }
+	            scanner.close();
+	        } catch (Exception e) {
+	            String location = "vminecraftusers.txt";
+                    log.log(Level.SEVERE, "Exception while writing to " + location + " (Are you sure you formatted it correctly?)", e);
+	        }
+		}
+
+
+		//=====================================================================
+		//Function:	getPlayer
+		//Input:	None
+		//Output:	Player: The player this profile belongs to
+		//Use:		Finds if the specified player is in the ignore list
+		//=====================================================================
+		public Player getPlayer(){return playerName;}
+
+		//=====================================================================
+		//Function:	isIgnored
+		//Input:	Player player: Checks if a player is ignored
+		//Output:	boolean: If they're ignored
+		//Use:		Finds if the specified player is in the ignore list
+		//=====================================================================
+		public boolean isIgnored(Player player){return ignoreList.contains(player);}
+
+		//=====================================================================
+		//Function:	addIgnore
+		//Input:	Player name: The player to ignore
+		//Output:	None
+		//Use:		Ignores a player.
+		//=====================================================================
+		public void addIgnore(Player name)
+		{
+			if(!ignoreList.contains(name))
+				ignoreList.add(name);
+		}
+
+		//=====================================================================
+		//Function:	removeIgnore
+		//Input:	Player name: The player to ignore
+		//Output:	None
+		//Use:		Ignores a player.
+		//=====================================================================
+		public void removeIgnore(Player name)
+		{
+			if(ignoreList.contains(name))
+				ignoreList.remove(name);
+		}
+
+		//=====================================================================
+		//Function:	addAlias
+		//Input:	String command: The command to try to call
+		//			String[] args: The arguments for the command
+		//Output:	None
+		//Use:		Adds a command
+		//=====================================================================
+		public void addAlias(String name, String callCommand)
+		{
+			aliasList.registerAlias(name, callCommand);
+		}
+
+		//=====================================================================
+		//Function:	addAlias
+		//Input:	String command: The command to try to call
+		//			String[] args: The arguments for the command
+		//Output:	None
+		//Use:		Adds a command
+		//=====================================================================
+		public void addAlias(String name, String callCommand, String[] args)
+		{
+			aliasList.registerAlias(name, callCommand, args);
+		}
+
+		//=====================================================================
+		//Function:	callAlias
+		//Input:	String command: The command to try to call
+		//			Player player: Checks if a player is ignored
+		//			String[] args: The arguments for the command
+		//Output:	int: Exit code
+		//Use:		Attempts to call a command
+		//=====================================================================
+		public int callAlias(String command, Player player, String[] args)
+		{
+			try
+			{
+				//Attemt to call the function
+				return aliasList.call(command, player, args);
+			}
+			catch (Throwable e)
+			{
+				//The function wasn't found, returns fail
+				return EXIT_FAIL;
+			}
+		}
+
+		//=====================================================================
+		//Function:	setTag
+		//Input:	String newTag: The tag to set for the player
+		//Output:	None
+		//Use:		Sets a player tag
+		//=====================================================================
+		public void setTag(String newTag){ tag = newTag; }
+
+		//=====================================================================
+		//Function:	getTag
+		//Input:	None
+		//Output:	String: The player tag
+		//Use:		Gets a player tag
+		//=====================================================================
+		public String getTag() { return tag; }
+	}
+}
+
+