퍼즐 게임의 핵심 자원인 라이프의 회복, 소모, 시간제 라이프 관리를 위한 서버 처리 흐름을 살펴봅니다.
목표를 달성하여 스테이지를 클리어하세요.
클라이언트가 시간 경과를 확인한 뒤 호출합니다. 서버는 lastRecoveryAt를 기준으로 회복 가능량을 계산하고, max를 초과하지 않도록 검증합니다.
1func (s *LifeService) RecoverLife(ctx context.Context, userID string) (resp *RecoverResponse, err error) {2 tx, err := s.db.BeginTx(ctx, nil)3 if err != nil {4 return nil, err5 }6 defer func() {7 if err != nil { tx.Rollback() } else { tx.Commit() }8 }()910 session, err := s.repo.GetSessionByUser(ctx, tx, userID)11 if err != nil {12 return nil, err13 }1415 life, err := s.repo.GetUserLife(ctx, tx, userID)16 if err != nil {17 return nil, err18 }1920 // 시간제 라이프가 있으면 회복 불필요21 timedCount, err := s.repo.CountActiveTimed(ctx, tx, userID)22 if err != nil {23 return nil, err24 }25 if timedCount > 0 {26 return &RecoverResponse{Current: life.Current, Max: session.MaxLife}, nil27 }2829 // lastRecoveryAt 기준 회복 가능량 계산30 elapsed := time.Since(life.LastRecoveryAt)31 recoverable := int(elapsed / RecoveryInterval)32 if recoverable <= 0 {33 return &RecoverResponse{Current: life.Current, Max: session.MaxLife}, nil34 }3536 // max 초과 검증37 if life.Current >= session.MaxLife {38 return nil, ErrAlreadyMaxLife39 }4041 life.Current = min(life.Current+recoverable, session.MaxLife)42 life.LastRecoveryAt = life.LastRecoveryAt.Add(43 time.Duration(recoverable) * RecoveryInterval,44 )45 if err := s.repo.SaveUserLife(ctx, tx, life); err != nil {46 return nil, err47 }4849 return &RecoverResponse{Current: life.Current, Max: session.MaxLife}, nil50}작성중입니다