From d0f01202718c118b86ff5f1cd09face09fa07539 Mon Sep 17 00:00:00 2001 From: nightnai Date: Mon, 7 Sep 2026 20:44:56 +0800 Subject: [PATCH] fixed lots of bugs --- pbutil/pbutil.go | 2 +- routes/api/suite/user/param_userid.go | 184 ++-------- routes/api/suite/user/param_userid/area.go | 5 +- .../param_userid/area/item/recommended.go | 121 +++++++ .../actionset/param_actionsetid.go | 20 ++ .../costume/param_costumeid.go | 65 ++++ .../character/param_characterid/costume3d.go | 74 ++++ .../param_userid/deco/character/3d/edit.go | 70 ++++ .../deco/character/live2d/edit.go | 68 ++++ .../deco/character/situation/edit.go | 66 ++++ .../suite/user/param_userid/deco/effect.go | 73 ++++ .../user/param_userid/deco/effect/edit.go | 59 ++++ .../user/param_userid/deco/framepins/edit.go | 75 ++++ .../settings/character/useprofilesetting.go | 59 ++++ .../deco/settings/degree/useprofilesetting.go | 59 ++++ .../user/param_userid/gacha/param_gachaid.go | 92 +++++ .../graphicalinformation/param_id/watch.go | 34 ++ .../memorialstory/param_eventid/param_seq.go | 63 ++++ .../param_userid/multiroom/param_roomid.go | 331 ++++++++++++++++++ .../user/param_userid/music/param_musicid.go | 236 +++++++++++++ .../newmusicintroduction/watching/param_id.go | 51 +++ .../watching/param_id.go | 53 +++ .../actionset/album/param_characterid.go | 64 ++++ .../genericanimation/param_ganimationid.go | 51 +++ routes/api/user/param_userid/memorialstory.go | 53 +-- .../user/param_userid/profile/param_usrid.go | 99 ++++++ .../profile/search/param_targetid.go | 109 ++++++ .../param_situationid/illust/param_illust.go | 112 ++++++ utils/helper.go | 285 +++++++++++++++ utils/profile.go | 21 ++ 30 files changed, 2442 insertions(+), 212 deletions(-) create mode 100644 routes/api/suite/user/param_userid/area/item/recommended.go create mode 100644 routes/api/suite/user/param_userid/area/param_areaid/actionset/param_actionsetid.go create mode 100644 routes/api/suite/user/param_userid/character/param_characterid/costume/param_costumeid.go create mode 100644 routes/api/suite/user/param_userid/character/param_characterid/costume3d.go create mode 100644 routes/api/suite/user/param_userid/deco/character/3d/edit.go create mode 100644 routes/api/suite/user/param_userid/deco/character/live2d/edit.go create mode 100644 routes/api/suite/user/param_userid/deco/character/situation/edit.go create mode 100644 routes/api/suite/user/param_userid/deco/effect.go create mode 100644 routes/api/suite/user/param_userid/deco/effect/edit.go create mode 100644 routes/api/suite/user/param_userid/deco/framepins/edit.go create mode 100644 routes/api/suite/user/param_userid/deco/settings/character/useprofilesetting.go create mode 100644 routes/api/suite/user/param_userid/deco/settings/degree/useprofilesetting.go create mode 100644 routes/api/suite/user/param_userid/gacha/param_gachaid.go create mode 100644 routes/api/suite/user/param_userid/graphicalinformation/param_id/watch.go create mode 100644 routes/api/suite/user/param_userid/memorialstory/param_eventid/param_seq.go create mode 100644 routes/api/suite/user/param_userid/multiroom/param_roomid.go create mode 100644 routes/api/suite/user/param_userid/newmusicintroduction/watching/param_id.go create mode 100644 routes/api/suite/user/param_userid/newsituationintroduction/watching/param_id.go create mode 100644 routes/api/user/param_userid/actionset/album/param_characterid.go create mode 100644 routes/api/user/param_userid/genericanimation/param_ganimationid.go create mode 100644 routes/api/user/param_userid/profile/param_usrid.go create mode 100644 routes/api/user/param_userid/profile/search/param_targetid.go create mode 100644 routes/api/user/param_userid/situation/param_situationid/illust/param_illust.go create mode 100644 utils/profile.go diff --git a/pbutil/pbutil.go b/pbutil/pbutil.go index b151b6a..1856490 100644 --- a/pbutil/pbutil.go +++ b/pbutil/pbutil.go @@ -45,7 +45,7 @@ func Encode(message string, data map[string]any) ([]byte, error) { msg := mt.New().Interface() // map → json → proto - jsonBytes, _ := json.Marshal(data) + jsonBytes, _ := json.MarshalIndent(data, "", " ") if err := protojson.Unmarshal(jsonBytes, msg); err != nil { return nil, err } diff --git a/routes/api/suite/user/param_userid.go b/routes/api/suite/user/param_userid.go index 952e61e..8121b43 100644 --- a/routes/api/suite/user/param_userid.go +++ b/routes/api/suite/user/param_userid.go @@ -221,6 +221,15 @@ func get(c *fiber.Ctx) error { } userProfileDegree := utils.BuildUserProfileDegree(userid, user) + decoDegree := map[string]any{} + for k, v := range userProfileDegree { + entry := v.(map[string]any) + decoDegree[k] = map[string]any{ + "decoFrameId": entry["userId"], + "profileDegreeType": entry["profileDegreeType"], + "degreeId": entry["degreeId"], + } + } charProfileL2d := map[string][]int{} if cpMap, ok := m["masterCharacterProfileLive2dMap"].(map[string]any); ok { @@ -346,114 +355,6 @@ func get(c *fiber.Ctx) error { } } - leaderSitId := fmt.Sprintf("%v", mainDeck["leader"]) - leaderEntry, _ := charSituationMap[leaderSitId].(map[string]any) - leaderCharId := any(nil) - if leaderEntry != nil { - leaderCharId = leaderEntry["characterId"] - } - leaderCharIdStr := fmt.Sprintf("%v", leaderCharId) - - decos, _ := user["decos"].(map[string]any) - if decos == nil { - decos = map[string]any{} - } - - decoSit, _ := decos["situation"].(map[string]any) - decoSitId := any(1) - decoSitStatus := any("normal") - if decoSit != nil { - decoSitId = decoSit["situationId"] - decoSitStatus = decoSit["situationStatus"] - } - - decoL2d, _ := decos["live2d"].(map[string]any) - l2dCharId := leaderCharId - l2dCostumeId := any(nil) - if wc[leaderCharIdStr] != nil { - l2dCostumeId = wc[leaderCharIdStr].(map[string]any)["costumeId"] - } - l2dMotionId := any(nil) - if decoL2dMap, ok := m["masterDecoCharacterLive2dMotionMap"].(map[string]any); ok { - var firstMotion map[string]any - for _, v := range decoL2dMap["entries"].(map[string]any) { - mot := v.(map[string]any) - if fmt.Sprintf("%v", mot["characterId"]) == leaderCharIdStr { - if firstMotion == nil || mot["seq"].(float64) < firstMotion["seq"].(float64) { - firstMotion = mot - } - } - } - if firstMotion != nil { - l2dMotionId = firstMotion["motionId"] - } - } - if decoL2d != nil { - if v, ok := decoL2d["characterId"]; ok { - l2dCharId = v - } - if v, ok := decoL2d["costumeId"]; ok { - l2dCostumeId = v - } - if v, ok := decoL2d["motionId"]; ok { - l2dMotionId = v - } - } - - deco3d, _ := decos["3d"].(map[string]any) - d3dCharId := leaderCharId - d3dDressId := any(nil) - d3dHairstyleId := any(nil) - if wc[leaderCharIdStr] != nil { - d3dDressId = wc[leaderCharIdStr].(map[string]any)["dressId"] - d3dHairstyleId = wc[leaderCharIdStr].(map[string]any)["hairstyleId"] - } - d3dMotionId := any(nil) - if em3Map, ok := m["masterEnableCharacter3dMotionTypeMap"].(map[string]any); ok { - if charEntry, ok := em3Map["entries"].(map[string]any)[leaderCharIdStr].(map[string]any); ok { - if decoEntry, ok := charEntry["entries"].(map[string]any)["deco"].(map[string]any); ok { - if entries, ok := decoEntry["entries"].([]any); ok { - var first map[string]any - for _, e := range entries { - entry := e.(map[string]any) - if first == nil || entry["seq"].(float64) < first["seq"].(float64) { - first = entry - } - } - if first != nil { - d3dMotionId = first["motionId"] - } - } - } - } - } - if deco3d != nil { - if v, ok := deco3d["characterId"]; ok { - d3dCharId = v - } - if v, ok := deco3d["dressId"]; ok { - d3dDressId = v - } - if v, ok := deco3d["hairstyleId"]; ok { - d3dHairstyleId = v - } - if v, ok := deco3d["motionId"]; ok { - d3dMotionId = v - } - } - - frameId := any(1) - if v, ok := decos["frameId"]; ok { - frameId = v - } - framepins, _ := decos["framepins"].([]any) - getPin := func(i int) any { - if framepins != nil && i < len(framepins) { - return framepins[i] - } - return nil - } - musicScore, _ := user["musicScore"].(map[string]any) if musicScore == nil { musicScore = map[string]any{} @@ -493,11 +394,6 @@ func get(c *fiber.Ctx) error { } } - decoEffectId := any(1) - if v, ok := decos["effect"]; ok { - decoEffectId = v - } - digestSeen := map[any]bool{} var digestEntries []any if dsList, ok := m["masterDigestStoryDetailList"].(map[string]any); ok { @@ -547,8 +443,10 @@ func get(c *fiber.Ctx) error { "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"], + "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"], @@ -739,7 +637,7 @@ func get(c *fiber.Ctx) error { return map[string]any{"entries": result} }(), "userLiveBoostRecoveryItemList": nil, - "userHighScoreMusicRating": nil, + "userHighScoreRating": nil, "userHighScoreMusicRatingMap": nil, "userSeason": map[string]any{"seasonId": seasonId}, "userQualifyTournamentMusicScoreMap": nil, @@ -753,8 +651,8 @@ func get(c *fiber.Ctx) error { } return map[string]any{"entries": entries} }(), - "userMiracleTicketMap": map[string]any{"entries": []any{}}, - "userMiracleTicketExchangesMap": map[string]any{"entries": []any{}}, + "userMiracleTicketMap": map[string]any{"entries": map[string]any{}}, + "userMiracleTicketExchangesMap": map[string]any{"entries": map[string]any{}}, "userMultiDisconnectionBadPenalty": nil, "userSpecialLotteryDrawResultMap": nil, "userMusicScoreMap": map[string]any{"entries": musicScoreEntries}, @@ -846,47 +744,7 @@ func get(c *fiber.Ctx) error { "userDecoFrameInventoryMap": map[string]any{"entries": decoFrameEntries}, "userDecoPinsInventoryMap": map[string]any{"entries": decoPinsEntries}, "userDecoEffectInventoryMap": map[string]any{"entries": decoEffectEntries}, - "userDecoEquipment": map[string]any{ - "userDecoCharacterSituation": map[string]any{ - "userId": userid, "situationId": decoSitId, "situationStatus": decoSitStatus, - }, - "userDecoCharacterLive2d": map[string]any{ - "userId": userid, "characterId": l2dCharId, "costumeId": l2dCostumeId, - "motionId": l2dMotionId, "backgroundId": func() any { - if decoL2d != nil { - if v, ok := decoL2d["backgroundId"]; ok { - return v - } - } - return 1 - }(), - }, - "userDecoCharacter3d": map[string]any{ - "userId": userid, "characterId": d3dCharId, "dressId": d3dDressId, - "hairstyleId": d3dHairstyleId, "motionId": d3dMotionId, - "backgroundId": func() any { - if deco3d != nil { - if v, ok := deco3d["backgroundId"]; ok { - return v - } - } - return 11 - }(), - }, - "userDecoFramePins": map[string]any{ - "userId": userid, "decoFrameId": frameId, - "decoPinsId1": getPin(0), "decoPinsId2": getPin(1), - "decoPinsId3": getPin(2), "decoPinsId4": getPin(3), "decoPinsId5": getPin(4), - }, - "userDecoDegreeMap": map[string]any{"entries": userProfileDegree}, - "userDecoAppealMap": map[string]any{}, - "userDecoSetting": map[string]any{ - "useProfileSettingDegree": user["useProfileSettingDegree"], - "useProfileSettingSituation": user["useProfileSettingSituation"], - "selectedCharacterType": user["selectedCharacterType"], - }, - "userDecoEffect": map[string]any{"userId": userid, "decoEffectId": decoEffectId}, - }, + "userDecoEquipment": utils.BuildDecoEquipment(userid, user, m), "userMusicVideoListMap": func() map[string]any { result := map[string]any{} if mvlm, ok := m["masterMusicVideoListMap"].(map[string]any); ok { @@ -968,7 +826,8 @@ func get(c *fiber.Ctx) error { result := map[string]any{} if cdm, ok := m["masterCostume3dDressMap"].(map[string]any); ok { for id := range cdm["entries"].(map[string]any) { - result[id] = map[string]any{"costume3dDressId": id, "status": "obtained"} + idInt, _ := strconv.Atoi(id) + result[id] = map[string]any{"costume3dDressId": idInt, "status": "obtained"} } } return map[string]any{"entries": result} @@ -977,7 +836,8 @@ func get(c *fiber.Ctx) error { result := map[string]any{} if chm, ok := m["masterCostume3dHairstyleMap"].(map[string]any); ok { for id := range chm["entries"].(map[string]any) { - result[id] = map[string]any{"costume3dHairstyleId": id, "status": "obtained"} + idInt, _ := strconv.Atoi(id) + result[id] = map[string]any{"costume3dHairstyleId": idInt, "status": "obtained"} } } return map[string]any{"entries": result} @@ -1053,11 +913,13 @@ func get(c *fiber.Ctx) error { encoded, err := pbutil.Encode("SuiteUserGetResponse", data) if err != nil { + fmt.Println(err) return c.Status(500).SendString(err.Error()) } encrypted, err := utils.Encrypt(encoded) if err != nil { + fmt.Println(err) return c.Status(500).SendString(err.Error()) } diff --git a/routes/api/suite/user/param_userid/area.go b/routes/api/suite/user/param_userid/area.go index 2236e8d..8246d0e 100644 --- a/routes/api/suite/user/param_userid/area.go +++ b/routes/api/suite/user/param_userid/area.go @@ -8,6 +8,7 @@ import ( "bdgrp_go/utils" "fmt" "math/rand" + "strconv" "time" "github.com/gofiber/fiber/v2" @@ -83,8 +84,8 @@ func get(c *fiber.Ctx) error { var seasonId any for _, v := range seasonMap { s := v.(map[string]any) - startAt := int64(s["startAt"].(float64)) - endAt := int64(s["endAt"].(float64)) + startAt, _ := strconv.ParseInt(s["startAt"].(string), 10, 64) + endAt, _ := strconv.ParseInt(s["endAt"].(string), 10, 64) if startAt <= now && now < endAt { seasonId = s["seasonId"] break diff --git a/routes/api/suite/user/param_userid/area/item/recommended.go b/routes/api/suite/user/param_userid/area/item/recommended.go new file mode 100644 index 0000000..5c3ba26 --- /dev/null +++ b/routes/api/suite/user/param_userid/area/item/recommended.go @@ -0,0 +1,121 @@ +package item + +import ( + "bdgrp_go/db" + "bdgrp_go/master" + "bdgrp_go/pbutil" + "bdgrp_go/routes" + "bdgrp_go/utils" + "fmt" + "math/rand" + + "github.com/gofiber/fiber/v2" +) + +func init() { + path := routes.PathOf() + routes.Register(func(app *fiber.App) { + app.Put(path, recommendedAreaItem) + fmt.Println("Loaded:", path) + }) +} + +func recommendedAreaItem(c *fiber.Ctx) error { + userid := c.Params("userid") + user := db.FindUser(userid) + + decrypted, err := utils.Decrypt(c.Body()) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decoded, err := pbutil.Decode("PutAreaItemRequestBody", decrypted) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + m := master.GetMaster() + areaItemMap := m["masterAreaItemMap"].(map[string]any)["entries"].(map[string]any) + + items := map[string]any{} + if idList, ok := decoded["areaItemIdList"].([]any); ok { + for _, id := range idList { + idStr := fmt.Sprintf("%v", id) + if entry, ok := areaItemMap[idStr].(map[string]any); ok { + areaId := fmt.Sprintf("%v", entry["areaId"]) + if items[areaId] == nil { + items[areaId] = []any{} + } + items[areaId] = append(items[areaId].([]any), id) + } + } + } + user["areaItems"] = items + db.Save() + + areaMap := m["masterAreaMap"].(map[string]any)["entries"].(map[string]any) + actionSetMap := m["masterActionSetMap"].(map[string]any)["entries"].(map[string]any) + + var areaList []any + for areaId, v := range areaMap { + area, ok := v.(map[string]any) + if !ok || area["areaType"] != "common" { + continue + } + + var available []any + for _, av := range actionSetMap { + a, ok := av.(map[string]any) + if !ok { + continue + } + if fmt.Sprintf("%v", a["areaId"]) == areaId { + available = append(available, a["actionSetId"]) + } + } + + rand.Shuffle(len(available), func(i, j int) { + available[i], available[j] = available[j], available[i] + }) + count := rand.Intn(3) + 1 + if count > len(available) { + count = len(available) + } + + var actionSets []any + for _, id := range available[:count] { + actionSets = append(actionSets, map[string]any{ + "actionSetId": id, + "status": "already_read", + }) + } + + areaItemIds := []any{} + if ids, ok := items[areaId]; ok { + areaItemIds = ids.([]any) + } + + areaList = append(areaList, map[string]any{ + "areaId": area["areaId"], + "actionSets": actionSets, + "areaItemIds": areaItemIds, + }) + } + + data := map[string]any{ + "updateResources": map[string]any{}, + "userAreaList": map[string]any{"entries": areaList}, + } + + encoded, err := pbutil.Encode("SuiteUserChangeAreaItemResponse", 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) +} diff --git a/routes/api/suite/user/param_userid/area/param_areaid/actionset/param_actionsetid.go b/routes/api/suite/user/param_userid/area/param_areaid/actionset/param_actionsetid.go new file mode 100644 index 0000000..259c23e --- /dev/null +++ b/routes/api/suite/user/param_userid/area/param_areaid/actionset/param_actionsetid.go @@ -0,0 +1,20 @@ +package actionset + +import ( + "bdgrp_go/routes" + "fmt" + + "github.com/gofiber/fiber/v2" +) + +func init() { + path := routes.PathOf() + routes.Register(func(app *fiber.App) { + app.Post(path, actionSet) + fmt.Println("Loaded:", path) + }) +} + +func actionSet(c *fiber.Ctx) error { + return c.SendStatus(200) +} diff --git a/routes/api/suite/user/param_userid/character/param_characterid/costume/param_costumeid.go b/routes/api/suite/user/param_userid/character/param_characterid/costume/param_costumeid.go new file mode 100644 index 0000000..5b1192a --- /dev/null +++ b/routes/api/suite/user/param_userid/character/param_characterid/costume/param_costumeid.go @@ -0,0 +1,65 @@ +package costume + +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, changeCostume) + fmt.Println("Loaded:", path) + }) +} + +func changeCostume(c *fiber.Ctx) error { + userid := c.Params("userid") + costumeid := c.Params("costumeid") + characterid := c.Params("characterid") + + user := db.FindUser(userid) + + wearingCostume := user["wearingCostume"].(map[string]any) + costume := wearingCostume[characterid].(map[string]any) + costume["costumeId"] = costumeid + db.Save() + + charMap := map[string]any{} + for charId, v := range wearingCostume { + c2 := v.(map[string]any) + charMap[charId] = map[string]any{ + "userId": userid, + "characterId": charId, + "costumeId": c2["costumeId"], + } + } + + data := map[string]any{ + "updateResources": map[string]any{ + "userCharacterMap": map[string]any{"entries": charMap}, + }, + "userCharacter": map[string]any{ + "userId": userid, + "characterId": characterid, + "costumeId": costumeid, + }, + } + + encoded, err := pbutil.Encode("SuiteUserCharacter", 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) +} diff --git a/routes/api/suite/user/param_userid/character/param_characterid/costume3d.go b/routes/api/suite/user/param_userid/character/param_characterid/costume3d.go new file mode 100644 index 0000000..3065a7d --- /dev/null +++ b/routes/api/suite/user/param_userid/character/param_characterid/costume3d.go @@ -0,0 +1,74 @@ +package param_characterid + +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, changeCostume3d) + fmt.Println("Loaded:", path) + }) +} + +func changeCostume3d(c *fiber.Ctx) error { + userid := c.Params("userid") + user := db.FindUser(userid) + + decrypted, err := utils.Decrypt(c.Body()) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decoded, err := pbutil.Decode("UserWearingCostume3d", decrypted) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + charId := fmt.Sprintf("%v", decoded["characterId"]) + wearingCostume := user["wearingCostume"].(map[string]any) + costume := wearingCostume[charId].(map[string]any) + costume["dressId"] = decoded["costume3dDressId"] + costume["hairstyleId"] = decoded["costume3dHairstyleId"] + db.Save() + + wearingMap := map[string]any{} + for cid, v := range wearingCostume { + c2 := v.(map[string]any) + wearingMap[cid] = map[string]any{ + "characterId": cid, + "costume3dDressId": c2["dressId"], + "costume3dHairstyleId": c2["hairstyleId"], + } + } + + data := map[string]any{ + "updateResources": map[string]any{ + "userWearingCostume3dMap": map[string]any{"entries": wearingMap}, + }, + "userWearingCostume3d": map[string]any{ + "characterId": decoded["characterId"], + "costume3dDressId": decoded["costume3dDressId"], + "costume3dHairstyleId": decoded["costume3dHairstyleId"], + }, + } + + encoded, err := pbutil.Encode("SuiteUserCostume3dChangeResponse", 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) +} diff --git a/routes/api/suite/user/param_userid/deco/character/3d/edit.go b/routes/api/suite/user/param_userid/deco/character/3d/edit.go new file mode 100644 index 0000000..596c17d --- /dev/null +++ b/routes/api/suite/user/param_userid/deco/character/3d/edit.go @@ -0,0 +1,70 @@ +package deco3d + +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, deco3d) + fmt.Println("Loaded:", path) + }) +} + +func deco3d(c *fiber.Ctx) error { + userid := c.Params("userid") + user := db.FindUser(userid) + + decrypted, err := utils.Decrypt(c.Body()) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decoded, err := pbutil.Decode("UserDecoCharacter3d", decrypted) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decos := user["decos"].(map[string]any) + decos["3d"] = map[string]any{ + "characterId": decoded["characterId"], + "dressId": decoded["dressId"], + "hairstyleId": decoded["hairstyleId"], + "motionId": decoded["motionId"], + "backgroundId": decoded["backgroundId"], + } + db.Save() + + deco3d := decos["3d"].(map[string]any) + data := map[string]any{ + "updateResources": map[string]any{ + "userDecoEquipment": map[string]any{ + "userDecoCharacter3d": map[string]any{ + "userId": userid, + "characterId": deco3d["characterId"], + "dressId": deco3d["dressId"], + "hairstyleId": deco3d["hairstyleId"], + "motionId": deco3d["motionId"], + "backgroundId": deco3d["backgroundId"], + }, + }, + }, + } + + encoded, err := pbutil.Encode("SuiteUserDecoCharacter3d", 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) +} diff --git a/routes/api/suite/user/param_userid/deco/character/live2d/edit.go b/routes/api/suite/user/param_userid/deco/character/live2d/edit.go new file mode 100644 index 0000000..6c1c544 --- /dev/null +++ b/routes/api/suite/user/param_userid/deco/character/live2d/edit.go @@ -0,0 +1,68 @@ +package live2d + +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, live2d) + fmt.Println("Loaded:", path) + }) +} + +func live2d(c *fiber.Ctx) error { + userid := c.Params("userid") + user := db.FindUser(userid) + + decrypted, err := utils.Decrypt(c.Body()) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decoded, err := pbutil.Decode("UserDecoCharacterLive2d", decrypted) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decos := user["decos"].(map[string]any) + decos["live2d"] = map[string]any{ + "characterId": decoded["characterId"], + "costumeId": decoded["costumeId"], + "motionId": decoded["motionId"], + "backgroundId": decoded["backgroundId"], + } + db.Save() + + live2d := decos["live2d"].(map[string]any) + data := map[string]any{ + "updateResources": map[string]any{ + "userDecoEquipment": map[string]any{ + "userDecoCharacterLive2d": map[string]any{ + "userId": userid, + "characterId": live2d["characterId"], + "costumeId": live2d["costumeId"], + "motionId": live2d["motionId"], + "backgroundId": live2d["backgroundId"], + }, + }, + }, + } + + encoded, err := pbutil.Encode("SuiteUserDecoCharacterLive2d", 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) +} diff --git a/routes/api/suite/user/param_userid/deco/character/situation/edit.go b/routes/api/suite/user/param_userid/deco/character/situation/edit.go new file mode 100644 index 0000000..652805a --- /dev/null +++ b/routes/api/suite/user/param_userid/deco/character/situation/edit.go @@ -0,0 +1,66 @@ +package situation + +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, situation) + fmt.Println("Loaded:", path) + }) +} + +func situation(c *fiber.Ctx) error { + userid := c.Params("userid") + user := db.FindUser(userid) + + decrypted, err := utils.Decrypt(c.Body()) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decoded, err := pbutil.Decode("UserDecoCharacterSituation", decrypted) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decos := user["decos"].(map[string]any) + decos["situation"] = map[string]any{ + "situationId": decoded["situationId"], + "situationStatus": decoded["situationStatus"], + "useProfileSetting": decoded["useProfileSetting"], + } + db.Save() + + sit := decos["situation"].(map[string]any) + data := map[string]any{ + "updateResources": map[string]any{ + "userDecoEquipment": map[string]any{ + "userDecoCharacterSituation": map[string]any{ + "userId": userid, + "situationId": sit["situationId"], + "situationStatus": sit["situationStatus"], + "useProfileSetting": sit["useProfileSetting"], + }, + }, + }, + } + + encoded, err := pbutil.Encode("SuiteUserDecoCharacterSituation", 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) +} diff --git a/routes/api/suite/user/param_userid/deco/effect.go b/routes/api/suite/user/param_userid/deco/effect.go new file mode 100644 index 0000000..059819b --- /dev/null +++ b/routes/api/suite/user/param_userid/deco/effect.go @@ -0,0 +1,73 @@ +package deco + +import ( + "bdgrp_go/db" + "bdgrp_go/master" + "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, getEffect) + fmt.Println("Loaded:", path) + }) +} + +func getEffect(c *fiber.Ctx) error { + userid := c.Params("userid") + user := db.FindUser(userid) + if user == nil { + return c.Status(404).SendStatus(404) + } + + m := master.GetMaster() + now := time.Now().UnixMilli() + + decoEffectEntries := map[string]any{} + if deMap, ok := m["masterDecoEffectList"].(map[string]any); ok { + if entries, ok := deMap["entries"].([]any); ok { + for _, v := range entries { + e := v.(map[string]any) + startAt := int64(0) + endAt := int64(0) + if s, ok := e["startAt"].(string); ok { + fmt.Sscanf(s, "%d", &startAt) + } + if s, ok := e["endAt"].(string); ok { + fmt.Sscanf(s, "%d", &endAt) + } + if startAt <= now && now <= endAt { + id := fmt.Sprintf("%v", e["decoEffectId"]) + decoEffectEntries[id] = map[string]any{ + "userId": userid, + "decoEffectId": e["decoEffectId"], + } + } + } + } + } + + data := map[string]any{ + "updateResources": map[string]any{ + "userDecoEffectInventoryMap": map[string]any{"entries": decoEffectEntries}, + "userDecoEquipment": utils.BuildDecoEquipment(userid, user, m), + }, + } + + encoded, err := pbutil.Encode("UserDecoEquipmentGetResponse", 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) +} diff --git a/routes/api/suite/user/param_userid/deco/effect/edit.go b/routes/api/suite/user/param_userid/deco/effect/edit.go new file mode 100644 index 0000000..b171e7c --- /dev/null +++ b/routes/api/suite/user/param_userid/deco/effect/edit.go @@ -0,0 +1,59 @@ +package effect + +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, effect) + fmt.Println("Loaded:", path) + }) +} + +func effect(c *fiber.Ctx) error { + userid := c.Params("userid") + user := db.FindUser(userid) + + decrypted, err := utils.Decrypt(c.Body()) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decoded, err := pbutil.Decode("UserDecoEffectRequestBody", decrypted) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decos := user["decos"].(map[string]any) + decos["effect"] = decoded["decoEffectId"] + db.Save() + + data := map[string]any{ + "updateResources": map[string]any{ + "userDecoEquipment": map[string]any{ + "userDecoEffect": map[string]any{ + "userId": userid, + "decoEffectId": decos["effect"], + }, + }, + }, + } + + encoded, err := pbutil.Encode("SuiteUserDecoCharacterSituation", 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) +} diff --git a/routes/api/suite/user/param_userid/deco/framepins/edit.go b/routes/api/suite/user/param_userid/deco/framepins/edit.go new file mode 100644 index 0000000..7f7f1ad --- /dev/null +++ b/routes/api/suite/user/param_userid/deco/framepins/edit.go @@ -0,0 +1,75 @@ +package framepins + +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, editFramePins) + fmt.Println("Loaded:", path) + }) +} + +func editFramePins(c *fiber.Ctx) error { + userid := c.Params("userid") + user := db.FindUser(userid) + + decrypted, err := utils.Decrypt(c.Body()) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decoded, err := pbutil.Decode("UserDecoFramePinsRequestBody", decrypted) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + pins := make([]any, 5) + for i := 0; i < 5; i++ { + key := fmt.Sprintf("decoPinsId%d", i+1) + if v, ok := decoded[key].(float64); ok && v > 0 { + pins[i] = v + } else { + pins[i] = 0 + } + } + + decos := user["decos"].(map[string]any) + decos["framepins"] = pins + decos["frameId"] = decoded["decoFrameId"] + db.Save() + + data := map[string]any{ + "updateResources": map[string]any{ + "userDecoEquipment": map[string]any{ + "userDecoFramePins": map[string]any{ + "userId": userid, + "decoFrameId": decos["frameId"], + "decoPinsId1": pins[0], + "decoPinsId2": pins[1], + "decoPinsId3": pins[2], + "decoPinsId4": pins[3], + "decoPinsId5": pins[4], + }, + }, + }, + } + + encoded, err := pbutil.Encode("DecoFramePinsResponse", 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) +} diff --git a/routes/api/suite/user/param_userid/deco/settings/character/useprofilesetting.go b/routes/api/suite/user/param_userid/deco/settings/character/useprofilesetting.go new file mode 100644 index 0000000..210716c --- /dev/null +++ b/routes/api/suite/user/param_userid/deco/settings/character/useprofilesetting.go @@ -0,0 +1,59 @@ +package character + +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, useProfileSetting) + fmt.Println("Loaded:", path) + }) +} + +func useProfileSetting(c *fiber.Ctx) error { + userid := c.Params("userid") + user := db.FindUser(userid) + + decrypted, err := utils.Decrypt(c.Body()) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decoded, err := pbutil.Decode("UserDecoSituationUseProfileSettingRequest", decrypted) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + user["useProfileSettingSituation"] = decoded["useProfileSettingSituation"] + db.Save() + + data := map[string]any{ + "updateResources": map[string]any{ + "userDecoEquipment": map[string]any{ + "userDecoSetting": map[string]any{ + "useProfileSettingDegree": user["useProfileSettingDegree"], + "useProfileSettingSituation": user["useProfileSettingSituation"], + "selectedCharacterType": user["selectedCharacterType"], + }, + }, + }, + } + + encoded, err := pbutil.Encode("UserDecoEquipmentGetResponse", 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) +} diff --git a/routes/api/suite/user/param_userid/deco/settings/degree/useprofilesetting.go b/routes/api/suite/user/param_userid/deco/settings/degree/useprofilesetting.go new file mode 100644 index 0000000..cf94dda --- /dev/null +++ b/routes/api/suite/user/param_userid/deco/settings/degree/useprofilesetting.go @@ -0,0 +1,59 @@ +package degree + +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, useProfileSetting) + fmt.Println("Loaded:", path) + }) +} + +func useProfileSetting(c *fiber.Ctx) error { + userid := c.Params("userid") + user := db.FindUser(userid) + + decrypted, err := utils.Decrypt(c.Body()) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decoded, err := pbutil.Decode("UserDecoDegreeUseProfileSettingRequest", decrypted) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + user["useProfileSettingDegree"] = decoded["useProfileSettingDegree"] + db.Save() + + data := map[string]any{ + "updateResources": map[string]any{ + "userDecoEquipment": map[string]any{ + "userDecoSetting": map[string]any{ + "useProfileSettingDegree": user["useProfileSettingDegree"], + "useProfileSettingSituation": user["useProfileSettingSituation"], + "selectedCharacterType": user["selectedCharacterType"], + }, + }, + }, + } + + encoded, err := pbutil.Encode("UserDecoEquipmentGetResponse", 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) +} diff --git a/routes/api/suite/user/param_userid/gacha/param_gachaid.go b/routes/api/suite/user/param_userid/gacha/param_gachaid.go new file mode 100644 index 0000000..d9f4ec1 --- /dev/null +++ b/routes/api/suite/user/param_userid/gacha/param_gachaid.go @@ -0,0 +1,92 @@ +package gacha + +import ( + "bdgrp_go/master" + "bdgrp_go/pbutil" + "bdgrp_go/routes" + "bdgrp_go/utils" + "fmt" + "math/rand" + + "github.com/gofiber/fiber/v2" +) + +func init() { + path := routes.PathOf() + routes.Register(func(app *fiber.App) { + app.Put(path, gacha) + fmt.Println("Loaded:", path) + }) +} + +func gacha(c *fiber.Ctx) error { + gachaid := c.Params("gachaid") + + decrypted, err := utils.Decrypt(c.Body()) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decoded, err := pbutil.Decode("UserGachaRequest", decrypted) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + m := master.GetMaster() + gachaMap := m["masterGachaMap"].(map[string]any)["entries"].(map[string]any) + gachaEntry, ok := gachaMap[gachaid].(map[string]any) + if !ok { + return c.Status(404).SendString("gacha not found") + } + + var list []any + if details, ok := gachaEntry["details"].([]any); ok { + for _, d := range details { + detail := d.(map[string]any) + if detail["rarityIndex"].(float64) == 5 { + list = append(list, detail["situationId"]) + } + } + } + + paymentMethodId := decoded["paymentMethodId"] + count := 0 + if methods, ok := gachaEntry["paymentMethods"].([]any); ok { + for _, pm := range methods { + method := pm.(map[string]any) + if fmt.Sprintf("%v", method["paymentMethodId"]) == fmt.Sprintf("%v", paymentMethodId) { + count = int(method["count"].(float64)) + break + } + } + } + + entries := make([]any, count) + for i := range entries { + entries[i] = map[string]any{ + "situationId": list[rand.Intn(len(list))], + "isFirstGet": true, + } + } + + data := map[string]any{ + "gachaResults": map[string]any{ + "entries": entries, + "extras": map[string]any{}, + "beforeGachaSeal": 14, + "afterGachaSeal": 15, + "gachaGuaranteedRarity": "none", + }, + "updateResources": map[string]any{}, + } + + encoded, err := pbutil.Encode("SuiteUserGachaResponse", 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) +} diff --git a/routes/api/suite/user/param_userid/graphicalinformation/param_id/watch.go b/routes/api/suite/user/param_userid/graphicalinformation/param_id/watch.go new file mode 100644 index 0000000..d061f5c --- /dev/null +++ b/routes/api/suite/user/param_userid/graphicalinformation/param_id/watch.go @@ -0,0 +1,34 @@ +package param_id + +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, watch) + fmt.Println("Loaded:", path) + }) +} + +func watch(c *fiber.Ctx) error { + data := map[string]any{ + "userGraphicalInformationList": map[string]any{}, + } + + encoded, err := pbutil.Encode("SuiteUserGetResponse", 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) +} diff --git a/routes/api/suite/user/param_userid/memorialstory/param_eventid/param_seq.go b/routes/api/suite/user/param_userid/memorialstory/param_eventid/param_seq.go new file mode 100644 index 0000000..502323d --- /dev/null +++ b/routes/api/suite/user/param_userid/memorialstory/param_eventid/param_seq.go @@ -0,0 +1,63 @@ +package param_eventid + +import ( + "bdgrp_go/master" + "bdgrp_go/pbutil" + "bdgrp_go/routes" + "bdgrp_go/utils" + "encoding/json" + "fmt" + "os" + "path/filepath" + + "github.com/gofiber/fiber/v2" +) + +func init() { + path := routes.PathOf() + routes.Register(func(app *fiber.App) { + app.Post(path, readStory) + fmt.Println("Loaded:", path) + }) +} + +func readStory(c *fiber.Ctx) error { + userid := c.Params("userid") + eventid := c.Params("eventid") + seq := c.Params("seq") + + m := master.GetMaster() + server := os.Getenv("SERVER") + + pastData, _ := os.ReadFile(filepath.Join("pastEvents", server+".json")) + var past map[string]any + json.Unmarshal(pastData, &past) + + eventStoryEntries := utils.BuildEventStoryMemorialMap(userid, m, past) + + data := map[string]any{ + "updateResources": map[string]any{ + "userEventStoryMemorialMap": map[string]any{"entries": eventStoryEntries}, + }, + "userStoryEventReadStoryResponse": map[string]any{ + "readUserEventStory": map[string]any{ + "userId": userid, + "eventId": eventid, + "seq": seq, + "status": "already_read", + }, + "rewards": map[string]any{}, + "newlyOpenedContents": map[string]any{}, + }, + } + + encoded, err := pbutil.Encode("SuiteReadStoryResponse", 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) +} diff --git a/routes/api/suite/user/param_userid/multiroom/param_roomid.go b/routes/api/suite/user/param_userid/multiroom/param_roomid.go new file mode 100644 index 0000000..1149f20 --- /dev/null +++ b/routes/api/suite/user/param_userid/multiroom/param_roomid.go @@ -0,0 +1,331 @@ +package multiroom + +import ( + "fmt" + "strconv" + + "bdgrp_go/db" + "bdgrp_go/master" + "bdgrp_go/pbutil" + "bdgrp_go/routes" + "bdgrp_go/utils" + + "github.com/gofiber/fiber/v2" +) + +func init() { + path := routes.PathOf() + + routes.Register(func(app *fiber.App) { + app.Post(path, post) + fmt.Println("Loaded:", path) + }) +} + +var drops = []map[string]any{ + {"resourceType": "coin", "quantity": 10000, "lbBonus": 20}, + {"resourceId": 1, "resourceType": "practice_ticket", "quantity": 100, "lbBonus": 20}, + {"resourceId": 2, "resourceType": "item", "quantity": 240, "lbBonus": 20}, + {"resourceId": 1, "resourceType": "item", "quantity": 240, "lbBonus": 20}, + {"resourceId": 3, "resourceType": "item", "quantity": 240, "lbBonus": 20}, + {"resourceId": 8, "resourceType": "item", "quantity": 160, "lbBonus": 20}, + {"resourceId": 7, "resourceType": "item", "quantity": 160, "lbBonus": 20}, + {"resourceId": 8, "resourceType": "item", "quantity": 160, "lbBonus": 20}, +} + +func getMultiScoreRank( + score uint32, + difficultyMaster map[string]any, + multiDifficulty uint32, +) string { + if difficultyMaster == nil { + return "c" + } + + multiMap, _ := difficultyMaster["multiLiveScoreMap"].(map[string]any) + target, _ := multiMap[strconv.FormatUint(uint64(multiDifficulty), 10)].(map[string]any) + + if target == nil { + return "c" + } + + getScore := func(key string) float64 { + switch value := target[key].(type) { + case float64: + return value + case uint32: + return float64(value) + case int: + return float64(value) + default: + return 0 + } + } + + value := float64(score) + + switch { + case value >= getScore("scoreSS"): + return "ss" + case value >= getScore("scoreS"): + return "s" + case value >= getScore("scoreA"): + return "a" + case value >= getScore("scoreB"): + return "b" + default: + return "c" + } +} + +func post(c *fiber.Ctx) error { + userid := c.Params("userid") + + user := db.FindUser(userid) + + decrypted, err := utils.Decrypt(c.Body()) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decoded, err := pbutil.Decode("UserMultiRoomRequest", decrypted) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + m := master.GetMaster() + if m == nil { + return c.Status(500). + SendString("master data unavailable") + } + + musicId := uint32(decoded["musicId"].(float64)) + musicIdString := strconv.FormatUint(uint64(musicId), 10) + + difficulty := fmt.Sprintf("%v", decoded["musicDifficulty"]) + score := uint32(decoded["score"].(float64)) + multiScore := uint32(decoded["multiScore"].(float64)) + multiDifficulty := uint32(decoded["multiDifficulty"].(float64)) + + musicScore, _ := user["musicScore"].(map[string]any) + if musicScore == nil { + musicScore = map[string]any{} + user["musicScore"] = musicScore + } + + scoreData, _ := musicScore[musicIdString].(map[string]any) + if scoreData == nil { + scoreData = map[string]any{ + "entries": []any{}, + } + musicScore[musicIdString] = scoreData + } + + entries, _ := scoreData["entries"].([]any) + + diffMaster := utils.GetMusicInfo( + m, + musicIdString, + difficulty, + ) + + scoreInfo := map[string]any{ + "userId": userid, + "musicId": musicId, + "musicDifficulty": difficulty, + "soloHighScore": score, + "maxCombo": decoded["combo"], + "soloScoreRank": utils.GetScoreRank(float64(score), diffMaster), + "clearStatus": decoded["clearStatus"], + } + + found := false + + for i, raw := range entries { + entry, ok := raw.(map[string]any) + if !ok { + continue + } + + if fmt.Sprintf("%v", entry["musicDifficulty"]) != difficulty { + continue + } + + found = true + + oldScore, _ := entry["soloHighScore"].(float64) + if oldScore < float64(score) { + entries[i] = scoreInfo + } + + break + } + + if !found { + entries = append(entries, scoreInfo) + } + + scoreData["entries"] = entries + db.Save() + + decks, _ := user["decks"].([]any) + mainDeckIndex := 0 + + if value, ok := user["mainDeck"].(float64); ok && int(value) > 1 { + mainDeckIndex = int(value) - 1 + } + + if len(decks) == 0 || mainDeckIndex >= len(decks) { + return c.Status(500). + SendString("main deck unavailable") + } + + mainDeck, _ := decks[mainDeckIndex].(map[string]any) + + situationFields := []string{ + "leader", + "member1", + "member2", + "member3", + "member4", + } + + characterSituationMap, _ := m["masterCharacterSituationMap"].(map[string]any) + + characterSituationEntries, _ := characterSituationMap["entries"].(map[string]any) + + situationIDs := make([]any, 0) + characterIDs := make([]int, 0) + seenCharacters := map[int]bool{} + + for _, field := range situationFields { + situationID, ok := mainDeck[field] + if !ok || situationID == nil { + continue + } + + situationIDs = append(situationIDs, situationID) + + entry, _ := characterSituationEntries[fmt.Sprintf("%v", situationID)].(map[string]any) + + if entry == nil { + continue + } + + characterID, ok := entry["characterId"].(float64) + if !ok { + continue + } + + id := int(characterID) + if !seenCharacters[id] { + seenCharacters[id] = true + characterIDs = append(characterIDs, id) + } + } + + userSituations := utils.BuildUserSituations(userid, m, user) + situationList := make([]any, 0) + + for _, situationID := range situationIDs { + for _, raw := range userSituations { + situation, _ := raw.(map[string]any) + if fmt.Sprintf("%v", situation["situationId"]) == + fmt.Sprintf("%v", situationID) { + situationList = append(situationList, situation) + break + } + } + } + + characterRankEntries := map[string]any{} + + for _, characterID := range characterIDs { + characterRankEntries[strconv.Itoa(characterID)] = map[string]any{ + "rank": 100, + "exp": 0, + "addExp": 0, + "nextExp": 0, + "totalExp": 0, + "releasedPotentialLevel": 50, + } + } + + data := map[string]any{ + "updateResources": map[string]any{ + "userMusicScoreMap": utils.BuildMusicScoreMap(user), + "userMusicClearInfoMap": utils.ComputeMusicClearInfo( + musicScore, + ), + "userMusicClearCountInfoMap": utils.ComputeMusicClearCountInfo( + musicScore, + ), + }, + + "drops": map[string]any{ + "entries": drops, + }, + + "newlyOpenedContents": map[string]any{}, + + "userBandRankList": map[string]any{ + "entries": []any{ + map[string]any{ + "userId": userid, + "bandId": 5, + "bandRank": 22, + "exp": 8280, + "addExp": 6000, + "totalExp": 101880, + "nextExp": 7520, + }, + }, + }, + + "userSituationList": map[string]any{ + "entries": situationList, + }, + + "achievementRewards": map[string]any{}, + "lbBonus": 20, + "lbUseCount": 10, + "soloScoreRank": utils.GetScoreRank(float64(score), diffMaster), + "multiScoreRank": getMultiScoreRank(multiScore, diffMaster, multiDifficulty), + "userMusicAchievementMap": map[string]any{}, + "dairyLiveRewardReceive": "REWARDRECEIVE", + "limitedDrops": map[string]any{}, + + "updatedBandDeckRankList": map[string]any{ + "entries": []any{ + map[string]any{ + "bandId": 5, + "beforeSymbol": "ss", + "beforeLevel": 1, + "afterSymbol": "ss", + "afterLevel": 1, + }, + }, + }, + + "livePoint": 114514, + + "userCharacterRankMap": map[string]any{ + "entries": characterRankEntries, + }, + } + + encoded, err := pbutil.Encode("SuiteUserMultiRoom", 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()) + } + + c.Set("Content-Type", "application/octet-stream") + return c.Send(encrypted) +} diff --git a/routes/api/suite/user/param_userid/music/param_musicid.go b/routes/api/suite/user/param_userid/music/param_musicid.go index 9df264e..0f2198f 100644 --- a/routes/api/suite/user/param_userid/music/param_musicid.go +++ b/routes/api/suite/user/param_userid/music/param_musicid.go @@ -1 +1,237 @@ package music + +import ( + "fmt" + "strconv" + + "bdgrp_go/db" + "bdgrp_go/master" + "bdgrp_go/pbutil" + "bdgrp_go/routes" + "bdgrp_go/utils" + + "github.com/gofiber/fiber/v2" +) + +func init() { + path := routes.PathOf() + routes.Register(func(app *fiber.App) { + app.Put(path, put) + fmt.Println("Loaded:", path) + }) +} + +var drops = []map[string]any{ + {"resourceType": "coin", "quantity": 10000, "lbBonus": 20}, + {"resourceId": 1, "resourceType": "practice_ticket", "quantity": 100, "lbBonus": 20}, + {"resourceId": 2, "resourceType": "item", "quantity": 240, "lbBonus": 20}, + {"resourceId": 1, "resourceType": "item", "quantity": 240, "lbBonus": 20}, + {"resourceId": 3, "resourceType": "item", "quantity": 240, "lbBonus": 20}, + {"resourceId": 8, "resourceType": "item", "quantity": 160, "lbBonus": 20}, + {"resourceId": 7, "resourceType": "item", "quantity": 160, "lbBonus": 20}, + {"resourceId": 8, "resourceType": "item", "quantity": 160, "lbBonus": 20}, +} + +func put(c *fiber.Ctx) error { + userid := c.Params("userid") + musicid := c.Params("musicid") + + user := db.FindUser(userid) + + decrypted, err := utils.Decrypt(c.Body()) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + decoded, err := pbutil.Decode("UserMusicRequest", decrypted) + if err != nil { + return c.Status(400).SendString(err.Error()) + } + + m := master.GetMaster() + if m == nil { + return c.Status(500).SendString("master data unavailable") + } + + musicScore, _ := user["musicScore"].(map[string]any) + if musicScore == nil { + musicScore = map[string]any{} + user["musicScore"] = musicScore + } + + scoreData, _ := musicScore[musicid].(map[string]any) + if scoreData == nil { + scoreData = map[string]any{"entries": []any{}} + musicScore[musicid] = scoreData + } + + entries, _ := scoreData["entries"].([]any) + difficulty := fmt.Sprintf("%v", decoded["musicDifficulty"]) + score := uint32(decoded["score"].(float64)) + + diffMaster := utils.GetMusicInfo(m, musicid, difficulty) + + scoreInfo := map[string]any{ + "userId": userid, + "musicId": score, + "musicDifficulty": difficulty, + "soloHighScore": score, + "maxCombo": decoded["combo"], + "soloScoreRank": utils.GetScoreRank(float64(score), diffMaster), + "clearStatus": decoded["clearStatus"], + } + + first := true + + for i, raw := range entries { + entry, ok := raw.(map[string]any) + if !ok || fmt.Sprintf("%v", entry["musicDifficulty"]) != difficulty { + continue + } + + first = false + + oldScore, _ := entry["soloHighScore"].(float64) + if oldScore < float64(score) { + entries[i] = scoreInfo + } + + break + } + + if first { + entries = append(entries, scoreInfo) + } + + scoreData["entries"] = entries + db.Save() + + decks, _ := user["decks"].([]any) + mainDeckIndex := 0 + + if value, ok := user["mainDeck"].(float64); ok && int(value) > 1 { + mainDeckIndex = int(value) - 1 + } + + if len(decks) == 0 || mainDeckIndex >= len(decks) { + return c.Status(500).SendString("main deck unavailable") + } + + mainDeck, _ := decks[mainDeckIndex].(map[string]any) + situationFields := []string{"leader", "member1", "member2", "member3", "member4"} + + characterSituationMap, _ := m["masterCharacterSituationMap"].(map[string]any) + characterSituationEntries, _ := characterSituationMap["entries"].(map[string]any) + + situationIDs := make([]any, 0) + seen := map[int]bool{} + characterIDs := make([]int, 0) + + for _, field := range situationFields { + sid, ok := mainDeck[field] + if !ok || sid == nil { + continue + } + + situationIDs = append(situationIDs, sid) + + entry, _ := characterSituationEntries[fmt.Sprintf("%v", sid)].(map[string]any) + if entry == nil { + continue + } + + if cid, ok := entry["characterId"].(float64); ok { + id := int(cid) + if !seen[id] { + seen[id] = true + characterIDs = append(characterIDs, id) + } + } + } + + userSituations := utils.BuildUserSituations(userid, m, user) + situationList := make([]any, 0) + + for _, sid := range situationIDs { + for _, raw := range userSituations { + situation, _ := raw.(map[string]any) + if fmt.Sprintf("%v", situation["situationId"]) == fmt.Sprintf("%v", sid) { + situationList = append(situationList, situation) + break + } + } + } + + characterRankEntries := map[string]any{} + for _, characterID := range characterIDs { + characterRankEntries[strconv.Itoa(characterID)] = map[string]any{ + "rank": 100, "exp": 0, "addExp": 0, + "nextExp": 0, "totalExp": 0, + "releasedPotentialLevel": 50, + } + } + + responseMusicScore := utils.BuildMusicScoreMap(user) + + if first { + scoreMap := responseMusicScore["entries"].(map[string]any) + musicResponse := scoreMap[musicid].(map[string]any) + responseEntries := musicResponse["entries"].([]any) + + for _, raw := range responseEntries { + entry := raw.(map[string]any) + if fmt.Sprintf("%v", entry["musicDifficulty"]) == difficulty { + entry["soloHighScore"] = uint32(0) + } + } + } + + data := map[string]any{ + "updateResources": map[string]any{ + "userMusicScoreMap": responseMusicScore, + "userMusicClearInfoMap": utils.ComputeMusicClearInfo(musicScore), + "userMusicClearCountInfoMap": utils.ComputeMusicClearCountInfo(musicScore), + }, + "drops": map[string]any{"entries": drops}, + "newlyOpenedContents": map[string]any{}, + "userBandRankList": map[string]any{ + "entries": []any{map[string]any{ + "userId": userid, "bandId": 5, "bandRank": 22, + "exp": 8280, "addExp": 6000, + "totalExp": 101880, "nextExp": 7520, + }}, + }, + "userSituationList": map[string]any{"entries": situationList}, + "achievementRewards": map[string]any{}, + "lbBonus": 20, + "lbUseCount": 10, + "soloScoreRank": utils.GetScoreRank(float64(score), diffMaster), + "userMusicAchievementMap": map[string]any{}, + "dairyLiveRewardReceive": "REWARDRECEIVE", + "limitedDrops": map[string]any{}, + "updatedBandDeckRankList": map[string]any{ + "entries": []any{map[string]any{ + "bandId": 5, "beforeSymbol": "ss", + "beforeLevel": 1, "afterSymbol": "ss", + "afterLevel": 1, + }}, + }, + "livePoint": 114514, + "userCharacterRankMap": map[string]any{ + "entries": characterRankEntries, + }, + } + + encoded, err := pbutil.Encode("SuiteUserMusic", 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()) + } + + c.Set("Content-Type", "application/octet-stream") + return c.Send(encrypted) +} diff --git a/routes/api/suite/user/param_userid/newmusicintroduction/watching/param_id.go b/routes/api/suite/user/param_userid/newmusicintroduction/watching/param_id.go new file mode 100644 index 0000000..6328a87 --- /dev/null +++ b/routes/api/suite/user/param_userid/newmusicintroduction/watching/param_id.go @@ -0,0 +1,51 @@ +package watching + +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.Post(path, watch) + fmt.Println("Loaded:", path) + }) +} + +func watch(c *fiber.Ctx) error { + userid := c.Params("userid") + m := master.GetMaster() + + entries := map[string]any{} + if nm, ok := m["masterNewMusicIntroductionMap"].(map[string]any); ok { + for _, v := range nm["entries"].(map[string]any) { + item := v.(map[string]any) + id := fmt.Sprintf("%v", item["newMusicIntroductionId"]) + entries[id] = map[string]any{ + "userId": userid, + "newMusicIntroductionId": item["newMusicIntroductionId"], + "status": "already_read", + } + } + } + + data := map[string]any{ + "userNewMusicIntroductionMap": map[string]any{"entries": entries}, + } + + encoded, err := pbutil.Encode("SuiteUserGetResponse", 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) +} diff --git a/routes/api/suite/user/param_userid/newsituationintroduction/watching/param_id.go b/routes/api/suite/user/param_userid/newsituationintroduction/watching/param_id.go new file mode 100644 index 0000000..2de9fae --- /dev/null +++ b/routes/api/suite/user/param_userid/newsituationintroduction/watching/param_id.go @@ -0,0 +1,53 @@ +package watching + +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.Post(path, watch) + fmt.Println("Loaded:", path) + }) +} + +func watch(c *fiber.Ctx) error { + userid := c.Params("userid") + m := master.GetMaster() + + entries := map[string]any{} + if nsi, ok := m["masterNewSituationIntroductionList"].(map[string]any); ok { + if list, ok := nsi["entries"].([]any); ok { + for _, v := range list { + item := v.(map[string]any) + id := fmt.Sprintf("%v", item["newSituationIntroductionId"]) + entries[id] = map[string]any{ + "userId": userid, + "newSituationIntroductionId": item["newSituationIntroductionId"], + "status": "already_read", + } + } + } + } + + data := map[string]any{ + "userNewSituationIntroductionMap": map[string]any{"entries": entries}, + } + + encoded, err := pbutil.Encode("SuiteUserGetResponse", 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) +} diff --git a/routes/api/user/param_userid/actionset/album/param_characterid.go b/routes/api/user/param_userid/actionset/album/param_characterid.go new file mode 100644 index 0000000..1251534 --- /dev/null +++ b/routes/api/user/param_userid/actionset/album/param_characterid.go @@ -0,0 +1,64 @@ +package album + +import ( + "bdgrp_go/master" + "bdgrp_go/pbutil" + "bdgrp_go/routes" + "bdgrp_go/utils" + "fmt" + "strconv" + + "github.com/gofiber/fiber/v2" +) + +func init() { + path := routes.PathOf() + routes.Register(func(app *fiber.App) { + app.Get(path, albumMap) + fmt.Println("Loaded:", path) + }) +} + +func albumMap(c *fiber.Ctx) error { + characterid, _ := strconv.Atoi(c.Params("characterid")) + m := master.GetMaster() + + entries := map[string]any{} + if asm, ok := m["masterActionSetMap"].(map[string]any); ok { + for key, v := range asm["entries"].(map[string]any) { + item, ok := v.(map[string]any) + if !ok { + continue + } + charIds, ok := item["characterIds"].([]any) + if !ok { + continue + } + for _, cid := range charIds { + if int(cid.(float64)) == characterid { + entry := map[string]any{ + "actionSetId": item["actionSetId"], + "balloonText": item["balloonText"], + } + if _, ok := item["endSeason"]; ok { + entry["isMemorial"] = true + } + entries[key] = entry + break + } + } + } + } + + encoded, err := pbutil.Encode("UserActionSetAlbumMap", map[string]any{"entries": entries}) + 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) +} diff --git a/routes/api/user/param_userid/genericanimation/param_ganimationid.go b/routes/api/user/param_userid/genericanimation/param_ganimationid.go new file mode 100644 index 0000000..9a11153 --- /dev/null +++ b/routes/api/user/param_userid/genericanimation/param_ganimationid.go @@ -0,0 +1,51 @@ +package genericanimation + +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.Post(path, animation) + fmt.Println("Loaded:", path) + }) +} + +func animation(c *fiber.Ctx) error { + userid := c.Params("userid") + m := master.GetMaster() + + entries := map[string]any{} + if gam, ok := m["masterGenericAnimationMap"].(map[string]any); ok { + for id := range gam["entries"].(map[string]any) { + entries[id] = map[string]any{ + "userId": userid, + "genericAnimationId": id, + "status": "already_read", + } + } + } + + data := map[string]any{ + "userGenericAnimationMap": map[string]any{"entries": entries}, + } + + encoded, err := pbutil.Encode("SuiteUserGetResponse", 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) +} diff --git a/routes/api/user/param_userid/memorialstory.go b/routes/api/user/param_userid/memorialstory.go index fda274e..4990dc0 100644 --- a/routes/api/user/param_userid/memorialstory.go +++ b/routes/api/user/param_userid/memorialstory.go @@ -17,64 +17,23 @@ import ( func init() { path := routes.PathOf() routes.Register(func(app *fiber.App) { - app.Get(path, handle) + app.Get(path, getMemorialStory) fmt.Println("Loaded:", path) }) } -func handle(c *fiber.Ctx) error { +func getMemorialStory(c *fiber.Ctx) error { userid := c.Params("userid") m := master.GetMaster() + server := os.Getenv("SERVER") - // 讀 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") - } + pastData, _ := os.ReadFile(filepath.Join("pastEvents", server+".json")) 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, + "entries": utils.BuildEventStoryMemorialMap(userid, m, past), }, } maps.Copy(data, past) @@ -83,11 +42,9 @@ func handle(c *fiber.Ctx) error { 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) } diff --git a/routes/api/user/param_userid/profile/param_usrid.go b/routes/api/user/param_userid/profile/param_usrid.go new file mode 100644 index 0000000..5a5c477 --- /dev/null +++ b/routes/api/user/param_userid/profile/param_usrid.go @@ -0,0 +1,99 @@ +package profile + +import ( + "bdgrp_go/db" + "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.Put(path, profile) + fmt.Println("Loaded:", path) + }) +} + +func profile(c *fiber.Ctx) error { + userid := c.Params("usrid") + user := db.FindUser(userid) + m := master.GetMaster() + + userSituations := utils.BuildUserSituations(userid, m, user) + situationMap := map[string]any{} + for _, sit := range userSituations { + s := sit.(map[string]any) + situationMap[fmt.Sprintf("%v", s["situationId"])] = s + } + + decks := user["decks"].([]any) + mainDeckIdx := 1 + if md, ok := user["mainDeck"].(float64); ok { + mainDeckIdx = int(md) + } + mainDeck := decks[mainDeckIdx-1].(map[string]any) + + situationIdFields := []string{"leader", "member1", "member2", "member3", "member4"} + var mainDeckSituations []any + for _, field := range situationIdFields { + if sid, ok := mainDeck[field]; ok && sid != nil { + sidStr := fmt.Sprintf("%v", sid) + if s, ok := situationMap[sidStr]; ok { + mainDeckSituations = append(mainDeckSituations, s) + } + } + } + + userProfileDegree := utils.BuildUserProfileDegree(userid, user) + musicScore, _ := user["musicScore"].(map[string]any) + + data := map[string]any{ + "userName": user["userName"], + "rank": user["rank"], + "degree": 100, + "introduction": user["introduction"], + "searchableFlg": true, + "publishUpdatedAtFlg": true, + "friendApplicableFlg": true, + "publishStageChallengeFriendRankingFlg": true, + "mainDeckUserSituations": map[string]any{"entries": mainDeckSituations}, + "enabledUserAreaItems": map[string]any{}, + "bandRankMap": map[string]any{"entries": utils.BandRankMap}, + "userHighScoreRating": map[string]any{ + "userPoppinPartyHighScoreMusicList": map[string]any{}, + "userPastelPalettesHighScoreMusicList": map[string]any{}, + "userRoseliaHighScoreMusicList": map[string]any{}, + "userOtherHighScoreMusicList": map[string]any{}, + "userMorfonicaHighScoreMusicList": map[string]any{}, + "userRaiseASuilenHighScoreMusicList": map[string]any{}, + "userMyGOScoreMusicList": map[string]any{}, + }, + "mainUserDeck": mainDeck, + "userProfileSituation": map[string]any{}, + "userProfileDegreeMap": map[string]any{"entries": userProfileDegree}, + "userTwitter": map[string]any{}, + "userDeckTotalRatingMap": map[string]any{"entries": utils.DeckRatingMap}, + "stageChallengeAchievementConditionsMap": map[string]any{}, + "userMusicClearInfoMap": utils.ComputeMusicClearInfo(musicScore), + "userCharacterRankMap": utils.BuildCharacterRankMap(), + } + + encoded, err := pbutil.Encode("UserProfile", data) + if err != nil { + fmt.Println(err) + return c.Status(500).SendString(err.Error()) + } + + encrypted, err := utils.Encrypt(encoded) + if err != nil { + fmt.Println(err) + return c.Status(500).SendString(err.Error()) + } + + return c.Send(encrypted) +} diff --git a/routes/api/user/param_userid/profile/search/param_targetid.go b/routes/api/user/param_userid/profile/search/param_targetid.go new file mode 100644 index 0000000..74efd9d --- /dev/null +++ b/routes/api/user/param_userid/profile/search/param_targetid.go @@ -0,0 +1,109 @@ +package search + +import ( + "bdgrp_go/db" + "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.Put(path, profileSearch) + fmt.Println("Loaded:", path) + }) +} + +func profileSearch(c *fiber.Ctx) error { + targetid := c.Params("targetid") + user := db.FindUser(targetid) + + var data map[string]any + + if user == nil { + data = map[string]any{"searchSuccessFlg": false} + } else { + m := master.GetMaster() + userid := fmt.Sprintf("%v", user["userId"]) + + userSituations := utils.BuildUserSituations(userid, m, user) + situationMap := map[string]any{} + for _, sit := range userSituations { + s := sit.(map[string]any) + situationMap[fmt.Sprintf("%v", s["situationId"])] = s + } + + decks := user["decks"].([]any) + mainDeckIdx := 1 + if md, ok := user["mainDeck"].(float64); ok { + mainDeckIdx = int(md) + } + mainDeck := decks[mainDeckIdx-1].(map[string]any) + + situationIdFields := []string{"leader", "member1", "member2", "member3", "member4"} + var mainDeckSituations []any + for _, field := range situationIdFields { + if sid, ok := mainDeck[field]; ok && sid != nil { + sidStr := fmt.Sprintf("%v", sid) + if s, ok := situationMap[sidStr]; ok { + mainDeckSituations = append(mainDeckSituations, s) + } + } + } + + userProfileDegree := utils.BuildUserProfileDegree(userid, user) + musicScore, _ := user["musicScore"].(map[string]any) + + data = map[string]any{ + "userProfile": map[string]any{ + "userName": user["userName"], + "rank": user["rank"], + "degree": 100, + "introduction": user["introduction"], + "searchableFlg": true, + "publishUpdatedAtFlg": true, + "friendApplicableFlg": true, + "publishStageChallengeFriendRankingFlg": true, + "mainDeckUserSituations": map[string]any{"entries": mainDeckSituations}, + "enabledUserAreaItems": map[string]any{}, + "bandRankMap": map[string]any{"entries": utils.BandRankMap}, + "userHighScoreRating": map[string]any{ + "userPoppinPartyHighScoreMusicList": map[string]any{}, + "userPastelPalettesHighScoreMusicList": map[string]any{}, + "userRoseliaHighScoreMusicList": map[string]any{}, + "userOtherHighScoreMusicList": map[string]any{}, + "userMorfonicaHighScoreMusicList": map[string]any{}, + "userRaiseASuilenHighScoreMusicList": map[string]any{}, + "userMyGOScoreMusicList": map[string]any{}, + }, + "mainUserDeck": mainDeck, + "userProfileSituation": map[string]any{}, + "userProfileDegreeMap": map[string]any{"entries": userProfileDegree}, + "userTwitter": map[string]any{}, + "userDeckTotalRatingMap": map[string]any{"entries": utils.DeckRatingMap}, + "stageChallengeAchievementConditionsMap": map[string]any{}, + "userMusicClearInfoMap": utils.ComputeMusicClearInfo(musicScore), + "userCharacterRankMap": utils.BuildCharacterRankMap(), + }, + } + } + + encoded, err := pbutil.Encode("UserProfileSearchResponse", data) + if err != nil { + fmt.Println(err) + return c.Status(500).SendString(err.Error()) + } + + encrypted, err := utils.Encrypt(encoded) + if err != nil { + fmt.Println(err) + return c.Status(500).SendString(err.Error()) + } + + return c.Send(encrypted) +} diff --git a/routes/api/user/param_userid/situation/param_situationid/illust/param_illust.go b/routes/api/user/param_userid/situation/param_situationid/illust/param_illust.go new file mode 100644 index 0000000..68b589b --- /dev/null +++ b/routes/api/user/param_userid/situation/param_situationid/illust/param_illust.go @@ -0,0 +1,112 @@ +package illust + +import ( + "bdgrp_go/db" + "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.Put(path, setIllust) + fmt.Println("Loaded:", path) + }) +} + +func setIllust(c *fiber.Ctx) error { + userid := c.Params("userid") + situationid := c.Params("situationid") + illust := c.Params("illust") + + user := db.FindUser(userid) + + situationIllust, _ := user["situationIllust"].(map[string]any) + if situationIllust == nil { + situationIllust = map[string]any{} + user["situationIllust"] = situationIllust + } + situationIllust[situationid] = illust + db.Save() + + m := master.GetMaster() + charSituationMap := m["masterCharacterSituationMap"].(map[string]any)["entries"].(map[string]any) + + var sit map[string]any + for _, v := range charSituationMap { + s := v.(map[string]any) + if fmt.Sprintf("%v", s["situationId"]) == situationid { + sit = s + break + } + } + if sit == nil { + return c.Status(404).SendString("situation not found") + } + + maxLevel := 0 + if paramMap, ok := sit["parameterMap"].(map[string]any); ok { + for k := range paramMap { + var level int + fmt.Sscanf(k, "%d", &level) + if level > maxLevel { + maxLevel = level + } + } + } + + rarity, _ := sit["rarity"].(float64) + hasTraining := rarity >= 3 + + data := map[string]any{ + "userId": userid, + "situationId": sit["situationId"], + "level": maxLevel, + "exp": 0, + "createdAt": sit["releasedAt"], + "addExp": 0, + "trainingStatus": map[bool]string{true: "done", false: "not_doing"}[hasTraining], + "duplicateCount": 0, + "illust": illust, + "skillExp": 0, + "skillLevel": 5, + "limitBreakRank": 0, + } + + if hasTraining { + training, _ := sit["training"].(map[string]any) + appendParam := map[string]any{ + "userId": userid, + "situationId": sit["situationId"], + "characterPotentialPerformance": 30, + "characterPotentialTechnique": 30, + "characterPotentialVisual": 30, + "characterBonusPerformance": 30, + "characterBonusTechnique": 30, + "characterBonusVisual": 30, + } + if training != nil { + appendParam["performance"] = training["trainingPerformance"] + appendParam["technique"] = training["trainingTechnique"] + appendParam["visual"] = training["trainingVisual"] + } + data["userAppendParameter"] = appendParam + } + + encoded, err := pbutil.Encode("UserSituation", 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) +} diff --git a/utils/helper.go b/utils/helper.go index 7c5866d..89ae090 100644 --- a/utils/helper.go +++ b/utils/helper.go @@ -220,3 +220,288 @@ func GetScoreRank(score float64, difficultyMaster map[string]any) string { return "c" } } + +func BuildDecoEquipment(userid string, user map[string]any, m map[string]any) map[string]any { + decos, _ := user["decos"].(map[string]any) + if decos == nil { + decos = map[string]any{} + } + wc, _ := user["wearingCostume"].(map[string]any) + + decks := user["decks"].([]any) + mainDeckIdx := 1 + if md, ok := user["mainDeck"].(float64); ok { + mainDeckIdx = int(md) + } + mainDeck := decks[mainDeckIdx-1].(map[string]any) + + charSituationMap := m["masterCharacterSituationMap"].(map[string]any)["entries"].(map[string]any) + leaderSitId := fmt.Sprintf("%v", mainDeck["leader"]) + leaderEntry, _ := charSituationMap[leaderSitId].(map[string]any) + leaderCharId := any(nil) + leaderCharIdStr := "" + if leaderEntry != nil { + leaderCharId = leaderEntry["characterId"] + leaderCharIdStr = fmt.Sprintf("%v", leaderCharId) + } + + decoSit, _ := decos["situation"].(map[string]any) + decoSitId := any(1) + decoSitStatus := any("normal") + if decoSit != nil { + decoSitId = decoSit["situationId"] + decoSitStatus = decoSit["situationStatus"] + } + + decoL2d, _ := decos["live2d"].(map[string]any) + l2dCharId := leaderCharId + l2dCostumeId := any(nil) + if wc != nil && wc[leaderCharIdStr] != nil { + l2dCostumeId = wc[leaderCharIdStr].(map[string]any)["costumeId"] + } + l2dMotionId := any(nil) + if decoL2dMap, ok := m["masterDecoCharacterLive2dMotionMap"].(map[string]any); ok { + var firstMotion map[string]any + for _, v := range decoL2dMap["entries"].(map[string]any) { + mot := v.(map[string]any) + if fmt.Sprintf("%v", mot["characterId"]) == leaderCharIdStr { + if firstMotion == nil || mot["seq"].(float64) < firstMotion["seq"].(float64) { + firstMotion = mot + } + } + } + if firstMotion != nil { + l2dMotionId = firstMotion["motionId"] + } + } + l2dBackgroundId := any(1) + if decoL2d != nil { + if v, ok := decoL2d["characterId"]; ok { + l2dCharId = v + } + if v, ok := decoL2d["costumeId"]; ok { + l2dCostumeId = v + } + if v, ok := decoL2d["motionId"]; ok { + l2dMotionId = v + } + if v, ok := decoL2d["backgroundId"]; ok { + l2dBackgroundId = v + } + } + + deco3d, _ := decos["3d"].(map[string]any) + d3dCharId := leaderCharId + d3dDressId := any(nil) + d3dHairstyleId := any(nil) + if wc != nil && wc[leaderCharIdStr] != nil { + d3dDressId = wc[leaderCharIdStr].(map[string]any)["dressId"] + d3dHairstyleId = wc[leaderCharIdStr].(map[string]any)["hairstyleId"] + } + d3dMotionId := any(nil) + if em3Map, ok := m["masterEnableCharacter3dMotionTypeMap"].(map[string]any); ok { + if charEntry, ok := em3Map["entries"].(map[string]any)[leaderCharIdStr].(map[string]any); ok { + if decoEntry, ok := charEntry["entries"].(map[string]any)["deco"].(map[string]any); ok { + if entries, ok := decoEntry["entries"].([]any); ok { + var first map[string]any + for _, e := range entries { + entry := e.(map[string]any) + if first == nil || entry["seq"].(float64) < first["seq"].(float64) { + first = entry + } + } + if first != nil { + d3dMotionId = first["motionId"] + } + } + } + } + } + d3dBackgroundId := any(11) + if deco3d != nil { + if v, ok := deco3d["characterId"]; ok { + d3dCharId = v + } + if v, ok := deco3d["dressId"]; ok { + d3dDressId = v + } + if v, ok := deco3d["hairstyleId"]; ok { + d3dHairstyleId = v + } + if v, ok := deco3d["motionId"]; ok { + d3dMotionId = v + } + if v, ok := deco3d["backgroundId"]; ok { + d3dBackgroundId = v + } + } + + frameId := any(1) + if v, ok := decos["frameId"]; ok { + frameId = v + } + framepins, _ := decos["framepins"].([]any) + getPin := func(i int) any { + if framepins != nil && i < len(framepins) { + return framepins[i] + } + return nil + } + + userProfileDegree := BuildUserProfileDegree(userid, user) + decoProfileDegree := map[string]any{} + for k, v := range userProfileDegree { + entry := v.(map[string]any) + decoProfileDegree[k] = map[string]any{ + "decoFrameId": entry["userId"], + "profileDegreeType": entry["profileDegreeType"], + "degreeId": entry["degreeId"], + } + } + + decoEffectId := any(1) + if v, ok := decos["effect"]; ok { + decoEffectId = v + } + + return map[string]any{ + "userDecoCharacterSituation": map[string]any{ + "userId": userid, + "situationId": decoSitId, + "situationStatus": decoSitStatus, + }, + "userDecoCharacterLive2d": map[string]any{ + "userId": userid, + "characterId": l2dCharId, + "costumeId": l2dCostumeId, + "motionId": l2dMotionId, + "backgroundId": l2dBackgroundId, + }, + "userDecoCharacter3d": map[string]any{ + "userId": userid, + "characterId": d3dCharId, + "dressId": d3dDressId, + "hairstyleId": d3dHairstyleId, + "motionId": d3dMotionId, + "backgroundId": d3dBackgroundId, + }, + "userDecoFramePins": map[string]any{ + "userId": userid, + "decoFrameId": frameId, + "decoPinsId1": getPin(0), + "decoPinsId2": getPin(1), + "decoPinsId3": getPin(2), + "decoPinsId4": getPin(3), + "decoPinsId5": getPin(4), + }, + "userDecoDegreeMap": map[string]any{"entries": decoProfileDegree}, + "userDecoAppealMap": map[string]any{}, + "userDecoSetting": map[string]any{ + "useProfileSettingDegree": user["useProfileSettingDegree"], + "useProfileSettingSituation": user["useProfileSettingSituation"], + "selectedCharacterType": user["selectedCharacterType"], + }, + "userDecoEffect": map[string]any{ + "userId": userid, + "decoEffectId": decoEffectId, + }, + } +} + +func BuildEventStoryMemorialMap(userid string, m map[string]any, past map[string]any) map[string]any { + entries := map[string]any{} + + pastStoryEntries := map[string]any{} + if pse, ok := past["pastEventStoryMap"].(map[string]any); ok { + if e, ok := pse["entries"].(map[string]any); ok { + pastStoryEntries = e + } + } + + if escMap, ok := m["masterEventStoryMemorialConfigMap"].(map[string]any); ok { + for eventId := range escMap["entries"].(map[string]any) { + length := 0 + if pe, ok := pastStoryEntries[eventId].(map[string]any); ok { + if en, ok := pe["entries"].([]any); ok { + length = len(en) + } + } + storyEntries := make([]any, length) + for i := range storyEntries { + storyEntries[i] = map[string]any{ + "userId": userid, + "eventId": eventId, + "seq": i, + "status": "already_read", + } + } + entries[eventId] = map[string]any{ + "eventId": eventId, + "userEventStoryList": map[string]any{ + "entries": storyEntries, + }, + "isExistUnReadStory": false, + "isLocked": false, + } + } + } + return entries +} + +func GetMusicInfo(master map[string]any, musicid string, difficulty string) map[string]any { + musicList, _ := master["masterMusicDifficultyList"].(map[string]any) + entries, _ := musicList["entries"].([]any) + + for _, raw := range entries { + entry, ok := raw.(map[string]any) + if !ok { + continue + } + + if fmt.Sprintf("%v", entry["musicId"]) == musicid && + fmt.Sprintf("%v", entry["difficulty"]) == difficulty { + return entry + } + } + + return nil +} + +func BuildMusicScoreMap(user map[string]any) map[string]any { + result := map[string]any{ + "entries": map[string]any{}, + } + + entries := result["entries"].(map[string]any) + + musicScore, _ := user["musicScore"].(map[string]any) + for musicid, raw := range musicScore { + scoreData, _ := raw.(map[string]any) + scoreEntries, _ := scoreData["entries"].([]any) + + normalizedEntries := make([]any, 0, len(scoreEntries)) + + for _, rawScore := range scoreEntries { + score, ok := rawScore.(map[string]any) + if !ok { + continue + } + + normalizedEntries = append(normalizedEntries, map[string]any{ + "userId": fmt.Sprintf("%v", user["userId"]), + "musicId": musicid, + "musicDifficulty": score["musicDifficulty"], + "soloHighScore": score["soloHighScore"], + "maxCombo": score["maxCombo"], + "soloScoreRank": score["soloScoreRank"], + "clearStatus": score["clearStatus"], + }) + } + + entries[musicid] = map[string]any{ + "entries": normalizedEntries, + } + } + + return result +} diff --git a/utils/profile.go b/utils/profile.go new file mode 100644 index 0000000..a2b1cd7 --- /dev/null +++ b/utils/profile.go @@ -0,0 +1,21 @@ +package utils + +import "fmt" + +var BandRankMap = func() map[string]any { + m := map[string]any{} + for _, id := range []int{1, 2, 3, 4, 5, 18, 21, 45} { + m[fmt.Sprintf("%d", id)] = 67 + } + return m +}() + +var DeckRatingMap = func() map[string]any { + m := map[string]any{} + for _, id := range []int{1, 2, 3, 4, 5, 18, 21, 45} { + m[fmt.Sprintf("%d", id)] = map[string]any{ + "rank": "c", "score": 0, "lowerRating": 1, "upperRating": 1600000, + } + } + return m +}()