64 lines
2.2 KiB
C#
64 lines
2.2 KiB
C#
using System.Net.Sockets;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
|
|
namespace ChatRoom.Centralized.Shared;
|
|
|
|
public class PacketWriter : BinaryWriter
|
|
{
|
|
public PacketWriter(NetworkStream stream) : base(stream) { }
|
|
|
|
public void Write(INetworkPacket packet, Aes? keys)
|
|
{
|
|
INetworkPacket.PacketInfo info = INetworkPacket.packetTypes.SingleOrDefault(
|
|
x => x.type == packet.GetType()) ?? throw new PacketSignatureException();
|
|
if (info.signature.Length != 4) throw new("Invalid packet signature length.");
|
|
Write(Encoding.UTF8.GetBytes(info.signature));
|
|
if (char.IsUpper(info.signature.First()))
|
|
{
|
|
// Encrypted packet.
|
|
if (keys is null) throw new PacketEncryptionException(true);
|
|
byte[] contents;
|
|
using (MemoryStream temp = new())
|
|
{
|
|
using (CryptoStream encrypted = new(temp, keys.CreateEncryptor(), CryptoStreamMode.Write))
|
|
{
|
|
using BinaryWriter encryptedWriter = new(encrypted);
|
|
packet.WriteData(encryptedWriter);
|
|
}
|
|
contents = temp.GetBuffer();
|
|
};
|
|
Write(contents.Length);
|
|
Write(contents);
|
|
}
|
|
else
|
|
{
|
|
// Unencrypted packet.
|
|
packet.WriteData(this);
|
|
}
|
|
}
|
|
public void Write<T>(T packet, Aes? keys) where T : INetworkPacket<T>
|
|
{
|
|
if (T.Signature.Length != 4) throw new("Invalid packet length.");
|
|
if (char.IsUpper(T.Signature.First()))
|
|
{
|
|
// Encrypted packet.
|
|
if (keys is null) throw new PacketEncryptionException(true);
|
|
MemoryStream temp = new();
|
|
CryptoStream encrypted = new(temp, keys.CreateEncryptor(), CryptoStreamMode.Write);
|
|
BinaryWriter encryptedWriter = new(encrypted);
|
|
packet.WriteData(encryptedWriter);
|
|
encrypted.Flush();
|
|
byte[] contents = temp.GetBuffer();
|
|
temp.Close();
|
|
Write(contents.Length);
|
|
Write(contents);
|
|
}
|
|
else
|
|
{
|
|
// Unencrypted packet.
|
|
packet.WriteData(this);
|
|
}
|
|
}
|
|
}
|