Core/Objects: Changed how update fields changes are identified, no longer storing old value to compare with new. Instead fields are now simply marked if changed. This means that even if a field changes back to its original value, packet will be sent anyway (client expects it for some fields like shapeshift)

This commit is contained in:
Shauren
2011-08-28 18:31:37 +02:00
parent 8cf3e5536a
commit 8c707a13de
3 changed files with 60 additions and 47 deletions
+59 -41
View File
@@ -69,8 +69,8 @@ Object::Object() : m_PackGUID(sizeof(uint64)+1)
m_objectTypeId = TYPEID_OBJECT; m_objectTypeId = TYPEID_OBJECT;
m_objectType = TYPEMASK_OBJECT; m_objectType = TYPEMASK_OBJECT;
m_uint32Values = 0; m_uint32Values = NULL;
m_uint32Values_mirror = 0; _changedFields = NULL;
m_valuesCount = 0; m_valuesCount = 0;
m_inWorld = false; m_inWorld = false;
@@ -112,17 +112,17 @@ Object::~Object()
} }
delete [] m_uint32Values; delete [] m_uint32Values;
delete [] m_uint32Values_mirror; delete [] _changedFields;
} }
void Object::_InitValues() void Object::_InitValues()
{ {
m_uint32Values = new uint32[ m_valuesCount ]; m_uint32Values = new uint32[m_valuesCount];
memset(m_uint32Values, 0, m_valuesCount*sizeof(uint32)); memset(m_uint32Values, 0, m_valuesCount*sizeof(uint32));
m_uint32Values_mirror = new uint32[ m_valuesCount ]; _changedFields = new bool[m_valuesCount];
memset(m_uint32Values_mirror, 0, m_valuesCount*sizeof(uint32)); memset(_changedFields, 0, sizeof(_changedFields));
m_objectUpdated = false; m_objectUpdated = false;
} }
@@ -750,7 +750,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
void Object::ClearUpdateMask(bool remove) void Object::ClearUpdateMask(bool remove)
{ {
memcpy(m_uint32Values_mirror, m_uint32Values, m_valuesCount*sizeof(uint32)); memset(_changedFields, 0, sizeof(_changedFields));
if (m_objectUpdated) if (m_objectUpdated)
{ {
@@ -774,7 +774,7 @@ void Object::BuildFieldsUpdate(Player* pl, UpdateDataMapType& data_map) const
BuildValuesUpdateBlockForPlayer(&iter->second, iter->first); BuildValuesUpdateBlockForPlayer(&iter->second, iter->first);
} }
void Object::_LoadIntoDataField(const char* data, uint32 startOffset, uint32 count) void Object::_LoadIntoDataField(char const* data, uint32 startOffset, uint32 count)
{ {
if (!data) if (!data)
return; return;
@@ -785,17 +785,19 @@ void Object::_LoadIntoDataField(const char* data, uint32 startOffset, uint32 cou
return; return;
for (uint32 index = 0; index < count; ++index) for (uint32 index = 0; index < count; ++index)
{
m_uint32Values[startOffset + index] = atol(tokens[index]); m_uint32Values[startOffset + index] = atol(tokens[index]);
_changedFields[startOffset + index] = true;
}
} }
void Object::_SetUpdateBits(UpdateMask* updateMask, Player* /*target*/) const void Object::_SetUpdateBits(UpdateMask* updateMask, Player* /*target*/) const
{ {
uint32 *value = m_uint32Values; bool* indexes = _changedFields;
uint32 *mirror = m_uint32Values_mirror;
for (uint16 index = 0; index < m_valuesCount; ++index, ++value, ++mirror) for (uint16 index = 0; index < m_valuesCount; ++index, ++indexes)
{ {
if (*mirror != *value) if (*indexes)
updateMask->SetBit(index); updateMask->SetBit(index);
} }
} }
@@ -815,9 +817,10 @@ void Object::SetInt32Value(uint16 index, int32 value)
{ {
ASSERT(index < m_valuesCount || PrintIndexError(index, true)); ASSERT(index < m_valuesCount || PrintIndexError(index, true));
if (m_int32Values[ index ] != value) if (m_int32Values[index] != value)
{ {
m_int32Values[ index ] = value; m_int32Values[index] = value;
_changedFields[index] = true;
if (m_inWorld) if (m_inWorld)
{ {
@@ -834,9 +837,10 @@ void Object::SetUInt32Value(uint16 index, uint32 value)
{ {
ASSERT(index < m_valuesCount || PrintIndexError(index, true)); ASSERT(index < m_valuesCount || PrintIndexError(index, true));
if (m_uint32Values[ index ] != value) if (m_uint32Values[index] != value)
{ {
m_uint32Values[ index ] = value; m_uint32Values[index] = value;
_changedFields[index] = true;
if (m_inWorld) if (m_inWorld)
{ {
@@ -853,16 +857,19 @@ void Object::UpdateUInt32Value(uint16 index, uint32 value)
{ {
ASSERT(index < m_valuesCount || PrintIndexError(index, true)); ASSERT(index < m_valuesCount || PrintIndexError(index, true));
m_uint32Values[ index ] = value; m_uint32Values[index] = value;
_changedFields[index] = true;
} }
void Object::SetUInt64Value(uint16 index, uint64 const value) void Object::SetUInt64Value(uint16 index, uint64 const value)
{ {
ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, true)); ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, true));
if (*((uint64*)&(m_uint32Values[ index ])) != value) if (*((uint64*)&(m_uint32Values[index])) != value)
{ {
m_uint32Values[ index ] = *((uint32*)&value); m_uint32Values[index] = *((uint32*)&value);
m_uint32Values[ index + 1 ] = *(((uint32*)&value) + 1); m_uint32Values[index + 1] = *(((uint32*)&value) + 1);
_changedFields[index] = true;
_changedFields[index + 1] = true;
if (m_inWorld) if (m_inWorld)
{ {
@@ -880,8 +887,10 @@ bool Object::AddUInt64Value(uint16 index, uint64 const value)
ASSERT(index + 1 < m_valuesCount || PrintIndexError(index , true)); ASSERT(index + 1 < m_valuesCount || PrintIndexError(index , true));
if (value && !*((uint64*)&(m_uint32Values[index]))) if (value && !*((uint64*)&(m_uint32Values[index])))
{ {
m_uint32Values[ index ] = *((uint32*)&value); m_uint32Values[index] = *((uint32*)&value);
m_uint32Values[ index + 1 ] = *(((uint32*)&value) + 1); m_uint32Values[index + 1] = *(((uint32*)&value) + 1);
_changedFields[index] = true;
_changedFields[index + 1] = true;
if (m_inWorld) if (m_inWorld)
{ {
@@ -901,8 +910,10 @@ bool Object::RemoveUInt64Value(uint16 index, const uint64 value)
ASSERT(index + 1 < m_valuesCount || PrintIndexError(index , true)); ASSERT(index + 1 < m_valuesCount || PrintIndexError(index , true));
if (value && *((uint64*)&(m_uint32Values[index])) == value) if (value && *((uint64*)&(m_uint32Values[index])) == value)
{ {
m_uint32Values[ index ] = 0; m_uint32Values[index] = 0;
m_uint32Values[ index + 1 ] = 0; m_uint32Values[index + 1] = 0;
_changedFields[index] = true;
_changedFields[index + 1] = true;
if (m_inWorld) if (m_inWorld)
{ {
@@ -923,9 +934,10 @@ void Object::SetFloatValue(uint16 index, float value)
{ {
ASSERT(index < m_valuesCount || PrintIndexError(index, true)); ASSERT(index < m_valuesCount || PrintIndexError(index, true));
if (m_floatValues[ index ] != value) if (m_floatValues[index] != value)
{ {
m_floatValues[ index ] = value; m_floatValues[index] = value;
_changedFields[index] = true;
if (m_inWorld) if (m_inWorld)
{ {
@@ -948,10 +960,11 @@ void Object::SetByteValue(uint16 index, uint8 offset, uint8 value)
return; return;
} }
if (uint8(m_uint32Values[ index ] >> (offset * 8)) != value) if (uint8(m_uint32Values[index] >> (offset * 8)) != value)
{ {
m_uint32Values[ index ] &= ~uint32(uint32(0xFF) << (offset * 8)); m_uint32Values[index] &= ~uint32(uint32(0xFF) << (offset * 8));
m_uint32Values[ index ] |= uint32(uint32(value) << (offset * 8)); m_uint32Values[index] |= uint32(uint32(value) << (offset * 8));
_changedFields[index] = true;
if (m_inWorld) if (m_inWorld)
{ {
@@ -974,10 +987,11 @@ void Object::SetUInt16Value(uint16 index, uint8 offset, uint16 value)
return; return;
} }
if (uint16(m_uint32Values[ index ] >> (offset * 16)) != value) if (uint16(m_uint32Values[index] >> (offset * 16)) != value)
{ {
m_uint32Values[ index ] &= ~uint32(uint32(0xFFFF) << (offset * 16)); m_uint32Values[index] &= ~uint32(uint32(0xFFFF) << (offset * 16));
m_uint32Values[ index ] |= uint32(uint32(value) << (offset * 16)); m_uint32Values[index] |= uint32(uint32(value) << (offset * 16));
_changedFields[index] = true;
if (m_inWorld) if (m_inWorld)
{ {
@@ -1041,12 +1055,13 @@ void Object::ApplyModPositiveFloatValue(uint16 index, float val, bool apply)
void Object::SetFlag(uint16 index, uint32 newFlag) void Object::SetFlag(uint16 index, uint32 newFlag)
{ {
ASSERT(index < m_valuesCount || PrintIndexError(index, true)); ASSERT(index < m_valuesCount || PrintIndexError(index, true));
uint32 oldval = m_uint32Values[ index ]; uint32 oldval = m_uint32Values[index];
uint32 newval = oldval | newFlag; uint32 newval = oldval | newFlag;
if (oldval != newval) if (oldval != newval)
{ {
m_uint32Values[ index ] = newval; m_uint32Values[index] = newval;
_changedFields[index] = true;
if (m_inWorld) if (m_inWorld)
{ {
@@ -1064,12 +1079,13 @@ void Object::RemoveFlag(uint16 index, uint32 oldFlag)
ASSERT(index < m_valuesCount || PrintIndexError(index, true)); ASSERT(index < m_valuesCount || PrintIndexError(index, true));
ASSERT(m_uint32Values); ASSERT(m_uint32Values);
uint32 oldval = m_uint32Values[ index ]; uint32 oldval = m_uint32Values[index];
uint32 newval = oldval & ~oldFlag; uint32 newval = oldval & ~oldFlag;
if (oldval != newval) if (oldval != newval)
{ {
m_uint32Values[ index ] = newval; m_uint32Values[index] = newval;
_changedFields[index] = true;
if (m_inWorld) if (m_inWorld)
{ {
@@ -1092,9 +1108,10 @@ void Object::SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
return; return;
} }
if (!(uint8(m_uint32Values[ index ] >> (offset * 8)) & newFlag)) if (!(uint8(m_uint32Values[index] >> (offset * 8)) & newFlag))
{ {
m_uint32Values[ index ] |= uint32(uint32(newFlag) << (offset * 8)); m_uint32Values[index] |= uint32(uint32(newFlag) << (offset * 8));
_changedFields[index] = true;
if (m_inWorld) if (m_inWorld)
{ {
@@ -1117,9 +1134,10 @@ void Object::RemoveByteFlag(uint16 index, uint8 offset, uint8 oldFlag)
return; return;
} }
if (uint8(m_uint32Values[ index ] >> (offset * 8)) & oldFlag) if (uint8(m_uint32Values[index] >> (offset * 8)) & oldFlag)
{ {
m_uint32Values[ index ] &= ~uint32(uint32(oldFlag) << (offset * 8)); m_uint32Values[index] &= ~uint32(uint32(oldFlag) << (offset * 8));
_changedFields[index] = true;
if (m_inWorld) if (m_inWorld)
{ {
@@ -1821,7 +1839,7 @@ void WorldObject::SendPlaySound(uint32 Sound, bool OnlySelf)
void Object::ForceValuesUpdateAtIndex(uint32 i) void Object::ForceValuesUpdateAtIndex(uint32 i)
{ {
m_uint32Values_mirror[i] = GetUInt32Value(i) + 1; // makes server think the field changed _changedFields[i] = true;
if (m_inWorld) if (m_inWorld)
{ {
if (!m_objectUpdated) if (!m_objectUpdated)
+1 -1
View File
@@ -358,7 +358,7 @@ class Object
float *m_floatValues; float *m_floatValues;
}; };
uint32 *m_uint32Values_mirror; bool* _changedFields;
uint16 m_valuesCount; uint16 m_valuesCount;
-5
View File
@@ -1866,11 +1866,6 @@ class Unit : public WorldObject
void SetShapeshiftForm(ShapeshiftForm form) void SetShapeshiftForm(ShapeshiftForm form)
{ {
SetByteValue(UNIT_FIELD_BYTES_2, 3, form); SetByteValue(UNIT_FIELD_BYTES_2, 3, form);
// force update as too quick shapeshifting and back
// causes the value to stay the same serverside
// causes issues clientside (player gets stuck)
ForceValuesUpdateAtIndex(UNIT_FIELD_BYTES_2);
} }
inline bool IsInFeralForm() const inline bool IsInFeralForm() const