From 97bf2e7d683b0854a2e09de178abd0acaee61e51 Mon Sep 17 00:00:00 2001 From: tomrus88 Date: Mon, 27 Oct 2008 20:00:56 +0300 Subject: [PATCH] Fixed windows build, account data should be saved server side now --- .../5_character_account_data.sql | 7 ++ src/game/CharacterHandler.cpp | 9 +-- src/game/MiscHandler.cpp | 66 +++++++++++++------ src/game/Pet.cpp | 4 +- src/game/Player.cpp | 29 +++++++- src/game/Player.h | 23 ++++++- src/game/SharedDefines.h | 1 + src/game/SpellAuras.cpp | 4 +- win/VC71/game.vcproj | 8 +++ win/VC80/game.vcproj | 8 +++ win/VC90/game.vcproj | 9 +++ 11 files changed, 138 insertions(+), 30 deletions(-) create mode 100644 sql/wotlk_updates/5_character_account_data.sql diff --git a/sql/wotlk_updates/5_character_account_data.sql b/sql/wotlk_updates/5_character_account_data.sql new file mode 100644 index 000000000..7e6fa8f11 --- /dev/null +++ b/sql/wotlk_updates/5_character_account_data.sql @@ -0,0 +1,7 @@ +CREATE TABLE `account_data` ( + `guid` 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 diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index a4e04348e..d665e6dc8 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -79,6 +79,7 @@ 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; } @@ -497,11 +498,11 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) data << pCurrChar->GetOrientation(); SendPacket(&data); - data.Initialize( SMSG_ACCOUNT_DATA_TIMES, 128 ); // changed in WotLK - data << uint32(0); // unix time of something + data.Initialize( 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 < 8; i++) - data << uint32(0); // also unix time + for(int i = 0; i < NUM_ACCOUNT_DATA_TYPES; i++) + data << uint32(pCurrChar->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 1da70f1cc..389807597 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -311,7 +311,7 @@ void WorldSession::HandleLogoutRequestOpcode( WorldPacket & /*recv_data*/ ) data.append(GetPlayer()->GetPackGUID()); data << (uint32)2; SendPacket( &data ); - GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); + GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); } WorldPacket data( SMSG_LOGOUT_RESPONSE, 5 ); @@ -348,7 +348,7 @@ void WorldSession::HandleLogoutCancelOpcode( WorldPacket & /*recv_data*/ ) GetPlayer()->SetStandState(PLAYER_STATE_NONE); //! DISABLE_ROTATE - GetPlayer()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); + GetPlayer()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); } sLog.outDebug( "WORLD: sent SMSG_LOGOUT_CANCEL_ACK Message" ); @@ -1073,27 +1073,37 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data) sLog.outDetail("WORLD: Received CMSG_UPDATE_ACCOUNT_DATA"); recv_data.hexlike(); - uint32 id1, timestamp, decompressedSize; - recv_data >> id1 >> timestamp >> decompressedSize; + uint32 type, timestamp, decompressedSize; + recv_data >> type >> timestamp >> decompressedSize; - if(decompressedSize == 0) + if(type > NUM_ACCOUNT_DATA_TYPES) return; + if(decompressedSize == 0) // erase + { + _player->SetAccountData(type, timestamp, ""); + _player->SaveAccountData(type); + return; + } + ByteBuffer dest; dest.resize(decompressedSize); uLongf realSize = decompressedSize; - if(uncompress(const_cast(dest.contents()), &realSize, const_cast(recv_data.contents() + recv_data.rpos()), recv_data.size() - recv_data.rpos()) == Z_OK) - { - dest.hexlike(); - } - else + if(uncompress(const_cast(dest.contents()), &realSize, const_cast(recv_data.contents() + recv_data.rpos()), recv_data.size() - recv_data.rpos()) != Z_OK) { sLog.outError("UAD: Failed to decompress packet"); + return; } + std::string adata; + dest >> adata; + + _player->SetAccountData(type, timestamp, adata); + _player->SaveAccountData(type); + WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4); - data << uint32(id1); + data << uint32(type); data << uint32(0); SendPacket(&data); } @@ -1105,15 +1115,33 @@ void WorldSession::HandleRequestAccountData(WorldPacket& recv_data) CHECK_PACKET_SIZE(recv_data, 4); - uint32 id; - recv_data >> id; + uint32 type; + recv_data >> type; - WorldPacket data (SMSG_UPDATE_ACCOUNT_DATA, 8+4+4+4); - data << uint64(_player->GetGUID()); - data << uint32(id); - data << uint32(time(NULL)); - data << uint32(0); // decompressed length - // data << account_data(data_len); + if(type > NUM_ACCOUNT_DATA_TYPES) + return; + + AccountData *adata = _player->GetAccountData(type); + uint32 size = adata->Data.size(); + uLongf destSize = compressBound(size); + ByteBuffer dest; + + //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); + data << uint64(_player->GetGUID()); // player guid + data << uint32(type); // type (0-7) + data << uint32(adata->Time); // unix time + data << uint32(size); // decompressed length + data.append(dest); // compressed data + SendPacket(&data); } void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data) diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index ad8d2e093..2bc5f1b20 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -481,12 +481,12 @@ void Pet::setDeathState(DeathState s) // overwrite virtual if(!mapEntry || (mapEntry->map_type != MAP_ARENA && mapEntry->map_type != MAP_BATTLEGROUND)) ModifyPower(POWER_HAPPINESS, -HAPPINESS_LEVEL_SIZE); - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); } } else if(getDeathState()==ALIVE) { - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); CastPetAuras(true); } } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index f3a28a6a5..116a4dc89 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2298,7 +2298,7 @@ void Player::InitStatsForLevel(bool reapplyMods) RemoveFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_ATTACKABLE_1 | UNIT_FLAG_PET_IN_COMBAT | UNIT_FLAG_SILENCED | UNIT_FLAG_PACIFIED | - UNIT_FLAG_DISABLE_ROTATE | UNIT_FLAG_IN_COMBAT | UNIT_FLAG_DISARMED | + UNIT_FLAG_STUNNED | UNIT_FLAG_IN_COMBAT | UNIT_FLAG_DISARMED | UNIT_FLAG_CONFUSED | UNIT_FLAG_FLEEING | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_SKINNABLE | UNIT_FLAG_MOUNT | UNIT_FLAG_TAXI_FLIGHT ); SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); // must be set @@ -15050,7 +15050,7 @@ void Player::SaveToDB() SetByteValue(UNIT_FIELD_BYTES_1, 0, 0); // stand state SetByteValue(UNIT_FIELD_BYTES_2, 3, 0); // shapeshift SetByteValue(UNIT_FIELD_BYTES_1, 3, 0); // stand flags? - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); SetDisplayId(GetNativeDisplayId()); bool inworld = IsInWorld(); @@ -18568,3 +18568,28 @@ 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 4d6c883e0..d7432d1e6 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -221,6 +221,12 @@ 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) @@ -835,9 +841,10 @@ 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 18 +#define MAX_PLAYER_LOGIN_QUERY 19 // Player summoning auto-decline time (in secs) #define MAX_PLAYER_SUMMON_DELAY (2*MINUTE) @@ -1345,6 +1352,18 @@ 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; } @@ -2217,6 +2236,8 @@ 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 8b942dfd4..f97a747a3 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -82,6 +82,7 @@ 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/SpellAuras.cpp b/src/game/SpellAuras.cpp index 496b79939..e76997017 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3162,7 +3162,7 @@ void Aura::HandleAuraModStun(bool apply, bool Real) m_target->addUnitState(UNIT_STAT_STUNNED); m_target->SetUInt64Value(UNIT_FIELD_TARGET, 0); - m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); + m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); m_target->CastStop(m_target->GetGUID() == GetCasterGUID() ? GetId() : 0); // Creature specific @@ -3184,7 +3184,7 @@ void Aura::HandleAuraModStun(bool apply, bool Real) return; m_target->clearUnitState(UNIT_STAT_STUNNED); - m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); + m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); if(!m_target->hasUnitState(UNIT_STAT_ROOT)) // prevent allow move if have also root effect { diff --git a/win/VC71/game.vcproj b/win/VC71/game.vcproj index b59d8a262..e36b3013e 100644 --- a/win/VC71/game.vcproj +++ b/win/VC71/game.vcproj @@ -135,6 +135,14 @@ + + + + + + diff --git a/win/VC80/game.vcproj b/win/VC80/game.vcproj index 67b4ec56d..32afa4649 100644 --- a/win/VC80/game.vcproj +++ b/win/VC80/game.vcproj @@ -354,6 +354,14 @@ RelativePath="..\..\src\game\AccountMgr.h" > + + + + diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj index 09e58cfad..dd2952950 100644 --- a/win/VC90/game.vcproj +++ b/win/VC90/game.vcproj @@ -6,6 +6,7 @@ ProjectGUID="{1DC6C4DA-A028-41F3-877D-D5400C594F88}" RootNamespace="game" Keyword="Win32Proj" + TargetFrameworkVersion="0" > + + + +