Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support 1.21.20 #262

Merged
merged 5 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions minecraft/protocol/ability.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const (
AbilityLayerTypeSpectator
AbilityLayerTypeCommands
AbilityLayerTypeEditor
AbilityLayerTypeLoadingScreen
)

const (
Expand Down
26 changes: 24 additions & 2 deletions minecraft/protocol/camera.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,20 @@ func (x *CameraInstructionFade) Marshal(r IO) {
OptionalFunc(r, &x.Colour, r.RGB)
}

// CameraInstructionTarget represents a camera instruction that targets a specific entity.
type CameraInstructionTarget struct {
// CenterOffset is the offset from the center of the entity that the camera should target.
CenterOffset Optional[mgl32.Vec3]
// EntityUniqueID is the unique ID of the entity that the camera should target.
EntityUniqueID int64
}

// Marshal encodes/decodes a CameraInstructionTarget.
func (x *CameraInstructionTarget) Marshal(r IO) {
OptionalFunc(r, &x.CenterOffset, r.Vec3)
r.Int64(&x.EntityUniqueID)
}

// CameraPreset represents a basic preset that can be extended upon by more complex instructions.
type CameraPreset struct {
// Name is the name of the preset. Each preset must have their own unique name.
Expand All @@ -134,8 +148,14 @@ type CameraPreset struct {
RotX Optional[float32]
// RotY is the default yaw of the camera.
RotY Optional[float32]
// AudioListener defines where the audio should be played from when using this preset. This is one of the constants
// above.
// ViewOffset is only used in a follow_orbit camera and controls an offset based on a pivot point to the
// player, causing it to be shifted in a certain direction.
ViewOffset Optional[mgl32.Vec2]
// Radius is only used in a follow_orbit camera and controls how far away from the player the camera should
// be rendered.
Radius Optional[float32]
// AudioListener defines where the audio should be played from when using this preset. This is one of the
// constants above.
AudioListener Optional[byte]
// PlayerEffects is currently unknown.
PlayerEffects Optional[bool]
Expand All @@ -150,6 +170,8 @@ func (x *CameraPreset) Marshal(r IO) {
OptionalFunc(r, &x.PosZ, r.Float32)
OptionalFunc(r, &x.RotX, r.Float32)
OptionalFunc(r, &x.RotY, r.Float32)
OptionalFunc(r, &x.ViewOffset, r.Vec2)
OptionalFunc(r, &x.Radius, r.Float32)
OptionalFunc(r, &x.AudioListener, r.Uint8)
OptionalFunc(r, &x.PlayerEffects, r.Bool)
}
15 changes: 15 additions & 0 deletions minecraft/protocol/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const (
ContainerCreatedOutput
ContainerSmithingTableTemplate
ContainerCrafterLevelEntity
ContainerDynamic
)

const (
Expand Down Expand Up @@ -106,3 +107,17 @@ const (
ContainerTypeDecoratedPot
ContainerTypeCrafter
)

// FullContainerName contains information required to identify a container in a StackRequestSlotInfo.
type FullContainerName struct {
// ContainerID is the ID of the container that the slot was in.
ContainerID byte
// DynamicContainerID is the ID of the container if it is dynamic. If the container is not dynamic, this field is
// set to 0.
DynamicContainerID uint32
}

func (x *FullContainerName) Marshal(r IO) {
r.Uint8(&x.ContainerID)
r.Uint32(&x.DynamicContainerID)
}
3 changes: 3 additions & 0 deletions minecraft/protocol/entity_link.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ type EntityLink struct {
// RiderInitiated specifies if the link was created by the rider, for example the player starting to ride
// a horse by itself. This is generally true in vanilla environment for players.
RiderInitiated bool
// VehicleAngularVelocity is the angular velocity of the vehicle that the rider is riding.
VehicleAngularVelocity float32
}

// Marshal encodes/decodes a single entity link.
Expand All @@ -36,4 +38,5 @@ func (x *EntityLink) Marshal(r IO) {
r.Uint8(&x.Type)
r.Bool(&x.Immediate)
r.Bool(&x.RiderInitiated)
r.Float32(&x.VehicleAngularVelocity)
}
4 changes: 2 additions & 2 deletions minecraft/protocol/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package protocol

const (
// CurrentProtocol is the current protocol version for the version below.
CurrentProtocol = 686
CurrentProtocol = 712
// CurrentVersion is the current version of Minecraft as supported by the `packet` package.
CurrentVersion = "1.21.2"
CurrentVersion = "1.21.20"
)
21 changes: 21 additions & 0 deletions minecraft/protocol/inventory.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,17 @@ const (
UseItemActionBreakBlock
)

const (
TriggerTypeUnknown = iota
TriggerTypePlayerInput
TriggerTypeSimulationTick
)

const (
ClientPredictionFailure = iota
ClientPredictionSuccess
)

// UseItemTransactionData represents an inventory transaction data object sent when the client uses an item on
// a block.
type UseItemTransactionData struct {
Expand All @@ -142,6 +153,11 @@ type UseItemTransactionData struct {
// ActionType is the type of the UseItem inventory transaction. It is one of the action types found above,
// and specifies the way the player interacted with the block.
ActionType uint32
// TriggerType is the type of the trigger that caused the inventory transaction. It is one of the trigger
// types found in the constants above. If TriggerType is TriggerTypePlayerInput, the transaction is from
// the initial input of the player. If it is TriggerTypeSimulationTick, the transaction is from a simulation
// tick when the player is holding down the input.
TriggerType uint32
// BlockPosition is the position of the block that was interacted with. This is only really a correct
// block position if ActionType is not UseItemActionClickAir.
BlockPosition BlockPos
Expand All @@ -163,6 +179,9 @@ type UseItemTransactionData struct {
// BlockRuntimeID is the runtime ID of the block that was clicked. It may be used by the server to verify
// that the player's world client-side is synchronised with the server's.
BlockRuntimeID uint32
// ClientPrediction is the client's prediction on the output of the transaction. It is one of the client
// prediction found in the constants above.
ClientPrediction uint32
}

const (
Expand Down Expand Up @@ -219,13 +238,15 @@ type ReleaseItemTransactionData struct {
// Marshal ...
func (data *UseItemTransactionData) Marshal(r IO) {
r.Varuint32(&data.ActionType)
r.Varuint32(&data.TriggerType)
r.UBlockPos(&data.BlockPosition)
r.Varint32(&data.BlockFace)
r.Varint32(&data.HotBarSlot)
r.ItemInstance(&data.HeldItem)
r.Vec3(&data.Position)
r.Vec3(&data.ClickedPosition)
r.Varuint32(&data.BlockRuntimeID)
r.Varuint32(&data.ClientPrediction)
}

// Marshal ...
Expand Down
25 changes: 22 additions & 3 deletions minecraft/protocol/item_stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,11 +468,15 @@ type CraftRecipeStackRequestAction struct {
// one of the recipes sent in the CraftingData packet, where each of the recipes have a RecipeNetworkID as
// of 1.16.
RecipeNetworkID uint32
// NumberOfCrafts is how many times the recipe was crafted. This field appears to be boilerplate and
// has no effect.
NumberOfCrafts byte
}

// Marshal ...
func (a *CraftRecipeStackRequestAction) Marshal(r IO) {
r.Varuint32(&a.RecipeNetworkID)
r.Uint8(&a.NumberOfCrafts)
}

// AutoCraftRecipeStackRequestAction is sent by the client similarly to the CraftRecipeStackRequestAction. The
Expand All @@ -482,6 +486,8 @@ type AutoCraftRecipeStackRequestAction struct {
// one of the recipes sent in the CraftingData packet, where each of the recipes have a RecipeNetworkID as
// of 1.16.
RecipeNetworkID uint32
// NumberOfCrafts is how many times the recipe was crafted. This field is just a duplicate of TimesCrafted.
NumberOfCrafts byte
// TimesCrafted is how many times the recipe was crafted.
TimesCrafted byte
// Ingredients is a slice of ItemDescriptorCount that contains the ingredients that were used to craft the recipe.
Expand All @@ -492,6 +498,7 @@ type AutoCraftRecipeStackRequestAction struct {
// Marshal ...
func (a *AutoCraftRecipeStackRequestAction) Marshal(r IO) {
r.Varuint32(&a.RecipeNetworkID)
r.Uint8(&a.NumberOfCrafts)
r.Uint8(&a.TimesCrafted)
FuncSlice(r, &a.Ingredients, r.ItemDescriptorCount)
}
Expand All @@ -502,11 +509,15 @@ type CraftCreativeStackRequestAction struct {
// CreativeItemNetworkID is the network ID of the creative item that is being created. This is one of the
// creative item network IDs sent in the CreativeContent packet.
CreativeItemNetworkID uint32
// NumberOfCrafts is how many times the recipe was crafted. This field appears to be boilerplate and
// has no effect.
NumberOfCrafts byte
}

// Marshal ...
func (a *CraftCreativeStackRequestAction) Marshal(r IO) {
r.Varuint32(&a.CreativeItemNetworkID)
r.Uint8(&a.NumberOfCrafts)
}

// CraftRecipeOptionalStackRequestAction is sent when using an anvil. When this action is sent, the
Expand All @@ -517,13 +528,17 @@ type CraftRecipeOptionalStackRequestAction struct {
// one of the multi-recipes sent in the CraftingData packet, where each of the recipes have a RecipeNetworkID as
// of 1.16.
RecipeNetworkID uint32
// NumberOfCrafts is how many times the recipe was crafted. This field appears to be boilerplate and
// has no effect.
NumberOfCrafts byte
// FilterStringIndex is the index of a filter string sent in a ItemStackRequest.
FilterStringIndex int32
}

// Marshal ...
func (c *CraftRecipeOptionalStackRequestAction) Marshal(r IO) {
r.Varuint32(&c.RecipeNetworkID)
r.Uint8(&c.NumberOfCrafts)
r.Int32(&c.FilterStringIndex)
}

Expand All @@ -534,13 +549,17 @@ type CraftGrindstoneRecipeStackRequestAction struct {
// one of the recipes sent in the CraftingData packet, where each of the recipes have a RecipeNetworkID as
// of 1.16.
RecipeNetworkID uint32
// NumberOfCrafts is how many times the recipe was crafted. This field appears to be boilerplate and
// has no effect.
NumberOfCrafts byte
// Cost is the cost of the recipe that was crafted.
Cost int32
}

// Marshal ...
func (c *CraftGrindstoneRecipeStackRequestAction) Marshal(r IO) {
r.Varuint32(&c.RecipeNetworkID)
r.Uint8(&c.NumberOfCrafts)
r.Varint32(&c.Cost)
}

Expand Down Expand Up @@ -580,8 +599,8 @@ func (a *CraftResultsDeprecatedStackRequestAction) Marshal(r IO) {

// StackRequestSlotInfo holds information on a specific slot client-side.
type StackRequestSlotInfo struct {
// ContainerID is the ID of the container that the slot was in.
ContainerID byte
// Container is the FullContainerName that describes the container that the slot is in.
Container FullContainerName
// Slot is the index of the slot within the container with the ContainerID above.
Slot byte
// StackNetworkID is the unique stack ID that the client assumes to be present in this slot. The server
Expand All @@ -592,7 +611,7 @@ type StackRequestSlotInfo struct {

// StackReqSlotInfo reads/writes a StackRequestSlotInfo x using IO r.
func StackReqSlotInfo(r IO, x *StackRequestSlotInfo) {
r.Uint8(&x.ContainerID)
Single(r, &x.Container)
r.Uint8(&x.Slot)
r.Varint32(&x.StackNetworkID)
}
6 changes: 6 additions & 0 deletions minecraft/protocol/packet/camera_instruction.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ type CameraInstruction struct {
Clear protocol.Optional[bool]
// Fade is a camera instruction that fades the screen to a specified colour.
Fade protocol.Optional[protocol.CameraInstructionFade]
// Target is a camera instruction that targets a specific entity.
Target protocol.Optional[protocol.CameraInstructionTarget]
// RemoveTarget can be set to true to remove the current target entity.
RemoveTarget protocol.Optional[bool]
}

// ID ...
Expand All @@ -23,4 +27,6 @@ func (pk *CameraInstruction) Marshal(io protocol.IO) {
protocol.OptionalMarshaler(io, &pk.Set)
protocol.OptionalFunc(io, &pk.Clear, io.Bool)
protocol.OptionalMarshaler(io, &pk.Fade)
protocol.OptionalMarshaler(io, &pk.Target)
protocol.OptionalFunc(io, &pk.RemoveTarget, io.Bool)
}
6 changes: 6 additions & 0 deletions minecraft/protocol/packet/change_dimension.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ type ChangeDimension struct {
// PlayerActionDimensionChangeRequest if it dies in another dimension, indicating that it needs a
// DimensionChange packet with Respawn set to true.
Respawn bool
// LoadingScreenID is a unique ID for the loading screen that the player is currently in. The client will
// update the server on its state through the ServerBoundLoadingScreen packet, and it can be used to not
// send specific packets to the client if it is changing dimensions. This field should be unique for every
//ChangeDimension packet sent.
LoadingScreenID protocol.Optional[uint32]
}

// ID ...
Expand All @@ -39,4 +44,5 @@ func (pk *ChangeDimension) Marshal(io protocol.IO) {
io.Varint32(&pk.Dimension)
io.Vec3(&pk.Position)
io.Bool(&pk.Respawn)
protocol.OptionalFunc(io, &pk.LoadingScreenID, io.Uint32)
}
8 changes: 4 additions & 4 deletions minecraft/protocol/packet/compressed_biome_definition_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (
// CompressedBiomeDefinitionList is sent by the server to send a list of biomes to the client. The contents of this packet
// are very large, even after being compressed. This packet is only required when using client-side chunk generation.
type CompressedBiomeDefinitionList struct {
// Biomes is a map of biomes with their identifier as key, and the biome data as value. The biome data contains many
// different fields such as climate, surface materials and generation rules etc.
Biomes map[string]any
// SerialisedBiomeDefinitions is a network NBT serialised compound of all definitions of biomes that are
// available on the server.
SerialisedBiomeDefinitions []byte
}

// ID ...
Expand All @@ -18,5 +18,5 @@ func (*CompressedBiomeDefinitionList) ID() uint32 {
}

func (pk *CompressedBiomeDefinitionList) Marshal(io protocol.IO) {
io.CompressedBiomeDefinitions(&pk.Biomes)
io.Bytes(&pk.SerialisedBiomeDefinitions)
}
3 changes: 3 additions & 0 deletions minecraft/protocol/packet/correct_player_move_prediction.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ type CorrectPlayerMovePrediction struct {
// Rotation is the rotation of the player at the tick written in the field below. It is only included if
// PredictionType is PredictionTypeVehicle.
Rotation mgl32.Vec2
// VehicleAngularVelocity is the angular velocity of the vehicle that the rider is riding.
VehicleAngularVelocity protocol.Optional[float32]
// OnGround specifies if the player was on the ground at the time of the tick below.
OnGround bool
// Tick is the tick of the movement which was corrected by this packet.
Expand All @@ -42,6 +44,7 @@ func (pk *CorrectPlayerMovePrediction) Marshal(io protocol.IO) {
io.Vec3(&pk.Delta)
if pk.PredictionType == PredictionTypeVehicle {
io.Vec2(&pk.Rotation)
protocol.OptionalFunc(io, &pk.VehicleAngularVelocity, io.Float32)
}
io.Bool(&pk.OnGround)
io.Varuint64(&pk.Tick)
Expand Down
22 changes: 22 additions & 0 deletions minecraft/protocol/packet/current_structure_feature.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package packet

import (
"github.com/sandertv/gophertunnel/minecraft/protocol"
)

// CurrentStructureFeature is sent by the server to let the client know the name of the structure feature
// that the player is currently occupying.
type CurrentStructureFeature struct {
// CurrentFeature is the identifier of the structure feature that the player is currently occupying.
// If the player is not occupying any structure feature, this field is empty.
CurrentFeature string
}

// ID ...
func (*CurrentStructureFeature) ID() uint32 {
return IDCurrentStructureFeature
}

func (pk *CurrentStructureFeature) Marshal(io protocol.IO) {
io.String(&pk.CurrentFeature)
}
3 changes: 3 additions & 0 deletions minecraft/protocol/packet/disconnect.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ type Disconnect struct {
// Message is an optional message to show when disconnected. This message is only written if the
// HideDisconnectionScreen field is set to true.
Message string
// FilteredMessage is always set to empty and the usage is currently unknown.
FilteredMessage string
}

// ID ...
Expand All @@ -28,5 +30,6 @@ func (pk *Disconnect) Marshal(io protocol.IO) {
io.Bool(&pk.HideDisconnectionScreen)
if !pk.HideDisconnectionScreen {
io.String(&pk.Message)
io.String(&pk.FilteredMessage)
}
}
3 changes: 3 additions & 0 deletions minecraft/protocol/packet/editor_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
// EditorNetwork is a packet sent from the server to the client and vise-versa to communicate editor-mode related
// information. It carries a single compound tag containing the relevant information.
type EditorNetwork struct {
// RouteToManager ...
RouteToManager bool
// Payload is a network little endian compound tag holding data relevant to the editor.
Payload map[string]any
}
Expand All @@ -18,5 +20,6 @@ func (*EditorNetwork) ID() uint32 {
}

func (pk *EditorNetwork) Marshal(io protocol.IO) {
io.Bool(&pk.RouteToManager)
io.NBT(&pk.Payload, nbt.NetworkLittleEndian)
}
Loading
Loading