first commit
This commit is contained in:
157
Minecraft.World/BlockRegionUpdatePacket.cpp
Normal file
157
Minecraft.World/BlockRegionUpdatePacket.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
#include "stdafx.h"
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include "InputOutputStream.h"
|
||||
#include "net.minecraft.world.level.h"
|
||||
#include "compression.h"
|
||||
#include "PacketListener.h"
|
||||
#include "BlockRegionUpdatePacket.h"
|
||||
#include "LevelChunk.h"
|
||||
#include "DataLayer.h"
|
||||
#include "Dimension.h"
|
||||
|
||||
|
||||
|
||||
BlockRegionUpdatePacket::~BlockRegionUpdatePacket()
|
||||
{
|
||||
delete [] buffer.data;
|
||||
}
|
||||
|
||||
BlockRegionUpdatePacket::BlockRegionUpdatePacket()
|
||||
{
|
||||
shouldDelay = true;
|
||||
x = 0;
|
||||
y = 0;
|
||||
z = 0;
|
||||
xs = 0;
|
||||
ys = 0;
|
||||
zs = 0;
|
||||
bIsFullChunk = false;
|
||||
}
|
||||
|
||||
BlockRegionUpdatePacket::BlockRegionUpdatePacket(int x, int y, int z, int xs, int ys, int zs, Level *level)
|
||||
{
|
||||
|
||||
shouldDelay = true;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
this->xs = xs;
|
||||
this->ys = ys;
|
||||
this->zs = zs;
|
||||
bIsFullChunk = false;
|
||||
levelIdx = ( ( level->dimension->id == 0 ) ? 0 : ( (level->dimension->id == -1) ? 1 : 2 ) );
|
||||
|
||||
// 4J - if we are compressing a full chunk, re-order the blocks so that they compress better
|
||||
// TODO - we should be using compressed data directly here rather than decompressing first and then recompressing...
|
||||
byteArray rawBuffer;
|
||||
|
||||
if( xs == 16 && ys == Level::maxBuildHeight && zs == 16 && ( ( x & 15 ) == 0 ) && ( y == 0 ) && ( ( z & 15 ) == 0 ) )
|
||||
{
|
||||
bIsFullChunk = true;
|
||||
|
||||
LevelChunk *lc = level->getChunkAt(x,z);
|
||||
rawBuffer = lc->getReorderedBlocksAndData(x&0xF, y, z&0xF, xs, this->ys, zs);
|
||||
}
|
||||
else
|
||||
{
|
||||
MemSect(50);
|
||||
rawBuffer = level->getBlocksAndData(x, y, z, xs, ys, zs, false);
|
||||
MemSect(0);
|
||||
}
|
||||
|
||||
if(rawBuffer.length == 0)
|
||||
{
|
||||
size = 0;
|
||||
buffer = byteArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't know how this will compress - just make a fixed length buffer to initially decompress into
|
||||
// Some small sets of blocks can end up compressing into something bigger than their source
|
||||
unsigned char *ucTemp = new unsigned char[(256 * 16 * 16 * 5)/2];
|
||||
unsigned int inputSize = (256 * 16 * 16 * 5)/2;
|
||||
|
||||
Compression::getCompression()->CompressLZXRLE(ucTemp, &inputSize, rawBuffer.data, (unsigned int) rawBuffer.length);
|
||||
//app.DebugPrintf("Chunk (%d,%d) compressed from %d to size %d\n", x>>4, z>>4, rawBuffer.length, inputSize);
|
||||
unsigned char *ucTemp2 = new unsigned char[inputSize];
|
||||
memcpy(ucTemp2,ucTemp,inputSize);
|
||||
delete [] ucTemp;
|
||||
buffer = byteArray(ucTemp2,inputSize);
|
||||
delete [] rawBuffer.data;
|
||||
size = inputSize;
|
||||
}
|
||||
}
|
||||
|
||||
void BlockRegionUpdatePacket::read(DataInputStream *dis) //throws IOException
|
||||
{
|
||||
bIsFullChunk = dis->readBoolean();
|
||||
x = dis->readInt();
|
||||
y = dis->readShort();
|
||||
z = dis->readInt();
|
||||
xs = dis->read() + 1;
|
||||
ys = dis->read() + 1;
|
||||
zs = dis->read() + 1;
|
||||
|
||||
size = dis->readInt();
|
||||
levelIdx = ( size >> 30 ) & 3;
|
||||
size &= 0x3fffffff;
|
||||
|
||||
if(size == 0)
|
||||
{
|
||||
buffer = byteArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
byteArray compressedBuffer(size);
|
||||
bool success = dis->readFully(compressedBuffer);
|
||||
|
||||
int bufferSize = xs * ys * zs * 5/2;
|
||||
// Add the size of the biome data if it's a full chunk
|
||||
if(bIsFullChunk) bufferSize += (16*16);
|
||||
buffer = byteArray(bufferSize);
|
||||
unsigned int outputSize = buffer.length;
|
||||
|
||||
if( success )
|
||||
{
|
||||
Compression::getCompression()->DecompressLZXRLE( buffer.data, &outputSize, compressedBuffer.data, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
app.DebugPrintf("Not decompressing packet that wasn't fully read\n");
|
||||
}
|
||||
|
||||
// printf("Block (%d %d %d), (%d %d %d) coming in decomp from %d to %d\n",x,y,z,xs,ys,zs,size,outputSize);
|
||||
|
||||
|
||||
delete [] compressedBuffer.data;
|
||||
assert(buffer.length == outputSize);
|
||||
}
|
||||
}
|
||||
|
||||
void BlockRegionUpdatePacket::write(DataOutputStream *dos) // throws IOException
|
||||
{
|
||||
dos->writeBoolean(bIsFullChunk);
|
||||
dos->writeInt(x);
|
||||
dos->writeShort(y);
|
||||
dos->writeInt(z);
|
||||
dos->write(xs - 1);
|
||||
dos->write(ys - 1);
|
||||
dos->write(zs - 1);
|
||||
|
||||
int sizeAndLevel = size;
|
||||
sizeAndLevel |= ( levelIdx << 30 );
|
||||
dos->writeInt(sizeAndLevel);
|
||||
dos->write(buffer, 0, size);
|
||||
}
|
||||
|
||||
void BlockRegionUpdatePacket::handle(PacketListener *listener)
|
||||
{
|
||||
listener->handleBlockRegionUpdate(shared_from_this());
|
||||
}
|
||||
|
||||
int BlockRegionUpdatePacket::getEstimatedSize()
|
||||
{
|
||||
return 17 + size;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user