mirror of
https://ghfast.top/https://github.com/StarCitizenToolBox/app.git
synced 2025-06-28 05:34:45 +08:00
feat: app full l10n support
This commit is contained in:
@ -25,13 +25,14 @@ class AboutUI extends HookConsumerWidget {
|
||||
const SizedBox(height: 32),
|
||||
Image.asset("assets/app_logo.png", width: 128, height: 128),
|
||||
const SizedBox(height: 6),
|
||||
const Text(
|
||||
"SC汉化盒子 V${ConstConf.appVersion} ${ConstConf.isMSE ? "" : " +Dev"}",
|
||||
style: TextStyle(fontSize: 18)),
|
||||
Text(
|
||||
S.current.app_index_version_info(
|
||||
ConstConf.appVersion, ConstConf.isMSE ? "" : " Dev"),
|
||||
style: const TextStyle(fontSize: 18)),
|
||||
const SizedBox(height: 12),
|
||||
Button(
|
||||
onPressed: () => _onCheckUpdate(context, ref),
|
||||
child: Padding(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: Text(S.current.about_check_update),
|
||||
)),
|
||||
@ -45,7 +46,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
"不仅仅是汉化!\n\nSC汉化盒子是你探索宇宙的好帮手,我们致力于为各位公民解决游戏中的常见问题,并为社区汉化、性能调优、常用网站汉化 等操作提供便利。",
|
||||
S.current.about_app_description,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: Colors.white.withOpacity(.9)),
|
||||
),
|
||||
@ -172,8 +173,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
static const tipTextEN =
|
||||
"This is an unofficial Star Citizen fan-made tools, not affiliated with the Cloud Imperium group of companies. All content on this Software not authored by its host or users are property of their respective owners. \nStar Citizen®, Roberts Space Industries® and Cloud Imperium® are registered trademarks of Cloud Imperium Rights LLC.";
|
||||
|
||||
static const tipTextCN =
|
||||
"这是一个非官方的星际公民工具,不隶属于 Cloud Imperium 公司集团。 本软件中非由其主机或用户创作的所有内容均为其各自所有者的财产。 \nStar Citizen®、Roberts Space Industries® 和 Cloud Imperium® 是 Cloud Imperium Rights LLC 的注册商标。";
|
||||
static String get tipTextCN => S.current.about_disclaimer;
|
||||
|
||||
Widget makeAnalyticsWidget(BuildContext context) {
|
||||
return LoadingWidget(
|
||||
@ -239,7 +239,8 @@ class AboutUI extends HookConsumerWidget {
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
Text(" ${name == "firstLaunch" ? "位" : "次"}")
|
||||
Text(
|
||||
" ${name == "firstLaunch" ? S.current.about_analytics_units_user : S.current.about_analytics_units_times}"),
|
||||
],
|
||||
),
|
||||
],
|
||||
@ -260,4 +261,4 @@ class AboutUI extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,8 +99,7 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
|
||||
final ok = await showConfirmDialogs(
|
||||
context,
|
||||
S.current.home_action_q_auto_password_fill_prompt,
|
||||
const Text(
|
||||
"盒子将使用 PIN 与 Windows 凭据加密保存您的密码,密码只存储在您的设备中。\n\n当下次登录需要输入密码时,您只需授权PIN即可自动填充登录。"));
|
||||
Text(S.current.home_login_info_password_encryption_notice));
|
||||
if (ok == true) {
|
||||
if (await _localAuth.authenticate(
|
||||
localizedReason:
|
||||
@ -131,8 +130,9 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
|
||||
final ok = await showConfirmDialogs(
|
||||
context,
|
||||
S.current.home_login_info_game_version_outdated,
|
||||
Text(
|
||||
"RSI 服务器报告版本号:${releaseInfo?["versionLabel"]} \n\n本地版本号:${buildInfo["RequestedP4ChangeNum"]} \n\n建议使用 RSI Launcher 更新游戏!"),
|
||||
Text(S.current.home_login_info_rsi_server_report(
|
||||
releaseInfo?["versionLabel"],
|
||||
buildInfo["RequestedP4ChangeNum"])),
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width * .4),
|
||||
cancel: S.current.home_login_info_action_ignore);
|
||||
@ -165,10 +165,9 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
|
||||
final ok = await showConfirmDialogs(
|
||||
context,
|
||||
S.current.home_login_action_title_box_one_click_launch,
|
||||
const Text(
|
||||
"本功能可以帮您更加便利的启动游戏。\n\n为确保账户安全 ,本功能使用汉化浏览器保留登录状态,且不会保存您的密码信息(除非你启用了自动填充功能)。"
|
||||
"\n\n使用此功能登录账号时请确保您的 SC汉化盒子 是从可信任的来源下载。",
|
||||
style: TextStyle(fontSize: 16),
|
||||
Text(
|
||||
S.current.home_login_info_one_click_launch_description,
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width * .6));
|
||||
@ -183,8 +182,8 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
|
||||
}
|
||||
if (!await WebviewWindow.isWebviewAvailable()) {
|
||||
if (!context.mounted) return;
|
||||
await showToast(context,
|
||||
S.current.home_login_action_title_need_webview2_runtime);
|
||||
await showToast(
|
||||
context, S.current.home_login_action_title_need_webview2_runtime);
|
||||
if (!context.mounted) return;
|
||||
await launchUrlString(
|
||||
"https://developer.microsoft.com/en-us/microsoft-edge/webview2/");
|
||||
|
@ -24,13 +24,17 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
const SizedBox(width: 24),
|
||||
const SizedBox(width: 12),
|
||||
for (final item in <MapEntry<String, IconData>, String>{
|
||||
const MapEntry("settings", FluentIcons.settings): S.current.downloader_speed_limit_settings,
|
||||
const MapEntry("settings", FluentIcons.settings):
|
||||
S.current.downloader_speed_limit_settings,
|
||||
if (state.tasks.isNotEmpty)
|
||||
const MapEntry("pause_all", FluentIcons.pause): S.current.downloader_action_pause_all,
|
||||
const MapEntry("pause_all", FluentIcons.pause):
|
||||
S.current.downloader_action_pause_all,
|
||||
if (state.waitingTasks.isNotEmpty)
|
||||
const MapEntry("resume_all", FluentIcons.download): S.current.downloader_action_resume_all,
|
||||
const MapEntry("resume_all", FluentIcons.download):
|
||||
S.current.downloader_action_resume_all,
|
||||
if (state.tasks.isNotEmpty || state.waitingTasks.isNotEmpty)
|
||||
const MapEntry("cancel_all", FluentIcons.cancel): S.current.downloader_action_cancel_all,
|
||||
const MapEntry("cancel_all", FluentIcons.cancel):
|
||||
S.current.downloader_action_cancel_all,
|
||||
}.entries)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 6, right: 6),
|
||||
@ -119,7 +123,9 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
"总大小:${FileSize.getSize(task.totalLength ?? 0)}",
|
||||
S.current.downloader_info_total_size(
|
||||
FileSize.getSize(
|
||||
task.totalLength ?? 0)),
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
@ -127,17 +133,22 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
task.verifiedLength != null &&
|
||||
task.verifiedLength != 0)
|
||||
Text(
|
||||
"校验中...(${FileSize.getSize(task.verifiedLength)})",
|
||||
S.current.downloader_info_verifying(
|
||||
FileSize.getSize(
|
||||
task.verifiedLength)),
|
||||
style: const TextStyle(fontSize: 14),
|
||||
)
|
||||
else if (task.status == "active")
|
||||
Text(
|
||||
"下载中... (${((task.completedLength ?? 0) * 100 / (task.totalLength ?? 1)).toStringAsFixed(4)}%)")
|
||||
Text(S.current
|
||||
.downloader_info_downloading(
|
||||
((task.completedLength ?? 0) *
|
||||
100 /
|
||||
(task.totalLength ?? 1))
|
||||
.toStringAsFixed(4)))
|
||||
else
|
||||
Text(
|
||||
"状态:${model.statusMap[task.status]}",
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
Text(S.current.downloader_info_status(
|
||||
model.statusMap[task.status] ??
|
||||
"Unknown")),
|
||||
const SizedBox(width: 24),
|
||||
if (task.status == "active" &&
|
||||
task.verifiedLength == null)
|
||||
@ -151,10 +162,10 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"已上传:${FileSize.getSize(task.uploadLength)}"),
|
||||
Text(
|
||||
"已下载:${FileSize.getSize(task.completedLength)}"),
|
||||
Text(S.current.downloader_info_uploaded(
|
||||
FileSize.getSize(task.uploadLength))),
|
||||
Text(S.current.downloader_info_downloaded(
|
||||
FileSize.getSize(task.completedLength))),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 18),
|
||||
@ -173,20 +184,23 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
closeAfterClick: false,
|
||||
title: Padding(
|
||||
padding: const EdgeInsets.all(3),
|
||||
child: Text(S.current.downloader_action_options),
|
||||
child:
|
||||
Text(S.current.downloader_action_options),
|
||||
),
|
||||
items: [
|
||||
if (task.status == "paused")
|
||||
MenuFlyoutItem(
|
||||
leading:
|
||||
const Icon(FluentIcons.download),
|
||||
text: Text(S.current.downloader_action_continue_download),
|
||||
text: Text(S.current
|
||||
.downloader_action_continue_download),
|
||||
onPressed: () =>
|
||||
model.resumeTask(task.gid))
|
||||
else if (task.status == "active")
|
||||
MenuFlyoutItem(
|
||||
leading: const Icon(FluentIcons.pause),
|
||||
text: Text(S.current.downloader_action_pause_download),
|
||||
text: Text(S.current
|
||||
.downloader_action_pause_download),
|
||||
onPressed: () =>
|
||||
model.pauseTask(task.gid)),
|
||||
const MenuFlyoutSeparator(),
|
||||
@ -195,7 +209,8 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
FluentIcons.chrome_close,
|
||||
size: 14,
|
||||
),
|
||||
text: Text(S.current.downloader_action_cancel_download),
|
||||
text: Text(S.current
|
||||
.downloader_action_cancel_download),
|
||||
onPressed: () =>
|
||||
model.cancelTask(context, task.gid)),
|
||||
MenuFlyoutItem(
|
||||
@ -231,10 +246,9 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
"下载: ${FileSize.getSize(state.globalStat?.downloadSpeed ?? 0)}/s 上传:${FileSize.getSize(state.globalStat?.uploadSpeed ?? 0)}/s",
|
||||
style: const TextStyle(fontSize: 12),
|
||||
)
|
||||
Text(S.current.downloader_info_download_upload_speed(
|
||||
FileSize.getSize(state.globalStat?.downloadSpeed ?? 0),
|
||||
FileSize.getSize(state.globalStat?.uploadSpeed ?? 0)))
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -243,4 +257,4 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
),
|
||||
useBodyContainer: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,9 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
||||
return;
|
||||
case "cancel_all":
|
||||
final userOK = await showConfirmDialogs(
|
||||
context, "确认取消全部任务?", Text(S.current.downloader_info_manual_file_deletion_note));
|
||||
context,
|
||||
S.current.downloader_action_confirm_cancel_all_tasks,
|
||||
Text(S.current.downloader_info_manual_file_deletion_note));
|
||||
if (userOK == true) {
|
||||
if (!aria2cState.isRunning) return;
|
||||
try {
|
||||
@ -170,7 +172,9 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
||||
if (gid != null) {
|
||||
if (!context.mounted) return;
|
||||
final ok = await showConfirmDialogs(
|
||||
context, "确认取消下载?", Text(S.current.downloader_info_manual_file_deletion_note));
|
||||
context,
|
||||
S.current.downloader_action_confirm_cancel_download,
|
||||
Text(S.current.downloader_info_manual_file_deletion_note));
|
||||
if (ok == true) {
|
||||
final aria2c = ref.read(aria2cModelProvider).aria2c;
|
||||
await aria2c?.remove(gid);
|
||||
@ -303,4 +307,4 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,8 @@ class HomeGameDoctorUI extends HookConsumerWidget {
|
||||
}, []);
|
||||
|
||||
return makeDefaultPage(context,
|
||||
title: "一键诊断 -> ${homeState.scInstalledPath}",
|
||||
title: S.current
|
||||
.doctor_title_one_click_diagnosis(homeState.scInstalledPath ?? ""),
|
||||
useBodyContainer: true,
|
||||
content: Stack(
|
||||
children: [
|
||||
@ -40,7 +41,7 @@ class HomeGameDoctorUI extends HookConsumerWidget {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
for (final item in {
|
||||
for (final item in {
|
||||
"rsi_log": S.current.doctor_action_rsi_launcher_log,
|
||||
"game_log": S.current.doctor_action_game_run_log,
|
||||
}.entries)
|
||||
@ -82,7 +83,8 @@ class HomeGameDoctorUI extends HookConsumerWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const SizedBox(height: 12),
|
||||
Text(S.current.doctor_info_scan_complete_no_issues, maxLines: 1),
|
||||
Text(S.current.doctor_info_scan_complete_no_issues,
|
||||
maxLines: 1),
|
||||
const SizedBox(height: 64),
|
||||
],
|
||||
),
|
||||
@ -121,8 +123,8 @@ class HomeGameDoctorUI extends HookConsumerWidget {
|
||||
Widget makeRescueBanner(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () async {
|
||||
await showToast(context,
|
||||
S.current.doctor_info_game_rescue_service_note);
|
||||
await showToast(
|
||||
context, S.current.doctor_info_game_rescue_service_note);
|
||||
launchUrlString(
|
||||
"https://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=-M4wEme_bCXbUGT4LFKLH0bAYTFt70Ad&authKey=vHVr0TNgRmKu%2BHwywoJV6EiLa7La2VX74Vkyixr05KA0H9TqB6qWlCdY%2B9jLQ4Ha&noverify=0&group_code=536454632");
|
||||
},
|
||||
@ -175,22 +177,26 @@ class HomeGameDoctorUI extends HookConsumerWidget {
|
||||
Widget makeResultItem(BuildContext context, MapEntry<String, String> item,
|
||||
HomeGameDoctorState state, HomeGameDoctorUIModel model) {
|
||||
final errorNames = {
|
||||
"unSupport_system":
|
||||
MapEntry("不支持的操作系统,游戏可能无法运行", "请升级您的系统 (${item.value})"),
|
||||
"unSupport_system": MapEntry(S.current.doctor_info_result_unsupported_os,
|
||||
S.current.doctor_info_result_upgrade_system(item.value)),
|
||||
"no_live_path": MapEntry(S.current.doctor_info_result_missing_live_folder,
|
||||
"点击修复为您创建 LIVE 文件夹,完成后重试安装。(${item.value})"),
|
||||
"nvme_PhysicalBytes": MapEntry(S.current.doctor_info_result_incompatible_nvme_device,
|
||||
"为注册表项添加 ForcedPhysicalSectorSizeInBytes 值 模拟旧设备。硬盘分区(${item.value})"),
|
||||
"eac_file_miss": MapEntry(S.current.doctor_info_result_missing_easyanticheat_files,
|
||||
S.current.doctor_info_result_create_live_folder(item.value)),
|
||||
"nvme_PhysicalBytes": MapEntry(
|
||||
S.current.doctor_info_result_incompatible_nvme_device,
|
||||
S.current.doctor_info_result_add_registry_value(item.value)),
|
||||
"eac_file_miss": MapEntry(
|
||||
S.current.doctor_info_result_missing_easyanticheat_files,
|
||||
S.current.doctor_info_result_verify_files_with_rsi_launcher),
|
||||
"eac_not_install": MapEntry(S.current.doctor_info_result_easyanticheat_not_installed,
|
||||
"eac_not_install": MapEntry(
|
||||
S.current.doctor_info_result_easyanticheat_not_installed,
|
||||
S.current.doctor_info_result_install_easyanticheat),
|
||||
"cn_user_name":
|
||||
MapEntry("中文用户名!", S.current.doctor_info_result_chinese_username_error),
|
||||
"cn_install_path": MapEntry(S.current.doctor_info_result_chinese_install_path,
|
||||
"中文安装路径!这可能会导致游戏 启动/安装 错误!(${item.value}),请在RSI启动器更换安装路径。"),
|
||||
"low_ram": MapEntry(
|
||||
"物理内存过低", "您至少需要 16GB 的物理内存(Memory)才可运行此游戏。(当前大小:${item.value})"),
|
||||
"cn_user_name": MapEntry(S.current.doctor_info_result_chinese_username,
|
||||
S.current.doctor_info_result_chinese_username_error),
|
||||
"cn_install_path": MapEntry(
|
||||
S.current.doctor_info_result_chinese_install_path,
|
||||
S.current.doctor_info_result_chinese_install_path_error(item.value)),
|
||||
"low_ram": MapEntry(S.current.doctor_info_result_low_physical_memory,
|
||||
S.current.doctor_info_result_memory_requirement(item.value)),
|
||||
};
|
||||
bool isCheckedError = errorNames.containsKey(item.key);
|
||||
|
||||
@ -211,7 +217,9 @@ class HomeGameDoctorUI extends HookConsumerWidget {
|
||||
children: [
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
"修复建议: ${errorNames[item.key]?.value ?? "暂无解决方法,请截图反馈"}",
|
||||
S.current.doctor_info_result_fix_suggestion(
|
||||
errorNames[item.key]?.value ??
|
||||
S.current.doctor_info_result_no_solution),
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: Colors.white.withOpacity(.7)),
|
||||
),
|
||||
@ -225,7 +233,8 @@ class HomeGameDoctorUI extends HookConsumerWidget {
|
||||
await model.doFix(context, item);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4),
|
||||
padding:
|
||||
const EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4),
|
||||
child: Text(S.current.doctor_info_action_fix),
|
||||
),
|
||||
),
|
||||
@ -263,8 +272,8 @@ class HomeGameDoctorUI extends HookConsumerWidget {
|
||||
launchUrlString(item.value);
|
||||
},
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 8, right: 8, top: 4, bottom: 4),
|
||||
child: Text(S.current.doctor_action_view_solution),
|
||||
),
|
||||
)
|
||||
@ -291,4 +300,4 @@ class HomeGameDoctorUI extends HookConsumerWidget {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,29 +49,30 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
|
||||
try {
|
||||
await Directory(item.value).create(recursive: true);
|
||||
if (!context.mounted) break;
|
||||
showToast(context, S.current.doctor_action_result_create_folder_success);
|
||||
showToast(
|
||||
context, S.current.doctor_action_result_create_folder_success);
|
||||
checkResult.remove(item);
|
||||
state = state.copyWith(checkResult: checkResult);
|
||||
} catch (e) {
|
||||
showToast(context, "创建文件夹失败,请尝试手动创建。\n目录:${item.value} \n错误:$e");
|
||||
showToast(context,
|
||||
S.current.doctor_action_result_create_folder_fail(item.value, e));
|
||||
}
|
||||
break;
|
||||
case "nvme_PhysicalBytes":
|
||||
final r = await SystemHelper.addNvmePatch();
|
||||
if (r == "") {
|
||||
if (!context.mounted) break;
|
||||
showToast(context,
|
||||
S.current.doctor_action_result_fix_success);
|
||||
showToast(context, S.current.doctor_action_result_fix_success);
|
||||
checkResult.remove(item);
|
||||
state = state.copyWith(checkResult: checkResult);
|
||||
} else {
|
||||
if (!context.mounted) break;
|
||||
showToast(context, "修复失败,$r");
|
||||
showToast(context, S.current.doctor_action_result_fix_fail(r));
|
||||
}
|
||||
break;
|
||||
case "eac_file_miss":
|
||||
showToast(
|
||||
context, S.current.doctor_info_result_verify_files_with_rsi_launcher);
|
||||
showToast(context,
|
||||
S.current.doctor_info_result_verify_files_with_rsi_launcher);
|
||||
break;
|
||||
case "eac_not_install":
|
||||
final eacJsonPath = "${item.value}\\Settings.json";
|
||||
@ -84,16 +85,18 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
|
||||
dPrint("${item.value}\\EasyAntiCheat_EOS_Setup.exe install $eacID");
|
||||
if (result.stderr == "") {
|
||||
if (!context.mounted) break;
|
||||
showToast(context, S.current.doctor_action_result_game_start_success);
|
||||
showToast(
|
||||
context, S.current.doctor_action_result_game_start_success);
|
||||
checkResult.remove(item);
|
||||
state = state.copyWith(checkResult: checkResult);
|
||||
} else {
|
||||
if (!context.mounted) break;
|
||||
showToast(context, "修复失败,${result.stderr}");
|
||||
showToast(context,
|
||||
S.current.doctor_action_result_fix_fail(result.stderr));
|
||||
}
|
||||
} catch (e) {
|
||||
if (!context.mounted) break;
|
||||
showToast(context, "修复失败,$e");
|
||||
showToast(context, S.current.doctor_action_result_fix_fail(e));
|
||||
}
|
||||
break;
|
||||
case "cn_user_name":
|
||||
@ -112,7 +115,8 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
|
||||
// ignore: avoid_build_context_in_providers
|
||||
doCheck(BuildContext context) async {
|
||||
if (state.isChecking) return;
|
||||
state = state.copyWith(isChecking: true, lastScreenInfo: S.current.doctor_action_analyzing);
|
||||
state = state.copyWith(
|
||||
isChecking: true, lastScreenInfo: S.current.doctor_action_analyzing);
|
||||
dPrint("-------- start docker check -----");
|
||||
if (!context.mounted) return;
|
||||
await _statCheck(context);
|
||||
@ -140,7 +144,9 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
|
||||
final lastScreenInfo = S.current.doctor_action_result_analysis_no_issue;
|
||||
state = state.copyWith(checkResult: null, lastScreenInfo: lastScreenInfo);
|
||||
} else {
|
||||
final lastScreenInfo = "分析完毕,发现 ${checkResult.length} 个问题";
|
||||
final lastScreenInfo = S.current
|
||||
.doctor_action_result_analysis_issues_found(
|
||||
checkResult.length.toString());
|
||||
state = state.copyWith(
|
||||
checkResult: checkResult, lastScreenInfo: lastScreenInfo);
|
||||
}
|
||||
@ -162,10 +168,13 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
|
||||
final info = SCLoggerHelper.getGameRunningLogInfo(logs);
|
||||
if (info != null) {
|
||||
if (info.key != "_") {
|
||||
checkResult.add(MapEntry("游戏异常退出:${info.key}", info.value));
|
||||
checkResult.add(MapEntry(
|
||||
S.current.doctor_action_info_game_abnormal_exit(info..key),
|
||||
info.value));
|
||||
} else {
|
||||
checkResult
|
||||
.add(MapEntry("游戏异常退出:未知异常", "info:${info.value},请点击右下角加群反馈。"));
|
||||
checkResult.add(MapEntry(
|
||||
S.current.doctor_action_info_game_abnormal_exit_unknown,
|
||||
S.current.doctor_action_info_info_feedback(info.value)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -212,7 +221,8 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
|
||||
Platform.operatingSystemVersion.contains("Windows 11"))) {
|
||||
checkResult
|
||||
.add(MapEntry("unSupport_system", Platform.operatingSystemVersion));
|
||||
final lastScreenInfo = "不支持的操作系统:${Platform.operatingSystemVersion}";
|
||||
final lastScreenInfo = S.current.doctor_action_result_info_unsupported_os(
|
||||
Platform.operatingSystemVersion);
|
||||
state = state.copyWith(lastScreenInfo: lastScreenInfo);
|
||||
await showToast(context, lastScreenInfo);
|
||||
}
|
||||
@ -226,7 +236,8 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
|
||||
if (ramSize < 16) {
|
||||
checkResult.add(MapEntry("low_ram", "$ramSize"));
|
||||
}
|
||||
state = state.copyWith(lastScreenInfo: S.current.doctor_action_info_checking_install_info);
|
||||
state = state.copyWith(
|
||||
lastScreenInfo: S.current.doctor_action_info_checking_install_info);
|
||||
// 检查安装分区
|
||||
try {
|
||||
final listData = await SCLoggerHelper.getGameInstallPath(
|
||||
@ -270,4 +281,4 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
|
||||
dPrint(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -207,10 +207,13 @@ class HomeUI extends HookConsumerWidget {
|
||||
colorFilter: makeSvgColor(Colors.white),
|
||||
height: 18,
|
||||
),
|
||||
name: S.current.home_action_star_citizen_website_localization,
|
||||
webTitle: S.current.home_action_star_citizen_website_localization,
|
||||
name: S.current
|
||||
.home_action_star_citizen_website_localization,
|
||||
webTitle: S.current
|
||||
.home_action_star_citizen_website_localization,
|
||||
webURL: "https://robertsspaceindustries.com",
|
||||
info: S.current.home_action_info_roberts_space_industries_origin,
|
||||
info: S.current
|
||||
.home_action_info_roberts_space_industries_origin,
|
||||
useLocalization: true,
|
||||
width: width,
|
||||
touchKey: "webLocalization_rsi"),
|
||||
@ -228,7 +231,8 @@ class HomeUI extends HookConsumerWidget {
|
||||
name: S.current.home_action_uex_localization,
|
||||
webTitle: S.current.home_action_uex_localization,
|
||||
webURL: "https://uexcorp.space/",
|
||||
info: S.current.home_action_info_mining_refining_trade_calculator,
|
||||
info: S.current
|
||||
.home_action_info_mining_refining_trade_calculator,
|
||||
useLocalization: true,
|
||||
width: width,
|
||||
touchKey: "webLocalization_uex"),
|
||||
@ -244,9 +248,11 @@ class HomeUI extends HookConsumerWidget {
|
||||
],
|
||||
),
|
||||
name: S.current.home_action_dps_calculator_localization,
|
||||
webTitle: S.current.home_action_dps_calculator_localization,
|
||||
webTitle:
|
||||
S.current.home_action_dps_calculator_localization,
|
||||
webURL: "https://www.erkul.games/live/calculator",
|
||||
info: S.current.home_action_info_ship_upgrade_damage_value_query,
|
||||
info: S.current
|
||||
.home_action_info_ship_upgrade_damage_value_query,
|
||||
useLocalization: true,
|
||||
width: width,
|
||||
touchKey: "webLocalization_dps"),
|
||||
@ -434,11 +440,20 @@ class HomeUI extends HookConsumerWidget {
|
||||
Widget makeIndexActionLists(BuildContext context, HomeUIModel model,
|
||||
HomeUIModelState homeState, WidgetRef ref) {
|
||||
final items = [
|
||||
_HomeItemData("game_doctor", "一键诊断", S.current.home_action_info_one_click_diagnosis_star_citizen,
|
||||
_HomeItemData(
|
||||
"game_doctor",
|
||||
S.current.home_action_one_click_diagnosis,
|
||||
S.current.home_action_info_one_click_diagnosis_star_citizen,
|
||||
FluentIcons.auto_deploy_settings),
|
||||
_HomeItemData(
|
||||
"localization", "汉化管理", S.current.home_action_info_quick_install_localization_resources, FluentIcons.locale_language),
|
||||
_HomeItemData("performance", "性能优化", S.current.home_action_info_engine_config_optimization,
|
||||
"localization",
|
||||
S.current.home_action_localization_management,
|
||||
S.current.home_action_info_quick_install_localization_resources,
|
||||
FluentIcons.locale_language),
|
||||
_HomeItemData(
|
||||
"performance",
|
||||
S.current.home_action_performance_optimization,
|
||||
S.current.home_action_info_engine_config_optimization,
|
||||
FluentIcons.process_meta_task),
|
||||
];
|
||||
return Padding(
|
||||
@ -591,7 +606,8 @@ class HomeUI extends HookConsumerWidget {
|
||||
double width, HomeUIModelState homeState) {
|
||||
final statusCnName = {
|
||||
"Platform": S.current.home_action_rsi_status_platform,
|
||||
"Persistent Universe": S.current.home_action_rsi_status_persistent_universe,
|
||||
"Persistent Universe":
|
||||
S.current.home_action_rsi_status_persistent_universe,
|
||||
"Electronic Access": S.current.home_action_rsi_status_electronic_access,
|
||||
"Arena Commander": S.current.home_action_rsi_status_arena_commander
|
||||
};
|
||||
@ -601,7 +617,9 @@ class HomeUI extends HookConsumerWidget {
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
model.goWebView(context, S.current.home_action_rsi_status_rsi_server_status,
|
||||
model.goWebView(
|
||||
context,
|
||||
S.current.home_action_rsi_status_rsi_server_status,
|
||||
"https://status.robertsspaceindustries.com/",
|
||||
useLocalization: true);
|
||||
},
|
||||
@ -741,7 +759,8 @@ class HomeUI extends HookConsumerWidget {
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return HomeMdContentDialogUI(
|
||||
title: homeState.appPlacardData?.title ?? S.current.home_announcement_details,
|
||||
title: homeState.appPlacardData?.title ??
|
||||
S.current.home_announcement_details,
|
||||
url: homeState.appPlacardData?.link,
|
||||
);
|
||||
});
|
||||
@ -757,7 +776,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
_onMenuTap(BuildContext context, String key, HomeUIModelState homeState,
|
||||
WidgetRef ref) async {
|
||||
String gameInstallReqInfo =
|
||||
"该功能需要一个有效的安装位置\n\n如果您的游戏未下载完成,请等待下载完毕后使用此功能。\n\n如果您的游戏已下载完毕但未识别,请启动一次游戏后重新打开盒子 或 在设置选项中手动设置安装位置。";
|
||||
S.current.home_action_info_valid_install_location_required;
|
||||
switch (key) {
|
||||
case "localization":
|
||||
if (homeState.scInstalledPath == "not_install") {
|
||||
@ -786,4 +805,4 @@ class _HomeItemData {
|
||||
String name;
|
||||
String infoString;
|
||||
IconData icon;
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,9 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
if (scInstallPaths.isNotEmpty) {
|
||||
scInstalledPath = scInstallPaths.first;
|
||||
}
|
||||
final lastScreenInfo = "扫描完毕,共找到 ${scInstallPaths.length} 个有效安装目录";
|
||||
final lastScreenInfo = S.current
|
||||
.home_action_info_scan_complete_valid_directories_found(
|
||||
scInstallPaths.length.toString());
|
||||
state = state.copyWith(
|
||||
scInstalledPath: scInstalledPath,
|
||||
scInstallPaths: scInstallPaths,
|
||||
@ -141,10 +143,9 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
final ok = await showConfirmDialogs(
|
||||
context,
|
||||
S.current.home_action_title_star_citizen_website_localization,
|
||||
const Text(
|
||||
"本插功能件仅供大致浏览使用,不对任何有关本功能产生的问题负责!在涉及账号操作前请注意确认网站的原本内容!"
|
||||
"\n\n\n使用此功能登录账号时请确保您的 SC汉化盒子 是从可信任的来源下载。",
|
||||
style: TextStyle(fontSize: 16),
|
||||
Text(
|
||||
S.current.home_action_info_web_localization_plugin_disclaimer,
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width * .6));
|
||||
@ -159,8 +160,8 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
}
|
||||
if (!await WebviewWindow.isWebviewAvailable()) {
|
||||
if (!context.mounted) return;
|
||||
showToast(context,
|
||||
S.current.home_login_action_title_need_webview2_runtime);
|
||||
showToast(
|
||||
context, S.current.home_login_action_title_need_webview2_runtime);
|
||||
launchUrlString(
|
||||
"https://developer.microsoft.com/en-us/microsoft-edge/webview2/");
|
||||
return;
|
||||
@ -171,13 +172,12 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
if (useLocalization) {
|
||||
state = state.copyWith(
|
||||
isFixing: true,
|
||||
isFixingString:
|
||||
S.current.home_action_info_initializing_resources);
|
||||
isFixingString: S.current.home_action_info_initializing_resources);
|
||||
try {
|
||||
await webViewModel.initLocalization(state.webLocalizationVersionsData!);
|
||||
} catch (e) {
|
||||
if (!context.mounted) return;
|
||||
showToast(context, "初始化网页汉化资源失败!$e");
|
||||
showToast(context, S.current.home_action_info_initialization_failed(e));
|
||||
}
|
||||
state = state.copyWith(isFixingString: "", isFixing: false);
|
||||
}
|
||||
@ -294,7 +294,8 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
if (toastContent != null) {
|
||||
final xmlNodeList = toastContent.getElementsByTagName('text');
|
||||
final title = S.current.home_localization_new_version_available;
|
||||
final content = '您在 ${updates.first} 安装的汉化有新版本啦!';
|
||||
final content =
|
||||
S.current.home_localization_new_version_installed(updates.first);
|
||||
xmlNodeList.item(0)?.appendChild(toastContent.createTextNode(title));
|
||||
xmlNodeList
|
||||
.item(1)
|
||||
@ -329,8 +330,7 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
final ok = await showConfirmDialogs(
|
||||
context,
|
||||
S.current.home_info_one_click_launch_warning,
|
||||
const Text("为确保账户安全,一键启动功能已在开发版中禁用,我们将在微软商店版本中提供此功能。"
|
||||
"\n\n微软商店版由微软提供可靠的分发下载与数字签名,可有效防止软件被恶意篡改。\n\n提示:您无需使用盒子启动游戏也可使用汉化。"),
|
||||
Text(S.current.home_info_account_security_warning),
|
||||
confirm: S.current.home_action_install_microsoft_store_version,
|
||||
cancel: S.current.home_action_cancel);
|
||||
if (ok == true) {
|
||||
@ -389,8 +389,21 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
}
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
showToast(context,
|
||||
"游戏非正常退出\nexitCode=${result.exitCode}\nstdout=${result.stdout ?? ""}\nstderr=${result.stderr ?? ""}\n\n诊断信息:${exitInfo == null ? "未知错误,请通过一键诊断加群反馈。" : exitInfo.key} \n${hasUrl ? "请查看弹出的网页链接获得详细信息。" : exitInfo?.value ?? ""}");
|
||||
// showToast(context,
|
||||
// "游戏非正常退出\nexitCode=${result.exitCode}\nstdout=${result.stdout ?? ""}\nstderr=${result.stderr ?? ""}\n\n诊断信息:${exitInfo == null ? "未知错误,请通过一键诊断加群反馈。" : exitInfo.key} \n${hasUrl ? "请查看弹出的网页链接获得详细信息。" : exitInfo?.value ?? ""}");
|
||||
// S.current.home_action_info_abnormal_game_exit
|
||||
showToast(
|
||||
context,
|
||||
S.current.home_action_info_abnormal_game_exit(
|
||||
result.exitCode.toString(),
|
||||
result.stdout ?? "",
|
||||
result.stderr ?? "",
|
||||
exitInfo == null
|
||||
? S.current.home_action_info_unknown_error
|
||||
: exitInfo.key,
|
||||
hasUrl
|
||||
? S.current.home_action_info_check_web_link
|
||||
: exitInfo?.value ?? ""));
|
||||
if (hasUrl) {
|
||||
await Future.delayed(const Duration(seconds: 3));
|
||||
launchUrlString(exitInfo!.value);
|
||||
|
@ -41,8 +41,8 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
child: InfoBar(
|
||||
title: Text(S.current.home_action_info_warning),
|
||||
content: Text(
|
||||
S.current.localization_info_machine_translation_warning),
|
||||
content: Text(S.current
|
||||
.localization_info_machine_translation_warning),
|
||||
severity: InfoBarSeverity.info,
|
||||
style: InfoBarThemeData(decoration: (severity) {
|
||||
return const BoxDecoration(
|
||||
@ -66,8 +66,10 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
Row(
|
||||
children: [
|
||||
Center(
|
||||
child: Text(
|
||||
"启用(${LocalizationUIModel.languageSupport[state.selectedLanguage]}):"),
|
||||
child: Text(S.current.localization_info_enabled(
|
||||
LocalizationUIModel.languageSupport[
|
||||
state.selectedLanguage] ??
|
||||
"")),
|
||||
),
|
||||
const Spacer(),
|
||||
ToggleSwitch(
|
||||
@ -79,7 +81,8 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
Text("已安装版本:${state.patchStatus?.value}"),
|
||||
Text(S.current.localization_info_installed_version(
|
||||
state.patchStatus?.value ?? "")),
|
||||
const Spacer(),
|
||||
if (state.patchStatus?.value !=
|
||||
S.current.home_action_info_game_built_in)
|
||||
@ -93,8 +96,8 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
children: [
|
||||
const Icon(FluentIcons.feedback),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
S.current.localization_action_translation_feedback),
|
||||
Text(S.current
|
||||
.localization_action_translation_feedback),
|
||||
],
|
||||
),
|
||||
)),
|
||||
@ -107,8 +110,8 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
children: [
|
||||
const Icon(FluentIcons.delete),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
S.current.localization_action_uninstall_translation),
|
||||
Text(S.current
|
||||
.localization_action_uninstall_translation),
|
||||
],
|
||||
),
|
||||
)),
|
||||
@ -185,8 +188,7 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
? FluentIcons.chevron_up
|
||||
: FluentIcons.chevron_down),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
S.current.localization_action_advanced_features),
|
||||
Text(S.current.localization_action_advanced_features),
|
||||
],
|
||||
),
|
||||
onPressed: model.toggleCustomize),
|
||||
@ -233,8 +235,8 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
right: 8,
|
||||
top: 4,
|
||||
bottom: 4),
|
||||
child: Text(
|
||||
S.current.localization_action_install),
|
||||
child: Text(S.current
|
||||
.localization_action_install),
|
||||
))
|
||||
],
|
||||
)
|
||||
@ -288,17 +290,20 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
"版本号:${item.value.versionName}",
|
||||
S.current.localization_info_version_number(
|
||||
item.value.versionName ?? ""),
|
||||
style: TextStyle(color: Colors.white.withOpacity(.6)),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
"通道:${item.value.gameChannel}",
|
||||
S.current.localization_info_channel(
|
||||
item.value.gameChannel ?? ""),
|
||||
style: TextStyle(color: Colors.white.withOpacity(.6)),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
"更新时间:${item.value.updateAt}",
|
||||
S.current.localization_info_update_time(
|
||||
item.value.updateAt ?? ""),
|
||||
style: TextStyle(color: Colors.white.withOpacity(.6)),
|
||||
),
|
||||
],
|
||||
@ -332,7 +337,7 @@ class LocalizationDialogUI extends HookConsumerWidget {
|
||||
Text(isInstalled
|
||||
? S.current.localization_info_installed
|
||||
: ((item.value.enable ?? false)
|
||||
? "安装"
|
||||
? S.current.localization_action_install
|
||||
: S.current.localization_info_unavailable)),
|
||||
],
|
||||
),
|
||||
|
@ -16,6 +16,7 @@ import 'package:starcitizen_doctor/common/io/rs_http.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/provider.dart';
|
||||
import 'package:starcitizen_doctor/data/sc_localization_data.dart';
|
||||
import 'package:starcitizen_doctor/generated/no_l10n_strings.dart';
|
||||
import 'package:starcitizen_doctor/ui/home/home_ui_model.dart';
|
||||
import 'package:starcitizen_doctor/widgets/widgets.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
@ -38,9 +39,9 @@ class LocalizationUIState with _$LocalizationUIState {
|
||||
|
||||
@riverpod
|
||||
class LocalizationUIModel extends _$LocalizationUIModel {
|
||||
static const languageSupport = {
|
||||
"chinese_(simplified)": "简体中文",
|
||||
"chinese_(traditional)": "繁體中文",
|
||||
static const languageSupport = {
|
||||
"chinese_(simplified)": NoL10n.langZHS,
|
||||
"chinese_(traditional)": NoL10n.langZHT,
|
||||
};
|
||||
|
||||
late final _downloadDir =
|
||||
@ -123,8 +124,8 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
||||
final ok = await showConfirmDialogs(
|
||||
context,
|
||||
S.current.localization_info_remove_incompatible_translation_params,
|
||||
const Text(
|
||||
"USER.cfg 包含不兼容的汉化参数,这可能是以前的汉化文件的残留信息。\n\n这将可能导致汉化无效或乱码,点击确认为您一键移除(不会影响其他配置)。"),
|
||||
Text(S.current
|
||||
.localization_info_incompatible_translation_params_warning),
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width * .35));
|
||||
if (ok == true) {
|
||||
@ -226,7 +227,9 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
||||
state = state.copyWith(workingVersion: filePath);
|
||||
final str = await f.readAsString();
|
||||
await _installFormString(
|
||||
StringBuffer(str), "自定义_${getCustomizeFileName(filePath)}");
|
||||
StringBuffer(str),
|
||||
S.current
|
||||
.localization_info_custom_file(getCustomizeFileName(filePath)));
|
||||
state = state.copyWith(workingVersion: "");
|
||||
};
|
||||
}
|
||||
@ -256,8 +259,7 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
||||
}
|
||||
|
||||
openDir(BuildContext context) async {
|
||||
showToast(context,
|
||||
"即将打开本地化文件夹,请将自定义的 任意名称.ini 文件放入 Customize_ini 文件夹。\n\n添加新文件后未显示请使用右上角刷新按钮。\n\n安装时请确保选择了正确的语言。");
|
||||
showToast(context, S.current.localization_info_custom_file_instructions);
|
||||
await Process.run(SystemHelper.powershellPath,
|
||||
["explorer.exe", "/select,\"${_customizeDir.absolute.path}\"\\"]);
|
||||
}
|
||||
@ -293,7 +295,8 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
||||
await _installFormString(globalIni, value.versionName ?? "");
|
||||
} catch (e) {
|
||||
if (!context.mounted) return;
|
||||
await showToast(context, "安装出错!\n\n $e");
|
||||
await showToast(
|
||||
context, S.current.localization_info_installation_error(e));
|
||||
if (await savePath.exists()) await savePath.delete();
|
||||
}
|
||||
state = state.copyWith(workingVersion: "");
|
||||
@ -371,7 +374,9 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
||||
|
||||
static Future<String> _getInstalledIniVersion(String iniPath) async {
|
||||
final iniFile = File(iniPath);
|
||||
if (!await iniFile.exists()) return S.current.home_action_info_game_built_in;
|
||||
if (!await iniFile.exists()) {
|
||||
return S.current.home_action_info_game_built_in;
|
||||
}
|
||||
final iniStringSplit = (await iniFile.readAsString()).split("\n");
|
||||
for (var i = iniStringSplit.length - 1; i > 0; i--) {
|
||||
if (iniStringSplit[i]
|
||||
@ -408,7 +413,9 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
||||
if (element.path.contains(lang)) {
|
||||
final installedVersion =
|
||||
await _getInstalledIniVersion("${element.path}\\global.ini");
|
||||
if (installedVersion == S.current.home_action_info_game_built_in) continue;
|
||||
if (installedVersion == S.current.home_action_info_game_built_in) {
|
||||
continue;
|
||||
}
|
||||
final curData = _allVersionLocalizationData[lang];
|
||||
dPrint("check Localization update $scInstallPath");
|
||||
if (!(curData?.keys.contains(installedVersion) ?? false)) {
|
||||
@ -428,4 +435,4 @@ class LocalizationUIModel extends _$LocalizationUIModel {
|
||||
}
|
||||
return updates;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,10 +30,11 @@ class HomePerformanceUI extends HookConsumerWidget {
|
||||
children: [
|
||||
if (state.showGraphicsPerformanceTip)
|
||||
InfoBar(
|
||||
title: Text(
|
||||
S.current.performance_info_graphic_optimization_hint),
|
||||
title: Text(S.current
|
||||
.performance_info_graphic_optimization_hint),
|
||||
content: Text(
|
||||
S.current.performance_info_graphic_optimization_warning,
|
||||
S.current
|
||||
.performance_info_graphic_optimization_warning,
|
||||
),
|
||||
onClose: () => model.closeTip(),
|
||||
),
|
||||
@ -41,7 +42,10 @@ class HomePerformanceUI extends HookConsumerWidget {
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
"当前状态:${state.enabled ? "已应用" : "未应用"}",
|
||||
S.current.performance_info_current_status(
|
||||
state.enabled
|
||||
? S.current.performance_info_applied
|
||||
: S.current.performance_info_not_applied),
|
||||
style: const TextStyle(fontSize: 18),
|
||||
),
|
||||
const SizedBox(width: 32),
|
||||
@ -66,8 +70,8 @@ class HomePerformanceUI extends HookConsumerWidget {
|
||||
onPressed: () =>
|
||||
model.onChangePreProfile(item.key)),
|
||||
),
|
||||
Text(
|
||||
S.current.performance_action_info_preset_only_changes_graphics),
|
||||
Text(S.current
|
||||
.performance_action_info_preset_only_changes_graphics),
|
||||
const Spacer(),
|
||||
Button(
|
||||
onPressed: () => model.refresh(),
|
||||
@ -93,7 +97,8 @@ class HomePerformanceUI extends HookConsumerWidget {
|
||||
const SizedBox(width: 6),
|
||||
Button(
|
||||
child: Text(
|
||||
S.current.performance_action_apply_and_clear_shaders,
|
||||
S.current
|
||||
.performance_action_apply_and_clear_shaders,
|
||||
style: const TextStyle(fontSize: 16),
|
||||
),
|
||||
onPressed: () => model.applyProfile(true)),
|
||||
@ -138,7 +143,8 @@ class HomePerformanceUI extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
return makeDefaultPage(context,
|
||||
title: "性能优化 -> ${model.scPath}",
|
||||
title:
|
||||
S.current.performance_title_performance_optimization(model.scPath),
|
||||
useBodyContainer: true,
|
||||
content: content);
|
||||
}
|
||||
@ -246,8 +252,7 @@ class HomePerformanceUI extends HookConsumerWidget {
|
||||
else if (item.type == "customize")
|
||||
TextFormBox(
|
||||
maxLines: 10,
|
||||
placeholder:
|
||||
"您可以在这里输入未收录进盒子的自定义参数。配置示例:\n\nr_displayinfo=0\nr_VSync=0",
|
||||
placeholder: S.current.performance_action_custom_parameters_input,
|
||||
controller: model.customizeCtrl,
|
||||
),
|
||||
if (item.info != null && item.info!.isNotEmpty) ...[
|
||||
@ -264,7 +269,8 @@ class HomePerformanceUI extends HookConsumerWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
"${item.key} 最小值: ${item.min} / 最大值: ${item.max}",
|
||||
S.current.performance_info_min_max_values(
|
||||
item.key ?? "", item.min ?? "", item.max ?? ""),
|
||||
style: TextStyle(color: Colors.white.withOpacity(.6)),
|
||||
)
|
||||
],
|
||||
|
@ -18,57 +18,71 @@ class SettingsUI extends HookConsumerWidget {
|
||||
margin: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
children: [
|
||||
makeSettingsItem(const Icon(FluentIcons.link, size: 20), S.current.setting_action_create_settings_shortcut,
|
||||
subTitle: S.current.setting_action_create_desktop_shortcut, onTap: ()=> model.addShortCut(context)),
|
||||
makeSettingsItem(const Icon(FluentIcons.link, size: 20),
|
||||
S.current.setting_action_create_settings_shortcut,
|
||||
subTitle: S.current.setting_action_create_desktop_shortcut,
|
||||
onTap: () => model.addShortCut(context)),
|
||||
if (ConstConf.isMSE) ...[
|
||||
const SizedBox(height: 12),
|
||||
makeSettingsItem(
|
||||
const Icon(FluentIcons.reset_device, size: 20), S.current.setting_action_reset_auto_password_fill,
|
||||
subTitle:
|
||||
"启用:${sate.isEnableAutoLogin ? "已启用" : "已禁用"} 设备支持:${sate.isDeviceSupportWinHello ? "支持" : "不支持"} 邮箱:${sate.autoLoginEmail} 密码:${sate.isEnableAutoLoginPwd ? "已加密保存" : "未保存"}",
|
||||
onTap: ()=> model.onResetAutoLogin(context)),
|
||||
makeSettingsItem(const Icon(FluentIcons.reset_device, size: 20),
|
||||
S.current.setting_action_reset_auto_password_fill,
|
||||
subTitle: S.current.setting_action_info_device_support_info(
|
||||
sate.isEnableAutoLogin
|
||||
? S.current.setting_action_info_enabled
|
||||
: S.current.setting_action_info_disabled,
|
||||
sate.isDeviceSupportWinHello
|
||||
? S.current.setting_action_info_support
|
||||
: S.current.setting_action_info_not_support,
|
||||
sate.autoLoginEmail,
|
||||
sate.isEnableAutoLoginPwd
|
||||
? S.current.setting_action_info_encrypted_saved
|
||||
: S.current.setting_action_info_not_saved),
|
||||
onTap: () => model.onResetAutoLogin(context)),
|
||||
],
|
||||
const SizedBox(height: 12),
|
||||
makeSettingsItem(const Icon(FontAwesomeIcons.microchip, size: 20),
|
||||
S.current.setting_action_ignore_efficiency_cores_on_launch,
|
||||
subTitle:
|
||||
"已设置的核心数量:${sate.inputGameLaunchECore} (此功能适用于首页的盒子一键启动 或 工具中的RSI启动器管理员模式,当为 0 时不启用此功能 )",
|
||||
onTap:()=> model.setGameLaunchECore(context)),
|
||||
subTitle: S.current
|
||||
.setting_action_set_core_count(sate.inputGameLaunchECore),
|
||||
onTap: () => model.setGameLaunchECore(context)),
|
||||
const SizedBox(height: 12),
|
||||
makeSettingsItem(const Icon(FluentIcons.folder_open, size: 20),
|
||||
S.current.setting_action_set_launcher_file,
|
||||
subTitle: sate.customLauncherPath != null
|
||||
? "${sate.customLauncherPath}"
|
||||
: S.current.setting_action_info_manual_launcher_location_setting,
|
||||
onTap: ()=> model.setLauncherPath(context), onDel: () {
|
||||
model.delName("custom_launcher_path");
|
||||
}),
|
||||
: S.current
|
||||
.setting_action_info_manual_launcher_location_setting,
|
||||
onTap: () => model.setLauncherPath(context),
|
||||
onDel: () {
|
||||
model.delName("custom_launcher_path");
|
||||
}),
|
||||
const SizedBox(height: 12),
|
||||
makeSettingsItem(const Icon(FluentIcons.game, size: 20),
|
||||
S.current.setting_action_set_game_file,
|
||||
subTitle: sate.customGamePath != null
|
||||
? "${sate.customGamePath}"
|
||||
: S.current.setting_action_info_manual_game_location_setting,
|
||||
onTap: ()=> model.setGamePath(context), onDel: () {
|
||||
model.delName("custom_game_path");
|
||||
}),
|
||||
onTap: () => model.setGamePath(context),
|
||||
onDel: () {
|
||||
model.delName("custom_game_path");
|
||||
}),
|
||||
const SizedBox(height: 12),
|
||||
makeSettingsItem(const Icon(FluentIcons.delete, size: 20), S.current.setting_action_clear_translation_file_cache,
|
||||
subTitle:
|
||||
"缓存大小 ${(sate.locationCacheSize / 1024 / 1024).toStringAsFixed(2)}MB,清理盒子下载的汉化文件缓存,不会影响已安装的汉化",
|
||||
onTap: ()=> model.cleanLocationCache(context)),
|
||||
makeSettingsItem(const Icon(FluentIcons.delete, size: 20),
|
||||
S.current.setting_action_clear_translation_file_cache,
|
||||
subTitle: S.current.setting_action_info_cache_clearing_info(
|
||||
(sate.locationCacheSize / 1024 / 1024).toStringAsFixed(2)),
|
||||
onTap: () => model.cleanLocationCache(context)),
|
||||
const SizedBox(height: 12),
|
||||
makeSettingsItem(
|
||||
const Icon(FluentIcons.speed_high, size: 20), S.current.setting_action_tool_site_access_acceleration,
|
||||
makeSettingsItem(const Icon(FluentIcons.speed_high, size: 20),
|
||||
S.current.setting_action_tool_site_access_acceleration,
|
||||
onTap: () =>
|
||||
model.onChangeToolSiteMirror(!sate.isEnableToolSiteMirrors),
|
||||
subTitle:
|
||||
S.current.setting_action_info_mirror_server_info,
|
||||
subTitle: S.current.setting_action_info_mirror_server_info,
|
||||
onSwitch: model.onChangeToolSiteMirror,
|
||||
switchStatus: sate.isEnableToolSiteMirrors),
|
||||
const SizedBox(height: 12),
|
||||
makeSettingsItem(
|
||||
const Icon(FluentIcons.document_set, size: 20), S.current.setting_action_view_log,
|
||||
makeSettingsItem(const Icon(FluentIcons.document_set, size: 20),
|
||||
S.current.setting_action_view_log,
|
||||
onTap: () => model.showLogs(),
|
||||
subTitle: S.current.setting_action_info_view_log_file),
|
||||
],
|
||||
@ -129,4 +143,4 @@ class SettingsUI extends HookConsumerWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,9 @@ class SettingsUIModel extends _$SettingsUIModel {
|
||||
}
|
||||
|
||||
Future<void> onResetAutoLogin(BuildContext context) async {
|
||||
final ok = await showConfirmDialogs(context, S.current.setting_action_info_confirm_reset_autofill,
|
||||
final ok = await showConfirmDialogs(
|
||||
context,
|
||||
S.current.setting_action_info_confirm_reset_autofill,
|
||||
Text(S.current.setting_action_info_delete_local_account_warning));
|
||||
if (ok) {
|
||||
final userBox = await Hive.openBox("rsi_account_data");
|
||||
@ -90,8 +92,7 @@ class SettingsUIModel extends _$SettingsUIModel {
|
||||
if (!context.mounted) return;
|
||||
final input = await showInputDialogs(context,
|
||||
title: S.current.setting_action_info_enter_cpu_core_to_ignore,
|
||||
content:
|
||||
"Tip:您的设备拥有几个能效核心就输入几,非大小核设备请保持 0\n\n此功能适用于首页的盒子一键启动 或 工具中的 RSI启动器管理员模式,当为 0 时不启用此功能。",
|
||||
content: S.current.setting_action_info_cpu_core_tip,
|
||||
initialValue: defaultInput,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly]);
|
||||
if (input == null) return;
|
||||
@ -175,7 +176,9 @@ class SettingsUIModel extends _$SettingsUIModel {
|
||||
|
||||
Future<void> cleanLocationCache(BuildContext context) async {
|
||||
final ok = await showConfirmDialogs(
|
||||
context, "确认清理汉化缓存?", Text(S.current.setting_action_info_clear_cache_warning));
|
||||
context,
|
||||
S.current.setting_action_info_confirm_clear_cache,
|
||||
Text(S.current.setting_action_info_clear_cache_warning));
|
||||
if (ok == true) {
|
||||
final dir =
|
||||
Directory("${appGlobalState.applicationSupportDir}/Localizations");
|
||||
@ -187,15 +190,17 @@ class SettingsUIModel extends _$SettingsUIModel {
|
||||
|
||||
Future<void> addShortCut(BuildContext context) async {
|
||||
if (ConstConf.isMSE) {
|
||||
showToast(context, S.current.setting_action_info_microsoft_version_limitation);
|
||||
showToast(
|
||||
context, S.current.setting_action_info_microsoft_version_limitation);
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
Process.run("explorer.exe", ["shell:AppsFolder"]);
|
||||
return;
|
||||
}
|
||||
dPrint(Platform.resolvedExecutable);
|
||||
final shortCuntName = S.current.app_shortcut_name;
|
||||
final script = """
|
||||
\$targetPath = "${Platform.resolvedExecutable}";
|
||||
\$shortcutPath = [System.IO.Path]::Combine([System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::DesktopDirectory), "SC汉化盒子DEV.lnk");
|
||||
\$shortcutPath = [System.IO.Path]::Combine([System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::DesktopDirectory), "$shortCuntName");
|
||||
\$shell = New-Object -ComObject WScript.Shell
|
||||
\$shortcut = \$shell.CreateShortcut(\$shortcutPath)
|
||||
if (\$shortcut -eq \$null) {
|
||||
@ -228,4 +233,4 @@ class SettingsUIModel extends _$SettingsUIModel {
|
||||
showLogs() async {
|
||||
SystemHelper.openDir(getDPrintFile()?.absolute.path.replaceAll("/", "\\"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,8 @@ class UpgradeDialogUI extends HookConsumerWidget {
|
||||
|
||||
return Material(
|
||||
child: ContentDialog(
|
||||
title: Text("发现新版本 -> $targetVersion"),
|
||||
title:
|
||||
Text(S.current.app_upgrade_title_new_version_found(targetVersion)),
|
||||
constraints:
|
||||
BoxConstraints(maxWidth: MediaQuery.of(context).size.width * .55),
|
||||
content: Column(
|
||||
@ -64,7 +65,8 @@ class UpgradeDialogUI extends HookConsumerWidget {
|
||||
children: [
|
||||
const ProgressRing(),
|
||||
const SizedBox(height: 16),
|
||||
Text(S.current.app_upgrade_info_getting_new_version_details)
|
||||
Text(S.current
|
||||
.app_upgrade_info_getting_new_version_details)
|
||||
],
|
||||
),
|
||||
)
|
||||
@ -98,7 +100,8 @@ class UpgradeDialogUI extends HookConsumerWidget {
|
||||
children: [
|
||||
Text(progress.value == 100
|
||||
? S.current.app_upgrade_info_installing
|
||||
: "正在下载: ${progress.value.toStringAsFixed(2)}% "),
|
||||
: S.current.app_upgrade_info_downloading(
|
||||
progress.value.toStringAsFixed(2))),
|
||||
Expanded(
|
||||
child: ProgressBar(
|
||||
value: progress.value == 100 ? null : progress.value,
|
||||
@ -260,4 +263,4 @@ class UpgradeDialogUI extends HookConsumerWidget {
|
||||
["explorer.exe", "/select,\"$fileName\""]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,8 +51,8 @@ class SplashUI extends HookConsumerWidget {
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
const Text(
|
||||
"SC汉化盒子 V${ConstConf.appVersion} ${ConstConf.isMSE ? "" : " Dev"}")
|
||||
Text(S.current.app_index_version_info(
|
||||
ConstConf.appVersion, ConstConf.isMSE ? "" : " Dev"))
|
||||
],
|
||||
),
|
||||
));
|
||||
@ -75,4 +75,4 @@ class SplashUI extends HookConsumerWidget {
|
||||
if (!context.mounted) return;
|
||||
context.go("/index");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -144,8 +144,7 @@ class ToolsUI extends HookConsumerWidget {
|
||||
try {
|
||||
item.onTap?.call();
|
||||
} catch (e) {
|
||||
showToast(
|
||||
context, "处理失败!:$e");
|
||||
showToast(context, S.current.tools_info_processing_failed(e));
|
||||
}
|
||||
},
|
||||
child: const Padding(
|
||||
|
@ -72,21 +72,21 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
ToolsItemData(
|
||||
"systemnfo",
|
||||
S.current.tools_action_view_system_info,
|
||||
"查看系统关键信息,用于快速问诊 \n\n耗时操作,请耐心等待。",
|
||||
S.current.tools_action_info_view_critical_system_info,
|
||||
const Icon(FluentIcons.system, size: 24),
|
||||
onTap: () => _showSystemInfo(context),
|
||||
),
|
||||
ToolsItemData(
|
||||
"p4k_downloader",
|
||||
S.current.tools_action_p4k_download_repair,
|
||||
"使用星际公民中文百科提供的分流下载服务,可用于下载或修复 p4k。 \n资源有限,请勿滥用。",
|
||||
S.current.tools_action_info_p4k_download_repair_tip,
|
||||
const Icon(FontAwesomeIcons.download, size: 24),
|
||||
onTap: () => _downloadP4k(context),
|
||||
),
|
||||
ToolsItemData(
|
||||
"hosts_booster",
|
||||
S.current.tools_action_hosts_acceleration_experimental,
|
||||
"将 IP 信息写入 Hosts 文件,解决部分地区的 DNS 污染导致无法登录官网等问题。\n该功能正在进行第一阶段测试,遇到问题请及时反馈。",
|
||||
S.current.tools_action_info_hosts_acceleration_experimental_tip,
|
||||
const Icon(FluentIcons.virtual_network, size: 24),
|
||||
onTap: () => _doHostsBooster(context),
|
||||
),
|
||||
@ -100,7 +100,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
ToolsItemData(
|
||||
"rsilauncher_admin_mode",
|
||||
S.current.tools_action_rsi_launcher_admin_mode,
|
||||
"以管理员身份运行RSI启动器,可能会解决一些问题。\n\n若设置了能效核心屏蔽参数,也会在此应用。",
|
||||
S.current.tools_action_info_run_rsi_as_admin,
|
||||
const Icon(FluentIcons.admin, size: 24),
|
||||
onTap: () => _adminRSILauncher(context),
|
||||
),
|
||||
@ -121,7 +121,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
state = state.copyWith(items: items, isItemLoading: false);
|
||||
} catch (e) {
|
||||
if (!context.mounted) return;
|
||||
showToast(context, "初始化失败,请截图报告给开发者。$e");
|
||||
showToast(context, S.current.tools_action_info_init_failed(e));
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,7 +137,8 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
ToolsItemData(
|
||||
"rsilauncher_log_fix",
|
||||
S.current.tools_action_rsi_launcher_log_fix,
|
||||
"在某些情况下 RSI启动器 的 log 文件会损坏,导致无法完成问题扫描,使用此工具清理损坏的 log 文件。\n\n当前日志文件大小:${(logPathLen.toStringAsFixed(4))} MB",
|
||||
S.current.tools_action_info_rsi_launcher_log_issue(
|
||||
logPathLen.toStringAsFixed(4)),
|
||||
const Icon(FontAwesomeIcons.bookBible, size: 24),
|
||||
onTap: () => _rsiLogFix(context),
|
||||
),
|
||||
@ -151,7 +152,9 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
ToolsItemData(
|
||||
"remove_nvme_settings",
|
||||
S.current.tools_action_remove_nvme_registry_patch,
|
||||
"若您使用 nvme 补丁出现问题,请运行此工具。(可能导致游戏 安装/更新 不可用。)\n\n当前补丁状态:${(nvmePatchStatus) ? "已安装" : "未安装"}",
|
||||
S.current.tools_action_info_nvme_patch_issue(nvmePatchStatus
|
||||
? S.current.localization_info_installed
|
||||
: S.current.tools_action_info_not_installed),
|
||||
const Icon(FluentIcons.hard_drive, size: 24),
|
||||
onTap: nvmePatchStatus
|
||||
? () async {
|
||||
@ -159,7 +162,8 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
await SystemHelper.doRemoveNvmePath();
|
||||
state = state.copyWith(working: false);
|
||||
if (!context.mounted) return;
|
||||
showToast(context, S.current.tools_action_info_removed_restart_effective);
|
||||
showToast(context,
|
||||
S.current.tools_action_info_removed_restart_effective);
|
||||
loadToolsCard(context, skipPathScan: true);
|
||||
}
|
||||
: null,
|
||||
@ -175,11 +179,11 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
final r = await SystemHelper.addNvmePatch();
|
||||
if (r == "") {
|
||||
if (!context.mounted) return;
|
||||
showToast(context,
|
||||
S.current.tools_action_info_fix_success_restart);
|
||||
showToast(
|
||||
context, S.current.tools_action_info_fix_success_restart);
|
||||
} else {
|
||||
if (!context.mounted) return;
|
||||
showToast(context, "修复失败,$r");
|
||||
showToast(context, S.current.doctor_action_result_fix_fail(r));
|
||||
}
|
||||
state = state.copyWith(working: false);
|
||||
loadToolsCard(context, skipPathScan: true);
|
||||
@ -190,12 +194,15 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
|
||||
Future<ToolsItemData> _addShaderCard(BuildContext context) async {
|
||||
final gameShaderCachePath = await SCLoggerHelper.getShaderCachePath();
|
||||
final shaderSize = ((await SystemHelper.getDirLen(gameShaderCachePath ?? "",
|
||||
skipPath: ["$gameShaderCachePath\\Crashes"])) /
|
||||
1024 /
|
||||
1024)
|
||||
.toStringAsFixed(4);
|
||||
return ToolsItemData(
|
||||
"clean_shaders",
|
||||
S.current.tools_action_clear_shader_cache,
|
||||
"若游戏画面出现异常或版本更新后可使用本工具清理过期的着色器(当大于500M时,建议清理) \n\n缓存大小:${((await SystemHelper.getDirLen(gameShaderCachePath ?? "", skipPath: [
|
||||
"$gameShaderCachePath\\Crashes"
|
||||
])) / 1024 / 1024).toStringAsFixed(4)} MB",
|
||||
S.current.tools_action_info_shader_cache_issue(shaderSize),
|
||||
const Icon(FontAwesomeIcons.shapes, size: 24),
|
||||
onTap: () => _cleanShaderCache(context),
|
||||
);
|
||||
@ -207,10 +214,12 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
|
||||
return ToolsItemData(
|
||||
"photography_mode",
|
||||
isEnable ? "关闭摄影模式" : S.current.tools_action_open_photography_mode,
|
||||
isEnable
|
||||
? "还原镜头摇晃效果。\n\n@拉邦那 Lapernum 提供参数信息。"
|
||||
: "一键${S.current.action_close}游戏内镜头晃动以便于摄影操作。\n\n @拉邦那 Lapernum 提供参数信息。",
|
||||
? S.current.tools_action_close_photography_mode
|
||||
: S.current.tools_action_open_photography_mode,
|
||||
isEnable
|
||||
? S.current.tools_action_info_restore_lens_shake
|
||||
: S.current.tools_action_info_one_key_close_lens_shake,
|
||||
const Icon(FontAwesomeIcons.camera, size: 24),
|
||||
onTap: () => _onChangePhotographyMode(context, isEnable),
|
||||
);
|
||||
@ -255,7 +264,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
} catch (e) {
|
||||
dPrint(e);
|
||||
if (!context.mounted) return;
|
||||
showToast(context, "解析 log 文件失败!\n请尝试使用 RSI Launcher log 修复 工具!");
|
||||
showToast(context, S.current.tools_action_info_log_file_parse_failed);
|
||||
}
|
||||
|
||||
if (rsiLauncherInstalledPath == "") {
|
||||
@ -271,7 +280,8 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
/// 重装EAC
|
||||
Future<void> _reinstallEAC(BuildContext context) async {
|
||||
if (state.scInstalledPath.isEmpty) {
|
||||
showToast(context, S.current.tools_action_info_valid_game_directory_needed);
|
||||
showToast(
|
||||
context, S.current.tools_action_info_valid_game_directory_needed);
|
||||
return;
|
||||
}
|
||||
state = state.copyWith(working: true);
|
||||
@ -301,28 +311,29 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
await eacLauncher.delete(recursive: true);
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
showToast(context,
|
||||
S.current.tools_action_info_eac_file_removed);
|
||||
showToast(context, S.current.tools_action_info_eac_file_removed);
|
||||
_adminRSILauncher(context);
|
||||
} catch (e) {
|
||||
showToast(context, "出现错误:$e");
|
||||
showToast(context, S.current.tools_action_info_error_occurred(e));
|
||||
}
|
||||
state = state.copyWith(working: false);
|
||||
loadToolsCard(context, skipPathScan: true);
|
||||
}
|
||||
|
||||
Future<String> getSystemInfo() async {
|
||||
return "系统:${await SystemHelper.getSystemName()}\n\n"
|
||||
"处理器:${await SystemHelper.getCpuName()}\n\n"
|
||||
"内存大小:${await SystemHelper.getSystemMemorySizeGB()}GB\n\n"
|
||||
"显卡信息:\n${await SystemHelper.getGpuInfo()}\n\n"
|
||||
"硬盘信息:\n${await SystemHelper.getDiskInfo()}\n\n";
|
||||
return S.current.tools_action_info_system_info_content(
|
||||
await SystemHelper.getSystemName(),
|
||||
await SystemHelper.getCpuName(),
|
||||
await SystemHelper.getSystemMemorySizeGB(),
|
||||
await SystemHelper.getGpuInfo(),
|
||||
await SystemHelper.getDiskInfo());
|
||||
}
|
||||
|
||||
/// 管理员模式运行 RSI 启动器
|
||||
Future _adminRSILauncher(BuildContext context) async {
|
||||
if (state.rsiLauncherInstalledPath == "") {
|
||||
showToast(context, S.current.tools_action_info_rsi_launcher_directory_not_found);
|
||||
showToast(context,
|
||||
S.current.tools_action_info_rsi_launcher_directory_not_found);
|
||||
}
|
||||
SystemHelper.checkAndLaunchRSILauncher(state.rsiLauncherInstalledPath);
|
||||
}
|
||||
@ -332,8 +343,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
final path = await SCLoggerHelper.getLogFilePath();
|
||||
if (!await File(path!).exists()) {
|
||||
if (!context.mounted) return;
|
||||
showToast(
|
||||
context, S.current.tools_action_info_log_file_not_exist);
|
||||
showToast(context, S.current.tools_action_info_log_file_not_exist);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@ -344,7 +354,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
SystemHelper.checkAndLaunchRSILauncher(state.rsiLauncherInstalledPath);
|
||||
} catch (_) {
|
||||
if (!context.mounted) return;
|
||||
showToast(context, "清理失败,请手动移除,文件位置:$path");
|
||||
showToast(context, S.current.tools_action_info_cleanup_failed(path));
|
||||
}
|
||||
|
||||
state = state.copyWith(working: false);
|
||||
@ -370,7 +380,8 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
actions: [
|
||||
FilledButton(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
padding:
|
||||
const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
child: Text(S.current.action_close),
|
||||
),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
@ -404,18 +415,15 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
|
||||
if ((await SystemHelper.getPID("\"RSI Launcher\"")).isNotEmpty) {
|
||||
if (!context.mounted) return;
|
||||
showToast(context, S.current.tools_action_info_rsi_launcher_running_warning,
|
||||
showToast(
|
||||
context, S.current.tools_action_info_rsi_launcher_running_warning,
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width * .35));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!context.mounted) return;
|
||||
await showToast(
|
||||
context,
|
||||
"${S.current.tools_action_info_p4k_file_description_part1}"
|
||||
"\n\n接下来会弹窗询问您保存位置(可以选择星际公民文件夹也可以选择别处),下载完成后请确保 P4K 文件夹位于 LIVE 文件夹内,之后使用星际公民启动器校验更新即可。");
|
||||
|
||||
await showToast(context, S.current.tools_action_info_p4k_file_description);
|
||||
try {
|
||||
state = state.copyWith(working: true);
|
||||
final aria2cManager = ref.read(aria2cModelProvider.notifier);
|
||||
@ -431,7 +439,8 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
final t = HomeDownloaderUIModel.getTaskTypeAndName(value);
|
||||
if (t.key == "torrent" && t.value.contains("Data.p4k")) {
|
||||
if (!context.mounted) return;
|
||||
showToast(context, S.current.tools_action_info_p4k_download_in_progress);
|
||||
showToast(
|
||||
context, S.current.tools_action_info_p4k_download_in_progress);
|
||||
state = state.copyWith(working: false);
|
||||
return;
|
||||
}
|
||||
@ -447,7 +456,8 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
if (torrentUrl == "") {
|
||||
state = state.copyWith(working: false);
|
||||
if (!context.mounted) return;
|
||||
showToast(context, S.current.tools_action_info_function_under_maintenance);
|
||||
showToast(
|
||||
context, S.current.tools_action_info_function_under_maintenance);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -486,7 +496,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
} catch (e) {
|
||||
state = state.copyWith(working: false);
|
||||
if (!context.mounted) return;
|
||||
showToast(context, "初始化失败!: $e");
|
||||
showToast(context, S.current.app_init_failed_with_reason(e));
|
||||
}
|
||||
await Future.delayed(const Duration(seconds: 3));
|
||||
launchUrlString(
|
||||
@ -496,7 +506,7 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
Future<bool> _checkPhotographyStatus(BuildContext context,
|
||||
{bool? setMode}) async {
|
||||
final scInstalledPath = state.scInstalledPath;
|
||||
final keys = ["AudioShakeStrength", "CameraSpringMovement", "ShakeScale"];
|
||||
final keys = ["AudioShakeStrength", "CameraSpringMovement", "ShakeScale"];
|
||||
final attributesFile = File(
|
||||
"$scInstalledPath\\USER\\Client\\0\\Profiles\\default\\attributes.xml");
|
||||
if (setMode == null) {
|
||||
@ -564,4 +574,4 @@ class ToolsUIModel extends _$ToolsUIModel {
|
||||
context: context,
|
||||
builder: (BuildContext context) => const HostsBoosterDialogUI());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ class WebViewModel {
|
||||
.then((value) => {webview.setWebviewWindowVisibility(false)});
|
||||
}
|
||||
} catch (e) {
|
||||
showToast(context, "初始化失败:$e");
|
||||
showToast(context, S.current.app_init_failed_with_reason(e));
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,7 +317,9 @@ class WebViewModel {
|
||||
webview.evaluateJavaScript("RSIAutoLogin(\"$email\",\"\")");
|
||||
if (pwdE != "" && nonceStr != "" && macStr != "") {
|
||||
// send toast
|
||||
webview.evaluateJavaScript("SCTShowToast(\"请完成 Windows Hello 验证以填充密码\")");
|
||||
final toastMsg =
|
||||
S.current.webview_localization_device_windows_hello_toast;
|
||||
webview.evaluateJavaScript("SCTShowToast(\"$toastMsg\")");
|
||||
// decrypt
|
||||
if (await localAuth.authenticate(
|
||||
localizedReason:
|
||||
|
Reference in New Issue
Block a user