mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Bugs fix for “ClickWindow“ packet
This commit is contained in:
parent
59ed18bb40
commit
86dfd60d07
5 changed files with 67 additions and 31 deletions
|
|
@ -1243,8 +1243,7 @@ namespace MinecraftClient
|
||||||
if (inventories.ContainsKey(windowId) && inventories[windowId].Items.ContainsKey(slotId))
|
if (inventories.ContainsKey(windowId) && inventories[windowId].Items.ContainsKey(slotId))
|
||||||
item = inventories[windowId].Items[slotId];
|
item = inventories[windowId].Items[slotId];
|
||||||
|
|
||||||
// Inventory update must be after sending packet
|
List<Tuple<short, Item>> changedSlots = new List<Tuple<short, Item>>(); // List<Slot ID, Changed Items>
|
||||||
bool result = handler.SendWindowAction(windowId, slotId, action, item, inventories[windowId].Items, inventories[windowId].StateID);
|
|
||||||
|
|
||||||
// Update our inventory base on action type
|
// Update our inventory base on action type
|
||||||
var inventory = GetInventory(windowId);
|
var inventory = GetInventory(windowId);
|
||||||
|
|
@ -1295,6 +1294,8 @@ namespace MinecraftClient
|
||||||
inventory.Items[slotId] = playerInventory.Items[-1];
|
inventory.Items[slotId] = playerInventory.Items[-1];
|
||||||
playerInventory.Items.Remove(-1);
|
playerInventory.Items.Remove(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)slotId, inventory.Items[slotId]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1307,6 +1308,8 @@ namespace MinecraftClient
|
||||||
// Put target slot item to cursor
|
// Put target slot item to cursor
|
||||||
playerInventory.Items[-1] = inventory.Items[slotId];
|
playerInventory.Items[-1] = inventory.Items[slotId];
|
||||||
inventory.Items.Remove(slotId);
|
inventory.Items.Remove(slotId);
|
||||||
|
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)slotId, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -1385,6 +1388,7 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)slotId, inventory.Items[slotId]));
|
||||||
break;
|
break;
|
||||||
case WindowActionType.ShiftClick:
|
case WindowActionType.ShiftClick:
|
||||||
if (slotId == 0) break;
|
if (slotId == 0) break;
|
||||||
|
|
@ -1412,6 +1416,7 @@ namespace MinecraftClient
|
||||||
// If hotbar already have same item, will put on it first until every stack are full
|
// If hotbar already have same item, will put on it first until every stack are full
|
||||||
// If no more same item , will put on the first empty slot (smaller slot id)
|
// If no more same item , will put on the first empty slot (smaller slot id)
|
||||||
// If inventory full, item will not move
|
// If inventory full, item will not move
|
||||||
|
int itemCount = inventory.Items[slotId].Count;
|
||||||
if (slotId <= upperEndSlot)
|
if (slotId <= upperEndSlot)
|
||||||
{
|
{
|
||||||
// Clicked slot is on upper side inventory, put it to hotbar
|
// Clicked slot is on upper side inventory, put it to hotbar
|
||||||
|
|
@ -1431,11 +1436,16 @@ namespace MinecraftClient
|
||||||
// Can fit into the stack
|
// Can fit into the stack
|
||||||
inventory.Items[_item.Key].Count += inventory.Items[slotId].Count;
|
inventory.Items[_item.Key].Count += inventory.Items[slotId].Count;
|
||||||
inventory.Items.Remove(slotId);
|
inventory.Items.Remove(slotId);
|
||||||
|
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)_item.Key, inventory.Items[_item.Key]));
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)slotId, inventory.Items[slotId]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
inventory.Items[slotId].Count -= spaceLeft;
|
inventory.Items[slotId].Count -= spaceLeft;
|
||||||
inventory.Items[_item.Key].Count = inventory.Items[_item.Key].Type.StackCount();
|
inventory.Items[_item.Key].Count = inventory.Items[_item.Key].Type.StackCount();
|
||||||
|
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)_item.Key, inventory.Items[_item.Key]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1454,6 +1464,13 @@ namespace MinecraftClient
|
||||||
var itemTmp = inventory.Items[slotId];
|
var itemTmp = inventory.Items[slotId];
|
||||||
inventory.Items[emptySlot] = new Item(itemTmp.Type, itemTmp.Count, itemTmp.NBT);
|
inventory.Items[emptySlot] = new Item(itemTmp.Type, itemTmp.Count, itemTmp.NBT);
|
||||||
inventory.Items.Remove(slotId);
|
inventory.Items.Remove(slotId);
|
||||||
|
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)emptySlot, inventory.Items[emptySlot]));
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)slotId, null));
|
||||||
|
}
|
||||||
|
else if (inventory.Items[slotId].Count != itemCount)
|
||||||
|
{
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)slotId, inventory.Items[slotId]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1477,11 +1494,16 @@ namespace MinecraftClient
|
||||||
// Can fit into the stack
|
// Can fit into the stack
|
||||||
inventory.Items[_item.Key].Count += inventory.Items[slotId].Count;
|
inventory.Items[_item.Key].Count += inventory.Items[slotId].Count;
|
||||||
inventory.Items.Remove(slotId);
|
inventory.Items.Remove(slotId);
|
||||||
|
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)_item.Key, inventory.Items[_item.Key]));
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)slotId, inventory.Items[slotId]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
inventory.Items[slotId].Count -= spaceLeft;
|
inventory.Items[slotId].Count -= spaceLeft;
|
||||||
inventory.Items[_item.Key].Count = inventory.Items[_item.Key].Type.StackCount();
|
inventory.Items[_item.Key].Count = inventory.Items[_item.Key].Type.StackCount();
|
||||||
|
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)_item.Key, inventory.Items[_item.Key]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1501,6 +1523,13 @@ namespace MinecraftClient
|
||||||
var itemTmp = inventory.Items[slotId];
|
var itemTmp = inventory.Items[slotId];
|
||||||
inventory.Items[emptySlot] = new Item(itemTmp.Type, itemTmp.Count, itemTmp.NBT);
|
inventory.Items[emptySlot] = new Item(itemTmp.Type, itemTmp.Count, itemTmp.NBT);
|
||||||
inventory.Items.Remove(slotId);
|
inventory.Items.Remove(slotId);
|
||||||
|
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)emptySlot, inventory.Items[emptySlot]));
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)slotId, null));
|
||||||
|
}
|
||||||
|
else if (inventory.Items[slotId].Count != itemCount)
|
||||||
|
{
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)slotId, inventory.Items[slotId]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1512,14 +1541,18 @@ namespace MinecraftClient
|
||||||
|
|
||||||
if (inventory.Items[slotId].Count <= 0)
|
if (inventory.Items[slotId].Count <= 0)
|
||||||
inventory.Items.Remove(slotId);
|
inventory.Items.Remove(slotId);
|
||||||
|
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)slotId, inventory.Items[slotId]));
|
||||||
break;
|
break;
|
||||||
case WindowActionType.DropItemStack:
|
case WindowActionType.DropItemStack:
|
||||||
inventory.Items.Remove(slotId);
|
inventory.Items.Remove(slotId);
|
||||||
|
|
||||||
|
changedSlots.Add(new Tuple<short, Item>((short)slotId, null));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return handler.SendWindowAction(windowId, slotId, action, item, changedSlots, inventories[windowId].StateID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -2046,8 +2079,11 @@ namespace MinecraftClient
|
||||||
/// <param name="inventoryID">Window ID</param>
|
/// <param name="inventoryID">Window ID</param>
|
||||||
/// <param name="slotID">Slot ID</param>
|
/// <param name="slotID">Slot ID</param>
|
||||||
/// <param name="item">Item (may be null for empty slot)</param>
|
/// <param name="item">Item (may be null for empty slot)</param>
|
||||||
public void OnSetSlot(byte inventoryID, short slotID, Item item)
|
public void OnSetSlot(byte inventoryID, short slotID, Item item, int stateId)
|
||||||
{
|
{
|
||||||
|
if (inventories.ContainsKey(inventoryID))
|
||||||
|
inventories[inventoryID].StateID = stateId;
|
||||||
|
|
||||||
// Handle inventoryID -2 - Add item to player inventory without animation
|
// Handle inventoryID -2 - Add item to player inventory without animation
|
||||||
if (inventoryID == 254)
|
if (inventoryID == 254)
|
||||||
inventoryID = 0;
|
inventoryID = 0;
|
||||||
|
|
|
||||||
|
|
@ -720,7 +720,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
return false; //Currently not implemented
|
return false; //Currently not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SendWindowAction(int windowId, int slotId, WindowActionType action, Item item, Dictionary<int, Item> Items, int stateId)
|
public bool SendWindowAction(int windowId, int slotId, WindowActionType action, Item item, List<Tuple<short, Item>> changedSlots, int stateId)
|
||||||
{
|
{
|
||||||
return false; //Currently not implemented
|
return false; //Currently not implemented
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -917,7 +917,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
|
|
||||||
short slotID = dataTypes.ReadNextShort(packetData);
|
short slotID = dataTypes.ReadNextShort(packetData);
|
||||||
Item item = dataTypes.ReadNextItemSlot(packetData, itemPalette);
|
Item item = dataTypes.ReadNextItemSlot(packetData, itemPalette);
|
||||||
handler.OnSetSlot(windowID, slotID, item);
|
handler.OnSetSlot(windowID, slotID, item, stateId);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PacketTypesIn.WindowConfirmation:
|
case PacketTypesIn.WindowConfirmation:
|
||||||
|
|
@ -1967,7 +1967,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
catch (ObjectDisposedException) { return false; }
|
catch (ObjectDisposedException) { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SendWindowAction(int windowId, int slotId, WindowActionType action, Item item, Dictionary<int, Item> items, int stateId)
|
public bool SendWindowAction(int windowId, int slotId, WindowActionType action, Item item, List<Tuple<short, Item>> changedSlots, int stateId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -2004,51 +2004,48 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
|
|
||||||
List<byte> packet = new List<byte>();
|
List<byte> packet = new List<byte>();
|
||||||
|
|
||||||
log.Info("Window id: " + windowId + " - State id: " + stateId + " - Slot id: " + slotId + " - Mode: " + mode);
|
packet.Add((byte)windowId); // Window ID
|
||||||
log.Info("Bytes > " + (byte)windowId + " - State id: " + dataTypes.ByteArrayToString(dataTypes.GetVarInt(stateId)) + " - Slot id: " + dataTypes.ByteArrayToString(dataTypes.GetVarInt(slotId)) + " - Mode: " + dataTypes.ByteArrayToString(dataTypes.GetVarInt(mode)));
|
|
||||||
|
|
||||||
packet.Add((byte)windowId);
|
|
||||||
|
|
||||||
// 1.18+
|
// 1.18+
|
||||||
if (protocolversion >= MC1181Version)
|
if (protocolversion >= MC1181Version)
|
||||||
{
|
{
|
||||||
packet.AddRange(dataTypes.GetVarInt(stateId));
|
packet.AddRange(dataTypes.GetVarInt(stateId)); // State ID
|
||||||
packet.AddRange(dataTypes.GetShort((short)slotId));
|
packet.AddRange(dataTypes.GetShort((short)slotId)); // Slot ID
|
||||||
}
|
}
|
||||||
// 1.17.1
|
// 1.17.1
|
||||||
else if (protocolversion == MC1171Version)
|
else if (protocolversion == MC1171Version)
|
||||||
{
|
{
|
||||||
packet.AddRange(dataTypes.GetShort((short)slotId));
|
packet.AddRange(dataTypes.GetShort((short)slotId)); // Slot ID
|
||||||
packet.AddRange(dataTypes.GetVarInt(stateId));
|
packet.AddRange(dataTypes.GetVarInt(stateId)); // State ID
|
||||||
}
|
}
|
||||||
// Older
|
// Older
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
packet.AddRange(dataTypes.GetShort((short)slotId));
|
packet.AddRange(dataTypes.GetShort((short)slotId)); // Slot ID
|
||||||
}
|
}
|
||||||
|
|
||||||
packet.Add(button);
|
packet.Add(button); // Button
|
||||||
if (protocolversion < MC117Version) packet.AddRange(dataTypes.GetShort(actionNumber));
|
|
||||||
|
if (protocolversion < MC117Version)
|
||||||
|
packet.AddRange(dataTypes.GetShort(actionNumber));
|
||||||
|
|
||||||
if (protocolversion >= MC19Version)
|
if (protocolversion >= MC19Version)
|
||||||
packet.AddRange(dataTypes.GetVarInt(mode));
|
packet.AddRange(dataTypes.GetVarInt(mode)); // Mode
|
||||||
else packet.Add(mode);
|
else packet.Add(mode);
|
||||||
|
|
||||||
// 1.17+
|
// 1.17+
|
||||||
if (protocolversion >= MC117Version)
|
if (protocolversion >= MC117Version)
|
||||||
{
|
{
|
||||||
byte[] arrayOfSlots = dataTypes.GetSlotsArray(items, itemPalette);
|
packet.AddRange(dataTypes.GetVarInt(changedSlots.Count)); // Length of the array
|
||||||
|
foreach (var slot in changedSlots)
|
||||||
log.Info("Length: " + dataTypes.ByteArrayToString(dataTypes.GetVarInt(arrayOfSlots.Length)) + " (" + arrayOfSlots.Length + ")");
|
{
|
||||||
log.Info("Array: " + dataTypes.ByteArrayToString(arrayOfSlots));
|
packet.AddRange(dataTypes.GetShort(slot.Item1)); // slot ID
|
||||||
|
packet.AddRange(dataTypes.GetItemSlot(slot.Item2, itemPalette)); // slot Data
|
||||||
packet.AddRange(dataTypes.GetVarInt(arrayOfSlots.Length));
|
}
|
||||||
packet.AddRange(arrayOfSlots);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
packet.AddRange(dataTypes.GetItemSlot(item, itemPalette)); // Carried item (Clicked item)
|
packet.AddRange(dataTypes.GetItemSlot(item, itemPalette)); // Carried item (Clicked item)
|
||||||
|
|
||||||
log.Info("Packet data: " + dataTypes.ByteArrayToString(packet.ToArray()));
|
|
||||||
|
|
||||||
SendPacket(PacketTypesOut.ClickWindow, packet);
|
SendPacket(PacketTypesOut.ClickWindow, packet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -162,10 +162,12 @@ namespace MinecraftClient.Protocol
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="windowId">Id of the window being clicked</param>
|
/// <param name="windowId">Id of the window being clicked</param>
|
||||||
/// <param name="slotId">Id of the clicked slot</param>
|
/// <param name="slotId">Id of the clicked slot</param>
|
||||||
/// <param name="buttom">Action to perform</param>
|
/// <param name="action">Action to perform</param>
|
||||||
/// <param name="item">Item in the clicked slot</param>
|
/// <param name="item">Item in the clicked slot</param>
|
||||||
|
/// <param name="changedSlots">Slots that have been changed in this event: List<SlotID, Changed Items> </param>
|
||||||
|
/// <param name="stateId">Inventory's stateId</param>
|
||||||
/// <returns>True if packet was successfully sent</returns>
|
/// <returns>True if packet was successfully sent</returns>
|
||||||
bool SendWindowAction(int windowId, int slotId, WindowActionType action, Item item, Dictionary<int, Item> Items, int stateId);
|
bool SendWindowAction(int windowId, int slotId, WindowActionType action, Item item, List<Tuple<short, Item>> changedSlots, int stateId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Request Creative Mode item creation into regular/survival Player Inventory
|
/// Request Creative Mode item creation into regular/survival Player Inventory
|
||||||
|
|
|
||||||
|
|
@ -272,7 +272,8 @@ namespace MinecraftClient.Protocol
|
||||||
/// <param name="inventoryID">Window ID</param>
|
/// <param name="inventoryID">Window ID</param>
|
||||||
/// <param name="slotID">Slot ID</param>
|
/// <param name="slotID">Slot ID</param>
|
||||||
/// <param name="item">Item (may be null for empty slot)</param>
|
/// <param name="item">Item (may be null for empty slot)</param>
|
||||||
void OnSetSlot(byte inventoryID, short slotID, Item item);
|
/// <param name="stateId">State ID</param>
|
||||||
|
void OnSetSlot(byte inventoryID, short slotID, Item item, int stateId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when player health or hunger changed.
|
/// Called when player health or hunger changed.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue