Documentation ¶
Index ¶
- Constants
- type Angle
- type Ary
- type Boolean
- type Builder
- type Byte
- type ByteArray
- type Chat
- type Double
- type Field
- type FieldDecoder
- type FieldEncoder
- type Float
- type Identifier
- type Int
- type Long
- type Opt
- type Packet
- type Position
- type Short
- type String
- type Tuple
- type UUID
- type UnsignedByte
- type UnsignedShort
- type VarInt
- type VarLong
Examples ¶
Constants ¶
const MaxVarIntLen = 5
const MaxVarLongLen = 10
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Ary ¶
type Ary struct { Len interface{} // Value or Pointer of any integer type, only needed in ReadFrom 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 NOT read or write the Len. You are controlling it manually.
func (Ary) ReadFrom ¶
Example ¶
package main import ( pk "github.com/RavMda/go-mc/net/packet" ) func main() { var length pk.VarInt var data []pk.String var p pk.Packet // = conn.ReadPacket() if err := p.Scan( &length, // decode length first pk.Ary{ // then decode Ary according to length Len: &length, Ary: &data, }, ); err != nil { panic(err) } }
Output:
func (Ary) WriteTo ¶
Example ¶
package main import ( pk "github.com/RavMda/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, // It's important to remember that // typically the responsibility of // sending the length field // is on you. pk.VarInt(len(data)), pk.Ary{ Len: len(data), // this line can be removed Ary: data, }, ) }
Output:
type Boolean ¶
type Boolean bool
Boolean of True is encoded as 0x01, false as 0x00.
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
func (*Builder) WriteField ¶
func (p *Builder) WriteField(fields ...FieldEncoder)
type ByteArray ¶
type ByteArray []byte
ByteArray is []byte with prefix VarInt as length
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 encode as minecraft protocol used.
type Identifier ¶
type Identifier = String
Identifier is encoded as a String with max length of 32767.
type Opt ¶
type Opt struct { Has interface{} // Pointer of bool, or `func() bool` Field interface{} // FieldEncoder, FieldDecoder or both (Field) }
func (Opt) ReadFrom ¶
Example ¶
package main import ( "fmt" pk "github.com/RavMda/go-mc/net/packet" ) func main() { var has pk.Boolean var data pk.String p1 := pk.Packet{Data: []byte{ 0x01, // pk.Boolean(true) 4, 'T', 'n', 'z', 'e', // pk.String }} if err := p1.Scan( &has, pk.Opt{ Has: &has, Field: &data, }, ); err != nil { panic(err) } fmt.Println(data) 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( &has, pk.Opt{ Has: &has, Field: &data2, }, ); err != nil { panic(err) } fmt.Println(data2) }
Output: Tnze WILL NOT BE READ, WILL NOT BE COVERED
Example (Func) ¶
package main import ( "fmt" pk "github.com/RavMda/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 flag pk.Byte 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( &flag, pk.Opt{ Has: func() bool { return flag&1 != 0 }, Field: &data, }, ); 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
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/RavMda/go-mc/net/packet" ) //go:embed joingame_test.bin var testJoinGameData []byte func main() { p := pk.Packet{ID: 0x24, Data: testJoinGameData} var ( EID pk.Int Hardcore pk.Boolean Gamemode pk.UnsignedByte PreGamemode pk.Byte WorldCount pk.VarInt WorldNames = make([]pk.Identifier, 0) // This cannot replace with "var WorldNames []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, &WorldCount, pk.Ary{ Len: &WorldCount, Ary: &WorldNames, }, pk.NBT(&DimensionCodec), pk.NBT(&Dimension), &WorldName, &HashedSeed, &MaxPlayers, &ViewDistance, &RDI, &ERS, &IsDebug, &IsFlat, ) fmt.Print(err) }
Output: <nil>
type Position ¶
type Position struct {
X, Y, Z int
}
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 String ¶
type String string
String is sequence of Unicode scalar values
type Tuple ¶
type Tuple []interface{} // FieldEncoder, FieldDecoder or both (Field)
func (Tuple) ReadFrom ¶
ReadFrom read Tuple from io.Reader, panic when any of field don't implement FieldDecoder
Example ¶
package main import ( pk "github.com/RavMda/go-mc/net/packet" ) func main() { // When you need to read an "Optional Array of X": var has pk.Boolean var arylen pk.Int var ary []pk.String var p pk.Packet // = conn.ReadPacket() if err := p.Scan( &has, pk.Opt{ Has: &has, Field: pk.Tuple{ &arylen, pk.Ary{ Len: &arylen, Ary: &ary, }, }, }, ); err != nil { panic(err) } }
Output:
type UnsignedByte ¶
type UnsignedByte uint8
UnsignedByte is unsigned 8-bit integer
type UnsignedShort ¶
type UnsignedShort uint16
UnsignedShort is unsigned 16-bit integer
type VarInt ¶
type VarInt int32
VarInt is variable-length data encoding a two's complement signed 32-bit integer