个人网站开发可行性报告,网站的所有权,网站做导航设计的作用是什么意思,南京小程序设计制作概述
1.区分lua#xff0c;cs用的proto 2.proto生成cs#xff0c;使用protogen.exe#xff0c;通过csharp.xslt修改生成cs样式 3.proto生成lua加载.pb二进制文件#xff0c;并生成.pb列表文件#xff0c;用于初始化加载 4.协议id生成cs#xff0c;lua中枚举
区分cscs用的proto 2.proto生成cs使用protogen.exe通过csharp.xslt修改生成cs样式 3.proto生成lua加载.pb二进制文件并生成.pb列表文件用于初始化加载 4.协议id生成cslua中枚举
区分cslua用proto
cs中序列化使用基于CSPacketBaseSCPacketBase的子类 lua中序列化使用lua-protobuf需要提前把pb二进制文件加载 cslua中不通用协议类型即某个协议类型只能在cs或者lua的一侧使用 使用两个文件夹区分cs用的.proto放CSlua用.proto放Lua文件夹下在生成工具中分别处理
协议id生成cslua中
在NetMsgID.txt中填写所有luacs用的协议id不区分lua用还是cs用例如
CSLogin 100,
SCLogin 101,
CSPlayerInfo 102,
SCPlayerInfo 103,
CSSelectCharacter 104,
SCSelectCharacter 105,生成到对应的模板中NetMsgIDTmpCS.cs
namespace Network
{
/// summary
/// 网络协议ID
/// /summary
public enum NetMsgID
{
__Content__
}}NetMsgIDTmpLua.lua
--网络协议ID
NetMsgID
{
__Content__
}替换__Content__再复制到工程目录中
static void GenMsgID()
{string sMsgContent File.ReadAllText(m_msgIDFullName);string sMsgCS File.ReadAllText(m_msgIDTmpCSFullName);string sMsgLua File.ReadAllText(m_msgIDTmpLuaFullName);sMsgCS sMsgCS.Replace(__Content__, sMsgContent); File.WriteAllText(m_msgIDCSFullName,sMsgCS);sMsgLua sMsgLua.Replace(__Content__, sMsgContent);sMsgLua sMsgLua.Replace(//, --);File.WriteAllText(m_msgIDLuaFullName, sMsgLua);
}proto生成cs
使用protogen.exe把.proto生成.cs文件
.net控制台遍历文件夹生成cs
protogen.exe单独使用如下运行命令行cd到protogen.exe的盘符再cd 到protogen.exe的根目录下 把Person.proto放到protogen.exe的同级目录下。
protogen -i:Person.proto -o:Person.cs 编写.net控制台程序执行 启动cmd并cd到protogen.exe根目录
using (Process p new Process())
{//启动cmd并设置好相关属性。p.StartInfo.FileName cmd.exe;p.StartInfo.UseShellExecute false; //是否使用操作系统shell启动p.StartInfo.RedirectStandardInput true;//接受来自调用程序的输入信息p.StartInfo.RedirectStandardOutput true;//由调用程序获取输出信息p.StartInfo.RedirectStandardError true;//重定向标准错误输出p.StartInfo.CreateNoWindow true;//不显示程序窗口p.StartInfo.WindowStyle ProcessWindowStyle.Hidden;p.Start();//cmd要到protogen.exe的根目录string[] arrDiskName Directory.GetCurrentDirectory().Split(:);string diskName arrDiskName[0] :;p.StandardInput.WriteLine(diskName);string cdPath cd m_protoRootPath;p.StandardInput.WriteLine(cdPath);遍历proto/CS目录下proto文件生成到工程目录
//遍历所有cs文件下proto
var files new DirectoryInfo(m_protoPathCS).GetFiles(*.proto, SearchOption.AllDirectories);
foreach (var f in files)
{string fileName f.Name.Replace(.proto, );//生成cs{string sIn -i:proto/CS/ f.Name;string sOut -o: m_csPath fileName .cs;string sCmd protogenPath sIn sOut;p.StandardInput.WriteLine(sCmd);}
}csharp.xslt修改输出cs样式
XSL 指扩展样式表语言EXtensible Stylesheet Language, 它是一个 XML 文档的样式表语言。 XSLT 指 XSL 转换 通过 XSLT您可以向输出文件添加元素和属性或从输出文件移除元素和属性。
在csharp.xslt中载入自定义.xslt xsl:import hrefcustom.xslt/修改基类名
csharp.xslt中增加自定义函数getBaseClassName
public partial class xsl:call-template namepascal/ xsl:call-template namegetBaseClassName /xsl:call-template custom.xslt中实现getBaseClassName !-- 定义获取基类名方法 --xsl:template namegetBaseClassNamexsl:variable name className xsl:call-template namepascal//xsl:variablexsl:choose xsl:when teststarts-with($className,SC) : SCPacketBase/xsl:whenxsl:when teststarts-with($className,CS) : CSPacketBase/xsl:whenxsl:otherwise /xsl:otherwise/xsl:choose/xsl:template如果SC开头的类增加基类为SCPacketBase服务器给客户端包 如果SC开头的类增加基类为CSPacketBase客户端给服务器包
增加Clear函数
csharp.xslt中增加自定义函数methodClear
xsl:call-template name methodClear /xsl:call-templatecustom.xslt中实现methodClear
!-- 是否显示Clear方法模版 --xsl:template namemethodClearxsl:variable name className xsl:call-template namepascal//xsl:variablexsl:choosexsl:when teststarts-with($className,SC) or starts-with($className,CS) //网络协议Idpublic override int Id { get {return (int)Network.NetMsgID.xsl:value-of select$className/;} } //回到引用池变量设置初始化。如果是引用型成员变量也要回到引用池public override void Clear(){
//xsl:value-of select$className/Clear}/xsl:whenxsl:otherwise//回到引用池变量设置初始化。如果是引用型成员变量也要回到引用池public override void Clear(){
//xsl:value-of select$className/Clear} /xsl:otherwise/xsl:choose/xsl:template协议类CSSC开头类子结构类都是基于引用池需要实现Clear()作用是回到引用池时需要把变量置为初始值这里先写入注释//className等待cs进入unity工程时通过正则再进一步处理 SCCS协议类需要实现协议ID这里对应NetMsgID.txt一一对应例如协议类名为CSLogin那么NetMsgID.txt有条内容为CSLogin 100
正则表达式填充Clear中类成员设置默认值
上一步生成的Clear内容为 public override void Clear(){
//CSLgoin}需要对上一步生成Clear函数内填充内容把类中成员设置为默认值例如CSLogin填充为 public override void Clear(){_account ;_password ;}用正则匹配文本规则添加 1.遍历所有packet.cs文件 2.一个packet.cs文件中匹配类名public partial class (\w) : 一个可能包含1至N个Class。例如包含ClassAClassB 3.提取文件中类名开始到Clear结尾时一个类的部分例如ClassA public static string GetClassContent(string fileContent,string className){string classContent ;string pattern (?s)public partial class className (.*?) className Clear;//(?s)这是一个正则表达式的选项称为“单行”模式single-line mode它使 . 匹配所有字符包括换行符。Debug.Log(pattern);// // 创建正则表达式对象使用 RegexOptions.Multiline 选项Regex regex new Regex(pattern, RegexOptions.Multiline);// 执行匹配Match match regex.Match(fileContent);if (match.Success){classContent match.Groups[1].Value;Debug.Log(match.Groups[1].Value);}return classContent;}4.ClassA中获取private变量进行取的类型默认值进行替换 public static string GetClassMemberClear(string classContent){StringBuilder sbClear new StringBuilder();string pattern private (.*?);;Regex regex new Regex(pattern);// 执行匹配MatchCollection matches regex.Matches(classContent);// 遍历所有匹配项foreach (Match match in matches){// 检查是否有成功的匹配if (match.Success){// 提取匹配的类名捕获组1string sMember match.Groups[1].Value;Debug.Log(找到成员: sMember); //string _account string[] arrMember sMember.Split( );string sType arrMember[0];string sVariant arrMember[1];//非引用池类型string clear ;for (int i 1; i arrMember.Length; i){clear arrMember[i];clear ;}clear clear ; \n;sbClear.Append( clear);}}string sClear sbClear.ToString();Debug.Log($Clear中{sClear});return sClear;}
注意SCCS类已经是引用池类类中间不能再嵌套引用池为类成员
可以使用unity监听导入资源对上一步产生的CS类再加工处理 private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths){if (m_isEnable false){//防止一边导入一边处理又一边导入了return;}m_isEnable false;for (int i 0; i importedAssets.Length; i){string path importedAssets[i];if (path.StartsWith(Assets/GameMain/Scripts/Network/Protobuf/ProtoCS)){//对生成cs类处理clear函数PacketGenClear.GenClear2ProtoCS(path);}}m_isEnable true;}Protoc生成pb二进制文件
使用protoc.exe把.proto生成.pb二进制文件用于lua中加载 基本使用
protoc -o addressbook.pb addressbook.proto遍历文件夹生成.pd到工程目录
var luaProtoFiles new DirectoryInfo(m_protoPathLua).GetFiles(*.proto, SearchOption.AllDirectories);
//遍历所有luaproto
foreach (var f in luaProtoFiles)
{string fileName f.Name.Replace(.proto, );//生成pb{string sIn proto/Lua/ f.Name;string spbFullName m_pbPath fileName .pb;string sOut -o spbFullName;string sCmd protocPath sOut sIn;p.StandardInput.WriteLine(sCmd);}m_sbProtoList.AppendLine(fileName);
}生成pd列表文件
File.WriteAllText(m_protoListFullName, m_sbProtoList.ToString());执行效果 生成cs类
[global::System.Serializable, global::ProtoBuf.ProtoContract(NameCSLogin)]
public partial class CSLogin : CSPacketBase
{
public CSLogin() {}private string _account ;
[global::ProtoBuf.ProtoMember(1, IsRequired false, Nameaccount, DataFormat global::ProtoBuf.DataFormat.Default)]
[global::System.ComponentModel.DefaultValue()]
public string account
{get { return _account; }set { _account value; }
}private string _password ;
[global::ProtoBuf.ProtoMember(2, IsRequired false, Namepassword, DataFormat global::ProtoBuf.DataFormat.Default)]
[global::System.ComponentModel.DefaultValue()]
public string password
{get { return _password; }set { _password value; }
} //网络协议Idpublic override int Id { get {return (int)Network.NetMsgID.CSLogin;} } //回到引用池变量设置初始化。如果是引用型成员变量也要回到引用池public override void Clear(){_account ;_password ;}}生成CSpd流程图