mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Implemented entity metadata to keep track of entity health (#1205)
* Implement entity metadata protocol handling * Add health information for entity * Make AutoAttack check entity health * LivingEntity: Default health is 1.0 as per https://wiki.vg/Entity_metadata#Living_Entity * Fix entity metadata for lower MC versions * Fix commit888297d(1.0f instead of 1.0) * Add OnEntityHealth ChatBot event (Remove protocol-dependant stuff from McClient (undo part of85c32b9)) * Remove OnEntityMetadata in favor of OnEntityHealth Co-authored-by: ORelio <ORelio@users.noreply.github.com>
This commit is contained in:
parent
526dabd1e7
commit
2c8ec4aa4a
9 changed files with 191 additions and 2 deletions
|
|
@ -494,6 +494,142 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
}
|
||||
}
|
||||
|
||||
public Dictionary<int, object> ReadNextMetadata(Queue<byte> cache)
|
||||
{
|
||||
Dictionary<int, object> data = new Dictionary<int, object>();
|
||||
byte Key = ReadNextByte(cache);
|
||||
while (Key != 0xff)
|
||||
{
|
||||
int Type = ReadNextVarInt(cache);
|
||||
|
||||
// starting from 1.13, Optional Chat is inserted as number 5 in 1.13 and IDs after 5 got shifted.
|
||||
// Increase type ID by 1 if
|
||||
// - below 1.13
|
||||
// - type ID larger than 4
|
||||
if (protocolversion < Protocol18Handler.MC113Version)
|
||||
{
|
||||
if (Type > 4)
|
||||
{
|
||||
Type += 1;
|
||||
}
|
||||
}
|
||||
// Value's data type is depended on Type
|
||||
object Value = null;
|
||||
|
||||
// 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);
|
||||
break;
|
||||
case 7: // Boolean
|
||||
Value = ReadNextBool(cache);
|
||||
break;
|
||||
case 8: // Rotation (3x floats)
|
||||
List<float> t = new List<float>();
|
||||
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<int> d = new List<int>();
|
||||
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;
|
||||
default:
|
||||
throw new System.IO.InvalidDataException("Unknown Metadata Type ID " + Type + ". Is this up to date for new MC Version?");
|
||||
}
|
||||
data.Add(Key, Value);
|
||||
Key = ReadNextByte(cache);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build an uncompressed Named Binary Tag blob for sending over the network
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
EntityEquipment,
|
||||
EntityVelocity,
|
||||
EntityEffect,
|
||||
EntityMetadata,
|
||||
TimeUpdate,
|
||||
UpdateHealth,
|
||||
SetExperience,
|
||||
|
|
|
|||
|
|
@ -861,6 +861,16 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
handler.OnEntityProperties(EntityID, keys);
|
||||
}
|
||||
break;
|
||||
case PacketIncomingType.EntityMetadata:
|
||||
if (handler.GetEntityHandlingEnabled())
|
||||
{
|
||||
int EntityID = dataTypes.ReadNextVarInt(packetData);
|
||||
Dictionary<int, object> metadata = dataTypes.ReadNextMetadata(packetData);
|
||||
int healthField = protocolversion >= MC114Version ? 8 : 7; // Health is field no. 7 in 1.10+ and 8 in 1.14+
|
||||
if (metadata.ContainsKey(healthField) && metadata[healthField].GetType() == typeof(float))
|
||||
handler.OnEntityHealth(EntityID, (float)metadata[healthField]);
|
||||
}
|
||||
break;
|
||||
case PacketIncomingType.TimeUpdate:
|
||||
long WorldAge = dataTypes.ReadNextLong(packetData);
|
||||
long TimeOfday = dataTypes.ReadNextLong(packetData);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue