mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-12-16 20:24:39 -06:00
Compare commits
19 Commits
script-deb
...
copilot/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
adbd9d78a6 | ||
|
|
89ea1ee831 | ||
|
|
177319438d | ||
|
|
74fb9428bb | ||
|
|
4d6debae84 | ||
|
|
48f8d0fe04 | ||
|
|
2b0791130f | ||
|
|
3c111735bc | ||
|
|
fc48f58425 | ||
|
|
125c98570d | ||
|
|
de49b53366 | ||
|
|
5a17e6cf23 | ||
|
|
b6764bbb10 | ||
|
|
e6204752aa | ||
|
|
d376775731 | ||
|
|
c20260cd85 | ||
|
|
90f325f59c | ||
|
|
a82aeec50e | ||
|
|
065817b1ce |
@@ -7,3 +7,4 @@ include(GoogleTest)
|
||||
# Add the subdirectories
|
||||
add_subdirectory(dCommonTests)
|
||||
add_subdirectory(dGameTests)
|
||||
add_subdirectory(dNetTests)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
set(DGAMETEST_SOURCES
|
||||
"GameDependencies.cpp"
|
||||
"MailTests.cpp"
|
||||
)
|
||||
|
||||
add_subdirectory(dComponentsTests)
|
||||
|
||||
403
tests/dGameTests/MailTests.cpp
Normal file
403
tests/dGameTests/MailTests.cpp
Normal file
@@ -0,0 +1,403 @@
|
||||
#include "GameDependencies.h"
|
||||
#include "Mail.h"
|
||||
#include "MailInfo.h"
|
||||
#include "BitStream.h"
|
||||
#include "Entity.h"
|
||||
#include "User.h"
|
||||
#include "Character.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "BitStreamUtils.h"
|
||||
|
||||
class MailTests : public GameDependenciesTest {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
SetUpDependencies();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
TearDownDependencies();
|
||||
}
|
||||
};
|
||||
|
||||
// Test SendRequest packet with MailInfo serialization
|
||||
TEST_F(MailTests, SendRequestMailInfoSerialization) {
|
||||
Mail::SendRequest sendRequest;
|
||||
|
||||
// Set up test mail info
|
||||
sendRequest.mailInfo.senderUsername = "TestSender";
|
||||
sendRequest.mailInfo.recipient = "TestRecipient";
|
||||
sendRequest.mailInfo.subject = "Test Subject";
|
||||
sendRequest.mailInfo.body = "Test mail body content";
|
||||
sendRequest.mailInfo.id = 12345;
|
||||
sendRequest.mailInfo.senderId = 678;
|
||||
sendRequest.mailInfo.receiverId = 901;
|
||||
sendRequest.mailInfo.timeSent = 1640995200;
|
||||
sendRequest.mailInfo.wasRead = false;
|
||||
sendRequest.mailInfo.languageCode = 1033;
|
||||
sendRequest.mailInfo.itemID = 555;
|
||||
sendRequest.mailInfo.itemCount = 10;
|
||||
sendRequest.mailInfo.itemLOT = 1234;
|
||||
sendRequest.mailInfo.itemSubkey = 999;
|
||||
|
||||
// Test that the mail info serializes to a non-empty bitstream
|
||||
RakNet::BitStream mailInfoStream;
|
||||
sendRequest.mailInfo.Serialize(mailInfoStream);
|
||||
|
||||
// Verify the stream contains data
|
||||
ASSERT_GT(mailInfoStream.GetNumberOfBytesUsed(), 0);
|
||||
|
||||
// Verify all fields are serialized correctly by reading them back
|
||||
mailInfoStream.ResetReadPointer();
|
||||
|
||||
// Read id (uint64_t)
|
||||
uint64_t readId;
|
||||
ASSERT_TRUE(mailInfoStream.Read(readId));
|
||||
ASSERT_EQ(readId, 12345);
|
||||
|
||||
// Read subject (LUWString, 50 chars)
|
||||
LUWString readSubject(50);
|
||||
ASSERT_TRUE(mailInfoStream.Read(readSubject));
|
||||
ASSERT_EQ(readSubject.GetAsString(), "Test Subject");
|
||||
|
||||
// Read body (LUWString, 400 chars)
|
||||
LUWString readBody(400);
|
||||
ASSERT_TRUE(mailInfoStream.Read(readBody));
|
||||
ASSERT_EQ(readBody.GetAsString(), "Test mail body content");
|
||||
|
||||
// Read sender (LUWString, 32 chars)
|
||||
LUWString readSender(32);
|
||||
ASSERT_TRUE(mailInfoStream.Read(readSender));
|
||||
ASSERT_EQ(readSender.GetAsString(), "TestSender");
|
||||
|
||||
// Read packing (uint32_t = 0)
|
||||
uint32_t packing1;
|
||||
ASSERT_TRUE(mailInfoStream.Read(packing1));
|
||||
ASSERT_EQ(packing1, 0);
|
||||
|
||||
// Read attachedCurrency (uint64_t = 0)
|
||||
uint64_t attachedCurrency;
|
||||
ASSERT_TRUE(mailInfoStream.Read(attachedCurrency));
|
||||
ASSERT_EQ(attachedCurrency, 0);
|
||||
|
||||
// Read itemID (LWOOBJID)
|
||||
LWOOBJID readItemID;
|
||||
ASSERT_TRUE(mailInfoStream.Read(readItemID));
|
||||
ASSERT_EQ(readItemID, 555);
|
||||
|
||||
// Read itemLOT (LOT)
|
||||
LOT readItemLOT;
|
||||
ASSERT_TRUE(mailInfoStream.Read(readItemLOT));
|
||||
ASSERT_EQ(readItemLOT, 1234);
|
||||
|
||||
// Read packing (uint32_t = 0)
|
||||
uint32_t packing2;
|
||||
ASSERT_TRUE(mailInfoStream.Read(packing2));
|
||||
ASSERT_EQ(packing2, 0);
|
||||
|
||||
// Read itemSubkey (LWOOBJID)
|
||||
LWOOBJID readItemSubkey;
|
||||
ASSERT_TRUE(mailInfoStream.Read(readItemSubkey));
|
||||
ASSERT_EQ(readItemSubkey, 999);
|
||||
|
||||
// Read itemCount (int16_t)
|
||||
int16_t readItemCount;
|
||||
ASSERT_TRUE(mailInfoStream.Read(readItemCount));
|
||||
ASSERT_EQ(readItemCount, 10);
|
||||
|
||||
// Read subject type (uint8_t = 0)
|
||||
uint8_t subjectType;
|
||||
ASSERT_TRUE(mailInfoStream.Read(subjectType));
|
||||
ASSERT_EQ(subjectType, 0);
|
||||
|
||||
// Read packing (uint8_t = 0)
|
||||
uint8_t packing3;
|
||||
ASSERT_TRUE(mailInfoStream.Read(packing3));
|
||||
ASSERT_EQ(packing3, 0);
|
||||
|
||||
// Read packing (uint32_t = 0)
|
||||
uint32_t packing4;
|
||||
ASSERT_TRUE(mailInfoStream.Read(packing4));
|
||||
ASSERT_EQ(packing4, 0);
|
||||
|
||||
// Read expiration date (uint64_t = timeSent)
|
||||
uint64_t expirationDate;
|
||||
ASSERT_TRUE(mailInfoStream.Read(expirationDate));
|
||||
ASSERT_EQ(expirationDate, 1640995200);
|
||||
|
||||
// Read send date (uint64_t = timeSent)
|
||||
uint64_t sendDate;
|
||||
ASSERT_TRUE(mailInfoStream.Read(sendDate));
|
||||
ASSERT_EQ(sendDate, 1640995200);
|
||||
|
||||
// Read wasRead (uint8_t)
|
||||
uint8_t readWasRead;
|
||||
ASSERT_TRUE(mailInfoStream.Read(readWasRead));
|
||||
ASSERT_EQ(readWasRead, false);
|
||||
|
||||
// Read isLocalized (uint8_t = 0)
|
||||
uint8_t isLocalized;
|
||||
ASSERT_TRUE(mailInfoStream.Read(isLocalized));
|
||||
ASSERT_EQ(isLocalized, 0);
|
||||
|
||||
// Read language code (uint16_t = 1033)
|
||||
uint16_t readLanguageCode;
|
||||
ASSERT_TRUE(mailInfoStream.Read(readLanguageCode));
|
||||
ASSERT_EQ(readLanguageCode, 1033);
|
||||
|
||||
// Read final packing (uint32_t = 0)
|
||||
uint32_t finalPacking;
|
||||
ASSERT_TRUE(mailInfoStream.Read(finalPacking));
|
||||
ASSERT_EQ(finalPacking, 0);
|
||||
|
||||
// Verify we've read all the data
|
||||
ASSERT_EQ(mailInfoStream.GetNumberOfUnreadBits(), 0);
|
||||
}
|
||||
|
||||
// Test SendResponse packet serialization
|
||||
TEST_F(MailTests, SendResponseSerialization) {
|
||||
Mail::SendResponse sendResponse;
|
||||
sendResponse.status = Mail::eSendResponse::Success;
|
||||
|
||||
RakNet::BitStream outStream;
|
||||
sendResponse.Serialize(outStream);
|
||||
|
||||
// Verify the stream contains data
|
||||
ASSERT_GT(outStream.GetNumberOfBytesUsed(), 0);
|
||||
|
||||
// Verify message ID and status are written
|
||||
outStream.ResetReadPointer();
|
||||
uint32_t messageID;
|
||||
uint32_t status;
|
||||
ASSERT_TRUE(outStream.Read(messageID));
|
||||
ASSERT_TRUE(outStream.Read(status));
|
||||
ASSERT_EQ(messageID, static_cast<uint32_t>(Mail::eMessageID::SendResponse));
|
||||
ASSERT_EQ(status, static_cast<uint32_t>(Mail::eSendResponse::Success));
|
||||
}
|
||||
|
||||
// Test NotificationResponse packet serialization
|
||||
TEST_F(MailTests, NotificationResponseSerialization) {
|
||||
Mail::NotificationResponse notificationResponse;
|
||||
notificationResponse.status = Mail::eNotificationResponse::NewMail;
|
||||
notificationResponse.auctionID = 12345;
|
||||
notificationResponse.mailCount = 3;
|
||||
|
||||
RakNet::BitStream outStream;
|
||||
notificationResponse.Serialize(outStream);
|
||||
|
||||
// Verify the stream contains data
|
||||
ASSERT_GT(outStream.GetNumberOfBytesUsed(), 0);
|
||||
|
||||
// Verify message ID and fields are written in the correct order
|
||||
// Order: messageID, status, unused, unused, auctionID, unused, mailCount, packing
|
||||
outStream.ResetReadPointer();
|
||||
uint32_t messageID;
|
||||
uint32_t status;
|
||||
uint64_t unused1, unused2, auctionID, unused3;
|
||||
uint32_t mailCount, packing;
|
||||
ASSERT_TRUE(outStream.Read(messageID));
|
||||
ASSERT_TRUE(outStream.Read(status));
|
||||
ASSERT_TRUE(outStream.Read(unused1));
|
||||
ASSERT_TRUE(outStream.Read(unused2));
|
||||
ASSERT_TRUE(outStream.Read(auctionID));
|
||||
ASSERT_TRUE(outStream.Read(unused3));
|
||||
ASSERT_TRUE(outStream.Read(mailCount));
|
||||
ASSERT_TRUE(outStream.Read(packing));
|
||||
ASSERT_EQ(messageID, static_cast<uint32_t>(Mail::eMessageID::NotificationResponse));
|
||||
ASSERT_EQ(status, static_cast<uint32_t>(Mail::eNotificationResponse::NewMail));
|
||||
ASSERT_EQ(auctionID, 12345);
|
||||
ASSERT_EQ(mailCount, 3);
|
||||
}
|
||||
|
||||
// Test DataResponse packet serialization
|
||||
TEST_F(MailTests, DataResponseSerialization) {
|
||||
Mail::DataResponse dataResponse;
|
||||
dataResponse.throttled = 0;
|
||||
|
||||
// Add some mail info
|
||||
MailInfo mail1, mail2;
|
||||
mail1.senderUsername = "Sender1";
|
||||
mail1.recipient = "Recipient1";
|
||||
mail1.subject = "Subject1";
|
||||
mail1.body = "Body1";
|
||||
mail1.id = 1;
|
||||
mail1.senderId = 100;
|
||||
mail1.receiverId = 200;
|
||||
mail1.timeSent = 1640995200;
|
||||
mail1.wasRead = false;
|
||||
mail1.languageCode = 1033;
|
||||
mail1.itemID = LWOOBJID_EMPTY;
|
||||
mail1.itemCount = 0;
|
||||
mail1.itemLOT = LOT_NULL;
|
||||
mail1.itemSubkey = LWOOBJID_EMPTY;
|
||||
|
||||
mail2.senderUsername = "Sender2";
|
||||
mail2.recipient = "Recipient2";
|
||||
mail2.subject = "Subject2";
|
||||
mail2.body = "Body2";
|
||||
mail2.id = 2;
|
||||
mail2.senderId = 300;
|
||||
mail2.receiverId = 400;
|
||||
mail2.timeSent = 1640995300;
|
||||
mail2.wasRead = true;
|
||||
mail2.languageCode = 1033;
|
||||
mail2.itemID = 555;
|
||||
mail2.itemCount = 10;
|
||||
mail2.itemLOT = 1234;
|
||||
mail2.itemSubkey = 999;
|
||||
|
||||
dataResponse.playerMail.push_back(mail1);
|
||||
dataResponse.playerMail.push_back(mail2);
|
||||
|
||||
RakNet::BitStream outStream;
|
||||
dataResponse.Serialize(outStream);
|
||||
|
||||
// Verify the stream contains data
|
||||
ASSERT_GT(outStream.GetNumberOfBytesUsed(), 0);
|
||||
|
||||
// Verify message ID, throttled, and mail count are written
|
||||
outStream.ResetReadPointer();
|
||||
uint32_t messageID;
|
||||
uint32_t throttled;
|
||||
uint16_t mailCount;
|
||||
ASSERT_TRUE(outStream.Read(messageID));
|
||||
ASSERT_TRUE(outStream.Read(throttled));
|
||||
ASSERT_TRUE(outStream.Read(mailCount));
|
||||
ASSERT_EQ(messageID, static_cast<uint32_t>(Mail::eMessageID::DataResponse));
|
||||
ASSERT_EQ(throttled, 0);
|
||||
ASSERT_EQ(mailCount, 2);
|
||||
}
|
||||
|
||||
// Test AttachmentCollectRequest packet deserialization
|
||||
TEST_F(MailTests, AttachmentCollectRequestDeserialize) {
|
||||
// This test verifies the deserialization reads data in the correct order
|
||||
RakNet::BitStream inStream;
|
||||
uint32_t unknown = 123; // Unknown field that comes first
|
||||
uint64_t mailID = 12345;
|
||||
uint64_t playerID = 67890;
|
||||
|
||||
// The Deserialize method reads: unknown, mailID, playerID
|
||||
inStream.Write(unknown);
|
||||
inStream.Write(mailID);
|
||||
inStream.Write(playerID);
|
||||
|
||||
inStream.ResetReadPointer();
|
||||
Mail::AttachmentCollectRequest request;
|
||||
ASSERT_TRUE(request.Deserialize(inStream));
|
||||
|
||||
ASSERT_EQ(request.mailID, mailID);
|
||||
ASSERT_EQ(request.playerID, playerID);
|
||||
}
|
||||
|
||||
// Test AttachmentCollectResponse packet serialization
|
||||
TEST_F(MailTests, AttachmentCollectResponseSerialization) {
|
||||
Mail::AttachmentCollectResponse response;
|
||||
response.status = Mail::eAttachmentCollectResponse::Success;
|
||||
response.mailID = 54321;
|
||||
|
||||
RakNet::BitStream outStream;
|
||||
response.Serialize(outStream);
|
||||
|
||||
// Verify the stream contains data
|
||||
ASSERT_GT(outStream.GetNumberOfBytesUsed(), 0);
|
||||
|
||||
// Verify message ID, status, and mail ID are written
|
||||
outStream.ResetReadPointer();
|
||||
uint32_t messageID;
|
||||
uint32_t status;
|
||||
uint64_t mailID;
|
||||
ASSERT_TRUE(outStream.Read(messageID));
|
||||
ASSERT_TRUE(outStream.Read(status));
|
||||
ASSERT_TRUE(outStream.Read(mailID));
|
||||
ASSERT_EQ(messageID, static_cast<uint32_t>(Mail::eMessageID::AttachmentCollectResponse));
|
||||
ASSERT_EQ(status, static_cast<uint32_t>(Mail::eAttachmentCollectResponse::Success));
|
||||
ASSERT_EQ(mailID, 54321);
|
||||
}
|
||||
|
||||
// Test DeleteRequest packet deserialization
|
||||
TEST_F(MailTests, DeleteRequestDeserialize) {
|
||||
// This test verifies the deserialization reads data in the correct order
|
||||
RakNet::BitStream inStream;
|
||||
int32_t unknown = 456; // Unknown field that comes first
|
||||
uint64_t mailID = 98765;
|
||||
uint64_t playerID = 11111;
|
||||
|
||||
// The Deserialize method reads: unknown, mailID, playerID
|
||||
inStream.Write(unknown);
|
||||
inStream.Write(mailID);
|
||||
inStream.Write(playerID);
|
||||
|
||||
inStream.ResetReadPointer();
|
||||
Mail::DeleteRequest request;
|
||||
ASSERT_TRUE(request.Deserialize(inStream));
|
||||
|
||||
ASSERT_EQ(request.mailID, mailID);
|
||||
ASSERT_EQ(request.playerID, playerID);
|
||||
}
|
||||
|
||||
// Test DeleteResponse packet serialization
|
||||
TEST_F(MailTests, DeleteResponseSerialization) {
|
||||
Mail::DeleteResponse response;
|
||||
response.status = Mail::eDeleteResponse::Success;
|
||||
response.mailID = 13579;
|
||||
|
||||
RakNet::BitStream outStream;
|
||||
response.Serialize(outStream);
|
||||
|
||||
// Verify the stream contains data
|
||||
ASSERT_GT(outStream.GetNumberOfBytesUsed(), 0);
|
||||
|
||||
// Verify message ID, status, and mail ID are written
|
||||
outStream.ResetReadPointer();
|
||||
uint32_t messageID;
|
||||
uint32_t status;
|
||||
uint64_t mailID;
|
||||
ASSERT_TRUE(outStream.Read(messageID));
|
||||
ASSERT_TRUE(outStream.Read(status));
|
||||
ASSERT_TRUE(outStream.Read(mailID));
|
||||
ASSERT_EQ(messageID, static_cast<uint32_t>(Mail::eMessageID::DeleteResponse));
|
||||
ASSERT_EQ(status, static_cast<uint32_t>(Mail::eDeleteResponse::Success));
|
||||
ASSERT_EQ(mailID, 13579);
|
||||
}
|
||||
|
||||
// Test ReadRequest packet deserialization
|
||||
TEST_F(MailTests, ReadRequestDeserialize) {
|
||||
// This test verifies the deserialization reads data in the correct order
|
||||
RakNet::BitStream inStream;
|
||||
int32_t unknown = 789; // Unknown field that comes first
|
||||
uint64_t mailID = 24680;
|
||||
|
||||
// The Deserialize method reads: unknown, mailID
|
||||
inStream.Write(unknown);
|
||||
inStream.Write(mailID);
|
||||
|
||||
inStream.ResetReadPointer();
|
||||
Mail::ReadRequest request;
|
||||
ASSERT_TRUE(request.Deserialize(inStream));
|
||||
|
||||
ASSERT_EQ(request.mailID, mailID);
|
||||
}
|
||||
|
||||
// Test ReadResponse packet serialization
|
||||
TEST_F(MailTests, ReadResponseSerialization) {
|
||||
Mail::ReadResponse response;
|
||||
response.mailID = 97531;
|
||||
response.status = Mail::eReadResponse::Success;
|
||||
|
||||
RakNet::BitStream outStream;
|
||||
response.Serialize(outStream);
|
||||
|
||||
// Verify the stream contains data
|
||||
ASSERT_GT(outStream.GetNumberOfBytesUsed(), 0);
|
||||
|
||||
// Verify message ID, status, and mail ID are written in correct order
|
||||
outStream.ResetReadPointer();
|
||||
uint32_t messageID;
|
||||
uint32_t status;
|
||||
uint64_t mailID;
|
||||
ASSERT_TRUE(outStream.Read(messageID));
|
||||
ASSERT_TRUE(outStream.Read(status));
|
||||
ASSERT_TRUE(outStream.Read(mailID));
|
||||
ASSERT_EQ(messageID, static_cast<uint32_t>(Mail::eMessageID::ReadResponse));
|
||||
ASSERT_EQ(status, static_cast<uint32_t>(Mail::eReadResponse::Success));
|
||||
ASSERT_EQ(mailID, 97531);
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
set(DCOMPONENTS_TESTS
|
||||
"DestroyableComponentTests.cpp"
|
||||
"PetComponentTests.cpp"
|
||||
"SimplePhysicsComponentTests.cpp"
|
||||
"SavingTests.cpp"
|
||||
"DestroyableComponentTests.cpp"
|
||||
"PetComponentTests.cpp"
|
||||
"SimplePhysicsComponentTests.cpp"
|
||||
"SavingTests.cpp"
|
||||
)
|
||||
|
||||
# Get the folder name and prepend it to the files above
|
||||
|
||||
28
tests/dNetTests/AuthPacketTests.cpp
Normal file
28
tests/dNetTests/AuthPacketTests.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "TestCommon.h"
|
||||
#include "AuthPackets.h"
|
||||
#include "MessageType/Auth.h"
|
||||
|
||||
class AuthPacketTests : public PacketTestsBase {};
|
||||
|
||||
// ===== AuthPackets Tests =====
|
||||
|
||||
TEST_F(AuthPacketTests, AuthStampSerialization) {
|
||||
Stamp testStamp(eStamps::PASSPORT_AUTH_START, 12345, 1609459200); // Jan 1, 2021 timestamp
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
testStamp.Serialize(bitStream);
|
||||
|
||||
// Verify serialized data
|
||||
eStamps readType;
|
||||
uint32_t readValue;
|
||||
uint64_t readTimestamp;
|
||||
|
||||
bitStream.Read(readType);
|
||||
bitStream.Read(readValue);
|
||||
bitStream.Read(readTimestamp);
|
||||
|
||||
ASSERT_EQ(readType, eStamps::PASSPORT_AUTH_START);
|
||||
ASSERT_EQ(readValue, 12345u);
|
||||
ASSERT_EQ(readTimestamp, 1609459200u);
|
||||
ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0);
|
||||
}
|
||||
26
tests/dNetTests/CMakeLists.txt
Normal file
26
tests/dNetTests/CMakeLists.txt
Normal file
@@ -0,0 +1,26 @@
|
||||
set(DNETTESTS_SOURCES
|
||||
"TestCommon.cpp"
|
||||
"AuthPacketTests.cpp"
|
||||
"ChatPacketTests.cpp"
|
||||
"WorldPacketTests.cpp"
|
||||
"MasterPacketTests.cpp"
|
||||
"PacketEdgeCaseTests.cpp"
|
||||
"MailBitStreamTests.cpp"
|
||||
)
|
||||
|
||||
# Set our executable
|
||||
add_executable(dNetTests ${DNETTESTS_SOURCES})
|
||||
|
||||
# Needs to be in binary dir for ctest
|
||||
if(APPLE)
|
||||
add_custom_target(dNetTestsLink
|
||||
${CMAKE_COMMAND} -E copy $<TARGET_FILE:MariaDB::ConnCpp> ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
add_dependencies(dNetTests dNetTestsLink)
|
||||
endif()
|
||||
|
||||
# Link needed libraries
|
||||
target_link_libraries(dNetTests ${COMMON_LIBRARIES} GTest::gtest_main dNet)
|
||||
|
||||
# Discover the tests
|
||||
gtest_discover_tests(dNetTests)
|
||||
207
tests/dNetTests/ChatPacketTests.cpp
Normal file
207
tests/dNetTests/ChatPacketTests.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
#include "TestCommon.h"
|
||||
#include "ChatPackets.h"
|
||||
#include "ClientPackets.h"
|
||||
#include "MessageType/Chat.h"
|
||||
#include "MessageType/Client.h"
|
||||
|
||||
class ChatPacketTests : public PacketTestsBase {};
|
||||
|
||||
// ===== ChatPackets Tests =====
|
||||
|
||||
TEST_F(ChatPacketTests, ChatShowAllRequestSerialization) {
|
||||
ShowAllRequest request;
|
||||
request.requestor = 123456789;
|
||||
request.displayZoneData = true;
|
||||
request.displayIndividualPlayers = false;
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
request.Serialize(bitStream);
|
||||
|
||||
VerifyHeader(&bitStream, ServiceType::CHAT, static_cast<uint32_t>(MessageType::Chat::SHOW_ALL));
|
||||
|
||||
LWOOBJID readRequestor;
|
||||
bool readDisplayZoneData;
|
||||
bool readDisplayIndividualPlayers;
|
||||
|
||||
bitStream.Read(readRequestor);
|
||||
bitStream.Read(readDisplayZoneData);
|
||||
bitStream.Read(readDisplayIndividualPlayers);
|
||||
|
||||
ASSERT_EQ(readRequestor, 123456789);
|
||||
ASSERT_EQ(readDisplayZoneData, true);
|
||||
ASSERT_EQ(readDisplayIndividualPlayers, false);
|
||||
ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0);
|
||||
}
|
||||
|
||||
TEST_F(ChatPacketTests, ChatShowAllRequestRoundTrip) {
|
||||
ShowAllRequest original;
|
||||
original.requestor = 987654321;
|
||||
original.displayZoneData = false;
|
||||
original.displayIndividualPlayers = true;
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
original.Serialize(bitStream);
|
||||
|
||||
// Skip header for deserialization
|
||||
uint8_t rakNetPacketId{};
|
||||
uint16_t serviceType{};
|
||||
uint32_t packetId{};
|
||||
uint8_t always0{};
|
||||
bitStream.Read(rakNetPacketId);
|
||||
bitStream.Read(serviceType);
|
||||
bitStream.Read(packetId);
|
||||
bitStream.Read(always0);
|
||||
|
||||
ShowAllRequest deserialized;
|
||||
deserialized.Deserialize(bitStream);
|
||||
|
||||
ASSERT_EQ(deserialized.requestor, original.requestor);
|
||||
ASSERT_EQ(deserialized.displayZoneData, original.displayZoneData);
|
||||
ASSERT_EQ(deserialized.displayIndividualPlayers, original.displayIndividualPlayers);
|
||||
}
|
||||
|
||||
TEST_F(ChatPacketTests, ChatFindPlayerRequestSerialization) {
|
||||
FindPlayerRequest request;
|
||||
request.requestor = 555555555;
|
||||
request.playerName = LUWString(u"TestPlayer123");
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
request.Serialize(bitStream);
|
||||
|
||||
VerifyHeader(&bitStream, ServiceType::CHAT, static_cast<uint32_t>(MessageType::Chat::WHO));
|
||||
|
||||
LWOOBJID readRequestor;
|
||||
LUWString readPlayerName;
|
||||
|
||||
bitStream.Read(readRequestor);
|
||||
bitStream.Read(readPlayerName);
|
||||
|
||||
ASSERT_EQ(readRequestor, 555555555);
|
||||
ASSERT_EQ(readPlayerName.string, u"TestPlayer123");
|
||||
ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0);
|
||||
}
|
||||
|
||||
TEST_F(ChatPacketTests, ChatFindPlayerRequestRoundTrip) {
|
||||
FindPlayerRequest original;
|
||||
original.requestor = 777777777;
|
||||
original.playerName = LUWString(u"PlayerToFind");
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
original.Serialize(bitStream);
|
||||
|
||||
// Skip header for deserialization
|
||||
uint8_t rakNetPacketId{};
|
||||
uint16_t serviceType{};
|
||||
uint32_t packetId{};
|
||||
uint8_t always0{};
|
||||
bitStream.Read(rakNetPacketId);
|
||||
bitStream.Read(serviceType);
|
||||
bitStream.Read(packetId);
|
||||
bitStream.Read(always0);
|
||||
|
||||
FindPlayerRequest deserialized;
|
||||
deserialized.Deserialize(bitStream);
|
||||
|
||||
ASSERT_EQ(deserialized.requestor, original.requestor);
|
||||
ASSERT_EQ(deserialized.playerName.string, original.playerName.string);
|
||||
}
|
||||
|
||||
TEST_F(ChatPacketTests, ChatAnnouncementSerialization) {
|
||||
ChatPackets::Announcement announcement;
|
||||
announcement.title = "Test Title";
|
||||
announcement.message = "Test announcement message";
|
||||
|
||||
// Call Send which will add header and serialize
|
||||
announcement.Send(UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
auto* bitStream = GetMostRecentBitStream();
|
||||
VerifyHeader(bitStream, ServiceType::CHAT, static_cast<uint32_t>(MessageType::Chat::GM_ANNOUNCE));
|
||||
|
||||
// Read announcement data (size prefixed strings)
|
||||
uint32_t titleSize;
|
||||
bitStream->Read(titleSize);
|
||||
ASSERT_EQ(titleSize, announcement.title.size());
|
||||
|
||||
std::string readTitle(titleSize, '\0');
|
||||
bitStream->ReadBits(reinterpret_cast<unsigned char*>(readTitle.data()), BYTES_TO_BITS(titleSize), true);
|
||||
|
||||
uint32_t messageSize;
|
||||
bitStream->Read(messageSize);
|
||||
ASSERT_EQ(messageSize, announcement.message.size());
|
||||
|
||||
std::string readMessage(messageSize, '\0');
|
||||
bitStream->ReadBits(reinterpret_cast<unsigned char*>(readMessage.data()), BYTES_TO_BITS(messageSize), true);
|
||||
|
||||
ASSERT_EQ(readTitle, "Test Title");
|
||||
ASSERT_EQ(readMessage, "Test announcement message");
|
||||
ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 0);
|
||||
}
|
||||
|
||||
TEST_F(ChatPacketTests, ChatAchievementNotifySerialization) {
|
||||
ChatPackets::AchievementNotify notify;
|
||||
notify.targetPlayerName = LUWString(u"TargetPlayer");
|
||||
notify.missionEmailID = 12345;
|
||||
notify.earningPlayerID = 987654321;
|
||||
notify.earnerName = LUWString(u"EarnerPlayer");
|
||||
|
||||
// Call Send which will add header and serialize
|
||||
notify.Send(UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
auto* bitStream = GetMostRecentBitStream();
|
||||
VerifyHeader(bitStream, ServiceType::CHAT, static_cast<uint32_t>(MessageType::Chat::ACHIEVEMENT_NOTIFY));
|
||||
|
||||
// Read achievement data based on actual Serialize implementation
|
||||
// Order: packing(13), earnerName, packing(15), missionEmailID, earningPlayerID, targetPlayerName
|
||||
uint64_t packing1;
|
||||
uint32_t packing2;
|
||||
uint8_t packing3;
|
||||
LUWString readEarnerName;
|
||||
uint64_t packing4;
|
||||
uint32_t packing5;
|
||||
uint16_t packing6;
|
||||
uint8_t packing7;
|
||||
uint32_t readMissionEmailID;
|
||||
LWOOBJID readEarningPlayerID;
|
||||
LUWString readTargetPlayerName;
|
||||
|
||||
bitStream->Read(packing1);
|
||||
bitStream->Read(packing2);
|
||||
bitStream->Read(packing3);
|
||||
bitStream->Read(readEarnerName);
|
||||
bitStream->Read(packing4);
|
||||
bitStream->Read(packing5);
|
||||
bitStream->Read(packing6);
|
||||
bitStream->Read(packing7);
|
||||
bitStream->Read(readMissionEmailID);
|
||||
bitStream->Read(readEarningPlayerID);
|
||||
bitStream->Read(readTargetPlayerName);
|
||||
|
||||
ASSERT_EQ(readEarnerName.string, u"EarnerPlayer");
|
||||
ASSERT_EQ(readMissionEmailID, 12345u);
|
||||
ASSERT_EQ(readEarningPlayerID, 987654321);
|
||||
ASSERT_EQ(readTargetPlayerName.string, u"TargetPlayer");
|
||||
ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 0);
|
||||
}
|
||||
|
||||
TEST_F(ChatPacketTests, ChatTeamInviteInitialResponseSerialization) {
|
||||
ChatPackets::TeamInviteInitialResponse response;
|
||||
response.inviteFailedToSend = true;
|
||||
response.playerName = LUWString(u"InviteePlayer");
|
||||
|
||||
// Call Send which will add header and serialize
|
||||
response.Send(UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
auto* bitStream = GetMostRecentBitStream();
|
||||
VerifyHeader(bitStream, ServiceType::CLIENT, static_cast<uint32_t>(MessageType::Client::TEAM_INVITE_INITIAL_RESPONSE));
|
||||
|
||||
// Read team invite response data
|
||||
uint8_t readInviteFailedToSend; // Written as uint8_t in actual implementation
|
||||
LUWString readPlayerName;
|
||||
|
||||
bitStream->Read(readInviteFailedToSend);
|
||||
bitStream->Read(readPlayerName);
|
||||
|
||||
ASSERT_EQ(readInviteFailedToSend, static_cast<uint8_t>(true));
|
||||
ASSERT_EQ(readPlayerName.string, u"InviteePlayer");
|
||||
ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 0);
|
||||
}
|
||||
269
tests/dNetTests/MailBitStreamTests.cpp
Normal file
269
tests/dNetTests/MailBitStreamTests.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
#include "TestCommon.h"
|
||||
#include "MailInfo.h"
|
||||
#include "dCommonVars.h"
|
||||
|
||||
class MailBitStreamTests : public PacketTestsBase {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
PacketTestsBase::SetUp();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
PacketTestsBase::TearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to create a sample MailInfo for testing
|
||||
*/
|
||||
MailInfo CreateSampleMailInfo() {
|
||||
MailInfo mailInfo;
|
||||
mailInfo.senderUsername = "TestSender";
|
||||
mailInfo.recipient = "TestRecipient";
|
||||
mailInfo.subject = "Test Subject";
|
||||
mailInfo.body = "Test body message";
|
||||
mailInfo.id = 12345;
|
||||
mailInfo.senderId = 67890;
|
||||
mailInfo.receiverId = 11111;
|
||||
mailInfo.timeSent = 1234567890;
|
||||
mailInfo.wasRead = false;
|
||||
mailInfo.languageCode = 1033;
|
||||
mailInfo.itemID = LWOOBJID_EMPTY;
|
||||
mailInfo.itemCount = 0;
|
||||
mailInfo.itemLOT = LOT_NULL;
|
||||
mailInfo.itemSubkey = LWOOBJID_EMPTY;
|
||||
return mailInfo;
|
||||
}
|
||||
};
|
||||
|
||||
// Test basic MailInfo serialization
|
||||
TEST_F(MailBitStreamTests, MailInfoBasicSerialization) {
|
||||
MailInfo originalMail = CreateSampleMailInfo();
|
||||
|
||||
RakNet::BitStream outStream;
|
||||
originalMail.Serialize(outStream);
|
||||
|
||||
// Verify the serialized data structure - basic sanity check
|
||||
ASSERT_GT(outStream.GetNumberOfBytesUsed(), 0);
|
||||
|
||||
// MailInfo serialization includes id, subject, body, sender, and various item data
|
||||
// Let's verify the first field (id) is written correctly
|
||||
outStream.ResetReadPointer();
|
||||
|
||||
uint64_t readId;
|
||||
outStream.Read(readId);
|
||||
ASSERT_EQ(readId, originalMail.id);
|
||||
}
|
||||
|
||||
// Test MailInfo serialization with item attachment
|
||||
TEST_F(MailBitStreamTests, MailInfoWithAttachmentSerialization) {
|
||||
MailInfo originalMail = CreateSampleMailInfo();
|
||||
originalMail.itemID = 999888777;
|
||||
originalMail.itemCount = 5;
|
||||
originalMail.itemLOT = 1234;
|
||||
originalMail.itemSubkey = 555444333;
|
||||
|
||||
RakNet::BitStream outStream;
|
||||
originalMail.Serialize(outStream);
|
||||
|
||||
// Verify the serialized data includes all our data
|
||||
ASSERT_GT(outStream.GetNumberOfBytesUsed(), 0);
|
||||
|
||||
// Reset and verify id
|
||||
outStream.ResetReadPointer();
|
||||
uint64_t readId;
|
||||
outStream.Read(readId);
|
||||
ASSERT_EQ(readId, originalMail.id);
|
||||
}
|
||||
|
||||
// Test MailInfo serialization with different attachment scenarios
|
||||
TEST_F(MailBitStreamTests, MailInfoVariousAttachmentScenarios) {
|
||||
// Test with no attachment
|
||||
{
|
||||
MailInfo noAttachment = CreateSampleMailInfo();
|
||||
noAttachment.itemID = LWOOBJID_EMPTY;
|
||||
noAttachment.itemCount = 0;
|
||||
noAttachment.itemLOT = LOT_NULL;
|
||||
noAttachment.itemSubkey = LWOOBJID_EMPTY;
|
||||
|
||||
RakNet::BitStream outStream;
|
||||
noAttachment.Serialize(outStream);
|
||||
|
||||
ASSERT_GT(outStream.GetNumberOfBytesUsed(), 0);
|
||||
outStream.ResetReadPointer();
|
||||
uint64_t readId;
|
||||
outStream.Read(readId);
|
||||
ASSERT_EQ(readId, noAttachment.id);
|
||||
}
|
||||
|
||||
// Test with attachment
|
||||
{
|
||||
MailInfo withAttachment = CreateSampleMailInfo();
|
||||
withAttachment.itemID = 123456789;
|
||||
withAttachment.itemCount = 5;
|
||||
withAttachment.itemLOT = 9876;
|
||||
withAttachment.itemSubkey = 555666777;
|
||||
|
||||
RakNet::BitStream outStream;
|
||||
withAttachment.Serialize(outStream);
|
||||
|
||||
ASSERT_GT(outStream.GetNumberOfBytesUsed(), 0);
|
||||
outStream.ResetReadPointer();
|
||||
uint64_t readId;
|
||||
outStream.Read(readId);
|
||||
ASSERT_EQ(readId, withAttachment.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Test MailInfo serialization consistency
|
||||
TEST_F(MailBitStreamTests, MailInfoSerializationConsistency) {
|
||||
MailInfo originalMail = CreateSampleMailInfo();
|
||||
originalMail.itemID = 111222333;
|
||||
originalMail.itemCount = 7;
|
||||
originalMail.itemLOT = 5678;
|
||||
originalMail.itemSubkey = 444555666;
|
||||
|
||||
// Serialize the same mail multiple times
|
||||
RakNet::BitStream stream1, stream2, stream3;
|
||||
|
||||
originalMail.Serialize(stream1);
|
||||
originalMail.Serialize(stream2);
|
||||
originalMail.Serialize(stream3);
|
||||
|
||||
// All streams should have the same number of bytes
|
||||
ASSERT_EQ(stream1.GetNumberOfBytesUsed(), stream2.GetNumberOfBytesUsed());
|
||||
ASSERT_EQ(stream2.GetNumberOfBytesUsed(), stream3.GetNumberOfBytesUsed());
|
||||
|
||||
// And the same data content
|
||||
std::vector<uint8_t> data1(stream1.GetNumberOfBytesUsed());
|
||||
std::vector<uint8_t> data2(stream2.GetNumberOfBytesUsed());
|
||||
std::vector<uint8_t> data3(stream3.GetNumberOfBytesUsed());
|
||||
|
||||
memcpy(data1.data(), stream1.GetData(), stream1.GetNumberOfBytesUsed());
|
||||
memcpy(data2.data(), stream2.GetData(), stream2.GetNumberOfBytesUsed());
|
||||
memcpy(data3.data(), stream3.GetData(), stream3.GetNumberOfBytesUsed());
|
||||
|
||||
ASSERT_EQ(data1, data2);
|
||||
ASSERT_EQ(data2, data3);
|
||||
}
|
||||
|
||||
// Test MailInfo with Unicode characters
|
||||
TEST_F(MailBitStreamTests, MailInfoUnicodeHandling) {
|
||||
MailInfo originalMail = CreateSampleMailInfo();
|
||||
originalMail.subject = "テストメール"; // "Test Mail" in Japanese
|
||||
originalMail.body = "これはテストメッセージです。"; // "This is a test message" in Japanese
|
||||
originalMail.senderUsername = "プレイヤー1"; // "Player 1" in Japanese
|
||||
|
||||
RakNet::BitStream outStream;
|
||||
originalMail.Serialize(outStream);
|
||||
|
||||
// Verify data was written
|
||||
ASSERT_GT(outStream.GetNumberOfBytesUsed(), 0);
|
||||
|
||||
// Since we can't easily deserialize (it doesn't read all fields),
|
||||
// we just verify that Unicode content can be serialized without errors
|
||||
outStream.ResetReadPointer();
|
||||
uint64_t readId;
|
||||
outStream.Read(readId);
|
||||
ASSERT_EQ(readId, originalMail.id);
|
||||
}
|
||||
|
||||
// Test MailInfo edge cases with special values
|
||||
TEST_F(MailBitStreamTests, MailInfoEdgeCases) {
|
||||
MailInfo originalMail = CreateSampleMailInfo();
|
||||
|
||||
// Test with special/edge case values
|
||||
originalMail.id = 0; // Zero ID
|
||||
originalMail.itemID = LWOOBJID_EMPTY; // Special empty value
|
||||
originalMail.itemCount = -1; // Negative count
|
||||
originalMail.itemLOT = LOT_NULL; // Null LOT
|
||||
originalMail.timeSent = 0; // Zero time
|
||||
|
||||
RakNet::BitStream outStream;
|
||||
originalMail.Serialize(outStream);
|
||||
|
||||
ASSERT_GT(outStream.GetNumberOfBytesUsed(), 0);
|
||||
|
||||
// Verify the ID field
|
||||
outStream.ResetReadPointer();
|
||||
uint64_t readId;
|
||||
outStream.Read(readId);
|
||||
ASSERT_EQ(readId, 0);
|
||||
}
|
||||
|
||||
// Test MailInfo with very long strings that get truncated
|
||||
TEST_F(MailBitStreamTests, MailInfoStringTruncation) {
|
||||
MailInfo originalMail = CreateSampleMailInfo();
|
||||
|
||||
// Create strings longer than the allowed maximums
|
||||
originalMail.subject = std::string(100, 'S'); // Longer than 50 char limit
|
||||
originalMail.body = std::string(500, 'B'); // Longer than 400 char limit
|
||||
originalMail.senderUsername = std::string(50, 'U'); // Longer than 32 char limit
|
||||
|
||||
RakNet::BitStream outStream;
|
||||
originalMail.Serialize(outStream);
|
||||
|
||||
// Should still serialize successfully (LUWString handles truncation)
|
||||
ASSERT_GT(outStream.GetNumberOfBytesUsed(), 0);
|
||||
|
||||
outStream.ResetReadPointer();
|
||||
uint64_t readId;
|
||||
outStream.Read(readId);
|
||||
ASSERT_EQ(readId, originalMail.id);
|
||||
}
|
||||
|
||||
// Test MailInfo data integrity across field types
|
||||
TEST_F(MailBitStreamTests, MailInfoDataTypeIntegrity) {
|
||||
MailInfo originalMail = CreateSampleMailInfo();
|
||||
|
||||
// Test with specific values to verify data types are handled correctly
|
||||
originalMail.id = 0xFFFFFFFFFFFFFFFF; // Max uint64_t
|
||||
originalMail.senderId = 0xFFFFFFFF; // Max uint32_t
|
||||
originalMail.receiverId = 0xFFFFFFFF; // Max uint32_t
|
||||
originalMail.timeSent = 0xFFFFFFFFFFFFFFFF; // Max uint64_t
|
||||
originalMail.wasRead = true;
|
||||
originalMail.languageCode = 0xFFFF; // Max uint16_t
|
||||
originalMail.itemID = 0xFFFFFFFFFFFFFFFF; // Max LWOOBJID
|
||||
originalMail.itemCount = 32767; // Max int16_t positive value
|
||||
originalMail.itemSubkey = 0xFFFFFFFFFFFFFFFF; // Max LWOOBJID
|
||||
|
||||
RakNet::BitStream outStream;
|
||||
originalMail.Serialize(outStream);
|
||||
|
||||
ASSERT_GT(outStream.GetNumberOfBytesUsed(), 0);
|
||||
|
||||
// Verify the first field (id)
|
||||
outStream.ResetReadPointer();
|
||||
uint64_t readId;
|
||||
outStream.Read(readId);
|
||||
ASSERT_EQ(readId, 0xFFFFFFFFFFFFFFFF);
|
||||
}
|
||||
|
||||
// Test MailInfo with empty/minimal data
|
||||
TEST_F(MailBitStreamTests, MailInfoMinimalData) {
|
||||
MailInfo minimalMail;
|
||||
// Set only required/essential fields
|
||||
minimalMail.id = 1;
|
||||
minimalMail.subject = "";
|
||||
minimalMail.body = "";
|
||||
minimalMail.senderUsername = "";
|
||||
minimalMail.recipient = "";
|
||||
minimalMail.senderId = 0;
|
||||
minimalMail.receiverId = 0;
|
||||
minimalMail.timeSent = 0;
|
||||
minimalMail.wasRead = false;
|
||||
minimalMail.languageCode = 0;
|
||||
minimalMail.itemID = 0;
|
||||
minimalMail.itemCount = 0;
|
||||
minimalMail.itemLOT = 0;
|
||||
minimalMail.itemSubkey = 0;
|
||||
|
||||
RakNet::BitStream outStream;
|
||||
minimalMail.Serialize(outStream);
|
||||
|
||||
ASSERT_GT(outStream.GetNumberOfBytesUsed(), 0);
|
||||
|
||||
outStream.ResetReadPointer();
|
||||
uint64_t readId;
|
||||
outStream.Read(readId);
|
||||
ASSERT_EQ(readId, 1);
|
||||
}
|
||||
69
tests/dNetTests/MasterPacketTests.cpp
Normal file
69
tests/dNetTests/MasterPacketTests.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "TestCommon.h"
|
||||
#include "MasterPackets.h"
|
||||
#include "MessageType/Master.h"
|
||||
|
||||
class MasterPacketTests : public PacketTestsBase {};
|
||||
|
||||
// ===== MasterPackets Tests =====
|
||||
// Note: These tests verify packet structure creation, but cannot easily test SendToMaster
|
||||
// since it's not virtual. We can test the structure by calling the internal serialization.
|
||||
|
||||
TEST_F(MasterPacketTests, MasterPersistentIDResponseStructure) {
|
||||
uint64_t testRequestID = 9876543210987654321ULL;
|
||||
uint32_t testObjID = 555555;
|
||||
|
||||
MasterPackets::SendPersistentIDResponse(Game::server, UNASSIGNED_SYSTEM_ADDRESS, testRequestID, testObjID);
|
||||
|
||||
auto* bitStream = GetMostRecentBitStream();
|
||||
VerifyHeader(bitStream, ServiceType::MASTER, static_cast<uint32_t>(MessageType::Master::REQUEST_PERSISTENT_ID_RESPONSE));
|
||||
|
||||
uint64_t readRequestID;
|
||||
uint32_t readObjID;
|
||||
|
||||
bitStream->Read(readRequestID);
|
||||
bitStream->Read(readObjID);
|
||||
|
||||
ASSERT_EQ(readRequestID, testRequestID);
|
||||
ASSERT_EQ(readObjID, testObjID);
|
||||
ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 0);
|
||||
}
|
||||
|
||||
TEST_F(MasterPacketTests, MasterZoneTransferResponseStructure) {
|
||||
uint64_t testRequestID = 1111111111111111111ULL;
|
||||
bool testMythranShift = true;
|
||||
uint32_t testZoneID = 1000;
|
||||
uint32_t testZoneInstance = 5;
|
||||
uint32_t testZoneClone = 10;
|
||||
std::string testServerIP = "192.168.1.100";
|
||||
uint32_t testServerPort = 2002;
|
||||
|
||||
MasterPackets::SendZoneTransferResponse(Game::server, UNASSIGNED_SYSTEM_ADDRESS, testRequestID, testMythranShift, testZoneID, testZoneInstance, testZoneClone, testServerIP, testServerPort);
|
||||
|
||||
auto* bitStream = GetMostRecentBitStream();
|
||||
VerifyHeader(bitStream, ServiceType::MASTER, static_cast<uint32_t>(MessageType::Master::REQUEST_ZONE_TRANSFER_RESPONSE));
|
||||
|
||||
uint64_t readRequestID;
|
||||
uint8_t readMythranShift;
|
||||
uint32_t readZoneID;
|
||||
uint32_t readZoneInstance;
|
||||
uint32_t readZoneClone;
|
||||
uint16_t readServerPort; // Note: written as uint16_t in actual implementation
|
||||
LUString readServerIP(255); // Note: written as LUString with size 255
|
||||
|
||||
bitStream->Read(readRequestID);
|
||||
bitStream->Read(readMythranShift);
|
||||
bitStream->Read(readZoneID);
|
||||
bitStream->Read(readZoneInstance);
|
||||
bitStream->Read(readZoneClone);
|
||||
bitStream->Read(readServerPort);
|
||||
bitStream->Read(readServerIP);
|
||||
|
||||
ASSERT_EQ(readRequestID, testRequestID);
|
||||
ASSERT_EQ(readMythranShift, static_cast<uint8_t>(testMythranShift));
|
||||
ASSERT_EQ(readZoneID, testZoneID);
|
||||
ASSERT_EQ(readZoneInstance, testZoneInstance);
|
||||
ASSERT_EQ(readZoneClone, testZoneClone);
|
||||
ASSERT_EQ(readServerPort, static_cast<uint16_t>(testServerPort));
|
||||
ASSERT_EQ(readServerIP.string, testServerIP);
|
||||
ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 0);
|
||||
}
|
||||
154
tests/dNetTests/PacketEdgeCaseTests.cpp
Normal file
154
tests/dNetTests/PacketEdgeCaseTests.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
#include "TestCommon.h"
|
||||
#include "AuthPackets.h"
|
||||
#include "ChatPackets.h"
|
||||
#include "WorldPackets.h"
|
||||
|
||||
class PacketEdgeCaseTests : public PacketTestsBase {};
|
||||
|
||||
// ===== Edge Cases and Boundary Tests =====
|
||||
|
||||
TEST_F(PacketEdgeCaseTests, EmptyStringsHandling) {
|
||||
FindPlayerRequest request;
|
||||
request.requestor = 0;
|
||||
request.playerName = LUWString(u"");
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
request.Serialize(bitStream);
|
||||
|
||||
// Skip header
|
||||
uint8_t rakNetPacketId{};
|
||||
uint16_t serviceType{};
|
||||
uint32_t packetId{};
|
||||
uint8_t always0{};
|
||||
bitStream.Read(rakNetPacketId);
|
||||
bitStream.Read(serviceType);
|
||||
bitStream.Read(packetId);
|
||||
bitStream.Read(always0);
|
||||
|
||||
FindPlayerRequest deserialized;
|
||||
deserialized.Deserialize(bitStream);
|
||||
|
||||
ASSERT_EQ(deserialized.requestor, 0);
|
||||
ASSERT_EQ(deserialized.playerName.string, u"");
|
||||
}
|
||||
|
||||
TEST_F(PacketEdgeCaseTests, MaxValueHandling) {
|
||||
// Test with maximum values
|
||||
ShowAllRequest request;
|
||||
request.requestor = LWOOBJID_EMPTY; // Max LWOOBJID
|
||||
request.displayZoneData = true;
|
||||
request.displayIndividualPlayers = true;
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
request.Serialize(bitStream);
|
||||
|
||||
// Skip header
|
||||
uint8_t rakNetPacketId{};
|
||||
uint16_t serviceType{};
|
||||
uint32_t packetId{};
|
||||
uint8_t always0{};
|
||||
bitStream.Read(rakNetPacketId);
|
||||
bitStream.Read(serviceType);
|
||||
bitStream.Read(packetId);
|
||||
bitStream.Read(always0);
|
||||
|
||||
ShowAllRequest deserialized;
|
||||
deserialized.Deserialize(bitStream);
|
||||
|
||||
ASSERT_EQ(deserialized.requestor, LWOOBJID_EMPTY);
|
||||
ASSERT_EQ(deserialized.displayZoneData, true);
|
||||
ASSERT_EQ(deserialized.displayIndividualPlayers, true);
|
||||
}
|
||||
|
||||
TEST_F(PacketEdgeCaseTests, LongPasswordHandling) {
|
||||
// Test with a very long password for HTTPMonitorInfo (which has port field)
|
||||
HTTPMonitorInfo info;
|
||||
info.port = 65535; // Max port value
|
||||
info.openWeb = true;
|
||||
info.supportsSum = true;
|
||||
info.supportsDetail = true;
|
||||
info.supportsWho = true;
|
||||
info.supportsObjects = true;
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
info.Serialize(bitStream);
|
||||
|
||||
// Read serialized data
|
||||
uint16_t readPort;
|
||||
uint8_t readOpenWeb;
|
||||
uint8_t readSupportsSum;
|
||||
uint8_t readSupportsDetail;
|
||||
uint8_t readSupportsWho;
|
||||
uint8_t readSupportsObjects;
|
||||
|
||||
bitStream.Read(readPort);
|
||||
bitStream.Read(readOpenWeb);
|
||||
bitStream.Read(readSupportsSum);
|
||||
bitStream.Read(readSupportsDetail);
|
||||
bitStream.Read(readSupportsWho);
|
||||
bitStream.Read(readSupportsObjects);
|
||||
|
||||
ASSERT_EQ(readPort, 65535);
|
||||
ASSERT_EQ(readOpenWeb, 1);
|
||||
ASSERT_EQ(readSupportsSum, 1);
|
||||
ASSERT_EQ(readSupportsDetail, 1);
|
||||
ASSERT_EQ(readSupportsWho, 1);
|
||||
ASSERT_EQ(readSupportsObjects, 1);
|
||||
ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0);
|
||||
}
|
||||
|
||||
TEST_F(PacketEdgeCaseTests, PacketDataConsistency) {
|
||||
// Test that multiple calls produce identical results
|
||||
Stamp stamp1(eStamps::PASSPORT_AUTH_START, 100, 2000000000);
|
||||
Stamp stamp2(eStamps::PASSPORT_AUTH_START, 100, 2000000000);
|
||||
|
||||
RakNet::BitStream stream1, stream2;
|
||||
stamp1.Serialize(stream1);
|
||||
stamp2.Serialize(stream2);
|
||||
|
||||
// Should produce identical bit streams
|
||||
ASSERT_EQ(stream1.GetNumberOfBitsUsed(), stream2.GetNumberOfBitsUsed());
|
||||
|
||||
// Read both streams and compare
|
||||
eStamps type1, type2;
|
||||
uint32_t value1, value2;
|
||||
uint64_t timestamp1, timestamp2;
|
||||
|
||||
stream1.Read(type1);
|
||||
stream1.Read(value1);
|
||||
stream1.Read(timestamp1);
|
||||
|
||||
stream2.Read(type2);
|
||||
stream2.Read(value2);
|
||||
stream2.Read(timestamp2);
|
||||
|
||||
ASSERT_EQ(type1, type2);
|
||||
ASSERT_EQ(value1, value2);
|
||||
ASSERT_EQ(timestamp1, timestamp2);
|
||||
}
|
||||
|
||||
TEST_F(PacketEdgeCaseTests, UnicodeStringHandling) {
|
||||
// Test with various Unicode characters
|
||||
FindPlayerRequest request;
|
||||
request.requestor = 12345;
|
||||
request.playerName = LUWString(u"テストプレイヤー123"); // Japanese characters
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
request.Serialize(bitStream);
|
||||
|
||||
// Skip header
|
||||
uint8_t rakNetPacketId{};
|
||||
uint16_t serviceType{};
|
||||
uint32_t packetId{};
|
||||
uint8_t always0{};
|
||||
bitStream.Read(rakNetPacketId);
|
||||
bitStream.Read(serviceType);
|
||||
bitStream.Read(packetId);
|
||||
bitStream.Read(always0);
|
||||
|
||||
FindPlayerRequest deserialized;
|
||||
deserialized.Deserialize(bitStream);
|
||||
|
||||
ASSERT_EQ(deserialized.requestor, request.requestor);
|
||||
ASSERT_EQ(deserialized.playerName.string, request.playerName.string);
|
||||
}
|
||||
17
tests/dNetTests/TestCommon.cpp
Normal file
17
tests/dNetTests/TestCommon.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "TestCommon.h"
|
||||
|
||||
// Define Game namespace globals needed for linking
|
||||
namespace Game {
|
||||
Logger* logger = nullptr;
|
||||
dServer* server = nullptr;
|
||||
dZoneManager* zoneManager = nullptr;
|
||||
dChatFilter* chatFilter = nullptr;
|
||||
dConfig* config = nullptr;
|
||||
std::mt19937 randomEngine;
|
||||
RakPeerInterface* chatServer = nullptr;
|
||||
AssetManager* assetManager = nullptr;
|
||||
SystemAddress chatSysAddr;
|
||||
EntityManager* entityManager = nullptr;
|
||||
std::string projectVersion;
|
||||
signal_t lastSignal = 0;
|
||||
}
|
||||
101
tests/dNetTests/TestCommon.h
Normal file
101
tests/dNetTests/TestCommon.h
Normal file
@@ -0,0 +1,101 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <memory>
|
||||
|
||||
#include "BitStream.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "RakNetTypes.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "ServiceType.h"
|
||||
|
||||
// Game dependencies for mocking
|
||||
#include "Game.h"
|
||||
#include "dServer.h"
|
||||
|
||||
// Forward declarations to minimize dependencies
|
||||
class Logger;
|
||||
class dConfig;
|
||||
class AssetManager;
|
||||
class dZoneManager;
|
||||
class dChatFilter;
|
||||
class EntityManager;
|
||||
|
||||
// Define Game namespace globals needed for linking
|
||||
namespace Game {
|
||||
extern Logger* logger;
|
||||
extern dServer* server;
|
||||
extern dZoneManager* zoneManager;
|
||||
extern dChatFilter* chatFilter;
|
||||
extern dConfig* config;
|
||||
extern std::mt19937 randomEngine;
|
||||
extern RakPeerInterface* chatServer;
|
||||
extern AssetManager* assetManager;
|
||||
extern SystemAddress chatSysAddr;
|
||||
extern EntityManager* entityManager;
|
||||
extern std::string projectVersion;
|
||||
extern signal_t lastSignal;
|
||||
}
|
||||
|
||||
// Simple mock server that captures bit streams for testing
|
||||
class dServerMock : public dServer {
|
||||
public:
|
||||
dServerMock() {}
|
||||
|
||||
RakNet::BitStream* GetMostRecentBitStream() {
|
||||
return this->m_MostRecentBitStream.get();
|
||||
}
|
||||
|
||||
void Send(RakNet::BitStream& bitStream, const SystemAddress& sysAddr, bool broadcast) override {
|
||||
this->m_MostRecentBitStream = std::make_unique<RakNet::BitStream>();
|
||||
*this->m_MostRecentBitStream = bitStream;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<RakNet::BitStream> m_MostRecentBitStream = nullptr;
|
||||
};
|
||||
|
||||
class PacketTestsBase : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
// Set up a minimal mock server for testing
|
||||
Game::server = new dServerMock();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
if (Game::server) {
|
||||
delete Game::server;
|
||||
Game::server = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get the most recent bit stream from the mock server
|
||||
*/
|
||||
RakNet::BitStream* GetMostRecentBitStream() {
|
||||
auto* server = static_cast<dServerMock*>(Game::server);
|
||||
return server->GetMostRecentBitStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to verify packet header
|
||||
*/
|
||||
void VerifyHeader(RakNet::BitStream* bitStream, ServiceType expectedServiceType, uint32_t expectedPacketId) {
|
||||
ASSERT_NE(bitStream, nullptr);
|
||||
|
||||
uint8_t rakNetPacketId{};
|
||||
uint16_t serviceType{};
|
||||
uint32_t packetId{};
|
||||
uint8_t always0{};
|
||||
|
||||
bitStream->Read(rakNetPacketId);
|
||||
bitStream->Read(serviceType);
|
||||
bitStream->Read(packetId);
|
||||
bitStream->Read(always0);
|
||||
|
||||
ASSERT_EQ(rakNetPacketId, 0x53); // ID_USER_PACKET_ENUM
|
||||
ASSERT_EQ(serviceType, static_cast<uint16_t>(expectedServiceType));
|
||||
ASSERT_EQ(packetId, expectedPacketId);
|
||||
ASSERT_EQ(always0, 0x00);
|
||||
}
|
||||
};
|
||||
110
tests/dNetTests/WorldPacketTests.cpp
Normal file
110
tests/dNetTests/WorldPacketTests.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#include "TestCommon.h"
|
||||
#include "WorldPackets.h"
|
||||
#include "MessageType/Client.h"
|
||||
#include "eRenameResponse.h"
|
||||
|
||||
class WorldPacketTests : public PacketTestsBase {};
|
||||
|
||||
// ===== WorldPackets Tests =====
|
||||
|
||||
TEST_F(WorldPacketTests, WorldHTTPMonitorInfoSerialization) {
|
||||
HTTPMonitorInfo info;
|
||||
info.port = 8080;
|
||||
info.openWeb = true;
|
||||
info.supportsSum = false;
|
||||
info.supportsDetail = true;
|
||||
info.supportsWho = false;
|
||||
info.supportsObjects = true;
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
info.Serialize(bitStream);
|
||||
|
||||
// Read serialized data
|
||||
uint16_t readPort;
|
||||
uint8_t readOpenWeb;
|
||||
uint8_t readSupportsSum;
|
||||
uint8_t readSupportsDetail;
|
||||
uint8_t readSupportsWho;
|
||||
uint8_t readSupportsObjects;
|
||||
|
||||
bitStream.Read(readPort);
|
||||
bitStream.Read(readOpenWeb);
|
||||
bitStream.Read(readSupportsSum);
|
||||
bitStream.Read(readSupportsDetail);
|
||||
bitStream.Read(readSupportsWho);
|
||||
bitStream.Read(readSupportsObjects);
|
||||
|
||||
ASSERT_EQ(readPort, 8080);
|
||||
ASSERT_EQ(readOpenWeb, 1);
|
||||
ASSERT_EQ(readSupportsSum, 0);
|
||||
ASSERT_EQ(readSupportsDetail, 1);
|
||||
ASSERT_EQ(readSupportsWho, 0);
|
||||
ASSERT_EQ(readSupportsObjects, 1);
|
||||
ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0);
|
||||
}
|
||||
|
||||
TEST_F(WorldPacketTests, WorldCharacterDeleteResponse) {
|
||||
bool testResponse = false;
|
||||
|
||||
WorldPackets::SendCharacterDeleteResponse(UNASSIGNED_SYSTEM_ADDRESS, testResponse);
|
||||
|
||||
auto* bitStream = GetMostRecentBitStream();
|
||||
VerifyHeader(bitStream, ServiceType::CLIENT, static_cast<uint32_t>(MessageType::Client::DELETE_CHARACTER_RESPONSE));
|
||||
|
||||
uint8_t readResponse;
|
||||
bitStream->Read(readResponse);
|
||||
|
||||
ASSERT_EQ(readResponse, static_cast<uint8_t>(testResponse));
|
||||
ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 0);
|
||||
}
|
||||
|
||||
TEST_F(WorldPacketTests, WorldCharacterRenameResponse) {
|
||||
// Test with different enum values for character rename response
|
||||
WorldPackets::SendCharacterRenameResponse(UNASSIGNED_SYSTEM_ADDRESS, eRenameResponse::NAME_IN_USE);
|
||||
|
||||
auto* bitStream = GetMostRecentBitStream();
|
||||
VerifyHeader(bitStream, ServiceType::CLIENT, static_cast<uint32_t>(MessageType::Client::CHARACTER_RENAME_RESPONSE));
|
||||
|
||||
uint8_t readResponse;
|
||||
bitStream->Read(readResponse);
|
||||
|
||||
ASSERT_EQ(readResponse, static_cast<uint8_t>(eRenameResponse::NAME_IN_USE));
|
||||
ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 0);
|
||||
}
|
||||
|
||||
TEST_F(WorldPacketTests, WorldTransferToWorld) {
|
||||
std::string testServerIP = "10.0.0.1";
|
||||
uint32_t testServerPort = 3000;
|
||||
bool testMythranShift = false;
|
||||
|
||||
WorldPackets::SendTransferToWorld(UNASSIGNED_SYSTEM_ADDRESS, testServerIP, testServerPort, testMythranShift);
|
||||
|
||||
auto* bitStream = GetMostRecentBitStream();
|
||||
VerifyHeader(bitStream, ServiceType::CLIENT, static_cast<uint32_t>(MessageType::Client::TRANSFER_TO_WORLD));
|
||||
|
||||
LUString readServerIP;
|
||||
uint16_t readServerPort;
|
||||
uint8_t readMythranShift;
|
||||
|
||||
bitStream->Read(readServerIP);
|
||||
bitStream->Read(readServerPort);
|
||||
bitStream->Read(readMythranShift);
|
||||
|
||||
ASSERT_EQ(readServerIP.string, testServerIP);
|
||||
ASSERT_EQ(readServerPort, static_cast<uint16_t>(testServerPort));
|
||||
ASSERT_EQ(readMythranShift, static_cast<uint8_t>(testMythranShift));
|
||||
ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 0);
|
||||
}
|
||||
|
||||
TEST_F(WorldPacketTests, WorldServerState) {
|
||||
WorldPackets::SendServerState(UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
auto* bitStream = GetMostRecentBitStream();
|
||||
VerifyHeader(bitStream, ServiceType::CLIENT, static_cast<uint32_t>(MessageType::Client::SERVER_STATES));
|
||||
|
||||
uint8_t readState;
|
||||
bitStream->Read(readState);
|
||||
|
||||
ASSERT_EQ(readState, 1); // Server is ready
|
||||
ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 0);
|
||||
}
|
||||
Reference in New Issue
Block a user