package main import ( "encoding/json" "fmt" "net/http" "net/url" "strconv" "git.1e99.eu/1e99/2b2t/models" ) type mcApiPoller struct { Address string } func (p *mcApiPoller) PollPlayerCount() (models.PlayerCount, error) { url, _ := url.Parse("https://mcapi.us/server/status") query := url.Query() query.Set("ip", p.Address) url.RawQuery = query.Encode() res, err := http.Get(url.String()) if err != nil { return models.PlayerCount{}, fmt.Errorf("http request: %w", err) } defer res.Body.Close() var data struct { Players struct { Max int `json:"max"` Now int `json:"now"` Sample []struct { Name string `json:"name"` Id string `json:"id"` } `json:"sample"` } `json:"players"` } err = json.NewDecoder(res.Body).Decode(&data) if err != nil { return models.PlayerCount{}, fmt.Errorf("invalid json response: %w", err) } var count models.PlayerCount for _, player := range data.Players.Sample { matched := playerRegex.FindStringSubmatch(player.Name) if matched == nil || len(matched) != 3 { return models.PlayerCount{}, fmt.Errorf("match player regex against \"%s\"", player.Name) } value, err := strconv.Atoi(matched[2]) if err != nil { return models.PlayerCount{}, fmt.Errorf("parse number: %w", err) } switch matched[1] { case "§6In-game": count.Playing = value case "§6Queue": count.NormalQueue = value case "§6Priority queue": count.PriorityQueue = value default: return models.PlayerCount{}, fmt.Errorf("unknown player \"%s\"", matched[1]) } } return count, nil } func (p *mcApiPoller) String() string { return fmt.Sprintf("mcapi[address=%s]", p.Address) }