Skip to content

Instantly share code, notes, and snippets.

@Bezo
Last active December 14, 2015 03:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Bezo/25c49cb50f3e96f4922a to your computer and use it in GitHub Desktop.
Save Bezo/25c49cb50f3e96f4922a to your computer and use it in GitHub Desktop.
diff --git a/sql/TriniChat2.sql b/sql/TriniChat2.sql
new file mode 100644
index 0000000..fa3d783
--- /dev/null
+++ b/sql/TriniChat2.sql
@@ -0,0 +1,80 @@
+/*
+* Table structure for irc_commands
+*/
+DROP TABLE IF EXISTS `irc_commands`;
+CREATE TABLE `irc_commands` (
+ `Command` varchar(10) NOT NULL default '',
+ `Description` varchar(350) default NULL,
+ `gmlevel` tinyint(3) unsigned NOT NULL default '0',
+ PRIMARY KEY (`Command`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='IRC Module System';
+
+/*
+* Records
+*/
+INSERT INTO `irc_commands` VALUES ('acct', '[acct <Player> <(un)lock/email/pass/rename/gmlevel>] : Perform Action To <Player> Account.', '3');
+INSERT INTO `irc_commands` VALUES ('ban', '[ban <Player/IP> <ip/acct/unban/reason>] : Ban/Unban <Player>', '3');
+INSERT INTO `irc_commands` VALUES ('chan', '[chan <op/deop/voice/devoice> <*IRC Nick*>] : Set Mode On Yourself, If <IRC Nick> Is Specified Then Set mode On Nick.', '3');
+INSERT INTO `irc_commands` VALUES ('char', '[char <Player> <mailcheat/taxicheat/maxskill/setskill/combatstop/quest/mod>] : Perform Action To Character.', '3');
+INSERT INTO `irc_commands` VALUES ('fun', '[fun <Player> <Sound/Say>] : Do Selected Fun Action To <Player>.', '3');
+INSERT INTO `irc_commands` VALUES ('help', '[help Command] : Use No Paramaters For List Of Available Commands.', '0');
+INSERT INTO `irc_commands` VALUES ('inchan', '[inchan <Channel>] : Display Users In Selected In Game <Channel>', '0');
+INSERT INTO `irc_commands` VALUES ('info', '[info] : Display Server Info. (Number Of Players Online/Max Since Last Restart/Uptime)', '0');
+INSERT INTO `irc_commands` VALUES ('item', '[item <Player> <add> <ItemID/[ItemName]> <Amount>] : Additem To <Player>, Use <ItemID> Or <[Exact Item Name]>.', '3');
+INSERT INTO `irc_commands` VALUES ('jail', '[jail <Player> <release/Reason>] : Jail Selected <Player> For <Reason>. Using release As <Reason> Releases Player.', '3');
+INSERT INTO `irc_commands` VALUES ('kick', '[kick <Player> <Reason>] : Kick <Player> For <Reason>.', '3');
+INSERT INTO `irc_commands` VALUES ('kill', '[kill <Player> <Reason>] : Kill <Player> For <Reason>.', '3');
+INSERT INTO `irc_commands` VALUES ('level', '[level <Player> <NewLevel>] : Level <Player> To <NewLevel>. *Can Be Done Offline*', '3');
+INSERT INTO `irc_commands` VALUES ('login', '[login <UserName> <Password>] : Login To TriniChat Admin Mode. (Must Be Done In A PM)', '0');
+INSERT INTO `irc_commands` VALUES ('logout', '[logout] : Logout Of TriniChat Admin Mode.', '0');
+INSERT INTO `irc_commands` VALUES ('lookup', '[lookup <acct/char/creature/faction/go/item/quest/skill/spell/tele> <ID/Name>] : ', '3');
+INSERT INTO `irc_commands` VALUES ('money', '[money <Player> <(-)Money>] : Give Money To <Player>, Use - To Take Money. *Can Be Done Offline*', '3');
+INSERT INTO `irc_commands` VALUES ('mute', '[mute <Player> <release/TimeInMins> <Reason>] : Mute Player For Reason, For <TimeInMins>. Using release As Time Releases Player. *Can Be Done Offline*', '3');
+INSERT INTO `irc_commands` VALUES ('online', '[online] : Display All Users Logged In Game.', '0');
+INSERT INTO `irc_commands` VALUES ('pm', '[pm <Player> <Message>] : Whisper <Player> In WoW <Message>.', '3');
+INSERT INTO `irc_commands` VALUES ('reload', '[reload] : Reload TriniChat Config Options And Security Level From DataBase.', '3');
+INSERT INTO `irc_commands` VALUES ('restart', '[restart] : Restart TriniChat, NOT Trinity Core World Server Itself. Forces Reconnection To IRC Server.', '3');
+INSERT INTO `irc_commands` VALUES ('revive', '[revive <Player>] : Revive <Player>.', '3');
+INSERT INTO `irc_commands` VALUES ('saveall', '[saveall] : Forces Trinity Core To Save All Players.', '3');
+INSERT INTO `irc_commands` VALUES ('server', '[server setmotd [<motd>]/flusharenapoints]', '3');
+INSERT INTO `irc_commands` VALUES ('shutdown', '[shutdown <TimeInSeconds>] : Shuts The Server Down In <TimeInSeconds>, Use 0 For Immediate Shut Down', '3');
+INSERT INTO `irc_commands` VALUES ('spell', '[spell <Player> <Cast/Learn/UnLearn> <SpellID>] : Make <Player> <Learn> Or <UnLearn> A Spell, Or <Cast> A Spell On A <Player>.', '3');
+INSERT INTO `irc_commands` VALUES ('sysmsg', '[sysmsg <a/n/e/add/del/list> <Message>] : Broadcasts A System Message. (a-Broadcast System Message)(n-Broadcast Notify Message)(e-Event Message)', '3');
+INSERT INTO `irc_commands` VALUES ('tele', '[tele <Player> <l/c/r/to/cr/go/homebind> <Loc.Name/MAPID X Y Z/Recall/Player/Creature GUID/Gameobject GUID>] : Teleport Player To Location, Coords, Recall Location, Another Player, Creature or Gameobject. (l-Location)(c-Coords)', '3');
+INSERT INTO `irc_commands` VALUES ('top', '[top <accttime/chartime/money> <limit>] : Display top stats for given option. Only GM Higher Than Config Option Can Use Limit.', '3');
+INSERT INTO `irc_commands` VALUES ('who', '[who] : Displays Users Currently Logged In To TriniChat.', '1');
+
+/*
+* Table structure for 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 '',
+ `channel` varchar(15) NOT NULL default '',
+ PRIMARY KEY (`guid`,`channel`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='IRC Module System';
+
+/*
+* Records
+*/
+/*
+* Table structure for irc_autoannounce
+*/
+DROP TABLE IF EXISTS `irc_autoannounce`;
+CREATE TABLE `irc_autoannounce` (
+ `id` int(11) NOT NULL auto_increment,
+ `message` longtext NOT NULL,
+ `addedby` varchar(12) NOT NULL default '',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='IRC Module System';
+
+/*
+* Records
+*/
+INSERT INTO `irc_autoannounce` VALUES ('1', 'Welcome to IRC Channel', '');
+
+DELETE FROM `trinity_string` WHERE entry IN (6620,6621,6622);
+INSERT INTO `trinity_string` VALUES ('6620', '|cffff0000[System Message]: %s|r', null, null, null, null, null, null, null, null);
+INSERT INTO `trinity_string` VALUES ('6621', '|cffff0000[Server Event]: %s|r', null, null, null, null, null, null, null, null);
+INSERT INTO `trinity_string` VALUES ('6622', '|cffff0000[Automatic]: %s|r', null, null, null, null, null, null, null, null);
\ No newline at end of file
diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
index f455610..cc0d949 100644
--- a/src/server/game/CMakeLists.txt
+++ b/src/server/game/CMakeLists.txt
@@ -43,6 +43,7 @@ file(GLOB_RECURSE sources_Server Server/*.cpp Server/*.h)
file(GLOB_RECURSE sources_Skills Skills/*.cpp Skills/*.h)
file(GLOB_RECURSE sources_Spells Spells/*.cpp Spells/*.h)
file(GLOB_RECURSE sources_Texts Texts/*.cpp Texts/*.h)
+file(GLOB_RECURSE sources_TriniChat TriniChat/*.cpp Texts/*.h)
file(GLOB_RECURSE sources_Tools Tools/*.cpp Tools/*.h)
file(GLOB_RECURSE sources_Tickets Tickets/*.cpp Tickets/*.h)
file(GLOB_RECURSE sources_Warden Warden/*.cpp Warden/*.h)
@@ -93,6 +94,7 @@ set(game_STAT_SRCS
${sources_Skills}
${sources_Spells}
${sources_Texts}
+ ${sources_TriniChat}
${sources_Tools}
${sources_Tickets}
${sources_Warden}
@@ -189,6 +191,7 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/Spells
${CMAKE_CURRENT_SOURCE_DIR}/Spells/Auras
${CMAKE_CURRENT_SOURCE_DIR}/Texts
+ ${CMAKE_CURRENT_SOURCE_DIR}/TriniChat
${CMAKE_CURRENT_SOURCE_DIR}/Tools
${CMAKE_CURRENT_SOURCE_DIR}/Tickets
${CMAKE_CURRENT_SOURCE_DIR}/Warden
diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp
index 9e7a63c..1d9c432 100644
--- a/src/server/game/Chat/Channels/Channel.cpp
+++ b/src/server/game/Chat/Channels/Channel.cpp
@@ -24,6 +24,7 @@
#include "DatabaseEnv.h"
#include "AccountMgr.h"
#include "Player.h"
+#include "IRCClient.h"
Channel::Channel(std::string const& name, uint32 channelId, uint32 team):
_announce(true),
@@ -210,6 +211,8 @@ void Channel::JoinChannel(Player* player, std::string const& pass)
JoinNotify(guid);
+ sIRC.Handle_WoW_Channel(_name, ObjectAccessor::FindPlayer(guid), CHANNEL_JOIN);
+
// Custom channel handling
if (!IsConstant())
{
@@ -260,6 +263,8 @@ void Channel::LeaveChannel(Player* player, bool send)
SendToAll(&data);
}
+ sIRC.Handle_WoW_Channel(_name, ObjectAccessor::FindPlayer(guid), CHANNEL_LEAVE);
+
LeaveNotify(guid);
if (!IsConstant())
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index 3cae9d0..2cb2254 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -35,6 +35,7 @@
#include "SpellMgr.h"
#include "ScriptMgr.h"
#include "ChatLink.h"
+#include "IRCClient.h"
bool ChatHandler::load_command_table = true;
@@ -371,6 +372,14 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, co
sLog->outCommand(m_session->GetAccountId(), "Command: %s [Player: %s (Account: %u) X: %f Y: %f Z: %f Map: %u Selected %s: %s (GUID: %u)]",
fullcmd.c_str(), p->GetName().c_str(), m_session->GetAccountId(), p->GetPositionX(), p->GetPositionY(), p->GetPositionZ(), p->GetMapId(),
GetLogNameForGuid(sel_guid), (p->GetSelectedUnit()) ? p->GetSelectedUnit()->GetName().c_str() : "", GUID_LOPART(sel_guid));
+ if ((sIRC.logmask & 2) != 0)
+ {
+ std::string logchan = "#";
+ logchan += sIRC.logchan;
+ std::stringstream ss;
+ ss << sIRC.iLog.GetLogDateTimeStr() << ": [ " << p->GetName() << "(" << GetSession()->GetSecurity() << ") ] Used Command: [ " << fullcmd << " ] Target: [" << GUID_LOPART(sel_guid) << "]";
+ sIRC.Send_IRC_Channel(logchan,ss.str().c_str(), true, "LOG");
+ }
}
}
}
@@ -879,6 +888,38 @@ char* ChatHandler::extractKeyFromLink(char* text, char const* const* linkTypes,
return NULL;
}
+char const *fmtstring (char const *format, ...)
+{
+ va_list argptr;
+ #define MAX_FMT_STRING 32000
+ static char temp_buffer[MAX_FMT_STRING];
+ static char string[MAX_FMT_STRING];
+ static int index = 0;
+ char *buf;
+ int len;
+
+ va_start(argptr, format);
+ vsnprintf(temp_buffer,MAX_FMT_STRING, format, argptr);
+ va_end(argptr);
+
+ len = strlen(temp_buffer);
+
+ if (len >= MAX_FMT_STRING)
+ return "ERROR";
+
+ if (len + index >= MAX_FMT_STRING-1)
+ {
+ index = 0;
+ }
+
+ buf = &string[index];
+ memcpy(buf, temp_buffer, len+1);
+
+ index += len + 1;
+
+ return buf;
+}
+
GameObject* ChatHandler::GetNearbyGameObject()
{
if (!m_session)
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index 4b93ddc..dd85692 100644
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -20,6 +20,7 @@
#define TRINITYCORE_CHAT_H
#include "SharedDefines.h"
+#include "../TriniChat/IRCClient.h"
#include "WorldSession.h"
#include <vector>
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index 529c847..a5d4fd0 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -665,7 +665,7 @@ struct ChrClassesEntry
// 1, unused
uint32 powerType; // 2
// 3-4, unused
- //char* name[16]; // 5-20 unused
+ char* name[16]; // 5-20 Trinichat2
// 21 string flag, unused
//char* nameFemale[16]; // 21-36 unused, if different from base (male) case
// 37 string flag, unused
diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h
index c82fdf8..fb20e99 100644
--- a/src/server/game/DataStores/DBCfmt.h
+++ b/src/server/game/DataStores/DBCfmt.h
@@ -34,7 +34,7 @@
char const CharStartOutfitEntryfmt[] = "dbbbXiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
char const CharTitlesEntryfmt[] = "nxssssssssssssssssxxxxxxxxxxxxxxxxxxi";
char const ChatChannelsEntryfmt[] = "nixssssssssssssssssxxxxxxxxxxxxxxxxxx";
-char const ChrClassesEntryfmt[] = "nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
+char const ChrClassesEntryfmt[] = "nxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
char const ChrRacesEntryfmt[] = "nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
char const CinematicSequencesEntryfmt[] = "nxxxxxxxxx";
char const CreatureDisplayInfofmt[] = "nixxfxxxxxxxxxxx";
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index c7c88ae..b13a583 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -49,6 +49,7 @@
#include "GuildMgr.h"
#include "InstanceSaveMgr.h"
#include "InstanceScript.h"
+#include "IRCClient.h"
#include "Language.h"
#include "LFGMgr.h"
#include "Log.h"
@@ -2433,6 +2434,15 @@ void Player::RemoveFromWorld()
SetViewpoint(viewpoint, false);
}
}
+ // TODO: FIXME
+ if (sIRC.ajoin == 1)
+ {
+ QueryResult result = WorldDatabase.PQuery("SELECT `name` FROM `irc_inchan` WHERE `name` = '%s'", Unit::GetName().c_str());
+ if (!result)
+ {
+ sIRC.AutoJoinChannel(this);
+ }
+ }
}
void Player::RegenerateAll()
@@ -3050,6 +3060,17 @@ void Player::GiveLevel(uint8 level)
InitTaxiNodesForLevel();
InitGlyphsForLevel();
+ if ((sIRC.BOTMASK & 64) != 0)
+ {
+ char temp [5];
+ sprintf(temp, "%u", level);
+ std::string plevel = temp;
+ std::string pname = GetName();
+ std::string ircchan = "#";
+ ircchan += sIRC._irc_chan[sIRC.Status].c_str();
+ sIRC.Send_IRC_Channel(ircchan, "\00311["+pname+"] : Has Reached Level: "+plevel, true);
+ }
+
UpdateAllStats();
if (sWorld->getBoolConfig(CONFIG_ALWAYS_MAXSKILL)) // Max weapon skill when leveling up
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 362b6ac..3393cf0 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2875,6 +2875,8 @@ class Player : public Unit, public GridObject<Player>
uint32 _pendingBindTimer;
uint32 _activeCheats;
+ public:
+ QuestStatusSaveMap m_RewardedQuestsSave2;
};
void AddItemsSetItem(Player*player, Item* item);
diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp
index 89ce810..53e44da 100644
--- a/src/server/game/Events/GameEventMgr.cpp
+++ b/src/server/game/Events/GameEventMgr.cpp
@@ -29,6 +29,7 @@
#include "BattlegroundMgr.h"
#include "UnitAI.h"
#include "GameObjectAI.h"
+#include "IRCClient.h"
bool GameEventMgr::CheckOneGameEvent(uint16 entry) const
{
@@ -1106,6 +1107,12 @@ void GameEventMgr::ApplyNewEvent(uint16 event_id)
{
if (sWorld->getBoolConfig(CONFIG_EVENT_ANNOUNCE))
sWorld->SendWorldText(LANG_EVENTMESSAGE, mGameEvent[event_id].description.c_str());
+ if ((sIRC.BOTMASK & 256) != 0)
+ {
+ std::string ircchan = "#";
+ ircchan += sIRC._irc_chan[sIRC.anchn].c_str();
+ sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("\00304,08\037/!\\\037\017\00304 Game Event \00304,08\037/!\\\037\017 %s", "%s", mGameEvent[event_id].description.c_str()), true);
+ }
sLog->outInfo(LOG_FILTER_GAMEEVENTS, "GameEvent %u \"%s\" started.", event_id, mGameEvent[event_id].description.c_str());
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index 6af397f..b40d10c 100644
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -824,7 +824,6 @@ class Guild
uint32 _GetRankRights(uint8 rankId) const;
int32 _GetRankBankMoneyPerDay(uint8 rankId) const;
int32 _GetRankBankTabSlotsPerDay(uint8 rankId, uint8 tabId) const;
- std::string _GetRankName(uint8 rankId) const;
int32 _GetMemberRemainingSlots(Member const* member, uint8 tabId) const;
int32 _GetMemberRemainingMoney(Member const* member) const;
@@ -843,6 +842,7 @@ class Guild
void _SendBankMoneyUpdate(WorldSession* session) const;
void _SendBankContentUpdate(MoveItemData* pSrc, MoveItemData* pDest) const;
void _SendBankContentUpdate(uint8 tabId, SlotIds slots) const;
+ std::string _GetRankName(uint8 rankId) const;
void _SendBankList(WorldSession* session = NULL, uint8 tabId = 0, bool sendFullSlots = false, SlotIds *slots = NULL) const;
void _BroadcastEvent(GuildEvents guildEvent, uint64 guid, const char* param1 = NULL, const char* param2 = NULL, const char* param3 = NULL) const;
diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp
index 6fc88f4..45d95ec 100644
--- a/src/server/game/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Handlers/AuctionHouseHandler.cpp
@@ -29,6 +29,7 @@
#include "UpdateMask.h"
#include "Util.h"
#include "AccountMgr.h"
+#include "IRCClient.h"
//please DO NOT use iterator++, because it is slower than ++iterator!!!
//post-incrementation is always slower than pre-incrementation !
@@ -549,10 +550,19 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket& recvData)
// Now remove the auction
+ uint32 item;
+ recvData >> item;
+
player->SaveInventoryAndGoldToDB(trans);
auction->DeleteFromDB(trans);
CharacterDatabase.CommitTransaction(trans);
+ if ((sIRC.BOTMASK & 2048) != 0)
+ {
+ ItemTemplate const *pProto = sObjectMgr->GetItemTemplate(item);
+ sIRC.AHFunc(auction->itemEntry, pProto->Name1, player->GetName(), auction->GetHouseId());
+ }
+
uint32 itemEntry = auction->itemEntry;
sAuctionMgr->RemoveAItem(auction->itemGUIDLow);
auctionHouse->RemoveAuction(auction, itemEntry);
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index d04d365..ea39082 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -429,7 +429,8 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
}
}
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(_player->GetTeam()))
+ sIRC.Send_WoW_IRC(_player, channel, msg);
+ if (ChannelMgr* cMgr = ChannelMgr::forTeam(_player->GetTeam()))
{
if (Channel* chn = cMgr->GetChannel(channel, _player))
{
diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp
index 2da2735..fae65c0 100644
--- a/src/server/game/Handlers/TicketHandler.cpp
+++ b/src/server/game/Handlers/TicketHandler.cpp
@@ -27,6 +27,7 @@
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
+#include "IRCClient.h"
void WorldSession::HandleGMTicketCreateOpcode(WorldPacket& recvData)
{
@@ -90,6 +91,22 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket& recvData)
sWorld->SendGMText(LANG_COMMAND_TICKETNEW, GetPlayer()->GetName().c_str(), ticket->GetId());
response = GMTICKET_RESPONSE_CREATE_SUCCESS;
+
+ if ((sIRC.TICMASK & 1) != 0 && (sIRC.BOTMASK & 1024) != 0)
+ {
+ std::string ircchan = "#";
+ std::ostringstream smsg;
+ ircchan += sIRC._irc_chan[sIRC.ticann].c_str();
+ smsg << "[By: \00304" << GetPlayer()->GetName().c_str() << "\003 ][ID: \00304" << ticket->GetId() << "\003 ]";
+ sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("[\00304Ticket Created\003] %s", " %s" , smsg.str().c_str()) , true);
+ if (ticket->GetMessage().size() <= 400)
+ sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("[\00304Ticket Massage\003]: %s ", " %s", ticket->GetMessage().c_str()), true);
+ else
+ {
+ sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("[\00304Ticket Massage(1/2)\003]: %s ", " %s", ticket->GetMessage().substr(0, 399).c_str()), true);
+ sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("[\00304Ticket Massage(2/2)\003]: %s ", " %s", ticket->GetMessage().substr(400, 800).c_str()), true);
+ }
+ }
}
WorldPacket data(SMSG_GMTICKET_CREATE, 4);
@@ -112,6 +129,22 @@ void WorldSession::HandleGMTicketUpdateOpcode(WorldPacket& recvData)
sWorld->SendGMText(LANG_COMMAND_TICKETUPDATED, GetPlayer()->GetName().c_str(), ticket->GetId());
response = GMTICKET_RESPONSE_UPDATE_SUCCESS;
+
+ if ((sIRC.TICMASK & 2) != 0 && (sIRC.BOTMASK & 1024) != 0)
+ {
+ std::string ircchan = "#";
+ std::ostringstream smsg;
+ ircchan += sIRC._irc_chan[sIRC.ticann].c_str();
+ smsg << "[By: \00304" << GetPlayer()->GetName().c_str() << "\003 ][ID: \00304" << ticket->GetId() << "\003 ]";
+ sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("[\00304Ticket Updated\003] %s", " %s" , smsg.str().c_str()) , true);
+ if (ticket->GetMessage().size() <= 400)
+ sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("[\00304Ticket Massage\003]: %s ", " %s", ticket->GetMessage().c_str()), true);
+ else
+ {
+ sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("[\00304Ticket Massage(1/2)\003]: %s ", " %s", ticket->GetMessage().substr(0, 399).c_str()), true);
+ sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("[\00304Ticket Massage(2/2)\003]: %s ", " %s", ticket->GetMessage().substr(400, 800).c_str()), true);
+ }
+ }
}
WorldPacket data(SMSG_GMTICKET_UPDATETEXT, 4);
@@ -131,6 +164,15 @@ void WorldSession::HandleGMTicketDeleteOpcode(WorldPacket & /*recvData*/)
sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
sTicketMgr->SendTicket(this, NULL);
+
+ if ((sIRC.TICMASK & 4) != 0 && (sIRC.BOTMASK & 1024) != 0)
+ {
+ std::string ircchan = "#";
+ std::ostringstream smsg;
+ ircchan += sIRC._irc_chan[sIRC.ticann].c_str();
+ smsg << "[By: \00304" << GetPlayer()->GetName().c_str() << " \003][ID: \00304" << ticket->GetId() << "\003 ]";
+ sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("[\00311Ticket Abandoned\003] %s", " %s" , smsg.str().c_str()) , true);
+ }
}
}
@@ -220,6 +262,36 @@ void WorldSession::HandleReportLag(WorldPacket& recvData)
stmt->setUInt32(6, GetLatency());
stmt->setUInt32(7, time(NULL));
CharacterDatabase.Execute(stmt);
+
+ if ((sIRC.TICMASK & 8) != 0 && (sIRC.BOTMASK & 1024) != 0)
+ {
+ std::string ircchan = "#";
+ std::ostringstream lmsg;
+ std::ostringstream ltype;
+ ircchan += sIRC._irc_chan[sIRC.ticann].c_str();
+ lmsg << "[By: \00310" << GetPlayer()->GetName().c_str() << "\003]";
+ sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("[\00310Lag Report\003] %s", " %s" , lmsg.str().c_str()) , true);
+ lmsg.str("");
+ lmsg.clear();
+ if (lagType == 0)
+ ltype << "Loot";
+ else if (lagType == 1)
+ ltype << "Auction House";
+ else if (lagType == 2)
+ ltype << "Mail";
+ else if (lagType == 3)
+ ltype << "Chat";
+ else if (lagType == 4)
+ ltype << "Movement";
+ else if (lagType == 5)
+ ltype << "Spells and Abilites";
+ else
+ ltype << "unknown";
+ lmsg << "[Type: \00310" << ltype.str().c_str() << " \003][mapid: \00310" << mapId << " \003][ X: \00310" << x << " \003][ Y: \00310" << y << " \003][ Z: \00310" << z
+ << " \003][Latancy: \00310" << GetLatency() << " \003][Time: \00310" << sLog->GetTimestampStr() << "\003]";
+ sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("\003 %s", " %s" , lmsg.str().c_str()) , true);
+
+ }
}
void WorldSession::HandleGMResponseResolve(WorldPacket& /*recvPacket*/)
diff --git a/src/server/game/TriniChat/IRCClient.cpp b/src/server/game/TriniChat/IRCClient.cpp
new file mode 100644
index 0000000..b705ea5
--- /dev/null
+++ b/src/server/game/TriniChat/IRCClient.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#include "IRCClient.h"
+#include "World.h"
+#include "ObjectMgr.h"
+#include "MapManager.h"
+
+#include "framework/Policies/SingletonImp.h"
+INSTANTIATE_SINGLETON_1(IRCClient);
+
+#ifdef WIN32
+ #define Delay(x) Sleep(x)
+#else
+ #define Delay(x) sleep(x / 1000)
+#endif
+// IRCClient Constructor
+IRCClient::IRCClient()
+{
+ for (int i = 0;i > 5;i++)
+ sIRC.Script_Lock[i] = false;
+}
+// IRCClient Destructor
+IRCClient::~IRCClient(){}
+
+// ZThread Entry This function is called when the thread is created in Master.cpp (trinitycore)
+void IRCClient::run()
+{
+ sIRC.iLog.WriteLog(" %s : ****** Trinity Core With TriniChat Has Been Started ******", sIRC.iLog.GetLogDateTimeStr().c_str());
+
+ // before we begin we wait a few
+ // mangos is still starting up.
+ ACE_Based::Thread::Sleep(500);
+ sLog->outError(LOG_FILTER_GENERAL, "\n%s\n%s\n%s\n%s",
+ "***************************************",
+ "** TriniChat2 Threaded IRC Client **",
+ "** With Enhanced GM Control. **",
+ "***************************************");
+ sLog->outError(LOG_FILTER_GENERAL, "****** TriniChat: %s ********", sIRC._Mver.c_str());
+ int cCount = 1;
+ // Clean Up MySQL Tables
+ sLog->outError(LOG_FILTER_GENERAL, "*** TriniChat: Cleaning Up Inchan Table*");
+ WorldDatabase.PExecute("DELETE FROM `irc_inchan`");
+ sIRC._Max_Script_Inst = 0;
+ // Create a loop to keep the thread running untill active is set to false
+ while (sIRC.Active && !World::IsStopped())
+ {
+ // Initialize socket library
+ if (this->InitSock())
+ {
+ // Connect To The IRC Server
+ sLog->outError(LOG_FILTER_GENERAL, "*** TriniChat: Connecting to %s Try # %d ******", sIRC._Host.c_str(), cCount);
+ if (this->Connect(sIRC._Host.c_str(), sIRC._Port))
+ {
+ // On connection success reset the connection counter
+ cCount = 0;
+ sLog->outError(LOG_FILTER_GENERAL, "*** TriniChat: Connected And Logging In*");
+ // Login to the IRC server
+ if (this->Login(sIRC._Nick, sIRC._User, sIRC._Pass))
+ {
+ sLog->outError(LOG_FILTER_GENERAL, "*** TriniChat: Logged In And Running!! *");
+ // While we are connected to the irc server keep listening for data on the socket
+ while (sIRC.Connected && !World::IsStopped()){ sIRC.SockRecv(); }
+ }
+ sLog->outError(LOG_FILTER_GENERAL, "*** TriniChat: Connection To IRC Server Lost! ***");
+ }
+ // When an error occures or connection lost cleanup
+ Disconnect();
+ // Increase the connection counter
+ cCount++;
+ // if MAX_CONNECT_ATTEMPT is reached stop trying
+ if (sIRC._MCA != 0 && cCount == sIRC._MCA)
+ sIRC.Active = false;
+ // If we need to reattempt a connection wait WAIT_CONNECT_TIME milli seconds before we try again
+ if (sIRC.Active)
+ ACE_Based::Thread::Sleep(sIRC._wct);
+ }
+ else
+ {
+ // Socket could not initialize cancel
+ sIRC.Active = false;
+ sLog->outError(LOG_FILTER_GENERAL, "** TriniChat: Could not initialize socket");
+ }
+ }
+ while (!World::IsStopped()){};
+}
+
+std::string IRCClient::GetChatLine(int nItem)
+{
+ return sIRC.ILINES[nItem];
+}
\ No newline at end of file
diff --git a/src/server/game/TriniChat/IRCClient.h b/src/server/game/TriniChat/IRCClient.h
new file mode 100644
index 0000000..c9872ea
--- /dev/null
+++ b/src/server/game/TriniChat/IRCClient.h
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef _IRC_CLIENT_H
+#define _IRC_CLIENT_H
+
+#include "framework/Policies/SingletonImp.h"
+#include "Player.h"
+#include "IRCLog.h"
+#include "IRCCmd.h"
+
+using namespace std;
+// The maximum ammount of channels used, must be >= config option
+#define MAX_CONF_CHANNELS 10
+#define MAX_CHAT_LINES 10
+// time we need to wait before we try another connecton attempt
+// Default is 30 seconds
+#define MAX_SCRIPT_INST 10
+// CLINES is used for the default chatlines
+// By using the GetChatLine function its easier and faster
+// to receieve the line you need.
+enum CLINES
+{
+ IRC_WOW = 0,
+ WOW_IRC = 1,
+ JOIN_WOW = 2,
+ JOIN_IRC = 3,
+ LEAVE_WOW = 4,
+ LEAVE_IRC = 5,
+ CHANGE_NICK = 6
+};
+// CACTION is used by the Handle_WoW_Channel function
+// this function is called in channel.h when a player
+// joins or leave a channel inside the client.
+enum CACTION
+{
+ CHANNEL_JOIN,
+ CHANNEL_LEAVE,
+};
+
+enum script_Names
+{
+ MCS_Players_Online = 0,
+};
+
+// IRCClient main class
+class IRCClient : public ACE_Based::Runnable
+{
+ public:
+ // IRCClient Constructor
+ IRCClient();
+ // IRCClient Destructor
+ ~IRCClient();
+ // ZThread Entry
+ void run();
+ public:
+ // AH Function
+ void AHFunc(uint64 itmid, std::string itmnme, std::string plname, uint32 faction);
+ //bool BeenToGMI(float posx, float posy, std::string player, std::string from);
+ // IRCClient active
+ bool Active;
+ // Connected to IRC
+ bool Connected;
+ // Socket indentifier
+ int SOCKET;
+ fd_set sfdset;
+ // Send data to IRC, in addition the endline is added \n
+ bool SendIRC(std::string data);
+ // This function is called in ChatHandler.cpp and processes the chat from game to IRC
+ void Send_WoW_IRC(Player *plr, std::string Channel, std::string Msg);
+ // Sends a message to all players on the specified channel
+ void Send_WoW_Channel(const char *channel, std::string chat);
+ // Send a system message to all players
+ void Send_WoW_System(std::string Message);
+ // Send a message to the specified IRC channel
+ void Send_IRC_Channel(std::string sChannel, std::string sMsg, bool NoPrefix = false, std::string nType = "PRIVMSG");
+ // Sends a message to all IRC Channels
+ void Send_IRC_Channels(std::string sMsg);
+ std::string 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;
+ }
+ void Send_WoW_Player(string sPlayer, string sMsg);
+ void Send_WoW_Player(Player *plr, string sMsg);
+
+ // This function is called in Channel.cpp and processes Join/leave messages
+ void Handle_WoW_Channel(std::string Channel, Player *plr, int nAction);
+ void ResetIRC();
+ public:
+ void AutoJoinChannel(Player *plr);
+
+ public:
+ bool Script_Lock[5];
+ bool _AmiOp;
+
+ public:
+ string _Mver;
+ // IRC Server host
+ string _Host;
+ // IRC Server Port
+ int _Port;
+ // IRC Username
+ string _User;
+ // IRC Password
+ string _Pass;
+ // IRC Nickname
+ string _Nick;
+ //Password for in-game channel
+ std::string _irc_pass[MAX_CONF_CHANNELS];
+ // Authentication type
+ int _Auth;
+ string _Auth_Nick;
+ // IRC Connect code
+ string _ICC;
+ // IRC Default channel
+ string _defchan;
+ // IRC Leave Default channel
+ int _ldefc;
+ // Wait Connect Time
+ int _wct;
+ // BotMask Options
+ int Botmask;
+ // Ticket Channel
+ int ticann;
+ // Status Channel
+ int Status;
+ // Announce Channel
+ int anchn;
+ int autoanc;
+ // IRC Channel count
+ int _chan_count;
+ // IRC Channel list
+ // Array to store our IRC channels
+ // each element will corrospond
+ // with _wow_chan array below.
+ std::string _irc_chan[MAX_CONF_CHANNELS];
+ // Game Channel list
+ std::string _wow_chan[MAX_CONF_CHANNELS];
+ // AutoJoin Options
+ int ajoin;
+ string ajchan;
+ // Online Command Max Results
+ int onlrslt;
+ // Channel OnJoin/Restart/Kick Messages
+ string JoinMsg;
+ string RstMsg;
+ string kikmsg;
+ // Misc Options
+ string ojGM1;
+ string ojGM2;
+ string ojGM3;
+ string ojGM4;
+ string ojGM5;
+ string ojGM6;
+ string ojGM7;
+ string ojGM8;
+ string logfile;
+ string logchan;
+ string logchanpw;
+ int logmask;
+ int games;
+ int gmlog;
+ // IRC Commands Security Level
+ int CACCT;
+ int CBAN;
+ int CCHAN;
+ int CCHAR;
+ int CFUN;
+ int CHELP;
+ int CINCHAN;
+ int CINFO;
+ int CITEM;
+ int CJAIL;
+ int CKICK;
+ int _KILL;
+ int CLEVEL;
+ int CLOOKUP;
+ int CMONEY;
+ int CMUTE;
+ int CONLINE;
+ int CPM;
+ int CRECONNECT;
+ int CRELOAD;
+ int CREVIVE;
+ int CSAVEALL;
+ int CSERVERCMD;
+ int CSHUTDOWN;
+ int CSPELL;
+ int CSYSMSG;
+ int CTELE;
+ int CTOP;
+ int CPLAYER;
+ int CWHO;
+ // BotMask
+ int BOTMASK;
+ // TicketMask
+ int TICMASK;
+ // Max connect attempt
+ int _MCA;
+ // Auto rejoin when kicked from irc
+ int _autojoinkick;
+ // IRC Command prefix
+ string _cmd_prefx;
+ int _op_gm;
+ int _op_gm_lev;
+ // Array that contains our chatlines from the conf file
+ // To increase this value change the MAX_CHAT_LINE define above
+ // Make sure the number of elements must match your items
+ // (remeber this starts at 0 so 0..9 is 10 items)
+ // and that you load the line in the LoadConfig function.
+ string ILINES[MAX_CHAT_LINES];
+ string GetChatLine(int nItem);
+
+ int _Max_Script_Inst;
+ // MAX_SCRIPT_INST
+
+ IRCLog iLog;
+
+private:
+ // Returns default chatline based on enum CLINES
+ // Initialize socket library
+ bool InitSock();
+ // Connect to IRC Server
+ bool Connect(const char *cHost, int nPort);
+ // Login to IRC Server
+ bool Login(std::string sNick, std::string sUser, std::string sPass);
+ // Send raw data to IRC
+ bool SendData(const char *data);
+ // Disconnect from IRC and cleanup socket
+ void Disconnect();
+ // Processes the data receieved from IRC
+ void Handle_IRC(std::string sData);
+ // Receieves data from the socket.
+ void SockRecv();
+};
+#endif
+#define sIRC Trinity::Singleton<IRCClient>::Instance()
\ No newline at end of file
diff --git a/src/server/game/TriniChat/IRCCmd.cpp b/src/server/game/TriniChat/IRCCmd.cpp
new file mode 100644
index 0000000..cd4ba6a
--- /dev/null
+++ b/src/server/game/TriniChat/IRCCmd.cpp
@@ -0,0 +1,897 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#include "IRCCmd.h"
+#include "IRCClient.h"
+#include "Database/DatabaseEnv.h"
+#include "ObjectMgr.h"
+#include "AccountMgr.h"
+#include "MapManager.h"
+#include "World.h"
+// Constructor
+IRCCmd::IRCCmd(){}
+// Destructor
+IRCCmd::~IRCCmd(){}
+
+std::string IRCCmd::MakeUpper(std::string Channel)
+{
+ std::string tmpchan = Channel;
+ std::transform(tmpchan.begin(), tmpchan.end(), tmpchan.begin(), towupper);
+ return tmpchan;
+}
+bool IRCCmd::ParamsValid(_CDATA *CD, int pCnt)
+{
+ CD->PCOUNT = pCnt;
+ if (CD->PARAMS.size() == 0)
+ return false;
+ return ValidParams(CD->PARAMS, pCnt);
+}
+
+int IRCCmd::ParamsValid(_CDATA *CD, int pCnt, int rLev)
+{
+ //CD->PCOUNT = pCnt;
+ if (!CanUse(CD->USER, rLev))
+ return E_AUTH;
+ else if (pCnt == 0)
+ return E_OK;
+ else if (CD->PARAMS.size() == 0)
+ return E_SIZE;
+ else if (!ValidParams(CD->PARAMS, pCnt))
+ return E_SIZE;
+ return E_OK;
+}
+
+// This function checks if chat from irc is a command or not
+// return true on yes and false on no
+bool IRCCmd::IsValid(std::string USER, std::string FROM, std::string CHAT, std::string TYPE)
+{
+ // If the first line of our chat is the command prefix we have a command
+ if (CHAT.substr(0, 1) == sIRC._cmd_prefx && CHAT.size() > 1)
+ {
+ _CDATA CDATA;
+ bool cValid = false;
+ bool AuthValid = true;
+ bool dontlog = true;
+ std::string* _PARAMS = getArray(CHAT, 2);
+ CDATA.USER = USER;
+ CDATA.FROM = FROM;
+ CDATA.TYPE = TYPE;
+ CDATA.PCOUNT = 0;
+ CDATA.CMD = MakeUpper(_PARAMS[0].substr(1, _PARAMS[0].size() - 1));
+ CDATA.PARAMS = _PARAMS[1];
+ if (CDATA.CMD == "LOGIN")
+ {
+ if (FROM == sIRC._Nick)
+ {
+ if (ParamsValid(&CDATA, 2))
+ Handle_Login(&CDATA);
+ else
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"login <Player> <Password>)", true, "ERROR");
+ }
+ else
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Please Send A PM To Login!", true, "ERROR");
+ if (GetLevel(USER) >= sIRC.gmlog)
+ dontlog = false;
+ cValid = true;
+ }
+ else if (CDATA.CMD == "LOGOUT")
+ {
+ if (FROM == sIRC._Nick)
+ {
+ Handle_Logout(&CDATA);
+ }
+ else
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Please Send A PM To Logout!", true, "ERROR");
+ cValid = true;
+ }
+ else if (CDATA.CMD == "ACCT")
+ {
+ switch(ParamsValid(&CDATA, 2, sIRC.CACCT))
+ {
+ case E_OK:
+ Account_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"acct <Player> <(un)lock/email/pass/rename/gmlevel>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "BAN")
+ {
+ switch(ParamsValid(&CDATA, 2, sIRC.CBAN))
+ {
+ case E_OK:
+ Ban_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"ban <Player> <acct/ip>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "CHAN")
+ {
+ switch(ParamsValid(&CDATA, 1, sIRC.CCHAN))
+ {
+ case E_OK:
+ Chan_Control(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"chan <op> <IRC User>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "CHAR")
+ {
+ switch(ParamsValid(&CDATA, 2, sIRC.CCHAR))
+ {
+ case E_OK:
+ Char_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"char <Player> <mailcheat/taxicheat/maxskill/setskill/quest/mod>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "FUN")
+ {
+ switch(ParamsValid(&CDATA, 2, sIRC.CFUN))
+ {
+ case E_OK:
+ Fun_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"fun <Player> <Sound/Say>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "HELP")
+ {
+ switch(ParamsValid(&CDATA, 0, sIRC.CHELP))
+ {
+ case E_OK:
+ Help_IRC(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"help <Command>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "INCHAN")
+ {
+ switch(ParamsValid(&CDATA, 1, sIRC.CINCHAN))
+ {
+ case E_OK:
+ Inchan_Server(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"inchan <Channel>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "INFO")
+ {
+ switch(ParamsValid(&CDATA, 0, sIRC.CINFO))
+ {
+ case E_OK:
+ Info_Server(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"info)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "ITEM")
+ {
+ CDATA.PCOUNT = 3;
+ switch(ParamsValid(&CDATA, 2, sIRC.CITEM))
+ {
+ case E_OK:
+ Item_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"item <Player> <add> <ItemID/[ItemName]> <Amount>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "JAIL")
+ {
+ CDATA.PCOUNT = 3;
+ switch(ParamsValid(&CDATA, 1, sIRC.CJAIL))
+ {
+ case E_OK:
+ Jail_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"jail <Player> <release/Reason>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "KICK")
+ {
+ CDATA.PCOUNT = 2;
+ switch(ParamsValid(&CDATA, 1, sIRC.CKICK))
+ {
+ case E_OK:
+ Kick_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"kick <Player> <Reason>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "KILL")
+ {
+ CDATA.PCOUNT = 2;
+ switch(ParamsValid(&CDATA, 1, sIRC._KILL))
+ {
+ case E_OK:
+ Kill_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"kill <Player> <Reason>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "LEVEL")
+ {
+ CDATA.PCOUNT = 2;
+ switch(ParamsValid(&CDATA, 2, sIRC.CLEVEL))
+ {
+ case E_OK:
+ Level_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"level <Player> <NewLevel>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "LOOKUP")
+ {
+ CDATA.PCOUNT = 2;
+ switch(ParamsValid(&CDATA, 2, sIRC.CLOOKUP))
+ {
+ case E_OK:
+ Lookup_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"lookup <acct/char/creature/faction/go/item/quest/skill/spell/tele> <ID/Name>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "MONEY")
+ {
+ CDATA.PCOUNT = 2;
+ switch(ParamsValid(&CDATA, 2, sIRC.CMONEY))
+ {
+ case E_OK:
+ Money_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"money <Player> <(-)Money>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "MUTE")
+ {
+ switch(ParamsValid(&CDATA, 2, sIRC.CMUTE))
+ {
+ case E_OK:
+ Mute_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"mute <Player> <release/TimeInMins> <Reason>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "ONLINE")
+ {
+ switch(ParamsValid(&CDATA, 0, sIRC.CONLINE))
+ {
+ case E_OK:
+ Online_Players(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"online)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "PM")
+ {
+ switch(ParamsValid(&CDATA, 2, sIRC.CPM))
+ {
+ case E_OK:
+ PM_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"pm <Player> <Message>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "RELOAD")
+ {
+ switch(ParamsValid(&CDATA, 0, sIRC.CRELOAD))
+ {
+ case E_OK:
+ sIRC.Send_IRC_Channels("Reloading Configiguration Options.");
+ sWorld->LoadConfigSettings(true);
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "RECONNECT")
+ {
+ switch(ParamsValid(&CDATA, 0, sIRC.CRECONNECT))
+ {
+ case E_OK:
+ sIRC.Send_IRC_Channels(sIRC.RstMsg);
+ sIRC.ResetIRC();
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "RESTART")
+ {
+ switch(ParamsValid(&CDATA, 0, sIRC.CSHUTDOWN))
+ {
+ case E_OK:
+ Restart_Trinity(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"server <setmotd/flusharenapoints/sec_number_for_restart>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "REVIVE")
+ {
+ CDATA.PCOUNT = 2;
+ switch(ParamsValid(&CDATA, 1, sIRC.CREVIVE))
+ {
+ case E_OK:
+ Revive_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"revive <Player>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "SAVEALL")
+ {
+ switch(ParamsValid(&CDATA, 0, sIRC.CSAVEALL))
+ {
+ case E_OK:
+ Saveall_Player(&CDATA);
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "SERVER")
+ {
+ CDATA.PCOUNT = 2;
+ switch(ParamsValid(&CDATA, 2, sIRC.CSERVERCMD))
+ {
+ case E_OK:
+ Server(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"server <setmotd/flusharenapoints>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "SHUTDOWN")
+ {
+ switch(ParamsValid(&CDATA, 1, sIRC.CSHUTDOWN))
+ {
+ case E_OK:
+ Shutdown_Trinity(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"shutdown <TimeInSeconds>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "SPELL")
+ {
+ switch(ParamsValid(&CDATA, 2, sIRC.CSPELL))
+ {
+ case E_OK:
+ Spell_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"spell <Player> <Cast/Learn/UnLearn> <SpellID>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "SYSMSG")
+ {
+ CDATA.PCOUNT = 2;
+ switch(ParamsValid(&CDATA, 2, sIRC.CSYSMSG))
+ {
+ case E_OK:
+ Sysmsg_Server(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"sysmsg <a/e/n/add/del/list> <Message>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "TELE")
+ {
+ switch(ParamsValid(&CDATA, 2, sIRC.CTELE))
+ {
+ case E_OK:
+ Tele_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"tele <Player> <l/c/r/to/cr/go/homebind> <Loc.Name/MAPID X Y Z/Recall/Player/Creature GUID/GO GUID/Homebind>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "TOP")
+ {
+ CDATA.PCOUNT = 1;
+ switch(ParamsValid(&CDATA, 1, sIRC.CTOP))
+ {
+ case E_OK:
+ Top_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"top <accttime/chartime/money> <limit>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "PLAYER")
+ {
+ CDATA.PCOUNT = 1;
+ switch(ParamsValid(&CDATA, 1, sIRC.CPLAYER))
+ {
+ case E_OK:
+ Player_Player(&CDATA);
+ break;
+ case E_SIZE:
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ("+sIRC._cmd_prefx+"player <PLAYER>)", true, "ERROR");
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ else if (CDATA.CMD == "WHO")
+ {
+ switch(ParamsValid(&CDATA, 0, sIRC.CWHO))
+ {
+ case E_OK:
+ Who_Logged(&CDATA);
+ break;
+ case E_AUTH:
+ AuthValid = false;
+ break;
+ }
+ cValid = true;
+ }
+ if (!AuthValid && IsLoggedIn(USER))
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Access Denied! Your Security Level Is Too Low To Use This Command!", true, "ERROR");
+ if (cValid == false && (sIRC.BOTMASK & 4) != 0)
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Unknown Command!", true, "ERROR");
+ if (cValid && dontlog)
+ {
+ sIRC.iLog.WriteLog(" %s : [ %s(%d) ] Used Command: [ %s ] With Parameters: [ %s ]", sIRC.iLog.GetLogDateTimeStr().c_str(), CDATA.USER.c_str(), GetLevel(USER), CDATA.CMD.c_str(), CDATA.PARAMS.c_str());
+ if ((sIRC.logmask & 1) != 0)
+ {
+ std::string logchan = "#";
+ logchan += sIRC.logchan;
+ std::stringstream ss;
+ ss << sIRC.iLog.GetLogDateTimeStr() << ": [ " << CDATA.USER << "(" << GetLevel(USER) << ") ] Used Command: [ " << CDATA.CMD << " ] With Parameters: [" << CDATA.PARAMS << " ]";
+ sIRC.Send_IRC_Channel(logchan, ss.str().c_str(), true);
+ }
+ }
+ return cValid;
+ }
+ return false;
+}
+
+bool IRCCmd::CanUse(std::string USER, int nLevel)
+{
+ if (IsLoggedIn(USER))
+ {
+ if (GetLevel(USER) >= nLevel)
+ return true;
+ else
+ return false;
+ }
+ else if (nLevel == 0)
+ {
+ return true;
+ }
+ else
+ sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : You Are Not Logged In!", true, "ERROR");
+ return false;
+}
+
+std::string IRCCmd::ChanOrPM(_CDATA *CD)
+{
+ if (CD->FROM == sIRC._Nick)
+ return CD->USER;
+ else
+ return CD->FROM;
+}
+
+Player *IRCCmd::GetPlayer(std::string WHO)
+{
+ normalizePlayerName(WHO);
+ return sObjectAccessor->FindPlayerByName(WHO.c_str());
+}
+
+_client *IRCCmd::GetClient(std::string cname)
+{
+ for (std::list<_client*>::iterator i=_CLIENTS.begin(); i!=_CLIENTS.end();i++)
+ {
+ if ((*i)->Name == cname)
+ return (*i);
+ }
+ return (NULL);
+}
+
+bool IRCCmd::IsLoggedIn(std::string USER)
+{
+ for (std::list<_client*>::iterator i=_CLIENTS.begin(); i!=_CLIENTS.end();i++)
+ {
+ if ((*i)->Name == USER)
+ return true;
+ }
+ return false;
+}
+
+bool IRCCmd::AcctIsLoggedIn(std::string USER)
+{
+ for (std::list<_client*>::iterator i=_CLIENTS.begin(); i!=_CLIENTS.end();i++)
+ {
+ if (MakeUpper((*i)->UName) == MakeUpper(USER))
+ return true;
+ }
+ return false;
+}
+
+std::string IRCCmd::AcctIsBanned(std::string ACCT)
+{
+ uint32 acctid = AccountMgr::GetId(ACCT);
+ std::string banned = "NOTBANNED";
+ QueryResult result = LoginDatabase.PQuery("SELECT banreason FROM ip_banned WHERE ip=(SELECT last_ip FROM account WHERE id = '%i')", acctid);
+ if (result)
+ {
+ banned = (*result)[0].GetCString();
+
+ return "IP Banned. Reason:" + banned;
+ }
+ QueryResult result2 = LoginDatabase.PQuery("SELECT banreason FROM account_banned WHERE id='%i'", acctid);
+ if (result2)
+ {
+ banned = (*result2)[0].GetCString();
+
+ return "Account Banned. Reason:" + banned;
+ }
+ return banned;
+}
+
+int IRCCmd::GetLevel(std::string sName)
+{
+ for (std::list<_client*>::iterator i=_CLIENTS.begin(); i!=_CLIENTS.end();i++)
+ {
+ if ((*i)->Name == sName)
+ return (*i)->GMLevel;
+ }
+ return 0;
+}
+
+int IRCCmd::AcctLevel(std::string plnme)
+{
+ uint64 guid = sObjectMgr->GetPlayerGUIDByName(plnme);
+ uint32 account_id = 0;
+ uint32 security = 0;
+ account_id = sObjectMgr->GetPlayerAccountIdByGUID(guid);
+ security = AccountMgr::GetSecurity(account_id);
+ return security;
+}
+
+std::string IRCCmd::GetAccName(std::string sName)
+{
+ for (std::list<_client*>::iterator i=_CLIENTS.begin(); i!=_CLIENTS.end();i++)
+ {
+ if ((*i)->Name == sName)
+ return (*i)->UName;
+ }
+ return "";
+}
+
+std::string IRCCmd::GetNameFromAcct(std::string sName)
+{
+ for (std::list<_client*>::iterator i=_CLIENTS.begin(); i!=_CLIENTS.end();i++)
+ {
+ if ((*i)->UName == sName)
+ return (*i)->Name;
+ }
+ return "";
+}
+
+int IRCCmd::GetAcctIDFromName(std::string sName)
+{
+ for (std::list<_client*>::iterator i=_CLIENTS.begin(); i!=_CLIENTS.end();i++)
+ {
+ if ((*i)->Name == sName)
+ {
+ uint32 acct_id = 0;
+ acct_id = AccountMgr::GetId((*i)->UName.c_str());
+ return acct_id;
+ }
+ }
+ return 0;
+}
+
+std::string IRCCmd::GetAcctNameFromID(uint32 acctid)
+{
+ QueryResult result = LoginDatabase.PQuery("SELECT username FROM account WHERE id = '%d'", acctid);
+ if (result)
+ {
+ std::string name = (*result)[0].GetCString();
+
+ return name;
+ }
+
+ return "";
+}
+
+std::string IRCCmd::GetIPFromPlayer(std::string player)
+{
+ QueryResult result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name = '%s'", player.c_str());
+ if (result)
+ {
+ std::string acctid = (*result)[0].GetCString();
+
+ QueryResult result2 = LoginDatabase.PQuery("SELECT last_ip FROM account WHERE id = '%s'", acctid.c_str());
+ if (result2)
+ {
+ std::string ip = (*result2)[0].GetCString();
+
+ return ip;
+ }
+ }
+
+ return "";
+}
+
+std::string IRCCmd::SecToDay(std::string secons)
+{
+ unsigned int seconds = atoi(secons.c_str());
+ unsigned int days = seconds / 86400;
+ unsigned int hours = seconds / 3600 % 24;
+ unsigned int mins = seconds / 60 % 60;
+ char tottime[1000];
+ sprintf(tottime, "%iDays:%iHours:%iMinutes", days, hours, mins);
+
+ return tottime;
+}
+
+bool IRCCmd::ValidParams(std::string PARAMS, int nCount)
+{
+ if (nCount == 1 && PARAMS.size() == 0)
+ return false;
+ int pcount = 0;
+ size_t p = -1;
+ for (int i = 0;i < nCount;i++)
+ {
+ p = PARAMS.find(" ", p + 1);
+ if (p == -1)
+ break;
+ else
+ pcount++;
+ }
+ nCount--;
+ if (pcount >= nCount)
+ return true;
+ else
+ return false;
+}
+
+std::string* IRCCmd::getArray(std::string PARAMS, int nCount)
+{
+ std::string *array = new std::string[nCount];
+ if (PARAMS.size() > 0)
+ {
+ int pcnt = 0;
+ size_t ps = 0;
+ size_t pc = -1;
+ for (int i = 0;i < nCount;i++)
+ {
+ pc = PARAMS.find(" ", pc + 1);
+ if (i + 1 == nCount && nCount != 1)
+ {
+ if (ps > 0 && pc > 0)
+ array[i] = PARAMS.substr(ps, PARAMS.size() - ps);
+ }
+ else
+ array[i] = PARAMS.substr(ps, pc - ps);
+ ps = pc + 1;
+ }
+ }
+ return array;
+}
+
+std::string IRCCmd::MakeMsg(const char *sLine, ...)
+{
+ va_list ap;
+ char tmpoutp[1024];
+ va_start(ap, sLine);
+ vsnprintf(tmpoutp, 1024, sLine, ap);
+ va_end(ap);
+ std::string outp = tmpoutp;
+ return outp;
+}
+
+void IRCClient::AHFunc(uint64 itmid, std::string itmnme, std::string plname, uint32 faction)
+{
+ IRCCmd Command;
+ Player* plr = Command.GetPlayer(plname);
+ if (plr)
+ {
+ std::string itemname = itmnme;
+
+ char temp [7];
+ sprintf(temp, "%u", itmid);
+ std::string itemid = temp;
+
+ std::string wowname = "";
+ std::string ircname = "";
+ switch (plr->GetTeam())
+ {
+ case 67:wowname="|cffff0000"+plname+"|r";ircname="\0034"+plname;break; //horde
+ case 469:wowname="|cff1589FF"+plname+"|r";ircname="\00312"+plname;break; //alliance
+ }
+
+ std::string wowfact = "|cffFF8040[Auction House]:|r";
+ std::string ircfact = "\00304,08\037/!\\\037\017\00307 Auction House \00304,08\037/!\\\037\017";
+ switch(faction)
+ {
+ //neutral
+ case 7:wowfact="|cffff8040[Neutral Auction House]:|r";ircfact="\00304,08\037/!\\\037\017\00307 Neutral Auction House \00304,08\037/!\\\037\017";break;
+ //horde
+ case 6:wowfact="|cffff0000[Horde Auction House]:|r";ircfact="\00304,08\037/!\\\037\017\00304 Horde Auction House \00304,08\037/!\\\037\017";break;
+ //alliance
+ case 2:wowfact="|cff1589FF[Alliance Auction House]:|r";ircfact="\00304,08\037/!\\\037\017\00312 Alliance Auction House \00304,08\037/!\\\037\017";break;
+ }
+ std::string wowstr = Command.MakeMsg("%s A New Item Has Been Added |cffffffff|Hitem:%s:0:0:0:0:0:0:0|h[%s]|h|r. By: %s",wowfact.c_str(), itemid.c_str(), itemname.c_str(), wowname.c_str());
+ std::string ircstr = Command.MakeMsg("%s A New Item Has Been Added [%s]. By: %s", ircfact.c_str(), itemname.c_str(), ircname.c_str());
+
+ sIRC.Send_WoW_Channel(sIRC._wow_chan[sIRC.Status].c_str(), wowstr.c_str());
+ sIRC.Send_IRC_Channel(sIRC._irc_chan[sIRC.Status].c_str(), ircstr.c_str());
+ }
+}
\ No newline at end of file
diff --git a/src/server/game/TriniChat/IRCCmd.h b/src/server/game/TriniChat/IRCCmd.h
new file mode 100644
index 0000000..fb959b9
--- /dev/null
+++ b/src/server/game/TriniChat/IRCCmd.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef _IRC_CMD_H
+#define _IRC_CMD_H
+
+#define MAX_CLIENTS 50
+#include "Common.h"
+#include "Player.h"
+#include "ObjectAccessor.h"
+#include "BattlegroundMgr.h"
+
+struct ChannelUser
+{
+ int UserType;
+ std::string Name;
+ std::string UName;
+ int UserLevel;
+};
+
+struct _client
+{
+ bool LoggedIn;
+ std::string Name;
+ std::string UName;
+ int GMLevel;
+};
+struct _CDATA
+{
+ std::string CMD;
+ std::string USER;
+ std::string FROM;
+ std::string PARAMS;
+ std::string TYPE;
+ int PCOUNT;
+};
+enum APVERR
+{
+ E_OK,
+ E_SIZE,
+ E_AUTH,
+ E_IVALID,
+};
+enum ESOUNDS
+{
+ S_ENTERWORLD = 602,
+ S_QUESTFAILED = 847,
+ S_INVITE = 880,
+ S_LEVELUP = 888,
+ S_COINSOUND = 895,
+ S_WHISPER = 3081,
+ S_STEALTH = 3325,
+};
+class IRCCmd
+{
+ public:
+ IRCCmd();
+ ~IRCCmd();
+
+ void Handle_Logout(_CDATA *CD);
+ bool IsLoggedIn(std::string USER);
+ bool IsValid(std::string USER, std::string FROM, std::string CHAT, std::string TYPE);
+ bool AcctIsLoggedIn(std::string USER);
+ _client *GetClient(std::string cname);
+
+ public:
+ static std::string MakeMsg(const char *sLine, ...);
+ static std::string ChanOrPM(_CDATA *CD);
+ int AcctLevel(std::string plnme);
+ int GetLevel(std::string sName);
+ std::string MakeUpper(std::string Channel);
+ std::string AcctIsBanned(std::string ACCT);
+ std::list<_client*> _CLIENTS;
+ Player* GetPlayer(std::string WHO);
+
+ private:
+ // TriniChat Commands
+ void Handle_Login(_CDATA *CD);
+ void Account_Player(_CDATA *CD);
+ void Ban_Player(_CDATA *CD);
+ void Chan_Control(_CDATA *CD);
+ void Char_Player(_CDATA *CD);
+ void Fun_Player(_CDATA *CD);
+ void Help_IRC(_CDATA *CD);
+ void Inchan_Server(_CDATA *CD);
+ void Info_Server(_CDATA *CD);
+ void Item_Player(_CDATA *CD);
+ void Jail_Player(_CDATA *CD);
+ void Kick_Player(_CDATA *CD);
+ void Kill_Player(_CDATA *CD);
+ void Player_Player(_CDATA *CD);
+ void Lookup_Player(_CDATA *CD);
+ void Level_Player(_CDATA *CD);
+ void Money_Player(_CDATA *CD);
+ void Mute_Player(_CDATA *CD);
+ void Online_Players(_CDATA *CD);
+ void PM_Player(_CDATA *CD);
+ void Restart_Trinity(_CDATA *CD);
+ void Revive_Player(_CDATA *CD);
+ void Saveall_Player(_CDATA *CD);
+ void Server(_CDATA *CD);
+ void Shutdown_Trinity(_CDATA *CD);
+ void Spell_Player(_CDATA *CD);
+ void Sysmsg_Server(_CDATA *CD);
+ void Tele_Player(_CDATA *CD);
+ void Top_Player(_CDATA *CD);
+ void Who_Logged(_CDATA *CD);
+ bool CanUse(std::string USER, int nLevel);
+ bool ValidParams(std::string PARAMS, int nCount = 1);
+ bool ParamsValid(_CDATA *CD, int pCnt);
+ int ParamsValid(_CDATA *CD, int pCnt, int rLev);
+ std::string GetAccName(std::string sName);
+ std::string GetNameFromAcct(std::string sName);
+ std::string GetAcctNameFromID(uint32 acctid);
+ std::string GetIPFromPlayer(std::string player);
+ std::string SecToDay(std::string secons);
+ int GetAcctIDFromName(std::string sName);
+ std::string* getArray(std::string PARAMS, int nCount = 1);
+};
+inline void MakeLower(std::string& str)
+{
+ std::transform(str.begin(), str.end(), str.begin(), ::tolower);
+}
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/IRCCmde.cpp b/src/server/game/TriniChat/IRCCmde.cpp
new file mode 100644
index 0000000..3687c97
--- /dev/null
+++ b/src/server/game/TriniChat/IRCCmde.cpp
@@ -0,0 +1,2364 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#include "IRCCmd.h"
+#include <iostream>
+#include "IRCClient.h"
+#include "MCS_OnlinePlayers.h"
+#include "WorldPacket.h"
+#include "Database/DatabaseEnv.h"
+#include "Chat.h"
+#include "MapManager.h"
+#include "World.h"
+#include "Guild.h"
+#include "ObjectMgr.h"
+#include "AccountMgr.h"
+#include "Language.h"
+#include "SpellAuras.h"
+#include "SystemConfig.h"
+#include "Config.h"
+#include "ReputationMgr.h"
+#include "ArenaTeamMgr.h"
+
+#pragma warning(disable:4018)
+#pragma warning(disable:4804)
+#pragma warning(disable:4700)
+
+#define Send_Player(p, m) sIRC.Send_WoW_Player(p, m)
+#define Send_IRCA(c, m, b, t) sIRC.Send_IRC_Channel(c, m, b, t)
+
+#ifdef WIN32
+#define Delay(x) Sleep(x)
+#else
+#define Delay(x) sleep(x / 1000)
+#endif
+
+void IRCCmd::Handle_Login(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 2);
+ std::string isbanned = AcctIsBanned(_PARAMS[0]);
+ LoginDatabase.EscapeString(_PARAMS[0]);
+ LoginDatabase.EscapeString(_PARAMS[1]);
+ if (isbanned == "NOTBANNED")
+ {
+ if (!IsLoggedIn(CD->USER))
+ {
+ if (!AcctIsLoggedIn(_PARAMS[0].c_str()))
+ {
+ QueryResult result = LoginDatabase.PQuery("SELECT `gmlevel` FROM `account`, `account_access` WHERE `username`='%s' AND `account_access`.`id`=`account`.`id` AND `sha_pass_hash`=SHA1(CONCAT(UPPER(`username`),':',UPPER('%s')));", _PARAMS[0].c_str(), _PARAMS[1].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ int GMLevel = fields[0].GetUInt8();
+ if (GMLevel >= 0)
+ {
+ _client *NewClient = new _client();
+ NewClient->Name = CD->USER;
+ NewClient->UName = MakeUpper(_PARAMS[0]);
+ NewClient->GMLevel = fields[0].GetUInt8();
+ _CLIENTS.push_back(NewClient);
+ Send_IRCA(CD->USER, MakeMsg("You Are Now Logged In As %s.", _PARAMS[0].c_str()), true, CD->TYPE);
+
+ if (sIRC._op_gm == 1 && GMLevel >= sIRC._op_gm_lev)
+ {
+ for (int i=1;i < sIRC._chan_count + 1;i++)
+ sIRC.SendIRC("MODE #"+sIRC._irc_chan[i]+" +o "+CD->USER);
+ }
+ }
+ }
+ else
+ Send_IRCA(CD->USER, "Sorry, Your Username Or Password Is Incorrect. Please Try Again. ", true, "ERROR");
+ }
+ else
+ for (std::list<_client*>::iterator i=_CLIENTS.begin(); i!=_CLIENTS.end();i++)
+ {
+ if ((*i)->UName == _PARAMS[0])
+ Send_IRCA(CD->USER, MakeMsg("%s Is Already Logged In With This Username. ", (*i)->Name.c_str()), true, "ERROR");
+ }
+ }
+ else
+ for (std::list<_client*>::iterator i=_CLIENTS.begin(); i!=_CLIENTS.end();i++)
+ {
+ if ((*i)->Name == CD->USER)
+ Send_IRCA(CD->USER, MakeMsg("You are already logged in as %s.", (*i)->UName.c_str()), true, "ERROR");
+ }
+ }
+ else
+ Send_IRCA(CD->USER, "Sorry, you are "+isbanned+" and can not log in.", true, "ERROR");
+}
+
+void IRCCmd::Handle_Logout(_CDATA *CD)
+{
+ for (std::list<_client*>::iterator i=_CLIENTS.begin(); i!=_CLIENTS.end();i++)
+ {
+ if ((*i)->Name == CD->USER)
+ {
+ delete (*i);
+ i = _CLIENTS.erase(i);
+ Send_IRCA(CD->USER, "Successfully logged out", true, CD->TYPE);
+ return;
+ }
+ }
+ Send_IRCA(CD->USER, "Not logged in", true, "ERROR");
+}
+
+void IRCCmd::Account_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 3);
+ if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512)!= 0)
+ {
+ Send_IRCA(CD->USER, MakeMsg("You do not have access to do this to a higher ranked GM [%i]", AcctLevel(_PARAMS[0])), true, "ERROR");
+ return;
+ }
+ normalizePlayerName(_PARAMS[0]);
+ uint64 guid = sObjectMgr->GetPlayerGUIDByName(_PARAMS[0]);
+ uint32 account_id = 0;
+ account_id = sObjectMgr->GetPlayerAccountIdByGUID(guid);
+ if (account_id)
+ {
+ if (account_id == GetAcctIDFromName(CD->USER) || GetLevel(CD->USER) >= sIRC._op_gm_lev)
+ {
+ Player* plr = ObjectAccessor::FindPlayer(guid);
+ if (_PARAMS[1] == "lock")
+ {
+ LoginDatabase.PExecute("UPDATE `account` SET `locked` = '1' WHERE `id` = '%d'",account_id);
+ if (plr) Send_Player(plr, MakeMsg("Your Account Has Been Locked To Your Current IP By: %s", CD->USER.c_str()));
+ Send_IRCA(ChanOrPM(CD), "\00313["+GetAcctNameFromID(account_id)+"] : Account Has Been Locked To Their Current IP Address.", true, CD->TYPE);
+ }
+ else if (_PARAMS[1] == "unlock")
+ {
+ LoginDatabase.PExecute("UPDATE `account` SET `locked` = '0' WHERE `id` = '%d'",account_id);
+ if (plr) Send_Player(plr, MakeMsg("Your Account Has Been UnLocked From The Associated IP By: %s", CD->USER.c_str()));
+ Send_IRCA(ChanOrPM(CD), "\00313["+GetAcctNameFromID(account_id)+"] : Account Has Been UnLocked From The Associated IP Address.", true, CD->TYPE);
+ }
+ else if (_PARAMS[1] == "email")
+ {
+ LoginDatabase.PExecute("UPDATE `account` SET `email` = '%s' WHERE `id` = '%d'",_PARAMS[2].c_str() ,account_id);
+ if (plr) Send_Player(plr, MakeMsg("%s Has Changed Your EMail Adress To: %s", CD->USER.c_str(), _PARAMS[2].c_str()));
+ Send_IRCA(ChanOrPM(CD), "\00313["+GetAcctNameFromID(account_id)+"] : EMail Address Successfully Changed To: "+_PARAMS[2], true, CD->TYPE);
+ }
+ else if (_PARAMS[1] == "pass")
+ {
+ LoginDatabase.PExecute("UPDATE `account` SET `sha_pass_hash` = SHA1(CONCAT(UPPER(`username`),':',UPPER('%s'))) WHERE `id` = '%d'",_PARAMS[2].c_str() ,account_id);
+ if (plr) Send_Player(plr, MakeMsg("%s Has Changed Your Password To: %s", CD->USER.c_str(), _PARAMS[2].c_str()));
+ Send_IRCA(ChanOrPM(CD), "\00313["+GetAcctNameFromID(account_id)+"] : Password Successfully Changed To: "+_PARAMS[2], true, CD->TYPE);
+ }
+ else if (_PARAMS[1] == "rename")
+ {
+ if (plr)
+ {
+ plr->SetAtLoginFlag(AT_LOGIN_RENAME);
+ Send_Player(plr, MakeMsg("%s Has Requested You Change This Characters Name, Rename Will Be Forced On Next Login!", CD->USER.c_str()));
+ }
+ CharacterDatabase.PExecute("UPDATE `characters` SET `at_login` = `at_login` | '1' WHERE `guid` = '%u'", guid);
+ Send_IRCA(ChanOrPM(CD), "\00313["+GetAcctNameFromID(account_id)+"] : Has Been Forced To Change Their Characters Name, Rename Will Be Forced On Next Login!", true, CD->TYPE);
+ }
+ else if (_PARAMS[1] == "gmlevel")
+ {
+ const char *cgmlevel = _PARAMS[2].c_str();
+ if (GetLevel(CD->USER) >= atoi(cgmlevel))
+ {
+ LoginDatabase.PExecute("UPDATE `account_access` SET `gmlevel` = '%s' WHERE `id` = '%d'", _PARAMS[2].c_str(), account_id);
+ Send_IRCA(ChanOrPM(CD), "\00313["+GetAcctNameFromID(account_id)+"] : Has GM Level Successfully Changed To: "+_PARAMS[2], true, CD->TYPE);
+ }
+ else
+ {
+ Send_IRCA(CD->USER, "The Specified GM Level Is Higher Than Your GM Level.", true, "ERROR");
+ }
+ }
+ }
+ else
+ Send_IRCA(CD->USER, "You Are Not A GM, You May Only Change Settings In Your Own Account.", true, "ERROR");
+ }
+ else
+ Send_IRCA(CD->USER, "No such player - account lookup failed", true, "ERROR");
+}
+
+void IRCCmd::Ban_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 4);
+ std::string duration = SecToDay (_PARAMS[3].c_str());
+ if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512)!= 0)
+ {
+ Send_IRCA(CD->USER, MakeMsg("You do not have access to do this to a higher ranked GM [%i]", AcctLevel(_PARAMS[0])), true, "ERROR");
+ return;
+ }
+ if (_PARAMS[1] == "ip")
+ {
+ std::string ip = GetIPFromPlayer(_PARAMS[0]);
+ if (_PARAMS[2] == "")
+ _PARAMS[2] = "No Reason";
+ if (ip != "")
+ {
+ sWorld->BanAccount(BAN_IP, ip.c_str(), _PARAMS[3].c_str(), _PARAMS[2], CD->USER);
+ if (Player* plr = GetPlayer(_PARAMS[0]))
+ plr->GetSession()->KickPlayer();
+ Send_IRCA(ChanOrPM(CD), MakeMsg("[%s] Has Had Their IP Address Banned. [%s] Reason: %s Duration: %s",_PARAMS[0].c_str() ,ip.c_str() , _PARAMS[2].c_str(), _PARAMS[3].c_str()), true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Can not locate IP-address for that charactername", true, "ERROR");
+ }
+ if (_PARAMS[1] == "acct")
+ {
+
+ if (_PARAMS[2] == "")
+ _PARAMS[2] = "No reason";
+ if (_PARAMS[3] == "")//set standard bantime to 1 day
+ _PARAMS[3] = "1d";
+ QueryResult result = LoginDatabase.PQuery("SELECT id FROM `account` WHERE username = '%s'", _PARAMS[0].c_str());
+ if (result)
+ {
+ sWorld->BanAccount(BAN_ACCOUNT, _PARAMS[0].c_str(), _PARAMS[3].c_str(), _PARAMS[2], CD->USER);
+ Send_IRCA(ChanOrPM(CD), MakeMsg("[%s] has been account-banned. Reason: %s Duration: %s",_PARAMS[0].c_str(), _PARAMS[2].c_str(), _PARAMS[3].c_str()), true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Can not find any accounts for that accountname", true, "ERROR");
+
+ }
+ if (_PARAMS[1] == "unban")
+ {
+ std::string unbani = _PARAMS[0];
+ if (atoi(unbani.c_str()) > 0)
+ {
+ LoginDatabase.PExecute("DELETE FROM ip_banned WHERE ip = '%s'", _PARAMS[0].c_str());
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\00313[%s] : Has Been Removed From The IP Ban List.", _PARAMS[0].c_str()), true, CD->TYPE);
+ }
+ else
+ {
+ QueryResult result = LoginDatabase.PQuery("SELECT id FROM `account` WHERE username = '%s'", _PARAMS[0].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ std::string id = fields[0].GetString();
+
+ LoginDatabase.PExecute("DELETE FROM account_banned WHERE id = %s", id.c_str());
+
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\00313[%s] : Has Been Removed From The Account Ban List.", _PARAMS[0].c_str()), true, CD->TYPE);
+
+ }
+ else
+ Send_IRCA(CD->USER, "I Cannot Locate An Account Or IP Address For The Paramaters Given.", true, "ERROR");
+ }
+ }
+}
+
+void IRCCmd::Char_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 5);
+ if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512)!= 0)
+ {
+ Send_IRCA(CD->USER, MakeMsg("You do not have access to do this to a higher ranked GM [%i]", AcctLevel(_PARAMS[0])), true, "ERROR");
+ return;
+ }
+ normalizePlayerName(_PARAMS[0]);
+ uint64 guid = sObjectMgr->GetPlayerGUIDByName(_PARAMS[0]);
+ Player* plr = ObjectAccessor::FindPlayer(guid);
+ if (plr)
+ {
+ if (_PARAMS[1] == "mapcheat")
+ {
+ bool explore = false;
+ if (_PARAMS[2] != "0")
+ explore = true;
+ for (uint8 i=0; i<64; i++)
+ {
+ if (_PARAMS[2] != "0")
+ plr->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
+ else
+ plr->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
+ }
+ if (explore)
+ {
+ Send_Player(plr, MakeMsg("All Your Zones Have Been Set To Explored By: %s", CD->USER.c_str()));
+ Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Now Explored All Zones.", true, CD->TYPE);
+ }
+ else
+ {
+ Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Now Had All Zones Set To Un-Explored.", true, CD->TYPE);
+ Send_Player(plr, MakeMsg("All Your Zones Have Been Set To Un-Explored By: %s", CD->USER.c_str()));
+ }
+ }
+ if (_PARAMS[1] == "taxicheat")
+ {
+ if (_PARAMS[2] != "0")
+ {
+ plr->SetTaxiCheater(true);
+ Send_Player(plr, MakeMsg("Taxi Node Cheat Has Been Enabled By: %s", CD->USER.c_str()));
+ Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Taxi Node Cheat Has Been Enabled.", true, CD->TYPE);
+ }
+ else
+ {
+ plr->SetTaxiCheater(false);
+ Send_Player(plr, MakeMsg("Taxi Node Cheat Has Been Disabled By: %s", CD->USER.c_str()));
+ Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Taxi Node Cheat Has Been Disabled.", true, CD->TYPE);
+ }
+ }
+ if (_PARAMS[1] == "maxskill")
+ {
+ plr->UpdateSkillsToMaxSkillsForLevel();
+ Send_Player(plr, MakeMsg("Your Skills Have Been Maxed Out By: %s", CD->USER.c_str()));
+ Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Skills Have Been Maxed Out.", true, CD->TYPE);
+ }
+ if (_PARAMS[1] == "setskill")
+ {
+ std::string* _PARAMSA = getArray(_PARAMS[2], 4);
+ uint32 skill = atoi(_PARAMS[2].c_str());
+ uint32 step = atoi(_PARAMS[3].c_str());
+ uint32 level = atol(_PARAMS[4].c_str());
+ int32 max = _PARAMS[5].c_str() ? atol (_PARAMS[5].c_str()) : plr->GetPureMaxSkillValue(skill);
+ SkillLineEntry const* skilllookup = sSkillLineStore.LookupEntry(skill);
+ //if skillid entered is not a number and greater then 0 then the command is being used wrong
+ if (skill >= 0)
+ {
+ //does the skill even exist
+ if (skilllookup)
+ {
+ //does player have the skill yet
+ if (plr->GetSkillValue(skill))
+ {
+ plr->SetSkill(skill,step,level,max);
+ Send_Player(plr, MakeMsg("Skill: %s Has Been Set To Level: %i Max: %i By: %s",skilllookup->name[0], level, max, CD->USER.c_str()));
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\00313[%s] : Has Had Skill: %s Set To Level: %d Max: %d",_PARAMS[0].c_str() , skilllookup->name[0], level, max), true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, MakeMsg("Player Does Not Have The %s Skill Yet.", skilllookup->name[0]), true, "ERROR");
+ }
+ else
+ Send_IRCA(CD->USER, "That Skill ID Does Not Exist.", true, "ERROR");
+ }
+ else
+ Send_IRCA(CD->USER, "The Skill ID Entered Is Invalid.", true, "ERROR");
+ }
+ if (_PARAMS[1] == "combatstop")
+ {
+ if (!plr->isInCombat())
+ {
+ plr->CombatStop();
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\00313[%s] : Was Dropped From Combat",_PARAMS[0].c_str()), true, CD->TYPE);
+ }else
+ {
+ Send_IRCA(CD->USER, "Specified Player Is Not In Combat.", true, "ERROR");
+ }
+ }
+ if (_PARAMS[1] == "quest")
+ {
+ std::string s_param = _PARAMS[3];
+ std::string QName = "";
+ char *args = (char*)s_param.c_str();
+ uint32 qId = 0;
+ if (args[0]=='[')
+ {
+ char* cQName = strtok((char*)args, "]");
+ if (cQName && cQName[0])
+ {
+ QName = cQName+1;
+ WorldDatabase.EscapeString(QName);
+ QueryResult result = WorldDatabase.PQuery("SELECT entry FROM quest_template WHERE name = '%s'", QName.c_str());
+ if (!result)
+ {
+ Send_IRCA(CD->USER, "Quest Not Found!", true, "ERROR");
+ return;
+ }
+ qId = result->Fetch()->GetUInt16();
+
+ }
+ }
+ else
+ {
+ qId = atoi(args);
+ QueryResult result = WorldDatabase.PQuery("SELECT title FROM quest_template WHERE entry = '%d'", qId);
+ if (!result)
+ {
+ Send_IRCA(CD->USER, "Quest Not Found!", true, "ERROR");
+ return;
+ }
+ QName = result->Fetch()->GetString();
+
+ }
+ if (_PARAMS[2] == "add")
+ {
+ QueryResult item_max = WorldDatabase.PQuery("SELECT MAX(entry) FROM item_template");
+ Quest const* pQuest = sObjectMgr->GetQuestTemplate(qId);
+ for (uint32 id = 0; id < item_max; id++)
+ {
+ ItemTemplate const *pProto = sObjectMgr->GetItemTemplate(id);
+ if (!pProto)
+ continue;
+
+ if (pProto->StartQuest == qId)
+ {
+ Send_IRCA(CD->USER, MakeMsg("This Quest Requires Activation By Item %d, Add It To The Player And Start Quest Manually.", pProto->ItemId),true, "ERROR");
+ }
+ }
+
+ if (plr->CanAddQuest(pQuest, true))
+ {
+ plr->AddQuest(pQuest, NULL);
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\00313[%s] : Had Quest [%s] Added To Quest Log.", _PARAMS[0].c_str(), QName.c_str()), true, "ERROR");
+ }
+ else
+ {
+ Send_IRCA(CD->USER, "Cannot Add Quest To Player, He Either Has No Space Or He Already Has The Quest In His Quest Log.", true, "ERROR");
+ }
+ }
+ if (_PARAMS[2] == "complete")
+ {
+ Quest const* pQuest = sObjectMgr->GetQuestTemplate(qId);
+ if (plr->GetQuestStatus(qId) == QUEST_STATUS_NONE)
+ {
+ Send_IRCA(CD->USER, "Player Does Not Have This Quest In Quest Log, Cannot Complete It.", true, "ERROR");
+ }
+ else
+ {
+ for (uint8 x = 0; x < QUEST_OBJECTIVES_COUNT; ++x)
+ {
+ uint32 id = pQuest->RequiredItemId[x];
+ uint32 count = pQuest->RequiredItemCount[x];
+ if (!id || !count)
+ continue;
+ uint32 curItemCount = plr->GetItemCount(id,true);
+ ItemPosCountVec dest;
+ uint8 msg = plr->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, id, count-curItemCount);
+ if (msg == EQUIP_ERR_OK)
+ {
+ Item* item = plr->StoreNewItem(dest, id, true);
+ plr->SendNewItem(item,count-curItemCount,true,false);
+ }
+ }
+
+ for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; i++)
+ {
+ uint32 creature = pQuest->RequiredNpcOrGo[i];
+ uint32 creaturecount = pQuest->RequiredNpcOrGoCount[i];
+ if (uint32 spell_id = pQuest->RequiredSpellCast[i])
+ {
+ for (uint16 z = 0; z < creaturecount; ++z)
+ plr->CastedCreatureOrGO(creature,0,spell_id);
+ }
+ else if (creature > 0)
+ {
+ if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature))
+ for (uint16 z = 0; z < creaturecount; ++z)
+ plr->KilledMonster(cInfo,0);
+ }
+ else if (creature < 0)
+ {
+ for (uint16 z = 0; z < creaturecount; ++z)
+ plr->CastedCreatureOrGO(creature,0,0);
+ }
+ }
+
+ if (uint32 repFaction = pQuest->GetRepObjectiveFaction())
+ {
+ uint32 repValue = pQuest->GetRepObjectiveValue();
+ uint32 curRep = plr->GetReputationMgr().GetReputation(repFaction);
+ if (curRep < repValue)
+ {
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry(repFaction);
+ plr->GetReputationMgr().SetReputation(factionEntry,repValue);
+ }
+ }
+
+ int32 ReqOrRewMoney = pQuest->GetRewOrReqMoney();
+ if (ReqOrRewMoney < 0)
+ plr->ModifyMoney(-ReqOrRewMoney);
+
+ plr->CompleteQuest(qId);
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\00313[%s] : Quest [%s] Status Set To Complete.", _PARAMS[0].c_str(), QName.c_str()), true, CD->TYPE);
+ }
+ }
+ }
+ if (_PARAMS[1] == "mod")
+ {
+ /*if (_PARAMS[2] == "rep") TODO
+ {
+ uint32 factionId = atoi((char*)_PARAMS[3].c_str());
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry(factionId);
+ if (!factionEntry)
+ {
+ Send_IRCA(CD->USER, "No Faction With That Name Exists.", true, "ERROR");
+ }
+ else
+ {
+ int32 amount = atol((char*)_PARAMS[4].c_str());
+ if (amount > -39000 && amount < 43000)
+ {
+ plr->SetFactionReputation(factionId,amount);
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\00313[%s] : Reputation With Faction %s Set To %s.", _PARAMS[0].c_str(), _PARAMS[3].c_str(), _PARAMS[4].c_str()), true, CD->TYPE);
+ }
+ else
+ {
+ Send_IRCA(CD->USER, "Reputation Value Incorrect. Must Be Between -39000 and 43000.", true, "ERROR");
+ }
+ }
+ }*/
+ if (_PARAMS[2] == "morph")
+ {
+ uint16 display_id = (uint16)atoi((char*)_PARAMS[3].c_str());
+ plr->SetDisplayId(display_id);
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\00313[%s] : Has Been Morphed Into DisplayID: %s.", _PARAMS[0].c_str(), _PARAMS[3].c_str()), true, CD->TYPE);
+ }
+ else
+ {
+ Send_IRCA(CD->USER, "Valid Parameters Are: morph <displayid>, reputation <faction><value>.", true, "ERROR");
+ }
+ }
+ }
+ else
+ Send_IRCA(CD->USER, "No Character With That Name Exists.", true, "ERROR");
+}
+
+void IRCCmd::Fun_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 3);
+ if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512)!= 0)
+ {
+ Send_IRCA(CD->USER, MakeMsg("You do not have access to do this to a higher ranked GM [%i]", AcctLevel(_PARAMS[0])), true, "ERROR");
+ return;
+ }
+ if (Player* plr = GetPlayer(_PARAMS[0]))
+ {
+ if (_PARAMS[1] == "say")
+ {
+ plr->Say(_PARAMS[2], LANG_UNIVERSAL);
+ Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Was Forced To Say: "+_PARAMS[2]+".", true, CD->TYPE);
+ }
+ if (_PARAMS[1] == "sound")
+ {
+ uint32 sndid = atoi(_PARAMS[2].c_str());
+ plr->SendPlaySound(sndid ,true);
+ Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Just Heard Sound ID: "+_PARAMS[2]+".", true, CD->TYPE);
+ }
+ }
+ else
+ Send_IRCA(CD->USER, "Player Not Online!", true, "ERROR");
+}
+
+void IRCCmd::Help_IRC(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 1);
+ QueryResult result = WorldDatabase.PQuery("SELECT `Command`, `Description`, `gmlevel` FROM `irc_commands`");
+ if (result)
+ {
+ if (IsLoggedIn(CD->USER))
+ {
+ if (_PARAMS[0] == "")
+ {
+ QueryResult result = WorldDatabase.PQuery("SELECT * FROM `irc_commands` WHERE `gmlevel` <= %u ORDER BY `Command`", GetLevel(CD->USER));
+ if (result)
+ {
+ std::string output = "\002TriniChat IRC Commands:\017 ";
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ Field *fields = result->Fetch();
+ output += fields[0].GetString() + ", ";
+ result->NextRow();
+ }
+
+ Send_IRCA(CD->USER, output, true, CD->TYPE.c_str());
+ }
+ }
+ else
+ {
+ QueryResult result = WorldDatabase.PQuery("SELECT `Description`, `gmlevel` FROM `irc_commands` WHERE `Command` = '%s'", _PARAMS[0].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ if (fields[1].GetUInt32() > GetLevel(CD->USER))
+ {
+ Send_IRCA(CD->USER, "You Do Not Have Access To That Command, So No Help Is Available.", true, CD->TYPE.c_str());
+ return;
+ }
+ if (result)
+ {
+ std::string cmdhlp = fields[0].GetString();
+
+ Send_IRCA(CD->USER, cmdhlp, true, CD->TYPE.c_str());
+ }
+ }
+ else
+ Send_IRCA(CD->USER, "No Such Command Exists, Please Check The Spelling And Try Again.", true, "ERROR");
+ }
+ }
+ else if (!IsLoggedIn(CD->USER))
+ {
+ if (_PARAMS[0] == "")
+ {
+ QueryResult result = WorldDatabase.PQuery("SELECT * FROM `irc_commands` WHERE `gmlevel` = 0 ORDER BY `Command`");
+ if (result)
+ {
+ std::string output = "\002TriniChat IRC Commands:\017 ";
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ Field *fields = result->Fetch();
+ output += fields[0].GetString() + ", ";
+ result->NextRow();
+ }
+
+ Send_IRCA(CD->USER, output, true, CD->TYPE.c_str());
+ Send_IRCA(CD->USER, "You Are Currently Not Logged In, Please Login To See A Complete List Of Commands Available To You.", true, CD->TYPE.c_str());
+ }
+ }
+ else
+ {
+ QueryResult result = WorldDatabase.PQuery("SELECT `Description`, `gmlevel` FROM `irc_commands` WHERE `Command` = '%s'", _PARAMS[0].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ if (fields[1].GetUInt32() > 0)
+ {
+ Send_IRCA(CD->USER, "You Do Not Have Access To That Command, So No Help Is Available.", true, CD->TYPE.c_str());
+ return;
+ }
+ std::string cmdhlp = fields[0].GetString();
+
+ Send_IRCA(CD->USER, cmdhlp, true, CD->TYPE.c_str());
+ }
+ else
+ Send_IRCA(CD->USER, "No Such Command Exists, Please Check The Spelling And Try Again.", true, "ERROR");
+ }
+ }
+ }
+ else
+ Send_IRCA(CD->USER, "Database Error! Please Make Sure You Used irc_commands.sql, You Must Have A Table In Your World Database (irc_commands)!", true, "ERROR");
+}
+
+void IRCCmd::Inchan_Server(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 1);
+ if (_PARAMS[0] == "")
+ {
+ Send_IRCA(CD->USER, "Syntax Error! ("+sIRC._cmd_prefx+"inchan <ChannelName>)", true, "ERROR");
+ return;
+ }
+ QueryResult result = WorldDatabase.PQuery("SELECT * FROM `irc_inchan` WHERE `channel` = '%s' ORDER BY `name`", _PARAMS[0].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ std::string output = "\0031Players In The \xF["+fields[2].GetString()+"] \0031Channel:\017 ";
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ output += fields[1].GetString() + ", ";
+ result->NextRow();
+ }
+
+ Send_IRCA(ChanOrPM(CD), output, true, CD->TYPE);
+ }
+ else
+ Send_IRCA(ChanOrPM(CD), "\0031No Players Are Currently In \xF["+_PARAMS[0]+"] \0031Channel!", true, CD->TYPE.c_str());
+}
+
+void IRCCmd::Info_Server(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 1);
+ char clientsNum [50];
+ sprintf(clientsNum, "%u", sWorld->GetActiveSessionCount());
+ char maxClientsNum [50];
+ sprintf(maxClientsNum, "%u", sWorld->GetMaxActiveSessionCount());
+ char ircupdt [50];
+ sprintf(ircupdt, "%u", sWorld->GetUpdateTime());
+ std::string str = secsToTimeString(sWorld->GetUptime());
+ std::string svnrev = _FULLVERSION;
+
+ float rdm = (ConfigMgr::GetFloatDefault("Rate.Drop.Money", 1.0f));
+ float rxk = (ConfigMgr::GetFloatDefault("Rate.XP.Kill", 1.0f));
+ float rxq = (ConfigMgr::GetFloatDefault("Rate.XP.Quest", 1.0f));
+ Send_IRCA(ChanOrPM(CD), "\00310Number Of Players Online: \xF"+(std::string)clientsNum+" | \00310Max Since Last Restart: \xF"+(std::string)maxClientsNum+" |\00310 UpTime: \xF"+str, true, CD->TYPE);
+ Send_IRCA(ChanOrPM(CD), "\00310Server: \xF"+svnrev+" |\00310 Update Time: \xF"+(std::string)ircupdt, true, CD->TYPE);
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\00310Server Rates - \xF[Monster XP: %u][Quest XP: %u][Money Drop Rate: %u]", int(rxk), int(rxq), int(rdm)), true, CD->TYPE);
+ Send_IRCA(ChanOrPM(CD), "\00310MotD: \xF"+(std::string)sWorld->GetMotd(), true, CD->TYPE);
+
+}
+
+void IRCCmd::Item_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 3);
+
+ normalizePlayerName(_PARAMS[0]);
+ Player *chr = GetPlayer(_PARAMS[0].c_str());
+ if (_PARAMS[1] == "add")
+ {
+ std::string s_param = _PARAMS[2];
+
+ char *args = (char*)s_param.c_str();
+ uint32 itemId = 0;
+ if (args[0]=='[')
+ {
+ char* citemName = strtok((char*)args, "]");
+ if (citemName && citemName[0])
+ {
+ std::string itemName = citemName+1;
+ WorldDatabase.EscapeString(itemName);
+ QueryResult result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
+ if (!result)
+ {
+ Send_IRCA(CD->USER, "Item Not Found!", true, "ERROR");
+ return;
+ }
+ itemId = result->Fetch()->GetUInt16();
+
+ }
+ else
+ {
+ Send_IRCA(CD->USER, "Syntax Error! ("+sIRC._cmd_prefx+"item <Player> <add> [Exact Item Name] <Amount>)", true, "ERROR");
+ return;
+ }
+ }
+ else
+ {
+ std::string itemName = s_param;
+ WorldDatabase.EscapeString(itemName);
+ QueryResult result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
+ if (result)
+ {
+ itemId = result->Fetch()->GetUInt16();
+ }
+
+
+ char* cId = strtok(args, " ");
+ if (!cId)
+ {
+ Send_IRCA(CD->USER, "Syntax Error! ("+sIRC._cmd_prefx+"item <Player> <add> <ItemID> <Amount>)", true, "ERROR");
+ return;
+ }
+ itemId = atol(cId);
+ }
+ char* ccount = strtok(NULL, " ");
+ int32 count = 1;
+ if (ccount) { count = atol(ccount); }
+ Player* plTarget = chr;
+ if (!plTarget)
+ {
+ Send_IRCA(CD->USER, ""+_PARAMS[0]+" Is Not Online!", true, "ERROR");
+ return;
+ }
+ ItemTemplate const *pProto = sObjectMgr->GetItemTemplate(itemId);
+ //Subtract
+ if (count < 0)
+ {
+ plTarget->DestroyItemCount(itemId, -count, true, false);
+ char itemid2[255];
+ sprintf(itemid2,"%d",itemId);
+ std::string itake = " \00313["+ _PARAMS[0] +"] :\0031Has Had Item \xF" +itemid2+ " \0031Taken From Them!";
+ Send_IRCA(ChanOrPM(CD), itake, true, CD->TYPE);
+ return;
+ }
+ //Adding items
+ uint32 noSpaceForCount = 0;
+
+ // check space and find places
+ ItemPosCountVec dest;
+ uint8 msg = plTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount);
+ if (msg == EQUIP_ERR_INVENTORY_FULL) // convert to possibel store amount
+ count -= noSpaceForCount;
+ else if (msg != EQUIP_ERR_OK) // other error, can't add
+ {
+ char s_countForStore[255];
+ sprintf(s_countForStore,"%d",count);
+ std::string ierror = " \00313["+ _PARAMS[0] +"] : Could Not Create All Items! " +s_countForStore+ " Item(s) Were Not Created!";
+ Send_IRCA(ChanOrPM(CD), ierror, true, CD->TYPE);
+ return;
+ }
+ Item* item = plTarget->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
+ if (count > 0 && item)
+ {
+ plTarget->SendNewItem(item,count,true,false);
+ QueryResult result = WorldDatabase.PQuery("SELECT name FROM item_template WHERE entry = %d", itemId);
+ char* dbitemname = NULL;
+ if (result)
+ {
+ dbitemname = (char*)result->Fetch()->GetCString();
+ }
+ std::string iinfo = " \00313[" + _PARAMS[0] + "] : Has Been Given Item "+dbitemname+". From: "+CD->USER.c_str()+".";
+ Send_IRCA(ChanOrPM(CD), iinfo, true, CD->TYPE);
+
+ }
+ if (noSpaceForCount > 0)
+ {
+ char s_countForStore[255];
+ sprintf(s_countForStore,"%d",noSpaceForCount);
+ std::string ierror = " \00313["+ _PARAMS[0] +"] : Could Not Create All Items! " +s_countForStore+ " Item(s) Were Not Created!";
+ Send_IRCA(ChanOrPM(CD), ierror, true, CD->TYPE);
+ return;
+ }
+ }
+ else
+ {
+ Send_IRCA(CD->USER, "Syntax Error! ("+sIRC._cmd_prefx+"item <Player> <add> <ItemID> <Amount>)", true, "ERROR");
+ return;
+ }
+}
+
+void IRCCmd::Jail_Player(_CDATA *CD)
+{
+ if (ValidParams(CD->PARAMS, 1))
+ {
+ std::string* _PARAMS = getArray(CD->PARAMS, 2);
+ if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512)!= 0)
+ {
+ Send_IRCA(CD->USER, MakeMsg("You do not have access to do this to a higher ranked GM [%i]", AcctLevel(_PARAMS[0])), true, "ERROR");
+ return;
+ }
+ if (Player *plr = GetPlayer(_PARAMS[0]))
+ {
+ std::string sReason = "";
+ if (_PARAMS[1] == "release")
+ {
+ float rposx, rposy, rposz, rposo = 0;
+ uint32 rmapid = 0;
+ CharacterDatabase.EscapeString(_PARAMS[0]);
+ QueryResult result = CharacterDatabase.PQuery("SELECT `map`, `position_x`, `position_y`, `position_z` FROM `character_homebind` WHERE `guid` = '" UI64FMTD "'", plr->GetGUID());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ rmapid = fields[0].GetUInt16();
+ rposx = fields[1].GetFloat();
+ rposy = fields[2].GetFloat();
+ rposz = fields[3].GetFloat();
+
+ plr->SetMovement(MOVE_UNROOT);
+ plr->TeleportTo(rmapid, rposx, rposy, rposz, rposo);
+ plr->RemoveAurasDueToSpell(42201);
+ plr->RemoveAurasDueToSpell(23775);
+ plr->RemoveAurasDueToSpell(9454);
+ Send_Player(plr, MakeMsg("You Have Been Released By: %s.", CD->USER.c_str()));
+ sReason = " \00313["+_PARAMS[0]+"] : Has Been Released By: "+CD->USER+".";
+ Send_IRCA(ChanOrPM(CD), sReason, true, CD->TYPE);
+ }
+ }
+ else
+ {
+ if (_PARAMS[1] == "")
+ _PARAMS[1] = "No Reason Given.";
+ plr->TeleportTo(13, 0, 0, 0, 0);
+ plr->SetMovement(MOVE_ROOT);
+ plr->CastSpell(plr, 42201, true);
+ plr->CastSpell(plr, 23775, true);
+ plr->CastSpell(plr, 9454, true);
+ Send_Player(plr, MakeMsg("You Have Been Jailed By: %s. Reason: %s.", CD->USER.c_str(), _PARAMS[1].c_str()));
+ sReason = " \00313["+_PARAMS[0]+"] : Has Been Jailed By: "+CD->USER+". Reason: "+_PARAMS[1]+".";
+ Send_IRCA(ChanOrPM(CD), sReason, true, CD->TYPE);
+ }
+ }
+ else
+ Send_IRCA(CD->USER, ""+_PARAMS[0]+" Is Not Online!", true, "ERROR");
+ }
+}
+
+void IRCCmd::Kick_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, CD->PCOUNT);
+ if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512)!= 0)
+ {
+ Send_IRCA(CD->USER, MakeMsg("You do not have access to do this to a higher ranked GM [%i]", AcctLevel(_PARAMS[0])), true, "ERROR");
+ return;
+ }
+ if (_PARAMS[1] == "")
+ _PARAMS[1] = "No Reason Given.";
+ if (Player* plr = GetPlayer(_PARAMS[0]))
+ {
+ plr->GetSession()->KickPlayer();
+ Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Been Kicked By: "+CD->USER+". Reason: "+_PARAMS[1]+".", true, CD->TYPE);
+ if (sWorld->getBoolConfig(CONFIG_SHOW_KICK_IN_WORLD))
+ sIRC.Send_WoW_System("Player|cffff0000 "+_PARAMS[0]+"|r kicked by|cffff0000 "+CD->USER+"|r. Reason:|cffff0000"+_PARAMS[1]+"|r.");
+ }
+ else
+ Send_IRCA(CD->USER, ""+_PARAMS[0]+" Is Not Online!", true, "ERROR");
+}
+
+void IRCCmd::Kill_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, CD->PCOUNT);
+ if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512)!= 0)
+ {
+ Send_IRCA(CD->USER, MakeMsg("You do not have access to do this to a higher ranked GM [%i]", AcctLevel(_PARAMS[0])), true, "ERROR");
+ return;
+ }
+ if (Player* plr = GetPlayer(_PARAMS[0]))
+ {
+ if (plr->isAlive())
+ {
+ plr->DealDamage(plr, plr->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ plr->SaveToDB();
+ if (_PARAMS[1] == "")
+ _PARAMS[1] = "No Reason Given.";
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\00313[%s] : Has Been Killed By: %s.", _PARAMS[0].c_str(), CD->USER.c_str()) + + + " Reason: "+_PARAMS[1]+".", true, CD->TYPE);
+ Send_Player(plr, MakeMsg("You Have Been Killed By: %s. Reason: %s.", CD->USER.c_str(), _PARAMS[1].c_str()));
+ }
+ else
+ Send_IRCA(CD->USER, ""+_PARAMS[0]+" Is Already Dead!", true, "ERROR");
+ }
+ else
+ Send_IRCA(CD->USER, ""+_PARAMS[0]+" Is Not Online!", true, "ERROR");
+}
+
+void IRCCmd::Player_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, CD->PCOUNT);
+ uint32 plguid = atoi(_PARAMS[0].c_str());
+ if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512)!= 0)
+ {
+ Send_IRCA(CD->USER, MakeMsg("You do not have access to do this to a higher ranked GM [%i]", AcctLevel(_PARAMS[0])), true, "ERROR");
+ return;
+ }
+ if (sObjectMgr->GetPlayerGUIDByName(_PARAMS[0].c_str()))
+ plguid = sObjectMgr->GetPlayerGUIDByName(_PARAMS[0].c_str());
+ if (plguid > 0)
+ {
+ QueryResult result = CharacterDatabase.PQuery("SELECT guid, account, name, race, class, online, SUBSTRING_INDEX(SUBSTRING_INDEX(`level`, ' ' , 35), ' ' , -1) AS level, SUBSTRING_INDEX(SUBSTRING_INDEX(`xp`, ' ' , 927), ' ' , -1) AS xp, SUBSTRING_INDEX(SUBSTRING_INDEX(money, ' ' , 1462), ' ' , -1) AS gold, SUBSTRING_INDEX(SUBSTRING_INDEX(`totalHonorPoints`, ' ' , 1454), ' ' , -1) AS Honor, totaltime FROM characters WHERE guid =%i", plguid);
+ uint32 latency = 0;
+ Player *chr = ObjectAccessor::FindPlayer(plguid);
+ if (chr)
+ {
+ latency = chr->GetSession()->GetLatency();
+ }
+ char templatency [100];
+ sprintf(templatency, "%ums", latency);
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ std::string pguid = fields[0].GetString();
+ std::string pacct = fields[1].GetString();
+ std::string pname = fields[2].GetString();
+ uint32 praceid = fields[3].GetUInt32();
+ uint32 pclassid = fields[4].GetUInt32();
+ std::string ponline = (fields[5].GetInt32() == 1 ? "\x3\x30\x33Online" : "\x3\x30\x34Offline\xF");
+ std::string plevel = fields[6].GetString();
+ std::string pxp = fields[7].GetString();
+ unsigned int money = fields[8].GetInt32();
+ std::string honor = fields[9].GetString();
+ std::string totaltim = SecToDay(fields[10].GetString());
+
+ std::string sqlquery = "SELECT `gmlevel` FROM `account_access` WHERE `id` = '" + pacct + "';";
+ QueryResult gmresult = LoginDatabase.Query(sqlquery.c_str());
+ std::string pgmlvl = "0";
+ if (gmresult)
+ {
+ Field *fields2 = gmresult->Fetch();
+ pgmlvl = fields2[0].GetString();
+ }
+
+ ChrRacesEntry const* prace = sChrRacesStore.LookupEntry(praceid);
+ ChrClassesEntry const* pclass = sChrClassesStore.LookupEntry(pclassid);
+
+ if (atoi(plevel.c_str()) < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
+ plevel += " (" + pxp + ")";
+ 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 * plr = sObjectAccessor->FindPlayerByName(pname.c_str());
+ if (plr)
+ {
+ AreaTableEntry const* area = GetAreaEntryByAreaID(plr->GetAreaId());
+ ponline += " in " + (std::string) area->area_name[sWorld->GetDefaultDbcLocale()];
+ if (area->zone != 0)
+ {
+ AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone);
+ ponline += " (" + (std::string)zone->area_name[sWorld->GetDefaultDbcLocale()] + ")";
+ }
+ }
+ }
+ std::string pinfo = "\00310About Player: \xF"+pname+" |\00310 GM Level: \xF"+pgmlvl+" |\00310 AcctID: \xF"+pacct+" |\00310 CharID: \xF"+pguid+" |\00310 Played Time: \xF"+totaltim.c_str()+" |\00310 Latency: \xF"+templatency;
+ std::string pinfo2 = "\00310Race: \xF"+(std::string)prace->name[sWorld->GetDefaultDbcLocale()]+" |\00310 Class: \xF"+(std::string)pclass->name[sWorld->GetDefaultDbcLocale()]+" |\00310 Level: \xF"+plevel+" |\00310 Money: \xF"+tempgold+"|\00310 Status: \xF"+ponline+" |\00310 Honor: \xF"+honor;
+ // pinfo3 = " :" + " \x2Honor Kills:\x2\x3\x31\x30 " + hk;
+ Send_IRCA(ChanOrPM(CD),pinfo , true, CD->TYPE);
+ Send_IRCA(ChanOrPM(CD),pinfo2 , true, CD->TYPE);
+ // Send_IRCA(ChanOrPM(CD),pinfo3 , true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown Character ID. (GUID)" ,true, "ERROR");
+ }
+ else
+ {
+ QueryResult result = CharacterDatabase.PQuery("SELECT guid, account, name FROM characters WHERE name LIKE '%%%s%%' LIMIT 10", _PARAMS[0].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ std::string items = "\x2 Character Search Results:\x3\x31\x30 ";
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ std::string guid = fields[0].GetString();
+ std::string account = fields[1].GetString();
+ std::string name = fields[2].GetString();
+ MakeUpper(name);
+ items.append(name+"(Account:"+account+" - GUID:"+guid+")\0031 | \xF");
+ result->NextRow();
+ }
+
+ Send_IRCA(ChanOrPM(CD), items, true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown Character. I Cant Find Any Characters With Those Search Terms." ,true, "ERROR");
+ }
+
+}
+
+void IRCCmd::Lookup_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, CD->PCOUNT);
+ if (_PARAMS[0] == "acct")
+ {
+ uint32 acctid = atoi(_PARAMS[1].c_str());
+ if (AccountMgr::GetId(_PARAMS[1]))
+ acctid = AccountMgr::GetId(_PARAMS[1]);
+ if (acctid > 0)
+ {
+ std::string DateTime = "%a, %b %d, %Y - %h:%i%p";
+ QueryResult result = LoginDatabase.PQuery("SELECT `account`.`id`, username, last_ip, (SELECT banreason FROM account_banned WHERE `account`.`id` = id LIMIT 1) as banned, (SELECT banreason FROM ip_banned WHERE ip = last_ip) as bannedip,(SELECT active FROM account_banned WHERE `account`.`id` = id) as banactive, (SELECT( unbandate - unix_timestamp( now() ) ) FROM account_banned WHERE `account`.`id` = id) as remainingtime, DATE_FORMAT(last_login, '%s') FROM `account` WHERE `account`.`id` =%d" ,DateTime.c_str(), acctid);
+ if (result)
+ {
+ Field *fields = result->Fetch();
+
+ uint32 id = fields[0].GetUInt32();
+ std::string usrname = fields[1].GetString();
+ std::string lastip = fields[2].GetString();
+ std::string banreason = fields[3].GetString();
+ std::string banreasonip = fields[4].GetString();
+ uint32 banactive = (fields[5].GetInt32() == 1 ? 1 : 0);
+ std::string TimeLeft = SecToDay(fields[6].GetString());
+ std::string lastlogin = fields[7].GetString();
+
+ QueryResult chars = CharacterDatabase.PQuery("SELECT guid, name, (SELECT SUM(totaltime) FROM characters WHERE account = %d) AS tottime FROM characters WHERE account = %u", id, id);
+ std::string characters = "None";
+ std::string totaccttime = "Never Logged In";
+ if (chars)
+ {
+ characters = "";
+ Field *fields = chars->Fetch();
+ totaccttime = SecToDay(fields[2].GetString());
+ for (uint64 i=0; i < chars->GetRowCount(); i++)
+ {
+ std::string guid = fields[0].GetString();
+ std::string charname = fields[1].GetString();
+ characters.append(charname+"("+guid+"), ");
+ chars->NextRow();
+ }
+
+ }
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\00310Username: \xF %s | \00310AccountID: \xF %d | \00310Last IP: \xF %s | \00310Last Login: \xF %s", usrname.c_str(), id, lastip.c_str(), lastlogin.c_str()), true, CD->TYPE);
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\00310Total play time: \xF %s | \00310Characters: \xF %s ", totaccttime.c_str(), characters.c_str()), true, CD->TYPE);
+ if (banreason.length() > 1)
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\0035Account banned : \xF %s | \0035Ban Active: \xF %u | \0035Ban Time: \xF %s", banreason.c_str(), banactive, TimeLeft.c_str()), true, CD->TYPE);
+ if (banreasonip.length() > 1)
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\0034This User Has An IP Ban. Ban Reason: %s", banreasonip.c_str()), true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown Account ID." ,true, "ERROR");
+ }
+ else
+ {
+ QueryResult result = LoginDatabase.PQuery("SELECT id, username FROM `account` WHERE username LIKE '%%%s%%' LIMIT 10", _PARAMS[1].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ std::string accts = "\002Account Search Results:\x3\x31\x30 ";
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ std::string acctid = fields[0].GetString();
+ std::string acctname = fields[1].GetString();
+ accts.append(acctname+"("+acctid+")\xF | \x3\x31\x30\x2");
+ result->NextRow();
+ }
+
+ Send_IRCA(ChanOrPM(CD), accts, true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown Username. I Cant Find Any Users With Those Search Terms." ,true, "ERROR");
+ }
+ }
+ if (_PARAMS[0] == "char")
+ {
+ uint32 plguid = atoi(_PARAMS[1].c_str());
+ if (sObjectMgr->GetPlayerGUIDByName(_PARAMS[1].c_str()))
+ plguid = sObjectMgr->GetPlayerGUIDByName(_PARAMS[1].c_str());
+ if (plguid > 0)
+ {
+ QueryResult result = CharacterDatabase.PQuery("SELECT guid, account, name, race, class, online, SUBSTRING_INDEX(SUBSTRING_INDEX(`level`, ' ' , 35), ' ' , -1) AS level, SUBSTRING_INDEX(SUBSTRING_INDEX(`xp`, ' ' , 927), ' ' , -1) AS xp, SUBSTRING_INDEX(SUBSTRING_INDEX(money, ' ' , 1462), ' ' , -1) AS gold, SUBSTRING_INDEX(SUBSTRING_INDEX(`totalHonorPoints`, ' ' , 1454), ' ' , -1) AS Honor, totaltime FROM characters WHERE guid =%i", plguid);
+ uint32 latency = 0;
+ Player *chr = ObjectAccessor::FindPlayer(plguid);
+ if (chr)
+ {
+ latency = chr->GetSession()->GetLatency();
+ }
+ char templatency [100];
+ sprintf(templatency, "%ums", latency);
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ std::string pguid = fields[0].GetString();
+ std::string pacct = fields[1].GetString();
+ std::string pname = fields[2].GetString();
+ uint32 praceid = fields[3].GetUInt32();
+ uint32 pclassid = fields[4].GetUInt32();
+ std::string ponline = (fields[5].GetInt32() == 1 ? "\x3\x30\x33Online" : "\x3\x30\x34Offline\xF");
+ std::string plevel = fields[6].GetString();
+ std::string pxp = fields[7].GetString();
+ unsigned int money = fields[8].GetInt32();
+ std::string honor = fields[9].GetString();
+ std::string totaltim = SecToDay(fields[10].GetString());
+
+ std::string sqlquery = "SELECT `gmlevel` FROM `account_access` WHERE `id` = '" + pacct + "';";
+ QueryResult gmresult = LoginDatabase.Query(sqlquery.c_str());
+ std::string pgmlvl = "0";
+ if (gmresult)
+ {
+ Field *fields = result->Fetch();
+ pgmlvl = fields[0].GetString();
+ }
+
+ ChrRacesEntry const* prace = sChrRacesStore.LookupEntry(praceid);
+ ChrClassesEntry const* pclass = sChrClassesStore.LookupEntry(pclassid);
+
+ if (atoi(plevel.c_str()) < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
+ plevel += " (" + pxp + ")";
+ 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 * plr = sObjectAccessor->FindPlayerByName(pname.c_str());
+ if (plr)
+ {
+ AreaTableEntry const* area = GetAreaEntryByAreaID(plr->GetAreaId());
+ ponline += " in " + (std::string) area->area_name[sWorld->GetDefaultDbcLocale()];
+ if (area->zone != 0)
+ {
+ AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone);
+ ponline += " (" + (std::string)zone->area_name[sWorld->GetDefaultDbcLocale()] + ")";
+ }
+ }
+ }
+ std::string pinfo = "\x2 About Player:\x3\x31\x30 " +pname+ "\xF |\x2 GM Level:\x3\x31\x30 " +pgmlvl+ "\xF |\x2 AcctID:\x3\x31\x30 " +pacct+ "\xF |\x2 CharID:\x3\x31\x30 " +pguid+ " \xF |\x2 Played Time:\x2\x3\x31\x30 " +totaltim.c_str()+" \xF |\x2 Latency:\x2\x3\x31\x30 "+templatency;
+ std::string pinfo2 = "\x2 Race:\x2\x3\x31\x30 " + (std::string)prace->name[sWorld->GetDefaultDbcLocale()] + "\xF |\x2 Class:\x2\x3\x31\x30 " + (std::string)pclass->name[sWorld->GetDefaultDbcLocale()] + "\xF |\x2 Level:\x2\x3\x31\x30 " + plevel + "\xF |\x2 Money:\x2 " + tempgold + "\xF |\x2 Status:\x2 " + ponline;
+ // pinfo3 = " :" + " \x2Honor Kills:\x2\x3\x31\x30 " + hk;
+ Send_IRCA(ChanOrPM(CD),pinfo , true, CD->TYPE);
+ Send_IRCA(ChanOrPM(CD),pinfo2 , true, CD->TYPE);
+ // Send_IRCA(ChanOrPM(CD),pinfo3 , true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown Character ID. (GUID)" ,true, "ERROR");
+ }
+ else
+ {
+ QueryResult result = CharacterDatabase.PQuery("SELECT guid, account, name FROM characters WHERE name LIKE '%%%s%%' LIMIT 10", _PARAMS[1].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ std::string items = "\x2 Character Search Results:\x3\x31\x30 ";
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ std::string guid = fields[0].GetString();
+ std::string account = fields[1].GetString();
+ std::string name = fields[2].GetString();
+ MakeUpper(name);
+ items.append(name+"(Account:"+account+" - GUID:"+guid+")\xF | \x3\x31\x30\x2");
+ result->NextRow();
+ }
+
+ Send_IRCA(ChanOrPM(CD), items, true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown Character. I Cant Find Any Characters With Those Search Terms." ,true, "ERROR");
+ }
+ }
+ if (_PARAMS[0] == "creature")
+ {
+ std::string creature = _PARAMS[1];
+ if (atoi(creature.c_str()) > 0)
+ {
+ WorldDatabase.EscapeString(_PARAMS[1]);
+ QueryResult result = WorldDatabase.PQuery("SELECT entry, name, minlevel,maxlevel, faction_A, (SELECT count(guid) FROM creature WHERE id = '%s') as spawns FROM creature_template WHERE entry = '%s';", _PARAMS[1].c_str(), _PARAMS[1].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+
+ uint32 entry = fields[0].GetUInt32();
+ std::string name = fields[1].GetString();
+ uint32 minlevel = fields[2].GetUInt32();
+ uint32 maxlevel = fields[3].GetUInt32();
+ uint32 faction = fields[4].GetUInt32();
+ uint32 spawns = fields[5].GetUInt32();
+
+
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\x2Name:\x3\x31\x30 %s \xF|\x2 CreatureID:\x3\x31\x30 %d", name.c_str(), entry), true, CD->TYPE);
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\x2minlevel:\x3\x31\x30 %d \xF|\x2 maxlevel:\x3\x31\x30 %d \xF|\x2 Faction:\x3\x31\x30 %d \xF|\x2 Spawns:\x3\x31\x30 %d", minlevel, maxlevel, faction, spawns), true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown Creature ID." ,true, "ERROR");
+ }
+ else
+ {
+ QueryResult result = WorldDatabase.PQuery("SELECT entry, name FROM creature_template WHERE name LIKE '%%%s%%' LIMIT 10", _PARAMS[1].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ std::string items = "\002Creature Search Results:\x3\x31\x30 ";
+ //Send_IRCA(ChanOrPM(CD), "", true, CD->TYPE);
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ std::string CreatureID = fields[0].GetString();
+ std::string Name = fields[1].GetString();
+ items.append(Name+"("+CreatureID+")\xF | \x3\x31\x30\x2");
+ result->NextRow();
+ }
+
+ Send_IRCA(ChanOrPM(CD), items, true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown Creature. I Cant Find Any Creatures With Those Search Terms." ,true, "ERROR");
+ }
+ }
+ if (_PARAMS[0] == "faction")
+ {
+ std::string faction = _PARAMS[1];
+ if (atoi(faction.c_str()) > 0)
+ {
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry(atoi(faction.c_str()));
+ if (factionEntry)
+ {
+ std::string name = factionEntry->name[sWorld->GetDefaultDbcLocale()];
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\x2 Faction:\x3\x31\x30 %s \xF|\x2 FactionID:\x3\x31\x30 %s",name.c_str(), faction.c_str()), true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown FactionID." ,true, "ERROR");
+
+ }
+ else
+ {
+ uint32 counter = 0;
+ std::string factions = "\002Faction Search Results:\x3\x31\x30 ";
+ for (uint32 id = 0; id < sFactionStore.GetNumRows(); id++)
+ {
+ FactionEntry const *factionEntry = sFactionStore.LookupEntry(id);
+ if (factionEntry)
+ {
+ MakeLower(_PARAMS[1]);
+ std::string name = factionEntry->name[sWorld->GetDefaultDbcLocale()];
+ MakeLower(name);
+ if (name.find(_PARAMS[1]) != std::string::npos && counter < 10)
+ {
+ char factionid[100];
+ sprintf(factionid, "%d", id);
+ factions.append(name+"("+factionid+")\xF | \x3\x31\x30\x2");
+ ++counter;
+ }
+ }
+ }
+ if (counter == 0)
+ factions.append("No Factions Found.");
+ Send_IRCA(ChanOrPM(CD), factions, true, CD->TYPE);
+ }
+ }
+ if (_PARAMS[0] == "go")
+ {
+ std::string gobject = _PARAMS[1];
+ if (atoi(gobject.c_str()) > 0)
+ {
+ WorldDatabase.EscapeString(_PARAMS[1]);
+ QueryResult result = WorldDatabase.PQuery("SELECT entry, type, displayId, name, faction, (SELECT count(*) FROM gameobject WHERE id = '%s') as spawns FROM gameobject_template WHERE entry = '%s';", _PARAMS[1].c_str(), _PARAMS[1].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+
+ uint32 entry = fields[0].GetUInt32();
+ uint32 type = fields[1].GetUInt32();
+ uint32 modelid = fields[2].GetUInt32();
+ std::string name = fields[3].GetString();
+ uint32 faction = fields[4].GetUInt32();
+ uint32 spawns = fields[5].GetUInt32();
+
+
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\x2GO Name:\x3\x31\x30 %s \xF|\x2 GameobjectID:\x3\x31\x30 %d \xF|\x2 DisplayID:\x3\x31\x30 %d \xF|\x2 Spawns:\x3\x31\x30 %d", name.c_str(), entry, modelid, spawns), true, CD->TYPE);
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\x2Type:\x3\x31\x30 %d \xF|\x2 Faction:\x3\x31\x30 %d", type, faction), true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown GameObject ID." ,true, "ERROR");
+ }
+ else
+ {
+ QueryResult result = WorldDatabase.PQuery("SELECT entry, name FROM gameobject_template WHERE name LIKE '%%%s%%' LIMIT 10", _PARAMS[1].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ std::string gos = "\002Gameobject Search Results:\x3\x31\x30 ";
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ std::string GOID = fields[0].GetString();
+ std::string GoName = fields[1].GetString();
+ gos.append(GoName+"("+GOID+")\xF | \x3\x31\x30\x2");
+ result->NextRow();
+ }
+
+ Send_IRCA(ChanOrPM(CD), gos, true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown Game Object. I Cant Find Any Game Object's With Those Search Terms." ,true, "ERROR");
+ }
+ }
+ if (_PARAMS[0] == "item")
+ {
+ std::string item = _PARAMS[1];
+ if (atoi(item.c_str()) > 0)
+ {
+ QueryResult result = WorldDatabase.PQuery("SELECT entry, name, displayid, (SELECT count(*) FROM creature_loot_template WHERE item = '%s') as loot FROM `item_template` WHERE entry = %s", _PARAMS[1].c_str(), _PARAMS[1].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ QueryResult result2 = CharacterDatabase.PQuery("SELECT count(*) FROM `character_inventory` WHERE item_template = %s", _PARAMS[1].c_str());
+ Field *fields2 = result2->Fetch();
+ uint32 charcnt = fields2[0].GetUInt32();
+
+
+ uint32 ItemID = fields[0].GetUInt32();
+ std::string ItmName = fields[1].GetString();
+ uint32 DisplayID = fields[2].GetUInt32();
+ uint32 loots = 0;
+ loots = fields[3].GetUInt32();
+
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\x2Item:\x3\x31\x30 %s \xF|\x2 ItemID:\x3\x31\x30 %d \xF|\x2 DisplayID:\x3\x31\x30 %d \xF|\x2 Owned By:\x3\x31\x30 %d players \xF|\x2 Dropped By:\x3\x31\x30 %d creatures", ItmName.c_str(), ItemID, DisplayID, charcnt, loots), true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown ItemID." ,true, "ERROR");
+ }
+ else
+ {
+ QueryResult result = WorldDatabase.PQuery("SELECT entry, name FROM `item_template` WHERE name LIKE '%%%s%%' LIMIT 10", _PARAMS[1].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ std::string items = "\002Item Search Results:\x3\x31\x30 ";
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ std::string ItemID = fields[0].GetString();
+ std::string ItemName = fields[1].GetString();
+ items.append(ItemName+"("+ItemID+")\xF | \x3\x31\x30\x2");
+ result->NextRow();
+ }
+
+ Send_IRCA(ChanOrPM(CD), items, true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown Item. I Cant Find Any Items With Those Search Terms." ,true, "ERROR");
+ }
+ }
+ if (_PARAMS[0] == "quest")
+ {
+ std::string quest = _PARAMS[1];
+ if (atoi(quest.c_str()) > 0)
+ {
+ WorldDatabase.EscapeString(_PARAMS[1]);
+ QueryResult result = WorldDatabase.PQuery("SELECT entry, Title FROM quest_template WHERE entry = '%s';", _PARAMS[1].c_str(), _PARAMS[1].c_str());
+ if (result)
+ {
+ QueryResult result2 = CharacterDatabase.PQuery("SELECT count(*) FROM character_queststatus WHERE quest = '%s' AND status = '1';", _PARAMS[1].c_str());
+ Field *fields2 = result2->Fetch();
+ uint32 status = fields2[0].GetUInt32();
+
+
+ Field *fields = result->Fetch();
+ uint32 entry = fields[0].GetUInt32();
+ std::string name = fields[1].GetString();
+
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\x2Quest Name:\x3\x31\x30 %s \xF|\x2 QuestID:\x3\x31\x30 %d \xF|\x2 Completed:\x3\x31\x30 %d times", name.c_str(), entry, status), true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown Quest ID." ,true, "ERROR");
+ }
+ else
+ {
+ QueryResult result = WorldDatabase.PQuery("SELECT entry, Title FROM quest_template WHERE Title LIKE '%%%s%%' LIMIT 10", _PARAMS[1].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ std::string quests = "\002Quest Search Results:\x3\x31\x30 ";
+ //Send_IRCA(ChanOrPM(CD), "", true, CD->TYPE);
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ std::string QuestID = fields[0].GetString();
+ std::string QuestName = fields[1].GetString();
+ quests.append(QuestName+"("+QuestID+")\xF | \x3\x31\x30\x2");
+ result->NextRow();
+ }
+
+ Send_IRCA(ChanOrPM(CD), quests, true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown Quest. I Cant Find Any Quest's With Those Search Terms." ,true, "ERROR");
+ }
+ }
+ if (_PARAMS[0] == "skill")
+ {
+ std::string skill = _PARAMS[1];
+ if (atoi(skill.c_str()) > 0)
+ {
+ SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(atoi(skill.c_str()));
+ if (skillInfo)
+ {
+ std::string name = skillInfo->name[sWorld->GetDefaultDbcLocale()];
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\x2Skill:\x3\x31\x30 %s \xF|\x2 SkillID:\x3\x31\x30 %s",name.c_str(), skill.c_str()), true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown SkillID." ,true, "ERROR");
+
+ }
+ else
+ {
+ uint32 counter = 0;
+ std::string skills = "\002Skill Search Results:\x3\x31\x30 ";
+ for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
+ {
+ SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
+ if (skillInfo)
+ {
+ MakeLower(_PARAMS[1]);
+ std::string name = skillInfo->name[sWorld->GetDefaultDbcLocale()];
+ MakeLower(name);
+ if (name.find(_PARAMS[1]) != std::string::npos && counter < 10)
+ {
+ char skillid[100];
+ sprintf(skillid, "%d", id);
+ skills.append(name+"("+skillid+")\xF | \x3\x31\x30\x2");
+ ++counter;
+ }
+ }
+ }
+ if (counter == 0)
+ skills.append("No Skills Found.");
+ Send_IRCA(ChanOrPM(CD), skills, true, CD->TYPE);
+ }
+ }
+ if (_PARAMS[0] == "spell")
+ {
+ std::string spell = _PARAMS[1];
+ if (atoi(spell.c_str()) > 0)
+ {
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(atoi(spell.c_str()));
+ if (spellInfo)
+ {
+ std::string name = spellInfo->SpellName[sWorld->GetDefaultDbcLocale()];
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\x2Spell:\x3\x31\x30 %s \xF|\x2 SpellID:\x3\x31\x30 %s",name.c_str(), spell.c_str()), true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown SpellID." ,true, "ERROR");
+
+ }
+ else
+ {
+ uint32 counter = 0;
+ std::string spells = "\002Spell Search Results:\x3\x31\x30 ";
+ for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
+ {
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
+ if (spellInfo)
+ {
+ MakeLower(_PARAMS[1]);
+ std::string name = spellInfo->SpellName[sWorld->GetDefaultDbcLocale()];
+ MakeLower(name);
+ if (name.find(_PARAMS[1]) != std::string::npos && counter < 10)
+ {
+ char itemid[100];
+ sprintf(itemid, "%d", id);
+ spells.append(name+"("+itemid+")\xF | \x3\x31\x30\x2");
+ ++counter;
+ }
+ }
+ }
+ if (counter == 0)
+ spells.append("No Spells Found.");
+ Send_IRCA(ChanOrPM(CD), spells, true, CD->TYPE);
+ }
+ }
+ if (_PARAMS[0] == "tele")
+ {
+ std::string tele = _PARAMS[1];
+ if (atoi(tele.c_str()) > 0)
+ {
+ QueryResult result = WorldDatabase.PQuery("SELECT * FROM `game_tele` WHERE id = %s", _PARAMS[1].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+
+ uint32 teleid = fields[0].GetUInt32();
+ uint32 pos_x = fields[1].GetUInt32();
+ uint32 pos_y = fields[2].GetUInt32();
+ uint32 pos_z = fields[3].GetUInt32();
+ uint32 oriet = fields[4].GetUInt32();
+ uint32 map = fields[5].GetUInt32();
+ std::string telname = fields[6].GetString();
+
+
+ Send_IRCA(ChanOrPM(CD), MakeMsg("\x2Tele Name:\x3\x31\x30 %s \xF|\x2 TeleID:\x3\x31\x30 %d \xF|\x2 Coordinates:\x3\x31\x30 [X: %d, Y: %d, Z: %d, MAP: %d, Orientation: %d]", telname.c_str(), teleid, pos_x, pos_y, pos_z, map, oriet), true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown Teleport Location ID." ,true, "ERROR");
+ }
+ else
+ {
+ QueryResult result = WorldDatabase.PQuery("SELECT id, name FROM `game_tele` WHERE name LIKE '%%%s%%' LIMIT 10", _PARAMS[1].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ std::string teles = "\002Tele Location Search Results:\x3\x31\x30 ";
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ std::string TeleID = fields[0].GetString();
+ std::string TeleName = fields[1].GetString();
+ teles.append(TeleName+"("+TeleID+")\xF | \x3\x31\x30\x2");
+ result->NextRow();
+ }
+ Send_IRCA(ChanOrPM(CD), teles, true, CD->TYPE);
+
+ }
+ else
+ Send_IRCA(CD->USER, "Unknown Item. I Cant Find Any Items With Those Search Terms." ,true, "ERROR");
+ }
+ }
+}
+
+void IRCCmd::Level_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, CD->PCOUNT);
+ if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512)!= 0)
+ {
+ Send_IRCA(CD->USER, MakeMsg("You do not have access to do this to a higher ranked GM [%i]", AcctLevel(_PARAMS[0])), true, "ERROR");
+ return;
+ }
+ std::string player = _PARAMS[0];
+ normalizePlayerName(player);
+ uint64 guid = sObjectMgr->GetPlayerGUIDByName(player.c_str());
+ std::string s_newlevel = _PARAMS[1];
+ uint8 i_newlvl = atoi(s_newlevel.c_str());
+ if (!guid)
+ {
+ Send_IRCA(CD->USER, "Player Not Found!", true, "ERROR");
+ return;
+ } else if (i_newlvl < 1 || i_newlvl > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
+ {
+ Send_IRCA(CD->USER, MakeMsg("Level Must Be Between 1 And %i!",ConfigMgr::GetIntDefault("MaxPlayerLevel", 70)), true, "ERROR");
+ return;
+ } else
+ {
+ Player *chr = ObjectAccessor::FindPlayer(guid);
+ uint64 level;
+ int32 i_oldlvl = chr ? chr->getLevel() : Player::GetLevelFromDB(level);
+ Player* plTarget = chr;
+ if (!plTarget)
+ {
+ Send_IRCA(CD->USER, ""+_PARAMS[0]+" Is Not Online!", true, "ERROR");
+ return;
+ }
+
+ if (chr)
+ {
+ chr->GiveLevel(i_newlvl);
+ chr->InitTalentForLevel();
+ chr->SetUInt32Value(PLAYER_XP,0);
+ WorldPacket data;
+ std::stringstream ss;
+ ChatHandler CH(chr->GetSession());
+ if (i_oldlvl == i_newlvl)
+ CH.FillSystemMessageData(&data, "Your level progress has been reset.");
+ else
+ if (i_oldlvl < i_newlvl)
+ {
+ ss << "You have been leveled up" << i_newlvl-i_oldlvl;
+ CH.FillSystemMessageData(&data, ss.str().c_str());
+ }
+ else if (i_oldlvl > i_newlvl)
+ {
+ ss << "You have been leveled down" << i_newlvl-i_oldlvl;
+ CH.FillSystemMessageData(&data, ss.str().c_str());
+ chr->GetSession()->SendPacket(&data);
+ }
+ }
+ else
+ {
+ Player::GetLevelFromDB(guid);
+ uint64 player_guid;
+ CharacterDatabase.PExecute("UPDATE characters SET level = '%u', xp = 0 WHERE guid = '%u'", i_newlvl, GUID_LOPART(player_guid));
+ }
+ }
+ Send_IRCA(ChanOrPM(CD), "\00313[" + _PARAMS[0]+ "] : Has Been Leveled To " + _PARAMS[1] + ". By: "+CD->USER+".", true, CD->TYPE);
+}
+
+void IRCCmd::Money_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 2);
+ if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512)!= 0)
+ {
+ Send_IRCA(CD->USER, MakeMsg("You do not have access to do this to a higher ranked GM [%i]", AcctLevel(_PARAMS[0])), true, "ERROR");
+ return;
+ }
+ std::string player = _PARAMS[0];
+ normalizePlayerName(player);
+ uint64 guid = sObjectMgr->GetPlayerGUIDByName(player.c_str());
+ Player *chr = ObjectAccessor::FindPlayer(guid);
+
+ std::string s_money = _PARAMS[1];
+ int32 money = atoi(s_money.c_str());
+ 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 (!guid)
+ {
+ Send_IRCA(CD->USER, "Player Not Found!", true, "ERROR");
+ return;
+ }
+ else
+ {
+ Player *chr = ObjectAccessor::FindPlayer(guid);
+ uint32 moneyuser = 0;
+ if (chr)
+ moneyuser = chr->GetMoney();
+ else {
+ CharacterDatabase.EscapeString(player);
+ std::string sqlquery = "SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(money, ' ' , 1462), ' ' , -1) AS `gold` FROM `characters` WHERE `name` = '"+player+"';";
+ QueryResult result = CharacterDatabase.Query(sqlquery.c_str());
+ Field *fields = result->Fetch();
+ moneyuser = fields[0].GetInt32();
+
+ }
+ int32 addmoney = money;
+ int32 newmoney = moneyuser + addmoney;
+ char s_newmoney[255];
+ sprintf(s_newmoney,"%d",newmoney);
+ if (addmoney < 0)
+ {
+ sLog->outError(LOG_FILTER_GENERAL, "USER1: %i, ADD: %i, DIF: %i\\n", moneyuser, addmoney, newmoney);
+ if (newmoney <= 0)
+ {
+ Send_IRCA(ChanOrPM(CD), "\00313["+player+"] : Has Had All Money Taken By: "+CD->USER.c_str()+".", true, CD->TYPE);
+ if (chr)
+ {
+ chr->SetMoney(0);
+ Send_Player(chr, MakeMsg("You Have Been Liquidated By: %s. Total Money Is Now 0.", CD->USER.c_str()));
+ }
+ else
+ CharacterDatabase.PExecute("UPDATE `characters` SET money=concat(substring_index(name,' ',1462-1),' ','%u',' ', right(name,length(name)-length(substring_index(name,' ',1462))-1)) where guid='%u'",newmoney, guid);
+ }
+ else
+ {
+ Send_IRCA(ChanOrPM(CD), "\00313["+player+"] : Has Had ("+s_money+"\00313) Taken From Them By: "+CD->USER.c_str()+".", true, CD->TYPE);
+ if (chr)
+ {
+ chr->SetMoney(newmoney);
+ Send_Player(chr, MakeMsg("You Have Had %s Copper Taken From You By: %s.", _PARAMS[1].c_str(), CD->USER.c_str()));
+ }
+ else
+ CharacterDatabase.PExecute("UPDATE `characters` SET money=concat(substring_index(name,' ',1462-1),' ','%u',' ', right(name,length(name)-length(substring_index(name,' ',1462))-1)) where guid='%u'",newmoney, guid);
+ }
+ }
+ else
+ {
+ Send_IRCA(ChanOrPM(CD), "\00313["+player+"] : Has Been Given ("+tempgold+"\00313) From: "+CD->USER.c_str()+".", true, CD->TYPE);
+ if (chr)
+ {
+ chr->ModifyMoney(addmoney);
+ Send_Player(chr, MakeMsg("You Have Been Given %s Copper. From: %s.", _PARAMS[1].c_str(), CD->USER.c_str()));
+ }
+ else
+ CharacterDatabase.PExecute("UPDATE `characters` SET money=concat(substring_index(name,' ',1462-1),' ','%u',' ', right(name,length(name)-length(substring_index(name,' ',1462))-1)) where guid='%u'",newmoney, guid);
+ }
+ }
+}
+
+void IRCCmd::Mute_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 3);
+ if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512)!= 0)
+ {
+ Send_IRCA(CD->USER, MakeMsg("You do not have access to do this to a higher ranked GM [%i]", AcctLevel(_PARAMS[0])), true, "ERROR");
+ return;
+ }
+ normalizePlayerName(_PARAMS[0]);
+ uint64 guid = sObjectMgr->GetPlayerGUIDByName(_PARAMS[0]);
+ if (guid)
+ {
+ if (_PARAMS[1] == "release")
+ {
+ Player* plr = ObjectAccessor::FindPlayer(guid);
+ uint32 account_id = 0;
+ account_id = sObjectMgr->GetPlayerAccountIdByGUID(guid);
+ LoginDatabase.PExecute("UPDATE `account` SET `mutetime` = '0', `mutereason` = '', `muteby` = '' WHERE `id` = '%d'",account_id);
+ Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Been UnMuted By: "+CD->USER+"." , true, CD->TYPE);
+ if (plr)
+ {
+ plr->GetSession()->m_muteTime = 0;
+ Send_Player(plr, MakeMsg("You Have Been UnMuted By: %s.", CD->USER.c_str()));
+ }
+ }
+ else
+ {
+ if (_PARAMS[2] == "")
+ _PARAMS[2] = "No Reason Given";
+ Player* plr = ObjectAccessor::FindPlayer(guid);
+ time_t mutetime = time(NULL) + atoi(_PARAMS[1].c_str())*60;
+ std::string By = "IRC:";
+ By += CD->USER.c_str();
+ uint32 account_id = 0;
+ account_id = sObjectMgr->GetPlayerAccountIdByGUID(guid);
+ if (plr)
+ plr->GetSession()->m_muteTime = mutetime;
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME);
+ stmt->setInt64(0, mutetime);
+ stmt->setString(1, _PARAMS[2].c_str());
+ stmt->setString(2, By.c_str());
+ stmt->setUInt32(3, account_id);
+ LoginDatabase.Execute(stmt);
+ Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Been Muted By: "+CD->USER+". For: "+_PARAMS[1]+" Minutes. Reason: "+_PARAMS[2] , true, CD->TYPE);
+ if (plr)
+ Send_Player(plr, MakeMsg("You Have Been Muted By: %s. For: %s Minutes. Reason: %s", CD->USER.c_str(), _PARAMS[1].c_str(), _PARAMS[2].c_str()));
+ }
+ }
+ else
+ Send_IRCA(CD->USER, "Player Does Not Exist!", true, "ERROR");
+}
+
+void IRCCmd::Online_Players(_CDATA *CD)
+{
+ sIRC.Script_Lock[MCS_Players_Online] = true;
+ ACE_Based::Thread script(new mcs_OnlinePlayers(CD));
+}
+
+void IRCCmd::PM_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 2);
+ if (Player* plr = GetPlayer(_PARAMS[0]))
+ {
+ if (plr->isAcceptWhispers())
+ {
+ std::string sMsg = MakeMsg("|cffFE87FD[<IRC>%s] Whispers: %s|r", CD->USER.c_str(), _PARAMS[1].c_str());
+ WorldPacket data(SMSG_MESSAGECHAT, 200);
+ data << (uint8)CHAT_MSG_SYSTEM;
+ data << (uint32)LANG_UNIVERSAL;
+ data << (uint64)plr->GetGUID();
+ data << (uint32)0;
+ data << (uint64)plr->GetGUID();
+ data << (uint32)(sMsg.length()+1);
+ data << sMsg;
+ data << (uint8)0;
+ plr->GetSession()->SendPacket(&data);
+ plr->SendPlaySound(3081, true);
+ Send_IRCA(ChanOrPM(CD), "\00313To ["+_PARAMS[0]+"] : "+_PARAMS[1]+".", true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "Is Not Accepting Private Messages!", true, "ERROR");
+ }
+ else
+ Send_IRCA(CD->USER, "Player not online!", true, "ERROR");
+}
+
+void IRCCmd::Restart_Trinity(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 1);
+ if (_PARAMS[0] == "cancel")
+ {
+ sWorld->ShutdownCancel();
+ Send_IRCA(ChanOrPM(CD), "\0034Server Restart Has Been Cancelled.", true, CD->TYPE);
+ }
+
+ int32 i_time = atoi(_PARAMS[0].c_str());
+ if (i_time < 0)
+ {
+ Send_IRCA(ChanOrPM(CD), "\00313["+CD->USER+"] : Please Enter A Number! And No Negative Numbers! "+_PARAMS[0]+" Seconds!?", true, CD->TYPE);
+ return;
+ }
+ if (i_time >= 1)
+ {
+ Send_IRCA(ChanOrPM(CD), "\00313["+CD->USER+"] : Has Requested Server To Restart In "+_PARAMS[0]+" Seconds!", true, CD->TYPE);
+ sWorld->ShutdownServ(i_time,SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
+ Delay(i_time*1000);
+ Send_IRCA(ChanOrPM(CD), "\0034Server Will Now Restart.. Be Back In A Flash!", true, CD->TYPE);
+ }
+}
+
+void IRCCmd::Revive_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, CD->PCOUNT);
+ if (Player* plr = GetPlayer(_PARAMS[0]))
+ {
+ if (plr->isDead())
+ {
+ plr->ResurrectPlayer(0.5f);
+ plr->SpawnCorpseBones();
+ plr->SaveToDB();
+ sIRC.Send_IRC_Channel(ChanOrPM(CD), " \00313["+_PARAMS[0]+"] : Has Been Revived By: " + CD->USER, true, CD->TYPE);
+ Send_Player(plr, MakeMsg("You Have Been Revived By: %s.", CD->USER.c_str()));
+ }
+ else
+ Send_IRCA(CD->USER, ""+_PARAMS[0]+" Is Not Dead!", true, "ERROR");
+ }
+ else
+ Send_IRCA(CD->USER, ""+_PARAMS[0]+" Is Not Online!", true, "ERROR");
+}
+
+void IRCCmd::Saveall_Player(_CDATA *CD)
+{
+ sObjectAccessor->SaveAllPlayers();
+ Send_IRCA(ChanOrPM(CD), "\00313["+CD->USER+"] : Has Saved All Players!", true, CD->TYPE);
+}
+
+void IRCCmd::Server(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, CD->PCOUNT);
+ if (_PARAMS[0] == "setmotd")
+ {
+ sWorld->SetMotd(_PARAMS[1]);
+ Send_IRCA(ChanOrPM(CD), "\00313["+CD->USER+"] : Has Set New Message Of The Day To: "+_PARAMS[1], true, CD->TYPE);
+ }
+ if (_PARAMS[0] == "flusharenapoints")
+ {
+ sArenaTeamMgr->DistributeArenaPoints();
+ }
+}
+
+void IRCCmd::Shutdown_Trinity(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 1);
+ if (_PARAMS[0] == "cancel")
+ {
+ sWorld->ShutdownCancel();
+ Send_IRCA(ChanOrPM(CD), "\0034Server Shutdown Has Been Cancelled.", true, CD->TYPE);
+ }
+
+ int32 i_time = atoi(_PARAMS[0].c_str());
+ if (i_time < 0)
+ {
+ Send_IRCA(ChanOrPM(CD), "\00313["+CD->USER+"] : Please Enter A Number! And No Negative Numbers! "+_PARAMS[0]+" Seconds!?", true, CD->TYPE);
+ return;
+ }
+ if (i_time >= 1)
+ {
+ Send_IRCA(ChanOrPM(CD), "\00313["+CD->USER+"] : Has Requested Server To Be Shut Down In "+_PARAMS[0]+" Seconds!", true, CD->TYPE);
+ sWorld->ShutdownServ(i_time, SHUTDOWN_MASK_IDLE , SHUTDOWN_EXIT_CODE);
+ Delay(i_time*1000);
+ Send_IRCA(ChanOrPM(CD), "\0034Server Will Now Shut Down.. Good Bye!", true, CD->TYPE);
+ }
+}
+
+void IRCCmd::Spell_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 3);
+ if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512)!= 0)
+ {
+ Send_IRCA(CD->USER, MakeMsg("You do not have access to do this to a higher ranked GM [%i]", AcctLevel(_PARAMS[0])), true, "ERROR");
+ return;
+ }
+ uint32 spell = atoi(_PARAMS[2].c_str());
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell);
+ if (Player* plr = GetPlayer(_PARAMS[0]))
+ {
+ if (spellInfo)
+ {
+ std::string name = spellInfo->SpellName[sWorld->GetDefaultDbcLocale()];
+ if (_PARAMS[1] == "cast")
+ {
+ plr->CastSpell(plr, spell, true);
+ Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Had Spell "+name+" Casted On Them.", true, CD->TYPE);
+ }
+ if (_PARAMS[1] == "learn")
+ {
+ plr->learnSpell(spell, true);
+ Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Learned Spell "+name+".", true, CD->TYPE);
+ }
+ if (_PARAMS[1] == "unlearn")
+ {
+ plr->removeSpell(spell);
+ Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Unlearned Spell "+name+".", true, CD->TYPE);
+ }
+ }
+ else
+ Send_IRCA(CD->USER, "Incorrect Spell ID!", true, "ERROR");
+ }
+ else
+ Send_IRCA(CD->USER, "Player Not Online!", true, "ERROR");
+}
+
+void IRCCmd::Sysmsg_Server(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, CD->PCOUNT);
+ std::string ircchan = "#";
+ ircchan += sIRC._irc_chan[sIRC.anchn].c_str();
+ if (_PARAMS[0] == "a")
+ {
+ std::string str = _PARAMS[1];
+ std::string ancmsg = MakeMsg("\00304,08\037/!\\\037\017\00304 System Message \00304,08\037/!\\\037\017 %s",_PARAMS[1].c_str());
+ sWorld->SendWorldText(6620,str.c_str());
+ sIRC.Send_IRC_Channel(ircchan, ancmsg, true);
+ }
+ else if (_PARAMS[0] == "e")
+ {
+ std::string str = _PARAMS[1];
+ std::string notstr = "[Server Event]: " + _PARAMS[1];
+ std::string notmsg = MakeMsg("\00304,08\037/!\\\037\017\00304 Server Event \00304,08\037/!\\\037\017 %s",_PARAMS[1].c_str());
+ WorldPacket data(SMSG_NOTIFICATION, (notstr.size()+1));
+ data << notstr;
+ WorldPacket data2(SMSG_PLAY_SOUND,32);
+ data2 << (uint32)1400;
+ sWorld->SendGlobalMessage(&data2);
+ sWorld->SendGlobalMessage(&data);
+ sWorld->SendWorldText(6621,str.c_str());
+ sIRC.Send_IRC_Channel(ircchan, notmsg, true);
+ }
+ else if (_PARAMS[0] == "n")
+ {
+ std::string str = "Global notify: " + _PARAMS[1];
+ std::string notmsg = MakeMsg("\00304,08\037/!\\\037\017\00304 Global Notify \00304,08\037/!\\\037\017 %s",_PARAMS[1].c_str());
+ WorldPacket data(SMSG_NOTIFICATION, (str.size()+1));
+ data << str;
+ sWorld->SendGlobalMessage(&data);
+ sIRC.Send_IRC_Channel(ircchan, notmsg, true);
+ }
+ else if (_PARAMS[0] == "gm")
+ {
+ std::string str = "GM Announcement: " + _PARAMS[1];
+ WorldPacket data(SMSG_NOTIFICATION, (str.size()+1));
+ data << str;
+ sWorld->SendGlobalGMMessage(&data);
+
+ }
+ else if (_PARAMS[0] == "add")
+ {
+ WorldDatabase.PExecute("INSERT INTO irc_autoannounce (message, addedby) VALUES ('%s', '%s')", _PARAMS[1].c_str(), CD->USER.c_str());
+ std::string str = _PARAMS[1];
+ std::string ancmsg = MakeMsg("\00304,08\037/!\\\037\017\00304 Automatic System Message \00304,08\037/!\\\037\017 %s",_PARAMS[1].c_str());
+ sWorld->SendWorldText(6622,str.c_str());
+ sIRC.Send_IRC_Channel(ircchan, ancmsg, true);
+ }
+ else if (_PARAMS[0] == "del")
+ {
+ WorldDatabase.PExecute("DELETE FROM irc_autoannounce WHERE id = %s", _PARAMS[1].c_str());
+ Send_IRCA(ChanOrPM(CD), MakeMsg("Deleted Automatic Announcement Message ID: %s", _PARAMS[1].c_str()), true, CD->TYPE);
+ }
+ else if (_PARAMS[0] == "list")
+ {
+ QueryResult result = WorldDatabase.PQuery("SELECT * FROM irc_autoannounce LIMIT 5;", _PARAMS[1].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ std::string id = fields[0].GetString();
+ std::string message = fields[1].GetString();
+ std::string addedby = fields[2].GetString();
+ Send_IRCA(ChanOrPM(CD), MakeMsg("ID: %s - Added By: %s - Message: %s", id.c_str(), addedby.c_str(), message.c_str()), true, CD->TYPE);
+ result->NextRow();
+ }
+ }
+ else
+ Send_IRCA(CD->USER, "No Auto Announce Messages Are In The Database.", true, "ERROR");
+ }
+ else
+ Send_IRCA(CD->USER, "Please Use (a-Announce)(n-Notify)(e-Event) As Second Parameter!", true, "ERROR");
+}
+
+void IRCCmd::Tele_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 4);
+ if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512)!= 0)
+ {
+ Send_IRCA(CD->USER, MakeMsg("You do not have access to do this to a higher ranked GM [%i]", AcctLevel(_PARAMS[0])), true, "ERROR");
+ return;
+ }
+ bool DoTeleport = false;
+ float pX, pY, pZ, pO = 0;
+ uint32 mapid = 0;
+ std::string rMsg = " Teleport Failed!";
+ std::string wMsg = "Invalid Tele Location";
+ Player* plr = GetPlayer(_PARAMS[0]);
+ if (plr)
+ {
+ if (plr->isInFlight() || plr->isInCombat())
+ {
+ Send_IRCA(CD->USER, MakeMsg("%s Is Busy And Cannot Be Teleported! They Could Be In Combat, Or Flying.",_PARAMS[0].c_str()), true, "ERROR");
+ return;
+ }
+ }
+ if (_PARAMS[1] == "l" || _PARAMS[1].size() > 2)
+ {
+ if (_PARAMS[1].size() > 1)
+ _PARAMS[2] = _PARAMS[1];
+ WorldDatabase.EscapeString(_PARAMS[2]);
+ QueryResult result = WorldDatabase.PQuery("SELECT position_x, position_y, position_z, orientation, map FROM game_tele WHERE name='%s';", _PARAMS[2].c_str());
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ pX = fields[0].GetFloat();
+ pY = fields[1].GetFloat();
+ pZ = fields[2].GetFloat();
+ pO = fields[3].GetFloat();
+ mapid = fields[4].GetUInt16();
+
+ rMsg = MakeMsg(" \00313[%s] : Teleported To %s! By: %s.",
+ _PARAMS[0].c_str(),
+ _PARAMS[2].c_str(),
+ CD->USER.c_str());
+ wMsg = MakeMsg("You Have Been Teleported To %s By: %s.",
+ _PARAMS[2].c_str(),
+ CD->USER.c_str());
+ DoTeleport = true;
+ }
+ else
+ {
+ WorldDatabase.EscapeString(_PARAMS[2]);
+ QueryResult result = WorldDatabase.PQuery("SELECT name FROM game_tele WHERE name LIKE '%%%s%%' LIMIT 7;", _PARAMS[2].c_str());
+ if (result)
+ {
+ std::string telename = "<> ";
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ Field *fields = result->Fetch();
+ telename.append(fields[0].GetString());
+ result->NextRow();
+ telename.append(" <> ");
+ }
+
+ Send_IRCA(CD->USER, "I Cannot Find Location: "+_PARAMS[2]+" . Perhaps One Of These Will Work For You.", true, "ERROR");
+ Send_IRCA(CD->USER, telename, true, "ERROR");
+ return;
+ }
+ else
+ Send_IRCA(CD->USER, "Location Not Found! Nothing Even Close Found!", true, "ERROR");
+ return;
+ }
+ }
+ else if (_PARAMS[1] == "c")
+ {
+ std::string* _PARAMSA = getArray(_PARAMS[2], 4);
+ pX = atof(_PARAMSA[1].c_str());
+ pY = atof(_PARAMSA[2].c_str());
+ pZ = atof(_PARAMSA[3].c_str());
+ mapid = atoi(_PARAMSA[0].c_str());
+ rMsg = MakeMsg(" \00313[%s] : Teleported To Map: %s. Position: X(%s) Y(%s) Z(%s)! By: %s.",
+ _PARAMS[0].c_str(),
+ _PARAMSA[0].c_str(),
+ _PARAMSA[1].c_str(),
+ _PARAMSA[2].c_str(),
+ _PARAMSA[3].c_str(),
+ CD->USER.c_str());
+ wMsg = MakeMsg("You Have Been Teleported To Map: %s. Position: X(%s) Y(%s) Z(%s)! By: %s.",
+ _PARAMSA[0].c_str(),
+ _PARAMSA[1].c_str(),
+ _PARAMSA[2].c_str(),
+ _PARAMSA[3].c_str(),
+ CD->USER.c_str());
+ DoTeleport = true;
+ }
+ else if (_PARAMS[1] == "r")
+ {
+ if (plr)
+ {
+ pX = plr->m_recallX;
+ pY = plr->m_recallY;
+ pZ = plr->m_recallZ;
+ pO = plr->m_recallO;
+ mapid = plr->m_recallMap;
+ rMsg = MakeMsg(" \00313[%s] : Has Been Recalled To Their Previous Location.",
+ _PARAMS[0].c_str());
+ wMsg = MakeMsg("You Have Been Recalled To Your Previous Location. By: %s",
+ CD->USER.c_str());
+ DoTeleport = true;
+ }
+ else
+ {
+ Send_IRCA(CD->USER, MakeMsg("\00313[%s] : Cannot Be Recalled, They Are Not Online.", _PARAMS[0].c_str()), true, "ERROR");
+ return;
+ }
+
+ }
+ else if (_PARAMS[1] == "to")
+ {
+ Player* plr2 = GetPlayer(_PARAMS[2]);
+ if (plr2)
+ {
+ plr2->GetContactPoint(plr, pX, pY, pZ);
+ mapid = plr2->GetMapId();
+ }
+ else
+ {
+ if (uint64 guid = sObjectMgr->GetPlayerGUIDByName(_PARAMS[2].c_str()))
+ {
+ bool in_flight;
+ Player::LoadPositionFromDB(mapid, pX, pY, pZ, pO, in_flight, guid);
+ }
+ else
+ {
+ Send_IRCA(CD->USER, "Second Player Not Found!", true, "ERROR");
+ return;
+ }
+ }
+ rMsg = MakeMsg(" \00313[%s] : Teleported To Player: [%s] By: %s.",
+ _PARAMS[0].c_str(),
+ _PARAMS[2].c_str(),
+ CD->USER.c_str());
+ wMsg = MakeMsg("You Are Being Teleported To: %s. By: %s.",
+ _PARAMS[2].c_str(),
+ CD->USER.c_str());
+ DoTeleport = true;
+ }
+ else if (_PARAMS[1] == "cr")
+ {
+ QueryResult result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature WHERE guid ='%s' LIMIT 1", _PARAMS[2].c_str());
+ if (!result)
+ {
+ Send_IRCA(CD->USER, "Creature GUID not found", true, "ERROR");
+ }
+ else
+ {
+ Field *fields = result->Fetch();
+ pX = fields[0].GetFloat();
+ pY = fields[1].GetFloat();
+ pZ = fields[2].GetFloat();
+ pO = fields[3].GetFloat();
+ mapid = fields[4].GetUInt16();
+
+ rMsg = MakeMsg(" \00313[%s] : Teleported To Creature: [%s] By: %s.",
+ _PARAMS[0].c_str(),
+ _PARAMS[2].c_str(),
+ CD->USER.c_str());
+ wMsg = MakeMsg("You Are Being Teleported To: %s. By: %s.",
+ _PARAMS[2].c_str(),
+ CD->USER.c_str());
+ DoTeleport = true;
+
+ }
+ }
+ else if (_PARAMS[1] == "go")
+ {
+ QueryResult result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM gameobject WHERE guid ='%s' LIMIT 1", _PARAMS[2].c_str());
+ if (!result)
+ {
+ Send_IRCA(CD->USER, "GO GUID not found", true, "ERROR");
+ }
+ else
+ {
+ Field *fields = result->Fetch();
+ pX = fields[0].GetFloat();
+ pY = fields[1].GetFloat();
+ pZ = fields[2].GetFloat();
+ pO = fields[3].GetFloat();
+ mapid = fields[4].GetUInt16();
+
+ rMsg = MakeMsg(" \00313[%s] : Teleported To Gameobject: [%s] By: %s.",
+ _PARAMS[0].c_str(),
+ _PARAMS[2].c_str(),
+ CD->USER.c_str());
+ wMsg = MakeMsg("You Are Being Teleported To: %s. By: %s.",
+ _PARAMS[2].c_str(),
+ CD->USER.c_str());
+ DoTeleport = true;
+
+ }
+ }
+ else if (_PARAMS[1] == "homebind")
+ {
+ QueryResult result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,map FROM `character_homebind` WHERE guid = '%d'", plr->GetGUID());
+ if (!result)
+ {
+ Send_IRCA(CD->USER, "Unexpected Error Loading Homebind Location", true, "ERROR");
+ }
+ else
+ {
+ Field *fields = result->Fetch();
+ pX = fields[0].GetFloat();
+ pY = fields[1].GetFloat();
+ pZ = fields[2].GetFloat();
+ pO = 1;
+ mapid = fields[3].GetUInt16();
+
+ rMsg = MakeMsg(" \00313[%s] : Teleported To Homebind Location By: %s.",
+ _PARAMS[0].c_str(),
+ CD->USER.c_str());
+ wMsg = MakeMsg("You Are Being Teleported To Your Homebind Location By: %s.",
+ CD->USER.c_str());
+ DoTeleport = true;
+
+ }
+
+ }
+ if (DoTeleport)
+ {
+ if (MapManager::IsValidMapCoord(mapid, pX ,pY ,pZ))
+ {
+ //if (!sIRC.BeenToGMI(pX, pY, _PARAMS[0], CD->USER))
+ //{
+ //if player is online teleport them in real time, if not set the DB to our coordinates.
+ if (plr)
+ {
+ plr->SaveRecallPosition();
+ plr->TeleportTo(mapid, pX, pY, pZ, pO);
+ sIRC.Send_IRC_Channel(ChanOrPM(CD), rMsg, true, CD->TYPE);
+ Send_Player(plr, wMsg);
+ }
+ else
+ {
+ uint64 guid = sObjectMgr->GetPlayerGUIDByName(_PARAMS[0]);
+ Player::SavePositionInDB(mapid,pX,pY,pZ,pO,sMapMgr->GetZoneId(mapid,pX,pY,pZ),guid);
+ sIRC.Send_IRC_Channel(ChanOrPM(CD), rMsg + " \0034*Offline Tele.* ", true, CD->TYPE);
+ }
+ //}
+ }
+ else
+ Send_IRCA(CD->USER, "Invalid Location!", true, "ERROR");
+ }
+ else
+ Send_IRCA(CD->USER, "Invalid Paramaters, Please Try Again [ "+sIRC._cmd_prefx+"help tele ] For More Information. ", true, "ERROR");
+}
+
+void IRCCmd::Top_Player(_CDATA *CD)
+{
+ std::string* _PARAMS = getArray(CD->PARAMS, 2);
+ uint32 limitr = 10;
+ if (atoi(_PARAMS[1].c_str()) > 0 && GetLevel(CD->USER) >= sIRC._op_gm_lev)
+ limitr = atoi(_PARAMS[1].c_str());
+ if (_PARAMS[0] == "accttime")
+ {
+ QueryResult result = CharacterDatabase.PQuery("SELECT account, name, (SUM(totaltime)) AS combinetime FROM characters GROUP BY account ORDER BY combinetime DESC LIMIT 0, %d ", limitr);
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ std::string tptime = MakeMsg("\x2 Top%d Accounts By Played Time:\x3\x31\x30 ", limitr);
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ uint32 account = fields[0].GetUInt32();
+ std::string PlName = GetAcctNameFromID(account);
+ std::string Time = SecToDay(fields[2].GetString());
+ uint32 rank = i+1;
+ tptime.append(MakeMsg("[%u]%s %s \xF| \x3\x31\x30\x2", rank, PlName.c_str(), Time.c_str()));
+ result->NextRow();
+ }
+
+ Send_IRCA(ChanOrPM(CD), tptime, true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "No Accounts Returned." ,true, "ERROR");
+ }
+ if (_PARAMS[0] == "chartime")
+ {
+ QueryResult result = CharacterDatabase.PQuery("SELECT name, totaltime FROM characters ORDER BY totaltime DESC LIMIT 0, %d ", limitr);
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ std::string tptime = MakeMsg("\x2 Top%d Characters By Played Time:\x3\x31\x30 ", limitr);
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ std::string Name = fields[0].GetString();
+ std::string Time = SecToDay(fields[1].GetString());
+ uint32 rank = i+1;
+ tptime.append(MakeMsg("[%u]%s %s \xF| \x3\x31\x30\x2", rank, Name.c_str(), Time.c_str()));
+ result->NextRow();
+ }
+
+ Send_IRCA(ChanOrPM(CD), tptime, true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "No Characters Returned." ,true, "ERROR");
+ }
+ if (_PARAMS[0] == "money")
+ {
+ QueryResult result = CharacterDatabase.PQuery("SELECT name, money FROM characters ORDER BY money DESC LIMIT 0, %d ", limitr);
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ std::string tptime = MakeMsg("\x2 Top%d Characters By Money:\x3\x31\x30 ", limitr);
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ std::string Name = fields[0].GetString();
+ unsigned int money = fields[1].GetInt32();
+
+ uint32 rank = i+1;
+
+ 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);
+
+ tptime.append(MakeMsg("[%u]%s %s \xF| \x3\x31\x30\x2", rank, Name.c_str(), tempgold));
+ result->NextRow();
+ }
+
+ Send_IRCA(ChanOrPM(CD), tptime, true, CD->TYPE);
+ }
+ else
+ Send_IRCA(CD->USER, "No Characters Returned." ,true, "ERROR");
+ }
+
+}
+
+void IRCCmd::Chan_Control(_CDATA *CD)
+{
+
+ std::string* _PARAMS = getArray(CD->PARAMS, 2);
+
+ if (CD->FROM == sIRC._Nick)
+ {
+ Send_IRCA(CD->USER, "\0034[ERROR] : You Cannot Use This Command Through A PM Yet.", true, "ERROR");
+ return;
+ }
+
+ if (_PARAMS[0] == "op")
+ {
+ if (_PARAMS[1].length() > 1)
+ sIRC.SendIRC("MODE "+CD->FROM+" +o "+_PARAMS[1]);
+ else
+ sIRC.SendIRC("MODE "+CD->FROM+" +o "+CD->USER);
+ }
+
+ if (_PARAMS[0] == "deop")
+ {
+ if (_PARAMS[1].length() > 1)
+ sIRC.SendIRC("MODE "+CD->FROM+" -o "+_PARAMS[1]);
+ else
+ sIRC.SendIRC("MODE "+CD->FROM+" -o "+CD->USER);
+ }
+
+ if (_PARAMS[0] == "voice")
+ {
+ if (_PARAMS[1].length() > 1)
+ sIRC.SendIRC("MODE "+CD->FROM+" +v "+_PARAMS[1]);
+ else
+ sIRC.SendIRC("MODE "+CD->FROM+" +v "+CD->USER);
+ }
+ if (_PARAMS[0] == "devoice")
+ {
+ if (_PARAMS[1].length() > 1)
+ sIRC.SendIRC("MODE "+CD->FROM+" -v "+_PARAMS[1]);
+ else
+ sIRC.SendIRC("MODE "+CD->FROM+" -v "+CD->USER);
+ }
+};
+void IRCCmd::Who_Logged(_CDATA *CD)
+{
+ std::string OPS = "";
+ for (std::list<_client*>::iterator i=_CLIENTS.begin(); i!=_CLIENTS.end();i++)
+ {
+ OPS.append(MakeMsg(" \002[GM:%d IRC: %s - WoW: %s]\002 ", (*i)->GMLevel, (*i)->Name.c_str(), (*i)->UName.c_str()));
+ }
+ Send_IRCA(ChanOrPM(CD), OPS, true, CD->TYPE);
+}
\ No newline at end of file
diff --git a/src/server/game/TriniChat/IRCFunc.h b/src/server/game/TriniChat/IRCFunc.h
new file mode 100644
index 0000000..1f39171
--- /dev/null
+++ b/src/server/game/TriniChat/IRCFunc.h
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef _IRC_CLIENT_FUNC
+#define _IRC_CLIENT_FUNC
+
+std::string GetUser(std::string szU)
+{
+ int pos = szU.find("!");
+ return szU.substr(0, pos);
+}
+// Delink will remove anything considered "non chat" from a string
+std::string Delink(std::string msg)
+{
+ std::size_t pos;
+
+ while((pos = msg.find("|Htrade")) != std::string::npos)
+ {
+ std::size_t find1 = msg.find("|h", pos);
+ msg.replace(pos, find1 - pos + 2, "\x2");
+ msg.replace(msg.find("|h", pos), 2, "\x2");
+ }
+ while((pos = msg.find("|Hglyph")) != std::string::npos)
+ {
+ std::size_t find1 = msg.find("|h", pos);
+ msg.replace(pos, find1 - pos + 2, "\x2");
+ msg.replace(msg.find("|h", pos), 2, "\x2");
+ }
+ while((pos = msg.find("|Hitem")) != std::string::npos)
+ {
+ std::size_t find1 = msg.find("|h", pos);
+ std::size_t find2 = msg.find("|h", find1 + 2);
+ msg.replace(pos, find1 - pos + 2, "\x2");
+ msg.replace(msg.find("|h", pos), 2, "\x2");
+ }
+ while((pos = msg.find("|Henchant")) != std::string::npos)
+ {
+ std::size_t find1 = msg.find("|h", pos);
+ std::size_t find2 = msg.find("|h", find1 + 2);
+ msg.replace(pos, find1 - pos + 2, "\x2");
+ msg.replace(msg.find("|h", pos), 2, "\x2");
+ //msg.replace(find2, 2, "\x2");
+ }
+ while((pos = msg.find("|Hquest")) != std::string::npos)
+ {
+ std::size_t find1 = msg.find("|h", pos);
+ std::size_t find2 = msg.find("|h", find1 + 2);
+ msg.replace(pos, find1 - pos + 2, "\x2");
+ msg.replace(msg.find("|h", pos), 2, "\x2");
+ }
+ while((pos = msg.find("|Hspell")) != std::string::npos)
+ {
+ std::size_t find1 = msg.find("|h", pos);
+ std::size_t find2 = msg.find("|h", find1 + 2);
+ msg.replace(pos, find1 - pos + 2, "\x2");
+ msg.replace(msg.find("|h", pos), 2, "\x2");
+ }
+ while((pos = msg.find("|Htalent")) != std::string::npos)
+ {
+ std::size_t find1 = msg.find("|h", pos);
+ std::size_t find2 = msg.find("|h", find1 + 2);
+ msg.replace(pos, find1 - pos + 2, "\x2");
+ msg.replace(msg.find("|h", pos), 2, "\x2");
+ }
+ while((pos = msg.find("|Hachievement")) != std::string::npos)
+ {
+ std::size_t find1 = msg.find("|h", pos);
+ msg.replace(pos, find1 - pos + 2, "\x2");
+ msg.replace(msg.find("|h", pos), 2, "\x2");
+ }
+ while((pos = msg.find("|Htrade")) != std::string::npos)
+ {
+ std::size_t find1 = msg.find("|h", pos);
+ msg.replace(pos, find1 - pos + 2, "\x2");
+ msg.replace(msg.find("|h", pos), 2, "\x2");
+ }
+ return msg;
+}
+
+// This function converts the characters used by the client to identify colour to IRC format.
+std::string WoWcol2IRC(std::string msg)
+{
+ std::size_t pos;
+ char IRCCol[17][6] = { "\xF", "\xF", "\x3\x31\x34", "\x3\x30\x33", "\x3\x31\x32", "\x3\x30\x36", "\x3\x30\x37", "\x3\x30\x34", "\x3\x30\x34", "\x3\x31\x34", "\x3\x31\x32", "\x3\x30\x37", "\x3\x30\x34", "\x3\x30\x33", "\x3\x31\x32", "\x3\x31\x32", "\x3\x30\x37"};
+ char WoWCol[17][12] = { "|r", "|cffffffff", "|cff9d9d9d", "|cff1eff00", "|cff0070dd", "|cffa335ee", "|cffff8000", "|cffe6cc80", "|cffffd000", "|cff808080", "|cff71d5ff", "|cffffff00", "|cffff2020", "|cff40c040", "|cff4e96f7", "|cff71d5ff", "|cffff8040"};
+ for (int i=0; i<=15; i++)
+ {
+ while ((pos = msg.find(WoWCol[i])) != std::string::npos)
+ {
+ if (i == 0)
+ msg.replace(pos, 2, IRCCol[i]);
+ else
+ msg.replace(pos, 11, IRCCol[i]);
+ }
+ }
+ return msg;
+}
+
+// This function converts the characters used by IRC to identify colour to a format the client can understand.
+std::string IRCcol2WoW(std::string msg)
+{
+ std::size_t pos;
+ char IRCCol[18][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", "\x3\x30\x37", "\x3\x30\x37"};
+ 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[18][12] = { "|cffffffff", "|cff000000", "|cff00007f", "|cff009300", "|cffff0000", "|cff7f0000", "|cff9c009c", "|cfffc9300", "|cffffff00", "|cff00fc00", "|cff009393", "|cff00ffff", "|cff0000fc", "|cffff00ff", "|cff7f7f7f", "|cffd2d2d2", "|cff808080", "|cff71d5ff"};
+ 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]);
+ }
+ }
+
+ // Remove Bold, Reverse, Underline from IRC
+ char Checker[3][3] = {"\x2","\x16","\x1F"}; // This is the Hex part not Dec. In Decimal its (2,22,31)
+ for (int I=0; I < 3; I++)
+ {
+ while ((pos = msg.find(Checker[I])) != std::string::npos)
+ {
+ msg.replace(pos, 1, "");
+ }
+ }
+ // Finished Removing !
+
+ }
+
+ 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;
+}
+
+// This function compares 2 strings
+int nocase_cmp(const string & s1, const string& s2)
+{
+ string::const_iterator it1=s1.begin();
+ string::const_iterator it2=s2.begin();
+
+ //stop when either string's end has been reached
+ while ((it1!=s1.end()) && (it2!=s2.end()))
+ {
+ if (::toupper(*it1) != ::toupper(*it2)) //letters differ?
+ // return -1 to indicate smaller than, 1 otherwise
+ return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1;
+ //proceed to the next character in each string
+ ++it1;
+ ++it2;
+ }
+ size_t size1=s1.size(), size2=s2.size(); // cache lengths
+ //return -1,0 or 1 according to strings' lengths
+ if (size1==size2)
+ return 0;
+ return (size1<size2) ? -1 : 1;
+}
+
+std::string MakeMsgA(const char *sLine, ...)
+{
+ va_list ap;
+ char tmpoutp[1024];
+ va_start(ap, sLine);
+ vsnprintf(tmpoutp, 1024, sLine, ap);
+ va_end(ap);
+ std::string outp = tmpoutp;
+ return outp;
+}
+
+std::string MakeMsgP(int CLINE, std::string Msg, Player *plr)
+{
+ std::string sMsg = sIRC.MakeMsg(sIRC.GetChatLine(CLINE), "$Msg", Msg);
+ if (plr->GetTeam() == 67)
+ sMsg = sIRC.MakeMsg(sMsg, "$Name", MakeMsgA("\0034%s\003", plr->GetName().c_str()));
+ else if (plr->GetTeam() == 469)
+ sMsg = sIRC.MakeMsg(sMsg, "$Name", MakeMsgA("\00312%s\003", plr->GetName().c_str()));
+ if (plr->isAFK())
+ sMsg = sIRC.MakeMsg(sMsg, "$Tag", "<AFK>");
+ else if (plr->isDND())
+ sMsg = sIRC.MakeMsg(sMsg, "$Tag", "<DND>");
+ else
+ sMsg = sIRC.MakeMsg(sMsg, "$Tag", "");
+ sMsg = sIRC.MakeMsg(sMsg, "$Level", MakeMsgA("%d", plr->getLevel()));
+ if (plr->getClass() == 1)
+ sMsg = sIRC.MakeMsg(sMsg, "$Class", MakeMsgA("\0035WR\003"));
+ else if (plr->getClass() == 2)
+ sMsg = sIRC.MakeMsg(sMsg, "$Class", MakeMsgA("\00313PA\003"));
+ else if (plr->getClass() == 3)
+ sMsg = sIRC.MakeMsg(sMsg, "$Class", MakeMsgA("\0033HU\003"));
+ else if (plr->getClass() == 4)
+ sMsg = sIRC.MakeMsg(sMsg, "$Class", MakeMsgA("\00310RO\003"));
+ else if (plr->getClass() == 5)
+ sMsg = sIRC.MakeMsg(sMsg, "$Class", MakeMsgA("\00314PR\003"));
+ else if (plr->getClass() == 6)
+ sMsg = sIRC.MakeMsg(sMsg, "$Class", MakeMsgA("\0034DK\003"));
+ else if (plr->getClass() == 7)
+ sMsg = sIRC.MakeMsg(sMsg, "$Class", MakeMsgA("\00312SH\003"));
+ else if (plr->getClass() == 8)
+ sMsg = sIRC.MakeMsg(sMsg, "$Class", MakeMsgA("\00311MA\003"));
+ else if (plr->getClass() == 9)
+ sMsg = sIRC.MakeMsg(sMsg, "$Class", MakeMsgA("\0036WL\003"));
+ else if (plr->getClass() == 11)
+ sMsg = sIRC.MakeMsg(sMsg, "$Class", MakeMsgA("\0037DR\003"));
+ sMsg = Delink(sMsg);
+ sMsg = WoWcol2IRC(sMsg);
+ return sMsg;
+}
+
+// This function checks if a channel exists in out configuration
+// TriniChat supports as many channels as you like
+bool Channel_Valid(std::string Channel)
+{
+ for (int i=1;i < sIRC._chan_count + 1;i++)
+ {
+ if (nocase_cmp(sIRC._wow_chan[i], Channel)==0)
+ return true;
+ }
+ return false;
+}
+
+std::string GetWoWChannel(std::string Channel)
+{
+ for (int i=1;i < sIRC._chan_count + 1;i++)
+ {
+ if ("#" + sIRC._irc_chan[i] == Channel)
+ return sIRC._wow_chan[i];
+ }
+ return "";
+}
+
+std::string GetIRCChannel(std::string Channel)
+{
+ for (int i=1;i < sIRC._chan_count + 1;i++)
+ {
+ if (sIRC._wow_chan[i] == Channel)
+ return sIRC._irc_chan[i];
+ }
+ return "";
+}
+
+std::string* getArray(std::string PARAMS, int nCount, std::string)
+{
+ std::string *array = new std::string[nCount];
+ if (PARAMS.size() > 0)
+ {
+ int pcnt = 0;
+ size_t ps = 0;
+ size_t pc = -1;
+ for (int i = 0;i < nCount;i++)
+ {
+ pc = PARAMS.find(" ", pc + 1);
+ if (i + 1 == nCount && nCount != 1)
+ {
+ if (ps > 0 && pc > 0)
+ array[i] = PARAMS.substr(ps, PARAMS.size() - ps);
+ }
+ else
+ array[i] = PARAMS.substr(ps, pc - ps);
+ ps = pc + 1;
+ }
+ }
+ return array;
+}
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/IRCIO.cpp b/src/server/game/TriniChat/IRCIO.cpp
new file mode 100644
index 0000000..2fb364d
--- /dev/null
+++ b/src/server/game/TriniChat/IRCIO.cpp
@@ -0,0 +1,470 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#include "IRCClient.h"
+#include "IRCCmd.h"
+#include "IRCFunc.h"
+#include "ObjectAccessor.h"
+#include "ObjectMgr.h"
+#include "WorldPacket.h"
+#include "ChannelMgr.h"
+#include "Config.h"
+#include "Channel.h"
+#include "World.h"
+
+IRCCmd Command;
+void IRCClient::Handle_IRC(std::string sData)
+{
+ //sLog->outDebug(sData.c_str());
+ // If first 5 chars are ERROR then something is wrong
+ // either link is being closed, nickserv ghost command, etc...
+ if (sData.substr(0, 5) == "ERROR")
+ {
+ Disconnect();
+ return;
+ }
+ if (sData.substr(0, 4) == "PING")
+ {
+ // if the first 4 characters contain PING
+ // the server is checking if we are still alive
+ // sen back PONG back plus whatever the server send with it
+ SendIRC("PONG " + sData.substr(4, sData.size() - 4));
+ }
+ else
+ {
+ // if the first line contains : its an irc message
+ // such as private messages channel join etc.
+ if (sData.substr(0, 1) == ":")
+ {
+ // find the spaces in the receieved line
+ size_t p1 = sData.find(" ");
+ size_t p2 = sData.find(" ", p1 + 1);
+ // because the irc protocol uses simple spaces
+ // to seperate data we can easy pick them out
+ // since we know the position of the spaces
+ std::string USR = sData.substr(1, p1 - 1);
+ std::string CMD = sData.substr(p1 + 1, p2 - p1 - 1);
+ // trasform the commands to lowercase to make sure they always match
+ std::transform(CMD.begin(), CMD.end(), CMD.begin(), towlower);
+ // Extract the username from the first part
+ std::string szUser = GetUser(USR);
+ // if we receieved the internet connect code
+ // we know for sure that were in and we can
+ // authenticate ourself.
+ if (CMD == sIRC._ICC)
+ {
+ // _Auth is defined in trinitycore.conf (irc.auth)
+ // 0 do not authenticate
+ // 1 use nickserv
+ // 2 use quakenet
+ // aditionally you can provide you own authentication method here
+ switch(sIRC._Auth)
+ {
+ case 1:
+ SendIRC("PRIVMSG nickserv :IDENTIFY " + sIRC._Pass);
+ break;
+ case 2:
+ SendIRC("PRIVMSG nickserv :IDENTIFY " + sIRC._Auth_Nick + " " + sIRC._Pass);
+ break;
+ case 3:
+ SendIRC("PRIVMSG Q@CServe.quakenet.org :AUTH " + sIRC._Nick + " " + sIRC._Pass);
+ break;
+ case 4:
+ SendIRC("PRIVMSG Q@CServe.quakenet.org :AUTH " + sIRC._Auth_Nick + " " + sIRC._Pass);
+ break;
+ }
+ // if we join a default channel leave this now.
+ if (sIRC._ldefc==1)
+ SendIRC("PART #" + sIRC._defchan);
+ // Loop thru the channel array and send a command to join them on IRC.
+ for (int i=1;i < sIRC._chan_count + 1;i++)
+ {
+ if (sIRC._irc_pass[i].size() > 0)
+ SendIRC("JOIN #" + sIRC._irc_chan[i] + " " + sIRC._irc_pass[i]);
+ else
+ SendIRC("JOIN #" + sIRC._irc_chan[i]);
+ }
+ // See if there's a logchannel available, if so: join it.
+ if (sIRC.logchan.size() > 0)
+ {
+ if (sIRC.logchanpw.size() > 0)
+ SendIRC("JOIN #" + sIRC.logchan + " " + sIRC.logchanpw);
+ else
+ SendIRC("JOIN #" + sIRC.logchan);
+ }
+ }
+ // someone joined the channel this could be the bot or another user
+ if (CMD == "join")
+ {
+ size_t p = sData.find(":", p1);
+ std::string CHAN = sData.substr(p + 1, sData.size() - p - 2);
+ // if the user is us it means we join the channel
+ if ((szUser == sIRC._Nick))
+ {
+ // its us that joined the channel
+ Send_IRC_Channel(CHAN, MakeMsg(MakeMsg(sIRC.JoinMsg, "$Ver", sIRC._Mver.c_str()), "$Trigger", sIRC._cmd_prefx.c_str()), true);
+ }
+ else
+ {
+ // if the user is not us its someone else that joins
+ // so we construct a message and send this to the clients.
+ // TriniChat now uses Send_WoW_Channel to send to the client
+ // this makes TriniChat handle the packets instead of previously the world.
+ if ((sIRC.BOTMASK & 2) != 0)
+ Send_WoW_Channel(GetWoWChannel(CHAN).c_str(), IRCcol2WoW(MakeMsg(MakeMsg(GetChatLine(JOIN_IRC), "$Name", szUser), "$Channel", GetWoWChannel(CHAN))));
+ }
+ }
+ // someone on irc left or quit the channel
+ if (CMD == "part" || CMD == "quit")
+ {
+ size_t p3 = sData.find(" ", p2 + 1);
+ std::string CHAN = sData.substr(p2 + 1, p3 - p2 - 1);
+ // Logout IRC Nick From TriniChat If User Leaves Or Quits IRC.
+ if (Command.IsLoggedIn(szUser))
+ {
+ _CDATA CDATA;
+ CDATA.USER = szUser;
+ Command.Handle_Logout(&CDATA);
+ }
+ // Construct a message and inform the clients on the same channel.
+ if ((sIRC.BOTMASK & 2) != 0)
+ Send_WoW_Channel(GetWoWChannel(CHAN).c_str(), IRCcol2WoW(MakeMsg(MakeMsg(GetChatLine(LEAVE_IRC), "$Name", szUser), "$Channel", GetWoWChannel(CHAN))));
+ }
+ // someone changed their nick
+ if (CMD == "nick" && (sIRC.BOTMASK & 128) != 0)
+ {
+ MakeMsg(MakeMsg(GetChatLine(CHANGE_NICK), "$Name", szUser), "$NewName", sData.substr(sData.find(":", p2) + 1));
+ // If the user is logged in and changes their nick
+ // then we want to either log them out or update
+ // their nick in the bot. I chose to update the bots user list.
+ if (Command.IsLoggedIn(szUser))
+ {
+ std::string NewNick = sData.substr(sData.find(":", p2) + 1);
+ // On freenode I noticed the server sends an extra character
+ // at the end of the string, so we need to erase the last
+ // character of the string. if you have a problem with getting
+ // the last letter of your nick erased, then remove the - 1.
+ NewNick.erase(NewNick.length() - 1, 1);
+
+ for (std::list<_client*>::iterator i=Command._CLIENTS.begin(); i!=Command._CLIENTS.end();i++)
+ {
+ if ((*i)->Name == szUser)
+ {
+ (*i)->Name = NewNick;
+ sIRC.Send_IRC_Channel(NewNick.c_str(), "I Noticed You Changed Your Nick, I Have Updated My Internal Database Accordingly.", true, "NOTICE");
+
+ // Figure why not output to the logfile, makes tracing problems easier.
+ sIRC.iLog.WriteLog(" %s : %s Changed Nick To: %s", sIRC.iLog.GetLogDateTimeStr().c_str(), szUser.c_str(), NewNick.c_str());
+ }
+ }
+ }
+
+ }
+ // someone was kicked from irc
+ if (CMD == "kick")
+ {
+ // extract the details
+ size_t p3 = sData.find(" ", p2 + 1);
+ size_t p4 = sData.find(" ", p3 + 1);
+ size_t p5 = sData.find(":", p4);
+ std::string CHAN = sData.substr(p2 + 1, p3 - p2 - 1);
+ std::string WHO = sData.substr(p3 + 1, p4 - p3 - 1);
+ std::string BY = sData.substr(p4 + 1, sData.size() - p4 - 1);
+ // if the one kicked was us
+ if (WHO == sIRC._Nick)
+ {
+ // and autojoin is enabled
+ // return to the channel
+ if (sIRC._autojoinkick == 1)
+ {
+ SendIRC("JOIN " + CHAN);
+ Send_IRC_Channel(CHAN, sIRC.kikmsg, true);
+ }
+ }
+ else
+ {
+ // if it is not us who was kicked we need to inform the clients someone
+ // was removed from the channel
+ // construct a message and send it to the players.
+ Send_WoW_Channel(GetWoWChannel(CHAN).c_str(), "<IRC>[" + WHO + "]: Was Kicked From " + CHAN + " By: " + szUser);
+ }
+ }
+ // a private chat message was receieved.
+ if (CMD == "privmsg" || CMD == "notice")
+ {
+ // extract the values
+ size_t p = sData.find(" ", p2 + 1);
+ std::string FROM = sData.substr(p2 + 1, p - p2 - 1);
+ std::string CHAT = sData.substr(p + 2, sData.size() - p - 3);
+ // if this is our username it means we recieved a PM
+ if (FROM == sIRC._Nick)
+ {
+ if (CHAT.find("\001VERSION\001") < CHAT.size())
+ {
+ Send_IRC_Channel(szUser, MakeMsg("\001VERSION TriniChat %s ?2008-2009 |Death|, Cybrax, Machiavelli\001", "%s" , sIRC._Mver.c_str()), true, "PRIVMSG");
+ }
+ // a pm is required for certain commands
+ // such as login. to validate the command
+ // we send it to the command class wich handles
+ // evrything else.
+ Command.IsValid(szUser, FROM, CHAT, CMD);
+ }
+ else
+ {
+ // if our name is not in it, it means we receieved chat on one of the channels
+ // magchat is in. the first thing we do is check if it is a command or not
+ if (!Command.IsValid(szUser, FROM, CHAT, CMD))
+ {
+ Send_WoW_Channel(GetWoWChannel(FROM).c_str(), IRCcol2WoW(MakeMsg(MakeMsg(GetChatLine(IRC_WOW), "$Name", szUser), "$Msg", CHAT)));
+ }
+ // if we indeed receieved a command we do not want to display this to the players
+ // so only incanse the isvalid command returns false it will be sent to all player.
+ // the isvalid function will automaitcly process the command on true.
+ }
+ }
+ if (CMD == "mode")
+ {
+ // extract the mode details
+ size_t p3 = sData.find(" ", p2 + 1);
+ size_t p4 = sData.find(" ", p3 + 1);
+ size_t p5 = sData.find(" ", p4 + 1);
+ std::string CHAN = sData.substr(p2 + 1, p3 - p2 - 1);
+ std::string MODE = sData.substr(p3 + 1, p4 - p3 - 1);
+ std::string NICK = sData.substr(p4 + 1, p5 - p4 - 1);
+ bool _AmiOp;
+ _AmiOp = false;
+ //A mode was changed on us
+ if (NICK.c_str() == sIRC._Nick)
+ _AmiOp = true;
+
+ }
+ }
+ }
+}
+
+// This function is called in Channel.h
+// based on nAction it will inform the people on
+// irc when someone leaves one of the game channels.
+// nAction is based on the struct CACTION
+void IRCClient::Handle_WoW_Channel(std::string Channel, Player *plr, int nAction)
+{
+ // make sure that we are connected
+ if (sIRC.Connected && (sIRC.BOTMASK & 1)!= 0)
+ {
+ if (Channel_Valid(Channel))
+ {
+ std::string GMRank = "";
+ std::string pname = plr->GetName().c_str();
+ bool DoGMAnnounce = false;
+ if (plr->GetSession()->GetSecurity() > 0 && (sIRC.BOTMASK & 8)!= 0)
+ DoGMAnnounce = true;
+ if (plr->isGameMaster() && (sIRC.BOTMASK & 16)!= 0)
+ DoGMAnnounce = true;
+ if (DoGMAnnounce)
+ {
+ switch(plr->GetSession()->GetSecurity()) //switch case to determine what rank the "gm" is
+ {
+ case 0: GMRank = "";break;
+ case 1: GMRank = "\0037"+sIRC.ojGM1;break;
+ case 2: GMRank = "\0037"+sIRC.ojGM2;break;
+ case 3: GMRank = "\0037"+sIRC.ojGM3;break;
+ case 4: GMRank = "\0037"+sIRC.ojGM4;break;
+ case 5: GMRank = "\0037"+sIRC.ojGM5;break;
+ case 6: GMRank = "\0037"+sIRC.ojGM6;break;
+ case 7: GMRank = "\0037"+sIRC.ojGM7;break;
+ case 8: GMRank = "\0037"+sIRC.ojGM8;break;
+ }
+ }
+ std::string ChatTag = "";
+ switch (plr->GetTeam())
+ {
+ case 67:ChatTag.append("\0034");break; //horde
+ case 469:ChatTag.append("\00312");break; //alliance
+ }
+ std::string query = "INSERT INTO `irc_inchan` VALUES (%d,'"+pname+"','"+Channel+"')";
+ std::string lchan = "DELETE FROM `irc_inchan` WHERE `guid` = %d AND `channel` = '"+Channel+"'";
+ switch(nAction)
+ {
+ case CHANNEL_JOIN:
+ Send_IRC_Channel(GetIRCChannel(Channel), MakeMsg(MakeMsg(MakeMsg(GetChatLine(JOIN_WOW), "$Name", ChatTag + plr->GetName().c_str()), "$Channel", Channel), "$GM", GMRank));
+ WorldDatabase.PExecute(lchan.c_str(), plr->GetGUID());
+ WorldDatabase.PExecute(query.c_str(), plr->GetGUID());
+ break;
+ case CHANNEL_LEAVE:
+ Send_IRC_Channel(GetIRCChannel(Channel), MakeMsg(MakeMsg(MakeMsg(GetChatLine(LEAVE_WOW), "$Name", ChatTag + plr->GetName().c_str()), "$Channel", Channel), "$GM", GMRank));
+ WorldDatabase.PExecute(lchan.c_str(), plr->GetGUID());
+ break;
+ }
+ }
+ }
+}
+
+// This function sends chat to a irc channel or user
+// to prevent the # beeing appended to send a msg to a user
+// set the NoPrefix to true
+void IRCClient::Send_IRC_Channel(std::string sChannel, std::string sMsg, bool NoPrefix, std::string nType)
+{
+ std::string mType = "PRIVMSG";
+ if (Command.MakeUpper(nType.c_str()) == "NOTICE")
+ mType = "NOTICE";
+ if (Command.MakeUpper(nType.c_str()) == "ERROR" && (sIRC.BOTMASK & 32)!= 0)
+ mType = "NOTICE";
+ if (sIRC.Connected)
+ {
+ if (NoPrefix)
+ SendIRC(mType + " " + sChannel + " :" + sMsg);
+ else
+ SendIRC(mType + " #" + sChannel + " :" + sMsg);
+ }
+}
+
+// This function sends a message to all irc channels
+// that TriniChat has in its configuration
+void IRCClient::Send_IRC_Channels(std::string sMsg)
+{
+ for (int i=1;i < sIRC._chan_count + 1;i++)
+ Send_IRC_Channel(sIRC._irc_chan[i], sMsg);
+}
+
+// This function is called in ChatHandler.cpp, any channel chat from wow will come
+// to this function, validates the channel and constructs a message that is send to IRC
+void IRCClient::Send_WoW_IRC(Player *plr, std::string Channel, std::string Msg)
+{
+ // Check if the channel exist in our configuration
+ if (Channel_Valid(Channel) && Msg.substr(0, 1) != ".")
+ Send_IRC_Channel(GetIRCChannel(Channel), MakeMsgP(WOW_IRC, Msg, plr));
+}
+
+void IRCClient::Send_WoW_Player(std::string sPlayer, std::string sMsg)
+{
+ normalizePlayerName(sPlayer);
+ if (Player* plr = sObjectAccessor->FindPlayerByName(sPlayer.c_str()))
+ Send_WoW_Player(plr, sMsg);
+}
+
+void IRCClient::Send_WoW_Player(Player *plr, string sMsg)
+{
+ WorldPacket data(SMSG_MESSAGECHAT, 200);
+ data << (uint8)CHAT_MSG_SYSTEM;
+ data << (uint32)LANG_UNIVERSAL;
+ data << (uint64)plr->GetGUID();
+ data << (uint32)0;
+ data << (uint64)plr->GetGUID();
+ data << (uint32)(sMsg.length()+1);
+ data << sMsg;
+ data << (uint8)0;
+ plr->GetSession()->SendPacket(&data);
+}
+
+// This function will construct and send a packet to all players
+// on the given channel ingame. (previuosly found in world.cpp)
+// it loops thru all sessions and checks if they are on the channel
+// if so construct a packet and send it.
+void IRCClient::Send_WoW_Channel(const char *channel, std::string chat)
+{
+ if (!(strlen(channel) > 0))
+ return;
+
+ #ifdef USE_UTF8
+ std::string chat2 = chat;
+ if (ConvertUTF8(chat2.c_str(), chat2))
+ chat = chat2;
+ #endif
+
+ HashMapHolder<Player>::MapType const& m = sObjectAccessor->GetPlayers();
+ for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
+ {
+ if (itr->second && itr->second->GetSession()->GetPlayer() && itr->second->GetSession()->GetPlayer()->IsInWorld())
+ {
+ if (ChannelMgr* cMgr = ChannelMgr::forTeam(itr->second->GetSession()->GetPlayer()->GetTeam()))
+ {
+ if (Channel *chn = cMgr->GetChannel(channel, itr->second->GetSession()->GetPlayer()))
+ {
+ WorldPacket data;
+ data.Initialize(SMSG_MESSAGECHAT);
+ data << (uint8)CHAT_MSG_CHANNEL;
+ data << (uint32)LANG_UNIVERSAL;
+ data << (uint64)0;
+ data << (uint32)0;
+ data << channel;
+ data << (uint64)0;
+ data << (uint32) (strlen(chat.c_str()) + 1);
+ data << IRCcol2WoW(chat.c_str());
+ data << (uint8)0;
+ itr->second->GetSession()->SendPacket(&data);
+ }
+ }
+ }
+ }
+}
+
+void IRCClient::Send_WoW_System(std::string Message)
+{
+ HashMapHolder<Player>::MapType const& m = sObjectAccessor->GetPlayers();
+ for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
+ {
+ if (itr->second && itr->second->GetSession()->GetPlayer() && itr->second->GetSession()->GetPlayer()->IsInWorld())
+ {
+ WorldPacket data;
+ data.Initialize(CHAT_MSG_SYSTEM);
+ data << (uint8)CHAT_MSG_SYSTEM;
+ data << (uint32)LANG_UNIVERSAL;
+ data << (uint64)0;
+ data << (uint32)0;
+ data << (uint64)0;
+ data << (uint32) (strlen(Message.c_str()) + 1);
+ data << Message.c_str();
+ data << (uint8)0;
+ itr->second->GetSession()->SendPacket(&data);
+ }
+ }
+}
+void IRCClient::ResetIRC()
+{
+ SendData("QUIT");
+ Disconnect();
+}
+
+#define CHAT_INVITE_NOTICE 0x18
+
+// this function should be called on player login Player::AddToWorld
+void IRCClient::AutoJoinChannel(Player *plr)
+{
+ //this will work if at least 1 player is logged in regrdless if he is on the channel or not
+ // the first person that login empty server is the one with bad luck and wont be invited,
+ // if at least 1 player is online the player will be inited to the chanel
+
+ std::string m_name = sIRC.ajchan;
+ WorldPacket data;
+ data.Initialize(SMSG_CHANNEL_NOTIFY, 1+m_name.size()+1);
+ data << uint8(CHAT_INVITE_NOTICE);
+ data << m_name.c_str();
+
+ HashMapHolder<Player>::MapType const& m = sObjectAccessor->GetPlayers();
+ for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
+ {
+ if (itr->second && itr->second->GetSession()->GetPlayer() && itr->second->GetSession()->GetPlayer()->IsInWorld())
+ {
+ data << uint64(itr->second->GetGUID());
+ break;
+ }
+ }
+ plr->GetSession()->SendPacket(&data);
+}
\ No newline at end of file
diff --git a/src/server/game/TriniChat/IRCLog.cpp b/src/server/game/TriniChat/IRCLog.cpp
new file mode 100644
index 0000000..bdc053a
--- /dev/null
+++ b/src/server/game/TriniChat/IRCLog.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#include "IRCLog.h"
+#include "Config.h"
+#include "IRCClient.h"
+#include <stdarg.h>
+#include "World.h"
+
+IRCLog::IRCLog()
+{
+ std::string logsDir = ConfigMgr::GetStringDefault("LogsDir","");
+ std::string ircLogName = logsDir + "/IRC_";
+ std::string ircLogTimestamp = GetLogDateStr();
+ ircLogName += ircLogTimestamp +".log";
+ ircLogfile.open (ircLogName.c_str(), std::ios::app);
+}
+
+IRCLog::~IRCLog()
+{
+ ircLogfile.close();
+}
+// Was added because using the time for logs is very annoying... one log per day.. much cleaner looking..
+std::string IRCLog::GetLogDateStr() const
+{
+ time_t t = time(NULL);
+ tm* aTm = localtime(&t);
+ // YYYY year
+ // MM month (2 digits 01-12)
+ // DD day (2 digits 01-31)
+ // HH hour (2 digits 00-23)
+ // MM minutes (2 digits 00-59)
+ // SS seconds (2 digits 00-59)
+ char buf[20];
+ snprintf(buf,20,"%04d-%02d-%02d",aTm->tm_year+1900,aTm->tm_mon+1,aTm->tm_mday);
+ return std::string(buf);
+}
+
+std::string IRCLog::GetLogDateTimeStr() const
+{
+ time_t t = time(NULL);
+ tm* aTm = localtime(&t);
+ // YYYY year
+ // MM month (2 digits 01-12)
+ // DD day (2 digits 01-31)
+ // HH hour (2 digits 00-23)
+ // MM minutes (2 digits 00-59)
+ // SS seconds (2 digits 00-59)
+ char buf[30];
+ snprintf(buf,30,"[ %04d-%02d-%02d ] [ %02d:%02d:%02d ]",aTm->tm_year+1900,aTm->tm_mon+1,aTm->tm_mday,aTm->tm_hour,aTm->tm_min,aTm->tm_sec);
+ return std::string(buf);
+}
+
+void IRCLog::WriteLog(const char *what, ...)
+{
+ va_list ap;
+ char tmpoutp[1024];
+ va_start(ap, what);
+ vsnprintf(tmpoutp, 1024, what, ap);
+ va_end(ap);
+ ircLogfile << tmpoutp;
+ ircLogfile << "\n";
+ ircLogfile.flush();
+}
\ No newline at end of file
diff --git a/src/server/game/TriniChat/IRCLog.h b/src/server/game/TriniChat/IRCLog.h
new file mode 100644
index 0000000..945cbc1
--- /dev/null
+++ b/src/server/game/TriniChat/IRCLog.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef _IRC_LOG_H
+#define _IRC_LOG_H
+
+#include "Common.h"
+#include <fstream>
+
+class IRCLog
+{
+ public:
+ IRCLog();
+ ~IRCLog();
+
+ public:
+ void WriteLog(const char *what, ...);
+ std::string GetLogDateStr() const;
+ std::string GetLogDateTimeStr() const;
+ private:
+ std::ofstream ircLogfile;
+};
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/IRCSock.cpp b/src/server/game/TriniChat/IRCSock.cpp
new file mode 100644
index 0000000..9e776bd
--- /dev/null
+++ b/src/server/game/TriniChat/IRCSock.cpp
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#include "IRCClient.h"
+#define MAXDATASIZE 512
+#include <fcntl.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+
+
+#define _UNICODE
+
+#ifdef _MBCS
+#undef _MBCS
+#endif
+
+bool IRCClient::InitSock()
+{
+ #ifdef _WIN32
+ WSADATA wsaData; //WSAData
+ if (WSAStartup(MAKEWORD(2,0),&wsaData) != 0)
+ {
+ sLog->outError(LOG_FILTER_GENERAL, "IRC Error: Winsock Initialization Error");
+ return false;
+ }
+ #endif
+ if ((sIRC.SOCKET = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
+ {
+ sLog->outError(LOG_FILTER_GENERAL, "IRC Error: Socket Error");
+ return false;
+ }
+ int on = 1;
+ if (setsockopt (sIRC.SOCKET, SOL_SOCKET, SO_REUSEADDR, (const char*) &on, sizeof (on)) == -1)
+ {
+ sLog->outError(LOG_FILTER_GENERAL, "IRC Error: Invalid Socket");
+ return false;
+ }
+ #ifdef _WIN32
+ u_long iMode = 0;
+ ioctlsocket(sIRC.SOCKET, FIONBIO, &iMode);
+ #else
+ fcntl(sIRC.SOCKET, F_SETFL, O_NONBLOCK); // set to non-blocking
+ fcntl(sIRC.SOCKET, F_SETFL, O_ASYNC); // set to asynchronous I/O
+ #endif
+ return true;
+}
+
+bool IRCClient::Connect(const char *cHost, int nPort)
+{
+ sIRC.Connected = false;
+ struct hostent *he;
+ if ((he=gethostbyname(cHost)) == NULL)
+ {
+ sLog->outError(LOG_FILTER_GENERAL, "IRCLIENT: Could not resolve host: %s", cHost);
+ return false;
+ }
+ struct sockaddr_in their_addr;
+ their_addr.sin_family = AF_INET;
+ their_addr.sin_port = htons(nPort);
+ their_addr.sin_addr = *((struct in_addr *)he->h_addr);
+ memset(&(their_addr.sin_zero), '\0', 8);
+ if (::connect(sIRC.SOCKET, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1)
+ {
+ sLog->outError(LOG_FILTER_GENERAL, "IRCLIENT: Cannot connect to %s", cHost);
+ return false;
+ }
+ //FD_ZERO(&sIRC.sfdset);
+ //FD_SET(sIRC.SOCKET,&sIRC.sfdset);
+ sIRC.Connected = true;
+ return true;
+}
+
+bool IRCClient::Login(std::string sNick, std::string sUser, std::string sPass)
+{
+ char hostname[128];
+ gethostname(hostname, sizeof(hostname));
+ if (SendIRC("HELLO"))
+ if (SendIRC("PASS " + sPass))
+ if (SendIRC("NICK " + sNick))
+ if (SendIRC("USER " + sUser + " " + (std::string)hostname + " TriniChat :TriniChat "+sIRC._Mver.c_str()))
+ return true;
+ return false;
+}
+
+bool IRCClient::SendData(const char *data)
+{
+ if (sIRC.Connected)
+ {
+ if (send(sIRC.SOCKET, data, strlen(data), 0) == -1)
+ {
+ sLog->outError(LOG_FILTER_GENERAL, "IRC Error: Socket Receieve ** \n");
+ //Disconnect();
+ return false;
+ }
+ }
+ return true;
+}
+
+bool IRCClient::SendIRC(std::string data)
+{
+ std::string RealData = data + "\n";
+ return SendData(RealData.c_str());
+}
+
+void IRCClient::Disconnect()
+{
+ if (sIRC.SOCKET)
+ {
+ #ifdef _WIN32
+ closesocket(sIRC.SOCKET);
+ //WSACleanup();
+ #else
+ close(sIRC.SOCKET);
+ #endif
+ }
+}
+
+void IRCClient::SockRecv()
+{
+// wchar_t bufferdata;
+
+ char szBuffer[MAXDATASIZE];
+
+ memset(szBuffer, 0, MAXDATASIZE);
+
+ int nBytesRecv = ::recv(sIRC.SOCKET, szBuffer, MAXDATASIZE - 1, 0);
+ if (nBytesRecv == -1)
+ {
+ sLog->outError(LOG_FILTER_GENERAL, "Connection lost.");
+ sIRC.Connected = false;
+ }
+ else
+ {
+ if (-1 == nBytesRecv)
+ {
+ sLog->outError(LOG_FILTER_GENERAL, "Error occurred while receiving from socket.");
+ }
+ else
+ {
+ std::string reply;
+ std::istringstream iss(szBuffer);
+ while (getline(iss, reply))
+ {
+ Handle_IRC(reply);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/server/game/TriniChat/MCS_OnlinePlayers.cpp b/src/server/game/TriniChat/MCS_OnlinePlayers.cpp
new file mode 100644
index 0000000..7455f22
--- /dev/null
+++ b/src/server/game/TriniChat/MCS_OnlinePlayers.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#include "MCS_OnlinePlayers.h"
+
+#include "MapManager.h"
+#include "ObjectMgr.h"
+#include "Config.h"
+
+mcs_OnlinePlayers::mcs_OnlinePlayers() { CD = NULL; }
+
+mcs_OnlinePlayers::mcs_OnlinePlayers(_CDATA *_CD)
+{
+ //create a new instance of data struct and copy its data
+ CD = new _CDATA();
+ CD->CMD = _CD->CMD;
+ CD->FROM = _CD->FROM;
+ CD->PARAMS = _CD->PARAMS;
+ CD->PCOUNT = _CD->PCOUNT;
+ CD->USER = _CD->USER;
+ CD->TYPE = _CD->TYPE;
+}
+
+mcs_OnlinePlayers::~mcs_OnlinePlayers()
+{
+ if (CD)
+ delete CD;
+}
+
+void mcs_OnlinePlayers::run()
+{
+ int OnlineCount = 0;
+ std::string IRCOut = "";
+ HashMapHolder<Player>::MapType const& m = sObjectAccessor->GetPlayers();
+ for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
+ {
+ if (itr->second && itr->second->GetSession()->GetPlayer() && itr->second->GetSession()->GetPlayer()->IsInWorld())
+ {
+ OnlineCount++;
+ Player *plr = itr->second->GetSession()->GetPlayer();
+ std::string ChatTag = " ";
+ switch(plr->GetSession()->GetSecurity())
+ {
+ case 0: ChatTag.append("");break;
+ case 1: ChatTag.append("\0037"+sIRC.ojGM1);break;
+ case 2: ChatTag.append("\0037"+sIRC.ojGM2);break;
+ case 3: ChatTag.append("\0037"+sIRC.ojGM3);break;
+ case 4: ChatTag.append("\0037"+sIRC.ojGM4);break;
+ case 5: ChatTag.append("\0037"+sIRC.ojGM5);break;
+ case 6: ChatTag.append("\0037"+sIRC.ojGM6);break;
+ case 7: ChatTag.append("\0037"+sIRC.ojGM7);break;
+ case 8: ChatTag.append("\0037"+sIRC.ojGM8);break;
+ }
+ if (plr->isAFK())
+ ChatTag.append("\002\0037<AFK>\003\002");
+ else if (plr->isDND())
+ ChatTag.append("\002\0037<DND>\003\002");
+ switch (plr->GetTeam())
+ {
+ case 67:ChatTag.append("\0034");break; //horde
+ case 469:ChatTag.append("\00312");break; //alliance
+ }
+
+ IRCOut.append(IRCCmd::MakeMsg("%s\002%s\003\017\002(%d)\002\017", ChatTag.c_str(), plr->GetName().c_str(), plr->getLevel()));
+
+ // after XX players have been added to the string
+ // output to irc and reset for the next XX
+ if (OnlineCount % sIRC.onlrslt == 0)
+ {
+ sIRC.Send_IRC_Channel(IRCCmd::ChanOrPM(CD), IRCCmd::MakeMsg("\002 %s", IRCOut.c_str()), true, CD->TYPE.c_str());
+ IRCOut = "";
+ ACE_Based::Thread::Sleep(1000);
+ }
+ }
+ }
+ // Remainder in IRCOUT && Total plyersonline
+ sIRC.Send_IRC_Channel(IRCCmd::ChanOrPM(CD), IRCCmd::MakeMsg("\002Players Online(%d):\017 %s", OnlineCount, IRCOut.c_str()), true, CD->TYPE);
+
+ sIRC.Script_Lock[MCS_Players_Online] = false;
+}
\ No newline at end of file
diff --git a/src/server/game/TriniChat/MCS_OnlinePlayers.h b/src/server/game/TriniChat/MCS_OnlinePlayers.h
new file mode 100644
index 0000000..9e4276b
--- /dev/null
+++ b/src/server/game/TriniChat/MCS_OnlinePlayers.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef _IRC_CLIENT_ONLINE
+#define _IRC_CLIENT_ONLINE
+
+#include "IRCClient.h"
+#include "IRCCmd.h"
+
+class mcs_OnlinePlayers : public ACE_Based::Runnable
+{
+ public:
+ mcs_OnlinePlayers();
+ mcs_OnlinePlayers(_CDATA *_CD);
+ ~mcs_OnlinePlayers();
+ void run();
+ public:
+ _CDATA *CD;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/CMakeLists.txt b/src/server/game/TriniChat/framework/CMakeLists.txt
new file mode 100644
index 0000000..50bbb99
--- /dev/null
+++ b/src/server/game/TriniChat/framework/CMakeLists.txt
@@ -0,0 +1,11 @@
+SET(trinityframework_STAT_SRCS
+ Policies/ObjectLifeTime.cpp
+ Utilities/EventProcessor.cpp
+)
+
+include_directories(
+ ${ACE_INCLUDE_DIR}
+ ${CMAKE_SOURCE_DIR}/src/framework
+)
+
+add_library(trinityframework STATIC ${trinityframework_STAT_SRCS})
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Dynamic/FactoryHolder.h b/src/server/game/TriniChat/framework/Dynamic/FactoryHolder.h
new file mode 100644
index 0000000..11c0929
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Dynamic/FactoryHolder.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_FACTORY_HOLDER
+#define TRINITY_FACTORY_HOLDER
+
+#include "Platform/Define.h"
+#include "Utilities/TypeList.h"
+#include "ObjectRegistry.h"
+#include "Policies/SingletonImp.h"
+
+/** FactoryHolder holds a factory object of a specific type
+ */
+template<class T, class Key = std::string>
+class FactoryHolder
+{
+ public:
+ typedef ObjectRegistry<FactoryHolder<T, Key >, Key > FactoryHolderRegistry;
+ typedef Trinity::Singleton<FactoryHolderRegistry > FactoryHolderRepository;
+
+ FactoryHolder(Key k) : i_key(k) {}
+ virtual ~FactoryHolder() {}
+ inline Key key() const { return i_key; }
+
+ void RegisterSelf(void) { FactoryHolderRepository::Instance().InsertItem(this, i_key); }
+ void DeregisterSelf(void) { FactoryHolderRepository::Instance().RemoveItem(this, false); }
+
+ /// Abstract Factory create method
+ virtual T* Create(void *data = NULL) const = 0;
+ private:
+ Key i_key;
+};
+
+/** Permissible is a classic way of letting the object decide
+ * whether how good they handle things. This is not retricted
+ * to factory selectors.
+ */
+template<class T>
+class Permissible
+{
+ public:
+ virtual ~Permissible() {}
+ virtual int Permit(const T *) const = 0;
+};
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Dynamic/ObjectRegistry.h b/src/server/game/TriniChat/framework/Dynamic/ObjectRegistry.h
new file mode 100644
index 0000000..5474c31
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Dynamic/ObjectRegistry.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_OBJECTREGISTRY_H
+#define TRINITY_OBJECTREGISTRY_H
+
+#include "Platform/Define.h"
+#include "Utilities/UnorderedMap.h"
+#include "Policies/Singleton.h"
+
+#include <string>
+#include <vector>
+#include <map>
+
+/** ObjectRegistry holds all registry item of the same type
+ */
+template<class T, class Key = std::string>
+class ObjectRegistry
+{
+ public:
+ typedef std::map<Key, T *> RegistryMapType;
+
+ /// Returns a registry item
+ const T* GetRegistryItem(Key key) const
+ {
+ typename RegistryMapType::const_iterator iter = i_registeredObjects.find(key);
+ return( iter == i_registeredObjects.end() ? NULL : iter->second );
+ }
+
+ /// Inserts a registry item
+ bool InsertItem(T *obj, Key key, bool override = false)
+ {
+ typename RegistryMapType::iterator iter = i_registeredObjects.find(key);
+ if( iter != i_registeredObjects.end() )
+ {
+ if( !override )
+ return false;
+ delete iter->second;
+ i_registeredObjects.erase(iter);
+ }
+
+ i_registeredObjects[key] = obj;
+ return true;
+ }
+
+ /// Removes a registry item
+ void RemoveItem(Key key, bool delete_object = true)
+ {
+ typename RegistryMapType::iterator iter = i_registeredObjects.find(key);
+ if( iter != i_registeredObjects.end() )
+ {
+ if( delete_object )
+ delete iter->second;
+ i_registeredObjects.erase(iter);
+ }
+ }
+
+ /// Returns true if registry contains an item
+ bool HasItem(Key key) const
+ {
+ return (i_registeredObjects.find(key) != i_registeredObjects.end());
+ }
+
+ /// Inefficiently return a vector of registered items
+ unsigned int GetRegisteredItems(std::vector<Key> &l) const
+ {
+ unsigned int sz = l.size();
+ l.resize(sz + i_registeredObjects.size());
+ for (typename RegistryMapType::const_iterator iter = i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter)
+ l[sz++] = iter->first;
+ return i_registeredObjects.size();
+ }
+
+ /// Return the map of registered items
+ RegistryMapType const &GetRegisteredItems() const
+ {
+ return i_registeredObjects;
+ }
+
+ private:
+ RegistryMapType i_registeredObjects;
+ friend class Trinity::OperatorNew<ObjectRegistry<T, Key> >;
+
+ // protected for friend use since it should be a singleton
+ ObjectRegistry() {}
+ ~ObjectRegistry()
+ {
+ for (typename RegistryMapType::iterator iter=i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter)
+ delete iter->second;
+ i_registeredObjects.clear();
+ }
+};
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/GameSystem/Grid.h b/src/server/game/TriniChat/framework/GameSystem/Grid.h
new file mode 100644
index 0000000..2cb2527
--- /dev/null
+++ b/src/server/game/TriniChat/framework/GameSystem/Grid.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_GRID_H
+#define TRINITY_GRID_H
+
+/*
+ @class Grid
+ Grid is a logical segment of the game world represented inside TrinIty.
+ Grid is bind at compile time to a particular type of object which
+ we call it the object of interested. There are many types of loader,
+ specially, dynamic loader, static loader, or on-demand loader. There's
+ a subtle difference between dynamic loader and on-demand loader but
+ this is implementation specific to the loader class. From the
+ Grid's perspective, the loader meets its API requirement is suffice.
+*/
+
+#include "Platform/Define.h"
+#include "Policies/ThreadingModel.h"
+#include "TypeContainer.h"
+#include "TypeContainerVisitor.h"
+
+// forward declaration
+template<class A, class T, class O> class GridLoader;
+
+template
+<
+class ACTIVE_OBJECT,
+class WORLD_OBJECT_TYPES,
+class GRID_OBJECT_TYPES,
+class ThreadModel = Trinity::SingleThreaded<ACTIVE_OBJECT>
+>
+class Grid
+{
+ // allows the GridLoader to access its internals
+ template<class A, class T, class O> friend class GridLoader;
+ public:
+
+ /** destructor to clean up its resources. This includes unloading the
+ grid if it has not been unload.
+ */
+ ~Grid() {}
+
+ /** an object of interested enters the grid
+ */
+ template<class SPECIFIC_OBJECT> void AddWorldObject(SPECIFIC_OBJECT *obj)
+ {
+ if(!i_objects.template insert<SPECIFIC_OBJECT>(obj))
+ assert(false);
+ }
+
+ /** an object of interested exits the grid
+ */
+ template<class SPECIFIC_OBJECT> void RemoveWorldObject(SPECIFIC_OBJECT *obj)
+ {
+ if(!i_objects.template remove<SPECIFIC_OBJECT>(obj))
+ assert(false);
+ }
+
+ /** Refreshes/update the grid. This required for remote grids.
+ */
+ void RefreshGrid(void) { /* TBI */}
+
+ /** Locks a grid. Any object enters must wait until the grid is unlock.
+ */
+ void LockGrid(void) { /* TBI */ }
+
+ /** Unlocks the grid.
+ */
+ void UnlockGrid(void) { /* TBI */ }
+
+ /** Grid visitor for grid objects
+ */
+ template<class T> void Visit(TypeContainerVisitor<T, TypeMapContainer<GRID_OBJECT_TYPES> > &visitor)
+ {
+ visitor.Visit(i_container);
+ }
+
+ /** Grid visitor for world objects
+ */
+ template<class T> void Visit(TypeContainerVisitor<T, TypeMapContainer<WORLD_OBJECT_TYPES> > &visitor)
+ {
+ visitor.Visit(i_objects);
+ }
+
+ /** Returns the number of object within the grid.
+ */
+ unsigned int ActiveObjectsInGrid(void) const { return /*m_activeGridObjects.size()+*/i_objects.template Count<ACTIVE_OBJECT>(); }
+
+ /** Inserts a container type object into the grid.
+ */
+ template<class SPECIFIC_OBJECT> void AddGridObject(SPECIFIC_OBJECT *obj)
+ {
+ if(!i_container.template insert<SPECIFIC_OBJECT>(obj))
+ assert(false);
+ }
+
+ /** Removes a containter type object from the grid
+ */
+ template<class SPECIFIC_OBJECT> void RemoveGridObject(SPECIFIC_OBJECT *obj)
+ {
+ if(!i_container.template remove<SPECIFIC_OBJECT>(obj))
+ assert(false);
+ }
+
+ /*bool NoWorldObjectInGrid() const
+ {
+ return i_objects.GetElements().isEmpty();
+ }
+
+ bool NoGridObjectInGrid() const
+ {
+ return i_container.GetElements().isEmpty();
+ }*/
+ private:
+
+ typedef typename ThreadModel::Lock Guard;
+ typedef typename ThreadModel::VolatileType VolatileType;
+
+ TypeMapContainer<GRID_OBJECT_TYPES> i_container;
+ TypeMapContainer<WORLD_OBJECT_TYPES> i_objects;
+ //typedef std::set<void*> ActiveGridObjects;
+ //ActiveGridObjects m_activeGridObjects;
+};
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/GameSystem/GridLoader.h b/src/server/game/TriniChat/framework/GameSystem/GridLoader.h
new file mode 100644
index 0000000..847e7d4
--- /dev/null
+++ b/src/server/game/TriniChat/framework/GameSystem/GridLoader.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_GRIDLOADER_H
+#define TRINITY_GRIDLOADER_H
+
+/**
+ @class GridLoader
+ The GridLoader is working in conjuction with the Grid and responsible
+ for loading and unloading object-types (one or more) when objects
+ enters a grid. Unloading is scheduled and might be canceled if
+ an interested object re-enters. GridLoader does not do the actuall
+ loading and unloading but implements as a template pattern that
+ delicate its loading and unloading for the actualy loader and unloader.
+ GridLoader manages the grid (both local and remote).
+ */
+
+#include "Platform/Define.h"
+#include "Grid.h"
+#include "TypeContainerVisitor.h"
+
+template
+<
+class ACTIVE_OBJECT,
+class WORLD_OBJECT_TYPES,
+class GRID_OBJECT_TYPES
+>
+class GridLoader
+{
+ public:
+
+ /** Loads the grid
+ */
+ template<class LOADER>
+ void Load(Grid<ACTIVE_OBJECT,WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> &grid, LOADER &loader)
+ {
+ grid.LockGrid();
+ loader.Load(grid);
+ grid.UnlockGrid();
+ }
+
+ /** Stop the grid
+ */
+ template<class STOPER>
+ void Stop(Grid<ACTIVE_OBJECT,WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> &grid, STOPER &stoper)
+ {
+ grid.LockGrid();
+ stoper.Stop(grid);
+ grid.UnlockGrid();
+ }
+ /** Unloads the grid
+ */
+ template<class UNLOADER>
+ void Unload(Grid<ACTIVE_OBJECT,WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> &grid, UNLOADER &unloader)
+ {
+ grid.LockGrid();
+ unloader.Unload(grid);
+ grid.UnlockGrid();
+ }
+};
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/GameSystem/GridRefManager.h b/src/server/game/TriniChat/framework/GameSystem/GridRefManager.h
new file mode 100644
index 0000000..be9c02d
--- /dev/null
+++ b/src/server/game/TriniChat/framework/GameSystem/GridRefManager.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef _GRIDREFMANAGER
+#define _GRIDREFMANAGER
+
+#include "Utilities/LinkedReference/RefManager.h"
+
+template<class OBJECT>
+class GridReference;
+
+template<class OBJECT>
+class GridRefManager : public RefManager<GridRefManager<OBJECT>, OBJECT>
+{
+ public:
+ typedef LinkedListHead::Iterator< GridReference<OBJECT> > iterator;
+
+ GridReference<OBJECT>* getFirst() { return (GridReference<OBJECT>*)RefManager<GridRefManager<OBJECT>, OBJECT>::getFirst(); }
+ GridReference<OBJECT>* getLast() { return (GridReference<OBJECT>*)RefManager<GridRefManager<OBJECT>, OBJECT>::getLast(); }
+
+ iterator begin() { return iterator(getFirst()); }
+ iterator end() { return iterator(NULL); }
+ iterator rbegin() { return iterator(getLast()); }
+ iterator rend() { return iterator(NULL); }
+};
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/GameSystem/GridReference.h b/src/server/game/TriniChat/framework/GameSystem/GridReference.h
new file mode 100644
index 0000000..e89180e
--- /dev/null
+++ b/src/server/game/TriniChat/framework/GameSystem/GridReference.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef _GRIDREFERENCE_H
+#define _GRIDREFERENCE_H
+
+#include "Utilities/LinkedReference/Reference.h"
+
+template<class OBJECT>
+class GridRefManager;
+
+template<class OBJECT>
+class GridReference : public Reference<GridRefManager<OBJECT>, OBJECT>
+{
+ protected:
+ void targetObjectBuildLink()
+ {
+ // called from link()
+ this->getTarget()->insertFirst(this);
+ this->getTarget()->incSize();
+ }
+ void targetObjectDestroyLink()
+ {
+ // called from unlink()
+ if(this->isValid()) this->getTarget()->decSize();
+ }
+ void sourceObjectDestroyLink()
+ {
+ // called from invalidate()
+ this->getTarget()->decSize();
+ }
+ public:
+ GridReference() : Reference<GridRefManager<OBJECT>, OBJECT>() {}
+ ~GridReference() { this->unlink(); }
+ GridReference *next() { return (GridReference*)Reference<GridRefManager<OBJECT>, OBJECT>::next(); }
+};
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/GameSystem/NGrid.h b/src/server/game/TriniChat/framework/GameSystem/NGrid.h
new file mode 100644
index 0000000..dd4e2a1
--- /dev/null
+++ b/src/server/game/TriniChat/framework/GameSystem/NGrid.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_NGRID_H
+#define TRINITY_NGRID_H
+
+/** NGrid is nothing more than a wrapper of the Grid with an NxN cells
+ */
+
+#include "GameSystem/Grid.h"
+#include "GameSystem/GridReference.h"
+#include "Timer.h"
+#include "Util.h"
+
+#define DEFAULT_VISIBILITY_NOTIFY_PERIOD 1000
+
+class GridInfo
+{
+public:
+ GridInfo()
+ : i_timer(0), i_unloadActiveLockCount(0), i_unloadExplicitLock(false), i_unloadReferenceLock(false),
+ vis_Update(0, irand(0,DEFAULT_VISIBILITY_NOTIFY_PERIOD)) {}
+ GridInfo(time_t expiry, bool unload = true )
+ : i_timer(expiry), i_unloadActiveLockCount(0), i_unloadExplicitLock(!unload), i_unloadReferenceLock(false),
+ vis_Update(0, irand(0,DEFAULT_VISIBILITY_NOTIFY_PERIOD)) {}
+ const TimeTracker& getTimeTracker() const { return i_timer; }
+ bool getUnloadLock() const { return i_unloadActiveLockCount || i_unloadExplicitLock || i_unloadReferenceLock; }
+ void setUnloadExplicitLock( bool on ) { i_unloadExplicitLock = on; }
+ void setUnloadReferenceLock( bool on ) { i_unloadReferenceLock = on; }
+ void incUnloadActiveLock() { ++i_unloadActiveLockCount; }
+ void decUnloadActiveLock() { if(i_unloadActiveLockCount) --i_unloadActiveLockCount; }
+
+ void setTimer(const TimeTracker& pTimer) { i_timer = pTimer; }
+ void ResetTimeTracker(time_t interval) { i_timer.Reset(interval); }
+ void UpdateTimeTracker(time_t diff) { i_timer.Update(diff); }
+ PeriodicTimer& getRelocationTimer() { return vis_Update; }
+private:
+ TimeTracker i_timer;
+ PeriodicTimer vis_Update;
+
+ uint16 i_unloadActiveLockCount : 16; // lock from active object spawn points (prevent clone loading)
+ bool i_unloadExplicitLock : 1; // explicit manual lock or config setting
+ bool i_unloadReferenceLock : 1; // lock from instance map copy
+};
+
+typedef enum
+{
+ GRID_STATE_INVALID = 0,
+ GRID_STATE_ACTIVE = 1,
+ GRID_STATE_IDLE = 2,
+ GRID_STATE_REMOVAL= 3,
+ MAX_GRID_STATE = 4
+} grid_state_t;
+
+template
+<
+unsigned int N,
+class ACTIVE_OBJECT,
+class WORLD_OBJECT_TYPES,
+class GRID_OBJECT_TYPES,
+class ThreadModel = Trinity::SingleThreaded<ACTIVE_OBJECT>
+>
+class NGrid
+{
+ public:
+
+ typedef Grid<ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> GridType;
+ NGrid(uint32 id, int32 x, int32 y, time_t expiry, bool unload = true)
+ : i_gridId(id), i_x(x), i_y(y), i_cellstate(GRID_STATE_INVALID), i_GridObjectDataLoaded(false)
+ {
+ i_GridInfo = GridInfo(expiry, unload);
+ }
+
+ const GridType& operator()(unsigned short x, unsigned short y) const
+ {
+ ASSERT(x < N);
+ ASSERT(y < N);
+ return i_cells[x][y];
+ }
+
+ GridType& operator()(unsigned short x, unsigned short y)
+ {
+ ASSERT(x < N);
+ ASSERT(y < N);
+ return i_cells[x][y];
+ }
+
+ const uint32& GetGridId(void) const { return i_gridId; }
+ void SetGridId(const uint32 id) const { i_gridId = id; }
+ grid_state_t GetGridState(void) const { return i_cellstate; }
+ void SetGridState(grid_state_t s) { i_cellstate = s; }
+ int32 getX() const { return i_x; }
+ int32 getY() const { return i_y; }
+
+ void link(GridRefManager<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> >* pTo)
+ {
+ i_Reference.link(pTo, this);
+ }
+ bool isGridObjectDataLoaded() const { return i_GridObjectDataLoaded; }
+ void setGridObjectDataLoaded(bool pLoaded) { i_GridObjectDataLoaded = pLoaded; }
+
+ GridInfo* getGridInfoRef() { return &i_GridInfo; }
+ const TimeTracker& getTimeTracker() const { return i_GridInfo.getTimeTracker(); }
+ bool getUnloadLock() const { return i_GridInfo.getUnloadLock(); }
+ void setUnloadExplicitLock( bool on ) { i_GridInfo.setUnloadExplicitLock(on); }
+ void setUnloadReferenceLock( bool on ) { i_GridInfo.setUnloadReferenceLock(on); }
+ void incUnloadActiveLock() { i_GridInfo.incUnloadActiveLock(); }
+ void decUnloadActiveLock() { i_GridInfo.decUnloadActiveLock(); }
+ void ResetTimeTracker(time_t interval) { i_GridInfo.ResetTimeTracker(interval); }
+ void UpdateTimeTracker(time_t diff) { i_GridInfo.UpdateTimeTracker(diff); }
+
+ template<class SPECIFIC_OBJECT> void AddWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj)
+ {
+ getGridType(x, y).AddWorldObject(obj);
+ }
+
+ template<class SPECIFIC_OBJECT> void RemoveWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj)
+ {
+ getGridType(x, y).RemoveWorldObject(obj);
+ }
+
+ template<class T, class TT> void Visit(TypeContainerVisitor<T, TypeMapContainer<TT> > &visitor)
+ {
+ for (unsigned int x=0; x < N; ++x)
+ for (unsigned int y=0; y < N; ++y)
+ getGridType(x, y).Visit(visitor);
+ }
+
+ template<class T, class TT> void Visit(const uint32 &x, const uint32 &y, TypeContainerVisitor<T, TypeMapContainer<TT> > &visitor)
+ {
+ getGridType(x, y).Visit(visitor);
+ }
+
+ unsigned int ActiveObjectsInGrid(void) const
+ {
+ unsigned int count=0;
+ for (unsigned int x=0; x < N; ++x)
+ for (unsigned int y=0; y < N; ++y)
+ count += i_cells[x][y].ActiveObjectsInGrid();
+ return count;
+ }
+
+ template<class SPECIFIC_OBJECT> bool AddGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj)
+ {
+ return getGridType(x, y).AddGridObject(obj);
+ }
+
+ template<class SPECIFIC_OBJECT> bool RemoveGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj)
+ {
+ return getGridType(x, y).RemoveGridObject(obj);
+ }
+
+ private:
+
+ GridType& getGridType(const uint32& x, const uint32& y)
+ {
+ ASSERT(x < N);
+ ASSERT(y < N);
+ return i_cells[x][y];
+ }
+
+ uint32 i_gridId;
+ GridInfo i_GridInfo;
+ GridReference<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> > i_Reference;
+ int32 i_x;
+ int32 i_y;
+ grid_state_t i_cellstate;
+ GridType i_cells[N][N];
+ bool i_GridObjectDataLoaded;
+};
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/GameSystem/TypeContainer.h b/src/server/game/TriniChat/framework/GameSystem/TypeContainer.h
new file mode 100644
index 0000000..ddcee97
--- /dev/null
+++ b/src/server/game/TriniChat/framework/GameSystem/TypeContainer.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_TYPECONTAINER_H
+#define TRINITY_TYPECONTAINER_H
+
+/*
+ * Here, you'll find a series of containers that allow you to hold multiple
+ * types of object at the same time.
+ */
+
+#include <map>
+#include <vector>
+#include "Platform/Define.h"
+#include "Utilities/TypeList.h"
+#include "GameSystem/GridRefManager.h"
+
+/*
+ * @class ContainerMapList is a mulit-type container for map elements
+ * By itself its meaningless but collaborate along with TypeContainers,
+ * it become the most powerfully container in the whole system.
+ */
+template<class OBJECT> struct ContainerMapList
+{
+ //std::map<OBJECT_HANDLE, OBJECT *> _element;
+ GridRefManager<OBJECT> _element;
+};
+
+template<> struct ContainerMapList<TypeNull> /* nothing is in type null */
+{
+};
+template<class H, class T> struct ContainerMapList<TypeList<H, T> >
+{
+ ContainerMapList<H> _elements;
+ ContainerMapList<T> _TailElements;
+};
+
+/*
+ * @class ContaierArrayList is a multi-type container for
+ * array of elements.
+ */
+template<class OBJECT> struct ContainerArrayList
+{
+ std::vector<OBJECT> _element;
+};
+
+// termination condition
+template<> struct ContainerArrayList<TypeNull> {};
+// recursion
+template<class H, class T> struct ContainerArrayList<TypeList<H, T> >
+{
+ ContainerArrayList<H> _elements;
+ ContainerArrayList<T> _TailElements;
+};
+
+/*
+ * @class ContainerList is a simple list of different types of elements
+ *
+ */
+template<class OBJECT> struct ContainerList
+{
+ OBJECT _element;
+};
+
+/* TypeNull is underfined */
+template<> struct ContainerList<TypeNull> {};
+template<class H, class T> struct ContainerList<TypeList<H, T> >
+{
+ ContainerList<H> _elements;
+ ContainerMapList<T> _TailElements;
+};
+
+#include "TypeContainerFunctions.h"
+
+/*
+ * @class TypeMapContainer contains a fixed number of types and is
+ * determined at compile time. This is probably the most complicated
+ * class and do its simplest thing, that is, holds objects
+ * of different types.
+ */
+
+template<class OBJECT_TYPES>
+class TypeMapContainer
+{
+ public:
+ template<class SPECIFIC_TYPE> size_t Count() const { return Trinity::Count(i_elements, (SPECIFIC_TYPE*)NULL); }
+
+ /// inserts a specific object into the container
+ template<class SPECIFIC_TYPE> bool insert(SPECIFIC_TYPE *obj)
+ {
+ SPECIFIC_TYPE* t = Trinity::Insert(i_elements, obj);
+ return (t != NULL);
+ }
+
+ /// Removes the object from the container, and returns the removed object
+ template<class SPECIFIC_TYPE> bool remove(SPECIFIC_TYPE* obj)
+ {
+ SPECIFIC_TYPE* t = Trinity::Remove(i_elements, obj);
+ return (t != NULL);
+ }
+
+ ContainerMapList<OBJECT_TYPES> & GetElements(void) { return i_elements; }
+ const ContainerMapList<OBJECT_TYPES> & GetElements(void) const { return i_elements;}
+
+ private:
+ ContainerMapList<OBJECT_TYPES> i_elements;
+};
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/GameSystem/TypeContainerFunctions.h b/src/server/game/TriniChat/framework/GameSystem/TypeContainerFunctions.h
new file mode 100644
index 0000000..d0c1f8a
--- /dev/null
+++ b/src/server/game/TriniChat/framework/GameSystem/TypeContainerFunctions.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TYPECONTAINER_FUNCTIONS_H
+#define TYPECONTAINER_FUNCTIONS_H
+
+/*
+ * Here you'll find a list of helper functions to make
+ * the TypeContainer usefull. Without it, its hard
+ * to access or mutate the container.
+ */
+
+#include "Platform/Define.h"
+#include "Utilities/TypeList.h"
+#include <map>
+
+namespace Trinity
+{
+ /* ContainerMapList Helpers */
+ // count functions
+ template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<SPECIFIC_TYPE> &elements, SPECIFIC_TYPE* /*fake*/)
+ {
+ return elements._element.getSize();
+ };
+
+ template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE* /*fake*/)
+ {
+ return 0;
+ }
+
+ template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE* /*fake*/)
+ {
+ return 0;
+ }
+
+ template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<TypeList<SPECIFIC_TYPE, T> >&elements, SPECIFIC_TYPE* fake)
+ {
+ return Count(elements._elements,fake);
+ }
+
+ template<class SPECIFIC_TYPE, class H, class T> size_t Count(const ContainerMapList<TypeList<H, T> >&elements, SPECIFIC_TYPE* fake)
+ {
+ return Count(elements._TailElements, fake);
+ }
+
+ // non-const insert functions
+ template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Insert(ContainerMapList<SPECIFIC_TYPE> &elements, SPECIFIC_TYPE *obj)
+ {
+ //elements._element[hdl] = obj;
+ obj->GetGridRef().link(&elements._element, obj);
+ return obj;
+ };
+
+ template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Insert(ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
+ {
+ return NULL;
+ }
+
+ // this is a missed
+ template<class SPECIFIC_TYPE, class T> SPECIFIC_TYPE* Insert(ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
+ {
+ return NULL; // a missed
+ }
+
+ // Recursion
+ template<class SPECIFIC_TYPE, class H, class T> SPECIFIC_TYPE* Insert(ContainerMapList<TypeList<H, T> >&elements, SPECIFIC_TYPE *obj)
+ {
+ SPECIFIC_TYPE* t= Insert(elements._elements, obj);
+ return (t != NULL ? t : Insert(elements._TailElements, obj));
+ }
+
+ // non-const remove method
+ template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Remove(ContainerMapList<SPECIFIC_TYPE> & /*elements*/, SPECIFIC_TYPE *obj)
+ {
+ obj->GetGridRef().unlink();
+ return obj;
+ }
+
+ template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Remove(ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
+ {
+ return NULL;
+ }
+
+ // this is a missed
+ template<class SPECIFIC_TYPE, class T> SPECIFIC_TYPE* Remove(ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
+ {
+ return NULL; // a missed
+ }
+
+ template<class SPECIFIC_TYPE, class T, class H> SPECIFIC_TYPE* Remove(ContainerMapList<TypeList<H, T> > &elements, SPECIFIC_TYPE *obj)
+ {
+ // The head element is bad
+ SPECIFIC_TYPE* t = Remove(elements._elements, obj);
+ return ( t != NULL ? t : Remove(elements._TailElements, obj) );
+ }
+
+}
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/GameSystem/TypeContainerFunctionsPtr.h b/src/server/game/TriniChat/framework/GameSystem/TypeContainerFunctionsPtr.h
new file mode 100644
index 0000000..dbeb80f
--- /dev/null
+++ b/src/server/game/TriniChat/framework/GameSystem/TypeContainerFunctionsPtr.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TYPECONTAINER_FUNCTIONS_PTR_H
+#define TYPECONTAINER_FUNCTIONS_PTR_H
+
+/*
+ * Here you'll find a list of helper functions to make
+ * the TypeContainer usefull. Without it, its hard
+ * to access or mutate the container.
+ */
+
+#include "Platform/Define.h"
+#include "Utilities/TypeList.h"
+#include <map>
+
+namespace Trinity
+{
+ /* ContainerMapList Helpers */
+ // count functions
+ // template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<SPECIFIC_TYPE> &elements, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
+ // {
+ // return elements._element.size();
+ // };
+ //
+ // template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<TypeNull> &elements, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
+ // {
+ // return 0;
+ // }
+ //
+ // template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<T> &elements, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
+ // {
+ // return 0;
+ // }
+ //
+ // template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<TypeList<SPECIFIC_TYPE, T> >&elements, SPECIFIC_TYPE* fake)
+ // {
+ // return Count(elements._elements,fake);
+ // }
+ //
+ // template<class SPECIFIC_TYPE, class H, class T> size_t Count(const ContainerMapList<TypeList<H, T> >&elements, SPECIFIC_TYPE* fake)
+ // {
+ // return Count(elements._TailElements, fake);
+ // }
+
+ // non-const find functions
+ template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<SPECIFIC_TYPE> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
+ {
+ typename std::map<OBJECT_HANDLE, CountedPtr<SPECIFIC_TYPE> >::iterator iter = elements._element.find(hdl);
+ return (iter == elements._element.end() ? NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL) : iter->second);
+ };
+
+ template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<TypeNull> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
+ {
+ return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);// terminate recursion
+ }
+
+ template<class SPECIFIC_TYPE, class T> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<T> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
+ {
+ return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);// this is a missed
+ }
+
+ template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<TypeList<H, T> >&elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* fake)
+ {
+ CountedPtr<SPECIFIC_TYPE> &t = Find(elements._elements, hdl,fake);
+ return (!t ? Find(elements._TailElements, hdl,fake) : t);
+ }
+
+ // const find functions
+ template<class SPECIFIC_TYPE> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<SPECIFIC_TYPE> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
+ {
+ typename CountedPtr<SPECIFIC_TYPE>::iterator iter = elements._element.find(hdl);
+ return (iter == elements._element.end() ? NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL) : iter->second);
+ };
+
+ template<class SPECIFIC_TYPE> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<TypeNull> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
+ {
+ return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);
+ }
+
+ template<class SPECIFIC_TYPE, class T> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<T> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
+ {
+ return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);
+ }
+
+ template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<TypeList<H, T> >&elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* fake)
+ {
+ CountedPtr<SPECIFIC_TYPE> &t = Find(elements._elements, hdl,fake);
+ if(!t)
+ t = Find(elements._TailElement, hdl,fake);
+
+ return t;
+ }
+
+ // non-const insert functions
+ template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<SPECIFIC_TYPE> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
+ {
+ elements._element[hdl] = obj;
+ return obj;
+ };
+
+ template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<TypeNull> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
+ {
+ return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);
+ }
+
+ // this is a missed
+ template<class SPECIFIC_TYPE, class T> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<T> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
+ {
+ return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);// a missed
+ }
+
+ // Recursion
+ template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<TypeList<H, T> >&elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
+ {
+ CountedPtr<SPECIFIC_TYPE> &t= Insert(elements._elements, obj, hdl);
+ return (!t ? Insert(elements._TailElements, obj, hdl) : t);
+ }
+
+ // non-const remove method
+ template<class SPECIFIC_TYPE> bool Remove(ContainerMapList<SPECIFIC_TYPE> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
+ {
+ typename std::map<OBJECT_HANDLE, CountedPtr<SPECIFIC_TYPE> >::iterator iter = elements._element.find(hdl);
+ if( iter != elements._element.end() )
+ {
+ elements._element.erase(iter);
+ return true;
+ }
+
+ return false; // found... terminate the search
+ }
+
+ template<class SPECIFIC_TYPE> bool Remove(ContainerMapList<TypeNull> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
+ {
+ return false;
+ }
+
+ // this is a missed
+ template<class SPECIFIC_TYPE, class T> bool Remove(ContainerMapList<T> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
+ {
+ return false;
+ }
+
+ template<class SPECIFIC_TYPE, class T, class H> bool Remove(ContainerMapList<TypeList<H, T> > &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
+ {
+ // The head element is bad
+ bool t = Remove(elements._elements, obj, hdl);
+ return ( !t ? Remove(elements._TailElements, obj, hdl) : t );
+ }
+
+}
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/GameSystem/TypeContainerVisitor.h b/src/server/game/TriniChat/framework/GameSystem/TypeContainerVisitor.h
new file mode 100644
index 0000000..14e3f19
--- /dev/null
+++ b/src/server/game/TriniChat/framework/GameSystem/TypeContainerVisitor.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_TYPECONTAINERVISITOR_H
+#define TRINITY_TYPECONTAINERVISITOR_H
+
+/*
+ * @class TypeContainerVisitor is implemented as a visitor pattern. It is
+ * a visitor to the TypeContainerList or TypeContainerMapList. The visitor has
+ * to overload its types as a visit method is called.
+ */
+
+#include "Platform/Define.h"
+#include "TypeContainer.h"
+
+// forward declaration
+template<class T, class Y> class TypeContainerVisitor;
+
+// visitor helper
+template<class VISITOR, class TYPE_CONTAINER> void VisitorHelper(VISITOR &v, TYPE_CONTAINER &c)
+{
+ v.Visit(c);
+};
+
+// terminate condition for container list
+template<class VISITOR> void VisitorHelper(VISITOR &v, ContainerList<TypeNull> &c)
+{
+}
+
+template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerList<T> &c)
+{
+ v.Visit(c._element);
+}
+
+// recursion for container list
+template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerList<TypeList<H, T> > &c)
+{
+ VisitorHelper(v, c._elements);
+ VisitorHelper(v, c._TailElements);
+}
+
+// terminate condition container map list
+template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerMapList<TypeNull> &/*c*/)
+{
+}
+
+template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerMapList<T> &c)
+{
+ v.Visit(c._element);
+}
+
+// recursion container map list
+template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerMapList<TypeList<H, T> > &c)
+{
+ VisitorHelper(v, c._elements);
+ VisitorHelper(v, c._TailElements);
+}
+
+// array list
+template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerArrayList<T> &c)
+{
+ v.Visit(c._element);
+}
+
+template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerArrayList<TypeNull> &/*c*/)
+{
+}
+
+// recursion
+template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerArrayList<TypeList<H, T> > &c)
+{
+ VisitorHelper(v, c._elements);
+ VisitorHelper(v, c._TailElements);
+}
+
+// for TypeMapContainer
+template<class VISITOR, class OBJECT_TYPES> void VisitorHelper(VISITOR &v, TypeMapContainer<OBJECT_TYPES> &c)
+{
+ VisitorHelper(v, c.GetElements());
+}
+
+template<class VISITOR, class TYPE_CONTAINER>
+class TypeContainerVisitor
+{
+ public:
+ TypeContainerVisitor(VISITOR &v) : i_visitor(v) {}
+
+ void Visit(TYPE_CONTAINER &c)
+ {
+ VisitorHelper(i_visitor, c);
+ }
+
+ void Visit(const TYPE_CONTAINER &c) const
+ {
+ VisitorHelper(i_visitor, c);
+ }
+
+ private:
+ VISITOR &i_visitor;
+};
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Network/SocketDefines.h b/src/server/game/TriniChat/framework/Network/SocketDefines.h
new file mode 100644
index 0000000..7ba412d
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Network/SocketDefines.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_SOCKETDEFINES_H
+#define TRINITY_SOCKETDEFINES_H
+
+#ifdef WIN32
+
+/* Windows socket definitions
+ */
+#define FD_SETSIZE 1024
+#include <winsock2.h>
+#include <Ws2tcpip.h>
+
+typedef SOCKET SocketHandle;
+typedef fd_set SelectSet;
+
+#else
+
+/* The unix socket definitions
+ */
+#include <sys/socket.h>
+#include <netinet/in.h>
+#ifdef __APPLE_CC__
+#include <sys/select.h>
+#endif
+
+typedef int SocketHandle;
+typedef fd_set SelectSet;
+#endif
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Platform/CompilerDefs.h b/src/server/game/TriniChat/framework/Platform/CompilerDefs.h
new file mode 100644
index 0000000..e880c12
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Platform/CompilerDefs.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_COMPILERDEFS_H
+#define TRINITY_COMPILERDEFS_H
+
+#define PLATFORM_WINDOWS 0
+#define PLATFORM_UNIX 1
+#define PLATFORM_APPLE 2
+#define PLATFORM_INTEL 3
+
+// must be first (win 64 also define WIN32)
+#if defined( _WIN64 )
+# define PLATFORM PLATFORM_WINDOWS
+#elif defined( __WIN32__ ) || defined( WIN32 ) || defined( _WIN32 )
+# define PLATFORM PLATFORM_WINDOWS
+#elif defined( __APPLE_CC__ )
+# define PLATFORM PLATFORM_APPLE
+#elif defined( __INTEL_COMPILER )
+# define PLATFORM PLATFORM_INTEL
+#else
+# define PLATFORM PLATFORM_UNIX
+#endif
+
+#define COMPILER_MICROSOFT 0
+#define COMPILER_GNU 1
+#define COMPILER_BORLAND 2
+#define COMPILER_INTEL 3
+
+#ifdef _MSC_VER
+# define COMPILER COMPILER_MICROSOFT
+#elif defined( __BORLANDC__ )
+# define COMPILER COMPILER_BORLAND
+#elif defined( __INTEL_COMPILER )
+# define COMPILER COMPILER_INTEL
+#elif defined( __GNUC__ )
+# define COMPILER COMPILER_GNU
+#else
+# pragma error "FATAL ERROR: Unknown compiler."
+#endif
+
+#if COMPILER == COMPILER_MICROSOFT
+# pragma warning( disable : 4267 ) // conversion from 'size_t' to 'int', possible loss of data
+# pragma warning( disable : 4786 ) // identifier was truncated to '255' characters in the debug information
+#endif
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Platform/Define.h b/src/server/game/TriniChat/framework/Platform/Define.h
new file mode 100644
index 0000000..9aa4132
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Platform/Define.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_DEFINE_H
+#define TRINITY_DEFINE_H
+
+#include <sys/types.h>
+
+#include <ace/Basic_Types.h>
+#include <ace/ACE_export.h>
+
+#include "Platform/CompilerDefs.h"
+
+#define TRINITY_LITTLEENDIAN 0
+#define TRINITY_BIGENDIAN 1
+
+#if !defined(TRINITY_ENDIAN)
+# if defined (ACE_BIG_ENDIAN)
+# define TRINITY_ENDIAN TRINITY_BIGENDIAN
+# else //ACE_BYTE_ORDER != ACE_BIG_ENDIAN
+# define TRINITY_ENDIAN TRINITY_LITTLEENDIAN
+# endif //ACE_BYTE_ORDER
+#endif //TRINITY_ENDIAN
+
+#if PLATFORM == PLATFORM_WINDOWS
+# define TRINITY_PATH_MAX MAX_PATH
+# ifndef DECLSPEC_NORETURN
+# define DECLSPEC_NORETURN __declspec(noreturn)
+# endif //DECLSPEC_NORETURN
+#else //PLATFORM != PLATFORM_WINDOWS
+# define TRINITY_PATH_MAX PATH_MAX
+# define DECLSPEC_NORETURN
+#endif //PLATFORM
+
+#if !defined(DEBUG)
+# define TRINITY_INLINE inline
+#else //DEBUG
+# if !defined(TRINITY_DEBUG)
+# define TRINITY_DEBUG
+# endif //TRINITY_DEBUG
+# define TRINITY_INLINE
+#endif //!DEBUG
+
+#if COMPILER == COMPILER_GNU
+# define ATTR_NORETURN __attribute__((noreturn))
+# define ATTR_PRINTF(F,V) __attribute__ ((format (printf, F, V)))
+#else //COMPILER != COMPILER_GNU
+# define ATTR_NORETURN
+# define ATTR_PRINTF(F,V)
+#endif //COMPILER == COMPILER_GNU
+
+typedef ACE_INT64 int64;
+typedef ACE_INT32 int32;
+typedef ACE_INT16 int16;
+typedef ACE_INT8 int8;
+typedef ACE_UINT64 uint64;
+typedef ACE_UINT32 uint32;
+typedef ACE_UINT16 uint16;
+typedef ACE_UINT8 uint8;
+
+#if COMPILER != COMPILER_MICROSOFT
+typedef uint16 WORD;
+typedef uint32 DWORD;
+#endif //COMPILER
+
+typedef uint64 OBJECT_HANDLE;
+
+#endif //TRINITY_DEFINE_H
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Policies/CreationPolicy.h b/src/server/game/TriniChat/framework/Policies/CreationPolicy.h
new file mode 100644
index 0000000..d375484
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Policies/CreationPolicy.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_CREATIONPOLICY_H
+#define TRINITY_CREATIONPOLICY_H
+
+#include <stdlib.h>
+#include "../Platform/Define.h"
+
+namespace Trinity
+{
+ /**
+ * OperatorNew policy creates an object on the heap using new.
+ */
+ template <class T>
+ class OperatorNew
+ {
+ public:
+ static T* Create(void) { return (new T); }
+ static void Destroy(T *obj) { delete obj; }
+ };
+
+ /**
+ * LocalStaticCreation policy creates an object on the stack
+ * the first time call Create.
+ */
+ template <class T>
+ class LocalStaticCreation
+ {
+ union MaxAlign
+ {
+ char t_[sizeof(T)];
+ short int shortInt_;
+ int int_;
+ long int longInt_;
+ float float_;
+ double double_;
+ long double longDouble_;
+ struct Test;
+ int Test::* pMember_;
+ int (Test::*pMemberFn_)(int);
+ };
+ public:
+ static T* Create(void)
+ {
+ static MaxAlign si_localStatic;
+ return new(&si_localStatic) T;
+ }
+
+ static void Destroy(T *obj) { obj->~T(); }
+ };
+
+ /**
+ * CreateUsingMalloc by pass the memory manger.
+ */
+ template<class T>
+ class CreateUsingMalloc
+ {
+ public:
+ static T* Create()
+ {
+ void* p = ::malloc(sizeof(T));
+ if (!p) return 0;
+ return new(p) T;
+ }
+
+ static void Destroy(T* p)
+ {
+ p->~T();
+ ::free(p);
+ }
+ };
+
+ /**
+ * CreateOnCallBack creates the object base on the call back.
+ */
+ template<class T, class CALL_BACK>
+ class CreateOnCallBack
+ {
+ public:
+ static T* Create()
+ {
+ return CALL_BACK::createCallBack();
+ }
+
+ static void Destroy(T *p)
+ {
+ CALL_BACK::destroyCallBack(p);
+ }
+ };
+}
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Policies/ObjectLifeTime.cpp b/src/server/game/TriniChat/framework/Policies/ObjectLifeTime.cpp
new file mode 100644
index 0000000..ff51cf1
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Policies/ObjectLifeTime.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#include <cstdlib>
+#include "ObjectLifeTime.h"
+
+namespace Trinity
+{
+ extern "C" void external_wrapper(void *p)
+ {
+ std::atexit( (void (*)())p );
+ }
+
+ void at_exit( void (*func)() )
+ {
+ external_wrapper((void*)func);
+ }
+}
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Policies/ObjectLifeTime.h b/src/server/game/TriniChat/framework/Policies/ObjectLifeTime.h
new file mode 100644
index 0000000..885f372
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Policies/ObjectLifeTime.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_OBJECTLIFETIME_H
+#define TRINITY_OBJECTLIFETIME_H
+
+#include <stdexcept>
+#include "../Platform/Define.h"
+
+typedef void (* Destroyer)(void);
+
+namespace Trinity
+{
+ void at_exit( void (*func)() );
+
+ template <class T>
+ class ObjectLifeTime
+ {
+ public:
+ static void ScheduleCall(void (*destroyer)() )
+ {
+ at_exit( destroyer );
+ }
+
+ DECLSPEC_NORETURN static void OnDeadReference(void) ATTR_NORETURN;
+
+ };
+
+ template <class T>
+ void ObjectLifeTime<T>::OnDeadReference(void) // We don't handle Dead Reference for now
+ {
+ throw std::runtime_error("Dead Reference");
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Policies/Singleton.h b/src/server/game/TriniChat/framework/Policies/Singleton.h
new file mode 100644
index 0000000..3992bd0
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Policies/Singleton.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_SINGLETON_H
+#define TRINITY_SINGLETON_H
+
+/**
+ * @brief class Singleton
+ */
+
+#include "CreationPolicy.h"
+#include "ThreadingModel.h"
+#include "ObjectLifeTime.h"
+
+namespace Trinity
+{
+ template
+ <
+ typename T,
+ class ThreadingModel = Trinity::SingleThreaded<T>,
+ class CreatePolicy = Trinity::OperatorNew<T>,
+ class LifeTimePolicy = Trinity::ObjectLifeTime<T>
+ >
+ class Singleton
+ {
+ public:
+ static T& Instance();
+
+ protected:
+ Singleton() {};
+
+ private:
+
+ // Prohibited actions...this does not prevent hijacking.
+ Singleton(const Singleton &);
+ Singleton& operator=(const Singleton &);
+
+ // Singleton Helpers
+ static void DestroySingleton();
+
+ // data structure
+ typedef typename ThreadingModel::Lock Guard;
+ static T *si_instance;
+ static bool si_destroyed;
+ };
+}
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Policies/SingletonImp.h b/src/server/game/TriniChat/framework/Policies/SingletonImp.h
new file mode 100644
index 0000000..908b1a3
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Policies/SingletonImp.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_SINGLETONIMPL_H
+#define TRINITY_SINGLETONIMPL_H
+
+#include "Singleton.h"
+
+// avoid the using namespace here cuz
+// its a .h file afterall
+
+template
+<
+typename T,
+class ThreadingModel,
+class CreatePolicy,
+class LifeTimePolicy
+>
+T&
+Trinity::Singleton<T, ThreadingModel, CreatePolicy, LifeTimePolicy >::Instance()
+{
+ if( !si_instance )
+ {
+ // double-checked Locking pattern
+ Guard();
+ if( !si_instance )
+ {
+ if( si_destroyed )
+ {
+ si_destroyed = false;
+ LifeTimePolicy::OnDeadReference();
+ }
+ si_instance = CreatePolicy::Create();
+ LifeTimePolicy::ScheduleCall(&DestroySingleton);
+ }
+ }
+
+ return *si_instance;
+}
+
+template
+<
+typename T,
+class ThreadingModel,
+class CreatePolicy,
+class LifeTimePolicy
+>
+void
+Trinity::Singleton<T, ThreadingModel, CreatePolicy, LifeTimePolicy>::DestroySingleton()
+{
+ CreatePolicy::Destroy(si_instance);
+ si_instance = NULL;
+ si_destroyed = true;
+}
+
+#define INSTANTIATE_SINGLETON_1(TYPE) \
+ template class Trinity::Singleton<TYPE, Trinity::SingleThreaded<TYPE>, Trinity::OperatorNew<TYPE>, Trinity::ObjectLifeTime<TYPE> >; \
+ template<> TYPE* Trinity::Singleton<TYPE, Trinity::SingleThreaded<TYPE>, Trinity::OperatorNew<TYPE>, Trinity::ObjectLifeTime<TYPE> >::si_instance = 0; \
+ template<> bool Trinity::Singleton<TYPE, Trinity::SingleThreaded<TYPE>, Trinity::OperatorNew<TYPE>, Trinity::ObjectLifeTime<TYPE> >::si_destroyed = false
+
+#define INSTANTIATE_SINGLETON_2(TYPE, THREADINGMODEL) \
+ template class Trinity::Singleton<TYPE, THREADINGMODEL, Trinity::OperatorNew<TYPE>, Trinity::ObjectLifeTime<TYPE> >; \
+ template<> TYPE* Trinity::Singleton<TYPE, THREADINGMODEL, Trinity::OperatorNew<TYPE>, Trinity::ObjectLifeTime<TYPE> >::si_instance = 0; \
+ template<> bool Trinity::Singleton<TYPE, THREADINGMODEL, Trinity::OperatorNew<TYPE>, Trinity::ObjectLifeTime<TYPE> >::si_destroyed = false
+
+#define INSTANTIATE_SINGLETON_3(TYPE, THREADINGMODEL, CREATIONPOLICY ) \
+ template class Trinity::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, Trinity::ObjectLifeTime<TYPE> >; \
+ template<> TYPE* Trinity::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, Trinity::ObjectLifeTime<TYPE> >::si_instance = 0; \
+ template<> bool Trinity::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, Trinity::ObjectLifeType<TYPE> >::si_destroyed = false
+
+#define INSTANTIATE_SINGLETON_4(TYPE, THREADINGMODEL, CREATIONPOLICY, OBJECTLIFETIME) \
+ template class Trinity::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, OBJECTLIFETIME >; \
+ template<> TYPE* Trinity::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, OBJECTLIFETIME >::si_instance = 0; \
+ template<> bool Trinity::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, OBJECTLIFETIME >::si_destroyed = false
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Policies/ThreadingModel.h b/src/server/game/TriniChat/framework/Policies/ThreadingModel.h
new file mode 100644
index 0000000..b1a799e
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Policies/ThreadingModel.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_THREADINGMODEL_H
+#define TRINITY_THREADINGMODEL_H
+
+/**
+ * @class ThreadingModel<T>
+ *
+ */
+
+#include "../Platform/Define.h"
+
+namespace Trinity
+{
+ inline void Guard(void *) {}
+
+ template<typename MUTEX> class GeneralLock
+ {
+ public:
+ GeneralLock(MUTEX &m) : i_mutex(m)
+ {
+ i_mutex.acquire();
+ }
+
+ ~GeneralLock()
+ {
+ i_mutex.release();
+ }
+ private:
+ GeneralLock(const GeneralLock &);
+ GeneralLock& operator=(const GeneralLock &);
+ MUTEX &i_mutex;
+ };
+
+ template <class T>
+ class SingleThreaded
+ {
+ public:
+
+ struct Lock // empty object
+ {
+ Lock() {}
+ Lock(const T &) {}
+ Lock(const SingleThreaded<T> &) // for single threaded we ignore this
+ {
+ }
+ };
+
+ typedef T VolatileType;
+ };
+
+ // object level lockable
+ template<class T, class MUTEX>
+ class ObjectLevelLockable
+ {
+ public:
+ ObjectLevelLockable() : i_mtx() {}
+
+ friend class Lock;
+
+ class Lock
+ {
+ public:
+ Lock(ObjectLevelLockable<T, MUTEX> &host) : i_lock(host.i_mtx)
+ {
+ }
+
+ private:
+ GeneralLock<MUTEX> i_lock;
+ };
+
+ typedef volatile T VolatileType;
+
+ private:
+ // prevent the compiler creating a copy construct
+ ObjectLevelLockable(const ObjectLevelLockable<T, MUTEX> &);
+ ObjectLevelLockable<T, MUTEX>& operator=(const ObjectLevelLockable<T, MUTEX> &);
+
+ MUTEX i_mtx;
+ };
+
+ template<class T, class MUTEX>
+ class ClassLevelLockable
+ {
+ public:
+ class Lock;
+ friend class Lock;
+ typedef volatile T VolatileType;
+
+ ClassLevelLockable() {}
+
+ class Lock
+ {
+ public:
+ Lock(T& /*host*/) { ClassLevelLockable<T, MUTEX>::si_mtx.acquire(); }
+ Lock(ClassLevelLockable<T, MUTEX> &) { ClassLevelLockable<T, MUTEX>::si_mtx.acquire(); }
+ Lock() { ClassLevelLockable<T, MUTEX>::si_mtx.acquire(); }
+ ~Lock() { ClassLevelLockable<T, MUTEX>::si_mtx.release(); }
+ };
+
+ private:
+ static MUTEX si_mtx;
+ };
+
+}
+
+template<class T, class MUTEX> MUTEX Trinity::ClassLevelLockable<T, MUTEX>::si_mtx;
+
+#define INSTANTIATE_CLASS_MUTEX(CTYPE,MUTEX) \
+ template class Trinity::ClassLevelLockable<CTYPE, MUTEX >
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Utilities/ByteConverter.h b/src/server/game/TriniChat/framework/Utilities/ByteConverter.h
new file mode 100644
index 0000000..18f81fe
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Utilities/ByteConverter.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_BYTECONVERTER_H
+#define TRINITY_BYTECONVERTER_H
+
+/** ByteConverter reverse your byte order. This is use
+ for cross platform where they have different endians.
+ */
+
+#include<Platform/Define.h>
+#include<algorithm>
+
+namespace ByteConverter
+{
+ template<size_t T>
+ inline void convert(char *val)
+ {
+ std::swap(*val, *(val + T - 1));
+ convert<T - 2>(val + 1);
+ }
+
+ template<> inline void convert<0>(char *) {}
+ template<> inline void convert<1>(char *) {} // ignore central byte
+
+ template<typename T> inline void apply(T *val)
+ {
+ convert<sizeof(T)>((char *)(val));
+ }
+}
+
+#if TRINITY_ENDIAN == TRINITY_BIGENDIAN
+template<typename T> inline void EndianConvert(T& val) { ByteConverter::apply<T>(&val); }
+template<typename T> inline void EndianConvertReverse(T&) { }
+#else
+template<typename T> inline void EndianConvert(T&) { }
+template<typename T> inline void EndianConvertReverse(T& val) { ByteConverter::apply<T>(&val); }
+#endif
+
+template<typename T> void EndianConvert(T*); // will generate link error
+template<typename T> void EndianConvertReverse(T*); // will generate link error
+
+inline void EndianConvert(uint8&) { }
+inline void EndianConvert( int8&) { }
+inline void EndianConvertReverse(uint8&) { }
+inline void EndianConvertReverse( int8&) { }
+
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Utilities/Callback.h b/src/server/game/TriniChat/framework/Utilities/Callback.h
new file mode 100644
index 0000000..d5703a5
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Utilities/Callback.h
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_CALLBACK_H
+#define TRINITY_CALLBACK_H
+
+/// ------------ BASE CLASSES ------------
+
+namespace Trinity
+{
+ template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void >
+ class _Callback
+ {
+ protected:
+ typedef void (Class::*Method)(ParamType1, ParamType2, ParamType3, ParamType4);
+ Class *m_object;
+ Method m_method;
+ ParamType1 m_param1;
+ ParamType2 m_param2;
+ ParamType3 m_param3;
+ ParamType4 m_param4;
+ void _Execute() { (m_object->*m_method)(m_param1, m_param2, m_param3, m_param4); }
+ public:
+ _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4)
+ : m_object(object), m_method(method), m_param1(param1), m_param2(param2), m_param3(param3), m_param4(param4) {}
+ _Callback(_Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4> const& cb)
+ : m_object(cb.object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3), m_param4(cb.m_param4) {}
+ };
+
+ template < class Class, typename ParamType1, typename ParamType2, typename ParamType3 >
+ class _Callback < Class, ParamType1, ParamType2, ParamType3 >
+ {
+ protected:
+ typedef void (Class::*Method)(ParamType1, ParamType2, ParamType3);
+ Class *m_object;
+ Method m_method;
+ ParamType1 m_param1;
+ ParamType2 m_param2;
+ ParamType3 m_param3;
+ void _Execute() { (m_object->*m_method)(m_param1, m_param2, m_param3); }
+ public:
+ _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3)
+ : m_object(object), m_method(method), m_param1(param1), m_param2(param2) {}
+ _Callback(_Callback < Class, ParamType1, ParamType2, ParamType3 > const& cb)
+ : m_object(cb.object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3) {}
+ };
+
+ template < class Class, typename ParamType1, typename ParamType2 >
+ class _Callback < Class, ParamType1, ParamType2 >
+ {
+ protected:
+ typedef void (Class::*Method)(ParamType1, ParamType2);
+ Class *m_object;
+ Method m_method;
+ ParamType1 m_param1;
+ ParamType2 m_param2;
+ void _Execute() { (m_object->*m_method)(m_param1, m_param2); }
+ public:
+ _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2)
+ : m_object(object), m_method(method), m_param1(param1), m_param2(param2) {}
+ _Callback(_Callback < Class, ParamType1, ParamType2 > const& cb)
+ : m_object(cb.m_object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2) {}
+ };
+
+ template < class Class, typename ParamType1 >
+ class _Callback < Class, ParamType1 >
+ {
+ protected:
+ typedef void (Class::*Method)(ParamType1);
+ Class *m_object;
+ Method m_method;
+ ParamType1 m_param1;
+ void _Execute() { (m_object->*m_method)(m_param1); }
+ public:
+ _Callback(Class *object, Method method, ParamType1 param1)
+ : m_object(object), m_method(method), m_param1(param1) {}
+ _Callback(_Callback < Class, ParamType1 > const& cb)
+ : m_object(cb.m_object), m_method(cb.m_method), m_param1(cb.m_param1) {}
+ };
+
+ template < class Class >
+ class _Callback < Class >
+ {
+ protected:
+ typedef void (Class::*Method)();
+ Class *m_object;
+ Method m_method;
+ void _Execute() { (m_object->*m_method)(); }
+ public:
+ _Callback(Class *object, Method method)
+ : m_object(object), m_method(method) {}
+ _Callback(_Callback < Class > const& cb)
+ : m_object(cb.m_object), m_method(cb.m_method) {}
+ };
+
+ /// ---- Statics ----
+
+ template < typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void >
+ class _SCallback
+ {
+ protected:
+ typedef void (*Method)(ParamType1, ParamType2, ParamType3, ParamType4);
+ Method m_method;
+ ParamType1 m_param1;
+ ParamType2 m_param2;
+ ParamType3 m_param3;
+ ParamType4 m_param4;
+ void _Execute() { (*m_method)(m_param1, m_param2, m_param3, m_param4); }
+ public:
+ _SCallback(Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4)
+ : m_method(method), m_param1(param1), m_param2(param2), m_param3(param3), m_param4(param4) {}
+ _SCallback(_SCallback < ParamType1, ParamType2, ParamType3, ParamType4> const& cb)
+ : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3), m_param4(cb.m_param4) {}
+ };
+
+ template < typename ParamType1, typename ParamType2, typename ParamType3 >
+ class _SCallback < ParamType1, ParamType2, ParamType3 >
+ {
+ protected:
+ typedef void (*Method)(ParamType1, ParamType2, ParamType3);
+ Method m_method;
+ ParamType1 m_param1;
+ ParamType2 m_param2;
+ ParamType3 m_param3;
+ void _Execute() { (*m_method)(m_param1, m_param2, m_param3); }
+ public:
+ _SCallback(Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3)
+ : m_method(method), m_param1(param1), m_param2(param2), m_param3(param3) {}
+ _SCallback(_SCallback < ParamType1, ParamType2, ParamType3 > const& cb)
+ : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3) {}
+ };
+
+ template < typename ParamType1, typename ParamType2 >
+ class _SCallback < ParamType1, ParamType2 >
+ {
+ protected:
+ typedef void (*Method)(ParamType1, ParamType2);
+ Method m_method;
+ ParamType1 m_param1;
+ ParamType2 m_param2;
+ void _Execute() { (*m_method)(m_param1, m_param2); }
+ public:
+ _SCallback(Method method, ParamType1 param1, ParamType2 param2)
+ : m_method(method), m_param1(param1), m_param2(param2) {}
+ _SCallback(_SCallback < ParamType1, ParamType2 > const& cb)
+ : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2) {}
+ };
+
+ template < typename ParamType1 >
+ class _SCallback < ParamType1 >
+ {
+ protected:
+ typedef void (*Method)(ParamType1);
+ Method m_method;
+ ParamType1 m_param1;
+ void _Execute() { (*m_method)(m_param1); }
+ public:
+ _SCallback(Method method, ParamType1 param1)
+ : m_method(method), m_param1(param1) {}
+ _SCallback(_SCallback < ParamType1 > const& cb)
+ : m_method(cb.m_method), m_param1(cb.m_param1) {}
+ };
+
+ template < >
+ class _SCallback < >
+ {
+ protected:
+ typedef void (*Method)();
+ Method m_method;
+ void _Execute() { (*m_method)(); }
+ public:
+ _SCallback(Method method)
+ : m_method(method) {}
+ _SCallback(_SCallback <> const& cb)
+ : m_method(cb.m_method) {}
+ };
+}
+
+/// --------- GENERIC CALLBACKS ----------
+
+namespace Trinity
+{
+ class ICallback
+ {
+ public:
+ virtual void Execute() = 0;
+ virtual ~ICallback() {}
+ };
+
+ template < class CB >
+ class _ICallback : public CB, public ICallback
+ {
+ public:
+ _ICallback(CB const& cb) : CB(cb) {}
+ void Execute() { CB::_Execute(); }
+ };
+
+ template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void >
+ class Callback :
+ public _ICallback< _Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4 > >
+ {
+ private:
+ typedef _Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4 > C4;
+ public:
+ Callback(Class *object, typename C4::Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4)
+ : _ICallback< C4 >(C4(object, method, param1, param2, param3, param4)) {}
+ };
+
+ template < class Class, typename ParamType1, typename ParamType2, typename ParamType3 >
+ class Callback < Class, ParamType1, ParamType2, ParamType3 > :
+ public _ICallback< _Callback < Class, ParamType1, ParamType2, ParamType3 > >
+ {
+ private:
+ typedef _Callback < Class, ParamType1, ParamType2, ParamType3 > C3;
+ public:
+ Callback(Class *object, typename C3::Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3)
+ : _ICallback< C3 >(C3(object, method, param1, param2, param3)) {}
+ };
+
+ template < class Class, typename ParamType1, typename ParamType2 >
+ class Callback < Class, ParamType1, ParamType2 > :
+ public _ICallback< _Callback < Class, ParamType1, ParamType2 > >
+ {
+ private:
+ typedef _Callback < Class, ParamType1, ParamType2 > C2;
+ public:
+ Callback(Class *object, typename C2::Method method, ParamType1 param1, ParamType2 param2)
+ : _ICallback< C2 >(C2(object, method, param1, param2)) {}
+ };
+
+ template < class Class, typename ParamType1 >
+ class Callback < Class, ParamType1 > :
+ public _ICallback< _Callback < Class, ParamType1 > >
+ {
+ private:
+ typedef _Callback < Class, ParamType1 > C1;
+ public:
+ Callback(Class *object, typename C1::Method method, ParamType1 param1)
+ : _ICallback< C1 >(C1(object, method, param1)) {}
+ };
+
+ template < class Class >
+ class Callback < Class > : public _ICallback< _Callback < Class > >
+ {
+ private:
+ typedef _Callback < Class > C0;
+ public:
+ Callback(Class *object, typename C0::Method method)
+ : _ICallback< C0 >(C0(object, method)) {}
+ };
+}
+
+/// ---------- QUERY CALLBACKS -----------
+
+#include "QueryResult.h"
+class QueryResult;
+
+namespace Trinity
+{
+ class IQueryCallback
+ {
+ public:
+ virtual void Execute() = 0;
+ virtual ~IQueryCallback() {}
+ virtual void SetResult(QueryResult_AutoPtr result) = 0;
+ virtual QueryResult_AutoPtr GetResult() = 0;
+ };
+
+ template < class CB >
+ class _IQueryCallback : public CB, public IQueryCallback
+ {
+ public:
+ _IQueryCallback(CB const& cb) : CB(cb) {}
+ void Execute() { CB::_Execute(); }
+ void SetResult(QueryResult_AutoPtr result) { CB::m_param1 = result; }
+ QueryResult_AutoPtr GetResult() { return CB::m_param1; }
+ };
+
+ template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void >
+ class QueryCallback :
+ public _IQueryCallback< _Callback < Class, QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3 > >
+ {
+ private:
+ typedef _Callback < Class, QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3 > QC3;
+ public:
+ QueryCallback(Class *object, typename QC3::Method method, QueryResult_AutoPtr result, ParamType1 param1, ParamType2 param2, ParamType3 param3)
+ : _IQueryCallback< QC3 >(QC3(object, method, result, param1, param2, param3)) {}
+ };
+
+ template < class Class, typename ParamType1, typename ParamType2 >
+ class QueryCallback < Class, ParamType1, ParamType2 > :
+ public _IQueryCallback< _Callback < Class, QueryResult_AutoPtr, ParamType1, ParamType2 > >
+ {
+ private:
+ typedef _Callback < Class, QueryResult_AutoPtr, ParamType1, ParamType2 > QC2;
+ public:
+ QueryCallback(Class *object, typename QC2::Method method, QueryResult_AutoPtr result, ParamType1 param1, ParamType2 param2)
+ : _IQueryCallback< QC2 >(QC2(object, method, result, param1, param2)) {}
+ };
+
+ template < class Class, typename ParamType1 >
+ class QueryCallback < Class, ParamType1 > :
+ public _IQueryCallback< _Callback < Class, QueryResult_AutoPtr, ParamType1 > >
+ {
+ private:
+ typedef _Callback < Class, QueryResult_AutoPtr, ParamType1 > QC1;
+ public:
+ QueryCallback(Class *object, typename QC1::Method method, QueryResult_AutoPtr result, ParamType1 param1)
+ : _IQueryCallback< QC1 >(QC1(object, method, result, param1)) {}
+ };
+
+ template < class Class >
+ class QueryCallback < Class > : public _IQueryCallback< _Callback < Class, QueryResult_AutoPtr > >
+ {
+ private:
+ typedef _Callback < Class, QueryResult_AutoPtr > QC0;
+ public:
+ QueryCallback(Class *object, typename QC0::Method method, QueryResult_AutoPtr result)
+ : _IQueryCallback< QC0 >(QC0(object, method, result)) {}
+ };
+
+ /// ---- Statics ----
+
+ template < typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void >
+ class SQueryCallback :
+ public _IQueryCallback< _SCallback < QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3 > >
+ {
+ private:
+ typedef _SCallback < QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3 > QC3;
+ public:
+ SQueryCallback(typename QC3::Method method, QueryResult_AutoPtr result, ParamType1 param1, ParamType2 param2, ParamType3 param3)
+ : _IQueryCallback< QC3 >(QC3(method, result, param1, param2, param3)) {}
+ };
+
+ template < typename ParamType1, typename ParamType2 >
+ class SQueryCallback < ParamType1, ParamType2 > :
+ public _IQueryCallback< _SCallback < QueryResult_AutoPtr, ParamType1, ParamType2 > >
+ {
+ private:
+ typedef _SCallback < QueryResult_AutoPtr, ParamType1, ParamType2 > QC2;
+ public:
+ SQueryCallback(typename QC2::Method method, QueryResult_AutoPtr result, ParamType1 param1, ParamType2 param2)
+ : _IQueryCallback< QC2 >(QC2(method, result, param1, param2)) {}
+ };
+
+ template < typename ParamType1 >
+ class SQueryCallback < ParamType1 > :
+ public _IQueryCallback< _SCallback < QueryResult_AutoPtr, ParamType1 > >
+ {
+ private:
+ typedef _SCallback < QueryResult_AutoPtr, ParamType1 > QC1;
+ public:
+ SQueryCallback(typename QC1::Method method, QueryResult_AutoPtr result, ParamType1 param1)
+ : _IQueryCallback< QC1 >(QC1(method, result, param1)) {}
+ };
+
+ template < >
+ class SQueryCallback < > : public _IQueryCallback< _SCallback < QueryResult_AutoPtr > >
+ {
+ private:
+ typedef _SCallback < QueryResult_AutoPtr > QC0;
+ public:
+ SQueryCallback(QC0::Method method, QueryResult_AutoPtr result)
+ : _IQueryCallback< QC0 >(QC0(method, result)) {}
+ };
+}
+
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Utilities/CountedReference/ReferenceHolder.h b/src/server/game/TriniChat/framework/Utilities/CountedReference/ReferenceHolder.h
new file mode 100644
index 0000000..5e5a182
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Utilities/CountedReference/ReferenceHolder.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_REFERENCEHOLDER_H
+#define TRINITY_REFERENCEHOLDER_H
+
+/** ReferenceHolder holds the actualy referenced obejct as well the refence
+ count. The ReferenecHolder implements as a policy base object and
+ will decided by the Reference class to be consnsitent.
+ */
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+struct ReferenceHolder : public THREADING_MODEL
+{
+ explicit ReferenceHolder(T *ref) : i_referencee(ref), i_referenceCount(0) {}
+ T *i_referencee;
+ unsigned int i_referenceCount;
+ typedef typename THREADING_MODEL::Lock Lock;
+};
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Utilities/CountedReference/ReferenceImpl.h b/src/server/game/TriniChat/framework/Utilities/CountedReference/ReferenceImpl.h
new file mode 100644
index 0000000..405797f
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Utilities/CountedReference/ReferenceImpl.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_REFERENCEIMPL_H
+#define TRINITY_REFERENCEIMPL_H
+
+#include "Reference.h"
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+Referencer<T, THREADING_MODEL>::Referencer(T *ref)
+: i_holder(NULL)
+{
+ if( ref != NULL )
+ {
+ i_holder = new ReferenceeHolder(ref);
+ ++i_holder->i_referenceCount;
+ }
+}
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+Referencer<T, THREADING_MODEL>::~Referencer()
+{
+ if( i_holder != NULL )
+ deReference(i_holder);
+ i_holder = NULL;
+}
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+Referencer<T, THREADING_MODEL>&
+Referencer<T, THREADING_MODEL>::operator=(const Referencer<T, THREADING_MODEL> &obj)
+{
+ if( i_holder != NULL )
+ deReference(i_holder);
+ if( obj.i_holder != NULL )
+ addReference(obj.i_holder);
+ i_holder = obj.i_holder;
+ return *this;
+}
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+Referencer<T, THREADING_MODEL>&
+Referencer<T, THREADING_MODEL>::operator=(T *ref)
+{
+ if( i_holder != NULL )
+ deReference(i_holder);
+ i_holder = NULL;
+ if( ref != NULL )
+ {
+ i_holder = new ReferenceeHolder(ref);
+ ++i_holder->i_referenceCount;
+ }
+
+ return *this;
+}
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+void
+Referencer<T, THREADING_MODEL>::deReference(ReferenceHolder<T, THREADING_MODEL> *holder)
+{
+ assert( holder != NULL && holder->i_referenceCount > 0);
+ bool delete_object = false;
+
+ {
+ // The guard is within the scope due to the guard
+ // must release earlier than expected.
+ Lock guard(*holder);
+ Guard(&guard);
+
+ --holder->i_referenceCount;
+ if( holder->i_referenceCount == 0 )
+ delete_object = true;
+ }
+
+ if( delete_object )
+ {
+ delete holder->i_referencee;
+ delete holder;
+ }
+}
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+void
+Referencer<T, THREADING_MODEL>::addReference(ReferenceHolder<T, THREADING_MODEL> *holder)
+{
+ assert( i_holder != NULL );
+ Lock guard(*holder);
+ Guard(&guard);
+
+ ++holder->i_referenceCount;
+}
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Utilities/LinkedList.h b/src/server/game/TriniChat/framework/Utilities/LinkedList.h
new file mode 100644
index 0000000..18ea2c8
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Utilities/LinkedList.h
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef _LINKEDLIST
+#define _LINKEDLIST
+
+#include "Common.h"
+
+//============================================
+class LinkedListHead;
+
+class LinkedListElement
+{
+ private:
+ friend class LinkedListHead;
+
+ LinkedListElement* iNext;
+ LinkedListElement* iPrev;
+ public:
+ LinkedListElement() { iNext = NULL; iPrev = NULL; }
+ ~LinkedListElement() { delink(); }
+
+ bool hasNext() const { return(iNext && iNext->iNext != NULL); }
+ bool hasPrev() const { return(iPrev && iPrev->iPrev != NULL); }
+ bool isInList() const { return(iNext != NULL && iPrev != NULL); }
+
+ LinkedListElement * next() { return hasNext() ? iNext : NULL; }
+ LinkedListElement const* next() const { return hasNext() ? iNext : NULL; }
+ LinkedListElement * prev() { return hasPrev() ? iPrev : NULL; }
+ LinkedListElement const* prev() const { return hasPrev() ? iPrev : NULL; }
+
+ LinkedListElement * nocheck_next() { return iNext; }
+ LinkedListElement const* nocheck_next() const { return iNext; }
+ LinkedListElement * nocheck_prev() { return iPrev; }
+ LinkedListElement const* nocheck_prev() const { return iPrev; }
+
+ void delink()
+ {
+ if(isInList())
+ {
+ iNext->iPrev = iPrev; iPrev->iNext = iNext; iNext = NULL; iPrev = NULL;
+ }
+ }
+
+ void insertBefore(LinkedListElement* pElem)
+ {
+ pElem->iNext = this;
+ pElem->iPrev = iPrev;
+ iPrev->iNext = pElem;
+ iPrev = pElem;
+ }
+
+ void insertAfter(LinkedListElement* pElem)
+ {
+ pElem->iPrev = this;
+ pElem->iNext = iNext;
+ iNext->iPrev = pElem;
+ iNext = pElem;
+ }
+};
+
+//============================================
+
+class LinkedListHead
+{
+ private:
+ LinkedListElement iFirst;
+ LinkedListElement iLast;
+ uint32 iSize;
+ public:
+ LinkedListHead()
+ {
+ // create empty list
+
+ iFirst.iNext = &iLast;
+ iLast.iPrev = &iFirst;
+ iSize = 0;
+ }
+
+ bool isEmpty() const { return(!iFirst.iNext->isInList()); }
+
+ LinkedListElement * getFirst() { return(isEmpty() ? NULL : iFirst.iNext); }
+ LinkedListElement const* getFirst() const { return(isEmpty() ? NULL : iFirst.iNext); }
+
+ LinkedListElement * getLast() { return(isEmpty() ? NULL : iLast.iPrev); }
+ LinkedListElement const* getLast() const { return(isEmpty() ? NULL : iLast.iPrev); }
+
+ void insertFirst(LinkedListElement* pElem)
+ {
+ iFirst.insertAfter(pElem);
+ }
+
+ void insertLast(LinkedListElement* pElem)
+ {
+ iLast.insertBefore(pElem);
+ }
+
+ uint32 getSize() const
+ {
+ if(!iSize)
+ {
+ uint32 result = 0;
+ LinkedListElement const* e = getFirst();
+ while(e)
+ {
+ ++result;
+ e = e->next();
+ }
+ return result;
+ }
+ else
+ return iSize;
+ }
+
+ void incSize() { ++iSize; }
+ void decSize() { --iSize; }
+
+ template<class _Ty>
+ class Iterator
+ {
+ public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef _Ty value_type;
+ typedef ptrdiff_t difference_type;
+ typedef ptrdiff_t distance_type;
+ typedef _Ty* pointer;
+ typedef _Ty const* const_pointer;
+ typedef _Ty& reference;
+ typedef _Ty const & const_reference;
+
+ Iterator() : _Ptr(0)
+ { // construct with null node pointer
+ }
+
+ Iterator(pointer _Pnode) : _Ptr(_Pnode)
+ { // construct with node pointer _Pnode
+ }
+
+ Iterator& operator=(Iterator const &_Right)
+ {
+ return (*this) = _Right._Ptr;
+ }
+
+ Iterator& operator=(const_pointer const &_Right)
+ {
+ _Ptr = (pointer)_Right;
+ return (*this);
+ }
+
+ reference operator*()
+ { // return designated value
+ return *_Ptr;
+ }
+
+ pointer operator->()
+ { // return pointer to class object
+ return _Ptr;
+ }
+
+ Iterator& operator++()
+ { // preincrement
+ _Ptr = _Ptr->next();
+ return (*this);
+ }
+
+ Iterator operator++(int)
+ { // postincrement
+ iterator _Tmp = *this;
+ ++*this;
+ return (_Tmp);
+ }
+
+ Iterator& operator--()
+ { // predecrement
+ _Ptr = _Ptr->prev();
+ return (*this);
+ }
+
+ Iterator operator--(int)
+ { // postdecrement
+ iterator _Tmp = *this;
+ --*this;
+ return (_Tmp);
+ }
+
+ bool operator==(Iterator const &_Right) const
+ { // test for iterator equality
+ return (_Ptr == _Right._Ptr);
+ }
+
+ bool operator!=(Iterator const &_Right) const
+ { // test for iterator inequality
+ return (!(*this == _Right));
+ }
+
+ bool operator==(pointer const &_Right) const
+ { // test for pointer equality
+ return (_Ptr != _Right);
+ }
+
+ bool operator!=(pointer const &_Right) const
+ { // test for pointer equality
+ return (!(*this == _Right));
+ }
+
+ bool operator==(const_reference _Right) const
+ { // test for reference equality
+ return (_Ptr == &_Right);
+ }
+
+ bool operator!=(const_reference _Right) const
+ { // test for reference equality
+ return (_Ptr != &_Right);
+ }
+
+ pointer _Mynode()
+ { // return node pointer
+ return (_Ptr);
+ }
+
+ protected:
+ pointer _Ptr; // pointer to node
+ };
+
+ typedef Iterator<LinkedListElement> iterator;
+};
+
+//============================================
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Utilities/LinkedReference/RefManager.h b/src/server/game/TriniChat/framework/Utilities/LinkedReference/RefManager.h
new file mode 100644
index 0000000..46d02f5
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Utilities/LinkedReference/RefManager.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef _REFERENCE_H
+#define _REFERENCE_H
+
+#include "Utilities/LinkedList.h"
+
+//=====================================================
+
+template <class TO, class FROM> class Reference : public LinkedListElement
+{
+ private:
+ TO* iRefTo;
+ FROM* iRefFrom;
+ protected:
+ // Tell our refTo (target) object that we have a link
+ virtual void targetObjectBuildLink() = 0;
+
+ // Tell our refTo (taget) object, that the link is cut
+ virtual void targetObjectDestroyLink() = 0;
+
+ // Tell our refFrom (source) object, that the link is cut (Target destroyed)
+ virtual void sourceObjectDestroyLink() = 0;
+ public:
+ Reference() { iRefTo = NULL; iRefFrom = NULL; }
+ virtual ~Reference() {}
+
+ // Create new link
+ void link(TO* toObj, FROM* fromObj)
+ {
+ assert(fromObj); // fromObj MUST not be NULL
+ if(isValid())
+ unlink();
+ if(toObj != NULL)
+ {
+ iRefTo = toObj;
+ iRefFrom = fromObj;
+ targetObjectBuildLink();
+ }
+ }
+
+ // We don't need the reference anymore. Call comes from the refFrom object
+ // Tell our refTo object, that the link is cut
+ void unlink() { targetObjectDestroyLink(); delink(); iRefTo = NULL; iRefFrom = NULL; }
+
+ // Link is invalid due to destruction of referenced target object. Call comes from the refTo object
+ // Tell our refFrom object, that the link is cut
+ void invalidate() // the iRefFrom MUST remain!!
+ {
+ sourceObjectDestroyLink(); delink(); iRefTo = NULL;
+ }
+
+ bool isValid() const // Only check the iRefTo
+ {
+ return iRefTo != NULL;
+ }
+
+ Reference<TO,FROM> * next() { return((Reference<TO,FROM> *) LinkedListElement::next()); }
+ Reference<TO,FROM> const * next() const { return((Reference<TO,FROM> const *) LinkedListElement::next()); }
+ Reference<TO,FROM> * prev() { return((Reference<TO,FROM> *) LinkedListElement::prev()); }
+ Reference<TO,FROM> const * prev() const { return((Reference<TO,FROM> const *) LinkedListElement::prev()); }
+
+ Reference<TO,FROM> * nocheck_next() { return((Reference<TO,FROM> *) LinkedListElement::nocheck_next()); }
+ Reference<TO,FROM> const * nocheck_next() const { return((Reference<TO,FROM> const *) LinkedListElement::nocheck_next()); }
+ Reference<TO,FROM> * nocheck_prev() { return((Reference<TO,FROM> *) LinkedListElement::nocheck_prev()); }
+ Reference<TO,FROM> const * nocheck_prev() const { return((Reference<TO,FROM> const *) LinkedListElement::nocheck_prev()); }
+
+ TO* operator ->() const { return iRefTo; }
+ TO* getTarget() const { return iRefTo; }
+
+ FROM* getSource() const { return iRefFrom; }
+};
+
+//=====================================================
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Utilities/LinkedReference/Reference.h b/src/server/game/TriniChat/framework/Utilities/LinkedReference/Reference.h
new file mode 100644
index 0000000..36d3437
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Utilities/LinkedReference/Reference.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef _REFMANAGER_H
+#define _REFMANAGER_H
+//=====================================================
+
+#include "Utilities/LinkedList.h"
+#include "Utilities/LinkedReference/Reference.h"
+
+template <class TO, class FROM> class RefManager : public LinkedListHead
+{
+ public:
+ typedef LinkedListHead::Iterator< Reference<TO, FROM> > iterator;
+ RefManager() { }
+ virtual ~RefManager() { clearReferences(); }
+
+ Reference<TO, FROM>* getFirst() { return ((Reference<TO, FROM>*) LinkedListHead::getFirst()); }
+ Reference<TO, FROM> const* getFirst() const { return ((Reference<TO, FROM> const*) LinkedListHead::getFirst()); }
+ Reference<TO, FROM>* getLast() { return ((Reference<TO, FROM>*) LinkedListHead::getLast()); }
+ Reference<TO, FROM> const* getLast() const { return ((Reference<TO, FROM> const*) LinkedListHead::getLast()); }
+
+ iterator begin() { return iterator(getFirst()); }
+ iterator end() { return iterator(NULL); }
+ iterator rbegin() { return iterator(getLast()); }
+ iterator rend() { return iterator(NULL); }
+
+ void clearReferences()
+ {
+ LinkedListElement* ref;
+ while((ref = getFirst()) != NULL)
+ {
+ ((Reference<TO, FROM>*) ref)->invalidate();
+ ref->delink(); // the delink might be already done by invalidate(), but doing it here again does not hurt and insures an empty list
+ }
+ }
+};
+
+//=====================================================
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Utilities/Reference.h b/src/server/game/TriniChat/framework/Utilities/Reference.h
new file mode 100644
index 0000000..70e60cb
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Utilities/Reference.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_REFERENCE_H
+#define TRINITY_REFERENCE_H
+
+/**
+ * Referencer<T>
+ * Referencer is an object that holds a reference holder that hold a reference
+ * counted object. When an object's reference count drop to zero, it removes
+ * the object. This is a non intrusive mechanism and any object at any point
+ * in time can be referenced. When and object is reference counted, do not
+ * pass the object directly to other methods but rather, pass its
+ * reference around. Objects can be reference counted in both single threaded
+ * model and multi-threaded model
+ */
+
+#include <stdexcept>
+#include "Platform/Define.h"
+#include "Policies/ThreadingModel.h"
+#include "ReferenceHolder.h"
+
+template
+<
+typename T,
+class THREADING_MODEL = Trinity::SingleThreaded<T>
+>
+class Referencer
+{
+ typedef typename THREADING_MODEL::Lock Lock;
+ typedef ReferenceHolder<T, THREADING_MODEL> ReferenceeHolder;
+ public:
+
+ /// Constructs a referencer.
+ Referencer(T *ref = NULL);
+
+ /// Copy constructor
+ Referencer(const Referencer &obj) : i_holder(NULL) { *this = obj; }
+
+ /// Destructor
+ ~Referencer();
+
+ /// Referencee accessor
+ T* referencee(void) { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+ const T* referencee(void) const { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+
+ //T& referencee(void){ return _referencee(); }
+ //const T& referencee(void) const { return const_cast<Referencer *>(this)->_referencee(); }
+ operator T&(void) { return _referencee(); }
+ operator const T&(void) const { return *const_cast<Referencer *>(this)->_referencee(); }
+
+ /// cast operators
+ T* operator*() { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+ T const * operator*() const { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+
+ /// overload operators
+ T* operator->() { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+ const T * operator->() const { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+
+ /// operator =
+ Referencer& operator=(const Referencer &obj);
+ Referencer& operator=(T *);
+
+ /// returns true if i_referencee is null
+ bool isNull(void) const { return i_holder == NULL; }
+
+ private:
+
+ T& _referencee(void)
+ {
+ if( i_holder == NULL )
+ throw std::runtime_error("Invalid access to null pointer");
+ return *i_holder->i_referencee;
+ }
+
+ void deReference(ReferenceeHolder *);
+ void addReference(ReferenceeHolder *);
+
+ // private data
+ ReferenceeHolder *i_holder;
+};
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Utilities/TypeList.h b/src/server/game/TriniChat/framework/Utilities/TypeList.h
new file mode 100644
index 0000000..e94c25e
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Utilities/TypeList.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_TYPELIST_H
+#define TRINITY_TYPELIST_H
+
+/*
+ @struct TypeList
+ TypeList is the most simple but yet the most powerfull class of all. It holds
+ at compile time the different type of objects in a linked list.
+ */
+
+class TypeNull;
+
+template<typename HEAD, typename TAIL>
+struct TypeList
+{
+ typedef HEAD Head;
+ typedef TAIL Tail;
+};
+
+// enough for now.. can be expand at any point in time as needed
+#define TYPELIST_1(T1) TypeList<T1,TypeNull>
+#define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2) >
+#define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3) >
+#define TYPELIST_4(T1, T2, T3, T4) TypeList<T1, TYPELIST_3(T2, T3, T4) >
+#define TYPELIST_5(T1, T2, T3, T4, T5) TypeList<T1, TYPELIST_4(T2, T3, T4, T5) >
+#endif
\ No newline at end of file
diff --git a/src/server/game/TriniChat/framework/Utilities/UnorderedMap.h b/src/server/game/TriniChat/framework/Utilities/UnorderedMap.h
new file mode 100644
index 0000000..1479006
--- /dev/null
+++ b/src/server/game/TriniChat/framework/Utilities/UnorderedMap.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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
+ */
+
+#ifndef TRINITY_UNORDERED_MAP_H
+#define TRINITY_UNORDERED_MAP_H
+
++#include "Platform/CompilerDefs.h"
+#include "Platform/Define.h"
+
+#if COMPILER == COMPILER_INTEL
+#include <ext/hash_map>
+#elif COMPILER == COMPILER_GNU && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+#include <tr1/unordered_map>
+#elif COMPILER == COMPILER_GNU && __GNUC__ >= 3
+#include <ext/hash_map>
+#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1500 && _HAS_TR1 // VC9.0 and later
+#include <unordered_map>
+#else
+#include <hash_map>
+#endif
+
+#ifdef _STLPORT_VERSION
+#define UNORDERED_MAP std::hash_map
+using std::hash_map;
+#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1500 && _HAS_TR1
+#define UNORDERED_MAP std::tr1::unordered_map
+#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1300
+#define UNORDERED_MAP stdext::hash_map
+using stdext::hash_map;
+#elif COMPILER == COMPILER_INTEL
+#define UNORDERED_MAP std::hash_map
+using std::hash_map;
+#elif COMPILER == COMPILER_GNU && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+#define UNORDERED_MAP std::tr1::unordered_map
+#elif COMPILER == COMPILER_GNU && __GNUC__ >= 3
+#define UNORDERED_MAP __gnu_cxx::hash_map
+
+namespace __gnu_cxx
+{
+ template<> struct hash<unsigned long long>
+ {
+ size_t operator()(const unsigned long long &__x) const { return (size_t)__x; }
+ };
+ template<typename T> struct hash<T *>
+ {
+ size_t operator()(T * const &__x) const { return (size_t)__x; }
+ };
+
+};
+
+#else
+#define UNORDERED_MAP std::hash_map
+using std::hash_map;
+#endif
+#endif
\ No newline at end of file
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 29ecdbb..05b7cf9 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -80,6 +80,7 @@
#include "Warden.h"
#include "CalendarMgr.h"
#include "BattlefieldMgr.h"
+#include "IRCClient.h"
ACE_Atomic_Op<ACE_Thread_Mutex, bool> World::m_stopEvent = false;
uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE;
@@ -1234,6 +1235,168 @@ void World::LoadConfigSettings(bool reload)
if (reload)
sScriptMgr->OnConfigLoad(reload);
+
+ // IRC Configurations.
+ int ConfCnt = 0;
+ sIRC._chan_count = 0;
+ if (ConfigMgr::GetIntDefault("irc.active", 1) == 1)
+ sIRC.Active = true;
+ else
+ sIRC.Active = false;
+
+ sIRC._Host = ConfigMgr::GetStringDefault("irc.host", "irc.freenode.net");
+ if (sIRC._Host.size() > 0)
+ ConfCnt++;
+ sIRC._Mver = "Version 3.0.0";
+ sIRC._Port = ConfigMgr::GetIntDefault("irc.port", 6667);
+ sIRC._User = ConfigMgr::GetStringDefault("irc.user", "TriniChat");
+ sIRC._Pass = ConfigMgr::GetStringDefault("irc.pass", "Services Password");
+ sIRC._Nick = ConfigMgr::GetStringDefault("irc.nick", "TriniChat");
+ sIRC._Auth = ConfigMgr::GetIntDefault("irc.auth", 0);
+ sIRC._Auth_Nick = ConfigMgr::GetStringDefault("irc.auth.nick", "AuthNick");
+ sIRC._ICC = ConfigMgr::GetStringDefault("irc.icc", "001");
+ sIRC._defchan = ConfigMgr::GetStringDefault("irc.defchan", "lobby");
+ sIRC._ldefc = ConfigMgr::GetIntDefault("irc.ldef", 0);
+ sIRC._wct = ConfigMgr::GetIntDefault("irc.wct", 30000);
+ sIRC.ajoin = ConfigMgr::GetIntDefault("irc.ajoin", 1);
+ sIRC.ajchan = ConfigMgr::GetStringDefault("irc.ajchan", "world");
+ sIRC.onlrslt = ConfigMgr::GetIntDefault("irc.online.result", 10);
+ sIRC.BOTMASK = ConfigMgr::GetIntDefault("Botmask", 0);
+ sIRC.TICMASK = ConfigMgr::GetIntDefault("Ticketmask", 0);
+ sIRC.logfile = ConfigMgr::GetStringDefault("irc.logfile.prefix", "IRC_");
+ sIRC.logmask = ConfigMgr::GetIntDefault("irc.logmask", 0);
+ sIRC.logchan = ConfigMgr::GetStringDefault("irc.logchannel","");
+ sIRC.logchanpw = ConfigMgr::GetStringDefault("irc.logchannelpassword","");
+ for (int i = 1; i < MAX_CONF_CHANNELS;i++)
+ {
+ std::ostringstream ss;
+ ss << i;
+ std::string ci = "irc.chan_" + ss.str();
+ std::string pw = "irc.pass_" + ss.str();
+ std::string t_chan = ConfigMgr::GetStringDefault(ci.c_str(), "");
+ if (t_chan.size() > 0)
+ {
+ sIRC._chan_count++;
+ sIRC._irc_chan[sIRC._chan_count] = t_chan;
+ sIRC._irc_pass[sIRC._chan_count] = ConfigMgr::GetStringDefault(pw.c_str(), t_chan.c_str());
+ ci = "wow.chan_" + ss.str();
+ sIRC._wow_chan[sIRC._chan_count] = ConfigMgr::GetStringDefault(ci.c_str(), t_chan.c_str());
+ }
+ }
+ sIRC.JoinMsg = ConfigMgr::GetStringDefault("irc.joinmsg", "TriniChat2 $Ver for Trinitycore 3.3.x Maintained by SPGM of Trinitycore http://code.google.com/p/spgm-trinity/");
+ sIRC.RstMsg = ConfigMgr::GetStringDefault("irc.rstmsg", "TriniChat Is Restarting, I Will Be Right Back!");
+ sIRC.kikmsg = ConfigMgr::GetStringDefault("irc.kickmsg", "Do Not Kick Me Again, Severe Actions Will Be Taken!");
+
+ // IRC LINES
+ sIRC.ILINES[WOW_IRC] = ConfigMgr::GetStringDefault("chat.wow_irc", "\003<WoW>[\002$Name($Level)\002\003] $Msg");
+ sIRC.ILINES[IRC_WOW] = ConfigMgr::GetStringDefault("chat.irc_wow", "\003<IRC>[$Name]: $Msg");
+ sIRC.ILINES[JOIN_WOW] = ConfigMgr::GetStringDefault("chat.join_wow", "\00312>>\00304 $Name \003Joined The Channel!");
+ sIRC.ILINES[JOIN_IRC] = ConfigMgr::GetStringDefault("chat.join_irc", "\003[$Name]: Has Joined IRC!");
+ sIRC.ILINES[LEAVE_WOW] = ConfigMgr::GetStringDefault("chat.leave_wow", "\00312<<\00304 $Name \003Left The Channel!");
+ sIRC.ILINES[LEAVE_IRC] = ConfigMgr::GetStringDefault("chat.leave_irc", "\003[$Name]: Has Left IRC!");
+ sIRC.ILINES[CHANGE_NICK] = ConfigMgr::GetStringDefault("chat.change_nick", "\003<> $Name Is Now Known As $NewName!");
+
+ // TriniChat Options
+ sIRC._MCA = ConfigMgr::GetIntDefault("irc.maxattempt", 10);
+ sIRC._autojoinkick = ConfigMgr::GetIntDefault("irc.autojoin_kick", 1);
+ sIRC._cmd_prefx = ConfigMgr::GetStringDefault("irc.command_prefix", ".");
+
+ sIRC._op_gm = ConfigMgr::GetIntDefault("irc.op_gm_login", 0);
+ sIRC._op_gm_lev = ConfigMgr::GetIntDefault("irc.op_gm_level", 3);
+
+ // Misc Options
+ sIRC.games = ConfigMgr::GetIntDefault("irc.fun.games", 0);
+ sIRC.gmlog = ConfigMgr::GetIntDefault("irc.gmlog", 1);
+ sIRC.BOTMASK = ConfigMgr::GetIntDefault("BotMask", 0);
+ sIRC.TICMASK = ConfigMgr::GetIntDefault("Ticketmask", 0);
+ sIRC.Status = ConfigMgr::GetIntDefault("irc.StatusChannel", 1);
+ sIRC.anchn = ConfigMgr::GetIntDefault("irc.AnnounceChannel", 1);
+ sIRC.ticann = ConfigMgr::GetIntDefault("irc.Tickets", 1);
+ sIRC.autoanc = ConfigMgr::GetIntDefault("irc.auto.announce", 30);
+ sIRC.ojGM1 = ConfigMgr::GetStringDefault("irc.gm1", "[VIP]");
+ sIRC.ojGM2 = ConfigMgr::GetStringDefault("irc.gm2", "[Donator]");
+ sIRC.ojGM3 = ConfigMgr::GetStringDefault("irc.gm3", "[Bug Tracker]");
+ sIRC.ojGM4 = ConfigMgr::GetStringDefault("irc.gm4", "[Moderator]");
+ sIRC.ojGM5 = ConfigMgr::GetStringDefault("irc.gm5", "[Game Master]");
+ sIRC.ojGM6 = ConfigMgr::GetStringDefault("irc.gm6", "[Admin]");
+ sIRC.ojGM7 = ConfigMgr::GetStringDefault("irc.gm7", "[Developer]");
+ sIRC.ojGM8 = ConfigMgr::GetStringDefault("irc.gm8", "[Owner]");
+
+ // REQUIRED GM LEVEL
+ QueryResult result = WorldDatabase.PQuery("SELECT `Command`, `gmlevel` FROM `irc_commands` ORDER BY `Command`");
+ if (result)
+ {
+ Field *fields = result->Fetch();
+ for (uint64 i=0; i < result->GetRowCount(); i++)
+ {
+ //TODO: ELSEIF? STRCMP?
+ std::string command = fields[0].GetCString();
+ int gmlvl = fields[1].GetUInt8();
+ if (command == "acct") sIRC.CACCT = gmlvl;
+ if (command == "ban") sIRC.CBAN = gmlvl;
+ if (command == "char") sIRC.CCHAN = gmlvl;
+ if (command == "char") sIRC.CCHAR = gmlvl;
+ if (command == "fun") sIRC.CFUN = gmlvl;
+ if (command == "help") sIRC.CHELP = gmlvl;
+ if (command == "inchan") sIRC.CINCHAN = gmlvl;
+ if (command == "info") sIRC.CINFO = gmlvl;
+ if (command == "item") sIRC.CITEM = gmlvl;
+ if (command == "jail") sIRC.CJAIL = gmlvl;
+ if (command == "kick") sIRC.CKICK = gmlvl;
+ if (command == "kill") sIRC._KILL = gmlvl;
+ if (command == "level") sIRC.CLEVEL = gmlvl;
+ if (command == "lookup") sIRC.CLOOKUP = gmlvl;
+ if (command == "money") sIRC.CMONEY = gmlvl;
+ if (command == "mute") sIRC.CMUTE = gmlvl;
+ if (command == "online") sIRC.CONLINE = gmlvl;
+ if (command == "pm") sIRC.CPM = gmlvl;
+ if (command == "reconnect") sIRC.CRECONNECT = gmlvl;
+ if (command == "reload") sIRC.CRELOAD = gmlvl;
+ if (command == "restart") sIRC.CSHUTDOWN = gmlvl;
+ if (command == "revive") sIRC.CREVIVE = gmlvl;
+ if (command == "saveall") sIRC.CSAVEALL = gmlvl;
+ if (command == "server") sIRC.CSERVERCMD = gmlvl;
+ if (command == "shutdown") sIRC.CSHUTDOWN = gmlvl;
+ if (command == "spell") sIRC.CSPELL = gmlvl;
+ if (command == "sysmsg") sIRC.CSYSMSG = gmlvl;
+ if (command == "tele") sIRC.CTELE = gmlvl;
+ if (command == "top") sIRC.CTOP = gmlvl;
+ if (command == "who") sIRC.CWHO = gmlvl;
+ result->NextRow();
+ }
+ }
+ else
+ {
+ sIRC.CACCT = 3;
+ sIRC.CBAN = 3;
+ sIRC.CCHAN = 3;
+ sIRC.CCHAR = 3;
+ sIRC.CFUN = 3;
+ sIRC.CHELP = 3;
+ sIRC.CINCHAN = 3;
+ sIRC.CINFO = 3;
+ sIRC.CITEM = 3;
+ sIRC.CJAIL = 3;
+ sIRC.CKICK = 3;
+ sIRC._KILL = 3;
+ sIRC.CLEVEL = 3;
+ sIRC.CLOOKUP = 3;
+ sIRC.CMONEY = 3;
+ sIRC.CMUTE = 3;
+ sIRC.CONLINE = 3;
+ sIRC.CPM = 3;
+ sIRC.CRECONNECT= 3;
+ sIRC.CRELOAD = 3;
+ sIRC.CREVIVE = 3;
+ sIRC.CSAVEALL = 3;
+ sIRC.CSERVERCMD= 3;
+ sIRC.CSHUTDOWN = 3;
+ sIRC.CSPELL = 3;
+ sIRC.CSYSMSG = 3;
+ sIRC.CTELE = 3;
+ sIRC.CTOP = 3;
+ sIRC.CWHO = 3;
+ }
}
extern void LoadGameObjectModelList();
@@ -1252,6 +1415,7 @@ void World::SetInitialWorldSettings()
///- Initialize config settings
LoadConfigSettings();
+ sLog->outInfo(LOG_FILTER_GENERAL, "Loading TrinityCore configuration settings...");
///- Initialize Allowed Security Level
LoadDBAllowedSecurityLevel();
@@ -1701,6 +1865,9 @@ void World::SetInitialWorldSettings()
LoginDatabase.PExecute("INSERT INTO uptime (realmid, starttime, uptime, revision) VALUES(%u, %u, 0, '%s')",
realmID, uint32(m_startTime), _FULLVERSION); // One-time query
+ static uint32 autoanc = 1;
+ autoanc = sIRC.autoanc;
+
m_timers[WUPDATE_WEATHERS].SetInterval(1*IN_MILLISECONDS);
m_timers[WUPDATE_AUCTIONS].SetInterval(MINUTE*IN_MILLISECONDS);
m_timers[WUPDATE_UPTIME].SetInterval(m_int_configs[CONFIG_UPTIME_UPDATE]*MINUTE*IN_MILLISECONDS);
@@ -1714,6 +1881,8 @@ void World::SetInitialWorldSettings()
m_timers[WUPDATE_PINGDB].SetInterval(getIntConfig(CONFIG_DB_PING_INTERVAL)*MINUTE*IN_MILLISECONDS); // Mysql ping time in minutes
+ m_timers[WUPDATE_AUTOANC].SetInterval(autoanc*MINUTE*1000);
+
//to set mailtimer to return mails every day between 4 and 5 am
//mailtimer is increased when updating auctions
//one second is 1000 -(tested on win system)
@@ -2077,6 +2246,12 @@ void World::Update(uint32 diff)
WorldDatabase.KeepAlive();
}
+ if (m_timers[WUPDATE_AUTOANC].Passed())
+ {
+ m_timers[WUPDATE_AUTOANC].Reset();
+ SendRNDBroadcastIRC();
+ }
+
// update the instance reset times
sInstanceSaveMgr->Update();
@@ -2663,6 +2838,20 @@ void World::SendAutoBroadcast()
sLog->outDebug(LOG_FILTER_GENERAL, "AutoBroadcast: '%s'", msg.c_str());
}
+void World::SendRNDBroadcastIRC()
+{
+ std::string msg;
+ QueryResult result = WorldDatabase.PQuery("SELECT `message` FROM `irc_autoannounce` ORDER BY RAND() LIMIT 1");
+ if (!result)
+ return;
+ msg = result->Fetch()[0].GetString();
+
+ sWorld->SendWorldText(6612,msg.c_str());
+ std::string ircchan = "#";
+ ircchan += sIRC._irc_chan[sIRC.anchn].c_str();
+ sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("\00304,08\037/!\\\037\017\00304 Automatic System Message \00304,08\037/!\\\037\017 %s", "%s", msg.c_str()), true);
+}
+
void World::UpdateRealmCharCount(uint32 accountId)
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_COUNT);
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 612078f..3562fcd 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -75,6 +75,7 @@ enum WorldTimers
WUPDATE_EVENTS,
WUPDATE_CLEANDB,
WUPDATE_AUTOBROADCAST,
+ WUPDATE_AUTOANC,
WUPDATE_MAILBOXQUEUE,
WUPDATE_DELETECHARS,
WUPDATE_PINGDB,
@@ -524,6 +525,7 @@ class World
void AddSession(WorldSession* s);
void SendAutoBroadcast();
bool RemoveSession(uint32 id);
+ void SendRNDBroadcastIRC();
/// Get the number of current active sessions
void UpdateMaxSessionCounters();
const SessionMap& GetAllSessions() const { return m_sessions; }
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index cf46180..f9c83ac 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -132,6 +132,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/game/Spells
${CMAKE_SOURCE_DIR}/src/server/game/Spells/Auras
${CMAKE_SOURCE_DIR}/src/server/game/Texts
+ ${CMAKE_SOURCE_DIR}/src/server/game/TriniChat
${CMAKE_SOURCE_DIR}/src/server/game/Tickets
${CMAKE_SOURCE_DIR}/src/server/game/Tools
${CMAKE_SOURCE_DIR}/src/server/game/Warden
diff --git a/src/server/scripts/Commands/cs_message.cpp b/src/server/scripts/Commands/cs_message.cpp
index e2c5349..18c7daf 100644
--- a/src/server/scripts/Commands/cs_message.cpp
+++ b/src/server/scripts/Commands/cs_message.cpp
@@ -27,6 +27,7 @@
#include "ChannelMgr.h"
#include "Language.h"
#include "Player.h"
+#include "IRCClient.h"
class message_commandscript : public CommandScript
{
@@ -133,6 +134,13 @@ class message_commandscript : public CommandScript
if (!*args)
return false;
+ if ((sIRC.BOTMASK & 256) != 0)
+ {
+ std::string ircchan = "#";
+ ircchan += sIRC._irc_chan[sIRC.anchn].c_str();
+ sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("\00304,08\037/!\\\037\017\00304 System Message \00304,08\037/!\\\037\017 %s", "%s", args), true);
+ }
+
char buff[2048];
sprintf(buff, handler->GetTrinityString(LANG_SYSTEMMESSAGE), args);
sWorld->SendServerMessage(SERVER_MSG_STRING, buff);
@@ -153,6 +161,13 @@ class message_commandscript : public CommandScript
if (!*args)
return false;
+ if ((sIRC.BOTMASK & 256) != 0)
+ {
+ std::string ircchan = "#";
+ ircchan += sIRC._irc_chan[sIRC.anchn].c_str();
+ sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("\00304,08\037/!\\\037\017\00304 Global Notify \00304,08\037/!\\\037\017 %s", "%s", args), true);
+ }
+
std::string str = handler->GetTrinityString(LANG_GLOBAL_NOTIFY);
str += args;
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index cacefea..69e753c 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -34,6 +34,7 @@
#include "Player.h"
#include "Pet.h"
#include "LFG.h"
+#include "IRCClient.h"
#include "GroupMgr.h"
class misc_commandscript : public CommandScript
@@ -121,6 +122,7 @@ class misc_commandscript : public CommandScript
{ "bindsight", SEC_ADMINISTRATOR, false, HandleBindSightCommand, "", NULL },
{ "unbindsight", SEC_ADMINISTRATOR, false, HandleUnbindSightCommand, "", NULL },
{ "playall", SEC_GAMEMASTER, false, HandlePlayAllCommand, "", NULL },
+ { "tcrecon", SEC_MODERATOR, false, HandleIRCRelogCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
return commandTable;
@@ -543,6 +545,25 @@ class misc_commandscript : public CommandScript
return true;
}
+
+ static bool HandleIRCpmCommand(ChatHandler* handler, const char* args)
+ {
+ std::string Msg = args;
+ if (Msg.find(" ") == std::string::npos)
+ return false;
+ std::string To = Msg.substr(0, Msg.find(" "));
+ Msg = Msg.substr(Msg.find(" ") + 1);
+ std::size_t pos;
+ while ((pos = To.find("||")) != std::string::npos)
+ {
+ std::size_t find1 = To.find("||", pos);
+ To.replace(pos, find1 - pos + 2, "|");
+ }
+ sIRC.SendIRC("PRIVMSG "+To+" : <WoW>["+handler->GetSession()->GetPlayerName()+"] : " + Msg);
+ sIRC.Send_WoW_Player(handler->GetSession()->GetPlayer(), "|cffCC4ACCTo ["+To+"]: "+Msg);
+ return true;
+ }
+
// Summon group of player
static bool HandleGroupSummonCommand(ChatHandler* handler, char const* args)
{
@@ -2907,6 +2928,14 @@ class misc_commandscript : public CommandScript
return true;
}
+ static bool HandleIRCRelogCommand(ChatHandler* handler, const char *args)
+ {
+ handler->SendSysMessage("TriniChat is dropping from IRC Server");
+ sIRC.ResetIRC();
+ handler->SendSysMessage("TriniChat is reconnecting to IRC Server");
+ return true;
+ }
+
static bool HandlePossessCommand(ChatHandler* handler, char const* /*args*/)
{
Unit* unit = handler->getSelectedUnit();
diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp
index aee01f4..b781172 100644
--- a/src/server/scripts/Commands/cs_ticket.cpp
+++ b/src/server/scripts/Commands/cs_ticket.cpp
@@ -30,6 +30,7 @@
#include "Player.h"
#include "TicketMgr.h"
#include "ScriptMgr.h"
+#include "IRCClient.h"
class ticket_commandscript : public CommandScript
{
@@ -131,6 +132,14 @@ class ticket_commandscript : public CommandScript
std::string msg = ticket->FormatMessageString(*handler, NULL, target.c_str(), NULL, NULL);
handler->SendGlobalGMSysMessage(msg.c_str());
+ if ((sIRC.TICMASK & 16) != 0 && (sIRC.BOTMASK & 1024) != 0)
+ {
+ std::string ircchan = "#";
+ std::ostringstream smsg;
+ ircchan += sIRC._irc_chan[sIRC.ticann].c_str();
+ smsg << "[\00304Ticket Assigned\003][By:\00304 " << ticket->GetPlayerName().c_str() << " \003][ID: \00304" << ticket->GetId() << " \003][Assigned To: \00304" << target.c_str() << " \003]";
+ sIRC.Send_IRC_Channel(ircchan, smsg.str().c_str() , true);
+ }
return true;
}
@@ -162,6 +171,15 @@ class ticket_commandscript : public CommandScript
std::string msg = ticket->FormatMessageString(*handler, player ? player->GetName().c_str() : "Console", NULL, NULL, NULL);
handler->SendGlobalGMSysMessage(msg.c_str());
+ if ((sIRC.TICMASK & 16) != 0 && (sIRC.BOTMASK & 1024) != 0)
+ {
+ std::string ircchan = "#";
+ std::ostringstream smsg;
+ ircchan += sIRC._irc_chan[sIRC.ticann].c_str();
+ smsg << "[\00304Ticket Closed\003][By:\00304 " << ticket->GetPlayerName().c_str() << " \003][ID: \00304" << ticket->GetId() << " \003][Assigned To: \00304" << player->GetName().c_str() << " \003]";
+ sIRC.Send_IRC_Channel(ircchan, smsg.str().c_str() , true);
+ }
+
// Inform player, who submitted this ticket, that it is closed
if (Player* submitter = ticket->GetPlayer())
{
@@ -264,6 +282,16 @@ class ticket_commandscript : public CommandScript
std::string msg = ticket->FormatMessageString(*handler, NULL, NULL, NULL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetName().c_str() : "Console");
handler->SendGlobalGMSysMessage(msg.c_str());
+ if ((sIRC.TICMASK & 16) != 0 && (sIRC.BOTMASK & 1024) != 0)
+ {
+ std::string ircchan = "#";
+ std::ostringstream smsg;
+ ircchan += sIRC._irc_chan[sIRC.ticann].c_str();
+ smsg << "[\00304Ticket Deleted\003][By:\00304 " << ticket->GetPlayerName().c_str() << " \003][ID: \00304" << ticket->GetId() << " \003][Deleted By: \00304"
+ << handler->GetSession()->GetPlayer()->GetName().c_str() << " \003]";
+ sIRC.Send_IRC_Channel(ircchan, smsg.str().c_str() , true);
+ }
+
sTicketMgr->RemoveTicket(ticket->GetId());
sTicketMgr->UpdateLastChange();
@@ -395,6 +423,16 @@ class ticket_commandscript : public CommandScript
std::string msg = ticket->FormatMessageString(*handler, NULL, assignedTo.c_str(),
handler->GetSession() ? handler->GetSession()->GetPlayer()->GetName().c_str() : "Console", NULL);
handler->SendGlobalGMSysMessage(msg.c_str());
+
+ if ((sIRC.TICMASK & 16) != 0 && (sIRC.BOTMASK & 1024) != 0)
+ {
+ std::string ircchan = "#";
+ std::ostringstream smsg;
+ ircchan += sIRC._irc_chan[sIRC.ticann].c_str();
+ smsg << "[\00304Ticket Assigned\003][By:\00304 " << ticket->GetPlayerName().c_str() << " \003][ID: \00304" << ticket->GetId() << " \003][Unssigned From: \00304"
+ << assignedTo.c_str() << " \003][By: \00304" << handler->GetSession()->GetPlayer()->GetName().c_str() << " \003]";
+ sIRC.Send_IRC_Channel(ircchan, smsg.str().c_str() , true);
+ }
return true;
}
diff --git a/src/server/worldserver/CommandLine/CliRunnable.cpp b/src/server/worldserver/CommandLine/CliRunnable.cpp
index 66740f1..f1cfc47 100644
--- a/src/server/worldserver/CommandLine/CliRunnable.cpp
+++ b/src/server/worldserver/CommandLine/CliRunnable.cpp
@@ -34,6 +34,7 @@
#include "MapManager.h"
#include "Player.h"
#include "Util.h"
+#include "../TriniChat/IRCClient.h"
#if PLATFORM != PLATFORM_WINDOWS
#include <readline/readline.h>
@@ -116,6 +117,15 @@ void commandFinished(void*, bool /*success*/)
fflush(stdout);
}
+//Reconnect TriniChat to IRC server via CLI command
+bool HandleIRCRelogCommand(bool, const char *args)
+{
+ sLog->outError(LOG_FILTER_GENERAL, "TriniChat is dropping from IRC Server");
+ sIRC.ResetIRC();
+ sLog->outError(LOG_FILTER_GENERAL, "TriniChat is reconnecting to IRC Server");
+ return true;
+}
+
#ifdef linux
// Non-blocking keypress detector, when return pressed, return 1, else always return 0
int kb_hit_return()
diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp
index 5287847..54df041 100644
--- a/src/server/worldserver/Main.cpp
+++ b/src/server/worldserver/Main.cpp
@@ -30,6 +30,7 @@
#include "Log.h"
#include "Master.h"
+#include "../TriniChat/IRCClient.h"
#ifndef _TRINITY_CORE_CONFIG
# define _TRINITY_CORE_CONFIG "worldserver.conf"
diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp
index 56dd64b..6dbc46b 100644
--- a/src/server/worldserver/Master.cpp
+++ b/src/server/worldserver/Master.cpp
@@ -41,6 +41,7 @@
#include "Timer.h"
#include "Util.h"
#include "AuthSocket.h"
+#include "../TriniChat/IRCClient.h"
#include "RealmList.h"
#include "BigNumber.h"
@@ -244,6 +245,15 @@ int Master::Run()
soap_thread = new ACE_Based::Thread(runnable);
}
+ // Start up TriniChat
+ if (sIRC.Active == 1)
+ {
+ ACE_Based::Thread irc(new IRCClient);
+ irc.setPriority ((ACE_Based::Priority)2);
+ }
+ else
+ sLog->outError(LOG_FILTER_GENERAL, "*** TriniChat Is Disabled. *");
+
///- Start up freeze catcher thread
if (uint32 freeze_delay = ConfigMgr::GetIntDefault("MaxCoreStuckTime", 0))
{
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 069c027..6b420b6 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -2836,3 +2836,268 @@ Log.Async.Enable = 0
#
###################################################################################################
+
+#########################################################
+# TriniChat IRC BOT For Trinity Core Configuration File #
+#########################################################
+# irc.active
+# Enable TriniChat Addon
+# Default: 1 - Enable
+# 0 - Disable
+#
+irc.active = 1
+
+##################################################
+# irc.icc
+# IRC connect code
+# Default: 001 - Welcome To Network msg
+# 375 - Beginning Of MOTD
+# 376 - End Of MOTD
+#
+irc.icc = 001
+
+##################################################
+# irc.host
+# IRC server to have TriniChat connect to
+#
+irc.host = "irc.xxxx.net"
+
+##################################################
+# irc.port
+# IRC server port to use
+#
+irc.port = "1337"
+
+##################################################
+# irc.user
+# The username to have TriniChat use to connect to the IRC server
+# irc.nick
+# IRC nickname to be used by the bot
+# irc.pass
+# The password to be used to identify to NickServ (IRC NickName Enforcement Services)
+#
+irc.user = "Trini_Chat"
+irc.nick = "Trini_Chat"
+irc.pass = "ServicesPass"
+
+##################################################
+# irc.auth
+# IRC Authentication Method
+# Default: 0 - Disable
+# 1 - NickServ - Normal Method - PRIVMSG NickServ :IDENTIFY Password
+# 2 - NickServ - Alternate Method To Identify To A Different Nick - PRIVMSG NickServ :IDENTIFY irc.auth.nick Password
+# 3 - QuakeNet - Normal Method - PRIVMSG Q@CServe.quakenet.org :AUTH irc.nick Password
+# 4 - QuakeNet - Alternate Method To Identify To A Different Nick - PRIVMSG Q@CServe.quakenet.org :AUTH irc.auth.nick Password
+# irc.auth.nick
+# IRC Nickname to use if Auth method 2 or 4 is used
+#
+irc.auth = 0
+irc.auth.nick = "AuthNick"
+
+##################################################
+# irc.ldef
+# Leave a defined IRC channel on server connect
+# Default: 0 - Disable
+# 1 - Enable
+# irc.defchan
+# IRC channel to leave on server connect if irc.ldef is on
+#
+irc.ldef = 0
+irc.defchan = "lobby"
+
+##################################################
+# irc.wct
+# Time to wait before (re)attemptimg connection to IRC server
+# Default: 30000 - (30 Seconds)
+# irc.maxattempt
+# Maximum attempts to try IRC server
+# Default: 20
+#
+irc.wct = 30000
+irc.maxattempt = 20
+
+##################################################
+# irc.auto.announce
+# Time to wait in Minutes to announce random messages from database.
+# Default: 30 - (30 Minutes)
+#
+irc.auto.announce = 30
+
+##################################################
+# irc.autojoin_kick
+# Autojoin IRC channel if kicked
+# Default: 1 - Enable
+# 0 - Disable
+#
+irc.autojoin_kick = 1
+
+##################################################
+# irc.command_prefix
+# IRC command prefix
+# Example: (.)online all
+#
+irc.command_prefix = "\"
+
+##################################################
+# irc.joinmsg
+# irc.rstmsg
+# irc.kickmsg
+# TriniChat bot join/restart/kick messages
+#
+irc.joinmsg = "Trinity Core With TriniChat $Ver Is Up And Running! Command Trigger Is: $Trigger"
+irc.rstmsg = "TriniChat Is Restarting, I Will Be Right Back."
+irc.kickmsg = "Do Not Kick Me Again, Severe Actions Will Be Taken!"
+
+##################################################
+# irc.chan_#
+# wow.chan_#
+# IRC and WOW channels to link. Leave # out of IRC channel. Both channels _ARE_ case sensitive
+# NOTE: you can have more than 1 IRC channel linked to wow channels, as in example:
+# Example: irc.chan_1 = "Trinity"
+# irc.chan_2 = "trinity2"
+# wow.chan_1 = "world"
+# wow.chan_2 = "LookingForGroup"
+# irc.pass_#
+# Passwords for said IRC channels (IRC server side)
+# Example:
+# irc.pass_1 = "password" password for irc channel #1
+# irc.pass_2 = "password2" password for irc channel #2
+irc.chan_1 = "ircchan"
+wow.chan_1 = "world"
+irc.pass_1 = "pass"
+
+##################################################
+# irc.StatusChannel
+# Channel Number To Display Status Messages In (AuctionHouse, Levels, Deaths, Etc)
+# Default: 1 - Channel ID 1
+# irc.AnnounceChannel
+# Channel Number To Display Announcements In (Announces, Notifies, Event)
+# Default: 1 - Channel ID 1
+# irc.Tickets
+# Channel Number To Display Ticket Announcment in (Create, Edit, Closed, lag Reports)
+# Default: 1 - Channel ID 1
+# Note: Botmask : Enable Ticket Announment must be activ
+#
+irc.StatusChannel = 1
+irc.AnnounceChannel = 1
+irc.Tickets = 1
+
+##################################################
+# irc.op_gm_login
+# Op The GM In All Channels The Bot Is On When They Log In To TriniChat
+# Default: 0 - Disable
+# 1 - Enable
+# irc.op_gm_level
+# The Minimum GM Level Required To Have The Bot Op The User
+# Default: 5 - GM Level 5
+#
+irc.op_gm_login = 0
+irc.op_gm_level = 3
+
+##################################################
+# irc.ajoin (Experimental/Under Development)
+# Force players to autojoin a WOW in game channel
+# Atleast one player must be in the channel on server start, and atleast one person online for invite to work
+# Default: 0 - Disable
+# 1 - Enable
+# irc.ajchan
+# Channel to join if above is Enabled.
+#
+irc.ajoin = 1
+irc.ajchan = "world"
+
+##################################################
+# irc.online.result
+# Maximum number of results per line for the online command
+#
+irc.online.result = 30
+
+##################################################
+# chat.*** (Defineable Strings) (maybe more in future)
+# wow_* - String is displayed in IRC channel
+# irc_* - String is displayed in WOW channel
+# Options: $Name, $Level, $Class, $Msg, $GM (not all options work in every string)
+#
+chat.wow_irc = "<WoW>[$Name($Level)[$Class]] $Msg"
+chat.irc_wow = "<IRC>[$Name]: $Msg"
+chat.join_wow = "12>>04 $GM$Name Joined The $Channel Channel!"
+chat.join_irc = "[$Name]: Has Joined IRC!"
+chat.leave_wow = "12<<04 $GM$Name Left The $Channel Channel!"
+chat.leave_irc = "[$Name]: Has Left IRC!"
+chat.change_nick = "<> $Name Is Now Known As $NewName!"
+
+##################################################
+# Botmask
+# This defines what the bot announces, if its 0 everything is disabled
+# simply add the values of the elements you want to create this mask.
+# Example: WoW join/leaves are 1 and IRC join/leaves are 2, if you want both of these active then the BotMask is 3.
+# (1)Display WoW Chan Join/Leaves In IRC
+# (2)Display IRC Chan Join/Leaves/NickChanges In WoW
+# (4)Display Unknown Command Message When Trigger Is Used And No Command Exists
+# (8)Announce Security Level > 0 As GM At Login
+# (16)Announce GM In GM ON State AS GM At Login
+# (32)Return Errors To Notice. (If disabled then default is Private Message)
+# (64)Display WoW Status Messages (Levels/Deaths)
+# (128)Display Nick Changes From IRC In WOW
+# (256)Display WoW Announces/Notifies In IRC
+# (512)Do Not Let Players Use Commands On Higher GM Level Players
+# (1024)Enable Ticket Annoucemnt
+# (2048)Enable AuctionHouse Announcements !!DISSABLED!!
+#
+# Tickets Botmask
+# (1) Announce Created Tickets.
+# (2) Announce Updated Tickets.
+# (4) Announce Abandoned Tickets.
+# (8) Announce Lag Reports.
+# (16) Announce Tickets updated by Gms. (Close ,Assigned ,Unassigned and ect..)
+#
+
+Botmask = 2047
+Ticketmask = 31
+
+##################################################
+# irc.gmlog
+# Minimum GM level to not show login/pass info in IRC logs
+# irc.logfile.prefix
+# The prefix of the IRC logfile. Directories can be added here.
+# Example: "IRC/IRC_" outputs IRC_YYYY-MM-DD.log to the IRC subdirectory in your logs dir
+# irc.logchannel
+# Specefies the channel where logged output gets broadcasted.
+# Default: "" (none)
+# irc.logchannelpw
+# The password for the log channel.
+# irc.logmask
+# Bitmask, see Botmask for explanation. Determines what gets logged to the logchannel.
+# (0) Do not broadcast into logchannel.
+# (1) Broadcast IRC Commands into logchannel.
+# (2) Broadcast Ingame GM Commands into logchannel.
+# (3) Broadcast both IRC Commands and GM Commands into logchannel.
+irc.gmlog = 1
+irc.logfile.prefix = "IRC_"
+irc.logchannel = "testlog"
+irc.logchannelpw = ""
+irc.logmask = 3
+
+##################################################
+# irc.fun.games (Experimental/Under Development)
+# Enable TriniChat Games
+# Default: 0 - Disable
+# 1 - Enable
+#
+irc.fun.games = 0
+
+##################################################
+# irc.gm#
+# GM tag to append to (GM onjoin / online command) IRC color codes are acceptable
+#
+irc.gm1 = "[VIP]"
+irc.gm2 = "[Donator]"
+irc.gm3 = "[Bug Tracker]"
+irc.gm4 = "[Moderator]"
+irc.gm5 = "[Game Master]"
+irc.gm6 = "[Admin]"
+irc.gm7 = "[Developer]"
+irc.gm8 = "[Owner]"
+
+###################################################################################################
+#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment