Files
JJBB/Assets/Editor/Scripts/AutoScript/BinaryMsgTool.cs
2024-08-23 15:49:34 +08:00

580 lines
22 KiB
C#

using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
public class BinaryMsgTool
{
[MenuItem("ProTool/AutoScript/BinaryMsg")]
public static void BinaryMsg()
{
var binaryMsgProto = Application.dataPath + "../../jjbb_public/CreatePacketTool/BinaryMessage.proto";
var fileReader = new StreamReader(binaryMsgProto);
var allClass = ReadAllClasses(fileReader, true);
Debug.Log("allClass:" + allClass.Count);
WriteBianryMsgInfoCs(allClass);
fileReader.Close();
}
[MenuItem("ProTool/AutoScript/BinaryLua")]
public static void BinaryLua()
{
var binaryMsgProto = Application.dataPath + "../../jjbb_public/CreatePacketTool/BinaryMessage.proto";
var fileReader = new StreamReader(binaryMsgProto);
var allClass = ReadAllClasses(fileReader, false, true);
Debug.Log("allClass:" + allClass.Count);
WriteBianryMsgInfoLua(allClass);
fileReader.Close();
}
private static List<MsgStrClass> ReadAllClasses(StreamReader fileReader, bool csFile = false, bool luaFile = false)
{
var classes = new List<MsgStrClass>();
while (!fileReader.EndOfStream)
{
var line = fileReader.ReadLine();
line = line.Trim();
if (line.StartsWith("//@"))
if (csFile && !line.Contains("luaonly") || luaFile && !line.Contains("csonly"))
{
var readClass = ReadClass(fileReader, line);
if (readClass != null) classes.Add(readClass);
}
}
return classes;
}
private static MsgStrClass ReadClass(StreamReader fileReader, string sysIdLine)
{
var msgClass = new MsgStrClass();
//get sysID
if (sysIdLine.Contains("sysid"))
{
var headLineSprit = sysIdLine.Split(' ');
var sysIDSprit = headLineSprit[1].Split('=');
var cmdIDSprit = headLineSprit[2].Split('=');
msgClass.sysID = byte.Parse(sysIDSprit[1]);
msgClass.cmdID = byte.Parse(cmdIDSprit[1]);
}
//get class name
var nameLine = fileReader.ReadLine();
var nameLineSplit = nameLine.Split(' ');
msgClass.msgName = nameLineSplit[1].Trim();
//get props
var brackLine = fileReader.ReadLine();
if (!brackLine.Contains("{"))
{
Debug.LogError("类名下一行需紧跟大括号!!!");
Debug.LogError("大括号独立一行!!");
return null;
}
var bracketCnt = 1;
while (bracketCnt > 0)
{
var lineStr = fileReader.ReadLine().Trim();
if (lineStr.Contains("{"))
{
++bracketCnt;
continue;
}
if (lineStr.Contains("}"))
{
--bracketCnt;
continue;
}
//single prop
if (!string.IsNullOrEmpty(lineStr)) msgClass.msgProps.Add(GetPropClass(lineStr));
}
return msgClass;
}
private static MsgProp GetPropClass(string propStr)
{
var msgProp = new MsgProp();
var propSplit = propStr.Split(' ');
if (propSplit[0].StartsWith("required"))
msgProp.isList = false;
else if (propSplit[0].StartsWith("repeated")) msgProp.isList = true;
msgProp.baseType = propSplit[1].Trim();
msgProp.propName = propSplit[2].Trim();
return msgProp;
}
public class MsgProp
{
public string baseType;
public bool isList;
public string propName;
}
public class MsgStrClass
{
public byte cmdID;
public string msgName;
public List<MsgProp> msgProps = new List<MsgProp>();
public byte sysID;
}
#region cs
private static void WriteBianryMsgInfoCs(List<MsgStrClass> msgClasses)
{
//write BinaryMessageInfo
var binaryInfoPath =
Application.dataPath + "/Project/Script/GameLogic/NetWork/BinaryMessage/BinaryMessageInfo.cs";
var fileStream = new FileStream(binaryInfoPath, FileMode.Create, FileAccess.Write);
fileStream.SetLength(0);
var tempWriter = new StreamWriter(fileStream);
var tempBasePath = Application.dataPath + "/Editor/AutoScript/Resources/BinaryMessageInfo.txt";
var tempClass = Application.dataPath + "/Editor/AutoScript/Resources/BinaryMessageClassTemp.txt";
var tempBaseReader = new StreamReader(tempBasePath);
var tempBase = tempBaseReader.ReadToEnd();
var tempClassReader = new StreamReader(tempClass);
var tempClassStr = tempClassReader.ReadToEnd();
tempWriter.Write(tempBase);
for (var i = 0; i < msgClasses.Count; ++i)
{
var classStr = GetClassStrCS(msgClasses[i], tempClassStr);
tempWriter.Write(classStr);
tempWriter.WriteLine();
}
tempWriter.Close();
//write BinaryMessageID
var binaryIDPath = Application.dataPath + "/Project/Script/GameLogic/NetWork/BinaryMessage/BinaryMessageID.cs";
var msgIDfs = new FileStream(binaryIDPath, FileMode.Create, FileAccess.Write);
msgIDfs.SetLength(0);
var msgIDWriter = new StreamWriter(msgIDfs);
var msgIDTemp = Application.dataPath + "/Project3D/Tool/Editor/AutoScript/Resources/BinaryMessageID.txt";
var msgIDReader = new StreamReader(msgIDTemp);
var msgIDStr = msgIDReader.ReadToEnd();
var binaryDistribute = new Dictionary<byte, List<MsgStrClass>>();
for (var i = 0; i < msgClasses.Count; ++i)
{
if (!binaryDistribute.ContainsKey(msgClasses[i].sysID))
binaryDistribute.Add(msgClasses[i].sysID, new List<MsgStrClass>());
binaryDistribute[msgClasses[i].sysID].Add(msgClasses[i]);
}
var msgIDInfo = "";
var msgHandles = "";
foreach (var distribute in binaryDistribute)
{
if (distribute.Key == 0)
continue;
var distibuteStr = "";
var distibuteHandleStr = "";
distibuteStr += "\t\tif (sysID == " + distribute.Key + ")\n";
distibuteStr += "\t\t{\n";
distibuteHandleStr = distibuteStr;
foreach (var msgClass in distribute.Value)
{
distibuteStr += "\t\t\tif (cmdID == " + msgClass.cmdID + ")\n";
distibuteStr += "\t\t\t\treturn new " + msgClass.msgName + "();\n";
distibuteHandleStr += "\t\t\tif (cmdID == " + msgClass.cmdID + ")\n";
distibuteHandleStr += "\t\t\t\treturn new " + msgClass.msgName + "_Handle();\n";
}
distibuteStr += "\t\t}\n";
distibuteHandleStr += "\t\t}\n";
msgIDInfo += distibuteStr;
msgHandles += distibuteHandleStr;
}
msgIDStr = msgIDStr.Replace("{BinaryIDs}", msgIDInfo);
msgIDStr = msgIDStr.Replace("{BinaryHandles}", msgHandles);
msgIDWriter.Write(msgIDStr);
msgIDWriter.Close();
//write BinaryMessageHandle
for (var i = 0; i < msgClasses.Count; ++i)
{
if (msgClasses[i].sysID == 0)
continue;
WriteMsgHandle(msgClasses[i]);
}
}
private static string GetClassStrCS(MsgStrClass msgClass, string tempStr)
{
var msgStr = tempStr;
msgStr = msgStr.Replace("{ClassName}", msgClass.msgName);
msgStr = msgStr.Replace("{sysIDValue}", msgClass.sysID.ToString());
msgStr = msgStr.Replace("{cmdIDValue}", msgClass.cmdID.ToString());
var propStr = "";
var propReadStr = "";
var propWriteStr = "";
for (var i = 0; i < msgClass.msgProps.Count; ++i)
{
var prop = "";
var propRead = "";
var propWrite = "";
var propBaseType = GetTypeStr(msgClass.msgProps[i].baseType);
if (!msgClass.msgProps[i].isList)
{
prop = "\tpublic " + propBaseType + " " + msgClass.msgProps[i].propName + ";";
propRead = GetReadFuncStr(msgClass.msgProps[i].baseType, msgClass.msgProps[i].propName);
propWrite = GetWriteFuncStr(msgClass.msgProps[i].baseType, msgClass.msgProps[i].propName, 2);
}
else
{
prop = "\tpublic List<" + propBaseType + "> " + msgClass.msgProps[i].propName + " = new List<" +
GetTypeStr(msgClass.msgProps[i].baseType) + ">();";
var propReadFunc = GetReadFuncStr(msgClass.msgProps[i].baseType, "temp", true);
propRead = "\t\tvar " + msgClass.msgProps[i].propName + "Cnt = binaryReader.ReadInt32();\n";
propRead += "\t\tfor (int i = 0; i < " + msgClass.msgProps[i].propName + "Cnt; ++i)\n";
propRead += "\t\t{\n";
propRead += "\t\t" + propReadFunc + "\n";
propRead += "\t\t" + msgClass.msgProps[i].propName + ".Add(temp);\n";
propRead += "\t\t}\n";
propWrite += "\t\tbinaryWriter.Write(" + msgClass.msgProps[i].propName + ".Count);\n";
propWrite += "\t\tfor (int i = 0; i < " + msgClass.msgProps[i].propName + ".Count; ++i)\n";
propWrite += "\t\t{\n";
propWrite += GetWriteFuncStr(msgClass.msgProps[i].baseType, msgClass.msgProps[i].propName + "[i]", 3) +
"\n";
propWrite += "\t\t}\n";
}
propStr += prop + "\n";
propReadStr += propRead + "\n";
propWriteStr += propWrite + "\n";
}
msgStr = msgStr.Replace("{Proprites}", propStr);
msgStr = msgStr.Replace("{ReadProps}", propReadStr);
msgStr = msgStr.Replace("{WriteProps}", propWriteStr);
return msgStr;
}
public static string GetTypeStr(string type)
{
if (type == "int32")
return "Int32";
if (type == "int64")
return "Int64";
return type;
}
public static string GetReadFuncStr(string type, string name, bool needConstruct = false)
{
var construct = "";
if (needConstruct) construct = "var ";
if (type == "int32") return "\t\t" + construct + name + " = binaryReader.ReadInt32();";
if (type == "byte") return "\t\t" + construct + name + " = binaryReader.ReadByte();";
if (type == "string") return "\t\t" + construct + name + " = BinaryMessageHandle.ReadString(binaryReader);";
if (type == "int64") return "\t\t" + construct + name + " = binaryReader.ReadInt64();";
var structStr = "\t\t" + construct + name + " = new " + type + "();\n";
structStr += "\t\t" + name + ".ReadMsg(binaryReader);";
return structStr;
}
private static void AppendTab(StringBuilder builder, int count)
{
for (var i = 0; i < count; i++)
builder.Append('\t');
}
public static string GetWriteFuncStr(string type, string name, int tabCount)
{
var builder = new StringBuilder();
switch (type)
{
case "int32":
case "byte":
case "int64":
AppendTab(builder, tabCount);
builder.Append(string.Format("binaryWriter.Write({0});", name));
builder.Append('\n');
break;
case "string":
AppendTab(builder, tabCount);
builder.Append('{');
builder.Append('\n');
AppendTab(builder, tabCount + 1);
builder.Append(string.Format("var bytes = System.Text.Encoding.UTF8.GetBytes({0});", name));
builder.Append('\n');
AppendTab(builder, tabCount + 1);
builder.Append("binaryWriter.Write((short)bytes.Length);");
builder.Append('\n');
AppendTab(builder, tabCount + 1);
builder.Append("binaryWriter.Write(bytes);");
builder.Append('\n');
AppendTab(builder, tabCount + 1);
builder.Append("binaryWriter.Write((byte)0);");
builder.Append('\n');
AppendTab(builder, tabCount);
builder.Append('}');
builder.Append('\n');
break;
//struct
default:
AppendTab(builder, tabCount);
builder.Append(string.Format("{0}.WriteMsg(binaryWriter);", name));
builder.Append('\n');
break;
}
return builder.ToString();
}
public static void WriteMsgHandle(MsgStrClass msgClass)
{
var fileName = Application.dataPath + "/Project/Script/GameLogic/NetWork/BinaryMessage/BinaryMsgHandles/" +
msgClass.msgName + "_Handle.cs";
if (File.Exists(fileName))
return;
var msgHandlefs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
msgHandlefs.SetLength(0);
var msgHandleWriter = new StreamWriter(msgHandlefs);
var msgIDTemp = Application.dataPath + "/Project3D/Tool/Editor/AutoScript/Resources/MsgHandleTemp.txt";
var msgIDReader = new StreamReader(msgIDTemp);
var msgIDStr = msgIDReader.ReadToEnd();
var msgHandleStr = msgIDStr.Replace("{ClassName}", msgClass.msgName);
msgHandleWriter.Write(msgHandleStr);
msgHandleWriter.Close();
}
#endregion
#region lua
private static void WriteBianryMsgInfoLua(List<MsgStrClass> msgClasses)
{
//write BinaryMessageID
var binaryIDPath = Application.dataPath + "/Project/Script/LuaScripts/NetWork/Lua/LuaMessageManager.txt";
var msgIDfs = new FileStream(binaryIDPath, FileMode.Create, FileAccess.Write);
msgIDfs.SetLength(0);
var msgIDWriter = new StreamWriter(msgIDfs);
var msgIDTemp = Application.dataPath + "/Project3D/Tool/Editor/AutoScript/Resources/LuaMessageManager.txt";
var msgIDReader = new StreamReader(msgIDTemp);
var msgIDStr = msgIDReader.ReadToEnd();
var binaryDistribute = new Dictionary<byte, List<MsgStrClass>>();
for (var i = 0; i < msgClasses.Count; ++i)
{
if (!binaryDistribute.ContainsKey(msgClasses[i].sysID))
binaryDistribute.Add(msgClasses[i].sysID, new List<MsgStrClass>());
binaryDistribute[msgClasses[i].sysID].Add(msgClasses[i]);
}
var msgIDInfo = "";
foreach (var distribute in binaryDistribute)
{
if (distribute.Key == 0)
continue;
var distibuteStr = "";
distibuteStr += "\tif(sysID == " + distribute.Key + ") then\n";
for (var i = 0; i < distribute.Value.Count; ++i)
{
if (i == 0)
distibuteStr += "\t\tif (cmdID == " + distribute.Value[i].cmdID + ") then\n";
else
distibuteStr += "\t\telseif (cmdID == " + distribute.Value[i].cmdID + ") then\n";
var handleName = "LuaHandle" + distribute.Value[i].msgName;
distibuteStr += "\t\t\trequire \"LuaHandle" + distribute.Value[i].msgName + "\"\n";
distibuteStr += "\t\t\t" + handleName + ".HandlePacket(binaryReader)\n";
}
distibuteStr += "\t\tend\n";
distibuteStr += "\tend\n";
msgIDInfo += distibuteStr;
}
msgIDStr = msgIDStr.Replace("{ProMsg}", msgIDInfo);
msgIDWriter.Write(msgIDStr);
msgIDWriter.Close();
for (var i = 0; i < msgClasses.Count; ++i)
{
if (msgClasses[i].sysID == 0)
continue;
WriteMsgHandleLua(msgClasses[i]);
}
for (var i = 0; i < msgClasses.Count; ++i) WriteMsgExtraLua(msgClasses[i], msgClasses);
}
private static void WriteMsgHandleLua(MsgStrClass msgClass)
{
var fileName = Application.dataPath + "/Project/Script/LuaScripts/NetWork/Lua/Handle/LuaHandle" +
msgClass.msgName + ".txt";
if (File.Exists(fileName))
return;
var msgHandlefs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
msgHandlefs.SetLength(0);
var msgHandleWriter = new StreamWriter(msgHandlefs);
var msgIDTemp = Application.dataPath + "/Project3D/Tool/Editor/AutoScript/Resources/LuaHandleTemp.txt";
var msgIDReader = new StreamReader(msgIDTemp);
var msgIDStr = msgIDReader.ReadToEnd();
var msgHandleStr = msgIDStr.Replace("{ClassName}", msgClass.msgName);
msgHandleWriter.Write(msgHandleStr);
msgHandleWriter.Close();
}
private static void WriteMsgExtraLua(MsgStrClass msgClass, List<MsgStrClass> msgClasses)
{
var fileName = Application.dataPath + "/Project/Script/LuaScripts/NetWork/Lua/Distributes/LuaDistributes" +
msgClass.msgName + ".txt";
var msgHandlefs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
msgHandlefs.SetLength(0);
var msgHandleWriter = new StreamWriter(msgHandlefs);
var msgDistributeTemp =
Application.dataPath + "/Project3D/Tool/Editor/AutoScript/Resources/LuaDistributesTemp.txt";
var msgDistributeReader = new StreamReader(msgDistributeTemp);
var msgDistributeStr = msgDistributeReader.ReadToEnd();
msgDistributeStr = msgDistributeStr.Replace("{sysID}", msgClass.sysID.ToString());
msgDistributeStr = msgDistributeStr.Replace("{cmdID}", msgClass.cmdID.ToString());
msgDistributeStr = msgDistributeStr.Replace("{ClassName}", msgClass.msgName);
var readLuaStr = "";
var writeLuaStr = "";
for (var i = 0; i < msgClass.msgProps.Count; ++i)
if (!msgClass.msgProps[i].isList)
{
var nameFormat = string.Format("packet['{0}']", msgClass.msgProps[i].propName);
readLuaStr += GetReadFuncLua(msgClass.msgProps[i].baseType, nameFormat, msgClasses);
readLuaStr += "\n\n";
writeLuaStr += GetWriteFuncLua(msgClass.msgProps[i].baseType, nameFormat);
writeLuaStr += "\n\n";
}
else
{
readLuaStr += "packet['" + msgClass.msgProps[i].propName + "'] = {}\n";
readLuaStr += string.Format("local {0}Cnt = binaryReader:ReadInt32()\n", msgClass.msgProps[i].propName);
readLuaStr += string.Format("for i=1,{0}Cnt,1 do\n", msgClass.msgProps[i].propName);
var nameFormat = "packet['" + msgClass.msgProps[i].propName + "'][i]";
readLuaStr += GetReadFuncLua(msgClass.msgProps[i].baseType, nameFormat, msgClasses);
readLuaStr += "\nend\n";
writeLuaStr += string.Format("if({0} == nil) then\n", msgClass.msgProps[i].propName);
writeLuaStr += "\t" + msgClass.msgProps[i].propName + " = {}\nend\n";
writeLuaStr += string.Format("message:WriteInt(#packet['{0}'])\n", msgClass.msgProps[i].propName);
writeLuaStr += string.Format("for k,v in ipairs(packet['{0}']) do\n", msgClass.msgProps[i].propName);
writeLuaStr += GetWriteFuncLua(msgClass.msgProps[i].baseType, "v");
writeLuaStr += "\nend\n\n";
}
msgDistributeStr = msgDistributeStr.Replace("{ReadPacket}", readLuaStr);
msgDistributeStr = msgDistributeStr.Replace("{WritePacket}", writeLuaStr);
msgHandleWriter.Write(msgDistributeStr);
msgHandleWriter.Close();
}
public static string GetReadFuncLua(string type, string name, List<MsgStrClass> structs)
{
if (type == "int32") return name + " = binaryReader:ReadInt32()";
if (type == "byte") return name + " = binaryReader:ReadByte()";
if (type == "string") return name + " = CS.BinaryMessageHandle.ReadString(binaryReader)";
if (type == "int64") return name + " = binaryReader:ReadInt64()";
var structStr = string.Format("require \"LuaDistributes{0}\"\n", type);
structStr += name + " = LuaDistributes" + type + ".ReadPacket(binaryReader)\n";
return structStr;
}
public static string GetWriteFuncLua(string type, string name)
{
if (type == "int32")
{
var writeStr = "";
writeStr += string.Format("if({0} == nil) then\n", name);
writeStr += string.Format("\t{0} = 0\nend\n", name);
writeStr += string.Format("message:WriteInt({0})", name);
return writeStr;
}
if (type == "byte")
{
var writeStr = "";
writeStr += string.Format("if({0} == nil) then\n", name);
writeStr += string.Format("\t{0} = 0\nend\n", name);
writeStr += string.Format("message:WriteByte({0})", name);
return writeStr;
}
if (type == "string")
{
var writeStr = "";
writeStr += string.Format("if({0} == nil) then\n", name);
writeStr += string.Format("\t{0} = \"\"\nend\n", name);
writeStr += string.Format("message:WriteString({0})", name);
return writeStr;
}
if (type == "int64")
{
var writeStr = "";
writeStr += string.Format("if({0} == nil) then\n", name);
writeStr += string.Format("\t{0} = 0\nend\n", name);
writeStr += string.Format("message:WriteLong({0})", name);
return writeStr;
}
else //struct
{
//writeStr += string.Format("if({0} == nil) then\n", name);
//writeStr += "\t" + name + " = {}\nend\n";
//writeStr += string.Format("CS.BinaryMessageHandle.LuaWriteInt64(binaryWriter, {0})/n", name);
var writeStr = string.Format("require \"LuaDistributes{0}\"\n", type);
writeStr += "LuaDistributes" + type + ".WritePacket(" + name + ", binaryWriter)\n";
return writeStr;
}
}
#endregion
}