1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#include <cassert>
#include "GameData.h"
#include "Net/Protocol/BaseNetProtocol.h"
#include "System/Net/PackPacket.h"
#include "System/Net/UnpackPacket.h"
#include "System/StringUtil.h"
using namespace netcode;
GameData::GameData()
{
std::memset(mapChecksum, 0, sizeof(mapChecksum));
std::memset(modChecksum, 0, sizeof(modChecksum));
}
GameData::GameData(const std::string& setup): setupText(setup)
{
std::memset(mapChecksum, 0, sizeof(mapChecksum));
std::memset(modChecksum, 0, sizeof(modChecksum));
}
GameData::GameData(std::shared_ptr<const RawPacket> pckt)
{
assert(pckt->data[0] == NETMSG_GAMEDATA);
UnpackPacket packet(pckt, 3);
std::uint16_t compressedSize;
packet >> compressedSize; compressed.resize(compressedSize);
packet >> compressed;
const std::vector<std::uint8_t> buffer{zlib::inflate(compressed)};
if (buffer.empty())
throw netcode::UnpackPacketException("Error decompressing GameData");
// avoid reinterpret_cast; buffer is not null-terminated
setupText = {buffer.begin(), buffer.end()};
for (auto& checksum: mapChecksum) { packet >> checksum; }
for (auto& checksum: modChecksum) { packet >> checksum; }
packet >> randomSeed;
}
const netcode::RawPacket* GameData::Pack() const
{
if (compressed.empty())
compressed = std::move(zlib::deflate(reinterpret_cast<const std::uint8_t*>(setupText.data()), setupText.size()));
assert(!compressed.empty());
assert(compressed.size() <= std::numeric_limits<std::uint16_t>::max());
const std::uint16_t size = 3 + sizeof(mapChecksum) + sizeof(modChecksum) + compressed.size() + 2 + sizeof(uint32_t);
PackPacket* buffer = new PackPacket(size, NETMSG_GAMEDATA);
*buffer << size;
*buffer << std::uint16_t(compressed.size());
*buffer << compressed;
for (auto& checksum: mapChecksum) { *buffer << checksum; }
for (auto& checksum: modChecksum) { *buffer << checksum; }
*buffer << randomSeed;
return buffer;
}
void GameData::SetSetupText(const std::string& newSetup)
{
setupText = newSetup;
compressed.clear();
}
|