diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs
index 91b921c2..c12c55ae 100644
--- a/MinecraftClient/McClient.cs
+++ b/MinecraftClient/McClient.cs
@@ -2111,6 +2111,16 @@ namespace MinecraftClient
{
DispatchBotEvent(bot => bot.OnUpdateScore(entityname, action, objectivename, value));
}
+
+ ///
+ /// Called when entity metadata added/updated
+ ///
+ /// Target entity's ID
+ /// Metadata
+ public void OnEntityMetadata(int entityID, Dictionary metadata)
+ {
+
+ }
#endregion
}
}
diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs
index c66d3a17..21161d36 100644
--- a/MinecraftClient/Protocol/Handlers/DataTypes.cs
+++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs
@@ -494,6 +494,126 @@ namespace MinecraftClient.Protocol.Handlers
}
}
+ public Dictionary ReadNextMetadata(Queue cache)
+ {
+ Dictionary data = new Dictionary();
+ byte Key = ReadNextByte(cache);
+ while (Key != 0xff)
+ {
+ int Type = ReadNextVarInt(cache);
+ // Value's data type is depended on Type
+ object Value = null;
+
+ // We need to go through every data in order to get all fields in the packet
+ // Store the value as needed
+ 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);
+ break;
+ case 7: // Boolean
+ Value = ReadNextBool(cache);
+ break;
+ case 8: // Rotation (3x floats)
+ List t = new List();
+ t.Add(ReadNextFloat(cache));
+ t.Add(ReadNextFloat(cache));
+ t.Add(ReadNextFloat(cache));
+ Value = t;
+ 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)
+ if (ReadNextBool(cache))
+ {
+ Value = ReadNextVarInt(cache);
+ }
+ break;
+ case 14: // NBT
+ Value = ReadNextNbt(cache);
+ break;
+ case 15: // Particle
+ // Currecutly not handled. Reading data only
+ int ParticleID = ReadNextVarInt(cache);
+ switch (ParticleID)
+ {
+ case 3:
+ ReadNextVarInt(cache);
+ break;
+ case 14:
+ ReadNextFloat(cache);
+ ReadNextFloat(cache);
+ ReadNextFloat(cache);
+ ReadNextFloat(cache);
+ break;
+ case 23:
+ ReadNextVarInt(cache);
+ break;
+ case 32:
+ ReadNextItemSlot(cache);
+ break;
+ }
+ break;
+ case 16: // Villager Data (3x VarInt)
+ List d = new List();
+ d.Add(ReadNextVarInt(cache));
+ d.Add(ReadNextVarInt(cache));
+ d.Add(ReadNextVarInt(cache));
+ Value = d;
+ break;
+ case 17: // Optional VarInt
+ if (ReadNextBool(cache))
+ {
+ Value = ReadNextVarInt(cache);
+ }
+ break;
+ case 18: // Pose
+ Value = ReadNextVarInt(cache);
+ break;
+ }
+ data.Add(Key, Value);
+ Key = ReadNextByte(cache);
+ }
+ return data;
+ }
+
///
/// Build an uncompressed Named Binary Tag blob for sending over the network
///
diff --git a/MinecraftClient/Protocol/Handlers/PacketIncomingType.cs b/MinecraftClient/Protocol/Handlers/PacketIncomingType.cs
index a612a8f5..03d8da68 100644
--- a/MinecraftClient/Protocol/Handlers/PacketIncomingType.cs
+++ b/MinecraftClient/Protocol/Handlers/PacketIncomingType.cs
@@ -47,6 +47,7 @@ namespace MinecraftClient.Protocol.Handlers
EntityEquipment,
EntityVelocity,
EntityEffect,
+ EntityMetadata,
TimeUpdate,
UpdateHealth,
SetExperience,
diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs
index a9f67407..de2f4c04 100644
--- a/MinecraftClient/Protocol/Handlers/Protocol18.cs
+++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs
@@ -861,6 +861,14 @@ namespace MinecraftClient.Protocol.Handlers
handler.OnEntityProperties(EntityID, keys);
}
break;
+ case PacketIncomingType.EntityMetadata:
+ if (handler.GetEntityHandlingEnabled())
+ {
+ int EntityID = dataTypes.ReadNextVarInt(packetData);
+ Dictionary metadata = dataTypes.ReadNextMetadata(packetData);
+ handler.OnEntityMetadata(EntityID, metadata);
+ }
+ break;
case PacketIncomingType.TimeUpdate:
long WorldAge = dataTypes.ReadNextLong(packetData);
long TimeOfday = dataTypes.ReadNextLong(packetData);
diff --git a/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs b/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs
index c958dbda..3e3c4ca3 100644
--- a/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs
+++ b/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs
@@ -109,6 +109,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x3B: return PacketIncomingType.EntityVelocity;
case 0x3C: return PacketIncomingType.EntityEquipment;
case 0x4B: return PacketIncomingType.EntityEffect;
+ case 0x39: return PacketIncomingType.EntityMetadata;
case 0x44: return PacketIncomingType.TimeUpdate;
case 0x3E: return PacketIncomingType.UpdateHealth;
case 0x3D: return PacketIncomingType.SetExperience;
@@ -157,6 +158,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x3D: return PacketIncomingType.EntityVelocity;
case 0x3E: return PacketIncomingType.EntityEquipment;
case 0x4E: return PacketIncomingType.EntityEffect;
+ case 0x3B: return PacketIncomingType.EntityMetadata;
case 0x46: return PacketIncomingType.TimeUpdate;
case 0x40: return PacketIncomingType.UpdateHealth;
case 0x3F: return PacketIncomingType.SetExperience;
@@ -205,6 +207,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x3E: return PacketIncomingType.EntityVelocity;
case 0x3F: return PacketIncomingType.EntityEquipment;
case 0x4F: return PacketIncomingType.EntityEffect;
+ case 0x3C: return PacketIncomingType.EntityMetadata;
case 0x47: return PacketIncomingType.TimeUpdate;
case 0x41: return PacketIncomingType.UpdateHealth;
case 0x40: return PacketIncomingType.SetExperience;
@@ -253,6 +256,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x41: return PacketIncomingType.EntityVelocity;
case 0x42: return PacketIncomingType.EntityEquipment;
case 0x53: return PacketIncomingType.EntityEffect;
+ case 0x3F: return PacketIncomingType.EntityMetadata;
case 0x4A: return PacketIncomingType.TimeUpdate;
case 0x44: return PacketIncomingType.UpdateHealth;
case 0x43: return PacketIncomingType.SetExperience;
@@ -301,6 +305,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x41: return PacketIncomingType.EntityVelocity;
case 0x46: return PacketIncomingType.EntityEquipment;
case 0x59: return PacketIncomingType.EntityEffect;
+ case 0x43: return PacketIncomingType.EntityMetadata;
case 0x4E: return PacketIncomingType.TimeUpdate;
case 0x48: return PacketIncomingType.UpdateHealth;
case 0x47: return PacketIncomingType.SetExperience;
@@ -349,6 +354,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x46: return PacketIncomingType.EntityVelocity;
case 0x47: return PacketIncomingType.EntityEquipment;
case 0x5A: return PacketIncomingType.EntityEffect;
+ case 0x44: return PacketIncomingType.EntityMetadata;
case 0x4F: return PacketIncomingType.TimeUpdate;
case 0x49: return PacketIncomingType.UpdateHealth;
case 0x48: return PacketIncomingType.SetExperience;
@@ -361,7 +367,7 @@ namespace MinecraftClient.Protocol.Handlers
}
} else {
- switch (packetID)
+ switch (packetID) // MC 1.16+
{
case 0x20: return PacketIncomingType.KeepAlive;
case 0x25: return PacketIncomingType.JoinGame;
@@ -396,6 +402,7 @@ namespace MinecraftClient.Protocol.Handlers
case 0x46: return PacketIncomingType.EntityVelocity;
case 0x47: return PacketIncomingType.EntityEquipment;
case 0x59: return PacketIncomingType.EntityEffect;
+ case 0x44: return PacketIncomingType.EntityMetadata;
case 0x4E: return PacketIncomingType.TimeUpdate;
case 0x49: return PacketIncomingType.UpdateHealth;
case 0x48: return PacketIncomingType.SetExperience;
diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs
index 40ddcf81..64c1dd99 100644
--- a/MinecraftClient/Protocol/IMinecraftComHandler.cs
+++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs
@@ -192,6 +192,13 @@ namespace MinecraftClient.Protocol
/// Dictionary of properties
void OnEntityProperties(int entityID, Dictionary prop);
+ ///
+ /// Called when entity metadata added/updated
+ ///
+ /// Target entity's ID
+ /// Metadata
+ void OnEntityMetadata(int entityID, Dictionary metadata);
+
///
/// Called when the world age has been updated
///