Add 1.21.30
This commit is contained in:
17
README.md
Normal file
17
README.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# legacy-version
|
||||||
|
|
||||||
|
A gophertunnel protocol interface implementation to support older Minecraft Bedrock versions.
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
| Protocol ID | Version | Support |
|
||||||
|
|-------------|---------|---------|
|
||||||
|
| 766 | 1.21.50 | ✅ |
|
||||||
|
| 748 | 1.21.40 | ✅ |
|
||||||
|
| 729 | 1.21.30 | ✅ |
|
||||||
|
| 712 | 1.21.20 | 🚧 |
|
||||||
|
| 686 | 1.21.2 | 🚧 |
|
||||||
|
| 685 | 1.21.0 | 🚧 |
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
- [Flonja/multiversion](https://github.com/Flonja/multiversion)
|
||||||
|
- [oomph-ac/new-mv](https://github.com/oomph-ac/new-mv)
|
||||||
BIN
legacyver/data/block_states_729.nbt
Normal file
BIN
legacyver/data/block_states_729.nbt
Normal file
Binary file not shown.
BIN
legacyver/data/item_runtime_ids_729.nbt
Normal file
BIN
legacyver/data/item_runtime_ids_729.nbt
Normal file
Binary file not shown.
6906
legacyver/data/required_item_list_729.json
Normal file
6906
legacyver/data/required_item_list_729.json
Normal file
File diff suppressed because it is too large
Load Diff
43
legacyver/legacypacket/inventory_content.go
Normal file
43
legacyver/legacypacket/inventory_content.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
47
legacyver/legacypacket/inventory_slot.go
Normal file
47
legacyver/legacypacket/inventory_slot.go
Normal 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)
|
||||||
|
}
|
||||||
52
legacyver/legacypacket/mob_effect.go
Normal file
52
legacyver/legacypacket/mob_effect.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -83,8 +83,10 @@ func (pk *PlayerAuthInput) Marshal(io protocol.IO) {
|
|||||||
io.Varuint32(&pk.InputMode)
|
io.Varuint32(&pk.InputMode)
|
||||||
io.Varuint32(&pk.PlayMode)
|
io.Varuint32(&pk.PlayMode)
|
||||||
io.Varuint32(&pk.InteractionModel)
|
io.Varuint32(&pk.InteractionModel)
|
||||||
|
if proto.IsProtoGTE(io, proto.ID748) {
|
||||||
io.Float32(&pk.InteractPitch)
|
io.Float32(&pk.InteractPitch)
|
||||||
io.Float32(&pk.InteractYaw)
|
io.Float32(&pk.InteractYaw)
|
||||||
|
}
|
||||||
io.Varuint64(&pk.Tick)
|
io.Varuint64(&pk.Tick)
|
||||||
io.Vec3(&pk.Delta)
|
io.Vec3(&pk.Delta)
|
||||||
|
|
||||||
@@ -106,7 +108,9 @@ func (pk *PlayerAuthInput) Marshal(io protocol.IO) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
io.Vec2(&pk.AnalogueMoveVector)
|
io.Vec2(&pk.AnalogueMoveVector)
|
||||||
|
if proto.IsProtoGTE(io, proto.ID748) {
|
||||||
io.Vec3(&pk.CameraOrientation)
|
io.Vec3(&pk.CameraOrientation)
|
||||||
|
}
|
||||||
|
|
||||||
if proto.IsProtoGTE(io, proto.ID766) {
|
if proto.IsProtoGTE(io, proto.ID766) {
|
||||||
io.Vec2(&pk.RawMoveVector)
|
io.Vec2(&pk.RawMoveVector)
|
||||||
|
|||||||
@@ -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
|
// The order of these texture packs is not relevant in this packet. It is however important in the
|
||||||
// ResourcePackStack packet.
|
// ResourcePackStack packet.
|
||||||
TexturePacks []proto.TexturePackInfo
|
TexturePacks []proto.TexturePackInfo
|
||||||
|
|
||||||
|
// PackURLs ...
|
||||||
|
PackURLs []protocol.PackURL
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID ...
|
// ID ...
|
||||||
@@ -47,4 +50,9 @@ func (pk *ResourcePacksInfo) Marshal(io protocol.IO) {
|
|||||||
io.String(&pk.WorldTemplateVersion)
|
io.String(&pk.WorldTemplateVersion)
|
||||||
}
|
}
|
||||||
protocol.SliceUint16Length(io, &pk.TexturePacks)
|
protocol.SliceUint16Length(io, &pk.TexturePacks)
|
||||||
|
if proto.IsProtoLT(io, proto.ID748) {
|
||||||
|
protocol.Slice(io, &pk.PackURLs)
|
||||||
|
} else {
|
||||||
|
proto.EmptySlice(io, &pk.PackURLs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,9 +112,11 @@ func (x *CameraPreset) Marshal(r protocol.IO) {
|
|||||||
protocol.OptionalFunc(r, &x.RotY, r.Float32)
|
protocol.OptionalFunc(r, &x.RotY, r.Float32)
|
||||||
protocol.OptionalFunc(r, &x.RotationSpeed, r.Float32)
|
protocol.OptionalFunc(r, &x.RotationSpeed, r.Float32)
|
||||||
protocol.OptionalFunc(r, &x.SnapToTarget, r.Bool)
|
protocol.OptionalFunc(r, &x.SnapToTarget, r.Bool)
|
||||||
|
if IsProtoGTE(r, ID748) {
|
||||||
protocol.OptionalFunc(r, &x.HorizontalRotationLimit, r.Vec2)
|
protocol.OptionalFunc(r, &x.HorizontalRotationLimit, r.Vec2)
|
||||||
protocol.OptionalFunc(r, &x.VerticalRotationLimit, r.Vec2)
|
protocol.OptionalFunc(r, &x.VerticalRotationLimit, r.Vec2)
|
||||||
protocol.OptionalFunc(r, &x.ContinueTargeting, r.Bool)
|
protocol.OptionalFunc(r, &x.ContinueTargeting, r.Bool)
|
||||||
|
}
|
||||||
if IsProtoGTE(r, ID766) {
|
if IsProtoGTE(r, ID766) {
|
||||||
protocol.OptionalFunc(r, &x.TrackingRadius, r.Float32)
|
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.Radius, r.Float32)
|
||||||
protocol.OptionalFunc(r, &x.AudioListener, r.Uint8)
|
protocol.OptionalFunc(r, &x.AudioListener, r.Uint8)
|
||||||
protocol.OptionalFunc(r, &x.PlayerEffects, r.Bool)
|
protocol.OptionalFunc(r, &x.PlayerEffects, r.Bool)
|
||||||
|
if IsProtoGTE(r, ID748) {
|
||||||
protocol.OptionalFunc(r, &x.AlignTargetAndCameraForward, r.Bool)
|
protocol.OptionalFunc(r, &x.AlignTargetAndCameraForward, r.Bool)
|
||||||
|
}
|
||||||
if IsProtoGTE(r, ID766) {
|
if IsProtoGTE(r, ID766) {
|
||||||
protocol.OptionalMarshaler(r, &x.AimAssist)
|
protocol.OptionalMarshaler(r, &x.AimAssist)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,3 +51,9 @@ func IsWriter(w protocol.IO) bool {
|
|||||||
_, ok := w.(*Writer)
|
_, ok := w.(*Writer)
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func EmptySlice[T any](io protocol.IO, slice *[]T) {
|
||||||
|
if IsReader(io) {
|
||||||
|
*slice = make([]T, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -75,5 +75,7 @@ func (x *TexturePackInfo) Marshal(r protocol.IO) {
|
|||||||
r.Bool(&x.HasScripts)
|
r.Bool(&x.HasScripts)
|
||||||
r.Bool(&x.AddonPack)
|
r.Bool(&x.AddonPack)
|
||||||
r.Bool(&x.RTXEnabled)
|
r.Bool(&x.RTXEnabled)
|
||||||
|
if IsProtoGTE(r, ID748) {
|
||||||
r.String(&x.DownloadURL)
|
r.String(&x.DownloadURL)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,12 +17,32 @@ func init() {
|
|||||||
packetPoolClient = packet.NewClientPool()
|
packetPoolClient = packet.NewClientPool()
|
||||||
packetPoolServer = packet.NewServerPool()
|
packetPoolServer = packet.NewServerPool()
|
||||||
|
|
||||||
packetPoolServer[packet.IDItemStackResponse] = func() packet.Packet { return &legacypacket.ItemStackResponse{} }
|
for pkId, cur := range packetPoolClient {
|
||||||
packetPoolServer[packet.IDResourcePacksInfo] = func() packet.Packet { return &legacypacket.ResourcePacksInfo{} }
|
packetPoolClient[pkId] = convertPacketFunc(pkId, cur)
|
||||||
packetPoolServer[packet.IDCameraPresets] = func() packet.Packet { return &legacypacket.CameraPresets{} }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
packetPoolClient[packet.IDPlayerAuthInput] = func() packet.Packet { return &legacypacket.PlayerAuthInput{} }
|
func convertPacketFunc(pid uint32, cur func() packet.Packet) func() packet.Packet {
|
||||||
packetPoolClient[packet.IDCameraAimAssist] = func() packet.Packet { return &legacypacket.CameraAimAssist{} }
|
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 {
|
type Protocol struct {
|
||||||
@@ -142,6 +162,7 @@ func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) [
|
|||||||
pks[pkIndex] = &legacypacket.ItemStackResponse{Responses: responses}
|
pks[pkIndex] = &legacypacket.ItemStackResponse{Responses: responses}
|
||||||
case *packet.ResourcePacksInfo:
|
case *packet.ResourcePacksInfo:
|
||||||
texturePacks := make([]proto.TexturePackInfo, len(pk.TexturePacks))
|
texturePacks := make([]proto.TexturePackInfo, len(pk.TexturePacks))
|
||||||
|
packURLs := make([]protocol.PackURL, 0)
|
||||||
for i, t := range pk.TexturePacks {
|
for i, t := range pk.TexturePacks {
|
||||||
texturePacks[i] = proto.TexturePackInfo{
|
texturePacks[i] = proto.TexturePackInfo{
|
||||||
UUID: t.UUID,
|
UUID: t.UUID,
|
||||||
@@ -155,6 +176,12 @@ func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) [
|
|||||||
RTXEnabled: t.RTXEnabled,
|
RTXEnabled: t.RTXEnabled,
|
||||||
DownloadURL: t.DownloadURL,
|
DownloadURL: t.DownloadURL,
|
||||||
}
|
}
|
||||||
|
if t.DownloadURL != "" {
|
||||||
|
packURLs = append(packURLs, protocol.PackURL{
|
||||||
|
UUIDVersion: t.UUID.String() + "_" + t.Version,
|
||||||
|
URL: t.DownloadURL,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pks[pkIndex] = &legacypacket.ResourcePacksInfo{
|
pks[pkIndex] = &legacypacket.ResourcePacksInfo{
|
||||||
TexturePackRequired: pk.TexturePackRequired,
|
TexturePackRequired: pk.TexturePackRequired,
|
||||||
@@ -163,6 +190,7 @@ func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) [
|
|||||||
WorldTemplateUUID: pk.WorldTemplateUUID,
|
WorldTemplateUUID: pk.WorldTemplateUUID,
|
||||||
WorldTemplateVersion: pk.WorldTemplateVersion,
|
WorldTemplateVersion: pk.WorldTemplateVersion,
|
||||||
TexturePacks: texturePacks,
|
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))
|
texturePacks := make([]protocol.TexturePackInfo, len(pk.TexturePacks))
|
||||||
for i, t := range pk.TexturePacks {
|
for i, t := range pk.TexturePacks {
|
||||||
texturePacks[i] = t.ToLatest()
|
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{
|
pks[pkIndex] = &packet.ResourcePacksInfo{
|
||||||
TexturePackRequired: pk.TexturePackRequired,
|
TexturePackRequired: pk.TexturePackRequired,
|
||||||
|
|||||||
36
legacyver/v729.go
Normal file
36
legacyver/v729.go
Normal 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),
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user