[2595] Applied MaNGOS coding style (see trunk/bcpp.cfg).
[mangos-git.git] / src / game / MiscHandler.cpp
blobf1add8250dce10639ccd0fa4166fdb77b4f2abd6
1 /*
2 * Copyright (C) 2005,2006 MaNGOS <http://www.mangosproject.org/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Common.h"
20 #include "Database/DatabaseEnv.h"
21 #include "WorldPacket.h"
22 #include "Opcodes.h"
23 #include "Log.h"
24 #include "Player.h"
25 #include "World.h"
26 #include "ObjectMgr.h"
27 #include "WorldSession.h"
28 #include "Auth/BigNumber.h"
29 #include "Auth/Sha1.h"
30 #include "UpdateData.h"
31 #include "LootMgr.h"
32 #include "Chat.h"
33 #include "ScriptCalls.h"
34 #include <zlib/zlib.h>
35 #include "MapManager.h"
36 #include "ObjectAccessor.h"
37 #include "Object.h"
38 #include "BattleGround.h"
39 #include "SpellAuras.h"
41 void WorldSession::HandleRepopRequestOpcode( WorldPacket & recv_data )
43 sLog.outDebug( "WORLD: Recvd CMSG_REPOP_REQUEST Message" );
45 if(GetPlayer()->isAlive()||GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
46 return;
48 GetPlayer()->BuildPlayerRepop();
49 GetPlayer()->RepopAtGraveyard();
52 void WorldSession::HandleWhoOpcode( WorldPacket & recv_data )
54 uint32 clientcount = 0;
55 WorldPacket data;
57 sLog.outDebug( "WORLD: Recvd CMSG_WHO Message" );
59 uint32 team = _player->GetTeam();
60 uint32 security = GetSecurity();
61 bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
63 data.Initialize( SMSG_WHO );
64 data << uint32( 0 ); // clientcount place holder
65 data << uint32( 0 ); // clientcount place holder
67 ObjectAccessor::PlayersMapType &m(ObjectAccessor::Instance().GetPlayers());
68 for(ObjectAccessor::PlayersMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
70 // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
71 // MODERATOR, GAME MASTER, ADMINISTRATOR can see all
72 if ( itr->second->GetName() && ( security > 0 || ( itr->second->GetTeam() == team || allowTwoSideWhoList ) && itr->second->GetSession()->GetSecurity() == 0 ) )
74 clientcount++;
76 data.append(itr->second->GetName() , strlen(itr->second->GetName()) + 1);
77 if(itr->second->GetGuildId()) // in fact just could use objmgr.GetGuildNameById(itr->second->GetGuildId()) cause getguildid() returns 0 with no guild and getguildnamebyid "" which equals uint8(0)
78 data << objmgr.GetGuildNameById(itr->second->GetGuildId());
79 else
80 data << uint8( 0 );
81 data << uint32( itr->second->getLevel() );
82 data << uint32( itr->second->getClass() );
83 data << uint32( itr->second->getRace() );
84 data << uint32( itr->second->GetZoneId() );
88 data.put( 0, clientcount ); //insert right count
89 data.put( sizeof(uint32), clientcount ); //insert right count
91 SendPacket(&data);
92 sLog.outDebug( "WORLD: Send SMSG_WHO Message" );
95 void WorldSession::HandleLogoutRequestOpcode( WorldPacket & recv_data )
97 WorldPacket data;
98 Player* Target = GetPlayer();
100 uint32 security = Target->GetSession()->GetSecurity();
102 sLog.outDebug( "WORLD: Recvd CMSG_LOGOUT_REQUEST Message, security - %u", security );
104 //instant logout for admins, gm's, mod's
105 if (security > 0)
107 LogoutRequest(0);
108 LogoutPlayer(true);
109 return;
112 //Can not logout if...
113 if( Target->isInCombat() || //...is in combat
114 Target->isInDuel() || //...is in Duel
115 //...is jumping ...is falling
116 Target->HasMovementFlags( MOVEMENT_JUMPING | MOVEMENT_FALLING ))
118 data.Initialize( SMSG_LOGOUT_RESPONSE );
119 data << (uint8)0xC;
120 data << uint32(0);
121 data << uint8(0);
122 SendPacket( &data );
123 LogoutRequest(0);
124 return;
127 //instant logout in taverns/cities
128 if(Target->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING))
130 LogoutRequest(0);
131 LogoutPlayer(true);
132 return;
135 // not set flags if flight - must continue move until exit, not saved anyway.
136 if(!GetPlayer()->isInFlight())
138 Target->SetFlag(UNIT_FIELD_BYTES_1,PLAYER_STATE_SIT);
140 data.Initialize( SMSG_FORCE_MOVE_ROOT );
141 data << (uint8)0xFF << Target->GetGUID() << (uint32)2;
142 SendPacket( &data );
143 Target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
146 data.Initialize( SMSG_LOGOUT_RESPONSE );
147 data << uint32(0);
148 data << uint8(0);
149 SendPacket( &data );
150 LogoutRequest(time(NULL));
154 void WorldSession::HandlePlayerLogoutOpcode( WorldPacket & recv_data )
156 sLog.outDebug( "WORLD: Recvd CMSG_PLAYER_LOGOUT Message" );
159 void WorldSession::HandleLogoutCancelOpcode( WorldPacket & recv_data )
161 WorldPacket data;
163 sLog.outDebug( "WORLD: Recvd CMSG_LOGOUT_CANCEL Message" );
165 LogoutRequest(0);
167 data.Initialize( SMSG_LOGOUT_CANCEL_ACK );
168 SendPacket( &data );
170 // not remove flags if flight - its not setted in Logout request code.
171 if(!GetPlayer()->isInFlight())
173 //!we can move again
174 data.Initialize( SMSG_FORCE_MOVE_UNROOT );
175 data << (uint8)0xFF << GetPlayer()->GetGUID();
176 SendPacket( &data );
178 //! Stand Up
179 //! Removes the flag so player stands
180 GetPlayer()->RemoveFlag(UNIT_FIELD_BYTES_1,PLAYER_STATE_SIT);
182 //! DISABLE_ROTATE
183 GetPlayer()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
186 sLog.outDebug( "WORLD: sent SMSG_LOGOUT_CANCEL_ACK Message" );
189 void WorldSession::SendGMTicketGetTicket(uint32 status, char const* text)
191 int len = text ? strlen(text) : 0;
192 WorldPacket data;
193 data.Initialize( SMSG_GMTICKET_GETTICKET );
194 data << uint32(6);
195 if(len > 0)
196 data.append((uint8 *)text,len+1);
197 else
198 data << uint32(0);
199 SendPacket( &data );
202 void WorldSession::HandleGMTicketGetTicketOpcode( WorldPacket & recv_data )
204 WorldPacket data;
205 data.Initialize( SMSG_QUERY_TIME_RESPONSE );
206 // data << (uint32)20;
207 data << (uint32)getMSTime();
208 SendPacket( &data );
210 uint64 guid;
211 Field *fields;
212 guid = GetPlayer()->GetGUID();
214 QueryResult *result = sDatabase.PQuery("SELECT COUNT(`ticket_id`) FROM `character_ticket` WHERE `guid` = '%u'", GUID_LOPART(guid));
216 if (result)
218 int cnt;
219 fields = result->Fetch();
220 cnt = fields[0].GetUInt32();
221 delete result;
223 if ( cnt > 0 )
225 QueryResult *result2 = sDatabase.PQuery("SELECT `ticket_text` FROM `character_ticket` WHERE `guid` = '%u'", GUID_LOPART(guid));
226 assert(result2);
227 Field *fields2 = result2->Fetch();
229 SendGMTicketGetTicket(6,fields2[0].GetString());
230 delete result2;
232 else
233 SendGMTicketGetTicket(1,0);
237 void WorldSession::HandleGMTicketUpdateTextOpcode( WorldPacket & recv_data )
239 WorldPacket data;
240 uint32 guid = GetPlayer()->GetGUIDLow();
241 std::string ticketText = "";
242 uint8 buf[516];
243 memcpy( buf, recv_data.contents(), sizeof buf <recv_data.size() ? sizeof buf : recv_data.size() );
245 ticketText = (char *)buf + 1;
246 sDatabase.escape_string(ticketText);
247 sDatabase.PExecute("UPDATE `character_ticket` SET `ticket_text` = '%s' WHERE `guid` = '%u'", ticketText.c_str(), guid);
251 void WorldSession::HandleGMTicketDeleteOpcode( WorldPacket & recv_data )
253 WorldPacket data;
254 uint32 guid = GetPlayer()->GetGUIDLow();
256 sDatabase.PExecute("DELETE FROM `character_ticket` WHERE `guid` = '%u' LIMIT 1",guid);
258 data.Initialize( SMSG_GMTICKET_DELETETICKET );
259 data << uint32(1);
260 data << uint32(0);
261 SendPacket( &data );
263 SendGMTicketGetTicket(1,0);
266 void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data )
269 WorldPacket data;
270 uint32 guid;
271 guid = GetPlayer()->GetGUIDLow();
272 std::string ticketText = "";
273 Field *fields;
274 uint8 buf[516];
275 uint32 cat[] = { 0,5,1,2,0,6,4,7,0,8,3 };
276 memcpy( buf, recv_data.contents(), sizeof buf < recv_data.size() ? sizeof buf : recv_data.size() );
277 buf[272] = 0;
279 ticketText = (char *)buf + 17;
280 sDatabase.escape_string(ticketText);
282 QueryResult *result = sDatabase.PQuery("SELECT COUNT(*) FROM `character_ticket` WHERE `guid` = '%u'",guid);
284 if (result)
286 int cnt;
287 fields = result->Fetch();
288 cnt = fields[0].GetUInt32();
289 delete result;
291 if ( cnt > 0 )
293 data.Initialize( SMSG_GMTICKET_CREATE );
294 data << uint32(1);
295 SendPacket( &data );
297 else
300 sDatabase.PExecute("INSERT INTO `character_ticket` (`guid`,`ticket_text`,`ticket_category`) VALUES ('%u', '%s', '%u')", guid, ticketText.c_str(), cat[buf[0]]);
302 data.Initialize( SMSG_QUERY_TIME_RESPONSE );
303 //data << (uint32)20;
304 data << (uint32)getMSTime();
305 SendPacket( &data );
307 data.Initialize( SMSG_GMTICKET_CREATE );
308 data << uint32(2);
309 SendPacket( &data );
310 DEBUG_LOG("update the ticket\n");
312 ObjectAccessor::PlayersMapType &m = ObjectAccessor::Instance().GetPlayers();
313 for(ObjectAccessor::PlayersMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
315 if(itr->second->GetSession()->GetSecurity() >= 2 && itr->second->isAcceptTickets())
316 ChatHandler::PSendSysMessage(itr->second->GetSession(),"New ticket from %s",GetPlayer()->GetName());
322 void WorldSession::HandleGMTicketSystemStatusOpcode( WorldPacket & recv_data )
324 WorldPacket data;
326 data.Initialize( SMSG_GMTICKET_SYSTEMSTATUS );
327 data << uint32(1);
329 SendPacket( &data );
332 void WorldSession::HandleEnablePvP(WorldPacket& recvPacket)
335 if ( (!GetPlayer()->isAlive()) || GetPlayer()->isInCombat() || GetPlayer()->isInDuel() )
337 WorldPacket data;
338 data.Initialize(SMSG_CAST_RESULT);
339 data << uint32(0);
340 data << uint8(2);
341 data << uint8(97);
342 SendPacket(&data);
343 return;
346 if( !GetPlayer()->GetPvP() || GetPlayer()->m_pvp_counting )
348 //sChatHandler.SendSysMessage(GetPlayer()->GetSession(), "You are now flagged PvP combat and will remain so until toggled off.");
349 GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
350 GetPlayer()->SetPvP (true);
351 return;
354 //sChatHandler.SendSysMessage(GetPlayer()->GetSession(), "You will be unflagged for PvP combat after five minutes of non-PvP action in friendly territory.");
356 GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
357 GetPlayer()->SetPVPCount(time(NULL));
361 void WorldSession::HandleZoneUpdateOpcode( WorldPacket & recv_data )
363 uint32 newZone;
364 WPAssert(GetPlayer());
366 // if player is resting stop resting
367 if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING))
369 if(GetPlayer()->GetRestType()==2) //rest in city
371 //speed collect rest bonus (section/in hour)
372 float bubble=1; //0% Blizzlike
373 GetPlayer()->SetRestBonus( GetPlayer()->GetRestBonus()+ (time(NULL)-GetPlayer()->GetTimeInnEter())*0.0142108*bubble );
374 if(GetPlayer()->GetRestBonus()>1534)GetPlayer()->SetRestBonus(1534);
375 GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
379 recv_data >> newZone;
380 sLog.outDetail("WORLD: Recvd ZONE_UPDATE: %u", newZone);
382 AreaTableEntry* area = GetAreaEntryByAreaID(newZone);
384 if(area && area->zone_type == 312) // city
386 GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
387 GetPlayer()->SetRestType(2);
388 GetPlayer()->InnEnter(time(NULL),0,0,0);
392 void WorldSession::HandleSetTargetOpcode( WorldPacket & recv_data )
394 uint64 guid ;
395 recv_data >> guid;
397 if( _player != 0 )
399 _player->SetTarget(guid);
403 void WorldSession::HandleSetSelectionOpcode( WorldPacket & recv_data )
405 uint64 guid;
406 recv_data >> guid;
408 if( _player != 0 )
409 _player->SetSelection(guid);
411 if(_player->GetUInt64Value(PLAYER_FIELD_COMBO_TARGET) != guid)
413 _player->SetUInt64Value(PLAYER_FIELD_COMBO_TARGET,0);
414 _player->SetUInt32Value(PLAYER_FIELD_BYTES,((_player->GetUInt32Value(PLAYER_FIELD_BYTES) & ~(0xFF << 8)) | (0x00 << 8)));
418 void WorldSession::HandleStandStateChangeOpcode( WorldPacket & recv_data )
420 sLog.outDebug( "WORLD: Received CMSG_STAND_STATE_CHANGE" );
421 if( GetPlayer() != 0 )
423 uint8 animstate;
424 recv_data >> animstate;
426 WorldPacket data;
427 data.Initialize(SMSG_STANDSTATE_CHANGE_ACK);
428 data << animstate;
429 SendPacket(&data);
431 uint32 bytes1 = _player->GetUInt32Value( UNIT_FIELD_BYTES_1 );
432 bytes1 &=0xFFFFFF00;
433 bytes1 |=animstate;
434 _player->SetUInt32Value(UNIT_FIELD_BYTES_1 , bytes1);
436 if (animstate != PLAYER_STATE_SIT_CHAIR && animstate != PLAYER_STATE_SIT_LOW_CHAIR && animstate != PLAYER_STATE_SIT_MEDIUM_CHAIR &&
437 animstate != PLAYER_STATE_SIT_HIGH_CHAIR && animstate != PLAYER_STATE_SIT && animstate != PLAYER_STATE_SLEEP &&
438 animstate != PLAYER_STATE_KNEEL)
440 // cancel drinking / eating
441 Unit::AuraMap& p_auras = _player->GetAuras();
442 for (Unit::AuraMap::iterator itr = p_auras.begin(); itr != p_auras.end();)
444 if (itr->second && (itr->second->GetSpellProto()->AuraInterruptFlags & (1<<18)) != 0)
445 _player->RemoveAura(itr);
446 else
447 ++itr;
453 void WorldSession::HandleFriendListOpcode( WorldPacket & recv_data )
455 sLog.outDebug( "WORLD: Received CMSG_FRIEND_LIST" );
457 GetPlayer()->SendFriendlist();
459 GetPlayer()->SendIgnorelist();
462 void WorldSession::HandleAddFriendOpcode( WorldPacket & recv_data )
464 sLog.outDebug( "WORLD: Received CMSG_ADD_FRIEND" );
466 std::string friendName = "UNKNOWN";
467 unsigned char friendResult = FRIEND_NOT_FOUND;
468 Player *pfriend=NULL;
469 uint64 friendGuid = 0;
470 uint32 friendArea = 0, friendLevel = 0, friendClass = 0;
471 WorldPacket data;
473 recv_data >> friendName;
475 normalizePlayerName(friendName);
476 sDatabase.escape_string(friendName); // prevent SQL injection - normal name don't must changed by this call
478 sLog.outDetail( "WORLD: %s asked to add friend : '%s'",
479 GetPlayer()->GetName(), friendName.c_str() );
481 friendGuid = objmgr.GetPlayerGUIDByName(friendName.c_str());
483 if(friendGuid)
485 pfriend = ObjectAccessor::Instance().FindPlayer(friendGuid);
486 if(pfriend==GetPlayer())
487 friendResult = FRIEND_SELF;
488 else if(GetPlayer()->GetTeam()!=objmgr.GetPlayerTeamByGUID(friendGuid))
489 friendResult = FRIEND_ENEMY;
490 else
492 QueryResult *result = sDatabase.PQuery("SELECT `guid` FROM `character_social` WHERE `guid` = '%u' AND `flags` = 'FRIEND' AND `friend` = '%u'", GetPlayer()->GetGUIDLow(), GUID_LOPART(friendGuid));
494 if( result )
495 friendResult = FRIEND_ALREADY;
497 delete result;
502 data.Initialize( SMSG_FRIEND_STATUS );
504 if (friendGuid && friendResult==FRIEND_NOT_FOUND)
506 if( pfriend && pfriend->IsInWorld() && pfriend->isGMVisibleFor(GetPlayer()))
508 friendResult = FRIEND_ADDED_ONLINE;
509 friendArea = pfriend->GetZoneId();
510 friendLevel = pfriend->getLevel();
511 friendClass = pfriend->getClass();
514 else
515 friendResult = FRIEND_ADDED_OFFLINE;
517 sDatabase.PExecute("INSERT INTO `character_social` (`guid`,`name`,`friend`,`flags`) VALUES ('%u', '%s', '%u', 'FRIEND')",
518 GetPlayer()->GetGUIDLow(), friendName.c_str(), GUID_LOPART(friendGuid));
520 sLog.outDetail( "WORLD: %s Guid found '%u' area:%u Level:%u Class:%u. ",
521 friendName.c_str(), GUID_LOPART(friendGuid), friendArea, friendLevel, friendClass);
524 else if(friendResult==FRIEND_ALREADY)
526 sLog.outDetail( "WORLD: %s Guid Already a Friend. ", friendName.c_str() );
528 else if(friendResult==FRIEND_SELF)
530 sLog.outDetail( "WORLD: %s Guid can't add himself. ", friendName.c_str() );
532 else
534 sLog.outDetail( "WORLD: %s Guid not found. ", friendName.c_str() );
537 data << (uint8)friendResult << (uint64)friendGuid << (uint8)0;
538 if(friendResult == FRIEND_ADDED_ONLINE)
539 data << (uint32)friendArea << (uint32)friendLevel << (uint32)friendClass;
541 SendPacket( &data );
543 sLog.outDebug( "WORLD: Sent (SMSG_FRIEND_STATUS)" );
546 void WorldSession::HandleDelFriendOpcode( WorldPacket & recv_data )
548 uint64 FriendGUID;
549 WorldPacket data;
551 sLog.outDebug( "WORLD: Received CMSG_DEL_FRIEND" );
552 recv_data >> FriendGUID;
554 uint8 FriendResult = FRIEND_REMOVED;
556 data.Initialize( SMSG_FRIEND_STATUS );
558 data << (uint8)FriendResult << (uint64)FriendGUID;
560 uint32 guidlow = GetPlayer()->GetGUIDLow();
562 sDatabase.PExecute("DELETE FROM `character_social` WHERE `flags` = 'FRIEND' AND `guid` = '%u' AND `friend` = '%u'",guidlow, GUID_LOPART(FriendGUID));
564 SendPacket( &data );
566 sLog.outDebug( "WORLD: Sent motd (SMSG_FRIEND_STATUS)" );
569 void WorldSession::HandleAddIgnoreOpcode( WorldPacket & recv_data )
571 sLog.outDebug( "WORLD: Received CMSG_ADD_IGNORE" );
573 std::string IgnoreName = "UNKNOWN";
574 unsigned char ignoreResult = FRIEND_IGNORE_NOT_FOUND;
575 uint64 IgnoreGuid = 0;
577 WorldPacket data;
579 recv_data >> IgnoreName;
581 normalizePlayerName(IgnoreName);
582 sDatabase.escape_string(IgnoreName); // prevent SQL injection - normal name don't must changed by this call
584 sLog.outDetail( "WORLD: %s asked to Ignore: '%s'",
585 GetPlayer()->GetName(), IgnoreName.c_str() );
587 IgnoreGuid = objmgr.GetPlayerGUIDByName(IgnoreName.c_str());
589 if(IgnoreGuid)
591 if(IgnoreGuid==GetPlayer()->GetGUID())
592 ignoreResult = FRIEND_IGNORE_SELF;
593 else
595 QueryResult *result = sDatabase.PQuery("SELECT `guid`,`name`,`friend`,`flags` FROM `character_social` WHERE `guid` = '%u' AND `flags` = 'IGNORE' AND `friend` = '%u'", GetPlayer()->GetGUIDLow(), GUID_LOPART(IgnoreGuid));
597 if( result )
598 ignoreResult = FRIEND_IGNORE_ALREADY;
600 delete result;
604 data.Initialize( SMSG_FRIEND_STATUS );
606 if (IgnoreGuid && ignoreResult == FRIEND_IGNORE_NOT_FOUND)
608 ignoreResult = FRIEND_IGNORE_ADDED;
610 sDatabase.PExecute("INSERT INTO `character_social` (`guid`,`name`,`friend`,`flags`) VALUES ('%u', '%s', '%u', 'IGNORE')",
611 GetPlayer()->GetGUIDLow(), IgnoreName.c_str(), GUID_LOPART(IgnoreGuid));
613 else if(ignoreResult==FRIEND_IGNORE_ALREADY)
615 sLog.outDetail( "WORLD: %s Guid Already Ignored. ", IgnoreName.c_str() );
617 else if(ignoreResult==FRIEND_IGNORE_SELF)
619 sLog.outDetail( "WORLD: %s Guid can't add himself. ", IgnoreName.c_str() );
621 else
623 sLog.outDetail( "WORLD: %s Guid not found. ", IgnoreName.c_str() );
626 data << (uint8)ignoreResult << (uint64)IgnoreGuid;
628 SendPacket( &data );
629 sLog.outDebug( "WORLD: Sent (SMSG_FRIEND_STATUS)" );
632 void WorldSession::HandleDelIgnoreOpcode( WorldPacket & recv_data )
634 uint64 IgnoreGUID;
635 WorldPacket data;
637 sLog.outDebug( "WORLD: Received CMSG_DEL_IGNORE" );
638 recv_data >> IgnoreGUID;
640 unsigned char IgnoreResult = FRIEND_IGNORE_REMOVED;
642 data.Initialize( SMSG_FRIEND_STATUS );
644 data << (uint8)IgnoreResult << (uint64)IgnoreGUID;
646 uint32 guidlow = GetPlayer()->GetGUIDLow();
648 sDatabase.PExecute("DELETE FROM `character_social` WHERE `flags` = 'IGNORE' AND `guid` = '%u' AND `friend` = '%u'",guidlow, GUID_LOPART(IgnoreGUID));
650 SendPacket( &data );
652 sLog.outDebug( "WORLD: Sent motd (SMSG_FRIEND_STATUS)" );
656 void WorldSession::HandleBugOpcode( WorldPacket & recv_data )
658 uint32 suggestion, contentlen;
659 std::string content;
660 uint32 typelen;
661 std::string type;
663 recv_data >> suggestion >> contentlen >> content >> typelen >> type;
665 if( suggestion == 0 )
666 sLog.outDebug( "WORLD: Received CMSG_BUG [Bug Report]" );
667 else
668 sLog.outDebug( "WORLD: Received CMSG_BUG [Suggestion]" );
670 sLog.outDebug( type.c_str( ) );
671 sLog.outDebug( content.c_str( ) );
673 sDatabase.escape_string(type);
674 sDatabase.escape_string(content);
675 sDatabase.PExecute ("INSERT INTO `bugreport` (`type`,`content`) VALUES('%s', '%s')", type.c_str( ), content.c_str( ));
679 void WorldSession::HandleCorpseReclaimOpcode(WorldPacket &recv_data)
681 sLog.outDetail("WORLD: Received CMSG_RECLAIM_CORPSE");
682 if (GetPlayer()->isAlive())
683 return;
685 // body not released yet
686 if(!GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
687 return;
689 Corpse* corpse = GetPlayer()->GetCorpse();
691 if (!corpse )
692 return;
694 // prevent resurrect before 30-sec delay after body release not finished
695 if(corpse->GetGhostTime() + CORPSE_RECLAIM_DELAY > time(NULL))
696 return;
698 float dist = corpse->GetDistance2dSq(GetPlayer());
699 sLog.outDebug("Corpse 2D Distance: \t%f",dist);
700 if (dist > CORPSE_RECLAIM_RADIUS*CORPSE_RECLAIM_RADIUS)
701 return;
703 uint64 guid;
704 recv_data >> guid;
706 // resurrect
707 GetPlayer()->ResurrectPlayer();
709 // spawnbones
710 GetPlayer()->SpawnCorpseBones();
712 // set health, mana
713 GetPlayer()->ApplyStats(false);
714 GetPlayer()->SetHealth(GetPlayer()->GetMaxHealth()/2);
715 GetPlayer()->SetPower(POWER_MANA,GetPlayer()->GetMaxPower(POWER_MANA)/2);
716 GetPlayer()->ApplyStats(true);
718 // update world right away
719 MapManager::Instance().GetMap(GetPlayer()->GetMapId())->Add(GetPlayer());
722 void WorldSession::HandleResurrectResponseOpcode(WorldPacket & recv_data)
724 sLog.outDetail("WORLD: Received CMSG_RESURRECT_RESPONSE");
726 if(GetPlayer()->isAlive())
727 return;
729 WorldPacket data;
730 uint64 guid;
731 uint8 status;
732 recv_data >> guid;
733 recv_data >> status;
735 if(status == 0)
736 return;
738 if(GetPlayer()->m_resurrectGUID == 0)
739 return;
741 GetPlayer()->ResurrectPlayer();
743 if(GetPlayer()->GetMaxHealth() > GetPlayer()->m_resurrectHealth)
744 GetPlayer()->SetHealth( GetPlayer()->m_resurrectHealth );
745 else
746 GetPlayer()->SetHealth( GetPlayer()->GetMaxHealth() );
748 if(GetPlayer()->GetMaxPower(POWER_MANA) > GetPlayer()->m_resurrectMana)
749 GetPlayer()->SetPower(POWER_MANA, GetPlayer()->m_resurrectMana );
750 else
751 GetPlayer()->SetPower(POWER_MANA, GetPlayer()->GetMaxPower(POWER_MANA) );
753 GetPlayer()->SetPower(POWER_RAGE, 0 );
755 GetPlayer()->SetPower(POWER_ENERGY, GetPlayer()->GetMaxPower(POWER_ENERGY) );
757 GetPlayer()->SpawnCorpseBones();
759 GetPlayer()->BuildTeleportAckMsg(&data, GetPlayer()->m_resurrectX, GetPlayer()->m_resurrectY, GetPlayer()->m_resurrectZ, GetPlayer()->GetOrientation());
760 GetPlayer()->GetSession()->SendPacket(&data);
762 GetPlayer()->SetPosition(GetPlayer()->m_resurrectX ,GetPlayer()->m_resurrectY ,GetPlayer()->m_resurrectZ,GetPlayer()->GetOrientation());
764 GetPlayer()->m_resurrectGUID = 0;
765 GetPlayer()->m_resurrectHealth = GetPlayer()->m_resurrectMana = 0;
766 GetPlayer()->m_resurrectX = GetPlayer()->m_resurrectY = GetPlayer()->m_resurrectZ = 0;
769 void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
771 sLog.outDebug("WORLD: Received CMSG_AREATRIGGER");
773 uint32 Trigger_ID;
774 WorldPacket data;
776 recv_data >> Trigger_ID;
777 sLog.outDebug("Trigger ID:%u",Trigger_ID);
779 if(GetPlayer()->isInFlight())
781 sLog.outDebug("Player '%s' in flight, ignore Area Trigger ID:%u",GetPlayer()->GetName(),Trigger_ID);
782 return;
785 AreaTriggerPoint *pArea = objmgr.GetAreaTriggerQuestPoint( Trigger_ID );
786 if( pArea )
788 uint32 quest_id = pArea->Quest_ID;
789 Quest* pQuest = GetPlayer()->GetActiveQuest(quest_id);
790 if( pQuest )
792 if( !Script->scriptAreaTrigger( GetPlayer(), pQuest, Trigger_ID ) )
794 if(GetPlayer()->GetQuestStatus(quest_id) == QUEST_STATUS_INCOMPLETE)
795 GetPlayer()->AreaExplored( quest_id );
800 QueryResult *result = sDatabase.PQuery("SELECT `name` FROM `areatrigger_tavern` WHERE `id` = '%u'", Trigger_ID);
801 if(result)
803 GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
804 result = sDatabase.PQuery("SELECT `trigger_map`,`trigger_position_x`,`trigger_position_y`,`trigger_position_z` FROM `areatrigger_template` WHERE `id` = '%u'", Trigger_ID);
805 if(result)
807 Field *fields = result->Fetch();
808 GetPlayer()->InnEnter(time(NULL),fields[1].GetFloat(),fields[2].GetFloat(),fields[3].GetFloat());
809 GetPlayer()->SetRestType(1);
810 delete result;
813 else if(AreaTrigger * at = objmgr.GetAreaTrigger(Trigger_ID))
815 if(at->mapId == GetPlayer()->GetMapId() && !GetPlayer()->m_bgInBattleGround )
817 WorldPacket movedata;
818 _player->BuildTeleportAckMsg(&movedata, at->X, at->Y, at->Z, at->Orientation );
819 _player->SendMessageToSet(&movedata,true);
820 //_player->SetPosition( at->X, at->Y, at->Z, _player->GetOrientation());
821 //_player->BuildHeartBeatMsg(&data);
822 //_player->SendMessageToSet(&data, true);
824 else if (GetPlayer()->m_bgInBattleGround) //if player is playing in a BattleGround
826 //! AreaTrigger BattleGround
828 //Get current BattleGround the player is in
829 BattleGround* TempBattlegrounds = sBattleGroundMgr.GetBattleGround(GetPlayer()->GetBattleGroundId());
830 //Run the areatrigger code
831 if(TempBattlegrounds)
832 TempBattlegrounds->HandleAreaTrigger(GetPlayer(),Trigger_ID);
834 else
836 GetPlayer()->TeleportTo(at->mapId,at->X,at->Y,at->Z,at->Orientation);
838 delete at;
841 // set resting flag we are in the inn
844 void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)
848 void WorldSession::HandleRequestAccountData(WorldPacket& recv_data)
850 sLog.outDetail("WORLD: Received CMSG_REQUEST_ACCOUNT_DATA");
853 void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data)
855 sLog.outDetail( "WORLD: Received CMSG_SET_ACTION_BUTTON" );
856 uint8 button, misc, type;
857 uint16 action;
858 recv_data >> button >> action >> misc >> type;
859 sLog.outDetail( "BUTTON: %u ACTION: %u TYPE: %u MISC: %u", button, action, type, misc );
860 if(action==0)
862 sLog.outDetail( "MISC: Remove action from button %u", button );
864 GetPlayer()->removeAction(button);
866 else
868 if(type==ACTION_BUTTON_MACRO)
870 sLog.outDetail( "MISC: Added Macro %u into button %u", action, button );
871 GetPlayer()->addAction(button,action,type,misc);
873 else if(type==ACTION_BUTTON_SPELL)
875 sLog.outDetail( "MISC: Added Action %u into button %u", action, button );
876 GetPlayer()->addAction(button,action,type,misc);
878 else if(type==ACTION_BUTTON_ITEM)
880 sLog.outDetail( "MISC: Added Item %u into button %u", action, button );
881 GetPlayer()->addAction(button,action,type,misc);
883 else
884 sLog.outError( "MISC: Unknown action button type %u for action %u into button %u", type, action, button );
888 void WorldSession::HandleCompleteCinema( WorldPacket & recv_data )
890 DEBUG_LOG( "WORLD: Player is watching cinema" );
893 void WorldSession::HandleNextCinematicCamera( WorldPacket & recv_data )
895 DEBUG_LOG( "WORLD: Which movie to play" );
898 void WorldSession::HandleRequestRaidInfoOpcode( WorldPacket & recv_data )
900 sLog.outDebug("Received opcode CMSG_REQUEST_RAID_INFO");
901 WorldPacket data;
902 data.Initialize(SMSG_RAID_INSTANCE_INFO);
903 data << (uint32)0;
904 _player->GetSession()->SendPacket(&data);
907 void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & recv_data )
910 DEBUG_LOG( "WORLD: Battleground status - not yet" );
913 void WorldSession::HandleMoveTimeSkippedOpcode( WorldPacket & recv_data )
916 WorldSession::Update( getMSTime() );
917 DEBUG_LOG( "WORLD: Time Lag/Synchronization Resent/Update" );
921 void WorldSession::HandleMoveUnRootAck(WorldPacket& recv_data)
924 sLog.outDebug( "WORLD: CMSG_FORCE_MOVE_UNROOT_ACK" );
925 WorldPacket data;
926 uint64 guid;
927 uint64 unknown1;
928 uint32 unknown2;
929 float PositionX;
930 float PositionY;
931 float PositionZ;
932 float Orientation;
934 recv_data >> guid;
935 recv_data >> unknown1;
936 recv_data >> unknown2;
937 recv_data >> PositionX;
938 recv_data >> PositionY;
939 recv_data >> PositionZ;
940 recv_data >> Orientation;
942 // TODO for later may be we can use for anticheat
943 // DEBUG_LOG("Guid " I64FMTD,guid);
944 // DEBUG_LOG("unknown1 " I64FMTD,unknown1);
945 // DEBUG_LOG("unknown2 %u",unknown2);
946 // DEBUG_LOG("X %f",PositionX);
947 // DEBUG_LOG("Y %f",PositionY);
948 // DEBUG_LOG("Z %f",PositionZ);
949 // DEBUG_LOG("O %f",Orientation);
952 void WorldSession::HandleLookingForGroup(WorldPacket& recv_data)
954 // TODO send groups need data
955 sLog.outDebug( "WORLD: MSG_LOOKING_FOR_GROUP" );
958 void WorldSession::HandleMoveRootAck(WorldPacket& recv_data)
961 sLog.outDebug( "WORLD: CMSG_FORCE_MOVE_ROOT_ACK" );
962 WorldPacket data;
963 uint64 guid;
964 uint64 unknown1;
965 uint32 unknown2;
966 float PositionX;
967 float PositionY;
968 float PositionZ;
969 float Orientation;
971 recv_data >> guid;
972 recv_data >> unknown1;
973 recv_data >> unknown2;
974 recv_data >> PositionX;
975 recv_data >> PositionY;
976 recv_data >> PositionZ;
977 recv_data >> Orientation;
979 // for later may be we can use for anticheat
980 // DEBUG_LOG("Guid " I64FMTD,guid);
981 // DEBUG_LOG("unknown1 " I64FMTD,unknown1);
982 // DEBUG_LOG("unknown1 %u",unknown2);
983 // DEBUG_LOG("X %f",PositionX);
984 // DEBUG_LOG("Y %f",PositionY);
985 // DEBUG_LOG("Z %f",PositionZ);
986 // DEBUG_LOG("O %f",Orientation);
989 void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data)
992 WorldPacket data;
993 uint64 guid;
994 uint32 value1;
996 recv_data >> guid;
997 recv_data >> value1; // ms time ?
998 DEBUG_LOG("Guid " I64FMTD,guid);
999 DEBUG_LOG("Value 1 %u",value1);
1002 void WorldSession::HandleForceRunSpeedChangeAck(WorldPacket& recv_data)
1004 //check for speed stuff
1005 recv_data.hexlike();
1006 uint64 GUID;
1007 uint32 Flags,unk1, unk0;
1008 uint32 d_time;
1009 float X,Y,Z,O;
1010 float NewSpeed;
1012 recv_data >> GUID;
1013 recv_data >> unk0 >> Flags;
1014 if ( (Flags & 0x2000) || (Flags & 0x6000) ) //0x2000 == jumping 0x6000 == Falling
1016 uint32 unk2, unk3, unk4, unk5;
1017 float OldSpeed;
1019 recv_data >> d_time;
1020 recv_data >> X >> Y >> Z >> O;
1021 recv_data >> unk2 >> unk3; //no idea, maybe unk2 = flags2
1022 recv_data >> unk4 >> unk5; //no idea
1023 recv_data >> OldSpeed >> NewSpeed;
1025 else //single check
1027 recv_data >> d_time;
1028 recv_data >> X >> Y >> Z >> O;
1029 recv_data >> unk1 >> NewSpeed;
1031 if (GetPlayer()->GetSpeed(MOVE_RUN) != NewSpeed)
1032 //now kick player???
1033 sLog.outError("SpeedChange player is NOT correct, its set to: %f", NewSpeed);
1036 void WorldSession::HandleForceSwimSpeedChangeAck(WorldPacket& recv_data)
1038 // set swim speed ? received data is more
1039 sLog.outDebug("CMSG_FORCE_SWIM_SPEED_CHANGE_ACK");
1043 void WorldSession::HandleSetActionBar(WorldPacket& recv_data)
1045 uint8 ActionBar;
1046 uint32 temp;
1048 recv_data >> ActionBar;
1050 temp = ((GetPlayer()->GetUInt32Value( PLAYER_FIELD_BYTES )) & 0xFFF0FFFF) + (ActionBar << 16);
1051 GetPlayer()->SetUInt32Value( PLAYER_FIELD_BYTES, temp);
1054 void WorldSession::HandleMoveWaterWalkAck(WorldPacket& recv_data)
1056 // TODO
1057 // we receive guid,x,y,z
1060 void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
1062 // TODO
1063 // need to be written
1066 void WorldSession::HandleWardenDataOpcode(WorldPacket& recv_data)
1068 uint8 tmp;
1069 recv_data >> tmp;
1070 sLog.outDebug("Received opcode CMSG_WARDEN_DATA, not resolve.uint8 = %u",tmp);
1073 void WorldSession::HandlePlayedTime(WorldPacket& recv_data)
1075 WorldPacket data;
1076 uint32 TotalTimePlayed = GetPlayer()->GetTotalPlayedTime();
1077 uint32 LevelPlayedTime = GetPlayer()->GetLevelPlayedTime();
1079 data.Initialize(SMSG_PLAYED_TIME);
1080 data << TotalTimePlayed;
1081 data << LevelPlayedTime;
1082 SendPacket(&data);
1085 void WorldSession::HandleInspectOpcode(WorldPacket& recv_data)
1088 WorldPacket data;
1089 uint64 guid;
1090 recv_data >> guid;
1091 DEBUG_LOG("Inspected guid is " I64FMTD,guid);
1093 if( _player != 0 )
1095 _player->SetSelection(guid);
1098 if(_player->GetUInt64Value(PLAYER_FIELD_COMBO_TARGET) != guid)
1100 _player->SetUInt64Value(PLAYER_FIELD_COMBO_TARGET,0);
1101 _player->SetUInt32Value(PLAYER_FIELD_BYTES,((_player->GetUInt32Value(PLAYER_FIELD_BYTES) & ~(0xFF << 8)) | (0x00 << 8)));
1104 data.Initialize( SMSG_INSPECT );
1105 data << guid;
1106 SendPacket(&data);
1110 void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data)
1112 WorldPacket data;
1113 Player *pl;
1114 uint64 guid;
1115 recv_data >> guid;
1116 DEBUG_LOG("Party Stats guid is " I64FMTD,guid);
1118 pl = objmgr.GetPlayer(guid);
1119 if(pl)
1121 data.Initialize( MSG_INSPECT_HONOR_STATS );
1122 data << guid; // player guid
1123 // Rank, filling bar, PLAYER_BYTES_3, ??
1124 data << (uint8)pl->GetUInt32Value(PLAYER_FIELD_HONOR_BAR);
1125 // Today Honorable and Dishonorable Kills
1126 data << pl->GetUInt32Value(PLAYER_FIELD_SESSION_KILLS);
1127 // Yesterday Honorable Kills
1128 data << pl->GetUInt32Value(PLAYER_FIELD_YESTERDAY_KILLS);
1129 // Last Week Honorable Kills
1130 data << pl->GetUInt32Value(PLAYER_FIELD_LAST_WEEK_KILLS);
1131 // This Week Honorable kills
1132 data << pl->GetUInt32Value(PLAYER_FIELD_THIS_WEEK_KILLS);
1133 // Lifetime Honorable Kills
1134 data << pl->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS);
1135 // Lifetime Dishonorable Kills
1136 data << pl->GetUInt32Value(PLAYER_FIELD_LIFETIME_DISHONORABLE_KILLS);
1137 // Yesterday Honor
1138 data << pl->GetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION);
1139 // Last Week Honor
1140 data << pl->GetUInt32Value(PLAYER_FIELD_LAST_WEEK_CONTRIBUTION);
1141 // This Week Honor
1142 data << pl->GetUInt32Value(PLAYER_FIELD_THIS_WEEK_CONTRIBUTION);
1143 // Last Week Standing
1144 data << pl->GetUInt32Value(PLAYER_FIELD_LAST_WEEK_RANK);
1145 data << (uint8)pl->GetHonorHighestRank(); // Highest Rank, ??
1146 SendPacket(&data);
1148 else
1149 sLog.outDebug("Player %u not found!", guid);
1152 void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data)
1154 // write in client console: worldport 469 452 6454 2536 180 or /console worldport 469 452 6454 2536 180
1155 // Received opcode CMSG_WORLD_TELEPORT
1156 // Time is ***, map=469, x=452.000000, y=6454.000000, z=2536.000000, orient=3.141593
1158 sLog.outDebug("Received opcode CMSG_WORLD_TELEPORT");
1160 if(GetPlayer()->isInFlight())
1162 sLog.outDebug("Player '%s' in flight, ignore worldport command.",GetPlayer()->GetName());
1163 return;
1166 WorldPacket data;
1167 uint32 time;
1168 uint32 mapid;
1169 float PositionX;
1170 float PositionY;
1171 float PositionZ;
1172 float Orientation;
1174 recv_data >> time; // time in m.sec.
1175 recv_data >> mapid;
1176 recv_data >> PositionX;
1177 recv_data >> PositionY;
1178 recv_data >> PositionZ;
1179 recv_data >> Orientation; // o (3.141593 = 180 degrees)
1180 DEBUG_LOG("Time %u sec, map=%u, x=%f, y=%f, z=%f, orient=%f", time/1000, mapid, PositionX, PositionY, PositionZ, Orientation);
1182 if (GetSecurity() >= 3)
1183 GetPlayer()->TeleportTo(mapid,PositionX,PositionY,PositionZ,Orientation);
1184 else
1185 SendNotification("You do not have permission to perform that function");
1186 sLog.outDebug("Received worldport command from player %s", GetPlayer()->GetName());
1189 void WorldSession::SendNotification(char* msg)
1191 if(msg)
1193 WorldPacket data;
1194 data.Initialize(SMSG_NOTIFICATION);
1195 data << msg;
1196 SendPacket(&data);