mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Improve ReadBlockStatesField
This commit is contained in:
parent
cd45c64300
commit
e09016cea5
3 changed files with 28 additions and 9 deletions
|
|
@ -19,7 +19,17 @@ namespace MinecraftClient.Mapping
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Blocks contained into the chunk
|
/// Blocks contained into the chunk
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Block[,,] blocks = new Block[SizeX, SizeY, SizeZ];
|
private readonly Block[] blocks;
|
||||||
|
|
||||||
|
public Chunk()
|
||||||
|
{
|
||||||
|
this.blocks = new Block[SizeY * SizeZ * SizeX];
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chunk(Block[] blocks)
|
||||||
|
{
|
||||||
|
this.blocks = blocks;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read, or set the specified block
|
/// Read, or set the specified block
|
||||||
|
|
@ -39,7 +49,7 @@ namespace MinecraftClient.Mapping
|
||||||
if (blockZ < 0 || blockZ >= SizeZ)
|
if (blockZ < 0 || blockZ >= SizeZ)
|
||||||
throw new ArgumentOutOfRangeException("blockZ", "Must be between 0 and " + (SizeZ - 1) + " (inclusive)");
|
throw new ArgumentOutOfRangeException("blockZ", "Must be between 0 and " + (SizeZ - 1) + " (inclusive)");
|
||||||
|
|
||||||
return blocks[blockY, blockZ, blockX];
|
return blocks[(blockY << 8) | (blockZ << 4) | blockX];
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
|
@ -50,7 +60,7 @@ namespace MinecraftClient.Mapping
|
||||||
if (blockZ < 0 || blockZ >= SizeZ)
|
if (blockZ < 0 || blockZ >= SizeZ)
|
||||||
throw new ArgumentOutOfRangeException("blockZ", "Must be between 0 and " + (SizeZ - 1) + " (inclusive)");
|
throw new ArgumentOutOfRangeException("blockZ", "Must be between 0 and " + (SizeZ - 1) + " (inclusive)");
|
||||||
|
|
||||||
blocks[blockY, blockZ, blockX] = value;
|
blocks[(blockY << 8) | (blockZ << 4) | blockX] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,7 +74,7 @@ namespace MinecraftClient.Mapping
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public void SetWithoutCheck(int blockX, int blockY, int blockZ, Block block)
|
public void SetWithoutCheck(int blockX, int blockY, int blockZ, Block block)
|
||||||
{
|
{
|
||||||
blocks[blockY, blockZ, blockX] = block;
|
blocks[(blockY << 8) | (blockZ << 4) | blockX] = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,12 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read some data from a cache of bytes and remove it from the cache
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cache">Cache of bytes to read from</param>
|
||||||
|
/// <param name="dest">Storage results</param>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public void ReadDataReverse(Queue<byte> cache, Span<byte> dest)
|
public void ReadDataReverse(Queue<byte> cache, Span<byte> dest)
|
||||||
{
|
{
|
||||||
for (int i = (dest.Length - 1); i >= 0; --i)
|
for (int i = (dest.Length - 1); i >= 0; --i)
|
||||||
|
|
|
||||||
|
|
@ -86,9 +86,10 @@ 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
|
||||||
dataTypes.SkipNextVarInt(cache);
|
dataTypes.SkipNextVarInt(cache);
|
||||||
Span<byte> entryDataByte = stackalloc byte[8];
|
Span<byte> entryDataByte = stackalloc byte[8];
|
||||||
|
Span<long> entryDataLong = MemoryMarshal.Cast<byte, long>(entryDataByte);
|
||||||
dataTypes.ReadDataReverse(cache, entryDataByte); // read long
|
dataTypes.ReadDataReverse(cache, entryDataByte); // read long
|
||||||
|
|
||||||
Chunk chunk = new();
|
Block[] blocks = new Block[Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ];
|
||||||
int startOffset = 0 - bitsPerEntry;
|
int startOffset = 0 - bitsPerEntry;
|
||||||
for (int blockY = 0; blockY < Chunk.SizeY; blockY++)
|
for (int blockY = 0; blockY < Chunk.SizeY; blockY++)
|
||||||
{
|
{
|
||||||
|
|
@ -112,7 +113,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
|
|
||||||
// NOTICE: In the future a single ushort may not store the entire block id;
|
// 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
|
// the Block class may need to change if block state IDs go beyond 65535
|
||||||
ushort blockId = (ushort)((MemoryMarshal.Read<long>(entryDataByte) >> startOffset) & valueMask);
|
uint blockId = (uint)(entryDataLong[0] >> startOffset) & valueMask;
|
||||||
|
|
||||||
// Map small IDs to actual larger block IDs
|
// Map small IDs to actual larger block IDs
|
||||||
if (usePalette)
|
if (usePalette)
|
||||||
|
|
@ -127,15 +128,17 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
blockNumber));
|
blockNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
blockId = (ushort)palette[blockId];
|
blockId = palette[(int)blockId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Block block = new((ushort)blockId);
|
||||||
|
|
||||||
// We have our block, save the block into the chunk
|
// We have our block, save the block into the chunk
|
||||||
chunk.SetWithoutCheck(blockX, blockY, blockZ, new Block(blockId));
|
blocks[(blockY << 8) | (blockZ << 4) | blockX] = block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return chunk;
|
return new Chunk(blocks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue