API: Add /stats - generic stats endpoint

This commit is contained in:
mkwcat
2024-01-01 23:33:05 -05:00
parent 4e8ad85020
commit 2c41f46def
3 changed files with 105 additions and 0 deletions

90
api/stats.go Normal file
View File

@@ -0,0 +1,90 @@
package api
import (
"encoding/json"
"net/http"
"net/url"
"strconv"
"wwfc/common"
"wwfc/qr2"
)
type Stats struct {
OnlinePlayerCount int `json:"online"`
ActivePlayerCount int `json:"active"`
GroupCount int `json:"groups"`
}
func HandleStats(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
u, err := url.Parse(r.URL.String())
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
query, err := url.ParseQuery(u.RawQuery)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
games := query["game"]
stats := map[string]Stats{}
servers := qr2.GetSessionServers()
groups := qr2.GetGroups("")
globalStats := Stats{
OnlinePlayerCount: len(servers),
ActivePlayerCount: 0,
GroupCount: len(groups),
}
for _, server := range servers {
gameName := server["gamename"]
if server["+joinindex"] != "" {
globalStats.ActivePlayerCount += 1
}
if len(games) > 0 && !common.StringInSlice(gameName, games) {
continue
}
gameStats, exists := stats[gameName]
if !exists {
gameStats = Stats{
OnlinePlayerCount: 0,
ActivePlayerCount: 0,
GroupCount: 0,
}
for _, group := range groups {
if group.GameName == gameName {
gameStats.GroupCount += 1
}
}
}
gameStats.OnlinePlayerCount += 1
if server["+joinindex"] != "" {
gameStats.ActivePlayerCount += 1
}
stats[gameName] = gameStats
}
stats["global"] = globalStats
jsonData, err := json.Marshal(stats)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Set("Content-Length", strconv.Itoa(len(jsonData)))
w.Write(jsonData)
}

View File

@@ -54,3 +54,12 @@ func IsUppercaseAlphanumeric(str string) bool {
return true
}
func StringInSlice(str string, slice []string) bool {
for _, s := range slice {
if s == str {
return true
}
}
return false
}

View File

@@ -87,6 +87,12 @@ func handleRequest(w http.ResponseWriter, r *http.Request) {
return
}
// Check for /api/stats
if r.URL.Path == "/api/stats" {
api.HandleStats(w, r)
return
}
// Handle conntest server
if strings.HasPrefix(r.Host, "conntest.") {
handleConnectionTest(w)