WorldSession::~WorldSession() { deleteMutex.Acquire(); if(HasGMPermissions()) sWorld.gmList.erase(this); if(_player) { printf("warning: logged out player in worldsession destructor"); LogoutPlayer(true); } if(permissions) delete [] permissions; WorldPacket *packet; while((packet = _recvQueue.Pop())) delete packet; for(uint32 x=0;x<8;x++) { if(sAccountData[x].data) delete [] sAccountData[x].data; } if(_socket) _socket->SetSession(0); if(m_loggingInPlayer) m_loggingInPlayer->SetSession(NULL); deleteMutex.Release(); }
void WorldSession::HandleGMTicketToggleSystemStatusOpcode(WorldPacket & recv_data) { if(!HasGMPermissions()) return; sWorld.toggleGMTicketStatus(); }
void WorldSession::HandleArenaTeamAddMemberOpcode(WorldPacket & recv_data) { WorldPacket data(SMSG_ARENA_TEAM_INVITE, 40); string player_name; uint32 teamId; recv_data >> teamId >> player_name; ArenaTeam * pTeam = objmgr.GetArenaTeamById(teamId); if( !pTeam ) return; if(!pTeam->HasMember(GetPlayer()->GetLowGUID())) { GetPlayer()->SoftDisconnect(); return; } Player * plr = objmgr.GetPlayer(player_name.c_str(), false); if(plr == NULL) { SystemMessage("Player `%s` is non-existent or not online.", player_name.c_str()); return; } if(pTeam->m_leader != _player->GetLowGUID()) { SystemMessage("You are not the captain of this arena team."); return; } if( plr->getLevel() < PLAYER_ARENA_MIN_LEVEL ) { SystemMessage( "Player must be level %u to join an arena team.", PLAYER_ARENA_MIN_LEVEL ); return; } if(plr->m_arenaTeams[pTeam->m_type] != NULL) { SystemMessage("That player is already in an arena team of this type."); return; } if(plr->m_arenateaminviteguid != 0) { SystemMessage("That player is already invited to an arena team"); return; } if(plr->GetTeam() != _player->GetTeam() && !HasGMPermissions()) { SystemMessage("That player is a member of a different faction."); return; } plr->m_arenateaminviteguid = _player->m_arenaTeams[pTeam->m_type]->m_id; data << _player->GetName(); data << _player->m_arenaTeams[pTeam->m_type]->m_name; plr->GetSession()->SendPacket(&data); }
void WorldSession::HandleMoveTeleportAckOpcode(WorldPacket & recv_data) { WoWGuid guid; recv_data >> guid; if(guid == _player->GetGUID()) { if(sWorld.antihack_teleport && !(HasGMPermissions() && sWorld.no_antihack_on_gm) && _player->GetPlayerStatus() != TRANSFER_PENDING) { /* we're obviously cheating */ sCheatLog.writefromsession(this, "Used teleport hack, disconnecting."); Disconnect(); return; } if(sWorld.antihack_teleport && !(HasGMPermissions() && sWorld.no_antihack_on_gm) && _player->m_position.Distance2DSq(_player->m_sentTeleportPosition) > 625.0f) /* 25.0f*25.0f */ { /* cheating.... :( */ sCheatLog.writefromsession(this, "Used teleport hack {2}, disconnecting."); Disconnect(); return; } LOG_DEBUG("WORLD: got MSG_MOVE_TELEPORT_ACK."); GetPlayer()->SetPlayerStatus(NONE); if(GetPlayer()->m_rooted <= 0) GetPlayer()->SetMovement(MOVE_UNROOT, 5); _player->SpeedCheatReset(); std::list<Pet*> summons = _player->GetSummons(); for(std::list<Pet*>::iterator itr = summons.begin(); itr != summons.end(); ++itr) { // move pet too (*itr)->SetPosition((GetPlayer()->GetPositionX() + 2), (GetPlayer()->GetPositionY() + 2), GetPlayer()->GetPositionZ(), M_PI_FLOAT); } if(_player->m_sentTeleportPosition.x != 999999.0f) { _player->m_position = _player->m_sentTeleportPosition; _player->m_sentTeleportPosition.ChangeCoords(999999.0f, 999999.0f, 999999.0f); } } }
void WorldSession::HandleBeginTrade(WorldPacket & recv_data) { if(!_player->IsInWorld()) { return; } #ifdef FORCED_GM_TRAINEE_MODE if( CanUseCommand('k') && !HasGMPermissions() ) { GetPlayer()->BroadcastMessage( "You are not allowed to use this feature" ); return; } #endif if( sWorld.getIntRate( INTRATE_DISABLE_TRADE_FEATURE ) ) { GetPlayer()->BroadcastMessage( "Trade feature is disabled right now" ); return; } sLog.outDebug( "WORLD: got CMSG_BEGIN_TRADE from player %s.", _player->GetName() ); packetSMSG_TRADE_STATUS data; memset( &data, 0, sizeof( data ) ); data.trade_status = TRADE_STATUS_INITIATED; data.trade_id = TRADE_ID_CONST; //this the constant used in status update also ! Player * plr = _player->GetTradeTarget(); if(_player->mTradeTarget == 0 || plr == 0) { data.trade_status = TRADE_STATUS_PLAYER_NOT_FOUND; OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); return; } // We're too far from target now? Player * plr2 = objmgr.GetPlayer(_player->mTradeTarget); if( plr2 == NULL ) { return; //wtf ? player is inside the map and not in objectmanager ? } if( _player->CalcDistance( plr2 ) > 10.0f ) data.trade_status = TRADE_STATUS_TOO_FAR_AWAY; //send to ourself OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); //send to our target plr->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); plr->mTradeStatus = data.trade_status; _player->mTradeStatus = data.trade_status; // _player->SendTradeUpdate( 0 ); // plr->SendTradeUpdate( 0 ); }
void WorldSession::HandleMoveTeleportAckOpcode( WorldPacket & recv_data ) { uint64 guid; recv_data >> guid; if(guid == _player->GetGUID()) { if(sWorld.antihack_teleport && !(HasGMPermissions() && sWorld.no_antihack_on_gm) && _player->GetPlayerStatus() != TRANSFER_PENDING) { /* we're obviously cheating */ sCheatLog.writefromsession(this, "Used teleport hack, disconnecting."); Disconnect(); return; } if(sWorld.antihack_teleport && !(HasGMPermissions() && sWorld.no_antihack_on_gm) && _player->m_position.Distance2DSq(_player->m_sentTeleportPosition) > 625.0f) /* 25.0f*25.0f */ { /* cheating.... :( */ sCheatLog.writefromsession(this, "Used teleport hack {2}, disconnecting."); Disconnect(); return; } sLog.outDebug( "WORLD: got MSG_MOVE_TELEPORT_ACK." ); GetPlayer()->SetPlayerStatus(NONE); if( GetPlayer()->m_rooted <= 0 ) GetPlayer()->SetMovement(MOVE_UNROOT,5); _player->SpeedCheatReset(); if(GetPlayer()->GetSummon() != NULL) // move pet too GetPlayer()->GetSummon()->SetPosition((GetPlayer()->GetPositionX() + 2), (GetPlayer()->GetPositionY() + 2), GetPlayer()->GetPositionZ(), float(M_PI)); if(_player->m_sentTeleportPosition.x != 999999.0f) { _player->m_position = _player->m_sentTeleportPosition; _player->m_sentTeleportPosition.ChangeCoords(999999.0f,999999.0f,999999.0f); } } }
void WorldSession::HandleTeleportCheatOpcode(WorldPacket & recv_data) { float x,y,z,o; LocationVector vec; if(!HasGMPermissions()) { SendNotification("You do not have permission to use this function."); return; } recv_data >> x >> y >> z >> o; vec.ChangeCoords(x,y,z,o); _player->SafeTeleport(_player->GetMapId(),_player->GetInstanceID(),vec); }
void WorldSession::HandleWorldportOpcode(WorldPacket & recv_data) { uint32 mapid; float x,y,z,o; recv_data >> mapid >> x >> y >> z >> o; if(!_player->IsInWorld()) return; if(!HasGMPermissions()) { SendNotification("You do not have permission to use this function."); return; } LocationVector vec(x,y,z,o); _player->SafeTeleport(mapid,0,vec); }
void WorldSession::HandleTeleportToUnitOpcode(WorldPacket & recv_data) { uint8 unk; Unit * target; recv_data >> unk; if(!_player->IsInWorld()) return; if(!HasGMPermissions()) { SendNotification("You do not have permission to use this function."); return; } if( (target = _player->GetMapMgr()->GetUnit(_player->GetSelection())) == NULL ) return; _player->SafeTeleport(_player->GetMapId(), _player->GetInstanceID(), target->GetPosition()); }
void WorldSession::HandleSetTradeGold(WorldPacket & recv_data) { #ifdef FORCED_GM_TRAINEE_MODE if( CanUseCommand('k') && !HasGMPermissions() ) { GetPlayer()->BroadcastMessage( "You are not allowed to use this feature" ); return; } #endif if(_player->mTradeTarget == 0) { return; } // cebernic: TradeGold sameway. Player * plr = _player->GetTradeTarget(); if(!plr) { return; } // packetSMSG_TRADE_STATUS data; // memset( &data, 0, sizeof( data ) ); // data.trade_status = TRADE_STATUS_STATE_CHANGED; // OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); // plr->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); plr->mTradeStatus = TRADE_STATUS_STATE_CHANGED; _player->mTradeStatus = TRADE_STATUS_STATE_CHANGED; uint64 Gold; recv_data >> Gold; if(_player->mTradeGold != Gold) { _player->mTradeGold = (Gold > _player->GetGold() ? _player->GetGold() : Gold); _player->SendTradeUpdate( ); } }
void WorldSession::FullLogin(Player* plr) { DEBUG_LOG("WorldSession", "Fully loading player %u", plr->GetLowGUID()); SetPlayer(plr); m_MoverWoWGuid.Init(plr->GetGUID()); // copy to movement array plr->movement_packet[0] = m_MoverWoWGuid.GetNewGuidMask(); memcpy(&plr->movement_packet[1], m_MoverWoWGuid.GetNewGuid(), m_MoverWoWGuid.GetNewGuidLen()); /* world preload */ packetSMSG_LOGIN_VERIFY_WORLD vwpck; vwpck.MapId = plr->GetMapId(); vwpck.O = plr->GetOrientation(); vwpck.X = plr->GetPositionX(); vwpck.Y = plr->GetPositionY(); vwpck.Z = plr->GetPositionZ(); OutPacket( SMSG_LOGIN_VERIFY_WORLD, sizeof(packetSMSG_LOGIN_VERIFY_WORLD), &vwpck ); // send voicechat state - active/inactive /* {SERVER} Packet: (0x03C7) UNKNOWN PacketSize = 2 |------------------------------------------------|----------------| |00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF| |------------------------------------------------|----------------| |02 01 |.. | ------------------------------------------------------------------- */ WorldPacket datab; datab.Initialize(SMSG_FEATURE_SYSTEM_STATUS); datab << uint8(2) << uint8(0); SendPacket(&datab); datab.Initialize(SMSG_LEARNED_DANCE_MOVES); datab << uint32(0); datab << uint32(0); SendPacket(&datab); plr->UpdateAttackSpeed(); // Anti max level hack. if(sWorld.LevelCap_Custom_All && (plr->getLevel() > sWorld.LevelCap_Custom_All)) plr->SetUInt32Value(UNIT_FIELD_LEVEL, sWorld.LevelCap_Custom_All); // Enable certain GM abilities on login. if(HasGMPermissions()) { plr->bGMTagOn = true; plr->m_isGmInvisible = true; plr->m_invisible = true; if(CanUseCommand('z')) { plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_DEVELOPER); plr->triggerpass_cheat = true; // Enable for admins automatically. } else plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_GM); } // Make sure our name exists (for premade system) PlayerInfo * info = objmgr.GetPlayerInfo(plr->GetLowGUID()); if(info == NULL) { info = new PlayerInfo; memset(info, 0, sizeof(PlayerInfo)); info->cl = plr->getClass(); info->gender = plr->getGender(); info->guid = plr->GetLowGUID(); info->name = strdup(plr->GetName()); info->lastLevel = plr->getLevel(); info->lastOnline = UNIXTIME; info->lastZone = plr->GetZoneId(); info->race = plr->getRace(); info->team = plr->GetTeam(); objmgr.AddPlayerInfo(info); } plr->m_playerInfo = info; if(plr->m_playerInfo->guild) { plr->m_uint32Values[PLAYER_GUILDID] = plr->m_playerInfo->guild->GetGuildId(); plr->m_uint32Values[PLAYER_GUILDRANK] = plr->m_playerInfo->guildRank->iId; } for(uint32 z = 0; z < NUM_ARENA_TEAM_TYPES; ++z) { if(plr->m_playerInfo->arenaTeam[z] != NULL) { plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*6), plr->m_playerInfo->arenaTeam[z]->m_id); if(plr->m_playerInfo->arenaTeam[z]->m_leader == plr->GetLowGUID()) plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*6) + 1, 0); else plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*6) + 1, 1); } } info->m_loggedInPlayer = plr; // account data == UI config if(sWorld.m_useAccountData) { WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4+1+4+8*4); MD5Hash md5hash; data << uint32(UNIXTIME) << uint8(1) << uint32(0xEA); for (int i = 0; i < 8; i++) { AccountDataEntry* acct_data = GetAccountData(i); if(0xEA & (1 << i)) data << uint32(acct_data->Time); md5hash.Initialize(); md5hash.UpdateData((const uint8*)acct_data->data, acct_data->sz); md5hash.Finalize(); } SendPacket(&data); } else { WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4+1+4+8*4); MD5Hash md5hash; data << uint32(UNIXTIME) << uint8(1) << uint32(0xEA); for (int i = 0; i < 8; i++) { if(0xEA & (1 << i)) data << uint32(0); AccountDataEntry* acct_data = GetAccountData(i); if(acct_data) { md5hash.Initialize(); md5hash.UpdateData((const uint8*)acct_data->data, acct_data->sz); md5hash.Finalize(); } } SendPacket(&data); } // Set TIME OF LOGIN CharacterDatabase.Execute ("UPDATE characters SET online = 1 WHERE guid = %u" , plr->GetLowGUID()); bool enter_world = true; #ifndef CLUSTERING // Find our transporter and add us if we're on one. if(plr->m_TransporterGUID != 0) { Transporter* pTrans = objmgr.GetTransporter(GUID_LOPART(plr->m_TransporterGUID)); if(pTrans) { if(plr->isDead()) { plr->RemoteRevive(); } float c_tposx = pTrans->GetPositionX() + plr->m_transportPosition->x; float c_tposy = pTrans->GetPositionY() + plr->m_transportPosition->y; float c_tposz = pTrans->GetPositionZ() + plr->m_transportPosition->z; if(plr->GetMapId() != pTrans->GetMapId()) // loaded wrong map { plr->SetMapId(pTrans->GetMapId()); WorldPacket dataw(SMSG_NEW_WORLD, 20); dataw << pTrans->GetMapId() << c_tposx << c_tposy << c_tposz << plr->GetOrientation(); SendPacket(&dataw); // shit is sent in worldport ack. enter_world = false; } plr->SetPosition(c_tposx, c_tposy, c_tposz, plr->GetOrientation(), false); plr->m_CurrentTransporter = pTrans; pTrans->AddPlayer(plr); } } #endif if(plr->GetVehicle()) plr->GetVehicle()->RemovePassenger(plr); DEBUG_LOG( "WorldSession","Player %s logged in.", plr->GetName()); if(plr->GetTeam() == 1) sWorld.HordePlayers++; else sWorld.AlliancePlayers++; if(sWorld.SendMovieOnJoin && plr->m_FirstLogin && !HasGMPermissions()) plr->SendCinematic(plr->myRace->cinematic_id); DEBUG_LOG( "WorldSession","Created new player for existing players (%s)", plr->GetName() ); // Login time, will be used for played time calc plr->m_playedtime[2] = (uint32)UNIXTIME; //Issue a message telling all guild members that this player has signed on if(plr->IsInGuild()) { Guild *pGuild = plr->m_playerInfo->guild; if(pGuild) { WorldPacket data(SMSG_GUILD_EVENT, 50); data << uint8(GUILD_EVENT_MOTD); data << uint8(0x01); if(pGuild->GetMOTD()) data << pGuild->GetMOTD(); else data << uint8(0); SendPacket(&data); pGuild->LogGuildEvent(GUILD_EVENT_HASCOMEONLINE, 1, plr->GetName()); } } // Send online status to people having this char in friendlist (excluding GM's) if(!HasGMPermissions()) plr->Social_TellFriendsOnline(); // send friend list (for ignores) plr->Social_SendFriendList(7); // Send revision plr->BroadcastMessage("%sServer:|r%s Sandshroud Hearthstone|r %s r%u-%s-%s", MSG_COLOR_GOLD, MSG_COLOR_ORANGEY, MSG_COLOR_TORQUISEBLUE, BUILD_REVISION, ARCH, CONFIG); plr->BroadcastMessage("%sPlease report all bugs to |r%shttp://mantis.sandshroud.org|r", MSG_COLOR_GOLD, MSG_COLOR_TORQUISEBLUE); plr->BroadcastMessage("%sOnline Players:|r%s %u |r%sPeak:|r%s %u |r%sAccepted Connections:|r%s %u |r", MSG_COLOR_GOLD, MSG_COLOR_TORQUISEBLUE, sWorld.GetSessionCount(), MSG_COLOR_GOLD, MSG_COLOR_TORQUISEBLUE, sWorld.PeakSessionCount, MSG_COLOR_GOLD, MSG_COLOR_TORQUISEBLUE, sWorld.mAcceptedConnections); plr->BroadcastMessage("%sServer Uptime:|r%s %s|r", MSG_COLOR_GOLD, MSG_COLOR_TORQUISEBLUE, sWorld.GetUptimeString().c_str()); // send to gms if(HasGMPermissions()) sWorld.SendMessageToGMs(this, "%s%s %s (%s) is now online.|r", MSG_COLOR_GOLD, CanUseCommand('z') ? "Admin" : "GameMaster", plr->GetName(), GetAccountNameS(), GetPermissions()); // Send first line of MOTD WorldPacket datat(SMSG_MOTD, 10); datat << uint32(0x04); datat << sWorld.GetMotd(); SendPacket(&datat); // Send second line of MOTD WorldPacket datat2(SMSG_MOTD, 10); datat2 << uint32(0x04); datat2 << sWorld.GetMotd2(); SendPacket(&datat2); //Set current RestState if( plr->m_isResting) // We are in a resting zone, turn on Zzz plr->ApplyPlayerRestState(true); //Check if there is a time difference between lastlogoff and now if( plr->m_timeLogoff > 0 && plr->GetUInt32Value(UNIT_FIELD_LEVEL) < plr->GetUInt32Value(PLAYER_FIELD_MAX_LEVEL)) // if timelogoff = 0 then it's the first login { uint32 currenttime = (uint32)UNIXTIME; uint32 timediff = currenttime - plr->m_timeLogoff; //Calculate rest bonus if( timediff > 0 ) plr->AddCalculatedRestXP(timediff); } sHookInterface.OnFullLogin(plr); if(info->m_Group) info->m_Group->Update(); if(!sWorld.m_blockgmachievements || !HasGMPermissions()) { // Retroactive: Level achievement plr->GetAchievementInterface()->HandleAchievementCriteriaLevelUp( plr->getLevel() ); // Send achievement data! if( plr->GetAchievementInterface()->HasAchievements() ) { WorldPacket * data = plr->GetAchievementInterface()->BuildAchievementData(); plr->CopyAndSendDelayedPacket(data); delete data; } } if(enter_world && !plr->GetMapMgr()) plr->AddToWorld(true); sTracker.CheckPlayerForTracker(plr, true); // If we have the talent, it returns anyway, so just call the function. plr->ResetTitansGrip(); if(plr->GetItemInterface()) plr->GetItemInterface()->CheckAreaItems(); objmgr.AddPlayer(plr); }
void WorldSession::HandleAttackSwingOpcode( WorldPacket & recv_data ) { CHECK_INWORLD_RETURN; CHECK_PACKET_SIZE(recv_data, 8); uint64 guid; recv_data >> guid; if(!guid) { // does this mean cancel combat? HandleAttackStopOpcode(recv_data); return; } // AttackSwing DEBUG_LOG( "WORLD"," Recvd CMSG_ATTACKSWING Message" ); if(GetPlayer()->IsPacified() || GetPlayer()->IsStunned() || GetPlayer()->IsFeared()) return; // printf("Got ATTACK SWING: %08X %08X\n", GUID_HIPART(guid), GUID_LOPART(guid)); Unit* pEnemy = _player->GetMapMgr()->GetUnit(guid); //printf("Pointer: %08X\n", pEnemy); if(!pEnemy) { OUT_DEBUG("WORLD: "I64FMT" does not exist.", guid); return; } if(pEnemy->isDead() || _player->isDead()) // haxors :( return; // Faction "Hack" by Deathshit // Implemented Hackfix for quest 1640 if(sWorld.antihack_cheatengine) { if(!HasGMPermissions() || !sWorld.no_antihack_on_gm) { if(pEnemy->GetEntry() == 6090 && _player->HasQuest(1640)) { GetPlayer()->smsg_AttackStart(pEnemy); GetPlayer()->EventAttackStart(); return; } int attackablestatus = intisAttackable( GetPlayer(), pEnemy, false ); if((attackablestatus < 1) && !pEnemy->IsInRangeOppFactSet(_player) && !pEnemy->CombatStatus.DidDamageTo(_player->GetGUID())) { if(attackablestatus == -1) return; sWorld.LogCheater(this, "Faction exploit detected. Damagetype: Melee."); GetPlayer()->BroadcastMessage("Faction exploit detected. You will be disconnected in 5 seconds."); GetPlayer()->Kick(5000); return; } } } GetPlayer()->smsg_AttackStart(pEnemy); GetPlayer()->EventAttackStart(); }
void WorldSession::FullLogin(Player* plr) { DEBUG_LOG("WorldSession", "Fully loading player %u", plr->GetLowGUID()); SetPlayer(plr); m_MoverWoWGuid.Init(plr->GetGUID()); // copy to movement array plr->movement_packet[0] = m_MoverWoWGuid.GetNewGuidMask(); memcpy(&plr->movement_packet[1], m_MoverWoWGuid.GetNewGuid(), m_MoverWoWGuid.GetNewGuidLen()); WorldPacket datab(MSG_SET_DUNGEON_DIFFICULTY, 20); datab << plr->iInstanceType; datab << uint32(0x01); datab << uint32(0x00); SendPacket(&datab); WorldPacket datac(MSG_SET_RAID_DIFFICULTY, 20); datac << plr->iRaidType; datac << uint32(0x01); datac << uint32(0x00); SendPacket(&datac); // Send first line of MOTD WorldPacket datat(SMSG_MOTD, sizeof(sWorld.GetMotd()) + 4); datat << uint32(0x04); datat << sWorld.GetMotd(); SendPacket(&datat); /* world preload */ packetSMSG_LOGIN_VERIFY_WORLD vwpck; vwpck.MapId = plr->GetMapId(); vwpck.O = plr->GetOrientation(); vwpck.X = plr->GetPositionX(); vwpck.Y = plr->GetPositionY(); vwpck.Z = plr->GetPositionZ(); OutPacket( SMSG_LOGIN_VERIFY_WORLD, sizeof(packetSMSG_LOGIN_VERIFY_WORLD), &vwpck ); ////////////////////////////////////////////////////////////////////////////////////////////////////// // send voicechat state - active/inactive // // {SERVER} Packet: (0x03C7) UNKNOWN PacketSize = 2 // |------------------------------------------------|----------------| // |00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF| // |------------------------------------------------|----------------| // |02 01 |.. | // ------------------------------------------------------------------- // // // Old packetdump is OLD. This is probably from 2.2.0 (that was the patch when it was added to wow)! // ////////////////////////////////////////////////////////////////////////////////////////////////////// plr->UpdateAttackSpeed(); // Make sure our name exists (for premade system) PlayerInfo * info = objmgr.GetPlayerInfo(plr->GetLowGUID()); if(info == NULL) { info = new PlayerInfo; memset(info, 0, sizeof(PlayerInfo)); info->cl = plr->getClass(); info->gender = plr->getGender(); info->guid = plr->GetLowGUID(); info->name = strdup(plr->GetName()); info->lastLevel = plr->getLevel(); info->lastOnline = UNIXTIME; info->lastZone = plr->GetZoneId(); info->race = plr->getRace(); info->team = plr->GetTeam(); objmgr.AddPlayerInfo(info); } plr->m_playerInfo = info; if(plr->m_playerInfo->guild) { plr->m_uint32Values[PLAYER_GUILDID] = plr->m_playerInfo->guild->GetGuildId(); plr->m_uint32Values[PLAYER_GUILDRANK] = plr->m_playerInfo->guildRank->iId; } for(uint32 z = 0; z < NUM_ARENA_TEAM_TYPES; ++z) { if(_player->m_playerInfo->arenaTeam[z] != NULL) { _player->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*7), _player->m_playerInfo->arenaTeam[z]->m_id); if(_player->m_playerInfo->arenaTeam[z]->m_leader == _player->GetLowGUID()) _player->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*7) + 1, 0); else _player->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*7) + 1, 1); } } info->m_loggedInPlayer = plr; // account data == UI config if(sWorld.m_useAccountData) { WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4+1+4+8*4); MD5Hash md5hash; data << uint32(UNIXTIME) << uint8(1) << uint32(0xEA); for (int i = 0; i < 8; i++) { AccountDataEntry* acct_data = GetAccountData(i); if(0xEA & (1 << i)) data << uint32(acct_data->Time); md5hash.Initialize(); md5hash.UpdateData((const uint8*)acct_data->data, acct_data->sz); md5hash.Finalize(); } SendPacket(&data); } else { WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4+1+4+8*4); MD5Hash md5hash; data << uint32(UNIXTIME) << uint8(1) << uint32(0xEA); for (int i = 0; i < 8; i++) { if(0xEA & (1 << i)) data << uint32(0); AccountDataEntry* acct_data = GetAccountData(i); if(acct_data) { md5hash.Initialize(); md5hash.UpdateData((const uint8*)acct_data->data, acct_data->sz); md5hash.Finalize(); } } SendPacket(&data); } // Set TIME OF LOGIN CharacterDatabase.Execute("UPDATE characters SET online = 1 WHERE guid = %u" , plr->GetLowGUID()); _player->ResetTitansGrip(); bool enter_world = true; #ifndef CLUSTERING // Find our transporter and add us if we're on one. if(plr->m_TransporterGUID != 0) { Transporter* pTrans = objmgr.GetTransporter(GUID_LOPART(plr->m_TransporterGUID)); if(pTrans) { if(plr->isDead()) { plr->RemoteRevive(); } float c_tposx = pTrans->GetPositionX() + plr->m_transportPosition->x; float c_tposy = pTrans->GetPositionY() + plr->m_transportPosition->y; float c_tposz = pTrans->GetPositionZ() + plr->m_transportPosition->z; if(plr->GetMapId() != pTrans->GetMapId()) // loaded wrong map { plr->SetMapId(pTrans->GetMapId()); WorldPacket dataw(SMSG_NEW_WORLD, 20); dataw << pTrans->GetMapId() << c_tposx << c_tposy << c_tposz << plr->GetOrientation(); SendPacket(&dataw); // shit is sent in worldport ack. enter_world = false; } plr->SetPosition(c_tposx, c_tposy, c_tposz, plr->GetOrientation(), false); plr->m_CurrentTransporter = pTrans; pTrans->AddPlayer(plr); } } #endif if(plr->m_CurrentVehicle) plr->m_CurrentVehicle->RemovePassenger(plr); DEBUG_LOG( "WorldSession","Player %s logged in.", plr->GetName()); if(plr->GetTeam() == 1) sWorld.HordePlayers++; else sWorld.AlliancePlayers++; if(plr->m_FirstLogin && !HasGMPermissions()) OutPacket(SMSG_TRIGGER_CINEMATIC, 4, &plr->myRace->cinematic_id); DEBUG_LOG( "WorldSession","Created new player for existing players (%s)", plr->GetName() ); // Login time, will be used for played time calc plr->m_playedtime[2] = uint32(UNIXTIME); //Issue a message telling all guild members that this player has signed on if(plr->IsInGuild()) { Guild *pGuild = plr->m_playerInfo->guild; if(pGuild) { WorldPacket data(50); data.Initialize(SMSG_GUILD_EVENT); data << uint8(GUILD_EVENT_MOTD); data << uint8(0x01); if(pGuild->GetMOTD()) data << pGuild->GetMOTD(); else data << uint8(0); SendPacket(&data); pGuild->LogGuildEvent(GUILD_EVENT_HASCOMEONLINE, 1, plr->GetName()); } } // Send online status to people having this char in friendlist (excluding GM's) if(!HasGMPermissions()) _player->Social_TellFriendsOnline(); // send friend list (for ignores) _player->Social_SendFriendList(7); // Send revision (if enabled) #ifdef WIN32 // _player->BroadcastMessage("Core server: ArcEmu %s r%u/%s-Windows-%s (www.github.com/ArcEmudev)", MSG_COLOR_WHITE, BUILD_TAG, BUILD_REVISION, CONFIG, ARCH, MSG_COLOR_LIGHTBLUE); #else // _player->BroadcastMessage("Core server: ArcEmu %s r%u/%s-%s (www.github.com/ArcEmudev)", MSG_COLOR_WHITE, BUILD_TAG, BUILD_REVISION, PLATFORM_TEXT, ARCH, MSG_COLOR_LIGHTBLUE); #endif // Bugs _player->BroadcastMessage("Bugs: %s%s", MSG_COLOR_LIGHTBLUE, BUG_TRACKER); if(sWorld.SendStatsOnJoin) { _player->BroadcastMessage("Online Players: %s%u |rPeak: %s%u|r Accepted Connections: %s%u", MSG_COLOR_WHITE, sWorld.GetSessionCount(), MSG_COLOR_WHITE, sWorld.PeakSessionCount, MSG_COLOR_WHITE, sWorld.mAcceptedConnections); _player->BroadcastMessage("Server Uptime: |r%s", sWorld.GetUptimeString().c_str()); } // send to gms if(HasGMPermissions()) sWorld.SendMessageToGMs(this, "%s %s (%s) is now online.", CanUseCommand('z') ? "Admin" : "GameMaster", _player->GetName(), GetAccountNameS(), GetPermissions()); //Set current RestState if( plr->m_isResting) // We are in a resting zone, turn on Zzz plr->ApplyPlayerRestState(true); //Check if there is a time difference between lastlogoff and now if( plr->m_timeLogoff > 0 && plr->GetUInt32Value(UNIT_FIELD_LEVEL) < plr->GetUInt32Value(PLAYER_FIELD_MAX_LEVEL)) // if timelogoff = 0 then it's the first login { uint32 currenttime = (uint32)UNIXTIME; uint32 timediff = currenttime - plr->m_timeLogoff; //Calculate rest bonus if( timediff > 0 ) plr->AddCalculatedRestXP(timediff); } sHookInterface.OnEnterWorld2(_player); if(info->m_Group) info->m_Group->Update(); // Retroactive: Level achievement if(plr->getLevel() > 10 && !GetPermissions()) { // Retroactive: Level achievement _player->GetAchievementInterface()->HandleAchievementCriteriaLevelUp( _player->getLevel() ); // Send achievement data! if( _player->GetAchievementInterface()->HasAchievements() ) { WorldPacket * data = _player->GetAchievementInterface()->BuildAchievementData(); _player->CopyAndSendDelayedPacket(data); delete data; } } if(enter_world && !_player->GetMapMgr()) plr->AddToWorld(); objmgr.AddPlayer(_player); }
void WorldSession::HandleSendMail(WorldPacket& recv_data) { CHECK_INWORLD_RETURN MailMessage msg; uint64 gameobject; uint32 unk2; uint8 itemcount; uint8 itemslot; uint8 i; uint64 itemguid; std::vector< Item* > items; std::vector< Item* >::iterator itr; std::string recepient; Item* pItem; //uint32 err = MAIL_OK; recv_data >> gameobject >> recepient; recv_data >> msg.subject >> msg.body >> msg.stationery; recv_data >> unk2 >> itemcount; if (itemcount > MAIL_MAX_ITEM_SLOT || msg.body.find("%") != std::string::npos || msg.subject.find("%") != std::string::npos) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } // Search for the recipient PlayerInfo* player = ObjectMgr::getSingleton().GetPlayerInfoByName(recepient.c_str()); if (player == NULL) { SendMailError(MAIL_ERR_RECIPIENT_NOT_FOUND); return; } for (i = 0; i < itemcount; ++i) { recv_data >> itemslot; recv_data >> itemguid; pItem = _player->GetItemInterface()->GetItemByGUID(itemguid); if (pItem == NULL || pItem->IsSoulbound() || pItem->IsConjured()) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } if (pItem->IsAccountbound() && GetAccountId() != player->acct) // don't mail account-bound items to another account { WorldPacket data(SMSG_SEND_MAIL_RESULT, 16); data << uint32(0); data << uint32(0); data << uint32(MAIL_ERR_BAG_FULL); data << uint32(INV_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS); SendPacket(&data); return; } items.push_back(pItem); } recv_data >> msg.money; recv_data >> msg.cod; ///\todo left over: (TODO- FIX ME BURLEX!) // uint32 // uint32 // uint8 bool interfaction = false; if (sMailSystem.MailOption(MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION) || (HasGMPermissions() && sMailSystem.MailOption(MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION_GM))) { interfaction = true; } // Check we're sending to the same faction (disable this for testing) if (player->team != _player->GetTeam() && !interfaction) { SendMailError(MAIL_ERR_NOT_YOUR_ALLIANCE); return; } // Check if we're sending mail to ourselves if (strcmp(player->name, _player->GetName()) == 0 && !GetPermissionCount()) { SendMailError(MAIL_ERR_CANNOT_SEND_TO_SELF); return; } if (msg.stationery == MAIL_STATIONERY_GM && !HasGMPermissions()) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } // Instant delivery time by default. msg.delivery_time = (uint32)UNIXTIME; // Set up the cost int32 cost = 0; // Check for attached money if (msg.money > 0) cost += msg.money; if (!sMailSystem.MailOption(MAIL_FLAG_DISABLE_POSTAGE_COSTS) && !(GetPermissionCount() && sMailSystem.MailOption(MAIL_FLAG_NO_COST_FOR_GM))) { cost += 30; } // check that we have enough in our backpack if (!_player->HasGold(cost)) { SendMailError(MAIL_ERR_NOT_ENOUGH_MONEY); return; } // Check for the item, and required item. if (!items.empty()) { for (itr = items.begin(); itr != items.end(); ++itr) { pItem = *itr; if (_player->GetItemInterface()->SafeRemoveAndRetreiveItemByGuid(pItem->GetGUID(), false) != pItem) continue; // should never be hit. pItem->RemoveFromWorld(); pItem->SetOwner(NULL); pItem->SaveToDB(INVENTORY_SLOT_NOT_SET, 0, true, NULL); msg.items.push_back(pItem->GetLowGUID()); if (GetPermissionCount() > 0) { /* log the message */ sGMLog.writefromsession(this, "sent mail with item entry %u to %s, with gold %u.", pItem->GetEntry(), player->name, msg.money); } pItem->DeleteMe(); } } if (msg.money != 0 || msg.cod != 0 || (!msg.items.size() && player->acct != _player->GetSession()->GetAccountId())) { if (!sMailSystem.MailOption(MAIL_FLAG_DISABLE_HOUR_DELAY_FOR_ITEMS)) msg.delivery_time += 3600; // 1hr } // take the money _player->ModGold(-cost); // Fill in the rest of the info msg.player_guid = player->guid; msg.sender_guid = _player->GetGUID(); // 30 day expiry time for unread mail if (!sMailSystem.MailOption(MAIL_FLAG_NO_EXPIRY)) msg.expire_time = (uint32)UNIXTIME + (TIME_DAY * MAIL_DEFAULT_EXPIRATION_TIME); else msg.expire_time = 0; msg.deleted_flag = false; msg.message_type = 0; msg.checked_flag = msg.body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY; // Great, all our info is filled in. Now we can add it to the other players mailbox. sMailSystem.DeliverMessage(player->guid, &msg); // Save/Update character's gold if they've received gold that is. This prevents a rollback. CharacterDatabase.Execute("UPDATE characters SET gold = %u WHERE guid = %u", _player->GetGold(), _player->m_playerInfo->guid); // Success packet :) SendMailError(MAIL_OK); }
void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) { if(!_player->IsInWorld() || _player->m_uint32Values[UNIT_FIELD_CHARMEDBY] || _player->GetPlayerStatus() == TRANSFER_PENDING || _player->GetTaxiState()) return; // spell cancel on movement, for now only fishing is added Object * t_go = _player->m_SummonedObject; uint32 mstime_s; if (t_go) { if (t_go->GetEntry() == GO_FISHING_BOBBER) ((GameObject*)t_go)->EndFishing(GetPlayer(),true); } /************************************************************************/ /* Make sure the packet is the correct size range. */ /************************************************************************/ if(recv_data.size() > 80) { Disconnect(); return; } /************************************************************************/ /* Read Movement Data Packet */ /************************************************************************/ movement_info.init(recv_data); /************************************************************************/ /* Update player movement state */ /************************************************************************/ if( recv_data.GetOpcode() == MSG_MOVE_STOP || recv_data.GetOpcode() == MSG_MOVE_STOP_STRAFE || recv_data.GetOpcode() == MSG_MOVE_STOP_TURN || recv_data.GetOpcode() == MSG_MOVE_FALL_LAND || ( recv_data.GetOpcode() == MSG_MOVE_SET_FACING && !(movement_info.flags & MOVEFLAG_MOVING_MASK) ) ) { if( _player->m_isMoving ) { #ifdef _DEBUG // printf("MOVING: FALSE (Packet %s)\n", LookupName( recv_data.GetOpcode(), g_worldOpcodeNames ) ); #endif mstime_s = getMSTime(); _player->_SpeedhackCheck(mstime_s); _player->m_isMoving = false; _player->_startMoveTime = 0; } } else { if( !_player->m_isMoving ) { #ifdef _DEBUG // printf("MOVING: TRUE (Packet %s)\n", LookupName( recv_data.GetOpcode(), g_worldOpcodeNames ) ); #endif mstime_s = getMSTime(); _player->m_isMoving = true; _player->_startMoveTime = mstime_s; _player->_lastHeartbeatPosition = _player->GetPosition(); } } /************************************************************************/ /* Remove Emote State */ /************************************************************************/ if(_player->m_uint32Values[UNIT_NPC_EMOTESTATE]) _player->SetUInt32Value(UNIT_NPC_EMOTESTATE,0); /************************************************************************/ /* Make sure the co-ordinates are valid. */ /************************************************************************/ if( !((movement_info.y >= _minY) && (movement_info.y <= _maxY)) || !((movement_info.x >= _minX) && (movement_info.x <= _maxX)) ) { Disconnect(); return; } /************************************************************************/ /* Dump movement flags - Wheee! */ /************************************************************************/ #if 0 printf("=========================================================\n"); printf("Full movement flags: 0x%.8X\n", movement_info.flags); uint32 z, b; for(z = 1, b = 1; b < 32;) { if(movement_info.flags & z) printf(" Bit %u (0x%.8X or %u) is set!\n", b, z, z); z <<= 1; b+=1; } printf("=========================================================\n"); #endif /************************************************************************/ /* Orientation dumping */ /************************************************************************/ #if 0 printf("Packet: 0x%03X (%s)\n", recv_data.GetOpcode(), LookupName( recv_data.GetOpcode(), g_worldOpcodeNames ) ); printf("Orientation: %.10f\n", movement_info.orientation); #endif /************************************************************************/ /* Anti-Hack Checks */ /************************************************************************/ if( !(HasGMPermissions() && sWorld.no_antihack_on_gm) && !_player->m_uint32Values[UNIT_FIELD_CHARM] && !_player->_heartbeatDisable) { /************************************************************************/ /* Anti-Teleport */ /************************************************************************/ if(sWorld.antihack_teleport && _player->m_position.Distance2DSq(movement_info.x, movement_info.y) > 5625.0f && _player->m_runSpeed < 50.0f && !_player->m_TransporterGUID) { sCheatLog.writefromsession(this, "Used teleport hack {3}, speed was %f", _player->m_runSpeed); Disconnect(); return; } } /************************************************************************/ /* Calculate the timestamp of the packet we have to send out */ /************************************************************************/ size_t pos = (size_t)m_MoverWoWGuid.GetNewGuidLen() + 1; uint32 mstime = mTimeStamp(); int32 move_time; if(m_clientTimeDelay == 0) m_clientTimeDelay = mstime - movement_info.time; /************************************************************************/ /* Copy into the output buffer. */ /************************************************************************/ if(_player->m_inRangePlayers.size()) { move_time = (movement_info.time - (mstime - m_clientTimeDelay)) + MOVEMENT_PACKET_TIME_DELAY + mstime; memcpy(&movement_packet[pos], recv_data.contents(), recv_data.size()); movement_packet[pos+5]=0; /************************************************************************/ /* Distribute to all inrange players. */ /************************************************************************/ for(set<Player*>::iterator itr = _player->m_inRangePlayers.begin(); itr != _player->m_inRangePlayers.end(); ++itr) { #ifdef USING_BIG_ENDIAN *(uint32*)&movement_packet[pos+5] = swap32(move_time + (*itr)->GetSession()->m_moveDelayTime); #else *(uint32*)&movement_packet[pos+5] = uint32(move_time + (*itr)->GetSession()->m_moveDelayTime); #endif #if defined(ENABLE_COMPRESSED_MOVEMENT) && defined(ENABLE_COMPRESSED_MOVEMENT_FOR_PLAYERS) if( _player->GetPositionNC().Distance2DSq((*itr)->GetPosition()) >= World::m_movementCompressThreshold ) (*itr)->AppendMovementData( recv_data.GetOpcode(), uint16(recv_data.size() + pos), movement_packet ); else (*itr)->GetSession()->OutPacket(recv_data.GetOpcode(), uint16(recv_data.size() + pos), movement_packet); #else (*itr)->GetSession()->OutPacket(recv_data.GetOpcode(), uint16(recv_data.size() + pos), movement_packet); #endif } } /************************************************************************/ /* Falling damage checks */ /************************************************************************/ if( _player->blinked ) { _player->blinked = false; _player->m_fallDisabledUntil = UNIXTIME + 5; _player->DelaySpeedHack( 5000 ); } else { if( recv_data.GetOpcode() == MSG_MOVE_FALL_LAND ) { // player has finished falling //if _player->z_axisposition contains no data then set to current position if( !_player->z_axisposition ) _player->z_axisposition = movement_info.z; // calculate distance fallen uint32 falldistance = float2int32( _player->z_axisposition - movement_info.z ); /*if player is a rogue or druid(in cat form), then apply -17 modifier to fall distance. these checks need improving, low level rogue/druid should not receive this benefit*/ if( ( _player->getClass() == ROGUE ) || ( _player->GetShapeShift() == FORM_CAT ) ) { if( falldistance > 17 ) falldistance -=17; else falldistance = 1; } //checks that player has fallen more than 12 units, otherwise no damage will be dealt //falltime check is also needed here, otherwise sudden changes in Z axis position, such as using !recall, may result in death if( _player->isAlive() && !_player->GodModeCheat && falldistance > 12 && ( UNIXTIME >= _player->m_fallDisabledUntil ) && movement_info.FallTime > 1000 ) { // 1.7% damage for each unit fallen on Z axis over 13 uint32 health_loss = float2int32( float( _player->GetUInt32Value( UNIT_FIELD_MAXHEALTH ) * ( ( falldistance - 12 ) * 0.017 ) ) ); if( health_loss >= _player->GetUInt32Value( UNIT_FIELD_HEALTH ) ) health_loss = _player->GetUInt32Value( UNIT_FIELD_HEALTH ); _player->SendEnvironmentalDamageLog( _player->GetGUID(), DAMAGE_FALL, health_loss ); _player->DealDamage( _player, health_loss, 0, 0, 0 ); _player->RemoveStealth(); // Fall Damage will cause stealthed units to lose stealth. } _player->z_axisposition = 0.0f; } else //whilst player is not falling, continuosly update Z axis position. //once player lands this will be used to determine how far he fell. if( !( movement_info.flags & MOVEFLAG_FALLING ) ) _player->z_axisposition = movement_info.z; } /************************************************************************/ /* Transporter Setup */ /************************************************************************/ if(!_player->m_lockTransportVariables) { if(_player->m_TransporterGUID && !movement_info.transGuid) { /* we left the transporter we were on */ if(_player->m_CurrentTransporter) { _player->m_CurrentTransporter->RemovePlayer(_player); _player->m_CurrentTransporter = NULL; } _player->m_TransporterGUID = 0; _player->ResetHeartbeatCoords(); } else if(movement_info.transGuid) { if(!_player->m_TransporterGUID) { /* just walked into a transport */ if(_player->IsMounted()) _player->RemoveAura(_player->m_MountSpellId); _player->m_CurrentTransporter = objmgr.GetTransporter(GUID_LOPART(movement_info.transGuid)); if(_player->m_CurrentTransporter) _player->m_CurrentTransporter->AddPlayer(_player); /* set variables */ _player->m_TransporterGUID = movement_info.transGuid; _player->m_TransporterUnk = movement_info.transUnk; _player->m_TransporterX = movement_info.transX; _player->m_TransporterY = movement_info.transY; _player->m_TransporterZ = movement_info.transZ; } else { /* no changes */ _player->m_TransporterUnk = movement_info.transUnk; _player->m_TransporterX = movement_info.transX; _player->m_TransporterY = movement_info.transY; _player->m_TransporterZ = movement_info.transZ; } } /*float x = movement_info.x - movement_info.transX; float y = movement_info.y - movement_info.transY; float z = movement_info.z - movement_info.transZ; Transporter* trans = _player->m_CurrentTransporter; if(trans) sChatHandler.SystemMessageToPlr(_player, "Client t pos: %f %f\nServer t pos: %f %f Diff: %f %f", x,y, trans->GetPositionX(), trans->GetPositionY(), trans->CalcDistance(x,y,z), trans->CalcDistance(movement_info.x, movement_info.y, movement_info.z));*/ } /************************************************************************/ /* Anti-Speed Hack Checks */ /************************************************************************/ /************************************************************************/ /* Breathing System */ /************************************************************************/ _HandleBreathing(movement_info, _player, this); /************************************************************************/ /* Remove Spells */ /************************************************************************/ _player->RemoveAurasByInterruptFlag(AURA_INTERRUPT_ON_MOVEMENT); /************************************************************************/ /* Update our position in the server. */ /************************************************************************/ if( _player->m_CurrentCharm ) _player->m_CurrentCharm->SetPosition(movement_info.x, movement_info.y, movement_info.z, movement_info.orientation); else { if(!_player->m_CurrentTransporter) { if( !_player->SetPosition(movement_info.x, movement_info.y, movement_info.z, movement_info.orientation) ) { _player->SetUInt32Value(UNIT_FIELD_HEALTH, 0); _player->KillPlayer(); } } else { _player->SetPosition(movement_info.x, movement_info.y, movement_info.z, movement_info.orientation + movement_info.transO, false); } } }
void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data, 10); std::string name; uint8 race, class_; recv_data >> name >> race >> class_; recv_data.rpos(0); if(!VerifyName(name.c_str(), name.length())) { OutPacket(SMSG_CHAR_CREATE, 1, "\x32"); return; } if(g_characterNameFilter->Parse(name, false)) { OutPacket(SMSG_CHAR_CREATE, 1, "\x32"); return; } if(objmgr.GetPlayerInfoByName(name.c_str()) != 0) { OutPacket(SMSG_CHAR_CREATE, 1, "\x32"); return; } if(!sHookInterface.OnNewCharacter(race, class_, this, name.c_str())) { OutPacket(SMSG_CHAR_CREATE, 1, "\x32"); return; } QueryResult * result = CharacterDatabase.Query("SELECT COUNT(*) FROM banned_names WHERE name = '%s'", CharacterDatabase.EscapeString(name).c_str()); if(result) { if(result->Fetch()[0].GetUInt32() > 0) { // That name is banned! OutPacket(SMSG_CHAR_CREATE, 1, "\x51"); // You cannot use that name delete result; return; } delete result; } // loading characters //checking number of chars is useless since client will not allow to create more than 10 chars //as the 'create' button will not appear (unless we want to decrease maximum number of characters) Player * pNewChar = objmgr.CreatePlayer(); pNewChar->SetSession(this); if(!pNewChar->Create( recv_data )) { // failed. pNewChar->ok_to_remove = true; delete pNewChar; return; } //Same Faction limitation only applies to PVP and RPPVP realms :) uint32 realmType = sLogonCommHandler.GetRealmType(); if( !HasGMPermissions() && realmType == REALM_PVP && _side < 0 ) { if( ((pNewChar->GetTeam()== 0) && (_side == 1)) || ((pNewChar->GetTeam()== 1) && (_side == 0)) ) { pNewChar->ok_to_remove = true; delete pNewChar; WorldPacket data(1); data.SetOpcode(SMSG_CHAR_CREATE); data << (uint8)ALL_CHARS_ON_PVP_REALM_MUST_AT_SAME_SIDE+1; SendPacket( &data ); return; } } pNewChar->UnSetBanned(); pNewChar->addSpell(22027); // Remove Insignia if(pNewChar->getClass() == WARLOCK) { pNewChar->AddSummonSpell(416, 3110); // imp fireball pNewChar->AddSummonSpell(417, 19505); pNewChar->AddSummonSpell(1860, 3716); pNewChar->AddSummonSpell(1863, 7814); } pNewChar->SaveToDB(true); PlayerInfo *pn=new PlayerInfo ; pn->guid = pNewChar->GetLowGUID(); pn->name = strdup(pNewChar->GetName()); pn->cl = pNewChar->getClass(); pn->race = pNewChar->getRace(); pn->gender = pNewChar->getGender(); pn->m_Group=0; pn->subGroup=0; pn->m_loggedInPlayer=NULL; pn->team = pNewChar->GetTeam (); pn->guild=NULL; pn->guildRank=NULL; pn->guildMember=NULL; #ifdef VOICE_CHAT pn->groupVoiceId = -1; #endif objmgr.AddPlayerInfo(pn); pNewChar->ok_to_remove = true; delete pNewChar; // CHAR_CREATE_SUCCESS OutPacket(SMSG_CHAR_CREATE, 1, "\x2F"); sLogonCommHandler.UpdateAccountCount(GetAccountId(), 1); }
void WorldSession::FullLogin(Player* plr) { Log.Debug("WorldSession", "Fully loading player %u", plr->GetLowGUID()); SetPlayer(plr); m_MoverWoWGuid.Init(plr->GetGUID()); MapMgr* mgr = sInstanceMgr.GetInstance(plr); if (mgr && mgr->m_battleground) { // Don't allow player to login into a bg that has ended or is full if (mgr->m_battleground->HasEnded() || mgr->m_battleground->HasFreeSlots(plr->GetTeamInitial(), mgr->m_battleground->GetType() == false)) mgr = NULL; } // Trying to log to an instance that doesn't exists anymore? if (!mgr) { if (!IS_INSTANCE(plr->m_bgEntryPointMap)) { plr->m_position.x = plr->m_bgEntryPointX; plr->m_position.y = plr->m_bgEntryPointY; plr->m_position.z = plr->m_bgEntryPointZ; plr->m_position.o = plr->m_bgEntryPointO; plr->m_mapId = plr->m_bgEntryPointMap; } else { plr->m_position.x = plr->GetBindPositionX(); plr->m_position.y = plr->GetBindPositionY(); plr->m_position.z = plr->GetBindPositionZ(); plr->m_position.o = 0; plr->m_mapId = plr->GetBindMapId(); } } // copy to movement array movement_packet[0] = m_MoverWoWGuid.GetNewGuidMask(); memcpy(&movement_packet[1], m_MoverWoWGuid.GetNewGuid(), m_MoverWoWGuid.GetNewGuidLen()); // world preload uint32 VMapId; float VO; float VX; float VY; float VZ; // GMs should start on GM Island and be bound there if (HasGMPermissions() && plr->m_FirstLogin && sWorld.gamemaster_startonGMIsland) { VMapId = 1; VO = 0; VX = 16222.6f; VY = 16265.9f; VZ = 14.2085f; plr->m_position.x = VX; plr->m_position.y = VY; plr->m_position.z = VZ; plr->m_position.o = VO; plr->m_mapId = VMapId; plr->SetBindPoint(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), plr->GetMapId(), plr->GetZoneId()); } else { VMapId = plr->GetMapId(); VO = plr->GetOrientation(); VX = plr->GetPositionX(); VY = plr->GetPositionY(); VZ = plr->GetPositionZ(); } plr->SendLoginVerifyWorld(VMapId, VX, VY, VZ, VO); /////////////////////////////////////////////////////////////////////////////////////////////////////// // send voicechat state - active/inactive // // {SERVER} Packet: (0x03C7) UNKNOWN PacketSize = 2 // |------------------------------------------------|----------------| // |00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF| // |------------------------------------------------|----------------| // |02 01 |.. | // ------------------------------------------------------------------- // // // Old packetdump is OLD. This is probably from 2.2.0 (that was the patch when it was added to wow)! // ////////////////////////////////////////////////////////////////////////////////////////////////////// StackWorldPacket<20> datab(SMSG_FEATURE_SYSTEM_STATUS); datab.Initialize(SMSG_FEATURE_SYSTEM_STATUS); datab << uint8(2); datab << uint8(0); SendPacket(&datab); WorldPacket dataldm(SMSG_LEARNED_DANCE_MOVES, 4 + 4); dataldm << uint32(0); dataldm << uint32(0); SendPacket(&dataldm); plr->UpdateAttackSpeed(); // Make sure our name exists (for premade system) PlayerInfo* info = objmgr.GetPlayerInfo(plr->GetLowGUID()); if (!info) { info = new PlayerInfo; info->class_ = plr->getClass(); info->gender = plr->getGender(); info->guid = plr->GetLowGUID(); info->name = strdup(plr->GetName()); info->lastLevel = plr->getLevel(); info->lastOnline = UNIXTIME; info->lastZone = plr->GetZoneId(); info->race = plr->getRace(); info->team = plr->GetTeam(); info->guild = NULL; info->guildRank = NULL; info->guildMember = NULL; info->m_Group = NULL; info->subGroup = 0; objmgr.AddPlayerInfo(info); } plr->m_playerInfo = info; if (plr->m_playerInfo->guild) { plr->SetGuildId(plr->m_playerInfo->guild->GetGuildId()); plr->SetGuildRank(plr->m_playerInfo->guildRank->iId); } info->m_loggedInPlayer = plr; // account data == UI config SendAccountDataTimes(PER_CHARACTER_CACHE_MASK); // Set TIME OF LOGIN CharacterDatabase.Execute("UPDATE characters SET online = 1 WHERE guid = %u", plr->GetLowGUID()); bool enter_world = true; // Find our transporter and add us if we're on one. if (plr->transporter_info.guid) { if (Transporter* pTrans = objmgr.GetTransporter(Arcemu::Util::GUID_LOPART(plr->transporter_info.guid))) { if (plr->IsDead()) { plr->ResurrectPlayer(); plr->SetHealth(plr->GetMaxHealth()); plr->SetPower(POWER_TYPE_MANA, plr->GetMaxPower(POWER_TYPE_MANA)); } float c_tposx = pTrans->GetPositionX() + plr->transporter_info.x; float c_tposy = pTrans->GetPositionY() + plr->transporter_info.y; float c_tposz = pTrans->GetPositionZ() + plr->transporter_info.z; if (plr->GetMapId() != pTrans->GetMapId()) // loaded wrong map { plr->SetMapId(pTrans->GetMapId()); StackWorldPacket<20> dataw(SMSG_NEW_WORLD); dataw << pTrans->GetMapId(); dataw << c_tposx; dataw << c_tposy; dataw << c_tposz; dataw << plr->GetOrientation(); SendPacket(&dataw); // shit is sent in worldport ack. enter_world = false; } plr->SetPosition(c_tposx, c_tposy, c_tposz, plr->GetOrientation(), false); plr->m_CurrentTransporter = pTrans; pTrans->AddPlayer(plr); } } Log.Debug("Login", "Player %s logged in.", plr->GetName()); sWorld.incrementPlayerCount(plr->GetTeam()); if (plr->m_FirstLogin) { if (PlayerCreateInfo* create_info = objmgr.GetPlayerCreateInfo(info->race, info->class_)) { uint32 introid = create_info->introid; OutPacket(SMSG_TRIGGER_CINEMATIC, 4, &introid); } if (sWorld.m_AdditionalFun) //cebernic: tells people who 's newbie :D { const int classtext[] = { 0, 5, 6, 8, 9, 11, 0, 4, 3, 7, 0, 10 }; sWorld.SendLocalizedWorldText(true, "{65}", classtext[(uint32)plr->getClass()], plr->GetName(), (plr->IsTeamHorde() ? "{63}" : "{64}")); } } LOG_DETAIL("WORLD: Created new player for existing players (%s)", plr->GetName()); // Login time, will be used for played time calc plr->m_playedtime[2] = uint32(UNIXTIME); //Issue a message telling all guild members that this player has signed on if (plr->IsInGuild()) { if (Guild* pGuild = plr->m_playerInfo->guild) { WorldPacket data(SMSG_GUILD_EVENT, 50); data << uint8(GUILD_EVENT_MOTD); data << uint8(1); if (pGuild->GetMOTD()) data << pGuild->GetMOTD(); else data << uint8(0); SendPacket(&data); pGuild->LogGuildEvent(GUILD_EVENT_HASCOMEONLINE, 1, plr->GetName()); } } // Send online status to people having this char in friendlist _player->Social_TellFriendsOnline(); // send friend list (for ignores) _player->Social_SendFriendList(7); plr->SendDungeonDifficulty(); plr->SendRaidDifficulty(); plr->SendEquipmentSetList(); #ifndef GM_TICKET_MY_MASTER_COMPATIBLE GM_Ticket* ticket = objmgr.GetGMTicketByPlayer(_player->GetGUID()); if (ticket != NULL) { //Send status change to gm_sync_channel Channel* chn = channelmgr.GetChannel(sWorld.getGmClientChannel().c_str(), _player); if (chn) { std::stringstream ss; ss << "GmTicket:" << GM_TICKET_CHAT_OPCODE_ONLINESTATE; ss << ":" << ticket->guid; ss << ":1"; chn->Say(_player, ss.str().c_str(), NULL, true); } } #endif // server Message Of The Day SendMOTD(); //Set current RestState if (plr->m_isResting) // We are resting at an inn , turn on Zzz plr->ApplyPlayerRestState(true); //Calculate rest bonus if there is time between lastlogoff and now if (plr->m_timeLogoff > 0 && plr->getLevel() < plr->GetMaxLevel()) // if timelogoff = 0 then it's the first login { uint32 currenttime = uint32(UNIXTIME); uint32 timediff = currenttime - plr->m_timeLogoff; //Calculate rest bonus if (timediff > 0) plr->AddCalculatedRestXP(timediff); } if (info->m_Group) info->m_Group->Update(); if (enter_world && !_player->GetMapMgr()) plr->AddToWorld(); sHookInterface.OnFullLogin(_player); objmgr.AddPlayer(_player); }
void WorldSession::HandleInitiateTrade(WorldPacket & recv_data) { if(!_player->IsInWorld()) { return; } #ifdef FORCED_GM_TRAINEE_MODE if( CanUseCommand('k') && !HasGMPermissions() ) { GetPlayer()->BroadcastMessage( "You are not allowed to use this feature" ); return; } #endif if( sWorld.getIntRate( INTRATE_DISABLE_TRADE_FEATURE ) ) { GetPlayer()->BroadcastMessage( "Trade feature is disabled right now" ); return; } // CHECK_PACKET_SIZE(recv_data, 8); // uint64 guid; // recv_data >> guid; uint8 GUID_mask; uint8 GUID_bytes[8]; memset( GUID_bytes, 0, sizeof( GUID_bytes ) ); recv_data >> GUID_mask; if( GUID_mask & BIT_0x01 ) recv_data >> GUID_bytes[2]; if( GUID_mask & BIT_0x02 ) recv_data >> GUID_bytes[1]; if( GUID_mask & BIT_0x40 ) recv_data >> GUID_bytes[3]; if( GUID_mask & BIT_0x04 ) recv_data >> GUID_bytes[0]; uint8 GUID_bytes_obfuscated[8]; *(uint64*)GUID_bytes_obfuscated = *(uint64*)GUID_bytes; GUID_un_obfuscate( GUID_bytes ); Player * pTarget = _player->GetMapMgr()->GetPlayer( *(uint64*)GUID_bytes ); uint32 TradeStatus = TRADE_STATUS_PROPOSED; if(pTarget == 0) { TradeStatus = TRADE_STATUS_PLAYER_NOT_FOUND; OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); return; } // Handle possible error outcomes if(pTarget->CalcDistance(_player) > 10.0f) // This needs to be checked TradeStatus = TRADE_STATUS_TOO_FAR_AWAY; else if(pTarget->IsDead()) TradeStatus = TRADE_STATUS_DEAD; else if(pTarget->mTradeTarget != 0) TradeStatus = TRADE_STATUS_ALREADY_TRADING; else if(pTarget->GetTeam() != _player->GetTeam() && GetPermissionCount() == 0 && !sWorld.interfaction_trade) TradeStatus = TRADE_STATUS_WRONG_FACTION; if(TradeStatus == TRADE_STATUS_PROPOSED) { _player->ResetTradeVariables(); pTarget->ResetTradeVariables(); pTarget->mTradeTarget = _player->GetLowGUID(); _player->mTradeTarget = pTarget->GetLowGUID(); pTarget->mTradeStatus = TradeStatus; _player->mTradeStatus = TradeStatus; } /* 13329 ME {CLIENT} Packet: (0x4106) CMSG_INITIATE_TRADE PacketSize = 8 TimeStamp = 32130418 8A A9 79 02 00 00 00 04 to me {SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32131338 0E 69 2B 33 18 8A A9 79 02 00 00 00 04 03 00 00 00 AB 2A 00 00 90 BC 61 58 AB 01 00 00 00 00 00 00 00 -> trade proposed to him {SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32209838 80 B9 46 42 98 8A A9 79 02 00 00 00 04 90 BC 61 58 AB 2A 00 00 B3 47 A5 00 00 01 00 00 00 AB 2A 00 00 -> trade proposed him {CLIENT} Packet: (0x4107) CMSG_BEGIN_TRADE PacketSize = 0 TimeStamp = 32209854 to me {SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32131338 01 00 00 00 00 10 BD 46 42 00 00 00 00 88 E3 29 0E 00 00 00 00 07 01 00 00 00 02 00 00 00 AB 2A 00 00 -> trade initiated to him {SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32209994 00 00 00 00 AE 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 09 01 00 00 00 02 00 00 00 00 00 00 00 -> trade initiated to me {SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32379442 80 B9 46 42 98 10 BD 46 42 00 00 00 00 00 00 00 00 AA 2A 00 00 10 0A 6C 58 AB 08 00 00 00 00 00 00 00 ->trade complete to him {SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32456725 05 00 00 00 0A 20 B8 46 42 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 04 00 00 00 00 00 00 00 ->trade accepted to him {SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32460750 80 B9 46 42 98 10 BD 46 42 00 00 00 00 00 00 00 00 AA 2A 00 00 10 0A 6C 58 AB 08 00 00 00 00 00 00 00 ->trade complete 14333 ///////////////////////////////////////// E9 D7 38 03 00 00 00 01 GUID OF A 07 E2 91 03 00 00 00 01 GUID OF B A asks B to trade {CLIENT} Packet: (0x3863) CMSG_INITIATE_TRADE PacketSize = 6 TimeStamp = 14190240 67 90 E3 02 00 06 server sends back to A confirmation of the received invite {SERVER} Packet: (0xDB61) SMSG_TRADE_STATUS PacketSize = 33 TimeStamp = 14190989 5D 00 00 01 00 00 00 00 00 00 00 90 02 00 00 00 00 00 00 06 80 7F 0D 41 E3 03 00 00 00 29 B4 5E 2D //maybe some auto click by client on some popup {CLIENT} Packet: (0x98CA) UNKNOWN PacketSize = 0 TimeStamp = 14191005 probably the other client accepted the trade {SERVER} Packet: (0xDB61) SMSG_TRADE_STATUS PacketSize = 31 TimeStamp = 14191301 49 00 00 02 00 00 00 AB 2A 00 00 DB 00 09 00 00 00 0A 40 80 0D 41 0A 20 84 0D 41 2C 31 E9 00 ///////////////////////////////////////// B asks A to trade {SERVER} Packet: (0xDB61) SMSG_TRADE_STATUS PacketSize = 33 TimeStamp = 14208430 5D 00 2A 01 00 00 00 AB 2A 00 00 90 02 00 00 00 00 00 01 06 30 7F 0D 41 E3 07 E2 91 03 30 95 A8 4A compressed guid of the inviter B accepts trade {CLIENT} Packet: (0x0869) UNKNOWN PacketSize = 0 TimeStamp = 14208430 server lets B know that he received the previous packet {SERVER} Packet: (0xDB61) SMSG_TRADE_STATUS PacketSize = 32 TimeStamp = 14208851 59 00 01 02 00 00 00 00 00 00 00 16 00 00 0A 00 00 00 DD E0 85 0D 41 BC B0 7D 0D 41 67 00 00 00 ///////////////////////////////////////// */ /* we receive invite {SERVER} Packet: (0xDB61) SMSG_TRADE_STATUS PacketSize = 33 TimeStamp = 14208430 5D 00 mask - 5 bits 2A junk 01 00 00 00 status ? AB 2A 00 00 famous contant value or 0 90 - go2 B we are asking this guy to accept our trade 02 - go3 B we are asking this guy to accept our trade 00 00 00 00 00 00 - junk ? 06 - go0 B we are asking this guy to accept our trade 80 7F 0D 41 - magic float ? E3 - go1 B we are asking this guy to accept our trade 07 E2 91 03 lowguid of the other guy junk ? 30 95 A8 4A serializer ? */ //right now trade initiator does not need this packet /* { sStackWorldPacket( data, SMSG_TRADE_STATUS, 44 + 10 ); data << uint16( 0x59 ); // mask bit_2 might be go0, bit_0 might be go7 data << uint8( 0 ); // junk // data << ObfuscateByte( GUID_bytes[6] ); data << uint32( TRADE_STATUS_PROPOSED ); data << uint32( TRADE_ID_CONST ); //used a lot of times or 0 data << ObfuscateByte( GUID_bytes[2] ); data << ObfuscateByte( GUID_bytes[3] ); data << uint8( 0 ); // junk data << uint32( 0x00000000 ); // highguid or junk // data << ObfuscateByte( GUID_bytes[7] ); data << ObfuscateByte( GUID_bytes[0] ); data << float( 0 ); // junk data << ObfuscateByte( GUID_bytes[1] ); data << uint32( pTarget->GetLowGUID() ); // junk data << uint32( 0x00000000 ); // could be trade ID. Like A asks B, B refuses, A received back this number SendPacket( &data ); }/**/ // _player->SendTradeUpdate( 0 ); //trade target does need this packet so he can auto reply with CMSG_BEGIN_TRADE { *(uint64*)GUID_bytes = _player->GetGUID(); sStackWorldPacket( data, SMSG_TRADE_STATUS, 44 + 10 ); data << uint16( 0x59 ); // mask bit_2 might be go0, bit_0 might be go7 data << uint8( 0 ); // junk, can send 0 also // data << ObfuscateByte( GUID_bytes[6] ); data << uint32( TRADE_STATUS_PROPOSED ); data << uint32( TRADE_ID_CONST ); //used a lot of times or 0, data << ObfuscateByte( GUID_bytes[2] ); data << ObfuscateByte( GUID_bytes[3] ); data << uint8( 0 ); // junk data << uint32( 0x00000000 ); // highguid ? trade session counter ? junk ? // data << ObfuscateByte( GUID_bytes[7] ); data << ObfuscateByte( GUID_bytes[0] ); data << float( 0 ); // junk seems to be some float sometimes data << ObfuscateByte( GUID_bytes[1] ); data << uint32( _player->GetLowGUID() ); // lowguid ? junk ? data << uint32( 0 ); // could be trade ID. Like A asks B, B refuses, A received back this number. Or it could be time, global packet serializer pTarget->m_session->SendPacket( &data ); }/**/ // pTarget->SendTradeUpdate( 0 ); }
void WorldSession::HandleCharCreateOpcode(WorldPacket & recv_data) { CHECK_PACKET_SIZE(recv_data, 10); std::string name; uint8 race, class_; recv_data >> name >> race >> class_; recv_data.rpos(0); LoginErrorCode res = VerifyName(name.c_str(), name.length()); if (res != E_CHAR_NAME_SUCCESS) { OutPacket(SMSG_CHAR_CREATE, 1, &res); return; } res = g_characterNameFilter->Parse(name, false) ? E_CHAR_NAME_PROFANE : E_CHAR_NAME_SUCCESS; if (res != E_CHAR_NAME_SUCCESS) { OutPacket(SMSG_CHAR_CREATE, 1, &res); return; } res = objmgr.GetPlayerInfoByName(name.c_str()) == NULL ? E_CHAR_CREATE_SUCCESS : E_CHAR_CREATE_NAME_IN_USE; if (res != E_CHAR_CREATE_SUCCESS) { OutPacket(SMSG_CHAR_CREATE, 1, &res); return; } res = sHookInterface.OnNewCharacter(race, class_, this, name.c_str()) ? E_CHAR_CREATE_SUCCESS : E_CHAR_CREATE_ERROR; if (res != E_CHAR_CREATE_SUCCESS) { OutPacket(SMSG_CHAR_CREATE, 1, &res); return; } QueryResult* result = CharacterDatabase.Query("SELECT COUNT(*) FROM banned_names WHERE name = '%s'", CharacterDatabase.EscapeString(name).c_str()); if (result) { if (result->Fetch()[0].GetUInt32() > 0) { // That name is banned! OutPacket(SMSG_CHAR_CREATE, 1, CHAR_NAME_PROFANE); delete result; return; } delete result; } // Check if player got Death Knight already on this realm. if (Config.OptionalConfig.GetBoolDefault("ClassOptions", "DeathKnightLimit", true) && has_dk && (class_ == DEATHKNIGHT)) { OutPacket(SMSG_CHAR_CREATE, 1, CHAR_CREATE_UNIQUE_CLASS_LIMIT); return; } // loading characters // Check the number of characters, so we can't make over 10. // They're able to manage to create >10 sometimes, not exactly sure how .. result = CharacterDatabase.Query("SELECT COUNT(*) FROM characters WHERE acct = %u", GetAccountId()); if (result) { if (result->Fetch()[0].GetUInt32() >= 10) { // We can't make any more characters. OutPacket(SMSG_CHAR_CREATE, 1, CHAR_CREATE_SERVER_LIMIT); delete result; return; } delete result; } Player* pNewChar = objmgr.CreatePlayer(class_); pNewChar->SetSession(this); if (!pNewChar->Create(recv_data)) { // failed. pNewChar->ok_to_remove = true; delete pNewChar; OutPacket(SMSG_CHAR_CREATE, 1, CHAR_CREATE_FAILED); return; } //Same Faction limitation only applies to PVP and RPPVP realms :) uint32 realmType = sLogonCommHandler.GetRealmType(); if (!HasGMPermissions() && realmType == REALMTYPE_PVP && _side >= 0 && !sWorld.crossover_chars) // ceberwow fixed bug { if ((pNewChar->IsTeamAlliance() && (_side == 1)) || (pNewChar->IsTeamHorde() && (_side == 0))) { pNewChar->ok_to_remove = true; delete pNewChar; OutPacket(SMSG_CHAR_CREATE, 1, CHAR_CREATE_PVP_TEAMS_VIOLATION); return; } } //Check if player has a level 55 or higher character on this realm and allow him to create DK. //This check can be turned off in optional.conf if (Config.OptionalConfig.GetBoolDefault("ClassOptions", "DeathKnightPreReq", false) && !has_level_55_char && (class_ == DEATHKNIGHT)) { pNewChar->ok_to_remove = true; delete pNewChar; /* WorldPacket data(1); data.SetOpcode(SMSG_CHAR_CREATE); data << (uint8)56 + 1; // This errorcode is not the actual one. Need to find a real error code. SendPacket( &data ); */ OutPacket(SMSG_CHAR_CREATE, 1, CHAR_CREATE_LEVEL_REQUIREMENT); return; } pNewChar->UnSetBanned(); pNewChar->addSpell(22027); // Remove Insignia if (pNewChar->getClass() == WARLOCK) { pNewChar->AddSummonSpell(416, 3110); // imp fireball pNewChar->AddSummonSpell(417, 19505); pNewChar->AddSummonSpell(1860, 3716); pNewChar->AddSummonSpell(1863, 7814); } pNewChar->SaveToDB(true); PlayerInfo* pn = new PlayerInfo; pn->guid = pNewChar->GetLowGUID(); pn->name = strdup(pNewChar->GetName()); pn->class_ = pNewChar->getClass(); pn->race = pNewChar->getRace(); pn->gender = pNewChar->getGender(); pn->acct = GetAccountId(); pn->m_Group = 0; pn->subGroup = 0; pn->m_loggedInPlayer = NULL; pn->team = pNewChar->GetTeam(); pn->guild = NULL; pn->guildRank = NULL; pn->guildMember = NULL; pn->lastOnline = UNIXTIME; objmgr.AddPlayerInfo(pn); pNewChar->ok_to_remove = true; delete pNewChar; OutPacket(SMSG_CHAR_CREATE, 1, CHAR_CREATE_SUCCESS); sLogonCommHandler.UpdateAccountCount(GetAccountId(), 1); }
void WorldSession::FullLogin(Player* plr) { sLog.Debug("WorldSession", "Fully loading player %u", plr->GetLowGUID()); SetPlayer(plr); m_MoverWoWGuid.Init(plr->GetGUID()); /* world preload */ packetSMSG_LOGIN_VERIFY_WORLD vwpck; vwpck.MapId = plr->GetMapId(); vwpck.O = plr->GetOrientation(); vwpck.X = plr->GetPositionX(); vwpck.Y = plr->GetPositionY(); vwpck.Z = plr->GetPositionZ(); OutPacket( SMSG_LOGIN_VERIFY_WORLD, sizeof(packetSMSG_LOGIN_VERIFY_WORLD), &vwpck ); // send voicechat state - active/inactive /* {SERVER} Packet: (0x03C7) UNKNOWN PacketSize = 2 |------------------------------------------------|----------------| |00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF| |------------------------------------------------|----------------| |02 01 |.. | ------------------------------------------------------------------- */ WorldPacket datab(SMSG_FEATURE_SYSTEM_STATUS, 2); datab << uint8(2) << uint8(0); SendPacket(&datab); datab.Initialize(SMSG_LEARNED_DANCE_MOVES, 8); datab << uint32(0); datab << uint32(0); SendPacket(&datab); plr->UpdateStats(); // Anti max level hack. if(sWorld.LevelCap_Custom_All && (plr->getLevel() > sWorld.LevelCap_Custom_All)) plr->SetUInt32Value(UNIT_FIELD_LEVEL, sWorld.LevelCap_Custom_All); // Enable certain GM abilities on login. if(HasGMPermissions()) { plr->bGMTagOn = true; plr->m_isGmInvisible = true; plr->m_invisible = true; plr->bInvincible = true; if(CanUseCommand('z')) { plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_DEVELOPER); plr->triggerpass_cheat = true; // Enable for admins automatically. } else plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_GM); } // Make sure our name exists (for premade system) PlayerInfo * info = objmgr.GetPlayerInfo(plr->GetLowGUID()); if(info == NULL) { info = new PlayerInfo; memset(info, 0, sizeof(PlayerInfo)); info->_class = plr->getClass(); info->gender = plr->getGender(); info->guid = plr->GetLowGUID(); info->name = strdup(plr->GetName()); info->lastLevel = plr->getLevel(); info->lastOnline = UNIXTIME; info->lastZone = plr->GetZoneId(); info->race = plr->getRace(); info->team = plr->GetTeam(); objmgr.AddPlayerInfo(info); } plr->m_playerInfo = info; if(plr->m_playerInfo->GuildId) { plr->m_uint32Values[PLAYER_GUILDID] = plr->m_playerInfo->GuildId; plr->m_uint32Values[PLAYER_GUILDRANK] = plr->m_playerInfo->GuildRank; } for(uint32 z = 0; z < NUM_ARENA_TEAM_TYPES; ++z) { if(plr->m_playerInfo->arenaTeam[z] != NULL) { plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*6), plr->m_playerInfo->arenaTeam[z]->m_id); if(plr->m_playerInfo->arenaTeam[z]->m_leader == plr->GetLowGUID()) plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*6) + 1, 0); else plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*6) + 1, 1); } } info->m_loggedInPlayer = plr; // account data == UI config if(sWorld.m_useAccountData) { WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4+1+4+8*4); MD5Hash md5hash; data << uint32(UNIXTIME) << uint8(1) << uint32(0xEA); for (int i = 0; i < 8; i++) { AccountDataEntry* acct_data = GetAccountData(i); if(0xEA & (1 << i)) data << uint32(acct_data->Time); md5hash.Initialize(); md5hash.UpdateData((const uint8*)acct_data->data, acct_data->sz); md5hash.Finalize(); } SendPacket(&data); } else { WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4+1+4+8*4); MD5Hash md5hash; data << uint32(UNIXTIME) << uint8(1) << uint32(0xEA); for (int i = 0; i < 8; i++) { if(0xEA & (1 << i)) data << uint32(0); AccountDataEntry* acct_data = GetAccountData(i); if(acct_data) { md5hash.Initialize(); md5hash.UpdateData((const uint8*)acct_data->data, acct_data->sz); md5hash.Finalize(); } } SendPacket(&data); } // Set TIME OF LOGIN CharacterDatabase.Execute("UPDATE characters SET online = 1 WHERE guid = %u" , plr->GetLowGUID()); bool enter_world = true; // Find our transporter and add us if we're on one. if(plr->GetTransportGuid() != 0) { uint64 transGuid = plr->GetTransportGuid(); Transporter* pTrans = objmgr.GetTransporter(GUID_LOPART(transGuid)); if(pTrans) { if(plr->isDead()) plr->RemoteRevive(); float c_tposx, c_tposy, c_tposz, c_tposo; plr->GetMovementInfo()->GetTransportPosition(c_tposx, c_tposy, c_tposz, c_tposo); c_tposx += pTrans->GetPositionX(); c_tposy += pTrans->GetPositionY(); c_tposz += pTrans->GetPositionZ(); if(plr->GetMapId() != pTrans->GetMapId()) // loaded wrong map { plr->SetMapId(pTrans->GetMapId()); WorldPacket dataw(SMSG_NEW_WORLD, 20); dataw << pTrans->GetMapId() << c_tposx << c_tposy << c_tposz << c_tposo; SendPacket(&dataw); // shit is sent in worldport ack. enter_world = false; } plr->SetPosition(c_tposx, c_tposy, c_tposz, c_tposo); plr->m_CurrentTransporter = pTrans; pTrans->AddPlayer(plr); } } if(plr->GetVehicle()) plr->GetVehicle()->RemovePassenger(plr); sLog.Debug( "WorldSession","Player %s logged in.", plr->GetName()); if(plr->GetTeam() == 1) sWorld.HordePlayers++; else sWorld.AlliancePlayers++; if(sWorld.SendMovieOnJoin && plr->m_FirstLogin && !HasGMPermissions()) plr->SendCinematic(plr->myRace->cinematic_id); sLog.Debug( "WorldSession","Created new player for existing players (%s)", plr->GetName() ); // Login time, will be used for played time calc plr->m_playedtime[2] = (uint32)UNIXTIME; // Send online status to people having this char in friendlist plr->Social_TellOnlineStatus(); // send friend list (for ignores) plr->Social_SendFriendList(7); // send to gms if(HasGMPermissions()) sWorld.SendMessageToGMs(this, "%s%s %s (%s) is now online.|r", MSG_COLOR_GOLD, CanUseCommand('z') ? "Admin" : "GameMaster", plr->GetName(), GetAccountNameS(), GetPermissions()); //Set current RestState if( plr->m_isResting) // We are in a resting zone, turn on Zzz plr->ApplyPlayerRestState(true); //Check if there is a time difference between lastlogoff and now if( plr->m_timeLogoff > 0 && plr->GetUInt32Value(UNIT_FIELD_LEVEL) < plr->GetUInt32Value(PLAYER_FIELD_MAX_LEVEL)) // if timelogoff = 0 then it's the first login { uint32 currenttime = (uint32)UNIXTIME; uint32 timediff = currenttime - plr->m_timeLogoff; //Calculate rest bonus if( timediff > 0 ) plr->AddCalculatedRestXP(timediff); } sHookInterface.OnFullLogin(plr); if(info->m_Group) info->m_Group->Update(); if(!sWorld.m_blockgmachievements || !HasGMPermissions()) { // Retroactive: Level achievement plr->GetAchievementInterface()->HandleAchievementCriteriaLevelUp( plr->getLevel() ); // Send achievement data! if( plr->GetAchievementInterface()->HasAchievements() ) { WorldPacket * data = plr->GetAchievementInterface()->BuildAchievementData(); plr->CopyAndSendDelayedPacket(data); delete data; } } if(enter_world && !plr->GetMapMgr()) plr->AddToWorld(true); sTracker.CheckPlayerForTracker(plr, true); // If we have the talent, it returns anyway, so just call the function. plr->ResetTitansGrip(); if(plr->GetItemInterface()) plr->GetItemInterface()->CheckAreaItems(); objmgr.AddPlayer(plr); }
void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data, 10); std::string name; uint8 race, class_; recv_data >> name >> race >> class_; recv_data.rpos(0); WorldPacket data(SMSG_CHAR_CREATE, 1); if(!sWorld.VerifyName(name.c_str(), name.length())) { data << uint8(CHAR_CREATE_NAME_IN_USE); SendPacket(&data); return; } if(g_characterNameFilter->Parse(name, false)) { data << uint8(CHAR_CREATE_NAME_IN_USE); SendPacket(&data); return; } //reserved for console whisper if(name == "Console" || name == "console") { data << uint8(CHAR_CREATE_NAME_IN_USE); SendPacket(&data); return; } if(objmgr.GetPlayerInfoByName(name.c_str()) != 0) { data << uint8(CHAR_CREATE_NAME_IN_USE); SendPacket(&data); return; } if(!sHookInterface.OnNewCharacter(race, class_, this, name.c_str())) { data << uint8(CHAR_CREATE_NAME_IN_USE); SendPacket(&data); return; } if( class_ == DEATHKNIGHT ) { if(!HasFlag(ACCOUNT_FLAG_XPACK_02)) { data << uint8(CHAR_CREATE_EXPANSION); SendPacket(&data); return; } else if(!CanCreateDeathKnight() && !HasGMPermissions()) { if(sWorld.m_deathKnightReqLevel > m_highestLevel) data << uint8(CHAR_CREATE_LEVEL_REQUIREMENT); else data << uint8(CHAR_CREATE_UNIQUE_CLASS_LIMIT); SendPacket(&data); return; } } QueryResult * result = CharacterDatabase.Query("SELECT COUNT(*) FROM banned_names WHERE name = '%s'", CharacterDatabase.EscapeString(name).c_str()); if(result) { if(result->Fetch()[0].GetUInt32() > 0) { // That name is banned! data << uint8(CHAR_NAME_PROFANE); SendPacket(&data); delete result; return; } delete result; } // loading characters //checking number of chars is useless since client will not allow to create more than 10 chars //as the 'create' button will not appear (unless we want to decrease maximum number of characters) Player* pNewChar = objmgr.CreatePlayer(); pNewChar->SetSession(this); if(!pNewChar->Create( recv_data )) { // failed. pNewChar->ok_to_remove = true; pNewChar->Destruct(); pNewChar = NULLPLR; return; } pNewChar->UnSetBanned(); pNewChar->addSpell(22027); // Remove Insignia if(pNewChar->getClass() == WARLOCK) { pNewChar->AddSummonSpell(416, 3110); // imp fireball pNewChar->AddSummonSpell(417, 19505); pNewChar->AddSummonSpell(1860, 3716); pNewChar->AddSummonSpell(1863, 7814); } pNewChar->SaveToDB(true); PlayerInfo *pn = new PlayerInfo; memset(pn, 0, sizeof(PlayerInfo)); pn->guid = pNewChar->GetLowGUID(); pn->name = strdup(pNewChar->GetName()); pn->_class = pNewChar->getClass(); pn->race = pNewChar->getRace(); pn->gender = pNewChar->getGender(); pn->lastLevel = pNewChar->getLevel(); pn->lastZone = pNewChar->GetZoneId(); pn->lastOnline = UNIXTIME; pn->team = pNewChar->GetTeam(); pn->acct = GetAccountId(); objmgr.AddPlayerInfo(pn); pNewChar->ok_to_remove = true; pNewChar->Destruct(); pNewChar = NULLPLR; // CHAR_CREATE_SUCCESS data << uint8(CHAR_CREATE_SUCCESS); SendPacket(&data); sLogonCommHandler.UpdateAccountCount(GetAccountId(), 1); }
void WorldSession::HandleAcceptTrade(WorldPacket & recv_data) { #ifdef FORCED_GM_TRAINEE_MODE if( CanUseCommand('k') && !HasGMPermissions() ) { GetPlayer()->BroadcastMessage( "You are not allowed to use this feature" ); return; } #endif if( sWorld.getIntRate( INTRATE_DISABLE_TRADE_FEATURE ) ) { GetPlayer()->BroadcastMessage( "Trade feature is disabled right now" ); return; } Player * plr = _player->GetTradeTarget(); if(_player->mTradeTarget == 0 || !plr) { return; } packetSMSG_TRADE_STATUS data; memset( &data, 0, sizeof( data ) ); data.trade_status = TRADE_STATUS_ACCEPTED; OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); plr->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); _player->mTradeStatus = TRADE_STATUS_ACCEPTED; //when both have this status we can close the deal bool bag_hack_detected = false; if(plr->mTradeStatus == TRADE_STATUS_ACCEPTED) { // Ready! uint32 ItemCount = 0; uint32 TargetItemCount = 0; Player * pTarget = plr; /* // Calculate Item Count for(uint32 Index = 0; Index < 7; ++Index) { if(_player->mTradeItems[Index] != 0) ++ItemCount; if(pTarget->mTradeItems[Index] != 0) ++TargetItemCount; }*/ // Calculate Count for(uint32 Index = 0; Index < TRADE_MAX_TRADABLE_ITEMS; ++Index) // cebernic: checking for MAX_TRADE_TRADABLE_ITEMS items ,untradable item check via others func. { Item * pItem; // safely trade checking pItem = _player->mTradeItems[Index]; if( pItem ) { if( ( pItem->IsContainer() && SafeContainerCast(pItem)->HasItems() ) || ( pItem->GetProto() && pItem->GetProto()->Bonding==ITEM_BIND_ON_PICKUP) ) { ItemCount = 0; TargetItemCount = 0; bag_hack_detected = true; break; } else ++ItemCount; } pItem = pTarget->mTradeItems[Index]; if( pItem ) { if( ( pItem->IsContainer() && SafeContainerCast(pItem)->HasItems() ) || ( pItem->GetProto() && pItem->GetProto()->Bonding==ITEM_BIND_ON_PICKUP) ) { ItemCount = 0; TargetItemCount = 0; bag_hack_detected = true; break; } else ++TargetItemCount; } //if(_player->mTradeItems[Index] != 0) ++ItemCount; //if(pTarget->mTradeItems[Index] != 0) ++TargetItemCount; } if( (_player->m_ItemInterface->CalculateFreeSlots(NULL) + ItemCount) < TargetItemCount || (pTarget->m_ItemInterface->CalculateFreeSlots(NULL) + TargetItemCount) < ItemCount || bag_hack_detected == true || (ItemCount==0 && TargetItemCount==0 && !pTarget->mTradeGold && !_player->mTradeGold) ) // ceberwow added it { // Not enough slots on one end. data.trade_status = TRADE_STATUS_CANCELLED; } else { data.trade_status = TRADE_STATUS_COMPLETE; uint64 Guid; Item * pItem; // Remove all items from the players inventory for(uint32 Index = 0; Index < TRADE_MAX_TRADABLE_ITEMS; ++Index) { Guid = _player->mTradeItems[Index] ? _player->mTradeItems[Index]->GetGUID() : 0; if(Guid != 0) { if( _player->mTradeItems[Index]->GetProto()->Bonding == ITEM_BIND_ON_PICKUP || _player->mTradeItems[Index]->GetProto()->Bonding >= ITEM_BIND_QUEST ) { _player->mTradeItems[Index] = NULL; } else { if(GetPermissionCount()>0) sGMLog.writefromsession(this, "traded item %s to %s", _player->mTradeItems[Index]->GetProto()->Name1, pTarget->GetName()); pItem = _player->m_ItemInterface->SafeRemoveAndRetreiveItemByGuid(Guid, true); } } Guid = pTarget->mTradeItems[Index] ? pTarget->mTradeItems[Index]->GetGUID() : 0; if(Guid != 0) { if( pTarget->mTradeItems[Index]->GetProto()->Bonding == ITEM_BIND_ON_PICKUP || pTarget->mTradeItems[Index]->GetProto()->Bonding >= ITEM_BIND_QUEST ) { pTarget->mTradeItems[Index] = NULL; } else { if(pTarget->GetSession() && pTarget->GetSession()->GetPermissionCount()>0) sGMLog.writefromsession(pTarget->GetSession(), "traded item %s to %s", pTarget->mTradeItems[Index]->GetProto()->Name1, _player->GetName()); pTarget->m_ItemInterface->SafeRemoveAndRetreiveItemByGuid(Guid, true); } } } // Dump all items back into the opposite players inventory for(uint32 Index = 0; Index < TRADE_MAX_TRADABLE_ITEMS; ++Index) { pItem = _player->mTradeItems[Index]; if(pItem != 0 && pTarget) { pItem->SetOwner(pTarget); // crash fixed. if( !pTarget->m_ItemInterface->AddItemToFreeSlot(&pItem) ) { pItem->DeleteMe(); pItem = NULL; _player->mTradeItems[Index] = NULL; continue; } } pItem = pTarget->mTradeItems[Index]; if(pItem != 0 && _player) { pItem->SetOwner(_player); if( !_player->m_ItemInterface->AddItemToFreeSlot(&pItem) ) { pItem->DeleteMe(); pItem = NULL; pTarget->mTradeItems[Index] = NULL; continue; } } } // Trade Gold if(pTarget->mTradeGold && pTarget->GetGold() >= pTarget->mTradeGold ) { _player->ModGold(pTarget->mTradeGold); pTarget->ModGold(-(int64)pTarget->mTradeGold); if(GetPermissionCount()>0) sGMLog.writefromsession(this, "traded(gave) %u gold to %s", pTarget->mTradeGold, pTarget->GetName()); } if(_player->mTradeGold && _player->GetGold() >= _player->mTradeGold) { pTarget->ModGold( _player->mTradeGold); _player->ModGold( -(int64)_player->mTradeGold); if(pTarget->GetSession() && pTarget->GetSession()->GetPermissionCount()>0) sGMLog.writefromsession(pTarget->GetSession(), "traded(gave) %u gold to %s", _player->mTradeGold, _player->GetName()); } // Close Window data.trade_status = TRADE_STATUS_COMPLETE; } OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); plr->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); _player->mTradeStatus = TRADE_STATUS_COMPLETE; plr->mTradeStatus = TRADE_STATUS_COMPLETE; // Reset Trade Vars _player->ResetTradeVariables(); plr->ResetTradeVariables(); //removed by zack. Hehe, just a way to spam db with saves. Not funny // added alternative way as item saves before // Save for eachother //plr->SaveToDB(false); //_player->SaveToDB(false); } }
void WorldSession::FullLogin(Player* plr) { DEBUG_LOG("WorldSession", "Fully loading player %u", plr->GetLowGUID()); SetPlayer(plr); m_MoverWoWGuid.Init(plr->GetGUID()); // copy to movement array //movement_packet[0] = m_MoverWoWGuid.GetNewGuidMask(); //memcpy(&movement_packet[1], m_MoverWoWGuid.GetNewGuid(), m_MoverWoWGuid.GetNewGuidLen()); WorldPacket datab(MSG_SET_DUNGEON_DIFFICULTY, 20); datab << plr->iInstanceType; datab << uint32(0x01); datab << uint32(0x00); SendPacket(&datab); WorldPacket datat(SMSG_MOTD, 50); datat << uint32(0x04); datat << sWorld.GetMotd(); SendPacket(&datat); /* world preload */ packetSMSG_LOGIN_VERIFY_WORLD vwpck; vwpck.MapId = plr->GetMapId(); vwpck.O = plr->GetOrientation(); vwpck.X = plr->GetPositionX(); vwpck.Y = plr->GetPositionY(); vwpck.Z = plr->GetPositionZ(); OutPacket( SMSG_LOGIN_VERIFY_WORLD, sizeof(packetSMSG_LOGIN_VERIFY_WORLD), &vwpck ); // send voicechat state - active/inactive /* {SERVER} Packet: (0x03C7) UNKNOWN PacketSize = 2 |------------------------------------------------|----------------| |00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF| |------------------------------------------------|----------------| |02 01 |.. | ------------------------------------------------------------------- */ #ifdef VOICE_CHAT datab.Initialize(SMSG_FEATURE_SYSTEM_STATUS); datab << uint8(2) << uint8(sVoiceChatHandler.CanUseVoiceChat() ? 1 : 0); SendPacket(&datab); #else datab.Initialize(SMSG_FEATURE_SYSTEM_STATUS); datab << uint8(2) << uint8(0); #endif plr->UpdateAttackSpeed(); /*if(plr->getLevel()>70) plr->SetUInt32Value(UNIT_FIELD_LEVEL,70);*/ // Enable trigger cheat by default //plr->triggerpass_cheat = HasGMPermissions(); // Make sure our name exists (for premade system) PlayerInfo * info = objmgr.GetPlayerInfo(plr->GetLowGUID()); if(info == 0) { info = new PlayerInfo; memset(info, 0, sizeof(PlayerInfo)); info->cl = plr->getClass(); info->gender = plr->getGender(); info->guid = plr->GetLowGUID(); info->name = strdup(plr->GetName()); info->lastLevel = plr->getLevel(); info->lastOnline = UNIXTIME; info->lastZone = plr->GetZoneId(); info->race = plr->getRace(); info->team = plr->GetTeam(); objmgr.AddPlayerInfo(info); } plr->m_playerInfo = info; if(plr->m_playerInfo->guild) { plr->m_uint32Values[PLAYER_GUILDID] = plr->m_playerInfo->guild->GetGuildId(); plr->m_uint32Values[PLAYER_GUILDRANK] = plr->m_playerInfo->guildRank->iId; } for(uint32 z = 0; z < NUM_ARENA_TEAM_TYPES; ++z) { if(_player->m_playerInfo->arenaTeam[z] != NULL) { _player->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*7), _player->m_playerInfo->arenaTeam[z]->m_id); if(_player->m_playerInfo->arenaTeam[z]->m_leader == _player->GetLowGUID()) _player->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*7) + 1, 0); else _player->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*7) + 1, 1); } } info->m_loggedInPlayer = plr; // account data == UI config SendAccountDataTimes(PER_CHARACTER_CACHE_MASK); _player->ResetTitansGrip(); // Set TIME OF LOGIN CharacterDatabase.Execute ( "UPDATE characters SET online = 1 WHERE guid = %u" , plr->GetLowGUID()); bool enter_world = true; #ifndef CLUSTERING // Find our transporter and add us if we're on one. if(plr->m_TransporterGUID != 0) { Transporter* pTrans = objmgr.GetTransporter(GUID_LOPART(plr->m_TransporterGUID)); if(pTrans) { if(plr->isDead()) { plr->RemoteRevive(); } float c_tposx = pTrans->GetPositionX() + plr->m_TransporterX; float c_tposy = pTrans->GetPositionY() + plr->m_TransporterY; float c_tposz = pTrans->GetPositionZ() + plr->m_TransporterZ; if(plr->GetMapId() != pTrans->GetMapId()) // loaded wrong map { plr->SetMapId(pTrans->GetMapId()); WorldPacket dataw(SMSG_NEW_WORLD, 20); dataw << pTrans->GetMapId() << c_tposx << c_tposy << c_tposz << plr->GetOrientation(); SendPacket(&dataw); // shit is sent in worldport ack. enter_world = false; } plr->SetPosition(c_tposx, c_tposy, c_tposz, plr->GetOrientation(), false); plr->m_CurrentTransporter = pTrans; pTrans->AddPlayer(plr); } } #endif DEBUG_LOG( "WorldSession","Player %s logged in.", plr->GetName()); if(plr->GetTeam() == 1) sWorld.HordePlayers++; else sWorld.AlliancePlayers++; if(plr->m_FirstLogin && !HasGMPermissions()) OutPacket(SMSG_TRIGGER_CINEMATIC, 4, &plr->myRace->cinematic_id); DEBUG_LOG( "WorldSession","Created new player for existing players (%s)", plr->GetName() ); // Login time, will be used for played time calc plr->m_playedtime[2] = (uint32)UNIXTIME; //Issue a message telling all guild members that this player has signed on if(plr->IsInGuild()) { Guild *pGuild = plr->m_playerInfo->guild; if(pGuild) { WorldPacket data(50); data.Initialize(SMSG_GUILD_EVENT); data << uint8(GUILD_EVENT_MOTD); data << uint8(0x01); if(pGuild->GetMOTD()) data << pGuild->GetMOTD(); else data << uint8(0); SendPacket(&data); pGuild->LogGuildEvent(GUILD_EVENT_HASCOMEONLINE, 1, plr->GetName()); } } // Send online status to people having this char in friendlist (excluding GM's) if(!HasGMPermissions()) _player->Social_TellFriendsOnline(); // send friend list (for ignores) _player->Social_SendFriendList(7); // Send revision (if enabled) #ifdef WIN32 _player->BroadcastMessage("Server: %sAscent %s r%u/%s-Win-%s %s(www.ascentemulator.net)", MSG_COLOR_WHITE, BUILD_REVISION, CONFIG, ARCH, MSG_COLOR_LIGHTBLUE); #else _player->BroadcastMessage("Server: %sAscent %s r%u/%s-%s %s(www.ascentemulator.net)", MSG_COLOR_WHITE, BUILD_REVISION, PLATFORM_TEXT, ARCH, MSG_COLOR_LIGHTBLUE); #endif if(sWorld.SendStatsOnJoin) { _player->BroadcastMessage("Online Players: %s%u |rPeak: %s%u|r Accepted Connections: %s%u", MSG_COLOR_WHITE, sWorld.GetSessionCount(), MSG_COLOR_WHITE, sWorld.PeakSessionCount, MSG_COLOR_WHITE, sWorld.mAcceptedConnections); _player->BroadcastMessage("Server Uptime: |r%s", sWorld.GetUptimeString().c_str()); } // send to gms if( HasGMPermissions() ) sWorld.SendMessageToGMs(this, "GM %s (%s) is now online. (Permissions: [%s])", _player->GetName(), GetAccountNameS(), GetPermissions()); //Set current RestState if( plr->m_isResting) // We are in a resting zone, turn on Zzz plr->ApplyPlayerRestState(true); //Check if there is a time difference between lastlogoff and now if( plr->m_timeLogoff > 0 && plr->GetUInt32Value(UNIT_FIELD_LEVEL) < plr->GetUInt32Value(PLAYER_FIELD_MAX_LEVEL)) // if timelogoff = 0 then it's the first login { uint32 currenttime = (uint32)UNIXTIME; uint32 timediff = currenttime - plr->m_timeLogoff; //Calculate rest bonus if( timediff > 0 ) plr->AddCalculatedRestXP(timediff); } sHookInterface.OnEnterWorld2(_player); if(info->m_Group) info->m_Group->Update(); // Retroactive: Level achievement _player->GetAchievementInterface()->HandleAchievementCriteriaLevelUp( _player->getLevel() ); // Retroactive: Bank slots: broken atm :( //_player->GetAchievementInterface()->HandleAchievementCriteriaBuyBankSlot(true); // Send achievement data! if( _player->GetAchievementInterface()->HasAchievements() ) { WorldPacket * data = _player->GetAchievementInterface()->BuildAchievementData(); _player->CopyAndSendDelayedPacket(data); delete data; } SendAccountDataTimes(GLOBAL_CACHE_MASK); if(enter_world && !_player->GetMapMgr()) plr->AddToWorld(); objmgr.AddPlayer(_player); }
void WorldSession::FullLogin(Player * plr) { Log.Debug("WorldSession", "Fully loading player %u", plr->GetLowGUID()); SetPlayer(plr); m_MoverWoWGuid.Init(plr->GetGUID()); // copy to movement array movement_packet[0] = m_MoverWoWGuid.GetNewGuidMask(); memcpy(&movement_packet[1], m_MoverWoWGuid.GetNewGuid(), m_MoverWoWGuid.GetNewGuidLen()); #ifndef USING_BIG_ENDIAN StackWorldPacket<20> datab(CMSG_DUNGEON_DIFFICULTY); #else WorldPacket datab(CMSG_DUNGEON_DIFFICULTY, 20); #endif datab << plr->iInstanceType; datab << uint32(0x01); datab << uint32(0x00); SendPacket(&datab); /* world preload */ packetSMSG_LOGIN_VERIFY_WORLD vwpck; vwpck.MapId = plr->GetMapId(); vwpck.O = plr->GetOrientation(); vwpck.X = plr->GetPositionX(); vwpck.Y = plr->GetPositionY(); vwpck.Z = plr->GetPositionZ(); OutPacket( SMSG_LOGIN_VERIFY_WORLD, sizeof(packetSMSG_LOGIN_VERIFY_WORLD), &vwpck ); // send voicechat state - active/inactive /* {SERVER} Packet: (0x03C7) UNKNOWN PacketSize = 2 |------------------------------------------------|----------------| |00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF| |------------------------------------------------|----------------| |02 01 |.. | ------------------------------------------------------------------- */ #ifdef VOICE_CHAT datab.Initialize(SMSG_VOICE_SYSTEM_STATUS); datab << uint8(2) << uint8(sVoiceChatHandler.CanUseVoiceChat() ? 1 : 0); SendPacket(&datab); #else datab.Initialize(SMSG_VOICE_SYSTEM_STATUS); datab << uint8(2) << uint8(0); #endif plr->UpdateAttackSpeed(); /*if(plr->getLevel()>70) plr->SetUInt32Value(UNIT_FIELD_LEVEL,70);*/ // enable trigger cheat by default plr->triggerpass_cheat = HasGMPermissions(); // Make sure our name exists (for premade system) PlayerInfo * info = objmgr.GetPlayerInfo(plr->GetLowGUID()); if(info == 0) { info = new PlayerInfo; info->cl = plr->getClass(); info->gender = plr->getGender(); info->guid = plr->GetLowGUID(); info->name = strdup(plr->GetName()); info->lastLevel = plr->getLevel(); info->lastOnline = UNIXTIME; info->lastZone = plr->GetZoneId(); info->race = plr->getRace(); info->team = plr->GetTeam(); info->guild=NULL; info->guildRank=NULL; info->guildMember=NULL; info->m_Group=0; info->subGroup=0; objmgr.AddPlayerInfo(info); } plr->m_playerInfo = info; if(plr->m_playerInfo->guild) { plr->m_uint32Values[PLAYER_GUILDID] = plr->m_playerInfo->guild->GetGuildId(); plr->m_uint32Values[PLAYER_GUILDRANK] = plr->m_playerInfo->guildRank->iId; } info->m_loggedInPlayer = plr; // account data == UI config #ifndef USING_BIG_ENDIAN StackWorldPacket<128> data(SMSG_ACCOUNT_DATA_MD5); #else WorldPacket data(SMSG_ACCOUNT_DATA_MD5, 128); #endif MD5Hash md5hash; for (int i = 0; i < 8; i++) { AccountDataEntry* acct_data = GetAccountData(i); if (!acct_data->data) { data << uint64(0) << uint64(0); // Nothing. continue; } md5hash.Initialize(); md5hash.UpdateData((const uint8*)acct_data->data, acct_data->sz); md5hash.Finalize(); #ifndef USING_BIG_ENDIAN data.Write(md5hash.GetDigest(), MD5_DIGEST_LENGTH); #else data.append(md5hash.GetDigest(), MD5_DIGEST_LENGTH); #endif } SendPacket(&data); // Set TIME OF LOGIN CharacterDatabase.Execute ( "UPDATE characters SET online = 1 WHERE guid = %u" , plr->GetLowGUID()); bool enter_world = true; #ifndef CLUSTERING // Find our transporter and add us if we're on one. if(plr->m_TransporterGUID != 0) { Transporter * pTrans = objmgr.GetTransporter(GUID_LOPART(plr->m_TransporterGUID)); if(pTrans) { if(plr->isDead()) { plr->ResurrectPlayer(); plr->SetUInt32Value(UNIT_FIELD_HEALTH, plr->GetUInt32Value(UNIT_FIELD_MAXHEALTH)); plr->SetUInt32Value(UNIT_FIELD_POWER1, plr->GetUInt32Value(UNIT_FIELD_MAXPOWER1)); } float c_tposx = pTrans->GetPositionX() + plr->m_TransporterX; float c_tposy = pTrans->GetPositionY() + plr->m_TransporterY; float c_tposz = pTrans->GetPositionZ() + plr->m_TransporterZ; if(plr->GetMapId() != pTrans->GetMapId()) // loaded wrong map { plr->SetMapId(pTrans->GetMapId()); #ifndef USING_BIG_ENDIAN StackWorldPacket<20> dataw(SMSG_NEW_WORLD); #else WorldPacket dataw(SMSG_NEW_WORLD, 20); #endif dataw << pTrans->GetMapId() << c_tposx << c_tposy << c_tposz << plr->GetOrientation(); SendPacket(&dataw); // shit is sent in worldport ack. enter_world = false; } plr->SetPosition(c_tposx, c_tposy, c_tposz, plr->GetOrientation(), false); plr->m_CurrentTransporter = pTrans; pTrans->AddPlayer(plr); } } #endif Log.Debug("Login", "Player %s logged in.", plr->GetName()); if(plr->GetTeam() == 1) sWorld.HordePlayers++; else sWorld.AlliancePlayers++; if(plr->m_FirstLogin && !HasGMPermissions()) { uint32 racecinematic = plr->myRace->cinematic_id; #ifdef USING_BIG_ENDIAN swap32(&racecinematic); #endif OutPacket(SMSG_TRIGGER_CINEMATIC, 4, &racecinematic); } sLog.outDetail( "WORLD: Created new player for existing players (%s)", plr->GetName() ); // Login time, will be used for played time calc plr->m_playedtime[2] = (uint32)UNIXTIME; //Issue a message telling all guild members that this player has signed on if(plr->IsInGuild()) { Guild *pGuild = plr->m_playerInfo->guild; if(pGuild) { WorldPacket data(50); data.Initialize(SMSG_GUILD_EVENT); data << uint8(GUILD_EVENT_MOTD); data << uint8(0x01); if(pGuild->GetMOTD()) data << pGuild->GetMOTD(); else data << uint8(0); SendPacket(&data); pGuild->LogGuildEvent(GUILD_EVENT_HASCOMEONLINE, 1, plr->GetName()); } } // Send online status to people having this char in friendlist _player->Social_TellFriendsOnline(); // send friend list (for ignores) _player->Social_SendFriendList(7); // Send MOTD _player->BroadcastMessage(sWorld.GetMotd()); // Send revision (if enabled) #ifdef WIN32 _player->BroadcastMessage("Server: %sAscent %s r%u/%s-Win-%s %s(www.ascentemu.com)", MSG_COLOR_WHITE, BUILD_TAG, BUILD_REVISION, CONFIG, ARCH, MSG_COLOR_LIGHTBLUE); #else _player->BroadcastMessage("Server: %sAscent %s r%u/%s-%s %s(www.ascentemu.com)", MSG_COLOR_WHITE, BUILD_TAG, BUILD_REVISION, PLATFORM_TEXT, ARCH, MSG_COLOR_LIGHTBLUE); #endif if(sWorld.SendStatsOnJoin) { _player->BroadcastMessage("Online Players: %s%u |rPeak: %s%u|r Accepted Connections: %s%u", MSG_COLOR_WHITE, sWorld.GetSessionCount(), MSG_COLOR_WHITE, sWorld.PeakSessionCount, MSG_COLOR_WHITE, sWorld.mAcceptedConnections); } //Set current RestState if( plr->m_isResting) // We are resting at an inn , turn on Zzz plr->ApplyPlayerRestState(true); //Calculate rest bonus if there is time between lastlogoff and now if( plr->m_timeLogoff > 0 && plr->GetUInt32Value(UNIT_FIELD_LEVEL) < plr->GetUInt32Value(PLAYER_FIELD_MAX_LEVEL)) // if timelogoff = 0 then it's the first login { uint32 currenttime = (uint32)UNIXTIME; uint32 timediff = currenttime - plr->m_timeLogoff; //Calculate rest bonus if( timediff > 0 ) plr->AddCalculatedRestXP(timediff); } #ifdef CLUSTERING plr->SetInstanceID(forced_instance_id); plr->SetMapId(forced_map_id); #else sHookInterface.OnEnterWorld2(_player); #endif if(info->m_Group) info->m_Group->Update(); if(enter_world && !_player->GetMapMgr()) { plr->AddToWorld(); } objmgr.AddPlayer(_player); }
void WorldSession::HandleSendMail(WorldPacket& recvData) { MailMessage msg; ObjectGuid mailbox; uint32_t unk1, unk2; uint64_t money, COD; std::vector< Item* > items; Item* pItem; recvData >> unk1; recvData >> unk2; recvData >> COD; recvData >> money; uint32_t bodyLength = recvData.readBits(12); uint32_t subjectLength = recvData.readBits(9); uint8_t items_count = static_cast<uint8_t>(recvData.readBits(5)); // attached items count if (items_count > MAIL_MAX_ITEM_SLOT) { SendMailError(MAIL_ERR_TOO_MANY_ATTACHMENTS); return; } mailbox[0] = recvData.readBit(); ObjectGuid itemGUIDs[MAIL_MAX_ITEM_SLOT]; for (uint8_t i = 0; i < items_count; ++i) { itemGUIDs[i][2] = recvData.readBit(); itemGUIDs[i][6] = recvData.readBit(); itemGUIDs[i][3] = recvData.readBit(); itemGUIDs[i][7] = recvData.readBit(); itemGUIDs[i][1] = recvData.readBit(); itemGUIDs[i][0] = recvData.readBit(); itemGUIDs[i][4] = recvData.readBit(); itemGUIDs[i][5] = recvData.readBit(); } mailbox[3] = recvData.readBit(); mailbox[4] = recvData.readBit(); uint32_t receiverLength = recvData.readBits(7); mailbox[2] = recvData.readBit(); mailbox[6] = recvData.readBit(); mailbox[1] = recvData.readBit(); mailbox[7] = recvData.readBit(); mailbox[5] = recvData.readBit(); recvData.ReadByteSeq(mailbox[4]); for (uint8_t i = 0; i < items_count; ++i) { recvData.ReadByteSeq(itemGUIDs[i][6]); recvData.ReadByteSeq(itemGUIDs[i][1]); recvData.ReadByteSeq(itemGUIDs[i][7]); recvData.ReadByteSeq(itemGUIDs[i][2]); recvData.read_skip<uint8_t>(); // item slot in mail, not used recvData.ReadByteSeq(itemGUIDs[i][3]); recvData.ReadByteSeq(itemGUIDs[i][0]); recvData.ReadByteSeq(itemGUIDs[i][4]); recvData.ReadByteSeq(itemGUIDs[i][5]); } recvData.ReadByteSeq(mailbox[7]); recvData.ReadByteSeq(mailbox[3]); recvData.ReadByteSeq(mailbox[6]); recvData.ReadByteSeq(mailbox[5]); std::string subject = recvData.ReadString(subjectLength); std::string receiver = recvData.ReadString(receiverLength); recvData.ReadByteSeq(mailbox[2]); recvData.ReadByteSeq(mailbox[0]); std::string body = recvData.ReadString(bodyLength); recvData.ReadByteSeq(mailbox[1]); // Search for the recipient PlayerInfo* player_info = ObjectMgr::getSingleton().GetPlayerInfoByName(receiver.c_str()); if (!player_info) { SendMailError(MAIL_ERR_RECIPIENT_NOT_FOUND); return; } for (uint8_t i = 0; i < items_count; ++i) { pItem = _player->GetItemInterface()->GetItemByGUID(itemGUIDs[i]); if (pItem == nullptr || pItem->isSoulbound() || pItem->hasFlags(ITEM_FLAG_CONJURED)) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } if (pItem->isAccountbound() && GetAccountId() != player_info->acct) // don't mail account-bound items to another account { WorldPacket data(SMSG_SEND_MAIL_RESULT, 16); data << uint32_t(0); data << uint32_t(0); data << uint32_t(MAIL_ERR_BAG_FULL); data << uint32_t(INV_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS); SendPacket(&data); return; } items.push_back(pItem); } if (receiver.empty()) return; bool interfaction = false; if (sMailSystem.MailOption(MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION) || (HasGMPermissions() && sMailSystem.MailOption(MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION_GM))) { interfaction = true; } // Check we're sending to the same faction (disable this for testing) if (player_info->team != _player->GetTeam() && !interfaction) { SendMailError(MAIL_ERR_NOT_YOUR_ALLIANCE); return; } // Check if we're sending mail to ourselves if (strcmp(player_info->name, _player->GetName()) == 0 && !GetPermissionCount()) { SendMailError(MAIL_ERR_CANNOT_SEND_TO_SELF); return; } if (msg.stationery == MAIL_STATIONERY_GM && !HasGMPermissions()) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } // Instant delivery time by default. msg.delivery_time = (uint32_t)UNIXTIME; // Set up the cost uint32_t cost = items_count ? 30 * items_count : 30; // price hardcoded in client if (!sMailSystem.MailOption(MAIL_FLAG_DISABLE_POSTAGE_COSTS) && !(GetPermissionCount() && sMailSystem.MailOption(MAIL_FLAG_NO_COST_FOR_GM))) { cost += 30; } // check that we have enough in our backpack if (!_player->HasGold(cost)) { SendMailError(MAIL_ERR_NOT_ENOUGH_MONEY); return; } // Check for the item, and required item. if (!items.empty()) { for (std::vector< Item* >::iterator itr = items.begin(); itr != items.end(); ++itr) { pItem = *itr; if (_player->GetItemInterface()->SafeRemoveAndRetreiveItemByGuid(pItem->getGuid(), false) != pItem) continue; // should never be hit. pItem->RemoveFromWorld(); pItem->setOwner(NULL); pItem->SaveToDB(INVENTORY_SLOT_NOT_SET, 0, true, NULL); msg.items.push_back(pItem->getGuidLow()); if (GetPermissionCount() > 0) { /* log the message */ sGMLog.writefromsession(this, "sent mail with item entry %u to %s, with gold %u.", pItem->getEntry(), player_info->name, money); } pItem->DeleteMe(); } } if (money != 0 || COD != 0 || (!items.size() && player_info->acct != _player->GetSession()->GetAccountId())) { if (!sMailSystem.MailOption(MAIL_FLAG_DISABLE_HOUR_DELAY_FOR_ITEMS)) msg.delivery_time += 3600; // 1hr } // take the money _player->ModGold(-static_cast<int32_t>(cost)); // Fill in the rest of the info msg.player_guid = player_info->guid; msg.sender_guid = _player->getGuid(); msg.money = static_cast<uint32_t>(money); msg.cod = static_cast<uint32_t>(COD); msg.subject = subject; msg.body = body; // 30 day expiry time for unread mail if (!sMailSystem.MailOption(MAIL_FLAG_NO_EXPIRY)) msg.expire_time = (uint32_t)UNIXTIME + (TIME_DAY * MAIL_DEFAULT_EXPIRATION_TIME); else msg.expire_time = 0; msg.deleted_flag = false; msg.message_type = 0; msg.checked_flag = msg.body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY; // Great, all our info is filled in. Now we can add it to the other players mailbox. sMailSystem.DeliverMessage(player_info->guid, &msg); // Save/Update character's gold if they've received gold that is. This prevents a rollback. CharacterDatabase.Execute("UPDATE characters SET gold = %u WHERE guid = %u", _player->GetGold(), _player->m_playerInfo->guid); // Success packet :) SendMailError(MAIL_OK); }
void WorldSession::HandleSendMail(WorldPacket & recv_data ) { MailMessage msg; uint64 gameobject; uint32 unk2; uint8 itemcount; uint8 itemslot; uint8 i; uint64 itemguid; vector< Item* > items; vector< Item* >::iterator itr; string recepient; Item * pItem; //uint32 err = MAIL_OK; recv_data >> gameobject >> recepient; recv_data >> msg.subject >> msg.body >> msg.stationary; recv_data >> unk2 >> itemcount; //he simply ads ' ' after each '%' to string so that vsnprintf function would not find tokens in string char *t=(char*)msg.subject.c_str(); if( t[0] != 0 ) //if not an empty string { int ind=1; //make sure we do not have any recognizable tokens here while(t[ind]!=0 && ind<5000) { if(t[ind-1]=='%') t[ind]=' ';//just remove chars that could be interpreted ind++; } } msg.subject = t; t=(char*)msg.body.c_str(); if( t[0] != 0 ) //if not an empty string { int ind=1; while(t[ind]!=0 && ind<5000) { if(t[ind-1]=='%') t[ind]=' ';//just remove chars that could be interpreted ind++; } } msg.body = t; if( itemcount > 12 ) { //SystemMessage("Sorry, Ascent does not support sending multiple items at this time. (don't want to lose your item do you) Remove some items, and try again."); SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } for( i = 0; i < itemcount; ++i ) { recv_data >> itemslot; recv_data >> itemguid; pItem = _player->GetItemInterface()->GetItemByGUID( itemguid ); if( pItem == NULL || pItem->IsSoulbound() || pItem->HasFlag( ITEM_FIELD_FLAGS, ITEM_FLAG_CONJURED ) ) { SendMailError( MAIL_ERR_INTERNAL_ERROR ); return; } items.push_back( pItem ); } recv_data >> msg.money; recv_data >> msg.cod; // left over: (TODO- FIX ME BURLEX!) // uint32 // uint32 // uint8 // Search for the recipient PlayerInfo* player = ObjectMgr::getSingleton().GetPlayerInfoByName(recepient.c_str()); if( player == NULL ) { SendMailError( MAIL_ERR_RECIPIENT_NOT_FOUND ); return; } bool interfaction = false; if( sMailSystem.MailOption( MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION ) || (HasGMPermissions() && sMailSystem.MailOption( MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION_GM ) ) ) { interfaction = true; } // Check we're sending to the same faction (disable this for testing) if( player->team != _player->GetTeam() && !interfaction ) { SendMailError( MAIL_ERR_NOT_YOUR_ALLIANCE ); return; } // Check if we're sending mail to ourselves if( strcmp(player->name, _player->GetName()) == 0 && !GetPermissionCount()) { SendMailError(MAIL_ERR_CANNOT_SEND_TO_SELF); return; } if( msg.stationary == 0x3d || msg.stationary == 0x3d && !HasGMPermissions()) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } // Instant delivery time by default. msg.delivery_time = (uint32)UNIXTIME; // Set up the cost int32 cost = 0; if( !sMailSystem.MailOption( MAIL_FLAG_DISABLE_POSTAGE_COSTS ) && !( GetPermissionCount() && sMailSystem.MailOption( MAIL_FLAG_NO_COST_FOR_GM ) ) ) { cost = 30; } // Check for attached money if( msg.money > 0 ) cost += msg.money; if( cost < 0 ) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } // check that we have enough in our backpack if( (int32)_player->GetUInt32Value( PLAYER_FIELD_COINAGE ) < cost ) { SendMailError( MAIL_ERR_NOT_ENOUGH_MONEY ); return; } // Check for the item, and required item. if( !items.empty( ) ) { for( itr = items.begin(); itr != items.end(); ++itr ) { pItem = *itr; if( _player->GetItemInterface()->SafeRemoveAndRetreiveItemByGuid(pItem->GetGUID(), false) != pItem ) continue; // should never be hit. pItem->RemoveFromWorld(); pItem->SetOwner( NULL ); pItem->SaveToDB( INVENTORY_SLOT_NOT_SET, 0, true, NULL ); msg.items.push_back( pItem->GetUInt32Value(OBJECT_FIELD_GUID) ); if( GetPermissionCount() > 0 ) { /* log the message */ sGMLog.writefromsession(this, "sent mail with item entry %u to %s, with gold %u.", pItem->GetEntry(), player->name, msg.money); } pItem->DeleteMe(); } } if(msg.money != 0 || msg.cod != 0 || !msg.items.size() && player->acct != _player->GetSession()->GetAccountId()) { if(!sMailSystem.MailOption(MAIL_FLAG_DISABLE_HOUR_DELAY_FOR_ITEMS)) msg.delivery_time += 3600; // 1hr } // take the money _player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -cost); // Fill in the rest of the info msg.player_guid = player->guid; msg.sender_guid = _player->GetGUID(); // 30 day expiry time for unread mail mail if(!sMailSystem.MailOption(MAIL_FLAG_NO_EXPIRY)) msg.expire_time = (uint32)UNIXTIME + (TIME_DAY * MAIL_DEFAULT_EXPIRATION_TIME); else msg.expire_time = 0; msg.copy_made = false; msg.read_flag = false; msg.deleted_flag = false; msg.message_type = 0; // Great, all our info is filled in. Now we can add it to the other players mailbox. sMailSystem.DeliverMessage(player->guid, &msg); // Success packet :) SendMailError(MAIL_OK); }
void WorldSession::HandleSendMail(WorldPacket & recv_data ) { MailMessage msg; uint64 gameobject; uint32 unk2; uint8 itemcount; uint8 itemslot; uint8 i; uint64 itemguid; vector< ItemPointer > items; vector< ItemPointer >::iterator itr; string recepient; ItemPointer pItem; int8 real_item_slot; recv_data >> gameobject >> recepient; // Search for the recipient PlayerInfo* player = ObjectMgr::getSingleton().GetPlayerInfoByName(recepient.c_str()); if( player == NULL ) { SendMailError(MAIL_ERR_RECIPIENT_NOT_FOUND); return; } msg.player_guid = player->guid; msg.sender_guid = _player->GetGUID(); recv_data >> msg.subject >> msg.body >> msg.stationary; // Check attached items recv_data >> unk2 >> itemcount; for( i = 0; i < itemcount; ++i ) { recv_data >> itemslot; recv_data >> itemguid; pItem = _player->GetItemInterface()->GetItemByGUID( itemguid ); real_item_slot = _player->GetItemInterface()->GetInventorySlotByGuid( itemguid ); if( pItem == NULL || pItem->IsSoulbound() || pItem->HasFlag( ITEM_FIELD_FLAGS, ITEM_FLAG_CONJURED ) || ( pItem->IsContainer() && (TO_CONTAINER( pItem ))->HasItems() ) || real_item_slot >= 0 && real_item_slot < INVENTORY_SLOT_ITEM_START ) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } items.push_back( pItem ); } if( items.size() > 12 || msg.body.find("%") != string::npos || msg.subject.find("%") != string::npos) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } recv_data >> msg.money; recv_data >> msg.cod; // left over: (TODO- FIX ME BURLEX!) // uint32 // uint32 // uint8 // Check if we're sending mail to ourselves if(msg.player_guid == msg.sender_guid && !GetPermissionCount()) { SendMailError(MAIL_ERR_CANNOT_SEND_TO_SELF); return; } // Check stationary if( msg.stationary == 0x3d && !HasGMPermissions()) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } // Set up the cost int32 cost = 0; if( !sMailSystem.MailOption( MAIL_FLAG_DISABLE_POSTAGE_COSTS ) && !( GetPermissionCount() && sMailSystem.MailOption( MAIL_FLAG_NO_COST_FOR_GM ) ) ) { cost = 30; } // Check for attached money if( msg.money > 0 ) cost += msg.money; if( cost < 0 ) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } // check that we have enough in our backpack if( (int32)_player->GetUInt32Value( PLAYER_FIELD_COINAGE ) < cost ) { SendMailError( MAIL_ERR_NOT_ENOUGH_MONEY ); return; } // Check we're sending to the same faction (disable this for testing) bool interfaction = (sMailSystem.MailOption( MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION ) || (HasGMPermissions() && sMailSystem.MailOption( MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION_GM ) )); if(!interfaction) { if(player->team != _player->GetTeam()) { SendMailError( MAIL_ERR_NOT_YOUR_ALLIANCE ); return; } } msg.message_id = 0; msg.message_type = 0; msg.copy_made = false; msg.read_flag = false; msg.deleted_flag = false; msg.returned_flag = false; msg.delivery_time = (uint32)UNIXTIME; if(msg.money != 0 || msg.cod != 0 || !items.size() && player->acct != _player->GetSession()->GetAccountId()) { if(!sMailSystem.MailOption(MAIL_FLAG_DISABLE_HOUR_DELAY_FOR_ITEMS)) msg.delivery_time += 3600; // +1hr } msg.expire_time = 0; if(!sMailSystem.MailOption(MAIL_FLAG_NO_EXPIRY)) { msg.expire_time = (uint32)UNIXTIME + (TIME_DAY * 30); if (msg.cod != 0) { msg.expire_time = (uint32)UNIXTIME + (TIME_DAY * 3); } } // Sending Message // take the money _player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -cost); // Check for the item, and required item. if( !items.empty( ) ) { for( itr = items.begin(); itr != items.end(); ++itr ) { pItem = *itr; if( _player->GetItemInterface()->SafeRemoveAndRetreiveItemByGuid(pItem->GetGUID(), false) != pItem ) continue; // should never be hit. pItem->RemoveFromWorld(); pItem->SetOwner( NULLPLR ); pItem->SaveToDB( INVENTORY_SLOT_NOT_SET, 0, true, NULL ); msg.items.push_back( pItem->GetUInt32Value(OBJECT_FIELD_GUID) ); if( GetPermissionCount() > 0 ) { /* log the message */ sGMLog.writefromsession(this, "sent mail with item entry %u to %s, with gold %u.", pItem->GetEntry(), player->name, msg.money); } pItem->Destructor(); } } // Great, all our info is filled in. Now we can add it to the other players mailbox. sMailSystem.DeliverMessage(&msg); // Success packet :) SendMailError(MAIL_OK); }
void WorldSession::HandleSetTradeItem(WorldPacket & recv_data) { #ifdef FORCED_GM_TRAINEE_MODE if( CanUseCommand('k') && !HasGMPermissions() ) { GetPlayer()->BroadcastMessage( "You are not allowed to use this feature" ); return; } #endif if(_player->mTradeTarget == 0) { sLog.outDebug("HandleSetTradeItem: missing trade target\n"); return; } if(!_player->IsInWorld()) { sLog.outDebug("HandleSetTradeItem: not in world\n"); return; } CHECK_PACKET_SIZE(recv_data, 3); uint8 TradeSlot = recv_data.contents()[1]; uint8 SourceSlot = recv_data.contents()[2]; uint8 SourceBag = recv_data.contents()[0]; Player * pTarget = _player->GetTradeTarget(); Item * pItem = _player->GetItemInterface()->GetInventoryItem(SourceBag, SourceSlot); if( pTarget == NULL || pItem == 0 || TradeSlot >= TRADE_TOTAL_TRADE_SLOTS || ( TradeSlot < TRADE_MAX_TRADABLE_ITEMS && pItem->IsSoulbound() ) ) { sLog.outDebug("HandleSetTradeItem: target missing or incorect item/slot. target(%u),item(%u),slot(%u))\n",pTarget != NULL,pItem != 0,TradeSlot ); return; } if( TradeSlot < TRADE_MAX_TRADABLE_ITEMS && pItem->IsAccountbound() ) { PlayerInfo* pinfo = ObjectMgr::getSingleton().GetPlayerInfo(_player->mTradeTarget); if(pinfo == NULL || GetAccountId() != pinfo->acct) // can't trade account-based items { sLog.outDebug("HandleSetTradeItem: item is account bound\n"); return; } } /* if( pItem->IsContainer() ) { if(_player->GetItemInterface()->IsBagSlot(SourceSlot)) return;*/ packetSMSG_TRADE_STATUS data; memset( &data, 0, sizeof( data ) ); // data.trade_status = TRADE_STATUS_STATE_CHANGED; // OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); // pTarget->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); pTarget->mTradeStatus = TRADE_STATUS_STATE_CHANGED; _player->mTradeStatus = TRADE_STATUS_STATE_CHANGED; if( pItem->IsContainer() ) { if( SafeContainerCast(pItem)->HasItems() ) { _player->GetItemInterface()->BuildInventoryChangeError(pItem,0, INV_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS); //--trade cancel data.trade_status = TRADE_STATUS_CANCELLED; OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); Player * plr = _player->GetTradeTarget(); if(plr) { if(plr->m_session && plr->m_session->GetSocket()) plr->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); plr->ResetTradeVariables(); } _player->ResetTradeVariables(); sLog.outDebug("HandleSetTradeItem: Container with items cannot be traded\n"); return; } } //well that covers all slots i think (MAX_TRADE_TRADABLE_ITEMS is temporal slot) if(TradeSlot < TRADE_MAX_TRADABLE_ITEMS) { if(pItem->IsSoulbound()) { sCheatLog.writefromsession(this, "tried to cheat trade a soulbound item"); sLog.outDebug("HandleSetTradeItem: Cannot trade soulbound item\n"); Item *ti = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SourceBag, SourceSlot, false); if( ti ) { ti->DeleteFromDB(); ti->DeleteMe(); ti = NULL; } string sReason = "Soulboundtrade 1"; uint32 uBanTime = (uint32)UNIXTIME + 60*60; //60 minutes ban _player->SetBanned( uBanTime, sReason ); sEventMgr.AddEvent( _player, &Player::_Kick, EVENT_PLAYER_KICK, 7000, 1, 0 ); return; //item is not valid anymore ! } //this was checked earlier ? How the hack did we get here again ? else if(pItem->IsAccountbound() && pTarget->GetSession() && pTarget->GetSession()->GetAccountId() != GetAccountId() ) { PlayerInfo* pinfo = ObjectMgr::getSingleton().GetPlayerInfo(_player->mTradeTarget); if(pinfo == NULL || GetAccountId() != pinfo->acct) // can't trade account-based items { sLog.outDebug("HandleSetTradeItem: Cannot trade account bound item\n"); sCheatLog.writefromsession(this, "tried to cheat trade an accountbound item"); Item *ti = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SourceBag, SourceSlot, false); if( ti ) { ti->DeleteFromDB(); ti->DeleteMe(); ti = NULL; } string sReason = "Account bound itemtrade"; uint32 uBanTime = (uint32)UNIXTIME + 60*60; //60 minutes ban _player->SetBanned( uBanTime, sReason ); sEventMgr.AddEvent( _player, &Player::_Kick, EVENT_PLAYER_KICK, 7000, 1, 0 ); return; //item is not valid anymore ! } } } for(uint32 i = 0; i < TRADE_TOTAL_TRADE_SLOTS; ++i) { // duping little shits if( TradeSlot != i && ( _player->mTradeItems[i] == pItem || pTarget->mTradeItems[i] == pItem ) ) { sCheatLog.writefromsession(this, "tried to dupe an item through trade"); Item *ti = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SourceBag, SourceSlot, false); if( ti ) { ti->DeleteFromDB(); ti->DeleteMe(); ti = NULL; } GetPlayer()->SoftDisconnect(); sLog.outDebug("HandleSetTradeItem: item dupe detected\n"); return; } } if( SourceBag <= INVENTORY_SLOT_NOT_SET && //we are removing from our direct character slot and not from a bag SourceSlot >= INVENTORY_SLOT_BAG_START && SourceSlot < INVENTORY_SLOT_BAG_END) { //More duping woohoo Item *ti = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SourceBag, SourceSlot, false); if( ti ) { ti->DeleteFromDB(); ti->DeleteMe(); ti = NULL; } sCheatLog.writefromsession(this, "tried to cheat trade a soulbound item"); string sReason = "trading from bagslot"; uint32 uBanTime = (uint32)UNIXTIME + 60*60; //60 minutes ban _player->SetBanned( uBanTime, sReason ); sEventMgr.AddEvent( _player, &Player::_Kick, EVENT_PLAYER_KICK, 7000, 1, 0 ); sLog.outDebug("HandleSetTradeItem: Cannot trade from bagslot\n"); return; //item is not valid anymore ! } _player->mTradeItems[TradeSlot] = pItem; _player->SendTradeUpdate(); }
void WorldSession::FullLogin(Player * plr) { Log.Debug("WorldSession", "Fully loading player %u", plr->GetLowGUID()); SetPlayer(plr); m_MoverWoWGuid.Init(plr->GetGUID()); MapMgr *mgr = sInstanceMgr.GetInstance(static_cast< Object* >( plr )); if (mgr && mgr->m_battleground) { /* Don't allow player to login into a bg that has ended or is full */ if (mgr->m_battleground->HasEnded() == true || mgr->m_battleground->HasFreeSlots(plr->GetTeamInitial(), mgr->m_battleground->GetType() == false)) { mgr = NULL; } } /* Trying to log to an instance that doesn't exists anymore? */ if (!mgr) { if(!IS_INSTANCE(plr->m_bgEntryPointMap)) { plr->m_position.x = plr->m_bgEntryPointX; plr->m_position.y = plr->m_bgEntryPointY; plr->m_position.z = plr->m_bgEntryPointZ; plr->m_position.o = plr->m_bgEntryPointO; plr->m_mapId = plr->m_bgEntryPointMap; } else { plr->m_position.x = plr->GetBindPositionX(); plr->m_position.y = plr->GetBindPositionY(); plr->m_position.z = plr->GetBindPositionZ(); plr->m_position.o = 0; plr->m_mapId = plr->GetBindMapId(); } } // copy to movement array movement_packet[0] = m_MoverWoWGuid.GetNewGuidMask(); memcpy(&movement_packet[1], m_MoverWoWGuid.GetNewGuid(), m_MoverWoWGuid.GetNewGuidLen()); /* world preload */ packetSMSG_LOGIN_VERIFY_WORLD vwpck; vwpck.MapId = plr->GetMapId(); vwpck.O = plr->GetOrientation(); vwpck.X = plr->GetPositionX(); vwpck.Y = plr->GetPositionY(); vwpck.Z = plr->GetPositionZ(); OutPacket( SMSG_LOGIN_VERIFY_WORLD, sizeof(packetSMSG_LOGIN_VERIFY_WORLD), &vwpck ); // send voicechat state - active/inactive /* {SERVER} Packet: (0x03C7) UNKNOWN PacketSize = 2 |------------------------------------------------|----------------| |00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF| |------------------------------------------------|----------------| |02 01 |.. | ------------------------------------------------------------------- */ #ifndef USING_BIG_ENDIAN StackWorldPacket<20> datab(SMSG_VOICE_SYSTEM_STATUS); #else WorldPacket datab(SMSG_VOICE_SYSTEM_STATUS, 20); #endif #ifdef VOICE_CHAT datab.Initialize(SMSG_VOICE_SYSTEM_STATUS); datab << uint8(2) << uint8(sVoiceChatHandler.CanUseVoiceChat() ? 1 : 0); SendPacket(&datab); #else datab.Initialize(SMSG_VOICE_SYSTEM_STATUS); datab << uint8(2) << uint8(0); #endif plr->UpdateAttackSpeed(); /*if(plr->getLevel()>PLAYER_LEVEL_CAP_70) plr->SetUInt32Value(UNIT_FIELD_LEVEL,PLAYER_LEVEL_CAP_70);*/ // enable trigger cheat by default // plr->TriggerpassCheat = HasGMPermissions(); // Make sure our name exists (for premade system) PlayerInfo * info = objmgr.GetPlayerInfo(plr->GetLowGUID()); if(info == 0) { info = new PlayerInfo; info->cl = plr->getClass(); info->gender = plr->getGender(); info->guid = plr->GetLowGUID(); info->name = strdup(plr->GetName()); info->lastLevel = plr->getLevel(); info->lastOnline = UNIXTIME; info->lastZone = plr->GetZoneId(); info->race = plr->getRace(); info->team = plr->GetTeam(); info->guild=NULL; info->guildRank=NULL; info->guildMember=NULL; info->m_Group=0; info->subGroup=0; objmgr.AddPlayerInfo(info); } plr->m_playerInfo = info; if(plr->m_playerInfo->guild) { plr->m_uint32Values[PLAYER_GUILDID] = plr->m_playerInfo->guild->GetGuildId(); plr->m_uint32Values[PLAYER_GUILDRANK] = plr->m_playerInfo->guildRank->iId; } info->m_loggedInPlayer = plr; // account data == UI config #ifndef USING_BIG_ENDIAN StackWorldPacket<128> data(SMSG_ACCOUNT_DATA_MD5); #else WorldPacket data(SMSG_ACCOUNT_DATA_MD5, 128); #endif MD5Hash md5hash; for (int i = 0; i < 8; i++) { AccountDataEntry* acct_data = GetAccountData(i); if (!acct_data->data) { data << uint64(0) << uint64(0); // Nothing. continue; } md5hash.Initialize(); md5hash.UpdateData((const uint8*)acct_data->data, acct_data->sz); md5hash.Finalize(); #ifndef USING_BIG_ENDIAN data.Write(md5hash.GetDigest(), MD5_DIGEST_LENGTH); #else data.append(md5hash.GetDigest(), MD5_DIGEST_LENGTH); #endif } SendPacket(&data); // Set TIME OF LOGIN CharacterDatabase.Execute("UPDATE characters SET online = 1 WHERE guid = %u" , plr->GetLowGUID()); bool enter_world = true; #ifndef CLUSTERING // Find our transporter and add us if we're on one. if(plr->m_TransporterGUID != 0) { Transporter * pTrans = objmgr.GetTransporter(GUID_LOPART(plr->m_TransporterGUID)); if(pTrans) { if(plr->isDead()) { plr->ResurrectPlayer(); plr->SetUInt32Value(UNIT_FIELD_HEALTH, plr->GetUInt32Value(UNIT_FIELD_MAXHEALTH)); plr->SetUInt32Value(UNIT_FIELD_POWER1, plr->GetUInt32Value(UNIT_FIELD_MAXPOWER1)); } float c_tposx = pTrans->GetPositionX() + plr->m_TransporterX; float c_tposy = pTrans->GetPositionY() + plr->m_TransporterY; float c_tposz = pTrans->GetPositionZ() + plr->m_TransporterZ; if(plr->GetMapId() != pTrans->GetMapId()) // loaded wrong map { plr->SetMapId(pTrans->GetMapId()); #ifndef USING_BIG_ENDIAN StackWorldPacket<20> dataw(SMSG_NEW_WORLD); #else WorldPacket dataw(SMSG_NEW_WORLD, 20); #endif dataw << pTrans->GetMapId() << c_tposx << c_tposy << c_tposz << plr->GetOrientation(); SendPacket(&dataw); // shit is sent in worldport ack. enter_world = false; } plr->SetPosition(c_tposx, c_tposy, c_tposz, plr->GetOrientation(), false); plr->m_CurrentTransporter = pTrans; pTrans->AddPlayer(plr); } } #endif if(HasGMPermissions()) { //Toggle for admin chat color. --Hemi if(_accountId == 1) //Hemi's chat color. Greenish.. GetPlayer()->chatColor = "|cff96E798 "; else if(_accountId == 3) //Paws' chat color. Magneta. GetPlayer()->chatColor ="|cFFF52887 "; else if(CanUseCommand('z')) //Admin chat colors GetPlayer()->chatColor = MSG_COLOR_LIGHTBLUE; else if(CanUseCommand('a') && !CanUseCommand('z')) //Co-Admin chat color GetPlayer()->chatColor = MSG_COLOR_LIGHTRED; } Log.Debug("Login", "Player %s logged in.", plr->GetName()); sLog.outString("[%s] has logged in.", plr->GetName()); if(plr->GetTeam() == 1) sWorld.HordePlayers++; else sWorld.AlliancePlayers++; if(plr->m_FirstLogin && !HasGMPermissions()) { uint32 racecinematic = plr->myRace->cinematic_id; #ifdef USING_BIG_ENDIAN swap32(&racecinematic); #endif OutPacket(SMSG_TRIGGER_CINEMATIC, 4, &racecinematic); #ifdef _TEST_EXTENDED_FEATURES_ const int classtext[] ={0,5,6,8,9,11,0,4,3,7,0,10}; sWorld.SendLocalizedWorldText(true,"{65}",classtext[ (uint32)plr->getClass() ] , plr->GetName() , (plr->GetTeam() ? "{63}":"{64}") ); #endif } sLog.outDetail( "WORLD: Created new player for existing players (%s)", plr->GetName() ); // Login time, will be used for played time calc plr->m_playedtime[2] = (uint32)UNIXTIME; //Issue a message telling all guild members that this player has signed on if(plr->IsInGuild()) { Guild *pGuild = plr->m_playerInfo->guild; if(pGuild) { WorldPacket data(50); data.Initialize(SMSG_GUILD_EVENT); data << uint8(GUILD_EVENT_MOTD); data << uint8(0x01); if(pGuild->GetMOTD()) data << pGuild->GetMOTD(); else data << uint8(0); SendPacket(&data); pGuild->LogGuildEvent(GUILD_EVENT_HASCOMEONLINE, 1, plr->GetName()); } } // Send online status to people having this char in friendlist _player->Social_TellFriendsOnline(); // send friend list (for ignores) _player->Social_SendFriendList(7); #ifndef GM_TICKET_MY_MASTER_COMPATIBLE GM_Ticket * ticket = objmgr.GetGMTicketByPlayer(_player->GetGUID()); if(ticket != NULL) { //Send status change to gm_sync_channel Channel *chn = channelmgr.GetChannel(sWorld.getGmClientChannel().c_str(), _player); if(chn) { std::stringstream ss; ss << "GmTicket:" << GM_TICKET_CHAT_OPCODE_ONLINESTATE; ss << ":" << ticket->guid; ss << ":1"; chn->Say(_player, ss.str().c_str(), NULL, true); } } #endif // Send MOTD _player->BroadcastMessage(sWorld.GetMotd()); // Send revision (if enabled) #ifdef WIN32 _player->BroadcastMessage("Powered by: %sArcEmu %s r%u/%s-Win-%s %s(Please report ALL bugs to www.ArcEmu.org/forums/)", MSG_COLOR_WHITE, BUILD_TAG, BUILD_REVISION, CONFIG, ARCH, MSG_COLOR_LIGHTBLUE); #else _player->BroadcastMessage("Powered by: %sArcEmu %s r%u/%s-%s %s(Please report ALL bugs to www.ArcEmu.org/forums/)", MSG_COLOR_WHITE, BUILD_TAG, BUILD_REVISION, PLATFORM_TEXT, ARCH, MSG_COLOR_LIGHTBLUE); #endif if(sWorld.SendStatsOnJoin || HasGMPermissions() ) { _player->BroadcastMessage("Online Players: %s%u |rPeak: %s%u|r Accepted Connections: %s%u", MSG_COLOR_WHITE, sWorld.GetSessionCount(), MSG_COLOR_WHITE, sWorld.PeakSessionCount, MSG_COLOR_WHITE, sWorld.mAcceptedConnections); } //Set current RestState if( plr->m_isResting) // We are resting at an inn , turn on Zzz plr->ApplyPlayerRestState(true); //Calculate rest bonus if there is time between lastlogoff and now if( plr->m_timeLogoff > 0 && plr->GetUInt32Value(UNIT_FIELD_LEVEL) < plr->GetUInt32Value(PLAYER_FIELD_MAX_LEVEL)) // if timelogoff = 0 then it's the first login { uint32 currenttime = (uint32)UNIXTIME; uint32 timediff = currenttime - plr->m_timeLogoff; //Calculate rest bonus if( timediff > 0 ) plr->AddCalculatedRestXP(timediff); } #ifdef CLUSTERING plr->SetInstanceID(forced_instance_id); plr->SetMapId(forced_map_id); #else sHookInterface.OnEnterWorld2(_player); #endif if(info->m_Group) info->m_Group->Update(); if(enter_world && !_player->GetMapMgr()) { plr->AddToWorld(); } objmgr.AddPlayer(_player); if(info->m_Group == NULL) plr->SendDungeonDifficulty(); }
void WorldSession::HandleArenaTeamAddMemberOpcode(WorldPacket & recv_data) { string player_name; uint32 teamId; recv_data >> teamId >> player_name; ArenaTeam * pTeam = objmgr.GetArenaTeamById(teamId); if( !pTeam ) return; if(!pTeam->HasMember(GetPlayer()->GetLowGUID())) { SendNotInArenaTeamPacket(uint8(pTeam->GetPlayersPerTeam())); return; } Player * plr = objmgr.GetPlayer(player_name.c_str(), false); if(plr == NULL) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", player_name, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S); return; } if(pTeam->m_leader != _player->GetLowGUID()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS); return; } if(plr->getLevel() < 70) { SystemMessage("%s is not high enough level to join your team", plr->GetName()); return; } if(plr->m_playerInfo->arenaTeam[pTeam->m_type] != NULL) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, plr->GetName(), "", ERR_ALREADY_IN_ARENA_TEAM_S); return; } if(plr->m_arenateaminviteguid != 0) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, plr->GetName(), "", ERR_ALREADY_INVITED_TO_ARENA_TEAM_S); return; } if(plr->GetTeam() != _player->GetTeam() && !HasGMPermissions()) { SystemMessage("You cannot invite players from the opposing alliance"); return; } if(pTeam->m_memberCount >= pTeam->GetPlayersPerTeam()) { SystemMessage("%s is full.", pTeam->m_name); return; } plr->m_arenateaminviteguid = _player->m_playerInfo->arenaTeam[pTeam->m_type]->m_id; WorldPacket data(SMSG_ARENA_TEAM_INVITE, 40); data << _player->GetName(); data << _player->m_playerInfo->arenaTeam[pTeam->m_type]->m_name; plr->GetSession()->SendPacket(&data); }