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 "InputOutputStream.h"
4#include "net.minecraft.world.level.h"
5#include "net.minecraft.world.level.chunk.h"
6#include "PacketListener.h"
7#include "ChunkTilesUpdatePacket.h"
8#include "Dimension.h"
9
10
11
12ChunkTilesUpdatePacket::~ChunkTilesUpdatePacket()
13{
14 delete [] blocks.data;
15 delete [] data.data;
16 delete [] positions.data;
17}
18
19ChunkTilesUpdatePacket::ChunkTilesUpdatePacket()
20{
21 shouldDelay = true;
22 xc = 0;
23 zc = 0;
24 count = 0;
25}
26
27ChunkTilesUpdatePacket::ChunkTilesUpdatePacket(int xc, int zc, shortArray positions, byte count, Level *level)
28{
29 shouldDelay = true;
30 this->xc = xc;
31 this->zc = zc;
32 this->count = count;
33 this->positions = shortArray(count);
34
35 this->blocks = byteArray(count);
36 this->data = byteArray(count);
37 LevelChunk *levelChunk = level->getChunk(xc, zc);
38 for (int i = 0; i < count; i++)
39 {
40 int x = (positions[i] >> 12) & 15;
41 int z = (positions[i] >> 8) & 15;
42 int y = (positions[i]) & 255;
43
44 this->positions[i] = positions[i];
45 blocks[i] = (byte) levelChunk->getTile(x, y, z);
46 data[i] = (byte) levelChunk->getData(x, y, z);
47 }
48 levelIdx = ( ( level->dimension->id == 0 ) ? 0 : ( (level->dimension->id == -1) ? 1 : 2 ) );
49}
50
51void ChunkTilesUpdatePacket::read(DataInputStream *dis) //throws IOException
52{
53 // 4J - changed format. See comments in write method.
54#ifdef _LARGE_WORLDS
55 xc = dis->readShort();
56 zc = dis->readShort();
57 xc = ( xc << 16 ) >> 16;
58 zc = ( zc << 16 ) >> 16;
59#else
60 xc = dis->read();
61 zc = dis->read();
62 xc = ( xc << 24 ) >> 24;
63 zc = ( zc << 24 ) >> 24;
64#endif
65
66 int countAndFlags = dis->readByte();
67 bool dataAllZero = (( countAndFlags & 0x80 ) == 0x80 );
68 levelIdx = ( countAndFlags >> 5 ) & 3;
69 count = countAndFlags & 0x1f;
70
71 positions = shortArray(count);
72 blocks = byteArray(count);
73 data = byteArray(count);
74
75 int currentBlockType = -1;
76 for( int i = 0; i < count; i++ )
77 {
78 int xzAndFlag = dis->readShort();
79 int y = dis->readByte();
80 positions[i] = (xzAndFlag & 0xff00) | (y & 0xff);
81 if( ( xzAndFlag & 0x0080 ) == 0x0080 )
82 {
83 currentBlockType = dis->read();
84 }
85 blocks[i] = currentBlockType;
86 if( !dataAllZero)
87 {
88 data[i] = dis->read();
89 }
90 else
91 {
92 data[i] = 0;
93 }
94 }
95}
96
97void ChunkTilesUpdatePacket::write(DataOutputStream *dos) //throws IOException
98{
99 // 4J - changed format to reduce size of these packets.
100#ifdef _LARGE_WORLDS
101 dos->writeShort(xc);
102 dos->writeShort(zc);
103#else
104 dos->write(xc);
105 dos->write(zc);
106#endif
107 // Determine if we've got any data elements that are non-zero - a large % of these packets set all data to zero, so we don't
108 // bother sending all those zeros in that case.
109 bool dataAllZero = true;
110 for( int i = 0; i < count; i++ )
111 {
112 if( data[i] ) dataAllZero = false;
113 }
114 int countAndFlags = count;
115 if( dataAllZero ) countAndFlags |= 0x80;
116 countAndFlags |= ( levelIdx << 5 );
117 dos->write(countAndFlags);
118 int lastBlockType = -1;
119 // Each block is represented by 15 bits of position, a flag to say whether the current block type is to change, and a possible data value.
120 // A large % of these packets set the same block type to a several positions, so no point resending the block type when not necessary.
121 for( int i = 0; i < count; i++ )
122 {
123 int xzAndFlag = positions[i] &0xff00;
124 int y = positions[i] & 0xff;
125 int thisBlockType = blocks[i];
126 if( thisBlockType != lastBlockType )
127 {
128 xzAndFlag |= 0x0080; // Use top bit of y as a flag, we only need 7 bits for that
129 dos->writeShort(xzAndFlag);
130 dos->write(y);
131 dos->write(thisBlockType);
132 lastBlockType = thisBlockType;
133 }
134 else
135 {
136 dos->writeShort(xzAndFlag);
137 dos->write(y);
138 }
139 if( !dataAllZero )
140 {
141 dos->write(data[i]);
142 }
143 }
144}
145
146void ChunkTilesUpdatePacket::handle(PacketListener *listener)
147{
148 listener->handleChunkTilesUpdate(shared_from_this());
149}
150
151int ChunkTilesUpdatePacket::getEstimatedSize()
152{
153 bool dataAllZero = true;
154 int lastBlockType = -1;
155 int blockTypeChanges = 0;
156 for( int i = 0; i < count; i++ )
157 {
158 if( data[i] ) dataAllZero = false;
159 int thisBlockType = blocks[i];
160 if( thisBlockType != lastBlockType )
161 {
162 blockTypeChanges++;
163 lastBlockType = thisBlockType;
164 }
165 }
166 int byteCount = 3 + 2 * count + blockTypeChanges;
167 if( !dataAllZero )
168 {
169 byteCount += count;
170 }
171
172 return byteCount;
173}