From ef79a98544041350f475580cb37e6a6cbd6ecc70 Mon Sep 17 00:00:00 2001 From: David Cernat Date: Fri, 24 Nov 2017 12:38:42 +0200 Subject: [PATCH] [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. --- apps/openmw-mp/Player.cpp | 8 +++- apps/openmw/mwmp/LocalPlayer.cpp | 45 ++++++++----------- components/openmw-mp/Base/BasePlayer.hpp | 10 +++++ .../Packets/Player/PacketPlayerAttribute.cpp | 2 + .../Packets/Player/PacketPlayerLevel.cpp | 2 + .../Packets/Player/PacketPlayerSkill.cpp | 23 +++++++--- 6 files changed, 56 insertions(+), 34 deletions(-) diff --git a/apps/openmw-mp/Player.cpp b/apps/openmw-mp/Player.cpp index 05719e637..d077acfde 100644 --- a/apps/openmw-mp/Player.cpp +++ b/apps/openmw-mp/Player.cpp @@ -172,6 +172,8 @@ void Player::update() packet->setPlayer(basePlayer); packet->Send(false); packet->Send(true); + + skillChanges.skillIndexes.clear(); } if (inventory.isEquipmentChanged()) @@ -443,7 +445,7 @@ int Player::getLevelProgress() const void Player::setLevelProgress(int progress) { npcStats.mLevelProgress = progress; - skillsChanged = true; + levelChanged = true; } 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.mProgress = progress; + skillChanges.skillIndexes.push_back(id); + skillsChanged = true; } @@ -521,7 +525,7 @@ void Player::setSkillIncrease(unsigned short attributeId, int increase) npcStats.mSkillIncrease[attributeId] = increase; - skillsChanged = true; + attributesChanged = true; } CharClass &Player::getCharClass(sol::this_state thisState) diff --git a/apps/openmw/mwmp/LocalPlayer.cpp b/apps/openmw/mwmp/LocalPlayer.cpp index fe905cd69..0e43a4c6f 100644 --- a/apps/openmw/mwmp/LocalPlayer.cpp +++ b/apps/openmw/mwmp/LocalPlayer.cpp @@ -237,6 +237,12 @@ void LocalPlayer::updateAttributes(bool forceUpdate) ptrNpcStats.getAttribute(i).writeState(creatureStats.mAttributes[i]); attributesChanged = true; } + + if (ptrNpcStats.getSkillIncrease(i) != npcStats.mSkillIncrease[i]) + { + npcStats.mSkillIncrease[i] = ptrNpcStats.getSkillIncrease(i); + attributesChanged = true; + } } if (attributesChanged || forceUpdate) @@ -255,52 +261,39 @@ void LocalPlayer::updateSkills(bool forceUpdate) MWWorld::Ptr ptrPlayer = getPlayerPtr(); 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) { - 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]); - 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)->Send(); + skillChanges.skillIndexes.clear(); } } void LocalPlayer::updateLevel(bool forceUpdate) { 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)->Send(); - - // Also update skills to refresh level progress and attribute bonuses - // for next level up - updateSkills(true); } } diff --git a/components/openmw-mp/Base/BasePlayer.hpp b/components/openmw-mp/Base/BasePlayer.hpp index 8f8b58606..de54314e7 100644 --- a/components/openmw-mp/Base/BasePlayer.hpp +++ b/components/openmw-mp/Base/BasePlayer.hpp @@ -79,6 +79,14 @@ namespace mwmp 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 skillIndexes; + unsigned int count; + }; + struct JournalChanges { std::vector journalItems; @@ -205,6 +213,8 @@ namespace mwmp int day; double hour; + SkillChanges skillChanges; + SpellbookChanges spellbookChanges; JournalChanges journalChanges; FactionChanges factionChanges; diff --git a/components/openmw-mp/Packets/Player/PacketPlayerAttribute.cpp b/components/openmw-mp/Packets/Player/PacketPlayerAttribute.cpp index bdab8abe5..089212d7a 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerAttribute.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerAttribute.cpp @@ -17,4 +17,6 @@ void PacketPlayerAttribute::Packet(RakNet::BitStream *bs, bool send) PlayerPacket::Packet(bs, send); RW(player->creatureStats.mAttributes, send); + + RW(player->npcStats.mSkillIncrease, send); } diff --git a/components/openmw-mp/Packets/Player/PacketPlayerLevel.cpp b/components/openmw-mp/Packets/Player/PacketPlayerLevel.cpp index 9e83d6398..22256489f 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerLevel.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerLevel.cpp @@ -13,4 +13,6 @@ void PacketPlayerLevel::Packet(RakNet::BitStream *bs, bool send) PlayerPacket::Packet(bs, send); RW(player->creatureStats.mLevel, send); + + RW(player->npcStats.mLevelProgress, send); } diff --git a/components/openmw-mp/Packets/Player/PacketPlayerSkill.cpp b/components/openmw-mp/Packets/Player/PacketPlayerSkill.cpp index ea25463ec..f293e9e27 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerSkill.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerSkill.cpp @@ -18,10 +18,21 @@ void PacketPlayerSkill::Packet(RakNet::BitStream *bs, bool send) { PlayerPacket::Packet(bs, send); - RW(player->npcStats.mSkills, send); - - - RW(player->npcStats.mSkillIncrease, send); - - RW(player->npcStats.mLevelProgress, send); + if (send) + player->skillChanges.count = (unsigned int)(player->skillChanges.skillIndexes.size()); + else + player->skillChanges.skillIndexes.clear(); + + RW(player->skillChanges.count, send); + + for (unsigned int i = 0; i < player->skillChanges.count; i++) + { + int skillId; + + if (send) + skillId = player->skillChanges.skillIndexes.at(i); + + RW(skillId, send); + RW(player->npcStats.mSkills[skillId], send); + } }