diff options
| -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  | 
