From 0d5e922316aac9328c30a9de748b889e0d7d53d7 Mon Sep 17 00:00:00 2001 From: TwistedAsylumMC Date: Sat, 16 Nov 2024 11:08:01 +0000 Subject: [PATCH 1/8] minecraft/protocol: Start work on 1.21.50 support --- minecraft/conn.go | 19 ++-- minecraft/listener.go | 2 +- minecraft/protocol/bitset.go | 43 ++++++++ minecraft/protocol/camera.go | 104 ++++++++++++++++++ minecraft/protocol/info.go | 4 +- minecraft/protocol/io.go | 1 + minecraft/protocol/item_stack.go | 3 + minecraft/protocol/os.go | 1 + .../protocol/packet/camera_aim_assist.go | 16 ++- .../packet/camera_aim_assist_presets.go | 20 ++++ minecraft/protocol/packet/id.go | 1 + minecraft/protocol/packet/level_event.go | 2 + .../protocol/packet/player_auth_input.go | 32 ++++-- minecraft/protocol/packet/pool.go | 1 + .../protocol/packet/resource_packs_info.go | 10 ++ minecraft/protocol/reader.go | 23 ++++ minecraft/protocol/resource_pack.go | 6 +- minecraft/protocol/writer.go | 17 +++ minecraft/resource/manifest.go | 13 ++- minecraft/resource/pack.go | 4 +- minecraft/resource_pack_queue.go | 7 +- 21 files changed, 288 insertions(+), 41 deletions(-) create mode 100644 minecraft/protocol/bitset.go create mode 100644 minecraft/protocol/packet/camera_aim_assist_presets.go diff --git a/minecraft/conn.go b/minecraft/conn.go index ba25a90d..99bbecdf 100644 --- a/minecraft/conn.go +++ b/minecraft/conn.go @@ -776,7 +776,7 @@ func (conn *Conn) handleClientToServerHandshake() error { } if pack.Encrypted() { texturePack.ContentKey = pack.ContentKey() - texturePack.ContentIdentity = pack.Manifest().Header.UUID + texturePack.ContentIdentity = pack.Manifest().Header.UUID.String() } pk.TexturePacks = append(pk.TexturePacks, texturePack) } @@ -855,22 +855,23 @@ func (conn *Conn) handleResourcePacksInfo(pk *packet.ResourcePacksInfo) error { packsToDownload := make([]string, 0, totalPacks) for index, pack := range pk.TexturePacks { - if _, ok := conn.packQueue.downloadingPacks[pack.UUID]; ok { + id := pack.UUID.String() + if _, ok := conn.packQueue.downloadingPacks[id]; ok { conn.log.Warn("handle ResourcePacksInfo: duplicate texture pack", "UUID", pack.UUID) conn.packQueue.packAmount-- continue } - if conn.downloadResourcePack != nil && !conn.downloadResourcePack(uuid.MustParse(pack.UUID), pack.Version, index, totalPacks) { + if conn.downloadResourcePack != nil && !conn.downloadResourcePack(uuid.MustParse(id), pack.Version, index, totalPacks) { conn.ignoredResourcePacks = append(conn.ignoredResourcePacks, exemptedResourcePack{ - uuid: pack.UUID, + uuid: id, version: pack.Version, }) conn.packQueue.packAmount-- continue } // This UUID_Version is a hack Mojang put in place. - packsToDownload = append(packsToDownload, pack.UUID+"_"+pack.Version) - conn.packQueue.downloadingPacks[pack.UUID] = downloadingPack{ + packsToDownload = append(packsToDownload, id+"_"+pack.Version) + conn.packQueue.downloadingPacks[id] = downloadingPack{ size: pack.Size, buf: bytes.NewBuffer(make([]byte, 0, pack.Size)), newFrag: make(chan []byte), @@ -939,7 +940,7 @@ func (conn *Conn) hasPack(uuid string, version string, hasBehaviours bool) bool } } for _, pack := range conn.resourcePacks { - if pack.UUID() == uuid && pack.Version() == version && pack.HasBehaviours() == hasBehaviours { + if pack.UUID().String() == uuid && pack.Version() == version && pack.HasBehaviours() == hasBehaviours { return true } } @@ -971,7 +972,7 @@ func (conn *Conn) handleResourcePackClientResponse(pk *packet.ResourcePackClient case packet.PackResponseAllPacksDownloaded: pk := &packet.ResourcePackStack{BaseGameVersion: protocol.CurrentVersion, Experiments: []protocol.ExperimentData{{Name: "cameras", Enabled: true}}} for _, pack := range conn.resourcePacks { - resourcePack := protocol.StackResourcePack{UUID: pack.UUID(), Version: pack.Version()} + resourcePack := protocol.StackResourcePack{UUID: pack.UUID().String(), Version: pack.Version()} // If it has behaviours, add it to the behaviour pack list. If not, we add it to the texture packs // list. if pack.HasBehaviours() { @@ -1158,7 +1159,7 @@ func (conn *Conn) handleResourcePackChunkData(pk *packet.ResourcePackChunkData) // pack to be downloaded. func (conn *Conn) handleResourcePackChunkRequest(pk *packet.ResourcePackChunkRequest) error { current := conn.packQueue.currentPack - if current.UUID() != pk.UUID { + if current.UUID().String() != pk.UUID { return fmt.Errorf("expected pack UUID %v, but got %v", current.UUID(), pk.UUID) } if conn.packQueue.currentOffset != uint64(pk.ChunkIndex)*packChunkSize { diff --git a/minecraft/listener.go b/minecraft/listener.go index 2a72ca78..6c64a8fd 100644 --- a/minecraft/listener.go +++ b/minecraft/listener.go @@ -192,7 +192,7 @@ func (listener *Listener) AddResourcePack(pack *resource.Pack) { func (listener *Listener) RemoveResourcePack(uuid string) { listener.packsMu.Lock() listener.packs = slices.DeleteFunc(listener.packs, func(pack *resource.Pack) bool { - return pack.UUID() == uuid + return pack.UUID().String() == uuid }) listener.packsMu.Unlock() } diff --git a/minecraft/protocol/bitset.go b/minecraft/protocol/bitset.go new file mode 100644 index 00000000..fa696199 --- /dev/null +++ b/minecraft/protocol/bitset.go @@ -0,0 +1,43 @@ +package protocol + +import "math/big" + +// Bitset is a representation of std::bitset being sent over the network, allowing for more than 64 bits +// to be stored in a single integer. A Bitset has a fixed size, which is set at creation time. +type Bitset struct { + size int + int *big.Int +} + +// NewBitset creates a new Bitset with a specific size. The size is the amount of bits that the Bitset can +// store. Attempting to set a bit at an index higher than the size will panic. +func NewBitset(size int) Bitset { + return Bitset{size: size, int: new(big.Int)} +} + +// Set sets a bit at a specific index in the Bitset. If the index is higher than the size of the Bitset, a +// panic will occur. +func (b Bitset) Set(i int) { + if i >= b.size { + panic("index out of bounds") + } + b.int.SetBit(b.int, i, 1) +} + +// Unset unsets a bit at a specific index in the Bitset. If the index is higher than the size of the Bitset, +// a panic will occur. +func (b Bitset) Unset(i int) { + if i >= b.size { + panic("index out of bounds") + } + b.int.SetBit(b.int, i, 0) +} + +// Test checks if a bit at a specific index in the Bitset is set. If the index is higher than the size of the +// Bitset, a panic will occur. +func (b Bitset) Test(i int) bool { + if i >= b.size { + panic("index out of bounds") + } + return b.int.Bit(i) == 1 +} diff --git a/minecraft/protocol/camera.go b/minecraft/protocol/camera.go index 5c6838a8..91cb5cd1 100644 --- a/minecraft/protocol/camera.go +++ b/minecraft/protocol/camera.go @@ -5,6 +5,11 @@ import ( "image/color" ) +const ( + AimAssistTargetModeAngle = iota + AimAssistTargetModeDistance +) + const ( AudioListenerCamera = iota AudioListenerPlayer @@ -165,6 +170,8 @@ type CameraPreset struct { VerticalRotationLimit Optional[mgl32.Vec2] // ContinueTargeting determines whether the camera should continue targeting the entity or not. ContinueTargeting Optional[bool] + // BlockListeningRadius ... + BlockListeningRadius Optional[float32] // 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] @@ -181,6 +188,8 @@ type CameraPreset struct { // AlignTargetAndCameraForward determines whether the camera should align the target and the camera forward // or not. AlignTargetAndCameraForward Optional[bool] + // AimAssist ... + AimAssist Optional[CameraPresetAimAssist] } // Marshal encodes/decodes a CameraPreset. @@ -204,3 +213,98 @@ func (x *CameraPreset) Marshal(r IO) { OptionalFunc(r, &x.PlayerEffects, r.Bool) OptionalFunc(r, &x.AlignTargetAndCameraForward, r.Bool) } + +type CameraPresetAimAssist struct { + PresetID Optional[string] + TargetMode Optional[int32] + Angle Optional[mgl32.Vec2] + Distance Optional[float32] +} + +// Marshal encodes/decodes a CameraPresetAimAssist. +func (x *CameraPresetAimAssist) Marshal(r IO) { + OptionalFunc(r, &x.PresetID, r.String) + OptionalFunc(r, &x.TargetMode, r.Int32) + OptionalFunc(r, &x.Angle, r.Vec2) + OptionalFunc(r, &x.Distance, r.Float32) +} + +type CameraAimAssistCategories struct { + Identifier string + Categories []CameraAimAssistCategory +} + +// Marshal encodes/decodes a CameraAimAssistCategories. +func (x *CameraAimAssistCategories) Marshal(r IO) { + r.String(&x.Identifier) + Slice(r, &x.Categories) +} + +type CameraAimAssistCategory struct { + Name string + Priorities CameraAimAssistPriorities +} + +// Marshal encodes/decodes a CameraAimAssistCategory. +func (x *CameraAimAssistCategory) Marshal(r IO) { + r.String(&x.Name) + Single(r, &x.Priorities) +} + +type CameraAimAssistPriorities struct { + Entities []CameraAimAssistPriority + Blocks []CameraAimAssistPriority + EntityDefault Optional[int32] + BlockDefault Optional[int32] +} + +// Marshal encodes/decodes a CameraAimAssistPriorities. +func (x *CameraAimAssistPriorities) Marshal(r IO) { + Slice(r, &x.Entities) + Slice(r, &x.Blocks) + OptionalFunc(r, &x.EntityDefault, r.Int32) + OptionalFunc(r, &x.BlockDefault, r.Int32) +} + +type CameraAimAssistPriority struct { + ID string + Priority int32 +} + +// Marshal encodes/decodes a CameraAimAssistPriority. +func (x *CameraAimAssistPriority) Marshal(r IO) { + r.String(&x.ID) + r.Int32(&x.Priority) +} + +type CameraAimAssistPreset struct { + Identifier string + Categories string + BlockExclusions []string + LiquidTargets []string + ItemSettings []CameraAimAssistItemSettings + DefaultItemSettings Optional[string] + HandSettings Optional[string] +} + +// Marshal encodes/decodes a CameraAimAssistPreset. +func (x *CameraAimAssistPreset) Marshal(r IO) { + r.String(&x.Identifier) + r.String(&x.Categories) + FuncSlice(r, &x.BlockExclusions, r.String) + FuncSlice(r, &x.LiquidTargets, r.String) + Slice(r, &x.ItemSettings) + OptionalFunc(r, &x.DefaultItemSettings, r.String) + OptionalFunc(r, &x.HandSettings, r.String) +} + +type CameraAimAssistItemSettings struct { + ItemID string + Category string +} + +// Marshal encodes/decodes a CameraAimAssistItemSettings. +func (x *CameraAimAssistItemSettings) Marshal(r IO) { + r.String(&x.ItemID) + r.String(&x.Category) +} diff --git a/minecraft/protocol/info.go b/minecraft/protocol/info.go index 265103dc..13508698 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 = 748 + CurrentProtocol = 766 // CurrentVersion is the current version of Minecraft as supported by the `packet` package. - CurrentVersion = "1.21.40" + CurrentVersion = "1.21.50" ) diff --git a/minecraft/protocol/io.go b/minecraft/protocol/io.go index 70fd51f1..27bda111 100644 --- a/minecraft/protocol/io.go +++ b/minecraft/protocol/io.go @@ -57,6 +57,7 @@ type IO interface { GameRule(x *GameRule) AbilityValue(x *any) CompressedBiomeDefinitions(x *map[string]any) + Bitset(x *Bitset, size int) ShieldID() int32 UnknownEnumOption(value any, enum string) diff --git a/minecraft/protocol/item_stack.go b/minecraft/protocol/item_stack.go index f4fc9ecb..5c9ef11e 100644 --- a/minecraft/protocol/item_stack.go +++ b/minecraft/protocol/item_stack.go @@ -259,6 +259,8 @@ type StackResponseSlotInfo struct { StackNetworkID int32 // CustomName is the custom name of the item stack. It is used in relation to text filtering. CustomName string + // FilteredCustomName is always set to empty and the usage is currently unknown. + FilteredCustomName string // DurabilityCorrection is the current durability of the item stack. This durability will be shown // client-side after the response is sent to the client. DurabilityCorrection int32 @@ -274,6 +276,7 @@ func (x *StackResponseSlotInfo) Marshal(r IO) { r.InvalidValue(x.HotbarSlot, "hotbar slot", "hot bar slot must be equal to normal slot") } r.String(&x.CustomName) + r.String(&x.FilteredCustomName) r.Varint32(&x.DurabilityCorrection) } diff --git a/minecraft/protocol/os.go b/minecraft/protocol/os.go index 1dbf1619..6641a7ee 100644 --- a/minecraft/protocol/os.go +++ b/minecraft/protocol/os.go @@ -9,6 +9,7 @@ const ( DeviceIOS DeviceOSX DeviceFireOS + // Deprecated: DeviceGearVR is deprecated as of 1.21.50. DeviceGearVR DeviceHololens DeviceWin10 diff --git a/minecraft/protocol/packet/camera_aim_assist.go b/minecraft/protocol/packet/camera_aim_assist.go index c0898f34..117708d2 100644 --- a/minecraft/protocol/packet/camera_aim_assist.go +++ b/minecraft/protocol/packet/camera_aim_assist.go @@ -10,21 +10,18 @@ const ( CameraAimAssistActionClear ) -const ( - CameraAimAssistTargetModeAngle = iota - CameraAimAssistTargetModeDistance -) - // CameraAimAssist is sent by the server to the client to set up aim assist for the client's camera. type CameraAimAssist struct { + // PresetID is the ID of the preset that has previously been defined in the CameraAimAssistPresets packet. + PresetID string // ViewAngle is the angle that the camera should aim at, if TargetMode is set to - // CameraAimAssistTargetModeAngle. + // protocol.AimAssistTargetModeAngle. ViewAngle mgl32.Vec2 // Distance is the distance that the camera should keep from the target, if TargetMode is set to - // CameraAimAssistTargetModeDistance. + // protocol.AimAssistTargetModeDistance. Distance float32 - // TargetMode is the mode that the camera should use to aim at the target. This is one of the constants - // above. + // TargetMode is the mode that the camera should use to aim at the target. This is currently one of + // protocol.AimAssistTargetModeAngle or protocol.AimAssistTargetModeDistance. TargetMode byte // Action is the action that should be performed with the aim assist. This is one of the constants above. Action byte @@ -36,6 +33,7 @@ func (*CameraAimAssist) ID() uint32 { } func (pk *CameraAimAssist) Marshal(io protocol.IO) { + io.String(&pk.PresetID) io.Vec2(&pk.ViewAngle) io.Float32(&pk.Distance) io.Uint8(&pk.TargetMode) diff --git a/minecraft/protocol/packet/camera_aim_assist_presets.go b/minecraft/protocol/packet/camera_aim_assist_presets.go new file mode 100644 index 00000000..a5b38766 --- /dev/null +++ b/minecraft/protocol/packet/camera_aim_assist_presets.go @@ -0,0 +1,20 @@ +package packet + +import ( + "github.com/sandertv/gophertunnel/minecraft/protocol" +) + +type CameraAimAssistPresets struct { + Categories []protocol.CameraAimAssistCategories + Presets []protocol.CameraAimAssistPreset +} + +// ID ... +func (*CameraAimAssistPresets) ID() uint32 { + return IDCameraAimAssistPresets +} + +func (pk *CameraAimAssistPresets) Marshal(io protocol.IO) { + protocol.Slice(io, &pk.Categories) + protocol.Slice(io, &pk.Presets) +} diff --git a/minecraft/protocol/packet/id.go b/minecraft/protocol/packet/id.go index c036fa9f..5edb792c 100644 --- a/minecraft/protocol/packet/id.go +++ b/minecraft/protocol/packet/id.go @@ -220,4 +220,5 @@ const ( IDContainerRegistryCleanup IDMovementEffect IDSetMovementAuthority + IDCameraAimAssistPresets ) diff --git a/minecraft/protocol/packet/level_event.go b/minecraft/protocol/packet/level_event.go index 1d6706c9..f3a46034 100644 --- a/minecraft/protocol/packet/level_event.go +++ b/minecraft/protocol/packet/level_event.go @@ -134,6 +134,8 @@ const ( LevelEventAnimationVaultDeactivate = 9812 LevelEventAnimationVaultEjectItem = 9813 LevelEventAnimationSpawnCobweb = 9814 + LevelEventParticleSmashAttackGroundDust = 9815 + LevelEventParticleCreakingHeartTrail = 9816 LevelEventParticleLegacyEvent = 0x4000 ) diff --git a/minecraft/protocol/packet/player_auth_input.go b/minecraft/protocol/packet/player_auth_input.go index 79a6cb06..4fc8355d 100644 --- a/minecraft/protocol/packet/player_auth_input.go +++ b/minecraft/protocol/packet/player_auth_input.go @@ -5,8 +5,10 @@ import ( "github.com/sandertv/gophertunnel/minecraft/protocol" ) +const PlayerAuthInputBitsetSize = 65 + const ( - InputFlagAscend = 1 << iota + InputFlagAscend = iota InputFlagDescend InputFlagNorthJump InputFlagJumpDown @@ -59,10 +61,18 @@ const ( InputFlagVerticalCollision InputFlagDownLeft InputFlagDownRight + InputFlagStartUsingItem InputFlagCameraRelativeMovementEnabled InputFlagRotControlledByMoveDirection InputFlagStartSpinAttack InputFlagStopSpinAttack + InputFlagIsHotbarTouchOnly + InputFlagJumpReleasedRaw + InputFlagJumpPressedRaw + InputFlagJumpCurrentRaw + InputFlagSneakReleasedRaw + InputFlagSneakPressedRaw + InputFlagSneakCurrentRaw ) const ( @@ -107,7 +117,7 @@ type PlayerAuthInput struct { HeadYaw float32 // InputData is a combination of bit flags that together specify the way the player moved last tick. It // is a combination of the flags above. - InputData uint64 + InputData protocol.Bitset // InputMode specifies the way that the client inputs data to the screen. It is one of the constants that // may be found above. InputMode uint32 @@ -140,7 +150,12 @@ type PlayerAuthInput struct { // AnalogueMoveVector is a Vec2 that specifies the direction in which the player moved, as a combination // of X/Z values which are created using an analogue input. AnalogueMoveVector mgl32.Vec2 - CameraOrientation mgl32.Vec3 + // CameraOrientation is the vector that represents the camera's forward direction which can be used to + // transform movement to be camera relative. + CameraOrientation mgl32.Vec3 + // RawMoveVector is the value of MoveVector before it is affected by input permissions, sneaking/fly + // speeds and isn't normalised for analogue inputs. + RawMoveVector mgl32.Vec2 } // ID ... @@ -154,7 +169,7 @@ func (pk *PlayerAuthInput) Marshal(io protocol.IO) { io.Vec3(&pk.Position) io.Vec2(&pk.MoveVector) io.Float32(&pk.HeadYaw) - io.Varuint64(&pk.InputData) + io.Bitset(&pk.InputData, PlayerAuthInputBitsetSize) io.Varuint32(&pk.InputMode) io.Varuint32(&pk.PlayMode) io.Varuint32(&pk.InteractionModel) @@ -163,23 +178,24 @@ func (pk *PlayerAuthInput) Marshal(io protocol.IO) { io.Varuint64(&pk.Tick) io.Vec3(&pk.Delta) - if pk.InputData&InputFlagPerformItemInteraction != 0 { + if pk.InputData.Test(InputFlagPerformItemInteraction) { io.PlayerInventoryAction(&pk.ItemInteractionData) } - if pk.InputData&InputFlagPerformItemStackRequest != 0 { + if pk.InputData.Test(InputFlagPerformItemStackRequest) { protocol.Single(io, &pk.ItemStackRequest) } - if pk.InputData&InputFlagPerformBlockActions != 0 { + if pk.InputData.Test(InputFlagPerformBlockActions) { protocol.SliceVarint32Length(io, &pk.BlockActions) } - if pk.InputData&InputFlagClientPredictedVehicle != 0 { + if pk.InputData.Test(InputFlagClientPredictedVehicle) { io.Vec2(&pk.VehicleRotation) io.Varint64(&pk.ClientPredictedVehicle) } io.Vec2(&pk.AnalogueMoveVector) io.Vec3(&pk.CameraOrientation) + io.Vec2(&pk.RawMoveVector) } diff --git a/minecraft/protocol/packet/pool.go b/minecraft/protocol/packet/pool.go index 4efab6cd..f50ae431 100644 --- a/minecraft/protocol/packet/pool.go +++ b/minecraft/protocol/packet/pool.go @@ -260,6 +260,7 @@ func init() { IDContainerRegistryCleanup: func() Packet { return &ContainerRegistryCleanup{} }, IDMovementEffect: func() Packet { return &MovementEffect{} }, IDSetMovementAuthority: func() Packet { return &SetMovementAuthority{} }, + IDCameraAimAssistPresets: func() Packet { return &CameraAimAssistPresets{} }, } for id, pk := range serverOriginating { RegisterPacketFromServer(id, pk) diff --git a/minecraft/protocol/packet/resource_packs_info.go b/minecraft/protocol/packet/resource_packs_info.go index 531f8acf..1844469c 100644 --- a/minecraft/protocol/packet/resource_packs_info.go +++ b/minecraft/protocol/packet/resource_packs_info.go @@ -1,6 +1,7 @@ package packet import ( + "github.com/google/uuid" "github.com/sandertv/gophertunnel/minecraft/protocol" ) @@ -17,6 +18,13 @@ type ResourcePacksInfo struct { // HasScripts specifies if any of the resource packs contain scripts in them. If set to true, only clients // that support scripts will be able to download them. HasScripts bool + // WorldTemplateUUID is teh UUID of the template that has been used to generate the world. Templates can + // be downloaded from the marketplace or installed via '.mctemplate' files. If the world was not generated + // from a template, this field is empty. + WorldTemplateUUID uuid.UUID + // WorldTemplateVersion is the version of the world template that has been used to generate the world. If + // the world was not generated from a template, this field is empty. + WorldTemplateVersion string // TexturePacks is a list of texture packs that the client needs to download before joining the server. // The order of these texture packs is not relevant in this packet. It is however important in the // ResourcePackStack packet. @@ -32,5 +40,7 @@ func (pk *ResourcePacksInfo) Marshal(io protocol.IO) { io.Bool(&pk.TexturePackRequired) io.Bool(&pk.HasAddons) io.Bool(&pk.HasScripts) + io.UUID(&pk.WorldTemplateUUID) + io.String(&pk.WorldTemplateVersion) protocol.SliceUint16Length(io, &pk.TexturePacks) } diff --git a/minecraft/protocol/reader.go b/minecraft/protocol/reader.go index 86bbf8be..114001c7 100644 --- a/minecraft/protocol/reader.go +++ b/minecraft/protocol/reader.go @@ -10,6 +10,8 @@ import ( "image/color" "io" "math" + "math/big" + "math/bits" "unsafe" ) @@ -589,6 +591,26 @@ func (r *Reader) CompressedBiomeDefinitions(x *map[string]any) { } } +func (r *Reader) Bitset(x *Bitset, size int) { + *x = NewBitset(size) + for i := 0; i < size; i += 7 { + b, err := r.r.ReadByte() + if err != nil { + r.panic(err) + } else if i+bits.Len8(b) > size { + r.panic(errBitsetOverflow) + } + + bi := big.NewInt(int64(b & 0x7f)) + x.int.Or(x.int, bi.Lsh(bi, uint(i))) + if b&0x80 == 0 { + return + } + } + + r.panic(errBitsetOverflow) +} + // LimitUint32 checks if the value passed is lower than the limit passed. If not, the Reader panics. func (r *Reader) LimitUint32(value uint32, max uint32) { if max == math.MaxUint32 { @@ -628,6 +650,7 @@ func (r *Reader) InvalidValue(value any, forField, reason string) { // errVarIntOverflow is an error set if one of the Varint methods encounters a varint that does not terminate // after 5 or 10 bytes, depending on the data type read into. var errVarIntOverflow = errors.New("varint overflows integer") +var errBitsetOverflow = errors.New("bitset overflows size") // Varint64 reads up to 10 bytes from the underlying buffer into an int64. func (r *Reader) Varint64(x *int64) { diff --git a/minecraft/protocol/resource_pack.go b/minecraft/protocol/resource_pack.go index 0c6fdc34..6f259811 100644 --- a/minecraft/protocol/resource_pack.go +++ b/minecraft/protocol/resource_pack.go @@ -1,11 +1,13 @@ package protocol +import "github.com/google/uuid" + // TexturePackInfo represents a texture pack's info sent over network. It holds information about the // texture pack such as its name, description and version. type TexturePackInfo struct { // UUID is the UUID of the texture pack. Each texture pack downloaded must have a different UUID in // order for the client to be able to handle them properly. - UUID string + UUID uuid.UUID // Version is the version of the texture pack. The client will cache texture packs sent by the server as // long as they carry the same version. Sending a texture pack with a different version than previously // will force the client to re-download it. @@ -35,7 +37,7 @@ type TexturePackInfo struct { // Marshal encodes/decodes a TexturePackInfo. func (x *TexturePackInfo) Marshal(r IO) { - r.String(&x.UUID) + r.UUID(&x.UUID) r.String(&x.Version) r.Uint64(&x.Size) r.String(&x.ContentKey) diff --git a/minecraft/protocol/writer.go b/minecraft/protocol/writer.go index 52dc59bc..af6818ca 100644 --- a/minecraft/protocol/writer.go +++ b/minecraft/protocol/writer.go @@ -8,6 +8,7 @@ import ( "github.com/sandertv/gophertunnel/minecraft/nbt" "image/color" "io" + "math/big" "reflect" "sort" "unsafe" @@ -472,6 +473,22 @@ func (w *Writer) CompressedBiomeDefinitions(x *map[string]any) { w.Bytes(&compressed) } +var varintMaxByteValue = big.NewInt(0x80) + +func (w *Writer) Bitset(x *Bitset, size int) { + if x.size != size { + w.panicf("bitset size mismatch: expected %v, got %v", size, x.size) + } + u := new(big.Int) + u.Set(x.int) + + for u.Cmp(varintMaxByteValue) >= 0 { + _ = w.w.WriteByte(byte(u.Bits()[0]) | 0x80) + u.Rsh(u, 7) + } + _ = w.w.WriteByte(byte(u.Bits()[0])) +} + // Varint64 writes an int64 as 1-10 bytes to the underlying buffer. func (w *Writer) Varint64(x *int64) { u := *x diff --git a/minecraft/resource/manifest.go b/minecraft/resource/manifest.go index 36d7422f..e3037812 100644 --- a/minecraft/resource/manifest.go +++ b/minecraft/resource/manifest.go @@ -1,5 +1,7 @@ package resource +import "github.com/google/uuid" + // Documentation on this may be found here: // https://learn.microsoft.com/en-us/minecraft/creator/reference/content/addonsreference/examples/addonmanifest @@ -30,8 +32,8 @@ type Header struct { Name string `json:"name"` // Description is a short description of the pack. It will appear in the game below the name of the pack. Description string `json:"description"` - // UUID is a unique identifier identifier this pack from any other pack. - UUID string `json:"uuid"` + // UUID is a unique identifier this pack from any other pack. + UUID uuid.UUID `json:"uuid"` // Version is the version of the pack, which can be used to identify changes in the pack. Version [3]int `json:"version"` // MinimumGameVersion is the minimum version of the game that this resource pack was written for. @@ -65,9 +67,10 @@ type Dependency struct { } // Capability is a particular feature that the pack utilises of that isn't necessarily enabled by default. -// experimental_custom_ui: Allows HTML files in the pack to be used for custom UI, and scripts in the pack -// to call and manipulate custom UI. -// chemistry: Allows the pack to add, change or replace Chemistry functionality. +// +// experimental_custom_ui: Allows HTML files in the pack to be used for custom UI, and scripts in the pack +// to call and manipulate custom UI. +// chemistry: Allows the pack to add, change or replace Chemistry functionality. type Capability string // Metadata contains additional information about the pack that is otherwise optional. diff --git a/minecraft/resource/pack.go b/minecraft/resource/pack.go index 9f45d193..ce8735d5 100644 --- a/minecraft/resource/pack.go +++ b/minecraft/resource/pack.go @@ -5,6 +5,7 @@ import ( "bytes" "crypto/sha256" "fmt" + "github.com/google/uuid" "github.com/muhammadmuzzammil1998/jsonc" "io" "net/http" @@ -116,7 +117,7 @@ func (pack *Pack) Name() string { } // UUID returns the UUID of the resource pack. -func (pack *Pack) UUID() string { +func (pack *Pack) UUID() uuid.UUID { return pack.manifest.Header.UUID } @@ -411,7 +412,6 @@ func readManifest(path string) (*Manifest, error) { if err := jsonc.Unmarshal(allData, manifest); err != nil { return nil, fmt.Errorf("decode manifest JSON: %w (data: %v)", err, string(allData)) } - manifest.Header.UUID = strings.ToLower(manifest.Header.UUID) if _, err := reader.find("level.dat"); err == nil { manifest.worldTemplate = true diff --git a/minecraft/resource_pack_queue.go b/minecraft/resource_pack_queue.go index b7fdf387..bb4def41 100644 --- a/minecraft/resource_pack_queue.go +++ b/minecraft/resource_pack_queue.go @@ -39,8 +39,9 @@ func (queue *resourcePackQueue) Request(packs []string) error { for _, pack := range queue.packs { // Mojang made some hack that merges the UUID with the version, so we need to combine that here // too in order to find the proper pack. - if pack.UUID()+"_"+pack.Version() == packUUID { - queue.packsToDownload[pack.UUID()] = pack + id := pack.UUID().String() + if id+"_"+pack.Version() == packUUID { + queue.packsToDownload[id] = pack found = true break } @@ -76,7 +77,7 @@ func (queue *resourcePackQueue) NextPack() (pk *packet.ResourcePackDataInfo, ok packType = packet.ResourcePackTypeSkins } return &packet.ResourcePackDataInfo{ - UUID: pack.UUID(), + UUID: pack.UUID().String(), DataChunkSize: packChunkSize, ChunkCount: uint32(pack.DataChunkCount(packChunkSize)), Size: uint64(pack.Len()), From 2ce4a985ceb8bc5eb63326301a4f62190ec3f8db Mon Sep 17 00:00:00 2001 From: inotflying <100377648+inotflying@users.noreply.github.com> Date: Sun, 17 Nov 2024 02:46:52 +0400 Subject: [PATCH 2/8] minecraft/text: Add Resin color (#271) --- minecraft/text/colour.go | 2 +- minecraft/text/map.go | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/minecraft/text/colour.go b/minecraft/text/colour.go index 033546b6..cfdc1754 100644 --- a/minecraft/text/colour.go +++ b/minecraft/text/colour.go @@ -8,7 +8,7 @@ import ( ) // cleaner represents the regex used to clean Minecraft formatting codes from a string. -var cleaner = regexp.MustCompile("§[0-9a-u]") +var cleaner = regexp.MustCompile("§[0-9a-v]") // Clean removes all Minecraft formatting codes from the string passed. func Clean(s string) string { diff --git a/minecraft/text/map.go b/minecraft/text/map.go index 3e0cce84..bd7cdb1b 100644 --- a/minecraft/text/map.go +++ b/minecraft/text/map.go @@ -34,6 +34,7 @@ const ( Diamond = "§s" Lapis = "§t" Amethyst = "§u" + Resin = "§v" ) const ( @@ -64,6 +65,7 @@ const ( ansiDiamond = "\x1b[38;5;122m" ansiLapis = "\x1b[38;5;4m" ansiAmethyst = "\x1b[38;5;171m" + ansiResin = "\x1b[38;5;172m" ansiObfuscated = "" ansiBold = "\x1b[1m" @@ -99,6 +101,7 @@ var m = map[string]string{ Diamond: ansiDiamond, Lapis: ansiLapis, Amethyst: ansiAmethyst, + Resin: ansiResin, Obfuscated: ansiObfuscated, Bold: ansiBold, @@ -139,6 +142,7 @@ var strMap = map[string]string{ "diamond": Diamond, "lapis": Lapis, "amethyst": Amethyst, + "resin": Resin, } // minecraftReplacer and ansiReplacer are used to translate ANSI formatting codes to Minecraft formatting From 3049fd6fec125a242ad829f87ed13cd8856ae1ac Mon Sep 17 00:00:00 2001 From: TwistedAsylumMC Date: Thu, 21 Nov 2024 17:40:09 +0000 Subject: [PATCH 3/8] protocol/camera.go: Marshal the BlockListeningRadius field --- minecraft/protocol/camera.go | 1 + 1 file changed, 1 insertion(+) diff --git a/minecraft/protocol/camera.go b/minecraft/protocol/camera.go index 91cb5cd1..46fb6e8c 100644 --- a/minecraft/protocol/camera.go +++ b/minecraft/protocol/camera.go @@ -206,6 +206,7 @@ func (x *CameraPreset) Marshal(r IO) { OptionalFunc(r, &x.HorizontalRotationLimit, r.Vec2) OptionalFunc(r, &x.VerticalRotationLimit, r.Vec2) OptionalFunc(r, &x.ContinueTargeting, r.Bool) + OptionalFunc(r, &x.BlockListeningRadius, r.Float32) OptionalFunc(r, &x.ViewOffset, r.Vec2) OptionalFunc(r, &x.EntityOffset, r.Vec3) OptionalFunc(r, &x.Radius, r.Float32) From 64ce0e369b7a296f8d6e2ed79be564a3e16eb56a Mon Sep 17 00:00:00 2001 From: TwistedAsylumMC Date: Mon, 25 Nov 2024 19:38:48 +0000 Subject: [PATCH 4/8] protocol/bitset.go: Rename Test() to Load() --- minecraft/protocol/bitset.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/minecraft/protocol/bitset.go b/minecraft/protocol/bitset.go index fa696199..13518cd8 100644 --- a/minecraft/protocol/bitset.go +++ b/minecraft/protocol/bitset.go @@ -33,9 +33,9 @@ func (b Bitset) Unset(i int) { b.int.SetBit(b.int, i, 0) } -// Test checks if a bit at a specific index in the Bitset is set. If the index is higher than the size of the +// Load returns if a bit at a specific index in the Bitset is set. If the index is higher than the size of the // Bitset, a panic will occur. -func (b Bitset) Test(i int) bool { +func (b Bitset) Load(i int) bool { if i >= b.size { panic("index out of bounds") } From af2083f28837f7fe2aad0c997201440a02c3e137 Mon Sep 17 00:00:00 2001 From: TwistedAsylumMC Date: Mon, 25 Nov 2024 19:47:19 +0000 Subject: [PATCH 5/8] protocol/bitset.go: Rename usages of Test() to Load() --- minecraft/protocol/packet/player_auth_input.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/minecraft/protocol/packet/player_auth_input.go b/minecraft/protocol/packet/player_auth_input.go index 4fc8355d..a901d190 100644 --- a/minecraft/protocol/packet/player_auth_input.go +++ b/minecraft/protocol/packet/player_auth_input.go @@ -178,19 +178,19 @@ func (pk *PlayerAuthInput) Marshal(io protocol.IO) { io.Varuint64(&pk.Tick) io.Vec3(&pk.Delta) - if pk.InputData.Test(InputFlagPerformItemInteraction) { + if pk.InputData.Load(InputFlagPerformItemInteraction) { io.PlayerInventoryAction(&pk.ItemInteractionData) } - if pk.InputData.Test(InputFlagPerformItemStackRequest) { + if pk.InputData.Load(InputFlagPerformItemStackRequest) { protocol.Single(io, &pk.ItemStackRequest) } - if pk.InputData.Test(InputFlagPerformBlockActions) { + if pk.InputData.Load(InputFlagPerformBlockActions) { protocol.SliceVarint32Length(io, &pk.BlockActions) } - if pk.InputData.Test(InputFlagClientPredictedVehicle) { + if pk.InputData.Load(InputFlagClientPredictedVehicle) { io.Vec2(&pk.VehicleRotation) io.Varint64(&pk.ClientPredictedVehicle) } From 495bf796187f2e9e1c94a80acf5a04d148f329d4 Mon Sep 17 00:00:00 2001 From: TwistedAsylumMC Date: Wed, 4 Dec 2024 10:00:49 +0000 Subject: [PATCH 6/8] protocol: Document aim assist features --- minecraft/protocol/camera.go | 87 ++++++++++++++----- .../protocol/packet/camera_aim_assist.go | 20 ++--- .../packet/camera_aim_assist_presets.go | 10 ++- .../protocol/packet/camera_instruction.go | 2 +- 4 files changed, 82 insertions(+), 37 deletions(-) diff --git a/minecraft/protocol/camera.go b/minecraft/protocol/camera.go index 46fb6e8c..8218027f 100644 --- a/minecraft/protocol/camera.go +++ b/minecraft/protocol/camera.go @@ -188,7 +188,7 @@ type CameraPreset struct { // AlignTargetAndCameraForward determines whether the camera should align the target and the camera forward // or not. AlignTargetAndCameraForward Optional[bool] - // AimAssist ... + // AimAssist defines the aim assist to use when using this preset. AimAssist Optional[CameraPresetAimAssist] } @@ -215,34 +215,49 @@ func (x *CameraPreset) Marshal(r IO) { OptionalFunc(r, &x.AlignTargetAndCameraForward, r.Bool) } +// CameraPresetAimAssist represents a preset for aim assist settings. type CameraPresetAimAssist struct { - PresetID Optional[string] + // Preset is the ID of the preset that has previously been defined in the CameraAimAssistPresets packet. + Preset Optional[string] + // TargetMode is the mode that the camera should use for detecting targets. This is one of the constants + // above. TargetMode Optional[int32] - Angle Optional[mgl32.Vec2] - Distance Optional[float32] + // Angle is the maximum angle around the playes's cursor that the aim assist should check for a target, + // if TargetMode is set to protocol.AimAssistTargetModeAngle. + Angle Optional[mgl32.Vec2] + // Distance is the maximum distance from the player's cursor should check for a target, if TargetMode is + // set to protocol.AimAssistTargetModeDistance. + Distance Optional[float32] } // Marshal encodes/decodes a CameraPresetAimAssist. func (x *CameraPresetAimAssist) Marshal(r IO) { - OptionalFunc(r, &x.PresetID, r.String) + OptionalFunc(r, &x.Preset, r.String) OptionalFunc(r, &x.TargetMode, r.Int32) OptionalFunc(r, &x.Angle, r.Vec2) OptionalFunc(r, &x.Distance, r.Float32) } -type CameraAimAssistCategories struct { +// CameraAimAssistCategoryGroup is a group of categories which can be used by a CameraAimAssistPreset. +type CameraAimAssistCategoryGroup struct { + // Identifier is the unique identifier of the group. Identifier string + // Categories is a list of categories within this group. Categories []CameraAimAssistCategory } -// Marshal encodes/decodes a CameraAimAssistCategories. -func (x *CameraAimAssistCategories) Marshal(r IO) { +// Marshal encodes/decodes a CameraAimAssistCategoryGroup. +func (x *CameraAimAssistCategoryGroup) Marshal(r IO) { r.String(&x.Identifier) Slice(r, &x.Categories) } +// CameraAssistCategory is an aim assist category that defines priorities for specific blocks and entities. type CameraAimAssistCategory struct { - Name string + // Name is the name of the category which can be used by a CameraAimAssistPreset. + Name string + // Priorities represents the block and entity specific priorities as well as the default priorities for + // this category. Priorities CameraAimAssistPriorities } @@ -252,11 +267,17 @@ func (x *CameraAimAssistCategory) Marshal(r IO) { Single(r, &x.Priorities) } +// CameraAimAssistPriorities represents the block and entity specific priorities for targetting. The aim +// assist will select the block or entity with the highest priority within the specified thresholds. type CameraAimAssistPriorities struct { - Entities []CameraAimAssistPriority - Blocks []CameraAimAssistPriority + // Entities is a list of priorities for specific entity identifiers. + Entities []CameraAimAssistPriority + // Blocks is a list of priorities for specific block identifiers. + Blocks []CameraAimAssistPriority + // EntityDefault is the default priority for entities. EntityDefault Optional[int32] - BlockDefault Optional[int32] + // BlockDefault is the default priority for blocks. + BlockDefault Optional[int32] } // Marshal encodes/decodes a CameraAimAssistPriorities. @@ -267,31 +288,46 @@ func (x *CameraAimAssistPriorities) Marshal(r IO) { OptionalFunc(r, &x.BlockDefault, r.Int32) } +// CameraAimAssistPriority represents a non-default priority for a specific target. type CameraAimAssistPriority struct { - ID string + // Identifier is the identifier of a target to define the priority for. + Identifier string + // Priority is the priority for this specific target. Priority int32 } // Marshal encodes/decodes a CameraAimAssistPriority. func (x *CameraAimAssistPriority) Marshal(r IO) { - r.String(&x.ID) + r.String(&x.Identifier) r.Int32(&x.Priority) } +// CameraAimAssistPreset defines a base preset that can be extended upon when sending an aim assist. type CameraAimAssistPreset struct { - Identifier string - Categories string - BlockExclusions []string - LiquidTargets []string - ItemSettings []CameraAimAssistItemSettings + // Identifier represents the identifier of this preset. + Identifier string + // CategoryGroup is the name of a CameraAimAssistCategoryGroup to use for the preset. + CategoryGroup string + // BlockExclusions is a list of block identifiers that should be ignored by the aim assist. + BlockExclusions []string + // LiquidTargets is a list of entity identifiers that should be targetted when inside of a liquid. + LiquidTargets []string + // ItemSettings is a list of settings for specific item identifiers. If an item is not listed here, it + // will fallback to DefaultItemSettings or HandSettings if no item is held. + ItemSettings []CameraAimAssistItemSettings + // DefaultItemSettings is the identifier of a category to use when the player is not holding an item + // listed in ItemSettings. This must be the identifier of a category within the + // CameraAimAssistCategoryGroup references by CategoryGroup. DefaultItemSettings Optional[string] - HandSettings Optional[string] + // HandSettings is the identifier of a category to use when the player is not holding an item. This must + // be the identifier of a category within the CameraAimAssistCategoryGroup references by CategoryGroup. + HandSettings Optional[string] } // Marshal encodes/decodes a CameraAimAssistPreset. func (x *CameraAimAssistPreset) Marshal(r IO) { r.String(&x.Identifier) - r.String(&x.Categories) + r.String(&x.CategoryGroup) FuncSlice(r, &x.BlockExclusions, r.String) FuncSlice(r, &x.LiquidTargets, r.String) Slice(r, &x.ItemSettings) @@ -299,13 +335,18 @@ func (x *CameraAimAssistPreset) Marshal(r IO) { OptionalFunc(r, &x.HandSettings, r.String) } +// CameraAimAssistItemSettings defines settings for how specific items should behave when using aim assist. type CameraAimAssistItemSettings struct { - ItemID string + // Item is the identifier of the item to apply the settings to. + Item string + // Category is the identifier of a category to use which has been defined by a CameraAimAssistCategory. + // Only categories defined in the CameraAimAssistCategoryGroup used by the CameraAimAssistPreset can be + // used here. Category string } // Marshal encodes/decodes a CameraAimAssistItemSettings. func (x *CameraAimAssistItemSettings) Marshal(r IO) { - r.String(&x.ItemID) + r.String(&x.Item) r.String(&x.Category) } diff --git a/minecraft/protocol/packet/camera_aim_assist.go b/minecraft/protocol/packet/camera_aim_assist.go index 117708d2..98802a73 100644 --- a/minecraft/protocol/packet/camera_aim_assist.go +++ b/minecraft/protocol/packet/camera_aim_assist.go @@ -12,15 +12,15 @@ const ( // CameraAimAssist is sent by the server to the client to set up aim assist for the client's camera. type CameraAimAssist struct { - // PresetID is the ID of the preset that has previously been defined in the CameraAimAssistPresets packet. - PresetID string - // ViewAngle is the angle that the camera should aim at, if TargetMode is set to - // protocol.AimAssistTargetModeAngle. - ViewAngle mgl32.Vec2 - // Distance is the distance that the camera should keep from the target, if TargetMode is set to - // protocol.AimAssistTargetModeDistance. + // Preset is the ID of the preset that has previously been defined in the CameraAimAssistPresets packet. + Preset string + // Angle is the maximum angle around the playes's cursor that the aim assist should check for a target, + // if TargetMode is set to protocol.AimAssistTargetModeAngle. + Angle mgl32.Vec2 + // Distance is the maximum distance from the player's cursor should check for a target, if TargetMode is + // set to protocol.AimAssistTargetModeDistance. Distance float32 - // TargetMode is the mode that the camera should use to aim at the target. This is currently one of + // TargetMode is the mode that the camera should use for detecting targets. This is currently one of // protocol.AimAssistTargetModeAngle or protocol.AimAssistTargetModeDistance. TargetMode byte // Action is the action that should be performed with the aim assist. This is one of the constants above. @@ -33,8 +33,8 @@ func (*CameraAimAssist) ID() uint32 { } func (pk *CameraAimAssist) Marshal(io protocol.IO) { - io.String(&pk.PresetID) - io.Vec2(&pk.ViewAngle) + io.String(&pk.Preset) + io.Vec2(&pk.Angle) io.Float32(&pk.Distance) io.Uint8(&pk.TargetMode) io.Uint8(&pk.Action) diff --git a/minecraft/protocol/packet/camera_aim_assist_presets.go b/minecraft/protocol/packet/camera_aim_assist_presets.go index a5b38766..8a646753 100644 --- a/minecraft/protocol/packet/camera_aim_assist_presets.go +++ b/minecraft/protocol/packet/camera_aim_assist_presets.go @@ -4,9 +4,13 @@ import ( "github.com/sandertv/gophertunnel/minecraft/protocol" ) +// CameraAimAssistPresets is sent by the server to the client to provide a list of categories and presets +// that can be used when sending a CameraAimAssist packet or a CameraInstruction including aim assist. type CameraAimAssistPresets struct { - Categories []protocol.CameraAimAssistCategories - Presets []protocol.CameraAimAssistPreset + // CategoryGroups is a list of groups of categories which can be referenced by one of the Presets. + CategoryGroups []protocol.CameraAimAssistCategoryGroup + // Presets is a list of presets which define a base for how aim assist should behave + Presets []protocol.CameraAimAssistPreset } // ID ... @@ -15,6 +19,6 @@ func (*CameraAimAssistPresets) ID() uint32 { } func (pk *CameraAimAssistPresets) Marshal(io protocol.IO) { - protocol.Slice(io, &pk.Categories) + protocol.Slice(io, &pk.CategoryGroups) protocol.Slice(io, &pk.Presets) } diff --git a/minecraft/protocol/packet/camera_instruction.go b/minecraft/protocol/packet/camera_instruction.go index a0f114dd..a01d4593 100644 --- a/minecraft/protocol/packet/camera_instruction.go +++ b/minecraft/protocol/packet/camera_instruction.go @@ -14,7 +14,7 @@ type CameraInstruction struct { 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 can be set to true to remove the current aim assist target. RemoveTarget protocol.Optional[bool] } From 5590e865c79e47d5cdc04e82dd47e902ed96d60c Mon Sep 17 00:00:00 2001 From: TwistedAsylumMC Date: Wed, 4 Dec 2024 10:15:52 +0000 Subject: [PATCH 7/8] minecraft/protocol: More camera docs & document filtered fields --- minecraft/protocol/camera.go | 8 ++++---- minecraft/protocol/item_stack.go | 3 ++- minecraft/protocol/packet/disconnect.go | 3 ++- minecraft/protocol/packet/set_title.go | 3 ++- minecraft/protocol/packet/text.go | 3 ++- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/minecraft/protocol/camera.go b/minecraft/protocol/camera.go index 8218027f..5cae6455 100644 --- a/minecraft/protocol/camera.go +++ b/minecraft/protocol/camera.go @@ -168,10 +168,10 @@ type CameraPreset struct { HorizontalRotationLimit Optional[mgl32.Vec2] // VerticalRotationLimit is the vertical rotation limit of the camera. VerticalRotationLimit Optional[mgl32.Vec2] - // ContinueTargeting determines whether the camera should continue targeting the entity or not. + // ContinueTargeting determines whether the camera should continue targeting when using aim assist. ContinueTargeting Optional[bool] - // BlockListeningRadius ... - BlockListeningRadius Optional[float32] + // TrackingRadius is the radius around the camera that the aim assist should track targets. + TrackingRadius Optional[float32] // 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] @@ -206,7 +206,7 @@ func (x *CameraPreset) Marshal(r IO) { OptionalFunc(r, &x.HorizontalRotationLimit, r.Vec2) OptionalFunc(r, &x.VerticalRotationLimit, r.Vec2) OptionalFunc(r, &x.ContinueTargeting, r.Bool) - OptionalFunc(r, &x.BlockListeningRadius, r.Float32) + OptionalFunc(r, &x.TrackingRadius, r.Float32) OptionalFunc(r, &x.ViewOffset, r.Vec2) OptionalFunc(r, &x.EntityOffset, r.Vec3) OptionalFunc(r, &x.Radius, r.Float32) diff --git a/minecraft/protocol/item_stack.go b/minecraft/protocol/item_stack.go index 949957c6..e1b5c206 100644 --- a/minecraft/protocol/item_stack.go +++ b/minecraft/protocol/item_stack.go @@ -259,7 +259,8 @@ type StackResponseSlotInfo struct { StackNetworkID int32 // CustomName is the custom name of the item stack. It is used in relation to text filtering. CustomName string - // FilteredCustomName is always set to empty and the usage is currently unknown. + // FilteredCustomName is a filtered version of CustomName with all the profanity removed. The client will + // use this over CustomName if this field is not empty and they have the "Filter Profanity" setting enabled. FilteredCustomName string // DurabilityCorrection is the current durability of the item stack. This durability will be shown // client-side after the response is sent to the client. diff --git a/minecraft/protocol/packet/disconnect.go b/minecraft/protocol/packet/disconnect.go index 94e629e5..8d0378aa 100644 --- a/minecraft/protocol/packet/disconnect.go +++ b/minecraft/protocol/packet/disconnect.go @@ -16,7 +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 is a filtered version of Message with all the profanity removed. The client will use + // this over Message if this field is not empty and they have the "Filter Profanity" setting enabled. FilteredMessage string } diff --git a/minecraft/protocol/packet/set_title.go b/minecraft/protocol/packet/set_title.go index 538842e2..672dbfb9 100644 --- a/minecraft/protocol/packet/set_title.go +++ b/minecraft/protocol/packet/set_title.go @@ -39,7 +39,8 @@ type SetTitle struct { XUID string // PlatformOnlineID is either a uint64 or an empty string. PlatformOnlineID string - // FilteredMessage is always set to empty and the usage is currently unknown. + // FilteredMessage is a filtered version of Message with all the profanity removed. The client will use + // this over Message if this field is not empty and they have the "Filter Profanity" setting enabled. FilteredMessage string } diff --git a/minecraft/protocol/packet/text.go b/minecraft/protocol/packet/text.go index 4ffc2c6f..11dc31db 100644 --- a/minecraft/protocol/packet/text.go +++ b/minecraft/protocol/packet/text.go @@ -46,7 +46,8 @@ type Text struct { // Nintendo Switch). It is otherwise an empty string, and is used to decide which players are able to // chat with each other. PlatformChatID string - // FilteredMessage is always set to empty and the usage is currently unknown. + // FilteredMessage is a filtered version of Message with all the profanity removed. The client will use + // this over Message if this field is not empty and they have the "Filter Profanity" setting enabled. FilteredMessage string } From 9353fa339d6c2efbe01764c20a7b23086b6f1445 Mon Sep 17 00:00:00 2001 From: TwistedAsylumMC Date: Wed, 4 Dec 2024 13:16:48 +0000 Subject: [PATCH 8/8] protocol/camera.go: Fix staticcheck --- minecraft/protocol/camera.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minecraft/protocol/camera.go b/minecraft/protocol/camera.go index 5cae6455..de0333b1 100644 --- a/minecraft/protocol/camera.go +++ b/minecraft/protocol/camera.go @@ -252,7 +252,7 @@ func (x *CameraAimAssistCategoryGroup) Marshal(r IO) { Slice(r, &x.Categories) } -// CameraAssistCategory is an aim assist category that defines priorities for specific blocks and entities. +// CameraAimAssistCategory is an aim assist category that defines priorities for specific blocks and entities. type CameraAimAssistCategory struct { // Name is the name of the category which can be used by a CameraAimAssistPreset. Name string