git-svn-id: http://mc-server.googlecode.com/svn/trunk@795 0a769ca7-a7f5-676a-18bf-c427514a06d6
parent
17253d2c90
commit
d97ad781b4
|
@ -388,6 +388,14 @@
|
|||
RelativePath="..\source\cHeartBeat.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\ChunkDataSerializer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\ChunkDataSerializer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\ChunkDef.h"
|
||||
>
|
||||
|
|
|
@ -338,6 +338,7 @@
|
|||
<ClCompile Include="..\Source\cGroup.cpp" />
|
||||
<ClCompile Include="..\Source\cGroupManager.cpp" />
|
||||
<ClCompile Include="..\Source\cHeartBeat.cpp" />
|
||||
<ClCompile Include="..\source\ChunkDataSerializer.cpp" />
|
||||
<ClCompile Include="..\source\ChunkSender.cpp" />
|
||||
<ClCompile Include="..\source\cIsThread.cpp" />
|
||||
<ClCompile Include="..\source\cItem.cpp" />
|
||||
|
@ -576,6 +577,7 @@
|
|||
<ClInclude Include="..\Source\cGroup.h" />
|
||||
<ClInclude Include="..\Source\cGroupManager.h" />
|
||||
<ClInclude Include="..\Source\cHeartBeat.h" />
|
||||
<ClInclude Include="..\source\ChunkDataSerializer.h" />
|
||||
<ClInclude Include="..\source\ChunkDef.h" />
|
||||
<ClInclude Include="..\source\ChunkSender.h" />
|
||||
<ClInclude Include="..\source\cIsThread.h" />
|
||||
|
|
|
@ -951,6 +951,7 @@
|
|||
<ClCompile Include="..\source\cNoteEntity.cpp">
|
||||
<Filter>cBlockEntity\cNoteEntity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\source\ChunkDataSerializer.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\source\cServer.h">
|
||||
|
@ -1663,6 +1664,7 @@
|
|||
<ClInclude Include="..\source\cNoteEntity.h">
|
||||
<Filter>cBlockEntity\cNoteEntity</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\source\ChunkDataSerializer.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\source\AllToLua.pkg">
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
|
||||
// ChunkDataSerializer.cpp
|
||||
|
||||
// Implements the cChunkDataSerializer class representing the object that can:
|
||||
// - serialize chunk data to different protocol versions
|
||||
// - cache such serialized data for multiple clients
|
||||
|
||||
#include "Globals.h"
|
||||
#include "ChunkDataSerializer.h"
|
||||
#include "zlib.h"
|
||||
|
||||
|
||||
|
||||
|
||||
cChunkDataSerializer::cChunkDataSerializer(
|
||||
const cChunkDef::BlockTypes & a_BlockTypes,
|
||||
const cChunkDef::BlockNibbles & a_BlockMetas,
|
||||
const cChunkDef::BlockNibbles & a_BlockLight,
|
||||
const cChunkDef::BlockNibbles & a_BlockSkyLight,
|
||||
const unsigned char * a_BiomeData
|
||||
) :
|
||||
m_BlockTypes(a_BlockTypes),
|
||||
m_BlockMetas(a_BlockMetas),
|
||||
m_BlockLight(a_BlockLight),
|
||||
m_BlockSkyLight(a_BlockSkyLight),
|
||||
m_BiomeData(a_BiomeData)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const AString & cChunkDataSerializer::Serialize(int a_Version)
|
||||
{
|
||||
Serializations::const_iterator itr = m_Serializations.find(a_Version);
|
||||
if (itr != m_Serializations.end())
|
||||
{
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
AString data;
|
||||
switch (a_Version)
|
||||
{
|
||||
case RELEASE_1_2_5: Serialize29(data); break;
|
||||
// TODO: Other protocol versions may serialize the data differently; implement here
|
||||
|
||||
default:
|
||||
{
|
||||
LOGERROR("cChunkDataSerializer::Serialize(): Unknown version: %d", a_Version);
|
||||
ASSERT(!"Unknown chunk data serialization version");
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_Serializations[a_Version] = data;
|
||||
return m_Serializations[a_Version];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkDataSerializer::Serialize29(AString & a_Data)
|
||||
{
|
||||
// TODO: Do not copy data and then compress it; rather, compress partial blocks of data (zlib *can* stream)
|
||||
|
||||
const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width;
|
||||
const int MetadataOffset = sizeof(m_BlockTypes);
|
||||
const int BlockLightOffset = MetadataOffset + sizeof(m_BlockMetas);
|
||||
const int SkyLightOffset = BlockLightOffset + sizeof(m_BlockLight);
|
||||
const int BiomeOffset = SkyLightOffset + sizeof(m_BlockSkyLight);
|
||||
const int DataSize = BiomeOffset + BiomeDataSize;
|
||||
|
||||
// Temporary buffer for the composed data:
|
||||
char AllData [DataSize];
|
||||
|
||||
memcpy(AllData, m_BlockTypes, sizeof(m_BlockTypes));
|
||||
memcpy(AllData + MetadataOffset, m_BlockMetas, sizeof(m_BlockMetas));
|
||||
memcpy(AllData + BlockLightOffset, m_BlockLight, sizeof(m_BlockLight));
|
||||
memcpy(AllData + SkyLightOffset, m_BlockSkyLight, sizeof(m_BlockSkyLight));
|
||||
memcpy(AllData + BiomeOffset, m_BiomeData, BiomeDataSize);
|
||||
|
||||
// Compress the data:
|
||||
// In order not to use allocation, use a fixed-size buffer, with the size
|
||||
// that uses the same calculation as compressBound():
|
||||
const uLongf CompressedMaxSize = DataSize + (DataSize >> 12) + (DataSize >> 14) + (DataSize >> 25) + 16;
|
||||
char CompressedBlockData[CompressedMaxSize];
|
||||
|
||||
uLongf CompressedSize = compressBound(DataSize);
|
||||
|
||||
// Run-time check that our compile-time guess about CompressedMaxSize was enough:
|
||||
ASSERT(CompressedSize <= CompressedMaxSize);
|
||||
|
||||
compress2((Bytef*)CompressedBlockData, &CompressedSize, (const Bytef*)AllData, sizeof(AllData), Z_DEFAULT_COMPRESSION);
|
||||
|
||||
// Now put all those data into a_Data:
|
||||
|
||||
// "Ground-up continuous", or rather, "biome data present" flag:
|
||||
a_Data.push_back('\xff');
|
||||
|
||||
// Two bitmaps; we're aways sending the full chunk with no additional data, so the bitmaps are 0xffff and 0, respectively
|
||||
// Also, no endian flipping is needed because of the const values
|
||||
unsigned short BitMap1 = 0xffff;
|
||||
unsigned short BitMap2 = 0;
|
||||
a_Data.append((const char *)&BitMap1, sizeof(short));
|
||||
a_Data.append((const char *)&BitMap2, sizeof(short));
|
||||
|
||||
Int32 CompressedSizeBE = htonl(CompressedSize);
|
||||
a_Data.append((const char *)&CompressedSizeBE, sizeof(CompressedSizeBE));
|
||||
|
||||
Int32 UnusedInt32 = 0;
|
||||
a_Data.append((const char *)&UnusedInt32, sizeof(UnusedInt32));
|
||||
|
||||
a_Data.append(CompressedBlockData, CompressedSize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
// ChunkDataSerializer.h
|
||||
|
||||
// Interfaces to the cChunkDataSerializer class representing the object that can:
|
||||
// - serialize chunk data to different protocol versions
|
||||
// - cache such serialized data for multiple clients
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cChunkDataSerializer
|
||||
{
|
||||
protected:
|
||||
const cChunkDef::BlockTypes & m_BlockTypes;
|
||||
const cChunkDef::BlockNibbles & m_BlockMetas;
|
||||
const cChunkDef::BlockNibbles & m_BlockLight;
|
||||
const cChunkDef::BlockNibbles & m_BlockSkyLight;
|
||||
const unsigned char * m_BiomeData;
|
||||
|
||||
typedef std::map<int, AString> Serializations;
|
||||
|
||||
Serializations m_Serializations;
|
||||
|
||||
void Serialize29(AString & a_Data); // Release 1.2.4 and 1.2.5
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
RELEASE_1_2_5 = 29,
|
||||
} ;
|
||||
|
||||
cChunkDataSerializer(
|
||||
const cChunkDef::BlockTypes & a_BlockTypes,
|
||||
const cChunkDef::BlockNibbles & a_BlockMetas,
|
||||
const cChunkDef::BlockNibbles & a_BlockLight,
|
||||
const cChunkDef::BlockNibbles & a_BlockSkyLight,
|
||||
const unsigned char * a_BiomeData
|
||||
);
|
||||
|
||||
const AString & Serialize(int a_Version); // Returns one of the internal m_Serializations[]
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
|
@ -10,9 +10,8 @@
|
|||
#include "Globals.h"
|
||||
#include "ChunkSender.h"
|
||||
#include "cWorld.h"
|
||||
#include "packets/cPacket_MapChunk.h"
|
||||
#include "packets/cPacket_PreChunk.h"
|
||||
#include "cBlockEntity.h"
|
||||
#include "ChunkDataSerializer.h"
|
||||
|
||||
|
||||
|
||||
|
@ -217,24 +216,21 @@ void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHa
|
|||
return;
|
||||
}
|
||||
|
||||
// Prepare MapChunk packets:
|
||||
// Query and prepare chunk data:
|
||||
if( !m_World->GetChunkData(a_ChunkX, a_ChunkY, a_ChunkZ, *this) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
cPacket_PreChunk PreChunk(a_ChunkX, a_ChunkZ, true);
|
||||
cPacket_MapChunk MapChunk(a_ChunkX, a_ChunkY, a_ChunkZ, (BLOCKTYPE *)m_BlockData, m_BiomeMap);
|
||||
cChunkDataSerializer Data(m_BlockTypes, m_BlockMetas, m_BlockLight, m_BlockSkyLight, m_BiomeMap);
|
||||
|
||||
// Send:
|
||||
if (a_Client == NULL)
|
||||
{
|
||||
m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, PreChunk);
|
||||
m_World->BroadcastToChunk(a_ChunkX, a_ChunkY, a_ChunkZ, MapChunk);
|
||||
m_World->BroadcastChunkData(a_ChunkX, a_ChunkZ, Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
a_Client->Send(PreChunk);
|
||||
a_Client->Send(MapChunk);
|
||||
a_Client->SendChunkData(a_ChunkX, a_ChunkZ, Data);
|
||||
}
|
||||
|
||||
// Send block-entity packets:
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
|
||||
class cChunkSender:
|
||||
public cIsThread,
|
||||
public cChunkDataCollector
|
||||
public cChunkDataSeparateCollector
|
||||
{
|
||||
typedef cIsThread super;
|
||||
public:
|
||||
|
|
|
@ -1936,6 +1936,22 @@ void cChunk::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, cons
|
|||
|
||||
|
||||
|
||||
void cChunk::BroadcastChunkData(cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr )
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendChunkData(m_PosX, m_PosZ, a_Serializer);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude)
|
||||
{
|
||||
// We can operate on entity pointers, we're inside the ChunkMap's CS lock which guards the list
|
||||
|
|
|
@ -43,6 +43,7 @@ class cFurnaceEntity;
|
|||
class cBlockArea;
|
||||
class cPawn;
|
||||
class cPickup;
|
||||
class cChunkDataSerializer;
|
||||
|
||||
typedef std::list<cClientHandle *> cClientHandleList;
|
||||
typedef cItemCallback<cEntity> cEntityCallback;
|
||||
|
@ -191,6 +192,7 @@ public:
|
|||
void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastChunkData (cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
|
||||
|
||||
void SendBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client);
|
||||
|
||||
|
|
|
@ -485,6 +485,22 @@ void cChunkMap::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, c
|
|||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, 0, a_ChunkZ);
|
||||
if (Chunk == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastChunkData(a_Serializer, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
|
|
|
@ -22,6 +22,7 @@ class cChestEntity;
|
|||
class cFurnaceEntity;
|
||||
class cPawn;
|
||||
class cPickup;
|
||||
class cChunkDataSerializer;
|
||||
|
||||
typedef std::list<cClientHandle *> cClientHandleList;
|
||||
typedef cChunk * cChunkPtr;
|
||||
|
@ -82,6 +83,8 @@ public:
|
|||
|
||||
void BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL);
|
||||
|
||||
void BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
|
||||
|
||||
/// Broadcasts the block entity, if it is at the coords specified, to all clients except a_Exclude
|
||||
void BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude);
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "cTimer.h"
|
||||
#include "items/Item.h"
|
||||
#include "blocks/Block.h"
|
||||
#include "ChunkDataSerializer.h"
|
||||
|
||||
#include "cTracer.h"
|
||||
#include "Vector3f.h"
|
||||
|
@ -2025,6 +2026,21 @@ void cClientHandle::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ)
|
|||
|
||||
|
||||
|
||||
void cClientHandle::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
|
||||
{
|
||||
// Send the pre-chunk:
|
||||
cPacket_PreChunk pre(a_ChunkX, a_ChunkZ, true);
|
||||
Send(pre);
|
||||
|
||||
// Send the data:
|
||||
cPacket_MapChunk mc(a_ChunkX, a_ChunkZ, a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_2_5));
|
||||
Send(mc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cClientHandle::CheckIfWorldDownloaded(void)
|
||||
{
|
||||
if (m_State != csDownloadingWorld)
|
||||
|
|
|
@ -36,6 +36,7 @@ class cWindow;
|
|||
class cPawn;
|
||||
class cPickup;
|
||||
class cMonster;
|
||||
class cChunkDataSerializer;
|
||||
|
||||
|
||||
|
||||
|
@ -121,6 +122,7 @@ public:
|
|||
void SendWeather(eWeather a_Weather);
|
||||
void SendTimeUpdate(Int64 a_WorldTime);
|
||||
void SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer);
|
||||
|
||||
const AString & GetUsername(void) const; //tolua_export
|
||||
|
||||
|
|
|
@ -1438,6 +1438,15 @@ void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude)
|
|||
|
||||
|
||||
|
||||
void cWorld::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastChunkData(a_ChunkX, a_ChunkZ, a_Serializer, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_Exclude);
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
void BroadcastWeather (eWeather a_Weather, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastTimeUpdate (const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
|
||||
|
||||
/// If there is a block entity at the specified coods, sends it to all clients except a_Exclude
|
||||
void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL);
|
||||
|
|
|
@ -4,131 +4,16 @@
|
|||
#include "cPacket_MapChunk.h"
|
||||
#include "../ChunkDef.h"
|
||||
|
||||
#include "zlib.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cPacket_MapChunk::~cPacket_MapChunk()
|
||||
{
|
||||
delete [] m_CompressedData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cPacket_MapChunk::cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const BLOCKTYPE * a_BlockData, const unsigned char * a_BiomeData)
|
||||
cPacket_MapChunk::cPacket_MapChunk(int a_ChunkX, int a_ChunkZ, const AString & a_SerializedData) :
|
||||
m_PosX(a_ChunkX),
|
||||
m_PosZ(a_ChunkZ),
|
||||
m_SerializedData(a_SerializedData)
|
||||
{
|
||||
m_PacketID = E_MAP_CHUNK;
|
||||
|
||||
m_PosX = a_ChunkX; // Chunk coordinates now, instead of block coordinates
|
||||
m_PosZ = a_ChunkZ;
|
||||
|
||||
m_bContiguous = true; // false = no biome data, true = with biome data
|
||||
m_BitMap1 = 0;
|
||||
m_BitMap2 = 0;
|
||||
|
||||
m_UnusedInt = 0;
|
||||
|
||||
|
||||
const int BlockDataSize = (cChunkDef::Height / 16) * (4096 + 2048 + 2048 + 2048);
|
||||
const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width;
|
||||
char AllData [ BlockDataSize + BiomeDataSize ];
|
||||
|
||||
#if AXIS_ORDER == AXIS_ORDER_YZX
|
||||
memset( AllData, 0, BlockDataSize );
|
||||
|
||||
unsigned int iterator = 0;
|
||||
for ( int i = 0; i < (cChunkDef::Height / 16); ++i )
|
||||
{
|
||||
m_BitMap1 |= (1 << i); // This tells what chunks are sent. Use this to NOT send air only chunks (right now everything is sent)
|
||||
for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) for( int x = 0; x < 16; ++x )
|
||||
{
|
||||
int idx = cChunk::MakeIndex(x, y + i * 16, z);
|
||||
AllData[iterator] = a_BlockData[idx];
|
||||
++iterator;
|
||||
} // for y, z, x
|
||||
}
|
||||
|
||||
// Send block metadata:
|
||||
char * Meta = a_BlockData + cChunkDef::NumBlocks;
|
||||
for ( int i = 0; i < (cChunkDef::Height / 16); ++i )
|
||||
{
|
||||
for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z )
|
||||
{
|
||||
for ( int x = 0; x < 8; ++x )
|
||||
{
|
||||
AllData[iterator] = cChunk::GetNibble(Meta, x * 2 + 0, y + i * 16, z) | (cChunk::GetNibble(Meta, x * 2 + 1, y + i * 16, z ) << 4);
|
||||
++iterator;
|
||||
} // for x
|
||||
} // for y, z
|
||||
}
|
||||
|
||||
// Send block light:
|
||||
char * Light = Meta + cChunkDef::NumBlocks / 2;
|
||||
for ( int i = 0; i < (cChunkDef::Height / 16); ++i )
|
||||
{
|
||||
for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z )
|
||||
{
|
||||
for ( int x = 0; x < 8; ++x )
|
||||
{
|
||||
AllData[iterator] = cChunk::GetNibble(Light, x * 2 + 0, y + i * 16, z ) | (cChunk::GetNibble(Light, x * 2 + 1, y + i * 16, z ) << 4);
|
||||
++iterator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send sky light:
|
||||
char * SkyLight = Light + cChunkDef::NumBlocks / 2;
|
||||
for( int i = 0; i < (cChunkDef::Height/16); ++i )
|
||||
{
|
||||
for( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z )
|
||||
{
|
||||
for( int x = 0; x < 8; ++x )
|
||||
{
|
||||
AllData[iterator] = cChunk::GetNibble(SkyLight, x * 2 + 0, y + i * 16, z ) | (cChunk::GetNibble(SkyLight, x * 2 + 1, y + i * 16, z ) << 4);
|
||||
++iterator;
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(AllData + BlockDataSize, a_BiomeData, BiomeDataSize);
|
||||
#elif AXIS_ORDER == AXIS_ORDER_XZY
|
||||
for ( int i = 0; i < 16; ++i )
|
||||
{
|
||||
m_BitMap1 |= (1 << i);
|
||||
}
|
||||
memcpy(AllData, a_BlockData, BlockDataSize);
|
||||
memcpy(AllData + BlockDataSize, a_BiomeData, BiomeDataSize);
|
||||
#endif // AXIS_ORDER
|
||||
|
||||
uLongf CompressedSize = compressBound( sizeof(AllData) );
|
||||
char * CompressedBlockData = new char[CompressedSize];
|
||||
|
||||
compress2( (Bytef*)CompressedBlockData, &CompressedSize, (const Bytef*)AllData, sizeof(AllData), Z_DEFAULT_COMPRESSION);
|
||||
|
||||
m_CompressedData = CompressedBlockData;
|
||||
m_CompressedSize = CompressedSize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cPacket_MapChunk::cPacket_MapChunk( const cPacket_MapChunk & a_Copy )
|
||||
{
|
||||
m_PacketID = E_MAP_CHUNK;
|
||||
|
||||
m_PosX = a_Copy.m_PosX;
|
||||
m_PosZ = a_Copy.m_PosZ;
|
||||
m_bContiguous = a_Copy.m_bContiguous;
|
||||
m_BitMap1 = a_Copy.m_BitMap1;
|
||||
m_BitMap2 = a_Copy.m_BitMap2;
|
||||
|
||||
m_CompressedSize = a_Copy.m_CompressedSize;
|
||||
m_CompressedData = new char[m_CompressedSize];
|
||||
memcpy( m_CompressedData, a_Copy.m_CompressedData, m_CompressedSize );
|
||||
}
|
||||
|
||||
|
||||
|
@ -141,12 +26,7 @@ void cPacket_MapChunk::Serialize(AString & a_Data) const
|
|||
|
||||
AppendInteger(a_Data, m_PosX);
|
||||
AppendInteger(a_Data, m_PosZ);
|
||||
AppendBool (a_Data, m_bContiguous);
|
||||
AppendShort (a_Data, m_BitMap1);
|
||||
AppendShort (a_Data, m_BitMap2);
|
||||
AppendInteger(a_Data, m_CompressedSize);
|
||||
AppendInteger(a_Data, m_UnusedInt);
|
||||
AppendData (a_Data, m_CompressedData, m_CompressedSize);
|
||||
a_Data.append(m_SerializedData);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -15,29 +15,18 @@ public:
|
|||
cPacket_MapChunk()
|
||||
: m_PosX( 0 )
|
||||
, m_PosZ( 0 )
|
||||
, m_bContiguous( false )
|
||||
, m_BitMap1( 0 )
|
||||
, m_BitMap2( 0 )
|
||||
, m_CompressedSize( 0 )
|
||||
, m_UnusedInt( 0 )
|
||||
, m_CompressedData( NULL )
|
||||
{ m_PacketID = E_MAP_CHUNK; }
|
||||
{
|
||||
m_PacketID = E_MAP_CHUNK;
|
||||
}
|
||||
|
||||
cPacket_MapChunk( const cPacket_MapChunk & a_Copy );
|
||||
cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const BLOCKTYPE * a_BlockData, const unsigned char * a_BiomeData);
|
||||
~cPacket_MapChunk();
|
||||
cPacket_MapChunk(int a_ChunkX, int a_ChunkZ, const AString & a_SerializedData);
|
||||
virtual cPacket* Clone() const { return new cPacket_MapChunk(*this); }
|
||||
|
||||
virtual void Serialize(AString & a_Data) const override;
|
||||
|
||||
int m_PosX;
|
||||
int m_PosZ;
|
||||
bool m_bContiguous;
|
||||
short m_BitMap1;
|
||||
short m_BitMap2;
|
||||
int m_CompressedSize;
|
||||
int m_UnusedInt;
|
||||
char * m_CompressedData;
|
||||
int m_PosX;
|
||||
int m_PosZ;
|
||||
AString m_SerializedData;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue