the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 173 lines 4.3 kB view raw
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}