diff --git a/dGame/dGameMessages/PlayerMessages.h b/dGame/dGameMessages/PlayerMessages.h index af19e8ebd..b8c5fb1ea 100644 --- a/dGame/dGameMessages/PlayerMessages.h +++ b/dGame/dGameMessages/PlayerMessages.h @@ -100,7 +100,9 @@ namespace GameMessages { LWOMAPID zoneID{ LWOMAPID_INVALID }; // optional }; - // Client -> server. + // Client -> server here; live sent it server -> client (live captures hold no client -> server copy). The client's CharacterComponent adds updateValue + // to the passport statistic and, for every statistic but MetersTraveled, updates the passport UI. updateID is a + // StatisticID. See docs/CaptureUnknowns.md. struct UpdatePlayerStatistic : public NetGameMsg { UpdatePlayerStatistic() : NetGameMsg(MessageType::Game::UPDATE_PLAYER_STATISTIC) {} void Serialize(RakNet::BitStream& bitStream) const override; diff --git a/tests/dGameTests/dGameMessagesTests/RemainingMessagesTests.cpp b/tests/dGameTests/dGameMessagesTests/RemainingMessagesTests.cpp index 425073e74..58e110b11 100644 --- a/tests/dGameTests/dGameMessagesTests/RemainingMessagesTests.cpp +++ b/tests/dGameTests/dGameMessagesTests/RemainingMessagesTests.cpp @@ -6,6 +6,7 @@ #include "ObjectMessages.h" #include "PlayerMessages.h" #include "QuickBuildMessages.h" +#include "StatisticID.h" #include "ZoneMessages.h" #include @@ -722,3 +723,23 @@ TEST_F(RemainingMessagesTests, LeaderboardMessagesMatchLegacy) { data.leaderboard = &leaderboard; ExpectSameAsLegacy([&](const SystemAddress& address) { LegacyGameMessages::SendActivitySummaryLeaderboardData(0x1000000000000001LL, &leaderboard, address); }, data, SendMode::SendToClient); } + +// Packets from 2011/2012 live captures: live sent UpdatePlayerStatistic (1481) server -> client. The client reads +// a u32 statistic and an optional i64 amount that defaults to 1 (0x00d8c870 in 1.10.64). +TEST_F(RemainingMessagesTests, UpdatePlayerStatisticMatchesLiveCapture) { + // CurrencyCollected after a SetCurrency, amount left at the default. + const auto currency = FromLiveCapture("5305000c000000005e7dea8e00000010c9050100000000"); + EXPECT_EQ(currency.target, 0x100000008eea7d5eLL); + EXPECT_EQ(currency.updateID, static_cast(StatisticID::CurrencyCollected)); + EXPECT_EQ(currency.updateValue, 1); + + // CurrencyCollected with an amount. + const auto coins = FromLiveCapture("5305000c000000005e7dea8e00000010c90501000000fa0080000000000000"); + EXPECT_EQ(coins.updateID, static_cast(StatisticID::CurrencyCollected)); + EXPECT_EQ(coins.updateValue, 500); + + // MetersTraveled, sent periodically while the player moves. + const auto meters = FromLiveCapture("5305000c000000005e7dea8e00000010c9050c0000008e8000000000000000"); + EXPECT_EQ(meters.updateID, static_cast(StatisticID::MetersTraveled)); + EXPECT_EQ(meters.updateValue, 29); +}