Skip to content

Commit

Permalink
MODIFIED: Achievements are now loaded and saved asynchronously using …
Browse files Browse the repository at this point in the history
…the QueryBuffer of each Player, http://arcemu.org/forums/index.php?showtopic=20490 , thanks Shauren.
  • Loading branch information
jackpoz committed Dec 16, 2010
1 parent 2e3ed30 commit d5565b5
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 17 deletions.
34 changes: 25 additions & 9 deletions src/arcemu-world/AchievementMgr.cpp
Expand Up @@ -202,7 +202,7 @@ AchievementMgr::~AchievementMgr()
Save Achievement data to database
Saves all completed achievements to database. Saves all achievement progresses that have been started, and that aren't calculated on login, to database.
*/
void AchievementMgr::SaveToDB()
void AchievementMgr::SaveToDB(QueryBuffer *buf)
{
if( !m_completedAchievements.empty() )
{
Expand All @@ -212,7 +212,10 @@ void AchievementMgr::SaveToDB()
ss << m_player->GetLowGUID();
ss << ";";

CharacterDatabase.ExecuteNA( ss.str().c_str() );
if(buf == NULL)
CharacterDatabase.ExecuteNA( ss.str().c_str() );
else
buf->AddQueryNA( ss.str().c_str() );

ss.rdbuf()->str("");

Expand All @@ -223,7 +226,10 @@ void AchievementMgr::SaveToDB()
if( ss.str().length() >= 16000 )
{
// SQL query length is limited to 16384 characters
CharacterDatabase.ExecuteNA( ss.str().c_str() );
if(buf == NULL)
CharacterDatabase.ExecuteNA( ss.str().c_str() );
else
buf->AddQueryNA( ss.str().c_str() );
ss.str("");
ss << "INSERT INTO character_achievement VALUES ";
first = true;
Expand All @@ -239,7 +245,10 @@ void AchievementMgr::SaveToDB()
}
ss << "(" << m_player->GetLowGUID() << ", " << iter->first << ", " << iter->second << ")";
}
CharacterDatabase.ExecuteNA( ss.str().c_str() );
if(buf == NULL)
CharacterDatabase.ExecuteNA( ss.str().c_str() );
else
buf->AddQueryNA( ss.str().c_str() );
}

if( !m_criteriaProgress.empty() )
Expand All @@ -250,7 +259,10 @@ void AchievementMgr::SaveToDB()
ss << m_player->GetLowGUID();
ss << ";";

CharacterDatabase.ExecuteNA( ss.str().c_str() );
if(buf == NULL)
CharacterDatabase.ExecuteNA( ss.str().c_str() );
else
buf->AddQueryNA( ss.str().c_str() );

ss.rdbuf()->str("");

Expand All @@ -264,7 +276,10 @@ void AchievementMgr::SaveToDB()
if( ss.str().length() >= 16000 )
{
// SQL query length is limited to 16384 characters
CharacterDatabase.ExecuteNA( ss.str().c_str() );
if(buf == NULL)
CharacterDatabase.ExecuteNA( ss.str().c_str() );
else
buf->AddQueryNA( ss.str().c_str() );
ss.str("");
ss << "INSERT INTO character_achievement_progress VALUES ";
first = true;
Expand All @@ -283,7 +298,10 @@ void AchievementMgr::SaveToDB()
if( !first )
{
// don't execute query if there's no entries to save
CharacterDatabase.ExecuteNA( ss.str().c_str() );
if(buf == NULL)
CharacterDatabase.ExecuteNA( ss.str().c_str() );
else
buf->AddQueryNA( ss.str().c_str() );
}
}
}
Expand All @@ -305,7 +323,6 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri
else
sLog.outError("Duplicate completed achievement %u for player %u, skipping", id, (uint32)m_player->GetGUID() );
} while(achievementResult->NextRow());
delete achievementResult;
}

if( criteriaResult )
Expand All @@ -323,7 +340,6 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri
sLog.outError( "Duplicate criteria progress %u for player %u, skipping", progress_id, (uint32) m_player->GetGUID() );

}while( criteriaResult->NextRow() );
delete criteriaResult;
}
}

Expand Down
5 changes: 1 addition & 4 deletions src/arcemu-world/AchievementMgr.h
Expand Up @@ -263,11 +263,8 @@ class SERVER_DECL AchievementMgr
public:
AchievementMgr(Player* pl);
~AchievementMgr();
// !IMPORTANT!
// Todo: Use QueryBuffer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// THIS IS WHY WE GET SO MUCH LAGGGGGGGGGGGG.
void LoadFromDB(QueryResult *achievementResult, QueryResult *criteriaResult);
void SaveToDB();
void SaveToDB(QueryBuffer *buf);
void CheckAllAchievementCriteria();
void SendAllAchievementData(Player* player);
void UpdateAchievementCriteria(AchievementCriteriaTypes type, int32 miscvalue1, int32 miscvalue2, uint32 time);
Expand Down
12 changes: 8 additions & 4 deletions src/arcemu-world/Player.cpp
Expand Up @@ -2648,12 +2648,12 @@ void Player::SaveToDB(bool bNewCharacter /* =false */)
_SavePetSpells(buf);
}
m_nextSave = getMSTime() + sWorld.getIntRate(INTRATE_SAVE);
#ifdef ENABLE_ACHIEVEMENTS
m_achievementMgr.SaveToDB(buf);
#endif

if(buf)
CharacterDatabase.AddQueryBuffer(buf);
#ifdef ENABLE_ACHIEVEMENTS
m_achievementMgr.SaveToDB();
#endif
}

void Player::_SaveQuestLogEntry(QueryBuffer * buf)
Expand Down Expand Up @@ -2753,6 +2753,10 @@ bool Player::LoadFromDB(uint32 guid)
q->AddQuery("SELECT SpellID FROM playerdeletedspells WHERE GUID = %u", guid ); // 13
q->AddQuery("SELECT SkillID, CurrentValue, MaximumValue FROM playerskills WHERE GUID = %u", guid ); // 14

//Achievements
q->AddQuery("SELECT achievement, date FROM character_achievement WHERE guid = '%u'", guid); // 15
q->AddQuery("SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = '%u'", guid); // 16

// queue it!
SetLowGUID( guid );
CharacterDatabase.QueueAsyncQuery(q);
Expand Down Expand Up @@ -2870,7 +2874,7 @@ void Player::LoadFromDBProc(QueryResultVector & results)

// load achievements before anything else otherwise skills would complete achievements already in the DB, leading to duplicate achievements and criterias(like achievement=126).
#ifdef ENABLE_ACHIEVEMENTS
m_achievementMgr.LoadFromDB(CharacterDatabase.Query("SELECT achievement, date FROM character_achievement WHERE guid = '%u'", GetLowGUID() ),CharacterDatabase.Query("SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = '%u'", GetLowGUID() ));
m_achievementMgr.LoadFromDB(results[15].result, results[16].result);
#endif

CalculateBaseStats();
Expand Down

0 comments on commit d5565b5

Please sign in to comment.