104 lines
2.9 KiB
Dart
104 lines
2.9 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:path/path.dart' as p;
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
|
import '../game/runtime_options.dart';
|
|
import 'game_package.dart';
|
|
import 'game_package_manifest.dart';
|
|
|
|
class StablePackageStore {
|
|
const StablePackageStore({
|
|
RuntimeOptions runtimeOptions = const RuntimeOptions(),
|
|
}) : _runtimeOptions = runtimeOptions;
|
|
|
|
final RuntimeOptions _runtimeOptions;
|
|
|
|
Future<Directory> cacheRoot() async {
|
|
final support = await getApplicationSupportDirectory();
|
|
final root = Directory(p.join(support.path, 'flame_lua_packages'));
|
|
root.createSync(recursive: true);
|
|
return root;
|
|
}
|
|
|
|
Future<Directory> versionDirectory(String gameId, String version) async {
|
|
final root = await cacheRoot();
|
|
return Directory(p.join(root.path, gameId, version));
|
|
}
|
|
|
|
Future<void> markStable(GamePackage package) async {
|
|
if (package.source != GamePackageSource.file) {
|
|
return;
|
|
}
|
|
final marker = await _markerFile(package.manifest.gameId);
|
|
marker.parent.createSync(recursive: true);
|
|
final previous = await stablePackage(package.manifest.gameId);
|
|
final data = {
|
|
'current': package.rootPath,
|
|
if (previous != null && previous.rootPath != package.rootPath)
|
|
'previous': previous.rootPath,
|
|
};
|
|
final temporary = File('${marker.path}.tmp');
|
|
temporary.writeAsStringSync(
|
|
const JsonEncoder.withIndent(' ').convert(data),
|
|
);
|
|
if (marker.existsSync()) {
|
|
marker.deleteSync();
|
|
}
|
|
temporary.renameSync(marker.path);
|
|
}
|
|
|
|
Future<GamePackage?> stablePackage(String gameId) async {
|
|
final data = await _readMarker(gameId);
|
|
return _packageFromPath(data?['current']);
|
|
}
|
|
|
|
Future<GamePackage?> previousStablePackage(String gameId) async {
|
|
final data = await _readMarker(gameId);
|
|
return _packageFromPath(data?['previous']);
|
|
}
|
|
|
|
Future<File> _markerFile(String gameId) async {
|
|
final root = await cacheRoot();
|
|
return File(p.join(root.path, gameId, 'stable.json'));
|
|
}
|
|
|
|
Future<Map<String, Object?>?> _readMarker(String gameId) async {
|
|
final marker = await _markerFile(gameId);
|
|
if (!marker.existsSync()) {
|
|
return null;
|
|
}
|
|
final source = await marker.readAsString();
|
|
if (source.trim().isEmpty) {
|
|
return null;
|
|
}
|
|
try {
|
|
final value = jsonDecode(source);
|
|
if (value is Map) {
|
|
return Map<String, Object?>.from(value);
|
|
}
|
|
} catch (_) {
|
|
return null;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
GamePackage? _packageFromPath(Object? pathValue) {
|
|
if (pathValue is! String || pathValue.isEmpty) {
|
|
return null;
|
|
}
|
|
final manifestFile = File(p.join(pathValue, 'manifest.json'));
|
|
if (!manifestFile.existsSync()) {
|
|
return null;
|
|
}
|
|
return GamePackage.file(
|
|
rootPath: pathValue,
|
|
manifest: GamePackageManifest.fromJsonString(
|
|
manifestFile.readAsStringSync(),
|
|
),
|
|
runtimeLuaRoot: _runtimeOptions.runtimeLuaRoot,
|
|
);
|
|
}
|
|
}
|