Skip to content

Commit

Permalink
Core/Object: Use updatefield flags extracted from client to determine…
Browse files Browse the repository at this point in the history
… whether to send or not a field value instead of sending all data to client for non-player objects
  • Loading branch information
Shauren committed Jul 22, 2012
1 parent 395994c commit 1fd37ac
Show file tree
Hide file tree
Showing 12 changed files with 1,791 additions and 177 deletions.
100 changes: 82 additions & 18 deletions src/server/game/Entities/Object/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "SpellAuraEffects.h"

#include "UpdateFieldFlags.h"
#include "TemporarySummon.h"
#include "Totem.h"
#include "OutdoorPvPMgr.h"
#include "MovementPacketBuilder.h"
#include "DynamicTree.h"
#include "Group.h"

uint32 GuidHigh2TypeId(uint32 guid_hi)
{
Expand Down Expand Up @@ -74,6 +75,7 @@ Object::Object() : m_PackGUID(sizeof(uint64)+1)
m_uint32Values = NULL;
_changedFields = NULL;
m_valuesCount = 0;
_fieldNotifyFlags = UF_FLAG_DYNAMIC;

m_inWorld = false;
m_objectUpdated = false;
Expand Down Expand Up @@ -463,28 +465,22 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask*
if (((GameObject*)this)->ActivateToQuest(target) || target->isGameMaster())
IsActivateToQuest = true;

updateMask->SetBit(GAMEOBJECT_DYNAMIC);

if (((GameObject*)this)->GetGoArtKit())
updateMask->SetBit(GAMEOBJECT_BYTES_1);
}
else if (isType(TYPEMASK_UNIT))
{
if (((Unit*)this)->HasFlag(UNIT_FIELD_AURASTATE, PER_CASTER_AURA_STATE_MASK))
{
updateMask->SetBit(UNIT_FIELD_AURASTATE);
}
}
}
else // case UPDATETYPE_VALUES
{
if (isType(TYPEMASK_GAMEOBJECT) && !((GameObject*)this)->IsTransport())
{
if (((GameObject*)this)->ActivateToQuest(target) || target->isGameMaster())
{
IsActivateToQuest = true;
}
updateMask->SetBit(GAMEOBJECT_DYNAMIC);

updateMask->SetBit(GAMEOBJECT_BYTES_1);

if (ToGameObject()->GetGoType() == GAMEOBJECT_TYPE_CHEST && ToGameObject()->GetGOInfo()->chest.groupLootRules &&
Expand All @@ -494,9 +490,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask*
else if (isType(TYPEMASK_UNIT))
{
if (((Unit*)this)->HasFlag(UNIT_FIELD_AURASTATE, PER_CASTER_AURA_STATE_MASK))
{
updateMask->SetBit(UNIT_FIELD_AURASTATE);
}
}
}

Expand Down Expand Up @@ -788,26 +782,96 @@ void Object::_LoadIntoDataField(char const* data, uint32 startOffset, uint32 cou
}
}

void Object::_SetUpdateBits(UpdateMask* updateMask, Player* /*target*/) const
void Object::GetUpdateFieldData(Player const* target, uint32*& flags, bool& isOwner, bool& isItemOwner, bool& hasSpecialInfo, bool& isPartyMember) const
{
// This function assumes updatefield index is always valid
switch (GetTypeId())
{
case TYPEID_ITEM:
case TYPEID_CONTAINER:
flags = ItemUpdateFieldFlags;
isOwner = isItemOwner = ((Item*)this)->GetOwnerGUID() == target->GetGUID();
break;
case TYPEID_UNIT:
case TYPEID_PLAYER:
{
Player* plr = ToUnit()->GetCharmerOrOwnerPlayerOrPlayerItself();
flags = UnitUpdateFieldFlags;
isOwner = ToUnit()->GetOwnerGUID() == target->GetGUID();
hasSpecialInfo = ToUnit()->HasAuraTypeWithCaster(SPELL_AURA_EMPATHY, target->GetGUID());
isPartyMember = plr && plr->IsInSameGroupWith(target);
break;
}
case TYPEID_GAMEOBJECT:
flags = GameObjectUpdateFieldFlags;
isOwner = ToGameObject()->GetOwnerGUID() == target->GetGUID();
break;
case TYPEID_DYNAMICOBJECT:
flags = DynamicObjectUpdateFieldFlags;
isOwner = ((DynamicObject*)this)->GetCasterGUID() == target->GetGUID();
break;
case TYPEID_CORPSE:
flags = CorpseUpdateFieldFlags;
isOwner = ToCorpse()->GetOwnerGUID() == target->GetGUID();
break;
}
}

bool Object::IsUpdateFieldVisible(uint32 flags, bool isSelf, bool isOwner, bool isItemOwner, bool isPartyMember) const
{
if (flags == UF_FLAG_NONE)
return false;

if (flags & UF_FLAG_PUBLIC)
return true;

if (flags & UF_FLAG_PRIVATE && isSelf)
return true;

if (flags & UF_FLAG_OWNER && isOwner)
return true;

if (flags & UF_FLAG_ITEM_OWNER && isItemOwner)
return true;

if (flags & UF_FLAG_PARTY_MEMBER && isPartyMember)
return true;

return false;
}

void Object::_SetUpdateBits(UpdateMask* updateMask, Player* target) const
{
bool* indexes = _changedFields;
uint32* flags = NULL;
bool isSelf = target == this;
bool isOwner = false;
bool isItemOwner = false;
bool hasSpecialInfo = false;
bool isPartyMember = false;

GetUpdateFieldData(target, flags, isOwner, isItemOwner, hasSpecialInfo, isPartyMember);

for (uint16 index = 0; index < m_valuesCount; ++index, ++indexes)
{
if (*indexes)
if (_fieldNotifyFlags & flags[index] || (flags[index] & UF_FLAG_SPECIAL_INFO && hasSpecialInfo) || (*indexes && IsUpdateFieldVisible(flags[index], isSelf, isOwner, isItemOwner, isPartyMember)))
updateMask->SetBit(index);
}
}

void Object::_SetCreateBits(UpdateMask* updateMask, Player* /*target*/) const
void Object::_SetCreateBits(UpdateMask* updateMask, Player* target) const
{
uint32* value = m_uint32Values;
uint32* flags = NULL;
bool isSelf = target == this;
bool isOwner = false;
bool isItemOwner = false;
bool hasSpecialInfo = false;
bool isPartyMember = false;

GetUpdateFieldData(target, flags, isOwner, isItemOwner, hasSpecialInfo, isPartyMember);

for (uint16 index = 0; index < m_valuesCount; ++index, ++value)
{
if (*value)
if (_fieldNotifyFlags & flags[index] || (flags[index] & UF_FLAG_SPECIAL_INFO && hasSpecialInfo) || (*value && IsUpdateFieldVisible(flags[index], isSelf, isOwner, isItemOwner, isPartyMember)))
updateMask->SetBit(index);
}
}

void Object::SetInt32Value(uint16 index, int32 value)
Expand Down
14 changes: 11 additions & 3 deletions src/server/game/Entities/Object/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,9 @@ class Object
virtual void BuildUpdate(UpdateDataMapType&) {}
void BuildFieldsUpdate(Player*, UpdateDataMapType &) const;

void SetFieldNotifyFlag(uint16 flag) { _fieldNotifyFlags |= flag; }
void RemoveFieldNotifyFlag(uint16 flag) { _fieldNotifyFlags &= ~flag; }

// FG: some hacky helpers
void ForceValuesUpdateAtIndex(uint32);

Expand All @@ -320,13 +323,16 @@ class Object
Object();

void _InitValues();
void _Create (uint32 guidlow, uint32 entry, HighGuid guidhigh);
void _Create(uint32 guidlow, uint32 entry, HighGuid guidhigh);
std::string _ConcatFields(uint16 startIndex, uint16 size) const;
void _LoadIntoDataField(const char* data, uint32 startOffset, uint32 count);

virtual void _SetUpdateBits(UpdateMask* updateMask, Player* target) const;
void GetUpdateFieldData(Player const* target, uint32*& flags, bool& isOwner, bool& isItemOwner, bool& hasSpecialInfo, bool& isPartyMember) const;

bool IsUpdateFieldVisible(uint32 flags, bool isSelf, bool isOwner, bool isItemOwner, bool isPartyMember) const;

virtual void _SetCreateBits(UpdateMask* updateMask, Player* target) const;
void _SetUpdateBits(UpdateMask* updateMask, Player* target) const;
void _SetCreateBits(UpdateMask* updateMask, Player* target) const;
void _BuildMovementUpdate(ByteBuffer * data, uint16 flags) const;
void _BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask* updateMask, Player* target) const;

Expand All @@ -346,6 +352,8 @@ class Object

uint16 m_valuesCount;

uint16 _fieldNotifyFlags;

bool m_objectUpdated;

private:
Expand Down

2 comments on commit 1fd37ac

@delro92
Copy link

Choose a reason for hiding this comment

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

this should slightly reduce bandwith usage right?

@telsamat
Copy link

Choose a reason for hiding this comment

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

this commit mabye made client crash #7680 (comment)

Please sign in to comment.