feat(statistics): 게임 통계 시스템 추가
- GameStatistics 모델 (전투, 퀘스트, 아이템 통계) - StatisticsStorage 영구 저장 - StatisticsDialog UI
This commit is contained in:
126
lib/src/core/storage/statistics_storage.dart
Normal file
126
lib/src/core/storage/statistics_storage.dart
Normal file
@@ -0,0 +1,126 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:askiineverdie/src/core/model/game_statistics.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
/// 게임 통계 저장소 (Statistics Storage)
|
||||
///
|
||||
/// 누적 통계 데이터 저장/로드 관리
|
||||
class StatisticsStorage {
|
||||
StatisticsStorage();
|
||||
|
||||
static const String _fileName = 'game_statistics.json';
|
||||
|
||||
Directory? _storageDir;
|
||||
|
||||
Future<Directory> _getStorageDir() async {
|
||||
if (_storageDir != null) return _storageDir!;
|
||||
_storageDir = await getApplicationSupportDirectory();
|
||||
return _storageDir!;
|
||||
}
|
||||
|
||||
File _getFile(Directory dir) {
|
||||
return File('${dir.path}/$_fileName');
|
||||
}
|
||||
|
||||
/// 누적 통계 로드
|
||||
Future<CumulativeStatistics> loadCumulative() async {
|
||||
try {
|
||||
final dir = await _getStorageDir();
|
||||
final file = _getFile(dir);
|
||||
|
||||
if (!await file.exists()) {
|
||||
return CumulativeStatistics.empty();
|
||||
}
|
||||
|
||||
final content = await file.readAsString();
|
||||
final json = jsonDecode(content) as Map<String, dynamic>;
|
||||
|
||||
// cumulative 키가 있으면 해당 데이터 사용
|
||||
if (json.containsKey('cumulative')) {
|
||||
return CumulativeStatistics.fromJson(
|
||||
json['cumulative'] as Map<String, dynamic>,
|
||||
);
|
||||
}
|
||||
|
||||
// 직접 CumulativeStatistics JSON인 경우
|
||||
return CumulativeStatistics.fromJson(json);
|
||||
} catch (e) {
|
||||
// 파일이 없거나 손상된 경우 빈 통계 반환
|
||||
return CumulativeStatistics.empty();
|
||||
}
|
||||
}
|
||||
|
||||
/// 누적 통계 저장
|
||||
Future<bool> saveCumulative(CumulativeStatistics stats) async {
|
||||
try {
|
||||
final dir = await _getStorageDir();
|
||||
final file = _getFile(dir);
|
||||
|
||||
final json = {
|
||||
'version': 1,
|
||||
'lastUpdated': DateTime.now().toIso8601String(),
|
||||
'cumulative': stats.toJson(),
|
||||
};
|
||||
|
||||
final content = const JsonEncoder.withIndent(' ').convert(json);
|
||||
await file.writeAsString(content);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 세션 종료 시 누적 통계 업데이트
|
||||
Future<bool> mergeSession(SessionStatistics session) async {
|
||||
final current = await loadCumulative();
|
||||
final updated = current.mergeSession(session);
|
||||
return saveCumulative(updated);
|
||||
}
|
||||
|
||||
/// 최고 레벨 업데이트
|
||||
Future<bool> updateHighestLevel(int level) async {
|
||||
final current = await loadCumulative();
|
||||
if (level <= current.highestLevel) return true;
|
||||
final updated = current.updateHighestLevel(level);
|
||||
return saveCumulative(updated);
|
||||
}
|
||||
|
||||
/// 최대 골드 업데이트
|
||||
Future<bool> updateHighestGold(int gold) async {
|
||||
final current = await loadCumulative();
|
||||
if (gold <= current.highestGoldHeld) return true;
|
||||
final updated = current.updateHighestGold(gold);
|
||||
return saveCumulative(updated);
|
||||
}
|
||||
|
||||
/// 새 게임 시작 기록
|
||||
Future<bool> recordGameStart() async {
|
||||
final current = await loadCumulative();
|
||||
final updated = current.recordGameStart();
|
||||
return saveCumulative(updated);
|
||||
}
|
||||
|
||||
/// 게임 클리어 기록
|
||||
Future<bool> recordGameComplete() async {
|
||||
final current = await loadCumulative();
|
||||
final updated = current.recordGameComplete();
|
||||
return saveCumulative(updated);
|
||||
}
|
||||
|
||||
/// 통계 초기화 (테스트용)
|
||||
Future<bool> clear() async {
|
||||
try {
|
||||
final dir = await _getStorageDir();
|
||||
final file = _getFile(dir);
|
||||
|
||||
if (await file.exists()) {
|
||||
await file.delete();
|
||||
}
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user