mt-multiserver-proxy/list.go

118 lines
2.1 KiB
Go

package proxy
import (
"bytes"
"encoding/json"
"log"
"math"
"mime/multipart"
"net"
"net/http"
"net/textproto"
"sync"
"time"
)
const (
listAdd = "start"
listUpdate = "update"
listRm = "delete"
)
var announceMu sync.Mutex
func announce(action string) error {
announceMu.Lock()
defer announceMu.Unlock()
addr, err := net.ResolveUDPAddr("udp", Conf().BindAddr)
if err != nil {
return err
}
a := map[string]interface{}{
"action": action,
"address": addr.IP.String(),
"port": addr.Port,
}
if action != listRm {
a["name"] = Conf().List.Name
a["description"] = Conf().List.Desc
a["version"] = versionString
a["proto_min"] = protoVer
a["proto_max"] = protoVer
a["url"] = Conf().List.URL
a["creative"] = Conf().List.Creative
a["damage"] = Conf().List.Dmg
a["password"] = Conf().RequirePasswd
a["pvp"] = Conf().List.PvP
a["uptime"] = math.Floor(Uptime().Seconds())
a["game_time"] = 0
playersMu.RLock()
a["clients"] = len(players)
clts := make([]string, 0, len(players))
for player := range players {
clts = append(clts, player)
}
playersMu.RUnlock()
a["clients_max"] = Conf().UserLimit
a["clients_list"] = clts
a["gameid"] = Conf().List.Game
}
if action == listAdd {
a["can_see_far_names"] = Conf().List.FarNames
a["mods"] = Conf().List.Mods
}
s, err := json.Marshal(a)
if err != nil {
return err
}
body := &bytes.Buffer{}
w := multipart.NewWriter(body)
header := textproto.MIMEHeader{}
header.Set("Content-Disposition", "form-data; name=\"json\"")
part, _ := w.CreatePart(header)
part.Write(s)
w.Close()
_, err = http.Post(Conf().List.Addr+"/announce", "multipart/form-data; boundary="+w.Boundary(), body)
if err != nil {
return err
}
log.Println("announce", action)
return nil
}
func init() {
if Conf().List.Enable {
go func() {
var added bool
t := time.NewTicker(time.Duration(Conf().List.Interval) * time.Second)
for {
<-t.C
if !added {
if err := announce(listAdd); err != nil {
log.Print(err)
}
added = true
continue
}
if err := announce(listUpdate); err != nil {
log.Print(err)
}
}
}()
}
}