Updated to new client build

This commit is contained in:
tomrus88 2009-03-04 14:58:11 +03:00
parent 2197da6407
commit e6a66cdc54
18 changed files with 360 additions and 188 deletions

View file

@ -67,7 +67,6 @@ bool LoginQueryHolder::Initialize()
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS, "SELECT spell,active,disabled FROM character_spell WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS, "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4 FROM character_queststatus WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS,"SELECT quest,time FROM character_queststatus_daily WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADTUTORIALS, "SELECT tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7 FROM character_tutorial WHERE account = '%u' AND realmid = '%u'", GetAccountId(), realmID);
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADREPUTATION, "SELECT faction,standing,flags FROM character_reputation WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADINVENTORY, "SELECT data,bag,slot,item,item_template FROM character_inventory JOIN item_instance ON character_inventory.item = item_instance.guid WHERE character_inventory.guid = '%u' ORDER BY bag,slot", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACTIONS, "SELECT button,action,type,misc FROM character_action WHERE guid = '%u' ORDER BY button", GUID_LOPART(m_guid));
@ -83,6 +82,7 @@ bool LoginQueryHolder::Initialize()
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADARENAINFO, "SELECT arenateamid, played_week, played_season, personal_rating FROM arena_team_member WHERE guid='%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS, "SELECT achievement, date FROM character_achievement WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS,"SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADEQUIPMENTSETS, "SELECT setguid, setindex, name, iconname, item0, item1, item2, item3, item4, item5, item6, item7, item8, item9, item10, item11, item12, item13, item14, item15, item16, item17, item18 FROM character_equipmentsets WHERE guid = '%u' ORDER BY setindex", GUID_LOPART(m_guid));
return res;
}
@ -759,7 +759,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
if(uint32 sourceNode = pCurrChar->m_taxi.GetTaxiSource())
{
sLog.outDebug( "WORLD: Restart character %u taxi flight", pCurrChar->GetGUIDLow() );
uint32 MountId = objmgr.GetTaxiMount(sourceNode, pCurrChar->GetTeam());
@ -924,9 +923,10 @@ void WorldSession::HandleTutorialFlag( WorldPacket & recv_data )
}
uint32 rInt = (iFlag % 32);
uint32 tutflag = GetPlayer()->GetTutorialInt( wInt );
uint32 tutflag = GetTutorialInt( wInt );
tutflag |= (1 << rInt);
GetPlayer()->SetTutorialInt( wInt, tutflag );
SetTutorialInt( wInt, tutflag );
SaveTutorialsData();
//sLog.outDebug("Received Tutorial Flag Set {%u}.", iFlag);
}
@ -934,13 +934,15 @@ void WorldSession::HandleTutorialFlag( WorldPacket & recv_data )
void WorldSession::HandleTutorialClear( WorldPacket & /*recv_data*/ )
{
for ( uint32 iI = 0; iI < 8; iI++)
GetPlayer()->SetTutorialInt( iI, 0xFFFFFFFF );
SetTutorialInt( iI, 0xFFFFFFFF );
SaveTutorialsData();
}
void WorldSession::HandleTutorialReset( WorldPacket & /*recv_data*/ )
{
for ( uint32 iI = 0; iI < 8; iI++)
GetPlayer()->SetTutorialInt( iI, 0x00000000 );
SetTutorialInt( iI, 0x00000000 );
SaveTutorialsData();
}
void WorldSession::HandleSetWatchedFactionIndexOpcode(WorldPacket & recv_data)
@ -1326,5 +1328,46 @@ void WorldSession::HandleCharCustomize(WorldPacket& recv_data)
void WorldSession::HandleEquipmentSetSave(WorldPacket &recv_data)
{
sLog.outDebug("CMSG_EQUIPMENT_SET_SAVE");
recv_data.hexlike();
uint64 setGuid;
if(!recv_data.readPackGUID(setGuid))
return;
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
uint32 Index;
recv_data >> Index;
std::string name, iconName;
recv_data >> name >> iconName;
EquipmentSet eqSet;
eqSet.Guid = setGuid;
eqSet.Index = Index;
eqSet.Name = name;
eqSet.IconName = iconName;
uint64 itemGuid;
for(uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
{
if(!recv_data.readPackGUID(itemGuid))
return;
eqSet.Items[i] = GUID_LOPART(itemGuid);
}
_player->SaveEquipmentSet(eqSet);
}
void WorldSession::HandleEquipmentSetDelete(WorldPacket &recv_data)
{
sLog.outDebug("CMSG_EQUIPMENT_SET_DELETE");
uint64 setGuid;
if(!recv_data.readPackGUID(setGuid))
return;
_player->DeleteEquipmentSet(setGuid);
}

View file

@ -994,9 +994,14 @@ void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data)
sLog.outDetail( "MISC: Added Macro %u into button %u", action, button );
GetPlayer()->addActionButton(button,action,type,misc);
}
else if(type==ACTION_BUTTON_EQSET)
{
sLog.outDetail( "MISC: Added EquipmentSet %u into button %u", action, button );
GetPlayer()->addActionButton(button,action,type,misc);
}
else if(type==ACTION_BUTTON_SPELL)
{
sLog.outDetail( "MISC: Added Action %u into button %u", action, button );
sLog.outDetail( "MISC: Added Spell %u into button %u", action, button );
GetPlayer()->addActionButton(button,action,type,misc);
}
else if(type==ACTION_BUTTON_ITEM)

View file

@ -344,7 +344,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x13B*/ { "CMSG_CANCEL_CHANNELLING", STATUS_LOGGEDIN, &WorldSession::HandleCancelChanneling },
/*0x13C*/ { "SMSG_AI_REACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x13D*/ { "CMSG_SET_SELECTION", STATUS_LOGGEDIN, &WorldSession::HandleSetSelectionOpcode },
/*0x13E*/ { "CMSG_SET_TARGET_OBSOLETE", STATUS_LOGGEDIN, &WorldSession::HandleSetTargetOpcode },
/*0x13E*/ { "CMSG_EQUIPMENT_SET_DELETE", STATUS_LOGGEDIN, &WorldSession::HandleEquipmentSetDelete },
/*0x13F*/ { "CMSG_UNUSED", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x140*/ { "CMSG_UNUSED2", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x141*/ { "CMSG_ATTACKSWING", STATUS_LOGGEDIN, &WorldSession::HandleAttackSwingOpcode },

View file

@ -345,14 +345,14 @@ enum Opcodes
SMSG_SPELL_COOLDOWN = 0x134,
SMSG_COOLDOWN_EVENT = 0x135,
CMSG_CANCEL_AURA = 0x136,
SMSG_UPDATE_AURA_DURATION_OBSOLETE = 0x137, // 3.1 - equipment manager? uint32+guid
SMSG_UPDATE_AURA_DURATION_OBSOLETE = 0x137, // 3.1 - equipment manager? uint32+PGUID
SMSG_PET_CAST_FAILED = 0x138,
MSG_CHANNEL_START = 0x139,
MSG_CHANNEL_UPDATE = 0x13A,
CMSG_CANCEL_CHANNELLING = 0x13B,
SMSG_AI_REACTION = 0x13C,
CMSG_SET_SELECTION = 0x13D,
CMSG_SET_TARGET_OBSOLETE = 0x13E,
CMSG_EQUIPMENT_SET_DELETE = 0x13E,
CMSG_UNUSED = 0x13F,
CMSG_UNUSED2 = 0x140,
CMSG_ATTACKSWING = 0x141,
@ -1257,7 +1257,8 @@ enum Opcodes
UMSG_UNKNOWN_1220 = 0x4C4, // not found
UMSG_UNKNOWN_1221 = 0x4C5, // not found
UMSG_UNKNOWN_1222 = 0x4C6, // not found
NUM_MSG_TYPES = 0x4C7
SMSG_UNKNOWN_1223 = 0x4C7, // arena pet?
NUM_MSG_TYPES = 0x4C8
};
/// Player state

View file

@ -343,10 +343,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this)
PlayerTalkClass = new PlayerMenu( GetSession() );
m_currentBuybackSlot = BUYBACK_SLOT_START;
for ( int aX = 0 ; aX < 8 ; aX++ )
m_Tutorials[ aX ] = 0x00;
m_TutorialsChanged = false;
m_DailyQuestChanged = false;
m_lastDailyQuestTime = 0;
@ -14012,6 +14008,36 @@ void Player::_LoadArenaTeamInfo(QueryResult *result)
delete result;
}
void Player::_LoadEquipmentSets(QueryResult *result)
{
if (!result)
return;
uint32 count = 0;
do
{
Field *fields = result->Fetch();
EquipmentSet eqSet;
eqSet.Guid = fields[0].GetUInt64();
eqSet.Index = fields[1].GetUInt32();
eqSet.Name = fields[2].GetCppString();
eqSet.IconName = fields[3].GetCppString();
for(uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
eqSet.Items[i] = fields[4+i].GetUInt32();
m_EquipmentSets[eqSet.Index] = eqSet;
++count;
if(count >= 10)
break;
} while (result->NextRow());
delete result;
}
bool Player::LoadPositionFromDB(uint32& mapid, float& x,float& y,float& z,float& o, bool& in_flight, uint64 guid)
{
QueryResult *result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,taxi_path FROM characters WHERE guid = '%u'",GUID_LOPART(guid));
@ -14467,8 +14493,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
InitTalentForLevel();
learnDefaultSpells();
_LoadTutorials(holder->GetResult(PLAYER_LOGIN_QUERY_LOADTUTORIALS));
// must be before inventory (some items required reputation check)
_LoadReputation(holder->GetResult(PLAYER_LOGIN_QUERY_LOADREPUTATION));
@ -14613,6 +14637,9 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
m_achievementMgr.LoadFromDB(holder->GetResult(PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS), holder->GetResult(PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS));
m_achievementMgr.CheckAllAchievementCriteria();
_LoadEquipmentSets(holder->GetResult(PLAYER_LOGIN_QUERY_LOADEQUIPMENTSETS));
return true;
}
@ -15281,27 +15308,6 @@ void Player::_LoadSpells(QueryResult *result)
}
}
void Player::_LoadTutorials(QueryResult *result)
{
//QueryResult *result = CharacterDatabase.PQuery("SELECT tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7 FROM character_tutorial WHERE account = '%u' AND realmid = '%u'", GetAccountId(), realmid);
if(result)
{
do
{
Field *fields = result->Fetch();
for (int iI=0; iI<8; iI++)
m_Tutorials[iI] = fields[iI].GetUInt32();
}
while( result->NextRow() );
delete result;
}
m_TutorialsChanged = false;
}
void Player::_LoadGroup(QueryResult *result)
{
//QueryResult *result = CharacterDatabase.PQuery("SELECT leaderGuid FROM group_member WHERE memberGuid='%u'", GetGUIDLow());
@ -15731,7 +15737,6 @@ void Player::SaveToDB()
_SaveInventory();
_SaveQuestStatus();
_SaveDailyQuestStatus();
_SaveTutorials();
_SaveSpells();
_SaveSpellCooldowns();
_SaveActions();
@ -16051,33 +16056,6 @@ void Player::_SaveSpells()
}
}
void Player::_SaveTutorials()
{
if(!m_TutorialsChanged)
return;
uint32 Rows=0;
// it's better than rebuilding indexes multiple times
QueryResult *result = CharacterDatabase.PQuery("SELECT count(*) AS r FROM character_tutorial WHERE account = '%u' AND realmid = '%u'", GetSession()->GetAccountId(), realmID );
if(result)
{
Rows = result->Fetch()[0].GetUInt32();
delete result;
}
if (Rows)
{
CharacterDatabase.PExecute("UPDATE character_tutorial SET tut0='%u', tut1='%u', tut2='%u', tut3='%u', tut4='%u', tut5='%u', tut6='%u', tut7='%u' WHERE account = '%u' AND realmid = '%u'",
m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7], GetSession()->GetAccountId(), realmID );
}
else
{
CharacterDatabase.PExecute("INSERT INTO character_tutorial (account,realmid,tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7) VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", GetSession()->GetAccountId(), realmID, m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7]);
};
m_TutorialsChanged = false;
}
void Player::outDebugValues() const
{
if(!sLog.IsOutDebug()) // optimize disabled debug output
@ -18085,12 +18063,6 @@ void Player::SendInitialPacketsBeforeAddToMap()
// SMSG_SET_PROFICIENCY
// SMSG_UPDATE_AURA_DURATION
// tutorial stuff
/*data.Initialize(SMSG_TUTORIAL_FLAGS, 8*4);
for (int i = 0; i < 8; ++i)
data << uint32( GetTutorialInt(i) );
GetSession()->SendPacket(&data);*/
SendTalentsInfoData(false);
SendInitialSpells();
@ -18104,18 +18076,17 @@ void Player::SendInitialPacketsBeforeAddToMap()
m_achievementMgr.SendAllAchievementData();
UpdateZone(GetZoneId());
// equipment manager!
data.Initialize(SMSG_EQUIPMENT_SET_LIST);
data << uint32(0); // count
/*for(count)
data << uint32(m_EquipmentSets.size()); // count
for(EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end(); ++itr)
{
data << uint8(0); // PGUID, equipment set guid?
data << uint32(0); // counter(0,1,...)?
data << uint8(0); // string set name
data << uint8(0); // string icon name
data.appendPackGUID(itr->second.Guid);
data << uint32(itr->second.Index);
data << itr->second.Name;
data << itr->second.IconName;
for(uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
data << uint8(0); // item GUID?
}*/
data.appendPackGUID(MAKE_NEW_GUID(itr->second.Items[i], 0, HIGHGUID_ITEM));
}
GetSession()->SendPacket(&data);
data.Initialize(SMSG_LOGIN_SETTIMESPEED, 8);
@ -18123,10 +18094,6 @@ void Player::SendInitialPacketsBeforeAddToMap()
data << (float)0.01666667f; // game speed
GetSession()->SendPacket( &data );
data.Initialize(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement
data << uint32(0x00000000); // on blizz it increments periodically
GetSession()->SendPacket(&data);
// set fly flag if in fly form or taxi flight to prevent visually drop at ground in showup moment
if(HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) || isInFlight())
AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
@ -19958,3 +19925,39 @@ void Player::LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank)
pet->learnSpell(spellid);
sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talentId, talentRank, spellid);
}
void Player::SaveEquipmentSet(EquipmentSet eqset)
{
if(m_EquipmentSets.size() >= 10) // client limit
return;
EquipmentSets::iterator itr = m_EquipmentSets.find(eqset.Index);
if(itr != m_EquipmentSets.end())
{
CharacterDatabase.PExecute("UPDATE character_equipmentsets SET name='%s', iconname='%s', item0='%u', item1='%u', item2='%u', item3='%u', item4='%u', item5='%u', item6='%u', item7='%u', item8='%u', item9='%u', item10='%u', item11='%u', item12='%u', item13='%u', item14='%u', item15='%u', item16='%u', item17='%u', item18='%u' WHERE guid='%u' AND setguid='"I64FMTD"' AND setindex='%u'",
eqset.Name.c_str(), eqset.IconName.c_str(), eqset.Items[0], eqset.Items[1], eqset.Items[2], eqset.Items[3], eqset.Items[4], eqset.Items[5], eqset.Items[6], eqset.Items[7],
eqset.Items[8], eqset.Items[9], eqset.Items[10], eqset.Items[11], eqset.Items[12], eqset.Items[13], eqset.Items[14], eqset.Items[15], eqset.Items[16], eqset.Items[17], eqset.Items[18], GetGUIDLow(), eqset.Guid, eqset.Index);
}
else
{
CharacterDatabase.PExecute("INSERT INTO character_equipmentsets VALUES ('%u', '"I64FMTD"', '%u', '%s', '%s', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')",
GetGUIDLow(), eqset.Guid, eqset.Index, eqset.Name.c_str(), eqset.IconName.c_str(), eqset.Items[0], eqset.Items[1], eqset.Items[2], eqset.Items[3], eqset.Items[4], eqset.Items[5], eqset.Items[6], eqset.Items[7],
eqset.Items[8], eqset.Items[9], eqset.Items[10], eqset.Items[11], eqset.Items[12], eqset.Items[13], eqset.Items[14], eqset.Items[15], eqset.Items[16], eqset.Items[17], eqset.Items[18]);
}
m_EquipmentSets[eqset.Index] = eqset;
}
void Player::DeleteEquipmentSet(uint64 setGuid)
{
CharacterDatabase.PExecute("DELETE FROM character_equipmentsets WHERE setguid="I64FMTD, setGuid);
for(EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end(); ++itr)
{
if(itr->second.Guid == setGuid)
{
m_EquipmentSets.erase(itr);
break;
}
}
}

View file

@ -145,6 +145,7 @@ struct ActionButton
enum ActionButtonType
{
ACTION_BUTTON_SPELL = 0,
ACTION_BUTTON_EQSET = 32,
ACTION_BUTTON_MACRO = 64,
ACTION_BUTTON_CMACRO= 65,
ACTION_BUTTON_ITEM = 128
@ -702,6 +703,17 @@ enum QuestBagSlots
QUESTBAG_SLOT_END = 200
};
struct EquipmentSet
{
uint64 Guid;
uint32 Index;
std::string Name;
std::string IconName;
uint32 Items[EQUIPMENT_SLOT_END];
};
typedef std::map<uint32, EquipmentSet> EquipmentSets;
struct ItemPosCount
{
ItemPosCount(uint16 _pos, uint32 _count) : pos(_pos), count(_count) {}
@ -833,24 +845,23 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOADSPELLS = 4,
PLAYER_LOGIN_QUERY_LOADQUESTSTATUS = 5,
PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS = 6,
PLAYER_LOGIN_QUERY_LOADTUTORIALS = 7, // common for all characters for some account at specific realm
PLAYER_LOGIN_QUERY_LOADREPUTATION = 8,
PLAYER_LOGIN_QUERY_LOADINVENTORY = 9,
PLAYER_LOGIN_QUERY_LOADACTIONS = 10,
PLAYER_LOGIN_QUERY_LOADMAILCOUNT = 11,
PLAYER_LOGIN_QUERY_LOADMAILDATE = 12,
PLAYER_LOGIN_QUERY_LOADSOCIALLIST = 13,
PLAYER_LOGIN_QUERY_LOADHOMEBIND = 14,
PLAYER_LOGIN_QUERY_LOADSPELLCOOLDOWNS = 15,
PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES = 16,
PLAYER_LOGIN_QUERY_LOADGUILD = 17,
PLAYER_LOGIN_QUERY_LOADARENAINFO = 18,
PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS = 19,
PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS = 20,
PLAYER_LOGIN_QUERY_LOADREPUTATION = 7,
PLAYER_LOGIN_QUERY_LOADINVENTORY = 8,
PLAYER_LOGIN_QUERY_LOADACTIONS = 9,
PLAYER_LOGIN_QUERY_LOADMAILCOUNT = 10,
PLAYER_LOGIN_QUERY_LOADMAILDATE = 11,
PLAYER_LOGIN_QUERY_LOADSOCIALLIST = 12,
PLAYER_LOGIN_QUERY_LOADHOMEBIND = 13,
PLAYER_LOGIN_QUERY_LOADSPELLCOOLDOWNS = 14,
PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES = 15,
PLAYER_LOGIN_QUERY_LOADGUILD = 16,
PLAYER_LOGIN_QUERY_LOADARENAINFO = 17,
PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS = 18,
PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS = 19,
PLAYER_LOGIN_QUERY_LOADEQUIPMENTSETS = 20,
MAX_PLAYER_LOGIN_QUERY = 21
};
// Player summoning auto-decline time (in secs)
#define MAX_PLAYER_SUMMON_DELAY (2*MINUTE)
#define MAX_MONEY_AMOUNT (0x7FFFFFFF-1)
@ -1363,22 +1374,6 @@ class MANGOS_DLL_SPEC Player : public Unit
MoneyChanged( value );
}
uint32 GetTutorialInt(uint32 intId )
{
ASSERT( (intId < 8) );
return m_Tutorials[intId];
}
void SetTutorialInt(uint32 intId, uint32 value)
{
ASSERT( (intId < 8) );
if(m_Tutorials[intId]!=value)
{
m_Tutorials[intId] = value;
m_TutorialsChanged = true;
}
}
QuestStatusMap& getQuestStatusMap() { return mQuestStatus; };
const uint64& GetSelection( ) const { return m_curSelection; }
@ -1856,6 +1851,9 @@ class MANGOS_DLL_SPEC Player : public Unit
void CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attType);
void CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 cast_count, uint32 glyphIndex);
void SaveEquipmentSet(EquipmentSet eqset);
void DeleteEquipmentSet(uint64 setGuid);
void SendInitWorldStates();
void SendUpdateWorldState(uint32 Field, uint32 Value);
void SendDirectMessage(WorldPacket *data);
@ -2210,11 +2208,11 @@ class MANGOS_DLL_SPEC Player : public Unit
void _LoadReputation(QueryResult *result);
void _LoadSkills();
void _LoadSpells(QueryResult *result);
void _LoadTutorials(QueryResult *result);
void _LoadFriendList(QueryResult *result);
bool _LoadHomeBind(QueryResult *result);
void _LoadDeclinedNames(QueryResult *result);
void _LoadArenaTeamInfo(QueryResult *result);
void _LoadEquipmentSets(QueryResult *result);
/*********************************************************/
/*** SAVE SYSTEM ***/
@ -2228,7 +2226,6 @@ class MANGOS_DLL_SPEC Player : public Unit
void _SaveDailyQuestStatus();
void _SaveReputation();
void _SaveSpells();
void _SaveTutorials();
void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
void _SetUpdateBits(UpdateMask *updateMask, Player *target) const;
@ -2318,9 +2315,6 @@ class MANGOS_DLL_SPEC Player : public Unit
time_t m_nextThinkTime;
uint32 m_Tutorials[8];
bool m_TutorialsChanged;
bool m_DailyQuestChanged;
time_t m_lastDailyQuestTime;
@ -2394,6 +2388,7 @@ class MANGOS_DLL_SPEC Player : public Unit
DeclinedName *m_declinedname;
Runes *m_runes;
AchievementMgr m_achievementMgr;
EquipmentSets m_EquipmentSets;
private:
// internal common parts for CanStore/StoreItem functions
uint8 _CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool swap, Item *pSrcItem ) const;

View file

@ -566,6 +566,58 @@ void WorldSession::SetAccountData(uint32 type, time_t time_, std::string data)
CharacterDatabase.CommitTransaction ();
}
void WorldSession::LoadTutorialsData()
{
for ( int aX = 0 ; aX < 8 ; ++aX )
m_Tutorials[ aX ] = 0;
QueryResult *result = CharacterDatabase.PQuery("SELECT tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7 FROM character_tutorial WHERE account = '%u'", GetAccountId());
if(result)
{
do
{
Field *fields = result->Fetch();
for (int iI = 0; iI < 8; iI++)
m_Tutorials[iI] = fields[iI].GetUInt32();
}
while( result->NextRow() );
delete result;
}
}
void WorldSession::SendTutorialsData()
{
WorldPacket data(SMSG_TUTORIAL_FLAGS, 4*8);
for(uint32 i = 0; i < 8; ++i)
data << m_Tutorials[i];
SendPacket(&data);
}
void WorldSession::SaveTutorialsData()
{
uint32 Rows=0;
// it's better than rebuilding indexes multiple times
QueryResult *result = CharacterDatabase.PQuery("SELECT count(*) AS r FROM character_tutorial WHERE account = '%u'", GetAccountId());
if(result)
{
Rows = result->Fetch()[0].GetUInt32();
delete result;
}
if (Rows)
{
CharacterDatabase.PExecute("UPDATE character_tutorial SET tut0='%u', tut1='%u', tut2='%u', tut3='%u', tut4='%u', tut5='%u', tut6='%u', tut7='%u' WHERE account = '%u'",
m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7], GetAccountId());
}
else
{
CharacterDatabase.PExecute("INSERT INTO character_tutorial (account,tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7) VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", GetAccountId(), m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7]);
}
}
void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
{
CHECK_PACKET_SIZE(data, data.rpos()+4+2+4+4+4+4+4);

View file

@ -169,6 +169,19 @@ class MANGOS_DLL_SPEC WorldSession
AccountData *GetAccountData(uint32 type) { return &m_accountData[type]; }
void SetAccountData(uint32 type, time_t time_, std::string data);
void LoadAccountData();
void LoadTutorialsData();
void SendTutorialsData();
void SaveTutorialsData();
uint32 GetTutorialInt(uint32 intId )
{
return m_Tutorials[intId];
}
void SetTutorialInt(uint32 intId, uint32 value)
{
if(m_Tutorials[intId] != value)
m_Tutorials[intId] = value;
}
//mail
//used with item_page table
@ -672,6 +685,7 @@ class MANGOS_DLL_SPEC WorldSession
void HandleCharCustomize(WorldPacket& recv_data);
void HandleInspectAchievements(WorldPacket& recv_data);
void HandleEquipmentSetSave(WorldPacket& recv_data);
void HandleEquipmentSetDelete(WorldPacket& recv_data);
private:
// private trade methods
void moveItems(Item* myItems[], Item* hisItems[]);
@ -696,6 +710,7 @@ class MANGOS_DLL_SPEC WorldSession
int m_sessionDbLocaleIndex;
uint32 m_latency;
AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES];
uint32 m_Tutorials[8];
ZThread::LockedQueue<WorldPacket*,ZThread::FastMutex> _recvQueue;
};

View file

@ -187,7 +187,7 @@ int WorldSocket::SendPacket (const WorldPacket& pct)
}
ServerPktHeader header(pct.size()+2, pct.GetOpcode());
m_Crypt.EncryptSend ( header.header, header.getHeaderLength());
//m_Crypt.EncryptSend ( header.header, header.getHeaderLength());
if (m_OutBuffer->space () >= pct.size () + header.getHeaderLength() && msg_queue()->is_empty())
{
@ -480,7 +480,7 @@ int WorldSocket::handle_input_header (void)
ACE_ASSERT (m_Header.length () == sizeof (ClientPktHeader));
m_Crypt.DecryptRecv ((ACE_UINT8*) m_Header.rd_ptr (), sizeof (ClientPktHeader));
//m_Crypt.DecryptRecv ((ACE_UINT8*) m_Header.rd_ptr (), sizeof (ClientPktHeader));
ClientPktHeader& header = *((ClientPktHeader*) m_Header.rd_ptr ());
@ -982,10 +982,10 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
// NOTE ATM the socket is singlethreaded, have this in mind ...
ACE_NEW_RETURN (m_Session, WorldSession (id, this, security, expansion, mutetime, locale), -1);
m_Crypt.SetKey (&K);
m_Crypt.Init ();
m_Crypt.Init(&K);
m_Session->LoadAccountData();
m_Session->LoadTutorialsData();
// In case needed sometime the second arg is in microseconds 1 000 000 = 1 sec
ACE_OS::sleep (ACE_Time_Value (0, 10000));
@ -996,11 +996,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
if (sAddOnHandler.BuildAddonPacket (&recvPacket, &SendAddonPacked))
SendPacket (SendAddonPacked);
// TODO: fix it!
WorldPacket data(SMSG_TUTORIAL_FLAGS, 4*8);
for(uint32 i = 0; i < 8; ++i)
data << uint32(-1);
SendPacket(data);
m_Session->SendTutorialsData();
return 0;
}

View file

@ -66,8 +66,8 @@ enum LoginResult
// we need to stick to 1 version or half of the stuff will work for someone
// others will not and opposite
// will only support WoW, WoW:TBC and WoW:WotLK 3.1.0 client build 9626...
// will only support WoW, WoW:TBC and WoW:WotLK 3.1.0 client build 9637...
#define EXPECTED_MANGOS_CLIENT_BUILD {9626, 0}
#define EXPECTED_MANGOS_CLIENT_BUILD {9637, 0}
#endif

View file

@ -24,57 +24,46 @@ AuthCrypt::AuthCrypt()
_initialized = false;
}
void AuthCrypt::Init()
AuthCrypt::~AuthCrypt()
{
_send_i = _send_j = _recv_i = _recv_j = 0;
}
void AuthCrypt::Init(BigNumber *K)
{
uint8 recvSeed[SEED_KEY_SIZE] = { 0x22, 0xBE, 0xE5, 0xCF, 0xBB, 0x07, 0x64, 0xD9, 0x00, 0x45, 0x1B, 0xD0, 0x24, 0xB8, 0xD5, 0x45 };
HmacHash recvHash(SEED_KEY_SIZE, (uint8*)recvSeed);
recvHash.UpdateBigNumber(K);
recvHash.Finalize();
_recvCrypt.Init(SHA_DIGEST_LENGTH, recvHash.GetDigest());
uint8 sendSeed[SEED_KEY_SIZE] = { 0xF4, 0x66, 0x31, 0x59, 0xFC, 0x83, 0x6E, 0x31, 0x31, 0x02, 0x51, 0xD5, 0x44, 0x31, 0x67, 0x98 };
HmacHash sendHash(SEED_KEY_SIZE, (uint8*)sendSeed);
sendHash.UpdateBigNumber(K);
sendHash.Finalize();
_sendCrypt.Init(SHA_DIGEST_LENGTH, sendHash.GetDigest());
uint8 emptyBuf[1000];
memset(emptyBuf, 0, 1000);
_sendCrypt.Process(1000, (uint8*)emptyBuf, (uint8*)emptyBuf);
_recvCrypt.Process(1000, (uint8*)emptyBuf, (uint8*)emptyBuf);
_initialized = true;
}
void AuthCrypt::DecryptRecv(uint8 *data, size_t len)
{
if (!_initialized) return;
if (len < CRYPTED_RECV_LEN) return;
if (!_initialized)
return;
for (size_t t = 0; t < CRYPTED_RECV_LEN; t++)
{
_recv_i %= _key.size();
uint8 x = (data[t] - _recv_j) ^ _key[_recv_i];
++_recv_i;
_recv_j = data[t];
data[t] = x;
}
_recvCrypt.Process(len, data, data);
}
void AuthCrypt::EncryptSend(uint8 *data, size_t len)
{
if (!_initialized) return;
if (!_initialized)
return;
for (size_t t = 0; t < len; t++)
{
_send_i %= _key.size();
uint8 x = (data[t] ^ _key[_send_i]) + _send_j;
++_send_i;
data[t] = _send_j = x;
}
}
void AuthCrypt::SetKey(BigNumber *bn)
{
uint8 *key = new uint8[SHA_DIGEST_LENGTH];
GenerateKey(key, bn);
_key.resize(SHA_DIGEST_LENGTH);
std::copy(key, key + SHA_DIGEST_LENGTH, _key.begin());
delete[] key;
}
AuthCrypt::~AuthCrypt()
{
}
void AuthCrypt::GenerateKey(uint8 *key, BigNumber *bn)
{
HmacHash hash;
hash.UpdateBigNumber(bn);
hash.Finalize();
memcpy(key, hash.GetDigest(), SHA_DIGEST_LENGTH);
_sendCrypt.Process(len, data, data);
}

View file

@ -21,6 +21,7 @@
#include <Common.h>
#include <vector>
#include "SARC4.h"
class BigNumber;
@ -30,22 +31,15 @@ class AuthCrypt
AuthCrypt();
~AuthCrypt();
const static size_t CRYPTED_RECV_LEN = 6;
void Init();
void SetKey(BigNumber *);
void Init(BigNumber *K);
void DecryptRecv(uint8 *, size_t);
void EncryptSend(uint8 *, size_t);
bool IsInitialized() { return _initialized; }
static void GenerateKey(uint8 *, BigNumber *);
private:
std::vector<uint8> _key;
uint8 _send_i, _send_j, _recv_i, _recv_j;
SARC4 _sendCrypt;
SARC4 _recvCrypt;
bool _initialized;
};
#endif

View file

@ -19,10 +19,11 @@
#include "Auth/Hmac.h"
#include "BigNumber.h"
HmacHash::HmacHash()
HmacHash::HmacHash(uint32 len, uint8 *seed)
{
uint8 temp[SEED_KEY_SIZE] = { 0x38, 0xA7, 0x83, 0x15, 0xF8, 0x92, 0x25, 0x30, 0x71, 0x98, 0x67, 0xB1, 0x8C, 0x4, 0xE2, 0xAA };
memcpy(&m_key, &temp, SEED_KEY_SIZE);
ASSERT(len == SEED_KEY_SIZE);
memcpy(&m_key, seed, len);
HMAC_CTX_init(&m_ctx);
HMAC_Init_ex(&m_ctx, &m_key, SEED_KEY_SIZE, EVP_sha1(), NULL);
}

View file

@ -30,7 +30,7 @@ class BigNumber;
class HmacHash
{
public:
HmacHash();
HmacHash(uint32 len, uint8 *seed);
~HmacHash();
void UpdateBigNumber(BigNumber *bn);
void UpdateData(const uint8 *data, int length);

View file

@ -33,6 +33,8 @@ libmangosauth_a_SOURCES = \
BigNumber.h \
Hmac.cpp \
Hmac.h \
SARC4.cpp \
SARC4.h \
Sha1.cpp \
Sha1.h \
md5.c \

30
src/shared/Auth/SARC4.cpp Normal file
View file

@ -0,0 +1,30 @@
/*
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Auth/SARC4.h"
#include "BigNumber.h"
void SARC4::Init(uint32 len, uint8 *seed)
{
RC4_set_key(&m_rc4_key, len, seed);
}
void SARC4::Process(uint32 len, uint8 *indata, uint8 *outdata)
{
RC4(&m_rc4_key, len, indata, outdata);
}

38
src/shared/Auth/SARC4.h Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _AUTH_SARC4_H
#define _AUTH_SARC4_H
#include "Common.h"
#include <openssl/rc4.h>
#include <openssl/sha.h>
class BigNumber;
#define SEED_KEY_SIZE 16
class SARC4
{
public:
void Init(uint32 len, uint8 *seed);
void Process(uint32 len, uint8 *indata, uint8 *outdata);
private:
RC4_KEY m_rc4_key;
};
#endif

View file

@ -632,6 +632,14 @@
RelativePath="..\..\src\shared\Auth\Hmac.h"
>
</File>
<File
RelativePath="..\..\src\shared\Auth\SARC4.cpp"
>
</File>
<File
RelativePath="..\..\src\shared\Auth\SARC4.h"
>
</File>
<File
RelativePath="..\..\src\shared\Auth\Sha1.cpp"
>