mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-14 07:47:13 +00:00
fix: send reputation in the character data as live did, as LDF type 8
Live sent the reputation key as a 64-bit number (LDF type 8) in all 451 character data packets looked at; the server sent it as an object ID (type 9). It now goes out as type 8 with the other keys live sent; the packet without them keeps type 9, and both are read. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
@@ -248,7 +248,9 @@ namespace ClientPackets {
|
||||
ldfData.Insert<u16string>(u"name", name);
|
||||
ldfData.Insert<int32_t>(u"gmlevel", static_cast<int32_t>(gmLevel));
|
||||
ldfData.Insert<int32_t>(u"chatmode", chatMode);
|
||||
ldfData.Insert<int64_t>(u"reputation", reputation);
|
||||
// Live sent reputation as LDF type 8 (451 of 451 character data packets); the old packet has it as type 9
|
||||
if (sendWorldKeys) ldfData.Insert<uint64_t>(u"reputation", static_cast<uint64_t>(reputation));
|
||||
else ldfData.Insert<int64_t>(u"reputation", reputation);
|
||||
ldfData.Insert<int32_t>(u"propertycloneid", propertyCloneID);
|
||||
if (txfring) ldfData.Insert<bool>(u"txfring", true);
|
||||
if (sendWorldKeys) {
|
||||
@@ -373,6 +375,7 @@ namespace ClientPackets {
|
||||
uint64_t value{};
|
||||
VALIDATE_READ(data.Read(value));
|
||||
if (key == u"levelid") { levelID = value; sendWorldKeys = true; }
|
||||
else if (key == u"reputation") reputation = static_cast<int64_t>(value);
|
||||
break;
|
||||
}
|
||||
case LDF_TYPE_FLOAT: {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include "ZCompression.h"
|
||||
#include "LDFFormat.h"
|
||||
#include "ChatPackets.h"
|
||||
#include "ClientPackets.h"
|
||||
#include "GameDependencies.h"
|
||||
@@ -365,6 +367,66 @@ TEST_F(WorldPacketsTests, CreateCharacterSendsTheWorldKeys) {
|
||||
EXPECT_FALSE(without.requiresRename);
|
||||
}
|
||||
|
||||
// Live sent reputation as LDF type 8 (a 64-bit number), not as an object ID (type 9), in every character data packet.
|
||||
// The entries are sorted by key: reputation follows propertycloneid.
|
||||
TEST_F(WorldPacketsTests, CreateCharacterSendsReputationAsLdfType8) {
|
||||
const auto reputationType = [](const ClientPackets::CreateCharacter& packet) {
|
||||
RakNet::BitStream bitStream;
|
||||
packet.Serialize(bitStream);
|
||||
// The LDF is compressed: size + 9, the compressed flag, the size, the compressed size, the data
|
||||
uint32_t sizePlusHeader{};
|
||||
uint8_t compressed{};
|
||||
uint32_t uncompressedSize{};
|
||||
uint32_t compressedSize{};
|
||||
EXPECT_TRUE(bitStream.Read(sizePlusHeader));
|
||||
EXPECT_TRUE(bitStream.Read(compressed));
|
||||
EXPECT_TRUE(bitStream.Read(uncompressedSize));
|
||||
EXPECT_TRUE(bitStream.Read(compressedSize));
|
||||
std::vector<uint8_t> compressedData(compressedSize);
|
||||
EXPECT_TRUE(bitStream.ReadAlignedBytes(compressedData.data(), compressedSize));
|
||||
std::vector<uint8_t> uncompressed(uncompressedSize);
|
||||
int32_t error{};
|
||||
EXPECT_EQ(ZCompression::Decompress(compressedData.data(), compressedSize, uncompressed.data(), uncompressedSize, error), static_cast<int32_t>(uncompressedSize));
|
||||
RakNet::BitStream data(uncompressed.data(), uncompressed.size(), false);
|
||||
uint32_t count{};
|
||||
EXPECT_TRUE(data.Read(count));
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
uint8_t keyBytes{};
|
||||
EXPECT_TRUE(data.Read(keyBytes));
|
||||
std::u16string key(keyBytes / 2, u'\0');
|
||||
for (auto& character : key) EXPECT_TRUE(data.Read(character));
|
||||
uint8_t type{};
|
||||
EXPECT_TRUE(data.Read(type));
|
||||
if (key == u"reputation") {
|
||||
int64_t value{};
|
||||
EXPECT_TRUE(data.Read(value));
|
||||
EXPECT_EQ(value, 300);
|
||||
return static_cast<int32_t>(type);
|
||||
}
|
||||
switch (type) {
|
||||
case LDF_TYPE_S32: case LDF_TYPE_U32: case LDF_TYPE_FLOAT: data.IgnoreBytes(4); break;
|
||||
case LDF_TYPE_BOOLEAN: data.IgnoreBytes(1); break;
|
||||
case LDF_TYPE_U64: case LDF_TYPE_OBJID: data.IgnoreBytes(8); break;
|
||||
case LDF_TYPE_UTF_16: { uint32_t length{}; EXPECT_TRUE(data.Read(length)); data.IgnoreBytes(length * 2); break; }
|
||||
case LDF_TYPE_UTF_8: { uint32_t length{}; EXPECT_TRUE(data.Read(length)); data.IgnoreBytes(length); break; }
|
||||
default: ADD_FAILURE() << "LDF type " << static_cast<int32_t>(type); return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
ClientPackets::CreateCharacter packet;
|
||||
packet.xmlData = "<obj/>";
|
||||
packet.reputation = 300;
|
||||
EXPECT_EQ(reputationType(packet), 8);
|
||||
EXPECT_EQ(RoundTrip(packet).reputation, 300);
|
||||
|
||||
// The packet from before the world keys keeps its type
|
||||
packet.sendWorldKeys = false;
|
||||
EXPECT_EQ(reputationType(packet), 9);
|
||||
EXPECT_EQ(RoundTrip(packet).reputation, 300);
|
||||
}
|
||||
|
||||
TEST_F(WorldPacketsTests, CharacterListMatchesLegacy) {
|
||||
FakeCharacter first;
|
||||
FakeCharacter second;
|
||||
|
||||
Reference in New Issue
Block a user