Add 1.21.30

This commit is contained in:
AkmalFairuz
2025-01-01 05:00:42 +07:00
parent a8442c7a2a
commit 45cfb78b30
14 changed files with 7174 additions and 13 deletions

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

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"
)
// InventoryContent is sent by the server to update the full content of a particular inventory. It is usually
// sent for the main inventory of the player, but also works for other inventories that are currently opened
// by the player.
type InventoryContent struct {
// WindowID is the ID that identifies one of the windows that the client currently has opened, or one of
// the consistent windows such as the main inventory.
WindowID uint32
// Content is the new content of the inventory. The length of this slice must be equal to the full size of
// the inventory window updated.
Content []protocol.ItemInstance
// Container is the protocol.FullContainerName that describes the container that the content is for.
Container protocol.FullContainerName
// DynamicContainerSize ...
DynamicContainerSize uint32
// StorageItem is the item that is acting as the storage container for the inventory. If the inventory is
// not a dynamic container then this field should be left empty. When set, only the item type is used by
// the client and none of the other stack info.
StorageItem protocol.ItemInstance
}
// ID ...
func (*InventoryContent) ID() uint32 {
return packet.IDInventoryContent
}
func (pk *InventoryContent) Marshal(io protocol.IO) {
io.Varuint32(&pk.WindowID)
protocol.FuncSlice(io, &pk.Content, io.ItemInstance)
protocol.Single(io, &pk.Container)
if proto.IsProtoGTE(io, proto.ID748) {
io.ItemInstance(&pk.StorageItem)
} else {
io.Varuint32(&pk.DynamicContainerSize)
}
}

View File

@@ -0,0 +1,47 @@
package legacypacket
import (
"github.com/akmalfairuz/legacy-version/legacyver/proto"
"github.com/sandertv/gophertunnel/minecraft/protocol"
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
)
// InventorySlot is sent by the server to update a single slot in one of the inventory windows that the client
// currently has opened. Usually this is the main inventory, but it may also be the off hand or, for example,
// a chest inventory.
type InventorySlot struct {
// WindowID is the ID of the window that the packet modifies. It must point to one of the windows that the
// client currently has opened.
WindowID uint32
// Slot is the index of the slot that the packet modifies. The new item will be set to the slot at this
// index.
Slot uint32
// Container is the protocol.FullContainerName that describes the container that the content is for.
Container protocol.FullContainerName
// DynamicContainerSize ...
DynamicContainerSize uint32
// StorageItem is the item that is acting as the storage container for the inventory. If the inventory is
// not a dynamic container then this field should be left empty. When set, only the item type is used by
// the client and none of the other stack info.
StorageItem protocol.ItemInstance
// NewItem is the item to be put in the slot at Slot. It will overwrite any item that may currently
// be present in that slot.
NewItem protocol.ItemInstance
}
// ID ...
func (*InventorySlot) ID() uint32 {
return packet.IDInventorySlot
}
func (pk *InventorySlot) Marshal(io protocol.IO) {
io.Varuint32(&pk.WindowID)
io.Varuint32(&pk.Slot)
protocol.Single(io, &pk.Container)
if proto.IsProtoGTE(io, proto.ID748) {
io.ItemInstance(&pk.StorageItem)
} else {
io.Varuint32(&pk.DynamicContainerSize)
}
io.ItemInstance(&pk.NewItem)
}

View File

@@ -0,0 +1,52 @@
package legacypacket
import (
"github.com/akmalfairuz/legacy-version/legacyver/proto"
"github.com/sandertv/gophertunnel/minecraft/protocol"
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
)
// MobEffect is sent by the server to apply an effect to the player, for example an effect like poison. It may
// also be used to modify existing effects, or removing them completely.
type MobEffect struct {
// EntityRuntimeID is the runtime ID of the entity. The runtime ID is unique for each world session, and
// entities are generally identified in packets using this runtime ID.
EntityRuntimeID uint64
// Operation is the operation of the packet. It is either MobEffectAdd, MobEffectModify or MobEffectRemove
// and specifies the result of the packet client-side.
Operation byte
// EffectType is the ID of the effect to be added, removed or modified. It is one of the constants that
// may be found above.
EffectType int32
// Amplifier is the amplifier of the effect. Take note that the amplifier is not the same as the effect's
// level. The level is usually one higher than the amplifier, and the amplifier can actually be negative
// to reverse the behaviour effect.
Amplifier int32
// Particles specifies if viewers of the entity that gets the effect shows particles around it. If set to
// false, no particles are emitted around the entity.
Particles bool
// Duration is the duration of the effect in seconds. After the duration has elapsed, the effect will be
// removed automatically client-side.
Duration int32
// Tick is the server tick at which the packet was sent. It is used in relation to CorrectPlayerMovePrediction.
Tick uint64
}
// ID ...
func (*MobEffect) ID() uint32 {
return packet.IDMobEffect
}
func (pk *MobEffect) Marshal(io protocol.IO) {
io.Varuint64(&pk.EntityRuntimeID)
io.Uint8(&pk.Operation)
io.Varint32(&pk.EffectType)
io.Varint32(&pk.Amplifier)
io.Bool(&pk.Particles)
io.Varint32(&pk.Duration)
if proto.IsProtoGTE(io, proto.ID748) {
io.Varuint64(&pk.Tick)
} else {
io.Uint64(&pk.Tick)
}
}

View File

@@ -83,8 +83,10 @@ func (pk *PlayerAuthInput) Marshal(io protocol.IO) {
io.Varuint32(&pk.InputMode)
io.Varuint32(&pk.PlayMode)
io.Varuint32(&pk.InteractionModel)
io.Float32(&pk.InteractPitch)
io.Float32(&pk.InteractYaw)
if proto.IsProtoGTE(io, proto.ID748) {
io.Float32(&pk.InteractPitch)
io.Float32(&pk.InteractYaw)
}
io.Varuint64(&pk.Tick)
io.Vec3(&pk.Delta)
@@ -106,7 +108,9 @@ func (pk *PlayerAuthInput) Marshal(io protocol.IO) {
}
io.Vec2(&pk.AnalogueMoveVector)
io.Vec3(&pk.CameraOrientation)
if proto.IsProtoGTE(io, proto.ID748) {
io.Vec3(&pk.CameraOrientation)
}
if proto.IsProtoGTE(io, proto.ID766) {
io.Vec2(&pk.RawMoveVector)

View File

@@ -31,6 +31,9 @@ type ResourcePacksInfo struct {
// The order of these texture packs is not relevant in this packet. It is however important in the
// ResourcePackStack packet.
TexturePacks []proto.TexturePackInfo
// PackURLs ...
PackURLs []protocol.PackURL
}
// ID ...
@@ -47,4 +50,9 @@ func (pk *ResourcePacksInfo) Marshal(io protocol.IO) {
io.String(&pk.WorldTemplateVersion)
}
protocol.SliceUint16Length(io, &pk.TexturePacks)
if proto.IsProtoLT(io, proto.ID748) {
protocol.Slice(io, &pk.PackURLs)
} else {
proto.EmptySlice(io, &pk.PackURLs)
}
}

View File

@@ -112,9 +112,11 @@ func (x *CameraPreset) Marshal(r protocol.IO) {
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, ID748) {
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)
}
@@ -123,7 +125,9 @@ func (x *CameraPreset) Marshal(r protocol.IO) {
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, ID748) {
protocol.OptionalFunc(r, &x.AlignTargetAndCameraForward, r.Bool)
}
if IsProtoGTE(r, ID766) {
protocol.OptionalMarshaler(r, &x.AimAssist)
}

View File

@@ -51,3 +51,9 @@ func IsWriter(w protocol.IO) bool {
_, ok := w.(*Writer)
return ok
}
func EmptySlice[T any](io protocol.IO, slice *[]T) {
if IsReader(io) {
*slice = make([]T, 0)
}
}

View File

@@ -75,5 +75,7 @@ func (x *TexturePackInfo) Marshal(r protocol.IO) {
r.Bool(&x.HasScripts)
r.Bool(&x.AddonPack)
r.Bool(&x.RTXEnabled)
r.String(&x.DownloadURL)
if IsProtoGTE(r, ID748) {
r.String(&x.DownloadURL)
}
}

View File

@@ -17,12 +17,32 @@ func init() {
packetPoolClient = packet.NewClientPool()
packetPoolServer = packet.NewServerPool()
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{} }
for pkId, cur := range packetPoolClient {
packetPoolClient[pkId] = convertPacketFunc(pkId, cur)
}
}
packetPoolClient[packet.IDPlayerAuthInput] = func() packet.Packet { return &legacypacket.PlayerAuthInput{} }
packetPoolClient[packet.IDCameraAimAssist] = func() packet.Packet { return &legacypacket.CameraAimAssist{} }
func convertPacketFunc(pid uint32, cur func() packet.Packet) func() packet.Packet {
switch pid {
case packet.IDCameraAimAssist:
return func() packet.Packet { return &legacypacket.CameraAimAssist{} }
case packet.IDCameraPresets:
return func() packet.Packet { return &legacypacket.CameraPresets{} }
case packet.IDInventoryContent:
return func() packet.Packet { return &legacypacket.InventoryContent{} }
case packet.IDInventorySlot:
return func() packet.Packet { return &legacypacket.InventorySlot{} }
case packet.IDItemStackResponse:
return func() packet.Packet { return &legacypacket.ItemStackResponse{} }
case packet.IDMobEffect:
return func() packet.Packet { return &legacypacket.MobEffect{} }
case packet.IDPlayerAuthInput:
return func() packet.Packet { return &legacypacket.PlayerAuthInput{} }
case packet.IDResourcePacksInfo:
return func() packet.Packet { return &legacypacket.ResourcePacksInfo{} }
default:
return cur
}
}
type Protocol struct {
@@ -142,6 +162,7 @@ func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) [
pks[pkIndex] = &legacypacket.ItemStackResponse{Responses: responses}
case *packet.ResourcePacksInfo:
texturePacks := make([]proto.TexturePackInfo, len(pk.TexturePacks))
packURLs := make([]protocol.PackURL, 0)
for i, t := range pk.TexturePacks {
texturePacks[i] = proto.TexturePackInfo{
UUID: t.UUID,
@@ -155,6 +176,12 @@ func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) [
RTXEnabled: t.RTXEnabled,
DownloadURL: t.DownloadURL,
}
if t.DownloadURL != "" {
packURLs = append(packURLs, protocol.PackURL{
UUIDVersion: t.UUID.String() + "_" + t.Version,
URL: t.DownloadURL,
})
}
}
pks[pkIndex] = &legacypacket.ResourcePacksInfo{
TexturePackRequired: pk.TexturePackRequired,
@@ -163,6 +190,7 @@ func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) [
WorldTemplateUUID: pk.WorldTemplateUUID,
WorldTemplateVersion: pk.WorldTemplateVersion,
TexturePacks: texturePacks,
PackURLs: packURLs,
}
}
}
@@ -220,6 +248,14 @@ func (p *Protocol) upgradePackets(pks []packet.Packet, conn *minecraft.Conn) []p
texturePacks := make([]protocol.TexturePackInfo, len(pk.TexturePacks))
for i, t := range pk.TexturePacks {
texturePacks[i] = t.ToLatest()
if texturePacks[i].DownloadURL == "" {
for _, u := range pk.PackURLs {
if u.UUIDVersion == t.UUID.String()+"_"+t.Version {
texturePacks[i].DownloadURL = u.URL
break
}
}
}
}
pks[pkIndex] = &packet.ResourcePacksInfo{
TexturePackRequired: pk.TexturePackRequired,

36
legacyver/v729.go Normal file
View File

@@ -0,0 +1,36 @@
package legacyver
import (
_ "embed"
"github.com/akmalfairuz/legacy-version/internal/chunk"
"github.com/akmalfairuz/legacy-version/legacyver/proto"
"github.com/akmalfairuz/legacy-version/mapping"
)
const (
// ItemVersion729 ...
ItemVersion729 = 211
// BlockVersion729 ...
BlockVersion729 int32 = (1 << 24) | (21 << 16) | (30 << 8)
)
var (
//go:embed data/item_runtime_ids_729.nbt
itemRuntimeIDData729 []byte
//go:embed data/required_item_list_729.json
requiredItemList729 []byte
//go:embed data/block_states_729.nbt
blockStateData729 []byte
)
func New729(direct bool) *Protocol {
itemMapping := mapping.NewItemMapping(itemRuntimeIDData729, requiredItemList729, ItemVersion729, false)
blockMapping := mapping.NewBlockMapping(blockStateData729)
return &Protocol{
ver: "1.21.30",
id: proto.ID729,
blockTranslator: NewBlockTranslator(blockMapping, latestBlockMapping, chunk.NewNetworkPersistentEncoding(blockMapping, BlockVersion729), chunk.NewBlockPaletteEncoding(blockMapping, BlockVersion729), false),
itemTranslator: NewItemTranslator(itemMapping, itemMappingLatest, blockMapping, blockMappingLatest),
}
}