From 0d46ee4557d81270c5e040948f8abeaafee768a4 Mon Sep 17 00:00:00 2001 From: Ilya Groshev Date: Sun, 17 May 2026 11:02:40 +0300 Subject: [PATCH] Fix replay flow loop on background quests and another-route flow type --- server/internal/questflow/quest.go | 28 ++++++++++++++++++++-------- server/internal/questflow/scene.go | 16 ++++++++++++++-- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/server/internal/questflow/quest.go b/server/internal/questflow/quest.go index 92f36f6..194c299 100644 --- a/server/internal/questflow/quest.go +++ b/server/internal/questflow/quest.go @@ -84,7 +84,7 @@ func (h *QuestHandler) handleQuestStartInternal(user *store.UserState, questId i } case isReplayFlow: - h.applyReplayStart(user, questId, isBattleOnly, nowMillis) + h.applyReplayStart(user, quest, questId, isBattleOnly, nowMillis) return } @@ -131,9 +131,7 @@ func snapshotMainQuestIfNeeded(user *store.UserState) { } } -// Preserve CurrentQuestFlowType when HandleReplayFlowSceneProgress already -// set it: replay-variant ids (30000+) aren't in RouteIdByQuestId. -func (h *QuestHandler) applyReplayStart(user *store.UserState, questId int32, isBattleOnly bool, nowMillis int64) { +func (h *QuestHandler) applyReplayStart(user *store.UserState, quest masterdata.EntityMQuest, questId int32, isBattleOnly bool, nowMillis int64) { flowType := h.replayFlowTypeFromQuestId(user, questId) if model.IsReplayQuestFlowType(user.MainQuest.CurrentQuestFlowType) { flowType = model.QuestFlowType(user.MainQuest.CurrentQuestFlowType) @@ -142,12 +140,26 @@ func (h *QuestHandler) applyReplayStart(user *store.UserState, questId int32, is user.MainQuest.LatestVersion = nowMillis questState := user.Quests[questId] - questState.QuestStateType = model.UserQuestStateTypeActive questState.LatestStartDatetime = nowMillis - user.Quests[questId] = questState - log.Printf("[HandleQuestStart] replay quest=%d flowType=%s isBattleOnly=%v current=%d head=%d", - questId, flowType, isBattleOnly, + if isMainQuestPlayable(quest) { + questState.QuestStateType = model.UserQuestStateTypeActive + user.Quests[questId] = questState + } else { + if questState.QuestStateType != model.UserQuestStateTypeCleared { + questState.QuestStateType = model.UserQuestStateTypeCleared + questState.ClearCount++ + questState.DailyClearCount++ + questState.LastClearDatetime = nowMillis + } + user.Quests[questId] = questState + if sceneIds := h.SceneIdsByQuestId[questId]; len(sceneIds) > 0 { + h.advanceReplayFlowScene(user, sceneIds[0]) + } + } + + log.Printf("[HandleQuestStart] replay quest=%d flowType=%s isBattleOnly=%v playable=%v current=%d head=%d", + questId, flowType, isBattleOnly, isMainQuestPlayable(quest), user.MainQuest.ReplayFlowCurrentQuestSceneId, user.MainQuest.ReplayFlowHeadQuestSceneId) } diff --git a/server/internal/questflow/scene.go b/server/internal/questflow/scene.go index 0500fe4..88795f7 100644 --- a/server/internal/questflow/scene.go +++ b/server/internal/questflow/scene.go @@ -51,8 +51,14 @@ func (h *QuestHandler) advanceMainFlowScene(user *store.UserState, questId, scen } } -// Backs IUserMainQuestSeasonRoute: the client needs the history to load -// scene metadata when cage menu-replay jumps to older chapters. +func (h *QuestHandler) advanceReplayFlowScene(user *store.UserState, sceneId int32) { + if !h.isSceneAhead(sceneId, user.MainQuest.ReplayFlowHeadQuestSceneId) { + return + } + user.MainQuest.ReplayFlowCurrentQuestSceneId = sceneId + user.MainQuest.ReplayFlowHeadQuestSceneId = sceneId +} + func RecordSeasonRoute(user *store.UserState, seasonId, routeId int32, nowMillis int64) { if seasonId <= 0 || routeId <= 0 { return @@ -176,6 +182,12 @@ func (h *QuestHandler) replayFlowTypeForRoute(user *store.UserState, routeId int return model.QuestFlowTypeAnotherRouteReplayFlow } } + if len(user.MainQuestSeasonRoutes) == 0 && + user.MainQuest.MainQuestSeasonId == seasonId && + user.MainQuest.CurrentMainQuestRouteId != 0 && + user.MainQuest.CurrentMainQuestRouteId != routeId { + return model.QuestFlowTypeAnotherRouteReplayFlow + } return model.QuestFlowTypeReplayFlow }