重写注册逻辑

This commit is contained in:
2026-03-18 15:36:15 +08:00
parent d2a61690de
commit 255c485703
3 changed files with 738 additions and 1283 deletions
+92 -480
View File
@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
@@ -15,388 +15,63 @@ namespace ExcelTool
if (string.IsNullOrEmpty(dirPath)) if (string.IsNullOrEmpty(dirPath))
return false; return false;
if (Directory.Exists(dirPath)) if (Directory.Exists(dirPath))
{
Directory.Delete(dirPath, true); Directory.Delete(dirPath, true);
}
Directory.CreateDirectory(dirPath); Directory.CreateDirectory(dirPath);
return true; return true;
} }
/// <summary> /// <summary>将数据写入二进制文件(IBinarySerializable 版本)</summary>
/// 将数据写入二进制文件
/// </summary>
/// <param name="filePath"></param>
/// <param name="data">继承自IBinarySerialize的数据</param>
public static bool WriteBinaryDataToFile(string filePath, IBinarySerializable data) public static bool WriteBinaryDataToFile(string filePath, IBinarySerializable data)
{ {
if (string.IsNullOrEmpty(filePath)) if (string.IsNullOrEmpty(filePath)) return false;
return false; if (File.Exists(filePath)) File.Delete(filePath);
if (File.Exists(filePath))
{ using var fileStream = new FileStream(filePath, FileMode.Create);
File.Delete(filePath); using var bw = new BinaryWriter(fileStream);
}
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
using (var bw = new BinaryWriter(fileStream))
{
data.Serialize(bw); data.Serialize(bw);
bw.Flush(); bw.Flush();
bw.Close();
}
fileStream.Close();
}
return true; return true;
} }
/// <summary> /// <summary>
/// 将数据写入二进制文件 /// 将数据写入二进制文件
/// 类型名(Item1)须与 <see cref="TypeRegistry"/> 中注册的 key 一致(不区分大小写)。
/// 额外支持 list&lt;T&gt; 泛型语法。
/// </summary> /// </summary>
/// <param name="filePath"></param>
/// <param name="datas">类型(小写)和value的字符串键值对</param>
/// <returns></returns>
public static bool WriteBinaryDatasToFile(string filePath, List<Tuple<string, string>> datas) public static bool WriteBinaryDatasToFile(string filePath, List<Tuple<string, string>> datas)
{ {
try try
{ {
if (string.IsNullOrEmpty(filePath)) if (string.IsNullOrEmpty(filePath)) return false;
return false; if (File.Exists(filePath)) File.Delete(filePath);
if (File.Exists(filePath))
{ using var fileStream = new FileStream(filePath, FileMode.Create);
File.Delete(filePath); using var bw = new BinaryWriter(fileStream);
}
using (var fileStream = new FileStream(filePath, FileMode.Create)) foreach (var (rawType, value) in datas)
{ {
using (var bw = new BinaryWriter(fileStream)) var type = rawType.ToLower();
{
foreach (var data in datas) // ── 优先从注册表查找 ──────────────────────────────
{ var desc = TypeRegistry.Get(type);
if (data.Item1.Equals("int")) if (desc != null)
{ {
if (string.IsNullOrEmpty(data.Item2)) desc.WriteBinary(bw, value);
{ continue;
bw.Write(Convert.ToInt32(0)); }
}
else // ── list<T> 泛型语法(如 list<int>)─────────────
{ if (type.StartsWith("list<") && type.EndsWith(">"))
bw.Write(Convert.ToInt32(data.Item2)); {
} WriteGenericList(bw, type, value);
} continue;
else if (data.Item1.Equals("uint")) }
{
if (string.IsNullOrEmpty(data.Item2)) ConsoleHelper.WriteErrorLine($"写入二进制文件:数据类型 \"{rawType}\" 未注册,请在 TypeRegistry 中添加");
{
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<Vector>类型
{
//[[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>,T不是支持的Int,Float,String这三种类型,需要扩展类型");
}
}
}
else
{
ConsoleHelper.WriteErrorLine($"写入二进制文件,数据类型{data.Item1}没有适配");
return false; return false;
} }
}
bw.Flush(); bw.Flush();
bw.Close();
}
fileStream.Close();
}
return true; return true;
} }
catch (Exception ex) catch (Exception ex)
@@ -406,167 +81,104 @@ namespace ExcelTool
} }
} }
/// <summary> // ──────────────────────────────────────────────────────────────
/// 从内存流中读取二进制 // list<T> 泛型列表写入(T 必须是已在 TypeRegistry 注册的基础类型)
/// </summary> // ──────────────────────────────────────────────────────────────
/// <param name="bytes"></param> private static void WriteGenericList(BinaryWriter bw, string fullType, string value)
/// <param name="data"></param> {
/// <returns></returns> // fullType 形如 "list<int>"
var innerType = fullType[5..^1]; // 去掉 "list<" 和 ">"
var elemDesc = TypeRegistry.Get(innerType);
if (elemDesc == null)
{
ConsoleHelper.WriteErrorLine($"list<T> 的元素类型 \"{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) public static bool ReadBinaryDataFromBytes(byte[] bytes, ref IBinarySerializable data)
{ {
if (bytes == null) if (bytes == null) return false;
return false; using var ms = new MemoryStream(bytes);
using (var memoryStream = new MemoryStream(bytes)) using var br = new BinaryReader(ms);
{
using (var br = new BinaryReader(memoryStream))
{
data.DeSerialize(br); data.DeSerialize(br);
br.Close();
}
memoryStream.Close();
}
return true; return true;
} }
/// <summary>
/// 读取二进制文件
/// </summary>
/// <param name="filePath"></param>
/// <param name="data"></param>
/// <returns></returns>
public static bool ReadBinaryDataFromFile(string filePath, ref IBinarySerializable data) public static bool ReadBinaryDataFromFile(string filePath, ref IBinarySerializable data)
{ {
if (string.IsNullOrEmpty(filePath)) if (string.IsNullOrEmpty(filePath)) return false;
{ using var fs = new FileStream(filePath, FileMode.Open);
return false; using var br = new BinaryReader(fs);
}
using (var fileStream = new FileStream(filePath, FileMode.Open))
{
using (var br = new BinaryReader(fileStream))
{
data.DeSerialize(br); data.DeSerialize(br);
br.Close();
}
fileStream.Close();
}
return true; return true;
} }
public static bool WriteBytesToFile(string filePath, byte[] data) public static bool WriteBytesToFile(string filePath, byte[] data)
{ {
if (string.IsNullOrEmpty(filePath)) if (string.IsNullOrEmpty(filePath)) return false;
return false; if (File.Exists(filePath)) File.Delete(filePath);
if (File.Exists(filePath)) using Stream sw = new FileInfo(filePath).Create();
{
File.Delete(filePath);
}
var file = new FileInfo(filePath);
using (Stream sw = file.Create())
{
sw.Write(data, 0, data.Length); sw.Write(data, 0, data.Length);
sw.Flush(); sw.Flush();
sw.Close();
}
return true; return true;
} }
/// <summary> public static bool WriteToFile(string filePath, string context) =>
/// 将字符串写入文件 WriteToFile(filePath, context, Encoding.Default);
/// </summary>
/// <param name="filePath"></param>
/// <param name="context"></param>
/// <returns></returns>
public static bool WriteToFile(string filePath, string context)
{
return WriteToFile(filePath, context, Encoding.Default);
}
public static bool WriteToFile(string filePath, string context, Encoding encoding) public static bool WriteToFile(string filePath, string context, Encoding encoding)
{ {
if (string.IsNullOrEmpty(filePath)) if (string.IsNullOrEmpty(filePath)) return false;
return false; if (File.Exists(filePath)) File.Delete(filePath);
if (File.Exists(filePath)) using var fs = new FileStream(filePath, FileMode.Create);
{
File.Delete(filePath);
}
using (FileStream fs = new FileStream(filePath, FileMode.Create))
{
var data = encoding.GetBytes(context); var data = encoding.GetBytes(context);
fs.Write(data, 0, data.Length); fs.Write(data, 0, data.Length);
fs.Flush(); fs.Flush();
fs.Close();
}
return true; return true;
} }
/// <summary>
/// 按行读取
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static string ReadAllByLine(string path) public static string ReadAllByLine(string path)
{ {
if (string.IsNullOrEmpty(path) || !File.Exists(path)) if (string.IsNullOrEmpty(path) || !File.Exists(path)) return string.Empty;
{ var sb = new StringBuilder();
return string.Empty; using var sr = new StreamReader(path, Encoding.Default);
}
StringBuilder sb = new StringBuilder();
using (StreamReader sr = new StreamReader(path, Encoding.Default))
{
string line; string line;
while ((line = sr.ReadLine()) != null) while ((line = sr.ReadLine()) != null)
{
sb.AppendLine(line); sb.AppendLine(line);
}
sr.Close();
}
return sb.ToString(); return sb.ToString();
} }
public static byte[] ReadAllBytes(string path) public static byte[] ReadAllBytes(string path) =>
{ string.IsNullOrEmpty(path) || !File.Exists(path) ? null : File.ReadAllBytes(path);
if (string.IsNullOrEmpty(path) || !File.Exists(path))
{
return null;
}
return File.ReadAllBytes(path);
}
/// <summary>
/// 修改文件内容
/// </summary>
/// <param name="path"></param>
/// <param name="normalStr"></param>
/// <param name="newStr"></param>
public static void ReplaceContent(string path, string normalStr, string newStr) public static void ReplaceContent(string path, string normalStr, string newStr)
{ {
if (string.IsNullOrEmpty(path) || !File.Exists(path)) if (string.IsNullOrEmpty(path) || !File.Exists(path)) return;
{ File.WriteAllText(path, File.ReadAllText(path).Replace(normalStr, newStr));
return;
}
string strContent = File.ReadAllText(path);
strContent = strContent.Replace(normalStr, newStr);
File.WriteAllText(path, strContent);
} }
/// <summary>
/// 批量修改文件内容
/// </summary>
/// <param name="path"></param>
/// <param name="newStr"></param>
/// <param name="normalStrs"></param>
public static void ReplaceContent(string path, string newStr, params string[] normalStrs) public static void ReplaceContent(string path, string newStr, params string[] normalStrs)
{ {
if (string.IsNullOrEmpty(path) || !File.Exists(path)) if (string.IsNullOrEmpty(path) || !File.Exists(path)) return;
{ string content = File.ReadAllText(path);
return; foreach (var s in normalStrs) content = content.Replace(s, newStr);
} File.WriteAllText(path, content);
string strContent = File.ReadAllText(path);
for (int i = 0; i < normalStrs.Length; i++)
{
strContent = strContent.Replace(normalStrs[i], newStr);
}
File.WriteAllText(path, strContent);
} }
} }
} }
+222 -657
View File
@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
@@ -7,13 +7,19 @@ namespace ExcelTool.Parser
{ {
public static class GenModels public static class GenModels
{ {
// ── 枚举类型映射(key: 小写类型名,value: C# 枚举类型名)──────────────
// 新增枚举类型只改这里
private static readonly Dictionary<string, string> EnumMap = new()
{
{ "killmode", "KillMode" },
{ "mixingtype", "MixingType" },
{ "containertype", "ContainerType" },
{ "blendcrossfadetype","BlendCrossFadeType" },
};
/// <summary> /// <summary>
/// 生成对应的 C# Model 类 /// 生成对应的 C# Model 类
/// </summary> /// </summary>
/// <param name="fileName">传入的文件名</param>
/// <param name="outputDir">输出cs文件的路径</param>
/// <param name="nameSpace">cs文件要使用的命名空间</param>
/// <returns></returns>
public static bool GenCSharpModel(string fileName, string outputDir, string nameSpace = "") public static bool GenCSharpModel(string fileName, string outputDir, string nameSpace = "")
{ {
if (string.IsNullOrEmpty(fileName)) if (string.IsNullOrEmpty(fileName))
@@ -21,684 +27,48 @@ namespace ExcelTool.Parser
"GenCSharpModel 参数传递有误".WriteErrorLine(); "GenCSharpModel 参数传递有误".WriteErrorLine();
return false; return false;
} }
try try
{ {
// 枚举类型映射
Dictionary<string, string> enumMap = new()
{
{ "killmode", "KillMode" },
{ "mixingtype", "MixingType" },
{ "containertype", "ContainerType" },
{ "blendcrossfadetype", "BlendCrossFadeType" }
};
FileInfo fileInfo = new(fileName); FileInfo fileInfo = new(fileName);
if (string.IsNullOrEmpty(outputDir)) if (string.IsNullOrEmpty(outputDir))
{
outputDir = fileInfo.DirectoryName; outputDir = fileInfo.DirectoryName;
}
for (int sheetNum = 0; ; sheetNum++) for (int sheetNum = 0; ; sheetNum++)
{ {
var headers = ExcelHelper.ExcelHeaders(fileName, out string sheetName, out int sheetCount, sheetNum); var headers = ExcelHelper.ExcelHeaders(fileName, out string sheetName, out int sheetCount, sheetNum);
if (headers == null || headers.Count == 0 || sheetName.StartsWith("#") || sheetNum > sheetCount) if (headers == null || headers.Count == 0 || sheetName.StartsWith('#') || sheetNum > sheetCount)
break; break;
StringBuilder sb = new();
var sb = new StringBuilder();
sb.Append($"/*\n * auto generated by tools(注意:千万不要手动修改本文件)\n * {sheetName}\n */\n"); 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"); sb.Append("using System;\nusing System.IO;\nusing System.Collections.Generic;\nusing System.Text;\nusing WKMobile.Generated;\n\n");
if (!string.IsNullOrEmpty(nameSpace)) if (!string.IsNullOrEmpty(nameSpace))
{
sb.Append($"namespace {nameSpace}\n{{\n"); sb.Append($"namespace {nameSpace}\n{{\n");
}
// ── 数据行类 ─────────────────────────────────────────────────
sb.Append("[Serializable]\n"); sb.Append("[Serializable]\n");
sb.Append($"public partial class {sheetName} : IBinarySerializable\n"); sb.Append($"public partial class {sheetName} : IBinarySerializable\n");
sb.Append("{\n"); sb.Append("{\n");
for (int i = 0; i < headers.Count; i++)
{
sb.Append($"\t/// <summary>\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/// </summary>\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<float> {0}", headers[i].FieldName));
sb.Append(" { get; set; }\n\n");
}
else if (type.Equals("vectorlist"))
{
sb.Append(string.Format("\tpublic List<List<float>> {0}", headers[i].FieldName));
sb.Append(" { get; set; }\n\n");
}
else if (type.Equals("intlist"))
{
sb.Append(string.Format("\tpublic List<int> {0}", headers[i].FieldName));
sb.Append(" { get; set; }\n\n");
}
else if (type.Equals("boollist"))
{
sb.Append(string.Format("\tpublic List<bool> {0}", headers[i].FieldName));
sb.Append(" { get; set; }\n\n");
}
else if (type.Equals("floatlist"))
{
sb.Append(string.Format("\tpublic List<float> {0}", headers[i].FieldName));
sb.Append(" { get; set; }\n\n");
}
else if (type.Equals("stringlist"))
{
sb.Append(string.Format("\tpublic List<string> {0}", headers[i].FieldName));
sb.Append(" { get; set; }\n\n");
}
else if (type.Equals("longlist"))
{
sb.Append(string.Format("\tpublic List<long> {0}", headers[i].FieldName));
sb.Append(" { get; set; }\n\n");
}
else if (type.Equals("uintlist"))
{
sb.Append(string.Format("\tpublic List<uint> {0}", headers[i].FieldName));
sb.Append(" { get; set; }\n\n");
}
else if (type.Equals("ushortlist"))
{
sb.Append(string.Format("\tpublic List<ushort> {0}", headers[i].FieldName));
sb.Append(" { get; set; }\n\n");
}
else if (type.Equals("sbytelist"))
{
sb.Append(string.Format("\tpublic List<sbyte> {0}", headers[i].FieldName));
sb.Append(" { get; set; }\n\n");
}
else if (type.Equals("bytelist"))
{
sb.Append(string.Format("\tpublic List<byte> {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<int> {0}", headers[i].FieldName));
sb.Append(" { get; set; }\n\n");
}
else if (newType.Equals("bool"))
{
sb.Append(string.Format("\tpublic List<bool> {0}", headers[i].FieldName));
sb.Append(" { get; set; }\n\n");
}
else if (newType.Equals("float"))
{
sb.Append(string.Format("\tpublic List<float> {0}", headers[i].FieldName));
sb.Append(" { get; set; }\n\n");
}
else if (newType.Equals("long"))
{
sb.Append(string.Format("\tpublic List<long> {0}", headers[i].FieldName));
sb.Append(" { get; set; }\n\n");
}
else if (newType.Equals("string"))
{
sb.Append(string.Format("\tpublic List<string> {0}", headers[i].FieldName));
sb.Append(" { get; set; }\n\n");
}
else
{
ConsoleHelper.WriteErrorLine("数组类型List<T>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) foreach (var header in headers)
{ AppendProperty(sb, header);
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<float>();\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<List<float>>();\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<float>();\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<int>();\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<uint>();\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<bool>();\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<float>();\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<string>();\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<long>();\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<int>();\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<bool>();\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<float>();\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<long>();\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<string>();\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<")) AppendDeserializeMethod(sb, headers, sheetName);
{ AppendSerializeMethod(sb, headers, sheetName);
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"))
{
} sb.Append("}\n\n");
else if (listTType.Equals("bool"))
{
} // ── Config 容器类 ─────────────────────────────────────────────
else if (listTType.Equals("float")) AppendConfigClass(sb, sheetName);
{
}
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<uint,{sheetName}> 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)) if (!string.IsNullOrEmpty(nameSpace))
{ sb.Append("}\n");
sb.Append("}\n"); // namespace 结束
}
FileManager.WriteToFile(Path.Combine(outputDir, $"{sheetName}.cs"), sb.ToString()); FileManager.WriteToFile(Path.Combine(outputDir, $"{sheetName}.cs"), sb.ToString());
} }
return true; return true;
} }
catch (Exception ex) catch (Exception ex)
@@ -707,5 +77,200 @@ namespace ExcelTool.Parser
return false; return false;
} }
} }
// ──────────────────────────────────────────────────────────────────────────
// 属性声明
// ──────────────────────────────────────────────────────────────────────────
private static void AppendProperty(StringBuilder sb, TableExcelHeader header)
{
// XML 注释
sb.Append("\t/// <summary>\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/// </summary>\n");
var csType = ResolveCSharpType(header.FieldType);
sb.Append($"\tpublic {csType} {header.FieldName} {{ get; set; }}\n\n");
}
// ──────────────────────────────────────────────────────────────────────────
// DeSerialize 方法
// ──────────────────────────────────────────────────────────────────────────
private static void AppendDeserializeMethod(StringBuilder sb, List<TableExcelHeader> 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<T> 泛型语法
if (TryParseGenericList(type, out var elemType))
{
var elemDesc = TypeRegistry.Get(elemType);
if (elemDesc == null)
{
$"list<T> 的元素类型 \"{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<TableExcelHeader> 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<T> 泛型语法
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<uint,{name}> 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");
}
// ──────────────────────────────────────────────────────────────────────────
// 工具方法
// ──────────────────────────────────────────────────────────────────────────
/// <summary>把字段类型名解析为 C# 属性类型字符串</summary>
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<T> 泛型
if (TryParseGenericList(lower, out var elemType))
{
var elemDesc = TypeRegistry.Get(elemType);
return elemDesc != null ? $"List<{elemDesc.CSharpType}>" : $"List<{elemType}>";
}
// 兜底:直接用原始类型名(可能是用户自定义类型)
return fieldType.ToLower();
}
/// <summary>尝试解析 list&lt;T&gt; 语法,成功返回元素类型名</summary>
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;
}
/// <summary>从 TypeDescriptor 反推 reader.ReadXxx() 表达式(用于 list&lt;T&gt; 代码生成)</summary>
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} */";
}
} }
} }
+278
View File
@@ -0,0 +1,278 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace ExcelTool
{
/// <summary>
/// 类型描述符:集中管理单个类型的「二进制写入」和「C# 代码生成」逻辑。
/// 新增类型时只需在 TypeRegistry.Register() 里追加一条注册即可。
/// </summary>
public class TypeDescriptor
{
/// <summary>小写类型名,作为注册 key</summary>
public string TypeName { get; init; }
/// <summary>对应的 C# 属性类型字符串,例如 "int"、"List&lt;float&gt;"</summary>
public string CSharpType { get; init; }
/// <summary>将字符串值写入 BinaryWriter 的逻辑</summary>
public Action<BinaryWriter, string> WriteBinary { get; init; }
/// <summary>
/// 生成 DeSerialize 方法体片段(变量名 → 代码行)
/// 返回的字符串已含换行,调用方直接 sb.Append 即可
/// </summary>
public Func<string, string> GenDeserialize { get; init; }
/// <summary>
/// 生成 Serialize 方法体片段(变量名 → 代码行)
/// </summary>
public Func<string, string> GenSerialize { get; init; }
}
/// <summary>
/// 类型注册表。所有支持的字段类型统一在这里注册,一处修改全局生效。
/// </summary>
public static class TypeRegistry
{
private static readonly Dictionary<string, TypeDescriptor> s_map = new();
static TypeRegistry()
{
RegisterAll();
}
// ──────────────────────────────────────────────
// 对外查询
// ──────────────────────────────────────────────
/// <summary>查找类型描述符,找不到返回 null</summary>
public static TypeDescriptor Get(string typeName) =>
s_map.TryGetValue(typeName.ToLower(), out var desc) ? desc : null;
/// <summary>是否包含该类型</summary>
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<float>(固定 3 分量,写入时先写分量数)
Register(new TypeDescriptor
{
TypeName = "vector",
CSharpType = "List<float>",
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<List<float>>
Register(new TypeDescriptor
{
TypeName = "vectorlist",
CSharpType = "List<List<float>>",
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;
/// <summary>注册基础值类型的快捷方法</summary>
private static void RegisterPrimitive(
string typeName,
string csType,
string readExpr,
Action<BinaryWriter, string> writeBinary)
{
Register(new TypeDescriptor
{
TypeName = typeName,
CSharpType = csType,
WriteBinary = writeBinary,
GenDeserialize = name => $"\t\t{name} = {readExpr};\n",
GenSerialize = name => $"\t\twriter.Write({name});\n",
});
}
/// <summary>注册 xxxlist 简写集合类型的快捷方法</summary>
private static void RegisterList(
string typeName,
string elemCsType,
string readElemExpr,
Action<BinaryWriter, string> 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<T> 泛型语法共用)
// ──────────────────────────────────────────────
/// <summary>生成 List&lt;T&gt; 的 DeSerialize 片段</summary>
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";
}
/// <summary>生成普通 List&lt;T&gt; 的 Serialize 片段(writer.Write 直接写元素)</summary>
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<List<float>>();\n" +
$"\t\t\tfor (int i = 0; i < {camel}Count; i++)\n" +
"\t\t\t{\n" +
"\t\t\t\tvar tempList = new List<float>();\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";
}
}
}