From fe8ba74c5fd9efce7e6afb465984b3471460fc36 Mon Sep 17 00:00:00 2001 From: nightnai Date: Fri, 4 Sep 2026 18:08:20 +0800 Subject: [PATCH] changed param logic & add more routes --- master/master.go | 65 +++++++++++++++++++ pbutil/pbutil.go | 11 ++++ .../api/acdm/{userid.go => param_userid.go} | 5 +- routes/api/application.go | 1 - routes/api/cleanupinfo.go | 1 - routes/api/information/overview.go | 1 - routes/api/missionreward.map.go | 49 ++++++++++++++ routes/api/multiroom.go | 21 ++++++ routes/api/suite/master.go | 55 ++++++++++++++++ routes/api/system/config.go | 1 - routes/api/track.go | 21 ++++++ routes/api/validation/ngword.go | 38 +++++++++++ routes/helper.go | 10 ++- 13 files changed, 267 insertions(+), 12 deletions(-) create mode 100644 master/master.go rename routes/api/acdm/{userid.go => param_userid.go} (71%) create mode 100644 routes/api/missionreward.map.go create mode 100644 routes/api/multiroom.go create mode 100644 routes/api/suite/master.go create mode 100644 routes/api/track.go create mode 100644 routes/api/validation/ngword.go diff --git a/master/master.go b/master/master.go new file mode 100644 index 0000000..8b7d07e --- /dev/null +++ b/master/master.go @@ -0,0 +1,65 @@ +package master + +import ( + "bdgrp_go/pbutil" + "bdgrp_go/utils" + "bytes" + "compress/bzip2" + "io" + "os" + "path/filepath" + "sync" +) + +var ( + cache map[string]any + mu sync.RWMutex +) + +func GetMaster() map[string]any { + mu.RLock() + defer mu.RUnlock() + if cache != nil { + return cache + } + mu.RUnlock() + return ReloadMaster() +} + +func ReloadMaster() map[string]any { + server := os.Getenv("SERVER") + filePath := filepath.Join("resp", server, "suitemaster.bz2") + + fileBuffer, err := os.ReadFile(filePath) + if err != nil { + return cache + } + + decrypted, err := utils.Decrypt(fileBuffer) + if err != nil { + return cache + } + + // bzip2 解壓 + decompressed, err := io.ReadAll(bzip2.NewReader(bytes.NewReader(decrypted))) + if err != nil { + return cache + } + + // protobuf decode → JSON map + msg, err := pbutil.Decode("SuiteMasterGetResponse", decompressed) + if err != nil { + return cache + } + + result, err := pbutil.ToMap(msg) + if err != nil { + return cache + } + + mu.Lock() + cache = result + mu.Unlock() + + return cache +} diff --git a/pbutil/pbutil.go b/pbutil/pbutil.go index 706458c..c5fe126 100644 --- a/pbutil/pbutil.go +++ b/pbutil/pbutil.go @@ -52,3 +52,14 @@ func Encode(message string, data map[string]any) ([]byte, error) { return proto.Marshal(msg) } + +func ToMap(msg proto.Message) (map[string]any, error) { + jsonBytes, err := protojson.Marshal(msg) + if err != nil { + return nil, err + } + + var result map[string]any + json.Unmarshal(jsonBytes, &result) + return result, nil +} diff --git a/routes/api/acdm/userid.go b/routes/api/acdm/param_userid.go similarity index 71% rename from routes/api/acdm/userid.go rename to routes/api/acdm/param_userid.go index a86ab24..5fe563d 100644 --- a/routes/api/acdm/userid.go +++ b/routes/api/acdm/param_userid.go @@ -9,9 +9,10 @@ import ( ) func init() { + path := routes.PathOf() routes.Register(func(app *fiber.App) { - app.Get("/api/acdm/:userid", acdm) - fmt.Println("Loaded: /api/acdm/:userid") + app.Post(path, acdm) + fmt.Println("Loaded:", path) }) } diff --git a/routes/api/application.go b/routes/api/application.go index dcc92a0..0ab574c 100644 --- a/routes/api/application.go +++ b/routes/api/application.go @@ -41,7 +41,6 @@ func application(c *fiber.Ctx) error { url := fmt.Sprintf("%s/api/application", upstream.BaseUrl()) data, err := upstream.Fetch(url, headers) if err != nil { - // fallback 到 cache data, err = os.ReadFile(cachePath) if err != nil { return c.Status(500).SendString("no cache available") diff --git a/routes/api/cleanupinfo.go b/routes/api/cleanupinfo.go index d677548..2371ff7 100644 --- a/routes/api/cleanupinfo.go +++ b/routes/api/cleanupinfo.go @@ -41,7 +41,6 @@ func cleanupinfo(c *fiber.Ctx) error { url := fmt.Sprintf("%s/api/application", upstream.BaseUrl()) data, err := upstream.Fetch(url, headers) if err != nil { - // fallback 到 cache data, err = os.ReadFile(cachePath) if err != nil { return c.Status(500).SendString("no cache available") diff --git a/routes/api/information/overview.go b/routes/api/information/overview.go index eb9ab02..0ee7f45 100644 --- a/routes/api/information/overview.go +++ b/routes/api/information/overview.go @@ -41,7 +41,6 @@ func application(c *fiber.Ctx) error { url := fmt.Sprintf("%s/api/information/overview", upstream.BaseUrl()) data, err := upstream.Fetch(url, headers) if err != nil { - // fallback 到 cache data, err = os.ReadFile(cachePath) if err != nil { return c.Status(500).SendString("no cache available") diff --git a/routes/api/missionreward.map.go b/routes/api/missionreward.map.go new file mode 100644 index 0000000..0c9962b --- /dev/null +++ b/routes/api/missionreward.map.go @@ -0,0 +1,49 @@ +package api + +import ( + "fmt" + "os" + "path/filepath" + + "bdgrp_go/routes" + "bdgrp_go/routes/upstream" + + "github.com/gofiber/fiber/v2" +) + +func init() { + path := routes.PathOf() + routes.Register(func(app *fiber.App) { + app.Get(path, rewardmap) + fmt.Println("Loaded:", path) + }) +} + +func rewardmap(c *fiber.Ctx) error { + server := os.Getenv("SERVER") + cachePath := filepath.Join("resp", server, "config.binpb") + + headers := map[string]string{ + "User-Agent": c.Get("User-Agent"), + "Content-Type": c.Get("Content-Type"), + "Accept": c.Get("Accept"), + "Accept-Encoding": c.Get("Accept-Encoding"), + "x-clientversion": c.Get("x-clientversion"), + "x-platformid": c.Get("x-platformid"), + "x-deviceid": c.Get("x-deviceid"), + "x-channelid": c.Get("x-channelid"), + "x-clientplatform": c.Get("x-clientplatform"), + } + + data, err := upstream.Fetch("https://l3-prod-all-bd.bilibiligame.net/api/missionreward.map", headers) + if err != nil { + data, err = os.ReadFile(cachePath) + if err != nil { + return c.Status(500).SendString("no cache available") + } + } else { + os.WriteFile(cachePath, data, 0644) + } + + return c.Send(data) +} diff --git a/routes/api/multiroom.go b/routes/api/multiroom.go new file mode 100644 index 0000000..49ff1b9 --- /dev/null +++ b/routes/api/multiroom.go @@ -0,0 +1,21 @@ +package api + +import ( + "fmt" + + "bdgrp_go/routes" + + "github.com/gofiber/fiber/v2" +) + +func init() { + path := routes.PathOf() + routes.Register(func(app *fiber.App) { + app.Post(path, multiroom) + fmt.Println("Loaded:", path) + }) +} + +func multiroom(c *fiber.Ctx) error { + return c.SendString("") +} diff --git a/routes/api/suite/master.go b/routes/api/suite/master.go new file mode 100644 index 0000000..7ba0a91 --- /dev/null +++ b/routes/api/suite/master.go @@ -0,0 +1,55 @@ +package suite + +import ( + mastermanager "bdgrp_go/master" + "fmt" + "os" + "path/filepath" + + "bdgrp_go/routes" + "bdgrp_go/routes/upstream" + + "github.com/gofiber/fiber/v2" +) + +func init() { + path := routes.PathOf() + routes.Register(func(app *fiber.App) { + app.Get(path, master) + fmt.Println("Loaded:", path) + }) +} + +func master(c *fiber.Ctx) error { + server := os.Getenv("SERVER") + cachePath := filepath.Join("resp", server, "suitemaster.bz2") + + headers := map[string]string{ + "User-Agent": c.Get("User-Agent"), + "Content-Type": c.Get("Content-Type"), + "Accept": c.Get("Accept"), + "Accept-Encoding": c.Get("Accept-Encoding"), + "x-clientversion": c.Get("x-clientversion"), + } + + if server == "CN" { + headers["x-platformid"] = c.Get("x-platformid") + headers["x-deviceid"] = c.Get("x-deviceid") + headers["x-channelid"] = c.Get("x-channelid") + headers["x-clientplatform"] = c.Get("x-clientplatform") + } + + url := fmt.Sprintf("%s/api/suite/master", upstream.BaseUrl()) + data, err := upstream.Fetch(url, headers) + if err != nil { + data, err = os.ReadFile(cachePath) + if err != nil { + return c.Status(500).SendString("no cache available") + } + } else { + os.WriteFile(cachePath, data, 0644) + mastermanager.ReloadMaster() + } + + return c.Send(data) +} diff --git a/routes/api/system/config.go b/routes/api/system/config.go index 3f3591c..3c6b5ae 100644 --- a/routes/api/system/config.go +++ b/routes/api/system/config.go @@ -37,7 +37,6 @@ func config(c *fiber.Ctx) error { data, err := upstream.Fetch("https://l3-prod-all-bd.bilibiligame.net/api/system/config", headers) if err != nil { - // fallback 到 cache data, err = os.ReadFile(cachePath) if err != nil { return c.Status(500).SendString("no cache available") diff --git a/routes/api/track.go b/routes/api/track.go new file mode 100644 index 0000000..e0393b4 --- /dev/null +++ b/routes/api/track.go @@ -0,0 +1,21 @@ +package api + +import ( + "fmt" + + "bdgrp_go/routes" + + "github.com/gofiber/fiber/v2" +) + +func init() { + path := routes.PathOf() + routes.Register(func(app *fiber.App) { + app.Get(path, track) + fmt.Println("Loaded:", path) + }) +} + +func track(c *fiber.Ctx) error { + return c.SendString("") +} diff --git a/routes/api/validation/ngword.go b/routes/api/validation/ngword.go new file mode 100644 index 0000000..ceb7590 --- /dev/null +++ b/routes/api/validation/ngword.go @@ -0,0 +1,38 @@ +package validation + +import ( + "bdgrp_go/pbutil" + "bdgrp_go/routes" + "bdgrp_go/utils" + "fmt" + + "github.com/gofiber/fiber/v2" +) + +func init() { + path := routes.PathOf() + routes.Register(func(app *fiber.App) { + app.Post(path, ngword) + fmt.Println("Loaded:", path) + }) +} + +func ngword(c *fiber.Ctx) error { + data := map[string]any{ + "isBadWord": false, + } + + encoded, err := pbutil.Encode("NgWordResponse", data) + + if err != nil { + fmt.Println(err) + return c.Status(500).SendString("") + } + + encrypted, err := utils.Encrypt(encoded) + if err != nil { + fmt.Println(err) + } + + return c.Send(encrypted) +} diff --git a/routes/helper.go b/routes/helper.go index 7f801c7..19ec9bc 100644 --- a/routes/helper.go +++ b/routes/helper.go @@ -1,6 +1,7 @@ package routes import ( + "regexp" "runtime" "strings" ) @@ -8,15 +9,12 @@ import ( func PathOf() string { _, file, _, _ := runtime.Caller(1) - // 取 routes/ 之後的部分 idx := strings.Index(file, "routes/") - if idx == -1 { - return "/" - } path := file[idx+len("routes"):] - - // 去掉 .go path = strings.TrimSuffix(path, ".go") + re := regexp.MustCompile(`param_(\w+)`) + path = re.ReplaceAllString(path, ":$1") + return path }