Fix 1.19.2 entity metadata handle

This commit is contained in:
BruceChen 2022-09-15 21:11:47 +08:00
parent 26bc6f16c0
commit c00468c103
6 changed files with 48 additions and 31 deletions

View file

@ -91,7 +91,7 @@ namespace MinecraftClient.Mapping
/// <summary> /// <summary>
/// Entity metadata /// Entity metadata
/// </summary> /// </summary>
public Dictionary<int, object> Metadata; public Dictionary<int, object?> Metadata;
/// <summary> /// <summary>
/// Entity equipment /// Entity equipment

View file

@ -3134,31 +3134,32 @@ namespace MinecraftClient
/// </summary> /// </summary>
/// <param name="entityID">Entity ID</param> /// <param name="entityID">Entity ID</param>
/// <param name="metadata">The metadata of the entity</param> /// <param name="metadata">The metadata of the entity</param>
public void OnEntityMetadata(int entityID, Dictionary<int, object> metadata) public void OnEntityMetadata(int entityID, Dictionary<int, object?> metadata)
{ {
if (entities.ContainsKey(entityID)) if (entities.ContainsKey(entityID))
{ {
Entity entity = entities[entityID]; Entity entity = entities[entityID];
entity.Metadata = metadata; entity.Metadata = metadata;
if (entity.Type.ContainsItem() && metadata.ContainsKey(7) && metadata[7] != null && metadata[7].GetType() == typeof(Item)) if (entity.Type.ContainsItem() && metadata.TryGetValue(7, out object? itemObj) && itemObj != null && itemObj.GetType() == typeof(Item))
{ {
Item item = (Item)metadata[7]; Item item = (Item)itemObj;
if (item == null) if (item == null)
entity.Item = new Item(ItemType.Air, 0, null); entity.Item = new Item(ItemType.Air, 0, null);
else entity.Item = item; else entity.Item = item;
} }
if (metadata.ContainsKey(6) && metadata[6] != null && metadata[6].GetType() == typeof(Int32)) if (metadata.TryGetValue(6, out object? poseObj) && poseObj != null && poseObj.GetType() == typeof(Int32))
{ {
entity.Pose = (EntityPose)metadata[6]; entity.Pose = (EntityPose)poseObj;
} }
if (metadata.ContainsKey(2) && metadata[2] != null && metadata[2].GetType() == typeof(string)) if (metadata.TryGetValue(2, out object? nameObj) && nameObj != null && nameObj.GetType() == typeof(string))
{ {
entity.CustomNameJson = metadata[2].ToString(); string name = nameObj.ToString()!;
entity.CustomName = ChatParser.ParseText(metadata[2].ToString()); entity.CustomNameJson = name;
entity.CustomName = ChatParser.ParseText(name);
} }
if (metadata.ContainsKey(3) && metadata[3] != null && metadata[3].GetType() == typeof(bool)) if (metadata.TryGetValue(3, out object? nameVisableObj) && nameVisableObj != null && nameVisableObj.GetType() == typeof(bool))
{ {
entity.IsCustomNameVisible = bool.Parse(metadata[3].ToString()); entity.IsCustomNameVisible = bool.Parse(nameVisableObj.ToString()!);
} }
DispatchBotEvent(bot => bot.OnEntityMetadata(entity, metadata)); DispatchBotEvent(bot => bot.OnEntityMetadata(entity, metadata));
} }

View file

@ -580,9 +580,9 @@ namespace MinecraftClient.Protocol.Handlers
} }
} }
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>(); Dictionary<int, object?> data = new();
byte key = ReadNextByte(cache); byte key = ReadNextByte(cache);
while (key != 0xff) while (key != 0xff)
{ {
@ -600,7 +600,7 @@ namespace MinecraftClient.Protocol.Handlers
} }
} }
// Value's data type is depended on Type // Value's data type is depended on Type
object value = null; object? value = null;
// This is backward compatible since new type is appended to the end // This is backward compatible since new type is appended to the end
// Version upgrade note // Version upgrade note
@ -625,9 +625,7 @@ namespace MinecraftClient.Protocol.Handlers
break; break;
case 5: // Optional Chat case 5: // Optional Chat
if (ReadNextBool(cache)) if (ReadNextBool(cache))
{
value = ReadNextString(cache); value = ReadNextString(cache);
}
break; break;
case 6: // Slot case 6: // Slot
value = ReadNextItemSlot(cache, itemPalette); value = ReadNextItemSlot(cache, itemPalette);
@ -636,11 +634,12 @@ namespace MinecraftClient.Protocol.Handlers
value = ReadNextBool(cache); value = ReadNextBool(cache);
break; break;
case 8: // Rotation (3x floats) case 8: // Rotation (3x floats)
List<float> t = new List<float>(); value = new List<float>
t.Add(ReadNextFloat(cache)); {
t.Add(ReadNextFloat(cache)); ReadNextFloat(cache),
t.Add(ReadNextFloat(cache)); ReadNextFloat(cache),
value = t; ReadNextFloat(cache)
};
break; break;
case 9: // Position case 9: // Position
value = ReadNextLocation(cache); value = ReadNextLocation(cache);
@ -689,11 +688,12 @@ namespace MinecraftClient.Protocol.Handlers
} }
break; break;
case 16: // Villager Data (3x VarInt) case 16: // Villager Data (3x VarInt)
List<int> d = new List<int>(); value = new List<int>
d.Add(ReadNextVarInt(cache)); {
d.Add(ReadNextVarInt(cache)); ReadNextVarInt(cache),
d.Add(ReadNextVarInt(cache)); ReadNextVarInt(cache),
value = d; ReadNextVarInt(cache)
};
break; break;
case 17: // Optional VarInt case 17: // Optional VarInt
if (ReadNextBool(cache)) if (ReadNextBool(cache))
@ -704,6 +704,21 @@ namespace MinecraftClient.Protocol.Handlers
case 18: // Pose case 18: // Pose
value = ReadNextVarInt(cache); value = ReadNextVarInt(cache);
break; 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);
else
value = null; // Dimension and blockPos, currently not in use
break;
case 22: // Painting Variant
value = ReadNextVarInt(cache);
break;
default: default:
throw new System.IO.InvalidDataException("Unknown Metadata Type ID " + type + ". Is this up to date for new MC Version?"); throw new System.IO.InvalidDataException("Unknown Metadata Type ID " + type + ". Is this up to date for new MC Version?");
} }

View file

@ -1470,7 +1470,7 @@ namespace MinecraftClient.Protocol.Handlers
if (handler.GetEntityHandlingEnabled()) if (handler.GetEntityHandlingEnabled())
{ {
int EntityID = dataTypes.ReadNextVarInt(packetData); int EntityID = dataTypes.ReadNextVarInt(packetData);
Dictionary<int, object> metadata = dataTypes.ReadNextMetadata(packetData, itemPalette); Dictionary<int, object?> metadata = dataTypes.ReadNextMetadata(packetData, itemPalette);
int healthField; // See https://wiki.vg/Entity_metadata#Living_Entity int healthField; // See https://wiki.vg/Entity_metadata#Living_Entity
if (protocolVersion > MC_1_19_2_Version) if (protocolVersion > MC_1_19_2_Version)
@ -1484,8 +1484,9 @@ namespace MinecraftClient.Protocol.Handlers
else else
throw new NotImplementedException(Translations.Get("exception.palette.healthfield")); throw new NotImplementedException(Translations.Get("exception.palette.healthfield"));
if (metadata.ContainsKey(healthField) && metadata[healthField] != null && metadata[healthField].GetType() == typeof(float)) if (metadata.TryGetValue(healthField, out object? healthObj) && healthObj != null && healthObj.GetType() == typeof(float))
handler.OnEntityHealth(EntityID, (float)metadata[healthField]); handler.OnEntityHealth(EntityID, (float)healthObj);
handler.OnEntityMetadata(EntityID, metadata); handler.OnEntityMetadata(EntityID, metadata);
} }
break; break;

View file

@ -318,7 +318,7 @@ namespace MinecraftClient.Protocol
/// </summary> /// </summary>
/// <param name="EntityID">Entity ID</param> /// <param name="EntityID">Entity ID</param>
/// <param name="metadata">Entity metadata</param> /// <param name="metadata">Entity metadata</param>
void OnEntityMetadata(int EntityID, Dictionary<int, object> metadata); void OnEntityMetadata(int EntityID, Dictionary<int, object?> metadata);
/// <summary> /// <summary>
/// Called when and explosion occurs on the server /// Called when and explosion occurs on the server

View file

@ -383,7 +383,7 @@ namespace MinecraftClient
/// </summary> /// </summary>
/// <param name="entity">Entity</param> /// <param name="entity">Entity</param>
/// <param name="metadata">The metadata of the entity</param> /// <param name="metadata">The metadata of the entity</param>
public virtual void OnEntityMetadata(Entity entity, Dictionary<int, object> metadata) { } public virtual void OnEntityMetadata(Entity entity, Dictionary<int, object?> metadata) { }
/// <summary> /// <summary>
/// Called when the status of client player have been changed /// Called when the status of client player have been changed