diff --git a/MinecraftClient/Commands/Move.cs b/MinecraftClient/Commands/Move.cs index a9cbcab6..f90424c7 100644 --- a/MinecraftClient/Commands/Move.cs +++ b/MinecraftClient/Commands/Move.cs @@ -65,7 +65,7 @@ namespace MinecraftClient.Commands } else return CMDDesc; } - else return "Please enable terrainandmovements in config to use this command."; + else return "Please enable terrainandmovements to use this command."; } } } diff --git a/MinecraftClient/Mapping/Location.cs b/MinecraftClient/Mapping/Location.cs index ed683134..0d199951 100644 --- a/MinecraftClient/Mapping/Location.cs +++ b/MinecraftClient/Mapping/Location.cs @@ -167,41 +167,6 @@ namespace MinecraftClient.Mapping return false; } - /// - /// Get a representation of the location as unsigned long - /// - /// - /// A modulo will be applied if the location is outside the following ranges: - /// X: -33,554,432 to +33,554,431 - /// Y: -2,048 to +2,047 - /// Z: -33,554,432 to +33,554,431 - /// - /// Location representation as ulong - - public ulong GetLong() - { - return ((((ulong)X) & 0x3FFFFFF) << 38) | ((((ulong)Y) & 0xFFF) << 26) | (((ulong)Z) & 0x3FFFFFF); - } - - /// - /// Get a location from an unsigned long. - /// - /// Location represented by the ulong - - public static Location FromLong(ulong location) - { - int x = (int)(location >> 38); - int y = (int)((location >> 26) & 0xFFF); - int z = (int)(location << 38 >> 38); - if (x >= 33554432) - x -= 67108864; - if (y >= 2048) - y -= 4096; - if (z >= 33554432) - z -= 67108864; - return new Location(x, y, z); - } - /// /// Compare two locations. Locations are equals if the integer part of their coordinates are equals. /// diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 976ec146..0a52f183 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -30,7 +30,7 @@ namespace MinecraftClient public const string Version = MCHighestVersion; public const string MCLowestVersion = "1.4.6"; - public const string MCHighestVersion = "1.13.2"; + public const string MCHighestVersion = "1.14"; public static readonly string BuildInfo = null; private static Thread offlinePrompt = null; diff --git a/MinecraftClient/Protocol/Handlers/Protocol16.cs b/MinecraftClient/Protocol/Handlers/Protocol16.cs index 391fa066..65a7cf49 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol16.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs @@ -38,9 +38,7 @@ namespace MinecraftClient.Protocol.Handlers if (Handler.GetTerrainEnabled()) { ConsoleIO.WriteLineFormatted("§8Terrain & Movements currently not handled for that MC version."); - // Re-enable terrain on next relog on a supported server version Handler.SetTerrainEnabled(false); - Handler.SetTerrainEnabled(true); } } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 32306896..548764ed 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -33,6 +33,7 @@ namespace MinecraftClient.Protocol.Handlers private const int MC1121Version = 338; private const int MC1122Version = 340; private const int MC113Version = 393; + private const int MC114Version = 477; private int compression_treshold = 0; private bool autocomplete_received = false; @@ -64,6 +65,12 @@ namespace MinecraftClient.Protocol.Handlers if (protocolversion >= MC113Version) Block.Palette = new Palette113(); else Block.Palette = new Palette112(); + + if (Handler.GetTerrainEnabled() && protocolversion >= MC114Version) + { + ConsoleIO.WriteLineFormatted("§8Terrain & Movements currently not handled for that MC version."); + Handler.SetTerrainEnabled(false); + } } private Protocol18Handler(TcpClient Client) @@ -232,13 +239,11 @@ namespace MinecraftClient.Protocol.Handlers case 0x20: return PacketIncomingType.ChunkData; case 0x10: return PacketIncomingType.MultiBlockChange; case 0x0B: return PacketIncomingType.BlockChange; - //MapChunkBulk removed in 1.9 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; - //NetworkCompressionTreshold removed in 1.9 case 0x33: return PacketIncomingType.ResourcePackSend; default: return PacketIncomingType.UnknownPacket; } @@ -255,18 +260,16 @@ namespace MinecraftClient.Protocol.Handlers case 0x20: return PacketIncomingType.ChunkData; case 0x10: return PacketIncomingType.MultiBlockChange; case 0x0B: return PacketIncomingType.BlockChange; - //MapChunkBulk removed in 1.9 case 0x1D: return PacketIncomingType.UnloadChunk; case 0x2E: return PacketIncomingType.PlayerListUpdate; case 0x0E: return PacketIncomingType.TabCompleteResult; case 0x18: return PacketIncomingType.PluginMessage; case 0x1A: return PacketIncomingType.KickPacket; - //NetworkCompressionTreshold removed in 1.9 case 0x34: return PacketIncomingType.ResourcePackSend; default: return PacketIncomingType.UnknownPacket; } } - else // MC 1.13+ + else if (protocolversion < MC114Version) // MC 1.13 to 1.13.2 { switch (packetID) { @@ -278,17 +281,36 @@ namespace MinecraftClient.Protocol.Handlers case 0x22: return PacketIncomingType.ChunkData; case 0x0F: return PacketIncomingType.MultiBlockChange; case 0x0B: return PacketIncomingType.BlockChange; - //MapChunkBulk removed in 1.9 case 0x1F: return PacketIncomingType.UnloadChunk; case 0x30: return PacketIncomingType.PlayerListUpdate; case 0x10: return PacketIncomingType.TabCompleteResult; case 0x19: return PacketIncomingType.PluginMessage; case 0x1B: return PacketIncomingType.KickPacket; - //NetworkCompressionTreshold removed in 1.9 case 0x37: return PacketIncomingType.ResourcePackSend; default: return PacketIncomingType.UnknownPacket; } } + else // MC 1.14 + { + switch (packetID) + { + case 0x20: return PacketIncomingType.KeepAlive; + case 0x25: return PacketIncomingType.JoinGame; + case 0x0E: return PacketIncomingType.ChatMessage; + case 0x3A: return PacketIncomingType.Respawn; + case 0x35: return PacketIncomingType.PlayerPositionAndLook; + case 0x21: return PacketIncomingType.ChunkData; + case 0x0F: return PacketIncomingType.MultiBlockChange; + case 0x0B: return PacketIncomingType.BlockChange; + case 0x1D: return PacketIncomingType.UnloadChunk; + case 0x33: return PacketIncomingType.PlayerListUpdate; + case 0x10: return PacketIncomingType.TabCompleteResult; + case 0x18: return PacketIncomingType.PluginMessage; + case 0x1A: return PacketIncomingType.KickPacket; + case 0x39: return PacketIncomingType.ResourcePackSend; + default: return PacketIncomingType.UnknownPacket; + } + } } /// @@ -380,7 +402,7 @@ namespace MinecraftClient.Protocol.Handlers case PacketOutgoingType.TeleportConfirm: return 0x00; } } - else // MC 1.13+ + else if (protocol < MC114Version) // MC 1.13 to 1.13.2 { switch (packet) { @@ -396,6 +418,22 @@ namespace MinecraftClient.Protocol.Handlers case PacketOutgoingType.TeleportConfirm: return 0x00; } } + else // MC 1.14 + { + switch (packet) + { + case PacketOutgoingType.KeepAlive: return 0x0F; + case PacketOutgoingType.ResourcePackStatus: return 0x1F; + case PacketOutgoingType.ChatMessage: return 0x03; + case PacketOutgoingType.ClientStatus: return 0x04; + case PacketOutgoingType.ClientSettings: return 0x05; + case PacketOutgoingType.PluginMessage: return 0x0B; + case PacketOutgoingType.TabComplete: return 0x06; + case PacketOutgoingType.PlayerPosition: return 0x11; + case PacketOutgoingType.PlayerPositionAndLook: return 0x12; + case PacketOutgoingType.TeleportConfirm: return 0x00; + } + } throw new System.ComponentModel.InvalidEnumArgumentException("Unknown PacketOutgoingType (protocol=" + protocol + ")", (int)packet, typeof(PacketOutgoingType)); } @@ -436,11 +474,14 @@ namespace MinecraftClient.Protocol.Handlers this.currentDimension = readNextInt(packetData); else this.currentDimension = (sbyte)readNextByte(packetData); - readNextByte(packetData); + if (protocolversion < MC114Version) + readNextByte(packetData); // Difficulty - 1.13 and below readNextByte(packetData); readNextString(packetData); + if (protocolversion >= MC114Version) + readNextVarInt(packetData); // View distance - 1.14 and above if (protocolversion >= MC18Version) - readNextBool(packetData); // Reduced debug info - 1.8 and above + readNextBool(packetData); // Reduced debug info - 1.8 and above break; case PacketIncomingType.ChatMessage: string message = readNextString(packetData); @@ -457,7 +498,8 @@ namespace MinecraftClient.Protocol.Handlers break; case PacketIncomingType.Respawn: this.currentDimension = readNextInt(packetData); - readNextByte(packetData); + if (protocolversion < MC114Version) + readNextByte(packetData); // Difficulty - 1.13 and below readNextByte(packetData); readNextString(packetData); handler.OnRespawn(); @@ -509,6 +551,10 @@ namespace MinecraftClient.Protocol.Handlers } else { + //TODO skip NBT Heightmaps field for 1.14 + //if (protocolversion >= MC114Version) + // readNextNBT(packetData); + //TODO update Material.cs for 1.14 int dataSize = readNextVarInt(packetData); ProcessChunkColumnData(chunkX, chunkZ, chunkMask, 0, false, chunksContinuous, packetData); } @@ -561,7 +607,7 @@ namespace MinecraftClient.Protocol.Handlers byte blockMeta = readNextByte(packetData); handler.GetWorld().SetBlock(new Location(blockX, blockY, blockZ), new Block(blockId, blockMeta)); } - else handler.GetWorld().SetBlock(Location.FromLong(readNextULong(packetData)), new Block((ushort)readNextVarInt(packetData))); + else handler.GetWorld().SetBlock(readNextLocation(packetData), new Block((ushort)readNextVarInt(packetData))); } break; case PacketIncomingType.MapChunkBulk: @@ -1218,6 +1264,35 @@ namespace MinecraftClient.Protocol.Handlers return BitConverter.ToUInt64(rawValue, 0); } + /// + /// Read a Location encoded as an ulong field and remove it from the cache + /// + /// The Location value + private Location readNextLocation(List cache) + { + ulong locEncoded = readNextULong(cache); + int x, y, z; + if (protocolversion >= MC114Version) + { + x = (int)(locEncoded >> 38); + y = (int)(locEncoded & 0xFFF); + z = (int)(locEncoded << 26 >> 38); + } + else + { + x = (int)(locEncoded >> 38); + y = (int)((locEncoded >> 26) & 0xFFF); + z = (int)(locEncoded << 38 >> 38); + } + if (x >= 33554432) + x -= 67108864; + if (y >= 2048) + y -= 4096; + if (z >= 33554432) + z -= 67108864; + return new Location(x, y, z); + } + /// /// Read several little endian unsigned short integers at once from a cache of bytes and remove them from the cache /// @@ -1462,6 +1537,25 @@ namespace MinecraftClient.Protocol.Handlers return concatBytes(getVarInt(bytes.Length), bytes); } + /// + /// Get a byte array representing the given location encoded as an unsigned short + /// + /// + /// A modulo will be applied if the location is outside the following ranges: + /// X: -33,554,432 to +33,554,431 + /// Y: -2,048 to +2,047 + /// Z: -33,554,432 to +33,554,431 + /// + /// Location representation as ulong + private byte[] GetLocation(Location location) + { + if (protocolversion >= MC114Version) + { + return BitConverter.GetBytes(((((ulong)location.X) & 0x3FFFFFF) << 38) | ((((ulong)location.Z) & 0x3FFFFFF) << 12) | (((ulong)location.Y) & 0xFFF)); + } + else return BitConverter.GetBytes(((((ulong)location.X) & 0x3FFFFFF) << 38) | ((((ulong)location.Y) & 0xFFF) << 26) | (((ulong)location.Z) & 0x3FFFFFF)); + } + /// /// Easily append several byte arrays /// diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index 06a5c8e0..16480a92 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -111,7 +111,7 @@ namespace MinecraftClient.Protocol int[] supportedVersions_Protocol16 = { 51, 60, 61, 72, 73, 74, 78 }; if (Array.IndexOf(supportedVersions_Protocol16, ProtocolVersion) > -1) return new Protocol16Handler(Client, ProtocolVersion, Handler); - int[] supportedVersions_Protocol18 = { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404 }; + int[] supportedVersions_Protocol18 = { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477 }; if (Array.IndexOf(supportedVersions_Protocol18, ProtocolVersion) > -1) return new Protocol18Handler(Client, ProtocolVersion, Handler, forgeInfo); throw new NotSupportedException("The protocol version no." + ProtocolVersion + " is not supported."); @@ -200,6 +200,9 @@ namespace MinecraftClient.Protocol return 401; case "1.13.2": return 404; + case "1.14": + case "1.14.0": + return 477; default: return 0; }