feat: 允许选择WPFGUI中的干员名称显示语言 (#10079)

允许选择“干员名称显示语言”为“跟随MAA”或“跟随游戏客户端”。
这个应该不会需要更多选项吧()
先糊一坨,睡了()

已知问题:
 - 所有相关内容都需要重启客户端才能生效

TODO:
 - 将“切换语言后重启MAA”引入此处选项修改后任务
 - Other languages
 - 更多显示干员名称的区域,如 #10067 提到的招募小工具界面
 - 拆分重置 #9457 

待讨论:
 - 更多的专有名词


![图片](https://github.com/user-attachments/assets/cf384f22-0549-40cd-a698-07b6d4316818)
This commit is contained in:
uye
2024-08-18 23:11:29 +08:00
committed by GitHub
12 changed files with 181 additions and 15 deletions

View File

@@ -30,6 +30,7 @@ namespace MaaWpfGui.Constants
public const string ConfigurationCron = "Cron";
public const string Localization = "GUI.Localization";
public const string OperNameLanguage = "GUI.OperNameLanguage";
public const string UseTray = "GUI.UseTray";
public const string MinimizeToTray = "GUI.MinimizeToTray";
public const string HideCloseButton = "GUI.HideCloseButton";

View File

@@ -100,7 +100,7 @@ namespace MaaWpfGui.Helper
return null;
}
language ??= Instances.SettingsViewModel.Language;
language ??= Instances.SettingsViewModel.OperNameLocalization;
return language switch
{

View File

@@ -1010,7 +1010,8 @@ namespace MaaWpfGui.Main
var missingOpers = details["details"]?["opers"]?.ToObject<List<List<string>>>();
if (missingOpers is not null)
{
var missingOpersStr = "[" + string.Join("]; [", missingOpers.Select(opers => string.Join(", ", opers))) + "]";
var missingOpersStr = "[" + string.Join("]; [", missingOpers.Select(opers =>
string.Join(", ", opers.Select(oper => DataHelper.GetLocalizedCharacterName(oper))))) + "]";
Instances.CopilotViewModel.AddLog(LocalizationHelper.GetString("MissingOperators") + missingOpersStr, UiLogColor.Error);
}
else
@@ -1432,11 +1433,12 @@ namespace MaaWpfGui.Main
}
case "BattleFormation":
Instances.CopilotViewModel.AddLog(LocalizationHelper.GetString("BattleFormation") + "\n" + JsonConvert.SerializeObject(subTaskDetails!["formation"]));
Instances.CopilotViewModel.AddLog(LocalizationHelper.GetString("BattleFormation") + "\n[" +
string.Join(", ", subTaskDetails!["formation"]?.ToObject<List<string>>().Select(oper => DataHelper.GetLocalizedCharacterName(oper))) + "]");
break;
case "BattleFormationSelected":
Instances.CopilotViewModel.AddLog(LocalizationHelper.GetString("BattleFormationSelected") + subTaskDetails!["selected"]);
Instances.CopilotViewModel.AddLog(LocalizationHelper.GetString("BattleFormationSelected") + DataHelper.GetLocalizedCharacterName(subTaskDetails!["selected"]?.ToString()));
break;
case "CopilotAction":

View File

@@ -408,6 +408,9 @@ Only supports Official(CN) and Bilibili server. Login account is not supported.<
<system:String x:Key="AutoRoguelike">Auto I.S.</system:String>
<system:String x:Key="ReclamationAlgorithm">Reclamation Algorithm</system:String>
<system:String x:Key="ReclamationAlgorithm2">Reclamation Algorithm 2</system:String>
<system:String x:Key="OperNameLanguage">Operator name display language</system:String>
<system:String x:Key="OperNameLanguageMAA">Follow MAA</system:String>
<system:String x:Key="OperNameLanguageClient">Follow game client</system:String>
<system:String x:Key="Light">Light</system:String>
<system:String x:Key="Dark">Dark</system:String>
<system:String x:Key="SyncWithOs">Sync with OS</system:String>
@@ -590,6 +593,12 @@ The video aspect ratio needs to be 16:9 without interference factors such as bla
<system:String x:Key="LoopTimes">Loop Times</system:String>
<system:String x:Key="Start">Start</system:String>
<system:String x:Key="VideoLink">Video Link</system:String>
<system:String x:Key="CopilotSkill">Skill</system:String>
<system:String x:Key="TotalOperatorsCount">Total {0} Operator(s)</system:String>
<system:String x:Key="DirectiveECTerm">Directive EC unit:</system:String>
<system:String x:Key="OtherOperators">Other operators:</system:String>
<system:String x:Key="InitialEquipmentHorizontal">Tactical Equipment (horizontal):</system:String>
<system:String x:Key="InitialStrategy">Initial Strategy:</system:String>
<!-- Logs -->
<system:String x:Key="CopilotTip">
Tips: \n\n

View File

@@ -407,6 +407,9 @@
<system:String x:Key="AutoRoguelike">自動ローグ</system:String>
<system:String x:Key="ReclamationAlgorithm">生息演算「砂中の火」</system:String>
<system:String x:Key="ReclamationAlgorithm2">生息演算「熱砂秘聞」</system:String>
<system:String x:Key="OperNameLanguage">オペレーター名の表示言語</system:String>
<system:String x:Key="OperNameLanguageMAA">MAAをフォローする</system:String>
<system:String x:Key="OperNameLanguageClient">ゲームクライアントをフォローする</system:String>
<system:String x:Key="Light">ライトモード</system:String>
<system:String x:Key="Dark">ダークモード</system:String>
<system:String x:Key="SyncWithOs">OSと同期する</system:String>
@@ -589,6 +592,12 @@
<system:String x:Key="LoopTimes">ループ回数</system:String>
<system:String x:Key="Start">開始</system:String>
<system:String x:Key="VideoLink">映像へのハイパーリンク</system:String>
<system:String x:Key="CopilotSkill">スキル</system:String>
<system:String x:Key="TotalOperatorsCount">合計 {0} 名のオペレーター</system:String>
<system:String x:Key="DirectiveECTerm">拡張式戦術ユニット:</system:String>
<system:String x:Key="OtherOperators">その他のオペレーター:</system:String>
<system:String x:Key="InitialEquipmentHorizontal">初期戦術装備(横):</system:String>
<system:String x:Key="InitialStrategy">初期戦略:</system:String>
<!-- Logs -->
<system:String x:Key="CopilotTip">
ヒント: \n\n

View File

@@ -407,6 +407,9 @@ OF-1을 해금하지 않았다면 선택하지 말아 주세요.</system:String>
<system:String x:Key="AutoRoguelike">통합전략</system:String>
<system:String x:Key="ReclamationAlgorithm">생존연산·모래 속의 불</system:String>
<system:String x:Key="ReclamationAlgorithm2">생존연산·사막 이야기</system:String>
<system:String x:Key="OperNameLanguage">간부 이름 표시 언어</system:String>
<system:String x:Key="OperNameLanguageMAA">MAA 따라가기</system:String>
<system:String x:Key="OperNameLanguageClient">게임 클라이언트 따라가기</system:String>
<system:String x:Key="Light">라이트</system:String>
<system:String x:Key="Dark">다크</system:String>
<system:String x:Key="SyncWithOs">시스템 연동</system:String>
@@ -591,6 +594,12 @@ Only once가 체크되면 실행 후 Only once가 체크되기 전 상태로 작
<system:String x:Key="LoopTimes">반복 횟수</system:String>
<system:String x:Key="Start">시작</system:String>
<system:String x:Key="VideoLink">영상 링크</system:String>
<system:String x:Key="CopilotSkill">스킬</system:String>
<system:String x:Key="TotalOperatorsCount">총 {0}명의 오퍼레이터</system:String>
<system:String x:Key="DirectiveECTerm">에너지 기어:</system:String>
<system:String x:Key="OtherOperators">기타 오퍼레이터:</system:String>
<system:String x:Key="InitialEquipmentHorizontal">전술 장비 (가로):</system:String>
<system:String x:Key="InitialStrategy">초기 전략:</system:String>
<!-- Logs -->
<system:String x:Key="CopilotTip">
팁:\n\n

View File

@@ -408,6 +408,9 @@
<system:String x:Key="AutoRoguelike">自动肉鸽</system:String>
<system:String x:Key="ReclamationAlgorithm">生息演算·沙中之火</system:String>
<system:String x:Key="ReclamationAlgorithm2">生息演算·沙洲遗闻</system:String>
<system:String x:Key="OperNameLanguage">干员名称显示语言</system:String>
<system:String x:Key="OperNameLanguageMAA">跟随MAA</system:String>
<system:String x:Key="OperNameLanguageClient">跟随游戏客户端</system:String>
<system:String x:Key="Light">亮色</system:String>
<system:String x:Key="Dark">暗色</system:String>
<system:String x:Key="SyncWithOs">与系统同步</system:String>
@@ -592,6 +595,12 @@
<system:String x:Key="CopilotClearTask">右键清除未激活任务</system:String>
<system:String x:Key="Start">开始</system:String>
<system:String x:Key="VideoLink">视频链接</system:String>
<system:String x:Key="CopilotSkill">技能</system:String>
<system:String x:Key="TotalOperatorsCount">共 {0} 名干员</system:String>
<system:String x:Key="DirectiveECTerm">导能原件:</system:String>
<system:String x:Key="OtherOperators">编队工具人:</system:String>
<system:String x:Key="InitialEquipmentHorizontal">开局装备(横向):</system:String>
<system:String x:Key="InitialStrategy">开局策略:</system:String>
<!-- 日志 -->
<system:String x:Key="CopilotTip">
小提示: \n\n

View File

@@ -398,6 +398,9 @@
<system:String x:Key="AutoRoguelike">自動肉鴿</system:String>
<system:String x:Key="ReclamationAlgorithm">生息演算·沙中之火</system:String>
<system:String x:Key="ReclamationAlgorithm2">生息演算·沙洲遺聞</system:String>
<system:String x:Key="OperNameLanguage">幹員名稱顯示語言</system:String>
<system:String x:Key="OperNameLanguageMAA">跟隨MAA</system:String>
<system:String x:Key="OperNameLanguageClient">跟隨遊戲客戶端</system:String>
<system:String x:Key="Light">亮色</system:String>
<system:String x:Key="Dark">暗色</system:String>
<system:String x:Key="SyncWithOs">與系統同步</system:String>
@@ -582,6 +585,12 @@
<system:String x:Key="LoopTimes">循環次數</system:String>
<system:String x:Key="Start">開始</system:String>
<system:String x:Key="VideoLink">影片連結</system:String>
<system:String x:Key="CopilotSkill">技能</system:String>
<system:String x:Key="TotalOperatorsCount">共 {0} 名幹員</system:String>
<system:String x:Key="DirectiveECTerm">導能組件:</system:String>
<system:String x:Key="OtherOperators">其他幹員:</system:String>
<system:String x:Key="InitialEquipmentHorizontal">開局裝備(橫向):</system:String>
<system:String x:Key="InitialStrategy">開局策略:</system:String>
<!-- 日誌 -->
<system:String x:Key="CopilotTip">
小提示: \n\n

View File

@@ -373,11 +373,15 @@ namespace MaaWpfGui.ViewModels.UI
}
AddLog(string.Empty, UiLogColor.Message, showTime: false);
AddLog("------------------------------------------------", UiLogColor.Message, showTime: false);
AddLog(string.Empty, UiLogColor.Message, showTime: false);
int count = 0;
foreach (var oper in json["opers"] ?? new JArray())
{
count++;
AddLog($"{oper["name"]}, {oper["skill"]} 技能", UiLogColor.Message, showTime: false);
var localizedName = DataHelper.GetLocalizedCharacterName((string?)oper["name"]);
AddLog($"{localizedName}, {LocalizationHelper.GetString("CopilotSkill")} {oper["skill"]}", UiLogColor.Message, showTime: false);
}
if (json.TryGetValue("groups", out var groupsValue))
@@ -386,13 +390,14 @@ namespace MaaWpfGui.ViewModels.UI
{
count++;
string groupName = group["name"] + ": ";
var operInfos = group["opers"]!.Cast<JObject>().Select(oper => $"{oper["name"]} {oper["skill"]}").ToList();
var operInfos = group["opers"]!.Cast<JObject>()
.Select(oper => $"{DataHelper.GetLocalizedCharacterName((string?)oper["name"])} {oper["skill"]}").ToList();
AddLog(groupName + string.Join(" / ", operInfos), UiLogColor.Message, showTime: false);
}
}
AddLog($"共 {count} 名干员", UiLogColor.Message, showTime: false);
AddLog(string.Format(LocalizationHelper.GetString("TotalOperatorsCount"), count), UiLogColor.Message, showTime: false);
if (json.TryGetValue("type", out var typeValue))
{
@@ -401,19 +406,28 @@ namespace MaaWpfGui.ViewModels.UI
{
_taskType = "SSSCopilot";
if (json.TryGetValue("buff", out var buffValue))
{
string buffLog = LocalizationHelper.GetString("DirectiveECTerm");
AddLog(buffLog + DataHelper.GetLocalizedCharacterName((string?)buffValue), UiLogColor.Message, showTime: false);
}
if (json.TryGetValue("tool_men", out var toolMenValue))
{
AddLog("编队工具人:\n" + toolMenValue, UiLogColor.Message, showTime: false);
string toolMenLog = LocalizationHelper.GetString("OtherOperators");
AddLog(toolMenLog + toolMenValue, UiLogColor.Message, showTime: false);
}
if (json.TryGetValue("equipment", out var equipmentValue) && equipmentValue is JArray equipmentJArray)
{
AddLog("开局装备(横向):\n" + string.Join('\n', equipmentJArray.Select(i => (string?)i).Chunk(4).Select(i => string.Join(",", i))), UiLogColor.Message, showTime: false);
string equipmentLog = LocalizationHelper.GetString("InitialEquipmentHorizontal") + '\n';
AddLog(equipmentLog + string.Join('\n', equipmentJArray.Select(i => (string?)i).Chunk(4).Select(i => string.Join(",", i))), UiLogColor.Message, showTime: false);
}
if (json.TryGetValue("strategy", out var strategyValue))
{
AddLog("开局策略:" + strategyValue, UiLogColor.Message, showTime: false);
string strategyLog = LocalizationHelper.GetString("InitialStrategy");
AddLog(strategyLog + strategyValue, UiLogColor.Message, showTime: false);
}
}
}

View File

@@ -316,8 +316,8 @@ namespace MaaWpfGui.ViewModels.UI
foreach (var oper in (JArray?)combs["opers"] ?? [])
{
int operLevel = (int)oper["level"];
string operId = oper["id"]?.ToString();
string operName = oper["name"]?.ToString();
var operId = oper["id"]?.ToString();
var operName = DataHelper.GetLocalizedCharacterName(oper["name"]?.ToString());
string potential = string.Empty;
@@ -617,7 +617,16 @@ namespace MaaWpfGui.ViewModels.UI
List<Tuple<string, int>> operHave = [];
List<Tuple<string, int>> operNotHave = [];
string localizedName = ConfigurationHelper.GetValue(ConfigurationKeys.Localization, string.Empty) switch
string localizedName = ConfigurationHelper.GetValue(ConfigurationKeys.OperNameLanguage, string.Empty) == "OperNameLanguageClient" ?
ConfigurationHelper.GetValue(ConfigurationKeys.ClientType, string.Empty) switch
{
"Official" => "name",
"Bilibili" => "name",
"YoStarJP" => "name_jp",
"YoStarKR" => "name_kr",
"txwy" => "name_tw",
_ => "name_en",
} : ConfigurationHelper.GetValue(ConfigurationKeys.Localization, string.Empty) switch
{
"zh-cn" => "name",
"ja-jp" => "name_jp",

View File

@@ -1970,7 +1970,7 @@ namespace MaaWpfGui.ViewModels.UI
continue;
}
var localizedName = DataHelper.GetLocalizedCharacterName(name, _language);
var localizedName = DataHelper.GetLocalizedCharacterName(name, OperNameLocalization);
if (!string.IsNullOrEmpty(localizedName) && !(_clientType.Contains("YoStar") && DataHelper.GetLocalizedCharacterName(name, "en-us") == DataHelper.GetLocalizedCharacterName(name, "zh-cn")))
{
roguelikeCoreCharList.Add(localizedName);
@@ -4571,6 +4571,15 @@ namespace MaaWpfGui.ViewModels.UI
/// </summary>
public List<CombinedData> LanguageList { get; set; }
/// <summary>
/// Gets the list of operator name language settings
/// </summary>
public List<CombinedData> OperNameLanguageModeList { get; } =
[
new() { Display = LocalizationHelper.GetString("OperNameLanguageMAA"), Value = "OperNameLanguageMAA" },
new() { Display = LocalizationHelper.GetString("OperNameLanguageClient"), Value = "OperNameLanguageClient" }
];
/// <summary>
/// Gets the list of dark mode.
/// </summary>
@@ -4845,7 +4854,7 @@ namespace MaaWpfGui.ViewModels.UI
get => _language;
set
{
if (!SetAndNotify(ref _language, value))
if (value == _language)
{
return;
}
@@ -4885,6 +4894,8 @@ namespace MaaWpfGui.ViewModels.UI
Bootstrapper.ShutdownAndRestartWithoutArgs();
}
SetAndNotify(ref _language, value);
return;
string FormatText(string text, string key)
@@ -4904,6 +4915,79 @@ namespace MaaWpfGui.ViewModels.UI
}
}
private static readonly Dictionary<string, string> _clientLanguageMapper = new()
{
{ string.Empty, "zh-cn" },
{ "Official", "zh-cn" },
{ "Bilibili", "zh-cn" },
{ "YoStarEN", "en-us" },
{ "YoStarJP", "ja-jp" },
{ "YoStarKR", "ko-kr" },
{ "txwy", "zh-tw" },
};
private string _operNameLanguage = ConfigurationHelper.GetValue(ConfigurationKeys.OperNameLanguage, "OperNameLanguageMAA");
public string OperNameLanguage
{
get => _operNameLanguage;
set
{
if (value == _operNameLanguage)
{
return;
}
switch (value)
{
case "OperNameLanguageClient":
ConfigurationHelper.SetValue(ConfigurationKeys.OperNameLanguage, value);
break;
case "OperNameLanguageMAA":
default:
ConfigurationHelper.SetValue(ConfigurationKeys.OperNameLanguage, "OperNameLanguageMAA");
break;
}
var mainWindow = Application.Current.MainWindow;
if (mainWindow != null)
{
mainWindow.Show();
mainWindow.WindowState = mainWindow.WindowState = WindowState.Normal;
mainWindow.Activate();
}
var result = MessageBoxHelper.Show(
LocalizationHelper.GetString("LanguageChangedTip"),
LocalizationHelper.GetString("Tip"),
MessageBoxButton.OKCancel,
MessageBoxImage.Question,
ok: LocalizationHelper.GetString("Ok"),
cancel: LocalizationHelper.GetString("ManualRestart"));
if (result == MessageBoxResult.OK)
{
Bootstrapper.ShutdownAndRestartWithoutArgs();
}
SetAndNotify(ref _operNameLanguage, value);
}
}
public string OperNameLocalization
{
get
{
if (_operNameLanguage == "OperNameLanguageClient")
{
return _clientLanguageMapper[ConfigurationHelper.GetValue(ConfigurationKeys.ClientType, string.Empty)];
}
return _language;
}
}
#endregion
#region HotKey

View File

@@ -93,6 +93,17 @@
SelectedValue="{Binding Language}"
SelectedValuePath="Value"
Style="{StaticResource ComboBoxExtend}" />
<ComboBox
Width="180"
Margin="10"
HorizontalAlignment="Right"
VerticalAlignment="Center"
hc:InfoElement.Title="{DynamicResource OperNameLanguage}"
DisplayMemberPath="Display"
ItemsSource="{Binding OperNameLanguageModeList}"
SelectedValue="{Binding OperNameLanguage}"
SelectedValuePath="Value"
Style="{StaticResource ComboBoxExtend}" />
<ComboBox
Width="180"
Margin="10"