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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#include <boost/format.hpp>
#include <assert.h>
#include <zlib.h>
#include "System/mmgr.h"
#include "GameData.h"
#include "System/BaseNetProtocol.h"
#include "System/Net/PackPacket.h"
#include "System/Net/UnpackPacket.h"
using namespace netcode;
GameData::GameData()
: mapChecksum(0)
, modChecksum(0)
, randomSeed(0)
{
}
GameData::GameData(boost::shared_ptr<const RawPacket> pckt)
{
assert(pckt->data[0] == NETMSG_GAMEDATA);
UnpackPacket packet(pckt, 3);
boost::uint16_t compressedSize;
packet >> compressedSize;
compressed.resize(compressedSize);
packet >> compressed;
// "the LSB does not describe any mechanism by which a
// compressor can communicate the size required to the
// uncompressor" ==> we must reserve some fixed-length
// buffer (256K bytes to handle very large scripts)
static const unsigned long bufSize = 262144;
unsigned long rawSize = bufSize;
std::vector<boost::uint8_t> buffer(bufSize);
if (uncompress(&buffer[0], &rawSize, &compressed[0], compressed.size()) != Z_OK) {
static const std::string err = str(boost::format("unpacking game-data packet failed (%u bytes decompressed)") %rawSize);
throw UnpackPacketException(err.c_str());
}
setupText = reinterpret_cast<char*>(&buffer[0]);
packet >> mapChecksum;
packet >> modChecksum;
packet >> randomSeed;
}
const netcode::RawPacket* GameData::Pack() const
{
if (compressed.empty())
{
long unsigned bufsize = (setupText.size() * 1.02) + 32;
compressed.resize(bufsize);
const int error = compress(&compressed[0], &bufsize, reinterpret_cast<const boost::uint8_t*>(setupText.c_str()), setupText.length());
compressed.resize(bufsize);
assert(error == Z_OK);
}
unsigned short size = 3 + 2*sizeof(unsigned) + compressed.size()+2 + 4;
PackPacket* buffer = new PackPacket(size, NETMSG_GAMEDATA);
*buffer << size;
*buffer << boost::uint16_t(compressed.size());
*buffer << compressed;
*buffer << mapChecksum;
*buffer << modChecksum;
*buffer << randomSeed;
return buffer;
}
void GameData::SetSetup(const std::string& newSetup)
{
setupText = newSetup;
compressed.clear();
}
void GameData::SetMapChecksum(const unsigned checksum)
{
mapChecksum = checksum;
}
void GameData::SetModChecksum(const unsigned checksum)
{
modChecksum = checksum;
}
void GameData::SetRandomSeed(const unsigned seed)
{
randomSeed = seed;
}
|