/// <summary> /// 获得某个参数的注解 /// </summary> /// <param name="item"></param> /// <param name="name"></param> /// <returns></returns> public static string GetParamSummary(this FunItem item, string name) { if (item == null) { return(string.Empty); } var p = item.Params.FirstOrDefault(o => o.Name == name); if (p != null) { return(p.Value); } return(string.Empty); }
/// <summary> /// 把vs生成的xml文件转换为必要的文档 /// </summary> /// <param name="xmlFile"></param> /// <returns></returns> public static List <FunItem> LoadXmlDocument(string xmlFile) { List <FunItem> ret = new List <FunItem>(); if (!File.Exists(xmlFile)) { Logs.Error("not find xml file", xmlFile); return(ret); } var xmlData = File.ReadAllText(xmlFile); XmlDocument dom = new XmlDocument(); dom.LoadXml(xmlData); foreach (XmlNode node in dom.SelectNodes("//member")) { FunItem item = new FunItem(); item.Name = node.Attributes["name"].Value; var nav = node.CreateNavigator(); item.Summary = nav.SelectSingleNode("summary").Value.Trim(); foreach (XPathNavigator pn in nav.Select("param")) { ParamItem pi = new ParamItem(); pi.Name = pn.GetAttribute("name", ""); pi.Value = pn.Value.Trim(); item.Params.Add(pi); } ret.Add(item); } return(ret); }
/// <summary> /// 添加一个方法 /// </summary> /// <param name="att"></param> /// <param name="methodinfo"></param> void AddMethod(NetMethodAttribute att, MethodInfo methodinfo) { var param = methodinfo.GetParameters(); if (param.Length < 1) { Logs.Error(string.Format("{0}.{1} 不支持 {2} 个参数", classType.Name, methodinfo.Name, param.Length.ToString())); return; } if (param[0].ParameterType != typeof(NetState)) { Logs.Error("{0}.{1} 的第一个参数必须是 NetState 对象", classType.Name, methodinfo.Name); return; } if (att.MethodType == NetMethodType.PacketReader) { Logs.Error("客户端代理类不支持这种模式 {0}", att.MethodType.ToString()); return; } if (att.MethodType == NetMethodType.ProtocolStruct) { #region ProtocolStruct Type parameterType = param[1].ParameterType; if (!parameterType.IsClass) { Logs.Error("{0}.{1} 的第二个参数必须是class类型。", classType.Name, methodinfo.Name); return; } if (parameterType.GetInterface(typeof(IPacketWriter).FullName) == null) { // 自己实现一个对对象的协议写入类 AddWriteProxy(parameterType); string methodName = methodinfo.Name; StringBuilder methonNameCode = new StringBuilder(); StringBuilder streamWriterCode = new StringBuilder(); methonNameCode.AppendFormat("public void {0}({1} obj)", methodName, parameterType.FullName); streamWriterCode.AppendLine("{"); streamWriterCode.AppendFormat("var pw = PacketWriter.AcquireContent({0});", att.OpCode); streamWriterCode.AppendLine(); streamWriterCode.AppendFormat( @" PacketProfile packetProfile = PacketProfile.GetOutgoingProfile( {0} ); if ( packetProfile != null ) packetProfile.RegConstruct(); ", att.OpCode); streamWriterCode.AppendFormat("{0}WriteProxy.Write(obj, pw);", parameterType.Name); streamWriterCode.AppendLine("NetState.Send(pw);"); streamWriterCode.AppendLine(" if ( packetProfile != null ) packetProfile.Record(pw.Length);"); streamWriterCode.AppendLine("PacketWriter.ReleaseContent(pw);"); streamWriterCode.AppendLine("}"); methonNameCode.Remove(methonNameCode.Length - 1, 1); methonNameCode.Append(")"); callCode.AppendLine(methonNameCode.ToString()); callCode.AppendLine(streamWriterCode.ToString()); } else { // 如果对象实现了 IPacketWriter 接口,则直接使用,否则则自己生成协议代码 string methodName = methodinfo.Name; StringBuilder methonNameCode = new StringBuilder(); StringBuilder streamWriterCode = new StringBuilder(); methonNameCode.AppendFormat("public void {0}({1} obj)", methodName, parameterType.FullName); streamWriterCode.AppendLine("{"); streamWriterCode.AppendFormat("var pw = PacketWriter.AcquireContent({0});", att.OpCode); streamWriterCode.AppendLine(); streamWriterCode.AppendFormat( @" PacketProfile packetProfile = PacketProfile.GetOutgoingProfile( {0} ); if ( packetProfile != null ) packetProfile.RegConstruct(); ", att.OpCode); streamWriterCode.AppendLine("obj.Write(pw);"); streamWriterCode.AppendLine("NetState.Send(pw);"); streamWriterCode.AppendLine(" if ( packetProfile != null ) packetProfile.Record(pw.Length);"); streamWriterCode.AppendLine("PacketWriter.ReleaseContent(pw);"); streamWriterCode.AppendLine("}"); methonNameCode.Remove(methonNameCode.Length - 1, 1); methonNameCode.Append(")"); callCode.AppendLine(methonNameCode.ToString()); callCode.AppendLine(streamWriterCode.ToString()); } #endregion } if (att.MethodType == NetMethodType.SimpleMethod) { #region SimpleMethod string methodName = Utils.GetFixCallProxyName(methodinfo.Name); StringBuilder methonNameCode = new StringBuilder(); StringBuilder streamWriterCode = new StringBuilder(); StringBuilder commentCode = new StringBuilder(); Console.WriteLine(classType.FullName + "." + methodinfo.Name); var doc = funDoc.FirstOrDefault(o => o.Name.IndexOf("M:" + classType.FullName + "." + methodinfo.Name) == 0); if (doc == null) doc = new FunItem(); commentCode.AppendFormat(@" /// <summary> /// {0} /// </summary> ", doc.Summary); methonNameCode.AppendFormat("public void {0}(", methodName); streamWriterCode.AppendLine("{"); streamWriterCode.AppendFormat("var pw = PacketWriter.AcquireContent({0});", att.OpCode); streamWriterCode.AppendLine(); for (int i = 1; i < param.Length; i++) { var p = param[i]; if (p.ParameterType == typeof(int)) { commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name)); methonNameCode.AppendFormat("int {0},", p.Name); streamWriterCode.AppendFormat("pw.Write({0});\r\n", p.Name); } else if (p.ParameterType == typeof(byte)) { commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name)); methonNameCode.AppendFormat("byte {0},", p.Name); streamWriterCode.AppendFormat("pw.Write({0});\r\n", p.Name); } else if (p.ParameterType == typeof(long)) { commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name)); methonNameCode.AppendFormat("long {0},", p.Name); streamWriterCode.AppendFormat("pw.Write({0});\r\n", p.Name); } else if (p.ParameterType == typeof(float)) { commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name)); methonNameCode.AppendFormat("float {0},", p.Name); streamWriterCode.AppendFormat("pw.Write({0});\r\n", p.Name); } else if (p.ParameterType == typeof(double)) { commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name)); methonNameCode.AppendFormat("double {0},", p.Name); streamWriterCode.AppendFormat("pw.Write({0});\r\n", p.Name); } else if (p.ParameterType == typeof(bool)) { commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name)); methonNameCode.AppendFormat("bool {0},", p.Name); streamWriterCode.AppendFormat("pw.Write({0});\r\n", p.Name); } else if (p.ParameterType == typeof(string)) { commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name)); methonNameCode.AppendFormat("string {0},", p.Name); streamWriterCode.AppendFormat("pw.WriteUTF8Null({0});\r\n", p.Name); } else if (p.ParameterType == typeof(DateTime)) { commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name)); methonNameCode.AppendFormat("DateTime {0},", p.Name); streamWriterCode.AppendFormat("pw.Write({0}.Ticks);\r\n", p.Name); } else if (p.ParameterType.IsEnum) { commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name)); methonNameCode.AppendFormat("{0} {1},", Utils.GetFixFullTypeName(p.ParameterType.FullName), p.Name); streamWriterCode.AppendFormat("pw.Write((byte){0});\r\n", p.Name); } else if (p.ParameterType.IsLayoutSequential) { commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name)); methonNameCode.AppendFormat("{0} {1},", Utils.GetFixFullTypeName(p.ParameterType.FullName), p.Name); streamWriterCode.AppendFormat("pw.WriteStruct({0});\r\n", p.Name); } else if (p.ParameterType.IsArray) { #region 数组的处理 var arrayType = p.ParameterType.GetElementType(); commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name)); methonNameCode.AppendFormat("{0} {1},", Utils.GetFixFullTypeName(p.ParameterType.FullName), p.Name); // 先写入长度 streamWriterCode.AppendFormat("pw.Write((int){0}.Length);\r\n", p.Name); streamWriterCode.AppendFormat("for(int i = 0;i < {0}.Length;i++){{\r\n", p.Name); if (arrayType == typeof(int)) { streamWriterCode.AppendFormat("pw.Write({0}[i]);\r\n", p.Name); } else if (arrayType == typeof(byte)) { streamWriterCode.AppendFormat("pw.Write({0}[i]);\r\n", p.Name); } else if (arrayType == typeof(long)) { streamWriterCode.AppendFormat("pw.Write({0}[i]);\r\n", p.Name); } else if (arrayType == typeof(float)) { streamWriterCode.AppendFormat("pw.Write({0}[i]);\r\n", p.Name); } else if (arrayType == typeof(double)) { streamWriterCode.AppendFormat("pw.Write({0}[i]);\r\n", p.Name); } else if (arrayType == typeof(bool)) { streamWriterCode.AppendFormat("pw.Write({0}[i]);\r\n", p.Name); } else if (arrayType == typeof(string)) { streamWriterCode.AppendFormat("pw.WriteUTF8Null({0}[i]);\r\n", p.Name); } else if (p.ParameterType == typeof(DateTime)) { streamWriterCode.AppendFormat("pw.Write({0}.Ticks);\r\n", p.Name); } else if (arrayType.IsEnum) { streamWriterCode.AppendFormat("pw.Write((byte){0}[i]);\r\n", p.Name); } else if (arrayType.IsLayoutSequential) { streamWriterCode.AppendFormat("pw.WriteStruct({0}[i]);\r\n", p.Name); } streamWriterCode.AppendLine("}"); #endregion } else if (p.ParameterType.IsClass) { AddWriteProxy(p.ParameterType, doc.GetParamSummary(p.Name)); commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name)); methonNameCode.AppendFormat("{0} {1},", Utils.GetFixFullTypeName(p.ParameterType.FullName), p.Name); streamWriterCode.AppendFormat("{0}WriteProxy.Write({1}, pw);\r\n", p.ParameterType.Name, p.Name); } else { Logs.Error(string.Format("{0}.{1} 存在不支持的参数 {2},类型未:{3}", classType.Name, methodinfo.Name, p.Name, p.ParameterType.Name)); } } streamWriterCode.AppendLine("NetState.Send(pw);PacketWriter.ReleaseContent(pw);"); streamWriterCode.AppendLine("}"); if (param.Length > 1) methonNameCode.Remove(methonNameCode.Length - 1, 1); methonNameCode.Append(")"); callCode.AppendLine(commentCode.ToString()); callCode.AppendLine(methonNameCode.ToString()); callCode.AppendLine(streamWriterCode.ToString()); #endregion } }
/// <summary> /// 把vs生成的xml文件转换为必要的文档 /// </summary> /// <param name="xmlFile"></param> /// <returns></returns> public static List<FunItem> LoadXmlDocument(string xmlFile) { List<FunItem> ret = new List<FunItem>(); if (!File.Exists(xmlFile)) { Logs.Error("not find xml file", xmlFile); return ret; } var xmlData = File.ReadAllText(xmlFile); XmlDocument dom = new XmlDocument(); dom.LoadXml(xmlData); foreach (XmlNode node in dom.SelectNodes("//member")) { FunItem item = new FunItem(); item.Name = node.Attributes["name"].Value; var nav = node.CreateNavigator(); item.Summary = nav.SelectSingleNode("summary").Value.Trim(); foreach (XPathNavigator pn in nav.Select("param")) { ParamItem pi = new ParamItem(); pi.Name = pn.GetAttribute("name", ""); pi.Value = pn.Value.Trim(); item.Params.Add(pi); } ret.Add(item); } return ret; }