1.21.111 support (thanks akmal)

This commit is contained in:
ethaniccc
2025-10-30 09:21:54 -04:00
17 changed files with 9794 additions and 61 deletions

View File

@@ -0,0 +1,43 @@
package legacypacket
import (
"github.com/akmalfairuz/legacy-version/legacyver/proto"
"github.com/sandertv/gophertunnel/minecraft/protocol"
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
)
// Animate is sent by the server to send a player animation from one player to all viewers of that player. It
// is used for a couple of actions, such as arm swimming and critical hits.
type Animate struct {
// ActionType is the ID of the animation action to execute. It is one of the action type constants that
// may be found above.
ActionType int32
// EntityRuntimeID is the runtime ID of the player that the animation should be played upon. The runtime
// ID is unique for each world session, and entities are generally identified in packets using this
// runtime ID.
EntityRuntimeID uint64
// Data ...
Data float32
// RowingTime is the time for rowing actions.
RowingTime float32
}
// ID ...
func (*Animate) ID() uint32 {
return packet.IDAnimate
}
func (pk *Animate) Marshal(io protocol.IO) {
io.Varint32(&pk.ActionType)
io.Varuint64(&pk.EntityRuntimeID)
if proto.IsProtoGTE(io, proto.ID859) {
io.Float32(&pk.Data)
if pk.ActionType == packet.AnimateActionRowLeft || pk.ActionType == packet.AnimateActionRowRight {
io.Float32(&pk.RowingTime)
}
} else {
if pk.ActionType&0x80 != 0 {
io.Float32(&pk.RowingTime)
}
}
}

View File

@@ -20,6 +20,12 @@ type CameraInstruction struct {
RemoveTarget protocol.Optional[bool]
// FieldOfView is a camera instruction that updates the field of view for the camera.
FieldOfView protocol.Optional[protocol.CameraInstructionFieldOfView]
// Spline is a camera instruction that creates a spline path for the camera to follow.
Spline protocol.Optional[protocol.CameraSplineInstruction]
// AttachToEntity is the entity ID to attach the camera to.
AttachToEntity protocol.Optional[int64]
// DetachFromEntity can be set to true to detach the camera from the current entity.
DetachFromEntity protocol.Optional[bool]
}
// ID ...
@@ -38,4 +44,9 @@ func (pk *CameraInstruction) Marshal(io protocol.IO) {
if proto.IsProtoGTE(io, proto.ID827) {
protocol.OptionalMarshaler(io, &pk.FieldOfView)
}
if proto.IsProtoGTE(io, proto.ID859) {
protocol.OptionalMarshaler(io, &pk.Spline)
protocol.OptionalFunc(io, &pk.AttachToEntity, io.Int64)
protocol.OptionalFunc(io, &pk.DetachFromEntity, io.Bool)
}
}

View File

@@ -55,7 +55,7 @@ type CommandBlockUpdate struct {
ShouldTrackOutput bool
// TickDelay is the delay in ticks between executions of a command block, if it is a repeating command
// block.
TickDelay int32
TickDelay uint32
// ExecuteOnFirstTick specifies if the command block should execute on the first tick, AKA as soon as the
// command block is enabled.
ExecuteOnFirstTick bool
@@ -83,6 +83,6 @@ func (pk *CommandBlockUpdate) Marshal(io protocol.IO) {
io.String(&pk.FilteredName)
}
io.Bool(&pk.ShouldTrackOutput)
io.Int32(&pk.TickDelay)
io.Uint32(&pk.TickDelay)
io.Bool(&pk.ExecuteOnFirstTick)
}

View File

@@ -31,7 +31,7 @@ func (pk *PlayerArmourDamage) Marshal(io protocol.IO) {
for _, flag := range flags {
if bitset&flag != 0 {
v := protocol.PlayerArmourDamageEntry{
ArmourSlot: flag,
ArmourSlot: int32(flag),
}
v2 := int32(0)
io.Varint32(&v2)
@@ -53,7 +53,7 @@ func (pk *PlayerArmourDamage) Marshal(io protocol.IO) {
if bitset&flag != 0 {
damage := int32(0)
for _, entry := range pk.List {
if entry.ArmourSlot == flag {
if entry.ArmourSlot == int32(flag) {
damage = int32(entry.Damage)
break
}
@@ -63,5 +63,5 @@ func (pk *PlayerArmourDamage) Marshal(io protocol.IO) {
}
return
}
protocol.SliceVarint32Length(io, &pk.List)
protocol.Slice(io, &pk.List)
}

View File

@@ -175,7 +175,7 @@ type StartGame struct {
EducationSharedResourceURI protocol.EducationSharedResourceURI
// ForceExperimentalGameplay specifies if experimental gameplay should be force enabled. For servers this
// should always be set to false.
ForceExperimentalGameplay protocol.Optional[bool]
ForceExperimentalGameplay bool
// LevelID is a base64 encoded world ID that is used to identify the world.
LevelID string
// WorldName is the name of the world that the player is joining. Note that this field shows up above the
@@ -306,7 +306,7 @@ func (pk *StartGame) Marshal(io protocol.IO) {
io.Int32(&pk.LimitedWorldDepth)
io.Bool(&pk.NewNether)
protocol.Single(io, &pk.EducationSharedResourceURI)
protocol.OptionalFunc(io, &pk.ForceExperimentalGameplay, io.Bool)
io.Bool(&pk.ForceExperimentalGameplay)
io.Uint8(&pk.ChatRestrictionLevel)
io.Bool(&pk.DisablePlayerInteractions)
if proto.IsProtoGTE(io, proto.ID685) {