feat(debug): 디버그 설정 서비스 추가

- 광고/IAP/무적 모드 토글
- 시간 스케일 조절
- SharedPreferences 기반 영속화
This commit is contained in:
JiWoong Sul
2026-01-16 20:08:59 +09:00
parent 77f3f1d46b
commit 28d3e53bab

View File

@@ -0,0 +1,180 @@
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:asciineverdie/src/core/engine/ad_service.dart';
import 'package:asciineverdie/src/core/engine/iap_service.dart';
/// 디버그 설정 서비스 (Phase 8)
///
/// 개발/테스트 중 사용하는 디버그 옵션을 통합 관리합니다.
/// kDebugMode에서만 활성화됩니다.
class DebugSettingsService {
DebugSettingsService._();
static DebugSettingsService? _instance;
/// 싱글톤 인스턴스
static DebugSettingsService get instance {
_instance ??= DebugSettingsService._();
return _instance!;
}
// ===========================================================================
// 상수
// ===========================================================================
static const String _keyAdEnabled = 'debug_ad_enabled';
static const String _keyIapSimulated = 'debug_iap_simulated';
static const String _keyOfflineHours = 'debug_offline_hours';
/// 오프라인 시간 시뮬레이션 옵션
static const List<int> offlineHoursOptions = [0, 1, 5, 10, 24];
// ===========================================================================
// 상태
// ===========================================================================
bool _isInitialized = false;
/// 광고 활성화 여부 (디버그 모드 전용)
bool _adEnabled = true;
/// IAP 구매 시뮬레이션 여부 (디버그 모드 전용)
bool _iapSimulated = false;
/// 오프라인 시간 시뮬레이션 (시간 단위)
int _offlineHours = 0;
// ===========================================================================
// 초기화
// ===========================================================================
/// 서비스 초기화 (저장된 설정 로드)
Future<void> initialize() async {
if (_isInitialized) return;
if (!kDebugMode) {
_isInitialized = true;
return;
}
final prefs = await SharedPreferences.getInstance();
_adEnabled = prefs.getBool(_keyAdEnabled) ?? true;
_iapSimulated = prefs.getBool(_keyIapSimulated) ?? false;
_offlineHours = prefs.getInt(_keyOfflineHours) ?? 0;
// 다른 서비스에 설정 동기화
_syncToServices();
_isInitialized = true;
debugPrint('[DebugSettings] Initialized: ad=$_adEnabled, '
'iap=$_iapSimulated, offline=$_offlineHours');
}
/// 설정을 다른 서비스에 동기화
void _syncToServices() {
AdService.instance.debugAdEnabled = _adEnabled;
IAPService.instance.debugIAPSimulated = _iapSimulated;
}
// ===========================================================================
// 디버그 모드 확인
// ===========================================================================
/// 디버그 모드 활성화 여부
bool get isDebugMode => kDebugMode;
// ===========================================================================
// 광고 설정
// ===========================================================================
/// 광고 활성화 여부
///
/// - true: 실제 광고 표시
/// - false: 광고 버튼 클릭 시 바로 보상 지급
bool get adEnabled => _adEnabled;
/// 광고 활성화 토글
Future<void> setAdEnabled(bool value) async {
if (!kDebugMode) return;
_adEnabled = value;
AdService.instance.debugAdEnabled = value;
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(_keyAdEnabled, value);
debugPrint('[DebugSettings] Ad enabled: $value');
}
// ===========================================================================
// IAP 설정
// ===========================================================================
/// IAP 구매 시뮬레이션 여부
///
/// - true: 유료 유저로 동작 (광고 제거됨)
/// - false: 무료 유저로 동작
bool get iapSimulated => _iapSimulated;
/// IAP 구매 시뮬레이션 토글
Future<void> setIapSimulated(bool value) async {
if (!kDebugMode) return;
_iapSimulated = value;
IAPService.instance.debugIAPSimulated = value;
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(_keyIapSimulated, value);
debugPrint('[DebugSettings] IAP simulated: $value');
}
// ===========================================================================
// 오프라인 시간 시뮬레이션
// ===========================================================================
/// 오프라인 시간 시뮬레이션 (시간 단위)
///
/// 복귀 보상 테스트용. 0이면 시뮬레이션 비활성화.
int get offlineHours => _offlineHours;
/// 오프라인 시간 시뮬레이션 설정
Future<void> setOfflineHours(int hours) async {
if (!kDebugMode) return;
_offlineHours = hours;
final prefs = await SharedPreferences.getInstance();
await prefs.setInt(_keyOfflineHours, hours);
debugPrint('[DebugSettings] Offline hours: $hours');
}
/// 시뮬레이션된 마지막 플레이 시간 계산
///
/// [actualLastPlayTime] 실제 마지막 플레이 시간
/// Returns: 시뮬레이션 적용된 마지막 플레이 시간
DateTime? getSimulatedLastPlayTime(DateTime? actualLastPlayTime) {
if (!kDebugMode || _offlineHours == 0) {
return actualLastPlayTime;
}
// 시뮬레이션: 현재 시간에서 offlineHours만큼 뺀 시간을 마지막 플레이 시간으로
return DateTime.now().subtract(Duration(hours: _offlineHours));
}
// ===========================================================================
// 전체 초기화
// ===========================================================================
/// 모든 디버그 설정 초기화
Future<void> resetAll() async {
if (!kDebugMode) return;
await setAdEnabled(true);
await setIapSimulated(false);
await setOfflineHours(0);
debugPrint('[DebugSettings] All settings reset');
}
}