Compare commits
5 Commits
e79282d8cc
...
5743a36f51
| Author | SHA1 | Date | |
|---|---|---|---|
| 5743a36f51 | |||
| 4688c10585 | |||
| fe8ba74c5f | |||
| a1569590bc | |||
| 3004676239 |
1
.env.example
Normal file
1
.env.example
Normal file
@@ -0,0 +1 @@
|
||||
SERVER=TW
|
||||
68
db/db.go
Normal file
68
db/db.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Database struct {
|
||||
Users map[string][]map[string]any `json:"Users"`
|
||||
}
|
||||
|
||||
type UserIdType string
|
||||
|
||||
const (
|
||||
UserId UserIdType = "userId"
|
||||
Bid UserIdType = "bid"
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
func FindUser(id string, idType ...UserIdType) map[string]any {
|
||||
key := UserId
|
||||
if len(idType) > 0 {
|
||||
key = idType[0]
|
||||
}
|
||||
for _, user := range DB.Users[os.Getenv("SERVER")] {
|
||||
if fmt.Sprintf("%v", user[string(key)]) == id {
|
||||
return user
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
50
gen/gen.go
Normal file
50
gen/gen.go
Normal file
@@ -0,0 +1,50 @@
|
||||
//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() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(d.Name(), ".go") {
|
||||
return nil
|
||||
}
|
||||
|
||||
pkg := moduleName + "/" + filepath.ToSlash(filepath.Dir(path))
|
||||
|
||||
for _, p := range packages {
|
||||
if p == pkg {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
packages = append(packages, pkg)
|
||||
return nil
|
||||
})
|
||||
|
||||
f, _ := os.Create("routes_gen.go")
|
||||
defer f.Close()
|
||||
template.Must(template.New("").Parse(tmpl)).Execute(f, packages)
|
||||
}
|
||||
25
go.mod
Normal file
25
go.mod
Normal file
@@ -0,0 +1,25 @@
|
||||
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
|
||||
google.golang.org/protobuf v1.36.12
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
41
go.sum
Normal file
41
go.sum
Normal file
@@ -0,0 +1,41 @@
|
||||
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/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
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=
|
||||
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
|
||||
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
64
main.go
64
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)
|
||||
}
|
||||
|
||||
58
master/master.go
Normal file
58
master/master.go
Normal file
@@ -0,0 +1,58 @@
|
||||
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
|
||||
}
|
||||
|
||||
decompressed, err := io.ReadAll(bzip2.NewReader(bytes.NewReader(decrypted)))
|
||||
if err != nil {
|
||||
return cache
|
||||
}
|
||||
|
||||
result, err := pbutil.Decode("SuiteMasterGetResponse", decompressed)
|
||||
if err != nil {
|
||||
return cache
|
||||
}
|
||||
|
||||
mu.Lock()
|
||||
cache = result
|
||||
mu.Unlock()
|
||||
|
||||
return cache
|
||||
}
|
||||
4681
mission.json
Normal file
4681
mission.json
Normal file
File diff suppressed because it is too large
Load Diff
48485
pastEvents/CN.json
Normal file
48485
pastEvents/CN.json
Normal file
File diff suppressed because it is too large
Load Diff
47043
pastEvents/GL.json
Normal file
47043
pastEvents/GL.json
Normal file
File diff suppressed because it is too large
Load Diff
50993
pastEvents/JP.json
Normal file
50993
pastEvents/JP.json
Normal file
File diff suppressed because it is too large
Load Diff
48623
pastEvents/TW.json
Normal file
48623
pastEvents/TW.json
Normal file
File diff suppressed because it is too large
Load Diff
65
pbutil/pbutil.go
Normal file
65
pbutil/pbutil.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package pbutil
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
_ "bdgrp_go/proto/cn"
|
||||
_ "bdgrp_go/proto/gl"
|
||||
_ "bdgrp_go/proto/jp"
|
||||
_ "bdgrp_go/proto/tw"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
)
|
||||
|
||||
func fullName(message string) protoreflect.FullName {
|
||||
server := strings.ToLower(os.Getenv("SERVER"))
|
||||
// twdori.proto.ce.UserLogin
|
||||
return protoreflect.FullName(fmt.Sprintf("%sdori.proto.ce.%s", server, message))
|
||||
}
|
||||
|
||||
func Decode(message string, data []byte) (map[string]any, error) {
|
||||
mt, err := protoregistry.GlobalTypes.FindMessageByName(fullName(message))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("message %s not found", message)
|
||||
}
|
||||
|
||||
msg := mt.New().Interface()
|
||||
if err := proto.Unmarshal(data, msg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ToMap(msg)
|
||||
}
|
||||
|
||||
func Encode(message string, data map[string]any) ([]byte, error) {
|
||||
mt, err := protoregistry.GlobalTypes.FindMessageByName(fullName(message))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("message %s not found", message)
|
||||
}
|
||||
|
||||
msg := mt.New().Interface()
|
||||
// map → json → proto
|
||||
jsonBytes, _ := json.Marshal(data)
|
||||
if err := protojson.Unmarshal(jsonBytes, msg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
135797
proto/cn/cn.go
Normal file
135797
proto/cn/cn.go
Normal file
File diff suppressed because it is too large
Load Diff
125786
proto/gl/gl.go
Normal file
125786
proto/gl/gl.go
Normal file
File diff suppressed because it is too large
Load Diff
129339
proto/jp/jp.go
Normal file
129339
proto/jp/jp.go
Normal file
File diff suppressed because it is too large
Load Diff
129280
proto/tw/tw.go
Normal file
129280
proto/tw/tw.go
Normal file
File diff suppressed because it is too large
Load Diff
21
routes/api/acdm/param_userid.go
Normal file
21
routes/api/acdm/param_userid.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package acdm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"bdgrp_go/routes"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Post(path, acdm)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func acdm(c *fiber.Ctx) error {
|
||||
return c.SendString("")
|
||||
}
|
||||
53
routes/api/application.go
Normal file
53
routes/api/application.go
Normal file
@@ -0,0 +1,53 @@
|
||||
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, application)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func application(c *fiber.Ctx) error {
|
||||
server := os.Getenv("SERVER")
|
||||
cachePath := filepath.Join("resp", server, "application.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"),
|
||||
}
|
||||
|
||||
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/application", 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)
|
||||
}
|
||||
|
||||
return c.Send(data)
|
||||
}
|
||||
53
routes/api/cleanupinfo.go
Normal file
53
routes/api/cleanupinfo.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"bdgrp_go/routes/upstream"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"bdgrp_go/routes"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Get(path, cleanupinfo)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func cleanupinfo(c *fiber.Ctx) error {
|
||||
server := os.Getenv("SERVER")
|
||||
cachePath := filepath.Join("resp", server, "cleanupinfo.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"),
|
||||
}
|
||||
|
||||
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/application", 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)
|
||||
}
|
||||
|
||||
return c.Send(data)
|
||||
}
|
||||
53
routes/api/information/overview.go
Normal file
53
routes/api/information/overview.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package information
|
||||
|
||||
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, application)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func application(c *fiber.Ctx) error {
|
||||
server := os.Getenv("SERVER")
|
||||
cachePath := filepath.Join("resp", server, "overview.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"),
|
||||
}
|
||||
|
||||
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/information/overview", 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)
|
||||
}
|
||||
|
||||
return c.Send(data)
|
||||
}
|
||||
49
routes/api/missionreward.map.go
Normal file
49
routes/api/missionreward.map.go
Normal file
@@ -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)
|
||||
}
|
||||
21
routes/api/multiroom.go
Normal file
21
routes/api/multiroom.go
Normal file
@@ -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("")
|
||||
}
|
||||
21
routes/api/multiroom/create/param_userid.go
Normal file
21
routes/api/multiroom/create/param_userid.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package create
|
||||
|
||||
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("")
|
||||
}
|
||||
58
routes/api/suite/master.go
Normal file
58
routes/api/suite/master.go
Normal file
@@ -0,0 +1,58 @@
|
||||
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()
|
||||
}
|
||||
|
||||
c.Set("Content-Length", fmt.Sprintf("%d", len(data)))
|
||||
c.Set("Content-Type", "application/octet-stream")
|
||||
c.Set("X-Encoding", "bzip2")
|
||||
return c.Send(data)
|
||||
}
|
||||
1078
routes/api/suite/user/param_userid.go
Normal file
1078
routes/api/suite/user/param_userid.go
Normal file
File diff suppressed because it is too large
Load Diff
120
routes/api/suite/user/param_userid/area.go
Normal file
120
routes/api/suite/user/param_userid/area.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package param_userid
|
||||
|
||||
import (
|
||||
"bdgrp_go/db"
|
||||
"bdgrp_go/master"
|
||||
"bdgrp_go/pbutil"
|
||||
"bdgrp_go/routes"
|
||||
"bdgrp_go/utils"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Get(path, get)
|
||||
app.Put(path, put)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func get(c *fiber.Ctx) error {
|
||||
userid := c.Params("userid")
|
||||
user := db.FindUser(userid)
|
||||
m := master.GetMaster()
|
||||
|
||||
areaMap := m["masterAreaMap"].(map[string]any)["entries"].(map[string]any)
|
||||
actionSetMap := m["masterActionSetMap"].(map[string]any)["entries"].(map[string]any)
|
||||
seasonMap := m["masterSeasonBasicMap"].(map[string]any)["entries"].(map[string]any)
|
||||
|
||||
// userAreaMap
|
||||
resultEntries := map[string]any{}
|
||||
for areaId, v := range areaMap {
|
||||
area := v.(map[string]any)
|
||||
if area["areaType"] != "common" {
|
||||
continue
|
||||
}
|
||||
|
||||
// filter actionSets by areaId
|
||||
var available []any
|
||||
for _, a := range actionSetMap {
|
||||
action := a.(map[string]any)
|
||||
if fmt.Sprintf("%v", action["areaId"]) == areaId {
|
||||
available = append(available, action["actionSetId"])
|
||||
}
|
||||
}
|
||||
|
||||
// shuffle + slice
|
||||
rand.Shuffle(len(available), func(i, j int) {
|
||||
available[i], available[j] = available[j], available[i]
|
||||
})
|
||||
count := min(rand.Intn(3)+1, len(available))
|
||||
|
||||
actionSets := make([]any, 0)
|
||||
for _, id := range available[:count] {
|
||||
actionSets = append(actionSets, map[string]any{
|
||||
"actionSetId": id,
|
||||
"status": "already_read",
|
||||
})
|
||||
}
|
||||
|
||||
// areaItems
|
||||
areaItems := []any{}
|
||||
if user["areaItems"] != nil {
|
||||
items := user["areaItems"].(map[string]any)
|
||||
if v, ok := items[areaId]; ok {
|
||||
areaItems = v.([]any)
|
||||
}
|
||||
}
|
||||
|
||||
resultEntries[areaId] = map[string]any{
|
||||
"areaId": areaId,
|
||||
"actionSets": actionSets,
|
||||
"areaItemIds": areaItems,
|
||||
}
|
||||
}
|
||||
|
||||
// current season
|
||||
now := time.Now().UnixMilli()
|
||||
var seasonId any
|
||||
for _, v := range seasonMap {
|
||||
s := v.(map[string]any)
|
||||
startAt := int64(s["startAt"].(float64))
|
||||
endAt := int64(s["endAt"].(float64))
|
||||
if startAt <= now && now < endAt {
|
||||
seasonId = s["seasonId"]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
data := map[string]any{
|
||||
"userAreaMap": map[string]any{
|
||||
"entries": resultEntries,
|
||||
},
|
||||
"backstage": nil,
|
||||
"userSeason": map[string]any{
|
||||
"seasonId": seasonId,
|
||||
},
|
||||
"userLotterySelectedBackstageTalkSetMap": nil,
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("UserAreaCharacterResponse", data)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
|
||||
func put(c *fiber.Ctx) error {
|
||||
return c.SendStatus(200)
|
||||
}
|
||||
66
routes/api/suite/user/param_userid/dailylivereward.go
Normal file
66
routes/api/suite/user/param_userid/dailylivereward.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package param_userid
|
||||
|
||||
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.Put(path, handle)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func handle(c *fiber.Ctx) error {
|
||||
userid := c.Params("userid")
|
||||
|
||||
data := map[string]any{
|
||||
"updateResources": map[string]any{
|
||||
"updatedBandDeckRankList": map[string]any{},
|
||||
"userDailyLive": map[string]any{
|
||||
"lastClearedAt": 1770992661000,
|
||||
"liveStartedAt": 1770992661000,
|
||||
"getDailyLiveRewardId": 6,
|
||||
},
|
||||
"userDailyLiveTotalRewardHistory": map[string]any{
|
||||
"userId": userid,
|
||||
"dailyLiveId": 8,
|
||||
"status": "STARTED",
|
||||
"dailyLiveCount": 1,
|
||||
},
|
||||
},
|
||||
"response": map[string]any{
|
||||
"userDailyLive": map[string]any{
|
||||
"lastClearedAt": 1770992661000,
|
||||
"liveStartedAt": 1770992661000,
|
||||
"getDailyLiveRewardId": 6,
|
||||
"dailyPresents": []any{
|
||||
map[string]any{
|
||||
"resourceId": 43,
|
||||
"resourceType": "practice_ticket",
|
||||
"quantity": 1,
|
||||
"lbBonus": 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("SuiteUserDailyLiveClearResponse", data)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
99
routes/api/suite/user/param_userid/deck/param_deckid.go
Normal file
99
routes/api/suite/user/param_userid/deck/param_deckid.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package deck
|
||||
|
||||
import (
|
||||
"bdgrp_go/db"
|
||||
"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.Put(path, deck)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func deck(c *fiber.Ctx) error {
|
||||
decrypted, err := utils.Decrypt(c.Body())
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
decoded, err := pbutil.Decode("EditUserDeckRequest", decrypted)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
userid := c.Params("userid")
|
||||
|
||||
user := db.FindUser(userid)
|
||||
|
||||
decks := user["decks"].([]any)
|
||||
isNew := false
|
||||
var deck map[string]any
|
||||
for _, d := range decks {
|
||||
d := d.(map[string]any)
|
||||
if fmt.Sprintf("%v", d["deckId"]) == c.Params("deckid") {
|
||||
deck = d
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if deck == nil {
|
||||
deck = map[string]any{
|
||||
"deckId": c.Params("deckid"),
|
||||
}
|
||||
isNew = true
|
||||
}
|
||||
|
||||
if v, ok := decoded["member1"].(string); ok && v != "" {
|
||||
deck["member1"] = v
|
||||
}
|
||||
if v, ok := decoded["member2"].(string); ok && v != "" {
|
||||
deck["member2"] = v
|
||||
}
|
||||
if v, ok := decoded["member3"].(string); ok && v != "" {
|
||||
deck["member3"] = v
|
||||
}
|
||||
if v, ok := decoded["member4"].(string); ok && v != "" {
|
||||
deck["member4"] = v
|
||||
}
|
||||
if v, ok := decoded["leader"].(string); ok && v != "" {
|
||||
deck["leader"] = v
|
||||
}
|
||||
|
||||
deck["deckName"] = decoded["deckName"].(string)
|
||||
deck["deckType"] = decoded["deckType"].(string)
|
||||
|
||||
if isNew {
|
||||
user["decks"] = append(user["decks"].([]any), deck)
|
||||
}
|
||||
|
||||
db.Save()
|
||||
|
||||
data := map[string]any{
|
||||
"updateResources": map[string]any{
|
||||
"userDeckList": map[string]any{
|
||||
"entries": user["decks"].([]any),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("EditUserDeckResponse", data)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
|
||||
}
|
||||
48
routes/api/suite/user/param_userid/friend/application.go
Normal file
48
routes/api/suite/user/param_userid/friend/application.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package friend
|
||||
|
||||
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.Get(path, handle)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func handle(c *fiber.Ctx) error {
|
||||
friendDetail := map[string]any{
|
||||
"applicationMap": map[string]any{},
|
||||
"approvalMap": map[string]any{},
|
||||
"friendMap": map[string]any{},
|
||||
"friendLimit": 60,
|
||||
"approvalLimit": 50,
|
||||
"applicationLimit": 50,
|
||||
}
|
||||
|
||||
data := map[string]any{
|
||||
"updateResources": map[string]any{
|
||||
"userFriendRelationDetail": friendDetail,
|
||||
},
|
||||
"userFriendDetail": friendDetail,
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("SuiteUserFriendTopResponse", data)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
16
routes/api/suite/user/param_userid/friend/approval.go
Normal file
16
routes/api/suite/user/param_userid/friend/approval.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package friend
|
||||
|
||||
import (
|
||||
"bdgrp_go/routes"
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Get(path, handle)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
16
routes/api/suite/user/param_userid/friend/friend.go
Normal file
16
routes/api/suite/user/param_userid/friend/friend.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package friend
|
||||
|
||||
import (
|
||||
"bdgrp_go/routes"
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Get(path, handle)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
45
routes/api/suite/user/param_userid/friend/relation.go
Normal file
45
routes/api/suite/user/param_userid/friend/relation.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package friend
|
||||
|
||||
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.Get(path, relation)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func relation(c *fiber.Ctx) error {
|
||||
data := map[string]any{
|
||||
"updateResources": map[string]any{
|
||||
"userFriendRelationDetail": map[string]any{
|
||||
"applicationMap": nil,
|
||||
"approvalMap": nil,
|
||||
"friendMap": nil,
|
||||
"friendLimit": 50,
|
||||
"approvalLimit": 50,
|
||||
"applicationLimit": 50,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("SuiteUserFriendRelationResponse", data)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
20
routes/api/suite/user/param_userid/index.go
Normal file
20
routes/api/suite/user/param_userid/index.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package param_userid
|
||||
|
||||
import (
|
||||
"bdgrp_go/routes"
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Put(path, index)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func index(c *fiber.Ctx) error {
|
||||
return c.SendStatus(200)
|
||||
}
|
||||
30
routes/api/suite/user/param_userid/loginbonus/acceptall.go
Normal file
30
routes/api/suite/user/param_userid/loginbonus/acceptall.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package loginbonus
|
||||
|
||||
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.Put(path, acceptAll)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func acceptAll(c *fiber.Ctx) error {
|
||||
data := map[string]any{
|
||||
"updateResources": map[string]any{},
|
||||
}
|
||||
|
||||
encoded, _ := pbutil.Encode("SuiteUserLoginBonusAcceptAllResponse", data)
|
||||
|
||||
encrypted, _ := utils.Encrypt(encoded)
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
package music
|
||||
79
routes/api/suite/user/param_userid/profile/degree.go
Normal file
79
routes/api/suite/user/param_userid/profile/degree.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package profile
|
||||
|
||||
import (
|
||||
"bdgrp_go/db"
|
||||
"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.Put(path, handle)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func handle(c *fiber.Ctx) error {
|
||||
userid := c.Params("userid")
|
||||
|
||||
decrypted, err := utils.Decrypt(c.Body())
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
decoded, err := pbutil.Decode("UserDecoDegreeRequest", decrypted)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
user := db.FindUser(userid)
|
||||
|
||||
degree := user["degree"].([]any)
|
||||
entries := map[string]any{}
|
||||
|
||||
degree[0] = decoded["degreeIdFirst"]
|
||||
entries["first"] = map[string]any{
|
||||
"userId": userid,
|
||||
"profileDegreeType": "first",
|
||||
"degreeId": degree[0],
|
||||
}
|
||||
|
||||
if v, ok := decoded["degreeIdSecond"]; ok && v != nil && v != "" {
|
||||
degree[1] = v
|
||||
entries["second"] = map[string]any{
|
||||
"userId": userid,
|
||||
"profileDegreeType": "second",
|
||||
"degreeId": degree[1],
|
||||
}
|
||||
} else {
|
||||
degree[1] = nil
|
||||
}
|
||||
|
||||
user["degree"] = degree
|
||||
db.Save()
|
||||
|
||||
data := map[string]any{
|
||||
"updateResources": map[string]any{
|
||||
"userProfileDegreeMap": map[string]any{
|
||||
"entries": entries,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("SuiteUserDecoDegreeResponse", data)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
57
routes/api/system/application.go
Normal file
57
routes/api/system/application.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"bdgrp_go/pbutil"
|
||||
"bdgrp_go/routes"
|
||||
"bdgrp_go/utils"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Get(path, application)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func application(c *fiber.Ctx) error {
|
||||
var offset int
|
||||
server := os.Getenv("SERVER")
|
||||
|
||||
switch server {
|
||||
case "TW", "CN":
|
||||
offset = 28800000
|
||||
break
|
||||
case "JP":
|
||||
offset = 32400000
|
||||
break
|
||||
case "GL":
|
||||
offset = 0
|
||||
break
|
||||
}
|
||||
|
||||
data := map[string]any{
|
||||
"serverDate": strconv.FormatInt(time.Now().Add(27*time.Hour).UnixMilli(), 10),
|
||||
"timeZoneRawOffset": offset,
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("ServerSystem", 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)
|
||||
}
|
||||
49
routes/api/system/config.go
Normal file
49
routes/api/system/config.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"bdgrp_go/routes/upstream"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"bdgrp_go/routes"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Get(path, config)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func config(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/system/config", 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)
|
||||
}
|
||||
90
routes/api/tcpServer/param_userid.go
Normal file
90
routes/api/tcpServer/param_userid.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package tcpServer
|
||||
|
||||
import (
|
||||
"bdgrp_go/routes"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
var skipReqHeaders = map[string]bool{
|
||||
"transfer-encoding": true,
|
||||
"connection": true,
|
||||
"keep-alive": true,
|
||||
"content-encoding": true,
|
||||
"content-length": true,
|
||||
"cf-connecting-ip": true,
|
||||
"cf-ray": true,
|
||||
"cf-visitor": true,
|
||||
"cf-ipcountry": true,
|
||||
"cf-pseudo-ipv4": true,
|
||||
"x-forwarded-for": true,
|
||||
"x-forwarded-proto": true,
|
||||
"x-real-ip": true,
|
||||
"cdn-loop": true,
|
||||
}
|
||||
|
||||
var skipRespHeaders = map[string]bool{
|
||||
"transfer-encoding": true,
|
||||
"connection": true,
|
||||
"keep-alive": true,
|
||||
"content-encoding": true,
|
||||
"content-length": true,
|
||||
}
|
||||
|
||||
var client = &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Post(path, handle)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func handle(c *fiber.Ctx) error {
|
||||
userid := c.Params("userid")
|
||||
url := fmt.Sprintf("https://l3-prod-all-bd.bilibiligame.net/api/tcpServer/%s", userid)
|
||||
|
||||
req, err := http.NewRequest("POST", url, strings.NewReader(string(c.Body())))
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
c.Request().Header.VisitAll(func(k, v []byte) {
|
||||
key := strings.ToLower(string(k))
|
||||
if !skipReqHeaders[key] {
|
||||
req.Header.Set(string(k), string(v))
|
||||
}
|
||||
})
|
||||
req.Header.Set("host", "l3-prod-all-bd.bilibiligame.net")
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
for key, values := range resp.Header {
|
||||
if !skipRespHeaders[strings.ToLower(key)] {
|
||||
c.Set(key, values[0])
|
||||
}
|
||||
}
|
||||
c.Response().Header.Del("Content-Length")
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
return c.Send(body)
|
||||
}
|
||||
21
routes/api/track.go
Normal file
21
routes/api/track.go
Normal file
@@ -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("")
|
||||
}
|
||||
21
routes/api/user/heart/param_userid.go
Normal file
21
routes/api/user/heart/param_userid.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package heart
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"bdgrp_go/routes"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Get(path, heart)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func heart(c *fiber.Ctx) error {
|
||||
return c.SendString("")
|
||||
}
|
||||
140
routes/api/user/index.go
Normal file
140
routes/api/user/index.go
Normal file
@@ -0,0 +1,140 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bdgrp_go/db"
|
||||
"bdgrp_go/pbutil"
|
||||
"bdgrp_go/routes"
|
||||
"bdgrp_go/utils"
|
||||
"fmt"
|
||||
"maps"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Post(path, postUser)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func postUser(c *fiber.Ctx) error {
|
||||
server := os.Getenv("SERVER")
|
||||
decrypted, err := utils.Decrypt(c.Body())
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
decoded, err := pbutil.Decode("UserPostRequest", decrypted)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
var (
|
||||
userName string
|
||||
introduction string
|
||||
)
|
||||
|
||||
switch server {
|
||||
case "TW":
|
||||
userName = "新人工作人員"
|
||||
introduction = "你好!"
|
||||
case "JP":
|
||||
userName = "新人スタッフ"
|
||||
introduction = "よろしくお願いします!"
|
||||
case "GL":
|
||||
userName = "New Staff"
|
||||
introduction = "Nice to meet you!"
|
||||
}
|
||||
|
||||
hash := uuid.New().String()
|
||||
|
||||
users := db.DB.Users[server]
|
||||
|
||||
nextId := 1001
|
||||
if len(users) > 0 {
|
||||
last := users[len(users)-1]
|
||||
if id, ok := last["userId"].(float64); ok {
|
||||
nextId = int(id) + 1
|
||||
}
|
||||
}
|
||||
|
||||
newUser := map[string]any{
|
||||
"userId": nextId,
|
||||
"hash": hash,
|
||||
"userName": userName,
|
||||
"clientVersion": decoded["clientVersion"].(string),
|
||||
"platform": decoded["platform"].(string),
|
||||
"deviceModel": decoded["deviceModel"].(string),
|
||||
"operatingSystem": decoded["operatingSystem"].(string),
|
||||
"birthMonth": "199001",
|
||||
"tutorialStatus": "end",
|
||||
"introduction": introduction,
|
||||
"unknownString": "standard",
|
||||
"tutorialEndedAt": time.Now().UnixMilli(),
|
||||
}
|
||||
|
||||
newGamedata := map[string]any{
|
||||
"rank": 114,
|
||||
"exp": 67,
|
||||
"coin": 114514,
|
||||
"mainDeck": 1,
|
||||
"paidStar": 0,
|
||||
"freeStar": 514,
|
||||
"seal": 0,
|
||||
"degree": []any{100, nil},
|
||||
"publishTotalDeckPowerFlg": false,
|
||||
"publishBandRankFlg": false,
|
||||
"publishMusicClearedFlg": false,
|
||||
"publishMusicFullComboFlg": false,
|
||||
"publishHighScoreRatingFlg": false,
|
||||
"pooledExp": 0,
|
||||
"totalExp": 0,
|
||||
"nextExp": 0,
|
||||
"publishUpdatedAtFlg": true,
|
||||
"startDashLoginBonusReceiveFlg": false,
|
||||
"publishMusicAllPerfectFlg": false,
|
||||
"publishDeckRankFlg": false,
|
||||
"publishStageAchievementConditionsFlg": false,
|
||||
"publishStageFriendRankingFlg": true,
|
||||
"publishCharacterRankFlg": false,
|
||||
"loginDays": 0,
|
||||
"useProfileSettingDegree": true,
|
||||
"useProfileSettingSituation": true,
|
||||
"selectedCharacterType": "character_situation",
|
||||
}
|
||||
|
||||
maps.Copy(newUser, newGamedata)
|
||||
|
||||
db.DB.Users[server] = append(db.DB.Users[server], newUser)
|
||||
db.Save()
|
||||
|
||||
data := map[string]any{
|
||||
"userId": fmt.Sprintf("%v", newUser["userId"]),
|
||||
"hash": newUser["hash"],
|
||||
"userName": newUser["userName"],
|
||||
"clientVersion": newUser["clientVersion"],
|
||||
"platform": newUser["platform"],
|
||||
"deviceModel": newUser["deviceModel"],
|
||||
"operatingSystem": newUser["operatingSystem"],
|
||||
"tutorialStatus": newUser["tutorialStatus"],
|
||||
"introduction": newUser["introduction"],
|
||||
"tutorialEndedAt": fmt.Sprintf("%v", newUser["tutorialEndedAt"]),
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("UserRegistration", data)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
130
routes/api/user/login.go
Normal file
130
routes/api/user/login.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bdgrp_go/db"
|
||||
"bdgrp_go/pbutil"
|
||||
"bdgrp_go/routes"
|
||||
"bdgrp_go/utils"
|
||||
"fmt"
|
||||
"maps"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Post(path, login)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func login(c *fiber.Ctx) error {
|
||||
server := os.Getenv("SERVER")
|
||||
decrypted, err := utils.Decrypt(c.Body())
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
decoded, err := pbutil.Decode("UserLogin", decrypted)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
user := db.FindUser(fmt.Sprintf("%v", decoded["bid"]), db.Bid)
|
||||
|
||||
if user == nil {
|
||||
hash := uuid.New().String()
|
||||
|
||||
users := db.DB.Users[server]
|
||||
|
||||
nextId := 1001
|
||||
if len(users) > 0 {
|
||||
last := users[len(users)-1]
|
||||
if id, ok := last["userId"].(float64); ok {
|
||||
nextId = int(id) + 1
|
||||
}
|
||||
}
|
||||
|
||||
newUser := map[string]any{
|
||||
"bid": decoded["bid"].(string),
|
||||
"userId": nextId,
|
||||
"hash": hash,
|
||||
"userName": "新手工作人员",
|
||||
"clientVersion": decoded["clientVersion"].(string),
|
||||
"platform": decoded["platform"].(string),
|
||||
"deviceModel": decoded["deviceModel"].(string),
|
||||
"operatingSystem": decoded["operatingSystem"].(string),
|
||||
"birthMonth": "199001",
|
||||
"tutorialStatus": "end",
|
||||
"introduction": "请多多关照!",
|
||||
"unknownString": "standard",
|
||||
"tutorialEndedAt": time.Now().UnixMilli(),
|
||||
}
|
||||
|
||||
newGamedata := map[string]any{
|
||||
"rank": 114,
|
||||
"exp": 67,
|
||||
"coin": 114514,
|
||||
"mainDeck": 1,
|
||||
"paidStar": 0,
|
||||
"freeStar": 514,
|
||||
"seal": 0,
|
||||
"degree": []any{100, nil},
|
||||
"publishTotalDeckPowerFlg": false,
|
||||
"publishBandRankFlg": false,
|
||||
"publishMusicClearedFlg": false,
|
||||
"publishMusicFullComboFlg": false,
|
||||
"publishHighScoreRatingFlg": false,
|
||||
"pooledExp": 0,
|
||||
"totalExp": 0,
|
||||
"nextExp": 0,
|
||||
"publishUpdatedAtFlg": true,
|
||||
"startDashLoginBonusReceiveFlg": false,
|
||||
"publishMusicAllPerfectFlg": false,
|
||||
"publishDeckRankFlg": false,
|
||||
"publishStageAchievementConditionsFlg": false,
|
||||
"publishStageFriendRankingFlg": true,
|
||||
"publishCharacterRankFlg": false,
|
||||
"loginDays": 0,
|
||||
"useProfileSettingDegree": true,
|
||||
"useProfileSettingSituation": true,
|
||||
"selectedCharacterType": "character_situation",
|
||||
}
|
||||
|
||||
maps.Copy(newUser, newGamedata)
|
||||
|
||||
db.DB.Users[server] = append(db.DB.Users[server], newUser)
|
||||
db.Save()
|
||||
|
||||
user = newUser
|
||||
}
|
||||
|
||||
data := map[string]any{
|
||||
"userId": fmt.Sprintf("%v", user["userId"]),
|
||||
"hash": user["hash"],
|
||||
"userName": user["userName"],
|
||||
"clientVersion": user["clientVersion"],
|
||||
"platform": user["platform"],
|
||||
"deviceModel": user["deviceModel"],
|
||||
"operatingSystem": user["operatingSystem"],
|
||||
"tutorialStatus": user["tutorialStatus"],
|
||||
"introduction": user["introduction"],
|
||||
"tutorialEndedAt": fmt.Sprintf("%v", user["tutorialEndedAt"]),
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("UserRegistration", data)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
59
routes/api/user/param_userid.go
Normal file
59
routes/api/user/param_userid.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bdgrp_go/db"
|
||||
"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.Get(path, get)
|
||||
app.Put(path, putUser)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func get(c *fiber.Ctx) error {
|
||||
return c.SendString("")
|
||||
}
|
||||
|
||||
func putUser(c *fiber.Ctx) error {
|
||||
decrypted, _ := utils.Decrypt(c.Body())
|
||||
|
||||
decoded, err := pbutil.Decode("UserPutRequest", decrypted)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
userId := c.Params("userid")
|
||||
|
||||
user := db.FindUser(userId)
|
||||
|
||||
if v, ok := decoded["userName"].(string); ok && v != "" {
|
||||
user["userName"] = v
|
||||
}
|
||||
if v, ok := decoded["birthMonth"].(string); ok && v != "" {
|
||||
user["birthMonth"] = v
|
||||
}
|
||||
if v, ok := decoded["introduction"].(string); ok && v != "" {
|
||||
user["introduction"] = v
|
||||
}
|
||||
if v, ok := decoded["tutorialStatus"].(string); ok && v != "" {
|
||||
user["tutorialStatus"] = v
|
||||
}
|
||||
if v, ok := decoded["mainDeck"].(float64); ok && v != 0 {
|
||||
user["mainDeck"] = uint64(v)
|
||||
}
|
||||
if v, ok := decoded["degree"].(float64); ok && v != 0 {
|
||||
user["degree"] = uint32(v)
|
||||
}
|
||||
|
||||
db.Save()
|
||||
return c.SendString("")
|
||||
}
|
||||
59
routes/api/user/param_userid/area/registeropentimearea.go
Normal file
59
routes/api/user/param_userid/area/registeropentimearea.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package area
|
||||
|
||||
import (
|
||||
"bdgrp_go/master"
|
||||
"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.Get(path, handle)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func handle(c *fiber.Ctx) error {
|
||||
userid := c.Params("userid")
|
||||
m := master.GetMaster()
|
||||
|
||||
areaMap := m["masterAreaMap"].(map[string]any)
|
||||
entries := areaMap["entries"].(map[string]any)
|
||||
|
||||
// .filter(area.areaType === "common").map(...)
|
||||
resultEntries := map[string]any{}
|
||||
for areaId, v := range entries {
|
||||
area := v.(map[string]any)
|
||||
if area["areaType"] != "common" {
|
||||
continue
|
||||
}
|
||||
resultEntries[areaId] = map[string]any{
|
||||
"userId": userid,
|
||||
"areaId": areaId,
|
||||
}
|
||||
}
|
||||
|
||||
data := map[string]any{
|
||||
"registerTimeOpenAreaIdList": nil,
|
||||
"userAreaStatusMap": map[string]any{
|
||||
"entries": resultEntries,
|
||||
},
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("RegisterTimeOpenAreaResponse", data)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
70
routes/api/user/param_userid/auth.go
Normal file
70
routes/api/user/param_userid/auth.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package param_userid
|
||||
|
||||
import (
|
||||
"bdgrp_go/db"
|
||||
"bdgrp_go/pbutil"
|
||||
"bdgrp_go/routes"
|
||||
"bdgrp_go/utils"
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Put(path, Auth)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func Auth(c *fiber.Ctx) error {
|
||||
server := os.Getenv("SERVER")
|
||||
userid := c.Params("userid")
|
||||
|
||||
decrypted, err := utils.Decrypt(c.Body())
|
||||
if err != nil {
|
||||
return c.Status(500).SendString("")
|
||||
}
|
||||
|
||||
decoded, err := pbutil.Decode("UserAuthRequest", decrypted)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString("")
|
||||
}
|
||||
|
||||
hash := fmt.Sprintf("%x", sha1.Sum([]byte(userid+":")))
|
||||
|
||||
errData := map[string]any{
|
||||
"httpStatus": 403,
|
||||
"errorCode": "",
|
||||
"errorMessage": "signature invalid.",
|
||||
}
|
||||
|
||||
sendErr := func() error {
|
||||
encoded, _ := pbutil.Encode("ClientErrorResponse", errData)
|
||||
encrypted, _ := utils.Encrypt(encoded)
|
||||
return c.Status(403).Send(encrypted)
|
||||
}
|
||||
|
||||
user := db.FindUser(userid)
|
||||
if hash != decoded["hash1"] || user == nil {
|
||||
return sendErr()
|
||||
}
|
||||
|
||||
if c.Get("x-signature") != user["hash"] {
|
||||
return sendErr()
|
||||
}
|
||||
|
||||
// 更新 clientVersion
|
||||
for i, u := range db.DB.Users[server] {
|
||||
if fmt.Sprintf("%v", u["userId"]) == userid {
|
||||
db.DB.Users[server][i]["clientVersion"] = c.Get("x-clientversion")
|
||||
break
|
||||
}
|
||||
}
|
||||
db.Save()
|
||||
|
||||
return c.Send(nil)
|
||||
}
|
||||
69
routes/api/user/param_userid/bandstory/param_bandid.go
Normal file
69
routes/api/user/param_userid/bandstory/param_bandid.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package bandstory
|
||||
|
||||
import (
|
||||
"bdgrp_go/master"
|
||||
"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.Get(path, handle)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
var bandStoryKeys = map[string]string{
|
||||
"1": "masterPoppinPartyStoryMap",
|
||||
"2": "masterAfterglowStoryMap",
|
||||
"3": "masterHelloHappyWorldStoryMap",
|
||||
"4": "masterPastelPalettesStoryMap",
|
||||
"5": "masterRoseliaStoryMap",
|
||||
"18": "masterRaiseASuilenStoryMap",
|
||||
"21": "masterMorfonicaStoryMap",
|
||||
"45": "masterMyGoStoryMap",
|
||||
}
|
||||
|
||||
func handle(c *fiber.Ctx) error {
|
||||
userid := c.Params("userid")
|
||||
bandid := c.Params("bandid")
|
||||
m := master.GetMaster()
|
||||
|
||||
key, _ := bandStoryKeys[bandid]
|
||||
|
||||
storyMap := m[key].(map[string]any)
|
||||
entries := storyMap["entries"].(map[string]any)
|
||||
|
||||
var result []any
|
||||
for _, v := range entries {
|
||||
story := v.(map[string]any)
|
||||
result = append(result, map[string]any{
|
||||
"userId": userid,
|
||||
"bandStoryId": story["bandStoryId"],
|
||||
"bandId": story["bandId"],
|
||||
"status": "already_read",
|
||||
"seq": story["seq"],
|
||||
})
|
||||
}
|
||||
|
||||
data := map[string]any{
|
||||
"entries": result,
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("UserBandStoryList", data)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
55
routes/api/user/param_userid/device/update.go
Normal file
55
routes/api/user/param_userid/device/update.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"bdgrp_go/db"
|
||||
"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.Put(path, updateDevice)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func updateDevice(c *fiber.Ctx) error {
|
||||
decrypted, err := utils.Decrypt(c.Body())
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
decoded, err := pbutil.Decode("DeviceInfoUpdateRequest", decrypted)
|
||||
|
||||
userid := c.Params("userid")
|
||||
|
||||
user := db.FindUser(userid)
|
||||
|
||||
user["deviceModel"] = decoded["deviceModel"]
|
||||
user["operatingSystem"] = decoded["operatingSystem"]
|
||||
|
||||
db.Save()
|
||||
|
||||
data := map[string]any{
|
||||
"deviceModel": user["deviceModel"],
|
||||
"operatingSystem": user["operatingSystem"],
|
||||
"clientVersion": user["clientVersion"],
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("UserRegistration", data)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
21
routes/api/user/param_userid/fcm.go
Normal file
21
routes/api/user/param_userid/fcm.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package param_userid
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"bdgrp_go/routes"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Put(path, fcm)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func fcm(c *fiber.Ctx) error {
|
||||
return c.SendString("")
|
||||
}
|
||||
87
routes/api/user/param_userid/index.go
Normal file
87
routes/api/user/param_userid/index.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package param_userid
|
||||
|
||||
import (
|
||||
"bdgrp_go/db"
|
||||
"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.Get(path, GetUser)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func GetUser(c *fiber.Ctx) error {
|
||||
userid := c.Params("userid")
|
||||
|
||||
user := db.FindUser(userid)
|
||||
|
||||
if user == nil {
|
||||
return c.Status(404).SendString("")
|
||||
}
|
||||
|
||||
userId := fmt.Sprintf("%v", user["userId"])
|
||||
|
||||
data := map[string]any{
|
||||
"userRegistration": map[string]any{
|
||||
"userId": userId,
|
||||
"hash": user["hash"],
|
||||
"userName": user["userName"],
|
||||
"clientVersion": user["clientVersion"],
|
||||
"platform": user["platform"],
|
||||
"deviceModel": user["deviceModel"],
|
||||
"operatingSystem": user["operatingSystem"],
|
||||
"birthMonth": user["birthMonth"],
|
||||
"tutorialStatus": user["tutorialStatus"],
|
||||
"introduction": user["introduction"],
|
||||
"tutorialEndedAt": fmt.Sprintf("%v", user["tutorialEndedAt"]),
|
||||
},
|
||||
"userGamedata": map[string]any{
|
||||
"userId": userId,
|
||||
"rank": user["rank"],
|
||||
"exp": user["exp"],
|
||||
"coin": fmt.Sprintf("%v", user["coin"]),
|
||||
"mainDeck": user["mainDeck"],
|
||||
"paidStar": user["paidStar"],
|
||||
"freeStar": user["freeStar"],
|
||||
"seal": user["seal"],
|
||||
"degree": user["degree"].([]any)[0],
|
||||
"publishTotalDeckPowerFlg": user["publishTotalDeckPowerFlg"],
|
||||
"publishBandRankFlg": user["publishBandRankFlg"],
|
||||
"publishMusicClearedFlg": user["publishMusicClearedFlg"],
|
||||
"publishMusicFullComboFlg": user["publishMusicFullComboFlg"],
|
||||
"publishHighScoreRatingFlg": user["publishHighScoreRatingFlg"],
|
||||
"pooledExp": fmt.Sprintf("%v", user["pooledExp"]),
|
||||
"totalExp": fmt.Sprintf("%v", user["totalExp"]),
|
||||
"nextExp": user["nextExp"],
|
||||
"publishUpdatedAtFlg": user["publishUpdatedAtFlg"],
|
||||
"userPaidStarRecallResponse": nil,
|
||||
"startDashLoginBonusReceiveFlg": user["startDashLoginBonusReceiveFlg"],
|
||||
"publishMusicAllPerfectFlg": user["publishMusicAllPerfectFlg"],
|
||||
"publishDeckRankFlg": user["publishDeckRankFlg"],
|
||||
"publishStageAchievementConditionsFlg": user["publishStageAchievementConditionsFlg"],
|
||||
"publishStageFriendRankingFlg": user["publishStageFriendRankingFlg"],
|
||||
"publishCharacterRankFlg": user["publishCharacterRankFlg"],
|
||||
"loginDays": user["loginDays"],
|
||||
},
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("UserGetResponse", data)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
40
routes/api/user/param_userid/liveboost.go
Normal file
40
routes/api/user/param_userid/liveboost.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package param_userid
|
||||
|
||||
import (
|
||||
"bdgrp_go/pbutil"
|
||||
"bdgrp_go/routes"
|
||||
"bdgrp_go/utils"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Get(path, liveBoost)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func liveBoost(c *fiber.Ctx) error {
|
||||
data := map[string]any{
|
||||
"userId": c.Params("userId"),
|
||||
"count": 67,
|
||||
"serverDate": time.Now().UnixMilli(),
|
||||
"liveBoostBonusType": "default",
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("UserLiveBoost", data)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
39
routes/api/user/param_userid/livefever.go
Normal file
39
routes/api/user/param_userid/livefever.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package param_userid
|
||||
|
||||
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.Get(path, liveFever)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func liveFever(c *fiber.Ctx) error {
|
||||
data := map[string]any {
|
||||
"userId": c.Params("userId"),
|
||||
"count": 67,
|
||||
"inActivity": true,
|
||||
"limit": 3,
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("UserLiveFeverCount", data)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
38
routes/api/user/param_userid/maindeck.go
Normal file
38
routes/api/user/param_userid/maindeck.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package param_userid
|
||||
|
||||
import (
|
||||
"bdgrp_go/db"
|
||||
"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.Put(path, mainDeck)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func mainDeck(c *fiber.Ctx) error {
|
||||
decrypted, err := utils.Decrypt(c.Body())
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
decoded, err := pbutil.Decode("UserPutRequest", decrypted)
|
||||
|
||||
userid := c.Params("userid")
|
||||
|
||||
user := db.FindUser(userid)
|
||||
|
||||
user["mainDeck"] = decoded["mainDeck"]
|
||||
|
||||
db.Save()
|
||||
|
||||
return c.Send(nil)
|
||||
}
|
||||
93
routes/api/user/param_userid/memorialstory.go
Normal file
93
routes/api/user/param_userid/memorialstory.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package param_userid
|
||||
|
||||
import (
|
||||
"bdgrp_go/master"
|
||||
"bdgrp_go/pbutil"
|
||||
"bdgrp_go/routes"
|
||||
"bdgrp_go/utils"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"maps"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Get(path, handle)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func handle(c *fiber.Ctx) error {
|
||||
userid := c.Params("userid")
|
||||
m := master.GetMaster()
|
||||
|
||||
// 讀 pastEvents/{SERVER}.json
|
||||
pastPath := filepath.Join("pastEvents", os.Getenv("SERVER")+".json")
|
||||
pastData, err := os.ReadFile(pastPath)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString("no past events")
|
||||
}
|
||||
var past map[string]any
|
||||
json.Unmarshal(pastData, &past)
|
||||
|
||||
// masterEventStoryMemorialConfigMap.entries
|
||||
configMap := m["masterEventStoryMemorialConfigMap"].(map[string]any)
|
||||
entries := configMap["entries"].(map[string]any)
|
||||
|
||||
// pastEventStoryMap.entries
|
||||
pastStoryMap := past["pastEventStoryMap"].(map[string]any)
|
||||
pastEntries := pastStoryMap["entries"].(map[string]any)
|
||||
|
||||
// Object.fromEntries(Object.entries(...).map(...))
|
||||
resultEntries := map[string]any{}
|
||||
for eventId := range entries {
|
||||
// Array.from({ length: ... }, (_, i) => ...)
|
||||
var storyList []any
|
||||
if pastEvent, ok := pastEntries[eventId].(map[string]any); ok {
|
||||
if innerEntries, ok := pastEvent["entries"].([]any); ok {
|
||||
for i := range innerEntries {
|
||||
storyList = append(storyList, map[string]any{
|
||||
"userId": userid,
|
||||
"eventId": eventId,
|
||||
"seq": i,
|
||||
"status": "already_read",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resultEntries[eventId] = map[string]any{
|
||||
"eventId": eventId,
|
||||
"userEventStoryList": map[string]any{
|
||||
"entries": storyList,
|
||||
},
|
||||
"isExistUnReadStory": false,
|
||||
"isLocked": false,
|
||||
}
|
||||
}
|
||||
|
||||
// 合併 past(等同 ...past)
|
||||
data := map[string]any{
|
||||
"userEventStoryMemorialMap": map[string]any{
|
||||
"entries": resultEntries,
|
||||
},
|
||||
}
|
||||
maps.Copy(data, past)
|
||||
|
||||
encoded, err := pbutil.Encode("UserEventStoryMemorialResponse", data)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
20
routes/api/user/param_userid/multiroomfriendrecruitment.go
Normal file
20
routes/api/user/param_userid/multiroomfriendrecruitment.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package param_userid
|
||||
|
||||
import (
|
||||
"bdgrp_go/routes"
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Get(path, recruitment)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func recruitment(c *fiber.Ctx) error {
|
||||
return c.SendStatus(200)
|
||||
}
|
||||
20
routes/api/user/param_userid/music/param_musicid.go
Normal file
20
routes/api/user/param_userid/music/param_musicid.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package music
|
||||
|
||||
import (
|
||||
"bdgrp_go/routes"
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Post(path, music)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func music(c *fiber.Ctx) error {
|
||||
return c.SendStatus(200)
|
||||
}
|
||||
82
routes/api/user/param_userid/music/param_musicid/continue.go
Normal file
82
routes/api/user/param_userid/music/param_musicid/continue.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package param_musicid
|
||||
|
||||
import (
|
||||
"bdgrp_go/db"
|
||||
"bdgrp_go/pbutil"
|
||||
"bdgrp_go/routes"
|
||||
"bdgrp_go/utils"
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Put(path, musicContinue)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func musicContinue(c *fiber.Ctx) error {
|
||||
userid := c.Params("userid")
|
||||
|
||||
decrypted, err := utils.Decrypt(c.Body())
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
decoded, err := pbutil.Decode("UserMusicContinueRequest", decrypted)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
user := db.FindUser(userid)
|
||||
|
||||
str := userid + decoded["continueCount"].(string) + decoded["continueTime"].(string)
|
||||
|
||||
data := map[string]any{
|
||||
"userGamedata": map[string]any{
|
||||
"userId": userid,
|
||||
"rank": user["rank"],
|
||||
"exp": user["exp"],
|
||||
"coin": user["coin"],
|
||||
"mainDeck": user["mainDeck"],
|
||||
"paidStar": user["paidStar"],
|
||||
"freeStar": user["freeStar"],
|
||||
"seal": user["seal"],
|
||||
"degree": user["degree"],
|
||||
"publishTotalDeckPowerFlg": user["publishTotalDeckPowerFlg"],
|
||||
"publishBandRankFlg": user["publishBandRankFlg"],
|
||||
"publishMusicClearedFlg": user["publishMusicClearedFlg"],
|
||||
"publishMusicFullComboFlg": user["publishMusicFullComboFlg"],
|
||||
"publishHighScoreRatingFlg": user["publishHighScoreRatingFlg"],
|
||||
"pooledExp": user["pooledExp"],
|
||||
"totalExp": user["totalExp"],
|
||||
"nextExp": user["nextExp"],
|
||||
"publishUpdatedAtFlg": user["publishUpdatedAtFlg"],
|
||||
"userPaidStarRecallResponse": nil,
|
||||
"startDashLoginBonusReceiveFlg": user["startDashLoginBonusReceiveFlg"],
|
||||
"publishMusicAllPerfectFlg": user["publishMusicAllPerfectFlg"],
|
||||
"publishDeckRankFlg": user["publishDeckRankFlg"],
|
||||
"publishStageAchievementConditionsFlg": user["publishStageAchievementConditionsFlg"],
|
||||
"publishStageFriendRankingFlg": user["publishStageFriendRankingFlg"],
|
||||
"publishCharacterRankFlg": user["publishCharacterRankFlg"],
|
||||
"loginDays": user["loginDays"],
|
||||
},
|
||||
"continueHash": fmt.Sprintf("%x", sha1.Sum([]byte(str))),
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("UserMusicContinueResponse", data)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
20
routes/api/user/param_userid/music/param_musicid/retry.go
Normal file
20
routes/api/user/param_userid/music/param_musicid/retry.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package param_musicid
|
||||
|
||||
import (
|
||||
"bdgrp_go/routes"
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
path := routes.PathOf()
|
||||
routes.Register(func(app *fiber.App) {
|
||||
app.Post(path, retry)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func retry(c *fiber.Ctx) error {
|
||||
return c.SendStatus(200)
|
||||
}
|
||||
40
routes/api/user/param_userid/present.go
Normal file
40
routes/api/user/param_userid/present.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package param_userid
|
||||
|
||||
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.Get(path, present)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func present(c *fiber.Ctx) error {
|
||||
data := map[string]any{
|
||||
"pagination": map[string]any{
|
||||
"start": 9223372036854775807,
|
||||
"limit": c.Query("limit"),
|
||||
"record": 0,
|
||||
},
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("UserPresentLimit", data)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
40
routes/api/user/param_userid/presenthistory.go
Normal file
40
routes/api/user/param_userid/presenthistory.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package param_userid
|
||||
|
||||
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.Get(path, presentHistory)
|
||||
fmt.Println("Loaded:", path)
|
||||
})
|
||||
}
|
||||
|
||||
func presentHistory(c *fiber.Ctx) error {
|
||||
data := map[string]any{
|
||||
"pagination": map[string]any{
|
||||
"start": 9223372036854775807,
|
||||
"limit": c.Query("limit"),
|
||||
"record": 0,
|
||||
},
|
||||
}
|
||||
|
||||
encoded, err := pbutil.Encode("UserPresentHistoryList", data)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
encrypted, err := utils.Encrypt(encoded)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return c.Send(encrypted)
|
||||
}
|
||||
38
routes/api/validation/ngword.go
Normal file
38
routes/api/validation/ngword.go
Normal file
@@ -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)
|
||||
}
|
||||
23
routes/helper.go
Normal file
23
routes/helper.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func PathOf() string {
|
||||
_, file, _, _ := runtime.Caller(1)
|
||||
idx := strings.Index(file, "routes/")
|
||||
path := file[idx+len("routes"):]
|
||||
path = strings.TrimSuffix(path, ".go")
|
||||
|
||||
if strings.HasSuffix(path, "/index") {
|
||||
path = strings.TrimSuffix(path, "index")
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(`param_(\w+)`)
|
||||
path = re.ReplaceAllString(path, ":$1")
|
||||
|
||||
return path
|
||||
}
|
||||
17
routes/registry.go
Normal file
17
routes/registry.go
Normal file
@@ -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)
|
||||
}
|
||||
}
|
||||
31
routes/upstream/upstream.go
Normal file
31
routes/upstream/upstream.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package upstream
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
var BaseUrls = map[string]string{
|
||||
"TW": "https://v1010-bd.mobimon.com.tw",
|
||||
"JP": "https://api.garupa.jp",
|
||||
"GL": "https://api.app-bang-dream-gbp.com",
|
||||
"CN": "https://l3-prod-all-bd.bilibiligame.net",
|
||||
}
|
||||
|
||||
func Fetch(url string, headers map[string]string) ([]byte, error) {
|
||||
req, _ := http.NewRequest("GET", url, nil)
|
||||
for k, v := range headers {
|
||||
req.Header.Set(k, v)
|
||||
}
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
return io.ReadAll(resp.Body)
|
||||
}
|
||||
|
||||
func BaseUrl() string {
|
||||
return BaseUrls[os.Getenv("SERVER")]
|
||||
}
|
||||
81
utils/crypto.go
Normal file
81
utils/crypto.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
var keys = map[string]string{
|
||||
"TW": "mikumikulukaluka",
|
||||
"JP": "mikumikulukaluka",
|
||||
"GL": "RXzFAC87WR28eNcP",
|
||||
"CN": "wakakabiliwakaka",
|
||||
}
|
||||
|
||||
var ivs = map[string]string{
|
||||
"TW": "lukalukamikumiku",
|
||||
"JP": "lukalukamikumiku",
|
||||
"GL": "hrk0k7knXlit3S_y",
|
||||
"CN": "biliwakakawohaha",
|
||||
}
|
||||
|
||||
func getKeyIV() ([]byte, []byte, error) {
|
||||
server := os.Getenv("SERVER")
|
||||
key, ok := keys[server]
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("unknown server: %s", server)
|
||||
}
|
||||
return []byte(key), []byte(ivs[server]), nil
|
||||
}
|
||||
|
||||
func Decrypt(buf []byte) ([]byte, error) {
|
||||
key, iv, err := getKeyIV()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(buf)%aes.BlockSize != 0 {
|
||||
return nil, fmt.Errorf("invalid block size")
|
||||
}
|
||||
|
||||
decrypted := make([]byte, len(buf))
|
||||
cipher.NewCBCDecrypter(block, iv).CryptBlocks(decrypted, buf)
|
||||
|
||||
// 手動移除 padding(setAutoPadding(false) 對應)
|
||||
padLen := int(decrypted[len(decrypted)-1])
|
||||
if padLen > 0 && padLen <= 16 && padLen <= len(decrypted) {
|
||||
decrypted = decrypted[:len(decrypted)-padLen]
|
||||
}
|
||||
|
||||
return decrypted, nil
|
||||
}
|
||||
|
||||
func Encrypt(buf []byte) ([]byte, error) {
|
||||
key, iv, err := getKeyIV()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 手動加 PKCS7 padding(setAutoPadding(true) 對應)
|
||||
blockSize := block.BlockSize()
|
||||
padding := blockSize - len(buf)%blockSize
|
||||
padded := append(buf, bytes.Repeat([]byte{byte(padding)}, padding)...)
|
||||
|
||||
encrypted := make([]byte, len(padded))
|
||||
cipher.NewCBCEncrypter(block, iv).CryptBlocks(encrypted, padded)
|
||||
|
||||
return encrypted, nil
|
||||
}
|
||||
222
utils/helper.go
Normal file
222
utils/helper.go
Normal file
@@ -0,0 +1,222 @@
|
||||
package utils
|
||||
|
||||
import "fmt"
|
||||
|
||||
func ComputeMusicClearInfo(musicScore map[string]any) map[string]any {
|
||||
difficulties := []string{"easy", "normal", "hard", "expert", "special"}
|
||||
type stat struct{ cleared, fullCombo, allPerfect int }
|
||||
stats := map[string]*stat{}
|
||||
for _, d := range difficulties {
|
||||
stats[d] = &stat{}
|
||||
}
|
||||
|
||||
for _, v := range musicScore {
|
||||
data := v.(map[string]any)
|
||||
entries, ok := data["entries"].([]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
for _, e := range entries {
|
||||
entry := e.(map[string]any)
|
||||
diff, _ := entry["musicDifficulty"].(string)
|
||||
clearStatus, _ := entry["clearStatus"].(string)
|
||||
if s, ok := stats[diff]; ok {
|
||||
s.cleared++
|
||||
if clearStatus == "full_combo" {
|
||||
s.fullCombo++
|
||||
}
|
||||
if clearStatus == "all_perfect" {
|
||||
s.allPerfect++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result := map[string]any{}
|
||||
for _, d := range difficulties {
|
||||
result[d] = map[string]any{
|
||||
"clearedMusicCount": stats[d].cleared,
|
||||
"fullComboMusicCount": stats[d].fullCombo,
|
||||
"allPerfectMusicCount": stats[d].allPerfect,
|
||||
}
|
||||
}
|
||||
return map[string]any{"entries": result}
|
||||
}
|
||||
|
||||
func ComputeMusicClearCountInfo(musicScore map[string]any) map[string]any {
|
||||
result := map[string]any{}
|
||||
for id, v := range musicScore {
|
||||
data := v.(map[string]any)
|
||||
entries, ok := data["entries"].([]any)
|
||||
if ok && len(entries) > 0 {
|
||||
result[id] = len(entries)
|
||||
}
|
||||
}
|
||||
return map[string]any{"entries": result}
|
||||
}
|
||||
|
||||
func BuildUserSituations(userid string, master map[string]any, user map[string]any) []any {
|
||||
situationMap := master["masterCharacterSituationMap"].(map[string]any)["entries"].(map[string]any)
|
||||
|
||||
var result []any
|
||||
for _, v := range situationMap {
|
||||
card := v.(map[string]any)
|
||||
releasedAt := fmt.Sprintf("%v", card["releasedAt"])
|
||||
if releasedAt == "4128645600000" || releasedAt == "4131237600000" {
|
||||
continue
|
||||
}
|
||||
|
||||
// maxLevel
|
||||
maxLevel := 0
|
||||
if paramMap, ok := card["parameterMap"].(map[string]any); ok {
|
||||
for k := range paramMap {
|
||||
var level int
|
||||
fmt.Sscanf(k, "%d", &level)
|
||||
if level > maxLevel {
|
||||
maxLevel = level
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rarity := 0
|
||||
if r, ok := card["rarity"].(float64); ok {
|
||||
rarity = int(r)
|
||||
}
|
||||
hasTraining := rarity >= 3
|
||||
|
||||
var ep0, ep1 map[string]any
|
||||
if eps, ok := card["episodes"].(map[string]any); ok {
|
||||
if entries, ok := eps["entries"].([]any); ok {
|
||||
if len(entries) > 0 {
|
||||
ep0, _ = entries[0].(map[string]any)
|
||||
}
|
||||
if len(entries) > 1 {
|
||||
ep1, _ = entries[1].(map[string]any)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
illust := "normal"
|
||||
if hasTraining {
|
||||
illust = "after_training"
|
||||
}
|
||||
if user != nil {
|
||||
if si, ok := user["situationIllust"].(map[string]any); ok {
|
||||
if v, ok := si[fmt.Sprintf("%v", card["situationId"])]; ok {
|
||||
illust = fmt.Sprintf("%v", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trainingStatus := "not_doing"
|
||||
if hasTraining {
|
||||
trainingStatus = "done"
|
||||
}
|
||||
|
||||
sit := map[string]any{
|
||||
"userId": userid,
|
||||
"situationId": card["situationId"],
|
||||
"level": maxLevel,
|
||||
"exp": 0,
|
||||
"createdAt": card["releasedAt"],
|
||||
"addExp": 0,
|
||||
"trainingStatus": trainingStatus,
|
||||
"duplicateCount": 0,
|
||||
"illust": illust,
|
||||
"skillExp": 0,
|
||||
"skillLevel": 5,
|
||||
"limitBreakRank": 4,
|
||||
}
|
||||
|
||||
if hasTraining {
|
||||
t, _ := card["training"].(map[string]any)
|
||||
perf, tech, vis := 0.0, 0.0, 0.0
|
||||
if t != nil {
|
||||
perf, _ = t["trainingPerformance"].(float64)
|
||||
tech, _ = t["trainingTechnique"].(float64)
|
||||
vis, _ = t["trainingVisual"].(float64)
|
||||
}
|
||||
ep0Perf, ep0Tech, ep0Vis := 0.0, 0.0, 0.0
|
||||
ep1Perf, ep1Tech, ep1Vis := 0.0, 0.0, 0.0
|
||||
if ep0 != nil {
|
||||
ep0Perf, _ = ep0["appendPerformance"].(float64)
|
||||
ep0Tech, _ = ep0["appendTechnique"].(float64)
|
||||
ep0Vis, _ = ep0["appendVisual"].(float64)
|
||||
}
|
||||
if ep1 != nil {
|
||||
ep1Perf, _ = ep1["appendPerformance"].(float64)
|
||||
ep1Tech, _ = ep1["appendTechnique"].(float64)
|
||||
ep1Vis, _ = ep1["appendVisual"].(float64)
|
||||
}
|
||||
|
||||
sit["userAppendParameter"] = map[string]any{
|
||||
"userId": userid,
|
||||
"situationId": card["situationId"],
|
||||
"performance": perf,
|
||||
"technique": tech,
|
||||
"visual": vis,
|
||||
"characterPotentialPerformance": 30,
|
||||
"characterPotentialTechnique": 30,
|
||||
"characterPotentialVisual": 30,
|
||||
"characterBonusPerformance": 30 + ep0Perf + ep1Perf,
|
||||
"characterBonusTechnique": 30 + ep0Tech + ep1Tech,
|
||||
"characterBonusVisual": 30 + ep0Vis + ep1Vis,
|
||||
}
|
||||
}
|
||||
|
||||
result = append(result, sit)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func BuildUserProfileDegree(userid string, user map[string]any) map[string]any {
|
||||
degree := user["degree"].([]any)
|
||||
result := map[string]any{
|
||||
"first": map[string]any{
|
||||
"userId": userid,
|
||||
"profileDegreeType": "first",
|
||||
"degreeId": degree[0],
|
||||
},
|
||||
}
|
||||
if len(degree) > 1 && degree[1] != nil {
|
||||
result["second"] = map[string]any{
|
||||
"userId": userid,
|
||||
"profileDegreeType": "second",
|
||||
"degreeId": degree[1],
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func BuildCharacterRankMap() map[string]any {
|
||||
entries := map[string]any{}
|
||||
for i := 1; i <= 40; i++ {
|
||||
entries[fmt.Sprintf("%d", i)] = map[string]any{
|
||||
"rank": 100, "exp": 0, "addExp": 0,
|
||||
"nextExp": 0, "totalExp": 0, "releasedPotentialLevel": 50,
|
||||
}
|
||||
}
|
||||
return map[string]any{"entries": entries}
|
||||
}
|
||||
|
||||
func GetScoreRank(score float64, difficultyMaster map[string]any) string {
|
||||
if difficultyMaster == nil {
|
||||
return "c"
|
||||
}
|
||||
get := func(key string) float64 {
|
||||
v, _ := difficultyMaster[key].(float64)
|
||||
return v
|
||||
}
|
||||
switch {
|
||||
case score >= get("scoreSS"):
|
||||
return "ss"
|
||||
case score >= get("scoreS"):
|
||||
return "s"
|
||||
case score >= get("scoreA"):
|
||||
return "a"
|
||||
case score >= get("scoreB"):
|
||||
return "b"
|
||||
default:
|
||||
return "c"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user