mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-11-07 17:36:07 +00:00
Fixed entity metadata, fixed a crash with Hurt Data packet, fixed a crash when someone flew by with elyra, added Entity Metadata Palettes (not used yet, requires further work)
This commit is contained in:
parent
2e55a6bc85
commit
1a22002bde
11 changed files with 1575 additions and 531 deletions
33
MinecraftClient/Mapping/EntityMetaDataType.cs
Normal file
33
MinecraftClient/Mapping/EntityMetaDataType.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
namespace MinecraftClient.Mapping;
|
||||||
|
|
||||||
|
public enum EntityMetaDataType
|
||||||
|
{
|
||||||
|
Byte,
|
||||||
|
VarInt,
|
||||||
|
VarLong,
|
||||||
|
Float,
|
||||||
|
String,
|
||||||
|
Chat,
|
||||||
|
OptionalChat,
|
||||||
|
Slot,
|
||||||
|
Boolean,
|
||||||
|
Rotation,
|
||||||
|
Position,
|
||||||
|
OptionalPosition,
|
||||||
|
Direction,
|
||||||
|
OptionalUuid,
|
||||||
|
BlockId,
|
||||||
|
OptionalBlockId,
|
||||||
|
Nbt,
|
||||||
|
Particle,
|
||||||
|
VillagerData,
|
||||||
|
OptionalVarInt,
|
||||||
|
Pose,
|
||||||
|
CatVariant,
|
||||||
|
FrogVariant,
|
||||||
|
OptionalGlobalPosition,
|
||||||
|
PaintingVariant,
|
||||||
|
SnifferState,
|
||||||
|
Vector3,
|
||||||
|
Quaternion
|
||||||
|
}
|
||||||
8
MinecraftClient/Mapping/EntityMetadataPalette.cs
Normal file
8
MinecraftClient/Mapping/EntityMetadataPalette.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Mapping;
|
||||||
|
|
||||||
|
public abstract class EntityMetadataPalette
|
||||||
|
{
|
||||||
|
public abstract Dictionary<int, EntityMetaDataType> GetEntityMetadataMappingsList();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Mapping.EntityMetadataPalettes;
|
||||||
|
|
||||||
|
public class EntityMetadataPalette111 : EntityMetadataPalette
|
||||||
|
{
|
||||||
|
// 1.11 : https://wiki.vg/index.php?title=Entity_metadata&oldid=8269
|
||||||
|
private readonly Dictionary<int, EntityMetaDataType> entityMetadataMappings = new()
|
||||||
|
{
|
||||||
|
{ 0, EntityMetaDataType.Byte },
|
||||||
|
{ 1, EntityMetaDataType.VarInt },
|
||||||
|
{ 2, EntityMetaDataType.Float },
|
||||||
|
{ 3, EntityMetaDataType.String },
|
||||||
|
{ 4, EntityMetaDataType.Chat },
|
||||||
|
{ 5, EntityMetaDataType.Slot },
|
||||||
|
{ 6, EntityMetaDataType.Boolean },
|
||||||
|
{ 7, EntityMetaDataType.Rotation },
|
||||||
|
{ 8, EntityMetaDataType.Position },
|
||||||
|
{ 9, EntityMetaDataType.OptionalPosition },
|
||||||
|
{ 10, EntityMetaDataType.Direction },
|
||||||
|
{ 11, EntityMetaDataType.OptionalUuid },
|
||||||
|
{ 12, EntityMetaDataType.OptionalBlockId }
|
||||||
|
};
|
||||||
|
|
||||||
|
public override Dictionary<int, EntityMetaDataType> GetEntityMetadataMappingsList()
|
||||||
|
{
|
||||||
|
return entityMetadataMappings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Mapping.EntityMetadataPalettes;
|
||||||
|
|
||||||
|
public class EntityMetadataPalette113 : EntityMetadataPalette
|
||||||
|
{
|
||||||
|
// 1.13 : https://wiki.vg/index.php?title=Entity_metadata&oldid=14539
|
||||||
|
private readonly Dictionary<int, EntityMetaDataType> entityMetadataMappings = new()
|
||||||
|
{
|
||||||
|
{ 0, EntityMetaDataType.Byte },
|
||||||
|
{ 1, EntityMetaDataType.VarInt },
|
||||||
|
{ 2, EntityMetaDataType.Float },
|
||||||
|
{ 3, EntityMetaDataType.String },
|
||||||
|
{ 4, EntityMetaDataType.Chat },
|
||||||
|
{ 5, EntityMetaDataType.OptionalChat },
|
||||||
|
{ 6, EntityMetaDataType.Slot },
|
||||||
|
{ 7, EntityMetaDataType.Boolean },
|
||||||
|
{ 8, EntityMetaDataType.Rotation },
|
||||||
|
{ 9, EntityMetaDataType.Position },
|
||||||
|
{ 10, EntityMetaDataType.OptionalPosition },
|
||||||
|
{ 11, EntityMetaDataType.Direction },
|
||||||
|
{ 12, EntityMetaDataType.OptionalUuid },
|
||||||
|
{ 13, EntityMetaDataType.OptionalBlockId },
|
||||||
|
{ 14, EntityMetaDataType.Nbt },
|
||||||
|
{ 15, EntityMetaDataType.Particle }
|
||||||
|
};
|
||||||
|
|
||||||
|
public override Dictionary<int, EntityMetaDataType> GetEntityMetadataMappingsList()
|
||||||
|
{
|
||||||
|
return entityMetadataMappings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Mapping.EntityMetadataPalettes;
|
||||||
|
|
||||||
|
public class EntityMetadataPalette114 : EntityMetadataPalette
|
||||||
|
{
|
||||||
|
private readonly Dictionary<int, EntityMetaDataType> entityMetadataMappings = new()
|
||||||
|
{
|
||||||
|
{ 0, EntityMetaDataType.Byte },
|
||||||
|
{ 1, EntityMetaDataType.VarInt },
|
||||||
|
{ 2, EntityMetaDataType.Float },
|
||||||
|
{ 3, EntityMetaDataType.String },
|
||||||
|
{ 4, EntityMetaDataType.Chat },
|
||||||
|
{ 5, EntityMetaDataType.OptionalChat },
|
||||||
|
{ 6, EntityMetaDataType.Slot },
|
||||||
|
{ 7, EntityMetaDataType.Boolean },
|
||||||
|
{ 8, EntityMetaDataType.Rotation },
|
||||||
|
{ 9, EntityMetaDataType.Position },
|
||||||
|
{ 10, EntityMetaDataType.OptionalPosition },
|
||||||
|
{ 11, EntityMetaDataType.Direction },
|
||||||
|
{ 12, EntityMetaDataType.OptionalUuid },
|
||||||
|
{ 13, EntityMetaDataType.OptionalBlockId },
|
||||||
|
{ 14, EntityMetaDataType.Nbt },
|
||||||
|
{ 15, EntityMetaDataType.Particle },
|
||||||
|
{ 16, EntityMetaDataType.VillagerData },
|
||||||
|
{ 17, EntityMetaDataType.OptionalVarInt },
|
||||||
|
{ 18, EntityMetaDataType.Pose }
|
||||||
|
};
|
||||||
|
|
||||||
|
public override Dictionary<int, EntityMetaDataType> GetEntityMetadataMappingsList()
|
||||||
|
{
|
||||||
|
return entityMetadataMappings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Mapping.EntityMetadataPalettes;
|
||||||
|
|
||||||
|
public class EntityMetadataPalette1191 : EntityMetadataPalette
|
||||||
|
{
|
||||||
|
private readonly Dictionary<int, EntityMetaDataType> entityMetadataMappings = new()
|
||||||
|
{
|
||||||
|
{ 0, EntityMetaDataType.Byte },
|
||||||
|
{ 1, EntityMetaDataType.VarInt },
|
||||||
|
{ 2, EntityMetaDataType.Float },
|
||||||
|
{ 3, EntityMetaDataType.String },
|
||||||
|
{ 4, EntityMetaDataType.Chat },
|
||||||
|
{ 5, EntityMetaDataType.OptionalChat },
|
||||||
|
{ 6, EntityMetaDataType.Slot },
|
||||||
|
{ 7, EntityMetaDataType.Boolean },
|
||||||
|
{ 8, EntityMetaDataType.Rotation },
|
||||||
|
{ 9, EntityMetaDataType.Position },
|
||||||
|
{ 10, EntityMetaDataType.OptionalPosition },
|
||||||
|
{ 11, EntityMetaDataType.Direction },
|
||||||
|
{ 12, EntityMetaDataType.OptionalUuid },
|
||||||
|
{ 13, EntityMetaDataType.OptionalBlockId },
|
||||||
|
{ 14, EntityMetaDataType.Nbt },
|
||||||
|
{ 15, EntityMetaDataType.Particle },
|
||||||
|
{ 16, EntityMetaDataType.VillagerData },
|
||||||
|
{ 17, EntityMetaDataType.OptionalVarInt },
|
||||||
|
{ 18, EntityMetaDataType.Pose },
|
||||||
|
{ 19, EntityMetaDataType.CatVariant },
|
||||||
|
{ 20, EntityMetaDataType.FrogVariant },
|
||||||
|
{ 21, EntityMetaDataType.OptionalGlobalPosition },
|
||||||
|
{ 22, EntityMetaDataType.PaintingVariant }
|
||||||
|
};
|
||||||
|
|
||||||
|
public override Dictionary<int, EntityMetaDataType> GetEntityMetadataMappingsList()
|
||||||
|
{
|
||||||
|
return entityMetadataMappings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Mapping.EntityMetadataPalettes;
|
||||||
|
|
||||||
|
public class EntityMetadataPalette1193 : EntityMetadataPalette
|
||||||
|
{
|
||||||
|
private readonly Dictionary<int, EntityMetaDataType> entityMetadataMappings = new()
|
||||||
|
{
|
||||||
|
{ 0, EntityMetaDataType.Byte },
|
||||||
|
{ 1, EntityMetaDataType.VarInt },
|
||||||
|
{ 2, EntityMetaDataType.VarLong },
|
||||||
|
{ 3, EntityMetaDataType.Float },
|
||||||
|
{ 4, EntityMetaDataType.String },
|
||||||
|
{ 5, EntityMetaDataType.Chat },
|
||||||
|
{ 6, EntityMetaDataType.OptionalChat },
|
||||||
|
{ 7, EntityMetaDataType.Slot },
|
||||||
|
{ 8, EntityMetaDataType.Boolean },
|
||||||
|
{ 9, EntityMetaDataType.Rotation },
|
||||||
|
{ 10, EntityMetaDataType.Position },
|
||||||
|
{ 11, EntityMetaDataType.OptionalPosition },
|
||||||
|
{ 12, EntityMetaDataType.Direction },
|
||||||
|
{ 13, EntityMetaDataType.OptionalUuid },
|
||||||
|
{ 14, EntityMetaDataType.OptionalBlockId },
|
||||||
|
{ 15, EntityMetaDataType.Nbt },
|
||||||
|
{ 16, EntityMetaDataType.Particle },
|
||||||
|
{ 17, EntityMetaDataType.VillagerData },
|
||||||
|
{ 18, EntityMetaDataType.OptionalVarInt },
|
||||||
|
{ 19, EntityMetaDataType.Pose },
|
||||||
|
{ 20, EntityMetaDataType.CatVariant },
|
||||||
|
{ 21, EntityMetaDataType.FrogVariant },
|
||||||
|
{ 22, EntityMetaDataType.OptionalGlobalPosition },
|
||||||
|
{ 23, EntityMetaDataType.PaintingVariant }
|
||||||
|
};
|
||||||
|
|
||||||
|
public override Dictionary<int, EntityMetaDataType> GetEntityMetadataMappingsList()
|
||||||
|
{
|
||||||
|
return entityMetadataMappings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Mapping.EntityMetadataPalettes;
|
||||||
|
|
||||||
|
public class EntityMetadataPalette1194 : EntityMetadataPalette
|
||||||
|
{
|
||||||
|
private readonly Dictionary<int, EntityMetaDataType> entityMetadataMappings = new()
|
||||||
|
{
|
||||||
|
{ 0, EntityMetaDataType.Byte },
|
||||||
|
{ 1, EntityMetaDataType.VarInt },
|
||||||
|
{ 2, EntityMetaDataType.VarLong },
|
||||||
|
{ 3, EntityMetaDataType.Float },
|
||||||
|
{ 4, EntityMetaDataType.String },
|
||||||
|
{ 5, EntityMetaDataType.Chat },
|
||||||
|
{ 6, EntityMetaDataType.OptionalChat },
|
||||||
|
{ 7, EntityMetaDataType.Slot },
|
||||||
|
{ 8, EntityMetaDataType.Boolean },
|
||||||
|
{ 9, EntityMetaDataType.Rotation },
|
||||||
|
{ 10, EntityMetaDataType.Position },
|
||||||
|
{ 11, EntityMetaDataType.OptionalPosition },
|
||||||
|
{ 12, EntityMetaDataType.Direction },
|
||||||
|
{ 13, EntityMetaDataType.OptionalUuid },
|
||||||
|
{ 14, EntityMetaDataType.BlockId },
|
||||||
|
{ 15, EntityMetaDataType.OptionalBlockId },
|
||||||
|
{ 16, EntityMetaDataType.Nbt },
|
||||||
|
{ 17, EntityMetaDataType.Particle },
|
||||||
|
{ 18, EntityMetaDataType.VillagerData },
|
||||||
|
{ 19, EntityMetaDataType.OptionalVarInt },
|
||||||
|
{ 20, EntityMetaDataType.Pose },
|
||||||
|
{ 21, EntityMetaDataType.CatVariant },
|
||||||
|
{ 22, EntityMetaDataType.FrogVariant },
|
||||||
|
{ 23, EntityMetaDataType.OptionalGlobalPosition },
|
||||||
|
{ 24, EntityMetaDataType.PaintingVariant },
|
||||||
|
{ 25, EntityMetaDataType.SnifferState },
|
||||||
|
{ 26, EntityMetaDataType.Vector3 },
|
||||||
|
{ 27, EntityMetaDataType.Quaternion },
|
||||||
|
};
|
||||||
|
|
||||||
|
public override Dictionary<int, EntityMetaDataType> GetEntityMetadataMappingsList()
|
||||||
|
{
|
||||||
|
return entityMetadataMappings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Mapping.EntityMetadataPalettes;
|
||||||
|
|
||||||
|
public class EntityMetadataPalette19 : EntityMetadataPalette
|
||||||
|
{
|
||||||
|
// 1.8 : https://wiki.vg/index.php?title=Entity_metadata&oldid=6220 (Requires a different algorithm)
|
||||||
|
// 1.9 : https://wiki.vg/index.php?title=Entity_metadata&oldid=7416
|
||||||
|
private readonly Dictionary<int, EntityMetaDataType> entityMetadataMappings = new()
|
||||||
|
{
|
||||||
|
{ 0, EntityMetaDataType.Byte },
|
||||||
|
{ 1, EntityMetaDataType.VarInt },
|
||||||
|
{ 2, EntityMetaDataType.Float },
|
||||||
|
{ 3, EntityMetaDataType.String },
|
||||||
|
{ 4, EntityMetaDataType.Chat },
|
||||||
|
{ 5, EntityMetaDataType.Slot },
|
||||||
|
{ 6, EntityMetaDataType.Boolean },
|
||||||
|
{ 7, EntityMetaDataType.Vector3 },
|
||||||
|
{ 8, EntityMetaDataType.Position },
|
||||||
|
{ 9, EntityMetaDataType.OptionalPosition },
|
||||||
|
{ 10, EntityMetaDataType.Direction },
|
||||||
|
{ 11, EntityMetaDataType.OptionalUuid },
|
||||||
|
{ 12, EntityMetaDataType.OptionalBlockId }
|
||||||
|
};
|
||||||
|
|
||||||
|
public override Dictionary<int, EntityMetaDataType> GetEntityMetadataMappingsList()
|
||||||
|
{
|
||||||
|
return entityMetadataMappings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -188,6 +188,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
y = (int)((locEncoded >> 26) & 0xFFF);
|
y = (int)((locEncoded >> 26) & 0xFFF);
|
||||||
z = (int)(locEncoded << 38 >> 38);
|
z = (int)(locEncoded << 38 >> 38);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x >= 0x02000000) // 33,554,432
|
if (x >= 0x02000000) // 33,554,432
|
||||||
x -= 0x04000000; // 67,108,864
|
x -= 0x04000000; // 67,108,864
|
||||||
if (y >= 0x00000800) // 2,048
|
if (y >= 0x00000800) // 2,048
|
||||||
|
|
@ -309,6 +310,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
if (j > 5) throw new OverflowException("VarInt too big");
|
if (j > 5) throw new OverflowException("VarInt too big");
|
||||||
if ((b & 0x80) != 128) break;
|
if ((b & 0x80) != 128) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -329,6 +331,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
i |= (b & 0x7F) << j++ * 7;
|
i |= (b & 0x7F) << j++ * 7;
|
||||||
if (j > 5) throw new OverflowException("VarInt too big");
|
if (j > 5) throw new OverflowException("VarInt too big");
|
||||||
} while ((b & 0x80) == 128);
|
} while ((b & 0x80) == 128);
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -360,6 +363,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
low &= 0x7FFF;
|
low &= 0x7FFF;
|
||||||
high = ReadNextByte(cache);
|
high = ReadNextByte(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((high & 0xFF) << 15) | low;
|
return ((high & 0xFF) << 15) | low;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -385,6 +389,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
throw new OverflowException("VarLong is too big");
|
throw new OverflowException("VarLong is too big");
|
||||||
}
|
}
|
||||||
} while ((read & 0x80) != 0);
|
} while ((read & 0x80) != 0);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -487,7 +492,8 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
short velocityY = ReadNextShort(cache);
|
short velocityY = ReadNextShort(cache);
|
||||||
short velocityZ = ReadNextShort(cache);
|
short velocityZ = ReadNextShort(cache);
|
||||||
|
|
||||||
return new Entity(entityID, entityType, new Location(entityX, entityY, entityZ), entityYaw, entityPitch, metadata);
|
return new Entity(entityID, entityType, new Location(entityX, entityY, entityZ), entityYaw, entityPitch,
|
||||||
|
metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -504,6 +510,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
cache.Dequeue();
|
cache.Dequeue();
|
||||||
return nbtData;
|
return nbtData;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cache.Peek() != 10) // TAG_Compound
|
if (cache.Peek() != 10) // TAG_Compound
|
||||||
throw new System.IO.InvalidDataException("Failed to decode NBT: Does not start with TAG_Compound");
|
throw new System.IO.InvalidDataException("Failed to decode NBT: Does not start with TAG_Compound");
|
||||||
ReadNextByte(cache); // Tag type (TAG_Compound)
|
ReadNextByte(cache); // Tag type (TAG_Compound)
|
||||||
|
|
@ -582,6 +589,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Refactor this to use new Entity Metadata Palettes
|
||||||
public Dictionary<int, object?> ReadNextMetadata(Queue<byte> cache, ItemPalette itemPalette)
|
public Dictionary<int, object?> ReadNextMetadata(Queue<byte> cache, ItemPalette itemPalette)
|
||||||
{
|
{
|
||||||
Dictionary<int, object?> data = new();
|
Dictionary<int, object?> data = new();
|
||||||
|
|
@ -603,90 +611,87 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
if (type > 4)
|
if (type > 4)
|
||||||
++type;
|
++type;
|
||||||
}
|
}
|
||||||
else if (protocolversion >= Protocol18Handler.MC_1_19_3_Version)
|
|
||||||
{
|
|
||||||
if (type == 2)
|
|
||||||
{
|
|
||||||
value = ReadNextVarLong(cache);
|
|
||||||
type = -1;
|
|
||||||
}
|
|
||||||
else if (type >= 3)
|
|
||||||
{
|
|
||||||
--type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is backward compatible since new type is appended to the end
|
// Temporary
|
||||||
// Version upgrade note
|
if (protocolversion >= Protocol18Handler.MC_1_19_3_Version)
|
||||||
// - Check type ID got shifted or not
|
|
||||||
// - Add new type if any
|
|
||||||
switch (type)
|
|
||||||
{
|
{
|
||||||
case -1: // already readed
|
switch (type)
|
||||||
break;
|
{
|
||||||
case 0: // byte
|
case 0: // byte
|
||||||
value = ReadNextByte(cache);
|
value = ReadNextByte(cache);
|
||||||
break;
|
break;
|
||||||
case 1: // VarInt
|
case 1: // VarInt
|
||||||
value = ReadNextVarInt(cache);
|
value = ReadNextVarInt(cache);
|
||||||
break;
|
break;
|
||||||
case 2: // Float
|
case 2: // Long
|
||||||
value = ReadNextFloat(cache);
|
value = ReadNextLong(cache);
|
||||||
break;
|
break;
|
||||||
case 3: // String
|
;
|
||||||
value = ReadNextString(cache);
|
case 3: // Float
|
||||||
break;
|
value = ReadNextFloat(cache);
|
||||||
case 4: // Chat
|
break;
|
||||||
value = ReadNextString(cache);
|
case 4: // String
|
||||||
break;
|
|
||||||
case 5: // Optional Chat
|
|
||||||
if (ReadNextBool(cache))
|
|
||||||
value = ReadNextString(cache);
|
value = ReadNextString(cache);
|
||||||
break;
|
break;
|
||||||
case 6: // Slot
|
case 5: // Chat
|
||||||
value = ReadNextItemSlot(cache, itemPalette);
|
value = ReadNextString(cache);
|
||||||
break;
|
break;
|
||||||
case 7: // Boolean
|
case 6: // Optional Chat
|
||||||
value = ReadNextBool(cache);
|
if (ReadNextBool(cache))
|
||||||
break;
|
value = ReadNextString(cache);
|
||||||
case 8: // Rotation (3x floats)
|
break;
|
||||||
value = new List<float>
|
case 7: // Slot
|
||||||
{
|
value = ReadNextItemSlot(cache, itemPalette);
|
||||||
ReadNextFloat(cache),
|
break;
|
||||||
ReadNextFloat(cache),
|
case 8: // Boolean
|
||||||
ReadNextFloat(cache)
|
value = ReadNextBool(cache);
|
||||||
};
|
break;
|
||||||
break;
|
case 9: // Rotation (3x floats)
|
||||||
case 9: // Position
|
value = new List<float>
|
||||||
value = ReadNextLocation(cache);
|
{
|
||||||
break;
|
ReadNextFloat(cache),
|
||||||
case 10: // Optional Position
|
ReadNextFloat(cache),
|
||||||
if (ReadNextBool(cache))
|
ReadNextFloat(cache)
|
||||||
{
|
};
|
||||||
|
break;
|
||||||
|
case 10: // Position
|
||||||
value = ReadNextLocation(cache);
|
value = ReadNextLocation(cache);
|
||||||
}
|
break;
|
||||||
break;
|
case 11: // Optional Position
|
||||||
case 11: // Direction (VarInt)
|
if (ReadNextBool(cache))
|
||||||
value = ReadNextVarInt(cache);
|
{
|
||||||
break;
|
value = ReadNextLocation(cache);
|
||||||
case 12: // Optional UUID
|
}
|
||||||
if (ReadNextBool(cache))
|
|
||||||
{
|
break;
|
||||||
value = ReadNextUUID(cache);
|
case 12: // Direction (VarInt)
|
||||||
}
|
value = ReadNextVarInt(cache);
|
||||||
break;
|
break;
|
||||||
case 13: // Optional BlockID (VarInt)
|
case 13: // Optional UUID
|
||||||
value = ReadNextVarInt(cache);
|
if (ReadNextBool(cache))
|
||||||
break;
|
{
|
||||||
case 14: // NBT
|
value = ReadNextUUID(cache);
|
||||||
value = ReadNextNbt(cache);
|
}
|
||||||
break;
|
|
||||||
case 15: // Particle
|
break;
|
||||||
// Currecutly not handled. Reading data only
|
case 14: // BlockID (VarInt)
|
||||||
int ParticleID = ReadNextVarInt(cache);
|
value = ReadNextVarInt(cache);
|
||||||
// Need to check the exact version where the change occurred!!!!!
|
break;
|
||||||
if (protocolversion >= Protocol18Handler.MC_1_19_3_Version)
|
case 15: // Optional BlockID (VarInt)
|
||||||
{
|
value = ReadNextVarInt(cache);
|
||||||
|
break;
|
||||||
|
case 16: // NBT
|
||||||
|
value = ReadNextNbt(cache);
|
||||||
|
break;
|
||||||
|
case 17: // Particle
|
||||||
|
// Currently not handled. Reading data only
|
||||||
|
int ParticleID = ReadNextVarInt(cache);
|
||||||
|
// TODO: Go through wiki history and write for every version
|
||||||
|
// 1.19.3 - https://wiki.vg/index.php?title=Data_types&oldid=17986
|
||||||
|
// 1.18 - https://wiki.vg/index.php?title=Data_types&oldid=17180
|
||||||
|
// 1.17 - https://wiki.vg/index.php?title=Data_types&oldid=16740
|
||||||
|
// 1.15 - https://wiki.vg/index.php?title=Data_types&oldid=15338
|
||||||
|
// 1.13 - https://wiki.vg/index.php?title=Data_types&oldid=14271
|
||||||
switch (ParticleID)
|
switch (ParticleID)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
|
|
@ -710,13 +715,16 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
ReadNextFloat(cache);
|
ReadNextFloat(cache);
|
||||||
ReadNextFloat(cache);
|
ReadNextFloat(cache);
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 25:
|
||||||
ReadNextVarInt(cache);
|
ReadNextVarInt(cache);
|
||||||
break;
|
break;
|
||||||
case 35:
|
case 30:
|
||||||
|
ReadNextFloat(cache);
|
||||||
|
break;
|
||||||
|
case 39:
|
||||||
ReadNextItemSlot(cache, itemPalette);
|
ReadNextItemSlot(cache, itemPalette);
|
||||||
break;
|
break;
|
||||||
case 36:
|
case 40:
|
||||||
string positionSourceType = ReadNextString(cache);
|
string positionSourceType = ReadNextString(cache);
|
||||||
if (positionSourceType == "minecraft:block")
|
if (positionSourceType == "minecraft:block")
|
||||||
{
|
{
|
||||||
|
|
@ -727,12 +735,149 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
ReadNextVarInt(cache);
|
ReadNextVarInt(cache);
|
||||||
ReadNextFloat(cache);
|
ReadNextFloat(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadNextVarInt(cache);
|
ReadNextVarInt(cache);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
break;
|
||||||
{
|
case 18: // Villager Data (3x VarInt)
|
||||||
|
value = new List<int>
|
||||||
|
{
|
||||||
|
ReadNextVarInt(cache),
|
||||||
|
ReadNextVarInt(cache),
|
||||||
|
ReadNextVarInt(cache)
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case 19: // Optional VarInt
|
||||||
|
if (ReadNextBool(cache))
|
||||||
|
{
|
||||||
|
value = ReadNextVarInt(cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 20: // Pose
|
||||||
|
value = ReadNextVarInt(cache);
|
||||||
|
break;
|
||||||
|
case 21: // Cat Variant
|
||||||
|
value = ReadNextVarInt(cache);
|
||||||
|
break;
|
||||||
|
case 22: // Frog Varint
|
||||||
|
value = ReadNextVarInt(cache);
|
||||||
|
break;
|
||||||
|
case 23: // GlobalPos at 1.19.2+; Painting Variant at 1.19-
|
||||||
|
if (protocolversion <= Protocol18Handler.MC_1_19_Version)
|
||||||
|
{
|
||||||
|
value = ReadNextVarInt(cache);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Dimension and blockPos, currently not in use
|
||||||
|
value = new Tuple<string, Location>(ReadNextString(cache), ReadNextLocation(cache));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 24: // Painting Variant
|
||||||
|
value = ReadNextVarInt(cache);
|
||||||
|
break;
|
||||||
|
case 25: // Sniffer state
|
||||||
|
value = ReadNextVarInt(cache);
|
||||||
|
break;
|
||||||
|
case 26: // Vector 3f
|
||||||
|
value = new List<float>
|
||||||
|
{
|
||||||
|
ReadNextFloat(cache),
|
||||||
|
ReadNextFloat(cache),
|
||||||
|
ReadNextFloat(cache)
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case 27: // Quaternion
|
||||||
|
value = new List<float>
|
||||||
|
{
|
||||||
|
ReadNextFloat(cache),
|
||||||
|
ReadNextFloat(cache),
|
||||||
|
ReadNextFloat(cache),
|
||||||
|
ReadNextFloat(cache)
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new System.IO.InvalidDataException("Unknown Metadata Type ID " + type +
|
||||||
|
". Is this up to date for new MC Version?");
|
||||||
|
}
|
||||||
|
|
||||||
|
data[key] = value;
|
||||||
|
key = ReadNextByte(cache);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This is backward compatible since new type is appended to the end
|
||||||
|
// Version upgrade note
|
||||||
|
// - Check type ID got shifted or not
|
||||||
|
// - Add new type if any
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 0: // byte
|
||||||
|
value = ReadNextByte(cache);
|
||||||
|
break;
|
||||||
|
case 1: // VarInt
|
||||||
|
value = ReadNextVarInt(cache);
|
||||||
|
break;
|
||||||
|
case 2: // Float
|
||||||
|
value = ReadNextFloat(cache);
|
||||||
|
break;
|
||||||
|
case 3: // String
|
||||||
|
value = ReadNextString(cache);
|
||||||
|
break;
|
||||||
|
case 4: // Chat
|
||||||
|
value = ReadNextString(cache);
|
||||||
|
break;
|
||||||
|
case 5: // Optional Chat
|
||||||
|
if (ReadNextBool(cache))
|
||||||
|
value = ReadNextString(cache);
|
||||||
|
break;
|
||||||
|
case 6: // Slot
|
||||||
|
value = ReadNextItemSlot(cache, itemPalette);
|
||||||
|
break;
|
||||||
|
case 7: // Boolean
|
||||||
|
value = ReadNextBool(cache);
|
||||||
|
break;
|
||||||
|
case 8: // Rotation (3x floats)
|
||||||
|
value = new List<float>
|
||||||
|
{
|
||||||
|
ReadNextFloat(cache),
|
||||||
|
ReadNextFloat(cache),
|
||||||
|
ReadNextFloat(cache)
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case 9: // Position
|
||||||
|
value = ReadNextLocation(cache);
|
||||||
|
break;
|
||||||
|
case 10: // Optional Position
|
||||||
|
if (ReadNextBool(cache))
|
||||||
|
{
|
||||||
|
value = ReadNextLocation(cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 11: // Direction (VarInt)
|
||||||
|
value = ReadNextVarInt(cache);
|
||||||
|
break;
|
||||||
|
case 12: // Optional UUID
|
||||||
|
if (ReadNextBool(cache))
|
||||||
|
{
|
||||||
|
value = ReadNextUUID(cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 13: // Optional BlockID (VarInt)
|
||||||
|
value = ReadNextVarInt(cache);
|
||||||
|
break;
|
||||||
|
case 14: // NBT
|
||||||
|
value = ReadNextNbt(cache);
|
||||||
|
break;
|
||||||
|
case 15: // Particle
|
||||||
|
int ParticleID = ReadNextVarInt(cache);
|
||||||
switch (ParticleID)
|
switch (ParticleID)
|
||||||
{
|
{
|
||||||
case 3:
|
case 3:
|
||||||
|
|
@ -751,49 +896,55 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
ReadNextItemSlot(cache, itemPalette);
|
ReadNextItemSlot(cache, itemPalette);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 16: // Villager Data (3x VarInt)
|
case 16: // Villager Data (3x VarInt)
|
||||||
value = new List<int>
|
value = new List<int>
|
||||||
{
|
{
|
||||||
ReadNextVarInt(cache),
|
ReadNextVarInt(cache),
|
||||||
ReadNextVarInt(cache),
|
ReadNextVarInt(cache),
|
||||||
ReadNextVarInt(cache)
|
ReadNextVarInt(cache)
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 17: // Optional VarInt
|
case 17: // Optional VarInt
|
||||||
if (ReadNextBool(cache))
|
if (ReadNextBool(cache))
|
||||||
{
|
{
|
||||||
|
value = ReadNextVarInt(cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 18: // Pose
|
||||||
value = ReadNextVarInt(cache);
|
value = ReadNextVarInt(cache);
|
||||||
}
|
break;
|
||||||
break;
|
case 19: // Cat Variant
|
||||||
case 18: // Pose
|
|
||||||
value = ReadNextVarInt(cache);
|
|
||||||
break;
|
|
||||||
case 19: // Cat Variant
|
|
||||||
value = ReadNextVarInt(cache);
|
|
||||||
break;
|
|
||||||
case 20: // Frog Varint
|
|
||||||
value = ReadNextVarInt(cache);
|
|
||||||
break;
|
|
||||||
case 21: // GlobalPos at 1.19.2+; Painting Variant at 1.19-
|
|
||||||
if (protocolversion <= Protocol18Handler.MC_1_19_Version)
|
|
||||||
value = ReadNextVarInt(cache);
|
value = ReadNextVarInt(cache);
|
||||||
else
|
break;
|
||||||
{
|
case 20: // Frog Varint
|
||||||
// Dimension and blockPos, currently not in use
|
value = ReadNextVarInt(cache);
|
||||||
value = new Tuple<string, Location>(ReadNextString(cache), ReadNextLocation(cache));
|
break;
|
||||||
}
|
case 21: // GlobalPos at 1.19.2+; Painting Variant at 1.19-
|
||||||
break;
|
if (protocolversion <= Protocol18Handler.MC_1_19_Version)
|
||||||
case 22: // Painting Variant
|
value = ReadNextVarInt(cache);
|
||||||
value = ReadNextVarInt(cache);
|
else
|
||||||
break;
|
{
|
||||||
default:
|
// Dimension and blockPos, currently not in use
|
||||||
throw new System.IO.InvalidDataException("Unknown Metadata Type ID " + type + ". Is this up to date for new MC Version?");
|
value = new Tuple<string, Location>(ReadNextString(cache), ReadNextLocation(cache));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 22: // Painting Variant
|
||||||
|
value = ReadNextVarInt(cache);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new System.IO.InvalidDataException("Unknown Metadata Type ID " + type +
|
||||||
|
". Is this up to date for new MC Version?");
|
||||||
|
}
|
||||||
|
|
||||||
|
data[key] = value;
|
||||||
|
key = ReadNextByte(cache);
|
||||||
}
|
}
|
||||||
data[key] = value;
|
|
||||||
key = ReadNextByte(cache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -823,7 +974,8 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
int specialPrice = ReadNextInt(cache);
|
int specialPrice = ReadNextInt(cache);
|
||||||
float priceMultiplier = ReadNextFloat(cache);
|
float priceMultiplier = ReadNextFloat(cache);
|
||||||
int demand = ReadNextInt(cache);
|
int demand = ReadNextInt(cache);
|
||||||
return new VillagerTrade(inputItem1, outputItem, inputItem2, tradeDisabled, numberOfTradeUses, maximumNumberOfTradeUses, xp, specialPrice, priceMultiplier, demand);
|
return new VillagerTrade(inputItem1, outputItem, inputItem2, tradeDisabled, numberOfTradeUses,
|
||||||
|
maximumNumberOfTradeUses, xp, specialPrice, priceMultiplier, demand);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -956,11 +1108,13 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
subsequentItemsBytes.AddRange(GetNbtField(item, out byte subsequentItemType));
|
subsequentItemsBytes.AddRange(GetNbtField(item, out byte subsequentItemType));
|
||||||
if (subsequentItemType != firstItemType)
|
if (subsequentItemType != firstItemType)
|
||||||
throw new System.IO.InvalidDataException(
|
throw new System.IO.InvalidDataException(
|
||||||
"GetNbt: Cannot encode object[] list with mixed types: " + firstItemTypeString + ", " + item.GetType().Name + " into NBT!");
|
"GetNbt: Cannot encode object[] list with mixed types: " + firstItemTypeString + ", " +
|
||||||
|
item.GetType().Name + " into NBT!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build NBT list: type, length, item array
|
// Build NBT list: type, length, item array
|
||||||
return ConcatBytes(new[] { firstItemType }, GetInt(arrayLengthTotal), firstItemBytes, subsequentItemsBytes.ToArray());
|
return ConcatBytes(new[] { firstItemType }, GetInt(arrayLengthTotal), firstItemBytes,
|
||||||
|
subsequentItemsBytes.ToArray());
|
||||||
}
|
}
|
||||||
else if (obj is Dictionary<string, object>)
|
else if (obj is Dictionary<string, object>)
|
||||||
{
|
{
|
||||||
|
|
@ -991,7 +1145,8 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new System.IO.InvalidDataException("GetNbt: Cannot encode data type " + obj.GetType().Name + " into NBT!");
|
throw new System.IO.InvalidDataException("GetNbt: Cannot encode data type " + obj.GetType().Name +
|
||||||
|
" into NBT!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1008,6 +1163,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
bytes.Add((byte)(paramInt & 127 | 128));
|
bytes.Add((byte)(paramInt & 127 | 128));
|
||||||
paramInt = (int)(((uint)paramInt) >> 7);
|
paramInt = (int)(((uint)paramInt) >> 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes.Add((byte)paramInt);
|
bytes.Add((byte)paramInt);
|
||||||
return bytes.ToArray();
|
return bytes.ToArray();
|
||||||
}
|
}
|
||||||
|
|
@ -1152,9 +1308,15 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
byte[] locationBytes;
|
byte[] locationBytes;
|
||||||
if (protocolversion >= Protocol18Handler.MC_1_14_Version)
|
if (protocolversion >= Protocol18Handler.MC_1_14_Version)
|
||||||
{
|
{
|
||||||
locationBytes = BitConverter.GetBytes(((((ulong)location.X) & 0x3FFFFFF) << 38) | ((((ulong)location.Z) & 0x3FFFFFF) << 12) | (((ulong)location.Y) & 0xFFF));
|
locationBytes = BitConverter.GetBytes(((((ulong)location.X) & 0x3FFFFFF) << 38) |
|
||||||
|
((((ulong)location.Z) & 0x3FFFFFF) << 12) |
|
||||||
|
(((ulong)location.Y) & 0xFFF));
|
||||||
}
|
}
|
||||||
else locationBytes = BitConverter.GetBytes(((((ulong)location.X) & 0x3FFFFFF) << 38) | ((((ulong)location.Y) & 0xFFF) << 26) | (((ulong)location.Z) & 0x3FFFFFF));
|
else
|
||||||
|
locationBytes = BitConverter.GetBytes(((((ulong)location.X) & 0x3FFFFFF) << 38) |
|
||||||
|
((((ulong)location.Y) & 0xFFF) << 26) |
|
||||||
|
(((ulong)location.Z) & 0x3FFFFFF));
|
||||||
|
|
||||||
Array.Reverse(locationBytes); //Endianness
|
Array.Reverse(locationBytes); //Endianness
|
||||||
return locationBytes;
|
return locationBytes;
|
||||||
}
|
}
|
||||||
|
|
@ -1193,6 +1355,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
slotData.AddRange(GetNbt(item.NBT));
|
slotData.AddRange(GetNbt(item.NBT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return slotData.ToArray();
|
return slotData.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1278,17 +1441,18 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
public byte[] GetLastSeenMessageList(Message.LastSeenMessageList msgList, bool isOnlineMode)
|
public byte[] GetLastSeenMessageList(Message.LastSeenMessageList msgList, bool isOnlineMode)
|
||||||
{
|
{
|
||||||
if (!isOnlineMode)
|
if (!isOnlineMode)
|
||||||
return GetVarInt(0); // Message list size
|
return GetVarInt(0); // Message list size
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
List<byte> fields = new();
|
List<byte> fields = new();
|
||||||
fields.AddRange(GetVarInt(msgList.entries.Length)); // Message list size
|
fields.AddRange(GetVarInt(msgList.entries.Length)); // Message list size
|
||||||
foreach (Message.LastSeenMessageList.AcknowledgedMessage entry in msgList.entries)
|
foreach (Message.LastSeenMessageList.AcknowledgedMessage entry in msgList.entries)
|
||||||
{
|
{
|
||||||
fields.AddRange(entry.profileId.ToBigEndianBytes()); // UUID
|
fields.AddRange(entry.profileId.ToBigEndianBytes()); // UUID
|
||||||
fields.AddRange(GetVarInt(entry.signature.Length)); // Signature length
|
fields.AddRange(GetVarInt(entry.signature.Length)); // Signature length
|
||||||
fields.AddRange(entry.signature); // Signature data
|
fields.AddRange(entry.signature); // Signature data
|
||||||
}
|
}
|
||||||
|
|
||||||
return fields.ToArray();
|
return fields.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1304,15 +1468,16 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
List<byte> fields = new();
|
List<byte> fields = new();
|
||||||
fields.AddRange(GetLastSeenMessageList(ack.lastSeen, isOnlineMode));
|
fields.AddRange(GetLastSeenMessageList(ack.lastSeen, isOnlineMode));
|
||||||
if (!isOnlineMode || ack.lastReceived == null)
|
if (!isOnlineMode || ack.lastReceived == null)
|
||||||
fields.AddRange(GetBool(false)); // Has last received message
|
fields.AddRange(GetBool(false)); // Has last received message
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fields.AddRange(GetBool(true));
|
fields.AddRange(GetBool(true));
|
||||||
fields.AddRange(ack.lastReceived.profileId.ToBigEndianBytes()); // Has last received message
|
fields.AddRange(ack.lastReceived.profileId.ToBigEndianBytes()); // Has last received message
|
||||||
fields.AddRange(GetVarInt(ack.lastReceived.signature.Length)); // Last received message signature length
|
fields.AddRange(GetVarInt(ack.lastReceived.signature.Length)); // Last received message signature length
|
||||||
fields.AddRange(ack.lastReceived.signature); // Last received message signature data
|
fields.AddRange(ack.lastReceived.signature); // Last received message signature data
|
||||||
}
|
}
|
||||||
|
|
||||||
return fields.ToArray();
|
return fields.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue