From c8db80cc270f7078fec85ec845fdc1efad8a0fda Mon Sep 17 00:00:00 2001 From: Salja Date: Mon, 6 Aug 2012 12:27:10 +0200 Subject: [PATCH] Fix crash on load filled database and fix SMSG_ALL_ACHIEVEMENT_DATA by Zakamurite Signed-off-by: Salja --- src/game/AchievementMgr.cpp | 167 ++++++++++++++++++++++++++++++------ src/game/AchievementMgr.h | 1 - src/game/DBCEnums.h | 42 ++++++--- src/game/Opcodes.cpp | 2 +- src/game/Opcodes.h | 2 +- src/game/World.cpp | 2 +- 6 files changed, 175 insertions(+), 41 deletions(-) diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index 339e66050..876f0bf59 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -2214,45 +2214,164 @@ void AchievementMgr::IncompletedAchievement(AchievementEntry const* achievement) void AchievementMgr::SendAllAchievementData() { // since we don't know the exact size of the packed GUIDs this is just an approximation - WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, 4 * 2 + m_completedAchievements.size() * 4 * 2 + m_completedAchievements.size() * 7 * 4); - BuildAllDataPacket(&data); + WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, 4*2+m_completedAchievements.size()*4*2+m_completedAchievements.size()*7*4); + + uint8 guidMask[] = { 4, 5, 3, 0, 2, 7, 6, 1 }; + uint8 counterMask[] = { 3, 0, 6, 4, 7, 2, 1, 5 }; + + uint8 guidBytes[] = { 3, 4, 6, 2, 5, 0, 7, 1 }; + uint8 counterBytes[] = { 5, 6, 2, 0, 3, 1, 4, 7 }; + + ObjectGuid guid = m_player->GetObjectGuid(); + + uint32 criteriaCount = m_criteriaProgress.size(); + + data.WriteBits(criteriaCount, 21); + + for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter) + { + uint64 counter = iter->second.counter; + + data.WriteGuidMask(guid, guidMask, 1); + data.WriteGuidMask(counter, counterMask, 1); + data.WriteGuidMask(guid, guidMask, 1, 1); + data.WriteGuidMask(counter, counterMask, 2, 1); + data.WriteGuidMask(guid, guidMask, 2, 2); + + data.WriteGuidMask(counter, counterMask, 1, 3); + data.WriteGuidMask(guid, guidMask, 1, 4); + data.WriteGuidMask(counter, counterMask, 1, 4); + data.WriteGuidMask(guid, guidMask, 1, 5); + uint8 flags = 0; // Seems always 0 + data.WriteBits(flags, 2); + data.WriteGuidMask(guid, guidMask, 1, 6); + + data.WriteGuidMask(counter, counterMask, 3, 5); + data.WriteGuidMask(guid, guidMask, 1, 7); + } + + uint32 achievCount = m_completedAchievements.size(); + data.WriteBits(achievCount, 23); + + time_t now = time(NULL); + for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter) + { + uint64 counter = iter->second.counter; + + data.WriteGuidBytes(guid, guidBytes, 1, 0); + data.WriteGuidBytes(counter, counterBytes, 2, 0); + data.WriteGuidBytes(guid, guidBytes, 2, 1); + data.WriteGuidBytes(counter, counterBytes, 1, 2); + + data << uint32(now - iter->second.date); // Timer 2 + + data.WriteGuidBytes(guid, guidBytes, 1, 3); + + data << uint32(iter->first); + + data.WriteGuidBytes(guid, guidBytes, 1, 4); + data.WriteGuidBytes(counter, counterBytes, 4, 3); + data.WriteGuidBytes(guid, guidBytes, 2, 5); + data.WriteGuidBytes(counter, counterBytes, 1, 7); + + data << uint32(now - iter->second.date); // Timer 1 + data << uint32(secsToTimeBitFields(now)); + + data.WriteGuidBytes(guid, guidBytes, 1, 7); + } + + for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter) + { + data << uint32(iter->first); + data << uint32(secsToTimeBitFields(iter->second.date)); + } + GetPlayer()->GetSession()->SendPacket(&data); } void AchievementMgr::SendRespondInspectAchievements(Player* player) { // since we don't know the exact size of the packed GUIDs this is just an approximation - WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 4 + 4 * 2 + m_completedAchievements.size() * 4 * 2 + m_completedAchievements.size() * 7 * 4); - data << GetPlayer()->GetPackGUID(); - BuildAllDataPacket(&data); - player->GetSession()->SendPacket(&data); -} + WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 4+4*2+m_completedAchievements.size()*4*2+m_completedAchievements.size()*7*4); -/** - * used by both SMSG_ALL_ACHIEVEMENT_DATA and SMSG_RESPOND_INSPECT_ACHIEVEMENT - */ -void AchievementMgr::BuildAllDataPacket(WorldPacket* data) -{ - for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter) + uint8 targetGuidMask[] = { 7, 4, 1, 0, 3, 2, 6, 5 }; + uint8 guidMask[] = { 5, 3, 6, 4, 1, 2, 0, 7 }; + uint8 counterMask[] = { 1, 4, 2, 0, 3, 7, 5, 6 }; + + uint8 targetGuidBytes[] = { 1, 6, 3, 0, 2, 7, 4, 5 }; + uint8 guidBytes[] = { 4, 3, 7, 0, 6, 1, 5, 2 }; + uint8 counterBytes[] = { 3, 1, 5, 4, 2, 6, 7, 0 }; + + ObjectGuid targetGuid = m_player->GetObjectGuid(); + ObjectGuid guid = m_player->GetObjectGuid(); + + data.WriteGuidMask(targetGuid, targetGuidMask, 3, 0); + + data.WriteBits(m_completedAchievements.size(), 23); + + data.WriteGuidMask(targetGuid, targetGuidMask, 2, 3); + + data.WriteBits(m_criteriaProgress.size(), 21); + + data.WriteGuidMask(targetGuid, targetGuidMask, 1, 5); + + for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter) { - *data << uint32(iter->first); - *data << uint32(secsToTimeBitFields(iter->second.date)); + uint64 counter = iter->second.counter; + + data.WriteGuidMask(guid, guidMask, 2, 0); + data.WriteGuidMask(counter, counterMask, 3, 0); + data.WriteGuidMask(guid, guidMask, 1, 2); + data.WriteGuidMask(counter, counterMask, 1, 3); + data.WriteGuidMask(guid, guidMask, 3, 3); + data.WriteGuidMask(counter, counterMask, 2, 4); + + data.WriteBits(0, 2); // Seems always 0 + + data.WriteGuidMask(guid, guidMask, 1, 6); + data.WriteGuidMask(counter, counterMask, 2, 6); + data.WriteGuidMask(guid, guidMask, 1, 7); } - *data << int32(-1); + + data.WriteGuidMask(targetGuid, targetGuidMask, 2, 6); time_t now = time(NULL); for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter) { - *data << uint32(iter->first); - data->appendPackGUID(iter->second.counter); - *data << GetPlayer()->GetPackGUID(); - *data << uint32(iter->second.timedCriteriaFailed ? 1 : 0); - *data << uint32(secsToTimeBitFields(now)); - *data << uint32(now - iter->second.date); - *data << uint32(now - iter->second.date); + uint64 counter = iter->second.counter; + + data.WriteGuidBytes(counter, counterBytes, 1, 0); + data.WriteGuidBytes(guid, guidBytes, 1, 0); + + data << uint32(now - iter->second.date); // Timer 1 + data << uint32(secsToTimeBitFields(now)); + + data.WriteGuidBytes(counter, counterBytes, 1, 1); + data.WriteGuidBytes(guid, guidBytes, 2, 1); + data.WriteGuidBytes(counter, counterBytes, 1, 2); + data.WriteGuidBytes(guid, guidBytes, 1, 3); + data.WriteGuidBytes(counter, counterBytes, 4, 3); + data.WriteGuidBytes(guid, guidBytes, 1, 4); + + data << uint32(iter->first); + data << uint32(now - iter->second.date); // Timer 2 + + data.WriteGuidBytes(guid, guidBytes, 2, 5); + data.WriteGuidBytes(counter, counterBytes, 1, 7); + data.WriteGuidBytes(guid, guidBytes, 1, 7); } - *data << int32(-1); + data.WriteGuidBytes(targetGuid, targetGuidBytes, 5, 0); + + for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter) + { + data << uint32(iter->first); + data << uint32(secsToTimeBitFields(iter->second.date)); + } + + data.WriteGuidBytes(targetGuid, targetGuidBytes, 3, 5); + + player->GetSession()->SendPacket(&data); } //========================================================== diff --git a/src/game/AchievementMgr.h b/src/game/AchievementMgr.h index 1621d98cf..c75f78e2c 100644 --- a/src/game/AchievementMgr.h +++ b/src/game/AchievementMgr.h @@ -299,7 +299,6 @@ class AchievementMgr void IncompletedAchievement(AchievementEntry const* entry); bool IsCompletedAchievement(AchievementEntry const* entry); void CompleteAchievementsWithRefs(AchievementEntry const* entry); - void BuildAllDataPacket(WorldPacket* data); Player* m_player; CriteriaProgressMap m_criteriaProgress; diff --git a/src/game/DBCEnums.h b/src/game/DBCEnums.h index 224086a20..22616f821 100644 --- a/src/game/DBCEnums.h +++ b/src/game/DBCEnums.h @@ -110,6 +110,7 @@ enum AchievementCriteriaTypes // you have to complete a daily quest x times in a row ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10, ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11, + ACHIEVEMENT_CRITERIA_TYPE_CURRENCY_EARNED = 12, ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13, ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14, ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND= 15, @@ -215,22 +216,37 @@ enum AchievementCriteriaTypes // 121 unused // 122 unused // 123 unused - // 124 Spend X gold on guildmember repairs. - // 125 Reach guild level X - // 126 Craft X items - // 127 Catch X fish from fishing pools. - // 128 Purchase the X guild bank tab. - // 129 Earn X guild achievement points. - // 130 Win X rated battlegrounds. + ACHIEVEMENT_CRITERIA_TYPE_SPENT_GOLD_GUILD_REPAIRS = 124, + ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL = 125, + ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD = 126, + ACHIEVEMENT_CRITERIA_TYPE_CATCH_FROM_POOL = 127, + ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_BANK_SLOTS = 128, + ACHIEVEMENT_CRITERIA_TYPE_EARN_GUILD_ACHIEVEMENT_POINTS = 129, + ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND = 130, // 131 unused - // 132 Earn a battleground rating of X. - // 133 Create and purchase a guild crest. - // 134 Complete quests - // 135 Honorable kills - // 0..135 => 136 criteria types total + ACHIEVEMENT_CRITERIA_TYPE_REACH_BG_RATING = 132, + ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_TABARD = 133, + ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_GUILD = 134, + ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILLS_GUILD = 135, + ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD = 136, + // 137 no achievements + ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_GUILD_CHALLENGE = 138, + ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_GUILD_CHALLENGE_2 = 139, + // 140 no achievements + // 141 no achievements + // 142 no achievements + // 143 no achievements + // 144 no achievements + // 145 no achievements + // 146 no achievements + // 147 no achievements + // 148 no achievements + // 149 no achievements + // 150 no achievements + // 0..150 => 151 criteria types total }; -#define ACHIEVEMENT_CRITERIA_TYPE_TOTAL 136 +#define ACHIEVEMENT_CRITERIA_TYPE_TOTAL 151 enum AchievementCriteriaMoreReqType { diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp index a1b31dbee..a9460198e 100644 --- a/src/game/Opcodes.cpp +++ b/src/game/Opcodes.cpp @@ -1191,7 +1191,7 @@ void InitializeOpcodes() //OPCODE(CMSG_PET_LEARN_TALENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetLearnTalent ); //OPCODE(CMSG_PET_UNLEARN_TALENTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //OPCODE(SMSG_SET_PHASE_SHIFT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //OPCODE(SMSG_ALL_ACHIEVEMENT_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + OPCODE(SMSG_ALL_ACHIEVEMENT_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(CMSG_FORCE_SAY_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //OPCODE(SMSG_HEALTH_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(SMSG_POWER_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h index baabb47a8..3fa288ae5 100644 --- a/src/game/Opcodes.h +++ b/src/game/Opcodes.h @@ -1185,7 +1185,7 @@ enum Opcodes CMSG_PET_LEARN_TALENT = 0x147B, CMSG_PET_UNLEARN_TALENTS = 0x147C, SMSG_SET_PHASE_SHIFT = 0x147D, - SMSG_ALL_ACHIEVEMENT_DATA = 0x147E, + SMSG_ALL_ACHIEVEMENT_DATA = 0x58B1, CMSG_FORCE_SAY_CHEAT = 0x147F, SMSG_HEALTH_UPDATE = 0x1480, SMSG_POWER_UPDATE = 0x1481, diff --git a/src/game/World.cpp b/src/game/World.cpp index c4485eeef..2ef122712 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1209,7 +1209,7 @@ void World::SetInitialWorldSettings() sLog.outString(); sLog.outString("Loading Achievements..."); sAchievementMgr.LoadAchievementReferenceList(); - //sAchievementMgr.LoadAchievementCriteriaList(); + sAchievementMgr.LoadAchievementCriteriaList(); sAchievementMgr.LoadAchievementCriteriaRequirements(); sAchievementMgr.LoadRewards(); sAchievementMgr.LoadRewardLocales();