From 3d9250881912c44e84b897d86f89723113e22ae9 Mon Sep 17 00:00:00 2001 From: xkeyC <3334969096@qq.com> Date: Sat, 24 Feb 2024 18:18:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=8E=E7=BD=91=E7=BB=9C=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/api/api.dart | 13 +++ lib/data/app_torrent_data.dart | 28 ++++++ lib/ui/home/downloads/downloads_ui.dart | 2 +- lib/ui/home/downloads/downloads_ui_model.dart | 2 +- lib/ui/tools/tools_ui_model.dart | 95 ++++++++++++------- 5 files changed, 105 insertions(+), 35 deletions(-) create mode 100644 lib/data/app_torrent_data.dart diff --git a/lib/api/api.dart b/lib/api/api.dart index 1f931aa..96ff9bc 100644 --- a/lib/api/api.dart +++ b/lib/api/api.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'package:starcitizen_doctor/common/conf/url_conf.dart'; import 'package:starcitizen_doctor/common/io/rs_http.dart'; import 'package:starcitizen_doctor/data/app_placard_data.dart'; +import 'package:starcitizen_doctor/data/app_torrent_data.dart'; import 'package:starcitizen_doctor/data/app_version_data.dart'; import 'package:starcitizen_doctor/data/countdown_festival_item_data.dart'; import 'package:starcitizen_doctor/data/sc_localization_data.dart'; @@ -50,6 +51,18 @@ class Api { return l; } + static Future> getAppTorrentDataList() async { + final data = await getRepoData("sc_doctor", "torrent.json"); + final dataJson = json.decode(data); + List l = []; + if (dataJson is List) { + for (var value in dataJson) { + l.add(AppTorrentData.fromJson(value)); + } + } + return l; + } + static Future getScServerStatus() async { final r = await RSHttp.getText( "https://status.robertsspaceindustries.com/index.json"); diff --git a/lib/data/app_torrent_data.dart b/lib/data/app_torrent_data.dart new file mode 100644 index 0000000..b2b05af --- /dev/null +++ b/lib/data/app_torrent_data.dart @@ -0,0 +1,28 @@ +/// name : "Data.p4k" +/// update_at : "2024-02-24 18:00" +/// url : "https://p4k.42kit.com/3.22.1-LIVE.9072370/Data.p4k.torrent" + +class AppTorrentData { + AppTorrentData({ + this.name, + this.updateAt, + this.url,}); + + AppTorrentData.fromJson(dynamic json) { + name = json['name']; + updateAt = json['update_at']; + url = json['url']; + } + String? name; + String? updateAt; + String? url; + + Map toJson() { + final map = {}; + map['name'] = name; + map['update_at'] = updateAt; + map['url'] = url; + return map; + } + +} \ No newline at end of file diff --git a/lib/ui/home/downloads/downloads_ui.dart b/lib/ui/home/downloads/downloads_ui.dart index 135c45b..ed6df7d 100644 --- a/lib/ui/home/downloads/downloads_ui.dart +++ b/lib/ui/home/downloads/downloads_ui.dart @@ -58,7 +58,7 @@ class DownloadsUI extends BaseUI { child: ListView.builder( itemBuilder: (BuildContext context, int index) { final (task, type, isFirstType) = model.getTaskAndType(index); - final nt = model.getTaskTypeAndName(task); + final nt = DownloadsUIModel.getTaskTypeAndName(task); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/ui/home/downloads/downloads_ui_model.dart b/lib/ui/home/downloads/downloads_ui_model.dart index 554ccf2..714e1b0 100644 --- a/lib/ui/home/downloads/downloads_ui_model.dart +++ b/lib/ui/home/downloads/downloads_ui_model.dart @@ -110,7 +110,7 @@ class DownloadsUIModel extends BaseUIModel { throw Exception("Index out of range or element is null"); } - MapEntry getTaskTypeAndName(Aria2Task task) { + static MapEntry getTaskTypeAndName(Aria2Task task) { if (task.bittorrent == null) { String uri = task.files?[0]['uris'][0]['uri'] as String; return MapEntry("url", uri.split('/').last); diff --git a/lib/ui/tools/tools_ui_model.dart b/lib/ui/tools/tools_ui_model.dart index 2201a44..ab29dbd 100644 --- a/lib/ui/tools/tools_ui_model.dart +++ b/lib/ui/tools/tools_ui_model.dart @@ -4,6 +4,8 @@ import 'dart:io'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/foundation.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:starcitizen_doctor/api/analytics.dart'; +import 'package:starcitizen_doctor/api/api.dart'; import 'package:starcitizen_doctor/base/ui_model.dart'; import 'package:starcitizen_doctor/common/helper/log_helper.dart'; import 'package:starcitizen_doctor/common/helper/system_helper.dart'; @@ -54,7 +56,7 @@ class ToolsUIModel extends BaseUIModel { _ToolsItemData( "p4k_downloader", "P4K 分流下载 / 修复", - "使用星际公民中文百科提供的分流下载服务。 \n\n资源有限,请勿滥用。请确保您的硬盘拥有至少大于 200G 的可用空间。", + "使用星际公民中文百科提供的分流下载服务,可用于下载或修复 p4k。 \n资源有限,请勿滥用。", const Icon(FontAwesomeIcons.download, size: 28), onTap: _downloadP4k, ), @@ -354,49 +356,76 @@ class ToolsUIModel extends BaseUIModel { context!, "P4k 是星际公民的核心游戏文件,高达 100GB+,盒子提供的离线下载是为了帮助一些p4k文件下载超级慢的用户 或用于修复官方启动器无法修复的 p4k 文件。" "\n\n接下来会弹窗询问您保存位置(可以选择星际公民文件夹也可以选择别处),下载完成后请确保 P4K 文件夹位于 LIVE 文件夹内,之后使用星际公民启动器校验更新即可。"); - // AnalyticsApi.touch("p4k_download"); - - final userSelect = await FilePicker.platform.saveFile( - initialDirectory: savePath, fileName: fileName, lockParentWindow: true); - if (userSelect == null) { - return; - } - // 不再需要删除旧 p4k,直接在其基础上校验 - // final f = File(userSelect); - // if (await f.exists()) { - // await f.delete(); - // } - savePath = userSelect; - dPrint(savePath); - notifyListeners(); - if (savePath.endsWith("\\$fileName")) { - savePath = savePath.substring(0, savePath.length - fileName.length - 1); - } - - _working = true; - final btData = await handleError(() => RSHttp.get( - "https://p4k.42kit.com/3.22.1-LIVE.9072370/Data.p4k.torrent")); - if (btData == null || btData.data == null) { - _working = false; - return; - } - - /// 启动模块 - await handleError(() => Aria2cManager.launchDaemon()); - final aria2c = Aria2cManager.getClient(); try { + working = true; + notifyListeners(); + + await Aria2cManager.launchDaemon(); + final aria2c = Aria2cManager.getClient(); + + // check download task list + for (var value in [ + ...await aria2c.tellActive(), + ...await aria2c.tellWaiting(0, 100000) + ]) { + final t = DownloadsUIModel.getTaskTypeAndName(value); + if (t.key == "torrent" && t.value.contains("Data.p4k")) { + showToast(context!, "已经有一个p4k下载任务正在进行中,请前往下载管理器查看!"); + working = false; + return; + } + } + + var torrentUrl = ""; + final l = await Api.getAppTorrentDataList(); + for (var torrent in l) { + if (torrent.name == "Data.p4k") { + torrentUrl = torrent.url!; + } + } + if (torrentUrl == "") { + working = false; + showToast(context!, "功能维护中,请稍后重试!"); + return; + } + + final userSelect = await FilePicker.platform.saveFile( + initialDirectory: savePath, + fileName: fileName, + lockParentWindow: true); + if (userSelect == null) { + working = false; + return; + } + + savePath = userSelect; + dPrint(savePath); + notifyListeners(); + if (savePath.endsWith("\\$fileName")) { + savePath = savePath.substring(0, savePath.length - fileName.length - 1); + } + + final btData = await handleError(() => RSHttp.get(torrentUrl)); + if (btData == null || btData.data == null) { + working = false; + return; + } final b64Str = base64Encode(btData.data!); + final gid = await aria2c.addTorrent(b64Str, extraParams: {"dir": savePath}); - _working = false; + working = false; dPrint("Aria2cManager.aria2c.addUri resp === $gid"); await aria2c.saveSession(); + AnalyticsApi.touch("p4k_download"); + BaseUIContainer( uiCreate: () => DownloadsUI(), modelCreate: () => DownloadsUIModel()).push(context!); } catch (e) { - showToast(context!, "初始化失败!"); + working = false; + showToast(context!, "初始化失败!: $e"); } // launchUrlString("https://citizenwiki.cn/SC%E6%B1%89%E5%8C%96%E7%9B%92%E5%AD%90#%E5%88%86%E6%B5%81%E4%B8%8B%E8%BD%BD%E6%95%99%E7%A8%8B"); }