From 479ace5c8e8f2d12e4861e718e4ca97c7f4a0ef7 Mon Sep 17 00:00:00 2001 From: Ilya Groshev Date: Tue, 12 May 2026 09:27:28 +0300 Subject: [PATCH] Fix menu pick from replay flow returning to wrong state --- server/internal/questflow/quest.go | 6 ++++-- server/internal/store/sqlite/load.go | 4 ++-- server/internal/store/sqlite/save.go | 6 ++++-- server/internal/store/types.go | 1 + ...20260512055406_add_saved_ctx_current_quest_flow_type.sql | 5 +++++ 5 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 server/migrations/20260512055406_add_saved_ctx_current_quest_flow_type.sql diff --git a/server/internal/questflow/quest.go b/server/internal/questflow/quest.go index 32ce14d..6c46198 100644 --- a/server/internal/questflow/quest.go +++ b/server/internal/questflow/quest.go @@ -122,6 +122,7 @@ func snapshotMainQuestIfNeeded(user *store.UserState) { MainQuestSeasonId: user.MainQuest.MainQuestSeasonId, IsReachedLastQuestScene: user.MainQuest.IsReachedLastQuestScene, PortalCageInProgress: user.PortalCageStatus.IsCurrentProgress, + CurrentQuestFlowType: user.MainQuest.CurrentQuestFlowType, } } @@ -270,13 +271,14 @@ func (h *QuestHandler) HandleQuestFinish(user *store.UserState, questId int32, i user.MainQuest.CurrentMainQuestRouteId = ctx.CurrentMainQuestRouteId user.MainQuest.MainQuestSeasonId = ctx.MainQuestSeasonId user.MainQuest.IsReachedLastQuestScene = ctx.IsReachedLastQuestScene + user.MainQuest.CurrentQuestFlowType = ctx.CurrentQuestFlowType user.PortalCageStatus.IsCurrentProgress = ctx.PortalCageInProgress user.PortalCageStatus.LatestVersion = nowMillis user.MainQuest.SavedContext = store.SavedQuestContext{} user.MainQuest.LatestVersion = nowMillis - log.Printf("[HandleQuestFinish] restored snapshot for quest %d (route=%d season=%d scene=%d head=%d cage=%v)", + log.Printf("[HandleQuestFinish] restored snapshot for quest %d (route=%d season=%d scene=%d head=%d cage=%v flow=%d)", questId, ctx.CurrentMainQuestRouteId, ctx.MainQuestSeasonId, - ctx.CurrentQuestSceneId, ctx.HeadQuestSceneId, ctx.PortalCageInProgress) + ctx.CurrentQuestSceneId, ctx.HeadQuestSceneId, ctx.PortalCageInProgress, ctx.CurrentQuestFlowType) } h.clearQuestMissions(user, questId, nowMillis) diff --git a/server/internal/store/sqlite/load.go b/server/internal/store/sqlite/load.go index 700ccb5..224b3f5 100644 --- a/server/internal/store/sqlite/load.go +++ b/server/internal/store/sqlite/load.go @@ -131,7 +131,7 @@ func load1to1(db *sql.DB, uid int64, u *store.UserState) { progress_quest_flow_type, main_quest_season_id, latest_version, saved_ctx_active, saved_ctx_current_quest_scene_id, saved_ctx_head_quest_scene_id, saved_ctx_current_main_quest_route_id, saved_ctx_main_quest_season_id, - saved_ctx_is_reached_last_quest_scene, saved_ctx_portal_cage_in_progress, + saved_ctx_is_reached_last_quest_scene, saved_ctx_portal_cage_in_progress, saved_ctx_current_quest_flow_type, replay_flow_current_quest_scene_id, replay_flow_head_quest_scene_id FROM user_main_quest WHERE user_id=?`, uid). Scan(&u.MainQuest.CurrentQuestFlowType, &u.MainQuest.CurrentMainQuestRouteId, &u.MainQuest.CurrentQuestSceneId, @@ -139,7 +139,7 @@ func load1to1(db *sql.DB, uid int64, u *store.UserState) { &u.MainQuest.ProgressQuestFlowType, &u.MainQuest.MainQuestSeasonId, &u.MainQuest.LatestVersion, &ctxActive, &u.MainQuest.SavedContext.CurrentQuestSceneId, &u.MainQuest.SavedContext.HeadQuestSceneId, &u.MainQuest.SavedContext.CurrentMainQuestRouteId, &u.MainQuest.SavedContext.MainQuestSeasonId, - &ctxIsLast, &ctxCage, + &ctxIsLast, &ctxCage, &u.MainQuest.SavedContext.CurrentQuestFlowType, &u.MainQuest.ReplayFlowCurrentQuestSceneId, &u.MainQuest.ReplayFlowHeadQuestSceneId) u.MainQuest.IsReachedLastQuestScene = b != 0 u.MainQuest.SavedContext.Active = ctxActive != 0 diff --git a/server/internal/store/sqlite/save.go b/server/internal/store/sqlite/save.go index 47aa82a..86601b5 100644 --- a/server/internal/store/sqlite/save.go +++ b/server/internal/store/sqlite/save.go @@ -49,7 +49,7 @@ func writeUserState(tx *sql.Tx, uid int64, u *store.UserState) error { u.LoginBonus.LatestRewardReceiveDatetime, u.LoginBonus.LatestVersion); err != nil { return err } - if err := exec(`INSERT INTO user_main_quest (user_id, current_quest_flow_type, current_main_quest_route_id, current_quest_scene_id, head_quest_scene_id, is_reached_last_quest_scene, progress_quest_scene_id, progress_head_quest_scene_id, progress_quest_flow_type, main_quest_season_id, latest_version, saved_ctx_active, saved_ctx_current_quest_scene_id, saved_ctx_head_quest_scene_id, saved_ctx_current_main_quest_route_id, saved_ctx_main_quest_season_id, saved_ctx_is_reached_last_quest_scene, saved_ctx_portal_cage_in_progress, replay_flow_current_quest_scene_id, replay_flow_head_quest_scene_id) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`, + if err := exec(`INSERT INTO user_main_quest (user_id, current_quest_flow_type, current_main_quest_route_id, current_quest_scene_id, head_quest_scene_id, is_reached_last_quest_scene, progress_quest_scene_id, progress_head_quest_scene_id, progress_quest_flow_type, main_quest_season_id, latest_version, saved_ctx_active, saved_ctx_current_quest_scene_id, saved_ctx_head_quest_scene_id, saved_ctx_current_main_quest_route_id, saved_ctx_main_quest_season_id, saved_ctx_is_reached_last_quest_scene, saved_ctx_portal_cage_in_progress, saved_ctx_current_quest_flow_type, replay_flow_current_quest_scene_id, replay_flow_head_quest_scene_id) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`, uid, u.MainQuest.CurrentQuestFlowType, u.MainQuest.CurrentMainQuestRouteId, u.MainQuest.CurrentQuestSceneId, u.MainQuest.HeadQuestSceneId, boolToInt(u.MainQuest.IsReachedLastQuestScene), u.MainQuest.ProgressQuestSceneId, u.MainQuest.ProgressHeadQuestSceneId, u.MainQuest.ProgressQuestFlowType, u.MainQuest.MainQuestSeasonId, @@ -59,6 +59,7 @@ func writeUserState(tx *sql.Tx, uid int64, u *store.UserState) error { u.MainQuest.SavedContext.CurrentMainQuestRouteId, u.MainQuest.SavedContext.MainQuestSeasonId, boolToInt(u.MainQuest.SavedContext.IsReachedLastQuestScene), boolToInt(u.MainQuest.SavedContext.PortalCageInProgress), + u.MainQuest.SavedContext.CurrentQuestFlowType, u.MainQuest.ReplayFlowCurrentQuestSceneId, u.MainQuest.ReplayFlowHeadQuestSceneId); err != nil { return err } @@ -566,7 +567,7 @@ func diffAndSave(tx *sql.Tx, uid int64, before, after *store.UserState) error { } } if before.MainQuest != after.MainQuest { - if err := exec(`UPDATE user_main_quest SET current_quest_flow_type=?, current_main_quest_route_id=?, current_quest_scene_id=?, head_quest_scene_id=?, is_reached_last_quest_scene=?, progress_quest_scene_id=?, progress_head_quest_scene_id=?, progress_quest_flow_type=?, main_quest_season_id=?, latest_version=?, saved_ctx_active=?, saved_ctx_current_quest_scene_id=?, saved_ctx_head_quest_scene_id=?, saved_ctx_current_main_quest_route_id=?, saved_ctx_main_quest_season_id=?, saved_ctx_is_reached_last_quest_scene=?, saved_ctx_portal_cage_in_progress=?, replay_flow_current_quest_scene_id=?, replay_flow_head_quest_scene_id=? WHERE user_id=?`, + if err := exec(`UPDATE user_main_quest SET current_quest_flow_type=?, current_main_quest_route_id=?, current_quest_scene_id=?, head_quest_scene_id=?, is_reached_last_quest_scene=?, progress_quest_scene_id=?, progress_head_quest_scene_id=?, progress_quest_flow_type=?, main_quest_season_id=?, latest_version=?, saved_ctx_active=?, saved_ctx_current_quest_scene_id=?, saved_ctx_head_quest_scene_id=?, saved_ctx_current_main_quest_route_id=?, saved_ctx_main_quest_season_id=?, saved_ctx_is_reached_last_quest_scene=?, saved_ctx_portal_cage_in_progress=?, saved_ctx_current_quest_flow_type=?, replay_flow_current_quest_scene_id=?, replay_flow_head_quest_scene_id=? WHERE user_id=?`, after.MainQuest.CurrentQuestFlowType, after.MainQuest.CurrentMainQuestRouteId, after.MainQuest.CurrentQuestSceneId, after.MainQuest.HeadQuestSceneId, boolToInt(after.MainQuest.IsReachedLastQuestScene), after.MainQuest.ProgressQuestSceneId, after.MainQuest.ProgressHeadQuestSceneId, after.MainQuest.ProgressQuestFlowType, after.MainQuest.MainQuestSeasonId, @@ -576,6 +577,7 @@ func diffAndSave(tx *sql.Tx, uid int64, before, after *store.UserState) error { after.MainQuest.SavedContext.CurrentMainQuestRouteId, after.MainQuest.SavedContext.MainQuestSeasonId, boolToInt(after.MainQuest.SavedContext.IsReachedLastQuestScene), boolToInt(after.MainQuest.SavedContext.PortalCageInProgress), + after.MainQuest.SavedContext.CurrentQuestFlowType, after.MainQuest.ReplayFlowCurrentQuestSceneId, after.MainQuest.ReplayFlowHeadQuestSceneId, uid); err != nil { return err } diff --git a/server/internal/store/types.go b/server/internal/store/types.go index 4ae1546..b978f8e 100644 --- a/server/internal/store/types.go +++ b/server/internal/store/types.go @@ -530,6 +530,7 @@ type SavedQuestContext struct { MainQuestSeasonId int32 IsReachedLastQuestScene bool PortalCageInProgress bool + CurrentQuestFlowType int32 } type EventQuestState struct { diff --git a/server/migrations/20260512055406_add_saved_ctx_current_quest_flow_type.sql b/server/migrations/20260512055406_add_saved_ctx_current_quest_flow_type.sql new file mode 100644 index 0000000..d35aec4 --- /dev/null +++ b/server/migrations/20260512055406_add_saved_ctx_current_quest_flow_type.sql @@ -0,0 +1,5 @@ +-- +goose Up +ALTER TABLE user_main_quest ADD COLUMN saved_ctx_current_quest_flow_type INTEGER NOT NULL DEFAULT 0; + +-- +goose Down +ALTER TABLE user_main_quest DROP COLUMN saved_ctx_current_quest_flow_type;