Advertisement
Guest User

Untitled

a guest
Jan 16th, 2012
198
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 227.76 KB | None | 0 0
  1. From 5d04e4958d659604f76821e992b81364d633fb6c Mon Sep 17 00:00:00 2001
  2. From: LordPsyan <samccstudios@gmail.com>
  3. Date: Mon, 16 Jan 2012 10:14:40 -0600
  4. Subject: [PATCH] 2012-01-16_MangChat
  5.  
  6. ---
  7. README.MANGCHAT | 31 +
  8. sql/custom/mangos_irc.sql | 55 +
  9. src/game/AuctionHouseHandler.cpp | 4 +
  10. src/game/CMakeLists.txt | 7 +
  11. src/game/Channel.cpp | 5 +
  12. src/game/CharacterHandler.cpp | 4 +
  13. src/game/Chat.cpp | 1 +
  14. src/game/Chat.h | 1 +
  15. src/game/ChatHandler.cpp | 3 +
  16. src/game/GMTicketHandler.cpp | 13 +
  17. src/game/GameEventMgr.cpp | 9 +-
  18. src/game/Level1.cpp | 37 +
  19. src/game/Player.cpp | 11 +
  20. src/game/mangchat/IRCClient.cpp | 103 ++
  21. src/game/mangchat/IRCClient.h | 233 ++++
  22. src/game/mangchat/IRCCmd.cpp | 941 ++++++++++++++
  23. src/game/mangchat/IRCCmd.h | 137 ++
  24. src/game/mangchat/IRCCmde.cpp | 2059 +++++++++++++++++++++++++++++++
  25. src/game/mangchat/IRCConf.cpp | 189 +++
  26. src/game/mangchat/IRCConf.h | 12 +
  27. src/game/mangchat/IRCFunc.h | 268 ++++
  28. src/game/mangchat/IRCIO.cpp | 437 +++++++
  29. src/game/mangchat/IRCLog.cpp | 74 ++
  30. src/game/mangchat/IRCLog.h | 36 +
  31. src/game/mangchat/IRCSock.cpp | 160 +++
  32. src/game/mangchat/MCS_OnlinePlayers.cpp | 83 ++
  33. src/game/mangchat/MCS_OnlinePlayers.h | 41 +
  34. src/game/mangchat/mangchat.conf.dist.in | 204 +++
  35. src/mangosd/Main.cpp | 12 +-
  36. src/mangosd/Master.cpp | 8 +
  37. win/VC90/game.vcproj | 60 +
  38. 31 files changed, 5235 insertions(+), 3 deletions(-)
  39. create mode 100644 README.MANGCHAT
  40. create mode 100644 sql/custom/mangos_irc.sql
  41. create mode 100644 src/game/mangchat/IRCClient.cpp
  42. create mode 100644 src/game/mangchat/IRCClient.h
  43. create mode 100644 src/game/mangchat/IRCCmd.cpp
  44. create mode 100644 src/game/mangchat/IRCCmd.h
  45. create mode 100644 src/game/mangchat/IRCCmde.cpp
  46. create mode 100644 src/game/mangchat/IRCConf.cpp
  47. create mode 100644 src/game/mangchat/IRCConf.h
  48. create mode 100644 src/game/mangchat/IRCFunc.h
  49. create mode 100644 src/game/mangchat/IRCIO.cpp
  50. create mode 100644 src/game/mangchat/IRCLog.cpp
  51. create mode 100644 src/game/mangchat/IRCLog.h
  52. create mode 100644 src/game/mangchat/IRCSock.cpp
  53. create mode 100644 src/game/mangchat/MCS_OnlinePlayers.cpp
  54. create mode 100644 src/game/mangchat/MCS_OnlinePlayers.h
  55. create mode 100644 src/game/mangchat/mangchat.conf.dist.in
  56.  
  57. diff --git a/README.MANGCHAT b/README.MANGCHAT
  58. new file mode 100644
  59. index 0000000..d667dfa
  60. --- /dev/null
  61. +++ b/README.MANGCHAT
  62. @@ -0,0 +1,31 @@
  63. +[url]https://gist.github.com/1003422[/url]
  64. +
  65. +Readme:
  66. +Apply sql/custom/mangos_irc.sql
  67. +Copy and configure mangchat.conf
  68. +
  69. +Changes:
  70. +Sql tables renamed to lowercase format
  71. +
  72. +Authors:
  73. +Cybrax <cybraxvd@gmail.com>
  74. +|Death| <death@hell360.net>,
  75. +Lice <lice@yeuxverts.net>
  76. +Dj_baby
  77. +Sanaell
  78. +Tase
  79. +Shinzon <shinzon@wowgollum.com>
  80. +Xeross
  81. +3raZar3
  82. +the orangevirus team <[url=http://www.orangevir.us]www.orangevir.us[/url]>
  83. +
  84. +Todolist:
  85. +Cleanup
  86. +Rewrite
  87. +
  88. +Compiled under win32 VS2008 with VC90.
  89. +[b]Not tested [u]ingame[/u][/b] ;) again but should work ;)
  90. +
  91. +If you want a clean mangos with this patch here up to date go [url=https://github.com/Darkknight900/mangos/tree/mangchat]here[/url]. For a clean patch you can diff it against my [url=https://github.com/Darkknight900/mangos/tree/master]master[/url] branch it has the same rev. as my patched branch or take the gist.
  92. +
  93. +Up to date for current rev. 116xx
  94. \ No newline at end of file
  95. diff --git a/sql/custom/mangos_irc.sql b/sql/custom/mangos_irc.sql
  96. new file mode 100644
  97. index 0000000..398d8fe
  98. --- /dev/null
  99. +++ b/sql/custom/mangos_irc.sql
  100. @@ -0,0 +1,55 @@
  101. +SET FOREIGN_KEY_CHECKS=0;
  102. +DROP TABLE IF EXISTS `irc_commands`;
  103. +CREATE TABLE `irc_commands` (
  104. + `Command` varchar(10) NOT NULL default '',
  105. + `Description` varchar(150) NOT NULL default '',
  106. + `gmlevel` tinyint(3) unsigned NOT NULL default '0',
  107. + PRIMARY KEY (`Command`)
  108. +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='IRC Module System';
  109. +
  110. +INSERT INTO `irc_commands` VALUES
  111. +('acct', '[acct <Player> <(un)lock/mail/pass/rename>] : Perform Action To <Player> Account.', '2'),
  112. +('ban', '[ban <Player/IP> <ip/acct/unban/reason>] : Ban/Unban <Player>', '2'),
  113. +('chan', '[chan <op/deop/voice/devoice> <*IRC Nick*>] : Set Mode On Yourself, If <IRC Nick> Is Specified Then Set mode On Nick.', '2'),
  114. +('char', '[char <Player> <mailcheat/taxicheat/maxskill/setskill>] : Perform Action To Character.', '2'),
  115. +('fun', '[fun <Player> <Sound/Say>] : Do Selected Fun Action To <Player>.', '2'),
  116. +('help', '[help Command] : Use No Paramaters For List Of Available Commands.', '0'),
  117. +('inchan', '[inchan <Channel>] : Display Users In Selected In Game <Channel>', '0'),
  118. +('info', '[info] : Display Server Info. (Number Of Players Online/Max Since Last Restart/Uptime)', '0'),
  119. +('item', '[item <Player> <add> <ItemID/[ItemName]> <Amount>] : Additem To <Player>, Use <ItemID> Or <[Exact Item Name]>.', '2'),
  120. +('jail', '[jail <Player> <release/Reason>] : Jail Selected <Player> For <Reason>. Using release As <Reason> Releases Player.', '2'),
  121. +('kick', '[kick <Player> <Reason>] : Kick <Player> For <Reason>.', '2'),
  122. +('kill', '[kill <Player> <Reason>] : Kill <Player> For <Reason>.', '2'),
  123. +('level', '[level <Player> <NewLevel>] : Level <Player> To <NewLevel>. *Can Be Done Offline*', '2'),
  124. +('lookup', '[lookup <acct/char/creature/faction/go/item/quest/skill/spell/tele> <ID/Name>] : ', '2'),
  125. +('login', '[login <UserName> <Password>] : Login To MangChat Admin Mode. (Must Be Done In A PM)', '0'),
  126. +('logout', '[logout] : Logout Of MangChat Admin Mode.', '0'),
  127. +('money', '[money <Player> <(-)Money>] : Give Money To <Player>, Use - To Take Money. *Can Be Done Offline*', '2'),
  128. +('mute', '[mute <Player> <release/TimeInMins> <Reason>] : Mute Player For Reason, For <TimeInMins>. Using release As Time Releases Player. *Can Be Done Offline*', '2'),
  129. +('online', '[online] : Display All Users Logged In Game.', '0'),
  130. +('pm', '[pm <Player> <Message>] : Whisper <Player> In WoW <Message>.', '2'),
  131. +('reload', '[reload] : Reload MangChat Config Options And Security Level From DataBase.', '2'),
  132. +('restart', '[restart] : Restart MangChat, NOT MaNGOS World Server Itself. Forces Reconnection To IRC Server.', '2'),
  133. +('revive', '[revive <Player>] : Revive <Player>.', '2'),
  134. +('saveall', '[saveall] : Forces MaNGOS To Save All Players.', '2'),
  135. +('shutdown', '[shutdown <TimeInSeconds>] : Shuts The Server Down In <TimeInSeconds>, Use 0 For Immediate Shut Down', '2'),
  136. +('spell', '[spell <Player> <Cast/Learn/UnLearn> <SpellID>] : Make <Player> <Learn> Or <UnLearn> A Spell, Or <Cast> A Spell On A <Player>.', '2'),
  137. +('tele', '[tele <Player> <l/c/r/to> <Loc.Name/MAPID X Y Z/Recall/Player>] : Teleport Player To Location, Coords, Or Another Player. (l-Location)(c-Coords)', '2'),
  138. +('ticket', '[ticket <list/read/respond/delete> <limit/name/all> <message>] : Manage GM tickets, respond with message', '2'),
  139. +('top', '[top <accttime/chartime/money> <limit>] : Display top stats for given option. Only GM Higher Than Config Option Can Use Limit.', '2'),
  140. +('who', '[who] : Displays Users Currently Logged In To MangChat.', '1'),
  141. +('sysmsg', '[sysmsg <a/n/e> <Message>] : Broadcasts A System Message. (a-Broadcast System Message)(n-Broadcast Notify Message)(e-Event Message)', 3);
  142. +
  143. +SET FOREIGN_KEY_CHECKS=0;
  144. +DROP TABLE IF EXISTS `irc_inchan`;
  145. +CREATE TABLE `irc_inchan` (
  146. + `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier',
  147. + `name` varchar(12) NOT NULL default '',
  148. + `channel` varchar(15) NOT NULL default '',
  149. + PRIMARY KEY (`guid`,`channel`)
  150. +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='IRC Module System';
  151. +
  152. +SET FOREIGN_KEY_CHECKS=0;
  153. +
  154. +DELETE FROM `command` WHERE `name` = 'ircpm';
  155. +INSERT INTO `command` VALUES ('ircpm', '1', 'Syntax:.ircpm #nick #Message\r\n\r\nSend a message to a person in irc');
  156. diff --git a/src/game/AuctionHouseHandler.cpp b/src/game/AuctionHouseHandler.cpp
  157. index 52124bb..c348c5d 100644
  158. --- a/src/game/AuctionHouseHandler.cpp
  159. +++ b/src/game/AuctionHouseHandler.cpp
  160. @@ -29,6 +29,7 @@
  161. #include "Mail.h"
  162. #include "Util.h"
  163. #include "Chat.h"
  164. +#include "mangchat/IRCClient.h"
  165.  
  166. // please DO NOT use iterator++, because it is slower than ++iterator!!!
  167. // post-incrementation is always slower than pre-incrementation !
  168. @@ -364,6 +365,9 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
  169. DETAIL_LOG("selling %s to auctioneer %s with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u",
  170. itemGuid.GetString().c_str(), auctioneerGuid.GetString().c_str(), bid, buyout, etime, auctionHouseEntry->houseId);
  171.  
  172. + if (sIRC.BOTMASK & 1024)
  173. + sIRC.AHFunc(it->GetEntry(), it->GetProto()->Name1, pl->GetName(), auctionHouseEntry->faction);
  174. +
  175. SendAuctionCommandResult(AH, AUCTION_STARTED, AUCTION_OK);
  176.  
  177. GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
  178. diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt
  179. index 6f9dd0a..b672503 100644
  180. --- a/src/game/CMakeLists.txt
  181. +++ b/src/game/CMakeLists.txt
  182. @@ -74,6 +74,10 @@ source_group("Movement"
  183. movement/util.cpp
  184. )
  185.  
  186. +source_group("MangChat"
  187. + REGULAR_EXPRESSION mangchat/.*
  188. +)
  189. +
  190. if(PCH)
  191. include_directories(${CMAKE_CURRENT_BINARY_DIR})
  192. endif()
  193. @@ -101,6 +105,9 @@ if(NOT ACE_USE_EXTERNAL)
  194. # add_dependencies(game ace)
  195. endif()
  196.  
  197. +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/mangchat/mangchat.conf.dist.in ${CMAKE_CURRENT_BINARY_DIR}/mangchat/mangchat.conf.dist)
  198. +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mangchat/mangchat.conf.dist DESTINATION ${CONF_DIR})
  199. +
  200. # Generate precompiled header
  201. if(PCH)
  202. if(MSVC OR XCODE)
  203. diff --git a/src/game/Channel.cpp b/src/game/Channel.cpp
  204. index 98a7a9c..cfd364c 100644
  205. --- a/src/game/Channel.cpp
  206. +++ b/src/game/Channel.cpp
  207. @@ -20,6 +20,7 @@
  208. #include "ObjectMgr.h"
  209. #include "World.h"
  210. #include "SocialMgr.h"
  211. +#include "mangchat/IRCClient.h"
  212.  
  213. Channel::Channel(const std::string& name, uint32 channel_id)
  214. : m_announce(true), m_moderate(false), m_name(name), m_flags(0), m_channelId(channel_id)
  215. @@ -109,6 +110,8 @@ void Channel::Join(ObjectGuid p, const char *pass)
  216. MakeYouJoined(&data);
  217. SendToOne(&data, p);
  218.  
  219. + sIRC.Handle_WoW_Channel(m_name, sObjectMgr.GetPlayer(p), CHANNEL_JOIN);
  220. +
  221. JoinNotify(p);
  222.  
  223. // if no owner first logged will become
  224. @@ -156,6 +159,8 @@ void Channel::Leave(ObjectGuid p, bool send)
  225.  
  226. LeaveNotify(p);
  227.  
  228. + sIRC.Handle_WoW_Channel(m_name, sObjectMgr.GetPlayer(p), CHANNEL_LEAVE);
  229. +
  230. if(changeowner)
  231. {
  232. ObjectGuid newowner = !m_players.empty() ? m_players.begin()->second.player : ObjectGuid();
  233. diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
  234. index a66f940..930d8b5 100644
  235. --- a/src/game/CharacterHandler.cpp
  236. +++ b/src/game/CharacterHandler.cpp
  237. @@ -38,6 +38,7 @@
  238. #include "Util.h"
  239. #include "ArenaTeam.h"
  240. #include "Language.h"
  241. +#include "mangchat/IRCClient.h"
  242.  
  243. // Playerbot mod:
  244. #include "playerbot/PlayerbotMgr.h"
  245. @@ -872,6 +873,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder *holder)
  246. pCurrChar->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN, 1);
  247.  
  248. delete holder;
  249. +
  250. + if(sIRC.ajoin == 1)
  251. + sIRC.AutoJoinChannel(pCurrChar);
  252. }
  253.  
  254. void WorldSession::HandleSetFactionAtWarOpcode( WorldPacket & recv_data )
  255. diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
  256. index a04f57c..af71481 100644
  257. --- a/src/game/Chat.cpp
  258. +++ b/src/game/Chat.cpp
  259. @@ -832,6 +832,7 @@ ChatCommand * ChatHandler::getCommandTable()
  260. { "bot", SEC_PLAYER, false, &ChatHandler::HandlePlayerbotCommand, "", NULL },
  261. { "quit", SEC_CONSOLE, true, &ChatHandler::HandleQuitCommand, "", NULL },
  262. { "gearscore", SEC_ADMINISTRATOR, false, &ChatHandler::HandleShowGearScoreCommand, "", NULL },
  263. + { "ircpm", SEC_PLAYER, false, &ChatHandler::HandleIRCpmCommand, "", NULL },
  264.  
  265. { NULL, 0, false, NULL, "", NULL }
  266. };
  267. diff --git a/src/game/Chat.h b/src/game/Chat.h
  268. index fca9a51..2952192 100644
  269. --- a/src/game/Chat.h
  270. +++ b/src/game/Chat.h
  271. @@ -615,6 +615,7 @@ class MANGOS_DLL_SPEC ChatHandler
  272. bool HandlePlayerbotCommand(char* args);
  273. bool HandleQuitCommand(char* args);
  274. bool HandleShowGearScoreCommand(char* args);
  275. + bool HandleIRCpmCommand(char* args);
  276.  
  277. //! Development Commands
  278. bool HandleSaveAllCommand(char* args);
  279. diff --git a/src/game/ChatHandler.cpp b/src/game/ChatHandler.cpp
  280. index 8ac0d77..4b06cdf 100644
  281. --- a/src/game/ChatHandler.cpp
  282. +++ b/src/game/ChatHandler.cpp
  283. @@ -36,6 +36,7 @@
  284. #include "Util.h"
  285. #include "GridNotifiersImpl.h"
  286. #include "CellImpl.h"
  287. +#include "mangchat/IRCClient.h"
  288.  
  289. // Playerbot mod
  290. #include "playerbot/PlayerbotAI.h"
  291. @@ -505,6 +506,8 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
  292.  
  293. sChatLog.ChannelMsg(GetPlayer(), channel, msg);
  294.  
  295. + sIRC.Send_WoW_IRC(_player, channel, msg);
  296. +
  297. if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
  298. if(Channel *chn = cMgr->GetChannel(channel, _player))
  299. chn->Say(_player->GetObjectGuid(), msg.c_str(), lang);
  300. diff --git a/src/game/GMTicketHandler.cpp b/src/game/GMTicketHandler.cpp
  301. index 4501701..41bb6b4 100644
  302. --- a/src/game/GMTicketHandler.cpp
  303. +++ b/src/game/GMTicketHandler.cpp
  304. @@ -24,6 +24,7 @@
  305. #include "ObjectAccessor.h"
  306. #include "Player.h"
  307. #include "Chat.h"
  308. +#include "mangchat/IRCClient.h"
  309.  
  310. void WorldSession::SendGMTicketGetTicket(uint32 status, GMTicket *ticket /*= NULL*/)
  311. {
  312. @@ -94,6 +95,12 @@ void WorldSession::HandleGMTicketDeleteTicketOpcode( WorldPacket & /*recv_data*/
  313. SendPacket( &data );
  314.  
  315. SendGMTicketGetTicket(0x0A);
  316. +
  317. + std::string name = GetPlayer()->GetName();
  318. + std::string channel = std::string("#") + sIRC._irc_chan[sIRC.Status];
  319. + sIRC.Send_IRC_Channel(channel, sIRC.MakeMsg("\00304,08\037/!\\\037\017\00304 GM Ticket Deleted For:\00304,08\037/!\\\037\017 %s", "%s", name.c_str()), true);
  320. +
  321. +
  322. }
  323.  
  324. void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data )
  325. @@ -139,6 +146,12 @@ void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data )
  326. if (itr->second->GetSession()->GetSecurity() >= SEC_GAMEMASTER && itr->second->isAcceptTickets())
  327. ChatHandler(itr->second).PSendSysMessage(LANG_COMMAND_TICKETNEW,GetPlayer()->GetName());
  328. }
  329. +
  330. + std::string name = GetPlayer()->GetName();
  331. + std::string details = ticketText;
  332. + std::string channel = std::string("#") + sIRC._irc_chan[sIRC.Status];
  333. + sIRC.Send_IRC_Channel(channel, sIRC.MakeMsg("\00304,08\037/!\\\037\017\00304 New GM Ticket from:\00304,08\037/!\\\037\017 %s", "%s", name.c_str()), true);
  334. + sIRC.Send_IRC_Channel(channel, sIRC.MakeMsg("\00304,08\037/!\\\037\017\00304 Ticket Details:\00304,08\037/!\\\037\017 %s", "%s", details.c_str()), true);
  335. }
  336.  
  337. void WorldSession::HandleGMTicketSystemStatusOpcode( WorldPacket & /*recv_data*/ )
  338. diff --git a/src/game/GameEventMgr.cpp b/src/game/GameEventMgr.cpp
  339. index d82e1b6..dc03c3f 100644
  340. --- a/src/game/GameEventMgr.cpp
  341. +++ b/src/game/GameEventMgr.cpp
  342. @@ -29,6 +29,7 @@
  343. #include "MassMailMgr.h"
  344. #include "SpellMgr.h"
  345. #include "Policies/SingletonImp.h"
  346. +#include "mangchat/IRCClient.h"
  347.  
  348. INSTANTIATE_SINGLETON_1(GameEventMgr);
  349.  
  350. @@ -670,8 +671,14 @@ void GameEventMgr::ApplyNewEvent(uint16 event_id, bool resume)
  351. CharacterDatabase.PExecute("REPLACE INTO game_event_status (event) VALUES (%u)", event_id);
  352.  
  353. if (sWorld.getConfig(CONFIG_BOOL_EVENT_ANNOUNCE))
  354. + {
  355. sWorld.SendWorldText(LANG_EVENTMESSAGE, mGameEvent[event_id].description.c_str());
  356. -
  357. + if(sIRC.BOTMASK & 256)
  358. + {
  359. + std::string ircchan = std::string("#")+sIRC._irc_chan[sIRC.anchn];
  360. + 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);
  361. + }
  362. + }
  363. sLog.outString("GameEvent %u \"%s\" started.", event_id, mGameEvent[event_id].description.c_str());
  364. // spawn positive event tagget objects
  365. GameEventSpawn(event_id);
  366. diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp
  367. index b0f94de..ecb98b0 100644
  368. --- a/src/game/Level1.cpp
  369. +++ b/src/game/Level1.cpp
  370. @@ -33,6 +33,7 @@
  371. #include "MapPersistentStateMgr.h"
  372. #include "Mail.h"
  373. #include "Util.h"
  374. +#include "mangchat/IRCClient.h"
  375. #ifdef _DEBUG_VMAPS
  376. #include "VMapFactory.h"
  377. #endif
  378. @@ -127,6 +128,11 @@ bool ChatHandler::HandleAnnounceCommand(char* args)
  379. return false;
  380.  
  381. sWorld.SendWorldText(LANG_SYSTEMMESSAGE,args);
  382. + if (sIRC.BOTMASK & 256)
  383. + {
  384. + std::string channel = "#" + sIRC._irc_chan[sIRC.anchn];
  385. + sIRC.Send_IRC_Channel(channel, sIRC.MakeMsg("\00304,08\037/!\\\037\017\00304 System Message \00304,08\037/!\\\037\017 %s", "%s", args), true);
  386. + }
  387. return true;
  388. }
  389.  
  390. @@ -143,6 +149,12 @@ bool ChatHandler::HandleNotifyCommand(char* args)
  391. data << str;
  392. sWorld.SendGlobalMessage(&data);
  393.  
  394. + if (sIRC.BOTMASK & 256)
  395. + {
  396. + std::string ircchan = std::string("#") + sIRC._irc_chan[sIRC.anchn];
  397. + sIRC.Send_IRC_Channel(ircchan, sIRC.MakeMsg("\00304,08\037/!\\\037\017\00304 Global Notify \00304,08\037/!\\\037\017 %s", "%s", args), true);
  398. + }
  399. +
  400. return true;
  401. }
  402.  
  403. @@ -2290,3 +2302,28 @@ bool ChatHandler::HandleSetViewCommand(char* /*args*/)
  404.  
  405. return true;
  406. }
  407. +
  408. +bool ChatHandler::HandleIRCpmCommand(char* args)
  409. +{
  410. + if (!*args)
  411. + return false;
  412. +
  413. + std::string Msg = args;
  414. + if (Msg.find(" ") == std::string::npos)
  415. + return false;
  416. +
  417. + std::string To = Msg.substr(0, Msg.find(" "));
  418. + Msg = Msg.substr(Msg.find(" ") + 1);
  419. + std::size_t pos;
  420. +
  421. + while((pos = To.find("||")) != std::string::npos)
  422. + {
  423. + std::size_t find1 = To.find("||", pos);
  424. + To.replace(pos, find1 - pos + 2, "|");
  425. + }
  426. +
  427. + sIRC.SendIRC("PRIVMSG "+To+" : <WoW>["+m_session->GetPlayerName()+"] : " + Msg);
  428. + sIRC.Send_WoW_Player(m_session->GetPlayer(), "|cffCC4ACCTo ["+To+"]: "+Msg);
  429. +
  430. + return true;
  431. +}
  432. diff --git a/src/game/Player.cpp b/src/game/Player.cpp
  433. index 690fd65..1fe61a6 100644
  434. --- a/src/game/Player.cpp
  435. +++ b/src/game/Player.cpp
  436. @@ -62,6 +62,7 @@
  437. #include "Mail.h"
  438. #include "AccountMgr.h"
  439. #include "SpellAuras.h"
  440. +#include "mangchat/IRCClient.h"
  441.  
  442. #include <cmath>
  443.  
  444. @@ -2701,6 +2702,16 @@ void Player::GiveLevel(uint32 level)
  445.  
  446. UpdateAllStats();
  447.  
  448. + if (sIRC.BOTMASK & 64)
  449. + {
  450. + char plevel [3];
  451. + sprintf(plevel, "%u", level);
  452. +
  453. + std::string pname = GetName();
  454. + std::string channel = std::string("#") + sIRC._irc_chan[sIRC.anchn].c_str();
  455. + sIRC.Send_IRC_Channel(channel, "\00311["+pname+"] : Has Reached Level: "+plevel, true);
  456. + }
  457. +
  458. // set current level health and mana/energy to maximum after applying all mods.
  459. if (isAlive())
  460. SetHealth(GetMaxHealth());
  461. diff --git a/src/game/mangchat/IRCClient.cpp b/src/game/mangchat/IRCClient.cpp
  462. new file mode 100644
  463. index 0000000..7d19101
  464. --- /dev/null
  465. +++ b/src/game/mangchat/IRCClient.cpp
  466. @@ -0,0 +1,103 @@
  467. +/*
  468. + * MangChat for MaNGOS, the open source MMORPG-server
  469. + *
  470. + * This Program Is Free Software; You Can Redistribute It And/Or Modify It Under The
  471. + * Terms Of The GNU General Public License
  472. + *
  473. + * Written and Developed by Cybrax <cybraxvd@gmail.com>, |Death| <death@hell360.net>,
  474. + * Lice <lice@yeuxverts.net>, Dj_baby, Sanaell, Tase, Shinzon <shinzon@wowgollum.com>,
  475. + * Xeross, 3raZar3, the orangevirus team <www.orangevir.us>, ...
  476. + *
  477. + * With Help And Support From The MaNGOS Project Community.
  478. + * PLEASE RETAIN THE COPYRIGHT OF THE AUTHORS.
  479. + */
  480. +
  481. +#include "IRCClient.h"
  482. +#include "../World.h"
  483. +#include "../ObjectMgr.h"
  484. +#include "../MapManager.h"
  485. +
  486. +#include "Policies/SingletonImp.h"
  487. +INSTANTIATE_SINGLETON_1( IRCClient );
  488. +
  489. +#ifdef WIN32
  490. + #define Delay(x) Sleep(x)
  491. +#else
  492. + #define Delay(x) sleep(x / 1000)
  493. +#endif
  494. +
  495. +// IRCClient Constructor
  496. +IRCClient::IRCClient()
  497. +{
  498. + for(int i = 0;i > 5;i++)
  499. + sIRC.Script_Lock[i] = false;
  500. +}
  501. +
  502. +// IRCClient Destructor
  503. +IRCClient::~IRCClient(){}
  504. +
  505. +// ZThread Entry This function is called when the thread is created in Master.cpp (mangosd)
  506. +void IRCClient::run()
  507. +{
  508. + sIRC.iLog.WriteLog(" %s : ****** MaNGOS With MangChat Has Been Started ******", sIRC.iLog.GetLogDateTimeStr().c_str());
  509. +
  510. + // Before we begin we wait a while MaNGOS is still starting up.
  511. + ACE_Based::Thread::Sleep(500);
  512. + sLog.outString("\n%s\n%s\n%s\n%s",
  513. + "***************************************",
  514. + "** MangChat Threaded IRC Client **",
  515. + "** for inferna & orangevirus **",
  516. + "***************************************");
  517. + sLog.outString("MangChat: %s", sIRC._Mver.c_str());
  518. + int cCount = 0;
  519. +
  520. + if (!sIRC.Active)
  521. + sLog.outString("MangChat: IRC BOT disabled (irc.active = 0)");
  522. +
  523. + // Clean Up MySQL Tables
  524. + sLog.outString("MangChat: Cleaning Up Inchan Table");
  525. + WorldDatabase.PExecute("DELETE FROM `irc_inchan`");
  526. + sIRC._Max_Script_Inst = 0;
  527. +
  528. + // Create a loop to keep the thread running untill active is set to false
  529. + while(sIRC.Active && !World::IsStopped())
  530. + {
  531. + // Initialize socket library
  532. + if (InitSock())
  533. + {
  534. + // Connect To The IRC Server
  535. + sLog.outString("MangChat: Connecting to %s Try # %d", sIRC._Host.c_str(), cCount);
  536. + if(this->Connect(sIRC._Host.c_str(), sIRC._Port))
  537. + {
  538. + // On connection success reset the connection counter
  539. + cCount = 0;
  540. + sLog.outString("MangChat: Connected And Logging In");
  541. + // Login to the IRC server
  542. + if(this->Login(sIRC._Nick, sIRC._User, sIRC._Pass))
  543. + {
  544. + sLog.outString("MangChat: Logged In And Running!!");
  545. + // While we are connected to the irc server keep listening for data on the socket
  546. + while(sIRC.Connected && !World::IsStopped()){ sIRC.SockRecv(); }
  547. + }
  548. + sLog.outString("MangChat: Connection To IRC Server Lost!");
  549. + }
  550. + // When an error occures or connection lost cleanup
  551. + Disconnect();
  552. + // Increase the connection counter
  553. + cCount++;
  554. + // if MAX_CONNECT_ATTEMPT is reached stop trying
  555. + if(sIRC._MCA && cCount == sIRC._MCA)
  556. + sIRC.Active = false;
  557. + // If we need to reattempt a connection wait WAIT_CONNECT_TIME milli seconds before we try again
  558. + if(sIRC.Active)
  559. + ACE_Based::Thread::Sleep(sIRC._wct);
  560. + }
  561. + else
  562. + {
  563. + // Socket could not initialize cancel
  564. + sIRC.Active = false;
  565. + sLog.outError("MangChat: Could not initialize socket");
  566. + }
  567. + }
  568. + // thread stays alive for calls from other threads
  569. +}
  570. diff --git a/src/game/mangchat/IRCClient.h b/src/game/mangchat/IRCClient.h
  571. new file mode 100644
  572. index 0000000..3ca011b
  573. --- /dev/null
  574. +++ b/src/game/mangchat/IRCClient.h
  575. @@ -0,0 +1,233 @@
  576. +/*
  577. + * MangChat for MaNGOS, the open source MMORPG-server
  578. + *
  579. + * This Program Is Free Software; You Can Redistribute It And/Or Modify It Under The
  580. + * Terms Of The GNU General Public License
  581. + *
  582. + * Written and Developed by Cybrax <cybraxvd@gmail.com>, |Death| <death@hell360.net>,
  583. + * Lice <lice@yeuxverts.net>, Dj_baby, Sanaell, Tase, Shinzon <shinzon@wowgollum.com>,
  584. + * Xeross, 3raZar3, the orangevirus team <www.orangevir.us>, ...
  585. + *
  586. + * With Help And Support From The MaNGOS Project Community.
  587. + * PLEASE RETAIN THE COPYRIGHT OF THE AUTHORS.
  588. + */
  589. +
  590. +#ifndef _IRC_CLIENT_H
  591. +#define _IRC_CLIENT_H
  592. +
  593. +#include "Policies/Singleton.h"
  594. +#include "../Player.h"
  595. +#include "IRCLog.h"
  596. +#include "IRCCmd.h"
  597. +
  598. +using namespace std;
  599. +// The maximum ammount of channels used, must be >= config option
  600. +#define MAX_CONF_CHANNELS 10
  601. +#define MAX_CHAT_LINES 10
  602. +
  603. +// let scripts know we have mangchat
  604. +#define MANGCHAT_INSTALLED
  605. +
  606. +// CLINES is used for the default chatlines
  607. +// By using the GetChatLine function its easier and faster
  608. +// to receieve the line you need.
  609. +enum CLINES
  610. +{
  611. + IRC_WOW = 0,
  612. + WOW_IRC = 1,
  613. + JOIN_WOW = 2,
  614. + JOIN_IRC = 3,
  615. + LEAVE_WOW = 4,
  616. + LEAVE_IRC = 5,
  617. + CHANGE_NICK = 6
  618. +};
  619. +
  620. +// CACTION is used by the Handle_WoW_Channel function
  621. +// this function is called in channel.h when a player
  622. +// joins or leave a channel inside the client.
  623. +enum CACTION
  624. +{
  625. + CHANNEL_JOIN,
  626. + CHANNEL_LEAVE,
  627. +};
  628. +
  629. +enum script_Names
  630. +{
  631. + MCS_Players_Online = 0,
  632. +};
  633. +
  634. +// IRCClient main class
  635. +class IRCClient : public ACE_Based::Runnable
  636. +{
  637. + public:
  638. + IRCClient();
  639. + ~IRCClient();
  640. + // ZThread Entry
  641. + void run();
  642. +
  643. + // AH Function
  644. + void AHFunc(uint64 itmid, std::string itmnme, std::string plname, uint32 faction);
  645. +
  646. + //NOTE: Removed "BeenToGMI" due to back overflows caused with new packet structure (Shinzon)
  647. + //bool BeenToGMI(float posx, float posy, std::string player, std::string from);
  648. +
  649. + // IRCClient active
  650. + bool Active;
  651. + // Connected to IRC
  652. + bool Connected;
  653. + // Send data to IRC, in addition the endline is added \n
  654. + bool SendIRC(std::string data);
  655. + // This function is called in ChatHandler.cpp and processes the chat from game to IRC
  656. + void Send_WoW_IRC(Player *plr, std::string Channel, std::string Msg);
  657. + // Sends a message to all players on the specified channel
  658. + void Send_WoW_Channel(const char *channel, std::string chat);
  659. + // Send a system message to all players
  660. + void Send_WoW_System(std::string Message);
  661. + // Send a message to the specified IRC channel
  662. + void Send_IRC_Channel(std::string sChannel, std::string sMsg, bool NoPrefix = false, std::string nType = "PRIVMSG");
  663. + // Sends a message to all IRC Channels
  664. + void Send_IRC_Channels(std::string sMsg);
  665. + std::string MakeMsg(std::string msg, std::string var, std::string val)
  666. + {
  667. + std::size_t start = msg.find(var);
  668. + if (start != std::string::npos)
  669. + msg.replace(start, var.length(), val);
  670. + return msg;
  671. + }
  672. + void Send_WoW_Player(string sPlayer, string sMsg);
  673. + void Send_WoW_Player(Player *plr, string sMsg);
  674. +
  675. + // This function is called in Channel.cpp and processes Join/leave messages
  676. + void Handle_WoW_Channel(std::string Channel, Player *plr, int nAction);
  677. + void ResetIRC();
  678. +
  679. + void AutoJoinChannel(Player *plr);
  680. +
  681. + bool Script_Lock[5];
  682. + bool _AmiOp;
  683. +
  684. + string _Mver;
  685. +
  686. + // BotMask Options
  687. + int Botmask;
  688. + // Status Channel
  689. + int Status;
  690. + // Announce Channel
  691. + int anchn;
  692. + int autoanc;
  693. + // IRC Channel count
  694. + int _chan_count;
  695. + // IRC Channel list
  696. + // Array to store our IRC channels
  697. + // each element will corrospond
  698. + // with _wow_chan array below.
  699. + std::string _irc_chan[MAX_CONF_CHANNELS];
  700. + // Game Channel list
  701. + std::string _wow_chan[MAX_CONF_CHANNELS];
  702. + // AutoJoin Options
  703. + int ajoin;
  704. + string ajchan;
  705. + // Online Command Max Results
  706. + int onlrslt;
  707. + // Channel OnJoin/Restart/Kick Messages
  708. + string JoinMsg;
  709. + string RstMsg;
  710. + string kikmsg;
  711. + // Misc Options
  712. + string ojGM[SEC_CONSOLE];
  713. + string logfile;
  714. + int games;
  715. + int gmlog;
  716. + // IRC Commands Security Level
  717. + int CACCT;
  718. + int CBAN;
  719. + int CCHAN;
  720. + int CCHAR;
  721. + int CFUN;
  722. + int CHELP;
  723. + int CINCHAN;
  724. + int CINFO;
  725. + int CITEM;
  726. + int CJAIL;
  727. + int CKICK;
  728. + int _KILL;
  729. + int CLEVEL;
  730. + int CLOOKUP;
  731. + int CMONEY;
  732. + int CMUTE;
  733. + int CONLINE;
  734. + int CPM;
  735. + int CRESTART;
  736. + int CREVIVE;
  737. + int CSAVEALL;
  738. + int CSHUTDOWN;
  739. + int CSPELL;
  740. + int CSYSMSG;
  741. + int CTELE;
  742. + int CTOP;
  743. + int CWHO;
  744. + // BotMask
  745. + int BOTMASK;
  746. + // Max connect attempt
  747. + int _MCA;
  748. + // Auto rejoin when kicked from irc
  749. + int _autojoinkick;
  750. + // IRC Command prefix
  751. + string _cmd_prefx;
  752. + int _op_gm;
  753. + int _op_gm_lev;
  754. +
  755. + string GetChatLine(int nItem);
  756. +
  757. + int _Max_Script_Inst;
  758. + // MAX_SCRIPT_INST
  759. +
  760. + IRCLog iLog;
  761. +
  762. + // Load MangChat configuration file
  763. + bool LoadConfig();
  764. + void SetCfgFile(char const* cfgfile);
  765. +
  766. + std::string* GetNick() {return &_Nick; }
  767. +
  768. + private:
  769. + // Socket indentifier
  770. + int SOCKET;
  771. + fd_set sfdset;
  772. +
  773. + // Initialize socket library
  774. + bool InitSock();
  775. + // Connect to IRC Server
  776. + bool Connect(const char *cHost, int nPort);
  777. + // Login to IRC Server
  778. + bool Login(std::string sNick, std::string sUser, std::string sPass);
  779. + // Send raw data to IRC
  780. + bool SendData(const char *data);
  781. + // Disconnect from IRC and cleanup socket
  782. + void Disconnect();
  783. + // Processes the data receieved from IRC
  784. + void Handle_IRC(std::string sData);
  785. + // Receieves data from the socket.
  786. + void SockRecv();
  787. + // the mangchat configuration file
  788. + char const* CfgFile;
  789. + // Array that contains our chatlines from the conf file
  790. + string ILINES[MAX_CHAT_LINES];
  791. +
  792. +
  793. + string _Host; // IRC Server host
  794. + int _Port; // IRC Server Port
  795. + string _User; // IRC Username
  796. + string _Pass; // IRC Password
  797. + string _Nick; // IRC Nickname
  798. +
  799. + int _Auth; // Authentication type
  800. + string _Auth_Nick;
  801. + string _ICC; // IRC Connect code
  802. +
  803. + string _defchan; // IRC Default channel
  804. + int _ldefc; // IRC Leave Default channel
  805. + int _wct; // Wait Connect Time
  806. +};
  807. +#endif
  808. +#define sIRC MaNGOS::Singleton<IRCClient>::Instance()
  809. diff --git a/src/game/mangchat/IRCCmd.cpp b/src/game/mangchat/IRCCmd.cpp
  810. new file mode 100644
  811. index 0000000..45cf074
  812. --- /dev/null
  813. +++ b/src/game/mangchat/IRCCmd.cpp
  814. @@ -0,0 +1,941 @@
  815. +/*
  816. + * MangChat for MaNGOS, the open source MMORPG-server
  817. + *
  818. + * This Program Is Free Software; You Can Redistribute It And/Or Modify It Under The
  819. + * Terms Of The GNU General Public License
  820. + *
  821. + * Written and Developed by Cybrax <cybraxvd@gmail.com>, |Death| <death@hell360.net>,
  822. + * Lice <lice@yeuxverts.net>, Dj_baby, Sanaell, Tase, Shinzon <shinzon@wowgollum.com>,
  823. + * Xeross, 3raZar3, the orangevirus team <www.orangevir.us>, ...
  824. + *
  825. + * With Help And Support From The MaNGOS Project Community.
  826. + * PLEASE RETAIN THE COPYRIGHT OF THE AUTHORS.
  827. + */
  828. +
  829. +#include "IRCCmd.h"
  830. +#include "IRCClient.h"
  831. +#include "Database/DatabaseEnv.h"
  832. +#include "../ObjectMgr.h"
  833. +#include "../AccountMgr.h"
  834. +#include "../MapManager.h"
  835. +// Constructor
  836. +IRCCmd::IRCCmd(){}
  837. +// Destructor
  838. +IRCCmd::~IRCCmd(){}
  839. +
  840. +std::string IRCCmd::MakeUpper(std::string Channel)
  841. +{
  842. + std::string tmpchan = Channel;
  843. + std::transform(tmpchan.begin(), tmpchan.end(), tmpchan.begin(), towupper);
  844. +
  845. + return tmpchan;
  846. +}
  847. +
  848. +bool IRCCmd::ParamsValid(_CDATA *CD, int pCnt)
  849. +{
  850. + CD->PCOUNT = pCnt;
  851. +
  852. + if(CD->PARAMS.size() == 0)
  853. + return false;
  854. +
  855. + return ValidParams(CD->PARAMS, pCnt);
  856. +}
  857. +
  858. +int IRCCmd::ParamsValid(_CDATA *CD, int pCnt, int rLev)
  859. +{
  860. + //CD->PCOUNT = pCnt;
  861. + if(!CanUse(CD->USER, rLev))
  862. + return E_AUTH;
  863. + else if(pCnt == 0)
  864. + return E_OK;
  865. + else if(CD->PARAMS.size() == 0)
  866. + return E_SIZE;
  867. + else if(!ValidParams(CD->PARAMS, pCnt))
  868. + return E_SIZE;
  869. +
  870. + return E_OK;
  871. +}
  872. +
  873. +// This function checks if chat from irc is a command or not
  874. +// return true on yes and false on no
  875. +bool IRCCmd::IsValid(std::string USER, std::string FROM, std::string CHAT, std::string TYPE)
  876. +{
  877. + // If the first line of our chat is the command prefix we have a command
  878. + if(CHAT.substr(0, 1) == sIRC._cmd_prefx && CHAT.size() > 1 )
  879. + {
  880. + _CDATA CDATA;
  881. + bool cValid = false;
  882. + bool AuthValid = true;
  883. + bool dontlog = true;
  884. + std::string* _PARAMS = getArray(CHAT, 2);
  885. + CDATA.USER = USER;
  886. + CDATA.FROM = FROM;
  887. + CDATA.TYPE = TYPE;
  888. + CDATA.PCOUNT = 0;
  889. + CDATA.CMD = MakeUpper(_PARAMS[0].substr(1, _PARAMS[0].size() - 1));
  890. + CDATA.PARAMS = _PARAMS[1];
  891. + if(CDATA.CMD == "LOGIN")
  892. + {
  893. + if (FROM == *(sIRC.GetNick()))
  894. + {
  895. + if(ParamsValid(&CDATA, 2))
  896. + Handle_Login(&CDATA);
  897. + else
  898. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "login <Player> <Password> )", true, "ERROR");
  899. + }
  900. + else
  901. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Please Send A PM To Login!", true, "ERROR");
  902. +
  903. + if(GetLevel(USER) >= sIRC.gmlog)
  904. + dontlog = false;
  905. +
  906. + cValid = true;
  907. + }
  908. + else if(CDATA.CMD == "LOGOUT")
  909. + {
  910. + if (FROM == *(sIRC.GetNick()))
  911. + Handle_Logout(&CDATA);
  912. + else
  913. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Please Send A PM To Logout!", true, "ERROR");
  914. +
  915. + cValid = true;
  916. + }
  917. + else if(CDATA.CMD == "ACCT")
  918. + {
  919. + switch(ParamsValid(&CDATA, 2, sIRC.CACCT))
  920. + {
  921. + case E_OK:
  922. + Account_Player(&CDATA);
  923. + break;
  924. + case E_SIZE:
  925. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "acct <Player> <(un)lock/mail/pass/rename> )", true, "ERROR");
  926. + break;
  927. + case E_AUTH:
  928. + AuthValid = false;
  929. + break;
  930. + }
  931. + cValid = true;
  932. + }
  933. + else if(CDATA.CMD == "BAN")
  934. + {
  935. + switch(ParamsValid(&CDATA, 2, sIRC.CBAN))
  936. + {
  937. + case E_OK:
  938. + Ban_Player(&CDATA);
  939. + break;
  940. + case E_SIZE:
  941. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "ban <Player> <acct/ip> )", true, "ERROR");
  942. + break;
  943. + case E_AUTH:
  944. + AuthValid = false;
  945. + break;
  946. + }
  947. + cValid = true;
  948. + }
  949. + else if(CDATA.CMD == "CHAN")
  950. + {
  951. + switch(ParamsValid(&CDATA, 1, sIRC.CCHAN))
  952. + {
  953. + case E_OK:
  954. + Chan_Control(&CDATA);
  955. + break;
  956. + case E_SIZE:
  957. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "chan <op> <IRC User> )", true, "ERROR");
  958. + break;
  959. + case E_AUTH:
  960. + AuthValid = false;
  961. + break;
  962. + }
  963. + cValid = true;
  964. + }
  965. + else if(CDATA.CMD == "CHAR")
  966. + {
  967. + switch(ParamsValid(&CDATA, 2, sIRC.CCHAR))
  968. + {
  969. + case E_OK:
  970. + Char_Player(&CDATA);
  971. + break;
  972. + case E_SIZE:
  973. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "char <Player> <mailcheat/taxicheat/maxskill/setskill> )", true, "ERROR");
  974. + break;
  975. + case E_AUTH:
  976. + AuthValid = false;
  977. + break;
  978. + }
  979. + cValid = true;
  980. + }
  981. + else if(CDATA.CMD == "FUN")
  982. + {
  983. + switch(ParamsValid(&CDATA, 2, sIRC.CFUN))
  984. + {
  985. + case E_OK:
  986. + Fun_Player(&CDATA);
  987. + break;
  988. + case E_SIZE:
  989. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( "+sIRC._cmd_prefx+"fun <Player> <Sound/Say> )", true, "ERROR");
  990. + break;
  991. + case E_AUTH:
  992. + AuthValid = false;
  993. + break;
  994. + }
  995. + cValid = true;
  996. + }
  997. + else if(CDATA.CMD == "HELP")
  998. + {
  999. + switch(ParamsValid(&CDATA, 0, sIRC.CHELP))
  1000. + {
  1001. + case E_OK:
  1002. + Help_IRC(&CDATA);
  1003. + break;
  1004. + case E_SIZE:
  1005. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( "+sIRC._cmd_prefx+"help <Command> )", true, "ERROR");
  1006. + break;
  1007. + case E_AUTH:
  1008. + AuthValid = false;
  1009. + break;
  1010. + }
  1011. + cValid = true;
  1012. + }
  1013. + else if(CDATA.CMD == "INCHAN")
  1014. + {
  1015. + switch(ParamsValid(&CDATA, 1, sIRC.CINCHAN))
  1016. + {
  1017. + case E_OK:
  1018. + Inchan_Server(&CDATA);
  1019. + break;
  1020. + case E_SIZE:
  1021. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "inchan <Channel> )", true, "ERROR");
  1022. + break;
  1023. + case E_AUTH:
  1024. + AuthValid = false;
  1025. + break;
  1026. + }
  1027. + cValid = true;
  1028. + }
  1029. + else if(CDATA.CMD == "INFO")
  1030. + {
  1031. + switch(ParamsValid(&CDATA, 0, sIRC.CINFO))
  1032. + {
  1033. + case E_OK:
  1034. + Info_Server(&CDATA);
  1035. + break;
  1036. + case E_SIZE:
  1037. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "info )", true, "ERROR");
  1038. + break;
  1039. + case E_AUTH:
  1040. + AuthValid = false;
  1041. + break;
  1042. + }
  1043. + cValid = true;
  1044. + }
  1045. + else if(CDATA.CMD == "ITEM")
  1046. + {
  1047. + CDATA.PCOUNT = 3;
  1048. + switch(ParamsValid(&CDATA, 2, sIRC.CITEM))
  1049. + {
  1050. + case E_OK:
  1051. + Item_Player(&CDATA);
  1052. + break;
  1053. + case E_SIZE:
  1054. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "item <Player> <add> <ItemID/[ItemName]> <Amount> )", true, "ERROR");
  1055. + break;
  1056. + case E_AUTH:
  1057. + AuthValid = false;
  1058. + break;
  1059. + }
  1060. + cValid = true;
  1061. + }
  1062. + else if(CDATA.CMD == "JAIL")
  1063. + {
  1064. + CDATA.PCOUNT = 3;
  1065. + switch(ParamsValid(&CDATA, 1, sIRC.CJAIL))
  1066. + {
  1067. + case E_OK:
  1068. + Jail_Player(&CDATA);
  1069. + break;
  1070. + case E_SIZE:
  1071. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "jail <Player> <release/Reason>)", true, "ERROR");
  1072. + break;
  1073. + case E_AUTH:
  1074. + AuthValid = false;
  1075. + break;
  1076. + }
  1077. + cValid = true;
  1078. + }
  1079. + else if(CDATA.CMD == "KICK")
  1080. + {
  1081. + CDATA.PCOUNT = 2;
  1082. + switch(ParamsValid(&CDATA, 1, sIRC.CKICK))
  1083. + {
  1084. + case E_OK:
  1085. + Kick_Player(&CDATA);
  1086. + break;
  1087. + case E_SIZE:
  1088. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "kick <Player> <Reason> )", true, "ERROR");
  1089. + break;
  1090. + case E_AUTH:
  1091. + AuthValid = false;
  1092. + break;
  1093. + }
  1094. + cValid = true;
  1095. + }
  1096. + else if(CDATA.CMD == "KILL")
  1097. + {
  1098. + CDATA.PCOUNT = 2;
  1099. + switch(ParamsValid(&CDATA, 1, sIRC._KILL))
  1100. + {
  1101. + case E_OK:
  1102. + Kill_Player(&CDATA);
  1103. + break;
  1104. + case E_SIZE:
  1105. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "kill <Player> <Reason> )", true, "ERROR");
  1106. + break;
  1107. + case E_AUTH:
  1108. + AuthValid = false;
  1109. + break;
  1110. + }
  1111. + cValid = true;
  1112. + }
  1113. + else if(CDATA.CMD == "LEVEL")
  1114. + {
  1115. + CDATA.PCOUNT = 2;
  1116. + switch(ParamsValid(&CDATA, 2, sIRC.CLEVEL))
  1117. + {
  1118. + case E_OK:
  1119. + Level_Player(&CDATA);
  1120. + break;
  1121. + case E_SIZE:
  1122. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "level <Player> <NewLevel> )", true, "ERROR");
  1123. + break;
  1124. + case E_AUTH:
  1125. + AuthValid = false;
  1126. + break;
  1127. + }
  1128. + cValid = true;
  1129. + }
  1130. + else if(CDATA.CMD == "LOOKUP")
  1131. + {
  1132. + CDATA.PCOUNT = 2;
  1133. + switch(ParamsValid(&CDATA, 2, sIRC.CLOOKUP))
  1134. + {
  1135. + case E_OK:
  1136. + Lookup_Player(&CDATA);
  1137. + break;
  1138. + case E_SIZE:
  1139. + 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");
  1140. + break;
  1141. + case E_AUTH:
  1142. + AuthValid = false;
  1143. + break;
  1144. + }
  1145. + cValid = true;
  1146. + }
  1147. + else if(CDATA.CMD == "MONEY")
  1148. + {
  1149. + CDATA.PCOUNT = 2;
  1150. + switch(ParamsValid(&CDATA, 2, sIRC.CMONEY))
  1151. + {
  1152. + case E_OK:
  1153. + Money_Player(&CDATA);
  1154. + break;
  1155. + case E_SIZE:
  1156. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "money <Player> <(-)Money> )", true, "ERROR");
  1157. + break;
  1158. + case E_AUTH:
  1159. + AuthValid = false;
  1160. + break;
  1161. + }
  1162. + cValid = true;
  1163. + }
  1164. + else if(CDATA.CMD == "MUTE")
  1165. + {
  1166. + switch(ParamsValid(&CDATA, 2, sIRC.CMUTE))
  1167. + {
  1168. + case E_OK:
  1169. + Mute_Player(&CDATA);
  1170. + break;
  1171. + case E_SIZE:
  1172. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "mute <Player> <release/TimeInMins> <Reason> )", true, "ERROR");
  1173. + break;
  1174. + case E_AUTH:
  1175. + AuthValid = false;
  1176. + break;
  1177. + }
  1178. + cValid = true;
  1179. + }
  1180. + else if(CDATA.CMD == "ONLINE")
  1181. + {
  1182. + switch(ParamsValid(&CDATA, 0, sIRC.CONLINE))
  1183. + {
  1184. + case E_OK:
  1185. + Online_Players(&CDATA);
  1186. + break;
  1187. + case E_SIZE:
  1188. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "online )", true, "ERROR");
  1189. + break;
  1190. + case E_AUTH:
  1191. + AuthValid = false;
  1192. + break;
  1193. + }
  1194. + cValid = true;
  1195. + }
  1196. + else if(CDATA.CMD == "PM")
  1197. + {
  1198. + switch(ParamsValid(&CDATA, 2, sIRC.CPM))
  1199. + {
  1200. + case E_OK:
  1201. + PM_Player(&CDATA);
  1202. + break;
  1203. + case E_SIZE:
  1204. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "pm <Player> <Message> )", true, "ERROR");
  1205. + break;
  1206. + case E_AUTH:
  1207. + AuthValid = false;
  1208. + break;
  1209. + }
  1210. + cValid = true;
  1211. + }
  1212. + else if(CDATA.CMD == "RELOAD")
  1213. + {
  1214. + switch(ParamsValid(&CDATA, 0, sIRC.CRESTART))
  1215. + {
  1216. + case E_OK:
  1217. + sIRC.Send_IRC_Channels("Reloading MangChat Config Options. (Restart recommended)");
  1218. + sIRC.LoadConfig();
  1219. + break;
  1220. + case E_AUTH:
  1221. + AuthValid = false;
  1222. + break;
  1223. + }
  1224. + cValid = true;
  1225. + }
  1226. + else if(CDATA.CMD == "RESTART")
  1227. + {
  1228. + switch(ParamsValid(&CDATA, 0, sIRC.CRESTART))
  1229. + {
  1230. + case E_OK:
  1231. + sIRC.Send_IRC_Channels(sIRC.RstMsg);
  1232. + sIRC.ResetIRC();
  1233. + break;
  1234. + case E_AUTH:
  1235. + AuthValid = false;
  1236. + break;
  1237. + }
  1238. + cValid = true;
  1239. + }
  1240. + else if(CDATA.CMD == "REVIVE")
  1241. + {
  1242. + CDATA.PCOUNT = 2;
  1243. + switch(ParamsValid(&CDATA, 1, sIRC.CREVIVE))
  1244. + {
  1245. + case E_OK:
  1246. + Revive_Player(&CDATA);
  1247. + break;
  1248. + case E_SIZE:
  1249. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "revive <Player> )", true, "ERROR");
  1250. + break;
  1251. + case E_AUTH:
  1252. + AuthValid = false;
  1253. + break;
  1254. + }
  1255. + cValid = true;
  1256. + }
  1257. + else if(CDATA.CMD == "SAVEALL")
  1258. + {
  1259. + switch(ParamsValid(&CDATA, 0, sIRC.CSAVEALL))
  1260. + {
  1261. + case E_OK:
  1262. + Saveall_Player(&CDATA);
  1263. + break;
  1264. + case E_AUTH:
  1265. + AuthValid = false;
  1266. + break;
  1267. + }
  1268. + cValid = true;
  1269. + }
  1270. + else if(CDATA.CMD == "SHUTDOWN")
  1271. + {
  1272. + switch(ParamsValid(&CDATA, 1, sIRC.CSHUTDOWN))
  1273. + {
  1274. + case E_OK:
  1275. + Shutdown_Mangos(&CDATA);
  1276. + break;
  1277. + case E_SIZE:
  1278. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "shutdown <TimeInSeconds/cancel> )", true, "ERROR");
  1279. + break;
  1280. + case E_AUTH:
  1281. + AuthValid = false;
  1282. + break;
  1283. + }
  1284. + cValid = true;
  1285. + }
  1286. + else if(CDATA.CMD == "SPELL")
  1287. + {
  1288. + switch(ParamsValid(&CDATA, 2, sIRC.CSPELL))
  1289. + {
  1290. + case E_OK:
  1291. + Spell_Player(&CDATA);
  1292. + break;
  1293. + case E_SIZE:
  1294. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "spell <Player> <Cast/Learn/UnLearn> <SpellID> )", true, "ERROR");
  1295. + break;
  1296. + case E_AUTH:
  1297. + AuthValid = false;
  1298. + break;
  1299. + }
  1300. + cValid = true;
  1301. + }
  1302. + else if(CDATA.CMD == "SYSMSG")
  1303. + {
  1304. + CDATA.PCOUNT = 2;
  1305. + switch(ParamsValid(&CDATA, 2, sIRC.CSYSMSG))
  1306. + {
  1307. + case E_OK:
  1308. + Sysmsg_Server(&CDATA);
  1309. + break;
  1310. + case E_SIZE:
  1311. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "sysmsg <a/e/n/add/del/list> <Message> )", true, "ERROR");
  1312. + break;
  1313. + case E_AUTH:
  1314. + AuthValid = false;
  1315. + break;
  1316. + }
  1317. + cValid = true;
  1318. + }
  1319. + else if(CDATA.CMD == "TELE")
  1320. + {
  1321. + switch(ParamsValid(&CDATA, 2, sIRC.CTELE))
  1322. + {
  1323. + case E_OK:
  1324. + Tele_Player(&CDATA);
  1325. + break;
  1326. + case E_SIZE:
  1327. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "tele <Player> <l/c/r/to> <Loc.Name/MAPID X Y Z/Recall/Player> )", true, "ERROR");
  1328. + break;
  1329. + case E_AUTH:
  1330. + AuthValid = false;
  1331. + break;
  1332. + }
  1333. + cValid = true;
  1334. + }
  1335. + else if(CDATA.CMD == "TOP")
  1336. + {
  1337. + CDATA.PCOUNT = 1;
  1338. + switch(ParamsValid(&CDATA, 1, sIRC.CTOP))
  1339. + {
  1340. + case E_OK:
  1341. + Top_Player(&CDATA);
  1342. + break;
  1343. + case E_SIZE:
  1344. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "top <accttime/chartime/money> <limit> )", true, "ERROR");
  1345. + break;
  1346. + case E_AUTH:
  1347. + AuthValid = false;
  1348. + break;
  1349. + }
  1350. + cValid = true;
  1351. + }
  1352. + else if(CDATA.CMD == "WHO")
  1353. + {
  1354. + switch(ParamsValid(&CDATA, 0, sIRC.CWHO))
  1355. + {
  1356. + case E_OK:
  1357. + Who_Logged(&CDATA);
  1358. + break;
  1359. + case E_AUTH:
  1360. + AuthValid = false;
  1361. + break;
  1362. + }
  1363. + cValid = true;
  1364. + }
  1365. + else if(CDATA.CMD == "TICKET") // GM Ticket by bizkut http://github.com/bizkut
  1366. + {
  1367. + CDATA.PCOUNT = 1;
  1368. + switch(ParamsValid(&CDATA, 1, sIRC.CTOP))
  1369. + {
  1370. + case E_OK:
  1371. + GM_Ticket(&CDATA);
  1372. + break;
  1373. + case E_SIZE:
  1374. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Syntax Error! ( " + sIRC._cmd_prefx + "ticket <list/read/respond/delete> <limit/name/all> <message> )", true, "ERROR");
  1375. + break;
  1376. + case E_AUTH:
  1377. + AuthValid = false;
  1378. + break;
  1379. + }
  1380. + cValid = true;
  1381. + }
  1382. +
  1383. + if(!AuthValid && IsLoggedIn(USER))
  1384. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Access Denied! Your Security Level Is Too Low To Use This Command!", true, "ERROR");
  1385. +
  1386. + if (cValid == false && (sIRC.BOTMASK & 4))
  1387. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : Unknown Command!", true, "ERROR");
  1388. +
  1389. + if (cValid && dontlog)
  1390. + 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());
  1391. +
  1392. + return cValid;
  1393. + }
  1394. + return false;
  1395. +}
  1396. +
  1397. +bool IRCCmd::CanUse(std::string USER, int nLevel)
  1398. +{
  1399. + if(IsLoggedIn(USER))
  1400. + {
  1401. + if(GetLevel(USER) >= nLevel)
  1402. + return true;
  1403. + else
  1404. + return false;
  1405. + }
  1406. + else if(nLevel == 0)
  1407. + {
  1408. + return true;
  1409. + }
  1410. + else
  1411. + sIRC.Send_IRC_Channel(USER, "\0034[ERROR] : You Are Not Logged In!", true, "ERROR");
  1412. +
  1413. + return false;
  1414. +}
  1415. +
  1416. +std::string IRCCmd::ChanOrPM(_CDATA *CD)
  1417. +{
  1418. + if (CD->FROM == *(sIRC.GetNick()))
  1419. + return CD->USER;
  1420. + else
  1421. + return CD->FROM;
  1422. +}
  1423. +
  1424. +Player *IRCCmd::GetPlayer(std::string WHO)
  1425. +{
  1426. + normalizePlayerName(WHO);
  1427. +
  1428. + return ObjectAccessor::Instance().FindPlayerByName(WHO.c_str());
  1429. +}
  1430. +
  1431. +_client *IRCCmd::GetClient(std::string cname)
  1432. +{
  1433. + for(std::list<_client*>::iterator i = _CLIENTS.begin(); i != _CLIENTS.end(); i++)
  1434. + {
  1435. + if((*i)->Name == cname)
  1436. + return (*i);
  1437. + }
  1438. +
  1439. + return (NULL);
  1440. +}
  1441. +
  1442. +bool IRCCmd::IsLoggedIn(std::string USER)
  1443. +{
  1444. + for(std::list<_client*>::iterator i = _CLIENTS.begin(); i != _CLIENTS.end(); i++)
  1445. + {
  1446. + if((*i)->Name == USER)
  1447. + return true;
  1448. + }
  1449. +
  1450. + return false;
  1451. +}
  1452. +
  1453. +bool IRCCmd::AcctIsLoggedIn(std::string USER)
  1454. +{
  1455. + for(std::list<_client*>::iterator i = _CLIENTS.begin(); i != _CLIENTS.end(); i++)
  1456. + {
  1457. + if(MakeUpper((*i)->UName) == MakeUpper(USER))
  1458. + return true;
  1459. + }
  1460. +
  1461. + return false;
  1462. +}
  1463. +
  1464. +std::string IRCCmd::AcctIsBanned(std::string ACCT)
  1465. +{
  1466. + uint32 acctid = sAccountMgr.GetId(ACCT);
  1467. + std::string banned = "NOTBANNED";
  1468. + QueryResult *result = LoginDatabase.PQuery("SELECT banreason FROM ip_banned WHERE ip=(SELECT last_ip FROM account WHERE id = '%i')", acctid);
  1469. +
  1470. + if(result)
  1471. + {
  1472. + banned = (*result)[0].GetCppString();
  1473. + delete result;
  1474. + return "IP Banned. Reason:" + banned;
  1475. + }
  1476. +
  1477. + QueryResult *result2 = LoginDatabase.PQuery("SELECT banreason FROM account_banned WHERE id='%i'", acctid);
  1478. +
  1479. + if(result2)
  1480. + {
  1481. + banned = (*result2)[0].GetCppString();
  1482. + delete result2;
  1483. + return "Account Banned. Reason:" + banned;
  1484. + }
  1485. +
  1486. + return banned;
  1487. +}
  1488. +
  1489. +int IRCCmd::GetLevel(std::string sName)
  1490. +{
  1491. + for(std::list<_client*>::iterator i = _CLIENTS.begin(); i != _CLIENTS.end(); i++)
  1492. + {
  1493. + if((*i)->Name == sName)
  1494. + return (*i)->GMLevel;
  1495. + }
  1496. +
  1497. + return 0;
  1498. +}
  1499. +
  1500. +int IRCCmd::AcctLevel(std::string plnme)
  1501. +{
  1502. + ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(plnme);
  1503. + uint32 account_id = 0;
  1504. + uint32 security = 0;
  1505. + account_id = sObjectMgr.GetPlayerAccountIdByGUID(guid);
  1506. + security = sAccountMgr.GetSecurity(account_id);
  1507. +
  1508. + return security;
  1509. +}
  1510. +
  1511. +std::string IRCCmd::GetAccName(std::string sName)
  1512. +{
  1513. + for(std::list<_client*>::iterator i = _CLIENTS.begin(); i != _CLIENTS.end(); i++)
  1514. + {
  1515. + if((*i)->Name == sName)
  1516. + return (*i)->UName;
  1517. + }
  1518. +
  1519. + return "";
  1520. +}
  1521. +
  1522. +std::string IRCCmd::GetNameFromAcct(std::string sName)
  1523. +{
  1524. + for(std::list<_client*>::iterator i = _CLIENTS.begin(); i != _CLIENTS.end(); i++)
  1525. + {
  1526. + if((*i)->UName == sName)
  1527. + return (*i)->Name;
  1528. + }
  1529. +
  1530. + return "";
  1531. +}
  1532. +
  1533. +int IRCCmd::GetAcctIDFromName(std::string sName)
  1534. +{
  1535. + for(std::list<_client*>::iterator i = _CLIENTS.begin(); i != _CLIENTS.end(); i++)
  1536. + {
  1537. + if((*i)->Name == sName)
  1538. + {
  1539. + uint32 acct_id = 0;
  1540. + acct_id = sAccountMgr.GetId((*i)->UName.c_str());
  1541. + return acct_id;
  1542. + }
  1543. + }
  1544. +
  1545. + return 0;
  1546. +}
  1547. +
  1548. +std::string IRCCmd::GetAcctNameFromID(uint32 acctid)
  1549. +{
  1550. + QueryResult *result = LoginDatabase.PQuery("SELECT username FROM account WHERE id = '%d'", acctid);
  1551. +
  1552. + if(result)
  1553. + {
  1554. + std::string name = (*result)[0].GetCppString();
  1555. + delete result;
  1556. + return name;
  1557. + }
  1558. +
  1559. + return "";
  1560. +}
  1561. +
  1562. +std::string IRCCmd::GetCharNameFromGUID(ObjectGuid guid)
  1563. +{
  1564. + QueryResult *result = CharacterDatabase.PQuery("SELECT name FROM characters WHERE guid = '%d'", guid.GetCounter());
  1565. + if (result)
  1566. + {
  1567. + std::string name = (*result)[0].GetCppString();
  1568. + delete result;
  1569. + return name;
  1570. + }
  1571. +
  1572. + return "";
  1573. +}
  1574. +
  1575. +std::string IRCCmd::GetIPFromPlayer(std::string player)
  1576. +{
  1577. + QueryResult *result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name = '%s'", player.c_str());
  1578. + if(result)
  1579. + {
  1580. + std::string acctid = (*result)[0].GetCppString();
  1581. + delete result;
  1582. + QueryResult *result2 = LoginDatabase.PQuery("SELECT last_ip FROM account WHERE id = '%s'", acctid.c_str());
  1583. +
  1584. + if(result2)
  1585. + {
  1586. + std::string ip = (*result2)[0].GetCppString();
  1587. + delete result2;
  1588. + return ip;
  1589. + }
  1590. + }
  1591. +
  1592. + return "";
  1593. +}
  1594. +
  1595. +std::string IRCCmd::SecToDay(std::string secons)
  1596. +{
  1597. + unsigned int seconds = atoi(secons.c_str());
  1598. + unsigned int days = seconds / 86400;
  1599. + unsigned int hours = seconds / 3600 % 24;
  1600. + unsigned int mins = seconds / 60 % 60;
  1601. + char tottime[1000];
  1602. + sprintf(tottime, "%iDays:%iHours:%iMinutes", days, hours, mins);
  1603. +
  1604. + return tottime;
  1605. +}
  1606. +
  1607. +bool IRCCmd::ValidParams(std::string PARAMS, int nCount)
  1608. +{
  1609. + if(nCount == 1 && PARAMS.size() == 0)
  1610. + return false;
  1611. +
  1612. + int pcount = 0;
  1613. + size_t p = -1;
  1614. +
  1615. + for(int i = 0; i < nCount; i++)
  1616. + {
  1617. + p = PARAMS.find(" ", p + 1);
  1618. +
  1619. + if(p == -1)
  1620. + break;
  1621. + else
  1622. + pcount++;
  1623. + }
  1624. + nCount--;
  1625. +
  1626. + if(pcount >= nCount)
  1627. + return true;
  1628. + else
  1629. + return false;
  1630. +}
  1631. +
  1632. +std::string* IRCCmd::getArray(std::string PARAMS, int nCount)
  1633. +{
  1634. + std::string *array = new std::string[nCount];
  1635. +
  1636. + if(PARAMS.size() > 0)
  1637. + {
  1638. + int pcnt = 0;
  1639. + size_t ps = 0;
  1640. + size_t pc = -1;
  1641. + for(int i = 0; i < nCount; i++)
  1642. + {
  1643. + pc = PARAMS.find(" ", pc + 1);
  1644. + if(i + 1 == nCount && nCount != 1)
  1645. + {
  1646. + if(ps > 0 && pc > 0)
  1647. + array[i] = PARAMS.substr(ps, PARAMS.size() - ps);
  1648. + }
  1649. + else
  1650. + array[i] = PARAMS.substr(ps, pc - ps);
  1651. + ps = pc + 1;
  1652. + }
  1653. + }
  1654. +
  1655. + return array;
  1656. +}
  1657. +
  1658. +std::string IRCCmd::MakeMsg(const char *sLine, ... )
  1659. +{
  1660. + va_list ap;
  1661. + char tmpoutp[1024];
  1662. + va_start(ap, sLine);
  1663. + vsnprintf(tmpoutp, 1024, sLine, ap );
  1664. + va_end(ap);
  1665. + std::string outp = tmpoutp;
  1666. +
  1667. + return outp;
  1668. +}
  1669. +
  1670. +void IRCClient::AHFunc(uint64 itmid, std::string itmnme, std::string plname, uint32 faction)
  1671. +{
  1672. + IRCCmd Command;
  1673. + Player* plr = Command.GetPlayer(plname);
  1674. +
  1675. + if(plr)
  1676. + {
  1677. + std::string itemname = itmnme;
  1678. +
  1679. + char temp [7];
  1680. + sprintf(temp, "%u", itmid);
  1681. + std::string itemid = temp;
  1682. +
  1683. + std::string wowname = "";
  1684. + std::string ircname = "";
  1685. + switch (plr->GetTeam())
  1686. + {
  1687. + case 67: //horde
  1688. + wowname = "|cffff0000" + plname + "|r";
  1689. + ircname = "\0034" + plname;
  1690. + break;
  1691. + case 469: //alliance
  1692. + wowname = "|cff1589FF" + plname + "|r";
  1693. + ircname = "\00312" + plname;
  1694. + break;
  1695. + }
  1696. +
  1697. + std::string wowfact = "|cffFF8040[Auction House]:|r";
  1698. + std::string ircfact = "\00304,08\037/!\\\037\017\00307 Auction House \00304,08\037/!\\\037\017";
  1699. +
  1700. + switch(faction)
  1701. + {
  1702. + case 7: //neutral
  1703. + wowfact = "|cffff8040[Neutral Auction House]:|r";
  1704. + ircfact = "\00304,08\037/!\\\037\017\00307 Neutral Auction House \00304,08\037/!\\\037\017";
  1705. + break;
  1706. + case 6: //horde
  1707. + wowfact = "|cffff0000[Horde Auction House]:|r";
  1708. + ircfact = "\00304,08\037/!\\\037\017\00304 Horde Auction House \00304,08\037/!\\\037\017";
  1709. + break;
  1710. + case 2: //alliance
  1711. + wowfact = "|cff1589FF[Alliance Auction House]:|r";
  1712. + ircfact = "\00304,08\037/!\\\037\017\00312 Alliance Auction House \00304,08\037/!\\\037\017";
  1713. + break;
  1714. + }
  1715. +
  1716. + 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());
  1717. + std::string ircstr = Command.MakeMsg("%s A New Item Has Been Added [%s]. By: %s", ircfact.c_str(), itemname.c_str(), ircname.c_str());
  1718. +
  1719. + sIRC.Send_WoW_Channel(sIRC._wow_chan[sIRC.Status].c_str(), wowstr.c_str());
  1720. + sIRC.Send_IRC_Channel(sIRC._irc_chan[sIRC.Status].c_str(), ircstr.c_str());
  1721. + }
  1722. +}
  1723. +
  1724. +//NOTE: Removed "BeenToGMI" due to back overflows caused with new packet structure (Shinzon)
  1725. +
  1726. +//bool IRCClient::BeenToGMI(float posx, float posy, float posz, std::string player, std::string from)
  1727. +//{
  1728. +// IRCCmd Command;
  1729. +// std::transform(location.begin(), location.end(), location.begin(), towupper);
  1730. +// sObjectMgr.GetAreaId
  1731. +// if(location == "GMI" || location == "GMISLAND")
  1732. +// if(MapManager::Instance().GetZoneId(1,posx,posy,posz) == 876)
  1733. +// {
  1734. +// QueryResult *result = WorldDatabase.PQuery("SELECT name FROM Hell_GMI WHERE name = '%s'",player.c_str());
  1735. +// if(result)
  1736. +// {
  1737. +// delete result;
  1738. +// uint64 guid = sObjectMgr.GetPlayerGUIDByName(player);
  1739. +// Player* plr = sObjectMgr.GetPlayer(guid);
  1740. +// uint64 guid2 = sObjectMgr.GetPlayerGUIDByName(from);
  1741. +// Player* plr2 = sObjectMgr.GetPlayer(guid2);
  1742. +// if(plr) sIRC.Send_WoW_Player(plr, "You Have Already Had A Trip To GM Island. There Is Only One Tele To GM Island Per Player, Please Donate If You Would like The .tele Command.");
  1743. +// if(plr2) sIRC.Send_WoW_Player(plr2, "This Player Has Already Had Their Trip To GM Island. The Tele Has Been Canceled.");
  1744. +// else sIRC.Send_IRC_Channel(from.c_str(), MakeMsg(" \0034[ERROR] : $Player Has Already Had Their Trip To GMI! The Tele Has Been Canceled", "$Player", player.c_str()), true, "ERROR");
  1745. +// return true;
  1746. +// }
  1747. +// else
  1748. +// {
  1749. +// if(Command.AcctLevel(player) == 0)
  1750. +// WorldDatabase.PExecute("INSERT INTO `Hell_GMI` VALUES ('%s')", player.c_str());
  1751. +// return false;
  1752. +// }
  1753. +// }
  1754. +// return false;
  1755. +//}
  1756. diff --git a/src/game/mangchat/IRCCmd.h b/src/game/mangchat/IRCCmd.h
  1757. new file mode 100644
  1758. index 0000000..39f8d97
  1759. --- /dev/null
  1760. +++ b/src/game/mangchat/IRCCmd.h
  1761. @@ -0,0 +1,137 @@
  1762. +/*
  1763. + * MangChat for MaNGOS, the open source MMORPG-server
  1764. + *
  1765. + * This Program Is Free Software; You Can Redistribute It And/Or Modify It Under The
  1766. + * Terms Of The GNU General Public License
  1767. + *
  1768. + * Written and Developed by Cybrax <cybraxvd@gmail.com>, |Death| <death@hell360.net>,
  1769. + * Lice <lice@yeuxverts.net>, Dj_baby, Sanaell, Tase, Shinzon <shinzon@wowgollum.com>,
  1770. + * Xeross, 3raZar3, the orangevirus team <www.orangevir.us>, ...
  1771. + *
  1772. + * With Help And Support From The MaNGOS Project Community.
  1773. + * PLEASE RETAIN THE COPYRIGHT OF THE AUTHORS.
  1774. + */
  1775. +
  1776. +#ifndef _IRC_CMD_H
  1777. +#define _IRC_CMD_H
  1778. +
  1779. +#define MAX_CLIENTS 50
  1780. +#include "Common.h"
  1781. +#include "../Player.h"
  1782. +#include "../ObjectAccessor.h"
  1783. +
  1784. +struct ChannelUser
  1785. +{
  1786. + int UserType;
  1787. + std::string Name;
  1788. + std::string UName;
  1789. + int UserLevel;
  1790. +};
  1791. +
  1792. +struct _client
  1793. +{
  1794. + bool LoggedIn;
  1795. + std::string Name;
  1796. + std::string UName;
  1797. + int GMLevel;
  1798. +};
  1799. +
  1800. +struct _CDATA
  1801. +{
  1802. + std::string CMD;
  1803. + std::string USER;
  1804. + std::string FROM;
  1805. + std::string PARAMS;
  1806. + std::string TYPE;
  1807. + int PCOUNT;
  1808. +};
  1809. +
  1810. +enum APVERR
  1811. +{
  1812. + E_OK,
  1813. + E_SIZE,
  1814. + E_AUTH,
  1815. + E_IVALID,
  1816. +};
  1817. +
  1818. +enum ESOUNDS
  1819. +{
  1820. + S_ENTERWORLD = 602,
  1821. + S_QUESTFAILED = 847,
  1822. + S_INVITE = 880,
  1823. + S_LEVELUP = 888,
  1824. + S_COINSOUND = 895,
  1825. + S_WHISPER = 3081,
  1826. + S_STEALTH = 3325,
  1827. +};
  1828. +
  1829. +class IRCCmd
  1830. +{
  1831. + public:
  1832. + IRCCmd();
  1833. + ~IRCCmd();
  1834. +
  1835. + void Handle_Logout(_CDATA *CD);
  1836. + bool IsLoggedIn(std::string USER);
  1837. + bool IsValid(std::string USER, std::string FROM, std::string CHAT, std::string TYPE);
  1838. + bool AcctIsLoggedIn(std::string USER);
  1839. + _client *GetClient(std::string cname);
  1840. +
  1841. + static std::string MakeMsg(const char *sLine, ... );
  1842. + static std::string ChanOrPM(_CDATA *CD);
  1843. + int AcctLevel(std::string plnme);
  1844. + int GetLevel(std::string sName);
  1845. + std::string MakeUpper(std::string Channel);
  1846. + std::string AcctIsBanned(std::string ACCT);
  1847. + std::list<_client*> _CLIENTS;
  1848. + Player* GetPlayer(std::string WHO);
  1849. +
  1850. + private:
  1851. + // MangChat Commands
  1852. + void Handle_Login(_CDATA *CD);
  1853. + void Account_Player(_CDATA *CD);
  1854. + void Ban_Player(_CDATA *CD);
  1855. + void Chan_Control(_CDATA *CD);
  1856. + void Char_Player(_CDATA *CD);
  1857. + void Fun_Player(_CDATA *CD);
  1858. + void Help_IRC(_CDATA *CD);
  1859. + void Item_Player(_CDATA *CD);
  1860. + void Inchan_Server(_CDATA *CD);
  1861. + void Info_Server(_CDATA *CD);
  1862. + void Jail_Player(_CDATA *CD);
  1863. + void Kick_Player(_CDATA *CD);
  1864. + void Kill_Player(_CDATA *CD);
  1865. + void Level_Player(_CDATA *CD);
  1866. + void Lookup_Player(_CDATA *CD);
  1867. + void Money_Player(_CDATA *CD);
  1868. + void Mute_Player(_CDATA *CD);
  1869. + void Online_Players(_CDATA *CD);
  1870. + void PM_Player(_CDATA *CD);
  1871. + void Revive_Player(_CDATA *CD);
  1872. + void Saveall_Player(_CDATA *CD);
  1873. + void Shutdown_Mangos(_CDATA *CD);
  1874. + void Spell_Player(_CDATA *CD);
  1875. + void Sysmsg_Server(_CDATA *CD);
  1876. + void Tele_Player(_CDATA *CD);
  1877. + void Top_Player(_CDATA *CD);
  1878. + void Who_Logged(_CDATA *CD);
  1879. + void GM_Ticket(_CDATA *CD);
  1880. + bool CanUse(std::string USER, int nLevel);
  1881. + bool ValidParams(std::string PARAMS, int nCount = 1);
  1882. + bool ParamsValid(_CDATA *CD, int pCnt);
  1883. + int ParamsValid(_CDATA *CD, int pCnt, int rLev);
  1884. + std::string GetAccName(std::string sName);
  1885. + std::string GetNameFromAcct(std::string sName);
  1886. + std::string GetAcctNameFromID(uint32 acctid);
  1887. + std::string GetCharNameFromGUID(ObjectGuid guid);
  1888. + std::string GetIPFromPlayer(std::string player);
  1889. + std::string SecToDay(std::string secons);
  1890. + int GetAcctIDFromName(std::string sName);
  1891. + std::string* getArray(std::string PARAMS, int nCount = 1);
  1892. +};
  1893. +
  1894. +inline void MakeLower(std::string& str)
  1895. +{
  1896. + std::transform( str.begin(), str.end(), str.begin(), ::tolower );
  1897. +}
  1898. +#endif
  1899. diff --git a/src/game/mangchat/IRCCmde.cpp b/src/game/mangchat/IRCCmde.cpp
  1900. new file mode 100644
  1901. index 0000000..8e0567d
  1902. --- /dev/null
  1903. +++ b/src/game/mangchat/IRCCmde.cpp
  1904. @@ -0,0 +1,2059 @@
  1905. +/*
  1906. + * MangChat for MaNGOS, the open source MMORPG-server
  1907. + *
  1908. + * This Program Is Free Software; You Can Redistribute It And/Or Modify It Under The
  1909. + * Terms Of The GNU General Public License
  1910. + *
  1911. + * Written and Developed by Cybrax <cybraxvd@gmail.com>, |Death| <death@hell360.net>,
  1912. + * Lice <lice@yeuxverts.net>, Dj_baby, Sanaell, Tase, Shinzon <shinzon@wowgollum.com>,
  1913. + * Xeross, 3raZar3, the orangevirus team <www.orangevir.us>, ...
  1914. + *
  1915. + * With Help And Support From The MaNGOS Project Community.
  1916. + * PLEASE RETAIN THE COPYRIGHT OF THE AUTHORS.
  1917. + */
  1918. +
  1919. +#include "IRCCmd.h"
  1920. +#include "IRCClient.h"
  1921. +#include "MCS_OnlinePlayers.h"
  1922. +#include "WorldPacket.h"
  1923. +#include "Database/DatabaseEnv.h"
  1924. +#include "../Chat.h"
  1925. +#include "../MapManager.h"
  1926. +#include "../World.h"
  1927. +#include "../Guild.h"
  1928. +#include "../GuildMgr.h"
  1929. +#include "../ObjectMgr.h"
  1930. +#include "../AccountMgr.h"
  1931. +#include "../Language.h"
  1932. +#include "../SpellAuras.h"
  1933. +#include "SystemConfig.h"
  1934. +#include "revision_nr.h"
  1935. +#include "../../shared/Config/Config.h"
  1936. +#include "../GMTicketMgr.h"
  1937. +
  1938. +#define Send_Player(p, m) sIRC.Send_WoW_Player(p, m)
  1939. +#define Send_IRCA(c, m, b, t) sIRC.Send_IRC_Channel(c, m, b, t)
  1940. +
  1941. +#ifdef WIN32
  1942. + #define Delay(x) Sleep(x)
  1943. +#else
  1944. + #define Delay(x) sleep(x / 1000)
  1945. +#endif
  1946. +
  1947. +void IRCCmd::Handle_Login(_CDATA *CD)
  1948. +{
  1949. + std::string* _PARAMS = getArray(CD->PARAMS, 2);
  1950. + std::string isbanned = AcctIsBanned(_PARAMS[0]);
  1951. + if (isbanned == "NOTBANNED")
  1952. + {
  1953. + if (!IsLoggedIn(CD->USER))
  1954. + {
  1955. + if (!AcctIsLoggedIn(_PARAMS[0].c_str()))
  1956. + {
  1957. + QueryResult *result = LoginDatabase.PQuery("SELECT `gmlevel` FROM `account` WHERE `username`='%s' AND `sha_pass_hash`=SHA1(CONCAT(UPPER(`username`),':',UPPER('%s')));", _PARAMS[0].c_str(), _PARAMS[1].c_str());
  1958. + if (result)
  1959. + {
  1960. + Field *fields = result->Fetch();
  1961. + int GMLevel = fields[0].GetInt16();
  1962. + if (GMLevel >= 0)
  1963. + {
  1964. + _client *NewClient = new _client();
  1965. + NewClient->Name = CD->USER;
  1966. + NewClient->UName = MakeUpper(_PARAMS[0]);
  1967. + NewClient->GMLevel = fields[0].GetInt16();
  1968. + _CLIENTS.push_back(NewClient);
  1969. + Send_IRCA(CD->USER, MakeMsg("You Are Now Logged In As %s, Welcome To MangChat Admin Mode.", _PARAMS[0].c_str()), true, CD->TYPE);
  1970. +
  1971. + if (sIRC._op_gm == 1 && GMLevel >= sIRC._op_gm_lev)
  1972. + {
  1973. + for (int i=1;i < sIRC._chan_count + 1;i++)
  1974. + sIRC.SendIRC("MODE #"+sIRC._irc_chan[i]+" +o "+CD->USER );
  1975. + }
  1976. + }
  1977. + } else
  1978. + Send_IRCA(CD->USER, "\0034[ERROR] : Sorry, Your Username Or Password Is Incorrect. Please Try Again. ", true, "ERROR");
  1979. + } else
  1980. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : %s Is Already Logged In With This Username. ", GetNameFromAcct(MakeUpper(_PARAMS[0])).c_str()), true, "ERROR");
  1981. + } else
  1982. + Send_IRCA(CD->USER, "\0034[ERROR] : You Are Already Logged In As "+ _PARAMS[0] +"!", true, "ERROR");
  1983. + } else
  1984. + Send_IRCA(CD->USER, "\0034[ERROR] : Sorry You Are "+isbanned+". You Cannot Log In To MangChat "+CD->USER.c_str()+"!", true, "ERROR");
  1985. +}
  1986. +
  1987. +void IRCCmd::Handle_Logout(_CDATA *CD)
  1988. +{
  1989. + for (std::list<_client*>::iterator i=_CLIENTS.begin(); i!=_CLIENTS.end();i++)
  1990. + {
  1991. + if ((*i)->Name == CD->USER)
  1992. + {
  1993. + _CLIENTS.erase(i);
  1994. + delete (*i);
  1995. + Send_IRCA(CD->USER, "You Are Now Logged Out!", true, CD->TYPE);
  1996. + return;
  1997. + }
  1998. + }
  1999. + Send_IRCA(CD->USER, "\0034[ERROR] : You Are Not Logged In!", true, "ERROR");
  2000. +}
  2001. +
  2002. +void IRCCmd::Account_Player(_CDATA *CD)
  2003. +{
  2004. + std::string* _PARAMS = getArray(CD->PARAMS, 3);
  2005. + if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512))
  2006. + {
  2007. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : Nice Try, This Player Has A Higher GM Level Than You! [ %i ]", AcctLevel(_PARAMS[0])), true, "ERROR");
  2008. + return;
  2009. + }
  2010. + normalizePlayerName(_PARAMS[0]);
  2011. + ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(_PARAMS[0]);
  2012. + uint32 account_id = 0;
  2013. + account_id = sObjectMgr.GetPlayerAccountIdByGUID(guid);
  2014. + if (account_id)
  2015. + {
  2016. + if (account_id == GetAcctIDFromName(CD->USER) || GetLevel(CD->USER) >= sIRC._op_gm_lev)
  2017. + {
  2018. + Player* plr = sObjectMgr.GetPlayer(guid);
  2019. + if (_PARAMS[1] == "lock")
  2020. + {
  2021. + LoginDatabase.PExecute( "UPDATE `account` SET `locked` = '1' WHERE `id` = '%d'",account_id);
  2022. + if (plr) Send_Player(plr, MakeMsg("Your Account Has Been Locked To Your Current IP By: %s", CD->USER.c_str()));
  2023. + Send_IRCA(ChanOrPM(CD), "\00313["+GetAcctNameFromID(account_id)+"] : Account Has Been Locked To Their Current IP Address.", true, CD->TYPE);
  2024. + }
  2025. + else if (_PARAMS[1] == "unlock")
  2026. + {
  2027. + LoginDatabase.PExecute( "UPDATE `account` SET `locked` = '0' WHERE `id` = '%d'",account_id);
  2028. + if (plr) Send_Player(plr, MakeMsg("Your Account Has Been UnLocked From The Associated IP By: %s", CD->USER.c_str()));
  2029. + Send_IRCA(ChanOrPM(CD), "\00313["+GetAcctNameFromID(account_id)+"] : Account Has Been UnLocked From The Associated IP Address.", true, CD->TYPE);
  2030. + }
  2031. + else if (_PARAMS[1] == "mail")
  2032. + {
  2033. + LoginDatabase.PExecute( "UPDATE `account` SET `email` = '%s' WHERE `id` = '%d'",_PARAMS[2].c_str() ,account_id);
  2034. + if (plr) Send_Player(plr, MakeMsg("%s Has Changed Your EMail Adress To: %s", CD->USER.c_str(), _PARAMS[2].c_str()));
  2035. + Send_IRCA(ChanOrPM(CD), "\00313["+GetAcctNameFromID(account_id)+"] : EMail Address Successfully Changed To: "+_PARAMS[2], true, CD->TYPE);
  2036. + }
  2037. + else if (_PARAMS[1] == "pass")
  2038. + {
  2039. + LoginDatabase.PExecute( "UPDATE `account` SET `sha_pass_hash` = SHA1(CONCAT(UPPER(`username`),':',UPPER('%s'))) WHERE `id` = '%d'",_PARAMS[2].c_str() ,account_id);
  2040. + if (plr) Send_Player(plr, MakeMsg("%s Has Changed Your Password To: %s", CD->USER.c_str(), _PARAMS[2].c_str()));
  2041. + Send_IRCA(ChanOrPM(CD), "\00313["+GetAcctNameFromID(account_id)+"] : Password Successfully Changed To: "+_PARAMS[2], true, CD->TYPE);
  2042. + }
  2043. + else if (_PARAMS[1] == "rename")
  2044. + {
  2045. + if (plr)
  2046. + {
  2047. + plr->SetAtLoginFlag(AT_LOGIN_RENAME);
  2048. + Send_Player(plr, MakeMsg("%s Has Requested You Change This Characters Name, Rename Will Be Forced On Next Login!", CD->USER.c_str()));
  2049. + }
  2050. + CharacterDatabase.PExecute("UPDATE `characters` SET `at_login` = `at_login` | '1' WHERE `guid` = '%u'", guid.GetCounter());
  2051. + 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);
  2052. + }
  2053. + }
  2054. + else
  2055. + Send_IRCA(CD->USER, "\0034[ERROR] : You Are Not A GM, You May Only Change Settings In Your Own Account.", true, "ERROR");
  2056. + }
  2057. + else
  2058. + Send_IRCA(CD->USER, "\0034[ERROR] : No Such Player Exists, So Account Cannot Be Looked Up.", true, "ERROR");
  2059. +}
  2060. +
  2061. +void IRCCmd::Ban_Player(_CDATA *CD)
  2062. +{
  2063. + std::string* _PARAMS = getArray(CD->PARAMS, 3);
  2064. + if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512))
  2065. + {
  2066. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : Nice Try, This Player Has A Higher GM Level Than You! [ %i ]", AcctLevel(_PARAMS[0])), true, "ERROR");
  2067. + return;
  2068. + }
  2069. + if (_PARAMS[1] == "ip")
  2070. + {
  2071. + std::string ip = GetIPFromPlayer(_PARAMS[0]);
  2072. + if (_PARAMS[2] == "")
  2073. + _PARAMS[2] = "No Reason";
  2074. + if (ip != "")
  2075. + {
  2076. + LoginDatabase.PExecute( "INSERT IGNORE INTO `ip_banned` VALUES ('%s', UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), '%s', '%s')", ip.c_str(), CD->USER.c_str(), _PARAMS[2].c_str());
  2077. + if (Player* plr = GetPlayer(_PARAMS[0]))
  2078. + plr->GetSession()->KickPlayer();
  2079. + Send_IRCA(ChanOrPM(CD), MakeMsg("\00313[%s] : Has Had Their IP Address Banned. [%s] Reason: %s",_PARAMS[0].c_str() ,ip.c_str() , _PARAMS[2].c_str()), true, CD->TYPE);
  2080. + }
  2081. + else
  2082. + Send_IRCA(CD->USER, "\0034[ERROR] : I Cannot Locate An IP Address For The Character Name Given.", true, "ERROR");
  2083. + }
  2084. + if (_PARAMS[1] == "acct")
  2085. + {
  2086. + ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(_PARAMS[0].c_str());
  2087. + uint32 acctid = sObjectMgr.GetPlayerAccountIdByGUID(guid);
  2088. + if (_PARAMS[2] == "")
  2089. + _PARAMS[2] = "No Reason";
  2090. + if (acctid)
  2091. + {
  2092. + LoginDatabase.PExecute( "INSERT INTO `account_banned` VALUES ('%u', UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), '%s', '%s', 1)", acctid, CD->USER.c_str(), _PARAMS[2].c_str());
  2093. + if (Player* plr = GetPlayer(_PARAMS[0]))
  2094. + plr->GetSession()->KickPlayer();
  2095. + Send_IRCA(ChanOrPM(CD), MakeMsg("\00313[%s] : Has Had Their Account Banned. Reason: %s",_PARAMS[0].c_str(), _PARAMS[2].c_str()), true, CD->TYPE);
  2096. + }
  2097. + else
  2098. + Send_IRCA(CD->USER, "\0034[ERROR] : I Cannot Locate An Account For The Character Name Given.", true, "ERROR");
  2099. + }
  2100. + if (_PARAMS[1] == "unban")
  2101. + {
  2102. + std::string unbani = _PARAMS[0];
  2103. + if (atoi(unbani.c_str()) > 0)
  2104. + {
  2105. + LoginDatabase.PExecute( "DELETE FROM ip_banned WHERE ip = '%s'", _PARAMS[0].c_str());
  2106. + Send_IRCA(ChanOrPM(CD), MakeMsg("\00313[%s] : Has Been Removed From The IP Ban List.", _PARAMS[0].c_str()), true, CD->TYPE);
  2107. + }
  2108. + else
  2109. + {
  2110. + QueryResult *result = LoginDatabase.PQuery("SELECT id FROM `account` WHERE username = '%s'", _PARAMS[0].c_str());
  2111. + if (result)
  2112. + {
  2113. + Field *fields = result->Fetch();
  2114. + std::string id = fields[0].GetCppString();
  2115. +
  2116. + LoginDatabase.PExecute( "DELETE FROM account_banned WHERE id = %s", id.c_str());
  2117. + delete result;
  2118. + Send_IRCA(ChanOrPM(CD), MakeMsg("\00313[%s] : Has Been Removed From The Account Ban List.", _PARAMS[0].c_str()), true, CD->TYPE);
  2119. +
  2120. + }
  2121. + else
  2122. + Send_IRCA(CD->USER, "\0034[ERROR] : I Cannot Locate An Account Or IP Address For The Paramaters Given.", true, "ERROR");
  2123. + }
  2124. + }
  2125. +}
  2126. +
  2127. +void IRCCmd::Chan_Control(_CDATA *CD)
  2128. +{
  2129. + std::string* _PARAMS = getArray(CD->PARAMS, 2);
  2130. + if (CD->FROM == *(sIRC.GetNick()))
  2131. + {
  2132. + Send_IRCA(CD->USER, "\0034[ERROR] : You Cannot Use This Command Through A PM Yet.", true, "ERROR");
  2133. + return;
  2134. + }
  2135. + if (_PARAMS[0] == "op")
  2136. + {
  2137. + if (_PARAMS[1].length() > 1)
  2138. + sIRC.SendIRC("MODE "+CD->FROM+" +o "+_PARAMS[1] );
  2139. + else
  2140. + sIRC.SendIRC("MODE "+CD->FROM+" +o "+CD->USER );
  2141. + }
  2142. + if (_PARAMS[0] == "deop")
  2143. + {
  2144. + if (_PARAMS[1].length() > 1)
  2145. + sIRC.SendIRC("MODE "+CD->FROM+" -o "+_PARAMS[1] );
  2146. + else
  2147. + sIRC.SendIRC("MODE "+CD->FROM+" -o "+CD->USER );
  2148. + }
  2149. + if (_PARAMS[0] == "voice")
  2150. + {
  2151. + if (_PARAMS[1].length() > 1)
  2152. + sIRC.SendIRC("MODE "+CD->FROM+" +v "+_PARAMS[1] );
  2153. + else
  2154. + sIRC.SendIRC("MODE "+CD->FROM+" +v "+CD->USER );
  2155. + }
  2156. + if (_PARAMS[0] == "devoice")
  2157. + {
  2158. + if (_PARAMS[1].length() > 1)
  2159. + sIRC.SendIRC("MODE "+CD->FROM+" -v "+_PARAMS[1] );
  2160. + else
  2161. + sIRC.SendIRC("MODE "+CD->FROM+" -v "+CD->USER );
  2162. + }
  2163. +}
  2164. +
  2165. +void IRCCmd::Char_Player(_CDATA *CD)
  2166. +{
  2167. + std::string* _PARAMS = getArray(CD->PARAMS, 5);
  2168. + if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512))
  2169. + {
  2170. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : Nice Try, This Player Has A Higher GM Level Than You! [ %i ]", AcctLevel(_PARAMS[0])), true, "ERROR");
  2171. + return;
  2172. + }
  2173. + normalizePlayerName(_PARAMS[0]);
  2174. + ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(_PARAMS[0]);
  2175. + Player* plr = sObjectMgr.GetPlayer(guid);
  2176. + if (plr)
  2177. + {
  2178. + if (_PARAMS[1] == "mapcheat")
  2179. + {
  2180. + bool explore = false;
  2181. + if (_PARAMS[2] != "0")
  2182. + explore = true;
  2183. + for (uint8 i=0; i<64; i++)
  2184. + {
  2185. + if (_PARAMS[2] != "0")
  2186. + plr->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0xFFFFFFFF);
  2187. + else
  2188. + plr->SetFlag(PLAYER_EXPLORED_ZONES_1+i,0);
  2189. + }
  2190. + if (explore)
  2191. + {
  2192. + Send_Player(plr, MakeMsg("All Your Zones Have Been Set To Explored By: %s", CD->USER.c_str()));
  2193. + Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Now Explored All Zones.", true, CD->TYPE);
  2194. + }
  2195. + else
  2196. + {
  2197. + Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Now Had All Zones Set To Un-Explored.", true, CD->TYPE);
  2198. + Send_Player(plr, MakeMsg("All Your Zones Have Been Set To Un-Explored By: %s", CD->USER.c_str()));
  2199. + }
  2200. + }
  2201. + if (_PARAMS[1] == "taxicheat")
  2202. + {
  2203. + if (_PARAMS[2] != "0")
  2204. + {
  2205. + plr->SetTaxiCheater(true);
  2206. + Send_Player(plr, MakeMsg("Taxi Node Cheat Has Been Enabled By: %s", CD->USER.c_str()));
  2207. + Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Taxi Node Cheat Has Been Enabled.", true, CD->TYPE);
  2208. + }
  2209. + else
  2210. + {
  2211. + plr->SetTaxiCheater(false);
  2212. + Send_Player(plr, MakeMsg("Taxi Node Cheat Has Been Disabled By: %s", CD->USER.c_str()));
  2213. + Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Taxi Node Cheat Has Been Disabled.", true, CD->TYPE);
  2214. + }
  2215. + }
  2216. + if (_PARAMS[1] == "maxskill")
  2217. + {
  2218. + plr->UpdateSkillsToMaxSkillsForLevel();
  2219. + Send_Player(plr, MakeMsg("Your Skills Have Been Maxed Out By: %s", CD->USER.c_str()));
  2220. + Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Skills Have Been Maxed Out.", true, CD->TYPE);
  2221. + }
  2222. + if (_PARAMS[1] == "setskill")
  2223. + {
  2224. + std::string* _PARAMSA = getArray(_PARAMS[2], 4);
  2225. + uint32 skill = atoi(_PARAMS[2].c_str());
  2226. + uint32 level = atol(_PARAMS[3].c_str());
  2227. + int32 max = _PARAMS[4].c_str() ? atol (_PARAMS[4].c_str()) : plr->GetPureMaxSkillValue(skill);
  2228. + SkillLineEntry const* skilllookup = sSkillLineStore.LookupEntry(skill);
  2229. + //if skillid entered is not a number and greater then 0 then the command is being used wrong
  2230. + if (skill >= 0)
  2231. + {
  2232. + //does the skill even exist
  2233. + if (skilllookup)
  2234. + {
  2235. + //does player have the skill yet
  2236. + if (plr->GetSkillValue(skill))
  2237. + {
  2238. + plr->SetSkill(skill,level,max);
  2239. + 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()));
  2240. + 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);
  2241. + }
  2242. + else
  2243. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : Player Does Not Have The %s Skill Yet.", skilllookup->name[0]), true, "ERROR");
  2244. + }
  2245. + else
  2246. + Send_IRCA(CD->USER, "\0034[ERROR] : That Skill ID Does Not Exist.", true, "ERROR");
  2247. + }
  2248. + else
  2249. + Send_IRCA(CD->USER, "\0034[ERROR] : The Skill ID Entered Is Invalid.", true, "ERROR");
  2250. + }
  2251. + }
  2252. + else
  2253. + Send_IRCA(CD->USER, "\0034[ERROR] : No Character With That Name Exists.", true, "ERROR");
  2254. +}
  2255. +
  2256. +void IRCCmd::Fun_Player(_CDATA *CD)
  2257. +{
  2258. + std::string* _PARAMS = getArray(CD->PARAMS, 3);
  2259. + if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512))
  2260. + {
  2261. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : Nice Try, This Player Has A Higher GM Level Than You! [ %i ]", AcctLevel(_PARAMS[0])), true, "ERROR");
  2262. + return;
  2263. + }
  2264. + if (Player* plr = GetPlayer(_PARAMS[0]))
  2265. + {
  2266. + if (_PARAMS[1] == "say")
  2267. + {
  2268. + plr->Say(_PARAMS[2], LANG_UNIVERSAL);
  2269. + Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Was Forced To Say: "+_PARAMS[2]+".", true, CD->TYPE);
  2270. + }
  2271. + if (_PARAMS[1] == "sound")
  2272. + {
  2273. + uint32 sndid = atoi(_PARAMS[2].c_str());
  2274. + plr->PlayDistanceSound(sndid);
  2275. + Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Just Heard Sound ID: "+_PARAMS[2]+".", true, CD->TYPE);
  2276. + }
  2277. + }
  2278. + else
  2279. + Send_IRCA(CD->USER, "\0034[ERROR] : Player Not Online!", true, "ERROR");
  2280. +}
  2281. +
  2282. +void IRCCmd::Help_IRC(_CDATA *CD)
  2283. +{
  2284. + std::string* _PARAMS = getArray(CD->PARAMS, 1);
  2285. + QueryResult *result = WorldDatabase.PQuery("SELECT `Command`, `Description`, `gmlevel` FROM `irc_commands`");
  2286. + if (result)
  2287. + {
  2288. + if (IsLoggedIn(CD->USER))
  2289. + {
  2290. + if (_PARAMS[0] == "")
  2291. + {
  2292. + QueryResult *result = WorldDatabase.PQuery("SELECT * FROM `irc_commands` WHERE `gmlevel` <= %u ORDER BY `Command`", GetLevel(CD->USER));
  2293. + if (result)
  2294. + {
  2295. + std::string output = "\002MangChat IRC Commands:\017 ";
  2296. + for (uint64 i=0; i < result->GetRowCount(); i++)
  2297. + {
  2298. + Field *fields = result->Fetch();
  2299. + output += fields[0].GetCppString() + ", ";
  2300. + result->NextRow();
  2301. + }
  2302. + delete result;
  2303. + Send_IRCA(CD->USER, output, true, CD->TYPE.c_str());
  2304. + }
  2305. + }
  2306. + else
  2307. + {
  2308. + QueryResult *result = WorldDatabase.PQuery("SELECT `Description`, `gmlevel` FROM `irc_commands` WHERE `Command` = '%s'", _PARAMS[0].c_str());
  2309. + if (result)
  2310. + {
  2311. + Field *fields = result->Fetch();
  2312. + if (fields[1].GetInt32() > GetLevel(CD->USER))
  2313. + {
  2314. + Send_IRCA(CD->USER, "You Do Not Have Access To That Command, So No Help Is Available.", true, CD->TYPE.c_str());
  2315. + return;
  2316. + }
  2317. + if (result)
  2318. + {
  2319. + std::string cmdhlp = fields[0].GetCppString();
  2320. + delete result;
  2321. + Send_IRCA(CD->USER, cmdhlp, true, CD->TYPE.c_str());
  2322. + }
  2323. + }
  2324. + else
  2325. + Send_IRCA(CD->USER, "\0034[ERROR] : No Such Command Exists, Please Check The Spelling And Try Again.", true, "ERROR");
  2326. + }
  2327. + }
  2328. + else if (!IsLoggedIn(CD->USER))
  2329. + {
  2330. + if (_PARAMS[0] == "")
  2331. + {
  2332. + QueryResult *result = WorldDatabase.PQuery("SELECT * FROM `irc_commands` WHERE `gmlevel` = 0 ORDER BY `Command`");
  2333. + if (result)
  2334. + {
  2335. + std::string output = "\002MangChat IRC Commands:\017 ";
  2336. + for (uint64 i=0; i < result->GetRowCount(); i++)
  2337. + {
  2338. + Field *fields = result->Fetch();
  2339. + output += fields[0].GetCppString() + ", ";
  2340. + result->NextRow();
  2341. + }
  2342. + delete result;
  2343. + Send_IRCA(CD->USER, output, true, CD->TYPE.c_str());
  2344. + 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());
  2345. + }
  2346. + }
  2347. + else
  2348. + {
  2349. + QueryResult *result = WorldDatabase.PQuery("SELECT `Description`, `gmlevel` FROM `irc_commands` WHERE `Command` = '%s'", _PARAMS[0].c_str());
  2350. + if (result)
  2351. + {
  2352. + Field *fields = result->Fetch();
  2353. + if (fields[1].GetUInt32() > 0)
  2354. + {
  2355. + Send_IRCA(CD->USER, "You Do Not Have Access To That Command, So No Help Is Available.", true, CD->TYPE.c_str());
  2356. + return;
  2357. + }
  2358. + std::string cmdhlp = fields[0].GetCppString();
  2359. + delete result;
  2360. + Send_IRCA(CD->USER, cmdhlp, true, CD->TYPE.c_str());
  2361. + }
  2362. + else
  2363. + Send_IRCA(CD->USER, "\0034[ERROR] : No Such Command Exists, Please Check The Spelling And Try Again.", true, "ERROR");
  2364. + }
  2365. + }
  2366. + }
  2367. + else
  2368. + Send_IRCA(CD->USER, "\0034[ERROR] : Database Error! Please Make Sure You Used irc_commands.sql, You Must Have A Table In Your World Database (irc_commands)!", true, "ERROR");
  2369. +}
  2370. +
  2371. +void IRCCmd::Inchan_Server(_CDATA *CD)
  2372. +{
  2373. + std::string* _PARAMS = getArray(CD->PARAMS, 1);
  2374. + if (_PARAMS[0] == "")
  2375. + {
  2376. + Send_IRCA(CD->USER, "\0034[ERROR] : Syntax Error! ( "+sIRC._cmd_prefx+"inchan <ChannelName> )", true, "ERROR");
  2377. + return;
  2378. + }
  2379. + QueryResult *result = WorldDatabase.PQuery("SELECT * FROM `irc_inchan` WHERE `channel` = '%s' ORDER BY `name`", _PARAMS[0].c_str());
  2380. + if (result)
  2381. + {
  2382. + Field *fields = result->Fetch();
  2383. + std::string output = "\002Players In The [ "+fields[2].GetCppString()+" ] Channel:\017 ";
  2384. + for (uint64 i=0; i < result->GetRowCount(); i++)
  2385. + {
  2386. + output += fields[1].GetCppString() + ", ";
  2387. + result->NextRow();
  2388. + }
  2389. + delete result;
  2390. + Send_IRCA(ChanOrPM(CD), output, true, CD->TYPE);
  2391. + }
  2392. + else
  2393. + Send_IRCA(ChanOrPM(CD), "No Players Are Currently In [ "+_PARAMS[0]+" ] Channel!", true, CD->TYPE.c_str());
  2394. +}
  2395. +
  2396. +void IRCCmd::Info_Server(_CDATA *CD)
  2397. +{
  2398. + std::string* _PARAMS = getArray(CD->PARAMS, 1);
  2399. +
  2400. + // get currently active Players
  2401. + char clientsNum [50];
  2402. + sprintf(clientsNum, "%u", sWorld.GetActiveSessionCount());
  2403. +
  2404. + // get max active Players since last restart
  2405. + char maxClientsNum [50];
  2406. + sprintf(maxClientsNum, "%u", sWorld.GetMaxActiveSessionCount());
  2407. +
  2408. + // get UpTime
  2409. + std::string upTime = secsToTimeString(sWorld.GetUptime());
  2410. +
  2411. + // Send Player and Uptime information to IRC
  2412. + Send_IRCA(ChanOrPM(CD), "\x2 Number Of Players Online:\x3\x31\x30 " + (std::string)clientsNum + "\xF |\x2 Max Since Last Restart:\x3\x31\x30 "+(std::string)maxClientsNum+"\xF |\x2 UpTime:\x3\x31\x30 "+upTime, true, CD->TYPE);
  2413. +
  2414. + // send core revision info to IRC
  2415. + #ifdef _DISTRIBUTION
  2416. + Send_IRCA(ChanOrPM(CD), " Core: \x2 " +(std::string)_DISTRIBUTION +" \x2 based on \x2 MaNGOS ["+ (std::string)REVISION_NR+"]", true, CD->TYPE);
  2417. + #else
  2418. + Send_IRCA(ChanOrPM(CD), " Core: \x2 MaNGOS ["+ (std::string)REVISION_NR+"]", true, CD->TYPE);
  2419. + #endif
  2420. +
  2421. +
  2422. + // send scripting library info to IRC
  2423. + std::string scriptVersion;
  2424. + if (sScriptMgr.IsScriptLibraryLoaded())
  2425. + {
  2426. + scriptVersion = sScriptMgr.GetScriptLibraryVersion();
  2427. + if (scriptVersion.empty())
  2428. + scriptVersion= "Unknown Script Library.";
  2429. + // cut a bit, if it is too long
  2430. + else if (scriptVersion.length() > 30)
  2431. + scriptVersion = scriptVersion.substr(0,30) + "...";
  2432. + }
  2433. + else
  2434. + scriptVersion = "No Script Library loaded!";
  2435. +
  2436. + Send_IRCA(ChanOrPM(CD), " Script Library: \x2"+scriptVersion, true, CD->TYPE);
  2437. +
  2438. +
  2439. + // send DB info to IRC
  2440. + std::string dbVersion(sWorld.GetDBVersion());
  2441. + if (dbVersion.empty())
  2442. + dbVersion = "Unknown DB Version.";
  2443. + else if (dbVersion.length() > 30)
  2444. + dbVersion = dbVersion.substr(0,30) + "...";
  2445. +
  2446. + Send_IRCA(ChanOrPM(CD), " Database: \x2"+dbVersion, true, CD->TYPE);
  2447. +}
  2448. +
  2449. +void IRCCmd::Item_Player(_CDATA *CD)
  2450. +{
  2451. + std::string* _PARAMS = getArray(CD->PARAMS, 3);
  2452. +
  2453. + normalizePlayerName(_PARAMS[0]);
  2454. + Player *chr = GetPlayer(_PARAMS[0].c_str());
  2455. + if (_PARAMS[1] == "add")
  2456. + {
  2457. + std::string s_param = _PARAMS[2];
  2458. +
  2459. + char *args = (char*)s_param.c_str();
  2460. + uint32 itemId = 0;
  2461. + if (args[0]=='[')
  2462. + {
  2463. + char* citemName = citemName = strtok((char*)args, "]");
  2464. + if (citemName && citemName[0])
  2465. + {
  2466. + std::string itemName = citemName+1;
  2467. + WorldDatabase.escape_string(itemName);
  2468. + QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
  2469. + if (!result)
  2470. + {
  2471. + Send_IRCA(CD->USER, "\0034[ERROR] : Item Not Found!", true, "ERROR");
  2472. + return;
  2473. + }
  2474. + itemId = result->Fetch()->GetUInt16();
  2475. + delete result;
  2476. + }
  2477. + else
  2478. + {
  2479. + Send_IRCA(CD->USER, "\0034[ERROR] : Syntax Error! ( "+sIRC._cmd_prefx+"item <Player> <add> [Exact Item Name] <Amount> )", true, "ERROR");
  2480. + return;
  2481. + }
  2482. + }
  2483. + else
  2484. + {
  2485. + std::string itemName = s_param;
  2486. + WorldDatabase.escape_string(itemName);
  2487. + QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE name = '%s'", itemName.c_str());
  2488. + if (result)
  2489. + {
  2490. + itemId = result->Fetch()->GetUInt16();
  2491. + }
  2492. + delete result;
  2493. +
  2494. + char* cId = strtok(args, " ");
  2495. + if (!cId)
  2496. + {
  2497. + Send_IRCA(CD->USER, "\0034[ERROR] : Syntax Error! ( "+sIRC._cmd_prefx+"item <Player> <add> <ItemID> <Amount> )", true, "ERROR");
  2498. + return;
  2499. + }
  2500. + itemId = atol(cId);
  2501. + }
  2502. + char* ccount = strtok(NULL, " ");
  2503. + int32 count = 1;
  2504. + if (ccount) {
  2505. + count = atol(ccount);
  2506. + }
  2507. + Player* plTarget = chr;
  2508. + if (!plTarget)
  2509. + {
  2510. + Send_IRCA(CD->USER, "\0034[ERROR] : "+_PARAMS[0]+" Is Not Online!", true, "ERROR");
  2511. + return;
  2512. + }
  2513. + ItemPrototype const *pProto = sObjectMgr.GetItemPrototype(itemId);
  2514. + //Subtract
  2515. + if (count < 0)
  2516. + {
  2517. + plTarget->DestroyItemCount(itemId, -count, true, false);
  2518. + char itemid2[255];
  2519. + sprintf(itemid2,"%d",itemId);
  2520. + std::string itake = " \00313["+ _PARAMS[0] +"] : Has Had Item " +itemid2+ " Taken From Them!";
  2521. + Send_IRCA(ChanOrPM(CD), itake, true, CD->TYPE);
  2522. + return;
  2523. + }
  2524. + //Adding items
  2525. + uint32 noSpaceForCount = 0;
  2526. +
  2527. + // check space and find places
  2528. + ItemPosCountVec dest;
  2529. + uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount );
  2530. + if ( msg == EQUIP_ERR_INVENTORY_FULL ) // convert to possibel store amount
  2531. + count -= noSpaceForCount;
  2532. + else if ( msg != EQUIP_ERR_OK ) // other error, can't add
  2533. + {
  2534. + char s_countForStore[255];
  2535. + sprintf(s_countForStore,"%d",count);
  2536. + std::string ierror = " \00313["+ _PARAMS[0] +"] : Could Not Create All Items! " +s_countForStore+ " Item(s) Were Not Created!";
  2537. + Send_IRCA(ChanOrPM(CD), ierror, true, CD->TYPE);
  2538. + return;
  2539. + }
  2540. + Item* item = plTarget->StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
  2541. + if (count > 0 && item)
  2542. + {
  2543. + plTarget->SendNewItem(item,count,true,false);
  2544. + QueryResult *result = WorldDatabase.PQuery("SELECT name FROM item_template WHERE entry = %d", itemId);
  2545. + char* dbitemname = NULL;
  2546. + if (result)
  2547. + {
  2548. + dbitemname = (char*)result->Fetch()->GetString();
  2549. + }
  2550. + std::string iinfo = " \00313[" + _PARAMS[0] + "] : Has Been Given Item "+dbitemname+". From: "+CD->USER.c_str()+".";
  2551. + Send_IRCA(ChanOrPM(CD), iinfo, true, CD->TYPE);
  2552. + delete result;
  2553. + }
  2554. + if (noSpaceForCount > 0)
  2555. + {
  2556. + char s_countForStore[255];
  2557. + sprintf(s_countForStore,"%d",noSpaceForCount);
  2558. + std::string ierror = " \00313["+ _PARAMS[0] +"] : Could Not Create All Items! " +s_countForStore+ " Item(s) Were Not Created!";
  2559. + Send_IRCA(ChanOrPM(CD), ierror, true, CD->TYPE);
  2560. + return;
  2561. + }
  2562. + }
  2563. + else
  2564. + {
  2565. + Send_IRCA(CD->USER, "\0034[ERROR] : Syntax Error! ( "+sIRC._cmd_prefx+"item <Player> <add> <ItemID> <Amount> )", true, "ERROR");
  2566. + return;
  2567. + }
  2568. +}
  2569. +
  2570. +void IRCCmd::Jail_Player(_CDATA *CD)
  2571. +{
  2572. + if (ValidParams(CD->PARAMS, 1))
  2573. + {
  2574. + std::string* _PARAMS = getArray(CD->PARAMS, 2);
  2575. + if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512))
  2576. + {
  2577. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : Nice Try, This Player Has A Higher GM Level Than You! [ %i ]", AcctLevel(_PARAMS[0])), true, "ERROR");
  2578. + return;
  2579. + }
  2580. + if (Player *plr = GetPlayer(_PARAMS[0]))
  2581. + {
  2582. + std::string sReason = "";
  2583. + if (_PARAMS[1] == "release")
  2584. + {
  2585. + float rposx, rposy, rposz, rposo = 0;
  2586. + uint32 rmapid = 0;
  2587. + CharacterDatabase.escape_string(_PARAMS[0]);
  2588. + QueryResult *result = CharacterDatabase.PQuery( "SELECT `map`, `position_x`, `position_y`, `position_z` FROM `character_homebind` WHERE `guid` = '" UI64FMTD "'", plr->GetObjectGuid() );
  2589. + if (result)
  2590. + {
  2591. + Field *fields = result->Fetch();
  2592. + rmapid = fields[0].GetUInt16();
  2593. + rposx = fields[1].GetFloat();
  2594. + rposy = fields[2].GetFloat();
  2595. + rposz = fields[3].GetFloat();
  2596. + delete result;
  2597. + plr->SetMovement(MOVE_UNROOT);
  2598. + plr->TeleportTo(rmapid, rposx, rposy, rposz, rposo);
  2599. + plr->RemoveAurasDueToSpell(42201);
  2600. + plr->RemoveAurasDueToSpell(23775);
  2601. + plr->RemoveAurasDueToSpell(9454);
  2602. + Send_Player(plr, MakeMsg("You Have Been Released By: %s.", CD->USER.c_str()));
  2603. + sReason = " \00313["+_PARAMS[0]+"] : Has Been Released By: "+CD->USER+".";
  2604. + Send_IRCA(ChanOrPM(CD), sReason, true, CD->TYPE);
  2605. + }
  2606. + }
  2607. + else
  2608. + {
  2609. + if (_PARAMS[1] == "")
  2610. + _PARAMS[1] = "No Reason Given.";
  2611. + plr->TeleportTo(13, 0, 0, 0, 0);
  2612. + plr->SetMovement(MOVE_ROOT);
  2613. + plr->CastSpell(plr, 42201, true);
  2614. + plr->CastSpell(plr, 23775, true);
  2615. + plr->CastSpell(plr, 9454, true);
  2616. + Send_Player(plr, MakeMsg("You Have Been Jailed By: %s. Reason: %s.", CD->USER.c_str(), _PARAMS[1].c_str()));
  2617. + sReason = " \00313["+_PARAMS[0]+"] : Has Been Jailed By: "+CD->USER+". Reason: "+_PARAMS[1]+".";
  2618. + Send_IRCA(ChanOrPM(CD), sReason, true, CD->TYPE);
  2619. + }
  2620. + }
  2621. + else
  2622. + Send_IRCA(CD->USER, "\0034[ERROR] : "+_PARAMS[0]+" Is Not Online!", true, "ERROR");
  2623. + }
  2624. +}
  2625. +
  2626. +void IRCCmd::Kick_Player(_CDATA *CD)
  2627. +{
  2628. + std::string* _PARAMS = getArray(CD->PARAMS, CD->PCOUNT);
  2629. + if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512))
  2630. + {
  2631. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : Nice Try, This Player Has A Higher GM Level Than You! [ %i ]", AcctLevel(_PARAMS[0])), true, "ERROR");
  2632. + return;
  2633. + }
  2634. + if (_PARAMS[1] == "")
  2635. + _PARAMS[1] = "No Reason Given.";
  2636. + if (Player* plr = GetPlayer(_PARAMS[0]))
  2637. + {
  2638. + plr->GetSession()->KickPlayer();
  2639. + Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Been Kicked By: "+CD->USER+". Reason: "+_PARAMS[1]+".", true, CD->TYPE);
  2640. + }
  2641. + else
  2642. + Send_IRCA(CD->USER, "\0034[ERROR] : "+_PARAMS[0]+" Is Not Online!", true, "ERROR");
  2643. +}
  2644. +
  2645. +void IRCCmd::Kill_Player(_CDATA *CD)
  2646. +{
  2647. + std::string* _PARAMS = getArray(CD->PARAMS, CD->PCOUNT);
  2648. + if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512))
  2649. + {
  2650. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : Nice Try, This Player Has A Higher GM Level Than You! [ %i ]", AcctLevel(_PARAMS[0])), true, "ERROR");
  2651. + return;
  2652. + }
  2653. + if (Player* plr = GetPlayer(_PARAMS[0]))
  2654. + {
  2655. + if (plr->isAlive())
  2656. + {
  2657. + plr->DealDamage(plr, plr->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
  2658. + plr->SaveToDB();
  2659. + if (_PARAMS[1] == "")
  2660. + _PARAMS[1] = "No Reason Given.";
  2661. + 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);
  2662. + Send_Player(plr, MakeMsg("You Have Been Killed By: %s. Reason: %s.", CD->USER.c_str(), _PARAMS[1].c_str()));
  2663. + }
  2664. + else
  2665. + Send_IRCA(CD->USER, "\0034[ERROR] : "+_PARAMS[0]+" Is Already Dead!", true, "ERROR");
  2666. + }
  2667. + else
  2668. + Send_IRCA(CD->USER, "\0034[ERROR] : "+_PARAMS[0]+" Is Not Online!", true, "ERROR");
  2669. +}
  2670. +
  2671. +void IRCCmd::Lookup_Player(_CDATA *CD)
  2672. +{
  2673. + std::string* _PARAMS = getArray(CD->PARAMS, CD->PCOUNT);
  2674. + if (_PARAMS[0] == "acct")
  2675. + {
  2676. + uint32 acctid = atoi(_PARAMS[1].c_str());
  2677. + if (sAccountMgr.GetId(_PARAMS[1]))
  2678. + acctid = sAccountMgr.GetId(_PARAMS[1]);
  2679. + if (acctid > 0)
  2680. + {
  2681. + std::string DateTime = "%a, %b %d, %Y - %h:%i%p";
  2682. + QueryResult *result = LoginDatabase.PQuery("SELECT id, username, gmlevel, last_ip, (SELECT banreason FROM account_banned WHERE id = %d LIMIT 1) as banned, (SELECT banreason FROM ip_banned WHERE ip = last_ip) as bannedip, DATE_FORMAT(last_login, '%s') FROM `account` WHERE id = %d", acctid, DateTime.c_str(), acctid, acctid);
  2683. + if (result)
  2684. + {
  2685. + Field *fields = result->Fetch();
  2686. +
  2687. + uint32 id = fields[0].GetUInt32();
  2688. + std::string usrname = fields[1].GetCppString();
  2689. + uint32 gm = fields[2].GetUInt32();
  2690. + std::string lastip = fields[3].GetCppString();
  2691. + std::string banreason = fields[4].GetCppString();
  2692. + std::string banreasonip = fields[5].GetCppString();
  2693. + std::string lastlogin = fields[6].GetCppString();
  2694. + delete result;
  2695. +
  2696. + QueryResult *chars = CharacterDatabase.PQuery("SELECT guid, name, (SELECT SUM(totaltime) FROM characters WHERE account = %d) AS tottime FROM characters WHERE account = %u", id, id);
  2697. + std::string characters = "None";
  2698. + std::string totaccttime = "Never Logged In";
  2699. + if (chars)
  2700. + {
  2701. + characters = "";
  2702. + Field *fields = chars->Fetch();
  2703. + totaccttime = SecToDay(fields[2].GetCppString());
  2704. + for (uint64 i=0; i < chars->GetRowCount(); i++)
  2705. + {
  2706. + std::string guid = fields[0].GetCppString();
  2707. + std::string charname = fields[1].GetCppString();
  2708. + characters.append(charname+"("+guid+"), ");
  2709. + chars->NextRow();
  2710. + }
  2711. + delete chars;
  2712. + }
  2713. + Send_IRCA(ChanOrPM(CD), MakeMsg("\x2Username:\x3\x31\x30 %s \xF|\x2 AccountID:\x3\x31\x30 %d \xF|\x2 GM Level:\x3\x31\x30 %d \xF|\x2 Last IP:\x3\x31\x30 %s \xF|\x2 Last Login:\x3\x31\x30 %s", usrname.c_str(), id, gm, lastip.c_str(), lastlogin.c_str()), true, CD->TYPE);
  2714. + Send_IRCA(ChanOrPM(CD), MakeMsg("\x2Total Play Time:\x3\x31\x30 %s \xF|\x2 Characters:\x3\x31\x30 %s ", totaccttime.c_str(), characters.c_str()), true, CD->TYPE);
  2715. + if (banreason.length() > 1)
  2716. + Send_IRCA(ChanOrPM(CD), MakeMsg("\0034This User Has An Account Ban. Ban Reason: %s", banreason.c_str()), true, CD->TYPE);
  2717. + if (banreasonip.length() > 1)
  2718. + Send_IRCA(ChanOrPM(CD), MakeMsg("\0034This User Has An IP Ban. Ban Reason: %s", banreasonip.c_str()), true, CD->TYPE);
  2719. + }
  2720. + else
  2721. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown Account ID." ,true, "ERROR");
  2722. + }
  2723. + else
  2724. + {
  2725. + QueryResult *result = LoginDatabase.PQuery("SELECT id, username FROM `account` WHERE username LIKE '%%%s%%' LIMIT 10", _PARAMS[1].c_str());
  2726. + if (result)
  2727. + {
  2728. + Field *fields = result->Fetch();
  2729. + std::string accts = "\002Account Search Results:\x3\x31\x30 ";
  2730. + for (uint64 i=0; i < result->GetRowCount(); i++)
  2731. + {
  2732. + std::string acctid = fields[0].GetCppString();
  2733. + std::string acctname = fields[1].GetCppString();
  2734. + accts.append(acctname+"("+acctid+")\xF | \x3\x31\x30\x2");
  2735. + result->NextRow();
  2736. + }
  2737. + delete result;
  2738. + Send_IRCA(ChanOrPM(CD), accts, true, CD->TYPE);
  2739. + }
  2740. + else
  2741. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown Username. I Cant Find Any Users With Those Search Terms." ,true, "ERROR");
  2742. + }
  2743. + }
  2744. + if (_PARAMS[0] == "char")
  2745. + {
  2746. + ObjectGuid plguid = ObjectGuid(uint64(_PARAMS[1].c_str()));
  2747. + if (!sObjectMgr.GetPlayerGuidByName(_PARAMS[1].c_str()).IsEmpty())
  2748. + plguid = sObjectMgr.GetPlayerGuidByName(_PARAMS[1].c_str());
  2749. + if (!plguid.IsEmpty())
  2750. + {
  2751. + QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, name, race, class, online, SUBSTRING_INDEX(SUBSTRING_INDEX(`data`, ' ' , 35), ' ' , -1) AS level, SUBSTRING_INDEX(SUBSTRING_INDEX(`data`, ' ' , 238), ' ' , -1) AS guildid, SUBSTRING_INDEX(SUBSTRING_INDEX(`data`, ' ' , 239), ' ' , -1) AS guildrank, SUBSTRING_INDEX(SUBSTRING_INDEX(`data`, ' ' , 927), ' ' , -1) AS xp, SUBSTRING_INDEX(SUBSTRING_INDEX(`data`, ' ' , 928), ' ' , -1) AS maxxp, SUBSTRING_INDEX(SUBSTRING_INDEX(data, ' ' , 1462), ' ' , -1) AS gold, SUBSTRING_INDEX(SUBSTRING_INDEX(`data`, ' ' , 1454), ' ' , -1) AS hk, totaltime FROM characters WHERE guid =%i", plguid.GetCounter());
  2752. + uint32 latency = 0;
  2753. + Player *chr = sObjectMgr.GetPlayer(plguid);
  2754. + if (chr)
  2755. + {
  2756. + latency = chr->GetSession()->GetLatency();
  2757. + }
  2758. + char templatency [100];
  2759. + sprintf(templatency, "%ums", latency);
  2760. + if (result)
  2761. + {
  2762. + Field *fields = result->Fetch();
  2763. + std::string pguid = fields[0].GetCppString();
  2764. + std::string pacct = fields[1].GetCppString();
  2765. + std::string pname = fields[2].GetCppString();
  2766. + uint32 praceid = fields[3].GetUInt32();
  2767. + uint32 pclassid = fields[4].GetUInt32();
  2768. + std::string ponline = (fields[5].GetInt32() == 1 ? "\x3\x30\x33Online" : "\x3\x30\x34Offline\xF");
  2769. + std::string plevel = fields[6].GetCppString();
  2770. + uint32 pguildid = fields[7].GetUInt32();
  2771. + uint32 pguildrank = fields[8].GetUInt32();
  2772. + std::string pxp = fields[9].GetCppString();
  2773. + std::string pmaxxp = fields[10].GetCppString();
  2774. + unsigned int money = fields[11].GetInt32();
  2775. + std::string hk = fields[12].GetCppString();
  2776. + std::string totaltim = SecToDay(fields[13].GetCppString());
  2777. + delete result;
  2778. + std::string sqlquery = "SELECT `gmlevel` FROM `account` WHERE `id` = '" + pacct + "';";
  2779. + QueryResult *result = LoginDatabase.Query(sqlquery.c_str());
  2780. + Field *fields2 = result->Fetch();
  2781. + std::string pgmlvl = fields2[0].GetCppString();
  2782. + delete result;
  2783. + std::string guildinfo = "";
  2784. + if (pguildid != 0)
  2785. + {
  2786. + Guild* guild = sGuildMgr.GetGuildById(pguildid);
  2787. + if (guild)
  2788. + {
  2789. + guildinfo = " " + guild->GetRankName(pguildrank) + " Of " + guild->GetName();
  2790. + }
  2791. + }
  2792. + else guildinfo = " None";
  2793. + ChrRacesEntry const* prace = sChrRacesStore.LookupEntry(praceid);
  2794. + ChrClassesEntry const* pclass = sChrClassesStore.LookupEntry(pclassid);
  2795. +
  2796. + if (atoi(plevel.c_str()) < sWorld.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL))
  2797. + plevel += " (" + pxp + "/" + pmaxxp + ")";
  2798. + unsigned int gold = money / 10000;
  2799. + unsigned int silv = (money % 10000) / 100;
  2800. + unsigned int cop = (money % 10000) % 100;
  2801. + char tempgold [100];
  2802. + sprintf(tempgold, "\x2\x3\x30\x37%ug \x3\x31\x34%us \x3\x30\x35%uc\xF", gold, silv, cop);
  2803. + if (ponline == "\x3\x30\x33Online")
  2804. + {
  2805. + Player * plr = ObjectAccessor::Instance().FindPlayerByName(pname.c_str());
  2806. + if (plr)
  2807. + {
  2808. + AreaTableEntry const* area = GetAreaEntryByAreaID(plr->GetAreaId());
  2809. + ponline += " in " + (std::string) area->area_name[sWorld.GetDefaultDbcLocale()];
  2810. + if (area->zone != 0)
  2811. + {
  2812. + AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone);
  2813. + ponline += " (" + (std::string)zone->area_name[sWorld.GetDefaultDbcLocale()] + ")";
  2814. + }
  2815. + }
  2816. + }
  2817. + 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;
  2818. + std::string pinfo2 = "\x2 Level:\x2\x3\x31\x30 " + plevel + "\xF |\x2 Money:\x2 " + tempgold + "\xF |\x2 Guild Info:\x2\x3\x31\x30 "+guildinfo+"\xF |\x2 Status:\x2 " + ponline;
  2819. + // pinfo3 = " :" + " \x2Honor Kills:\x2\x3\x31\x30 " + hk;
  2820. + Send_IRCA(ChanOrPM(CD),pinfo , true, CD->TYPE);
  2821. + Send_IRCA(ChanOrPM(CD),pinfo2 , true, CD->TYPE);
  2822. + // Send_IRCA(ChanOrPM(CD),pinfo3 , true, CD->TYPE);
  2823. + }
  2824. + else
  2825. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown Character ID. (GUID)" ,true, "ERROR");
  2826. + }
  2827. + else
  2828. + {
  2829. + QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, name FROM characters WHERE name LIKE '%%%s%%' LIMIT 10", _PARAMS[1].c_str());
  2830. + if (result)
  2831. + {
  2832. + Field *fields = result->Fetch();
  2833. + std::string items = "\x2 Character Search Results:\x3\x31\x30 ";
  2834. + for (uint64 i=0; i < result->GetRowCount(); i++)
  2835. + {
  2836. + std::string guid = fields[0].GetCppString();
  2837. + std::string account = fields[1].GetCppString();
  2838. + std::string name = fields[2].GetCppString();
  2839. + MakeUpper(name);
  2840. + items.append(name+"(Account:"+account+" - GUID:"+guid+")\xF | \x3\x31\x30\x2");
  2841. + result->NextRow();
  2842. + }
  2843. + delete result;
  2844. + Send_IRCA(ChanOrPM(CD), items, true, CD->TYPE);
  2845. + }
  2846. + else
  2847. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown Character. I Cant Find Any Characters With Those Search Terms." ,true, "ERROR");
  2848. + }
  2849. + }
  2850. + if (_PARAMS[0] == "creature")
  2851. + {
  2852. + std::string creature = _PARAMS[1];
  2853. + if (atoi(creature.c_str()) > 0)
  2854. + {
  2855. + WorldDatabase.escape_string(_PARAMS[1]);
  2856. + QueryResult *result = WorldDatabase.PQuery("SELECT entry, modelid_A, name, (minlevel*maxlevel/2) as level, faction_A, armor, (SELECT count(*) FROM creature WHERE id = '%s') as spawns FROM creature_template WHERE entry = '%s';", _PARAMS[1].c_str(), _PARAMS[1].c_str());
  2857. + if (result)
  2858. + {
  2859. + Field *fields = result->Fetch();
  2860. +
  2861. + uint32 entry = fields[0].GetUInt32();
  2862. + uint32 modelid = fields[1].GetUInt32();
  2863. + std::string name = fields[2].GetCppString();
  2864. + uint32 level = fields[3].GetUInt32();
  2865. + uint32 faction = fields[4].GetUInt32();
  2866. + uint32 armor = fields[5].GetUInt32();
  2867. + uint32 spawns = fields[6].GetUInt32();
  2868. + delete result;
  2869. +
  2870. + Send_IRCA(ChanOrPM(CD), MakeMsg("\x2Name:\x3\x31\x30 %s \xF|\x2 CreatureID:\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);
  2871. + Send_IRCA(ChanOrPM(CD), MakeMsg("\x2Level:\x3\x31\x30 %d \xF|\x2 Faction:\x3\x31\x30 %d \xF|\x2 Armor:\x3\x31\x30 %d", level, faction, armor), true, CD->TYPE);
  2872. + }
  2873. + else
  2874. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown Creature ID." ,true, "ERROR");
  2875. + }
  2876. + else
  2877. + {
  2878. + QueryResult *result = WorldDatabase.PQuery("SELECT entry, name FROM creature_template WHERE name LIKE '%%%s%%' LIMIT 10", _PARAMS[1].c_str());
  2879. + if (result)
  2880. + {
  2881. + Field *fields = result->Fetch();
  2882. + std::string items = "\002Creature Search Results:\x3\x31\x30 ";
  2883. + //Send_IRCA(ChanOrPM(CD), "", true, CD->TYPE);
  2884. + for (uint64 i=0; i < result->GetRowCount(); i++)
  2885. + {
  2886. + std::string CreatureID = fields[0].GetCppString();
  2887. + std::string Name = fields[1].GetCppString();
  2888. + items.append(Name+"("+CreatureID+")\xF | \x3\x31\x30\x2");
  2889. + result->NextRow();
  2890. + }
  2891. + delete result;
  2892. + Send_IRCA(ChanOrPM(CD), items, true, CD->TYPE);
  2893. + }
  2894. + else
  2895. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown Creature. I Cant Find Any Creatures With Those Search Terms." ,true, "ERROR");
  2896. + }
  2897. + }
  2898. + if (_PARAMS[0] == "faction")
  2899. + {
  2900. + std::string faction = _PARAMS[1];
  2901. + if (atoi(faction.c_str()) > 0)
  2902. + {
  2903. + FactionEntry const *factionEntry = sFactionStore.LookupEntry(atoi(faction.c_str()));
  2904. + if (factionEntry)
  2905. + {
  2906. + std::string name = factionEntry->name[sWorld.GetDefaultDbcLocale()];
  2907. + 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);
  2908. + }
  2909. + else
  2910. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown FactionID." ,true, "ERROR");
  2911. +
  2912. + }
  2913. + else
  2914. + {
  2915. + uint32 counter = 0;
  2916. + std::string factions = "\002Faction Search Results:\x3\x31\x30 ";
  2917. + for (uint32 id = 0; id < sFactionStore.GetNumRows(); id++)
  2918. + {
  2919. + FactionEntry const *factionEntry = sFactionStore.LookupEntry(id);
  2920. + if (factionEntry)
  2921. + {
  2922. + MakeLower( _PARAMS[1] );
  2923. + std::string name = factionEntry->name[sWorld.GetDefaultDbcLocale()];
  2924. + MakeLower( name );
  2925. + if (name.find(_PARAMS[1]) != std::string::npos && counter < 10)
  2926. + {
  2927. + char factionid[100];
  2928. + sprintf(factionid, "%d", id);
  2929. + factions.append(name+"("+factionid+")\xF | \x3\x31\x30\x2");
  2930. + ++counter;
  2931. + }
  2932. + }
  2933. + }
  2934. + if (counter == 0)
  2935. + factions.append("No Factions Found.");
  2936. + Send_IRCA(ChanOrPM(CD), factions, true, CD->TYPE);
  2937. + }
  2938. + }
  2939. + if (_PARAMS[0] == "go")
  2940. + {
  2941. + std::string gobject = _PARAMS[1];
  2942. + if (atoi(gobject.c_str()) > 0)
  2943. + {
  2944. + WorldDatabase.escape_string(_PARAMS[1]);
  2945. + 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());
  2946. + if (result)
  2947. + {
  2948. + Field *fields = result->Fetch();
  2949. +
  2950. + uint32 entry = fields[0].GetUInt32();
  2951. + uint32 type = fields[1].GetUInt32();
  2952. + uint32 modelid = fields[2].GetUInt32();
  2953. + std::string name = fields[3].GetCppString();
  2954. + uint32 faction = fields[4].GetUInt32();
  2955. + uint32 spawns = fields[5].GetUInt32();
  2956. + delete result;
  2957. +
  2958. + 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);
  2959. + Send_IRCA(ChanOrPM(CD), MakeMsg("\x2Type:\x3\x31\x30 %d \xF|\x2 Faction:\x3\x31\x30 %d", type, faction), true, CD->TYPE);
  2960. + }
  2961. + else
  2962. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown Creature ID." ,true, "ERROR");
  2963. + }
  2964. + else
  2965. + {
  2966. + QueryResult *result = WorldDatabase.PQuery("SELECT entry, name FROM gameobject_template WHERE name LIKE '%%%s%%' LIMIT 10", _PARAMS[1].c_str());
  2967. + if (result)
  2968. + {
  2969. + Field *fields = result->Fetch();
  2970. + std::string gos = "\002Gameobject Search Results:\x3\x31\x30 ";
  2971. + for (uint64 i=0; i < result->GetRowCount(); i++)
  2972. + {
  2973. + std::string GOID = fields[0].GetCppString();
  2974. + std::string GoName = fields[1].GetCppString();
  2975. + gos.append(GoName+"("+GOID+")\xF | \x3\x31\x30\x2");
  2976. + result->NextRow();
  2977. + }
  2978. + delete result;
  2979. + Send_IRCA(ChanOrPM(CD), gos, true, CD->TYPE);
  2980. + }
  2981. + else
  2982. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown Game Object. I Cant Find Any Game Object's With Those Search Terms." ,true, "ERROR");
  2983. + }
  2984. + }
  2985. + if (_PARAMS[0] == "item")
  2986. + {
  2987. + std::string item = _PARAMS[1];
  2988. + if (atoi(item.c_str()) > 0)
  2989. + {
  2990. + 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());
  2991. + if (result)
  2992. + {
  2993. + Field *fields = result->Fetch();
  2994. + QueryResult *result2 = CharacterDatabase.PQuery("SELECT count(*) FROM `character_inventory` WHERE item_template = %s", _PARAMS[1].c_str());
  2995. + Field *fields2 = result2->Fetch();
  2996. + uint32 charcnt = fields2[0].GetUInt32();
  2997. + delete result2;
  2998. +
  2999. + uint32 ItemID = fields[0].GetUInt32();
  3000. + std::string ItmName = fields[1].GetCppString();
  3001. + uint32 DisplayID = fields[2].GetUInt32();
  3002. + uint32 loots = 0;
  3003. + loots = fields[3].GetUInt32();
  3004. + delete result;
  3005. + 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);
  3006. + }
  3007. + else
  3008. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown ItemID." ,true, "ERROR");
  3009. + }
  3010. + else
  3011. + {
  3012. + QueryResult *result = WorldDatabase.PQuery("SELECT entry, name FROM `item_template` WHERE name LIKE '%%%s%%' LIMIT 10", _PARAMS[1].c_str());
  3013. + if (result)
  3014. + {
  3015. + Field *fields = result->Fetch();
  3016. + std::string items = "\002Item Search Results:\x3\x31\x30 ";
  3017. + for (uint64 i=0; i < result->GetRowCount(); i++)
  3018. + {
  3019. + std::string ItemID = fields[0].GetCppString();
  3020. + std::string ItemName = fields[1].GetCppString();
  3021. + items.append(ItemName+"("+ItemID+")\xF | \x3\x31\x30\x2");
  3022. + result->NextRow();
  3023. + }
  3024. + delete result;
  3025. + Send_IRCA(ChanOrPM(CD), items, true, CD->TYPE);
  3026. + }
  3027. + else
  3028. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown Item. I Cant Find Any Items With Those Search Terms." ,true, "ERROR");
  3029. + }
  3030. + }
  3031. + if (_PARAMS[0] == "quest")
  3032. + {
  3033. + std::string quest = _PARAMS[1];
  3034. + if (atoi(quest.c_str()) > 0)
  3035. + {
  3036. + WorldDatabase.escape_string(_PARAMS[1]);
  3037. + QueryResult *result = WorldDatabase.PQuery("SELECT entry, Title FROM quest_template WHERE entry = '%s';", _PARAMS[1].c_str(), _PARAMS[1].c_str());
  3038. + if (result)
  3039. + {
  3040. + QueryResult *result2 = CharacterDatabase.PQuery("SELECT count(*) FROM character_queststatus WHERE quest = '%s' AND status = '1';", _PARAMS[1].c_str());
  3041. + Field *fields2 = result2->Fetch();
  3042. + uint32 status = fields2[0].GetUInt32();
  3043. + delete result2;
  3044. +
  3045. + Field *fields = result->Fetch();
  3046. + uint32 entry = fields[0].GetUInt32();
  3047. + std::string name = fields[1].GetCppString();
  3048. + delete result;
  3049. + 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);
  3050. + }
  3051. + else
  3052. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown Quest ID." ,true, "ERROR");
  3053. + }
  3054. + else
  3055. + {
  3056. + QueryResult *result = WorldDatabase.PQuery("SELECT entry, Title FROM quest_template WHERE Title LIKE '%%%s%%' LIMIT 10", _PARAMS[1].c_str());
  3057. + if (result)
  3058. + {
  3059. + Field *fields = result->Fetch();
  3060. + std::string quests = "\002Quest Search Results:\x3\x31\x30 ";
  3061. + //Send_IRCA(ChanOrPM(CD), "", true, CD->TYPE);
  3062. + for (uint64 i=0; i < result->GetRowCount(); i++)
  3063. + {
  3064. + std::string QuestID = fields[0].GetCppString();
  3065. + std::string QuestName = fields[1].GetCppString();
  3066. + quests.append(QuestName+"("+QuestID+")\xF | \x3\x31\x30\x2");
  3067. + result->NextRow();
  3068. + }
  3069. + delete result;
  3070. + Send_IRCA(ChanOrPM(CD), quests, true, CD->TYPE);
  3071. + }
  3072. + else
  3073. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown Quest. I Cant Find Any Quest's With Those Search Terms." ,true, "ERROR");
  3074. + }
  3075. + }
  3076. + if (_PARAMS[0] == "skill")
  3077. + {
  3078. + std::string skill = _PARAMS[1];
  3079. + if (atoi(skill.c_str()) > 0)
  3080. + {
  3081. + SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(atoi(skill.c_str()));
  3082. + if (skillInfo)
  3083. + {
  3084. + std::string name = skillInfo->name[sWorld.GetDefaultDbcLocale()];
  3085. + 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);
  3086. + }
  3087. + else
  3088. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown SkillID." ,true, "ERROR");
  3089. +
  3090. + }
  3091. + else
  3092. + {
  3093. + uint32 counter = 0;
  3094. + std::string skills = "\002Skill Search Results:\x3\x31\x30 ";
  3095. + for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
  3096. + {
  3097. + SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id);
  3098. + if (skillInfo)
  3099. + {
  3100. + MakeLower( _PARAMS[1] );
  3101. + std::string name = skillInfo->name[sWorld.GetDefaultDbcLocale()];
  3102. + MakeLower( name );
  3103. + if (name.find(_PARAMS[1]) != std::string::npos && counter < 10)
  3104. + {
  3105. + char skillid[100];
  3106. + sprintf(skillid, "%d", id);
  3107. + skills.append(name+"("+skillid+")\xF | \x3\x31\x30\x2");
  3108. + ++counter;
  3109. + }
  3110. + }
  3111. + }
  3112. + if (counter == 0)
  3113. + skills.append("No Skills Found.");
  3114. + Send_IRCA(ChanOrPM(CD), skills, true, CD->TYPE);
  3115. + }
  3116. + }
  3117. + if (_PARAMS[0] == "spell")
  3118. + {
  3119. + std::string spell = _PARAMS[1];
  3120. + if (atoi(spell.c_str()) > 0)
  3121. + {
  3122. + SpellEntry const *spellInfo = sSpellStore.LookupEntry(atoi(spell.c_str()));
  3123. + if (spellInfo)
  3124. + {
  3125. + std::string name = spellInfo->SpellName[sWorld.GetDefaultDbcLocale()];
  3126. + 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);
  3127. + }
  3128. + else
  3129. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown SpellID." ,true, "ERROR");
  3130. +
  3131. + }
  3132. + else
  3133. + {
  3134. + uint32 counter = 0;
  3135. + std::string spells = "\002Spell Search Results:\x3\x31\x30 ";
  3136. + for (uint32 id = 0; id < sSpellStore.GetNumRows(); id++)
  3137. + {
  3138. + SpellEntry const *spellInfo = sSpellStore.LookupEntry(id);
  3139. + if (spellInfo)
  3140. + {
  3141. + MakeLower( _PARAMS[1] );
  3142. + std::string name = spellInfo->SpellName[sWorld.GetDefaultDbcLocale()];
  3143. + MakeLower( name );
  3144. + if (name.find(_PARAMS[1]) != std::string::npos && counter < 10)
  3145. + {
  3146. + char itemid[100];
  3147. + sprintf(itemid, "%d", id);
  3148. + spells.append(name+"("+itemid+")\xF | \x3\x31\x30\x2");
  3149. + ++counter;
  3150. + }
  3151. + }
  3152. + }
  3153. + if (counter == 0)
  3154. + spells.append("No Spells Found.");
  3155. + Send_IRCA(ChanOrPM(CD), spells, true, CD->TYPE);
  3156. + }
  3157. + }
  3158. + if (_PARAMS[0] == "tele")
  3159. + {
  3160. + std::string tele = _PARAMS[1];
  3161. + if (atoi(tele.c_str()) > 0)
  3162. + {
  3163. + QueryResult *result = WorldDatabase.PQuery("SELECT * FROM `game_tele` WHERE id = %s", _PARAMS[1].c_str());
  3164. + if (result)
  3165. + {
  3166. + Field *fields = result->Fetch();
  3167. +
  3168. + uint32 teleid = fields[0].GetUInt32();
  3169. + uint32 pos_x = fields[1].GetUInt32();
  3170. + uint32 pos_y = fields[2].GetUInt32();
  3171. + uint32 pos_z = fields[3].GetUInt32();
  3172. + uint32 oriet = fields[4].GetUInt32();
  3173. + uint32 map = fields[5].GetUInt32();
  3174. + std::string telname = fields[6].GetCppString();
  3175. + delete result;
  3176. +
  3177. + 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);
  3178. + }
  3179. + else
  3180. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown Teleport Location ID." ,true, "ERROR");
  3181. + }
  3182. + else
  3183. + {
  3184. + QueryResult *result = WorldDatabase.PQuery("SELECT id, name FROM `game_tele` WHERE name LIKE '%%%s%%' LIMIT 10", _PARAMS[1].c_str());
  3185. + if (result)
  3186. + {
  3187. + Field *fields = result->Fetch();
  3188. + std::string teles = "\002Tele Location Search Results:\x3\x31\x30 ";
  3189. + for (uint64 i=0; i < result->GetRowCount(); i++)
  3190. + {
  3191. + std::string TeleID = fields[0].GetCppString();
  3192. + std::string TeleName = fields[1].GetCppString();
  3193. + teles.append(TeleName+"("+TeleID+")\xF | \x3\x31\x30\x2");
  3194. + result->NextRow();
  3195. + }
  3196. + Send_IRCA(ChanOrPM(CD), teles, true, CD->TYPE);
  3197. + delete result;
  3198. + }
  3199. + else
  3200. + Send_IRCA(CD->USER, "\0034[ERROR] : Unknown Item. I Cant Find Any Items With Those Search Terms." ,true, "ERROR");
  3201. + }
  3202. + }
  3203. +}
  3204. +
  3205. +void IRCCmd::Sysmsg_Server(_CDATA *CD)
  3206. +{
  3207. + std::string* _PARAMS = getArray(CD->PARAMS, CD->PCOUNT);
  3208. + std::string ircchan = "#";
  3209. + ircchan += sIRC._irc_chan[sIRC.anchn].c_str();
  3210. + if(_PARAMS[0] == "a")
  3211. + {
  3212. + std::string str = _PARAMS[1];
  3213. + std::string ancmsg = MakeMsg("\00304,08\037/!\\\037\017\00304 Server Announcement \00304,08\037/!\\\037\017 %s",_PARAMS[1].c_str());
  3214. + sWorld.SendWorldText(LANG_SYSTEMMESSAGE,str.c_str());
  3215. + sIRC.Send_IRC_Channel(ircchan, ancmsg, true);
  3216. + }
  3217. + else if (_PARAMS[0] == "e")
  3218. + {
  3219. + std::string str = _PARAMS[1];
  3220. + std::string notstr = "[Server Event]: " + _PARAMS[1];
  3221. + std::string notmsg = MakeMsg("\00304,08\037/!\\\037\017\00304 Game Event \00304,08\037/!\\\037\017 %s",_PARAMS[1].c_str());
  3222. + sWorld.SendWorldText(LANG_EVENTMESSAGE,str.c_str());
  3223. + sIRC.Send_IRC_Channel(ircchan, notmsg, true);
  3224. + }
  3225. + else if (_PARAMS[0] == "n")
  3226. + {
  3227. + std::string str = "Global notify: " + _PARAMS[1];
  3228. + std::string notmsg = MakeMsg("\00304,08\037/!\\\037\017\00304 Global Notify \00304,08\037/!\\\037\017 %s",_PARAMS[1].c_str());
  3229. + WorldPacket data(SMSG_NOTIFICATION, (str.size()+1));
  3230. + data << str;
  3231. + sWorld.SendGlobalMessage(&data);
  3232. + sIRC.Send_IRC_Channel(ircchan, notmsg, true);
  3233. + }
  3234. + /* NOT WORKING!!
  3235. + else if (_PARAMS[0] == "add")
  3236. + {
  3237. + WorldDatabase.PExecute( "INSERT INTO IRC_AutoAnnounce (message, addedby) VALUES ('%s', '%s')", _PARAMS[1].c_str(), CD->USER.c_str());
  3238. + std::string str = _PARAMS[1];
  3239. + std::string ancmsg = MakeMsg("\00304,08\037/!\\\037\017\00304 Server Information \00304,08\037/!\\\037\017 %s",_PARAMS[1].c_str());
  3240. + sWorld.SendWorldText(3000,str.c_str());
  3241. + sIRC.Send_IRC_Channel(ircchan, ancmsg, true);
  3242. + }
  3243. + else if (_PARAMS[0] == "del")
  3244. + {
  3245. + WorldDatabase.PExecute( "DELETE FROM IRC_AutoAnnounce WHERE id = %s", _PARAMS[1].c_str());
  3246. + Send_IRCA(ChanOrPM(CD), MakeMsg("Deleted Automatic Announcement Message ID: %s", _PARAMS[1].c_str()), true, CD->TYPE);
  3247. + }
  3248. + else if (_PARAMS[0] == "list")
  3249. + {
  3250. + QueryResult *result = WorldDatabase.PQuery("SELECT * FROM IRC_AutoAnnounce LIMIT 5;", _PARAMS[1].c_str());
  3251. + if(result)
  3252. + {
  3253. + Field *fields = result->Fetch();
  3254. + for (uint64 i=0; i < result->GetRowCount(); i++)
  3255. + {
  3256. + std::string id = fields[0].GetCppString();
  3257. + std::string message = fields[1].GetCppString();
  3258. + std::string addedby = fields[2].GetCppString();
  3259. + Send_IRCA(ChanOrPM(CD), MakeMsg("ID: %s - Added By: %s - Message: %s", id.c_str(), addedby.c_str(), message.c_str()), true, CD->TYPE);
  3260. + result->NextRow();
  3261. + }
  3262. + delete result;
  3263. + }
  3264. + else
  3265. + Send_IRCA(CD->USER, "\0034[ERROR] : No Auto Announce Messages Are In The Database.", true, "ERROR");
  3266. + }*/
  3267. + else
  3268. + Send_IRCA(CD->USER, "\0034[ERROR] : Please Use (a-Announce)(n-Notify)(e-Event) As Second Parameter!", true, "ERROR");
  3269. +}
  3270. +
  3271. +void IRCCmd::Level_Player(_CDATA *CD)
  3272. +{
  3273. + std::string* _PARAMS = getArray(CD->PARAMS, CD->PCOUNT);
  3274. + if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512))
  3275. + {
  3276. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : Nice Try, This Player Has A Higher GM Level Than You! [ %i ]", AcctLevel(_PARAMS[0])), true, "ERROR");
  3277. + return;
  3278. + }
  3279. + std::string player = _PARAMS[0];
  3280. + normalizePlayerName(player);
  3281. + ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(player.c_str());
  3282. + std::string s_newlevel = _PARAMS[1];
  3283. + uint8 i_newlvl = atoi(s_newlevel.c_str());
  3284. + if (guid.IsEmpty())
  3285. + {
  3286. + Send_IRCA(CD->USER, "\0034[ERROR] : Player Not Found!", true, "ERROR");
  3287. + return;
  3288. + } else if ( i_newlvl < 1 || i_newlvl > sWorld.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL) )
  3289. + {
  3290. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : Level Must Be Between 1 And %i!",sConfig.GetIntDefault("MaxPlayerLevel", 70)), true, "ERROR");
  3291. + return;
  3292. + } else
  3293. + {
  3294. + Player *chr = sObjectMgr.GetPlayer(guid);
  3295. + int32 i_oldlvl = chr ? chr->getLevel() : Player::GetLevelFromDB(guid);
  3296. + if (chr)
  3297. + {
  3298. + chr->GiveLevel(i_newlvl);
  3299. + chr->InitTalentForLevel();
  3300. + chr->SetUInt32Value(PLAYER_XP,0);
  3301. + WorldPacket data;
  3302. + ChatHandler CH(chr->GetSession());
  3303. + if (i_oldlvl == i_newlvl)
  3304. + CH.FillSystemMessageData(&data, "Your level progress has been reset.");
  3305. + else
  3306. + if (i_oldlvl < i_newlvl)
  3307. + {
  3308. + char temp [32];
  3309. + sprintf(temp, "You have been leveled up (%i)",i_newlvl-i_oldlvl);
  3310. + CH.FillSystemMessageData(&data, temp);
  3311. + }
  3312. + else
  3313. + if (i_oldlvl > i_newlvl)
  3314. + {
  3315. + char temp [34];
  3316. + sprintf(temp, "You have been leveled down (%i)",i_newlvl-i_oldlvl);
  3317. + CH.FillSystemMessageData(&data, temp);
  3318. + }
  3319. + chr->GetSession()->SendPacket( &data );
  3320. + }
  3321. + else
  3322. + {
  3323. + std::ostringstream ss;
  3324. + ss << "UPDATE characters SET level='"<<uint32(i_newlvl)<<"',xp='0' WHERE guid='"<</*GUID_LOPART(guid)*/ chr->GetGUIDLow() <<"'";
  3325. + sLog.outDebug("%s", ss.str().c_str());
  3326. + CharacterDatabase.Execute(ss.str().c_str());
  3327. + }
  3328. + }
  3329. + Send_IRCA(ChanOrPM(CD), "\00313[" + _PARAMS[0]+ "] : Has Been Leveled To " + _PARAMS[1] + ". By: "+CD->USER+".", true, CD->TYPE);
  3330. +}
  3331. +
  3332. +void IRCCmd::Money_Player(_CDATA *CD)
  3333. +{
  3334. + std::string* _PARAMS = getArray(CD->PARAMS, 2);
  3335. + if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512))
  3336. + {
  3337. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : Nice Try, This Player Has A Higher GM Level Than You! [ %i ]", AcctLevel(_PARAMS[0])), true, "ERROR");
  3338. + return;
  3339. + }
  3340. + std::string player = _PARAMS[0];
  3341. + normalizePlayerName(player);
  3342. + ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(player.c_str());
  3343. + Player *chr = sObjectMgr.GetPlayer(guid);
  3344. +
  3345. + std::string s_money = _PARAMS[1];
  3346. + int32 money = atoi(s_money.c_str());
  3347. + unsigned int gold = money / 10000;
  3348. + unsigned int silv = (money % 10000) / 100;
  3349. + unsigned int cop = (money % 10000) % 100;
  3350. + char tempgold [100];
  3351. + sprintf(tempgold, "\x2\x3\x30\x37%ug \x3\x31\x34%us \x3\x30\x35%uc\xF", gold, silv, cop);
  3352. + if (guid.IsEmpty())
  3353. + {
  3354. + Send_IRCA(CD->USER, "\0034[ERROR] : Player Not Found!", true, "ERROR");
  3355. + return;
  3356. + }
  3357. + else
  3358. + {
  3359. + Player *chr = sObjectMgr.GetPlayer(guid);
  3360. + uint32 moneyuser = 0;
  3361. + if (chr)
  3362. + moneyuser = chr->GetMoney();
  3363. + else {
  3364. + CharacterDatabase.escape_string(player);
  3365. + std::string sqlquery = "SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(data, ' ' , 1462), ' ' , -1) AS `gold` FROM `characters` WHERE `name` = '"+player+"';";
  3366. + QueryResult *result = CharacterDatabase.Query(sqlquery.c_str());
  3367. + Field *fields = result->Fetch();
  3368. + moneyuser = fields[0].GetInt32();
  3369. + delete result;
  3370. + }
  3371. + int32 addmoney = money;
  3372. + int32 newmoney = moneyuser + addmoney;
  3373. + char s_newmoney[255];
  3374. + sprintf(s_newmoney,"%d",newmoney);
  3375. + if (addmoney < 0)
  3376. + {
  3377. + sLog.outDetail("USER1: %i, ADD: %i, DIF: %i\\n", moneyuser, addmoney, newmoney);
  3378. + if (newmoney <= 0 )
  3379. + {
  3380. + Send_IRCA(ChanOrPM(CD), "\00313["+player+"] : Has Had All Money Taken By: "+CD->USER.c_str()+".", true, CD->TYPE);
  3381. + if (chr)
  3382. + {
  3383. + chr->SetMoney(0);
  3384. + Send_Player(chr, MakeMsg("You Have Been Liquidated By: %s. Total Money Is Now 0.", CD->USER.c_str()));
  3385. + }
  3386. + else
  3387. + CharacterDatabase.PExecute("UPDATE `characters` SET data=concat(substring_index(data,' ',1462-1),' ','%u',' ', right(data,length(data)-length(substring_index(data,' ',1462))-1) ) where guid='%u'",newmoney, guid.GetCounter() );
  3388. + }
  3389. + else
  3390. + {
  3391. + Send_IRCA(ChanOrPM(CD), "\00313["+player+"] : Has Had ("+s_money+"\00313) Taken From Them By: "+CD->USER.c_str()+".", true, CD->TYPE);
  3392. + if (chr)
  3393. + {
  3394. + chr->SetMoney( newmoney );
  3395. + Send_Player(chr, MakeMsg("You Have Had %s Copper Taken From You By: %s.", _PARAMS[1].c_str(), CD->USER.c_str()));
  3396. + }
  3397. + else
  3398. + CharacterDatabase.PExecute("UPDATE `characters` SET data=concat(substring_index(data,' ',1462-1),' ','%u',' ', right(data,length(data)-length(substring_index(data,' ',1462))-1) ) where guid='%u'",newmoney, guid.GetCounter() );
  3399. + }
  3400. + }
  3401. + else
  3402. + {
  3403. + Send_IRCA(ChanOrPM(CD), "\00313["+player+"] : Has Been Given ("+tempgold+"\00313) From: "+CD->USER.c_str()+".", true, CD->TYPE);
  3404. + if (chr)
  3405. + {
  3406. + chr->ModifyMoney( addmoney );
  3407. + Send_Player(chr, MakeMsg("You Have Been Given %s Copper. From: %s.", _PARAMS[1].c_str(), CD->USER.c_str()));
  3408. + }
  3409. + else
  3410. + CharacterDatabase.PExecute("UPDATE `characters` SET data=concat(substring_index(data,' ',1462-1),' ','%u',' ', right(data,length(data)-length(substring_index(data,' ',1462))-1) ) where guid='%u'",newmoney, guid.GetCounter() );
  3411. + }
  3412. + }
  3413. +}
  3414. +
  3415. +void IRCCmd::Mute_Player(_CDATA *CD)
  3416. +{
  3417. + std::string* _PARAMS = getArray(CD->PARAMS, 3);
  3418. + if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512))
  3419. + {
  3420. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : Nice Try, This Player Has A Higher GM Level Than You! [ %i ]", AcctLevel(_PARAMS[0])), true, "ERROR");
  3421. + return;
  3422. + }
  3423. + normalizePlayerName(_PARAMS[0]);
  3424. + ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(_PARAMS[0]);
  3425. + if (!guid.IsEmpty())
  3426. + {
  3427. + if (_PARAMS[1] == "release")
  3428. + {
  3429. + Player* plr = sObjectMgr.GetPlayer(guid);
  3430. + uint32 account_id = 0;
  3431. + account_id = sObjectMgr.GetPlayerAccountIdByGUID(guid);
  3432. + LoginDatabase.PExecute("UPDATE `account` SET `mutetime` = '0' WHERE `id` = '%u'", account_id );
  3433. + Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Been UnMuted By: "+CD->USER+"." , true, CD->TYPE);
  3434. + if (plr)
  3435. + {
  3436. + plr->GetSession()->m_muteTime = 0;
  3437. + Send_Player(plr, MakeMsg("You Have Been UnMuted By: %s.", CD->USER.c_str()));
  3438. + }
  3439. + }
  3440. + else
  3441. + {
  3442. + if (_PARAMS[2] == "")
  3443. + _PARAMS[2] = "No Reason Given";
  3444. + Player* plr = sObjectMgr.GetPlayer(guid);
  3445. + time_t mutetime = time(NULL) + atoi(_PARAMS[1].c_str())*60;
  3446. + uint32 account_id = 0;
  3447. + account_id = sObjectMgr.GetPlayerAccountIdByGUID(guid);
  3448. + if (plr) plr->GetSession()->m_muteTime = mutetime;
  3449. + LoginDatabase.PExecute("UPDATE `account` SET `mutetime` = " UI64FMTD " WHERE `id` = '%u'",uint64(mutetime), account_id );
  3450. + Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Been Muted By: "+CD->USER+". For: "+_PARAMS[1]+" Minutes. Reason: "+_PARAMS[2] , true, CD->TYPE);
  3451. + 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()));
  3452. + }
  3453. + }
  3454. + else
  3455. + Send_IRCA(CD->USER, "\0034[ERROR] : Player Does Not Exist!", true, "ERROR");
  3456. +}
  3457. +
  3458. +void IRCCmd::Online_Players(_CDATA *CD)
  3459. +{
  3460. + sIRC.Script_Lock[MCS_Players_Online] = true;
  3461. + ACE_Based::Thread script(new mcs_OnlinePlayers(CD));
  3462. +}
  3463. +
  3464. +void IRCCmd::PM_Player(_CDATA *CD)
  3465. +{
  3466. + std::string* _PARAMS = getArray(CD->PARAMS, 2);
  3467. + if (Player* plr = GetPlayer(_PARAMS[0]))
  3468. + {
  3469. + if (plr->isAcceptWhispers())
  3470. + {
  3471. + std::string sMsg = MakeMsg("|cffFE87FD[<IRC>%s] Whispers: %s|r", CD->USER.c_str(), _PARAMS[1].c_str());
  3472. + Send_Player(plr, sMsg);
  3473. + plr->PlayDistanceSound(3081);
  3474. + Send_IRCA(ChanOrPM(CD), "\00313To ["+_PARAMS[0]+"] : "+_PARAMS[1]+".", true, CD->TYPE);
  3475. + }
  3476. + else
  3477. + Send_IRCA(CD->USER, "\0034[ERROR] : Is Not Accepting Private Messages!", true, "ERROR");
  3478. + }
  3479. + else
  3480. + Send_IRCA(CD->USER, "\0034[ERROR] : Player not online!", true, "ERROR");
  3481. +}
  3482. +
  3483. +void IRCCmd::Revive_Player(_CDATA *CD)
  3484. +{
  3485. + std::string* _PARAMS = getArray(CD->PARAMS, CD->PCOUNT);
  3486. + if (Player* plr = GetPlayer(_PARAMS[0]))
  3487. + {
  3488. + if (plr->isDead())
  3489. + {
  3490. + plr->ResurrectPlayer(0.5f);
  3491. + plr->SpawnCorpseBones();
  3492. + plr->SaveToDB();
  3493. + sIRC.Send_IRC_Channel(ChanOrPM(CD), " \00313["+_PARAMS[0]+"] : Has Been Revived By: " + CD->USER, true, CD->TYPE);
  3494. + Send_Player(plr, MakeMsg("You Have Been Revived By: %s.", CD->USER.c_str()));
  3495. + }
  3496. + else
  3497. + Send_IRCA(CD->USER, "\0034[ERROR] : "+_PARAMS[0]+" Is Not Dead!", true, "ERROR");
  3498. + }
  3499. + else
  3500. + Send_IRCA(CD->USER, "\0034[ERROR] : "+_PARAMS[0]+" Is Not Online!", true, "ERROR");
  3501. +}
  3502. +
  3503. +void IRCCmd::Saveall_Player(_CDATA *CD)
  3504. +{
  3505. + ObjectAccessor::Instance().SaveAllPlayers();
  3506. + Send_IRCA(ChanOrPM(CD), "\00313["+CD->USER+"] : Has Saved All Players!", true, CD->TYPE);
  3507. +}
  3508. +
  3509. +void IRCCmd::Shutdown_Mangos(_CDATA *CD)
  3510. +{
  3511. + std::string* _PARAMS = getArray(CD->PARAMS, 1);
  3512. + if (_PARAMS[0] == "cancel")
  3513. + {
  3514. + sWorld.ShutdownCancel();
  3515. + Send_IRCA(ChanOrPM(CD), "\0034Server Shutdown Has Been Cancelled.", true, CD->TYPE);
  3516. + }
  3517. +
  3518. + int32 i_time = atoi(_PARAMS[0].c_str());
  3519. + if (i_time <= 0 && _PARAMS[0]!="0")
  3520. + {
  3521. + Send_IRCA(ChanOrPM(CD), "\00313["+CD->USER+"] : Please Enter A Number! And No Negative Numbers! "+_PARAMS[0]+" Seconds!?", true, CD->TYPE);
  3522. + return;
  3523. + }
  3524. + 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);
  3525. + sWorld.ShutdownServ(i_time, 0, 0);
  3526. + Delay(i_time*1000);
  3527. + Send_IRCA(ChanOrPM(CD), "\0034Server Will Now Shut Down.. Good Bye!", true, CD->TYPE);
  3528. + sIRC.Active = false;
  3529. + sIRC.ResetIRC();
  3530. +}
  3531. +
  3532. +void IRCCmd::Spell_Player(_CDATA *CD)
  3533. +{
  3534. + std::string* _PARAMS = getArray(CD->PARAMS, 3);
  3535. + if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512))
  3536. + {
  3537. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : Nice Try, This Player Has A Higher GM Level Than You! [ %i ]", AcctLevel(_PARAMS[0])), true, "ERROR");
  3538. + return;
  3539. + }
  3540. + uint32 spell = atoi(_PARAMS[2].c_str());
  3541. + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell);
  3542. + if (Player* plr = GetPlayer(_PARAMS[0]))
  3543. + {
  3544. + if (spellInfo)
  3545. + {
  3546. + std::string name = spellInfo->SpellName[sWorld.GetDefaultDbcLocale()];
  3547. + if (_PARAMS[1] == "cast")
  3548. + {
  3549. + plr->CastSpell(plr, spell, true);
  3550. + Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Had Spell "+name+" Casted On Them.", true, CD->TYPE);
  3551. + }
  3552. + if (_PARAMS[1] == "learn")
  3553. + {
  3554. + plr->learnSpell(spell,false);
  3555. + Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Learned Spell "+name+".", true, CD->TYPE);
  3556. + }
  3557. + if (_PARAMS[1] == "unlearn")
  3558. + {
  3559. + plr->removeSpell(spell);
  3560. + Send_IRCA(ChanOrPM(CD), "\00313["+_PARAMS[0]+"] : Has Unlearned Spell "+name+".", true, CD->TYPE);
  3561. + }
  3562. + }
  3563. + else
  3564. + Send_IRCA(CD->USER, "\0034[ERROR] : Incorrect Spell ID!", true, "ERROR");
  3565. + }
  3566. + else
  3567. + Send_IRCA(CD->USER, "\0034[ERROR] : Player Not Online!", true, "ERROR");
  3568. +}
  3569. +
  3570. +void IRCCmd::Tele_Player(_CDATA *CD)
  3571. +{
  3572. + std::string* _PARAMS = getArray(CD->PARAMS, 4);
  3573. + if (AcctLevel(_PARAMS[0]) > GetLevel(CD->USER) && (sIRC.BOTMASK & 512))
  3574. + {
  3575. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : Nice Try, This Player Has A Higher GM Level Than You! [ %i ]", AcctLevel(_PARAMS[0])), true, "ERROR");
  3576. + return;
  3577. + }
  3578. + bool DoTeleport = false;
  3579. + float pX, pY, pZ, pO = 0;
  3580. + uint32 mapid = 0;
  3581. + std::string rMsg = " \0034[ERROR] : Teleport Failed!";
  3582. + std::string wMsg = "Invalid Tele Location";
  3583. + Player* plr = GetPlayer(_PARAMS[0]);
  3584. + if (plr)
  3585. + {
  3586. + if (plr->IsTaxiFlying() || plr->isInCombat())
  3587. + {
  3588. + Send_IRCA(CD->USER, MakeMsg("\0034[ERROR] : %s Is Busy And Cannot Be Teleported! They Could Be In Combat, Or Flying.",_PARAMS[0].c_str()), true, "ERROR");
  3589. + return;
  3590. + }
  3591. + }
  3592. + if (_PARAMS[1] == "l" || _PARAMS[1].size() > 2)
  3593. + {
  3594. + if (_PARAMS[1].size() > 1)
  3595. + _PARAMS[2] = _PARAMS[1];
  3596. + WorldDatabase.escape_string(_PARAMS[2]);
  3597. + QueryResult *result = WorldDatabase.PQuery("SELECT position_x, position_y, position_z, orientation, map FROM game_tele WHERE name='%s';", _PARAMS[2].c_str());
  3598. + if (result)
  3599. + {
  3600. + Field *fields = result->Fetch();
  3601. + pX = fields[0].GetFloat();
  3602. + pY = fields[1].GetFloat();
  3603. + pZ = fields[2].GetFloat();
  3604. + pO = fields[3].GetFloat();
  3605. + mapid = fields[4].GetUInt16();
  3606. + delete result;
  3607. + rMsg = MakeMsg(" \00313[%s] : Teleported To %s! By: %s.",
  3608. + _PARAMS[0].c_str(),
  3609. + _PARAMS[2].c_str(),
  3610. + CD->USER.c_str());
  3611. + wMsg = MakeMsg("You Have Been Teleported To %s By: %s.",
  3612. + _PARAMS[2].c_str(),
  3613. + CD->USER.c_str());
  3614. + DoTeleport = true;
  3615. + }
  3616. + else
  3617. + {
  3618. + WorldDatabase.escape_string(_PARAMS[2]);
  3619. + QueryResult *result = WorldDatabase.PQuery("SELECT name FROM game_tele WHERE name LIKE '%%%s%%' LIMIT 7;", _PARAMS[2].c_str());
  3620. + if (result)
  3621. + {
  3622. + std::string telename = "<> ";
  3623. + for (uint64 i=0; i < result->GetRowCount(); i++)
  3624. + {
  3625. + Field *fields = result->Fetch();
  3626. + telename.append(fields[0].GetCppString());
  3627. + result->NextRow();
  3628. + telename.append(" <> ");
  3629. + }
  3630. + delete result;
  3631. + Send_IRCA(CD->USER, "I Cannot Find Location: "+_PARAMS[2]+" . Perhaps One Of These Will Work For You.", true, "ERROR");
  3632. + Send_IRCA(CD->USER, telename, true, "ERROR");
  3633. + return;
  3634. + }
  3635. + else
  3636. + Send_IRCA(CD->USER, "\0034[ERROR] : Location Not Found! Nothing Even Close Found!", true, "ERROR");
  3637. + return;
  3638. + }
  3639. + }
  3640. + else if (_PARAMS[1] == "c")
  3641. + {
  3642. + std::string* _PARAMSA = getArray(_PARAMS[2], 4);
  3643. + pX = atof(_PARAMSA[1].c_str());
  3644. + pY = atof(_PARAMSA[2].c_str());
  3645. + pZ = atof(_PARAMSA[3].c_str());
  3646. + mapid = atoi(_PARAMSA[0].c_str());
  3647. + rMsg = MakeMsg(" \00313[%s] : Teleported To Map: %s. Position: X(%s) Y(%s) Z(%s)! By: %s.",
  3648. + _PARAMS[0].c_str(),
  3649. + _PARAMSA[0].c_str(),
  3650. + _PARAMSA[1].c_str(),
  3651. + _PARAMSA[2].c_str(),
  3652. + _PARAMSA[3].c_str(),
  3653. + CD->USER.c_str());
  3654. + wMsg = MakeMsg("You Have Been Teleported To Map: %s. Position: X(%s) Y(%s) Z(%s)! By: %s.",
  3655. + _PARAMSA[0].c_str(),
  3656. + _PARAMSA[1].c_str(),
  3657. + _PARAMSA[2].c_str(),
  3658. + _PARAMSA[3].c_str(),
  3659. + CD->USER.c_str());
  3660. + DoTeleport = true;
  3661. + }
  3662. + else if (_PARAMS[1] == "r")
  3663. + {
  3664. + if (plr)
  3665. + {
  3666. + pX = plr->m_recallX;
  3667. + pY = plr->m_recallY;
  3668. + pZ = plr->m_recallZ;
  3669. + pO = plr->m_recallO;
  3670. + mapid = plr->m_recallMap;
  3671. + rMsg = MakeMsg(" \00313[%s] : Has Been Recalled To Their Previous Location.",
  3672. + _PARAMS[0].c_str());
  3673. + wMsg = MakeMsg("You Have Been Recalled To Your Previous Location. By: %s",
  3674. + CD->USER.c_str());
  3675. + DoTeleport = true;
  3676. + }
  3677. + else
  3678. + {
  3679. + Send_IRCA(CD->USER, MakeMsg("\00313[%s] : Cannot Be Recalled, They Are Not Online.", _PARAMS[0].c_str()), true, "ERROR");
  3680. + return;
  3681. + }
  3682. +
  3683. + }
  3684. + else if (_PARAMS[1] == "to")
  3685. + {
  3686. + if (!plr)
  3687. + {
  3688. + Send_IRCA(CD->USER, "\0034[ERROR] First Player Not Online! Offline Tele Not Supported For 'to'.", true, "ERROR");
  3689. + return;
  3690. + }
  3691. + Player* plr2 = GetPlayer(_PARAMS[2]);
  3692. + if (plr2)
  3693. + {
  3694. + plr2->GetContactPoint(plr, pX, pY, pZ);
  3695. + mapid = plr2->GetMapId();
  3696. + }
  3697. + else
  3698. + {
  3699. + if (!sObjectMgr.GetPlayerGuidByName(_PARAMS[2].c_str()).IsEmpty())
  3700. + {
  3701. + ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(_PARAMS[2].c_str());
  3702. + bool in_flight;
  3703. + Player::LoadPositionFromDB(guid,mapid, pX, pY, pZ, pO, in_flight);
  3704. + }
  3705. + else
  3706. + {
  3707. + Send_IRCA(CD->USER, "\0034[ERROR] : Second Player Not Found!", true, "ERROR");
  3708. + return;
  3709. + }
  3710. + }
  3711. + rMsg = MakeMsg(" \00313[%s] : Teleported To Player: [%s] By: %s.",
  3712. + _PARAMS[0].c_str(),
  3713. + _PARAMS[2].c_str(),
  3714. + CD->USER.c_str());
  3715. + wMsg = MakeMsg("You Are Being Teleported To: %s. By: %s.",
  3716. + _PARAMS[2].c_str(),
  3717. + CD->USER.c_str());
  3718. + DoTeleport = true;
  3719. + }
  3720. + if (DoTeleport)
  3721. + {
  3722. + if (MapManager::IsValidMapCoord(mapid, pX ,pY))
  3723. + {
  3724. + //NOTE: Removed "BeenToGMI" due to back overflows caused with new packet structure (Shinzon)
  3725. +
  3726. + // if(!sIRC.BeenToGMI(pX, pY, _PARAMS[0], CD->USER))
  3727. + // {
  3728. + // if player is online teleport them in real time, if not set the DB to our coordinates.
  3729. + if (plr)
  3730. + {
  3731. + plr->SaveRecallPosition();
  3732. + plr->TeleportTo(mapid, pX, pY, pZ, pO);
  3733. + sIRC.Send_IRC_Channel(ChanOrPM(CD), rMsg, true, CD->TYPE);
  3734. + Send_Player(plr, wMsg);
  3735. + sIRC.Send_WoW_Channel(sIRC._wow_chan[1].c_str(), IRCCmd::MakeMsg("|cffffff21 %s : Teleported To %s. By: %s.|r", _PARAMS[0].c_str(), _PARAMS[2].c_str(), CD->USER.c_str()));
  3736. + }
  3737. + else
  3738. + {
  3739. + ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(_PARAMS[0]);
  3740. + Player::SavePositionInDB(guid,mapid,pX,pY,pZ,pO,TerrainManager::Instance().GetZoneId(mapid,pX,pY,pZ));
  3741. + sIRC.Send_IRC_Channel(ChanOrPM(CD), rMsg + " \0034*Offline Tele.* ", true, CD->TYPE);
  3742. + }
  3743. + // }
  3744. + }
  3745. + else
  3746. + Send_IRCA(CD->USER, "\0034[ERROR] : Invalid Location!", true, "ERROR");
  3747. + }
  3748. + else
  3749. + Send_IRCA(CD->USER, "\0034[ERROR] : Invalid Paramaters, Please Try Again [ "+sIRC._cmd_prefx+"help tele ] For More Information. ", true, "ERROR");
  3750. +}
  3751. +
  3752. +void IRCCmd::Top_Player(_CDATA *CD)
  3753. +{
  3754. + std::string* _PARAMS = getArray(CD->PARAMS, 2);
  3755. + uint32 limitr = 10;
  3756. + if (atoi(_PARAMS[1].c_str()) > 0 && GetLevel(CD->USER) >= sIRC._op_gm_lev)
  3757. + limitr = atoi(_PARAMS[1].c_str());
  3758. + if (_PARAMS[0] == "accttime")
  3759. + {
  3760. + QueryResult *result = CharacterDatabase.PQuery("SELECT account, name, (SUM(totaltime)) AS combinetime FROM characters GROUP BY account ORDER BY combinetime DESC LIMIT 0, %d ", limitr);
  3761. + if (result)
  3762. + {
  3763. + Field *fields = result->Fetch();
  3764. + std::string tptime = MakeMsg("\x2 Top%d Accounts By Played Time:\x3\x31\x30 ", limitr);
  3765. + for (uint64 i=0; i < result->GetRowCount(); i++)
  3766. + {
  3767. + uint32 account = fields[0].GetUInt32();
  3768. + std::string PlName = GetAcctNameFromID(account);
  3769. + std::string Time = SecToDay(fields[2].GetCppString());
  3770. + uint32 rank = i+1;
  3771. + tptime.append(MakeMsg("[%u]%s %s \xF| \x3\x31\x30\x2", rank, PlName.c_str(), Time.c_str()));
  3772. + result->NextRow();
  3773. + }
  3774. + delete result;
  3775. + Send_IRCA(ChanOrPM(CD), tptime, true, CD->TYPE);
  3776. + }
  3777. + else
  3778. + Send_IRCA(CD->USER, "\0034[ERROR] : No Accounts Returned." ,true, "ERROR");
  3779. + }
  3780. + if (_PARAMS[0] == "chartime")
  3781. + {
  3782. + QueryResult *result = CharacterDatabase.PQuery("SELECT name, totaltime FROM characters ORDER BY totaltime DESC LIMIT 0, %d ", limitr);
  3783. + if (result)
  3784. + {
  3785. + Field *fields = result->Fetch();
  3786. + std::string tptime = MakeMsg("\x2 Top%d Characters By Played Time:\x3\x31\x30 ", limitr);
  3787. + for (uint64 i=0; i < result->GetRowCount(); i++)
  3788. + {
  3789. + std::string Name = fields[0].GetCppString();
  3790. + std::string Time = SecToDay(fields[1].GetCppString());
  3791. + uint32 rank = i+1;
  3792. + tptime.append(MakeMsg("[%u]%s %s \xF| \x3\x31\x30\x2", rank, Name.c_str(), Time.c_str()));
  3793. + result->NextRow();
  3794. + }
  3795. + delete result;
  3796. + Send_IRCA(ChanOrPM(CD), tptime, true, CD->TYPE);
  3797. + }
  3798. + else
  3799. + Send_IRCA(CD->USER, "\0034[ERROR] : No Characters Returned." ,true, "ERROR");
  3800. + }
  3801. + if (_PARAMS[0] == "money")
  3802. + {
  3803. + QueryResult *result = CharacterDatabase.PQuery("SELECT name, CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(data, ' ', 1462), ' ', -1) AS UNSIGNED) AS money FROM characters ORDER BY money DESC LIMIT 0, %d ", limitr);
  3804. + if (result)
  3805. + {
  3806. + Field *fields = result->Fetch();
  3807. + std::string tptime = MakeMsg("\x2 Top%d Characters By Money:\x3\x31\x30 ", limitr);
  3808. + for (uint64 i=0; i < result->GetRowCount(); i++)
  3809. + {
  3810. + std::string Name = fields[0].GetCppString();
  3811. + unsigned int money = fields[1].GetInt32();
  3812. +
  3813. + uint32 rank = i+1;
  3814. +
  3815. + unsigned int gold = money / 10000;
  3816. + unsigned int silv = (money % 10000) / 100;
  3817. + unsigned int cop = (money % 10000) % 100;
  3818. + char tempgold [100];
  3819. + sprintf(tempgold, "\x2\x3\x30\x37%ug \x3\x31\x34%us \x3\x30\x35%uc\xF", gold, silv, cop);
  3820. +
  3821. + tptime.append(MakeMsg("[%u]%s %s \xF| \x3\x31\x30\x2", rank, Name.c_str(), tempgold));
  3822. + result->NextRow();
  3823. + }
  3824. + delete result;
  3825. + Send_IRCA(ChanOrPM(CD), tptime, true, CD->TYPE);
  3826. + }
  3827. + else
  3828. + Send_IRCA(CD->USER, "\0034[ERROR] : No Characters Returned." ,true, "ERROR");
  3829. + }
  3830. +
  3831. +}
  3832. +
  3833. +void IRCCmd::Who_Logged(_CDATA *CD)
  3834. +{
  3835. + std::string OPS = "";
  3836. + for (std::list<_client*>::iterator i=_CLIENTS.begin(); i!=_CLIENTS.end();i++)
  3837. + {
  3838. + OPS.append(MakeMsg(" \002[GM:%d IRC: %s - WoW: %s]\002 ", (*i)->GMLevel, (*i)->Name.c_str(), (*i)->UName.c_str()));
  3839. + }
  3840. + Send_IRCA(ChanOrPM(CD), OPS, true, CD->TYPE);
  3841. +}
  3842. +
  3843. +// GM Ticket by bizkut http://github.com/bizkut
  3844. +void IRCCmd::GM_Ticket(_CDATA *CD)
  3845. +{
  3846. + std::string* _PARAMS = getArray(CD->PARAMS, 3);
  3847. + uint32 limitr = 10;
  3848. + std::string DateTime = "%h:%i%p, %a %d %b %Y";
  3849. + if (atoi(_PARAMS[1].c_str()) > 0 && GetLevel(CD->USER) >= sIRC._op_gm_lev)
  3850. + limitr = atoi(_PARAMS[1].c_str());
  3851. + if (_PARAMS[0] == "list")
  3852. + {
  3853. + QueryResult *result = CharacterDatabase.PQuery("SELECT guid, DATE_FORMAT(ticket_lastchange, '%s') FROM character_ticket ORDER BY ticket_id ASC LIMIT 0, %d", DateTime.c_str(), limitr);
  3854. + if (result)
  3855. + {
  3856. + Field *fields = result->Fetch();
  3857. + std::string tptime = MakeMsg("\x2 First %d Tickets:\x3\x31\x30 ", limitr);
  3858. + for (uint64 i=0; i < result->GetRowCount(); i++)
  3859. + {
  3860. + ObjectGuid guid = ObjectGuid(fields[0].GetUInt64());
  3861. + std::string CharName = GetCharNameFromGUID(guid);
  3862. + std::string lastchange = fields[1].GetCppString();
  3863. + uint32 tindex = i+1;
  3864. + tptime.append(MakeMsg("[%u] %s \xF| \x3\x31\x30\x2", tindex, CharName.c_str()));
  3865. + result->NextRow();
  3866. + }
  3867. + delete result;
  3868. + Send_IRCA(ChanOrPM(CD), tptime, true, CD->TYPE);
  3869. + }
  3870. + else
  3871. + Send_IRCA(CD->USER, "\0034[ERROR] : No Ticket Returned." ,true, "ERROR");
  3872. + }
  3873. + // read ticket
  3874. + if (_PARAMS[0] == "read")
  3875. + {
  3876. + std::string CharName = _PARAMS[1].c_str();
  3877. + ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(CharName);
  3878. + QueryResult *result = CharacterDatabase.PQuery("SELECT guid, ticket_text, DATE_FORMAT(ticket_lastchange, '%s'), response_text FROM character_ticket WHERE guid=%u",DateTime.c_str(), guid.GetCounter());
  3879. + if (result)
  3880. + {
  3881. + Field *fields = result->Fetch();
  3882. + std::string tptime = MakeMsg("\x2 Ticket [%s]\x3\x31\x30 ", CharName.c_str());
  3883. + uint32 guid = fields[0].GetUInt32();
  3884. + std::string ticktext = fields[1].GetCppString();
  3885. + std::string lastchange = fields[2].GetCppString();
  3886. + std::string tresponse = fields[3].GetCppString();
  3887. + if (tresponse == "")
  3888. + tresponse = "NO RESPONSE YET";
  3889. + tptime.append(MakeMsg("\x02[%s] - %s -\x02 Response: \x02%s\x02", lastchange.c_str(), ticktext.c_str(), tresponse.c_str()));
  3890. + delete result;
  3891. + Send_IRCA(ChanOrPM(CD), tptime, true, CD->TYPE);
  3892. + return;
  3893. + }
  3894. + if (guid.IsEmpty())
  3895. + {
  3896. + Send_IRCA(CD->USER, "\0034[ERROR] : Character not found." ,true, "ERROR");
  3897. + return;
  3898. + }
  3899. + else
  3900. + Send_IRCA(CD->USER, "\0034[ERROR] : The character has no ticket." ,true, "ERROR");
  3901. + }
  3902. + if (_PARAMS[0] == "respond")
  3903. + {
  3904. + if (_PARAMS[2] == "")
  3905. + {
  3906. + Send_IRCA(CD->USER, "\0034[ERROR] : Please specify character's name and respond message." ,true, "ERROR");
  3907. + return;
  3908. + }
  3909. + std::string CharName = _PARAMS[1].c_str();
  3910. + ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(CharName);
  3911. +
  3912. + if (guid.IsEmpty())
  3913. + {
  3914. + Send_IRCA(CD->USER, "\0034[ERROR] : Character not found. " ,true, "ERROR");
  3915. + return;
  3916. + }
  3917. +
  3918. + GMTicket* ticket = sTicketMgr.GetGMTicket(guid);
  3919. +
  3920. + if (!ticket)
  3921. + {
  3922. + Send_IRCA(CD->USER, "\0034[ERROR] : Ticket not found." ,true, "ERROR");
  3923. + return;
  3924. + }
  3925. +
  3926. + ticket->SetResponseText(_PARAMS[2].c_str());
  3927. +
  3928. + if (Player* pl = sObjectMgr.GetPlayer(guid))
  3929. + pl->GetSession()->SendGMResponse(ticket);
  3930. +
  3931. + std::string tptime = MakeMsg("\x2 Ticket [%s] Has Been Respond\x3\x31\x30 ", CharName.c_str());
  3932. + Send_IRCA(ChanOrPM(CD), tptime, true, CD->TYPE);
  3933. + }
  3934. + if (_PARAMS[0] == "delete")
  3935. + {
  3936. +
  3937. + if (_PARAMS[1] == "")
  3938. + {
  3939. + Send_IRCA(CD->USER, "\0034[ERROR] : Please specify character's name or 'all' to delete all tickets." ,true, "ERROR");
  3940. + return;
  3941. + }
  3942. + if (_PARAMS[1] == "all")
  3943. + {
  3944. + sTicketMgr.DeleteAll();
  3945. + std::string tptime = MakeMsg("\x2 All Tickets Deleted!\x3\x31\x30 ");
  3946. + Send_IRCA(ChanOrPM(CD), tptime, true, CD->TYPE);
  3947. + return;
  3948. + }
  3949. + std::string CharName = _PARAMS[1].c_str();
  3950. + ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(CharName);
  3951. + GMTicket* ticket = sTicketMgr.GetGMTicket(guid);
  3952. + if (!ticket)
  3953. + {
  3954. + Send_IRCA(CD->USER, "\0034[ERROR] : Ticket not found." ,true, "ERROR");
  3955. + return;
  3956. + }
  3957. + sTicketMgr.Delete(guid);
  3958. + if (Player* pl = sObjectMgr.GetPlayer(guid))
  3959. + pl->GetSession()->SendGMTicketGetTicket(0x0A, 0);
  3960. + std::string tptime = MakeMsg("\x2 Ticket [%s] Deleted\x3\x31\x30 ", CharName.c_str());
  3961. + Send_IRCA(ChanOrPM(CD), tptime, true, CD->TYPE);
  3962. + }
  3963. +}
  3964. diff --git a/src/game/mangchat/IRCConf.cpp b/src/game/mangchat/IRCConf.cpp
  3965. new file mode 100644
  3966. index 0000000..6e3c6eb
  3967. --- /dev/null
  3968. +++ b/src/game/mangchat/IRCConf.cpp
  3969. @@ -0,0 +1,189 @@
  3970. +/*
  3971. + * MangChat for MaNGOS, the open source MMORPG-server
  3972. + *
  3973. + * This Program Is Free Software; You Can Redistribute It And/Or Modify It Under The
  3974. + * Terms Of The GNU General Public License
  3975. + *
  3976. + * Written and Developed by Cybrax <cybraxvd@gmail.com>, |Death| <death@hell360.net>,
  3977. + * Lice <lice@yeuxverts.net>, Dj_baby, Sanaell, Tase, Shinzon <shinzon@wowgollum.com>,
  3978. + * Xeross, 3raZar3, the orangevirus team <www.orangevir.us>, ...
  3979. + *
  3980. + * With Help And Support From The MaNGOS Project Community.
  3981. + * PLEASE RETAIN THE COPYRIGHT OF THE AUTHORS.
  3982. + */
  3983. +
  3984. +#include "IRCClient.h"
  3985. +#include "IRCCmd.h"
  3986. +#include "../../shared/Config/Config.h"
  3987. +#include "IRCConf.h"
  3988. +
  3989. +Config MCConfig;
  3990. +void IRCClient::SetCfgFile(char const* cfgfile)
  3991. +{
  3992. + sIRC.CfgFile = cfgfile;
  3993. +}
  3994. +
  3995. +bool IRCClient::LoadConfig()
  3996. +{
  3997. + if (!MCConfig.SetSource(CfgFile))
  3998. + sLog.outString("MangChat: Unable to open configuration file (%s), All default options are being used.", CfgFile);
  3999. + else
  4000. + sLog.outString("MangChat: Found the configuration file, %s", CfgFile);
  4001. +
  4002. + int ConfCnt = 0;
  4003. + sIRC._chan_count = 0;
  4004. + if (MCConfig.GetIntDefault("irc.active", 0))
  4005. + sIRC.Active = true;
  4006. + else
  4007. + sIRC.Active = false;
  4008. +
  4009. + sIRC._Host = MCConfig.GetStringDefault("irc.host", "irc.freenode.net");
  4010. + if (sIRC._Host.size() > 0)
  4011. + ConfCnt++;
  4012. + sIRC._Mver = MCConfig.GetStringDefault("irc.mver", "Version 1.7.9");
  4013. + sIRC._Port = MCConfig.GetIntDefault("irc.port", 6667);
  4014. + sIRC._User = MCConfig.GetStringDefault("irc.user", "MangChat");
  4015. + sIRC._Pass = MCConfig.GetStringDefault("irc.pass", "MyDumbPass");
  4016. + sIRC._Nick = MCConfig.GetStringDefault("irc.nick", "MangChat");
  4017. + sIRC._Auth = MCConfig.GetIntDefault("irc.auth", 0);
  4018. + sIRC._Auth_Nick = MCConfig.GetStringDefault("irc.auth.nick", "AuthNick");
  4019. + sIRC._ICC = MCConfig.GetStringDefault("irc.icc", "001");
  4020. + sIRC._defchan = MCConfig.GetStringDefault("irc.defchan", "lobby");
  4021. + sIRC._ldefc = MCConfig.GetIntDefault("irc.ldef", 0);
  4022. + sIRC._wct = MCConfig.GetIntDefault("irc.wct", 30000);
  4023. + sIRC.ajoin = MCConfig.GetIntDefault("irc.ajoin", 1);
  4024. + sIRC.ajchan = MCConfig.GetStringDefault("irc.ajchan", "world");
  4025. + sIRC.onlrslt = MCConfig.GetIntDefault("irc.online.result", 10);
  4026. + sIRC.BOTMASK = MCConfig.GetIntDefault("Botmask", 0);
  4027. + sIRC.logfile = MCConfig.GetStringDefault("irc.logfile.prefix", "IRC_");
  4028. + for (int i = 1; i < MAX_CONF_CHANNELS;i++)
  4029. + {
  4030. + std::ostringstream ss;
  4031. + ss << i;
  4032. + std::string ci = "irc.chan_" + ss.str();
  4033. + std::string t_chan = MCConfig.GetStringDefault(ci.c_str(), "");
  4034. + if (t_chan.size() > 0)
  4035. + {
  4036. + sIRC._chan_count++;
  4037. + sIRC._irc_chan[sIRC._chan_count] = t_chan;
  4038. + ci = "wow.chan_" + ss.str();
  4039. + sIRC._wow_chan[sIRC._chan_count] = MCConfig.GetStringDefault(ci.c_str(), t_chan.c_str());
  4040. + }
  4041. + }
  4042. + sIRC.JoinMsg = MCConfig.GetStringDefault("irc.joinmsg", "Whhaaazzzzaaaa, MangChat $Ver Baby!!");
  4043. + sIRC.RstMsg = MCConfig.GetStringDefault("irc.rstmsg", "MangChat Is Restarting, I Will Be Right Back!");
  4044. + sIRC.kikmsg = MCConfig.GetStringDefault("irc.kickmsg", "Do Not Kick Me Again, Severe Actions Will Be Taken!");
  4045. +
  4046. + // IRC LINES
  4047. + sIRC.ILINES[WOW_IRC] = MCConfig.GetStringDefault("chat.wow_irc", "\003<WoW>[\002$Name($Level)\002\003] $Msg");
  4048. + sIRC.ILINES[IRC_WOW] = MCConfig.GetStringDefault("chat.irc_wow", "\003<IRC>[$Name]: $Msg");
  4049. + sIRC.ILINES[JOIN_WOW] = MCConfig.GetStringDefault("chat.join_wow", "\00312>>\00304 $Name \003Joined The Channel!");
  4050. + sIRC.ILINES[JOIN_IRC] = MCConfig.GetStringDefault("chat.join_irc", "\003[$Name]: Has Joined IRC!");
  4051. + sIRC.ILINES[LEAVE_WOW] = MCConfig.GetStringDefault("chat.leave_wow", "\00312<<\00304 $Name \003Left The Channel!");
  4052. + sIRC.ILINES[LEAVE_IRC] = MCConfig.GetStringDefault("chat.leave_irc", "\003[$Name]: Has Left IRC!");
  4053. + sIRC.ILINES[CHANGE_NICK] = MCConfig.GetStringDefault("chat.change_nick", "\003<> $Name Is Now Known As $NewName!");
  4054. +
  4055. + // MangChat Options
  4056. + sIRC._MCA = MCConfig.GetIntDefault("irc.maxattempt", 10);
  4057. + sIRC._autojoinkick = MCConfig.GetIntDefault("irc.autojoin_kick", 1);
  4058. + sIRC._cmd_prefx = MCConfig.GetStringDefault("irc.command_prefix", ".");
  4059. +
  4060. + sIRC._op_gm = MCConfig.GetIntDefault("irc.op_gm_login", 0);
  4061. + sIRC._op_gm_lev = MCConfig.GetIntDefault("irc.op_gm_level", 3);
  4062. +
  4063. + // Misc Options
  4064. + sIRC.games = MCConfig.GetIntDefault("irc.fun.games", 0);
  4065. + sIRC.gmlog = MCConfig.GetIntDefault("irc.gmlog", 1);
  4066. + sIRC.BOTMASK = MCConfig.GetIntDefault("BotMask", 0);
  4067. + sIRC.Status = MCConfig.GetIntDefault("irc.StatusChannel", 1);
  4068. + sIRC.anchn = MCConfig.GetIntDefault("irc.AnnounceChannel", 1);
  4069. + sIRC.autoanc = MCConfig.GetIntDefault("irc.auto.announce", 30);
  4070. +
  4071. + for (uint16 i = 0; i<SEC_ADMINISTRATOR; i++)
  4072. + {
  4073. + std::stringstream ircKeyWord, defaultEntry;
  4074. + ircKeyWord << "irc.gm" << i;
  4075. + if (!i)
  4076. + defaultEntry << "";
  4077. + else
  4078. + defaultEntry << "[GM" << i << "]";
  4079. + sIRC.ojGM[i] = MCConfig.GetStringDefault(ircKeyWord.str().c_str(), defaultEntry.str().c_str());
  4080. + }
  4081. +
  4082. + // REQUIRED GM LEVEL
  4083. + QueryResult *result = WorldDatabase.PQuery("SELECT `Command`, `gmlevel` FROM `irc_commands` ORDER BY `Command`");
  4084. + if (result)
  4085. + {
  4086. + Field *fields = result->Fetch();
  4087. + for (uint64 i=0; i < result->GetRowCount(); i++)
  4088. + {
  4089. + std::string command = fields[0].GetCppString();
  4090. + uint32 gmlvl = fields[1].GetUInt32();
  4091. + if (command == "acct") sIRC.CACCT = gmlvl;
  4092. + if (command == "ban") sIRC.CBAN = gmlvl;
  4093. + if (command == "char") sIRC.CCHAN = gmlvl;
  4094. + if (command == "char") sIRC.CCHAR = gmlvl;
  4095. + if (command == "fun") sIRC.CFUN = gmlvl;
  4096. + if (command == "help") sIRC.CHELP = gmlvl;
  4097. + if (command == "inchan") sIRC.CINCHAN = gmlvl;
  4098. + if (command == "info") sIRC.CINFO = gmlvl;
  4099. + if (command == "item") sIRC.CITEM = gmlvl;
  4100. + if (command == "jail") sIRC.CJAIL = gmlvl;
  4101. + if (command == "kick") sIRC.CKICK = gmlvl;
  4102. + if (command == "kill") sIRC._KILL = gmlvl;
  4103. + if (command == "level") sIRC.CLEVEL = gmlvl;
  4104. + if (command == "lookup") sIRC.CLOOKUP = gmlvl;
  4105. + if (command == "money") sIRC.CMONEY = gmlvl;
  4106. + if (command == "mute") sIRC.CMUTE = gmlvl;
  4107. + if (command == "online") sIRC.CONLINE = gmlvl;
  4108. + if (command == "pm") sIRC.CPM = gmlvl;
  4109. + if (command == "restart") sIRC.CRESTART = gmlvl;
  4110. + if (command == "revive") sIRC.CREVIVE = gmlvl;
  4111. + if (command == "saveall") sIRC.CSAVEALL = gmlvl;
  4112. + if (command == "shutdown") sIRC.CSHUTDOWN = gmlvl;
  4113. + if (command == "spell") sIRC.CSPELL = gmlvl;
  4114. + if (command == "sysmsg") sIRC.CSPELL = gmlvl;
  4115. + if (command == "tele") sIRC.CTELE = gmlvl;
  4116. + if (command == "top") sIRC.CTOP = gmlvl;
  4117. + if (command == "who") sIRC.CWHO = gmlvl;
  4118. + result->NextRow();
  4119. + }
  4120. + delete result;
  4121. + }
  4122. + else
  4123. + {
  4124. + sIRC.CACCT = 3;
  4125. + sIRC.CBAN = 3;
  4126. + sIRC.CCHAN = 3;
  4127. + sIRC.CCHAR = 3;
  4128. + sIRC.CFUN = 3;
  4129. + sIRC.CHELP = 3;
  4130. + sIRC.CINCHAN = 3;
  4131. + sIRC.CINFO = 3;
  4132. + sIRC.CITEM = 3;
  4133. + sIRC.CJAIL = 3;
  4134. + sIRC.CKICK = 3;
  4135. + sIRC._KILL = 3;
  4136. + sIRC.CLEVEL = 3;
  4137. + sIRC.CLOOKUP = 3;
  4138. + sIRC.CMONEY = 3;
  4139. + sIRC.CMUTE = 3;
  4140. + sIRC.CONLINE = 3;
  4141. + sIRC.CPM = 3;
  4142. + sIRC.CRESTART = 3;
  4143. + sIRC.CREVIVE = 3;
  4144. + sIRC.CSAVEALL = 3;
  4145. + sIRC.CSHUTDOWN = 3;
  4146. + sIRC.CSPELL = 3;
  4147. + sIRC.CSYSMSG = 3;
  4148. + sIRC.CTELE = 3;
  4149. + sIRC.CTOP = 3;
  4150. + sIRC.CWHO = 3;
  4151. + }
  4152. + return true;
  4153. +}
  4154. +
  4155. +std::string IRCClient::GetChatLine(int nItem)
  4156. +{
  4157. + return sIRC.ILINES[nItem];
  4158. +}
  4159. diff --git a/src/game/mangchat/IRCConf.h b/src/game/mangchat/IRCConf.h
  4160. new file mode 100644
  4161. index 0000000..ae9b2d8
  4162. --- /dev/null
  4163. +++ b/src/game/mangchat/IRCConf.h
  4164. @@ -0,0 +1,12 @@
  4165. +#ifndef MC_CONFIG_H
  4166. +#define MC_CONFIG_H
  4167. +
  4168. +#include "Platform/CompilerDefs.h"
  4169. +
  4170. +#if PLATFORM == PLATFORM_WINDOWS
  4171. + #define _MANGCHAT_CONFIG "mangchat.conf"
  4172. +#else
  4173. + #define _MANGCHAT_CONFIG SYSCONFDIR"mangchat.conf"
  4174. +#endif
  4175. +
  4176. +#endif
  4177. diff --git a/src/game/mangchat/IRCFunc.h b/src/game/mangchat/IRCFunc.h
  4178. new file mode 100644
  4179. index 0000000..27bcde8
  4180. --- /dev/null
  4181. +++ b/src/game/mangchat/IRCFunc.h
  4182. @@ -0,0 +1,268 @@
  4183. +/*
  4184. + * MangChat for MaNGOS, the open source MMORPG-server
  4185. + *
  4186. + * This Program Is Free Software; You Can Redistribute It And/Or Modify It Under The
  4187. + * Terms Of The GNU General Public License
  4188. + *
  4189. + * Written and Developed by Cybrax <cybraxvd@gmail.com>, |Death| <death@hell360.net>,
  4190. + * Lice <lice@yeuxverts.net>, Dj_baby, Sanaell, Tase, Shinzon <shinzon@wowgollum.com>,
  4191. + * Xeross, 3raZar3, the orangevirus team <www.orangevir.us>, ...
  4192. + *
  4193. + * With Help And Support From The MaNGOS Project Community.
  4194. + * PLEASE RETAIN THE COPYRIGHT OF THE AUTHORS.
  4195. + */
  4196. +
  4197. +#ifndef _IRC_CLIENT_FUNC
  4198. +#define _IRC_CLIENT_FUNC
  4199. +
  4200. +std::string GetUser(std::string szU)
  4201. +{
  4202. + int pos = szU.find("!");
  4203. + return szU.substr(0, pos);
  4204. +}
  4205. +
  4206. +// determines weather a string is terminated by a Carriage Return or not
  4207. +bool isCRTerminated(std::string arg)
  4208. +{
  4209. + return (arg.end() != arg.begin() && (*--arg.end()) == 0x0D);
  4210. +}
  4211. +
  4212. +// Delink will remove anything considered "non chat" from a string
  4213. +// Linked items (items that players can click on to see a description)
  4214. +// contain extra characters wich the client filter out, this function
  4215. +// makes sure people on irc do not see those characters.
  4216. +std::string Delink(std::string msg)
  4217. +{
  4218. + std::size_t pos;
  4219. + const char delinkExpression[4][10] = {"|Hitem", "|Hquest", "|Henchant", "|Hspell"};
  4220. +
  4221. + for (uint8 i = 0; i < 4; ++i)
  4222. + while((pos = msg.find(delinkExpression[i])) != std::string::npos)
  4223. + {
  4224. + std::size_t find1 = msg.find("|h", pos);
  4225. + std::size_t find2 = msg.find("|h", find1 + 2);
  4226. + msg.replace(pos, find1 - pos + 2, "\x2");
  4227. + msg.replace(msg.find("|h", pos), 2, "\x2");
  4228. + }
  4229. +
  4230. + return msg;
  4231. +}
  4232. +
  4233. +// This function converts the characters used by the client to identify colour to IRC format.
  4234. +std::string WoWcol2IRC(std::string msg)
  4235. +{
  4236. + std::size_t pos;
  4237. + char IRCCol[15][4] = { "\xF", "\xF", "\x3\x31\x34", "\x3\x30\x33", "\x3\x31\x32", "\x3\x30\x36", "\x3\x30\x37", "\x3\x30\x34", "\x3\x30\x37", "\x3\x30\x38", "\x3\x31\x34", "\x3\x30\x33","\x3\x30\x34", "\x3\x30\x37", "\x3\x31\x31"};
  4238. + char WoWCol[15][12] = { "|r", "|cffffffff", "|cff9d9d9d", "|cff1eff00", "|cff0070dd", "|cffa335ee", "|cffff8000", "|cffe6cc80", "|cffffd000", "|cffffff00", "|cff808080", "|cff40c040", "|cffff2020", "|cffff8040", "|cff71d5ff"};
  4239. + for (int i=0; i<15; i++)
  4240. + {
  4241. + while ((pos = msg.find(WoWCol[i])) != std::string::npos)
  4242. + {
  4243. + if (i == 0)
  4244. + msg.replace(pos, 2, IRCCol[i]);
  4245. + else
  4246. + msg.replace(pos, 10, IRCCol[i]);
  4247. + }
  4248. + }
  4249. + return msg;
  4250. +}
  4251. +
  4252. +// This function converts the characters used by IRC to identify colour to a format the client can understand.
  4253. +std::string IRCcol2WoW(std::string msg)
  4254. +{
  4255. + std::size_t pos;
  4256. + char IRCCol[16][4] = { "\x3\x30", "\x3\x31", "\x3\x32", "\x3\x33", "\x3\x34", "\x3\x35", "\x3\x36", "\x3\x37", "\x3\x38", "\x3\x39", "\x3\x31\x30", "\x3\x31\x31", "\x3\x31\x32", "\x3\x31\x33", "\x3\x31\x34", "\x3\x31\x35"};
  4257. + 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"};
  4258. + char WoWcol[16][12] = { "|cffffffff", "|cff000000", "|cff00007f", "|cff009300", "|cffff0000", "|cff7f0000", "|cff9c009c", "|cfffc9300", "|cffffff00", "|cff00fc00", "|cff009393", "|cff00ffff", "|cff0000fc", "|cffff00ff", "|cff7f7f7f", "|cffd2d2d2"};
  4259. + for (int i=15; i>=0; i--)
  4260. + {
  4261. + if (i<10)
  4262. + {
  4263. + while ((pos = msg.find(IRCCol2[i])) != std::string::npos)
  4264. + {
  4265. + msg.replace(pos, 3, WoWcol[i]);
  4266. + }
  4267. + while ((pos = msg.find(IRCCol[i])) != std::string::npos)
  4268. + {
  4269. + msg.replace(pos, 2, WoWcol[i]);
  4270. + }
  4271. +
  4272. + }
  4273. + else
  4274. + {
  4275. + while ((pos = msg.find(IRCCol[i])) != std::string::npos)
  4276. + {
  4277. + msg.replace(pos, 3, WoWcol[i]);
  4278. + }
  4279. + }
  4280. +
  4281. + // Remove Bold, Reverse, Underline from IRC
  4282. + char Checker[3][3] = {"\x2","\x16","\x1F"}; // This is the Hex part not Dec. In Decimal its (2,22,31)
  4283. + for(int I=0; I < 3; I++)
  4284. + {
  4285. + while ((pos = msg.find(Checker[I])) != std::string::npos)
  4286. + {
  4287. + msg.replace(pos, 1, "");
  4288. + }
  4289. + }
  4290. + // Finished Removing !
  4291. +
  4292. + }
  4293. +
  4294. + while ((pos = msg.find("\x3")) != std::string::npos)
  4295. + {
  4296. + msg.replace(pos, 1, "|r");
  4297. + }
  4298. + while ((pos = msg.find("\xF")) != std::string::npos)
  4299. + {
  4300. + msg.replace(pos, 1, "|r");
  4301. + }
  4302. +
  4303. + return msg;
  4304. +}
  4305. +
  4306. +// This function compares 2 strings
  4307. +int nocase_cmp(const string & s1, const string& s2)
  4308. +{
  4309. + string::const_iterator it1=s1.begin();
  4310. + string::const_iterator it2=s2.begin();
  4311. +
  4312. + //stop when either string's end has been reached
  4313. + while ( (it1!=s1.end()) && (it2!=s2.end()) )
  4314. + {
  4315. + if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
  4316. + // return -1 to indicate smaller than, 1 otherwise
  4317. + return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1;
  4318. + //proceed to the next character in each string
  4319. + ++it1;
  4320. + ++it2;
  4321. + }
  4322. + size_t size1=s1.size(), size2=s2.size(); // cache lengths
  4323. + //return -1,0 or 1 according to strings' lengths
  4324. + if (size1==size2)
  4325. + return 0;
  4326. + return (size1<size2) ? -1 : 1;
  4327. +}
  4328. +
  4329. +std::string MakeMsgA(const char *sLine, ... )
  4330. +{
  4331. + va_list ap;
  4332. + char tmpoutp[1024];
  4333. + va_start(ap, sLine);
  4334. + vsnprintf(tmpoutp, 1024, sLine, ap );
  4335. + va_end(ap);
  4336. + std::string outp = tmpoutp;
  4337. + return outp;
  4338. +}
  4339. +
  4340. +std::string MakeMsgP(int CLINE, std::string Msg, Player *plr)
  4341. +{
  4342. + // std::string ChatTag = "";
  4343. + // switch (plr->GetTeam())
  4344. + // {
  4345. + // case 67:ChatTag.append("4");break; //horde
  4346. + // case 469:ChatTag.append("12");break; //alliance
  4347. + // }
  4348. + std::string sMsg = sIRC.MakeMsg(sIRC.GetChatLine(CLINE), "$Msg", Msg);
  4349. + // sMsg = ChatTag + MakeMsg(sMsg, "$Name", plr->GetName());
  4350. + if (plr->GetTeam() == 67)
  4351. + sMsg = sIRC.MakeMsg(sMsg, "$Name", MakeMsgA("\0034%s\003", plr->GetName()));
  4352. + else if (plr->GetTeam() == 469)
  4353. + sMsg = sIRC.MakeMsg(sMsg, "$Name", MakeMsgA("\00312%s\003", plr->GetName()));
  4354. + if(plr->isAFK())
  4355. + sMsg = sIRC.MakeMsg(sMsg, "$Tag", "<AFK>");
  4356. + else if(plr->isDND())
  4357. + sMsg = sIRC.MakeMsg(sMsg, "$Tag", "<DND>");
  4358. + else
  4359. + sMsg = sIRC.MakeMsg(sMsg, "$Tag", "");
  4360. + sMsg = sIRC.MakeMsg(sMsg, "$Level", MakeMsgA("%d", plr->getLevel()));
  4361. + sMsg = Delink(sMsg);
  4362. + sMsg = WoWcol2IRC(sMsg);
  4363. + return sMsg;
  4364. +}
  4365. +
  4366. +/*
  4367. +std::string MakeMsg(std::string msg, std::string var, int val)
  4368. +{
  4369. + std::ostringstream ss;
  4370. + ss << val;
  4371. +
  4372. + std::string nval = ss.str();
  4373. + std::size_t start = msg.find(var);
  4374. + if (start != std::string::npos)
  4375. + msg.replace(start, var.length(), val);
  4376. + return msg;
  4377. +}
  4378. +*/
  4379. +/*
  4380. +std::string MakeMsg(const char *sLine, ... )
  4381. +{
  4382. + va_list ap;
  4383. + char tmpoutp[1024];
  4384. + va_start(ap, sLine);
  4385. + vsnprintf(tmpoutp, 1024, sLine, ap );
  4386. + va_end(ap);
  4387. + std::string outp = tmpoutp;
  4388. + return outp;
  4389. +}
  4390. +*/
  4391. +
  4392. +// This function checks if a channel exists in out configuration
  4393. +// Mangchat supports as many channels as you like
  4394. +// However the default has been set to 10
  4395. +// if you wish to increase this you must edit the:
  4396. +// MAX_CONF_CHANNELS variable in IRCClient.h
  4397. +bool Channel_Valid(std::string Channel)
  4398. +{
  4399. + for(int i=1;i < sIRC._chan_count + 1;i++)
  4400. + {
  4401. + if(nocase_cmp(sIRC._wow_chan[i], Channel)==0)
  4402. + return true;
  4403. + }
  4404. + return false;
  4405. +}
  4406. +
  4407. +std::string GetWoWChannel(std::string Channel)
  4408. +{
  4409. + for(int i=1;i < sIRC._chan_count + 1;i++)
  4410. + {
  4411. + if("#" + sIRC._irc_chan[i] == Channel)
  4412. + return sIRC._wow_chan[i];
  4413. + }
  4414. + return "";
  4415. +}
  4416. +
  4417. +std::string GetIRCChannel(std::string Channel)
  4418. +{
  4419. + for(int i=1;i < sIRC._chan_count + 1;i++)
  4420. + {
  4421. + if(sIRC._wow_chan[i] == Channel)
  4422. + return sIRC._irc_chan[i];
  4423. + }
  4424. + return "";
  4425. +}
  4426. +
  4427. +std::string* getArray(std::string PARAMS, int nCount, std::string )
  4428. +{
  4429. + std::string *array = new std::string[nCount];
  4430. + if(PARAMS.size() > 0)
  4431. + {
  4432. + int pcnt = 0;
  4433. + size_t ps = 0;
  4434. + size_t pc = -1;
  4435. + for(int i = 0;i < nCount;i++)
  4436. + {
  4437. + pc = PARAMS.find(" ", pc + 1);
  4438. + if(i + 1 == nCount && nCount != 1)
  4439. + {
  4440. + if(ps > 0 && pc > 0)
  4441. + array[i] = PARAMS.substr(ps, PARAMS.size() - ps);
  4442. + }
  4443. + else
  4444. + array[i] = PARAMS.substr(ps, pc - ps);
  4445. + ps = pc + 1;
  4446. + }
  4447. + }
  4448. + return array;
  4449. +}
  4450. +#endif
  4451. diff --git a/src/game/mangchat/IRCIO.cpp b/src/game/mangchat/IRCIO.cpp
  4452. new file mode 100644
  4453. index 0000000..3fd1862
  4454. --- /dev/null
  4455. +++ b/src/game/mangchat/IRCIO.cpp
  4456. @@ -0,0 +1,437 @@
  4457. +/*
  4458. + * MangChat for MaNGOS, the open source MMORPG-server
  4459. + *
  4460. + * This Program Is Free Software; You Can Redistribute It And/Or Modify It Under The
  4461. + * Terms Of The GNU General Public License
  4462. + *
  4463. + * Written and Developed by Cybrax <cybraxvd@gmail.com>, |Death| <death@hell360.net>,
  4464. + * Lice <lice@yeuxverts.net>, Dj_baby, Sanaell, Tase, Shinzon <shinzon@wowgollum.com>,
  4465. + * Xeross, 3raZar3, the orangevirus team <www.orangevir.us>, ...
  4466. + *
  4467. + * With Help And Support From The MaNGOS Project Community.
  4468. + * PLEASE RETAIN THE COPYRIGHT OF THE AUTHORS.
  4469. + */
  4470. +
  4471. +#include "IRCClient.h"
  4472. +#include "IRCCmd.h"
  4473. +#include "IRCFunc.h"
  4474. +#include "../ObjectAccessor.h"
  4475. +#include "../ObjectMgr.h"
  4476. +#include "../../shared/WorldPacket.h"
  4477. +#include "../ChannelMgr.h"
  4478. +#include "../../shared/Config/Config.h"
  4479. +#include "../Channel.h"
  4480. +#include "../World.h"
  4481. +#include "../Chat.h"
  4482. +
  4483. +IRCCmd Command;
  4484. +void IRCClient::Handle_IRC(std::string sData)
  4485. +{
  4486. + sLog.outDebug(sData.c_str());
  4487. + // If first 5 chars are ERROR then something is wrong
  4488. + // either link is being closed, nickserv ghost command, etc...
  4489. + try
  4490. + {
  4491. + if(sData.substr(0, 5) == "ERROR")
  4492. + {
  4493. + Disconnect();
  4494. + return;
  4495. + }
  4496. + if(sData.substr(0, 4) == "PING")
  4497. + {
  4498. + // if the first 4 characters contain PING
  4499. + // the server is checking if we are still alive
  4500. + // sen back PONG back plus whatever the server send with it
  4501. + SendIRC("PONG " + sData.substr(4, sData.size() - 4));
  4502. + }
  4503. + else
  4504. + {
  4505. + // if the first line contains : its an irc message
  4506. + // such as private messages channel join etc.
  4507. + if(sData.substr(0, 1) == ":")
  4508. + {
  4509. + // find the spaces in the receieved line
  4510. + size_t p1 = sData.find(" ");
  4511. + size_t p2 = sData.find(" ", p1 + 1);
  4512. + // because the irc protocol uses simple spaces
  4513. + // to seperate data we can easy pick them out
  4514. + // since we know the position of the spaces
  4515. + std::string USR = sData.substr(1, p1 - 1);
  4516. + std::string CMD = sData.substr(p1 + 1, p2 - p1 - 1);
  4517. + // trasform the commands to lowercase to make sure they always match
  4518. + std::transform(CMD.begin(), CMD.end(), CMD.begin(), towlower);
  4519. + // Extract the username from the first part
  4520. + std::string szUser = GetUser(USR);
  4521. + // if we receieved the internet connect code
  4522. + // we know for sure that were in and we can
  4523. + // authenticate ourself.
  4524. + if(CMD == sIRC._ICC)
  4525. + {
  4526. + // _Auth is defined in mangosd.conf (irc.auth)
  4527. + // 0 do not authenticate
  4528. + // 1 use nickserv
  4529. + // 2 use quakenet
  4530. + // aditionally you can provide you own authentication method here
  4531. + switch(sIRC._Auth)
  4532. + {
  4533. + case 1:
  4534. + SendIRC("PRIVMSG nickserv :IDENTIFY " + sIRC._Pass);
  4535. + break;
  4536. + case 2:
  4537. + SendIRC("PRIVMSG nickserv :IDENTIFY " + sIRC._Auth_Nick + " " + sIRC._Pass);
  4538. + break;
  4539. + case 3:
  4540. + SendIRC("PRIVMSG Q@CServe.quakenet.org :AUTH " + sIRC._Nick + " " + sIRC._Pass);
  4541. + break;
  4542. + case 4:
  4543. + SendIRC("PRIVMSG Q@CServe.quakenet.org :AUTH " + sIRC._Auth_Nick + " " + sIRC._Pass);
  4544. + break;
  4545. + }
  4546. + // if we join a default channel leave this now.
  4547. + if(sIRC._ldefc==1)
  4548. + SendIRC("PART #" + sIRC._defchan);
  4549. + // Loop thru the channel array and send a command to join them on IRC.
  4550. + for(int i=1;i < sIRC._chan_count + 1;i++)
  4551. + {
  4552. + SendIRC("JOIN #" + sIRC._irc_chan[i]);
  4553. + }
  4554. + }
  4555. + // someone joined the channel this could be the bot or another user
  4556. + if(CMD == "join")
  4557. + {
  4558. + size_t p = sData.find(":", p1);
  4559. + std::string CHAN = sData.substr(p + 1, sData.size() - (p + 1 + isCRTerminated(sData)));
  4560. + // if the user is us it means we join the channel
  4561. + if ((szUser == sIRC._Nick) )
  4562. + {
  4563. + // its us that joined the channel
  4564. + Send_IRC_Channel(CHAN, MakeMsg(MakeMsg(sIRC.JoinMsg, "$Ver", sIRC._Mver.c_str()), "$Trigger", sIRC._cmd_prefx.c_str()), true);
  4565. + }
  4566. + else
  4567. + {
  4568. + // if the user is not us its someone else that joins
  4569. + // so we construct a message and send this to the clients.
  4570. + // MangChat now uses Send_WoW_Channel to send to the client
  4571. + // this makes MangChat handle the packets instead of previously the world.
  4572. + if(sIRC.BOTMASK & 2)
  4573. + Send_WoW_Channel(GetWoWChannel(CHAN).c_str(), IRCcol2WoW(MakeMsg(MakeMsg(GetChatLine(JOIN_IRC), "$Name", szUser), "$Channel", GetWoWChannel(CHAN))));
  4574. + }
  4575. + }
  4576. + // someone on irc left or quit the channel
  4577. + if(CMD == "part" || CMD == "quit")
  4578. + {
  4579. + size_t p3 = sData.find(" ", p2 + 1);
  4580. + std::string CHAN = sData.substr(p2 + 1, p3 - (p2 - isCRTerminated(sData)));
  4581. + // Logout IRC Nick From MangChat If User Leaves Or Quits IRC.
  4582. + if(Command.IsLoggedIn(szUser))
  4583. + {
  4584. + _CDATA CDATA;
  4585. + CDATA.USER = szUser;
  4586. + Command.Handle_Logout(&CDATA);
  4587. + }
  4588. + // Construct a message and inform the clients on the same channel.
  4589. + if (sIRC.BOTMASK & 2)
  4590. + Send_WoW_Channel(GetWoWChannel(CHAN).c_str(), IRCcol2WoW(MakeMsg(MakeMsg(GetChatLine(LEAVE_IRC), "$Name", szUser), "$Channel", GetWoWChannel(CHAN))));
  4591. + }
  4592. + // someone changed their nick
  4593. + if (CMD == "nick" && (sIRC.BOTMASK & 128))
  4594. + {
  4595. + MakeMsg(MakeMsg(GetChatLine(CHANGE_NICK), "$Name", szUser), "$NewName", sData.substr(sData.find(":", p2) + 1, sData.size()- isCRTerminated(sData)));
  4596. + // If the user is logged in and changes their nick
  4597. + // then we want to either log them out or update
  4598. + // their nick in the bot. I chose to update the bots user list.
  4599. + if(Command.IsLoggedIn(szUser))
  4600. + {
  4601. + std::string NewNick = sData.substr(sData.find(":", p2) + 1, isCRTerminated(sData));
  4602. + // On freenode I noticed the server sends an extra character
  4603. + // at the end of the string, so we need to erase the last
  4604. + // character of the string. if you have a problem with getting
  4605. + // the last letter of your nick erased, then remove the - 1.
  4606. + NewNick.erase(NewNick.length() - 1, 1);
  4607. +
  4608. + for(std::list<_client*>::iterator i=Command._CLIENTS.begin(); i!=Command._CLIENTS.end();i++)
  4609. + {
  4610. + if((*i)->Name == szUser)
  4611. + {
  4612. + (*i)->Name = NewNick;
  4613. + sIRC.Send_IRC_Channel(NewNick.c_str(), "I Noticed You Changed Your Nick, I Have Updated My Internal Database Accordingly.", true, "NOTICE");
  4614. +
  4615. + // Figure why not output to the logfile, makes tracing problems easier.
  4616. + sIRC.iLog.WriteLog(" %s : %s Changed Nick To: %s", sIRC.iLog.GetLogDateTimeStr().c_str(), szUser.c_str(), NewNick.c_str());
  4617. + }
  4618. + }
  4619. + }
  4620. +
  4621. + }
  4622. + // someone was kicked from irc
  4623. + if (CMD == "kick")
  4624. + {
  4625. + // extract the details
  4626. + size_t p3 = sData.find(" ", p2 + 1);
  4627. + size_t p4 = sData.find(" ", p3 + 1);
  4628. + size_t p5 = sData.find(":", p4);
  4629. + std::string CHAN = sData.substr(p2 + 1, p3 - p2 - 1);
  4630. + std::string WHO = sData.substr(p3 + 1, p4 - (p3 + 1));
  4631. + std::string BY = sData.substr(p4 + 1, sData.size() - (p4 + isCRTerminated(sData)));
  4632. + // if the one kicked was us
  4633. + if(WHO == sIRC._Nick)
  4634. + {
  4635. + // and autojoin is enabled
  4636. + // return to the channel
  4637. + if(sIRC._autojoinkick == 1)
  4638. + {
  4639. + SendIRC("JOIN " + CHAN);
  4640. + Send_IRC_Channel(CHAN, sIRC.kikmsg, true);
  4641. + }
  4642. + }
  4643. + else
  4644. + {
  4645. + // if it is not us who was kicked we need to inform the clients someone
  4646. + // was removed from the channel
  4647. + // construct a message and send it to the players.
  4648. + Send_WoW_Channel(GetWoWChannel(CHAN).c_str(), "<IRC>[" + WHO + "]: Was Kicked From " + CHAN + " By: " + szUser);
  4649. + }
  4650. + }
  4651. + // a private chat message was receieved.
  4652. + if(CMD == "privmsg" || CMD == "notice")
  4653. + {
  4654. + // extract the values
  4655. + size_t p = sData.find(" ", p2 + 1);
  4656. + std::string FROM = sData.substr(p2 + 1, p - p2 - 1);
  4657. + std::string CHAT = sData.substr(p + 2, sData.size() - (p + 2 + isCRTerminated(sData)));
  4658. + // if this is our username it means we recieved a PM
  4659. + if(FROM == sIRC._Nick)
  4660. + {
  4661. + if(CHAT.find("\001VERSION\001") < CHAT.size())
  4662. + {
  4663. + Send_IRC_Channel(szUser, MakeMsg("\001VERSION MangChat %s ©2008 |Death|\001", "%s" , sIRC._Mver.c_str()), true, "NOTICE");
  4664. + }
  4665. + // a pm is required for certain commands
  4666. + // such as login. to validate the command
  4667. + // we send it to the command class wich handles
  4668. + // evrything else.
  4669. + Command.IsValid(szUser, FROM, CHAT, CMD);
  4670. + }
  4671. + else
  4672. + {
  4673. + // if our name is not in it, it means we receieved chat on one of the channels
  4674. + // magchat is in. the first thing we do is check if it is a command or not
  4675. + if(!Command.IsValid(szUser, FROM, CHAT, CMD))
  4676. + {
  4677. + Send_WoW_Channel(GetWoWChannel(FROM).c_str(), IRCcol2WoW(MakeMsg(MakeMsg(GetChatLine(IRC_WOW), "$Name", szUser), "$Msg", CHAT)));
  4678. + }
  4679. + // if we indeed receieved a command we do not want to display this to the players
  4680. + // so only incanse the isvalid command returns false it will be sent to all player.
  4681. + // the isvalid function will automaitcly process the command on true.
  4682. + }
  4683. + }
  4684. + if(CMD == "mode")
  4685. + {
  4686. + // extract the mode details
  4687. + size_t p3 = sData.find(" ", p2 + 1);
  4688. + size_t p4 = sData.find(" ", p3 + 1);
  4689. + size_t p5 = sData.find(" ", p4 + 1);
  4690. + std::string CHAN = sData.substr(p2 + 1, p3 - p2 - 1);
  4691. + std::string MODE = sData.substr(p3 + 1, p4 - p3 - 1);
  4692. + std::string NICK = sData.substr(p4 + 1, p5 - p4 - 1);
  4693. + bool _AmiOp;
  4694. + _AmiOp = false;
  4695. + //A mode was changed on us
  4696. + if(NICK.c_str() == sIRC._Nick)
  4697. + _AmiOp = true;
  4698. +
  4699. + }
  4700. + }
  4701. + }
  4702. + }
  4703. + catch(std::out_of_range& e)
  4704. + {
  4705. + }
  4706. +}
  4707. +
  4708. +// This function is called in Channel.h
  4709. +// based on nAction it will inform the people on
  4710. +// irc when someone leaves one of the game channels.
  4711. +// nAction is based on the struct CACTION
  4712. +void IRCClient::Handle_WoW_Channel(std::string Channel, Player *plr, int nAction)
  4713. +{
  4714. + // make sure that we are connected
  4715. + if (sIRC.Connected && (sIRC.BOTMASK & 1))
  4716. + {
  4717. + if(Channel_Valid(Channel))
  4718. + {
  4719. + std::string GMRank = "";
  4720. + std::string pname = plr->GetName();
  4721. + bool DoGMAnnounce = false;
  4722. + if (plr->GetSession()->GetSecurity() > 0 && (sIRC.BOTMASK & 8))
  4723. + DoGMAnnounce = true;
  4724. + if (plr->isGameMaster() && (sIRC.BOTMASK & 16))
  4725. + DoGMAnnounce = true;
  4726. + if(DoGMAnnounce)
  4727. + {
  4728. + uint16 gmLevel = plr->GetSession()->GetSecurity();
  4729. + GMRank = "\0037"+sIRC.ojGM[ gmLevel < SEC_CONSOLE ? gmLevel : SEC_CONSOLE];
  4730. + }
  4731. + std::string ChatTag = "";
  4732. + switch (plr->GetTeam())
  4733. + {
  4734. + case 67:ChatTag.append("\0034");break; //horde
  4735. + case 469:ChatTag.append("\00312");break; //alliance
  4736. + }
  4737. + std::string query = "INSERT INTO `irc_inchan` VALUES (%d,'"+pname+"','"+Channel+"')";
  4738. + std::string lchan = "DELETE FROM `irc_inchan` WHERE `guid` = %d AND `channel` = '"+Channel+"'";
  4739. + switch(nAction)
  4740. + {
  4741. + case CHANNEL_JOIN:
  4742. + Send_IRC_Channel(GetIRCChannel(Channel), MakeMsg(MakeMsg(MakeMsg(GetChatLine(JOIN_WOW), "$Name", ChatTag + plr->GetName()), "$Channel", Channel), "$GM", GMRank));
  4743. + WorldDatabase.PExecute(lchan.c_str(), plr->GetObjectGuid().GetCounter());
  4744. + WorldDatabase.PExecute(query.c_str(), plr->GetObjectGuid().GetCounter());
  4745. + break;
  4746. + case CHANNEL_LEAVE:
  4747. + Send_IRC_Channel(GetIRCChannel(Channel), MakeMsg(MakeMsg(MakeMsg(GetChatLine(LEAVE_WOW), "$Name", ChatTag + plr->GetName()), "$Channel", Channel), "$GM", GMRank));
  4748. + WorldDatabase.PExecute(lchan.c_str(), plr->GetObjectGuid().GetCounter());
  4749. + break;
  4750. + }
  4751. + }
  4752. + }
  4753. +}
  4754. +
  4755. +// This function sends chat to a irc channel or user
  4756. +// to prevent the # beeing appended to send a msg to a user
  4757. +// set the NoPrefix to true
  4758. +void IRCClient::Send_IRC_Channel(std::string sChannel, std::string sMsg, bool NoPrefix, std::string nType)
  4759. +{
  4760. + std::string mType = "PRIVMSG";
  4761. + if(Command.MakeUpper(nType.c_str()) == "NOTICE")
  4762. + mType = "NOTICE";
  4763. + if(Command.MakeUpper(nType.c_str()) == "ERROR" && (sIRC.BOTMASK & 32))
  4764. + mType = "NOTICE";
  4765. + if(sIRC.Connected)
  4766. + {
  4767. + if(NoPrefix)
  4768. + SendIRC(mType + " " + sChannel + " :" + sMsg);
  4769. + else
  4770. + SendIRC(mType + " #" + sChannel + " :" + sMsg);
  4771. + }
  4772. +}
  4773. +
  4774. +// This function sends a message to all irc channels
  4775. +// that mangchat has in its configuration
  4776. +void IRCClient::Send_IRC_Channels(std::string sMsg)
  4777. +{
  4778. + for(int i=1;i < sIRC._chan_count + 1;i++)
  4779. + Send_IRC_Channel(sIRC._irc_chan[i], sMsg);
  4780. +}
  4781. +
  4782. +// This function is called in ChatHandler.cpp, any channel chat from wow will come
  4783. +// to this function, validates the channel and constructs a message that is send to IRC
  4784. +void IRCClient::Send_WoW_IRC(Player *plr, std::string Channel, std::string Msg)
  4785. +{
  4786. + // Check if the channel exist in our configuration
  4787. + if(Channel_Valid(Channel) && Msg.substr(0, 1) != ".")
  4788. + Send_IRC_Channel(GetIRCChannel(Channel), MakeMsgP(WOW_IRC, Msg, plr));
  4789. +}
  4790. +
  4791. +void IRCClient::Send_WoW_Player(std::string sPlayer, std::string sMsg)
  4792. +{
  4793. + normalizePlayerName(sPlayer);
  4794. + if (Player* plr = ObjectAccessor::Instance().FindPlayerByName(sPlayer.c_str()))
  4795. + Send_WoW_Player(plr, sMsg);
  4796. +}
  4797. +
  4798. +void IRCClient::Send_WoW_Player(Player *plr, string sMsg)
  4799. +{
  4800. + WorldPacket data(SMSG_MESSAGECHAT, 200);
  4801. + ChatHandler::FillMessageData(&data, plr->GetSession(), CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, plr->GetObjectGuid(), sMsg.c_str(), NULL);
  4802. + plr->GetSession()->SendPacket(&data);
  4803. +}
  4804. +
  4805. +// This function will construct and send a packet to all players
  4806. +// on the given channel ingame. (previuosly found in world.cpp)
  4807. +// it loops thru all sessions and checks if they are on the channel
  4808. +// if so construct a packet and send it.
  4809. +void IRCClient::Send_WoW_Channel(const char *channel, std::string chat)
  4810. +{
  4811. + if(!(strlen(channel) > 0))
  4812. + return;
  4813. +
  4814. + // IRC-Protocol does not use a specific character encoding.
  4815. + // TODO: Autoencode to UTF8 (as used in the wow client)
  4816. +
  4817. + HashMapHolder<Player>::MapType& m = ObjectAccessor::Instance().GetPlayers();
  4818. + for(HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
  4819. + {
  4820. + if (itr->second && itr->second->GetSession()->GetPlayer() && itr->second->GetSession()->GetPlayer()->IsInWorld())
  4821. + {
  4822. + if(ChannelMgr* cMgr = channelMgr(itr->second->GetSession()->GetPlayer()->GetTeam()))
  4823. + {
  4824. + if(Channel *chn = cMgr->GetChannel(channel, itr->second->GetSession()->GetPlayer()))
  4825. + {
  4826. + WorldPacket data;
  4827. + ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_CHANNEL, LANG_UNIVERSAL, channel, ObjectGuid(), IRCcol2WoW(chat.c_str()).c_str(), NULL);
  4828. + itr->second->GetSession()->SendPacket(&data);
  4829. + }
  4830. + }
  4831. + }
  4832. + }
  4833. +}
  4834. +
  4835. +void IRCClient::Send_WoW_System(std::string Message)
  4836. +{
  4837. + HashMapHolder<Player>::MapType& m = ObjectAccessor::Instance().GetPlayers();
  4838. + for(HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
  4839. + {
  4840. + if (itr->second && itr->second->GetSession()->GetPlayer() && itr->second->GetSession()->GetPlayer()->IsInWorld())
  4841. + {
  4842. + WorldPacket data;
  4843. + data.Initialize(CHAT_MSG_SYSTEM);
  4844. + data << (uint8)CHAT_MSG_SYSTEM;
  4845. + data << (uint32)LANG_UNIVERSAL;
  4846. + data << (uint64)0;
  4847. + data << (uint32)0;
  4848. + data << (uint64)0;
  4849. + data << (uint32) (strlen(Message.c_str()) + 1);
  4850. + data << Message.c_str();
  4851. + data << (uint8)0;
  4852. + itr->second->GetSession()->SendPacket(&data);
  4853. + }
  4854. + }
  4855. +}
  4856. +void IRCClient::ResetIRC()
  4857. +{
  4858. + SendData("QUIT");
  4859. + Disconnect();
  4860. +}
  4861. +
  4862. +#define CHAT_INVITE_NOTICE 0x18
  4863. +
  4864. +// this function should be called on player login WorldSession::HandlePlayerLogin
  4865. +void IRCClient::AutoJoinChannel(Player *plr)
  4866. +{
  4867. + if(ChannelMgr* cMgr = channelMgr(plr->GetTeam()))
  4868. + {
  4869. + if(Channel *chn = cMgr->GetChannel(sIRC.ajchan,plr))
  4870. + return;
  4871. + }
  4872. +
  4873. + //this will work if at least 1 player is logged in regrdless if he is on the channel or not
  4874. + // the first person that login empty server is the one with bad luck and wont be invited,
  4875. + // if at least 1 player is online the player will be inited to the chanel
  4876. +
  4877. + std::string m_name = sIRC.ajchan;
  4878. + WorldPacket data;
  4879. + data.Initialize(SMSG_CHANNEL_NOTIFY, 1+m_name.size()+1);
  4880. + data << uint8(CHAT_INVITE_NOTICE);
  4881. + data << m_name.c_str();
  4882. +
  4883. + HashMapHolder<Player>::MapType& m = ObjectAccessor::Instance().GetPlayers();
  4884. + for(HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
  4885. + {
  4886. + if (itr->second && itr->second->GetSession()->GetPlayer() && itr->second->GetSession()->GetPlayer()->IsInWorld())
  4887. + {
  4888. + data << itr->second->GetObjectGuid();
  4889. + break;
  4890. + }
  4891. + }
  4892. + plr->GetSession()->SendPacket(&data);
  4893. +}
  4894. diff --git a/src/game/mangchat/IRCLog.cpp b/src/game/mangchat/IRCLog.cpp
  4895. new file mode 100644
  4896. index 0000000..0120627
  4897. --- /dev/null
  4898. +++ b/src/game/mangchat/IRCLog.cpp
  4899. @@ -0,0 +1,74 @@
  4900. +/*
  4901. + * MangChat for MaNGOS, the open source MMORPG-server
  4902. + *
  4903. + * This Program Is Free Software; You Can Redistribute It And/Or Modify It Under The
  4904. + * Terms Of The GNU General Public License
  4905. + *
  4906. + * Written and Developed by Cybrax <cybraxvd@gmail.com>, |Death| <death@hell360.net>,
  4907. + * Lice <lice@yeuxverts.net>, Dj_baby, Sanaell, Tase, Shinzon <shinzon@wowgollum.com>,
  4908. + * Xeross, 3raZar3, the orangevirus team <www.orangevir.us>, ...
  4909. + *
  4910. + * With Help And Support From The MaNGOS Project Community.
  4911. + * PLEASE RETAIN THE COPYRIGHT OF THE AUTHORS.
  4912. + */
  4913. +
  4914. +#include "IRCLog.h"
  4915. +#include "Config/Config.h"
  4916. +#include "IRCClient.h"
  4917. +#include <stdarg.h>
  4918. +
  4919. +IRCLog::IRCLog()
  4920. +{
  4921. + std::string logsDir = sConfig.GetStringDefault("LogsDir","");
  4922. + std::string ircLogName = logsDir + "/IRC_";
  4923. + std::string ircLogTimestamp = GetLogDateStr();
  4924. + ircLogName += ircLogTimestamp +".log";
  4925. + ircLogfile.open (ircLogName.c_str(), std::ios::app);
  4926. +}
  4927. +
  4928. +IRCLog::~IRCLog()
  4929. +{
  4930. + ircLogfile.close();
  4931. +}
  4932. +// Was added because using the time for logs is very annoying... one log per day.. much cleaner looking..
  4933. +std::string IRCLog::GetLogDateStr() const
  4934. +{
  4935. + time_t t = time(NULL);
  4936. + tm* aTm = localtime(&t);
  4937. + // YYYY year
  4938. + // MM month (2 digits 01-12)
  4939. + // DD day (2 digits 01-31)
  4940. + // HH hour (2 digits 00-23)
  4941. + // MM minutes (2 digits 00-59)
  4942. + // SS seconds (2 digits 00-59)
  4943. + char buf[20];
  4944. + snprintf(buf,20,"%04d-%02d-%02d",aTm->tm_year+1900,aTm->tm_mon+1,aTm->tm_mday);
  4945. + return std::string(buf);
  4946. +}
  4947. +
  4948. +std::string IRCLog::GetLogDateTimeStr() const
  4949. +{
  4950. + time_t t = time(NULL);
  4951. + tm* aTm = localtime(&t);
  4952. + // YYYY year
  4953. + // MM month (2 digits 01-12)
  4954. + // DD day (2 digits 01-31)
  4955. + // HH hour (2 digits 00-23)
  4956. + // MM minutes (2 digits 00-59)
  4957. + // SS seconds (2 digits 00-59)
  4958. + char buf[30];
  4959. + 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);
  4960. + return std::string(buf);
  4961. +}
  4962. +
  4963. +void IRCLog::WriteLog(const char *what, ...)
  4964. +{
  4965. + va_list ap;
  4966. + char tmpoutp[1024];
  4967. + va_start(ap, what);
  4968. + vsnprintf(tmpoutp, 1024, what, ap );
  4969. + va_end(ap);
  4970. + ircLogfile << tmpoutp;
  4971. + ircLogfile << "\n";
  4972. + ircLogfile.flush();
  4973. +}
  4974. diff --git a/src/game/mangchat/IRCLog.h b/src/game/mangchat/IRCLog.h
  4975. new file mode 100644
  4976. index 0000000..329d78e
  4977. --- /dev/null
  4978. +++ b/src/game/mangchat/IRCLog.h
  4979. @@ -0,0 +1,36 @@
  4980. +/*
  4981. + * MangChat for MaNGOS, the open source MMORPG-server
  4982. + *
  4983. + * This Program Is Free Software; You Can Redistribute It And/Or Modify It Under The
  4984. + * Terms Of The GNU General Public License
  4985. + *
  4986. + * Written and Developed by Cybrax <cybraxvd@gmail.com>, |Death| <death@hell360.net>,
  4987. + * Lice <lice@yeuxverts.net>, Dj_baby, Sanaell, Tase, Shinzon <shinzon@wowgollum.com>,
  4988. + * Xeross, 3raZar3, the orangevirus team <www.orangevir.us>, ...
  4989. + *
  4990. + * With Help And Support From The MaNGOS Project Community.
  4991. + * PLEASE RETAIN THE COPYRIGHT OF THE AUTHORS.
  4992. + */
  4993. +
  4994. +#ifndef _IRC_LOG_H
  4995. +#define _IRC_LOG_H
  4996. +
  4997. +#include "Common.h"
  4998. +#include <fstream>
  4999. +
  5000. +class IRCLog
  5001. +{
  5002. + public:
  5003. + IRCLog();
  5004. + ~IRCLog();
  5005. +
  5006. + public:
  5007. + void WriteLog(const char *what, ...);
  5008. + std::string GetLogDateStr() const;
  5009. + std::string GetLogDateTimeStr() const;
  5010. + private:
  5011. + std::ofstream ircLogfile;
  5012. +};
  5013. +
  5014. +
  5015. +#endif
  5016. diff --git a/src/game/mangchat/IRCSock.cpp b/src/game/mangchat/IRCSock.cpp
  5017. new file mode 100644
  5018. index 0000000..3090737
  5019. --- /dev/null
  5020. +++ b/src/game/mangchat/IRCSock.cpp
  5021. @@ -0,0 +1,160 @@
  5022. +/*
  5023. + * MangChat for MaNGOS, the open source MMORPG-server
  5024. + *
  5025. + * This Program Is Free Software; You Can Redistribute It And/Or Modify It Under The
  5026. + * Terms Of The GNU General Public License
  5027. + *
  5028. + * Written and Developed by Cybrax <cybraxvd@gmail.com>, |Death| <death@hell360.net>,
  5029. + * Lice <lice@yeuxverts.net>, Dj_baby, Sanaell, Tase, Shinzon <shinzon@wowgollum.com>,
  5030. + * Xeross, 3raZar3, the orangevirus team <www.orangevir.us>, ...
  5031. + *
  5032. + * With Help And Support From The MaNGOS Project Community.
  5033. + * PLEASE RETAIN THE COPYRIGHT OF THE AUTHORS.
  5034. + */
  5035. +
  5036. +#include "IRCClient.h"
  5037. +#define MAXDATASIZE 512
  5038. +#include <fcntl.h>
  5039. +
  5040. +#include <stdio.h>
  5041. +#include <sys/types.h>
  5042. +
  5043. +
  5044. +#define _UNICODE
  5045. +
  5046. +#ifdef _MBCS
  5047. +#undef _MBCS
  5048. +#endif
  5049. +
  5050. +bool IRCClient::InitSock()
  5051. +{
  5052. + #ifdef _WIN32
  5053. + WSADATA wsaData; //WSAData
  5054. + if(WSAStartup(MAKEWORD(2,0),&wsaData) != 0)
  5055. + {
  5056. + sLog.outError("IRC Error: Winsock Initialization Error");
  5057. + return false;
  5058. + }
  5059. + #endif
  5060. + if ((sIRC.SOCKET = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
  5061. + {
  5062. + sLog.outError("IRC Error: Socket Error");
  5063. + return false;
  5064. + }
  5065. + int on = 1;
  5066. + if ( setsockopt ( sIRC.SOCKET, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 )
  5067. + {
  5068. + sLog.outError("IRC Error: Invalid Socket");
  5069. + return false;
  5070. + }
  5071. + #ifdef _WIN32
  5072. + u_long iMode = 0;
  5073. + ioctlsocket(sIRC.SOCKET, FIONBIO, &iMode);
  5074. + #else
  5075. + fcntl(sIRC.SOCKET, F_SETFL, O_NONBLOCK); // set to non-blocking
  5076. + fcntl(sIRC.SOCKET, F_SETFL, O_ASYNC); // set to asynchronous I/O
  5077. + #endif
  5078. + return true;
  5079. +}
  5080. +
  5081. +bool IRCClient::Connect(const char *cHost, int nPort)
  5082. +{
  5083. + sIRC.Connected = false;
  5084. + struct hostent *he;
  5085. + if ((he=gethostbyname(cHost)) == NULL)
  5086. + {
  5087. + sLog.outError("IRCLIENT: Could not resolve host: %s", cHost);
  5088. + return false;
  5089. + }
  5090. + struct sockaddr_in their_addr;
  5091. + their_addr.sin_family = AF_INET;
  5092. + their_addr.sin_port = htons(nPort);
  5093. + their_addr.sin_addr = *((struct in_addr *)he->h_addr);
  5094. + memset(&(their_addr.sin_zero), '\0', 8);
  5095. + if (::connect(sIRC.SOCKET, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1)
  5096. + {
  5097. + sLog.outError("IRCLIENT: Cannot connect to %s", cHost);
  5098. + return false;
  5099. + }
  5100. + //FD_ZERO(&sIRC.sfdset);
  5101. + //FD_SET(sIRC.SOCKET,&sIRC.sfdset);
  5102. + sIRC.Connected = true;
  5103. + return true;
  5104. +}
  5105. +
  5106. +bool IRCClient::Login(std::string sNick, std::string sUser, std::string sPass)
  5107. +{
  5108. + char hostname[128];
  5109. + gethostname(hostname, sizeof(hostname));
  5110. + if(SendIRC("HELLO"))
  5111. + if(SendIRC("PASS " + sPass))
  5112. + if(SendIRC("NICK " + sNick))
  5113. + if(SendIRC("USER " + sUser + " " + (std::string)hostname + " MangChat :MangChat "+sIRC._Mver.c_str()))
  5114. + return true;
  5115. + return false;
  5116. +}
  5117. +
  5118. +bool IRCClient::SendData(const char *data)
  5119. +{
  5120. + if(sIRC.Connected)
  5121. + {
  5122. + if (send(sIRC.SOCKET, data, strlen(data), 0) == -1)
  5123. + {
  5124. + sLog.outError("IRC Error: Socket Receieve ** \n");
  5125. + //Disconnect();
  5126. + return false;
  5127. + }
  5128. + }
  5129. + return true;
  5130. +}
  5131. +
  5132. +bool IRCClient::SendIRC(std::string data)
  5133. +{
  5134. + std::string RealData = data + "\n";
  5135. + return SendData(RealData.c_str());
  5136. +}
  5137. +
  5138. +void IRCClient::Disconnect()
  5139. +{
  5140. + if(sIRC.SOCKET)
  5141. + {
  5142. + #ifdef _WIN32
  5143. + closesocket(sIRC.SOCKET);
  5144. + //WSACleanup();
  5145. + #else
  5146. + close(sIRC.SOCKET);
  5147. + #endif
  5148. + }
  5149. +}
  5150. +
  5151. +void IRCClient::SockRecv()
  5152. +{
  5153. +// wchar_t bufferdata;
  5154. +
  5155. + char szBuffer[MAXDATASIZE];
  5156. +
  5157. + memset(szBuffer, 0, MAXDATASIZE );
  5158. +
  5159. + int nBytesRecv = ::recv(sIRC.SOCKET, szBuffer, MAXDATASIZE - 1, 0 );
  5160. + if ( nBytesRecv == -1 )
  5161. + {
  5162. + sLog.outError("Connection lost.");
  5163. + sIRC.Connected = false;
  5164. + }
  5165. + else
  5166. + {
  5167. + if (-1 == nBytesRecv)
  5168. + {
  5169. + sLog.outError("Error occurred while receiving from socket.");
  5170. + }
  5171. + else
  5172. + {
  5173. + std::string reply;
  5174. + std::istringstream iss(szBuffer);
  5175. + while(getline(iss, reply))
  5176. + {
  5177. + Handle_IRC(reply);
  5178. + }
  5179. + }
  5180. + }
  5181. +}
  5182. diff --git a/src/game/mangchat/MCS_OnlinePlayers.cpp b/src/game/mangchat/MCS_OnlinePlayers.cpp
  5183. new file mode 100644
  5184. index 0000000..203d962
  5185. --- /dev/null
  5186. +++ b/src/game/mangchat/MCS_OnlinePlayers.cpp
  5187. @@ -0,0 +1,83 @@
  5188. +/*
  5189. + * MangChat for MaNGOS, the open source MMORPG-server
  5190. + *
  5191. + * This Program Is Free Software; You Can Redistribute It And/Or Modify It Under The
  5192. + * Terms Of The GNU General Public License
  5193. + *
  5194. + * Written and Developed by Cybrax <cybraxvd@gmail.com>, |Death| <death@hell360.net>,
  5195. + * Lice <lice@yeuxverts.net>, Dj_baby, Sanaell, Tase, Shinzon <shinzon@wowgollum.com>,
  5196. + * Xeross, 3raZar3, the orangevirus team <www.orangevir.us>, ...
  5197. + *
  5198. + * With Help And Support From The MaNGOS Project Community.
  5199. + * PLEASE RETAIN THE COPYRIGHT OF THE AUTHORS.
  5200. + */
  5201. +
  5202. +#include "MCS_OnlinePlayers.h"
  5203. +
  5204. +#include "../MapManager.h"
  5205. +#include "../ObjectMgr.h"
  5206. +#include "../../shared/Config/Config.h"
  5207. +
  5208. +mcs_OnlinePlayers::mcs_OnlinePlayers() { CD = NULL; }
  5209. +
  5210. +mcs_OnlinePlayers::mcs_OnlinePlayers(_CDATA *_CD)
  5211. +{
  5212. + //create a new instance of data struct and copy its data
  5213. + CD = new _CDATA();
  5214. + CD->CMD = _CD->CMD;
  5215. + CD->FROM = _CD->FROM;
  5216. + CD->PARAMS = _CD->PARAMS;
  5217. + CD->PCOUNT = _CD->PCOUNT;
  5218. + CD->USER = _CD->USER;
  5219. + CD->TYPE = _CD->TYPE;
  5220. +}
  5221. +
  5222. +mcs_OnlinePlayers::~mcs_OnlinePlayers()
  5223. +{
  5224. + if(CD)
  5225. + delete CD;
  5226. +}
  5227. +
  5228. +void mcs_OnlinePlayers::run()
  5229. +{
  5230. + int OnlineCount = 0;
  5231. + std::string IRCOut = "";
  5232. + HashMapHolder<Player>::MapType& m = ObjectAccessor::Instance().GetPlayers();
  5233. + for(HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
  5234. + {
  5235. + if (itr->second && itr->second->GetSession()->GetPlayer() && itr->second->GetSession()->GetPlayer()->IsInWorld())
  5236. + {
  5237. + OnlineCount++;
  5238. + Player *plr = itr->second->GetSession()->GetPlayer();
  5239. + std::string ChatTag = " ";
  5240. +
  5241. + uint16 gmLevel = plr->GetSession()->GetSecurity();
  5242. + ChatTag.append("\0037"+sIRC.ojGM[ gmLevel < SEC_CONSOLE ? gmLevel : SEC_CONSOLE]);
  5243. +
  5244. + if(plr->isAFK())
  5245. + ChatTag.append("\002\0037<AFK>\003\002");
  5246. + else if(plr->isDND())
  5247. + ChatTag.append("\002\0037<DND>\003\002");
  5248. + switch (plr->GetTeam())
  5249. + {
  5250. + case 67:ChatTag.append("\0034");break; //horde
  5251. + case 469:ChatTag.append("\00312");break; //alliance
  5252. + }
  5253. +
  5254. + IRCOut.append(IRCCmd::MakeMsg("%s\002%s\003\017\002(%d)\002\017", ChatTag.c_str(), plr->GetName(), plr->getLevel()));
  5255. +
  5256. + // after XX players have been added to the string
  5257. + // output to irc and reset for the next XX
  5258. + if(OnlineCount % sIRC.onlrslt == 0)
  5259. + {
  5260. + sIRC.Send_IRC_Channel(IRCCmd::ChanOrPM(CD), IRCCmd::MakeMsg("\002 %s", IRCOut.c_str()), true, CD->TYPE.c_str());
  5261. + IRCOut = "";
  5262. + ACE_Based::Thread::Sleep(1000);
  5263. + }
  5264. + }
  5265. + }
  5266. + // Remainder in IRCOUT && Total plyersonline
  5267. + sIRC.Send_IRC_Channel(IRCCmd::ChanOrPM(CD), IRCCmd::MakeMsg("\002Players Online(%d):\017 %s", OnlineCount, IRCOut.c_str()), true, CD->TYPE);
  5268. +
  5269. + sIRC.Script_Lock[MCS_Players_Online] = false;
  5270. +}
  5271. diff --git a/src/game/mangchat/MCS_OnlinePlayers.h b/src/game/mangchat/MCS_OnlinePlayers.h
  5272. new file mode 100644
  5273. index 0000000..17f3610
  5274. --- /dev/null
  5275. +++ b/src/game/mangchat/MCS_OnlinePlayers.h
  5276. @@ -0,0 +1,41 @@
  5277. +/*
  5278. + * MangChat for MaNGOS, the open source MMORPG-server
  5279. + *
  5280. + * This Program Is Free Software; You Can Redistribute It And/Or Modify It Under The
  5281. + * Terms Of The GNU General Public License
  5282. + *
  5283. + * Written and Developed by Cybrax <cybraxvd@gmail.com>, |Death| <death@hell360.net>,
  5284. + * Lice <lice@yeuxverts.net>, Dj_baby, Sanaell, Tase, Shinzon <shinzon@wowgollum.com>,
  5285. + * Xeross, 3raZar3, the orangevirus team <www.orangevir.us>, ...
  5286. + *
  5287. + * With Help And Support From The MaNGOS Project Community.
  5288. + * PLEASE RETAIN THE COPYRIGHT OF THE AUTHORS.
  5289. + */
  5290. +
  5291. +#ifndef _IRC_CLIENT_ONLINE
  5292. +#define _IRC_CLIENT_ONLINE
  5293. +
  5294. +#include "IRCClient.h"
  5295. +#include "IRCCmd.h"
  5296. +
  5297. +// the reason to run this command multithreaded
  5298. +// is to be able to "spread" the output over irc
  5299. +// for servers with high player count
  5300. +// in order not to freeze the mangchat core with sleep
  5301. +// a new thread is spawned it will output the player data
  5302. +// evry "10 players" and pauzes to not spam irc
  5303. +// in addition the command is locked so it cannot be used
  5304. +// while active.
  5305. +
  5306. +class mcs_OnlinePlayers : public ACE_Based::Runnable
  5307. +{
  5308. + public:
  5309. + mcs_OnlinePlayers();
  5310. + mcs_OnlinePlayers(_CDATA *_CD);
  5311. + ~mcs_OnlinePlayers();
  5312. + void run();
  5313. + public:
  5314. + _CDATA *CD;
  5315. +};
  5316. +
  5317. +#endif
  5318. diff --git a/src/game/mangchat/mangchat.conf.dist.in b/src/game/mangchat/mangchat.conf.dist.in
  5319. new file mode 100644
  5320. index 0000000..2ad7312
  5321. --- /dev/null
  5322. +++ b/src/game/mangchat/mangchat.conf.dist.in
  5323. @@ -0,0 +1,204 @@
  5324. +##################################################
  5325. +# MangChat IRC BOT FOR MaNGOS Configuration File #
  5326. +##################################################
  5327. +
  5328. +[MangchatConf]
  5329. +
  5330. +###################################################################################################################
  5331. +# irc.active
  5332. +# Enable MangChat Addon
  5333. +# Default: 1 - Enable
  5334. +# 0 - Disable
  5335. +###################################################################################################################
  5336. +
  5337. +irc.active = 1
  5338. +
  5339. +###################################################################################################################
  5340. +# Botmask
  5341. +# This defines what the bot announces, if its 0 everything is disabled
  5342. +# simply add the values of the elements you want to create this mask.
  5343. +# Example: WoW join/leaves are 1 and IRC join/leaves are 2, if you want both of these active then the BotMask is 3.
  5344. +# (1)Display WoW Chan Join/Leaves In IRC
  5345. +# (2)Display IRC Chan Join/Leaves/NickChanges In WoW
  5346. +# (4)Display Unknown Command Message When Trigger Is Used And No Command Exists
  5347. +# (8)Announce Security Level > 0 As GM At Login
  5348. +# (16)Announce GM In GM ON State AS GM At Login
  5349. +# (32)Return Errors To Notice. (If disabled then default is Private Message)
  5350. +# (64)Display WoW Status Messages (Levels/Deaths)
  5351. +# (128)Display Nick Changes From IRC In WOW
  5352. +# (256)Display WoW Announces/Notifies In IRC
  5353. +# (512)Do Not Let Players Use Commands On Higher GM Level Players
  5354. +# (1024)Enable AuctionHouse Announcements
  5355. +###################################################################################################################
  5356. +
  5357. +Botmask = 1023
  5358. +
  5359. +###################################################################################################################
  5360. +# irc.host
  5361. +# IRC server to have MangChat connect to
  5362. +# irc.port
  5363. +# IRC server port to use
  5364. +# irc.user
  5365. +# The username to have MangChat use to connect to the IRC server
  5366. +# irc.nick
  5367. +# IRC nickname to be used by the bot
  5368. +# irc.pass
  5369. +# The password to be used to identify to NickServ (IRC NickName Enforcement Services)
  5370. +###################################################################################################################
  5371. +
  5372. +irc.host = "irc.freenode.net"
  5373. +irc.port = "6667"
  5374. +irc.user = "MangChat"
  5375. +irc.nick = "MangChat"
  5376. +irc.pass = "MyDumbPass"
  5377. +
  5378. +###################################################################################################################
  5379. +# irc.icc
  5380. +# IRC connect code
  5381. +# Default: 001 - Welcome To Network msg
  5382. +# 375 - Beginning Of MOTD
  5383. +# 376 - End Of MOTD
  5384. +# irc.auth
  5385. +# IRC Authentication Method
  5386. +# Default: 0 - Disable
  5387. +# 1 - NickServ - Normal Method - PRIVMSG NickServ :IDENTIFY Password
  5388. +# 2 - NickServ - Alternate Method To Identify To A Different Nick - PRIVMSG NickServ :IDENTIFY irc.auth.nick Password
  5389. +# 3 - QuakeNet - Normal Method - PRIVMSG Q@CServe.quakenet.org :AUTH irc.nick Password
  5390. +# 4 - QuakeNet - Alternate Method To Identify To A Different Nick - PRIVMSG Q@CServe.quakenet.org :AUTH irc.auth.nick Password
  5391. +# irc.auth.nick
  5392. +# IRC Nickname to use if Auth method 2 or 4 is used
  5393. +###################################################################################################################
  5394. +
  5395. +irc.icc = 001
  5396. +irc.auth = 1
  5397. +irc.auth.nick = "AuthNick"
  5398. +
  5399. +###################################################################################################################
  5400. +# irc.ldef
  5401. +# Leave a defined IRC channel on server connect
  5402. +# Default: 0 - Disable
  5403. +# 1 - Enable
  5404. +# irc.defchan
  5405. +# IRC channel to leave on server connect if irc.ldef is on
  5406. +# irc.wct
  5407. +# Time to wait before (re)attemptimg connection to IRC server
  5408. +# Default: 30000 - (30 Seconds)
  5409. +# irc.maxattempt
  5410. +# Maximum attempts to try IRC server
  5411. +# Default: 20
  5412. +# irc.auto.announce
  5413. +# Time to wait in Minutes to announce random messages from database.
  5414. +# Default: 30 - (30 Minutes)
  5415. +# irc.autojoin_kick
  5416. +# Autojoin IRC channel if kicked
  5417. +# Default: 1 - Enable
  5418. +# 0 - Disable
  5419. +# irc.command_prefix
  5420. +# IRC command prefix
  5421. +# Example: (.)online all
  5422. +###################################################################################################################
  5423. +
  5424. +irc.ldef = 0
  5425. +irc.defchan = "lobby"
  5426. +irc.wct = 30000
  5427. +irc.maxattempt = 20
  5428. +irc.auto.announce = 30
  5429. +irc.autojoin_kick = 1
  5430. +irc.command_prefix = "."
  5431. +
  5432. +###################################################################################################################
  5433. +# irc.joinmsg
  5434. +# irc.rstmsg
  5435. +# irc.kickmsg
  5436. +# MangChat bot join/restart/kick messages
  5437. +###################################################################################################################
  5438. +
  5439. +irc.joinmsg = "Whhaaazzzzaaaa, MangChat $Ver Is Up And Running! Command Trigger Is: $Trigger"
  5440. +irc.rstmsg = "MangChat Is Restarting, I Will Be Right Back!!"
  5441. +irc.kickmsg = "Do Not Kick Me Again, Severe Actions Will Be Taken!"
  5442. +
  5443. +###################################################################################################################
  5444. +# irc.chan_#
  5445. +# wow.chan_#
  5446. +# IRC and WOW channels to link. Leave # out of IRC channel. Both channels _ARE_ case sensitive
  5447. +# Example: irc.chan_1 = "Mangos"
  5448. +# irc.chan_2 = "mangos2"
  5449. +# wow.chan_1 = "world"
  5450. +# wow.chan_2 = "LookingForGroup"
  5451. +###################################################################################################################
  5452. +
  5453. +irc.chan_1 = "mangos"
  5454. +wow.chan_1 = "world"
  5455. +
  5456. +###################################################################################################################
  5457. +# irc.StatusChannel
  5458. +# Channel Number To Display Status Messages In (AuctionHouse, Levels, Deaths, Etc)
  5459. +# Default: 1 - Channel ID 1
  5460. +# irc.AnnounceChannel
  5461. +# Channel Number To Display Announcements In (Announces, Notifies, Event)
  5462. +# Default: 1 - Channel ID 1
  5463. +# irc.op_gm_login
  5464. +# Op The GM In All Channels The Bot Is On When They Log In To MangChat
  5465. +# Default: 0 - Disable
  5466. +# 1 - Enable
  5467. +# irc.op_gm_level
  5468. +# The Minimum GM Level Required To Have The Bot Op The User
  5469. +# Default: 5 - GM Level 5
  5470. +# irc.online.result
  5471. +# Maximum number of results per line for the online command
  5472. +# irc.gmlog
  5473. +# Minimum GM level to not show login/pass info in IRC logs
  5474. +# irc.logfile.prefix
  5475. +# The prefix of the IRC logfile. Directories can be added here.
  5476. +# Example: "IRC/IRC_" outputs IRC_YYYY-MM-DD.log to the IRC subdirectory in your logs dir
  5477. +# irc.fun.games (Experimental/Under Development)
  5478. +# Enable MangChat Games
  5479. +# Default: 0 - Disable
  5480. +# 1 - Enable
  5481. +# irc.gm#
  5482. +# GM tag to append to (GM onjoin / online command) IRC color codes are acceptable
  5483. +###################################################################################################################
  5484. +
  5485. +irc.StatusChannel = 1
  5486. +irc.AnnounceChannel = 1
  5487. +irc.op_gm_login = 0
  5488. +irc.op_gm_level = 3
  5489. +irc.online.result = 30
  5490. +irc.gmlog = 1
  5491. +irc.logfile.prefix = "IRC_"
  5492. +irc.fun.games = 0
  5493. +irc.gm1 = "[Moderator]"
  5494. +irc.gm2 = "[Game Master]"
  5495. +irc.gm3 = "[BugTracker]"
  5496. +irc.gm4 = "[Developer]"
  5497. +irc.gm5 = "[Group Leader]"
  5498. +irc.gm6 = "[Administrator]"
  5499. +irc.gm7 = "[SysOP]"
  5500. +
  5501. +###################################################################################################################
  5502. +# irc.ajoin (Experimental/Under Development)
  5503. +# Force players to autojoin a WOW in game channel
  5504. +# Atleast one player must be in the channel on server start, and atleast one person online for invite to work
  5505. +# Default: 0 - Disable
  5506. +# 1 - Enable
  5507. +# irc.ajchan
  5508. +# Channel to join if above is Enabled.
  5509. +###################################################################################################################
  5510. +
  5511. +irc.ajoin = 1
  5512. +irc.ajchan = "world"
  5513. +
  5514. +###################################################################################################################
  5515. +# chat.*** (Defineable Strings) (maybe more in future)
  5516. +# wow_* - String is displayed in IRC channel
  5517. +# irc_* - String is displayed in WOW channel
  5518. +# Options: $Name, $Level, $Msg, $GM (not all options work in every string)
  5519. +###################################################################################################################
  5520. +
  5521. +chat.wow_irc = "<WoW>[$Name($Level)] $Msg"
  5522. +chat.irc_wow = "<IRC>[$Name]: $Msg"
  5523. +chat.join_wow = "12>>04 $GM$Name Joined The $Channel Channel!"
  5524. +chat.join_irc = "[$Name]: Has Joined IRC!"
  5525. +chat.leave_wow = "12<<04 $GM$Name Left The $Channel Channel!"
  5526. +chat.leave_irc = "[$Name]: Has Left IRC!"
  5527. +chat.change_nick = "<> $Name Is Now Known As $NewName!"
  5528. diff --git a/src/mangosd/Main.cpp b/src/mangosd/Main.cpp
  5529. index c53d476..e6b2275 100644
  5530. --- a/src/mangosd/Main.cpp
  5531. +++ b/src/mangosd/Main.cpp
  5532. @@ -27,6 +27,8 @@
  5533. #include "Log.h"
  5534. #include "Master.h"
  5535. #include "SystemConfig.h"
  5536. +#include "../game/mangchat/IRCConf.h"
  5537. +#include "../game/mangchat/IRCClient.h"
  5538. #include "AuctionHouseBot/AuctionHouseBot.h"
  5539. #include "revision.h"
  5540. #include "revision_nr.h"
  5541. @@ -70,6 +72,7 @@ void usage(const char *prog)
  5542. " -s run run as service\n\r"
  5543. " -s install install service\n\r"
  5544. " -s uninstall uninstall service\n\r"
  5545. + " -m MangChat_config use Mangchat_config as configuration file for MangChat\n\r"
  5546. #else
  5547. " Running as daemon functions:\n\r"
  5548. " -s run run as daemon\n\r"
  5549. @@ -83,9 +86,9 @@ extern int main(int argc, char **argv)
  5550. {
  5551. ///- Command line parsing
  5552. char const* cfg_file = _MANGOSD_CONFIG;
  5553. + char const* mc_cfg_file = _MANGCHAT_CONFIG;
  5554.  
  5555. -
  5556. - char const *options = ":a:c:s:";
  5557. + char const *options = ":a:c:m:s:";
  5558.  
  5559. ACE_Get_Opt cmd_opts(argc, argv, options);
  5560. cmd_opts.long_option("version", 'v', ACE_Get_Opt::NO_ARG);
  5561. @@ -104,6 +107,9 @@ extern int main(int argc, char **argv)
  5562. case 'c':
  5563. cfg_file = cmd_opts.opt_arg();
  5564. break;
  5565. + case 'm':
  5566. + mc_cfg_file = cmd_opts.opt_arg();
  5567. + break;
  5568. case 'v':
  5569. printf("%s\n", _FULLVERSION(REVISION_NR));
  5570. printf("%s\n", _R2FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_R2,REVISION_ID));
  5571. @@ -181,6 +187,8 @@ extern int main(int argc, char **argv)
  5572. }
  5573. #endif
  5574.  
  5575. + sIRC.SetCfgFile(mc_cfg_file);
  5576. +
  5577. sLog.outString( "%s [world-daemon]", _FULLVERSION(REVISION_NR) );
  5578. sLog.outString( "%s [world-daemon]", _R2FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_R2,REVISION_ID) );
  5579. sLog.outString( "<Ctrl-C> to stop." );
  5580. diff --git a/src/mangosd/Master.cpp b/src/mangosd/Master.cpp
  5581. index 6c8707c..0d47e46 100644
  5582. --- a/src/mangosd/Master.cpp
  5583. +++ b/src/mangosd/Master.cpp
  5584. @@ -42,6 +42,7 @@
  5585. #include "Util.h"
  5586. #include "revision_sql.h"
  5587. #include "MaNGOSsoap.h"
  5588. +#include "mangchat/IRCClient.h"
  5589. #include "MassMailMgr.h"
  5590. #include "DBCStores.h"
  5591.  
  5592. @@ -203,6 +204,9 @@ int Master::Run()
  5593. return 1;
  5594. }
  5595.  
  5596. + // Load Mangchat Config (MangChat needs DB for gm levels, AutoBroadcast uses world timers)
  5597. + sIRC.LoadConfig();
  5598. +
  5599. ///- Initialize the World
  5600. sWorld.SetInitialWorldSettings();
  5601.  
  5602. @@ -302,6 +306,10 @@ int Master::Run()
  5603. soap_thread = new ACE_Based::Thread(runnable);
  5604. }
  5605.  
  5606. + //Start up MangChat
  5607. + ACE_Based::Thread irc(new IRCClient);
  5608. + irc.setPriority (ACE_Based::High);
  5609. +
  5610. ///- Start up freeze catcher thread
  5611. ACE_Based::Thread* freeze_thread = NULL;
  5612. if(uint32 freeze_delay = sConfig.GetIntDefault("MaxCoreStuckTime", 0))
  5613. diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj
  5614. index d13999f..f56a8f5 100644
  5615. --- a/win/VC90/game.vcproj
  5616. +++ b/win/VC90/game.vcproj
  5617. @@ -1983,6 +1983,66 @@
  5618. >
  5619. </File>
  5620. </Filter>
  5621. + <Filter
  5622. + Name="IRC"
  5623. + >
  5624. + <File
  5625. + RelativePath="..\..\src\game\mangchat\IRCClient.cpp"
  5626. + >
  5627. + </File>
  5628. + <File
  5629. + RelativePath="..\..\src\game\mangchat\IRCClient.h"
  5630. + >
  5631. + </File>
  5632. + <File
  5633. + RelativePath="..\..\src\game\mangchat\IRCCmd.cpp"
  5634. + >
  5635. + </File>
  5636. + <File
  5637. + RelativePath="..\..\src\game\mangchat\IRCCmd.h"
  5638. + >
  5639. + </File>
  5640. + <File
  5641. + RelativePath="..\..\src\game\mangchat\IRCCmde.cpp"
  5642. + >
  5643. + </File>
  5644. + <File
  5645. + RelativePath="..\..\src\game\mangchat\IRCConf.cpp"
  5646. + >
  5647. + </File>
  5648. + <File
  5649. + RelativePath="..\..\src\game\mangchat\IRCConf.h"
  5650. + >
  5651. + </File>
  5652. + <File
  5653. + RelativePath="..\..\src\game\mangchat\IRCFunc.h"
  5654. + >
  5655. + </File>
  5656. + <File
  5657. + RelativePath="..\..\src\game\mangchat\IRCIO.cpp"
  5658. + >
  5659. + </File>
  5660. + <File
  5661. + RelativePath="..\..\src\game\mangchat\IRCLog.cpp"
  5662. + >
  5663. + </File>
  5664. + <File
  5665. + RelativePath="..\..\src\game\mangchat\IRCLog.h"
  5666. + >
  5667. + </File>
  5668. + <File
  5669. + RelativePath="..\..\src\game\mangchat\IRCSock.cpp"
  5670. + >
  5671. + </File>
  5672. + <File
  5673. + RelativePath="..\..\src\game\mangchat\MCS_OnlinePlayers.cpp"
  5674. + >
  5675. + </File>
  5676. + <File
  5677. + RelativePath="..\..\src\game\mangchat\MCS_OnlinePlayers.h"
  5678. + >
  5679. + </File>
  5680. + </Filter>
  5681. <File
  5682. RelativePath="..\..\src\game\pchdef.cpp"
  5683. >
  5684. --
  5685. 1.7.2.5
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement