Add authentication server, dev CLI, Docker multi-service setup, and cross-platform improvements

This commit is contained in:
Ilya Groshev
2026-04-21 16:49:44 +03:00
parent 43d6527b42
commit a3fbb1aeba
121 changed files with 4523 additions and 2888 deletions
+33 -59
View File
@@ -8,7 +8,6 @@ import (
"lunar-tear/server/internal/gametime"
"lunar-tear/server/internal/model"
"lunar-tear/server/internal/store"
"lunar-tear/server/internal/userdata"
)
type DeckServiceServer struct {
@@ -23,26 +22,23 @@ func NewDeckServiceServer(users store.UserRepository, sessions store.SessionRepo
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)
userId := CurrentUserId(ctx, s.users, s.sessions)
user, _ := s.users.UpdateUser(userId, func(user *store.UserState) {
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.ProjectTables(user, []string{"IUserDeck"})
return &pb.UpdateNameResponse{
DiffUserData: userdata.BuildDiffFromTables(result),
}, nil
return &pb.UpdateNameResponse{}, 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)
userId := CurrentUserId(ctx, s.users, s.sessions)
user, _ := s.users.UpdateUser(userId, func(user *store.UserState) {
s.users.UpdateUser(userId, func(user *store.UserState) {
if req.DeckPower == nil {
log.Printf("[DeckService] RefreshDeckPower: deckPower is nil")
return
@@ -81,19 +77,14 @@ func (s *DeckServiceServer) RefreshDeckPower(ctx context.Context, req *pb.Refres
}
})
result := userdata.ProjectTables(user, []string{
"IUserDeck", "IUserDeckCharacter", "IUserDeckTypeNote",
})
return &pb.RefreshDeckPowerResponse{
DiffUserData: userdata.BuildDiffFromTables(result),
}, nil
return &pb.RefreshDeckPowerResponse{}, 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)
userId := CurrentUserId(ctx, s.users, s.sessions)
user, _ := s.users.UpdateUser(userId, func(user *store.UserState) {
s.users.UpdateUser(userId, func(user *store.UserState) {
for _, info := range req.DeckPowerInfo {
if info.DeckPower == nil {
continue
@@ -133,12 +124,7 @@ func (s *DeckServiceServer) RefreshMultiDeckPower(ctx context.Context, req *pb.R
}
})
result := userdata.ProjectTables(user, []string{
"IUserDeck", "IUserDeckCharacter", "IUserDeckTypeNote",
})
return &pb.RefreshMultiDeckPowerResponse{
DiffUserData: userdata.BuildDiffFromTables(result),
}, nil
return &pb.RefreshMultiDeckPowerResponse{}, nil
}
func deckSlotsFromProto(deck *pb.Deck) []store.DeckCharacterInput {
@@ -171,47 +157,23 @@ func (s *DeckServiceServer) ReplaceDeck(ctx context.Context, req *pb.ReplaceDeck
i+1, ch.UserCostumeUuid, ch.MainUserWeaponUuid, ch.SubUserWeaponUuid, ch.UserCompanionUuid, ch.UserThoughtUuid)
}
}
userId := currentUserId(ctx, s.users, s.sessions)
userId := CurrentUserId(ctx, s.users, s.sessions)
oldUser, _ := s.users.LoadUser(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) {
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.ProjectTables(user, []string{
"IUserDeck", "IUserDeckCharacter", "IUserDeckSubWeaponGroup", "IUserDeckPartsGroup",
"IUserDeckCharacterDressupCostume",
})
return &pb.ReplaceDeckResponse{
DiffUserData: tracker.Apply(user, result),
}, nil
return &pb.ReplaceDeckResponse{}, 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)
userId := CurrentUserId(ctx, s.users, s.sessions)
oldUser, _ := s.users.LoadUser(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) {
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 {
@@ -231,11 +193,23 @@ func (s *DeckServiceServer) ReplaceTripleDeck(ctx context.Context, req *pb.Repla
}
})
result := userdata.ProjectTables(user, []string{
"IUserDeck", "IUserDeckCharacter", "IUserDeckSubWeaponGroup", "IUserDeckPartsGroup",
"IUserDeckCharacterDressupCostume",
})
return &pb.ReplaceTripleDeckResponse{
DiffUserData: tracker.Apply(user, result),
}, nil
return &pb.ReplaceTripleDeckResponse{}, nil
}
func (s *DeckServiceServer) ReplaceMultiDeck(ctx context.Context, req *pb.ReplaceMultiDeckRequest) (*pb.ReplaceMultiDeckResponse, error) {
log.Printf("[DeckService] ReplaceMultiDeck: %d entries", len(req.DeckDetail))
userId := CurrentUserId(ctx, s.users, s.sessions)
s.users.UpdateUser(userId, func(user *store.UserState) {
nowMillis := gametime.NowMillis()
for idx, detail := range req.DeckDetail {
if detail == nil || detail.Deck == nil {
continue
}
log.Printf("[DeckService] ReplaceMultiDeck detail %d: deckType=%d deckNumber=%d", idx+1, detail.DeckType, detail.UserDeckNumber)
store.ApplyDeckReplacement(user, model.DeckType(detail.DeckType), detail.UserDeckNumber, deckSlotsFromProto(detail.Deck), nowMillis)
}
})
return &pb.ReplaceMultiDeckResponse{}, nil
}