Inventory handling improvements

Fix click issue for item with NBT
Show custom display names in inventory
See issues #910 #912 #914
This commit is contained in:
ORelio 2020-04-01 22:05:44 +02:00
parent b01c50b792
commit dbe02c063c
4 changed files with 51 additions and 9 deletions

View file

@ -37,7 +37,12 @@ namespace MinecraftClient.Commands
List<string> response = new List<string>();
response.Add("Inventory #" + inventoryId + " - " + inventory.Title + "§8");
foreach (KeyValuePair<int, Item> item in inventory.Items)
response.Add(String.Format(" #{0}: {1} x{2}", item.Key, item.Value.Type, item.Value.Count));
{
string displayName = item.Value.DisplayName;
if (String.IsNullOrEmpty(displayName))
response.Add(String.Format(" #{0}: {1} x{2}", item.Key, item.Value.Type, item.Value.Count));
else response.Add(String.Format(" #{0}: {1} x{2} - {3}§8", item.Key, item.Value.Type, item.Value.Count, displayName));
}
return String.Join("\n", response.ToArray());
case "click":
if (args.Length == 3)

View file

@ -49,5 +49,26 @@ namespace MinecraftClient.Inventory
return Type == ItemType.Air || Count == 0;
}
}
/// <summary>
/// Retrieve item display name from NBT properties. NULL if no display name is defined.
/// </summary>
public string DisplayName
{
get
{
if (NBT != null && NBT.ContainsKey("display"))
{
var displayProperties = NBT["display"] as Dictionary<string, object>;
if (displayProperties != null && displayProperties.ContainsKey("Name"))
{
string displayName = displayProperties["Name"] as string;
if (!String.IsNullOrEmpty(displayName))
return MinecraftClient.Protocol.ChatParser.ParseText(displayProperties["Name"].ToString());
}
}
return null;
}
}
}
}

View file

@ -368,7 +368,11 @@ namespace MinecraftClient.Protocol.Handlers
if (cache[0] != 10) // TAG_Compound
throw new System.IO.InvalidDataException("Failed to decode NBT: Does not start with TAG_Compound");
ReadNextByte(cache); // Tag type (TAG_Compound)
ReadData(ReadNextUShort(cache), cache); // NBT root name
// NBT root name
string rootName = Encoding.ASCII.GetString(ReadData(ReadNextUShort(cache), cache));
if (!String.IsNullOrEmpty(rootName))
NbtData[""] = rootName;
}
while (true)
@ -456,6 +460,15 @@ namespace MinecraftClient.Protocol.Handlers
if (root)
{
bytes.Add(10); // TAG_Compound
// NBT root name
string rootName = null;
if (nbt.ContainsKey(""))
rootName = nbt[""] as string;
if (rootName == null)
rootName = "";
bytes.AddRange(GetUShort((ushort)rootName.Length));
bytes.AddRange(Encoding.ASCII.GetBytes(rootName));
}
foreach (var item in nbt)
@ -464,9 +477,9 @@ namespace MinecraftClient.Protocol.Handlers
byte[] fieldNameLength = GetUShort((ushort)item.Key.Length);
byte[] fieldName = Encoding.ASCII.GetBytes(item.Key);
byte[] fieldData = GetNbtField(item.Value, out fieldType);
bytes.Add(fieldType);
bytes.AddRange(fieldNameLength);
bytes.AddRange(fieldName);
bytes.Add(fieldType);
bytes.AddRange(fieldData);
}

View file

@ -507,7 +507,6 @@ namespace MinecraftClient.Protocol.Handlers
string title = dataTypes.ReadNextString(packetData);
byte slots = dataTypes.ReadNextByte(packetData);
Container inventory = new Container(windowID, inventoryType, ChatParser.ParseText(title));
window_actions[windowID] = 0;
handler.OnInventoryOpen(windowID, inventory);
}
else
@ -517,7 +516,6 @@ namespace MinecraftClient.Protocol.Handlers
int windowType = dataTypes.ReadNextVarInt(packetData);
string title = dataTypes.ReadNextString(packetData);
Container inventory = new Container(windowID, windowType, ChatParser.ParseText(title));
window_actions[windowID] = 0;
handler.OnInventoryOpen(windowID, inventory);
}
}
@ -526,7 +524,7 @@ namespace MinecraftClient.Protocol.Handlers
if (handler.GetInventoryEnabled())
{
byte windowID = dataTypes.ReadNextByte(packetData);
window_actions[windowID] = 0;
lock (window_actions) { window_actions[windowID] = 0; }
handler.OnInventoryClose(windowID);
}
break;
@ -542,7 +540,6 @@ namespace MinecraftClient.Protocol.Handlers
if (item != null)
inventorySlots[slotId] = item;
}
window_actions[windowId] = 0;
handler.OnWindowItems(windowId, inventorySlots);
}
break;
@ -1317,8 +1314,14 @@ namespace MinecraftClient.Protocol.Handlers
{
try
{
short actionNumber = (short)(window_actions[windowId] + 1);
window_actions[windowId] = actionNumber;
short actionNumber;
lock (window_actions)
{
if (!window_actions.ContainsKey(windowId))
window_actions[windowId] = 0;
actionNumber = (short)(window_actions[windowId] + 1);
window_actions[windowId] = actionNumber;
}
List<byte> packet = new List<byte>();
packet.Add((byte)windowId);