mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
1.16+ Terrain and Movement support (#1353)
* First implementation * Improve chunk reading performance * Fix indentation * Remove debug information * Update MultiBlockChange packet * Move skip varint to a method * Fix crash when not using block palette * Fix DataTypes.cs not compiling on .NET 4.0 Binary (0b) values not handled so converted to Hexadecimal (0x) * Use the 1.16 chunk parsing code for 1.15 too Document the differences in padding and factor the code Co-authored-by: ORelio <ORelio@users.noreply.github.com>
This commit is contained in:
parent
9b5fde0689
commit
53bd56100f
6 changed files with 1505 additions and 44 deletions
|
|
@ -75,43 +75,86 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
// EG, if bitsPerBlock = 5, valueMask = 00011111 in binary
|
||||
uint valueMask = (uint)((1 << bitsPerBlock) - 1);
|
||||
|
||||
// Block IDs are packed in the array of 64-bits integers
|
||||
ulong[] dataArray = dataTypes.ReadNextULongArray(cache);
|
||||
|
||||
Chunk chunk = new Chunk();
|
||||
|
||||
if (dataArray.Length > 0)
|
||||
{
|
||||
int longIndex = 0;
|
||||
int startOffset = 0 - bitsPerBlock;
|
||||
|
||||
for (int blockY = 0; blockY < Chunk.SizeY; blockY++)
|
||||
{
|
||||
for (int blockZ = 0; blockZ < Chunk.SizeZ; blockZ++)
|
||||
{
|
||||
for (int blockX = 0; blockX < Chunk.SizeX; blockX++)
|
||||
{
|
||||
int blockNumber = (blockY * Chunk.SizeZ + blockZ) * Chunk.SizeX + blockX;
|
||||
|
||||
int startLong = (blockNumber * bitsPerBlock) / 64;
|
||||
int startOffset = (blockNumber * bitsPerBlock) % 64;
|
||||
int endLong = ((blockNumber + 1) * bitsPerBlock - 1) / 64;
|
||||
|
||||
// TODO: In the future a single ushort may not store the entire block id;
|
||||
// the Block code may need to change if block state IDs go beyond 65535
|
||||
// NOTICE: In the future a single ushort may not store the entire block id;
|
||||
// the Block class may need to change if block state IDs go beyond 65535
|
||||
ushort blockId;
|
||||
if (startLong == endLong)
|
||||
|
||||
// Calculate location of next block ID inside the array of Longs
|
||||
startOffset += bitsPerBlock;
|
||||
bool overlap = false;
|
||||
|
||||
if ((startOffset + bitsPerBlock) > 64)
|
||||
{
|
||||
blockId = (ushort)((dataArray[startLong] >> startOffset) & valueMask);
|
||||
if (protocolversion >= Protocol18Handler.MC116Version)
|
||||
{
|
||||
// In MC 1.16+, padding is applied to prevent overlapping between Longs:
|
||||
// [ LONG INTEGER ][ LONG INTEGER ]
|
||||
// [Block][Block][Block]XXXXX[Block][Block][Block]XXXXX
|
||||
|
||||
// When overlapping, move forward to the beginning of the next Long
|
||||
startOffset = 0;
|
||||
longIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// In MC 1.15 and lower, block IDs can overlap between Longs:
|
||||
// [ LONG INTEGER ][ LONG INTEGER ]
|
||||
// [Block][Block][Block][Blo ck][Block][Block][Block][
|
||||
|
||||
// Detect when we reached the next Long or switch to overlap mode
|
||||
if (startOffset >= 64)
|
||||
{
|
||||
startOffset -= 64;
|
||||
longIndex++;
|
||||
}
|
||||
else overlap = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Extract Block ID
|
||||
if (overlap)
|
||||
{
|
||||
int endOffset = 64 - startOffset;
|
||||
blockId = (ushort)((dataArray[longIndex] >> startOffset | dataArray[longIndex + 1] << endOffset) & valueMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
int endOffset = 64 - startOffset;
|
||||
blockId = (ushort)((dataArray[startLong] >> startOffset | dataArray[endLong] << endOffset) & valueMask);
|
||||
blockId = (ushort)((dataArray[longIndex] >> startOffset) & valueMask);
|
||||
}
|
||||
|
||||
// Map small IDs to actual larger block IDs
|
||||
if (usePalette)
|
||||
{
|
||||
// Get the real block ID out of the palette
|
||||
if (paletteLength <= blockId)
|
||||
{
|
||||
int blockNumber = (blockY * Chunk.SizeZ + blockZ) * Chunk.SizeX + blockX;
|
||||
throw new IndexOutOfRangeException(String.Format("Block ID {0} is outside Palette range 0-{1}! (bitsPerBlock: {2}, blockNumber: {3})",
|
||||
blockId,
|
||||
paletteLength - 1,
|
||||
bitsPerBlock,
|
||||
blockNumber));
|
||||
}
|
||||
|
||||
blockId = (ushort)palette[blockId];
|
||||
}
|
||||
|
||||
// We have our block, save the block into the chunk
|
||||
chunk[blockX, blockY, blockZ] = new Block(blockId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue