tests: cover quest framing and restart cooldowns
This commit is contained in:
@@ -5,6 +5,7 @@ endif()
|
||||
add_executable(metin_smoke_tests
|
||||
smoke_auth.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/game/SecureCipher.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/game/quest_packet.cpp
|
||||
)
|
||||
|
||||
add_executable(metin_login_smoke
|
||||
|
||||
@@ -5,9 +5,14 @@
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#include "common/packet_headers.h"
|
||||
#include "game/stdafx.h"
|
||||
#include "common/packet_headers.h"
|
||||
#include "common/tables.h"
|
||||
#include "game/packet_structs.h"
|
||||
#include "game/quest_packet.h"
|
||||
#include "game/request_cooldown.h"
|
||||
#include "game/SecureCipher.h"
|
||||
#include "libthecore/fdwatch.h"
|
||||
#include "libthecore/signal.h"
|
||||
@@ -366,6 +371,55 @@ void TestFdwatchSlotReuseAfterDelete()
|
||||
close(sockets_b[0]);
|
||||
close(sockets_b[1]);
|
||||
}
|
||||
|
||||
void TestQuestInfoPacketFraming()
|
||||
{
|
||||
quest::QuestInfoPacketData data {};
|
||||
data.quest_index = 77;
|
||||
data.send_flags = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
data.is_begin = true;
|
||||
data.title = "Mall reward";
|
||||
data.clock_name = "Soon";
|
||||
data.clock_value = 15;
|
||||
data.counter_name = "Kills";
|
||||
data.counter_value = 2;
|
||||
data.icon_file = "d:/icon/test.tga";
|
||||
|
||||
const auto quest_packet = quest::BuildQuestInfoPacket(data);
|
||||
Expect(!quest_packet.empty(), "Quest info packet is empty");
|
||||
Expect(quest_packet.size() == sizeof(packet_quest_info) + 1 + 31 + 17 + 4 + 17 + 4 + 25,
|
||||
"Unexpected quest info packet size");
|
||||
|
||||
const auto* quest_header = reinterpret_cast<const packet_quest_info*>(quest_packet.data());
|
||||
Expect(quest_header->header == GC::QUEST_INFO, "Unexpected quest info header");
|
||||
Expect(quest_header->length == quest_packet.size(), "Quest info packet length does not match payload size");
|
||||
Expect(quest_packet[sizeof(packet_quest_info)] == 1, "Quest begin flag payload mismatch");
|
||||
|
||||
TPacketGCItemGet item_get {};
|
||||
item_get.header = GC::ITEM_GET;
|
||||
item_get.length = sizeof(item_get);
|
||||
item_get.dwItemVnum = 50187;
|
||||
item_get.bCount = 1;
|
||||
item_get.bArg = 0;
|
||||
|
||||
std::vector<uint8_t> stream = quest_packet;
|
||||
const auto* item_bytes = reinterpret_cast<const uint8_t*>(&item_get);
|
||||
stream.insert(stream.end(), item_bytes, item_bytes + sizeof(item_get));
|
||||
|
||||
const size_t next_frame_offset = quest_header->length;
|
||||
Expect(stream.size() >= next_frame_offset + sizeof(item_get), "Combined stream truncated after quest packet");
|
||||
|
||||
const auto* next_frame = reinterpret_cast<const TPacketGCItemGet*>(stream.data() + next_frame_offset);
|
||||
Expect(next_frame->header == GC::ITEM_GET, "Quest info packet left trailing bytes before next frame");
|
||||
Expect(next_frame->length == sizeof(TPacketGCItemGet), "Item get packet length mismatch after quest packet");
|
||||
}
|
||||
|
||||
void TestRequestCooldownGuard()
|
||||
{
|
||||
Expect(!HasRecentRequestCooldown(0, 5, 10), "Initial zero request pulse should not trigger cooldown");
|
||||
Expect(HasRecentRequestCooldown(95, 100, 10), "Recent request pulse should still be on cooldown");
|
||||
Expect(!HasRecentRequestCooldown(90, 100, 10), "Cooldown boundary should allow request");
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
@@ -379,6 +433,8 @@ int main()
|
||||
TestCheckpointBackendMetadata();
|
||||
TestFdwatchReadAndOneshotWrite();
|
||||
TestFdwatchSlotReuseAfterDelete();
|
||||
TestQuestInfoPacketFraming();
|
||||
TestRequestCooldownGuard();
|
||||
std::cout << "metin smoke tests passed\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user