- Use ACE_Future and ACE_Future_Set for async SQL queries with callback
* Callbacks will now be executed from the thread and object that scheduled the request, instead of the world runnable thread (and thus are no longer dependent on the 50ms forced sleep time).
* This design gets rid of a potential DOS loophole in the resultqueue system - unique requests will be cancelled when re-requested.
- Drop now redundant SQLQueryTask, SQLResultQueue, SQLResultQueueTask operations.
- Drop now redundant CharacterHandler class
- Change static callback functions in WorldSession to normal functions.

Thanks to Derex and Zor for advice along the way.

--HG--
branch : trunk
This commit is contained in:
Machiavelli
2010-08-18 19:48:51 +02:00
parent 2ffe785765
commit d845a903b1
15 changed files with 303 additions and 862 deletions
@@ -59,7 +59,6 @@
#include "OutdoorPvPMgr.h"
#include "ArenaTeam.h"
#include "Chat.h"
#include "AsyncDatabaseImpl.h"
#include "Spell.h"
#include "SocialMgr.h"
#include "GameEventMgr.h"
@@ -27,7 +27,6 @@
#include "WorldSession.h"
#include "MD5.h"
#include "DatabaseEnv.h"
#include "AsyncDatabaseImpl.h"
#include "ArenaTeam.h"
#include "Chat.h"
@@ -103,33 +102,6 @@ bool LoginQueryHolder::Initialize()
return res;
}
// don't call WorldSession directly
// it may get deleted before the query callbacks get executed
// instead pass an account id to this handler
class CharacterHandler
{
public:
void HandleCharEnumCallback(QueryResult_AutoPtr result, uint32 account)
{
WorldSession * session = sWorld.FindSession(account);
if (!session)
return;
session->HandleCharEnum(result);
}
void HandlePlayerLoginCallback(QueryResult_AutoPtr /*dummy*/, SQLQueryHolder * holder)
{
if (!holder) return;
WorldSession *session = sWorld.FindSession(((LoginQueryHolder*)holder)->GetAccountId());
if (!session)
{
delete holder;
return;
}
session->HandlePlayerLogin((LoginQueryHolder*)holder);
}
} chrHandler;
void WorldSession::HandleCharEnum(QueryResult_AutoPtr result)
{
WorldPacket data(SMSG_CHAR_ENUM, 100); // we guess size
@@ -158,31 +130,33 @@ void WorldSession::HandleCharEnum(QueryResult_AutoPtr result)
void WorldSession::HandleCharEnumOpcode(WorldPacket & /*recv_data*/)
{
/// get all the data necessary for loading all characters (along with their pets) on the account
CharacterDatabase.AsyncPQuery(&chrHandler, &CharacterHandler::HandleCharEnumCallback, GetAccountId(),
!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) ?
// ------- Query Without Declined Names --------
// 0 1 2 3 4 5 6 7
"SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
// 8 9 10 11 12 13 14
"characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
// 15 16 17 18 19
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache "
"FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='%u' "
"LEFT JOIN guild_member ON characters.guid = guild_member.guid "
"WHERE characters.account = '%u' ORDER BY characters.guid"
:
// --------- Query With Declined Names ---------
// 0 1 2 3 4 5 6 7
"SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
// 8 9 10 11 12 13 14
"characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
// 15 16 17 18 19 20
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache, character_declinedname.genitive "
"FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='%u' "
"LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid "
"LEFT JOIN guild_member ON characters.guid = guild_member.guid "
"WHERE characters.account = '%u' ORDER BY characters.guid",
PET_SAVE_AS_CURRENT,GetAccountId());
m_charEnumCallback =
CharacterDatabase.AsyncPQuery(
!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) ?
// ------- Query Without Declined Names --------
// 0 1 2 3 4 5 6 7
"SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
// 8 9 10 11 12 13 14
"characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
// 15 16 17 18 19
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache "
"FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='%u' "
"LEFT JOIN guild_member ON characters.guid = guild_member.guid "
"WHERE characters.account = '%u' ORDER BY characters.guid"
:
// --------- Query With Declined Names ---------
// 0 1 2 3 4 5 6 7
"SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
// 8 9 10 11 12 13 14
"characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
// 15 16 17 18 19 20
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache, character_declinedname.genitive "
"FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='%u' "
"LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid "
"LEFT JOIN guild_member ON characters.guid = guild_member.guid "
"WHERE characters.account = '%u' ORDER BY characters.guid",
PET_SAVE_AS_CURRENT, GetAccountId()
);
}
void WorldSession::HandleCharCreateOpcode(WorldPacket & recv_data)
@@ -565,7 +539,7 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket & recv_data)
return;
}
CharacterDatabase.DelayQueryHolder(&chrHandler, &CharacterHandler::HandlePlayerLoginCallback, holder);
m_charLoginCallback = CharacterDatabase.DelayQueryHolder((SQLQueryHolder*)holder);
}
void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
@@ -957,24 +931,22 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data)
// make sure that the character belongs to the current account, that rename at login is enabled
// and that there is no character with the desired new name
CharacterDatabase.AsyncPQuery(&WorldSession::HandleChangePlayerNameOpcodeCallBack,
GetAccountId(), newname,
m_charRenameCallback.SetParam(newname);
m_charRenameCallback.SetFutureResult(
CharacterDatabase.AsyncPQuery(
"SELECT guid, name FROM characters WHERE guid = %d AND account = %d AND (at_login & %d) = %d AND NOT EXISTS (SELECT NULL FROM characters WHERE name = '%s')",
GUID_LOPART(guid), GetAccountId(), AT_LOGIN_RENAME, AT_LOGIN_RENAME, escaped_newname.c_str()
);
)
);
}
void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult_AutoPtr result, uint32 accountId, std::string newname)
void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult_AutoPtr result, std::string newname)
{
WorldSession * session = sWorld.FindSession(accountId);
if (!session)
return;
if (!result)
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
data << uint8(CHAR_CREATE_ERROR);
session->SendPacket(&data);
SendPacket(&data);
return;
}
@@ -985,13 +957,13 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult_AutoPtr resu
CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME), guidLow);
CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", guidLow);
sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", session->GetAccountId(), session->GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str());
sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str());
WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newname.size()+1));
data << uint8(RESPONSE_SUCCESS);
data << uint64(guid);
data << newname;
session->SendPacket(&data);
SendPacket(&data);
}
void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data)
@@ -21,7 +21,6 @@
#include "Common.h"
#include "Language.h"
#include "DatabaseEnv.h"
#include "AsyncDatabaseImpl.h"
#include "WorldPacket.h"
#include "Opcodes.h"
#include "Log.h"
@@ -554,21 +553,19 @@ void WorldSession::HandleAddFriendOpcode(WorldPacket & recv_data)
sLog.outDebug("WORLD: %s asked to add friend : '%s'",
GetPlayer()->GetName(), friendName.c_str());
CharacterDatabase.AsyncPQuery(&WorldSession::HandleAddFriendOpcodeCallBack, GetAccountId(), friendNote, "SELECT guid, race, account FROM characters WHERE name = '%s'", friendName.c_str());
m_addFriendCallback.SetParam(friendNote);
m_addFriendCallback.SetFutureResult(
CharacterDatabase.AsyncPQuery("SELECT guid, race, account FROM characters WHERE name = '%s'", friendName.c_str())
);
}
void WorldSession::HandleAddFriendOpcodeCallBack(QueryResult_AutoPtr result, uint32 accountId, std::string friendNote)
void WorldSession::HandleAddFriendOpcodeCallBack(QueryResult_AutoPtr result, std::string friendNote)
{
uint64 friendGuid;
uint64 friendAcctid;
uint32 team;
FriendsResult friendResult;
WorldSession * session = sWorld.FindSession(accountId);
if (!session || !session->GetPlayer())
return;
friendResult = FRIEND_NOT_FOUND;
friendGuid = 0;
@@ -578,35 +575,35 @@ void WorldSession::HandleAddFriendOpcodeCallBack(QueryResult_AutoPtr result, uin
team = Player::TeamForRace((*result)[1].GetUInt8());
friendAcctid = (*result)[2].GetUInt32();
if (session->GetSecurity() >= SEC_MODERATOR || sWorld.getConfig(CONFIG_ALLOW_GM_FRIEND) || sAccountMgr.GetSecurity(friendAcctid) < SEC_MODERATOR)
if (GetSecurity() >= SEC_MODERATOR || sWorld.getConfig(CONFIG_ALLOW_GM_FRIEND) || sAccountMgr.GetSecurity(friendAcctid) < SEC_MODERATOR)
{
if (friendGuid)
{
if (friendGuid == session->GetPlayer()->GetGUID())
if (friendGuid == GetPlayer()->GetGUID())
friendResult = FRIEND_SELF;
else if (session->GetPlayer()->GetTeam() != team && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && session->GetSecurity() < SEC_MODERATOR)
else if (GetPlayer()->GetTeam() != team && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && GetSecurity() < SEC_MODERATOR)
friendResult = FRIEND_ENEMY;
else if (session->GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid)))
else if (GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid)))
friendResult = FRIEND_ALREADY;
else
{
Player* pFriend = ObjectAccessor::FindPlayer(friendGuid);
if (pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(session->GetPlayer()))
if (pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(GetPlayer()))
friendResult = FRIEND_ADDED_ONLINE;
else
friendResult = FRIEND_ADDED_OFFLINE;
if (!session->GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(friendGuid), false))
if (!GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(friendGuid), false))
{
friendResult = FRIEND_LIST_FULL;
sLog.outDebug("WORLD: %s's friend list is full.", session->GetPlayer()->GetName());
sLog.outDebug("WORLD: %s's friend list is full.", GetPlayer()->GetName());
}
}
session->GetPlayer()->GetSocial()->SetFriendNote(GUID_LOPART(friendGuid), friendNote);
GetPlayer()->GetSocial()->SetFriendNote(GUID_LOPART(friendGuid), friendNote);
}
}
}
sSocialMgr.SendFriendStatus(session->GetPlayer(), friendResult, GUID_LOPART(friendGuid), false);
sSocialMgr.SendFriendStatus(GetPlayer(), friendResult, GUID_LOPART(friendGuid), false);
sLog.outDebug("WORLD: Sent (SMSG_FRIEND_STATUS)");
}
@@ -642,19 +639,14 @@ void WorldSession::HandleAddIgnoreOpcode(WorldPacket & recv_data)
sLog.outDebug("WORLD: %s asked to Ignore: '%s'",
GetPlayer()->GetName(), IgnoreName.c_str());
CharacterDatabase.AsyncPQuery(&WorldSession::HandleAddIgnoreOpcodeCallBack, GetAccountId(), "SELECT guid FROM characters WHERE name = '%s'", IgnoreName.c_str());
m_addIgnoreCallback = CharacterDatabase.AsyncPQuery("SELECT guid FROM characters WHERE name = '%s'", IgnoreName.c_str());
}
void WorldSession::HandleAddIgnoreOpcodeCallBack(QueryResult_AutoPtr result, uint32 accountId)
void WorldSession::HandleAddIgnoreOpcodeCallBack(QueryResult_AutoPtr result)
{
uint64 IgnoreGuid;
FriendsResult ignoreResult;
WorldSession * session = sWorld.FindSession(accountId);
if (!session || !session->GetPlayer())
return;
ignoreResult = FRIEND_IGNORE_NOT_FOUND;
IgnoreGuid = 0;
@@ -664,22 +656,22 @@ void WorldSession::HandleAddIgnoreOpcodeCallBack(QueryResult_AutoPtr result, uin
if (IgnoreGuid)
{
if (IgnoreGuid == session->GetPlayer()->GetGUID()) //not add yourself
if (IgnoreGuid == GetPlayer()->GetGUID()) //not add yourself
ignoreResult = FRIEND_IGNORE_SELF;
else if (session->GetPlayer()->GetSocial()->HasIgnore(GUID_LOPART(IgnoreGuid)))
else if (GetPlayer()->GetSocial()->HasIgnore(GUID_LOPART(IgnoreGuid)))
ignoreResult = FRIEND_IGNORE_ALREADY;
else
{
ignoreResult = FRIEND_IGNORE_ADDED;
// ignore list full
if (!session->GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(IgnoreGuid), true))
if (!GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(IgnoreGuid), true))
ignoreResult = FRIEND_IGNORE_FULL;
}
}
}
sSocialMgr.SendFriendStatus(session->GetPlayer(), ignoreResult, GUID_LOPART(IgnoreGuid), false);
sSocialMgr.SendFriendStatus(GetPlayer(), ignoreResult, GUID_LOPART(IgnoreGuid), false);
sLog.outDebug("WORLD: Sent (SMSG_FRIEND_STATUS)");
}
@@ -21,7 +21,6 @@
#include "Common.h"
#include "Language.h"
#include "DatabaseEnv.h"
#include "AsyncDatabaseImpl.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Opcodes.h"
@@ -61,37 +60,37 @@ void WorldSession::SendNameQueryOpcode(Player *p)
void WorldSession::SendNameQueryOpcodeFromDB(uint64 guid)
{
CharacterDatabase.AsyncPQuery(&WorldSession::SendNameQueryOpcodeFromDBCallBack, GetAccountId(),
!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) ?
// ------- Query Without Declined Names --------
// 0 1 2 3 4
"SELECT guid, name, race, gender, class "
"FROM characters WHERE guid = '%u'"
:
// --------- Query With Declined Names ---------
// 0 1 2 3 4
"SELECT characters.guid, name, race, gender, class, "
// 5 6 7 8 9
"genitive, dative, accusative, instrumental, prepositional "
"FROM characters LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid WHERE characters.guid = '%u'",
GUID_LOPART(guid));
m_nameQueryCallbacks.insert(
CharacterDatabase.AsyncPQuery(
!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) ?
// ------- Query Without Declined Names --------
// 0 1 2 3 4
"SELECT guid, name, race, gender, class "
"FROM characters WHERE guid = '%u'"
:
// --------- Query With Declined Names ---------
// 0 1 2 3 4
"SELECT characters.guid, name, race, gender, class, "
// 5 6 7 8 9
"genitive, dative, accusative, instrumental, prepositional "
"FROM characters LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid WHERE characters.guid = '%u'",
GUID_LOPART(guid))
);
// CharacterDatabase.AsyncPQuery(&WorldSession::SendNameQueryOpcodeFromDBCallBack, GetAccountId(),
}
void WorldSession::SendNameQueryOpcodeFromDBCallBack(QueryResult_AutoPtr result, uint32 accountId)
void WorldSession::SendNameQueryOpcodeFromDBCallBack(QueryResult_AutoPtr result)
{
if (!result)
return;
WorldSession * session = sWorld.FindSession(accountId);
if (!session)
return;
Field *fields = result->Fetch();
uint32 guid = fields[0].GetUInt32();
std::string name = fields[1].GetCppString();
uint8 pRace = 0, pGender = 0, pClass = 0;
if (name == "")
name = session->GetTrinityString(LANG_NON_EXIST_CHARACTER);
name = GetTrinityString(LANG_NON_EXIST_CHARACTER);
else
{
pRace = fields[2].GetUInt8();
@@ -118,7 +117,7 @@ void WorldSession::SendNameQueryOpcodeFromDBCallBack(QueryResult_AutoPtr result,
else
data << uint8(0); // is not declined
session->SendPacket(&data);
SendPacket(&data);
}
void WorldSession::HandleNameQueryOpcode(WorldPacket & recv_data)
+62
View File
@@ -290,6 +290,8 @@ bool WorldSession::Update(uint32 diff)
delete packet;
}
ProcessQueryCallbacks();
time_t currTime = time(NULL);
///- If necessary, log the player out
if (ShouldLogOut(currTime) && !m_playerLoading)
@@ -955,3 +957,63 @@ void WorldSession::SetPlayer(Player *plr)
if (_player)
m_GUIDLow = _player->GetGUIDLow();
}
void WorldSession::ProcessQueryCallbacks()
{
QueryResult_AutoPtr result;
//! HandleNameQueryOpcode
while (!m_nameQueryCallbacks.is_empty())
{
QueryResultFuture lResult;
ACE_Time_Value timeout = ACE_Time_Value::zero;
if (m_nameQueryCallbacks.next_readable(lResult, &timeout) != 1)
break;
lResult.get(result);
SendNameQueryOpcodeFromDBCallBack(result);
}
//! HandleCharEnumOpcode
if (m_charEnumCallback.ready())
{
m_charEnumCallback.get(result);
HandleCharEnum(result);
m_charEnumCallback.cancel();
}
//! HandlePlayerLoginOpcode
if (m_charLoginCallback.ready())
{
SQLQueryHolder* param;
m_charLoginCallback.get(param);
HandlePlayerLogin((LoginQueryHolder*)param);
m_charLoginCallback.cancel();
}
//! HandleAddFriendOpcode
if (m_addFriendCallback.IsReady())
{
std::string& param = m_addFriendCallback.GetParam();
m_addFriendCallback.GetResult(result);
HandleAddFriendOpcodeCallBack(result, param);
m_addFriendCallback.FreeResult();
}
//- HandleCharRenameOpcode
if (m_charRenameCallback.IsReady())
{
std::string& param = m_charRenameCallback.GetParam();
m_charRenameCallback.GetResult(result);
HandleChangePlayerNameOpcodeCallBack(result, param);
m_charRenameCallback.FreeResult();
}
//- HandleCharAddIgnoreOpcode
if (m_addIgnoreCallback.ready())
{
m_addIgnoreCallback.get(result);
HandleAddIgnoreOpcodeCallBack(result);
m_addIgnoreCallback.cancel();
}
}
+15 -4
View File
@@ -192,7 +192,7 @@ class WorldSession
//void SendTestCreatureQueryOpcode(uint32 entry, uint64 guid, uint32 testvalue);
void SendNameQueryOpcode(Player* p);
void SendNameQueryOpcodeFromDB(uint64 guid);
static void SendNameQueryOpcodeFromDBCallBack(QueryResult_AutoPtr result, uint32 accountId);
void SendNameQueryOpcodeFromDBCallBack(QueryResult_AutoPtr result);
void SendTrainerList(uint64 guid);
void SendTrainerList(uint64 guid, const std::string& strTitle);
@@ -389,10 +389,10 @@ class WorldSession
void HandleEmoteOpcode(WorldPacket& recvPacket);
void HandleContactListOpcode(WorldPacket& recvPacket);
void HandleAddFriendOpcode(WorldPacket& recvPacket);
static void HandleAddFriendOpcodeCallBack(QueryResult_AutoPtr result, uint32 accountId, std::string friendNote);
void HandleAddFriendOpcodeCallBack(QueryResult_AutoPtr result, std::string friendNote);
void HandleDelFriendOpcode(WorldPacket& recvPacket);
void HandleAddIgnoreOpcode(WorldPacket& recvPacket);
static void HandleAddIgnoreOpcodeCallBack(QueryResult_AutoPtr result, uint32 accountId);
void HandleAddIgnoreOpcodeCallBack(QueryResult_AutoPtr result);
void HandleDelIgnoreOpcode(WorldPacket& recvPacket);
void HandleSetContactNotesOpcode(WorldPacket& recvPacket);
void HandleBugOpcode(WorldPacket& recvPacket);
@@ -665,7 +665,7 @@ class WorldSession
void HandleSetActionBarToggles(WorldPacket& recv_data);
void HandleCharRenameOpcode(WorldPacket& recv_data);
static void HandleChangePlayerNameOpcodeCallBack(QueryResult_AutoPtr result, uint32 accountId, std::string newname);
void HandleChangePlayerNameOpcodeCallBack(QueryResult_AutoPtr result, std::string newname);
void HandleSetPlayerDeclinedNames(WorldPacket& recv_data);
void HandleTotemDestroyed(WorldPacket& recv_data);
@@ -798,6 +798,17 @@ class WorldSession
void HandleQuestPOIQuery(WorldPacket& recv_data);
void HandleEjectPasenger(WorldPacket &data);
void HandleEnterPlayerVehicle(WorldPacket &data);
private:
void ProcessQueryCallbacks();
QueryResultFutureSet m_nameQueryCallbacks;
QueryResultFuture m_charEnumCallback;
QueryResultFuture m_addIgnoreCallback;
QueryCallback<std::string> m_charRenameCallback;
QueryCallback<std::string> m_addFriendCallback;
QueryResultHolderFuture m_charLoginCallback;
private:
// private trade methods
void moveItems(Item* myItems[], Item* hisItems[]);
+20 -19
View File
@@ -54,7 +54,6 @@
#include "VMapFactory.h"
#include "GameEventMgr.h"
#include "PoolMgr.h"
#include "AsyncDatabaseImpl.h"
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
#include "InstanceSaveMgr.h"
@@ -103,7 +102,6 @@ World::World()
m_maxQueuedSessionCount = 0;
m_PlayerCount = 0;
m_MaxPlayerCount = 0;
m_resultQueue = NULL;
m_NextDailyQuestReset = 0;
m_NextWeeklyQuestReset = 0;
m_scheduledScripts = 0;
@@ -134,8 +132,6 @@ World::~World()
VMAP::VMapFactory::clear();
delete m_resultQueue;
//TODO free addSessQueue
}
@@ -1979,8 +1975,8 @@ void World::Update(uint32 diff)
RecordTimeDiff("UpdateLFGMgr");
// execute callbacks from sql queries that were queued recently
UpdateResultQueue();
RecordTimeDiff("UpdateResultQueue");
ProcessQueryCallbacks();
RecordTimeDiff("ProcessQueryCallbacks");
///- Erase corpses once every 20 minutes
if (m_timers[WUPDATE_CORPSES].Passed())
@@ -2500,21 +2496,12 @@ void World::SendRNDBroadcast()
}
}
void World::InitResultQueue()
{
m_resultQueue = new SQLResultQueue;
CharacterDatabase.SetResultQueue(m_resultQueue);
}
void World::UpdateResultQueue()
{
m_resultQueue->Update();
}
void World::UpdateRealmCharCount(uint32 accountId)
{
CharacterDatabase.AsyncPQuery(this, &World::_UpdateRealmCharCount, accountId,
"SELECT COUNT(guid) FROM characters WHERE account = '%u'", accountId);
m_realmCharCallback.SetParam(accountId);
m_realmCharCallback.SetFutureResult(
LoginDatabase.AsyncPQuery("SELECT COUNT(guid) FROM characters WHERE account = '%u'", accountId)
);
}
void World::_UpdateRealmCharCount(QueryResult_AutoPtr resultCharCount, uint32 accountId)
@@ -2742,3 +2729,17 @@ uint64 World::getWorldState(uint32 index) const
WorldStatesMap::const_iterator it = m_worldstates.find(index);
return it != m_worldstates.end() ? it->second : 0;
}
void World::ProcessQueryCallbacks()
{
QueryResult_AutoPtr result;
//-UpdateRealmCharCount
if (m_realmCharCallback.IsReady())
{
uint32 param = m_realmCharCallback.GetParam();
m_realmCharCallback.GetResult(result);
_UpdateRealmCharCount(result, param);
m_realmCharCallback.FreeResult();
}
}
+5 -5
View File
@@ -31,6 +31,7 @@
#include "SharedDefines.h"
#include "ace/Atomic_Op.h"
#include "QueryResult.h"
#include "Callback.h"
#include <map>
#include <set>
@@ -42,7 +43,6 @@ class WorldSession;
class Player;
struct ScriptAction;
struct ScriptInfo;
class SQLResultQueue;
class QueryResult;
class WorldSocket;
class SystemMgr;
@@ -670,9 +670,6 @@ class World
void ProcessCliCommands();
void QueueCliCommand(CliCommandHolder* commandHolder) { cliCmdQueue.add(commandHolder); }
void UpdateResultQueue();
void InitResultQueue();
void ForceGameEventUpdate();
void UpdateRealmCharCount(uint32 accid);
@@ -768,7 +765,6 @@ class World
// CLI command holder to be thread safe
ACE_Based::LockedQueue<CliCommandHolder*,ACE_Thread_Mutex> cliCmdQueue;
SQLResultQueue *m_resultQueue;
// next daily quests and random bg reset time
time_t m_NextDailyQuestReset;
@@ -787,6 +783,10 @@ class World
std::string m_CreatureEventAIVersion;
std::list<std::string> m_Autobroadcasts;
private:
void ProcessQueryCallbacks();
QueryCallback<uint32> m_realmCharCallback;
};
extern uint32 realmID;