Core/PacketIO: Fixed dynamic updatefield handling when values get removed

This commit is contained in:
Shauren
2016-07-13 00:07:09 +02:00
parent cb803e58ff
commit db85bad1ff
3 changed files with 30 additions and 7 deletions

View File

@@ -1145,7 +1145,10 @@ void Item::BuildDynamicValuesUpdate(uint8 updateType, ByteBuffer* data, Player*
UpdateMask::SetUpdateBit(data->contents() + maskPos, index);
std::size_t arrayBlockCount = UpdateMask::GetBlockCount(values.size());
*data << uint8(arrayBlockCount);
*data << uint8(UpdateMask::EncodeDynamicFieldChangeType(arrayBlockCount, _dynamicChangesMask[index], updateType));
if (_dynamicChangesMask[index] == UpdateMask::VALUE_AND_SIZE_CHANGED && updateType == UPDATETYPE_VALUES)
*data << uint16(values.size());
std::size_t arrayMaskPos = data->wpos();
data->resize(data->size() + arrayBlockCount * sizeof(UpdateMask::BlockType));
if (index != ITEM_DYNAMIC_FIELD_MODIFIERS)
@@ -1158,13 +1161,13 @@ void Item::BuildDynamicValuesUpdate(uint8 updateType, ByteBuffer* data, Player*
*data << uint32(values[v]);
}
}
}
else
{
// in case of ITEM_DYNAMIC_FIELD_MODIFIERS it is ITEM_FIELD_MODIFIERS_MASK that controls index of each value, not updatemask
// so we just have to write this starting from 0 index
for (std::size_t v = 0, m = 0; v < values.size(); ++v)
uint16 m = 0;
for (std::size_t v = 0; v < values.size(); ++v)
{
if (values[v])
{
@@ -1173,6 +1176,8 @@ void Item::BuildDynamicValuesUpdate(uint8 updateType, ByteBuffer* data, Player*
}
}
if (_changesMask[ITEM_FIELD_MODIFIERS_MASK] && updateType == UPDATETYPE_VALUES)
data->put(arrayMaskPos - sizeof(m), m);
}
}
}

View File

@@ -793,7 +793,10 @@ void Object::BuildDynamicValuesUpdate(uint8 updateType, ByteBuffer* data, Player
UpdateMask::SetUpdateBit(data->contents() + maskPos, index);
std::size_t arrayBlockCount = UpdateMask::GetBlockCount(values.size());
*data << uint8(arrayBlockCount);
*data << uint8(UpdateMask::EncodeDynamicFieldChangeType(arrayBlockCount, _dynamicChangesMask[index], updateType));
if (_dynamicChangesMask[index] == UpdateMask::VALUE_AND_SIZE_CHANGED && updateType == UPDATETYPE_VALUES)
*data << uint16(values.size());
std::size_t arrayMaskPos = data->wpos();
data->resize(data->size() + arrayBlockCount * sizeof(UpdateMask::BlockType));
for (std::size_t v = 0; v < values.size(); ++v)
@@ -1359,7 +1362,7 @@ void Object::ClearDynamicValue(uint16 index)
if (!_dynamicValues[index].empty())
{
_dynamicValues[index].clear();
_dynamicChangesMask[index] = 1;
_dynamicChangesMask[index] = UpdateMask::VALUE_AND_SIZE_CHANGED;
_dynamicChangesArrayMask[index].clear();
AddToObjectUpdateIfNeeded();
@@ -1370,9 +1373,13 @@ void Object::SetDynamicValue(uint16 index, uint8 offset, uint32 value)
{
ASSERT(index < _dynamicValuesCount || PrintIndexError(index, false));
UpdateMask::DynamicFieldChangeType changeType = UpdateMask::VALUE_CHANGED;
std::vector<uint32>& values = _dynamicValues[index];
if (values.size() <= offset)
{
values.resize(offset + 1);
changeType = UpdateMask::VALUE_AND_SIZE_CHANGED;
}
if (_dynamicChangesArrayMask[index].size() <= offset)
_dynamicChangesArrayMask[index].resize((offset / 32 + 1) * 32);
@@ -1380,7 +1387,7 @@ void Object::SetDynamicValue(uint16 index, uint8 offset, uint32 value)
if (values[offset] != value)
{
values[offset] = value;
_dynamicChangesMask[index] = 1;
_dynamicChangesMask[index] = changeType;
_dynamicChangesArrayMask[index][offset] = 1;
AddToObjectUpdateIfNeeded();

View File

@@ -96,12 +96,23 @@ namespace UpdateMask
{
typedef uint32 BlockType;
enum DynamicFieldChangeType : uint8
{
VALUE_CHANGED = 0x7F,
VALUE_AND_SIZE_CHANGED = 0x80
};
inline std::size_t GetBlockCount(std::size_t bitCount)
{
using BitsPerBlock = std::integral_constant<std::size_t, sizeof(BlockType) * 8>;
return (bitCount + BitsPerBlock::value - 1) / BitsPerBlock::value;
}
inline std::size_t EncodeDynamicFieldChangeType(std::size_t blockCount, DynamicFieldChangeType changeType, uint8 updateType)
{
return blockCount | ((changeType & VALUE_AND_SIZE_CHANGED) * (3 - updateType /*this part evaluates to 0 if update type is not VALUES*/));
}
template<typename T>
inline void SetUpdateBit(T* data, std::size_t bitIndex)
{
@@ -259,7 +270,7 @@ class TC_GAME_API Object
std::vector<uint32>* _dynamicValues;
std::vector<uint8> _changesMask;
std::vector<uint8> _dynamicChangesMask;
std::vector<UpdateMask::DynamicFieldChangeType> _dynamicChangesMask;
std::vector<uint8>* _dynamicChangesArrayMask;
uint16 m_valuesCount;