diff --git a/bot/example_test.go b/bot/example_test.go index 9c72547..721d640 100644 --- a/bot/example_test.go +++ b/bot/example_test.go @@ -1,7 +1,7 @@ package bot import ( - "github.com/Tnze/go-mc/authenticate" + "github.com/Tnze/go-mc/yggdrasil" "log" ) @@ -43,7 +43,7 @@ func ExampleClient_JoinServer_online() { c := NewClient() //Login Mojang account to get AccessToken - auth, err := authenticate.Authenticate("Your E-mail", "Your Password") + auth, err := yggdrasil.Authenticate("Your E-mail", "Your Password") if err != nil { panic(err) } diff --git a/bot/login.go b/bot/login.go index 14fb40d..609c7d2 100644 --- a/bot/login.go +++ b/bot/login.go @@ -159,7 +159,7 @@ func loginAuth(AsTk, name, UUID string, shareSecret []byte, er encryptionRequest }, ) if err != nil { - return fmt.Errorf("create request packet to authenticate faile: %v", err) + return fmt.Errorf("create request packet to yggdrasil faile: %v", err) } PostRequest, err := http.NewRequest(http.MethodPost, "https://sessionserver.mojang.com/session/minecraft/join", diff --git a/chat/chatMsg.go b/chat/chatMsg.go index c58fcd3..469f8bd 100644 --- a/chat/chatMsg.go +++ b/chat/chatMsg.go @@ -125,15 +125,19 @@ func (m Message) ClearString() string { msg.WriteString(text) //handle translate - if m.Translate != "" && translateMap != nil { - + if m.Translate != "" { args := make([]interface{}, len(m.With)) for i, v := range m.With { var arg Message _ = arg.UnmarshalJSON(v) //ignore error args[i] = arg.ClearString() } - _, _ = fmt.Fprintf(&msg, translateMap[m.Translate], args...) + + if translateMap != nil { + _, _ = fmt.Fprintf(&msg, translateMap[m.Translate], args...) + } else { + _, _ = fmt.Fprint(&msg, m.Translate, m.With) + } } if m.Extra != nil { @@ -172,8 +176,7 @@ func (m Message) String() string { msg.WriteString(text) //handle translate - if m.Translate != "" && translateMap != nil { - + if m.Translate != "" { args := make([]interface{}, len(m.With)) for i, v := range m.With { var arg Message @@ -181,7 +184,11 @@ func (m Message) String() string { args[i] = arg } - _, _ = fmt.Fprintf(&msg, translateMap[m.Translate], args...) + if translateMap != nil { + _, _ = fmt.Fprintf(&msg, translateMap[m.Translate], args...) + } else { + _, _ = fmt.Fprint(&msg, m.Translate, m.With) + } } if m.Extra != nil { diff --git a/cmd/daze/daze.go b/cmd/daze/daze.go index 24ee64d..20fa47d 100644 --- a/cmd/daze/daze.go +++ b/cmd/daze/daze.go @@ -15,7 +15,7 @@ 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") + // auth, err := yggdrasil.Authenticate("Your E-mail", "Your Password") // if err != nil { // panic(err) // } diff --git a/cmd/substitute_server/substitute.go b/cmd/substitute_server/substitute.go index 2aea7bf..164284f 100644 --- a/cmd/substitute_server/substitute.go +++ b/cmd/substitute_server/substitute.go @@ -20,7 +20,7 @@ import ( "net/http" "strings" - "github.com/Tnze/go-mc/authenticate" + "github.com/Tnze/go-mc/yggdrasil" "github.com/Tnze/go-mc/bot" "github.com/Tnze/go-mc/chat" _ "github.com/Tnze/go-mc/data/lang/en-us" @@ -103,7 +103,7 @@ func Handle(conn net.Conn) { case PlayerLogin: signal := make(chan int) client := bot.NewClient() - auth, err := authenticate.Authenticate(Email, Paswd) + auth, err := yggdrasil.Authenticate(Email, Paswd) if err != nil { panic(err) } @@ -374,7 +374,7 @@ func (c *Client) encryptionResponse() ([]byte, []byte, error) { return nil, nil, err } if p.ID != 0x01 { - return nil, nil, fmt.Errorf("0x%02X is not Encryption Response", p.ID) + return nil, nil, fmt.Errorf("0x%02X is not Encryption AuthResp", p.ID) } var ( diff --git a/authenticate/authenticate.go b/yggdrasil/authenticate.go similarity index 70% rename from authenticate/authenticate.go rename to yggdrasil/authenticate.go index 2ef7687..ac8918f 100644 --- a/authenticate/authenticate.go +++ b/yggdrasil/authenticate.go @@ -1,6 +1,4 @@ -package authenticate - -//Simple yggdrasil-minecraft-login method. +package yggdrasil import ( "bytes" @@ -10,15 +8,15 @@ import ( "net/http" ) -// agent is a struct of auth -type agent struct { +// Agent is a struct of auth +type Agent struct { Name string `json:"name"` Version int `json:"version"` } -// payload is a authenticate request struct -type payload struct { - Agent agent `json:"agent"` +// AuthPayload is a yggdrasil request struct +type AuthPayload struct { + Agent Agent `json:"agent"` UserName string `json:"username"` Password string `json:"password"` ClientToken string `json:"clientToken"` @@ -26,18 +24,18 @@ type payload struct { } // Authenticate authenticates a user using their password. -func Authenticate(user, passwd string) (respData Response, err error) { - j, err := json.Marshal(payload{ - Agent: agent{ +func Authenticate(user, password string) (respData AuthResp, err error) { + j, err := json.Marshal(AuthPayload{ + Agent: Agent{ Name: "Minecraft", Version: 1, }, UserName: user, - Password: passwd, + Password: password, ClientToken: "go-mc", RequestUser: true, }) - // fmt.Println(string(j)) + if err != nil { err = fmt.Errorf("encoding json fail: %v", err) return @@ -45,24 +43,24 @@ func Authenticate(user, passwd string) (respData Response, err error) { //Post client := http.Client{} - PostRequest, err := http.NewRequest(http.MethodPost, "https://authserver.mojang.com/authenticate", + PostRequest, err := http.NewRequest(http.MethodPost, "https://authserver.mojang.com/yggdrasil", bytes.NewReader(j)) if err != nil { err = fmt.Errorf("make request error: %v", err) return } - PostRequest.Header.Set("User-agent", "go-mc") + PostRequest.Header.Set("User-Agent", "go-mc") PostRequest.Header.Set("Connection", "keep-alive") PostRequest.Header.Set("Content-Type", "application/json") resp, err := client.Do(PostRequest) if err != nil { - err = fmt.Errorf("post authenticate fail: %v", err) + err = fmt.Errorf("post yggdrasil fail: %v", err) return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { - err = fmt.Errorf("read authenticate resp fail: %v", err) + err = fmt.Errorf("read yggdrasil resp fail: %v", err) return } err = json.Unmarshal(body, &respData) @@ -71,15 +69,15 @@ func Authenticate(user, passwd string) (respData Response, err error) { return } if respData.Error != "" { - err = fmt.Errorf("authenticate fail: {error: %q, errorMessage: %q, cause: %q}", + err = fmt.Errorf("yggdrasil fail: {error: %q, errorMessage: %q, cause: %q}", respData.Error, respData.ErrorMessage, respData.Cause) return } return } -// Response is the response from Mojang's auth server -type Response struct { +// AuthResp is the response from Mojang's auth server +type AuthResp struct { Error string `json:"error"` ErrorMessage string `json:"errorMessage"` Cause string `json:"cause"` @@ -90,14 +88,14 @@ type Response struct { ID string `json:"ID"` // hexadecimal Name string `json:"name"` Legacy bool `json:"legacy"` // In practice, this field only appears in the response if true. Default to false. - } `json:"availableProfiles"` // only present if the agent field was received + } `json:"availableProfiles"` // only present if the Agent field was received - SelectedProfile struct { // only present if the agent field was received + SelectedProfile struct { // only present if the Agent field was received ID string `json:"id"` Name string `json:"name"` Legacy bool `json:"legacy"` } `json:"selectedProfile"` - User struct { // only present if requestUser was true in the request payload + User struct { // only present if requestUser was true in the request AuthPayload ID string `json:"id"` // hexadecimal Properties []struct { Name string `json:"name"` diff --git a/authenticate/authenticate_test.go b/yggdrasil/authenticate_test.go similarity index 86% rename from authenticate/authenticate_test.go rename to yggdrasil/authenticate_test.go index b9e79ef..396555b 100644 --- a/authenticate/authenticate_test.go +++ b/yggdrasil/authenticate_test.go @@ -1,4 +1,4 @@ -package authenticate +package yggdrasil import ( "encoding/json" @@ -7,8 +7,8 @@ import ( ) func TestEncodingPayload(t *testing.T) { - j, err := json.Marshal(payload{ - Agent: agent{ + j, err := json.Marshal(AuthPayload{ + Agent: Agent{ Name: "Minecraft", Version: 1, }, diff --git a/yggdrasil/yggdrasil.go b/yggdrasil/yggdrasil.go new file mode 100644 index 0000000..18887db --- /dev/null +++ b/yggdrasil/yggdrasil.go @@ -0,0 +1,10 @@ +// Package yggdrasil implement Yggdrasil protocol. +// +// Minecraft 1.6 introduced a new authentication scheme called Yggdrasil +// which completely replaces the previous authentication system. +// Mojang's other game, Scrolls, uses this method of authentication as well. +// Mojang has said that this authentication system should be used by everyone for custom logins, +// but credentials should never be collected from users. ----- https://wiki.vg +package yggdrasil + +var Server = ""