Documentation ¶
Index ¶
- Constants
- type Angle
- type Ary
- type BitSet
- type Boolean
- type Builder
- type Byte
- type ByteArray
- type Chat
- type Double
- type Field
- type FieldDecoder
- type FieldEncoder
- type FixedBitSet
- type Float
- type Identifier
- type Int
- type Long
- type NbtField
- type Optional
- type Packet
- type PluginMessageData
- type Position
- type Property
- type Short
- type String
- type Tuple
- type UUID
- type UnsignedByte
- type UnsignedShort
- type VarInt
- type VarLong
Examples ¶
Constants ¶
const MaxDataLength = 2097152
const MaxVarIntLen = 5
const MaxVarLongLen = 10
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Ary ¶
type Ary[T VarInt | VarLong | Byte | UnsignedByte | Short | UnsignedShort | Int | Long] struct { Ary interface{} // Slice or Pointer of Slice of FieldEncoder, FieldDecoder or both (Field) }
Ary is used to send or receive the packet field like "Array of X" which has a count must be known from the context.
Typically, you must decode an integer representing the length. Then receive the corresponding amount of data according to the length. In this case, the field Len should be a pointer of integer type so the value can be updating when Packet.Scan() method is decoding the previous field. In some special cases, you might want to read an "Array of X" with a fix length. So it's allowed to directly set an integer type Len, but not a pointer.
Note that Ary DO read or write the Len. You aren't need to do so by your self.
func (Ary[T]) ReadFrom ¶
Example ¶
package main import ( pk "github.com/Edouard127/go-mc/net/packet" ) func main() { var data []pk.String var p pk.Packet // = conn.ReadPacket() if err := p.Scan( pk.Ary[pk.VarInt]{ // then decode Ary according to length Ary: &data, }, ); err != nil { panic(err) } }
Output:
func (Ary[T]) WriteTo ¶
Example ¶
package main import ( pk "github.com/Edouard127/go-mc/net/packet" ) func main() { data := []pk.Int{0, 1, 2, 3, 4, 5, 6} // Len is completely ignored by WriteTo method. // The length is inferred from the length of Ary. pk.Marshal( 0x00, pk.Ary[pk.VarInt]{ Ary: data, }, ) }
Output:
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
func (*Builder) WriteField ¶
func (p *Builder) WriteField(fields ...FieldEncoder)
type Chat ¶
type Chat = String
Chat is encoded as a String with max length of 32767. Deprecated: Use chat.Message
type Double ¶
type Double float64
A Double is a double-precision 64-bit IEEE 754 floating point number
type Field ¶
type Field interface { FieldEncoder FieldDecoder }
A Field is both FieldEncoder and FieldDecoder
type FieldDecoder ¶
type FieldDecoder io.ReaderFrom
A FieldDecoder can Decode from minecraft protocol
type FieldEncoder ¶
A FieldEncoder can be encoded as minecraft protocol used.
type FixedBitSet ¶
type FixedBitSet []byte
FixedBitSet is a fixed size BitSet
func NewFixedBitSet ¶
func NewFixedBitSet(n int64) FixedBitSet
NewFixedBitSet make a FixedBitSet which can store n bits at least. If n <= 0, return nil
func (FixedBitSet) Get ¶
func (f FixedBitSet) Get(index int) bool
func (FixedBitSet) Set ¶
func (f FixedBitSet) Set(index int, value bool)
type Identifier ¶
type Identifier = String
Identifier is encoded as a String with max length of 32767.
type Optional ¶
type Optional[T FieldEncoder, P fieldPointer[T]] struct { Has any // Pointer of bool, or `func() bool` Value T }
Optional is used to send or receive the packet field like "Optional X" which has a bool must be known from the context. It is only used for buffer writing/reader. Not for code logic.
Typically, you must decode a boolean representing the existence of the field. Then receive the corresponding amount of data according to the boolean. In this case, the field Has should be a pointer of bool type so the value can be updating when Packet.Scan() method is decoding the previous field. In some special cases, you might want to read an "Optional X" with a fix length. So it's allowed to directly set a bool type Has, but not a pointer.
Note that Optional DO read or write the Has. You aren't need to do so by your self. But if you do, you might get undefined behavior.
func (Optional[T, P]) ReadFrom ¶
Example ¶
package main import ( pk "github.com/Edouard127/go-mc/net/packet" ) func main() { var str pk.String p1 := pk.Packet{Data: []byte{ 0x01, // pk.Boolean(true) 4, 'T', 'n', 'z', 'e', // pk.String }} var data = pk.Optional[pk.String, *pk.String, *pk.Boolean]{Value: str} if err := p1.Scan(data); err != nil { panic(err) } var data2 pk.String = "WILL NOT BE READ, WILL NOT BE COVERED" p2 := pk.Packet{Data: []byte{ 0x00, // pk.Boolean(false) // empty }} if err := p2.Scan(pk.Optional[pk.String, *pk.String, *pk.Boolean]{Value: data2}); err != nil { panic(err) } // Tnze // WILL NOT BE READ, WILL NOT BE COVERED }
Output:
Example (Func) ¶
package main import ( "fmt" pk "github.com/Edouard127/go-mc/net/packet" ) func main() { // As an example, we define this packet as this: // +------+-----------------+----------------------------------+ // | Name | Type | Notes | // +------+-----------------+----------------------------------+ // | Flag | Unsigned Byte | Odd if the following is present. | // +------+-----------------+----------------------------------+ // | User | Optional String | The player's name. | // +------+-----------------+----------------------------------+ // So we need a function to decide if the User field is present. var data pk.String p := pk.Packet{Data: []byte{ 0b_0010_0011, // pk.Byte(flag) 4, 'T', 'n', 'z', 'e', // pk.String }} if err := p.Scan(pk.Optional[pk.String, *pk.String, *pk.Byte]{ Value: data, Comp: func(p *pk.Byte) pk.Boolean { return *p&1 == 1 }, }); err != nil { panic(err) } fmt.Println(data) }
Output: Tnze
type Packet ¶
Packet define a net data package
func Marshal ¶
func Marshal(id int32, fields ...FieldEncoder) (pk Packet)
Marshal generate Packet with the ID and Fields
Example (SetSlot) ¶
package main import ( "fmt" _ "embed" pk "github.com/Edouard127/go-mc/net/packet" ) func main() { for _, pf := range []struct { WindowID byte Slot int16 Present bool ItemID int ItemCount byte NBT interface{} }{ {WindowID: 0, Slot: 5, Present: false}, {WindowID: 0, Slot: 5, Present: true, ItemID: 0x01, ItemCount: 1, NBT: pk.Byte(0)}, {WindowID: 0, Slot: 5, Present: true, ItemID: 0x01, ItemCount: 1, NBT: pk.NBT(int32(0x12345678))}, } { p := pk.Marshal(0x15, pk.Byte(pf.WindowID), pk.Short(pf.Slot), pk.Boolean(pf.Present), pk.Optional[pk.Tuple, *pk.Tuple, *pk.Boolean]{ Has: (*pk.Boolean)(&pf.Present), Value: pk.Tuple{ pk.VarInt(pf.ItemID), pk.Byte(pf.ItemCount), pf.NBT, }}, ) fmt.Printf("%02X % 02X\n", p.ID, p.Data) } }
Output: 15 00 00 05 00 15 00 00 05 01 01 01 00 15 00 00 05 01 01 01 03 00 00 12 34 56 78
func (Packet) Scan ¶
func (p Packet) Scan(fields ...FieldDecoder) error
Scan decode the packet and fill data into fields
Example (JoinGame) ¶
package main import ( "fmt" _ "embed" pk "github.com/Edouard127/go-mc/net/packet" ) //go:embed joingame_test.bin var testJoinGameData []byte func main() { p := pk.Packet{ID: 0x23, Data: testJoinGameData} var ( EID pk.Int Hardcore pk.Boolean Gamemode pk.UnsignedByte PreGamemode pk.Byte WorldNames = make([]pk.Identifier, 0) // This cannot replace with "var DimensionNames []pk.Identifier" because "nil" has no type information DimensionCodec struct { DimensionType interface{} `nbt:"minecraft:dimension_type"` WorldgenBiome interface{} `nbt:"minecraft:worldgen/biome"` } Dimension interface{} WorldName pk.Identifier HashedSeed pk.Long MaxPlayers pk.VarInt ViewDistance pk.VarInt RDI, ERS, IsDebug, IsFlat pk.Boolean ) err := p.Scan( &EID, &Hardcore, &Gamemode, &PreGamemode, pk.Array(&WorldNames), pk.NBT(&DimensionCodec), pk.NBT(&Dimension), &WorldName, &HashedSeed, &MaxPlayers, &ViewDistance, &RDI, &ERS, &IsDebug, &IsFlat, ) fmt.Println(err) }
Output: <nil>
type PluginMessageData ¶
type PluginMessageData []byte
PluginMessageData is only used in LoginPlugin,and it will read all left bytes
type Position ¶
Position x as a 26-bit integer, followed by y as a 12-bit integer, followed by z as a 26-bit integer (all signed, two's complement)
type Tuple ¶
type Tuple []any // FieldEncoder, FieldDecoder or both (Field)
type UnsignedShort ¶
type UnsignedShort uint16
UnsignedShort is unsigned 16-bit integer