From 14c3da77d7606fd6b42f577d70722aa8a0e96a56 Mon Sep 17 00:00:00 2001 From: TwistedAsylumMC Date: Fri, 8 Dec 2023 18:37:39 +0000 Subject: [PATCH] minecraft/protocol: Update to support 1.20.50 --- minecraft/protocol/container.go | 3 + minecraft/protocol/info.go | 4 +- minecraft/protocol/packet/compression.go | 4 +- minecraft/protocol/packet/crafting_event.go | 38 ------------ minecraft/protocol/packet/id.go | 4 +- minecraft/protocol/packet/level_event.go | 2 + .../protocol/packet/level_sound_event.go | 7 +++ minecraft/protocol/packet/network_settings.go | 6 ++ .../player_toggle_crafter_slot_request.go | 32 ++++++++++ minecraft/protocol/packet/pool.go | 18 +++--- .../packet/set_player_inventory_options.go | 58 +++++++++++++++++++ minecraft/protocol/packet/show_store_offer.go | 18 ++++-- minecraft/protocol/recipe.go | 9 +-- 13 files changed, 140 insertions(+), 63 deletions(-) delete mode 100644 minecraft/protocol/packet/crafting_event.go create mode 100644 minecraft/protocol/packet/player_toggle_crafter_slot_request.go create mode 100644 minecraft/protocol/packet/set_player_inventory_options.go diff --git a/minecraft/protocol/container.go b/minecraft/protocol/container.go index b228e557..daac53ea 100644 --- a/minecraft/protocol/container.go +++ b/minecraft/protocol/container.go @@ -63,6 +63,7 @@ const ( ContainerCursor ContainerCreatedOutput ContainerSmithingTableTemplate + ContainerCrafterLevelEntity ) const ( @@ -102,4 +103,6 @@ const ( ContainerTypeJigsawEditor ContainerTypeSmithingTable ContainerTypeChestBoat + ContainerTypeDecoratedPot + ContainerTypeCrafter ) diff --git a/minecraft/protocol/info.go b/minecraft/protocol/info.go index 1a2e0a87..7b091441 100644 --- a/minecraft/protocol/info.go +++ b/minecraft/protocol/info.go @@ -2,7 +2,7 @@ package protocol const ( // CurrentProtocol is the current protocol version for the version below. - CurrentProtocol = 622 + CurrentProtocol = 630 // CurrentVersion is the current version of Minecraft as supported by the `packet` package. - CurrentVersion = "1.20.40" + CurrentVersion = "1.20.50" ) diff --git a/minecraft/protocol/packet/compression.go b/minecraft/protocol/packet/compression.go index ffa33aa2..77b23e4c 100644 --- a/minecraft/protocol/packet/compression.go +++ b/minecraft/protocol/packet/compression.go @@ -54,7 +54,7 @@ var ( // EncodeCompression ... func (flateCompression) EncodeCompression() uint16 { - return 0 + return CompressionAlgorithmFlate } // Compress ... @@ -103,7 +103,7 @@ func (flateCompression) Decompress(compressed []byte) ([]byte, error) { // EncodeCompression ... func (snappyCompression) EncodeCompression() uint16 { - return 1 + return CompressionAlgorithmSnappy } // Compress ... diff --git a/minecraft/protocol/packet/crafting_event.go b/minecraft/protocol/packet/crafting_event.go deleted file mode 100644 index d24c55f2..00000000 --- a/minecraft/protocol/packet/crafting_event.go +++ /dev/null @@ -1,38 +0,0 @@ -package packet - -import ( - "github.com/google/uuid" - "github.com/sandertv/gophertunnel/minecraft/protocol" -) - -// CraftingEvent is sent by the client when it crafts a particular item. Note that this packet may be fully -// ignored, as the InventoryTransaction packet provides all the information required. -type CraftingEvent struct { - // WindowID is the ID representing the window that the player crafted in. - WindowID byte - // CraftingType is a type that indicates the way the crafting was done, for example if a crafting table - // was used. - // TODO: Find out the options of the CraftingType field in the CraftingEvent packet. - CraftingType int32 - // RecipeUUID is the UUID of the recipe that was crafted. It points to the UUID of the recipe that was - // sent earlier in the CraftingData packet. - RecipeUUID uuid.UUID - // Input is a list of items that the player put into the recipe so that it could create the Output items. - // These items are consumed in the process. - Input []protocol.ItemInstance - // Output is a list of items that were obtained as a result of crafting the recipe. - Output []protocol.ItemInstance -} - -// ID ... -func (*CraftingEvent) ID() uint32 { - return IDCraftingEvent -} - -func (pk *CraftingEvent) Marshal(io protocol.IO) { - io.Uint8(&pk.WindowID) - io.Varint32(&pk.CraftingType) - io.UUID(&pk.RecipeUUID) - protocol.FuncSlice(io, &pk.Input, io.ItemInstance) - protocol.FuncSlice(io, &pk.Output, io.ItemInstance) -} diff --git a/minecraft/protocol/packet/id.go b/minecraft/protocol/packet/id.go index 0c104158..e24abccc 100644 --- a/minecraft/protocol/packet/id.go +++ b/minecraft/protocol/packet/id.go @@ -53,7 +53,7 @@ const ( IDInventorySlot IDContainerSetData IDCraftingData - IDCraftingEvent + _ IDGUIDataPickItem IDAdventureSettings IDBlockActorData @@ -206,4 +206,6 @@ const ( IDOpenSign IDAgentAnimation IDRefreshEntitlements + IDPlayerToggleCrafterSlotRequest + IDSetPlayerInventoryOptions ) diff --git a/minecraft/protocol/packet/level_event.go b/minecraft/protocol/packet/level_event.go index 15560f6f..4b02bfaa 100644 --- a/minecraft/protocol/packet/level_event.go +++ b/minecraft/protocol/packet/level_event.go @@ -86,6 +86,7 @@ const ( LevelEventSculkCharge = 2037 LevelEventSculkChargePop = 2038 LevelEventSonicExplosion = 2039 + LevelEventDustPlume = 2040 LevelEventStartRaining = 3001 LevelEventStartThunderstorm = 3002 LevelEventStopRaining = 3003 @@ -118,6 +119,7 @@ const ( LevelEventParticlesCrackBlockSouth = 3606 LevelEventParticlesCrackBlockWest = 3607 LevelEventParticlesCrackBlockEast = 3608 + LevelEventParticlesShootWhiteSmoke = 3609 LevelEventAllPlayersSleeping = 9800 LevelEventSleepingPlayers = 9801 LevelEventJumpPrevented = 9810 diff --git a/minecraft/protocol/packet/level_sound_event.go b/minecraft/protocol/packet/level_sound_event.go index 51d4f4c6..dbf39c79 100644 --- a/minecraft/protocol/packet/level_sound_event.go +++ b/minecraft/protocol/packet/level_sound_event.go @@ -486,6 +486,13 @@ const ( SoundEventAmbientUnderwaterExit SoundEventBottleFill SoundEventBottleEmpty + SoundEventCrafterCraft + SoundEventCrafterFail + SoundEventDecoratedPotInsert + SoundEventDecoratedPotInsertFail + SoundEventCrafterDisableSlot + SoundEventCopperBulbTurnOn + SoundEventCopperBulbTurnOff ) // LevelSoundEvent is sent by the server to make any kind of built-in sound heard to a player. It is sent to, diff --git a/minecraft/protocol/packet/network_settings.go b/minecraft/protocol/packet/network_settings.go index d70c2b6d..98c27ef8 100644 --- a/minecraft/protocol/packet/network_settings.go +++ b/minecraft/protocol/packet/network_settings.go @@ -4,6 +4,12 @@ import ( "github.com/sandertv/gophertunnel/minecraft/protocol" ) +const ( + CompressionAlgorithmFlate = iota + CompressionAlgorithmSnappy + CompressionAlgorithmNone = 0xffff +) + // NetworkSettings is sent by the server to update a variety of network settings. These settings modify the // way packets are sent over the network stack. type NetworkSettings struct { diff --git a/minecraft/protocol/packet/player_toggle_crafter_slot_request.go b/minecraft/protocol/packet/player_toggle_crafter_slot_request.go new file mode 100644 index 00000000..66f5fbc3 --- /dev/null +++ b/minecraft/protocol/packet/player_toggle_crafter_slot_request.go @@ -0,0 +1,32 @@ +package packet + +import ( + "github.com/sandertv/gophertunnel/minecraft/protocol" +) + +// PlayerToggleCrafterSlotRequest is sent by the client when it tries to toggle the state of a slot within a Crafter. +type PlayerToggleCrafterSlotRequest struct { + // PosX is the X position of the Crafter that is being modified. + PosX int32 + // PosY is the Y position of the Crafter that is being modified. + PosY int32 + // PosZ is the Z position of the Crafter that is being modified. + PosZ int32 + // Slot is the index of the slot that was toggled. This should be a value between 0 and 8. + Slot byte + // Disabled is the new state of the slot. If true, the slot is disabled, if false, the slot is enabled. + Disabled bool +} + +// ID ... +func (*PlayerToggleCrafterSlotRequest) ID() uint32 { + return IDPlayerToggleCrafterSlotRequest +} + +func (pk *PlayerToggleCrafterSlotRequest) Marshal(io protocol.IO) { + io.Int32(&pk.PosX) + io.Int32(&pk.PosY) + io.Int32(&pk.PosZ) + io.Uint8(&pk.Slot) + io.Bool(&pk.Disabled) +} diff --git a/minecraft/protocol/packet/pool.go b/minecraft/protocol/packet/pool.go index 896c5677..88691e82 100644 --- a/minecraft/protocol/packet/pool.go +++ b/minecraft/protocol/packet/pool.go @@ -98,7 +98,6 @@ func init() { IDInventorySlot: func() Packet { return &InventorySlot{} }, IDContainerSetData: func() Packet { return &ContainerSetData{} }, IDCraftingData: func() Packet { return &CraftingData{} }, - IDCraftingEvent: func() Packet { return &CraftingEvent{} }, IDGUIDataPickItem: func() Packet { return &GUIDataPickItem{} }, IDAdventureSettings: func() Packet { return &AdventureSettings{} }, IDBlockActorData: func() Packet { return &BlockActorData{} }, @@ -245,12 +244,14 @@ func init() { IDCameraPresets: func() Packet { return &CameraPresets{} }, IDUnlockedRecipes: func() Packet { return &UnlockedRecipes{} }, // --- - IDCameraInstruction: func() Packet { return &CameraInstruction{} }, - IDCompressedBiomeDefinitionList: func() Packet { return &CompressedBiomeDefinitionList{} }, - IDTrimData: func() Packet { return &TrimData{} }, - IDOpenSign: func() Packet { return &OpenSign{} }, - IDAgentAnimation: func() Packet { return &AgentAnimation{} }, - IDRefreshEntitlements: func() Packet { return &RefreshEntitlements{} }, + IDCameraInstruction: func() Packet { return &CameraInstruction{} }, + IDCompressedBiomeDefinitionList: func() Packet { return &CompressedBiomeDefinitionList{} }, + IDTrimData: func() Packet { return &TrimData{} }, + IDOpenSign: func() Packet { return &OpenSign{} }, + IDAgentAnimation: func() Packet { return &AgentAnimation{} }, + IDRefreshEntitlements: func() Packet { return &RefreshEntitlements{} }, + IDPlayerToggleCrafterSlotRequest: func() Packet { return &PlayerToggleCrafterSlotRequest{} }, + IDSetPlayerInventoryOptions: func() Packet { return &SetPlayerInventoryOptions{} }, } for id, pk := range serverOriginating { RegisterPacketFromServer(id, pk) @@ -279,7 +280,6 @@ func init() { IDRespawn: func() Packet { return &Respawn{} }, IDContainerOpen: func() Packet { return &ContainerOpen{} }, IDContainerClose: func() Packet { return &ContainerClose{} }, - IDCraftingEvent: func() Packet { return &CraftingEvent{} }, IDAdventureSettings: func() Packet { return &AdventureSettings{} }, IDPlayerInput: func() Packet { return &PlayerInput{} }, IDSetPlayerGameType: func() Packet { return &SetPlayerGameType{} }, @@ -333,6 +333,8 @@ func init() { IDGameTestResults: func() Packet { return &GameTestResults{} }, IDOpenSign: func() Packet { return &OpenSign{} }, IDBlockActorData: func() Packet { return &BlockActorData{} }, + IDPlayerToggleCrafterSlotRequest: func() Packet { return &PlayerToggleCrafterSlotRequest{} }, + IDSetPlayerInventoryOptions: func() Packet { return &SetPlayerInventoryOptions{} }, } for id, pk := range clientOriginating { RegisterPacketFromClient(id, pk) diff --git a/minecraft/protocol/packet/set_player_inventory_options.go b/minecraft/protocol/packet/set_player_inventory_options.go new file mode 100644 index 00000000..1bf50536 --- /dev/null +++ b/minecraft/protocol/packet/set_player_inventory_options.go @@ -0,0 +1,58 @@ +package packet + +import ( + "github.com/sandertv/gophertunnel/minecraft/protocol" +) + +const ( + InventoryLayoutNone = iota + InventoryLayoutSurvival + InventoryLayoutRecipeBook + InventoryLayoutCreative +) + +const ( + InventoryLeftTabNone = iota + InventoryLeftTabConstruction + InventoryLeftTabEquipment + InventoryLeftTabItems + InventoryLeftTabNature + InventoryLeftTabSearch + InventoryLeftTabSurvival +) + +const ( + InventoryRightTabNone = iota + InventoryRightTabFullScreen + InventoryRightTabCrafting + InventoryRightTabArmour +) + +// SetPlayerInventoryOptions is sent by the client when it tries to toggle the state of a slot within a Crafter. +type SetPlayerInventoryOptions struct { + // LeftInventoryTab is the tab that is selected on the left side of the inventory. This is usually for the creative + // inventory. It is one of the constants above. + LeftInventoryTab byte + // RightInventoryTab is the tab that is selected on the right side of the inventory. This is usually for the player's + // own inventory. It is one of the constants above. + RightInventoryTab byte + // Filtering is whether the player has enabled the filtering between recipes they have unlocked or not. + Filtering bool + // InventoryLayout is the layout of the inventory. It is one of the constants above. + InventoryLayout byte + // CraftingLayout is the layout of the crafting inventory. It is one of the constants above. + CraftingLayout byte +} + +// ID ... +func (*SetPlayerInventoryOptions) ID() uint32 { + return IDSetPlayerInventoryOptions +} + +func (pk *SetPlayerInventoryOptions) Marshal(io protocol.IO) { + io.Uint8(&pk.LeftInventoryTab) + io.Uint8(&pk.RightInventoryTab) + io.Bool(&pk.Filtering) + io.Uint8(&pk.InventoryLayout) + io.Uint8(&pk.CraftingLayout) +} diff --git a/minecraft/protocol/packet/show_store_offer.go b/minecraft/protocol/packet/show_store_offer.go index 73be5fc5..c7c47907 100644 --- a/minecraft/protocol/packet/show_store_offer.go +++ b/minecraft/protocol/packet/show_store_offer.go @@ -4,6 +4,12 @@ import ( "github.com/sandertv/gophertunnel/minecraft/protocol" ) +const ( + StoreOfferTypeMarketplace = iota + StoreOfferTypeDressingRoom + StoreOfferTypeServerPage +) + // ShowStoreOffer is sent by the server to show a Marketplace store offer to a player. It opens a window // client-side that displays the item. // The ShowStoreOffer packet only works on the partnered servers: Servers that are not partnered will not have @@ -11,12 +17,12 @@ import ( // on the client side. Sending the packet does therefore not work when using a proxy that is not connected to // with the domain of one of the partnered servers. type ShowStoreOffer struct { - // OfferID is a string that identifies the offer for which a window should be opened. While typically a - // UUID, the ID could be anything. + // OfferID is a string that identifies the offer for which a window should be opened. ID should be in the format of + // a UUID, however it can be left empty if StoreOfferTypeServerPage is used. OfferID string - // ShowAll specifies if all other offers of the same 'author' as the one of the offer associated with the - // OfferID should also be displayed, alongside the target offer. - ShowAll bool + // Type is the type of the store offer that is being shown to the player. It is one of the constants that may be + // found above. + Type byte } // ID ... @@ -26,5 +32,5 @@ func (*ShowStoreOffer) ID() uint32 { func (pk *ShowStoreOffer) Marshal(io protocol.IO) { io.String(&pk.OfferID) - io.Bool(&pk.ShowAll) + io.Uint8(&pk.Type) } diff --git a/minecraft/protocol/recipe.go b/minecraft/protocol/recipe.go index e5f4b7a8..ceba5953 100644 --- a/minecraft/protocol/recipe.go +++ b/minecraft/protocol/recipe.go @@ -149,8 +149,7 @@ type ShapelessRecipe struct { Input []ItemDescriptorCount // Output is a list of items that are created as a result of crafting the recipe. Output []ItemStack - // UUID is a UUID identifying the recipe. This can actually be set to an empty UUID if the CraftingEvent - // packet is not used. + // UUID is a UUID identifying the recipe. Since the CraftingEvent packet no longer exists, this can always be empty. UUID uuid.UUID // Block is the block name that is required to craft the output of the recipe. The block is not prefixed // with 'minecraft:', so it will look like 'crafting_table' as an example. @@ -199,8 +198,7 @@ type ShapedRecipe struct { Input []ItemDescriptorCount // Output is a list of items that are created as a result of crafting the recipe. Output []ItemStack - // UUID is a UUID identifying the recipe. This can actually be set to an empty UUID if the CraftingEvent - // packet is not used. + // UUID is a UUID identifying the recipe. Since the CraftingEvent packet no longer exists, this can always be empty. UUID uuid.UUID // Block is the block name that is required to craft the output of the recipe. The block is not prefixed // with 'minecraft:', so it will look like 'crafting_table' as an example. @@ -240,8 +238,7 @@ type FurnaceDataRecipe struct { // MultiRecipe serves as an 'enable' switch for multi-shape recipes. type MultiRecipe struct { - // UUID is a UUID identifying the recipe. This can actually be set to an empty UUID if the CraftingEvent - // packet is not used. + // UUID is a UUID identifying the recipe. Since the CraftingEvent packet no longer exists, this can always be empty. UUID uuid.UUID // RecipeNetworkID is a unique ID used to identify the recipe over network. Each recipe must have a unique // network ID. Recommended is to just increment a variable for each unique recipe registered.