Skip to content

Commit 53bd561

Browse files
1.16+ Terrain and Movement support (MCCTeam#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 <[email protected]>
1 parent 9b5fde0 commit 53bd561

File tree

6 files changed

+1502
-41
lines changed

6 files changed

+1502
-41
lines changed

MinecraftClient/Mapping/BlockPalettes/Palette116.cs

Lines changed: 1250 additions & 0 deletions
Large diffs are not rendered by default.

MinecraftClient/Mapping/Material.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public enum Material
4848
GoldOre,
4949
IronOre,
5050
CoalOre,
51+
NetherGoldOre,
5152
OakLog,
5253
SpruceLog,
5354
BirchLog,
@@ -157,6 +158,7 @@ public enum Material
157158
Torch,
158159
WallTorch,
159160
Fire,
161+
SoulFire,
160162
Spawner,
161163
OakStairs,
162164
Chest,
@@ -207,6 +209,11 @@ public enum Material
207209
Pumpkin,
208210
Netherrack,
209211
SoulSand,
212+
SoulSoil,
213+
Basalt,
214+
PolishedBasalt,
215+
SoulTorch,
216+
SoulWallTorch,
210217
Glowstone,
211218
NetherPortal,
212219
CarvedPumpkin,
@@ -249,6 +256,7 @@ public enum Material
249256
RedMushroomBlock,
250257
MushroomStem,
251258
IronBars,
259+
Chain,
252260
GlassPane,
253261
Melon,
254262
AttachedPumpkinStem,
@@ -685,14 +693,89 @@ public enum Material
685693
Stonecutter,
686694
Bell,
687695
Lantern,
696+
SoulLantern,
688697
Campfire,
698+
SoulCampfire,
689699
SweetBerryBush,
700+
WarpedStem,
701+
StrippedWarpedStem,
702+
WarpedHyphae,
703+
StrippedWarpedHyphae,
704+
WarpedNylium,
705+
WarpedFungus,
706+
WarpedWartBlock,
707+
WarpedRoots,
708+
NetherSprouts,
709+
CrimsonStem,
710+
StrippedCrimsonStem,
711+
CrimsonHyphae,
712+
StrippedCrimsonHyphae,
713+
CrimsonNylium,
714+
CrimsonFungus,
715+
Shroomlight,
716+
WeepingVines,
717+
WeepingVinesPlant,
718+
TwistingVines,
719+
TwistingVinesPlant,
720+
CrimsonRoots,
721+
CrimsonPlanks,
722+
WarpedPlanks,
723+
CrimsonSlab,
724+
WarpedSlab,
725+
CrimsonPressurePlate,
726+
WarpedPressurePlate,
727+
CrimsonFence,
728+
WarpedFence,
729+
CrimsonTrapdoor,
730+
WarpedTrapdoor,
731+
CrimsonFenceGate,
732+
WarpedFenceGate,
733+
CrimsonStairs,
734+
WarpedStairs,
735+
CrimsonButton,
736+
WarpedButton,
737+
CrimsonDoor,
738+
WarpedDoor,
739+
CrimsonSign,
740+
WarpedSign,
741+
CrimsonWallSign,
742+
WarpedWallSign,
690743
StructureBlock,
691744
Jigsaw,
692745
Composter,
746+
Target,
693747
BeeNest,
694748
Beehive,
695749
HoneyBlock,
696750
HoneycombBlock,
751+
NetheriteBlock,
752+
AncientDebris,
753+
CryingObsidian,
754+
RespawnAnchor,
755+
PottedCrimsonFungus,
756+
PottedWarpedFungus,
757+
PottedCrimsonRoots,
758+
PottedWarpedRoots,
759+
Lodestone,
760+
Blackstone,
761+
BlackstoneStairs,
762+
BlackstoneWall,
763+
BlackstoneSlab,
764+
PolishedBlackstone,
765+
PolishedBlackstoneBricks,
766+
CrackedPolishedBlackstoneBricks,
767+
ChiseledPolishedBlackstone,
768+
PolishedBlackstoneBrickSlab,
769+
PolishedBlackstoneBrickStairs,
770+
PolishedBlackstoneBrickWall,
771+
GildedBlackstone,
772+
PolishedBlackstoneStairs,
773+
PolishedBlackstoneSlab,
774+
PolishedBlackstonePressurePlate,
775+
PolishedBlackstoneButton,
776+
PolishedBlackstoneWall,
777+
ChiseledNetherBricks,
778+
CrackedNetherBricks,
779+
QuartzBricks,
697780
}
698781
}

MinecraftClient/MinecraftClient.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@
141141
<Compile Include="Mapping\BlockPalettes\Palette115.cs" />
142142
<Compile Include="Mapping\BlockPalettes\BlockPaletteGenerator.cs" />
143143
<Compile Include="Mapping\BlockPalettes\BlockPalette.cs" />
144+
<Compile Include="Mapping\BlockPalettes\Palette116.cs" />
144145
<Compile Include="Mapping\CommandBlockFlags.cs" />
145146
<Compile Include="Mapping\CommandBlockMode.cs" />
146147
<Compile Include="Mapping\Entity.cs" />
@@ -401,4 +402,4 @@
401402
<Target Name="AfterBuild">
402403
</Target>
403404
-->
404-
</Project>
405+
</Project>

MinecraftClient/Protocol/Handlers/DataTypes.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,19 @@ public int ReadNextVarInt(Queue<byte> cache)
267267
return i;
268268
}
269269

270+
/// <summary>
271+
/// Skip a VarInt from a cache of bytes with better performance
272+
/// </summary>
273+
/// <param name="cache">Cache of bytes to read from</param>
274+
public void SkipNextVarInt(Queue<byte> cache)
275+
{
276+
while (true)
277+
{
278+
if ((ReadNextByte(cache) & 0x80) != 128)
279+
break;
280+
}
281+
}
282+
270283
/// <summary>
271284
/// Read an "extended short", which is actually an int of some kind, from the cache of bytes.
272285
/// This is only done with forge. It looks like it's a normal short, except that if the high
@@ -286,6 +299,31 @@ public int ReadNextVarShort(Queue<byte> cache)
286299
return ((high & 0xFF) << 15) | low;
287300
}
288301

302+
/// <summary>
303+
/// Read a long from a cache of bytes and remove it from the cache
304+
/// </summary>
305+
/// <param name="cache">Cache of bytes to read from</param>
306+
/// <returns>The long value</returns>
307+
public long ReadNextVarLong(Queue<byte> cache)
308+
{
309+
int numRead = 0;
310+
long result = 0;
311+
byte read;
312+
do
313+
{
314+
read = ReadNextByte(cache);
315+
long value = (read & 0x7F);
316+
result |= (value << (7 * numRead));
317+
318+
numRead++;
319+
if (numRead > 10)
320+
{
321+
throw new OverflowException("VarLong is too big");
322+
}
323+
} while ((read & 0x80) != 0);
324+
return result;
325+
}
326+
289327
/// <summary>
290328
/// Read a single byte from a cache of bytes and remove it from the cache
291329
/// </summary>

MinecraftClient/Protocol/Handlers/Protocol18.cs

Lines changed: 74 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan
8080
this.pTerrain = new Protocol18Terrain(protocolVersion, dataTypes, handler);
8181
this.packetPalette = new PacketTypeHandler(protocolVersion).GetTypeHandler();
8282

83-
if (handler.GetTerrainEnabled() && protocolversion > MC1152Version)
83+
if (handler.GetTerrainEnabled() && protocolversion > MC1164Version)
8484
{
8585
Translations.WriteLineFormatted("extra.terrainandmovement_disabled");
8686
handler.SetTerrainEnabled(false);
@@ -101,9 +101,11 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan
101101
// Block palette
102102
if (protocolversion >= MC113Version)
103103
{
104-
if (protocolVersion > MC1152Version && handler.GetTerrainEnabled())
104+
if (protocolVersion > MC1164Version && handler.GetTerrainEnabled())
105105
throw new NotImplementedException(Translations.Get("exception.palette.block"));
106-
if (protocolVersion >= MC115Version)
106+
if (protocolVersion >= MC116Version)
107+
Block.Palette = new Palette116();
108+
else if (protocolVersion >= MC115Version)
107109
Block.Palette = new Palette115();
108110
else if (protocolVersion >= MC114Version)
109111
Block.Palette = new Palette114();
@@ -398,6 +400,8 @@ internal bool HandlePacket(int packetID, Queue<byte> packetData)
398400
int chunkX = dataTypes.ReadNextInt(packetData);
399401
int chunkZ = dataTypes.ReadNextInt(packetData);
400402
bool chunksContinuous = dataTypes.ReadNextBool(packetData);
403+
if (protocolversion >= MC116Version && protocolversion <= MC1161Version)
404+
dataTypes.ReadNextBool(packetData); // Ignore old data - 1.16 to 1.16.1 only
401405
ushort chunkMask = protocolversion >= MC19Version
402406
? (ushort)dataTypes.ReadNextVarInt(packetData)
403407
: dataTypes.ReadNextUShort(packetData);
@@ -413,8 +417,23 @@ internal bool HandlePacket(int packetID, Queue<byte> packetData)
413417
{
414418
if (protocolversion >= MC114Version)
415419
dataTypes.ReadNextNbt(packetData); // Heightmaps - 1.14 and above
420+
int biomesLength = 0;
421+
if (protocolversion >= MC1162Version)
422+
if (chunksContinuous)
423+
biomesLength = dataTypes.ReadNextVarInt(packetData); // Biomes length - 1.16.2 and above
416424
if (protocolversion >= MC115Version && chunksContinuous)
417-
dataTypes.ReadData(1024 * 4, packetData); // Biomes - 1.15 and above
425+
{
426+
if (protocolversion >= MC1162Version)
427+
{
428+
for (int i = 0; i < biomesLength; i++)
429+
{
430+
// Biomes - 1.16.2 and above
431+
// Don't use ReadNextVarInt because it cost too much time
432+
dataTypes.SkipNextVarInt(packetData);
433+
}
434+
}
435+
else dataTypes.ReadData(1024 * 4, packetData); // Biomes - 1.15 and above
436+
}
418437
int dataSize = dataTypes.ReadNextVarInt(packetData);
419438
pTerrain.ProcessChunkColumnData(chunkX, chunkZ, chunkMask, 0, false, chunksContinuous, currentDimension, packetData);
420439
}
@@ -514,35 +533,62 @@ internal bool HandlePacket(int packetID, Queue<byte> packetData)
514533
case PacketTypesIn.MultiBlockChange:
515534
if (handler.GetTerrainEnabled())
516535
{
517-
int chunkX = dataTypes.ReadNextInt(packetData);
518-
int chunkZ = dataTypes.ReadNextInt(packetData);
519-
int recordCount = protocolversion < MC18Version
520-
? (int)dataTypes.ReadNextShort(packetData)
521-
: dataTypes.ReadNextVarInt(packetData);
522-
523-
for (int i = 0; i < recordCount; i++)
536+
if (protocolversion >= MC1162Version)
524537
{
525-
byte locationXZ;
526-
ushort blockIdMeta;
527-
int blockY;
528-
529-
if (protocolversion < MC18Version)
538+
long chunkSection = dataTypes.ReadNextLong(packetData);
539+
int sectionX = (int)(chunkSection >> 42);
540+
int sectionY = (int)((chunkSection << 44) >> 44);
541+
int sectionZ = (int)((chunkSection << 22) >> 42);
542+
dataTypes.ReadNextBool(packetData); // Useless boolean
543+
int blocksSize = dataTypes.ReadNextVarInt(packetData);
544+
for (int i = 0; i < blocksSize; i++)
530545
{
531-
blockIdMeta = dataTypes.ReadNextUShort(packetData);
532-
blockY = (ushort)dataTypes.ReadNextByte(packetData);
533-
locationXZ = dataTypes.ReadNextByte(packetData);
546+
ulong block = (ulong)dataTypes.ReadNextVarLong(packetData);
547+
int blockId = (int)(block >> 12);
548+
int localX = (int)((block >> 8) & 0x0F);
549+
int localZ = (int)((block >> 4) & 0x0F);
550+
int localY = (int)(block & 0x0F);
551+
552+
Block b = new Block((ushort)blockId);
553+
int blockX = (sectionX * 16) + localX;
554+
int blockY = (sectionY * 16) + localY;
555+
int blockZ = (sectionZ * 16) + localZ;
556+
var l = new Location(blockX, blockY, blockZ);
557+
handler.GetWorld().SetBlock(l, b);
534558
}
535-
else
559+
}
560+
else
561+
{
562+
int chunkX = dataTypes.ReadNextInt(packetData);
563+
int chunkZ = dataTypes.ReadNextInt(packetData);
564+
int recordCount = protocolversion < MC18Version
565+
? (int)dataTypes.ReadNextShort(packetData)
566+
: dataTypes.ReadNextVarInt(packetData);
567+
568+
for (int i = 0; i < recordCount; i++)
536569
{
537-
locationXZ = dataTypes.ReadNextByte(packetData);
538-
blockY = (ushort)dataTypes.ReadNextByte(packetData);
539-
blockIdMeta = (ushort)dataTypes.ReadNextVarInt(packetData);
540-
}
570+
byte locationXZ;
571+
ushort blockIdMeta;
572+
int blockY;
541573

542-
int blockX = locationXZ >> 4;
543-
int blockZ = locationXZ & 0x0F;
544-
Block block = new Block(blockIdMeta);
545-
handler.GetWorld().SetBlock(new Location(chunkX, chunkZ, blockX, blockY, blockZ), block);
574+
if (protocolversion < MC18Version)
575+
{
576+
blockIdMeta = dataTypes.ReadNextUShort(packetData);
577+
blockY = (ushort)dataTypes.ReadNextByte(packetData);
578+
locationXZ = dataTypes.ReadNextByte(packetData);
579+
}
580+
else
581+
{
582+
locationXZ = dataTypes.ReadNextByte(packetData);
583+
blockY = (ushort)dataTypes.ReadNextByte(packetData);
584+
blockIdMeta = (ushort)dataTypes.ReadNextVarInt(packetData);
585+
}
586+
587+
int blockX = locationXZ >> 4;
588+
int blockZ = locationXZ & 0x0F;
589+
Block block = new Block(blockIdMeta);
590+
handler.GetWorld().SetBlock(new Location(chunkX, chunkZ, blockX, blockY, blockZ), block);
591+
}
546592
}
547593
}
548594
break;

0 commit comments

Comments
 (0)