pub mod consts;
pub mod options;
#[cfg(feature = "client")]
pub mod client;
#[cfg(feature = "server")]
pub mod server;
use std::
{
io::Error,
net::{ UdpSocket, SocketAddr },
};
use wincode::{ SchemaRead, SchemaWrite };
use crate::
{
crypto,
consts::SharedKeys,
};
#[cfg(not(feature = "server"))]
use crate::options as chat_options;
#[derive(Clone, PartialEq, SchemaRead, SchemaWrite)]
pub enum VoiceCode
{
PING, PONG, }
#[derive(SchemaRead, SchemaWrite)]
pub struct VoicePacket {
pub voice: Option<Vec<u8>>, pub username: Option<String>, pub code: Option<VoiceCode>, pub id: Option<usize>, pub target_id: Option<usize>, pub seq: usize, pub timestamp: Option<u128>, }
impl Default for VoicePacket
{
fn default() -> Self
{
VoicePacket
{
voice: None,
id: None,
target_id: None,
code: None,
username: None,
seq: 0,
timestamp: None,
}
}
}
pub fn send (
socket: &UdpSocket,
mut packet: VoicePacket,
#[cfg(feature = "server")] addr: &SocketAddr,
#[cfg(feature = "server")] recipient_id: &usize,
keys: &SharedKeys
) -> Result<usize, Error>
{
#[cfg(feature = "server")]
{
if let Some(mut conn) = server::CONNECTIONS.get_mut(recipient_id) &&
let Some(conn) = conn.0.as_mut()
{
packet.seq = conn.server_seq() + 1;
*conn.server_seq_mut() = packet.seq;
}
}
#[cfg(feature = "client")]
{
packet.seq = options::get_seq() + 1;
options::set_seq(packet.seq);
}
let packet_bytes = wincode::serialize(&packet).expect("Encoding packet failed");
#[cfg(feature = "server")]
let encrypted_bytes: Vec<u8>;
#[cfg(not(feature = "server"))]
let mut encrypted_bytes: Vec<u8>;
encrypted_bytes = crypto::encrypt_packet::< { consts::GRID_WIDTH }, { consts::GRID_HEIGHT } >(packet_bytes, keys);
#[cfg(feature = "client")]
{
let id_be_bytes = packet.id.unwrap().to_be_bytes();
encrypted_bytes.splice(0..0, id_be_bytes);
}
#[cfg(feature = "server")]
{
socket.send_to(&encrypted_bytes, addr)
}
#[cfg(not(feature = "server"))]
{
socket.send(&encrypted_bytes)
}
}
pub fn receive(socket: &UdpSocket) -> Option<(VoicePacket, SocketAddr)> {
let mut buffer = [0u8; 2048];
loop {
#[cfg(feature = "client")]
if !options::get_use_voice() { break None; }
let (len, addr) = match socket.recv_from(&mut buffer)
{
Ok(result) => result,
Err(_) => continue
};
let buffer_offset: usize;
let keys =
{
#[cfg(feature = "server")]
{
if len <= 8 { continue; }
let id = match buffer[..8].try_into()
{
Ok(id_be_bytes) => usize::from_be_bytes(id_be_bytes),
Err(_) => continue
};
buffer_offset = 8;
match server::find_key(&id)
{
Some(k) => k,
None => continue
}
}
#[cfg(not(feature = "server"))]
{
buffer_offset = 0;
chat_options::get_keys().unwrap()
}
};
let decrypted_bytes = match crypto::decrypt_packet::<{ consts::GRID_WIDTH }, { consts::GRID_HEIGHT }>
(buffer[buffer_offset..len].to_vec(), &keys)
{
Some(d) => d,
None => continue
};
return match wincode::deserialize::<VoicePacket>(&decrypted_bytes)
{
Ok(packet) => Some((packet, addr)),
Err(_) => continue
}
}
}