Skip to content

Commit

Permalink
[8677] Move most client update data functions to object itself from O…
Browse files Browse the repository at this point in the history
…bjectAccessor.

Also use virtual function BuildUpdateData (old ObjectAccessor::_buildUpdateObject)
that different for world objects and items.
  • Loading branch information
VladimirMangos committed Oct 19, 2009
1 parent 9c50d9e commit a94d615
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 79 deletions.
8 changes: 8 additions & 0 deletions src/game/Item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -996,6 +996,14 @@ bool Item::IsBindedNotWith( Player const* player ) const
}
}

void Item::BuildUpdateData(UpdateDataMapType& update_players)
{
if (Player* pl = GetOwner())
BuildUpdateDataForPlayer(pl, update_players);

ClearUpdateMask(false);
}

bool ItemRequiredTarget::IsFitToRequirements( Unit* pUnitTarget ) const
{
if(pUnitTarget->GetTypeId() != TYPEID_UNIT)
Expand Down
1 change: 1 addition & 0 deletions src/game/Item.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ class MANGOS_DLL_SPEC Item : public Object
bool IsPotion() const { return GetProto()->IsPotion(); }
bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); }

void BuildUpdateData(UpdateDataMapType& update_players);
private:
uint8 m_slot;
Bag *m_container;
Expand Down
56 changes: 50 additions & 6 deletions src/game/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ void Object::BuildMovementUpdateBlock(UpdateData * data, uint32 flags ) const
buf << uint8( UPDATETYPE_MOVEMENT );
buf.append(GetPackGUID());

_BuildMovementUpdate(&buf, flags, 0x00000000);
BuildMovementUpdate(&buf, flags, 0x00000000);

data->AddUpdateBlock(buf);
}
Expand Down Expand Up @@ -189,12 +189,12 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c
buf.append(GetPackGUID());
buf << (uint8)m_objectTypeId;

_BuildMovementUpdate(&buf, flags, flags2);
BuildMovementUpdate(&buf, flags, flags2);

UpdateMask updateMask;
updateMask.SetCount( m_valuesCount );
_SetCreateBits( &updateMask, target );
_BuildValuesUpdate(updatetype, &buf, &updateMask, target);
BuildValuesUpdate(updatetype, &buf, &updateMask, target);
data->AddUpdateBlock(buf);
}

Expand All @@ -220,7 +220,7 @@ void Object::BuildValuesUpdateBlockForPlayer(UpdateData *data, Player *target) c
updateMask.SetCount( m_valuesCount );

_SetUpdateBits( &updateMask, target );
_BuildValuesUpdate(UPDATETYPE_VALUES, &buf, &updateMask, target);
BuildValuesUpdate(UPDATETYPE_VALUES, &buf, &updateMask, target);

data->AddUpdateBlock(buf);
}
Expand All @@ -240,7 +240,7 @@ void Object::DestroyForPlayer( Player *target, bool anim ) const
target->GetSession()->SendPacket( &data );
}

void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2) const
void Object::BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2) const
{
uint16 unk_flags = ((GetTypeId() == TYPEID_PLAYER) ? ((Player*)this)->m_movementInfo.unk1 : 0);

Expand Down Expand Up @@ -567,7 +567,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2
}
}

void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *updateMask, Player *target) const
void Object::BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *updateMask, Player *target) const
{
if(!target)
return;
Expand Down Expand Up @@ -1065,6 +1065,20 @@ bool Object::PrintIndexError(uint32 index, bool set) const
return false;
}

void Object::BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_players)
{
UpdateDataMapType::iterator iter = update_players.find(pl);

if (iter == update_players.end())
{
std::pair<UpdateDataMapType::iterator, bool> p = update_players.insert( UpdateDataMapType::value_type(pl, UpdateData()) );
assert(p.second);
iter = p.first;
}

BuildValuesUpdateBlockForPlayer(&iter->second, iter->first);
}

WorldObject::WorldObject()
: m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL),
m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f), m_currMap(NULL)
Expand Down Expand Up @@ -1857,3 +1871,33 @@ void WorldObject::UpdateObjectVisibility()
GetMap()->UpdateObjectVisibility(this, cell, p);
}

struct WorldObjectChangeAccumulator
{
UpdateDataMapType &i_updateDatas;
WorldObject &i_object;
WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) {}
void Visit(PlayerMapType &m)
{
for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
if(iter->getSource()->HaveAtClient(&i_object))
i_object.BuildUpdateDataForPlayer(iter->getSource(), i_updateDatas);
}

template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
};

void WorldObject::BuildUpdateData( UpdateDataMapType & update_players)
{
CellPair p = MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY());
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
WorldObjectChangeAccumulator notifier(*this, update_players);
TypeContainerVisitor<WorldObjectChangeAccumulator, WorldTypeMapContainer > player_notifier(notifier);
CellLock<GridReadGuard> cell_lock(cell, p);
Map* aMap = GetMap();
//we must build packets for all visible players
cell_lock->Visit(cell_lock, player_notifier, *aMap, *this, aMap->GetVisibilityDistance());

ClearUpdateMask(false);
}
16 changes: 12 additions & 4 deletions src/game/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ class MANGOS_DLL_SPEC Object
virtual void BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
void SendCreateUpdateToPlayer(Player* player);

virtual void BuildUpdateData(UpdateDataMapType& update_players) =0;
void BuildValuesUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
void BuildOutOfRangeUpdateBlock( UpdateData *data ) const;
void BuildMovementUpdateBlock( UpdateData * data, uint32 flags = 0 ) const;
Expand Down Expand Up @@ -307,8 +308,9 @@ class MANGOS_DLL_SPEC Object
virtual void _SetUpdateBits(UpdateMask *updateMask, Player *target) const;

virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
void _BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2 ) const;
void _BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const;
void BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2 ) const;
void BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const;
void BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_players);

uint16 m_objectType;

Expand Down Expand Up @@ -339,8 +341,12 @@ class MANGOS_DLL_SPEC Object
Object& operator=(Object const&); // prevent generation assigment operator
};

struct WorldObjectChangeAccumulator;

class MANGOS_DLL_SPEC WorldObject : public Object
{
friend struct WorldObjectChangeAccumulator;

public:
virtual ~WorldObject ( ) {}

Expand Down Expand Up @@ -488,18 +494,20 @@ class MANGOS_DLL_SPEC WorldObject : public Object
//this function should be removed in nearest time...
Map const* GetBaseMap() const;

Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
void BuildUpdateData(UpdateDataMapType &);

Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
protected:
explicit WorldObject();
std::string m_name;

//these functions are used mostly for Relocate() and Corpse/Player specific stuff...
//use them ONLY in LoadFromDB()/Create() funcs and nowhere else!
//mapId/instanceId should be set in SetMap() function!
void SetLocationMapId(uint32 _mapId) { m_mapId = _mapId; }
void SetLocationInstanceId(uint32 _instanceId) { m_InstanceId = _instanceId; }

std::string m_name;

private:
Map * m_currMap; //current object's Map location

Expand Down
54 changes: 1 addition & 53 deletions src/game/ObjectAccessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,49 +182,6 @@ ObjectAccessor::SaveAllPlayers()
itr->second->SaveToDB();
}

void
ObjectAccessor::_buildUpdateObject(Object *obj, UpdateDataMapType &update_players)
{
if(obj->isType(TYPEMASK_ITEM))
{
Item *item = static_cast<Item *>(obj);
if (Player* pl = item->GetOwner())
_buildPacket(pl, obj, update_players);
}
else
_buildChangeObjectForPlayer(static_cast<WorldObject*>(obj), update_players);
}

void
ObjectAccessor::_buildPacket(Player *pl, Object *obj, UpdateDataMapType &update_players)
{
UpdateDataMapType::iterator iter = update_players.find(pl);

if( iter == update_players.end() )
{
std::pair<UpdateDataMapType::iterator, bool> p = update_players.insert( UpdateDataValueType(pl, UpdateData()) );
assert(p.second);
iter = p.first;
}

obj->BuildValuesUpdateBlockForPlayer(&iter->second, iter->first);
}

void
ObjectAccessor::_buildChangeObjectForPlayer(WorldObject *obj, UpdateDataMapType &update_players)
{
CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
WorldObjectChangeAccumulator notifier(*obj, update_players);
TypeContainerVisitor<WorldObjectChangeAccumulator, WorldTypeMapContainer > player_notifier(notifier);
CellLock<GridReadGuard> cell_lock(cell, p);
Map& map = *obj->GetMap();
//we must build packets for all visible players
cell_lock->Visit(cell_lock, player_notifier, map, *obj, map.GetVisibilityDistance());
}

Pet*
ObjectAccessor::GetPet(uint64 guid)
{
Expand Down Expand Up @@ -386,8 +343,7 @@ ObjectAccessor::Update(uint32 diff)
i_objects.erase(i_objects.begin());
if (!obj)
continue;
_buildUpdateObject(obj, update_players);
obj->ClearUpdateMask(false);
obj->BuildUpdateData(update_players);
}
}

Expand All @@ -400,14 +356,6 @@ ObjectAccessor::Update(uint32 diff)
}
}

void
ObjectAccessor::WorldObjectChangeAccumulator::Visit(PlayerMapType &m)
{
for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
if(iter->getSource()->HaveAtClient(&i_object))
ObjectAccessor::_buildPacket(iter->getSource(), &i_object, i_updateDatas);
}

/// Define the static member of HashMapHolder

template <class T> UNORDERED_MAP< uint64, T* > HashMapHolder<T>::m_objectMap;
Expand Down
15 changes: 0 additions & 15 deletions src/game/ObjectAccessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,

public:
typedef UNORDERED_MAP<uint64, Corpse* > Player2CorpsesMapType;
typedef UNORDERED_MAP<Player*, UpdateData>::value_type UpdateDataValueType;

template<class T> static T* GetObjectInWorld(uint64 guid, T* /*fake*/)
{
Expand Down Expand Up @@ -180,21 +179,10 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map);
Corpse* ConvertCorpseForPlayer(uint64 player_guid, bool insignia = false);

static void _buildUpdateObject(Object* obj, UpdateDataMapType &);

// TODO: This methods will need lock in MT environment
static void LinkMap(Map* map) { i_mapList.push_back(map); }
static void DelinkMap(Map* map) { i_mapList.remove(map); }
private:
struct WorldObjectChangeAccumulator
{
UpdateDataMapType &i_updateDatas;
WorldObject &i_object;
WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) {}
void Visit(PlayerMapType &);
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
};

// TODO: This methods will need lock in MT environment
// Theoreticaly multiple threads can enter and search in this method but
// in that case linking/delinking other map should be guarded
Expand All @@ -213,14 +201,11 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,

static std::list<Map*> i_mapList;

friend struct WorldObjectChangeAccumulator;
Player2CorpsesMapType i_player2corpse;

typedef ACE_Thread_Mutex LockType;
typedef MaNGOS::GeneralLock<LockType > Guard;

static void _buildChangeObjectForPlayer(WorldObject *, UpdateDataMapType &);
static void _buildPacket(Player *, Object *, UpdateDataMapType &);
std::set<Object *> i_objects;
LockType i_playerGuard;
LockType i_updateGuard;
Expand Down
2 changes: 1 addition & 1 deletion src/shared/revision_nr.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8676"
#define REVISION_NR "8677"
#endif // __REVISION_NR_H__

3 comments on commit a94d615

@waza123
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

На [8677] перестал работать респаун игроков на тех же бг.

@VladimirMangos
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specific commit can't affect any server side functionality: it only affect client side show.
BUT: ofc it not expected using totally wrong mtmopa patch and similar. If someone use then this his personal problem. ;)

@VladimirMangos
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for add: code itself not expected any functionality changes: this mostly just move code from onw class to another

Please sign in to comment.