1080 lines
37 KiB
Go
1080 lines
37 KiB
Go
package user
|
|
|
|
import (
|
|
"bdgrp_go/db"
|
|
"bdgrp_go/master"
|
|
"bdgrp_go/pbutil"
|
|
"bdgrp_go/routes"
|
|
"bdgrp_go/utils"
|
|
"encoding/json"
|
|
"fmt"
|
|
"math/rand"
|
|
"os"
|
|
"path/filepath"
|
|
"slices"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
var decoMotionMap = buildDecoMotionMap()
|
|
|
|
func buildDecoMotionMap() map[string][]int {
|
|
m := map[string][]int{}
|
|
for i := 1; i <= 35; i++ {
|
|
base := 217 + (i-1)*5
|
|
m[fmt.Sprintf("%d", i)] = []int{base, base + 1, base + 2}
|
|
}
|
|
m["601"] = []int{392, 393, 394}
|
|
for i := 36; i <= 40; i++ {
|
|
base := 462 + (i-36)*5
|
|
m[fmt.Sprintf("%d", i)] = []int{base, base + 1, base + 2}
|
|
}
|
|
return m
|
|
}
|
|
|
|
func init() {
|
|
path := routes.PathOf()
|
|
routes.Register(func(app *fiber.App) {
|
|
app.Get(path, get)
|
|
fmt.Println("Loaded:", path)
|
|
})
|
|
}
|
|
|
|
func storyList(userid string, storyMap map[string]any) 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"],
|
|
})
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}
|
|
|
|
func get(c *fiber.Ctx) error {
|
|
userid := c.Params("userid")
|
|
server := os.Getenv("SERVER")
|
|
user := db.FindUser(userid)
|
|
if user == nil {
|
|
return c.Status(404).SendStatus(404)
|
|
}
|
|
m := master.GetMaster()
|
|
|
|
// pastEvents
|
|
pastPath := filepath.Join("pastEvents", server+".json")
|
|
pastData, _ := os.ReadFile(pastPath)
|
|
var past map[string]any
|
|
json.Unmarshal(pastData, &past)
|
|
|
|
// mission.json
|
|
missionData, _ := os.ReadFile("mission.json")
|
|
var missionsBase map[string]any
|
|
json.Unmarshal(missionData, &missionsBase)
|
|
missions := deepCopy(missionsBase)
|
|
for _, v := range missions {
|
|
group := v.(map[string]any)
|
|
if entries, ok := group["entries"].([]any); ok {
|
|
for _, e := range entries {
|
|
entry := e.(map[string]any)
|
|
entry["userId"] = userid
|
|
}
|
|
}
|
|
}
|
|
|
|
deckName := map[string]string{
|
|
"TW": "樂團1", "JP": "バンド1", "GL": "Band 1", "CN": "乐队1",
|
|
}[server]
|
|
|
|
changed := false
|
|
if user["situationIllust"] == nil {
|
|
user["situationIllust"] = map[string]any{}
|
|
changed = true
|
|
}
|
|
if user["decks"] == nil {
|
|
user["decks"] = []any{map[string]any{
|
|
"deckId": 1, "deckName": deckName,
|
|
"leader": 947, "member1": 1765, "member2": 1730, "member3": 2193, "member4": 2018,
|
|
"deckType": "normal",
|
|
}}
|
|
changed = true
|
|
}
|
|
if user["musicScore"] == nil {
|
|
user["musicScore"] = map[string]any{}
|
|
changed = true
|
|
}
|
|
if user["wearingCostume"] == nil {
|
|
costumeDefaults := map[int]map[string]any{
|
|
36: {"dressId": 12854, "hairstyleId": 502, "costumeId": 1786},
|
|
37: {"dressId": 12855, "hairstyleId": 503, "costumeId": 1787},
|
|
38: {"dressId": 12856, "hairstyleId": 504, "costumeId": 1788},
|
|
39: {"dressId": 12857, "hairstyleId": 505, "costumeId": 1789},
|
|
40: {"dressId": 12858, "hairstyleId": 506, "costumeId": 1790},
|
|
601: {"dressId": 36, "hairstyleId": 36, "costumeId": 1643},
|
|
}
|
|
wc := map[string]any{}
|
|
charIds := append(rangeInts(1, 40), 601)
|
|
for _, charId := range charIds {
|
|
key := fmt.Sprintf("%d", charId)
|
|
if def, ok := costumeDefaults[charId]; ok {
|
|
wc[key] = def
|
|
} else {
|
|
wc[key] = map[string]any{
|
|
"dressId": charId, "hairstyleId": charId, "costumeId": 1332 + charId,
|
|
}
|
|
}
|
|
}
|
|
user["wearingCostume"] = wc
|
|
changed = true
|
|
}
|
|
if user["decos"] == nil {
|
|
user["decos"] = map[string]any{}
|
|
changed = true
|
|
}
|
|
if user["areaItems"] == nil {
|
|
user["areaItems"] = map[string]any{}
|
|
changed = true
|
|
}
|
|
if changed {
|
|
db.Save()
|
|
}
|
|
|
|
charIds := append(rangeInts(1, 40), 601)
|
|
userCharacterMap := map[string]any{}
|
|
wc := user["wearingCostume"].(map[string]any)
|
|
for _, id := range charIds {
|
|
key := fmt.Sprintf("%d", id)
|
|
costume := wc[key].(map[string]any)
|
|
userCharacterMap[key] = map[string]any{
|
|
"userId": userid, "characterId": id,
|
|
"costumeId": costume["costumeId"],
|
|
}
|
|
}
|
|
|
|
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"}
|
|
charSituationMap := m["masterCharacterSituationMap"].(map[string]any)["entries"].(map[string]any)
|
|
seen := map[int]bool{}
|
|
var deckMembers []int
|
|
for _, field := range situationIdFields {
|
|
if sid, ok := mainDeck[field]; ok && sid != nil {
|
|
sidStr := fmt.Sprintf("%v", sid)
|
|
if entry, ok := charSituationMap[sidStr].(map[string]any); ok {
|
|
if charId, ok := entry["characterId"].(float64); ok {
|
|
cid := int(charId)
|
|
if !seen[cid] {
|
|
seen[cid] = true
|
|
deckMembers = append(deckMembers, cid)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
commonsLive2d := map[string]map[int][]int{}
|
|
if cl2dMap, ok := m["masterCommonsLive2dMap"].(map[string]any); ok {
|
|
for _, v := range cl2dMap["entries"].(map[string]any) {
|
|
entry := v.(map[string]any)
|
|
cat := fmt.Sprintf("%v", entry["live2dCategory"])
|
|
cid := int(entry["characterId"].(float64))
|
|
lid := int(entry["live2dId"].(float64))
|
|
if commonsLive2d[cat] == nil {
|
|
commonsLive2d[cat] = map[int][]int{}
|
|
}
|
|
commonsLive2d[cat][cid] = append(commonsLive2d[cat][cid], lid)
|
|
}
|
|
}
|
|
aggregated := map[string][]int{}
|
|
for cat, charMap := range commonsLive2d {
|
|
for charId, ids := range charMap {
|
|
if slices.Contains(deckMembers, charId) {
|
|
aggregated[cat] = append(aggregated[cat], ids...)
|
|
}
|
|
}
|
|
}
|
|
userCommonsLive2dEntries := map[string]any{}
|
|
for cat, idArray := range aggregated {
|
|
entries := make([]any, len(idArray))
|
|
for i, lid := range idArray {
|
|
entries[i] = map[string]any{"live2dId": lid, "live2dCategory": cat}
|
|
}
|
|
userCommonsLive2dEntries[cat] = map[string]any{"entries": entries}
|
|
}
|
|
|
|
userProfileDegree := utils.BuildUserProfileDegree(userid, user)
|
|
|
|
charProfileL2d := map[string][]int{}
|
|
if cpMap, ok := m["masterCharacterProfileLive2dMap"].(map[string]any); ok {
|
|
for _, v := range cpMap["entries"].(map[string]any) {
|
|
entry := v.(map[string]any)
|
|
cid := fmt.Sprintf("%v", entry["characterId"])
|
|
lid := int(entry["characterProfileLive2dId"].(float64))
|
|
charProfileL2d[cid] = append(charProfileL2d[cid], lid)
|
|
}
|
|
}
|
|
charProfileL2dEntries := map[string]any{}
|
|
for cid, ids := range charProfileL2d {
|
|
entries := make([]any, len(ids))
|
|
for i, id := range ids {
|
|
entries[i] = map[string]any{"characterId": cid, "live2dId": id}
|
|
}
|
|
charProfileL2dEntries[cid] = map[string]any{"entries": entries}
|
|
}
|
|
|
|
purchaseIds := []string{}
|
|
if pm, ok := m["masterPurchaseMap"].(map[string]any); ok {
|
|
for id := range pm["entries"].(map[string]any) {
|
|
purchaseIds = append(purchaseIds, id)
|
|
}
|
|
}
|
|
|
|
userEpisodeMap := map[string]any{}
|
|
for _, v := range charSituationMap {
|
|
card := v.(map[string]any)
|
|
rel := fmt.Sprintf("%v", card["releasedAt"])
|
|
if rel == "4128645600000" || rel == "4131237600000" {
|
|
continue
|
|
}
|
|
eps, ok := card["episodes"].(map[string]any)
|
|
if !ok {
|
|
continue
|
|
}
|
|
entries, ok := eps["entries"].([]any)
|
|
if !ok {
|
|
continue
|
|
}
|
|
for _, e := range entries {
|
|
ep := e.(map[string]any)
|
|
epId := fmt.Sprintf("%v", ep["episodeId"])
|
|
userEpisodeMap[epId] = map[string]any{
|
|
"userId": userid, "episodeId": ep["episodeId"], "episodeStatus": "already_read",
|
|
}
|
|
}
|
|
}
|
|
|
|
validSpawnPoints := map[string]bool{}
|
|
if spMap, ok := m["masterAreaItemSpawnMap"].(map[string]any); ok {
|
|
for k := range spMap["entries"].(map[string]any) {
|
|
validSpawnPoints[k] = true
|
|
}
|
|
}
|
|
|
|
now := time.Now().UnixMilli()
|
|
var seasonId any
|
|
if sbMap, ok := m["masterSeasonBasicMap"].(map[string]any); ok {
|
|
for _, v := range sbMap["entries"].(map[string]any) {
|
|
s := v.(map[string]any)
|
|
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
|
|
}
|
|
}
|
|
}
|
|
|
|
eventStoryEntries := map[string]any{}
|
|
if escMap, ok := m["masterEventStoryMemorialConfigMap"].(map[string]any); ok {
|
|
pastStoryEntries := map[string]any{}
|
|
if pse, ok := past["pastEventStoryMap"].(map[string]any); ok {
|
|
if entries, ok := pse["entries"].(map[string]any); ok {
|
|
pastStoryEntries = entries
|
|
}
|
|
}
|
|
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",
|
|
}
|
|
}
|
|
eventStoryEntries[eventId] = map[string]any{
|
|
"eventId": eventId,
|
|
"userEventStoryList": map[string]any{"entries": storyEntries},
|
|
"isExistUnReadStory": false,
|
|
"isLocked": false,
|
|
}
|
|
}
|
|
}
|
|
|
|
areaStatusEntries := map[string]any{}
|
|
if areaMap, ok := m["masterAreaMap"].(map[string]any); ok {
|
|
for areaId, v := range areaMap["entries"].(map[string]any) {
|
|
area := v.(map[string]any)
|
|
if area["areaType"] == "common" {
|
|
areaStatusEntries[areaId] = map[string]any{"userId": userid, "areaId": areaId}
|
|
}
|
|
}
|
|
}
|
|
|
|
areaItemEntries := map[string]any{}
|
|
if aiMap, ok := m["masterAreaItemMap"].(map[string]any); ok {
|
|
for id, v := range aiMap["entries"].(map[string]any) {
|
|
areaItem := v.(map[string]any)
|
|
sp := fmt.Sprintf("%v", areaItem["spawnPoint"])
|
|
if validSpawnPoints[sp] {
|
|
areaItemEntries[id] = map[string]any{
|
|
"userId": userid, "areaItemId": areaItem["areaItemId"],
|
|
"areaItemCategory": areaItem["categoryId"], "level": 8,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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{}
|
|
}
|
|
musicScoreEntries := map[string]any{}
|
|
for musicId, v := range musicScore {
|
|
sd := v.(map[string]any)
|
|
entries, _ := sd["entries"].([]any)
|
|
mapped := make([]any, len(entries))
|
|
for i, e := range entries {
|
|
score := e.(map[string]any)
|
|
mapped[i] = 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"],
|
|
}
|
|
}
|
|
musicScoreEntries[musicId] = map[string]any{"entries": mapped}
|
|
}
|
|
|
|
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, _ := strconv.ParseInt(e["startAt"].(string), 10, 64)
|
|
endAt, _ := strconv.ParseInt(e["endAt"].(string), 10, 64)
|
|
if startAt <= now && now >= endAt {
|
|
id := fmt.Sprintf("%v", e["decoEffectId"])
|
|
decoEffectEntries[id] = map[string]any{"userId": userid, "decoEffectId": e["decoEffectId"]}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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 {
|
|
if entries, ok := dsList["entries"].([]any); ok {
|
|
for _, v := range entries {
|
|
story := v.(map[string]any)
|
|
id := story["digestStoryId"]
|
|
if !digestSeen[id] {
|
|
digestSeen[id] = true
|
|
digestEntries = append(digestEntries, map[string]any{
|
|
"userId": userid, "digestStoryId": id, "status": "already_read",
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
decoFrameEntries := map[string]any{}
|
|
if dfMap, ok := m["masterDecoFrameMap"].(map[string]any); ok {
|
|
for _, v := range dfMap["entries"].(map[string]any) {
|
|
f := v.(map[string]any)
|
|
id := fmt.Sprintf("%v", f["decoFrameId"])
|
|
decoFrameEntries[id] = map[string]any{"userId": userid, "decoFrameId": f["decoFrameId"], "level": 5}
|
|
}
|
|
}
|
|
|
|
decoPinsEntries := map[string]any{}
|
|
if dpMap, ok := m["masterDecoPinsMap"].(map[string]any); ok {
|
|
for _, v := range dpMap["entries"].(map[string]any) {
|
|
p := v.(map[string]any)
|
|
id := fmt.Sprintf("%v", p["decoPinsId"])
|
|
decoPinsEntries[id] = map[string]any{"userId": userid, "decoPinsId": p["decoPinsId"], "quantity": 5}
|
|
}
|
|
}
|
|
|
|
_ = rand.Intn
|
|
|
|
userId := fmt.Sprintf("%v", user["userId"])
|
|
|
|
data := map[string]any{
|
|
"user": 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"],
|
|
},
|
|
},
|
|
"userCharacterMap": map[string]any{"entries": userCharacterMap},
|
|
"userSituationMap": map[string]any{"entries": situationMap},
|
|
"userMainStoryList": func() map[string]any {
|
|
var entries []any
|
|
if msMap, ok := m["masterMainStoryMap"].(map[string]any); ok {
|
|
list := msMap["entries"].([]any)
|
|
for _, l := range slices.Backward(list) {
|
|
story := l.(map[string]any)
|
|
entries = append(entries, map[string]any{
|
|
"userId": userid, "storyId": story["mainStoryId"], "status": "already_read",
|
|
})
|
|
}
|
|
}
|
|
return map[string]any{"entries": entries}
|
|
}(),
|
|
"userPracticeTicketList": nil,
|
|
"userBondsList": map[string]any{
|
|
"entries": func() []any {
|
|
result := make([]any, 9)
|
|
for i := range result {
|
|
result[i] = map[string]any{
|
|
"userId": userid, "bondsId": i + 1, "level": 1, "bonds": 5 * (i + 2),
|
|
}
|
|
}
|
|
return result
|
|
}(),
|
|
},
|
|
"userBandRankMap": map[string]any{
|
|
"entries": func() map[string]any {
|
|
result := map[string]any{}
|
|
for _, bandId := range []int{1, 2, 3, 4, 5, 18, 21, 45} {
|
|
result[fmt.Sprintf("%d", bandId)] = map[string]any{
|
|
"userId": userid, "bandId": bandId, "bandRank": 50,
|
|
"exp": 0, "totalExp": 0, "nextExp": 0,
|
|
}
|
|
}
|
|
return result
|
|
}(),
|
|
},
|
|
"userPoppinPartyStoryList": storyList(userid, m["masterPoppinPartyStoryMap"].(map[string]any)),
|
|
"userAfterglowStoryList": storyList(userid, m["masterAfterglowStoryMap"].(map[string]any)),
|
|
"userPastelPalettesStoryList": storyList(userid, m["masterPastelPalettesStoryMap"].(map[string]any)),
|
|
"userHelloHappyWorldStoryList": storyList(userid, m["masterHelloHappyWorldStoryMap"].(map[string]any)),
|
|
"userRoseliaStoryList": storyList(userid, m["masterRoseliaStoryMap"].(map[string]any)),
|
|
"userItemList": func() map[string]any {
|
|
var entries []any
|
|
if itemMap, ok := m["masterItemMap"].(map[string]any); ok {
|
|
for _, v := range itemMap["entries"].(map[string]any) {
|
|
item := v.(map[string]any)
|
|
entries = append(entries, map[string]any{
|
|
"userId": userid, "itemId": item["itemId"], "quantity": 6767,
|
|
})
|
|
}
|
|
}
|
|
return map[string]any{"entries": entries}
|
|
}(),
|
|
"userCommonsLive2dMap": map[string]any{"entries": userCommonsLive2dEntries},
|
|
"userEpisodeMap": map[string]any{"entries": userEpisodeMap},
|
|
"userAppendParameterMap": nil,
|
|
"userMusicInventoryList": func() map[string]any {
|
|
var entries []any
|
|
if ml, ok := m["masterMusicList"].(map[string]any); ok {
|
|
if songs, ok := ml["entries"].([]any); ok {
|
|
mvMap := map[string]any{}
|
|
if mvl, ok := m["masterMusicVideoListMap"].(map[string]any); ok {
|
|
mvMap = mvl["entries"].(map[string]any)
|
|
}
|
|
for _, v := range songs {
|
|
song := v.(map[string]any)
|
|
musicId := song["musicId"]
|
|
_, hasMv := mvMap[fmt.Sprintf("%v", musicId)]
|
|
entries = append(entries, map[string]any{
|
|
"userId": userid, "musicId": musicId, "seq": 1,
|
|
"hasMv": hasMv, "createdAt": fmt.Sprintf("%d", now),
|
|
})
|
|
}
|
|
}
|
|
}
|
|
return map[string]any{"entries": entries}
|
|
}(),
|
|
"userCostumeMap": func() map[string]any {
|
|
result := map[string]any{}
|
|
if cm, ok := m["masterCostumeMap"].(map[string]any); ok {
|
|
for _, v := range cm["entries"].(map[string]any) {
|
|
costume := v.(map[string]any)
|
|
id := fmt.Sprintf("%v", costume["costumeId"])
|
|
result[id] = map[string]any{
|
|
"userId": userid, "costumeId": costume["costumeId"], "characterId": costume["characterId"],
|
|
}
|
|
}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userAfterLiveTalkListMap": nil,
|
|
"userAreaItemMap": map[string]any{
|
|
"entries": areaItemEntries,
|
|
"newlyOpenedContents": map[string]any{"entries": []any{}},
|
|
},
|
|
"userResourceCount": nil,
|
|
"userLiveBoost": map[string]any{
|
|
"userId": userid, "liveBoost": 67,
|
|
"serverDate": fmt.Sprintf("%d", now), "liveBoostBonusType": "default",
|
|
},
|
|
"userExchangesList": map[string]any{
|
|
"entries": []any{map[string]any{"userId": userid, "exchangesId": 1563, "resetAt": "1779155725000"}},
|
|
},
|
|
"userGachaTicketList": nil,
|
|
"userGachaStatusMap": nil,
|
|
"userAreaStatusMap": map[string]any{"entries": areaStatusEntries},
|
|
"userLoginBonusMap": map[string]any{"entries": map[string]any{}},
|
|
"userHomeBannerList": nil,
|
|
"userStampMap": func() map[string]any {
|
|
result := map[string]any{}
|
|
if sm, ok := m["masterStampMap"].(map[string]any); ok {
|
|
for stampId, v := range sm["entries"].(map[string]any) {
|
|
stamp := v.(map[string]any)
|
|
_, withVoice := stamp["withVoice"]
|
|
result[stampId] = map[string]any{
|
|
"userId": userid, "stampId": stamp["stampId"],
|
|
"seq": 1, "isUnlockVoice": withVoice,
|
|
}
|
|
}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userDegreeMap": func() map[string]any {
|
|
result := map[string]any{}
|
|
if dm, ok := m["masterDegreeMap"].(map[string]any); ok {
|
|
for degreeId := range dm["entries"].(map[string]any) {
|
|
result[degreeId] = map[string]any{"userId": userid, "degreeId": degreeId}
|
|
}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userBadPenalty": nil,
|
|
"userCharacterProfileLive2dMap": map[string]any{"entries": charProfileL2dEntries},
|
|
"userEventExchangesList": map[string]any{"entries": []any{}},
|
|
"userEventItemList": func() map[string]any {
|
|
var entries []any
|
|
if eim, ok := m["masterEventItemMap"].(map[string]any); ok {
|
|
for _, v := range eim["entries"].(map[string]any) {
|
|
item := v.(map[string]any)
|
|
entries = append(entries, map[string]any{
|
|
"userId": userid, "eventItemId": item["eventItemId"], "quantity": 1,
|
|
})
|
|
}
|
|
}
|
|
return map[string]any{"entries": entries}
|
|
}(),
|
|
"userPurchaseMap": func() map[string]any {
|
|
result := map[string]any{}
|
|
for _, id := range purchaseIds {
|
|
result[id] = map[string]any{"userId": userid, "purchaseId": id, "count": 0}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userMissionMap": map[string]any{"entries": missions},
|
|
"userGenericStoryMap": func() map[string]any {
|
|
result := map[string]any{}
|
|
if gsm, ok := m["masterGenericStoryMap"].(map[string]any); ok {
|
|
for id, v := range gsm["entries"].(map[string]any) {
|
|
story := v.(map[string]any)
|
|
result[id] = map[string]any{
|
|
"userId": userid, "genericStoryId": story["genericStoryId"], "status": "already_read",
|
|
}
|
|
}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userLiveBoostRecoveryItemList": nil,
|
|
"userHighScoreMusicRating": nil,
|
|
"userHighScoreMusicRatingMap": nil,
|
|
"userSeason": map[string]any{"seasonId": seasonId},
|
|
"userQualifyTournamentMusicScoreMap": nil,
|
|
"userEventStoryMemorialMap": map[string]any{"entries": eventStoryEntries},
|
|
"userReleasedBondsIdList": func() map[string]any {
|
|
var entries []any
|
|
if bm, ok := m["masterBondsMap"].(map[string]any); ok {
|
|
for k := range bm["entries"].(map[string]any) {
|
|
entries = append(entries, k)
|
|
}
|
|
}
|
|
return map[string]any{"entries": entries}
|
|
}(),
|
|
"userMiracleTicketMap": map[string]any{"entries": []any{}},
|
|
"userMiracleTicketExchangesMap": map[string]any{"entries": []any{}},
|
|
"userMultiDisconnectionBadPenalty": nil,
|
|
"userSpecialLotteryDrawResultMap": nil,
|
|
"userMusicScoreMap": map[string]any{"entries": musicScoreEntries},
|
|
"userMusicAchievementMap": nil,
|
|
"userBirthdayStoryMap": func() map[string]any {
|
|
result := map[string]any{}
|
|
if bpm, ok := m["masterBirthdayPageMap"].(map[string]any); ok {
|
|
for _, v := range bpm["entries"].(map[string]any) {
|
|
item := v.(map[string]any)
|
|
if item["birthdayStoryId"] == nil {
|
|
continue
|
|
}
|
|
id := fmt.Sprintf("%v", item["birthdayStoryId"])
|
|
result[id] = map[string]any{
|
|
"userId": userid, "birthdayStoryId": item["birthdayStoryId"], "status": "already_read",
|
|
}
|
|
}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userGenericAnimationMap": func() map[string]any {
|
|
result := map[string]any{}
|
|
if gam, ok := m["masterGenericAnimationMap"].(map[string]any); ok {
|
|
for id := range gam["entries"].(map[string]any) {
|
|
result[id] = map[string]any{"userId": userid, "genericAnimationId": id, "status": "already_read"}
|
|
}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userMusicShopMap": func() map[string]any {
|
|
var entries []any
|
|
if ml, ok := m["masterMusicList"].(map[string]any); ok {
|
|
if songs, ok := ml["entries"].([]any); ok {
|
|
for i, v := range songs {
|
|
song := v.(map[string]any)
|
|
entries = append(entries, map[string]any{
|
|
"userId": userid, "musicShopId": i + 1, "shopId": 7,
|
|
"shopCategory": "common", "musicId": song["musicId"],
|
|
"status": "sold_out", "seq": i + 1, "isInitialDistribution": false,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
return map[string]any{"entries": map[string]any{"7": map[string]any{"entries": entries}}}
|
|
}(),
|
|
"userTitleList": nil,
|
|
"userPurchaseVoidBadPenaltyStandard": nil,
|
|
"userSelectNewYearCardMap": nil,
|
|
"userGachaCountCeilingMap": nil,
|
|
"userBackstageTalkSetReadHistoryMap": nil,
|
|
"userNewMusicIntroductionMap": func() map[string]any {
|
|
result := 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"])
|
|
result[id] = map[string]any{
|
|
"userId": userid, "newMusicIntroductionId": item["newMusicIntroductionId"], "status": "already_read",
|
|
}
|
|
}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userNewSituationIntroductionMap": func() map[string]any {
|
|
result := map[string]any{}
|
|
if nsi, ok := m["masterNewSituationIntroductionList"].(map[string]any); ok {
|
|
if entries, ok := nsi["entries"].([]any); ok {
|
|
for _, v := range entries {
|
|
item := v.(map[string]any)
|
|
id := fmt.Sprintf("%v", item["newSituationIntroductionId"])
|
|
result[id] = map[string]any{
|
|
"userId": userid, "newSituationIntroductionId": item["newSituationIntroductionId"], "status": "already_read",
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userFriendRelationDetail": map[string]any{
|
|
"applicationMap": nil, "approvalMap": nil, "friendMap": nil,
|
|
"friendLimit": 50, "approvalLimit": 50, "applicationLimit": 50,
|
|
},
|
|
"userNotHaveViewExchangesMiracleTicketIdList": map[string]any{"entries": []any{}},
|
|
"userProfileSituation": nil,
|
|
"userProfileDegreeMap": map[string]any{"entries": userProfileDegree},
|
|
"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},
|
|
},
|
|
"userMusicVideoListMap": func() map[string]any {
|
|
result := map[string]any{}
|
|
if mvlm, ok := m["masterMusicVideoListMap"].(map[string]any); ok {
|
|
for musicId := range mvlm["entries"].(map[string]any) {
|
|
result[musicId] = map[string]any{
|
|
"entries": []any{map[string]any{"userId": userid, "musicId": musicId, "seq": 1}},
|
|
}
|
|
}
|
|
}
|
|
return map[string]any{"userMusicVideoInventoryListMap": map[string]any{"entries": result}}
|
|
}(),
|
|
"userPurchaseMenuLastVisitMap": map[string]any{"entries": map[string]any{}},
|
|
"userSkinLaneMap": nil,
|
|
"currentUserEventMusicScoresMap": nil,
|
|
"currentUserEventMusicAchievementsMap": nil,
|
|
"currentUserEventBoxGachaMap": nil,
|
|
"userMonthlyPurchaseMap": nil,
|
|
"userSubscriptionList": nil,
|
|
"userCommentBannerList": nil,
|
|
"userEventBoxGachaSpinSettings": nil,
|
|
"userMorfonicaStoryList": storyList(userid, m["masterMorfonicaStoryMap"].(map[string]any)),
|
|
"userMatchingBonusList": nil,
|
|
"userRaiseASuilenStoryList": storyList(userid, m["masterRaiseASuilenStoryMap"].(map[string]any)),
|
|
"userCollaboOriginalMusicScoreMap": nil,
|
|
"userDailyLive": map[string]any{
|
|
"lastClearedAt": 0, "liveStartedAt": 0, "getDailyLiveRewardId": 6,
|
|
},
|
|
"userDailyLiveTotalRewardHistory": nil,
|
|
"userComebackStatus": nil,
|
|
"userGraphicalInformationList": nil,
|
|
"userMultiLiveCountRewardList": nil,
|
|
"userDigestStoryList": map[string]any{"entries": digestEntries},
|
|
"userLiveBoostUseBonusLimitList": nil,
|
|
"userReceivablePresentLocationList": nil,
|
|
"userPanelMissionList": nil,
|
|
"userBirthdayIntroductionMap": nil,
|
|
"userFestivalTeamMap": nil,
|
|
"userLimitedItemList": nil,
|
|
"userLimitedExchangesList": map[string]any{"entries": []any{}},
|
|
"userDeckList": map[string]any{"entries": decks},
|
|
"userAddMusicDifficultyIntroductionList": nil,
|
|
"userGalleryList": nil,
|
|
"userBandDeckRatingMap": nil,
|
|
"updatedBandDeckRankList": nil,
|
|
"userStageChallengeStageNoMap": nil,
|
|
"userStageChallengeMap": nil,
|
|
"userStageChallengeScoreMap": nil,
|
|
"userStarSeal": map[string]any{"amount": user["seal"]},
|
|
"userLiveBoostUseFull": map[string]any{"dailyUseFullCount": 67, "resetTime": 0},
|
|
"userAutoLive": map[string]any{"resetTime": 0},
|
|
"userMonthlyMission": nil,
|
|
"userMonthlyMissionRewardList": nil,
|
|
"userCharacterRankMap": utils.BuildCharacterRankMap(),
|
|
"userCharacterPotentialLevelMap": func() map[string]any {
|
|
result := map[string]any{}
|
|
for i := 1; i <= 40; i++ {
|
|
result[fmt.Sprintf("%d", i)] = map[string]any{
|
|
"performanceLevel": 1, "techniqueLevel": 1, "visualLevel": 1,
|
|
}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userMusicVideo3dListMap": func() map[string]any {
|
|
result := map[string]any{}
|
|
if mv3m, ok := m["masterMusicVideo3dMap"].(map[string]any); ok {
|
|
for _, v := range mv3m["entries"].(map[string]any) {
|
|
mv := v.(map[string]any)
|
|
musicId := fmt.Sprintf("%v", mv["musicId"])
|
|
result[musicId] = map[string]any{
|
|
"entries": []any{map[string]any{
|
|
"musicVideo3dId": mv["musicVideo3dId"], "musicId": mv["musicId"], "seq": mv["seq"],
|
|
}},
|
|
}
|
|
}
|
|
}
|
|
return map[string]any{"userMusicVideo3dInventoryListMap": map[string]any{"entries": result}}
|
|
}(),
|
|
"userCostume3dDressInventoryMap": func() map[string]any {
|
|
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"}
|
|
}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userCostume3dHairstyleInventoryMap": func() map[string]any {
|
|
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"}
|
|
}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userWearingCostume3dMap": func() map[string]any {
|
|
result := map[string]any{}
|
|
for charId, v := range wc {
|
|
costume := v.(map[string]any)
|
|
result[charId] = map[string]any{
|
|
"characterId": charId,
|
|
"costume3dDressId": costume["dressId"],
|
|
"costume3dHairstyleId": costume["hairstyleId"],
|
|
}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userMusicClearInfoMap": utils.ComputeMusicClearInfo(musicScore),
|
|
"userMusicClearCountInfoMap": utils.ComputeMusicClearCountInfo(musicScore),
|
|
"userCharacterSituationCountMap": nil,
|
|
"userDecoCharacterBackgroundInventoryMap": func() map[string]any {
|
|
result := map[string]any{}
|
|
if dcbm, ok := m["masterDecoCharacterBackgroundMap"].(map[string]any); ok {
|
|
for backgroundId := range dcbm["entries"].(map[string]any) {
|
|
result[backgroundId] = map[string]any{"userId": userid, "backgroundId": backgroundId}
|
|
}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userDecoCharacter3dMotionInventoryListMap": func() map[string]any {
|
|
result := map[string]any{}
|
|
for charId, motionIds := range decoMotionMap {
|
|
entries := make([]any, len(motionIds))
|
|
for i, motionId := range motionIds {
|
|
entries[i] = map[string]any{"userId": userid, "motionId": motionId}
|
|
}
|
|
result[charId] = map[string]any{"entries": entries}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userMusicVideo3dCustomDeckMap": nil,
|
|
"userCostume3dMakingItemInventoryMap": nil,
|
|
"userMusicVideo3dOriginalDeckCostumeMap": nil,
|
|
"userLimitBreakItemList": nil,
|
|
"userDecoAppealInventoryMap": nil,
|
|
"userInvitationInfo": nil,
|
|
"userCharacterUseStyleMap": nil,
|
|
"userPurchaseStarList": nil,
|
|
"userInviteMissionListMap": nil,
|
|
"userGachaBonusMap": nil,
|
|
"userStampVoiceMap": func() map[string]any {
|
|
result := map[string]any{}
|
|
if sm, ok := m["masterStampMap"].(map[string]any); ok {
|
|
for stampId, v := range sm["entries"].(map[string]any) {
|
|
stamp := v.(map[string]any)
|
|
if _, ok := stamp["withVoice"]; ok {
|
|
result[stampId] = map[string]any{"userId": userid, "stampId": stampId}
|
|
}
|
|
}
|
|
}
|
|
return map[string]any{"entries": result}
|
|
}(),
|
|
"userEventRankedCountAppeal": nil,
|
|
"userEventMusicRankedCountAppeal": nil,
|
|
"userMyGoStoryList": storyList(userid, m["masterMyGoStoryMap"].(map[string]any)),
|
|
"userTerms": map[string]any{"userId": userid},
|
|
"userCharacterMissionBonusMap": nil,
|
|
"userPhotoStudioMap": nil,
|
|
"userGachaSelfPickupSituationList": nil,
|
|
"userPhotoBackInventoryMap": nil,
|
|
"userLimitedSkinInventoryMap": nil,
|
|
"userMusicClearCountDetailMap": nil,
|
|
}
|
|
|
|
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())
|
|
}
|
|
|
|
c.Set("Content-Type", "application/octet-stream")
|
|
return c.Send(encrypted)
|
|
}
|
|
|
|
// helpers
|
|
func rangeInts(from, to int) []int {
|
|
result := make([]int, to-from+1)
|
|
for i := range result {
|
|
result[i] = from + i
|
|
}
|
|
return result
|
|
}
|
|
|
|
func deepCopy(src map[string]any) map[string]any {
|
|
b, _ := json.Marshal(src)
|
|
var dst map[string]any
|
|
json.Unmarshal(b, &dst)
|
|
return dst
|
|
}
|