Added 1.8 entity handling

This commit is contained in:
Anon 2023-03-28 13:39:18 +02:00
parent 4ec3d0c13a
commit 0b98628572
4 changed files with 390 additions and 48 deletions

View file

@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes
{
/// <summary>
/// Defines mappings of entitiy IDs for 1.8
/// Manually typed out by Milutinke :(
/// Data source: https://pokechu22.github.io/Burger/1.8.json and https://wiki.vg/index.php?title=Entity_metadata&oldid=7415
/// </summary>
public class EntityPalette18 : EntityPalette
{
private static Dictionary<int, EntityType> mappingsObjects = new Dictionary<int, EntityType>()
{
// https://wiki.vg/Entity_metadata#Objects
{ 1, EntityType.Boat },
{ 2, EntityType.Item },
{ 3, EntityType.AreaEffectCloud },
{ 10, EntityType.Minecart },
{ 50, EntityType.Tnt },
{ 51, EntityType.EndCrystal },
{ 60, EntityType.Arrow },
{ 61, EntityType.Snowball },
{ 62, EntityType.Egg },
{ 63, EntityType.Fireball },
{ 64, EntityType.SmallFireball },
{ 65, EntityType.EnderPearl },
{ 66, EntityType.WitherSkull },
{ 70, EntityType.FallingBlock },
{ 71, EntityType.ItemFrame },
{ 72, EntityType.EyeOfEnder },
{ 73, EntityType.Egg },
{ 75, EntityType.ExperienceBottle },
{ 76, EntityType.FireworkRocket },
{ 77, EntityType.LeashKnot },
{ 78, EntityType.ArmorStand },
{ 90, EntityType.FishingBobber },
{ 91, EntityType.SpectralArrow },
{ 93, EntityType.DragonFireball },
};
private static Dictionary<int, EntityType> mappingsMobs = new Dictionary<int, EntityType>() {
{ 1, EntityType.Item },
{ 2, EntityType.ExperienceOrb },
{ 8, EntityType.LeashKnot },
{ 9, EntityType.Painting },
{ 10, EntityType.Arrow },
{ 11, EntityType.Snowball },
{ 12, EntityType.Fireball },
{ 13, EntityType.SmallFireball },
{ 14, EntityType.EnderPearl },
{ 15, EntityType.EyeOfEnder },
{ 16, EntityType.Potion },
{ 17, EntityType.ExperienceBottle },
{ 18, EntityType.ItemFrame },
{ 19, EntityType.WitherSkull },
{ 20, EntityType.Tnt },
{ 21, EntityType.FallingBlock },
{ 22, EntityType.FireworkRocket },
{ 30, EntityType.ArmorStand },
{ 40, EntityType.CommandBlockMinecart },
{ 41, EntityType.Boat },
{ 42, EntityType.Minecart },
{ 43, EntityType.ChestMinecart },
{ 44, EntityType.FurnaceMinecart },
{ 45, EntityType.TntMinecart },
{ 46, EntityType.HopperMinecart },
{ 47, EntityType.SpawnerMinecart },
{ 50, EntityType.Creeper },
{ 51, EntityType.Skeleton },
{ 52, EntityType.Spider },
{ 53, EntityType.Giant },
{ 54, EntityType.Zombie },
{ 55, EntityType.Slime },
{ 56, EntityType.Ghast },
{ 57, EntityType.ZombifiedPiglin },
{ 58, EntityType.Enderman },
{ 59, EntityType.CaveSpider },
{ 60, EntityType.Silverfish },
{ 61, EntityType.Blaze },
{ 62, EntityType.MagmaCube },
{ 63, EntityType.EnderDragon },
{ 64, EntityType.Wither },
{ 65, EntityType.Bat },
{ 66, EntityType.Witch },
{ 67, EntityType.Endermite },
{ 68, EntityType.Guardian },
{ 90, EntityType.Pig },
{ 91, EntityType.Sheep },
{ 92, EntityType.Cow },
{ 93, EntityType.Chicken },
{ 94, EntityType.Squid },
{ 95, EntityType.Wolf },
{ 96, EntityType.Mooshroom },
{ 97, EntityType.SnowGolem },
{ 98, EntityType.Cat },
{ 99, EntityType.IronGolem },
{ 100, EntityType.Horse },
{ 101, EntityType.Rabbit },
{ 120, EntityType.Villager },
{ 200, EntityType.EndCrystal }
};
protected override Dictionary<int, EntityType> GetDict()
{
return mappingsMobs;
}
protected override Dictionary<int, EntityType> GetDictNonLiving()
{
return mappingsObjects;
}
}
}

View file

@ -463,47 +463,74 @@ namespace MinecraftClient.Protocol.Handlers
public Entity ReadNextEntity(Queue<byte> cache, EntityPalette entityPalette, bool living)
{
int entityID = ReadNextVarInt(cache);
if (protocolversion > Protocol18Handler.MC_1_8_Version)
ReadNextUUID(cache);
Guid entityUUID = Guid.Empty;
// UUID field added in 1.9 +
if (protocolversion >= Protocol18Handler.MC_1_9_Version)
entityUUID = ReadNextUUID(cache);
// Entity type data type change from byte to varint in 1.13.2
EntityType entityType;
// Entity type data type change from byte to varint after 1.14
if (protocolversion > Protocol18Handler.MC_1_13_Version)
entityType = entityPalette.FromId(ReadNextVarInt(cache), living);
else
entityType = entityPalette.FromId(ReadNextByte(cache), living);
double entityX = ReadNextDouble(cache);
double entityY = ReadNextDouble(cache);
double entityZ = ReadNextDouble(cache);
byte entityPitch = ReadNextByte(cache);
byte entityYaw = ReadNextByte(cache);
int metadata = -1;
if (living)
{
if (protocolversion == Protocol18Handler.MC_1_18_2_Version)
entityYaw = ReadNextByte(cache);
else
entityPitch = ReadNextByte(cache);
// For living entities the Type field was changed to VarInt from Byte in 1.11 +
if (protocolversion >= Protocol18Handler.MC_1_11_Version)
entityType = entityPalette.FromId(ReadNextVarInt(cache), living);
else entityType = entityPalette.FromId(ReadNextByte(cache), living);
}
else
{
// For non-living entities the Type field was changed to VarInt from Byte in 1.13.2 +
if (protocolversion >= Protocol18Handler.MC_1_13_2_Version)
entityType = entityPalette.FromId(ReadNextVarInt(cache), living);
else entityType = entityPalette.FromId(ReadNextByte(cache), living);
}
Double entityX, entityY, entityZ;
if (protocolversion < Protocol18Handler.MC_1_9_Version)
{
entityX = (Double)ReadNextInt(cache); // X
entityY = (Double)ReadNextInt(cache); // Y
entityZ = (Double)ReadNextInt(cache); // Z
}
else
{
entityX = ReadNextDouble(cache); // X
entityY = ReadNextDouble(cache); // Y
entityZ = ReadNextDouble(cache); // Z
}
int metadata = -1;
byte entityPitch, entityYaw;
if (living)
{
entityYaw = ReadNextByte(cache); // Yaw
entityPitch = ReadNextByte(cache); // Pitch
entityPitch = ReadNextByte(cache); // Head Pitch
}
else
{
entityPitch = ReadNextByte(cache); // Pitch
entityYaw = ReadNextByte(cache); // Yaw
if (protocolversion >= Protocol18Handler.MC_1_19_Version)
{
entityYaw = ReadNextByte(cache);
metadata = ReadNextVarInt(cache);
}
else
metadata = ReadNextInt(cache);
entityYaw = ReadNextByte(cache); // Head Yaw
// Data
if (protocolversion >= Protocol18Handler.MC_1_19_Version)
ReadNextVarInt(cache);
else ReadNextInt(cache);
}
short velocityX = ReadNextShort(cache);
short velocityY = 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>

View file

@ -0,0 +1,130 @@
using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{
public class PacketPalette18 : PacketTypePalette
{
private Dictionary<int, PacketTypesIn> typeIn = new Dictionary<int, PacketTypesIn>()
{
{ 0x00, PacketTypesIn.KeepAlive },
{ 0x01, PacketTypesIn.JoinGame },
{ 0x02, PacketTypesIn.ChatMessage },
{ 0x03, PacketTypesIn.TimeUpdate },
{ 0x04, PacketTypesIn.EntityEquipment },
{ 0x05, PacketTypesIn.SpawnPosition },
{ 0x06, PacketTypesIn.UpdateHealth },
{ 0x07, PacketTypesIn.Respawn },
{ 0x08, PacketTypesIn.PlayerPositionAndLook },
{ 0x09, PacketTypesIn.HeldItemChange },
{ 0x0A, PacketTypesIn.UseBed },
{ 0x0B, PacketTypesIn.EntityAnimation },
{ 0x0C, PacketTypesIn.SpawnPlayer },
{ 0x0D, PacketTypesIn.CollectItem },
{ 0x0E, PacketTypesIn.SpawnEntity },
{ 0x0F, PacketTypesIn.SpawnLivingEntity },
{ 0x10, PacketTypesIn.SpawnPainting },
{ 0x11, PacketTypesIn.SpawnExperienceOrb },
{ 0x12, PacketTypesIn.EntityVelocity },
{ 0x13, PacketTypesIn.DestroyEntities },
{ 0x15, PacketTypesIn.EntityMovement },
{ 0x16, PacketTypesIn.EntityRotation },
{ 0x17, PacketTypesIn.EntityPositionAndRotation },
{ 0x18, PacketTypesIn.EntityTeleport },
{ 0x19, PacketTypesIn.EntityHeadLook },
{ 0x1A, PacketTypesIn.EntityStatus },
{ 0x1B, PacketTypesIn.AttachEntity },
{ 0x1C, PacketTypesIn.EntityMetadata },
{ 0x1D, PacketTypesIn.EntityEffect },
{ 0x1E, PacketTypesIn.RemoveEntityEffect },
{ 0x1F, PacketTypesIn.SetExperience },
{ 0x20, PacketTypesIn.EntityProperties },
{ 0x21, PacketTypesIn.ChunkData },
{ 0x22, PacketTypesIn.MultiBlockChange },
{ 0x23, PacketTypesIn.BlockChange },
{ 0x24, PacketTypesIn.BlockAction },
{ 0x25, PacketTypesIn.BlockBreakAnimation },
// Missing Chunk Bulk Data
{ 0x27, PacketTypesIn.Explosion },
{ 0x28, PacketTypesIn.Effect },
{ 0x29, PacketTypesIn.SoundEffect },
{ 0x2A, PacketTypesIn.Particle },
{ 0x2B, PacketTypesIn.ChangeGameState },
{ 0x2C, PacketTypesIn.SpawnWeatherEntity },
{ 0x2D, PacketTypesIn.OpenWindow },
{ 0x2E, PacketTypesIn.CloseWindow },
{ 0x2F, PacketTypesIn.SetSlot },
{ 0x30, PacketTypesIn.WindowItems },
{ 0x31, PacketTypesIn.WindowProperty },
{ 0x32, PacketTypesIn.WindowConfirmation },
// Missing Update Sign
{ 0x34, PacketTypesIn.MapData },
{ 0x35, PacketTypesIn.BlockEntityData },
{ 0x36, PacketTypesIn.OpenSignEditor },
{ 0x37, PacketTypesIn.Statistics },
// Missing Player List Item
{ 0x39, PacketTypesIn.PlayerAbilities },
{ 0x3A, PacketTypesIn.TabComplete },
{ 0x3B, PacketTypesIn.ScoreboardObjective },
{ 0x3C, PacketTypesIn.UpdateScore },
{ 0x3D, PacketTypesIn.DisplayScoreboard },
{ 0x3E, PacketTypesIn.Teams },
{ 0x3D, PacketTypesIn.PluginMessage },
{ 0x40, PacketTypesIn.Disconnect },
{ 0x41, PacketTypesIn.ServerDifficulty },
{ 0x42, PacketTypesIn.CombatEvent },
{ 0x43, PacketTypesIn.Camera },
{ 0x44, PacketTypesIn.WorldBorder },
{ 0x45, PacketTypesIn.Title },
{ 0x47, PacketTypesIn.PlayerListHeaderAndFooter },
{ 0x48, PacketTypesIn.ResourcePackSend },
{ 0x49, PacketTypesIn.UpdateEntityNBT }
};
private Dictionary<int, PacketTypesOut> typeOut = new Dictionary<int, PacketTypesOut>()
{
{ 0x00, PacketTypesOut.TeleportConfirm },
{ 0x01, PacketTypesOut.Unknown },
{ 0x02, PacketTypesOut.TabComplete },
{ 0x03, PacketTypesOut.ChatMessage },
{ 0x04, PacketTypesOut.ClientStatus },
{ 0x05, PacketTypesOut.ClientSettings },
{ 0x06, PacketTypesOut.WindowConfirmation },
{ 0x07, PacketTypesOut.EnchantItem },
{ 0x08, PacketTypesOut.ClickWindow },
{ 0x09, PacketTypesOut.CloseWindow },
{ 0x0A, PacketTypesOut.PluginMessage },
{ 0x0B, PacketTypesOut.InteractEntity },
{ 0x0C, PacketTypesOut.KeepAlive },
{ 0x0D, PacketTypesOut.PlayerMovement },
{ 0x0E, PacketTypesOut.PlayerPosition },
{ 0x0F, PacketTypesOut.PlayerPositionAndRotation },
{ 0x10, PacketTypesOut.PlayerRotation },
{ 0x11, PacketTypesOut.VehicleMove },
{ 0x12, PacketTypesOut.SteerBoat },
{ 0x13, PacketTypesOut.PlayerAbilities },
{ 0x14, PacketTypesOut.PlayerDigging },
{ 0x15, PacketTypesOut.EntityAction },
{ 0x16, PacketTypesOut.SteerVehicle },
{ 0x17, PacketTypesOut.RecipeBookData },
{ 0x18, PacketTypesOut.ResourcePackStatus },
{ 0x19, PacketTypesOut.AdvancementTab },
{ 0x1A, PacketTypesOut.HeldItemChange },
{ 0x1B, PacketTypesOut.CreativeInventoryAction },
{ 0x1C, PacketTypesOut.UpdateSign },
{ 0x1D, PacketTypesOut.Animation },
{ 0x1E, PacketTypesOut.Spectate },
{ 0x1F, PacketTypesOut.PlayerBlockPlacement },
{ 0x20, PacketTypesOut.UseItem },
};
protected override Dictionary<int, PacketTypesIn> GetListIn()
{
return typeIn;
}
protected override Dictionary<int, PacketTypesOut> GetListOut()
{
return typeOut;
}
}
}

View file

@ -44,6 +44,7 @@ namespace MinecraftClient.Protocol.Handlers
internal const int MC_1_9_Version = 107;
internal const int MC_1_9_1_Version = 108;
internal const int MC_1_10_Version = 210;
internal const int MC_1_11_Version = 315;
internal const int MC_1_11_2_Version = 316;
internal const int MC_1_12_Version = 335;
internal const int MC_1_12_2_Version = 340;
@ -119,14 +120,14 @@ namespace MinecraftClient.Protocol.Handlers
}
if (handler.GetInventoryEnabled() &&
(protocolVersion < MC_1_10_Version || protocolVersion > MC_1_19_4_Version))
(protocolVersion < MC_1_8_Version || protocolVersion > MC_1_19_4_Version))
{
log.Error("§c" + Translations.extra_inventory_disabled);
handler.SetInventoryEnabled(false);
}
if (handler.GetEntityHandlingEnabled() &&
(protocolVersion < MC_1_10_Version || protocolVersion > MC_1_19_4_Version))
(protocolVersion < MC_1_8_Version || protocolVersion > MC_1_19_4_Version))
{
log.Error("§c" + Translations.extra_entity_disabled);
handler.SetEntityHandlingEnabled(false);
@ -177,8 +178,9 @@ namespace MinecraftClient.Protocol.Handlers
entityPalette = new EntityPalette114();
else if (protocolVersion >= MC_1_13_Version)
entityPalette = new EntityPalette113();
else
else if (protocolVersion >= MC_1_12_Version)
entityPalette = new EntityPalette112();
else entityPalette = new EntityPalette18();
entityMetadataPalette = EntityMetadataPalette.GetPalette(protocolVersion);
@ -1973,7 +1975,10 @@ namespace MinecraftClient.Protocol.Handlers
}
else
{
int slot2 = dataTypes.ReadNextVarInt(packetData);
int slot2 = protocolVersion < MC_1_9_Version
? dataTypes.ReadNextShort(packetData)
: dataTypes.ReadNextVarInt(packetData);
Item? item = dataTypes.ReadNextItemSlot(packetData, itemPalette);
handler.OnEntityEquipment(entityid, slot2, item);
}
@ -2059,13 +2064,27 @@ namespace MinecraftClient.Protocol.Handlers
if (handler.GetEntityHandlingEnabled())
{
int EntityID = dataTypes.ReadNextVarInt(packetData);
Double DeltaX = Convert.ToDouble(dataTypes.ReadNextShort(packetData));
Double DeltaY = Convert.ToDouble(dataTypes.ReadNextShort(packetData));
Double DeltaZ = Convert.ToDouble(dataTypes.ReadNextShort(packetData));
Double DeltaX, DeltaY, DeltaZ;
if (protocolVersion < MC_1_9_Version)
{
DeltaX = Convert.ToDouble(dataTypes.ReadNextByte(packetData));
DeltaY = Convert.ToDouble(dataTypes.ReadNextByte(packetData));
DeltaZ = Convert.ToDouble(dataTypes.ReadNextByte(packetData));
}
else
{
DeltaX = Convert.ToDouble(dataTypes.ReadNextShort(packetData));
DeltaY = Convert.ToDouble(dataTypes.ReadNextShort(packetData));
DeltaZ = Convert.ToDouble(dataTypes.ReadNextShort(packetData));
}
bool OnGround = dataTypes.ReadNextBool(packetData);
DeltaX /= (128 * 32);
DeltaY /= (128 * 32);
DeltaZ /= (128 * 32);
DeltaX = DeltaX / (128 * 32);
DeltaY = DeltaY / (128 * 32);
DeltaZ = DeltaZ / (128 * 32);
handler.OnEntityPosition(EntityID, DeltaX, DeltaY, DeltaZ, OnGround);
}
@ -2074,15 +2093,30 @@ namespace MinecraftClient.Protocol.Handlers
if (handler.GetEntityHandlingEnabled())
{
int EntityID = dataTypes.ReadNextVarInt(packetData);
Double DeltaX = Convert.ToDouble(dataTypes.ReadNextShort(packetData));
Double DeltaY = Convert.ToDouble(dataTypes.ReadNextShort(packetData));
Double DeltaZ = Convert.ToDouble(dataTypes.ReadNextShort(packetData));
Double DeltaX, DeltaY, DeltaZ;
if (protocolVersion < MC_1_9_Version)
{
DeltaX = Convert.ToDouble(dataTypes.ReadNextByte(packetData));
DeltaY = Convert.ToDouble(dataTypes.ReadNextByte(packetData));
DeltaZ = Convert.ToDouble(dataTypes.ReadNextByte(packetData));
}
else
{
DeltaX = Convert.ToDouble(dataTypes.ReadNextShort(packetData));
DeltaY = Convert.ToDouble(dataTypes.ReadNextShort(packetData));
DeltaZ = Convert.ToDouble(dataTypes.ReadNextShort(packetData));
}
byte _yaw = dataTypes.ReadNextByte(packetData);
byte _pitch = dataTypes.ReadNextByte(packetData);
bool OnGround = dataTypes.ReadNextBool(packetData);
DeltaX /= (128 * 32);
DeltaY /= (128 * 32);
DeltaZ /= (128 * 32);
DeltaX = DeltaX / (128 * 32);
DeltaY = DeltaY / (128 * 32);
DeltaZ = DeltaZ / (128 * 32);
handler.OnEntityPosition(EntityID, DeltaX, DeltaY, DeltaZ, OnGround);
}
@ -2137,7 +2171,8 @@ namespace MinecraftClient.Protocol.Handlers
if (handler.GetEntityHandlingEnabled())
{
int EntityID = dataTypes.ReadNextVarInt(packetData);
Dictionary<int, object?> metadata = dataTypes.ReadNextMetadata(packetData, itemPalette, entityMetadataPalette);
Dictionary<int, object?> metadata =
dataTypes.ReadNextMetadata(packetData, itemPalette, entityMetadataPalette);
// Also make a palette for field? Will be a lot of work
int healthField; // See https://wiki.vg/Entity_metadata#Living_Entity
@ -2149,6 +2184,8 @@ namespace MinecraftClient.Protocol.Handlers
healthField = 8;
else if (protocolVersion >= MC_1_10_Version) // 1.10 and above
healthField = 7;
else if (protocolVersion >= MC_1_8_Version) // 1.8 and above
healthField = 6;
else
throw new NotImplementedException(Translations.exception_palette_healthfield);
@ -2178,9 +2215,22 @@ namespace MinecraftClient.Protocol.Handlers
if (handler.GetEntityHandlingEnabled())
{
int EntityID = dataTypes.ReadNextVarInt(packetData);
Double X = dataTypes.ReadNextDouble(packetData);
Double Y = dataTypes.ReadNextDouble(packetData);
Double Z = dataTypes.ReadNextDouble(packetData);
Double X, Y, Z;
if (protocolVersion < MC_1_9_Version)
{
X = Convert.ToDouble(dataTypes.ReadNextInt(packetData));
Y = Convert.ToDouble(dataTypes.ReadNextInt(packetData));
Z = Convert.ToDouble(dataTypes.ReadNextInt(packetData));
}
else
{
X = dataTypes.ReadNextDouble(packetData);
Y = dataTypes.ReadNextDouble(packetData);
Z = dataTypes.ReadNextDouble(packetData);
}
byte EntityYaw = dataTypes.ReadNextByte(packetData);
byte EntityPitch = dataTypes.ReadNextByte(packetData);
bool OnGround = dataTypes.ReadNextBool(packetData);
@ -3550,10 +3600,31 @@ namespace MinecraftClient.Protocol.Handlers
public bool SendPlayerBlockPlacement(int hand, Location location, Direction face, int sequenceId)
{
if (protocolVersion < MC_1_14_Version)
return false; // NOT IMPLEMENTED for older MC versions
{
Container? playerInventory = handler.GetInventory(0);
if (playerInventory == null)
return false;
List<byte> packet = new List<byte>();
packet.AddRange(dataTypes.GetLocation(location));
packet.Add(dataTypes.GetBlockFace(face));
Item item = playerInventory.Items[((McClient)handler).GetCurrentSlot()];
packet.AddRange(dataTypes.GetItemSlot(item, itemPalette));
packet.Add((byte)0); // cursorX
packet.Add((byte)0); // cursorY
packet.Add((byte)0); // cursorZ
SendPacket(PacketTypesOut.PlayerBlockPlacement, packet);
return true;
}
try
{
List<byte> packet = new();
List<byte> packet = new List<byte>();
packet.AddRange(DataTypes.GetVarInt(hand));
packet.AddRange(dataTypes.GetLocation(location));
packet.AddRange(DataTypes.GetVarInt(dataTypes.GetBlockFace(face)));