using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using TeamAAS.Localization;
namespace TeamAAS.Tools
{
///
/// 多语言翻译模板生成器 - 自动扫描插件并生成翻译模板
///
public class LocalizationTemplateGenerator
{
///
/// 扫描程序集中的所有插件模型并生成翻译模板
///
/// 要扫描的程序集列表
/// 输出模板文件路径
/// 目标语言代码(如 "en-US")
public static void GenerateTemplate(Assembly[] assemblies, string outputPath, string languageCode = "en-US")
{
var pack = new LanguageResourcePack
{
LanguageCode = languageCode,
LanguageName = GetLanguageName(languageCode),
Version = "1.0.0",
Author = "Auto Generated"
};
// 扫描所有插件模型
foreach (var assembly in assemblies)
{
ScanAssembly(assembly, pack);
}
// 序列化为 JSON
var options = new JsonSerializerOptions
{
WriteIndented = true,
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
var json = JsonSerializer.Serialize(pack, options);
File.WriteAllText(outputPath, json);
Console.WriteLine($"翻译模板已生成: {outputPath}");
Console.WriteLine($" - 类型数: {pack.Properties.Count}");
Console.WriteLine($" - 属性数: {pack.Properties.Sum(p => p.Value.Count)}");
Console.WriteLine($" - 插件数: {pack.Plugins.Count}");
}
///
/// 扫描单个程序集
///
private static void ScanAssembly(Assembly assembly, LanguageResourcePack pack)
{
try
{
var types = assembly.GetTypes();
foreach (var type in types)
{
// 扫描插件模型(继承自 BasePluginModel)
if (IsPluginModel(type))
{
ScanPluginModel(type, pack);
}
// 扫描插件类(带 PluginAttribute)
if (IsPlugin(type))
{
ScanPlugin(type, pack);
}
// 扫描枚举类型
if (type.IsEnum)
{
ScanEnum(type, pack);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"警告: 扫描程序集 {assembly.FullName} 时出错: {ex.Message}");
}
}
///
/// 扫描插件模型类型
///
private static void ScanPluginModel(Type type, LanguageResourcePack pack)
{
var typeName = type.Name;
var properties = new Dictionary();
foreach (var prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
// 跳过标记为 Browsable(false) 的属性
var browsable = prop.GetCustomAttribute();
if (browsable != null && !browsable.Browsable)
continue;
var displayNameAttr = prop.GetCustomAttribute();
var descriptionAttr = prop.GetCustomAttribute();
var categoryAttr = prop.GetCustomAttribute();
properties[prop.Name] = new PropertyTranslation
{
DisplayName = displayNameAttr?.DisplayName ?? $"[TODO: {prop.Name}]",
Description = descriptionAttr?.Description ?? $"[TODO: Description for {prop.Name}]",
Category = categoryAttr?.Category ?? "Miscellaneous"
};
}
if (properties.Count > 0)
{
pack.Properties[typeName] = properties;
}
}
///
/// 扫描插件类
///
private static void ScanPlugin(Type type, LanguageResourcePack pack)
{
var pluginAttr = type.GetCustomAttributes(false)
.FirstOrDefault(a => a.GetType().Name == "PluginAttribute");
if (pluginAttr != null)
{
var displayNameProp = pluginAttr.GetType().GetProperty("DisplayName");
var descriptionProp = pluginAttr.GetType().GetProperty("Description");
var categoryProp = pluginAttr.GetType().GetProperty("Category");
var displayName = displayNameProp?.GetValue(pluginAttr)?.ToString();
var description = descriptionProp?.GetValue(pluginAttr)?.ToString();
var category = categoryProp?.GetValue(pluginAttr)?.ToString();
if (!string.IsNullOrWhiteSpace(displayName))
{
pack.Plugins[type.Name] = new PluginTranslation
{
DisplayName = displayName,
Description = description ?? $"[TODO: Description for {type.Name}]",
Category = category?.ToString() ?? "Others"
};
}
}
}
///
/// 扫描枚举类型
///
private static void ScanEnum(Type type, LanguageResourcePack pack)
{
var enumValues = new Dictionary();
foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Static))
{
var displayNameAttr = field.GetCustomAttribute();
var displayName = displayNameAttr?.DisplayName ?? field.Name;
enumValues[field.Name] = $"[TODO: {displayName}]";
}
if (enumValues.Count > 0)
{
pack.Enums[type.Name] = enumValues;
}
}
///
/// 判断是否为插件模型类型
///
private static bool IsPluginModel(Type type)
{
if (type.IsAbstract || type.IsInterface)
return false;
var baseType = type.BaseType;
while (baseType != null)
{
if (baseType.Name == "BasePluginModel")
return true;
baseType = baseType.BaseType;
}
return false;
}
///
/// 判断是否为插件类
///
private static bool IsPlugin(Type type)
{
return type.GetCustomAttributes(false)
.Any(a => a.GetType().Name == "PluginAttribute");
}
///
/// 获取语言显示名称
///
private static string GetLanguageName(string languageCode)
{
return languageCode switch
{
"zh-CN" => "简体中文",
"zh-TW" => "繁体中文",
"en-US" => "English",
"en-GB" => "English (UK)",
"ja-JP" => "日本語",
"ko-KR" => "한국어",
"de-DE" => "Deutsch",
"fr-FR" => "Français",
"es-ES" => "Español",
"ru-RU" => "Русский",
"it-IT" => "Italiano",
"pt-BR" => "Português (Brasil)",
"ar-SA" => "العربية",
"th-TH" => "ไทย",
"vi-VN" => "Tiếng Việt",
_ => languageCode
};
}
///
/// 批量生成多个语言的模板
///
public static void GenerateMultipleTemplates(Assembly[] assemblies, string outputDirectory, params string[] languageCodes)
{
if (!Directory.Exists(outputDirectory))
Directory.CreateDirectory(outputDirectory);
foreach (var langCode in languageCodes)
{
var outputPath = Path.Combine(outputDirectory, $"{langCode}.json");
GenerateTemplate(assemblies, outputPath, langCode);
}
}
///
/// 使用示例
///
public static void Example()
{
// 示例 1: 生成单个语言模板
var assemblies = new[]
{
Assembly.Load("TeamAAS.Plugins.Standard"),
Assembly.Load("TeamAAS.Plugins.Vpp"),
Assembly.Load("TeamAAS.Plugins.Feeder")
};
GenerateTemplate(
assemblies,
@"D:\Program\TeamAAS\Localization\template-en-US.json",
"en-US"
);
// 示例 2: 批量生成多个语言模板
GenerateMultipleTemplates(
assemblies,
@"D:\Program\TeamAAS\Localization\templates",
"en-US", "ja-JP", "ko-KR", "de-DE", "fr-FR"
);
Console.WriteLine("模板生成完成!");
Console.WriteLine("请编辑生成的模板文件,将 [TODO: ...] 标记替换为实际翻译。");
}
}
}