All pastes #984659 Raw Edit

Anonym

public text v1 · immutable
·published 2008-04-14 13:53 UTC
rendered paste body
Index: D:/L2J Workspace/L2_GameServer_CT1/java/config/irc.properties
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/config/irc.properties	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/config/irc.properties	(revision 0)
@@ -0,0 +1,41 @@
+# IRC Client Settings
+#
+# IRC BOT Functions
+# !online - displays online player count
+# !gmlist - displays the gmlist
+
+# Enable the Client
+Enable = True
+
+# Server hostname/ip
+Server = l2-eternal.de
+
+# Server Port
+Port = 6667
+
+# Use SSL
+SSL = False
+
+# Password
+Password =
+
+# Nickname 
+Nick = l2bot
+
+# User
+User = l2
+
+# Name
+Name = l2
+
+# Nickserv Support
+Nickserv = False
+NickservName = nickserv
+NickservCommand = password
+
+# Optional Login Command
+# example : LoginCommand : nickserv identify YourBotPassword
+LoginCommand = 
+
+# Channel
+Channel = #L2Tube
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/Config.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/Config.java	(revision 62)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/Config.java	(working copy)
@@ -82,6 +82,8 @@
     public static final String  SIEGE_CONFIGURATION_FILE						= "./config/siege.properties";
     /** Properties file for telnet configuration */
     public static final String  TELNET_FILE										= "./config/telnet.properties";
+    /** Properties file for IRC configuration */
+    public static final String IRC_FILE                                         = "./config/irc.properties";
 
     /******************************************************************************************************************************************************/
     /** L2J Property File Definitions End Here**/
@@ -914,7 +916,30 @@
     public static int     NORMAL_CONNECTION_TIME;
     public static int     FAST_CONNECTION_TIME;
     public static int     MAX_CONNECTION_PER_IP;  
+    
+    /** ************************************************** **/
+    /** IRC Settings - Begin                               **/
+    /** ************************************************** **/
+       
+    public static boolean       IRC_ENABLED;
+    public static boolean       IRC_SSL;
+    public static String        IRC_SERVER;
+    public static int           IRC_PORT;
+    public static String        IRC_PASS;
+    public static String        IRC_NICK;
+    public static String        IRC_USER;
+    public static String        IRC_NAME;
+    public static boolean       IRC_NICKSERV;
+    public static String        IRC_NICKSERV_NAME;
+    public static String        IRC_NICKSERV_COMMAND;
+    public static String        IRC_LOGIN_COMMAND;
+    public static String        IRC_CHANNEL;
+           
+    /** ************************************************** **/
+    /** IRC Settings - END                                 **/
+    /** ************************************************** **/
 
+
     /**
      * This class initializes all global variables for configuration.<br>
      * If key doesn't appear in properties file, a default value is setting on by this class.
@@ -1297,6 +1322,34 @@
                 e.printStackTrace();
                 throw new Error("Failed to Load "+ID_CONFIG_FILE+" File.");
             }
+            
+         // IRC
+         try
+         {
+            Properties ircSettings   = new Properties();
+            InputStream is          = new FileInputStream(new File(IRC_FILE));
+            ircSettings.load(is);
+            is.close();
+            
+            IRC_ENABLED                    = Boolean.parseBoolean(ircSettings.getProperty("Enable", "false"));
+            IRC_SSL                        = Boolean.parseBoolean(ircSettings.getProperty("SSL", "false"));
+            IRC_SERVER                     = ircSettings.getProperty("Server", "localhost");
+            IRC_PORT                       = Integer.parseInt(ircSettings.getProperty("Port", "6667"));
+            IRC_PASS                       = ircSettings.getProperty("Pass", "localhost");
+            IRC_NICK                       = ircSettings.getProperty("Nick", "l2bot");
+            IRC_USER                       = ircSettings.getProperty("User", "l2");
+            IRC_NAME                       = ircSettings.getProperty("Name", "l2");
+            IRC_NICKSERV                   = Boolean.parseBoolean(ircSettings.getProperty("NickServ", "false"));
+            IRC_NICKSERV_NAME              = ircSettings.getProperty("NickservName", "nickserv");
+            IRC_NICKSERV_COMMAND           = ircSettings.getProperty("NickservCommand", "");
+            IRC_LOGIN_COMMAND              = ircSettings.getProperty("LoginCommand", "");
+            IRC_CHANNEL                    = ircSettings.getProperty("Channel", "#mychan");
+                        }
+                        catch (Exception e)
+                        {
+                            e.printStackTrace();
+                            throw new Error("Failed to Load "+IRC_FILE+" File.");
+                        }
 
             // General Config File
             try
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/clientpackets/Say2.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/clientpackets/Say2.java	(revision 62)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/clientpackets/Say2.java	(working copy)
@@ -24,6 +24,7 @@
 import net.sf.l2j.gameserver.datatables.MapRegionTable;
 import net.sf.l2j.gameserver.handler.IVoicedCommandHandler;
 import net.sf.l2j.gameserver.handler.VoicedCommandHandler;
+import net.sf.l2j.gameserver.instancemanager.IrcManager;
 import net.sf.l2j.gameserver.instancemanager.PetitionManager;
 import net.sf.l2j.gameserver.model.BlockList;
 import net.sf.l2j.gameserver.model.L2World;
@@ -225,6 +226,8 @@
                         player.sendPacket(cs);
                     }
                 }
+                if(Config.IRC_ENABLED)
+                               IrcManager.getInstance().getConnection().sendChan("07!"+ activeChar.getName() +": " + _text);
                 break;
 			case TRADE:
 				if (Config.DEFAULT_TRADE_CHAT.equalsIgnoreCase("on") ||
@@ -243,7 +246,9 @@
                             player.sendPacket(cs);
                     }
                 }
-                break;
+				if (Config.IRC_ENABLED)
+				                IrcManager.getInstance().getConnection().sendChan("13+" + activeChar.getName() + ": " + _text);
+				break;
 			case ALL:
 				if (_text.startsWith("."))
 				{
@@ -330,6 +335,10 @@
 						activeChar.sendMessage("Action failed. Heroes are only able to speak in the global channel once every 10 seconds.");
 						return;
 					}
+					if(Config.IRC_ENABLED)
+					{
+					IrcManager.getInstance().getConnection().sendChan("12%"+ activeChar.getName() +": " + _text);
+					}
 					for (L2PcInstance player : L2World.getInstance().getAllPlayers())
 						if (!BlockList.isBlocked(player, activeChar))
 							player.sendPacket(cs);
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/network/L2IrcClient.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/network/L2IrcClient.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/network/L2IrcClient.java	(revision 0)
@@ -0,0 +1,382 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.network;
+
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.StringTokenizer;
+import java.util.logging.Logger;
+
+import javolution.util.FastMap;
+import net.sf.l2j.Base64;
+import net.sf.l2j.Config;
+import net.sf.l2j.L2DatabaseFactory;
+import net.sf.l2j.gameserver.GmListTable;
+import net.sf.l2j.gameserver.LoginServerThread;
+import net.sf.l2j.gameserver.handler.IIrcCommandHandler;
+import net.sf.l2j.gameserver.handler.IrcCommandHandler;
+import net.sf.l2j.gameserver.instancemanager.IrcManager;
+import net.sf.l2j.gameserver.lib.irc.IRCConnection;
+import net.sf.l2j.gameserver.lib.irc.IRCEventListener;
+import net.sf.l2j.gameserver.lib.irc.IRCModeParser;
+import net.sf.l2j.gameserver.lib.irc.IRCUser;
+import net.sf.l2j.gameserver.model.L2World;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.serverpackets.CreatureSay;
+import net.sf.l2j.util.Rnd;
+
+public class L2IrcClient extends Thread
+{
+    protected final static Logger _log = Logger.getLogger(L2IrcClient.class.getName());
+       
+       protected IRCConnection conn;
+       protected String channel;
+       protected String adminchan;
+       protected String nickname;
+       protected FastMap<String, String> _authedGms = new FastMap<String, String>();
+
+       public L2IrcClient(String host, int port, String pass, String nick, String user, String name, boolean ssl, String Chan)
+       {
+               conn = new IRCConnection(host, new int[] { port }, pass, nick, user, name);
+               channel = Chan;
+               nickname = nick;
+        adminchan = channel+"Admin";
+               conn.addIRCEventListener(new Listener());
+               conn.setEncoding("UTF-8");
+               conn.setPong(true);
+               conn.setDaemon(false);
+               conn.setColors(false);
+               start();
+       }
+
+       public void connect() throws IOException
+       {
+               if (!conn.isConnected())
+               {
+                       conn.connect();
+                       conn.send("JOIN " + channel);
+            conn.send("JOIN " + adminchan);
+                       setDaemon(true);
+               }
+       }
+
+       public void disconnect()
+       {
+               if (conn.isConnected())
+               {
+                       //conn.close();
+                       //IrcManager.getInstance().removeConnection();
+                       conn.doQuit();
+                       conn.setDaemon(false);
+               }
+       }
+
+       public void send(String Text)
+       {
+               if (checkConnection())
+                       conn.send(Text);
+       }
+
+       public void send(String target, String Text)
+       {
+               if (checkConnection())
+                       conn.doPrivmsg(target, Text);
+       }
+
+       public void sendChan(String Text)
+       {
+               if (checkConnection())
+               {
+                       conn.doPrivmsg(channel, Text);
+               }
+       }
+    
+    public void sendAdminChan(String Text)
+    {
+        if(checkConnection())
+        {
+            conn.doPrivmsg(adminchan, Text);
+        }
+   }
+
+       public boolean checkConnection()
+       {
+               if (!conn.isConnected())
+               {
+                       try
+                       {
+                               IrcManager.getInstance().reConnect();
+                       }
+                       catch (Exception exc)
+                       {
+                               exc.printStackTrace();
+                       }
+               }
+               return conn.isConnected();
+      }
+
+       /**
+        * Treats IRC events.
+        */
+       public class Listener implements IRCEventListener
+       {
+               private boolean isconnected;
+
+               public void onRegistered()
+               {
+                       _log.info("IRC: Connected");
+                       if (!Config.IRC_LOGIN_COMMAND.trim().equals(""))
+                               send(Config.IRC_LOGIN_COMMAND.trim());
+                       if (Config.IRC_NICKSERV)
+                               send(Config.IRC_NICKSERV_NAME, Config.IRC_NICKSERV_COMMAND);
+                       isconnected = true;
+               }
+
+               public void onDisconnected()
+               {
+                       _log.info("IRC: Disconnected");
+                       isconnected = false;
+                       IrcManager.getInstance().reConnect();
+               }
+
+               public void onError(String msg)
+               {
+                       _log.info("IRC: Error: " + msg);
+               }
+
+               public void onError(int num, String msg)
+               {
+                       _log.info("IRC: Error #" + num + ": " + msg);
+                       // nickname already in use
+                       if (num == 433)
+                      {
+                               Integer random = Rnd.get(999);
+                               send("NICK " + nickname + random);
+                               send("JOIN " + channel);
+                send("JOIN " + adminchan);
+                       }
+               }
+
+               public void onInvite(String chan, IRCUser u, String nickPass)
+               {
+               }
+
+               public void onJoin(String chan, IRCUser u)
+               {
+               }
+
+               public void onKick(String chan, IRCUser u, String nickPass, String msg)
+               {
+               }
+
+              public void onMode(IRCUser u, String nickPass, String mode)
+               {
+               }
+
+               public void onMode(String chan, IRCUser u, IRCModeParser mp)
+               {
+               }
+
+               public void onNick(IRCUser u, String nickNew)
+               {
+                       removeAccount(u.getUsername(),u.getHost());
+               }
+
+               public void onNotice(String target, IRCUser u, String msg)
+               {
+               }
+
+               public void onPart(String chan, IRCUser u, String msg)
+               {
+                       removeAccount(u.getUsername(),u.getHost());
+               }
+
+               public void onPrivmsg(String chan, IRCUser u, String msg)
+               {
+                       if (msg.equals("!online"))
+                       {
+                double onl = L2World.getInstance().getAllPlayersCount();
+                double onlshown = Math.round(((onl/100)*35)+onl);
+                               sendChan("Online Players: " + (int)onlshown + " / " + LoginServerThread.getInstance().getMaxPlayer());
+                sendAdminChan("Online Players: " + (int)onl + " / " + LoginServerThread.getInstance().getMaxPlayer());
+                       }
+                       else if (msg.equals("!gmlist"))
+                       {
+                               if (GmListTable.getInstance().getAllGms(false).size() <= 0)
+                                       sendChan("There are not any GMs that are providing customer service currently");
+                               else
+                                       for (L2PcInstance gm : GmListTable.getInstance().getAllGms(false))
+                                               sendChan(gm.getName());
+                       }
+                       else if (chan.equalsIgnoreCase(channel))
+                       {
+                           CreatureSay cs = new CreatureSay(0, 1, "[IRC]" + u.getNick(), msg);
+                           for (L2PcInstance player : L2World.getInstance().getAllPlayers())
+                           {
+                               player.sendPacket(cs);
+                           }
+                       }
+            else if (chan.equalsIgnoreCase(adminchan))
+            {
+                if (msg.startsWith("!"))
+                {
+                    IIrcCommandHandler ircch = IrcCommandHandler.getInstance().getIrcCommandHandler(msg);
+                    
+                    if (ircch != null)
+                        ircch.useIrcCommand(msg, u.getNick(), null, _authedGms.containsKey(u.getUsername()));
+                }
+                else
+              {
+                    CreatureSay cs = new CreatureSay(0, 1, "[IRC]" + u.getNick(), msg);
+                    for (L2PcInstance player : L2World.getInstance().getAllPlayers())
+                    {
+                        player.sendPacket(cs);
+                    }
+                }
+            }
+                       else
+                       {
+                               if (msg.startsWith("ident"))
+                               {
+                                       StringTokenizer st = new StringTokenizer(msg);
+                                       st.nextToken();
+                                       try
+                                       {
+                                               String username = st.nextToken();
+                                               String password = st.nextToken();
+                                               isAccountValid(username,password,u.getUsername(),u.getNick(),u.getHost());
+                                       }
+                                       catch(Exception e)
+                                       {
+                                               e.printStackTrace();
+                                       }
+                               }
+                       }
+               }
+
+               public void onQuit(IRCUser u, String msg)
+               {
+                       removeAccount(u.getUsername(),u.getHost());
+               }
+
+               public void onReply(int num, String value, String msg)
+               {
+               }
+
+               public void onTopic(String chan, IRCUser u, String topic)
+               {
+               }
+
+               public void onPing(String p)
+               {
+                       // keep connection alive
+                       conn.doPong(p);
+               }
+
+               public void unknown(String a, String b, String c, String d)
+               {
+                       _log.warning("IRC UNKNOWN: " + a + " b " + c + " " + d);
+               }
+
+               public boolean isConnected()
+               {
+                       return isconnected;
+               }
+       }
+       
+       protected void isAccountValid(String account,String password,String ident,String nick,String ip)
+       {
+               boolean ok = false;
+               java.sql.Connection con = null;
+               try
+               {
+                       MessageDigest md = MessageDigest.getInstance("SHA");
+                       byte[] raw = password.getBytes("UTF-8");
+                       byte[] hash = md.digest(raw);
+                       byte[] expected = null;
+                       int access = 0;
+                       con = L2DatabaseFactory.getInstance().getConnection();
+                       PreparedStatement statement = con.prepareStatement("SELECT password, access_level FROM irc WHERE login=?");
+                       statement.setString(1, account);
+                       ResultSet rset = statement.executeQuery();
+                       if (rset.next())
+                       {
+                               expected = Base64.decode(rset.getString("password"));
+                               access = rset.getInt("access_level");
+                       }
+                       rset.close();
+                       statement.close();
+                       
+                       if (expected == null)
+                               return;
+                       else
+                       {
+                               if (access <= 0)
+                                       return;
+                               
+                               ok = true;
+                               for (int i = 0; i < expected.length; i++)
+                               {
+                                       if (hash[i] != expected[i])
+                                       {
+                                               ok = false;
+                                               break;
+                                       }
+                               }
+                       }
+                       if (ok)
+                       {
+                               if (!_authedGms.containsKey(ident))
+                               {
+                                       _authedGms.put(ident, ip);
+                                       send(nick,"Successfully Authed!");
+                               }
+                               else
+                               {
+                                      send(nick,"Already Authed!");
+                               }
+                               
+                       }
+                       else
+                       {
+                               send(nick,"Authentication Failed!");
+                       }
+               }
+               catch (Exception e)
+               {
+                       e.printStackTrace();
+               }
+               finally
+               {
+                       try
+                       {
+                               con.close();
+                       }
+                       catch (Exception e)
+                       {
+                       }
+               }
+       }
+       
+       protected void removeAccount(String nick,String ip)
+       {
+               if (_authedGms.containsKey(nick))
+                       _authedGms.remove(nick);
+               else if (_authedGms.containsValue(ip))
+                       _authedGms.remove(ip);
+       }
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/Shutdown.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/Shutdown.java	(revision 62)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/Shutdown.java	(working copy)
@@ -300,11 +300,11 @@
 	public void startShutdown(L2PcInstance activeChar, int seconds, boolean restart) {
 		_log.warning("GM: "+activeChar.getName()+"("+activeChar.getObjectId()+") issued shutdown command. " + MODE_TEXT[_shutdownMode] + " in "+seconds+ " seconds!");
 
-		if (restart) {
+		if (restart) 
             _shutdownMode = GM_RESTART;
-        } else {
+         else 
             _shutdownMode = GM_SHUTDOWN;
-        }
+        
 
         if(_shutdownMode > 0)
         {
@@ -342,12 +342,74 @@
 	}
 
 	/**
+	 * This functions starts a shutdown countdown
+	 * 
+	 * @param activeChar    GM who issued the shutdown command
+     * @param seconds               seconds until shutdown
+	 * @param restart               true if the server will restart after shutdown
+	 */
+	       public void startShutdown(String activeChar, int seconds, boolean restart)
+	       {
+	               _log.warning("GM: "+activeChar+" issued shutdown command. " + MODE_TEXT[_shutdownMode] + " in "+seconds+ " seconds!");
+	               
+	               if (restart)
+	            _shutdownMode = GM_RESTART;
+	        else
+	            _shutdownMode = GM_SHUTDOWN;
+	        
+	               if(_shutdownMode > 0)
+	        {
+	                       switch (seconds)
+	                       {
+	                           case 540:
+	                           case 480:
+	                           case 420:
+	                           case 360:
+	                               case 300:
+	                               case 240:
+	                               case 180:
+	                               case 120:
+	                               case 60:
+	                               case 30:
+	                               case 10:
+	                              case 5:
+	                               case 4:
+	                               case 3:
+	                               case 2:
+	                               case 1:
+	                                       break;
+	                               default:
+	                                       SendServerQuit(seconds);
+	                       }
+	        }
+	
+	               if (_counterInstance != null)
+	                       _counterInstance._abort();
+	               
+	               // the main instance should only run for shutdown hook, so we start a new instance
+	               _counterInstance = new Shutdown(seconds, restart);
+	               _counterInstance.start();
+	       }
+
+	/**
 	 * This function aborts a running countdown
 	 *
 	 * @param activeChar	GM who issued the abort command
 	 */
-	public void abort(L2PcInstance activeChar) {
+	public void abort(L2PcInstance activeChar)
+	{
 		_log.warning("GM: "+activeChar.getName()+"("+activeChar.getObjectId()+") issued shutdown ABORT. " + MODE_TEXT[_shutdownMode] + " has been stopped!");
+		if (_counterInstance != null)
+		                 {
+		                         _counterInstance._abort();
+		                         Announcements _an = Announcements.getInstance();
+		                         _an.announceToAll("Server aborts " + MODE_TEXT[_shutdownMode] + " and continues normal operation!");
+		                 }
+		         }
+		         
+		         public void abort(String activeChar)
+		         {
+		             _log.warning("GM: "+activeChar+" issued shutdown ABORT. " + MODE_TEXT[_shutdownMode] + " has been stopped!");
 		if (_counterInstance != null) {
 			_counterInstance._abort();
 			Announcements _an = Announcements.getInstance();
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/Announcements.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/Announcements.java	(revision 62)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/Announcements.java	(working copy)
@@ -30,6 +30,7 @@
 import net.sf.l2j.Config;
 import net.sf.l2j.gameserver.cache.HtmCache;
 import net.sf.l2j.gameserver.clientpackets.Say2;
+import net.sf.l2j.gameserver.instancemanager.IrcManager;
 import net.sf.l2j.gameserver.model.L2World;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
 import net.sf.l2j.gameserver.network.SystemMessageId;
@@ -207,15 +208,19 @@
 		}
 	}
 
-	public void announceToAll(String text) {
+	public void announceToAll(String text) 
+	{
 		CreatureSay cs = new CreatureSay(0, Say2.ANNOUNCEMENT, "", text);
 
 		for (L2PcInstance player : L2World.getInstance().getAllPlayers())
 		{
 			player.sendPacket(cs);
 		}
+		if(Config.IRC_ENABLED)
+		IrcManager.getInstance().getConnection().sendChan("10Announce: " + text);
 	}
-	public void announceToAll(SystemMessage sm) {
+	public void announceToAll(SystemMessage sm) 
+	{
 
 		for (L2PcInstance player : L2World.getInstance().getAllPlayers())
 		{
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/model/GMAudit.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/model/GMAudit.java	(revision 62)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/model/GMAudit.java	(working copy)
@@ -23,6 +23,7 @@
 import java.util.logging.Logger;
 
 import net.sf.l2j.Config;
+import net.sf.l2j.gameserver.instancemanager.IrcManager;
 import net.sf.l2j.gameserver.lib.Log;
 
 public class GMAudit
@@ -58,6 +59,8 @@
 			{
 				_log.log(Level.SEVERE, "GMAudit for GM " + gmName +" could not be saved: ", e);
 			}
+			if (Config.IRC_ENABLED)
+			IrcManager.getInstance().getConnection().sendAdminChan(today + ">" + gmName + ">" + action + ">" +target + ">" + params);
 		}
 	}
 }
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCModeParser.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCModeParser.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCModeParser.java	(revision 0)
@@ -0,0 +1,293 @@
+/*
+ * IRClib -- A Java Internet Relay Chat library -- class IRCModeParser
+ * Copyright (C) 2002 - 2006 Christoph Schwering <schwering@gmail.com>
+ * 
+ * This library and the accompanying materials are made available under the
+ * terms of the
+ *     - GNU Lesser General Public License,
+ *     - Apache License, Version 2.0 and
+ *     - Eclipse Public License v1.0.
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY.
++ */
+package net.sf.l2j.gameserver.lib.irc;
+
+/**
+ * Parses channel-modes.
+ * <p>
+ * An instance of this class is an argument of the <code>{@link 
+ * org.schwering.irc.lib.IRCEventListener#onMode(String chan, IRCUser user,
+ * IRCModeParser modeParser)}</code>.
+ * It's intended to help the programmer to work with the modes.
+ * <p>
+ * Channelmodes are:
+ * <ul>
+ * <li> +/- o nick </li>
+ * <li> +/- v nick </li>
+ * <li> +/- b banmask </li>
+ * <li> +/- l limit </li>
+ * <li> +/- k key </li>
+ * <li> +/- p </li>
+ * <li> +/- s </li>
+ * <li> +/- i </li>
+ * <li> +/- t </li>
+ * <li> +/- n </li>
+ * <li> +/- m </li>
+ * </ul>
+ * <p>
+ * These are all channel-modes defined in RFC1459. Nevertheless, most networks
+ * provide more channel-modes. This class can handle all modes; it's not
+ * restricted to the rights defined in RFC1459.
+ * 
+ * @author Christoph Schwering &lt;schwering@gmail.com&gt;
+ * @version 1.22
+ * @see IRCEventListener
+ */
+public class IRCModeParser
+{
+       /**
+        * Represents the operators, modes and nicks as they were sent from the IRC
+        * server.
+        */
+       private String _line;
+
+       /**
+        * Contains pluses (<code>+</code>) and minuses (<code>-</code>)
+        * which show if the mode is taken or given.
+        */
+       private char[] operatorsArr;
+
+       /**
+        * This array contains the modes that are set with the operator of the
+        * <code>operatorsArr</code>-array. *
+        */
+       private char[] modesArr;
+
+       /**
+        * Represents the parsed nicks, hostnames, limits or keys in an array of
+        * Strings.
+        */
+       private String[] argsArr;
+
+       // ------------------------------
+       /**
+        * Analyzes the modes and parses them into the parts operators (<code>+</code>
+        * or <code>-</code>), modes (one character) and optional arguments (one
+        * word or number).
+        * 
+        * @param line
+        *            The modes and the arguments; nothing more.
+        */
+      public IRCModeParser(String line)
+       {
+               line = line.trim();
+               this._line = line;
+               int index = line.indexOf(' ');
+               if (index >= 2)
+               { // with arguments
+                       String modes = line.substring(0, index);
+                       String args = line.substring(index + 1);
+                       parse(modes, args); // call real constructor.
+               }
+               else if (line.length() >= 2)
+               { // no arguments
+                       String modes = line;
+                       String args = "";
+                       parse(modes, args);
+               }
+               else
+               { // nothing
+                       argsArr = new String[0];
+                       operatorsArr = new char[0];
+                       modesArr = new char[0];
+               }
+       }
+
+       // ------------------------------
+       /**
+        * Analyzes the modes and parses them into the parts operators (<code>+</code>
+        * or <code>-</code>), modes (one character) and optional arguments (one
+        * word or number).
+        * 
+        * @param modes
+        *            The modes (for example <code>+oo+m-v</code>).
+       * @param args
+        *            The modes' arguments (for example <code>Heinz Hans 
+       *             Thomas</code>).
+        */
+       public IRCModeParser(String modes, String args)
+       {
+               _line = modes + " " + args;
+               parse(modes, args);
+       }
+
+       // ------------------------------
+       /**
+       * Parses the modes into two <code>char</code>-arrays and one
+        * <code>String</code>-array. <br />
+        * The first one contains the operator of the mode (<code>+</code> or
+        * </code>-</code>) and the second one the mode (<code>w</code>,
+        * <code>i</code>, <code>s</code>, <code>o</code> or any other
+        * mode). The <code>String[]</code> contains the nicknames.
+        * 
+        * @param modes
+        *            The modes (for example <code>+oo+m-v</code>).
+        * @param args
+        *            The modes' arguments (for example <code>Heinz Hans Thomas</code>).
+        */
+       private void parse(String modes, String args)
+       {
+               String[] argsTmp = IRCUtil.split(args, ' ');
+               int modesLen = modes.length();
+               int modesCount = getModesCount(modes);
+               char c;
+               char operator = '+'; // any value cause it must be initialized
+               operatorsArr = new char[modesCount];
+               modesArr = new char[modesCount];
+               argsArr = new String[modesCount];
+               // parse and fill the arrays
+               for (int i = 0, j = 0, n = 0; i < modesLen; i++)
+               {
+                       c = modes.charAt(i);
+                       if (c == '+' || c == '-')
+                       {
+                               operator = c;
+                       }
+                       else
+                       {
+                               // add the operator (which was found earlier in the loop)
+                               operatorsArr[n] = operator;
+                               modesArr[n] = c; // add the mode
+                               if ((c == 'o' || c == 'v' || c == 'b' || c == 'k') // come with
+                                                                                                                                       // arg
+                                               || (c == 'l' && operator == '+'))
+                               { // key comes with arg if '+'
+                                       argsArr[n] = (j < argsTmp.length) ? argsTmp[j++] : "";
+                               }
+                               else
+                               {
+                                       argsArr[n] = ""; // null if mode has no argument (for
+                                                                               // example m, p, s)
+                               }
+                               n++; // increase n, not i. n is used to fill the arrays
+                       }
+               }
+       }
+
+       // ------------------------------
+       /**
+        * Returns the amount of modes in the string. This is done by counting all
+        * chars which are not <code>+</code> or <code>-</code>.
+        * 
+        * @param modes
+        *            The modes which are to analyze.
+        * @return The count of modes without operators.
+        */
+       private int getModesCount(String modes)
+       {
+               int count = 0;
+               for (int i = 0, c, len = modes.length(); i < len; i++)
+                       if ((c = modes.charAt(i)) != '+' && c != '-')
+                               count++;
+               return count;
+       }
+
+       // ------------------------------
+       /**
+        * Returns count of modes.
+        * 
+        * @return The count of modes.
+        * @see #getOperatorAt(int)
+        * @see #getModeAt(int)
+        * @see #getArgAt(int)
+        */
+       public int getCount()
+       {
+               return operatorsArr.length;
+       }
+
+       // ------------------------------
+       /**
+        * Returns the operator (<code>+</code> or <code>-</code>) of a given
+        * index.
+        * 
+        * @param i
+        *            The index of the operator you want to get. The index starts
+        *            with <code>1</code> and not with <code>0</code>.
+        * @return The operator at the given index (<code>+</code> or
+        *         <code>-</code>).
+        * @see #getCount()
+        * @see #getModeAt(int)
+        * @see #getArgAt(int)
+        */
+       public char getOperatorAt(int i)
+       {
+               return operatorsArr[i - 1];
+       }
+
+       // ------------------------------
+       /**
+        * Returns the mode (for example <code>o</code>, <code>v</code>,
+        * <code>m</code>, <code>i</code>) of a given index.
+        * 
+        * @param i
+        *            The index of the mode you want to get. The index starts with
+        *            <code>1</code> and not with <code>0</code>.
+        * @return The mode of the given index (for example <code>o</code>,
+        *         <code>v</code>, <code>m</code>, <code>i</code>)
+        * @see #getCount()
+        * @see #getOperatorAt(int)
+        * @see #getArgAt(int)
+        */
+       public char getModeAt(int i)
+       {
+               return modesArr[i - 1];
+       }
+
+       // ------------------------------
+       /**
+        * Returns the nick of a given index.
+        * 
+        * @param i
+        *            The index of the argument you want to get. The index starts
+        *            with <code>1</code> and not with <code>0</code>.
+        * @return The argument you requested. It's <code>""</code> if there's no
+        *         argument at this index (for example <code>+m</code> for
+        *         moderated has never an argument).
+        * @see #getCount()
+        * @see #getOperatorAt(int)
+        * @see #getModeAt(int)
+        */
+       public String getArgAt(int i)
+       {
+               return argsArr[i - 1];
+       }
+
+       // ------------------------------
+       /**
+        * Returns the line as it was sent from the IRC server. The line contains
+        * the the operators, the modes and the nicknames, but not the channel or
+        * the nickname who executed the MODE command!
+        * 
+        * @return The line which was set as argument when the parser was
+        *         initialized.
+        */
+       public String getLine()
+       {
+               return _line;
+       }
+
+       // ------------------------------
+       /**
+        * Generates a <code>String</code> with some information about the
+        * instance of <code>IRCModeParser</code>. Its format is:
+        * <code>classname[line]</code>.
+        * 
+        * @return A <code>String</code> with information about the instance.
+        */
+       @Override
+       public String toString()
+       {
+               return getClass().getName() + "[" + getLine() + "]";
+       }
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCEventAdapter.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCEventAdapter.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCEventAdapter.java	(revision 0)
@@ -0,0 +1,301 @@
+/*
+ * IRClib -- A Java Internet Relay Chat library -- class IRCEventAdapter
+ * Copyright (C) 2002 - 2006 Christoph Schwering <schwering@gmail.com>
+ * 
+ * This library and the accompanying materials are made available under the
+ * terms of the
+ *     - GNU Lesser General Public License,
+ *     - Apache License, Version 2.0 and
+ *     - Eclipse Public License v1.0.
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY.
+ */
+
+package net.sf.l2j.gameserver.lib.irc;
+
+/**
+ * Adapts the events of the <code>IRCEventListener</code> interface.
+ * <p>
+ * Supported events:
+ * <ul>
+ * <li>Connect</li>
+ * <li>Disconnect</li>
+ * <li>Error</li>
+ * <li>Invite</li>
+ * <li>Join</li>
+ * <li>Kick</li>
+ * <li>Private Message</li>
+ * <li>Mode (Chan)</li>
+ * <li>Mode (User)</li>
+ * <li>Nick</li>
+ * <li>Notice</li>
+ * <li>Numeric Reply</li>
+ * <li>Numeric Error</li>
+ * <li>Part</li>
+ * <li>Ping</li>
+ * <li>Quit</li>
+ * <li>Topic</li>
+ * </ul>
+ * <p>
+ * For other, unkown events there's the <code>unknown</code>-method.
+ * @author Christoph Schwering &lt;schwering@gmail.com&gt;
+ * @version 1.63
+ * @see IRCEventListener
+ */
+public class IRCEventAdapter implements IRCEventListener {
+       
+       /** 
+        * The default and only constructor does nothing. 
+        */
+       public IRCEventAdapter() {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when the own connection is successfully established. 
+        * This is the case when the first PING? is received. <br />
+        * This happens between the connection is opened with a socket and the 
+        * connection is registered: The client sends his information to the server 
+        * (nickname, username). The server says hello to you by sending you 
+        * some <code>NOTICE</code>s. And if your nickname is invalid or in use or 
+        * anything else is wrong with your nickname, it asks you for a new one.
+        */
+       public void onRegistered() {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when the own connection is broken.
+        */
+       public void onDisconnected() {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when an <code>ERROR</code> command is received.
+        * @param msg The message of the error.
+        */
+       public void onError(String msg) {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when a numeric error is received.
+        * The server often sends numeric errors (wrong nickname etc.). 
+        * The <code>msg</code>'s format is different for every reply. All replies'
+        * formats are described in the {@link org.schwering.irc.lib.IRCUtil}. 
+        * @param num The identifier (usually a 3-digit number).
+        * @param msg The message of the error.
+        */
+       public void onError(int num, String msg) {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when somebody is invited to a channel.
+        * @param chan The channel the user is invited to.
+        * @param user The user who invites another. Contains nick, username and host.
+        * @param passiveNick The nickname of the user who is invited by another user 
+        *                    (passive).
+        */
+       public void onInvite(String chan, IRCUser user, String passiveNick) {
+               // nothing
+       }
+       
+// ------------------------------
+      
+       /** 
+        * Fired when somebody joins a channel.
+        * @param chan The channel the person joins.
+        * @param user The user who joins. Contains nick, username and host.
+        */
+       public void onJoin(String chan, IRCUser user) {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when somebody is kicked from a channel.
+        * @param chan The channel somebody is kicked from.
+        * @param user The user who kicks another user from a channel. 
+        *             Contains nick, username and host.
+        * @param passiveNick The nickname of the user who is kicked from a channel 
+        *                    (passive).
+        * @param msg The message the active user has set. This is <code>""</code> if 
+        *            no message was set.
+        */
+       public void onKick(String chan, IRCUser user, String passiveNick, 
+                       String msg) {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when an operator changes the modes of a channel. 
+        * For example, he can set somebody as an operator, too, or take him the 
+        * oper-status. 
+        * Also keys, moderated and other channelmodes are fired here.
+        * @param chan The channel in which the modes are changed. 
+        * @param user The user who changes the modes. 
+        *             Contains nick, username and host.
+        * @param modeParser The <code>IRCModeParser</code> object which contains the 
+        *                   parsed information about the modes which are changed. 
+        */
+       public void onMode(String chan, IRCUser user, IRCModeParser modeParser) {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when somebody changes somebody's usermodes. 
+        * Note that this event is not fired when a channel-mode is set, for example
+        * when someone sets another user as operator or the mode moderated.
+        * @param user The user who changes the modes of another user or himself. 
+        *             Contains nick, username and host.
+        * @param passiveNick The nickname of the person whose modes are changed by 
+        *                    another user or himself. 
+        * @param mode The changed modes which are set.
+        */
+       public void onMode(IRCUser user, String passiveNick, String mode) {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when somebody changes his nickname successfully.
+        * @param user The user who changes his nickname. 
+        *             Contains nick, username and host.
+        * @param newNick The new nickname of the user who changes his nickname.
+        */
+       public void onNick(IRCUser user, String newNick) {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when somebody sends a <code>NOTICE</code> to a user or a group. 
+        * @param target The channel or nickname the user sent a <code>NOTICE</code> 
+        *               to.
+        * @param user The user who notices another person or a group. 
+        *             Contains nick, username and host.
+        * @param msg The message.
+        */
+       public void onNotice(String target, IRCUser user, String msg) {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when somebody parts from a channel.
+        * @param chan The channel somebody parts from.
+        * @param user The user who parts from a channel. 
+        *             Contains nick, username and host.
+        * @param msg The part-message which is optionally. 
+        *            If it's empty, msg is <code>""</code>.
+        */
+       public void onPart(String chan, IRCUser user, String msg) {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when a <code>PING</code> comes in. 
+        * The IRC server tests in different periods if the client is still there by 
+        * sending PING &lt;ping&gt;. The client must response PONG &lt;ping&gt;.
+        * @param ping The ping which is received from the server.
+        */
+       public void onPing(String ping) {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when a user sends a <code>PRIVMSG</code> to a user or to a
+        * group.
+        * @param target The channel or nickname the user sent a <code>PRIVMSG</code> 
+        *               to.
+        * @param user The user who sent the <code>PRIVMSG</code>. 
+        *             Contains nick, username and host.
+        * @param msg The message the user transmits.
+        */
+       public void onPrivmsg(String target, IRCUser user, String msg) {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when somebody quits from the network.
+        * @param user The user who quits. Contains nick, username and host.
+        * @param msg The optional message. <code>""</code> if no message is set by 
+        *            the user.
+        */
+       public void onQuit(IRCUser user, String msg) {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when a numeric reply is received. 
+        * For example, <code>WHOIS</code> queries are answered by the server with 
+        * numeric replies. 
+        * The <code>msg</code>'s format is different for every reply. All replies'
+        * formats are described in the {@link org.schwering.irc.lib.IRCUtil}. 
+        * The first word in the <code>value</code> is always your own nickname! 
+        * @param num The numeric reply. 
+        * @param value The first part of the message.
+        * @param msg The main part of the message.
+        */
+       public void onReply(int num, String value, String msg) {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Fired when the topic is changed by operators. 
+        * Note that the topic is given as a numeric reply fired in 
+        * <code>onReply</code> when you join a channel.
+        * @param chan The channel where the topic is changed. 
+        * @param user The user who changes the topic. 
+        *             Contains nick, username and host.
+        * @param topic The new topic.
+        */
+       public void onTopic(String chan, IRCUser user, String topic) {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * This event is fired when the incoming line can not be identified as a known
+        * event.
+        * @param prefix The prefix of the incoming line.
+        * @param command The command of the incoming line.
+        * @param middle The part until the colon (<code>:</code>).
+        * @param trailing The part behind the colon (<code>:</code>).
+        */
+       public void unknown(String prefix, String command, String middle,
+                       String trailing) {
+               // nothing
+       }
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCEventListener.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCEventListener.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCEventListener.java	(revision 0)
@@ -0,0 +1,264 @@
+/*
+ * IRClib -- A Java Internet Relay Chat library -- class IRCEventListener
+ * Copyright (C) 2002 - 2006 Christoph Schwering <schwering@gmail.com>
+ * 
+ * This library and the accompanying materials are made available under the
+ * terms of the
+ *     - GNU Lesser General Public License,
+ *     - Apache License, Version 2.0 and
+ *     - Eclipse Public License v1.0.
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY.
+*/
+
+package net.sf.l2j.gameserver.lib.irc;
+
+import java.util.EventListener;
+
+/**
+ * Used as listener for incoming events like messages.
+ * <p>
+ * The <code>IRCEventListener</code> is used by the 
+ * <code>IRCConnection.addEventListener(IRCEventListener)</code> method to add
+ * a listener which listens to the connection for incoming IRC events like 
++ * <code>PRIVMSG</code>s or numeric replies.
+ * <p>
+ * Supported events:
+ * <ul>
+ * <li>Connect</li>
+ * <li>Disconnect</li>
+ * <li>Error</li>
+ * <li>Invite</li>
+ * <li>Join</li>
+ * <li>Kick</li>
+ * <li>Private Message</li>
+ * <li>Mode (Chan)</li>
+ * <li>Mode (User)</li>
+ * <li>Nick</li>
+ * <li>Notice</li>
+ * <li>Numeric Reply</li>
+ * <li>Numeric Error</li>
+ * <li>Part</li>
+ * <li>Ping</li>
+ * <li>Quit</li>
+ * <li>Topic</li>
+ * </ul>
+ * <p>
+ * For other, unkown events there's the <code>unknown</code>-method.
+ * @author Christoph Schwering &lt;schwering@gmail.com&gt;
+ * @version 1.64
+ * @see IRCEventAdapter
+ * @see IRCConnection
+ */
+public interface IRCEventListener extends EventListener, IRCConstants {
+       
+       /** 
+        * Fired when the own connection is successfully established. 
+        * This is the case when the first PING? is received. <br />
+        * This happens between the connection is opened with a socket and the 
+        * connection is registered: The client sends his information to the server 
+        * (nickname, username). The server says hello to you by sending you 
+        * some <code>NOTICE</code>s. And if your nickname is invalid or in use or 
+        * anything else is wrong with your nickname, it asks you for a new one.
+        */
+       public void onRegistered();
+       
+// ------------------------------
+       
+       /** 
+        * Fired when the own connection is broken.
+        */
+       public void onDisconnected();
+       
+// ------------------------------
+       
+       /** 
+        * Fired when an <code>ERROR</code> command is received.
+        * @param msg The message of the error.
+        */
+       public void onError(String msg);
+       
+// ------------------------------
+       
+       /** 
+        * Fired when a numeric error is received.
+        * The server often sends numeric errors (wrong nickname etc.). 
+        * The <code>msg</code>'s format is different for every reply. All replies'
+        * formats are described in the {@link org.schwering.irc.lib.IRCUtil}. 
+        * @param num The identifier (usually a 3-digit number).
+        * @param msg The message of the error. 
+        */
+       public void onError(int num, String msg);
+       
+// ------------------------------
+       
+       /** 
+        * Fired when somebody is invited to a channel.
+        * @param chan The channel the user is invited to.
+        * @param user The user who invites another. Contains nick, username and host.
+        * @param passiveNick The nickname of the user who is invited by another user 
+        *                    (passive).
+        */
+      public void onInvite(String chan, IRCUser user, String passiveNick);
+       
+// ------------------------------
+       
+       /** 
+        * Fired when somebody joins a channel.
+        * @param chan The channel the person joins.
+        * @param user The user who joins. Contains nick, username and host.
+        */
+       public void onJoin(String chan, IRCUser user);
+       
+// ------------------------------
+       
+       /** 
+        * Fired when somebody is kicked from a channel.
+        * @param chan The channel somebody is kicked from.
+        * @param user The user who kicks another user from a channel. 
+        *             Contains nick, username and host.
+        * @param passiveNick The nickname of the user who is kicked from a channel 
+        *                    (passive).
+        * @param msg The message the active user has set. This is <code>""</code> if 
+        *            no message was set.
+        */
+       public void onKick(String chan, IRCUser user, String passiveNick, String msg);
+       
+// ------------------------------
+       
+       /** 
+        * Fired when an operator changes the modes of a channel. 
+        * For example, he can set somebody as an operator, too, or take him the 
+        * oper-status. 
+        * Also keys, moderated and other channelmodes are fired here.
+        * @param chan The channel in which the modes are changed. 
+        * @param user The user who changes the modes. 
+        *             Contains nick, username and host.
+        * @param modeParser The <code>IRCModeParser</code> object which contains the 
+        *                   parsed information about the modes which are changed. 
+        */
+       public void onMode(String chan, IRCUser user, IRCModeParser modeParser);
+       
+// ------------------------------
+       
+       /** 
+        * Fired when somebody changes somebody's usermodes. 
+        * Note that this event is not fired when a channel-mode is set, for example
+        * when someone sets another user as operator or the mode moderated.
+        * @param user The user who changes the modes of another user or himself. 
+        *             Contains nick, username and host.
+        * @param passiveNick The nickname of the person whose modes are changed by 
+        *                    another user or himself. 
+        * @param mode The changed modes which are set.
+       */
+       public void onMode(IRCUser user, String passiveNick, String mode);
+       
+// ------------------------------
+       
+       /** 
+        * Fired when somebody changes his nickname successfully.
+        * @param user The user who changes his nickname. 
+        *             Contains nick, username and host.
+        * @param newNick The new nickname of the user who changes his nickname.
+        */
+       public void onNick(IRCUser user, String newNick);
+       
+// ------------------------------
+       
+       /** 
+        * Fired when somebody sends a <code>NOTICE</code> to a user or a group. 
+        * @param target The channel or nickname the user sent a <code>NOTICE</code> 
+        *               to.
+        * @param user The user who notices another person or a group. 
+        *             Contains nick, username and host.
+        * @param msg The message.
+        */
+       public void onNotice(String target, IRCUser user, String msg);
+       
+// ------------------------------
+       
+       /** 
+        * Fired when somebody parts from a channel.
+        * @param chan The channel somebody parts from.
+        * @param user The user who parts from a channel. 
+        *             Contains nick, username and host.
+        * @param msg The part-message which is optionally. 
+        *            If it's empty, msg is <code>""</code>.
+        */
+       public void onPart(String chan, IRCUser user, String msg);
+       
+// ------------------------------
+       
+       /** 
+        * Fired when a <code>PING</code> comes in. 
+        * The IRC server tests in different periods if the client is still there by 
+        * sending PING &lt;ping&gt;. The client must response PONG &lt;ping&gt;.
+        * @param ping The ping which is received from the server.
+        */
+       public void onPing(String ping);
+       
+// ------------------------------
+       
+       /** 
+        * Fired when a user sends a <code>PRIVMSG</code> to a user or to a
+        * group.
+        * @param target The channel or nickname the user sent a <code>PRIVMSG</code> 
+        *               to.
+        * @param user The user who sent the <code>PRIVMSG</code>. 
+        *             Contains nick, username and host.
+        * @param msg The message the user transmits.
+        */
+       public void onPrivmsg(String target, IRCUser user, String msg);
+       
+// ------------------------------
+       
+       /** 
+        * Fired when somebody quits from the network.
+        * @param user The user who quits. Contains nick, username and host.
+        * @param msg The optional message. <code>""</code> if no message is set by 
+        *            the user.
+        */
+       public void onQuit(IRCUser user, String msg);
+       
+// ------------------------------
+       
+       /** 
+        * Fired when a numeric reply is received. 
+        * For example, <code>WHOIS</code> queries are answered by the server with 
+        * numeric replies. 
+        * The <code>msg</code>'s format is different for every reply. All replies'
+        * formats are described in the {@link org.schwering.irc.lib.IRCUtil}. 
+        * The first word in the <code>value</code> is always your own nickname! 
+        * @param num The numeric reply. 
+        * @param value The first part of the message.
+        * @param msg The main part of the message.
+        */
+       public void onReply(int num, String value, String msg);
+       
+// ------------------------------
+       
+       /** 
+        * Fired when the topic is changed by operators. 
+        * Note that the topic is given as a numeric reply fired in 
+        * <code>onReply</code> when you join a channel.
+        * @param chan The channel where the topic is changed. 
+        * @param user The user who changes the topic. 
+        *             Contains nick, username and host.
+        * @param topic The new topic.
+        */
+       public void onTopic(String chan, IRCUser user, String topic);
+       
+// ------------------------------
+       
+       /** 
+       * This event is fired when the incoming line can not be identified as a known
+       * event.
+       * @param prefix The prefix of the incoming line.
+       * @param command The command of the incoming line.
+       * @param middle The part until the colon (<code>:</code>).
+       * @param trailing The part behind the colon (<code>:</code>).
+       */
+       public void unknown(String prefix, String command, String middle,
+                       String trailing);
+       
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCParser.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCParser.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCParser.java	(revision 0)
@@ -0,0 +1,559 @@
+/*
+ * IRClib -- A Java Internet Relay Chat library -- class IRCParser
+ * Copyright (C) 2002 - 2006 Christoph Schwering <schwering@gmail.com>
+ * 
+ * This library and the accompanying materials are made available under the
+ * terms of the
+ *     - GNU Lesser General Public License,
+ *     - Apache License, Version 2.0 and
+ *     - Eclipse Public License v1.0.
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY.
+ */
+
+package net.sf.l2j.gameserver.lib.irc;
+
+/**
+ * Parses a line sent from the IRC server.
+ * <p>
+ * Note: Probably this class is unimportant for you. It's used by the
+ * <code>IRCConnection</code> to parse incoming lines. Nevertheless I declared
+ * it as <code>public</code> because you might want to use it to parse IRC 
+ * command-shortcuts like <code>MSG</code> instead of <code>PRIVMSG</code> in 
+ * your client.<br />
+ * The following text goes on with the description of the class and what it
+ * does.
+ * <p>
+ * According with RFC1459 it divides the line into a prefix, a command and 
+ * its parameters.
+ * <p>
+ * The prefix is only given if a line starts with a <code>:</code> (colon) 
+ * and is used to indicate from where the line is send.
+ * <p>
+ * The next word in the line (if no prefix exists it is the first, else the 
+ * second word) is the command.
+ * The command is eiter a valid IRC command or a three-digit number which 
+ * represents a numeric reply or a numeric error.
+ * <p>
+ * The parameters are divided into a middle and a trailing part. 
+ * In the middle part one word means one parameter while the trailing part is 
+ * just one parameter independent from the amount of words in it. 
+ * If there is a  "<code>&nbsp;:</code>" (space+colon) in the line, this point 
+ * means the beginning of the trailing.
+ * If there is no such space+colon, the trailing is just the last word. 
+ * All words behind the space+colon mean just one parameter.
+ * If there is only one parameter given (the parameter is the first, the last 
+ * and the only one), the parameter is available as trailing (with 
+ * <code>getTrailing</code>), not as middle!
+ * <p>
+ * One line may have up to 15 parameters. Therefore up to 14 are middle and 
+ * one is the trailing.
+ * <p>
+ * The line may have up to 510 characters plus the CR-LF (carriage return - 
+ * line feed) which trails the incoming line. 
+ * <p>
+ * The following extract of the RFC1459 shows the message format in BNF:
+ * <blockquote cite="RFC1459"><code>
+ * &lt;message&gt;&nbsp;&nbsp;::=
+ * [':' &lt;prefix&gt; &lt;SPACE&gt; ] &lt;command&gt; &lt;params&gt; 
+ * &lt;crlf&gt; <br />
+ * &lt;prefix&gt;&nbsp;&nbsp;&nbsp;::=
+ * &lt;servername&gt; | &lt;nick&gt; 
+ * [ '!' &lt;username&gt; ] [ '@' &lt;host&gt; ]
+ * <br />
+ * &lt;command&gt;&nbsp;&nbsp;::=
+ * &lt;letter&gt; { &lt;letter&gt; } | &lt;number&gt; &lt;number&gt; 
+ * &lt;number&gt; <br />
+ * &lt;SPACE&gt;&nbsp;&nbsp;&nbsp;&nbsp;::=
+ * ' ' { ' ' }<br />
+ * &lt;params&gt;&nbsp;&nbsp;&nbsp;::=
+ * &lt;SPACE&gt; [ ':' &lt;trailing&gt; | &lt;middle&gt; &lt;params&gt; ] <br />
+ * &lt;middle&gt;&nbsp;&nbsp;&nbsp;::=
+ * &lt;Any *non-empty* sequence of octets not including SPACE or NUL or CR or 
+ * LF, the first of which may not be ':'&gt; <br />
+ * &lt;trailing&gt;&nbsp;::=
+ * &lt;Any, possibly *empty*, sequence of octets not including NUL or CR or 
+ * LF&gt; <br />
++ * &lt;crlf&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;::=
++ * CR LF<br />
++ * </code></blockquote>
++ * @author Christoph Schwering &lt;schwering@gmail.com&gt;
++ * @version 3.22
++ * @see IRCConnection
++ */
+public class IRCParser {
+       
+       /** 
+        * The <code>StringBuffer</code> contains the line which was analyzed. 
+        */
+       private StringBuffer buf;
+       
+       /**
+        * The length of the line. 
+        */
+       private int len;
+       
+       /**
+        * The prefix, which is parsed out in the constructor. 
+        */
+       private String prefix;
+       
+       /**
+        * The command, which is parsed out in the constructor. 
+        */
+       private String command;
+       
+       /**
+        * The middle, which is parsed out in the constructor. 
+        */
+       private String middle;
+       
+       /**
+        * The trailing, which is parsed out in the constructor. The trailing is the 
+        * part behind the colon (<code>:</code>) or the last parameter. 
+        */
+       private String trailing;
+       
+       /**
+        * The parameters' array. It's not initialized in the constructor because of 
+        * rare access. The methods which use and need this parameter-array 
+        * (getParametersCount, getParameter, getParameterFrom etc.) initialize this 
+        * array by calling initParameters, if the array isn't initialized yet.
+        */
+       private String[] parameters;
+       
+// ------------------------------
+       
+       /**
+        * Parses the line after erasing all mIRC color codes.
+        * This constructor is a shorthand for <code>IRCParser(line, false)</code>.
+        * @param line The line which will be parsed. 
+        */
+       public IRCParser(String line) {
+               this(line, false);
+       }
+       
+// ------------------------------
+       
+       /**
+        * The main constructor. 
+        * Parses prefix, command, middle and trailing.
+        * @param line The line which will be parsed. 
+        * @param colorsEnabled If <code>false</code>, mIRC color codes are parsed out
+        *                      by using <code>IRCUtil.parseColors</code> method. 
+        */
+       public IRCParser(String line, boolean colorsEnabled) {
+               int index = 0;
+               int trail;
+               
+               buf = new StringBuffer(line);
+               if (!colorsEnabled)
+                       buf = IRCUtil.parseColors(buf);
+               len = buf.length();
+               
+               // prefix
+               if (buf.charAt(0) == ':') {
+                       prefix = buf.substring(1, (index = indexOf(' ', index)));
+                       index++;
+               }
+               
+               while (buf.charAt(index) == ' ')
+                       index++;
+               
+               // command
+               command = buf.substring(index, ((index = indexOf(' ', index)) != -1) 
+                               ? index : (index = len));
+               
+               while (index < len && buf.charAt(index) == ' ')
+                       index++;
+               index--;
+               
+               // middle & trailing
+               if ((trail = indexOf(" :", index)) != -1)
+                       trailing = buf.substring(trail + 2, len);
+               else if ((trail = lastIndexOf(' ')) != -1 && trail >= index) 
+                       trailing = buf.substring(trail + 1, len);
+               middle = (index < trail) ? buf.substring(index + 1, trail) : "";
+               
+               // save
+               prefix = (prefix != null) ?  prefix : "";
+               command = (command != null) ?  command : "";
+               middle = (middle != null) ?  middle : "";
+               trailing = (trailing != null) ?  trailing : "";
+       }
+       
+// ------------------------------
+       
+       /**
+        * Searches for a char in the <code>StringBuffer buf</code> from a given index
+        * and returns its index.
+        * @param c The char to search.
+        * @param i The index the method will start searching at.
+        * @return The index of the searched char. 
+        */
+       private int indexOf(int c, int i) {
+               while (i < len)
+                       if (buf.charAt(i++) == c)
+                               return --i;
+               return -1;
+       }
+       
+// ------------------------------
+       
+       /**
+        * Searches for a string in the <code>StringBuffer buf</code> from a given 
+        * index and returns its beginning index.
+        * @param str The string to search.
+        * @param i The index the method will start searching at.
+        * @return The index of the searched string.
+        */
+       private int indexOf(String str, int i) {
+               int sublen = str.length();
+               int index = -1;
+               int j;
+               for ( ; i < len; i++) 
+                       for (index = i, j = 0; i < len && j < sublen; i++, j++)
+                               if (buf.charAt(i) != str.charAt(j))
+                                      break;
+                               else if (j + 1 == sublen) 
+                                       return index;
+               return -1;
+       }
+       
+// ------------------------------
+       
+       /**
+        * Searches for a given char in the <code>StringBuffer buf</code>. <br />
+        * It starts at the end. <br />
+        * Note: The method expects a character which is not <code>c</code> before
+        * it can return an index. Thus in a string like "<code>nick moor&nbsp;&nbsp;
+        * &nbsp;&nbsp;</code>" with four trailing spaces 
+        * <code>lastIndexOf(' ')</code> does not return the the index of the last 
+        * space. It first waits for characters which are not a space (r, o, o, m) and
+        * then returns the index of the next space: the space between 
+       * <code>nick</code> and <code>moor</code>. By this, also in lines with 
++        * trailing whitespace the trailing-part is correctly recognized.
+        * @param c The char to search.
+       * @return The last index of the searched char.
+        */
+       private int lastIndexOf(int c) {
+               int i = len;
+               boolean ok = false;
+               while (i > 0)
+                       if (buf.charAt(--i) != c)
+                               ok = true;
+                       else if (ok)
+                               return i;
+               return -1;
+       }
+       
+// ------------------------------
+       
+       /**
+        * Initializes the <code>parameters[]</code>. 
+        * This method is called by <code>getParam</code>, <code>getParamFrom</code> 
+        * and <code>getParamTo</code>, if the <code>parameters[]</code> aren't 
+        * initialized yet.<br />
+        * The method splits the <code>middle</code> into all words using and appends 
+        * the trailing as last parameter. It uses the <code>IRCUtil.split</code>
+        * method.
+        */
+       private void initParameters() {
+               parameters = IRCUtil.split(middle, ' ', trailing);
+       }
+       
+// ------------------------------
+       
+       /**
+        * Returns the line's prefix. A prefix is the part which contains information
+        * about the sender of the line. If no prefix is set, <code>""</code> is 
+        * returned; but in fact there's always a prefix.
+        * @return The line's prefix.
+        */
+      public String getPrefix() {
+               return prefix;
+       }
+       
+// ------------------------------
+       
+       /**
+        * Returns the line's command.
+        * @return The line's command.
+        */
+       public String getCommand() {
+              return command;
+       }
+       
+// ------------------------------
+       
+       /**
+        * Returns the line's middle.
+        * @return The line's middle.
+       */
+       public String getMiddle() {
+               return middle;
+       }
+       
+// ------------------------------
+       
+       /**
+        * Returns the line's trailing.
+        * @return The line's trailing.
+        */
+       public String getTrailing() {
+               return trailing;
+       }
+       
+// ------------------------------
+       
+       /**
+        * Returns the unparsed line. It looks exacttly as the server sent it, but
+        * if colors are disabled and therefore already parsed out by 
+        * IRCUtil.parseColors, the colors are not included in here.
+       * @return The line.
+        */
+       public String getLine() {
+               return buf.toString();
+       }
+       
+// ------------------------------
+       
+       /**
+        * Returns the line's parameters which consists of the middle and the 
+        * trailing.
+        * @return The line's parameters.
+        */
+       public String getParameters() {
+               return middle + 
+               ((middle.length() != 0 && trailing.length() != 0) ? " " : "") + 
+               trailing;
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Returns the nickname of the person who sent the line 
+        * or the servername of the server which sent the line. <br />
+        * It is found in the prefix which always looks like that:<br />
+        * <code>
+        * &lt;servername&gt; | &lt;nick&gt; 
+        * [ '!' &lt;username&gt; ] [ '@' &lt;host&gt; ]
+        * </code><br /><br />
+        * If no prefix is given in the whole line, <code>null</code> is returned.
+        * <br /><br />
+        * <b>Note:</b> This method is totally equal to <code>getServername</code>!
+        * <br />
+        * <b>Note:</b> There is also the method <code>getUser</code> which returns
+        * an <code>IRCUser</code> object which holds the nickname, username and host.
+        * By the way, the <code>getUser</code> uses the <code>getNick</code>, 
+        * <code>getUsername</code> and <code>getHost</code> methods to create this
+       * object.
+        * @return The nickname or the servername of the line. If no prefix is given,
+        *         <code>null</code> is returned.
+        * @see #getServername()
+        * @see #getUsername()
+        * @see #getHost()
+        * @see #getUser()
+        */
+       public String getNick() {
+               int i = prefix.indexOf('!');
+               if (i != -1 || (i = prefix.indexOf('@')) != -1)
+                       return prefix.substring(0, i); 
+               return (prefix.length() != 0) ? prefix : null;
+       }
+      
+// ------------------------------
+      
+       /** 
+        * Returns the servername of the server which sent the line 
+        * or the nickname of the person who sent the line. <br />
+        * It is found in the prefix which always looks like that:<br />
+        * <code>
+        * &lt;servername&gt; | &lt;nick&gt; 
+        * [ '!' &lt;username&gt; ] [ '@' &lt;host&gt; ]
+        * </code><br /><br />
+        * If no prefix is given in the whole line, <code>null</code> is returned.
+        * <br /><br />
+        * <b>Note:</b> This method is totally equal to <code>getNick</code>!
+        * <br />
+        * <b>Note:</b> There is also the method <code>getUser</code> which returns
+        * an <code>IRCUser</code> object which holds the nickname, username and host.
+        * By the way, the <code>getUser</code> uses the <code>getNick</code>, 
+        * <code>getUsername</code> and <code>getHost</code> methods to create this
+        * object.
+        * @return The servername or the nickname of the line. If no prefix is given,
+        *         <code>null</code> is returned.
+       * @see #getNick()
+        * @see #getUser()
+        */
+       public String getServername() {
+               return getNick();
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Returns the username of the person who sent the line.<br />
+        * It is found in the prefix which always looks like that:<br />
+        * <code>
+        * &lt;servername&gt; | &lt;nick&gt; 
+        * [ '!' &lt;username&gt; ] [ '@' &lt;host&gt; ]
+        * </code><br /><br />
+        * If the username is not specified, this method returns <code>null</code>.
+        * <br />
+        * <b>Note:</b> There is also the method <code>getUser</code> which returns
+        * an <code>IRCUser</code> object which holds the nickname, username and host.
+        * By the way, the <code>getUser</code> uses the <code>getNick</code>, 
+        * <code>getUsername</code> and <code>getHost</code> methods to create this
+        * object.
+        * @return The username of the line; <code>null</code> if it's not given.
+        * @see #getNick()
+        * @see #getHost()
+        * @see #getUser()
+        */
+       public String getUsername() {
+               int i = prefix.indexOf('!') + 1;
+               if (i != 0) {
+                       int j = prefix.indexOf('@', i); 
+                       return prefix.substring(i, (j != -1) ? j : prefix.length()); 
+               }
+               return null;
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Returns the host of the person who sent the line.<br />
+        * It is found in the prefix which always looks like that:<br />
+        * <code>
+        * &lt;servername&gt; | &lt;nick&gt; 
+        * [ '!' &lt;username&gt; ] [ '@' &lt;host&gt; ]
+        * </code><br /><br />
+        * If the host is not specified, this method returns <code>null</code>.
+        * <br />
+        * <b>Note:</b> There is also the method <code>getUser</code> which returns
+        * an <code>IRCUser</code> object which holds the nickname, username and host.
+        * By the way, the <code>getUser</code> uses the <code>getNick</code>, 
+        * <code>getUsername</code> and <code>getHost</code> methods to create this
+        * object.
+        * @return The host of the line; <code>null</code> if it's not given.
+        * @see #getNick()
+        * @see #getUsername()
+        * @see #getUser()
+        */
+       public String getHost() {
+               int i = prefix.indexOf('@') + 1;
+               if (i != 0)
+                      return prefix.substring(i, prefix.length()); 
+               return null;
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Returns a new <code>IRCUser</code> object.
+        * This method is equal to <code>new IRCUser(IRCParser.getNick(), 
+        * IRCParser.getUsername(), IRCParser.getHost())</code>. See those methods to
+        * learn which value they return if they are not set. 
+        * @return A new <code>IRCUser</code> object with exactly those values which
+        *         are returned by the <code>getNick</code>, <code>getUsername</code> 
+        *         and <code>getHost</code> methods.
+        * @see #getNick()
+        * @see #getUsername()
+        * @see #getHost()
+       */
+       public IRCUser getUser() {
+               return new IRCUser(getNick(), getUsername(), getHost());
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Gets count of parameters.
+        * If <code>parameters</code> isn't initialized yet, it calls 
+        * <code>initParameters</code> to do that.
+        * @return The number of parameters. 
+        */
+       public int getParameterCount() {
+               if (parameters == null) 
+                       initParameters();
+               return parameters.length;
+       }
+       
+// ------------------------------
+      
+       /** 
+        * Get one parameter of the line.
+        * If <code>parameters</code> isn't initialized yet, it calls 
+        * <code>initParameters</code> to do that.
+        * @param i The index of the parameter you want to get. The index starts with 
+        *          1 and not with 0.
+        * @return The <code>i</code>th parameter. If <code>i</code> is out of bounds,
+        *         <code>""</code> is returned. 
+        */
+       public String getParameter(int i) {
+               if (parameters == null) 
+                       initParameters();
+               --i;
+               if (i >= 0 && i < parameters.length)
+                       return parameters[i];
+               else
+                       return "";
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Grabs the line's parameters from the <code>i</code>th to the last 
+        * parameter (including the <code>i</code>th).
+        * If <code>parameters</code> isn't initialized yet, it calls 
+        * <code>initParameters</code> to do that.
+        * @param i The index of the first parameter you want to get. 
+        * @return All parameters behind another beginning at the <code>i</code>th. 
+        *         If <code>i</code> is out of bounds, <code>""</code> is returned. 
+        */
+       public String getParametersFrom(int i) {
+               if (parameters == null) 
+                       initParameters();
+               StringBuffer params = new StringBuffer();
+               for (i--; i < parameters.length; i++)
+                       params.append(parameters[i] +" ");
+               return params.toString();
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Grabs the line's parameters from the first to the <code>i</code>th 
+        * parameters (including the <code>i</code>th).
+        * If <code>parameters</code> isn't initialized yet, it calls 
+        * <code>initParameters</code> to do that.
+        * @param i The index of the last parameter you want to get. 
+        * @return All parameters beginning at the first and ending at the 
+        *         <code>i</code>th.  If <code>i</code> is out of bounds, 
+        *         <code>""</code> is returned. 
+        */
+       public String getParametersTo(int i) {
+               if (parameters == null) 
+                       initParameters();
+               StringBuffer params = new StringBuffer();
+               int max = (i < parameters.length) ? i : parameters.length;
+               for (i = 0; i < max; i++)
+                       params.append(parameters[i] +" ");
+               return params.toString();
+       }
+       
+// ------------------------------
+       
+       /**
+        * Generates a <code>String</code> with some information about the instance of
+        * <code>IRCParser</code>.<br />
+        * Its format is: <code>classname[prefix,command,middle,trailing]</code>.
+        * @return A <code>String</code> with information about the instance.
+        */
+       @Override
+       public String toString() {
+               return getClass().getName() +"["+ prefix +","+ command +","+ middle +","+ 
+               trailing +"]";
+       }
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCConstants.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCConstants.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCConstants.java	(revision 0)
@@ -0,0 +1,1402 @@
+package net.sf.l2j.gameserver.lib.irc;
+
+/**
+ * Contains constants: reply codes, error codes and mIRC color codes.
+ * @author Christoph Schwering &lt;schwering@gmail.com&gt;
+ * @since 1.10
+ * @version 1.00
+ * @see IRCEventListener#onError(int, String)
+ * @see IRCEventListener#onReply(int, String, String)
+ */
+public interface IRCConstants {
+       
+       /**
+        * Usually the first replies when you're connected.
+        */
+       public static final int RPL_WELCOME = 001;
+       
+       /**
+        * Usually the first replies when you're connected.
+        */
+       public static final int RPL_YOURHOST = 002;
+       
+       /**
+        * Usually the first replies when you're connected.
+        */
+       public static final int RPL_CREATED = 003;
+       
+       /**
+        * Usually the first replies when you're connected.
+        */
+       public static final int RPL_MYINFO = 004;
+       
+       /**
+        * Usually the first replies when you're connected.
+        */
+       public static final int RPL_ISUPPORT = 005;
+       
+       
+       /**
+        * Used to indicate the nickname parameter supplied to 
+        * a command is currently unused.
+        */
+       public static final int ERR_NOSUCHNICK = 401;
+       
+       /**
+        * Format: "&lt;server name&gt; No such server". <br />
+        * Used to indicate the server name given currently
+        * doesn't exist.
+        */
+       public static final int ERR_NOSUCHSERVER = 402;
+       
+       /**
+        * Format: "&lt;channel name&gt; No such channel". <br />
+        * Used to indicate the given channel name is invalid.
+        */
+       public static final int ERR_NOSUCHCHANNEL = 403;
+       
+       /**
+        * Format: "&lt;channel name&gt; Cannot send to channel". <br />
+        * Sent to a user who is either (a) not on a channel
+        * which is mode +n or (b) not a chanop (or mode +v) on
+        * a channel which has mode +m set and is trying to send
+        * a PRIVMSG message to that channel.
+        */
+       public static final int ERR_CANNOTSENDTOCHAN = 404;
+       
+       /**
+        * Format: "&lt;channel name&gt; You have joined too many
+        * channels". <br />
+        * Sent to a user when they have joined the maximum
+        * number of allowed channels and they try to join
+        * another channel.
+        */
+       public static final int ERR_TOOMANYCHANNELS = 405;
+       
+       /**
+        * Format: "&lt;nickname&gt; There was no such nickname". <br />
+        * Returned by WHOWAS to indicate there is no history
+        * information for that nickname.
+       */
+       public static final int ERR_WASNOSUCHNICK = 406;
+      
+       
+       /**
+        * Format: "&lt;target&gt; Duplicate recipients. No message delivered". <br />
+        * Returned to a client which is attempting to send a PRIVMSG/NOTICE using 
+        * the user@host destination format and for a user@host which has several 
+        * occurrences.
+        */
+       public static final int ERR_TOOMANYTARGETS = 407;
+       
+       /**
+        * Format: "No origin specified". <br />
+        * PING or PONG message missing the originator parameter
+        * which is required since these commands must work
+        * without valid prefixes.
+        */
+       public static final int ERR_NOORIGIN = 409;
+       
+       /**
+        * Format: "No recipient given (&lt;command&gt;)".
+        */
+       public static final int ERR_NORECIPIENT = 411;
+       
+       /**
+        * Format: "No text to send". <br />
+        * 412 - 414 are returned by PRIVMSG to indicate that
+        * the message wasn't delivered for some reason.
+        * ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that
+        * are returned when an invalid use of
+        * "PRIVMSG $&lt;server&gt;" or "PRIVMSG #&lt;host&gt;" is attempted.
+        */
+       public static final int ERR_NOTEXTTOSEND = 412;
+       
+      /**
+       * Format: "&lt;mask&gt; No toplevel domain specified". <br />
+       * 412 - 414 are returned by PRIVMSG to indicate that
+       * the message wasn't delivered for some reason.
+       * ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that
+       * are returned when an invalid use of
+       * "PRIVMSG $&lt;server&gt;" or "PRIVMSG #&lt;host&gt;" is attempted.
+       */
+       public static final int ERR_NOTOPLEVEL = 413;
+       
+       /**
+        * Format: "&lt;mask&gt; Wildcard in toplevel domain". <br />
+        * 412 - 414 are returned by PRIVMSG to indicate that
+        * the message wasn't delivered for some reason.
+        * ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that
+        * are returned when an invalid use of
+        * "PRIVMSG $&lt;server&gt;" or "PRIVMSG #&lt;host&gt;" is attempted.
+        */
+       public static final int ERR_WILDTOPLEVEL = 414;
+       
+       /**
+        * Format: "&lt;command&gt; Unknown command". <br />
+        * Returned to a registered client to indicate that the
+        * command sent is unknown by the server.
+        */
+       public static final int ERR_UNKNOWNCOMMAND = 421;
+       
+       /**
+        * Format: "MOTD File is missing". <br />
+        * Server's MOTD file could not be opened by the server.
+        */
+       public static final int ERR_NOMOTD = 422;
+       
+       /**
+        * Format: "&lt;server&gt; No administrative info available". <br />
+        * Returned by a server in response to an ADMIN message
+        * when there is an error in finding the appropriate
+        * information.
+        */
+       public static final int ERR_NOADMININFO = 423;
+       
+       /**
+        * Format: "File error doing &lt;file op&gt; on &lt;file&gt;". <br />
+        * Generic error message used to report a failed file
+        * operation during the processing of a message.
+        */
+      public static final int ERR_FILEERROR = 424;
+       
+       /**
+        * Format: "No nickname given". <br />
+        * Returned when a nickname parameter expected for a
+        * command and isn't found.
+        */
+       public static final int ERR_NONICKNAMEGIVEN = 431;
+      
+       /**
+        * Format: "&lt;nick&gt; Erroneus nickname". <br />
+        * Returned after receiving a NICK message which contains
+        * characters which do not fall in the defined set.  See
+        * section x.x.x for details on valid nicknames.
+        */
+       public static final int ERR_ERRONEUSNICKNAME = 432;
+       
+       /**
+        * Format: "&lt;nick&gt; Nickname is already in use". <br />
+        * Returned when a NICK message is processed that results
+        * in an attempt to change to a currently existing
+        * nickname.
+        */
+       public static final int ERR_NICKNAMEINUSE = 433;
+       
+       /**
+        * Format: "&lt;nick&gt; Nickname collision KILL". <br />
+        * Returned by a server to a client when it detects a
+        * nickname collision (registered of a NICK that
+        * already exists by another server).
+        */
+       public static final int ERR_NICKCOLLISION = 436;
+       
+       /**
+        * Format: "&lt;nick&gt; &lt;channel&gt; They aren't on that channel". <br />
+        * Returned by the server to indicate that the target
+        * user of the command is not on the given channel.
+        */
+       public static final int ERR_USERNOTINCHANNEL = 441;
+       
+       /**
+        * Format: "&lt;channel&gt; You're not on that channel". <br />
+        * Returned by the server whenever a client tries to
+        * perform a channel effecting command for which the
+        * client isn't a member.
+        */
+       public static final int ERR_NOTONCHANNEL = 442;
+       
+       /**
+        * Format: "&lt;user&gt; &lt;channel&gt; is already on channel". <br />
+        * Returned when a client tries to invite a user to a
+        * channel they are already on.
+        */
+       public static final int ERR_USERONCHANNEL = 443;
+       
+       /**
+        * Format: "&lt;user&gt; User not logged in". <br />
+        * Returned by the summon after a SUMMON command for a
+        * user was unable to be performed since they were not
+        * logged in.
+        */
+       public static final int ERR_NOLOGIN = 444;
+       
+       /**
+        * Format: "SUMMON has been disabled". <br />
+        * Returned as a response to the SUMMON command.  Must be
+        * returned by any server which does not implement it.
+        */
+       public static final int ERR_SUMMONDISABLED = 445;
+       
+       /**
+        * Format: "USERS has been disabled". <br />
+        * Returned as a response to the USERS command.  Must be
+        * returned by any server which does not implement it.
+        */
+       public static final int ERR_USERSDISABLED = 446;
+       
+       /**
+        * Format: "You have not registered". <br /> 
+        * Returned by the server to indicate that the client
+        * must be registered before the server will allow it
+        * to be parsed in detail.
+        */
+       public static final int ERR_NOTREGISTERED = 451;
+       
+       /**
+        * Format: "&lt;command&gt; Not enough parameters". <br />
+        * Returned by the server by numerous commands to
+        * indicate to the client that it didn't supply enough
+        * parameters.
+        */
+       public static final int ERR_NEEDMOREPARAMS = 461;
+       
+       /**
+        * Format: "You may not reregister". <br />
+        * Returned by the server to any link which tries to
+        * change part of the registered details (such as
+        * password or user details from second USER message).
+        */
+       public static final int ERR_ALREADYREGISTRED = 462;
+       
+       /**
+        * Format: "Your host isn't among the privileged". <br />
+        * Returned to a client which attempts to register with
+        * a server which does not been setup to allow
+        * connections from the host the attempted connection
+        * is tried.
+        */
+       public static final int ERR_NOPERMFORHOST = 463;
+       
+       /**
+        * Format: "Password incorrect". <br />
+        * Returned to indicate a failed attempt at registering
+        * a connection for which a password was required and
+        * was either not given or incorrect.
+        */
+       public static final int ERR_PASSWDMISMATCH = 464;
+       
+       /**
+        * Format: "You are banned from this server". <br />
+        * Returned after an attempt to connect and register
+        * yourself with a server which has been setup to
+        * explicitly deny connections to you.
+        */
+        public static final int ERR_YOUREBANNEDCREEP = 465;
+       
+       /**
+        * Format: "&lt;channel&gt; Channel key already set".
+        */
+      public static final int ERR_KEYSET = 467;
+       
+       /**
+        * Format:  "&lt;channel&gt; Cannot join channel (+l)".
+        */
+       public static final int ERR_CHANNELISFULL = 471;
+       
+       /**
+        * Format:  "&lt;char&gt; is unknown mode char to me".
+        */
+       public static final int ERR_UNKNOWNMODE = 472;
+       
+       /**
+        * Format: "&lt;channel&gt; Cannot join channel (+i)".
+        */
+       public static final int ERR_INVITEONLYCHAN = 473;
+       
+       /**
+        * Format:  "&lt;channel&gt; Cannot join channel (+b)".
+       */
+       public static final int ERR_BANNEDFROMCHAN = 474;
+       
+       /**
+        * Format:  "&lt;channel&gt; Cannot join channel (+k)".
+        */
+       public static final int ERR_BADCHANNELKEY = 475;
+       
+       /**
+        * Format:  "Permission Denied- You're not an IRC operator".
+        * Any command requiring operator privileges to operate
+        * must return this error to indicate the attempt was
+        * unsuccessful.
+        */
+       public static final int ERR_NOPRIVILEGES = 481;
+       
+       /**
+        * Format: "&lt;channel&gt; You're not channel operator". <br />
+        * Any command requiring 'chanop' privileges (such as
+        * MODE messages) must return this error if the client
+        * making the attempt is not a chanop on the specified
+        * channel.
+        */
+       public static final int ERR_CHANOPRIVSNEEDED = 482;
+       
+       /**
+        * Format: "You cant kill a server!". <br />
+        * Any attempts to use the KILL command on a server
+        * are to be refused and this error returned directly
+        * to the client.
+        */
+       public static final int ERR_CANTKILLSERVER = 483;
+       
+       /**
+        * Format: "No O-lines for your host". <br />
+        * If a client sends an OPER message and the server has
+        * not been configured to allow connections from the
+        * client's host as an operator, this error must be
+        * returned.
+        */
+       public static final int ERR_NOOPERHOST = 491;
+       
+       /**
+        * Format: "Unknown MODE flag". <br />
+        * Returned by the server to indicate that a MODE
+        * message was sent with a nickname parameter and that
+        * the a mode flag sent was not recognized.
+        */
+       public static final int ERR_UMODEUNKNOWNFLAG = 501;
+       
+      /**
+       * Format: "Cant change mode for other users". <br />
+       * Error sent to any user trying to view or change the
+       * user mode for a user other than themselves.
+       */
+       public static final int ERR_USERSDONTMATCH = 502;
+      
+       /**
+        * Dummy reply number. Not used.
+        */
+       public static final int RPL_NONE = 300;
+       
+       /**
+        * Format: "[&lt;reply&gt;{&lt;space&gt;&lt;reply&gt;}]". <br />
+        * Reply format used by USERHOST to list replies to
+        * the query list.  The reply string is composed as
+        * follows:<br />
+        * &lt;reply&gt; ::= &lt;nick&gt;['*'] '=' &lt;'+'|'-'&gt;&lt;hostname&gt;
+        * <br />
+        * The '*' indicates whether the client has registered
+        * as an Operator.  The '-' or '+' characters represent
+        * whether the client has set an AWAY message or not
+        * respectively.
+        */
+       public static final int RPL_USERHOST = 302;
+      
+       /**
+        * Format: "[&lt;nick&gt; {&lt;space&gt;&lt;nick&gt;}]". <br />
+        * Reply format used by ISON to list replies to the
+        * query list.
+        */
+       public static final int RPL_ISON = 303;
+       
+       /**
+        * Format: "&lt;nick&gt; &lt;away message&gt;".
+        */
+       public static final int RPL_AWAY = 301;
+      
+       /**
+        * Format: "You are no longer marked as being away".
+        */
+       public static final int RPL_UNAWAY = 305;
+       
+       /**
+        * Format: "You have been marked as being away". <br />
+        * These replies are used with the AWAY command (if
+        * allowed).  RPL_AWAY is sent to any client sending a
+        * PRIVMSG to a client which is away.  RPL_AWAY is only
+        * sent by the server to which the client is connected.
+        * Replies RPL_UNAWAY and RPL_NOWAWAY are sent when the
+        * client removes and sets an AWAY message.
+        */
+       public static final int RPL_NOWAWAY = 306;
+       
+       /**
+       * Format: "&lt;nick&gt; &lt;user&gt; &lt;host&gt; * :&lt;real name&gt;".
+        * <br />
+        * Replies 311 - 313, 317 - 319 are all replies
+        * generated in response to a WHOIS message.  Given that
+        * there are enough parameters present, the answering
+        * server must either formulate a reply out of the above
+        * numerics (if the query nick is found) or return an
+        * error reply.  The '*' in RPL_WHOISUSER is there as
+        * the literal character and not as a wild card.  For
+        * each reply set, only RPL_WHOISCHANNELS may appear
+        * more than once (for long lists of channel names).
+        * The '@' and '+' characters next to the channel name
+        * indicate whether a client is a channel operator or
+        * has been granted permission to speak on a moderated
+        * channel.  The RPL_ENDOFWHOIS reply is used to mark
+        * the end of processing a WHOIS message.
+        */
+       public static final int RPL_WHOISUSER = 311;
+       
+       /**
+        * Format: "&lt;nick&gt; &lt;server&gt; &lt;server info&gt;". <br />
+        * Replies 311 - 313, 317 - 319 are all replies
+        * generated in response to a WHOIS message.  Given that
+        * there are enough parameters present, the answering
+        * server must either formulate a reply out of the above
+        * numerics (if the query nick is found) or return an
+        * error reply.  The '*' in RPL_WHOISUSER is there as
+        * the literal character and not as a wild card.  For
+        * each reply set, only RPL_WHOISCHANNELS may appear
+        * more than once (for long lists of channel names).
+        * The '@' and '+' characters next to the channel name
+        * indicate whether a client is a channel operator or
+        * has been granted permission to speak on a moderated
+        * channel.  The RPL_ENDOFWHOIS reply is used to mark
+        * the end of processing a WHOIS message.
+        */
+       public static final int RPL_WHOISSERVER = 312;
+       
+       /**
+        * Format: "&lt;nick&gt; is an IRC operator". <br />
+        * Replies 311 - 313, 317 - 319 are all replies
+        * generated in response to a WHOIS message.  Given that
+        * there are enough parameters present, the answering
+        * server must either formulate a reply out of the above
+        * numerics (if the query nick is found) or return an
+        * error reply.  The '*' in RPL_WHOISUSER is there as
+        * the literal character and not as a wild card.  For
+        * each reply set, only RPL_WHOISCHANNELS may appear
+        * more than once (for long lists of channel names).
+        * The '@' and '+' characters next to the channel name
+        * indicate whether a client is a channel operator or
+        * has been granted permission to speak on a moderated
+        * channel.  The RPL_ENDOFWHOIS reply is used to mark
+        * the end of processing a WHOIS message.
+        */
+      public static final int RPL_WHOISOPERATOR = 313;
+       
+       /**
+        * Format: "&lt;nick&gt; &lt;integer&gt; seconds idle". <br />
+        * Replies 311 - 313, 317 - 319 are all replies
+        * generated in response to a WHOIS message.  Given that
+        * there are enough parameters present, the answering
+        * server must either formulate a reply out of the above
+        * numerics (if the query nick is found) or return an
+        * error reply.  The '*' in RPL_WHOISUSER is there as
+        * the literal character and not as a wild card.  For
+        * each reply set, only RPL_WHOISCHANNELS may appear
+        * more than once (for long lists of channel names).
+        * The '@' and '+' characters next to the channel name
+        * indicate whether a client is a channel operator or
+        * has been granted permission to speak on a moderated
+        * channel.  The RPL_ENDOFWHOIS reply is used to mark
+        * the end of processing a WHOIS message.
+        */
+       public static final int RPL_WHOISIDLE = 317;
+       
+      /**
+       * Format: "&lt;nick&gt; End of /WHOIS list". <br />
+       * Replies 311 - 313, 317 - 319 are all replies
+       * generated in response to a WHOIS message.  Given that
+       * there are enough parameters present, the answering
+       * server must either formulate a reply out of the above
+       * numerics (if the query nick is found) or return an
+       * error reply.  The '*' in RPL_WHOISUSER is there as
+       * the literal character and not as a wild card.  For
+       * each reply set, only RPL_WHOISCHANNELS may appear
+       * more than once (for long lists of channel names).
+       * The '@' and '+' characters next to the channel name
+       * indicate whether a client is a channel operator or
+       * has been granted permission to speak on a moderated
+       * channel.  The RPL_ENDOFWHOIS reply is used to mark
+       * the end of processing a WHOIS message.
+       */
+       public static final int RPL_ENDOFWHOIS = 318;
+       
+       /**
+        * Format: "&lt;nick&gt; {[@|+]&lt;channel&gt;&lt;space&gt;}". <br />
+        * Replies 311 - 313, 317 - 319 are all replies
+        * generated in response to a WHOIS message.  Given that
+        * there are enough parameters present, the answering
+        * server must either formulate a reply out of the above
+        * numerics (if the query nick is found) or return an
+        * error reply.  The '*' in RPL_WHOISUSER is there as
+        * the literal character and not as a wild card.  For
+        * each reply set, only RPL_WHOISCHANNELS may appear
+        * more than once (for long lists of channel names).
+        * The '@' and '+' characters next to the channel name
+        * indicate whether a client is a channel operator or
+        * has been granted permission to speak on a moderated
+        * channel.  The RPL_ENDOFWHOIS reply is used to mark
+        * the end of processing a WHOIS message.
+        */
+       public static final int RPL_WHOISCHANNELS = 319;
+       
+       /**
+        * Format: "&lt;nick&gt; &lt;user&gt; &lt;host&gt; * &lt;real name&gt;".
+       */
+       public static final int RPL_WHOWASUSER = 314;
+       
+       /**
+        * Format: "&lt;nick&gt; End of WHOWAS". <br />
+        * When replying to a WHOWAS message, a server must use
+        * the replies RPL_WHOWASUSER, RPL_WHOISSERVER or
+        * ERR_WASNOSUCHNICK for each nickname in the presented
+        * list.  At the end of all reply batches, there must
+        * be RPL_ENDOFWHOWAS (even if there was only one reply
+        * and it was an error).
+        */
+       public static final int RPL_ENDOFWHOWAS = 369;
+       
+       /**
+        * Format: "Channel Users  Name". <br />
+        * Replies RPL_LISTSTART, RPL_LIST, RPL_LISTEND mark
+        * the start, actual replies with data and end of the
+        * server's response to a LIST command.  If there are
+        * no channels available to return, only the start
+        * and end reply must be sent.
+       */
+       public static final int RPL_LISTSTART = 321;
+       
+       /**
+        * Format: "&lt;channel&gt; &lt;# visible&gt; &lt;topic&gt;". <br />
+        * Replies RPL_LISTSTART, RPL_LIST, RPL_LISTEND mark
+        * the start, actual replies with data and end of the
+        * server's response to a LIST command.  If there are
+        * no channels available to return, only the start
+        * and end reply must be sent.
+        */
+      public static final int RPL_LIST = 322;
+       
+       /**
+        * Format: "End of /LIST". <br />
+        * Replies RPL_LISTSTART, RPL_LIST, RPL_LISTEND mark
+        * the start, actual replies with data and end of the
+        * server's response to a LIST command.  If there are
+        * no channels available to return, only the start
+        * and end reply must be sent.
+        */
+       public static final int RPL_LISTEND = 323;
+       
+       /**
+        * Format: "&lt;channel&gt; &lt;mode&gt; &lt;mode params&gt;". <br />
+        */
+       public static final int RPL_CHANNELMODEIS = 324;
+       
+       /**
+        * Format: "&lt;nick&gt; &lt;authname&gt; is authed as"<br />
+        * This is part of /WHOIS on many servers which provide bots to authenticate.
+        */
+       public static final int RPL_AUTHNAME = 333;
+       
+       /**
+        * Format: "&lt;channel&gt; No topic is set". <br />
+        * When sending a TOPIC message to determine the
+        * channel topic, one of two replies is sent.  If
+        * the topic is set, RPL_TOPIC is sent back else
+        * public static final int RPL_NOTOPIC.
+        */
+       public static final int RPL_NOTOPIC = 331;
+       
+       /**
+        * Format: "&lt;channel&gt; &lt;topic&gt;". <br />
+        * When sending a TOPIC message to determine the
+        * channel topic, one of two replies is sent.  If
+        * the topic is set, RPL_TOPIC is sent back else
+        * public static final int RPL_NOTOPIC.
+        */
+       public static final int RPL_TOPIC = 332;
+      
+       /**
+        * Format: "&lt;channel&gt; &lt;nick-who-set-topic&gt; &lt;seconds&gt;".
+        * The seconds are not milliseconds; just multiply it with 1000 and then 
+        * format a date with it.
+        */
+       public static final int RPL_TOPICINFO = 333;
+       
+       /**
+        * Format: "&lt;channel&gt; &lt;nick&gt;". <br />
+        * Returned by the server to indicate that the
+        * attempted INVITE message was successful and is
+        * being passed onto the end client.
+        */
+       public static final int RPL_INVITING = 341;
+       
+       /**
+        * Format: "&lt;user&gt; Summoning user to IRC". <br />
+        * Returned by a server answering a SUMMON message to
+        * indicate that it is summoning that user.
+        */
+       public static final int RPL_SUMMONING = 342;
+       
+       /**
+       * Format: "&lt;version&gt;.&lt;debuglevel&gt; &lt;server&gt; 
+        * &lt;comments&gt;". <br />
+        * Reply by the server showing its version details.
+        * The &lt;version&gt; is the version of the software being
+        * used (including any patchlevel revisions) and the
+        * &lt;debuglevel&gt; is used to indicate if the server is
+        * running in "debug mode". <br />
+        * The "comments" field may contain any comments about
+        * the version or further version details.
+        */
+       public static final int RPL_VERSION = 351;
+       
+       /**
+        * Format: "&lt;channel&gt; &lt;user&gt; &lt;host&gt; &lt;server&gt; 
+        * &lt;nick&gt; &lt;H|G&gt;[*][@|+] &lt;hopcount&gt; &lt;real name&gt;". <br />
+        * The RPL_WHOREPLY and RPL_ENDOFWHO pair are used
+        * to answer a WHO message.  The RPL_WHOREPLY is only
+        * sent if there is an appropriate match to the WHO
+        * query.  If there is a list of parameters supplied
+        * with a WHO message, a RPL_ENDOFWHO must be sent
+        * after processing each list item with &lt;name&gt; being
+        * the item.
+        */
+      public static final int RPL_WHOREPLY = 352;
+       
+      /**
+        * Format: "&lt;name&gt; End of /WHO list". <br />
+        * The RPL_WHOREPLY and RPL_ENDOFWHO pair are used
++        * to answer a WHO message.  The RPL_WHOREPLY is only
+        * sent if there is an appropriate match to the WHO
+        * query.  If there is a list of parameters supplied
+        * with a WHO message, a RPL_ENDOFWHO must be sent
+        * after processing each list item with &lt;name&gt; being
+        * the item.
+        */
+       public static final int RPL_ENDOFWHO = 315;
+       
+       /**
+        * Format: "&lt;channel&gt; [[@|+]&lt;nick&gt; [[@|+]&lt;nick&gt; 
+        * [...]]]". <br />
+        * To reply to a NAMES message, a reply pair consisting
+        * of RPL_NAMREPLY and RPL_ENDOFNAMES is sent by the
+        * server back to the client.  If there is no channel
+        * found as in the query, then only RPL_ENDOFNAMES is
+        * returned.  The exception to this is when a NAMES
+        * message is sent with no parameters and all visible
+        * channels and contents are sent back in a series of
+        * RPL_NAMEREPLY messages with a RPL_ENDOFNAMES to mark
+        * the end.
+        */
+       public static final int RPL_NAMREPLY = 353;
+       
+       /**
+        * Format: "&lt;channel&gt; End of /NAMES list". <br />
+        * To reply to a NAMES message, a reply pair consisting
+        * of RPL_NAMREPLY and RPL_ENDOFNAMES is sent by the
+        * server back to the client.  If there is no channel
+        * found as in the query, then only RPL_ENDOFNAMES is
+        * returned.  The exception to this is when a NAMES
+        * message is sent with no parameters and all visible
+        * channels and contents are sent back in a series of
+        * RPL_NAMEREPLY messages with a RPL_ENDOFNAMES to mark
+        * the end.
+        */
+      public static final int RPL_ENDOFNAMES = 366;
+       
+      /**
+        * Format: "&lt;mask&gt; &lt;server&gt; &lt;hopcount&gt; &lt;server info&gt;".
+        * <br />
+        * In replying to the LINKS message, a server must send
+        * replies back using the RPL_LINKS numeric and mark the
+        * end of the list using an RPL_ENDOFLINKS reply.
+       */
+       public static final int RPL_LINKS = 364;
+       
+       /**
+        * Format: "&lt;mask&gt; End of /LINKS list". <br />
+        * In replying to the LINKS message, a server must send
+        * replies back using the RPL_LINKS numeric and mark the
+       * end of the list using an RPL_ENDOFLINKS reply.
+        */
+       public static final int RPL_ENDOFLINKS = 365;
+       
+       /**
+        * Format: "&lt;channel&gt; &lt;banid&gt;". <br />
+        * When listing the active 'bans' for a given channel,
+        * a server is required to send the list back using the
+        * RPL_BANLIST and RPL_ENDOFBANLIST messages.  A separate
+        * RPL_BANLIST is sent for each active banid.  After the
+        * banids have been listed (or if none present) a
+        * RPL_ENDOFBANLIST must be sent.
+        */
+       public static final int RPL_BANLIST = 367;
+       
+       /**
+        * Format: "&lt;channel&gt; End of channel ban list". <br />
+        * When listing the active 'bans' for a given channel,
+        * a server is required to send the list back using the
+        * RPL_BANLIST and RPL_ENDOFBANLIST messages.  A separate
+        * RPL_BANLIST is sent for each active banid.  After the
+        * banids have been listed (or if none present) a
+        * RPL_ENDOFBANLIST must be sent.
+        */
+       public static final int RPL_ENDOFBANLIST = 368;
+       
+       /**
+        * Format: "&lt;string&gt;". <br />
+        * A server responding to an INFO message is required to
+        * send all its 'info' in a series of RPL_INFO messages
+        * with a RPL_ENDOFINFO reply to indicate the end of the
+        * replies.
+        */
+      public static final int RPL_INFO = 371;
+       
+       
+       /**
+        * Format: "End of /INFO list". <br />
+        * A server responding to an INFO message is required to
+        * send all its 'info' in a series of RPL_INFO messages
+        * with a RPL_ENDOFINFO reply to indicate the end of the
+        * replies.
+        */
+       public static final int RPL_ENDOFINFO = 374;
+       
+       /**
+        * Format: "- &lt;server&gt; Message of the day - ". <br />
+        * When responding to the MOTD message and the MOTD file
+        * is found, the file is displayed line by line, with
+        * each line no longer than 80 characters, using
+        * RPL_MOTD format replies.  These should be surrounded
+        * by a RPL_MOTDSTART (before the RPL_MOTDs) and an
+        * RPL_ENDOFMOTD (after).
+        */
+       public static final int RPL_MOTDSTART = 375;
+       
+       /**
+        * Format: "- &lt;text&gt;". <br />
+        * When responding to the MOTD message and the MOTD file
+        * is found, the file is displayed line by line, with
+        * each line no longer than 80 characters, using
+        * RPL_MOTD format replies.  These should be surrounded
+        * by a RPL_MOTDSTART (before the RPL_MOTDs) and an
+        * RPL_ENDOFMOTD (after).
+        */
+       public static final int RPL_MOTD = 372;
+       
+       /**
+        * Format: "End of /MOTD command". <br />
+        * When responding to the MOTD message and the MOTD file
+        * is found, the file is displayed line by line, with
+        * each line no longer than 80 characters, using
+        * RPL_MOTD format replies.  These should be surrounded
+        * by a RPL_MOTDSTART (before the RPL_MOTDs) and an
+        * RPL_ENDOFMOTD (after).
+        */
+       public static final int RPL_ENDOFMOTD = 376;
+       
+       /**
+        * Format: "You are now an IRC operator". <br />
+        * RPL_YOUREOPER is sent back to a client which has
+        * just successfully issued an OPER message and gained
+        * operator status.
+        */
+       public static final int RPL_YOUREOPER = 381;
+       
+       /**
+        * Format: "&lt;config file&gt; Rehashing". <br />
+        * If the REHASH option is used and an operator sends
+        * a REHASH message, an RPL_REHASHING is sent back to
+        * the operator.
+        */
+       public static final int RPL_REHASHING = 382;
+       
+       /**
+        * Format: "&lt;server&gt; &lt;string showing server's local time&gt;". <br />
+        * When replying to the TIME message, a server must send
+        * the reply using the RPL_TIME format above.  The string
+        * showing the time need only contain the correct day and
+        * time there.  There is no further requirement for the
+        * time string.
+        */
+       public static final int RPL_TIME = 391;
+      
+       /**
+        * Format: "UserID   Terminal  Host". <br />
+        * If the USERS message is handled by a server, the
+        * replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and
+        * RPL_NOUSERS are used.  RPL_USERSSTART must be sent
+        * first, following by either a sequence of RPL_USERS
+        * or a single RPL_NOUSER.  Following this is
+        * RPL_ENDOFUSERS.
+        */
+       public static final int RPL_USERSSTART = 392;
+       
+       /**
+        * Format: "%-8s %-9s %-8s". <br />
+        * If the USERS message is handled by a server, the
+        * replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and
+        * RPL_NOUSERS are used.  RPL_USERSSTART must be sent
+        * first, following by either a sequence of RPL_USERS
+        * or a single RPL_NOUSER.  Following this is
+        * RPL_ENDOFUSERS.
+        */
+       public static final int RPL_USERS = 393;
+       
+       /**
+        * Format: "End of users". <br />
+        * If the USERS message is handled by a server, the
+        * replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and
+        * RPL_NOUSERS are used.  RPL_USERSSTART must be sent
+        * first, following by either a sequence of RPL_USERS
+        * or a single RPL_NOUSER.  Following this is
+        * RPL_ENDOFUSERS.
+        */
+       public static final int RPL_ENDOFUSERS = 394;
+       
+       /**
+        * Format: "Nobody logged in". <br />
+        * If the USERS message is handled by a server, the
+        * replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and
+        * RPL_NOUSERS are used.  RPL_USERSSTART must be sent
+        * first, following by either a sequence of RPL_USERS
+        * or a single RPL_NOUSER.  Following this is
+        * RPL_ENDOFUSERS.
+        */
+       public static final int RPL_NOUSERS = 395;
+       
+       /**
+        * Format: "Link &lt;version & debug level&gt; &lt;destination&gt; 
+        * &lt;next server&gt;". <br />
+        * The RPL_TRACE* are all returned by the server in
+        * response to the TRACE message.  How many are
+        * returned is dependent on the the TRACE message and
+        * whether it was sent by an operator or not.  There
+        * is no predefined order for which occurs first.
+        * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and
+        * RPL_TRACEHANDSHAKE are all used for connections
+        * which have not been fully established and are either
+        * unknown, still attempting to connect or in the
+        * process of completing the 'server handshake'.
+        * RPL_TRACELINK is sent by any server which handles
+        * a TRACE message and has to pass it on to another
+        * server.  The list of RPL_TRACELINKs sent in
+        * response to a TRACE command traversing the IRC
+        * network should reflect the actual connectivity of
+        * the servers themselves along that path.
+        * RPL_TRACENEWTYPE is to be used for any connection
+        * which does not fit in the other categories but is
+        * being displayed anyway.
+        */
+       public static final int RPL_TRACELINK = 200;
+       
+       /**
+        * Format: "Try. &lt;class&gt; &lt;server&gt;". <br />
+        * The RPL_TRACE* are all returned by the server in
+        * response to the TRACE message.  How many are
+        * returned is dependent on the the TRACE message and
+        * whether it was sent by an operator or not.  There
+        * is no predefined order for which occurs first.
+        * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and
+        * RPL_TRACEHANDSHAKE are all used for connections
+        * which have not been fully established and are either
+        * unknown, still attempting to connect or in the
+        * process of completing the 'server handshake'.
+        * RPL_TRACELINK is sent by any server which handles
+        * a TRACE message and has to pass it on to another
+        * server.  The list of RPL_TRACELINKs sent in
+        * response to a TRACE command traversing the IRC
+        * network should reflect the actual connectivity of
+        * the servers themselves along that path.
+        * RPL_TRACENEWTYPE is to be used for any connection
+        * which does not fit in the other categories but is
+        * being displayed anyway.
+        */
+       public static final int RPL_TRACECONNECTING = 201;
+       
+       /**
+        * Format: "H.S. &lt;class&gt; &lt;server&gt;". <br />
+        * The RPL_TRACE* are all returned by the server in
+        * response to the TRACE message.  How many are
+        * returned is dependent on the the TRACE message and
+        * whether it was sent by an operator or not.  There
+        * is no predefined order for which occurs first.
+        * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and
+        * RPL_TRACEHANDSHAKE are all used for connections
+        * which have not been fully established and are either
+        * unknown, still attempting to connect or in the
+        * process of completing the 'server handshake'.
+        * RPL_TRACELINK is sent by any server which handles
+        * a TRACE message and has to pass it on to another
+        * server.  The list of RPL_TRACELINKs sent in
+        * response to a TRACE command traversing the IRC
+        * network should reflect the actual connectivity of
+        * the servers themselves along that path.
+        * RPL_TRACENEWTYPE is to be used for any connection
+        * which does not fit in the other categories but is
+        * being displayed anyway.
+        */
+       public static final int RPL_TRACEHANDSHAKE = 202;
+       
+       /**
+        * Format: "???? &lt;class&gt; [&lt;client IP address in dot form&gt;]". <br />
+        * The RPL_TRACE* are all returned by the server in
+        * response to the TRACE message.  How many are
+        * returned is dependent on the the TRACE message and
+        * whether it was sent by an operator or not.  There
+        * is no predefined order for which occurs first.
+        * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and
+        * RPL_TRACEHANDSHAKE are all used for connections
+        * which have not been fully established and are either
+        * unknown, still attempting to connect or in the
+        * process of completing the 'server handshake'.
+        * RPL_TRACELINK is sent by any server which handles
+        * a TRACE message and has to pass it on to another
+        * server.  The list of RPL_TRACELINKs sent in
+        * response to a TRACE command traversing the IRC
+        * network should reflect the actual connectivity of
+        * the servers themselves along that path.
+        * RPL_TRACENEWTYPE is to be used for any connection
+        * which does not fit in the other categories but is
+        * being displayed anyway.
+        */
+       public static final int RPL_TRACEUNKNOWN = 203;
+       
+       /**
+        * Format: "Oper &lt;class&gt; &lt;nick&gt;". <br />
+        * The RPL_TRACE* are all returned by the server in
+        * response to the TRACE message.  How many are
+        * returned is dependent on the the TRACE message and
+        * whether it was sent by an operator or not.  There
+        * is no predefined order for which occurs first.
+        * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and
+        * RPL_TRACEHANDSHAKE are all used for connections
+        * which have not been fully established and are either
+        * unknown, still attempting to connect or in the
+        * process of completing the 'server handshake'.
+        * RPL_TRACELINK is sent by any server which handles
+        * a TRACE message and has to pass it on to another
+        * server.  The list of RPL_TRACELINKs sent in
+        * response to a TRACE command traversing the IRC
+        * network should reflect the actual connectivity of
+        * the servers themselves along that path.
+        * RPL_TRACENEWTYPE is to be used for any connection
+        * which does not fit in the other categories but is
+        * being displayed anyway.
+        */
+       public static final int RPL_TRACEOPERATOR = 204;
+       
+       /**
+        * Format: "User &lt;class&gt; &lt;nick&gt;". <br />
+        * The RPL_TRACE* are all returned by the server in
+        * response to the TRACE message.  How many are
+        * returned is dependent on the the TRACE message and
+        * whether it was sent by an operator or not.  There
+        * is no predefined order for which occurs first.
+        * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and
+        * RPL_TRACEHANDSHAKE are all used for connections
+        * which have not been fully established and are either
+        * unknown, still attempting to connect or in the
+        * process of completing the 'server handshake'.
+        * RPL_TRACELINK is sent by any server which handles
+        * a TRACE message and has to pass it on to another
+        * server.  The list of RPL_TRACELINKs sent in
+        * response to a TRACE command traversing the IRC
+        * network should reflect the actual connectivity of
+        * the servers themselves along that path.
+        * RPL_TRACENEWTYPE is to be used for any connection
+        * which does not fit in the other categories but is
+        * being displayed anyway.
+        */
+       public static final int RPL_TRACEUSER = 205;
+       
+       /**
+        * Format: "Serv &lt;class&gt; &lt;int&gt;S &lt;int&gt;C &lt;server&gt;
+        * &lt;nick!user|*!*&gt;@&lt;host|server&gt;". <br />
+        * The RPL_TRACE* are all returned by the server in
+        * response to the TRACE message.  How many are
+        * returned is dependent on the the TRACE message and
+       * whether it was sent by an operator or not.  There
+        * is no predefined order for which occurs first.
+        * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and
+        * RPL_TRACEHANDSHAKE are all used for connections
+        * which have not been fully established and are either
+        * unknown, still attempting to connect or in the
+        * process of completing the 'server handshake'.
+        * RPL_TRACELINK is sent by any server which handles
+        * a TRACE message and has to pass it on to another
+        * server.  The list of RPL_TRACELINKs sent in
+        * response to a TRACE command traversing the IRC
+        * network should reflect the actual connectivity of
+        * the servers themselves along that path.
+        * RPL_TRACENEWTYPE is to be used for any connection
+        * which does not fit in the other categories but is
+        * being displayed anyway.
+        */
+       public static final int RPL_TRACESERVER = 206;
+       
+       /**
+        * Format: "&lt;newtype&gt; 0 &lt;client name&gt;". <br />
+        * The RPL_TRACE* are all returned by the server in
+        * response to the TRACE message.  How many are
+        * returned is dependent on the the TRACE message and
+        * whether it was sent by an operator or not.  There
+        * is no predefined order for which occurs first.
+        * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and
+        * RPL_TRACEHANDSHAKE are all used for connections
+        * which have not been fully established and are either
+        * unknown, still attempting to connect or in the
+        * process of completing the 'server handshake'.
+        * RPL_TRACELINK is sent by any server which handles
+        * a TRACE message and has to pass it on to another
+        * server.  The list of RPL_TRACELINKs sent in
+        * response to a TRACE command traversing the IRC
+        * network should reflect the actual connectivity of
+        * the servers themselves along that path.
+        * RPL_TRACENEWTYPE is to be used for any connection
+        * which does not fit in the other categories but is
+        * being displayed anyway.
+        */
+       public static final int RPL_TRACENEWTYPE = 208;
+       
+       /**
+        * Format: "File &lt;logfile&gt; &lt;debug level&gt;". <br />
+        * The RPL_TRACE* are all returned by the server in
+        * response to the TRACE message.  How many are
+        * returned is dependent on the the TRACE message and
+        * whether it was sent by an operator or not.  There
+        * is no predefined order for which occurs first.
+        * Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and
+        * RPL_TRACEHANDSHAKE are all used for connections
+        * which have not been fully established and are either
+        * unknown, still attempting to connect or in the
+        * process of completing the 'server handshake'.
+        * RPL_TRACELINK is sent by any server which handles
+        * a TRACE message and has to pass it on to another
+        * server.  The list of RPL_TRACELINKs sent in
+        * response to a TRACE command traversing the IRC
+        * network should reflect the actual connectivity of
+        * the servers themselves along that path.
+        * RPL_TRACENEWTYPE is to be used for any connection
+        * which does not fit in the other categories but is
+        * being displayed anyway.
+        */
+       public static final int RPL_TRACELOG = 261;
+      
+       /**
+        * Format: "&lt;linkname&gt; &lt;sendq&gt; &lt;sent messages&gt; 
+        * &lt;sent bytes&gt; &lt;received messages&gt; 
+        * &lt;received bytes&gt; &lt;time open&gt;".
+        */
+       public static final int RPL_STATSLINKINFO = 211;
+       
+       /**
+        * Format: "&lt;command&gt; &lt;count&gt;".
+        */
+       public static final int RPL_STATSCOMMANDS = 212;
+       
+       /**
+        * Format: "C &lt;host&gt; * &lt;name&gt; &lt;port&gt; &lt;class&gt;".
+        */
+       public static final int RPL_STATSCLINE = 213;
+       
+       /**
+        * Format: "N &lt;host&gt; * &lt;name&gt; &lt;port&gt; &lt;class&gt;".
+        */
+       public static final int RPL_STATSNLINE = 214;
+       
+       /**
+        * Format: "I &lt;host&gt; * &lt;host&gt; &lt;port&gt; &lt;class&gt;".
+        */
+       public static final int RPL_STATSILINE = 215;
+       
+       /**
+        * Format: "K &lt;host&gt; * &lt;username&gt; &lt;port&gt; &lt;class&gt;".
+        */
+       public static final int RPL_STATSKLINE = 216;
+       
+       /**
+        * Format: "Y &lt;class&gt; &lt;ping frequency&gt; &lt;connect 
+        * frequency&gt; &lt;max sendq&gt;".
+        */
+       public static final int RPL_STATSYLINE = 218;
+       
+       /**
+        * Format: "&lt;stats letter&gt; End of /STATS report".
+        */
+       public static final int RPL_ENDOFSTATS = 219;
+       
+       /**
+        * Format: "L &lt;hostmask&gt; * &lt;servername&gt; &lt;maxdepth&gt;".
+        */
+       public static final int RPL_STATSLLINE = 241;
+       
+       /**
+        * Format: "Server Up %d days %d:%02d:%02d".
+        */
+       public static final int RPL_STATSUPTIME = 242;
+       
+       /**
+        * Format: "O &lt;hostmask&gt; * &lt;name&gt;"
+        */
+       public static final int RPL_STATSOLINE = 243;
+       
+       /**
+        * Format: "H &lt;hostmask&gt; * &lt;servername&gt;".
+        */
+       public static final int RPL_STATSHLINE = 244;
+       
+       /**
+        * Format: "&lt;user mode string&gt;". <br />
+        * To answer a query about a client's own mode,
+        * RPL_UMODEIS is sent back.
+        */
+       public static final int RPL_UMODEIS = 221;
+       
+       /**
+        * Format:   "There are &lt;integer&gt; users and &lt;integer&gt; 
+        * invisible on &lt;integer&gt; servers". <br />
+        * In processing an LUSERS message, the server
+        * sends a set of replies from RPL_LUSERCLIENT,
+        * RPL_LUSEROP, RPL_USERUNKNOWN,
+        * RPL_LUSERCHANNELS and RPL_LUSERME.  When
+        * replying, a server must send back
+        * RPL_LUSERCLIENT and RPL_LUSERME.  The other
+        * replies are only sent back if a non-zero count
+        * is found for them.
+        */
+       public static final int RPL_LUSERCLIENT = 251;
+       
+       /**
+        * Format: "&lt;integer&gt; operator(s) online". <br />
+        * In processing an LUSERS message, the server
+        * sends a set of replies from RPL_LUSERCLIENT,
+        * RPL_LUSEROP, RPL_USERUNKNOWN,
+        * RPL_LUSERCHANNELS and RPL_LUSERME.  When
+        * replying, a server must send back
+        * RPL_LUSERCLIENT and RPL_LUSERME.  The other
+        * replies are only sent back if a non-zero count
+        * is found for them.
+        */
+       public static final int RPL_LUSEROP = 252;
+       
+       /**
+        * Format: "&lt;integer&gt; unknown connection(s)". <br />
+        * In processing an LUSERS message, the server
+        * sends a set of replies from RPL_LUSERCLIENT,
+        * RPL_LUSEROP, RPL_USERUNKNOWN,
+        * RPL_LUSERCHANNELS and RPL_LUSERME.  When
+        * replying, a server must send back
+        * RPL_LUSERCLIENT and RPL_LUSERME.  The other
+        * replies are only sent back if a non-zero count
+        * is found for them.
+        */
+       public static final int RPL_LUSERUNKNOWN = 253;
+       
+       /**
+        * Format: "&lt;integer&gt; channels formed". <br />
+        * In processing an LUSERS message, the server
+        * sends a set of replies from RPL_LUSERCLIENT,
+        * RPL_LUSEROP, RPL_USERUNKNOWN,
+        * RPL_LUSERCHANNELS and RPL_LUSERME.  When
+        * replying, a server must send back
+        * RPL_LUSERCLIENT and RPL_LUSERME.  The other
+        * replies are only sent back if a non-zero count
+        * is found for them.
+        */
+       public static final int RPL_LUSERCHANNELS = 254;
+       
+       /**
+        * Format: "I have &lt;integer&gt; clients and &lt;integer&gt; 
+        * servers". <br />
+        * In processing an LUSERS message, the server
+        * sends a set of replies from RPL_LUSERCLIENT,
+        * RPL_LUSEROP, RPL_USERUNKNOWN,
+        * RPL_LUSERCHANNELS and RPL_LUSERME.  When
+        * replying, a server must send back
+        * RPL_LUSERCLIENT and RPL_LUSERME.  The other
+        * replies are only sent back if a non-zero count
+        * is found for them.
+        */
+       public static final int RPL_LUSERME = 255;
+       
+       /**
+        * Format: "&lt;server&gt; Administrative info". <br />
+        * When replying to an ADMIN message, a server
+        * is expected to use replies RLP_ADMINME
+        * through to RPL_ADMINEMAIL and provide a text
+        * message with each.  For RPL_ADMINLOC1 a
+        * description of what city, state and country
+        * the server is in is expected, followed by
+        * details of the university and department
+        * (RPL_ADMINLOC2) and finally the administrative
+        * contact for the server (an email address here
+        * is required) in RPL_ADMINEMAIL.
+        */
+       public static final int RPL_ADMINME = 256;
+       
+       /**
+        * Format: "&lt;admin info&gt;". <br />
+        * When replying to an ADMIN message, a server
+        * is expected to use replies RLP_ADMINME
+        * through to RPL_ADMINEMAIL and provide a text
+        * message with each.  For RPL_ADMINLOC1 a
+        * description of what city, state and country
+        * the server is in is expected, followed by
+        * details of the university and department
+        * (RPL_ADMINLOC2) and finally the administrative
+        * contact for the server (an email address here
+        * is required) in RPL_ADMINEMAIL.
+        */
+       public static final int RPL_ADMINLOC1 = 257;
+       
+       /**
+        * Format: "&lt;admin info&gt;". <br />
+        * When replying to an ADMIN message, a server
+        * is expected to use replies RLP_ADMINME
+        * through to RPL_ADMINEMAIL and provide a text
+        * message with each.  For RPL_ADMINLOC1 a
+        * description of what city, state and country
+        * the server is in is expected, followed by
+        * details of the university and department
+        * (RPL_ADMINLOC2) and finally the administrative
+        * contact for the server (an email address here
+        * is required) in RPL_ADMINEMAIL.
+        */
+       public static final int RPL_ADMINLOC2 = 258;
+       
+       /**
+        * Format: "&lt;admin info&gt;". <br />
+        * When replying to an ADMIN message, a server
+        * is expected to use replies RLP_ADMINME
+        * through to RPL_ADMINEMAIL and provide a text
+        * message with each.  For RPL_ADMINLOC1 a
+        * description of what city, state and country
+        * the server is in is expected, followed by
+        * details of the university and department
+        * (RPL_ADMINLOC2) and finally the administrative
+        * contact for the server (an email address here
+        * is required) in RPL_ADMINEMAIL.
+        */
+       public static final int RPL_ADMINEMAIL = 259;
+       
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+       public static final int RPL_TRACECLASS = 209;
+       
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+       public static final int RPL_STATSQLINE = 217;
+       
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+       public static final int RPL_SERVICEINFO = 231;
+       
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+       public static final int RPL_ENDOFSERVICES = 232;
+       
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+       public static final int RPL_SERVICE = 233;
+       
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+       public static final int RPL_SERVLIST = 234;
+       
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+       public static final int RPL_SERVLISTEND = 235;
+      
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+      public static final int RPL_WHOISCHANOP = 316;
+       
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+       public static final int RPL_KILLDONE = 361;
+       
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+       public static final int RPL_CLOSING = 362;
+       
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+       public static final int RPL_CLOSEEND = 363;
+       
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+       public static final int RPL_INFOSTART = 373;
+       
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+       public static final int RPL_MYPORTIS = 384;
+       
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+       public static final int ERR_YOUWILLBEBANNED = 466;
+       
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+       public static final int ERR_BADCHANMASK = 476;
+       
+       /**
+        * This numeric is no longer in use, reserved for future planned use or
+        * anything else.
+        */
+       public static final int ERR_NOSERVICEHOST = 492;
+       
+       /** 
+        * This is part of the mIRC code and shows that a color-code starts / ends. 
+        * Here it is as the ASCII decimal int 3. 
+        */
+       public static final char COLOR_INDICATOR = 3; // ASCII code
+       
+       /** 
+        * This is part of the mIRC code and shows that bold starts / ends.
+        * Here it is as the ASCII decimal int 31. 
+        */
+       public static final char BOLD_INDICATOR = 31; // ASCII code
+       
+       /**
+        * This is part of the mIRC code and shows that bold starts / ends.
+        * Here it is as the ASCII decimal int 2. 
+        */ 
+       public static final char UNDERLINE_INDICATOR = 2; // ASCII code
+       
+       /**
+        * This is part of the mIRC code and shows that bold, underline and colors 
+        * end. 
+        * Here it is as the ASCII decimal int 15. 
+        */
+       public static final char COLOR_END_INDICATOR = 15; // ASCII code
+       
+       /**
+        * This is part of the mIRC code and indicates that the client's colors are 
+        * reversed (background -&gt; foreground and foreground -&gt; background).
+        * Here it is as the ASCII decimal int 22. 
+        */ 
+       public static final char COLOR_REVERSE_INDICATOR = 22; // ASCII code
+       
+       /**
+        * This is part of the mIRC code and shows that a PRIVMSG is an ACTION 
+        * (<code>/me</code>).
+        * Here it is as the ASCII decimal int 1. 
+        */ 
+       public static final char ACTION_INDICATOR = 1; // ASCII code
+}
\ No newline at end of file
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCUtil.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCUtil.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCUtil.java	(revision 0)
@@ -0,0 +1,253 @@
+/*
+ * IRClib -- A Java Internet Relay Chat library -- class IRCUtil
+ * Copyright (C) 2002 - 2006 Christoph Schwering <schwering@gmail.com>
+ * 
+ * This library and the accompanying materials are made available under the
+ * terms of the
+ *     - GNU Lesser General Public License,
+ *     - Apache License, Version 2.0 and
+ *     - Eclipse Public License v1.0.
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY.
+*/
+
+package net.sf.l2j.gameserver.lib.irc;
+
+import java.util.Vector;
+/**
+ * Contains some utilities like numeric error and reply numbers.
+ * <p>
+ * The most description of the numeric errors and numeric replies are copied
+ * from RFC1459.
+ * @author Christoph Schwering &lt;schwering@gmail.com&gt;
+ * @author Normton &lt;normton@latinmail.com&gt;
+ * @version 2.03
+ * @see IRCConnection
+ * @see IRCEventListener#onError(int, String)
+ * @see IRCEventListener#onReply(int, String, String)
+ */
+public class IRCUtil implements IRCConstants {
+       /** 
+        * This is part of the mIRC code and shows that a color-code starts / ends. 
+        * Here it is as the ASCII decimal int 3. 
+        * @deprecated Moved to <code>IRCConstants</code>.
+        */
+       @Deprecated
+       public static char colorIndicator = 3; // ASCII code
+       
+       /** 
+        * This is part of the mIRC code and shows that bold starts / ends.
+        * Here it is as the ASCII decimal int 31. 
+        * @deprecated Moved to <code>IRCConstants</code>.
+        */
+       @Deprecated
+       public static char boldIndicator = 31; // ASCII code
+       
+       /**
+        * This is part of the mIRC code and shows that bold starts / ends.
+        * Here it is as the ASCII decimal int 2. 
+        * @deprecated Moved to <code>IRCConstants</code>.
+        */ 
+       @Deprecated
+       public static char underlinedIndicator = 2; // ASCII code
+       
+       /**
+        * This is part of the mIRC code and shows that bold, underline and colors 
+        * end. 
+        * Here it is as the ASCII decimal int 15. 
+        * @deprecated Moved to <code>IRCConstants</code>.
+        */
+       @Deprecated
+       public static char colorEndIndicator = 15; // ASCII code
+       
+       /**
+        * This is part of the mIRC code and indicates that the client's colors are 
+        * reversed (background -&gt; foreground and foreground -&gt; background).
+        * Here it is as the ASCII decimal int 22. 
+        * @deprecated Moved to <code>IRCConstants</code>.
+        */ 
+       @Deprecated
+       public static char colorReverseIndicator = 22; // ASCII code
+       
+       /**
+        * This is part of the mIRC code and shows that a PRIVMSG is an ACTION 
+        * (<code>/me</code>).
+        * Here it is as the ASCII decimal int 1. 
+        * @deprecated Moved to <code>IRCConstants</code>.
+        */ 
+       @Deprecated
+       public static char actionIndicator = 1; // ASCII code
+       
+// ------------------------------
+       
+       /** 
+        * This is an empty constructor, it does nothing. Nobody may instantiate this
+        * class.
+        */
+       private IRCUtil() {
+               // nothing
+       }
+       
+// ------------------------------
+       
+       /** 
+        * According to RFC2812 the channel's name may and must start with one of the
+        * following characters.
+        * <ul>
+        * <li>! == 33 (ASCII)</li>
+        * <li># == 35</li>
+        * <li>&amp; == 38</li>
+        * <li>+ == 43</li>
+        * </ul>. 
+        * @param str The name to check if it's a channel. 
+        * @return <code>true</code> if the argument starts with one of the characters
+        *         mentioned above.
+       */
+      public static boolean isChan(String str) {
+               int c;
+               return str.length() >= 2 
+               && ((c = str.charAt(0)) == 35 || c == 38 || c == 33 || c == 43);
+       }
+       
+// ------------------------------
+       
+       /**
+        * Parses a <code>String</code> to an <code>int</code> via
+        * <code>Integer.parseInt</code> but avoids the
+        * <code>NumberFormatException</code>.
+        * @param str The <code>String</code> to parse.
+       * @return The parsed new <code>int</code>. <code>-1</code> if
+        *         <code>NumberFormatException</code> was thrown. 
+        */
+       public static int parseInt(String str) {
+               try {
+                       return Integer.parseInt(str);
+               } catch (NumberFormatException exc) {
+                      return -1;
+               }
+       }
+       
+// ------------------------------
+       
+       /** 
+       * Erases the mIRC colorcodes from a String. 
+        * The documentation of the evil color codes is available on
+        * <a href="http://www.mirc.co.uk/help/color.txt" 
+        * target="_blank">http://www.mirc.co.uk/help/color.txt</a>. 
+        * This method links to the <code>parseColors(StringBuffer)</code> method.
+        * @param str The line which should be parsed. 
+        * @return A line cleaned from any mIRC colorcodes.
+        * @see #parseColors(StringBuffer)
+        */
+       public static String parseColors(String str) {
+               return parseColors(new StringBuffer(str)).toString();
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Erases the mIRC colorcodes from a String. 
+        * The documentation of the evil color codes is available on 
+        * <a href="http://www.mirc.co.uk/help/color.txt" 
+        * target="_blank">http://www.mirc.co.uk/help/color.txt</a>. 
+        * @param buf The line which should be parsed. 
+        * @return A line as <code>StringBuffer</code> object which is cleaned from 
+        *         any mIRC colorcodes.
+        * @see #parseColors(String)
+        */
+       public static StringBuffer parseColors(StringBuffer buf) {
+               int len = buf.length();
+               
+               for (int i = 0, j = 0, c; i < len; i++, j = i) {
+                       c = buf.charAt(i);
+                       try {
+                               // COLORS Beginning 
+                               // (format: <colorIndicator><int>[<int>][[,<int>[<int>]]
+                               if (c == COLOR_INDICATOR) { 
+                                       c = buf.charAt(++j);
+                                       if ('0' <= c && c <= '9') { // first int
+                                               c = buf.charAt(++j);
+                                               if ('0' <= c && c <= '9') 
+                                                       c = buf.charAt(++j); // second int
+                                       }
+                                       if (c == ',') 
+                                               c = buf.charAt(++j); // comma 
+                                       if ('0' <= c && c <= '9') { // first int
+                                               c = buf.charAt(++j); 
+                                               if ('0' <= c && c <= '9') 
+                                                       c = buf.charAt(++j); // second int
+                                       }
+                                       // ACTION / BOLD / UNDERLINE / COLOR END 
+                                       // (format: <actionIndicator> / <boldIndicator> etc.)
+                               } else if (c == ACTION_INDICATOR || c == BOLD_INDICATOR || 
+                                               c == UNDERLINE_INDICATOR || c == COLOR_END_INDICATOR ||
+                                              c == COLOR_REVERSE_INDICATOR) {
+                                       j++;
+                              }
+                       } catch(StringIndexOutOfBoundsException exc) {
+                               // we got the end of the string with a call to charAt(++iIndexEnd)
+                               // nothing
+                      }
+                       
+                       if (j > i) {
+                               buf = buf.delete(i, j); // remove the cars
+                               len -= j - i;
+                               i--;
+                       }
+               }
+               return buf;
+       }
+       
+// ------------------------------
+       
+       /**
+        * Splits a string into substrings. 
+        * @param str The string which is to split.
+        * @param delim The delimiter character, for example a space <code>' '</code>.
+        * @param trailing The ending which is added as a substring though it wasn't 
+        *                 in the <code>str</code>. This parameter is just for the 
+        *                 <code>IRCParser</code> class which uses this method to 
+        *                 split the <code>middle</code> part into the parameters. 
+        *                 But as last parameter always the <code>trailing</code> is 
+        *                 added. This is done here because it's the fastest way to 
+        *                 do it here. <br />
+        *                 If the <code>end</code> is <code>null</code> or 
+        *                 <code>""</code>, nothing is appended.
+        * @return An array with all substrings.
+        * @see #split(String, int)
+        */
+       public static String[] split(String str, int delim, String trailing) {
+               Vector items = new Vector(15);
+               int last = 0;
+               int index = 0; 
+              int len = str.length(); 
+               while (index < len) {
+                       if (str.charAt(index) == delim) {
+                              items.add(str.substring(last, index));
+                               last = index + 1;
+                       }
+                       index++;
+               }
+               if (last != len)
+                       items.add(str.substring(last));
+               if (trailing != null && trailing.length() != 0)
+                       items.add(trailing);
+               String[] result = new String[items.size()];
+               items.copyInto(result);
+               return result;
+       }
+       
+// ------------------------------
+       
+       /**
+        * Splits a string into substrings. This method is totally equal to 
+        * <code>split(str, delim, null)</code>.
+        * @param str The string which is to split.
+        * @param delim The delimiter character, for example a space <code>' '</code>.
+        * @return An array with all substrings.
+        * @see #split(String, int, String)
+        */
+       public static String[] split(String str, int delim) {
+               return split(str, delim, null);
+       }
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCUser.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCUser.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCUser.java	(revision 0)
@@ -0,0 +1,126 @@
+/*
+ * IRClib -- A Java Internet Relay Chat library -- class IRCUser
+ * Copyright (C) 2002 - 2006 Christoph Schwering <schwering@gmail.com>
+ * 
+ * This library and the accompanying materials are made available under the
+ * terms of the
+ *     - GNU Lesser General Public License,
+ *     - Apache License, Version 2.0 and
+ *     - Eclipse Public License v1.0.
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY.
+ */
+
+package net.sf.l2j.gameserver.lib.irc;
+
+/**
+ * Holds variables for the nick, username and host of a user.
+ <p>
+ * It's used to pack these information in one object.
+ * @author Christoph Schwering &lt;schwering@gmail.com&gt;
+ * @version 1.02
+ * @see IRCEventListener
+ * @see IRCParser
+*/
+public class IRCUser {
+      
+      /** 
+        * The user's nickname.
+        */
+       private String _nick;
+       
+       /**
+        * The user's username.
+        */
+       private String _username;
+       
+       /**
+        * The user's host.
+        */
+      private String _host;
+       
+// ------------------------------
+       
+       /**
+        * Creates a new <code>IRCUser</code> object.
+       * @param nick The user's nickname.
++        * @param username The user's username.
+        * @param host The user's host.
+        */
+       public IRCUser(String nick, String username, String host) {
+               this._nick = nick;
+               this._username = username;
+               this._host = host;
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Returns the nickname of the person who sent the line 
+        * or the servername of the server which sent the line. <br />
+        * If no nickname is given, <code>null</code> is returned.
+        * <br /><br />
+        * <b>Note:</b> This method is totally equal to <code>getServername</code>!
+        * @return The nickname or the servername of the line. If no nick is given,
+        *         <code>null</code> is returned.
+        * @see #getServername()
+        * @see #getUsername()
+        * @see #getHost()
+        */
+       public String getNick() {
+               return _nick;
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Returns the servername of the server which sent the line or the nickname of
+        * the person who sent the line. <br />
+        * If no nickname is given, <code>null</code> is returned.
+        * <br /><br />
+        * <b>Note:</b> This method is totally equal to <code>getNick</code>!
+        * @return The servername or the nickname of the line. If no server is given,
+        *         <code>null</code> is returned.
+        * @see #getNick()
+        */
+       public String getServername() {
+               return getNick();
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Returns the username of the person who sent the line. <br />
+        * If the username is not specified, this method returns <code>null</code>.
+        * @return The username of the line; <code>null</code> if it's not given.
+        * @see #getNick()
+        * @see #getHost()
+        */
+       public String getUsername() {
+               return _username;
+       }
+       
+// ------------------------------
+       
+       /** 
+        * Returns the host of the person who sent the line. <br />
+        * If the host is not specified, this method returns <code>null</code>.
+        * @return The host of the line; <code>null</code> if it's not given.
+        * @see #getNick()
+        * @see #getUsername()
+        */
+       public String getHost() {
+               return _host;
+       }
+       
+// ------------------------------
+       
+       /**
+        * Returns the nickname.
+        * @return The nickname.
+       */
+       @Override
+       public String toString() {
+               return getNick();
+       }
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCConnection.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCConnection.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/lib/irc/IRCConnection.java	(revision 0)
@@ -0,0 +1,1320 @@
+/*
+ * IRClib -- A Java Internet Relay Chat library -- class IRCConnection
+ * Copyright (C) 2002 - 2006 Christoph Schwering <schwering@gmail.com>
+ * 
+ * This library and the accompanying materials are made available under the
+ * terms of the
+ *     - GNU Lesser General Public License,
+ *     - Apache License, Version 2.0 and
+ *     - Eclipse Public License v1.0.
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY.
+ */
+package net.sf.l2j.gameserver.lib.irc;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.Socket;
+import java.net.SocketException;
+/**
+ * Creates a new connection to an IRC server. It's the main class of the
+ * IRClib, the point everything starts.
+ * <p>
+ * The following sample code tries to establish an IRC connection to an 
+ * IRC server:
+ * <p>
+ * <hr /><pre>
+ * /&#42; 
+ *  &#42; The following code of a class which imports org.schwering.irc.lib.*
+ *  &#42; prepares an IRC connection and then tries to establish the connection.
+ *  &#42; The server is "irc.somenetwork.com", the default portrange (6667 and 
+ *  &#42; 6669) is set, no password is used (null). The nickname is "Foo" and 
+ *  &#42; the realname is "Mr. Foobar". The username "foobar".
+ *  &#42; Because of setDaemon(true), the JVM exits even if this thread is 
+ *  &#42; running.
+ *  &#42; An instance of the class MyListener which must implement 
+ *  &#42; IRCActionListener is added as only event-listener for the connection. 
+ *  &#42; The connection is told to parse out mIRC color codes and to enable
+ *  &#42; automatic PING? PONG! replies.
+ *  &#42;/
+ * IRCConnection conn = new IRCConnection(
+ *                            "irc.somenetwork.com", 
+ *                            6667, 
+ *                            6669, 
+ *                            null, 
+ *                            "Foo", 
+ *                            "Mr. Foobar", 
+ *                            "foo@bar.com" 
+ *                          ); 
+ * 
+ * conn.addIRCEventListener(new MyListener()); 
+ * conn.setDaemon(true);
+ * conn.setColors(false); 
+ * conn.setPong(true); 
+ * 
+ * try {
+ *   conn.connect(); // Try to connect!!! Don't forget this!!!
+ * } catch (IOException ioexc) {
+ *   ioexc.printStackTrace(); 
+ * }
+ * </pre><hr />
+ * <p>
+ * The serverpassword isn't needed in most cases. You can give 
+ * <code>null</code> or <code>""</code> instead as done in this example.
+ * @author Christoph Schwering &lt;schwering@gmail.com&gt;
+ * @version 3.05
+ * @see IRCEventListener
+ * @see IRCParser
+ * @see IRCUtil
+ * @see SSLIRCConnection
+ */
+
+public class IRCConnection extends Thread
+{
+       /**
+        * This <code>Socket</code> is a connection to the IRC server.
+        */
+       private Socket socket;
+
+      /**
+        * This is like a UNIX-runlevel. Its value indicates the level of the
+        * <code>IRCConnection</code> object. <code>0</code> means that the
+        * object has not yet been connected, <code>1</code> means that it's
+        * connected but not registered, <code>2</code> means that it's connected
+        * and registered but still waiting to receive the nickname the first time,
+        * <code>3</code> means that it's connected and registered, and
+        * <code>-1</code> means that it was connected but is disconnected.
+        * Therefore the defaultvalue is <code>0</code>.
+        */
+      protected byte level = 0;
+
+       /**
+        * The host of the IRC server.
+        */
+       protected String _host;
+
+      /**
+        * The <code>int[]</code> contains all ports to which we are going to try
+        * to connect. This can be a portrange from port 6667 to 6669, for example.
+        */
+       protected int[] _ports;
+
+       /**
+        * The <code>BufferedReader</code> receives Strings from the IRC server.
+        */
+       private volatile BufferedReader in;
+
+       /**
+        * The <code>PrintWriter</code> sends Strings to the IRC server.
+        */
+       private PrintWriter out;
+
+       /**
+        * The <code>String</code> contains the name of the character encoding
+        * used to talk to the server. This can be ISO-8859-1 or UTF-8 for example.
+        * The default is ISO-8859-1.
+        */
+       protected String _encoding = "ISO-8859-1";
+
+       /**
+        * This array contains <code>IRCEventListener</code> objects.
+        */
+       private IRCEventListener[] listeners = new IRCEventListener[0];
+
+       /**
+        * This <code>int</code> is the connection's timeout in milliseconds. It's
+        * used in the <code>Socket.setSoTimeout</code> method. The default is
+        * <code>1000 * 60 * 15</code> millis which are 15 minutes.
+        */
+       private int timeout = 1000 * 60 * 15;
+
+       /**
+        * This <code>boolean</code> stands for enabled (<code>true</code>) or
+        * disabled (<code>false</code>) ColorCodes.<br />
+        * Default is enabled (<code>false</code>).
+        */
+       private boolean colorsEnabled = false;
+
+       /**
+        * This <code>boolean</code> stands for enabled or disabled automatic
+        * PING? PONG! support. <br />
+        * It means, that if the server asks with PING for the ping, the PONG is
+        * automatically sent. Default is automatic PONG enabled (<code>true</code>).
+        */
+       private boolean pongAutomatic = true;
+
+       /**
+        * The password, which is needed to get access to the IRC server.
+        */
+       private String _pass;
+
+       /**
+        * The user's nickname, which is indispensably to connect.
+        */
+       private String _nick;
+
+       /**
+        * The user's realname, which is indispensably to connect.
+        */
+       private String _realname;
+
+       /**
+        * The user's username, which is indispensable to connect.
+        */
+       private String _username;
+
+       // ------------------------------
+       /**
+        * Creates a new IRC connection. <br />
+        * The difference to the other constructor is, that it transmits the ports
+        * in an <code>int[]</code>. Thus, also ports like 1024, 2048, 6667 and
+        * 6669 can be selected.<br />
+        * <br />
+        * The constructor prepares a new IRC connection which can be really started
+        * by invoking the <code>connect</code> method. Before invoking it, you
+        * should set the <code>IRCEventListener</code> and other settings.<br />
+        * Note that you do not need to set a password to connect to the large
+        * public IRC networks like QuakeNet, EFNet etc. To use no password in your
+        * IRC connection, use <code>""</code> or <code>null</code> for the
+        * password argument in the constructor.
+        * 
+        * @param host
+        *            The hostname of the server we want to connect to.
+        * @param ports
+        *            The portrange to which we want to connect.
+        * @param pass
+        *            The password of the IRC server. If your server isn't secured
+        *            by a password (that's normal), use <code>null</code> or
+        *            <code>""</code>.
+        * @param nick
+        *            The nickname for the connection. Is used to register the
+        *            connection.
+        * @param username
+        *            The username. Is used to register the connection.
+        * @param realname
+        *            The realname. Is used to register the connection.
+        * @throws IllegalArgumentException
+        *             If the <code>host</code> or <code>ports</code> is
+        *             <code>null</code> or <code>ports</code>' length is
+        *             <code>0</code>.
+        * @see #connect()
+        */
+       public IRCConnection(String host, int[] ports, String pass, String nick, String username, String realname)
+       {
+               if (host == null || ports == null || ports.length == 0)
+                       throw new IllegalArgumentException("Host and ports may not be null.");
+               this._host = host;
+               this._ports = ports;
+               this._pass = (pass != null && pass.length() == 0) ? null : pass;
+               this._nick = nick;
+               this._username = username;
+               this._realname = realname;
+       }
+
+       // ------------------------------
+       /**
+        * Creates a new IRC connection. <br />
+        * The difference to the other constructor is, that it transmits the ports
+        * as two <code>int</code>s. Thus, only a portrange from port
+        * <code>x</code> to port <code>y</code> like from port 6667 to 6669 can
+        * be selected.<br />
+        * <br />
+        * The constructor prepares a new IRC connection which can be really started
+        * by invoking the <code>connect</code> method. Before invoking it, you
+        * should set the <code>IRCEventListener</code> and other settings.<br />
+        * Note that you do not need to set a password to connect to the large
+        * public IRC networks like QuakeNet, EFNet etc. To use no password in your
+        * IRC connection, use <code>""</code> or <code>null</code> for the
+        * password argument in the constructor.
+        * 
+        * @param host
+        *            The hostname of the server we want to connect to.
+        * @param portMin
+        *            The beginning of the port range we are going to connect to.
+        * @param portMax
+        *            The ending of the port range we are going to connect to.
+        * @param pass
+        *            The password of the IRC server. If your server isn't secured
+        *            by a password (that's normal), use <code>null</code> or
+        *            <code>""</code>.
+        * @param nick
+        *            The nickname for the connection. Is used to register the
+        *            connection.
+        * @param username
+        *            The username. Is used to register the connection.
+        * @param realname
+        *            The realname. Is used to register the connection.
+        * @throws IllegalArgumentException
+        *             If the <code>host</code> is <code>null</code>.
+        * @see #connect()
+        */
+       public IRCConnection(String host, int portMin, int portMax, String pass, String nick, String username, String realname)
+       {
+               this(host, portRangeToArray(portMin, portMax), pass, nick, username, realname);
+       }
+
+       // ------------------------------
+       /**
+        * Converts a portrange which starts with a given <code>int</code> and
+        * ends with a given <code>int</code> into an array which contains all
+        * <code>int</code>s from the beginning to the ending (including
+        * beginning and ending).<br />
+        * If <code>portMin > portMax</code>, the portrange is turned arount
+        * automatically.
+        * 
+        * @param portMin
+        *            The beginning port of the portrange.
+        * @param portMax
+        *            The ending port of the portrange.
+        */
+       private static int[] portRangeToArray(int portMin, int portMax)
+       {
+               if (portMin > portMax)
+               {
+                       int tmp = portMin;
+                       portMin = portMax;
+                       portMax = tmp;
+               }
+               int[] ports = new int[portMax - portMin + 1];
+               for (int i = 0; i < ports.length; i++)
+                       ports[i] = portMin + i;
+               return ports;
+       }
+
+       // ------------------------------
+       /**
+        * Establish a connection to the server. <br />
+        * This method must be invoked to start a connection; the constructor
+        * doesn't do that!<br />
+        * It tries all set ports until one is open. If all ports fail it throws an
+        * <code>IOException</code>.<br />
+        * You can invoke <code>connect</code> only one time.
+        * 
+        * @throws IOException
+        *             If an I/O error occurs.
+        * @throws SocketException
+        *             If the <code>connect</code> method was already invoked.
+        * @see #isConnected()
+        * @see #doQuit()
+        * @see #doQuit(String)
+        * @see #close()
+        */
+       public void connect() throws IOException
+       {
+               if (level != 0) // otherwise disconnected or connect
+                       throw new SocketException("Socket closed or already open (" + level + ")");
+               IOException exception = null;
+               Socket s = null;
+               for (int i = 0; i < _ports.length && s == null; i++)
+               {
+                       try
+                       {
+                               s = new Socket(_host, _ports[i]);
+                               exception = null;
+                       }
+                       catch (IOException exc)
+                       {
+                               if (s != null)
+                                       s.close();
+                               s = null;
+                               exception = exc;
+                       }
+               }
+               if (exception != null)
+                       throw exception; // connection wasn't successful at any port
+               prepare(s);
+       }
+
+       // ------------------------------
+       /**
+        * Invoked by the <code>connect</code> method, this method prepares the
+        * connection. <br />
+        * It initializes the class-vars for the inputstream and the outputstream of
+        * the socket, starts the registration of at the IRC server by calling
+        * <code>register()</code> and starts the receiving of lines from the
+        * server by starting the thread with the <code>start</code> method.<br />
+        * <br />
+        * This method must be protected, because it is used by extending classes,
+        * which override the <code>connect</code> method.
+        * 
+        * @param s
+        *            The socket which is used for the connection.
+        * @throws IOException
+        *             If an I/O error occurs.
+        * @see #connect()
+        * @see #run()
+        */
+       protected void prepare(Socket s) throws IOException
+       {
+               if (s == null)
+                       throw new SocketException("Socket s is null, not connected");
+               socket = s;
+               level = 1;
+               s.setSoTimeout(timeout);
+               in = new BufferedReader(new InputStreamReader(s.getInputStream(), _encoding));
+               out = new PrintWriter(new OutputStreamWriter(s.getOutputStream(), _encoding));
+               start();
+               register();
+       }
+
+       // ------------------------------
+       /**
+        * Registers the connection with the IRC server. <br />
+        * In fact, it sends a password (if set, else nothing), the nickname and the
+        * user, the realname and the host which we're connecting to.<br />
+        * The action synchronizes <code>code> so that no important messages 
+        * (like the first PING) come in before this registration is finished.<br />
+        * The <code>USER</code> command's format is:<br /><code>
+        * &lt;username&gt; &lt;localhost&gt; &lt;irchost&gt; &lt;realname&gt;
+        * </code>
+        */
+       private void register()
+       {
+               if (_pass != null)
+                       send("PASS " + _pass);
+               send("NICK " + _nick);
+               send("USER " + _username + " " + socket.getLocalAddress() + " " + _host + " :" + _realname);
+       }
+
+       // ------------------------------
+       /**
+        * The <code>Thread</code> is started by the <code>connect</code>
+        * method. It's task is to receive strings from the IRC server and hand them
+        * over to the <code>get</code> method.
+        */
+       @Override
+       public void run()
+       {
+               try
+               {
+                       String line;
+                       while (!isInterrupted())
+                       {
+                               line = in.readLine();
+                               if (line != null)
+                                       get(line);
+                               else
+                                       close();
+                       }
+               }
+               catch (IOException exc)
+               {
+                       close();
+               }
+       }
+
+       // ------------------------------
+       /**
+        * Sends a String to the server. You should use this method only, if you
+        * must do it. For most purposes, there are <code>do*</code> methods (like
+        * <code>doJoin</code>). A carriage return line feed (<code>\r\n</code>)
+        * is appended automatically.
+        * 
+        * @param line
+        *            The line which should be send to the server without the
+        *            trailing carriage return line feed (<code>\r\n</code>).
+        */
+       public void send(String line)
+       {
+               try
+               {
+                       out.write(line + "\r\n");
+                       out.flush();
+                       if (level == 1)
+                       { // not registered
+                               IRCParser p = new IRCParser(line);
+                               if (p.getCommand().equalsIgnoreCase("NICK"))
+                                       _nick = p.getParameter(1).trim();
+                       }
+               }
+               catch (Exception exc)
+               {
+                       exc.printStackTrace();
+               }
+       }
+
+       // ------------------------------
+       /**
+        * Just parses a String given as the only argument with the help of the
+        * <code>IRCParser</code> class. Then it controls the command and fires
+        * events through the <code>IRCEventListener</code>.<br />
+       * 
+        * @param line
+        *            The line which is sent from the server.
+        */
+       private synchronized void get(String line)
+       {
+               IRCParser p;
+               try
+               {
+                       p = new IRCParser(line, colorsEnabled);
+               }
+               catch (Exception exc)
+               {
+                       return;
+               }
+               String command = p.getCommand();
+               int reply; // 3-digit reply will be parsed in the later if-condition
+               if (command.equalsIgnoreCase("PRIVMSG"))
+               { // MESSAGE
+                       IRCUser user = p.getUser();
+                       String middle = p.getMiddle();
+                       String trailing = p.getTrailing();
+                       for (int i = listeners.length - 1; i >= 0; i--)
+                               listeners[i].onPrivmsg(middle, user, trailing);
+               }
+               else if (command.equalsIgnoreCase("MODE"))
+               { // MODE
+                       String chan = p.getParameter(1);
+                       if (IRCUtil.isChan(chan))
+                       {
+                               IRCUser user = p.getUser();
+                               String param2 = p.getParameter(2);
+                               String paramsFrom3 = p.getParametersFrom(3);
+                               for (int i = listeners.length - 1; i >= 0; i--)
+                                       listeners[i].onMode(chan, user, new IRCModeParser(param2, paramsFrom3));
+                       }
+                       else
+                       {
+                               IRCUser user = p.getUser();
+                               String paramsFrom2 = p.getParametersFrom(2);
+                               for (int i = listeners.length - 1; i >= 0; i--)
+                                       listeners[i].onMode(user, chan, paramsFrom2);
+                       }
+               }
+               else if (command.equalsIgnoreCase("PING"))
+               { // PING
+                      String ping = p.getTrailing(); // no int cause sometimes it's text
+                       if (pongAutomatic)
+                               doPong(ping);
+                       else
+                               for (int i = listeners.length - 1; i >= 0; i--)
+                                       listeners[i].onPing(ping);
+                       if (level == 1)
+                       { // not registered
+                               level = 2; // first PING received -> connection
+                              for (int i = listeners.length - 1; i >= 0; i--)
+                                       listeners[i].onRegistered();
+                       }
+               }
+               else if (command.equalsIgnoreCase("JOIN"))
+               { // JOIN
+                       IRCUser user = p.getUser();
+                       String trailing = p.getTrailing();
+                       for (int i = listeners.length - 1; i >= 0; i--)
+                               listeners[i].onJoin(trailing, user);
+               }
+               else if (command.equalsIgnoreCase("NICK"))
+               { // NICK
+                       IRCUser user = p.getUser();
+                       String changingNick = p.getNick();
+                       String newNick = p.getTrailing();
+                       if (changingNick.equalsIgnoreCase(_nick))
+                               _nick = newNick;
+                       for (int i = listeners.length - 1; i >= 0; i--)
+                               listeners[i].onNick(user, newNick);
+               }
+               else if (command.equalsIgnoreCase("QUIT"))
+               { // QUIT
+                       IRCUser user = p.getUser();
+                       String trailing = p.getTrailing();
+                       for (int i = listeners.length - 1; i >= 0; i--)
+                               listeners[i].onQuit(user, trailing);
+               }
+              else if (command.equalsIgnoreCase("PART"))
+               { // PART
+                       IRCUser user = p.getUser();
+                       String chan = p.getParameter(1);
+                       String msg = p.getParameterCount() > 1 ? p.getTrailing() : "";
+                       // not logic: "PART :#zentrum" is without msg, "PART #zentrum :cjo
+                       // all"
+                       // is with msg. so we cannot use getMiddle and getTrailing :-/
+                       for (int i = listeners.length - 1; i >= 0; i--)
+                              listeners[i].onPart(chan, user, msg);
+               }
+               else if (command.equalsIgnoreCase("NOTICE"))
+               { // NOTICE
+                       IRCUser user = p.getUser();
+                       String middle = p.getMiddle();
+                       String trailing = p.getTrailing();
+                       for (int i = listeners.length - 1; i >= 0; i--)
+                               listeners[i].onNotice(middle, user, trailing);
+              }
+               else if ((reply = IRCUtil.parseInt(command)) >= 1 && reply < 400)
+               { // RPL
+                      String potNick = p.getParameter(1);
+                       if ((level == 1 || level == 2) && _nick.length() > potNick.length() && _nick.substring(0, potNick.length()).equalsIgnoreCase(potNick))
+                       {
+                               _nick = potNick;
+                               if (level == 2)
+                                       level = 3;
+                       }
+                       if (level == 1)
+                       { // not registered
+                               level = 2; // if first PING wasn't received, we're
+                               for (int i = listeners.length - 1; i >= 0; i--)
+                                       listeners[i].onRegistered(); // connected now for sure
+                      }
+                       String middle = p.getMiddle();
+                       String trailing = p.getTrailing();
+                       for (int i = listeners.length - 1; i >= 0; i--)
+                               listeners[i].onReply(reply, middle, trailing);
+              }
+               else if (reply >= 400 && reply < 600)
+              { // ERROR
+                       String trailing = p.getTrailing();
+                       for (int i = listeners.length - 1; i >= 0; i--)
+                               listeners[i].onError(reply, trailing);
+               }
+               else if (command.equalsIgnoreCase("KICK"))
+               { // KICK
+                       IRCUser user = p.getUser();
+                      String param1 = p.getParameter(1);
+                       String param2 = p.getParameter(2);
+                       String msg = (p.getParameterCount() > 2) ? p.getTrailing() : "";
+                       for (int i = listeners.length - 1; i >= 0; i--)
+                               listeners[i].onKick(param1, user, param2, msg);
+               }
+               else if (command.equalsIgnoreCase("INVITE"))
+               { // INVITE
+                       IRCUser user = p.getUser();
+                       String middle = p.getMiddle();
+                       String trailing = p.getTrailing();
+                       for (int i = listeners.length - 1; i >= 0; i--)
+                               listeners[i].onInvite(trailing, user, middle);
+               }
+              else if (command.equalsIgnoreCase("TOPIC"))
+               { // TOPIC
+                       IRCUser user = p.getUser();
+                       String middle = p.getMiddle();
+                       String trailing = p.getTrailing();
+                       for (int i = listeners.length - 1; i >= 0; i--)
+                               listeners[i].onTopic(middle, user, trailing);
+               }
+               else if (command.equalsIgnoreCase("ERROR"))
+               { // ERROR
+                      String trailing = p.getTrailing();
+                       for (int i = listeners.length - 1; i >= 0; i--)
+                               listeners[i].onError(trailing);
+              }
+               else
+               { // OTHER
+                       String prefix = p.getPrefix();
+                      String middle = p.getMiddle();
+                       String trailing = p.getTrailing();
+                       for (int i = listeners.length - 1; i >= 0; i--)
+                               listeners[i].unknown(prefix, command, middle, trailing);
+              }
+       }
+
+       // ------------------------------
+       /**
+       * Close down the connection brutally. <br />
+        * It does *NOT* send the proper IRC command <code>QUIT</code>. You
+        * should always use the <code>doQuit</code> methods or
+        * <code>send("QUIT")</code> instead of this method. <br />
+        * You should use this method to close down the connection only when the IRC
+       * server doesn't react to the <code>QUIT</code> command.
+        * 
+        * @see #connect()
+        * @see #doQuit
+        * @see #doQuit(String)
+       */
+       public synchronized void close()
+       {
+               try
+               {
+                       if (!isInterrupted())
+                               interrupt();
+               }
+               catch (Exception exc)
+               {
+                       exc.printStackTrace();
+               }
+              try
+               {
+                       if (socket != null)
+                               socket.close();
+               }
+               catch (Exception exc)
+               {
+                       exc.printStackTrace();
+               }
+               try
+               {
+                       if (out != null)
+                               out.close();
+               }
+               catch (Exception exc)
+               {
+                       exc.printStackTrace();
+              }
+               try
+               {
+                       if (in != null)
+                               in.close();
+               }
+               catch (Exception exc)
+               {
+                       exc.printStackTrace();
+               }
+               if (level != -1)
+               {
+                       level = -1;
+                       for (int i = listeners.length - 1; i >= 0; i--)
+                               listeners[i].onDisconnected();
+               }
+              socket = null;
+               in = null;
+               out = null;
+               listeners = new IRCEventListener[0];
+      }
+
+      // ------------------------------
+       /**
+        * Adds a new {@link org.schwering.irc.lib.IRCEventListener} which listens
+        * for actions coming from the IRC server.
+        * 
+        * @param l
+        *            An instance of the
+        *            {@link org.schwering.irc.lib.IRCEventListener} interface.
+       * @throws IllegalArgumentException
+        *             If <code>listener</code> is <code>null</code>.
+       */
+       public synchronized void addIRCEventListener(IRCEventListener l)
+      {
+               if (l == null)
+                      throw new IllegalArgumentException("Listener is null.");
+               int len = listeners.length;
+               IRCEventListener[] oldListeners = listeners;
+               listeners = new IRCEventListener[len + 1];
+               System.arraycopy(oldListeners, 0, listeners, 0, len);
+               listeners[len] = l;
+       }
+
+       // ------------------------------
+       /**
+        * Removes the first occurence of the given
+        * {@link org.schwering.irc.lib.IRCEventListener} from the listener-vector.
+        * 
+        * @param l
+        *            An instance of the
+        *            {@link org.schwering.irc.lib.IRCEventListener} interface.
+        * @return <code>true</code> if the listener was successfully removed;
+        *         <code>false</code> if it was not found.
+        */
+       public synchronized boolean removeIRCEventListener(IRCEventListener l)
+       {
+               if (l == null)
+                       return false;
+               int index = -1;
+               for (int i = 0; i < listeners.length; i++)
+                       if (listeners[i].equals(l))
+                       {
+                              index = i;
+                               break;
+                       }
+               if (index == -1)
+                       return false;
+              listeners[index] = null;
+               int len = listeners.length - 1;
+               IRCEventListener[] newListeners = new IRCEventListener[len];
+               for (int i = 0, j = 0; i < len; j++)
+                       if (listeners[j] != null)
+                               newListeners[i++] = listeners[j];
+               listeners = newListeners;
+               return true;
+       }
+
+       // ------------------------------
+       /**
+        * Enables or disables the mIRC colorcodes.
+        * 
+        * @param colors
+        *            <code>true</code> to enable, <code>false</code> to disable
+        *            colors.
+        */
+      public void setColors(boolean colors)
+       {
+               colorsEnabled = colors;
+       }
+
+       // ------------------------------
+       /**
+        * Enables or disables the automatic PING? PONG! support.
+        * 
+        * @param pong
+        *            <code>true</code> to enable automatic <code>PONG</code>
+        *            reply, <code>false</code> makes the class fire
+        *            <code>onPing</code> events.
+       */
+       public void setPong(boolean pong)
+       {
+               pongAutomatic = pong;
+       }
+
+      // ------------------------------
+       /**
+        * Changes the character encoding used to talk to the server. This can be
+        * ISO-8859-1 or UTF-8 for example. This property must be set before a call
+        * to the <code>connect()</code> method.
+        * 
+        * @param encoding
+        */
+      public void setEncoding(String encoding)
+       {
+               this._encoding = encoding;
+       }
+
+       // ------------------------------
+       /**
+        * Sets the connection's timeout in milliseconds. <br />
+        * The default is <code>1000 * 60 15</code> millis which are 15 minutes.
+        */
+       public void setTimeout(int millis)
+      {
+               if (socket != null)
+                       try
+                      {
+                               socket.setSoTimeout(millis);
+                      }
+                       catch (IOException exc)
+                       {
+                               exc.printStackTrace();
+                       }
+               timeout = millis;
+      }
+
+       // ------------------------------
+      /**
+        * Tells whether there's a connection to the IRC network or not. <br />
+        * If <code>connect</code> wasn't called yet, it returns
+        * <code>false</code>.
+       * 
+        * @return The status of the connection; <code>true</code> if it's
+        *         connected.
+        * @see #connect()
+        * @see #doQuit()
+        * @see #doQuit(String)
+        * @see #close()
+        */
+       public boolean isConnected()
+      {
+               return level >= 1;
+       }
+
+       // ------------------------------
+       /**
+        * Returns the nickname of this instance.
+        * 
+        * @return The nickname.
+        */
+       public String getNick()
+      {
+               return _nick;
+       }
+
+       // ------------------------------
+       /**
+        * Returns the realname of this instance.
+        * 
+        * @return The realname.
+       */
+       public String getRealname()
+       {
+               return _realname;
+       }
+
+       // ------------------------------
+       /**
+        * Returns the username of this instance.
+        * 
+        * @return The username.
+        */
+      public String getUsername()
+       {
+              return _username;
+       }
+
+       // ------------------------------
+       /**
+        * Returns the server of this instance.
+        * 
+        * @return The server's hostname.
+        */
+       public String getHost()
+      {
+               return _host;
+       }
+
+       // ------------------------------
+       /**
+        * Returns the password of this instance. If no password is set,
+        * <code>null</code> is returned.
+        * 
+        * @return The password. If no password is set, <code>null</code> is
+        *         returned.
+        */
+       public String getPassword()
+       {
+               return _pass;
+      }
+
+      // ------------------------------
+       /**
+       * Returns all ports to which the <code>IRCConnection</code> is going to
+        * try or has tried to connect to.
+        * 
+        * @return The ports in an <code>int[]</code> array.
+        */
+       public int[] getPorts()
+      {
+               return _ports;
+      }
+
+       // ------------------------------
+       /**
+        * Returns the port to which the <code>IRCConnection</code> connected, or
+        * <code>0</code> if the connection failed or wasn't tried yet.
+        * 
+        * @return The port to which the <code>IRCConnection</code>, or
+        *         <code>0</code> if the connection failed or wasn't tried yet.
+        */
+       public int getPort()
+       {
+               return (socket != null) ? socket.getPort() : 0;
+       }
+       // ------------------------------
+      /**
+        * Indicates whether colors are stripped out or not.
+        * 
+        * @return <code>true</code> if colors are disabled.
+        */
+      public boolean getColors()
+       {
+               return colorsEnabled;
+       }
+
+       // ------------------------------
+       /**
+        * Indicates whether automatic PING? PONG! is enabled or not.
+       * 
+        * @return <code>true</code> if PING? PONG! is done automatically.
+       */
+       public boolean getPong()
+       {
+               return pongAutomatic;
+       }
+       // ------------------------------
+      /**
+        * Returns the encoding of the socket.
+        * 
+        * @return The socket's encoding.
+        */
+       public String getEncoding()
+       {
+              return _encoding;
+       }
+
+       // ------------------------------
+       /**
+        * Returns the timeout of the socket. <br />
+       * If an error occurs, which is never the case, <code>-1</code> is
+        * returned.
+        * 
+        * @return The timeout.
+        */
+       public int getTimeout()
+       {
+               if (socket != null)
+                       try
+                       {
+                               return socket.getSoTimeout();
+                      }
+                       catch (IOException exc)
+                       {
+                               exc.printStackTrace();
+                              return -1;
+                       }
+               else
+                       return timeout;
+       }
+
+       // ------------------------------
+       /**
+        * Generates a <code>String</code> with some information about the
+        * instance of <code>IRCConnection</code>. Its format is: <code>
+        * classname[host,portMin,portMax,username,nick,realname,pass,connected]
+        * </code>.
+        * 
+        * @return A <code>String</code> with information about the instance.
+        */
+       @Override
+       public String toString()
+       {
+               return getClass().getName() + "[" + _host + "," + getPort() + "," + _username + "," + _nick + "," + _realname + "," + _pass + "," + isConnected() + "]";
+       }
+       // ------------------------------
+       /**
+        * Removes away message.
+        */
+       public void doAway()
+       {
+               send("AWAY");
+      }
+
+       // ------------------------------
+       /**
+        * Sets away message.
+        * 
+        * @param msg
+        *            The away message.
+        */
+       public void doAway(String msg)
+       {
+               send("AWAY :" + msg);
+       }
+
+       // ------------------------------
+       /**
+       * Invites a user to a channel.
+        * 
+        * @param nick
+       *            The nickname of the user who should be invited.
+        * @param chan
+        *            The channel the user should be invited to.
+        */
+       public void doInvite(String nick, String chan)
+       {
+               send("INVITE " + nick + " " + chan);
+       }
+
+       // ------------------------------
+       /**
+       * Checks if one or more nicks are used on the server.
+        * 
+        * @param nick
+        *            The nickname of the user we search for.
+        */
+       public void doIson(String nick)
+       {
+               send("ISON " + nick);
+       }
+
+       // ------------------------------
+       /**
+        * Joins a channel without a key.
+        * 
+        * @param chan
+        *            The channel which is to join.
+        */
+       public void doJoin(String chan)
+      {
+               send("JOIN " + chan);
+       }
+
+       // ------------------------------
+      /**
+        * Joins a channel with a key.
+        * 
+        * @param chan
+        *            The channel which is to join.
+        * @param key
+        *            The key of the channel.
+       */
+       public void doJoin(String chan, String key)
+       {
+               send("JOIN " + chan + " " + key);
+       }
+
+       // ------------------------------
+      /**
+        * Kicks a user from a channel.
+        * 
+        * @param chan
+        *            The channel somebody should be kicked from.
+        * @param nick
+        *            The nickname of the user who should be kicked.
+        */
+       public void doKick(String chan, String nick)
+       {
+               send("KICK " + chan + " " + nick);
+       }
+
+      // ------------------------------
+       /**
+        * Kicks a user from a channel with a comment.
+        * 
+        * @param chan
+        *            The channel somebody should be kicked from.
+        * @param nick
+        *            The nickname of the user who should be kicked.
+        * @param msg
+        *            The optional kickmessage.
+        */
+       public void doKick(String chan, String nick, String msg)
+       {
+               send("KICK " + chan + " " + nick + " :" + msg);
+       }
+
+       // ------------------------------
+       /**
+        * Lists all channels with their topic and status.
+        */
+      public void doList()
+       {
+               send("LIST");
+       }
+
+       // ------------------------------
+       /**
+        * Lists channel(s) with their topic and status.
+        * 
+        * @param chan
+       *            The channel the <code>LIST</code> refers to.
+        */
+       public void doList(String chan)
+       {
+               send("LIST " + chan);
+       }
+       // ------------------------------
+       /**
+        * Lists all visible users.
+        */
+      public void doNames()
+       {
+              send("NAMES");
+       }
+
+       // ------------------------------
+       /**
+        * Lists all visible users of (a) channel(s).
+       * 
+        * @param chan
+        *            The channel the <code>NAMES</code> command is refering to.
+        */
+       public void doNames(String chan)
+       {
+               send("NAMES " + chan);
+       }
+      // ------------------------------
+       /**
+        * Sends a message to a person or a channel.
+       * 
+        * @param target
+        *            The nickname or channel the message should be sent to.
+        * @param msg
+       *            The message which should be transmitted.
+        */
+       public void doPrivmsg(String target, String msg)
+       {
+              send("PRIVMSG " + target + " :" + msg);
+       }
+
+       // ------------------------------
+      /**
+        * Requests a Reply 324 for the modes of a given channel.
+        * 
+        * @param chan
+        *            The channel the <code>MODE</code> request is refering to.
+        */
+       public void doMode(String chan)
+       {
+               send("MODE " + chan);
+       }
+
+       // ------------------------------
+       /**
+        * Sends a mode to the server. <br />
+        * The first argument is a nickname (user-mode) or a channel (channel-mode).
+        * <code>String mode</code> must contain the operators (+/-), the modes
+        * (o/v/i/k/l/p/s/w) and the possibly values (nicks/banmask/limit/key).
+        * 
+        * @param target
+        *            The nickname or channel of the user whose modes will be
+       *            changed.
+        * @param mode
+        *            The new modes.
+        */
+       public void doMode(String target, String mode)
+      {
+               send("MODE " + target + " " + mode);
+       }
+
+       // ------------------------------
+      /**
+        * Changes the nickname.
+        * 
+        * @param nick
+        *            The new nickname.
+        */
+      public void doNick(String nick)
+       {
+               send("NICK " + nick);
+       }
+
+       // ------------------------------
+       /**
+        * Notices a message to a person or a channel.
+        * 
+       * @param target
+        *            The nickname or channel (group) the message should be sent to.
+        * @param msg
+        *            The message which should be transmitted.
+        */
+      public void doNotice(String target, String msg)
+       {
+               send("NOTICE " + target + " :" + msg);
+       }
+
+       // ------------------------------
+       /**
+       * Parts from a given channel.
+        * 
+        * @param chan
+        *            The channel you want to part from.
+        */
+       public void doPart(String chan)
+       {
+               send("PART " + chan);
+       }
+       // ------------------------------
+       /**
+        * Parts from a given channel with a given parg-msg.
+        * 
+        * @param chan
+        *            The channel you want to part from.
+        * @param msg
+        *            The optional partmessage.
+       */
+       public void doPart(String chan, String msg)
+      {
+               send("PART " + chan + " :" + msg);
+       }
+
+       // ------------------------------
+       /**
+        * Quits from the IRC server with a quit-msg.
+        * 
+        * @param ping
+        *            The ping which was received in <code>onPing</code>. It's a
+        *            <code>String</code>, because sometimes on some networks the
+        *            server-hostname (for example splatterworld.quakenet.org) is
+        *            given as parameter which would throw an Exception if we gave
+        *            the ping as long.
+        */
+       public void doPong(String ping)
+       {
+              send("PONG :" + ping);
+       }
+
+       // ------------------------------
+       /**
+        * Quits from the IRC server. Calls the <code>disconnect</code>-method
+        * which does the work actually.
+        * 
+        * @see #isConnected()
+        * @see #connect()
+        * @see #doQuit(String)
+       * @see #close()
+        */
+       public void doQuit()
+      {
+               send("QUIT");
+       }
+
+       // ------------------------------
+       /**
+        * Quits from the IRC server with a quit-msg. Calls the
+        * <code>disconnect</code>-method which does the work actually.
+        * 
+        * @param msg
+        *            The optional quitmessage.
+        * @see #isConnected()
+        * @see #connect()
+        * @see #doQuit()
+       * @see #close()
+        */
+       public void doQuit(String msg)
+       {
+               send("QUIT :" + msg);
+       }
+       // ------------------------------
+       /**
+        * Requests the topic of a chan. The topic is given in a numeric reply.
+        * 
+        * @param chan
+        *            The channel which topic should be requested.
+        */
+       public void doTopic(String chan)
+       {
+               send("TOPIC " + chan);
+       }
+
+       // ------------------------------
+       /**
+        * Changes the topic of a chan.
+        * 
+        * @param chan
+        *            The channel which topic is changed.
+        * @param topic
+        *            The new topic.
+        */
+       public void doTopic(String chan, String topic)
+       {
+              send("TOPIC " + chan + " :" + topic);
+       }
+
+       // ------------------------------
+       /**
+        * Requests information about users matching the given criteric, for example
+        * a channel they are on.
+        * 
+        * @param criteric
+        *            The criterics of the <code>WHO</code> query.
+        */
+       public void doWho(String criteric)
+       {
+               send("WHO " + criteric);
+       }
+
+       // ------------------------------
+       /**
+        * Requires information about an existing user.
+        * 
+        * @param nick
+        *            The nickname of the user the query is refering to.
+        */
+       public void doWhois(String nick)
+       {
+               send("WHOIS " + nick);
+       }
+
+       // ------------------------------
+       /**
+        * Requires host-information about a user, who is not connected anymore.
+       * 
+        * @param nick
+        *            The nickname of the user the query is refering to.
+        */
+       public void doWhowas(String nick)
+       {
+               send("WHOWAS " + nick);
+       }
+
+       // ------------------------------
+       /**
+        * Requires host-information about up to 5 users which must be listed and
+        * divided by spaces.
+        * 
+        * @param nick
+        *            The nickname of the user the query is refering to.
+        */
+       public void doUserhost(String nick)
+       {
+              send("USERHOST " + nick);
+       }
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/IrcCommandHandler.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/IrcCommandHandler.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/IrcCommandHandler.java	(revision 0)
@@ -0,0 +1,93 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.handler;
+
+import java.util.Map;
+import java.util.logging.Logger;
+
+import javolution.util.FastMap;
+import net.sf.l2j.Config;
+import net.sf.l2j.gameserver.handler.irccommandhandlers.IrcAnnounce;
+import net.sf.l2j.gameserver.handler.irccommandhandlers.IrcJail;
+import net.sf.l2j.gameserver.handler.irccommandhandlers.IrcKick;
+import net.sf.l2j.gameserver.handler.irccommandhandlers.IrcShutdown;
+import net.sf.l2j.gameserver.handler.irccommandhandlers.IrcStatus;
+
+/**
+ * @author nBd
+ */
+
+public class IrcCommandHandler
+{
+       private static Logger _log = Logger.getLogger(IrcCommandHandler.class.getName());
+
+       private static IrcCommandHandler _instance;
+
+       private Map<String, IIrcCommandHandler> _datatable;
+
+       public static IrcCommandHandler getInstance()
+       {
+               if (_instance == null)
+               {
+                      _instance = new IrcCommandHandler();
+               }
+               return _instance;
+       }
+
+       private IrcCommandHandler()
+       {
+               _datatable = new FastMap<String, IIrcCommandHandler>();
+               registerIrcCommandHandler(new IrcAnnounce());
+               registerIrcCommandHandler(new IrcShutdown());
+               registerIrcCommandHandler(new IrcStatus());
+               registerIrcCommandHandler(new IrcKick());
+              registerIrcCommandHandler(new IrcJail());
+        _log.config("BypassCommandHandler: Loaded " + _datatable.size() + " handlers.");
+      }
+
+       public void registerIrcCommandHandler(IIrcCommandHandler handler)
+       {
+               String[] ids = handler.getIrcCommandList();
+
+               for (String element : ids)
+               {
+                      if (Config.DEBUG) _log.fine("Adding handler for command "+element);
+                               _datatable.put(element, handler);
+               }
+       }
+
+       public IIrcCommandHandler getIrcCommandHandler(String BypassCommand)
+       {
+               String command = BypassCommand;
+
+               if (BypassCommand.indexOf(" ") != -1)
+               {
+                       command = BypassCommand.substring(0, BypassCommand.indexOf(" "));
+               }
+
+               if (Config.DEBUG)
+                       _log.fine("getting handler for command: "+command+ " -> "+(_datatable.get(command) != null));
+
+               return _datatable.get(command);
+       }
+
+    /**
+     * @return
+     */
+    public int size()
+    {
+        return _datatable.size();
+   }
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcKick.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcKick.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcKick.java	(revision 0)
@@ -0,0 +1,90 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
++ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.handler.irccommandhandlers;
+
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+import net.sf.l2j.gameserver.handler.IIrcCommandHandler;
+import net.sf.l2j.gameserver.instancemanager.IrcManager;
+import net.sf.l2j.gameserver.model.L2World;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.serverpackets.LeaveWorld;
+
+/**
+ * @author Daedalus
+ */
+public class IrcKick implements IIrcCommandHandler
+{
+    private static final String[] IRC_COMMANDS =
+    {
+        "!kick","!kick_nongm"
+    };
+
+    public boolean useIrcCommand(String command, String gm, String target, boolean authed)
+    {
+        if (!authed)
+            return false;
+        
+        StringTokenizer st = new StringTokenizer(command);
+        st.nextToken();
+        String player = "";
+        
+        if (command.startsWith("!kick_nongm"))
+        {
+            int counter = 0;
+            for (L2PcInstance plyr : L2World.getInstance().getAllPlayers())
+            {
+                if(!plyr.isGM())
+                {
+                    counter++;
+                    plyr.sendPacket(new LeaveWorld());
+                    plyr.logout();
+                }
+            }
+            IrcManager.getInstance().getConnection().sendAdminChan("Kicked "+counter+" players");
+        }
+        else if (command.startsWith("!kick"))
+        {
+            try
+            {
+                player = st.nextToken();
+                L2PcInstance plyr = L2World.getInstance().getPlayer(player);
+                if (plyr != null)
+                {
+                    plyr.logout();
+                    IrcManager.getInstance().getConnection().sendAdminChan("You kicked " + plyr.getName() + " from the game.");
+                }             
+            }
+            catch (NoSuchElementException nsee)
+            {
+                IrcManager.getInstance().getConnection().sendAdminChan("Specify a character name.");
+            }
+            catch (NumberFormatException nfe)
+            {
+                IrcManager.getInstance().getConnection().sendAdminChan("Usage: !kick <charname>");
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+        }
+        return true;
+    }
+    
+    public String[] getIrcCommandList()
+    {
+        return IRC_COMMANDS;
+    }
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcStatus.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcStatus.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcStatus.java	(revision 0)
@@ -0,0 +1,152 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.handler.irccommandhandlers;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import net.sf.l2j.gameserver.GameServer;
+import net.sf.l2j.gameserver.GameTimeController;
+import net.sf.l2j.gameserver.GmListTable;
+import net.sf.l2j.gameserver.LoginServerThread;
+import net.sf.l2j.gameserver.handler.IIrcCommandHandler;
+import net.sf.l2j.gameserver.instancemanager.IrcManager;
+import net.sf.l2j.gameserver.model.L2Character;
+import net.sf.l2j.gameserver.model.L2ItemInstance;
+import net.sf.l2j.gameserver.model.L2Object;
+import net.sf.l2j.gameserver.model.L2Summon;
+import net.sf.l2j.gameserver.model.L2World;
+import net.sf.l2j.gameserver.model.actor.instance.L2DoorInstance;
+import net.sf.l2j.gameserver.model.actor.instance.L2MonsterInstance;
+import net.sf.l2j.gameserver.model.actor.instance.L2NpcInstance;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author nBd
+ */
+
+public class IrcStatus implements IIrcCommandHandler
+{      
+      private static final String[] IRC_COMMANDS =
+       {
+               "!status"
+       };
+      
+       @SuppressWarnings("deprecation")
+       public boolean useIrcCommand(String command, String gm, String target, boolean authed)
+       {
+               if (!authed)
+                       return false;
+               
+               if (command.equalsIgnoreCase("!status"))
+               {
+                       int playerCount = 0, objectCount = 0;
+                       int max = LoginServerThread.getInstance().getMaxPlayer();
+                      playerCount = L2World.getInstance().getAllPlayersCount();
+                       objectCount = L2World.getInstance().getAllVisibleObjectsCount();
+                       int itemCount = 0;
+                       int itemVoidCount = 0;
+                       int monsterCount = 0;
+                      int minionCount = 0;
+                       int minionsGroupCount = 0;
+                       int npcCount = 0;
+                       int charCount = 0;
+                       int pcCount = 0;
+                       int doorCount = 0;
+                       int summonCount = 0;
+                       int AICount = 0;
+                       for (L2Object obj : L2World.getInstance().getAllVisibleObjects())
+                       {
+                               if (obj == null)
+                                       continue;
+                               if (obj instanceof L2Character)
+                                       if (((L2Character) obj).hasAI())
+                                              AICount++;
+                               if (obj instanceof L2ItemInstance)
+                                       if (((L2ItemInstance) obj).getLocation() == L2ItemInstance.ItemLocation.VOID)
+                                               itemVoidCount++;
+                                       else
+                                               itemCount++;
+                               else if (obj instanceof L2MonsterInstance)
+                               {
+                                       monsterCount++;
+                                       minionCount += ((L2MonsterInstance) obj).getTotalSpawnedMinionsInstances();
+                                       minionsGroupCount += ((L2MonsterInstance) obj).getTotalSpawnedMinionsGroups();
+                               }
+                               else if (obj instanceof L2NpcInstance)
+                                      npcCount++;
+                               else if (obj instanceof L2PcInstance)
+                                       pcCount++;
+                               else if (obj instanceof L2Summon)
+                                       summonCount++;
+                               else if (obj instanceof L2DoorInstance)
+                                      doorCount++;
+                               else if (obj instanceof L2Character)
+                                       charCount++;
+                       }
+                       IrcManager.getInstance().getConnection().sendAdminChan("Server Status: ");
+                       IrcManager.getInstance().getConnection().sendAdminChan("  --->  Player Count: " + playerCount + "/" + max);
+                       IrcManager.getInstance().getConnection().sendAdminChan("  +-->  Object Count: " + objectCount);
+                       IrcManager.getInstance().getConnection().sendAdminChan("  +-->      AI Count: " + AICount);
+                       IrcManager.getInstance().getConnection().sendAdminChan("  +.... L2Item(Void): " + itemVoidCount);
+                       IrcManager.getInstance().getConnection().sendAdminChan("  +.......... L2Item: " + itemCount);
+                       IrcManager.getInstance().getConnection().sendAdminChan("  +....... L2Monster: " + monsterCount);
+                       IrcManager.getInstance().getConnection().sendAdminChan("  +......... Minions: " + minionCount);
+                       IrcManager.getInstance().getConnection().sendAdminChan("  +.. Minions Groups: " + minionsGroupCount);
+                       IrcManager.getInstance().getConnection().sendAdminChan("  +........... L2Npc: " + npcCount);
+                       IrcManager.getInstance().getConnection().sendAdminChan("  +............ L2Pc: " + pcCount);
+                       IrcManager.getInstance().getConnection().sendAdminChan("  +........ L2Summon: " + summonCount);
+                       IrcManager.getInstance().getConnection().sendAdminChan("  +.......... L2Door: " + doorCount);
+                       IrcManager.getInstance().getConnection().sendAdminChan("  +.......... L2Char: " + charCount);
+                       IrcManager.getInstance().getConnection().sendAdminChan("  --->   Ingame Time: " + gameTime());
+                       IrcManager.getInstance().getConnection().sendAdminChan("  ---> Server Uptime: " + getUptime(GameServer.dateTimeServerStarted.getTimeInMillis()));
+                       IrcManager.getInstance().getConnection().sendAdminChan("  --->      GM Count: " + getOnlineGMS());
+                       IrcManager.getInstance().getConnection().sendAdminChan("  --->       Threads: " + Thread.activeCount());
+                       IrcManager.getInstance().getConnection().sendAdminChan("  RAM Used: " + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1048576));
+               }
+               return true;
+       }
+       
+      private String gameTime()
+       {
+               int t = GameTimeController.getInstance().getGameTime();
+               int h = t / 60;
+               int m = t % 60;
+               SimpleDateFormat format = new SimpleDateFormat("H:mm");
+               Calendar cal = Calendar.getInstance();
+               cal.set(Calendar.HOUR_OF_DAY, h);
+               cal.set(Calendar.MINUTE, m);
+               return format.format(cal.getTime());
+       }
+       
+       private String getUptime(long time)
+    {
+               long uptime = (System.currentTimeMillis() - time);
+        uptime = uptime / 1000;
+        long h = uptime / 3600;
+        long m = (uptime-(h*3600))/60;
+        long s = ((uptime-(h*3600))-(m*60));
+        return h + "hrs " + m + "mins " + s + "secs";
+    }
+       
+       private int getOnlineGMS()
+       {
+               return GmListTable.getInstance().getAllGms(true).size();
+       }
+       
+       public String[] getIrcCommandList()
+       {
+               return IRC_COMMANDS;
+       }
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcAnnounce.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcAnnounce.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcAnnounce.java	(revision 0)
@@ -0,0 +1,46 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.handler.irccommandhandlers;
+
+import net.sf.l2j.gameserver.Announcements;
+import net.sf.l2j.gameserver.handler.IIrcCommandHandler;
+
+/**
+ * @author nBd
+ */
+public class IrcAnnounce implements IIrcCommandHandler
+{
+       private static final String[] IRC_COMMANDS =
+       {
+               "!announce"
+       };
+
+       public boolean useIrcCommand(String command, String gm, String target, boolean authed)
+       {
+               if (!authed)
+                       return false;
+               
+               if (command.startsWith("!announce "))
+               {
+                       Announcements.getInstance().handleAnnounce(command, 10);
+               }
+               return true;
+       }
+
+       public String[] getIrcCommandList()
+       {
+               return IRC_COMMANDS;
+       }
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcShutdown.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcShutdown.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcShutdown.java	(revision 0)
@@ -0,0 +1,57 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.handler.irccommandhandlers;
+
+import net.sf.l2j.gameserver.Shutdown;
+import net.sf.l2j.gameserver.handler.IIrcCommandHandler;
+
+/**
+ * @author nBd
+ */
+
+public class IrcShutdown implements IIrcCommandHandler
+{
+       private static final String[] IRC_COMMANDS =
+       {
+               "!shutdown", "!restart", "!abort"
+       };
+       
+       public boolean useIrcCommand(String command, String gm, String target, boolean authed)
+       {
+               if (!authed)
+                       return false;
+               
+               if (command.startsWith("!shutdown "))
+              {
+                       int val = Integer.parseInt(command.substring(10));
+                       Shutdown.getInstance().startShutdown(gm, val, false);
+               }
+               else if (command.startsWith("!restart "))
+               {               
+                       int val = Integer.parseInt(command.substring(9));
+                       Shutdown.getInstance().startShutdown(gm, val, true);
+               }
+               else if (command.equalsIgnoreCase("!abort"))
+               {                       
+                       Shutdown.getInstance().abort(gm);
+               }
+               return true;
+       }
+       
+       public String[] getIrcCommandList()
+       {
+               return IRC_COMMANDS;
+       }
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcJail.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcJail.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/irccommandhandlers/IrcJail.java	(revision 0)
@@ -0,0 +1,188 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.handler.irccommandhandlers;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+import net.sf.l2j.Config;
+import net.sf.l2j.L2DatabaseFactory;
+import net.sf.l2j.gameserver.handler.IIrcCommandHandler;
+import net.sf.l2j.gameserver.instancemanager.IrcManager;
+import net.sf.l2j.gameserver.model.L2World;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author Daedalus
+ */
+public class IrcJail implements IIrcCommandHandler
+{
+   private static final String[] IRC_COMMANDS =
+    {
+        "!jail", "!unjail"
+    };
+
+    public boolean useIrcCommand(String command, String gm, String target, boolean authed)
+    {
+        if (!authed)
+            return false;
+        
+        StringTokenizer st = new StringTokenizer(command);
+        st.nextToken();
+        String player = "";
+        
+        if (command.startsWith("!jail"))
+        {
+            try
+            {
+                player = st.nextToken();
+                int delay = 0;
+                try
+               {
+                    delay = Integer.parseInt(st.nextToken());
+                }
+                catch (NumberFormatException nfe)
+                {
+                   IrcManager.getInstance().getConnection().sendAdminChan("Usage: !jail <charname> [penalty_minutes]");
+                }
+                catch (NoSuchElementException nsee)
+               {
+                }
+                L2PcInstance playerObj = L2World.getInstance().getPlayer(player);
+                if (playerObj != null)
+                {
+                    playerObj.setInJail(true, delay);
+                   IrcManager.getInstance().getConnection().sendAdminChan("Character " + player + " has been jailed for " + (delay > 0 ? delay + " minutes!" : "ever!"));
+                }
+                else
+                    IRCjailOfflinePlayer(player, delay);
+            }
+            catch (NoSuchElementException nsee)
+            {
+                IrcManager.getInstance().getConnection().sendAdminChan("Usage: !jail <charname> [penalty_minutes]");
+            }
+            catch (Exception e)
+            {
+                if (Config.DEBUG)
+                    e.printStackTrace();
+           }
+        }
+        else if (command.startsWith("!unjail"))
+        {
+            try
+            {
+                player = st.nextToken();
+                L2PcInstance playerObj = L2World.getInstance().getPlayer(player);
+                if (playerObj != null)
+                {
+                    playerObj.setInJail(false, 0);
+                    IrcManager.getInstance().getConnection().sendAdminChan("Character "+player+" removed from jail");
+                }
+                else
+                    IRCunjailOfflinePlayer(player);
+            }
+            catch (NoSuchElementException nsee)
+            {
+                IrcManager.getInstance().getConnection().sendAdminChan("Specify a character name.");
+            }
+            catch (Exception e)
+            {
+               if (Config.DEBUG)
+                    e.printStackTrace();
+           }
+        }
+       return true;
+    }
+    private void IRCjailOfflinePlayer(String name, int delay)
+    {
+       Connection con = null;
+        try
+       {
+            con = L2DatabaseFactory.getInstance().getConnection();
+
+           PreparedStatement statement = con.prepareStatement("UPDATE characters SET x=?, y=?, z=?, in_jail=?, jail_timer=? WHERE char_name=?");
+            statement.setInt(1, -114356);
+            statement.setInt(2, -249645);
+            statement.setInt(3, -2984);
+            statement.setInt(4, 1);
+            statement.setLong(5, delay * 60000L);
+            statement.setString(6, name);
+
+            statement.execute();
+            int count = statement.getUpdateCount();
+            statement.close();
+
+            if (count == 0)
+                IrcManager.getInstance().getConnection().sendAdminChan("Character not found!");
+           else
+                IrcManager.getInstance().getConnection().sendAdminChan("Character "+name+" jailed for "+(delay>0 ? delay+" minutes." : "ever!"));
+        } catch (SQLException se)
+        {
+           IrcManager.getInstance().getConnection().sendAdminChan("SQLException while jailing player");
+            if (Config.DEBUG) se.printStackTrace();
+        } finally
+        {
+            try { con.close(); } catch (Exception e)
+            {
+                if (Config.DEBUG)
+                    e.printStackTrace();
+            }
+       }
+    }
+
+    private void IRCunjailOfflinePlayer(String name)
+    {
+        Connection con = null;
+       try
+        {
+            con = L2DatabaseFactory.getInstance().getConnection();
+            PreparedStatement statement = con.prepareStatement("UPDATE characters SET x=?, y=?, z=?, in_jail=?, jail_timer=? WHERE char_name=?");
+            statement.setInt(1, 17836);
+            statement.setInt(2, 170178);
+           statement.setInt(3, -3507);
+            statement.setInt(4, 0);
+           statement.setLong(5, 0);
+            statement.setString(6, name);
+            statement.execute();
+            int count = statement.getUpdateCount();
+            statement.close();
+            if (count == 0)
+                IrcManager.getInstance().getConnection().sendAdminChan("Character not found!");
+           else
+                IrcManager.getInstance().getConnection().sendAdminChan("Character "+name+" removed from jail");
+        } catch (SQLException se)
+        {
+            IrcManager.getInstance().getConnection().sendAdminChan("SQLException while jailing player");
+            if (Config.DEBUG) se.printStackTrace();
+        } finally
+        {
+            try 
+            {
+                con.close();
+            }
+           catch (Exception e)
+            {
+                if (Config.DEBUG)
+                    e.printStackTrace();
+            }
+        }
+    }
+    public String[] getIrcCommandList()
+   {
+        return IRC_COMMANDS;
+    }
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/IIrcCommandHandler.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/IIrcCommandHandler.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/handler/IIrcCommandHandler.java	(revision 0)
@@ -0,0 +1,36 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.handler;
+
+/**
+ *
+ * @author  nBd
+ */
+public interface IIrcCommandHandler
+{
+       /**
+        * this is the worker method that is called when someone uses an bypass command.
+        * @param activeChar
+        * @param command
+        * @return command success
+       */
+       public boolean useIrcCommand(String command, String gm, String target, boolean authed);
+       
+       /**
+        * this method is called at initialization to register all the item ids automatically 
+        * @return all known itemIds
+        */
+       public String[] getIrcCommandList();
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/GameServer.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/GameServer.java	(revision 62)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/GameServer.java	(working copy)
@@ -60,6 +60,7 @@
 import net.sf.l2j.gameserver.geoeditorcon.GeoEditorListener;
 import net.sf.l2j.gameserver.handler.AdminCommandHandler;
 import net.sf.l2j.gameserver.handler.ItemHandler;
+import net.sf.l2j.gameserver.handler.IrcCommandHandler;
 import net.sf.l2j.gameserver.handler.SkillHandler;
 import net.sf.l2j.gameserver.handler.UserCommandHandler;
 import net.sf.l2j.gameserver.handler.VoicedCommandHandler;
@@ -216,6 +217,7 @@
 import net.sf.l2j.gameserver.instancemanager.FortManager; 
 import net.sf.l2j.gameserver.instancemanager.FortSiegeManager;
 import net.sf.l2j.gameserver.instancemanager.GrandBossManager;
+import net.sf.l2j.gameserver.instancemanager.IrcManager;
 import net.sf.l2j.gameserver.instancemanager.ItemsOnGroundManager;
 import net.sf.l2j.gameserver.instancemanager.MercTicketManager;
 import net.sf.l2j.gameserver.instancemanager.PetitionManager;
@@ -637,6 +639,8 @@
 						
 		if(Config.L2JMOD_ALLOW_WEDDING)
 			CoupleManager.getInstance();
+		
+		IrcCommandHandler.getInstance();
 
         TaskManager.getInstance();
 
@@ -733,8 +737,11 @@
 		    _statusServer = new Status(Server.serverMode);
 		    _statusServer.start();
 		}
-		else {
+		else 
+		{
 		    _log.info("Telnet server is currently disabled.");
 		}
+		if (Config.IRC_ENABLED)
+		       IrcManager.getInstance().getConnection().sendChan("GameServer Started");
     }
 }
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/instancemanager/IrcManager.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/instancemanager/IrcManager.java	(revision 0)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/instancemanager/IrcManager.java	(revision 0)
@@ -0,0 +1,102 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.instancemanager;
+import java.util.logging.Logger;
+
+import net.sf.l2j.Config;
+import net.sf.l2j.gameserver.network.L2IrcClient;
+/**
+ * @author evill33t
+ * 
+ */
+public class IrcManager
+{
+    private static final Logger _log = Logger.getLogger(IrcManager.class.getName());
+
+       // =========================================================
+       private static IrcManager _Instance;
+
+       private static L2IrcClient _IrcConnection;
+
+       public static final IrcManager getInstance()
+       {
+               if (_Instance == null)
+               {
+                       _log.info("Initializing IrcManager");
+                       _Instance = new IrcManager();
+                       _Instance.load();
+               }
+               return _Instance;
+       }
+
+       // =========================================================
+       // =========================================================
+       // Method - Public
+       public void reload()
+       {
+               _IrcConnection.disconnect();
+               try
+               {
+                       _IrcConnection.connect();
+               }
+               catch (Exception e)
+               {
+                       _log.warning(e.toString());
+               }
+       }
+       
+       public void reConnect()
+       {
+               _IrcConnection = null;
+               _IrcConnection = new L2IrcClient(Config.IRC_SERVER, Config.IRC_PORT, Config.IRC_PASS, Config.IRC_NICK, Config.IRC_USER,
+                               Config.IRC_NAME, Config.IRC_SSL, Config.IRC_CHANNEL);
+               try
+               {
+                       _IrcConnection.connect();
+               }
+               catch (Exception e)
+               {
+            _log.warning(e.toString());
+               }
+       }
+
+       public L2IrcClient getConnection()
+       {
+               return _IrcConnection;
+       }
+       
+       public void removeConnection()
+       {
+               _IrcConnection.disconnect();
+               _IrcConnection = null;
+               load();
+       }
+
+       // =========================================================
+       // Method - Private
+       private final void load()
+       {
+               _IrcConnection = new L2IrcClient(Config.IRC_SERVER, Config.IRC_PORT, Config.IRC_PASS, Config.IRC_NICK, Config.IRC_USER,
+                               Config.IRC_NAME, Config.IRC_SSL, Config.IRC_CHANNEL);
+               try
+               {
+                       _IrcConnection.connect();
+               }
+               catch (Exception e)
+               {
+            _log.warning(e.toString());
+               }
+       }
+}
Index: D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/util/IllegalPlayerAction.java
===================================================================
--- D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/util/IllegalPlayerAction.java	(revision 62)
+++ D:/L2J Workspace/L2_GameServer_CT1/java/net/sf/l2j/gameserver/util/IllegalPlayerAction.java	(working copy)
@@ -30,6 +30,7 @@
 
 import net.sf.l2j.Config;
 import net.sf.l2j.gameserver.GmListTable;
+import net.sf.l2j.gameserver.instancemanager.IrcManager;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
 
 /**
@@ -77,6 +78,9 @@
 		record.setLoggerName("audit");
 		record.setParameters(new Object[]{_actor, _punishment});
 		_logAudit.log(record);
+		
+		if (Config.IRC_ENABLED)
+		          IrcManager.getInstance().getConnection().sendAdminChan("4Warning: " + _message);
 
         GmListTable.broadcastMessageToGMs(_message);