public override void Handle(object sender, Packet packet) { GameMessage gameMessage = (GameMessage)packet; int frameIndex = gameMessage.Frame; List <Packet> list = new List <Packet>(); Command[] comm = new Command[gameMessage.Command.Count]; gameMessage.Command.CopyTo(comm, 0); // comm 是一帧中的所有事件的帧命令数据 for (int i = 0; i < comm.Length; i++) { if (comm[i].Type != -1) { using (MemoryStream stream = new MemoryStream()) { byte[] data = comm[i].Data.ToByteArray(); stream.Write(data, 0, data.Length); stream.Position = 0; //Debug.Log(stream.Length); Type packetType = NetworkChannelHelper.GetAllPacketType(comm[i].Type); object instance = Activator.CreateInstance(packetType); Packet framePacket = (Packet)ProtobufHelper.FromStream(instance, stream); list.Add(framePacket); // list是一帧的所有数据包命令 } } } // 将帧数据保存下来 //Debug.Log("AddOneFrame ---- frameIndex: " + frameIndex); GameEntry.LockManager.AddOneFrame(frameIndex, list); }
// // 摘要: // 序列化消息包。 // // 参数: // packet: // 要序列化的消息包。 // // destination: // 要序列化的目标流。 // // 类型参数: // T: // 消息包类型。 // // 返回结果: // 是否序列化成功。 public bool Serialize <T>(T packet, Stream destination) where T : Packet { PacketBase packetImpl = packet as PacketBase; if (packetImpl == null) { Log.Warning("Packet is invalid."); return(false); } if (packetImpl.PacketType != PacketType.ClientToServer) { Log.Warning("Send packet invalid."); return(false); } // 恐怖的 GCAlloc,这里是例子,不做优化(这句注释是框架作者写的,我本人并不懂GC什么的) /* 以下内容为木头本人做的改动,不知道是否有错误的地方(虽然它运行起来是正确的),希望大家能帮忙指正 */ // 因为头部消息有8字节长度,所以先跳过8字节 using (MemoryStream memoryStream = new MemoryStream()) { memoryStream.SetLength(memoryStream.Capacity); // 此行防止 Array.Copy 的数据无法写入 memoryStream.Position = 8; ProtobufHelper.ToStream(packet, memoryStream); //Serializer.SerializeWithLengthPrefix<T>(m_CachedStream, packet, PrefixStyle.Fixed32); //Serializer.Serialize(m_CachedStream, packet); // // 头部消息 //CSPacketHeader packetHeader = ReferencePool.Acquire<CSPacketHeader>(); memoryStream.Position = 0; int mid = packet.Id; int length = (int)memoryStream.Length - 4; // 消息内容长度需要减去头部消息长度 byte[] midData = BitConverter.GetBytes(mid); byte[] lenData = BitConverter.GetBytes(length); //反转 Array.Reverse(midData); Array.Reverse(lenData); memoryStream.Write(lenData, 0, 4); memoryStream.Position = 4; memoryStream.Write(midData, 0, 4); //Serializer.SerializeWithLengthPrefix(m_CachedStream, packetHeader, PrefixStyle.Fixed32BigEndian); //ReferencePool.Release(packetHeader); memoryStream.WriteTo(destination); } //Debug.Log("msgSend"); return(true); }
/// <summary> /// 反序列化消息包。 /// </summary> /// <param name="packetHeader">消息包头。</param> /// <param name="source">要反序列化的来源流。</param> /// <param name="customErrorData">用户自定义错误数据。</param> /// <returns>反序列化后的消息包。</returns> public Packet DeserializePacket(IPacketHeader packetHeader, Stream source, out object customErrorData) { // 注意:此函数并不在主线程调用! customErrorData = null; SCPacketHeader scPacketHeader = packetHeader as SCPacketHeader; if (scPacketHeader == null) { Log.Warning("Packet header is invalid."); return(null); } Packet packet = null; if (scPacketHeader.IsValid) { Type packetType = GetServerToClientPacketType(scPacketHeader.Id); if (packetType != null && source is MemoryStream) { //packet = (Packet)RuntimeTypeModel.Default.DeserializeWithLengthPrefix(source, ReferencePool.Acquire(packetType), packetType, PrefixStyle.Fixed32, 0); object instance = Activator.CreateInstance(packetType); //packet = (Packet)ProtobufHelper.FromStream(packetType, (MemoryStream)source); packet = (Packet)ProtobufHelper.FromStream(instance, (MemoryStream)source); } else { Log.Warning("Can not deserialize packet for packet id '{0}'.", scPacketHeader.Id.ToString()); } } else { Log.Warning("Packet header is invalid."); } ReferencePool.Release(scPacketHeader); return(packet); }