From 255c48570306ce31d5375d3e8a27d3ef818d4490 Mon Sep 17 00:00:00 2001 From: Oliver Wong Date: Wed, 18 Mar 2026 15:36:15 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=86=99=E6=B3=A8=E5=86=8C=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ExcelTool/FileManager.cs | 756 +++++++------------------- ExcelTool/Parser/GenModels.cs | 987 ++++++++++------------------------ ExcelTool/TypeRegistry.cs | 278 ++++++++++ 3 files changed, 738 insertions(+), 1283 deletions(-) create mode 100644 ExcelTool/TypeRegistry.cs diff --git a/ExcelTool/FileManager.cs b/ExcelTool/FileManager.cs index 0deb56d..8fffa0e 100644 --- a/ExcelTool/FileManager.cs +++ b/ExcelTool/FileManager.cs @@ -1,572 +1,184 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -namespace ExcelTool -{ - /// - /// 文件操作类 - /// - public static class FileManager - { - public static bool CreateDir(string dirPath) - { - if (string.IsNullOrEmpty(dirPath)) - return false; - if (Directory.Exists(dirPath)) - { - Directory.Delete(dirPath, true); - } - Directory.CreateDirectory(dirPath); - return true; - } - - /// - /// 将数据写入二进制文件 - /// - /// - /// 继承自IBinarySerialize的数据 - public static bool WriteBinaryDataToFile(string filePath, IBinarySerializable data) - { - if (string.IsNullOrEmpty(filePath)) - return false; - if (File.Exists(filePath)) - { - File.Delete(filePath); - } - using (var fileStream = new FileStream(filePath, FileMode.Create)) - { - using (var bw = new BinaryWriter(fileStream)) - { - data.Serialize(bw); - bw.Flush(); - bw.Close(); - } - fileStream.Close(); - } - return true; - } - - /// - /// 将数据写入二进制文件 - /// - /// - /// 类型(小写)和value的字符串键值对 - /// - public static bool WriteBinaryDatasToFile(string filePath, List> datas) - { - try - { - if (string.IsNullOrEmpty(filePath)) - return false; - if (File.Exists(filePath)) - { - File.Delete(filePath); - } - using (var fileStream = new FileStream(filePath, FileMode.Create)) - { - using (var bw = new BinaryWriter(fileStream)) - { - foreach (var data in datas) - { - if (data.Item1.Equals("int")) - { - if (string.IsNullOrEmpty(data.Item2)) - { - bw.Write(Convert.ToInt32(0)); - } - else - { - bw.Write(Convert.ToInt32(data.Item2)); - } - } - else if (data.Item1.Equals("uint")) - { - if (string.IsNullOrEmpty(data.Item2)) - { - bw.Write(Convert.ToUInt32(0)); - } - else - { - bw.Write(Convert.ToUInt32(data.Item2)); - } - }else if (data.Item1.Equals("short")) - { - bw.Write(string.IsNullOrEmpty(data.Item2) ? Convert.ToInt16(0) : Convert.ToInt16(data.Item2)); - } - else if (data.Item1.Equals("ushort")) - { - bw.Write(string.IsNullOrEmpty(data.Item2) ? Convert.ToUInt16(0) : Convert.ToUInt16(data.Item2)); - } - else if (data.Item1.Equals("sbyte")) - { - if (string.IsNullOrEmpty(data.Item2)) - { - bw.Write(Convert.ToSByte(0)); - } - else - { - bw.Write(Convert.ToSByte(data.Item2)); - } - } - else if (data.Item1.Equals("byte")) - { - if (string.IsNullOrEmpty(data.Item2)) - { - bw.Write(Convert.ToByte(0)); - } - else - { - bw.Write(Convert.ToByte(data.Item2)); - } - } - else if (data.Item1.Equals("bool")) - { - if (string.IsNullOrEmpty(data.Item2)) - { - bw.Write(false); - } - else - { - string v = data.Item2.Trim().ToLower(); - bw.Write(v is "true" or "1"); - } - } - else if (data.Item1.Equals("float")) - { - if (string.IsNullOrEmpty(data.Item2)) - { - bw.Write(Convert.ToSingle(0)); - } - else - { - bw.Write(Convert.ToSingle(data.Item2)); - } - } - else if (data.Item1.Equals("double")) - { - if (string.IsNullOrEmpty(data.Item2)) - { - bw.Write(Convert.ToDouble(0)); - } - else - { - bw.Write(Convert.ToDouble(data.Item2)); - } - } - else if (data.Item1.Equals("string")) - { - bw.Write(string.IsNullOrEmpty(data.Item2) ? "" : data.Item2.ToString()); - } - else if (data.Item1.Equals("long")) - { - if (string.IsNullOrEmpty(data.Item2)) - { - bw.Write(Convert.ToInt64(0)); - } - else - { - bw.Write(Convert.ToInt64(data.Item2)); - } - } - else if (data.Item1.Equals("vector")) - { - //[1.2,3.4,5.6] - var str = data.Item2.ToString(); - if (string.IsNullOrEmpty(str)) - { - bw.Write(Convert.ToInt32(0)); - } - else - { - str = str.Replace("]", "").Replace("[", ""); - var numStrs = str.Split(','); - int vectorCount = 3; - bw.Write(vectorCount); - for (int i = 0; i < vectorCount; i++) - { - float v = Convert.ToSingle(numStrs[i]); - bw.Write(v); - } - } - } - else if (data.Item1.Equals("vectorlist")) //List类型 - { - //[[1.2,3.4,5.6],[2.2,3.4,5.6],[3.2,3.4,5.6]] - string str = data.Item2.ToString(); - if (string.IsNullOrEmpty(str)) - { - bw.Write(Convert.ToInt32(0)); - } - else - { - str = str.Replace("]", "").Replace("[", ""); - var numStrs = str.Split(','); - bw.Write(Convert.ToInt32(numStrs.Length / 3)); - for (int i = 0; i < numStrs.Length; i++) - { - if (i % 3 == 0) - bw.Write(Convert.ToInt32(3)); - bw.Write(Convert.ToSingle(numStrs[i])); - } - } - } - else if (data.Item1.Equals("intlist")) - { - string str = data.Item2.ToString(); - if (string.IsNullOrEmpty(str)) - { - bw.Write(Convert.ToInt32(0)); - } - else - { - var numStrs = str.Split(','); - bw.Write(numStrs.Length); - for (int i = 0; i < numStrs.Length; i++) - { - bw.Write(Convert.ToInt32(numStrs[i])); - } - } - } - else if (data.Item1.Equals("floatlist")) - { - string str = data.Item2.ToString(); - if (string.IsNullOrEmpty(str)) - { - bw.Write(Convert.ToInt32(0)); - } - else - { - var numStrs = str.Split(','); - bw.Write(numStrs.Length); - for (int i = 0; i < numStrs.Length; i++) - { - bw.Write(Convert.ToSingle(numStrs[i])); - } - } - } - else if (data.Item1.Equals("boollist")) - { - string str = data.Item2.ToString(); - if (string.IsNullOrEmpty(str)) - { - bw.Write(Convert.ToInt32(0)); - } - else - { - var numStrs = str.Split(','); - bw.Write(numStrs.Length); - for (int i = 0; i < numStrs.Length; i++) - { - bw.Write(Convert.ToBoolean(numStrs[i])); - } - } - } - else if (data.Item1.Equals("stringlist")) - { - string str = data.Item2.ToString(); - if (string.IsNullOrEmpty(str)) - { - bw.Write(Convert.ToInt32(0)); - } - else - { - var numStrs = str.Split(','); - bw.Write(numStrs.Length); - for (int i = 0; i < numStrs.Length; i++) - { - bw.Write(numStrs[i]); - } - } - } - else if (data.Item1.Equals("longlist")) - { - string str = data.Item2.ToString(); - if (string.IsNullOrEmpty(str)) - { - bw.Write(Convert.ToInt32(0)); - } - else - { - var numStrs = str.Split(','); - bw.Write(numStrs.Length); - for (int i = 0; i < numStrs.Length; i++) - { - bw.Write(Convert.ToInt64(numStrs[i])); - } - } - } - else if (data.Item1.Contains("list<")) //泛型数组类型 - { - string str = data.Item2.ToString(); - if (string.IsNullOrEmpty(str)) - { - bw.Write(Convert.ToInt32(0)); - } - else - { - var numStrs = str.Split(','); - bw.Write(numStrs.Length); - var tempS = data.Item1.Substring(5); - var listType = tempS.Substring(0, tempS.Length - 1); - if (listType.Equals("int")) - { - for (int i = 0; i < numStrs.Length; i++) - { - bw.Write(Convert.ToInt32(numStrs[i])); - } - } - else if (listType.Equals("uint")) - { - for (int i = 0; i < numStrs.Length; i++) - { - bw.Write(Convert.ToUInt32(numStrs[i])); - } - } - else if (listType.Equals("short")) - { - foreach (string t in numStrs) - { - bw.Write(Convert.ToInt16(t)); - } - } - else if (listType.Equals("ushort")) - { - foreach (string t in numStrs) - { - bw.Write(Convert.ToUInt16(t)); - } - } - else if (listType.Equals("sbyte")) - { - for (int i = 0; i < numStrs.Length; i++) - { - bw.Write(Convert.ToSByte(numStrs[i])); - } - } - else if (listType.Equals("byte")) - { - for (int i = 0; i < numStrs.Length; i++) - { - bw.Write(Convert.ToByte(numStrs[i])); - } - } - else if (listType.Equals("bool")) - { - for (int i = 0; i < numStrs.Length; i++) - { - bw.Write(Convert.ToBoolean(numStrs[i])); - } - } - else if (listType.Equals("float")) - { - for (int i = 0; i < numStrs.Length; i++) - { - bw.Write(Convert.ToSingle(numStrs[i])); - } - } - else if (listType.Equals("long")) - { - for (int i = 0; i < numStrs.Length; i++) - { - bw.Write(Convert.ToInt64(numStrs[i])); - } - } - else if (listType.Equals("string")) - { - for (int i = 0; i < numStrs.Length; i++) - { - bw.Write(Convert.ToString(numStrs[i])); - } - } - else - { - ConsoleHelper.WriteErrorLine("数组类型List,T不是支持的Int,Float,String这三种类型,需要扩展类型"); - } - } - } - else - { - ConsoleHelper.WriteErrorLine($"写入二进制文件,数据类型{data.Item1}没有适配"); - return false; - } - } - bw.Flush(); - bw.Close(); - } - fileStream.Close(); - } - return true; - } - catch (Exception ex) - { - ConsoleHelper.WriteErrorLine(ex.ToString()); - return false; - } - } - - /// - /// 从内存流中读取二进制 - /// - /// - /// - /// - public static bool ReadBinaryDataFromBytes(byte[] bytes, ref IBinarySerializable data) - { - if (bytes == null) - return false; - using (var memoryStream = new MemoryStream(bytes)) - { - using (var br = new BinaryReader(memoryStream)) - { - data.DeSerialize(br); - br.Close(); - } - memoryStream.Close(); - } - return true; - } - - /// - /// 读取二进制文件 - /// - /// - /// - /// - public static bool ReadBinaryDataFromFile(string filePath, ref IBinarySerializable data) - { - if (string.IsNullOrEmpty(filePath)) - { - return false; - } - using (var fileStream = new FileStream(filePath, FileMode.Open)) - { - using (var br = new BinaryReader(fileStream)) - { - data.DeSerialize(br); - br.Close(); - } - fileStream.Close(); - } - return true; - } - - public static bool WriteBytesToFile(string filePath, byte[] data) - { - if (string.IsNullOrEmpty(filePath)) - return false; - if (File.Exists(filePath)) - { - File.Delete(filePath); - } - var file = new FileInfo(filePath); - using (Stream sw = file.Create()) - { - sw.Write(data, 0, data.Length); - sw.Flush(); - sw.Close(); - } - return true; - } - - /// - /// 将字符串写入文件 - /// - /// - /// - /// - public static bool WriteToFile(string filePath, string context) - { - return WriteToFile(filePath, context, Encoding.Default); - } - - public static bool WriteToFile(string filePath, string context, Encoding encoding) - { - if (string.IsNullOrEmpty(filePath)) - return false; - if (File.Exists(filePath)) - { - File.Delete(filePath); - } - using (FileStream fs = new FileStream(filePath, FileMode.Create)) - { - var data = encoding.GetBytes(context); - fs.Write(data, 0, data.Length); - fs.Flush(); - fs.Close(); - } - return true; - } - - /// - /// 按行读取 - /// - /// - /// - public static string ReadAllByLine(string path) - { - if (string.IsNullOrEmpty(path) || !File.Exists(path)) - { - return string.Empty; - } - StringBuilder sb = new StringBuilder(); - using (StreamReader sr = new StreamReader(path, Encoding.Default)) - { - string line; - while ((line = sr.ReadLine()) != null) - { - sb.AppendLine(line); - } - sr.Close(); - } - return sb.ToString(); - } - - public static byte[] ReadAllBytes(string path) - { - if (string.IsNullOrEmpty(path) || !File.Exists(path)) - { - return null; - } - return File.ReadAllBytes(path); - } - - /// - /// 修改文件内容 - /// - /// - /// - /// - public static void ReplaceContent(string path, string normalStr, string newStr) - { - if (string.IsNullOrEmpty(path) || !File.Exists(path)) - { - return; - } - string strContent = File.ReadAllText(path); - strContent = strContent.Replace(normalStr, newStr); - File.WriteAllText(path, strContent); - } - - /// - /// 批量修改文件内容 - /// - /// - /// - /// - public static void ReplaceContent(string path, string newStr, params string[] normalStrs) - { - if (string.IsNullOrEmpty(path) || !File.Exists(path)) - { - return; - } - string strContent = File.ReadAllText(path); - for (int i = 0; i < normalStrs.Length; i++) - { - strContent = strContent.Replace(normalStrs[i], newStr); - } - File.WriteAllText(path, strContent); - } - } -} +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace ExcelTool +{ + /// + /// 文件操作类 + /// + public static class FileManager + { + public static bool CreateDir(string dirPath) + { + if (string.IsNullOrEmpty(dirPath)) + return false; + if (Directory.Exists(dirPath)) + Directory.Delete(dirPath, true); + Directory.CreateDirectory(dirPath); + return true; + } + + /// 将数据写入二进制文件(IBinarySerializable 版本) + public static bool WriteBinaryDataToFile(string filePath, IBinarySerializable data) + { + if (string.IsNullOrEmpty(filePath)) return false; + if (File.Exists(filePath)) File.Delete(filePath); + + using var fileStream = new FileStream(filePath, FileMode.Create); + using var bw = new BinaryWriter(fileStream); + data.Serialize(bw); + bw.Flush(); + return true; + } + + /// + /// 将数据写入二进制文件。 + /// 类型名(Item1)须与 中注册的 key 一致(不区分大小写)。 + /// 额外支持 list<T> 泛型语法。 + /// + public static bool WriteBinaryDatasToFile(string filePath, List> datas) + { + try + { + if (string.IsNullOrEmpty(filePath)) return false; + if (File.Exists(filePath)) File.Delete(filePath); + + using var fileStream = new FileStream(filePath, FileMode.Create); + using var bw = new BinaryWriter(fileStream); + + foreach (var (rawType, value) in datas) + { + var type = rawType.ToLower(); + + // ── 优先从注册表查找 ────────────────────────────── + var desc = TypeRegistry.Get(type); + if (desc != null) + { + desc.WriteBinary(bw, value); + continue; + } + + // ── list 泛型语法(如 list)───────────── + if (type.StartsWith("list<") && type.EndsWith(">")) + { + WriteGenericList(bw, type, value); + continue; + } + + ConsoleHelper.WriteErrorLine($"写入二进制文件:数据类型 \"{rawType}\" 未注册,请在 TypeRegistry 中添加"); + return false; + } + + bw.Flush(); + return true; + } + catch (Exception ex) + { + ConsoleHelper.WriteErrorLine(ex.ToString()); + return false; + } + } + + // ────────────────────────────────────────────────────────────── + // list 泛型列表写入(T 必须是已在 TypeRegistry 注册的基础类型) + // ────────────────────────────────────────────────────────────── + private static void WriteGenericList(BinaryWriter bw, string fullType, string value) + { + // fullType 形如 "list" + var innerType = fullType[5..^1]; // 去掉 "list<" 和 ">" + var elemDesc = TypeRegistry.Get(innerType); + if (elemDesc == null) + { + ConsoleHelper.WriteErrorLine($"list 的元素类型 \"{innerType}\" 未注册,请在 TypeRegistry 中添加"); + return; + } + + if (string.IsNullOrEmpty(value)) + { + bw.Write(0); + return; + } + + var parts = value.Split(','); + bw.Write(parts.Length); + foreach (var p in parts) + elemDesc.WriteBinary(bw, p); + } + + // ────────────────────────────────────────────────────────────── + // 其余文件工具方法(不涉及类型系统,保持不变) + // ────────────────────────────────────────────────────────────── + + public static bool ReadBinaryDataFromBytes(byte[] bytes, ref IBinarySerializable data) + { + if (bytes == null) return false; + using var ms = new MemoryStream(bytes); + using var br = new BinaryReader(ms); + data.DeSerialize(br); + return true; + } + + public static bool ReadBinaryDataFromFile(string filePath, ref IBinarySerializable data) + { + if (string.IsNullOrEmpty(filePath)) return false; + using var fs = new FileStream(filePath, FileMode.Open); + using var br = new BinaryReader(fs); + data.DeSerialize(br); + return true; + } + + public static bool WriteBytesToFile(string filePath, byte[] data) + { + if (string.IsNullOrEmpty(filePath)) return false; + if (File.Exists(filePath)) File.Delete(filePath); + using Stream sw = new FileInfo(filePath).Create(); + sw.Write(data, 0, data.Length); + sw.Flush(); + return true; + } + + public static bool WriteToFile(string filePath, string context) => + WriteToFile(filePath, context, Encoding.Default); + + public static bool WriteToFile(string filePath, string context, Encoding encoding) + { + if (string.IsNullOrEmpty(filePath)) return false; + if (File.Exists(filePath)) File.Delete(filePath); + using var fs = new FileStream(filePath, FileMode.Create); + var data = encoding.GetBytes(context); + fs.Write(data, 0, data.Length); + fs.Flush(); + return true; + } + + public static string ReadAllByLine(string path) + { + if (string.IsNullOrEmpty(path) || !File.Exists(path)) return string.Empty; + var sb = new StringBuilder(); + using var sr = new StreamReader(path, Encoding.Default); + string line; + while ((line = sr.ReadLine()) != null) + sb.AppendLine(line); + return sb.ToString(); + } + + public static byte[] ReadAllBytes(string path) => + string.IsNullOrEmpty(path) || !File.Exists(path) ? null : File.ReadAllBytes(path); + + public static void ReplaceContent(string path, string normalStr, string newStr) + { + if (string.IsNullOrEmpty(path) || !File.Exists(path)) return; + File.WriteAllText(path, File.ReadAllText(path).Replace(normalStr, newStr)); + } + + public static void ReplaceContent(string path, string newStr, params string[] normalStrs) + { + if (string.IsNullOrEmpty(path) || !File.Exists(path)) return; + string content = File.ReadAllText(path); + foreach (var s in normalStrs) content = content.Replace(s, newStr); + File.WriteAllText(path, content); + } + } +} diff --git a/ExcelTool/Parser/GenModels.cs b/ExcelTool/Parser/GenModels.cs index 8a02a7a..c4677e1 100644 --- a/ExcelTool/Parser/GenModels.cs +++ b/ExcelTool/Parser/GenModels.cs @@ -1,711 +1,276 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -namespace ExcelTool.Parser -{ - public static class GenModels - { - /// - /// 生成对应的C#Model类 - /// - /// 传入的文件名 - /// 输出cs文件的路径 - /// cs文件要使用的命名空间 - /// - public static bool GenCSharpModel(string fileName, string outputDir, string nameSpace = "") - { - if (string.IsNullOrEmpty(fileName)) - { - "GenCSharpModel 参数传递有误".WriteErrorLine(); - return false; - } - try - { - // 枚举类型映射 - Dictionary enumMap = new() - { - { "killmode", "KillMode" }, - { "mixingtype", "MixingType" }, - { "containertype", "ContainerType" }, - { "blendcrossfadetype", "BlendCrossFadeType" } - }; - FileInfo fileInfo = new(fileName); - if (string.IsNullOrEmpty(outputDir)) - { - outputDir = fileInfo.DirectoryName; - } - for (int sheetNum = 0; ; sheetNum++) - { - var headers = ExcelHelper.ExcelHeaders(fileName, out string sheetName, out int sheetCount, sheetNum); - if (headers == null || headers.Count == 0 || sheetName.StartsWith("#") || sheetNum > sheetCount) - break; - StringBuilder sb = new(); - sb.Append($"/*\n * auto generated by tools(注意:千万不要手动修改本文件)\n * {sheetName}\n */\n"); - sb.Append("using System;\nusing System.IO;\nusing System.Collections.Generic;\nusing System.Text;\nusing WKMobile.Generated;\n\n"); - - - if (!string.IsNullOrEmpty(nameSpace)) - { - sb.Append($"namespace {nameSpace}\n{{\n"); - } - - sb.Append("[Serializable]\n"); - sb.Append($"public partial class {sheetName} : IBinarySerializable\n"); - sb.Append("{\n"); - for (int i = 0; i < headers.Count; i++) - { - sb.Append($"\t/// \n"); - var descLines = headers[i].FieldDesc?.Replace("\r", "").Split('\n'); - if (descLines != null) - { - foreach (var line in descLines) - { - sb.Append($"\t/// {line}\n"); - } - } - sb.Append($"\t/// \n"); - var type = headers[i].FieldType.ToLower(); - var origType = headers[i].FieldType; - var fieldName = headers[i].FieldName; - if (enumMap.ContainsKey(type)) - { - sb.Append($"\tpublic {enumMap[type]} {fieldName} {{ get; set; }}\n\n"); - } - else if (type.Equals("vector")) - { - sb.Append(string.Format("\tpublic List {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else if (type.Equals("vectorlist")) - { - sb.Append(string.Format("\tpublic List> {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else if (type.Equals("intlist")) - { - sb.Append(string.Format("\tpublic List {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else if (type.Equals("boollist")) - { - sb.Append(string.Format("\tpublic List {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else if (type.Equals("floatlist")) - { - sb.Append(string.Format("\tpublic List {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else if (type.Equals("stringlist")) - { - sb.Append(string.Format("\tpublic List {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else if (type.Equals("longlist")) - { - sb.Append(string.Format("\tpublic List {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else if (type.Equals("uintlist")) - { - sb.Append(string.Format("\tpublic List {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else if (type.Equals("ushortlist")) - { - sb.Append(string.Format("\tpublic List {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else if (type.Equals("sbytelist")) - { - sb.Append(string.Format("\tpublic List {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else if (type.Equals("bytelist")) - { - sb.Append(string.Format("\tpublic List {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else if (type.Contains("list<")) - { - var tempS = type.Substring(5); - var newType = tempS.Substring(0, tempS.Length - 1); - if (newType.Equals("int")) - { - sb.Append(string.Format("\tpublic List {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else if (newType.Equals("bool")) - { - sb.Append(string.Format("\tpublic List {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else if (newType.Equals("float")) - { - sb.Append(string.Format("\tpublic List {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else if (newType.Equals("long")) - { - sb.Append(string.Format("\tpublic List {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else if (newType.Equals("string")) - { - sb.Append(string.Format("\tpublic List {0}", headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - else - { - ConsoleHelper.WriteErrorLine("数组类型List,T类型不支持"); - } - } - else - { - sb.Append(string.Format("\tpublic {0} {1}", headers[i].FieldType.ToLower(), headers[i].FieldName)); - sb.Append(" { get; set; }\n\n"); - } - } - sb.Append("\n\tpublic void DeSerialize(BinaryReader reader)\n"); - sb.Append("\t{\n"); - foreach (var header in headers) - { - var type = header.FieldType.ToLower(); - var name = header.FieldName; - if (enumMap.ContainsKey(type)) - { - sb.Append($"\t\t{name} = ({enumMap[type]})reader.ReadByte();\n"); - } - else if (type.Equals("int")) - { - sb.Append($"\t\t{name} = reader.ReadInt32();\n"); - } - else if (type.Equals("uint")) - { - sb.Append($"\t\t{name} = reader.ReadUInt32();\n"); - } - else if (type.Equals("short")) - { - sb.Append($"\t\t{name} = reader.ReadInt16();\n"); - } - else if (type.Equals("ushort")) - { - sb.Append($"\t\t{name} = reader.ReadUInt16();\n"); - } - else if (type.Equals("sbyte")) - { - sb.Append($"\t\t{name} = reader.ReadSByte();\n"); - } - else if (type.Equals("byte")) - { - sb.Append($"\t\t{name} = reader.ReadByte();\n"); - } - else if (type.Equals("bool")) - { - sb.Append($"\t\t{name} = reader.ReadBoolean();\n"); - } - else if (type.Equals("float")) - { - sb.Append($"\t\t{name} = reader.ReadSingle();\n"); - } - else if (type.Equals("string")) - { - sb.Append($"\t\t{name} = reader.ReadString();\n"); - } - else if (type.Equals("vector")) - { - sb.Append($"\t\tvar {name.ToCamelCase()}Count = reader.ReadInt32();\n"); - sb.Append($"\t\tif ({name.ToCamelCase()}Count > 0)\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = new List();\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name.ToCamelCase()}Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\t{name}.Add(reader.ReadSingle());\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = null;\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("vectorlist")) - { - sb.Append($"\t\tvar {name.ToCamelCase()}Count = reader.ReadInt32();\n"); - sb.Append($"\t\tif ({name.ToCamelCase()}Count > 0)\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = new List>();\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name.ToCamelCase()}Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\tvar tempList = new List();\n"); - sb.Append($"\t\t\t\tvar tempListCount = reader.ReadInt32();\n"); - sb.Append($"\t\t\t\tfor (int j = 0; j < tempListCount; j++)\n"); - sb.Append("\t\t\t\t{\n"); - sb.Append($"\t\t\t\t\ttempList.Add(reader.ReadSingle());\n"); - sb.Append("\t\t\t\t}\n"); - sb.Append($"\t\t\t\t{name}.Add(tempList);\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = null;\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("intlist")) - { - sb.Append($"\t\tvar {name.ToCamelCase()}Count = reader.ReadInt32();\n"); - sb.Append($"\t\tif ({name.ToCamelCase()}Count > 0)\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = new List();\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name.ToCamelCase()}Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\t{name}.Add(reader.ReadInt32());\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = null;\n"); - sb.Append("\t\t}\n"); - }else if (type.Equals("uintlist")) - { - sb.Append($"\t\tvar {name.ToCamelCase()}Count = reader.ReadInt32();\n"); - sb.Append($"\t\tif ({name.ToCamelCase()}Count > 0)\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = new List();\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name.ToCamelCase()}Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\t{name}.Add(reader.ReadUInt32());\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = null;\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("boollist")) - { - sb.Append($"\t\tvar {name.ToCamelCase()}Count = reader.ReadInt32();\n"); - sb.Append($"\t\tif ({name.ToCamelCase()}Count > 0)\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = new List();\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name.ToCamelCase()}Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\t{name}.Add(reader.ReadBoolean());\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = null;\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("floatlist")) - { - sb.Append($"\t\tvar {name.ToCamelCase()}Count = reader.ReadInt32();\n"); - sb.Append($"\t\tif ({name.ToCamelCase()}Count > 0)\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = new List();\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name.ToCamelCase()}Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\t{name}.Add(reader.ReadSingle());\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = null;\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("stringlist")) - { - sb.Append($"\t\tvar {name.ToCamelCase()}Count = reader.ReadInt32();\n"); - sb.Append($"\t\tif ({name.ToCamelCase()}Count > 0)\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = new List();\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name.ToCamelCase()}Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\t{name}.Add(reader.ReadString());\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = null;\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("longlist")) - { - sb.Append($"\t\tvar {name.ToCamelCase()}Count = reader.ReadInt32();\n"); - sb.Append($"\t\tif ({name.ToCamelCase()}Count > 0)\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = new List();\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name.ToCamelCase()}Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\t{name}.Add(reader.ReadInt64());\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = null;\n"); - sb.Append("\t\t}\n"); - } - else if (type.Contains("list<")) - { - var tempS = type.Substring(5); - var listTType = tempS.Substring(0, tempS.Length - 1); - sb.Append($"\t\tvar {name.ToCamelCase()}Count = reader.ReadInt32();\n"); - sb.Append($"\t\tif ({name.ToCamelCase()}Count > 0)\n"); - sb.Append("\t\t{\n"); - if (listTType.Equals("int")) - { - sb.Append($"\t\t\t{name} = new List();\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name.ToCamelCase()}Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\t{name}.Add(reader.ReadInt32());\n"); - } - else if (listTType.Equals("bool")) - { - sb.Append($"\t\t\t{name} = new List();\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name.ToCamelCase()}Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\t{name}.Add(reader.ReadBoolean());\n"); - } - else if (listTType.Equals("float")) - { - sb.Append($"\t\t\t{name} = new List();\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name.ToCamelCase()}Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\t{name}.Add(reader.ReadSingle());\n"); - } - else if (listTType.Equals("long")) - { - sb.Append($"\t\t\t{name} = new List();\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name.ToCamelCase()}Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\t{name}.Add(reader.ReadInt64());\n"); - } - else if (listTType.Equals("string")) - { - sb.Append($"\t\t\t{name} = new List();\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name.ToCamelCase()}Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\t{name}.Add(reader.ReadString());\n"); - } - else - { - "数组泛型T不是指定类型".WriteErrorLine(); - } - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{name} = null;\n"); - sb.Append("\t\t}\n"); - } - else - { - $"类型:{type}没有解析 {fileName}处理异常".WriteErrorLine(); - return false; - } - } - sb.Append("\t}\n\n"); - sb.Append("\tpublic void Serialize(BinaryWriter writer)\n"); - sb.Append("\t{\n"); - foreach (var header in headers) - { - var type = header.FieldType.ToLower(); - var name = header.FieldName; - if (enumMap.ContainsKey(type)) - { - sb.Append($"\t\twriter.Write((byte){name});\n"); - } - else if (type.Equals("int") || - type.Equals("bool") || - type.Equals("float") || - type.Equals("string") || - type.Equals("uint") || - type.Equals("ushort") || - type.Equals("short") || - type.Equals("sbyte") || - type.Equals("byte")) - { - sb.Append($"\t\twriter.Write({name});\n"); - } - else if (type.Equals("vector")) - { - sb.Append($"\t\tif ({name} == null || {name}.Count == 0)\n"); - sb.Append("\t\t{\n"); - sb.Append("\t\t\twriter.Write(0);\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\twriter.Write({name}.Count);\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name}.Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\twriter.Write({name}[i]);\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("vectorlist")) - { - sb.Append($"\t\tif ({name} == null || {name}.Count == 0)\n"); - sb.Append("\t\t{\n"); - sb.Append("\t\t\twriter.Write(0);\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\twriter.Write({name}.Count);\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name}.Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\twriter.Write({name}[i].Count);\n"); - sb.Append($"\t\t\t\tfor (int j = 0; j < {name}[i].Count; j++)\n"); - sb.Append("\t\t\t\t{\n"); - sb.Append($"\t\t\t\t\twriter.Write({name}[i][j]);\n"); - sb.Append("\t\t\t\t}\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("intlist")) - { - sb.Append($"\t\tif ({name} == null || {name}.Count == 0)\n"); - sb.Append("\t\t{\n"); - sb.Append("\t\t\twriter.Write(0);\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\twriter.Write({name}.Count);\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name}.Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\twriter.Write({name}[i]);\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("boollist")) - { - sb.Append($"\t\tif ({name} == null || {name}.Count == 0)\n"); - sb.Append("\t\t{\n"); - sb.Append("\t\t\twriter.Write(0);\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\twriter.Write({name}.Count);\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name}.Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\twriter.Write({name}[i]);\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("floatlist")) - { - sb.Append($"\t\tif ({name} == null || {name}.Count == 0)\n"); - sb.Append("\t\t{\n"); - sb.Append("\t\t\twriter.Write(0);\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\twriter.Write({name}.Count);\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name}.Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\twriter.Write({name}[i]);\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("longlist")) - { - sb.Append($"\t\tif ({name} == null || {name}.Count == 0)\n"); - sb.Append("\t\t{\n"); - sb.Append("\t\t\twriter.Write(0);\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\twriter.Write({name}.Count);\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name}.Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\twriter.Write({name}[i]);\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("stringlist")) - { - sb.Append($"\t\tif ({name} == null || {name}.Count == 0)\n"); - sb.Append("\t\t{\n"); - sb.Append("\t\t\twriter.Write(0);\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\twriter.Write({name}.Count);\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name}.Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\twriter.Write({name}[i]);\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("uintlist")) - { - sb.Append($"\t\tif ({name} == null || {name}.Count == 0)\n"); - sb.Append("\t\t{\n"); - sb.Append("\t\t\twriter.Write(0);\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\twriter.Write({name}.Count);\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name}.Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\twriter.Write({name}[i]);\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("ushortlist")) - { - sb.Append($"\t\tif ({name} == null || {name}.Count == 0)\n"); - sb.Append("\t\t{\n"); - sb.Append("\t\t\twriter.Write(0);\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\twriter.Write({name}.Count);\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name}.Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\twriter.Write({name}[i]);\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("sbytelist")) - { - sb.Append($"\t\tif ({name} == null || {name}.Count == 0)\n"); - sb.Append("\t\t{\n"); - sb.Append("\t\t\twriter.Write(0);\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\twriter.Write({name}.Count);\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name}.Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\twriter.Write({name}[i]);\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - } - else if (type.Equals("bytelist")) - { - sb.Append($"\t\tif ({name} == null || {name}.Count == 0)\n"); - sb.Append("\t\t{\n"); - sb.Append("\t\t\twriter.Write(0);\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\twriter.Write({name}.Count);\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name}.Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\twriter.Write({name}[i]);\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - } - - else if (type.Contains("list<")) - { - var tempS = type.Substring(5); - var listTType = tempS.Substring(0, tempS.Length - 1); - sb.Append($"\t\tif ({name} == null || {name}.Count == 0)\n"); - sb.Append("\t\t{\n"); - sb.Append("\t\t\twriter.Write(0);\n"); - sb.Append("\t\t}\n"); - sb.Append("\t\telse\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\twriter.Write({name}.Count);\n"); - sb.Append($"\t\t\tfor (int i = 0; i < {name}.Count; i++)\n"); - sb.Append("\t\t\t{\n"); - sb.Append($"\t\t\t\twriter.Write({name}[i]);\n"); - sb.Append("\t\t\t}\n"); - sb.Append("\t\t}\n"); - if (listTType.Equals("int")) - { - - } - else if (listTType.Equals("bool")) - { - - } - else if (listTType.Equals("float")) - { - - } - else if (listTType.Equals("long")) - { - - } - else if (listTType.Equals("string")) - { - - } - else - { - ConsoleHelper.WriteErrorLine("数组泛型T不是指定类型"); - } - } - else - { - ConsoleHelper.WriteErrorLine($"类型:{type}没有解析 {fileName}处理异常"); - return false; - } - } - sb.Append("\t}\n"); - sb.Append("}\n"); - - sb.Append("\n"); - sb.Append("[Serializable]\n"); - sb.Append($"public partial class {sheetName}Config : IBinarySerializable\n"); - sb.Append("{\n"); - // sb.Append($"\tpublic List<{excelName}> {excelName}Infos = new List<{excelName}>();\n"); - sb.Append($"\tDictionary m_{sheetName.ToCamelCase()}Infos = new();\n"); - sb.Append($"\tList<{sheetName}> m_{sheetName.ToCamelCase()}InfoList;\n"); - sb.Append("\n"); - sb.Append($"\tpublic List<{sheetName}> {sheetName}List()\n"); - sb.Append("\t{\n"); - sb.Append($"\t\tthis.m_{sheetName.ToCamelCase()}InfoList ??= new List<{sheetName}>(m_{sheetName.ToCamelCase()}Infos.Values);\n"); - sb.Append($"\t\treturn this.m_{sheetName.ToCamelCase()}InfoList;\n"); - sb.Append("\t}\n"); - sb.Append("\n"); - sb.Append($"\tpublic void DeSerialize(BinaryReader reader)\n"); - sb.Append("\t{\n"); - sb.Append($"\t\tint count = reader.ReadInt32();\n"); - sb.Append($"\t\tfor (int i = 0;i < count; i++)\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{sheetName} tempData = new();\n"); - sb.Append($"\t\t\ttempData.DeSerialize(reader);\n"); - // sb.Append($"\t\t\t{excelName}Infos.Add(tempData);\n"); - sb.Append($"\t\t\tthis.m_{sheetName.ToCamelCase()}Infos.Add(tempData.Id, tempData);\n"); - sb.Append("\t\t}\n"); - sb.Append("\t}\n"); - sb.Append("\n"); - sb.Append("\tpublic void Serialize(BinaryWriter writer)\n"); - sb.Append("\t{\n"); - sb.Append($"\t\twriter.Write(this.m_{sheetName.ToCamelCase()}Infos.Count);\n"); - sb.Append($"\t\tforeach ({sheetName} {sheetName.ToCamelCase()} in this.m_{sheetName.ToCamelCase()}Infos.Values)\n"); - sb.Append("\t\t{\n"); - sb.Append($"\t\t\t{sheetName.ToCamelCase()}.Serialize(writer);\n"); - sb.Append("\t\t}\n"); - sb.Append("\t}\n\n"); - sb.Append($"\tpublic {sheetName} QueryById(uint id)\n"); - sb.Append("\t{\n"); - // sb.Append($"\t\tvar datas = from d in {excelName}Infos\n"); - // sb.Append($"\t\t\t\t\twhere d.Id == id\n"); - // sb.Append($"\t\t\t\t\tselect d;\n"); - // sb.Append("\t\treturn datas.First();\n"); - sb.Append($"\t\treturn this.m_{sheetName.ToCamelCase()}Infos.GetValueOrDefault(id);\n"); - sb.Append("\t}\n"); - sb.Append("}\n"); - - if (!string.IsNullOrEmpty(nameSpace)) - { - sb.Append("}\n"); // namespace 结束 - } - FileManager.WriteToFile(Path.Combine(outputDir, $"{sheetName}.cs"), sb.ToString()); - } - return true; - } - catch (Exception ex) - { - ex.ToString().WriteErrorLine(); - return false; - } - } - } -} +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace ExcelTool.Parser +{ + public static class GenModels + { + // ── 枚举类型映射(key: 小写类型名,value: C# 枚举类型名)────────────── + // 新增枚举类型只改这里 + private static readonly Dictionary EnumMap = new() + { + { "killmode", "KillMode" }, + { "mixingtype", "MixingType" }, + { "containertype", "ContainerType" }, + { "blendcrossfadetype","BlendCrossFadeType" }, + }; + + /// + /// 生成对应的 C# Model 类 + /// + public static bool GenCSharpModel(string fileName, string outputDir, string nameSpace = "") + { + if (string.IsNullOrEmpty(fileName)) + { + "GenCSharpModel 参数传递有误".WriteErrorLine(); + return false; + } + + try + { + FileInfo fileInfo = new(fileName); + if (string.IsNullOrEmpty(outputDir)) + outputDir = fileInfo.DirectoryName; + + for (int sheetNum = 0; ; sheetNum++) + { + var headers = ExcelHelper.ExcelHeaders(fileName, out string sheetName, out int sheetCount, sheetNum); + if (headers == null || headers.Count == 0 || sheetName.StartsWith('#') || sheetNum > sheetCount) + break; + + var sb = new StringBuilder(); + sb.Append($"/*\n * auto generated by tools(注意:千万不要手动修改本文件)\n * {sheetName}\n */\n"); + sb.Append("using System;\nusing System.IO;\nusing System.Collections.Generic;\nusing System.Text;\nusing WKMobile.Generated;\n\n"); + + if (!string.IsNullOrEmpty(nameSpace)) + sb.Append($"namespace {nameSpace}\n{{\n"); + + // ── 数据行类 ───────────────────────────────────────────────── + sb.Append("[Serializable]\n"); + sb.Append($"public partial class {sheetName} : IBinarySerializable\n"); + sb.Append("{\n"); + + foreach (var header in headers) + AppendProperty(sb, header); + + AppendDeserializeMethod(sb, headers, sheetName); + AppendSerializeMethod(sb, headers, sheetName); + + sb.Append("}\n\n"); + + // ── Config 容器类 ───────────────────────────────────────────── + AppendConfigClass(sb, sheetName); + + if (!string.IsNullOrEmpty(nameSpace)) + sb.Append("}\n"); + + FileManager.WriteToFile(Path.Combine(outputDir, $"{sheetName}.cs"), sb.ToString()); + } + + return true; + } + catch (Exception ex) + { + ex.ToString().WriteErrorLine(); + return false; + } + } + + // ────────────────────────────────────────────────────────────────────────── + // 属性声明 + // ────────────────────────────────────────────────────────────────────────── + + private static void AppendProperty(StringBuilder sb, TableExcelHeader header) + { + // XML 注释 + sb.Append("\t/// \n"); + var descLines = header.FieldDesc?.Replace("\r", "").Split('\n'); + if (descLines != null) + foreach (var line in descLines) + sb.Append($"\t/// {line}\n"); + sb.Append("\t/// \n"); + + var csType = ResolveCSharpType(header.FieldType); + sb.Append($"\tpublic {csType} {header.FieldName} {{ get; set; }}\n\n"); + } + + // ────────────────────────────────────────────────────────────────────────── + // DeSerialize 方法 + // ────────────────────────────────────────────────────────────────────────── + + private static void AppendDeserializeMethod(StringBuilder sb, List headers, string sheetName) + { + sb.Append("\n\tpublic void DeSerialize(BinaryReader reader)\n\t{\n"); + + foreach (var header in headers) + { + var type = header.FieldType.ToLower(); + var name = header.FieldName; + + // 枚举 + if (EnumMap.TryGetValue(type, out var enumCsType)) + { + sb.Append($"\t\t{name} = ({enumCsType})reader.ReadByte();\n"); + continue; + } + + // 注册表中的具名类型 + var desc = TypeRegistry.Get(type); + if (desc != null) + { + sb.Append(desc.GenDeserialize(name)); + continue; + } + + // list 泛型语法 + if (TryParseGenericList(type, out var elemType)) + { + var elemDesc = TypeRegistry.Get(elemType); + if (elemDesc == null) + { + $"list 的元素类型 \"{elemType}\" 未注册 ({sheetName})".WriteErrorLine(); + continue; + } + // 读取表达式复用注册表中的 GenDeserialize 只取 ReadXxx() 部分比较麻烦, + // 这里直接用公共辅助方法生成片段 + sb.Append(TypeRegistry.GenListDeserialize(name, elemDesc.CSharpType, GetReadExpr(elemDesc))); + continue; + } + + $"类型 \"{type}\" 未注册,{sheetName} 处理异常".WriteErrorLine(); + } + + sb.Append("\t}\n"); + } + + // ────────────────────────────────────────────────────────────────────────── + // Serialize 方法 + // ────────────────────────────────────────────────────────────────────────── + + private static void AppendSerializeMethod(StringBuilder sb, List headers, string sheetName) + { + sb.Append("\n\tpublic void Serialize(BinaryWriter writer)\n\t{\n"); + + foreach (var header in headers) + { + var type = header.FieldType.ToLower(); + var name = header.FieldName; + + // 枚举 + if (EnumMap.ContainsKey(type)) + { + sb.Append($"\t\twriter.Write((byte){name});\n"); + continue; + } + + // 注册表 + var desc = TypeRegistry.Get(type); + if (desc != null) + { + sb.Append(desc.GenSerialize(name)); + continue; + } + + // list 泛型语法 + if (TryParseGenericList(type, out _)) + { + sb.Append(TypeRegistry.GenListSerialize(name)); + continue; + } + + $"类型 \"{type}\" 未注册,{sheetName} 处理异常".WriteErrorLine(); + } + + sb.Append("\t}\n"); + } + + // ────────────────────────────────────────────────────────────────────────── + // Config 容器类(不涉及类型系统,逻辑不变,仅格式整理) + // ────────────────────────────────────────────────────────────────────────── + + private static void AppendConfigClass(StringBuilder sb, string name) + { + var camel = name.ToCamelCase(); + sb.Append("[Serializable]\n"); + sb.Append($"public partial class {name}Config : IBinarySerializable\n{{\n"); + sb.Append($"\tDictionary m_{camel}Infos = new();\n"); + sb.Append($"\tList<{name}> m_{camel}InfoList;\n\n"); + + sb.Append($"\tpublic List<{name}> {name}List()\n\t{{\n"); + sb.Append($"\t\tthis.m_{camel}InfoList ??= new List<{name}>(m_{camel}Infos.Values);\n"); + sb.Append($"\t\treturn this.m_{camel}InfoList;\n\t}}\n\n"); + + sb.Append($"\tpublic void DeSerialize(BinaryReader reader)\n\t{{\n"); + sb.Append($"\t\tint count = reader.ReadInt32();\n"); + sb.Append($"\t\tfor (int i = 0; i < count; i++)\n\t\t{{\n"); + sb.Append($"\t\t\t{name} tempData = new();\n"); + sb.Append($"\t\t\ttempData.DeSerialize(reader);\n"); + sb.Append($"\t\t\tthis.m_{camel}Infos.Add(tempData.Id, tempData);\n"); + sb.Append("\t\t}\n\t}\n\n"); + + sb.Append($"\tpublic void Serialize(BinaryWriter writer)\n\t{{\n"); + sb.Append($"\t\twriter.Write(this.m_{camel}Infos.Count);\n"); + sb.Append($"\t\tforeach ({name} {camel} in this.m_{camel}Infos.Values)\n\t\t{{\n"); + sb.Append($"\t\t\t{camel}.Serialize(writer);\n"); + sb.Append("\t\t}\n\t}\n\n"); + + sb.Append($"\tpublic {name} QueryById(uint id)\n\t{{\n"); + sb.Append($"\t\treturn this.m_{camel}Infos.GetValueOrDefault(id);\n"); + sb.Append("\t}\n}\n"); + } + + // ────────────────────────────────────────────────────────────────────────── + // 工具方法 + // ────────────────────────────────────────────────────────────────────────── + + /// 把字段类型名解析为 C# 属性类型字符串 + private static string ResolveCSharpType(string fieldType) + { + var lower = fieldType.ToLower(); + + if (EnumMap.TryGetValue(lower, out var enumType)) + return enumType; + + var desc = TypeRegistry.Get(lower); + if (desc != null) + return desc.CSharpType; + + // list 泛型 + if (TryParseGenericList(lower, out var elemType)) + { + var elemDesc = TypeRegistry.Get(elemType); + return elemDesc != null ? $"List<{elemDesc.CSharpType}>" : $"List<{elemType}>"; + } + + // 兜底:直接用原始类型名(可能是用户自定义类型) + return fieldType.ToLower(); + } + + /// 尝试解析 list<T> 语法,成功返回元素类型名 + private static bool TryParseGenericList(string type, out string elemType) + { + if (type.StartsWith("list<") && type.EndsWith(">")) + { + elemType = type[5..^1]; + return true; + } + elemType = null; + return false; + } + + /// 从 TypeDescriptor 反推 reader.ReadXxx() 表达式(用于 list<T> 代码生成) + private static string GetReadExpr(TypeDescriptor desc) + { + // GenDeserialize 生成的行形如 "\t\tname = reader.ReadXxx();\n" + // 这里简单地从注册表拿一个占位 name 然后截取表达式部分 + const string placeholder = "__x__"; + var line = desc.GenDeserialize(placeholder).Trim(); // "x = reader.ReadXxx();" + var eqIdx = line.IndexOf('='); + return eqIdx >= 0 + ? line[(eqIdx + 1)..].TrimEnd(';').Trim() // "reader.ReadXxx()" + : $"/* unknown read for {desc.TypeName} */"; + } + } +} diff --git a/ExcelTool/TypeRegistry.cs b/ExcelTool/TypeRegistry.cs new file mode 100644 index 0000000..30c096f --- /dev/null +++ b/ExcelTool/TypeRegistry.cs @@ -0,0 +1,278 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace ExcelTool +{ + /// + /// 类型描述符:集中管理单个类型的「二进制写入」和「C# 代码生成」逻辑。 + /// 新增类型时只需在 TypeRegistry.Register() 里追加一条注册即可。 + /// + public class TypeDescriptor + { + /// 小写类型名,作为注册 key + public string TypeName { get; init; } + + /// 对应的 C# 属性类型字符串,例如 "int"、"List<float>" + public string CSharpType { get; init; } + + /// 将字符串值写入 BinaryWriter 的逻辑 + public Action WriteBinary { get; init; } + + /// + /// 生成 DeSerialize 方法体片段(变量名 → 代码行) + /// 返回的字符串已含换行,调用方直接 sb.Append 即可 + /// + public Func GenDeserialize { get; init; } + + /// + /// 生成 Serialize 方法体片段(变量名 → 代码行) + /// + public Func GenSerialize { get; init; } + } + + /// + /// 类型注册表。所有支持的字段类型统一在这里注册,一处修改全局生效。 + /// + public static class TypeRegistry + { + private static readonly Dictionary s_map = new(); + + static TypeRegistry() + { + RegisterAll(); + } + + // ────────────────────────────────────────────── + // 对外查询 + // ────────────────────────────────────────────── + + /// 查找类型描述符,找不到返回 null + public static TypeDescriptor Get(string typeName) => + s_map.TryGetValue(typeName.ToLower(), out var desc) ? desc : null; + + /// 是否包含该类型 + public static bool Contains(string typeName) => s_map.ContainsKey(typeName.ToLower()); + + // ────────────────────────────────────────────── + // 注册入口:新增类型只需在此追加 Register(...) + // ────────────────────────────────────────────── + + private static void RegisterAll() + { + // ---------- 基础值类型 ---------- + RegisterPrimitive("int", "int", "reader.ReadInt32()", (bw, v) => bw.Write(string.IsNullOrEmpty(v) ? 0 : Convert.ToInt32(v))) ; + RegisterPrimitive("uint", "uint", "reader.ReadUInt32()", (bw, v) => bw.Write(string.IsNullOrEmpty(v) ? 0u : Convert.ToUInt32(v))) ; + RegisterPrimitive("short", "short", "reader.ReadInt16()", (bw, v) => bw.Write(string.IsNullOrEmpty(v) ? (short)0 : Convert.ToInt16(v))) ; + RegisterPrimitive("ushort", "ushort", "reader.ReadUInt16()", (bw, v) => bw.Write(string.IsNullOrEmpty(v) ? (ushort)0 : Convert.ToUInt16(v))) ; + RegisterPrimitive("sbyte", "sbyte", "reader.ReadSByte()", (bw, v) => bw.Write(string.IsNullOrEmpty(v) ? (sbyte)0 : Convert.ToSByte(v))) ; + RegisterPrimitive("byte", "byte", "reader.ReadByte()", (bw, v) => bw.Write(string.IsNullOrEmpty(v) ? (byte)0 : Convert.ToByte(v))) ; + RegisterPrimitive("float", "float", "reader.ReadSingle()", (bw, v) => bw.Write(string.IsNullOrEmpty(v) ? 0f : Convert.ToSingle(v))) ; + RegisterPrimitive("double", "double", "reader.ReadDouble()", (bw, v) => bw.Write(string.IsNullOrEmpty(v) ? 0d : Convert.ToDouble(v))) ; + RegisterPrimitive("long", "long", "reader.ReadInt64()", (bw, v) => bw.Write(string.IsNullOrEmpty(v) ? 0L : Convert.ToInt64(v))) ; + RegisterPrimitive("string", "string", "reader.ReadString()", (bw, v) => bw.Write(v ?? "")) ; + + // bool 单独处理(解析逻辑稍特殊) + Register(new TypeDescriptor + { + TypeName = "bool", + CSharpType = "bool", + WriteBinary = (bw, v) => + { + if (string.IsNullOrEmpty(v)) { bw.Write(false); return; } + var s = v.Trim().ToLower(); + bw.Write(s is "true" or "1"); + }, + GenDeserialize = name => $"\t\t{name} = reader.ReadBoolean();\n", + GenSerialize = name => $"\t\twriter.Write({name});\n", + }); + + // ---------- 集合类型 ---------- + // vector → List(固定 3 分量,写入时先写分量数) + Register(new TypeDescriptor + { + TypeName = "vector", + CSharpType = "List", + WriteBinary = (bw, v) => + { + if (string.IsNullOrEmpty(v)) { bw.Write(0); return; } + var parts = v.Replace("]", "").Replace("[", "").Split(','); + int count = 3; + bw.Write(count); + for (int i = 0; i < count; i++) + bw.Write(Convert.ToSingle(parts[i])); + }, + GenDeserialize = name => GenListDeserialize(name, "float", "reader.ReadSingle()"), + GenSerialize = name => GenListSerialize(name), + }); + + // vectorlist → List> + Register(new TypeDescriptor + { + TypeName = "vectorlist", + CSharpType = "List>", + WriteBinary = (bw, v) => + { + if (string.IsNullOrEmpty(v)) { bw.Write(0); return; } + var parts = v.Replace("]", "").Replace("[", "").Split(','); + bw.Write(parts.Length / 3); + for (int i = 0; i < parts.Length; i++) + { + if (i % 3 == 0) bw.Write(3); + bw.Write(Convert.ToSingle(parts[i])); + } + }, + GenDeserialize = name => GenVectorListDeserialize(name), + GenSerialize = name => GenVectorListSerialize(name), + }); + + // 简写集合类型(xxxlist) + RegisterList("intlist", "int", "reader.ReadInt32()", (bw, s) => bw.Write(Convert.ToInt32(s))); + RegisterList("uintlist", "uint", "reader.ReadUInt32()", (bw, s) => bw.Write(Convert.ToUInt32(s))); + RegisterList("shortlist", "short", "reader.ReadInt16()", (bw, s) => bw.Write(Convert.ToInt16(s))); + RegisterList("ushortlist", "ushort", "reader.ReadUInt16()", (bw, s) => bw.Write(Convert.ToUInt16(s))); + RegisterList("sbytelist", "sbyte", "reader.ReadSByte()", (bw, s) => bw.Write(Convert.ToSByte(s))); + RegisterList("bytelist", "byte", "reader.ReadByte()", (bw, s) => bw.Write(Convert.ToByte(s))); + RegisterList("boollist", "bool", "reader.ReadBoolean()",(bw, s) => bw.Write(Convert.ToBoolean(s))); + RegisterList("floatlist", "float", "reader.ReadSingle()", (bw, s) => bw.Write(Convert.ToSingle(s))); + RegisterList("doublelist", "double", "reader.ReadDouble()", (bw, s) => bw.Write(Convert.ToDouble(s))); + RegisterList("longlist", "long", "reader.ReadInt64()", (bw, s) => bw.Write(Convert.ToInt64(s))); + RegisterList("stringlist", "string", "reader.ReadString()", (bw, s) => bw.Write(s)); + } + + // ────────────────────────────────────────────── + // 注册辅助 + // ────────────────────────────────────────────── + + public static void Register(TypeDescriptor desc) => + s_map[desc.TypeName.ToLower()] = desc; + + /// 注册基础值类型的快捷方法 + private static void RegisterPrimitive( + string typeName, + string csType, + string readExpr, + Action writeBinary) + { + Register(new TypeDescriptor + { + TypeName = typeName, + CSharpType = csType, + WriteBinary = writeBinary, + GenDeserialize = name => $"\t\t{name} = {readExpr};\n", + GenSerialize = name => $"\t\twriter.Write({name});\n", + }); + } + + /// 注册 xxxlist 简写集合类型的快捷方法 + private static void RegisterList( + string typeName, + string elemCsType, + string readElemExpr, + Action writeElem) + { + Register(new TypeDescriptor + { + TypeName = typeName, + CSharpType = $"List<{elemCsType}>", + WriteBinary = (bw, v) => + { + if (string.IsNullOrEmpty(v)) { bw.Write(0); return; } + var parts = v.Split(','); + bw.Write(parts.Length); + foreach (var p in parts) writeElem(bw, p); + }, + GenDeserialize = name => GenListDeserialize(name, elemCsType, readElemExpr), + GenSerialize = name => GenListSerialize(name), + }); + } + + // ────────────────────────────────────────────── + // 公共代码生成片段(供 GenModels 中 list 泛型语法共用) + // ────────────────────────────────────────────── + + /// 生成 List<T> 的 DeSerialize 片段 + public static string GenListDeserialize(string name, string elemCsType, string readElemExpr) + { + var camel = StringExtensions.ToCamelCase(name); + return + $"\t\tvar {camel}Count = reader.ReadInt32();\n" + + $"\t\tif ({camel}Count > 0)\n" + + "\t\t{\n" + + $"\t\t\t{name} = new List<{elemCsType}>();\n" + + $"\t\t\tfor (int i = 0; i < {camel}Count; i++)\n" + + "\t\t\t{\n" + + $"\t\t\t\t{name}.Add({readElemExpr});\n" + + "\t\t\t}\n" + + "\t\t}\n" + + "\t\telse\n" + + "\t\t{\n" + + $"\t\t\t{name} = null;\n" + + "\t\t}\n"; + } + + /// 生成普通 List<T> 的 Serialize 片段(writer.Write 直接写元素) + public static string GenListSerialize(string name) + { + return + $"\t\tif ({name} == null || {name}.Count == 0)\n" + + "\t\t{\n" + + "\t\t\twriter.Write(0);\n" + + "\t\t}\n" + + "\t\telse\n" + + "\t\t{\n" + + $"\t\t\twriter.Write({name}.Count);\n" + + $"\t\t\tfor (int i = 0; i < {name}.Count; i++)\n" + + "\t\t\t{\n" + + $"\t\t\t\twriter.Write({name}[i]);\n" + + "\t\t\t}\n" + + "\t\t}\n"; + } + + private static string GenVectorListDeserialize(string name) + { + var camel = StringExtensions.ToCamelCase(name); + return + $"\t\tvar {camel}Count = reader.ReadInt32();\n" + + $"\t\tif ({camel}Count > 0)\n" + + "\t\t{\n" + + $"\t\t\t{name} = new List>();\n" + + $"\t\t\tfor (int i = 0; i < {camel}Count; i++)\n" + + "\t\t\t{\n" + + "\t\t\t\tvar tempList = new List();\n" + + "\t\t\t\tvar tempListCount = reader.ReadInt32();\n" + + "\t\t\t\tfor (int j = 0; j < tempListCount; j++)\n" + + "\t\t\t\t{\n" + + "\t\t\t\t\ttempList.Add(reader.ReadSingle());\n" + + "\t\t\t\t}\n" + + $"\t\t\t\t{name}.Add(tempList);\n" + + "\t\t\t}\n" + + "\t\t}\n" + + "\t\telse\n" + + "\t\t{\n" + + $"\t\t\t{name} = null;\n" + + "\t\t}\n"; + } + + private static string GenVectorListSerialize(string name) + { + return + $"\t\tif ({name} == null || {name}.Count == 0)\n" + + "\t\t{\n" + + "\t\t\twriter.Write(0);\n" + + "\t\t}\n" + + "\t\telse\n" + + "\t\t{\n" + + $"\t\t\twriter.Write({name}.Count);\n" + + $"\t\t\tfor (int i = 0; i < {name}.Count; i++)\n" + + "\t\t\t{\n" + + $"\t\t\t\twriter.Write({name}[i].Count);\n" + + $"\t\t\t\tfor (int j = 0; j < {name}[i].Count; j++)\n" + + "\t\t\t\t{\n" + + $"\t\t\t\t\twriter.Write({name}[i][j]);\n" + + "\t\t\t\t}\n" + + "\t\t\t}\n" + + "\t\t}\n"; + } + } +}