mirror of
https://ghfast.top/https://github.com/StarCitizenToolBox/app.git
synced 2025-06-29 18:13:58 +08:00
feat: 高级汉化
This commit is contained in:
@ -9,6 +9,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/provider.dart';
|
||||
import 'package:starcitizen_doctor/data/app_advanced_localization_data.dart';
|
||||
import 'package:starcitizen_doctor/data/sc_localization_data.dart';
|
||||
import 'package:starcitizen_doctor/provider/unp4kc.dart';
|
||||
|
||||
import '../home_ui_model.dart';
|
||||
@ -25,9 +26,21 @@ class AdvancedLocalizationUIState with _$AdvancedLocalizationUIState {
|
||||
Map<String, AppAdvancedLocalizationClassKeysData>? classMap,
|
||||
String? p4kGlobalIni,
|
||||
String? serverGlobalIni,
|
||||
ScLocalizationData? apiLocalizationData,
|
||||
@Default(0) int p4kGlobalIniLines,
|
||||
@Default(0) int serverGlobalIniLines,
|
||||
}) = _AdvancedLocalizationUIState;
|
||||
}
|
||||
|
||||
extension AdvancedLocalizationUIStateEx on AdvancedLocalizationUIState {
|
||||
Map<AppAdvancedLocalizationClassKeysDataMode, String> get typeNames => {
|
||||
AppAdvancedLocalizationClassKeysDataMode.localization: "汉化",
|
||||
AppAdvancedLocalizationClassKeysDataMode.unLocalization: "英文原文",
|
||||
AppAdvancedLocalizationClassKeysDataMode.mixed: "双语",
|
||||
AppAdvancedLocalizationClassKeysDataMode.mixedNewline: "双语(换行)",
|
||||
};
|
||||
}
|
||||
|
||||
@riverpod
|
||||
class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
|
||||
@override
|
||||
@ -47,10 +60,14 @@ class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
|
||||
if (ald.classKeys == null) return;
|
||||
state = state.copyWith(workingText: "正在分类 ...");
|
||||
final m = await compute(_doClassIni, (ald, p4kGlobalIni, serverGlobalIni));
|
||||
final p4kGlobalIniLines = p4kGlobalIni.split("\n").length;
|
||||
final serverGlobalIniLines = serverGlobalIni.split("\n").length;
|
||||
state = state.copyWith(
|
||||
workingText: "",
|
||||
p4kGlobalIni: p4kGlobalIni,
|
||||
serverGlobalIni: serverGlobalIni,
|
||||
p4kGlobalIniLines: p4kGlobalIniLines,
|
||||
serverGlobalIniLines: serverGlobalIniLines,
|
||||
classMap: m);
|
||||
}
|
||||
|
||||
@ -70,10 +87,12 @@ class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
|
||||
id: "un_localization",
|
||||
className: "未汉化",
|
||||
keys: [],
|
||||
);
|
||||
)
|
||||
..mode = AppAdvancedLocalizationClassKeysDataMode.unLocalization
|
||||
..lockMod = true;
|
||||
final unClass = AppAdvancedLocalizationClassKeysData(
|
||||
id: "un_class",
|
||||
className: "未分类",
|
||||
className: "其他",
|
||||
keys: [],
|
||||
);
|
||||
final classMap = <String, AppAdvancedLocalizationClassKeysData>{
|
||||
@ -84,18 +103,22 @@ class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
|
||||
final serverIniMap = readIniAsMap(serverGlobalIni);
|
||||
|
||||
var regexList = classMap.values
|
||||
.expand((c) => c.keys!.map((k) => MapEntry(c, RegExp(k))))
|
||||
.expand((c) =>
|
||||
c.keys!.map((k) => MapEntry(c, RegExp(k, caseSensitive: false))))
|
||||
.toList();
|
||||
|
||||
iniKeysLoop:
|
||||
for (var p4kIniKey in p4kIniMap.keys) {
|
||||
final serverValue = serverIniMap[p4kIniKey];
|
||||
if (serverValue == null) {
|
||||
unLocalization.valuesMap[p4kIniKey] = p4kIniMap[p4kIniKey] ?? "";
|
||||
if (serverValue == null || serverValue.trim().isEmpty) {
|
||||
final p4kValue = p4kIniMap[p4kIniKey] ?? "";
|
||||
if (p4kValue.trim().isNotEmpty) {
|
||||
unLocalization.valuesMap[p4kIniKey] = p4kValue;
|
||||
}
|
||||
continue iniKeysLoop;
|
||||
} else {
|
||||
for (var item in regexList) {
|
||||
if (item.value.hasMatch(p4kIniKey)) {
|
||||
if (p4kIniKey.startsWith(item.value)) {
|
||||
item.key.valuesMap[p4kIniKey] = serverValue;
|
||||
serverIniMap.remove(p4kIniKey);
|
||||
continue iniKeysLoop;
|
||||
@ -103,15 +126,15 @@ class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unLocalization.valuesMap.isNotEmpty) {
|
||||
classMap[unLocalization.id!] = unLocalization;
|
||||
}
|
||||
if (serverIniMap.isNotEmpty) {
|
||||
for (var element in serverIniMap.keys) {
|
||||
unClass.valuesMap[element] = serverIniMap[element] ?? "";
|
||||
}
|
||||
classMap[unClass.id!] = unClass;
|
||||
}
|
||||
if (unLocalization.valuesMap.isNotEmpty) {
|
||||
classMap[unLocalization.id!] = unLocalization;
|
||||
}
|
||||
return classMap;
|
||||
}
|
||||
|
||||
@ -150,6 +173,7 @@ class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
|
||||
await localizationUIModel.downloadLocalizationFile(
|
||||
file, apiLocalizationData);
|
||||
}
|
||||
state = state.copyWith(apiLocalizationData: apiLocalizationData);
|
||||
final serverGlobalIni =
|
||||
(await compute(LocalizationUIModel.readArchive, file.absolute.path))
|
||||
.toString();
|
||||
@ -158,13 +182,80 @@ class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
|
||||
}
|
||||
|
||||
Future<String> readEnglishInI(String gameDir) async {
|
||||
final data = await Unp4kCModel.unp4kTools(
|
||||
var data = await Unp4kCModel.unp4kTools(
|
||||
appGlobalState.applicationBinaryModuleDir!, [
|
||||
"extract_memory",
|
||||
"$gameDir\\Data.p4k",
|
||||
"Data\\Localization\\english\\global.ini"
|
||||
]);
|
||||
|
||||
// remove bom
|
||||
if (data.length > 3 &&
|
||||
data[0] == 0xEF &&
|
||||
data[1] == 0xBB &&
|
||||
data[2] == 0xBF) {
|
||||
data = data.sublist(3);
|
||||
}
|
||||
|
||||
final iniData = String.fromCharCodes(data);
|
||||
return iniData;
|
||||
}
|
||||
|
||||
onChangeMod(AppAdvancedLocalizationClassKeysData item,
|
||||
AppAdvancedLocalizationClassKeysDataMode mode) async {
|
||||
if (item.lockMod) return;
|
||||
item.mode = mode;
|
||||
item.isWorking = true;
|
||||
final classMap =
|
||||
Map<String, AppAdvancedLocalizationClassKeysData>.from(state.classMap!);
|
||||
classMap[item.id!] = item;
|
||||
state = state.copyWith(classMap: classMap);
|
||||
|
||||
final p4kIniMap = readIniAsMap(state.p4kGlobalIni!);
|
||||
final serverIniMap = readIniAsMap(state.serverGlobalIni!);
|
||||
final newValuesMap = <String, String>{};
|
||||
|
||||
for (var kv in item.valuesMap.entries) {
|
||||
switch (mode) {
|
||||
case AppAdvancedLocalizationClassKeysDataMode.localization:
|
||||
newValuesMap[kv.key] = serverIniMap[kv.key] ?? "";
|
||||
break;
|
||||
case AppAdvancedLocalizationClassKeysDataMode.unLocalization:
|
||||
newValuesMap[kv.key] = p4kIniMap[kv.key] ?? "";
|
||||
break;
|
||||
case AppAdvancedLocalizationClassKeysDataMode.mixed:
|
||||
newValuesMap[kv.key] =
|
||||
"${serverIniMap[kv.key]} [${p4kIniMap[kv.key]}]";
|
||||
break;
|
||||
case AppAdvancedLocalizationClassKeysDataMode.mixedNewline:
|
||||
newValuesMap[kv.key] =
|
||||
"${serverIniMap[kv.key]}\\n${p4kIniMap[kv.key]}";
|
||||
break;
|
||||
}
|
||||
await Future.delayed(Duration.zero);
|
||||
}
|
||||
item.valuesMap = newValuesMap;
|
||||
item.isWorking = false;
|
||||
classMap[item.id!] = item;
|
||||
state = state.copyWith(classMap: classMap);
|
||||
}
|
||||
|
||||
Future<bool> doInstall() async {
|
||||
state = state.copyWith(workingText: "生成汉化文件...");
|
||||
final classMap = state.classMap!;
|
||||
final globalIni = StringBuffer();
|
||||
for (var item in classMap.values) {
|
||||
for (var kv in item.valuesMap.entries) {
|
||||
globalIni.write("${kv.key}=${kv.value}\n");
|
||||
await Future.delayed(Duration.zero);
|
||||
}
|
||||
}
|
||||
state = state.copyWith(workingText: "安装汉化文件...");
|
||||
final localizationUIModel = ref.read(localizationUIModelProvider.notifier);
|
||||
await localizationUIModel.installFormString(
|
||||
globalIni, state.apiLocalizationData?.versionName ?? "-",
|
||||
advanced: true);
|
||||
state = state.copyWith(workingText: "");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user