bool ChatHandler::HandleGOSpawn(const char *args, WorldSession *m_session) { std::stringstream sstext; char* pEntryID = strtok((char*)args, " "); if (!pEntryID) return false; uint32 EntryID = atoi(pEntryID); bool Save = false; char* pSave = strtok(NULL, " "); if (pSave) Save = (atoi(pSave)>0?true:false); GameObjectInfo* goi = GameObjectNameStorage.LookupEntry(EntryID); if(!goi) { sstext << "GameObject Info '" << EntryID << "' Not Found" << '\0'; SystemMessage(m_session, sstext.str().c_str()); return true; } sLog.outDebug("Spawning GameObject By Entry '%u'", EntryID); sstext << "Spawning GameObject By Entry '" << EntryID << "'" << '\0'; SystemMessage(m_session, sstext.str().c_str()); GameObject *go = m_session->GetPlayer()->GetMapMgr()->CreateGameObject(); Player *chr = m_session->GetPlayer(); uint32 mapid = chr->GetMapId(); float x = chr->GetPositionX(); float y = chr->GetPositionY(); float z = chr->GetPositionZ(); float o = chr->GetOrientation(); go->SetInstanceID(chr->GetInstanceID()); go->CreateFromProto(EntryID,mapid,x,y,z,o); /* f**k blizz coordinate system */ go->SetFloatValue(GAMEOBJECT_ROTATION_02, sinf(o / 2)); go->SetFloatValue(GAMEOBJECT_ROTATION_03, cosf(o / 2)); go->PushToWorld(m_session->GetPlayer()->GetMapMgr()); // Create sapwn instance GOSpawn * gs = new GOSpawn; gs->entry = go->GetEntry(); gs->facing = go->GetOrientation(); gs->faction = go->GetUInt32Value(GAMEOBJECT_FACTION); gs->flags = go->GetUInt32Value(GAMEOBJECT_FLAGS); gs->id = objmgr.GenerateGameObjectSpawnID(); gs->o = go->GetFloatValue(GAMEOBJECT_ROTATION); gs->o1 = go->GetFloatValue(GAMEOBJECT_ROTATION_01); gs->o2 = go->GetFloatValue(GAMEOBJECT_ROTATION_02); gs->o3 = go->GetFloatValue(GAMEOBJECT_ROTATION_03); gs->scale = go->GetFloatValue(OBJECT_FIELD_SCALE_X); gs->x = go->GetPositionX(); gs->y = go->GetPositionY(); gs->z = go->GetPositionZ(); gs->state = go->GetUInt32Value(GAMEOBJECT_STATE); //gs->stateNpcLink = 0; uint32 cx = m_session->GetPlayer()->GetMapMgr()->GetPosX(m_session->GetPlayer()->GetPositionX()); uint32 cy = m_session->GetPlayer()->GetMapMgr()->GetPosY(m_session->GetPlayer()->GetPositionY()); m_session->GetPlayer()->GetMapMgr()->GetBaseMap()->GetSpawnsListAndCreate(cx,cy)->GOSpawns.push_back(gs); go->m_spawn = gs; go->spawnid = gs->id; //go->AddToWorld(); if(Save == true) { // If we're saving, create template and add index go->SaveToDB(); } return true; }
void WorldSession::HandleMovementOpcodes(WorldPacket & recvData) { uint16 opcode = recvData.GetOpcode(); Unit* mover = _player->m_mover; ASSERT(mover != NULL); // there must always be a mover Player* plrMover = mover->ToPlayer(); // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck if (plrMover && plrMover->IsBeingTeleported()) { recvData.rfinish(); // prevent warnings spam return; } /* extract packet */ uint64 guid; recvData.readPackGUID(guid); MovementInfo movementInfo; movementInfo.guid = guid; ReadMovementInfo(recvData, &movementInfo); recvData.rfinish(); // prevent warnings spam // pussywizard: typical check for incomming movement packets if (!mover || !mover->IsInWorld() || mover->IsDuringRemoveFromWorld() || guid != mover->GetGUID()) return; if (!movementInfo.pos.IsPositionValid()) { recvData.rfinish(); // prevent warnings spam return; } if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) { // T_POS ON VEHICLES! if (mover->GetVehicle()) movementInfo.transport.pos = mover->m_movementInfo.transport.pos; // transports size limited // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped) if (movementInfo.transport.pos.GetPositionX() > 75.0f || movementInfo.transport.pos.GetPositionY() > 75.0f || movementInfo.transport.pos.GetPositionZ() > 75.0f || movementInfo.transport.pos.GetPositionX() < -75.0f || movementInfo.transport.pos.GetPositionY() < -75.0f || movementInfo.transport.pos.GetPositionZ() < -75.0f) { recvData.rfinish(); // prevent warnings spam return; } if (!Trinity::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.transport.pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.transport.pos.GetPositionY(), movementInfo.pos.GetPositionZ() + movementInfo.transport.pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.transport.pos.GetOrientation())) { recvData.rfinish(); // prevent warnings spam return; } // if we boarded a transport, add us to it if (plrMover) { if (!plrMover->GetTransport()) { if (Transport* transport = plrMover->GetMap()->GetTransport(movementInfo.transport.guid)) { plrMover->m_transport = transport; transport->AddPassenger(plrMover); } } else if (plrMover->GetTransport()->GetGUID() != movementInfo.transport.guid) { bool foundNewTransport = false; plrMover->m_transport->RemovePassenger(plrMover); if (Transport* transport = plrMover->GetMap()->GetTransport(movementInfo.transport.guid)) { foundNewTransport = true; plrMover->m_transport = transport; transport->AddPassenger(plrMover); } if (!foundNewTransport) { plrMover->m_transport = NULL; movementInfo.transport.Reset(); } } } if (!mover->GetTransport() && !mover->GetVehicle()) movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT; } else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave { plrMover->m_transport->RemovePassenger(plrMover); plrMover->m_transport = NULL; movementInfo.transport.Reset(); } if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater()) { // now client not include swimming flag in case jumping under water plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ())); } if (plrMover)//Hook for OnPlayerMove sScriptMgr->OnPlayerMove(plrMover, movementInfo, opcode); // Dont allow to turn on walking if charming other player if (mover->GetGUID() != _player->GetGUID()) movementInfo.flags &= ~MOVEMENTFLAG_WALKING; uint32 mstime = World::GetGameTimeMS(); /*----------------------*/ if(m_clientTimeDelay == 0) m_clientTimeDelay = mstime > movementInfo.time ? std::min(mstime - movementInfo.time, (uint32)100) : 0; // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE if (mover->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE)) { // Xinef: skip moving packets if (movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_MOVING)) return; movementInfo.pos.Relocate(mover->GetPositionX(), mover->GetPositionY(), mover->GetPositionZ()); if (mover->GetTypeId() == TYPEID_UNIT) { movementInfo.transport.guid = mover->m_movementInfo.transport.guid; movementInfo.transport.pos.Relocate(mover->m_movementInfo.transport.pos.GetPositionX(), mover->m_movementInfo.transport.pos.GetPositionY(), mover->m_movementInfo.transport.pos.GetPositionZ()); movementInfo.transport.seat = mover->m_movementInfo.transport.seat; } } /* process position-change */ WorldPacket data(opcode, recvData.size()); //movementInfo.time = movementInfo.time + m_clientTimeDelay + MOVEMENT_PACKET_TIME_DELAY; movementInfo.time = mstime; // pussywizard: set to time of relocation (server time), constant addition may smoothen movement clientside, but client sees target on different position than the real serverside position movementInfo.guid = mover->GetGUID(); WriteMovementInfo(&data, &movementInfo); mover->SendMessageToSet(&data, _player); mover->m_movementInfo = movementInfo; // this is almost never true (pussywizard: only one packet when entering vehicle), normally use mover->IsVehicle() if (mover->GetVehicle()) { mover->SetOrientation(movementInfo.pos.GetOrientation()); mover->UpdatePosition(movementInfo.pos); return; } // pussywizard: previously always mover->UpdatePosition(movementInfo.pos); if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT && mover->GetTransport()) { float x, y, z, o; movementInfo.transport.pos.GetPosition(x, y, z, o); mover->GetTransport()->CalculatePassengerPosition(x, y, z, &o); mover->UpdatePosition(x, y, z, o); } else mover->UpdatePosition(movementInfo.pos); // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map). // Xinef: moved it here, previously StopMoving function called when player died relocated him to last saved coordinates (which were in air) if (opcode == MSG_MOVE_FALL_LAND && plrMover && !plrMover->IsInFlight() && (!plrMover->GetTransport() || plrMover->GetTransport()->IsStaticTransport())) plrMover->HandleFall(movementInfo); // Xinef: interrupt parachutes upon falling or landing in water if (opcode == MSG_MOVE_FALL_LAND || opcode == MSG_MOVE_START_SWIM) mover->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_LANDING); // Parachutes if (plrMover) // nothing is charmed, or player charmed { if (plrMover->IsSitState() && (movementInfo.flags & (MOVEMENTFLAG_MASK_MOVING | MOVEMENTFLAG_MASK_TURNING))) plrMover->SetStandState(UNIT_STAND_STATE_STAND); plrMover->UpdateFallInformationIfNeed(movementInfo, opcode); if (movementInfo.pos.GetPositionZ() < plrMover->GetMap()->GetMinHeight(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY())) if (!plrMover->GetBattleground() || !plrMover->GetBattleground()->HandlePlayerUnderMap(_player)) { if (plrMover->IsAlive()) { plrMover->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_IS_OUT_OF_BOUNDS); plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth()); // player can be alive if GM if (plrMover->IsAlive()) plrMover->KillPlayer(); } else if (!plrMover->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IS_OUT_OF_BOUNDS)) { WorldSafeLocsEntry const* grave = sObjectMgr->GetClosestGraveyard(plrMover->GetPositionX(), plrMover->GetPositionY(), plrMover->GetPositionZ(), plrMover->GetMapId(), plrMover->GetTeamId()); if ( grave) plrMover->TeleportTo(grave->map_id, grave->x, grave->y, grave->z, plrMover->GetOrientation()); plrMover->Relocate(grave->x, grave->y, grave->z, plrMover->GetOrientation()); } plrMover->StopMovingOnCurrentPos(); // pussywizard: moving corpse can't release spirit } } }
void WorldSession::HandlePlayerLoginOpcode( WorldPacket & recv_data ) { WorldPacket data; uint64 playerGuid = 0; DEBUG_LOG( "WORLD: Recvd Player Logon Message" ); recv_data >> playerGuid; Player* plr = new Player(this); ASSERT(plr); plr->SetSession(this); if(!plr->LoadFromDB(GUID_LOPART(playerGuid))) return; //plr->_RemoveAllItemMods(); SetPlayer(plr); data.Initialize( SMSG_ACCOUNT_DATA_MD5 ); for(int i = 0; i < 80; i++) data << uint8(0); SendPacket(&data); sChatHandler.FillSystemMessageData(&data, this, sWorld.GetMotd()); SendPacket( &data ); DEBUG_LOG( "WORLD: Sent motd (SMSG_MESSAGECHAT)" ); // home bind stuff Field *fields; QueryResult *result7 = sDatabase.PQuery("SELECT COUNT(`guid`) FROM `character_homebind` WHERE `guid` = '%u'", GUID_LOPART(playerGuid)); if (result7) { int cnt; fields = result7->Fetch(); cnt = fields[0].GetUInt32(); if ( cnt > 0 ) { QueryResult *result4 = sDatabase.PQuery("SELECT `map`,`zone`,`position_x`,`position_y`,`position_z` FROM `character_homebind` WHERE `guid` = '%u'", GUID_LOPART(playerGuid)); assert(result4); fields = result4->Fetch(); data.Initialize (SMSG_BINDPOINTUPDATE); data << fields[2].GetFloat() << fields[3].GetFloat() << fields[4].GetFloat(); data << fields[0].GetUInt32(); data << fields[1].GetUInt32(); SendPacket (&data); DEBUG_LOG("Setting player home position: mapid is: %u, zoneid is %u, X is %f, Y is %f, Z is %f\n",fields[0].GetUInt32(),fields[1].GetUInt32(),fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat()); delete result4; } else { int plrace = GetPlayer()->getRace(); int plclass = GetPlayer()->getClass(); QueryResult *result5 = sDatabase.PQuery("SELECT `map`,`zone`,`position_x`,`position_y`,`position_z` FROM `playercreateinfo` WHERE `race` = '%u' AND `class` = '%u'", plrace, plclass); assert(result5); fields = result5->Fetch(); // store and send homebind for player sDatabase.PExecute("INSERT INTO `character_homebind` (`guid`,`map`,`zone`,`position_x`,`position_y`,`position_z`) VALUES ('%u', '%u', '%u', '%f', '%f', '%f')", GUID_LOPART(playerGuid), fields[0].GetUInt32(), fields[1].GetUInt32(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat()); data.Initialize (SMSG_BINDPOINTUPDATE); data << fields[2].GetFloat() << fields[3].GetFloat() << fields[4].GetFloat(); data << fields[0].GetUInt32(); data << fields[1].GetUInt32(); SendPacket (&data); DEBUG_LOG("Setting player home position: mapid is: %u, zoneid is %u, X is %f, Y is %f, Z is %f\n",fields[0].GetUInt32(),fields[1].GetUInt32(),fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat()); delete result5; } delete result7; } data.Initialize( SMSG_TUTORIAL_FLAGS ); for (int i = 0; i < 8; i++) data << uint32( GetPlayer()->GetTutorialInt(i) ); SendPacket(&data); sLog.outDebug( "WORLD: Sent tutorial flags." ); GetPlayer()->SendInitialSpells(); GetPlayer()->SendInitialActions(); /*if(GetPlayer()->getClass() == CLASS_HUNTER || GetPlayer()->getClass() == CLASS_ROGUE) { uint32 shiftdata=0x01; for(uint8 i=0;i<32;i++) { if ( 522753 & shiftdata ) { data.Initialize(SMSG_SET_FLAT_SPELL_MODIFIER); data << uint8(i); data << uint8(5); data << uint16(1); data << uint16(0); SendPacket(&data); } shiftdata=shiftdata<<1; } }*/ data.Initialize(SMSG_INITIALIZE_FACTIONS); data << uint32 (0x00000040); for(uint32 a=0; a<64; a++) { if(GetPlayer()->FactionIsInTheList(a)) { std::list<struct Factions>::iterator itr; for(itr = GetPlayer()->factions.begin(); itr != GetPlayer()->factions.end(); ++itr) { if(itr->ReputationListID == a) { data << uint8 (itr->Flags); data << uint32 (itr->Standing); break; } } } else { data << uint8 (0x00); data << uint32 (0x00000000); } } SendPacket(&data); GetPlayer()->UpdateHonor(); GetPlayer()->SetPvP( !GetPlayer()->HasFlag(UNIT_FIELD_FLAGS , UNIT_FLAG_NOT_IN_PVP) ); data.Initialize(SMSG_LOGIN_SETTIMESPEED); time_t minutes = sWorld.GetGameTime( ) / 60; time_t hours = minutes / 60; minutes %= 60; time_t gameTime = minutes + ( hours << 6 ); data << (uint32)gameTime; data << (float)0.017f; SendPacket( &data ); //Show cinematic at the first time that player login if( !GetPlayer()->getCinematic() ) { GetPlayer()->setCinematic(1); data.Initialize( SMSG_TRIGGER_CINEMATIC ); uint8 race = GetPlayer()->getRace(); switch (race) { case HUMAN: data << uint32(81); break; case ORC: data << uint32(21); break; case DWARF: data << uint32(41); break; case NIGHTELF: data << uint32(61); break; case UNDEAD_PLAYER: data << uint32(2); break; case TAUREN: data << uint32(141); break; case GNOME: data << uint32(101); break; case TROLL: data << uint32(121); break; default: data << uint32(0); } SendPacket( &data ); } Player *pCurrChar = GetPlayer(); QueryResult *result = sDatabase.PQuery("SELECT `guildid`,`rank` FROM `guild_member` WHERE `guid` = '%u'",pCurrChar->GetGUIDLow()); if(result) { Field *fields = result->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); delete result; } MapManager::Instance().GetMap(pCurrChar->GetMapId())->Add(pCurrChar); ObjectAccessor::Instance().InsertPlayer(pCurrChar); sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); sDatabase.PExecute("UPDATE `character` SET `online` = 1 WHERE `guid` = '%u'", pCurrChar->GetGUID()); loginDatabase.PExecute("UPDATE `account` SET `online` = 1 WHERE `id` = '%u'", GetAccountId()); plr->SetInGameTime( getMSTime() ); std::string outstring = pCurrChar->GetName(); outstring.append( " has come online." ); pCurrChar->BroadcastToFriends(outstring); // setting new speed if dead if ( pCurrChar->m_deathState == DEAD ) { GetPlayer()->SetMovement(MOVE_WATER_WALK); if (GetPlayer()->getRace() == RACE_NIGHT_ELF) { pCurrChar->SetPlayerSpeed(MOVE_RUN, (float)12.75, true); pCurrChar->SetPlayerSpeed(MOVE_SWIM, (float)8.85, true); } else { pCurrChar->SetPlayerSpeed(MOVE_RUN, (float)10.625, true); pCurrChar->SetPlayerSpeed(MOVE_SWIM, (float)7.375, true); } } pCurrChar->LoadEnchant(); // Place charcter in world (and load zone) before some object loading pCurrChar->LoadCorpse(); pCurrChar->LoadPet(); }
//Teleport to Player bool ChatHandler::HandleAppearCommand(const char* args) { Player* target; uint64 target_guid; std::string target_name; if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; Player* _player = m_session->GetPlayer(); if (target == _player || target_guid == _player->GetGUID()) { SendSysMessage(LANG_CANT_TELEPORT_SELF); SetSentErrorMessage(true); return false; } if (target) { // check online security if (HasLowerSecurity(target, 0)) return false; std::string chrNameLink = playerLink(target_name); Map* cMap = target->GetMap(); if (cMap->IsBattlegroundOrArena()) { // only allow if gm mode is on if (!_player->isGameMaster()) { PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM, chrNameLink.c_str()); SetSentErrorMessage(true); return false; } // if both players are in different bgs else if (_player->GetBattlegroundId() && _player->GetBattlegroundId() != target->GetBattlegroundId()) _player->LeaveBattleground(false); // Note: should be changed so _player gets no Deserter debuff // all's well, set bg id // when porting out from the bg, it will be reset to 0 _player->SetBattlegroundId(target->GetBattlegroundId(), target->GetBattlegroundTypeId()); // remember current position as entry point for return at bg end teleportation if (!_player->GetMap()->IsBattlegroundOrArena()) _player->SetBattlegroundEntryPoint(); } else if (cMap->IsDungeon()) { // we have to go to instance, and can go to player only if: // 1) we are in his group (either as leader or as member) // 2) we are not bound to any group and have GM mode on if (_player->GetGroup()) { // we are in group, we can go only if we are in the player group if (_player->GetGroup() != target->GetGroup()) { PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY, chrNameLink.c_str()); SetSentErrorMessage(true); return false; } } else { // we are not in group, let's verify our GM mode if (!_player->isGameMaster()) { PSendSysMessage(LANG_CANNOT_GO_TO_INST_GM, chrNameLink.c_str()); SetSentErrorMessage(true); return false; } } // if the player or the player's group is bound to another instance // the player will not be bound to another one InstancePlayerBind *pBind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficulty(cMap->IsRaid())); if (!pBind) { Group* group = _player->GetGroup(); // if no bind exists, create a solo bind InstanceGroupBind *gBind = group ? group->GetBoundInstance(target) : NULL; // if no bind exists, create a solo bind if (!gBind) if (InstanceSave *save = sInstanceSaveMgr->GetInstanceSave(target->GetInstanceId())) _player->BindToInstance(save, !save->CanReset()); } if (cMap->IsRaid()) _player->SetRaidDifficulty(target->GetRaidDifficulty()); else _player->SetDungeonDifficulty(target->GetDungeonDifficulty()); } PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str()); // stop flight if need if (_player->isInFlight()) { _player->GetMotionMaster()->MovementExpired(); _player->CleanupAfterTaxiFlight(); } // save only in non-flight case else _player->SaveRecallPosition(); // to point to see at target with same orientation float x, y, z; target->GetContactPoint(_player, x, y, z); _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE); _player->SetPhaseMask(target->GetPhaseMask(), true); } else { // check offline security if (HasLowerSecurity(NULL, target_guid)) return false; std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_APPEARING_AT, nameLink.c_str()); // to point where player stay (if loaded) float x, y, z, o; uint32 map; bool in_flight; if (!Player::LoadPositionFromDB(map, x, y, z, o, in_flight, target_guid)) return false; // stop flight if need if (_player->isInFlight()) { _player->GetMotionMaster()->MovementExpired(); _player->CleanupAfterTaxiFlight(); } // save only in non-flight case else _player->SaveRecallPosition(); _player->TeleportTo(map, x, y, z, _player->GetOrientation()); } return true; }
static bool GOMove_Command(ChatHandler* handler, const char* args) { if (!args) return false; char* ID_t = strtok((char*)args, " "); if (!ID_t) return false; uint32 ID = (uint32)atol(ID_t); char* GObjectID_C = strtok(NULL, " "); uint32 GObjectID = 0; bool isHex = false; if (GObjectID_C) { GObjectID = strtoul(GObjectID_C, NULL, 0); // can take in hex as well as dec isHex = (std::string(GObjectID_C).find("0x") != std::string::npos); } char* ARG_t = strtok(NULL, " "); uint32 ARG = 0; if (ARG_t) ARG = (uint32)atol(ARG_t); WorldSession* session = handler->GetSession(); Player* player = session->GetPlayer(); uint64 playerGUID = player->GetGUID(); if (ID < SPAWN) // no args { if (ID >= DELET && ID <= GOTO) // has target (needs retrieve gameobject) { GameObject* target = GetObjectByGObjectID(player, GObjectID, isHex); if (!target) ChatHandler(player->GetSession()).PSendSysMessage("Object GUID: %u not found. Temp(%u)", GObjectID, isHex ? 1 : 0); else { float x,y,z,o; target->GetPosition(x,y,z,o); uint32 p = target->GetPhaseMask(); switch(ID) { case DELET: DeleteObject(target/*, isHex ? GObjectID : 0*/); SendSelectionInfo(player, GObjectID, isHex, false); break; case X: SpawnObject(player,player->GetPositionX(),y,z,o,p,true,GObjectID, isHex); break; case Y: SpawnObject(player,x,player->GetPositionY(),z,o,p,true,GObjectID, isHex); break; case Z: SpawnObject(player,x,y,player->GetPositionZ(),o,p,true,GObjectID, isHex); break; case O: SpawnObject(player,x,y,z,player->GetOrientation(),p,true,GObjectID, isHex); break; case GOTO: player->TeleportTo(target->GetMapId(), x,y,z,o); break; case RESPAWN: SpawnObject(player,x,y,z,o,p,false,target->GetEntry(), isHex); break; case GROUND: { float ground = target->GetMap()->GetHeight(target->GetPhaseMask(), x, y, MAX_HEIGHT); if(ground != INVALID_HEIGHT) SpawnObject(player,x,y,ground,o,p,true,GObjectID, isHex); } break; } } } else { switch(ID) { case TEST: session->SendAreaTriggerMessage(player->GetName().c_str()); break; case FACE: { float piper2 = M_PI/2; float multi = player->GetOrientation()/piper2; float multi_int = floor(multi); float new_ori = (multi-multi_int > 0.5f) ? (multi_int+1)*piper2 : multi_int*piper2; player->SetFacingTo(new_ori); } break; case SAVE: SaveObject(player, GObjectID, isHex); break; case SELECTNEAR: { GameObject* object = handler->GetNearbyGameObject(); object = GetClosestGObjectID(player, object); if (!object) ChatHandler(player->GetSession()).PSendSysMessage("No objects found"); else { bool isHex = (object->GetGUIDHigh() != HIGHGUID_GAMEOBJECT); SendSelectionInfo(player, isHex ? object->GetGUIDHigh() : object->GetDBTableGUIDLow() ? object->GetDBTableGUIDLow() : object->GetGUIDLow(), isHex, true); session->SendAreaTriggerMessage("Selected %s", object->GetName().c_str()); } } break; } } } else if (ARG && ID >= SPAWN) { if (ID >= NORTH && ID <= PHASE) { GameObject* target = GetObjectByGObjectID(player, GObjectID, isHex); if (!target) ChatHandler(player->GetSession()).PSendSysMessage("Object GUID: %u not found. Temporary: %s", GObjectID, isHex ? "true" : "false"); else { float x,y,z,o; target->GetPosition(x,y,z,o); uint32 p = target->GetPhaseMask(); switch(ID) { case NORTH: SpawnObject(player,x+((float)ARG/100),y,z,o,p,true,GObjectID, isHex); break; case EAST: SpawnObject(player,x,y-((float)ARG/100),z,o,p,true,GObjectID, isHex); break; case SOUTH: SpawnObject(player,x-((float)ARG/100),y,z,o,p,true,GObjectID, isHex); break; case WEST: SpawnObject(player,x,y+((float)ARG/100),z,o,p,true,GObjectID, isHex); break; case NORTHEAST: SpawnObject(player,x+((float)ARG/100),y-((float)ARG/100),z,o,p,true,GObjectID, isHex); break; case SOUTHEAST: SpawnObject(player,x-((float)ARG/100),y-((float)ARG/100),z,o,p,true,GObjectID, isHex); break; case SOUTHWEST: SpawnObject(player,x-((float)ARG/100),y+((float)ARG/100),z,o,p,true,GObjectID, isHex); break; case NORTHWEST: SpawnObject(player,x+((float)ARG/100),y+((float)ARG/100),z,o,p,true,GObjectID, isHex); break; case UP: SpawnObject(player,x,y,z+((float)ARG/100),o,p,true,GObjectID, isHex); break; case DOWN: SpawnObject(player,x,y,z-((float)ARG/100),o,p,true,GObjectID, isHex); break; case RIGHT: SpawnObject(player,x,y,z,o-((float)ARG/100),p,true,GObjectID, isHex); break; case LEFT: SpawnObject(player,x,y,z,o+((float)ARG/100),p,true,GObjectID, isHex); break; case PHASE: SpawnObject(player,x,y,z,o,ARG,true,GObjectID, isHex); break; } } } else { switch(ID) { case SPAWN: { if (SpawnObject(player, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), player->GetPhaseMaskForSpawn(), false, ARG, false, true)) SpawnQue[player->GetGUID()] = ARG; } break; case SPAWNSPELL: { SpawnQue[player->GetGUID()] = ARG; } break; case SELECTALLNEAR: { if (ARG > 5000) ARG = 5000; QueryResult result = WorldDatabase.PQuery("SELECT guid, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%u' AND position_x BETWEEN '%f'-'%u' AND '%f'+'%u' AND position_y BETWEEN '%f'-'%u' AND '%f'+'%u' AND position_z BETWEEN '%f'-'%u' AND '%f'+'%u' ORDER BY order_ ASC LIMIT 100", player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetPositionX(), ARG, player->GetPositionX(), ARG, player->GetPositionY(), ARG, player->GetPositionY(), ARG, player->GetPositionZ(), ARG, player->GetPositionZ(), ARG); if (result) { do { Field* fields = result->Fetch(); uint32 guidLow = fields[0].GetUInt32(); if (GameObject* object = GetObjectByGObjectID(player, guidLow, false)) SendSelectionInfo(player, guidLow, false, true); } while (result->NextRow()); } for(std::set<uint32>::const_iterator it = GObjects.begin(); it != GObjects.end();) { GameObject* temp = player->GetGameObject(*it); if(!temp) { GObjects.erase(*it++); continue; } if(temp->IsWithinDistInMap(player, ARG)) SendSelectionInfo(player, (*it), true, true); ++it; } } break; } } } else return false; return true; }
// Summon group of player static bool HandleGroupSummonCommand(ChatHandler* handler, char const* args) { Player* target; if (!handler->extractPlayerTarget((char*)args, &target)) return false; // check online security if (handler->HasLowerSecurity(target, ObjectGuid::Empty)) return false; Group* group = target->GetGroup(); std::string nameLink = handler->GetNameLink(target); if (!group) { handler->PSendSysMessage(LANG_NOT_IN_GROUP, nameLink.c_str()); handler->SetSentErrorMessage(true); return false; } Player* gmPlayer = handler->GetSession()->GetPlayer(); Group* gmGroup = gmPlayer->GetGroup(); Map* gmMap = gmPlayer->GetMap(); bool toInstance = gmMap->Instanceable(); // we are in instance, and can summon only player in our group with us as lead if (toInstance && ( !gmGroup || group->GetLeaderGUID() != gmPlayer->GetGUID() || gmGroup->GetLeaderGUID() != gmPlayer->GetGUID())) // the last check is a bit excessive, but let it be, just in case { handler->SendSysMessage(LANG_CANNOT_SUMMON_TO_INST); handler->SetSentErrorMessage(true); return false; } for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* player = itr->GetSource(); if (!player || player == gmPlayer || !player->GetSession()) continue; // check online security if (handler->HasLowerSecurity(player, ObjectGuid::Empty)) return false; std::string plNameLink = handler->GetNameLink(player); if (player->IsBeingTeleported()) { handler->PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str()); handler->SetSentErrorMessage(true); return false; } if (toInstance) { Map* playerMap = player->GetMap(); if (playerMap->Instanceable() && playerMap->GetInstanceId() != gmMap->GetInstanceId()) { // cannot summon from instance to instance handler->PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST, plNameLink.c_str()); handler->SetSentErrorMessage(true); return false; } } handler->PSendSysMessage(LANG_SUMMONING, plNameLink.c_str(), ""); if (handler->needReportToTarget(player)) ChatHandler(player->GetSession()).PSendSysMessage(LANG_SUMMONED_BY, handler->GetNameLink().c_str()); // stop flight if need if (player->IsInFlight()) { player->GetMotionMaster()->MovementExpired(); player->CleanupAfterTaxiFlight(); } // save only in non-flight case else player->SaveRecallPosition(); // before GM float x, y, z; gmPlayer->GetClosePoint(x, y, z, player->GetObjectSize()); player->TeleportTo(gmPlayer->GetMapId(), x, y, z, player->GetOrientation()); } return true; }
void WorldSession::SendLfgUpdateProposal(LFGProposal* pProposal) { if (!sWorld.getConfig(CONFIG_BOOL_LFG_ENABLE)) { DEBUG_LOG("SendLfgUpdateProposal %u failed - Dungeon finder disabled", GetPlayer()->GetObjectGuid().GetCounter()); return; } if (!pProposal) return; LFGDungeonEntry const* dungeon = pProposal->GetDungeon(); if (!dungeon) { DEBUG_LOG("SMSG_LFG_PROPOSAL_UPDATE: no dungeon in proposal %u, returning.", pProposal->ID); return; } ObjectGuid guid = GetPlayer()->GetObjectGuid(); bool isSameDungeon = false; bool isSameGroup = false; uint32 completedEncounters = 0; LFGRolesMap rolesMap; if (Group* group = pProposal->GetGroup()) { for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) if (Player* member = itr->getSource()) if (member->IsInWorld()) { rolesMap.insert(std::make_pair(member->GetObjectGuid(), member->GetLFGState()->GetRoles())); if (InstancePlayerBind* bind = member->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty))) { if (DungeonPersistentState* state = bind->state) completedEncounters |= state->GetCompletedEncountersMask(); } } // isContinue = group->isLFGGroup() && sLFGMgr->GetState(gguid) != LFG_STATE_FINISHED_DUNGEON; isSameDungeon = dungeon->map == GetPlayer()->GetMapId(); isSameGroup = GetPlayer()->GetGroup() == group; } LFGQueueSet const proposalGuids = pProposal->GetMembers(); if (!proposalGuids.empty()) { for (LFGQueueSet::const_iterator itr = proposalGuids.begin(); itr != proposalGuids.end(); ++itr) if (Player* player = sObjectMgr.GetPlayer(*itr)) if (player->IsInWorld()) rolesMap.insert(std::make_pair(player->GetObjectGuid(), player->GetLFGState()->GetRoles())); } uint32 size = rolesMap.size(); DEBUG_LOG("SMSG_LFG_PROPOSAL_UPDATE proposal %u, player %u, state: %u", pProposal->ID, GetPlayer()->GetObjectGuid().GetCounter(), pProposal->GetState()); WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + size * (4 + 1 + 1 + 1 + 1 +1)); data << uint32(dungeon->Entry()); // Dungeon data << uint8(pProposal->GetState()); // Result state data << uint32(pProposal->ID); // Internal Proposal ID data << uint32(completedEncounters); // Bosses killed data << uint8(isSameDungeon); // Silent (show client window) data << uint8(size); // Group size for (LFGRolesMap::const_iterator itr = rolesMap.begin(); itr != rolesMap.end(); ++itr) { Player* pPlayer = sObjectMgr.GetPlayer(itr->first); if (!pPlayer) continue; isSameDungeon = dungeon->map == pPlayer->GetMapId(); isSameGroup = pPlayer->GetGroup() == pProposal->GetGroup(); data << uint32(itr->second); // Role data << uint8(pPlayer->GetObjectGuid() == guid); // Self player data << uint8(isSameDungeon); // Not in dungeon data << uint8(isSameGroup); // Not same group data << uint8(pPlayer->GetLFGState()->GetAnswer() != LFG_ANSWER_PENDING); // Answered data << uint8(pPlayer->GetLFGState()->GetAnswer() == LFG_ANSWER_AGREE); // Accepted } SendPacket(&data); }
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) { uint8 bagIndex, slot; uint8 unk_flags; // flags (if 0x02 - some additional data are received) uint8 cast_count; // next cast if exists (single or not) ObjectGuid itemGuid; uint32 glyphIndex; // something to do with glyphs? uint32 spellid; // casted spell id recvPacket >> bagIndex >> slot >> cast_count >> spellid >> itemGuid >> glyphIndex >> unk_flags; // TODO: add targets.read() check Player* pUser = _player; // ignore for remote control state if (!pUser->IsSelfMover()) { recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail return; } // reject fake data if (glyphIndex >= MAX_GLYPH_SLOT_INDEX) { recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); return; } Item *pItem = pUser->GetItemByPos(bagIndex, slot); if (!pItem) { recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); return; } if (pItem->GetObjectGuid() != itemGuid) { recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); return; } DETAIL_LOG("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, cast_count: %u, spellid: %u, Item: %u, glyphIndex: %u, unk_flags: %u, data length = %i", bagIndex, slot, cast_count, spellid, pItem->GetEntry(), glyphIndex, unk_flags, (uint32)recvPacket.size()); ItemPrototype const *proto = pItem->GetProto(); if (!proto) { recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL ); return; } // some item classes can be used only in equipped state if (proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped()) { recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL ); return; } InventoryResult msg = pUser->CanUseItem(pItem); if (msg != EQUIP_ERR_OK) { recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError( msg, pItem, NULL ); return; } // not allow use item from trade (cheat way only) if (pItem->IsInTrade()) { recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL ); return; } // only allow conjured consumable, bandage, poisons (all should have the 2^21 item flag set in DB) if (proto->Class == ITEM_CLASS_CONSUMABLE && !(proto->Flags & ITEM_FLAG_USEABLE_IN_ARENA) && pUser->InArena()) { recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH,pItem,NULL); return; } if (proto->Area && proto->Area != pUser->GetAreaId() || proto->Map && proto->Map != pUser->GetMapId()) { if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid)) Spell::SendCastResult(pUser, spellInfo, cast_count, SPELL_FAILED_INCORRECT_AREA); return; } if (pUser->isInCombat()) { for(int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) { if (SpellEntry const *spellInfo = sSpellStore.LookupEntry(proto->Spells[i].SpellId)) { if (IsNonCombatSpell(spellInfo)) { recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT,pItem,NULL); return; } } } // Prevent potion drink if another potion in processing (client have potions disabled in like case) if (pItem->IsPotion() && pUser->GetLastPotionId()) { recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail pUser->SendEquipError(EQUIP_ERR_OBJECT_IS_BUSY,pItem,NULL); return; } } // check also BIND_WHEN_PICKED_UP and BIND_QUEST_ITEM for .additem or .additemset case by GM (not binded at adding to inventory) if( pItem->GetProto()->Bonding == BIND_WHEN_USE || pItem->GetProto()->Bonding == BIND_WHEN_PICKED_UP || pItem->GetProto()->Bonding == BIND_QUEST_ITEM ) { if (!pItem->IsSoulBound()) { pItem->SetState(ITEM_CHANGED, pUser); pItem->SetBinding( true ); } } SpellCastTargets targets; recvPacket >> targets.ReadForCaster(pUser); targets.Update(pUser); if (!pItem->IsTargetValidForItemUse(targets.getUnitTarget())) { // free gray item after use fail pUser->SendEquipError(EQUIP_ERR_NONE, pItem, NULL); // send spell error if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid)) { // for implicit area/coord target spells if (IsPointEffectTarget(Targets(spellInfo->EffectImplicitTargetA[EFFECT_INDEX_0])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[EFFECT_INDEX_0]))) Spell::SendCastResult(_player,spellInfo,cast_count,SPELL_FAILED_NO_VALID_TARGETS); // for explicit target spells else Spell::SendCastResult(_player,spellInfo,cast_count,SPELL_FAILED_BAD_TARGETS); } return; } //Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state. if (!sScriptMgr.OnItemUse(pUser, pItem, targets)) { // no script or script not process request by self pUser->CastItemUseSpell(pItem,targets,cast_count,glyphIndex); } }
void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) { uint64 playerGuid = holder->GetGuid(); Player* pCurrChar = new Player(this); pCurrChar->GetMotionMaster()->Initialize(); // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if(!pCurrChar->LoadFromDB(GUID_LOPART(playerGuid), holder)) { KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete pCurrChar; // delete it manually delete holder; // delete all unprocessed queries m_playerLoading = false; return; } SetPlayer(pCurrChar); pCurrChar->SendDungeonDifficulty(false); WorldPacket data( SMSG_LOGIN_VERIFY_WORLD, 20 ); data << pCurrChar->GetMapId(); data << pCurrChar->GetPositionX(); data << pCurrChar->GetPositionY(); data << pCurrChar->GetPositionZ(); data << pCurrChar->GetOrientation(); SendPacket(&data); data.Initialize( SMSG_ACCOUNT_DATA_TIMES, 4+1+8*4 ); // changed in WotLK data << uint32(time(NULL)); // unix time of something data << uint8(1); for(int i = 0; i < NUM_ACCOUNT_DATA_TYPES; i++) data << uint32(GetAccountData(i)->Time); // also unix time SendPacket(&data); data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0 data << uint8(2); // unknown value data << uint8(0); // enable(1)/disable(0) voice chat interface in client SendPacket(&data); // Send MOTD { data.Initialize(SMSG_MOTD, 50); // new in 2.0.1 data << (uint32)0; uint32 linecount=0; std::string str_motd = sWorld.GetMotd(); std::string::size_type pos, nextpos; pos = 0; while ( (nextpos= str_motd.find('@',pos)) != std::string::npos ) { if (nextpos != pos) { data << str_motd.substr(pos,nextpos-pos); ++linecount; } pos = nextpos+1; } if (pos<str_motd.length()) { data << str_motd.substr(pos); ++linecount; } data.put(0, linecount); SendPacket( &data ); DEBUG_LOG( "WORLD: Sent motd (SMSG_MOTD)" ); } //QueryResult *result = CharacterDatabase.PQuery("SELECT guildid,rank FROM guild_member WHERE guid = '%u'",pCurrChar->GetGUIDLow()); QueryResult *resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD); if(resultGuild) { Field *fields = resultGuild->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); delete resultGuild; } else if(pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about non existed membership { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } if(pCurrChar->GetGuildId() != 0) { Guild* guild = objmgr.GetGuildById(pCurrChar->GetGuildId()); if(guild) { data.Initialize(SMSG_GUILD_EVENT, (2+guild->GetMOTD().size()+1)); data << (uint8)GE_MOTD; data << (uint8)1; data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG( "WORLD: Sent guild-motd (SMSG_GUILD_EVENT)" ); data.Initialize(SMSG_GUILD_EVENT, (5+10)); // we guess size data<<(uint8)GE_SIGNED_ON; data<<(uint8)1; data<<pCurrChar->GetName(); data<<pCurrChar->GetGUID(); guild->BroadcastPacket(&data); DEBUG_LOG( "WORLD: Sent guild-signed-on (SMSG_GUILD_EVENT)" ); // Increment online members of the guild guild->IncOnlineMemberCount(); } else { // remove wrong guild data sLog.outError("Player %s (GUID: %u) marked as member not existed guild (id: %u), removing guild membership for player.",pCurrChar->GetName(),pCurrChar->GetGUIDLow(),pCurrChar->GetGuildId()); pCurrChar->SetInGuild(0); } } if(!pCurrChar->isAlive()) pCurrChar->SendCorpseReclaimDelay(true); pCurrChar->SendInitialPacketsBeforeAddToMap(); //Show cinematic at the first time that player login if( !pCurrChar->getCinematic() ) { pCurrChar->setCinematic(1); if(ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(pCurrChar->getClass())) { if(cEntry->CinematicSequence) { data.Initialize(SMSG_TRIGGER_CINEMATIC, 4); data << uint32(cEntry->CinematicSequence); SendPacket( &data ); } else if(ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) { data.Initialize(SMSG_TRIGGER_CINEMATIC, 4); data << uint32(rEntry->CinematicSequence); SendPacket( &data ); } } } if (!pCurrChar->GetMap()->Add(pCurrChar)) { AreaTrigger const* at = objmgr.GetGoBackTrigger(pCurrChar->GetMapId()); if(at) pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); else pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation()); } ObjectAccessor::Instance().AddObject(pCurrChar); //sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); pCurrChar->GetSocial()->SendSocialList(); pCurrChar->SendInitialPacketsAfterAddToMap(); CharacterDatabase.PExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", pCurrChar->GetGUIDLow()); loginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = '%u'", GetAccountId()); pCurrChar->SetInGameTime( getMSTime() ); // announce group about member online (must be after add to player list to receive announce to self) if(Group *group = pCurrChar->GetGroup()) { //pCurrChar->groupInfo.group->SendInit(this); // useless group->SendUpdate(); } // friend status sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), true); // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); // setting Ghost+speed if dead if (pCurrChar->m_deathState != ALIVE) { // not blizz like, we must correctly save and load player instead... if(pCurrChar->getRace() == RACE_NIGHTELF) pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) pCurrChar->SetMovement(MOVE_WATER_WALK); } if(uint32 sourceNode = pCurrChar->m_taxi.GetTaxiSource()) { sLog.outDebug( "WORLD: Restart character %u taxi flight", pCurrChar->GetGUIDLow() ); uint32 MountId = objmgr.GetTaxiMount(sourceNode, pCurrChar->GetTeam()); uint32 path = pCurrChar->m_taxi.GetCurrentTaxiPath(); // search appropriate start path node uint32 startNode = 0; TaxiPathNodeList const& nodeList = sTaxiPathNodesByPath[path]; float distPrev = MAP_SIZE*MAP_SIZE; float distNext = (nodeList[0].x-pCurrChar->GetPositionX())*(nodeList[0].x-pCurrChar->GetPositionX())+ (nodeList[0].y-pCurrChar->GetPositionY())*(nodeList[0].y-pCurrChar->GetPositionY())+ (nodeList[0].z-pCurrChar->GetPositionZ())*(nodeList[0].z-pCurrChar->GetPositionZ()); for(uint32 i = 1; i < nodeList.size(); ++i) { TaxiPathNode const& node = nodeList[i]; TaxiPathNode const& prevNode = nodeList[i-1]; // skip nodes at another map if(node.mapid != pCurrChar->GetMapId()) continue; distPrev = distNext; distNext = (node.x-pCurrChar->GetPositionX())*(node.x-pCurrChar->GetPositionX())+ (node.y-pCurrChar->GetPositionY())*(node.y-pCurrChar->GetPositionY())+ (node.z-pCurrChar->GetPositionZ())*(node.z-pCurrChar->GetPositionZ()); float distNodes = (node.x-prevNode.x)*(node.x-prevNode.x)+ (node.y-prevNode.y)*(node.y-prevNode.y)+ (node.z-prevNode.z)*(node.z-prevNode.z); if(distNext + distPrev < distNodes) { startNode = i; break; } } SendDoFlight( MountId, path, startNode ); } // Load pet if any and player is alive and not in taxi flight if(pCurrChar->isAlive() && pCurrChar->m_taxi.GetTaxiSource()==0) pCurrChar->LoadPet(); // Set FFA PvP for non GM in non-rest mode if(sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_RESTING) ) pCurrChar->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); if(pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP)) pCurrChar->SetContestedPvP(); // Apply at_login requests if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) { pCurrChar->resetSpells(); SendNotification(LANG_RESET_SPELLS); } if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) { pCurrChar->resetTalents(true); SendNotification(LANG_RESET_TALENTS); } // show time before shutdown if shutdown planned. if(sWorld.IsShutdowning()) sWorld.ShutdownMsg(true,pCurrChar); if(sWorld.getConfig(CONFIG_ALL_TAXI_PATHS)) pCurrChar->SetTaxiCheater(true); if(pCurrChar->isGameMaster()) SendNotification(LANG_GM_ON); std::string IP_str = GetRemoteAddress(); sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid:%u)", GetAccountId(),IP_str.c_str(),pCurrChar->GetName() ,pCurrChar->GetGUIDLow()); m_playerLoading = false; delete holder; }
void Transporter::TransportPassengers(uint32 mapid, uint32 oldmap, float x, float y, float z) { sEventMgr.RemoveEvents(this, EVENT_TRANSPORTER_NEXT_WAYPOINT); if(mPassengers.size() > 0) { PassengerIterator itr = mPassengers.begin(); PassengerIterator it2; WorldPacket Pending(SMSG_TRANSFER_PENDING, 12); Pending << mapid << GetEntry() << oldmap; WorldPacket NewWorld; LocationVector v; for(; itr != mPassengers.end();) { it2 = itr++; Player* plr = objmgr.GetPlayer(it2->first); if(!plr) { // remove from map mPassengers.erase(it2); continue; } if(!plr->GetSession() || !plr->IsInWorld()) continue; v.x = x + plr->m_transportPosition->x; v.y = y + plr->m_transportPosition->y; v.z = z + plr->m_transportPosition->z; v.o = plr->GetOrientation(); if(mapid == 530 && !plr->GetSession()->HasFlag(ACCOUNT_FLAG_XPACK_01)) { // player is not flagged to access bc content, repop at graveyard plr->RepopAtGraveyard(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), plr->GetMapId()); continue; } if(mapid == 571 && !plr->GetSession()->HasFlag(ACCOUNT_FLAG_XPACK_02)) { plr->RepopAtGraveyard(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), plr->GetMapId()); continue; } // Lucky bitch. Do it like on official. if(plr->isDead()) plr->RemoteRevive(); if( plr->m_CurrentVehicle ) plr->m_CurrentVehicle->RemovePassenger( plr ); plr->m_lockTransportVariables = true; plr->GetSession()->SendPacket(&Pending); #ifndef CLUSTERING plr->_Relocate(mapid, v, false, true, 0); #else plr->RelocateCallback(mapid); #endif } } // Set our position RemoveFromWorld(false); SetMapId(mapid); SetPosition(x,y,z,m_position.o,false); AddToWorld(); }
bool ChatHandler::HandleGOSpawn(const char* args, WorldSession* m_session) { std::stringstream sstext; char* pEntryID = strtok((char*)args, " "); if(!pEntryID) return false; uint32 EntryID = atoi(pEntryID); bool Save = false; char* pSave = strtok(NULL, " "); if(pSave) Save = (atoi(pSave) > 0 ? true : false); GameObjectInfo* goi = GameObjectNameStorage.LookupEntry(EntryID); if(!goi) { sstext << "GameObject Info '" << EntryID << "' Not Found" << '\0'; SystemMessage(m_session, sstext.str().c_str()); return false; } LOG_DEBUG("Spawning GameObject By Entry '%u'", EntryID); sstext << "Spawning GameObject By Entry '" << EntryID << "'" << '\0'; SystemMessage(m_session, sstext.str().c_str()); Player* chr = m_session->GetPlayer(); GameObject* go = chr->GetMapMgr()->CreateGameObject(EntryID); uint32 mapid = chr->GetMapId(); float x = chr->GetPositionX(); float y = chr->GetPositionY(); float z = chr->GetPositionZ(); float o = chr->GetOrientation(); go->CreateFromProto(EntryID, mapid, x, y, z, o); go->PushToWorld(chr->GetMapMgr()); go->Phase(PHASE_SET, chr->GetPhase()); // Create spawn instance GOSpawn* gs = new GOSpawn; gs->entry = go->GetEntry(); gs->facing = go->GetOrientation(); gs->faction = go->GetFaction(); gs->flags = go->GetUInt32Value(GAMEOBJECT_FLAGS); gs->id = objmgr.GenerateGameObjectSpawnID(); gs->o = 0.0f; gs->o1 = go->GetParentRotation(0); gs->o2 = go->GetParentRotation(2); gs->o3 = go->GetParentRotation(3); gs->scale = go->GetScale(); gs->x = go->GetPositionX(); gs->y = go->GetPositionY(); gs->z = go->GetPositionZ(); gs->state = go->GetByte(GAMEOBJECT_BYTES_1, 0); //gs->stateNpcLink = 0; gs->phase = go->GetPhase(); gs->overrides = go->GetOverrides(); uint32 cx = chr->GetMapMgr()->GetPosX(chr->GetPositionX()); uint32 cy = chr->GetMapMgr()->GetPosY(chr->GetPositionY()); chr->GetMapMgr()->GetBaseMap()->GetSpawnsListAndCreate(cx, cy)->GOSpawns.push_back(gs); go->m_spawn = gs; MapCell* mCell = chr->GetMapMgr()->GetCell(cx, cy); if(mCell) mCell->SetLoaded(); if(Save == true) { // If we're saving, create template and add index go->SaveToDB(); go->m_loadedFromDB = true; } sGMLog.writefromsession(m_session, "spawned gameobject %s, entry %u at %u %f %f %f%s", GameObjectNameStorage.LookupEntry(gs->entry)->Name, gs->entry, chr->GetMapId(), gs->x, gs->y, gs->z, Save ? ", saved in DB" : ""); return true; }
bool Group::_addMember(ObjectGuid guid, const char* name, bool isAssistant, uint8 group) { if (IsFull()) return false; if (!guid) return false; Player* player = sObjectMgr.GetPlayer(guid, false); uint32 lastMap = 0; if (player && player->IsInWorld()) lastMap = player->GetMapId(); else if (player && player->IsBeingTeleported()) lastMap = player->GetTeleportDest().mapid; MemberSlot member; member.guid = guid; member.name = name; member.group = group; member.assistant = isAssistant; member.lastMap = lastMap; m_memberSlots.push_back(member); SubGroupCounterIncrease(group); if (player) { player->SetGroupInvite(nullptr); // if player is in group and he is being added to BG raid group, then call SetBattleGroundRaid() if (player->GetGroup() && isBattleGroup()) player->SetBattleGroundRaid(this, group); // if player is in bg raid and we are adding him to normal group, then call SetOriginalGroup() else if (player->GetGroup()) player->SetOriginalGroup(this, group); // if player is not in group, then call set group else player->SetGroup(this, group); if (player->IsInWorld()) { // if the same group invites the player back, cancel the homebind timer if (InstanceGroupBind* bind = GetBoundInstance(player->GetMapId())) if (bind->state->GetInstanceId() == player->GetInstanceId()) player->m_InstanceValid = true; } } if (!isRaidGroup()) // reset targetIcons for non-raid-groups { for (auto& m_targetIcon : m_targetIcons) m_targetIcon.Clear(); } if (!isBattleGroup()) { // insert into group table CharacterDatabase.PExecute("INSERT INTO group_member(groupId,memberGuid,assistant,subgroup) VALUES('%u','%u','%u','%u')", m_Id, member.guid.GetCounter(), ((member.assistant == 1) ? 1 : 0), member.group); } return true; }
void WorldSession::SendLfgUpdateProposal(uint32 proposalId, const LfgProposal* pProp) { if (!pProp) return; uint64 guid = GetPlayer()->GetGUID(); LfgProposalPlayerMap::const_iterator itPlayer = pProp->players.find(guid); if (itPlayer == pProp->players.end()) // Player MUST be in the proposal return; LfgProposalPlayer* ppPlayer = itPlayer->second; uint32 pLowGroupGuid = ppPlayer->groupLowGuid; uint32 dLowGuid = pProp->groupLowGuid; uint32 dungeonId = pProp->dungeonId; bool isSameDungeon = false; bool isContinue = false; Group* grp = dLowGuid ? sGroupMgr->GetGroupByGUID(dLowGuid) : NULL; uint32 completedEncounters = 0; if (grp) { uint64 gguid = grp->GetGUID(); isContinue = grp->isLFGGroup() && sLFGMgr->GetState(gguid) != LFG_STATE_FINISHED_DUNGEON; isSameDungeon = GetPlayer()->GetGroup() == grp && isContinue; } sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PROPOSAL_UPDATE [" UI64FMTD "] state: %u", GetPlayer()->GetGUID(), pProp->state); WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + pProp->players.size() * (4 + 1 + 1 + 1 + 1 +1)); if (!isContinue) // Only show proposal dungeon if it's continue { LfgDungeonSet playerDungeons = sLFGMgr->GetSelectedDungeons(guid); if (playerDungeons.size() == 1) dungeonId = (*playerDungeons.begin()); } if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId)) { dungeonId = dungeon->Entry(); // Select a player inside to be get completed encounters from if (grp) { for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* groupMember = itr->getSource(); if (groupMember && groupMember->GetMapId() == uint32(dungeon->map)) { if (InstanceScript* instance = groupMember->GetInstanceScript()) completedEncounters = instance->GetCompletedEncounterMask(); break; } } } } data << uint32(dungeonId); // Dungeon data << uint8(pProp->state); // Result state data << uint32(proposalId); // Internal Proposal ID data << uint32(completedEncounters); // Bosses killed data << uint8(isSameDungeon); // Silent (show client window) data << uint8(pProp->players.size()); // Group size for (itPlayer = pProp->players.begin(); itPlayer != pProp->players.end(); ++itPlayer) { ppPlayer = itPlayer->second; data << uint32(ppPlayer->role); // Role data << uint8(itPlayer->first == guid); // Self player if (!ppPlayer->groupLowGuid) // Player not it a group { data << uint8(0); // Not in dungeon data << uint8(0); // Not same group } else { data << uint8(ppPlayer->groupLowGuid == dLowGuid); // In dungeon (silent) data << uint8(ppPlayer->groupLowGuid == pLowGroupGuid); // Same Group than player } data << uint8(ppPlayer->accept != LFG_ANSWER_PENDING); // Answered data << uint8(ppPlayer->accept == LFG_ANSWER_AGREE); // Accepted } SendPacket(&data); }
void WorldSession::HandleGroupInviteOpcode(WorldPacket& recv_data) { ObjectGuid guid; recv_data.read_skip<uint32>(); // cross-realm party related recv_data.read_skip<uint32>(); // roles mask? recv_data.ReadGuidMask<2, 7>(guid); uint32 realmLength = recv_data.ReadBits(9); recv_data.ReadGuidMask<3>(guid); uint32 nameLength = recv_data.ReadBits(10); recv_data.ReadGuidMask<5, 4, 6, 0, 1>(guid); recv_data.ReadGuidBytes<4, 7, 6>(guid); std::string membername = recv_data.ReadString(nameLength); std::string realmname = recv_data.ReadString(realmLength); // attempt add selected player // cheating if (!normalizePlayerName(membername)) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } Player* player = sObjectMgr.GetPlayer(membername.c_str()); // no player if (!player) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } // can't group with if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_PLAYER_WRONG_FACTION); return; } if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us if (player->GetSocial()->HasIgnore(GetPlayer()->GetObjectGuid())) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S); return; } Group* group = GetPlayer()->GetGroup(); if (group && group->isBGGroup()) group = GetPlayer()->GetOriginalGroup(); if (group && group->isRaidGroup() && !player->GetAllowLowLevelRaid() && (player->getLevel() < sWorld.getConfig(CONFIG_UINT32_MIN_LEVEL_FOR_RAID))) { SendPartyResult(PARTY_OP_INVITE, "", ERR_RAID_DISALLOWED_BY_LEVEL); return; } // player already invited if (player->GetGroupInvite()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_ALREADY_IN_GROUP_S); return; } Group* group2 = player->GetGroup(); if (group2 && group2->isBGGroup()) group2 = player->GetOriginalGroup(); // player already in another group if (group2) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_ALREADY_IN_GROUP_S); // tell the player that they were invited but it failed as they were already in a group player->GetSession()->SendGroupInvite(player, true); return; } if (group) { // not have permissions for invite if (!group->IsLeader(GetPlayer()->GetObjectGuid()) && !group->IsAssistant(GetPlayer()->GetObjectGuid())) { SendPartyResult(PARTY_OP_INVITE, "", ERR_NOT_LEADER); return; } // not have place if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } } // ok, but group not exist, start a new group // but don't create and save the group to the DB until // at least one person joins if (!group) { group = new Group; // new group: if can't add then delete if (!group->AddLeaderInvite(GetPlayer())) { delete group; return; } if (!group->AddInvite(player)) { delete group; return; } } else { // already existing group: if can't add then just leave if (!group->AddInvite(player)) { return; } } player->GetSession()->SendGroupInvite(_player); SendPartyResult(PARTY_OP_INVITE, membername, ERR_PARTY_RESULT_OK); }
void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) { uint64 playerGuid = holder->GetGuid(); Player* pCurrChar = new Player(this); // for send server info and strings (config) ChatHandler chH = ChatHandler(pCurrChar); // "GetAccountId() == db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if (!pCurrChar->LoadFromDB(GUID_LOPART(playerGuid), holder)) { KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete pCurrChar; // delete it manually delete holder; // delete all unprocessed queries m_playerLoading = false; return; } pCurrChar->GetMotionMaster()->Initialize(); SetPlayer(pCurrChar); pCurrChar->SendDungeonDifficulty(false); WorldPacket data(SMSG_LOGIN_VERIFY_WORLD, 20); data << pCurrChar->GetMapId(); data << pCurrChar->GetPositionX(); data << pCurrChar->GetPositionY(); data << pCurrChar->GetPositionZ(); data << pCurrChar->GetOrientation(); SendPacket(&data); data.Initialize(SMSG_ACCOUNT_DATA_TIMES, 128); for (int i = 0; i < 32; i++) data << uint32(0); SendPacket(&data); data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0 data << uint8(2); // unknown value data << uint8(0); // enable(1)/disable(0) voice chat interface in client SendPacket(&data); // Send MOTD { data.Initialize(SMSG_MOTD, 50); // new in 2.0.1 data << (uint32)0; uint32 linecount=0; std::string str_motd = sWorld.GetMotd(); std::string::size_type pos, nextpos; pos = 0; while ((nextpos= str_motd.find('@',pos)) != std::string::npos) { if (nextpos != pos) { data << str_motd.substr(pos,nextpos-pos); ++linecount; } pos = nextpos+1; } if (pos<str_motd.length()) { data << str_motd.substr(pos); ++linecount; } data.put(0, linecount); SendPacket(&data); DEBUG_LOG("WORLD: Sent motd (SMSG_MOTD)"); // send server info if (sWorld.getConfig(CONFIG_ENABLE_SINFO_LOGIN) == 1) chH.PSendSysMessage(_FULLVERSION); DEBUG_LOG("WORLD: Sent server info"); } QueryResult_AutoPtr resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD); if (resultGuild) { Field *fields = resultGuild->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); } else if (pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about non existed membership { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } if (pCurrChar->GetGuildId() != 0) { Guild* guild = objmgr.GetGuildById(pCurrChar->GetGuildId()); if (guild) { data.Initialize(SMSG_GUILD_EVENT, (1+1+guild->GetMOTD().size()+1)); data << uint8(GE_MOTD); data << uint8(1); data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG("WORLD: Sent guild-motd (SMSG_GUILD_EVENT)"); data.Initialize(SMSG_GUILD_EVENT, (5+10)); // we guess size data<<(uint8)GE_SIGNED_ON; data<<(uint8)1; data<<pCurrChar->GetName(); data<<pCurrChar->GetGUID(); guild->BroadcastPacket(&data); DEBUG_LOG("WORLD: Sent guild-signed-on (SMSG_GUILD_EVENT)"); // Increment online members of the guild guild->IncOnlineMemberCount(); } else { // remove wrong guild data sLog.outError("Player %s (GUID: %u) marked as member of invalid guild (id: %u), removing guild membership for player.",pCurrChar->GetName(),pCurrChar->GetGUIDLow(),pCurrChar->GetGuildId()); pCurrChar->SetInGuild(0); } } if (!pCurrChar->isAlive()) pCurrChar->SendCorpseReclaimDelay(true); pCurrChar->SendInitialPacketsBeforeAddToMap(); //Show cinematic at the first time that player login if (!pCurrChar->getCinematic()) { pCurrChar->setCinematic(1); if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) { pCurrChar->SendCinematicStart(rEntry->CinematicSequence); // send new char string if not empty if (!sWorld.GetNewCharString().empty()) chH.PSendSysMessage("%s", sWorld.GetNewCharString().c_str()); } } if (!pCurrChar->GetMap()->Add(pCurrChar)) { // normal delayed teleport protection not applied (and this correct) for this case (Player object just created) AreaTrigger const* at = objmgr.GetGoBackTrigger(pCurrChar->GetMapId()); if (at) pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); else pCurrChar->TeleportToHomebind(); } ObjectAccessor::Instance().AddObject(pCurrChar); //sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); pCurrChar->GetSocial()->SendSocialList(); pCurrChar->SendInitialPacketsAfterAddToMap(); CharacterDatabase.PExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", pCurrChar->GetGUIDLow()); //LoginDatabase.PExecute("UPDATE account SET active_realm_id = %d WHERE id = '%u'", realmID, GetAccountId()); pCurrChar->SetInGameTime(getMSTime()); // announce group about member online (must be after add to player list to receive announce to self) if (Group *group = pCurrChar->GetGroup()) group->SendUpdate(); // friend status sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), true); // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); // setting Ghost+speed if dead if (pCurrChar->m_deathState != ALIVE) { // not blizz like, we must correctly save and load player instead... if (pCurrChar->getRace() == RACE_NIGHTELF) { pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) } pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) pCurrChar->SetMovement(MOVE_WATER_WALK); } pCurrChar->ContinueTaxiFlight(); // Load pet if any and player is alive and not in taxi flight if (pCurrChar->isAlive() && pCurrChar->m_taxi.GetTaxiSource() == 0) pCurrChar->LoadPet(); // Set FFA PvP for non GM in non-rest mode if (sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_RESTING)) pCurrChar->SetFFAPvP(true); if (pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP)) pCurrChar->SetContestedPvP(); // Apply at_login requests if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) { pCurrChar->resetSpells(); SendNotification(LANG_RESET_SPELLS); } if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) { pCurrChar->resetTalents(true); SendNotification(LANG_RESET_TALENTS); } // show time before shutdown if shutdown planned. if (sWorld.IsShutdowning()) sWorld.ShutdownMsg(true,pCurrChar); // ImpConfig - Max weapon skill when logging in if (sWorld.getConfig(CONFIG_ALWAYS_MAXSKILL)) pCurrChar->UpdateSkillsToMaxSkillsForLevel(); if (sWorld.getConfig(CONFIG_ALL_TAXI_PATHS)) pCurrChar->SetTaxiCheater(true); //Reputations if "StartAllReputation" is enabled if (sWorld.getConfig(CONFIG_START_ALL_REP)) { pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(942),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(935),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(936),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(1011),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(970),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(967),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(989),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(932),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(934),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(1038),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(1077),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(990),42999); // Factions depending on team, like cities and some more stuff switch(pCurrChar->GetTeam()) { case ALLIANCE: pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(72),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(47),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(69),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(930),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(730),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(978),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(54),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(946),42999); break; case HORDE: pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(76),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(68),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(81),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(911),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(729),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(941),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(530),42999); pCurrChar->SetFactionReputation(sFactionStore.LookupEntry(947),42999); break; default: break; } } if (pCurrChar->isGameMaster()) SendNotification(LANG_GM_ON); std::string IP_str = GetRemoteAddress(); sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), pCurrChar->GetName(), pCurrChar->GetGUIDLow()); m_playerLoading = false; //Hook for OnLogin Event sScriptMgr.OnLogin(pCurrChar); delete holder; }
void WorldSession::HandleMovementOpcodes(WorldPacket& recvData) { uint16 opcode = recvData.GetOpcode(); Unit* mover = _player->m_mover; ASSERT(mover != NULL); // there must always be a mover Player* plrMover = mover->ToPlayer(); // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck if (plrMover && plrMover->IsBeingTeleported()) { recvData.rfinish(); // prevent warnings spam return; } /* extract packet */ uint64 guid; recvData.readPackGUID(guid); MovementInfo movementInfo; movementInfo.guid = guid; ReadMovementInfo(recvData, &movementInfo); recvData.rfinish(); // prevent warnings spam // prevent tampered movement data if (guid != mover->GetGUID()) return; if (!movementInfo.pos.IsPositionValid()) { recvData.rfinish(); // prevent warnings spam return; } /* handle special cases */ if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) { // transports size limited // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped) if (movementInfo.transport.pos.GetPositionX() > 50 || movementInfo.transport.pos.GetPositionY() > 50 || movementInfo.transport.pos.GetPositionZ() > 50) { recvData.rfinish(); // prevent warnings spam return; } if (!Trinity::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.transport.pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.transport.pos.GetPositionY(), movementInfo.pos.GetPositionZ() + movementInfo.transport.pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.transport.pos.GetOrientation())) { recvData.rfinish(); // prevent warnings spam return; } // if we boarded a transport, add us to it if (plrMover) { if (!plrMover->GetTransport()) { // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter) { if ((*iter)->GetGUID() == movementInfo.transport.guid) { plrMover->m_transport = *iter; (*iter)->AddPassenger(plrMover); break; } } } else if (plrMover->GetTransport()->GetGUID() != movementInfo.transport.guid) { bool foundNewTransport = false; plrMover->m_transport->RemovePassenger(plrMover); for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter) { if ((*iter)->GetGUID() == movementInfo.transport.guid) { foundNewTransport = true; plrMover->m_transport = *iter; (*iter)->AddPassenger(plrMover); break; } } if (!foundNewTransport) { plrMover->m_transport = NULL; movementInfo.transport.Reset(); } } } if (!mover->GetTransport() && !mover->GetVehicle()) { GameObject* go = mover->GetMap()->GetGameObject(movementInfo.transport.guid); if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT) movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT; } } else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave { plrMover->m_transport->RemovePassenger(plrMover); plrMover->m_transport = NULL; movementInfo.transport.Reset(); } // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map). if (opcode == MSG_MOVE_FALL_LAND && plrMover && !plrMover->IsInFlight()) plrMover->HandleFall(movementInfo); if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater()) { // now client not include swimming flag in case jumping under water plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ())); } if (plrMover) sAnticheatMgr->StartHackDetection(plrMover, movementInfo, opcode); /*----------------------*/ /* process position-change */ WorldPacket data(opcode, recvData.size()); movementInfo.time = getMSTime(); movementInfo.guid = mover->GetGUID(); WriteMovementInfo(&data, &movementInfo); mover->SendMessageToSet(&data, _player); mover->m_movementInfo = movementInfo; // this is almost never true (not sure why it is sometimes, but it is), normally use mover->IsVehicle() if (mover->GetVehicle()) { mover->SetOrientation(movementInfo.pos.GetOrientation()); return; } mover->UpdatePosition(movementInfo.pos); if (plrMover) // nothing is charmed, or player charmed { plrMover->UpdateFallInformationIfNeed(movementInfo, opcode); float underMapValueZ; switch (plrMover->GetMapId()) { case 617: // Dalaran Sewers underMapValueZ = 3.0f; break; case 618: // Ring of Valor underMapValueZ = 28.0f; break; case 562: // Blade Edge Arena underMapValueZ = -10.0f; break; case 559: // Nagrand arena underMapValueZ = -18.0f; break; case 572: // Lordearon underMapValueZ = 28.0f; break; case 571: // Northrend underMapValueZ = -400.0f; break; default: underMapValueZ = -500.0f; break; } if (plrMover->GetMapId() == 617 && movementInfo.pos.GetPositionZ() < 3.0) // Dalaran Arena plrMover->TeleportTo(617, 13313.605f, 813.23f, 7.11f, 5.1f); if (movementInfo.pos.GetPositionZ() < -500.0f) { if (underMapValueZ != -500) // Only Case Values { // Hackfix for ArenaUnderZ -> Teleport if (plrMover->GetMapId() == 572) // Lordaeron Arena plrMover->TeleportTo(572, 1286.14868f, 1667.32f, 41.0f, 1.6f); if (plrMover->GetMapId() == 559) // Nagrand Arena plrMover->TeleportTo(559, 4052.79868f, 2926.32f, 16.0f, 1.6f); if (plrMover->GetMapId() == 562) // Blade Edge arena plrMover->TeleportTo(562, 6237.79768f, 261.142f, 2.0f, 4.0f); if (plrMover->GetMapId() == 617) // Dalaran Arena plrMover->TeleportTo(617, 1292.34868f, 790.40f, 8.5f, 1.6f); } else if (!(plrMover->GetBattleground() && plrMover->GetBattleground()->HandlePlayerUnderMap(_player))) { // NOTE: this is actually called many times while falling // even after the player has been teleported away /// @todo discard movement packets after the player is rooted if (plrMover->IsAlive()) { plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth()); // player can be alive if GM/etc // change the death state to CORPSE to prevent the death timer from // starting in the next player update if (!plrMover->IsAlive()) plrMover->KillPlayer(); } } } } }
void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data ) { std::string membername; recv_data >> membername; // attempt add selected player // cheating if(!normalizePlayerName(membername)) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET); return; } Player *player = objmgr.GetPlayer(membername.c_str()); // no player if(!player) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET); return; } // restrict invite to GMs if (!sWorld.getConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->isGameMaster() && player->isGameMaster()) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET); return; } // can't group with if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_UNFRIENDLY); return; } if(GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_NOT_IN_YOUR_INSTANCE); return; } // just ignore us if(player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty()) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_IGNORE_YOU); return; } if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_IGNORE_YOU); return; } Group *group = GetPlayer()->GetGroup(); if( group && group->isBGGroup() ) group = GetPlayer()->GetOriginalGroup(); Group *group2 = player->GetGroup(); if( group2 && group2->isBGGroup() ) group2 = player->GetOriginalGroup(); // player already in another group or invited if( group2 || player->GetGroupInvite() ) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_ALREADY_IN_GROUP); return; } if(group) { // not have permissions for invite if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) { SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_YOU_NOT_LEADER); return; } // not have place if(group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL); return; } } // ok, but group not exist, start a new group // but don't create and save the group to the DB until // at least one person joins if(!group) { group = new Group; // new group: if can't add then delete if(!group->AddLeaderInvite(GetPlayer())) { delete group; return; } if(!group->AddInvite(player)) { delete group; return; } } else { // already existed group: if can't add then just leave if(!group->AddInvite(player)) { return; } } // ok, we do it WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size data << uint8(1); // ok data << GetPlayer()->GetName(); player->GetSession()->SendPacket(&data); SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_OK); }
static bool HandleMmapLocCommand(ChatHandler* handler, char const* /*args*/) { handler->PSendSysMessage("mmap tileloc:"); // grid tile location Player* player = handler->GetSession()->GetPlayer(); int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS; int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS; handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gy, gx); handler->PSendSysMessage("gridloc [%i, %i]", gx, gy); // calculate navmesh tile location dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId()); dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(handler->GetSession()->GetPlayer()->GetMapId(), player->GetInstanceId()); if (!navmesh || !navmeshquery) { handler->PSendSysMessage("NavMesh not loaded for current map."); return true; } float const* min = navmesh->getParams()->orig; float x, y, z; player->GetPosition(x, y, z); float location[VERTEX_SIZE] = {y, z, x}; float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f}; int32 tilex = int32((y - min[0]) / SIZE_OF_GRIDS); int32 tiley = int32((x - min[2]) / SIZE_OF_GRIDS); handler->PSendSysMessage("Calc [%02i, %02i]", tilex, tiley); // navmesh poly -> navmesh tile location dtQueryFilter filter = dtQueryFilter(); dtPolyRef polyRef = INVALID_POLYREF; if (dtStatusFailed(navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, NULL))) { handler->PSendSysMessage("Dt [??,??] (invalid poly, probably no tile loaded)"); return true; } if (polyRef == INVALID_POLYREF) handler->PSendSysMessage("Dt [??, ??] (invalid poly, probably no tile loaded)"); else { dtMeshTile const* tile; dtPoly const* poly; if (dtStatusSucceed(navmesh->getTileAndPolyByRef(polyRef, &tile, &poly))) { if (tile) { handler->PSendSysMessage("Dt [%02i,%02i]", tile->header->x, tile->header->y); return false; } } handler->PSendSysMessage("Dt [??,??] (no tile loaded)"); } return true; }
void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recv_data) { uint8 slotid; uint64 lootguid, target_playerguid; recv_data >> lootguid >> slotid >> target_playerguid; if (!_player->GetGroup() || _player->GetGroup()->GetMasterLooterGuid() != _player->GetGUID() || _player->GetGroup()->GetLootMethod() != MASTER_LOOT) { _player->SendLootError(lootguid, LOOT_ERROR_DIDNT_KILL); return; } Player* target = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(target_playerguid, 0, HIGHGUID_PLAYER)); if (!target) { _player->SendLootError(lootguid, LOOT_ERROR_PLAYER_NOT_FOUND); return; } // TODO : add some error message? if (_player->GetMapId() != target->GetMapId() || _player->GetDistance(target) > sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) return; sLog.outDebug("WorldSession::HandleLootMasterGiveOpcode (CMSG_LOOT_MASTER_GIVE, 0x02A3) Target = [%s].", target->GetName()); if (_player->GetLootGUID() != lootguid) { _player->SendLootError(lootguid, LOOT_ERROR_DIDNT_KILL); return; } Loot* pLoot = NULL; if (IS_CREATURE_GUID(GetPlayer()->GetLootGUID())) { Creature* pCreature = GetPlayer()->GetMap()->GetCreature(lootguid); if (!pCreature) return; pLoot = &pCreature->loot; } else if (IS_GAMEOBJECT_GUID(GetPlayer()->GetLootGUID())) { GameObject* pGO = GetPlayer()->GetMap()->GetGameObject(lootguid); if (!pGO) return; pLoot = &pGO->loot; } if (!pLoot) return; if (slotid > pLoot->items.size()) { sLog.outDebug("AutoLootItem: Player %s might be using a hack! (slot %d, size %lu)", GetPlayer()->GetName(), slotid, (unsigned long)pLoot->items.size()); return; } LootItem& item = pLoot->items[slotid]; ItemPosCountVec dest; uint8 msg = target->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item.itemid, item.count); if (msg != EQUIP_ERR_OK) { if (msg == EQUIP_ERR_CANT_CARRY_MORE_OF_THIS) _player->SendLootError(lootguid, LOOT_ERROR_MASTER_UNIQUE_ITEM); else if (msg == EQUIP_ERR_INVENTORY_FULL) _player->SendLootError(lootguid, LOOT_ERROR_MASTER_INV_FULL); else _player->SendLootError(lootguid, LOOT_ERROR_MASTER_OTHER); target->SendEquipError(msg, NULL, NULL); return; } // now move item from loot to target inventory Item* newitem = target->StoreNewItem(dest, item.itemid, true, item.randomPropertyId); target->SendNewItem(newitem, uint32(item.count), false, false, true); // mark as looted item.count = 0; item.is_looted = true; pLoot->NotifyItemRemoved(slotid); --pLoot->unlootedCount; }
void Transporter::TransportPassengers(uint32 mapid, uint32 oldmap, float x, float y, float z) { sEventMgr.RemoveEvents(this, EVENT_TRANSPORTER_NEXT_WAYPOINT); if(mPassengers.size() > 0) { PassengerIterator itr = mPassengers.begin(); PassengerIterator it2; WorldPacket Pending(SMSG_TRANSFER_PENDING, 12); Pending << mapid << GetEntry() << oldmap; WorldPacket NewWorld; LocationVector v; for(; itr != mPassengers.end();) { it2 = itr; ++itr; Player *plr = objmgr.GetPlayer(it2->first); if(!plr) { // remove all non players from map mPassengers.erase(it2); continue; } if(!plr->GetSession() || !plr->IsInWorld()) continue; plr->m_lockTransportVariables = true; v.x = x + plr->m_TransporterX; v.y = y + plr->m_TransporterY; v.z = z + plr->m_TransporterZ; v.o = plr->GetOrientation(); if(mapid == 530 && !plr->GetSession()->HasFlag(ACCOUNT_FLAG_XPACK_01)) { // player does not have BC content, repop at graveyard plr->RepopAtGraveyard(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), plr->GetMapId()); continue; } plr->GetSession()->SendPacket(&Pending); plr->_Relocate(mapid, v, false, true, 0); // Lucky bitch. Do it like on official. 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)); } } } // Set our position RemoveFromWorld(false); SetMapId(mapid); SetPosition(x,y,z,m_position.o,false); AddToWorld(); }
void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data) { uint16 opcode = recv_data.GetOpcode(); Unit* mover = _player->m_mover; ASSERT(mover != NULL); // there must always be a mover Player* plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL; // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck if (plMover && plMover->IsBeingTeleported()) { recv_data.rfinish(); // prevent warnings spam return; } /* extract packet */ uint64 guid; recv_data.readPackGUID(guid); MovementInfo movementInfo; movementInfo.guid = guid; ReadMovementInfo(recv_data, &movementInfo); recv_data.rfinish(); // prevent warnings spam // prevent tampered movement data if (guid != mover->GetGUID()) return; if (!movementInfo.pos.IsPositionValid()) { recv_data.rfinish(); // prevent warnings spam return; } /* handle special cases */ if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) { // transports size limited // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped) if (movementInfo.t_pos.GetPositionX() > 50 || movementInfo.t_pos.GetPositionY() > 50 || movementInfo.t_pos.GetPositionZ() > 50) { recv_data.rfinish(); // prevent warnings spam return; } if (!Trinity::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.t_pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.t_pos.GetPositionY(), movementInfo.pos.GetPositionZ() + movementInfo.t_pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.t_pos.GetOrientation())) { recv_data.rfinish(); // prevent warnings spam return; } // if we boarded a transport, add us to it if (plMover && !plMover->GetTransport()) { // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter) { if ((*iter)->GetGUID() == movementInfo.t_guid) { plMover->m_transport = (*iter); (*iter)->AddPassenger(plMover); break; } } } if (!mover->GetTransport() && !mover->GetVehicle()) { GameObject* go = mover->GetMap()->GetGameObject(movementInfo.t_guid); if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT) movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT; } } else if (plMover && plMover->GetTransport()) // if we were on a transport, leave { plMover->m_transport->RemovePassenger(plMover); plMover->m_transport = NULL; movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); movementInfo.t_time = 0; movementInfo.t_seat = -1; } // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map). if (opcode == MSG_MOVE_FALL_LAND && plMover && !plMover->isInFlight()) plMover->HandleFall(movementInfo); if (plMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plMover->IsInWater()) { // now client not include swimming flag in case jumping under water plMover->SetInWater(!plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ())); } if (plMover) sAnticheatMgr->StartHackDetection(plMover, movementInfo, opcode); /*----------------------*/ /* process position-change */ WorldPacket data(opcode, recv_data.size()); movementInfo.time = getMSTime(); movementInfo.guid = mover->GetGUID(); WriteMovementInfo(&data, &movementInfo); mover->SendMessageToSet(&data, _player); mover->m_movementInfo = movementInfo; // this is almost never true (not sure why it is sometimes, but it is), normally use mover->IsVehicle() if (mover->GetVehicle()) { mover->SetOrientation(movementInfo.pos.GetOrientation()); return; } mover->UpdatePosition(movementInfo.pos); if (plMover) // nothing is charmed, or player charmed { plMover->UpdateFallInformationIfNeed(movementInfo, opcode); float underMapValueZ; switch (plMover->GetMapId()) { case 617: underMapValueZ = 3.0f; break; // Dalaran Sewers case 618: underMapValueZ = 28.0f; break; // Ring of Valor default: underMapValueZ = -500.0f; break; } if (movementInfo.pos.GetPositionZ() < underMapValueZ) { if (!(plMover->InBattleground() && plMover->GetBattleground() && plMover->GetBattleground()->HandlePlayerUnderMap(_player))) { // NOTE: this is actually called many times while falling // even after the player has been teleported away // TODO: discard movement packets after the player is rooted if (plMover->isAlive()) { plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth()); // pl can be alive if GM/etc // change the death state to CORPSE to prevent the death timer from // starting in the next player update if (!plMover->isAlive()) plMover->KillPlayer(); } } } } }
void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) { ObjectGuid playerGuid = holder->GetGuid(); Player* pCurrChar = new Player(this); pCurrChar->GetMotionMaster()->Initialize(); // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if (!pCurrChar->LoadFromDB(playerGuid, holder)) { KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete pCurrChar; // delete it manually delete holder; // delete all unprocessed queries m_playerLoading = false; return; } SetPlayer(pCurrChar); WorldPacket data(SMSG_LOGIN_VERIFY_WORLD, 20); data << pCurrChar->GetMapId(); data << pCurrChar->GetPositionX(); data << pCurrChar->GetPositionY(); data << pCurrChar->GetPositionZ(); data << pCurrChar->GetOrientation(); SendPacket(&data); data.Initialize(SMSG_ACCOUNT_DATA_TIMES, 128); for (int i = 0; i < 32; ++i) data << uint32(0); SendPacket(&data); // Send MOTD (1.12.1 not have SMSG_MOTD, so do it in another way) { uint32 linecount = 0; std::string str_motd = sWorld.GetMotd(); std::string::size_type pos, nextpos; std::string motd; pos = 0; while ((nextpos = str_motd.find('@', pos)) != std::string::npos) { if (nextpos != pos) { ChatHandler(pCurrChar).PSendSysMessage("%s", str_motd.substr(pos, nextpos - pos).c_str()); ++linecount; } pos = nextpos + 1; } if (pos < str_motd.length()) { ChatHandler(pCurrChar).PSendSysMessage("%s", str_motd.substr(pos).c_str()); ++linecount; } DEBUG_LOG("WORLD: Sent motd (SMSG_MOTD)"); } // QueryResult *result = CharacterDatabase.PQuery("SELECT guildid,rank FROM guild_member WHERE guid = '%u'",pCurrChar->GetGUIDLow()); QueryResult* resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD); if (resultGuild) { Field* fields = resultGuild->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); delete resultGuild; } else if (pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about nonexistent membership { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } if (pCurrChar->GetGuildId() != 0) { Guild* guild = sGuildMgr.GetGuildById(pCurrChar->GetGuildId()); if (guild) { data.Initialize(SMSG_GUILD_EVENT, (1 + 1 + guild->GetMOTD().size() + 1)); data << uint8(GE_MOTD); data << uint8(1); data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG("WORLD: Sent guild-motd (SMSG_GUILD_EVENT)"); guild->BroadcastEvent(GE_SIGNED_ON, pCurrChar->GetObjectGuid(), pCurrChar->GetName()); } else { // remove wrong guild data sLog.outError("Player %s (GUID: %u) marked as member of nonexistent guild (id: %u), removing guild membership for player.", pCurrChar->GetName(), pCurrChar->GetGUIDLow(), pCurrChar->GetGuildId()); pCurrChar->SetInGuild(0); } } if (!pCurrChar->isAlive()) pCurrChar->SendCorpseReclaimDelay(true); pCurrChar->SendInitialPacketsBeforeAddToMap(); // Show cinematic at the first time that player login if (!pCurrChar->getCinematic()) { pCurrChar->setCinematic(1); if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) pCurrChar->SendCinematicStart(rEntry->CinematicSequence); } uint32 miscRequirement = 0; AreaLockStatus lockStatus = AREA_LOCKSTATUS_OK; if (AreaTrigger const* at = sObjectMgr.GetMapEntranceTrigger(pCurrChar->GetMapId())) lockStatus = pCurrChar->GetAreaTriggerLockStatus(at, miscRequirement); else { // Some basic checks in case of a map without areatrigger MapEntry const* mapEntry = sMapStore.LookupEntry(pCurrChar->GetMapId()); if (!mapEntry) lockStatus = AREA_LOCKSTATUS_UNKNOWN_ERROR; } if (lockStatus != AREA_LOCKSTATUS_OK || !pCurrChar->GetMap()->Add(pCurrChar)) { // normal delayed teleport protection not applied (and this correct) for this case (Player object just created) AreaTrigger const* at = sObjectMgr.GetGoBackTrigger(pCurrChar->GetMapId()); if (at) lockStatus = pCurrChar->GetAreaTriggerLockStatus(at, miscRequirement); if (!at || lockStatus != AREA_LOCKSTATUS_OK || !pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation())) pCurrChar->TeleportToHomebind(); } sObjectAccessor.AddObject(pCurrChar); // DEBUG_LOG("Player %s added to Map.",pCurrChar->GetName()); pCurrChar->GetSocial()->SendFriendList(); pCurrChar->GetSocial()->SendIgnoreList(); pCurrChar->SendInitialPacketsAfterAddToMap(); static SqlStatementID updChars; static SqlStatementID updAccount; SqlStatement stmt = CharacterDatabase.CreateStatement(updChars, "UPDATE characters SET online = 1 WHERE guid = ?"); stmt.PExecute(pCurrChar->GetGUIDLow()); stmt = LoginDatabase.CreateStatement(updAccount, "UPDATE account SET active_realm_id = ? WHERE id = ?"); stmt.PExecute(realmID, GetAccountId()); pCurrChar->SetInGameTime(WorldTimer::getMSTime()); // announce group about member online (must be after add to player list to receive announce to self) if (Group* group = pCurrChar->GetGroup()) group->SendUpdate(); // friend status sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetObjectGuid(), true); // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); // setting Ghost+speed if dead if (pCurrChar->m_deathState != ALIVE) { // not blizz like, we must correctly save and load player instead... if (pCurrChar->getRace() == RACE_NIGHTELF) pCurrChar->CastSpell(pCurrChar, 20584, true); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, 8326, true); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) pCurrChar->SetWaterWalk(true); } pCurrChar->ContinueTaxiFlight(); // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned) pCurrChar->LoadPet(); // Set FFA PvP for non GM in non-rest mode if (sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING)) pCurrChar->SetFFAPvP(true); if (pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP)) pCurrChar->SetContestedPvP(); // Apply at_login requests if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) { pCurrChar->resetSpells(); SendNotification(LANG_RESET_SPELLS); } if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) { pCurrChar->resetTalents(true); SendNotification(LANG_RESET_TALENTS); // we can use SMSG_TALENTS_INVOLUNTARILY_RESET here } if (pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST)) pCurrChar->RemoveAtLoginFlag(AT_LOGIN_FIRST); // show time before shutdown if shutdown planned. if (sWorld.IsShutdowning()) sWorld.ShutdownMsg(true, pCurrChar); if (sWorld.getConfig(CONFIG_BOOL_ALL_TAXI_PATHS)) pCurrChar->SetTaxiCheater(true); if (pCurrChar->isGameMaster()) SendNotification(LANG_GM_ON); if (!pCurrChar->isGMVisible()) { SendNotification(LANG_INVISIBLE_INVISIBLE); SpellEntry const* invisibleAuraInfo = sSpellStore.LookupEntry(sWorld.getConfig(CONFIG_UINT32_GM_INVISIBLE_AURA)); if (invisibleAuraInfo && IsSpellAppliesAura(invisibleAuraInfo)) pCurrChar->CastSpell(pCurrChar, invisibleAuraInfo, true); } std::string IP_str = GetRemoteAddress(); sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), pCurrChar->GetName(), pCurrChar->GetGUIDLow()); if (!pCurrChar->IsStandState() && !pCurrChar->hasUnitState(UNIT_STAT_STUNNED)) pCurrChar->SetStandState(UNIT_STAND_STATE_STAND); m_playerLoading = false; if (sWorld.getConfig(CONFIG_BOOL_WORLD_LOGN_ON)) { sWorld.SendWorldText(20001, pCurrChar->GetName(), pCurrChar->getLevel()); } delete holder; }
bool ChatHandler::HandleFlyMountCommand(char* /*args*/) { Player *chr = m_session->GetPlayer(); // Zakaz: if( chr->isInCombat() // - Pocas combatu || chr->GetMap()->Instanceable() // - V instancii || !chr->CanFreeMove() ) // - Ak sa nemoze volne pohybovat (sap, taxi ...) { SendSysMessage(LANG_YOU_IN_COMBAT); SetSentErrorMessage(true); return false; } // smrt if(chr->isDead()) { SendSysMessage("You are dead!"); SetSentErrorMessage(true); return false; } // zakaz pre low lvl if(chr->getLevel() != 70) { SendSysMessage("Required 70 level!"); SetSentErrorMessage(true); return false; } switch(chr->GetAreaId()) { //case 1637: // orgrimmar //case 1519: // stormwind //case 3487: // silvermoon case 168: // Tirisfal glades sea case 1256: // Azshara sea case 4080: // ioqd SendSysMessage("Not allowed here!"); SetSentErrorMessage(true); return false; } // cely ioqd a Diremaul if(chr->GetZoneId() == 4080 || chr->GetZoneId() == 2557) { SendSysMessage("Not allowed here!"); SetSentErrorMessage(true); return false; } // ine mapy ako azeroth if(chr->GetMapId() != 0 && chr->GetMapId() != 1 && chr->GetMapId() != 530) { SendSysMessage("Not allowed here!"); SetSentErrorMessage(true); return false; } // dismount chr->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); Item * firstpositem = chr->GetItemByPos(INVENTORY_SLOT_BAG_0, 23); if(firstpositem && ( firstpositem->GetProto()->RequiredSkill == 762 && firstpositem->GetProto()->RequiredSkillRank > 150 || // 762 = riding skill firstpositem->GetProto()->ItemId == 34060 || // Flying Machine Control firstpositem->GetProto()->ItemId == 34061 )) // Turbo-Charged Flying Machine Control chr->CastSpell(chr, firstpositem->GetProto()->Spells[0].SpellId, false); else if(chr->getClass() == CLASS_DRUID) { // odstranenie formy chr->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT); // swift flight form chr->CastSpell(chr, 40120, false); } // alici grifina else if (chr->GetTeam() == ALLIANCE) chr->CastSpell(chr, 32290, false); // horda netopiera else chr->CastSpell(chr, 32295, false); return true; }
void FocusMagic(uint32 diff) { if (!FOCUSMAGIC || me->getLevel() < 20 || fmCheckTimer > diff || GC_Timer > diff || Rand() < 50 || IsCasting()) return; if (Unit* target = FindAffectedTarget(FOCUSMAGIC, me->GetGUID(), 70, 2)) { fmCheckTimer = 30000; return; } else { Group* pGroup = master->GetGroup(); if (!pGroup) { if (master->getPowerType() == POWER_MANA && !master->HasAura(FOCUSMAGIC) && me->GetExactDist(master) < 30) target = master; } else { for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pPlayer = itr->GetSource(); if (!pPlayer || pPlayer->isDead()) continue; if (me->GetMapId() != pPlayer->GetMapId()) continue; if ((pPlayer->getClass() == CLASS_MAGE || pPlayer->getClass() == CLASS_PRIEST || pPlayer->getClass() == CLASS_SHAMAN || pPlayer->getClass() == CLASS_DRUID || pPlayer->getClass() == CLASS_PALADIN || pPlayer->getClass() == CLASS_WARLOCK) && !pPlayer->HasAura(FOCUSMAGIC) && me->GetExactDist(pPlayer) < 30) { target = pPlayer; break; } } if (!target) { for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pPlayer = itr->GetSource(); if (!pPlayer || !pPlayer->HaveBot()) continue; if (me->GetMapId() != pPlayer->GetMapId()) continue; for (uint8 i = 0; i != pPlayer->GetMaxNpcBots(); ++i) { Creature* cre = pPlayer->GetBotMap(i)->_Cre(); if (!cre || cre == me || cre->isDead() || cre->getPowerType() != POWER_MANA) continue; if ((cre->GetBotClass() == CLASS_MAGE || cre->GetBotClass() == CLASS_PRIEST || cre->GetBotClass() == CLASS_SHAMAN || cre->GetBotClass() == CLASS_DRUID || cre->GetBotClass() == CLASS_WARLOCK) && !cre->HasAura(FOCUSMAGIC) && me->GetExactDist(cre) < 30) { target = cre; break; } } } } } if (target && doCast(target, FOCUSMAGIC)) { GC_Timer = 500; fmCheckTimer = 30000; return; } } fmCheckTimer = 5000; }
void WorldSession::HandleGroupInviteOpcode(WorldPacket & recv_data) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_INVITE"); std::string membername; recv_data >> membername; recv_data.read_skip<uint32>(); // attempt add selected player // cheating if (!normalizePlayerName(membername)) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } Player* player = sObjectAccessor->FindPlayerByName(membername.c_str()); // no player if (!player) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } // restrict invite to GMs if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->isGameMaster() && player->isGameMaster()) return; // can't group with if (!GetPlayer()->isGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_PLAYER_WRONG_FACTION); return; } if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us if (player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S); return; } if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S); return; } Group* group = GetPlayer()->GetGroup(); if (group && group->isBGGroup()) group = GetPlayer()->GetOriginalGroup(); Group* group2 = player->GetGroup(); if (group2 && group2->isBGGroup()) group2 = player->GetOriginalGroup(); // player already in another group or invited if (group2 || player->GetGroupInvite()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_ALREADY_IN_GROUP_S); if (group2) { // tell the player that they were invited but it failed as they were already in a group WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size data << uint8(0); // invited/already in group flag data << GetPlayer()->GetName(); // max len 48 data << uint32(0); // unk data << uint8(0); // count data << uint32(0); // unk player->GetSession()->SendPacket(&data); } return; } if (group) { // not have permissions for invite if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) { SendPartyResult(PARTY_OP_INVITE, "", ERR_NOT_LEADER); return; } // not have place if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } } // ok, but group not exist, start a new group // but don't create and save the group to the DB until // at least one person joins if (!group) { group = new Group; // new group: if can't add then delete if (!group->AddLeaderInvite(GetPlayer())) { delete group; return; } if (!group->AddInvite(player)) { delete group; return; } } else { // already existed group: if can't add then just leave if (!group->AddInvite(player)) { return; } } // ok, we do it WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size data << uint8(1); // invited/already in group flag data << GetPlayer()->GetName(); // max len 48 data << uint32(0); // unk data << uint8(0); // count data << uint32(0); // unk player->GetSession()->SendPacket(&data); SendPartyResult(PARTY_OP_INVITE, membername, ERR_PARTY_RESULT_OK); }
//show info of player bool ChatHandler::HandlePInfoCommand(const char* args) { Player* target; uint64 target_guid; std::string target_name; uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER); if (sObjectMgr->GetPlayerNameByGUID(parseGUID, target_name)) { target = sObjectMgr->GetPlayerByLowGUID(parseGUID); target_guid = parseGUID; } else if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; uint32 accId = 0; uint32 money = 0; uint32 total_player_time = 0; uint8 level = 0; uint32 latency = 0; uint8 race; uint8 Class; int64 muteTime = 0; int64 banTime = -1; uint32 mapId; uint32 areaId; uint32 phase = 0; // get additional information from Player object if (target) { // check online security if (HasLowerSecurity(target, 0)) return false; accId = target->GetSession()->GetAccountId(); money = target->GetMoney(); total_player_time = target->GetTotalPlayedTime(); level = target->getLevel(); latency = target->GetSession()->GetLatency(); race = target->getRace(); Class = target->getClass(); muteTime = target->GetSession()->m_muteTime; mapId = target->GetMapId(); areaId = target->GetAreaId(); phase = target->GetPhaseMask(); } // get additional information from DB else { // check offline security if (HasLowerSecurity(NULL, target_guid)) return false; // 0 1 2 3 4 5 6 7 QueryResult result = CharacterDatabase.PQuery("SELECT totaltime, level, money, account, race, class, map, zone FROM characters " "WHERE guid = '%u'", GUID_LOPART(target_guid)); if (!result) return false; Field* fields = result->Fetch(); total_player_time = fields[0].GetUInt32(); level = fields[1].GetUInt32(); money = fields[2].GetUInt32(); accId = fields[3].GetUInt32(); race = fields[4].GetUInt8(); Class = fields[5].GetUInt8(); mapId = fields[6].GetUInt16(); areaId = fields[7].GetUInt16(); } std::string username = GetTrinityString(LANG_ERROR); std::string email = GetTrinityString(LANG_ERROR); std::string last_ip = GetTrinityString(LANG_ERROR); uint32 security = 0; std::string last_login = GetTrinityString(LANG_ERROR); QueryResult result = LoginDatabase.PQuery("SELECT a.username, aa.gmlevel, a.email, a.last_ip, a.last_login, a.mutetime " "FROM account a " "LEFT JOIN account_access aa " "ON (a.id = aa.id) " "WHERE a.id = '%u'", accId); if (result) { Field* fields = result->Fetch(); username = fields[0].GetString(); security = fields[1].GetUInt32(); email = fields[2].GetString(); muteTime = fields[5].GetUInt64(); if (email.empty()) email = "-"; if (!m_session || m_session->GetSecurity() >= AccountTypes(security)) { last_ip = fields[3].GetString(); last_login = fields[4].GetString(); } else { last_ip = "-"; last_login = "******"; } } std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetTrinityString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(target_guid), username.c_str(), accId, email.c_str(), security, last_ip.c_str(), last_login.c_str(), latency); std::string bannedby = "unknown"; std::string banreason = ""; if (QueryResult result2 = LoginDatabase.PQuery("SELECT unbandate, bandate = unbandate, bannedby, banreason FROM account_banned " "WHERE id = '%u' AND active ORDER BY bandate ASC LIMIT 1", accId)) { Field* fields = result2->Fetch(); banTime = fields[1].GetBool() ? 0 : fields[0].GetUInt64(); bannedby = fields[2].GetString(); banreason = fields[3].GetString(); } else if (QueryResult result3 = CharacterDatabase.PQuery("SELECT unbandate, bandate = unbandate, bannedby, banreason FROM character_banned " "WHERE guid = '%u' AND active ORDER BY bandate ASC LIMIT 1", GUID_LOPART(target_guid))) { Field* fields = result3->Fetch(); banTime = fields[1].GetBool() ? 0 : fields[0].GetUInt64(); bannedby = fields[2].GetString(); banreason = fields[3].GetString(); } if (muteTime > 0) PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str()); if (banTime >= 0) PSendSysMessage(LANG_PINFO_BAN, banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "permanently", bannedby.c_str(), banreason.c_str()); std::string race_s, Class_s; switch (race) { case RACE_HUMAN: race_s = "Human"; break; case RACE_ORC: race_s = "Orc"; break; case RACE_DWARF: race_s = "Dwarf"; break; case RACE_NIGHTELF: race_s = "Night Elf"; break; case RACE_UNDEAD_PLAYER: race_s = "Undead"; break; case RACE_TAUREN: race_s = "Tauren"; break; case RACE_GNOME: race_s = "Gnome"; break; case RACE_TROLL: race_s = "Troll"; break; case RACE_BLOODELF: race_s = "Blood Elf"; break; case RACE_DRAENEI: race_s = "Draenei"; break; } switch (Class) { case CLASS_WARRIOR: Class_s = "Warrior"; break; case CLASS_PALADIN: Class_s = "Paladin"; break; case CLASS_HUNTER: Class_s = "Hunter"; break; case CLASS_ROGUE: Class_s = "Rogue"; break; case CLASS_PRIEST: Class_s = "Priest"; break; case CLASS_DEATH_KNIGHT: Class_s = "Death Knight"; break; case CLASS_SHAMAN: Class_s = "Shaman"; break; case CLASS_MAGE: Class_s = "Mage"; break; case CLASS_WARLOCK: Class_s = "Warlock"; break; case CLASS_DRUID: Class_s = "Druid"; break; } std::string timeStr = secsToTimeString(total_player_time, true, true); uint32 gold = money /GOLD; uint32 silv = (money % GOLD) / SILVER; uint32 copp = (money % GOLD) % SILVER; PSendSysMessage(LANG_PINFO_LEVEL, race_s.c_str(), Class_s.c_str(), timeStr.c_str(), level, gold, silv, copp); // Add map, zone, subzone and phase to output int locale = GetSessionDbcLocale(); std::string areaName = "<unknown>"; std::string zoneName = ""; MapEntry const* map = sMapStore.LookupEntry(mapId); AreaTableEntry const* area = GetAreaEntryByAreaID(areaId); if (area) { areaName = area->area_name[locale]; AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone); if (zone) zoneName = zone->area_name[locale]; } if (target) { if (!zoneName.empty()) PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], zoneName.c_str(), areaName.c_str(), phase); else PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], areaName.c_str(), "<unknown>", phase); } else PSendSysMessage(LANG_PINFO_MAP_OFFLINE, map->name[locale], areaName.c_str()); return true; }
bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, const std::string& fullcmd) { char const* oldtext = text; std::string cmd = ""; while (*text != ' ' && *text != '\0') { cmd += *text; ++text; } while (*text == ' ') ++text; for (uint32 i = 0; table[i].Name != NULL; ++i) { if (!hasStringAbbr(table[i].Name, cmd.c_str())) continue; bool match = false; if (strlen(table[i].Name) > cmd.length()) { for (uint32 j = 0; table[j].Name != NULL; ++j) { if (!hasStringAbbr(table[j].Name, cmd.c_str())) continue; if (strcmp(table[j].Name, cmd.c_str()) != 0) continue; else { match = true; break; } } } if (match) continue; // select subcommand from child commands list if (table[i].ChildCommands != NULL) { if (!ExecuteCommandInTable(table[i].ChildCommands, text, fullcmd)) { if (text && text[0] != '\0') SendSysMessage(LANG_NO_SUBCMD); else SendSysMessage(LANG_CMD_SYNTAX); ShowHelpForCommand(table[i].ChildCommands, text); } return true; } // must be available and have handler if (!table[i].Handler || !isAvailable(table[i])) continue; SetSentErrorMessage(false); // table[i].Name == "" is special case: send original command to handler if ((table[i].Handler)(this, table[i].Name[0] != '\0' ? text : oldtext)) { if (!AccountMgr::IsPlayerAccount(table[i].SecurityLevel)) { // chat case if (m_session) { Player* p = m_session->GetPlayer(); uint64 sel_guid = p->GetSelection(); sLog->outCommand(m_session->GetAccountId(), "Command: %s [Player: %s (Account: %u) X: %f Y: %f Z: %f Map: %u Selected %s: %s (GUID: %u)]", fullcmd.c_str(), p->GetName(), m_session->GetAccountId(), p->GetPositionX(), p->GetPositionY(), p->GetPositionZ(), p->GetMapId(), GetLogNameForGuid(sel_guid), (p->GetSelectedUnit()) ? p->GetSelectedUnit()->GetName() : "", GUID_LOPART(sel_guid)); } } } // some commands have custom error messages. Don't send the default one in these cases. else if (!HasSentErrorMessage()) { if (!table[i].Help.empty()) SendSysMessage(table[i].Help.c_str()); else SendSysMessage(LANG_CMD_SYNTAX); } return true; } return false; }
void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) { sLog->outInfo(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_INVITE"); time_t now = time(NULL); if (now - timeLastGroupInviteCommand < 5) return; else timeLastGroupInviteCommand = now; ObjectGuid crossRealmGuid; // unused recvData.read_skip<uint32>(); // Non-zero in cross realm invites recvData.read_skip<uint8>(); recvData.read_skip<uint32>(); // Always 0 crossRealmGuid[7] = recvData.ReadBit(); uint8 realmLen = recvData.ReadBits(9); crossRealmGuid[3] = recvData.ReadBit(); uint8 nameLen = recvData.ReadBits(9); crossRealmGuid[2] = recvData.ReadBit(); crossRealmGuid[5] = recvData.ReadBit(); crossRealmGuid[4] = recvData.ReadBit(); crossRealmGuid[0] = recvData.ReadBit(); crossRealmGuid[1] = recvData.ReadBit(); crossRealmGuid[6] = recvData.ReadBit(); recvData.ReadByteSeq(crossRealmGuid[7]); recvData.ReadByteSeq(crossRealmGuid[6]); recvData.ReadByteSeq(crossRealmGuid[0]); recvData.ReadByteSeq(crossRealmGuid[4]); std::string realmName = recvData.ReadString(realmLen); // unused recvData.ReadByteSeq(crossRealmGuid[1]); recvData.ReadByteSeq(crossRealmGuid[2]); recvData.ReadByteSeq(crossRealmGuid[3]); std::string memberName = recvData.ReadString(nameLen); recvData.ReadByteSeq(crossRealmGuid[5]); // attempt add selected player // cheating if (!normalizePlayerName(memberName)) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } Player* player = sObjectAccessor->FindPlayerByName(memberName.c_str()); // no player if (!player) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } // restrict invite to GMs if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->isGameMaster() && player->isGameMaster()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } // can't group with if (!GetPlayer()->isGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PLAYER_WRONG_FACTION); return; } if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us if (player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); return; } if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); return; } Group* group = GetPlayer()->GetGroup(); if (group && group->isBGGroup()) group = GetPlayer()->GetOriginalGroup(); Group* group2 = player->GetGroup(); if (group2 && group2->isBGGroup()) group2 = player->GetOriginalGroup(); // player already in another group or invited if (group2 || player->GetGroupInvite()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_ALREADY_IN_GROUP_S); if (group2) { // tell the player that they were invited but it failed as they were already in a group player->GetSession()->SendGroupInviteNotification(GetPlayer()->GetName(), true); } return; } if (group) { // not have permissions for invite if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) { SendPartyResult(PARTY_OP_INVITE, "", ERR_NOT_LEADER); return; } // not have place if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } } // ok, but group not exist, start a new group // but don't create and save the group to the DB until // at least one person joins if (!group) { group = new Group; // new group: if can't add then delete if (!group->AddLeaderInvite(GetPlayer())) { delete group; return; } if (!group->AddInvite(player)) { delete group; return; } } else { // already existed group: if can't add then just leave if (!group->AddInvite(player)) { return; } } // ok, we do it player->GetSession()->SendGroupInviteNotification(GetPlayer()->GetName(), false); SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PARTY_RESULT_OK); }
void WorldSession::HandleGroupInviteOpcode(WorldPacket& recv_data) { std::string membername; recv_data >> membername; // attempt add selected player // cheating if (!normalizePlayerName(membername)) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } Player* player = sObjectMgr.GetPlayer(membername.c_str()); // no player if (!player) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } // can't group with if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_PLAYER_WRONG_FACTION); return; } if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us if (player->GetSocial()->HasIgnore(GetPlayer()->GetObjectGuid())) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S); return; } Group* group = GetPlayer()->GetGroup(); if (group && group->isBGGroup()) group = GetPlayer()->GetOriginalGroup(); Group* group2 = player->GetGroup(); if (group2 && group2->isBGGroup()) group2 = player->GetOriginalGroup(); // player already in another group or invited if (group2 || player->GetGroupInvite()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_ALREADY_IN_GROUP_S); return; } if (group) { // not have permissions for invite if (!group->IsLeader(GetPlayer()->GetObjectGuid()) && !group->IsAssistant(GetPlayer()->GetObjectGuid())) { SendPartyResult(PARTY_OP_INVITE, "", ERR_NOT_LEADER); return; } // not have place if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } } // ok, but group not exist, start a new group // but don't create and save the group to the DB until // at least one person joins if (!group) { group = new Group; // new group: if can't add then delete if (!group->AddLeaderInvite(GetPlayer())) { delete group; return; } if (!group->AddInvite(player)) { delete group; return; } } else { // already existing group: if can't add then just leave if (!group->AddInvite(player)) { return; } } // ok, we do it WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size data << GetPlayer()->GetName(); player->GetSession()->SendPacket(&data); SendPartyResult(PARTY_OP_INVITE, membername, ERR_PARTY_RESULT_OK); }
bool ChatHandler::HandleGOSpawn(const char *args, WorldSession *m_session) { std::stringstream sstext; char* pEntryID = strtok((char*)args, " "); if (!pEntryID) return false; uint32 EntryID = atoi(pEntryID); bool Save = false; char* pSave = strtok(NULL, " "); if (pSave) Save = (atoi(pSave)>0?true:false); OUT_DEBUG("Spawning GameObject By Entry '%u'", EntryID); sstext << "Spawning GameObject By Entry '" << EntryID << "'" << '\0'; SystemMessage(m_session, sstext.str().c_str()); GameObject* go = m_session->GetPlayer()->GetMapMgr()->CreateGameObject(EntryID); if(go == NULL) { sstext << "GameObject Info '" << EntryID << "' Not Found" << '\0'; SystemMessage(m_session, sstext.str().c_str()); return true; } Player* chr = m_session->GetPlayer(); uint32 mapid = chr->GetMapId(); float x = chr->GetPositionX(); float y = chr->GetPositionY(); float z = chr->GetPositionZ(); float o = chr->GetOrientation(); go->SetInstanceID(chr->GetInstanceID()); go->CreateFromProto(EntryID,mapid,x,y,z,o,0.0f,0.0f,0.0f,0.0f); go->PushToWorld(m_session->GetPlayer()->GetMapMgr()); // Create spawn instance GOSpawn * gs = new GOSpawn; gs->entry = go->GetEntry(); gs->facing = go->GetOrientation(); gs->faction = go->GetUInt32Value(GAMEOBJECT_FACTION); gs->flags = go->GetUInt32Value(GAMEOBJECT_FLAGS); gs->id = objmgr.GenerateGameObjectSpawnID(); gs->orientation1 = go->GetFloatValue(GAMEOBJECT_ROTATION); gs->orientation2 = go->GetFloatValue(GAMEOBJECT_ROTATION_01); gs->orientation3 = go->GetFloatValue(GAMEOBJECT_ROTATION_02); gs->orientation4 = go->GetFloatValue(GAMEOBJECT_ROTATION_03); gs->scale = go->GetFloatValue(OBJECT_FIELD_SCALE_X); gs->x = go->GetPositionX(); gs->y = go->GetPositionY(); gs->z = go->GetPositionZ(); gs->state = go->GetByte(GAMEOBJECT_BYTES_1, GAMEOBJECT_BYTES_STATE); gs->phase = 1; uint32 cx = m_session->GetPlayer()->GetMapMgr()->GetPosX(m_session->GetPlayer()->GetPositionX()); uint32 cy = m_session->GetPlayer()->GetMapMgr()->GetPosY(m_session->GetPlayer()->GetPositionY()); m_session->GetPlayer()->GetMapMgr()->GetBaseMap()->GetSpawnsListAndCreate(cx,cy)->GOSpawns.push_back(gs); go->m_spawn = gs; if(Save == true) { // If we're saving, create template and add index go->SaveToDB(); } return true; }