[General] Rework PlayerAttribute packets so they are of minimal size

Previously, whenever a single attribute value changed for a player, that player then sent a PlayerAttribute packet with all values for all 8 attributes.

This did not cause anywhere as much packet spam as PlayerSkill used to, but there was no good reason not to fix it as well.

(cherry picked from commit b0965f094a)
0.6.3
David Cernat 7 years ago
parent 78441c769a
commit b6099024df

@ -408,6 +408,10 @@ void StatsFunctions::SetAttributeBase(unsigned short pid, unsigned short attribu
return; return;
player->creatureStats.mAttributes[attributeId].mBase = value; player->creatureStats.mAttributes[attributeId].mBase = value;
if (std::find(player->attributeChanges.attributeIndexes.begin(), player->attributeChanges.attributeIndexes.end(), attributeId) ==
player->attributeChanges.attributeIndexes.end())
player->attributeChanges.attributeIndexes.push_back(attributeId);
} }
void StatsFunctions::ClearAttributeModifier(unsigned short pid, unsigned short attributeId) noexcept void StatsFunctions::ClearAttributeModifier(unsigned short pid, unsigned short attributeId) noexcept
@ -419,6 +423,10 @@ void StatsFunctions::ClearAttributeModifier(unsigned short pid, unsigned short a
return; return;
player->creatureStats.mAttributes[attributeId].mMod = 0; player->creatureStats.mAttributes[attributeId].mMod = 0;
if (std::find(player->attributeChanges.attributeIndexes.begin(), player->attributeChanges.attributeIndexes.end(), attributeId) ==
player->attributeChanges.attributeIndexes.end())
player->attributeChanges.attributeIndexes.push_back(attributeId);
} }
void StatsFunctions::SetSkillBase(unsigned short pid, unsigned short skillId, int value) noexcept void StatsFunctions::SetSkillBase(unsigned short pid, unsigned short skillId, int value) noexcept
@ -469,6 +477,10 @@ void StatsFunctions::SetSkillIncrease(unsigned short pid, unsigned int attribute
return; return;
player->npcStats.mSkillIncrease[attributeId] = value; player->npcStats.mSkillIncrease[attributeId] = value;
if (std::find(player->attributeChanges.attributeIndexes.begin(), player->attributeChanges.attributeIndexes.end(), attributeId) ==
player->attributeChanges.attributeIndexes.end())
player->attributeChanges.attributeIndexes.push_back(attributeId);
} }
void StatsFunctions::SetBounty(unsigned short pid, int value) noexcept void StatsFunctions::SetBounty(unsigned short pid, int value) noexcept
@ -520,6 +532,8 @@ void StatsFunctions::SendAttributes(unsigned short pid) noexcept
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_ATTRIBUTE)->setPlayer(player); mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_ATTRIBUTE)->setPlayer(player);
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_ATTRIBUTE)->Send(false); mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_ATTRIBUTE)->Send(false);
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_ATTRIBUTE)->Send(true); mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_ATTRIBUTE)->Send(true);
player->attributeChanges.attributeIndexes.clear();
} }
void StatsFunctions::SendSkills(unsigned short pid) noexcept void StatsFunctions::SendSkills(unsigned short pid) noexcept

@ -237,28 +237,25 @@ void LocalPlayer::updateAttributes(bool forceUpdate)
MWWorld::Ptr ptrPlayer = getPlayerPtr(); MWWorld::Ptr ptrPlayer = getPlayerPtr();
const MWMechanics::NpcStats &ptrNpcStats = ptrPlayer.getClass().getNpcStats(ptrPlayer); const MWMechanics::NpcStats &ptrNpcStats = ptrPlayer.getClass().getNpcStats(ptrPlayer);
bool attributesChanged = false;
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
{ {
if (ptrNpcStats.getAttribute(i).getBase() != creatureStats.mAttributes[i].mBase || if (ptrNpcStats.getAttribute(i).getBase() != creatureStats.mAttributes[i].mBase ||
ptrNpcStats.getAttribute(i).getModifier() != creatureStats.mAttributes[i].mMod) ptrNpcStats.getAttribute(i).getModifier() != creatureStats.mAttributes[i].mMod ||
ptrNpcStats.getSkillIncrease(i) != npcStats.mSkillIncrease[i] ||
forceUpdate)
{ {
ptrNpcStats.getAttribute(i).writeState(creatureStats.mAttributes[i]); ptrNpcStats.getAttribute(i).writeState(creatureStats.mAttributes[i]);
attributesChanged = true;
}
if (ptrNpcStats.getSkillIncrease(i) != npcStats.mSkillIncrease[i])
{
npcStats.mSkillIncrease[i] = ptrNpcStats.getSkillIncrease(i); npcStats.mSkillIncrease[i] = ptrNpcStats.getSkillIncrease(i);
attributesChanged = true; attributeChanges.attributeIndexes.push_back(i);
} }
} }
if (attributesChanged || forceUpdate) if (attributeChanges.attributeIndexes.size() > 0)
{ {
getNetworking()->getPlayerPacket(ID_PLAYER_ATTRIBUTE)->setPlayer(this); getNetworking()->getPlayerPacket(ID_PLAYER_ATTRIBUTE)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_ATTRIBUTE)->Send(); getNetworking()->getPlayerPacket(ID_PLAYER_ATTRIBUTE)->Send();
attributeChanges.attributeIndexes.clear();
} }
} }

@ -95,6 +95,14 @@ namespace mwmp
int type; // 0 - Cell load, 1 - Cell unload int type; // 0 - Cell load, 1 - Cell unload
}; };
// Track only the indexes of the attributes that have been changed,
// with the attribute values themselves being stored in creatureStats.mAttributes
struct AttributeChanges
{
std::vector<int> attributeIndexes;
unsigned int count;
};
// Track only the indexes of the skills that have been changed, // Track only the indexes of the skills that have been changed,
// with the skill values themselves being stored in npcStats.mSkills // with the skill values themselves being stored in npcStats.mSkills
struct SkillChanges struct SkillChanges
@ -249,6 +257,7 @@ namespace mwmp
int day; int day;
double hour; double hour;
AttributeChanges attributeChanges;
SkillChanges skillChanges; SkillChanges skillChanges;
InventoryChanges inventoryChanges; InventoryChanges inventoryChanges;

@ -1,8 +1,5 @@
//
// Created by koncord on 08.03.16.
//
#include "PacketPlayerAttribute.hpp" #include "PacketPlayerAttribute.hpp"
#include <components/openmw-mp/NetworkMessages.hpp> #include <components/openmw-mp/NetworkMessages.hpp>
using namespace mwmp; using namespace mwmp;
@ -16,7 +13,23 @@ void PacketPlayerAttribute::Packet(RakNet::BitStream *bs, bool send)
{ {
PlayerPacket::Packet(bs, send); PlayerPacket::Packet(bs, send);
RW(player->creatureStats.mAttributes, send); if (send)
player->attributeChanges.count = (unsigned int)(player->attributeChanges.attributeIndexes.size());
else
player->attributeChanges.attributeIndexes.clear();
RW(player->attributeChanges.count, send);
for (unsigned int i = 0; i < player->attributeChanges.count; i++)
{
int attributeId;
if (send)
attributeId = player->attributeChanges.attributeIndexes.at(i);
RW(attributeId, send);
RW(player->npcStats.mSkillIncrease, send); RW(player->creatureStats.mAttributes[attributeId], send);
RW(player->npcStats.mSkillIncrease[attributeId], send);
}
} }

Loading…
Cancel
Save