fix: possible packet issues

This commit is contained in:
2026-02-16 13:42:03 +08:00
parent d2bec53bb8
commit a885a7eec4
11 changed files with 542 additions and 433 deletions
+104 -104
View File
@@ -3602,110 +3602,6 @@ func (c WrittenBookPage) WriteTo(w io.Writer) (n int64, err error) {
return n, err return n, err
} }
// Int32VarIntArray a utility type for encoding/decoding packet.Int -> int32[packet.VarInt] slice.
type Int32VarIntArray []int32
func (a Int32VarIntArray) WriteTo(w io.Writer) (n int64, err error) {
size := len(a)
nn, err := packet.VarInt(size).WriteTo(w)
if err != nil {
return n, err
}
n += nn
for i := 0; i < size; i++ {
nn, err := packet.Int(a[i]).WriteTo(w)
n += nn
if err != nil {
return n, err
}
}
return n, nil
}
func (a *Int32VarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
var size packet.VarInt
nn, err := size.ReadFrom(r)
n += nn
if err != nil {
return n, err
}
if size < 0 {
return n, errors.New("array length less than zero")
}
if size > 32767 {
return n, errors.New("array length greater than 32767")
}
if cap(*a) >= int(size) {
*a = (*a)[:int(size)]
} else {
*a = make(Int32VarIntArray, int(size))
}
for i := 0; i < int(size); i++ {
nn, err = (*packet.Int)(&(*a)[i]).ReadFrom(r)
n += nn
if err != nil {
return n, err
}
}
return n, err
}
// Int32PrefixedArrayVarIntArray a utility type for encoding/decoding packet.Int -> int32[packet.VarInt] slice.
type Int32PrefixedArrayVarIntArray []int32
func (a Int32PrefixedArrayVarIntArray) WriteTo(w io.Writer) (n int64, err error) {
size := len(a)
nn, err := packet.VarInt(size).WriteTo(w)
if err != nil {
return n, err
}
n += nn
for i := 0; i < size; i++ {
nn, err := packet.Int(a[i]).WriteTo(w)
n += nn
if err != nil {
return n, err
}
}
return n, nil
}
func (a *Int32PrefixedArrayVarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
var size packet.VarInt
nn, err := size.ReadFrom(r)
n += nn
if err != nil {
return n, err
}
if size < 0 {
return n, errors.New("array length less than zero")
}
if size > 32767 {
return n, errors.New("array length greater than 32767")
}
if cap(*a) >= int(size) {
*a = (*a)[:int(size)]
} else {
*a = make(Int32PrefixedArrayVarIntArray, int(size))
}
for i := 0; i < int(size); i++ {
nn, err = (*packet.Int)(&(*a)[i]).ReadFrom(r)
n += nn
if err != nil {
return n, err
}
}
return n, err
}
// Float32VarIntArray a utility type for encoding/decoding packet.Float -> float32[packet.VarInt] slice. // Float32VarIntArray a utility type for encoding/decoding packet.Float -> float32[packet.VarInt] slice.
type Float32VarIntArray []float32 type Float32VarIntArray []float32
@@ -3913,3 +3809,107 @@ func (a *Int32VarIntVarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
return n, err return n, err
} }
// Int32VarIntArray a utility type for encoding/decoding packet.Int -> int32[packet.VarInt] slice.
type Int32VarIntArray []int32
func (a Int32VarIntArray) WriteTo(w io.Writer) (n int64, err error) {
size := len(a)
nn, err := packet.VarInt(size).WriteTo(w)
if err != nil {
return n, err
}
n += nn
for i := 0; i < size; i++ {
nn, err := packet.Int(a[i]).WriteTo(w)
n += nn
if err != nil {
return n, err
}
}
return n, nil
}
func (a *Int32VarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
var size packet.VarInt
nn, err := size.ReadFrom(r)
n += nn
if err != nil {
return n, err
}
if size < 0 {
return n, errors.New("array length less than zero")
}
if size > 32767 {
return n, errors.New("array length greater than 32767")
}
if cap(*a) >= int(size) {
*a = (*a)[:int(size)]
} else {
*a = make(Int32VarIntArray, int(size))
}
for i := 0; i < int(size); i++ {
nn, err = (*packet.Int)(&(*a)[i]).ReadFrom(r)
n += nn
if err != nil {
return n, err
}
}
return n, err
}
// Int32PrefixedArrayVarIntArray a utility type for encoding/decoding packet.Int -> int32[packet.VarInt] slice.
type Int32PrefixedArrayVarIntArray []int32
func (a Int32PrefixedArrayVarIntArray) WriteTo(w io.Writer) (n int64, err error) {
size := len(a)
nn, err := packet.VarInt(size).WriteTo(w)
if err != nil {
return n, err
}
n += nn
for i := 0; i < size; i++ {
nn, err := packet.Int(a[i]).WriteTo(w)
n += nn
if err != nil {
return n, err
}
}
return n, nil
}
func (a *Int32PrefixedArrayVarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
var size packet.VarInt
nn, err := size.ReadFrom(r)
n += nn
if err != nil {
return n, err
}
if size < 0 {
return n, errors.New("array length less than zero")
}
if size > 32767 {
return n, errors.New("array length greater than 32767")
}
if cap(*a) >= int(size) {
*a = (*a)[:int(size)]
} else {
*a = make(Int32PrefixedArrayVarIntArray, int(size))
}
for i := 0; i < int(size); i++ {
nn, err = (*packet.Int)(&(*a)[i]).ReadFrom(r)
n += nn
if err != nil {
return n, err
}
}
return n, err
}
@@ -17,3 +17,11 @@ var packetRegistry = make(map[packetid.ServerboundPacketID]serverPacketCreator)
func registerPacket(id packetid.ServerboundPacketID, creator serverPacketCreator) { func registerPacket(id packetid.ServerboundPacketID, creator serverPacketCreator) {
packetRegistry[id] = creator packetRegistry[id] = creator
} }
func CreatePacket(id packetid.ServerboundPacketID) (ServerboundPacket, bool) {
creator, ok := packetRegistry[id]
if !ok {
return nil, false
}
return creator(), true
}
+210 -210
View File
@@ -2047,7 +2047,7 @@ func (c CommonPlayerSpawnInfo) WriteTo(w io.Writer) (n int64, err error) {
} }
func (c *Login) ReadFrom(r io.Reader) (n int64, err error) { func (c *Login) ReadFrom(r io.Reader) (n int64, err error) {
var temp int64 var temp int64
temp, err = (*packet.VarInt)(&c.PlayerID).ReadFrom(r) temp, err = (*packet.Int)(&c.PlayerID).ReadFrom(r)
n += temp n += temp
if err != nil { if err != nil {
return n, err return n, err
@@ -2107,7 +2107,7 @@ func (c *Login) ReadFrom(r io.Reader) (n int64, err error) {
func (c Login) WriteTo(w io.Writer) (n int64, err error) { func (c Login) WriteTo(w io.Writer) (n int64, err error) {
var temp int64 var temp int64
temp, err = (*packet.VarInt)(&c.PlayerID).WriteTo(w) temp, err = (*packet.Int)(&c.PlayerID).WriteTo(w)
n += temp n += temp
if err != nil { if err != nil {
return n, err return n, err
@@ -7067,58 +7067,6 @@ func (c Waypoint) WriteTo(w io.Writer) (n int64, err error) {
return n, err return n, err
} }
// Int8VarIntArray a utility type for encoding/decoding packet.Byte -> int8[packet.VarInt] slice.
type Int8VarIntArray []int8
func (a Int8VarIntArray) WriteTo(w io.Writer) (n int64, err error) {
size := len(a)
nn, err := packet.VarInt(size).WriteTo(w)
if err != nil {
return n, err
}
n += nn
for i := 0; i < size; i++ {
nn, err := packet.Byte(a[i]).WriteTo(w)
n += nn
if err != nil {
return n, err
}
}
return n, nil
}
func (a *Int8VarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
var size packet.VarInt
nn, err := size.ReadFrom(r)
n += nn
if err != nil {
return n, err
}
if size < 0 {
return n, errors.New("array length less than zero")
}
if size > 32767 {
return n, errors.New("array length greater than 32767")
}
if cap(*a) >= int(size) {
*a = (*a)[:int(size)]
} else {
*a = make(Int8VarIntArray, int(size))
}
for i := 0; i < int(size); i++ {
nn, err = (*packet.Byte)(&(*a)[i]).ReadFrom(r)
n += nn
if err != nil {
return n, err
}
}
return n, err
}
// StringVarIntArray a utility type for encoding/decoding packet.String -> string[packet.VarInt] slice. // StringVarIntArray a utility type for encoding/decoding packet.String -> string[packet.VarInt] slice.
type StringVarIntArray []string type StringVarIntArray []string
@@ -7171,110 +7119,6 @@ func (a *StringVarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
return n, err return n, err
} }
// StringIdentifierVarIntArray a utility type for encoding/decoding packet.Identifier -> string[packet.VarInt] slice.
type StringIdentifierVarIntArray []string
func (a StringIdentifierVarIntArray) WriteTo(w io.Writer) (n int64, err error) {
size := len(a)
nn, err := packet.VarInt(size).WriteTo(w)
if err != nil {
return n, err
}
n += nn
for i := 0; i < size; i++ {
nn, err := packet.Identifier(a[i]).WriteTo(w)
n += nn
if err != nil {
return n, err
}
}
return n, nil
}
func (a *StringIdentifierVarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
var size packet.VarInt
nn, err := size.ReadFrom(r)
n += nn
if err != nil {
return n, err
}
if size < 0 {
return n, errors.New("array length less than zero")
}
if size > 32767 {
return n, errors.New("array length greater than 32767")
}
if cap(*a) >= int(size) {
*a = (*a)[:int(size)]
} else {
*a = make(StringIdentifierVarIntArray, int(size))
}
for i := 0; i < int(size); i++ {
nn, err = (*packet.Identifier)(&(*a)[i]).ReadFrom(r)
n += nn
if err != nil {
return n, err
}
}
return n, err
}
// UuidUUIDUUIDVarIntArray a utility type for encoding/decoding packet.UUID -> uuid.UUID[packet.VarInt] slice.
type UuidUUIDUUIDVarIntArray []uuid.UUID
func (a UuidUUIDUUIDVarIntArray) WriteTo(w io.Writer) (n int64, err error) {
size := len(a)
nn, err := packet.VarInt(size).WriteTo(w)
if err != nil {
return n, err
}
n += nn
for i := 0; i < size; i++ {
nn, err := packet.UUID(a[i]).WriteTo(w)
n += nn
if err != nil {
return n, err
}
}
return n, nil
}
func (a *UuidUUIDUUIDVarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
var size packet.VarInt
nn, err := size.ReadFrom(r)
n += nn
if err != nil {
return n, err
}
if size < 0 {
return n, errors.New("array length less than zero")
}
if size > 32767 {
return n, errors.New("array length greater than 32767")
}
if cap(*a) >= int(size) {
*a = (*a)[:int(size)]
} else {
*a = make(UuidUUIDUUIDVarIntArray, int(size))
}
for i := 0; i < int(size); i++ {
nn, err = (*packet.UUID)(&(*a)[i]).ReadFrom(r)
n += nn
if err != nil {
return n, err
}
}
return n, err
}
// Int32VarIntVarIntArray a utility type for encoding/decoding packet.VarInt -> int32[packet.VarInt] slice. // Int32VarIntVarIntArray a utility type for encoding/decoding packet.VarInt -> int32[packet.VarInt] slice.
type Int32VarIntVarIntArray []int32 type Int32VarIntVarIntArray []int32
@@ -7379,6 +7223,214 @@ func (a *Int64VarLongVarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
return n, err return n, err
} }
// Int8VarIntArray a utility type for encoding/decoding packet.Byte -> int8[packet.VarInt] slice.
type Int8VarIntArray []int8
func (a Int8VarIntArray) WriteTo(w io.Writer) (n int64, err error) {
size := len(a)
nn, err := packet.VarInt(size).WriteTo(w)
if err != nil {
return n, err
}
n += nn
for i := 0; i < size; i++ {
nn, err := packet.Byte(a[i]).WriteTo(w)
n += nn
if err != nil {
return n, err
}
}
return n, nil
}
func (a *Int8VarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
var size packet.VarInt
nn, err := size.ReadFrom(r)
n += nn
if err != nil {
return n, err
}
if size < 0 {
return n, errors.New("array length less than zero")
}
if size > 32767 {
return n, errors.New("array length greater than 32767")
}
if cap(*a) >= int(size) {
*a = (*a)[:int(size)]
} else {
*a = make(Int8VarIntArray, int(size))
}
for i := 0; i < int(size); i++ {
nn, err = (*packet.Byte)(&(*a)[i]).ReadFrom(r)
n += nn
if err != nil {
return n, err
}
}
return n, err
}
// Int64VarIntArray a utility type for encoding/decoding packet.Long -> int64[packet.VarInt] slice.
type Int64VarIntArray []int64
func (a Int64VarIntArray) WriteTo(w io.Writer) (n int64, err error) {
size := len(a)
nn, err := packet.VarInt(size).WriteTo(w)
if err != nil {
return n, err
}
n += nn
for i := 0; i < size; i++ {
nn, err := packet.Long(a[i]).WriteTo(w)
n += nn
if err != nil {
return n, err
}
}
return n, nil
}
func (a *Int64VarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
var size packet.VarInt
nn, err := size.ReadFrom(r)
n += nn
if err != nil {
return n, err
}
if size < 0 {
return n, errors.New("array length less than zero")
}
if size > 32767 {
return n, errors.New("array length greater than 32767")
}
if cap(*a) >= int(size) {
*a = (*a)[:int(size)]
} else {
*a = make(Int64VarIntArray, int(size))
}
for i := 0; i < int(size); i++ {
nn, err = (*packet.Long)(&(*a)[i]).ReadFrom(r)
n += nn
if err != nil {
return n, err
}
}
return n, err
}
// StringIdentifierVarIntArray a utility type for encoding/decoding packet.Identifier -> string[packet.VarInt] slice.
type StringIdentifierVarIntArray []string
func (a StringIdentifierVarIntArray) WriteTo(w io.Writer) (n int64, err error) {
size := len(a)
nn, err := packet.VarInt(size).WriteTo(w)
if err != nil {
return n, err
}
n += nn
for i := 0; i < size; i++ {
nn, err := packet.Identifier(a[i]).WriteTo(w)
n += nn
if err != nil {
return n, err
}
}
return n, nil
}
func (a *StringIdentifierVarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
var size packet.VarInt
nn, err := size.ReadFrom(r)
n += nn
if err != nil {
return n, err
}
if size < 0 {
return n, errors.New("array length less than zero")
}
if size > 32767 {
return n, errors.New("array length greater than 32767")
}
if cap(*a) >= int(size) {
*a = (*a)[:int(size)]
} else {
*a = make(StringIdentifierVarIntArray, int(size))
}
for i := 0; i < int(size); i++ {
nn, err = (*packet.Identifier)(&(*a)[i]).ReadFrom(r)
n += nn
if err != nil {
return n, err
}
}
return n, err
}
// UuidUUIDUUIDVarIntArray a utility type for encoding/decoding packet.UUID -> uuid.UUID[packet.VarInt] slice.
type UuidUUIDUUIDVarIntArray []uuid.UUID
func (a UuidUUIDUUIDVarIntArray) WriteTo(w io.Writer) (n int64, err error) {
size := len(a)
nn, err := packet.VarInt(size).WriteTo(w)
if err != nil {
return n, err
}
n += nn
for i := 0; i < size; i++ {
nn, err := packet.UUID(a[i]).WriteTo(w)
n += nn
if err != nil {
return n, err
}
}
return n, nil
}
func (a *UuidUUIDUUIDVarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
var size packet.VarInt
nn, err := size.ReadFrom(r)
n += nn
if err != nil {
return n, err
}
if size < 0 {
return n, errors.New("array length less than zero")
}
if size > 32767 {
return n, errors.New("array length greater than 32767")
}
if cap(*a) >= int(size) {
*a = (*a)[:int(size)]
} else {
*a = make(UuidUUIDUUIDVarIntArray, int(size))
}
for i := 0; i < int(size); i++ {
nn, err = (*packet.UUID)(&(*a)[i]).ReadFrom(r)
n += nn
if err != nil {
return n, err
}
}
return n, err
}
// Int8ByteVarIntArray a utility type for encoding/decoding packet.Byte -> int8[packet.VarInt] slice. // Int8ByteVarIntArray a utility type for encoding/decoding packet.Byte -> int8[packet.VarInt] slice.
type Int8ByteVarIntArray []int8 type Int8ByteVarIntArray []int8
@@ -7482,55 +7534,3 @@ func (a *StringStringVarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
return n, err return n, err
} }
// Int64VarIntArray a utility type for encoding/decoding packet.Long -> int64[packet.VarInt] slice.
type Int64VarIntArray []int64
func (a Int64VarIntArray) WriteTo(w io.Writer) (n int64, err error) {
size := len(a)
nn, err := packet.VarInt(size).WriteTo(w)
if err != nil {
return n, err
}
n += nn
for i := 0; i < size; i++ {
nn, err := packet.Long(a[i]).WriteTo(w)
n += nn
if err != nil {
return n, err
}
}
return n, nil
}
func (a *Int64VarIntArray) ReadFrom(r io.Reader) (n int64, err error) {
var size packet.VarInt
nn, err := size.ReadFrom(r)
n += nn
if err != nil {
return n, err
}
if size < 0 {
return n, errors.New("array length less than zero")
}
if size > 32767 {
return n, errors.New("array length greater than 32767")
}
if cap(*a) >= int(size) {
*a = (*a)[:int(size)]
} else {
*a = make(Int64VarIntArray, int(size))
}
for i := 0; i < int(size); i++ {
nn, err = (*packet.Long)(&(*a)[i]).ReadFrom(r)
n += nn
if err != nil {
return n, err
}
}
return n, err
}
+1 -1
View File
@@ -29,7 +29,7 @@ type CommonPlayerSpawnInfo struct {
//codec:gen //codec:gen
type Login struct { type Login struct {
PlayerID int32 `mc:"VarInt"` PlayerID int32
Hardcore bool Hardcore bool
Levels []string `mc:"Identifier"` Levels []string `mc:"Identifier"`
MaxPlayers int32 `mc:"VarInt"` MaxPlayers int32 `mc:"VarInt"`
@@ -1,7 +1,9 @@
package client package client
import ( import (
"fmt"
"io" "io"
"sort"
"github.com/google/uuid" "github.com/google/uuid"
@@ -21,121 +23,95 @@ type PlayerInfoUpdate struct {
} }
func (p PlayerInfoUpdate) WriteTo(w io.Writer) (n int64, err error) { func (p PlayerInfoUpdate) WriteTo(w io.Writer) (n int64, err error) {
//bitset := pk.NewFixedBitSet(8) actions, err := collectPlayerInfoActions(p.Players)
//for _, infos := range p.Players { if err != nil {
// for _, info := range infos { return 0, err
// bitset.Set(info.playerInfoBitMask(), true) }
// }
//} bitset := pk.NewFixedBitSet(8)
//n1, err := bitset.WriteTo(w) for _, action := range actions {
//if err != nil { bitset.Set(actionIndex(action), true)
// return n1, err }
//} n1, err := bitset.WriteTo(w)
//n += n1 if err != nil {
//n2, err := pk.VarInt(len(p.Players)).WriteTo(w) return n1, err
//if err != nil { }
// return n1 + n2, err n += n1
//} n2, err := pk.VarInt(len(p.Players)).WriteTo(w)
//n += n2 if err != nil {
//for playerUUID, infos := range p.Players { return n1 + n2, err
// n3, err := (*pk.UUID)(&playerUUID).WriteTo(w) }
// if err != nil { n += n2
// return n1 + n2 + n3, err for playerUUID, infos := range p.Players {
// } n3, err := (*pk.UUID)(&playerUUID).WriteTo(w)
// n += n3 if err != nil {
// for _, info := range infos { return n1 + n2 + n3, err
// n4, err := info.WriteTo(w) }
// if err != nil { n += n3
// return n1 + n2 + n3 + n4, err
// } infosByAction, err := indexPlayerInfos(infos)
// n += n4 if err != nil {
// } return n, err
//} }
return 0, nil
for _, action := range actions {
info, ok := infosByAction[action]
if !ok {
return n, fmt.Errorf("player %s missing player info action mask %#02x", playerUUID.String(), action)
}
n4, err := info.WriteTo(w)
if err != nil {
return n1 + n2 + n3 + n4, err
}
n += n4
}
}
return n, nil
} }
func (p *PlayerInfoUpdate) ReadFrom(r io.Reader) (n int64, err error) { func (p *PlayerInfoUpdate) ReadFrom(r io.Reader) (n int64, err error) {
//bitset := pk.NewFixedBitSet(256) bitset := pk.NewFixedBitSet(8)
//n1, err := bitset.ReadFrom(r) n1, err := bitset.ReadFrom(r)
//if err != nil { if err != nil {
// return n1, err return n1, err
//} }
//m := make(map[uuid.UUID][]PlayerInfo) n += n1
//
//var playerLens pk.VarInt actions := actionsFromBitSet(bitset)
//n2, err := playerLens.ReadFrom(r)
//if err != nil { var playerCount pk.VarInt
// return n1 + n2, err n2, err := playerCount.ReadFrom(r)
//} if err != nil {
//for i := 0; i < int(playerLens); i++ { return n + n2, err
// var playerUUID uuid.UUID }
// n3, err := (*pk.UUID)(&playerUUID).ReadFrom(r) n += n2
// if err != nil {
// return n1 + n2 + n3, err players := make(map[uuid.UUID][]PlayerInfo, int(playerCount))
// } for i := 0; i < int(playerCount); i++ {
// var temp int64 var playerUUID uuid.UUID
// var infos []PlayerInfo n3, err := (*pk.UUID)(&playerUUID).ReadFrom(r)
// if bitset.Get(0x01) { if err != nil {
// n4, err := playerInfoRead(&infos, &PlayerInfoAddPlayer{}, r) return n + n3, err
// if err != nil { }
// return n1 + n2 + n3 + n4, err n += n3
// }
// temp += n4 infos := make([]PlayerInfo, 0, len(actions))
// } for _, action := range actions {
// if bitset.Get(0x02) { info := newPlayerInfoByAction(action)
// n4, err := playerInfoRead(&infos, &PlayerInfoInitializeChat{}, r) if info == nil {
// if err != nil { return n, fmt.Errorf("unsupported player info action mask %#02x", action)
// return n1 + n2 + n3 + n4, err }
// } n4, err := playerInfoRead(&infos, info, r)
// temp += n4 if err != nil {
// } return n + n4, err
// if bitset.Get(0x04) { }
// n4, err := playerInfoRead(&infos, &PlayerInfoUpdateGameMode{}, r) n += n4
// if err != nil { }
// return n1 + n2 + n3 + n4, err players[playerUUID] = infos
// } }
// temp += n4
// } p.Players = players
// if bitset.Get(0x08) { return n, nil
// n4, err := playerInfoRead(&infos, &PlayerInfoUpdateListed{}, r)
// if err != nil {
// return n1 + n2 + n3 + n4, err
// }
// temp += n4
// }
// if bitset.Get(0x10) {
// n4, err := playerInfoRead(&infos, &PlayerInfoUpdateLatency{}, r)
// if err != nil {
// return n1 + n2 + n3 + n4, err
// }
// temp += n4
// }
// if bitset.Get(0x20) {
// n4, err := playerInfoRead(&infos, &PlayerInfoUpdateDisplayName{}, r)
// if err != nil {
// return n1 + n2 + n3 + n4, err
// }
// temp += n4
// }
// if bitset.Get(0x40) {
// n4, err := playerInfoRead(&infos, &PlayerInfoUpdateListPriority{}, r)
// if err != nil {
// return n1 + n2 + n3 + n4, err
// }
// temp += n4
// }
// if bitset.Get(0x80) {
// n4, err := playerInfoRead(&infos, &PlayerInfoUpdateHat{}, r)
// if err != nil {
// return n1 + n2 + n3 + n4, err
// }
// temp += n4
// }
//
// m[playerUUID] = infos
//}
//return
return 0, nil
} }
func playerInfoRead(infos *[]PlayerInfo, info PlayerInfo, r io.Reader) (int64, error) { func playerInfoRead(infos *[]PlayerInfo, info PlayerInfo, r io.Reader) (int64, error) {
@@ -147,6 +123,103 @@ func playerInfoRead(infos *[]PlayerInfo, info PlayerInfo, r io.Reader) (int64, e
return n, err return n, err
} }
func collectPlayerInfoActions(players map[uuid.UUID][]PlayerInfo) ([]int, error) {
actions := make(map[int]struct{}, 8)
for playerID, infos := range players {
seen := make(map[int]struct{}, len(infos))
for _, info := range infos {
mask := info.playerInfoBitMask()
if err := validatePlayerInfoActionMask(mask); err != nil {
return nil, fmt.Errorf("player %s has invalid action: %w", playerID.String(), err)
}
if _, exists := seen[mask]; exists {
return nil, fmt.Errorf("player %s has duplicated action mask %#02x", playerID.String(), mask)
}
seen[mask] = struct{}{}
actions[mask] = struct{}{}
}
}
sorted := make([]int, 0, len(actions))
for mask := range actions {
sorted = append(sorted, mask)
}
sort.Ints(sorted)
return sorted, nil
}
func indexPlayerInfos(infos []PlayerInfo) (map[int]PlayerInfo, error) {
indexed := make(map[int]PlayerInfo, len(infos))
for _, info := range infos {
mask := info.playerInfoBitMask()
if err := validatePlayerInfoActionMask(mask); err != nil {
return nil, err
}
if _, exists := indexed[mask]; exists {
return nil, fmt.Errorf("duplicated player info action mask %#02x", mask)
}
indexed[mask] = info
}
return indexed, nil
}
func validatePlayerInfoActionMask(mask int) error {
if mask <= 0 || mask > 0x80 {
return fmt.Errorf("action mask out of range: %#02x", mask)
}
// Action mask is an enum bit. It must have exactly one bit set.
if mask&(mask-1) != 0 {
return fmt.Errorf("action mask must be a single bit: %#02x", mask)
}
return nil
}
func actionIndex(mask int) int {
index := 0
for (mask & 0x01) == 0 {
index++
mask >>= 1
}
return index
}
func actionsFromBitSet(bitset pk.FixedBitSet) []int {
actions := make([]int, 0, len(playerInfoActionMasks))
for _, mask := range playerInfoActionMasks {
if bitset.Get(actionIndex(mask)) {
actions = append(actions, mask)
}
}
return actions
}
func newPlayerInfoByAction(mask int) PlayerInfo {
switch mask {
case 0x01:
return &PlayerInfoAddPlayer{}
case 0x02:
return &PlayerInfoInitializeChat{}
case 0x04:
return &PlayerInfoUpdateGameMode{}
case 0x08:
return &PlayerInfoUpdateListed{}
case 0x10:
return &PlayerInfoUpdateLatency{}
case 0x20:
return &PlayerInfoUpdateDisplayName{}
case 0x40:
return &PlayerInfoUpdateListPriority{}
case 0x80:
return &PlayerInfoUpdateHat{}
default:
return nil
}
}
var playerInfoActionMasks = [...]int{
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
}
//codec:gen //codec:gen
type PlayerInfoAddPlayer struct { type PlayerInfoAddPlayer struct {
Name string Name string
@@ -18,3 +18,11 @@ var packetRegistry = make(map[packetid.ServerboundPacketID]serverPacketCreator)
func registerPacket(id packetid.ServerboundPacketID, creator serverPacketCreator) { func registerPacket(id packetid.ServerboundPacketID, creator serverPacketCreator) {
packetRegistry[id] = creator packetRegistry[id] = creator
} }
func CreatePacket(id packetid.ServerboundPacketID) (ServerboundPacket, bool) {
creator, ok := packetRegistry[id]
if !ok {
return nil, false
}
return creator(), true
}
+14 -2
View File
@@ -154,9 +154,21 @@ func (c LoginLoginDisconnect) WriteTo(w io.Writer) (n int64, err error) {
return n, err return n, err
} }
func (c *LoginLoginFinished) ReadFrom(r io.Reader) (n int64, err error) { func (c *LoginLoginFinished) ReadFrom(r io.Reader) (n int64, err error) {
return 0, nil var temp int64
temp, err = (&c.GameProfile).ReadFrom(r)
n += temp
if err != nil {
return n, err
}
return n, err
} }
func (c LoginLoginFinished) WriteTo(w io.Writer) (n int64, err error) { func (c LoginLoginFinished) WriteTo(w io.Writer) (n int64, err error) {
return 0, nil var temp int64
temp, err = (&c.GameProfile).WriteTo(w)
n += temp
if err != nil {
return n, err
}
return n, err
} }
@@ -7,7 +7,7 @@ import (
//codec:gen //codec:gen
type LoginLoginFinished struct { type LoginLoginFinished struct {
protocol.GameProfile GameProfile protocol.GameProfile
} }
func (*LoginLoginFinished) PacketID() packetid.ClientboundPacketID { func (*LoginLoginFinished) PacketID() packetid.ClientboundPacketID {
+2 -2
View File
@@ -64,7 +64,7 @@ func (c *LoginCustomQueryAnswer) ReadFrom(r io.Reader) (n int64, err error) {
return n, err return n, err
} }
if c.HasData { if c.HasData {
temp, err = (*packet.ByteArray)(&c.Data).ReadFrom(r) temp, err = (*packet.PluginMessageData)(&c.Data).ReadFrom(r)
n += temp n += temp
if err != nil { if err != nil {
return n, err return n, err
@@ -86,7 +86,7 @@ func (c LoginCustomQueryAnswer) WriteTo(w io.Writer) (n int64, err error) {
return n, err return n, err
} }
if c.HasData { if c.HasData {
temp, err = (*packet.ByteArray)(&c.Data).WriteTo(w) temp, err = (*packet.PluginMessageData)(&c.Data).WriteTo(w)
n += temp n += temp
if err != nil { if err != nil {
return n, err return n, err
@@ -7,7 +7,7 @@ type LoginCustomQueryAnswer struct {
MessageID int32 `mc:"VarInt"` MessageID int32 `mc:"VarInt"`
HasData bool HasData bool
//opt:optional:HasData //opt:optional:HasData
Data []byte `mc:"ByteArray"` Data []byte `mc:"PluginMessageData"`
} }
func (*LoginCustomQueryAnswer) PacketID() packetid.ServerboundPacketID { func (*LoginCustomQueryAnswer) PacketID() packetid.ServerboundPacketID {
@@ -17,3 +17,11 @@ var packetRegistry = make(map[packetid.ServerboundPacketID]serverPacketCreator)
func registerPacket(id packetid.ServerboundPacketID, creator serverPacketCreator) { func registerPacket(id packetid.ServerboundPacketID, creator serverPacketCreator) {
packetRegistry[id] = creator packetRegistry[id] = creator
} }
func CreatePacket(id packetid.ServerboundPacketID) (ServerboundPacket, bool) {
creator, ok := packetRegistry[id]
if !ok {
return nil, false
}
return creator(), true
}