Skip to content

Commit

Permalink
Pipe stealth and aura updates through create object
Browse files Browse the repository at this point in the history
  • Loading branch information
killerwife committed Feb 1, 2025
1 parent ec168b2 commit 7c66ae0
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 50 deletions.
7 changes: 2 additions & 5 deletions src/game/Entities/ItemHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,15 +587,12 @@ void WorldSession::HandleSellItemOpcode(WorldPacket& recv_data)
_player->ItemRemovedQuestCheck(pItem->GetEntry(), count);
UpdateData data;
if (_player->IsInWorld())
pItem->SendCreateUpdateToPlayer(_player, data);
_player->GetMap()->AddUpdateObject(pItem);
pItem->SetState(ITEM_CHANGED, _player);

_player->AddItemToBuyBackSlot(pNewItem, money);
if (_player->IsInWorld())
pNewItem->SendCreateUpdateToPlayer(_player, data);

if (_player->IsInWorld())
data.SendData(*_player->GetSession());
_player->GetMap()->AddUpdateCreateObject(pNewItem);
}
else
{
Expand Down
13 changes: 5 additions & 8 deletions src/game/Entities/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,6 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData& data, Player* target) c
data.AddUpdateBlock(buf);
}

void Object::SendCreateUpdateToPlayer(Player* player, UpdateData& data) const
{
// send create update to player
BuildCreateUpdateBlockForPlayer(data, player);
}

void Object::BuildValuesUpdateBlockForPlayer(UpdateData& data, Player* target) const
{
UpdateMask updateMask;
Expand Down Expand Up @@ -1269,7 +1263,7 @@ void Object::BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_play
BuildValuesUpdateBlockForPlayer(iter->second, iter->first);
}

void Object::BuildCreateDataForPlayer(Player* pl, UpdateDataMapType& update_players) const
void Object::BuildCreateDataForPlayer(Player* pl, UpdateDataMapType& update_players, bool auras) const
{
UpdateDataMapType::iterator iter = update_players.find(pl);

Expand All @@ -1281,6 +1275,9 @@ void Object::BuildCreateDataForPlayer(Player* pl, UpdateDataMapType& update_play
}

BuildCreateUpdateBlockForPlayer(iter->second, iter->first);

if (auras && IsUnit())
iter->second.AddAfterCreatePacket(Player::BuildAurasForTarget(static_cast<Unit const*>(this)));
}

void Object::BuildOutOfRangeDataForPlayer(Player* pl, UpdateDataMapType& update_players, ObjectGuid oorObject)
Expand Down Expand Up @@ -2798,7 +2795,7 @@ void WorldObject::BuildUpdateData(UpdateDataMapType& update_players)

void WorldObject::BuildCreateData(UpdateDataMapType& update_players)
{
WorldObjectChangeAccumulator notifier(*this, update_players);
WorldObjectCreateAccumulator notifier(*this, update_players);
Cell::VisitWorldObjects(this, notifier, GetVisibilityData().GetVisibilityDistance());

ClearUpdateMask(false);
Expand Down
3 changes: 1 addition & 2 deletions src/game/Entities/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,6 @@ class Object
bool isType(TypeMask mask) const { return (mask & m_objectType) != 0; }

virtual void BuildCreateUpdateBlockForPlayer(UpdateData& data, Player* target) const;
void SendCreateUpdateToPlayer(Player* player, UpdateData& data) const;

// must be overwrite in appropriate subclasses (WorldObject, Item currently), or will crash
virtual void AddToClientUpdateList();
Expand Down Expand Up @@ -633,6 +632,7 @@ class Object
MaNGOS::unique_weak_ptr<Object> GetWeakPtr() const { return m_scriptRef; }

static void BuildOutOfRangeDataForPlayer(Player* pl, UpdateDataMapType& update_players, ObjectGuid oorObject);
void BuildCreateDataForPlayer(Player* pl, UpdateDataMapType& update_players, bool auras = true) const;

protected:
Object();
Expand All @@ -647,7 +647,6 @@ class Object
void BuildMovementUpdate(ByteBuffer* data, uint16 updateFlags) const;
void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, UpdateMask* updateMask, Player* target) const;
void BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_players) const;
void BuildCreateDataForPlayer(Player* pl, UpdateDataMapType& update_players) const;

uint16 m_objectType;

Expand Down
53 changes: 25 additions & 28 deletions src/game/Entities/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,8 +590,6 @@ Player::Player(WorldSession* session): Unit(), m_taxiTracker(*this), m_mover(thi

m_swingErrorMsg = 0;

m_DetectInvTimer = 1 * IN_MILLISECONDS;

for (auto& j : m_bgBattleGroundQueueID)
{
j.bgQueueTypeId = BATTLEGROUND_QUEUE_NONE;
Expand Down Expand Up @@ -1664,20 +1662,12 @@ void Player::Update(const uint32 diff)
m_nextSave -= diff;
}

// Handle detect stealth players
if (m_DetectInvTimer > 0)
{
if (diff >= m_DetectInvTimer)
{
// every 400ms vs every 2000ms
if (GetMap()->IsBattleGroundOrArena() ? GetMap()->IsUpdateObjectTick() : GetMap()->IsStealthTick())
#ifdef ENABLE_PLAYERBOTS
if (isRealPlayer())
if (isRealPlayer())
#endif
HandleStealthedUnitsDetection();
m_DetectInvTimer = GetMap()->IsBattleGroundOrArena() ? 500 : 2000;
}
else
m_DetectInvTimer -= diff;
}

// Played time
if (now > m_Last_tick)
Expand Down Expand Up @@ -2282,7 +2272,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
{
AddAtClient(currentTransport);
UpdateData data;
currentTransport->SendCreateUpdateToPlayer(this, data);
currentTransport->BuildCreateUpdateBlockForPlayer(data, this);
data.SendData(*GetSession());
}
}
Expand Down Expand Up @@ -20021,31 +20011,23 @@ void Player::HandleStealthedUnitsDetection()
{
if (!hasAtClient)
{
ObjectGuid i_guid = (*i)->GetObjectGuid();
target->SendCreateUpdateToPlayer(this, data);
GetMap()->AddCreateAtClientObject(this, target);
AddAtClient((*i));
added.push_back((*i));

ObjectGuid i_guid = (*i)->GetObjectGuid();
DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "%s is detected in stealth by player %u. Distance = %f", i_guid.GetString().c_str(), GetGUIDLow(), GetDistance(*i));
}
}
else
{
if (hasAtClient)
{
target->DestroyForPlayer(this);
GetMap()->AddUpdateRemoveObject({ GetObjectGuid()}, target->GetObjectGuid());
if (target->GetTypeId() == TYPEID_UNIT)
BeforeVisibilityDestroy(static_cast<Creature*>(target));
RemoveAtClient(target);
}
}
}
if (!added.empty())
{
data.SendData(*GetSession());
for (Unit* newUnit : added)
SendAurasForTarget(newUnit);
}
}

bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc /*= nullptr*/, uint32 spellid /*= 0*/)
Expand Down Expand Up @@ -21156,7 +21138,7 @@ void Player::AddAtClient(WorldObject* target)
target->AddClientIAmAt(this);
}

void Player::RemoveAtClient(WorldObject* target, bool skipRemovalOfAt = false)
void Player::RemoveAtClient(WorldObject* target, bool skipRemovalOfAt)
{
if (target->GetTypeId() == TYPEID_UNIT)
{
Expand Down Expand Up @@ -21278,7 +21260,7 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* targe
{
if (target->isVisibleForInState(this, viewPoint, false))
{
target->SendCreateUpdateToPlayer(this, updateData);
target->BuildCreateUpdateBlockForPlayer(updateData, this);
if (target->GetTypeId() != TYPEID_GAMEOBJECT || !((GameObject*)target)->IsMoTransport())
AddAtClient(target);

Expand Down Expand Up @@ -21815,6 +21797,21 @@ void Player::SendAurasForTarget(Unit* target) const
GetSession()->SendPacket(data);
}

WorldPacket Player::BuildAurasForTarget(Unit const* target)
{
WorldPacket data(SMSG_AURA_UPDATE_ALL);
data << target->GetPackGUID();

Unit::VisibleAuraMap const& visibleAuras = target->GetVisibleAuras();
for (const auto& visibleAura : visibleAuras)
{
SpellAuraHolderConstBounds bounds = target->GetSpellAuraHolderBounds(visibleAura.second);
for (SpellAuraHolderMap::const_iterator iter = bounds.first; iter != bounds.second; ++iter)
iter->second->BuildUpdatePacket(data);
}
return data;
}

ItemSetEffect* Player::GetItemSetEffect(uint32 setId)
{
auto itr = m_itemSetEffects.find(setId);
Expand Down Expand Up @@ -22067,7 +22064,7 @@ void Player::UpdateForQuestWorldObjects()
continue;

if (canSeeSpellClickOn(obj))
obj->BuildCreateUpdateBlockForPlayer(updateData, this);
obj->BuildValuesUpdateBlockForPlayerWithFlags(updateData, this, UF_FLAG_DYNAMIC);
}
}
updateData.SendData(*GetSession());
Expand Down
3 changes: 1 addition & 2 deletions src/game/Entities/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -2166,6 +2166,7 @@ class Player : public Unit
void FillBGWeekendWorldStates(WorldPacket& data, uint32& count) const;

void SendAurasForTarget(Unit* target) const;
static WorldPacket BuildAurasForTarget(Unit const* target);

PlayerMenu* GetPlayerMenu() const { return m_playerMenu.get(); }

Expand Down Expand Up @@ -2942,8 +2943,6 @@ class Player : public Unit
bool m_needsZoneUpdate;
uint32 m_newZone;

uint32 m_DetectInvTimer;

// Temporary removed pet cache
uint32 m_temporaryUnsummonedPetNumber;
uint32 m_BGPetSpell;
Expand Down
8 changes: 8 additions & 0 deletions src/game/Entities/UpdateData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ void UpdateData::AddUpdateBlock(const ByteBuffer& block)
}
}

void UpdateData::AddAfterCreatePacket(const WorldPacket& data)
{
m_afterCreatePacket.emplace_back(data);
}

void UpdateData::Compress(void* dst, uint32* dst_size, void* src, int src_size)
{
z_stream c_stream;
Expand Down Expand Up @@ -173,4 +178,7 @@ void UpdateData::SendData(WorldSession& session)
WorldPacket packet = BuildPacket(i);
session.SendPacket(packet);
}

for (auto& packet : m_afterCreatePacket)
session.SendPacket(packet);
}
3 changes: 3 additions & 0 deletions src/game/Entities/UpdateData.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class UpdateData
void AddOutOfRangeGUID(GuidSet& guids);
void AddOutOfRangeGUID(ObjectGuid const& guid);
void AddUpdateBlock(const ByteBuffer& block);
void AddAfterCreatePacket(const WorldPacket& data);
WorldPacket BuildPacket(size_t index); // Copy Elision is a thing
bool HasData() const { return m_data[0].m_buffer.size() > 0 || !m_outOfRangeGUIDs.empty(); }
size_t GetPacketCount() const { return m_data.size(); }
Expand All @@ -78,6 +79,8 @@ class UpdateData
std::vector<BufferPair> m_data;
uint32 m_currentIndex;

std::vector<WorldPacket> m_afterCreatePacket;

static void Compress(void* dst, uint32* dst_size, void* src, int src_size);
};
#endif
41 changes: 38 additions & 3 deletions src/game/Maps/Map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,11 @@ bool Map::IsUpdateObjectTick() const
return m_clientUpdateTimer >= UPDATE_TICK;
}

bool Map::IsStealthTick() const
{
return IsUpdateObjectTick() && m_clientUpdateTick % 5 == 0;
}

void Map::ChangeGOPathfinding(uint32 entry, uint32 displayId, bool apply)
{
auto tileIds = GameObjectModel::GetTilesForGOEntry(GetId(), entry);
Expand Down Expand Up @@ -754,6 +759,8 @@ void Map::VisitNearbyCellsOf(WorldObject* obj, TypeContainerVisitor<MaNGOS::Obje
void Map::Update(const uint32& t_diff)
{
m_clientUpdateTimer += t_diff;
if (IsUpdateObjectTick())
++m_clientUpdateTick;
#ifdef BUILD_METRICS
metric::duration<std::chrono::milliseconds> meas("map.update", {
{ "map_id", std::to_string(i_id) },
Expand Down Expand Up @@ -1074,10 +1081,9 @@ void Map::Update(const uint32& t_diff)
// Send world objects and item update field changes
if (IsUpdateObjectTick())
{
SendObjectUpdates(m_clientUpdateTick % 3 == 0);
m_clientUpdateTimer -= UPDATE_TICK;
++m_clientUpdateTick;
SendObjectUpdates(m_clientUpdateTick >= 3);
if (m_clientUpdateTick >= 3)
if (m_clientUpdateTick > 30)
m_clientUpdateTick = 0;
}

Expand Down Expand Up @@ -1106,6 +1112,7 @@ void Map::Remove(Player* player, bool remove)
m_objectsToClientUpdate.erase(player);
m_objectsToClientCreateUpdate.erase(player);
m_objectsToClientMovementUpdate.erase(player);
m_visibilityAdded.erase(player);

if (IsRaid())
for (auto& playerRef : GetPlayers())
Expand Down Expand Up @@ -1179,6 +1186,7 @@ void Map::Remove(T* obj, bool remove)
m_objectsToClientUpdate.erase(obj);
m_objectsToClientCreateUpdate.erase(obj);
m_objectsToClientMovementUpdate.erase(obj);
m_visibilityAdded.erase(obj);

if (obj->isActiveObject())
RemoveFromActive(obj);
Expand Down Expand Up @@ -1626,6 +1634,8 @@ void Map::SendInitSelf(Player* player, UpdateData& updateData) const
{
player->AddAtClient(passenger);
passenger->BuildCreateUpdateBlockForPlayer(updateData, player);
if (passenger->IsUnit())
updateData.AddAfterCreatePacket(Player::BuildAurasForTarget(static_cast<Unit const*>(passenger)));
}
}
}
Expand Down Expand Up @@ -2648,6 +2658,26 @@ void Map::SendObjectUpdates(bool movement)
}
}

{
std::unordered_map<Object*, PlayerSet> visibilityAdded;
std::swap(visibilityAdded, m_visibilityAdded);
for (auto& visData : visibilityAdded)
{
for (Player* player : visData.second)
visData.first->BuildCreateDataForPlayer(player, update_players, false);

if (visData.first->IsUnit())
{
WorldPacket packet = Player::BuildAurasForTarget(static_cast<Unit const*>(visData.first));
for (Player* player : visData.second)
{
auto& updateDataData = update_players.find(player); // always exist after previous loop
updateDataData->second.AddAfterCreatePacket(packet);
}
}
}
}

while (!m_objectsToClientUpdate.empty())
{
Object* obj = *m_objectsToClientUpdate.begin();
Expand Down Expand Up @@ -2806,6 +2836,11 @@ void Map::AddUpdateRemoveObject(GuidSet&& visible, ObjectGuid guid)
m_objectsToClientRemove.emplace_back(visible, guid);
}

void Map::AddCreateAtClientObject(Player* player, Object* obj)
{
m_visibilityAdded[obj].insert(player);
}

uint32 Map::GenerateLocalLowGuid(HighGuid guidhigh)
{
// TODO: for map local guid counters possible force reload map instead shutdown server at guid counter overflow
Expand Down
4 changes: 4 additions & 0 deletions src/game/Maps/Map.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,8 @@ class Map : public GridRefManager<NGridType>
void AddUpdateRemoveObject(GuidSet& visible, ObjectGuid guid);
void AddUpdateRemoveObject(GuidSet&& visible, ObjectGuid guid);

void AddCreateAtClientObject(Player* player, Object* obj);

// DynObjects currently
uint32 GenerateLocalLowGuid(HighGuid guidhigh);

Expand Down Expand Up @@ -456,6 +458,7 @@ class Map : public GridRefManager<NGridType>
void AwardLFGRewards(uint32 dungeonId);

bool IsUpdateObjectTick() const;
bool IsStealthTick() const;

private:
void LoadMapAndVMap(int gx, int gy);
Expand Down Expand Up @@ -496,6 +499,7 @@ class Map : public GridRefManager<NGridType>
std::set<Object*> m_objectsToClientCreateUpdate;
std::set<Object*> m_objectsToClientMovementUpdate;
std::vector<std::pair<GuidSet, ObjectGuid>> m_objectsToClientRemove;
std::unordered_map<Object*, PlayerSet> m_visibilityAdded;

protected:
MapEntry const* i_mapEntry;
Expand Down
2 changes: 1 addition & 1 deletion src/game/Spells/SpellAuras.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10193,7 +10193,7 @@ bool SpellAuraHolder::IsNeedVisibleSlot(Unit const* caster) const
return !m_isPassive || totemAura || HasAreaAuraEffect(m_spellProto);
}

void SpellAuraHolder::BuildUpdatePacket(WorldPacket& data) const
void SpellAuraHolder::BuildUpdatePacket(ByteBuffer& data) const
{
data << uint8(GetAuraSlot());
data << uint32(GetId());
Expand Down
Loading

0 comments on commit 7c66ae0

Please sign in to comment.