39 lines
1.5 KiB
C#

using ChatRoom.Centralized.Shared.Packets;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
namespace ChatRoom.Centralized.Shared;
public class PacketReader : BinaryReader
{
public PacketReader(NetworkStream stream) : base(stream) { }
public INetworkPacket ReadPacket(Aes? keys) => ReadPacket(keys, out _);
public INetworkPacket ReadPacket(Aes? keys, out string outSignature)
{
string signature = Encoding.UTF8.GetString(ReadBytes(4));
INetworkPacket.PacketInfo info = INetworkPacket.packetTypes.SingleOrDefault(
x => x.signature.Equals(signature)) ?? throw new PacketSignatureException();
outSignature = signature;
if (char.IsUpper(signature.First()))
{
// Encrypted packet.
if (keys is null) throw new PacketEncryptionException(true);
int length = ReadInt32();
byte[] buffer = ReadBytes(length);
INetworkPacket result;
using (MemoryStream temp = new(buffer))
{
using CryptoStream encrypted = new(temp, keys.CreateDecryptor(), CryptoStreamMode.Read);
using BinaryReader encryptedReader = new(encrypted);
result = (INetworkPacket)info.readDataMethod.Invoke(null, new object[] { encryptedReader })!;
}
return result;
}
else return (INetworkPacket)info.readDataMethod.Invoke(null, new object[] { this })!;
}
}