mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-09-05 14:58:27 +00:00
Complete comprehensive packet testing framework with 20 tests covering all major packet types and edge cases
Co-authored-by: aronwk-aaron <26027722+aronwk-aaron@users.noreply.github.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
#include "MessageType/Chat.h"
|
#include "MessageType/Chat.h"
|
||||||
#include "MessageType/Client.h"
|
#include "MessageType/Client.h"
|
||||||
#include "MessageType/Master.h"
|
#include "MessageType/Master.h"
|
||||||
|
#include "eRenameResponse.h"
|
||||||
|
|
||||||
// Game dependencies for mocking
|
// Game dependencies for mocking
|
||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
@@ -237,21 +238,30 @@ TEST_F(PacketTests, ChatAnnouncementSerialization) {
|
|||||||
announcement.title = "Test Title";
|
announcement.title = "Test Title";
|
||||||
announcement.message = "Test announcement message";
|
announcement.message = "Test announcement message";
|
||||||
|
|
||||||
RakNet::BitStream bitStream;
|
// Call Send which will add header and serialize
|
||||||
announcement.Serialize(bitStream);
|
announcement.Send(UNASSIGNED_SYSTEM_ADDRESS);
|
||||||
|
|
||||||
VerifyHeader(&bitStream, ServiceType::CHAT, static_cast<uint32_t>(MessageType::Chat::GM_ANNOUNCE));
|
auto* bitStream = GetMostRecentBitStream();
|
||||||
|
VerifyHeader(bitStream, ServiceType::CHAT, static_cast<uint32_t>(MessageType::Chat::GM_ANNOUNCE));
|
||||||
|
|
||||||
// Read announcement data
|
// Read announcement data (size prefixed strings)
|
||||||
LUString readTitle;
|
uint32_t titleSize;
|
||||||
LUString readMessage;
|
bitStream->Read(titleSize);
|
||||||
|
ASSERT_EQ(titleSize, announcement.title.size());
|
||||||
|
|
||||||
bitStream.Read(readTitle);
|
std::string readTitle(titleSize, '\0');
|
||||||
bitStream.Read(readMessage);
|
bitStream->ReadBits(reinterpret_cast<unsigned char*>(readTitle.data()), BYTES_TO_BITS(titleSize), true);
|
||||||
|
|
||||||
ASSERT_EQ(readTitle.string, "Test Title");
|
uint32_t messageSize;
|
||||||
ASSERT_EQ(readMessage.string, "Test announcement message");
|
bitStream->Read(messageSize);
|
||||||
ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0);
|
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(PacketTests, ChatAchievementNotifySerialization) {
|
TEST_F(PacketTests, ChatAchievementNotifySerialization) {
|
||||||
@@ -261,27 +271,43 @@ TEST_F(PacketTests, ChatAchievementNotifySerialization) {
|
|||||||
notify.earningPlayerID = 987654321;
|
notify.earningPlayerID = 987654321;
|
||||||
notify.earnerName = LUWString(u"EarnerPlayer");
|
notify.earnerName = LUWString(u"EarnerPlayer");
|
||||||
|
|
||||||
RakNet::BitStream bitStream;
|
// Call Send which will add header and serialize
|
||||||
notify.Serialize(bitStream);
|
notify.Send(UNASSIGNED_SYSTEM_ADDRESS);
|
||||||
|
|
||||||
VerifyHeader(&bitStream, ServiceType::CHAT, static_cast<uint32_t>(MessageType::Chat::ACHIEVEMENT_NOTIFY));
|
auto* bitStream = GetMostRecentBitStream();
|
||||||
|
VerifyHeader(bitStream, ServiceType::CHAT, static_cast<uint32_t>(MessageType::Chat::ACHIEVEMENT_NOTIFY));
|
||||||
|
|
||||||
// Read achievement data
|
// Read achievement data based on actual Serialize implementation
|
||||||
LUWString readTargetPlayerName;
|
// 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;
|
uint32_t readMissionEmailID;
|
||||||
LWOOBJID readEarningPlayerID;
|
LWOOBJID readEarningPlayerID;
|
||||||
LUWString readEarnerName;
|
LUWString readTargetPlayerName;
|
||||||
|
|
||||||
bitStream.Read(readTargetPlayerName);
|
bitStream->Read(packing1);
|
||||||
bitStream.Read(readMissionEmailID);
|
bitStream->Read(packing2);
|
||||||
bitStream.Read(readEarningPlayerID);
|
bitStream->Read(packing3);
|
||||||
bitStream.Read(readEarnerName);
|
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(readTargetPlayerName.string, u"TargetPlayer");
|
ASSERT_EQ(readEarnerName.string, u"EarnerPlayer");
|
||||||
ASSERT_EQ(readMissionEmailID, 12345u);
|
ASSERT_EQ(readMissionEmailID, 12345u);
|
||||||
ASSERT_EQ(readEarningPlayerID, 987654321);
|
ASSERT_EQ(readEarningPlayerID, 987654321);
|
||||||
ASSERT_EQ(readEarnerName.string, u"EarnerPlayer");
|
ASSERT_EQ(readTargetPlayerName.string, u"TargetPlayer");
|
||||||
ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0);
|
ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(PacketTests, ChatTeamInviteInitialResponseSerialization) {
|
TEST_F(PacketTests, ChatTeamInviteInitialResponseSerialization) {
|
||||||
@@ -289,21 +315,22 @@ TEST_F(PacketTests, ChatTeamInviteInitialResponseSerialization) {
|
|||||||
response.inviteFailedToSend = true;
|
response.inviteFailedToSend = true;
|
||||||
response.playerName = LUWString(u"InviteePlayer");
|
response.playerName = LUWString(u"InviteePlayer");
|
||||||
|
|
||||||
RakNet::BitStream bitStream;
|
// Call Send which will add header and serialize
|
||||||
response.Serialize(bitStream);
|
response.Send(UNASSIGNED_SYSTEM_ADDRESS);
|
||||||
|
|
||||||
VerifyHeader(&bitStream, ServiceType::CLIENT, static_cast<uint32_t>(MessageType::Client::TEAM_INVITE_INITIAL_RESPONSE));
|
auto* bitStream = GetMostRecentBitStream();
|
||||||
|
VerifyHeader(bitStream, ServiceType::CLIENT, static_cast<uint32_t>(MessageType::Client::TEAM_INVITE_INITIAL_RESPONSE));
|
||||||
|
|
||||||
// Read team invite response data
|
// Read team invite response data
|
||||||
bool readInviteFailedToSend;
|
uint8_t readInviteFailedToSend; // Written as uint8_t in actual implementation
|
||||||
LUWString readPlayerName;
|
LUWString readPlayerName;
|
||||||
|
|
||||||
bitStream.Read(readInviteFailedToSend);
|
bitStream->Read(readInviteFailedToSend);
|
||||||
bitStream.Read(readPlayerName);
|
bitStream->Read(readPlayerName);
|
||||||
|
|
||||||
ASSERT_EQ(readInviteFailedToSend, true);
|
ASSERT_EQ(readInviteFailedToSend, static_cast<uint8_t>(true));
|
||||||
ASSERT_EQ(readPlayerName.string, u"InviteePlayer");
|
ASSERT_EQ(readPlayerName.string, u"InviteePlayer");
|
||||||
ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0);
|
ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== WorldPackets Tests =====
|
// ===== WorldPackets Tests =====
|
||||||
@@ -387,24 +414,24 @@ TEST_F(PacketTests, MasterZoneTransferResponseStructure) {
|
|||||||
uint32_t readZoneID;
|
uint32_t readZoneID;
|
||||||
uint32_t readZoneInstance;
|
uint32_t readZoneInstance;
|
||||||
uint32_t readZoneClone;
|
uint32_t readZoneClone;
|
||||||
LUString readServerIP;
|
uint16_t readServerPort; // Note: written as uint16_t in actual implementation
|
||||||
uint32_t readServerPort;
|
LUString readServerIP(255); // Note: written as LUString with size 255
|
||||||
|
|
||||||
bitStream->Read(readRequestID);
|
bitStream->Read(readRequestID);
|
||||||
bitStream->Read(readMythranShift);
|
bitStream->Read(readMythranShift);
|
||||||
bitStream->Read(readZoneID);
|
bitStream->Read(readZoneID);
|
||||||
bitStream->Read(readZoneInstance);
|
bitStream->Read(readZoneInstance);
|
||||||
bitStream->Read(readZoneClone);
|
bitStream->Read(readZoneClone);
|
||||||
bitStream->Read(readServerIP);
|
|
||||||
bitStream->Read(readServerPort);
|
bitStream->Read(readServerPort);
|
||||||
|
bitStream->Read(readServerIP);
|
||||||
|
|
||||||
ASSERT_EQ(readRequestID, testRequestID);
|
ASSERT_EQ(readRequestID, testRequestID);
|
||||||
ASSERT_EQ(readMythranShift, static_cast<uint8_t>(testMythranShift));
|
ASSERT_EQ(readMythranShift, static_cast<uint8_t>(testMythranShift));
|
||||||
ASSERT_EQ(readZoneID, testZoneID);
|
ASSERT_EQ(readZoneID, testZoneID);
|
||||||
ASSERT_EQ(readZoneInstance, testZoneInstance);
|
ASSERT_EQ(readZoneInstance, testZoneInstance);
|
||||||
ASSERT_EQ(readZoneClone, testZoneClone);
|
ASSERT_EQ(readZoneClone, testZoneClone);
|
||||||
|
ASSERT_EQ(readServerPort, static_cast<uint16_t>(testServerPort));
|
||||||
ASSERT_EQ(readServerIP.string, testServerIP);
|
ASSERT_EQ(readServerIP.string, testServerIP);
|
||||||
ASSERT_EQ(readServerPort, testServerPort);
|
|
||||||
ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 0);
|
ASSERT_EQ(bitStream->GetNumberOfUnreadBits(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,3 +526,127 @@ TEST_F(PacketTests, LongPasswordHandling) {
|
|||||||
ASSERT_EQ(readSupportsObjects, 1);
|
ASSERT_EQ(readSupportsObjects, 1);
|
||||||
ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0);
|
ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== Additional Comprehensive Tests =====
|
||||||
|
|
||||||
|
TEST_F(PacketTests, 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(PacketTests, 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(PacketTests, 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(PacketTests, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PacketTests, 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(PacketTests, 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);
|
||||||
|
}
|
Reference in New Issue
Block a user