mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-15 16:27:14 +00:00
fix: a character's activity or PVP change is serialized once
LWOCharacterComponent::Deserialize (0x00ca3a40) reads the GM and PVP block and the current activity each behind its own flag bit. DLU never cleared the two dirty flags, so after the first quick build or pet taming every later serialization of the player carried both blocks again. They are cleared after an update now, as the guild block's is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -245,11 +245,15 @@ void CharacterComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInit
|
||||
outBitStream.Write(m_GMLevel);
|
||||
outBitStream.Write(m_EditorEnabled);
|
||||
outBitStream.Write(m_EditorLevel);
|
||||
if (!bIsInitialUpdate) m_DirtyGMInfo = false;
|
||||
}
|
||||
|
||||
const bool writeCurrentActivity = bIsInitialUpdate || m_DirtyCurrentActivity;
|
||||
outBitStream.Write(writeCurrentActivity);
|
||||
if (writeCurrentActivity) outBitStream.Write(m_CurrentActivity);
|
||||
if (writeCurrentActivity) {
|
||||
outBitStream.Write(m_CurrentActivity);
|
||||
if (!bIsInitialUpdate) m_DirtyCurrentActivity = false;
|
||||
}
|
||||
|
||||
const bool writeSocialInfo = bIsInitialUpdate || m_DirtySocialInfo;
|
||||
outBitStream.Write(writeSocialInfo);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "MovingPlatformComponent.h"
|
||||
#include "SimplePhysicsComponent.h"
|
||||
#include "User.h"
|
||||
#include "eGameActivity.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "eReplicaPacketType.h"
|
||||
|
||||
@@ -130,6 +131,48 @@ TEST_F(ReplicaConstructionTest, CharacterConstructionAlwaysWritesGmActivityAndSo
|
||||
player.SetCharacter(nullptr);
|
||||
}
|
||||
|
||||
// A current-activity or PVP change is written once, as a guild change is: LWOCharacterComponent::Deserialize reads each
|
||||
// block behind its own flag bit.
|
||||
TEST_F(ReplicaConstructionTest, CharacterActivityAndPvpChangesAreWrittenOnce) {
|
||||
User user(UNASSIGNED_SYSTEM_ADDRESS, "tester", "key");
|
||||
Character character(1, &user);
|
||||
info.lot = 1;
|
||||
Entity player(1152921506064087005, info);
|
||||
player.SetCharacter(&character);
|
||||
character.SetEntity(&player);
|
||||
auto* const component = player.AddComponent<CharacterComponent>(-1, &character, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
component->SetCurrentActivity(eGameActivity::QUICKBUILDING);
|
||||
component->SetPvpEnabled(true);
|
||||
RakNet::BitStream serialization;
|
||||
component->Serialize(serialization, false);
|
||||
RakNet::BitStream expected;
|
||||
expected.Write1(); // gm_pvp_info
|
||||
expected.Write1(); // pvp_enabled
|
||||
expected.Write0(); // is_gm
|
||||
expected.Write<uint8_t>(0); // gm_level
|
||||
expected.Write0(); // editor_enabled
|
||||
expected.Write<uint8_t>(0); // editor_level
|
||||
expected.Write1(); // current_activity
|
||||
expected.Write(eGameActivity::QUICKBUILDING);
|
||||
expected.Write0(); // social_info
|
||||
ExpectSameBits(serialization, expected);
|
||||
|
||||
RakNet::BitStream again;
|
||||
component->Serialize(again, false);
|
||||
EXPECT_EQ(again.GetNumberOfBitsUsed(), 3u);
|
||||
|
||||
// A construction in between (another player coming into range) doesn't swallow a pending change
|
||||
component->SetCurrentActivity(eGameActivity::NONE);
|
||||
RakNet::BitStream construction;
|
||||
component->Serialize(construction, true);
|
||||
RakNet::BitStream after;
|
||||
component->Serialize(after, false);
|
||||
EXPECT_EQ(after.GetNumberOfBitsUsed(), 3u + 32u);
|
||||
|
||||
player.SetCharacter(nullptr);
|
||||
}
|
||||
|
||||
// A guild change (docs/Guilds.md) is written once: the client reads guild id, a u8 length and 16-bit characters, and
|
||||
// redraws the name billboard every time it reads a name.
|
||||
TEST_F(ReplicaConstructionTest, CharacterGuildChangeIsWrittenOnce) {
|
||||
|
||||
Reference in New Issue
Block a user