2b2t-queue-tracker/worker/poller-mcapi.go
2025-06-29 11:20:23 +02:00

76 lines
1.6 KiB
Go

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)
}