diff options
author | KingPin <none@none> | 2008-11-05 20:10:19 -0600 |
---|---|---|
committer | KingPin <none@none> | 2008-11-05 20:10:19 -0600 |
commit | 8d331f2b10cff29ee0571f7056ad353df6a3eabd (patch) | |
tree | 36ef334fec8d6a55f151d40ca5e709880346c219 /src | |
parent | 404f72c7a2e9c230156e51f8013993b3c8f03d93 (diff) |
[svn] * Avoid access to bag item prototype for getting bag size, use related item update field instead as more fast source.
* Better check client inventory pos data received in some client packets to skip invalid cases.
* Removed some unnecessary database queries.
* Make guid lookup for adding ignore async.
* Added two parameter versions of the AsyncQuery function
* Make queries for adding friends async. - Hunuza
* Replace some PQuery() calls with more simple Query() - Hunuza
* Mark spell as executed instead of deleteable to solve crash.
*** Source mangos.
**Its a big commit. so test with care... or without care.... whatever floats your boat.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/framework/Utilities/EventProcessor.cpp | 26 | ||||
-rw-r--r-- | src/framework/Utilities/EventProcessor.h | 4 | ||||
-rw-r--r-- | src/game/CharacterHandler.cpp | 2 | ||||
-rw-r--r-- | src/game/Creature.cpp | 9 | ||||
-rw-r--r-- | src/game/Guild.cpp | 21 | ||||
-rw-r--r-- | src/game/Guild.h | 1 | ||||
-rw-r--r-- | src/game/GuildHandler.cpp | 193 | ||||
-rw-r--r-- | src/game/InstanceSaveMgr.cpp | 12 | ||||
-rw-r--r-- | src/game/Level2.cpp | 29 | ||||
-rw-r--r-- | src/game/Level3.cpp | 77 | ||||
-rw-r--r-- | src/game/Map.cpp | 3 | ||||
-rw-r--r-- | src/game/MiscHandler.cpp | 125 | ||||
-rw-r--r-- | src/game/ObjectMgr.cpp | 22 | ||||
-rw-r--r-- | src/game/SkillDiscovery.cpp | 2 | ||||
-rw-r--r-- | src/game/SkillExtraItems.cpp | 2 | ||||
-rw-r--r-- | src/game/SocialMgr.cpp | 2 | ||||
-rw-r--r-- | src/game/SocialMgr.h | 2 | ||||
-rw-r--r-- | src/game/Spell.cpp | 18 | ||||
-rw-r--r-- | src/game/Spell.h | 9 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 2 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 4 | ||||
-rw-r--r-- | src/game/Transports.cpp | 2 | ||||
-rw-r--r-- | src/game/Unit.cpp | 24 | ||||
-rw-r--r-- | src/game/WorldSession.cpp | 2 | ||||
-rw-r--r-- | src/game/WorldSession.h | 2 | ||||
-rw-r--r-- | src/shared/Database/Database.h | 8 | ||||
-rw-r--r-- | src/shared/Database/DatabaseImpl.h | 65 |
27 files changed, 391 insertions, 277 deletions
diff --git a/src/framework/Utilities/EventProcessor.cpp b/src/framework/Utilities/EventProcessor.cpp index 225497e6935..0a869481916 100644 --- a/src/framework/Utilities/EventProcessor.cpp +++ b/src/framework/Utilities/EventProcessor.cpp @@ -28,7 +28,7 @@ EventProcessor::EventProcessor() EventProcessor::~EventProcessor() { - KillAllEvents(); + KillAllEvents(true); } void EventProcessor::Update(uint32 p_time) @@ -60,21 +60,31 @@ void EventProcessor::Update(uint32 p_time) } } -void EventProcessor::KillAllEvents() +void EventProcessor::KillAllEvents(bool force) { // prevent event insertions m_aborting = true; // first, abort all existing events - for (EventList::iterator i = m_events.begin(); i != m_events.end(); ++i) + for (EventList::iterator i = m_events.begin(); i != m_events.end();) { - i->second->to_Abort = true; - i->second->Abort(m_time); - delete i->second; + EventList::iterator i_old = i; + ++i; + + i_old->second->to_Abort = true; + i_old->second->Abort(m_time); + if(force || i_old->second->IsDeletable()) + { + delete i_old->second; + + if(!force) // need per-element cleanup + m_events.erase (i_old); + } } - // clear event list - m_events.clear(); + // fast clear event list (in force case) + if(force) + m_events.clear(); } void EventProcessor::AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime) diff --git a/src/framework/Utilities/EventProcessor.h b/src/framework/Utilities/EventProcessor.h index c40e065c87a..09cc243a2b2 100644 --- a/src/framework/Utilities/EventProcessor.h +++ b/src/framework/Utilities/EventProcessor.h @@ -39,6 +39,8 @@ class BasicEvent // return false if event does not want to be deleted // e_time is execution time, p_time is update interval virtual bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) { return true; } + + virtual bool IsDeletable() const { return true; } // this event can be safely deleted virtual void Abort(uint64 /*e_time*/) {} // this method executes when the event is aborted @@ -59,7 +61,7 @@ class EventProcessor ~EventProcessor(); void Update(uint32 p_time); - void KillAllEvents(); + void KillAllEvents(bool force); void AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime = true); uint64 CalculateTime(uint64 t_offset); protected: diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index bc897fd8fec..4c295892b3e 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -634,7 +634,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) } // friend status - sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), "", true); + sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), true); // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 322a2aea95d..54f51fd2dd7 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -853,16 +853,19 @@ void Creature::OnGossipSelect(Player* player, uint32 option) if(!gossip) return; } - uint32 textid=GetGossipTextId( action, zoneid); - if(textid==0) - textid=GetNpcTextId(); switch (gossip->Action) { case GOSSIP_OPTION_GOSSIP: + { + uint32 textid = GetGossipTextId(action, zoneid); + if (textid == 0) + textid=GetNpcTextId(); + player->PlayerTalkClass->CloseGossip(); player->PlayerTalkClass->SendTalking(textid); break; + } case GOSSIP_OPTION_OUTDOORPVP: sOutdoorPvPMgr.HandleGossipOption(player, GetGUID(), option); break; diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp index 9d17b175abc..2fafd68bb8c 100644 --- a/src/game/Guild.cpp +++ b/src/game/Guild.cpp @@ -112,8 +112,17 @@ bool Guild::create(uint64 lGuid, std::string gname) bool Guild::AddMember(uint64 plGuid, uint32 plRank) { - if(Player::GetGuildIdFromDB(plGuid) != 0) // player already in guild + Player* pl = objmgr.GetPlayer(plGuid); + if(pl) + { + if(pl->GetGuildId() != 0) + return false; + } + else + { + if(Player::GetGuildIdFromDB(plGuid) != 0) // player already in guild return false; + } // remove all player signs from another petitions // this will be prevent attempt joining player to many guilds and corrupt guild data integrity @@ -142,7 +151,6 @@ bool Guild::AddMember(uint64 plGuid, uint32 plRank) CharacterDatabase.PExecute("INSERT INTO guild_member (guildid,guid,rank,pnote,offnote) VALUES ('%u', '%u', '%u','%s','%s')", Id, GUID_LOPART(plGuid), newmember.RankId, dbPnote.c_str(), dbOFFnote.c_str()); - Player* pl = objmgr.GetPlayer(plGuid); if(pl) { pl->SetInGuild(Id); @@ -676,6 +684,15 @@ void Guild::SetRankRights(uint32 rankId, uint32 rights) CharacterDatabase.PExecute("UPDATE guild_rank SET rights='%u' WHERE rid='%u' AND guildid='%u'", rights, (rankId+1), Id); } +int32 Guild::GetRank(uint32 LowGuid) +{ + MemberList::iterator itr = members.find(LowGuid); + if (itr==members.end()) + return -1; + + return itr->second.RankId; +} + void Guild::Disband() { WorldPacket data(SMSG_GUILD_EVENT, 1); diff --git a/src/game/Guild.h b/src/game/Guild.h index 457e7be1495..d1431c287bd 100644 --- a/src/game/Guild.h +++ b/src/game/Guild.h @@ -326,6 +326,7 @@ class Guild { return ((GetRankRights(rankId) & right) != GR_RIGHT_EMPTY) ? true : false; } + int32 GetRank(uint32 LowGuid); void Roster(WorldSession *session); void Query(WorldSession *session); diff --git a/src/game/GuildHandler.cpp b/src/game/GuildHandler.cpp index 1c90df71e1c..fbe03b2776c 100644 --- a/src/game/GuildHandler.cpp +++ b/src/game/GuildHandler.cpp @@ -164,9 +164,20 @@ void WorldSession::HandleGuildRemoveOpcode(WorldPacket& recvPacket) if(!normalizePlayerName(plName)) return; - player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str()); guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); - + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + + if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_REMOVE)) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str()); if(player) { plGuid = player->GetGUID(); @@ -178,24 +189,12 @@ void WorldSession::HandleGuildRemoveOpcode(WorldPacket& recvPacket) plGuildId = Player::GetGuildIdFromDB(plGuid); } - if(!guild) - { - SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); - return; - } - if(!plGuid) { SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND); return; } - if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_REMOVE)) - { - SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); - return; - } - if(plGuid == guild->GetLeader()) { SendGuildCommandResult(GUILD_QUIT_S, "", GUILD_LEADER_LEAVE); @@ -296,11 +295,6 @@ void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket) CHECK_PACKET_SIZE(recvPacket, 1); std::string plName; - uint64 plGuid; - uint32 plGuildId; - uint32 plRankId; - Player *player; - Guild *guild; //sLog.outDebug("WORLD: Received CMSG_GUILD_PROMOTE"); @@ -308,28 +302,22 @@ void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket) if(!normalizePlayerName(plName)) return; - - player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str()); - guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); - if(player) - { - plGuid = player->GetGUID(); - plGuildId = player->GetGuildId(); - plRankId = player->GetRank(); - } - else - { - plGuid = objmgr.GetPlayerGUIDByName(plName); - plGuildId = Player::GetGuildIdFromDB(plGuid); - plRankId = Player::GetRankFromDB(plGuid); - } - + + Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); if(!guild) { SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); return; } - else if(!plGuid) + if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_PROMOTE)) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + uint64 plGuid = objmgr.GetPlayerGUIDByName(plName); + + if(!plGuid) { SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND); return; @@ -339,25 +327,16 @@ void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket) SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_NAME_INVALID); return; } - else if(GetPlayer()->GetGuildId() != plGuildId) + + int32 plRankId = guild->GetRank(GUID_LOPART(plGuid)); + if(plRankId == -1) { SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S); return; } - else if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_PROMOTE)) - { - SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); - return; - } - else if((plRankId-1) == 0 || (plRankId-1) < this->GetPlayer()->GetRank()) + if(plRankId < 2 || (plRankId-1) < GetPlayer()->GetRank()) return; - if(plRankId < 1) - { - SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_INTERNAL); - return; - } - uint32 newRankId = plRankId < guild->GetNrRanks() ? plRankId-1 : guild->GetNrRanks()-1; guild->ChangeRank(plGuid, newRankId); @@ -378,11 +357,6 @@ void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket) CHECK_PACKET_SIZE(recvPacket, 1); std::string plName; - uint64 plGuid; - uint32 plGuildId; - uint32 plRankId; - Player *player; - Guild *guild; //sLog.outDebug("WORLD: Received CMSG_GUILD_DEMOTE"); @@ -391,26 +365,21 @@ void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket) if(!normalizePlayerName(plName)) return; - player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str()); - guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); - if(player) - { - plGuid = player->GetGUID(); - plGuildId = player->GetGuildId(); - plRankId = player->GetRank(); - } - else - { - plGuid = objmgr.GetPlayerGUIDByName(plName); - plGuildId = Player::GetGuildIdFromDB(plGuid); - plRankId = Player::GetRankFromDB(plGuid); - } + Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); if(!guild) { SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); return; } + + if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_DEMOTE)) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + uint64 plGuid = objmgr.GetPlayerGUIDByName(plName); if( !plGuid ) { @@ -424,18 +393,13 @@ void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket) return; } - if(GetPlayer()->GetGuildId() != plGuildId) + int32 plRankId = guild->GetRank(GUID_LOPART(plGuid)); + if(plRankId == -1) { SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S); return; } - if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_DEMOTE)) - { - SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); - return; - } - if((plRankId+1) >= guild->GetNrRanks() || plRankId <= this->GetPlayer()->GetRank()) return; @@ -535,6 +499,20 @@ void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket) if(!normalizePlayerName(name)) return; + + guild = objmgr.GetGuildById(oldLeader->GetGuildId()); + + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + + if(oldLeader->GetGUID() != guild->GetLeader()) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } newLeader = ObjectAccessor::Instance().FindPlayerByName(name.c_str()); if(newLeader) @@ -547,14 +525,7 @@ void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket) newLeaderGUID = objmgr.GetPlayerGUIDByName(name); newLeaderGuild = Player::GetGuildIdFromDB(newLeaderGUID); } - guild = objmgr.GetGuildById(oldLeader->GetGuildId()); - - if(!guild) - { - SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); - return; - } - else if(!newLeaderGUID) + if(!newLeaderGUID) { SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_FOUND); return; @@ -564,11 +535,6 @@ void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket) SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_IN_GUILD_S); return; } - if(oldLeader->GetGUID() != guild->GetLeader()) - { - SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); - return; - } guild->SetLeader(newLeaderGUID); guild->ChangeRank(oldLeader->GetGUID(), GR_OFFICER); @@ -635,8 +601,20 @@ void WorldSession::HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket) if(!normalizePlayerName(name)) return; - player = ObjectAccessor::Instance().FindPlayerByName(name.c_str()); guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + + if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EPNOTE)) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + player = ObjectAccessor::Instance().FindPlayerByName(name.c_str()); if(player) { plGuid = player->GetGUID(); @@ -648,12 +626,7 @@ void WorldSession::HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket) plGuildId = Player::GetGuildIdFromDB(plGuid); } - if(!guild) - { - SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); - return; - } - else if(!plGuid) + if(!plGuid) { SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_FOUND); return; @@ -663,11 +636,6 @@ void WorldSession::HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket) SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_IN_GUILD_S); return; } - if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EPNOTE)) - { - SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); - return; - } recvPacket >> PNOTE; guild->SetPNOTE(plGuid, PNOTE); @@ -692,8 +660,19 @@ void WorldSession::HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket) if(!normalizePlayerName(plName)) return; - player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str()); guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + if(!guild) + { + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + return; + } + if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EOFFNOTE)) + { + SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); + return; + } + + player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str()); if(player) { plGuid = player->GetGUID(); @@ -705,12 +684,7 @@ void WorldSession::HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket) plGuildId = Player::GetGuildIdFromDB(plGuid); } - if(!guild) - { - SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); - return; - } - else if( !plGuid ) + if( !plGuid ) { SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND); return; @@ -720,11 +694,6 @@ void WorldSession::HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket) SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S); return; } - if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EOFFNOTE)) - { - SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); - return; - } recvPacket >> OFFNOTE; guild->SetOFFNOTE(plGuid, OFFNOTE); diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp index 15f2d097615..f97fc4bff19 100644 --- a/src/game/InstanceSaveMgr.cpp +++ b/src/game/InstanceSaveMgr.cpp @@ -271,7 +271,7 @@ void InstanceSaveManager::CleanupInstances() // creature_respawn and gameobject_respawn are in another database // first, obtain total instance set std::set< uint32 > InstanceSet; - QueryResult *result = CharacterDatabase.PQuery("SELECT id FROM instance"); + QueryResult *result = CharacterDatabase.Query("SELECT id FROM instance"); if( result ) { do @@ -284,7 +284,7 @@ void InstanceSaveManager::CleanupInstances() } // creature_respawn - result = WorldDatabase.PQuery("SELECT DISTINCT(instance) FROM creature_respawn WHERE instance <> 0"); + result = WorldDatabase.Query("SELECT DISTINCT(instance) FROM creature_respawn WHERE instance <> 0"); if( result ) { do @@ -298,7 +298,7 @@ void InstanceSaveManager::CleanupInstances() } // gameobject_respawn - result = WorldDatabase.PQuery("SELECT DISTINCT(instance) FROM gameobject_respawn WHERE instance <> 0"); + result = WorldDatabase.Query("SELECT DISTINCT(instance) FROM gameobject_respawn WHERE instance <> 0"); if( result ) { do @@ -327,7 +327,7 @@ void InstanceSaveManager::PackInstances() // all valid ids are in the instance table // any associations to ids not in this table are assumed to be // cleaned already in CleanupInstances - QueryResult *result = CharacterDatabase.PQuery("SELECT id FROM instance"); + QueryResult *result = CharacterDatabase.Query("SELECT id FROM instance"); if( result ) { do @@ -377,7 +377,7 @@ void InstanceSaveManager::LoadResetTimes() // resettime = 0 in the DB for raid/heroic instances so those are skipped typedef std::map<uint32, std::pair<uint32, uint64> > ResetTimeMapType; ResetTimeMapType InstResetTime; - QueryResult *result = CharacterDatabase.PQuery("SELECT id, map, resettime FROM instance WHERE resettime > 0"); + QueryResult *result = CharacterDatabase.Query("SELECT id, map, resettime FROM instance WHERE resettime > 0"); if( result ) { do @@ -393,7 +393,7 @@ void InstanceSaveManager::LoadResetTimes() delete result; // update reset time for normal instances with the max creature respawn time + X hours - result = WorldDatabase.PQuery("SELECT MAX(respawntime), instance FROM creature_respawn WHERE instance > 0 GROUP BY instance"); + result = WorldDatabase.Query("SELECT MAX(respawntime), instance FROM creature_respawn WHERE instance > 0 GROUP BY instance"); if( result ) { do diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 722ed64fb97..9cc98d97169 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -1795,13 +1795,28 @@ bool ChatHandler::HandlePInfoCommand(const char* args) // get additional information from DB else { + QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", targetGUID); + if (!result) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + Field *fields = result->Fetch(); + total_player_time = fields[0].GetUInt32(); + delete result; + + Tokens data; + if (!Player::LoadValuesArrayFromDB(data,targetGUID)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + money = Player::GetUInt32ValueFromArray(data, PLAYER_FIELD_COINAGE); + level = Player::GetUInt32ValueFromArray(data, UNIT_FIELD_LEVEL); accId = objmgr.GetPlayerAccountIdByGUID(targetGUID); - WorldSession session(0,NULL,SEC_PLAYER,0,0,LOCALE_enUS); - Player plr(&session); // use fake session for temporary load - plr.MinimalLoadFromDB(NULL, targetGUID); - money = plr.GetMoney(); - total_player_time = plr.GetTotalPlayedTime(); - level = plr.getLevel(); } std::string username = GetTrinityString(LANG_ERROR); @@ -3383,7 +3398,7 @@ bool ChatHandler::HandleWpImportCommand(const char *args) { getline (infile,line); //cout << line << endl; - QueryResult *result = WorldDatabase.PQuery(line.c_str()); + QueryResult *result = WorldDatabase.Query(line.c_str()); delete result; } infile.close(); diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 11cbf235bde..47a3cc1a59b 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -2004,45 +2004,44 @@ bool ChatHandler::HandleAddItemSetCommand(const char* args) sLog.outDetail(GetTrinityString(LANG_ADDITEMSET), itemsetId); - QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE itemset = %u",itemsetId); - - if(!result) - { - PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId); - - SetSentErrorMessage(true); - return false; - } - - do + bool found = false; + for (uint32 id = 0; id < sItemStorage.MaxEntry; id++) { - Field *fields = result->Fetch(); - uint32 itemId = fields[0].GetUInt32(); + ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id); + if (!pProto) + continue; - ItemPosCountVec dest; - uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, 1 ); - if( msg == EQUIP_ERR_OK ) + if (pProto->ItemSet == itemsetId) { - Item* item = plTarget->StoreNewItem( dest, itemId, true); - - // remove binding (let GM give it to another player later) - if(pl==plTarget) - item->SetBinding( false ); + found = true; + ItemPosCountVec dest; + uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 ); + if (msg == EQUIP_ERR_OK) + { + Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true); + // remove binding (let GM give it to another player later) + if (pl==plTarget) + item->SetBinding( false ); pl->SendNewItem(item,1,false,true); - if(pl!=plTarget) + if (pl!=plTarget) plTarget->SendNewItem(item,1,true,false); + } + else + { + pl->SendEquipError( msg, NULL, NULL ); + PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1); + } } - else - { - pl->SendEquipError( msg, NULL, NULL ); - PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, 1); - } - - }while( result->NextRow() ); + } - delete result; + if (!found) + { + PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId); + SetSentErrorMessage(true); + return false; + } return true; } @@ -4765,16 +4764,18 @@ bool ChatHandler::HandleAddQuest(const char* args) } // check item starting quest (it can work incorrectly if added without item in inventory) - QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE startquest = '%u' LIMIT 1",entry); - if(result) + for (uint32 id = 0; id < sItemStorage.MaxEntry; id++) { - Field* fields = result->Fetch(); - uint32 item_id = fields[0].GetUInt32(); - delete result; + ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id); + if (!pProto) + continue; - PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry,item_id); - SetSentErrorMessage(true); - return false; + if (pProto->StartQuest == entry) + { + PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId); + SetSentErrorMessage(true); + return false; + } } // ok, normal (creature/GO starting) quest diff --git a/src/game/Map.cpp b/src/game/Map.cpp index dd6ce3ea14e..c47d5dd3a64 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -1357,6 +1357,9 @@ void Map::RemoveAllObjectsInRemoveList() Remove((GameObject*)obj,true); break; case TYPEID_UNIT: + // in case triggred sequence some spell can continue casting after prev CleanupsBeforeDelete call + // make sure that like sources auras/etc removed before destructor start + ((Creature*)obj)->CleanupsBeforeDelete (); Remove((Creature*)obj,true); break; default: diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 9d08539497a..d4306443f5f 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -21,6 +21,7 @@ #include "Common.h" #include "Language.h" #include "Database/DatabaseEnv.h" +#include "Database/DatabaseImpl.h" #include "WorldPacket.h" #include "Opcodes.h" #include "Log.h" @@ -649,12 +650,9 @@ void WorldSession::HandleAddFriendOpcode( WorldPacket & recv_data ) sLog.outDebug( "WORLD: Received CMSG_ADD_FRIEND" ); - std::string friendName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN); + std::string friendName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN); std::string friendNote; - FriendsResult friendResult = FRIEND_NOT_FOUND; - Player *pFriend = NULL; - uint64 friendGuid = 0; - + recv_data >> friendName; // recheck @@ -670,50 +668,51 @@ void WorldSession::HandleAddFriendOpcode( WorldPacket & recv_data ) sLog.outDebug( "WORLD: %s asked to add friend : '%s'", GetPlayer()->GetName(), friendName.c_str() ); - friendGuid = objmgr.GetPlayerGUIDByName(friendName); + CharacterDatabase.AsyncPQuery(&WorldSession::HandleAddFriendOpcodeCallBack, GetAccountId(), friendNote, "SELECT guid, race FROM characters WHERE name = '%s'", friendName.c_str()); +} +void WorldSession::HandleAddFriendOpcodeCallBack(QueryResult *result, uint32 accountId, std::string friendNote) +{ + if(!result) + return; + + uint64 friendGuid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER); + uint32 team = Player::TeamForRace((*result)[1].GetUInt8()); + + delete result; + + WorldSession * session = sWorld.FindSession(accountId); + if(!session) + return; + + FriendsResult friendResult = FRIEND_NOT_FOUND; if(friendGuid) { - pFriend = ObjectAccessor::FindPlayer(friendGuid); - if(pFriend==GetPlayer()) + if(friendGuid==session->GetPlayer()->GetGUID()) friendResult = FRIEND_SELF; - else if(GetPlayer()->GetTeam()!=objmgr.GetPlayerTeamByGUID(friendGuid) && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && GetSecurity() < SEC_MODERATOR) + else if(session->GetPlayer()->GetTeam() != team && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && session->GetSecurity() < SEC_MODERATOR) friendResult = FRIEND_ENEMY; - else if(GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid))) + else if(session->GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid))) friendResult = FRIEND_ALREADY; - } - - if (friendGuid && friendResult==FRIEND_NOT_FOUND) - { - if( pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(GetPlayer())) - friendResult = FRIEND_ADDED_ONLINE; else - friendResult = FRIEND_ADDED_OFFLINE; - - if(!_player->GetSocial()->AddToSocialList(GUID_LOPART(friendGuid), false)) + { + Player* pFriend = ObjectAccessor::FindPlayer(friendGuid); + if( pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(session->GetPlayer())) + friendResult = FRIEND_ADDED_ONLINE; + else + friendResult = FRIEND_ADDED_OFFLINE; + + if(!session->GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(friendGuid), false)) { friendResult = FRIEND_LIST_FULL; - sLog.outDebug( "WORLD: %s's friend list is full.", GetPlayer()->GetName()); + sLog.outDebug( "WORLD: %s's friend list is full.", session->GetPlayer()->GetName()); } - _player->GetSocial()->SetFriendNote(GUID_LOPART(friendGuid), friendNote); - - sLog.outDebug( "WORLD: %s Guid found '%u'.", friendName.c_str(), GUID_LOPART(friendGuid)); - } - else if(friendResult==FRIEND_ALREADY) - { - sLog.outDebug( "WORLD: %s Guid Already a Friend.", friendName.c_str() ); - } - else if(friendResult==FRIEND_SELF) - { - sLog.outDebug( "WORLD: %s Guid can't add himself.", friendName.c_str() ); - } - else - { - sLog.outDebug( "WORLD: %s Guid not found.", friendName.c_str() ); + session->GetPlayer()->GetSocial()->SetFriendNote(GUID_LOPART(friendGuid), friendNote); + } } - sSocialMgr.SendFriendStatus(GetPlayer(), friendResult, GUID_LOPART(friendGuid), friendName, false); + sSocialMgr.SendFriendStatus(session->GetPlayer(), friendResult, GUID_LOPART(friendGuid), false); sLog.outDebug( "WORLD: Sent (SMSG_FRIEND_STATUS)" ); } @@ -730,7 +729,7 @@ void WorldSession::HandleDelFriendOpcode( WorldPacket & recv_data ) _player->GetSocial()->RemoveFromSocialList(GUID_LOPART(FriendGUID), false); - sSocialMgr.SendFriendStatus(GetPlayer(), FRIEND_REMOVED, GUID_LOPART(FriendGUID), "", false); + sSocialMgr.SendFriendStatus(GetPlayer(), FRIEND_REMOVED, GUID_LOPART(FriendGUID), false); sLog.outDebug( "WORLD: Sent motd (SMSG_FRIEND_STATUS)" ); } @@ -742,8 +741,6 @@ void WorldSession::HandleAddIgnoreOpcode( WorldPacket & recv_data ) sLog.outDebug( "WORLD: Received CMSG_ADD_IGNORE" ); std::string IgnoreName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN); - FriendsResult ignoreResult = FRIEND_IGNORE_NOT_FOUND; - uint64 IgnoreGuid = 0; recv_data >> IgnoreName; @@ -755,40 +752,40 @@ void WorldSession::HandleAddIgnoreOpcode( WorldPacket & recv_data ) sLog.outDebug( "WORLD: %s asked to Ignore: '%s'", GetPlayer()->GetName(), IgnoreName.c_str() ); - IgnoreGuid = objmgr.GetPlayerGUIDByName(IgnoreName); + CharacterDatabase.AsyncPQuery(&WorldSession::HandleAddIgnoreOpcodeCallBack, GetAccountId(), "SELECT guid FROM characters WHERE name = '%s'", IgnoreName.c_str()); +} +void WorldSession::HandleAddIgnoreOpcodeCallBack(QueryResult *result, uint32 accountId) +{ + if(!result) + return; + + uint64 IgnoreGuid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER); + + delete result; + + WorldSession * session = sWorld.FindSession(accountId); + if(!session) + return; + + FriendsResult ignoreResult = FRIEND_IGNORE_NOT_FOUND; if(IgnoreGuid) { - if(IgnoreGuid==GetPlayer()->GetGUID()) + if(IgnoreGuid==session->GetPlayer()->GetGUID()) //not add yourself ignoreResult = FRIEND_IGNORE_SELF; + else if( session->GetPlayer()->GetSocial()->HasIgnore(GUID_LOPART(IgnoreGuid)) ) + ignoreResult = FRIEND_IGNORE_ALREADY; else { - if( GetPlayer()->GetSocial()->HasIgnore(GUID_LOPART(IgnoreGuid)) ) - ignoreResult = FRIEND_IGNORE_ALREADY; - } - } - - if (IgnoreGuid && ignoreResult == FRIEND_IGNORE_NOT_FOUND) - { - ignoreResult = FRIEND_IGNORE_ADDED; + ignoreResult = FRIEND_IGNORE_ADDED; - if(!_player->GetSocial()->AddToSocialList(GUID_LOPART(IgnoreGuid), true)) + // ignore list full + if(!session->GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(IgnoreGuid), true)) ignoreResult = FRIEND_IGNORE_FULL; - } - else if(ignoreResult==FRIEND_IGNORE_ALREADY) - { - sLog.outDebug( "WORLD: %s Guid Already Ignored.", IgnoreName.c_str() ); - } - else if(ignoreResult==FRIEND_IGNORE_SELF) - { - sLog.outDebug( "WORLD: %s Guid can't add himself.", IgnoreName.c_str() ); - } - else - { - sLog.outDebug( "WORLD: %s Guid not found.", IgnoreName.c_str() ); + } } - sSocialMgr.SendFriendStatus(GetPlayer(), ignoreResult, GUID_LOPART(IgnoreGuid), "", false); + sSocialMgr.SendFriendStatus(session->GetPlayer(), ignoreResult, GUID_LOPART(IgnoreGuid), false); sLog.outDebug( "WORLD: Sent (SMSG_FRIEND_STATUS)" ); } @@ -805,7 +802,7 @@ void WorldSession::HandleDelIgnoreOpcode( WorldPacket & recv_data ) _player->GetSocial()->RemoveFromSocialList(GUID_LOPART(IgnoreGUID), true); - sSocialMgr.SendFriendStatus(GetPlayer(), FRIEND_IGNORE_REMOVED, GUID_LOPART(IgnoreGUID), "", false); + sSocialMgr.SendFriendStatus(GetPlayer(), FRIEND_IGNORE_REMOVED, GUID_LOPART(IgnoreGUID), false); sLog.outDebug( "WORLD: Sent motd (SMSG_FRIEND_STATUS)" ); } diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 97a0ce0c9e8..87706bc68a1 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -2728,7 +2728,7 @@ void ObjectMgr::LoadGroups() uint64 leaderGuid = 0; uint32 count = 0; // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - QueryResult *result = CharacterDatabase.PQuery("SELECT mainTank, mainAssistant, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, isRaid, difficulty, leaderGuid FROM groups"); + QueryResult *result = CharacterDatabase.Query("SELECT mainTank, mainAssistant, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, isRaid, difficulty, leaderGuid FROM groups"); if( !result ) { @@ -2770,7 +2770,7 @@ void ObjectMgr::LoadGroups() group = NULL; leaderGuid = 0; // 0 1 2 3 - result = CharacterDatabase.PQuery("SELECT memberGuid, assistant, subgroup, leaderGuid FROM group_member ORDER BY leaderGuid"); + result = CharacterDatabase.Query("SELECT memberGuid, assistant, subgroup, leaderGuid FROM group_member ORDER BY leaderGuid"); if(!result) { barGoLink bar( 1 ); @@ -2823,7 +2823,7 @@ void ObjectMgr::LoadGroups() count = 0; group = NULL; leaderGuid = 0; - result = CharacterDatabase.PQuery( + result = CharacterDatabase.Query( // 0 1 2 3 4 5 "SELECT leaderGuid, map, instance, permanent, difficulty, resettime, " // 6 @@ -3691,7 +3691,7 @@ void ObjectMgr::LoadQuestLocales() void ObjectMgr::LoadPetCreateSpells() { - QueryResult *result = WorldDatabase.PQuery("SELECT entry, Spell1, Spell2, Spell3, Spell4 FROM petcreateinfo_spell"); + QueryResult *result = WorldDatabase.Query("SELECT entry, Spell1, Spell2, Spell3, Spell4 FROM petcreateinfo_spell"); if(!result) { barGoLink bar( 1 ); @@ -4071,7 +4071,7 @@ void ObjectMgr::LoadEventScripts() void ObjectMgr::LoadItemTexts() { - QueryResult *result = CharacterDatabase.PQuery("SELECT id, text FROM item_text"); + QueryResult *result = CharacterDatabase.Query("SELECT id, text FROM item_text"); uint32 count = 0; @@ -4154,7 +4154,7 @@ void ObjectMgr::LoadPageTextLocales() { mPageTextLocaleMap.clear(); - QueryResult *result = WorldDatabase.PQuery("SELECT entry,text_loc1,text_loc2,text_loc3,text_loc4,text_loc5,text_loc6,text_loc7,text_loc8 FROM locales_page_text"); + QueryResult *result = WorldDatabase.Query("SELECT entry,text_loc1,text_loc2,text_loc3,text_loc4,text_loc5,text_loc6,text_loc7,text_loc8 FROM locales_page_text"); if(!result) { @@ -5710,7 +5710,7 @@ void ObjectMgr::LoadCorpses() { uint32 count = 0; // 0 1 2 3 4 5 6 7 8 10 - QueryResult *result = CharacterDatabase.PQuery("SELECT position_x, position_y, position_z, orientation, map, data, time, corpse_type, instance, guid FROM corpse WHERE corpse_type <> 0"); + QueryResult *result = CharacterDatabase.Query("SELECT position_x, position_y, position_z, orientation, map, data, time, corpse_type, instance, guid FROM corpse WHERE corpse_type <> 0"); if( !result ) { @@ -6074,7 +6074,7 @@ void ObjectMgr::LoadReservedPlayersNames() { m_ReservedNames.clear(); // need for reload case - QueryResult *result = WorldDatabase.PQuery("SELECT name FROM reserved_name"); + QueryResult *result = WorldDatabase.Query("SELECT name FROM reserved_name"); uint32 count = 0; @@ -6961,7 +6961,7 @@ void ObjectMgr::LoadTrainerSpell() std::set<uint32> skip_trainers; - QueryResult *result = WorldDatabase.PQuery("SELECT entry, spell,spellcost,reqskill,reqskillvalue,reqlevel FROM npc_trainer"); + QueryResult *result = WorldDatabase.Query("SELECT entry, spell,spellcost,reqskill,reqskillvalue,reqlevel FROM npc_trainer"); if( !result ) { @@ -7052,7 +7052,7 @@ void ObjectMgr::LoadVendors() std::set<uint32> skip_vendors; - QueryResult *result = WorldDatabase.PQuery("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor"); + QueryResult *result = WorldDatabase.Query("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor"); if( !result ) { barGoLink bar( 1 ); @@ -7098,7 +7098,7 @@ void ObjectMgr::LoadNpcTextId() m_mCacheNpcTextIdMap.clear(); - QueryResult* result = WorldDatabase.PQuery("SELECT npc_guid, textid FROM npc_gossip"); + QueryResult* result = WorldDatabase.Query("SELECT npc_guid, textid FROM npc_gossip"); if( !result ) { barGoLink bar( 1 ); diff --git a/src/game/SkillDiscovery.cpp b/src/game/SkillDiscovery.cpp index 94264bf88ff..7167d25883b 100644 --- a/src/game/SkillDiscovery.cpp +++ b/src/game/SkillDiscovery.cpp @@ -54,7 +54,7 @@ void LoadSkillDiscoveryTable() uint32 count = 0; // 0 1 2 - QueryResult *result = WorldDatabase.PQuery("SELECT spellId, reqSpell, chance FROM skill_discovery_template"); + QueryResult *result = WorldDatabase.Query("SELECT spellId, reqSpell, chance FROM skill_discovery_template"); if (result) { diff --git a/src/game/SkillExtraItems.cpp b/src/game/SkillExtraItems.cpp index 2791cd7b401..d4d46d8611d 100644 --- a/src/game/SkillExtraItems.cpp +++ b/src/game/SkillExtraItems.cpp @@ -59,7 +59,7 @@ void LoadSkillExtraItemTable() SkillExtraItemStore.clear(); // need for reload // 0 1 2 3 - QueryResult *result = WorldDatabase.PQuery("SELECT spellId, requiredSpecialization, additionalCreateChance, additionalMaxNum FROM skill_extra_item_template"); + QueryResult *result = WorldDatabase.Query("SELECT spellId, requiredSpecialization, additionalCreateChance, additionalMaxNum FROM skill_extra_item_template"); if (result) { diff --git a/src/game/SocialMgr.cpp b/src/game/SocialMgr.cpp index 83995b875ca..baabe9b043f 100644 --- a/src/game/SocialMgr.cpp +++ b/src/game/SocialMgr.cpp @@ -237,7 +237,7 @@ void SocialMgr::MakeFriendStatusPacket(FriendsResult result, uint32 guid, WorldP *data << uint64(guid); } -void SocialMgr::SendFriendStatus(Player *player, FriendsResult result, uint32 friend_guid, std::string name, bool broadcast) +void SocialMgr::SendFriendStatus(Player *player, FriendsResult result, uint32 friend_guid, bool broadcast) { FriendInfo fi; diff --git a/src/game/SocialMgr.h b/src/game/SocialMgr.h index c5df12864c8..9ce1fbcfbed 100644 --- a/src/game/SocialMgr.h +++ b/src/game/SocialMgr.h @@ -147,7 +147,7 @@ class SocialMgr void GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo); // Packet management void MakeFriendStatusPacket(FriendsResult result, uint32 friend_guid, WorldPacket *data); - void SendFriendStatus(Player *player, FriendsResult result, uint32 friend_guid, std::string name, bool broadcast); + void SendFriendStatus(Player *player, FriendsResult result, uint32 friend_guid, bool broadcast); void BroadcastToFriendListers(Player *player, WorldPacket *packet); // Loading PlayerSocial *LoadFromDB(QueryResult *result, uint32 guid); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 7b4c855474c..1ee787d042e 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -287,7 +287,8 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi m_triggeringContainer = triggeringContainer; m_magnetPair.first = false; m_magnetPair.second = NULL; - m_deletable = true; + m_referencedFromCurrentSpell = false; + m_executedCurrently = false; m_delayAtDamageCount = 0; m_applyMultiplierMask = 0; @@ -2201,6 +2202,8 @@ void Spell::cancel() void Spell::cast(bool skipCheck) { + SetExecutedCurrently(true); + uint8 castResult = 0; // update pointers base at GUIDs to prevent access to non-existed already object @@ -2210,6 +2213,7 @@ void Spell::cast(bool skipCheck) if(!m_targets.getUnitTarget() && m_targets.getUnitTargetGUID() && m_targets.getUnitTargetGUID() != m_caster->GetGUID()) { cancel(); + SetExecutedCurrently(false); return; } @@ -2221,6 +2225,7 @@ void Spell::cast(bool skipCheck) { SendCastResult(castResult); finish(false); + SetExecutedCurrently(false); return; } @@ -2232,6 +2237,7 @@ void Spell::cast(bool skipCheck) { SendCastResult(castResult); finish(false); + SetExecutedCurrently(false); return; } } @@ -2277,7 +2283,10 @@ void Spell::cast(bool skipCheck) TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot if(m_spellState == SPELL_STATE_FINISHED) // stop cast if spell marked as finish somewhere in Take*/FillTargetMap + { + SetExecutedCurrently(false); return; + } SendCastResult(castResult); SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()... @@ -2309,6 +2318,8 @@ void Spell::cast(bool skipCheck) // Immediate spell, no big deal handle_immediate(); } + + SetExecutedCurrently(false); } void Spell::handle_immediate() @@ -5126,3 +5137,8 @@ void SpellEvent::Abort(uint64 /*e_time*/) if (m_Spell->getState() != SPELL_STATE_FINISHED) m_Spell->cancel(); } + +bool SpellEvent::IsDeletable() const +{ + return m_Spell->IsDeletable(); +} diff --git a/src/game/Spell.h b/src/game/Spell.h index 8ec4a1d64d4..79addb5bfcc 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -396,8 +396,9 @@ class Spell bool IsMeleeAttackResetSpell() const { return !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK); } bool IsRangedAttackResetSpell() const { return !m_IsTriggeredSpell && IsRangedSpell() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK); } - bool IsDeletable() const { return m_deletable; } - void SetDeletable(bool deletable) { m_deletable = deletable; } + bool IsDeletable() const { return !m_referencedFromCurrentSpell && !m_executedCurrently; } + void SetReferencedFromCurrent(bool yes) { m_referencedFromCurrentSpell = yes; } + void SetExecutedCurrently(bool yes) { m_executedCurrently = yes; } uint64 GetDelayStart() const { return m_delayStart; } void SetDelayStart(uint64 m_time) { m_delayStart = m_time; } uint64 GetDelayMoment() const { return m_delayMoment; } @@ -449,7 +450,8 @@ class Spell bool m_immediateHandled; // were immediate actions handled? (used by delayed spells only) // These vars are used in both delayed spell system and modified immediate spell system - bool m_deletable; // is the spell pending deletion or must be updated till permitted to delete? + bool m_referencedFromCurrentSpell; // mark as references to prevent deleted and access by dead pointers + bool m_executedCurrently; // mark as executed to prevent deleted and access by dead pointers bool m_needSpellLog; // need to send spell log? uint8 m_applyMultiplierMask; // by effect: damage multiplier needed? float m_damageMultipliers[3]; // by effect: damage multiplier @@ -656,6 +658,7 @@ class SpellEvent : public BasicEvent virtual bool Execute(uint64 e_time, uint32 p_time); virtual void Abort(uint64 e_time); + virtual bool IsDeletable() const; protected: Spell* m_Spell; }; diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 9fd8ba42baf..0f20a414c8a 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3482,7 +3482,7 @@ void Aura::HandleAuraModSilence(bool apply, bool Real) if ( state == SPELL_STATE_PREPARING || state == SPELL_STATE_CASTING ) { currentSpell->cancel(); - currentSpell->SetDeletable(true); + currentSpell->SetReferencedFromCurrent(false); m_target->m_currentSpells[i] = NULL; } } diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 48cae6c2663..a248bb8d2d5 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1458,7 +1458,7 @@ void SpellMgr::LoadSpellChains() mSpellChains.clear(); // need for reload case mSpellChainsNext.clear(); // need for reload case - QueryResult *result = WorldDatabase.PQuery("SELECT spell_id, prev_spell, first_spell, rank, req_spell FROM spell_chain"); + QueryResult *result = WorldDatabase.Query("SELECT spell_id, prev_spell, first_spell, rank, req_spell FROM spell_chain"); if(result == NULL) { barGoLink bar( 1 ); @@ -1665,7 +1665,7 @@ void SpellMgr::LoadSpellLearnSpells() { mSpellLearnSpells.clear(); // need for reload case - QueryResult *result = WorldDatabase.PQuery("SELECT entry, SpellID FROM spell_learn_spell"); + QueryResult *result = WorldDatabase.Query("SELECT entry, SpellID FROM spell_learn_spell"); if(!result) { barGoLink bar( 1 ); diff --git a/src/game/Transports.cpp b/src/game/Transports.cpp index 8c8544ff9e1..d73835c172d 100644 --- a/src/game/Transports.cpp +++ b/src/game/Transports.cpp @@ -116,7 +116,7 @@ void MapManager::LoadTransports() sLog.outString( ">> Loaded %u transports", count ); // check transport data DB integrity - result = WorldDatabase.PQuery("SELECT gameobject.guid,gameobject.id,transports.name FROM gameobject,transports WHERE gameobject.id = transports.entry"); + result = WorldDatabase.Query("SELECT gameobject.guid,gameobject.id,transports.name FROM gameobject,transports WHERE gameobject.id = transports.entry"); if(result) // wrong data found { do diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 70b334b3c3c..f1d8269cd65 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -237,9 +237,11 @@ Unit::~Unit() // set current spells as deletable for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++) { - // spell may be safely deleted now - if (m_currentSpells[i]) m_currentSpells[i]->SetDeletable(true); - m_currentSpells[i] = NULL; + if (m_currentSpells[i]) + { + m_currentSpells[i]->SetReferencedFromCurrent(false); + m_currentSpells[i] = NULL; + } } RemoveAllGameObjects(); @@ -3163,7 +3165,7 @@ void Unit::_UpdateSpells( uint32 time ) { if (m_currentSpells[i] && m_currentSpells[i]->getState() == SPELL_STATE_FINISHED) { - m_currentSpells[i]->SetDeletable(true); // spell may be safely deleted now + m_currentSpells[i]->SetReferencedFromCurrent(false); m_currentSpells[i] = NULL; // remove pointer } } @@ -3276,7 +3278,6 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell ) uint32 CSpellType = pSpell->GetCurrentContainer(); - pSpell->SetDeletable(false); // spell will not be deleted until gone from current pointers if (pSpell == m_currentSpells[CSpellType]) return; // avoid breaking self // break same type spell if it is not delayed @@ -3333,10 +3334,11 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell ) // current spell (if it is still here) may be safely deleted now if (m_currentSpells[CSpellType]) - m_currentSpells[CSpellType]->SetDeletable(true); + m_currentSpells[CSpellType]->SetReferencedFromCurrent(false); // set new current spell m_currentSpells[CSpellType] = pSpell; + pSpell->SetReferencedFromCurrent(true); } void Unit::InterruptSpell(uint32 spellType, bool withDelayed) @@ -3354,7 +3356,7 @@ void Unit::InterruptSpell(uint32 spellType, bool withDelayed) if (m_currentSpells[spellType]->getState() != SPELL_STATE_FINISHED) m_currentSpells[spellType]->cancel(); - m_currentSpells[spellType]->SetDeletable(true); + m_currentSpells[spellType]->SetReferencedFromCurrent(false); m_currentSpells[spellType] = NULL; } } @@ -3390,7 +3392,7 @@ void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id) if ( (m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_FINISHED) && (withDelayed || m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_DELAYED) ) m_currentSpells[CURRENT_GENERIC_SPELL]->cancel(); - m_currentSpells[CURRENT_GENERIC_SPELL]->SetDeletable(true); + m_currentSpells[CURRENT_GENERIC_SPELL]->SetReferencedFromCurrent(false); m_currentSpells[CURRENT_GENERIC_SPELL] = NULL; } @@ -3404,7 +3406,7 @@ void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id) if ( (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() != SPELL_STATE_FINISHED) && (withDelayed || m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() != SPELL_STATE_DELAYED) ) m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->cancel(); - m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->SetDeletable(true); + m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->SetReferencedFromCurrent(false); m_currentSpells[CURRENT_AUTOREPEAT_SPELL] = NULL; } @@ -3413,7 +3415,7 @@ void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id) { if (m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED) m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel(); - m_currentSpells[CURRENT_CHANNELED_SPELL]->SetDeletable(true); + m_currentSpells[CURRENT_CHANNELED_SPELL]->SetReferencedFromCurrent(false); m_currentSpells[CURRENT_CHANNELED_SPELL] = NULL; } } @@ -9860,7 +9862,7 @@ void Unit::CleanupsBeforeDelete() if(m_uint32Values) // only for fully created object { InterruptNonMeleeSpells(true); - m_Events.KillAllEvents(); + m_Events.KillAllEvents(false); // non-delatable (currently casted spells) will not deleted ans will deleated at call in Map::RemoveAllObjectsInRemoveList CombatStop(); ClearComboPointHolders(); DeleteThreatList(); diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 0e6dfedc162..f4e4e1c1d46 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -379,7 +379,7 @@ void WorldSession::LogoutPlayer(bool Save) _player->GetGroup()->SendUpdate(); ///- Broadcast a logout message to the player's friends - sSocialMgr.SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUIDLow(), "", true); + sSocialMgr.SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUIDLow(), true); ///- Delete the player object _player->CleanupsBeforeDelete(); // do some cleanup before deleting to prevent crash at crossreferences to already deleted data diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index 4526d4d7b39..e544891b899 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -281,8 +281,10 @@ class TRINITY_DLL_SPEC WorldSession void HandleEmoteOpcode(WorldPacket& recvPacket); void HandleFriendListOpcode(WorldPacket& recvPacket); void HandleAddFriendOpcode(WorldPacket& recvPacket); + static void HandleAddFriendOpcodeCallBack(QueryResult *result, uint32 accountId, std::string friendNote); void HandleDelFriendOpcode(WorldPacket& recvPacket); void HandleAddIgnoreOpcode(WorldPacket& recvPacket); + static void HandleAddIgnoreOpcodeCallBack(QueryResult *result, uint32 accountId); void HandleDelIgnoreOpcode(WorldPacket& recvPacket); void HandleSetFriendNoteOpcode(WorldPacket& recvPacket); void HandleBugOpcode(WorldPacket& recvPacket); diff --git a/src/shared/Database/Database.h b/src/shared/Database/Database.h index 49d948da7c2..1b9968da720 100644 --- a/src/shared/Database/Database.h +++ b/src/shared/Database/Database.h @@ -61,14 +61,22 @@ class TRINITY_DLL_SPEC Database bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*), const char *sql); template<class Class, typename ParamType1> bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql); + template<class Class, typename ParamType1, typename ParamType2> + bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql); template<typename ParamType1> bool AsyncQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql); + template<typename ParamType1, typename ParamType2> + bool AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql); template<class Class> bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...) ATTR_PRINTF(4,5); template<class Class, typename ParamType1> bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6); + template<class Class, typename ParamType1, typename ParamType2> + bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(5,6); template<typename ParamType1> bool AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6); + template<typename ParamType1, typename ParamType2> + bool AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(5,6); template<class Class> bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*), SqlQueryHolder *holder); template<class Class, typename ParamType1> diff --git a/src/shared/Database/DatabaseImpl.h b/src/shared/Database/DatabaseImpl.h index be3a001a8b7..694ac566db1 100644 --- a/src/shared/Database/DatabaseImpl.h +++ b/src/shared/Database/DatabaseImpl.h @@ -47,6 +47,18 @@ Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamTyp return true; } +template<class Class, typename ParamType1, typename ParamType2> +bool +Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql) +{ + if (!sql) return false; + ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current(); + QueryQueues::iterator itr = m_queryQueues.find(queryThread); + if (itr == m_queryQueues.end()) return false; + m_threadBody->Delay(new SqlQuery(sql, new Trinity::QueryCallback<Class, ParamType1, ParamType2>(object, method, (QueryResult*)NULL, param1, param2), itr->second)); + return true; +} + template<typename ParamType1> bool Database::AsyncQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql) @@ -59,6 +71,18 @@ Database::AsyncQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1 return true; } +template<typename ParamType1, typename ParamType2> +bool +Database::AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql) +{ + if (!sql) return false; + ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current(); + QueryQueues::iterator itr = m_queryQueues.find(queryThread); + if (itr == m_queryQueues.end()) return false; + m_threadBody->Delay(new SqlQuery(sql, new Trinity::SQueryCallback<ParamType1, ParamType2>(method, (QueryResult*)NULL, param1, param2), itr->second)); + return true; +} + template<class Class> bool Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...) @@ -101,6 +125,27 @@ Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamTy return AsyncQuery(object, method, param1, szQuery); } +template<class Class, typename ParamType1, typename ParamType2> +bool +Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) +{ + if(!format) return false; + + va_list ap; + char szQuery [MAX_QUERY_LEN]; + va_start(ap, format); + int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap ); + va_end(ap); + + if(res==-1) + { + sLog.outError("SQL Query truncated (and not execute) for format: %s",format); + return false; + } + + return AsyncQuery(object, method, param1, param2, szQuery); +} + template<typename ParamType1> bool Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) @@ -122,6 +167,26 @@ Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param return AsyncQuery(method, param1, szQuery); } +template<typename ParamType1, typename ParamType2> +bool +Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) +{ + if(!format) return false; + + va_list ap; + char szQuery [MAX_QUERY_LEN]; + va_start(ap, format); + int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap ); + va_end(ap); + + if(res==-1) + { + sLog.outError("SQL Query truncated (and not execute) for format: %s",format); + return false; + } + + return AsyncQuery(method, param1, param2, szQuery); +} template<class Class> bool |