#include "Client/ReplayPacketRecorder.h" #include "Network/PacketLengths.h" #include #include #include #include // clang-format off #include // clang-format on // OFFSET: 0x00B86880 // FUNCTION: fn_19332 bool ReplayPacketRecorder::Record(std::uint16_t bytes, const void* packet, int event, std::uint32_t delay) { if (bytes == 0 || !packet) { return false; } std::uint16_t id; std::memcpy(&id, packet, sizeof(id)); if (id != 2222) { if (this->lengths.IsRecorded(id) == 0) { return false; } switch (id) { case 141: case 142: case 151: case 265: case 383: case 732: case 3038: if (this->recordRestricted == 0) { return false; } break; default: break; } } std::vector record(static_cast(bytes) + 10, 0); std::memcpy(record.data() + 8, &bytes, sizeof(bytes)); if (event == 42 || event == 43) { const std::uint32_t frameDelta = this->frame - this->baseFrame; const std::uint32_t tick = event == 43 ? delay - this->started + timeGetTime() : timeGetTime() - this->started; std::memcpy(record.data(), &frameDelta, sizeof(frameDelta)); std::memcpy(record.data() + 4, &tick, sizeof(tick)); } std::memcpy(record.data() + 10, packet, bytes); this->cipherKey = this->key1 >> 3; this->cipherIndex = 0; this->cipherBase = this->key0 >> 5; for (unsigned index = 0; index < bytes / 4u; ++index) { std::uint32_t word; std::memcpy(&word, record.data() + 10 + index * 4, sizeof(word)); word ^= this->cipherKey * (++this->cipherIndex + this->cipherBase); std::memcpy(record.data() + 10 + index * 4, &word, sizeof(word)); } std::fseek(this->file, std::bit_cast(this->fileOffset), SEEK_SET); std::fwrite(record.data(), record.size(), 1, this->file); this->fileOffset += static_cast(record.size()); ++this->records; return true; } // OFFSET: 0x00A82F00 // FUNCTION: fn_16999 void WindowResponseRecorder::Record(int windowId, int response, std::intptr_t b, std::intptr_t c, std::intptr_t d) { if (this->mode != 2) { return; } #pragma pack(push, 1) struct Response { std::uint32_t marker; std::uint16_t bytes; std::int32_t windowId; std::int32_t response; std::uint32_t arguments[3]; }; #pragma pack(pop) static_assert(sizeof(Response) == 26); const Response packet{ 0x038408AEu, 26, windowId, response, {static_cast(b), static_cast(c), static_cast(d)} }; this->packets.Record(sizeof(packet), &packet, 42, 0); }