Add server list support

master
HimbeerserverDE 2021-09-11 15:38:45 +02:00
parent fdbd728918
commit 935156d9fb
No known key found for this signature in database
GPG Key ID: 1A651504791E6A8B
5 changed files with 149 additions and 0 deletions

View File

@ -43,6 +43,21 @@ type Config struct {
DropCSMRF bool
Groups map[string][]string
UserGroups map[string]string
List struct {
Enable bool
Addr string
Interval int
Name string
Desc string
URL string
Creative bool
Dmg bool
PvP bool
Game string
FarNames bool
Mods []string
}
}
// Conf returns a copy of the Config used by the proxy.

117
list.go Normal file
View File

@ -0,0 +1,117 @@
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"] = latestProtoVer
a["proto_max"] = latestProtoVer
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.Print("{←|⇶} 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)
}
}
}()
}
}

View File

@ -6,6 +6,7 @@ package proxy
const latestSerializeVer = 28
const latestProtoVer = 39
const versionString = "5.5.0-dev-83a7b48bb"
const maxPlayerNameLen = 20
const playerNameChars = "^[a-zA-Z0-9-_]+$"
const bytesPerMediaBunch = 5000

6
run.go
View File

@ -49,6 +49,12 @@ func Run() {
signal.Notify(sig, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP)
<-sig
if Conf().List.Enable {
if err := announce(listRm); err != nil {
log.Print("{←|⇶} ", err)
}
}
clts := l.clients()
var wg sync.WaitGroup

10
uptime.go Normal file
View File

@ -0,0 +1,10 @@
package proxy
import "time"
var startTime = time.Now()
// Uptime returns the time the proxy has been running for
func Uptime() time.Duration {
return time.Since(startTime)
}