Add SQLite persistence, import-snapshot tool, and karma functionality

This commit is contained in:
Ilya Groshev
2026-04-20 09:57:47 +03:00
parent c9ad3fa4f4
commit c33e738fd5
70 changed files with 4151 additions and 833 deletions
+4 -4
View File
@@ -11,15 +11,15 @@ import (
type BannerServiceServer struct {
pb.UnimplementedBannerServiceServer
gacha store.GachaRepository
catalog []store.GachaCatalogEntry
}
func NewBannerServiceServer(gacha store.GachaRepository) *BannerServiceServer {
return &BannerServiceServer{gacha: gacha}
func NewBannerServiceServer(catalog []store.GachaCatalogEntry) *BannerServiceServer {
return &BannerServiceServer{catalog: catalog}
}
func (s *BannerServiceServer) GetMamaBanner(ctx context.Context, req *pb.GetMamaBannerRequest) (*pb.GetMamaBannerResponse, error) {
catalog, _ := s.gacha.SnapshotCatalog()
catalog := s.catalog
var termLimited []*pb.GachaBanner
var latestChapter *pb.GachaBanner
for _, entry := range catalog {
+2 -4
View File
@@ -43,8 +43,7 @@ func (s *CageOrnamentServiceServer) ReceiveReward(ctx context.Context, req *pb.R
s.granter.GrantFull(user, model.PossessionType(reward.PossessionType), reward.PossessionId, reward.Count, nowMillis)
})
diff := userdata.BuildDiffFromTables(userdata.SelectTables(
userdata.FullClientTableMap(user),
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(user,
[]string{
"IUserMaterial", "IUserConsumableItem", "IUserGem",
"IUserCostume", "IUserCostumeActiveSkill", "IUserCharacter",
@@ -82,8 +81,7 @@ func (s *CageOrnamentServiceServer) RecordAccess(ctx context.Context, req *pb.Re
}
})
diff := userdata.BuildDiffFromTables(userdata.SelectTables(
userdata.FullClientTableMap(user),
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(user,
[]string{"IUserCageOrnamentReward"},
))
+2 -2
View File
@@ -35,7 +35,7 @@ func (s *CharacterServiceServer) Rebirth(ctx context.Context, req *pb.RebirthReq
return &pb.RebirthResponse{}, nil
}
oldUser, _ := s.users.SnapshotUser(userId)
oldUser, _ := s.users.LoadUser(userId)
tracker := userdata.NewDeleteTracker().
Track("IUserMaterial", oldUser, userdata.SortedMaterialRecords, []string{"userId", "materialId"})
@@ -78,7 +78,7 @@ func (s *CharacterServiceServer) Rebirth(ctx context.Context, req *pb.RebirthReq
}
rebirthTables := []string{"IUserCharacterRebirth", "IUserMaterial", "IUserConsumableItem"}
tables := userdata.SelectTables(userdata.FullClientTableMap(snapshot), rebirthTables)
tables := userdata.ProjectTables(snapshot, rebirthTables)
diff := tracker.Apply(snapshot, tables)
return &pb.RebirthResponse{DiffUserData: diff}, nil
+2 -2
View File
@@ -27,7 +27,7 @@ func (s *CharacterBoardServiceServer) ReleasePanel(ctx context.Context, req *pb.
userId := currentUserId(ctx, s.users, s.sessions)
oldUser, _ := s.users.SnapshotUser(userId)
oldUser, _ := s.users.LoadUser(userId)
tracker := userdata.NewDeleteTracker().
Track("IUserMaterial", oldUser, userdata.SortedMaterialRecords, []string{"userId", "materialId"}).
Track("IUserConsumableItem", oldUser, userdata.SortedConsumableItemRecords, []string{"userId", "consumableItemId"})
@@ -54,7 +54,7 @@ func (s *CharacterBoardServiceServer) ReleasePanel(ctx context.Context, req *pb.
"IUserConsumableItem",
"IUserGem",
}
tables := userdata.SelectTables(userdata.FullClientTableMap(user), boardTables)
tables := userdata.ProjectTables(user, boardTables)
diff := tracker.Apply(user, tables)
return &pb.ReleasePanelResponse{DiffUserData: diff}, nil
+1 -1
View File
@@ -29,7 +29,7 @@ func (s *CharacterViewerServiceServer) CharacterViewerTop(ctx context.Context, _
log.Printf("[CharacterViewerService] CharacterViewerTop")
userId := currentUserId(ctx, s.users, s.sessions)
user, err := s.users.SnapshotUser(userId)
user, err := s.users.LoadUser(userId)
if err != nil {
panic(fmt.Sprintf("CharacterViewerTop: no user for userId=%d: %v", userId, err))
}
+1 -2
View File
@@ -77,8 +77,7 @@ func (s *CompanionServiceServer) Enhance(ctx context.Context, req *pb.CompanionE
return nil, fmt.Errorf("companion enhance: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, companionDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, companionDiffTables))
return &pb.CompanionEnhanceResponse{
DiffUserData: diff,
+2 -2
View File
@@ -28,7 +28,7 @@ func (s *ConsumableItemServiceServer) Sell(ctx context.Context, req *pb.Consumab
userId := currentUserId(ctx, s.users, s.sessions)
oldUser, _ := s.users.SnapshotUser(userId)
oldUser, _ := s.users.LoadUser(userId)
tracker := userdata.NewDeleteTracker().
Track("IUserConsumableItem", oldUser, userdata.SortedConsumableItemRecords, []string{"userId", "consumableItemId"})
@@ -66,7 +66,7 @@ func (s *ConsumableItemServiceServer) Sell(ctx context.Context, req *pb.Consumab
return nil, fmt.Errorf("consumable item sell: %w", err)
}
tables := userdata.SelectTables(userdata.FullClientTableMap(snapshot), []string{"IUserConsumableItem"})
tables := userdata.ProjectTables(snapshot, []string{"IUserConsumableItem"})
diff := tracker.Apply(snapshot, tables)
return &pb.ConsumableItemSellResponse{
+1 -2
View File
@@ -34,8 +34,7 @@ func (s *ContentsStoryServiceServer) RegisterPlayed(ctx context.Context, req *pb
return nil, fmt.Errorf("update user: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, []string{"IUserContentsStory"}))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, []string{"IUserContentsStory"}))
return &pb.ContentsStoryRegisterPlayedResponse{
DiffUserData: diff,
+219 -11
View File
@@ -4,6 +4,9 @@ import (
"context"
"fmt"
"log"
"math/rand"
"github.com/google/uuid"
pb "lunar-tear/server/gen/proto"
"lunar-tear/server/internal/gametime"
@@ -95,8 +98,7 @@ func (s *CostumeServiceServer) Enhance(ctx context.Context, req *pb.EnhanceReque
return nil, fmt.Errorf("costume enhance: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, costumeDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, costumeDiffTables))
return &pb.EnhanceResponse{
IsGreatSuccess: false,
@@ -177,8 +179,7 @@ func (s *CostumeServiceServer) Awaken(ctx context.Context, req *pb.AwakenRequest
return nil, fmt.Errorf("costume awaken: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, awakenDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, awakenDiffTables))
return &pb.AwakenResponse{
DiffUserData: diff,
@@ -229,10 +230,12 @@ func (s *CostumeServiceServer) applyAwakenItemAcquire(user *store.UserState, ite
return
}
key := fmt.Sprintf("awaken-thought-%d", acq.PossessionId)
if _, exists := user.Thoughts[key]; exists {
return
for _, t := range user.Thoughts {
if t.ThoughtId == acq.PossessionId {
return
}
}
key := uuid.New().String()
user.Thoughts[key] = store.ThoughtState{
UserThoughtUuid: key,
ThoughtId: acq.PossessionId,
@@ -329,8 +332,7 @@ func (s *CostumeServiceServer) EnhanceActiveSkill(ctx context.Context, req *pb.E
return nil, fmt.Errorf("costume enhance active skill: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, activeSkillDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, activeSkillDiffTables))
return &pb.EnhanceActiveSkillResponse{
DiffUserData: diff,
@@ -387,10 +389,216 @@ func (s *CostumeServiceServer) LimitBreak(ctx context.Context, req *pb.LimitBrea
return nil, fmt.Errorf("costume limit break: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, costumeDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, costumeDiffTables))
return &pb.LimitBreakResponse{
DiffUserData: diff,
}, nil
}
var lotteryEffectDiffTables = []string{
"IUserCostume",
"IUserCostumeLotteryEffect",
"IUserCostumeLotteryEffectAbility",
"IUserCostumeLotteryEffectStatusUp",
"IUserCostumeLotteryEffectPending",
"IUserConsumableItem",
"IUserMaterial",
}
func (s *CostumeServiceServer) UnlockLotteryEffectSlot(ctx context.Context, req *pb.UnlockLotteryEffectSlotRequest) (*pb.UnlockLotteryEffectSlotResponse, error) {
log.Printf("[CostumeService] UnlockLotteryEffectSlot: uuid=%s slot=%d", req.UserCostumeUuid, req.SlotNumber)
userId := currentUserId(ctx, s.users, s.sessions)
nowMillis := gametime.NowMillis()
snapshot, err := s.users.UpdateUser(userId, func(user *store.UserState) {
costume, ok := user.Costumes[req.UserCostumeUuid]
if !ok {
log.Printf("[CostumeService] UnlockLotteryEffectSlot: costume uuid=%s not found", req.UserCostumeUuid)
return
}
effectRow, ok := s.catalog.LotteryEffects[[2]int32{costume.CostumeId, req.SlotNumber}]
if !ok {
log.Printf("[CostumeService] UnlockLotteryEffectSlot: no lottery effect for costumeId=%d slot=%d", costume.CostumeId, req.SlotNumber)
return
}
user.ConsumableItems[s.config.ConsumableItemIdForGold] -= s.config.CostumeLotteryEffectUnlockSlotConsumeGold
mats := s.catalog.LotteryEffectMats[effectRow.CostumeLotteryEffectUnlockMaterialGroupId]
for _, mat := range mats {
cur := user.Materials[mat.MaterialId]
cost := mat.Count
if cur < cost {
log.Printf("[CostumeService] UnlockLotteryEffectSlot: insufficient material id=%d have=%d need=%d", mat.MaterialId, cur, cost)
cost = cur
}
user.Materials[mat.MaterialId] = cur - cost
}
key := store.CostumeLotteryEffectKey{
UserCostumeUuid: req.UserCostumeUuid,
SlotNumber: req.SlotNumber,
}
user.CostumeLotteryEffects[key] = store.CostumeLotteryEffectState{
UserCostumeUuid: req.UserCostumeUuid,
SlotNumber: req.SlotNumber,
OddsNumber: 0,
LatestVersion: nowMillis,
}
costume.CostumeLotteryEffectUnlockedSlotCount++
costume.LatestVersion = nowMillis
user.Costumes[req.UserCostumeUuid] = costume
log.Printf("[CostumeService] UnlockLotteryEffectSlot: costumeId=%d slot=%d unlocked slotCount=%d", costume.CostumeId, req.SlotNumber, costume.CostumeLotteryEffectUnlockedSlotCount)
})
if err != nil {
return nil, fmt.Errorf("costume unlock lottery effect slot: %w", err)
}
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, lotteryEffectDiffTables))
return &pb.UnlockLotteryEffectSlotResponse{
DiffUserData: diff,
}, nil
}
func (s *CostumeServiceServer) DrawLotteryEffect(ctx context.Context, req *pb.DrawLotteryEffectRequest) (*pb.DrawLotteryEffectResponse, error) {
log.Printf("[CostumeService] DrawLotteryEffect: uuid=%s slot=%d", req.UserCostumeUuid, req.SlotNumber)
userId := currentUserId(ctx, s.users, s.sessions)
nowMillis := gametime.NowMillis()
oldUser, _ := s.users.LoadUser(userId)
tracker := userdata.NewDeleteTracker().
Track("IUserMaterial", oldUser, userdata.SortedMaterialRecords, []string{"userId", "materialId"}).
Track("IUserConsumableItem", oldUser, userdata.SortedConsumableItemRecords, []string{"userId", "consumableItemId"}).
Track("IUserCostumeLotteryEffectPending", oldUser, userdata.SortedCostumeLotteryEffectPendingRecords, []string{"userId", "userCostumeUuid"})
snapshot, err := s.users.UpdateUser(userId, func(user *store.UserState) {
costume, ok := user.Costumes[req.UserCostumeUuid]
if !ok {
log.Printf("[CostumeService] DrawLotteryEffect: costume uuid=%s not found", req.UserCostumeUuid)
return
}
effectRow, ok := s.catalog.LotteryEffects[[2]int32{costume.CostumeId, req.SlotNumber}]
if !ok {
log.Printf("[CostumeService] DrawLotteryEffect: no lottery effect for costumeId=%d slot=%d", costume.CostumeId, req.SlotNumber)
return
}
oddsPool := s.catalog.LotteryEffectOdds[effectRow.CostumeLotteryEffectOddsGroupId]
if len(oddsPool) == 0 {
log.Printf("[CostumeService] DrawLotteryEffect: empty odds pool for groupId=%d", effectRow.CostumeLotteryEffectOddsGroupId)
return
}
user.ConsumableItems[s.config.ConsumableItemIdForGold] -= s.config.CostumeLotteryEffectDrawSlotConsumeGold
mats := s.catalog.LotteryEffectMats[effectRow.CostumeLotteryEffectDrawMaterialGroupId]
for _, mat := range mats {
cur := user.Materials[mat.MaterialId]
cost := mat.Count
if cur < cost {
log.Printf("[CostumeService] DrawLotteryEffect: insufficient material id=%d have=%d need=%d", mat.MaterialId, cur, cost)
cost = cur
}
user.Materials[mat.MaterialId] = cur - cost
}
totalWeight := int32(0)
for _, row := range oddsPool {
totalWeight += row.Weight
}
roll := rand.Int31n(totalWeight)
var picked masterdata.CostumeLotteryEffectOddsRow
for _, row := range oddsPool {
roll -= row.Weight
if roll < 0 {
picked = row
break
}
}
key := store.CostumeLotteryEffectKey{
UserCostumeUuid: req.UserCostumeUuid,
SlotNumber: req.SlotNumber,
}
existing := user.CostumeLotteryEffects[key]
if existing.OddsNumber == 0 {
existing.UserCostumeUuid = req.UserCostumeUuid
existing.SlotNumber = req.SlotNumber
existing.OddsNumber = picked.OddsNumber
existing.LatestVersion = nowMillis
user.CostumeLotteryEffects[key] = existing
} else {
user.CostumeLotteryEffectPending[req.UserCostumeUuid] = store.CostumeLotteryEffectPendingState{
UserCostumeUuid: req.UserCostumeUuid,
SlotNumber: req.SlotNumber,
OddsNumber: picked.OddsNumber,
LatestVersion: nowMillis,
}
}
log.Printf("[CostumeService] DrawLotteryEffect: costumeId=%d slot=%d drew oddsNumber=%d type=%d targetId=%d firstDraw=%v",
costume.CostumeId, req.SlotNumber, picked.OddsNumber, picked.CostumeLotteryEffectType, picked.CostumeLotteryEffectTargetId, existing.OddsNumber == 0)
})
if err != nil {
return nil, fmt.Errorf("costume draw lottery effect: %w", err)
}
diff := tracker.Apply(snapshot, userdata.ProjectTables(snapshot, lotteryEffectDiffTables))
return &pb.DrawLotteryEffectResponse{
DiffUserData: diff,
}, nil
}
func (s *CostumeServiceServer) ConfirmLotteryEffect(ctx context.Context, req *pb.ConfirmLotteryEffectRequest) (*pb.ConfirmLotteryEffectResponse, error) {
log.Printf("[CostumeService] ConfirmLotteryEffect: uuid=%s accept=%v", req.UserCostumeUuid, req.IsAccept)
userId := currentUserId(ctx, s.users, s.sessions)
nowMillis := gametime.NowMillis()
oldUser, _ := s.users.LoadUser(userId)
tracker := userdata.NewDeleteTracker().
Track("IUserCostumeLotteryEffectPending", oldUser, userdata.SortedCostumeLotteryEffectPendingRecords, []string{"userId", "userCostumeUuid"})
snapshot, err := s.users.UpdateUser(userId, func(user *store.UserState) {
pending, ok := user.CostumeLotteryEffectPending[req.UserCostumeUuid]
if !ok {
log.Printf("[CostumeService] ConfirmLotteryEffect: no pending for uuid=%s", req.UserCostumeUuid)
return
}
if req.IsAccept {
key := store.CostumeLotteryEffectKey{
UserCostumeUuid: pending.UserCostumeUuid,
SlotNumber: pending.SlotNumber,
}
effect := user.CostumeLotteryEffects[key]
effect.UserCostumeUuid = pending.UserCostumeUuid
effect.SlotNumber = pending.SlotNumber
effect.OddsNumber = pending.OddsNumber
effect.LatestVersion = nowMillis
user.CostumeLotteryEffects[key] = effect
log.Printf("[CostumeService] ConfirmLotteryEffect: accepted oddsNumber=%d for slot=%d", pending.OddsNumber, pending.SlotNumber)
} else {
log.Printf("[CostumeService] ConfirmLotteryEffect: rejected oddsNumber=%d for slot=%d", pending.OddsNumber, pending.SlotNumber)
}
delete(user.CostumeLotteryEffectPending, req.UserCostumeUuid)
})
if err != nil {
return nil, fmt.Errorf("costume confirm lottery effect: %w", err)
}
diff := tracker.Apply(snapshot, userdata.ProjectTables(snapshot, lotteryEffectDiffTables))
return &pb.ConfirmLotteryEffectResponse{
DiffUserData: diff,
}, nil
}
+2 -2
View File
@@ -42,12 +42,12 @@ func (s *DataServiceServer) GetUserData(ctx context.Context, req *pb.UserDataGet
log.Printf("[DataService] GetUserData: tables=%v", req.TableName)
userId := currentUserId(ctx, s.users, s.sessions)
user, err := s.users.SnapshotUser(userId)
user, err := s.users.LoadUser(userId)
if err != nil {
return nil, fmt.Errorf("snapshot user: %w", err)
}
defaults := userdata.FirstEntranceClientTableMap(user)
defaults := userdata.FullClientTableMap(user)
result := userdata.SelectTables(defaults, req.TableName)
return &pb.UserDataGetResponse{
UserDataJson: result,
+7 -7
View File
@@ -32,7 +32,7 @@ func (s *DeckServiceServer) UpdateName(ctx context.Context, req *pb.UpdateNameRe
user.Decks[deckKey] = deck
})
result := userdata.SelectTables(userdata.FullClientTableMap(user), []string{"IUserDeck"})
result := userdata.ProjectTables(user, []string{"IUserDeck"})
return &pb.UpdateNameResponse{
DiffUserData: userdata.BuildDiffFromTables(result),
}, nil
@@ -81,7 +81,7 @@ func (s *DeckServiceServer) RefreshDeckPower(ctx context.Context, req *pb.Refres
}
})
result := userdata.SelectTables(userdata.FullClientTableMap(user), []string{
result := userdata.ProjectTables(user, []string{
"IUserDeck", "IUserDeckCharacter", "IUserDeckTypeNote",
})
return &pb.RefreshDeckPowerResponse{
@@ -133,7 +133,7 @@ func (s *DeckServiceServer) RefreshMultiDeckPower(ctx context.Context, req *pb.R
}
})
result := userdata.SelectTables(userdata.FullClientTableMap(user), []string{
result := userdata.ProjectTables(user, []string{
"IUserDeck", "IUserDeckCharacter", "IUserDeckTypeNote",
})
return &pb.RefreshMultiDeckPowerResponse{
@@ -173,7 +173,7 @@ func (s *DeckServiceServer) ReplaceDeck(ctx context.Context, req *pb.ReplaceDeck
}
userId := currentUserId(ctx, s.users, s.sessions)
oldUser, _ := s.users.SnapshotUser(userId)
oldUser, _ := s.users.LoadUser(userId)
tracker := userdata.NewDeleteTracker().
Track("IUserDeckSubWeaponGroup", oldUser, userdata.DeckSubWeaponRecords,
[]string{"userId", "userDeckCharacterUuid", "userWeaponUuid"}).
@@ -189,7 +189,7 @@ func (s *DeckServiceServer) ReplaceDeck(ctx context.Context, req *pb.ReplaceDeck
store.ApplyDeckReplacement(user, model.DeckType(req.DeckType), req.UserDeckNumber, deckSlotsFromProto(req.Deck), gametime.NowMillis())
})
result := userdata.SelectTables(userdata.FullClientTableMap(user), []string{
result := userdata.ProjectTables(user, []string{
"IUserDeck", "IUserDeckCharacter", "IUserDeckSubWeaponGroup", "IUserDeckPartsGroup",
"IUserDeckCharacterDressupCostume",
})
@@ -202,7 +202,7 @@ func (s *DeckServiceServer) ReplaceTripleDeck(ctx context.Context, req *pb.Repla
log.Printf("[DeckService] ReplaceTripleDeck: deckType=%d deckNumber=%d", req.DeckType, req.UserDeckNumber)
userId := currentUserId(ctx, s.users, s.sessions)
oldUser, _ := s.users.SnapshotUser(userId)
oldUser, _ := s.users.LoadUser(userId)
tracker := userdata.NewDeleteTracker().
Track("IUserDeckSubWeaponGroup", oldUser, userdata.DeckSubWeaponRecords,
[]string{"userId", "userDeckCharacterUuid", "userWeaponUuid"}).
@@ -231,7 +231,7 @@ func (s *DeckServiceServer) ReplaceTripleDeck(ctx context.Context, req *pb.Repla
}
})
result := userdata.SelectTables(userdata.FullClientTableMap(user), []string{
result := userdata.ProjectTables(user, []string{
"IUserDeck", "IUserDeckCharacter", "IUserDeckSubWeaponGroup", "IUserDeckPartsGroup",
"IUserDeckCharacterDressupCostume",
})
+1 -2
View File
@@ -33,8 +33,7 @@ func (s *DokanServiceServer) RegisterDokanConfirmed(ctx context.Context, req *pb
return nil, fmt.Errorf("update user: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, []string{"IUserDokan"}))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, []string{"IUserDokan"}))
return &pb.RegisterDokanConfirmedResponse{
DiffUserData: diff,
+3 -6
View File
@@ -71,8 +71,7 @@ func (s *ExploreServiceServer) StartExplore(ctx context.Context, req *pb.StartEx
return nil, fmt.Errorf("start explore: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, exploreDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, exploreDiffTables))
return &pb.StartExploreResponse{
DiffUserData: diff,
@@ -124,8 +123,7 @@ func (s *ExploreServiceServer) FinishExplore(ctx context.Context, req *pb.Finish
return nil, fmt.Errorf("finish explore: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, exploreFinishDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, exploreFinishDiffTables))
rewards := []*pb.ExploreReward{
{
@@ -161,8 +159,7 @@ func (s *ExploreServiceServer) RetireExplore(ctx context.Context, req *pb.Retire
return nil, fmt.Errorf("retire explore: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, []string{"IUserExplore"}))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, []string{"IUserExplore"}))
return &pb.RetireExploreResponse{
DiffUserData: diff,
+10 -13
View File
@@ -34,20 +34,20 @@ type GachaServiceServer struct {
pb.UnimplementedGachaServiceServer
users store.UserRepository
sessions store.SessionRepository
gacha store.GachaRepository
catalog []store.GachaCatalogEntry
handler *gacha.GachaHandler
}
func NewGachaServiceServer(
users store.UserRepository,
sessions store.SessionRepository,
gachaRepo store.GachaRepository,
catalog []store.GachaCatalogEntry,
handler *gacha.GachaHandler,
) *GachaServiceServer {
return &GachaServiceServer{
users: users,
sessions: sessions,
gacha: gachaRepo,
catalog: catalog,
handler: handler,
}
}
@@ -55,7 +55,7 @@ func NewGachaServiceServer(
func (s *GachaServiceServer) GetGachaList(ctx context.Context, req *pb.GetGachaListRequest) (*pb.GetGachaListResponse, error) {
log.Printf("[GachaService] GetGachaList: labels=%v", req.GachaLabelType)
catalog, _ := s.gacha.SnapshotCatalog()
catalog := s.catalog
userId := currentUserId(ctx, s.users, s.sessions)
nowMillis := gametime.NowMillis()
@@ -132,10 +132,10 @@ func (s *GachaServiceServer) autoConvertExpiredMedals(user *store.UserState, cat
func (s *GachaServiceServer) GetGacha(ctx context.Context, req *pb.GetGachaRequest) (*pb.GetGachaResponse, error) {
log.Printf("[GachaService] GetGacha: ids=%v", req.GachaId)
catalog, _ := s.gacha.SnapshotCatalog()
catalog := s.catalog
userId := currentUserId(ctx, s.users, s.sessions)
user, err := s.users.SnapshotUser(userId)
user, err := s.users.LoadUser(userId)
if err != nil {
return nil, fmt.Errorf("snapshot user: %w", err)
}
@@ -160,8 +160,7 @@ func (s *GachaServiceServer) GetGacha(ctx context.Context, req *pb.GetGachaReque
func (s *GachaServiceServer) Draw(ctx context.Context, req *pb.DrawRequest) (*pb.DrawResponse, error) {
log.Printf("[GachaService] Draw: gachaId=%d phaseId=%d execCount=%d", req.GachaId, req.GachaPricePhaseId, req.ExecCount)
catalog, _ := s.gacha.SnapshotCatalog()
entry := findCatalogEntry(catalog, req.GachaId)
entry := findCatalogEntry(s.catalog, req.GachaId)
if entry == nil {
return nil, fmt.Errorf("gacha %d not found", req.GachaId)
}
@@ -293,8 +292,7 @@ func (s *GachaServiceServer) Draw(ctx context.Context, req *pb.DrawRequest) (*pb
changedStoryIds := s.handler.Granter.DrainChangedStoryWeaponIds()
diffOrder := append(gachaDiffTables, "IUserWeaponStory")
allTables := userdata.FullClientTableMap(updatedUser)
diff := userdata.BuildDiffFromTablesOrdered(userdata.SelectTables(allTables, diffOrder), diffOrder)
diff := userdata.BuildDiffFromTablesOrdered(userdata.ProjectTables(updatedUser, diffOrder), diffOrder)
userdata.AddWeaponStoryDiff(diff, updatedUser, changedStoryIds)
return &pb.DrawResponse{
@@ -309,8 +307,7 @@ func (s *GachaServiceServer) Draw(ctx context.Context, req *pb.DrawRequest) (*pb
func (s *GachaServiceServer) ResetBoxGacha(ctx context.Context, req *pb.ResetBoxGachaRequest) (*pb.ResetBoxGachaResponse, error) {
log.Printf("[GachaService] ResetBoxGacha: gachaId=%d", req.GachaId)
catalog, _ := s.gacha.SnapshotCatalog()
entry := findCatalogEntry(catalog, req.GachaId)
entry := findCatalogEntry(s.catalog, req.GachaId)
if entry == nil {
return nil, fmt.Errorf("gacha %d not found", req.GachaId)
}
@@ -336,7 +333,7 @@ func (s *GachaServiceServer) ResetBoxGacha(ctx context.Context, req *pb.ResetBox
func (s *GachaServiceServer) GetRewardGacha(ctx context.Context, req *emptypb.Empty) (*pb.GetRewardGachaResponse, error) {
log.Printf("[GachaService] GetRewardGacha")
userId := currentUserId(ctx, s.users, s.sessions)
user, err := s.users.SnapshotUser(userId)
user, err := s.users.LoadUser(userId)
if err != nil {
return nil, fmt.Errorf("snapshot user: %w", err)
}
+2 -2
View File
@@ -71,7 +71,7 @@ func (s *GiftServiceServer) GetGiftList(ctx context.Context, req *pb.GetGiftList
req.RewardKindType, req.ExpirationType, req.IsAscendingSort, req.NextCursor, req.PreviousCursor, req.GetCount)
userId := currentUserId(ctx, s.users, s.sessions)
user, err := s.users.SnapshotUser(userId)
user, err := s.users.LoadUser(userId)
if err != nil {
return nil, fmt.Errorf("snapshot user: %w", err)
}
@@ -108,7 +108,7 @@ func (s *GiftServiceServer) GetGiftList(ctx context.Context, req *pb.GetGiftList
func (s *GiftServiceServer) GetGiftReceiveHistoryList(ctx context.Context, req *emptypb.Empty) (*pb.GetGiftReceiveHistoryListResponse, error) {
log.Printf("[GiftService] GetGiftReceiveHistoryList")
userId := currentUserId(ctx, s.users, s.sessions)
user, err := s.users.SnapshotUser(userId)
user, err := s.users.LoadUser(userId)
if err != nil {
return nil, fmt.Errorf("snapshot user: %w", err)
}
+4 -4
View File
@@ -38,7 +38,7 @@ func (s *GimmickServiceServer) UpdateSequence(ctx context.Context, req *pb.Updat
user.Gimmick.Sequences[key] = sequence
})
return &pb.UpdateSequenceResponse{
DiffUserData: userdata.BuildDiffFromTables(userdata.SelectTables(userdata.FullClientTableMap(user), []string{"IUserGimmickSequence"})),
DiffUserData: userdata.BuildDiffFromTables(userdata.ProjectTables(user, []string{"IUserGimmickSequence"})),
}, nil
}
@@ -74,7 +74,7 @@ func (s *GimmickServiceServer) UpdateGimmickProgress(ctx context.Context, req *p
GimmickOrnamentReward: []*pb.GimmickReward{},
IsSequenceCleared: false,
GimmickSequenceClearReward: []*pb.GimmickReward{},
DiffUserData: userdata.BuildDiffFromTables(userdata.SelectTables(userdata.FullClientTableMap(user), []string{
DiffUserData: userdata.BuildDiffFromTables(userdata.ProjectTables(user, []string{
"IUserGimmick",
"IUserGimmickOrnamentProgress",
})),
@@ -98,7 +98,7 @@ func (s *GimmickServiceServer) InitSequenceSchedule(ctx context.Context, _ *empt
}
})
return &pb.InitSequenceScheduleResponse{
DiffUserData: userdata.BuildDiffFromTables(userdata.SelectTables(userdata.FullClientTableMap(user), gimmickDiffTables)),
DiffUserData: userdata.BuildDiffFromTables(userdata.ProjectTables(user, gimmickDiffTables)),
}, nil
}
@@ -119,6 +119,6 @@ func (s *GimmickServiceServer) Unlock(ctx context.Context, req *pb.UnlockRequest
}
})
return &pb.UnlockResponse{
DiffUserData: userdata.BuildDiffFromTables(userdata.SelectTables(userdata.FullClientTableMap(user), []string{"IUserGimmickUnlock"})),
DiffUserData: userdata.BuildDiffFromTables(userdata.ProjectTables(user, []string{"IUserGimmickUnlock"})),
}, nil
}
+1 -1
View File
@@ -495,4 +495,4 @@ func objectIdToFilePathCandidates(revision, assetType, objectId string) (candida
}
}
return candidates, entry.Size, true
}
}
+4 -4
View File
@@ -2,10 +2,11 @@ package service
import (
"context"
"fmt"
"log"
"time"
"github.com/google/uuid"
pb "lunar-tear/server/gen/proto"
"lunar-tear/server/internal/gametime"
"lunar-tear/server/internal/masterdata"
@@ -55,7 +56,7 @@ func (s *LoginBonusServiceServer) ReceiveStamp(ctx context.Context, req *emptypb
GrantDatetime: now,
},
ExpirationDatetime: now + int64(30*24*time.Hour/time.Millisecond),
UserGiftUuid: fmt.Sprintf("login-bonus-%d-%d", userId, nextStamp),
UserGiftUuid: uuid.New().String(),
})
user.Notifications.GiftNotReceiveCount = int32(len(user.Gifts.NotReceived))
user.LoginBonus.CurrentStampNumber = nextStamp
@@ -63,8 +64,7 @@ func (s *LoginBonusServiceServer) ReceiveStamp(ctx context.Context, req *emptypb
user.LoginBonus.LatestVersion = now
})
diff := userdata.BuildDiffFromTables(userdata.SelectTables(
userdata.FullClientTableMap(user),
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(user,
[]string{"IUserLoginBonus"},
))
setCommonResponseTrailers(ctx, diff, false)
+2 -2
View File
@@ -33,7 +33,7 @@ func (s *MaterialServiceServer) Sell(ctx context.Context, req *pb.MaterialSellRe
userId := currentUserId(ctx, s.users, s.sessions)
oldUser, _ := s.users.SnapshotUser(userId)
oldUser, _ := s.users.LoadUser(userId)
tracker := userdata.NewDeleteTracker().
Track("IUserMaterial", oldUser, userdata.SortedMaterialRecords, []string{"userId", "materialId"})
@@ -71,7 +71,7 @@ func (s *MaterialServiceServer) Sell(ctx context.Context, req *pb.MaterialSellRe
return nil, fmt.Errorf("material sell: %w", err)
}
tables := userdata.SelectTables(userdata.FullClientTableMap(snapshot), materialDiffTables)
tables := userdata.ProjectTables(snapshot, materialDiffTables)
diff := tracker.Apply(snapshot, tables)
return &pb.MaterialSellResponse{
+2 -3
View File
@@ -24,13 +24,12 @@ func (s *MissionServiceServer) UpdateMissionProgress(ctx context.Context, req *p
log.Printf("[MissionService] UpdateMissionProgress: cage=%v pictureBook=%v", req.CageMeasurableValues, req.PictureBookMeasurableValues)
userId := currentUserId(ctx, s.users, s.sessions)
snapshot, err := s.users.SnapshotUser(userId)
snapshot, err := s.users.LoadUser(userId)
if err != nil {
return nil, fmt.Errorf("snapshot user: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, []string{"IUserMission"}))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, []string{"IUserMission"}))
return &pb.UpdateMissionProgressResponse{
DiffUserData: diff,
+1 -2
View File
@@ -36,8 +36,7 @@ func (s *MovieServiceServer) SaveViewedMovie(ctx context.Context, req *pb.SaveVi
return nil, fmt.Errorf("update user: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, []string{"IUserMovie"}))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, []string{"IUserMovie"}))
return &pb.SaveViewedMovieResponse{
DiffUserData: diff,
+1 -2
View File
@@ -31,8 +31,7 @@ func (s *NaviCutInServiceServer) RegisterPlayed(ctx context.Context, req *pb.Reg
return nil, fmt.Errorf("update user: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, []string{"IUserNaviCutIn"}))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, []string{"IUserNaviCutIn"}))
return &pb.RegisterPlayedResponse{
DiffUserData: diff,
+1 -1
View File
@@ -24,7 +24,7 @@ func NewNotificationServiceServer(users store.UserRepository, sessions store.Ses
func (s *NotificationServiceServer) GetHeaderNotification(ctx context.Context, req *emptypb.Empty) (*pb.GetHeaderNotificationResponse, error) {
log.Printf("[NotificationService] GetHeaderNotification")
userId := currentUserId(ctx, s.users, s.sessions)
user, err := s.users.SnapshotUser(userId)
user, err := s.users.LoadUser(userId)
if err != nil {
return &pb.GetHeaderNotificationResponse{
GiftNotReceiveCount: 0,
+1 -2
View File
@@ -36,8 +36,7 @@ func (s *OmikujiServiceServer) OmikujiDraw(ctx context.Context, req *pb.OmikujiD
return nil, fmt.Errorf("update user: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, []string{"IUserOmikuji"}))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, []string{"IUserOmikuji"}))
return &pb.OmikujiDrawResponse{
OmikujiResultAssetId: s.catalog.LookupAssetId(req.OmikujiId),
+4 -6
View File
@@ -37,7 +37,7 @@ func (s *PartsServiceServer) Sell(ctx context.Context, req *pb.PartsSellRequest)
userId := currentUserId(ctx, s.users, s.sessions)
oldUser, _ := s.users.SnapshotUser(userId)
oldUser, _ := s.users.LoadUser(userId)
tracker := userdata.NewDeleteTracker().
Track("IUserParts", oldUser, userdata.SortedPartsRecords, []string{"userId", "userPartsUuid"})
@@ -81,7 +81,7 @@ func (s *PartsServiceServer) Sell(ctx context.Context, req *pb.PartsSellRequest)
return nil, fmt.Errorf("parts sell: %w", err)
}
tables := userdata.SelectTables(userdata.FullClientTableMap(snapshot), partsDiffTables)
tables := userdata.ProjectTables(snapshot, partsDiffTables)
diff := tracker.Apply(snapshot, tables)
return &pb.PartsSellResponse{
@@ -158,8 +158,7 @@ func (s *PartsServiceServer) Enhance(ctx context.Context, req *pb.PartsEnhanceRe
return nil, fmt.Errorf("parts enhance: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, partsDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, partsDiffTables))
return &pb.PartsEnhanceResponse{
IsSuccess: isSuccess,
@@ -187,8 +186,7 @@ func (s *PartsServiceServer) ReplacePreset(ctx context.Context, req *pb.PartsRep
return nil, fmt.Errorf("parts replace preset: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, []string{"IUserPartsPreset"}))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, []string{"IUserPartsPreset"}))
return &pb.PartsReplacePresetResponse{
DiffUserData: diff,
+1 -2
View File
@@ -30,8 +30,7 @@ func (s *PortalCageServiceServer) UpdatePortalCageSceneProgress(ctx context.Cont
user.PortalCageStatus.LatestVersion = now
})
tables := userdata.SelectTables(
userdata.FullClientTableMap(user),
tables := userdata.ProjectTables(user,
[]string{"IUserPortalCageStatus"},
)
return &pb.UpdatePortalCageSceneProgressResponse{
+2 -2
View File
@@ -42,7 +42,7 @@ var bigHuntDiffTables = []string{
}
func buildBigHuntDiff(user store.UserState, tableNames []string) map[string]*pb.DiffData {
tables := userdata.SelectTables(userdata.FullClientTableMap(user), tableNames)
tables := userdata.ProjectTables(user, tableNames)
return userdata.BuildDiffFromTablesOrdered(tables, tableNames)
}
@@ -331,7 +331,7 @@ func (s *BigHuntServiceServer) GetBigHuntTopData(ctx context.Context, _ *emptypb
log.Printf("[BigHuntService] GetBigHuntTopData")
userId := currentUserId(ctx, s.users, s.sessions)
user, _ := s.users.SnapshotUser(userId)
user, _ := s.users.LoadUser(userId)
nowMillis := gametime.NowMillis()
weeklyVersion := gametime.WeeklyVersion(nowMillis)
+1 -1
View File
@@ -29,7 +29,7 @@ func NewQuestServiceServer(users store.UserRepository, sessions store.SessionRep
}
func buildSelectedQuestDiff(user store.UserState, tableNames []string) map[string]*pb.DiffData {
tables := userdata.SelectTables(userdata.FullClientTableMap(user), tableNames)
tables := userdata.ProjectTables(user, tableNames)
return userdata.BuildDiffFromTablesOrdered(tables, tableNames)
}
+1 -1
View File
@@ -24,7 +24,7 @@ func NewSideStoryQuestServiceServer(users store.UserRepository, sessions store.S
}
func buildSideStoryDiff(user store.UserState, tableNames []string) map[string]*pb.DiffData {
tables := userdata.SelectTables(userdata.FullClientTableMap(user), tableNames)
tables := userdata.ProjectTables(user, tableNames)
return userdata.BuildDiffFromTablesOrdered(tables, tableNames)
}
+1 -1
View File
@@ -106,7 +106,7 @@ func (s *RewardServiceServer) ReceiveBigHuntReward(ctx context.Context, _ *empty
weeklyScoreResults = []*pb.WeeklyScoreResult{}
}
tables := userdata.SelectTables(userdata.FullClientTableMap(user), []string{
tables := userdata.ProjectTables(user, []string{
"IUserBigHuntWeeklyStatus",
"IUserBigHuntWeeklyMaxScore",
"IUserConsumableItem",
+5 -9
View File
@@ -89,8 +89,7 @@ func (s *ShopServiceServer) Buy(ctx context.Context, req *pb.BuyRequest) (*pb.Bu
return nil, fmt.Errorf("shop buy: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, shopDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, shopDiffTables))
userdata.AddWeaponStoryDiff(diff, snapshot, s.granter.DrainChangedStoryWeaponIds())
return &pb.BuyResponse{
@@ -132,8 +131,7 @@ func (s *ShopServiceServer) RefreshUserData(ctx context.Context, req *pb.Refresh
return nil, fmt.Errorf("shop refresh: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, shopDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, shopDiffTables))
return &pb.RefreshResponse{
DiffUserData: diff,
@@ -195,8 +193,7 @@ func (s *ShopServiceServer) CreatePurchaseTransaction(ctx context.Context, req *
txId := fmt.Sprintf("tx_%d_%d_%d", userId, req.ShopItemId, nowMillis)
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, shopDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, shopDiffTables))
return &pb.CreatePurchaseTransactionResponse{
PurchaseTransactionId: txId,
@@ -208,13 +205,12 @@ func (s *ShopServiceServer) PurchaseGooglePlayStoreProduct(ctx context.Context,
log.Printf("[ShopService] PurchaseGooglePlayStoreProduct: txId=%s", req.PurchaseTransactionId)
userId := currentUserId(ctx, s.users, s.sessions)
snapshot, err := s.users.SnapshotUser(userId)
snapshot, err := s.users.LoadUser(userId)
if err != nil {
return nil, fmt.Errorf("purchase google play: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, shopDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, shopDiffTables))
return &pb.PurchaseGooglePlayStoreProductResponse{
OverflowPossession: []*pb.Possession{},
+1 -2
View File
@@ -15,7 +15,6 @@ var startedGameStartTables = []string{
"IUserWeapon",
"IUserWeaponSkill",
"IUserWeaponAbility",
"IUserWeaponStory",
"IUserCompanion",
"IUserDeckCharacter",
"IUserDeck",
@@ -47,7 +46,7 @@ var gimmickDiffTables = []string{
func currentUserId(ctx context.Context, users store.UserRepository, sessions store.SessionRepository) int64 {
if md, ok := metadata.FromIncomingContext(ctx); ok {
if vals := md.Get("x-session-key"); len(vals) > 0 {
if vals := md.Get("x-apb-session-key"); len(vals) > 0 {
if userId, err := sessions.ResolveUserId(vals[0]); err == nil {
return userId
}
+4 -5
View File
@@ -37,11 +37,10 @@ func (s *TutorialServiceServer) SetTutorialProgress(ctx context.Context, req *pb
ChoiceId: req.ChoiceId,
}
}
if req.TutorialType == int32(model.TutorialTypeMenuFirst) ||
req.TutorialType == int32(model.TutorialTypeMenuSecond) {
grants = s.engine.ApplyTutorialReward(user, model.TutorialType(req.TutorialType), req.ChoiceId, nowMillis)
if req.TutorialType == int32(model.TutorialTypeMenuFirst) && req.ProgressPhase == 20 {
store.EnsureDefaultDeck(user, nowMillis)
}
grants = s.engine.ApplyTutorialReward(user, model.TutorialType(req.TutorialType), req.ChoiceId, nowMillis)
})
tables := []string{"IUserTutorialProgress"}
if req.TutorialType == int32(model.TutorialTypeMenuFirst) ||
@@ -55,7 +54,7 @@ func (s *TutorialServiceServer) SetTutorialProgress(ctx context.Context, req *pb
if len(grants) > 0 {
tables = append(tables, "IUserCompanion")
}
result := userdata.SelectTables(userdata.FullClientTableMap(user), tables)
result := userdata.ProjectTables(user, tables)
for _, t := range tables {
log.Printf("[TutorialService] DiffTable %s -> %s", t, result[t])
}
@@ -89,7 +88,7 @@ func (s *TutorialServiceServer) SetTutorialProgressAndReplaceDeck(ctx context.Co
}
})
return &pb.SetTutorialProgressAndReplaceDeckResponse{
DiffUserData: userdata.BuildDiffFromTables(userdata.SelectTables(userdata.FullClientTableMap(user), []string{
DiffUserData: userdata.BuildDiffFromTables(userdata.ProjectTables(user, []string{
"IUserTutorialProgress",
"IUserDeck",
"IUserDeckCharacter",
+24 -17
View File
@@ -50,9 +50,13 @@ func setCommonResponseTrailers(ctx context.Context, diff map[string]*pb.DiffData
}
func (s *UserServiceServer) RegisterUser(ctx context.Context, req *pb.RegisterUserRequest) (*pb.RegisterUserResponse, error) {
user, err := s.users.EnsureUser(req.Uuid)
userId, err := s.users.CreateUser(req.Uuid)
if err != nil {
return nil, fmt.Errorf("ensure user: %w", err)
return nil, fmt.Errorf("create user: %w", err)
}
user, err := s.users.LoadUser(userId)
if err != nil {
return nil, fmt.Errorf("load user: %w", err)
}
log.Printf("[UserService] RegisterUser: uuid=%s terminalId=%s -> userId=%d", req.Uuid, req.TerminalId, user.UserId)
@@ -66,10 +70,14 @@ func (s *UserServiceServer) RegisterUser(ctx context.Context, req *pb.RegisterUs
func (s *UserServiceServer) Auth(ctx context.Context, req *pb.AuthUserRequest) (*pb.AuthUserResponse, error) {
log.Printf("[UserService] Auth: uuid=%s", req.Uuid)
user, session, err := s.sessions.CreateSession(req.Uuid, 24*time.Hour)
session, err := s.sessions.CreateSession(req.Uuid, 24*time.Hour)
if err != nil {
return nil, fmt.Errorf("create session: %w", err)
}
user, err := s.users.LoadUser(session.UserId)
if err != nil {
return nil, fmt.Errorf("load user: %w", err)
}
return &pb.AuthUserResponse{
SessionKey: session.SessionKey,
@@ -84,7 +92,7 @@ func (s *UserServiceServer) GameStart(ctx context.Context, _ *emptypb.Empty) (*p
log.Printf("[UserService] GameStart")
if md, ok := metadata.FromIncomingContext(ctx); ok {
if vals := md.Get("x-session-key"); len(vals) > 0 {
if vals := md.Get("x-apb-session-key"); len(vals) > 0 {
log.Printf("[UserService] GameStart session: %s", vals[0])
}
}
@@ -93,8 +101,7 @@ func (s *UserServiceServer) GameStart(ctx context.Context, _ *emptypb.Empty) (*p
user, _ := s.users.UpdateUser(userId, func(user *store.UserState) {
user.GameStartDatetime = gametime.NowMillis()
})
fullTables := userdata.FullClientTableMap(user)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(fullTables, startedGameStartTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(user, startedGameStartTables))
setCommonResponseTrailers(ctx, diff, true)
return &pb.GameStartResponse{
@@ -106,12 +113,12 @@ func (s *UserServiceServer) GameStart(ctx context.Context, _ *emptypb.Empty) (*p
func (s *UserServiceServer) TransferUser(ctx context.Context, req *pb.TransferUserRequest) (*pb.TransferUserResponse, error) {
log.Printf("[UserService] TransferUser")
user, err := s.users.EnsureUser(req.Uuid)
userId, err := s.users.CreateUser(req.Uuid)
if err != nil {
return nil, fmt.Errorf("ensure user: %w", err)
return nil, fmt.Errorf("create user: %w", err)
}
return &pb.TransferUserResponse{
UserId: user.UserId,
UserId: userId,
Signature: "transferred-sig",
DiffUserData: userdata.EmptyDiff(),
}, nil
@@ -126,7 +133,7 @@ func (s *UserServiceServer) SetUserName(ctx context.Context, req *pb.SetUserName
user.Profile.NameUpdateDatetime = nowMillis
})
return &pb.SetUserNameResponse{
DiffUserData: userdata.BuildDiffFromTables(userdata.SelectTables(userdata.FullClientTableMap(user), []string{"IUserProfile"})),
DiffUserData: userdata.BuildDiffFromTables(userdata.ProjectTables(user, []string{"IUserProfile"})),
}, nil
}
@@ -139,7 +146,7 @@ func (s *UserServiceServer) SetUserMessage(ctx context.Context, req *pb.SetUserM
user.Profile.MessageUpdateDatetime = nowMillis
})
return &pb.SetUserMessageResponse{
DiffUserData: userdata.BuildDiffFromTables(userdata.SelectTables(userdata.FullClientTableMap(user), []string{"IUserProfile"})),
DiffUserData: userdata.BuildDiffFromTables(userdata.ProjectTables(user, []string{"IUserProfile"})),
}, nil
}
@@ -152,7 +159,7 @@ func (s *UserServiceServer) SetUserFavoriteCostumeId(ctx context.Context, req *p
user.Profile.FavoriteCostumeIdUpdateDatetime = nowMillis
})
return &pb.SetUserFavoriteCostumeIdResponse{
DiffUserData: userdata.BuildDiffFromTables(userdata.SelectTables(userdata.FullClientTableMap(user), []string{"IUserProfile"})),
DiffUserData: userdata.BuildDiffFromTables(userdata.ProjectTables(user, []string{"IUserProfile"})),
}, nil
}
@@ -162,7 +169,7 @@ func (s *UserServiceServer) GetUserProfile(ctx context.Context, req *pb.GetUserP
if userId == 0 {
userId = currentUserId(ctx, s.users, s.sessions)
}
user, err := s.users.SnapshotUser(userId)
user, err := s.users.LoadUser(userId)
if err != nil {
return &pb.GetUserProfileResponse{DiffUserData: userdata.EmptyDiff()}, nil
}
@@ -219,7 +226,7 @@ func (s *UserServiceServer) SetBirthYearMonth(ctx context.Context, req *pb.SetBi
func (s *UserServiceServer) GetBirthYearMonth(ctx context.Context, _ *emptypb.Empty) (*pb.GetBirthYearMonthResponse, error) {
userId := currentUserId(ctx, s.users, s.sessions)
user, err := s.users.SnapshotUser(userId)
user, err := s.users.LoadUser(userId)
if err != nil {
return &pb.GetBirthYearMonthResponse{BirthYear: 2000, BirthMonth: 1, DiffUserData: userdata.EmptyDiff()}, nil
}
@@ -228,7 +235,7 @@ func (s *UserServiceServer) GetBirthYearMonth(ctx context.Context, _ *emptypb.Em
func (s *UserServiceServer) GetChargeMoney(ctx context.Context, _ *emptypb.Empty) (*pb.GetChargeMoneyResponse, error) {
userId := currentUserId(ctx, s.users, s.sessions)
user, err := s.users.SnapshotUser(userId)
user, err := s.users.LoadUser(userId)
if err != nil {
return &pb.GetChargeMoneyResponse{ChargeMoneyThisMonth: 0, DiffUserData: userdata.EmptyDiff()}, nil
}
@@ -242,7 +249,7 @@ func (s *UserServiceServer) SetUserSetting(ctx context.Context, req *pb.SetUserS
user.Setting.IsNotifyPurchaseAlert = req.IsNotifyPurchaseAlert
})
return &pb.SetUserSettingResponse{
DiffUserData: userdata.BuildDiffFromTables(userdata.SelectTables(userdata.FullClientTableMap(user), []string{"IUserSetting"})),
DiffUserData: userdata.BuildDiffFromTables(userdata.ProjectTables(user, []string{"IUserSetting"})),
}, nil
}
@@ -252,7 +259,7 @@ func (s *UserServiceServer) GetAndroidArgs(ctx context.Context, req *pb.GetAndro
func (s *UserServiceServer) GetBackupToken(ctx context.Context, req *pb.GetBackupTokenRequest) (*pb.GetBackupTokenResponse, error) {
userId := currentUserId(ctx, s.users, s.sessions)
user, err := s.users.SnapshotUser(userId)
user, err := s.users.LoadUser(userId)
if err != nil {
return &pb.GetBackupTokenResponse{BackupToken: "mock-backup-token", DiffUserData: userdata.EmptyDiff()}, nil
}
+14 -22
View File
@@ -71,8 +71,7 @@ func (s *WeaponServiceServer) Protect(ctx context.Context, req *pb.ProtectReques
}
})
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, []string{"IUserWeapon"}))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, []string{"IUserWeapon"}))
return &pb.ProtectResponse{DiffUserData: diff}, nil
}
@@ -95,8 +94,7 @@ func (s *WeaponServiceServer) Unprotect(ctx context.Context, req *pb.UnprotectRe
}
})
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, []string{"IUserWeapon"}))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, []string{"IUserWeapon"}))
return &pb.UnprotectResponse{DiffUserData: diff}, nil
}
@@ -165,8 +163,7 @@ func (s *WeaponServiceServer) EnhanceByMaterial(ctx context.Context, req *pb.Enh
return nil, fmt.Errorf("weapon enhance by material: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, weaponDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, weaponDiffTables))
userdata.AddWeaponStoryDiff(diff, snapshot, changedStoryIds)
return &pb.EnhanceByMaterialResponse{
@@ -181,7 +178,7 @@ func (s *WeaponServiceServer) Sell(ctx context.Context, req *pb.SellRequest) (*p
userId := currentUserId(ctx, s.users, s.sessions)
oldUser, _ := s.users.SnapshotUser(userId)
oldUser, _ := s.users.LoadUser(userId)
tracker := userdata.NewDeleteTracker().
Track("IUserWeapon", oldUser, userdata.SortedWeaponRecords, []string{"userId", "userWeaponUuid"}).
Track("IUserWeaponSkill", oldUser, userdata.SortedWeaponSkillRecords, []string{"userId", "userWeaponUuid", "slotNumber"}).
@@ -229,7 +226,7 @@ func (s *WeaponServiceServer) Sell(ctx context.Context, req *pb.SellRequest) (*p
}
sellDiffTables := []string{"IUserWeapon", "IUserWeaponSkill", "IUserWeaponAbility", "IUserWeaponAwaken", "IUserConsumableItem"}
tables := userdata.SelectTables(userdata.FullClientTableMap(snapshot), sellDiffTables)
tables := userdata.ProjectTables(snapshot, sellDiffTables)
diff := tracker.Apply(snapshot, tables)
return &pb.SellResponse{DiffUserData: diff}, nil
@@ -307,8 +304,7 @@ func (s *WeaponServiceServer) Evolve(ctx context.Context, req *pb.EvolveRequest)
return nil, fmt.Errorf("weapon evolve: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, weaponDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, weaponDiffTables))
userdata.AddWeaponStoryDiff(diff, snapshot, changedStoryIds)
return &pb.EvolveResponse{DiffUserData: diff}, nil
@@ -407,8 +403,7 @@ func (s *WeaponServiceServer) EnhanceSkill(ctx context.Context, req *pb.EnhanceS
return nil, fmt.Errorf("weapon enhance skill: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, weaponDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, weaponDiffTables))
return &pb.EnhanceSkillResponse{DiffUserData: diff}, nil
}
@@ -506,8 +501,7 @@ func (s *WeaponServiceServer) EnhanceAbility(ctx context.Context, req *pb.Enhanc
return nil, fmt.Errorf("weapon enhance ability: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, weaponDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, weaponDiffTables))
return &pb.EnhanceAbilityResponse{DiffUserData: diff}, nil
}
@@ -578,8 +572,7 @@ func (s *WeaponServiceServer) LimitBreakByMaterial(ctx context.Context, req *pb.
return nil, fmt.Errorf("weapon limit break by material: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, limitBreakDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, limitBreakDiffTables))
return &pb.LimitBreakByMaterialResponse{DiffUserData: diff}, nil
}
@@ -590,7 +583,7 @@ func (s *WeaponServiceServer) LimitBreakByWeapon(ctx context.Context, req *pb.Li
userId := currentUserId(ctx, s.users, s.sessions)
nowMillis := gametime.NowMillis()
oldUser, _ := s.users.SnapshotUser(userId)
oldUser, _ := s.users.LoadUser(userId)
tracker := userdata.NewDeleteTracker().
Track("IUserWeapon", oldUser, userdata.SortedWeaponRecords, []string{"userId", "userWeaponUuid"}).
Track("IUserWeaponSkill", oldUser, userdata.SortedWeaponSkillRecords, []string{"userId", "userWeaponUuid", "slotNumber"}).
@@ -665,7 +658,7 @@ func (s *WeaponServiceServer) LimitBreakByWeapon(ctx context.Context, req *pb.Li
return nil, fmt.Errorf("weapon limit break by weapon: %w", err)
}
tables := userdata.SelectTables(userdata.FullClientTableMap(snapshot), limitBreakDiffTables)
tables := userdata.ProjectTables(snapshot, limitBreakDiffTables)
diff := tracker.Apply(snapshot, tables)
return &pb.LimitBreakByWeaponResponse{DiffUserData: diff}, nil
@@ -677,7 +670,7 @@ func (s *WeaponServiceServer) EnhanceByWeapon(ctx context.Context, req *pb.Enhan
userId := currentUserId(ctx, s.users, s.sessions)
nowMillis := gametime.NowMillis()
oldUser, _ := s.users.SnapshotUser(userId)
oldUser, _ := s.users.LoadUser(userId)
tracker := userdata.NewDeleteTracker().
Track("IUserWeapon", oldUser, userdata.SortedWeaponRecords, []string{"userId", "userWeaponUuid"}).
Track("IUserWeaponSkill", oldUser, userdata.SortedWeaponSkillRecords, []string{"userId", "userWeaponUuid", "slotNumber"}).
@@ -753,7 +746,7 @@ func (s *WeaponServiceServer) EnhanceByWeapon(ctx context.Context, req *pb.Enhan
return nil, fmt.Errorf("weapon enhance by weapon: %w", err)
}
tables := userdata.SelectTables(userdata.FullClientTableMap(snapshot), weaponDiffTables)
tables := userdata.ProjectTables(snapshot, weaponDiffTables)
diff := tracker.Apply(snapshot, tables)
userdata.AddWeaponStoryDiff(diff, snapshot, changedStoryIds)
@@ -864,8 +857,7 @@ func (s *WeaponServiceServer) Awaken(ctx context.Context, req *pb.WeaponAwakenRe
return nil, fmt.Errorf("weapon awaken: %w", err)
}
tables := userdata.FullClientTableMap(snapshot)
diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, weaponAwakenDiffTables))
diff := userdata.BuildDiffFromTables(userdata.ProjectTables(snapshot, weaponAwakenDiffTables))
return &pb.WeaponAwakenResponse{DiffUserData: diff}, nil
}