You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

320 lines
10 KiB

using System;
using System.IO;
using System.Reflection;
using System.Text;
namespace StructToClass
{
class Program
{
private static string[] forVals = {"i", "j", "k", "m", "n", "x", "y", "z"};
private static string fileName = "../../../u2china_svr_proj/BattleServer/Src/ProtoHelper.cs";
private static FileStream fileStream = null;
public enum ConvertMode
{
ClassToStruct = 1,
StructToClass = 2,
}
private static void Write(string filename, string content)
{
fileStream.Write(ASCIIEncoding.Default.GetBytes(content));
//File.AppendAllText(filename, content);
}
private static void WriteLine(string filename, string content)
{
content += "\n";
fileStream.Write(ASCIIEncoding.Default.GetBytes(content));
//File.AppendAllText(filename, content);
//File.AppendAllText(filename, "\n");
}
private static void WriteIndent(int indentNum)
{
string str = null;
for (int i = 0; i < indentNum; i++)
{
str += "\t";
}
Write(fileName, str);
}
private static void WriteFileHead()
{
string str = @"// GENERATE BY TOOLS, DO NOT EDIT!
namespace Battle
{
public static class ProtoHelper
{";
WriteLine(fileName, str);
}
private static void WriteFileTail()
{
WriteLine(fileName, "\t}");
WriteLine(fileName, "}");
}
private static void WriteFuncHead(Type clsType, ConvertMode mode)
{
if (mode == ConvertMode.ClassToStruct)
{
string str = $"\t\tpublic static void {clsType.Name}ToStruct(ProtoCSClass.{clsType.Name} cls, ref ProtoCSStruct.{clsType.Name} st)";
WriteLine(fileName, str);
WriteLine(fileName, "\t\t{");
}
else
{
string str = $"\t\tpublic static ProtoCSClass.{clsType.Name} {clsType.Name}ToClass(ref ProtoCSStruct.{clsType.Name} st)";
WriteLine(fileName, str);
WriteLine(fileName, "\t\t{");
str = $"\t\t\tvar cls = new ProtoCSClass.{clsType.Name}();";
WriteLine(fileName, str);
}
}
private static void WriteFuncTail(ConvertMode mode)
{
if (mode == ConvertMode.StructToClass)
{
WriteLine(fileName, "\t\t\treturn cls;");
}
WriteLine(fileName, "\t\t}");
}
public static void StructToClass(Type clsType, string prefix, int indentNum, int forIdx, ConvertMode convMode)
{
string src, dst, ns;
if (convMode == ConvertMode.ClassToStruct)
{
src = "cls";
dst = "st";
ns = "ProtoCSStruct";
}
else
{
src = "st";
dst = "cls";
ns = "ProtoCSClass";
}
string newPrefix;
var allFiled = clsType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
foreach (FieldInfo field in allFiled)
{
string line;
var fieldType = field.FieldType;
if (fieldType.IsEnum)
{
WriteIndent(indentNum);
if (prefix != null)
{
line = $"{dst}.{prefix}.{field.Name} = ({ns}.{fieldType.Name}){src}.{prefix}.{field.Name};";
}
else
{
line = $"{dst}.{field.Name} = ({ns}.{fieldType.Name}){src}.{field.Name};";
}
WriteLine(fileName, line);
}
else if (fieldType.IsPrimitive)
{
WriteIndent(indentNum);
if (prefix != null)
{
line = $"{dst}.{prefix}.{field.Name} = {src}.{prefix}.{field.Name};";
}
else
{
line = $"{dst}.{field.Name} = {src}.{field.Name};";
}
WriteLine(fileName, line);
}
else if (fieldType == typeof(string))
{
WriteIndent(indentNum);
if (convMode == ConvertMode.ClassToStruct)
{
if (prefix != null)
{
line = $"{dst}.{prefix}.{field.Name}.SetString({src}.{prefix}.{field.Name});";
}
else
{
line = $"{dst}.{prefix}.SetString({src}.{prefix});";
}
}
else
{
if (prefix != null)
{
line = $"{dst}.{prefix}.{field.Name} = {src}.{prefix}.{field.Name}.GetString();";
}
else
{
line = $"{dst}.{prefix} = {src}.{prefix}.GetString();";
}
}
WriteLine(fileName, line);
}
else if (fieldType.IsGenericType)
{
string fp = forVals[forIdx];
// class转struct传入引用ref, 数组先clear避免引入脏数据
if (convMode == ConvertMode.ClassToStruct)
{
WriteIndent(indentNum);
if (prefix != null)
{
line = $"{dst}.{prefix}.{field.Name}.Clear();";
}
else
{
line = $"{dst}.{field.Name}.Clear();";
}
WriteLine(fileName, line);
}
WriteIndent(indentNum);
if (prefix != null)
{
line = string.Format("for (int {0} = 0; {0} < {3}.{1}.{2}.Count; ++{0})", fp, prefix, field.Name, src);
}
else
{
line = string.Format("for (int {0} = 0; {0} < {2}.{1}.Count; ++{0})", fp, field.Name, src);
}
WriteLine(fileName, line);
WriteIndent(indentNum);
WriteLine(fileName, "{");
if (fieldType.GetGenericArguments()[0].IsPrimitive)
{
WriteIndent(indentNum + 1);
if (prefix != null)
{
line = $"{dst}.{prefix}.{field.Name}.Add({src}.{prefix}.{field.Name}[{fp}]);";
}
else
{
line = $"{dst}.{field.Name}.Add({src}.{field.Name}[{fp}]);";
}
WriteLine(fileName, line);
}
else
{
string gname = fieldType.GetGenericArguments()[0].Name;
WriteIndent(indentNum + 1);
if (prefix != null)
{
line = $"{dst}.{prefix}.{field.Name}.Add(new {ns}.{gname}());";
}
else
{
line = $"{dst}.{field.Name}.Add(new {ns}.{gname}());";
}
WriteLine(fileName, line);
if (prefix != null)
{
newPrefix = string.Format("{0}.{1}[{2}]", prefix, field.Name, fp);
}
else
{
newPrefix = string.Format("{0}[{1}]", field.Name, fp);
}
StructToClass(fieldType.GetGenericArguments()[0], newPrefix, indentNum + 1, forIdx + 1, convMode);
}
WriteIndent(indentNum);
WriteLine(fileName, "}");
}
else if (fieldType.IsClass)
{
if (prefix != null)
{
newPrefix = $"{prefix}.{field.Name}";
}
else
{
newPrefix = field.Name;
}
StructToClass(fieldType, newPrefix, indentNum, forIdx, convMode);
}
}
}
static void Main(string[] args)
{
string path = "./config";
if (! File.Exists(path))
{
Console.WriteLine("path {0} not exist", path);
return;
}
var lines = File.ReadAllLines(path);
if (lines.Length <= 0)
{
Console.WriteLine("config {0} no content", path);
return;
}
if (File.Exists(fileName))
{
Console.WriteLine(" {0} exist, delete it", fileName);
File.Delete(fileName);
}
fileStream = new FileStream(fileName, FileMode.CreateNew);
WriteFileHead();
foreach (string str in lines)
{
string name = str.Trim();
if (!string.IsNullOrEmpty(name))
{
Type clsType = Type.GetType("ProtoCSClass." + name);
WriteFuncHead(clsType, ConvertMode.ClassToStruct);
StructToClass(clsType, null, 3, 0, ConvertMode.ClassToStruct);
WriteFuncTail(ConvertMode.ClassToStruct);
WriteLine(fileName, "");
WriteFuncHead(clsType, ConvertMode.StructToClass);
StructToClass(clsType, null, 3, 0, ConvertMode.StructToClass);
WriteFuncTail(ConvertMode.StructToClass);
WriteLine(fileName, "");
}
}
WriteFileTail();
fileStream.Close();
}
}
}