mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 19:37:03 +00:00
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:
parent
9c731c9a74
commit
c8db80cc27
6 changed files with 175 additions and 41 deletions
|
|
@ -2214,45 +2214,164 @@ void AchievementMgr::IncompletedAchievement(AchievementEntry const* achievement)
|
||||||
void AchievementMgr::SendAllAchievementData()
|
void AchievementMgr::SendAllAchievementData()
|
||||||
{
|
{
|
||||||
// since we don't know the exact size of the packed GUIDs this is just an approximation
|
// 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);
|
WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, 4*2+m_completedAchievements.size()*4*2+m_completedAchievements.size()*7*4);
|
||||||
BuildAllDataPacket(&data);
|
|
||||||
|
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);
|
GetPlayer()->GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AchievementMgr::SendRespondInspectAchievements(Player* player)
|
void AchievementMgr::SendRespondInspectAchievements(Player* player)
|
||||||
{
|
{
|
||||||
// since we don't know the exact size of the packed GUIDs this is just an approximation
|
// 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);
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
uint8 targetGuidMask[] = { 7, 4, 1, 0, 3, 2, 6, 5 };
|
||||||
* used by both SMSG_ALL_ACHIEVEMENT_DATA and SMSG_RESPOND_INSPECT_ACHIEVEMENT
|
uint8 guidMask[] = { 5, 3, 6, 4, 1, 2, 0, 7 };
|
||||||
*/
|
uint8 counterMask[] = { 1, 4, 2, 0, 3, 7, 5, 6 };
|
||||||
void AchievementMgr::BuildAllDataPacket(WorldPacket* data)
|
|
||||||
{
|
uint8 targetGuidBytes[] = { 1, 6, 3, 0, 2, 7, 4, 5 };
|
||||||
for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter)
|
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);
|
uint64 counter = iter->second.counter;
|
||||||
*data << uint32(secsToTimeBitFields(iter->second.date));
|
|
||||||
|
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);
|
time_t now = time(NULL);
|
||||||
for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter)
|
for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter)
|
||||||
{
|
{
|
||||||
*data << uint32(iter->first);
|
uint64 counter = iter->second.counter;
|
||||||
data->appendPackGUID(iter->second.counter);
|
|
||||||
*data << GetPlayer()->GetPackGUID();
|
data.WriteGuidBytes(counter, counterBytes, 1, 0);
|
||||||
*data << uint32(iter->second.timedCriteriaFailed ? 1 : 0);
|
data.WriteGuidBytes(guid, guidBytes, 1, 0);
|
||||||
*data << uint32(secsToTimeBitFields(now));
|
|
||||||
*data << uint32(now - iter->second.date);
|
data << uint32(now - iter->second.date); // Timer 1
|
||||||
*data << uint32(now - iter->second.date);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================
|
//==========================================================
|
||||||
|
|
|
||||||
|
|
@ -299,7 +299,6 @@ class AchievementMgr
|
||||||
void IncompletedAchievement(AchievementEntry const* entry);
|
void IncompletedAchievement(AchievementEntry const* entry);
|
||||||
bool IsCompletedAchievement(AchievementEntry const* entry);
|
bool IsCompletedAchievement(AchievementEntry const* entry);
|
||||||
void CompleteAchievementsWithRefs(AchievementEntry const* entry);
|
void CompleteAchievementsWithRefs(AchievementEntry const* entry);
|
||||||
void BuildAllDataPacket(WorldPacket* data);
|
|
||||||
|
|
||||||
Player* m_player;
|
Player* m_player;
|
||||||
CriteriaProgressMap m_criteriaProgress;
|
CriteriaProgressMap m_criteriaProgress;
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ enum AchievementCriteriaTypes
|
||||||
// you have to complete a daily quest x times in a row
|
// you have to complete a daily quest x times in a row
|
||||||
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10,
|
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10,
|
||||||
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11,
|
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11,
|
||||||
|
ACHIEVEMENT_CRITERIA_TYPE_CURRENCY_EARNED = 12,
|
||||||
ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13,
|
ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13,
|
||||||
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14,
|
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14,
|
||||||
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND= 15,
|
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND= 15,
|
||||||
|
|
@ -215,22 +216,37 @@ enum AchievementCriteriaTypes
|
||||||
// 121 unused
|
// 121 unused
|
||||||
// 122 unused
|
// 122 unused
|
||||||
// 123 unused
|
// 123 unused
|
||||||
// 124 Spend X gold on guildmember repairs.
|
ACHIEVEMENT_CRITERIA_TYPE_SPENT_GOLD_GUILD_REPAIRS = 124,
|
||||||
// 125 Reach guild level X
|
ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL = 125,
|
||||||
// 126 Craft X items
|
ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD = 126,
|
||||||
// 127 Catch X fish from fishing pools.
|
ACHIEVEMENT_CRITERIA_TYPE_CATCH_FROM_POOL = 127,
|
||||||
// 128 Purchase the X guild bank tab.
|
ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_BANK_SLOTS = 128,
|
||||||
// 129 Earn X guild achievement points.
|
ACHIEVEMENT_CRITERIA_TYPE_EARN_GUILD_ACHIEVEMENT_POINTS = 129,
|
||||||
// 130 Win X rated battlegrounds.
|
ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND = 130,
|
||||||
// 131 unused
|
// 131 unused
|
||||||
// 132 Earn a battleground rating of X.
|
ACHIEVEMENT_CRITERIA_TYPE_REACH_BG_RATING = 132,
|
||||||
// 133 Create and purchase a guild crest.
|
ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_TABARD = 133,
|
||||||
// 134 Complete quests
|
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_GUILD = 134,
|
||||||
// 135 Honorable kills
|
ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILLS_GUILD = 135,
|
||||||
// 0..135 => 136 criteria types total
|
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
|
enum AchievementCriteriaMoreReqType
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1191,7 +1191,7 @@ void InitializeOpcodes()
|
||||||
//OPCODE(CMSG_PET_LEARN_TALENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetLearnTalent );
|
//OPCODE(CMSG_PET_LEARN_TALENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetLearnTalent );
|
||||||
//OPCODE(CMSG_PET_UNLEARN_TALENTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
//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_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(CMSG_FORCE_SAY_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||||
//OPCODE(SMSG_HEALTH_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
//OPCODE(SMSG_HEALTH_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
//OPCODE(SMSG_POWER_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
//OPCODE(SMSG_POWER_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
|
|
|
||||||
|
|
@ -1185,7 +1185,7 @@ enum Opcodes
|
||||||
CMSG_PET_LEARN_TALENT = 0x147B,
|
CMSG_PET_LEARN_TALENT = 0x147B,
|
||||||
CMSG_PET_UNLEARN_TALENTS = 0x147C,
|
CMSG_PET_UNLEARN_TALENTS = 0x147C,
|
||||||
SMSG_SET_PHASE_SHIFT = 0x147D,
|
SMSG_SET_PHASE_SHIFT = 0x147D,
|
||||||
SMSG_ALL_ACHIEVEMENT_DATA = 0x147E,
|
SMSG_ALL_ACHIEVEMENT_DATA = 0x58B1,
|
||||||
CMSG_FORCE_SAY_CHEAT = 0x147F,
|
CMSG_FORCE_SAY_CHEAT = 0x147F,
|
||||||
SMSG_HEALTH_UPDATE = 0x1480,
|
SMSG_HEALTH_UPDATE = 0x1480,
|
||||||
SMSG_POWER_UPDATE = 0x1481,
|
SMSG_POWER_UPDATE = 0x1481,
|
||||||
|
|
|
||||||
|
|
@ -1209,7 +1209,7 @@ void World::SetInitialWorldSettings()
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
sLog.outString("Loading Achievements...");
|
sLog.outString("Loading Achievements...");
|
||||||
sAchievementMgr.LoadAchievementReferenceList();
|
sAchievementMgr.LoadAchievementReferenceList();
|
||||||
//sAchievementMgr.LoadAchievementCriteriaList();
|
sAchievementMgr.LoadAchievementCriteriaList();
|
||||||
sAchievementMgr.LoadAchievementCriteriaRequirements();
|
sAchievementMgr.LoadAchievementCriteriaRequirements();
|
||||||
sAchievementMgr.LoadRewards();
|
sAchievementMgr.LoadRewards();
|
||||||
sAchievementMgr.LoadRewardLocales();
|
sAchievementMgr.LoadRewardLocales();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue