From ead394d991a4ea42ec7d671c616c45a680ee7122 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Tue, 10 Nov 2026 16:48:56 -0600 Subject: [PATCH] fix: adapt the login packet tests to a session key that differs every time The tests compared the login response and SET_SESSION_KEY of the old hand written code with the structs byte for byte, with the same seed for both. The key no longer comes from the seeded engine, so the tests leave its bytes out, and the copy of the old code writes the key the way main writes it now. Co-Authored-By: Claude Fable 5.2 --- .../dNetTests/CommonAuthPacketsTests.cpp | 25 ++++++++++++++++++- .../Legacy/CommonAuthPacketsLegacy.h | 8 +++--- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/tests/dGameTests/dNetTests/CommonAuthPacketsTests.cpp b/tests/dGameTests/dNetTests/CommonAuthPacketsTests.cpp index e52d9528b..4c62fa1d5 100644 --- a/tests/dGameTests/dNetTests/CommonAuthPacketsTests.cpp +++ b/tests/dGameTests/dNetTests/CommonAuthPacketsTests.cpp @@ -48,11 +48,30 @@ namespace { handler(inStream, sysAddr, header.internalPacketID); } + // A session key is different every time it is made, so it is taken out of the two packets that carry one: + // the login response (33 wide characters after the response code, the 8 event names and the 3 version numbers) + // and the SET_SESSION_KEY sent to the master server (33 characters after the header) + CapturedPacket WithoutSessionKey(CapturedPacket packet) { + constexpr size_t headerSize = 8; + if (packet.bytes.size() < headerSize) return packet; + const auto blank = [&packet](const size_t offset, const size_t size) { + for (size_t i = offset; i < offset + size && i < packet.bytes.size(); i++) packet.bytes[i] = 0; + }; + const auto service = static_cast(packet.bytes[1] | (packet.bytes[2] << 8)); + const auto messageId = packet.bytes[3]; + if (service == ServiceType::CLIENT && messageId == static_cast(MessageType::Client::LOGIN_RESPONSE)) { + blank(headerSize + 1 + 8 * 33 + 3 * 2, 33 * 2); + } else if (service == ServiceType::MASTER && messageId == static_cast(MessageType::Master::SET_SESSION_KEY)) { + blank(headerSize, 33); + } + return packet; + } + void ExpectSamePackets(const std::vector& expected, const std::vector& actual) { ASSERT_FALSE(expected.empty()); ASSERT_EQ(expected.size(), actual.size()); for (size_t i = 0; i < expected.size(); i++) { - EXPECT_PACKET_EQ(FromCapture(expected[i]), FromCapture(actual[i])); + EXPECT_PACKET_EQ(FromCapture(WithoutSessionKey(expected[i])), FromCapture(WithoutSessionKey(actual[i]))); EXPECT_EQ(expected[i].sysAddr, actual[i].sysAddr); EXPECT_EQ(expected[i].broadcast, actual[i].broadcast); } @@ -432,6 +451,10 @@ TEST_F(CommonAuthPacketsTests, LoginRequestMatchesLegacy) { const auto stamps = convertedResponse.stamps.list; legacyResponse.stamps.list.clear(); convertedResponse.stamps.list.clear(); + // Each response has a session key of its own + EXPECT_EQ(legacyResponse.userKey.GetAsString().size(), convertedResponse.userKey.GetAsString().size()); + legacyResponse.userKey = LUWString(); + convertedResponse.userKey = LUWString(); RakNet::BitStream legacyBytes; legacyResponse.WritePacket(legacyBytes); RakNet::BitStream convertedBytes; diff --git a/tests/dGameTests/dNetTests/Legacy/CommonAuthPacketsLegacy.h b/tests/dGameTests/dNetTests/Legacy/CommonAuthPacketsLegacy.h index 4b69af535..57039cb0c 100644 --- a/tests/dGameTests/dNetTests/Legacy/CommonAuthPacketsLegacy.h +++ b/tests/dGameTests/dNetTests/Legacy/CommonAuthPacketsLegacy.h @@ -117,10 +117,8 @@ inline void SendLoginResponse(dServer* server, const SystemAddress& sysAddr, eLo loginResponse.Write(version_minor); // Writes the user key - uint32_t sessionKey = GeneralUtils::GenerateRandomNumber(); - std::string userHash = std::to_string(sessionKey); - userHash = md5(userHash); - loginResponse.Write(LUWString(userHash)); + const std::string sessionKey = GeneralUtils::GenerateUnpredictableHexString(16); + loginResponse.Write(LUWString(sessionKey)); // World Server IP loginResponse.Write(LUString(wServerIP)); @@ -162,7 +160,7 @@ inline void SendLoginResponse(dServer* server, const SystemAddress& sysAddr, eLo if (responseCode == eLoginResponse::SUCCESS) { CBITSTREAM; BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::SET_SESSION_KEY); - bitStream.Write(sessionKey); + bitStream.Write(LUString(sessionKey)); bitStream.Write(LUString(username)); server->SendToMaster(bitStream);