mirror of
https://github.com/Walter-Sparrow/lunar-tear.git
synced 2026-07-02 05:43:41 +03:00
Compare commits
2 Commits
fa5d023f58
...
dd00cadc18
| Author | SHA1 | Date | |
|---|---|---|---|
| dd00cadc18 | |||
| ae884b4060 |
@@ -2,6 +2,7 @@ package masterdata
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
"lunar-tear/server/internal/model"
|
"lunar-tear/server/internal/model"
|
||||||
"lunar-tear/server/internal/utils"
|
"lunar-tear/server/internal/utils"
|
||||||
@@ -34,6 +35,7 @@ func BuildExpThresholds(paramMapRows []EntityMNumericalParameterMap, mapId int32
|
|||||||
type MaterialCatalog struct {
|
type MaterialCatalog struct {
|
||||||
All map[int32]EntityMMaterial
|
All map[int32]EntityMMaterial
|
||||||
ByType map[model.MaterialType]map[int32]EntityMMaterial
|
ByType map[model.MaterialType]map[int32]EntityMMaterial
|
||||||
|
SaleObtain map[int32][]EntityMMaterialSaleObtainPossession
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadMaterialCatalog() (*MaterialCatalog, error) {
|
func LoadMaterialCatalog() (*MaterialCatalog, error) {
|
||||||
@@ -45,6 +47,7 @@ func LoadMaterialCatalog() (*MaterialCatalog, error) {
|
|||||||
catalog := &MaterialCatalog{
|
catalog := &MaterialCatalog{
|
||||||
All: make(map[int32]EntityMMaterial, len(rows)),
|
All: make(map[int32]EntityMMaterial, len(rows)),
|
||||||
ByType: make(map[model.MaterialType]map[int32]EntityMMaterial),
|
ByType: make(map[model.MaterialType]map[int32]EntityMMaterial),
|
||||||
|
SaleObtain: make(map[int32][]EntityMMaterialSaleObtainPossession),
|
||||||
}
|
}
|
||||||
for _, row := range rows {
|
for _, row := range rows {
|
||||||
catalog.All[row.MaterialId] = row
|
catalog.All[row.MaterialId] = row
|
||||||
@@ -54,5 +57,15 @@ func LoadMaterialCatalog() (*MaterialCatalog, error) {
|
|||||||
}
|
}
|
||||||
catalog.ByType[mt][row.MaterialId] = row
|
catalog.ByType[mt][row.MaterialId] = row
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saleRows, err := utils.ReadTable[EntityMMaterialSaleObtainPossession]("m_material_sale_obtain_possession")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("material catalog: sale-obtain table unavailable, side rewards on sell will be skipped: %v", err)
|
||||||
|
} else {
|
||||||
|
for _, row := range saleRows {
|
||||||
|
catalog.SaleObtain[row.MaterialSaleObtainPossessionId] = append(catalog.SaleObtain[row.MaterialSaleObtainPossessionId], row)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return catalog, nil
|
return catalog, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,6 +166,10 @@ func (h *QuestHandler) applyExpRewards(user *store.UserState, questId int32, now
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if questDef.CharacterExp == 0 && questDef.CostumeExp == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
deckCostumeUuids, deckCharacterIds := h.resolveDeckUnits(user, questId)
|
deckCostumeUuids, deckCharacterIds := h.resolveDeckUnits(user, questId)
|
||||||
if deckCostumeUuids == nil {
|
if deckCostumeUuids == nil {
|
||||||
log.Printf("[applyExpRewards] questId=%d skipping character/costume exp (deck not resolved)", questId)
|
log.Printf("[applyExpRewards] questId=%d skipping character/costume exp (deck not resolved)", questId)
|
||||||
|
|||||||
@@ -191,11 +191,45 @@ func (s *DeckServiceServer) ReplaceTripleDeck(ctx context.Context, req *pb.Repla
|
|||||||
}
|
}
|
||||||
store.ApplyDeckReplacement(user, model.DeckType(detail.DeckType), detail.UserDeckNumber, deckSlotsFromProto(detail.Deck), nowMillis)
|
store.ApplyDeckReplacement(user, model.DeckType(detail.DeckType), detail.UserDeckNumber, deckSlotsFromProto(detail.Deck), nowMillis)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := store.DeckKey{DeckType: model.DeckType(req.DeckType), UserDeckNumber: req.UserDeckNumber}
|
||||||
|
td := user.TripleDecks[key]
|
||||||
|
td.DeckType = model.DeckType(req.DeckType)
|
||||||
|
td.UserDeckNumber = req.UserDeckNumber
|
||||||
|
td.DeckNumber01 = innerDeckNumber(req.DeckDetail01)
|
||||||
|
td.DeckNumber02 = innerDeckNumber(req.DeckDetail02)
|
||||||
|
td.DeckNumber03 = innerDeckNumber(req.DeckDetail03)
|
||||||
|
td.LatestVersion = nowMillis
|
||||||
|
user.TripleDecks[key] = td
|
||||||
})
|
})
|
||||||
|
|
||||||
return &pb.ReplaceTripleDeckResponse{}, nil
|
return &pb.ReplaceTripleDeckResponse{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func innerDeckNumber(d *pb.DeckDetail) int32 {
|
||||||
|
if d == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return d.UserDeckNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DeckServiceServer) UpdateTripleDeckName(ctx context.Context, req *pb.UpdateTripleDeckNameRequest) (*pb.UpdateTripleDeckNameResponse, error) {
|
||||||
|
log.Printf("[DeckService] UpdateTripleDeckName: deckType=%d deckNumber=%d name=%q", req.DeckType, req.UserDeckNumber, req.Name)
|
||||||
|
userId := CurrentUserId(ctx, s.users, s.sessions)
|
||||||
|
|
||||||
|
s.users.UpdateUser(userId, func(user *store.UserState) {
|
||||||
|
key := store.DeckKey{DeckType: model.DeckType(req.DeckType), UserDeckNumber: req.UserDeckNumber}
|
||||||
|
td := user.TripleDecks[key]
|
||||||
|
td.DeckType = model.DeckType(req.DeckType)
|
||||||
|
td.UserDeckNumber = req.UserDeckNumber
|
||||||
|
td.Name = req.Name
|
||||||
|
td.LatestVersion = gametime.NowMillis()
|
||||||
|
user.TripleDecks[key] = td
|
||||||
|
})
|
||||||
|
|
||||||
|
return &pb.UpdateTripleDeckNameResponse{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *DeckServiceServer) ReplaceMultiDeck(ctx context.Context, req *pb.ReplaceMultiDeckRequest) (*pb.ReplaceMultiDeckResponse, error) {
|
func (s *DeckServiceServer) ReplaceMultiDeck(ctx context.Context, req *pb.ReplaceMultiDeckRequest) (*pb.ReplaceMultiDeckResponse, error) {
|
||||||
log.Printf("[DeckService] ReplaceMultiDeck: %d entries", len(req.DeckDetail))
|
log.Printf("[DeckService] ReplaceMultiDeck: %d entries", len(req.DeckDetail))
|
||||||
userId := CurrentUserId(ctx, s.users, s.sessions)
|
userId := CurrentUserId(ctx, s.users, s.sessions)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
|
|
||||||
pb "lunar-tear/server/gen/proto"
|
pb "lunar-tear/server/gen/proto"
|
||||||
|
"lunar-tear/server/internal/model"
|
||||||
"lunar-tear/server/internal/runtime"
|
"lunar-tear/server/internal/runtime"
|
||||||
"lunar-tear/server/internal/store"
|
"lunar-tear/server/internal/store"
|
||||||
)
|
)
|
||||||
@@ -52,6 +53,14 @@ func (s *MaterialServiceServer) Sell(ctx context.Context, req *pb.MaterialSellRe
|
|||||||
gold := mat.SellPrice * item.Count
|
gold := mat.SellPrice * item.Count
|
||||||
totalGold += gold
|
totalGold += gold
|
||||||
log.Printf("[MaterialService] Sell: materialId=%d x%d -> %d gold", item.MaterialId, item.Count, gold)
|
log.Printf("[MaterialService] Sell: materialId=%d x%d -> %d gold", item.MaterialId, item.Count, gold)
|
||||||
|
|
||||||
|
if mat.MaterialSaleObtainPossessionId != 0 {
|
||||||
|
for _, row := range catalog.SaleObtain[mat.MaterialSaleObtainPossessionId] {
|
||||||
|
grantCount := row.Count * item.Count
|
||||||
|
store.GrantPossession(user, model.PossessionType(row.PossessionType), row.PossessionId, grantCount)
|
||||||
|
log.Printf("[MaterialService] Sell: materialId=%d x%d -> SaleObtain type=%d id=%d +%d", item.MaterialId, item.Count, row.PossessionType, row.PossessionId, grantCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if totalGold > 0 {
|
if totalGold > 0 {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ func CloneUserState(u UserState) UserState {
|
|||||||
out.DeckSubWeapons = cloneSliceMap(u.DeckSubWeapons)
|
out.DeckSubWeapons = cloneSliceMap(u.DeckSubWeapons)
|
||||||
out.DeckParts = cloneSliceMap(u.DeckParts)
|
out.DeckParts = cloneSliceMap(u.DeckParts)
|
||||||
out.Decks = maps.Clone(u.Decks)
|
out.Decks = maps.Clone(u.Decks)
|
||||||
|
out.TripleDecks = maps.Clone(u.TripleDecks)
|
||||||
out.Quests = maps.Clone(u.Quests)
|
out.Quests = maps.Clone(u.Quests)
|
||||||
out.QuestMissions = maps.Clone(u.QuestMissions)
|
out.QuestMissions = maps.Clone(u.QuestMissions)
|
||||||
out.WeaponStories = maps.Clone(u.WeaponStories)
|
out.WeaponStories = maps.Clone(u.WeaponStories)
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ func SeedUserState(userId int64, uuid string, nowMillis int64, platform model.Cl
|
|||||||
Companions: make(map[string]CompanionState),
|
Companions: make(map[string]CompanionState),
|
||||||
DeckCharacters: make(map[string]DeckCharacterState),
|
DeckCharacters: make(map[string]DeckCharacterState),
|
||||||
Decks: make(map[DeckKey]DeckState),
|
Decks: make(map[DeckKey]DeckState),
|
||||||
|
TripleDecks: make(map[DeckKey]TripleDeckState),
|
||||||
DeckSubWeapons: make(map[string][]string),
|
DeckSubWeapons: make(map[string][]string),
|
||||||
DeckParts: make(map[string][]string),
|
DeckParts: make(map[string][]string),
|
||||||
Quests: make(map[int32]UserQuestState),
|
Quests: make(map[int32]UserQuestState),
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ func initMaps(u *store.UserState) {
|
|||||||
u.Thoughts = make(map[string]store.ThoughtState)
|
u.Thoughts = make(map[string]store.ThoughtState)
|
||||||
u.DeckCharacters = make(map[string]store.DeckCharacterState)
|
u.DeckCharacters = make(map[string]store.DeckCharacterState)
|
||||||
u.Decks = make(map[store.DeckKey]store.DeckState)
|
u.Decks = make(map[store.DeckKey]store.DeckState)
|
||||||
|
u.TripleDecks = make(map[store.DeckKey]store.TripleDeckState)
|
||||||
u.DeckSubWeapons = make(map[string][]string)
|
u.DeckSubWeapons = make(map[string][]string)
|
||||||
u.DeckParts = make(map[string][]string)
|
u.DeckParts = make(map[string][]string)
|
||||||
u.Quests = make(map[int32]store.UserQuestState)
|
u.Quests = make(map[int32]store.UserQuestState)
|
||||||
@@ -299,6 +300,16 @@ func loadMapTables(db *sql.DB, uid int64, u *store.UserState) {
|
|||||||
u.Decks[store.DeckKey{DeckType: v.DeckType, UserDeckNumber: v.UserDeckNumber}] = v
|
u.Decks[store.DeckKey{DeckType: v.DeckType, UserDeckNumber: v.UserDeckNumber}] = v
|
||||||
})
|
})
|
||||||
|
|
||||||
|
queryRows(db, `SELECT deck_type, user_deck_number, name, deck_number01, deck_number02, deck_number03, latest_version
|
||||||
|
FROM user_triple_decks WHERE user_id=?`, uid,
|
||||||
|
func(rows *sql.Rows) {
|
||||||
|
var v store.TripleDeckState
|
||||||
|
var dt int32
|
||||||
|
rows.Scan(&dt, &v.UserDeckNumber, &v.Name, &v.DeckNumber01, &v.DeckNumber02, &v.DeckNumber03, &v.LatestVersion)
|
||||||
|
v.DeckType = model.DeckType(dt)
|
||||||
|
u.TripleDecks[store.DeckKey{DeckType: v.DeckType, UserDeckNumber: v.UserDeckNumber}] = v
|
||||||
|
})
|
||||||
|
|
||||||
queryRows(db, `SELECT user_deck_character_uuid, ordinal, user_weapon_uuid
|
queryRows(db, `SELECT user_deck_character_uuid, ordinal, user_weapon_uuid
|
||||||
FROM user_deck_sub_weapons WHERE user_id=? ORDER BY user_deck_character_uuid, ordinal`, uid,
|
FROM user_deck_sub_weapons WHERE user_id=? ORDER BY user_deck_character_uuid, ordinal`, uid,
|
||||||
func(rows *sql.Rows) {
|
func(rows *sql.Rows) {
|
||||||
|
|||||||
@@ -171,6 +171,12 @@ func writeUserState(tx *sql.Tx, uid int64, u *store.UserState) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for k, v := range u.TripleDecks {
|
||||||
|
if err := exec(`INSERT INTO user_triple_decks (user_id, deck_type, user_deck_number, name, deck_number01, deck_number02, deck_number03, latest_version) VALUES (?,?,?,?,?,?,?,?)`,
|
||||||
|
uid, int32(k.DeckType), k.UserDeckNumber, v.Name, v.DeckNumber01, v.DeckNumber02, v.DeckNumber03, v.LatestVersion); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
for key, uuids := range u.DeckSubWeapons {
|
for key, uuids := range u.DeckSubWeapons {
|
||||||
for i, uuid := range uuids {
|
for i, uuid := range uuids {
|
||||||
if err := exec(`INSERT INTO user_deck_sub_weapons (user_id, user_deck_character_uuid, ordinal, user_weapon_uuid) VALUES (?,?,?,?)`,
|
if err := exec(`INSERT INTO user_deck_sub_weapons (user_id, user_deck_character_uuid, ordinal, user_weapon_uuid) VALUES (?,?,?,?)`,
|
||||||
@@ -713,6 +719,18 @@ func diffAndSave(tx *sql.Tx, uid int64, before, after *store.UserState) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for k, v := range after.TripleDecks {
|
||||||
|
if old, ok := before.TripleDecks[k]; !ok || old != v {
|
||||||
|
exec(`INSERT OR REPLACE INTO user_triple_decks (user_id, deck_type, user_deck_number, name, deck_number01, deck_number02, deck_number03, latest_version) VALUES (?,?,?,?,?,?,?,?)`,
|
||||||
|
uid, int32(k.DeckType), k.UserDeckNumber, v.Name, v.DeckNumber01, v.DeckNumber02, v.DeckNumber03, v.LatestVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for k := range before.TripleDecks {
|
||||||
|
if _, ok := after.TripleDecks[k]; !ok {
|
||||||
|
exec(`DELETE FROM user_triple_decks WHERE user_id=? AND deck_type=? AND user_deck_number=?`, uid, int32(k.DeckType), k.UserDeckNumber)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
replaceSliceTable(tx, uid, "user_deck_sub_weapons", after.DeckSubWeapons, func(key string, uuids []string) {
|
replaceSliceTable(tx, uid, "user_deck_sub_weapons", after.DeckSubWeapons, func(key string, uuids []string) {
|
||||||
for i, uuid := range uuids {
|
for i, uuid := range uuids {
|
||||||
exec(`INSERT INTO user_deck_sub_weapons (user_id, user_deck_character_uuid, ordinal, user_weapon_uuid) VALUES (?,?,?,?)`, uid, key, i, uuid)
|
exec(`INSERT INTO user_deck_sub_weapons (user_id, user_deck_character_uuid, ordinal, user_weapon_uuid) VALUES (?,?,?,?)`, uid, key, i, uuid)
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ type UserState struct {
|
|||||||
Thoughts map[string]ThoughtState
|
Thoughts map[string]ThoughtState
|
||||||
DeckCharacters map[string]DeckCharacterState
|
DeckCharacters map[string]DeckCharacterState
|
||||||
Decks map[DeckKey]DeckState
|
Decks map[DeckKey]DeckState
|
||||||
|
TripleDecks map[DeckKey]TripleDeckState
|
||||||
Quests map[int32]UserQuestState
|
Quests map[int32]UserQuestState
|
||||||
QuestMissions map[QuestMissionKey]UserQuestMissionState
|
QuestMissions map[QuestMissionKey]UserQuestMissionState
|
||||||
Missions map[int32]UserMissionState
|
Missions map[int32]UserMissionState
|
||||||
@@ -142,6 +143,9 @@ func (u *UserState) EnsureMaps() {
|
|||||||
if u.Decks == nil {
|
if u.Decks == nil {
|
||||||
u.Decks = make(map[DeckKey]DeckState)
|
u.Decks = make(map[DeckKey]DeckState)
|
||||||
}
|
}
|
||||||
|
if u.TripleDecks == nil {
|
||||||
|
u.TripleDecks = make(map[DeckKey]TripleDeckState)
|
||||||
|
}
|
||||||
if u.DeckSubWeapons == nil {
|
if u.DeckSubWeapons == nil {
|
||||||
u.DeckSubWeapons = make(map[string][]string)
|
u.DeckSubWeapons = make(map[string][]string)
|
||||||
}
|
}
|
||||||
@@ -455,6 +459,16 @@ type DeckState struct {
|
|||||||
LatestVersion int64
|
LatestVersion int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TripleDeckState struct {
|
||||||
|
DeckType model.DeckType
|
||||||
|
UserDeckNumber int32
|
||||||
|
Name string
|
||||||
|
DeckNumber01 int32
|
||||||
|
DeckNumber02 int32
|
||||||
|
DeckNumber03 int32
|
||||||
|
LatestVersion int64
|
||||||
|
}
|
||||||
|
|
||||||
type DeckCharacterInput struct {
|
type DeckCharacterInput struct {
|
||||||
UserCostumeUuid string
|
UserCostumeUuid string
|
||||||
MainUserWeaponUuid string
|
MainUserWeaponUuid string
|
||||||
|
|||||||
@@ -188,6 +188,9 @@ func ChangedTables(before, after *store.UserState) []string {
|
|||||||
if !mapsEqualStruct(before.Decks, after.Decks) {
|
if !mapsEqualStruct(before.Decks, after.Decks) {
|
||||||
add("IUserDeck")
|
add("IUserDeck")
|
||||||
}
|
}
|
||||||
|
if !mapsEqualStruct(before.TripleDecks, after.TripleDecks) {
|
||||||
|
add("IUserTripleDeck")
|
||||||
|
}
|
||||||
if !mapsEqualSliceValues(before.DeckSubWeapons, after.DeckSubWeapons) {
|
if !mapsEqualSliceValues(before.DeckSubWeapons, after.DeckSubWeapons) {
|
||||||
add("IUserDeckSubWeaponGroup")
|
add("IUserDeckSubWeaponGroup")
|
||||||
}
|
}
|
||||||
@@ -358,6 +361,8 @@ func keyFieldsForTable(table string) []string {
|
|||||||
return []string{"userId", "userDeckCharacterUuid"}
|
return []string{"userId", "userDeckCharacterUuid"}
|
||||||
case "IUserDeck":
|
case "IUserDeck":
|
||||||
return []string{"userId", "deckType", "userDeckNumber"}
|
return []string{"userId", "deckType", "userDeckNumber"}
|
||||||
|
case "IUserTripleDeck":
|
||||||
|
return []string{"userId", "deckType", "userDeckNumber"}
|
||||||
case "IUserDeckSubWeaponGroup":
|
case "IUserDeckSubWeaponGroup":
|
||||||
return []string{"userId", "userDeckCharacterUuid", "sortOrder"}
|
return []string{"userId", "userDeckCharacterUuid", "sortOrder"}
|
||||||
case "IUserDeckPartsGroup":
|
case "IUserDeckPartsGroup":
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ func init() {
|
|||||||
s, _ := utils.EncodeJSONMaps(sortedDeckRecords(user)...)
|
s, _ := utils.EncodeJSONMaps(sortedDeckRecords(user)...)
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
|
register("IUserTripleDeck", func(user store.UserState) string {
|
||||||
|
s, _ := utils.EncodeJSONMaps(sortedTripleDeckRecords(user)...)
|
||||||
|
return s
|
||||||
|
})
|
||||||
register("IUserDeckCharacter", func(user store.UserState) string {
|
register("IUserDeckCharacter", func(user store.UserState) string {
|
||||||
s, _ := utils.EncodeJSONMaps(sortedDeckCharacterRecords(user)...)
|
s, _ := utils.EncodeJSONMaps(sortedDeckCharacterRecords(user)...)
|
||||||
return s
|
return s
|
||||||
@@ -68,6 +72,35 @@ func sortedDeckRecords(user store.UserState) []map[string]any {
|
|||||||
return records
|
return records
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sortedTripleDeckRecords(user store.UserState) []map[string]any {
|
||||||
|
keys := make([]store.DeckKey, 0, len(user.TripleDecks))
|
||||||
|
for key := range user.TripleDecks {
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
sort.Slice(keys, func(i, j int) bool {
|
||||||
|
if keys[i].DeckType != keys[j].DeckType {
|
||||||
|
return keys[i].DeckType < keys[j].DeckType
|
||||||
|
}
|
||||||
|
return keys[i].UserDeckNumber < keys[j].UserDeckNumber
|
||||||
|
})
|
||||||
|
|
||||||
|
records := make([]map[string]any, 0, len(keys))
|
||||||
|
for _, key := range keys {
|
||||||
|
row := user.TripleDecks[key]
|
||||||
|
records = append(records, map[string]any{
|
||||||
|
"userId": user.UserId,
|
||||||
|
"deckType": int32(row.DeckType),
|
||||||
|
"userDeckNumber": row.UserDeckNumber,
|
||||||
|
"name": row.Name,
|
||||||
|
"deckNumber01": row.DeckNumber01,
|
||||||
|
"deckNumber02": row.DeckNumber02,
|
||||||
|
"deckNumber03": row.DeckNumber03,
|
||||||
|
"latestVersion": row.LatestVersion,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return records
|
||||||
|
}
|
||||||
|
|
||||||
func sortedDeckCharacterRecords(user store.UserState) []map[string]any {
|
func sortedDeckCharacterRecords(user store.UserState) []map[string]any {
|
||||||
keys := sortedStringKeys(user.DeckCharacters)
|
keys := sortedStringKeys(user.DeckCharacters)
|
||||||
records := make([]map[string]any, 0, len(keys))
|
records := make([]map[string]any, 0, len(keys))
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ func FullClientTableMap(user store.UserState) map[string]string {
|
|||||||
"IUserThought": projectTable("IUserThought", user),
|
"IUserThought": projectTable("IUserThought", user),
|
||||||
"IUserDeckCharacter": projectTable("IUserDeckCharacter", user),
|
"IUserDeckCharacter": projectTable("IUserDeckCharacter", user),
|
||||||
"IUserDeck": projectTable("IUserDeck", user),
|
"IUserDeck": projectTable("IUserDeck", user),
|
||||||
|
"IUserTripleDeck": projectTable("IUserTripleDeck", user),
|
||||||
"IUserLogin": projectTable("IUserLogin", user),
|
"IUserLogin": projectTable("IUserLogin", user),
|
||||||
"IUserLoginBonus": projectTable("IUserLoginBonus", user),
|
"IUserLoginBonus": projectTable("IUserLoginBonus", user),
|
||||||
"IUserMission": projectTable("IUserMission", user),
|
"IUserMission": projectTable("IUserMission", user),
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
-- +goose Up
|
||||||
|
CREATE TABLE user_triple_decks (
|
||||||
|
user_id INTEGER NOT NULL REFERENCES users(user_id),
|
||||||
|
deck_type INTEGER NOT NULL,
|
||||||
|
user_deck_number INTEGER NOT NULL,
|
||||||
|
name TEXT NOT NULL DEFAULT '',
|
||||||
|
deck_number01 INTEGER NOT NULL DEFAULT 0,
|
||||||
|
deck_number02 INTEGER NOT NULL DEFAULT 0,
|
||||||
|
deck_number03 INTEGER NOT NULL DEFAULT 0,
|
||||||
|
latest_version INTEGER NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY (user_id, deck_type, user_deck_number)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Legacy BigHunt wave-decks have no preset wrapper rows and aren't reachable
|
||||||
|
-- via the new IUserTripleDeck projection. Drop them so users start clean and
|
||||||
|
-- repopulate via ReplaceTripleDeck from the client.
|
||||||
|
DELETE FROM user_decks WHERE deck_type = 5;
|
||||||
|
|
||||||
|
-- +goose Down
|
||||||
|
DROP TABLE IF EXISTS user_triple_decks;
|
||||||
Reference in New Issue
Block a user