From f8a0f2db13fe0727c8cf3550474d7692e02eaedf Mon Sep 17 00:00:00 2001 From: Sean Du Date: Sat, 6 Jun 2026 15:56:44 +0800 Subject: [PATCH] Refine live schedule data - Add special_live_rotation_m data to main.db for rotated special live scheduling - Split normal and special live queries to avoid selecting special-only columns from normal_live_m - Build live schedule/status around rotated special lives and derived training lives - Reuse user training energy values in login top info and live party list responses - Set training energy and max training energy defaults to 999 Signed-off-by: Sean Du --- assets/main.db | Bin 5480448 -> 5505024 bytes internal/handler/api/live/common.go | 314 ++++++++++++++++++++++ internal/handler/api/live/schedule.go | 17 +- internal/handler/api/live/status.go | 39 +-- internal/handler/api/login/topinfoonce.go | 5 +- internal/handler/live/partylist.go | 7 +- internal/session/userdata.go | 6 +- 7 files changed, 343 insertions(+), 45 deletions(-) create mode 100644 internal/handler/api/live/common.go diff --git a/assets/main.db b/assets/main.db index 64752b3fa6d5ce8ae345f6130d5490005e120d87..7046a9a2d86256c86db0633a28462fdc70b6eeef 100644 GIT binary patch delta 11794 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 diff --git a/internal/handler/api/live/common.go b/internal/handler/api/live/common.go new file mode 100644 index 0000000..e2dfba1 --- /dev/null +++ b/internal/handler/api/live/common.go @@ -0,0 +1,314 @@ +package live + +import ( + "fmt" + liveapischema "honoka-chan/internal/schema/api/live" + "honoka-chan/internal/session" + "os" + "path/filepath" + "sort" + "time" +) + +const ( + randomLiveStartDate = "1970-01-01 00:00:00" + randomLiveEndDate = "2038-01-19 12:14:07" +) + +var jst = time.FixedZone("JST", 9*3600) + +type liveAvailabilityRow struct { + LiveDifficultyID int `xorm:"live_difficulty_id"` + LiveTrackID int `xorm:"live_track_id"` + LiveSettingID int `xorm:"live_setting_id"` + Difficulty int `xorm:"difficulty"` + AcFlag int `xorm:"ac_flag"` + NotesSettingAsset string `xorm:"notes_setting_asset"` + ExcludeClearCountFlag int `xorm:"exclude_clear_count_flag"` +} + +type specialLiveRotationRow struct { + RotationGroupID int `xorm:"rotation_group_id"` + LiveDifficultyID int `xorm:"live_difficulty_id"` + BaseDate string `xorm:"base_date"` +} + +func listAvailableNormalLiveDifficultyIDs(ss *session.Session) ([]int, error) { + rows, err := listAvailableNormalLiveRows(ss) + if err != nil { + return nil, err + } + + result := make([]int, 0, len(rows)) + for _, row := range rows { + result = append(result, row.LiveDifficultyID) + } + return result, nil +} + +func listAvailableNormalLiveTrackIDs(ss *session.Session) ([]int, error) { + rows, err := listAvailableNormalLiveRows(ss) + if err != nil { + return nil, err + } + + trackSet := map[int]struct{}{} + for _, row := range rows { + trackSet[row.LiveTrackID] = struct{}{} + } + + result := make([]int, 0, len(trackSet)) + for id := range trackSet { + result = append(result, id) + } + sort.Ints(result) + return result, nil +} + +func listAvailableNormalLiveRows(ss *session.Session) ([]liveAvailabilityRow, error) { + rows := []liveAvailabilityRow{} + err := ss.MainEng.Table("normal_live_m").Alias("live"). + Join("LEFT", "live_setting_m setting", "live.live_setting_id = setting.live_setting_id"). + Select(` + live.live_difficulty_id, + live.live_setting_id, + setting.live_track_id, + setting.difficulty, + setting.ac_flag, + setting.notes_setting_asset, + 0 AS exclude_clear_count_flag + `). + OrderBy("live.live_difficulty_id ASC"). + Find(&rows) + if err != nil { + return nil, err + } + + result := make([]liveAvailabilityRow, 0, len(rows)) + for _, row := range rows { + if !hasBeatmap(row.NotesSettingAsset) { + continue + } + result = append(result, row) + } + return result, nil +} + +func listAvailableSpecialLiveRows(ss *session.Session) ([]liveAvailabilityRow, error) { + rows := []liveAvailabilityRow{} + err := ss.MainEng.Table("special_live_m").Alias("live"). + Join("LEFT", "live_setting_m setting", "live.live_setting_id = setting.live_setting_id"). + Select(` + live.live_difficulty_id, + live.live_setting_id, + setting.live_track_id, + setting.difficulty, + setting.ac_flag, + setting.notes_setting_asset, + COALESCE(live.exclude_clear_count_flag, 0) AS exclude_clear_count_flag + `). + OrderBy("live.live_difficulty_id ASC"). + Find(&rows) + if err != nil { + return nil, err + } + + result := make([]liveAvailabilityRow, 0, len(rows)) + for _, row := range rows { + if !hasBeatmap(row.NotesSettingAsset) { + continue + } + result = append(result, row) + } + return result, nil +} + +func hasBeatmap(notesSettingAsset string) bool { + if notesSettingAsset == "" { + return false + } + path := filepath.Join("assets/serverdata/beatmaps", notesSettingAsset) + info, err := os.Stat(path) + return err == nil && !info.IsDir() +} + +func listTodaySpecialRotationDifficultyIDs(ss *session.Session, now time.Time) ([]int, error) { + rows := []specialLiveRotationRow{} + err := ss.MainEng.Table("special_live_rotation_m"). + OrderBy("rotation_group_id ASC, base_date ASC"). + Find(&rows) + if err != nil { + return nil, err + } + + grouped := map[int][]struct { + liveDifficultyID int + dayModulo int64 + }{} + for _, row := range rows { + baseDate, err := parseRotationBaseDate(row.BaseDate) + if err != nil { + return nil, err + } + grouped[row.RotationGroupID] = append(grouped[row.RotationGroupID], struct { + liveDifficultyID int + dayModulo int64 + }{ + liveDifficultyID: row.LiveDifficultyID, + dayModulo: baseDate.Unix() / 86400, + }) + } + + currentDay := now.In(jst).Unix() / 86400 + groupIDs := make([]int, 0, len(grouped)) + for groupID := range grouped { + groupIDs = append(groupIDs, groupID) + } + sort.Ints(groupIDs) + + result := make([]int, 0, len(groupIDs)) + for _, groupID := range groupIDs { + liveList := grouped[groupID] + if len(liveList) == 0 { + continue + } + currentDayModulo := currentDay % int64(len(liveList)) + for _, live := range liveList { + if live.dayModulo%int64(len(liveList)) == currentDayModulo { + result = append(result, live.liveDifficultyID) + break + } + } + } + return result, nil +} + +func listAllSpecialRotationDifficultyIDs(ss *session.Session) (map[int]struct{}, error) { + ids := []int{} + err := ss.MainEng.Table("special_live_rotation_m"). + Cols("live_difficulty_id"). + Find(&ids) + if err != nil { + return nil, err + } + + result := make(map[int]struct{}, len(ids)) + for _, id := range ids { + result[id] = struct{}{} + } + return result, nil +} + +func listAvailableTrainingLiveDifficultyIDs(ss *session.Session) ([]int, error) { + normalTrackIDs, err := listAvailableNormalLiveTrackIDs(ss) + if err != nil { + return nil, err + } + + specialRows, err := listAvailableSpecialLiveRows(ss) + if err != nil { + return nil, err + } + + rotationIDs, err := listAllSpecialRotationDifficultyIDs(ss) + if err != nil { + return nil, err + } + + normalTrackIDSet := make(map[int]struct{}, len(normalTrackIDs)) + for _, id := range normalTrackIDs { + normalTrackIDSet[id] = struct{}{} + } + + result := make([]int, 0) + for _, row := range specialRows { + if _, ok := normalTrackIDSet[row.LiveTrackID]; !ok { + continue + } + if row.Difficulty <= 5 || row.AcFlag != 0 || row.ExcludeClearCountFlag != 0 { + continue + } + if _, ok := rotationIDs[row.LiveDifficultyID]; ok { + continue + } + result = append(result, row.LiveDifficultyID) + } + + sort.Ints(result) + return result, nil +} + +func parseRotationBaseDate(value string) (time.Time, error) { + layouts := []string{ + "2006/01/02 15:04:05", + "2006/01/02 3:04:05", + } + for _, layout := range layouts { + t, err := time.ParseInLocation(layout, value, jst) + if err == nil { + return t, nil + } + } + return time.Time{}, fmt.Errorf("invalid special live rotation base_date: %s", value) +} + +func startOfDay(t time.Time) time.Time { + return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()) +} + +func nextDayStart(t time.Time) time.Time { + return startOfDay(t).Add(24 * time.Hour) +} + +func buildRandomLiveList() []liveapischema.RandomLiveList { + return []liveapischema.RandomLiveList{ + {AttributeID: 1, StartDate: randomLiveStartDate, EndDate: randomLiveEndDate}, + {AttributeID: 2, StartDate: randomLiveStartDate, EndDate: randomLiveEndDate}, + {AttributeID: 3, StartDate: randomLiveStartDate, EndDate: randomLiveEndDate}, + } +} + +func buildNormalLiveStatusList(ids []int) []liveapischema.NormalLiveStatusList { + result := make([]liveapischema.NormalLiveStatusList, 0, len(ids)) + for _, id := range ids { + result = append(result, liveapischema.NormalLiveStatusList{ + LiveDifficultyID: id, + Status: 1, + HiScore: 0, + HiComboCount: 0, + ClearCnt: 0, + AchievedGoalIDList: []int{}, + }) + } + return result +} + +func buildSpecialLiveStatusList(ids []int) []liveapischema.SpecialLiveStatusList { + result := make([]liveapischema.SpecialLiveStatusList, 0, len(ids)) + for _, id := range ids { + result = append(result, liveapischema.SpecialLiveStatusList{ + LiveDifficultyID: id, + Status: 1, + HiScore: 0, + HiComboCount: 0, + ClearCnt: 0, + AchievedGoalIDList: []int{}, + }) + } + return result +} + +func buildTrainingLiveStatusList(ids []int) []liveapischema.TrainingLiveStatusList { + result := make([]liveapischema.TrainingLiveStatusList, 0, len(ids)) + for _, id := range ids { + result = append(result, liveapischema.TrainingLiveStatusList{ + LiveDifficultyID: id, + Status: 1, + HiScore: 0, + HiComboCount: 0, + ClearCnt: 0, + AchievedGoalIDList: []int{}, + }) + } + return result +} diff --git a/internal/handler/api/live/schedule.go b/internal/handler/api/live/schedule.go index df5f293..b278431 100644 --- a/internal/handler/api/live/schedule.go +++ b/internal/handler/api/live/schedule.go @@ -11,19 +11,20 @@ import ( func liveSchedule(ctx *gin.Context) (res any, err error) { ss := session.Get(ctx) - var liveID []int - err = ss.MainEng.Table("special_live_m"). - Cols("live_difficulty_id").OrderBy("live_difficulty_id ASC").Find(&liveID) + now := time.Now() + liveIDs, err := listTodaySpecialRotationDifficultyIDs(ss, now) if err != nil { return nil, err } - liveList := []liveapischema.LiveList{} - for _, id := range liveID { + liveList := make([]liveapischema.LiveList, 0, len(liveIDs)) + startDate := startOfDay(now.In(jst)).Format("2006-01-02 15:04:05") + endDate := nextDayStart(now.In(jst)).Format("2006-01-02 15:04:05") + for _, id := range liveIDs { liveList = append(liveList, liveapischema.LiveList{ LiveDifficultyID: id, - StartDate: "2023-01-01 00:00:00", - EndDate: "2037-01-01 00:00:00", + StartDate: startDate, + EndDate: endDate, IsRandom: false, }) } @@ -34,7 +35,7 @@ func liveSchedule(ctx *gin.Context) (res any, err error) { LiveList: liveList, LimitedBonusList: []any{}, LimitedBonusCommonList: []liveapischema.LimitedBonusCommonList{}, - RandomLiveList: []liveapischema.RandomLiveList{}, + RandomLiveList: buildRandomLiveList(), FreeLiveList: []any{}, TrainingLiveList: []liveapischema.TrainingLiveList{}, }, diff --git a/internal/handler/api/live/status.go b/internal/handler/api/live/status.go index c176e83..a831837 100644 --- a/internal/handler/api/live/status.go +++ b/internal/handler/api/live/status.go @@ -11,49 +11,28 @@ import ( func liveStatus(ctx *gin.Context) (res any, err error) { ss := session.Get(ctx) - var liveDifficultyID []int - normalLives := []liveapischema.NormalLiveStatusList{} - err = ss.MainEng.Table("normal_live_m").Cols("live_difficulty_id").OrderBy("live_difficulty_id ASC").Find(&liveDifficultyID) + normalIDs, err := listAvailableNormalLiveDifficultyIDs(ss) if err != nil { return nil, err } - for _, id := range liveDifficultyID { - normalLive := liveapischema.NormalLiveStatusList{ - LiveDifficultyID: id, - Status: 1, - HiScore: 0, - HiComboCount: 0, - ClearCnt: 0, - AchievedGoalIDList: []int{}, - } - normalLives = append(normalLives, normalLive) - } - specialLives := []liveapischema.SpecialLiveStatusList{} - err = ss.MainEng.Table("special_live_m").Cols("live_difficulty_id").OrderBy("live_difficulty_id ASC").Find(&liveDifficultyID) + specialIDs, err := listTodaySpecialRotationDifficultyIDs(ss, time.Now()) if err != nil { return nil, err } - for _, id := range liveDifficultyID { - specialLive := liveapischema.SpecialLiveStatusList{ - LiveDifficultyID: id, - Status: 1, - HiScore: 0, - HiComboCount: 0, - ClearCnt: 0, - AchievedGoalIDList: []int{}, - } - specialLives = append(specialLives, specialLive) + trainingIDs, err := listAvailableTrainingLiveDifficultyIDs(ss) + if err != nil { + return nil, err } res = liveapischema.StatusResp{ Result: liveapischema.StatusData{ - NormalLiveStatusList: normalLives, - SpecialLiveStatusList: specialLives, - TrainingLiveStatusList: []liveapischema.TrainingLiveStatusList{}, + NormalLiveStatusList: buildNormalLiveStatusList(normalIDs), + SpecialLiveStatusList: buildSpecialLiveStatusList(specialIDs), + TrainingLiveStatusList: buildTrainingLiveStatusList(trainingIDs), MarathonLiveStatusList: []any{}, FreeLiveStatusList: []any{}, - CanResumeLive: false, + CanResumeLive: true, }, Status: 200, CommandNum: false, diff --git a/internal/handler/api/login/topinfoonce.go b/internal/handler/api/login/topinfoonce.go index d0af3ec..6c47d20 100644 --- a/internal/handler/api/login/topinfoonce.go +++ b/internal/handler/api/login/topinfoonce.go @@ -10,14 +10,15 @@ import ( func loginTopInfoOnce(ctx *gin.Context) (res any, err error) { ss := session.Get(ctx) + userInfo := ss.GetUserInfo() res = loginapischema.TopInfoOnceResp{ Result: loginapischema.TopInfoOnceData{ NewAchievementCnt: 0, UnaccomplishedAchievementCnt: 0, LiveDailyRewardExist: false, - TrainingEnergy: 10, - TrainingEnergyMax: 10, + TrainingEnergy: userInfo.TrainingEnergy, + TrainingEnergyMax: userInfo.TrainingEnergyMax, Notification: loginapischema.Notification{ Push: false, Lp: false, diff --git a/internal/handler/live/partylist.go b/internal/handler/live/partylist.go index f1f8ee4..08d48b1 100644 --- a/internal/handler/live/partylist.go +++ b/internal/handler/live/partylist.go @@ -14,6 +14,7 @@ import ( func partyList(ctx *gin.Context) { ss := session.Get(ctx) defer ss.Finalize() + userInfo := ss.GetUserInfo() pref := usermodel.UserPref{} _, err := ss.UserEng.Table("user_pref").Where("user_id = ?", ss.UserID).Get(&pref) @@ -37,7 +38,7 @@ func partyList(ctx *gin.Context) { if len(partyList) == 0 { selfParty := liveschema.PartyList{ - UserInfo: ss.GetUserInfo(), + UserInfo: userInfo, SettingAwardID: pref.AwardID, FriendStatus: usermodel.ClientFriendStatusNone, } @@ -52,8 +53,8 @@ func partyList(ctx *gin.Context) { ss.Respond(liveschema.PartyListResp{ ResponseData: liveschema.PartyListData{ PartyList: partyList, - TrainingEnergy: 10, - TrainingEnergyMax: 10, + TrainingEnergy: userInfo.TrainingEnergy, + TrainingEnergyMax: userInfo.TrainingEnergyMax, ServerTimestamp: time.Now().Unix(), }, ReleaseInfo: []any{}, diff --git a/internal/session/userdata.go b/internal/session/userdata.go index c85a9f3..b18cbb4 100644 --- a/internal/session/userdata.go +++ b/internal/session/userdata.go @@ -16,6 +16,8 @@ var defaultLpRecoveryItemIDs = []int{ 777015, 777016, 777017, 777018, 777019, 777020, } +const defaultTrainingEnergy = 999 + func (ss *Session) GetUserPref(userID string) usermodel.UserPref { pref := usermodel.UserPref{} has, err := ss.UserEng.Table(new(usermodel.UserPref)). @@ -62,8 +64,8 @@ func (ss *Session) GetUserInfo() userschema.UserInfo { LicenseLiveEnergyRecoverlyTime: 60, EnergyFullNeedTime: 0, OverMaxEnergy: ss.UserPref.EffectiveCurrentEnergy(), - TrainingEnergy: 10, - TrainingEnergyMax: 10, + TrainingEnergy: defaultTrainingEnergy, + TrainingEnergyMax: defaultTrainingEnergy, FriendMax: 99, InviteCode: ss.UserPref.InviteCode, InsertDate: "2015-08-10 18:58:30",