Implement Tower accumulation reward claiming

This commit is contained in:
Ilya Groshev
2026-05-16 20:51:44 +03:00
parent 1dc5b8fd7c
commit 25cbe8635f
13 changed files with 272 additions and 66 deletions
+1
View File
@@ -26,6 +26,7 @@ func CloneUserState(u UserState) UserState {
Unlocks: maps.Clone(u.Gimmick.Unlocks),
}
out.CageOrnamentRewards = maps.Clone(u.CageOrnamentRewards)
out.TowerAccumulationRewards = maps.Clone(u.TowerAccumulationRewards)
out.ConsumableItems = maps.Clone(u.ConsumableItems)
out.Materials = maps.Clone(u.Materials)
out.Parts = maps.Clone(u.Parts)
+25 -24
View File
@@ -123,30 +123,31 @@ func SeedUserState(userId int64, uuid string, nowMillis int64, platform model.Cl
Sequences: make(map[GimmickSequenceKey]GimmickSequenceState),
Unlocks: make(map[GimmickKey]GimmickUnlockState),
},
CageOrnamentRewards: make(map[int32]CageOrnamentRewardState),
ConsumableItems: make(map[int32]int32),
Materials: make(map[int32]int32),
Thoughts: make(map[string]ThoughtState),
Parts: make(map[string]PartsState),
PartsGroupNotes: make(map[int32]PartsGroupNoteState),
PartsPresets: make(map[int32]PartsPresetState),
PartsPresetTags: make(map[int32]PartsPresetTagState),
PartsStatusSubs: make(map[PartsStatusSubKey]PartsStatusSubState),
ImportantItems: make(map[int32]int32),
CostumeActiveSkills: make(map[string]CostumeActiveSkillState),
WeaponSkills: make(map[string][]WeaponSkillState),
WeaponAbilities: make(map[string][]WeaponAbilityState),
DeckTypeNotes: make(map[model.DeckType]DeckTypeNoteState),
WeaponNotes: make(map[int32]WeaponNoteState),
NaviCutInPlayed: make(map[int32]bool),
ViewedMovies: make(map[int32]int64),
ContentsStories: make(map[int32]int64),
DrawnOmikuji: make(map[int32]int64),
PremiumItems: make(map[int32]int64),
DokanConfirmed: make(map[int32]bool),
ShopItems: make(map[int32]UserShopItemState),
ShopReplaceableLineup: make(map[int32]UserShopReplaceableLineupState),
ExploreScores: make(map[int32]ExploreScoreState),
CageOrnamentRewards: make(map[int32]CageOrnamentRewardState),
TowerAccumulationRewards: make(map[int32]TowerAccumulationRewardState),
ConsumableItems: make(map[int32]int32),
Materials: make(map[int32]int32),
Thoughts: make(map[string]ThoughtState),
Parts: make(map[string]PartsState),
PartsGroupNotes: make(map[int32]PartsGroupNoteState),
PartsPresets: make(map[int32]PartsPresetState),
PartsPresetTags: make(map[int32]PartsPresetTagState),
PartsStatusSubs: make(map[PartsStatusSubKey]PartsStatusSubState),
ImportantItems: make(map[int32]int32),
CostumeActiveSkills: make(map[string]CostumeActiveSkillState),
WeaponSkills: make(map[string][]WeaponSkillState),
WeaponAbilities: make(map[string][]WeaponAbilityState),
DeckTypeNotes: make(map[model.DeckType]DeckTypeNoteState),
WeaponNotes: make(map[int32]WeaponNoteState),
NaviCutInPlayed: make(map[int32]bool),
ViewedMovies: make(map[int32]int64),
ContentsStories: make(map[int32]int64),
DrawnOmikuji: make(map[int32]int64),
PremiumItems: make(map[int32]int64),
DokanConfirmed: make(map[int32]bool),
ShopItems: make(map[int32]UserShopItemState),
ShopReplaceableLineup: make(map[int32]UserShopReplaceableLineupState),
ExploreScores: make(map[int32]ExploreScoreState),
CharacterBoards: make(map[int32]CharacterBoardState),
CharacterBoardAbilities: make(map[CharacterBoardAbilityKey]CharacterBoardAbilityState),
+8
View File
@@ -77,6 +77,7 @@ func initMaps(u *store.UserState) {
u.ShopReplaceableLineup = make(map[int32]store.UserShopReplaceableLineupState)
u.ExploreScores = make(map[int32]store.ExploreScoreState)
u.CageOrnamentRewards = make(map[int32]store.CageOrnamentRewardState)
u.TowerAccumulationRewards = make(map[int32]store.TowerAccumulationRewardState)
u.CharacterBoards = make(map[int32]store.CharacterBoardState)
u.CharacterBoardAbilities = make(map[store.CharacterBoardAbilityKey]store.CharacterBoardAbilityState)
u.CharacterBoardStatusUps = make(map[store.CharacterBoardStatusUpKey]store.CharacterBoardStatusUpState)
@@ -651,6 +652,13 @@ func loadMapTables(db *sql.DB, uid int64, u *store.UserState) {
u.CageOrnamentRewards[v.CageOrnamentId] = v
})
queryRows(db, `SELECT event_quest_chapter_id, latest_reward_receive_quest_mission_clear_count, latest_version
FROM user_event_quest_tower_accumulation_rewards WHERE user_id=?`, uid, func(rows *sql.Rows) {
var v store.TowerAccumulationRewardState
rows.Scan(&v.EventQuestChapterId, &v.LatestRewardReceiveQuestMissionClearCount, &v.LatestVersion)
u.TowerAccumulationRewards[v.EventQuestChapterId] = v
})
queryRows(db, `SELECT shop_item_id, bought_count, latest_bought_count_changed_datetime, latest_version
FROM user_shop_items WHERE user_id=?`, uid, func(rows *sql.Rows) {
var v store.UserShopItemState
+11
View File
@@ -454,6 +454,12 @@ func writeUserState(tx *sql.Tx, uid int64, u *store.UserState) error {
return err
}
}
for _, v := range u.TowerAccumulationRewards {
if err := exec(`INSERT INTO user_event_quest_tower_accumulation_rewards (user_id, event_quest_chapter_id, latest_reward_receive_quest_mission_clear_count, latest_version) VALUES (?,?,?,?)`,
uid, v.EventQuestChapterId, v.LatestRewardReceiveQuestMissionClearCount, v.LatestVersion); err != nil {
return err
}
}
for _, v := range u.ShopItems {
if err := exec(`INSERT INTO user_shop_items (user_id, shop_item_id, bought_count, latest_bought_count_changed_datetime, latest_version) VALUES (?,?,?,?,?)`,
uid, v.ShopItemId, v.BoughtCount, v.LatestBoughtCountChangedDatetime, v.LatestVersion); err != nil {
@@ -994,6 +1000,11 @@ func diffAndSave(tx *sql.Tx, uid int64, before, after *store.UserState) error {
return []any{v.CageOrnamentId, v.AcquisitionDatetime, v.LatestVersion}
},
"cage_ornament_id, acquisition_datetime, latest_version")
diffMapInt32(tx, uid, before.TowerAccumulationRewards, after.TowerAccumulationRewards, "user_event_quest_tower_accumulation_rewards", "event_quest_chapter_id",
func(v store.TowerAccumulationRewardState) []any {
return []any{v.EventQuestChapterId, v.LatestRewardReceiveQuestMissionClearCount, v.LatestVersion}
},
"event_quest_chapter_id, latest_reward_receive_quest_mission_clear_count, latest_version")
diffMapInt32(tx, uid, before.ShopItems, after.ShopItems, "user_shop_items", "shop_item_id",
func(v store.UserShopItemState) []any {
return []any{v.ShopItemId, v.BoughtCount, v.LatestBoughtCountChangedDatetime, v.LatestVersion}
+1
View File
@@ -79,6 +79,7 @@ func (s *SQLiteStore) ImportUser(u *store.UserState) error {
// Child tables in reverse-dependency order (matches schema's goose Down).
childTables := []string{
"user_event_quest_tower_accumulation_rewards",
"user_cage_ornament_rewards",
"user_shop_replaceable_lineup",
"user_shop_items",
+51 -41
View File
@@ -63,47 +63,48 @@ type UserState struct {
Gacha GachaState
Notifications NotificationState
Characters map[int32]CharacterState
Costumes map[string]CostumeState
Weapons map[string]WeaponState
Companions map[string]CompanionState
Thoughts map[string]ThoughtState
DeckCharacters map[string]DeckCharacterState
Decks map[DeckKey]DeckState
TripleDecks map[DeckKey]TripleDeckState
Quests map[int32]UserQuestState
QuestMissions map[QuestMissionKey]UserQuestMissionState
Missions map[int32]UserMissionState
WeaponStories map[int32]WeaponStoryState
Gimmick GimmickState
CageOrnamentRewards map[int32]CageOrnamentRewardState
ConsumableItems map[int32]int32
Materials map[int32]int32
Parts map[string]PartsState
PartsGroupNotes map[int32]PartsGroupNoteState
PartsPresets map[int32]PartsPresetState
PartsPresetTags map[int32]PartsPresetTagState
PartsStatusSubs map[PartsStatusSubKey]PartsStatusSubState
ImportantItems map[int32]int32
CostumeActiveSkills map[string]CostumeActiveSkillState
WeaponSkills map[string][]WeaponSkillState // key: userWeaponUuid
WeaponAbilities map[string][]WeaponAbilityState // key: userWeaponUuid
WeaponAwakens map[string]WeaponAwakenState // key: userWeaponUuid
DeckTypeNotes map[model.DeckType]DeckTypeNoteState
WeaponNotes map[int32]WeaponNoteState
DeckSubWeapons map[string][]string
DeckParts map[string][]string
NaviCutInPlayed map[int32]bool
ViewedMovies map[int32]int64
ContentsStories map[int32]int64
DrawnOmikuji map[int32]int64
PremiumItems map[int32]int64
DokanConfirmed map[int32]bool
PortalCageStatus PortalCageStatusState
GuerrillaFreeOpen GuerrillaFreeOpenState
ShopItems map[int32]UserShopItemState
ShopReplaceable UserShopReplaceableState
ShopReplaceableLineup map[int32]UserShopReplaceableLineupState
Characters map[int32]CharacterState
Costumes map[string]CostumeState
Weapons map[string]WeaponState
Companions map[string]CompanionState
Thoughts map[string]ThoughtState
DeckCharacters map[string]DeckCharacterState
Decks map[DeckKey]DeckState
TripleDecks map[DeckKey]TripleDeckState
Quests map[int32]UserQuestState
QuestMissions map[QuestMissionKey]UserQuestMissionState
Missions map[int32]UserMissionState
WeaponStories map[int32]WeaponStoryState
Gimmick GimmickState
CageOrnamentRewards map[int32]CageOrnamentRewardState
TowerAccumulationRewards map[int32]TowerAccumulationRewardState
ConsumableItems map[int32]int32
Materials map[int32]int32
Parts map[string]PartsState
PartsGroupNotes map[int32]PartsGroupNoteState
PartsPresets map[int32]PartsPresetState
PartsPresetTags map[int32]PartsPresetTagState
PartsStatusSubs map[PartsStatusSubKey]PartsStatusSubState
ImportantItems map[int32]int32
CostumeActiveSkills map[string]CostumeActiveSkillState
WeaponSkills map[string][]WeaponSkillState // key: userWeaponUuid
WeaponAbilities map[string][]WeaponAbilityState // key: userWeaponUuid
WeaponAwakens map[string]WeaponAwakenState // key: userWeaponUuid
DeckTypeNotes map[model.DeckType]DeckTypeNoteState
WeaponNotes map[int32]WeaponNoteState
DeckSubWeapons map[string][]string
DeckParts map[string][]string
NaviCutInPlayed map[int32]bool
ViewedMovies map[int32]int64
ContentsStories map[int32]int64
DrawnOmikuji map[int32]int64
PremiumItems map[int32]int64
DokanConfirmed map[int32]bool
PortalCageStatus PortalCageStatusState
GuerrillaFreeOpen GuerrillaFreeOpenState
ShopItems map[int32]UserShopItemState
ShopReplaceable UserShopReplaceableState
ShopReplaceableLineup map[int32]UserShopReplaceableLineupState
Explore ExploreState
ExploreScores map[int32]ExploreScoreState
@@ -192,6 +193,9 @@ func (u *UserState) EnsureMaps() {
if u.CageOrnamentRewards == nil {
u.CageOrnamentRewards = make(map[int32]CageOrnamentRewardState)
}
if u.TowerAccumulationRewards == nil {
u.TowerAccumulationRewards = make(map[int32]TowerAccumulationRewardState)
}
if u.ConsumableItems == nil {
u.ConsumableItems = make(map[int32]int32)
}
@@ -868,6 +872,12 @@ type CageOrnamentRewardState struct {
LatestVersion int64
}
type TowerAccumulationRewardState struct {
EventQuestChapterId int32
LatestRewardReceiveQuestMissionClearCount int32
LatestVersion int64
}
type PartsState struct {
UserPartsUuid string
PartsId int32