monitor-player-count/poller-mcapi.go
2025-07-14 19:35:50 +02:00

74 lines
1.6 KiB
Go

package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"strconv"
)
type mcApiPoller struct {
Address string
}
func (p *mcApiPoller) PollPlayerCount() (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 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 PlayerCount{}, fmt.Errorf("invalid json response: %w", err)
}
var count PlayerCount
for _, player := range data.Players.Sample {
matched := playerRegex.FindStringSubmatch(player.Name)
if matched == nil || len(matched) != 3 {
return PlayerCount{}, fmt.Errorf("match player regex against \"%s\"", player.Name)
}
value, err := strconv.Atoi(matched[2])
if err != nil {
return 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 PlayerCount{}, fmt.Errorf("unknown player \"%s\"", matched[1])
}
}
return count, nil
}
func (p *mcApiPoller) String() string {
return fmt.Sprintf("mcapi[address=%s]", p.Address)
}