using UnityEngine; using System.Collections; using System; using System.Reflection; namespace Engine.Net { /// 消息对象 public class NetMsg { /// 创建一个NetMsg对象 public static NetMsg OnCreateNetMsg(int msgCode = 0) { return new NetMsg(msgCode); } /// 创建一个NetMsg对象 public static NetMsg OnCreateNetMsg(byte[] bytes) { return new NetMsg(bytes); } /// 接受消息的最大长度 public const int MAX_MSG_LEN = 81920; /// 消息的固定最小长度 public const int MIN_MSG_LEN = 12; /// 消息内容长度 public int nBodyLeng = 0; /// 消息编号 public int nCode = 0; public int UserId = -1; /// 消息时序 public short nSequence = 0; /// 消息内容 public NetBytes arrData = null; /// 读取位置 protected int nPos; public NetMsg() { arrData = new NetBytes(); } public NetMsg(int msgCode) { nCode = msgCode; arrData = new NetBytes(); } public NetMsg(byte[] bytes) { arrData = new NetBytes(bytes); } // 解包参数 public virtual void UnPackMsg(ref T x) { Type t = x.GetType(); FieldInfo[] fields = t.GetFields(); foreach (FieldInfo f in fields) { if (f.FieldType == typeof(int)) { f.SetValue(x, arrData.ReadInt()); } else if (f.FieldType == typeof(short)) { f.SetValue(x, arrData.ReadShort()); } else if (f.FieldType == typeof(byte)) { f.SetValue(x, arrData.ReadByte()); } else if (f.FieldType == typeof(byte[])) { f.SetValue(x, arrData.ReadByteArray()); } else if (f.FieldType == typeof(bool)) { f.SetValue(x, arrData.ReadBool()); } else if (f.FieldType == typeof(float)) { f.SetValue(x, arrData.ReadFloat()); } else if (f.FieldType == typeof(Vector3)) { f.SetValue(x, arrData.ReadVector3()); } else if (f.FieldType == typeof(string)) { f.SetValue(x, arrData.ReadString().Replace("\0", ""));//标准化; } else if(f.FieldType == typeof(char[])) { f.SetValue(x, arrData.ReadChars()); } } } // 封装参数 public virtual void PackMsg(T x) { Type t = x.GetType(); FieldInfo[] fields = t.GetFields(); foreach (FieldInfo f in fields) { if (f.FieldType == typeof(int)) { arrData.WriteInt((int)f.GetValue(x)); } else if (f.FieldType == typeof(short)) { arrData.WriteShort((short)f.GetValue(x)); } else if (f.FieldType == typeof(byte)) { arrData.WriteByte((byte)f.GetValue(x)); } else if (f.FieldType == typeof(byte[])) { arrData.WriteByteArray((byte[])f.GetValue(x)); } else if (f.FieldType == typeof(bool)) { arrData.WriteBool((bool)f.GetValue(x)); } else if (f.FieldType == typeof(float)) { arrData.WriteFloat((float)f.GetValue(x)); } else if (f.FieldType == typeof(Vector3)) { arrData.WriteVector3((Vector3)f.GetValue(x)); } else if (f.FieldType == typeof(string)) { arrData.WriteString((string)f.GetValue(x), 20); } else if (f.FieldType == typeof(char[])) { arrData.WriteChars((char[])f.GetValue(x)); } else { //CDebug.Log("打包数组参数" + f.FieldType); if (f.FieldType.IsArray) { System.Object[] datas = (System.Object[])f.GetValue(x); for(int i=0; i< datas.Length; i++) { PackMsg(datas[i]); } } } } } /// 读取消息 public virtual bool ReadMessage(byte[] buff, int nMsgSize) { if (buff != null) { if(nMsgSize< MIN_MSG_LEN) { return false; } //读取连接ID nCode = arrData.ReadInt(); //读取用户id UserId = arrData.ReadInt(); //消息包内容长度 nBodyLeng = nMsgSize - MIN_MSG_LEN; if (nBodyLeng > MAX_MSG_LEN) { return false; } else { if (nBodyLeng <= 0) { return true; } //拷贝消息数据 arrData.Data = new byte[nBodyLeng]; Array.Copy(buff, MIN_MSG_LEN, arrData.Data, 0, nBodyLeng); arrData.Position = 0; return true; } } else { return false; } } /// 消息打包 public virtual byte[] FastPackMsg() { int packageSize = arrData.Length + MIN_MSG_LEN; NetBytes netBytes = new NetBytes(); // 写入总长度 netBytes.WriteInt(packageSize); // 写入消息号 netBytes.WriteInt(nCode); // 写入用户id netBytes.WriteInt(UserId); // 写入其他数据 if (arrData.Length > 0) netBytes.WriteBytes(arrData.Data, false); return netBytes.Data; } /// 确保消息长度不会溢出 private bool EnsureCap(int nCap) { if (arrData != null && arrData.Length >= nCap) return true; if (nCap > MAX_MSG_LEN) return false; int nCurSize = arrData == null ? 0 : arrData.Length; int nNewSize = Mathf.Max(nCurSize * 2, nCap); nNewSize = Mathf.Min(nNewSize, MAX_MSG_LEN); if (arrData == null) { arrData = new NetBytes(new byte[nNewSize]); } else { byte[] arrBytes = null; Array.Resize(ref arrBytes, nNewSize); arrData.Data = arrBytes; arrData.Position = 0; } return true; } } }