diff --git a/api/stats.go b/api/stats.go new file mode 100644 index 0000000..1339b94 --- /dev/null +++ b/api/stats.go @@ -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) +} diff --git a/common/strings.go b/common/strings.go index 0d41d97..0cd695b 100644 --- a/common/strings.go +++ b/common/strings.go @@ -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 +} diff --git a/nas/main.go b/nas/main.go index 7439d3b..5e7eff9 100644 --- a/nas/main.go +++ b/nas/main.go @@ -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)