package utils import "fmt" func ComputeMusicClearInfo(musicScore map[string]any) map[string]any { difficulties := []string{"easy", "normal", "hard", "expert", "special"} type stat struct{ cleared, fullCombo, allPerfect int } stats := map[string]*stat{} for _, d := range difficulties { stats[d] = &stat{} } for _, v := range musicScore { data := v.(map[string]any) entries, ok := data["entries"].([]any) if !ok { continue } for _, e := range entries { entry := e.(map[string]any) diff, _ := entry["musicDifficulty"].(string) clearStatus, _ := entry["clearStatus"].(string) if s, ok := stats[diff]; ok { s.cleared++ if clearStatus == "full_combo" { s.fullCombo++ } if clearStatus == "all_perfect" { s.allPerfect++ } } } } result := map[string]any{} for _, d := range difficulties { result[d] = map[string]any{ "clearedMusicCount": stats[d].cleared, "fullComboMusicCount": stats[d].fullCombo, "allPerfectMusicCount": stats[d].allPerfect, } } return map[string]any{"entries": result} } func ComputeMusicClearCountInfo(musicScore map[string]any) map[string]any { result := map[string]any{} for id, v := range musicScore { data := v.(map[string]any) entries, ok := data["entries"].([]any) if ok && len(entries) > 0 { result[id] = len(entries) } } return map[string]any{"entries": result} } func BuildUserSituations(userid string, master map[string]any, user map[string]any) []any { situationMap := master["masterCharacterSituationMap"].(map[string]any)["entries"].(map[string]any) var result []any for _, v := range situationMap { card := v.(map[string]any) releasedAt := fmt.Sprintf("%v", card["releasedAt"]) if releasedAt == "4128645600000" || releasedAt == "4131237600000" { continue } // maxLevel maxLevel := 0 if paramMap, ok := card["parameterMap"].(map[string]any); ok { for k := range paramMap { var level int fmt.Sscanf(k, "%d", &level) if level > maxLevel { maxLevel = level } } } rarity := 0 if r, ok := card["rarity"].(float64); ok { rarity = int(r) } hasTraining := rarity >= 3 var ep0, ep1 map[string]any if eps, ok := card["episodes"].(map[string]any); ok { if entries, ok := eps["entries"].([]any); ok { if len(entries) > 0 { ep0, _ = entries[0].(map[string]any) } if len(entries) > 1 { ep1, _ = entries[1].(map[string]any) } } } illust := "normal" if hasTraining { illust = "after_training" } if user != nil { if si, ok := user["situationIllust"].(map[string]any); ok { if v, ok := si[fmt.Sprintf("%v", card["situationId"])]; ok { illust = fmt.Sprintf("%v", v) } } } trainingStatus := "not_doing" if hasTraining { trainingStatus = "done" } sit := map[string]any{ "userId": userid, "situationId": card["situationId"], "level": maxLevel, "exp": 0, "createdAt": card["releasedAt"], "addExp": 0, "trainingStatus": trainingStatus, "duplicateCount": 0, "illust": illust, "skillExp": 0, "skillLevel": 5, "limitBreakRank": 4, } if hasTraining { t, _ := card["training"].(map[string]any) perf, tech, vis := 0.0, 0.0, 0.0 if t != nil { perf, _ = t["trainingPerformance"].(float64) tech, _ = t["trainingTechnique"].(float64) vis, _ = t["trainingVisual"].(float64) } ep0Perf, ep0Tech, ep0Vis := 0.0, 0.0, 0.0 ep1Perf, ep1Tech, ep1Vis := 0.0, 0.0, 0.0 if ep0 != nil { ep0Perf, _ = ep0["appendPerformance"].(float64) ep0Tech, _ = ep0["appendTechnique"].(float64) ep0Vis, _ = ep0["appendVisual"].(float64) } if ep1 != nil { ep1Perf, _ = ep1["appendPerformance"].(float64) ep1Tech, _ = ep1["appendTechnique"].(float64) ep1Vis, _ = ep1["appendVisual"].(float64) } sit["userAppendParameter"] = map[string]any{ "userId": userid, "situationId": card["situationId"], "performance": perf, "technique": tech, "visual": vis, "characterPotentialPerformance": 30, "characterPotentialTechnique": 30, "characterPotentialVisual": 30, "characterBonusPerformance": 30 + ep0Perf + ep1Perf, "characterBonusTechnique": 30 + ep0Tech + ep1Tech, "characterBonusVisual": 30 + ep0Vis + ep1Vis, } } result = append(result, sit) } return result } func BuildUserProfileDegree(userid string, user map[string]any) map[string]any { degree := user["degree"].([]any) result := map[string]any{ "first": map[string]any{ "userId": userid, "profileDegreeType": "first", "degreeId": degree[0], }, } if len(degree) > 1 && degree[1] != nil { result["second"] = map[string]any{ "userId": userid, "profileDegreeType": "second", "degreeId": degree[1], } } return result } func BuildCharacterRankMap() map[string]any { entries := map[string]any{} for i := 1; i <= 40; i++ { entries[fmt.Sprintf("%d", i)] = map[string]any{ "rank": 100, "exp": 0, "addExp": 0, "nextExp": 0, "totalExp": 0, "releasedPotentialLevel": 50, } } return map[string]any{"entries": entries} } func GetScoreRank(score float64, difficultyMaster map[string]any) string { if difficultyMaster == nil { return "c" } get := func(key string) float64 { v, _ := difficultyMaster[key].(float64) return v } switch { case score >= get("scoreSS"): return "ss" case score >= get("scoreS"): return "s" case score >= get("scoreA"): return "a" case score >= get("scoreB"): return "b" default: return "c" } } 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 }