From f90f6e81ee7614aacbcbb96175cb8f2c10947153 Mon Sep 17 00:00:00 2001 From: aAbed <39409020+TheAabedKhan@users.noreply.github.com> Date: Fri, 11 Aug 2023 06:56:19 +0545 Subject: [PATCH] feat: patch apps without internet (#1114) --- lib/services/github_api.dart | 31 ++++++++++-- lib/services/manager_api.dart | 47 +++++++++++++++++-- lib/services/patcher_api.dart | 2 + lib/ui/views/home/home_viewmodel.dart | 2 +- .../settings_manage_sources.dart | 2 + 5 files changed, 75 insertions(+), 9 deletions(-) diff --git a/lib/services/github_api.dart b/lib/services/github_api.dart index c846d272..de8c160b 100644 --- a/lib/services/github_api.dart +++ b/lib/services/github_api.dart @@ -6,12 +6,14 @@ import 'package:dio_cache_interceptor/dio_cache_interceptor.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:injectable/injectable.dart'; +import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/services/manager_api.dart'; @lazySingleton class GithubAPI { late Dio _dio = Dio(); + late final ManagerAPI _managerAPI = locator(); final _cacheOptions = CacheOptions( store: MemCacheStore(), @@ -201,8 +203,14 @@ class GithubAPI { String extension, String repoName, String version, + String url, ) async { try { + if (url.isNotEmpty) { + return await DefaultCacheManager().getSingleFile( + url, + ); + } final Map? release = await getPatchesRelease(repoName, version); if (release != null) { @@ -211,8 +219,16 @@ class GithubAPI { (asset) => (asset['name'] as String).endsWith(extension), ); if (asset != null) { + final String downloadUrl = asset['browser_download_url']; + if (extension == '.apk') { + _managerAPI.setIntegrationsDownloadURL(downloadUrl); + } else if (extension == '.json') { + _managerAPI.setPatchesDownloadURL(downloadUrl, false); + } else { + _managerAPI.setPatchesDownloadURL(downloadUrl, true); + } return await DefaultCacheManager().getSingleFile( - asset['browser_download_url'], + downloadUrl, ); } } @@ -224,10 +240,19 @@ class GithubAPI { return null; } - Future> getPatches(String repoName, String version) async { + Future> getPatches( + String repoName, + String version, + String url, + ) async { List patches = []; try { - final File? f = await getPatchesReleaseFile('.json', repoName, version); + final File? f = await getPatchesReleaseFile( + '.json', + repoName, + version, + url, + ); if (f != null) { final List list = jsonDecode(f.readAsStringSync()); patches = list.map((patch) => Patch.fromJson(patch)).toList(); diff --git a/lib/services/manager_api.dart b/lib/services/manager_api.dart index 28b2b8fa..d334eba2 100644 --- a/lib/services/manager_api.dart +++ b/lib/services/manager_api.dart @@ -76,6 +76,14 @@ class ManagerAPI { await _prefs.setString('repoUrl', url); } + String getPatchesDownloadURL(bool bundle) { + return _prefs.getString('patchesDownloadURL-$bundle') ?? ''; + } + + Future setPatchesDownloadURL(String value, bool bundle) async { + await _prefs.setString('patchesDownloadURL-$bundle', value); + } + String getPatchesRepo() { return _prefs.getString('patchesRepo') ?? defaultPatchesRepo; } @@ -119,6 +127,14 @@ class ManagerAPI { await _prefs.setStringList('savedPatches-$packageName', patchesJson); } + String getIntegrationsDownloadURL() { + return _prefs.getString('integrationsDownloadURL') ?? ''; + } + + Future setIntegrationsDownloadURL(String value) async { + await _prefs.setString('integrationsDownloadURL', value); + } + List getUsedPatches(String packageName) { final List patchesJson = _prefs.getStringList('usedPatches-$packageName') ?? []; @@ -260,7 +276,12 @@ class ManagerAPI { try { final String repoName = getPatchesRepo(); final String currentVersion = await getCurrentPatchesVersion(); - return await _githubAPI.getPatches(repoName, currentVersion); + final String url = getPatchesDownloadURL(false); + return await _githubAPI.getPatches( + repoName, + currentVersion, + url, + ); } on Exception catch (e) { if (kDebugMode) { print(e); @@ -273,10 +294,12 @@ class ManagerAPI { try { final String repoName = getPatchesRepo(); final String currentVersion = await getCurrentPatchesVersion(); + final String url = getPatchesDownloadURL(true); return await _githubAPI.getPatchesReleaseFile( '.jar', repoName, currentVersion, + url, ); } on Exception catch (e) { if (kDebugMode) { @@ -290,10 +313,12 @@ class ManagerAPI { try { final String repoName = getIntegrationsRepo(); final String currentVersion = await getCurrentIntegrationsVersion(); + final String url = getIntegrationsDownloadURL(); return await _githubAPI.getPatchesReleaseFile( '.apk', repoName, currentVersion, + url, ); } on Exception catch (e) { if (kDebugMode) { @@ -384,27 +409,39 @@ class ManagerAPI { Future getCurrentPatchesVersion() async { patchesVersion = _prefs.getString('patchesVersion') ?? '0.0.0'; if (patchesVersion == '0.0.0' || isPatchesAutoUpdate()) { - patchesVersion = await getLatestPatchesVersion() ?? '0.0.0'; - await setCurrentPatchesVersion(patchesVersion!); + final String newPatchesVersion = + await getLatestPatchesVersion() ?? '0.0.0'; + if (patchesVersion != newPatchesVersion && newPatchesVersion != '0.0.0') { + await setCurrentPatchesVersion(newPatchesVersion); + } } return patchesVersion!; } Future setCurrentPatchesVersion(String version) async { await _prefs.setString('patchesVersion', version); + await setPatchesDownloadURL('', false); + await setPatchesDownloadURL('', true); + await downloadPatches(); } Future getCurrentIntegrationsVersion() async { integrationsVersion = _prefs.getString('integrationsVersion') ?? '0.0.0'; if (integrationsVersion == '0.0.0' || isPatchesAutoUpdate()) { - integrationsVersion = await getLatestIntegrationsVersion() ?? '0.0.0'; - await setCurrentIntegrationsVersion(integrationsVersion!); + final String newIntegrationsVersion = + await getLatestIntegrationsVersion() ?? '0.0.0'; + if (integrationsVersion != newIntegrationsVersion && + newIntegrationsVersion != '0.0.0') { + await setCurrentIntegrationsVersion(newIntegrationsVersion); + } } return integrationsVersion!; } Future setCurrentIntegrationsVersion(String version) async { await _prefs.setString('integrationsVersion', version); + await setIntegrationsDownloadURL(''); + await downloadIntegrations(); } Future> getAppsToRemove( diff --git a/lib/services/patcher_api.dart b/lib/services/patcher_api.dart index c449cbc5..dfaaf3ec 100644 --- a/lib/services/patcher_api.dart +++ b/lib/services/patcher_api.dart @@ -30,6 +30,8 @@ class PatcherAPI { Future initialize() async { await _loadPatches(); + await _managerAPI.downloadPatches(); + await _managerAPI.downloadIntegrations(); final Directory appCache = await getTemporaryDirectory(); _dataDir = await getExternalStorageDirectory() ?? appCache; _tmpDir = Directory('${appCache.path}/patcher'); diff --git a/lib/ui/views/home/home_viewmodel.dart b/lib/ui/views/home/home_viewmodel.dart index e2ce5125..cfc99e66 100644 --- a/lib/ui/views/home/home_viewmodel.dart +++ b/lib/ui/views/home/home_viewmodel.dart @@ -256,9 +256,9 @@ class HomeViewModel extends BaseViewModel { final String integrationsVersion = await _managerAPI.getLatestIntegrationsVersion() ?? '0.0.0'; if (patchesVersion != '0.0.0' && integrationsVersion != '0.0.0') { - _toast.showBottom('homeView.downloadedMessage'); await _managerAPI.setCurrentPatchesVersion(patchesVersion); await _managerAPI.setCurrentIntegrationsVersion(integrationsVersion); + _toast.showBottom('homeView.downloadedMessage'); forceRefresh(context); } else { _toast.showBottom('homeView.errorDownloadMessage'); diff --git a/lib/ui/views/settings/settingsFragment/settings_manage_sources.dart b/lib/ui/views/settings/settingsFragment/settings_manage_sources.dart index 97dd35be..76e3171b 100644 --- a/lib/ui/views/settings/settingsFragment/settings_manage_sources.dart +++ b/lib/ui/views/settings/settingsFragment/settings_manage_sources.dart @@ -129,6 +129,7 @@ class SManageSources extends BaseViewModel { '${_orgIntSourceController.text.trim()}/${_intSourceController.text.trim()}', ); _managerAPI.setCurrentPatchesVersion('0.0.0'); + _managerAPI.setCurrentIntegrationsVersion('0.0.0'); _toast.showBottom('settingsView.restartAppForChanges'); Navigator.of(context).pop(); }, @@ -158,6 +159,7 @@ class SManageSources extends BaseViewModel { _managerAPI.setPatchesRepo(''); _managerAPI.setIntegrationsRepo(''); _managerAPI.setCurrentPatchesVersion('0.0.0'); + _managerAPI.setCurrentIntegrationsVersion('0.0.0'); _toast.showBottom('settingsView.restartAppForChanges'); Navigator.of(context) ..pop()