|
@@ -4,10 +4,10 @@ using System.IO;
|
|
|
using System.Linq;
|
|
using System.Linq;
|
|
|
using System.Reflection;
|
|
using System.Reflection;
|
|
|
using System.Text;
|
|
using System.Text;
|
|
|
|
|
+using System.Threading.Tasks;
|
|
|
using Microsoft.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis;
|
|
|
using Microsoft.CodeAnalysis.CSharp;
|
|
using Microsoft.CodeAnalysis.CSharp;
|
|
|
using Microsoft.CodeAnalysis.Emit;
|
|
using Microsoft.CodeAnalysis.Emit;
|
|
|
-using MongoDB.Bson;
|
|
|
|
|
using MongoDB.Bson.Serialization;
|
|
using MongoDB.Bson.Serialization;
|
|
|
using OfficeOpenXml;
|
|
using OfficeOpenXml;
|
|
|
using ProtoBuf;
|
|
using ProtoBuf;
|
|
@@ -17,10 +17,10 @@ namespace ET
|
|
|
{
|
|
{
|
|
|
public enum ConfigType
|
|
public enum ConfigType
|
|
|
{
|
|
{
|
|
|
- c,
|
|
|
|
|
- s,
|
|
|
|
|
|
|
+ c = 0,
|
|
|
|
|
+ s = 1,
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
class HeadInfo
|
|
class HeadInfo
|
|
|
{
|
|
{
|
|
|
public string FieldAttribute;
|
|
public string FieldAttribute;
|
|
@@ -38,21 +38,58 @@ namespace ET
|
|
|
this.FieldIndex = index;
|
|
this.FieldIndex = index;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // 这里加个标签是为了防止编译时裁剪掉protobuf,因为整个tool工程没有用到protobuf,编译会去掉引用,然后动态编译就会出错
|
|
|
|
|
+ [ProtoContract]
|
|
|
|
|
+ class Table
|
|
|
|
|
+ {
|
|
|
|
|
+ public bool C;
|
|
|
|
|
+ public bool S;
|
|
|
|
|
+ public int Index;
|
|
|
|
|
+ public Dictionary<string, HeadInfo> HeadInfos = new Dictionary<string, HeadInfo>();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
public static class ExcelExporter
|
|
public static class ExcelExporter
|
|
|
{
|
|
{
|
|
|
private static string template;
|
|
private static string template;
|
|
|
|
|
|
|
|
- private const string clientClassDir = "../Unity/Codes/Model/Generate/Config";
|
|
|
|
|
- private const string serverClassDir = "../Apps/Model/Generate/Config";
|
|
|
|
|
-
|
|
|
|
|
|
|
+ public const string ClientClassDir = "../Unity/Codes/Model/Generate/Config";
|
|
|
|
|
+ public const string ServerClassDir = "../Apps/Model/Generate/Config";
|
|
|
|
|
+
|
|
|
private const string excelDir = "../Excel";
|
|
private const string excelDir = "../Excel";
|
|
|
-
|
|
|
|
|
- private const string jsonDir = "./Json/{0}";
|
|
|
|
|
-
|
|
|
|
|
- private const string clientProtoDir = "../Unity/Assets/Bundles/Config";
|
|
|
|
|
- private const string serverProtoDir = "../Config";
|
|
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ private const string jsonDir = "../Excel/Json/{0}/{1}";
|
|
|
|
|
+
|
|
|
|
|
+ private const string clientProtoDir = "../Unity/Assets/Bundles/Config/{0}";
|
|
|
|
|
+ private const string serverProtoDir = "../Config/{0}";
|
|
|
|
|
+ private static Assembly[] configAssemblies = new Assembly[2];
|
|
|
|
|
+
|
|
|
|
|
+ private static Dictionary<string, Table> tables = new Dictionary<string, Table>();
|
|
|
|
|
+ private static Dictionary<string, ExcelPackage> packages = new Dictionary<string, ExcelPackage>();
|
|
|
|
|
+
|
|
|
|
|
+ private static Table GetTable(string protoName)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!tables.TryGetValue(protoName, out var table))
|
|
|
|
|
+ {
|
|
|
|
|
+ table = new Table();
|
|
|
|
|
+ tables[protoName] = table;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return table;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static ExcelPackage GetPackage(string filePath)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!packages.TryGetValue(filePath, out var package))
|
|
|
|
|
+ {
|
|
|
|
|
+ using Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
|
|
|
|
+ package = new ExcelPackage(stream);
|
|
|
|
|
+ packages[filePath] = package;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return package;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public static void Export()
|
|
public static void Export()
|
|
|
{
|
|
{
|
|
|
try
|
|
try
|
|
@@ -60,91 +97,268 @@ namespace ET
|
|
|
template = File.ReadAllText("Template.txt");
|
|
template = File.ReadAllText("Template.txt");
|
|
|
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
|
|
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
|
|
|
|
|
|
|
|
- if (Directory.Exists(clientClassDir))
|
|
|
|
|
|
|
+ if (Directory.Exists(ClientClassDir))
|
|
|
{
|
|
{
|
|
|
- Directory.Delete(clientClassDir, true);
|
|
|
|
|
|
|
+ Directory.Delete(ClientClassDir, true);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (Directory.Exists(serverClassDir))
|
|
|
|
|
|
|
+ if (Directory.Exists(ServerClassDir))
|
|
|
{
|
|
{
|
|
|
- Directory.Delete(serverClassDir, true);
|
|
|
|
|
|
|
+ Directory.Delete(ServerClassDir, true);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
foreach (string path in Directory.GetFiles(excelDir))
|
|
foreach (string path in Directory.GetFiles(excelDir))
|
|
|
{
|
|
{
|
|
|
string fileName = Path.GetFileName(path);
|
|
string fileName = Path.GetFileName(path);
|
|
|
- if (!fileName.EndsWith(".xlsx") || fileName.StartsWith("~$"))
|
|
|
|
|
|
|
+ if (!fileName.EndsWith(".xlsx") || fileName.StartsWith("~$") || fileName.Contains("#"))
|
|
|
{
|
|
{
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
- using Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
|
|
|
|
- using ExcelPackage p = new ExcelPackage(stream);
|
|
|
|
|
- string name = Path.GetFileNameWithoutExtension(path);
|
|
|
|
|
|
|
|
|
|
- string cs = p.Workbook.Worksheets[0].Cells[1, 1].Text.Trim();
|
|
|
|
|
- if (cs.Contains("#"))
|
|
|
|
|
|
|
+ string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
|
|
|
|
|
+ string fileNameWithoutCS = fileNameWithoutExtension;
|
|
|
|
|
+ string cs = "cs";
|
|
|
|
|
+ if (fileNameWithoutExtension.Contains("@"))
|
|
|
{
|
|
{
|
|
|
- continue;
|
|
|
|
|
|
|
+ string[] ss = fileNameWithoutExtension.Split("@");
|
|
|
|
|
+ fileNameWithoutCS = ss[0];
|
|
|
|
|
+ cs = ss[1];
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
if (cs == "")
|
|
if (cs == "")
|
|
|
{
|
|
{
|
|
|
cs = "cs";
|
|
cs = "cs";
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ ExcelPackage p = GetPackage(Path.GetFullPath(path));
|
|
|
|
|
+
|
|
|
|
|
+ string protoName = fileNameWithoutCS;
|
|
|
|
|
+ if (fileNameWithoutCS.Contains('_'))
|
|
|
|
|
+ {
|
|
|
|
|
+ protoName = fileNameWithoutCS.Substring(0, fileNameWithoutCS.LastIndexOf('_'));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Table table = GetTable(protoName);
|
|
|
|
|
+
|
|
|
if (cs.Contains("c"))
|
|
if (cs.Contains("c"))
|
|
|
{
|
|
{
|
|
|
- ExportExcelClass(p, name, ConfigType.c);
|
|
|
|
|
|
|
+ table.C = true;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
if (cs.Contains("s"))
|
|
if (cs.Contains("s"))
|
|
|
{
|
|
{
|
|
|
- ExportExcelClass(p, name, ConfigType.s);
|
|
|
|
|
|
|
+ table.S = true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ExportExcelClass(p, protoName, table);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ foreach (var kv in tables)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (kv.Value.C)
|
|
|
|
|
+ {
|
|
|
|
|
+ ExportClass(kv.Key, kv.Value.HeadInfos, ConfigType.c);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (kv.Value.S)
|
|
|
|
|
+ {
|
|
|
|
|
+ ExportClass(kv.Key, kv.Value.HeadInfos, ConfigType.s);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- ExportExcelProtobuf(ConfigType.c);
|
|
|
|
|
- ExportExcelProtobuf(ConfigType.s);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 动态编译生成的配置代码
|
|
|
|
|
+ configAssemblies[(int) ConfigType.c] = DynamicBuild(ConfigType.c);
|
|
|
|
|
+ configAssemblies[(int) ConfigType.s] = DynamicBuild(ConfigType.s);
|
|
|
|
|
+
|
|
|
|
|
+ foreach (string path in Directory.GetFiles(excelDir))
|
|
|
|
|
+ {
|
|
|
|
|
+ ExportExcel(path);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ // 多线程导出
|
|
|
|
|
+ //List<Task> tasks = new List<Task>();
|
|
|
|
|
+ //foreach (string path in Directory.GetFiles(excelDir))
|
|
|
|
|
+ //{
|
|
|
|
|
+ // Task task = Task.Run(() => ExportExcel(path));
|
|
|
|
|
+ // tasks.Add(task);
|
|
|
|
|
+ //}
|
|
|
|
|
+ //Task.WaitAll(tasks.ToArray());
|
|
|
|
|
+
|
|
|
|
|
+ // 导出StartConfig
|
|
|
|
|
+ string startConfigPath = Path.Combine(excelDir, "StartConfig");
|
|
|
|
|
+ DirectoryInfo directoryInfo = new DirectoryInfo(startConfigPath);
|
|
|
|
|
+ foreach (FileInfo subStartConfig in directoryInfo.GetFiles("*", SearchOption.AllDirectories))
|
|
|
|
|
+ {
|
|
|
|
|
+ ExportExcel(subStartConfig.FullName);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
Log.Console("Export Excel Sucess!");
|
|
Log.Console("Export Excel Sucess!");
|
|
|
}
|
|
}
|
|
|
catch (Exception e)
|
|
catch (Exception e)
|
|
|
{
|
|
{
|
|
|
Log.Console(e.ToString());
|
|
Log.Console(e.ToString());
|
|
|
}
|
|
}
|
|
|
|
|
+ finally
|
|
|
|
|
+ {
|
|
|
|
|
+ tables.Clear();
|
|
|
|
|
+ foreach (var kv in packages)
|
|
|
|
|
+ {
|
|
|
|
|
+ kv.Value.Dispose();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ packages.Clear();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private static string GetProtoDir(ConfigType configType)
|
|
|
|
|
|
|
+ private static void ExportExcel(string path)
|
|
|
|
|
+ {
|
|
|
|
|
+ string dir = Path.GetDirectoryName(path);
|
|
|
|
|
+ string relativePath = Path.GetRelativePath(excelDir, dir);
|
|
|
|
|
+ string fileName = Path.GetFileName(path);
|
|
|
|
|
+ if (!fileName.EndsWith(".xlsx") || fileName.StartsWith("~$") || fileName.Contains("#"))
|
|
|
|
|
+ {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
|
|
|
|
|
+ string fileNameWithoutCS = fileNameWithoutExtension;
|
|
|
|
|
+ string cs = "cs";
|
|
|
|
|
+ if (fileNameWithoutExtension.Contains("@"))
|
|
|
|
|
+ {
|
|
|
|
|
+ string[] ss = fileNameWithoutExtension.Split("@");
|
|
|
|
|
+ fileNameWithoutCS = ss[0];
|
|
|
|
|
+ cs = ss[1];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (cs == "")
|
|
|
|
|
+ {
|
|
|
|
|
+ cs = "cs";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ string protoName = fileNameWithoutCS;
|
|
|
|
|
+ if (fileNameWithoutCS.Contains('_'))
|
|
|
|
|
+ {
|
|
|
|
|
+ protoName = fileNameWithoutCS.Substring(0, fileNameWithoutCS.LastIndexOf('_'));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Table table = GetTable(protoName);
|
|
|
|
|
+
|
|
|
|
|
+ ExcelPackage p = GetPackage(Path.GetFullPath(path));
|
|
|
|
|
+
|
|
|
|
|
+ if (cs.Contains("c"))
|
|
|
|
|
+ {
|
|
|
|
|
+ ExportExcelJson(p, fileNameWithoutCS, table, ConfigType.c, relativePath);
|
|
|
|
|
+ ExportExcelProtobuf(ConfigType.c, protoName, relativePath);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (cs.Contains("s"))
|
|
|
|
|
+ {
|
|
|
|
|
+ ExportExcelJson(p, fileNameWithoutCS, table, ConfigType.s, relativePath);
|
|
|
|
|
+ ExportExcelProtobuf(ConfigType.s, protoName, relativePath);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static string GetProtoDir(ConfigType configType, string relativeDir)
|
|
|
{
|
|
{
|
|
|
if (configType == ConfigType.c)
|
|
if (configType == ConfigType.c)
|
|
|
{
|
|
{
|
|
|
- return clientProtoDir;
|
|
|
|
|
|
|
+ return string.Format(clientProtoDir, relativeDir);
|
|
|
}
|
|
}
|
|
|
- return serverProtoDir;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ return string.Format(serverProtoDir, relativeDir);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ private static Assembly GetAssembly(ConfigType configType)
|
|
|
|
|
+ {
|
|
|
|
|
+ return configAssemblies[(int) configType];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private static string GetClassDir(ConfigType configType)
|
|
private static string GetClassDir(ConfigType configType)
|
|
|
{
|
|
{
|
|
|
if (configType == ConfigType.c)
|
|
if (configType == ConfigType.c)
|
|
|
{
|
|
{
|
|
|
- return clientClassDir;
|
|
|
|
|
|
|
+ return ClientClassDir;
|
|
|
}
|
|
}
|
|
|
- return serverClassDir;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ return ServerClassDir;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-#region 导出class
|
|
|
|
|
- static void ExportExcelClass(ExcelPackage p, string name, ConfigType configType)
|
|
|
|
|
|
|
+ // 动态编译生成的cs代码
|
|
|
|
|
+ private static Assembly DynamicBuild(ConfigType configType)
|
|
|
|
|
+ {
|
|
|
|
|
+ string classPath = GetClassDir(configType);
|
|
|
|
|
+ List<SyntaxTree> syntaxTrees = new List<SyntaxTree>();
|
|
|
|
|
+ List<string> protoNames = new List<string>();
|
|
|
|
|
+ foreach (string classFile in Directory.GetFiles(classPath, "*.cs"))
|
|
|
|
|
+ {
|
|
|
|
|
+ protoNames.Add(Path.GetFileNameWithoutExtension(classFile));
|
|
|
|
|
+ syntaxTrees.Add(CSharpSyntaxTree.ParseText(File.ReadAllText(classFile)));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<PortableExecutableReference> references = new List<PortableExecutableReference>();
|
|
|
|
|
+ Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
|
|
|
|
+ foreach (Assembly assembly in assemblies)
|
|
|
|
|
+ {
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ if (assembly.IsDynamic)
|
|
|
|
|
+ {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (assembly.Location == "")
|
|
|
|
|
+ {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (Exception e)
|
|
|
|
|
+ {
|
|
|
|
|
+ Console.WriteLine(e);
|
|
|
|
|
+ throw;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ PortableExecutableReference reference = MetadataReference.CreateFromFile(assembly.Location);
|
|
|
|
|
+ references.Add(reference);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ CSharpCompilation compilation = CSharpCompilation.Create(null,
|
|
|
|
|
+ syntaxTrees.ToArray(),
|
|
|
|
|
+ references.ToArray(),
|
|
|
|
|
+ new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
|
|
|
|
|
+
|
|
|
|
|
+ using MemoryStream memSteam = new MemoryStream();
|
|
|
|
|
+
|
|
|
|
|
+ EmitResult emitResult = compilation.Emit(memSteam);
|
|
|
|
|
+ if (!emitResult.Success)
|
|
|
|
|
+ {
|
|
|
|
|
+ StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
|
+ foreach (Diagnostic t in emitResult.Diagnostics)
|
|
|
|
|
+ {
|
|
|
|
|
+ stringBuilder.AppendLine(t.GetMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ throw new Exception($"动态编译失败:\n{stringBuilder}");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ memSteam.Seek(0, SeekOrigin.Begin);
|
|
|
|
|
+
|
|
|
|
|
+ Assembly ass = Assembly.Load(memSteam.ToArray());
|
|
|
|
|
+ return ass;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ #region 导出class
|
|
|
|
|
+
|
|
|
|
|
+ static void ExportExcelClass(ExcelPackage p, string name, Table table)
|
|
|
{
|
|
{
|
|
|
- Dictionary<string, HeadInfo> classField = new Dictionary<string, HeadInfo>();
|
|
|
|
|
foreach (ExcelWorksheet worksheet in p.Workbook.Worksheets)
|
|
foreach (ExcelWorksheet worksheet in p.Workbook.Worksheets)
|
|
|
{
|
|
{
|
|
|
- ExportSheetClass(worksheet, classField, configType);
|
|
|
|
|
|
|
+ ExportSheetClass(worksheet, table);
|
|
|
}
|
|
}
|
|
|
- ExportClass(name, classField, configType);
|
|
|
|
|
- ExportExcelJson(p, name, classField, configType);
|
|
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- static void ExportSheetClass(ExcelWorksheet worksheet, Dictionary<string, HeadInfo> classField, ConfigType configType)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ static void ExportSheetClass(ExcelWorksheet worksheet, Table table)
|
|
|
{
|
|
{
|
|
|
- string configTypeStr = configType.ToString();
|
|
|
|
|
const int row = 2;
|
|
const int row = 2;
|
|
|
for (int col = 3; col <= worksheet.Dimension.End.Column; ++col)
|
|
for (int col = 3; col <= worksheet.Dimension.End.Column; ++col)
|
|
|
{
|
|
{
|
|
@@ -152,22 +366,22 @@ namespace ET
|
|
|
{
|
|
{
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
string fieldName = worksheet.Cells[row + 2, col].Text.Trim();
|
|
string fieldName = worksheet.Cells[row + 2, col].Text.Trim();
|
|
|
if (fieldName == "")
|
|
if (fieldName == "")
|
|
|
{
|
|
{
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (classField.ContainsKey(fieldName))
|
|
|
|
|
|
|
+ if (table.HeadInfos.ContainsKey(fieldName))
|
|
|
{
|
|
{
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
string fieldCS = worksheet.Cells[row, col].Text.Trim().ToLower();
|
|
string fieldCS = worksheet.Cells[row, col].Text.Trim().ToLower();
|
|
|
if (fieldCS.Contains("#"))
|
|
if (fieldCS.Contains("#"))
|
|
|
{
|
|
{
|
|
|
- classField[fieldName] = null;
|
|
|
|
|
|
|
+ table.HeadInfos[fieldName] = null;
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -176,16 +390,20 @@ namespace ET
|
|
|
fieldCS = "cs";
|
|
fieldCS = "cs";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!fieldCS.Contains(configTypeStr))
|
|
|
|
|
|
|
+ if (table.HeadInfos.TryGetValue(fieldName, out var oldClassField))
|
|
|
{
|
|
{
|
|
|
- classField[fieldName] = null;
|
|
|
|
|
|
|
+ if (oldClassField.FieldAttribute != fieldCS)
|
|
|
|
|
+ {
|
|
|
|
|
+ Log.Console($"field cs not same: {worksheet.Name} {fieldName} oldcs: {oldClassField.FieldAttribute} {fieldCS}");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
string fieldDesc = worksheet.Cells[row + 1, col].Text.Trim();
|
|
string fieldDesc = worksheet.Cells[row + 1, col].Text.Trim();
|
|
|
string fieldType = worksheet.Cells[row + 3, col].Text.Trim();
|
|
string fieldType = worksheet.Cells[row + 3, col].Text.Trim();
|
|
|
|
|
|
|
|
- classField[fieldName] = new HeadInfo(fieldCS, fieldDesc, fieldName, fieldType, col);
|
|
|
|
|
|
|
+ table.HeadInfos[fieldName] = new HeadInfo(fieldCS, fieldDesc, fieldName, fieldType, ++table.Index);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -196,11 +414,12 @@ namespace ET
|
|
|
{
|
|
{
|
|
|
Directory.CreateDirectory(dir);
|
|
Directory.CreateDirectory(dir);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
string exportPath = Path.Combine(dir, $"{protoName}.cs");
|
|
string exportPath = Path.Combine(dir, $"{protoName}.cs");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
using FileStream txt = new FileStream(exportPath, FileMode.Create);
|
|
using FileStream txt = new FileStream(exportPath, FileMode.Create);
|
|
|
using StreamWriter sw = new StreamWriter(txt);
|
|
using StreamWriter sw = new StreamWriter(txt);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
StringBuilder sb = new StringBuilder();
|
|
StringBuilder sb = new StringBuilder();
|
|
|
foreach ((string _, HeadInfo headInfo) in classField)
|
|
foreach ((string _, HeadInfo headInfo) in classField)
|
|
|
{
|
|
{
|
|
@@ -208,16 +427,38 @@ namespace ET
|
|
|
{
|
|
{
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
- sb.Append($"\t\t[ProtoMember({headInfo.FieldIndex - 2})]\n");
|
|
|
|
|
- sb.Append($"\t\tpublic {headInfo.FieldType} {headInfo.FieldName} {{ get; set; }}\n");
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if (headInfo.FieldType == "json")
|
|
|
|
|
+ {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!headInfo.FieldAttribute.Contains(configType.ToString()))
|
|
|
|
|
+ {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ sb.Append($"\t\t/// <summary>{headInfo.FieldDesc}</summary>\n");
|
|
|
|
|
+ sb.Append($"\t\t[ProtoMember({headInfo.FieldIndex})]\n");
|
|
|
|
|
+ string fieldType = headInfo.FieldType;
|
|
|
|
|
+ if (fieldType == "int[][]")
|
|
|
|
|
+ {
|
|
|
|
|
+ fieldType = "string[]";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ sb.Append($"\t\tpublic {fieldType} {headInfo.FieldName} {{ get; set; }}\n");
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
string content = template.Replace("(ConfigName)", protoName).Replace(("(Fields)"), sb.ToString());
|
|
string content = template.Replace("(ConfigName)", protoName).Replace(("(Fields)"), sb.ToString());
|
|
|
sw.Write(content);
|
|
sw.Write(content);
|
|
|
}
|
|
}
|
|
|
-#endregion
|
|
|
|
|
|
|
|
|
|
-#region 导出json
|
|
|
|
|
- static void ExportExcelJson(ExcelPackage p, string name, Dictionary<string, HeadInfo> classField, ConfigType configType)
|
|
|
|
|
|
|
+ #endregion
|
|
|
|
|
+
|
|
|
|
|
+ #region 导出json
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ static void ExportExcelJson(ExcelPackage p, string name, Table table, ConfigType configType, string relativeDir)
|
|
|
{
|
|
{
|
|
|
StringBuilder sb = new StringBuilder();
|
|
StringBuilder sb = new StringBuilder();
|
|
|
sb.AppendLine("{\"list\":[");
|
|
sb.AppendLine("{\"list\":[");
|
|
@@ -227,23 +468,26 @@ namespace ET
|
|
|
{
|
|
{
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
- ExportSheetJson(worksheet, name, classField, configType, sb);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ ExportSheetJson(worksheet, name, table.HeadInfos, configType, sb);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
sb.AppendLine("]}");
|
|
sb.AppendLine("]}");
|
|
|
-
|
|
|
|
|
- string dir = string.Format(jsonDir, configType.ToString());
|
|
|
|
|
|
|
+
|
|
|
|
|
+ string dir = string.Format(jsonDir, configType.ToString(), relativeDir);
|
|
|
if (!Directory.Exists(dir))
|
|
if (!Directory.Exists(dir))
|
|
|
{
|
|
{
|
|
|
Directory.CreateDirectory(dir);
|
|
Directory.CreateDirectory(dir);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
string jsonPath = Path.Combine(dir, $"{name}.txt");
|
|
string jsonPath = Path.Combine(dir, $"{name}.txt");
|
|
|
using FileStream txt = new FileStream(jsonPath, FileMode.Create);
|
|
using FileStream txt = new FileStream(jsonPath, FileMode.Create);
|
|
|
using StreamWriter sw = new StreamWriter(txt);
|
|
using StreamWriter sw = new StreamWriter(txt);
|
|
|
sw.Write(sb.ToString());
|
|
sw.Write(sb.ToString());
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- static void ExportSheetJson(ExcelWorksheet worksheet, string name, Dictionary<string, HeadInfo> classField, ConfigType configType, StringBuilder sb)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ static void ExportSheetJson(ExcelWorksheet worksheet, string name,
|
|
|
|
|
+ Dictionary<string, HeadInfo> classField, ConfigType configType, StringBuilder sb)
|
|
|
{
|
|
{
|
|
|
string configTypeStr = configType.ToString();
|
|
string configTypeStr = configType.ToString();
|
|
|
for (int row = 6; row <= worksheet.Dimension.End.Row; ++row)
|
|
for (int row = 6; row <= worksheet.Dimension.End.Row; ++row)
|
|
@@ -263,11 +507,12 @@ namespace ET
|
|
|
{
|
|
{
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (worksheet.Cells[row, 3].Text.Trim() == "")
|
|
if (worksheet.Cells[row, 3].Text.Trim() == "")
|
|
|
{
|
|
{
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
sb.Append("{");
|
|
sb.Append("{");
|
|
|
sb.Append($"\"_t\":\"{name}\"");
|
|
sb.Append($"\"_t\":\"{name}\"");
|
|
|
for (int col = 3; col <= worksheet.Dimension.End.Column; ++col)
|
|
for (int col = 3; col <= worksheet.Dimension.End.Column; ++col)
|
|
@@ -284,29 +529,39 @@ namespace ET
|
|
|
{
|
|
{
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if (headInfo.FieldType == "json")
|
|
|
|
|
+ {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
string fieldN = headInfo.FieldName;
|
|
string fieldN = headInfo.FieldName;
|
|
|
if (fieldN == "Id")
|
|
if (fieldN == "Id")
|
|
|
{
|
|
{
|
|
|
fieldN = "_id";
|
|
fieldN = "_id";
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
sb.Append($",\"{fieldN}\":{Convert(headInfo.FieldType, worksheet.Cells[row, col].Text.Trim())}");
|
|
sb.Append($",\"{fieldN}\":{Convert(headInfo.FieldType, worksheet.Cells[row, col].Text.Trim())}");
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
sb.Append("},\n");
|
|
sb.Append("},\n");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
private static string Convert(string type, string value)
|
|
private static string Convert(string type, string value)
|
|
|
{
|
|
{
|
|
|
switch (type)
|
|
switch (type)
|
|
|
{
|
|
{
|
|
|
|
|
+ case "uint[]":
|
|
|
case "int[]":
|
|
case "int[]":
|
|
|
case "int32[]":
|
|
case "int32[]":
|
|
|
case "long[]":
|
|
case "long[]":
|
|
|
return $"[{value}]";
|
|
return $"[{value}]";
|
|
|
case "string[]":
|
|
case "string[]":
|
|
|
|
|
+ case "int[][]":
|
|
|
return $"[{value}]";
|
|
return $"[{value}]";
|
|
|
case "int":
|
|
case "int":
|
|
|
|
|
+ case "uint":
|
|
|
case "int32":
|
|
case "int32":
|
|
|
case "int64":
|
|
case "int64":
|
|
|
case "long":
|
|
case "long":
|
|
@@ -316,98 +571,57 @@ namespace ET
|
|
|
{
|
|
{
|
|
|
return "0";
|
|
return "0";
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
return value;
|
|
return value;
|
|
|
case "string":
|
|
case "string":
|
|
|
return $"\"{value}\"";
|
|
return $"\"{value}\"";
|
|
|
|
|
+ case "AttrConfig":
|
|
|
|
|
+ string[] ss = value.Split(':');
|
|
|
|
|
+ return "{\"_t\":\"AttrConfig\"," + "\"Ks\":" + ss[0] + ",\"Vs\":" + ss[1] + "}";
|
|
|
default:
|
|
default:
|
|
|
throw new Exception($"不支持此类型: {type}");
|
|
throw new Exception($"不支持此类型: {type}");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-#endregion
|
|
|
|
|
|
|
|
|
|
- // 根据生成的类,动态编译把json转成protobuf
|
|
|
|
|
- private static void ExportExcelProtobuf(ConfigType configType)
|
|
|
|
|
|
|
+ #endregion
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // 根据生成的类,把json转成protobuf
|
|
|
|
|
+ private static void ExportExcelProtobuf(ConfigType configType, string protoName, string relativeDir)
|
|
|
{
|
|
{
|
|
|
- string classPath = GetClassDir(configType);
|
|
|
|
|
- List<SyntaxTree> syntaxTrees = new List<SyntaxTree>();
|
|
|
|
|
- List<string> protoNames = new List<string>();
|
|
|
|
|
- foreach (string classFile in Directory.GetFiles(classPath, "*.cs"))
|
|
|
|
|
|
|
+ string dir = GetProtoDir(configType, relativeDir);
|
|
|
|
|
+ if (!Directory.Exists(dir))
|
|
|
{
|
|
{
|
|
|
- protoNames.Add(Path.GetFileNameWithoutExtension(classFile));
|
|
|
|
|
- syntaxTrees.Add(CSharpSyntaxTree.ParseText(File.ReadAllText(classFile)));
|
|
|
|
|
|
|
+ Directory.CreateDirectory(dir);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- List<PortableExecutableReference> references = new List<PortableExecutableReference>();
|
|
|
|
|
- Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
|
|
|
|
- foreach (Assembly assembly in assemblies)
|
|
|
|
|
- {
|
|
|
|
|
- try
|
|
|
|
|
- {
|
|
|
|
|
- if (assembly.IsDynamic)
|
|
|
|
|
- {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- if (assembly.Location == "")
|
|
|
|
|
- {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- catch (Exception e)
|
|
|
|
|
- {
|
|
|
|
|
- Console.WriteLine(e);
|
|
|
|
|
- throw;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ Assembly ass = GetAssembly(configType);
|
|
|
|
|
+ Type type = ass.GetType($"ET.{protoName}Category");
|
|
|
|
|
+ Type subType = ass.GetType($"ET.{protoName}");
|
|
|
|
|
|
|
|
- PortableExecutableReference reference = MetadataReference.CreateFromFile(assembly.Location);
|
|
|
|
|
- references.Add(reference);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ Serializer.NonGeneric.PrepareSerializer(type);
|
|
|
|
|
+ Serializer.NonGeneric.PrepareSerializer(subType);
|
|
|
|
|
|
|
|
- CSharpCompilation compilation = CSharpCompilation.Create(
|
|
|
|
|
- null,
|
|
|
|
|
- syntaxTrees.ToArray(),
|
|
|
|
|
- references.ToArray(),
|
|
|
|
|
- new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
|
|
|
|
|
|
|
+ IMerge final = Activator.CreateInstance(type) as IMerge;
|
|
|
|
|
|
|
|
- using MemoryStream memSteam = new MemoryStream();
|
|
|
|
|
-
|
|
|
|
|
- EmitResult emitResult = compilation.Emit(memSteam);
|
|
|
|
|
- if (!emitResult.Success)
|
|
|
|
|
- {
|
|
|
|
|
- StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
|
- foreach (Diagnostic t in emitResult.Diagnostics)
|
|
|
|
|
- {
|
|
|
|
|
- stringBuilder.AppendLine(t.GetMessage());
|
|
|
|
|
- }
|
|
|
|
|
- throw new Exception($"动态编译失败:\n{stringBuilder}");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- memSteam.Seek(0, SeekOrigin.Begin);
|
|
|
|
|
-
|
|
|
|
|
- Assembly ass = Assembly.Load(memSteam.ToArray());
|
|
|
|
|
|
|
+ string p = Path.Combine(string.Format(jsonDir, configType, relativeDir));
|
|
|
|
|
+ string[] ss = Directory.GetFiles(p, $"{protoName}_*.txt");
|
|
|
|
|
+ List<string> jsonPaths = ss.ToList();
|
|
|
|
|
+ jsonPaths.Add(Path.Combine(string.Format(jsonDir, configType, relativeDir), $"{protoName}.txt"));
|
|
|
|
|
|
|
|
- string dir = GetProtoDir(configType);
|
|
|
|
|
- if (!Directory.Exists(dir))
|
|
|
|
|
|
|
+ jsonPaths.Sort();
|
|
|
|
|
+ jsonPaths.Reverse();
|
|
|
|
|
+ foreach (string jsonPath in jsonPaths)
|
|
|
{
|
|
{
|
|
|
- Directory.CreateDirectory(dir);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- foreach (string protoName in protoNames)
|
|
|
|
|
- {
|
|
|
|
|
- Type type = ass.GetType($"ET.{protoName}Category");
|
|
|
|
|
- Type subType = ass.GetType($"ET.{protoName}");
|
|
|
|
|
- Serializer.NonGeneric.PrepareSerializer(type);
|
|
|
|
|
- Serializer.NonGeneric.PrepareSerializer(subType);
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- string json = File.ReadAllText(Path.Combine(string.Format(jsonDir, configType), $"{protoName}.txt"));
|
|
|
|
|
|
|
+ string json = File.ReadAllText(jsonPath);
|
|
|
object deserialize = BsonSerializer.Deserialize(json, type);
|
|
object deserialize = BsonSerializer.Deserialize(json, type);
|
|
|
|
|
+ final.Merge(deserialize);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- string path = Path.Combine(dir, $"{protoName}Category.bytes");
|
|
|
|
|
|
|
+ string path = Path.Combine(dir, $"{protoName}Category.bytes");
|
|
|
|
|
|
|
|
- using FileStream file = File.Create(path);
|
|
|
|
|
- Serializer.Serialize(file, deserialize);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ using FileStream file = File.Create(path);
|
|
|
|
|
+ Serializer.Serialize(file, final);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|