This commit is contained in:
BruceChen 2022-07-25 18:11:25 +08:00
commit 002795a1b6

View file

@ -358,6 +358,40 @@ namespace MinecraftClient.Protocol.Handlers
ItemType type = itemPalette.FromId(ReadNextVarInt(cache));
byte itemCount = ReadNextByte(cache);
Dictionary<string, object> nbt = ReadNextNbt(cache);
Console.WriteLine("Got ITEM NBT DATA: ");
Console.WriteLine("-----------------------------");
foreach (string x2 in GetNbtAsString(nbt, true))
{
ConsoleIO.WriteLine(x2);
}
Console.WriteLine("-----------------------------");
Console.WriteLine("-----------------------------");
foreach (KeyValuePair<string, object> i in nbt)
{
if (i.Value is object[])
{
ConsoleIO.WriteLine(i.Key.ToString() + " = {");
foreach (object o in (object[])i.Value)
{
ConsoleIO.WriteLine("\t{");
foreach (KeyValuePair<string, object> o2 in ((Dictionary<string, object>)o))
{
ConsoleIO.WriteLine("\t\t" + o2.Key.ToString() + " = " + o2.Value.ToString() + ",");
}
ConsoleIO.WriteLine("\t},\n");
}
ConsoleIO.WriteLine("},\n");
}
else ConsoleIO.WriteLine(i.Key.ToString() + " = " + i.Value.ToString() + ",");
}
Console.WriteLine("-----------------------------");
return new Item(type, itemCount, nbt);
}
else return null;
@ -447,6 +481,7 @@ namespace MinecraftClient.Protocol.Handlers
// NBT root name
string rootName = Encoding.ASCII.GetString(ReadData(ReadNextUShort(cache), cache));
if (!String.IsNullOrEmpty(rootName))
nbtData[""] = rootName;
}
@ -703,10 +738,13 @@ namespace MinecraftClient.Protocol.Handlers
// 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));
}
@ -731,6 +769,227 @@ namespace MinecraftClient.Protocol.Handlers
return bytes.ToArray();
}
public List<string> GetNbtAsString(Dictionary<string, object> nbt, bool root, string depth = "")
{
List<string> strings = new List<string>();
if (nbt == null || nbt.Count == 0)
{
strings.Add("TAG_End - No count or null");
return strings;
}
if (root)
{
// NBT root name
string rootName = null;
if (nbt.ContainsKey(""))
rootName = nbt[""] as string;
if (rootName == null)
rootName = "";
strings.Add("TAG_Compound('" + rootName + "'):");
}
foreach (var item in nbt)
{
// Skip NBT root name
if (item.Key == "" && root)
continue;
int fieldType;
string fieldContent = GetNbtFieldAsAString(item.Value, out fieldType, depth);
strings.Add(GetNbtFieldTypeString(fieldType) + "('" + item.Key + "'):");
strings.Add(depth + (fieldType == 10 ? "\t" : "") + fieldContent);
}
strings.Add("TAG_End"); // TAG_End
return strings;
}
private string GetNbtFieldAsAString(object obj, out int fieldType, string depth)
{
if (obj is byte)
{
fieldType = 1; // TAG_Byte
return ByteArrayToString(new byte[] { (byte)obj });
}
else if (obj is short)
{
fieldType = 2; // TAG_Short
return "" + (short)obj;
}
else if (obj is int)
{
fieldType = 3; // TAG_Int
return "" + (int)obj;
}
else if (obj is long)
{
fieldType = 4; // TAG_Long
return "" + (long)obj;
}
else if (obj is float)
{
fieldType = 5; // TAG_Float
return "" + (float)obj;
}
else if (obj is double)
{
fieldType = 6; // TAG_Double
return "" + (double)obj;
}
else if (obj is byte[])
{
fieldType = 7; // TAG_Byte_Array
return ByteArrayToString((byte[])obj);
}
else if (obj is string)
{
fieldType = 8; // TAG_String
return "'" + (string)obj + "'";
}
else if (obj is object[])
{
fieldType = 9; // TAG_List
List<object> list = new List<object>((object[])obj);
int arrayLengthTotal = list.Count;
// Treat empty list as TAG_Byte, length 0
if (arrayLengthTotal == 0)
return "Empty List";
// Encode first list item, retain its type
int firstItemType;
string firstItemTypeString = list[0].GetType().Name;
string firstItemData = GetNbtFieldAsAString(list[0], out firstItemType, depth);
list.RemoveAt(0);
Console.WriteLine("Parsing a TAG_List it has a size of: " + arrayLengthTotal + " and type of: " + GetNbtFieldTypeString(firstItemType));
// Encode further list items, check they have the same type
int subsequentItemType;
List<string> subsequentItems = new List<string>();
foreach (object item in list)
{
string _item = GetNbtFieldAsAString(item, out subsequentItemType, depth);
Console.WriteLine("Adding item to a list: " + _item);
subsequentItems.Add(_item);
if (subsequentItemType != firstItemType)
throw new System.IO.InvalidDataException(
"GetNbt: Cannot encode object[] list with mixed types: " + firstItemTypeString + ", " + item.GetType().Name + " into NBT string!");
}
string itemsString = "" + GetNbtFieldTypeString(firstItemType) + "('" + firstItemData.Replace("\n", "").Trim() + "'): ";
foreach (string listStr in subsequentItems)
{
itemsString += listStr;
}
return itemsString;
}
else if (obj is Dictionary<string, object>)
{
fieldType = 10; // TAG_Compound
depth += "\t";
List<string> stringList = GetNbtAsString((Dictionary<string, object>)obj, false, depth);
string itemsString = "";
foreach (string listStr in stringList)
{
itemsString = depth + listStr;
itemsString += "\n";
}
return itemsString;
}
else if (obj is int[])
{
fieldType = 11; // TAG_Int_Array
int[] srcIntList = (int[])obj;
string intListString = "";
foreach (int item in srcIntList)
{
intListString += item + ",";
}
return intListString;
}
else if (obj is long[])
{
fieldType = 12; // TAG_Long_Array
long[] srcLongList = (long[])obj;
string longListString = "";
foreach (int item in srcLongList)
{
longListString += item + ",";
}
return longListString;
}
else
{
throw new System.IO.InvalidDataException("GetNbt: Cannot encode data type " + obj.GetType().Name + " into NBT string!");
}
}
private string GetNbtFieldTypeString(int fieldType)
{
if (fieldType == 0)
return "TAG_End";
if (fieldType == 1)
return "TAG_Byte";
if (fieldType == 2)
return "TAG_Short";
if (fieldType == 3)
return "TAG_Int";
if (fieldType == 4)
return "TAG_Long";
if (fieldType == 5)
return "TAG_Float";
if (fieldType == 6)
return "TAG_Double";
if (fieldType == 7)
return "TAG_Byte_Array";
if (fieldType == 8)
return "TAG_String";
if (fieldType == 9)
return "TAG_List";
if (fieldType == 10)
return "TAG_Compound";
if (fieldType == 11)
return "TAG_Int_Array";
if (fieldType == 11)
return "TAG_Long_Array";
throw new System.IO.InvalidDataException("Invalid Field Type provided: " + fieldType);
}
/// <summary>
/// Convert a single object into its NBT representation (internal)
/// </summary>
@ -1007,10 +1266,10 @@ namespace MinecraftClient.Protocol.Handlers
{
// MC 1.13 and greater
if (item == null || item.IsEmpty)
slotData.Add(0); // No item
slotData.AddRange(GetBool(false)); // No item
else
{
slotData.Add(1); // Item is present
slotData.AddRange(GetBool(true)); // Item is present
slotData.AddRange(GetVarInt(itemPalette.ToId(item.Type)));
slotData.Add((byte)item.Count);
slotData.AddRange(GetNbt(item.NBT));