Merge pull request #983 from kwsch/r/checkstrings-refactor

Refactored implementation of #959
This commit is contained in:
Kurt 2017-03-24 16:51:44 -07:00 committed by GitHub
commit 7650ade09b
11 changed files with 148 additions and 116 deletions

View File

@ -12,6 +12,7 @@
using PKHeX.Core;
using PKHeX.Core.Properties;
using System.Configuration;
using System.Threading.Tasks;
namespace PKHeX.WinForms
{
@ -1390,6 +1391,14 @@ private static void refreshWC7DB()
// Language Translation
private void changeMainLanguage(object sender, EventArgs e)
{
if (CB_MainLanguage.SelectedIndex < 8)
curlanguage = GameInfo.lang_val[CB_MainLanguage.SelectedIndex];
// Set the culture (makes it easy to pass language to other forms)
Properties.Settings.Default.Language = curlanguage;
Thread.CurrentThread.CurrentCulture = new CultureInfo(curlanguage.Substring(0, 2));
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
PKM pk = SAV.getPKM((fieldsInitialized ? preparePKM() : pkm).Data);
bool alreadyInit = fieldsInitialized;
fieldsInitialized = false;
@ -1402,24 +1411,16 @@ private void changeMainLanguage(object sender, EventArgs e)
// Recenter PKM SubEditors
FLP_PKMEditors.Location = new Point((Tab_OTMisc.Width - FLP_PKMEditors.Width)/2, FLP_PKMEditors.Location.Y);
populateFields(pk); // put data back in form
fieldsInitialized |= alreadyInit;
// Set the culture (makes it easy to pass language to other forms)
Properties.Settings.Default.Language = curlanguage;
Thread.CurrentThread.CurrentCulture = new CultureInfo(curlanguage.Substring(0, 2));
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
fieldsInitialized |= alreadyInit;
}
private void InitializeStrings()
{
if (CB_MainLanguage.SelectedIndex < 8)
curlanguage = GameInfo.lang_val[CB_MainLanguage.SelectedIndex];
{
string l = curlanguage;
GameInfo.Strings = GameInfo.getStrings(l);
// Update Legality Strings
// Clipboard.SetText(string.Join(Environment.NewLine, CheckStrings.getLocalization()));
new Thread(() => { CheckStrings.setLocalization(GameInfo.getCheckStrings(l)); }).Start();
Task.Run(() => Util.setLocalization(typeof(LegalityCheckStrings)));
// Force an update to the met locations
origintrack = GameVersion.Unknown;

View File

@ -9,9 +9,7 @@ public static class GameInfo
private static readonly string[] ptransp = { "ポケシフター", "Poké Transfer", "Poké Fret", "Pokétrasporto", "Poképorter", "Pokétransfer", "포케시프터", "宝可传送", "寶可傳送", "ポケシフター" };
public static readonly string[] lang_val = { "ja", "en", "fr", "it", "de", "es", "ko", "zh", "zh2", "pt" };
private const string DefaultLanguage = "en";
private const string LegalityName = "legality_";
private static readonly GameStrings[] Languages = new GameStrings[lang_val.Length];
private static readonly string[][] CheckStrings = new string[lang_val.Length][];
// Lazy fetch implementation
private static int DefaultLanguageIndex => Array.IndexOf(lang_val, DefaultLanguage);
@ -25,11 +23,6 @@ public static GameStrings getStrings(string lang)
int index = getLanguageIndex(lang);
return Languages[index] ?? (Languages[index] = new GameStrings(lang_val[index]));
}
public static IEnumerable<string> getCheckStrings(string lang)
{
int index = getLanguageIndex(lang);
return CheckStrings[index] ?? (CheckStrings[index] = Util.getStringList(LegalityName + lang_val[index]));
}
private static string getTransporterName(string lang)
{
int index = getLanguageIndex(lang);

View File

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using static PKHeX.Core.CheckStrings;
using static PKHeX.Core.LegalityCheckStrings;
namespace PKHeX.Core
{

View File

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using static PKHeX.Core.CheckStrings;
using static PKHeX.Core.LegalityCheckStrings;
namespace PKHeX.Core
{

View File

@ -7,57 +7,8 @@
namespace PKHeX.Core
{
public static class CheckStrings
public static class LegalityCheckStrings
{
private const string splitter = " = ";
private static readonly Type t = typeof(CheckStrings);
private static string[] getProps(IEnumerable<string> input)
{
return input.Select(l => l.Substring(0, l.IndexOf(splitter, StringComparison.Ordinal))).ToArray();
}
private static IEnumerable<string> DumpStrings()
{
var props = ReflectUtil.getPropertiesStartWithPrefix(t, "V");
return props.Select(p => $"{p}{splitter}{ReflectUtil.GetValue(t, p).ToString()}");
}
public static void setLocalization(IEnumerable<string> lines)
{
if (lines == null)
return;
foreach (var line in lines.Where(l => l != null))
{
var index = line.IndexOf(splitter, StringComparison.Ordinal);
if (index < 0)
continue;
var prop = line.Substring(0, index);
var value = line.Substring(index + splitter.Length);
try
{
ReflectUtil.SetValue(t, prop.ToUpper(), value);
}
catch
{
Console.WriteLine($"Property not present: {prop} || Value written: {value}");
}
}
}
public static string[] getLocalization(string[] existingLines = null)
{
existingLines = existingLines ?? new string[0];
var currentLines = DumpStrings().ToArray();
var existing = getProps(existingLines);
var current = getProps(currentLines);
var result = new string[currentLines.Length];
for (int i = 0; i < current.Length; i++)
{
int index = Array.IndexOf(existing, current[i]);
result[i] = index < 0 ? currentLines[i] : existingLines[index];
}
return result;
}
#region General Strings

View File

@ -152,7 +152,7 @@
<Compile Include="Game\GameVersion.cs" />
<Compile Include="Legality\Analysis.cs" />
<Compile Include="Legality\Checks.cs" />
<Compile Include="Legality\CheckStrings.cs" />
<Compile Include="Legality\LegalityCheckStrings.cs" />
<Compile Include="Legality\Core.cs" />
<Compile Include="Legality\Data.cs" />
<Compile Include="Legality\Structures\DexLevel.cs" />
@ -3521,8 +3521,8 @@
<ItemGroup>
<Content Include="Resources\img\misc\horohoro.png" />
<Content Include="Resources\img\misc\vc.png" />
<None Include="Resources\text\en\legality_en.txt" />
<None Include="Resources\text\zh\legality_zh.txt" />
<None Include="Resources\text\en\LegalityCheckStrings_en.txt" />
<None Include="Resources\text\zh\LegalityCheckStrings_zh.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -18156,47 +18156,45 @@ public class Resources {
///V201 = Encryption Constant is not set.
///V204 = H [rest of string was truncated]&quot;;.
/// </summary>
public static string legality_en {
public static string LegalityCheckStrings_en {
get {
return ResourceManager.GetString("legality_en", resourceCulture);
return ResourceManager.GetString("LegalityCheckStrings_en", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to V = 有效.
///V193 = 合法!
///V190 = 内部错误.
///V189 = 无法对该宝可梦分析.
///V196 = {0}: {1}
///V191 = {0} 招式 {1}: {2}
///V192 = {0} 回忆招式 {1}: {2}
///V195 = 相遇方式: {0}
///V205 = 初训家
///V206 = 持有人
///V167 = 空招式.
///V171 = 遗传招式.
///V172 = 可回忆招式.
///V173 = 通过TM/HM学习.
///V174 = 通过招式教学学习.
///V175 = 特殊不可回忆招式.
///V177 = 升级招式.
///V203 = 无性别宝可梦不能没有性别.
///V201 = 未设置加密常数.
///V204 = 持有物未解禁.
///V187 = 种类在原始版本中不存在.
///V188 = 没有匹配的命中注定遇见. 神秘礼物数据有被共享吗?
///V194 = 太阳月亮游戏内交换功能尚未开发.
///V207 = 未设置PID.
///V208 = 加密常数与PID一致.
///V209 = 定点闪光不匹配.
///V210 = 刺尾虫进化形态与加密常数不一致.
///V211 = 加密常数 与 异色xor PID 匹配.
///V212 = 刺尾虫进化形态: {0}
///V213 [rest of string was truncated]&quot;;.
/// Looks up a localized string similar to V = 有效。
///V193 = 合法。
///V190 = 内部错误。
///V189 = 无法对该宝可梦分析。
///V196 = {0}: {1}
///V191 = {0} 招式 {1}: {2}
///V192 = {0} 回忆招式 {1}: {2}
///V195 = 相遇方式: {0}
///V205 = 初训家
///V206 = 持有人
///V167 = 空招式。
///V171 = 遗传招式。
///V172 = 可回忆招式。
///V173 = 通过TM/HM习得。
///V174 = 通过招式教学习得。
///V175 = 特殊不可回忆招式。
///V177 = 通过升级习得。
///V203 = 无性别宝可梦不能有性别。
///V201 = 未设置加密常数。
///V204 = 持有物未解禁。
///V187 = 该种宝可梦在原始版本中不存在。
///V188 = 没有匹配的“命中注定遇见”的数据。 该神秘礼物有被共享吗?
///V194 = 太阳月亮游戏内交换宝可梦的功能尚未开发。
///V207 = 未设置PID。
///V208 = 加密常数与PID一致。
///V209 = 定点相遇闪光条件不匹配。
///V210 = 刺尾虫进化形态与加密常数不一致。
///V211 = 加密 [rest of string was truncated]&quot;;.
/// </summary>
public static string legality_zh {
public static string LegalityCheckStrings_zh {
get {
return ResourceManager.GetString("legality_zh", resourceCulture);
return ResourceManager.GetString("LegalityCheckStrings_zh", resourceCulture);
}
}
@ -27650,10 +27648,10 @@ public class Resources {
///
///
///Go
///
///藍色[INT]/綠色[JP]
///藍色[JP]
///黃色.
///
///蓝[国际]/绿[日]
///蓝[日]
///.
/// </summary>
public static string text_games_zh {
get {

View File

@ -7561,10 +7561,10 @@
<data name="pgf" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\byte\pgf.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="legality_en" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\text\en\legality_en.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-16</value>
<data name="LegalityCheckStrings_en" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\text\en\LegalityCheckStrings_en.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-16</value>
</data>
<data name="legality_zh" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\text\zh\legality_zh.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
<data name="LegalityCheckStrings_zh" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\text\zh\LegalityCheckStrings_zh.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
</root>

View File

@ -1,12 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
namespace PKHeX.Core
{
public partial class Util
{
private const string TranslationSplitter = " = ";
#region String Lists
/// <summary>
@ -127,7 +130,93 @@ public static string[] getNulledStringArray(string[] SimpleStringList)
}
catch { return null; }
}
#region Non-Form Translation
/// <summary>
/// Gets the names of the properties defined in the given input
/// </summary>
/// <param name="input">Enumerable of translation definitions in the form "Property = Value".</param>
/// <returns></returns>
private static string[] getProps(IEnumerable<string> input)
{
return input.Select(l => l.Substring(0, l.IndexOf(TranslationSplitter, StringComparison.Ordinal))).ToArray();
}
private static IEnumerable<string> DumpStrings(Type t)
{
var props = ReflectUtil.getPropertiesStartWithPrefix(t, "V");
return props.Select(p => $"{p}{TranslationSplitter}{ReflectUtil.GetValue(t, p).ToString()}");
}
/// <summary>
/// Gets the current localization in a static class containing language-specific strings
/// </summary>
public static string[] getLocalization(Type t, string[] existingLines = null)
{
existingLines = existingLines ?? new string[0];
var currentLines = DumpStrings(t).ToArray();
var existing = getProps(existingLines);
var current = getProps(currentLines);
var result = new string[currentLines.Length];
for (int i = 0; i < current.Length; i++)
{
int index = Array.IndexOf(existing, current[i]);
result[i] = index < 0 ? currentLines[i] : existingLines[index];
}
return result;
}
/// <summary>
/// Applies localization to a static class containing language-specific strings.
/// </summary>
/// <typeparam name="T">Type of the static class containing the desired strings.</typeparam>
/// <param name="lines">Lines containing the localized strings</param>
public static void setLocalization(Type t, IEnumerable<string> lines)
{
if (lines == null)
return;
foreach (var line in lines.Where(l => l != null))
{
var index = line.IndexOf(TranslationSplitter, StringComparison.Ordinal);
if (index < 0)
continue;
var prop = line.Substring(0, index);
var value = line.Substring(index + TranslationSplitter.Length);
try
{
ReflectUtil.SetValue(t, prop.ToUpper(), value);
}
catch
{
Console.WriteLine($"Property not present: {prop} || Value written: {value}");
}
}
}
/// <summary>
/// Applies localization to a static class containing language-specific strings.
/// </summary>
/// <typeparam name="T">Type of the static class containing the desired strings.</typeparam>
/// <param name="languageFilePrefix">Prefix of the language file to use. Example: if the target is legality_en.txt, <paramref name="languageFilePrefix"/> should be "legality".</param>
public static void setLocalization(Type t, string languageFilePrefix)
{
setLocalization(t, getStringList($"{languageFilePrefix}_{Thread.CurrentThread.CurrentCulture.Name.Substring(0, 2)}"));
}
/// <summary>
/// Applies localization to a static class containing language-specific strings.
/// </summary>
/// <typeparam name="T">Type of the static class containing the desired strings.</typeparam>
/// <remarks>The values used to translate the given static class are retrieved from [TypeName]_[CurrentLangCode2].txt in the resource manager of PKHeX.Core.</remarks>
public static void setLocalization(Type t)
{
setLocalization(t, t.Name);
}
#endregion
#region DataSource Providing
public static List<ComboItem> getCBList(string textfile, string lang)
{