From af1485c75309fb15f028e5d0ea8f9ce05cf02cb3 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Wed, 24 Aug 2022 12:37:22 +0800 Subject: [PATCH 01/20] login support --- MinecraftClient/McClient.cs | 8 +- MinecraftClient/Program.cs | 2 +- .../PacketPalettes/PacketPalette1192.cs | 184 ++++++++++++++++++ .../Protocol/Handlers/PacketType18Handler.cs | 6 +- .../Protocol/Handlers/PacketTypesIn.cs | 7 +- .../Protocol/Handlers/PacketTypesOut.cs | 3 + .../Protocol/Handlers/Protocol18.cs | 33 +++- MinecraftClient/Protocol/IMinecraftCom.cs | 2 +- .../Protocol/ProfileKey/PlayerKeyPair.cs | 5 +- .../Protocol/ProfileKey/PublicKey.cs | 7 +- MinecraftClient/Protocol/ProtocolHandler.cs | 6 +- 11 files changed, 247 insertions(+), 16 deletions(-) create mode 100644 MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1192.cs diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index abc001e8..4309c1ba 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -70,7 +70,7 @@ namespace MinecraftClient private string username; private string uuid; private string sessionid; - private PlayerKeyPair playerKeyPair; + private PlayerKeyPair? playerKeyPair; private DateTime lastKeepAlive; private object lastKeepAliveLock = new(); private int respawnTicks = 0; @@ -141,7 +141,7 @@ namespace MinecraftClient /// The server IP /// The server port to use /// Minecraft protocol version to use - public McClient(string username, string uuid, string sessionID, PlayerKeyPair playerKeyPair, int protocolversion, ForgeInfo forgeInfo, string server_ip, ushort port) + public McClient(string username, string uuid, string sessionID, PlayerKeyPair? playerKeyPair, int protocolversion, ForgeInfo forgeInfo, string server_ip, ushort port) { StartClient(username, uuid, sessionID, playerKeyPair, server_ip, port, protocolversion, forgeInfo, false, ""); } @@ -156,7 +156,7 @@ namespace MinecraftClient /// The server port to use /// Minecraft protocol version to use /// The text or command to send. - public McClient(string username, string uuid, string sessionID, PlayerKeyPair playerKeyPair, string server_ip, ushort port, int protocolversion, ForgeInfo forgeInfo, string command) + public McClient(string username, string uuid, string sessionID, PlayerKeyPair? playerKeyPair, string server_ip, ushort port, int protocolversion, ForgeInfo forgeInfo, string command) { StartClient(username, uuid, sessionID, playerKeyPair, server_ip, port, protocolversion, forgeInfo, true, command); } @@ -172,7 +172,7 @@ namespace MinecraftClient /// The player's UUID for online-mode authentication /// If set to true, the client will send a single command and then disconnect from the server /// The text or command to send. Will only be sent if singlecommand is set to true. - private void StartClient(string user, string uuid, string sessionID, PlayerKeyPair playerKeyPair, string server_ip, ushort port, int protocolversion, ForgeInfo forgeInfo, bool singlecommand, string command) + private void StartClient(string user, string uuid, string sessionID, PlayerKeyPair? playerKeyPair, string server_ip, ushort port, int protocolversion, ForgeInfo forgeInfo, bool singlecommand, string command) { terrainAndMovementsEnabled = Settings.TerrainAndMovements; inventoryHandlingEnabled = Settings.InventoryHandling; diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 334de9bc..37df416c 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -40,7 +40,7 @@ namespace MinecraftClient public const string Version = MCHighestVersion; public const string MCLowestVersion = "1.4.6"; - public const string MCHighestVersion = "1.19"; + public const string MCHighestVersion = "1.19.2"; public static readonly string BuildInfo = null; private static Tuple? offlinePrompt = null; diff --git a/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1192.cs b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1192.cs new file mode 100644 index 00000000..619f87e7 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1192.cs @@ -0,0 +1,184 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Protocol.Handlers.PacketPalettes +{ + public class PacketPalette1192 : PacketTypePalette + { + private Dictionary typeIn = new Dictionary() + { + { 0x00, PacketTypesIn.SpawnEntity }, // Changed in 1.19 (Wiki name: Spawn Entity) - DONE + { 0x01, PacketTypesIn.SpawnExperienceOrb }, //(Wiki name: Spawn Exeprience Orb) + { 0x02, PacketTypesIn.SpawnPlayer }, + { 0x03, PacketTypesIn.EntityAnimation }, //(Wiki name: Entity Animation (clientbound)) + { 0x04, PacketTypesIn.Statistics }, //(Wiki name: Award Statistics) + { 0x05, PacketTypesIn.BlockChangedAck }, //Added 1.19 (Wiki name: Acknowledge Block Change) - DONE + { 0x06, PacketTypesIn.BlockBreakAnimation }, //(Wiki name: Set Block Destroy Stage) + { 0x07, PacketTypesIn.BlockEntityData }, + { 0x08, PacketTypesIn.BlockAction }, + { 0x09, PacketTypesIn.BlockChange }, //(Wiki name: Block Update) + { 0x0A, PacketTypesIn.BossBar }, + { 0x0B, PacketTypesIn.ServerDifficulty }, // (Wiki name: Change Difficulty) + { 0x0C, PacketTypesIn.ChatPreview }, // Added 1.19 + { 0x0D, PacketTypesIn.ClearTiles }, + { 0x0E, PacketTypesIn.TabComplete }, // (Wiki name: Command Suggestions Response) + { 0x0F, PacketTypesIn.DeclareCommands }, // (Wiki name: Commands) + { 0x10, PacketTypesIn.CloseWindow }, // (Wiki name: Close Container (clientbound)) + { 0x11, PacketTypesIn.WindowItems }, // (Wiki name: Set Container Content) + { 0x12, PacketTypesIn.WindowProperty }, // (Wiki name: Set Container Property) + { 0x13, PacketTypesIn.SetSlot }, // (Wiki name: Set Container Slot) + { 0x14, PacketTypesIn.SetCooldown }, + { 0x15, PacketTypesIn.ChatSuggestions }, // Added 1.19.1 + { 0x16, PacketTypesIn.PluginMessage }, // (Wiki name: Plugin Message (clientbound)) + { 0x17, PacketTypesIn.NamedSoundEffect }, // Changed in 1.19 (Added "Speed" field) (Wiki name: Custom Sound Effect) - DONE (No need to be implemented) + { 0x18, PacketTypesIn.HideMessage }, // Added 1.19.1 + { 0x19, PacketTypesIn.Disconnect }, + { 0x1A, PacketTypesIn.EntityStatus }, // (Wiki name: Entity Event) + { 0x1B, PacketTypesIn.Explosion }, // Changed in 1.19 (Location fields are now Double instead of Float) (Wiki name: Explosion) - DONE + { 0x1C, PacketTypesIn.UnloadChunk }, // (Wiki name: Forget Chunk) + { 0x1D, PacketTypesIn.ChangeGameState }, // (Wiki name: Game Event) + { 0x1E, PacketTypesIn.OpenHorseWindow }, // (Wiki name: Horse Screen Open) + { 0x1F, PacketTypesIn.InitializeWorldBorder }, + { 0x20, PacketTypesIn.KeepAlive }, + { 0x21, PacketTypesIn.ChunkData }, + { 0x22, PacketTypesIn.Effect }, // (Wiki name: Level Event) + { 0x23, PacketTypesIn.Particle }, // Changed in 1.19 ("Particle Data" field is now "Max Speed", it's the same Float data type) (Wiki name: Level Particle) - DONE (No need to be implemented) + { 0x24, PacketTypesIn.UpdateLight }, // (Wiki name: Light Update) + { 0x25, PacketTypesIn.JoinGame }, // Changed in 1.19 (lot's of changes) (Wiki name: Login (play)) - DONE + { 0x26, PacketTypesIn.MapData }, // (Wiki name: Map Item Data) + { 0x27, PacketTypesIn.TradeList }, // (Wiki name: Merchant Offers) + { 0x28, PacketTypesIn.EntityPosition }, // (Wiki name: Move Entity Position) + { 0x29, PacketTypesIn.EntityPositionAndRotation }, // (Wiki name: Move Entity Position and Rotation) + { 0x2A, PacketTypesIn.EntityRotation }, // (Wiki name: Move Entity Rotation) + { 0x2B, PacketTypesIn.VehicleMove }, // (Wiki name: Move Vehicle) + { 0x2C, PacketTypesIn.OpenBook }, + { 0x2D, PacketTypesIn.OpenWindow }, // (Wiki name: Open Screen) + { 0x2E, PacketTypesIn.OpenSignEditor }, + { 0x2F, PacketTypesIn.Ping }, // (Wiki name: Ping (play)) + { 0x30, PacketTypesIn.CraftRecipeResponse }, // (Wiki name: Place Ghost Recipe) + { 0x31, PacketTypesIn.PlayerAbilities }, + { 0x32, PacketTypesIn.MessageHeader }, // Added 1.19.1 + { 0x33, PacketTypesIn.ChatMessage }, // Changed in 1.19 (Completely changed) (Wiki name: Player Chat Message) + { 0x34, PacketTypesIn.EndCombatEvent }, // (Wiki name: Player Combat End) + { 0x35, PacketTypesIn.EnterCombatEvent }, // (Wiki name: Player Combat Enter) + { 0x36, PacketTypesIn.DeathCombatEvent }, // (Wiki name: Player Combat Kill) + { 0x37, PacketTypesIn.PlayerInfo }, // Changed in 1.19 (Heavy changes) - DONE + { 0x38, PacketTypesIn.FacePlayer }, // (Wiki name: Player Look At) + { 0x39, PacketTypesIn.PlayerPositionAndLook }, // (Wiki name: Player Position) + { 0x3A, PacketTypesIn.UnlockRecipes }, // (Wiki name: Recipe) + { 0x3B, PacketTypesIn.DestroyEntities }, // (Wiki name: Remove Entites) + { 0x3C, PacketTypesIn.RemoveEntityEffect }, + { 0x3D, PacketTypesIn.ResourcePackSend }, // (Wiki name: Resource Pack) + { 0x3E, PacketTypesIn.Respawn }, // Changed in 1.19 (Heavy changes) - DONE + { 0x3F, PacketTypesIn.EntityHeadLook }, // (Wiki name: Rotate Head) + { 0x40, PacketTypesIn.MultiBlockChange }, // (Wiki name: Sections Block Update) + { 0x41, PacketTypesIn.SelectAdvancementTab }, + { 0x42, PacketTypesIn.ServerData }, // Added in 1.19 + { 0x43, PacketTypesIn.ActionBar }, // (Wiki name: Set Action Bar Text) + { 0x44, PacketTypesIn.WorldBorderCenter }, // (Wiki name: Set Border Center) + { 0x45, PacketTypesIn.WorldBorderLerpSize }, + { 0x46, PacketTypesIn.WorldBorderSize }, // (Wiki name: Set World Border Size) + { 0x47, PacketTypesIn.WorldBorderWarningDelay }, // (Wiki name: Set World Border Warning Delay) + { 0x48, PacketTypesIn.WorldBorderWarningReach }, // (Wiki name: Set Border Warning Distance) + { 0x49, PacketTypesIn.Camera }, // (Wiki name: Set Camera) + { 0x4A, PacketTypesIn.HeldItemChange }, // (Wiki name: Set Carried Item (clientbound)) + { 0x4B, PacketTypesIn.UpdateViewPosition }, // (Wiki name: Set Chunk Cache Center) + { 0x4C, PacketTypesIn.UpdateViewDistance }, // (Wiki name: Set Chunk Cache Radius) + { 0x4D, PacketTypesIn.SpawnPosition }, // (Wiki name: Set Default Spawn Position) + { 0x4E, PacketTypesIn.SetDisplayChatPreview }, // Added in 1.19 (Wiki name: Set Display Chat Preview) + { 0x4F, PacketTypesIn.DisplayScoreboard }, // (Wiki name: Set Display Objective) + { 0x50, PacketTypesIn.EntityMetadata }, // (Wiki name: Set Entity Metadata) + { 0x51, PacketTypesIn.AttachEntity }, // (Wiki name: Set Entity Link) + { 0x52, PacketTypesIn.EntityVelocity }, // (Wiki name: Set Entity Motion) + { 0x53, PacketTypesIn.EntityEquipment }, // (Wiki name: Set Equipment) + { 0x54, PacketTypesIn.SetExperience }, + { 0x55, PacketTypesIn.UpdateHealth }, // (Wiki name: Set Health) + { 0x56, PacketTypesIn.ScoreboardObjective }, // (Wiki name: Set Objective) + { 0x57, PacketTypesIn.SetPassengers }, + { 0x58, PacketTypesIn.Teams }, // (Wiki name: Set Player Team) + { 0x59, PacketTypesIn.UpdateScore }, // (Wiki name: Set Score) + { 0x5A, PacketTypesIn.UpdateSimulationDistance }, // (Wiki name: Set Simulation Distance) + { 0x5B, PacketTypesIn.SetTitleSubTitle }, // (Wiki name: Set Subtitle Test) + { 0x5C, PacketTypesIn.TimeUpdate }, // (Wiki name: Set Time) + { 0x5D, PacketTypesIn.SetTitleText }, // (Wiki name: Set Title) + { 0x5E, PacketTypesIn.SetTitleTime }, // (Wiki name: Set Titles Animation) + { 0x5F, PacketTypesIn.EntitySoundEffect }, // (Wiki name: Sound Entity) + { 0x60, PacketTypesIn.SoundEffect }, // Changed in 1.19 (Added "Seed" field) (Wiki name: Sound Effect) - DONE (No need to be implemented) + { 0x61, PacketTypesIn.StopSound }, + { 0x62, PacketTypesIn.SystemChat }, // Added in 1.19 (Wiki name: System Chat Message) + { 0x63, PacketTypesIn.PlayerListHeaderAndFooter }, // (Wiki name: Tab List) + { 0x64, PacketTypesIn.NBTQueryResponse }, // (Wiki name: Tab Query) + { 0x65, PacketTypesIn.CollectItem }, // (Wiki name: Take Item Entity) + { 0x66, PacketTypesIn.EntityTeleport }, // (Wiki name: Teleport Entity) + { 0x67, PacketTypesIn.Advancements }, // (Wiki name: Update Advancements) + { 0x68, PacketTypesIn.EntityProperties }, // (Wiki name: Update Attributes) + { 0x69, PacketTypesIn.EntityEffect }, // Changed in 1.19 (Added "Has Factor Data" and "Factor Codec" fields) (Wiki name: Entity Effect) - DONE + { 0x6A, PacketTypesIn.DeclareRecipes }, // (Wiki name: Update Recipes) + { 0x6B, PacketTypesIn.Tags }, // (Wiki name: Update Tags) + }; + + private Dictionary typeOut = new Dictionary() + { + { 0x00, PacketTypesOut.TeleportConfirm }, // (Wiki name: Confirm Teleportation) + { 0x01, PacketTypesOut.QueryBlockNBT }, // (Wiki name: Query Block Entity Tag) + { 0x02, PacketTypesOut.SetDifficulty }, // (Wiki name: Change Difficutly) + { 0x03, PacketTypesOut.MessageAcknowledgment }, // Added in 1.19.1 + { 0x04, PacketTypesOut.ChatCommand }, // Added in 1.19 + { 0x05, PacketTypesOut.ChatMessage }, // Changed in 1.19 (Completely changed) (Wiki name: Chat) + { 0x06, PacketTypesOut.ChatPreview }, // Added in 1.19 (Wiki name: Chat Preview (serverbound)) + { 0x07, PacketTypesOut.ClientStatus }, // (Wiki name: Client Command) + { 0x08, PacketTypesOut.ClientSettings }, // (Wiki name: Client Information) + { 0x09, PacketTypesOut.TabComplete }, // (Wiki name: Command Suggestions Request) + { 0x0A, PacketTypesOut.ClickWindowButton }, // (Wiki name: Click Container Button) + { 0x0B, PacketTypesOut.ClickWindow }, // (Wiki name: Click Container) + { 0x0C, PacketTypesOut.CloseWindow }, // (Wiki name: Close Container (serverbound)) + { 0x0D, PacketTypesOut.PluginMessage }, // (Wiki name: Plugin Message (serverbound)) + { 0x0E, PacketTypesOut.EditBook }, + { 0x0F, PacketTypesOut.EntityNBTRequest }, // (Wiki name: Query Entity Tag) + { 0x10, PacketTypesOut.InteractEntity }, // (Wiki name: Interact) + { 0x11, PacketTypesOut.GenerateStructure }, // (Wiki name: Jigsaw Generate) + { 0x12, PacketTypesOut.KeepAlive }, + { 0x13, PacketTypesOut.LockDifficulty }, + { 0x14, PacketTypesOut.PlayerPosition }, // (Wiki name: Move Player Position) + { 0x15, PacketTypesOut.PlayerPositionAndRotation }, // (Wiki name: Set Player Position and Rotation) + { 0x16, PacketTypesOut.PlayerRotation }, // (Wiki name: Set Player Rotation) + { 0x17, PacketTypesOut.PlayerMovement }, // (Wiki name: Set Player On Ground) + { 0x18, PacketTypesOut.VehicleMove }, // (Wiki name: Move Vehicle (serverbound)) + { 0x19, PacketTypesOut.SteerBoat }, // (Wiki name: Paddle Boat) + { 0x1A, PacketTypesOut.PickItem }, + { 0x1B, PacketTypesOut.CraftRecipeRequest }, // (Wiki name: Place recipe) + { 0x1C, PacketTypesOut.PlayerAbilities }, + { 0x1D, PacketTypesOut.PlayerDigging }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Player Action) - DONE + { 0x1E, PacketTypesOut.EntityAction }, // (Wiki name: Player Command) + { 0x1F, PacketTypesOut.SteerVehicle }, // (Wiki name: Player Input) + { 0x20, PacketTypesOut.Pong }, // (Wiki name: Pong (play)) + { 0x21, PacketTypesOut.SetDisplayedRecipe }, // (Wiki name: Recipe Book Change Settings) + { 0x22, PacketTypesOut.SetRecipeBookState }, // (Wiki name: Recipe Book Seen Recipe) + { 0x23, PacketTypesOut.NameItem }, // (Wiki name: Rename Item) + { 0x24, PacketTypesOut.ResourcePackStatus }, // (Wiki name: Resource Pack (serverbound)) + { 0x25, PacketTypesOut.AdvancementTab }, // (Wiki name: Seen Advancements) + { 0x26, PacketTypesOut.SelectTrade }, + { 0x27, PacketTypesOut.SetBeaconEffect }, // Changed in 1.19 (Added a "Secondary Effect Present" and "Secondary Effect" fields) (Wiki name: Set Beacon) - DONE - (No need to be implemented) + { 0x28, PacketTypesOut.HeldItemChange }, // (Wiki name: Set Carried Item (serverbound)) + { 0x29, PacketTypesOut.UpdateCommandBlock }, // (Wiki name: Set Command Block) + { 0x2A, PacketTypesOut.UpdateCommandBlockMinecart }, + { 0x2B, PacketTypesOut.CreativeInventoryAction }, // (Wiki name: Set Creative Mode Slot) + { 0x2C, PacketTypesOut.UpdateJigsawBlock }, // (Wiki name: Set Jigsaw Block) + { 0x2D, PacketTypesOut.UpdateStructureBlock }, // (Wiki name: Set Structure Block) + { 0x2E, PacketTypesOut.UpdateSign }, // (Wiki name: Sign Update) + { 0x2F, PacketTypesOut.Animation }, // (Wiki name: Swing) + { 0x30, PacketTypesOut.Spectate }, // (Wiki name: Teleport To Entity) + { 0x31, PacketTypesOut.PlayerBlockPlacement }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item On) - DONE + { 0x32, PacketTypesOut.UseItem }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item) - DONE + }; + + protected override Dictionary GetListIn() + { + return typeIn; + } + + protected override Dictionary GetListOut() + { + return typeOut; + } + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs index 9218ada8..b086e747 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -51,7 +51,7 @@ namespace MinecraftClient.Protocol.Handlers public PacketTypePalette GetTypeHandler(int protocol) { PacketTypePalette p; - if (protocol > Protocol18Handler.MC_1_19_Version) + if (protocol > Protocol18Handler.MC_1_19_2_Version) throw new NotImplementedException(Translations.Get("exception.palette.packet")); if (protocol <= Protocol18Handler.MC_1_8_Version) p = new PacketPalette17(); @@ -75,8 +75,10 @@ namespace MinecraftClient.Protocol.Handlers p = new PacketPalette117(); else if (protocol <= Protocol18Handler.MC_1_18_2_Version) p = new PacketPalette118(); - else + else if (protocol <= Protocol18Handler.MC_1_19_Version) p = new PacketPalette119(); + else + p = new PacketPalette1192(); p.SetForgeEnabled(this.forgeEnabled); return p; diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs index 9001e0eb..9d6eda02 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs @@ -132,6 +132,11 @@ namespace MinecraftClient.Protocol.Handlers ChatPreview, ServerData, SetDisplayChatPreview, - SystemChat + SystemChat, + + // Added in 1.19.1 (1.19.2) + ChatSuggestions, + HideMessage, + MessageHeader } } diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs index e65c6d90..0cd4b85f 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs @@ -67,5 +67,8 @@ namespace MinecraftClient.Protocol.Handlers // Added in 1.19 ChatCommand, ChatPreview, + + // Added in 1.19.1 (1.19.2) + MessageAcknowledgment } } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index ecb3dfed..ca42bad5 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -55,6 +55,7 @@ namespace MinecraftClient.Protocol.Handlers internal const int MC_1_18_1_Version = 757; internal const int MC_1_18_2_Version = 758; internal const int MC_1_19_Version = 759; + internal const int MC_1_19_2_Version = 760; private int compression_treshold = 0; private bool autocomplete_received = false; @@ -414,7 +415,7 @@ namespace MinecraftClient.Protocol.Handlers handler.OnTextReceived(new(message, true, messageType, senderUUID)); } - else // 1.19+ + else if (protocolversion == MC_1_19_Version) // 1.19 { string signedChat = dataTypes.ReadNextString(packetData); @@ -443,6 +444,10 @@ namespace MinecraftClient.Protocol.Handlers handler.OnTextReceived(new(signedChat, true, messageType, senderUUID, unsignedChatContent, senderDisplayName, senderTeamName, timestamp, verifyResult)); } + else // 1.19.1 + + { + // Todo + } break; case PacketTypesIn.Respawn: string? dimensionNameInRespawn = null; @@ -1533,7 +1538,21 @@ namespace MinecraftClient.Protocol.Handlers fullLoginPacket.AddRange(dataTypes.GetBool(true)); // Has Sig Data fullLoginPacket.AddRange(dataTypes.GetLong(playerKeyPair.GetExpirationMilliseconds())); // Expiration time fullLoginPacket.AddRange(dataTypes.GetArray(playerKeyPair.PublicKey.Key)); // Public key received from Microsoft API - fullLoginPacket.AddRange(dataTypes.GetArray(playerKeyPair.PublicKey.Signature)); // Public key signature received from Microsoft API + if (protocolversion >= MC_1_19_2_Version) + fullLoginPacket.AddRange(dataTypes.GetArray(playerKeyPair.PublicKey.SignatureV2!)); // Public key signature received from Microsoft API + else + fullLoginPacket.AddRange(dataTypes.GetArray(playerKeyPair.PublicKey.Signature!)); // Public key signature received from Microsoft API + } + } + if (protocolversion >= MC_1_19_2_Version) + { + string uuid = handler.GetUserUUID(); + if (uuid == "0") + fullLoginPacket.AddRange(dataTypes.GetBool(false)); // Has UUID + else + { + fullLoginPacket.AddRange(dataTypes.GetBool(true)); // Has UUID + fullLoginPacket.AddRange(dataTypes.GetUUID(Guid.Parse(uuid))); // UUID } } SendPacket(0x00, fullLoginPacket); @@ -1952,6 +1971,13 @@ namespace MinecraftClient.Protocol.Handlers if (String.IsNullOrEmpty(message)) return true; + if (protocolversion >= MC_1_19_2_Version) + { + // Todo + log.Warn("Not implement"); + return false; + } + // Process Chat Command - 1.19 and above if (protocolversion >= MC_1_19_Version && message.StartsWith('/')) return SendChatCommand(message[1..], playerKeyPair); @@ -1989,6 +2015,9 @@ namespace MinecraftClient.Protocol.Handlers // Signed Preview: Boolean fields.AddRange(dataTypes.GetBool(false)); + + fields.AddRange(dataTypes.GetVarInt(0)); + fields.AddRange(dataTypes.GetBool(false)); } SendPacket(PacketTypesOut.ChatMessage, fields); return true; diff --git a/MinecraftClient/Protocol/IMinecraftCom.cs b/MinecraftClient/Protocol/IMinecraftCom.cs index a7c36b5b..1fb3db9d 100644 --- a/MinecraftClient/Protocol/IMinecraftCom.cs +++ b/MinecraftClient/Protocol/IMinecraftCom.cs @@ -22,7 +22,7 @@ namespace MinecraftClient.Protocol /// Start the login procedure once connected to the server /// /// True if login was successful - bool Login(PlayerKeyPair playerKeyPair); + bool Login(PlayerKeyPair? playerKeyPair); /// /// Disconnect from the server diff --git a/MinecraftClient/Protocol/ProfileKey/PlayerKeyPair.cs b/MinecraftClient/Protocol/ProfileKey/PlayerKeyPair.cs index 6f6bf824..d5468bb2 100644 --- a/MinecraftClient/Protocol/ProfileKey/PlayerKeyPair.cs +++ b/MinecraftClient/Protocol/ProfileKey/PlayerKeyPair.cs @@ -65,7 +65,10 @@ namespace MinecraftClient.Protocol.Keys { List datas = new List(); datas.Add(Convert.ToBase64String(PublicKey.Key)); - datas.Add(Convert.ToBase64String(PublicKey.Signature)); + if (PublicKey.Signature == null) + datas.Add(String.Empty); + else + datas.Add(Convert.ToBase64String(PublicKey.Signature)); if (PublicKey.SignatureV2 == null) datas.Add(String.Empty); else diff --git a/MinecraftClient/Protocol/ProfileKey/PublicKey.cs b/MinecraftClient/Protocol/ProfileKey/PublicKey.cs index 763fc569..f0a2cdd8 100644 --- a/MinecraftClient/Protocol/ProfileKey/PublicKey.cs +++ b/MinecraftClient/Protocol/ProfileKey/PublicKey.cs @@ -10,19 +10,20 @@ namespace MinecraftClient.Protocol.Keys public class PublicKey { public byte[] Key { get; set; } - public byte[] Signature { get; set; } + public byte[]? Signature { get; set; } public byte[]? SignatureV2 { get; set; } private readonly RSA rsa; - public PublicKey(string pemKey, string sig, string? sigV2 = null) + public PublicKey(string pemKey, string? sig = null, string? sigV2 = null) { this.Key = KeyUtils.DecodePemKey(pemKey, "-----BEGIN RSA PUBLIC KEY-----", "-----END RSA PUBLIC KEY-----"); this.rsa = RSA.Create(); rsa.ImportSubjectPublicKeyInfo(this.Key, out _); - this.Signature = Convert.FromBase64String(sig); + if (!string.IsNullOrEmpty(sig)) + this.Signature = Convert.FromBase64String(sig); if (!string.IsNullOrEmpty(sigV2)) this.SignatureV2 = Convert.FromBase64String(sigV2!); diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index b03df4ce..eedf2002 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -131,7 +131,7 @@ namespace MinecraftClient.Protocol 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, 477, 480, 485, 490, 498, 573, 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759 }; + int[] supportedVersions_Protocol18 = { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477, 480, 485, 490, 498, 573, 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760 }; if (Array.IndexOf(supportedVersions_Protocol18, ProtocolVersion) > -1) return new Protocol18Handler(Client, ProtocolVersion, Handler, forgeInfo); @@ -263,6 +263,9 @@ namespace MinecraftClient.Protocol return 758; case "1.19": return 759; + case "1.19.1": + case "1.19.2": + return 760; default: return 0; } @@ -329,6 +332,7 @@ namespace MinecraftClient.Protocol case 757: return "1.18.1"; case 758: return "1.18.2"; case 759: return "1.19"; + case 760: return "1.19.2"; default: return "0.0"; } } From c34dd460672b505aeaf96fc8fb93c8575073c650 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 27 Aug 2022 02:10:44 +0800 Subject: [PATCH 02/20] Basic support for 1.19.2 --- MinecraftClient/McClient.cs | 35 +-- .../Protocol/Handlers/DataTypes.cs | 46 +++- .../Protocol/Handlers/PacketType18Handler.cs | 1 + .../Protocol/Handlers/Protocol16.cs | 3 +- .../Protocol/Handlers/Protocol18.cs | 244 +++++++++++++++--- .../Protocol/IMinecraftComHandler.cs | 4 +- .../Protocol/{ => Message}/ChatMessage.cs | 31 ++- .../Protocol/{ => Message}/ChatParser.cs | 119 +++++---- .../Protocol/Message/LastSeenMessageList.cs | 117 +++++++++ MinecraftClient/Protocol/PlayerInfo.cs | 96 ++++++- .../Protocol/ProfileKey/KeyUtils.cs | 55 +++- .../Protocol/ProfileKey/PrivateKey.cs | 35 ++- .../Protocol/ProfileKey/PublicKey.cs | 44 +++- MinecraftClient/Scripting/ChatBot.cs | 2 +- 14 files changed, 703 insertions(+), 129 deletions(-) rename MinecraftClient/Protocol/{ => Message}/ChatMessage.cs (69%) rename MinecraftClient/Protocol/{ => Message}/ChatParser.cs (82%) create mode 100644 MinecraftClient/Protocol/Message/LastSeenMessageList.cs diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index 4309c1ba..cb779ccf 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -14,6 +14,7 @@ using MinecraftClient.Mapping; using MinecraftClient.Inventory; using MinecraftClient.Logger; using MinecraftClient.Protocol.Keys; +using MinecraftClient.Protocol.Message; namespace MinecraftClient { @@ -68,7 +69,8 @@ namespace MinecraftClient private int port; private int protocolversion; private string username; - private string uuid; + private Guid uuid; + private string uuidStr; private string sessionid; private PlayerKeyPair? playerKeyPair; private DateTime lastKeepAlive; @@ -104,7 +106,8 @@ namespace MinecraftClient public int GetServerPort() { return port; } public string GetServerHost() { return host; } public string GetUsername() { return username; } - public string GetUserUUID() { return uuid; } + public Guid GetUserUuid() { return uuid; } + public string GetUserUuidStr() { return uuidStr; } public string GetSessionID() { return sessionid; } public Location GetCurrentLocation() { return location; } public float GetYaw() { return playerYaw; } @@ -180,7 +183,8 @@ namespace MinecraftClient bool retry = false; this.sessionid = sessionID; - this.uuid = uuid; + this.uuid = new Guid(uuid); + this.uuidStr = uuid; this.username = user; this.host = server_ip; this.port = port; @@ -2093,20 +2097,18 @@ namespace MinecraftClient List links = new(); string messageText; - if (message.isJson) + if (message.isSignedChat) { - if (message.isSignedChat) - { - if (!Settings.ShowIllegalSignedChat && !message.isSystemChat && !(bool)message.isSignatureLegal!) - return; - messageText = ChatParser.ParseSignedChat(message, links); - } - else - messageText = ChatParser.ParseText(message.content, links); + if (!Settings.ShowIllegalSignedChat && !message.isSystemChat && !(bool)message.isSignatureLegal!) + return; + messageText = ChatParser.ParseSignedChat(message, links); } else { - messageText = message.content; + if (message.isJson) + messageText = ChatParser.ParseText(message.content, links); + else + messageText = message.content; } Log.Chat(messageText); @@ -2243,15 +2245,16 @@ namespace MinecraftClient if (player.Name == username) { // 1.19+ offline server is possible to return different uuid - this.uuid = player.UUID.ToString().Replace("-", string.Empty); + this.uuid = player.Uuid; + this.uuidStr = player.Uuid.ToString().Replace("-", string.Empty); } lock (onlinePlayers) { - onlinePlayers[player.UUID] = player; + onlinePlayers[player.Uuid] = player; } - DispatchBotEvent(bot => bot.OnPlayerJoin(player.UUID, player.Name)); + DispatchBotEvent(bot => bot.OnPlayerJoin(player.Uuid, player.Name)); } /// diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index 624924ab..6907484e 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -1103,9 +1103,51 @@ namespace MinecraftClient.Protocol.Handlers /// /// Byte array /// String representation - public string ByteArrayToString(byte[] bytes) + public string ByteArrayToString(byte[]? bytes) { - return BitConverter.ToString(bytes).Replace("-", " "); + if (bytes == null) + return "null"; + else + return BitConverter.ToString(bytes).Replace("-", " "); + } + + /// + /// Write LastSeenMessageList + /// + /// Message.LastSeenMessageList + /// Message.LastSeenMessageList Packet Data + public byte[] GetLastSeenMessageList(Message.LastSeenMessageList msgList) + { + List fields = new List(); + fields.AddRange(GetVarInt(msgList.entries.Length)); + foreach (Message.LastSeenMessageList.Entry entry in msgList.entries) + { + fields.AddRange(entry.profileId.ToBigEndianBytes()); + fields.AddRange(GetVarInt(entry.lastSignature.Length)); + fields.AddRange(entry.lastSignature); + } + return fields.ToArray(); + } + + /// + /// Write LastSeenMessageList.Acknowledgment + /// + /// Acknowledgment + /// Acknowledgment Packet Data + public byte[] GetAcknowledgment(Message.LastSeenMessageList.Acknowledgment ack) + { + List fields = new List(); + fields.AddRange(GetLastSeenMessageList(ack.lastSeen)); + if (ack.lastReceived == null) + fields.AddRange(GetBool(false)); + else + { + fields.AddRange(GetBool(true)); + fields.AddRange(ack.lastReceived.profileId.ToBigEndianBytes()); + fields.AddRange(GetVarInt(ack.lastReceived.lastSignature.Length)); + fields.AddRange(ack.lastReceived.lastSignature); + } + return fields.ToArray(); } } } diff --git a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs index b086e747..4dff45a9 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -53,6 +53,7 @@ namespace MinecraftClient.Protocol.Handlers PacketTypePalette p; if (protocol > Protocol18Handler.MC_1_19_2_Version) throw new NotImplementedException(Translations.Get("exception.palette.packet")); + if (protocol <= Protocol18Handler.MC_1_8_Version) p = new PacketPalette17(); else if (protocol <= Protocol18Handler.MC_1_11_2_Version) diff --git a/MinecraftClient/Protocol/Handlers/Protocol16.cs b/MinecraftClient/Protocol/Handlers/Protocol16.cs index f691a2be..957e5d9e 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol16.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs @@ -10,6 +10,7 @@ using System.Security.Cryptography; using MinecraftClient.Mapping; using MinecraftClient.Inventory; using MinecraftClient.Protocol.Keys; +using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol.Handlers { @@ -559,7 +560,7 @@ namespace MinecraftClient.Protocol.Handlers public bool Login(PlayerKeyPair playerKeyPair) { - if (Handshake(handler.GetUserUUID(), handler.GetUsername(), handler.GetSessionID(), handler.GetServerHost(), handler.GetServerPort())) + if (Handshake(handler.GetUserUuidStr(), handler.GetUsername(), handler.GetSessionID(), handler.GetServerHost(), handler.GetServerPort())) { Send(new byte[] { 0xCD, 0 }); try diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index ca42bad5..64bdec30 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -19,6 +19,7 @@ using MinecraftClient.Logger; using System.Threading.Tasks; using MinecraftClient.Protocol.Keys; using System.Text.RegularExpressions; +using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol.Handlers { @@ -66,6 +67,10 @@ namespace MinecraftClient.Protocol.Handlers private int protocolversion; private int currentDimension; + private int pendingAcknowledgments = 0; + private LastSeenMessagesCollector lastSeenMessagesCollector = new(5); + private LastSeenMessageList.Entry? lastReceivedMessage = null; + Protocol18Forge pForge; Protocol18Terrain pTerrain; IMinecraftComHandler handler; @@ -163,6 +168,36 @@ namespace MinecraftClient.Protocol.Handlers else itemPalette = new ItemPalette1161(); } else itemPalette = new ItemPalette115(); + + // MessageType + // You can find it in https://wiki.vg/Protocol#Player_Chat_Message or /net/minecraft/network/message/MessageType.java + if (protocolversion >= MC_1_19_2_Version) + { + ChatParser.ChatId2Type = new() + { + { 0, ChatParser.MessageType.CHAT }, + { 1, ChatParser.MessageType.SAY_COMMAND }, + { 2, ChatParser.MessageType.MSG_COMMAND_INCOMING }, + { 3, ChatParser.MessageType.MSG_COMMAND_OUTGOING }, + { 4, ChatParser.MessageType.TEAM_MSG_COMMAND_INCOMING }, + { 5, ChatParser.MessageType.TEAM_MSG_COMMAND_OUTGOING }, + { 6, ChatParser.MessageType.EMOTE_COMMAND }, + }; + } + else if (protocolversion >= MC_1_19_Version) + { + ChatParser.ChatId2Type = new() + { + { 0, ChatParser.MessageType.CHAT }, + { 1, ChatParser.MessageType.RAW_MSG }, + { 2, ChatParser.MessageType.RAW_MSG }, + { 3, ChatParser.MessageType.SAY_COMMAND }, + { 4, ChatParser.MessageType.MSG_COMMAND_INCOMING }, + { 5, ChatParser.MessageType.TEAM_MSG_COMMAND_INCOMING }, + { 6, ChatParser.MessageType.EMOTE_COMMAND }, + { 7, ChatParser.MessageType.RAW_MSG }, + }; + } } /// @@ -439,14 +474,104 @@ namespace MinecraftClient.Protocol.Handlers byte[] messageSignature = dataTypes.ReadNextByteArray(packetData); - PlayerInfo? player = handler.GetPlayerInfo(senderUUID); - bool verifyResult = player == null ? false : player.VerifyMessage(signedChat, senderUUID, timestamp, salt, ref messageSignature); + bool verifyResult; + if (senderUUID.ToString().Replace("-", String.Empty) == handler.GetUserUuidStr()) + verifyResult = true; + else + { + PlayerInfo? player = handler.GetPlayerInfo(senderUUID); + verifyResult = player == null ? false : player.VerifyMessage(signedChat, timestamp, salt, ref messageSignature); + } - handler.OnTextReceived(new(signedChat, true, messageType, senderUUID, unsignedChatContent, senderDisplayName, senderTeamName, timestamp, verifyResult)); + handler.OnTextReceived(new(signedChat, true, messageType, senderUUID, unsignedChatContent, senderDisplayName, senderTeamName, timestamp, messageSignature, verifyResult)); } else // 1.19.1 + { - // Todo + byte[]? precedingSignature = dataTypes.ReadNextBool(packetData) ? dataTypes.ReadNextByteArray(packetData) : null; + Guid senderUUID = dataTypes.ReadNextUUID(packetData); + byte[] headerSignature = dataTypes.ReadNextByteArray(packetData); + + string signedChat = dataTypes.ReadNextString(packetData); + string? decorated = dataTypes.ReadNextBool(packetData) ? dataTypes.ReadNextString(packetData) : null; + + long timestamp = dataTypes.ReadNextLong(packetData); + long salt = dataTypes.ReadNextLong(packetData); + + int lastSeenMessageListLen = dataTypes.ReadNextVarInt(packetData); + LastSeenMessageList.Entry[] lastSeenMessageList = new LastSeenMessageList.Entry[lastSeenMessageListLen]; + for (int i = 0; i < lastSeenMessageListLen; ++i) + { + Guid user = dataTypes.ReadNextUUID(packetData); + byte[] lastSignature = dataTypes.ReadNextByteArray(packetData); + lastSeenMessageList[i] = new(user, lastSignature); + } + LastSeenMessageList lastSeenMessages = new(lastSeenMessageList); + + string? unsignedChatContent = dataTypes.ReadNextBool(packetData) ? dataTypes.ReadNextString(packetData) : null; + + int filterEnum = dataTypes.ReadNextVarInt(packetData); + if (filterEnum == 2) // PARTIALLY_FILTERED + dataTypes.ReadNextULongArray(packetData); + + int chatTypeId = dataTypes.ReadNextVarInt(packetData); + string chatName = dataTypes.ReadNextString(packetData); + string? targetName = dataTypes.ReadNextBool(packetData) ? dataTypes.ReadNextString(packetData) : null; + + bool verifyResult; + if (senderUUID.ToString().Replace("-", String.Empty) == handler.GetUserUuidStr()) + verifyResult = true; + else + { + PlayerInfo? player = handler.GetPlayerInfo(senderUUID); + if (player == null) + verifyResult = false; + else + { + bool lastVerifyResult = player.IsMessageChainLegal(); + verifyResult = player.VerifyMessage(signedChat, timestamp, salt, ref headerSignature, ref precedingSignature, lastSeenMessages); + if (lastVerifyResult && !verifyResult) + log.Warn("Player " + player.DisplayName + " message chains broken!"); + } + } + + Dictionary chatInfo = Json.ParseJson(chatName).Properties; + string senderDisplayName = (chatInfo.ContainsKey("insertion") ? chatInfo["insertion"] : chatInfo["text"]).StringValue; + string? senderTeamName = null; + ChatParser.MessageType messageTypeEnum = ChatParser.ChatId2Type![chatTypeId]; + if (targetName != null && + (messageTypeEnum == ChatParser.MessageType.TEAM_MSG_COMMAND_INCOMING || messageTypeEnum == ChatParser.MessageType.TEAM_MSG_COMMAND_OUTGOING)) + senderTeamName = Json.ParseJson(targetName).Properties["with"].DataArray[0].Properties["text"].StringValue; + + ChatMessage chat = new(signedChat, false, chatTypeId, senderUUID, unsignedChatContent, senderDisplayName, senderTeamName, timestamp, headerSignature, verifyResult); + if (!chat.lacksSender()) + this.acknowledge(chat); + handler.OnTextReceived(chat); + } + break; + case PacketTypesIn.MessageHeader: + if (protocolversion >= MC_1_19_2_Version) + { + byte[]? precedingSignature = dataTypes.ReadNextBool(packetData) ? dataTypes.ReadNextByteArray(packetData) : null; + Guid senderUUID = dataTypes.ReadNextUUID(packetData); + byte[] headerSignature = dataTypes.ReadNextByteArray(packetData); + byte[] bodyDigest = dataTypes.ReadNextByteArray(packetData); + + bool verifyResult; + if (senderUUID.ToString().Replace("-", String.Empty) == handler.GetUserUuidStr()) + verifyResult = true; + else + { + PlayerInfo? player = handler.GetPlayerInfo(senderUUID); + if (player == null) + verifyResult = false; + else + { + bool lastVerifyResult = player.IsMessageChainLegal(); + verifyResult = player.VerifyMessageHead(ref precedingSignature, ref headerSignature, ref bodyDigest); + if (lastVerifyResult && !verifyResult) + log.Warn("Player " + player.DisplayName + " message chains broken!"); + } + } } break; case PacketTypesIn.Respawn: @@ -826,6 +951,8 @@ namespace MinecraftClient.Protocol.Handlers //handler.OnTextReceived(message, true); } + break; + case PacketTypesIn.ChatSuggestions: break; case PacketTypesIn.MapChunkBulk: if (protocolversion < MC_1_9_Version && handler.GetTerrainEnabled()) @@ -1546,7 +1673,7 @@ namespace MinecraftClient.Protocol.Handlers } if (protocolversion >= MC_1_19_2_Version) { - string uuid = handler.GetUserUUID(); + string uuid = handler.GetUserUuidStr(); if (uuid == "0") fullLoginPacket.AddRange(dataTypes.GetBool(false)); // Has UUID else @@ -1572,7 +1699,7 @@ namespace MinecraftClient.Protocol.Handlers string serverID = dataTypes.ReadNextString(packetData); byte[] serverPublicKey = dataTypes.ReadNextByteArray(packetData); byte[] token = dataTypes.ReadNextByteArray(packetData); - return StartEncryption(handler.GetUserUUID(), handler.GetSessionID(), token, serverID, serverPublicKey, playerKeyPair); + return StartEncryption(handler.GetUserUuidStr(), handler.GetSessionID(), token, serverID, serverPublicKey, playerKeyPair); } else if (packetID == 0x02) //Login successful { @@ -1854,15 +1981,57 @@ namespace MinecraftClient.Protocol.Handlers return protocolversion; } + /// + /// Send MessageAcknowledgment packet + /// + /// Message acknowledgment + /// True if properly sent + public bool SendMessageAcknowledgment(LastSeenMessageList.Acknowledgment acknowledgment) + { + try + { + byte[] fields = dataTypes.GetAcknowledgment(acknowledgment); + + SendPacket(PacketTypesOut.MessageAcknowledgment, fields); + + return true; + } + catch (SocketException) { return false; } + catch (System.IO.IOException) { return false; } + catch (ObjectDisposedException) { return false; } + } + + public LastSeenMessageList.Acknowledgment consumeAcknowledgment() + { + this.pendingAcknowledgments = 0; + return new LastSeenMessageList.Acknowledgment(this.lastSeenMessagesCollector.GetLastSeenMessages(), this.lastReceivedMessage); + } + + public void acknowledge(ChatMessage message) + { + LastSeenMessageList.Entry? entry = message.toLastSeenMessageEntry(); + + if (entry != null) + { + lastSeenMessagesCollector.Add(entry); + lastReceivedMessage = null; + + if (pendingAcknowledgments++ > 64) + SendMessageAcknowledgment(this.consumeAcknowledgment()); + } + } /// /// The signable argument names and their values from command /// Signature will used in Vanilla's say, me, msg, teammsg, ban, banip, and kick commands. /// https://gist.github.com/kennytv/ed783dd244ca0321bbd882c347892874#signed-command-arguments + /// You can find all the commands that need to be signed by searching for "MessageArgumentType.getSignedMessage" in the source code. + /// Don't forget to handle the redirected commands, e.g. /tm, /w + /// /// /// Command /// List< Argument Name, Argument Value > - private List> collectCommandArguments(string command) + private static List> CollectCommandArguments(string command) { List> needSigned = new(); @@ -1874,21 +2043,25 @@ namespace MinecraftClient.Protocol.Handlers { /* /me /say - /teammsg */ + /teammsg + /tm */ if (argStage1[0] == "me") needSigned.Add(new("action", argStage1[1])); - else if (argStage1[0] == "say" || argStage1[0] == "teammsg") + else if (argStage1[0] == "say" || argStage1[0] == "teammsg" || argStage1[0] == "tm") needSigned.Add(new("message", argStage1[1])); - else if (argStage1[0] == "msg" || argStage1[0] == "ban" || argStage1[0] == "ban-ip" || argStage1[0] == "kick") + else if (argStage1[0] == "msg" || argStage1[0] == "tell" || argStage1[0] == "w" || + argStage1[0] == "ban" || argStage1[0] == "ban-ip" || argStage1[0] == "kick") { /* /msg + /tell + /w /ban [] /ban-ip [] /kick [] */ string[] argStage2 = argStage1[1].Split(' ', 2, StringSplitOptions.None); if (argStage2.Length == 2) { - if (argStage1[0] == "msg") + if (argStage1[0] == "msg" || argStage1[0] == "tell" || argStage1[0] == "w") needSigned.Add(new("message", argStage2[1])); else if (argStage1[0] == "ban" || argStage1[0] == "ban-ip" || argStage1[0] == "kick") needSigned.Add(new("reason", argStage2[1])); @@ -1917,6 +2090,8 @@ namespace MinecraftClient.Protocol.Handlers try { + LastSeenMessageList.Acknowledgment? acknowledgment = (protocolversion >= MC_1_19_2_Version) ? this.consumeAcknowledgment() : null; + List fields = new(); // Command: String @@ -1926,9 +2101,7 @@ namespace MinecraftClient.Protocol.Handlers DateTimeOffset timeNow = DateTimeOffset.UtcNow; fields.AddRange(dataTypes.GetLong(timeNow.ToUnixTimeMilliseconds())); - List> needSigned = collectCommandArguments(command); // List< Argument Name, Argument Value > - // foreach (var msg in needSigned) - // log.Info("<" + msg.Item1 + ">: " + msg.Item2); + List> needSigned = CollectCommandArguments(command); // List< Argument Name, Argument Value > if (needSigned.Count == 0 || playerKeyPair == null || !Settings.SignMessageInCommand) { fields.AddRange(dataTypes.GetLong(0)); // Salt: Long @@ -1936,14 +2109,16 @@ namespace MinecraftClient.Protocol.Handlers } else { - string uuid = handler.GetUserUUID()!; + Guid uuid = handler.GetUserUuid(); byte[] salt = GenerateSalt(); fields.AddRange(salt); // Salt: Long fields.AddRange(dataTypes.GetVarInt(needSigned.Count)); // Signature Length: VarInt foreach (var argument in needSigned) { fields.AddRange(dataTypes.GetString(argument.Item1)); // Argument name: String - byte[] sign = playerKeyPair.PrivateKey.SignMessage(argument.Item2, uuid, timeNow, ref salt); + byte[] sign = (protocolversion >= MC_1_19_2_Version) ? + playerKeyPair.PrivateKey.SignMessage(argument.Item2, uuid, timeNow, ref salt, acknowledgment!.lastSeen) : + playerKeyPair.PrivateKey.SignMessage(argument.Item2, uuid, timeNow, ref salt); fields.AddRange(dataTypes.GetVarInt(sign.Length)); // Signature length: VarInt fields.AddRange(sign); // Signature: Byte Array } @@ -1952,6 +2127,12 @@ namespace MinecraftClient.Protocol.Handlers // Signed Preview: Boolean fields.AddRange(dataTypes.GetBool(false)); + if (protocolversion >= MC_1_19_2_Version) + { + // Message Acknowledgment + fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!)); + } + SendPacket(PacketTypesOut.ChatCommand, fields); return true; } @@ -1971,19 +2152,14 @@ namespace MinecraftClient.Protocol.Handlers if (String.IsNullOrEmpty(message)) return true; - if (protocolversion >= MC_1_19_2_Version) - { - // Todo - log.Warn("Not implement"); - return false; - } - // Process Chat Command - 1.19 and above if (protocolversion >= MC_1_19_Version && message.StartsWith('/')) return SendChatCommand(message[1..], playerKeyPair); try { + LastSeenMessageList.Acknowledgment? acknowledgment = (protocolversion >= MC_1_19_2_Version) ? this.consumeAcknowledgment() : null; + List fields = new(); // Message: String (up to 256 chars) @@ -2007,8 +2183,10 @@ namespace MinecraftClient.Protocol.Handlers fields.AddRange(salt); // Signature Length & Signature: (VarInt) and Byte Array - string uuid = handler.GetUserUUID()!; - byte[] sign = playerKeyPair.PrivateKey.SignMessage(message, uuid, timeNow, ref salt); + Guid uuid = handler.GetUserUuid(); + byte[] sign = (protocolversion >= MC_1_19_2_Version) ? + playerKeyPair.PrivateKey.SignMessage(message, uuid, timeNow, ref salt, acknowledgment!.lastSeen) : + playerKeyPair.PrivateKey.SignMessage(message, uuid, timeNow, ref salt); fields.AddRange(dataTypes.GetVarInt(sign.Length)); fields.AddRange(sign); } @@ -2016,8 +2194,11 @@ namespace MinecraftClient.Protocol.Handlers // Signed Preview: Boolean fields.AddRange(dataTypes.GetBool(false)); - fields.AddRange(dataTypes.GetVarInt(0)); - fields.AddRange(dataTypes.GetBool(false)); + if (protocolversion >= MC_1_19_2_Version) + { + // Message Acknowledgment + fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!)); + } } SendPacket(PacketTypesOut.ChatMessage, fields); return true; @@ -2098,9 +2279,12 @@ namespace MinecraftClient.Protocol.Handlers List fields = new List(); fields.AddRange(dataTypes.GetString(language)); fields.Add(viewDistance); - fields.AddRange(protocolversion >= MC_1_9_Version - ? dataTypes.GetVarInt(chatMode) - : new byte[] { chatMode }); + + if (protocolversion >= MC_1_9_Version) + fields.AddRange(dataTypes.GetVarInt(chatMode)); + else + fields.AddRange(new byte[] { chatMode }); + fields.Add(chatColors ? (byte)1 : (byte)0); if (protocolversion < MC_1_8_Version) { diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index 96b4e4b7..4e0de511 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -5,6 +5,7 @@ using System.Text; using MinecraftClient.Mapping; using MinecraftClient.Inventory; using MinecraftClient.Logger; +using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol { @@ -22,7 +23,8 @@ namespace MinecraftClient.Protocol int GetServerPort(); string GetServerHost(); string GetUsername(); - string GetUserUUID(); + Guid GetUserUuid(); + string GetUserUuidStr(); string GetSessionID(); string[] GetOnlinePlayers(); Dictionary GetOnlinePlayersWithUUID(); diff --git a/MinecraftClient/Protocol/ChatMessage.cs b/MinecraftClient/Protocol/Message/ChatMessage.cs similarity index 69% rename from MinecraftClient/Protocol/ChatMessage.cs rename to MinecraftClient/Protocol/Message/ChatMessage.cs index 1a4b961a..28d4c650 100644 --- a/MinecraftClient/Protocol/ChatMessage.cs +++ b/MinecraftClient/Protocol/Message/ChatMessage.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace MinecraftClient.Protocol +namespace MinecraftClient.Protocol.Message { public class ChatMessage { @@ -17,7 +17,7 @@ namespace MinecraftClient.Protocol // 0: chat (chat box), 1: system message (chat box), 2: game info (above hotbar), 3: say command, // 4: msg command, 5: team msg command, 6: emote command, 7: tellraw command - public readonly int chatType; + public readonly int chatTypeId; public readonly Guid senderUUID; @@ -31,31 +31,44 @@ namespace MinecraftClient.Protocol public readonly DateTime? timestamp; + public readonly byte[]? signature; + public readonly bool? isSignatureLegal; - public ChatMessage(string content, bool isJson, int chatType, Guid senderUUID, string? unsignedContent, string displayName, string? teamName, long timestamp, bool isSignatureLegal) + public ChatMessage(string content, bool isJson, int chatType, Guid senderUUID, string? unsignedContent, string displayName, string? teamName, long timestamp, byte[] signature, bool isSignatureLegal) { - this.isSignedChat = true; - this.isSystemChat = false; + isSignedChat = true; + isSystemChat = false; this.content = content; this.isJson = isJson; - this.chatType = chatType; + this.chatTypeId = chatType; this.senderUUID = senderUUID; this.unsignedContent = unsignedContent; this.displayName = displayName; this.teamName = teamName; - this.timestamp = DateTimeOffset.FromUnixTimeMilliseconds(timestamp).DateTime; + this.timestamp = DateTimeOffset.FromUnixTimeMilliseconds(timestamp).DateTime; + this.signature = signature; this.isSignatureLegal = isSignatureLegal; } public ChatMessage(string content, bool isJson, int chatType, Guid senderUUID, bool isSystemChat = false) { - this.isSignedChat = isSystemChat; + isSignedChat = isSystemChat; this.isSystemChat = isSystemChat; this.content = content; this.isJson = isJson; - this.chatType = chatType; + this.chatTypeId = chatType; this.senderUUID = senderUUID; } + + public LastSeenMessageList.Entry? toLastSeenMessageEntry() + { + return signature != null ? new LastSeenMessageList.Entry(senderUUID, signature) : null; + } + + public bool lacksSender() + { + return this.senderUUID == Guid.Empty; + } } } diff --git a/MinecraftClient/Protocol/ChatParser.cs b/MinecraftClient/Protocol/Message/ChatParser.cs similarity index 82% rename from MinecraftClient/Protocol/ChatParser.cs rename to MinecraftClient/Protocol/Message/ChatParser.cs index 57cee341..6fd05251 100644 --- a/MinecraftClient/Protocol/ChatParser.cs +++ b/MinecraftClient/Protocol/Message/ChatParser.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol { @@ -12,6 +13,20 @@ namespace MinecraftClient.Protocol static class ChatParser { + public enum MessageType + { + CHAT, + SAY_COMMAND, + MSG_COMMAND_INCOMING, + MSG_COMMAND_OUTGOING, + TEAM_MSG_COMMAND_INCOMING, + TEAM_MSG_COMMAND_OUTGOING, + EMOTE_COMMAND, + RAW_MSG + }; + + public static Dictionary? ChatId2Type; + /// /// The main function to convert text from MC 1.6+ JSON to MC 1.5.2 formatted text /// @@ -31,56 +46,64 @@ namespace MinecraftClient.Protocol /// Returns the translated text public static string ParseSignedChat(ChatMessage message, List? links = null) { - string content; - if (Settings.ShowModifiedChat && message.unsignedContent != null) - content = ChatParser.ParseText(message.unsignedContent, links); - else - content = ChatParser.ParseText(message.content, links); + string chatContent = Settings.ShowModifiedChat && message.unsignedContent != null ? message.unsignedContent : message.content; + string content = message.isJson ? ParseText(chatContent, links) : chatContent; string sender = message.displayName!; + string text; List usingData = new(); - switch (message.chatType) + + MessageType chatType; + if (message.isSystemChat) + chatType = MessageType.RAW_MSG; + else if (!ChatId2Type!.TryGetValue(message.chatTypeId, out chatType)) + chatType = MessageType.CHAT; + switch (chatType) { - case 0: // chat (chat box) + case MessageType.CHAT: usingData.Add(sender); usingData.Add(content); text = TranslateString("chat.type.text", usingData); break; - case 1: // system message (chat box) - text = content; - break; - case 2: // game info (above hotbar) - text = content; - break; - case 3: // say command + case MessageType.SAY_COMMAND: usingData.Add(sender); usingData.Add(content); text = TranslateString("chat.type.announcement", usingData); break; - case 4: // msg command + case MessageType.MSG_COMMAND_INCOMING: usingData.Add(sender); usingData.Add(content); text = TranslateString("commands.message.display.incoming", usingData); break; - case 5: // team msg command (/teammsg) + case MessageType.MSG_COMMAND_OUTGOING: + usingData.Add(sender); + usingData.Add(content); + text = TranslateString("commands.message.display.outgoing", usingData); + break; + case MessageType.TEAM_MSG_COMMAND_INCOMING: usingData.Add(message.teamName!); usingData.Add(sender); usingData.Add(content); text = TranslateString("chat.type.team.text", usingData); break; - case 6: // emote command (/me) + case MessageType.TEAM_MSG_COMMAND_OUTGOING: + usingData.Add(message.teamName!); + usingData.Add(sender); + usingData.Add(content); + text = TranslateString("chat.type.team.sent", usingData); + break; + case MessageType.EMOTE_COMMAND: usingData.Add(sender); usingData.Add(content); text = TranslateString("chat.type.emote", usingData); break; - case 7: // tellraw command + case MessageType.RAW_MSG: text = content; break; default: - text = $"{sender}: {content}"; - break; + goto case MessageType.CHAT; } - string color = String.Empty; + string color = string.Empty; if (message.isSystemChat) { if (Settings.MarkSystemMessage) @@ -121,21 +144,21 @@ namespace MinecraftClient.Protocol { /* MC 1.7+ Name MC 1.6 Name Classic tag */ case "black": /* Blank if same */ return "§0"; - case "dark_blue": return "§1"; - case "dark_green": return "§2"; - case "dark_aqua": case "dark_cyan": return "§3"; - case "dark_red": return "§4"; - case "dark_purple": case "dark_magenta": return "§5"; - case "gold": case "dark_yellow": return "§6"; - case "gray": return "§7"; - case "dark_gray": return "§8"; - case "blue": return "§9"; - case "green": return "§a"; - case "aqua": case "cyan": return "§b"; - case "red": return "§c"; - case "light_purple": case "magenta": return "§d"; - case "yellow": return "§e"; - case "white": return "§f"; + case "dark_blue": return "§1"; + case "dark_green": return "§2"; + case "dark_aqua": case "dark_cyan": return "§3"; + case "dark_red": return "§4"; + case "dark_purple": case "dark_magenta": return "§5"; + case "gold": case "dark_yellow": return "§6"; + case "gray": return "§7"; + case "dark_gray": return "§8"; + case "blue": return "§9"; + case "green": return "§a"; + case "aqua": case "cyan": return "§b"; + case "red": return "§c"; + case "light_purple": case "magenta": return "§d"; + case "yellow": return "§e"; + case "white": return "§f"; default: return ""; } } @@ -172,13 +195,13 @@ namespace MinecraftClient.Protocol TranslationRules["commands.message.display.outgoing"] = "§7You whisper to %s: %s"; //Language file in a subfolder, depending on the language setting - if (!System.IO.Directory.Exists("lang")) - System.IO.Directory.CreateDirectory("lang"); + if (!Directory.Exists("lang")) + Directory.CreateDirectory("lang"); string Language_File = "lang" + Path.DirectorySeparatorChar + Settings.Language + ".lang"; //File not found? Try downloading language file from Mojang's servers? - if (!System.IO.File.Exists(Language_File)) + if (!File.Exists(Language_File)) { ConsoleIO.WriteLineFormatted(Translations.Get("chat.download", Settings.Language)); try @@ -197,7 +220,7 @@ namespace MinecraftClient.Protocol stringBuilder.Append(entry.Key + "=" + entry.Value.StringValue + Environment.NewLine); } - System.IO.File.WriteAllText(Language_File, stringBuilder.ToString()); + File.WriteAllText(Language_File, stringBuilder.ToString()); ConsoleIO.WriteLineFormatted(Translations.Get("chat.done", Language_File)); } catch @@ -207,17 +230,17 @@ namespace MinecraftClient.Protocol } //Download Failed? Defaulting to en_GB.lang if the game is installed - if (!System.IO.File.Exists(Language_File) //Try en_GB.lang - && System.IO.File.Exists(Settings.TranslationsFile_FromMCDir)) + if (!File.Exists(Language_File) //Try en_GB.lang + && File.Exists(Settings.TranslationsFile_FromMCDir)) { Language_File = Settings.TranslationsFile_FromMCDir; Translations.WriteLineFormatted("chat.from_dir"); } //Load the external dictionnary of translation rules or display an error message - if (System.IO.File.Exists(Language_File)) + if (File.Exists(Language_File)) { - string[] translations = System.IO.File.ReadAllLines(Language_File); + string[] translations = File.ReadAllLines(Language_File); foreach (string line in translations) { if (line.Length > 0) @@ -289,7 +312,7 @@ namespace MinecraftClient.Protocol } return result.ToString(); } - else return "[" + rulename + "] " + String.Join(" ", using_data); + else return "[" + rulename + "] " + string.Join(" ", using_data); } /// @@ -315,11 +338,11 @@ namespace MinecraftClient.Protocol if (clickEvent.Properties.ContainsKey("action") && clickEvent.Properties.ContainsKey("value") && clickEvent.Properties["action"].StringValue == "open_url" - && !String.IsNullOrEmpty(clickEvent.Properties["value"].StringValue)) + && !string.IsNullOrEmpty(clickEvent.Properties["value"].StringValue)) { links.Add(clickEvent.Properties["value"].StringValue); } - } + } if (data.Properties.ContainsKey("extra")) { Json.JSONData[] extras = data.Properties["extra"].DataArray.ToArray(); @@ -372,7 +395,7 @@ namespace MinecraftClient.Protocol System.Net.HttpWebRequest myRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url); myRequest.Method = "GET"; System.Net.WebResponse myResponse = myRequest.GetResponse(); - System.IO.StreamReader sr = new System.IO.StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8); + StreamReader sr = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8); string result = sr.ReadToEnd(); sr.Close(); myResponse.Close(); diff --git a/MinecraftClient/Protocol/Message/LastSeenMessageList.cs b/MinecraftClient/Protocol/Message/LastSeenMessageList.cs new file mode 100644 index 00000000..262b1b55 --- /dev/null +++ b/MinecraftClient/Protocol/Message/LastSeenMessageList.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MinecraftClient.Protocol.Message +{ + /// + /// A list of messages a client has seen. + /// + public class LastSeenMessageList + { + public static readonly LastSeenMessageList EMPTY = new(new Entry[0]); + public static readonly int MAX_ENTRIES = 5; + + public Entry[] entries; + + public LastSeenMessageList(Entry[] list) + { + entries = list; + } + + public void WriteForSign(List data) + { + foreach (Entry entry in entries) + { + data.Add(70); + data.AddRange(entry.profileId.ToBigEndianBytes()); + data.AddRange(entry.lastSignature); + } + } + + /// + /// A pair of a player's UUID and the signature of the last message they saw, used as an entry of LastSeenMessageList. + /// + public class Entry + { + public Guid profileId; + public byte[] lastSignature; + + public Entry(Guid profileId, byte[] lastSignature) + { + this.profileId = profileId; + this.lastSignature = lastSignature; + } + } + + /// + /// A record of messages acknowledged by a client. + /// This holds the messages the client has recently seen, as well as the last message they received, if any. + /// + public class Acknowledgment + { + public LastSeenMessageList lastSeen; + public Entry? lastReceived; + + public Acknowledgment(LastSeenMessageList lastSeenMessageList, Entry? lastReceivedMessage) + { + lastSeen = lastSeenMessageList; + lastReceived = lastReceivedMessage; + } + } + } + + /// + /// Collects the message that are last seen by a client. + /// The message, along with the "last received" message, forms an "acknowledgment" of received messages. + /// They are sent to the server when the client has enough messages received or when they send a message. + /// The maximum amount of message entries are specified in the constructor.The vanilla clients collect 5 entries. + /// Calling add adds the message to the beginning of the entries list, and evicts the oldest message. + /// If there are entries with the same sender profile ID, the older entry will be replaced with null instead of filling the hole. + /// + public class LastSeenMessagesCollector + { + private readonly LastSeenMessageList.Entry[] entries; + private int size = 0; + private LastSeenMessageList lastSeenMessages; + + public LastSeenMessagesCollector(int size) + { + lastSeenMessages = LastSeenMessageList.EMPTY; + entries = new LastSeenMessageList.Entry[size]; + } + + public void Add(LastSeenMessageList.Entry entry) + { + LastSeenMessageList.Entry? lastEntry = entry; + + for (int i = 0; i < size; ++i) + { + LastSeenMessageList.Entry curEntry = entries[i]; + entries[i] = lastEntry; + lastEntry = curEntry; + if (curEntry.profileId == entry.profileId) + { + lastEntry = null; + break; + } + } + + if (lastEntry != null && size < entries.Length) + entries[size++] = lastEntry; + + LastSeenMessageList.Entry[] msgList = new LastSeenMessageList.Entry[size]; + for (int i = 0; i < size; ++i) + msgList[i] = entries[i]; + lastSeenMessages = new LastSeenMessageList(msgList); + } + + public LastSeenMessageList GetLastSeenMessages() + { + return lastSeenMessages; + } + + } +} diff --git a/MinecraftClient/Protocol/PlayerInfo.cs b/MinecraftClient/Protocol/PlayerInfo.cs index f810b763..46c50bf6 100644 --- a/MinecraftClient/Protocol/PlayerInfo.cs +++ b/MinecraftClient/Protocol/PlayerInfo.cs @@ -4,12 +4,13 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using MinecraftClient.Protocol.Keys; +using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol { public class PlayerInfo { - public readonly Guid UUID; + public readonly Guid Uuid; public readonly string Name; @@ -26,9 +27,13 @@ namespace MinecraftClient.Protocol private readonly DateTime? KeyExpiresAt; + private bool lastMessageVerified; + + private byte[]? precedingSignature; + public PlayerInfo(Guid uuid, string name, Tuple[]? property, int gamemode, int ping, string? displayName, long? timeStamp, byte[]? publicKey, byte[]? signature) { - UUID = uuid; + Uuid = uuid; Name = name; if (property != null) Property = property; @@ -48,36 +53,107 @@ namespace MinecraftClient.Protocol PublicKey = null; } } + lastMessageVerified = true; + precedingSignature = null; } public PlayerInfo(string name, Guid uuid) { Name = name; - UUID = uuid; + Uuid = uuid; Gamemode = -1; Ping = 0; + lastMessageVerified = true; + precedingSignature = null; } - public bool IsKeyVaild() + public bool IsMessageChainLegal() { - return PublicKey != null && DateTime.Now.ToUniversalTime() > this.KeyExpiresAt; + return this.lastMessageVerified; } - public bool VerifyMessage(string message, Guid uuid, long timestamp, long salt, ref byte[] signature) + public bool IsKeyExpired() { - if (PublicKey == null) + return DateTime.Now.ToUniversalTime() > this.KeyExpiresAt; + } + + /// + /// Verify message - 1.19 + /// + /// Message content + /// Timestamp + /// Salt + /// Message signature + /// Is this message vaild + public bool VerifyMessage(string message, long timestamp, long salt, ref byte[] signature) + { + if (PublicKey == null || IsKeyExpired()) return false; else { - string uuidString = uuid.ToString().Replace("-", string.Empty); - DateTimeOffset timeOffset = DateTimeOffset.FromUnixTimeMilliseconds(timestamp); byte[] saltByte = BitConverter.GetBytes(salt); Array.Reverse(saltByte); - return PublicKey.VerifyMessage(message, uuidString, timeOffset, ref saltByte, ref signature); + return PublicKey.VerifyMessage(message, Uuid, timeOffset, ref saltByte, ref signature); } } + + /// + /// Verify message - 1.19.1 and above + /// + /// Message content + /// Timestamp + /// Salt + /// Message signature + /// Preceding message signature + /// LastSeenMessages + /// Is this message chain vaild + public bool VerifyMessage(string message, long timestamp, long salt, ref byte[] signature, ref byte[]? precedingSignature, LastSeenMessageList lastSeenMessages) + { + if (this.lastMessageVerified == false) + return false; + if (PublicKey == null || IsKeyExpired() || (this.precedingSignature != null && precedingSignature == null)) + return false; + if (this.precedingSignature != null && !this.precedingSignature.SequenceEqual(precedingSignature!)) + return false; + + DateTimeOffset timeOffset = DateTimeOffset.FromUnixTimeMilliseconds(timestamp); + + byte[] saltByte = BitConverter.GetBytes(salt); + Array.Reverse(saltByte); + + bool res = PublicKey.VerifyMessage(message, Uuid, timeOffset, ref saltByte, ref signature, ref precedingSignature, lastSeenMessages); + + this.lastMessageVerified = res; + this.precedingSignature = signature; + + return res; + } + + /// + /// Verify message head - 1.19.1 and above + /// + /// Preceding message signature + /// Message signature + /// Message body hash + /// Is this message chain vaild + public bool VerifyMessageHead(ref byte[]? precedingSignature, ref byte[] headerSignature, ref byte[] bodyDigest) + { + if (this.lastMessageVerified == false) + return false; + if (PublicKey == null || IsKeyExpired() || (this.precedingSignature != null && precedingSignature == null)) + return false; + if (this.precedingSignature != null && !this.precedingSignature.SequenceEqual(precedingSignature!)) + return false; + + bool res = PublicKey.VerifyHeader(ref bodyDigest, ref headerSignature); + + this.lastMessageVerified = res; + this.precedingSignature = headerSignature; + + return res; + } } } diff --git a/MinecraftClient/Protocol/ProfileKey/KeyUtils.cs b/MinecraftClient/Protocol/ProfileKey/KeyUtils.cs index 95c8fd57..775947f1 100644 --- a/MinecraftClient/Protocol/ProfileKey/KeyUtils.cs +++ b/MinecraftClient/Protocol/ProfileKey/KeyUtils.cs @@ -1,14 +1,19 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; +using MinecraftClient.Protocol.Handlers; +using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol.Keys { static class KeyUtils { - private static string certificates = "https://api.minecraftservices.com/player/certificates"; + private static readonly SHA256 sha256Hash = SHA256.Create(); + + private static readonly string certificates = "https://api.minecraftservices.com/player/certificates"; public static PlayerKeyPair? GetKeys(string accessToken) { @@ -67,19 +72,18 @@ namespace MinecraftClient.Protocol.Keys return Convert.FromBase64String(key); } - public static byte[] GetSignatureData(string message, string uuid, DateTimeOffset timestamp, ref byte[] salt) + public static byte[] ComputeHash(byte[] data) + { + return sha256Hash.ComputeHash(data); + } + + public static byte[] GetSignatureData(string message, Guid uuid, DateTimeOffset timestamp, ref byte[] salt) { List data = new(); data.AddRange(salt); - byte[] UUIDLeastSignificantBits = BitConverter.GetBytes(Convert.ToInt64(uuid[..16], 16)); - Array.Reverse(UUIDLeastSignificantBits); - data.AddRange(UUIDLeastSignificantBits); - - byte[] UUIDMostSignificantBits = BitConverter.GetBytes(Convert.ToInt64(uuid.Substring(16, 16), 16)); - Array.Reverse(UUIDMostSignificantBits); - data.AddRange(UUIDMostSignificantBits); + data.AddRange(uuid.ToBigEndianBytes()); byte[] timestampByte = BitConverter.GetBytes(timestamp.ToUnixTimeSeconds()); Array.Reverse(timestampByte); @@ -90,6 +94,39 @@ namespace MinecraftClient.Protocol.Keys return data.ToArray(); } + public static byte[] GetSignatureData(string message, DateTimeOffset timestamp, ref byte[] salt, LastSeenMessageList lastSeenMessages) + { + List data = new(); + + data.AddRange(salt); + + byte[] timestampByte = BitConverter.GetBytes(timestamp.ToUnixTimeSeconds()); + Array.Reverse(timestampByte); + data.AddRange(timestampByte); + + data.AddRange(Encoding.UTF8.GetBytes(message)); + + data.Add(70); + + lastSeenMessages.WriteForSign(data); + + return data.ToArray(); + } + + public static byte[] GetSignatureData(byte[]? precedingSignature, Guid sender, byte[] bodySign) + { + List data = new(); + + if (precedingSignature != null) + data.AddRange(precedingSignature); + + data.AddRange(sender.ToBigEndianBytes()); + + data.AddRange(bodySign); + + return data.ToArray(); + } + // https://github.com/mono/mono/blob/master/mcs/class/System.Json/System.Json/JsonValue.cs public static string EscapeString(string src) { diff --git a/MinecraftClient/Protocol/ProfileKey/PrivateKey.cs b/MinecraftClient/Protocol/ProfileKey/PrivateKey.cs index b02be93f..0683ef46 100644 --- a/MinecraftClient/Protocol/ProfileKey/PrivateKey.cs +++ b/MinecraftClient/Protocol/ProfileKey/PrivateKey.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; +using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol.Keys { @@ -13,6 +14,8 @@ namespace MinecraftClient.Protocol.Keys private readonly RSA rsa; + private byte[]? precedingSignature = null; + public PrivateKey(string pemKey) { this.Key = KeyUtils.DecodePemKey(pemKey, "-----BEGIN RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----"); @@ -26,7 +29,15 @@ namespace MinecraftClient.Protocol.Keys return rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); } - public byte[] SignMessage(string message, string uuid, DateTimeOffset timestamp, ref byte[] salt) + /// + /// Sign message - 1.19 + /// + /// Message content + /// Sender uuid + /// Timestamp + /// Salt + /// Signature data + public byte[] SignMessage(string message, Guid uuid, DateTimeOffset timestamp, ref byte[] salt) { string messageJson = "{\"text\":\"" + KeyUtils.EscapeString(message) + "\"}"; @@ -35,5 +46,27 @@ namespace MinecraftClient.Protocol.Keys return SignData(data); } + /// + /// Sign message - 1.19.1 and above + /// + /// Message content + /// Sender uuid + /// Timestamp + /// Salt + /// LastSeenMessageList + /// Signature data + public byte[] SignMessage(string message, Guid uuid, DateTimeOffset timestamp, ref byte[] salt, LastSeenMessageList lastSeenMessages) + { + byte[] bodySignData = KeyUtils.GetSignatureData(message, timestamp, ref salt, lastSeenMessages); + byte[] bodyDigest = KeyUtils.ComputeHash(bodySignData); + + byte[] msgSignData = KeyUtils.GetSignatureData(precedingSignature, uuid, bodyDigest); + byte[] msgSign = SignData(msgSignData); + + this.precedingSignature = msgSign; + + return msgSign; + } + } } diff --git a/MinecraftClient/Protocol/ProfileKey/PublicKey.cs b/MinecraftClient/Protocol/ProfileKey/PublicKey.cs index f0a2cdd8..6bec8ae9 100644 --- a/MinecraftClient/Protocol/ProfileKey/PublicKey.cs +++ b/MinecraftClient/Protocol/ProfileKey/PublicKey.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; +using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol.Keys { @@ -44,12 +45,53 @@ namespace MinecraftClient.Protocol.Keys return rsa.VerifyData(data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); } - public bool VerifyMessage(string message, string uuid, DateTimeOffset timestamp, ref byte[] salt, ref byte[] signature) + /// + /// Verify message - 1.19 + /// + /// Message content + /// Sender uuid + /// Timestamp + /// Salt + /// Message signature + /// Is this message vaild + public bool VerifyMessage(string message, Guid uuid, DateTimeOffset timestamp, ref byte[] salt, ref byte[] signature) { byte[] data = KeyUtils.GetSignatureData(message, uuid, timestamp, ref salt); return VerifyData(data, signature); } + /// + /// Verify message - 1.19.1 and above + /// + /// Message content + /// Sender uuid + /// Timestamp + /// Salt + /// Message signature + /// Preceding message signature + /// LastSeenMessages + /// Is this message vaild + public bool VerifyMessage(string message, Guid uuid, DateTimeOffset timestamp, ref byte[] salt, ref byte[] signature, ref byte[]? precedingSignature, LastSeenMessageList lastSeenMessages) + { + byte[] bodySignData = KeyUtils.GetSignatureData(message, timestamp, ref salt, lastSeenMessages); + byte[] bodyDigest = KeyUtils.ComputeHash(bodySignData); + + byte[] msgSignData = KeyUtils.GetSignatureData(precedingSignature, uuid, bodyDigest); + + return VerifyData(msgSignData, signature); + } + + /// + /// Verify message head - 1.19.1 and above + /// + /// Message body hash + /// Message signature + /// Is this message header vaild + public bool VerifyHeader(ref byte[] bodyDigest, ref byte[] signature) + { + return VerifyData(bodyDigest, signature); + } + } } diff --git a/MinecraftClient/Scripting/ChatBot.cs b/MinecraftClient/Scripting/ChatBot.cs index 650bcf8c..4fc59e1e 100644 --- a/MinecraftClient/Scripting/ChatBot.cs +++ b/MinecraftClient/Scripting/ChatBot.cs @@ -1110,7 +1110,7 @@ namespace MinecraftClient /// UserUUID of the current account protected string GetUserUUID() { - return Handler.GetUserUUID(); + return Handler.GetUserUuidStr(); } /// From 93c89f879dfd95356e1be2dd656e74c3b7b6ae0d Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 27 Aug 2022 02:14:25 +0800 Subject: [PATCH 03/20] Fix format --- .../Protocol/Message/ChatParser.cs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/MinecraftClient/Protocol/Message/ChatParser.cs b/MinecraftClient/Protocol/Message/ChatParser.cs index 6fd05251..7f817d25 100644 --- a/MinecraftClient/Protocol/Message/ChatParser.cs +++ b/MinecraftClient/Protocol/Message/ChatParser.cs @@ -144,21 +144,21 @@ namespace MinecraftClient.Protocol { /* MC 1.7+ Name MC 1.6 Name Classic tag */ case "black": /* Blank if same */ return "§0"; - case "dark_blue": return "§1"; - case "dark_green": return "§2"; - case "dark_aqua": case "dark_cyan": return "§3"; - case "dark_red": return "§4"; - case "dark_purple": case "dark_magenta": return "§5"; - case "gold": case "dark_yellow": return "§6"; - case "gray": return "§7"; - case "dark_gray": return "§8"; - case "blue": return "§9"; - case "green": return "§a"; - case "aqua": case "cyan": return "§b"; - case "red": return "§c"; - case "light_purple": case "magenta": return "§d"; - case "yellow": return "§e"; - case "white": return "§f"; + case "dark_blue": return "§1"; + case "dark_green": return "§2"; + case "dark_aqua": case "dark_cyan": return "§3"; + case "dark_red": return "§4"; + case "dark_purple": case "dark_magenta": return "§5"; + case "gold": case "dark_yellow": return "§6"; + case "gray": return "§7"; + case "dark_gray": return "§8"; + case "blue": return "§9"; + case "green": return "§a"; + case "aqua": case "cyan": return "§b"; + case "red": return "§c"; + case "light_purple": case "magenta": return "§d"; + case "yellow": return "§e"; + case "white": return "§f"; default: return ""; } } From 7ceb4807f3d813252d153d1df386b1c435850b06 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 27 Aug 2022 02:32:59 +0800 Subject: [PATCH 04/20] Adjust some comments --- MinecraftClient/Protocol/Handlers/Protocol18.cs | 14 +++++++------- MinecraftClient/Protocol/Message/ChatParser.cs | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 64bdec30..2da4394e 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -475,7 +475,7 @@ namespace MinecraftClient.Protocol.Handlers byte[] messageSignature = dataTypes.ReadNextByteArray(packetData); bool verifyResult; - if (senderUUID.ToString().Replace("-", String.Empty) == handler.GetUserUuidStr()) + if (senderUUID == handler.GetUserUuid()) verifyResult = true; else { @@ -518,19 +518,19 @@ namespace MinecraftClient.Protocol.Handlers string? targetName = dataTypes.ReadNextBool(packetData) ? dataTypes.ReadNextString(packetData) : null; bool verifyResult; - if (senderUUID.ToString().Replace("-", String.Empty) == handler.GetUserUuidStr()) + if (senderUUID == handler.GetUserUuid()) verifyResult = true; else { PlayerInfo? player = handler.GetPlayerInfo(senderUUID); - if (player == null) + if (player == null || !player.IsMessageChainLegal()) verifyResult = false; else { bool lastVerifyResult = player.IsMessageChainLegal(); verifyResult = player.VerifyMessage(signedChat, timestamp, salt, ref headerSignature, ref precedingSignature, lastSeenMessages); if (lastVerifyResult && !verifyResult) - log.Warn("Player " + player.DisplayName + " message chains broken!"); + log.Warn("Player " + player.DisplayName + "'s message chain is broken!"); } } @@ -557,19 +557,19 @@ namespace MinecraftClient.Protocol.Handlers byte[] bodyDigest = dataTypes.ReadNextByteArray(packetData); bool verifyResult; - if (senderUUID.ToString().Replace("-", String.Empty) == handler.GetUserUuidStr()) + if (senderUUID == handler.GetUserUuid()) verifyResult = true; else { PlayerInfo? player = handler.GetPlayerInfo(senderUUID); - if (player == null) + if (player == null || !player.IsMessageChainLegal()) verifyResult = false; else { bool lastVerifyResult = player.IsMessageChainLegal(); verifyResult = player.VerifyMessageHead(ref precedingSignature, ref headerSignature, ref bodyDigest); if (lastVerifyResult && !verifyResult) - log.Warn("Player " + player.DisplayName + " message chains broken!"); + log.Warn("Player " + player.DisplayName + "'s message chain is broken!"); } } } diff --git a/MinecraftClient/Protocol/Message/ChatParser.cs b/MinecraftClient/Protocol/Message/ChatParser.cs index 7f817d25..ff36ca13 100644 --- a/MinecraftClient/Protocol/Message/ChatParser.cs +++ b/MinecraftClient/Protocol/Message/ChatParser.cs @@ -107,7 +107,7 @@ namespace MinecraftClient.Protocol if (message.isSystemChat) { if (Settings.MarkSystemMessage) - color = "§z §r "; // Custom: Background Gray + color = "§z §r "; // Custom color code §z : Background Gray } else { @@ -116,18 +116,18 @@ namespace MinecraftClient.Protocol if (Settings.ShowModifiedChat && message.unsignedContent != null) { if (Settings.MarkModifiedMsg) - color = "§x §r "; // Custom: Background Yellow + color = "§x §r "; // Custom color code §x : Background Yellow } else { if (Settings.MarkLegallySignedMsg) - color = "§y §r "; // Custom: Background Green + color = "§y §r "; // Custom color code §y : Background Green } } else { if (Settings.MarkIllegallySignedMsg) - color = "§w §r "; // Custom: Background Red + color = "§w §r "; // Custom color code §w : Background Red } } return color + text; From 9e4184a98ddc8b5c21f953743677b5604acec701 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 28 Aug 2022 18:39:59 +0800 Subject: [PATCH 05/20] Add 1.19 block palette --- .../Mapping/BlockPalettes/Palette113.cs | 2 +- .../Mapping/BlockPalettes/Palette114.cs | 2 +- .../Mapping/BlockPalettes/Palette115.cs | 2 +- .../Mapping/BlockPalettes/Palette116.cs | 2 +- .../Mapping/BlockPalettes/Palette117.cs | 2 +- .../Mapping/BlockPalettes/Palette119.cs | 1530 +++++++++++++++++ MinecraftClient/Mapping/Material.cs | 93 +- MinecraftClient/Mapping/Material2Tool.cs | 2 +- MinecraftClient/Mapping/MaterialExtensions.cs | 2 +- .../Protocol/Handlers/Protocol18.cs | 353 ++-- 10 files changed, 1778 insertions(+), 212 deletions(-) create mode 100644 MinecraftClient/Mapping/BlockPalettes/Palette119.cs diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette113.cs b/MinecraftClient/Mapping/BlockPalettes/Palette113.cs index ca29cfab..b0e2006d 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette113.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette113.cs @@ -760,7 +760,7 @@ namespace MinecraftClient.Mapping.BlockPalettes materials[8158] = Material.EndStoneBricks; for (int i = 8159; i <= 8162; i++) materials[i] = Material.Beetroots; - materials[8163] = Material.GrassPath; + materials[8163] = Material.DirtPath; materials[8164] = Material.EndGateway; for (int i = 8165; i <= 8176; i++) materials[i] = Material.RepeatingCommandBlock; diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette114.cs b/MinecraftClient/Mapping/BlockPalettes/Palette114.cs index 2503f1bb..b44b20d6 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette114.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette114.cs @@ -792,7 +792,7 @@ namespace MinecraftClient.Mapping.BlockPalettes materials[8682] = Material.EndStoneBricks; for (int i = 8683; i <= 8686; i++) materials[i] = Material.Beetroots; - materials[8687] = Material.GrassPath; + materials[8687] = Material.DirtPath; materials[8688] = Material.EndGateway; for (int i = 8689; i <= 8700; i++) materials[i] = Material.RepeatingCommandBlock; diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette115.cs b/MinecraftClient/Mapping/BlockPalettes/Palette115.cs index b56accc1..e84fbd11 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette115.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette115.cs @@ -792,7 +792,7 @@ namespace MinecraftClient.Mapping.BlockPalettes materials[8682] = Material.EndStoneBricks; for (int i = 8683; i <= 8686; i++) materials[i] = Material.Beetroots; - materials[8687] = Material.GrassPath; + materials[8687] = Material.DirtPath; materials[8688] = Material.EndGateway; for (int i = 8689; i <= 8700; i++) materials[i] = Material.RepeatingCommandBlock; diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette116.cs b/MinecraftClient/Mapping/BlockPalettes/Palette116.cs index e44085f8..1d63b6b4 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette116.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette116.cs @@ -800,7 +800,7 @@ namespace MinecraftClient.Mapping.BlockPalettes materials[9222] = Material.EndStoneBricks; for (int i = 9223; i <= 9226; i++) materials[i] = Material.Beetroots; - materials[9227] = Material.GrassPath; + materials[9227] = Material.DirtPath; materials[9228] = Material.EndGateway; for (int i = 9229; i <= 9240; i++) materials[i] = Material.RepeatingCommandBlock; diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette117.cs b/MinecraftClient/Mapping/BlockPalettes/Palette117.cs index 6a8f78c6..826b630e 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette117.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette117.cs @@ -820,7 +820,7 @@ namespace MinecraftClient.Mapping.BlockPalettes materials[9468] = Material.EndStoneBricks; for (int i = 9469; i <= 9472; i++) materials[i] = Material.Beetroots; - materials[9473] = Material.GrassPath; + materials[9473] = Material.DirtPath; materials[9474] = Material.EndGateway; for (int i = 9475; i <= 9486; i++) materials[i] = Material.RepeatingCommandBlock; diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette119.cs b/MinecraftClient/Mapping/BlockPalettes/Palette119.cs new file mode 100644 index 00000000..b3cc787d --- /dev/null +++ b/MinecraftClient/Mapping/BlockPalettes/Palette119.cs @@ -0,0 +1,1530 @@ +using System; +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.BlockPalettes +{ + public class Palette119 : BlockPalette + { + private static Dictionary materials = new Dictionary(); + + static Palette119() + { + for (int i = 7035; i <= 7058; i++) + materials[i] = Material.AcaciaButton; + for (int i = 9747; i <= 9810; i++) + materials[i] = Material.AcaciaDoor; + for (int i = 9459; i <= 9490; i++) + materials[i] = Material.AcaciaFence; + for (int i = 9267; i <= 9298; i++) + materials[i] = Material.AcaciaFenceGate; + for (int i = 318; i <= 345; i++) + materials[i] = Material.AcaciaLeaves; + for (int i = 129; i <= 131; i++) + materials[i] = Material.AcaciaLog; + materials[19] = Material.AcaciaPlanks; + for (int i = 4186; i <= 4187; i++) + materials[i] = Material.AcaciaPressurePlate; + for (int i = 30; i <= 31; i++) + materials[i] = Material.AcaciaSapling; + for (int i = 3732; i <= 3763; i++) + materials[i] = Material.AcaciaSign; + for (int i = 9065; i <= 9070; i++) + materials[i] = Material.AcaciaSlab; + for (int i = 8004; i <= 8083; i++) + materials[i] = Material.AcaciaStairs; + for (int i = 4676; i <= 4739; i++) + materials[i] = Material.AcaciaTrapdoor; + for (int i = 4056; i <= 4063; i++) + materials[i] = Material.AcaciaWallSign; + for (int i = 176; i <= 178; i++) + materials[i] = Material.AcaciaWood; + for (int i = 7440; i <= 7463; i++) + materials[i] = Material.ActivatorRail; + materials[0] = Material.Air; + materials[1669] = Material.Allium; + materials[18619] = Material.AmethystBlock; + for (int i = 18621; i <= 18632; i++) + materials[i] = Material.AmethystCluster; + materials[17036] = Material.AncientDebris; + materials[6] = Material.Andesite; + for (int i = 11724; i <= 11729; i++) + materials[i] = Material.AndesiteSlab; + for (int i = 11350; i <= 11429; i++) + materials[i] = Material.AndesiteStairs; + for (int i = 14340; i <= 14663; i++) + materials[i] = Material.AndesiteWall; + for (int i = 7227; i <= 7230; i++) + materials[i] = Material.Anvil; + for (int i = 5147; i <= 5150; i++) + materials[i] = Material.AttachedMelonStem; + for (int i = 5143; i <= 5146; i++) + materials[i] = Material.AttachedPumpkinStem; + materials[19714] = Material.Azalea; + for (int i = 402; i <= 429; i++) + materials[i] = Material.AzaleaLeaves; + materials[1670] = Material.AzureBluet; + for (int i = 10533; i <= 10544; i++) + materials[i] = Material.Bamboo; + materials[10532] = Material.BambooSapling; + for (int i = 15996; i <= 16007; i++) + materials[i] = Material.Barrel; + materials[8245] = Material.Barrier; + for (int i = 4311; i <= 4313; i++) + materials[i] = Material.Basalt; + materials[6248] = Material.Beacon; + materials[74] = Material.Bedrock; + for (int i = 16985; i <= 17008; i++) + materials[i] = Material.BeeNest; + for (int i = 17009; i <= 17032; i++) + materials[i] = Material.Beehive; + for (int i = 10100; i <= 10103; i++) + materials[i] = Material.Beetroots; + for (int i = 16059; i <= 16090; i++) + materials[i] = Material.Bell; + for (int i = 19718; i <= 19749; i++) + materials[i] = Material.BigDripleaf; + for (int i = 19750; i <= 19757; i++) + materials[i] = Material.BigDripleafStem; + for (int i = 6987; i <= 7010; i++) + materials[i] = Material.BirchButton; + for (int i = 9619; i <= 9682; i++) + materials[i] = Material.BirchDoor; + for (int i = 9395; i <= 9426; i++) + materials[i] = Material.BirchFence; + for (int i = 9203; i <= 9234; i++) + materials[i] = Material.BirchFenceGate; + for (int i = 262; i <= 289; i++) + materials[i] = Material.BirchLeaves; + for (int i = 123; i <= 125; i++) + materials[i] = Material.BirchLog; + materials[17] = Material.BirchPlanks; + for (int i = 4182; i <= 4183; i++) + materials[i] = Material.BirchPressurePlate; + for (int i = 26; i <= 27; i++) + materials[i] = Material.BirchSapling; + for (int i = 3700; i <= 3731; i++) + materials[i] = Material.BirchSign; + for (int i = 9053; i <= 9058; i++) + materials[i] = Material.BirchSlab; + for (int i = 6076; i <= 6155; i++) + materials[i] = Material.BirchStairs; + for (int i = 4548; i <= 4611; i++) + materials[i] = Material.BirchTrapdoor; + for (int i = 4048; i <= 4055; i++) + materials[i] = Material.BirchWallSign; + for (int i = 170; i <= 172; i++) + materials[i] = Material.BirchWood; + for (int i = 8878; i <= 8893; i++) + materials[i] = Material.BlackBanner; + for (int i = 1519; i <= 1534; i++) + materials[i] = Material.BlackBed; + for (int i = 18569; i <= 18584; i++) + materials[i] = Material.BlackCandle; + for (int i = 18617; i <= 18618; i++) + materials[i] = Material.BlackCandleCake; + materials[8622] = Material.BlackCarpet; + materials[10334] = Material.BlackConcrete; + materials[10350] = Material.BlackConcretePowder; + for (int i = 10315; i <= 10318; i++) + materials[i] = Material.BlackGlazedTerracotta; + for (int i = 10249; i <= 10254; i++) + materials[i] = Material.BlackShulkerBox; + materials[4419] = Material.BlackStainedGlass; + for (int i = 7972; i <= 8003; i++) + materials[i] = Material.BlackStainedGlassPane; + materials[7491] = Material.BlackTerracotta; + for (int i = 8954; i <= 8957; i++) + materials[i] = Material.BlackWallBanner; + materials[1653] = Material.BlackWool; + materials[17048] = Material.Blackstone; + for (int i = 17453; i <= 17458; i++) + materials[i] = Material.BlackstoneSlab; + for (int i = 17049; i <= 17128; i++) + materials[i] = Material.BlackstoneStairs; + for (int i = 17129; i <= 17452; i++) + materials[i] = Material.BlackstoneWall; + for (int i = 16016; i <= 16023; i++) + materials[i] = Material.BlastFurnace; + for (int i = 8814; i <= 8829; i++) + materials[i] = Material.BlueBanner; + for (int i = 1455; i <= 1470; i++) + materials[i] = Material.BlueBed; + for (int i = 18505; i <= 18520; i++) + materials[i] = Material.BlueCandle; + for (int i = 18609; i <= 18610; i++) + materials[i] = Material.BlueCandleCake; + materials[8618] = Material.BlueCarpet; + materials[10330] = Material.BlueConcrete; + materials[10346] = Material.BlueConcretePowder; + for (int i = 10299; i <= 10302; i++) + materials[i] = Material.BlueGlazedTerracotta; + materials[10529] = Material.BlueIce; + materials[1668] = Material.BlueOrchid; + for (int i = 10225; i <= 10230; i++) + materials[i] = Material.BlueShulkerBox; + materials[4415] = Material.BlueStainedGlass; + for (int i = 7844; i <= 7875; i++) + materials[i] = Material.BlueStainedGlassPane; + materials[7487] = Material.BlueTerracotta; + for (int i = 8938; i <= 8941; i++) + materials[i] = Material.BlueWallBanner; + materials[1649] = Material.BlueWool; + for (int i = 10137; i <= 10139; i++) + materials[i] = Material.BoneBlock; + materials[1686] = Material.Bookshelf; + for (int i = 10413; i <= 10414; i++) + materials[i] = Material.BrainCoral; + materials[10397] = Material.BrainCoralBlock; + for (int i = 10433; i <= 10434; i++) + materials[i] = Material.BrainCoralFan; + for (int i = 10489; i <= 10496; i++) + materials[i] = Material.BrainCoralWallFan; + for (int i = 5720; i <= 5727; i++) + materials[i] = Material.BrewingStand; + for (int i = 9119; i <= 9124; i++) + materials[i] = Material.BrickSlab; + for (int i = 5359; i <= 5438; i++) + materials[i] = Material.BrickStairs; + for (int i = 11748; i <= 12071; i++) + materials[i] = Material.BrickWall; + materials[1683] = Material.Bricks; + for (int i = 8830; i <= 8845; i++) + materials[i] = Material.BrownBanner; + for (int i = 1471; i <= 1486; i++) + materials[i] = Material.BrownBed; + for (int i = 18521; i <= 18536; i++) + materials[i] = Material.BrownCandle; + for (int i = 18611; i <= 18612; i++) + materials[i] = Material.BrownCandleCake; + materials[8619] = Material.BrownCarpet; + materials[10331] = Material.BrownConcrete; + materials[10347] = Material.BrownConcretePowder; + for (int i = 10303; i <= 10306; i++) + materials[i] = Material.BrownGlazedTerracotta; + materials[1679] = Material.BrownMushroom; + for (int i = 4880; i <= 4943; i++) + materials[i] = Material.BrownMushroomBlock; + for (int i = 10231; i <= 10236; i++) + materials[i] = Material.BrownShulkerBox; + materials[4416] = Material.BrownStainedGlass; + for (int i = 7876; i <= 7907; i++) + materials[i] = Material.BrownStainedGlassPane; + materials[7488] = Material.BrownTerracotta; + for (int i = 8942; i <= 8945; i++) + materials[i] = Material.BrownWallBanner; + materials[1650] = Material.BrownWool; + for (int i = 10548; i <= 10549; i++) + materials[i] = Material.BubbleColumn; + for (int i = 10415; i <= 10416; i++) + materials[i] = Material.BubbleCoral; + materials[10398] = Material.BubbleCoralBlock; + for (int i = 10435; i <= 10436; i++) + materials[i] = Material.BubbleCoralFan; + for (int i = 10497; i <= 10504; i++) + materials[i] = Material.BubbleCoralWallFan; + materials[18620] = Material.BuddingAmethyst; + for (int i = 4240; i <= 4255; i++) + materials[i] = Material.Cactus; + for (int i = 4333; i <= 4339; i++) + materials[i] = Material.Cake; + materials[18670] = Material.Calcite; + for (int i = 16099; i <= 16130; i++) + materials[i] = Material.Campfire; + for (int i = 18313; i <= 18328; i++) + materials[i] = Material.Candle; + for (int i = 18585; i <= 18586; i++) + materials[i] = Material.CandleCake; + for (int i = 6923; i <= 6930; i++) + materials[i] = Material.Carrots; + materials[16024] = Material.CartographyTable; + for (int i = 4325; i <= 4328; i++) + materials[i] = Material.CarvedPumpkin; + materials[5728] = Material.Cauldron; + materials[10547] = Material.CaveAir; + for (int i = 19659; i <= 19710; i++) + materials[i] = Material.CaveVines; + for (int i = 19711; i <= 19712; i++) + materials[i] = Material.CaveVinesPlant; + for (int i = 5104; i <= 5109; i++) + materials[i] = Material.Chain; + for (int i = 10118; i <= 10129; i++) + materials[i] = Material.ChainCommandBlock; + for (int i = 2288; i <= 2311; i++) + materials[i] = Material.Chest; + for (int i = 7231; i <= 7234; i++) + materials[i] = Material.ChippedAnvil; + materials[21425] = Material.ChiseledDeepslate; + materials[18310] = Material.ChiseledNetherBricks; + materials[17462] = Material.ChiseledPolishedBlackstone; + materials[7356] = Material.ChiseledQuartzBlock; + materials[8959] = Material.ChiseledRedSandstone; + materials[477] = Material.ChiseledSandstone; + materials[4871] = Material.ChiseledStoneBricks; + for (int i = 10009; i <= 10014; i++) + materials[i] = Material.ChorusFlower; + for (int i = 9945; i <= 10008; i++) + materials[i] = Material.ChorusPlant; + materials[4256] = Material.Clay; + materials[8624] = Material.CoalBlock; + materials[114] = Material.CoalOre; + materials[11] = Material.CoarseDirt; + materials[19781] = Material.CobbledDeepslate; + for (int i = 19862; i <= 19867; i++) + materials[i] = Material.CobbledDeepslateSlab; + for (int i = 19782; i <= 19861; i++) + materials[i] = Material.CobbledDeepslateStairs; + for (int i = 19868; i <= 20191; i++) + materials[i] = Material.CobbledDeepslateWall; + materials[14] = Material.Cobblestone; + for (int i = 9113; i <= 9118; i++) + materials[i] = Material.CobblestoneSlab; + for (int i = 3952; i <= 4031; i++) + materials[i] = Material.CobblestoneStairs; + for (int i = 6249; i <= 6572; i++) + materials[i] = Material.CobblestoneWall; + materials[1595] = Material.Cobweb; + for (int i = 5749; i <= 5760; i++) + materials[i] = Material.Cocoa; + for (int i = 6236; i <= 6247; i++) + materials[i] = Material.CommandBlock; + for (int i = 7295; i <= 7310; i++) + materials[i] = Material.Comparator; + for (int i = 16960; i <= 16968; i++) + materials[i] = Material.Composter; + for (int i = 10530; i <= 10531; i++) + materials[i] = Material.Conduit; + materials[18911] = Material.CopperBlock; + materials[18912] = Material.CopperOre; + materials[1676] = Material.Cornflower; + materials[21426] = Material.CrackedDeepslateBricks; + materials[21427] = Material.CrackedDeepslateTiles; + materials[18311] = Material.CrackedNetherBricks; + materials[17461] = Material.CrackedPolishedBlackstoneBricks; + materials[4870] = Material.CrackedStoneBricks; + materials[3611] = Material.CraftingTable; + for (int i = 7187; i <= 7202; i++) + materials[i] = Material.CreeperHead; + for (int i = 7203; i <= 7206; i++) + materials[i] = Material.CreeperWallHead; + for (int i = 16688; i <= 16711; i++) + materials[i] = Material.CrimsonButton; + for (int i = 16736; i <= 16799; i++) + materials[i] = Material.CrimsonDoor; + for (int i = 16272; i <= 16303; i++) + materials[i] = Material.CrimsonFence; + for (int i = 16464; i <= 16495; i++) + materials[i] = Material.CrimsonFenceGate; + materials[16197] = Material.CrimsonFungus; + for (int i = 16190; i <= 16192; i++) + materials[i] = Material.CrimsonHyphae; + materials[16196] = Material.CrimsonNylium; + materials[16254] = Material.CrimsonPlanks; + for (int i = 16268; i <= 16269; i++) + materials[i] = Material.CrimsonPressurePlate; + materials[16253] = Material.CrimsonRoots; + for (int i = 16864; i <= 16895; i++) + materials[i] = Material.CrimsonSign; + for (int i = 16256; i <= 16261; i++) + materials[i] = Material.CrimsonSlab; + for (int i = 16528; i <= 16607; i++) + materials[i] = Material.CrimsonStairs; + for (int i = 16184; i <= 16186; i++) + materials[i] = Material.CrimsonStem; + for (int i = 16336; i <= 16399; i++) + materials[i] = Material.CrimsonTrapdoor; + for (int i = 16928; i <= 16935; i++) + materials[i] = Material.CrimsonWallSign; + materials[17037] = Material.CryingObsidian; + materials[18917] = Material.CutCopper; + for (int i = 19256; i <= 19261; i++) + materials[i] = Material.CutCopperSlab; + for (int i = 19158; i <= 19237; i++) + materials[i] = Material.CutCopperStairs; + materials[8960] = Material.CutRedSandstone; + for (int i = 9155; i <= 9160; i++) + materials[i] = Material.CutRedSandstoneSlab; + materials[478] = Material.CutSandstone; + for (int i = 9101; i <= 9106; i++) + materials[i] = Material.CutSandstoneSlab; + for (int i = 8782; i <= 8797; i++) + materials[i] = Material.CyanBanner; + for (int i = 1423; i <= 1438; i++) + materials[i] = Material.CyanBed; + for (int i = 18473; i <= 18488; i++) + materials[i] = Material.CyanCandle; + for (int i = 18605; i <= 18606; i++) + materials[i] = Material.CyanCandleCake; + materials[8616] = Material.CyanCarpet; + materials[10328] = Material.CyanConcrete; + materials[10344] = Material.CyanConcretePowder; + for (int i = 10291; i <= 10294; i++) + materials[i] = Material.CyanGlazedTerracotta; + for (int i = 10213; i <= 10218; i++) + materials[i] = Material.CyanShulkerBox; + materials[4413] = Material.CyanStainedGlass; + for (int i = 7780; i <= 7811; i++) + materials[i] = Material.CyanStainedGlassPane; + materials[7485] = Material.CyanTerracotta; + for (int i = 8930; i <= 8933; i++) + materials[i] = Material.CyanWallBanner; + materials[1647] = Material.CyanWool; + for (int i = 7235; i <= 7238; i++) + materials[i] = Material.DamagedAnvil; + materials[1666] = Material.Dandelion; + for (int i = 7059; i <= 7082; i++) + materials[i] = Material.DarkOakButton; + for (int i = 9811; i <= 9874; i++) + materials[i] = Material.DarkOakDoor; + for (int i = 9491; i <= 9522; i++) + materials[i] = Material.DarkOakFence; + for (int i = 9299; i <= 9330; i++) + materials[i] = Material.DarkOakFenceGate; + for (int i = 346; i <= 373; i++) + materials[i] = Material.DarkOakLeaves; + for (int i = 132; i <= 134; i++) + materials[i] = Material.DarkOakLog; + materials[20] = Material.DarkOakPlanks; + for (int i = 4188; i <= 4189; i++) + materials[i] = Material.DarkOakPressurePlate; + for (int i = 32; i <= 33; i++) + materials[i] = Material.DarkOakSapling; + for (int i = 3796; i <= 3827; i++) + materials[i] = Material.DarkOakSign; + for (int i = 9071; i <= 9076; i++) + materials[i] = Material.DarkOakSlab; + for (int i = 8084; i <= 8163; i++) + materials[i] = Material.DarkOakStairs; + for (int i = 4740; i <= 4803; i++) + materials[i] = Material.DarkOakTrapdoor; + for (int i = 4072; i <= 4079; i++) + materials[i] = Material.DarkOakWallSign; + for (int i = 179; i <= 181; i++) + materials[i] = Material.DarkOakWood; + materials[8344] = Material.DarkPrismarine; + for (int i = 8597; i <= 8602; i++) + materials[i] = Material.DarkPrismarineSlab; + for (int i = 8505; i <= 8584; i++) + materials[i] = Material.DarkPrismarineStairs; + for (int i = 7311; i <= 7342; i++) + materials[i] = Material.DaylightDetector; + for (int i = 10403; i <= 10404; i++) + materials[i] = Material.DeadBrainCoral; + materials[10392] = Material.DeadBrainCoralBlock; + for (int i = 10423; i <= 10424; i++) + materials[i] = Material.DeadBrainCoralFan; + for (int i = 10449; i <= 10456; i++) + materials[i] = Material.DeadBrainCoralWallFan; + for (int i = 10405; i <= 10406; i++) + materials[i] = Material.DeadBubbleCoral; + materials[10393] = Material.DeadBubbleCoralBlock; + for (int i = 10425; i <= 10426; i++) + materials[i] = Material.DeadBubbleCoralFan; + for (int i = 10457; i <= 10464; i++) + materials[i] = Material.DeadBubbleCoralWallFan; + materials[1598] = Material.DeadBush; + for (int i = 10407; i <= 10408; i++) + materials[i] = Material.DeadFireCoral; + materials[10394] = Material.DeadFireCoralBlock; + for (int i = 10427; i <= 10428; i++) + materials[i] = Material.DeadFireCoralFan; + for (int i = 10465; i <= 10472; i++) + materials[i] = Material.DeadFireCoralWallFan; + for (int i = 10409; i <= 10410; i++) + materials[i] = Material.DeadHornCoral; + materials[10395] = Material.DeadHornCoralBlock; + for (int i = 10429; i <= 10430; i++) + materials[i] = Material.DeadHornCoralFan; + for (int i = 10473; i <= 10480; i++) + materials[i] = Material.DeadHornCoralWallFan; + for (int i = 10401; i <= 10402; i++) + materials[i] = Material.DeadTubeCoral; + materials[10391] = Material.DeadTubeCoralBlock; + for (int i = 10421; i <= 10422; i++) + materials[i] = Material.DeadTubeCoralFan; + for (int i = 10441; i <= 10448; i++) + materials[i] = Material.DeadTubeCoralWallFan; + for (int i = 19778; i <= 19780; i++) + materials[i] = Material.Deepslate; + for (int i = 21095; i <= 21100; i++) + materials[i] = Material.DeepslateBrickSlab; + for (int i = 21015; i <= 21094; i++) + materials[i] = Material.DeepslateBrickStairs; + for (int i = 21101; i <= 21424; i++) + materials[i] = Material.DeepslateBrickWall; + materials[21014] = Material.DeepslateBricks; + materials[115] = Material.DeepslateCoalOre; + materials[18913] = Material.DeepslateCopperOre; + materials[3609] = Material.DeepslateDiamondOre; + materials[5842] = Material.DeepslateEmeraldOre; + materials[111] = Material.DeepslateGoldOre; + materials[113] = Material.DeepslateIronOre; + materials[462] = Material.DeepslateLapisOre; + for (int i = 4194; i <= 4195; i++) + materials[i] = Material.DeepslateRedstoneOre; + for (int i = 20684; i <= 20689; i++) + materials[i] = Material.DeepslateTileSlab; + for (int i = 20604; i <= 20683; i++) + materials[i] = Material.DeepslateTileStairs; + for (int i = 20690; i <= 21013; i++) + materials[i] = Material.DeepslateTileWall; + materials[20603] = Material.DeepslateTiles; + for (int i = 1559; i <= 1582; i++) + materials[i] = Material.DetectorRail; + materials[3610] = Material.DiamondBlock; + materials[3608] = Material.DiamondOre; + materials[4] = Material.Diorite; + for (int i = 11742; i <= 11747; i++) + materials[i] = Material.DioriteSlab; + for (int i = 11590; i <= 11669; i++) + materials[i] = Material.DioriteStairs; + for (int i = 15636; i <= 15959; i++) + materials[i] = Material.DioriteWall; + materials[10] = Material.Dirt; + materials[10104] = Material.DirtPath; + for (int i = 464; i <= 475; i++) + materials[i] = Material.Dispenser; + materials[5746] = Material.DragonEgg; + for (int i = 7207; i <= 7222; i++) + materials[i] = Material.DragonHead; + for (int i = 7223; i <= 7226; i++) + materials[i] = Material.DragonWallHead; + materials[10378] = Material.DriedKelpBlock; + materials[19658] = Material.DripstoneBlock; + for (int i = 7464; i <= 7475; i++) + materials[i] = Material.Dropper; + materials[5995] = Material.EmeraldBlock; + materials[5841] = Material.EmeraldOre; + materials[5719] = Material.EnchantingTable; + materials[10105] = Material.EndGateway; + materials[5736] = Material.EndPortal; + for (int i = 5737; i <= 5744; i++) + materials[i] = Material.EndPortalFrame; + for (int i = 9939; i <= 9944; i++) + materials[i] = Material.EndRod; + materials[5745] = Material.EndStone; + for (int i = 11700; i <= 11705; i++) + materials[i] = Material.EndStoneBrickSlab; + for (int i = 10950; i <= 11029; i++) + materials[i] = Material.EndStoneBrickStairs; + for (int i = 15312; i <= 15635; i++) + materials[i] = Material.EndStoneBrickWall; + materials[10099] = Material.EndStoneBricks; + for (int i = 5843; i <= 5850; i++) + materials[i] = Material.EnderChest; + materials[18910] = Material.ExposedCopper; + materials[18916] = Material.ExposedCutCopper; + for (int i = 19250; i <= 19255; i++) + materials[i] = Material.ExposedCutCopperSlab; + for (int i = 19078; i <= 19157; i++) + materials[i] = Material.ExposedCutCopperStairs; + for (int i = 3620; i <= 3627; i++) + materials[i] = Material.Farmland; + materials[1597] = Material.Fern; + for (int i = 1694; i <= 2205; i++) + materials[i] = Material.Fire; + for (int i = 10417; i <= 10418; i++) + materials[i] = Material.FireCoral; + materials[10399] = Material.FireCoralBlock; + for (int i = 10437; i <= 10438; i++) + materials[i] = Material.FireCoralFan; + for (int i = 10505; i <= 10512; i++) + materials[i] = Material.FireCoralWallFan; + materials[16025] = Material.FletchingTable; + materials[6897] = Material.FlowerPot; + materials[19715] = Material.FloweringAzalea; + for (int i = 430; i <= 457; i++) + materials[i] = Material.FloweringAzaleaLeaves; + materials[21446] = Material.Frogspawn; + for (int i = 10130; i <= 10133; i++) + materials[i] = Material.FrostedIce; + for (int i = 3628; i <= 3635; i++) + materials[i] = Material.Furnace; + materials[17873] = Material.GildedBlackstone; + materials[460] = Material.Glass; + for (int i = 5110; i <= 5141; i++) + materials[i] = Material.GlassPane; + for (int i = 5199; i <= 5326; i++) + materials[i] = Material.GlowLichen; + materials[4322] = Material.Glowstone; + materials[1681] = Material.GoldBlock; + materials[110] = Material.GoldOre; + materials[2] = Material.Granite; + for (int i = 11718; i <= 11723; i++) + materials[i] = Material.GraniteSlab; + for (int i = 11270; i <= 11349; i++) + materials[i] = Material.GraniteStairs; + for (int i = 13044; i <= 13367; i++) + materials[i] = Material.GraniteWall; + materials[1596] = Material.Grass; + for (int i = 8; i <= 9; i++) + materials[i] = Material.GrassBlock; + materials[109] = Material.Gravel; + for (int i = 8750; i <= 8765; i++) + materials[i] = Material.GrayBanner; + for (int i = 1391; i <= 1406; i++) + materials[i] = Material.GrayBed; + for (int i = 18441; i <= 18456; i++) + materials[i] = Material.GrayCandle; + for (int i = 18601; i <= 18602; i++) + materials[i] = Material.GrayCandleCake; + materials[8614] = Material.GrayCarpet; + materials[10326] = Material.GrayConcrete; + materials[10342] = Material.GrayConcretePowder; + for (int i = 10283; i <= 10286; i++) + materials[i] = Material.GrayGlazedTerracotta; + for (int i = 10201; i <= 10206; i++) + materials[i] = Material.GrayShulkerBox; + materials[4411] = Material.GrayStainedGlass; + for (int i = 7716; i <= 7747; i++) + materials[i] = Material.GrayStainedGlassPane; + materials[7483] = Material.GrayTerracotta; + for (int i = 8922; i <= 8925; i++) + materials[i] = Material.GrayWallBanner; + materials[1645] = Material.GrayWool; + for (int i = 8846; i <= 8861; i++) + materials[i] = Material.GreenBanner; + for (int i = 1487; i <= 1502; i++) + materials[i] = Material.GreenBed; + for (int i = 18537; i <= 18552; i++) + materials[i] = Material.GreenCandle; + for (int i = 18613; i <= 18614; i++) + materials[i] = Material.GreenCandleCake; + materials[8620] = Material.GreenCarpet; + materials[10332] = Material.GreenConcrete; + materials[10348] = Material.GreenConcretePowder; + for (int i = 10307; i <= 10310; i++) + materials[i] = Material.GreenGlazedTerracotta; + for (int i = 10237; i <= 10242; i++) + materials[i] = Material.GreenShulkerBox; + materials[4417] = Material.GreenStainedGlass; + for (int i = 7908; i <= 7939; i++) + materials[i] = Material.GreenStainedGlassPane; + materials[7489] = Material.GreenTerracotta; + for (int i = 8946; i <= 8949; i++) + materials[i] = Material.GreenWallBanner; + materials[1651] = Material.GreenWool; + for (int i = 16026; i <= 16037; i++) + materials[i] = Material.Grindstone; + for (int i = 19774; i <= 19775; i++) + materials[i] = Material.HangingRoots; + for (int i = 8604; i <= 8606; i++) + materials[i] = Material.HayBlock; + for (int i = 7279; i <= 7294; i++) + materials[i] = Material.HeavyWeightedPressurePlate; + materials[17033] = Material.HoneyBlock; + materials[17034] = Material.HoneycombBlock; + for (int i = 7345; i <= 7354; i++) + materials[i] = Material.Hopper; + for (int i = 10419; i <= 10420; i++) + materials[i] = Material.HornCoral; + materials[10400] = Material.HornCoralBlock; + for (int i = 10439; i <= 10440; i++) + materials[i] = Material.HornCoralFan; + for (int i = 10513; i <= 10520; i++) + materials[i] = Material.HornCoralWallFan; + materials[4238] = Material.Ice; + materials[4879] = Material.InfestedChiseledStoneBricks; + materials[4875] = Material.InfestedCobblestone; + materials[4878] = Material.InfestedCrackedStoneBricks; + for (int i = 21428; i <= 21430; i++) + materials[i] = Material.InfestedDeepslate; + materials[4877] = Material.InfestedMossyStoneBricks; + materials[4874] = Material.InfestedStone; + materials[4876] = Material.InfestedStoneBricks; + for (int i = 5072; i <= 5103; i++) + materials[i] = Material.IronBars; + materials[1682] = Material.IronBlock; + for (int i = 4114; i <= 4177; i++) + materials[i] = Material.IronDoor; + materials[112] = Material.IronOre; + for (int i = 8278; i <= 8341; i++) + materials[i] = Material.IronTrapdoor; + for (int i = 4329; i <= 4332; i++) + materials[i] = Material.JackOLantern; + for (int i = 16948; i <= 16959; i++) + materials[i] = Material.Jigsaw; + for (int i = 4273; i <= 4274; i++) + materials[i] = Material.Jukebox; + for (int i = 7011; i <= 7034; i++) + materials[i] = Material.JungleButton; + for (int i = 9683; i <= 9746; i++) + materials[i] = Material.JungleDoor; + for (int i = 9427; i <= 9458; i++) + materials[i] = Material.JungleFence; + for (int i = 9235; i <= 9266; i++) + materials[i] = Material.JungleFenceGate; + for (int i = 290; i <= 317; i++) + materials[i] = Material.JungleLeaves; + for (int i = 126; i <= 128; i++) + materials[i] = Material.JungleLog; + materials[18] = Material.JunglePlanks; + for (int i = 4184; i <= 4185; i++) + materials[i] = Material.JunglePressurePlate; + for (int i = 28; i <= 29; i++) + materials[i] = Material.JungleSapling; + for (int i = 3764; i <= 3795; i++) + materials[i] = Material.JungleSign; + for (int i = 9059; i <= 9064; i++) + materials[i] = Material.JungleSlab; + for (int i = 6156; i <= 6235; i++) + materials[i] = Material.JungleStairs; + for (int i = 4612; i <= 4675; i++) + materials[i] = Material.JungleTrapdoor; + for (int i = 4064; i <= 4071; i++) + materials[i] = Material.JungleWallSign; + for (int i = 173; i <= 175; i++) + materials[i] = Material.JungleWood; + for (int i = 10351; i <= 10376; i++) + materials[i] = Material.Kelp; + materials[10377] = Material.KelpPlant; + for (int i = 3924; i <= 3931; i++) + materials[i] = Material.Ladder; + for (int i = 16091; i <= 16094; i++) + materials[i] = Material.Lantern; + materials[463] = Material.LapisBlock; + materials[461] = Material.LapisOre; + for (int i = 18633; i <= 18644; i++) + materials[i] = Material.LargeAmethystBud; + for (int i = 8636; i <= 8637; i++) + materials[i] = Material.LargeFern; + for (int i = 91; i <= 106; i++) + materials[i] = Material.Lava; + materials[5732] = Material.LavaCauldron; + for (int i = 16038; i <= 16053; i++) + materials[i] = Material.Lectern; + for (int i = 4088; i <= 4111; i++) + materials[i] = Material.Lever; + for (int i = 8246; i <= 8277; i++) + materials[i] = Material.Light; + for (int i = 8686; i <= 8701; i++) + materials[i] = Material.LightBlueBanner; + for (int i = 1327; i <= 1342; i++) + materials[i] = Material.LightBlueBed; + for (int i = 18377; i <= 18392; i++) + materials[i] = Material.LightBlueCandle; + for (int i = 18593; i <= 18594; i++) + materials[i] = Material.LightBlueCandleCake; + materials[8610] = Material.LightBlueCarpet; + materials[10322] = Material.LightBlueConcrete; + materials[10338] = Material.LightBlueConcretePowder; + for (int i = 10267; i <= 10270; i++) + materials[i] = Material.LightBlueGlazedTerracotta; + for (int i = 10177; i <= 10182; i++) + materials[i] = Material.LightBlueShulkerBox; + materials[4407] = Material.LightBlueStainedGlass; + for (int i = 7588; i <= 7619; i++) + materials[i] = Material.LightBlueStainedGlassPane; + materials[7479] = Material.LightBlueTerracotta; + for (int i = 8906; i <= 8909; i++) + materials[i] = Material.LightBlueWallBanner; + materials[1641] = Material.LightBlueWool; + for (int i = 8766; i <= 8781; i++) + materials[i] = Material.LightGrayBanner; + for (int i = 1407; i <= 1422; i++) + materials[i] = Material.LightGrayBed; + for (int i = 18457; i <= 18472; i++) + materials[i] = Material.LightGrayCandle; + for (int i = 18603; i <= 18604; i++) + materials[i] = Material.LightGrayCandleCake; + materials[8615] = Material.LightGrayCarpet; + materials[10327] = Material.LightGrayConcrete; + materials[10343] = Material.LightGrayConcretePowder; + for (int i = 10287; i <= 10290; i++) + materials[i] = Material.LightGrayGlazedTerracotta; + for (int i = 10207; i <= 10212; i++) + materials[i] = Material.LightGrayShulkerBox; + materials[4412] = Material.LightGrayStainedGlass; + for (int i = 7748; i <= 7779; i++) + materials[i] = Material.LightGrayStainedGlassPane; + materials[7484] = Material.LightGrayTerracotta; + for (int i = 8926; i <= 8929; i++) + materials[i] = Material.LightGrayWallBanner; + materials[1646] = Material.LightGrayWool; + for (int i = 7263; i <= 7278; i++) + materials[i] = Material.LightWeightedPressurePlate; + for (int i = 19614; i <= 19637; i++) + materials[i] = Material.LightningRod; + for (int i = 8628; i <= 8629; i++) + materials[i] = Material.Lilac; + materials[1678] = Material.LilyOfTheValley; + materials[5601] = Material.LilyPad; + for (int i = 8718; i <= 8733; i++) + materials[i] = Material.LimeBanner; + for (int i = 1359; i <= 1374; i++) + materials[i] = Material.LimeBed; + for (int i = 18409; i <= 18424; i++) + materials[i] = Material.LimeCandle; + for (int i = 18597; i <= 18598; i++) + materials[i] = Material.LimeCandleCake; + materials[8612] = Material.LimeCarpet; + materials[10324] = Material.LimeConcrete; + materials[10340] = Material.LimeConcretePowder; + for (int i = 10275; i <= 10278; i++) + materials[i] = Material.LimeGlazedTerracotta; + for (int i = 10189; i <= 10194; i++) + materials[i] = Material.LimeShulkerBox; + materials[4409] = Material.LimeStainedGlass; + for (int i = 7652; i <= 7683; i++) + materials[i] = Material.LimeStainedGlassPane; + materials[7481] = Material.LimeTerracotta; + for (int i = 8914; i <= 8917; i++) + materials[i] = Material.LimeWallBanner; + materials[1643] = Material.LimeWool; + materials[17047] = Material.Lodestone; + for (int i = 15992; i <= 15995; i++) + materials[i] = Material.Loom; + for (int i = 8670; i <= 8685; i++) + materials[i] = Material.MagentaBanner; + for (int i = 1311; i <= 1326; i++) + materials[i] = Material.MagentaBed; + for (int i = 18361; i <= 18376; i++) + materials[i] = Material.MagentaCandle; + for (int i = 18591; i <= 18592; i++) + materials[i] = Material.MagentaCandleCake; + materials[8609] = Material.MagentaCarpet; + materials[10321] = Material.MagentaConcrete; + materials[10337] = Material.MagentaConcretePowder; + for (int i = 10263; i <= 10266; i++) + materials[i] = Material.MagentaGlazedTerracotta; + for (int i = 10171; i <= 10176; i++) + materials[i] = Material.MagentaShulkerBox; + materials[4406] = Material.MagentaStainedGlass; + for (int i = 7556; i <= 7587; i++) + materials[i] = Material.MagentaStainedGlassPane; + materials[7478] = Material.MagentaTerracotta; + for (int i = 8902; i <= 8905; i++) + materials[i] = Material.MagentaWallBanner; + materials[1640] = Material.MagentaWool; + materials[10134] = Material.MagmaBlock; + for (int i = 7083; i <= 7106; i++) + materials[i] = Material.MangroveButton; + for (int i = 9875; i <= 9938; i++) + materials[i] = Material.MangroveDoor; + for (int i = 9523; i <= 9554; i++) + materials[i] = Material.MangroveFence; + for (int i = 9331; i <= 9362; i++) + materials[i] = Material.MangroveFenceGate; + for (int i = 374; i <= 401; i++) + materials[i] = Material.MangroveLeaves; + for (int i = 135; i <= 137; i++) + materials[i] = Material.MangroveLog; + materials[21] = Material.MangrovePlanks; + for (int i = 4190; i <= 4191; i++) + materials[i] = Material.MangrovePressurePlate; + for (int i = 34; i <= 73; i++) + materials[i] = Material.MangrovePropagule; + for (int i = 138; i <= 139; i++) + materials[i] = Material.MangroveRoots; + for (int i = 3828; i <= 3859; i++) + materials[i] = Material.MangroveSign; + for (int i = 9077; i <= 9082; i++) + materials[i] = Material.MangroveSlab; + for (int i = 8164; i <= 8243; i++) + materials[i] = Material.MangroveStairs; + for (int i = 4804; i <= 4867; i++) + materials[i] = Material.MangroveTrapdoor; + for (int i = 4080; i <= 4087; i++) + materials[i] = Material.MangroveWallSign; + for (int i = 182; i <= 184; i++) + materials[i] = Material.MangroveWood; + for (int i = 18645; i <= 18656; i++) + materials[i] = Material.MediumAmethystBud; + materials[5142] = Material.Melon; + for (int i = 5159; i <= 5166; i++) + materials[i] = Material.MelonStem; + materials[19717] = Material.MossBlock; + materials[19716] = Material.MossCarpet; + materials[1687] = Material.MossyCobblestone; + for (int i = 11694; i <= 11699; i++) + materials[i] = Material.MossyCobblestoneSlab; + for (int i = 10870; i <= 10949; i++) + materials[i] = Material.MossyCobblestoneStairs; + for (int i = 6573; i <= 6896; i++) + materials[i] = Material.MossyCobblestoneWall; + for (int i = 11682; i <= 11687; i++) + materials[i] = Material.MossyStoneBrickSlab; + for (int i = 10710; i <= 10789; i++) + materials[i] = Material.MossyStoneBrickStairs; + for (int i = 12720; i <= 13043; i++) + materials[i] = Material.MossyStoneBrickWall; + materials[4869] = Material.MossyStoneBricks; + for (int i = 1654; i <= 1665; i++) + materials[i] = Material.MovingPiston; + materials[19777] = Material.Mud; + for (int i = 9131; i <= 9136; i++) + materials[i] = Material.MudBrickSlab; + for (int i = 5519; i <= 5598; i++) + materials[i] = Material.MudBrickStairs; + for (int i = 13692; i <= 14015; i++) + materials[i] = Material.MudBrickWall; + materials[4873] = Material.MudBricks; + for (int i = 140; i <= 142; i++) + materials[i] = Material.MuddyMangroveRoots; + for (int i = 5008; i <= 5071; i++) + materials[i] = Material.MushroomStem; + for (int i = 5599; i <= 5600; i++) + materials[i] = Material.Mycelium; + for (int i = 5603; i <= 5634; i++) + materials[i] = Material.NetherBrickFence; + for (int i = 9137; i <= 9142; i++) + materials[i] = Material.NetherBrickSlab; + for (int i = 5635; i <= 5714; i++) + materials[i] = Material.NetherBrickStairs; + for (int i = 14016; i <= 14339; i++) + materials[i] = Material.NetherBrickWall; + materials[5602] = Material.NetherBricks; + materials[116] = Material.NetherGoldOre; + for (int i = 4323; i <= 4324; i++) + materials[i] = Material.NetherPortal; + materials[7344] = Material.NetherQuartzOre; + materials[16183] = Material.NetherSprouts; + for (int i = 5715; i <= 5718; i++) + materials[i] = Material.NetherWart; + materials[10135] = Material.NetherWartBlock; + materials[17035] = Material.NetheriteBlock; + materials[4308] = Material.Netherrack; + for (int i = 479; i <= 1278; i++) + materials[i] = Material.NoteBlock; + for (int i = 6939; i <= 6962; i++) + materials[i] = Material.OakButton; + for (int i = 3860; i <= 3923; i++) + materials[i] = Material.OakDoor; + for (int i = 4275; i <= 4306; i++) + materials[i] = Material.OakFence; + for (int i = 5327; i <= 5358; i++) + materials[i] = Material.OakFenceGate; + for (int i = 206; i <= 233; i++) + materials[i] = Material.OakLeaves; + for (int i = 117; i <= 119; i++) + materials[i] = Material.OakLog; + materials[15] = Material.OakPlanks; + for (int i = 4178; i <= 4179; i++) + materials[i] = Material.OakPressurePlate; + for (int i = 22; i <= 23; i++) + materials[i] = Material.OakSapling; + for (int i = 3636; i <= 3667; i++) + materials[i] = Material.OakSign; + for (int i = 9041; i <= 9046; i++) + materials[i] = Material.OakSlab; + for (int i = 2208; i <= 2287; i++) + materials[i] = Material.OakStairs; + for (int i = 4420; i <= 4483; i++) + materials[i] = Material.OakTrapdoor; + for (int i = 4032; i <= 4039; i++) + materials[i] = Material.OakWallSign; + for (int i = 164; i <= 166; i++) + materials[i] = Material.OakWood; + for (int i = 10141; i <= 10152; i++) + materials[i] = Material.Observer; + materials[1688] = Material.Obsidian; + for (int i = 21437; i <= 21439; i++) + materials[i] = Material.OchreFroglight; + for (int i = 8654; i <= 8669; i++) + materials[i] = Material.OrangeBanner; + for (int i = 1295; i <= 1310; i++) + materials[i] = Material.OrangeBed; + for (int i = 18345; i <= 18360; i++) + materials[i] = Material.OrangeCandle; + for (int i = 18589; i <= 18590; i++) + materials[i] = Material.OrangeCandleCake; + materials[8608] = Material.OrangeCarpet; + materials[10320] = Material.OrangeConcrete; + materials[10336] = Material.OrangeConcretePowder; + for (int i = 10259; i <= 10262; i++) + materials[i] = Material.OrangeGlazedTerracotta; + for (int i = 10165; i <= 10170; i++) + materials[i] = Material.OrangeShulkerBox; + materials[4405] = Material.OrangeStainedGlass; + for (int i = 7524; i <= 7555; i++) + materials[i] = Material.OrangeStainedGlassPane; + materials[7477] = Material.OrangeTerracotta; + materials[1672] = Material.OrangeTulip; + for (int i = 8898; i <= 8901; i++) + materials[i] = Material.OrangeWallBanner; + materials[1639] = Material.OrangeWool; + materials[1675] = Material.OxeyeDaisy; + materials[18908] = Material.OxidizedCopper; + materials[18914] = Material.OxidizedCutCopper; + for (int i = 19238; i <= 19243; i++) + materials[i] = Material.OxidizedCutCopperSlab; + for (int i = 18918; i <= 18997; i++) + materials[i] = Material.OxidizedCutCopperStairs; + materials[8625] = Material.PackedIce; + materials[4872] = Material.PackedMud; + for (int i = 21443; i <= 21445; i++) + materials[i] = Material.PearlescentFroglight; + for (int i = 8632; i <= 8633; i++) + materials[i] = Material.Peony; + for (int i = 9107; i <= 9112; i++) + materials[i] = Material.PetrifiedOakSlab; + for (int i = 8734; i <= 8749; i++) + materials[i] = Material.PinkBanner; + for (int i = 1375; i <= 1390; i++) + materials[i] = Material.PinkBed; + for (int i = 18425; i <= 18440; i++) + materials[i] = Material.PinkCandle; + for (int i = 18599; i <= 18600; i++) + materials[i] = Material.PinkCandleCake; + materials[8613] = Material.PinkCarpet; + materials[10325] = Material.PinkConcrete; + materials[10341] = Material.PinkConcretePowder; + for (int i = 10279; i <= 10282; i++) + materials[i] = Material.PinkGlazedTerracotta; + for (int i = 10195; i <= 10200; i++) + materials[i] = Material.PinkShulkerBox; + materials[4410] = Material.PinkStainedGlass; + for (int i = 7684; i <= 7715; i++) + materials[i] = Material.PinkStainedGlassPane; + materials[7482] = Material.PinkTerracotta; + materials[1674] = Material.PinkTulip; + for (int i = 8918; i <= 8921; i++) + materials[i] = Material.PinkWallBanner; + materials[1644] = Material.PinkWool; + for (int i = 1602; i <= 1613; i++) + materials[i] = Material.Piston; + for (int i = 1614; i <= 1637; i++) + materials[i] = Material.PistonHead; + for (int i = 7167; i <= 7182; i++) + materials[i] = Material.PlayerHead; + for (int i = 7183; i <= 7186; i++) + materials[i] = Material.PlayerWallHead; + for (int i = 12; i <= 13; i++) + materials[i] = Material.Podzol; + for (int i = 19638; i <= 19657; i++) + materials[i] = Material.PointedDripstone; + materials[7] = Material.PolishedAndesite; + for (int i = 11736; i <= 11741; i++) + materials[i] = Material.PolishedAndesiteSlab; + for (int i = 11510; i <= 11589; i++) + materials[i] = Material.PolishedAndesiteStairs; + for (int i = 4314; i <= 4316; i++) + materials[i] = Material.PolishedBasalt; + materials[17459] = Material.PolishedBlackstone; + for (int i = 17463; i <= 17468; i++) + materials[i] = Material.PolishedBlackstoneBrickSlab; + for (int i = 17469; i <= 17548; i++) + materials[i] = Material.PolishedBlackstoneBrickStairs; + for (int i = 17549; i <= 17872; i++) + materials[i] = Material.PolishedBlackstoneBrickWall; + materials[17460] = Material.PolishedBlackstoneBricks; + for (int i = 17962; i <= 17985; i++) + materials[i] = Material.PolishedBlackstoneButton; + for (int i = 17960; i <= 17961; i++) + materials[i] = Material.PolishedBlackstonePressurePlate; + for (int i = 17954; i <= 17959; i++) + materials[i] = Material.PolishedBlackstoneSlab; + for (int i = 17874; i <= 17953; i++) + materials[i] = Material.PolishedBlackstoneStairs; + for (int i = 17986; i <= 18309; i++) + materials[i] = Material.PolishedBlackstoneWall; + materials[20192] = Material.PolishedDeepslate; + for (int i = 20273; i <= 20278; i++) + materials[i] = Material.PolishedDeepslateSlab; + for (int i = 20193; i <= 20272; i++) + materials[i] = Material.PolishedDeepslateStairs; + for (int i = 20279; i <= 20602; i++) + materials[i] = Material.PolishedDeepslateWall; + materials[5] = Material.PolishedDiorite; + for (int i = 11688; i <= 11693; i++) + materials[i] = Material.PolishedDioriteSlab; + for (int i = 10790; i <= 10869; i++) + materials[i] = Material.PolishedDioriteStairs; + materials[3] = Material.PolishedGranite; + for (int i = 11670; i <= 11675; i++) + materials[i] = Material.PolishedGraniteSlab; + for (int i = 10550; i <= 10629; i++) + materials[i] = Material.PolishedGraniteStairs; + materials[1667] = Material.Poppy; + for (int i = 6931; i <= 6938; i++) + materials[i] = Material.Potatoes; + materials[6902] = Material.PottedAcaciaSapling; + materials[6909] = Material.PottedAllium; + materials[21435] = Material.PottedAzaleaBush; + materials[6910] = Material.PottedAzureBluet; + materials[10545] = Material.PottedBamboo; + materials[6900] = Material.PottedBirchSapling; + materials[6908] = Material.PottedBlueOrchid; + materials[6920] = Material.PottedBrownMushroom; + materials[6922] = Material.PottedCactus; + materials[6916] = Material.PottedCornflower; + materials[17043] = Material.PottedCrimsonFungus; + materials[17045] = Material.PottedCrimsonRoots; + materials[6906] = Material.PottedDandelion; + materials[6903] = Material.PottedDarkOakSapling; + materials[6921] = Material.PottedDeadBush; + materials[6905] = Material.PottedFern; + materials[21436] = Material.PottedFloweringAzaleaBush; + materials[6901] = Material.PottedJungleSapling; + materials[6917] = Material.PottedLilyOfTheValley; + materials[6904] = Material.PottedMangrovePropagule; + materials[6898] = Material.PottedOakSapling; + materials[6912] = Material.PottedOrangeTulip; + materials[6915] = Material.PottedOxeyeDaisy; + materials[6914] = Material.PottedPinkTulip; + materials[6907] = Material.PottedPoppy; + materials[6919] = Material.PottedRedMushroom; + materials[6911] = Material.PottedRedTulip; + materials[6899] = Material.PottedSpruceSapling; + materials[17044] = Material.PottedWarpedFungus; + materials[17046] = Material.PottedWarpedRoots; + materials[6913] = Material.PottedWhiteTulip; + materials[6918] = Material.PottedWitherRose; + materials[18672] = Material.PowderSnow; + for (int i = 5733; i <= 5735; i++) + materials[i] = Material.PowderSnowCauldron; + for (int i = 1535; i <= 1558; i++) + materials[i] = Material.PoweredRail; + materials[8342] = Material.Prismarine; + for (int i = 8591; i <= 8596; i++) + materials[i] = Material.PrismarineBrickSlab; + for (int i = 8425; i <= 8504; i++) + materials[i] = Material.PrismarineBrickStairs; + materials[8343] = Material.PrismarineBricks; + for (int i = 8585; i <= 8590; i++) + materials[i] = Material.PrismarineSlab; + for (int i = 8345; i <= 8424; i++) + materials[i] = Material.PrismarineStairs; + for (int i = 12072; i <= 12395; i++) + materials[i] = Material.PrismarineWall; + materials[4307] = Material.Pumpkin; + for (int i = 5151; i <= 5158; i++) + materials[i] = Material.PumpkinStem; + for (int i = 8798; i <= 8813; i++) + materials[i] = Material.PurpleBanner; + for (int i = 1439; i <= 1454; i++) + materials[i] = Material.PurpleBed; + for (int i = 18489; i <= 18504; i++) + materials[i] = Material.PurpleCandle; + for (int i = 18607; i <= 18608; i++) + materials[i] = Material.PurpleCandleCake; + materials[8617] = Material.PurpleCarpet; + materials[10329] = Material.PurpleConcrete; + materials[10345] = Material.PurpleConcretePowder; + for (int i = 10295; i <= 10298; i++) + materials[i] = Material.PurpleGlazedTerracotta; + for (int i = 10219; i <= 10224; i++) + materials[i] = Material.PurpleShulkerBox; + materials[4414] = Material.PurpleStainedGlass; + for (int i = 7812; i <= 7843; i++) + materials[i] = Material.PurpleStainedGlassPane; + materials[7486] = Material.PurpleTerracotta; + for (int i = 8934; i <= 8937; i++) + materials[i] = Material.PurpleWallBanner; + materials[1648] = Material.PurpleWool; + materials[10015] = Material.PurpurBlock; + for (int i = 10016; i <= 10018; i++) + materials[i] = Material.PurpurPillar; + for (int i = 9161; i <= 9166; i++) + materials[i] = Material.PurpurSlab; + for (int i = 10019; i <= 10098; i++) + materials[i] = Material.PurpurStairs; + materials[7355] = Material.QuartzBlock; + materials[18312] = Material.QuartzBricks; + for (int i = 7357; i <= 7359; i++) + materials[i] = Material.QuartzPillar; + for (int i = 9143; i <= 9148; i++) + materials[i] = Material.QuartzSlab; + for (int i = 7360; i <= 7439; i++) + materials[i] = Material.QuartzStairs; + for (int i = 3932; i <= 3951; i++) + materials[i] = Material.Rail; + materials[21433] = Material.RawCopperBlock; + materials[21434] = Material.RawGoldBlock; + materials[21432] = Material.RawIronBlock; + for (int i = 8862; i <= 8877; i++) + materials[i] = Material.RedBanner; + for (int i = 1503; i <= 1518; i++) + materials[i] = Material.RedBed; + for (int i = 18553; i <= 18568; i++) + materials[i] = Material.RedCandle; + for (int i = 18615; i <= 18616; i++) + materials[i] = Material.RedCandleCake; + materials[8621] = Material.RedCarpet; + materials[10333] = Material.RedConcrete; + materials[10349] = Material.RedConcretePowder; + for (int i = 10311; i <= 10314; i++) + materials[i] = Material.RedGlazedTerracotta; + materials[1680] = Material.RedMushroom; + for (int i = 4944; i <= 5007; i++) + materials[i] = Material.RedMushroomBlock; + for (int i = 11730; i <= 11735; i++) + materials[i] = Material.RedNetherBrickSlab; + for (int i = 11430; i <= 11509; i++) + materials[i] = Material.RedNetherBrickStairs; + for (int i = 14664; i <= 14987; i++) + materials[i] = Material.RedNetherBrickWall; + materials[10136] = Material.RedNetherBricks; + materials[108] = Material.RedSand; + materials[8958] = Material.RedSandstone; + for (int i = 9149; i <= 9154; i++) + materials[i] = Material.RedSandstoneSlab; + for (int i = 8961; i <= 9040; i++) + materials[i] = Material.RedSandstoneStairs; + for (int i = 12396; i <= 12719; i++) + materials[i] = Material.RedSandstoneWall; + for (int i = 10243; i <= 10248; i++) + materials[i] = Material.RedShulkerBox; + materials[4418] = Material.RedStainedGlass; + for (int i = 7940; i <= 7971; i++) + materials[i] = Material.RedStainedGlassPane; + materials[7490] = Material.RedTerracotta; + materials[1671] = Material.RedTulip; + for (int i = 8950; i <= 8953; i++) + materials[i] = Material.RedWallBanner; + materials[1652] = Material.RedWool; + materials[7343] = Material.RedstoneBlock; + for (int i = 5747; i <= 5748; i++) + materials[i] = Material.RedstoneLamp; + for (int i = 4192; i <= 4193; i++) + materials[i] = Material.RedstoneOre; + for (int i = 4196; i <= 4197; i++) + materials[i] = Material.RedstoneTorch; + for (int i = 4198; i <= 4205; i++) + materials[i] = Material.RedstoneWallTorch; + for (int i = 2312; i <= 3607; i++) + materials[i] = Material.RedstoneWire; + materials[21447] = Material.ReinforcedDeepslate; + for (int i = 4340; i <= 4403; i++) + materials[i] = Material.Repeater; + for (int i = 10106; i <= 10117; i++) + materials[i] = Material.RepeatingCommandBlock; + for (int i = 17038; i <= 17042; i++) + materials[i] = Material.RespawnAnchor; + materials[19776] = Material.RootedDirt; + for (int i = 8630; i <= 8631; i++) + materials[i] = Material.RoseBush; + materials[107] = Material.Sand; + materials[476] = Material.Sandstone; + for (int i = 9095; i <= 9100; i++) + materials[i] = Material.SandstoneSlab; + for (int i = 5761; i <= 5840; i++) + materials[i] = Material.SandstoneStairs; + for (int i = 14988; i <= 15311; i++) + materials[i] = Material.SandstoneWall; + for (int i = 15960; i <= 15991; i++) + materials[i] = Material.Scaffolding; + materials[18769] = Material.Sculk; + for (int i = 18898; i <= 18899; i++) + materials[i] = Material.SculkCatalyst; + for (int i = 18673; i <= 18768; i++) + materials[i] = Material.SculkSensor; + for (int i = 18900; i <= 18907; i++) + materials[i] = Material.SculkShrieker; + for (int i = 18770; i <= 18897; i++) + materials[i] = Material.SculkVein; + materials[8603] = Material.SeaLantern; + for (int i = 10521; i <= 10528; i++) + materials[i] = Material.SeaPickle; + materials[1599] = Material.Seagrass; + materials[16198] = Material.Shroomlight; + for (int i = 10153; i <= 10158; i++) + materials[i] = Material.ShulkerBox; + for (int i = 7107; i <= 7122; i++) + materials[i] = Material.SkeletonSkull; + for (int i = 7123; i <= 7126; i++) + materials[i] = Material.SkeletonWallSkull; + materials[8244] = Material.SlimeBlock; + for (int i = 18657; i <= 18668; i++) + materials[i] = Material.SmallAmethystBud; + for (int i = 19758; i <= 19773; i++) + materials[i] = Material.SmallDripleaf; + materials[16054] = Material.SmithingTable; + for (int i = 16008; i <= 16015; i++) + materials[i] = Material.Smoker; + materials[21431] = Material.SmoothBasalt; + materials[9169] = Material.SmoothQuartz; + for (int i = 11712; i <= 11717; i++) + materials[i] = Material.SmoothQuartzSlab; + for (int i = 11190; i <= 11269; i++) + materials[i] = Material.SmoothQuartzStairs; + materials[9170] = Material.SmoothRedSandstone; + for (int i = 11676; i <= 11681; i++) + materials[i] = Material.SmoothRedSandstoneSlab; + for (int i = 10630; i <= 10709; i++) + materials[i] = Material.SmoothRedSandstoneStairs; + materials[9168] = Material.SmoothSandstone; + for (int i = 11706; i <= 11711; i++) + materials[i] = Material.SmoothSandstoneSlab; + for (int i = 11110; i <= 11189; i++) + materials[i] = Material.SmoothSandstoneStairs; + materials[9167] = Material.SmoothStone; + for (int i = 9089; i <= 9094; i++) + materials[i] = Material.SmoothStoneSlab; + for (int i = 4230; i <= 4237; i++) + materials[i] = Material.Snow; + materials[4239] = Material.SnowBlock; + for (int i = 16131; i <= 16162; i++) + materials[i] = Material.SoulCampfire; + materials[2206] = Material.SoulFire; + for (int i = 16095; i <= 16098; i++) + materials[i] = Material.SoulLantern; + materials[4309] = Material.SoulSand; + materials[4310] = Material.SoulSoil; + materials[4317] = Material.SoulTorch; + for (int i = 4318; i <= 4321; i++) + materials[i] = Material.SoulWallTorch; + materials[2207] = Material.Spawner; + materials[458] = Material.Sponge; + materials[19713] = Material.SporeBlossom; + for (int i = 6963; i <= 6986; i++) + materials[i] = Material.SpruceButton; + for (int i = 9555; i <= 9618; i++) + materials[i] = Material.SpruceDoor; + for (int i = 9363; i <= 9394; i++) + materials[i] = Material.SpruceFence; + for (int i = 9171; i <= 9202; i++) + materials[i] = Material.SpruceFenceGate; + for (int i = 234; i <= 261; i++) + materials[i] = Material.SpruceLeaves; + for (int i = 120; i <= 122; i++) + materials[i] = Material.SpruceLog; + materials[16] = Material.SprucePlanks; + for (int i = 4180; i <= 4181; i++) + materials[i] = Material.SprucePressurePlate; + for (int i = 24; i <= 25; i++) + materials[i] = Material.SpruceSapling; + for (int i = 3668; i <= 3699; i++) + materials[i] = Material.SpruceSign; + for (int i = 9047; i <= 9052; i++) + materials[i] = Material.SpruceSlab; + for (int i = 5996; i <= 6075; i++) + materials[i] = Material.SpruceStairs; + for (int i = 4484; i <= 4547; i++) + materials[i] = Material.SpruceTrapdoor; + for (int i = 4040; i <= 4047; i++) + materials[i] = Material.SpruceWallSign; + for (int i = 167; i <= 169; i++) + materials[i] = Material.SpruceWood; + for (int i = 1583; i <= 1594; i++) + materials[i] = Material.StickyPiston; + materials[1] = Material.Stone; + for (int i = 9125; i <= 9130; i++) + materials[i] = Material.StoneBrickSlab; + for (int i = 5439; i <= 5518; i++) + materials[i] = Material.StoneBrickStairs; + for (int i = 13368; i <= 13691; i++) + materials[i] = Material.StoneBrickWall; + materials[4868] = Material.StoneBricks; + for (int i = 4206; i <= 4229; i++) + materials[i] = Material.StoneButton; + for (int i = 4112; i <= 4113; i++) + materials[i] = Material.StonePressurePlate; + for (int i = 9083; i <= 9088; i++) + materials[i] = Material.StoneSlab; + for (int i = 11030; i <= 11109; i++) + materials[i] = Material.StoneStairs; + for (int i = 16055; i <= 16058; i++) + materials[i] = Material.Stonecutter; + for (int i = 152; i <= 154; i++) + materials[i] = Material.StrippedAcaciaLog; + for (int i = 197; i <= 199; i++) + materials[i] = Material.StrippedAcaciaWood; + for (int i = 146; i <= 148; i++) + materials[i] = Material.StrippedBirchLog; + for (int i = 191; i <= 193; i++) + materials[i] = Material.StrippedBirchWood; + for (int i = 16193; i <= 16195; i++) + materials[i] = Material.StrippedCrimsonHyphae; + for (int i = 16187; i <= 16189; i++) + materials[i] = Material.StrippedCrimsonStem; + for (int i = 155; i <= 157; i++) + materials[i] = Material.StrippedDarkOakLog; + for (int i = 200; i <= 202; i++) + materials[i] = Material.StrippedDarkOakWood; + for (int i = 149; i <= 151; i++) + materials[i] = Material.StrippedJungleLog; + for (int i = 194; i <= 196; i++) + materials[i] = Material.StrippedJungleWood; + for (int i = 161; i <= 163; i++) + materials[i] = Material.StrippedMangroveLog; + for (int i = 203; i <= 205; i++) + materials[i] = Material.StrippedMangroveWood; + for (int i = 158; i <= 160; i++) + materials[i] = Material.StrippedOakLog; + for (int i = 185; i <= 187; i++) + materials[i] = Material.StrippedOakWood; + for (int i = 143; i <= 145; i++) + materials[i] = Material.StrippedSpruceLog; + for (int i = 188; i <= 190; i++) + materials[i] = Material.StrippedSpruceWood; + for (int i = 16176; i <= 16178; i++) + materials[i] = Material.StrippedWarpedHyphae; + for (int i = 16170; i <= 16172; i++) + materials[i] = Material.StrippedWarpedStem; + for (int i = 16944; i <= 16947; i++) + materials[i] = Material.StructureBlock; + materials[10140] = Material.StructureVoid; + for (int i = 4257; i <= 4272; i++) + materials[i] = Material.SugarCane; + for (int i = 8626; i <= 8627; i++) + materials[i] = Material.Sunflower; + for (int i = 16163; i <= 16166; i++) + materials[i] = Material.SweetBerryBush; + for (int i = 8634; i <= 8635; i++) + materials[i] = Material.TallGrass; + for (int i = 1600; i <= 1601; i++) + materials[i] = Material.TallSeagrass; + for (int i = 16969; i <= 16984; i++) + materials[i] = Material.Target; + materials[8623] = Material.Terracotta; + materials[18671] = Material.TintedGlass; + for (int i = 1684; i <= 1685; i++) + materials[i] = Material.Tnt; + materials[1689] = Material.Torch; + for (int i = 7239; i <= 7262; i++) + materials[i] = Material.TrappedChest; + for (int i = 5867; i <= 5994; i++) + materials[i] = Material.Tripwire; + for (int i = 5851; i <= 5866; i++) + materials[i] = Material.TripwireHook; + for (int i = 10411; i <= 10412; i++) + materials[i] = Material.TubeCoral; + materials[10396] = Material.TubeCoralBlock; + for (int i = 10431; i <= 10432; i++) + materials[i] = Material.TubeCoralFan; + for (int i = 10481; i <= 10488; i++) + materials[i] = Material.TubeCoralWallFan; + materials[18669] = Material.Tuff; + for (int i = 10379; i <= 10390; i++) + materials[i] = Material.TurtleEgg; + for (int i = 16226; i <= 16251; i++) + materials[i] = Material.TwistingVines; + materials[16252] = Material.TwistingVinesPlant; + for (int i = 21440; i <= 21442; i++) + materials[i] = Material.VerdantFroglight; + for (int i = 5167; i <= 5198; i++) + materials[i] = Material.Vine; + materials[10546] = Material.VoidAir; + for (int i = 1690; i <= 1693; i++) + materials[i] = Material.WallTorch; + for (int i = 16712; i <= 16735; i++) + materials[i] = Material.WarpedButton; + for (int i = 16800; i <= 16863; i++) + materials[i] = Material.WarpedDoor; + for (int i = 16304; i <= 16335; i++) + materials[i] = Material.WarpedFence; + for (int i = 16496; i <= 16527; i++) + materials[i] = Material.WarpedFenceGate; + materials[16180] = Material.WarpedFungus; + for (int i = 16173; i <= 16175; i++) + materials[i] = Material.WarpedHyphae; + materials[16179] = Material.WarpedNylium; + materials[16255] = Material.WarpedPlanks; + for (int i = 16270; i <= 16271; i++) + materials[i] = Material.WarpedPressurePlate; + materials[16182] = Material.WarpedRoots; + for (int i = 16896; i <= 16927; i++) + materials[i] = Material.WarpedSign; + for (int i = 16262; i <= 16267; i++) + materials[i] = Material.WarpedSlab; + for (int i = 16608; i <= 16687; i++) + materials[i] = Material.WarpedStairs; + for (int i = 16167; i <= 16169; i++) + materials[i] = Material.WarpedStem; + for (int i = 16400; i <= 16463; i++) + materials[i] = Material.WarpedTrapdoor; + for (int i = 16936; i <= 16943; i++) + materials[i] = Material.WarpedWallSign; + materials[16181] = Material.WarpedWartBlock; + for (int i = 75; i <= 90; i++) + materials[i] = Material.Water; + for (int i = 5729; i <= 5731; i++) + materials[i] = Material.WaterCauldron; + materials[19262] = Material.WaxedCopperBlock; + materials[19269] = Material.WaxedCutCopper; + for (int i = 19608; i <= 19613; i++) + materials[i] = Material.WaxedCutCopperSlab; + for (int i = 19510; i <= 19589; i++) + materials[i] = Material.WaxedCutCopperStairs; + materials[19264] = Material.WaxedExposedCopper; + materials[19268] = Material.WaxedExposedCutCopper; + for (int i = 19602; i <= 19607; i++) + materials[i] = Material.WaxedExposedCutCopperSlab; + for (int i = 19430; i <= 19509; i++) + materials[i] = Material.WaxedExposedCutCopperStairs; + materials[19265] = Material.WaxedOxidizedCopper; + materials[19266] = Material.WaxedOxidizedCutCopper; + for (int i = 19590; i <= 19595; i++) + materials[i] = Material.WaxedOxidizedCutCopperSlab; + for (int i = 19270; i <= 19349; i++) + materials[i] = Material.WaxedOxidizedCutCopperStairs; + materials[19263] = Material.WaxedWeatheredCopper; + materials[19267] = Material.WaxedWeatheredCutCopper; + for (int i = 19596; i <= 19601; i++) + materials[i] = Material.WaxedWeatheredCutCopperSlab; + for (int i = 19350; i <= 19429; i++) + materials[i] = Material.WaxedWeatheredCutCopperStairs; + materials[18909] = Material.WeatheredCopper; + materials[18915] = Material.WeatheredCutCopper; + for (int i = 19244; i <= 19249; i++) + materials[i] = Material.WeatheredCutCopperSlab; + for (int i = 18998; i <= 19077; i++) + materials[i] = Material.WeatheredCutCopperStairs; + for (int i = 16199; i <= 16224; i++) + materials[i] = Material.WeepingVines; + materials[16225] = Material.WeepingVinesPlant; + materials[459] = Material.WetSponge; + for (int i = 3612; i <= 3619; i++) + materials[i] = Material.Wheat; + for (int i = 8638; i <= 8653; i++) + materials[i] = Material.WhiteBanner; + for (int i = 1279; i <= 1294; i++) + materials[i] = Material.WhiteBed; + for (int i = 18329; i <= 18344; i++) + materials[i] = Material.WhiteCandle; + for (int i = 18587; i <= 18588; i++) + materials[i] = Material.WhiteCandleCake; + materials[8607] = Material.WhiteCarpet; + materials[10319] = Material.WhiteConcrete; + materials[10335] = Material.WhiteConcretePowder; + for (int i = 10255; i <= 10258; i++) + materials[i] = Material.WhiteGlazedTerracotta; + for (int i = 10159; i <= 10164; i++) + materials[i] = Material.WhiteShulkerBox; + materials[4404] = Material.WhiteStainedGlass; + for (int i = 7492; i <= 7523; i++) + materials[i] = Material.WhiteStainedGlassPane; + materials[7476] = Material.WhiteTerracotta; + materials[1673] = Material.WhiteTulip; + for (int i = 8894; i <= 8897; i++) + materials[i] = Material.WhiteWallBanner; + materials[1638] = Material.WhiteWool; + materials[1677] = Material.WitherRose; + for (int i = 7127; i <= 7142; i++) + materials[i] = Material.WitherSkeletonSkull; + for (int i = 7143; i <= 7146; i++) + materials[i] = Material.WitherSkeletonWallSkull; + for (int i = 8702; i <= 8717; i++) + materials[i] = Material.YellowBanner; + for (int i = 1343; i <= 1358; i++) + materials[i] = Material.YellowBed; + for (int i = 18393; i <= 18408; i++) + materials[i] = Material.YellowCandle; + for (int i = 18595; i <= 18596; i++) + materials[i] = Material.YellowCandleCake; + materials[8611] = Material.YellowCarpet; + materials[10323] = Material.YellowConcrete; + materials[10339] = Material.YellowConcretePowder; + for (int i = 10271; i <= 10274; i++) + materials[i] = Material.YellowGlazedTerracotta; + for (int i = 10183; i <= 10188; i++) + materials[i] = Material.YellowShulkerBox; + materials[4408] = Material.YellowStainedGlass; + for (int i = 7620; i <= 7651; i++) + materials[i] = Material.YellowStainedGlassPane; + materials[7480] = Material.YellowTerracotta; + for (int i = 8910; i <= 8913; i++) + materials[i] = Material.YellowWallBanner; + materials[1642] = Material.YellowWool; + for (int i = 7147; i <= 7162; i++) + materials[i] = Material.ZombieHead; + for (int i = 7163; i <= 7166; i++) + materials[i] = Material.ZombieWallHead; + } + + protected override Dictionary GetDict() + { + return materials; + } + } +} diff --git a/MinecraftClient/Mapping/Material.cs b/MinecraftClient/Mapping/Material.cs index ea5cc704..507dcc56 100644 --- a/MinecraftClient/Mapping/Material.cs +++ b/MinecraftClient/Mapping/Material.cs @@ -4,10 +4,10 @@ /// Represents Minecraft Materials /// /// - /// Generated from blocks.json using BlockPaletteGenerator.cs. + /// Generated from blocks.json using the --generator flag on the client /// Typical steps to handle new blocks for newer Minecraft versions: - /// 1. Generate blocks.json using data reporting on Vanilla Minecraft (https://wiki.vg/Data_Generators) - /// 2. Generate temporary MaterialXXX.cs and PaletteXXX.cs using BlockPaletteGenerator.cs + /// 1. Generate blocks.json using data reporting on Vanilla Minecraft (https://wiki.vg/Data_Generators) or download it from: https://github.com/PixiGeko/Minecraft-generated-data + /// 2. Generate temporary MaterialXXX.cs and PaletteXXX.cs using the --generator flag on the client /// 3. Perform a diff with existing versions, add missing entries in Material.cs and MaterialExtensions.cs /// 4. If existing state IDs were not randomized by Mojang, simply add missing state entries to Palette113.cs /// 5. If existing state IDs were randomized, add a new palette as PaletteXXX.cs into the codebase (worst case) @@ -52,8 +52,8 @@ Basalt, Beacon, Bedrock, - Beehive, BeeNest, + Beehive, Beetroots, Bell, BigDripleaf, @@ -84,13 +84,13 @@ BlackShulkerBox, BlackStainedGlass, BlackStainedGlassPane, + BlackTerracotta, + BlackWallBanner, + BlackWool, Blackstone, BlackstoneSlab, BlackstoneStairs, BlackstoneWall, - BlackTerracotta, - BlackWallBanner, - BlackWool, BlastFurnace, BlueBanner, BlueBed, @@ -115,10 +115,10 @@ BrainCoralFan, BrainCoralWallFan, BrewingStand, - Bricks, BrickSlab, BrickStairs, BrickWall, + Bricks, BrownBanner, BrownBed, BrownCandle, @@ -277,10 +277,10 @@ DeadTubeCoralFan, DeadTubeCoralWallFan, Deepslate, - DeepslateBricks, DeepslateBrickSlab, DeepslateBrickStairs, DeepslateBrickWall, + DeepslateBricks, DeepslateCoalOre, DeepslateCopperOre, DeepslateDiamondOre, @@ -289,10 +289,10 @@ DeepslateIronOre, DeepslateLapisOre, DeepslateRedstoneOre, - DeepslateTiles, DeepslateTileSlab, DeepslateTileStairs, DeepslateTileWall, + DeepslateTiles, DetectorRail, DiamondBlock, DiamondOre, @@ -301,6 +301,7 @@ DioriteStairs, DioriteWall, Dirt, + DirtPath, Dispenser, DragonEgg, DragonHead, @@ -311,16 +312,16 @@ EmeraldBlock, EmeraldOre, EnchantingTable, - EnderChest, EndGateway, EndPortal, EndPortalFrame, EndRod, EndStone, - EndStoneBricks, EndStoneBrickSlab, EndStoneBrickStairs, EndStoneBrickWall, + EndStoneBricks, + EnderChest, ExposedCopper, ExposedCutCopper, ExposedCutCopperSlab, @@ -333,9 +334,10 @@ FireCoralFan, FireCoralWallFan, FletchingTable, + FlowerPot, FloweringAzalea, FloweringAzaleaLeaves, - FlowerPot, + Frogspawn, FrostedIce, Furnace, GildedBlackstone, @@ -351,7 +353,6 @@ GraniteWall, Grass, GrassBlock, - GrassPath, Gravel, GrayBanner, GrayBed, @@ -464,8 +465,8 @@ LightGrayTerracotta, LightGrayWallBanner, LightGrayWool, - LightningRod, LightWeightedPressurePlate, + LightningRod, Lilac, LilyOfTheValley, LilyPad, @@ -500,6 +501,22 @@ MagentaWallBanner, MagentaWool, MagmaBlock, + MangroveButton, + MangroveDoor, + MangroveFence, + MangroveFenceGate, + MangroveLeaves, + MangroveLog, + MangrovePlanks, + MangrovePressurePlate, + MangrovePropagule, + MangroveRoots, + MangroveSign, + MangroveSlab, + MangroveStairs, + MangroveTrapdoor, + MangroveWallSign, + MangroveWood, MediumAmethystBud, Melon, MelonStem, @@ -509,26 +526,32 @@ MossyCobblestoneSlab, MossyCobblestoneStairs, MossyCobblestoneWall, - MossyStoneBricks, MossyStoneBrickSlab, MossyStoneBrickStairs, MossyStoneBrickWall, + MossyStoneBricks, MovingPiston, + Mud, + MudBrickSlab, + MudBrickStairs, + MudBrickWall, + MudBricks, + MuddyMangroveRoots, MushroomStem, Mycelium, NetherBrickFence, - NetherBricks, NetherBrickSlab, NetherBrickStairs, NetherBrickWall, + NetherBricks, NetherGoldOre, - NetheriteBlock, NetherPortal, NetherQuartzOre, - Netherrack, NetherSprouts, NetherWart, NetherWartBlock, + NetheriteBlock, + Netherrack, NoteBlock, OakButton, OakDoor, @@ -547,6 +570,7 @@ OakWood, Observer, Obsidian, + OchreFroglight, OrangeBanner, OrangeBed, OrangeCandle, @@ -568,6 +592,8 @@ OxidizedCutCopperSlab, OxidizedCutCopperStairs, PackedIce, + PackedMud, + PearlescentFroglight, Peony, PetrifiedOakSlab, PinkBanner, @@ -596,10 +622,10 @@ PolishedAndesiteStairs, PolishedBasalt, PolishedBlackstone, - PolishedBlackstoneBricks, PolishedBlackstoneBrickSlab, PolishedBlackstoneBrickStairs, PolishedBlackstoneBrickWall, + PolishedBlackstoneBricks, PolishedBlackstoneButton, PolishedBlackstonePressurePlate, PolishedBlackstoneSlab, @@ -636,6 +662,7 @@ PottedFloweringAzaleaBush, PottedJungleSapling, PottedLilyOfTheValley, + PottedMangrovePropagule, PottedOakSapling, PottedOrangeTulip, PottedOxeyeDaisy, @@ -652,9 +679,9 @@ PowderSnowCauldron, PoweredRail, Prismarine, - PrismarineBricks, PrismarineBrickSlab, PrismarineBrickStairs, + PrismarineBricks, PrismarineSlab, PrismarineStairs, PrismarineWall, @@ -697,10 +724,10 @@ RedGlazedTerracotta, RedMushroom, RedMushroomBlock, - RedNetherBricks, RedNetherBrickSlab, RedNetherBrickStairs, RedNetherBrickWall, + RedNetherBricks, RedSand, RedSandstone, RedSandstoneSlab, @@ -709,16 +736,17 @@ RedShulkerBox, RedStainedGlass, RedStainedGlassPane, + RedTerracotta, + RedTulip, + RedWallBanner, + RedWool, RedstoneBlock, RedstoneLamp, RedstoneOre, RedstoneTorch, RedstoneWallTorch, RedstoneWire, - RedTerracotta, - RedTulip, - RedWallBanner, - RedWool, + ReinforcedDeepslate, Repeater, RepeatingCommandBlock, RespawnAnchor, @@ -730,10 +758,14 @@ SandstoneStairs, SandstoneWall, Scaffolding, + Sculk, + SculkCatalyst, SculkSensor, - Seagrass, + SculkShrieker, + SculkVein, SeaLantern, SeaPickle, + Seagrass, Shroomlight, ShulkerBox, SkeletonSkull, @@ -784,15 +816,15 @@ SpruceWood, StickyPiston, Stone, - StoneBricks, StoneBrickSlab, StoneBrickStairs, StoneBrickWall, + StoneBricks, StoneButton, - Stonecutter, StonePressurePlate, StoneSlab, StoneStairs, + Stonecutter, StrippedAcaciaLog, StrippedAcaciaWood, StrippedBirchLog, @@ -803,6 +835,8 @@ StrippedDarkOakWood, StrippedJungleLog, StrippedJungleWood, + StrippedMangroveLog, + StrippedMangroveWood, StrippedOakLog, StrippedOakWood, StrippedSpruceLog, @@ -832,6 +866,7 @@ TurtleEgg, TwistingVines, TwistingVinesPlant, + VerdantFroglight, Vine, VoidAir, WallTorch, diff --git a/MinecraftClient/Mapping/Material2Tool.cs b/MinecraftClient/Mapping/Material2Tool.cs index d8433808..f2259d0f 100644 --- a/MinecraftClient/Mapping/Material2Tool.cs +++ b/MinecraftClient/Mapping/Material2Tool.cs @@ -367,7 +367,7 @@ namespace MinecraftClient.Mapping Material.Farmland, Material.Grass, Material.GrassBlock, - Material.GrassPath, + Material.DirtPath, Material.Gravel, Material.GrayConcretePowder, Material.GreenConcretePowder, diff --git a/MinecraftClient/Mapping/MaterialExtensions.cs b/MinecraftClient/Mapping/MaterialExtensions.cs index 391097f6..39f9e51a 100644 --- a/MinecraftClient/Mapping/MaterialExtensions.cs +++ b/MinecraftClient/Mapping/MaterialExtensions.cs @@ -372,7 +372,7 @@ namespace MinecraftClient.Mapping case Material.PurpurPillar: case Material.PurpurStairs: case Material.EndStoneBricks: - case Material.GrassPath: + case Material.DirtPath: case Material.RepeatingCommandBlock: case Material.ChainCommandBlock: case Material.FrostedIce: diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 2da4394e..9c8666f1 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -64,7 +64,7 @@ namespace MinecraftClient.Protocol.Handlers private readonly List autocomplete_result = new List(); private readonly Dictionary window_actions = new Dictionary(); private bool login_phase = true; - private int protocolversion; + private int protocolVersion; private int currentDimension; private int pendingAcknowledgments = 0; @@ -89,7 +89,7 @@ namespace MinecraftClient.Protocol.Handlers ChatParser.InitTranslations(); this.socketWrapper = new SocketWrapper(Client); this.dataTypes = new DataTypes(protocolVersion); - this.protocolversion = protocolVersion; + this.protocolVersion = protocolVersion; this.handler = handler; this.pForge = new Protocol18Forge(forgeInfo, protocolVersion, dataTypes, this, handler); this.pTerrain = new Protocol18Terrain(protocolVersion, dataTypes, handler); @@ -97,82 +97,86 @@ namespace MinecraftClient.Protocol.Handlers this.log = handler.GetLogger(); this.randomGen = RandomNumberGenerator.Create(); - if (handler.GetTerrainEnabled() && protocolversion > MC_1_18_2_Version) + if (handler.GetTerrainEnabled() && this.protocolVersion > MC_1_18_2_Version) { log.Error(Translations.Get("extra.terrainandmovement_disabled")); handler.SetTerrainEnabled(false); } - if (handler.GetInventoryEnabled() && (protocolversion < MC_1_10_Version || protocolversion > MC_1_18_2_Version)) + if (handler.GetInventoryEnabled() && (this.protocolVersion < MC_1_10_Version || this.protocolVersion > MC_1_18_2_Version)) { log.Error(Translations.Get("extra.inventory_disabled")); handler.SetInventoryEnabled(false); } - if (handler.GetEntityHandlingEnabled() && (protocolversion < MC_1_10_Version || protocolversion > MC_1_18_2_Version)) + if (handler.GetEntityHandlingEnabled() && (this.protocolVersion < MC_1_10_Version || this.protocolVersion > MC_1_18_2_Version)) { log.Error(Translations.Get("extra.entity_disabled")); handler.SetEntityHandlingEnabled(false); } // Block palette - if (protocolversion >= MC_1_13_Version) + if (this.protocolVersion >= MC_1_13_Version) { - if (protocolVersion > MC_1_18_2_Version && handler.GetTerrainEnabled()) + if (protocolVersion > MC_1_19_Version && handler.GetTerrainEnabled()) throw new NotImplementedException(Translations.Get("exception.palette.block")); - if (protocolVersion >= MC_1_17_Version) + + if (this.protocolVersion == MC_1_19_Version) + Block.Palette = new Palette119(); + else if (this.protocolVersion >= MC_1_17_Version) Block.Palette = new Palette117(); else if (protocolVersion >= MC_1_16_Version) - if (protocolVersion >= MC_1_16_Version) - Block.Palette = new Palette116(); - else if (protocolVersion >= MC_1_15_Version) - Block.Palette = new Palette115(); - else if (protocolVersion >= MC_1_14_Version) - Block.Palette = new Palette114(); - else Block.Palette = new Palette113(); + Block.Palette = new Palette116(); + else if (protocolVersion >= MC_1_15_Version) + Block.Palette = new Palette115(); + else if (protocolVersion >= MC_1_14_Version) + Block.Palette = new Palette114(); + else + Block.Palette = new Palette113(); } else Block.Palette = new Palette112(); // Entity palette - if (protocolversion >= MC_1_13_Version) + if (this.protocolVersion >= MC_1_13_Version) { - if (protocolversion > MC_1_18_2_Version && handler.GetEntityHandlingEnabled()) + if (this.protocolVersion > MC_1_18_2_Version && handler.GetEntityHandlingEnabled()) throw new NotImplementedException(Translations.Get("exception.palette.entity")); - if (protocolversion >= MC_1_17_Version) + + if (this.protocolVersion >= MC_1_17_Version) entityPalette = new EntityPalette117(); - else if (protocolversion >= MC_1_16_2_Version) - if (protocolversion >= MC_1_16_2_Version) - entityPalette = new EntityPalette1162(); - else if (protocolversion >= MC_1_16_Version) - entityPalette = new EntityPalette1161(); - else if (protocolversion >= MC_1_15_Version) - entityPalette = new EntityPalette115(); - else if (protocolVersion >= MC_1_14_Version) - entityPalette = new EntityPalette114(); - else entityPalette = new EntityPalette113(); + else if (this.protocolVersion >= MC_1_16_2_Version) + entityPalette = new EntityPalette1162(); + else if (this.protocolVersion >= MC_1_16_Version) + entityPalette = new EntityPalette1161(); + else if (this.protocolVersion >= MC_1_15_Version) + entityPalette = new EntityPalette115(); + else if (protocolVersion >= MC_1_14_Version) + entityPalette = new EntityPalette114(); + else + entityPalette = new EntityPalette113(); } else entityPalette = new EntityPalette112(); // Item palette - if (protocolversion >= MC_1_16_2_Version) + if (protocolVersion >= MC_1_16_2_Version) { - if (protocolversion > MC_1_18_2_Version && handler.GetInventoryEnabled()) + if (protocolVersion > MC_1_19_Version && handler.GetInventoryEnabled()) throw new NotImplementedException(Translations.Get("exception.palette.item")); - if (protocolversion >= MC_1_18_1_Version) + + if (protocolVersion >= MC_1_18_1_Version) itemPalette = new ItemPalette118(); - else if (protocolversion >= MC_1_17_Version) + else if (protocolVersion >= MC_1_17_Version) itemPalette = new ItemPalette117(); - else if (protocolversion >= MC_1_16_2_Version) - if (protocolversion >= MC_1_16_2_Version) - itemPalette = new ItemPalette1162(); - else itemPalette = new ItemPalette1161(); + else if (protocolVersion >= MC_1_16_2_Version) + itemPalette = new ItemPalette1162(); + else + itemPalette = new ItemPalette1161(); } else itemPalette = new ItemPalette115(); // MessageType // You can find it in https://wiki.vg/Protocol#Player_Chat_Message or /net/minecraft/network/message/MessageType.java - if (protocolversion >= MC_1_19_2_Version) - { + if (this.protocolVersion >= MC_1_19_2_Version) ChatParser.ChatId2Type = new() { { 0, ChatParser.MessageType.CHAT }, @@ -183,9 +187,7 @@ namespace MinecraftClient.Protocol.Handlers { 5, ChatParser.MessageType.TEAM_MSG_COMMAND_OUTGOING }, { 6, ChatParser.MessageType.EMOTE_COMMAND }, }; - } - else if (protocolversion >= MC_1_19_Version) - { + else if (this.protocolVersion == MC_1_19_Version) ChatParser.ChatId2Type = new() { { 0, ChatParser.MessageType.CHAT }, @@ -197,7 +199,6 @@ namespace MinecraftClient.Protocol.Handlers { 6, ChatParser.MessageType.EMOTE_COMMAND }, { 7, ChatParser.MessageType.RAW_MSG }, }; - } } /// @@ -280,7 +281,7 @@ namespace MinecraftClient.Protocol.Handlers packetData.Enqueue(rawpacket[i]); //Handle packet decompression - if (protocolversion >= MC_1_8_Version + if (protocolVersion >= MC_1_8_Version && compression_treshold > 0) { int sizeUncompressed = dataTypes.ReadNextVarInt(packetData); @@ -318,7 +319,7 @@ namespace MinecraftClient.Protocol.Handlers switch (packetID) //Packet IDs are different while logging in { case 0x03: - if (protocolversion >= MC_1_8_Version) + if (protocolVersion >= MC_1_8_Version) compression_treshold = dataTypes.ReadNextVarInt(packetData); break; case 0x04: @@ -345,12 +346,12 @@ namespace MinecraftClient.Protocol.Handlers int playerEntityID = dataTypes.ReadNextInt(packetData); handler.OnReceivePlayerEntityID(playerEntityID); - if (protocolversion >= MC_1_16_2_Version) + if (protocolVersion >= MC_1_16_2_Version) dataTypes.ReadNextBool(packetData); // Is hardcore - 1.16.2 and above handler.OnGamemodeUpdate(Guid.Empty, dataTypes.ReadNextByte(packetData)); - if (protocolversion >= MC_1_16_Version) + if (protocolVersion >= MC_1_16_Version) { dataTypes.ReadNextByte(packetData); // Previous Gamemode - 1.16 and above int worldCount = dataTypes.ReadNextVarInt(packetData); // Dimension Count (World Count) - 1.16 and above @@ -367,55 +368,55 @@ namespace MinecraftClient.Protocol.Handlers // String identifier: 1.16 and 1.16.1 // varInt: [1.9.1 to 1.15.2] // byte: below 1.9.1 - if (protocolversion >= MC_1_16_Version) + if (protocolVersion >= MC_1_16_Version) { - if (protocolversion >= MC_1_19_Version) + if (protocolVersion >= MC_1_19_Version) { dataTypes.ReadNextString(packetData); // Dimension Type: Identifier currentDimensionType = new Dictionary(); } - else if (protocolversion >= MC_1_16_2_Version) + else if (protocolVersion >= MC_1_16_2_Version) currentDimensionType = dataTypes.ReadNextNbt(packetData); // Dimension Type: NBT Tag Compound else dataTypes.ReadNextString(packetData); this.currentDimension = 0; } - else if (protocolversion >= MC_1_9_1_Version) + else if (protocolVersion >= MC_1_9_1_Version) this.currentDimension = dataTypes.ReadNextInt(packetData); else this.currentDimension = (sbyte)dataTypes.ReadNextByte(packetData); - if (protocolversion < MC_1_14_Version) + if (protocolVersion < MC_1_14_Version) dataTypes.ReadNextByte(packetData); // Difficulty - 1.13 and below - if (protocolversion >= MC_1_16_Version) + if (protocolVersion >= MC_1_16_Version) currentDimensionName = dataTypes.ReadNextString(packetData); // Dimension Name (World Name) - 1.16 and above - if (protocolversion >= MC_1_16_2_Version) + if (protocolVersion >= MC_1_16_2_Version) World.SetDimension(currentDimensionName, currentDimensionType); - if (protocolversion >= MC_1_15_Version) + if (protocolVersion >= MC_1_15_Version) dataTypes.ReadNextLong(packetData); // Hashed world seed - 1.15 and above - if (protocolversion >= MC_1_16_2_Version) + if (protocolVersion >= MC_1_16_2_Version) dataTypes.ReadNextVarInt(packetData); // Max Players - 1.16.2 and above else dataTypes.ReadNextByte(packetData); // Max Players - 1.16.1 and below - if (protocolversion < MC_1_16_Version) + if (protocolVersion < MC_1_16_Version) dataTypes.ReadNextString(packetData); // Level Type - 1.15 and below - if (protocolversion >= MC_1_14_Version) + if (protocolVersion >= MC_1_14_Version) dataTypes.ReadNextVarInt(packetData); // View distance - 1.14 and above - if (protocolversion >= MC_1_18_1_Version) + if (protocolVersion >= MC_1_18_1_Version) dataTypes.ReadNextVarInt(packetData); // Simulation Distance - 1.18 and above - if (protocolversion >= MC_1_8_Version) + if (protocolVersion >= MC_1_8_Version) dataTypes.ReadNextBool(packetData); // Reduced debug info - 1.8 and above - if (protocolversion >= MC_1_15_Version) + if (protocolVersion >= MC_1_15_Version) dataTypes.ReadNextBool(packetData); // Enable respawn screen - 1.15 and above - if (protocolversion >= MC_1_16_Version) + if (protocolVersion >= MC_1_16_Version) { dataTypes.ReadNextBool(packetData); // Is Debug - 1.16 and above dataTypes.ReadNextBool(packetData); // Is Flat - 1.16 and above } - if (protocolversion >= MC_1_19_Version) + if (protocolVersion >= MC_1_19_Version) { bool hasDeathLocation = dataTypes.ReadNextBool(packetData); // Has death location if (hasDeathLocation) @@ -428,12 +429,12 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.ChatMessage: int messageType = 0; - if (protocolversion <= MC_1_18_2_Version) // 1.18 and bellow + if (protocolVersion <= MC_1_18_2_Version) // 1.18 and bellow { string message = dataTypes.ReadNextString(packetData); Guid senderUUID; - if (protocolversion >= MC_1_8_Version) + if (protocolVersion >= MC_1_8_Version) { //Hide system messages or xp bar messages? messageType = dataTypes.ReadNextByte(packetData); @@ -441,7 +442,7 @@ namespace MinecraftClient.Protocol.Handlers || (messageType == 2 && !Settings.DisplayXPBarMessages)) break; - if (protocolversion >= MC_1_16_5_Version) + if (protocolVersion >= MC_1_16_5_Version) senderUUID = dataTypes.ReadNextUUID(packetData); else senderUUID = Guid.Empty; } @@ -450,7 +451,7 @@ namespace MinecraftClient.Protocol.Handlers handler.OnTextReceived(new(message, true, messageType, senderUUID)); } - else if (protocolversion == MC_1_19_Version) // 1.19 + else if (protocolVersion == MC_1_19_Version) // 1.19 { string signedChat = dataTypes.ReadNextString(packetData); @@ -549,7 +550,7 @@ namespace MinecraftClient.Protocol.Handlers } break; case PacketTypesIn.MessageHeader: - if (protocolversion >= MC_1_19_2_Version) + if (protocolVersion >= MC_1_19_2_Version) { byte[]? precedingSignature = dataTypes.ReadNextBool(packetData) ? dataTypes.ReadNextByteArray(packetData) : null; Guid senderUUID = dataTypes.ReadNextUUID(packetData); @@ -577,14 +578,14 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.Respawn: string? dimensionNameInRespawn = null; Dictionary dimensionTypeInRespawn = null; - if (protocolversion >= MC_1_16_Version) + if (protocolVersion >= MC_1_16_Version) { - if (protocolversion >= MC_1_19_Version) + if (protocolVersion >= MC_1_19_Version) { dataTypes.ReadNextString(packetData); // Dimension Type: Identifier dimensionTypeInRespawn = new Dictionary(); } - else if (protocolversion >= MC_1_16_2_Version) + else if (protocolVersion >= MC_1_16_2_Version) dimensionTypeInRespawn = dataTypes.ReadNextNbt(packetData); // Dimension Type: NBT Tag Compound else dataTypes.ReadNextString(packetData); @@ -595,28 +596,28 @@ namespace MinecraftClient.Protocol.Handlers // 1.15 and below this.currentDimension = dataTypes.ReadNextInt(packetData); } - if (protocolversion >= MC_1_16_Version) + if (protocolVersion >= MC_1_16_Version) dimensionNameInRespawn = dataTypes.ReadNextString(packetData); // Dimension Name (World Name) - 1.16 and above - if (protocolversion >= MC_1_16_2_Version) + if (protocolVersion >= MC_1_16_2_Version) World.SetDimension(dimensionNameInRespawn, dimensionTypeInRespawn); - if (protocolversion < MC_1_14_Version) + if (protocolVersion < MC_1_14_Version) dataTypes.ReadNextByte(packetData); // Difficulty - 1.13 and below - if (protocolversion >= MC_1_15_Version) + if (protocolVersion >= MC_1_15_Version) dataTypes.ReadNextLong(packetData); // Hashed world seed - 1.15 and above dataTypes.ReadNextByte(packetData); // Gamemode - if (protocolversion >= MC_1_16_Version) + if (protocolVersion >= MC_1_16_Version) dataTypes.ReadNextByte(packetData); // Previous Game mode - 1.16 and above - if (protocolversion < MC_1_16_Version) + if (protocolVersion < MC_1_16_Version) dataTypes.ReadNextString(packetData); // Level Type - 1.15 and below - if (protocolversion >= MC_1_16_Version) + if (protocolVersion >= MC_1_16_Version) { dataTypes.ReadNextBool(packetData); // Is Debug - 1.16 and above dataTypes.ReadNextBool(packetData); // Is Flat - 1.16 and above dataTypes.ReadNextBool(packetData); // Copy metadata - 1.16 and above } - if (protocolversion >= MC_1_19_Version) + if (protocolVersion >= MC_1_19_Version) { bool hasDeathLocation = dataTypes.ReadNextBool(packetData); // Has death location if (hasDeathLocation) @@ -639,7 +640,7 @@ namespace MinecraftClient.Protocol.Handlers // entity handling require player pos for distance calculating if (handler.GetTerrainEnabled() || handler.GetEntityHandlingEnabled()) { - if (protocolversion >= MC_1_8_Version) + if (protocolVersion >= MC_1_8_Version) { Location location = handler.GetCurrentLocation(); location.X = (locMask & 1 << 0) != 0 ? location.X + x : x; @@ -650,14 +651,14 @@ namespace MinecraftClient.Protocol.Handlers else handler.UpdateLocation(new Location(x, y, z), yaw, pitch); } - if (protocolversion >= MC_1_9_Version) + if (protocolVersion >= MC_1_9_Version) { int teleportID = dataTypes.ReadNextVarInt(packetData); // Teleport confirm packet SendPacket(PacketTypesOut.TeleportConfirm, dataTypes.GetVarInt(teleportID)); } - if (protocolversion >= MC_1_17_Version) + if (protocolVersion >= MC_1_17_Version) dataTypes.ReadNextBool(packetData); // Dismount Vehicle - 1.17 and above break; case PacketTypesIn.ChunkData: @@ -665,16 +666,16 @@ namespace MinecraftClient.Protocol.Handlers { int chunkX = dataTypes.ReadNextInt(packetData); int chunkZ = dataTypes.ReadNextInt(packetData); - if (protocolversion >= MC_1_17_Version) + if (protocolVersion >= MC_1_17_Version) { ulong[]? verticalStripBitmask = null; - if (protocolversion == MC_1_17_Version || protocolversion == MC_1_17_1_Version) + if (protocolVersion == MC_1_17_Version || protocolVersion == MC_1_17_1_Version) verticalStripBitmask = dataTypes.ReadNextULongArray(packetData); // Bit Mask Le:ngth and Primary Bit Mask dataTypes.ReadNextNbt(packetData); // Heightmaps - if (protocolversion == MC_1_17_Version || protocolversion == MC_1_17_1_Version) + if (protocolVersion == MC_1_17_Version || protocolVersion == MC_1_17_1_Version) { int biomesLength = dataTypes.ReadNextVarInt(packetData); // Biomes length for (int i = 0; i < biomesLength; i++) @@ -696,12 +697,12 @@ namespace MinecraftClient.Protocol.Handlers else { bool chunksContinuous = dataTypes.ReadNextBool(packetData); - if (protocolversion >= MC_1_16_Version && protocolversion <= MC_1_16_1_Version) + if (protocolVersion >= MC_1_16_Version && protocolVersion <= MC_1_16_1_Version) dataTypes.ReadNextBool(packetData); // Ignore old data - 1.16 to 1.16.1 only - ushort chunkMask = protocolversion >= MC_1_9_Version + ushort chunkMask = protocolVersion >= MC_1_9_Version ? (ushort)dataTypes.ReadNextVarInt(packetData) : dataTypes.ReadNextUShort(packetData); - if (protocolversion < MC_1_8_Version) + if (protocolVersion < MC_1_8_Version) { ushort addBitmap = dataTypes.ReadNextUShort(packetData); int compressedDataSize = dataTypes.ReadNextInt(packetData); @@ -714,15 +715,15 @@ namespace MinecraftClient.Protocol.Handlers } else { - if (protocolversion >= MC_1_14_Version) + if (protocolVersion >= MC_1_14_Version) dataTypes.ReadNextNbt(packetData); // Heightmaps - 1.14 and above int biomesLength = 0; - if (protocolversion >= MC_1_16_2_Version) + if (protocolVersion >= MC_1_16_2_Version) if (chunksContinuous) biomesLength = dataTypes.ReadNextVarInt(packetData); // Biomes length - 1.16.2 and above - if (protocolversion >= MC_1_15_Version && chunksContinuous) + if (protocolVersion >= MC_1_15_Version && chunksContinuous) { - if (protocolversion >= MC_1_16_2_Version) + if (protocolVersion >= MC_1_16_2_Version) { for (int i = 0; i < biomesLength; i++) { @@ -745,13 +746,13 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.MapData: int mapid = dataTypes.ReadNextVarInt(packetData); byte scale = dataTypes.ReadNextByte(packetData); - bool trackingposition = protocolversion >= MC_1_17_Version ? false : dataTypes.ReadNextBool(packetData); + bool trackingposition = protocolVersion >= MC_1_17_Version ? false : dataTypes.ReadNextBool(packetData); bool locked = false; - if (protocolversion >= MC_1_14_Version) + if (protocolVersion >= MC_1_14_Version) { locked = dataTypes.ReadNextBool(packetData); } - if (protocolversion >= MC_1_17_Version) + if (protocolVersion >= MC_1_17_Version) { trackingposition = dataTypes.ReadNextBool(packetData); } @@ -759,7 +760,7 @@ namespace MinecraftClient.Protocol.Handlers handler.OnMapData(mapid, scale, trackingposition, locked, iconcount); break; case PacketTypesIn.TradeList: - if ((protocolversion >= MC_1_14_Version) && (handler.GetInventoryEnabled())) + if ((protocolVersion >= MC_1_14_Version) && (handler.GetInventoryEnabled())) { // MC 1.14 or greater int windowID = dataTypes.ReadNextVarInt(packetData); @@ -781,7 +782,7 @@ namespace MinecraftClient.Protocol.Handlers } break; case PacketTypesIn.Title: - if (protocolversion >= MC_1_8_Version) + if (protocolVersion >= MC_1_8_Version) { int action2 = dataTypes.ReadNextVarInt(packetData); string titletext = String.Empty; @@ -791,7 +792,7 @@ namespace MinecraftClient.Protocol.Handlers int fadein = -1; int stay = -1; int fadeout = -1; - if (protocolversion >= MC_1_10_Version) + if (protocolVersion >= MC_1_10_Version) { if (action2 == 0) { @@ -840,7 +841,7 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.MultiBlockChange: if (handler.GetTerrainEnabled()) { - if (protocolversion >= MC_1_16_2_Version) + if (protocolVersion >= MC_1_16_2_Version) { long chunkSection = dataTypes.ReadNextLong(packetData); int sectionX = (int)(chunkSection >> 42); @@ -868,7 +869,7 @@ namespace MinecraftClient.Protocol.Handlers { int chunkX = dataTypes.ReadNextInt(packetData); int chunkZ = dataTypes.ReadNextInt(packetData); - int recordCount = protocolversion < MC_1_8_Version + int recordCount = protocolVersion < MC_1_8_Version ? (int)dataTypes.ReadNextShort(packetData) : dataTypes.ReadNextVarInt(packetData); @@ -878,7 +879,7 @@ namespace MinecraftClient.Protocol.Handlers ushort blockIdMeta; int blockY; - if (protocolversion < MC_1_8_Version) + if (protocolVersion < MC_1_8_Version) { blockIdMeta = dataTypes.ReadNextUShort(packetData); blockY = (ushort)dataTypes.ReadNextByte(packetData); @@ -917,7 +918,7 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.BlockChange: if (handler.GetTerrainEnabled()) { - if (protocolversion < MC_1_8_Version) + if (protocolVersion < MC_1_8_Version) { int blockX = dataTypes.ReadNextInt(packetData); int blockY = dataTypes.ReadNextByte(packetData); @@ -955,14 +956,14 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.ChatSuggestions: break; case PacketTypesIn.MapChunkBulk: - if (protocolversion < MC_1_9_Version && handler.GetTerrainEnabled()) + if (protocolVersion < MC_1_9_Version && handler.GetTerrainEnabled()) { int chunkCount; bool hasSkyLight; Queue chunkData = packetData; //Read global fields - if (protocolversion < MC_1_8_Version) + if (protocolVersion < MC_1_8_Version) { chunkCount = dataTypes.ReadNextShort(packetData); int compressedDataSize = dataTypes.ReadNextInt(packetData); @@ -987,7 +988,7 @@ namespace MinecraftClient.Protocol.Handlers chunkXs[chunkColumnNo] = dataTypes.ReadNextInt(packetData); chunkZs[chunkColumnNo] = dataTypes.ReadNextInt(packetData); chunkMasks[chunkColumnNo] = dataTypes.ReadNextUShort(packetData); - addBitmaps[chunkColumnNo] = protocolversion < MC_1_8_Version + addBitmaps[chunkColumnNo] = protocolVersion < MC_1_8_Version ? dataTypes.ReadNextUShort(packetData) : (ushort)0; } @@ -998,7 +999,7 @@ namespace MinecraftClient.Protocol.Handlers } break; case PacketTypesIn.UnloadChunk: - if (protocolversion >= MC_1_9_Version && handler.GetTerrainEnabled()) + if (protocolVersion >= MC_1_9_Version && handler.GetTerrainEnabled()) { int chunkX = dataTypes.ReadNextInt(packetData); int chunkZ = dataTypes.ReadNextInt(packetData); @@ -1013,7 +1014,7 @@ namespace MinecraftClient.Protocol.Handlers } break; case PacketTypesIn.PlayerInfo: - if (protocolversion >= MC_1_8_Version) + if (protocolVersion >= MC_1_8_Version) { int action = dataTypes.ReadNextVarInt(packetData); // Action Name int numberOfPlayers = dataTypes.ReadNextVarInt(packetData); // Number Of Players @@ -1050,7 +1051,7 @@ namespace MinecraftClient.Protocol.Handlers // 1.19 Additions long? keyExpiration = null; byte[]? publicKey = null, signature = null; - if (protocolversion >= MC_1_19_Version) + if (protocolVersion >= MC_1_19_Version) { if (dataTypes.ReadNextBool(packetData)) // Has Sig Data (if true, red the following fields) { @@ -1100,7 +1101,7 @@ namespace MinecraftClient.Protocol.Handlers } break; case PacketTypesIn.TabComplete: - if (protocolversion >= MC_1_13_Version) + if (protocolVersion >= MC_1_13_Version) { autocomplete_transaction_id = dataTypes.ReadNextVarInt(packetData); dataTypes.ReadNextVarInt(packetData); // Start of text to replace @@ -1113,7 +1114,7 @@ namespace MinecraftClient.Protocol.Handlers for (int i = 0; i < autocomplete_count; i++) { autocomplete_result.Add(dataTypes.ReadNextString(packetData)); - if (protocolversion >= MC_1_13_Version) + if (protocolVersion >= MC_1_13_Version) { // Skip optional tooltip for each tab-complete result if (dataTypes.ReadNextBool(packetData)) @@ -1126,7 +1127,7 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.PluginMessage: String channel = dataTypes.ReadNextString(packetData); // Length is unneeded as the whole remaining packetData is the entire payload of the packet. - if (protocolversion < MC_1_8_Version) + if (protocolVersion < MC_1_8_Version) pForge.ReadNextVarShort(packetData); handler.OnPluginChannelMessage(channel, packetData.ToArray()); return pForge.HandlePluginMessage(channel, packetData, ref currentDimension); @@ -1134,13 +1135,13 @@ namespace MinecraftClient.Protocol.Handlers handler.OnConnectionLost(ChatBot.DisconnectReason.InGameKick, ChatParser.ParseText(dataTypes.ReadNextString(packetData))); return false; case PacketTypesIn.SetCompression: - if (protocolversion >= MC_1_8_Version && protocolversion < MC_1_9_Version) + if (protocolVersion >= MC_1_8_Version && protocolVersion < MC_1_9_Version) compression_treshold = dataTypes.ReadNextVarInt(packetData); break; case PacketTypesIn.OpenWindow: if (handler.GetInventoryEnabled()) { - if (protocolversion < MC_1_14_Version) + if (protocolVersion < MC_1_14_Version) { // MC 1.13 or lower byte windowID = dataTypes.ReadNextByte(packetData); @@ -1177,7 +1178,7 @@ namespace MinecraftClient.Protocol.Handlers int stateId = -1; int elements = 0; - if (protocolversion >= MC_1_17_1_Version) + if (protocolVersion >= MC_1_17_1_Version) { // State ID and Elements as VarInt - 1.17.1 and above stateId = dataTypes.ReadNextVarInt(packetData); @@ -1197,7 +1198,7 @@ namespace MinecraftClient.Protocol.Handlers inventorySlots[slotId] = item; } - if (protocolversion >= MC_1_17_1_Version) // Carried Item - 1.17.1 and above + if (protocolVersion >= MC_1_17_1_Version) // Carried Item - 1.17.1 and above dataTypes.ReadNextItemSlot(packetData, itemPalette); handler.OnWindowItems(windowId, inventorySlots, stateId); @@ -1208,7 +1209,7 @@ namespace MinecraftClient.Protocol.Handlers { byte windowID = dataTypes.ReadNextByte(packetData); int stateId = -1; - if (protocolversion >= MC_1_17_1_Version) + if (protocolVersion >= MC_1_17_1_Version) stateId = dataTypes.ReadNextVarInt(packetData); // State ID - 1.17.1 and above short slotID = dataTypes.ReadNextShort(packetData); Item item = dataTypes.ReadNextItemSlot(packetData, itemPalette); @@ -1231,7 +1232,7 @@ namespace MinecraftClient.Protocol.Handlers string url = dataTypes.ReadNextString(packetData); string hash = dataTypes.ReadNextString(packetData); bool forced = true; // Assume forced for MC 1.16 and below - if (protocolversion >= MC_1_17_Version) + if (protocolVersion >= MC_1_17_Version) { forced = dataTypes.ReadNextBool(packetData); string forcedMessage = ChatParser.ParseText(dataTypes.ReadNextString(packetData)); @@ -1243,7 +1244,7 @@ namespace MinecraftClient.Protocol.Handlers break; //Send back "accepted" and "successfully loaded" responses for plugins or server config making use of resource pack mandatory byte[] responseHeader = new byte[0]; - if (protocolversion < MC_1_10_Version) //MC 1.10 does not include resource pack hash in responses + if (protocolVersion < MC_1_10_Version) //MC 1.10 does not include resource pack hash in responses responseHeader = dataTypes.ConcatBytes(dataTypes.GetVarInt(hash.Length), Encoding.UTF8.GetBytes(hash)); SendPacket(PacketTypesOut.ResourcePackStatus, dataTypes.ConcatBytes(responseHeader, dataTypes.GetVarInt(3))); //Accepted pack SendPacket(PacketTypesOut.ResourcePackStatus, dataTypes.ConcatBytes(responseHeader, dataTypes.GetVarInt(0))); //Successfully loaded @@ -1259,7 +1260,7 @@ namespace MinecraftClient.Protocol.Handlers if (handler.GetEntityHandlingEnabled()) { int entityid = dataTypes.ReadNextVarInt(packetData); - if (protocolversion >= MC_1_16_Version) + if (protocolVersion >= MC_1_16_Version) { bool hasNext; do @@ -1320,7 +1321,7 @@ namespace MinecraftClient.Protocol.Handlers bool hasFactorData = false; Dictionary? factorCodec = null; - if (protocolversion >= MC_1_19_Version) + if (protocolVersion >= MC_1_19_Version) { hasFactorData = dataTypes.ReadNextBool(packetData); factorCodec = dataTypes.ReadNextNbt(packetData); @@ -1334,7 +1335,7 @@ namespace MinecraftClient.Protocol.Handlers if (handler.GetEntityHandlingEnabled()) { int entityCount = 1; // 1.17.0 has only one entity per packet - if (protocolversion != MC_1_17_Version) + if (protocolVersion != MC_1_17_Version) entityCount = dataTypes.ReadNextVarInt(packetData); // All other versions have a "count" field int[] entityList = new int[entityCount]; for (int i = 0; i < entityCount; i++) @@ -1378,7 +1379,7 @@ namespace MinecraftClient.Protocol.Handlers if (handler.GetEntityHandlingEnabled()) { int EntityID = dataTypes.ReadNextVarInt(packetData); - int NumberOfProperties = protocolversion >= MC_1_17_Version ? dataTypes.ReadNextVarInt(packetData) : dataTypes.ReadNextInt(packetData); + int NumberOfProperties = protocolVersion >= MC_1_17_Version ? dataTypes.ReadNextVarInt(packetData) : dataTypes.ReadNextInt(packetData); Dictionary keys = new Dictionary(); for (int i = 0; i < NumberOfProperties; i++) { @@ -1417,11 +1418,11 @@ namespace MinecraftClient.Protocol.Handlers // See https://wiki.vg/Entity_metadata#Living_Entity int healthField = 7; // From 1.10 to 1.13.2 - if (protocolversion >= MC_1_14_Version) + if (protocolVersion >= MC_1_14_Version) healthField = 8; // 1.14 and above - if (protocolversion >= MC_1_17_Version) + if (protocolVersion >= MC_1_17_Version) healthField = 9; // 1.17 and above - if (protocolversion > MC_1_18_2_Version) + if (protocolVersion > MC_1_18_2_Version) throw new NotImplementedException(Translations.Get("exception.palette.healthfield")); if (metadata.ContainsKey(healthField) && metadata[healthField] != null && metadata[healthField].GetType() == typeof(float)) @@ -1465,7 +1466,7 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.UpdateHealth: float health = dataTypes.ReadNextFloat(packetData); int food; - if (protocolversion >= MC_1_8_Version) + if (protocolVersion >= MC_1_8_Version) food = dataTypes.ReadNextVarInt(packetData); else food = dataTypes.ReadNextShort(packetData); @@ -1480,12 +1481,12 @@ namespace MinecraftClient.Protocol.Handlers break; case PacketTypesIn.Explosion: Location explosionLocation; - if (protocolversion >= MC_1_19_Version) + if (protocolVersion >= MC_1_19_Version) explosionLocation = new(dataTypes.ReadNextDouble(packetData), dataTypes.ReadNextDouble(packetData), dataTypes.ReadNextDouble(packetData)); else explosionLocation = new(dataTypes.ReadNextFloat(packetData), dataTypes.ReadNextFloat(packetData), dataTypes.ReadNextFloat(packetData)); float explosionStrength = dataTypes.ReadNextFloat(packetData); - int explosionBlockCount = protocolversion >= MC_1_17_Version + int explosionBlockCount = protocolVersion >= MC_1_17_Version ? dataTypes.ReadNextVarInt(packetData) : dataTypes.ReadNextInt(packetData); // Ignoring additional fields (records, pushback) @@ -1509,12 +1510,12 @@ namespace MinecraftClient.Protocol.Handlers break; case PacketTypesIn.UpdateScore: string entityname = dataTypes.ReadNextString(packetData); - int action3 = protocolversion >= MC_1_18_2_Version + int action3 = protocolVersion >= MC_1_18_2_Version ? dataTypes.ReadNextVarInt(packetData) : dataTypes.ReadNextByte(packetData); string objectivename2 = string.Empty; int value = -1; - if (action3 != 1 || protocolversion >= MC_1_8_Version) + if (action3 != 1 || protocolVersion >= MC_1_8_Version) objectivename2 = dataTypes.ReadNextString(packetData); if (action3 != 1) value = dataTypes.ReadNextVarInt(packetData); @@ -1553,7 +1554,7 @@ namespace MinecraftClient.Protocol.Handlers Translations.Get("exception.packet_process", packetPalette.GetIncommingTypeById(packetID), packetID, - protocolversion, + protocolVersion, login_phase, innerException.GetType()), innerException); @@ -1647,7 +1648,7 @@ namespace MinecraftClient.Protocol.Handlers /// True if login successful public bool Login(PlayerKeyPair? playerKeyPair) { - byte[] protocol_version = dataTypes.GetVarInt(protocolversion); + byte[] protocol_version = dataTypes.GetVarInt(protocolVersion); string server_address = pForge.GetServerAddress(handler.GetServerHost()); byte[] server_port = dataTypes.GetUShort((ushort)handler.GetServerPort()); byte[] next_state = dataTypes.GetVarInt(2); @@ -1656,7 +1657,7 @@ namespace MinecraftClient.Protocol.Handlers List fullLoginPacket = new List(); fullLoginPacket.AddRange(dataTypes.GetString(handler.GetUsername())); // Username - if (protocolversion >= MC_1_19_Version) + if (protocolVersion >= MC_1_19_Version) { if (playerKeyPair == null) fullLoginPacket.AddRange(dataTypes.GetBool(false)); // Has Sig Data @@ -1665,13 +1666,13 @@ namespace MinecraftClient.Protocol.Handlers fullLoginPacket.AddRange(dataTypes.GetBool(true)); // Has Sig Data fullLoginPacket.AddRange(dataTypes.GetLong(playerKeyPair.GetExpirationMilliseconds())); // Expiration time fullLoginPacket.AddRange(dataTypes.GetArray(playerKeyPair.PublicKey.Key)); // Public key received from Microsoft API - if (protocolversion >= MC_1_19_2_Version) + if (protocolVersion >= MC_1_19_2_Version) fullLoginPacket.AddRange(dataTypes.GetArray(playerKeyPair.PublicKey.SignatureV2!)); // Public key signature received from Microsoft API else fullLoginPacket.AddRange(dataTypes.GetArray(playerKeyPair.PublicKey.Signature!)); // Public key signature received from Microsoft API } } - if (protocolversion >= MC_1_19_2_Version) + if (protocolVersion >= MC_1_19_2_Version) { string uuid = handler.GetUserUuidStr(); if (uuid == "0") @@ -1744,7 +1745,7 @@ namespace MinecraftClient.Protocol.Handlers // Encryption Response packet List encryptionResponse = new(); encryptionResponse.AddRange(dataTypes.GetArray(RSAService.Encrypt(secretKey, false))); // Shared Secret - if (protocolversion >= Protocol18Handler.MC_1_19_Version) + if (protocolVersion >= Protocol18Handler.MC_1_19_Version) { if (playerKeyPair == null) { @@ -1792,7 +1793,7 @@ namespace MinecraftClient.Protocol.Handlers Guid uuidReceived = dataTypes.ReadNextUUID(packetData); string userName = dataTypes.ReadNextString(packetData); Tuple[]? playerProperty = null; - if (protocolversion >= Protocol18Handler.MC_1_19_Version) + if (protocolVersion >= Protocol18Handler.MC_1_19_Version) { int count = dataTypes.ReadNextVarInt(packetData); // Number Of Properties playerProperty = new Tuple[count]; @@ -1847,9 +1848,9 @@ namespace MinecraftClient.Protocol.Handlers byte[] tabcomplete_packet = new byte[] { }; - if (protocolversion >= MC_1_8_Version) + if (protocolVersion >= MC_1_8_Version) { - if (protocolversion >= MC_1_13_Version) + if (protocolVersion >= MC_1_13_Version) { tabcomplete_packet = dataTypes.ConcatBytes(tabcomplete_packet, transaction_id); tabcomplete_packet = dataTypes.ConcatBytes(tabcomplete_packet, dataTypes.GetString(BehindCursor)); @@ -1858,7 +1859,7 @@ namespace MinecraftClient.Protocol.Handlers { tabcomplete_packet = dataTypes.ConcatBytes(tabcomplete_packet, dataTypes.GetString(BehindCursor)); - if (protocolversion >= MC_1_9_Version) + if (protocolVersion >= MC_1_9_Version) { tabcomplete_packet = dataTypes.ConcatBytes(tabcomplete_packet, assume_command); } @@ -1964,7 +1965,7 @@ namespace MinecraftClient.Protocol.Handlers /// Max length, in characters public int GetMaxChatMessageLength() { - return protocolversion > MC_1_10_Version + return protocolVersion > MC_1_10_Version ? 256 : 100; } @@ -1978,7 +1979,7 @@ namespace MinecraftClient.Protocol.Handlers /// Minecraft Protocol version number public int GetProtocolVersion() { - return protocolversion; + return protocolVersion; } /// @@ -2090,7 +2091,7 @@ namespace MinecraftClient.Protocol.Handlers try { - LastSeenMessageList.Acknowledgment? acknowledgment = (protocolversion >= MC_1_19_2_Version) ? this.consumeAcknowledgment() : null; + LastSeenMessageList.Acknowledgment? acknowledgment = (protocolVersion >= MC_1_19_2_Version) ? this.consumeAcknowledgment() : null; List fields = new(); @@ -2116,7 +2117,7 @@ namespace MinecraftClient.Protocol.Handlers foreach (var argument in needSigned) { fields.AddRange(dataTypes.GetString(argument.Item1)); // Argument name: String - byte[] sign = (protocolversion >= MC_1_19_2_Version) ? + byte[] sign = (protocolVersion >= MC_1_19_2_Version) ? playerKeyPair.PrivateKey.SignMessage(argument.Item2, uuid, timeNow, ref salt, acknowledgment!.lastSeen) : playerKeyPair.PrivateKey.SignMessage(argument.Item2, uuid, timeNow, ref salt); fields.AddRange(dataTypes.GetVarInt(sign.Length)); // Signature length: VarInt @@ -2127,7 +2128,7 @@ namespace MinecraftClient.Protocol.Handlers // Signed Preview: Boolean fields.AddRange(dataTypes.GetBool(false)); - if (protocolversion >= MC_1_19_2_Version) + if (protocolVersion >= MC_1_19_2_Version) { // Message Acknowledgment fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!)); @@ -2153,19 +2154,19 @@ namespace MinecraftClient.Protocol.Handlers return true; // Process Chat Command - 1.19 and above - if (protocolversion >= MC_1_19_Version && message.StartsWith('/')) + if (protocolVersion >= MC_1_19_Version && message.StartsWith('/')) return SendChatCommand(message[1..], playerKeyPair); try { - LastSeenMessageList.Acknowledgment? acknowledgment = (protocolversion >= MC_1_19_2_Version) ? this.consumeAcknowledgment() : null; + LastSeenMessageList.Acknowledgment? acknowledgment = (protocolVersion >= MC_1_19_2_Version) ? this.consumeAcknowledgment() : null; List fields = new(); // Message: String (up to 256 chars) fields.AddRange(dataTypes.GetString(message)); - if (protocolversion >= MC_1_19_Version) + if (protocolVersion >= MC_1_19_Version) { // Timestamp: Instant(Long) DateTimeOffset timeNow = DateTimeOffset.UtcNow; @@ -2184,7 +2185,7 @@ namespace MinecraftClient.Protocol.Handlers // Signature Length & Signature: (VarInt) and Byte Array Guid uuid = handler.GetUserUuid(); - byte[] sign = (protocolversion >= MC_1_19_2_Version) ? + byte[] sign = (protocolVersion >= MC_1_19_2_Version) ? playerKeyPair.PrivateKey.SignMessage(message, uuid, timeNow, ref salt, acknowledgment!.lastSeen) : playerKeyPair.PrivateKey.SignMessage(message, uuid, timeNow, ref salt); fields.AddRange(dataTypes.GetVarInt(sign.Length)); @@ -2194,7 +2195,7 @@ namespace MinecraftClient.Protocol.Handlers // Signed Preview: Boolean fields.AddRange(dataTypes.GetBool(false)); - if (protocolversion >= MC_1_19_2_Version) + if (protocolVersion >= MC_1_19_2_Version) { // Message Acknowledgment fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!)); @@ -2251,7 +2252,7 @@ namespace MinecraftClient.Protocol.Handlers return false; // Plugin channels were significantly changed between Minecraft 1.12 and 1.13 // https://wiki.vg/index.php?title=Pre-release_protocol&oldid=14132#Plugin_Channels - if (protocolversion >= MC_1_13_Version) + if (protocolVersion >= MC_1_13_Version) { return SendPluginChannelPacket("minecraft:brand", dataTypes.GetString(brandInfo)); } @@ -2280,28 +2281,28 @@ namespace MinecraftClient.Protocol.Handlers fields.AddRange(dataTypes.GetString(language)); fields.Add(viewDistance); - if (protocolversion >= MC_1_9_Version) + if (protocolVersion >= MC_1_9_Version) fields.AddRange(dataTypes.GetVarInt(chatMode)); else fields.AddRange(new byte[] { chatMode }); fields.Add(chatColors ? (byte)1 : (byte)0); - if (protocolversion < MC_1_8_Version) + if (protocolVersion < MC_1_8_Version) { fields.Add(difficulty); fields.Add((byte)(skinParts & 0x1)); //show cape } else fields.Add(skinParts); - if (protocolversion >= MC_1_9_Version) + if (protocolVersion >= MC_1_9_Version) fields.AddRange(dataTypes.GetVarInt(mainHand)); - if (protocolversion >= MC_1_17_Version) + if (protocolVersion >= MC_1_17_Version) { - if (protocolversion >= MC_1_18_1_Version) + if (protocolVersion >= MC_1_18_1_Version) fields.Add(0); // 1.18 and above - Enable text filtering. (Always false) else fields.Add(1); // 1.17 and 1.17.1 - Disable text filtering. (Always true) } - if (protocolversion >= MC_1_18_1_Version) + if (protocolVersion >= MC_1_18_1_Version) fields.Add(1); // 1.18 and above - Allow server listings SendPacket(PacketTypesOut.ClientSettings, fields); } @@ -2337,7 +2338,7 @@ namespace MinecraftClient.Protocol.Handlers SendPacket(packetType, dataTypes.ConcatBytes( dataTypes.GetDouble(location.X), dataTypes.GetDouble(location.Y), - protocolversion < MC_1_8_Version + protocolVersion < MC_1_8_Version ? dataTypes.GetDouble(location.Y + 1.62) : new byte[0], dataTypes.GetDouble(location.Z), @@ -2363,7 +2364,7 @@ namespace MinecraftClient.Protocol.Handlers { // In 1.7, length needs to be included. // In 1.8, it must not be. - if (protocolversion < MC_1_8_Version) + if (protocolVersion < MC_1_8_Version) { byte[] length = BitConverter.GetBytes((short)data.Length); Array.Reverse(length); @@ -2418,7 +2419,7 @@ namespace MinecraftClient.Protocol.Handlers // Is player Sneaking (Only 1.16 and above) // Currently hardcoded to false // TODO: Update to reflect the real player state - if (protocolversion >= MC_1_16_Version) + if (protocolVersion >= MC_1_16_Version) fields.AddRange(dataTypes.GetBool(false)); SendPacket(PacketTypesOut.InteractEntity, fields); @@ -2444,7 +2445,7 @@ namespace MinecraftClient.Protocol.Handlers // Is player Sneaking (Only 1.16 and above) // Currently hardcoded to false // TODO: Update to reflect the real player state - if (protocolversion >= MC_1_16_Version) + if (protocolVersion >= MC_1_16_Version) fields.AddRange(dataTypes.GetBool(false)); SendPacket(PacketTypesOut.InteractEntity, fields); return true; @@ -2464,7 +2465,7 @@ namespace MinecraftClient.Protocol.Handlers // Is player Sneaking (Only 1.16 and above) // Currently hardcoded to false // TODO: Update to reflect the real player state - if (protocolversion >= MC_1_16_Version) + if (protocolVersion >= MC_1_16_Version) fields.AddRange(dataTypes.GetBool(false)); SendPacket(PacketTypesOut.InteractEntity, fields); return true; @@ -2480,7 +2481,7 @@ namespace MinecraftClient.Protocol.Handlers public bool SendUseItem(int hand, int sequenceId) { - if (protocolversion < MC_1_9_Version) + if (protocolVersion < MC_1_9_Version) return false; // Packet does not exist prior to MC 1.9 // According to https://wiki.vg/index.php?title=Protocol&oldid=5486#Player_Block_Placement // MC 1.7 does this using Player Block Placement with special values @@ -2489,7 +2490,7 @@ namespace MinecraftClient.Protocol.Handlers { List packet = new List(); packet.AddRange(dataTypes.GetVarInt(hand)); - if (protocolversion >= MC_1_19_Version) + if (protocolVersion >= MC_1_19_Version) packet.AddRange(dataTypes.GetVarInt(sequenceId)); SendPacket(PacketTypesOut.UseItem, packet); return true; @@ -2507,7 +2508,7 @@ namespace MinecraftClient.Protocol.Handlers packet.AddRange(dataTypes.GetVarInt(status)); packet.AddRange(dataTypes.GetLocation(location)); packet.AddRange(dataTypes.GetVarInt(dataTypes.GetBlockFace(face))); - if (protocolversion >= MC_1_19_Version) + if (protocolVersion >= MC_1_19_Version) packet.AddRange(dataTypes.GetVarInt(sequenceId)); SendPacket(PacketTypesOut.PlayerDigging, packet); return true; @@ -2519,7 +2520,7 @@ namespace MinecraftClient.Protocol.Handlers public bool SendPlayerBlockPlacement(int hand, Location location, Direction face, int sequenceId) { - if (protocolversion < MC_1_14_Version) + if (protocolVersion < MC_1_14_Version) return false; // NOT IMPLEMENTED for older MC versions try { @@ -2531,7 +2532,7 @@ namespace MinecraftClient.Protocol.Handlers packet.AddRange(dataTypes.GetFloat(0.5f)); // cursorY packet.AddRange(dataTypes.GetFloat(0.5f)); // cursorZ packet.Add(0); // insideBlock = false; - if (protocolversion >= MC_1_19_Version) + if (protocolVersion >= MC_1_19_Version) packet.AddRange(dataTypes.GetVarInt(sequenceId)); SendPacket(PacketTypesOut.PlayerBlockPlacement, packet); return true; @@ -2594,13 +2595,13 @@ namespace MinecraftClient.Protocol.Handlers packet.Add((byte)windowId); // Window ID // 1.18+ - if (protocolversion >= MC_1_18_1_Version) + if (protocolVersion >= MC_1_18_1_Version) { packet.AddRange(dataTypes.GetVarInt(stateId)); // State ID packet.AddRange(dataTypes.GetShort((short)slotId)); // Slot ID } // 1.17.1 - else if (protocolversion == MC_1_17_1_Version) + else if (protocolVersion == MC_1_17_1_Version) { packet.AddRange(dataTypes.GetShort((short)slotId)); // Slot ID packet.AddRange(dataTypes.GetVarInt(stateId)); // State ID @@ -2613,15 +2614,15 @@ namespace MinecraftClient.Protocol.Handlers packet.Add(button); // Button - if (protocolversion < MC_1_17_Version) + if (protocolVersion < MC_1_17_Version) packet.AddRange(dataTypes.GetShort(actionNumber)); - if (protocolversion >= MC_1_9_Version) + if (protocolVersion >= MC_1_9_Version) packet.AddRange(dataTypes.GetVarInt(mode)); // Mode else packet.Add(mode); // 1.17+ Array of changed slots - if (protocolversion >= MC_1_17_Version) + if (protocolVersion >= MC_1_17_Version) { packet.AddRange(dataTypes.GetVarInt(changedSlots.Count)); // Length of the array foreach (var slot in changedSlots) @@ -2664,12 +2665,12 @@ namespace MinecraftClient.Protocol.Handlers { List packet = new List(); - if (protocolversion < MC_1_8_Version) + if (protocolVersion < MC_1_8_Version) { packet.AddRange(dataTypes.GetInt(playerid)); packet.Add((byte)1); // Swing arm } - else if (protocolversion < MC_1_9_Version) + else if (protocolVersion < MC_1_9_Version) { // No fields in 1.8.X } @@ -2737,7 +2738,7 @@ namespace MinecraftClient.Protocol.Handlers public bool UpdateCommandBlock(Location location, string command, CommandBlockMode mode, CommandBlockFlags flags) { - if (protocolversion <= MC_1_13_Version) + if (protocolVersion <= MC_1_13_Version) { try { @@ -2775,7 +2776,7 @@ namespace MinecraftClient.Protocol.Handlers public bool SelectTrade(int selectedSlot) { // MC 1.13 or greater - if (protocolversion >= MC_1_13_Version) + if (protocolVersion >= MC_1_13_Version) { try { @@ -2794,7 +2795,7 @@ namespace MinecraftClient.Protocol.Handlers public bool SendSpectate(Guid UUID) { // MC 1.8 or greater - if (protocolversion >= MC_1_8_Version) + if (protocolVersion >= MC_1_8_Version) { try { From 9e2f6d3b57541c797fd950655a46d363b3f99423 Mon Sep 17 00:00:00 2001 From: Milutinke Date: Sun, 28 Aug 2022 13:59:55 +0200 Subject: [PATCH 06/20] Updated the README.md and the configs/README.md --- MinecraftClient/config/README.md | 515 +------------------------------ README.md | 58 ++-- 2 files changed, 25 insertions(+), 548 deletions(-) diff --git a/MinecraftClient/config/README.md b/MinecraftClient/config/README.md index 4901a4e8..61a446f6 100644 --- a/MinecraftClient/config/README.md +++ b/MinecraftClient/config/README.md @@ -1,517 +1,4 @@ Minecraft Console Client User Manual ====== -**Thanks for dowloading Minecraft Console Client!** - -Minecraft Console Client is a lightweight app able to connect to any minecraft server, -both offline and online mode. It enables you to send commands and receive text messages -in a fast and easy way without having to open the main Minecraft game. - -How to use ------- - -First, extract the archive if not already extracted. -On Windows, simply open MinecraftClient.exe by double-clicking on it. -On Mac or Linux you need to install the Mono Runtime: - - On Mac: http://www.mono-project.com/download/#download-mac - - On Linux: sudo apt-get install mono-runtime libmono-reflection-cil -Then, open a terminal in this folder and run "mono MinecraftClient.exe". -If you cannot authenticate on Mono because you have TLS/HTTPS/Certificate errors, you'll need to run `mozroots --import --ask-remove` once or install `ca-certificates-mono` (See [#1708](https://github.com/MCCTeam/Minecraft-Console-Client/issues/1708#issuecomment-893768862)). -If Mono crashes, retry with `mono-complete` instead of `mono-runtime`. Use at least Mono v4.0. - -Docker ------- - -Using Docker do the following: - -**Building the Image:** -```bash -# Using HTTPS -git clone https://github.com/MCCTeam/Minecraft-Console-Client.git - -# Using SSH -git clone git@github.com:MCCTeam/Minecraft-Console-Client.git - -cd Minecraft-Console-Client/Docker - -docker build -t minecraft-console-client:latest . -``` - -**Start the container using Docker:** -```bash -# You could also ignore the -v parameter if you dont want to mount the volume that is up to you. If you don't it's harder to edit the .ini file if thats something you want to do -docker run -it -v :/opt/data minecraft-console-client:latest -``` -Now you could login and the Client is running. To detach from the Client but still keep it running in the Background press: `CTRL + P`, `CTRL + Q`. -To reattach use the `docker attach` command. - -**Start the container using docker-compose:** - -By default, the volume of the container gets mapped into a new folder named `data` in the same folder the `docker-compose.yml` is stored. - -If you don't want to map a volume, you have to comment out or delete the entire volumes section: -```yml -#volumes: -#- './data:/opt/data' -``` -Make sure you are in the directory the `docker-compose.yml` is stored before you attempt to start. If you do so, you can start the container: -```bash -docker-compose run MCC -``` -Remember to remove the container after usage: -```bash -docker-compose down -``` - -If you use the INI file and entered your data (username, password, server) there, you can start your container using -```bash -docker-compose up -docker-compose up -d #for deamonized running in the background -``` -Note that you won't be able to interact with the client using `docker-compose up`. If you want that functionality, please use the first method: `docker-compose run MCC`. -As above, you can stop and remove the container using -```bash -docker-compose down -``` - -Using Configuration files & Enabling bots ------- - -Simply open the INI configuration file with a text editor and change the values. -To enable a bot change the `enabled` value in the INI file from `false` to `true`. -You will still be able to send and receive chat messages when a bot is loaded. -You can remove or comment some lines from the INI file to use the default values instead. -You can have several INI files and drag & drop one of them over MinecraftClient.exe - -Command-line usage ------- - -Quick usage: - -``` -MinecraftClient.exe --help -MinecraftClient.exe -MinecraftClient.exe "/mycommand" -MinecraftClient.exe --setting=value [--other settings] -MinecraftClient.exe --section.setting=value [--other settings] -MinecraftClient.exe [--other settings] -``` -You can mix and match arguments by following theses rules: - * First positional argument may be either the login or settings file - * Other positional arguments are read in order: login, password, server, command - * Arguments starting with `--` can be in any order and position - -Examples and further explanations: - -``` -MinecraftClient.exe -``` - -* This will automatically connect you to the chosen server. -* You may omit password and/or server to specify e.g. only the login -* To specify a server but ask password interactively, use `""` as password. -* To specify offline mode with no password, use `-` as password. - -``` -MinecraftClient.exe "/mycommand" -``` - -* This will automatically send `/mycommand` to the server and close. -* To send several commands and/or stay connected, use the ScriptScheduler bot instead. - -``` -MinecraftClient.exe -``` - -* This will load the specified configuration file -* If the file contains login / password / server ip, it will automatically connect. - -``` -MinecraftClient.exe --setting=value [--other settings] -``` - -* Specify settings on the command-line, see possible value in the configuration file -* Use `--section.setting=value` for settings outside the `[Main]` section -* Example: `--antiafk.enabled=true` for enabling the AntiAFK bot - -``` -MinecraftClient.exe [--other settings] -``` - -* Load the specified configuration file and override some settings from the file - -Internal commands ------- - -These commands can be performed from the chat prompt, scripts or remote control. -From chat prompt, commands must by default be prepended with a slash, eg. `/quit`. -In scripts and remote control, no slash is needed to perform the command, eg. `quit`. - - - `quit` or `exit`: disconnect from the server and close the application - - `reco [account]`: disconnect and reconnect to the server - - `connect [account]`: go to the given server and resume the script - - `script