mirror of
https://mirror.ghproxy.com/https://github.com/StarCitizenToolBox/app.git
synced 2024-12-23 05:23:44 +08:00
新增汉化更新提示
新增周期性汉化版本检查
This commit is contained in:
parent
39b357d223
commit
eee1bfdeb0
@ -46,6 +46,8 @@ class AppConf {
|
|||||||
static const rssTextUrl2 =
|
static const rssTextUrl2 =
|
||||||
"$_rssHomeUrl/baidu/tieba/user/%E7%81%AC%E7%81%ACG%E7%81%AC%E7%81%AC&";
|
"$_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 late final String applicationSupportDir;
|
||||||
|
|
||||||
static AppVersionData? networkVersionData;
|
static AppVersionData? networkVersionData;
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
/// enable : true
|
/// enable : true
|
||||||
/// versionName : "3.21.1(PU)_CN_V2"
|
/// versionName : "3.21.1(PU)_CNE_V2"
|
||||||
/// updateAt : "2023-12-03: 14:50:00"
|
/// updateAt : "2023-12-03: 14:50:00"
|
||||||
/// info : "简体中文汉化(首选)"
|
/// info : "简体中文半汉化(物品名称英文版)"
|
||||||
/// game_channel : "PU"
|
/// game_channel : "PU"
|
||||||
/// note : "·因游戏暂不支持3D字体汉化,F键交互将依旧为英文。\n·角色抬头显示器(HUD)的中文字体不显示。\n·某些元素字体过小。\n·搜索栏无法输入中文。\n·部位文本未翻译(在翻了,在翻了!)"
|
/// note : ""
|
||||||
/// upgrade_channel : "CN"
|
|
||||||
|
|
||||||
class ScLocalizationData {
|
class ScLocalizationData {
|
||||||
ScLocalizationData({
|
ScLocalizationData({
|
||||||
@ -13,8 +12,7 @@ class ScLocalizationData {
|
|||||||
this.updateAt,
|
this.updateAt,
|
||||||
this.info,
|
this.info,
|
||||||
this.gameChannel,
|
this.gameChannel,
|
||||||
this.note,
|
this.note,});
|
||||||
this.upgradeChannel,});
|
|
||||||
|
|
||||||
ScLocalizationData.fromJson(dynamic json) {
|
ScLocalizationData.fromJson(dynamic json) {
|
||||||
enable = json['enable'];
|
enable = json['enable'];
|
||||||
@ -23,7 +21,6 @@ class ScLocalizationData {
|
|||||||
info = json['info'];
|
info = json['info'];
|
||||||
gameChannel = json['game_channel'];
|
gameChannel = json['game_channel'];
|
||||||
note = json['note'];
|
note = json['note'];
|
||||||
upgradeChannel = json['upgrade_channel'];
|
|
||||||
}
|
}
|
||||||
bool? enable;
|
bool? enable;
|
||||||
String? versionName;
|
String? versionName;
|
||||||
@ -31,7 +28,6 @@ class ScLocalizationData {
|
|||||||
String? info;
|
String? info;
|
||||||
String? gameChannel;
|
String? gameChannel;
|
||||||
String? note;
|
String? note;
|
||||||
String? upgradeChannel;
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final map = <String, dynamic>{};
|
final map = <String, dynamic>{};
|
||||||
@ -41,7 +37,6 @@ class ScLocalizationData {
|
|||||||
map['info'] = info;
|
map['info'] = info;
|
||||||
map['game_channel'] = gameChannel;
|
map['game_channel'] = gameChannel;
|
||||||
map['note'] = note;
|
map['note'] = note;
|
||||||
map['upgrade_channel'] = upgradeChannel;
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,6 +466,17 @@ class HomeUI extends BaseUI<HomeUIModel> {
|
|||||||
Text(item.infoString),
|
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),
|
const SizedBox(width: 12),
|
||||||
if (item.key == "auto_check" && model.isChecking)
|
if (item.key == "auto_check" && model.isChecking)
|
||||||
const ProgressRing()
|
const ProgressRing()
|
||||||
|
@ -29,6 +29,7 @@ import 'package:url_launcher/url_launcher_string.dart';
|
|||||||
|
|
||||||
import 'package:html/parser.dart' as html;
|
import 'package:html/parser.dart' as html;
|
||||||
import 'package:html/dom.dart' as html_dom;
|
import 'package:html/dom.dart' as html_dom;
|
||||||
|
import 'package:windows_ui/windows_ui.dart';
|
||||||
|
|
||||||
import 'countdown/countdown_dialog_ui.dart';
|
import 'countdown/countdown_dialog_ui.dart';
|
||||||
import 'localization/localization_ui.dart';
|
import 'localization/localization_ui.dart';
|
||||||
@ -67,6 +68,10 @@ class HomeUIModel extends BaseUIModel {
|
|||||||
|
|
||||||
List<CountdownFestivalItemData>? countdownFestivalListData;
|
List<CountdownFestivalItemData>? countdownFestivalListData;
|
||||||
|
|
||||||
|
MapEntry<String, bool>? localizationUpdateInfo;
|
||||||
|
|
||||||
|
bool _isSendLocalizationUpdateNotification = false;
|
||||||
|
|
||||||
final cnExp = RegExp(r"[^\x00-\xff]");
|
final cnExp = RegExp(r"[^\x00-\xff]");
|
||||||
|
|
||||||
AppPlacardData? appPlacardData;
|
AppPlacardData? appPlacardData;
|
||||||
@ -74,6 +79,7 @@ class HomeUIModel extends BaseUIModel {
|
|||||||
List? scServerStatus;
|
List? scServerStatus;
|
||||||
|
|
||||||
Timer? serverUpdateTimer;
|
Timer? serverUpdateTimer;
|
||||||
|
Timer? appUpdateTimer;
|
||||||
|
|
||||||
final statusCnName = const {
|
final statusCnName = const {
|
||||||
"Platform": "平台",
|
"Platform": "平台",
|
||||||
@ -110,6 +116,8 @@ class HomeUIModel extends BaseUIModel {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
dPrint(e);
|
dPrint(e);
|
||||||
}
|
}
|
||||||
|
// check Localization update
|
||||||
|
_checkLocalizationUpdate();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,11 +125,15 @@ class HomeUIModel extends BaseUIModel {
|
|||||||
void initModel() {
|
void initModel() {
|
||||||
reScanPath();
|
reScanPath();
|
||||||
serverUpdateTimer = Timer.periodic(
|
serverUpdateTimer = Timer.periodic(
|
||||||
const Duration(minutes: 1),
|
const Duration(minutes: 10),
|
||||||
(timer) {
|
(timer) {
|
||||||
updateSCServerStatus();
|
updateSCServerStatus();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
appUpdateTimer = Timer.periodic(const Duration(minutes: 30), (timer) {
|
||||||
|
_checkLocalizationUpdate();
|
||||||
|
});
|
||||||
super.initModel();
|
super.initModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,6 +141,8 @@ class HomeUIModel extends BaseUIModel {
|
|||||||
void dispose() {
|
void dispose() {
|
||||||
serverUpdateTimer?.cancel();
|
serverUpdateTimer?.cancel();
|
||||||
serverUpdateTimer = null;
|
serverUpdateTimer = null;
|
||||||
|
appUpdateTimer?.cancel();
|
||||||
|
appUpdateTimer = null;
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,7 +398,7 @@ class HomeUIModel extends BaseUIModel {
|
|||||||
showToast(context!, "该功能需要一个有效的安装位置");
|
showToast(context!, "该功能需要一个有效的安装位置");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
showDialog(
|
await showDialog(
|
||||||
context: context!,
|
context: context!,
|
||||||
dismissWithEsc: false,
|
dismissWithEsc: false,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
@ -392,6 +406,7 @@ class HomeUIModel extends BaseUIModel {
|
|||||||
uiCreate: () => LocalizationUI(),
|
uiCreate: () => LocalizationUI(),
|
||||||
modelCreate: () => LocalizationUIModel(scInstalledPath));
|
modelCreate: () => LocalizationUIModel(scInstalledPath));
|
||||||
});
|
});
|
||||||
|
_checkLocalizationUpdate();
|
||||||
return;
|
return;
|
||||||
case "performance":
|
case "performance":
|
||||||
if (scInstalledPath == "not_install") {
|
if (scInstalledPath == "not_install") {
|
||||||
@ -612,4 +627,34 @@ class HomeUIModel extends BaseUIModel {
|
|||||||
title = title.replaceAll("】", " ] ");
|
title = title.replaceAll("】", " ] ");
|
||||||
return title;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,8 +100,10 @@ class LocalizationUIModel extends BaseUIModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_updateStatus() async {
|
_updateStatus() async {
|
||||||
patchStatus = MapEntry(await getLangCfgEnableLang(lang: selectedLanguage),
|
patchStatus = MapEntry(
|
||||||
await getInstalledIniVersion());
|
await getLangCfgEnableLang(lang: selectedLanguage),
|
||||||
|
await getInstalledIniVersion(
|
||||||
|
"${scDataDir.absolute.path}\\Localization\\$selectedLanguage\\global.ini"));
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,9 +171,8 @@ class LocalizationUIModel extends BaseUIModel {
|
|||||||
str.contains("g_languageAudio=english");
|
str.contains("g_languageAudio=english");
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> getInstalledIniVersion() async {
|
static Future<String> getInstalledIniVersion(String iniPath) async {
|
||||||
final iniFile = File(
|
final iniFile = File(iniPath);
|
||||||
"${scDataDir.absolute.path}\\Localization\\$selectedLanguage\\global.ini");
|
|
||||||
if (!await iniFile.exists()) return "游戏内置";
|
if (!await iniFile.exists()) return "游戏内置";
|
||||||
final iniStringSplit = (await iniFile.readAsString()).split("\n");
|
final iniStringSplit = (await iniFile.readAsString()).split("\n");
|
||||||
for (var i = iniStringSplit.length - 1; i > 0; i--) {
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ dependencies:
|
|||||||
freezed_annotation: ^2.4.1
|
freezed_annotation: ^2.4.1
|
||||||
meta: ^1.9.1
|
meta: ^1.9.1
|
||||||
win32: ^5.0.9
|
win32: ^5.0.9
|
||||||
|
windows_ui: ^0.2.0
|
||||||
local_auth: ^2.1.7
|
local_auth: ^2.1.7
|
||||||
cryptography: ^2.7.0
|
cryptography: ^2.7.0
|
||||||
cryptography_flutter: ^2.3.2
|
cryptography_flutter: ^2.3.2
|
||||||
|
Loading…
Reference in New Issue
Block a user