using ProtoBuf; using Serilog; namespace ClientTester.Packet { // 패킷 헤더 크기 4(패킷 타입, 패킷 길이) public static class PacketSerializer { // 직렬화: 객체 → byte[] (size는 payload 크기로 자동 계산) public static byte[] Serialize(ushort type, T packet) { using MemoryStream payloadMs = new MemoryStream(); Serializer.Serialize(payloadMs, packet); byte[] payload = payloadMs.ToArray(); ushort size = (ushort)payload.Length; byte[] result = new byte[4 + payload.Length]; result[0] = (byte)(type & 0xFF); result[1] = (byte)(type >> 8); result[2] = (byte)(size & 0xFF); result[3] = (byte)(size >> 8); Buffer.BlockCopy(payload, 0, result, 4, payload.Length); return result; } // 역직렬화: byte[] → (PacketType, payload bytes) public static (ushort type, ushort size, byte[] payload) Deserialize(byte[] data) { if (data.Length < 4) { Log.Warning("[PacketHeader]의 길이가 4이하입니다."); return (0, 0, null)!; } ushort type = (ushort)(data[0] | (data[1] << 8)); ushort size = (ushort)(data[2] | (data[3] << 8)); int actualPayloadLen = data.Length - 4; if (size > actualPayloadLen) { Log.Warning("[PacketSerializer] 페이로드 크기 불일치 HeaderSize={Size} ActualSize={Actual}", size, actualPayloadLen); return (0, 0, null)!; } byte[] payload = new byte[size]; Buffer.BlockCopy(data, 4, payload, 0, size); return (type, size, payload); } // 페이로드 → 특정 타입으로 역직렬화 public static T DeserializePayload(byte[] payload) { using MemoryStream ms = new MemoryStream(payload); return Serializer.Deserialize(ms); } } }