Exemplo n.º 1
0
    //解析服务器返回的数据包,步骤如下:
    //1、把包头长度去掉
    //2、CRC校验,
    //3、检查压缩标志,先校验CRC再解压,因为打包时的CRC就是压缩后的值
    //4、使用异或算法得到真实包体
    //5、通过解析协议编号,派发对应的委托
    void Update()
    {
        while (true)
        {
            if (mReceiveCount <= 3)
            {
                mReceiveCount++;
                lock (mReceiveQueue)
                {
                    if (mReceiveQueue.Count > 0)
                    {
                        byte[] buffer     = mReceiveQueue.Dequeue();     //取一个服务器返回的未处理的数据包
                        byte[] dataBody   = new byte[buffer.Length - 3]; //获取数据包包体,未解压(压缩标志+CRC一共3字节,包头部分在数据传过来的之前就处理掉了)
                        bool   isCompress = false;                       //压缩标志
                        ushort CRC        = 0;                           //CRC校验码
                        ushort protoCode  = 0;                           //协议编号

                        using (MemoryStreamUtil stream = new MemoryStreamUtil(buffer))
                        {
                            isCompress = stream.ReadBool();
                            CRC        = stream.ReadUShort();
                            stream.Read(dataBody, 0, dataBody.Length);
                        }
                        ushort newCRC = Crc16.CalculateCrc16(dataBody);
                        if (CRC == newCRC)
                        {
                            if (isCompress)
                            {
                                dataBody = ZlibHelper.DeCompressBytes(dataBody); //解压
                            }
                            dataBody = SecurityUtil.XorAlgorithm(dataBody);      //解密
                        }
                        else
                        {
                            Debug.Log("client:CRC验证失败!");
                            break;
                        }
                        //开始解析原始真实数据
                        byte[] protoContent = new byte[dataBody.Length - 2];   //协议内容,减去协议编号
                        using (MemoryStreamUtil stream = new MemoryStreamUtil(dataBody))
                        {
                            protoCode = stream.ReadUShort();
                            //这里开始使用观察者派发协议
                            stream.Read(protoContent, 0, protoContent.Length);
                            SocketDispatcher.Instance.Dispatch(protoCode, protoContent);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            else
            {
                mReceiveCount = 0;
                break;
            }
        }
    }
Exemplo n.º 2
0
    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="path"></param>
    public GameDataTableParser(string path)
    {
        m_FieldNameDic = new Dictionary <string, int>();

        //------------------
        //第1步:读取文件
        //------------------

        /* 48课以后读取AB资源时使用新写法
         * using (FileStream fs = new FileStream(path, FileMode.Open))
         * {
         *  buffer = new byte[fs.Length];
         *  fs.Read(buffer, 0, buffer.Length);
         * }
         */
        byte[] buffer = LocalFileManager.Instance.GetBuffer(path);
        //------------------
        //第2步:解压缩
        //------------------
        buffer = ZlibHelper.DeCompressBytes(buffer);

        //------------------
        //第3步:xor解密
        //43课以后将其移动到Leo_SecurityUtil中
        //------------------
        buffer = SecurityUtil.XorAlgorithm(buffer);

        //------------------
        //第4步:解析数据到数组
        //------------------
        using (MemoryStreamUtil ms = new MemoryStreamUtil(buffer))
        {
            m_Row    = ms.ReadInt();
            m_Column = ms.ReadInt();

            m_GameData  = new String[m_Row, m_Column];
            m_FieldName = new string[m_Column];

            for (int i = 0; i < m_Row; i++)
            {
                for (int j = 0; j < m_Column; j++)
                {
                    string str = ms.ReadUTF8String();

                    if (i == 0)
                    {
                        //表示读取的是字段
                        m_FieldName[j]      = str;
                        m_FieldNameDic[str] = j;
                    }
                    else if (i > 2)
                    {
                        //表示读取的是内容
                        m_GameData[i, j] = str;
                    }
                }
            }
        }
    }
    public static Account_RoleInfoRespProto GetProto(byte[] buffer)
    {
        Account_RoleInfoRespProto proto = new Account_RoleInfoRespProto();

        using (MemoryStreamUtil ms = new MemoryStreamUtil(buffer))
        {
            proto.IsSuccess = ms.ReadBool();
            if (proto.IsSuccess)
            {
                proto.RoldId           = ms.ReadInt();
                proto.RoleNickName     = ms.ReadUTF8String();
                proto.ClassId          = (byte)ms.ReadByte();
                proto.Level            = ms.ReadInt();
                proto.VIPLevel         = ms.ReadInt();
                proto.TotalRechargeGem = ms.ReadInt();
                proto.Gem                   = ms.ReadInt();
                proto.Gold                  = ms.ReadInt();
                proto.CurrEnergy            = ms.ReadInt();
                proto.MaxEnergy             = ms.ReadInt();
                proto.Exp                   = ms.ReadInt();
                proto.MaxHP                 = ms.ReadInt();
                proto.MaxMP                 = ms.ReadInt();
                proto.CurrHP                = ms.ReadInt();
                proto.CurrMP                = ms.ReadInt();
                proto.Attack                = ms.ReadInt();
                proto.Defense               = ms.ReadInt();
                proto.Hit                   = ms.ReadInt();
                proto.Dodge                 = ms.ReadInt();
                proto.Cri                   = ms.ReadInt();
                proto.Res                   = ms.ReadInt();
                proto.SumDPS                = ms.ReadInt();
                proto.LastPassGameQuestId   = ms.ReadInt();
                proto.LastInWorldMapId      = ms.ReadInt();
                proto.LastInWorldMapPos     = ms.ReadUTF8String();
                proto.Equip_Weapon          = ms.ReadInt();
                proto.Equip_Pants           = ms.ReadInt();
                proto.Equip_Clothes         = ms.ReadInt();
                proto.Equip_Belt            = ms.ReadInt();
                proto.Equip_Cuff            = ms.ReadInt();
                proto.Equip_Necklace        = ms.ReadInt();
                proto.Equip_Shoe            = ms.ReadInt();
                proto.Equip_Ring            = ms.ReadInt();
                proto.Equip_WeaponTableId   = ms.ReadInt();
                proto.Equip_PantsTableId    = ms.ReadInt();
                proto.Equip_ClothesTableId  = ms.ReadInt();
                proto.Equip_BeltTableId     = ms.ReadInt();
                proto.Equip_CuffTableId     = ms.ReadInt();
                proto.Equip_NecklaceTableId = ms.ReadInt();
                proto.Equip_ShoeTableId     = ms.ReadInt();
                proto.Equip_RingTableId     = ms.ReadInt();
            }
            else
            {
                proto.MsgCode = ms.ReadInt();
            }
        }
        return(proto);
    }
Exemplo n.º 4
0
    public int    RoldId; //角色编号

    public byte[] ToArray()
    {
        using (MemoryStreamUtil ms = new MemoryStreamUtil())
        {
            ms.WriteUShort(ProtoCode);
            ms.WriteInt(RoldId);
            return(ms.ToArray());
        }
    }
    public int    Equip_RingTableId;     //穿戴戒指

    public byte[] ToArray()
    {
        using (MemoryStreamUtil ms = new MemoryStreamUtil())
        {
            ms.WriteUShort(ProtoCode);
            ms.WriteBool(IsSuccess);
            if (IsSuccess)
            {
                ms.WriteInt(RoldId);
                ms.WriteUTF8String(RoleNickName);
                ms.WriteByte(ClassId);
                ms.WriteInt(Level);
                ms.WriteInt(VIPLevel);
                ms.WriteInt(TotalRechargeGem);
                ms.WriteInt(Gem);
                ms.WriteInt(Gold);
                ms.WriteInt(CurrEnergy);
                ms.WriteInt(MaxEnergy);
                ms.WriteInt(Exp);
                ms.WriteInt(MaxHP);
                ms.WriteInt(MaxMP);
                ms.WriteInt(CurrHP);
                ms.WriteInt(CurrMP);
                ms.WriteInt(Attack);
                ms.WriteInt(Defense);
                ms.WriteInt(Hit);
                ms.WriteInt(Dodge);
                ms.WriteInt(Cri);
                ms.WriteInt(Res);
                ms.WriteInt(SumDPS);
                ms.WriteInt(LastPassGameQuestId);
                ms.WriteInt(LastInWorldMapId);
                ms.WriteUTF8String(LastInWorldMapPos);
                ms.WriteInt(Equip_Weapon);
                ms.WriteInt(Equip_Pants);
                ms.WriteInt(Equip_Clothes);
                ms.WriteInt(Equip_Belt);
                ms.WriteInt(Equip_Cuff);
                ms.WriteInt(Equip_Necklace);
                ms.WriteInt(Equip_Shoe);
                ms.WriteInt(Equip_Ring);
                ms.WriteInt(Equip_WeaponTableId);
                ms.WriteInt(Equip_PantsTableId);
                ms.WriteInt(Equip_ClothesTableId);
                ms.WriteInt(Equip_BeltTableId);
                ms.WriteInt(Equip_CuffTableId);
                ms.WriteInt(Equip_NecklaceTableId);
                ms.WriteInt(Equip_ShoeTableId);
                ms.WriteInt(Equip_RingTableId);
            }
            else
            {
                ms.WriteInt(MsgCode);
            }
            return(ms.ToArray());
        }
    }
    public int    GameServerId; //区服ID

    public byte[] ToArray()
    {
        using (MemoryStreamUtil ms = new MemoryStreamUtil())
        {
            ms.WriteUShort(ProtoCode);
            ms.WriteInt(AccountId);
            ms.WriteInt(GameServerId);
            return(ms.ToArray());
        }
    }
Exemplo n.º 7
0
    public static Account_RoleInfoReqProto GetProto(byte[] buffer)
    {
        Account_RoleInfoReqProto proto = new Account_RoleInfoReqProto();

        using (MemoryStreamUtil ms = new MemoryStreamUtil(buffer))
        {
            proto.RoldId = ms.ReadInt();
        }
        return(proto);
    }
    public static Account_LoginGameServerReqProto GetProto(byte[] buffer)
    {
        Account_LoginGameServerReqProto proto = new Account_LoginGameServerReqProto();

        using (MemoryStreamUtil ms = new MemoryStreamUtil(buffer))
        {
            proto.AccountId    = ms.ReadInt();
            proto.GameServerId = ms.ReadInt();
        }
        return(proto);
    }
    public static Account_EnterGameReqProto GetProto(byte[] buffer)
    {
        Account_EnterGameReqProto proto = new Account_EnterGameReqProto();

        using (MemoryStreamUtil ms = new MemoryStreamUtil(buffer))
        {
            proto.RoleId    = ms.ReadInt();
            proto.ChannelId = ms.ReadInt();
        }
        return(proto);
    }
Exemplo n.º 10
0
    public int    GameServerId; //角色所在区服ID

    public byte[] ToArray()
    {
        using (MemoryStreamUtil ms = new MemoryStreamUtil())
        {
            ms.WriteUShort(ProtoCode);
            ms.WriteByte(ClassId);
            ms.WriteUTF8String(RoleNickName);
            ms.WriteInt(GameServerId);
            return(ms.ToArray());
        }
    }
Exemplo n.º 11
0
    public static Account_AddRoleReqProto GetProto(byte[] buffer)
    {
        Account_AddRoleReqProto proto = new Account_AddRoleReqProto();

        using (MemoryStreamUtil ms = new MemoryStreamUtil(buffer))
        {
            proto.ClassId      = (byte)ms.ReadByte();
            proto.RoleNickName = ms.ReadUTF8String();
            proto.GameServerId = ms.ReadInt();
        }
        return(proto);
    }
    public int    MsgCode;   //消息码

    public byte[] ToArray()
    {
        using (MemoryStreamUtil ms = new MemoryStreamUtil())
        {
            ms.WriteUShort(ProtoCode);
            ms.WriteBool(IsSuccess);
            if (!IsSuccess)
            {
                ms.WriteInt(MsgCode);
            }
            return(ms.ToArray());
        }
    }
    public static Account_DeleteRoleRespProto GetProto(byte[] buffer)
    {
        Account_DeleteRoleRespProto proto = new Account_DeleteRoleRespProto();

        using (MemoryStreamUtil ms = new MemoryStreamUtil(buffer))
        {
            proto.IsSuccess = ms.ReadBool();
            if (!proto.IsSuccess)
            {
                proto.MsgCode = ms.ReadInt();
            }
        }
        return(proto);
    }
 public byte[] ToArray()
 {
     using (MemoryStreamUtil ms = new MemoryStreamUtil())
     {
         ms.WriteUShort(ProtoCode);
         ms.WriteInt(RoleCount);
         for (int i = 0; i < RoleCount; i++)
         {
             ms.WriteInt(RoleList[i].RoleId);
             ms.WriteUTF8String(RoleList[i].RoleNickName);
             ms.WriteByte(RoleList[i].RoleClass);
             ms.WriteInt(RoleList[i].RoleLevel);
         }
         return(ms.ToArray());
     }
 }
    public static Account_LoginGameServerRespProto GetProto(byte[] buffer)
    {
        Account_LoginGameServerRespProto proto = new Account_LoginGameServerRespProto();

        using (MemoryStreamUtil ms = new MemoryStreamUtil(buffer))
        {
            proto.RoleCount = ms.ReadInt();
            proto.RoleList  = new List <RoleItem>();
            for (int i = 0; i < proto.RoleCount; i++)
            {
                RoleItem _Role = new RoleItem();
                _Role.RoleId       = ms.ReadInt();
                _Role.RoleNickName = ms.ReadUTF8String();
                _Role.RoleClass    = (byte)ms.ReadByte();
                _Role.RoleLevel    = ms.ReadInt();
                proto.RoleList.Add(_Role);
            }
        }
        return(proto);
    }
Exemplo n.º 16
0
    /// <summary>
    /// 制作一个数据包,该数据包是符合传给服务器的格式的(包头+包体)
    /// 当前工程的格式是包头:包体长度,包体:压缩标志+CRC校验码+加密的真正数据(异或算法)(协议编码+协议内容)
    /// 把private改为public,配合本机模式本地测试用
    /// </summary>
    /// <param name="data">真实数据</param>
    /// <returns></returns>
    public byte[] MakeDataPkg(byte[] data)
    {
        byte[] returnBuffer = null;
        data = SecurityUtil.XorAlgorithm(data);           //1、加密
        bool isCompress = data.Length > mCompressMinSize; //2、压缩

        if (isCompress)
        {
            //开始压缩
            data = ZlibHelper.CompressBytes(data);
        }
        ushort crc16 = Crc16.CalculateCrc16(data);  //3、CRC校验

        using (MemoryStreamUtil stream = new MemoryStreamUtil())
        {
            stream.WriteUShort((ushort)(data.Length + 3)); //写包头,+3是因为多了一个bool,一个ushort,一共3字节
            stream.WriteBool(isCompress);                  //写压缩标志
            stream.WriteUShort(crc16);                     //写CRC
            stream.Write(data, 0, data.Length);            //写加密后的真实数据
            returnBuffer = stream.ToArray();
        }
        Debug.Log("数据包构建完毕!");
        return(returnBuffer);
    }
Exemplo n.º 17
0
    /// <summary>
    /// 模拟要点:解客户端数据包,同时向正式代码模拟发送服务端数据包
    /// 41课以后包体结构更复杂,包体=协议编号+协议内容
    /// 43课以后数据包完全体为:包体=压缩标志+CRC校验码+异或算法后的真实数据(协议编号+协议内容)
    /// </summary>
    /// <param name="dataPkg">本地向服务器传什么数据</param>
    /// <param name="isDIYReturnMsg">是否由客户端决定服务器返回什么数据,默认为false,就是由服务端通过逻辑处理后返回一个伪真实的数据,如果为true,就是一个由客户端决定的纯伪造的数据</param>
    /// <param name="returnPkg">希望服务器向本地传什么数据</param>
    public void ServerOperator(byte[] dataPkg, bool isDIYReturnPkg = false)
    {
        if (isDIYReturnPkg == true)  //向客户端返回的是客户端指定的数据包,不必再做下列处理
        {
            return;
        }
        mReceiveStream.Position = mReceiveStream.Length;
        mReceiveStream.Write(dataPkg, 0, dataPkg.Length);        //数据写进内存,等待操作
        mReceiveStream.Position = 0;
        int currentMsgLen  = mReceiveStream.ReadUShort();        //包体长度
        int currentFullLen = 2 + currentMsgLen;                  //包头+包体长度

        if (mReceiveStream.Length >= currentFullLen)             //接收的数据包大于一个完整包的长度,表示至少有一个完整包传过来了
        {
            byte[] buffer = new byte[currentMsgLen];             //此buffer为数据包,包体内容
            mReceiveStream.Position = 2;                         //把包头去掉,剩下包体
            mReceiveStream.Read(buffer, 0, currentMsgLen);       //把数据读到buffer中
            #region 43课以后完整版数据包增加以下内容
            ushort CRC            = 0;                           //CRC校验码
            bool   isCompress     = false;                       //压缩标志
            byte[] realDataBuffer = new byte[buffer.Length - 3]; //刨除CRC和压缩标志,真正数据部分
            using (MemoryStreamUtil stream = new MemoryStreamUtil(buffer))
            {
                isCompress = stream.ReadBool();   //获取压缩标志
                CRC        = stream.ReadUShort(); //获取CRC校验码
                stream.Read(realDataBuffer, 0, realDataBuffer.Length);
            }
            ushort newCRC = Crc16.CalculateCrc16(realDataBuffer); //开始校验CRC
            if (CRC == newCRC)                                    //校验通过
            {
                if (isCompress)
                {
                    realDataBuffer = ZlibHelper.DeCompressBytes(realDataBuffer); //解压
                }
                realDataBuffer = SecurityUtil.XorAlgorithm(realDataBuffer);      //解密,此时realDataBuffer是可以操作的数据
            }
            else
            {
                Debug.Log("server:CRC verify failed!");
                return;
            }

            #endregion
            #region 41课以后服务器增加以下内容
            ushort protoCode    = 0;
            byte[] protoContent = new byte[realDataBuffer.Length - 2];  //可操作数据buffer减去协议编号部分
            #endregion
            using (MemoryStreamUtil stream = new MemoryStreamUtil(realDataBuffer))
            {
                protoCode = stream.ReadUShort();
                stream.Read(protoContent, 0, protoContent.Length);
                SocketDispatcher.Instance.Dispatch(protoCode, protoContent);
                //EventDispatcherS.Instance.Dispatch(protoCode, null, protoContent);
            }
            //41课以后使用网络协议,增加此部分判断逻辑
            //43课以后使用观察者模式
            //此处作为模拟器不使用观察者模式,采用模拟数据的方式简易处理

            /*
             * if (protoCode == Leo_ProtoCodeDefine.RoleOperation_Login)
             * {
             *  Leo_ProtoTest test = Leo_ProtoTest.ToObject(protoContent);
             *  Debug.Log("服务器解析协议成功,协议编号:" + protoCode);
             *  Debug.Log("ID:" + test.ID);
             *  Debug.Log("name:" + test.name);
             *  Leo_ProtoTest testReturn = new Leo_ProtoTest();
             *  testReturn.protoCode = Leo_ProtoCodeDefine.RoleOperation_Login;
             *  testReturn.ID = 2002;
             *  testReturn.name = "return";
             *  testReturn.price = 2.22f;
             *  byte[] returnBuffer = Leo_SocketManager.Instance.MakeDataPkg(testReturn.ToArray()); //模拟服务器向客户端返回一条协议数据
             * }
             * */
            //Leo_SocketDispatcher.Instance.Dispatch(protoCode, protoContent);
        }
        else
        {
            Debug.Log("服务器解析数据包错误!");
        }
        //2020-06-25新增,一次接收结束后把stream里的内容清空,保证下次接收的内容是新的
        mReceiveStream.Position = 0;
        mReceiveStream.SetLength(0);
    }
Exemplo n.º 18
0
    private void ReceiveCallback(IAsyncResult result)
    {
        try
        {
            int len = client.EndReceive(result);
            if (len > 0)    //接收到数据了
            {
                mReceiveStream.Position = mReceiveStream.Length;
                mReceiveStream.Write(mReceiveBuffer, 0, mReceiveBuffer.Length); //数据写进内存,等待操作
                //根据我们自定义数据包的格式,大于2字节代表有一个包传过来了
                if (mReceiveStream.Length > 2)
                {
                    while (true)
                    {
                        mReceiveStream.Position = 0;
                        int currentMsgLen  = mReceiveStream.ReadUShort(); //包体长度
                        int currentFullLen = 2 + currentMsgLen;           //包头+包体长度
                        if (mReceiveStream.Length >= currentFullLen)      //接收的数据包大于一个完整包的长度,表示至少有一个完整包传过来了
                        {
                            byte[] buffer = new byte[currentMsgLen];      //此buffer为真实数据

                            mReceiveStream.Position = 2;                  //根据我们自定义的数据包格式,刨除前2位,后面的是真实数据
                            mReceiveStream.Read(buffer, 0, currentMsgLen);
                            lock (mReceiveQueue)
                            {
                                mReceiveQueue.Enqueue(buffer);      //加入接收队列中
                            }

                            using (MemoryStreamUtil stream = new MemoryStreamUtil())
                            {
                                string data = stream.ReadUTF8String();  //
                                Debug.Log("data:" + data);
                            }

                            //上面是一个完整数据包处理过程,下面是本次接收多余的数据进行处理
                            int remainLen = (int)mReceiveStream.Length - currentFullLen;
                            if (remainLen > 0)  //本次接收的数据大于一个完整包时
                            {
                                mReceiveStream.Position = currentFullLen;
                                byte[] remainBuffer = new byte[remainLen];
                                mReceiveStream.Read(remainBuffer, 0, remainLen);    //把剩余所有数据读进内存

                                //把流中数据清空
                                mReceiveStream.Position = 0;
                                mReceiveStream.SetLength(0);

                                mReceiveStream.Write(remainBuffer, 0, remainBuffer.Length);
                                remainBuffer = null;
                            }
                            else
                            {
                                //把流中数据清空
                                mReceiveStream.Position = 0;
                                mReceiveStream.SetLength(0);
                                break;
                            }
                        }
                        else
                        {
                            //还没收到完整包
                            break;
                        }
                    }
                }
                ReceiveMessage();
            }
            else
            {
                Debug.Log("断开连接else");
            }
        }
        catch (Exception e)
        {
            Debug.Log(e.Message);
            Debug.Log("断开连接catch");
        }
    }