package main import ( "bufio" "encoding/json" "fmt" "io/ioutil" "net/http" "os" "time" ) func main() { fmt.Printf("Minecraft Username Lookup -- by MrMelon\n") if len(os.Args) > 1 { for i := 1; i < len(os.Args); i++ { fmt.Printf("Find: " + os.Args[i]) result, err := lookup(os.Args[i]) if err != nil { fmt.Printf("\rFail: %s\n", os.Args[i]) fmt.Fprintln(os.Stderr, "Internal error:", err) continue } fmt.Printf("\rDone: %s -- %s\n", result.Data.Player.ID, result.Data.Player.Username) } } fi, _ := os.Stdin.Stat() if (fi.Mode() & os.ModeCharDevice) == 0 { scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { fmt.Printf("Find: " + scanner.Text()) result, err := lookup(scanner.Text()) if err != nil { fmt.Printf("\rFail: %s\n", scanner.Text()) fmt.Fprintln(os.Stderr, "Internal error:", err) continue } fmt.Printf("\rDone: %s -- %s\n", result.Data.Player.ID, result.Data.Player.Username) } if err := scanner.Err(); err != nil { fmt.Fprintln(os.Stderr, "Failed to read pipe:", err) } } } // APIResponse is used to parse the data from the api. type APIResponse struct { Data struct { Player APIPlayerData `json:"player"` } `json:"data"` } // APIPlayerData is used to store player object. type APIPlayerData struct { Username string `json:"username"` ID string `json:"id"` Avatar string `json:"avatar"` } func lookup(uuid string) (*APIResponse, error) { var err error data := &APIResponse{} bytes, err := request("https://playerdb.co/api/player/minecraft/" + uuid) if err != nil { return nil, err } err = json.Unmarshal(bytes, data) if err != nil { return nil, err } return data, err } func request(url string) ([]byte, error) { var body []byte mclookupClient := http.Client{ Timeout: time.Second * 2, } req, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { return body, err } req.Header.Set("User-Agent", "mclookup") res, err := mclookupClient.Do(req) if err != nil { return body, err } if res.Body != nil { defer res.Body.Close() } body, err = ioutil.ReadAll(res.Body) if err != nil { return body, err } return body, nil }