Add basic serverlist announcements

master
HimbeerserverDE 2021-03-06 20:33:25 +01:00
parent 5d5b0f6d7f
commit 6a57dc6489
No known key found for this signature in database
GPG Key ID: 1A651504791E6A8B
5 changed files with 187 additions and 0 deletions

View File

@ -122,3 +122,8 @@ Description: If this is true players are automatically redirected to
the default server if the server they are on shuts down or crashes,
default is true
```
> `serverlist_address`
```
Type: String
Description: Address to send to server list
```

2
end.go
View File

@ -49,6 +49,8 @@ func End(crash, reconnect bool) {
time.Sleep(time.Second)
Announce(AnnounceDelete)
if crash {
os.Exit(1)
} else {

View File

@ -43,6 +43,9 @@ func main() {
l := Listen(lc)
SetListener(l)
Announce(AnnounceStart)
for {
clt, err := l.Accept()
if err != nil {
@ -83,6 +86,27 @@ func main() {
go func() {
srv = <-fin
if srv == nil {
data := []byte{
0, ToClientAccessDenied,
AccessDeniedServerFail, 0, 0, 0, 0,
}
select {
case <-clt.Disco():
default:
ack, err := clt.Send(rudp.Pkt{Data: data})
if err != nil {
log.Print(err)
}
<-ack
}
clt.SendDisco(0, true)
clt.Close()
return
}
clt.SetServer(srv)
go Proxy(clt, srv)

139
serverlist.go Normal file
View File

@ -0,0 +1,139 @@
package main
import (
"bytes"
"encoding/json"
"log"
"mime/multipart"
"net"
"net/http"
"net/textproto"
"time"
)
const (
AnnounceStart = "start"
AnnounceUpdate = "update"
AnnounceDelete = "delete"
)
func Announce(action string) error {
announce, ok := GetConfKey("serverlist_announce").(bool)
if !ok || !announce {
return nil
}
listsrv, ok := GetConfKey("serverlist_url").(string)
if !ok {
log.Print("Server list URL not set or not a string")
return nil
}
log.Print("Updating server list announcement")
host := GetConfKey("host").(string)
addr, err := net.ResolveUDPAddr("udp", host)
if err != nil {
return err
}
peers := GetListener().GetPeers()
mods, ok := GetConfKey("serverlist_mods").([]string)
if !ok {
mods = make([]string, 0)
}
clients_list := make([]string, 0)
for _, peer := range peers {
clients_list = append(clients_list, peer.Username())
}
maxPeers, ok := GetConfKey("player_limit").(int)
if !ok {
maxPeers = -1
}
conf := func(key string) interface{} {
value, ok := GetConfKey(key).(string)
if !ok {
return ""
}
return value
}
confBool := func(key string) interface{} {
value, ok := GetConfKey(key).(bool)
if !ok {
return false
}
return value
}
data := make(map[string]interface{})
data["action"] = action
data["port"] = addr.Port
data["address"] = conf("serverlist_address")
if action != AnnounceDelete {
data["name"] = conf("serverlist_name")
data["description"] = conf("serverlist_desc")
data["version"] = "multiserver v1.8.1"
data["proto_min"] = 37
data["proto_max"] = 39
data["url"] = conf("serverlist_display_url")
data["creative"] = confBool("serverlist_creative")
data["damage"] = confBool("serverlist_damage")
data["password"] = confBool("disallow_empty_passwords")
data["pvp"] = confBool("serverlist_pvp")
data["uptime"] = Uptime()
data["game_time"] = 0
data["clients"] = GetPeerCount()
data["clients_max"] = maxPeers
data["clients_list"] = clients_list
data["gameid"] = conf("serverlist_game")
}
if action == AnnounceStart {
data["dedicated"] = true
data["rollback"] = confBool("serverlist_rollback")
data["privs"] = conf("serverlist_default_privs")
data["can_see_far_names"] = confBool("serverlist_can_see_far_names")
data["mods"] = mods
}
s, err := json.Marshal(data)
if err != nil {
return err
}
rqBody := &bytes.Buffer{}
writer := multipart.NewWriter(rqBody)
mimeHeader := textproto.MIMEHeader{}
mimeHeader.Set("Content-Disposition", "form-data; name=\"json\"")
part, _ := writer.CreatePart(mimeHeader)
part.Write(s)
writer.Close()
_, err = http.Post(listsrv + "/announce", "multipart/form-data; boundary=" + writer.Boundary(), rqBody)
if err != nil {
return err
}
return nil
}
func init() {
go func() {
announce := time.NewTicker(5 * time.Minute)
for {
select {
case <-announce.C:
Announce(AnnounceUpdate)
}
}
}()
}

17
uptime.go Normal file
View File

@ -0,0 +1,17 @@
package main
import (
"math"
"time"
)
var uptime time.Time
// Uptime reports how long the program has been running
func Uptime() float64 {
return math.Floor(time.Since(uptime).Seconds())
}
func init() {
uptime = time.Now()
}