多语言:de fr es pl ru ja 六种语言表;匿名币改称隐私币;英文手册数字改占位符

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Sonnet 5.5 committed 2026-11-04 14:26:21 +08:00
1 parent 0520895b18
commit f5de68aea9
12 files changed
+4913 -9

No files matched your search

+38 -3
View File
@@ -1504,21 +1504,21 @@ internal static class Program
finally { StoryMods.Current = saved; }
});
Test("黑市商家收币:每类商家都收 CRT 或匿名币,平台收 PSC、CRT、CRA", () =>
Test("黑市商家收币:每类商家都收 CRT 或隐私币,平台收 PSC、CRT、CRA", () =>
{
foreach (MerchantType ty in Enum.GetValues(typeof(MerchantType)))
{
var acc = Merchants.Accepts(ty);
Check(acc.Length >= 2 && acc.Distinct().Count() == acc.Length && acc.All(a => a == Assets.PSC || a == Assets.CRT || a == Assets.CRA || a == Assets.Ponero), $"{ty} 收 {string.Join("/", acc)}");
}
Check(Merchants.Accepts(MerchantType.Arms).Contains(Assets.Ponero) && !Merchants.Accepts(MerchantType.Rigs).Contains(Assets.Ponero), "违禁类收匿名币,硬件类不收");
Check(Merchants.Accepts(MerchantType.Arms).Contains(Assets.Ponero) && !Merchants.Accepts(MerchantType.Rigs).Contains(Assets.Ponero), "违禁类收隐私币,硬件类不收");
Check(Merchants.PlatformAccepts.Contains(Assets.CRT) && Tuning.BmAutoSwapSlip > Tuning.DexFee * 10, "自动换币的滑点远高于 DEX 手续费");
});
Test("手册数值占位符:中英文都能从 Tuning 取到值,渲染后不留花括号", () =>
{
var dir = System.IO.Path.GetFullPath(System.IO.Path.Combine(AppContext.BaseDirectory, "../../../../../src/Decentralized/ModFiles/Localization"));
foreach (var lang in new[] { "zh", "en" })
foreach (var lang in new[] { "zh", "en", "de", "fr", "es", "pl", "ru", "ja" })
{
var line = System.IO.File.ReadAllLines(System.IO.Path.Combine(dir, lang + ".csv")).First(l => l.StartsWith("guide.web3.text,"));
var text = line.Substring("guide.web3.text,".Length).Trim('"').Replace("\"\"", "\"");
@@ -1530,6 +1530,41 @@ internal static class Program
Check(TuningText.Render("{BmListFee:%}") == "5%" && TuningText.Render("{PonziRates[4]:%}") == "10%" && TuningText.Render("{WalletMax}") == "5", "格式:百分比、数组下标、整数");
});
Test("多语言表:8 种语言键集合与英文一致,占位符和标记一致", () =>
{
var dir = System.IO.Path.GetFullPath(System.IO.Path.Combine(AppContext.BaseDirectory, "../../../../../src/Decentralized/ModFiles/Localization"));
Func<string, Dictionary<string, string>> load = lang =>
{
var d = new Dictionary<string, string>();
foreach (var line in System.IO.File.ReadAllLines(System.IO.Path.Combine(dir, lang + ".csv")))
{
if (string.IsNullOrWhiteSpace(line) || line.StartsWith("#")) continue;
int c = line.IndexOf(',');
Check(c > 0, lang + " 行没有逗号:" + line);
var v = line.Substring(c + 1).Trim();
if (v.Length >= 2 && v[0] == '"' && v[v.Length - 1] == '"') v = v.Substring(1, v.Length - 2).Replace("\"\"", "\"");
d[line.Substring(0, c).Trim()] = v;
}
return d;
};
var en = load("en");
var ph = new System.Text.RegularExpressions.Regex(@"\{[^{}]+\}");
foreach (var lang in new[] { "zh", "de", "fr", "es", "pl", "ru", "ja" })
{
var d = load(lang);
Check(d.Keys.OrderBy(x => x).SequenceEqual(en.Keys.OrderBy(x => x)), lang + " 键集合和英文不同");
foreach (var kv in en)
{
var v = d[kv.Key];
Check(ph.Matches(kv.Value).Cast<System.Text.RegularExpressions.Match>().Select(m => m.Value).OrderBy(x => x)
.SequenceEqual(ph.Matches(v).Cast<System.Text.RegularExpressions.Match>().Select(m => m.Value).OrderBy(x => x)), lang + " 占位符不一致:" + kv.Key);
foreach (var mark in new[] { "§", "¶", "\\n" })
Check(kv.Value.Split(new[] { mark }, StringSplitOptions.None).Length == v.Split(new[] { mark }, StringSplitOptions.None).Length, lang + " 标记 " + mark + " 数量不一致:" + kv.Key);
if (lang != "zh" && lang != "ja") Check(!System.Text.RegularExpressions.Regex.IsMatch(v, "[\u3040-\u30ff\u4e00-\u9fff]"), lang + " 有汉字或假名:" + kv.Key);
}
}
});
Test("预测市场:先验概率", () =>
{
Check(Math.Abs(PredictMath.PurityAtLeast(8500, 8000, 8999) - 0.5) < 1e-9, "纯度 8500 以上一半");