From 3004676239871759053361536566a9d6274f4307 Mon Sep 17 00:00:00 2001 From: nightnai Date: Wed, 2 Sep 2026 18:16:35 +0800 Subject: [PATCH] write base server --- .env.example | 0 db/db.go | 47 ++++++++++++++++++++++++++++++++++ gen/gen.go | 45 ++++++++++++++++++++++++++++++++ go.mod | 24 +++++++++++++++++ go.sum | 37 +++++++++++++++++++++++++++ main.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++ routes/registry.go | 17 ++++++++++++ 7 files changed, 234 insertions(+) create mode 100644 .env.example create mode 100644 db/db.go create mode 100644 gen/gen.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 routes/registry.go diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..e69de29 diff --git a/db/db.go b/db/db.go new file mode 100644 index 0000000..cb55600 --- /dev/null +++ b/db/db.go @@ -0,0 +1,47 @@ +package db + +import ( + "encoding/json" + "os" + "sync" +) + +type Database struct { + Users map[string][]map[string]any `json:"Users"` +} + +var ( + DB Database + mu sync.Mutex + path = "db.json" +) + +func Init(servers []string) { + data, err := os.ReadFile(path) + if err == nil { + json.Unmarshal(data, &DB) + } + + if DB.Users == nil { + DB.Users = make(map[string][]map[string]any) + } + + for _, s := range servers { + if DB.Users[s] == nil { + DB.Users[s] = []map[string]any{} + } + } + + Save() +} + +func Save() { + mu.Lock() + defer mu.Unlock() + + data, _ := json.MarshalIndent(DB, "", " ") + + tmp := path + ".tmp" + os.WriteFile(tmp, data, 0644) + os.Rename(tmp, path) +} diff --git a/gen/gen.go b/gen/gen.go new file mode 100644 index 0000000..0d5d0b5 --- /dev/null +++ b/gen/gen.go @@ -0,0 +1,45 @@ +//go:build ignore + +package main + +import ( + "os" + "path/filepath" + "strings" + "text/template" +) + +const tmpl = `// Code generated by gen/gen.go — DO NOT EDIT +package main + +import ( +{{- range .}} + _ "{{.}}" +{{- end}} +) +` + +func main() { + var packages []string + moduleName := "bdgrp_go" + + filepath.WalkDir("routes", func(path string, d os.DirEntry, err error) error { + if err != nil || !d.IsDir() || path == "routes" { + return nil + } + + entries, _ := os.ReadDir(path) + for _, e := range entries { + if !e.IsDir() && strings.HasSuffix(e.Name(), ".go") { + pkg := moduleName + "/" + filepath.ToSlash(path) + packages = append(packages, pkg) + break + } + } + return nil + }) + + f, _ := os.Create("routes_gen.go") + defer f.Close() + template.Must(template.New("").Parse(tmpl)).Execute(f, packages) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..a805955 --- /dev/null +++ b/go.mod @@ -0,0 +1,24 @@ +module bdgrp_go + +go 1.27.1 + +require ( + github.com/gofiber/fiber/v2 v2.52.15 + github.com/gookit/color v1.6.1 + github.com/joho/godotenv v1.5.1 +) + +require ( + github.com/andybalholm/brotli v1.1.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasthttp v1.51.0 // indirect + github.com/valyala/tcplisten v1.0.0 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + golang.org/x/sys v0.30.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..0ff6943 --- /dev/null +++ b/go.sum @@ -0,0 +1,37 @@ +github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= +github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +github.com/gofiber/fiber/v2 v2.52.15 h1:Cov1uKeVPyu9q0jSrN60W+A8XNX+/WK8J7cy5osHLIk= +github.com/gofiber/fiber/v2 v2.52.15/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gookit/assert v0.1.1 h1:lh3GcawXe/p+cU7ESTZ5Ui3Sm/x8JWpIis4/1aF0mY0= +github.com/gookit/assert v0.1.1/go.mod h1:jS5bmIVQZTIwk42uXl4lyj4iaaxx32tqH16CFj0VX2E= +github.com/gookit/color v1.6.1 h1:KoTnDxJPRgrL0SoX0f8rCFg2zI0t4E3GZZBMo2nN8LU= +github.com/gookit/color v1.6.1/go.mod h1:9ACFc7/1IpHGBW8RwuDm/0YEnhg3dwwXpoMsmtyHfjs= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= +github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= +github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/main.go b/main.go index 8b13789..825a725 100644 --- a/main.go +++ b/main.go @@ -1 +1,65 @@ +//go:generate go run gen/gen.go +package main + +import ( + "log" + "os" + "regexp" + "slices" + + "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/middleware/logger" + "github.com/gookit/color" + "github.com/joho/godotenv" + + "bdgrp_go/db" + "bdgrp_go/routes" +) + +const PORT = ":8482" + +var servers = []string{"TW", "JP", "GL", "CN"} + +func main() { + if _, err := os.Stat(".env"); os.IsNotExist(err) { + log.Fatal("Error: .env not found.") + } + godotenv.Load() + + server := os.Getenv("SERVER") + valid := slices.Contains(servers, server) + if !valid { + log.Fatal("Error: Unknown Server.") + } + + for _, s := range servers { + os.MkdirAll("resp/"+s, 0755) + } + + db.Init(servers) + + app := fiber.New(fiber.Config{ + StrictRouting: true, + ETag: false, + }) + + app.Use(logger.New()) + + re := regexp.MustCompile(`/+`) + app.Use(func(c *fiber.Ctx) error { + c.Path(re.ReplaceAllString(c.Path(), "/")) + return c.Next() + }) + + routes.LoadAll(app) + + app.Get("/", func(c *fiber.Ctx) error { + return c.SendString(os.Getenv("SERVER")) + }) + + log.Printf("Running on %s", PORT) + color.HEX("#00AABB").Printf("Server: %s\n", server) + + app.Listen(PORT) +} diff --git a/routes/registry.go b/routes/registry.go new file mode 100644 index 0000000..32f084e --- /dev/null +++ b/routes/registry.go @@ -0,0 +1,17 @@ +package routes + +import "github.com/gofiber/fiber/v2" + +type RouteHandler func(*fiber.App) + +var registry []RouteHandler + +func Register(handler RouteHandler) { + registry = append(registry, handler) +} + +func LoadAll(app *fiber.App) { + for _, handler := range registry { + handler(app) + } +}