Persist live status and migrate legacy live data
- Add user_live_status to store hi score, hi combo count, and clear count per chart - Expand user_live_goal to persist achieved live_goal_reward_id entries instead of only coarse goal types - Update live reward handling to refresh live status and sync newly achieved live goals on every clear - Return live status and achieved goal ids from stored user data in /api/live/status - Aggregate profile liveCnt from stored user_live_status instead of hardcoded values - Load complete-rank thresholds from live info for goal evaluation - Migrate legacy user_live_record data into user_live_status and backfill achievable live goals on startup Signed-off-by: Sean Du <do4suki@gmail.com>
This commit is contained in:
@@ -1,34 +1,87 @@
|
||||
package profile
|
||||
|
||||
import (
|
||||
usermodel "honoka-chan/internal/model/user"
|
||||
profileapischema "honoka-chan/internal/schema/api/profile"
|
||||
"honoka-chan/internal/session"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func liveCnt() (res any, err error) {
|
||||
type profileLiveDifficultyRow struct {
|
||||
LiveDifficultyID int `xorm:"live_difficulty_id"`
|
||||
Difficulty int `xorm:"difficulty"`
|
||||
}
|
||||
|
||||
func liveCnt(ctx *gin.Context, targetUserID int) (res any, err error) {
|
||||
ss := session.Get(ctx)
|
||||
|
||||
targetPref, err := getTargetUserPref(ss, targetUserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
difficultyByLiveID := map[int]int{}
|
||||
loadDifficultyRows := func(table string) error {
|
||||
rows := []profileLiveDifficultyRow{}
|
||||
err := ss.MainEng.Table(table).Alias("live").
|
||||
Join("LEFT", "live_setting_m setting", "live.live_setting_id = setting.live_setting_id").
|
||||
Select("live.live_difficulty_id, setting.difficulty").
|
||||
Find(&rows)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, row := range rows {
|
||||
difficultyByLiveID[row.LiveDifficultyID] = row.Difficulty
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if err := loadDifficultyRows("normal_live_m"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := loadDifficultyRows("special_live_m"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
statusRows := []usermodel.UserLiveStatus{}
|
||||
err = ss.UserEng.Table(new(usermodel.UserLiveStatus)).
|
||||
Where("user_id = ?", targetPref.UserID).
|
||||
Where("clear_cnt > 0").
|
||||
Cols("live_difficulty_id", "clear_cnt").
|
||||
Find(&statusRows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
difficultyCounts := map[int]int{}
|
||||
for _, row := range statusRows {
|
||||
difficulty, ok := difficultyByLiveID[row.LiveDifficultyID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if difficulty == 5 {
|
||||
continue
|
||||
}
|
||||
difficultyCounts[difficulty]++
|
||||
}
|
||||
|
||||
orderedDifficulties := []int{1, 2, 3, 4, 6}
|
||||
result := make([]profileapischema.LiveCntData, 0, len(orderedDifficulties))
|
||||
for _, difficulty := range orderedDifficulties {
|
||||
result = append(result, profileapischema.LiveCntData{
|
||||
Difficulty: difficulty,
|
||||
ClearCnt: difficultyCounts[difficulty],
|
||||
})
|
||||
}
|
||||
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
return result[i].Difficulty < result[j].Difficulty
|
||||
})
|
||||
|
||||
res = profileapischema.LiveCntResp{
|
||||
Result: []profileapischema.LiveCntData{
|
||||
{
|
||||
Difficulty: 1,
|
||||
ClearCnt: 315,
|
||||
},
|
||||
{
|
||||
Difficulty: 2,
|
||||
ClearCnt: 310,
|
||||
},
|
||||
{
|
||||
Difficulty: 3,
|
||||
ClearCnt: 314,
|
||||
},
|
||||
{
|
||||
Difficulty: 4,
|
||||
ClearCnt: 455,
|
||||
},
|
||||
{
|
||||
Difficulty: 6,
|
||||
ClearCnt: 233,
|
||||
},
|
||||
},
|
||||
Result: result,
|
||||
Status: 200,
|
||||
CommandNum: false,
|
||||
TimeStamp: time.Now().Unix(),
|
||||
|
||||
@@ -11,7 +11,7 @@ func ProfileApi(ctx *gin.Context, action string, targetUserID int) (res any, err
|
||||
case "cardRanking":
|
||||
res, err = cardRanking()
|
||||
case "liveCnt":
|
||||
res, err = liveCnt()
|
||||
res, err = liveCnt(ctx, targetUserID)
|
||||
case "profileInfo":
|
||||
res, err = profileInfo(ctx, targetUserID)
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user