Fx equipment duplication and add CopyDeck/RemoveDeck

This commit is contained in:
Ilya Groshev
2026-04-22 08:59:10 +03:00
parent a3fbb1aeba
commit 7828de031c
3 changed files with 111 additions and 16 deletions
+2
View File
@@ -40,6 +40,7 @@ func main() {
// lunar-tear (grpc) flags
grpcListen := flag.String("grpc.listen", "0.0.0.0:8003", "lunar-tear gRPC listen address (host:port)")
grpcPublicAddr := flag.String("grpc.public-addr", "10.0.2.2:8003", "lunar-tear externally-reachable address")
grpcDB := flag.String("grpc.db", "db/game.db", "lunar-tear SQLite database path")
grpcOctoURL := flag.String("grpc.octo-url", "", "Octo CDN base URL passed to lunar-tear (default: derived from cdn.public-addr)")
grpcAuthURL := flag.String("grpc.auth-url", "", "auth server base URL passed to lunar-tear (default: derived from auth.listen)")
@@ -87,6 +88,7 @@ func main() {
cmd: exec.CommandContext(ctx, "go", "run", "./cmd/lunar-tear",
"--listen", *grpcListen,
"--public-addr", *grpcPublicAddr,
"--db", *grpcDB,
"--octo-url", *grpcOctoURL,
"--auth-url", *grpcAuthURL,
),
+40
View File
@@ -213,3 +213,43 @@ func (s *DeckServiceServer) ReplaceMultiDeck(ctx context.Context, req *pb.Replac
return &pb.ReplaceMultiDeckResponse{}, nil
}
func (s *DeckServiceServer) RemoveDeck(ctx context.Context, req *pb.RemoveDeckRequest) (*pb.RemoveDeckResponse, error) {
log.Printf("[DeckService] RemoveDeck: deckType=%d deckNumber=%d", req.DeckType, req.UserDeckNumber)
userId := CurrentUserId(ctx, s.users, s.sessions)
s.users.UpdateUser(userId, func(user *store.UserState) {
store.RemoveDeckData(user, model.DeckType(req.DeckType), req.UserDeckNumber)
})
return &pb.RemoveDeckResponse{}, nil
}
func (s *DeckServiceServer) CopyDeck(ctx context.Context, req *pb.CopyDeckRequest) (*pb.CopyDeckResponse, error) {
log.Printf("[DeckService] CopyDeck: from deckType=%d deckNumber=%d -> to deckType=%d deckNumber=%d",
req.FromDeckType, req.FromUserDeckNumber, req.ToDeckType, req.ToUserDeckNumber)
userId := CurrentUserId(ctx, s.users, s.sessions)
var resultType int32
s.users.UpdateUser(userId, func(user *store.UserState) {
slots := store.ReadDeckSlots(user, model.DeckType(req.FromDeckType), req.FromUserDeckNumber)
if slots == nil {
return
}
nowMillis := gametime.NowMillis()
fromKey := store.DeckKey{DeckType: model.DeckType(req.FromDeckType), UserDeckNumber: req.FromUserDeckNumber}
srcName := user.Decks[fromKey].Name
store.ApplyDeckReplacement(user, model.DeckType(req.ToDeckType), req.ToUserDeckNumber, slots, nowMillis)
toKey := store.DeckKey{DeckType: model.DeckType(req.ToDeckType), UserDeckNumber: req.ToUserDeckNumber}
deck := user.Decks[toKey]
deck.Name = srcName
user.Decks[toKey] = deck
resultType = 1
})
return &pb.CopyDeckResponse{ResultType: resultType}, nil
}
+69 -16
View File
@@ -330,31 +330,84 @@ func ApplyDeckReplacement(user *UserState, deckType model.DeckType, userDeckNumb
deck.Power = 100
}
uuidPtrs := []*string{&deck.UserDeckCharacterUuid01, &deck.UserDeckCharacterUuid02, &deck.UserDeckCharacterUuid03}
for i, uuidPtr := range uuidPtrs {
for _, oldUuid := range []string{deck.UserDeckCharacterUuid01, deck.UserDeckCharacterUuid02, deck.UserDeckCharacterUuid03} {
if oldUuid == "" {
continue
}
delete(user.DeckCharacters, oldUuid)
delete(user.DeckSubWeapons, oldUuid)
delete(user.DeckParts, oldUuid)
}
var newUuids [3]string
for i := range 3 {
if i >= len(slots) || slots[i].UserCostumeUuid == "" {
*uuidPtr = ""
continue
}
slot := slots[i]
dcUuid := *uuidPtr
if dcUuid == "" {
dcUuid = uuid.New().String()
dcUuid := uuid.New().String()
user.DeckCharacters[dcUuid] = DeckCharacterState{
UserDeckCharacterUuid: dcUuid,
UserCostumeUuid: slot.UserCostumeUuid,
MainUserWeaponUuid: slot.MainUserWeaponUuid,
UserCompanionUuid: slot.UserCompanionUuid,
UserThoughtUuid: slot.UserThoughtUuid,
DressupCostumeId: slot.DressupCostumeId,
LatestVersion: nowMillis,
}
dc := user.DeckCharacters[dcUuid]
dc.UserDeckCharacterUuid = dcUuid
dc.UserCostumeUuid = slot.UserCostumeUuid
dc.MainUserWeaponUuid = slot.MainUserWeaponUuid
dc.UserCompanionUuid = slot.UserCompanionUuid
dc.UserThoughtUuid = slot.UserThoughtUuid
dc.DressupCostumeId = slot.DressupCostumeId
dc.LatestVersion = nowMillis
user.DeckCharacters[dcUuid] = dc
user.DeckSubWeapons[dcUuid] = slot.SubWeaponUuids
user.DeckParts[dcUuid] = slot.PartsUuids
*uuidPtr = dcUuid
newUuids[i] = dcUuid
}
deck.UserDeckCharacterUuid01 = newUuids[0]
deck.UserDeckCharacterUuid02 = newUuids[1]
deck.UserDeckCharacterUuid03 = newUuids[2]
deck.LatestVersion = nowMillis
user.Decks[deckKey] = deck
}
func RemoveDeckData(user *UserState, deckType model.DeckType, userDeckNumber int32) {
deckKey := DeckKey{DeckType: deckType, UserDeckNumber: userDeckNumber}
deck, ok := user.Decks[deckKey]
if !ok {
return
}
for _, dcUuid := range []string{deck.UserDeckCharacterUuid01, deck.UserDeckCharacterUuid02, deck.UserDeckCharacterUuid03} {
if dcUuid == "" {
continue
}
delete(user.DeckCharacters, dcUuid)
delete(user.DeckSubWeapons, dcUuid)
delete(user.DeckParts, dcUuid)
}
delete(user.Decks, deckKey)
}
func ReadDeckSlots(user *UserState, deckType model.DeckType, userDeckNumber int32) []DeckCharacterInput {
deckKey := DeckKey{DeckType: deckType, UserDeckNumber: userDeckNumber}
deck, ok := user.Decks[deckKey]
if !ok {
return nil
}
slots := make([]DeckCharacterInput, 3)
for i, dcUuid := range []string{deck.UserDeckCharacterUuid01, deck.UserDeckCharacterUuid02, deck.UserDeckCharacterUuid03} {
if dcUuid == "" {
continue
}
dc, ok := user.DeckCharacters[dcUuid]
if !ok {
continue
}
slots[i] = DeckCharacterInput{
UserCostumeUuid: dc.UserCostumeUuid,
MainUserWeaponUuid: dc.MainUserWeaponUuid,
SubWeaponUuids: user.DeckSubWeapons[dcUuid],
PartsUuids: user.DeckParts[dcUuid],
UserCompanionUuid: dc.UserCompanionUuid,
UserThoughtUuid: dc.UserThoughtUuid,
DressupCostumeId: dc.DressupCostumeId,
}
}
return slots
}