You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
2.8 KiB
140 lines
2.8 KiB
package main |
|
|
|
import ( |
|
"bytes" |
|
"encoding/json" |
|
"log" |
|
"mime/multipart" |
|
"net" |
|
"net/http" |
|
"net/textproto" |
|
"time" |
|
) |
|
|
|
const ( |
|
AnnounceStart = "start" |
|
AnnounceUpdate = "update" |
|
AnnounceDelete = "delete" |
|
) |
|
|
|
const verString = "multiserver v1.13.3" |
|
|
|
func Announce(action string) error { |
|
listsrv, ok := ConfKey("serverlist_url").(string) |
|
if !ok { |
|
return nil |
|
} |
|
|
|
log.Print("Updating server list announcement") |
|
|
|
host, ok := ConfKey("host").(string) |
|
if !ok { |
|
host = "0.0.0.0:33000" |
|
} |
|
|
|
addr, err := net.ResolveUDPAddr("udp", host) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
conns := Conns() |
|
|
|
mods, ok := ConfKey("serverlist_mods").([]string) |
|
if !ok { |
|
mods = make([]string, 0) |
|
} |
|
|
|
clients_list := make([]string, 0) |
|
for _, conn := range conns { |
|
clients_list = append(clients_list, conn.Username()) |
|
} |
|
|
|
maxPeers, ok := ConfKey("player_limit").(int) |
|
if !ok { |
|
maxPeers = int(^uint(0) >> 1) |
|
} |
|
|
|
conf := func(key string) interface{} { |
|
value, ok := ConfKey(key).(string) |
|
if !ok { |
|
return "" |
|
} |
|
return value |
|
} |
|
|
|
confBool := func(key string) interface{} { |
|
value, ok := ConfKey(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"] = verString |
|
data["proto_min"] = ProtoMin |
|
data["proto_max"] = ProtoLatest |
|
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"] = ConnCount() |
|
data["clients_max"] = maxPeers |
|
data["clients_list"] = clients_list |
|
data["gameid"] = conf("serverlist_game") |
|
} |
|
|
|
if action == AnnounceStart { |
|
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() { |
|
reannounce, ok := ConfKey("serverlist_announce_interval").(int) |
|
if !ok { |
|
reannounce = 300 |
|
} |
|
|
|
go func() { |
|
announce := time.NewTicker(time.Duration(reannounce) * time.Second) |
|
for { |
|
select { |
|
case <-announce.C: |
|
Announce(AnnounceUpdate) |
|
} |
|
} |
|
}() |
|
}
|
|
|