mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-11-07 17:36:07 +00:00
Improve ReadBlockStatesField
This commit is contained in:
parent
64915c87cf
commit
5f520e2cf4
3 changed files with 20 additions and 22 deletions
|
|
@ -18,7 +18,7 @@ namespace MinecraftClient.Mapping
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Blocks contained into the chunk
|
/// Blocks contained into the chunk
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Chunk[] chunks;
|
private readonly Chunk?[] chunks;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new ChunkColumn
|
/// Create a new ChunkColumn
|
||||||
|
|
@ -26,7 +26,7 @@ namespace MinecraftClient.Mapping
|
||||||
public ChunkColumn(int size = 16)
|
public ChunkColumn(int size = 16)
|
||||||
{
|
{
|
||||||
ColumnSize = size;
|
ColumnSize = size;
|
||||||
chunks = new Chunk[size];
|
chunks = new Chunk?[size];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -35,7 +35,7 @@ namespace MinecraftClient.Mapping
|
||||||
/// <param name="chunkX">ChunkColumn X</param>
|
/// <param name="chunkX">ChunkColumn X</param>
|
||||||
/// <param name="chunkY">ChunkColumn Y</param>
|
/// <param name="chunkY">ChunkColumn Y</param>
|
||||||
/// <returns>chunk at the given location</returns>
|
/// <returns>chunk at the given location</returns>
|
||||||
public Chunk this[int chunkY]
|
public Chunk? this[int chunkY]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -118,10 +118,9 @@ namespace MinecraftClient.Mapping
|
||||||
/// <param name="chunkColumnSize">ChunkColumn size</param>
|
/// <param name="chunkColumnSize">ChunkColumn size</param>
|
||||||
/// <param name="chunk">Chunk data</param>
|
/// <param name="chunk">Chunk data</param>
|
||||||
/// <param name="loadCompleted">Whether the ChunkColumn has been fully loaded</param>
|
/// <param name="loadCompleted">Whether the ChunkColumn has been fully loaded</param>
|
||||||
public void StoreChunk(int chunkX, int chunkY, int chunkZ, int chunkColumnSize, Chunk chunk, bool loadCompleted)
|
public void StoreChunk(int chunkX, int chunkY, int chunkZ, int chunkColumnSize, Chunk? chunk, bool loadCompleted)
|
||||||
{
|
{
|
||||||
ChunkColumn? chunkColumn = null;
|
ChunkColumn? chunkColumn = null;
|
||||||
|
|
||||||
chunksLock.EnterUpgradeableReadLock();
|
chunksLock.EnterUpgradeableReadLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -151,7 +150,6 @@ namespace MinecraftClient.Mapping
|
||||||
{
|
{
|
||||||
chunksLock.ExitUpgradeableReadLock();
|
chunksLock.ExitUpgradeableReadLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
chunkColumn[chunkY] = chunk;
|
chunkColumn[chunkY] = chunk;
|
||||||
if (loadCompleted)
|
if (loadCompleted)
|
||||||
chunkColumn.FullyLoaded = true;
|
chunkColumn.FullyLoaded = true;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
//using System.Linq;
|
//using System.Linq;
|
||||||
//using System.Text;
|
//using System.Text;
|
||||||
using MinecraftClient.Mapping;
|
using MinecraftClient.Mapping;
|
||||||
|
|
@ -32,9 +33,8 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reading the "Block states" field: consists of 4096 entries, representing all the blocks in the chunk section.
|
/// Reading the "Block states" field: consists of 4096 entries, representing all the blocks in the chunk section.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="chunk">Blocks will store in this chunk</param>
|
|
||||||
/// <param name="cache">Cache for reading data</param>
|
/// <param name="cache">Cache for reading data</param>
|
||||||
private Chunk? ReadBlockStatesField(ref Chunk chunk, Queue<byte> cache)
|
private Chunk? ReadBlockStatesField(Queue<byte> cache)
|
||||||
{
|
{
|
||||||
// read Block states (Type: Paletted Container)
|
// read Block states (Type: Paletted Container)
|
||||||
byte bitsPerEntry = dataTypes.ReadNextByte(cache);
|
byte bitsPerEntry = dataTypes.ReadNextByte(cache);
|
||||||
|
|
@ -44,18 +44,20 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
{
|
{
|
||||||
// Palettes: Single valued - 1.18(1.18.1) and above
|
// Palettes: Single valued - 1.18(1.18.1) and above
|
||||||
ushort blockId = (ushort)dataTypes.ReadNextVarInt(cache);
|
ushort blockId = (ushort)dataTypes.ReadNextVarInt(cache);
|
||||||
|
Block block = new(blockId);
|
||||||
|
|
||||||
dataTypes.SkipNextVarInt(cache); // Data Array Length will be zero
|
dataTypes.SkipNextVarInt(cache); // Data Array Length will be zero
|
||||||
|
|
||||||
// Empty chunks will not be stored
|
// Empty chunks will not be stored
|
||||||
if (new Block(blockId).Type == Material.Air)
|
if (block.Type == Material.Air)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
Chunk chunk = new();
|
||||||
for (int blockY = 0; blockY < Chunk.SizeY; blockY++)
|
for (int blockY = 0; blockY < Chunk.SizeY; blockY++)
|
||||||
for (int blockZ = 0; blockZ < Chunk.SizeZ; blockZ++)
|
for (int blockZ = 0; blockZ < Chunk.SizeZ; blockZ++)
|
||||||
for (int blockX = 0; blockX < Chunk.SizeX; blockX++)
|
for (int blockX = 0; blockX < Chunk.SizeX; blockX++)
|
||||||
chunk.SetWithoutCheck(blockX, blockY, blockZ, new Block(blockId));
|
chunk.SetWithoutCheck(blockX, blockY, blockZ, block);
|
||||||
|
return chunk;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -79,6 +81,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
// Block IDs are packed in the array of 64-bits integers
|
// Block IDs are packed in the array of 64-bits integers
|
||||||
ulong[] dataArray = dataTypes.ReadNextULongArray(cache);
|
ulong[] dataArray = dataTypes.ReadNextULongArray(cache);
|
||||||
|
|
||||||
|
Chunk chunk = new();
|
||||||
int longIndex = 0;
|
int longIndex = 0;
|
||||||
int startOffset = 0 - bitsPerEntry;
|
int startOffset = 0 - bitsPerEntry;
|
||||||
for (int blockY = 0; blockY < Chunk.SizeY; blockY++)
|
for (int blockY = 0; blockY < Chunk.SizeY; blockY++)
|
||||||
|
|
@ -87,10 +90,6 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
{
|
{
|
||||||
for (int blockX = 0; blockX < Chunk.SizeX; blockX++)
|
for (int blockX = 0; blockX < Chunk.SizeX; blockX++)
|
||||||
{
|
{
|
||||||
// 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;
|
|
||||||
|
|
||||||
// Calculate location of next block ID inside the array of Longs
|
// Calculate location of next block ID inside the array of Longs
|
||||||
startOffset += bitsPerEntry;
|
startOffset += bitsPerEntry;
|
||||||
|
|
||||||
|
|
@ -105,8 +104,9 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
longIndex++;
|
longIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract Block ID
|
// NOTICE: In the future a single ushort may not store the entire block id;
|
||||||
blockId = (ushort)((dataArray[longIndex] >> startOffset) & valueMask);
|
// the Block class may need to change if block state IDs go beyond 65535
|
||||||
|
ushort blockId = (ushort)((dataArray[longIndex] >> startOffset) & valueMask);
|
||||||
|
|
||||||
// Map small IDs to actual larger block IDs
|
// Map small IDs to actual larger block IDs
|
||||||
if (usePalette)
|
if (usePalette)
|
||||||
|
|
@ -129,9 +129,8 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
return chunk;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -156,11 +155,13 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
{
|
{
|
||||||
// 1.17 and above chunk format
|
// 1.17 and above chunk format
|
||||||
// Unloading chunks is handled by a separate packet
|
// Unloading chunks is handled by a separate packet
|
||||||
|
|
||||||
for (int chunkY = 0; chunkY < chunkColumnSize; chunkY++)
|
for (int chunkY = 0; chunkY < chunkColumnSize; chunkY++)
|
||||||
{
|
{
|
||||||
int lastChunkY = 0;
|
int lastChunkY;
|
||||||
if (protocolversion == Protocol18Handler.MC_1_17_Version || protocolversion == Protocol18Handler.MC_1_17_1_Version)
|
if (protocolversion == Protocol18Handler.MC_1_17_Version || protocolversion == Protocol18Handler.MC_1_17_1_Version)
|
||||||
{
|
{
|
||||||
|
lastChunkY = 0;
|
||||||
for (int i = verticalStripBitmask!.Length - 1; i >= 0; --i)
|
for (int i = verticalStripBitmask!.Length - 1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
if (verticalStripBitmask![i] != 0)
|
if (verticalStripBitmask![i] != 0)
|
||||||
|
|
@ -187,8 +188,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
int blockCnt = dataTypes.ReadNextShort(cache);
|
int blockCnt = dataTypes.ReadNextShort(cache);
|
||||||
|
|
||||||
// Read Block states (Type: Paletted Container)
|
// Read Block states (Type: Paletted Container)
|
||||||
Chunk chunk = new Chunk();
|
Chunk? chunk = ReadBlockStatesField(cache);
|
||||||
ReadBlockStatesField(ref chunk, cache);
|
|
||||||
|
|
||||||
// check before store chunk
|
// check before store chunk
|
||||||
if (cancellationToken.IsCancellationRequested)
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue