/// <summary> /// Serializes this message as a byte array and optionally positions the job ID in the header as though we are a server /// </summary> /// <param name="server"></param> /// <returns></returns> public byte[] Serialize(bool server) { using (MemoryStream stream = new MemoryStream()) using (BinaryWriter writer = new BinaryWriter(stream)) { writer.Write(MessageTypeUtils.MergeMessage(MessageType, Protobuf)); if (Header is ProtobufClientHeader head) { using (MemoryStream protoStream = new MemoryStream()) { Serializer.Serialize(protoStream, (Header as ProtobufClientHeader).CreateProtobuf(server)); byte[] content = protoStream.ToArray(); writer.Write(content.Length); writer.Write(content); } } else if (Header is ClientHeader extended) { writer.Write((byte)36); writer.Write((ushort)2); writer.Write(server ? SteamGid.Invalid : extended.JobId); writer.Write(server ? extended.JobId : SteamGid.Invalid); writer.Write((byte)239); writer.Write(extended.SteamId); writer.Write(extended.SessionId); } else { writer.Write(server ? SteamGid.Invalid : Header.JobId); writer.Write(server ? Header.JobId : SteamGid.Invalid); } writer.Write(_body.Serialize()); return(stream.ToArray()); } }
public byte[] Serialize() { using (MemoryStream stream = new MemoryStream()) using (BinaryWriter writer = new BinaryWriter(stream)) { if (Protobuf) { writer.Write(MessageTypeUtils.MergeMessage((uint)MessageType, Protobuf)); using (MemoryStream protoStream = new MemoryStream()) { Serializer.Serialize(protoStream, (Header as GameCoordinatorProtobufHeader)); writer.Write((uint)protoStream.Length); writer.Write(protoStream.ToArray()); } } else { writer.Write((ushort)1); writer.Write(SteamGid.Invalid); writer.Write(Header.JobId); } writer.Write(_body.Serialize()); return(stream.ToArray()); } }
/// <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)))); } }
protected internal async Task SendAsync(GameCoordinatorMessageType messageType, bool protobuf, byte[] data) { await SendAsync(NetworkMessage .CreateAppRoutedMessage(MessageType.ClientToGC, new CMsgGCClient { appid = (uint)AppId, msgtype = MessageTypeUtils.MergeMessage((uint)messageType, protobuf), payload = data }, AppId)); }