/// <summary> /// Deserializes a <see cref="NetworkMessage"/> from a byte array as a server /// </summary> /// <param name="data"></param> /// <param name="server"></param> /// <returns></returns> public static NetworkMessage CreateFromByteArray(byte[] data, bool server) { using (MemoryStream stream = new MemoryStream(data, false)) using (BinaryReader reader = new BinaryReader(stream)) { (MessageType type, bool protobuf) = MessageTypeUtils.SplitMessage(reader.ReadUInt32()); Header header; void ReadHeader() { ulong targetJob = reader.ReadUInt64(); ulong sourceJob = reader.ReadUInt64(); header = new Header(sourceJob); } if (protobuf) { int length = reader.ReadInt32(); CMsgProtoBufHeader protobufHeader; using (MemoryStream protoStream = new MemoryStream(reader.ReadBytes(length))) protobufHeader = Serializer.Deserialize <CMsgProtoBufHeader>(protoStream); header = new ProtobufClientHeader(protobufHeader, server); } else if (stream.Length > 36 && reader.ReadByte() == 36 && reader.ReadUInt16() == 2) { // please never fail ulong target = reader.ReadUInt64(); ulong source = reader.ReadUInt64(); if (reader.ReadByte() != 239) { stream.Seek(4, SeekOrigin.Begin); ReadHeader(); } else { ulong steamId = reader.ReadUInt64(); int sessionId = reader.ReadInt32(); header = new ClientHeader(source, steamId, sessionId); // if we somehow get here and it turns out we're not in the header anymore (and it was a normal header), // tell me so I can shoot myself } } else { stream.Seek(4, SeekOrigin.Begin); ReadHeader(); } return(new NetworkMessage(type, header, new ArraySegment <byte>(data, (int)stream.Position, (int)(stream.Length - stream.Position)))); } }
/// <summary> /// Creates a protobuf message with a protobuf header with the specified routing app ID /// </summary> /// <param name="type"></param> /// <param name="body"></param> /// <param name="appId"></param> /// <returns></returns> public static NetworkMessage CreateAppRoutedMessage(MessageType type, object body, long appId) { if (appId < uint.MinValue || appId > uint.MaxValue) { throw new ArgumentOutOfRangeException(nameof(appId)); } var header = new ProtobufClientHeader((uint)appId, 0, null, SteamGid.Invalid, SteamId.Zero, 0); return(new NetworkMessage(type, header, body)); }
/// <summary> /// Creates a protobuf message with a protobuf header /// </summary> /// <param name="type"></param> /// <param name="body"></param> /// <returns></returns> public static NetworkMessage CreateProtobufMessage(MessageType type, object body) { var head = new ProtobufClientHeader(); return(new NetworkMessage(type, head, body)); }