Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: patch apps without internet #1114

Merged
merged 9 commits into from
Aug 11, 2023
31 changes: 28 additions & 3 deletions lib/services/github_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<ManagerAPI>();

final _cacheOptions = CacheOptions(
store: MemCacheStore(),
Expand Down Expand Up @@ -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<String, dynamic>? release =
await getPatchesRelease(repoName, version);
if (release != null) {
Expand All @@ -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,
);
}
}
Expand All @@ -224,10 +240,19 @@ class GithubAPI {
return null;
}

Future<List<Patch>> getPatches(String repoName, String version) async {
Future<List<Patch>> getPatches(
String repoName,
String version,
String url,
) async {
List<Patch> patches = [];
try {
final File? f = await getPatchesReleaseFile('.json', repoName, version);
final File? f = await getPatchesReleaseFile(
'.json',
repoName,
version,
url,
);
if (f != null) {
final List<dynamic> list = jsonDecode(f.readAsStringSync());
patches = list.map((patch) => Patch.fromJson(patch)).toList();
Expand Down
47 changes: 42 additions & 5 deletions lib/services/manager_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ class ManagerAPI {
await _prefs.setString('repoUrl', url);
}

String getPatchesDownloadURL(bool bundle) {
return _prefs.getString('patchesDownloadURL-$bundle') ?? '';
}

Future<void> setPatchesDownloadURL(String value, bool bundle) async {
await _prefs.setString('patchesDownloadURL-$bundle', value);
}

String getPatchesRepo() {
return _prefs.getString('patchesRepo') ?? defaultPatchesRepo;
}
Expand Down Expand Up @@ -119,6 +127,14 @@ class ManagerAPI {
await _prefs.setStringList('savedPatches-$packageName', patchesJson);
}

String getIntegrationsDownloadURL() {
return _prefs.getString('integrationsDownloadURL') ?? '';
}

Future<void> setIntegrationsDownloadURL(String value) async {
await _prefs.setString('integrationsDownloadURL', value);
}

List<Patch> getUsedPatches(String packageName) {
final List<String> patchesJson =
_prefs.getStringList('usedPatches-$packageName') ?? [];
Expand Down Expand Up @@ -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);
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -384,27 +409,39 @@ class ManagerAPI {
Future<String> 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<void> setCurrentPatchesVersion(String version) async {
await _prefs.setString('patchesVersion', version);
await setPatchesDownloadURL('', false);
await setPatchesDownloadURL('', true);
await downloadPatches();
}

Future<String> 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<void> setCurrentIntegrationsVersion(String version) async {
await _prefs.setString('integrationsVersion', version);
await setIntegrationsDownloadURL('');
await downloadIntegrations();
}

Future<List<PatchedApplication>> getAppsToRemove(
Expand Down
2 changes: 2 additions & 0 deletions lib/services/patcher_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class PatcherAPI {

Future<void> initialize() async {
await _loadPatches();
await _managerAPI.downloadPatches();
await _managerAPI.downloadIntegrations();
final Directory appCache = await getTemporaryDirectory();
_dataDir = await getExternalStorageDirectory() ?? appCache;
_tmpDir = Directory('${appCache.path}/patcher');
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/views/home/home_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
},
Expand Down Expand Up @@ -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()
Expand Down