mirror of
https://github.com/Walter-Sparrow/lunar-tear.git
synced 2026-07-02 13:53:41 +03:00
242 lines
8.8 KiB
Go
242 lines
8.8 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
|
|
pb "lunar-tear/server/gen/proto"
|
|
"lunar-tear/server/internal/gametime"
|
|
"lunar-tear/server/internal/model"
|
|
"lunar-tear/server/internal/store"
|
|
"lunar-tear/server/internal/userdata"
|
|
)
|
|
|
|
type DeckServiceServer struct {
|
|
pb.UnimplementedDeckServiceServer
|
|
users store.UserRepository
|
|
sessions store.SessionRepository
|
|
}
|
|
|
|
func NewDeckServiceServer(users store.UserRepository, sessions store.SessionRepository) *DeckServiceServer {
|
|
return &DeckServiceServer{users: users, sessions: sessions}
|
|
}
|
|
|
|
func (s *DeckServiceServer) UpdateName(ctx context.Context, req *pb.UpdateNameRequest) (*pb.UpdateNameResponse, error) {
|
|
log.Printf("[DeckService] UpdateName: deckType=%d deckNumber=%d name=%q", req.DeckType, req.UserDeckNumber, req.Name)
|
|
userId := currentUserId(ctx, s.users, s.sessions)
|
|
|
|
user, _ := s.users.UpdateUser(userId, func(user *store.UserState) {
|
|
deckKey := store.DeckKey{DeckType: model.DeckType(req.DeckType), UserDeckNumber: req.UserDeckNumber}
|
|
deck := user.Decks[deckKey]
|
|
deck.Name = req.Name
|
|
user.Decks[deckKey] = deck
|
|
})
|
|
|
|
result := userdata.SelectTables(userdata.FullClientTableMap(user), []string{"IUserDeck"})
|
|
return &pb.UpdateNameResponse{
|
|
DiffUserData: userdata.BuildDiffFromTables(result),
|
|
}, nil
|
|
}
|
|
|
|
func (s *DeckServiceServer) RefreshDeckPower(ctx context.Context, req *pb.RefreshDeckPowerRequest) (*pb.RefreshDeckPowerResponse, error) {
|
|
log.Printf("[DeckService] RefreshDeckPower: deckType=%d deckNumber=%d", req.DeckType, req.UserDeckNumber)
|
|
userId := currentUserId(ctx, s.users, s.sessions)
|
|
|
|
user, _ := s.users.UpdateUser(userId, func(user *store.UserState) {
|
|
if req.DeckPower == nil {
|
|
log.Printf("[DeckService] RefreshDeckPower: deckPower is nil")
|
|
return
|
|
}
|
|
|
|
dt := model.DeckType(req.DeckType)
|
|
deckKey := store.DeckKey{DeckType: dt, UserDeckNumber: req.UserDeckNumber}
|
|
deck, ok := user.Decks[deckKey]
|
|
if !ok {
|
|
log.Fatalf("[DeckService] RefreshDeckPower: deck not found")
|
|
}
|
|
|
|
deck.Power = req.DeckPower.Power
|
|
user.Decks[deckKey] = deck
|
|
|
|
for _, cp := range []*pb.DeckCharacterPower{
|
|
req.DeckPower.DeckCharacterPower01,
|
|
req.DeckPower.DeckCharacterPower02,
|
|
req.DeckPower.DeckCharacterPower03,
|
|
} {
|
|
if cp == nil || cp.UserDeckCharacterUuid == "" {
|
|
continue
|
|
}
|
|
|
|
if dc, ok := user.DeckCharacters[cp.UserDeckCharacterUuid]; ok {
|
|
dc.Power = cp.Power
|
|
user.DeckCharacters[cp.UserDeckCharacterUuid] = dc
|
|
}
|
|
}
|
|
|
|
note := user.DeckTypeNotes[dt]
|
|
if req.DeckPower.Power > note.MaxDeckPower {
|
|
note.DeckType = dt
|
|
note.MaxDeckPower = req.DeckPower.Power
|
|
user.DeckTypeNotes[dt] = note
|
|
}
|
|
})
|
|
|
|
result := userdata.SelectTables(userdata.FullClientTableMap(user), []string{
|
|
"IUserDeck", "IUserDeckCharacter", "IUserDeckTypeNote",
|
|
})
|
|
return &pb.RefreshDeckPowerResponse{
|
|
DiffUserData: userdata.BuildDiffFromTables(result),
|
|
}, nil
|
|
}
|
|
|
|
func (s *DeckServiceServer) RefreshMultiDeckPower(ctx context.Context, req *pb.RefreshMultiDeckPowerRequest) (*pb.RefreshMultiDeckPowerResponse, error) {
|
|
log.Printf("[DeckService] RefreshMultiDeckPower: %d entries", len(req.DeckPowerInfo))
|
|
userId := currentUserId(ctx, s.users, s.sessions)
|
|
|
|
user, _ := s.users.UpdateUser(userId, func(user *store.UserState) {
|
|
for _, info := range req.DeckPowerInfo {
|
|
if info.DeckPower == nil {
|
|
continue
|
|
}
|
|
|
|
dt := model.DeckType(info.DeckType)
|
|
deckKey := store.DeckKey{DeckType: dt, UserDeckNumber: info.UserDeckNumber}
|
|
deck, ok := user.Decks[deckKey]
|
|
if !ok {
|
|
log.Printf("[DeckService] RefreshMultiDeckPower: deck not found deckType=%d deckNumber=%d", info.DeckType, info.UserDeckNumber)
|
|
continue
|
|
}
|
|
|
|
deck.Power = info.DeckPower.Power
|
|
user.Decks[deckKey] = deck
|
|
|
|
for _, cp := range []*pb.DeckCharacterPower{
|
|
info.DeckPower.DeckCharacterPower01,
|
|
info.DeckPower.DeckCharacterPower02,
|
|
info.DeckPower.DeckCharacterPower03,
|
|
} {
|
|
if cp == nil || cp.UserDeckCharacterUuid == "" {
|
|
continue
|
|
}
|
|
if dc, ok := user.DeckCharacters[cp.UserDeckCharacterUuid]; ok {
|
|
dc.Power = cp.Power
|
|
user.DeckCharacters[cp.UserDeckCharacterUuid] = dc
|
|
}
|
|
}
|
|
|
|
note := user.DeckTypeNotes[dt]
|
|
if info.DeckPower.Power > note.MaxDeckPower {
|
|
note.DeckType = dt
|
|
note.MaxDeckPower = info.DeckPower.Power
|
|
user.DeckTypeNotes[dt] = note
|
|
}
|
|
}
|
|
})
|
|
|
|
result := userdata.SelectTables(userdata.FullClientTableMap(user), []string{
|
|
"IUserDeck", "IUserDeckCharacter", "IUserDeckTypeNote",
|
|
})
|
|
return &pb.RefreshMultiDeckPowerResponse{
|
|
DiffUserData: userdata.BuildDiffFromTables(result),
|
|
}, nil
|
|
}
|
|
|
|
func deckSlotsFromProto(deck *pb.Deck) []store.DeckCharacterInput {
|
|
slots := make([]store.DeckCharacterInput, 3)
|
|
for i, ch := range []*pb.DeckCharacter{deck.Character01, deck.Character02, deck.Character03} {
|
|
if ch == nil {
|
|
continue
|
|
}
|
|
slots[i] = store.DeckCharacterInput{
|
|
UserCostumeUuid: ch.UserCostumeUuid,
|
|
MainUserWeaponUuid: ch.MainUserWeaponUuid,
|
|
SubWeaponUuids: ch.SubUserWeaponUuid,
|
|
PartsUuids: ch.UserPartsUuid,
|
|
UserCompanionUuid: ch.UserCompanionUuid,
|
|
UserThoughtUuid: ch.UserThoughtUuid,
|
|
DressupCostumeId: ch.DressupCostumeId,
|
|
}
|
|
}
|
|
return slots
|
|
}
|
|
|
|
func (s *DeckServiceServer) ReplaceDeck(ctx context.Context, req *pb.ReplaceDeckRequest) (*pb.ReplaceDeckResponse, error) {
|
|
log.Printf("[DeckService] ReplaceDeck: deckType=%d deckNumber=%d", req.DeckType, req.UserDeckNumber)
|
|
if req.Deck != nil {
|
|
for i, ch := range []*pb.DeckCharacter{req.Deck.Character01, req.Deck.Character02, req.Deck.Character03} {
|
|
if ch == nil {
|
|
continue
|
|
}
|
|
log.Printf("[DeckService] ReplaceDeck slot %d: costume=%s mainWeapon=%s subWeapons=%v companion=%s thought=%s",
|
|
i+1, ch.UserCostumeUuid, ch.MainUserWeaponUuid, ch.SubUserWeaponUuid, ch.UserCompanionUuid, ch.UserThoughtUuid)
|
|
}
|
|
}
|
|
userId := currentUserId(ctx, s.users, s.sessions)
|
|
|
|
oldUser, _ := s.users.SnapshotUser(userId)
|
|
tracker := userdata.NewDeleteTracker().
|
|
Track("IUserDeckSubWeaponGroup", oldUser, userdata.DeckSubWeaponRecords,
|
|
[]string{"userId", "userDeckCharacterUuid", "userWeaponUuid"}).
|
|
Track("IUserDeckPartsGroup", oldUser, userdata.DeckPartsGroupRecords,
|
|
[]string{"userId", "userDeckCharacterUuid", "userPartsUuid"}).
|
|
Track("IUserDeckCharacterDressupCostume", oldUser, userdata.DeckDressupCostumeRecords,
|
|
[]string{"userId", "userDeckCharacterUuid"})
|
|
|
|
user, _ := s.users.UpdateUser(userId, func(user *store.UserState) {
|
|
if req.Deck == nil {
|
|
return
|
|
}
|
|
store.ApplyDeckReplacement(user, model.DeckType(req.DeckType), req.UserDeckNumber, deckSlotsFromProto(req.Deck), gametime.NowMillis())
|
|
})
|
|
|
|
result := userdata.SelectTables(userdata.FullClientTableMap(user), []string{
|
|
"IUserDeck", "IUserDeckCharacter", "IUserDeckSubWeaponGroup", "IUserDeckPartsGroup",
|
|
"IUserDeckCharacterDressupCostume",
|
|
})
|
|
return &pb.ReplaceDeckResponse{
|
|
DiffUserData: tracker.Apply(user, result),
|
|
}, nil
|
|
}
|
|
|
|
func (s *DeckServiceServer) ReplaceTripleDeck(ctx context.Context, req *pb.ReplaceTripleDeckRequest) (*pb.ReplaceTripleDeckResponse, error) {
|
|
log.Printf("[DeckService] ReplaceTripleDeck: deckType=%d deckNumber=%d", req.DeckType, req.UserDeckNumber)
|
|
userId := currentUserId(ctx, s.users, s.sessions)
|
|
|
|
oldUser, _ := s.users.SnapshotUser(userId)
|
|
tracker := userdata.NewDeleteTracker().
|
|
Track("IUserDeckSubWeaponGroup", oldUser, userdata.DeckSubWeaponRecords,
|
|
[]string{"userId", "userDeckCharacterUuid", "userWeaponUuid"}).
|
|
Track("IUserDeckPartsGroup", oldUser, userdata.DeckPartsGroupRecords,
|
|
[]string{"userId", "userDeckCharacterUuid", "userPartsUuid"}).
|
|
Track("IUserDeckCharacterDressupCostume", oldUser, userdata.DeckDressupCostumeRecords,
|
|
[]string{"userId", "userDeckCharacterUuid"})
|
|
|
|
user, _ := s.users.UpdateUser(userId, func(user *store.UserState) {
|
|
nowMillis := gametime.NowMillis()
|
|
for idx, detail := range []*pb.DeckDetail{req.DeckDetail01, req.DeckDetail02, req.DeckDetail03} {
|
|
if detail == nil || detail.Deck == nil {
|
|
continue
|
|
}
|
|
log.Printf("[DeckService] ReplaceTripleDeck detail %d: deckType=%d deckNumber=%d", idx+1, detail.DeckType, detail.UserDeckNumber)
|
|
if detail.Deck != nil {
|
|
for i, ch := range []*pb.DeckCharacter{detail.Deck.Character01, detail.Deck.Character02, detail.Deck.Character03} {
|
|
if ch == nil {
|
|
continue
|
|
}
|
|
log.Printf("[DeckService] ReplaceTripleDeck detail %d slot %d: costume=%s mainWeapon=%s subWeapons=%v companion=%s thought=%s",
|
|
idx+1, i+1, ch.UserCostumeUuid, ch.MainUserWeaponUuid, ch.SubUserWeaponUuid, ch.UserCompanionUuid, ch.UserThoughtUuid)
|
|
}
|
|
}
|
|
store.ApplyDeckReplacement(user, model.DeckType(detail.DeckType), detail.UserDeckNumber, deckSlotsFromProto(detail.Deck), nowMillis)
|
|
}
|
|
})
|
|
|
|
result := userdata.SelectTables(userdata.FullClientTableMap(user), []string{
|
|
"IUserDeck", "IUserDeckCharacter", "IUserDeckSubWeaponGroup", "IUserDeckPartsGroup",
|
|
"IUserDeckCharacterDressupCostume",
|
|
})
|
|
return &pb.ReplaceTripleDeckResponse{
|
|
DiffUserData: tracker.Apply(user, result),
|
|
}, nil
|
|
}
|