aboutsummaryrefslogtreecommitdiff
path: root/src/game/WorldSession.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/WorldSession.cpp')
-rw-r--r--src/game/WorldSession.cpp101
1 files changed, 82 insertions, 19 deletions
diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp
index 3ec1675ca49..fc3ddb4b486 100644
--- a/src/game/WorldSession.cpp
+++ b/src/game/WorldSession.cpp
@@ -207,6 +207,19 @@ bool WorldSession::Update(uint32 /*diff*/)
}
// lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
break;
+ case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT:
+ if(!_player && !m_playerRecentlyLogout)
+ {
+ LogUnexpectedOpcode(packet, "the player has not logged in yet and not recently logout");
+ }
+ else
+ {
+ // not expected _player or must checked in packet hanlder
+ (this->*opHandle.handler)(*packet);
+ if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
+ LogUnprocessedTail(packet);
+ }
+ break;
case STATUS_TRANSFER:
if(!_player)
LogUnexpectedOpcode(packet, "the player has not logged in yet");
@@ -423,7 +436,7 @@ void WorldSession::LogoutPlayer(bool Save)
_player->CleanupsBeforeDelete();
Map* _map = _player->GetMap();
_map->Remove(_player, true);
- _player = NULL; // deleted in Remove call
+ SetPlayer(NULL); // deleted in Remove call
///- Send the 'logout complete' packet to the client
WorldPacket data( SMSG_LOGOUT_COMPLETE, 0 );
@@ -559,15 +572,19 @@ void WorldSession::SendAuthWaitQue(uint32 position)
}
}
-void WorldSession::LoadAccountData()
+void WorldSession::LoadGlobalAccountData()
{
- for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
- {
- AccountData data;
- m_accountData[i] = data;
- }
+ LoadAccountData(
+ CharacterDatabase.PQuery("SELECT type, time, data FROM account_data WHERE account='%u'", GetAccountId()),
+ GLOBAL_CACHE_MASK
+ );
+}
- QueryResult *result = CharacterDatabase.PQuery("SELECT type, time, data FROM account_data WHERE account='%u'", GetAccountId());
+void WorldSession::LoadAccountData(QueryResult* result, uint32 mask)
+{
+ for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
+ if (mask & (1 << i))
+ m_accountData[i] = AccountData();
if(!result)
return;
@@ -577,28 +594,65 @@ void WorldSession::LoadAccountData()
Field *fields = result->Fetch();
uint32 type = fields[0].GetUInt32();
- if(type < NUM_ACCOUNT_DATA_TYPES)
+ if (type >= NUM_ACCOUNT_DATA_TYPES)
+ {
+ sLog.outError("Table `%s` have invalid account data type (%u), ignore.",
+ mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data");
+ continue;
+ }
+
+ if ((mask & (1 << type))==0)
{
- m_accountData[type].Time = fields[1].GetUInt32();
- m_accountData[type].Data = fields[2].GetCppString();
+ sLog.outError("Table `%s` have non appropriate for table account data type (%u), ignore.",
+ mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data");
+ continue;
}
+
+ m_accountData[type].Time = fields[1].GetUInt32();
+ m_accountData[type].Data = fields[2].GetCppString();
+
} while (result->NextRow());
delete result;
}
-void WorldSession::SetAccountData(uint32 type, time_t time_, std::string data)
+void WorldSession::SetAccountData(AccountDataType type, time_t time_, std::string data)
{
+ if ((1 << type) & GLOBAL_CACHE_MASK)
+ {
+ uint32 acc = GetAccountId();
+
+ CharacterDatabase.BeginTransaction ();
+ CharacterDatabase.PExecute("DELETE FROM account_data WHERE account='%u' AND type='%u'", acc, type);
+ CharacterDatabase.escape_string(data);
+ CharacterDatabase.PExecute("INSERT INTO account_data VALUES ('%u','%u','%u','%s')", acc, type, (uint32)time_, data.c_str());
+ CharacterDatabase.CommitTransaction ();
+ }
+ else
+ {
+ // _player can be NULL and packet received after logout but m_GUID still store correct guid
+ if(!m_GUIDLow)
+ return;
+
+ CharacterDatabase.BeginTransaction ();
+ CharacterDatabase.PExecute("DELETE FROM character_account_data WHERE guid='%u' AND type='%u'", m_GUIDLow, type);
+ CharacterDatabase.escape_string(data);
+ CharacterDatabase.PExecute("INSERT INTO character_account_data VALUES ('%u','%u','%u','%s')", m_GUIDLow, type, (uint32)time_, data.c_str());
+ CharacterDatabase.CommitTransaction ();
+ }
+
m_accountData[type].Time = time_;
m_accountData[type].Data = data;
+}
- uint32 acc = GetAccountId();
-
- CharacterDatabase.BeginTransaction ();
- CharacterDatabase.PExecute("DELETE FROM account_data WHERE account='%u' AND type='%u'", acc, type);
- CharacterDatabase.escape_string(data);
- CharacterDatabase.PExecute("INSERT INTO account_data VALUES ('%u','%u','%u','%s')", acc, type, (uint32)time_, data.c_str());
- CharacterDatabase.CommitTransaction ();
+void WorldSession::SendAccountDataTimes()
+{
+ WorldPacket data( SMSG_ACCOUNT_DATA_TIMES, 4+1+8*4 ); // changed in WotLK
+ data << uint32(time(NULL)); // unix time of something
+ data << uint8(1);
+ for(int i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
+ data << uint32(m_accountData[i].Time); // also unix time
+ SendPacket(&data);
}
void WorldSession::LoadTutorialsData()
@@ -825,3 +879,12 @@ void WorldSession::SendAddonsInfo()
SendPacket(&data);
}
+
+void WorldSession::SetPlayer( Player *plr )
+{
+ _player = plr;
+
+ // set m_GUID that can be used while player loggined and later until m_playerRecentlyLogout not reset
+ if(_player)
+ m_GUIDLow = _player->GetGUIDLow();
+} \ No newline at end of file