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;
}
}
}