the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
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