协议(消息)配置
什么是协议生成工具
//协议生成工具 一般值消息(协议)生成工具
//就是专门用于自动化生成消息的程序
//我们之前学习了:
//1.消息的序列化和反序列化
//2.区分消息类型
//3.分包黏包
//等等关于消息的知识
// 当需要一个新消息时,我们需要手动的按照规则去声明新的类
// 这部分工作费时又费力,技术含量也不高
// 如果前后端是统一的语言,我们按照语法声明一次就行
// 但是如果前后端语言不统一,比如前端用 C#,后端用 C++ 或者 Java
// 那么前后端分开去声明,也容易造成沟通不一致,声明不统一的问题
// 所以如果靠我们手动的去声明消息类
// 是一件费时、费力、还容易出问题的事情
// 所以我们在商业游戏开发时,往往就需要使用协议生成工具
// 来帮助我们自动化的声明消息类
// 这样做的好处是:
//1. 提升开发效率
//2. 降低沟通成本,避免前后端消息不匹配的问题
如何制作协议生成工具
// 要制作工具,首先要确定需求
// 对于协议生成工具来说,主要需求如下
//1. 通过配置文件配置消息或数据类 名字、变量等
//2. 工具根据该配置文件信息动态的生成 类文件(脚本文件,代码是自动生成)
//3. 我们可以在开发中直接使用生成文件中声明好的消息和数据结构类进行开发
// 根据需求分析,我们需要做
//1. 确定协议配置方式
// 可以使用 json、xml、自定义格式进行协议配置
// 主要目的,是通过配置文件确定
// 1: 消息或者数据结构类名字
// 2: 字段名等
//2. 确定生成格式
// 最终我们是要自动生成类声明文件
// 所以具体类应该如何生成需要确定格式
// 比如:
// 继承关系 固定写法
// 序列化、反序列化 固定写法
// 提取出共同点
//3. 制作生成工具
// 基于配置文件 和 生成格式 动态的生成对应类文件
总结:
// 制作协议生成工具的目的是一劳永逸
// 制作完成后
// 它可以提升开发效率,避免协议不统一等问题
// 之后多了不同的语言,按照规则进行编写即可
选择哪种格式配置协议
//1.xml
//2.json
//3.excel
//4. 自定义
// 等等
// 我们可以根据自己的喜好选择
// 选择方便配置的,好用即可
// 配置的主要目的是确定
// 类名、成员变量名
// 之后根据读取的这些配置信息
// 再通过代码按照规则自动生成对应的类文件
// 我个人喜欢使用 xml 作为协议配置文件
// 学会 xml 配置,其它的方式都是大同小异的
// 我们主要是学习制作思路和流程
// 以后的项目中,大家根据自己的喜好选择即可
以xml配置为例--制定配置规则
//xml 相关知识,可以在数据持久化之 xml 中进行学习
//1. 创建 xml 配置文件
//2. 制定配置规则
// 1. 枚举规则
// 2. 数据类规则
// 3. 消息类规则
制作xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<messages><!--枚举配置规则--><enum name="E_PLAYER_TYPE" namespace="GamePlayer"><field name="MAIN">1</field><field name="OTHER"/></enum> <enum name="E_MONSTER_TYPE" namespace="GameMonster"><field name="NORMAL">2</field><field name="BOSS"/></enum> <!--数据结构类配置规则--><data name="PlayerData" namespace="GamePlayer"><field type="int" name="id"/><field type="float" name="atk"/><field type="bool" name="sex"/><field type="long" name="lev"/><field type="array" name="arrays"/><field type="list" T="int" name="list"/><field type="dic" Tkey="int" Tvalue="string" name="dic"/> </data><!--消息类配置规则--><message id="1001" name="PlayerMsg" namespace="GamePlayer"><field type="int" name="playerID"/><field type="PlayerData" name="data"/></message><message id="1002" name="HeartMsg" namespace="GameSystem"/>
</messages>
根据xml文件读取配置信息
//1. 读取 xml 文件信息XmlDocument xml = new XmlDocument();xml.Load(Application.dataPath + "/Scripts/协议配置/Lesson37.xml");//2. 读取各节点元素//2-1: 根节点读取XmlNode root = xml.SelectSingleNode("messages");//2-2: 读取出所有枚举结构类节点XmlNodeList enumList = root.SelectNodes("enum");foreach (XmlNode enumNode in enumList){print("*****************");print("********枚举*******");print("枚举名字" + enumNode.Attributes["name"].Value);print("枚举所在命名空间" + enumNode.Attributes["namespace"].Value);print("******枚举成员*******");XmlNodeList fields = enumNode.SelectNodes("field");foreach (XmlNode field in fields){string str = field.Attributes["name"].Value;if (field.InnerText != "")str += "=" + field.InnerText;str += ",";print(str);}}//2-3: 读取出所有数据结构类节点XmlNodeList dataList = root.SelectNodes("data");foreach (XmlNode data in dataList){print("*****************");print("********数据结构类*******");print("数据类名" + data.Attributes["name"].Value);print("数据类所在命名空间" + data.Attributes["namespace"].Value);print("******数据类成员*******");XmlNodeList fields = data.SelectNodes("field");foreach (XmlNode field in fields){print(field.Attributes["type"].Value + " " + field.Attributes["name"].Value + ";");}}//2-4: 读取出所有消息节点XmlNodeList msgList = root.SelectNodes("message");foreach (XmlNode msg in msgList){print("*****************");print("********消息类*******");print("消息类名" + msg.Attributes["name"].Value);print("消息类所在命名空间" + msg.Attributes["namespace"].Value);print("消息ID" + msg.Attributes["id"].Value);print("******消息类成员*******");XmlNodeList fields = msg.SelectNodes("field");foreach (XmlNode field in fields){print(field.Attributes["type"].Value + " " + field.Attributes["name"].Value + ";");}}
总结:
// 利用配置文件配置消息、数据结构、枚举的目的
//1. 减少工作量,配置一次,之后自动化生成各种语言对应的类文件
//2. 减少沟通成本,避免前后端语言不同时,手动写代码出现前后端不统一的问题