mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-11-07 17:36:07 +00:00
Interact with inventories
The /inventory command allow listing inventory and clicking on items Should be enough for operating GUI menus such as Server chooser/teleporter
This commit is contained in:
parent
bc3d6aba00
commit
e04f06cece
13 changed files with 574 additions and 217 deletions
|
|
@ -5,6 +5,7 @@ using System.Text;
|
|||
using System.Net.Sockets;
|
||||
using MinecraftClient.Mapping;
|
||||
using MinecraftClient.Crypto;
|
||||
using MinecraftClient.Inventory;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers
|
||||
{
|
||||
|
|
@ -319,6 +320,40 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
return ReadNextNbt(cache, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a single item slot from a cache of byte and remove it from the cache
|
||||
/// </summary>
|
||||
/// <param name="item">Item</param>
|
||||
/// <returns>The item that was read or NULL for an empty slot</returns>
|
||||
public Item ReadNextItemSlot(List<byte> cache)
|
||||
{
|
||||
List<byte> slotData = new List<byte>();
|
||||
if (protocolversion > Protocol18Handler.MC113Version)
|
||||
{
|
||||
// MC 1.13 and greater
|
||||
bool itemPresent = ReadNextBool(cache);
|
||||
if (itemPresent)
|
||||
{
|
||||
int itemID = ReadNextVarInt(cache);
|
||||
byte itemCount = ReadNextByte(cache);
|
||||
Dictionary<string, object> NBT = ReadNextNbt(cache);
|
||||
return new Item(itemID, itemCount, NBT);
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// MC 1.12.2 and lower
|
||||
short itemID = ReadNextShort(cache);
|
||||
if (itemID == -1)
|
||||
return null;
|
||||
byte itemCount = ReadNextByte(cache);
|
||||
short itemDamage = ReadNextShort(cache);
|
||||
Dictionary<string, object> NBT = ReadNextNbt(cache);
|
||||
return new Item(itemID, itemCount, NBT);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read an uncompressed Named Binary Tag blob and remove it from the cache (internal)
|
||||
/// </summary>
|
||||
|
|
@ -395,6 +430,163 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build an uncompressed Named Binary Tag blob for sending over the network
|
||||
/// </summary>
|
||||
/// <param name="nbt">Dictionary to encode as Nbt</param>
|
||||
/// <returns>Byte array for this NBT tag</returns>
|
||||
public byte[] GetNbt(Dictionary<string, object> nbt)
|
||||
{
|
||||
return GetNbt(nbt, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build an uncompressed Named Binary Tag blob for sending over the network (internal)
|
||||
/// </summary>
|
||||
/// <param name="nbt">Dictionary to encode as Nbt</param>
|
||||
/// <param name="root">TRUE if starting a new NBT tag, FALSE if processing a nested NBT tag</param>
|
||||
/// <returns>Byte array for this NBT tag</returns>
|
||||
private byte[] GetNbt(Dictionary<string, object> nbt, bool root)
|
||||
{
|
||||
if (nbt == null || nbt.Count == 0)
|
||||
return new byte[] { 0 }; // TAG_End
|
||||
|
||||
List<byte> bytes = new List<byte>();
|
||||
|
||||
if (root)
|
||||
{
|
||||
bytes.Add(10); // TAG_Compound
|
||||
}
|
||||
|
||||
foreach (var item in nbt)
|
||||
{
|
||||
byte fieldType;
|
||||
byte[] fieldNameLength = GetUShort((ushort)item.Key.Length);
|
||||
byte[] fieldName = Encoding.ASCII.GetBytes(item.Key);
|
||||
byte[] fieldData = GetNbtField(item.Value, out fieldType);
|
||||
bytes.AddRange(fieldNameLength);
|
||||
bytes.AddRange(fieldName);
|
||||
bytes.Add(fieldType);
|
||||
bytes.AddRange(fieldData);
|
||||
}
|
||||
|
||||
bytes.Add(0); // TAG_End
|
||||
return bytes.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a single object into its NBT representation (internal)
|
||||
/// </summary>
|
||||
/// <param name="obj">Object to convert</param>
|
||||
/// <param name="fieldType">Field type for the passed object</param>
|
||||
/// <returns>Binary data for the passed object</returns>
|
||||
private byte[] GetNbtField(object obj, out byte fieldType)
|
||||
{
|
||||
if (obj is byte)
|
||||
{
|
||||
fieldType = 1; // TAG_Byte
|
||||
return new[] { (byte)obj };
|
||||
}
|
||||
else if (obj is short)
|
||||
{
|
||||
fieldType = 2; // TAG_Short
|
||||
return GetShort((short)obj);
|
||||
}
|
||||
else if (obj is int)
|
||||
{
|
||||
fieldType = 3; // TAG_Int
|
||||
return GetInt((int)obj);
|
||||
}
|
||||
else if (obj is long)
|
||||
{
|
||||
fieldType = 4; // TAG_Long
|
||||
return GetLong((long)obj);
|
||||
}
|
||||
else if (obj is float)
|
||||
{
|
||||
fieldType = 5; // TAG_Float
|
||||
return GetFloat((float)obj);
|
||||
}
|
||||
else if (obj is double)
|
||||
{
|
||||
fieldType = 6; // TAG_Double
|
||||
return GetDouble((double)obj);
|
||||
}
|
||||
else if (obj is byte[])
|
||||
{
|
||||
fieldType = 7; // TAG_Byte_Array
|
||||
return (byte[])obj;
|
||||
}
|
||||
else if (obj is string)
|
||||
{
|
||||
fieldType = 8; // TAG_String
|
||||
byte[] stringBytes = Encoding.UTF8.GetBytes((string)obj);
|
||||
return ConcatBytes(GetUShort((ushort)stringBytes.Length), stringBytes);
|
||||
}
|
||||
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 ConcatBytes(new[] { (byte)1 }, GetInt(0));
|
||||
|
||||
// Encode first list item, retain its type
|
||||
byte firstItemType;
|
||||
string firstItemTypeString = list[0].GetType().Name;
|
||||
byte[] firstItemBytes = GetNbtField(list[0], out firstItemType);
|
||||
list.RemoveAt(0);
|
||||
|
||||
// Encode further list items, check they have the same type
|
||||
byte subsequentItemType;
|
||||
List<byte> subsequentItemsBytes = new List<byte>();
|
||||
foreach (object item in list)
|
||||
{
|
||||
subsequentItemsBytes.AddRange(GetNbtField(item, out subsequentItemType));
|
||||
if (subsequentItemType != firstItemType)
|
||||
throw new System.IO.InvalidDataException(
|
||||
"GetNbt: Cannot encode object[] list with mixed types: " + firstItemTypeString + ", " + item.GetType().Name + " into NBT!");
|
||||
}
|
||||
|
||||
// Build NBT list: type, length, item array
|
||||
return ConcatBytes(new[] { firstItemType }, GetInt(arrayLengthTotal), firstItemBytes, subsequentItemsBytes.ToArray());
|
||||
}
|
||||
else if (obj is Dictionary<string, object>)
|
||||
{
|
||||
fieldType = 10; // TAG_Compound
|
||||
return GetNbt((Dictionary<string, object>)obj, false);
|
||||
}
|
||||
else if (obj is int[])
|
||||
{
|
||||
fieldType = 11; // TAG_Int_Array
|
||||
|
||||
int[] srcIntList = (int[])obj;
|
||||
List<byte> encIntList = new List<byte>();
|
||||
encIntList.AddRange(GetInt(srcIntList.Length));
|
||||
foreach (int item in srcIntList)
|
||||
encIntList.AddRange(GetInt(item));
|
||||
return encIntList.ToArray();
|
||||
}
|
||||
else if (obj is long[])
|
||||
{
|
||||
fieldType = 12; // TAG_Long_Array
|
||||
|
||||
long[] srcLongList = (long[])obj;
|
||||
List<byte> encLongList = new List<byte>();
|
||||
encLongList.AddRange(GetInt(srcLongList.Length));
|
||||
foreach (long item in srcLongList)
|
||||
encLongList.AddRange(GetLong(item));
|
||||
return encLongList.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.IO.InvalidDataException("GetNbt: Cannot encode data type " + obj.GetType().Name + " into NBT!");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build an integer for sending over the network
|
||||
/// </summary>
|
||||
|
|
@ -412,6 +604,30 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
return bytes.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get byte array representing a long integer
|
||||
/// </summary>
|
||||
/// <param name="number">Long to process</param>
|
||||
/// <returns>Array ready to send</returns>
|
||||
public byte[] GetLong(long number)
|
||||
{
|
||||
byte[] theLong = BitConverter.GetBytes(number);
|
||||
Array.Reverse(theLong);
|
||||
return theLong;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get byte array representing an integer
|
||||
/// </summary>
|
||||
/// <param name="number">Integer to process</param>
|
||||
/// <returns>Array ready to send</returns>
|
||||
public byte[] GetInt(int number)
|
||||
{
|
||||
byte[] theInt = BitConverter.GetBytes(number);
|
||||
Array.Reverse(theInt);
|
||||
return theInt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get byte array representing a short
|
||||
/// </summary>
|
||||
|
|
@ -424,6 +640,18 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
return theShort;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get byte array representing an unsigned short
|
||||
/// </summary>
|
||||
/// <param name="number">Short to process</param>
|
||||
/// <returns>Array ready to send</returns>
|
||||
public byte[] GetUShort(ushort number)
|
||||
{
|
||||
byte[] theShort = BitConverter.GetBytes(number);
|
||||
Array.Reverse(theShort);
|
||||
return theShort;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get byte array representing a double
|
||||
/// </summary>
|
||||
|
|
@ -448,7 +676,6 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
return theFloat;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get byte array with length information prepended to it
|
||||
/// </summary>
|
||||
|
|
@ -473,7 +700,6 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
public byte[] GetString(string text)
|
||||
{
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(text);
|
||||
|
||||
return ConcatBytes(GetVarInt(bytes.Length), bytes);
|
||||
}
|
||||
|
||||
|
|
@ -499,6 +725,42 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
return locationBytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a byte array representing the given item as an item slot
|
||||
/// </summary>
|
||||
/// <param name="item">Item</param>
|
||||
/// <returns>Item slot representation</returns>
|
||||
public byte[] GetItemSlot(Item item)
|
||||
{
|
||||
List<byte> slotData = new List<byte>();
|
||||
if (protocolversion > Protocol18Handler.MC113Version)
|
||||
{
|
||||
// MC 1.13 and greater
|
||||
if (item == null || item.IsEmpty)
|
||||
slotData.Add(0); // No item
|
||||
else
|
||||
{
|
||||
slotData.Add(1); // Item is present
|
||||
slotData.AddRange(GetVarInt((int)item.Type));
|
||||
slotData.Add((byte)item.Count);
|
||||
slotData.AddRange(GetNbt(item.NBT));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// MC 1.12.2 and lower
|
||||
if (item == null || item.IsEmpty)
|
||||
slotData.AddRange(GetShort(-1));
|
||||
else
|
||||
{
|
||||
slotData.AddRange(GetShort((short)item.Type));
|
||||
slotData.Add((byte)item.Count);
|
||||
slotData.AddRange(GetNbt(item.NBT));
|
||||
}
|
||||
}
|
||||
return slotData.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easily append several byte arrays
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
HeldItemChange,
|
||||
InteractEntity,
|
||||
UseItem,
|
||||
ClickWindow,
|
||||
CloseWindow,
|
||||
PlayerBlockPlacement
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using MinecraftClient.Crypto;
|
|||
using MinecraftClient.Proxy;
|
||||
using System.Security.Cryptography;
|
||||
using MinecraftClient.Mapping;
|
||||
using MinecraftClient.Inventory;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers
|
||||
{
|
||||
|
|
@ -641,22 +642,32 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
return false; //Currently not implemented
|
||||
}
|
||||
|
||||
public bool SendInteractEntityPacket(int EntityID, int type)
|
||||
public bool SendInteractEntity(int EntityID, int type)
|
||||
{
|
||||
return false; //Currently not implemented
|
||||
}
|
||||
|
||||
public bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z, int hand)
|
||||
public bool SendInteractEntity(int EntityID, int type, float X, float Y, float Z, int hand)
|
||||
{
|
||||
return false; //Currently not implemented
|
||||
}
|
||||
|
||||
public bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z)
|
||||
public bool SendInteractEntity(int EntityID, int type, float X, float Y, float Z)
|
||||
{
|
||||
return false; //Currently not implemented
|
||||
}
|
||||
|
||||
public bool SendUseItemPacket(int hand)
|
||||
public bool SendUseItem(int hand)
|
||||
{
|
||||
return false; //Currently not implemented
|
||||
}
|
||||
|
||||
public bool SendClickWindow(int windowId, int slotId, Item item)
|
||||
{
|
||||
return false; //Currently not implemented
|
||||
}
|
||||
|
||||
public bool SendCloseWindow(int windowId)
|
||||
{
|
||||
return false; //Currently not implemented
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
private bool autocomplete_received = false;
|
||||
private int autocomplete_transaction_id = 0;
|
||||
private readonly List<string> autocomplete_result = new List<string>();
|
||||
private readonly Dictionary<int, short> window_actions = new Dictionary<int, short>();
|
||||
private bool login_phase = true;
|
||||
private int protocolversion;
|
||||
private int currentDimension;
|
||||
|
|
@ -497,23 +498,27 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case PacketIncomingType.OpenWindow:
|
||||
if (handler.GetInventoryEnabled())
|
||||
{
|
||||
if (protocolversion < MC114Version) // packet changed at 1.14
|
||||
if (protocolversion < MC114Version)
|
||||
{
|
||||
// MC 1.13 or lower
|
||||
byte windowID = dataTypes.ReadNextByte(packetData);
|
||||
string type = dataTypes.ReadNextString(packetData).Replace("minecraft:", "").ToUpper();
|
||||
ContainerTypeOld inventoryType = (ContainerTypeOld)Enum.Parse(typeof(ContainerTypeOld), type);
|
||||
string title = dataTypes.ReadNextString(packetData);
|
||||
byte slots = dataTypes.ReadNextByte(packetData);
|
||||
Container inventory = new Container(windowID, inventoryType, title);
|
||||
handler.OnInventoryOpen(inventory);
|
||||
Container inventory = new Container(windowID, inventoryType, ChatParser.ParseText(title));
|
||||
window_actions[windowID] = 0;
|
||||
handler.OnInventoryOpen(windowID, inventory);
|
||||
}
|
||||
else
|
||||
{
|
||||
int WindowID = dataTypes.ReadNextVarInt(packetData);
|
||||
int WindowType = dataTypes.ReadNextVarInt(packetData);
|
||||
// MC 1.14 or greater
|
||||
int windowID = dataTypes.ReadNextVarInt(packetData);
|
||||
int windowType = dataTypes.ReadNextVarInt(packetData);
|
||||
string title = dataTypes.ReadNextString(packetData);
|
||||
Container inventory = new Container(WindowID, WindowType, title);
|
||||
handler.OnInventoryOpen(inventory);
|
||||
Container inventory = new Container(windowID, windowType, ChatParser.ParseText(title));
|
||||
window_actions[windowID] = 0;
|
||||
handler.OnInventoryOpen(windowID, inventory);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -521,103 +526,32 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
if (handler.GetInventoryEnabled())
|
||||
{
|
||||
byte windowID = dataTypes.ReadNextByte(packetData);
|
||||
window_actions[windowID] = 0;
|
||||
handler.OnInventoryClose(windowID);
|
||||
}
|
||||
break;
|
||||
case PacketIncomingType.WindowItems:
|
||||
if (handler.GetInventoryEnabled())
|
||||
{
|
||||
// MC 1.12.2 or lower
|
||||
if (protocolversion < MC113Version)
|
||||
byte windowId = dataTypes.ReadNextByte(packetData);
|
||||
short elements = dataTypes.ReadNextShort(packetData);
|
||||
Dictionary<int, Item> inventorySlots = new Dictionary<int, Item>();
|
||||
for (short slotId = 0; slotId < elements; slotId++)
|
||||
{
|
||||
byte id = dataTypes.ReadNextByte(packetData);
|
||||
short elements = dataTypes.ReadNextShort(packetData);
|
||||
Dictionary<int, Item> itemsList = new Dictionary<int, Item>(); // 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);
|
||||
Dictionary<string, object> NBT = new Dictionary<string, object>();
|
||||
//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<int, Item> itemsList = new Dictionary<int, Item>(); // 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, i);
|
||||
itemsList.Add(i, item);
|
||||
}
|
||||
}
|
||||
handler.OnWindowItems(id, itemsList);
|
||||
Item item = dataTypes.ReadNextItemSlot(packetData);
|
||||
if (item != null)
|
||||
inventorySlots[slotId] = item;
|
||||
}
|
||||
handler.OnWindowItems(windowId, inventorySlots);
|
||||
}
|
||||
break;
|
||||
case PacketIncomingType.SetSlot:
|
||||
if(handler.GetInventoryEnabled())
|
||||
if (handler.GetInventoryEnabled())
|
||||
{
|
||||
// MC 1.12.2 or lower
|
||||
if (protocolversion < MC113Version)
|
||||
{
|
||||
byte WindowID = dataTypes.ReadNextByte(packetData);
|
||||
short SlotID = dataTypes.ReadNextShort(packetData);
|
||||
short ItemID = dataTypes.ReadNextShort(packetData);
|
||||
if (ItemID == -1)
|
||||
{
|
||||
handler.OnSlotClear(WindowID, SlotID);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte Count = dataTypes.ReadNextByte(packetData);
|
||||
short itemDamage = dataTypes.ReadNextShort(packetData); // useless so ignored
|
||||
Dictionary<string, object> NBT = new Dictionary<string, object>();
|
||||
//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, ItemID, Count, NBT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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<string, object> NBT = dataTypes.ReadNextNbt(packetData);
|
||||
handler.OnSetSlot(WindowID, SlotID, ItemID, Count, NBT);
|
||||
}
|
||||
else
|
||||
{
|
||||
handler.OnSlotClear(WindowID, SlotID);
|
||||
}
|
||||
}
|
||||
byte windowID = dataTypes.ReadNextByte(packetData);
|
||||
short slotID = dataTypes.ReadNextShort(packetData);
|
||||
Item item = dataTypes.ReadNextItemSlot(packetData);
|
||||
handler.OnSetSlot(windowID, slotID, item);
|
||||
}
|
||||
break;
|
||||
case PacketIncomingType.ResourcePackSend:
|
||||
|
|
@ -1285,7 +1219,7 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
/// <param name="EntityID"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public bool SendInteractEntityPacket(int EntityID, int type)
|
||||
public bool SendInteractEntity(int EntityID, int type)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -1300,7 +1234,7 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
catch (ObjectDisposedException) { return false; }
|
||||
}
|
||||
// TODO: Interact at block location (e.g. chest minecart)
|
||||
public bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z, int hand)
|
||||
public bool SendInteractEntity(int EntityID, int type, float X, float Y, float Z, int hand)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -1318,12 +1252,12 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
catch (System.IO.IOException) { return false; }
|
||||
catch (ObjectDisposedException) { return false; }
|
||||
}
|
||||
public bool SendInteractEntityPacket(int EntityID, int type, float X, float Y, float Z)
|
||||
public bool SendInteractEntity(int EntityID, int type, float X, float Y, float Z)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool SendUseItemPacket(int hand)
|
||||
public bool SendUseItem(int hand)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -1370,5 +1304,45 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
catch (System.IO.IOException) { return false; }
|
||||
catch (ObjectDisposedException) { return false; }
|
||||
}
|
||||
|
||||
public bool SendClickWindow(int windowId, int slotId, Item item)
|
||||
{
|
||||
try
|
||||
{
|
||||
short actionNumber = (short)(window_actions[windowId] + 1);
|
||||
window_actions[windowId] = actionNumber;
|
||||
|
||||
List<byte> packet = new List<byte>();
|
||||
packet.Add((byte)windowId);
|
||||
packet.AddRange(dataTypes.GetShort((short)slotId));
|
||||
packet.Add(0); // Left mouse click
|
||||
packet.AddRange(dataTypes.GetShort(actionNumber));
|
||||
|
||||
// Operation mode = 0 (default)
|
||||
if (protocolversion >= MC19Version)
|
||||
packet.AddRange(dataTypes.GetVarInt(0));
|
||||
else packet.Add(0);
|
||||
|
||||
packet.AddRange(dataTypes.GetItemSlot(item));
|
||||
|
||||
SendPacket(PacketOutgoingType.ClickWindow, packet);
|
||||
return true;
|
||||
}
|
||||
catch (SocketException) { return false; }
|
||||
catch (System.IO.IOException) { return false; }
|
||||
catch (ObjectDisposedException) { return false; }
|
||||
}
|
||||
|
||||
public bool SendCloseWindow(int windowId)
|
||||
{
|
||||
try
|
||||
{
|
||||
SendPacket(PacketOutgoingType.CloseWindow, new[] { (byte)windowId });
|
||||
return true;
|
||||
}
|
||||
catch (SocketException) { return false; }
|
||||
catch (System.IO.IOException) { return false; }
|
||||
catch (ObjectDisposedException) { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,6 +306,8 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case PacketOutgoingType.HeldItemChange: return 0x17;
|
||||
case PacketOutgoingType.InteractEntity: return 0x02;
|
||||
case PacketOutgoingType.TeleportConfirm: throw new InvalidOperationException("Teleport confirm is not supported in protocol " + protocol);
|
||||
case PacketOutgoingType.ClickWindow: return 0x0E;
|
||||
case PacketOutgoingType.CloseWindow: return 0x0D;
|
||||
}
|
||||
}
|
||||
else if (protocol <= Protocol18Handler.MC1112Version) // MC 1.9, 1,10 and 1.11
|
||||
|
|
@ -324,6 +326,8 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case PacketOutgoingType.TeleportConfirm: return 0x00;
|
||||
case PacketOutgoingType.HeldItemChange: return 0x17;
|
||||
case PacketOutgoingType.InteractEntity: return 0x0A;
|
||||
case PacketOutgoingType.ClickWindow: return 0x07;
|
||||
case PacketOutgoingType.CloseWindow: return 0x08;
|
||||
}
|
||||
}
|
||||
else if (protocol <= Protocol18Handler.MC112Version) // MC 1.12
|
||||
|
|
@ -342,6 +346,8 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case PacketOutgoingType.TeleportConfirm: return 0x00;
|
||||
case PacketOutgoingType.HeldItemChange: return 0x1A;
|
||||
case PacketOutgoingType.InteractEntity: return 0x0B;
|
||||
case PacketOutgoingType.ClickWindow: return 0x07;
|
||||
case PacketOutgoingType.CloseWindow: return 0x08;
|
||||
}
|
||||
}
|
||||
else if (protocol <= Protocol18Handler.MC1122Version) // 1.12.2
|
||||
|
|
@ -360,6 +366,8 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case PacketOutgoingType.TeleportConfirm: return 0x00;
|
||||
case PacketOutgoingType.HeldItemChange: return 0x1F;
|
||||
case PacketOutgoingType.InteractEntity: return 0x0A;
|
||||
case PacketOutgoingType.ClickWindow: return 0x07;
|
||||
case PacketOutgoingType.CloseWindow: return 0x08;
|
||||
}
|
||||
}
|
||||
else if (protocol < Protocol18Handler.MC114Version) // MC 1.13 to 1.13.2
|
||||
|
|
@ -378,6 +386,8 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case PacketOutgoingType.TeleportConfirm: return 0x00;
|
||||
case PacketOutgoingType.HeldItemChange: return 0x21;
|
||||
case PacketOutgoingType.InteractEntity: return 0x0D;
|
||||
case PacketOutgoingType.ClickWindow: return 0x08;
|
||||
case PacketOutgoingType.CloseWindow: return 0x09;
|
||||
}
|
||||
}
|
||||
else // MC 1.14 to 1.15
|
||||
|
|
@ -398,6 +408,8 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case PacketOutgoingType.InteractEntity: return 0x0E;
|
||||
case PacketOutgoingType.UseItem: return 0x2D;
|
||||
case PacketOutgoingType.PlayerBlockPlacement: return 0x2C;
|
||||
case PacketOutgoingType.ClickWindow: return 0x09;
|
||||
case PacketOutgoingType.CloseWindow: return 0x0A;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue