导表修改

This commit is contained in:
2025-10-09 23:58:11 +08:00
parent 547d234ad3
commit 520d4f37bd
8 changed files with 95 additions and 305 deletions

View File

@@ -1,169 +0,0 @@
using System.Reflection;
using Fantasy.Serialize;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using ProtoBuf;
namespace NBConfigBuilder;
/// <summary>
/// 动态程序集类,用于加载动态生成的程序集并获取动态信息。
/// </summary>
public static class DynamicAssembly
{
private static void MetadataReference(out string assemblyName, out List<MetadataReference> metadataReferenceList)
{
AssemblyMetadata assemblyMetadata;
MetadataReference metadataReference;
var currentDomain = AppDomain.CurrentDomain;
assemblyName = Path.GetRandomFileName();
var assemblyArray = currentDomain.GetAssemblies();
metadataReferenceList = new List<MetadataReference>();
// 注册引用
foreach (var domainAssembly in assemblyArray)
{
if (string.IsNullOrEmpty(domainAssembly.Location))
{
continue;
}
assemblyMetadata = AssemblyMetadata.CreateFromFile(domainAssembly.Location);
metadataReference = assemblyMetadata.GetReference();
metadataReferenceList.Add(metadataReference);
}
// 添加Proto支持
assemblyMetadata = AssemblyMetadata.CreateFromFile(typeof(ProtoMemberAttribute).Assembly.Location);
metadataReference = assemblyMetadata.GetReference();
metadataReferenceList.Add(metadataReference);
// 添加Fantasy支持
assemblyMetadata = AssemblyMetadata.CreateFromFile(typeof(ASerialize).Assembly.Location);
metadataReference = assemblyMetadata.GetReference();
metadataReferenceList.Add(metadataReference);
}
/// <summary>
/// 加载指定路径下的动态程序集。
/// </summary>
/// <param name="path">程序集文件路径。</param>
/// <returns>加载的动态程序集。</returns>
public static Assembly Load(string path)
{
var fileList = new List<string>();
// 找到所有需要加载的CS文件
foreach (string file in Directory.GetFiles(path))
{
if (Path.GetExtension(file) != ".cs")
{
continue;
}
fileList.Add(file);
}
var syntaxTreeList = new List<SyntaxTree>();
foreach (var file in fileList)
{
using var fileStream = new StreamReader(file);
var cSharp = CSharpSyntaxTree.ParseText(fileStream.ReadToEnd());
syntaxTreeList.Add(cSharp);
}
// 注册程序集
MetadataReference(out var assemblyName, out var metadataReferenceList);
var compilation = CSharpCompilation.Create(assemblyName, syntaxTreeList, metadataReferenceList, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using var ms = new MemoryStream();
var result = compilation.Emit(ms);
if (!result.Success)
{
foreach (var resultDiagnostic in result.Diagnostics)
{
Log.Error(resultDiagnostic.GetMessage());
}
throw new Exception("failures");
}
ms.Seek(0, SeekOrigin.Begin);
return Assembly.Load(ms.ToArray());
}
/// <summary>
/// 获取动态程序集中指定表格的动态信息。
/// </summary>
/// <param name="dynamicAssembly">动态程序集。</param>
/// <param name="tableName">表格名称。</param>
/// <returns>动态信息对象。</returns>
public static DynamicConfigDataType GetDynamicInfo(Assembly dynamicAssembly, string tableName)
{
var dynamicConfigDataType = new DynamicConfigDataType
{
ConfigDataType = GetConfigType(dynamicAssembly, $"{tableName}Data"),
ConfigType = GetConfigType(dynamicAssembly, $"{tableName}")
};
dynamicConfigDataType.ConfigData = CreateInstance(dynamicConfigDataType.ConfigDataType);
var listPropertyType = dynamicConfigDataType.ConfigDataType.GetProperty("List");
if (listPropertyType == null)
{
throw new Exception("No Property named Add was found");
}
dynamicConfigDataType.Obj = listPropertyType.GetValue(dynamicConfigDataType.ConfigData);
dynamicConfigDataType.Method = listPropertyType.PropertyType.GetMethod("Add");
if (dynamicConfigDataType.Method == null)
{
throw new Exception("No method named Add was found");
}
return dynamicConfigDataType;
}
/// <summary>
/// 根据类型名称获取动态类型。
/// </summary>
/// <param name="dynamicAssembly">动态程序集。</param>
/// <param name="typeName">类型名称。</param>
/// <returns>动态类型。</returns>
private static Type GetConfigType(Assembly dynamicAssembly, string typeName)
{
var configType = dynamicAssembly.GetType($"Fantasy.{typeName}");
if (configType == null)
{
throw new FileNotFoundException($"Fantasy.{typeName} not found");
}
return configType;
// return dynamicAssembly.GetType($"Fantasy.{typeName}");
}
/// <summary>
/// 创建动态实例。
/// </summary>
/// <param name="configType">动态类型。</param>
/// <returns>动态实例。</returns>
public static object CreateInstance(Type configType)
{
var config = Activator.CreateInstance(configType);
if (config == null)
{
throw new Exception($"{configType.Name} is Activator.CreateInstance error");
}
return config;
}
}

View File

@@ -1,35 +0,0 @@
using System.Reflection;
using System.Text;
namespace NBConfigBuilder;
/// <summary>
/// 动态配置数据类型类,用于存储动态配置数据的相关信息。
/// </summary>
public class DynamicConfigDataType
{
/// <summary>
/// 配置数据对象,继承自 AProto 基类。
/// </summary>
public object ConfigData;
/// <summary>
/// 配置数据类型。
/// </summary>
public Type ConfigDataType;
/// <summary>
/// 配置类型。
/// </summary>
public Type ConfigType;
/// <summary>
/// 反射方法信息,用于调用特定方法。
/// </summary>
public MethodInfo Method;
/// <summary>
/// 配置数据对象实例。
/// </summary>
public object Obj;
/// <summary>
/// 用于生成 JSON 格式数据的字符串构建器。
/// </summary>
public StringBuilder Json = new StringBuilder();
}

View File

@@ -1,69 +0,0 @@
using System.Reflection;
using Fantasy.Serialize;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using ProtoBuf;
namespace NBConfigBuilder;
public class OneDynamicAssembly
{
private readonly List<SyntaxTree> _syntaxTreeList = new List<SyntaxTree>();
public void Load(string file)
{
using var fileStream = new StreamReader(file);
var cSharp = CSharpSyntaxTree.ParseText(fileStream.ReadToEnd());
_syntaxTreeList.Add(cSharp);
}
public Assembly Assembly
{
get
{
AssemblyMetadata assemblyMetadata;
MetadataReference metadataReference;
var currentDomain = AppDomain.CurrentDomain;
var assemblyName = Path.GetRandomFileName();
var assemblyArray = currentDomain.GetAssemblies();
var metadataReferenceList = new List<MetadataReference>();
// 注册引用
foreach (var domainAssembly in assemblyArray)
{
if (string.IsNullOrEmpty(domainAssembly.Location))
{
continue;
}
assemblyMetadata = AssemblyMetadata.CreateFromFile(domainAssembly.Location);
metadataReference = assemblyMetadata.GetReference();
metadataReferenceList.Add(metadataReference);
}
// 添加ProtoEntity支持
assemblyMetadata = AssemblyMetadata.CreateFromFile(typeof(ASerialize).Assembly.Location);
metadataReference = assemblyMetadata.GetReference();
metadataReferenceList.Add(metadataReference);
// 添加MessagePack支持
assemblyMetadata = AssemblyMetadata.CreateFromFile(typeof(ProtoMemberAttribute).Assembly.Location);
metadataReference = assemblyMetadata.GetReference();
metadataReferenceList.Add(metadataReference);
CSharpCompilation compilation = CSharpCompilation.Create(assemblyName, _syntaxTreeList, metadataReferenceList, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using var ms = new MemoryStream();
var result = compilation.Emit(ms);
if (!result.Success)
{
foreach (var resultDiagnostic in result.Diagnostics)
{
Log.Error(resultDiagnostic.GetMessage());
}
throw new Exception("failures");
}
ms.Seek(0, SeekOrigin.Begin);
return Assembly.Load(ms.ToArray());
}
}
}

View File

@@ -21,14 +21,14 @@ public sealed class ExcelExporter
public ExportType ExportType;
private readonly string _excelProgramPath;
private readonly string _versionFilePath;
// public VersionInfo VersionInfo; // 存储 Excel 文件的版本信息。
private readonly Regex _regexName = new Regex("^[a-zA-Z][a-zA-Z0-9_]*$"); // 用于验证 Excel 表名的正则表达式。
private readonly HashSet<string> _loadFiles = [".xlsx", ".xlsm", ".csv"]; // 加载的支持文件扩展名。
private readonly ConcurrentDictionary<string, ExcelTable> _excelTables =
new ConcurrentDictionary<string, ExcelTable>(); // 存储解析后的 Excel 表。
/// <summary>
/// 导表支持的数据类型集合。
/// </summary>
@@ -635,6 +635,12 @@ public sealed class ExcelExporter
var colInfos = isServer ? table.ServerColInfos : table.ClientColInfos;
var exportPath = isServer ? App.Config.ServerPath : App.Config.ClientPath;
var csNamespace = isServer ? App.Config.ServerNamespace : App.Config.ClientNamespace;
if (string.IsNullOrEmpty(csNamespace))
{
csNamespace = "NB";
}
if (colInfos.Count <= 0)
{
return;
@@ -723,7 +729,7 @@ public sealed class ExcelExporter
FileHelper.CreateDirectory(exportPath);
}
var content = template.Replace("(namespace)", "Fantasy")
var content = template.Replace("(namespace)", csNamespace)
.Replace("(ConfigName)", csName)
.Replace("(Fields)", fileBuilder.ToString());
File.WriteAllText(Path.Combine(exportPath, $"{csName}.cs"), content);