Add support for protocol version 800 (1.21.80)
Introduced support for protocol 800, including biome definitions, camera presets, and player list updates. Upgraded dependencies, adjusted mappings, and enhanced the README to reflect recent changes.
This commit is contained in:
@@ -5,6 +5,7 @@ import "github.com/sandertv/gophertunnel/minecraft"
|
||||
// All returns a slice of all legacy protocol versions that are supported.
|
||||
func All() []minecraft.Protocol {
|
||||
return []minecraft.Protocol{
|
||||
New786(),
|
||||
New776(),
|
||||
New766(),
|
||||
New748(),
|
||||
|
||||
BIN
legacyver/data/block_states_800.nbt
Normal file
BIN
legacyver/data/block_states_800.nbt
Normal file
Binary file not shown.
9151
legacyver/data/required_item_list_800.json
Normal file
9151
legacyver/data/required_item_list_800.json
Normal file
File diff suppressed because it is too large
Load Diff
42
legacyver/legacypacket/biome_definition_list.go
Normal file
42
legacyver/legacypacket/biome_definition_list.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package legacypacket
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"github.com/akmalfairuz/legacy-version/legacyver/proto"
|
||||
"github.com/samber/lo"
|
||||
"github.com/sandertv/gophertunnel/minecraft/protocol"
|
||||
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
|
||||
)
|
||||
|
||||
// BiomeDefinitionList is sent by the server to let the client know all biomes that are available and
|
||||
// implemented on the server side. When enabled, it also includes information for the client to
|
||||
// accurately recreate the server-side generation in vanilla worlds/servers for increased performance.
|
||||
type BiomeDefinitionList struct {
|
||||
// BiomeDefinitions is a list of biomes that are available on the server.
|
||||
BiomeDefinitions []protocol.BiomeDefinition
|
||||
// StringList is a makeshift dictionary implementation Mojang created to try and reduce the size of the
|
||||
// overall packet. It is a list of common strings that are used in the biome definitions, such as
|
||||
// biome names, float values or query expressions.
|
||||
StringList []string
|
||||
}
|
||||
|
||||
// ID ...
|
||||
func (*BiomeDefinitionList) ID() uint32 {
|
||||
return packet.IDBiomeDefinitionList
|
||||
}
|
||||
|
||||
func (pk *BiomeDefinitionList) Marshal(io protocol.IO) {
|
||||
if proto.IsProtoGTE(io, proto.ID800) {
|
||||
protocol.Slice(io, &pk.BiomeDefinitions)
|
||||
protocol.FuncSlice(io, &pk.StringList, io.String)
|
||||
} else {
|
||||
io.Bytes(lo.ToPtr(append([]byte(nil), rawOldSerializedBiomeDefinitionList...)))
|
||||
}
|
||||
}
|
||||
|
||||
var rawOldSerializedBiomeDefinitionList []byte
|
||||
|
||||
func init() {
|
||||
const s = `CgAKDWJhbWJvb19qdW5nbGUFCGRvd25mYWxsZmZmPwULdGVtcGVyYXR1cmUzM3M/AAoTYmFtYm9vX2p1bmdsZV9oaWxscwUIZG93bmZhbGxmZmY/BQt0ZW1wZXJhdHVyZTMzcz8ACgViZWFjaAUIZG93bmZhbGzNzMw+BQt0ZW1wZXJhdHVyZc3MTD8ACgxiaXJjaF9mb3Jlc3QFCGRvd25mYWxsmpkZPwULdGVtcGVyYXR1cmWamRk/AAoSYmlyY2hfZm9yZXN0X2hpbGxzBQhkb3duZmFsbJqZGT8FC3RlbXBlcmF0dXJlmpkZPwAKGmJpcmNoX2ZvcmVzdF9oaWxsc19tdXRhdGVkBQhkb3duZmFsbM3MTD8FC3RlbXBlcmF0dXJlMzMzPwAKFGJpcmNoX2ZvcmVzdF9tdXRhdGVkBQhkb3duZmFsbM3MTD8FC3RlbXBlcmF0dXJlMzMzPwAKCmNvbGRfYmVhY2gFCGRvd25mYWxsmpmZPgULdGVtcGVyYXR1cmXNzEw9AAoKY29sZF9vY2VhbgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAD8ACgpjb2xkX3RhaWdhBQhkb3duZmFsbM3MzD4FC3RlbXBlcmF0dXJlAAAAvwAKEGNvbGRfdGFpZ2FfaGlsbHMFCGRvd25mYWxszczMPgULdGVtcGVyYXR1cmUAAAC/AAoSY29sZF90YWlnYV9tdXRhdGVkBQhkb3duZmFsbM3MzD4FC3RlbXBlcmF0dXJlAAAAvwAKD2RlZXBfY29sZF9vY2VhbgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAD8AChFkZWVwX2Zyb3plbl9vY2VhbgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAAAAChNkZWVwX2x1a2V3YXJtX29jZWFuBQhkb3duZmFsbAAAAD8FC3RlbXBlcmF0dXJlAAAAPwAKCmRlZXBfb2NlYW4FCGRvd25mYWxsAAAAPwULdGVtcGVyYXR1cmUAAAA/AAoPZGVlcF93YXJtX29jZWFuBQhkb3duZmFsbAAAAD8FC3RlbXBlcmF0dXJlAAAAPwAKBmRlc2VydAUIZG93bmZhbGwAAAAABQt0ZW1wZXJhdHVyZQAAAEAACgxkZXNlcnRfaGlsbHMFCGRvd25mYWxsAAAAAAULdGVtcGVyYXR1cmUAAABAAAoOZGVzZXJ0X211dGF0ZWQFCGRvd25mYWxsAAAAAAULdGVtcGVyYXR1cmUAAABAAAoNZXh0cmVtZV9oaWxscwUIZG93bmZhbGyamZk+BQt0ZW1wZXJhdHVyZc3MTD4AChJleHRyZW1lX2hpbGxzX2VkZ2UFCGRvd25mYWxsmpmZPgULdGVtcGVyYXR1cmXNzEw+AAoVZXh0cmVtZV9oaWxsc19tdXRhdGVkBQhkb3duZmFsbJqZmT4FC3RlbXBlcmF0dXJlzcxMPgAKGGV4dHJlbWVfaGlsbHNfcGx1c190cmVlcwUIZG93bmZhbGyamZk+BQt0ZW1wZXJhdHVyZc3MTD4ACiBleHRyZW1lX2hpbGxzX3BsdXNfdHJlZXNfbXV0YXRlZAUIZG93bmZhbGyamZk+BQt0ZW1wZXJhdHVyZc3MTD4ACg1mbG93ZXJfZm9yZXN0BQhkb3duZmFsbM3MTD8FC3RlbXBlcmF0dXJlMzMzPwAKBmZvcmVzdAUIZG93bmZhbGzNzEw/BQt0ZW1wZXJhdHVyZTMzMz8ACgxmb3Jlc3RfaGlsbHMFCGRvd25mYWxszcxMPwULdGVtcGVyYXR1cmUzMzM/AAoMZnJvemVuX29jZWFuBQhkb3duZmFsbAAAAD8FC3RlbXBlcmF0dXJlAAAAAAAKDGZyb3plbl9yaXZlcgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAAAACgRoZWxsBQhkb3duZmFsbAAAAAAFC3RlbXBlcmF0dXJlAAAAQAAKDWljZV9tb3VudGFpbnMFCGRvd25mYWxsAAAAPwULdGVtcGVyYXR1cmUAAAAAAAoKaWNlX3BsYWlucwUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAAAAChFpY2VfcGxhaW5zX3NwaWtlcwUIZG93bmZhbGwAAIA/BQt0ZW1wZXJhdHVyZQAAAAAACgZqdW5nbGUFCGRvd25mYWxsZmZmPwULdGVtcGVyYXR1cmUzM3M/AAoLanVuZ2xlX2VkZ2UFCGRvd25mYWxszcxMPwULdGVtcGVyYXR1cmUzM3M/AAoTanVuZ2xlX2VkZ2VfbXV0YXRlZAUIZG93bmZhbGzNzEw/BQt0ZW1wZXJhdHVyZTMzcz8ACgxqdW5nbGVfaGlsbHMFCGRvd25mYWxsZmZmPwULdGVtcGVyYXR1cmUzM3M/AAoOanVuZ2xlX211dGF0ZWQFCGRvd25mYWxsZmZmPwULdGVtcGVyYXR1cmUzM3M/AAoTbGVnYWN5X2Zyb3plbl9vY2VhbgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAAAACg5sdWtld2FybV9vY2VhbgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAD8ACgptZWdhX3RhaWdhBQhkb3duZmFsbM3MTD8FC3RlbXBlcmF0dXJlmpmZPgAKEG1lZ2FfdGFpZ2FfaGlsbHMFCGRvd25mYWxszcxMPwULdGVtcGVyYXR1cmWamZk+AAoEbWVzYQUIZG93bmZhbGwAAAAABQt0ZW1wZXJhdHVyZQAAAEAACgptZXNhX2JyeWNlBQhkb3duZmFsbAAAAAAFC3RlbXBlcmF0dXJlAAAAQAAKDG1lc2FfcGxhdGVhdQUIZG93bmZhbGwAAAAABQt0ZW1wZXJhdHVyZQAAAEAAChRtZXNhX3BsYXRlYXVfbXV0YXRlZAUIZG93bmZhbGwAAAAABQt0ZW1wZXJhdHVyZQAAAEAAChJtZXNhX3BsYXRlYXVfc3RvbmUFCGRvd25mYWxsAAAAAAULdGVtcGVyYXR1cmUAAABAAAoabWVzYV9wbGF0ZWF1X3N0b25lX211dGF0ZWQFCGRvd25mYWxsAAAAAAULdGVtcGVyYXR1cmUAAABAAAoPbXVzaHJvb21faXNsYW5kBQhkb3duZmFsbAAAgD8FC3RlbXBlcmF0dXJlZmZmPwAKFW11c2hyb29tX2lzbGFuZF9zaG9yZQUIZG93bmZhbGwAAIA/BQt0ZW1wZXJhdHVyZWZmZj8ACgVvY2VhbgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAD8ACgZwbGFpbnMFCGRvd25mYWxszczMPgULdGVtcGVyYXR1cmXNzEw/AAobcmVkd29vZF90YWlnYV9oaWxsc19tdXRhdGVkBQhkb3duZmFsbM3MTD8FC3RlbXBlcmF0dXJlmpmZPgAKFXJlZHdvb2RfdGFpZ2FfbXV0YXRlZAUIZG93bmZhbGzNzEw/BQt0ZW1wZXJhdHVyZQAAgD4ACgVyaXZlcgUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZQAAAD8ACg1yb29mZWRfZm9yZXN0BQhkb3duZmFsbM3MTD8FC3RlbXBlcmF0dXJlMzMzPwAKFXJvb2ZlZF9mb3Jlc3RfbXV0YXRlZAUIZG93bmZhbGzNzEw/BQt0ZW1wZXJhdHVyZTMzMz8ACgdzYXZhbm5hBQhkb3duZmFsbAAAAAAFC3RlbXBlcmF0dXJlmpmZPwAKD3NhdmFubmFfbXV0YXRlZAUIZG93bmZhbGwAAAA/BQt0ZW1wZXJhdHVyZc3MjD8ACg9zYXZhbm5hX3BsYXRlYXUFCGRvd25mYWxsAAAAAAULdGVtcGVyYXR1cmUAAIA/AAoXc2F2YW5uYV9wbGF0ZWF1X211dGF0ZWQFCGRvd25mYWxsAAAAPwULdGVtcGVyYXR1cmUAAIA/AAoLc3RvbmVfYmVhY2gFCGRvd25mYWxsmpmZPgULdGVtcGVyYXR1cmXNzEw+AAoQc3VuZmxvd2VyX3BsYWlucwUIZG93bmZhbGzNzMw+BQt0ZW1wZXJhdHVyZc3MTD8ACglzd2FtcGxhbmQFCGRvd25mYWxsAAAAPwULdGVtcGVyYXR1cmXNzEw/AAoRc3dhbXBsYW5kX211dGF0ZWQFCGRvd25mYWxsAAAAPwULdGVtcGVyYXR1cmXNzEw/AAoFdGFpZ2EFCGRvd25mYWxszcxMPwULdGVtcGVyYXR1cmUAAIA+AAoLdGFpZ2FfaGlsbHMFCGRvd25mYWxszcxMPwULdGVtcGVyYXR1cmUAAIA+AAoNdGFpZ2FfbXV0YXRlZAUIZG93bmZhbGzNzEw/BQt0ZW1wZXJhdHVyZQAAgD4ACgd0aGVfZW5kBQhkb3duZmFsbAAAAD8FC3RlbXBlcmF0dXJlAAAAPwAKCndhcm1fb2NlYW4FCGRvd25mYWxsAAAAPwULdGVtcGVyYXR1cmUAAAA/AAA=`
|
||||
rawOldSerializedBiomeDefinitionList, _ = base64.StdEncoding.DecodeString(s)
|
||||
}
|
||||
49
legacyver/legacypacket/player_list.go
Normal file
49
legacyver/legacypacket/player_list.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package legacypacket
|
||||
|
||||
import (
|
||||
"github.com/akmalfairuz/legacy-version/legacyver/proto"
|
||||
"github.com/sandertv/gophertunnel/minecraft/protocol"
|
||||
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
|
||||
)
|
||||
|
||||
const (
|
||||
PlayerListActionAdd = iota
|
||||
PlayerListActionRemove
|
||||
)
|
||||
|
||||
// PlayerList is sent by the server to update the client-side player list in the in-game menu screen. It shows
|
||||
// the icon of each player if the correct XUID is written in the packet.
|
||||
// Sending the PlayerList packet is obligatory when sending an AddPlayer packet. The added player will not
|
||||
// show up to a client if it has not been added to the player list, because several properties of the player
|
||||
// are obtained from the player list, such as the skin.
|
||||
type PlayerList struct {
|
||||
// ActionType is the action to execute upon the player list. The entries that follow specify which entries
|
||||
// are added or removed from the player list.
|
||||
ActionType byte
|
||||
// Entries is a list of all player list entries that should be added/removed from the player list,
|
||||
// depending on the ActionType set.
|
||||
Entries []proto.PlayerListEntry
|
||||
}
|
||||
|
||||
// ID ...
|
||||
func (*PlayerList) ID() uint32 {
|
||||
return packet.IDPlayerList
|
||||
}
|
||||
|
||||
// Marshal ...
|
||||
func (pk *PlayerList) Marshal(io protocol.IO) {
|
||||
io.Uint8(&pk.ActionType)
|
||||
switch pk.ActionType {
|
||||
case PlayerListActionAdd:
|
||||
protocol.Slice(io, &pk.Entries)
|
||||
case PlayerListActionRemove:
|
||||
protocol.FuncIOSlice(io, &pk.Entries, proto.PlayerListRemoveEntry)
|
||||
default:
|
||||
io.UnknownEnumOption(pk.ActionType, "player list action type")
|
||||
}
|
||||
if pk.ActionType == PlayerListActionAdd {
|
||||
for i := 0; i < len(pk.Entries); i++ {
|
||||
io.Bool(&pk.Entries[i].Skin.Trusted)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,18 @@ type CameraPreset struct {
|
||||
AlignTargetAndCameraForward protocol.Optional[bool]
|
||||
// AimAssist defines the aim assist to use when using this preset.
|
||||
AimAssist protocol.Optional[protocol.CameraPresetAimAssist]
|
||||
// ControlScheme is the control scheme that the client should use in this camera. It is one of the following:
|
||||
// - ControlSchemeLockedPlayerRelativeStrafe is the default behaviour, this cannot be set when the client
|
||||
// is in a custom camera.
|
||||
// - ControlSchemeCameraRelative makes movement relative to the camera's transform, with the client's
|
||||
// rotation being relative to the client's movement.
|
||||
// - ControlSchemeCameraRelativeStrafe makes movement relative to the camera's transform, with the
|
||||
// client's rotation being locked.
|
||||
// - ControlSchemePlayerRelative makes movement relative to the player's transform, meaning holding
|
||||
// left/right will make the player turn in a circle.
|
||||
// - ControlSchemePlayerRelativeStrafe makes movement the same as the default behaviour, but can be
|
||||
// used in a custom camera.
|
||||
ControlScheme protocol.Optional[byte]
|
||||
}
|
||||
|
||||
func (x *CameraPreset) FromLatest(cp protocol.CameraPreset) CameraPreset {
|
||||
@@ -78,6 +90,7 @@ func (x *CameraPreset) FromLatest(cp protocol.CameraPreset) CameraPreset {
|
||||
x.PlayerEffects = cp.PlayerEffects
|
||||
x.AlignTargetAndCameraForward = cp.AlignTargetAndCameraForward
|
||||
x.AimAssist = cp.AimAssist
|
||||
x.ControlScheme = cp.ControlScheme
|
||||
return *x
|
||||
}
|
||||
|
||||
@@ -105,6 +118,7 @@ func (x *CameraPreset) ToLatest() protocol.CameraPreset {
|
||||
PlayerEffects: x.PlayerEffects,
|
||||
AlignTargetAndCameraForward: x.AlignTargetAndCameraForward,
|
||||
AimAssist: x.AimAssist,
|
||||
ControlScheme: x.ControlScheme,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,4 +160,7 @@ func (x *CameraPreset) Marshal(r protocol.IO) {
|
||||
if IsProtoGTE(r, ID766) {
|
||||
protocol.OptionalMarshaler(r, &x.AimAssist)
|
||||
}
|
||||
if IsProtoGTE(r, ID800) {
|
||||
protocol.OptionalFunc(r, &x.ControlScheme, r.Uint8)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package proto
|
||||
import "github.com/sandertv/gophertunnel/minecraft/protocol"
|
||||
|
||||
const (
|
||||
ID800 = 800 // v1.21.80
|
||||
ID786 = 786 // v1.21.70
|
||||
ID776 = 776 // v1.21.60
|
||||
ID766 = 766 // v1.21.50
|
||||
|
||||
97
legacyver/proto/player.go
Normal file
97
legacyver/proto/player.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package proto
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/sandertv/gophertunnel/minecraft/protocol"
|
||||
)
|
||||
|
||||
// PlayerListEntry is an entry found in the PlayerList packet. It represents a single player using the UUID
|
||||
// found in the entry, and contains several properties such as the skin.
|
||||
type PlayerListEntry struct {
|
||||
// UUID is the UUID of the player as sent in the Login packet when the client joined the server. It must
|
||||
// match this UUID exactly for the correct XBOX Live icon to show up in the list.
|
||||
UUID uuid.UUID
|
||||
// EntityUniqueID is the unique entity ID of the player. This ID typically stays consistent during the
|
||||
// lifetime of a world, but servers often send the runtime ID for this.
|
||||
EntityUniqueID int64
|
||||
// Username is the username that is shown in the player list of the player that obtains a PlayerList
|
||||
// packet with this entry. It does not have to be the same as the actual username of the player.
|
||||
Username string
|
||||
// XUID is the XBOX Live user ID of the player, which will remain consistent as long as the player is
|
||||
// logged in with the XBOX Live account.
|
||||
XUID string
|
||||
// PlatformChatID is an identifier only set for particular platforms when chatting (presumably only for
|
||||
// Nintendo Switch). It is otherwise an empty string, and is used to decide which players are able to
|
||||
// chat with each other.
|
||||
PlatformChatID string
|
||||
// BuildPlatform is the platform of the player as sent by that player in the Login packet.
|
||||
BuildPlatform int32
|
||||
// Skin is the skin of the player that should be added to the player list. Once sent here, it will not
|
||||
// have to be sent again.
|
||||
Skin protocol.Skin
|
||||
// Teacher is a Minecraft: Education Edition field. It specifies if the player to be added to the player
|
||||
// list is a teacher.
|
||||
Teacher bool
|
||||
// Host specifies if the player that is added to the player list is the host of the game.
|
||||
Host bool
|
||||
// SubClient specifies if the player that is added to the player list is a sub-client of another player.
|
||||
SubClient bool
|
||||
// PlayerColour is the colour of the player that is shown in UI elements, currently only used for the
|
||||
// player locator bar.
|
||||
PlayerColour int32
|
||||
}
|
||||
|
||||
// Marshal encodes/decodes a PlayerListEntry.
|
||||
func (x *PlayerListEntry) Marshal(r protocol.IO) {
|
||||
r.UUID(&x.UUID)
|
||||
r.Varint64(&x.EntityUniqueID)
|
||||
r.String(&x.Username)
|
||||
r.String(&x.XUID)
|
||||
r.String(&x.PlatformChatID)
|
||||
r.Int32(&x.BuildPlatform)
|
||||
protocol.Single(r, &x.Skin)
|
||||
r.Bool(&x.Teacher)
|
||||
r.Bool(&x.Host)
|
||||
r.Bool(&x.SubClient)
|
||||
if IsProtoGTE(r, ID800) {
|
||||
r.Int32(&x.PlayerColour)
|
||||
}
|
||||
}
|
||||
|
||||
// FromLatest ...
|
||||
func (x *PlayerListEntry) FromLatest(y protocol.PlayerListEntry) PlayerListEntry {
|
||||
x.UUID = y.UUID
|
||||
x.EntityUniqueID = y.EntityUniqueID
|
||||
x.Username = y.Username
|
||||
x.XUID = y.XUID
|
||||
x.PlatformChatID = y.PlatformChatID
|
||||
x.BuildPlatform = y.BuildPlatform
|
||||
x.Skin = y.Skin
|
||||
x.Teacher = y.Teacher
|
||||
x.Host = y.Host
|
||||
x.SubClient = y.SubClient
|
||||
x.PlayerColour = y.PlayerColour
|
||||
return *x
|
||||
}
|
||||
|
||||
// ToLatest ...
|
||||
func (x *PlayerListEntry) ToLatest() protocol.PlayerListEntry {
|
||||
return protocol.PlayerListEntry{
|
||||
UUID: x.UUID,
|
||||
EntityUniqueID: x.EntityUniqueID,
|
||||
Username: x.Username,
|
||||
XUID: x.XUID,
|
||||
PlatformChatID: x.PlatformChatID,
|
||||
BuildPlatform: x.BuildPlatform,
|
||||
Skin: x.Skin,
|
||||
Teacher: x.Teacher,
|
||||
Host: x.Host,
|
||||
SubClient: x.SubClient,
|
||||
PlayerColour: x.PlayerColour,
|
||||
}
|
||||
}
|
||||
|
||||
// PlayerListRemoveEntry encodes/decodes a PlayerListEntry for removal from the list.
|
||||
func PlayerListRemoveEntry(r protocol.IO, x *PlayerListEntry) {
|
||||
r.UUID(&x.UUID)
|
||||
}
|
||||
@@ -120,6 +120,10 @@ func convertPacketFunc(pid uint32, cur func() packet.Packet) func() packet.Packe
|
||||
return func() packet.Packet { return &legacypacket.UpdatePlayerGameType{} }
|
||||
case packet.IDSetActorMotion:
|
||||
return func() packet.Packet { return &legacypacket.SetActorMotion{} }
|
||||
case packet.IDBiomeDefinitionList:
|
||||
return func() packet.Packet { return &legacypacket.BiomeDefinitionList{} }
|
||||
case packet.IDPlayerList:
|
||||
return func() packet.Packet { return &legacypacket.PlayerList{} }
|
||||
default:
|
||||
return cur
|
||||
}
|
||||
@@ -708,6 +712,20 @@ func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) [
|
||||
Elements: pk.Elements,
|
||||
Visibility: pk.Visibility,
|
||||
}
|
||||
case *packet.BiomeDefinitionList:
|
||||
pks[pkIndex] = &legacypacket.BiomeDefinitionList{
|
||||
BiomeDefinitions: pk.BiomeDefinitions,
|
||||
StringList: pk.StringList,
|
||||
}
|
||||
case *packet.PlayerList:
|
||||
entries := make([]proto.PlayerListEntry, len(pk.Entries))
|
||||
for i, e := range pk.Entries {
|
||||
entries[i] = (&proto.PlayerListEntry{}).FromLatest(e)
|
||||
}
|
||||
pks[pkIndex] = &legacypacket.PlayerList{
|
||||
ActionType: pk.ActionType,
|
||||
Entries: entries,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1213,6 +1231,20 @@ func (p *Protocol) upgradePackets(pks []packet.Packet, conn *minecraft.Conn) []p
|
||||
Elements: pk.Elements,
|
||||
Visibility: pk.Visibility,
|
||||
}
|
||||
case *legacypacket.BiomeDefinitionList:
|
||||
pks[pkIndex] = &packet.BiomeDefinitionList{
|
||||
BiomeDefinitions: pk.BiomeDefinitions,
|
||||
StringList: pk.StringList,
|
||||
}
|
||||
case *legacypacket.PlayerList:
|
||||
entries := make([]protocol.PlayerListEntry, len(pk.Entries))
|
||||
for i, e := range pk.Entries {
|
||||
entries[i] = e.ToLatest()
|
||||
}
|
||||
pks[pkIndex] = &packet.PlayerList{
|
||||
ActionType: pk.ActionType,
|
||||
Entries: entries,
|
||||
}
|
||||
}
|
||||
}
|
||||
return pks
|
||||
|
||||
@@ -2,6 +2,8 @@ package legacyver
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/akmalfairuz/legacy-version/internal/chunk"
|
||||
"github.com/akmalfairuz/legacy-version/legacyver/proto"
|
||||
"github.com/akmalfairuz/legacy-version/mapping"
|
||||
)
|
||||
|
||||
@@ -18,6 +20,15 @@ var (
|
||||
//go:embed data/block_states_786.nbt
|
||||
blockStateData786 []byte
|
||||
|
||||
itemMappingLatest = mapping.NewItemMapping(requiredItemList786, ItemVersion786)
|
||||
blockMappingLatest = mapping.NewBlockMapping(blockStateData786)
|
||||
itemMapping786 = mapping.NewItemMapping(requiredItemList786, ItemVersion786)
|
||||
blockMapping786 = mapping.NewBlockMapping(blockStateData786)
|
||||
)
|
||||
|
||||
func New786() *Protocol {
|
||||
return &Protocol{
|
||||
ver: "1.21.70",
|
||||
id: proto.ID786,
|
||||
blockTranslator: NewBlockTranslator(blockMapping786, blockMappingLatest, chunk.NewNetworkPersistentEncoding(blockMapping786, BlockVersion786), chunk.NewBlockPaletteEncoding(blockMapping786, BlockVersion786), false),
|
||||
itemTranslator: NewItemTranslator(itemMapping786, itemMappingLatest, blockMapping786, blockMappingLatest),
|
||||
}
|
||||
}
|
||||
|
||||
23
legacyver/v800.go
Normal file
23
legacyver/v800.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package legacyver
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"github.com/akmalfairuz/legacy-version/mapping"
|
||||
)
|
||||
|
||||
const (
|
||||
// ItemVersion800 ...
|
||||
ItemVersion800 = 251
|
||||
// BlockVersion800 ...
|
||||
BlockVersion800 int32 = (1 << 24) | (21 << 16) | (80 << 8)
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed data/required_item_list_800.json
|
||||
requiredItemList800 []byte
|
||||
//go:embed data/block_states_800.nbt
|
||||
blockStateData800 []byte
|
||||
|
||||
itemMappingLatest = mapping.NewItemMapping(requiredItemList800, ItemVersion800)
|
||||
blockMappingLatest = mapping.NewBlockMapping(blockStateData800)
|
||||
)
|
||||
Reference in New Issue
Block a user