diff options
| author | Xanadu <none@none> | 2010-12-23 05:49:23 +0100 | 
|---|---|---|
| committer | Xanadu <none@none> | 2010-12-23 05:49:23 +0100 | 
| commit | cfa26522adccff5c42ce34668783ad50d6f3af59 (patch) | |
| tree | b794fc706934ad6ce3ec8aee2224f14d452c0267 /src | |
| parent | 66b4c8003c8b6ed4b826ba5b0da512f4dd073f68 (diff) | |
Core: Fixed occasional wrong order of async operations at respawn time saving. Closes issue #5239.
DB schema: Sorted out a discrepancy in respawn time column format.
--HG--
branch : trunk
Diffstat (limited to 'src')
7 files changed, 73 insertions, 29 deletions
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 3ff9d38e0ee..3105a026b84 100755 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -1577,7 +1577,7 @@ void Battleground::SpawnBGCreature(uint32 type, uint32 respawntime)          {              //obj->Respawn();                               // bugged              obj->SetRespawnTime(0); -            sObjectMgr->SaveCreatureRespawnTime(obj->GetGUIDLow(), GetInstanceID(), 0); +            sObjectMgr->RemoveCreatureRespawnTime(obj->GetGUIDLow(), GetInstanceID());              map->Add(obj);          }      } diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 3cf4d08e841..6d4a5443344 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1396,7 +1396,7 @@ void Creature::DeleteFromDB()          return;      } -    sObjectMgr->SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); +    sObjectMgr->RemoveCreatureRespawnTime(m_DBTableGuid, GetInstanceId());      sObjectMgr->DeleteCreatureData(m_DBTableGuid);      SQLTransaction trans = WorldDatabase.BeginTransaction(); @@ -1587,7 +1587,7 @@ void Creature::Respawn(bool force)      if (getDeathState() == DEAD)      {          if (m_DBTableGuid) -            sObjectMgr->SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); +            sObjectMgr->RemoveCreatureRespawnTime(m_DBTableGuid, GetInstanceId());          sLog.outStaticDebug("Respawning...");          m_respawnTime = 0; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 5dad68c2ab7..554c165513b 100755 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -742,7 +742,7 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)              if (m_respawnTime && m_respawnTime <= time(NULL))              {                  m_respawnTime = 0; -                sObjectMgr->SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),0); +                sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId());              }          }      } @@ -760,7 +760,7 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)  void GameObject::DeleteFromDB()  { -    sObjectMgr->SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),0); +    sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId());      sObjectMgr->DeleteGOData(m_DBTableGuid);      WorldDatabase.PExecute("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid);      WorldDatabase.PExecute("DELETE FROM game_event_gameobject WHERE guid = '%u'", m_DBTableGuid); @@ -853,7 +853,7 @@ void GameObject::Respawn()      if (m_spawnedByDefault && m_respawnTime > 0)      {          m_respawnTime = time(NULL); -        sObjectMgr->SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),0); +        sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId());      }  } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 4b3b319dff9..b7d875127b8 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1842,9 +1842,9 @@ void ObjectMgr::LoadGameobjectRespawnTimes()  {      uint32 oldMSTime = getMSTime(); -    // remove outdated data -    PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GAMEOBJECT_RESPAWN_TIMES); -    CharacterDatabase.Execute(stmt); +    // Remove outdated data +    PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_EXPIRED_GO_RESPAWN_TIMES); +    CharacterDatabase.DirectExecute(stmt);      uint32 count = 0; @@ -7459,26 +7459,40 @@ void ObjectMgr::LoadNPCSpellClickSpells()  void ObjectMgr::SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t)  { -    // This function can be Called from various map threads concurrently +    if (!t) +    { +        // Delete only +        RemoveCreatureRespawnTime(loguid, instance); +        return; +    } +     +    // This function can be called from various map threads concurrently      {          m_CreatureRespawnTimesMtx.acquire(); -        mCreatureRespawnTimes[MAKE_PAIR64(loguid,instance)] = t; +        mCreatureRespawnTimes[MAKE_PAIR64(loguid, instance)] = t;          m_CreatureRespawnTimesMtx.release();      } -    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CRESPAWNTIME); +    PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_CREATURE_RESPAWN_TIME);      stmt->setUInt32(0, loguid); -    stmt->setUInt32(1, instance); +    stmt->setUInt64(1, uint64(t)); +    stmt->setUInt32(2, instance);      CharacterDatabase.Execute(stmt); +} -    if (t) +void ObjectMgr::RemoveCreatureRespawnTime(uint32 loguid, uint32 instance) +{ +    // This function can be called from various map threads concurrently      { -        stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_CRESPAWNTIME); -        stmt->setUInt32(0, loguid); -        stmt->setUInt64(1, uint64(t)); -        stmt->setUInt32(2, instance); -        CharacterDatabase.Execute(stmt); +        m_CreatureRespawnTimesMtx.acquire(); +        mCreatureRespawnTimes[MAKE_PAIR64(loguid, instance)] = 0; +        m_CreatureRespawnTimesMtx.release();      } + +    PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN_TIME); +    stmt->setUInt32(0, loguid); +    stmt->setUInt32(1, instance); +    CharacterDatabase.Execute(stmt);  }  void ObjectMgr::DeleteCreatureData(uint32 guid) @@ -7493,16 +7507,40 @@ void ObjectMgr::DeleteCreatureData(uint32 guid)  void ObjectMgr::SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t)  { +    if (!t) +    { +        // Delete only +        RemoveGORespawnTime(loguid, instance); +        return; +    } +     +    // This function can be called from different map threads concurrently +    { +        m_GORespawnTimesMtx.acquire(); +        mGORespawnTimes[MAKE_PAIR64(loguid, instance)] = t; +        m_GORespawnTimesMtx.release(); +    } + +    PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_GO_RESPAWN_TIME); +    stmt->setUInt32(0, loguid); +    stmt->setUInt64(1, uint64(t)); +    stmt->setUInt32(2, instance); +    CharacterDatabase.Execute(stmt); +} + +void ObjectMgr::RemoveGORespawnTime(uint32 loguid, uint32 instance) +{      // This function can be called from different map threads concurrently      {          m_GORespawnTimesMtx.acquire(); -        mGORespawnTimes[MAKE_PAIR64(loguid,instance)] = t; +        mGORespawnTimes[MAKE_PAIR64(loguid, instance)] = 0;          m_GORespawnTimesMtx.release();      } -    CharacterDatabase.PExecute("DELETE FROM gameobject_respawn WHERE guid = '%u' AND instance = '%u'", loguid, instance); -    if (t) -        CharacterDatabase.PExecute("INSERT INTO gameobject_respawn VALUES ('%u', '" UI64FMTD "', '%u')", loguid, uint64(t), instance); +    PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN_TIME); +    stmt->setUInt32(0, loguid); +    stmt->setUInt32(1, instance); +    CharacterDatabase.Execute(stmt);  }  void ObjectMgr::DeleteRespawnTimeForInstance(uint32 instance) diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 1c2bbc98e72..09ceef4fc83 100755 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -1079,12 +1079,14 @@ class ObjectMgr              return mCreatureRespawnTimes[MAKE_PAIR64(loguid,instance)];          }          void SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t); +        void RemoveCreatureRespawnTime(uint32 loguid, uint32 instance);          time_t GetGORespawnTime(uint32 loguid, uint32 instance)          {              ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, m_GORespawnTimesMtx, 0);              return mGORespawnTimes[MAKE_PAIR64(loguid,instance)];          }          void SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t); +        void RemoveGORespawnTime(uint32 loguid, uint32 instance);          void DeleteRespawnTimeForInstance(uint32 instance);          // grid objects diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index 63cbac6ead0..598223415c0 100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -237,9 +237,11 @@ bool CharacterDatabaseConnection::Open()      PrepareStatement(CHAR_CLEAN_GUILD_BANK_TABS, "DELETE FROM guild_bank_tab WHERE guildId NOT IN (SELECT guildid FROM guild)", true);      PrepareStatement(CHAR_CLEAN_GUILD_BANK_RIGHTS, "DELETE FROM guild_bank_right WHERE guildId NOT IN (SELECT guildid FROM guild)", true);      PrepareStatement(CHAR_CLEAN_GUILD_BANK_ITEMS, "DELETE FROM guild_bank_item WHERE guildId NOT IN (SELECT guildid FROM guild)", true); -    PrepareStatement(CHAR_DEL_GAMEOBJECT_RESPAWN_TIMES, "DELETE FROM gameobject_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())", true); -    PrepareStatement(CHAR_DEL_CRESPAWNTIME, "DELETE FROM creature_respawn WHERE guid = ? AND instance = ?", true); -    PrepareStatement(CHAR_ADD_CRESPAWNTIME, "INSERT INTO creature_respawn VALUES (?, ?, ?)", true); +    PrepareStatement(CHAR_DEL_CREATURE_RESPAWN_TIME, "DELETE FROM creature_respawn WHERE guid = ? AND instance = ?", true); +    PrepareStatement(CHAR_ADD_CREATURE_RESPAWN_TIME, "REPLACE INTO creature_respawn VALUES (?, ?, ?)", true); +    PrepareStatement(CHAR_DEL_EXPIRED_GO_RESPAWN_TIMES, "DELETE FROM gameobject_respawn WHERE respawntime <= UNIX_TIMESTAMP()"); +    PrepareStatement(CHAR_DEL_GO_RESPAWN_TIME, "DELETE FROM gameobject_respawn WHERE guid = ? AND instance = ?", true); +    PrepareStatement(CHAR_ADD_GO_RESPAWN_TIME, "REPLACE INTO gameobject_respawn VALUES (?, ?, ?)", true);      // Chat channel handling      PrepareStatement(CHAR_LOAD_CHANNEL, "SELECT m_announce, m_ownership, m_password, BannedList FROM channels WHERE m_name = ? AND m_team = ?"); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index e9b83fcfad8..3d203bf67e3 100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -196,9 +196,11 @@ enum CharacterDatabaseStatements      CHAR_CLEAN_GUILD_BANK_RIGHTS,      CHAR_CLEAN_GUILD_BANK_ITEMS, -    CHAR_DEL_GAMEOBJECT_RESPAWN_TIMES, -    CHAR_DEL_CRESPAWNTIME, -    CHAR_ADD_CRESPAWNTIME, +    CHAR_DEL_CREATURE_RESPAWN_TIME, +    CHAR_ADD_CREATURE_RESPAWN_TIME, +    CHAR_DEL_EXPIRED_GO_RESPAWN_TIMES, +    CHAR_DEL_GO_RESPAWN_TIME, +    CHAR_ADD_GO_RESPAWN_TIME,      CHAR_LOAD_CHANNEL,      CHAR_ADD_CHANNEL,  | 
