diff --git a/legacyver/block_translator.go b/legacyver/block_translator.go index 78624b2..4499bcb 100644 --- a/legacyver/block_translator.go +++ b/legacyver/block_translator.go @@ -18,7 +18,7 @@ const ( ) var ( - //go:embed block_states_766.nbt + //go:embed data/block_states_766.nbt latestBlockStateData []byte // latestBlockMapping is the BlockMapping used for translating blocks between versions. diff --git a/legacyver/block_states_748.nbt b/legacyver/data/block_states_748.nbt similarity index 100% rename from legacyver/block_states_748.nbt rename to legacyver/data/block_states_748.nbt diff --git a/legacyver/block_states_766.nbt b/legacyver/data/block_states_766.nbt similarity index 100% rename from legacyver/block_states_766.nbt rename to legacyver/data/block_states_766.nbt diff --git a/legacyver/item_runtime_ids_748.nbt b/legacyver/data/item_runtime_ids_748.nbt similarity index 100% rename from legacyver/item_runtime_ids_748.nbt rename to legacyver/data/item_runtime_ids_748.nbt diff --git a/legacyver/item_runtime_ids_766.nbt b/legacyver/data/item_runtime_ids_766.nbt similarity index 100% rename from legacyver/item_runtime_ids_766.nbt rename to legacyver/data/item_runtime_ids_766.nbt diff --git a/legacyver/required_item_list_748.json b/legacyver/data/required_item_list_748.json similarity index 100% rename from legacyver/required_item_list_748.json rename to legacyver/data/required_item_list_748.json diff --git a/legacyver/required_item_list_766.json b/legacyver/data/required_item_list_766.json similarity index 100% rename from legacyver/required_item_list_766.json rename to legacyver/data/required_item_list_766.json diff --git a/legacyver/legacypacket/camera_aim_assist.go b/legacyver/legacypacket/camera_aim_assist.go new file mode 100644 index 0000000..c8572df --- /dev/null +++ b/legacyver/legacypacket/camera_aim_assist.go @@ -0,0 +1,40 @@ +package legacypacket + +import ( + "github.com/akmalfairuz/legacy-version/legacyver/proto" + "github.com/go-gl/mathgl/mgl32" + "github.com/sandertv/gophertunnel/minecraft/protocol" + "github.com/sandertv/gophertunnel/minecraft/protocol/packet" +) + +// CameraAimAssist is sent by the server to the client to set up aim assist for the client's camera. +type CameraAimAssist struct { + // 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 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. + Action byte +} + +// ID ... +func (*CameraAimAssist) ID() uint32 { + return packet.IDCameraAimAssist +} + +func (pk *CameraAimAssist) Marshal(io protocol.IO) { + if proto.IsProtoGTE(io, proto.ID766) { + io.String(&pk.Preset) + } + io.Vec2(&pk.Angle) + io.Float32(&pk.Distance) + io.Uint8(&pk.TargetMode) + io.Uint8(&pk.Action) +} diff --git a/legacyver/legacypacket/camera_presets.go b/legacyver/legacypacket/camera_presets.go new file mode 100644 index 0000000..c954938 --- /dev/null +++ b/legacyver/legacypacket/camera_presets.go @@ -0,0 +1,23 @@ +package legacypacket + +import ( + "github.com/akmalfairuz/legacy-version/legacyver/proto" + "github.com/sandertv/gophertunnel/minecraft/protocol" + "github.com/sandertv/gophertunnel/minecraft/protocol/packet" +) + +// CameraPresets gives the client a list of custom camera presets. +type CameraPresets struct { + // Presets is a list of camera presets that can be used by other cameras. The order of this list is important because + // the index of presets is used as a pointer in the CameraInstruction packet. + Presets []proto.CameraPreset +} + +// ID ... +func (*CameraPresets) ID() uint32 { + return packet.IDCameraPresets +} + +func (pk *CameraPresets) Marshal(io protocol.IO) { + protocol.Slice(io, &pk.Presets) +} diff --git a/legacyver/legacypacket/player_auth_input.go b/legacyver/legacypacket/player_auth_input.go index 75ac970..9831dd0 100644 --- a/legacyver/legacypacket/player_auth_input.go +++ b/legacyver/legacypacket/player_auth_input.go @@ -7,102 +7,6 @@ import ( "github.com/sandertv/gophertunnel/minecraft/protocol/packet" ) -const PlayerAuthInputBitsetSize = 65 - -const ( - InputFlagAscend = iota - InputFlagDescend - InputFlagNorthJump - InputFlagJumpDown - InputFlagSprintDown - InputFlagChangeHeight - InputFlagJumping - InputFlagAutoJumpingInWater - InputFlagSneaking - InputFlagSneakDown - InputFlagUp - InputFlagDown - InputFlagLeft - InputFlagRight - InputFlagUpLeft - InputFlagUpRight - InputFlagWantUp - InputFlagWantDown - InputFlagWantDownSlow - InputFlagWantUpSlow - InputFlagSprinting - InputFlagAscendBlock - InputFlagDescendBlock - InputFlagSneakToggleDown - InputFlagPersistSneak - InputFlagStartSprinting - InputFlagStopSprinting - InputFlagStartSneaking - InputFlagStopSneaking - InputFlagStartSwimming - InputFlagStopSwimming - InputFlagStartJumping - InputFlagStartGliding - InputFlagStopGliding - InputFlagPerformItemInteraction - InputFlagPerformBlockActions - InputFlagPerformItemStackRequest - InputFlagHandledTeleport - InputFlagEmoting - InputFlagMissedSwing - InputFlagStartCrawling - InputFlagStopCrawling - InputFlagStartFlying - InputFlagStopFlying - InputFlagClientAckServerData - InputFlagClientPredictedVehicle - InputFlagPaddlingLeft - InputFlagPaddlingRight - InputFlagBlockBreakingDelayEnabled - InputFlagHorizontalCollision - InputFlagVerticalCollision - InputFlagDownLeft - InputFlagDownRight - InputFlagStartUsingItem - InputFlagCameraRelativeMovementEnabled - InputFlagRotControlledByMoveDirection - InputFlagStartSpinAttack - InputFlagStopSpinAttack - InputFlagIsHotbarTouchOnly - InputFlagJumpReleasedRaw - InputFlagJumpPressedRaw - InputFlagJumpCurrentRaw - InputFlagSneakReleasedRaw - InputFlagSneakPressedRaw - InputFlagSneakCurrentRaw -) - -const ( - InputModeMouse = iota + 1 - InputModeTouch - InputModeGamePad - InputModeMotionController -) - -const ( - PlayModeNormal = iota - PlayModeTeaser - PlayModeScreen - PlayModeViewer - PlayModeReality - PlayModePlacement - PlayModeLivingRoom - PlayModeExitLevel - PlayModeExitLevelLivingRoom - PlayModeNumModes -) - -const ( - InteractionModelTouch = iota - InteractionModelCrosshair - InteractionModelClassic -) - // PlayerAuthInput is sent by the client to allow for server authoritative movement. It is used to synchronise // the player input with the position server-side. // The client sends this packet when the ServerAuthoritativeMovementMode field in the StartGame packet is set @@ -172,7 +76,7 @@ func (pk *PlayerAuthInput) Marshal(io protocol.IO) { io.Vec2(&pk.MoveVector) io.Float32(&pk.HeadYaw) if proto.IsProtoGTE(io, proto.ID766) { - io.Bitset(&pk.InputData, PlayerAuthInputBitsetSize) + io.Bitset(&pk.InputData, packet.PlayerAuthInputBitsetSize) } else { io.Bitset(&pk.InputData, 64) } @@ -184,19 +88,19 @@ func (pk *PlayerAuthInput) Marshal(io protocol.IO) { io.Varuint64(&pk.Tick) io.Vec3(&pk.Delta) - if pk.InputData.Load(InputFlagPerformItemInteraction) { + if pk.InputData.Load(packet.InputFlagPerformItemInteraction) { io.PlayerInventoryAction(&pk.ItemInteractionData) } - if pk.InputData.Load(InputFlagPerformItemStackRequest) { + if pk.InputData.Load(packet.InputFlagPerformItemStackRequest) { protocol.Single(io, &pk.ItemStackRequest) } - if pk.InputData.Load(InputFlagPerformBlockActions) { + if pk.InputData.Load(packet.InputFlagPerformBlockActions) { protocol.SliceVarint32Length(io, &pk.BlockActions) } - if pk.InputData.Load(InputFlagClientPredictedVehicle) { + if pk.InputData.Load(packet.InputFlagClientPredictedVehicle) { io.Vec2(&pk.VehicleRotation) io.Varint64(&pk.ClientPredictedVehicle) } diff --git a/legacyver/proto/camera.go b/legacyver/proto/camera.go new file mode 100644 index 0000000..8f94362 --- /dev/null +++ b/legacyver/proto/camera.go @@ -0,0 +1,130 @@ +package proto + +import ( + "github.com/go-gl/mathgl/mgl32" + "github.com/sandertv/gophertunnel/minecraft/protocol" +) + +// 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. + Name string + // Parent is the name of the preset that this preset extends upon. This can be left empty. + Parent string + // PosX is the default X position of the camera. + PosX protocol.Optional[float32] + // PosY is the default Y position of the camera. + PosY protocol.Optional[float32] + // PosZ is the default Z position of the camera. + PosZ protocol.Optional[float32] + // RotX is the default pitch of the camera. + RotX protocol.Optional[float32] + // RotY is the default yaw of the camera. + RotY protocol.Optional[float32] + // RotationSpeed is the speed at which the camera should rotate. + RotationSpeed protocol.Optional[float32] + // SnapToTarget determines whether the camera should snap to the target entity or not. + SnapToTarget protocol.Optional[bool] + // HorizontalRotationLimit is the horizontal rotation limit of the camera. + HorizontalRotationLimit protocol.Optional[mgl32.Vec2] + // VerticalRotationLimit is the vertical rotation limit of the camera. + VerticalRotationLimit protocol.Optional[mgl32.Vec2] + // ContinueTargeting determines whether the camera should continue targeting when using aim assist. + ContinueTargeting protocol.Optional[bool] + // TrackingRadius is the radius around the camera that the aim assist should track targets. + TrackingRadius protocol.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 protocol.Optional[mgl32.Vec2] + // EntityOffset controls the offset from the entity that the camera should be rendered at. + EntityOffset protocol.Optional[mgl32.Vec3] + // Radius is only used in a follow_orbit camera and controls how far away from the player the camera should + // be rendered. + Radius protocol.Optional[float32] + // AudioListener defines where the audio should be played from when using this preset. This is one of the + // constants above. + AudioListener protocol.Optional[byte] + // PlayerEffects is currently unknown. + PlayerEffects protocol.Optional[bool] + // AlignTargetAndCameraForward determines whether the camera should align the target and the camera forward + // or not. + AlignTargetAndCameraForward protocol.Optional[bool] + // AimAssist defines the aim assist to use when using this preset. + AimAssist protocol.Optional[protocol.CameraPresetAimAssist] +} + +func (x *CameraPreset) FromLatest(cp protocol.CameraPreset) { + x.Name = cp.Name + x.Parent = cp.Parent + x.PosX = cp.PosX + x.PosY = cp.PosY + x.PosZ = cp.PosZ + x.RotX = cp.RotX + x.RotY = cp.RotY + x.RotationSpeed = cp.RotationSpeed + x.SnapToTarget = cp.SnapToTarget + x.HorizontalRotationLimit = cp.HorizontalRotationLimit + x.VerticalRotationLimit = cp.VerticalRotationLimit + x.ContinueTargeting = cp.ContinueTargeting + x.TrackingRadius = cp.TrackingRadius + x.ViewOffset = cp.ViewOffset + x.EntityOffset = cp.EntityOffset + x.Radius = cp.Radius + x.AudioListener = cp.AudioListener + x.PlayerEffects = cp.PlayerEffects + x.AlignTargetAndCameraForward = cp.AlignTargetAndCameraForward + x.AimAssist = cp.AimAssist +} + +func (x *CameraPreset) ToLatest() protocol.CameraPreset { + return protocol.CameraPreset{ + Name: x.Name, + Parent: x.Parent, + PosX: x.PosX, + PosY: x.PosY, + PosZ: x.PosZ, + RotX: x.RotX, + RotY: x.RotY, + RotationSpeed: x.RotationSpeed, + SnapToTarget: x.SnapToTarget, + HorizontalRotationLimit: x.HorizontalRotationLimit, + VerticalRotationLimit: x.VerticalRotationLimit, + ContinueTargeting: x.ContinueTargeting, + TrackingRadius: x.TrackingRadius, + ViewOffset: x.ViewOffset, + EntityOffset: x.EntityOffset, + Radius: x.Radius, + AudioListener: x.AudioListener, + PlayerEffects: x.PlayerEffects, + AlignTargetAndCameraForward: x.AlignTargetAndCameraForward, + AimAssist: x.AimAssist, + } +} + +// Marshal encodes/decodes a CameraPreset. +func (x *CameraPreset) Marshal(r protocol.IO) { + r.String(&x.Name) + r.String(&x.Parent) + protocol.OptionalFunc(r, &x.PosX, r.Float32) + protocol.OptionalFunc(r, &x.PosY, r.Float32) + protocol.OptionalFunc(r, &x.PosZ, r.Float32) + protocol.OptionalFunc(r, &x.RotX, r.Float32) + protocol.OptionalFunc(r, &x.RotY, r.Float32) + protocol.OptionalFunc(r, &x.RotationSpeed, r.Float32) + protocol.OptionalFunc(r, &x.SnapToTarget, r.Bool) + protocol.OptionalFunc(r, &x.HorizontalRotationLimit, r.Vec2) + protocol.OptionalFunc(r, &x.VerticalRotationLimit, r.Vec2) + protocol.OptionalFunc(r, &x.ContinueTargeting, r.Bool) + if IsProtoGTE(r, ID766) { + protocol.OptionalFunc(r, &x.TrackingRadius, r.Float32) + } + protocol.OptionalFunc(r, &x.ViewOffset, r.Vec2) + protocol.OptionalFunc(r, &x.EntityOffset, r.Vec3) + protocol.OptionalFunc(r, &x.Radius, r.Float32) + protocol.OptionalFunc(r, &x.AudioListener, r.Uint8) + protocol.OptionalFunc(r, &x.PlayerEffects, r.Bool) + protocol.OptionalFunc(r, &x.AlignTargetAndCameraForward, r.Bool) + if IsProtoGTE(r, ID766) { + protocol.OptionalMarshaler(r, &x.AimAssist) + } +} diff --git a/legacyver/protocol.go b/legacyver/protocol.go index 421968f..43c2755 100644 --- a/legacyver/protocol.go +++ b/legacyver/protocol.go @@ -19,8 +19,10 @@ func init() { packetPoolServer[packet.IDItemStackResponse] = func() packet.Packet { return &legacypacket.ItemStackResponse{} } packetPoolServer[packet.IDResourcePacksInfo] = func() packet.Packet { return &legacypacket.ResourcePacksInfo{} } + packetPoolServer[packet.IDCameraPresets] = func() packet.Packet { return &legacypacket.CameraPresets{} } packetPoolClient[packet.IDPlayerAuthInput] = func() packet.Packet { return &legacypacket.PlayerAuthInput{} } + packetPoolClient[packet.IDCameraAimAssist] = func() packet.Packet { return &legacypacket.CameraAimAssist{} } } type Protocol struct { @@ -69,6 +71,14 @@ func (p *Protocol) ConvertFromLatest(pk packet.Packet, conn *minecraft.Conn) []p func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) []packet.Packet { for pkIndex, pk := range pks { switch pk := pk.(type) { + case *packet.CameraPresets: + presets := make([]proto.CameraPreset, len(pk.Presets)) + for i, p := range pk.Presets { + presets[i].FromLatest(p) + } + pks[pkIndex] = &legacypacket.CameraPresets{ + Presets: presets, + } case *packet.StartGame: pk.GameVersion = p.ver pk.BaseGameVersion = p.ver @@ -163,6 +173,14 @@ func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) [ func (p *Protocol) upgradePackets(pks []packet.Packet, conn *minecraft.Conn) []packet.Packet { for pkIndex, pk := range pks { switch pk := pk.(type) { + case *legacypacket.CameraPresets: + presets := make([]protocol.CameraPreset, len(pk.Presets)) + for i, p := range pk.Presets { + presets[i] = p.ToLatest() + } + pks[pkIndex] = &packet.CameraPresets{ + Presets: presets, + } case *packet.StartGame: pk.GameVersion = p.ver pk.BaseGameVersion = p.ver diff --git a/legacyver/v748.go b/legacyver/v748.go index 3e2a667..949d7cc 100644 --- a/legacyver/v748.go +++ b/legacyver/v748.go @@ -15,11 +15,11 @@ const ( ) var ( - //go:embed item_runtime_ids_748.nbt + //go:embed data/item_runtime_ids_748.nbt itemRuntimeIDData748 []byte - //go:embed required_item_list_748.json + //go:embed data/required_item_list_748.json requiredItemList748 []byte - //go:embed block_states_748.nbt + //go:embed data/block_states_748.nbt blockStateData748 []byte ) diff --git a/legacyver/v766.go b/legacyver/v766.go index b9d32ae..4ca2308 100644 --- a/legacyver/v766.go +++ b/legacyver/v766.go @@ -13,11 +13,11 @@ const ( ) var ( - //go:embed item_runtime_ids_766.nbt + //go:embed data/item_runtime_ids_766.nbt itemRuntimeIDData766 []byte - //go:embed required_item_list_766.json + //go:embed data/required_item_list_766.json requiredItemList766 []byte - //go:embed block_states_766.nbt + //go:embed data/block_states_766.nbt blockStateData766 []byte itemMappingLatest = mapping.NewItemMapping(itemRuntimeIDData766, requiredItemList766, ItemVersion766, false)