Derive main-quest season routes at projection time

This commit is contained in:
Ilya Groshev
2026-05-22 17:24:30 +03:00
parent ef69c54949
commit 810adcf990
11 changed files with 101 additions and 96 deletions
+4 -2
View File
@@ -101,8 +101,9 @@ func ChangedTables(before, after *store.UserState) []string {
add("IUserMainQuestMainFlowStatus")
add("IUserMainQuestProgressStatus")
add("IUserMainQuestReplayFlowStatus")
}
if !mapsEqualStruct(before.MainQuestSeasonRoutes, after.MainQuestSeasonRoutes) {
// IUserMainQuestSeasonRoute is derived from MainQuest + Quests at projection
// time (see proj_quest.go / questflow.QuestHandler.SeasonRoutesFor) — flag it
// whenever either of those upstream inputs changes.
add("IUserMainQuestSeasonRoute")
}
if before.EventQuest != after.EventQuest {
@@ -202,6 +203,7 @@ func ChangedTables(before, after *store.UserState) []string {
}
if !mapsEqualStruct(before.Quests, after.Quests) {
add("IUserQuest")
add("IUserMainQuestSeasonRoute")
}
if !mapsEqualStruct(before.QuestMissions, after.QuestMissions) {
add("IUserQuestMission")
+17 -26
View File
@@ -116,38 +116,29 @@ func init() {
return s
})
register("IUserMainQuestSeasonRoute", func(user store.UserState) string {
if len(user.MainQuestSeasonRoutes) == 0 {
// Fallback to current (season, route) for legacy saves with no history.
s, _ := utils.EncodeJSONMaps(map[string]any{
"userId": user.UserId,
"mainQuestSeasonId": user.MainQuest.MainQuestSeasonId,
"mainQuestRouteId": user.MainQuest.CurrentMainQuestRouteId,
"latestVersion": user.MainQuest.LatestVersion,
})
return s
if questHandler == nil {
return "[]"
}
keys := make([]store.SeasonRouteKey, 0, len(user.MainQuestSeasonRoutes))
for k := range user.MainQuestSeasonRoutes {
keys = append(keys, k)
pairs := questHandler.SeasonRoutesFor(&user)
if len(pairs) == 0 {
return "[]"
}
sort.Slice(keys, func(i, j int) bool {
if keys[i].MainQuestSeasonId != keys[j].MainQuestSeasonId {
return keys[i].MainQuestSeasonId < keys[j].MainQuestSeasonId
}
return keys[i].MainQuestRouteId < keys[j].MainQuestRouteId
})
records := make([]map[string]any, 0, len(keys))
for _, k := range keys {
e := user.MainQuestSeasonRoutes[k]
seasons := make([]int32, 0, len(pairs))
for s := range pairs {
seasons = append(seasons, s)
}
sort.Slice(seasons, func(i, j int) bool { return seasons[i] < seasons[j] })
records := make([]map[string]any, 0, len(seasons))
for _, s := range seasons {
records = append(records, map[string]any{
"userId": user.UserId,
"mainQuestSeasonId": e.MainQuestSeasonId,
"mainQuestRouteId": e.MainQuestRouteId,
"latestVersion": e.LatestVersion,
"mainQuestSeasonId": s,
"mainQuestRouteId": pairs[s],
"latestVersion": user.MainQuest.LatestVersion,
})
}
s, _ := utils.EncodeJSONMaps(records...)
return s
out, _ := utils.EncodeJSONMaps(records...)
return out
})
register("IUserEventQuestProgressStatus", func(user store.UserState) string {
s, _ := utils.EncodeJSONMaps(map[string]any{
+7
View File
@@ -3,6 +3,7 @@ package userdata
import (
"sort"
"lunar-tear/server/internal/questflow"
"lunar-tear/server/internal/store"
)
@@ -10,6 +11,12 @@ type Projector func(user store.UserState) string
var projectors = make(map[string]Projector)
var questHandler *questflow.QuestHandler
func SetQuestHandler(h *questflow.QuestHandler) {
questHandler = h
}
func register(tableName string, fn Projector) {
projectors[tableName] = fn
}