// ignore_for_file: avoid_print import 'dart:io'; import 'package:dio/dio.dart'; import 'package:archive/archive.dart'; import 'package:naiyouwl/app/const/const.dart'; import 'package:path/path.dart' as path; final dio = Dio(); // https://github.com/dart-lang/sdk/issues/31610 final assetsPath = path.normalize(path.join(Platform.script.toFilePath(), '../../assets')); final binDir = Directory(path.join(assetsPath, 'bin')); final depDir = Directory(path.join(assetsPath, 'dep')); Future downloadLatestClashCore() async { const version = "v1.16.0"; final String clashCoreName = 'clash.meta-${ClashName.platform}-${ClashName.arch}-cgo-$version'; // Fetching release info from the GitHub API final info = await dio.get('https://api.github.com/repos/MetaCubeX/Clash.Meta/releases/tags/$version'); // Extracting the download URL from the API response based on the asset name final Map latest = (info.data['assets'] as List) .firstWhere((it) => (it['name'] as String).contains(clashCoreName)); final String downloadUrl = latest['browser_download_url']; //final String newName = 'clash-${ClashName.platform}-${ClashName.arch}'; final String name = clashCoreName; final tempFile = File(path.join(binDir.path, '$name.temp')); print('Downloading $name'); await dio.download(downloadUrl, tempFile.path); // Use the obtained download URL print('Download Success'); print('Unarchiving $name'); final tempBetys = await tempFile.readAsBytes(); if (name.contains('.gz')) { final bytes = GZipDecoder().decodeBytes(tempBetys); final String filePath = path.join(binDir.path, ClashName.name); await File(filePath).writeAsBytes(bytes); await Process.run('chmod', ['+x', filePath]); } else { final file = ZipDecoder().decodeBytes(tempBetys).first; await File(path.join(binDir.path, ClashName.name)).writeAsBytes(file.content); } await tempFile.delete(); print('Unarchiv Success'); } Future downloadAndUnarchiveService() async { // const String token = "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"; // 请确保不在公共代码中硬编码这个token final serviceName = 'ccore-service-${ClashName.platform}-${ClashName.arch}'; // "name" -> "ccore-service-darwin-amd64-v1.0.0.gz" //final newSericeName = "$serviceName-v1.0.0.gz"; // 获取GitHub release信息 // dio.options.headers["Authorization"] = "token $token"; final response = await dio.get('https://api.github.com/repos/alroyso/core-service/releases/latest'); final Map latest = (response.data['assets'] as List) .firstWhere((it) => (it['name'] as String).contains(serviceName)); final downloadUrl = latest['browser_download_url']; print('Downloading $downloadUrl'); final tempFile = File(path.join(binDir.path, '${latest['name']}.temp')); try { print(dio.options.headers); await dio.download(downloadUrl, tempFile.path); } catch (e){ print(e); return; } print('Download Success'); print('Unarchiving ${latest['name']}'); final tempBytes = await tempFile.readAsBytes(); if (latest['name'].contains('.gz')) { final bytes = GZipDecoder().decodeBytes(tempBytes); await File(path.join(binDir.path, serviceName)).writeAsBytes(bytes); final filePath = path.join(binDir.path, serviceName); await Process.run('chmod', ['+x', filePath]); } else { final file = ZipDecoder().decodeBytes(tempBytes).first; await File(path.join(binDir.path, file.name)).writeAsBytes(file.content); } await tempFile.delete(); print('Unarchive Success'); } Future downloadLatestClashService() async { final String serviceName = 'ccore-service-${ClashName.platform}-${ClashName.arch}'; // // final info = await dio.get('https://api.github.com/repos/alroyso/clash-for-flutter-service/releases/latest'); // // final Map latest = (info.data['assets'] as List).firstWhere((it) => (it['name'] as String).contains(serviceName)); // //https://github.com/alroyso/clash-for-flutter-service/releases/download/untagged-8273cca760b55d0725ab/naiyou-service-darwin-arm64-v1.0.1.gz // var verion = 'v1.0.1'; // final String name = 'naiyou-service-${ClashName.platform}-${ClashName.arch}-$verion.gz'; // final tempFile = File(path.join(binDir.path, '$name.temp')); // var url = "https://github.com/alroyso/clash-for-flutter-service/releases/tag/untagged-8273cca760b55d0725ab"; // print('Downloading $url/$name'); // dio.options.headers["Authorization"] = "token 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"; // await dio.download('$url/$name', tempFile.path); // print('Download Success'); // // print('Unarchiving $name'); // final tempBetys = await tempFile.readAsBytes(); // if (name.contains('.gz')) { // final bytes = GZipDecoder().decodeBytes(tempBetys); // final String filePath = path.join(binDir.path, serviceName); // await File(filePath).writeAsBytes(bytes); // await Process.run('chmod', ['+x', filePath]); // } else { // final file = ZipDecoder().decodeBytes(tempBetys).first; // await File(path.join(binDir.path, file.name)).writeAsBytes(file.content); // } final String filePath = path.join(binDir.path, serviceName); await Process.run('chmod', ['+x', filePath]); //await tempFile.delete(); print('Unarchiv Success'); } Future downloadCountryMmdb() async { print('Downloading Country.mmdb'); final String geoipFilePath = path.join(depDir.path, 'Country.mmdb'); await dio.download('https://github.com/Dreamacro/maxmind-geoip/releases/latest/download/Country.mmdb', geoipFilePath); print('Download Success'); } Future downloadWintun() async { print('Downloading Wintun'); final File wintunFile = File(path.join(depDir.path, 'wintun.zip.temp')); await dio.download('https://www.wintun.net/builds/wintun-0.14.1.zip', wintunFile.path); print('Download Success'); print('Unarchiving wintun.zip'); final files = ZipDecoder().decodeBytes(await wintunFile.readAsBytes()); final file = files.firstWhere((it) => it.name == 'wintun/bin/${ClashName.arch}/wintun.dll'); await File(path.join(depDir.path, 'wintun.dll')).writeAsBytes(file.content); await wintunFile.delete(); print('Unarchiv Success'); } void main() async { if (!(await binDir.exists())) await binDir.create(); if (!(await depDir.exists())) await depDir.create(); await downloadLatestClashCore(); await downloadAndUnarchiveService(); await downloadCountryMmdb(); if (Platform.isWindows) await downloadWintun(); }