508 lines
13 KiB
Go
508 lines
13 KiB
Go
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
|
|
}
|