the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 167 lines 4.4 kB view raw
1#include "stdafx.h" 2#include <iostream> 3#include <exception> 4#include "InputOutputStream.h" 5#include "net.minecraft.world.level.h" 6#include "compression.h" 7#include "PacketListener.h" 8#include "BlockRegionUpdatePacket.h" 9#include "LevelChunk.h" 10#include "DataLayer.h" 11#include "Dimension.h" 12 13 14#define BLOCK_REGION_UPDATE_FULLCHUNK 0x01 15#define BLOCK_REGION_UPDATE_ZEROHEIGHT 0x02 // added so we can still send a byte for ys, which really needs the range 0-256 16 17BlockRegionUpdatePacket::~BlockRegionUpdatePacket() 18{ 19 delete [] buffer.data; 20} 21 22BlockRegionUpdatePacket::BlockRegionUpdatePacket() 23{ 24 shouldDelay = true; 25 x = 0; 26 y = 0; 27 z = 0; 28 xs = 0; 29 ys = 0; 30 zs = 0; 31 bIsFullChunk = false; 32} 33 34BlockRegionUpdatePacket::BlockRegionUpdatePacket(int x, int y, int z, int xs, int ys, int zs, Level *level) 35{ 36 37 shouldDelay = true; 38 this->x = x; 39 this->y = y; 40 this->z = z; 41 this->xs = xs; 42 this->ys = ys; 43 this->zs = zs; 44 bIsFullChunk = false; 45 levelIdx = ( ( level->dimension->id == 0 ) ? 0 : ( (level->dimension->id == -1) ? 1 : 2 ) ); 46 47 // 4J - if we are compressing a full chunk, re-order the blocks so that they compress better 48 // TODO - we should be using compressed data directly here rather than decompressing first and then recompressing... 49 byteArray rawBuffer; 50 51 if( xs == 16 && ys == Level::maxBuildHeight && zs == 16 && ( ( x & 15 ) == 0 ) && ( y == 0 ) && ( ( z & 15 ) == 0 ) ) 52 { 53 bIsFullChunk = true; 54 55 LevelChunk *lc = level->getChunkAt(x,z); 56 rawBuffer = lc->getReorderedBlocksAndData(x&0xF, y, z&0xF, xs, this->ys, zs); 57 } 58 else 59 { 60 MemSect(50); 61 rawBuffer = level->getBlocksAndData(x, y, z, xs, ys, zs, false); 62 MemSect(0); 63 } 64 65 if(rawBuffer.length == 0) 66 { 67 size = 0; 68 buffer = byteArray(); 69 } 70 else 71 { 72 // We don't know how this will compress - just make a fixed length buffer to initially decompress into 73 // Some small sets of blocks can end up compressing into something bigger than their source 74 unsigned char *ucTemp = new unsigned char[(256 * 16 * 16 * 5)/2]; 75 unsigned int inputSize = (256 * 16 * 16 * 5)/2; 76 77 Compression::getCompression()->CompressLZXRLE(ucTemp, &inputSize, rawBuffer.data, (unsigned int) rawBuffer.length); 78 //app.DebugPrintf("Chunk (%d,%d) compressed from %d to size %d\n", x>>4, z>>4, rawBuffer.length, inputSize); 79 unsigned char *ucTemp2 = new unsigned char[inputSize]; 80 memcpy(ucTemp2,ucTemp,inputSize); 81 delete [] ucTemp; 82 buffer = byteArray(ucTemp2,inputSize); 83 delete [] rawBuffer.data; 84 size = inputSize; 85 } 86} 87 88void BlockRegionUpdatePacket::read(DataInputStream *dis) //throws IOException 89{ 90 byte chunkFlags = dis->readByte(); 91 x = dis->readInt(); 92 y = dis->readShort(); 93 z = dis->readInt(); 94 xs = dis->read() + 1; 95 ys = dis->read() + 1; 96 zs = dis->read() + 1; 97 98 bIsFullChunk = (chunkFlags & BLOCK_REGION_UPDATE_FULLCHUNK) ? true : false; 99 if(chunkFlags & BLOCK_REGION_UPDATE_ZEROHEIGHT) 100 ys = 0; 101 102 size = dis->readInt(); 103 levelIdx = ( size >> 30 ) & 3; 104 size &= 0x3fffffff; 105 106 if(size == 0) 107 { 108 buffer = byteArray(); 109 } 110 else 111 { 112 byteArray compressedBuffer(size); 113 bool success = dis->readFully(compressedBuffer); 114 115 int bufferSize = xs * ys * zs * 5/2; 116 // Add the size of the biome data if it's a full chunk 117 if(bIsFullChunk) bufferSize += (16*16); 118 buffer = byteArray(bufferSize); 119 unsigned int outputSize = buffer.length; 120 121 if( success ) 122 { 123 Compression::getCompression()->DecompressLZXRLE( buffer.data, &outputSize, compressedBuffer.data, size); 124 } 125 else 126 { 127 app.DebugPrintf("Not decompressing packet that wasn't fully read\n"); 128 } 129 130 // printf("Block (%d %d %d), (%d %d %d) coming in decomp from %d to %d\n",x,y,z,xs,ys,zs,size,outputSize); 131 132 133 delete [] compressedBuffer.data; 134 assert(buffer.length == outputSize); 135 } 136} 137 138void BlockRegionUpdatePacket::write(DataOutputStream *dos) // throws IOException 139{ 140 byte chunkFlags = 0; 141 if(bIsFullChunk) chunkFlags |= BLOCK_REGION_UPDATE_FULLCHUNK; 142 if(ys == 0) chunkFlags |= BLOCK_REGION_UPDATE_ZEROHEIGHT; 143 144 dos->writeByte(chunkFlags); 145 dos->writeInt(x); 146 dos->writeShort(y); 147 dos->writeInt(z); 148 dos->write(xs - 1); 149 dos->write(ys - 1); 150 dos->write(zs - 1); 151 152 int sizeAndLevel = size; 153 sizeAndLevel |= ( levelIdx << 30 ); 154 dos->writeInt(sizeAndLevel); 155 dos->write(buffer, 0, size); 156} 157 158void BlockRegionUpdatePacket::handle(PacketListener *listener) 159{ 160 listener->handleBlockRegionUpdate(shared_from_this()); 161} 162 163int BlockRegionUpdatePacket::getEstimatedSize() 164{ 165 return 17 + size; 166} 167