use std::
{
net::TcpStream,
collections::HashMap,
sync::{ Arc, Mutex },
};
use why2::stream::RexStream;
use crate::
{
crypto,
network::
{
screen,
Streams,
server::{ self, Connection },
},
};
struct ScreenTransferGuard
{
id: usize,
}
impl Drop for ScreenTransferGuard
{
fn drop(&mut self)
{
if let Some(mut conn) = server::CONNECTIONS.iter_mut().find(|c| c.id() == Some(&self.id))
{
conn.remove_screen_stream();
}
}
}
pub fn screen(token: [u8; 32], id: usize, streams: &mut Streams)
{
let keys =
{
let conn = server::CONNECTIONS.iter_mut()
.find(|e| e.value().id() == Some(&id));
match conn
{
Some(mut c) =>
{
let keys = match c.keys()
{
Some(k) => k.clone(),
None => return
};
c.set_screen_stream(Arc::new(Mutex::new(streams.0.try_clone().unwrap())));
keys
},
None => return
}
};
let _guard = ScreenTransferGuard { id };
let mut seq = 0usize;
let mut viewer_seqs = HashMap::<usize, usize>::new();
let mut viewer_streams = HashMap::<usize, ([u8; 32], RexStream)>::new();
let mut rex_stream = crypto::init_rex_stream(&keys, &token).unwrap();
loop
{
let read = match screen::receive_frame(streams, &mut rex_stream, &mut seq)
{
Some(r) => r,
None => return
};
let entries: Vec<(usize, Arc<TcpStream>)> = server::CONNECTIONS.iter().filter_map(|entry|
{
match entry.value()
{
Connection::Authenticated { id: client_id, attached_screen, keys, .. } =>
{
if let Some(attached_screen) = attached_screen && attached_screen.target_id == id
{
if viewer_streams.get(client_id).map(|(t, _)| t != &attached_screen.token).unwrap_or(true)
{
let rex_stream = crypto::init_rex_stream(&keys, &attached_screen.token).unwrap();
viewer_streams.insert(*client_id, (attached_screen.token, rex_stream));
}
if *client_id == id && read.frame.is_none()
{
return None;
}
Some((*client_id, attached_screen.stream.clone()))
} else { None }
},
_ => None,
}
}).collect();
for (client_id, stream) in entries
{
if let Ok(mut cloned_stream) = stream.try_clone()
{
let viewer_seq = viewer_seqs.entry(client_id).or_insert(0);
let viewer_stream = viewer_streams.get_mut(&client_id).unwrap();
screen::send_frame(&mut cloned_stream, read.clone(), &mut viewer_stream.1, Some(viewer_seq));
}
}
}
}