diff --git a/minecraft/protocol/camera.go b/minecraft/protocol/camera.go index e5e2cbd3..1ec6d91a 100644 --- a/minecraft/protocol/camera.go +++ b/minecraft/protocol/camera.go @@ -148,12 +148,14 @@ type CameraPreset struct { RotX Optional[float32] // RotY is the default yaw of the camera. RotY Optional[float32] - // ViewOffset ... + // 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 ... + // 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 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] diff --git a/minecraft/protocol/container.go b/minecraft/protocol/container.go index a2fd8e42..d9a36991 100644 --- a/minecraft/protocol/container.go +++ b/minecraft/protocol/container.go @@ -108,6 +108,7 @@ const ( 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 diff --git a/minecraft/protocol/item_stack.go b/minecraft/protocol/item_stack.go index d9e8daac..c09f031c 100644 --- a/minecraft/protocol/item_stack.go +++ b/minecraft/protocol/item_stack.go @@ -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 @@ -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. @@ -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) } @@ -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 @@ -517,6 +528,9 @@ 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 } @@ -524,6 +538,7 @@ type CraftRecipeOptionalStackRequestAction struct { // Marshal ... func (c *CraftRecipeOptionalStackRequestAction) Marshal(r IO) { r.Varuint32(&c.RecipeNetworkID) + r.Uint8(&c.NumberOfCrafts) r.Int32(&c.FilterStringIndex) } @@ -534,6 +549,9 @@ 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 } @@ -541,6 +559,7 @@ type CraftGrindstoneRecipeStackRequestAction struct { // Marshal ... func (c *CraftGrindstoneRecipeStackRequestAction) Marshal(r IO) { r.Varuint32(&c.RecipeNetworkID) + r.Uint8(&c.NumberOfCrafts) r.Varint32(&c.Cost) } diff --git a/minecraft/protocol/packet/change_dimension.go b/minecraft/protocol/packet/change_dimension.go index 383a1e2c..e7a6b5e2 100644 --- a/minecraft/protocol/packet/change_dimension.go +++ b/minecraft/protocol/packet/change_dimension.go @@ -28,9 +28,10 @@ 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 is displayed while the client is changing - // dimensions. The client will update the server on its state through the ServerBoundLoadingScreen packet. - // This field should be unique for every ChangeDimension packet sent. + // 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] } diff --git a/minecraft/protocol/packet/correct_player_move_prediction.go b/minecraft/protocol/packet/correct_player_move_prediction.go index 8a15cc7e..6fa352f1 100644 --- a/minecraft/protocol/packet/correct_player_move_prediction.go +++ b/minecraft/protocol/packet/correct_player_move_prediction.go @@ -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. @@ -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) diff --git a/minecraft/protocol/packet/player_armour_damage.go b/minecraft/protocol/packet/player_armour_damage.go index b173209b..a9492cf3 100644 --- a/minecraft/protocol/packet/player_armour_damage.go +++ b/minecraft/protocol/packet/player_armour_damage.go @@ -4,6 +4,14 @@ import ( "github.com/sandertv/gophertunnel/minecraft/protocol" ) +const ( + PlayerArmourDamageFlagHelmet = 1 << (iota + 1) + PlayerArmourDamageFlagChestplate + PlayerArmourDamageFlagLeggings + PlayerArmourDamageFlagBoots + PlayerArmourDamageFlagBody +) + // PlayerArmourDamage is sent by the server to damage the armour of a player. It is a very efficient packet, // but generally it's much easier to just send a slot update for the damaged armour. type PlayerArmourDamage struct { @@ -19,6 +27,8 @@ type PlayerArmourDamage struct { LeggingsDamage int32 // BootsDamage is the amount of damage that should be dealt to the boots. BootsDamage int32 + // BodyDamage is the amount of damage that should be dealt to the body. + BodyDamage int32 } // ID ... @@ -28,24 +38,29 @@ func (pk *PlayerArmourDamage) ID() uint32 { func (pk *PlayerArmourDamage) Marshal(io protocol.IO) { io.Uint8(&pk.Bitset) - if pk.Bitset&0b0001 != 0 { + if pk.Bitset&PlayerArmourDamageFlagHelmet != 0 { io.Varint32(&pk.HelmetDamage) } else { pk.HelmetDamage = 0 } - if pk.Bitset&0b0010 != 0 { + if pk.Bitset&PlayerArmourDamageFlagChestplate != 0 { io.Varint32(&pk.ChestplateDamage) } else { pk.ChestplateDamage = 0 } - if pk.Bitset&0b0100 != 0 { + if pk.Bitset&PlayerArmourDamageFlagLeggings != 0 { io.Varint32(&pk.LeggingsDamage) } else { pk.LeggingsDamage = 0 } - if pk.Bitset&0b1000 != 0 { + if pk.Bitset&PlayerArmourDamageFlagBoots != 0 { io.Varint32(&pk.BootsDamage) } else { pk.BootsDamage = 0 } + if pk.Bitset&PlayerArmourDamageFlagBody != 0 { + io.Varint32(&pk.BodyDamage) + } else { + pk.BodyDamage = 0 + } } diff --git a/minecraft/protocol/packet/server_bound_diagnostics.go b/minecraft/protocol/packet/server_bound_diagnostics.go index 17b4c4fd..5173e267 100644 --- a/minecraft/protocol/packet/server_bound_diagnostics.go +++ b/minecraft/protocol/packet/server_bound_diagnostics.go @@ -5,7 +5,7 @@ import ( ) // ServerBoundDiagnostics is sent by the client to tell the server about the performance diagnostics -// of the client. It is +// of the client. It is sent by the client roughly every 500ms or 10 in-game ticks. type ServerBoundDiagnostics struct { // AverageFramesPerSecond is the average amount of frames per second that the client has been // running at. diff --git a/minecraft/protocol/packet/server_bound_loading_screen.go b/minecraft/protocol/packet/server_bound_loading_screen.go index 66ffce22..76188b8f 100644 --- a/minecraft/protocol/packet/server_bound_loading_screen.go +++ b/minecraft/protocol/packet/server_bound_loading_screen.go @@ -16,7 +16,7 @@ type ServerBoundLoadingScreen struct { // Type is the type of the loading screen event. It is one of the constants that may be found above. Type int32 // LoadingScreenID is the ID of the screen that was previously sent by the server in the ChangeDimension - // packet. The server should validate that the screen ID is correct. + // packet. The server should validate that the ID matches the last one it sent. LoadingScreenID protocol.Optional[uint32] } diff --git a/minecraft/protocol/packet/stop_sound.go b/minecraft/protocol/packet/stop_sound.go index 694ddcf7..bd129467 100644 --- a/minecraft/protocol/packet/stop_sound.go +++ b/minecraft/protocol/packet/stop_sound.go @@ -13,9 +13,8 @@ type StopSound struct { // StopAll specifies if all sounds currently playing to the player should be stopped. If set to true, the // SoundName field may be left empty. StopAll bool - // StopMusic specifies if all music currently playing to the player should be stopped. If set to true, the - // SoundName field may be left empty. - StopMusic bool + // StopMusicLegacy is currently unknown. + StopMusicLegacy bool } // ID ... @@ -26,4 +25,5 @@ func (*StopSound) ID() uint32 { func (pk *StopSound) Marshal(io protocol.IO) { io.String(&pk.SoundName) io.Bool(&pk.StopAll) + io.Bool(&pk.StopMusicLegacy) }