void WorldSession::HandlePlayerLoginOpcode( WorldPacket & recv_data ) { m_playerLoading = true; uint64 playerGuid = 0; DEBUG_LOG( "WORLD: Recvd Player Logon Message" ); recv_data >> playerGuid; Player* plr = new Player(this); ASSERT(plr); plr->SetSession(this); // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if(!plr->LoadFromDB(GUID_LOPART(playerGuid))) { m_playerLoading = false; return; } //plr->_RemoveAllItemMods(); //set a count of unread mails: QueryResult *resultMails = sDatabase.PQuery("SELECT COUNT(id) FROM `mail` WHERE `receiver` = '%u' AND `checked` = 0", GUID_LOPART(playerGuid)); if (resultMails) { Field *fieldMail = resultMails->Fetch(); plr->unReadMails = fieldMail[0].GetUInt8(); delete resultMails; } else plr->unReadMails = 0; SetPlayer(plr); WorldPacket data( SMSG_ACCOUNT_DATA_MD5, (80) ); for(int i = 0; i < 80; i++) data << uint8(0); SendPacket(&data); Player *pCurrChar = GetPlayer(); pCurrChar->LoadIgnoreList(); pCurrChar->SendFriendlist(); pCurrChar->SendIgnorelist(); sChatHandler.FillSystemMessageData(&data, this, sWorld.GetMotd()); SendPacket( &data ); DEBUG_LOG( "WORLD: Sent motd (SMSG_MESSAGECHAT)" ); if(pCurrChar->GetGuildId() != 0) { Guild* guild = objmgr.GetGuildById(pCurrChar->GetGuildId()); if(guild) { data.Initialize(SMSG_GUILD_EVENT, (2+guild->GetMOTD().size()+1)); data << (uint8)GE_MOTD; data << (uint8)1; data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG( "WORLD: Sent guild-motd (SMSG_GUILD_EVENT)" ); data.Initialize(SMSG_GUILD_EVENT, (5+10)); // we guess size data<<(uint8)GE_SIGNED_ON; data<<(uint8)1; data<<pCurrChar->GetName(); data<<(uint8)0<<(uint8)0<<(uint8)0; guild->BroadcastPacket(&data); DEBUG_LOG( "WORLD: Sent guild-signed-on (SMSG_GUILD_EVENT)" ); } else { // remove wrong guild data sLog.outError("Player %s (GUID: %u) marked as member not existed guild (id: %u), removing guild membership for player.",pCurrChar->GetName(),pCurrChar->GetGUIDLow(),pCurrChar->GetGuildId()); pCurrChar->SetUInt32Value(PLAYER_GUILDID,0); pCurrChar->SetUInt32ValueInDB(PLAYER_GUILDID,0,pCurrChar->GetGUID()); } } // home bind stuff Field *fields; QueryResult *result7 = sDatabase.PQuery("SELECT COUNT(`guid`) FROM `character_homebind` WHERE `guid` = '%u'", GUID_LOPART(playerGuid)); if (result7) { int cnt; fields = result7->Fetch(); cnt = fields[0].GetUInt32(); if ( cnt > 0 ) { QueryResult *result4 = sDatabase.PQuery("SELECT `map`,`zone`,`position_x`,`position_y`,`position_z` FROM `character_homebind` WHERE `guid` = '%u'", GUID_LOPART(playerGuid)); assert(result4); fields = result4->Fetch(); data.Initialize (SMSG_BINDPOINTUPDATE, 5*4); data << fields[2].GetFloat() << fields[3].GetFloat() << fields[4].GetFloat(); data << fields[0].GetUInt32(); data << fields[1].GetUInt32(); SendPacket (&data); DEBUG_LOG("Setting player home position: mapid is: %u, zoneid is %u, X is %f, Y is %f, Z is %f\n",fields[0].GetUInt32(),fields[1].GetUInt32(),fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat()); delete result4; } else { int plrace = GetPlayer()->getRace(); int plclass = GetPlayer()->getClass(); QueryResult *result5 = sDatabase.PQuery("SELECT `map`,`zone`,`position_x`,`position_y`,`position_z` FROM `playercreateinfo` WHERE `race` = '%u' AND `class` = '%u'", plrace, plclass); assert(result5); fields = result5->Fetch(); // store and send homebind for player sDatabase.PExecute("INSERT INTO `character_homebind` (`guid`,`map`,`zone`,`position_x`,`position_y`,`position_z`) VALUES ('%u', '%u', '%u', '%f', '%f', '%f')", GUID_LOPART(playerGuid), fields[0].GetUInt32(), fields[1].GetUInt32(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat()); data.Initialize (SMSG_BINDPOINTUPDATE, 5*4); data << fields[2].GetFloat() << fields[3].GetFloat() << fields[4].GetFloat(); data << fields[0].GetUInt32(); data << fields[1].GetUInt32(); SendPacket (&data); DEBUG_LOG("Setting player home position: mapid is: %u, zoneid is %u, X is %f, Y is %f, Z is %f\n",fields[0].GetUInt32(),fields[1].GetUInt32(),fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat()); delete result5; } delete result7; } data.Initialize( SMSG_TUTORIAL_FLAGS, 8*32 ); for (int i = 0; i < 8; i++) data << uint32( GetPlayer()->GetTutorialInt(i) ); SendPacket(&data); //sLog.outDebug( "WORLD: Sent tutorial flags." ); GetPlayer()->SendInitialSpells(); GetPlayer()->SendInitialActionButtons(); /*if(GetPlayer()->getClass() == CLASS_HUNTER || GetPlayer()->getClass() == CLASS_ROGUE) { uint32 shiftdata=0x01; for(uint8 i=0;i<32;i++) { if ( 522753 & shiftdata ) { data.Initialize(SMSG_SET_FLAT_SPELL_MODIFIER); data << uint8(i); data << uint8(5); data << uint16(1); data << uint16(0); SendPacket(&data); } shiftdata=shiftdata<<1; } }*/ data.Initialize(SMSG_INITIALIZE_FACTIONS, (4+64*5)); data << uint32 (0x00000040); for(uint32 a=0; a<64; a++) { if(GetPlayer()->FactionIsInTheList(a)) { std::list<struct Factions>::iterator itr; for(itr = GetPlayer()->factions.begin(); itr != GetPlayer()->factions.end(); ++itr) { if(itr->ReputationListID == a) { data << uint8 (itr->Flags); data << uint32 (itr->Standing); break; } } } else { data << uint8 (0x00); data << uint32 (0x00000000); } } SendPacket(&data); GetPlayer()->UpdateHonor(); data.Initialize(SMSG_LOGIN_SETTIMESPEED, 8); time_t gameTime = sWorld.GetGameTime(); struct tm *lt = localtime(&gameTime); uint32 xmitTime = (lt->tm_year - 100) << 24 | lt->tm_mon << 20 | (lt->tm_mday - 1) << 14 | lt->tm_wday << 11 | lt->tm_hour << 6 | lt->tm_min; data << xmitTime; data << (uint32)0x3C888889; //(float)0.017f; SendPacket( &data ); //Show cinematic at the first time that player login if( !GetPlayer()->getCinematic() ) { GetPlayer()->setCinematic(1); ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(GetPlayer()->getRace()); if(rEntry) { data.Initialize( SMSG_TRIGGER_CINEMATIC,4 ); data << uint32(rEntry->startmovie); SendPacket( &data ); } } QueryResult *result = sDatabase.PQuery("SELECT `guildid`,`rank` FROM `guild_member` WHERE `guid` = '%u'",pCurrChar->GetGUIDLow()); if(result) { Field *fields = result->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); delete result; } MapManager::Instance().GetMap(pCurrChar->GetMapId())->Add(pCurrChar); ObjectAccessor::Instance().InsertPlayer(pCurrChar); //sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); if (pCurrChar->m_transport) { Transport* curTrans = pCurrChar->m_transport; pCurrChar->TeleportTo(curTrans->GetMapId(), curTrans->GetPositionX(), curTrans->GetPositionY(), curTrans->GetPositionZ(), curTrans->GetOrientation(), true, false); } sDatabase.PExecute("UPDATE `character` SET `online` = 1 WHERE `guid` = '%u'", pCurrChar->GetGUIDLow()); loginDatabase.PExecute("UPDATE `account` SET `online` = 1 WHERE `id` = '%u'", GetAccountId()); plr->SetInGameTime( getMSTime() ); data.Initialize(SMSG_FRIEND_STATUS, 19); data<<uint8(FRIEND_ONLINE); data<<pCurrChar->GetGUID(); data<<uint8(1); data<<pCurrChar->GetAreaId(); data<<pCurrChar->getLevel(); data<<pCurrChar->getClass(); pCurrChar->BroadcastPacketToFriendListers(&data); // setting new speed if dead if ( pCurrChar->m_deathState == DEAD ) { pCurrChar->SetMovement(MOVE_WATER_WALK); if (pCurrChar->getRace() == RACE_NIGHTELF) { pCurrChar->SetSpeed(MOVE_RUN, 1.5f*1.2f, true); pCurrChar->SetSpeed(MOVE_SWIM, 1.5f*1.2f, true); } else { pCurrChar->SetSpeed(MOVE_RUN, 1.5f, true); pCurrChar->SetSpeed(MOVE_SWIM, 1.5f, true); } } pCurrChar->LoadEnchant(); pCurrChar->_LoadSpellCooldowns(); // Place charcter in world (and load zone) before some object loading pCurrChar->LoadCorpse(); pCurrChar->LoadPet(); // show time before shutdown if shudown planned. if(sWorld.IsShutdowning()) sWorld.ShutdownMsg(true,pCurrChar); result = sDatabase.PQuery("SELECT `leaderGuid` FROM `raidgroup_member` WHERE `memberGuid`='%u'", GUID_LOPART(pCurrChar->GetGUID())); if(result) { uint64 leaderGuid = MAKE_GUID((*result)[0].GetUInt32(),HIGHGUID_PLAYER); delete result; pCurrChar->groupInfo.group = objmgr.GetGroupByLeader(leaderGuid); if(pCurrChar->groupInfo.group) { pCurrChar->groupInfo.group->SendInit(this); pCurrChar->groupInfo.group->SendUpdate(); } } if(pCurrChar->isGameMaster()) SendNotification("GM mode is ON"); m_playerLoading = false; }
void WorldSession::HandlePlayerLoginOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,8); m_playerLoading = true; uint64 playerGuid = 0; DEBUG_LOG( "WORLD: Recvd Player Logon Message" ); recv_data >> playerGuid; Player* plr = new Player(this); // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if(!plr->LoadFromDB(GUID_LOPART(playerGuid))) { KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete plr; // delete it manually m_playerLoading = false; return; } //plr->_RemoveAllItemMods(); //set a count of unread mails time_t cTime = time(NULL); QueryResult *resultMails = sDatabase.PQuery("SELECT COUNT(id) FROM `mail` WHERE `receiver` = '%u' AND `checked` = 0 AND `deliver_time` <= '" I64FMTD "'", GUID_LOPART(playerGuid),(uint64)cTime); if (resultMails) { Field *fieldMail = resultMails->Fetch(); plr->unReadMails = fieldMail[0].GetUInt8(); delete resultMails; } // store nearest delivery time (it > 0 and if it < current then at next player update SendNewMaill will be called) resultMails = sDatabase.PQuery("SELECT MIN(`deliver_time`) FROM `mail` WHERE `receiver` = '%u' AND `checked` = 0", GUID_LOPART(playerGuid)); if (resultMails) { Field *fieldMail = resultMails->Fetch(); plr->m_nextMailDelivereTime = (time_t)fieldMail[0].GetUInt64(); delete resultMails; } SetPlayer(plr); Player *pCurrChar = GetPlayer(); pCurrChar->SendDungeonDifficulty(); WorldPacket data( SMSG_LOGIN_VERIFY_WORLD, 20 ); data << plr->GetMapId(); data << plr->GetPositionX(); data << plr->GetPositionY(); data << plr->GetPositionZ(); data << plr->GetOrientation(); SendPacket(&data); data.Initialize( SMSG_ACCOUNT_DATA_MD5, 128 ); for(int i = 0; i < 32; i++) data << uint32(0); SendPacket(&data); pCurrChar->LoadIgnoreList(); pCurrChar->SendFriendlist(); pCurrChar->SendIgnorelist(); // Send MOTD { data.Initialize(SMSG_MOTD, 50); // new in 2.0.1 data << (uint32)0; uint32 linecount=0; string str_motd = sWorld.GetMotd(); string::size_type pos, nextpos; pos = 0; while ( (nextpos= str_motd.find('@',pos)) != string::npos ) { if (nextpos != pos) { data << str_motd.substr(pos,nextpos-pos); linecount++; } pos = nextpos+1; } if (pos<str_motd.length()) { data << str_motd.substr(pos); linecount++; } data.put(0, linecount); SendPacket( &data ); DEBUG_LOG( "WORLD: Sent motd (SMSG_MOTD)" ); } if(pCurrChar->GetGuildId() != 0) { Guild* guild = objmgr.GetGuildById(pCurrChar->GetGuildId()); if(guild) { data.Initialize(SMSG_GUILD_EVENT, (2+guild->GetMOTD().size()+1)); data << (uint8)GE_MOTD; data << (uint8)1; data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG( "WORLD: Sent guild-motd (SMSG_GUILD_EVENT)" ); data.Initialize(SMSG_GUILD_EVENT, (5+10)); // we guess size data<<(uint8)GE_SIGNED_ON; data<<(uint8)1; data<<pCurrChar->GetName(); data<<pCurrChar->GetGUID(); guild->BroadcastPacket(&data); DEBUG_LOG( "WORLD: Sent guild-signed-on (SMSG_GUILD_EVENT)" ); } else { // remove wrong guild data sLog.outError("Player %s (GUID: %u) marked as member not existed guild (id: %u), removing guild membership for player.",pCurrChar->GetName(),pCurrChar->GetGUIDLow(),pCurrChar->GetGuildId()); pCurrChar->SetUInt32Value(PLAYER_GUILDID,0); pCurrChar->SetUInt32ValueInDB(PLAYER_GUILDID,0,pCurrChar->GetGUID()); } } // rest_start // home bind stuff { QueryResult *result4 = sDatabase.PQuery("SELECT `map`,`zone`,`position_x`,`position_y`,`position_z` FROM `character_homebind` WHERE `guid` = '%u'", GUID_LOPART(playerGuid)); if (result4) { Field *fields = result4->Fetch(); _player->m_homebindMapId = fields[0].GetUInt32(); _player->m_homebindZoneId = fields[1].GetUInt16(); _player->m_homebindX = fields[2].GetFloat(); _player->m_homebindY = fields[3].GetFloat(); _player->m_homebindZ = fields[4].GetFloat(); delete result4; } else { int plrace = GetPlayer()->getRace(); int plclass = GetPlayer()->getClass(); QueryResult *result5 = sDatabase.PQuery("SELECT `map`,`zone`,`position_x`,`position_y`,`position_z` FROM `playercreateinfo` WHERE `race` = '%u' AND `class` = '%u'", plrace, plclass); if(!result5) { sLog.outErrorDb("Table `playercreateinfo` not have data for race %u class %u , character can't be loaded.",plrace, plclass); LogoutPlayer(false); // without save return; } Field *fields = result5->Fetch(); // store and send homebind for player _player->m_homebindMapId = fields[0].GetUInt32(); _player->m_homebindZoneId = fields[1].GetUInt16(); _player->m_homebindX = fields[2].GetFloat(); _player->m_homebindY = fields[3].GetFloat(); _player->m_homebindZ = fields[4].GetFloat(); sDatabase.PExecute("INSERT INTO `character_homebind` (`guid`,`map`,`zone`,`position_x`,`position_y`,`position_z`) VALUES ('%u', '%u', '%u', '%f', '%f', '%f')", GUID_LOPART(playerGuid), _player->m_homebindMapId, (uint32)_player->m_homebindZoneId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ); delete result5; } data.Initialize (SMSG_BINDPOINTUPDATE, 5*4); data << _player->m_homebindX << _player->m_homebindY << _player->m_homebindZ; data << (uint32) _player->m_homebindMapId; data << (uint32) _player->m_homebindZoneId; SendPacket (&data); DEBUG_LOG("Setting player home position: mapid is: %u, zoneid is %u, X is %f, Y is %f, Z is %f\n", _player->m_homebindMapId,_player->m_homebindZoneId,_player->m_homebindX,_player->m_homebindY, _player->m_homebindZ); } data.Initialize( SMSG_TUTORIAL_FLAGS, 8*32 ); for (int i = 0; i < 8; i++) data << uint32( GetPlayer()->GetTutorialInt(i) ); SendPacket(&data); //sLog.outDebug( "WORLD: Sent tutorial flags." ); pCurrChar->_LoadSpellCooldowns(); GetPlayer()->SendInitialSpells(); GetPlayer()->SendInitialActionButtons(); GetPlayer()->SendInitialReputations(); /*if(GetPlayer()->getClass() == CLASS_HUNTER || GetPlayer()->getClass() == CLASS_ROGUE) { uint32 shiftdata=0x01; for(uint8 i=0;i<32;i++) { if ( 522753 & shiftdata ) { data.Initialize(SMSG_SET_FLAT_SPELL_MODIFIER); data << uint8(i); data << uint8(5); data << uint16(1); data << uint16(0); SendPacket(&data); } shiftdata=shiftdata<<1; } }*/ //Show cinematic at the first time that player login if( !GetPlayer()->getCinematic() ) { GetPlayer()->setCinematic(1); ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(GetPlayer()->getRace()); if(rEntry) { data.Initialize( SMSG_TRIGGER_CINEMATIC,4 ); data << uint32(rEntry->startmovie); SendPacket( &data ); } } pCurrChar->SendInitWorldStates(); pCurrChar->CastSpell(pCurrChar, 836, true); // LOGINEFFECT data.Initialize(SMSG_LOGIN_SETTIMESPEED, 8); time_t gameTime = sWorld.GetGameTime(); struct tm *lt = localtime(&gameTime); uint32 xmitTime = (lt->tm_year - 100) << 24 | lt->tm_mon << 20 | (lt->tm_mday - 1) << 14 | lt->tm_wday << 11 | lt->tm_hour << 6 | lt->tm_min; data << xmitTime; data << (float)0.017f; // game speed SendPacket( &data ); GetPlayer()->UpdateHonorFields(); QueryResult *result = sDatabase.PQuery("SELECT `guildid`,`rank` FROM `guild_member` WHERE `guid` = '%u'",pCurrChar->GetGUIDLow()); if(result) { Field *fields = result->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); delete result; } else if(pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about non existed membership { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } if (!MapManager::Instance().GetMap(pCurrChar->GetMapId(), pCurrChar)->AddInstanced(pCurrChar)) { // TODO : Teleport to zone-in area } MapManager::Instance().GetMap(pCurrChar->GetMapId(), pCurrChar)->Add(pCurrChar); ObjectAccessor::Instance().InsertPlayer(pCurrChar); //sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); if (pCurrChar->m_transport) { Transport* curTrans = pCurrChar->m_transport; pCurrChar->TeleportTo(curTrans->GetMapId(), curTrans->GetPositionX(), curTrans->GetPositionY(), curTrans->GetPositionZ(), curTrans->GetOrientation(), true, false); } sDatabase.PExecute("UPDATE `character` SET `online` = 1 WHERE `guid` = '%u'", pCurrChar->GetGUIDLow()); loginDatabase.PExecute("UPDATE `account` SET `online` = 1 WHERE `id` = '%u'", GetAccountId()); plr->SetInGameTime( getMSTime() ); // set some aura effects after add player to map if(pCurrChar->HasAuraType(SPELL_AURA_MOD_STUN)) pCurrChar->SetMovement(MOVE_ROOT); if(pCurrChar->HasAuraType(SPELL_AURA_MOD_ROOT)) { WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10); data.append(pCurrChar->GetPackGUID()); data << (uint32)2; pCurrChar->SendMessageToSet(&data,true); } // announce group about member online (must be after add to player list to receive announce to self) if(pCurrChar->groupInfo.group) { //pCurrChar->groupInfo.group->SendInit(this); // useless pCurrChar->groupInfo.group->SendUpdate(); } // friend status data.Initialize(SMSG_FRIEND_STATUS, 19); data<<uint8(FRIEND_ONLINE); data<<pCurrChar->GetGUID(); data<<uint8(1); data<<pCurrChar->GetAreaId(); data<<pCurrChar->getLevel(); data<<pCurrChar->getClass(); pCurrChar->BroadcastPacketToFriendListers(&data); pCurrChar->SendEnchantmentDurations(); // must be after add to map // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); // setting Ghost+speed if dead //if ( pCurrChar->m_deathState == DEAD ) if ( pCurrChar->m_deathState != ALIVE ) { // not blizz like, we must correctly save and load player instead... if(pCurrChar->getRace() == RACE_NIGHTELF) pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+41, 8326); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+42, 20584); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAFLAGS+6, 238); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURALEVELS+11, 514); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+11, 65535); //pCurrChar->SetUInt32Value(UNIT_FIELD_DISPLAYID, 1825); //if (pCurrChar->getRace() == RACE_NIGHTELF) //{ // pCurrChar->SetSpeed(MOVE_RUN, 1.5f*1.2f, true); // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f*1.2f, true); //} //else //{ // pCurrChar->SetSpeed(MOVE_RUN, 1.5f, true); // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f, true); //} pCurrChar->SetMovement(MOVE_WATER_WALK); } // Load pet if any and player is alive if(pCurrChar->isAlive()) pCurrChar->LoadPet(); // show time before shutdown if shutdown planned. if(sWorld.IsShutdowning()) sWorld.ShutdownMsg(true,pCurrChar); if(pCurrChar->isGameMaster()) SendNotification("GM mode is ON"); m_playerLoading = false; pCurrChar->SendAllowMove(); data.Initialize(SMSG_UNKNOWN_811, 4); data << uint32(0); SendPacket(&data); }