diff --git a/sql/wotlk_updates/5_character_account_data.sql b/sql/wotlk_updates/5_character_account_data.sql index 7e6fa8f11..08b9a5b5b 100644 --- a/sql/wotlk_updates/5_character_account_data.sql +++ b/sql/wotlk_updates/5_character_account_data.sql @@ -1,7 +1,7 @@ CREATE TABLE `account_data` ( - `guid` int(11) unsigned NOT NULL default '0', + `account` int(11) unsigned NOT NULL default '0', `type` int(11) unsigned NOT NULL default '0', `time` bigint(11) unsigned NOT NULL default '0', - `data` longtext NOT NULL default '', - PRIMARY KEY (`guid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file + `data` longtext NOT NULL, + PRIMARY KEY (`account`,`type`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index d665e6dc8..ace5be7c7 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -79,7 +79,6 @@ bool LoginQueryHolder::Initialize() res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = '%u'",GUID_LOPART(m_guid)); // in other case still be dummy query res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGUILD, "SELECT guildid,rank FROM guild_member WHERE guid = '%u'", GUID_LOPART(m_guid)); - res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACCOUNTDATA, "SELECT type,time,data FROM account_data WHERE guid = '%u'", GUID_LOPART(m_guid)); return res; } @@ -502,7 +501,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) data << uint32(time(NULL)); // unix time of something data << uint8(1); for(int i = 0; i < NUM_ACCOUNT_DATA_TYPES; i++) - data << uint32(pCurrChar->GetAccountData(i)->Time); // also unix time + data << uint32(GetAccountData(i)->Time); // also unix time SendPacket(&data); data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0 diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 389807597..44c34f5d1 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -1081,8 +1081,8 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data) if(decompressedSize == 0) // erase { - _player->SetAccountData(type, timestamp, ""); - _player->SaveAccountData(type); + SetAccountData(type, timestamp, ""); + SaveAccountData(type); return; } @@ -1099,8 +1099,8 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data) std::string adata; dest >> adata; - _player->SetAccountData(type, timestamp, adata); - _player->SaveAccountData(type); + SetAccountData(type, timestamp, adata); + SaveAccountData(type); WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4); data << uint32(type); @@ -1121,18 +1121,18 @@ void WorldSession::HandleRequestAccountData(WorldPacket& recv_data) if(type > NUM_ACCOUNT_DATA_TYPES) return; - AccountData *adata = _player->GetAccountData(type); + AccountData *adata = GetAccountData(type); uint32 size = adata->Data.size(); - uLongf destSize = compressBound(size); + uLongf destSize = size; ByteBuffer dest; + dest.resize(size); - //if(compress(const_cast(dest.contents()), &destSize, const_cast(adata->Data.c_str()), size) != Z_OK) if(compress(const_cast(dest.contents()), &destSize, (uint8*)adata->Data.c_str(), size) != Z_OK) { sLog.outDebug("RAD: Failed to compress account data, error"); return; } - + dest.resize(destSize); WorldPacket data (SMSG_UPDATE_ACCOUNT_DATA, 8+4+4+4+destSize); diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index f9ab1ded7..cc2fb033c 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -552,7 +552,7 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data, 8); - sLog.outDebug("WORLD: Recv CMSG_STABLE_PET not dispose."); + sLog.outDebug("WORLD: Recv CMSG_STABLE_PET"); uint64 npcGUID; recv_data >> npcGUID; diff --git a/src/game/Object.h b/src/game/Object.h index 9358996fe..ce905cb50 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -242,7 +242,9 @@ class MANGOS_DLL_SPEC Object { ASSERT( index < m_valuesCount || PrintIndexError( index , false ) ); ASSERT( offset < 4 ); - return (((uint8*)m_uint32Values[index])[offset] & flag) != 0; + //return *(((uint16*)&m_uint32Values[ index ])+offset); + //return (((uint8*)m_uint32Values[index])[offset] & flag) != 0; + return (((uint8*)&m_uint32Values[index])[offset] & flag) != 0; } void ApplyModFlag( uint16 index, uint32 flag, bool apply) diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h index 9879cfea9..3ec8544e7 100644 --- a/src/game/Opcodes.h +++ b/src/game/Opcodes.h @@ -1210,13 +1210,13 @@ enum Opcodes UMSG_UNKNOWN_1179 = 0x49B, // not found in client CMSG_UNKNOWN_1180 = 0x49C, // lua: HearthAndResurrectFromArea SMSG_UNKNOWN_1181 = 0x49D, // empty - SMSG_UNKNOWN_1182 = 0x49E, // uint32 - SMSG_UNKNOWN_1183 = 0x49F, // uint32 + SMSG_UNKNOWN_1182 = 0x49E, // uint32 EVENT_CRITERIA_UPDATE + SMSG_UNKNOWN_1183 = 0x49F, // uint32 EVENT_ACHIEVEMENT_EARNED UMSG_UNKNOWN_1184 = 0x4A0, // not found in client - UMSG_UNKNOWN_1185 = 0x4A1, - UMSG_UNKNOWN_1186 = 0x4A2, - UMSG_UNKNOWN_1187 = 0x4A3, - UMSG_UNKNOWN_1188 = 0x4A4, + UMSG_UNKNOWN_1185 = 0x4A1, // not found in client + UMSG_UNKNOWN_1186 = 0x4A2, // not found in client + UMSG_UNKNOWN_1187 = 0x4A3, // not found in client + UMSG_UNKNOWN_1188 = 0x4A4, // not found in client NUM_MSG_TYPES = 0x4A5 }; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 116a4dc89..a7811759c 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -18568,28 +18568,3 @@ void Player::InitGlyphsForLevel() SetUInt32Value(PLAYER_GLYPHS_ENABLED, value); } - -void Player::LoadAccountData(QueryResult *result) -{ - do - { - Field *fields = result->Fetch(); - - AccountData data; - uint32 type = fields[0].GetUInt32(); - data.Time = fields[1].GetUInt32(); - data.Data = fields[2].GetCppString(); - - if(type < NUM_ACCOUNT_DATA_TYPES) - m_accountData[type] = data; - } while (result->NextRow()); - - delete result; -} - -void Player::SaveAccountData(uint32 type) -{ - uint32 lowguid = GetGUIDLow(); - CharacterDatabase.PExecute("DELETE FROM account_data WHERE guid=%u AND type=%u", lowguid, type); - CharacterDatabase.PExecute("INSERT INTO account_data VALUES (%u,%u,%u,%s)", lowguid, type, (uint32)m_accountData[type].Time, m_accountData[type].Data.c_str()); -} diff --git a/src/game/Player.h b/src/game/Player.h index d7432d1e6..4d6c883e0 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -221,12 +221,6 @@ struct Areas float y2; }; -struct AccountData -{ - time_t Time; - std::string Data; -}; - enum FactionFlags { FACTION_FLAG_VISIBLE = 0x01, // makes visible in client (set or can be set at interaction with target of this faction) @@ -841,10 +835,9 @@ enum PlayerLoginQueryIndex PLAYER_LOGIN_QUERY_LOADSPELLCOOLDOWNS = 15, PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES = 16, PLAYER_LOGIN_QUERY_LOADGUILD = 17, - PLAYER_LOGIN_QUERY_LOADACCOUNTDATA = 18, }; -#define MAX_PLAYER_LOGIN_QUERY 19 +#define MAX_PLAYER_LOGIN_QUERY 18 // Player summoning auto-decline time (in secs) #define MAX_PLAYER_SUMMON_DELAY (2*MINUTE) @@ -1352,18 +1345,6 @@ class MANGOS_DLL_SPEC Player : public Unit } } - AccountData *GetAccountData(uint32 type) - { - return &m_accountData[type]; - } - void SetAccountData(uint32 type, time_t time_, std::string data) - { - m_accountData[type].Time = time_; - m_accountData[type].Data = data; - } - void LoadAccountData(QueryResult *result); - void SaveAccountData(uint32 type); - QuestStatusMap& getQuestStatusMap() { return mQuestStatus; }; const uint64& GetSelection( ) const { return m_curSelection; } @@ -2236,8 +2217,6 @@ class MANGOS_DLL_SPEC Player : public Unit uint32 m_Tutorials[8]; bool m_TutorialsChanged; - AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES]; - bool m_DailyQuestChanged; time_t m_lastDailyQuestTime; diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index f97a747a3..8b942dfd4 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -82,7 +82,6 @@ enum Classes #define CLASSMASK_WAND_USERS ((1<<(CLASS_PRIEST-1))|(1<<(CLASS_MAGE-1))|(1<<(CLASS_WARLOCK-1))) #define PLAYER_MAX_BATTLEGROUND_QUEUES 3 -#define NUM_ACCOUNT_DATA_TYPES 8 enum ReputationRank { diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 6cc0894da..7e08e0871 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -509,3 +509,38 @@ void WorldSession::SendAuthWaitQue(uint32 position) SendPacket(&packet); } } + +void WorldSession::LoadAccountData() +{ + for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i) + { + AccountData data; + m_accountData[i] = data; + } + + QueryResult *result = CharacterDatabase.PQuery("SELECT type, time, data FROM account_data WHERE account='%u'", GetAccountId()); + + if(!result) + return; + + do + { + Field *fields = result->Fetch(); + + uint32 type = fields[0].GetUInt32(); + if(type < NUM_ACCOUNT_DATA_TYPES) + { + m_accountData[type].Time = fields[1].GetUInt32(); + m_accountData[type].Data = fields[2].GetCppString(); + } + } while (result->NextRow()); + + delete result; +} + +void WorldSession::SaveAccountData(uint32 type) +{ + uint32 acc = GetAccountId(); + CharacterDatabase.PExecute("DELETE FROM account_data WHERE account='%u' AND type='%u'", acc, type); + CharacterDatabase.PExecute("INSERT INTO account_data VALUES ('%u','%u','%u','%s')", acc, type, (uint32)m_accountData[type].Time, m_accountData[type].Data.c_str()); +} diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index 0ce24f429..5465d2664 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -44,6 +44,16 @@ class CharacterHandler; #define CHECK_PACKET_SIZE(P,S) if((P).size() < (S)) return SizeError((P),(S)); +#define NUM_ACCOUNT_DATA_TYPES 8 + +struct AccountData +{ + AccountData() : Time(NULL), Data("") {} + + time_t Time; + std::string Data; +}; + enum PartyOperation { PARTY_OP_INVITE = 0, @@ -147,6 +157,20 @@ class MANGOS_DLL_SPEC WorldSession //pet void SendPetNameQuery(uint64 guid, uint32 petnumber); + // Account Data + AccountData *GetAccountData(uint32 type) + { + return &m_accountData[type]; + } + void SetAccountData(uint32 type, time_t time_, std::string data) + { + m_accountData[type].Time = time_; + m_accountData[type].Data = data; + } + + void LoadAccountData(); + void SaveAccountData(uint32 type); + //mail //used with item_page table bool SendItemInfo( uint32 itemid, WorldPacket data ); @@ -661,6 +685,7 @@ class MANGOS_DLL_SPEC WorldSession LocaleConstant m_sessionDbcLocale; int m_sessionDbLocaleIndex; uint32 m_latency; + AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES]; ZThread::LockedQueue _recvQueue; }; diff --git a/src/game/WorldSocket.cpp b/src/game/WorldSocket.cpp index e8b11cb99..be9a05fe8 100644 --- a/src/game/WorldSocket.cpp +++ b/src/game/WorldSocket.cpp @@ -876,6 +876,8 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) m_Crypt.SetKey (&K); m_Crypt.Init (); + m_Session->LoadAccountData(); + // In case needed sometime the second arg is in microseconds 1 000 000 = 1 sec ACE_OS::sleep (ACE_Time_Value (0, 10000)); diff --git a/src/shared/Database/Database.h b/src/shared/Database/Database.h index 3fd319ffe..fdec33473 100644 --- a/src/shared/Database/Database.h +++ b/src/shared/Database/Database.h @@ -31,7 +31,7 @@ class SqlQueryHolder; typedef HM_NAMESPACE::hash_map TransactionQueues; typedef HM_NAMESPACE::hash_map QueryQueues; -#define MAX_QUERY_LEN 1024 +#define MAX_QUERY_LEN 5*1024 class MANGOS_DLL_SPEC Database {