/// <summary> /// 生成消息的字符串 /// </summary> /// <param name="msg"></param> /// <param name="needCheckCSharpType">是否需要检查C#类型</param> /// <returns></returns> private string GenerateDecodeMessage(ProtocolControlCache_ProtoStructure.Message msg, bool needCheckCSharpType) { if (msg == null) { return(string.Empty); } stringBuilderForMessage.Remove(0, stringBuilderForMessage.Length); //消息名 stringBuilderForMessage.Append(GetCurrentRetract()); stringBuilderForMessage.Append("function "); stringBuilderForMessage.Append(proto.Package); stringBuilderForMessage.Append('.'); stringBuilderForMessage.Append(msg.MessageName); stringBuilderForMessage.Append("(decodedData)"); //判空 AddRetract(); stringBuilderForMessage.Append(GetCurrentRetract()); stringBuilderForMessage.Append("if (decodedData == nil) then"); AddRetract(); stringBuilderForMessage.Append(GetCurrentRetract()); stringBuilderForMessage.Append("return nil"); MinusRetract(); stringBuilderForMessage.Append(GetCurrentRetract()); stringBuilderForMessage.Append("end"); //C#对象定义 stringBuilderForMessage.Append(GetCurrentRetract()); stringBuilderForMessage.Append("local data = CS."); stringBuilderForMessage.Append(proto.Package); stringBuilderForMessage.Append('.'); stringBuilderForMessage.Append(msg.MessageName); stringBuilderForMessage.Append("()"); //向C#对象中填充内容 for (int i = 0; i < msg.Variables.Length; i++) { var variableTemp = msg.Variables[i]; if (needCheckCSharpType && !ServerTool_ProtocolControllerUtility.IsFieldExistInCSType(proto.Package, msg.MessageName, variableTemp.VariableName)) { stringBuilderForMessage.Append(GetCurrentRetract()); stringBuilderForMessage.Append("--C#的"); stringBuilderForMessage.Append(proto.Package); stringBuilderForMessage.Append("."); stringBuilderForMessage.Append(msg.MessageName); stringBuilderForMessage.Append("类中没有找到"); stringBuilderForMessage.Append(variableTemp.VariableName); stringBuilderForMessage.Append("字段,不填充数据"); UnityEngine.Debug.LogErrorFormat("未在C#类 {0}.{1} 中找到 {2} 字段或属性,未进行数据填充", proto.Package, msg.MessageName, variableTemp.VariableName); continue; } stringBuilderForMessage.Append(GenerateDecodeVariable(msg, variableTemp)); } stringBuilderForMessage.Append(GetCurrentRetract()); stringBuilderForMessage.Append("return data"); MinusRetract(); stringBuilderForMessage.Append(GetCurrentRetract()); stringBuilderForMessage.Append("end"); return(stringBuilderForMessage.ToString()); }
/// <summary> /// 消息中是否有某个字段的类型不存在 /// </summary> /// <param name="messageStructure"></param> /// <param name="list"></param> /// <returns></returns> private static bool IsAnyFieldNotExistInMessageInternal(ProtocolControlCache_ProtoStructure.Message messageStructure, List <string> list = null) { if (messageStructure == null || messageStructure.Owner == null) { //消息不存在时返回false return(false); } if (list == null) { list = new List <string>(); } string msgTypeStr = messageStructure.Owner.Package + "." + messageStructure.MessageName; if (list.Contains(msgTypeStr)) { //已经检查过了,防止递归死循环 return(false); } list.Add(msgTypeStr); for (int i = 0; i < messageStructure.Variables.Length; i++) { var variableTemp = messageStructure.Variables[i]; if (!ServerTool_ProtocolControllerUtility.IsFieldExistInCSType(messageStructure.Owner.Package, messageStructure.MessageName, variableTemp.VariableName)) { //若字段在C#类中不存在,则返回true return(true); } if (variableTemp.VType == ProtocolControlCache_ProtoStructure.VariableInMessage.VariableType.Others) { var variableType = ServerTool_ProtocolController_GenerateLuaFromProto.GetVariableTypeInOthers(messageStructure.Owner, messageStructure, variableTemp); if (variableType.isEnumType || variableType.messageType == null) { continue; } if (!ServerTool_ProtocolControllerUtility.IsCSTypeLoaded(variableType.typeString, out Type typeTemp)) { //若字段使用的类型未在C#中找到,则返回true return(true); } if (IsAnyFieldNotExistInMessageInternal(variableType.messageType, list)) { //若字段使用的类型中也有字段未在C#中实现,则也返回true return(true); } } } return(false); }
/// <summary> /// 生成转换lua代码至字符串拼接器中 /// </summary> private void GenerateDecodeLuaCodes(bool needCheckCSharpType) { //拼接表名 cacheStringBuilder.Append("--[[本文件为工具自动生成,禁止手动修改]]\r\nlocal "); cacheStringBuilder.Append(proto.Package); cacheStringBuilder.Append(" = {}\r\n\r\nlocal decodeTable = protobufMgr.DecodeTable"); //拼接消息内容 for (int i = 0; i < proto.Messages.Count; i++) { //若需要检查C#类型是否存在,则在不存在该C#类型时,不生成对应的适配代码 if (needCheckCSharpType && !ServerTool_ProtocolControllerUtility.IsCSTypeLoaded(proto.Package, proto.Messages[i].MessageName)) { cacheStringBuilder.Append(GetCurrentRetract()); cacheStringBuilder.Append(GetCurrentRetract()); cacheStringBuilder.Append("--[["); cacheStringBuilder.Append(proto.Package); cacheStringBuilder.Append("."); cacheStringBuilder.Append(proto.Messages[i].MessageName); cacheStringBuilder.Append(" 未在C#中找到对应的类型,不生成对应的lua转换代码"); cacheStringBuilder.Append("]]"); UnityEngine.Debug.Log("C#程序集中未找到 " + proto.Package + "." + proto.Messages[i].MessageName + " 类型,故忽略该类型的lua=>C#转化"); continue; } isAnyMessageGenerated = true; cacheStringBuilder.Append(GetCurrentRetract()); cacheStringBuilder.Append(GetCurrentRetract()); cacheStringBuilder.Append("---@param decodedData "); cacheStringBuilder.Append(proto.Package); cacheStringBuilder.Append("."); cacheStringBuilder.Append(proto.Messages[i].MessageName); cacheStringBuilder.Append(" lua中的数据结构"); cacheStringBuilder.Append(GetCurrentRetract()); cacheStringBuilder.Append("---@return "); cacheStringBuilder.Append(proto.Package); cacheStringBuilder.Append("."); cacheStringBuilder.Append(proto.Messages[i].MessageName); cacheStringBuilder.Append(" C#中的数据结构"); cacheStringBuilder.Append(GenerateDecodeMessage(proto.Messages[i], needCheckCSharpType)); } cacheStringBuilder.Append(GetCurrentRetract()); cacheStringBuilder.Append(GetCurrentRetract()); cacheStringBuilder.Append("return "); cacheStringBuilder.Append(proto.Package); }
/// <summary> /// 生成调整lua代码至字符串拼接器中 /// </summary> /// <param name="needCheckCSharpType"></param> private void GenerateAdjustLuaCodes(bool needCheckCSharpType) { //拼接表名 cacheStringBuilder.Append("--[[本文件为工具自动生成,禁止手动修改]]\r\nlocal "); cacheStringBuilder.Append(proto.Package); cacheStringBuilder.Append("_adj = {}\r\n\r\nlocal adjustTable = protobufMgr.AdjustTable"); //拼接消息内容 for (int i = 0; i < proto.Messages.Count; i++) { //若需要检查C#类型是否存在,则在不存在该C#类型时,不生成对应的适配代码 if (needCheckCSharpType && !ServerTool_ProtocolControllerUtility.IsCSTypeLoaded(proto.Package, proto.Messages[i].MessageName)) { cacheStringBuilder.Append(GetCurrentRetract()); cacheStringBuilder.Append(GetCurrentRetract()); cacheStringBuilder.Append("--[["); cacheStringBuilder.Append(proto.Package); cacheStringBuilder.Append("."); cacheStringBuilder.Append(proto.Messages[i].MessageName); cacheStringBuilder.Append(" 未在C#中找到对应的类型,不生成对应的lua调整代码"); cacheStringBuilder.Append("]]"); UnityEngine.Debug.Log("C#程序集中未找到 " + proto.Package + "." + proto.Messages[i].MessageName + "类型,故忽略该类型的luaTable调整"); continue; } isAnyMessageGenerated = true; cacheStringBuilder.Append(GetCurrentRetract()); cacheStringBuilder.Append(GetCurrentRetract()); cacheStringBuilder.Append(GenerateLuaClassHint(proto, proto.Messages[i])); cacheStringBuilder.Append("---function params"); cacheStringBuilder.Append(GetCurrentRetract()); cacheStringBuilder.Append("---@param tbl "); cacheStringBuilder.Append(proto.Package); cacheStringBuilder.Append("."); cacheStringBuilder.Append(proto.Messages[i].MessageName); cacheStringBuilder.Append(" 待调整的table数据"); cacheStringBuilder.Append(GenerateAdjustMessage(proto.Messages[i], needCheckCSharpType)); } cacheStringBuilder.Append(GetCurrentRetract()); cacheStringBuilder.Append(GetCurrentRetract()); cacheStringBuilder.Append("return "); cacheStringBuilder.Append(proto.Package); cacheStringBuilder.Append("_adj"); }