feat: 多语言 初步引入

This commit is contained in:
2024-03-15 00:01:06 +08:00
parent eae02be2af
commit b2c13a8a6f
45 changed files with 525 additions and 446 deletions

View File

@ -27,7 +27,7 @@ class HomeGameDoctorUI extends HookConsumerWidget {
model.doCheck(context);
});
return null;
}, const []);
}, []);
return makeDefaultPage(context,
title: "一键诊断 -> ${homeState.scInstalledPath}",
@ -40,9 +40,9 @@ class HomeGameDoctorUI extends HookConsumerWidget {
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
for (final item in const {
"rsi_log": "RSI启动器log",
"game_log": "游戏运行log",
for (final item in {
"rsi_log": S.current.doctor_action_rsi_launcher_log,
"game_log": S.current.doctor_action_game_run_log,
}.entries)
Padding(
padding: const EdgeInsets.only(left: 6, right: 6),
@ -76,14 +76,14 @@ class HomeGameDoctorUI extends HookConsumerWidget {
))
else if (state.checkResult == null ||
state.checkResult!.isEmpty) ...[
const Expanded(
Expanded(
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(height: 12),
Text("扫描完毕,没有找到问题!", maxLines: 1),
SizedBox(height: 64),
const SizedBox(height: 12),
Text(S.current.doctor_info_scan_complete_no_issues, maxLines: 1),
const SizedBox(height: 64),
],
),
))
@ -104,7 +104,7 @@ class HomeGameDoctorUI extends HookConsumerWidget {
const SizedBox(height: 12),
Text(state.isFixingString.isNotEmpty
? state.isFixingString
: "正在处理..."),
: S.current.doctor_info_processing),
],
),
),
@ -122,7 +122,7 @@ class HomeGameDoctorUI extends HookConsumerWidget {
return GestureDetector(
onTap: () async {
await showToast(context,
"您即将前往由 深空治疗中心QQ群号536454632 提供的游戏异常救援服务,主要解决游戏安装失败与频繁闪退,如游戏玩法问题,请勿加群。");
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");
},
@ -140,7 +140,7 @@ class HomeGameDoctorUI extends HookConsumerWidget {
children: [
Image.asset("assets/rescue.png", width: 24, height: 24),
const SizedBox(width: 12),
const Text("需要帮助? 点击加群寻求免费人工支援!"),
Text(S.current.doctor_info_need_help),
],
),
)),
@ -155,7 +155,7 @@ class HomeGameDoctorUI extends HookConsumerWidget {
Text(state.lastScreenInfo, maxLines: 1),
const SizedBox(height: 12),
Text(
"注意:本工具检测结果仅供参考,若您不理解以下操作,请提供截图给有经验的玩家!",
S.current.doctor_info_tool_check_result_note,
style: TextStyle(color: Colors.red, fontSize: 16),
),
const SizedBox(height: 24),
@ -177,17 +177,17 @@ class HomeGameDoctorUI extends HookConsumerWidget {
final errorNames = {
"unSupport_system":
MapEntry("不支持的操作系统,游戏可能无法运行", "请升级您的系统 (${item.value})"),
"no_live_path": MapEntry("安装目录缺少LIVE文件夹可能导致安装失败",
"no_live_path": MapEntry(S.current.doctor_info_result_missing_live_folder,
"点击修复为您创建 LIVE 文件夹,完成后重试安装。(${item.value})"),
"nvme_PhysicalBytes": MapEntry("新型 NVME 设备,与 RSI 启动器暂不兼容,可能导致安装失败",
"nvme_PhysicalBytes": MapEntry(S.current.doctor_info_result_incompatible_nvme_device,
"为注册表项添加 ForcedPhysicalSectorSizeInBytes 值 模拟旧设备。硬盘分区(${item.value})"),
"eac_file_miss": const MapEntry("EasyAntiCheat 文件丢失",
"未在 LIVE 文件夹找到 EasyAntiCheat 文件 或 文件不完整,请使用 RSI 启动器校验文件"),
"eac_not_install": const MapEntry("EasyAntiCheat 未安装 或 未正常退出",
"EasyAntiCheat 未安装,请点击修复为您一键安装。(在游戏正常启动并结束前,该问题会一直出现,若您因为其他原因游戏闪退,可忽略此条目)"),
"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,
S.current.doctor_info_result_install_easyanticheat),
"cn_user_name":
const MapEntry("中文用户名!", "中文用户名可能会导致游戏启动/安装错误! 点击修复按钮查看修改教程!"),
"cn_install_path": MapEntry("中文安装路径!",
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}"),
@ -224,9 +224,9 @@ class HomeGameDoctorUI extends HookConsumerWidget {
: () async {
await model.doFix(context, item);
},
child: const Padding(
padding: EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4),
child: Text("修复"),
child: Padding(
padding: const EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4),
child: Text(S.current.doctor_info_action_fix),
),
),
),
@ -262,10 +262,10 @@ class HomeGameDoctorUI extends HookConsumerWidget {
onPressed: () {
launchUrlString(item.value);
},
child: const Padding(
child: Padding(
padding:
EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4),
child: Text("查看解决方案"),
const EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4),
child: Text(S.current.doctor_action_view_solution),
),
)
: null,
@ -284,11 +284,11 @@ class HomeGameDoctorUI extends HookConsumerWidget {
case "game_log":
if (homeState.scInstalledPath == "not_install" ||
homeState.scInstalledPath == null) {
showToast(context, "请在首页选择游戏安装目录。");
showToast(context, S.current.doctor_tip_title_select_game_directory);
return;
}
SystemHelper.openDir("${homeState.scInstalledPath}\\Game.log");
return;
}
}
}
}

View File

@ -17,7 +17,7 @@ part 'game_doctor_ui_model.freezed.dart';
@freezed
class HomeGameDoctorState with _$HomeGameDoctorState {
const factory HomeGameDoctorState({
factory HomeGameDoctorState({
@Default(false) bool isChecking,
@Default(false) bool isFixing,
@Default("") String lastScreenInfo,
@ -30,7 +30,7 @@ class HomeGameDoctorState with _$HomeGameDoctorState {
class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
@override
HomeGameDoctorState build() {
state = const HomeGameDoctorState();
state = HomeGameDoctorState();
return state;
}
@ -43,13 +43,13 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
state = state.copyWith(isFixing: true, isFixingString: "");
switch (item.key) {
case "unSupport_system":
showToast(context, "若您的硬件达标,请尝试安装最新的 Windows 系统。");
showToast(context, S.current.doctor_action_result_try_latest_windows);
break;
case "no_live_path":
try {
await Directory(item.value).create(recursive: true);
if (!context.mounted) break;
showToast(context, "创建文件夹成功,请尝试继续下载游戏!");
showToast(context, S.current.doctor_action_result_create_folder_success);
checkResult.remove(item);
state = state.copyWith(checkResult: checkResult);
} catch (e) {
@ -61,7 +61,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
if (r == "") {
if (!context.mounted) break;
showToast(context,
"修复成功,请尝试重启后继续安装游戏! 若注册表修改操作导致其他软件出现兼容问题,请使用 工具 中的 NVME 注册表清理。");
S.current.doctor_action_result_fix_success);
checkResult.remove(item);
state = state.copyWith(checkResult: checkResult);
} else {
@ -71,7 +71,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
break;
case "eac_file_miss":
showToast(
context, "未在 LIVE 文件夹找到 EasyAntiCheat 文件 或 文件不完整,请使用 RSI 启动器校验文件");
context, S.current.doctor_info_result_verify_files_with_rsi_launcher);
break;
case "eac_not_install":
final eacJsonPath = "${item.value}\\Settings.json";
@ -84,7 +84,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
dPrint("${item.value}\\EasyAntiCheat_EOS_Setup.exe install $eacID");
if (result.stderr == "") {
if (!context.mounted) break;
showToast(context, "修复成功,请尝试启动游戏。(若问题无法解决,请使用工具箱的 《重装 EAC》");
showToast(context, S.current.doctor_action_result_game_start_success);
checkResult.remove(item);
state = state.copyWith(checkResult: checkResult);
} else {
@ -97,13 +97,13 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
}
break;
case "cn_user_name":
showToast(context, "即将跳转,教程来自互联网,请谨慎操作...");
showToast(context, S.current.doctor_action_result_redirect_warning);
await Future.delayed(const Duration(milliseconds: 300));
launchUrlString(
"https://btfy.eu.org/?q=5L+u5pS5d2luZG93c+eUqOaIt+WQjeS7juS4reaWh+WIsOiLseaWhw==");
break;
default:
showToast(context, "该问题暂不支持自动处理,请提供截图寻求帮助");
showToast(context, S.current.doctor_action_result_issue_not_supported);
break;
}
state = state.copyWith(isFixing: false, isFixingString: "");
@ -112,7 +112,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
// ignore: avoid_build_context_in_providers
doCheck(BuildContext context) async {
if (state.isChecking) return;
state = state.copyWith(isChecking: true, lastScreenInfo: "正在分析...");
state = state.copyWith(isChecking: true, lastScreenInfo: S.current.doctor_action_analyzing);
dPrint("-------- start docker check -----");
if (!context.mounted) return;
await _statCheck(context);
@ -126,9 +126,9 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
final checkResult = <MapEntry<String, String>>[];
// TODO for debug
// checkResult?.add(const MapEntry("unSupport_system", "android"));
// checkResult?.add(const MapEntry("nvme_PhysicalBytes", "C"));
// checkResult?.add(const MapEntry("no_live_path", ""));
// checkResult?.add(MapEntry("unSupport_system", "android"));
// checkResult?.add(MapEntry("nvme_PhysicalBytes", "C"));
// checkResult?.add(MapEntry("no_live_path", ""));
await _checkPreInstall(context, scInstalledPath, checkResult);
if (!context.mounted) return;
@ -137,7 +137,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
await _checkGameRunningLog(context, scInstalledPath, checkResult);
if (checkResult.isEmpty) {
const lastScreenInfo = "分析完毕,没有发现问题";
final lastScreenInfo = S.current.doctor_action_result_analysis_no_issue;
state = state.copyWith(checkResult: null, lastScreenInfo: lastScreenInfo);
} else {
final lastScreenInfo = "分析完毕,发现 ${checkResult.length} 个问题";
@ -147,7 +147,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
if (scInstalledPath == "not_install" && (checkResult.isEmpty)) {
if (!context.mounted) return;
showToast(context, "扫描完毕,没有发现问题,若仍然安装失败,请尝试使用工具箱中的 RSI启动器管理员模式。");
showToast(context, S.current.doctor_action_result_toast_scan_no_issue);
}
}
@ -155,7 +155,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
Future _checkGameRunningLog(BuildContext context, String scInstalledPath,
List<MapEntry<String, String>> checkResult) async {
if (scInstalledPath == "not_install") return;
const lastScreenInfo = "正在检查Game.log";
final lastScreenInfo = S.current.doctor_action_tip_checking_game_log;
state = state.copyWith(lastScreenInfo: lastScreenInfo);
final logs = await SCLoggerHelper.getGameRunningLogs(scInstalledPath);
if (logs == null) return;
@ -174,7 +174,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
Future _checkEAC(BuildContext context, String scInstalledPath,
List<MapEntry<String, String>> checkResult) async {
if (scInstalledPath == "not_install") return;
const lastScreenInfo = "正在检查EAC";
final lastScreenInfo = S.current.doctor_action_info_checking_eac;
state = state.copyWith(lastScreenInfo: lastScreenInfo);
final eacPath = "$scInstalledPath\\EasyAntiCheat";
@ -205,7 +205,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
// ignore: avoid_build_context_in_providers
Future _checkPreInstall(BuildContext context, String scInstalledPath,
List<MapEntry<String, String>> checkResult) async {
const lastScreenInfo = "正在检查:运行环境";
final lastScreenInfo = S.current.doctor_action_info_checking_runtime;
state = state.copyWith(lastScreenInfo: lastScreenInfo);
if (!(Platform.operatingSystemVersion.contains("Windows 10") ||
@ -226,7 +226,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
if (ramSize < 16) {
checkResult.add(MapEntry("low_ram", "$ramSize"));
}
state = state.copyWith(lastScreenInfo: "正在检查:安装信息");
state = state.copyWith(lastScreenInfo: S.current.doctor_action_info_checking_install_info);
// 检查安装分区
try {
final listData = await SCLoggerHelper.getGameInstallPath(
@ -270,4 +270,4 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
dPrint(e);
}
}
}
}

View File

@ -147,7 +147,7 @@ class __$$HomeGameDoctorStateImplCopyWithImpl<$Res>
/// @nodoc
class _$HomeGameDoctorStateImpl implements _HomeGameDoctorState {
const _$HomeGameDoctorStateImpl(
_$HomeGameDoctorStateImpl(
{this.isChecking = false,
this.isFixing = false,
this.lastScreenInfo = "",
@ -217,7 +217,7 @@ class _$HomeGameDoctorStateImpl implements _HomeGameDoctorState {
}
abstract class _HomeGameDoctorState implements HomeGameDoctorState {
const factory _HomeGameDoctorState(
factory _HomeGameDoctorState(
{final bool isChecking,
final bool isFixing,
final String lastScreenInfo,

View File

@ -7,7 +7,7 @@ part of 'game_doctor_ui_model.dart';
// **************************************************************************
String _$homeGameDoctorUIModelHash() =>
r'1e32d75095de065cf2cdedf444f74ffc753ce66f';
r'10e8103fca9565ee6363c093e1d0bf2bc9e68f41';
/// See also [HomeGameDoctorUIModel].
@ProviderFor(HomeGameDoctorUIModel)