Initial commit

This commit is contained in:
MrFastwind
2026-07-06 01:29:23 +02:00
commit b853aead8c
48 changed files with 5822 additions and 0 deletions

105
backend/cmd/server/main.go Normal file
View File

@@ -0,0 +1,105 @@
package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"path/filepath"
"syscall"
"time"
"arma3-web-server/internal/api"
"arma3-web-server/internal/services"
"github.com/gin-gonic/gin"
)
func main() {
dataDir := mustAbs(getEnv("DATA_DIR", filepath.Join("data")))
serverfileDir := mustAbs(getEnv("SERVERFILE_DIR", "serverfiles"))
modsDir := mustAbs(getEnv("MODS_DIR", "serverfiles/mods"))
cfgDir := mustAbs(getEnv("CFG_DIR", "serverfiles/cfg"))
profilesDir := mustAbs(getEnv("PROFILES_DIR", "serverfiles/profiles"))
listen := getEnv("LISTEN", ":8080")
frontendDir := mustAbs(getEnv("FRONTEND_DIR", filepath.Join("..", "frontend", "dist")))
log.Printf("data dir: %s", dataDir)
log.Printf("serverfile dir: %s", serverfileDir)
log.Printf("mods dir: %s", modsDir)
log.Printf("cfg dir: %s", cfgDir)
log.Printf("profiles dir: %s", profilesDir)
log.Printf("listening on %s", listen)
dirs := []string{
dataDir, filepath.Join(dataDir, "modlists"),
serverfileDir, modsDir, cfgDir, profilesDir,
filepath.Join(serverfileDir, "steamapps", "workshop", "content", "107410"),
}
for _, dir := range dirs {
if err := os.MkdirAll(dir, 0755); err != nil {
log.Fatalf("mkdir %s: %v", dir, err)
}
}
settings := services.NewSettingsManager(dataDir)
streamer := services.NewLogStreamer()
configMgr := services.NewConfigManager(cfgDir)
modlistMgr := services.NewModlistManager(dataDir)
process := services.NewProcessManager(serverfileDir, modsDir, cfgDir, profilesDir, settings, modlistMgr, configMgr, streamer)
steamcmd := services.NewSteamCmdManager(serverfileDir, streamer)
r := gin.Default()
if fi, err := os.Stat(frontendDir); err == nil && fi.IsDir() {
r.Static("/assets", filepath.Join(frontendDir, "assets"))
r.StaticFile("/favicon.ico", filepath.Join(frontendDir, "favicon.ico"))
r.NoRoute(func(c *gin.Context) {
c.File(filepath.Join(frontendDir, "index.html"))
})
log.Printf("serving frontend from %s", frontendDir)
}
handler := api.New(settings, configMgr, modlistMgr, process, steamcmd, streamer, serverfileDir, modsDir, cfgDir, profilesDir)
handler.SetupRoutes(r)
log.Printf("starting server on %s", listen)
srv := &http.Server{Addr: listen, Handler: r}
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("server: %v", err)
}
}()
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Print("shutting down server...")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatalf("server forced shutdown: %v", err)
}
log.Print("server exited")
}
func mustAbs(p string) string {
a, err := filepath.Abs(p)
if err != nil {
log.Fatalf("abs %s: %v", p, err)
}
return a
}
func getEnv(key, fallback string) string {
if v := os.Getenv(key); v != "" {
return v
}
return fallback
}