Skip to content

Commit

Permalink
Add 'builds' field to /api/stats
Browse files Browse the repository at this point in the history
  • Loading branch information
MineGame159 committed Jan 8, 2025
1 parent d137ead commit 25238f7
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 3 deletions.
182 changes: 179 additions & 3 deletions pkg/web/api/stats.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
package api

import (
"net/http"

"archive/zip"
"bytes"
"encoding/json"
"encoding/xml"
"errors"
"io"
"meteor-server/pkg/core"
"meteor-server/pkg/db"
"net/http"
"strconv"
"strings"
"sync"
"time"
)

type Stats struct {
Expand All @@ -15,6 +24,22 @@ type Stats struct {
Downloads int `json:"downloads"`
OnlinePlayers int `json:"onlinePlayers"`
OnlineUUIDs int `json:"onlineUUIDs"`

Builds map[string]int `json:"builds"`
}

var builds map[string]int

func InitStats() {
t := time.NewTicker(time.Minute)

go func() {
for {
builds = getBuildNumbers()

<-t.C
}
}()
}

func StatsHandler(w http.ResponseWriter, r *http.Request) {
Expand All @@ -23,7 +48,14 @@ func StatsHandler(w http.ResponseWriter, r *http.Request) {
if date == "" {
g := db.GetGlobal()

core.Json(w, Stats{Config: core.GetConfig(), Date: core.GetDate(), DevBuild: g.DevBuild, Downloads: g.Downloads, OnlinePlayers: GetPlayingCount()})
core.Json(w, Stats{
Config: core.GetConfig(),
Date: core.GetDate(),
DevBuild: g.DevBuild,
Downloads: g.Downloads,
OnlinePlayers: GetPlayingCount(),
Builds: builds,
})
} else {
stats, err := db.GetJoinStats(date)

Expand All @@ -35,3 +67,147 @@ func StatsHandler(w http.ResponseWriter, r *http.Request) {
core.Json(w, stats)
}
}

func RecheckMavenHandler(w http.ResponseWriter, _ *http.Request) {
builds = getBuildNumbers()

core.Json(w, struct{}{})
}

// Maven

type MavenSnapshotVersion struct {
Extension string `xml:"extension"`
Classifier string `xml:"classifier"`
Value string `xml:"value"`
}

type MavenVersioning struct {
Versions []string `xml:"versions>version"`
SnapshotVersions []MavenSnapshotVersion `xml:"snapshotVersions>snapshotVersion"`
}

type MavenMetadata struct {
Versioning MavenVersioning `xml:"versioning"`
}

type FabricMod struct {
Version string `json:"version"`
}

func getBuildNumbers() map[string]int {
builds := make(map[string]int)

res, err := http.Get("https://maven.meteordev.org/snapshots/meteordevelopment/meteor-client/maven-metadata.xml")
if err != nil {
return builds
}

var metadata MavenMetadata
err = xml.NewDecoder(res.Body).Decode(&metadata)
if err != nil {
return builds
}

mutex := sync.Mutex{}
group := sync.WaitGroup{}

for _, version := range metadata.Versioning.Versions {
version := version
group.Add(1)

go func() {
i := strings.IndexRune(version, '-')
mcVersion := version[:i]

if !strings.HasPrefix(mcVersion, "0") {
build, err := getBuildNumber(version)

if err == nil {
mutex.Lock()
builds[mcVersion] = build
mutex.Unlock()
}
}

group.Done()
}()
}

group.Wait()

return builds
}

func getBuildNumber(version string) (int, error) {
res, err := http.Get("https://maven.meteordev.org/snapshots/meteordevelopment/meteor-client/" + version + "/maven-metadata.xml")
if err != nil {
return -1, err
}

//goland:noinspection GoUnhandledErrorResult
defer res.Body.Close()

var metadata MavenMetadata
err = xml.NewDecoder(res.Body).Decode(&metadata)
if err != nil {
return -1, err
}

var filename = ""

for _, version := range metadata.Versioning.SnapshotVersions {
if version.Classifier == "" && version.Extension == "jar" {
filename = "meteor-client-" + version.Value + ".jar"
break
}
}

res, err = http.Get("https://maven.meteordev.org/snapshots/meteordevelopment/meteor-client/" + version + "/" + filename)
if err != nil {
return -1, err
}

//goland:noinspection GoUnhandledErrorResult
defer res.Body.Close()

body, err := io.ReadAll(res.Body)
if err != nil {
return -1, err
}

jar, err := zip.NewReader(bytes.NewReader(body), int64(len(body)))
if err != nil {
return -1, err
}

var mod FabricMod

for _, file := range jar.File {
if file.Name == "fabric.mod.json" {
reader, err := file.Open()
if err != nil {
continue
}

_ = json.NewDecoder(reader).Decode(&mod)

_ = reader.Close()

break
}
}

if mod.Version != "" {
i := strings.IndexRune(mod.Version, '-')

build, err := strconv.ParseInt(mod.Version[i+1:], 10, 32)
if err != nil {
return -1, err
}

return int(build), nil
}

return -1, errors.New("unknown build")
}
3 changes: 3 additions & 0 deletions pkg/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ func Main() {
}
}()

api.InitStats()

// Middlewares
r.Use(middleware.RealIP)

Expand Down Expand Up @@ -77,6 +79,7 @@ func Main() {
r.Get("/capeowners", api.CapeOwnersHandler)

r.Post("/uploadDevBuild", auth.TokenAuth(api.UploadDevBuildHandler))
r.Post("/recheckMaven", auth.TokenAuth(api.RecheckMavenHandler))

// /api/account
r.Route("/account", func(r chi.Router) {
Expand Down

0 comments on commit 25238f7

Please sign in to comment.