diff --git a/MinecraftClient/McTcpClient.cs b/MinecraftClient/McTcpClient.cs index 765ca3bf..fa1238be 100644 --- a/MinecraftClient/McTcpClient.cs +++ b/MinecraftClient/McTcpClient.cs @@ -26,12 +26,14 @@ namespace MinecraftClient private readonly List bots = new List(); private static readonly List botsOnHold = new List(); + private static List inventories = new List(); private readonly Dictionary> registeredBotPluginChannels = new Dictionary>(); private readonly List registeredServerPluginChannels = new List(); private bool terrainAndMovementsEnabled; private bool terrainAndMovementsRequested = false; + private bool inventoryHandling; private object locationLock = new object(); private bool locationReceived = false; private World world = new World(); @@ -47,8 +49,7 @@ namespace MinecraftClient private string username; private string uuid; private string sessionid; - private Inventory inventory; - + private Inventory playerInventory; public int GetServerPort() { return port; } public string GetServerHost() { return host; } @@ -105,6 +106,7 @@ namespace MinecraftClient private void StartClient(string user, string uuid, string sessionID, string server_ip, ushort port, int protocolversion, ForgeInfo forgeInfo, bool singlecommand, string command) { terrainAndMovementsEnabled = Settings.TerrainAndMovements; + inventoryHandling = Settings.InventoryHandling; bool retry = false; this.sessionid = sessionID; @@ -419,6 +421,14 @@ namespace MinecraftClient return terrainAndMovementsEnabled; } + /// + /// Get Inventory Handling Mode + /// + public bool GetInventoryEnabled() + { + return inventoryHandling; + } + /// /// Enable or disable Terrain and Movements. /// Please note that Enabling will be deferred until next relog, respawn or world change. @@ -598,6 +608,28 @@ namespace MinecraftClient public void onInventoryOpen(Inventory inventory) { //TODO: Handle Inventory + if (!inventories.Contains(inventory)) + { + inventories.Add(inventory); + } + } + + /// + /// When an inventory is close + /// + /// Location to reach + public void onInventoryClose(byte inventoryID) + { + for (int i = 0; i < inventories.Count; i++) + { + Inventory inventory = inventories[i]; + if (inventory == null) continue; + if (inventory.id == inventoryID) + { + inventories.Remove(inventory); + return; + } + } } /// diff --git a/MinecraftClient/Protocol/Handlers/PacketIncomingType.cs b/MinecraftClient/Protocol/Handlers/PacketIncomingType.cs index 104e2664..5cbfd3ac 100644 --- a/MinecraftClient/Protocol/Handlers/PacketIncomingType.cs +++ b/MinecraftClient/Protocol/Handlers/PacketIncomingType.cs @@ -10,7 +10,7 @@ namespace MinecraftClient.Protocol.Handlers /// enum PacketIncomingType { - KeepAlive, + KeepAlive, JoinGame, ChatMessage, Respawn, @@ -26,6 +26,7 @@ namespace MinecraftClient.Protocol.Handlers KickPacket, NetworkCompressionTreshold, ResourcePackSend, + CloseWindow, OpenWindow, WindowItems, SetSlot, diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 3130a6c8..70a09507 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -465,7 +465,7 @@ namespace MinecraftClient.Protocol.Handlers compression_treshold = dataTypes.ReadNextVarInt(packetData); break; case PacketIncomingType.OpenWindow: - if (protocolversion < MC1141Version) + if (protocolversion < MC1141Version && handler.GetInventoryEnabled()) { byte windowID = dataTypes.ReadNextByte(packetData); string type = dataTypes.ReadNextString(packetData).Replace("minecraft:", "").ToUpper(); @@ -474,12 +474,19 @@ namespace MinecraftClient.Protocol.Handlers byte slots = dataTypes.ReadNextByte(packetData); Inventory inventory = new Inventory(windowID, inventoryType, title, slots); - handler.onInventoryOpen(inventory); } break; + case PacketIncomingType.CloseWindow: + if (protocolversion < MC1141Version && handler.GetInventoryEnabled()) + { + byte windowID = dataTypes.ReadNextByte(packetData); + + handler.onInventoryClose(windowID); + } + break; case PacketIncomingType.WindowItems: - if (protocolversion < MC1141Version) + if (protocolversion < MC1141Version && handler.GetInventoryEnabled()) { byte id = dataTypes.ReadNextByte(packetData); short elements = dataTypes.ReadNextShort(packetData); diff --git a/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs b/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs index 5d0f893a..5c757922 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18PacketTypes.cs @@ -31,6 +31,7 @@ namespace MinecraftClient.Protocol.Handlers case 0x22: return PacketIncomingType.MultiBlockChange; case 0x23: return PacketIncomingType.BlockChange; case 0x26: return PacketIncomingType.MapChunkBulk; + case 0x30: return PacketIncomingType.WindowItems; //UnloadChunk does not exists prior to 1.9 case 0x38: return PacketIncomingType.PlayerListUpdate; case 0x3A: return PacketIncomingType.TabCompleteResult; @@ -39,7 +40,7 @@ namespace MinecraftClient.Protocol.Handlers case 0x46: return PacketIncomingType.NetworkCompressionTreshold; case 0x48: return PacketIncomingType.ResourcePackSend; case 0x2D: return PacketIncomingType.OpenWindow; - case 0x30: return PacketIncomingType.WindowItems; + case 0x2E: return PacketIncomingType.CloseWindow; case 0x2F: return PacketIncomingType.SetSlot; default: return PacketIncomingType.UnknownPacket; } @@ -62,6 +63,7 @@ namespace MinecraftClient.Protocol.Handlers case 0x0E: return PacketIncomingType.TabCompleteResult; case 0x18: return PacketIncomingType.PluginMessage; case 0x1A: return PacketIncomingType.KickPacket; + case 0x12: return PacketIncomingType.CloseWindow; case 0x13: return PacketIncomingType.OpenWindow; case 0x14: return PacketIncomingType.WindowItems; case 0x16: return PacketIncomingType.SetSlot; @@ -81,16 +83,17 @@ namespace MinecraftClient.Protocol.Handlers case 0x2E: return PacketIncomingType.PlayerPositionAndLook; case 0x20: return PacketIncomingType.ChunkData; case 0x10: return PacketIncomingType.MultiBlockChange; + case 0x14: return PacketIncomingType.WindowItems; + case 0x16: return PacketIncomingType.SetSlot; case 0x0B: return PacketIncomingType.BlockChange; case 0x1D: return PacketIncomingType.UnloadChunk; case 0x2D: return PacketIncomingType.PlayerListUpdate; case 0x0E: return PacketIncomingType.TabCompleteResult; case 0x18: return PacketIncomingType.PluginMessage; case 0x1A: return PacketIncomingType.KickPacket; + case 0x12: return PacketIncomingType.CloseWindow; case 0x13: return PacketIncomingType.OpenWindow; case 0x33: return PacketIncomingType.ResourcePackSend; - case 0x14: return PacketIncomingType.WindowItems; - case 0x16: return PacketIncomingType.SetSlot; default: return PacketIncomingType.UnknownPacket; } } @@ -111,6 +114,7 @@ namespace MinecraftClient.Protocol.Handlers case 0x0E: return PacketIncomingType.TabCompleteResult; case 0x18: return PacketIncomingType.PluginMessage; case 0x1A: return PacketIncomingType.KickPacket; + case 0x12: return PacketIncomingType.CloseWindow; case 0x13: return PacketIncomingType.OpenWindow; case 0x14: return PacketIncomingType.WindowItems; case 0x16: return PacketIncomingType.SetSlot; @@ -136,6 +140,7 @@ namespace MinecraftClient.Protocol.Handlers case 0x19: return PacketIncomingType.PluginMessage; case 0x1B: return PacketIncomingType.KickPacket; case 0x37: return PacketIncomingType.ResourcePackSend; + case 0x13: return PacketIncomingType.CloseWindow; case 0x14: return PacketIncomingType.OpenWindow; case 0x15: return PacketIncomingType.WindowItems; case 0x17: return PacketIncomingType.SetSlot; @@ -161,6 +166,7 @@ namespace MinecraftClient.Protocol.Handlers case 0x1A: return PacketIncomingType.KickPacket; case 0x39: return PacketIncomingType.ResourcePackSend; case 0x2E: return PacketIncomingType.OpenWindow; + case 0x13: return PacketIncomingType.CloseWindow; case 0x14: return PacketIncomingType.WindowItems; case 0x16: return PacketIncomingType.SetSlot; default: return PacketIncomingType.UnknownPacket; diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index 181f2be7..52701c2e 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -28,6 +28,7 @@ namespace MinecraftClient.Protocol World GetWorld(); bool GetTerrainEnabled(); bool SetTerrainEnabled(bool enabled); + bool GetInventoryEnabled(); /// /// Called when a server was successfully joined @@ -41,11 +42,15 @@ namespace MinecraftClient.Protocol /// TRUE if the text is JSON-Encoded void OnTextReceived(string text, bool isJson); - /// - /// This method is called when an inventory is opened + /// + /// Called when an inventory is opened /// - /// Inventory that was opened - void onInventoryOpen(Inventory inventory); + void onInventoryOpen(Inventory inventory); + + /// + /// Called when an inventory is closed + /// + void onInventoryClose(byte inventoryID); /// /// Called when the player respawns, which happens on login, respawn and world change. diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index 31715970..d928ee91 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -59,14 +59,14 @@ namespace MinecraftClient { get { - return (byte) ( - ((MCSettings_Skin_Cape ? 1 : 0) << 0) - | ((MCSettings_Skin_Jacket ? 1 : 0) << 1) - | ((MCSettings_Skin_Sleeve_Left ? 1 : 0) << 2) + return (byte)( + ((MCSettings_Skin_Cape ? 1 : 0) << 0) + | ((MCSettings_Skin_Jacket ? 1 : 0) << 1) + | ((MCSettings_Skin_Sleeve_Left ? 1 : 0) << 2) | ((MCSettings_Skin_Sleeve_Right ? 1 : 0) << 3) - | ((MCSettings_Skin_Pants_Left ? 1 : 0) << 4) - | ((MCSettings_Skin_Pants_Right ? 1 : 0) << 5) - | ((MCSettings_Skin_Hat ? 1 : 0) << 6) + | ((MCSettings_Skin_Pants_Left ? 1 : 0) << 4) + | ((MCSettings_Skin_Pants_Right ? 1 : 0) << 5) + | ((MCSettings_Skin_Hat ? 1 : 0) << 6) ); } } @@ -89,6 +89,7 @@ namespace MinecraftClient public static bool DisplayXPBarMessages = true; public static bool DisplayChatLinks = true; public static bool TerrainAndMovements = false; + public static bool InventoryHandling = false; public static string PrivateMsgsCmdName = "tell"; public static CacheType SessionCaching = CacheType.Disk; public static bool DebugMessages = false; @@ -209,7 +210,7 @@ namespace MinecraftClient { case "login": Login = argValue; break; case "password": Password = argValue; break; - case "serverip": if(!SetServerIP(argValue)) serverAlias = argValue; ; break; + case "serverip": if (!SetServerIP(argValue)) serverAlias = argValue; ; break; case "singlecommand": SingleCommand = argValue; break; case "language": Language = argValue; break; case "consoletitle": ConsoleTitle = argValue; break; @@ -224,6 +225,7 @@ namespace MinecraftClient case "showxpbarmessages": DisplayXPBarMessages = str2bool(argValue); break; case "showchatlinks": DisplayChatLinks = str2bool(argValue); break; case "terrainandmovements": TerrainAndMovements = str2bool(argValue); break; + case "inventoryhandling": InventoryHandling = str2bool(argValue); break; case "privatemsgscmdname": PrivateMsgsCmdName = argValue.ToLower().Trim(); break; case "botmessagedelay": botMessageDelay = TimeSpan.FromSeconds(str2int(argValue)); break; case "debugmessages": DebugMessages = str2bool(argValue); break; @@ -538,6 +540,7 @@ namespace MinecraftClient + "showxpbarmessages=true # Messages displayed above xp bar\r\n" + "showchatlinks=true # Show links embedded in chat messages\r\n" + "terrainandmovements=false # Uses more ram, cpu, bandwidth\r\n" + + "inventoryhandling=false # Toggle inventory handling\r\n" + "sessioncache=disk # How to retain session tokens. Use 'none', 'memory' or 'disk'\r\n" + "resolvesrvrecords=fast # Use 'false', 'fast' (5s timeout), or 'true'. Required for joining some servers.\r\n" + "accountlist=accounts.txt # See README > 'Servers and Accounts file' for more info about this file\r\n"