Fix crash on load filled database and fix SMSG_ALL_ACHIEVEMENT_DATA by Zakamurite

Signed-off-by: Salja <salja2012@hotmail.de>
This commit is contained in:
Salja 2012-08-06 12:27:10 +02:00 committed by Antz
parent 9c731c9a74
commit c8db80cc27
6 changed files with 175 additions and 41 deletions

View file

@ -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);
}
//==========================================================

View file

@ -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;

View file

@ -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
{

View file

@ -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 );

View file

@ -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,

View file

@ -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();