新增汉化更新提示

新增周期性汉化版本检查
This commit is contained in:
xkeyC 2023-12-06 22:45:36 +08:00
parent 39b357d223
commit eee1bfdeb0
6 changed files with 107 additions and 16 deletions

View File

@ -46,6 +46,8 @@ class AppConf {
static const rssTextUrl2 =
"$_rssHomeUrl/baidu/tieba/user/%E7%81%AC%E7%81%ACG%E7%81%AC%E7%81%AC&";
static const gameChannels = ["LIVE", "PTU", "EPTU"];
static late final String applicationSupportDir;
static AppVersionData? networkVersionData;

View File

@ -1,10 +1,9 @@
/// enable : true
/// versionName : "3.21.1(PU)_CN_V2"
/// versionName : "3.21.1(PU)_CNE_V2"
/// updateAt : "2023-12-03: 14:50:00"
/// info : "简体中文汉化(首选"
/// info : "简体中文半汉化(物品名称英文版"
/// game_channel : "PU"
/// note : "·因游戏暂不支持3D字体汉化F键交互将依旧为英文。\n·角色抬头显示器(HUD)的中文字体不显示。\n·某些元素字体过小。\n·搜索栏无法输入中文。\n·部位文本未翻译(在翻了,在翻了!)"
/// upgrade_channel : "CN"
/// note : ""
class ScLocalizationData {
ScLocalizationData({
@ -13,8 +12,7 @@ class ScLocalizationData {
this.updateAt,
this.info,
this.gameChannel,
this.note,
this.upgradeChannel,});
this.note,});
ScLocalizationData.fromJson(dynamic json) {
enable = json['enable'];
@ -23,7 +21,6 @@ class ScLocalizationData {
info = json['info'];
gameChannel = json['game_channel'];
note = json['note'];
upgradeChannel = json['upgrade_channel'];
}
bool? enable;
String? versionName;
@ -31,7 +28,6 @@ class ScLocalizationData {
String? info;
String? gameChannel;
String? note;
String? upgradeChannel;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
@ -41,7 +37,6 @@ class ScLocalizationData {
map['info'] = info;
map['game_channel'] = gameChannel;
map['note'] = note;
map['upgrade_channel'] = upgradeChannel;
return map;
}

View File

@ -466,6 +466,17 @@ class HomeUI extends BaseUI<HomeUIModel> {
Text(item.infoString),
],
)),
if (item.key == "localization" &&
model.localizationUpdateInfo != null)
Container(
padding: const EdgeInsets.only(
top: 3, bottom: 3, left: 8, right: 8),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(12)),
child:
Text(model.localizationUpdateInfo?.key ?? " "),
),
const SizedBox(width: 12),
if (item.key == "auto_check" && model.isChecking)
const ProgressRing()

View File

@ -29,6 +29,7 @@ import 'package:url_launcher/url_launcher_string.dart';
import 'package:html/parser.dart' as html;
import 'package:html/dom.dart' as html_dom;
import 'package:windows_ui/windows_ui.dart';
import 'countdown/countdown_dialog_ui.dart';
import 'localization/localization_ui.dart';
@ -67,6 +68,10 @@ class HomeUIModel extends BaseUIModel {
List<CountdownFestivalItemData>? countdownFestivalListData;
MapEntry<String, bool>? localizationUpdateInfo;
bool _isSendLocalizationUpdateNotification = false;
final cnExp = RegExp(r"[^\x00-\xff]");
AppPlacardData? appPlacardData;
@ -74,6 +79,7 @@ class HomeUIModel extends BaseUIModel {
List? scServerStatus;
Timer? serverUpdateTimer;
Timer? appUpdateTimer;
final statusCnName = const {
"Platform": "平台",
@ -110,6 +116,8 @@ class HomeUIModel extends BaseUIModel {
} catch (e) {
dPrint(e);
}
// check Localization update
_checkLocalizationUpdate();
notifyListeners();
}
@ -117,11 +125,15 @@ class HomeUIModel extends BaseUIModel {
void initModel() {
reScanPath();
serverUpdateTimer = Timer.periodic(
const Duration(minutes: 1),
const Duration(minutes: 10),
(timer) {
updateSCServerStatus();
},
);
appUpdateTimer = Timer.periodic(const Duration(minutes: 30), (timer) {
_checkLocalizationUpdate();
});
super.initModel();
}
@ -129,6 +141,8 @@ class HomeUIModel extends BaseUIModel {
void dispose() {
serverUpdateTimer?.cancel();
serverUpdateTimer = null;
appUpdateTimer?.cancel();
appUpdateTimer = null;
super.dispose();
}
@ -384,7 +398,7 @@ class HomeUIModel extends BaseUIModel {
showToast(context!, "该功能需要一个有效的安装位置");
return;
}
showDialog(
await showDialog(
context: context!,
dismissWithEsc: false,
builder: (BuildContext context) {
@ -392,6 +406,7 @@ class HomeUIModel extends BaseUIModel {
uiCreate: () => LocalizationUI(),
modelCreate: () => LocalizationUIModel(scInstalledPath));
});
_checkLocalizationUpdate();
return;
case "performance":
if (scInstalledPath == "not_install") {
@ -612,4 +627,34 @@ class HomeUIModel extends BaseUIModel {
title = title.replaceAll("", " ] ");
return title;
}
Future<void> _checkLocalizationUpdate() async {
final info = await handleError(
() => LocalizationUIModel.checkLocalizationUpdates(scInstallPaths));
dPrint("lUpdateInfo === $info");
localizationUpdateInfo = info;
notifyListeners();
if (info?.value == true && !_isSendLocalizationUpdateNotification) {
final toastNotifier =
ToastNotificationManager.createToastNotifierWithId("SC汉化盒子");
if (toastNotifier != null) {
final toastContent = ToastNotificationManager.getTemplateContent(
ToastTemplateType.toastText02);
if (toastContent != null) {
final xmlNodeList = toastContent.getElementsByTagName('text');
const title = '汉化有新版本!';
final content = '您在 ${info?.key} 安装的汉化有新版本啦!';
xmlNodeList.item(0)?.appendChild(toastContent.createTextNode(title));
xmlNodeList
.item(1)
?.appendChild(toastContent.createTextNode(content));
final toastNotification =
ToastNotification.createToastNotification(toastContent);
toastNotifier.show(toastNotification);
_isSendLocalizationUpdateNotification = true;
}
}
}
}
}

View File

@ -100,8 +100,10 @@ class LocalizationUIModel extends BaseUIModel {
}
_updateStatus() async {
patchStatus = MapEntry(await getLangCfgEnableLang(lang: selectedLanguage),
await getInstalledIniVersion());
patchStatus = MapEntry(
await getLangCfgEnableLang(lang: selectedLanguage),
await getInstalledIniVersion(
"${scDataDir.absolute.path}\\Localization\\$selectedLanguage\\global.ini"));
notifyListeners();
}
@ -169,9 +171,8 @@ class LocalizationUIModel extends BaseUIModel {
str.contains("g_languageAudio=english");
}
Future<String> getInstalledIniVersion() async {
final iniFile = File(
"${scDataDir.absolute.path}\\Localization\\$selectedLanguage\\global.ini");
static Future<String> getInstalledIniVersion(String iniPath) async {
final iniFile = File(iniPath);
if (!await iniFile.exists()) return "游戏内置";
final iniStringSplit = (await iniFile.readAsString()).split("\n");
for (var i = iniStringSplit.length - 1; i > 0; i--) {
@ -342,4 +343,40 @@ class LocalizationUIModel extends BaseUIModel {
}
}
}
static Future<MapEntry<String, bool>?> checkLocalizationUpdates(
List<String> gameInstallPaths) async {
final updateInfo = <String, bool>{};
for (var kv in languageSupport.entries) {
final l = await Api.getScLocalizationData(kv.key);
for (var value in gameInstallPaths) {
final iniPath = "$value\\data\\Localization\\${kv.key}\\global.ini";
if (!await File(iniPath).exists()) {
continue;
}
final installed = await getInstalledIniVersion(iniPath);
if (installed == "游戏内置" || installed == "自定义文件") {
continue;
}
final hasUpdate = l
.where((element) => element.versionName == installed)
.firstOrNull ==
null;
updateInfo[value] = hasUpdate;
}
}
dPrint("checkLocalizationUpdates ==== $updateInfo");
for (var v in updateInfo.entries) {
if (v.value) {
for (var element in AppConf.gameChannels) {
if (v.key.contains("StarCitizen\\$element")) {
return MapEntry(element, true);
}else {
return const MapEntry("", true);
}
}
}
}
return null;
}
}

View File

@ -58,6 +58,7 @@ dependencies:
freezed_annotation: ^2.4.1
meta: ^1.9.1
win32: ^5.0.9
windows_ui: ^0.2.0
local_auth: ^2.1.7
cryptography: ^2.7.0
cryptography_flutter: ^2.3.2