137 lines
4.3 KiB
Dart
137 lines
4.3 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:crypto/crypto.dart' as crypto;
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
import 'Backend.dart';
|
|
import 'DebugHelper.dart';
|
|
import 'package:path/path.dart' as Path;
|
|
import 'package:http/http.dart' as http;
|
|
|
|
import 'FileHashEntry.dart';
|
|
class InstallHelper{
|
|
|
|
static String GetFilePath(int id) => Backend.prefs!.getString('${Backend.Games[id].name}_path') ?? '${Path.join(Backend.docPath!.path, Backend.Games[id].name)}';
|
|
|
|
static String GetValidationSaveKey(int id)=>'${Backend.Games[id].code}_localFileData';
|
|
static String? GetSavedValidationData(int id) => Backend.prefs!.getString(GetValidationSaveKey(id));
|
|
|
|
static Future<List<FileHashEntry>> GetMissingFiles(int gameId, {bool force = false}) async{
|
|
List<FileHashEntry> missingFiles = [];
|
|
Directory pathDir = Directory(GetFilePath(gameId));
|
|
|
|
List<FileHashEntry> localFiles = [];
|
|
bool usedLocalSave = false;
|
|
if(!force){
|
|
String? savedData =GetSavedValidationData(gameId);
|
|
if(savedData != null){
|
|
localFiles = FileHashEntry.listFromJson(savedData);
|
|
usedLocalSave=true;
|
|
}else{
|
|
localFiles = await getHashtable(pathDir);
|
|
}
|
|
}else{
|
|
localFiles = await getHashtable(pathDir);
|
|
}
|
|
//Get local hashtable
|
|
Debug.LogResponse(jsonEncode(localFiles), src:"local files");
|
|
//Write to file
|
|
if(!usedLocalSave){
|
|
String localFilesJson = FileHashEntry.listToJson(localFiles);
|
|
Backend.prefs!.setString(GetValidationSaveKey(gameId),localFilesJson);
|
|
if(kDebugMode) {
|
|
String hashFilePath = Path.join(pathDir.parent.path, "hashes.txt");
|
|
File writeJsonFile = File(hashFilePath);
|
|
writeJsonFile.writeAsString(localFilesJson);
|
|
Debug.Log("Wrote hash into ${hashFilePath}");
|
|
}
|
|
}
|
|
|
|
//Get remote hashtable
|
|
String link ='${Backend.API_ENDPOINT}${Backend.Games[gameId].code}/get_hashes.php';
|
|
var remoteHashResponse = (await http.post(Uri.parse(link)));
|
|
Debug.LogResponse(remoteHashResponse.body.toString(),src: link);
|
|
List<FileHashEntry> remoteList = FileHashEntry.listFromJson(remoteHashResponse.body.toString());
|
|
|
|
//Comapreeee
|
|
for(int i = 0; i <remoteList.length;i++) {
|
|
bool isLocalGood = false;
|
|
for (int j = 0; j < localFiles.length; j++) {
|
|
if (localFiles[j].file == remoteList[i].file) {
|
|
isLocalGood = localFiles[j].hash == remoteList[i].hash;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isLocalGood) {
|
|
missingFiles.add(remoteList[i]);
|
|
}
|
|
}
|
|
|
|
return missingFiles;
|
|
}
|
|
|
|
static Future<List<FileHashEntry>> getHashtable(Directory pathDir) async{
|
|
|
|
if(!pathDir.existsSync()){return [];}
|
|
List<FileSystemEntity> list =await pathDir.list(recursive: true).toList();
|
|
List<FileHashEntry> output = [];
|
|
|
|
for(int i =0; i < list.length; i++){
|
|
FileSystemEntity element = list[i];
|
|
File file = File(element.path);
|
|
if(await file.exists()) {
|
|
String hash = await calculateMD5SumAsyncWithCrypto(element.path);
|
|
int size = file.lengthSync();
|
|
output.add(FileHashEntry(element.path.replaceAll(pathDir.path, ''), hash, size));
|
|
// Debug.Log('${element.path}: ${hash}: ${size}');
|
|
}
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
static String DOWNLOAD_BIN_ROOT = "https://vps.playpoolstudios.com/metahunt/data/bin/";
|
|
|
|
static List<String> GetMissingFileLinks(List<FileHashEntry> missingList,int gameId){
|
|
List<String> output = [];
|
|
missingList.forEach((element) {
|
|
output.add(GetFileUrl(element.file, gameId));
|
|
});
|
|
|
|
return output;
|
|
}
|
|
|
|
static String GetFileUrl(String path, int id){
|
|
return '${DOWNLOAD_BIN_ROOT}${Backend.Games[id].code}${path.replaceAll('\\', '/')}';
|
|
}
|
|
|
|
static Future<String> calculateMD5SumAsyncWithCrypto(String filePath) async {
|
|
var ret = '';
|
|
var file = File(filePath);
|
|
if (await file.exists()) {
|
|
try {
|
|
var md5 = crypto.md5;
|
|
var hash = await md5.bind(file.openRead()).first;
|
|
ret = hash.toString();
|
|
// ret = base64.encode(hash.bytes);
|
|
} catch (exception) {
|
|
print('Unable to evaluate the MD5 sum :$exception');
|
|
return '';
|
|
}
|
|
} else {
|
|
print('`$filePath` does not exits so unable to evaluate its MD5 sum.');
|
|
return '';
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
static String GetExeFilePath(int i){
|
|
return Path.join(GetFilePath(i), Backend.Games[i].exeName);
|
|
}
|
|
}
|
|
|
|
|