diff --git a/bot/client.go b/bot/client.go index 80a459d..a5983c3 100644 --- a/bot/client.go +++ b/bot/client.go @@ -5,7 +5,7 @@ import ( "github.com/Tnze/go-mc/net" ) -// Client is the Object used to access Minecraft server +// Client is used to access Minecraft server type Client struct { conn *net.Conn Auth @@ -19,7 +19,13 @@ type Client struct { Events eventBroker } -//NewClient init and return a new Client +// NewClient init and return a new Client. +// +// A new Client has default name "Steve" and zero UUID. +// It is useable for an offline-mode game. +// +// For online-mode, you need login your Mojang account +// and load your Name, UUID and AccessToken to client. func NewClient() (c *Client) { c = new(Client) diff --git a/bot/example_test.go b/bot/example_test.go new file mode 100644 index 0000000..09ae12e --- /dev/null +++ b/bot/example_test.go @@ -0,0 +1,71 @@ +package bot + +import ( + "github.com/Tnze/go-mc/authenticate" + "log" +) + +func ExamplePingAndList() { + resp, delay, err := PingAndList("localhost", 25565) + if err != nil { + log.Fatalf("ping and list server fail: %v", err) + } + + log.Println("Status:", string(resp)) + log.Println("Delay:", delay) +} + +func ExampleClient_JoinServer_offline() { + c := NewClient() + c.Name = "Tnze" // set it's name before login. + + //Login + err := c.JoinServer("localhost", 25565) + if err != nil { + log.Fatal(err) + } + log.Println("Login success") + + // Regist event handlers + // c.Events.GameStart = onGameStartFunc + // c.Events.ChatMsg = onChatMsgFunc + // c.Events.Disconnect = onDisconnectFunc + // ... + + //JoinGame + err = c.HandleGame() + if err != nil { + log.Fatal(err) + } +} + +func ExampleClient_JoinServer_online() { + c := NewClient() + + //Login Mojang account to get AccessToken + auth, err := authenticate.Authenticate("Your E-mail", "Your Password") + if err != nil { + panic(err) + } + c.Name = auth.SelectedProfile.Name + c.AsTk = auth.SelectedProfile.ID + + //Connect server + err = c.JoinServer("localhost", 25565) + if err != nil { + log.Fatal(err) + } + log.Println("Login success") + + // Regist event handlers + // c.Events.GameStart = onGameStartFunc + // c.Events.ChatMsg = onChatMsgFunc + // c.Events.Disconnect = onDisconnectFunc + // ... + + //Join the game + err = c.HandleGame() + if err != nil { + log.Fatal(err) + } +} diff --git a/bot/mcbot.go b/bot/mcbot.go index 5700a25..0b690a1 100644 --- a/bot/mcbot.go +++ b/bot/mcbot.go @@ -1,3 +1,7 @@ +// Package bot implements a simple Minecraft client that can join a server +// or just ping it for getting information. +// +// Runable example could be found at cmd/ . package bot import ( @@ -8,13 +12,13 @@ import ( pk "github.com/Tnze/go-mc/net/packet" ) -//ProtocalVersion is the protocal version -// 477 for 1.14 +// ProtocalVersion , the protocal version number of minecraft net protocal const ProtocalVersion = 477 -// PingAndList chack server status and list online player -// Return a JSON string about server status. -// see JSON format at https://wiki.vg/Server_List_Ping#Response +// PingAndList chack server status and list online player. +// Returns a JSON data with server status, and the delay. +// +// For more infomation for JSON format, see https://wiki.vg/Server_List_Ping#Response func PingAndList(addr string, port int) ([]byte, time.Duration, error) { conn, err := net.DialMC(fmt.Sprintf("%s:%d", addr, port)) if err != nil { @@ -54,8 +58,8 @@ func PingAndList(addr string, port int) ([]byte, time.Duration, error) { } //PING - now := time.Now() - err = conn.WritePacket(pk.Marshal(0x01, pk.Long(now.Unix()))) + startTime := time.Now() + err = conn.WritePacket(pk.Marshal(0x01, pk.Long(startTime.Unix()))) if err != nil { return nil, 0, fmt.Errorf("bot: send ping packect fail: %v", err) } @@ -69,11 +73,11 @@ func PingAndList(addr string, port int) ([]byte, time.Duration, error) { if err != nil { return nil, 0, fmt.Errorf("bot: scan pong packect fail: %v", err) } - if t != pk.Long(now.Unix()) { + if t != pk.Long(startTime.Unix()) { return nil, 0, fmt.Errorf("bot: pong packect no match: %v", err) } - return []byte(s), time.Now().Sub(now), err + return []byte(s), time.Since(startTime), err } // JoinServer connect a Minecraft server for playing the game. diff --git a/bot/settings.go b/bot/settings.go index 73af757..91cb4d7 100644 --- a/bot/settings.go +++ b/bot/settings.go @@ -27,7 +27,7 @@ const ( //DefaultSettings are the default settings of client var DefaultSettings = Settings{ - Locale: "zh_CN", + Locale: "zh_CN", // ^_^ ViewDistance: 15, ChatMode: 0, DisplayedSkinParts: Jacket | LeftSleeve | RightSleeve | LeftPantsLeg | RightPantsLeg | Hat, diff --git a/cmd/daze/daze.go b/cmd/daze/daze.go index 352dd30..f7aa949 100644 --- a/cmd/daze/daze.go +++ b/cmd/daze/daze.go @@ -12,11 +12,11 @@ func main() { // For online-mode, you need login your Mojang account // and load your Name and UUID to client: // - // auth, err := authenticate.Authenticate(Your E-mail", "Your Password") - // if err != nil { - // panic(err) - // } - // c.Name, c.AsTk = auth.SelectedProfile.Name, auth.SelectedProfile.ID + // auth, err := authenticate.Authenticate(Your E-mail", "Your Password") + // if err != nil { + // panic(err) + // } + // c.Name, c.AsTk = auth.SelectedProfile.Name, auth.SelectedProfile.ID //Login err := c.JoinServer("localhost", 25565) diff --git a/net/conn.go b/net/conn.go index c3f4210..c3b9cd4 100644 --- a/net/conn.go +++ b/net/conn.go @@ -1,3 +1,4 @@ +// Package net pack network connection for Minecraft. package net import ( @@ -17,6 +18,7 @@ type Conn struct { threshold int } +// DialMC create a Minecraft connection func DialMC(addr string) (conn *Conn, err error) { conn = new(Conn) conn.socket, err = net.Dial("tcp", addr) @@ -30,6 +32,7 @@ func DialMC(addr string) (conn *Conn, err error) { return } +// ReadPacket read a Packet from Conn. func (c *Conn) ReadPacket() (pk.Packet, error) { p, err := pk.RecvPacket(c.ByteReader, c.threshold > 0) if err != nil { @@ -38,11 +41,13 @@ func (c *Conn) ReadPacket() (pk.Packet, error) { return *p, err } +//WritePacket write a Packet to Conn. func (c *Conn) WritePacket(p pk.Packet) error { _, err := c.Write(p.Pack(c.threshold)) return err } +// SetCipher load the decode/encode stream to this Conn func (c *Conn) SetCipher(encoStream, decoStream cipher.Stream) { //加密连接 c.ByteReader = bufio.NewReader(cipher.StreamReader{ //Set reciver for AES @@ -55,6 +60,9 @@ func (c *Conn) SetCipher(encoStream, decoStream cipher.Stream) { } } +// SetThreshold set threshold to Conn. +// The data packet with length longger then threshold +// will be compress when sendding. func (c *Conn) SetThreshold(t int) { c.threshold = t } diff --git a/net/packet/packet_test.go b/net/packet/packet_test.go index 8fe7a7d..e11c89e 100644 --- a/net/packet/packet_test.go +++ b/net/packet/packet_test.go @@ -40,7 +40,7 @@ func TestUnpackInt(t *testing.T) { } func TestPositionPack(t *testing.T) { - // x (-33554432 to 33554431), y (-2048 to 2047), z (-33554432 to 33554431) + // This test is not good. for x := -33554432; x < 33554432; x += 55443 { for y := -2048; y < 2048; y += 48 {