All pastes #549251 Raw Edit

Something

public text v1 · immutable
·published 2007-06-08 01:47 UTC
rendered paste body
Index: sql/MangChat.sql
===================================================================
--- sql/MangChat.sql	(revision 0)
+++ sql/MangChat.sql	(revision 0)
@@ -0,0 +1,46 @@
+-- MySQL dump 10.11
+--
+-- Host: localhost    Database: mangos
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `irc_inchan`
+--
+
+DROP TABLE IF EXISTS `irc_inchan`;
+CREATE TABLE `irc_inchan` (
+  `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier',
+  `name` varchar(12) NOT NULL default '',
+  `team` smallint(3) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`guid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='IRC Module system';
+
+--
+-- Table structure for table `irc_logedin`
+--
+
+DROP TABLE IF EXISTS `irc_logedin`;
+CREATE TABLE `irc_logedin` (
+  `account` int(11) unsigned NOT NULL default '0' COMMENT 'Account Identifier',
+  `nick` varchar(50) NOT NULL default '',
+  `gmlevel` tinyint(3) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`account`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='IRC Module system';
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
Index: src/game/Channel.cpp
===================================================================
--- src/game/Channel.cpp	(revision 3815)
+++ src/game/Channel.cpp	(working copy)
@@ -16,9 +16,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "Common.h"
 #include "Channel.h"
 #include "ObjectMgr.h"
 #include "Chat.h"
+#include "IRCClient.h"
 
 Channel::Channel(std::string _name)
     : name(_name), announce(true), constant(false), moderate(false), m_ownerGUID(0), password("")
@@ -30,6 +32,13 @@
         constant = true;                                    // built-in channel    
         announce = false;                                   // no join/leave announces
     }
+    std::string tempname = _name;
+    std::transform(tempname.begin(), tempname.end(), tempname.begin(), towlower);
+    if (sIRC.WOW_CHAN == tempname)
+    {
+        constant = true;                                    // built-in channel    
+        announce = false;                                   // no join/leave announces
+    }
 }
 
 void Channel::Join(uint64 p, const char *pass, uint32 unk1)
Index: src/game/CharacterHandler.cpp
===================================================================
--- src/game/CharacterHandler.cpp	(revision 3815)
+++ src/game/CharacterHandler.cpp	(working copy)
@@ -34,6 +34,8 @@
 #include "ObjectAccessor.h"
 #include "Transports.h"
 #include "Group.h"
+#include "IRCClient.h"
+#include "Config/ConfigEnv.h"
 
 // check used symbols in player name at creating and rename
 std::string notAllowedChars = "\t\v\b\f\a\n\r\\\"\'\? <>[](){}_=+-|/!@#$%^&*~`.,0123456789\0";
@@ -563,8 +565,51 @@
     if(sWorld.IsShutdowning())
         sWorld.ShutdownMsg(true,pCurrChar);
 
+    bool announceallowed = true;
     if(pCurrChar->isGameMaster())
+     {
         SendNotification("GM mode is ON");
+        //retreive the toggle value from the conf
+        std::string GMLoginMessage = sConfig.GetStringDefault("GMAnnounceMessage","|cffff0000[$Rank $Name has come Online]|r");
+        std::string GMLoginIRCMessage = sConfig.GetStringDefault("GMAnnounceIRCMessage","12>>04 $Rank $Name has come Online");
+        std::string GMRankMod= sConfig.GetStringDefault("GMRankMod","Mod");
+        std::string GMRankGM= sConfig.GetStringDefault("GMRankGM","GM");
+        std::string GMRankAdmin= sConfig.GetStringDefault("GMRankAdmin","Admin");
+        //retreive the custom message from the conf
+
+        std::string GMRank;//String to store readable GM rank 1=mod 2=gm 3=admin
+
+        switch(GetSecurity())//switch case to determine what rank the "gm" is
+        {
+            case 1: GMRank = GMRankMod;break;
+            case 2: GMRank = GMRankGM;break;
+            case 3: GMRank = GMRankAdmin;break;
+        }
+
+        if((sIRC.BOTMASK & 32)!= 0)
+        {
+            announceallowed = false;
+            std::string str = sIRC.MakeMsg(sIRC.MakeMsg(GMLoginMessage, "$Name", pCurrChar->GetName()), "$Rank", GMRank);
+            sWorld.SendWorldText(str.c_str(), NULL);
+            sIRC.ChannelBot(sIRC.MakeMsg(sIRC.MakeMsg(GMLoginIRCMessage, "$Name", pCurrChar->GetName()), "$Rank", GMRank));
+            sLog.outBasic("GM '%s' logged in and announced",pCurrChar->GetName());
+        }
+        else sLog.outBasic("Not announced xD");
+     }
+
+    if (announceallowed)
+     {
+        std::string pname = pCurrChar->GetName();
+        if ((sIRC.BOTMASK & 8)!= 0)
+        {
+            sWorld.SendWorldMessage(sIRC.WOW_CHAN.c_str(),sIRC.MakeMsg(sIRC.WoW_comeonline, "$Name", pname));
+        }
+        if ((sIRC.BOTMASK & 16)!= 0)
+        {
+            sIRC.ChannelBot(sIRC.MakeMsg(sIRC.IRC_comeonline, "$Name", pname));
+        }
+     }
+ 
     m_playerLoading = false;
     pCurrChar->SendAllowMove();
 
Index: src/game/Chat.cpp
===================================================================
--- src/game/Chat.cpp	(revision 3815)
+++ src/game/Chat.cpp	(working copy)
@@ -175,6 +175,7 @@
         { "guid",        2, &ChatHandler::HandleGUIDCommand,             "",   NULL },
         { "help",        0, &ChatHandler::HandleHelpCommand,             "",   NULL },
         { "info",        0, &ChatHandler::HandleInfoCommand,             "",   NULL },
+        { "ircpm",       0, &ChatHandler::HandleIRCpmCommand,            "",   NULL },
         { "npcinfo",     3, &ChatHandler::HandleNpcInfoCommand,          "",   NULL },
         { "npcinfoset",  3, &ChatHandler::HandleNpcInfoSetCommand,       "",   NULL },
         { "addvendoritem",2,&ChatHandler::HandleAddVendorItemCommand,    "",   NULL },
Index: src/game/Chat.h
===================================================================
--- src/game/Chat.h	(revision 3815)
+++ src/game/Chat.h	(working copy)
@@ -136,6 +136,7 @@
         bool HandleDismountCommand(const char* args);
         bool HandleSaveCommand(const char* args);
         bool HandleGMListCommand(const char* args);
+        bool HandleIRCpmCommand(const char* args);
 
         bool HandleNamegoCommand(const char* args);
         bool HandleGonameCommand(const char* args);
Index: src/game/ChatHandler.cpp
===================================================================
--- src/game/ChatHandler.cpp	(revision 3815)
+++ src/game/ChatHandler.cpp	(working copy)
@@ -31,6 +31,7 @@
 #include "MapManager.h"
 #include "ObjectAccessor.h"
 #include "ScriptCalls.h"
+#include "IRCClient.h"
 #include "Player.h"
 #include "Language.h"
 
@@ -277,14 +278,24 @@
 
             recv_data >> msg;
 
-            if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+            if (sChatHandler.ParseCommands(msg.c_str(), this) > 0)
+                break;
+
+            // if two side interraction is disabled and this is our channel, send to both channel manager instances, in LANG_UNIVERSAL.
+            if(sIRC.ChannelMsg(GetPlayer(), channel, msg) && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
             {
-                if(Channel *chn = cMgr->GetChannel(channel,_player))
-                {
-                    chn->Say(_player->GetGUID(),msg.c_str(),lang);
-                    GetPlayer()->UpdateSpeakTime();
-                }
+                sWorld.SendWorldMessage(channel.c_str(), msg, _player->GetGUID());
+                GetPlayer()->UpdateSpeakTime();
             }
+            else // otherwise let mangos handle it normally.
+            {
+                if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
+                    if(Channel *chn = cMgr->GetChannel(channel,_player))
+                    {
+                        chn->Say(_player->GetGUID(),msg.c_str(),lang);
+                        GetPlayer()->UpdateSpeakTime();
+                    }
+            }
         } break;
 
         case CHAT_MSG_AFK:
Index: src/game/IRCClient.cpp
===================================================================
--- src/game/IRCClient.cpp	(revision 0)
+++ src/game/IRCClient.cpp	(revision 0)
@@ -0,0 +1,1014 @@
+/*
+ * MangChat Enhanced v0.2
+ * Based on MANGCHAT a Threaded IRC Client for MaNGOS V0.1 by Cybrax
+ * 
+ * MANGCHAT is a Internet Relay Chat client intergrated in mangos
+ * it allows you to have chat messages send from and to irc within 
+ * the wow client. making it possible for players to get support
+ * from irc directly ingame or have several servers join the same
+ * irc channel and have "cross server chat". the client uses c
+ * sockets to send and receieve data from and to the irc server
+ *
+ * MangChat Enhanced aims to add many features to MangChat,
+ * including total "gm" control from irc, in channel and in game
+ * announces of level ups, deaths, resurrects, and so on.
+ * MangChat Enhanced features are designed to be fully integrated
+ * into the MaNGOS core system as well as be easly customised or
+ * disabled from the MaNGOS conf file.
+ * 
+ * This software is currently still under development the client
+ * has been tested locally with 1 Windows XP server (Visual Studio)
+ * and 1 UNIX Debian 3.1 (g++) server.
+ * 
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *                                                                           
+ * MANGCHAT is:
+ * Copyright (C) 2007 VisualDreams <http://www.visualdreams.nl/>             
+ * Written and Develloped by Cybrax. dev@visualdreams.nl
+ *
+ * MangChat was enhanced by Lice <lice@yeuxverts.net>, Dj_baby & Sanaell
+ * with help and support from the MaNGOS project community.
+ * 
+ * PLEASE RETAIN THE COPYRIGHT OF THE AUTHOR.
+ *
+ */
+#include "IRCClient.h"
+#include "IRCCommands.h"
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "Config/ConfigEnv.h"
+#include "Policies/SingletonImp.h"
+#include "ObjectAccessor.h"
+#include "WorldSession.h"
+#include "WorldPacket.h"
+#include "Log.h"
+#include "Chat.h"
+#include "ObjectMgr.h"
+#include "Guild.h"
+#include "MapManager.h"
+
+#include <fcntl.h>
+
+#pragma warning(disable:4305)
+INSTANTIATE_SINGLETON_1( IRCClient );
+
+/*------------------------------------------
+Threaded Function and declaration for the 
+socket handler they are practicly simiair 
+however the sockets and threading differs 
+from win and unix. These functions are run
+on a seperate thread to "fake" asynchronus 
+IO. the thread constantly listens on the 
+socket for incomming data from IRC.
+------------------------------------------*/
+#ifdef _WIN32
+    #include <winsock.h>
+    
+    // Thread Declarations
+    // These comments apply to the unix part aswell
+    // they only slightly differ in names for some parts
+
+    DWORD        nThreadID;                    
+    HANDLE        hThread;
+    DWORD        WINAPI SocketHandler(void* ptr);    
+    // Thread Function
+    DWORD WINAPI SocketHandler(void* ptr)
+    {
+        char szBuffer[MAXDATASIZE];
+        // We want to constantly keep looking for data
+        // so we create a loop
+        while(sIRC.AcceptData == true)
+        {
+            // reset the buffer
+            ZeroMemory(szBuffer,MAXDATASIZE);
+            
+            // check for incomming data on the socket
+            int nBytesRecv = recv(sIRC.sockfd, szBuffer, MAXDATASIZE - 1, 0 );
+            if ( nBytesRecv == -1 )
+            {
+                sLog.outError("Connection lost.");
+                // end the loop
+                sIRC.AcceptData = false;
+            }
+            else
+            {
+                if (-1 == nBytesRecv)
+                {
+                    sLog.outError("Error occurred while receiving from socket.");
+                }
+                else
+                {
+                    // Recieve was successfull send the data to RecvData function
+                    sIRC.RecvData(szBuffer);
+                }
+            }
+        }
+        return 0;
+    }
+#else
+    #include <stdio.h>
+    #include <stdlib.h>
+    #include <sys/unistd.h>
+    #include <sys/fcntl.h>
+    #include <errno.h>
+    #include <string.h>
+    #include <netdb.h>
+    #include <sys/types.h>
+    #include <netinet/in.h>
+    #include <sys/socket.h>
+
+    pthread_t    hThread;
+    int            nThreadID;
+    void        *SocketHandler( void *ptr );
+    void *SocketHandler( void *ptr )
+    {
+        char szBuffer[MAXDATASIZE];
+        while(sIRC.AcceptData == true)
+        {
+            memset ( szBuffer, 0, MAXDATASIZE + 1 );
+            int nBytesRecv = recv(sIRC.sockfd, szBuffer, MAXDATASIZE - 1, 0 );
+            if ( nBytesRecv == -1 )
+            {
+                sLog.outError("Connection lost.");
+                sIRC.AcceptData = false;
+            }
+            else
+            {
+                if (-1 == nBytesRecv)
+                {
+                    // socket error
+                    sLog.outError("Error occurred while receiving from socket.");
+                }
+                else
+                {
+                    sIRC.RecvData(szBuffer);
+                }
+            }
+        }
+        return 0;
+    }
+#endif
+
+/*------------------------------------------
+IRCClient Constructor
+------------------------------------------*/
+IRCClient::IRCClient()
+{
+}
+
+/*------------------------------------------
+IRCClient Destructor
+------------------------------------------*/
+IRCClient::~IRCClient()
+{
+}
+
+/*------------------------------------------
+IRCClient::IRCcmd
+
+Checks in chan commands from irc
+------------------------------------------*/
+bool IRCClient::IRCcmd(std::string SndLine, std::string outputChan, std::string from, std::string type)
+{
+    std::size_t pos = SndLine.find(" ");
+    std::string cmd  = SndLine.substr(0, pos);
+    std::transform(cmd.begin(), cmd.end(), cmd.begin(), towlower);
+    std::string param  = "";
+    if (pos != std::string::npos)
+        param = SndLine.substr(pos + 1);
+    int level = 0;
+    std::string query = "SELECT * FROM `irc_logedin` WHERE `nick` = '" + from + "'";
+    QueryResult *result = sDatabase.Query(query.c_str());
+    if (result)
+    {
+        Field *fields = result->Fetch();
+        level = fields[2].GetInt32();
+        delete result;
+    }
+    if ((sIRC.IRC_CMDS_MASK & 1) != 0)  // if level 0 commands are active
+    {
+        if (cmd == sIRC.IRC_CMDS_PREFIX + "online")
+        {
+            IRCcommand::HandleOnlineIRCCommand(param, outputChan, type);
+            return true;
+        }
+
+        if (cmd == sIRC.IRC_CMDS_PREFIX + "inchan")
+        {
+            IRCcommand::HandleInChanIRCCommand(outputChan, type);
+            return true;
+        }
+    
+        if (cmd == sIRC.IRC_CMDS_PREFIX + "player")
+        {
+            IRCcommand::HandlePlayerIRCCommand(param, outputChan, type);
+            return true;
+        }
+
+        if (cmd == sIRC.IRC_CMDS_PREFIX + "info")
+        {
+            IRCcommand::HandleInfoIRCCommand(outputChan, type);
+            return true;
+        }
+    }
+
+    if (((sIRC.IRC_CMDS_MASK & 2) != 0) && (cmd == sIRC.IRC_CMDS_PREFIX + "pm")) // if the pm system is active
+    {
+        IRCcommand::HandlePmIRCCommand(param, outputChan, level, from, type);
+        return true;
+    }
+
+    if ((sIRC.IRC_CMDS_MASK & 4) != 0)  // if gm commands are active
+    {
+        if (cmd == sIRC.IRC_CMDS_PREFIX + "kick")
+        {
+            IRCcommand::HandleKickIRCCommand(param, outputChan, level, type);
+            return true;
+        }
+
+        if (cmd == sIRC.IRC_CMDS_PREFIX + "saveall")
+        {
+            IRCcommand::HandleSaveAllIRCCommand(outputChan, level, type);
+            return true;
+        }
+
+        if (cmd == sIRC.IRC_CMDS_PREFIX + "tele")
+        {
+            IRCcommand::HandleTeleIRCCommand(param, outputChan, level, type);
+            return true;
+        }
+
+        if (cmd == sIRC.IRC_CMDS_PREFIX + "revive")
+        {
+            IRCcommand::HandleReviveIRCCommand(param, outputChan, level, type);
+            return true;
+        }
+
+        if (cmd == sIRC.IRC_CMDS_PREFIX + "kill")
+        {
+            IRCcommand::HandleKillIRCCommand(param, outputChan, level, type);
+            return true;
+        }
+
+        if (cmd == sIRC.IRC_CMDS_PREFIX + "announce")
+        {
+            IRCcommand::HandleAnnounceIRCCommand(param, outputChan, level, type);
+            return true;
+        }
+
+        if (cmd == sIRC.IRC_CMDS_PREFIX + "notify")
+        {
+            IRCcommand::HandleNotifyIRCCommand(param, outputChan, level, type);
+            return true;
+        }
+    }
+
+    if ((sIRC.IRC_CMDS_MASK & 6) != 0) // loging in and out will only be possible if the pm system or the gm commands are active.
+    {
+        if (cmd == sIRC.IRC_CMDS_PREFIX + "login")
+        {
+            IRCcommand::HandleLoginIRCCommand(param, outputChan, from, type);
+            return true;
+        }
+
+        if (cmd == sIRC.IRC_CMDS_PREFIX + "logout")
+        {
+            IRCcommand::HandleLogoutIRCCommand(outputChan, from, type);
+            return true;
+        }
+    }
+
+    return false;
+}
+
+/*------------------------------------------
+IRCClient::GetData
+
+Processes the lines from IRC
+IRC uses a verry simplt protocol where the
+data is split by spaces once we found the
+spaces we can split them up and use or
+analyze the variables
+------------------------------------------*/
+void IRCClient::GetData(std::string SndLine) {
+    
+    if(SndLine.substr(0, 4) == "PING")
+    {
+        // we revceived a ping request
+        // we need to return pong + what the server sent us
+        std::string ret = "PONG " + SndLine.substr(4, SndLine.size() - 4);
+        sLog.outDebug("IRC: [PING] %s", ret.c_str());
+        SendData(ret.c_str());
+    }
+    else
+    {
+        // we receieved another type of message
+        sLog.outDebug("IRC: [IN] %s", SndLine.c_str());
+
+        // if the first character contains :
+        // we receievd a normal irc message
+        if(SndLine.substr(0,1)==":")
+        {
+            // find the spaces in the line
+            // and extract the values
+            int pos1 = SndLine.find(" ");
+            int pos2 = SndLine.find(" ", pos1 + 1);
+            std::string part1  = SndLine.substr(1, pos1 - 1);
+            std::string part2  = SndLine.substr(pos1 + 1, pos2 - pos1 - 1);
+            std::string rest = "", part3 = "";
+            // username contains nick and host adress extract it
+            std::string szUser = GetUser(part1);
+            
+            // user ignore check
+            std::string ignorecheck = " " + szUser + " ";
+            std::transform(ignorecheck.begin(), ignorecheck.end(), ignorecheck.begin(), towlower);
+            if (sIRC.IGNORE_LIST.find(ignorecheck) != std::string::npos) return;
+
+            // make evrything lowercase to ensure compare matches
+            std::transform(part2.begin(), part2.end(), part2.begin(), towlower);
+
+            if(part2 == sIRC.IRC_CODE)
+            {
+                // we receieved the irc connectcode
+                sLog.outDebug("IRC: Connectcode received: %s", IRC_CODE.c_str());
+                /*
+                std::string modes = sConfig.GetStringDefault("IRCUSERMODES", "")
+                if (modes != "")
+                {
+                    SendData("MODE " + sIRC.IRC_NICK + " :" + modes);
+                }
+                */
+                std::string ircpass = sConfig.GetStringDefault("IRCNICKPASS", "");
+                if(sConfig.GetIntDefault("IRCQUAKENET", 0) == 1)
+                {
+                    // if we use quakenet authenticate now
+                    if (ircpass != "")
+                        SendData("PRIVMSG Q@CServe.quakenet.org :AUTH " + sIRC.IRC_NICK + " " + ircpass + "\n");
+                }
+                else
+                {
+                    // if we use nickserv authenticate now
+                    if (ircpass != "")
+                        SendData("PRIVMSG nickserv :IDENTIFY " + ircpass + "\n");
+                }
+                // time to join the channel
+                SendData("JOIN #" + sIRC.IRC_CHAN + "\n");
+            }
+
+            if(part2 == "join")
+            {
+                int pos3 = SndLine.find(":", pos2);
+                part3  = SndLine.substr(pos3 + 1);
+                std::transform(part3.begin(), part3.end(), part3.begin(), towlower);
+                if ((szUser == sIRC.IRC_NICK) && (part3 == "#" + sIRC.IRC_CHAN))
+                {
+                    if(sConfig.GetIntDefault("IRCSTARTMSGON", 0) == 1)
+                    {
+                        SendPMsg("#" + sIRC.IRC_CHAN, sConfig.GetStringDefault("IRCSTARTMSG", "Server Online"));
+                    }
+                }
+                else if ((szUser == sIRC.IRC_NICK) && (sIRC.IRC_LDEF == 1) && (part3 == "#" + sIRC.IRC_DEF_CHAN))
+                {
+                    // if we have to leave the default channel do this now
+                    SendData("PART #" + sIRC.IRC_DEF_CHAN + "\n");
+                }
+                else if ((sIRC.BOTMASK & 1) != 0)
+                    sWorld.SendWorldMessage(sIRC.WOW_CHAN.c_str(), sIRC.MakeMsg(sIRC.WoW_joinedIRC, "$Name", szUser));
+                    // someone joined the channel on irc
+            }
+
+            if ((part2 == "part") || (part2 == "quit"))
+            {
+                std::string query = "DELETE FROM `irc_logedin` WHERE `nick` = '" + szUser + "'";
+                sDatabase.PExecute(query.c_str());
+                if ((sIRC.BOTMASK & 1) != 0)
+                    sWorld.SendWorldMessage(sIRC.WOW_CHAN.c_str(), sIRC.MakeMsg(sIRC.WoW_leftIRC, "$Name", szUser));
+            }
+
+            if (part2 == "nick")
+            {
+                std::string query = "DELETE FROM `irc_logedin` WHERE `nick` = '" + szUser + "'";
+                sDatabase.PExecute(query.c_str());
+                int pos3 = SndLine.find(":", pos2);
+                part3  = SndLine.substr(pos3 + 1);
+                if ((sIRC.BOTMASK & 1) != 0)
+                    sWorld.SendWorldMessage(sIRC.WOW_CHAN.c_str(), sIRC.MakeMsg(sIRC.MakeMsg(sIRC.WoW_changedIRCnick, "$Name", szUser), "$NewName", part3));
+            }
+
+            if (part2 == "kick")
+            {
+                int pos3 = SndLine.find(" ", pos2 + 1);
+                int pos4 = SndLine.find(" ", pos3 + 1);
+                part3  = SndLine.substr(pos2 + 1, pos3 - pos2 - 1);
+                szUser  = SndLine.substr(pos3 + 1, pos4 - pos3 -1);
+                std::transform(part3.begin(), part3.end(), part3.begin(), towlower);
+                std::string query = "DELETE FROM `irc_logedin` WHERE `nick` = '" + szUser + "'";
+                sDatabase.PExecute(query.c_str());
+                if(part3 == "#" + sIRC.IRC_CHAN)
+                {
+                    if (((sIRC.BOTMASK & 1) != 0) && (szUser != sIRC.IRC_NICK)) //if someone is kicked from the chan
+                        sWorld.SendWorldMessage(sIRC.WOW_CHAN.c_str(), sIRC.MakeMsg(sIRC.WoW_leftIRC, "$Name", szUser));
+                    else if (sConfig.GetIntDefault("auto_rejoin_kick", 1) == 1) //If we are kicked and auto rejoin is 1 join channel back
+                    {
+                        SendData("JOIN #" + sIRC.IRC_CHAN + "\n");
+                    }
+                }
+            }
+
+            if(part2 == "privmsg")
+            {
+                int pos3 = SndLine.find(" ", pos2 + 1);
+                part3  = SndLine.substr(pos2 + 1, pos3 - pos2 - 1);
+                rest  = SndLine.substr(pos3 + 1, SndLine.size() - pos3 - 2);
+
+                std::transform(part3.begin(), part3.end(), part3.begin(), towlower);
+                std::string chat = rest.substr(1, rest.size());
+
+                // we receieved chat from the irc channel
+                if(part3 == "#" + sIRC.IRC_CHAN)
+                {
+                    std::string WorldMsg = "[" + szUser + "]" + chat;
+                    sLog.outDebug("IRC: [IN] %s", WorldMsg.c_str());
+
+                    // check if its a command or not.
+                    if (IRCcmd(chat, "#" + sIRC.IRC_CHAN, szUser)) return;
+
+                    std::string str;
+                    if (chat.substr(1, 7) == "ACTION ")
+                        str = sIRC.MakeMsg(sIRC.MakeMsg(sIRC.WoW_IRCaction, "$Name", szUser), "$Msg", chat.substr(8, chat.length() - 9));
+                    else
+                        str = sIRC.MakeMsg(sIRC.MakeMsg(sIRC.WoW_IRCmsg, "$Name", szUser), "$Msg", chat);
+                    // we use the custom made function here because we have to loop
+                    // thry the player sessoins and check of they are on the channel
+                    // i couldnt figure out how to make it work in this class
+                    // so i had to use world
+                    sWorld.SendWorldMessage(sIRC.WOW_CHAN.c_str() , sIRC.IRCcol2WoW(str.c_str()));
+                    //sWorld.SendWorldMessage(sIRC.WOW_CHAN.c_str() , sIRC.IRCcol2WoW(sIRC.Hybrid2UTF(str.c_str())));
+                }
+
+                // we received a PM
+                std::string ircnick = sIRC.IRC_NICK;
+                std::transform(ircnick.begin(), ircnick.end(), ircnick.begin(), towlower);
+                if(part3 == ircnick)
+                {
+                    sLog.outDebug("IRC: Private message received: %s", szUser.c_str());
+                    // check if its a command or not.
+                    if (IRCcmd(chat, szUser, szUser, "NOTICE")) return;
+                }
+            }
+        }
+    }
+}
+
+/*------------------------------------------
+IRCClient::ChannelBot
+
+Public function for announcing to the irc
+channel
+------------------------------------------*/
+void IRCClient::ChannelBot(std::string Msg)
+{
+    if(sIRC.Connected && sIRC.IRC_Login)
+    {
+        Msg = sIRC.Delink(Msg);
+        Msg = sIRC.WoWcol2IRC(Msg);
+        SendMsg(Msg);
+    }
+}
+
+void IRCClient::SendIRCData(std::string data)
+{
+    if(sIRC.Connected && sIRC.IRC_Login)
+    {
+        sLog.outDebug("IRC [OUT]: %s", data.c_str());
+        SendData(data.c_str());
+    }
+}
+
+void IRCClient::SendIRCpm(Player *From, std::string To, std::string Msg)
+{
+    if(sIRC.Connected && sIRC.IRC_Login)
+    {
+        char plevel [5];
+        sprintf(plevel, "%u", From->getLevel());
+        Msg = sIRC.Delink(Msg);
+        Msg = sIRC.WoWcol2IRC(Msg);
+        SendData("NOTICE " + To + " :13" + sIRC.MakeMsg(sIRC.MakeMsg(sIRC.MakeMsg(sIRC.IRC_WoWmsg, "$Name", From->GetName()), "$Msg", Msg), "$Lev", plevel) + "\n");
+    }
+}
+
+void IRCClient::HandleChannelJoin(Player *p)
+{
+    std::string pname = p->GetName();
+    std::string pteam = "12";
+    if (p->GetTeam() == 67)
+        pteam = "4";
+    sDatabase.PExecute("DELETE FROM `irc_inchan` WHERE `guid` = %d", p->GetGUID());
+    std::string query = "INSERT INTO `irc_inchan` VALUES(%d, '" + pname + "', " + pteam + ")";
+    sDatabase.PExecute(query.c_str(), p->GetGUID());
+    if ((sIRC.BOTMASK & 2)!= 0)
+        sIRC.ChannelBot(sIRC.MakeMsg(sIRC.IRC_joinedWoWchan, "$Name", p->GetName()));
+    if ((sIRC.BOTMASK & 4)!= 0)
+        sWorld.SendWorldMessage(sIRC.WOW_CHAN.c_str(), sIRC.MakeMsg(sIRC.WoW_joinedWoWchan, "$Name", p->GetName()), 0, p->GetSession());
+}
+
+void IRCClient::HandleChannelPart(Player *p)
+{
+    QueryResult *result = sDatabase.PQuery("SELECT * FROM `irc_inchan` WHERE `guid` = %d", p->GetGUID());
+    if (result)
+    {
+        delete result;
+        sDatabase.PExecute("DELETE FROM `irc_inchan` WHERE `guid` = %d", p->GetGUID());
+        if ((sIRC.BOTMASK & 2)!= 0)
+            sIRC.ChannelBot(sIRC.MakeMsg(sIRC.IRC_leftWoWchan, "$Name", p->GetName()));
+        if ((sIRC.BOTMASK & 4)!= 0)
+            sWorld.SendWorldMessage(sIRC.WOW_CHAN.c_str(), sIRC.MakeMsg(sIRC.WoW_leftWoWchan, "$Name", p->GetName()), 0, p->GetSession());
+    }
+}
+
+/*------------------------------------------
+IRCClient::ChannelMsg
+
+This function is called by the ChatHandler
+whenever a player talks on a channel the
+info is sent to this function. if the
+channel matches the one set in the config
+it will send the message to irc
+------------------------------------------*/
+bool IRCClient::ChannelMsg(Player *plr, std::string Channel, std::string Msg)
+{
+    std::transform(Channel.begin(), Channel.end(), Channel.begin(), towlower);
+    if(Channel == sIRC.WOW_CHAN)
+    {
+        if(sIRC.Connected && sIRC.IRC_Login)
+        {
+            char plevel [5];
+            sprintf(plevel, "%u", plr->getLevel());
+            Msg = sIRC.Delink(Msg);
+            Msg = sIRC.WoWcol2IRC(Msg);
+            SendMsg(sIRC.MakeMsg(sIRC.MakeMsg(sIRC.MakeMsg(sIRC.IRC_WoWmsg, "$Name", plr->GetName()), "$Msg", Msg), "$Lev", plevel));
+        }
+        return true;
+    }
+    return false;
+}
+
+/*------------------------------------------
+IRCClient::GetUser
+
+This extracts the username from the lines
+recieved from irc. because irc sends the
+username and hostinfo in one line.
+------------------------------------------*/
+std::string IRCClient::GetUser(std::string szU)
+{
+    // username and host are seperated by ! find the
+    // character and return the part before it
+    int pos = szU.find("!");
+    return szU.substr(0, pos);
+}
+
+std::string IRCClient::MakeMsg(std::string msg, std::string var, std::string val)
+{
+    std::size_t start = msg.find(var);
+    if (start != std::string::npos)
+        msg.replace(start, var.length(), val);
+    return msg;
+}
+
+std::string IRCClient::Delink(std::string msg)
+{
+    std::size_t pos;
+    while ((pos = msg.find("|Hitem")) != std::string::npos)
+    {
+        msg.replace(pos, msg.find("|h") - pos + 2, "\x2");
+        msg.replace(msg.find("|h"), 2, "\x2");
+    }
+    return msg;
+}
+
+std::string IRCClient::WoWcol2IRC(std::string msg)
+{
+    std::size_t pos;
+    char IRCCol[8][4] = { "\xF", "\xF", "\x3\x31\x34", "\x3\x30\x33", "\x3\x31\x32", "\x3\x30\x36", "\x3\x30\x37", "\x3\x30\x34"};
+    char WoWCol[8][12] = { "|r", "|cffffffff", "|cff9d9d9d", "|cff1eff00", "|cff0070dd", "|cffa335ee", "|cffff8000", "|cffe6cc80"};
+    for (int i=0; i<=7; i++)
+    {
+            while ((pos = msg.find(WoWCol[i])) != std::string::npos)
+        {
+            if (i == 0)
+                msg.replace(pos, 2, IRCCol[i]);
+            else
+                msg.replace(pos, 10, IRCCol[i]);
+        }
+    }
+    return msg;
+}
+
+std::string IRCClient::IRCcol2WoW(std::string msg)
+{
+    std::size_t pos;
+    char IRCCol[16][4] = { "\x3\x30", "\x3\x31", "\x3\x32", "\x3\x33", "\x3\x34", "\x3\x35", "\x3\x36", "\x3\x37", "\x3\x38", "\x3\x39", "\x3\x31\x30", "\x3\x31\x31", "\x3\x31\x32", "\x3\x31\x33", "\x3\x31\x34", "\x3\x31\x35"};
+    char IRCCol2[10][4] = { "\x3\x30\x30", "\x3\x30\x31", "\x3\x30\x32", "\x3\x30\x33", "\x3\x30\x34", "\x3\x30\x35", "\x3\x30\x36", "\x3\x30\x37", "\x3\x30\x38", "\x3\x30\x39"};
+    char WoWcol[16][12] = { "|cffffffff", "|cff000000", "|cff00007f", "|cff009300", "|cffff0000", "|cff7f0000", "|cff9c009c", "|cfffc9300", "|cffffff00", "|cff00fc00", "|cff009393", "|cff00ffff", "|cff0000fc", "|cffff00ff", "|cff7f7f7f", "|cffd2d2d2"};
+    for (int i=15; i>=0; i--)
+    {
+        if (i<10)
+        {
+            while ((pos = msg.find(IRCCol2[i])) != std::string::npos)
+            {
+                msg.replace(pos, 3, WoWcol[i]);
+            }
+            while ((pos = msg.find(IRCCol[i])) != std::string::npos)
+            {
+                msg.replace(pos, 2, WoWcol[i]);
+            }
+
+        }
+        else
+        {
+            while ((pos = msg.find(IRCCol[i])) != std::string::npos)
+            {
+                msg.replace(pos, 3, WoWcol[i]);
+            }
+        }
+    }
+
+    while ((pos = msg.find("\x3")) != std::string::npos)
+    {
+        msg.replace(pos, 1, "|r");
+    }
+    while ((pos = msg.find("\xF")) != std::string::npos)
+    {
+        msg.replace(pos, 1, "|r");
+    }
+
+    return msg;
+}
+
+std::string IRCClient::Hybrid2UTF(std::string Msg)
+{
+   /*char * tempchar = NULL;
+
+   tempchar = (char*)malloc(strlen(Msg.c_str())+1);
+    
+   strcpy(tempchar,Msg.c_str());
+
+   BSTR in_text;
+   int nLen = MultiByteToWideChar(28591, 0, tempchar, lstrlen(tempchar), NULL, NULL);
+   in_text = SysAllocStringLen(NULL, nLen);
+   MultiByteToWideChar(28591, 0, tempchar, lstrlen(tempchar), in_text, nLen);
+
+   //change to UTF..
+   char *out_text = NULL;
+   int nLen2 = WideCharToMultiByte(65001, 0, in_text, -1, out_text, 0, NULL, NULL);
+   out_text = (char*)malloc(nLen2+1);
+   WideCharToMultiByte(65001, 0, in_text, -1, out_text, nLen2, NULL, NULL);
+
+   Msg = out_text;
+
+   free(tempchar);
+   SysFreeString(in_text);
+   free(out_text);*/
+
+   return Msg;
+}
+/*------------------------------------------
+IRCClient::LoadConfig
+
+Loads the configuration set in mangosd.conf
+------------------------------------------*/
+bool IRCClient::LoadConfig()
+{
+    int ConfCnt = 0;
+    sLog.outBasic("Loading IRC Configuration\n");
+
+    IRC_HOST = sConfig.GetStringDefault("IRCHost", "");
+    if(IRC_HOST.size() != 0) { ConfCnt++; }
+
+    IRC_Port = sConfig.GetIntDefault("IRCPort", 0);
+    if(IRC_Port != 0) { ConfCnt++; }
+
+    sIRC.IRC_CODE =  sConfig.GetStringDefault("IRCCONNECTCODE", "001");
+    sIRC.IRC_LDEF = sConfig.GetIntDefault("IRCLeaveDefChannel", 0);
+    sIRC.IRC_NICK = sConfig.GetStringDefault("IRCNICK", "mangosirc");
+    sIRC.IRC_DEF_CHAN = sConfig.GetStringDefault("IRCDEFCHAN", "lobby");
+    sIRC.IRC_CHAN = sConfig.GetStringDefault("IRCCHAN", "world");
+    sIRC.WOW_CHAN = sConfig.GetStringDefault("WOWCHAN", "world");    
+    sIRC.BOTMASK = sConfig.GetIntDefault("BotMask", 0);
+    sIRC.IRC_CMDS_MASK = sConfig.GetIntDefault("IRC_Cmds_Mask", 0);
+    sIRC.IRC_CMDS_PREFIX = sConfig.GetStringDefault("IRC_Cmds_Prefix", ".");
+    sIRC.IGNORE_LIST = " " + sConfig.GetStringDefault("IRCIgnorList", "") + " ";
+
+    // IRC Text Varriables:
+    sIRC.WoW_joinedIRC = sConfig.GetStringDefault("WoW_joinedIRC", ">> $Name joined IRC.");
+    sIRC.WoW_leftIRC = sConfig.GetStringDefault("WoW_leftIRC",  "<< $Name left IRC.");
+    sIRC.WoW_changedIRCnick = sConfig.GetStringDefault("WoW_changedIRCnick",  "<> $Name is now known as $NewName.");
+    sIRC.IRC_joinedWoWchan = sConfig.GetStringDefault("IRC_joinedWoWchan", "12>>04 $Name Joined The Channel");
+    sIRC.WoW_joinedWoWchan = sConfig.GetStringDefault("WoW_joinedWoWchan", ">> $Name Joined The Channel");
+    sIRC.IRC_leftWoWchan = sConfig.GetStringDefault("IRC_leftWoWchan", "12<<04 $Name Left The Channel");
+    sIRC.WoW_leftWoWchan = sConfig.GetStringDefault("WoW_leftWoWchan", "<< $Name Left The Channel");
+    sIRC.IRC_comeonline = sConfig.GetStringDefault("IRC_comeonline", "12>>04 $Name has come Online");
+    sIRC.WoW_comeonline = sConfig.GetStringDefault("WoW_comeonline", ">> $Name has come Online");
+    sIRC.IRC_goneoffline = sConfig.GetStringDefault("IRC_goneoffline", "12<<04 $Name has gone Offline");
+    sIRC.WoW_goneoffline = sConfig.GetStringDefault("WoW_goneoffline", "<< $Name has gone Offline");
+    sIRC.IRC_died = sConfig.GetStringDefault("IRC_died", "12<>04 $Name has joined the Spirits!");
+    sIRC.WoW_died = sConfig.GetStringDefault("WoW_died", "<> $Name has joined the Spirits!");
+    sIRC.IRC_revive = sConfig.GetStringDefault("IRC_revive", "12<>04 $Name has rejoined the Living!");
+    sIRC.WoW_revive = sConfig.GetStringDefault("WoW_revive", "<> $Name has rejoined the Living!");
+    sIRC.IRC_levelup = sConfig.GetStringDefault("IRC_levelup", "12<>04 $Name has gained Level $Lev!");
+    sIRC.WoW_levelup = sConfig.GetStringDefault("WoW_levelup", "<> $Name has gained Level $Lev!");
+    sIRC.IRC_WoWmsg = sConfig.GetStringDefault("IRC_WoWmsg", "<WoW>[$Name] $Msg");
+    sIRC.WoW_IRCmsg = sConfig.GetStringDefault("WoW_IRCmsg", "<IRC>[$Name]: $Msg");
+    sIRC.WoW_IRCaction = sConfig.GetStringDefault("WoW_IRCaction", "<IRC>*$Name $Msg");
+    sIRC.IRC_sysmsg = sConfig.GetStringDefault("IRC_sysmsg", "04,08/!\\System Message/!\\ $Msg 04,08/!\\System Message/!\\");
+    sIRC.IRC_sysnotice = sConfig.GetStringDefault("IRC_sysnotice", "04,08/!\\System Notice/!\\ $Msg 04,08/!\\System Notice/!\\");
+
+    if(ConfCnt == 2)
+    {
+        // make sure we have at least a host and port
+        // or we cant connect
+        return true;
+    }
+    else
+    {
+        // config missing
+        sLog.outError("ERROR MISSING CONFIGURATION FOR HOST AND OR PORT AND OR GMPASS\n");
+        return false;
+    }
+}
+
+/*------------------------------------------
+IRCClient::run
+
+function called by ZThread 
+when we create the thread
+------------------------------------------*/
+void IRCClient::run()
+{
+    sLog.outBasic("\n%s\n%s\n%s\n%s\n%s\n%s\n",
+    "***************************************",
+    "#    MANGCHAT Threaded IRC CLient     #",
+    "#        (C) 2007 VisuaDreams         #",
+    "#          Written by Cybrax          #",
+    "# Enhanced by Lice, Dj_baby & Sanaell #",
+    "***************************************");
+
+    // Thread started load config
+    if(!LoadConfig()) 
+    {
+        return;
+    }
+    // clear irc tables
+    sDatabase.PExecute("DELETE FROM `irc_inchan`");
+    sDatabase.PExecute("DELETE FROM `irc_logedin`");
+
+    sIRC.IRC_Login = false;
+    sIRC.Connected = false;
+
+    if(sConfig.GetIntDefault("IRCON", 0))
+    {
+        if(Connect(IRC_HOST.c_str(), IRC_Port))
+        {
+            // If connections success
+            sLog.outBasic("IRC: Connected");
+            // send hello to let the server know were here
+            if(SendData("HELLO\n"))
+            {    
+                // begin with password first
+                std::string ircpass = sConfig.GetStringDefault("IRCSERVERPASS", "mangosirc");
+                if(SendData("PASS " + ircpass + "\n"))
+                {
+                    // send nickname
+                    if(SendData("NICK " + sIRC.IRC_NICK + "\n"))
+                    {
+                        // send username and some required info
+                        char hostname[128];
+                        gethostname(hostname, sizeof(hostname));
+                        if(SendData("USER " + sConfig.GetStringDefault("IRCUSER", "mangosirc") + " " + (std::string)hostname + " " + " MaNGOS :MaNGOS IRC 0.2\n"))
+                        {
+                            // login was a success
+                            sLog.outBasic("IRC: Login succeeded\n");
+                            sIRC.IRC_Login = true;
+                        }// send username 
+                    }// send nickname
+                } // password
+            } // send hello
+
+            if(sIRC.IRC_Login == true)
+            {
+                sIRC.AcceptData = true;
+                // if we are logged in we need to start the listener thread and keep them alive
+                char *tmsg = ""; // bogus message to be passed to prevent errors
+                #ifdef _WIN32
+                    // create the thread 
+                    hThread = CreateThread(0, 0, SocketHandler, (void*)tmsg, 0, &nThreadID);
+                    //wait for it to finish
+                    WaitForSingleObject(hThread, INFINITE);
+                #else
+                    // create the thread 
+                    nThreadID = pthread_create( &hThread, NULL, &SocketHandler, (void*)tmsg);
+                    //wait for it to finish
+                    pthread_join( hThread, NULL);
+                #endif
+            }
+            // The thread ended connection lost
+            sLog.outError("Connection died\n");
+            Disconnect();
+        }
+        else
+        {
+            // unable to login
+            sLog.outError("Unable to connect to %s\n", IRC_HOST.c_str());
+        }
+    }
+    // close and cloeanup the socket
+    return;
+}
+
+/*------------------------------------------
+IRCClient::Connect
+
+Initiate the connection to the irc server
+returns true on success
+returns false on error
+------------------------------------------*/
+bool IRCClient::Connect(const char *host, int port)
+{
+    sLog.outBasic("***** Attempting IRC Connection *\n");
+
+    #ifdef _WIN32
+        // if we use WIN32 we must initialize the winsock library
+        WSADATA wsaData; //WSAData
+        if(WSAStartup(MAKEWORD(2,0),&wsaData) != 0)
+        {
+            sLog.outError("IRC Error: Winsock Initialization Error");
+            return false;
+        }
+    #endif
+
+    struct hostent *he;
+    struct sockaddr_in their_addr;
+
+    // get the hostname
+    if ((he=gethostbyname(host)) == NULL)
+    {
+        sLog.outError("IRC Error: Host Resolve Error");
+        return false;
+    }
+
+    // Create the socket
+    if ((sIRC.sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
+    {
+        sLog.outError("IRC Error: Socket Error");
+        return false;
+    }
+
+    int on = 1;
+    if ( setsockopt ( sIRC.sockfd, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 )
+    {
+        sLog.outError("IRC Error: Invalid Socket");
+        return false;
+    }
+
+    // set the socket to asynchronous IO and NON Blocking
+    #ifdef _WIN32
+        u_long iMode = 0;
+        ioctlsocket(sIRC.sockfd, FIONBIO, &iMode);
+    #else
+        fcntl(sIRC.sockfd, F_SETFL, O_NONBLOCK);  // set to non-blocking
+        fcntl(sIRC.sockfd, F_SETFL, O_ASYNC);     // set to asynchronous I/O
+    #endif
+    
+    // construct data to be passed to the socket connect function
+    // this is port and host
+
+    their_addr.sin_family = AF_INET;    // host byte order 
+    their_addr.sin_port = htons(port);  // short, network byte order 
+    their_addr.sin_addr = *((struct in_addr *)he->h_addr);
+    memset(&(their_addr.sin_zero), '\0', 8);  // zero the rest of the struct 
+
+    // attempt a connection to the server
+    if (connect(sIRC.sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1)
+    {
+        sLog.outError("IRC Error: Cannot connect to %s", host);
+        return false;
+    }
+    // Connection success
+    sIRC.Connected = true;
+    return true;
+}
+
+/*------------------------------------------
+IRCClient::RecvData
+
+this function takes the data from the
+socket and puts it in a stringstream
+we do this because the data can contain 
+more then 1 line and we need to process
+each line seperately
+------------------------------------------*/
+void IRCClient::RecvData(std::string SockData)
+{
+    // the data receieved in the socket can have more then 1 line
+    // put the data into a stringstream and send each line
+    // to the GetData function
+    std::string reply;
+    std::istringstream iss(SockData);
+    while(getline(iss, reply))
+    {
+        GetData(reply);
+    }
+}
+
+/*------------------------------------------
+IRCClient::SendMsg
+
+This function constructs a message a 
+channel on the IRC server
+------------------------------------------*/
+bool IRCClient::SendMsg(std::string SndLine) {
+    sLog.outDebug("IRC [OUT]: %s", SndLine.c_str());
+    return SendData("PRIVMSG #" + sIRC.IRC_CHAN + " :" + SndLine + "\n");
+}
+
+/*------------------------------------------
+IRCClient::SendPMsg
+
+This function constructs a message for
+a user on the IRC server  
+------------------------------------------*/
+bool IRCClient::SendPMsg(std::string user, std::string SndLine) {
+    sLog.outDebug("IRC [OUT]: %s", SndLine.c_str());
+    return SendData("PRIVMSG " + user + " :" + SndLine + "\n");
+}
+
+/*------------------------------------------
+IRCClient::SendData
+
+This function sends the data passed to the
+socket its similair to the previous function
+however excepts a string as argument 
+
+Note that we use the same function name
+twice however the argument is different this
+is called Function Overloading C++ will 
+automaticly detect the argument type passed
+and select the right function
+------------------------------------------*/
+bool IRCClient::SendData(const char *data) {
+    // send data on the socket
+    if (send(sIRC.sockfd, data, strlen(data), 0) == -1)
+    {
+        sLog.outError("IRC Error: Socket Receieve ** \n");
+        Disconnect();
+        return false;
+    }
+    return true;
+}
+
+bool IRCClient::SendData(std::string data)
+{
+    // send data on the socket
+    // function overloaded
+    return SendData(data.c_str());
+}
+
+/*------------------------------------------
+IRCClient::Disconnect
+
+Function to close and cleanup the socket
+------------------------------------------*/
+void IRCClient::Disconnect()
+{
+    close(sIRC.sockfd);
+    #ifdef _WIN32
+        WSACleanup();
+    #endif
+}
+
+/*------------------------------------------
+IRCSocket Constructor
+------------------------------------------*/
+IRCSocket::IRCSocket()
+{
+}
+
+/*------------------------------------------
+IRCSocket Destructor
+------------------------------------------*/
+IRCSocket::~IRCSocket()
+{
+}
Index: src/game/IRCClient.h
===================================================================
--- src/game/IRCClient.h	(revision 0)
+++ src/game/IRCClient.h	(revision 0)
@@ -0,0 +1,155 @@
+/*
+ * MangChat Enhanced v0.2
+ * Based on MANGCHAT a Threaded IRC Client for MaNGOS V0.1 by Cybrax
+ * 
+ * MANGCHAT is a Internet Relay Chat client intergrated in mangos
+ * it allows you to have chat messages send from and to irc within 
+ * the wow client. making it possible for players to get support
+ * from irc directly ingame or have several servers join the same
+ * irc channel and have "cross server chat". the client uses c
+ * sockets to send and receieve data from and to the irc server
+ *
+ * MangChat Enhanced aims to add many features to MangChat,
+ * including total "gm" control from irc, in channel and in game
+ * announces of level ups, deaths, resurrects, and so on.
+ * MangChat Enhanced features are designed to be fully integrated
+ * into the MaNGOS core system as well as be easly customised or
+ * disabled from the MaNGOS conf file.
+ * 
+ * This software is currently still under development the client
+ * has been tested locally with 1 Windows XP server (Visual Studio)
+ * and 1 UNIX Debian 3.1 (g++) server.
+ * 
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *                                                                           
+ * MANGCHAT is:
+ * Copyright (C) 2007 VisualDreams <http://www.visualdreams.nl/>             
+ * Written and Develloped by Cybrax. dev@visualdreams.nl
+ *
+ * MangChat was enhanced by Lice <lice@yeuxverts.net>, Dj_baby & Sanaell
+ * with help and support from the MaNGOS project community.
+ * 
+ * PLEASE RETAIN THE COPYRIGHT OF THE AUTHOR.
+ *
+ */
+
+#ifndef _IRC_CLIENT_H
+#define _IRC_CLIENT_H
+
+#include "Policies/Singleton.h"
+#include "Player.h"
+
+#define MAXDATASIZE 512
+#define IRC_CHANNEL_JOIN 0
+#define IRC_CHANNEL_LEAVE 1
+
+class IRCClient : public ZThread::Runnable 
+{
+public:
+    IRCClient();
+    ~IRCClient();
+    void run();
+    void RecvData(std::string SockData);
+    void SendIRCpm(Player *From, std::string To, std::string Msg);
+    void ChannelBot(std::string Msg);
+    void SendIRCData(std::string data);
+    void HandleChannelJoin(Player *p);
+    void HandleChannelPart(Player *p);
+
+public:
+    bool            Connected;    
+    bool            IRC_Login;
+    bool            AcceptData;
+    bool            ChannelMsg(Player *plr, std::string Channel, std::string Msg);
+
+public:
+    int                sockfd;
+    int                IRC_LDEF;
+    int                BOTMASK;
+    int                IRC_CMDS_MASK;
+
+public:
+    std::string MakeMsg(std::string msg, std::string var, std::string val);
+    std::string Delink(std::string msg);
+    std::string WoWcol2IRC(std::string msg);
+    std::string IRCcol2WoW(std::string msg);
+    std::string Hybrid2UTF(std::string Msg);
+
+    std::string        IRC_NICK;
+    std::string        IRC_CMDS_PREFIX;
+    std::string        IGNORE_LIST;
+    std::string        IRC_CODE;
+    std::string        IRC_DEF_CHAN;
+    std::string        IRC_CHAN;
+    std::string        WOW_CHAN;
+
+    // IRC Text Variables
+    std::string        WoW_joinedIRC;
+    std::string        WoW_leftIRC;
+    std::string        WoW_changedIRCnick;
+    std::string        IRC_joinedWoWchan;
+    std::string        WoW_joinedWoWchan;
+    std::string        IRC_leftWoWchan;
+    std::string        WoW_leftWoWchan;
+    std::string        IRC_comeonline;
+    std::string        WoW_comeonline;
+    std::string        IRC_goneoffline;
+    std::string        WoW_goneoffline;
+    std::string        IRC_died;
+    std::string        WoW_died;
+    std::string        IRC_revive;
+    std::string        WoW_revive;
+    std::string        IRC_levelup;
+    std::string        WoW_levelup;
+    std::string        IRC_WoWmsg;
+    std::string        WoW_IRCmsg;
+    std::string        WoW_IRCaction;
+    std::string        IRC_sysmsg;
+    std::string        IRC_sysnotice;
+
+private:
+    void Disconnect();
+    void GetData(std::string SndLine);
+
+private:
+    bool LoadConfig();
+    bool Connect(const char *host, int port);
+    bool SendMsg(std::string SndLine);
+    bool SendPMsg(std::string user, std::string SndLine);
+    bool SendData(const char *data);
+    bool SendData(std::string data);
+    bool IRCcmd(std::string SndLine, std::string outputChan, std::string from, std::string type="PRIVMSG");
+
+private:
+    std::string GetUser(std::string szU);
+
+private:
+    int                IRC_Port;
+
+private:
+    std::string        IRC_HOST;
+};
+
+#define sIRC MaNGOS::Singleton<IRCClient>::Instance()
+
+
+class IRCSocket
+{
+public:
+    IRCSocket();
+    ~IRCSocket();
+};
+
+#endif
Index: src/game/IRCCommands.cpp
===================================================================
--- src/game/IRCCommands.cpp	(revision 0)
+++ src/game/IRCCommands.cpp	(revision 0)
@@ -0,0 +1,483 @@
+/*
+ * MangChat Enhanced v0.2
+ * Based on MANGCHAT a Threaded IRC Client for MaNGOS V0.1 by Cybrax
+ * 
+ * MANGCHAT is a Internet Relay Chat client intergrated in mangos
+ * it allows you to have chat messages send from and to irc within 
+ * the wow client. making it possible for players to get support
+ * from irc directly ingame or have several servers join the same
+ * irc channel and have "cross server chat". the client uses c
+ * sockets to send and receieve data from and to the irc server
+ *
+ * MangChat Enhanced aims to add many features to MangChat,
+ * including total "gm" control from irc, in channel and in game
+ * announces of level ups, deaths, resurrects, and so on.
+ * MangChat Enhanced features are designed to be fully integrated
+ * into the MaNGOS core system as well as be easly customised or
+ * disabled from the MaNGOS conf file.
+ * 
+ * This software is currently still under development the client
+ * has been tested locally with 1 Windows XP server (Visual Studio)
+ * and 1 UNIX Debian 3.1 (g++) server.
+ * 
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *                                                                           
+ * MANGCHAT is:
+ * Copyright (C) 2007 VisualDreams <http://www.visualdreams.nl/>             
+ * Written and Develloped by Cybrax. dev@visualdreams.nl
+ *
+ * MangChat was enhanced by Lice <lice@yeuxverts.net>, Dj_baby & Sanaell
+ * with help and support from the MaNGOS project community.
+ * 
+ * PLEASE RETAIN THE COPYRIGHT OF THE AUTHOR.
+ *
+ */
+
+#include "IRCCommands.h"
+#include "IRCClient.h"
+#include "Common.h"
+#include "Language.h"
+#include "Database/DatabaseEnv.h"
+#include "Config/ConfigEnv.h"
+#include "Policies/SingletonImp.h"
+#include "ObjectAccessor.h"
+#include "WorldSession.h"
+#include "WorldPacket.h"
+#include "Log.h"
+#include "Chat.h"
+#include "ObjectMgr.h"
+#include "Guild.h"
+#include "MapManager.h"
+
+void IRCcommand::HandlePlayerIRCCommand(std::string param, std::string outputChan,std::string type)
+{
+	int pos = param.find(" ");
+	if (param == "")
+    {
+        sIRC.SendIRCData(type + " " + outputChan + " :" + "Syntax: " + sIRC.IRC_CMDS_PREFIX + "player playername" + "\n");
+        return;
+    }
+    std::string pname  = param.substr(0, pos);
+    normalizePlayerName(pname);
+    sDatabase.escape_string(pname);
+    std::string sqlquery = "SELECT `guid`, `name`, `race`, `class`, `online`, SUBSTRING_INDEX(SUBSTRING_INDEX(`data`, ' ' , 35), ' ' , -1) AS `level`, SUBSTRING_INDEX(SUBSTRING_INDEX(`data`, ' ' , 230), ' ' , -1) AS `guildid`, SUBSTRING_INDEX(SUBSTRING_INDEX(`data`, ' ' , 231), ' ' , -1) AS `guildrank`, SUBSTRING_INDEX(SUBSTRING_INDEX(`data`, ' ' , 859), ' ' , -1) AS `xp`, SUBSTRING_INDEX(SUBSTRING_INDEX(`data`, ' ' , 860), ' ' , -1) AS `maxxp`, SUBSTRING_INDEX(SUBSTRING_INDEX(data, ' ' , 1327), ' ' , -1) AS `gold` FROM `character` WHERE `name` LIKE '" + pname + "';";
+    QueryResult *result = sDatabase.Query(sqlquery.c_str());
+    if(result) 
+    {
+        Field *fields = result->Fetch();
+        std::string pguid = fields[0].GetCppString();
+        pname = fields[1].GetCppString();
+        uint32 praceid = fields[2].GetUInt32();
+        uint32 pclassid = fields[3].GetUInt32();
+        std::string ponline = (fields[4].GetInt32() == 1 ? "\x3\x30\x33Online" : "\x3\x30\x34Offline\xF");
+        std::string plevel = fields[5].GetCppString();
+        uint32 pguildid = fields[6].GetUInt32();
+        uint32 pguildrank = fields[7].GetUInt32();
+        std::string pxp = fields[8].GetCppString();
+        std::string pmaxxp = fields[9].GetCppString();
+        unsigned int money = fields[10].GetInt32();
+        delete result;
+
+        std::string guildinfo = "";
+        if (pguildid != 0)
+        {
+            Guild* guild = objmgr.GetGuildById(pguildid);
+            if (guild)
+            {
+                guildinfo = ", " + guild->GetRankName(pguildrank) + " of " + guild->GetName();
+            }
+        }
+
+        ChrRacesEntry const* prace = sChrRacesStore.LookupEntry(praceid);
+        ChrClassesEntry const* pclass = sChrClassesStore.LookupEntry(pclassid);
+
+        if (atoi(plevel.c_str()) < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+            plevel += " (" + pxp + "/" + pmaxxp + ")";
+
+        unsigned int gold = money / 10000;
+        unsigned int silv = (money % 10000) / 100;
+        unsigned int cop = (money % 10000) % 100;
+        char tempgold [100];
+        sprintf(tempgold, "\x2\x3\x30\x37%ug \x3\x31\x34%us \x3\x30\x35%uc\xF", gold, silv, cop);
+
+        if (ponline == "\x3\x30\x33Online")
+        {
+            Player * player = ObjectAccessor::Instance().FindPlayerByName(pname.c_str());
+            if (player)
+            {
+                AreaTableEntry const* area = GetAreaEntryByAreaID(player->GetAreaId());
+                ponline += " in " + (std::string) area->area_name[sWorld.GetDBClang()];
+                if (area->zone != 0)
+                {
+                    AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone);
+                    ponline += " (" + (std::string)zone->area_name[sWorld.GetDBClang()] + ")";
+                }
+            }
+        }
+
+        sIRC.SendIRCData(type + " " + outputChan + " :" + "About " + pname + guildinfo + "\n");
+        sIRC.SendIRCData(type + " " + outputChan + " :" + "\x2Race:\x2\x3\x31\x30 " + (std::string)prace->name[sWorld.GetDBClang()] + "\xF |\x2 Class:\x2\x3\x31\x30 " + (std::string)pclass->name[sWorld.GetDBClang()] + "\xF |\x2 Level:\x2\x3\x31\x30 " + plevel + "\xF |\x2 Money:\x2 " + tempgold + "\xF |\x2 Status:\x2 " + ponline + "\n");
+
+    }
+    else
+        sIRC.SendIRCData(type + " " + outputChan + " :" + "Unknown Player: " + pname + "\n");
+
+}
+
+void IRCcommand::HandleOnlineIRCCommand(std::string param, std::string outputChan,std::string type)
+{
+    std::transform(param.begin(), param.end(), param.begin(), towlower);
+    bool showHorde = false;
+    bool showAlli = false;
+    if (param.length() > 0)
+    {
+        if (param.substr(0, 3) == "all")
+        {
+            showHorde = true;
+            showAlli = true;
+        }
+        else if (param.at(0) == 'h')
+            showHorde = true;
+        else if (param.at(0) == 'a')
+            showAlli = true;
+    }
+    uint32 playersonline = 0;
+    std::string output = ":";
+    char buffer[80];
+    ObjectAccessor::PlayersMapType& m = ObjectAccessor::Instance().GetPlayers();
+    for(ObjectAccessor::PlayersMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
+    {
+        if (((itr->second->GetTeam() == 67) && showHorde) || ((itr->second->GetTeam() == 469) && showAlli))
+        {
+            std::string pname = itr->second->GetName();
+            if (itr->second->GetSession()->GetSecurity() > 0)
+            {
+                sprintf(buffer, "%c%s%c", 31, pname.c_str(), 31);
+                pname = buffer;
+            }
+            if (itr->second->GetSession()->GetPlayer()->isGameMaster())
+            {
+                sprintf(buffer, "%c03<GM>%s%c", 3, pname.c_str(), 3);
+                pname = buffer;
+            }
+            switch (itr->second->GetTeam())
+            {
+                case 67: //horde
+                    sprintf (buffer, "%c04%s%c", 3, pname.c_str(), 3);
+                    pname = buffer;
+                    break;
+
+                case 469: //alliance
+                    sprintf (buffer, "%c12%s%c", 3, pname.c_str(), 3);
+                    pname = buffer;
+                    break;
+                default:
+                    break;
+            }
+
+            sprintf (buffer, " %s(%d)", pname.c_str(), itr->second->getLevel());
+
+            output += buffer;
+            playersonline++;
+        }
+        if (!showHorde && !showAlli)
+            playersonline++;
+    }
+        sprintf (buffer, "%c%d Player(s) Online", 2, playersonline);
+        output = (output == ":" ? buffer : buffer + output);
+        sIRC.SendIRCData(type + " " + outputChan + " :" + output + "\n");
+}
+
+void IRCcommand::HandleInChanIRCCommand(std::string outputChan,std::string type)
+{
+    QueryResult *result = sDatabase.Query("SELECT * FROM irc_inchan ORDER BY `name`");
+    if (!result)
+    {
+        sIRC.SendIRCData(type + " " + outputChan + " :No Players are in the Channel\n");
+        return;
+    }
+    std::string output = "\x02Players in the Channel:";
+    for (uint64 i=0; i < result->GetRowCount(); i++)
+    {
+        Field *fields = result->Fetch();
+        output += " \x03" + fields[2].GetCppString() + fields[1].GetCppString() + "\x03";
+        result->NextRow();
+    }
+    delete result;
+    sIRC.SendIRCData(type + " " + outputChan + " :" + output + "\n");
+}
+
+void IRCcommand::HandleInfoIRCCommand(std::string outputChan,std::string type)
+{
+        char clientsNum [50];
+        sprintf(clientsNum, "%u", sWorld.GetSessionCount());
+        char maxClientsNum [50];
+        sprintf(maxClientsNum, "%u", sWorld.GetMaxSessionCount());
+        std::string str = secsToTimeString(sWorld.GetUptime());
+        
+        sIRC.SendIRCData(type + " " + outputChan + " :Number of Players Online: " + (std::string)clientsNum + " (Max since last restart: " + (std::string)maxClientsNum + ")" + " Uptime: " + str + "\n");
+}
+
+void IRCcommand::HandleKickIRCCommand(std::string param, std::string outputChan, int level, std::string type)
+{
+    if (level < 2)
+    {
+        sIRC.SendIRCData(type + " " + outputChan + " :You Dont Have Access To That Command\n");
+        return;
+    }
+    int pos = param.find(" ");
+    param  = param.substr(0, pos);
+    normalizePlayerName(param);
+    Player* chr = ObjectAccessor::Instance().FindPlayerByName( param.c_str() );
+    if (chr)
+    {
+        chr->GetSession()->KickPlayer();
+        sIRC.SendIRCData(type + " " + outputChan + " :" + param + " was kicked.\n");
+    }
+    else
+        sIRC.SendIRCData(type + " " + outputChan + " :" + param + " was not online.\n");
+}
+
+void IRCcommand::HandleSaveAllIRCCommand(std::string outputChan, int level, std::string type)
+{
+    if (level < 1)
+    {
+        sIRC.SendIRCData(type + " " + outputChan + " :You Dont Have Access To That Command\n");
+        return;
+    }
+    ObjectAccessor::Instance().SaveAllPlayers();
+    sIRC.SendIRCData(type + " " + outputChan + " :All Players Saved\n");
+}
+
+void IRCcommand::HandleTeleIRCCommand(std::string param, std::string outputChan, int level, std::string type)
+{
+    if (level < 1)
+    {
+        sIRC.SendIRCData(type + " " + outputChan + " :You Dont Have Access To That Command\n");
+        return;
+    }
+    int pos = param.find(" ");
+    std::string player  = param.substr(0, pos);
+    normalizePlayerName(player);
+    Player* chr = ObjectAccessor::Instance().FindPlayerByName( player.c_str() );
+    if (chr)
+    {
+        if(chr->isInFlight())
+        {
+            sIRC.SendIRCData(type + " " + outputChan + " :4[ERROR]: " + player + " is flying and cannot be transported\n");
+        }
+        else
+        {
+            std::string location  = param.substr(pos + 1, param.size() - pos - 1);
+            if(location != "")
+            {
+                sDatabase.escape_string(location);
+                std::string sqlquery = "SELECT `position_x`,`position_y`,`position_z`,`orientation`,`map` FROM `game_tele` WHERE `name` = '" + location + "';";
+                QueryResult *result = sDatabase.Query(sqlquery.c_str());
+                if (!result)
+                {
+                    sIRC.SendIRCData(type + " " + outputChan + " :4[ERROR]: Tele location not found: " + location + "\n");
+                }
+                else 
+                {
+                    Field *fields = result->Fetch();
+                    float x = fields[0].GetFloat();
+                    float y = fields[1].GetFloat();
+                    float z = fields[2].GetFloat();
+                    float ort = fields[3].GetFloat();
+                    int mapid = fields[4].GetUInt16();
+                    delete result;
+                    if(!MapManager::IsValidMapCoord(mapid,x,y))
+                        sIRC.SendIRCData(type + " " + outputChan + " :4[ERROR]: Invalid tele location: " + location + "\n");
+                    else
+                    {
+                        chr->SetRecallPosition(chr->GetMapId(),chr->GetPositionX(),chr->GetPositionY(),chr->GetPositionZ(),chr->GetOrientation());
+                        chr->TeleportTo(mapid, x, y, z, ort);
+                        sIRC.SendIRCData(type + " " + outputChan + " :13[" + player + "]: teleported to " + location + "\n");
+                    }                                                
+                }
+            }
+            else
+                sIRC.SendIRCData(type + " " + outputChan + " :4[ERROR]: Please Suply tele location\n");
+        }
+    }
+    else 
+        sIRC.SendIRCData(type + " " + outputChan + " :4[ERROR]: " + player + "  is not online\n");
+}
+
+void IRCcommand::HandleReviveIRCCommand(std::string param, std::string outputChan, int level, std::string type)
+{
+    if (level < 3)
+    {
+        sIRC.SendIRCData(type + " " + outputChan + " :You Dont Have Access To That Command\n");
+        return;
+    }
+    int pos = param.find(" ");
+    param  = param.substr(0, pos);
+    normalizePlayerName(param);
+    Player* chr = ObjectAccessor::Instance().FindPlayerByName( param.c_str() );
+    if (chr)
+    {
+        if(chr->isDead())
+        {
+            chr->ResurrectPlayer(0.5f);
+            chr->SpawnCorpseBones();
+            chr->SaveToDB();
+            sIRC.SendIRCData(type + " " + outputChan + " :" + param + " resurrected\n");
+        }
+        else
+            sIRC.SendIRCData(type + " " + outputChan + " :" + param + " is not Dead\n");
+    }
+    else 
+        sIRC.SendIRCData(type + " " + outputChan + " :" + param + " Is not online\n");
+}
+
+void IRCcommand::HandleKillIRCCommand(std::string param, std::string outputChan, int level, std::string type)
+{
+    if (level < 3)
+    {
+        sIRC.SendIRCData(type + " " + outputChan + " :You Dont Have Access To That Command\n");
+        return;
+    }
+    int pos = param.find(" ");
+    param  = param.substr(0, pos);
+    normalizePlayerName(param);
+    Player* chr = ObjectAccessor::Instance().FindPlayerByName( param.c_str() );
+    if (chr)
+    {
+        if(chr->isAlive())
+        {
+            chr->DealDamage(chr, chr->GetHealth(), DIRECT_DAMAGE, 0, NULL, 0, false);
+            chr->SaveToDB();
+            sIRC.SendIRCData(type + " " + outputChan + " :" + param + " killed\n");
+        }
+        else
+            sIRC.SendIRCData(type + " " + outputChan + " :" + param + " is already Dead\n");
+    }
+    else 
+        sIRC.SendIRCData(type + " " + outputChan + " :" + param + " Is not online\n");
+}
+
+void IRCcommand::HandleAnnounceIRCCommand(std::string param, std::string outputChan, int level, std::string type)
+{
+    if (level < 1)
+    {
+        sIRC.SendIRCData(type + " " + outputChan + " :You Dont Have Access To That Command\n");
+        return;
+    }
+    std::string str = LANG_SYSTEMMESSAGE + sIRC.IRCcol2WoW(param);
+    sWorld.SendWorldText(str.c_str(), NULL);
+
+    if ((sIRC.BOTMASK & 1024)!= 0)
+    {
+        sIRC.ChannelBot(sIRC.MakeMsg(sIRC.IRC_sysmsg, "$Msg", param));
+    }
+}
+
+void IRCcommand::HandleNotifyIRCCommand(std::string param, std::string outputChan, int level, std::string type)
+{
+    if (level < 1)
+    {
+        sIRC.SendIRCData(type + " " + outputChan + " :You Dont Have Access To That Command\n");
+        return;
+    }
+    std::string str = LANG_GLOBAL_NOTIFY + sIRC.IRCcol2WoW(param);
+
+    WorldPacket data(SMSG_NOTIFICATION, (str.size()+1));
+    data << str;
+    sWorld.SendGlobalMessage(&data);
+
+    if ((sIRC.BOTMASK & 1024)!= 0)
+    {
+        sIRC.ChannelBot(sIRC.MakeMsg(sIRC.IRC_sysnotice, "$Msg", str.substr(15)));
+    }
+}
+
+void IRCcommand::HandlePmIRCCommand(std::string param, std::string outputChan, int level, std::string from, std::string type)
+{
+    int pos = param.find(" ");
+    std::string player  = param.substr(0, pos);
+    normalizePlayerName(player);
+    Player* chr = ObjectAccessor::Instance().FindPlayerByName( player.c_str() );
+    if (chr)
+    {
+        if(chr->isAcceptWhispers() || chr->GetSession()->GetSecurity() <= level)
+        {
+            std::string msg  = param.substr(pos + 1, param.size() - pos - 1);
+
+            std::string chat = "|cffCC4ACC" + sIRC.IRCcol2WoW(sIRC.MakeMsg(sIRC.MakeMsg(sIRC.WoW_IRCmsg, "$Name", from), "$Msg", msg)) + "|r";
+            // construct a packet
+            WorldPacket data(SMSG_MESSAGECHAT, 200);
+            data << (uint8)CHAT_MSG_SYSTEM;
+            data << (uint32)LANG_UNIVERSAL;
+            data << chr->GetSession()->GetPlayer()->GetGUID();
+            data << (uint32) strlen(chat.c_str()) + 1;
+            data << chat.c_str();
+            data << (uint8)0;
+
+            // send the packet to the player
+            chr->GetSession()->SendPacket(&data);
+            sIRC.SendIRCData(type + " " + outputChan + " :13To [" + player + "]: " + msg + "\n");
+        }
+        else
+            sIRC.SendIRCData(type + " " + outputChan + " :" + player + " is not accepting private messages\n");
+    }
+    else
+        sIRC.SendIRCData(type + " " + outputChan + " :" + player + " is not online\n");
+}
+
+void IRCcommand::HandleLoginIRCCommand(std::string param, std::string outputChan, std::string from, std::string type)
+{
+    std::string query = "DELETE FROM `irc_logedin` WHERE `nick` = '" + from + "'";
+    sDatabase.PExecute(query.c_str());
+    std::size_t pos = param.find(" ");
+    std::string user = param.substr(0, pos);
+    if (pos == std::string::npos)
+    {
+        sIRC.SendIRCData(type + " " + outputChan + " :You must specify a username and password\n");
+        return;
+    }
+    std::string pass = param.substr(pos + 1);
+    loginDatabase.escape_string(user);
+    loginDatabase.escape_string(pass);
+    query = "SELECT id, gmlevel FROM `account` WHERE `username` LIKE '" + user + "' AND `password` = '" + pass + "'";
+    QueryResult *result = loginDatabase.Query(query.c_str());
+    if (!result)
+    {
+        sIRC.SendIRCData(type + " " + outputChan + " :Wrong User or Pass\n");
+        return;
+    }
+    Field *fields = result->Fetch();
+    query = "DELETE FROM `irc_logedin` WHERE `account` = " + fields[0].GetCppString();
+    sDatabase.PExecute(query.c_str());
+    query = "INSERT INTO `irc_logedin` VALUES(" + fields[0].GetCppString() + ", '" + from + "', " + fields[1].GetCppString() + ")";
+    sDatabase.PExecute(query.c_str());
+    delete result;
+    sIRC.SendIRCData(type + " " + outputChan + " :You are now loged in as " + user + "\n");
+}
+void IRCcommand::HandleLogoutIRCCommand(std::string outputChan, std::string from, std::string type)
+{
+    std::string query = "SELECT * FROM `irc_logedin` WHERE `nick` = '" + from + "'";
+    QueryResult *result = sDatabase.Query(query.c_str());
+    if (!result)
+    {
+        sIRC.SendIRCData(type + " " + outputChan + " :You are not loged in.\n");
+        return;
+    }
+    delete result;
+    query = "DELETE FROM `irc_logedin` WHERE `nick` = '" + from + "'";
+    sDatabase.PExecute(query.c_str());
+    sIRC.SendIRCData(type + " " + outputChan + " :You are now loged out.\n");
+}
\ No newline at end of file
Index: src/game/IRCCommands.h
===================================================================
--- src/game/IRCCommands.h	(revision 0)
+++ src/game/IRCCommands.h	(revision 0)
@@ -0,0 +1,69 @@
+/*
+ * MangChat Enhanced v0.2
+ * Based on MANGCHAT a Threaded IRC Client for MaNGOS V0.1 by Cybrax
+ * 
+ * MANGCHAT is a Internet Relay Chat client intergrated in mangos
+ * it allows you to have chat messages send from and to irc within 
+ * the wow client. making it possible for players to get support
+ * from irc directly ingame or have several servers join the same
+ * irc channel and have "cross server chat". the client uses c
+ * sockets to send and receieve data from and to the irc server
+ *
+ * MangChat Enhanced aims to add many features to MangChat,
+ * including total "gm" control from irc, in channel and in game
+ * announces of level ups, deaths, resurrects, and so on.
+ * MangChat Enhanced features are designed to be fully integrated
+ * into the MaNGOS core system as well as be easly customised or
+ * disabled from the MaNGOS conf file.
+ * 
+ * This software is currently still under development the client
+ * has been tested locally with 1 Windows XP server (Visual Studio)
+ * and 1 UNIX Debian 3.1 (g++) server.
+ * 
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *                                                                           
+ * MANGCHAT is:
+ * Copyright (C) 2007 VisualDreams <http://www.visualdreams.nl/>             
+ * Written and Develloped by Cybrax. dev@visualdreams.nl
+ *
+ * MangChat was enhanced by Lice <lice@yeuxverts.net>, Dj_baby & Sanaell
+ * with help and support from the MaNGOS project community.
+ * 
+ * PLEASE RETAIN THE COPYRIGHT OF THE AUTHOR.
+ *
+ */
+
+#include "Common.h"
+
+namespace IRCcommand
+{
+    // chan commands, default return type == PRIVMSG
+    void HandlePlayerIRCCommand(std::string param, std::string outputChan, std::string type="PRIVMSG");
+    void HandleOnlineIRCCommand(std::string param, std::string outputChan, std::string type="PRIVMSG");
+    void HandleInChanIRCCommand(std::string outputChan, std::string type="PRIVMSG");
+    void HandleInfoIRCCommand(std::string outputChan, std::string type="PRIVMSG");
+
+    // priv commands, default return type == NOTICE
+    void HandleKickIRCCommand(std::string param, std::string outputChan, int level, std::string type="NOTICE");
+    void HandleSaveAllIRCCommand(std::string outputChan, int level, std::string type="NOTICE");
+    void HandleTeleIRCCommand(std::string param, std::string outputChan, int level, std::string type="NOTICE");
+    void HandleReviveIRCCommand(std::string param, std::string outputChan, int level, std::string type="NOTICE");
+    void HandleKillIRCCommand(std::string param, std::string outputChan, int level, std::string type="NOTICE");
+    void HandleAnnounceIRCCommand(std::string param, std::string outputChan, int level, std::string type="NOTICE");
+    void HandleNotifyIRCCommand(std::string param, std::string outputChan, int level, std::string type="NOTICE");
+    void HandlePmIRCCommand(std::string param, std::string outputChan, int level, std::string from, std::string type="NOTICE");
+    void HandleLoginIRCCommand(std::string param, std::string outputChan, std::string from, std::string type="NOTICE");
+    void HandleLogoutIRCCommand(std::string outputChan, std::string from, std::string type="NOTICE");
+}
Index: src/game/Level0.cpp
===================================================================
--- src/game/Level0.cpp	(revision 3815)
+++ src/game/Level0.cpp	(working copy)
@@ -29,6 +29,7 @@
 #include "ObjectAccessor.h"
 #include "Language.h"
 #include "SpellAuras.h"
+#include "IRCClient.h"
 
 bool ChatHandler::ShowHelpForCommand(ChatCommand *table, const char* cmd)
 {
@@ -365,3 +366,22 @@
         SendSysMessage(LANG_BAD_VALUE);
     return true;
 }
+
+bool ChatHandler::HandleIRCpmCommand(const char* args)
+{
+    std::string Msg = args;
+    if ((sIRC.IRC_CMDS_MASK & 2) == 0)
+    {
+        Msg = "WoW <-> iRC pm system disabled";
+        PSendSysMessage(Msg.c_str());
+        return true;
+    }
+    if (Msg.find(" ") == std::string::npos)
+        return false;
+    std::string To = Msg.substr(0, Msg.find(" "));
+    Msg = Msg.substr(Msg.find(" ") + 1);
+    sIRC.SendIRCpm(m_session->GetPlayer(), To, Msg);
+    Msg = "|cffCC4ACCTo [" + To + "]: " + Msg + "|r";
+    PSendSysMessage(Msg.c_str());
+    return true;
+}
Index: src/game/Level1.cpp
===================================================================
--- src/game/Level1.cpp	(revision 3815)
+++ src/game/Level1.cpp	(working copy)
@@ -31,6 +31,7 @@
 #include "Language.h"
 #include "RedZoneDistrict.h"
 #include "Transports.h"
+#include "IRCClient.h"
 
 bool ChatHandler::HandleSayCommand(const char* args)
 {
@@ -107,7 +108,8 @@
     std::string str = LANG_SYSTEMMESSAGE;
     str += args;
     sWorld.SendWorldText(str.c_str(), NULL);
-
+    if ((sIRC.BOTMASK & 1024)!= 0)
+        sIRC.ChannelBot(sIRC.MakeMsg(sIRC.IRC_sysmsg, "$Msg", args));
     return true;
 }
 
@@ -122,7 +124,8 @@
     WorldPacket data(SMSG_NOTIFICATION, (str.size()+1));
     data << str;
     sWorld.SendGlobalMessage(&data);
-
+    if ((sIRC.BOTMASK & 1024)!= 0)
+        sIRC.ChannelBot(sIRC.MakeMsg(sIRC.IRC_sysnotice, "$Msg", args));
     return true;
 }
 
Index: src/game/Makefile.am
===================================================================
--- src/game/Makefile.am	(revision 3815)
+++ src/game/Makefile.am	(working copy)
@@ -115,6 +115,10 @@
 	HomeMovementGenerator.h \
 	IdleMovementGenerator.cpp \
 	IdleMovementGenerator.h \
+	IRCClient.cpp \
+	IRCClient.h \
+	IRCCommands.cpp \
+	IRCCommands.h \
 	Item.cpp \
 	Item.h \
 	ItemHandler.cpp \
Index: src/game/Player.cpp
===================================================================
--- src/game/Player.cpp	(revision 3815)
+++ src/game/Player.cpp	(working copy)
@@ -33,6 +33,7 @@
 #include "UpdateData.h"
 #include "Channel.h"
 #include "Chat.h"
+#include "IRCClient.h"
 #include "MapManager.h"
 #include "MapInstanced.h"
 #include "ObjectMgr.h"
@@ -1904,6 +1905,15 @@
 
     level += 1;
 
+    std::string pname = GetName();
+    char  temp [5];
+    sprintf(temp, "%u", level);
+    std::string plevel = temp;
+    if ((sIRC.BOTMASK & 256)!= 0)
+        sWorld.SendWorldMessage(sIRC.WOW_CHAN.c_str(),sIRC.MakeMsg(sIRC.MakeMsg(sIRC.WoW_levelup, "$Name", pname), "$Lev", plevel));
+    if ((sIRC.BOTMASK & 512)!= 0)
+        sIRC.ChannelBot(sIRC.MakeMsg(sIRC.MakeMsg(sIRC.IRC_levelup, "$Name", pname), "$Lev", plevel));
+
     InitStatsForLevel(level);
     InitTalentForLevel();
 
@@ -3144,6 +3154,12 @@
 
 void Player::ResurrectPlayer(float restore_percent, bool updateToWorld)
 {
+    std::string pname = GetName();
+    if ((sIRC.BOTMASK & 64)!= 0)
+        sWorld.SendWorldMessage(sIRC.WOW_CHAN.c_str(),sIRC.MakeMsg(sIRC.WoW_revive, "$Name", pname));
+    if ((sIRC.BOTMASK & 128)!= 0)
+        sIRC.ChannelBot(sIRC.MakeMsg(sIRC.IRC_revive, "$Name", pname));
+
     WorldPacket data(SMSG_SH_POSITION, 4*4);                // remove spirit healer position
     data << uint32(-1);
     data << uint32(0);
@@ -3237,6 +3253,12 @@
 
 void Player::KillPlayer()
 {
+    std::string pname = GetName();
+    if ((sIRC.BOTMASK & 64)!= 0)
+        sWorld.SendWorldMessage(sIRC.WOW_CHAN.c_str(),sIRC.MakeMsg(sIRC.WoW_died, "$Name", pname));
+    if ((sIRC.BOTMASK & 128)!= 0)
+        sIRC.ChannelBot(sIRC.MakeMsg(sIRC.IRC_died, "$Name", pname));
+
     if(InBattleGround())
     {
         BattleGround* bg = sBattleGroundMgr.GetBattleGround(GetBattleGroundId());
@@ -3483,12 +3505,25 @@
 
 void Player::JoinedChannel(Channel *c)
 {
+    std::string channame = c->GetName();
+    std::transform(channame.begin(), channame.end(), channame.begin(), towlower);
+    if (channame == sIRC.WOW_CHAN)
+    {
+        sIRC.HandleChannelJoin(this);
+    }
     m_channels.push_back(c);
 }
 
 void Player::LeftChannel(Channel *c)
 {
     m_channels.remove(c);
+
+    std::string channame = c->GetName();
+    std::transform(channame.begin(), channame.end(), channame.begin(), towlower);
+    if (channame == sIRC.WOW_CHAN)
+    {
+        sIRC.HandleChannelPart(this);
+    }
 }
 
 void Player::CleanupChannels()
Index: src/game/World.cpp
===================================================================
--- src/game/World.cpp	(revision 3815)
+++ src/game/World.cpp	(working copy)
@@ -46,6 +46,7 @@
 #include "TargetedMovementGenerator.h"
 #include "RedZoneDistrict.h"
 #include "WaypointMovementGenerator.h"
+#include "ChannelMgr.h"
 
 INSTANTIATE_SINGLETON_1( World );
 
@@ -879,6 +880,48 @@
     return;
 }
 
+void World::SendWorldMessage(const char *channel, std::string chat, uint64 guid, WorldSession *self)
+{
+    /*
+        Why is this function needed?
+        tobe able to send a message you need a valid ingame GUID
+        snce the IRC client isnt logged in we cant properly send message
+        or it would result in non existing players
+        also i didnt manage to figure out how to get the sessions in my own clas
+        so this function was born
+    */
+    SessionMap::iterator itr;
+    for (itr = m_sessions.begin(); itr != m_sessions.end(); itr++)
+    {
+        // Loop thru all online sessions
+        if (itr->second && itr->second->GetPlayer() && itr->second->GetPlayer()->IsInWorld() && itr->second != self)
+        {
+            // check if the player is in the world
+            if(ChannelMgr* cMgr = channelMgr(itr->second->GetPlayer()->GetTeam()))
+            {
+                // check if the player is grouped
+                if(Channel *chn = cMgr->GetChannel(channel, itr->second->GetPlayer()))
+                {
+                    // if the player is on our channel
+
+                    WorldPacket data;
+
+                    data.Initialize(SMSG_MESSAGECHAT);
+                    data << (uint8)14;
+                    data << (uint32)0;
+                    data << channel;
+                    data << guid;
+                    data << (uint32) (strlen(chat.c_str()) + 1);
+                    data << chat.c_str();
+                    data << (uint8)0;
+
+                    itr->second->SendPacket(&data);
+                }
+            }
+        }
+    }
+}
+
 /// Send a packet to all players (except self if mentionned)
 void World::SendGlobalMessage(WorldPacket *packet, WorldSession *self, uint32 team)
 {
Index: src/game/World.h
===================================================================
--- src/game/World.h	(revision 3815)
+++ src/game/World.h	(working copy)
@@ -206,6 +206,7 @@
 
         void SendWorldText(const char *text, WorldSession *self = 0);
         void SendGlobalMessage(WorldPacket *packet, WorldSession *self = 0, uint32 team = 0);
+        void SendWorldMessage(const char *channel, std::string chat, uint64 guid = 0, WorldSession *self = 0);
         void SendZoneMessage(uint32 zone, WorldPacket *packet, WorldSession *self = 0, uint32 team = 0);
         void SendZoneText(uint32 zone, const char *text, WorldSession *self = 0, uint32 team = 0);
         void SendServerMessage(uint32 type, const char *text = "", Player* player = NULL);
Index: src/game/WorldSession.cpp
===================================================================
--- src/game/WorldSession.cpp	(revision 3815)
+++ src/game/WorldSession.cpp	(working copy)
@@ -37,6 +37,8 @@
 #include "ObjectAccessor.h"
 #include "BattleGroundMgr.h"
 #include "Language.h"                                       // for CMSG_DISMOUNT handler
+#include "IRCClient.h"
+#include "ChannelMgr.h"
 
 /// WorldSession constructor
 WorldSession::WorldSession(uint32 id, WorldSocket *sock, uint32 sec) : _player(NULL), _socket(sock),
@@ -647,6 +649,15 @@
         data<<_player->GetGUID();
         _player->BroadcastPacketToFriendListers(&data);
 
+        std::string pname = _player->GetName();
+
+        sIRC.HandleChannelPart(_player);
+
+        if ((sIRC.BOTMASK & 8)!= 0)
+            sWorld.SendWorldMessage(sIRC.WOW_CHAN.c_str(),sIRC.MakeMsg(sIRC.WoW_goneoffline, "$Name", pname));
+        if ((sIRC.BOTMASK & 16)!= 0)
+            sIRC.ChannelBot(sIRC.MakeMsg(sIRC.IRC_goneoffline, "$Name", pname));
+
         ///- Delete the player object
         delete _player;
         _player = 0;
Index: src/mangosd/CliRunnable.cpp
===================================================================
--- src/mangosd/CliRunnable.cpp	(revision 3815)
+++ src/mangosd/CliRunnable.cpp	(working copy)
@@ -31,6 +31,7 @@
 #include "SystemConfig.h"
 #include "Config/ConfigEnv.h"
 #include "Util.h"
+#include "../game/IRCClient.h"
 
 #include "CliRunnable.h"
 
@@ -217,6 +218,8 @@
     str += text;
     sWorld.SendWorldText(str.c_str(), NULL);
     zprintf("Broadcasting to the world:%s\r\n",str.c_str());
+    if ((sIRC.BOTMASK & 1024)!= 0)
+        sIRC.ChannelBot(sIRC.MakeMsg(sIRC.IRC_sysmsg, "$Msg", text));
 }
 
 /// Print the list of commands and associated description
Index: src/mangosd/mangosd.conf.in
===================================================================
--- src/mangosd/mangosd.conf.in	(revision 3815)
+++ src/mangosd/mangosd.conf.in	(working copy)
@@ -338,3 +338,122 @@
 # Beep at mangosd start finished (mostly work only at Unix/Linux systems)
 # Default: 1 
 BeepAtStart = 1
+
+#####################
+# IRC Configuration #
+#####################
+
+# IRCON - enable (1) or disable (0) the IRC extension.
+IRCON = 1
+
+# IRCCONNECTCODE - what code to wait for before starting to identify / join channels
+# 001 == Welcome to Network msg
+# 375 == Beginning of MOTD
+# 376 == End of MOTD
+IRCCONNECTCODE = "001"
+
+# IRCPort - irc server port to connect to
+IRCPort = 6667
+
+# IRCHost - irc server's host / ip
+IRCHost = "irc.station51.net"
+
+# IRCSERVERPASS - the pass requierd to connect to the server
+IRCSERVERPASS = "MyServerPass"
+
+# IRCNICK - the bots nick on irc
+IRCNICK = "MaNGOServ"
+
+# IRCUSER - the irc username
+IRCUSER = "MaNGOS"
+
+# IRCNICKPASS - the pass for identifying to nickserv or quakenet
+IRCNICKPASS = "MyDumbPass"
+
+# IRCQUAKENET - 0 == identify to nickserv, 1 == identify to quakenet
+IRCQUAKENET = 0
+
+# IRCDEFCHAN - channel to leave if IRCLeaveDefChannel == 1, must be lowercase
+IRCDEFCHAN = "lobby"
+IRCLeaveDefChannel = 0
+
+# IRCCHAN - the linked IRC channel, lowercase, no hash
+IRCCHAN = "mangostest"
+
+# WOWCHAN - the linked ingame channel, lowercase
+WOWCHAN = "mangostest"
+
+# IRCIgnorList - irc nicks to ignonre, use this if you dont want other channel bots to be echoed to the wow channel, seperate with spaces.
+IRCIgnorList = ""
+
+# IRCSTARTMSG - Msg to display in the irc channel when the bot comes online if IRCSTARTMSGON == 1
+IRCSTARTMSG = "Server Online"
+IRCSTARTMSGON = 1
+
+# BotMask - This mask defines what the bot announces. if its 0 everything is disabled... simply add the values of the elements you want to create this mask.
+# eg: irc join/leaves are 1 and wow join/leaves are 2, if you want both of these active and nothing else, the the mode is 3.
+# display irc joins/leaves/nickchanges ingame: 1
+# display wow chan join/leaves in irc: 2
+# display wow chan join/leaves in wow: 4
+# display wow come online/gone offline ingame: 8
+# display wow come online/gone offline in irc: 16
+# Announce gm logons ingame and irc (when the gm is in gmmode): 32
+# display death/resurrects ingame: 64
+# display death/resurrects in irc: 128
+# display level ups ingame: 256
+# display level ups in irc: 512
+# display system msgs and notices in irc: 1024
+BotMask = 2047
+
+# IRC_Cmds_Mask - this defines which commands will be active, IRC_Cmds_Prefix defines the command prefix.
+# level 0 commands (.online, .info ....): 1
+# irc <-> wow pms: 2
+# gm commands: 4
+IRC_Cmds_Mask = 7
+IRC_Cmds_Prefix = "."
+
+# rejoin channel on kick
+# 0 = disable
+# 1 = enable
+auto_rejoin_kick = 1
+
+####################################################
+# IRC Text Variables:
+# anything here with its name starting with WoW is displayed ingame, anything starting with IRC is displayed in the irc channel.
+# $Name == Player Name or IRC Nick
+# $Lev == Level
+# $Msg == Message
+# $Rank == GM Rank
+WoW_joinedIRC = ">> $Name joined IRC."
+WoW_leftIRC = "<< $Name left IRC."
+WoW_changedIRCnick =  "<> $Name is now known as $NewName."
+IRC_joinedWoWchan = "12>>04 $Name Joined The Channel"
+WoW_joinedWoWchan = ">> $Name Joined The Channel"
+IRC_leftWoWchan = "12<<04 $Name Left The Channel"
+WoW_leftWoWchan = "<< $Name Left The Channel"
+IRC_comeonline = "12>>04 $Name has come Online"
+WoW_comeonline = ">> $Name has come Online"
+IRC_goneoffline = "12<<04 $Name has gone Offline"
+WoW_goneoffline = "<< $Name has gone Offline"
+IRC_died = "12<>04 $Name has joined the Spirits!"
+WoW_died = "<> $Name has joined the Spirits!"
+IRC_revive = "12<>04 $Name has rejoined the Living!"
+WoW_revive = "<> $Name has rejoined the Living!"
+IRC_levelup = "12<>04 $Name has gained Level $Lev!"
+WoW_levelup = "<> $Name has gained Level $Lev!"
+IRC_WoWmsg = "<WoW>[$Name] $Msg"
+WoW_IRCmsg = "<IRC>[$Name]: $Msg"
+WoW_IRCaction = "<IRC>*$Name $Msg"
+IRC_sysmsg = "04,08/!\System Message/!\ $Msg 04,08/!\System Message/!\"
+IRC_sysnotice = "04,08/!\System Notice/!\ $Msg 04,08/!\System Notice/!\"
+GMAnnounceMessage = "|cffff0000[$Rank $Name has come Online]|r"
+GMAnnounceIRCMessage = "12>>04 $Rank $Name has come Online"
+GMRankMod  = "Mod"
+GMRankGM = "GM"
+GMRankAdmin = "Admin"
+# IRC Text Variables End
+####################################################
+
+#########################
+# IRC Configuration End #
+#########################
Index: src/mangosd/Master.cpp
===================================================================
--- src/mangosd/Master.cpp	(revision 3815)
+++ src/mangosd/Master.cpp	(working copy)
@@ -34,6 +34,7 @@
 #include "SystemConfig.h"
 #include "Config/ConfigEnv.h"
 #include "Database/DatabaseEnv.h"
+#include "../game/IRCClient.h"
 #include "CliRunnable.h"
 #include "RASocket.h"
 #include "ScriptCalls.h"
@@ -178,6 +179,9 @@
     uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / socketSelecttime));
     uint32 loopCounter = 0;
 
+    ZThread::Thread irc(new IRCClient);
+    irc.setPriority ((ZThread::Priority )2);
+
     ///- Wait for termination signal
     while (!World::m_stopEvent)
     {
Index: src/realmd/Makefile.am
===================================================================
--- src/realmd/Makefile.am	(revision 3815)
+++ src/realmd/Makefile.am	(working copy)
@@ -30,7 +30,7 @@
 	RealmList.h
 
 ## Link realm list daemon against the shared library
-mangos_realmd_LDADD = ../shared/libmangosdatabase.a ../shared/libmangosconfig.a ../shared/libmangosauth.a ../shared/libmangosshared.a ../shared/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zthread/libZThread.la
+mangos_realmd_LDADD = ../shared/libmangosdatabase.a ../shared/libmangosconfig.a ../shared/libmangosauth.a ../shared/libmangosshared.a ../shared/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zlib/libzlib.a ../../dep/src/zthread/libZThread.la
 mangos_realmd_LDFLAGS = -L../../dep/src/zthread $(MYSQL_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB)
 
 ## Additional files to include when running 'make dist'
Index: src/shared/Database/DBCfmt.cpp
===================================================================
--- src/shared/Database/DBCfmt.cpp	(revision 3815)
+++ src/shared/Database/DBCfmt.cpp	(working copy)
@@ -16,11 +16,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-const char AreaTableEntryfmt[]="iiinixxxxxixxxxxxxxxixxxxxx";
+const char AreaTableEntryfmt[]="iiinixxxxxissssssssxixxxxxx";
 const char BankBagSlotPricesEntryfmt[]="ni";
 const char BattlemasterListEntryfmt[]="niixxxxxxiiiixxssssssssx";
 const char ChatChannelsEntryfmt[]="iixssssssssxxxxxxxxxx";  // data not sorted (more compact store)
-const char ChrClassesEntryfmt[]="nxxixxxxxxxxxxxxxx";
+const char ChrClassesEntryfmt[]="nxxixssssssssxxxxx";
 const char ChrRacesEntryfmt[]="nxixiixxixxxxissssssssxxxxx";
 const char CreatureFamilyfmt[]="nxxxxxiissssssssxx";
 const char EmoteEntryfmt[]="nxixxxxxxxxxxxxxxxx";
Index: src/shared/Database/DBCStructure.h
===================================================================
--- src/shared/Database/DBCStructure.h	(revision 3815)
+++ src/shared/Database/DBCStructure.h	(working copy)
@@ -41,7 +41,7 @@
     uint32    flags;                                        // 4, unknown value but 312 for all cities
                                                             // 5-9 unused
     int32     area_level;                                   //10
-    //char*     area_name[8];                               //11-18, unused
+    char*     area_name[8];                               //11-18, unused
                                                             //19, string flags, unused
     uint32    team;                                         //20,
 };
@@ -84,7 +84,7 @@
                                                             // 1-2, unused
     uint32      powerType;                                  // 3
                                                             // 4, unused
-    //char*       name[8];                                  // 5-12, unused
+    char*       name[8];                                  // 5-12, unused
                                                             // 13 string flags, unused
 };
 
Index: win/mangosdVC71.sln
===================================================================
--- win/mangosdVC71.sln	(revision 3815)
+++ win/mangosdVC71.sln	(working copy)
@@ -34,6 +34,7 @@
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "realmd", "VC71\realmd.vcproj", "{563E9905-3657-460C-AE63-0AC39D162E23}"
 	ProjectSection(ProjectDependencies) = postProject
 		{BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E} = {BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E}
+		{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942} = {8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}
 		{90297C34-F231-4DF4-848E-A74BCC0E40ED} = {90297C34-F231-4DF4-848E-A74BCC0E40ED}
 		{1DC6C4DA-A028-41F3-877D-D5400C594F88} = {1DC6C4DA-A028-41F3-877D-D5400C594F88}
 		{262199E8-EEDF-4700-A1D1-E9CC901CF480} = {262199E8-EEDF-4700-A1D1-E9CC901CF480}
Index: win/mangosdVC80.sln
===================================================================
--- win/mangosdVC80.sln	(revision 3815)
+++ win/mangosdVC80.sln	(working copy)
@@ -1,9 +1,9 @@
 Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual C++ Express 2005
+# Visual Studio 2005
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "game", "VC80\game.vcproj", "{1DC6C4DA-A028-41F3-877D-D5400C594F88}"
 	ProjectSection(ProjectDependencies) = postProject
+		{BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E} = {BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E}
 		{90297C34-F231-4DF4-848E-A74BCC0E40ED} = {90297C34-F231-4DF4-848E-A74BCC0E40ED}
-		{BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E} = {BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared", "VC80\shared.vcproj", "{90297C34-F231-4DF4-848E-A74BCC0E40ED}"
@@ -13,11 +13,11 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mangosd", "VC80\mangosd.vcproj", "{A3A04E47-43A2-4C08-90B3-029CEF558594}"
 	ProjectSection(ProjectDependencies) = postProject
+		{BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E} = {BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E}
+		{90297C34-F231-4DF4-848E-A74BCC0E40ED} = {90297C34-F231-4DF4-848E-A74BCC0E40ED}
+		{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2} = {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}
+		{1DC6C4DA-A028-41F3-877D-D5400C594F88} = {1DC6C4DA-A028-41F3-877D-D5400C594F88}
 		{262199E8-EEDF-4700-A1D1-E9CC901CF480} = {262199E8-EEDF-4700-A1D1-E9CC901CF480}
-		{1DC6C4DA-A028-41F3-877D-D5400C594F88} = {1DC6C4DA-A028-41F3-877D-D5400C594F88}
-		{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2} = {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}
-		{90297C34-F231-4DF4-848E-A74BCC0E40ED} = {90297C34-F231-4DF4-848E-A74BCC0E40ED}
-		{BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E} = {BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zthread", "VC80\zthread.vcproj", "{262199E8-EEDF-4700-A1D1-E9CC901CF480}"
@@ -28,11 +28,12 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "realmd", "VC80\realmd.vcproj", "{563E9905-3657-460C-AE63-0AC39D162E23}"
 	ProjectSection(ProjectDependencies) = postProject
+		{A3A04E47-43A2-4C08-90B3-029CEF558594} = {A3A04E47-43A2-4C08-90B3-029CEF558594}
 		{BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E} = {BF6F5D0E-33A5-4E23-9E7D-DD481B7B5B9E}
+		{90297C34-F231-4DF4-848E-A74BCC0E40ED} = {90297C34-F231-4DF4-848E-A74BCC0E40ED}
+		{8F1DEA42-6A5B-4B62-839D-C141A7BFACF2} = {8F1DEA42-6A5B-4B62-839D-C141A7BFACF2}
+		{1DC6C4DA-A028-41F3-877D-D5400C594F88} = {1DC6C4DA-A028-41F3-877D-D5400C594F88}
 		{262199E8-EEDF-4700-A1D1-E9CC901CF480} = {262199E8-EEDF-4700-A1D1-E9CC901CF480}
-		{1DC6C4DA-A028-41F3-877D-D5400C594F88} = {1DC6C4DA-A028-41F3-877D-D5400C594F88}
-		{A3A04E47-43A2-4C08-90B3-029CEF558594} = {A3A04E47-43A2-4C08-90B3-029CEF558594}
-		{90297C34-F231-4DF4-848E-A74BCC0E40ED} = {90297C34-F231-4DF4-848E-A74BCC0E40ED}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "script", "VC80\script.vcproj", "{4205C8A9-79B7-4354-8064-F05FB9CA0C96}"
Index: win/VC71/game.vcproj
===================================================================
--- win/VC71/game.vcproj	(revision 3815)
+++ win/VC71/game.vcproj	(working copy)
@@ -709,6 +709,21 @@
 			</File>
 		</Filter>
 		<Filter
+			Name="IRC">
+			<File
+				RelativePath="..\..\src\game\IRCClient.cpp">
+			</File>
+			<File
+				RelativePath="..\..\src\game\IRCClient.h">
+			</File>
+			<File
+				RelativePath="..\..\src\game\IRCCommands.cpp">
+			</File>
+			<File
+				RelativePath="..\..\src\game\IRCCommands.h">
+			</File>
+		</Filter>
+		<Filter
 			Name="Tool">
 			<File
 				RelativePath="..\..\src\game\Language.h">
Index: win/VC80/game.vcproj
===================================================================
--- win/VC80/game.vcproj	(revision 3815)
+++ win/VC80/game.vcproj	(working copy)
@@ -968,6 +968,26 @@
 				>
 			</File>
 		</Filter>
+		<Filter
+			Name="IRC"
+			>
+			<File
+				RelativePath="..\..\src\game\IRCClient.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\game\IRCClient.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\game\IRCCommands.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\game\IRCCommands.h"
+				>
+			</File>
+		</Filter>
 	</Files>
 	<Globals>
 	</Globals>
Index: win/VC80/mangosd.vcproj
===================================================================
--- win/VC80/mangosd.vcproj	(revision 3815)
+++ win/VC80/mangosd.vcproj	(working copy)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="8,00"
+	Version="8.00"
 	Name="mangosd"
 	ProjectGUID="{A3A04E47-43A2-4C08-90B3-029CEF558594}"
 	RootNamespace="mangosd"