feat(messages): read ModifyGhostingDistance

LWOCharacterComponent sends ModifyGhostingDistance (1485: an optional
fDistanceScalar, default 1) on load. All 239 live packets were
the single byte 00 (default scale), so there is nothing for the server to
change; it was logged as an unknown game message. It is now read and
ignored.

Check in game: nothing changes; the world server log no longer has
"Received Unknown GM ... 1485" on each load.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-29 03:25:15 -05:00
parent 3672b64dec
commit 3c7f93dac4
4 changed files with 32 additions and 0 deletions

View File

@@ -220,6 +220,7 @@ namespace {
{ ACKNOWLEDGE_POSSESSION, []() { return std::make_unique<AcknowledgePossession>(); } },
{ TOGGLE_GHOST_REFERENCE_OVERRIDE, []() { return std::make_unique<ToggleGhostReferenceOverride>(); } },
{ SET_GHOST_REFERENCE_POSITION, []() { return std::make_unique<SetGhostReferencePosition>(); } },
{ MODIFY_GHOSTING_DISTANCE, []() { return std::make_unique<ModifyGhostingDistance>(); } },
};
};

View File

@@ -396,6 +396,15 @@ namespace GameMessages {
return ReadPoint(bitStream, pos);
}
void ModifyGhostingDistance::Serialize(RakNet::BitStream& bitStream) const {
BitStreamUtils::WriteOptional(bitStream, fDistanceScalar, 1.0f);
}
bool ModifyGhostingDistance::Deserialize(RakNet::BitStream& bitStream) {
VALIDATE_READ(BitStreamUtils::ReadOptional(bitStream, fDistanceScalar, 1.0f));
return true;
}
void SetGhostReferencePosition::Handle(Entity& entity, const SystemAddress& sysAddr) {
auto* player = PlayerManager::GetPlayer(sysAddr);
if (player == nullptr) return;

View File

@@ -253,6 +253,17 @@ namespace GameMessages {
LWOOBJID possessedObjID{ LWOOBJID_EMPTY }; // optional
};
// Client -> server. LWOCharacterComponent sends it on load: a scale for the distance at which objects are ghosted
// for this player. All 239 live packets left the optional scale at its default (1), so the server keeps its own
// ghosting distances.
struct ModifyGhostingDistance : public NetGameMsg {
ModifyGhostingDistance() : NetGameMsg(MessageType::Game::MODIFY_GHOSTING_DISTANCE) {}
void Serialize(RakNet::BitStream& bitStream) const override;
bool Deserialize(RakNet::BitStream& bitStream) override;
float fDistanceScalar{ 1.0f }; // optional
};
// Client -> server.
struct ToggleGhostReferenceOverride : public NetGameMsg {
ToggleGhostReferenceOverride() : NetGameMsg(MessageType::Game::TOGGLE_GHOST_REFERENCE_OVERRIDE) {}

View File

@@ -12,6 +12,7 @@
#include "Entity.h"
#include "InventoryComponent.h"
#include "InventoryMessages.h"
#include "MovementMessages.h"
#include "PlayerMessages.h"
#include <memory>
@@ -144,3 +145,13 @@ TEST_F(ClientMessagesTests, ResyncEquipmentResendsTheEquipment) {
ASSERT_TRUE(resent.Read(equipmentSent));
EXPECT_TRUE(equipmentSent);
}
// ModifyGhostingDistance (1485): an optional scale, default 1. Every one of the 239 live packets was the default.
TEST_F(ClientMessagesTests, ModifyGhostingDistanceMatchesLiveCapture) {
auto msg = FromLiveClientCapture<GameMessages::ModifyGhostingDistance>(std::string(PLAYER_HEADER) + "cd05" + "00");
EXPECT_EQ(msg.fDistanceScalar, 1.0f);
msg.fDistanceScalar = 0.5f;
EXPECT_EQ(RoundTrip(msg).fDistanceScalar, 0.5f);
ExpectTruncatedFails(msg);
msg.Handle(*player, UNASSIGNED_SYSTEM_ADDRESS); // nothing to do
}