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

Previously, whenever a single skill value changed for a player, that player then sent a PlayerSkill packet with all values for all 27 skills, plus the player's progress towards the next level and the bonuses to each attribute on the next level up as the result of sklll increases thus far.

This commit makes PlayerSkill contain only the values of specific skills, moves the player's progress towards the next level to PlayerLevel packets, and moves the bonuses to each attribute on the next level up to PlayerAttribute packets.

Players now also send a PlayerSkill packet whenever their progress towards a new point in a skill changes. This was previously avoided so as to not have massive packet spam.
new-script-api
David Cernat 7 years ago
parent 64b57983f0
commit ef79a98544

@ -172,6 +172,8 @@ void Player::update()
packet->setPlayer(basePlayer); packet->setPlayer(basePlayer);
packet->Send(false); packet->Send(false);
packet->Send(true); packet->Send(true);
skillChanges.skillIndexes.clear();
} }
if (inventory.isEquipmentChanged()) if (inventory.isEquipmentChanged())
@ -443,7 +445,7 @@ int Player::getLevelProgress() const
void Player::setLevelProgress(int progress) void Player::setLevelProgress(int progress)
{ {
npcStats.mLevelProgress = progress; npcStats.mLevelProgress = progress;
skillsChanged = true; levelChanged = true;
} }
std::string Player::getCreatureModel() const std::string Player::getCreatureModel() const
@ -506,6 +508,8 @@ void Player::setSkill(unsigned short id, int base, int current, float progress)
skill.mCurrent = current; skill.mCurrent = current;
skill.mProgress = progress; skill.mProgress = progress;
skillChanges.skillIndexes.push_back(id);
skillsChanged = true; skillsChanged = true;
} }
@ -521,7 +525,7 @@ void Player::setSkillIncrease(unsigned short attributeId, int increase)
npcStats.mSkillIncrease[attributeId] = increase; npcStats.mSkillIncrease[attributeId] = increase;
skillsChanged = true; attributesChanged = true;
} }
CharClass &Player::getCharClass(sol::this_state thisState) CharClass &Player::getCharClass(sol::this_state thisState)

@ -237,6 +237,12 @@ void LocalPlayer::updateAttributes(bool forceUpdate)
ptrNpcStats.getAttribute(i).writeState(creatureStats.mAttributes[i]); ptrNpcStats.getAttribute(i).writeState(creatureStats.mAttributes[i]);
attributesChanged = true; attributesChanged = true;
} }
if (ptrNpcStats.getSkillIncrease(i) != npcStats.mSkillIncrease[i])
{
npcStats.mSkillIncrease[i] = ptrNpcStats.getSkillIncrease(i);
attributesChanged = true;
}
} }
if (attributesChanged || forceUpdate) if (attributesChanged || forceUpdate)
@ -255,52 +261,39 @@ void LocalPlayer::updateSkills(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);
// Track whether skills have changed their values, but not whether
// progress towards skill increases has changed (to not spam server
// with packets every time tiny progress is made)
bool skillsChanged = false;
for (int i = 0; i < 27; ++i) for (int i = 0; i < 27; ++i)
{ {
if (ptrNpcStats.getSkill(i).getBase() != npcStats.mSkills[i].mBase) // Update a skill if its base value has changed at all or its progress has changed enough
if (ptrNpcStats.getSkill(i).getBase() != npcStats.mSkills[i].mBase ||
ptrNpcStats.getSkill(i).getProgress() != npcStats.mSkills[i].mProgress ||
forceUpdate)
{ {
ptrNpcStats.getSkill(i).writeState(npcStats.mSkills[i]); ptrNpcStats.getSkill(i).writeState(npcStats.mSkills[i]);
skillsChanged = true; skillChanges.skillIndexes.push_back(i);
}
// If we only have skill progress, remember it for future packets,
// but don't send a packet just because of this
else if (ptrNpcStats.getSkill(i).getProgress() != npcStats.mSkills[i].mProgress)
ptrNpcStats.getSkill(i).writeState(npcStats.mSkills[i]);
} }
for (int i = 0; i < 8; i++)
{
if (ptrNpcStats.getSkillIncrease(i) != npcStats.mSkillIncrease[i])
npcStats.mSkillIncrease[i] = ptrNpcStats.getSkillIncrease(i);
} }
if (skillsChanged || forceUpdate) if (skillChanges.skillIndexes.size() > 0)
{ {
npcStats.mLevelProgress = ptrNpcStats.getLevelProgress();
getNetworking()->getPlayerPacket(ID_PLAYER_SKILL)->setPlayer(this); getNetworking()->getPlayerPacket(ID_PLAYER_SKILL)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_SKILL)->Send(); getNetworking()->getPlayerPacket(ID_PLAYER_SKILL)->Send();
skillChanges.skillIndexes.clear();
} }
} }
void LocalPlayer::updateLevel(bool forceUpdate) void LocalPlayer::updateLevel(bool forceUpdate)
{ {
MWWorld::Ptr ptrPlayer = getPlayerPtr(); MWWorld::Ptr ptrPlayer = getPlayerPtr();
const MWMechanics::CreatureStats &ptrCreatureStats = ptrPlayer.getClass().getCreatureStats(ptrPlayer); const MWMechanics::NpcStats &ptrNpcStats = ptrPlayer.getClass().getNpcStats(ptrPlayer);
if (ptrCreatureStats.getLevel() != creatureStats.mLevel || forceUpdate) if (ptrNpcStats.getLevel() != creatureStats.mLevel ||
ptrNpcStats.getLevelProgress() != npcStats.mLevelProgress ||
forceUpdate)
{ {
creatureStats.mLevel = ptrCreatureStats.getLevel(); creatureStats.mLevel = ptrNpcStats.getLevel();
npcStats.mLevelProgress = ptrNpcStats.getLevelProgress();
getNetworking()->getPlayerPacket(ID_PLAYER_LEVEL)->setPlayer(this); getNetworking()->getPlayerPacket(ID_PLAYER_LEVEL)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_LEVEL)->Send(); getNetworking()->getPlayerPacket(ID_PLAYER_LEVEL)->Send();
// Also update skills to refresh level progress and attribute bonuses
// for next level up
updateSkills(true);
} }
} }

@ -79,6 +79,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 skills that have been changed,
// with the skill values themselves being stored in npcStats.mSkills
struct SkillChanges
{
std::vector<int> skillIndexes;
unsigned int count;
};
struct JournalChanges struct JournalChanges
{ {
std::vector<JournalItem> journalItems; std::vector<JournalItem> journalItems;
@ -205,6 +213,8 @@ namespace mwmp
int day; int day;
double hour; double hour;
SkillChanges skillChanges;
SpellbookChanges spellbookChanges; SpellbookChanges spellbookChanges;
JournalChanges journalChanges; JournalChanges journalChanges;
FactionChanges factionChanges; FactionChanges factionChanges;

@ -17,4 +17,6 @@ void PacketPlayerAttribute::Packet(RakNet::BitStream *bs, bool send)
PlayerPacket::Packet(bs, send); PlayerPacket::Packet(bs, send);
RW(player->creatureStats.mAttributes, send); RW(player->creatureStats.mAttributes, send);
RW(player->npcStats.mSkillIncrease, send);
} }

@ -13,4 +13,6 @@ void PacketPlayerLevel::Packet(RakNet::BitStream *bs, bool send)
PlayerPacket::Packet(bs, send); PlayerPacket::Packet(bs, send);
RW(player->creatureStats.mLevel, send); RW(player->creatureStats.mLevel, send);
RW(player->npcStats.mLevelProgress, send);
} }

@ -18,10 +18,21 @@ void PacketPlayerSkill::Packet(RakNet::BitStream *bs, bool send)
{ {
PlayerPacket::Packet(bs, send); PlayerPacket::Packet(bs, send);
RW(player->npcStats.mSkills, send); if (send)
player->skillChanges.count = (unsigned int)(player->skillChanges.skillIndexes.size());
else
player->skillChanges.skillIndexes.clear();
RW(player->skillChanges.count, send);
RW(player->npcStats.mSkillIncrease, send); for (unsigned int i = 0; i < player->skillChanges.count; i++)
{
int skillId;
if (send)
skillId = player->skillChanges.skillIndexes.at(i);
RW(player->npcStats.mLevelProgress, send); RW(skillId, send);
RW(player->npcStats.mSkills[skillId], send);
}
} }

Loading…
Cancel
Save