From 311815be9f95b9660daee2edf1ef67f72bbf2664 Mon Sep 17 00:00:00 2001
From: ReinforceZwei <39955851+ReinforceZwei@users.noreply.github.com>
Date: Thu, 26 Mar 2020 19:10:28 +0800
Subject: [PATCH] Fix backwards support for entity, inventory handling
Seems AutoAttack not work in 1.12.2
Entity handling currently only support 1.13 or higher
---
MinecraftClient/McTcpClient.cs | 24 +++
.../Protocol/Handlers/Protocol18.cs | 137 ++++++++++++------
2 files changed, 118 insertions(+), 43 deletions(-)
diff --git a/MinecraftClient/McTcpClient.cs b/MinecraftClient/McTcpClient.cs
index 3b28c704..d5a1d231 100644
--- a/MinecraftClient/McTcpClient.cs
+++ b/MinecraftClient/McTcpClient.cs
@@ -564,6 +564,27 @@ namespace MinecraftClient
return entityHandlingEnabled;
}
+ public bool SetEntityHandlingEnabled(bool enabled)
+ {
+ if (!enabled)
+ {
+ if (entityHandlingEnabled)
+ {
+ entityHandlingEnabled = false;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ // Entity Handling cannot be enabled in runtime (or after joining server)
+ return false;
+ }
+ }
+
///
/// Get client player's inventory items
///
@@ -1104,6 +1125,7 @@ namespace MinecraftClient
///
public void OnSpawnEntity(int EntityID, int TypeID, Guid UUID, Location location)
{
+ if (entities.ContainsKey(EntityID)) return;
Entity entity = new Entity(EntityID, TypeID, EntityType.NonLivingThings, location);
entities.Add(EntityID, entity);
foreach (ChatBot bot in bots.ToArray())
@@ -1120,6 +1142,7 @@ namespace MinecraftClient
/// Cannot determine is a Mob or a Cuty Animal
public void OnSpawnLivingEntity(int EntityID, int TypeID, Guid UUID, Location location)
{
+ if (entities.ContainsKey(EntityID)) return;
Entity entity = new Entity(EntityID, TypeID, EntityType.MobAndAnimal, location);
entities.Add(EntityID, entity);
foreach (ChatBot bot in bots.ToArray())
@@ -1136,6 +1159,7 @@ namespace MinecraftClient
///
public void OnSpawnPlayer(int EntityID, Guid UUID, Location location, byte Yaw, byte Pitch)
{
+ if (entities.ContainsKey(EntityID)) return;
Entity entity = new Entity(EntityID, EntityType.Player, location);
entities.Add(EntityID, entity);
foreach (ChatBot bot in bots.ToArray())
diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs
index 38164159..93593985 100644
--- a/MinecraftClient/Protocol/Handlers/Protocol18.cs
+++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs
@@ -69,12 +69,18 @@ namespace MinecraftClient.Protocol.Handlers
handler.SetTerrainEnabled(false);
}
- if (handler.GetInventoryEnabled() && protocolversion > MC1152Version)
+ if (handler.GetInventoryEnabled() && (protocolversion > MC1152Version || protocolversion < MC110Version))
{
ConsoleIO.WriteLineFormatted("§8Inventories are currently not handled for that MC version.");
handler.SetInventoryEnabled(false);
}
+ if(handler.GetEntityHandlingEnabled() && protocolversion < MC1122Version)
+ {
+ ConsoleIO.WriteLineFormatted("§8Entities are currently not handled for that MC version.");
+ handler.SetInventoryEnabled(false);
+ }
+
if (protocolversion >= MC113Version)
{
if (protocolVersion > MC1152Version && handler.GetTerrainEnabled())
@@ -525,61 +531,96 @@ namespace MinecraftClient.Protocol.Handlers
case PacketIncomingType.WindowItems:
if (handler.GetInventoryEnabled())
{
- /*
- * Following commented code will crash
- *
- byte id = dataTypes.ReadNextByte(packetData);
- short elements = dataTypes.ReadNextShort(packetData);
+ // MC 1.12.2 or lower
+ if (protocolversion < MC113Version)
+ {
+ byte id = dataTypes.ReadNextByte(packetData);
+ short elements = dataTypes.ReadNextShort(packetData);
+ Dictionary itemsList = new Dictionary(); // index is SlotID
- for (int i = 0; i < elements; i++)
- {
- short itemID = dataTypes.ReadNextShort(packetData);
- if (itemID == -1) continue;
- byte itemCount = dataTypes.ReadNextByte(packetData);
- short itemDamage = dataTypes.ReadNextShort(packetData);
- Item item = new Item(itemID, itemCount, itemDamage, 0);
- //TODO: Add to the dictionary for the inventory its in using the id
- if (packetData.ToArray().Count() > 0)
+ for (int i = 0; i < elements; i++)
{
- dataTypes.ReadNextNbt(packetData);
- }
- }
- */
- byte id = dataTypes.ReadNextByte(packetData);
- short elements = dataTypes.ReadNextShort(packetData);
- Dictionary itemsList = new Dictionary(); // index is SlotID
- for(int i = 0; i < elements; i++)
- {
- bool haveItem = dataTypes.ReadNextBool(packetData);
- if (haveItem)
- {
- int itemID = dataTypes.ReadNextVarInt(packetData);
+ short itemID = dataTypes.ReadNextShort(packetData);
+ if (itemID == -1) continue;
byte itemCount = dataTypes.ReadNextByte(packetData);
- dataTypes.ReadNextNbt(packetData);
-
- Item item = new Item(itemID, itemCount);
+ short itemDamage = dataTypes.ReadNextShort(packetData);
+ Dictionary NBT = new Dictionary();
+ //TODO: Add to the dictionary for the inventory its in using the id
+ if (packetData.ToArray().Count() > 0)
+ {
+ NBT = dataTypes.ReadNextNbt(packetData);
+ }
+ Item item = new Item(itemID, itemCount, itemDamage, NBT);
itemsList.Add(i, item);
}
+ handler.OnWindowItems(id, itemsList);
+ }
+ else
+ {
+ // MC 1.13 after
+ byte id = dataTypes.ReadNextByte(packetData);
+ short elements = dataTypes.ReadNextShort(packetData);
+ Dictionary itemsList = new Dictionary(); // index is SlotID
+ for (int i = 0; i < elements; i++)
+ {
+ bool haveItem = dataTypes.ReadNextBool(packetData);
+ if (haveItem)
+ {
+ int itemID = dataTypes.ReadNextVarInt(packetData);
+ byte itemCount = dataTypes.ReadNextByte(packetData);
+ dataTypes.ReadNextNbt(packetData);
+
+ Item item = new Item(itemID, itemCount);
+ itemsList.Add(i, item);
+ }
+ }
+ handler.OnWindowItems(id, itemsList);
}
- handler.OnWindowItems(id, itemsList);
}
break;
case PacketIncomingType.SetSlot:
if(handler.GetInventoryEnabled())
{
- byte WindowID = dataTypes.ReadNextByte(packetData);
- short SlotID = dataTypes.ReadNextShort(packetData);
- bool Present = dataTypes.ReadNextBool(packetData);
- if (Present)
+ // MC 1.12.2 or lower
+ if (protocolversion < MC113Version)
{
- int ItemID = dataTypes.ReadNextVarInt(packetData);
- byte Count = dataTypes.ReadNextByte(packetData);
- Dictionary NBT = dataTypes.ReadNextNbt(packetData);
- handler.OnSetSlot(WindowID, SlotID, Present, ItemID, Count, NBT);
+ byte WindowID = dataTypes.ReadNextByte(packetData);
+ short SlotID = dataTypes.ReadNextShort(packetData);
+ short ItemID = dataTypes.ReadNextShort(packetData);
+ if (ItemID == -1)
+ {
+ handler.OnSetSlot(WindowID, SlotID, false);
+ }
+ else
+ {
+ byte Count = dataTypes.ReadNextByte(packetData);
+ short itemDamage = dataTypes.ReadNextShort(packetData); // useless so ignored
+ Dictionary NBT = new Dictionary();
+ //TODO: Add to the dictionary for the inventory its in using the id
+ if (packetData.ToArray().Count() > 0)
+ {
+ NBT = dataTypes.ReadNextNbt(packetData);
+ }
+ handler.OnSetSlot(WindowID, SlotID, true, ItemID, Count, NBT);
+ }
}
else
{
- handler.OnSetSlot(WindowID, SlotID, Present);
+ // MC 1.13 after
+ byte WindowID = dataTypes.ReadNextByte(packetData);
+ short SlotID = dataTypes.ReadNextShort(packetData);
+ bool Present = dataTypes.ReadNextBool(packetData);
+ if (Present)
+ {
+ int ItemID = dataTypes.ReadNextVarInt(packetData);
+ byte Count = dataTypes.ReadNextByte(packetData);
+ Dictionary NBT = dataTypes.ReadNextNbt(packetData);
+ handler.OnSetSlot(WindowID, SlotID, Present, ItemID, Count, NBT);
+ }
+ else
+ {
+ handler.OnSetSlot(WindowID, SlotID, Present);
+ }
}
}
break;
@@ -597,7 +638,11 @@ namespace MinecraftClient.Protocol.Handlers
if (handler.GetEntityHandlingEnabled())
{
int EntityID = dataTypes.ReadNextVarInt(packetData);
- Guid EntityUUID = dataTypes.ReadNextUUID(packetData);
+ Guid EntityUUID = Guid.Empty;
+ if (protocolversion > MC18Version)
+ {
+ EntityUUID = dataTypes.ReadNextUUID(packetData);
+ }
int EntityType = dataTypes.ReadNextVarInt(packetData);
Double X = dataTypes.ReadNextDouble(packetData);
Double Y = dataTypes.ReadNextDouble(packetData);
@@ -619,7 +664,11 @@ namespace MinecraftClient.Protocol.Handlers
if (handler.GetEntityHandlingEnabled())
{
int EntityID = dataTypes.ReadNextVarInt(packetData);
- Guid EntityUUID = dataTypes.ReadNextUUID(packetData);
+ Guid EntityUUID = Guid.Empty;
+ if (protocolversion > MC18Version)
+ {
+ EntityUUID = dataTypes.ReadNextUUID(packetData);
+ }
int EntityType = dataTypes.ReadNextVarInt(packetData);
Double X = dataTypes.ReadNextDouble(packetData);
Double Y = dataTypes.ReadNextDouble(packetData);
@@ -631,6 +680,8 @@ namespace MinecraftClient.Protocol.Handlers
short VelocityY = dataTypes.ReadNextShort(packetData);
short VelocityZ = dataTypes.ReadNextShort(packetData);
+ // packet before 1.15 has metadata at the end
+
Location EntityLocation = new Location(X, Y, Z);
handler.OnSpawnLivingEntity(EntityID, EntityType, EntityUUID, EntityLocation);