Files
backend/internal/core/server_poller.go

89 lines
2.1 KiB
Go

package core
import (
"context"
"encoding/json"
"log"
"time"
"gitea.mrixs.me/minecraft-platform/backend/internal/database"
"gitea.mrixs.me/minecraft-platform/backend/internal/models"
"github.com/Tnze/go-mc/bot/basic"
"github.com/Tnze/go-mc/net"
)
type ServerPoller struct {
Repo *database.ServerRepository
}
func (p *ServerPoller) Start(ctx context.Context) {
log.Println("Starting server poller...")
ticker := time.NewTicker(60 * time.Second)
defer ticker.Stop()
p.pollAllServers(ctx)
for {
select {
case <-ticker.C:
p.pollAllServers(ctx)
case <-ctx.Done():
log.Println("Stopping server poller...")
return
}
}
}
func (p *ServerPoller) pollAllServers(ctx context.Context) {
servers, err := p.Repo.GetAllEnabledServers(ctx)
if err != nil {
log.Printf("Poller: failed to get servers: %v", err)
return
}
for _, s := range servers {
go p.pollServer(ctx, s)
}
}
func (p *ServerPoller) pollServer(ctx context.Context, server *models.GameServer) {
resp, delay, err := net.PingAndListTimeout(server.Address, 5*time.Second)
if err != nil {
log.Printf("Poller: failed to ping %s (%s): %v", server.Name, server.Address, err)
return
}
var status basic.ServerList
if err := json.Unmarshal(resp, &status); err != nil {
log.Printf("Poller: failed to unmarshal status for %s: %v", server.Name, err)
return
}
// MOTD может быть сложным объектом, извлекаем текст
var motdText string
if s, ok := status.Description.(string); ok {
motdText = s
} else {
if m, ok := status.Description.(map[string]interface{}); ok {
if t, ok := m["text"].(string); ok {
motdText = t
}
}
}
updateData := &models.ServerStatus{
StatusJSON: string(resp),
Motd: motdText,
PlayerCount: status.Players.Online,
MaxPlayers: status.Players.Max,
VersionName: status.Version.Name,
Ping: delay.Milliseconds(),
}
if err := p.Repo.UpdateServerStatus(ctx, server.ID, updateData); err != nil {
log.Printf("Poller: failed to update status for %s: %v", server.Name, err)
} else {
log.Printf("Poller: successfully polled %s", server.Name)
}
}