void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) { uint32 opcode = recv_data.GetOpcode(); sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode); Unit *mover = _player->m_mover; Player *plMover = mover->GetTypeId()==TYPEID_PLAYER ? (Player*)mover : NULL; // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck if(plMover && plMover->IsBeingTeleported()) { // movement anticheat plMover->m_anti_JustTeleported = 1; // end movement anticheat return; } /* extract packet */ MovementInfo movementInfo; ReadMovementInfo(recv_data, &movementInfo); /*----------------*/ if(!(movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) && _player->GetVehicleGUID()) { if(mover->GetGUID() == _player->GetGUID()) { return; } } // we sent a movement packet with MOVEMENTFLAG_ONTRANSPORT and we are on vehicle // this can be moving on vehicle or entering another transport (eg. boat) if((movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) && _player->GetVehicleGUID()) { // we are controlling that vehicle if(mover->GetGUID() == _player->GetVehicleGUID()) { // we sent movement packet, related to movement ON vehicle, // but not WITH vehicle, so mover = player if(_player->GetVehicleGUID() == movementInfo.t_guid) { // this is required to avoid client crash, otherwise it will result // in moving with vehicle on the same vehicle and that = crash mover = _player; plMover = _player; } } if(_player->GetVehicleGUID() == movementInfo.t_guid) { _player->m_SeatData.OffsetX = movementInfo.t_x; _player->m_SeatData.OffsetY = movementInfo.t_y; _player->m_SeatData.OffsetZ = movementInfo.t_z; _player->m_SeatData.Orientation = movementInfo.t_o; } } if(recv_data.size() != recv_data.rpos()) { sLog.outError("MovementHandler: player %s (guid %d, account %u) sent a packet (opcode %u) that is " SIZEFMTD " bytes larger than it should be. Kicked as cheater.", _player->GetName(), _player->GetGUIDLow(), _player->GetSession()->GetAccountId(), recv_data.GetOpcode(), recv_data.size() - recv_data.rpos()); KickPlayer(); return; } if (!MaNGOS::IsValidMapCoord(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o)) return; /* handle special cases */ if (movementInfo.HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && !mover->GetVehicleGUID()) { // 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_x > 60 || movementInfo.t_y > 60 || movementInfo.t_x < -60 || movementInfo.t_y < -60 ) return; if( !MaNGOS::IsValidMapCoord(movementInfo.x+movementInfo.t_x, movementInfo.y + movementInfo.t_y, movementInfo.z + movementInfo.t_z, movementInfo.o + movementInfo.t_o) ) return; if (plMover && plMover->m_anti_TransportGUID == 0 && (movementInfo.t_guid !=0)) { // if we boarded a transport, add us to it if (plMover && !plMover->m_transport) { // 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 = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter) { if ((*iter)->GetGUID() == movementInfo.t_guid) { plMover->m_transport = (*iter); (*iter)->AddPassenger(plMover); break; } } } //movement anticheat; //Correct finding GO guid in DB (thanks to GriffonHeart) GameObject *obj = HashMapHolder<GameObject>::Find(movementInfo.t_guid); if(obj) plMover->m_anti_TransportGUID = obj->GetDBTableGUIDLow(); else plMover->m_anti_TransportGUID = GUID_LOPART(movementInfo.t_guid); // end movement anticheat } } else if (plMover && plMover->m_anti_TransportGUID != 0){ if (plMover && plMover->m_transport) // if we were on a transport, leave { plMover->m_transport->RemovePassenger(plMover); plMover->m_transport = NULL; } movementInfo.t_x = 0.0f; movementInfo.t_y = 0.0f; movementInfo.t_z = 0.0f; movementInfo.t_o = 0.0f; movementInfo.t_time = 0; movementInfo.t_seat = -1; plMover->m_anti_TransportGUID = 0; } // 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()) { //movement anticheat plMover->m_anti_JustJumped = 0; plMover->m_anti_JumpBaseZ = 0; //end movement anticheat plMover->HandleFall(movementInfo); } if (plMover && (movementInfo.HasMovementFlag(MOVEMENTFLAG_SWIMMING) != plMover->IsInWater())) { // now client not include swimming flag in case jumping under water plMover->SetInWater( !plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) ); } if (movementInfo.HasMovementFlag(MOVEMENTFLAG_SWIMMING)) { if(mover->GetTypeId() == TYPEID_UNIT) { if(((Creature*)mover)->isVehicle() && !((Creature*)mover)->canSwim()) { // NOTE : we should enter evade mode here, but... ((Vehicle*)mover)->SetSpawnDuration(1); } } } /*----------------------*/ //---- anti-cheat features -->>> bool check_passed = true; #ifdef MOVEMENT_ANTICHEAT_DEBUG if (plMover){ sLog.outBasic("MA-%s > client-time:%d fall-time:%d | xyzo: %f,%f,%fo(%f) flags[%X] opcode[%s]| transport (xyzo): %f,%f,%fo(%f)", plMover->GetName(),movementInfo.time,movementInfo.fallTime,movementInfo.x,movementInfo.y,movementInfo.z,movementInfo.o, movementInfo.flags, LookupOpcodeName(opcode),movementInfo.t_x,movementInfo.t_y,movementInfo.t_z,movementInfo.t_o); sLog.outBasic("MA-%s Transport > server GUID: %d | client GUID: (lo)%d - (hi)%d", plMover->GetName(),plMover->m_anti_TransportGUID, GUID_LOPART(movementInfo.t_guid), GUID_HIPART(movementInfo.t_guid)); } else { sLog.outBasic("MA > client-time:%d fall-time:%d | xyzo: %f,%f,%fo(%f) flags[%X] opcode[%s]| transport (xyzo): %f,%f,%fo(%f)", movementInfo.time,movementInfo.fallTime,movementInfo.x,movementInfo.y,movementInfo.z,movementInfo.o, movementInfo.flags, LookupOpcodeName(opcode),movementInfo.t_x,movementInfo.t_y,movementInfo.t_z,movementInfo.t_o); sLog.outBasic("MA Transport > server GUID: | client GUID: (lo)%d - (hi)%d", GUID_LOPART(movementInfo.t_guid), GUID_HIPART(movementInfo.t_guid)); } #endif if (plMover && World::GetEnableMvAnticheat()) { //calc time deltas int32 cClientTimeDelta = 1500; if (plMover->m_anti_LastClientTime !=0){ cClientTimeDelta = movementInfo.time - plMover->m_anti_LastClientTime; plMover->m_anti_DeltaClientTime += cClientTimeDelta; plMover->m_anti_LastClientTime = movementInfo.time; } else { plMover->m_anti_LastClientTime = movementInfo.time; } uint32 cServerTime=getMSTime(); uint32 cServerTimeDelta = 1500; if (plMover->m_anti_LastServerTime != 0){ cServerTimeDelta = cServerTime - plMover->m_anti_LastServerTime; plMover->m_anti_DeltaServerTime += cServerTimeDelta; plMover->m_anti_LastServerTime = cServerTime; } else { plMover->m_anti_LastServerTime = cServerTime; } //resync times on client login (first 15 sec for heavy areas) if (plMover->m_anti_DeltaServerTime < 15000 && plMover->m_anti_DeltaClientTime < 15000) plMover->m_anti_DeltaClientTime = plMover->m_anti_DeltaServerTime; int32 sync_time = plMover->m_anti_DeltaClientTime - plMover->m_anti_DeltaServerTime; #ifdef MOVEMENT_ANTICHEAT_DEBUG sLog.outBasic("MA-%s Time > cClientTimeDelta: %d, cServerTime: %d || deltaC: %d - deltaS: %d || SyncTime: %d", plMover->GetName(),cClientTimeDelta, cServerTime, plMover->m_anti_DeltaClientTime, plMover->m_anti_DeltaServerTime, sync_time); #endif //mistiming checks int32 gmd = World::GetMistimingDelta(); if (sync_time > gmd || sync_time < -gmd){ cClientTimeDelta = cServerTimeDelta; plMover->m_anti_MistimingCount++; sLog.outError("MA-%s, mistiming exception. #:%d, mistiming: %dms ", plMover->GetName(), plMover->m_anti_MistimingCount, sync_time); if (plMover->m_anti_MistimingCount > World::GetMistimingAlarms()) { sWorld.SendWorldText(3,"Bye Cheto! ",plMover->GetName()); plMover->GetSession()->KickPlayer(); return; } check_passed = false; } // end mistiming checks uint32 curDest = plMover->m_taxi.GetTaxiDestination(); //check taxi flight if ((plMover->m_anti_TransportGUID == 0) && !curDest) { UnitMoveType move_type; // calculating section --------------------- //current speed if (movementInfo.flags & MOVEMENTFLAG_FLYING) move_type = movementInfo.flags & MOVEMENTFLAG_BACKWARD ? MOVE_FLIGHT_BACK : MOVE_FLIGHT; else if (movementInfo.flags & MOVEMENTFLAG_SWIMMING) move_type = movementInfo.flags & MOVEMENTFLAG_BACKWARD ? MOVE_SWIM_BACK : MOVE_SWIM; else if (movementInfo.flags & MOVEMENTFLAG_WALK_MODE) move_type = MOVE_WALK; //hmm... in first time after login player has MOVE_SWIMBACK instead MOVE_WALKBACK else move_type = movementInfo.flags & MOVEMENTFLAG_BACKWARD ? MOVE_SWIM_BACK : MOVE_RUN; float current_speed = plMover->GetSpeed(move_type); // end current speed // movement distance float allowed_delta= 0; float delta_x = plMover->GetPositionX() - movementInfo.x; float delta_y = plMover->GetPositionY() - movementInfo.y; float delta_z = plMover->GetPositionZ() - movementInfo.z; float real_delta = delta_x * delta_x + delta_y * delta_y; float tg_z = -99999; //tangens // end movement distance if (cClientTimeDelta < 0) {cClientTimeDelta = 0;} float time_delta = (cClientTimeDelta < 1500) ? (float)cClientTimeDelta/1000 : 1.5f; //normalize time - 1.5 second allowed for heavy loaded server if (!(movementInfo.flags & (MOVEMENTFLAG_FLYING | MOVEMENTFLAG_SWIMMING))) tg_z = (real_delta !=0) ? (delta_z*delta_z / real_delta) : -99999; if (current_speed < plMover->m_anti_Last_HSpeed) { allowed_delta = plMover->m_anti_Last_HSpeed; if (plMover->m_anti_LastSpeedChangeTime == 0 ) plMover->m_anti_LastSpeedChangeTime = movementInfo.time + (uint32)floor(((plMover->m_anti_Last_HSpeed / current_speed) * 1500)) + 100; //100ms above for random fluctuating =))) } else { allowed_delta = current_speed; } allowed_delta = allowed_delta * time_delta; allowed_delta = allowed_delta * allowed_delta + 2; if (tg_z > 2.2) allowed_delta = allowed_delta + (delta_z*delta_z)/2.37; // mountain fall allowed speed if (movementInfo.time>plMover->m_anti_LastSpeedChangeTime) { plMover->m_anti_Last_HSpeed = current_speed; // store current speed plMover->m_anti_Last_VSpeed = -2.3f; if (plMover->m_anti_LastSpeedChangeTime != 0) plMover->m_anti_LastSpeedChangeTime = 0; } // end calculating section --------------------- //AntiGravitation (thanks to Meekro) float JumpHeight = plMover->m_anti_JumpBaseZ - movementInfo.z; if ((plMover->m_anti_JumpBaseZ != 0) && !(movementInfo.flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING | MOVEMENTFLAG_FLYING2)) && (JumpHeight < plMover->m_anti_Last_VSpeed)) { #ifdef MOVEMENT_ANTICHEAT_DEBUG sLog.outError("MA-%s, GraviJump exception. JumpHeight = %f, Allowed Veritcal Speed = %f", plMover->GetName(), JumpHeight, plMover->m_anti_Last_VSpeed); #endif check_passed = false; } //multi jump checks if (opcode == MSG_MOVE_JUMP && !plMover->IsInWater()) { if (plMover->m_anti_JustJumped >= 1){ check_passed = false; //don't process new jump packet } else { plMover->m_anti_JustJumped += 1; plMover->m_anti_JumpBaseZ = movementInfo.z; } } else if (plMover->IsInWater()) { plMover->m_anti_JustJumped = 0; } //speed hack checks if ((real_delta > allowed_delta)) // && (delta_z < 0)) { #ifdef MOVEMENT_ANTICHEAT_DEBUG sLog.outError("MA-%s, speed exception | cDelta=%f aDelta=%f | cSpeed=%f lSpeed=%f deltaTime=%f", plMover->GetName(), real_delta, allowed_delta, current_speed, plMover->m_anti_Last_HSpeed,time_delta); #endif check_passed = false; } //teleport hack checks if ((real_delta>4900.0f) && !(real_delta < allowed_delta)) { #ifdef MOVEMENT_ANTICHEAT_DEBUG sLog.outError("MA-%s, is teleport exception | cDelta=%f aDelta=%f | cSpeed=%f lSpeed=%f deltaToime=%f", plMover->GetName(),real_delta, allowed_delta, current_speed, plMover->m_anti_Last_HSpeed,time_delta); #endif check_passed = false; } //mountian hack checks // 1.56f (delta_z < GetPlayer()->m_anti_Last_VSpeed)) if ((delta_z < plMover->m_anti_Last_VSpeed) && (plMover->m_anti_JustJumped == 0) && (tg_z > 2.37f)) { #ifdef MOVEMENT_ANTICHEAT_DEBUG sLog.outError("MA-%s, mountain exception | tg_z=%f", plMover->GetName(),tg_z); #endif check_passed = false; } //Fly hack checks if (((movementInfo.flags & (MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_FLYING | MOVEMENTFLAG_FLYING2)) != 0) && !plMover->isGameMaster() && !(plMover->HasAuraType(SPELL_AURA_FLY) || plMover->HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED))) { #ifdef MOVEMENT_ANTICHEAT_DEBUG sLog.outError("MA-%s, flight exception. {SPELL_AURA_FLY=[%X]} {SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED=[%X]} {SPELL_AURA_MOD_SPEED_FLIGHT=[%X]} {SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS=[%X]} {SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK=[%X]}", plMover->GetName(), plMover->HasAuraType(SPELL_AURA_FLY), plMover->HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED), plMover->HasAuraType(SPELL_AURA_MOD_SPEED_FLIGHT), plMover->HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS), plMover->HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK)); #endif check_passed = false; } //Water-Walk checks if (((movementInfo.flags & MOVEMENTFLAG_WATERWALKING) != 0) && !plMover->isGameMaster() && !(plMover->HasAuraType(SPELL_AURA_WATER_WALK) | plMover->HasAuraType(SPELL_AURA_GHOST))) { #ifdef MOVEMENT_ANTICHEAT_DEBUG sLog.outError("MA-%s, water-walk exception. [%X]{SPELL_AURA_WATER_WALK=[%X]}", plMover->GetName(), movementInfo.flags, plMover->HasAuraType(SPELL_AURA_WATER_WALK)); #endif check_passed = false; } //Teleport To Plane checks if (movementInfo.z < 0.0001f && movementInfo.z > -0.0001f && ((movementInfo.flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_FLYING | MOVEMENTFLAG_FLYING2)) == 0) && !plMover->isGameMaster()) { // Prevent using TeleportToPlan. Map *map = plMover->GetMap(); if (map){ float plane_z = map->GetHeight(movementInfo.x, movementInfo.y, MAX_HEIGHT) - movementInfo.z; plane_z = (plane_z < -500.0f) ? 0 : plane_z; //check holes in heigth map if(plane_z > 0.1f || plane_z < -0.1f) { plMover->m_anti_TeleToPlane_Count++; check_passed = false; #ifdef MOVEMENT_ANTICHEAT_DEBUG sLog.outDebug("MA-%s, teleport to plan exception. plane_z: %f ", plMover->GetName(), plane_z); #endif if (plMover->m_anti_TeleToPlane_Count > World::GetTeleportToPlaneAlarms()) { sLog.outError("MA-%s, teleport to plan exception. Exception count: %d ", plMover->GetName(), plMover->m_anti_TeleToPlane_Count); sWorld.SendWorldText(3,"Bye Cheto! ",plMover->GetName()); plMover->GetSession()->KickPlayer(); return; } } } } else { if (plMover->m_anti_TeleToPlane_Count != 0) plMover->m_anti_TeleToPlane_Count = 0; } } else if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) { //antiwrap checks if (plMover->m_transport) { float trans_rad = movementInfo.t_x*movementInfo.t_x + movementInfo.t_y*movementInfo.t_y + movementInfo.t_z*movementInfo.t_z; if (trans_rad > 3600.0f){ check_passed = false; #ifdef MOVEMENT_ANTICHEAT_DEBUG sLog.outError("MA-%s, leave transport.", plMover->GetName()); #endif } } else { if (GameObjectData const* go_data = objmgr.GetGOData(plMover->m_anti_TransportGUID)) { float delta_gox = go_data->posX - movementInfo.x; float delta_goy = go_data->posY - movementInfo.y; float delta_goz = go_data->posZ - movementInfo.z; int mapid = go_data->mapid; #ifdef MOVEMENT_ANTICHEAT_DEBUG sLog.outDebug("MA-%s, transport movement. GO xyzo: %f,%f,%f", plMover->GetName(), go_data->posX,go_data->posY,go_data->posZ); #endif if (plMover->GetMapId() != mapid){ check_passed = false; } else if (mapid !=369) { float delta_go = delta_gox*delta_gox + delta_goy*delta_goy; if (delta_go > 3600.0f) { check_passed = false; #ifdef MOVEMENT_ANTICHEAT_DEBUG sLog.outError("MA-%s, leave transport. GO xyzo: %f,%f,%f", plMover->GetName(), go_data->posX,go_data->posY,go_data->posZ); #endif } } } else { #ifdef MOVEMENT_ANTICHEAT_DEBUG sLog.outDebug("MA-%s, undefined transport.", plMover->GetName()); #endif check_passed = false; } } if (!check_passed){ if (plMover->m_transport) { plMover->m_transport->RemovePassenger(plMover); plMover->m_transport = NULL; } movementInfo.t_x = 0.0f; movementInfo.t_y = 0.0f; movementInfo.t_z = 0.0f; movementInfo.t_o = 0.0f; movementInfo.t_time = 0; plMover->m_anti_TransportGUID = 0; } } } /* process position-change */ if (check_passed) { recv_data.put<uint32>(6, getMSTime()); // fix time, offset flags(4) + unk(2) WorldPacket data(recv_data.GetOpcode(), (mover->GetPackGUID().size()+recv_data.size())); data.append(mover->GetPackGUID()); // use mover guid data.append(recv_data.contents(), recv_data.size()); GetPlayer()->SendMessageToSet(&data, false); if(plMover) // nothing is charmed, or player charmed { plMover->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); plMover->m_movementInfo = movementInfo; plMover->UpdateFallInformationIfNeed(movementInfo, recv_data.GetOpcode()); if(plMover->isMovingOrTurning()) plMover->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); if(movementInfo.z < -500.0f) { if(plMover->InBattleGround() && plMover->GetBattleGround() && plMover->GetBattleGround()->HandlePlayerUnderMap(_player)) { // do nothing, the handle already did if returned true } else { // 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 if(!plMover->isAlive()) { // change the death state to CORPSE to prevent the death timer from // starting in the next player update plMover->KillPlayer(); plMover->BuildPlayerRepop(); } } // cancel the death timer here if started plMover->RepopAtGraveyard(); } } //movement anticheat >>> if (plMover->m_anti_AlarmCount > 0){ sLog.outError("MA-%s produce %d anticheat alarms",plMover->GetName(),plMover->m_anti_AlarmCount); plMover->m_anti_AlarmCount = 0; } // end movement anticheat } else // creature charmed { if(mover->IsInWorld()) { mover->GetMap()->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); if(((Creature*)mover)->isVehicle()) ((Vehicle*)mover)->RellocatePassengers(mover->GetMap()); } } } else if (plMover) { plMover->m_anti_AlarmCount++; WorldPacket data; //GetPlayer()->m_movementInfo.SetMovementFlags(MovementFlags(MOVEMENTFLAG_NONE)); plMover->m_movementInfo.SetMovementFlags(MovementFlags(MOVEMENTFLAG_NONE)); plMover->BuildTeleportAckMsg(&data, plMover->GetPositionX(), plMover->GetPositionY(), plMover->GetPositionZ(), plMover->GetOrientation()); plMover->GetSession()->SendPacket(&data); plMover->BuildHeartBeatMsg(&data); plMover->SendMessageToSet(&data, true); } }
void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEGROUND_PLAYER_POSITIONS Message"); Battleground* bg = _player->GetBattleground(); if (!bg) // can't be received if player not in battleground return; uint32 acount = 0; uint32 hcount = 0; Player* aplr = NULL; Player* hplr = NULL; if (uint64 guid = bg->GetFlagPickerGUID(TEAM_ALLIANCE)) { aplr = ObjectAccessor::FindPlayer(guid); if (aplr) ++acount; } if (uint64 guid = bg->GetFlagPickerGUID(TEAM_HORDE)) { hplr = ObjectAccessor::FindPlayer(guid); if (hplr) ++hcount; } ObjectGuid aguid = aplr ? aplr->GetGUID() : 0; ObjectGuid hguid = hplr ? hplr->GetGUID() : 0; WorldPacket data(SMSG_BATTLEFIELD_PLAYER_POSITIONS); data.WriteBits(acount, 22); for (uint8 i = 0; i < acount; i++) { data.WriteBit(aguid[3]); data.WriteBit(aguid[5]); data.WriteBit(aguid[1]); data.WriteBit(aguid[6]); data.WriteBit(aguid[7]); data.WriteBit(aguid[0]); data.WriteBit(aguid[2]); data.WriteBit(aguid[4]); } data.WriteBits(hcount, 22); for (uint8 i = 0; i < hcount; i++) { data.WriteBit(hguid[6]); data.WriteBit(hguid[5]); data.WriteBit(hguid[4]); data.WriteBit(hguid[7]); data.WriteBit(hguid[2]); data.WriteBit(hguid[1]); data.WriteBit(hguid[0]); data.WriteBit(hguid[3]); } data.FlushBits(); for (uint8 i = 0; i < hcount; i++) { data.WriteByteSeq(hguid[2]); data.WriteByteSeq(hguid[1]); data << float(hplr->GetPositionY()); data.WriteByteSeq(hguid[5]); data.WriteByteSeq(hguid[4]); data.WriteByteSeq(hguid[7]); data.WriteByteSeq(hguid[0]); data.WriteByteSeq(hguid[6]); data.WriteByteSeq(hguid[3]); data << float(hplr->GetPositionX()); } for (uint8 i = 0; i < acount; i++) { data.WriteByteSeq(aguid[6]); data << float(aplr->GetPositionX()); data.WriteByteSeq(aguid[5]); data.WriteByteSeq(aguid[3]); data << float(aplr->GetPositionY()); data.WriteByteSeq(aguid[1]); data.WriteByteSeq(aguid[7]); data.WriteByteSeq(aguid[0]); data.WriteByteSeq(aguid[2]); data.WriteByteSeq(aguid[4]); } SendPacket(&data); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recv_data) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 Guid; recv_data >> Guid; Player* player = HashMapHolder<Player>::Find(Guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(Guid); data << (uint32) GROUP_UPDATE_FLAG_STATUS; data << (uint16) MEMBER_STATUS_OFFLINE; SendPacket(&data); return; } Pet* pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if (pet) mask1 = 0x7FFFFFFF; // for hunters and other classes with pets Powers powerType = player->getPowerType(); data << (uint32) mask1; // group update mask data << (uint16) MEMBER_STATUS_ONLINE; // member's online status data << (uint32) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP data << (uint32) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER data << (uint16) player->getLevel(); // GROUP_UPDATE_FLAG_LEVEL data << (uint16) player->GetZoneId(); // GROUP_UPDATE_FLAG_ZONE data << (uint16) player->GetPositionX(); // GROUP_UPDATE_FLAG_POSITION data << (uint16) player->GetPositionY(); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << (uint64) auramask; // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication * aurApp = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << (uint32) aurApp->GetBase()->GetId(); data << (uint8) 1; } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (pet) { Powers petpowertype = pet->getPowerType(); data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << (uint32) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP data << (uint32) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << (uint64) petauramask; // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication * auraApp = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << (uint32) auraApp->GetBase()->GetId(); data << (uint8) 1; } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << (uint8) 0; // GROUP_UPDATE_FLAG_PET_NAME data << (uint64) 0; // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid Guid; recvData >> Guid; Player* player = ObjectAccessor::FindConnectedPlayer(Guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << Guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet* pet = player->GetPet(); Powers powerType = player->getPowerType(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); uint32 updateFlags = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | GROUP_UPDATE_FLAG_PET_AURAS; if (powerType != POWER_MANA) updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE; if (pet) updateFlags |= GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_POWER_TYPE | GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER; if (player->GetVehicle()) updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT; uint16 playerStatus = MEMBER_STATUS_ONLINE; if (player->IsPvP()) playerStatus |= MEMBER_STATUS_PVP; if (!player->IsAlive()) { if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) playerStatus |= MEMBER_STATUS_GHOST; else playerStatus |= MEMBER_STATUS_DEAD; } if (player->IsFFAPvP()) playerStatus |= MEMBER_STATUS_PVP_FFA; if (player->isAFK()) playerStatus |= MEMBER_STATUS_AFK; if (player->isDND()) playerStatus |= MEMBER_STATUS_DND; data << uint32(updateFlags); data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE) data << uint8(powerType); data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION uint64 auraMask = 0; size_t maskPos = data.wpos(); data << uint64(auraMask); // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = player->GetVisibleAura(i)) { auraMask |= uint64(1) << i; data << uint32(aurApp->GetBase()->GetId()); data << uint8(aurApp->GetFlags()); } } data.put<uint64>(maskPos, auraMask); // GROUP_UPDATE_FLAG_AURAS if (updateFlags & GROUP_UPDATE_FLAG_PET_GUID) data << uint64(ASSERT_NOTNULL(pet)->GetGUID()); data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP) data << uint32(pet->GetHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP) data << uint32(pet->GetMaxHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE) data << (uint8)pet->getPowerType(); if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER) data << uint16(pet->GetPower(pet->getPowerType())); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER) data << uint16(pet->GetMaxPower(pet->getPowerType())); uint64 petAuraMask = 0; maskPos = data.wpos(); data << uint64(petAuraMask); // placeholder if (pet) { for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) { petAuraMask |= uint64(1) << i; data << uint32(aurApp->GetBase()->GetId()); data << uint8(aurApp->GetFlags()); } } } data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT) data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]); SendPacket(&data); }
static bool HandleGameObjectTargetCommand(ChatHandler* handler, char const* args) { Player* player = handler->GetSession()->GetPlayer(); QueryResult result; GameEventMgr::ActiveEvents const& activeEventsList = sGameEventMgr->GetActiveEventList(); if (*args) { // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r char* id = handler->extractKeyFromLink((char*)args, "Hgameobject_entry"); if (!id) return false; uint32 objectId = atol(id); if (objectId) result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, phaseMask, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND id = '%u' ORDER BY order_ ASC LIMIT 1", player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), objectId); else { std::string name = id; WorldDatabase.EscapeString(name); result = WorldDatabase.PQuery( "SELECT guid, id, position_x, position_y, position_z, orientation, map, phaseMask, (POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ " "FROM gameobject, gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_" "_CONCAT3_("'%%'", "'%s'", "'%%'")" ORDER BY order_ ASC LIMIT 1", player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), name.c_str()); } } else { std::ostringstream eventFilter; eventFilter << " AND (eventEntry IS NULL "; bool initString = true; for (GameEventMgr::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr) { if (initString) { eventFilter << "OR eventEntry IN (" << *itr; initString = false; } else eventFilter << ',' << *itr; } if (!initString) eventFilter << "))"; else eventFilter << ')'; result = WorldDatabase.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, phaseMask, " "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject " "LEFT OUTER JOIN game_event_gameobject on gameobject.guid = game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 10", handler->GetSession()->GetPlayer()->GetPositionX(), handler->GetSession()->GetPlayer()->GetPositionY(), handler->GetSession()->GetPlayer()->GetPositionZ(), handler->GetSession()->GetPlayer()->GetMapId(), eventFilter.str().c_str()); } if (!result) { handler->SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND); return true; } bool found = false; float x, y, z, o; uint32 guidLow, id; uint16 mapId, phase; uint32 poolId; do { Field* fields = result->Fetch(); guidLow = fields[0].GetUInt32(); id = fields[1].GetUInt32(); x = fields[2].GetFloat(); y = fields[3].GetFloat(); z = fields[4].GetFloat(); o = fields[5].GetFloat(); mapId = fields[6].GetUInt16(); phase = fields[7].GetUInt16(); poolId = sPoolMgr->IsPartOfAPool<GameObject>(guidLow); if (!poolId || sPoolMgr->IsSpawnedObject<GameObject>(guidLow)) found = true; } while (result->NextRow() && !found); if (!found) { handler->PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST, id); return false; } GameObjectTemplate const* objectInfo = sObjectMgr->GetGameObjectTemplate(id); if (!objectInfo) { handler->PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST, id); return false; } GameObject* target = handler->GetSession()->GetPlayer()->GetMap()->GetGameObject(MAKE_NEW_GUID(guidLow, id, HIGHGUID_GAMEOBJECT)); handler->PSendSysMessage(LANG_GAMEOBJECT_DETAIL, guidLow, objectInfo->name.c_str(), guidLow, id, x, y, z, mapId, o, phase); if (target) { int32 curRespawnDelay = int32(target->GetRespawnTimeEx() - time(NULL)); if (curRespawnDelay < 0) curRespawnDelay = 0; std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay, true); std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(), true); handler->PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(), curRespawnDelayStr.c_str()); } return true; }
void StatDumper::DumpStats() { if( Filename[0] == NULL ) return; FILE* f = fopen( Filename, "w" ); if( !f ) return; Log.Debug( "StatDumper", "Writing %s", Filename ); // Dump Header fprintf(f, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); fprintf(f, "<?xml-stylesheet type=\"text/xsl\" href=\"server_stats.xsl\"?>\n"); fprintf(f, "<serverpage>\n"); fprintf(f, " <status>\n"); uint32 races[RACE_DRAENEI+1]; uint32 classes[DRUID+1]; memset(&races[0], 0, sizeof(uint32)*(RACE_DRAENEI+1)); memset(&classes[0], 0, sizeof(uint32)*(RACE_DRAENEI+1)); std::deque<Player*> gms; { // Dump server information. #ifdef WIN32 fprintf(f, " <platform>Ascent %s r%u/%s-Win-%s (www.ascentcommunity.com)</platform>\n", BUILD_TAG, BUILD_REVISION, CONFIG, ARCH); #else fprintf(f, " <platform>Ascent %s r%u/%s-%s (www.ascentcommunity.com)</platform>\n", BUILD_TAG, BUILD_REVISION, PLATFORM_TEXT, ARCH); #endif char uptime[80]; GenerateUptimeString(uptime); float AvgLat; uint32 GMCount; int gm = 0; int count = 0; int avg = 0; // lock players reader objmgr._playerslock.AcquireReadLock(); HM_NAMESPACE::hash_map<uint32, Player*>::const_iterator itr; for (itr = objmgr._players.begin(); itr != objmgr._players.end(); itr++) { if(itr->second->GetSession() && itr->second->IsInWorld()) { count++; avg += itr->second->GetSession()->GetLatency(); if(itr->second->GetSession()->GetPermissionCount()) { gm++; gms.push_back(itr->second); } classes[itr->second->getClass()]++; races[itr->second->getRace()]++; } } objmgr._playerslock.ReleaseReadLock(); AvgLat = count ? (float)((float)avg / (float)count) : 0; GMCount = gm; fprintf(f, " <uptime>%s</uptime>\n", uptime); fprintf(f, " <oplayers>%u</oplayers>\n", (unsigned int)(sWorld.AlliancePlayers + sWorld.HordePlayers)); fprintf(f, " <cpu>%2.2f</cpu>\n", GetCPUUsage()); fprintf(f, " <qplayers>%u</qplayers>\n", (unsigned int)sWorld.GetQueueCount()); fprintf(f, " <ram>%.3f</ram>\n", GetRAMUsage()); fprintf(f, " <avglat>%.3f</avglat>\n", AvgLat); fprintf(f, " <threads>%u</threads>\n", (unsigned int)ThreadPool.GetActiveThreadCount()); fprintf(f, " <fthreads>%u</fthreads>\n", (unsigned int)ThreadPool.GetFreeThreadCount()); time_t t = (time_t)UNIXTIME; fprintf(f, " <gmcount>%u</gmcount>\n", (unsigned int)GMCount); fprintf(f, " <lastupdate>%s</lastupdate>\n", asctime(localtime(&t))); fprintf(f, " <alliance>%u</alliance>\n", (unsigned int)sWorld.AlliancePlayers); fprintf(f, " <horde>%u</horde>\n", (unsigned int)sWorld.HordePlayers); fprintf(f, " <acceptedconns>%u</acceptedconns>\n", (unsigned int)sWorld.mAcceptedConnections); fprintf(f, " <peakcount>%u</peakcount>\n", (unsigned int)sWorld.PeakSessionCount); fprintf(f, " <wdbquerysize>%u</wdbquerysize>\n", WorldDatabase.GetQueueSize()); fprintf(f, " <cdbquerysize>%u</cdbquerysize>\n", CharacterDatabase.GetQueueSize()); } fprintf(f, " </status>\n"); static const char * race_names[RACE_DRAENEI+1] = { NULL, "human", "orc", "dwarf", "nightelf", "undead", "tauren", "gnome", "troll", NULL, "bloodelf", "draenei", }; static const char * class_names[DRUID+1] = { NULL, "warrior", "paladin", "hunter", "rogue", "priest", NULL, "shaman", "mage", "warlock", NULL, "druid", }; fprintf(f, " <statsummary>\n"); uint32 i; for(i = 0; i <= RACE_DRAENEI; ++i) { if( race_names[i] != NULL ) fprintf(f, " <%s>%u</%s>\n", race_names[i], races[i], race_names[i]); } for(i = 0; i <= DRUID; ++i) { if( class_names[i] != NULL ) fprintf(f, " <%s>%u</%s>\n", class_names[i], classes[i], class_names[i]); } fprintf(f, " </statsummary>\n"); Player * plr; uint32 t = (uint32)time(NULL); char otime[100]; { fprintf(f, " <instances>\n"); // need a big buffer.. static char buf[500000]; memset(buf, 0, 500000); // Dump Instance Information //sWorldCreator.BuildXMLStats(buf); sInstanceMgr.BuildXMLStats(buf); fprintf(f, buf); fprintf(f, " </instances>\n"); } { // GM Information fprintf(f, " <gms>\n"); while(!gms.empty()) { plr = gms.front(); gms.pop_front(); if(!plr->bGMTagOn) continue; FillOnlineTime(t - plr->OnlineTime, otime); fprintf(f, " <gmplr>\n"); fprintf(f, " <name>%s</name>\n", plr->GetName()); fprintf(f, " <race>%u</race>\n", plr->getRace()); fprintf(f, " <class>%u</class>\n", (unsigned int)plr->getClass()); fprintf(f, " <gender>%u</gender>\n", (unsigned int)plr->getGender()); fprintf(f, " <pvprank>%u</pvprank>\n", (unsigned int)plr->GetPVPRank()); fprintf(f, " <level>%u</level>\n", (unsigned int)plr->GetUInt32Value(UNIT_FIELD_LEVEL)); fprintf(f, " <map>%u</map>\n", (unsigned int)plr->GetMapId()); fprintf(f, " <areaid>%u</areaid>\n", (unsigned int)plr->GetAreaID()); fprintf(f, " <ontime>%s</ontime>\n", otime); fprintf(f, " <latency>%u</latency>\n", (unsigned int)plr->GetSession()->GetLatency()); fprintf(f, " <permissions>%s</permissions>\n", plr->GetSession()->GetPermissions()); fprintf(f, " </gmplr>\n"); } fprintf(f, " </gms>\n"); } { fprintf(f, " <sessions>\n"); // Dump Player Information objmgr._playerslock.AcquireReadLock(); HM_NAMESPACE::hash_map<uint32, Player*>::const_iterator itr; for (itr = objmgr._players.begin(); itr != objmgr._players.end(); itr++) { plr = itr->second; if(itr->second->GetSession() && itr->second->IsInWorld()) { FillOnlineTime(t - plr->OnlineTime, otime); fprintf(f, " <plr>\n"); fprintf(f, " <name>%s</name>\n", plr->GetName()); fprintf(f, " <race>%u</race>\n", (unsigned int)plr->getRace()); fprintf(f, " <class>%u</class>\n", (unsigned int)plr->getClass()); fprintf(f, " <gender>%u</gender>\n", (unsigned int)plr->getGender()); fprintf(f, " <pvprank>%u</pvprank>\n", (unsigned int)plr->GetPVPRank()); fprintf(f, " <level>%u</level>\n", (unsigned int)plr->GetUInt32Value(UNIT_FIELD_LEVEL)); fprintf(f, " <map>%u</map>\n", (unsigned int)plr->GetMapId()); fprintf(f, " <areaid>%u</areaid>\n", (unsigned int)plr->GetAreaID()); //requested by Zdarkside for he's online map. I hope it does not scre up any parser. If so, then make a better one :P fprintf(f, " <xpos>%f</xpos>\n", plr->GetPositionX ()); fprintf(f, " <ypos>%f</ypos>\n", plr->GetPositionY()); fprintf(f, " <ontime>%s</ontime>\n", otime); fprintf(f, " <latency>%u</latency>\n", (unsigned int)plr->GetSession()->GetLatency()); fprintf(f, " </plr>\n"); if(plr->GetSession()->GetPermissionCount() > 0) gms.push_back(plr); } } objmgr._playerslock.ReleaseReadLock(); fprintf(f, " </sessions>\n"); } fprintf(f, "</serverpage>\n"); fclose(f); }
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; } 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 != NULL) 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; }
//Ruthless Cunning bool RuthlessCunning(uint32 i, Spell* pSpell) { if(!pSpell->u_caster->IsPlayer()) return true; Player* plr = TO_PLAYER(pSpell->u_caster); if( plr == NULL ) return true; Creature* kilsorrow = plr->GetMapMgr()->GetInterface()->GetCreatureNearestCoords(plr->GetPositionX(), plr->GetPositionY() , plr->GetPositionZ()); if( kilsorrow == NULL || kilsorrow->isAlive() ) return true; QuestLogEntry *qle = plr->GetQuestLogForEntry(9927); if(qle && qle->GetMobCount(0) < qle->GetQuest()->required_mobcount[0]) { kilsorrow->Despawn(0, 60000); qle->SetMobCount(0, qle->GetMobCount(0)+1); qle->SendUpdateAddKill(0); qle->UpdatePlayerFields(); }; return true; }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) { CHECK_PACKET_SIZE(recv_data, 8); sLog.outDebug("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 Guid; recv_data >> Guid; Player *player = objmgr.GetPlayer(Guid); if(!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data.appendPackGUID(Guid); data << (uint32) GROUP_UPDATE_FLAG_STATUS; data << (uint16) MEMBER_STATUS_OFFLINE; SendPacket(&data); return; } Pet *pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data.append(player->GetPackGUID()); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if(pet) mask1 = 0x7FFFFFFF; // for hunters and other classes with pets Powers powerType = player->getPowerType(); data << (uint32) mask1; // group update mask data << (uint16) MEMBER_STATUS_ONLINE; // member's online status data << (uint16) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP data << (uint16) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER data << (uint16) player->getLevel(); // GROUP_UPDATE_FLAG_LEVEL data << (uint16) player->GetZoneId(); // GROUP_UPDATE_FLAG_ZONE data << (uint16) player->GetPositionX(); // GROUP_UPDATE_FLAG_POSITION data << (uint16) player->GetPositionY(); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << (uint64) auramask; // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { if(uint32 aura = player->GetUInt32Value(UNIT_FIELD_AURA + i)) { auramask |= (uint64(1) << i); data << uint16(aura); data << uint8(1); } } data.put<uint64>(maskPos,auramask); // GROUP_UPDATE_FLAG_AURAS if(pet) { Powers petpowertype = pet->getPowerType(); data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << (uint16) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP data << (uint16) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << (uint64) petauramask; // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { if(uint32 petaura = pet->GetUInt32Value(UNIT_FIELD_AURA + i)) { petauramask |= (uint64(1) << i); data << (uint16) petaura; data << (uint8) 1; } } data.put<uint64>(petMaskPos,petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << (uint8) 0; // GROUP_UPDATE_FLAG_PET_NAME data << (uint64) 0; // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
void WorldSession::HandleBattleGroundPlayerPositionsOpcode(WorldPacket& /*recv_data*/) { // empty opcode DEBUG_LOG("WORLD: Recvd CMSG_BATTLEGROUND_PLAYER_POSITIONS Message"); BattleGround* bg = _player->GetBattleGround(); if (!bg) // can't be received if player not in battleground return; Player* flagCarrierA = NULL; Player* flagCarrierH = NULL; uint32 flagCarrierCountA = 0; // obsolete uint32 flagCarrierCountH = 0; switch (bg->GetTypeID(true)) { case BATTLEGROUND_TP: case BATTLEGROUND_WS: { if (flagCarrierA = sObjectMgr.GetPlayer(((BattleGroundWS*)bg)->GetAllianceFlagCarrierGuid())) ++flagCarrierCountH; if (flagCarrierH = sObjectMgr.GetPlayer(((BattleGroundWS*)bg)->GetHordeFlagCarrierGuid())) ++flagCarrierCountH; break; } case BATTLEGROUND_EY: { if (flagCarrierH = sObjectMgr.GetPlayer(((BattleGroundEY*)bg)->GetFlagCarrierGuid())) ++flagCarrierCountH; break; } case BATTLEGROUND_AB: case BATTLEGROUND_AV: // for other BG types - send default break; default: // maybe it is sent also in arena - do nothing break; } WorldPacket data(SMSG_BATTLEGROUND_PLAYER_POSITIONS, (3 + 1) * 2 + (8 + 4 + 4) * 2); data.WriteBits(flagCarrierCountA, 22); data.WriteBits(flagCarrierCountH, 22); if (flagCarrierA) data.WriteGuidMask<6, 5, 4, 7, 2, 1, 0, 3>(flagCarrierA->GetObjectGuid()); if (flagCarrierH) data.WriteGuidMask<6, 5, 4, 7, 2, 1, 0, 3>(flagCarrierH->GetObjectGuid()); if (flagCarrierA) { data.WriteGuidBytes<2, 1>(flagCarrierA->GetObjectGuid()); data << float(flagCarrierA->GetPositionY()); data.WriteGuidBytes<5, 4, 7, 0, 6, 3>(flagCarrierA->GetObjectGuid()); data << float(flagCarrierA->GetPositionX()); } if (flagCarrierH) { data.WriteGuidBytes<2, 1>(flagCarrierH->GetObjectGuid()); data << float(flagCarrierH->GetPositionY()); data.WriteGuidBytes<5, 4, 7, 0, 6, 3>(flagCarrierH->GetObjectGuid()); data << float(flagCarrierH->GetPositionX()); } SendPacket(&data); }
// Stopping the Spread bool StoppingTheSpread(uint32 i, Spell* pSpell) { if( !pSpell->u_caster->IsPlayer() ) return true; Player* plr = TO_PLAYER(pSpell->u_caster); if( plr == NULL ) return true; Creature* target = TO_CREATURE(plr->GetMapMgr()->GetInterface()->GetCreatureNearestCoords( plr->GetPositionX(), plr->GetPositionY() , plr->GetPositionZ(), 18240 )); if( target == NULL ) return true; QuestLogEntry *qle = plr->GetQuestLogForEntry(9874); if( qle == NULL ) return true; if( qle && qle->GetMobCount(0) < qle->GetQuest()->required_mobcount[0] ) { qle->SetMobCount( 0, qle->GetMobCount( 0 ) + 1 ); qle->SendUpdateAddKill( 0 ); GameObject* obj = sEAS.SpawnGameobject(plr, 183816, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation(), 1, 0, 0, 0, 0); sEAS.GameobjectDelete(obj, 1*30*1000); }; target->Despawn( 2000, 60*1000 ); plr->UpdateNearbyGameObjects(); qle->UpdatePlayerFields(); 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[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)) { // FIXME: When Command system is moved to RBAC this check must be changed if (!AccountMgr::IsPlayerAccount(table[i].SecurityLevel)) { // chat case if (m_session) { Player* p = m_session->GetPlayer(); uint64 sel_guid = p->GetSelection(); uint32 areaId = p->GetAreaId(); std::string areaName = "Unknown"; std::string zoneName = "Unknown"; if (AreaTableEntry const* area = GetAreaEntryByAreaID(areaId)) { int locale = GetSessionDbcLocale(); areaName = area->area_name[locale]; if (AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone)) zoneName = zone->area_name[locale]; } sLog->outCommand(m_session->GetAccountId(), "Command: %s [Player: %s (Guid: %u) (Account: %u) X: %f Y: %f Z: %f Map: %u (%s) Area: %u (%s) Zone: %s Selected %s: %s (GUID: %u)]", fullcmd.c_str(), p->GetName().c_str(), GUID_LOPART(p->GetGUID()), m_session->GetAccountId(), p->GetPositionX(), p->GetPositionY(), p->GetPositionZ(), p->GetMapId(), p->GetMap() ? p->GetMap()->GetMapName() : "Unknown", areaId, areaName.c_str(), zoneName.c_str(), GetLogNameForGuid(sel_guid), (p->GetSelectedUnit()) ? p->GetSelectedUnit()->GetName().c_str() : "", 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; }
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::IsVIPorPlayer(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; }
static bool HandleWarpCommand(ChatHandler* handler, char const* args) { if (!*args) return false; Player* player = handler->GetSession()->GetPlayer(); char* arg1 = strtok((char*)args, " "); char* arg2 = strtok(NULL, " "); if (!arg1 || !arg2) return false; char dir = arg1[0]; float value = float(atof(arg2)); float x = player->GetPositionX(); float y = player->GetPositionY(); float z = player->GetPositionZ(); float o = player->GetOrientation(); uint32 mapid = player->GetMapId(); Map const* map = sMapMgr->CreateBaseMap(mapid); z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); switch (dir) { case 'l': // left { x = x + cos(o+(M_PI/2))*value; y = y + sin(o+(M_PI/2))*value; player->TeleportTo(mapid, x, y, z, o); } break; case 'r': // right { x = x + cos(o-(M_PI/2))*value; y = y + sin(o-(M_PI/2))*value; player->TeleportTo(mapid, x, y, z, o); } break; case 'f': // forward { x = x + cosf(o)*value; y = y + sinf(o)*value; player->TeleportTo(mapid, x, y, z, o); } break; case 'u': // up { player->TeleportTo(mapid, x, y, z + value, o); } break; case 'd': // down { player->TeleportTo(mapid, x, y, z - value, o); } break; case 'o': //orientation { o = Position::NormalizeOrientation((value * M_PI_F/180.0f)+ o); player->TeleportTo(mapid, x, y, z, o); } break; } return true; };
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(str_motd.substr(pos, nextpos - pos).c_str()); ++linecount; } pos = nextpos + 1; } if (pos < str_motd.length()) { ChatHandler(pCurrChar).PSendSysMessage(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); } if (!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) pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); else 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; delete holder; }
//spawn go static bool HandleGameObjectAddCommand(ChatHandler* handler, char const* args) { if (!*args) return false; // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r char* id = handler->extractKeyFromLink((char*)args, "Hgameobject_entry"); if (!id) return false; uint32 objectId = atol(id); if (!objectId) return false; if (handler->GetSession()->GetSecurity() == SEC_MODERATOR && handler->GetSession()->GetPlayer()->GetPhaseMask() == 1) { handler->SendSysMessage("You cannot permanently spawn in the main phase. Use .modify phase $number to spawn your GameObject, or spawn your GameObject temporarily."); return true; } if (handler->GetSession()->GetSecurity() == SEC_MODERATOR && handler->GetSession()->GetPlayer()->GetPhaseMask() == -1) { handler->SendSysMessage("You cannot permanently spawn in the main phase. Use .modify phase $number to spawn your GameObject, or spawn your GameObject temporarily."); return true; } char* spawntimeSecs = strtok(NULL, " "); const GameObjectTemplate* objectInfo = sObjectMgr->GetGameObjectTemplate(objectId); if (!objectInfo) { handler->PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST, objectId); handler->SetSentErrorMessage(true); return false; } if (objectInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(objectInfo->displayId)) { // report to DB errors log as in loading case TC_LOG_ERROR("sql.sql", "Gameobject (Entry %u GoType: %u) have invalid displayId (%u), not spawned.", objectId, objectInfo->type, objectInfo->displayId); handler->PSendSysMessage(LANG_GAMEOBJECT_HAVE_INVALID_DATA, objectId); handler->SetSentErrorMessage(true); return false; } Player* player = handler->GetSession()->GetPlayer(); float x = float(player->GetPositionX()); float y = float(player->GetPositionY()); float z = float(player->GetPositionZ()); float o = float(player->GetOrientation()); Map* map = player->GetMap(); GameObject* object = new GameObject; uint32 guidLow = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT); if (!object->Create(guidLow, objectInfo->entry, map, player->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) { delete object; return false; } if (spawntimeSecs) { uint32 value = atoi((char*)spawntimeSecs); object->SetRespawnTime(value); } // fill the gameobject data and save to the db object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMaskForSpawn()); // delete the old object and do a clean load from DB with a fresh new GameObject instance. // this is required to avoid weird behavior and memory leaks delete object; object = new GameObject(); // this will generate a new guid if the object is in an instance if (!object->LoadGameObjectFromDB(guidLow, map)) { delete object; return false; } /// @todo is it really necessary to add both the real and DB table guid here ? sObjectMgr->AddGameobjectToGrid(guidLow, sObjectMgr->GetGOData(guidLow)); handler->PSendSysMessage(LANG_GAMEOBJECT_ADD, objectId, objectInfo->name.c_str(), guidLow, x, y, z); return true; }
void UpdateAI(const uint32 diff) { events.Update(diff); if (!UpdateVictim()) return; if (fixated) { if (target_after != NULL && target_after && target_after->IsInWorld() && target_after->isAlive() && target_after->HasAura(FIXATE_AURA)) { me->AttackStop(); // Stop attacking DoMeleeAttackIfReady() me->SetReactState(REACT_PASSIVE); me->GetMotionMaster()->MovePoint(1, target_after->GetPositionX(), target_after->GetPositionY(), target_after->GetPositionZ()); } else { fixated = false; target_after = NULL; AttackStart(me->getVictim()); // Start attack the victim (random?) me->SetReactState(REACT_AGGRESSIVE); } } // band of valor std::list<Creature*> Cr_list; JadeCore::AnyCreatureInObjectRangeCheck check(me, 8.0f); JadeCore::CreatureListSearcher<JadeCore::AnyCreatureInObjectRangeCheck> searcher(me, Cr_list, check); me->VisitNearbyObject(8.0f, searcher); for (std::list<Creature*>::const_iterator it = Cr_list.begin(); it != Cr_list.end(); ++it) { if (!(*it)) return; if ((*it)->GetEntry() == 63591 || (*it)->GetEntry() == 64453) { if (me->HasAura(125422)) { AuraPtr band_of_valor = me->GetAura(125422); if (band_of_valor) { band_of_valor->SetStackAmount(Cr_list.size() - 1); } } else { me->AddAura(125422, me); } } } while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_FIXATE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true)) { me->CastSpell(target, FIXATE); fixated = true; target_after = target->ToPlayer(); events.ScheduleEvent(EVENT_FIXATE, urand(32000, 60000)); } break; case EVENT_SONIC_BLADE: me->CastSpell(me->getVictim(), SONIC_BOMB); events.ScheduleEvent(EVENT_SONIC_BLADE, urand(6000, 10000)); break; case EVENT_DISPATCH: me->AddAura(DISPATCH, me); events.ScheduleEvent(DISPATCH, 21000); break; case EVENT_STICKY_RESIN: Position pos; int32 reduction = urand(0, 1); if (reduction == 1) { me->GetRandomNearPosition(pos, frand(5.0f, 10.0f)); me->SummonCreature(STICKY_RESIN_TRIGGER, pos, TEMPSUMMON_MANUAL_DESPAWN); events.ScheduleEvent(EVENT_STICKY_RESIN, urand(15000, 22000)); } break; } } DoMeleeAttackIfReady(); }
static bool HandleGameObjectAddTempCommand(ChatHandler* handler, char const* args) { if (handler->GetSession()->GetSecurity() == SEC_PLAYER) { int timeSinceLastSpawn = handler->GetSession()->GetPlayer()->m_lastSpawnTime - getMSTime(); if (timeSinceLastSpawn > -TIME_BETWEEN_SPAWNS_MILLIS && timeSinceLastSpawn < TIME_BETWEEN_SPAWNS_MILLIS) { handler->SendSysMessage("You may only spawn GameObjects once every second, unless you are a voter."); return true; } else handler->GetSession()->GetPlayer()->m_lastSpawnTime = getMSTime(); } if (!handler->GetSession()->GetPlayer()->CanUseID(DISABLE_TYPE_ZONE, handler->GetSession()->GetPlayer()->GetZoneId())) { handler->SendSysMessage("Spawning is prohibited in this zone."); return true; } if (!*args) return false; char* id = strtok((char*)args, " "); if (!id) return false; Player* player = handler->GetSession()->GetPlayer(); char* spawntime = strtok(NULL, " "); uint32 spawntm = 300; if (spawntime) spawntm = atoi((char*)spawntime); float x = player->GetPositionX(); float y = player->GetPositionY(); float z = player->GetPositionZ(); float ang = player->GetOrientation(); float rot2 = std::sin(ang/2); float rot3 = std::cos(ang/2); uint32 objectId = atoi(id); if (!handler->GetSession()->GetPlayer()->CanUseID(DISABLE_TYPE_GOBJECT, objectId)) { handler->PSendSysMessage("This GameObject (id '%u') is disabled.", objectId); return true; } if (!sObjectMgr->GetGameObjectTemplate(objectId)) { handler->PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST, objectId); handler->SetSentErrorMessage(true); return false; } player->SummonGameObject(objectId, x, y, z, ang, 0, 0, rot2, rot3, spawntm); return true; }
static bool HandleWPGPSCommand(ChatHandler* handler, const char *args) { Player* player = handler->GetSession()->GetPlayer(); sLog->outSQLDev("(@PATH,XX,%.3f,%.3f,%.5f,0,0,0,100,0),", player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); handler->PSendSysMessage("Waypoint SQL written to SQL Developer log"); return true; }
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); // load player specific part before send times LoadAccountData(holder->GetResult(PLAYER_LOGIN_QUERY_LOADACCOUNTDATA),PER_CHARACTER_CACHE_MASK); SendAccountDataTimes(PER_CHARACTER_CACHE_MASK); 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 = sObjectMgr.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->DisplayGuildBankTabsInfo(this); guild->BroadcastEvent(GE_SIGNED_ON, pCurrChar->GetGUID(), 1, pCurrChar->GetName(), "", ""); } 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); } } data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4+4); data << uint32(0); data << uint32(0); SendPacket(&data); 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) pCurrChar->SendCinematicStart(cEntry->CinematicSequence); else if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) pCurrChar->SendCinematicStart(rEntry->CinematicSequence); } } if (!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) pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); else pCurrChar->TeleportToHomebind(); } sObjectAccessor.AddObject(pCurrChar); //DEBUG_LOG("Player %s added to Map.",pCurrChar->GetName()); 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); // 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->SetMovement(MOVE_WATER_WALK); } pCurrChar->ContinueTaxiFlight(); // reset for all pets before pet loading if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS)) Pet::resetTalentsForAllPetsOf(pCurrChar); // 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,true); pCurrChar->SendTalentsInfoData(false); // original talents send already in to SendInitialPacketsBeforeAddToMap, resend reset state 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); 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; delete holder; }
void SpellHitTarget(Unit* pTarget, const SpellInfo *spell) { if (spell->Id == SPELL_INSANITY) { // Not good target or too many players if (pTarget->GetTypeId() != TYPEID_PLAYER || insanityHandled > 4) return; // First target - start channel visual and set self as unnattackable if (!insanityHandled) { me->RemoveAllAuras(); me->CastSpell(me, INSANITY_VISUAL, true); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetControlled(true, UNIT_STATE_STUNNED); } // phase mask pTarget->CastSpell(pTarget, SPELL_INSANITY_TARGET+insanityHandled, true); // summon twisted party members for this target Map::PlayerList const &players = me->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) { Player *plr = i->GetSource(); if (!plr || !plr->IsAlive() || pTarget->GetGUID() == plr->GetGUID()) continue; // Summon clone if (Unit* summon = me->SummonCreature(NPC_TWISTED_VISAGE, plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), plr->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 0)) { summon->AddThreat(pTarget, 0.0f); summon->SetInCombatWith(pTarget); pTarget->SetInCombatWith(summon); plr->CastSpell(summon, SPELL_CLONE_PLAYER, true); summon->SetPhaseMask(1|(1<<(4+insanityHandled)), true); summon->SetUInt32Value(UNIT_FIELD_MINDAMAGE, plr->GetUInt32Value(UNIT_FIELD_MINDAMAGE)); summon->SetUInt32Value(UNIT_FIELD_MAXDAMAGE, plr->GetUInt32Value(UNIT_FIELD_MAXDAMAGE)); } } ++insanityHandled; } }
void WorldSession::HandlePlayerLoginOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,8); m_playerLoading = true; uint64 playerGuid = 0; DEBUG_LOG( "WORLD: Recvd Player Logon Message" ); recv_data >> playerGuid; Player* plr = new Player(this); // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if(!plr->LoadFromDB(GUID_LOPART(playerGuid))) { KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete plr; // delete it manually m_playerLoading = false; return; } //plr->_RemoveAllItemMods(); //set a count of unread mails time_t cTime = time(NULL); QueryResult *resultMails = sDatabase.PQuery("SELECT COUNT(id) FROM `mail` WHERE `receiver` = '%u' AND `checked` = 0 AND `deliver_time` <= '" I64FMTD "'", GUID_LOPART(playerGuid),(uint64)cTime); if (resultMails) { Field *fieldMail = resultMails->Fetch(); plr->unReadMails = fieldMail[0].GetUInt8(); delete resultMails; } // store nearest delivery time (it > 0 and if it < current then at next player update SendNewMaill will be called) resultMails = sDatabase.PQuery("SELECT MIN(`deliver_time`) FROM `mail` WHERE `receiver` = '%u' AND `checked` = 0", GUID_LOPART(playerGuid)); if (resultMails) { Field *fieldMail = resultMails->Fetch(); plr->m_nextMailDelivereTime = (time_t)fieldMail[0].GetUInt64(); delete resultMails; } SetPlayer(plr); Player *pCurrChar = GetPlayer(); pCurrChar->SendDungeonDifficulty(); WorldPacket data( SMSG_LOGIN_VERIFY_WORLD, 20 ); data << plr->GetMapId(); data << plr->GetPositionX(); data << plr->GetPositionY(); data << plr->GetPositionZ(); data << plr->GetOrientation(); SendPacket(&data); data.Initialize( SMSG_ACCOUNT_DATA_MD5, 128 ); for(int i = 0; i < 32; i++) data << uint32(0); SendPacket(&data); pCurrChar->LoadIgnoreList(); pCurrChar->SendFriendlist(); pCurrChar->SendIgnorelist(); // Send MOTD { data.Initialize(SMSG_MOTD, 50); // new in 2.0.1 data << (uint32)0; uint32 linecount=0; string str_motd = sWorld.GetMotd(); string::size_type pos, nextpos; pos = 0; while ( (nextpos= str_motd.find('@',pos)) != string::npos ) { if (nextpos != pos) { data << str_motd.substr(pos,nextpos-pos); linecount++; } pos = nextpos+1; } if (pos<str_motd.length()) { data << str_motd.substr(pos); linecount++; } data.put(0, linecount); SendPacket( &data ); DEBUG_LOG( "WORLD: Sent motd (SMSG_MOTD)" ); } if(pCurrChar->GetGuildId() != 0) { Guild* guild = objmgr.GetGuildById(pCurrChar->GetGuildId()); if(guild) { data.Initialize(SMSG_GUILD_EVENT, (2+guild->GetMOTD().size()+1)); data << (uint8)GE_MOTD; data << (uint8)1; data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG( "WORLD: Sent guild-motd (SMSG_GUILD_EVENT)" ); data.Initialize(SMSG_GUILD_EVENT, (5+10)); // we guess size data<<(uint8)GE_SIGNED_ON; data<<(uint8)1; data<<pCurrChar->GetName(); data<<pCurrChar->GetGUID(); guild->BroadcastPacket(&data); DEBUG_LOG( "WORLD: Sent guild-signed-on (SMSG_GUILD_EVENT)" ); } else { // remove wrong guild data sLog.outError("Player %s (GUID: %u) marked as member not existed guild (id: %u), removing guild membership for player.",pCurrChar->GetName(),pCurrChar->GetGUIDLow(),pCurrChar->GetGuildId()); pCurrChar->SetUInt32Value(PLAYER_GUILDID,0); pCurrChar->SetUInt32ValueInDB(PLAYER_GUILDID,0,pCurrChar->GetGUID()); } } // rest_start // home bind stuff { QueryResult *result4 = sDatabase.PQuery("SELECT `map`,`zone`,`position_x`,`position_y`,`position_z` FROM `character_homebind` WHERE `guid` = '%u'", GUID_LOPART(playerGuid)); if (result4) { Field *fields = result4->Fetch(); _player->m_homebindMapId = fields[0].GetUInt32(); _player->m_homebindZoneId = fields[1].GetUInt16(); _player->m_homebindX = fields[2].GetFloat(); _player->m_homebindY = fields[3].GetFloat(); _player->m_homebindZ = fields[4].GetFloat(); delete result4; } else { int plrace = GetPlayer()->getRace(); int plclass = GetPlayer()->getClass(); QueryResult *result5 = sDatabase.PQuery("SELECT `map`,`zone`,`position_x`,`position_y`,`position_z` FROM `playercreateinfo` WHERE `race` = '%u' AND `class` = '%u'", plrace, plclass); if(!result5) { sLog.outErrorDb("Table `playercreateinfo` not have data for race %u class %u , character can't be loaded.",plrace, plclass); LogoutPlayer(false); // without save return; } Field *fields = result5->Fetch(); // store and send homebind for player _player->m_homebindMapId = fields[0].GetUInt32(); _player->m_homebindZoneId = fields[1].GetUInt16(); _player->m_homebindX = fields[2].GetFloat(); _player->m_homebindY = fields[3].GetFloat(); _player->m_homebindZ = fields[4].GetFloat(); sDatabase.PExecute("INSERT INTO `character_homebind` (`guid`,`map`,`zone`,`position_x`,`position_y`,`position_z`) VALUES ('%u', '%u', '%u', '%f', '%f', '%f')", GUID_LOPART(playerGuid), _player->m_homebindMapId, (uint32)_player->m_homebindZoneId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ); delete result5; } data.Initialize (SMSG_BINDPOINTUPDATE, 5*4); data << _player->m_homebindX << _player->m_homebindY << _player->m_homebindZ; data << (uint32) _player->m_homebindMapId; data << (uint32) _player->m_homebindZoneId; SendPacket (&data); DEBUG_LOG("Setting player home position: mapid is: %u, zoneid is %u, X is %f, Y is %f, Z is %f\n", _player->m_homebindMapId,_player->m_homebindZoneId,_player->m_homebindX,_player->m_homebindY, _player->m_homebindZ); } data.Initialize( SMSG_TUTORIAL_FLAGS, 8*32 ); for (int i = 0; i < 8; i++) data << uint32( GetPlayer()->GetTutorialInt(i) ); SendPacket(&data); //sLog.outDebug( "WORLD: Sent tutorial flags." ); pCurrChar->_LoadSpellCooldowns(); GetPlayer()->SendInitialSpells(); GetPlayer()->SendInitialActionButtons(); GetPlayer()->SendInitialReputations(); /*if(GetPlayer()->getClass() == CLASS_HUNTER || GetPlayer()->getClass() == CLASS_ROGUE) { uint32 shiftdata=0x01; for(uint8 i=0;i<32;i++) { if ( 522753 & shiftdata ) { data.Initialize(SMSG_SET_FLAT_SPELL_MODIFIER); data << uint8(i); data << uint8(5); data << uint16(1); data << uint16(0); SendPacket(&data); } shiftdata=shiftdata<<1; } }*/ //Show cinematic at the first time that player login if( !GetPlayer()->getCinematic() ) { GetPlayer()->setCinematic(1); ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(GetPlayer()->getRace()); if(rEntry) { data.Initialize( SMSG_TRIGGER_CINEMATIC,4 ); data << uint32(rEntry->startmovie); SendPacket( &data ); } } pCurrChar->SendInitWorldStates(); pCurrChar->CastSpell(pCurrChar, 836, true); // LOGINEFFECT data.Initialize(SMSG_LOGIN_SETTIMESPEED, 8); time_t gameTime = sWorld.GetGameTime(); struct tm *lt = localtime(&gameTime); uint32 xmitTime = (lt->tm_year - 100) << 24 | lt->tm_mon << 20 | (lt->tm_mday - 1) << 14 | lt->tm_wday << 11 | lt->tm_hour << 6 | lt->tm_min; data << xmitTime; data << (float)0.017f; // game speed SendPacket( &data ); GetPlayer()->UpdateHonorFields(); QueryResult *result = sDatabase.PQuery("SELECT `guildid`,`rank` FROM `guild_member` WHERE `guid` = '%u'",pCurrChar->GetGUIDLow()); if(result) { Field *fields = result->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); delete result; } else if(pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about non existed membership { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } if (!MapManager::Instance().GetMap(pCurrChar->GetMapId(), pCurrChar)->AddInstanced(pCurrChar)) { // TODO : Teleport to zone-in area } MapManager::Instance().GetMap(pCurrChar->GetMapId(), pCurrChar)->Add(pCurrChar); ObjectAccessor::Instance().InsertPlayer(pCurrChar); //sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); if (pCurrChar->m_transport) { Transport* curTrans = pCurrChar->m_transport; pCurrChar->TeleportTo(curTrans->GetMapId(), curTrans->GetPositionX(), curTrans->GetPositionY(), curTrans->GetPositionZ(), curTrans->GetOrientation(), true, false); } sDatabase.PExecute("UPDATE `character` SET `online` = 1 WHERE `guid` = '%u'", pCurrChar->GetGUIDLow()); loginDatabase.PExecute("UPDATE `account` SET `online` = 1 WHERE `id` = '%u'", GetAccountId()); plr->SetInGameTime( getMSTime() ); // set some aura effects after add player to map if(pCurrChar->HasAuraType(SPELL_AURA_MOD_STUN)) pCurrChar->SetMovement(MOVE_ROOT); if(pCurrChar->HasAuraType(SPELL_AURA_MOD_ROOT)) { WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10); data.append(pCurrChar->GetPackGUID()); data << (uint32)2; pCurrChar->SendMessageToSet(&data,true); } // announce group about member online (must be after add to player list to receive announce to self) if(pCurrChar->groupInfo.group) { //pCurrChar->groupInfo.group->SendInit(this); // useless pCurrChar->groupInfo.group->SendUpdate(); } // friend status data.Initialize(SMSG_FRIEND_STATUS, 19); data<<uint8(FRIEND_ONLINE); data<<pCurrChar->GetGUID(); data<<uint8(1); data<<pCurrChar->GetAreaId(); data<<pCurrChar->getLevel(); data<<pCurrChar->getClass(); pCurrChar->BroadcastPacketToFriendListers(&data); pCurrChar->SendEnchantmentDurations(); // must be after add to map // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); // setting Ghost+speed if dead //if ( pCurrChar->m_deathState == DEAD ) if ( pCurrChar->m_deathState != ALIVE ) { // not blizz like, we must correctly save and load player instead... if(pCurrChar->getRace() == RACE_NIGHTELF) pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+41, 8326); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+42, 20584); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAFLAGS+6, 238); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURALEVELS+11, 514); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+11, 65535); //pCurrChar->SetUInt32Value(UNIT_FIELD_DISPLAYID, 1825); //if (pCurrChar->getRace() == RACE_NIGHTELF) //{ // pCurrChar->SetSpeed(MOVE_RUN, 1.5f*1.2f, true); // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f*1.2f, true); //} //else //{ // pCurrChar->SetSpeed(MOVE_RUN, 1.5f, true); // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f, true); //} pCurrChar->SetMovement(MOVE_WATER_WALK); } // Load pet if any and player is alive if(pCurrChar->isAlive()) pCurrChar->LoadPet(); // show time before shutdown if shutdown planned. if(sWorld.IsShutdowning()) sWorld.ShutdownMsg(true,pCurrChar); if(pCurrChar->isGameMaster()) SendNotification("GM mode is ON"); m_playerLoading = false; pCurrChar->SendAllowMove(); data.Initialize(SMSG_UNKNOWN_811, 4); data << uint32(0); SendPacket(&data); }
//spawn go static bool HandleGameObjectAddCommand(ChatHandler* handler, char const* args) { if (!*args) return false; // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r char* id = handler->extractKeyFromLink((char*)args, "Hgameobject_entry"); if (!id) return false; uint32 objectId = atol(id); if (!objectId) return false; char* spawntimeSecs = strtok(NULL, " "); const GameObjectTemplate* objectInfo = sObjectMgr->GetGameObjectTemplate(objectId); if (!objectInfo) { handler->PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST, objectId); handler->SetSentErrorMessage(true); return false; } if (objectInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(objectInfo->displayId)) { // report to DB errors log as in loading case sLog->outErrorDb("Gameobject (Entry %u GoType: %u) have invalid displayId (%u), not spawned.", objectId, objectInfo->type, objectInfo->displayId); handler->PSendSysMessage(LANG_GAMEOBJECT_HAVE_INVALID_DATA, objectId); handler->SetSentErrorMessage(true); return false; } Player* player = handler->GetSession()->GetPlayer(); float x = float(player->GetPositionX()); float y = float(player->GetPositionY()); float z = float(player->GetPositionZ()); float o = float(player->GetOrientation()); Map* map = player->GetMap(); GameObject* object = new GameObject; uint32 guidLow = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT); if (!object->Create(guidLow, objectInfo->entry, map, player->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) { delete object; return false; } if (spawntimeSecs) { uint32 value = atoi((char*)spawntimeSecs); object->SetRespawnTime(value); } // fill the gameobject data and save to the db object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMaskForSpawn()); // this will generate a new guid if the object is in an instance if (!object->LoadGameObjectFromDB(guidLow, map)) { delete object; return false; } // TODO: is it really necessary to add both the real and DB table guid here ? sObjectMgr->AddGameobjectToGrid(guidLow, sObjectMgr->GetGOData(guidLow)); handler->PSendSysMessage(LANG_GAMEOBJECT_ADD, objectId, objectInfo->name.c_str(), guidLow, x, y, z); return true; }
void WorldSession::HandleBattleGroundJoinOpcode(WorldPacket& recv_data) { uint64 guid; uint32 bgTypeId; uint32 instanceId; uint8 joinAsGroup; Group * grp; recv_data >> guid; // battlemaster guid recv_data >> bgTypeId; // battleground type id (DBC id) recv_data >> instanceId; // instance id, 0 if First Available selected recv_data >> joinAsGroup; // join as group if (bgTypeId >= MAX_BATTLEGROUND_TYPES) { sLog.outError("Battleground: invalid bgtype received. possible cheater? player guid %u",_player->GetGUIDLow()); return; } sLog.outDebug("WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid))); // can do this, since it's battleground, not arena uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId, 0); // ignore if player is already in BG if (_player->InBattleGround()) return; Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); if (!unit) return; if (!unit->isBattleMaster()) // it's not battlemaster return; // get bg instance or bg template if instance not found BattleGround* bg = NULL; if (instanceId) bg = sBattleGroundMgr.GetBattleGround(instanceId); if (!bg && !(bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId))) { sLog.outError("Battleground: no available bg / template found"); return; } // check queueing conditions if (!joinAsGroup) { // check Deserter debuff if (!_player->CanJoinToBattleground()) { WorldPacket data(SMSG_GROUP_JOINED_BATTLEGROUND, 4); data << (uint32) 0xFFFFFFFE; _player->GetSession()->SendPacket(&data); return; } // check if already in queue if (_player->GetBattleGroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES) //player is already in this queue return; // check if has free queue slots if (!_player->HasFreeBattleGroundQueueId()) return; } else { grp = _player->GetGroup(); // no group found, error if (!grp) return; uint32 err = grp->CanJoinBattleGroundQueue(bgTypeId, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0); if (err != BG_JOIN_ERR_OK) { SendBattleGroundOrArenaJoinError(err); return; } } // if we're here, then the conditions to join a bg are met. We can proceed in joining. // _player->GetGroup() was already checked, grp is already initialized if (joinAsGroup /* && _player->GetGroup()*/) { sLog.outDebug("Battleground: the following players are joining as group:"); GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, 0); for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->getSource(); if (!member) continue; // this should never happen uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId); // add to queue // store entry point coords (same as leader entry point) if (!sWorld.getConfig(CONFIG_BATTLEGROUND_WRATH_LEAVE_MODE)) member->SetBattleGroundEntryPoint(member->GetMapId(), member->GetPositionX(), member->GetPositionY(), member->GetPositionZ(), member->GetOrientation()); WorldPacket data; // send status packet (in queue) sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0); member->GetSession()->SendPacket(&data); sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId); member->GetSession()->SendPacket(&data); sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(member, ginfo); sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName()); } sLog.outDebug("Battleground: group end"); sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel()); } else { // already checked if queueSlot is valid, now just get it uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId); // store entry point coords if (!sWorld.getConfig(CONFIG_BATTLEGROUND_WRATH_LEAVE_MODE)) _player->SetBattleGroundEntryPoint(_player->GetMapId(), _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetOrientation()); WorldPacket data; // send status packet (in queue) sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0); SendPacket(&data); GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, 0); sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo); sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel()); sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName()); } }
//move selected object static bool HandleGameObjectMoveCommand(ChatHandler* handler, char const* args) { // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r char* id = handler->extractKeyFromLink((char*)args, "Hgameobject"); if (!id) return false; uint32 guidLow = atoi(id); if (!guidLow) return false; GameObject* object = NULL; // by DB guid if (GameObjectData const* gameObjectData = sObjectMgr->GetGOData(guidLow)) object = handler->GetObjectGlobalyWithGuidOrNearWithDbGuid(guidLow, gameObjectData->id); if (!object) { handler->PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, guidLow); handler->SetSentErrorMessage(true); return false; } char* toX = strtok(NULL, " "); char* toY = strtok(NULL, " "); char* toZ = strtok(NULL, " "); if (!toX) { Player* player = handler->GetSession()->GetPlayer(); object->Relocate(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), object->GetOrientation()); object->DestroyForNearbyPlayers(); object->UpdateObjectVisibility(); } else { if (!toY || !toZ) return false; float x = (float)atof(toX); float y = (float)atof(toY); float z = (float)atof(toZ); if (!MapManager::IsValidMapCoord(object->GetMapId(), x, y, z)) { handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, x, y, object->GetMapId()); handler->SetSentErrorMessage(true); return false; } object->Relocate(x, y, z, object->GetOrientation()); object->DestroyForNearbyPlayers(); object->UpdateObjectVisibility(); } object->SaveToDB(); object->Refresh(); handler->PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, object->GetGUIDLow(), object->GetGOInfo()->name.c_str(), object->GetGUIDLow()); return true; }
bool ToLegionHold(uint32 i, Aura * pAura, bool apply) { if ( pAura == NULL || pAura->GetUnitCaster() == NULL || !pAura->GetUnitCaster()->IsPlayer() ) return true; Player * pPlayer = TO_PLAYER( pAura->GetUnitCaster() ); Creature * pJovaanCheck = pPlayer->GetMapMgr()->GetInterface()->GetCreatureNearestCoords(-3310.743896f, 2951.929199f, 171.132538f, 21633); if ( pJovaanCheck != NULL ) return true; QuestLogEntry *pQuest = pPlayer->GetQuestLogForEntry( 10563 ); if ( pQuest == NULL ) { pQuest = pPlayer->GetQuestLogForEntry( 10596 ); if ( pQuest == NULL ) return true; } if ( apply ) { pPlayer->SetUInt32Value( UNIT_FIELD_DISPLAYID, 20366 ); pPlayer->Root(); Creature * pJovaan = sEAS.SpawnCreature( pPlayer, 21633, -3310.743896f, 2951.929199f, 171.132538f, 5.054039f, 0 ); // Spawn Jovaan if ( pJovaan != NULL ) { pJovaan->SetUInt64Value( UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2 ); if ( pJovaan->GetAIInterface() != NULL ) { pJovaan->GetAIInterface()->SetAllowedToEnterCombat( false ); } } GameObject * pGameObject = pPlayer->GetMapMgr()->GetInterface()->GetGameObjectNearestCoords(pPlayer->GetPositionX(), pPlayer->GetPositionY(), pPlayer->GetPositionZ(), 184834); if ( pGameObject != NULL ) { pGameObject->Despawn(60000); pPlayer->UpdateNearbyGameObjects(); } } else { if ( pQuest->GetMobCount( 2 ) < pQuest->GetQuest()->required_mobcount[2] ) { pQuest->SetMobCount( 2, pQuest->GetMobCount( 2 ) + 1 ); pQuest->SendUpdateAddKill( 2 ); pQuest->UpdatePlayerFields(); } pPlayer->SetUInt32Value( UNIT_FIELD_DISPLAYID, pPlayer->GetUInt32Value( UNIT_FIELD_NATIVEDISPLAYID ) ); pPlayer->UnRoot(); } return true; }
bool ChatHandler::HandleWaypointAddFlyCommand(const char* args, WorldSession* m_session) { uint64 guid = m_session->GetPlayer()->GetSelection(); if(guid == 0) { SystemMessage(m_session, "No Selection"); return true; } AIInterface* ai = NULL; Creature* pCreature = NULL; Player* p = m_session->GetPlayer(); if(p->waypointunit != NULL) { SystemMessage(m_session, "Using Previous Unit."); ai = p->waypointunit; if(!ai) { SystemMessage(m_session, "Invalid Creature, please select another one."); return true; } pCreature = TO_CREATURE(ai->GetUnit()); if(!pCreature || pCreature->IsPet()) { SystemMessage(m_session, "Invalid Creature, please select another one."); return true; } } else { pCreature = m_session->GetPlayer()->GetMapMgr()->GetCreature(GET_LOWGUID_PART(guid)); if(!pCreature || pCreature->IsPet()) { SystemMessage(m_session, "You should select a creature."); return true; } ai = pCreature->GetAIInterface(); } char* pWaitTime = strtok((char*)args, " "); uint32 WaitTime = (pWaitTime) ? atoi(pWaitTime) : 10000; char* pForwardEmoteId = strtok(NULL, " "); uint32 ForwardEmoteId = (pForwardEmoteId) ? atoi(pForwardEmoteId) : 0; char* pBackwardEmoteId = strtok(NULL, " "); uint32 BackwardEmoteId = (pBackwardEmoteId) ? atoi(pBackwardEmoteId) : 0; char* pForwardSkinId = strtok(NULL, " "); uint32 ForwardSkinId = (pForwardSkinId) ? atoi(pForwardSkinId) : pCreature->GetNativeDisplayId(); char* pBackwardSkinId = strtok(NULL, " "); uint32 BackwardSkinId = (pBackwardSkinId) ? atoi(pBackwardSkinId) : pCreature->GetNativeDisplayId(); char* pForwardEmoteOneShot = strtok(NULL, " "); uint32 ForwardEmoteOneShot = (pForwardEmoteOneShot) ? atoi(pForwardEmoteOneShot) : 1; char* pBackwardEmoteOneShot = strtok(NULL, " "); uint32 BackwardEmoteOneShot = (pBackwardEmoteOneShot) ? atoi(pBackwardEmoteOneShot) : 1; WayPoint* wp = new WayPoint; bool showing = ai->m_WayPointsShowing; wp->id = (uint32)ai->GetWayPointsCount() + 1; wp->x = p->GetPositionX(); wp->y = p->GetPositionY(); wp->z = p->GetPositionZ(); wp->waittime = WaitTime; wp->flags = 768; wp->forwardemoteoneshot = (ForwardEmoteOneShot > 0) ? true : false; wp->forwardemoteid = ForwardEmoteId; wp->backwardemoteoneshot = (BackwardEmoteOneShot > 0) ? true : false; wp->backwardemoteid = BackwardEmoteId; wp->forwardskinid = ForwardSkinId; wp->backwardskinid = BackwardSkinId; if(showing) ai->hideWayPoints(p); if(ai->addWayPointUnsafe(wp)) { ai->saveWayPoints(); SystemMessage(m_session, "Waypoint %u added.", wp->id); } else { SystemMessage(m_session, "An error occurred while adding the Waypoint"); delete wp; } if(showing) ai->showWayPoints(p, ai->m_WayPointsShowBackwards); return true; }
bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, std::string const& 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) { 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[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 (!m_session) // ignore console return true; Player* player = m_session->GetPlayer(); if (!AccountMgr::IsPlayerAccount(m_session->GetSecurity())) { ObjectGuid guid = player->GetTarget(); uint32 areaId = player->GetAreaId(); std::string areaName = "Unknown"; std::string zoneName = "Unknown"; if (AreaTableEntry const* area = GetAreaEntryByAreaID(areaId)) { areaName = area->AreaName_lang; if (AreaTableEntry const* zone = GetAreaEntryByAreaID(area->ParentAreaID)) zoneName = zone->AreaName_lang; } sLog->outCommand(m_session->GetAccountId(), "Command: %s [Player: %s (%s) (Account: %u) X: %f Y: %f Z: %f Map: %u (%s) Area: %u (%s) Zone: %s Selected: %s (%s)]", fullcmd.c_str(), player->GetName().c_str(), player->GetGUID().ToString().c_str(), m_session->GetAccountId(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetMap() ? player->GetMap()->GetMapName() : "Unknown", areaId, areaName.c_str(), zoneName.c_str(), (player->GetSelectedUnit()) ? player->GetSelectedUnit()->GetName().c_str() : "", guid.ToString().c_str()); } } // 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; }
static bool HandleWpModifyCommand(ChatHandler* handler, const char* args) { if (!*args) return false; // first arg: add del text emote spell waittime move char* show_str = strtok((char*)args, " "); if (!show_str) { return false; } std::string show = show_str; // Check // Remember: "show" must also be the name of a column! if ((show != "delay") && (show != "action") && (show != "action_chance") && (show != "move_flag") && (show != "del") && (show != "move") && (show != "wpadd") ) { return false; } // Next arg is: <PATHID> <WPNUM> <ARGUMENT> char* arg_str = nullptr; // Did user provide a GUID // or did the user select a creature? // -> variable lowguid is filled with the GUID of the NPC uint32 pathid = 0; uint32 point = 0; uint32 wpGuid = 0; Creature* target = handler->getSelectedCreature(); if (!target || target->GetEntry() != VISUAL_WAYPOINT) { handler->SendSysMessage("|cffff33ffERROR: You must select a waypoint.|r"); return false; } // The visual waypoint wpGuid = target->GetGUIDLow(); // User did select a visual waypoint? // Check the creature PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_BY_WPGUID); stmt->setUInt32(0, wpGuid); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow()); // Select waypoint number from database // Since we compare float values, we have to deal with // some difficulties. // Here we search for all waypoints that only differ in one from 1 thousand // (0.001) - There is no other way to compare C++ floats with mySQL floats // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html std::string maxDiff = "0.01"; PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_BY_POS); stmt->setFloat(0, target->GetPositionX()); stmt->setString(1, maxDiff); stmt->setFloat(2, target->GetPositionY()); stmt->setString(3, maxDiff); stmt->setFloat(4, target->GetPositionZ()); stmt->setString(5, maxDiff); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid); return true; } } do { Field* fields = result->Fetch(); pathid = fields[0].GetUInt32(); point = fields[1].GetUInt32(); } while (result->NextRow()); // We have the waypoint number and the GUID of the "master npc" // Text is enclosed in "<>", all other arguments not arg_str = strtok((char*)NULL, " "); // Check for argument if (show != "del" && show != "move" && arg_str == NULL) { handler->PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str); return false; } if (show == "del") { handler->PSendSysMessage("|cff00ff00DEBUG: wp modify del, PathID: |r|cff00ffff%u|r", pathid); if (wpGuid != 0) if (Creature* wcreature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT))) { wcreature->CombatStop(); wcreature->DeleteFromDB(); wcreature->AddObjectToRemoveList(); } PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_WAYPOINT_DATA); stmt->setUInt32(0, pathid); stmt->setUInt32(1, point); WorldDatabase.Execute(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_POINT); stmt->setUInt32(0, pathid); stmt->setUInt32(1, point); WorldDatabase.Execute(stmt); handler->PSendSysMessage(LANG_WAYPOINT_REMOVED); return true; } // del if (show == "move") { handler->PSendSysMessage("|cff00ff00DEBUG: wp move, PathID: |r|cff00ffff%u|r", pathid); Player* chr = handler->GetSession()->GetPlayer(); Map* map = chr->GetMap(); { // What to do: // Move the visual spawnpoint // Respawn the owner of the waypoints if (wpGuid != 0) { if (Creature* wcreature = map->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT))) { wcreature->CombatStop(); wcreature->DeleteFromDB(); wcreature->AddObjectToRemoveList(); } // re-create Creature* wcreature2 = new Creature(); if (!wcreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMask(), VISUAL_WAYPOINT, 0, 0, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); delete wcreature2; wcreature2 = nullptr; return false; } wcreature2->CopyPhaseFrom(chr); wcreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); /// @todo Should we first use "Create" then use "LoadFromDB"? if (!wcreature2->LoadCreatureFromDB(wcreature2->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); delete wcreature2; wcreature2 = nullptr; return false; } //sMapMgr->GetMap(npcCreature->GetMapId())->Add(wcreature2); } PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_POSITION); stmt->setFloat(0, chr->GetPositionX()); stmt->setFloat(1, chr->GetPositionY()); stmt->setFloat(2, chr->GetPositionZ()); stmt->setUInt32(3, pathid); stmt->setUInt32(4, point); WorldDatabase.Execute(stmt); handler->PSendSysMessage(LANG_WAYPOINT_CHANGED); } return true; } // move const char *text = arg_str; if (text == 0) { // show_str check for present in list of correct values, no sql injection possible WorldDatabase.PExecute("UPDATE waypoint_data SET %s=NULL WHERE id='%u' AND point='%u'", show_str, pathid, point); // Query can't be a prepared statement } else { // show_str check for present in list of correct values, no sql injection possible std::string text2 = text; WorldDatabase.EscapeString(text2); WorldDatabase.PExecute("UPDATE waypoint_data SET %s='%s' WHERE id='%u' AND point='%u'", show_str, text2.c_str(), pathid, point); // Query can't be a prepared statement } handler->PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str); return true; }
// this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recv_data) { DEBUG_LOG("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid guid; recv_data >> guid; Player* player = ObjectAccessor::FindPlayer(guid, false); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 1 + 8 + 4 + 2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Powers powerType = player->getPowerType(); uint32 updateFlags = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | GROUP_UPDATE_FLAG_PET_AURAS; if (powerType != POWER_MANA) updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE; Pet* pet = player->GetPet(); if (pet) updateFlags |= GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_POWER_TYPE | GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER; if (player->GetVehicle()) updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT; uint16 playerStatus = player->IsReferAFriendLinked(player) ? (MEMBER_STATUS_ONLINE | MEMBER_STATUS_RAF) : MEMBER_STATUS_ONLINE; if (player->IsPvP()) playerStatus |= MEMBER_STATUS_PVP; if (!player->isAlive()) { if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) playerStatus |= MEMBER_STATUS_GHOST; else playerStatus |= MEMBER_STATUS_DEAD; } if (player->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) playerStatus |= MEMBER_STATUS_PVP_FFA; if (player->isAFK()) playerStatus |= MEMBER_STATUS_AFK; if (player->isDND()) playerStatus |= MEMBER_STATUS_DND; WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 255); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); data << uint32(updateFlags); data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE) data << uint8(powerType); data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL // verify player coordinates and zoneid to send to teammates uint16 iZoneId = 0; uint16 iCoordX = 0; uint16 iCoordY = 0; if (player->IsInWorld()) { iZoneId = player->GetZoneId(); iCoordX = player->GetPositionX(); iCoordY = player->GetPositionY(); } else if (player->IsBeingTeleported()) // Player is in teleportation { WorldLocation& loc = player->GetTeleportDest(); // So take teleportation destination iZoneId = sTerrainMgr.GetZoneId(loc.GetMapId(), loc.x, loc.y, loc.z); iCoordX = loc.x; iCoordY = loc.y; } data << uint16(iZoneId); // GROUP_UPDATE_FLAG_ZONE data << uint16(iCoordX); // GROUP_UPDATE_FLAG_POSITION data << uint16(iCoordY); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (SpellAuraHolderPtr holder = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(holder->GetId()); data << uint8(holder->GetAuraFlags()); } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if(pet) { Powers petPowerType = pet->getPowerType(); data << pet->GetObjectGuid(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8(petPowerType); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petPowerType)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petPowerType)); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petAuraMask = 0; size_t petMaskPos = data.wpos(); data << uint64(petAuraMask); // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (SpellAuraHolderPtr holder = pet->GetVisibleAura(i)) { petAuraMask |= (uint64(1) << i); data << uint32(holder->GetId()); data << uint8(holder->GetAuraFlags()); } } data.put<uint64>(petMaskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(0); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS } if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT) data << uint32(player->m_movementInfo.GetTransportDBCSeat()); SendPacket(&data); }