mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-03-28 15:40:54 +03:00
fingerprint add ui mockup
This commit is contained in:
223
src/client.rs
223
src/client.rs
@@ -1,18 +1,63 @@
|
||||
use std::net::SocketAddr;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
collections::HashSet,
|
||||
net::{IpAddr, SocketAddr},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
use slab::Slab;
|
||||
|
||||
use lan_mouse_ipc::{ClientConfig, ClientHandle, ClientState, Position};
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Clone, Default)]
|
||||
pub struct ClientManager {
|
||||
clients: Slab<(ClientConfig, ClientState)>,
|
||||
clients: Rc<RefCell<Slab<(ClientConfig, ClientState)>>>,
|
||||
}
|
||||
|
||||
impl ClientManager {
|
||||
/// add a new client to this manager
|
||||
pub fn add_client(&mut self) -> ClientHandle {
|
||||
self.clients.insert(Default::default()) as ClientHandle
|
||||
pub fn add_client(&self) -> ClientHandle {
|
||||
self.clients.borrow_mut().insert(Default::default()) as ClientHandle
|
||||
}
|
||||
|
||||
/// set the config of the given client
|
||||
pub fn set_config(&self, handle: ClientHandle, config: ClientConfig) {
|
||||
if let Some((c, _)) = self.clients.borrow_mut().get_mut(handle as usize) {
|
||||
*c = config;
|
||||
}
|
||||
}
|
||||
|
||||
/// set the state of the given client
|
||||
pub fn set_state(&self, handle: ClientHandle, state: ClientState) {
|
||||
if let Some((_, s)) = self.clients.borrow_mut().get_mut(handle as usize) {
|
||||
*s = state;
|
||||
}
|
||||
}
|
||||
|
||||
/// activate the given client
|
||||
/// returns, whether the client was activated
|
||||
pub fn activate_client(&self, handle: ClientHandle) -> bool {
|
||||
let mut clients = self.clients.borrow_mut();
|
||||
match clients.get_mut(handle as usize) {
|
||||
Some((_, s)) if s.active == false => {
|
||||
s.active = true;
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// deactivate the given client
|
||||
/// returns, whether the client was deactivated
|
||||
pub fn deactivate_client(&self, handle: ClientHandle) -> bool {
|
||||
let mut clients = self.clients.borrow_mut();
|
||||
match clients.get_mut(handle as usize) {
|
||||
Some((_, s)) if s.active => {
|
||||
s.active = false;
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// find a client by its address
|
||||
@@ -20,6 +65,7 @@ impl ClientManager {
|
||||
// since there shouldn't be more than a handful of clients at any given
|
||||
// time this is likely faster than using a HashMap
|
||||
self.clients
|
||||
.borrow()
|
||||
.iter()
|
||||
.find_map(|(k, (_, s))| {
|
||||
if s.active && s.ips.contains(&addr.ip()) {
|
||||
@@ -31,8 +77,10 @@ impl ClientManager {
|
||||
.map(|p| p as ClientHandle)
|
||||
}
|
||||
|
||||
pub fn find_client(&self, pos: Position) -> Option<ClientHandle> {
|
||||
/// get the client at the given position
|
||||
pub fn client_at(&self, pos: Position) -> Option<ClientHandle> {
|
||||
self.clients
|
||||
.borrow()
|
||||
.iter()
|
||||
.find_map(|(k, (c, s))| {
|
||||
if s.active && c.pos == pos {
|
||||
@@ -44,31 +92,162 @@ impl ClientManager {
|
||||
.map(|p| p as ClientHandle)
|
||||
}
|
||||
|
||||
pub(crate) fn get_hostname(&self, handle: ClientHandle) -> Option<String> {
|
||||
self.clients
|
||||
.borrow_mut()
|
||||
.get_mut(handle as usize)
|
||||
.and_then(|(c, _)| c.hostname.clone())
|
||||
}
|
||||
|
||||
/// get the position of the corresponding client
|
||||
pub(crate) fn get_pos(&self, handle: ClientHandle) -> Option<Position> {
|
||||
self.clients
|
||||
.borrow()
|
||||
.get(handle as usize)
|
||||
.map(|(c, _)| c.pos)
|
||||
}
|
||||
|
||||
/// remove a client from the list
|
||||
pub fn remove_client(&mut self, client: ClientHandle) -> Option<(ClientConfig, ClientState)> {
|
||||
pub fn remove_client(&self, client: ClientHandle) -> Option<(ClientConfig, ClientState)> {
|
||||
// remove id from occupied ids
|
||||
self.clients.try_remove(client as usize)
|
||||
self.clients.borrow_mut().try_remove(client as usize)
|
||||
}
|
||||
|
||||
// returns an immutable reference to the client state corresponding to `client`
|
||||
pub fn get(&self, handle: ClientHandle) -> Option<&(ClientConfig, ClientState)> {
|
||||
self.clients.get(handle as usize)
|
||||
/// get the config & state of the given client
|
||||
pub fn get_state(&self, handle: ClientHandle) -> Option<(ClientConfig, ClientState)> {
|
||||
self.clients.borrow().get(handle as usize).cloned()
|
||||
}
|
||||
|
||||
/// returns a mutable reference to the client state corresponding to `client`
|
||||
pub fn get_mut(&mut self, handle: ClientHandle) -> Option<&mut (ClientConfig, ClientState)> {
|
||||
self.clients.get_mut(handle as usize)
|
||||
/// get the current config & state of all clients
|
||||
pub fn get_client_states(&self) -> Vec<(ClientHandle, ClientConfig, ClientState)> {
|
||||
self.clients
|
||||
.borrow()
|
||||
.iter()
|
||||
.map(|(k, v)| (k as ClientHandle, v.0.clone(), v.1.clone()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn get_client_states(
|
||||
&self,
|
||||
) -> impl Iterator<Item = (ClientHandle, &(ClientConfig, ClientState))> {
|
||||
self.clients.iter().map(|(k, v)| (k as ClientHandle, v))
|
||||
/// update the fix ips of the client
|
||||
pub fn set_fix_ips(&self, handle: ClientHandle, fix_ips: Vec<IpAddr>) {
|
||||
if let Some((c, _)) = self.clients.borrow_mut().get_mut(handle as usize) {
|
||||
c.fix_ips = fix_ips
|
||||
}
|
||||
self.update_ips(handle);
|
||||
}
|
||||
|
||||
pub fn get_client_states_mut(
|
||||
&mut self,
|
||||
) -> impl Iterator<Item = (ClientHandle, &mut (ClientConfig, ClientState))> {
|
||||
self.clients.iter_mut().map(|(k, v)| (k as ClientHandle, v))
|
||||
/// update the dns-ips of the client
|
||||
pub fn set_dns_ips(&self, handle: ClientHandle, dns_ips: Vec<IpAddr>) {
|
||||
if let Some((_, s)) = self.clients.borrow_mut().get_mut(handle as usize) {
|
||||
s.dns_ips = dns_ips
|
||||
}
|
||||
self.update_ips(handle);
|
||||
}
|
||||
|
||||
fn update_ips(&self, handle: ClientHandle) {
|
||||
if let Some((c, s)) = self.clients.borrow_mut().get_mut(handle as usize) {
|
||||
s.ips = c
|
||||
.fix_ips
|
||||
.iter()
|
||||
.cloned()
|
||||
.chain(s.dns_ips.iter().cloned())
|
||||
.collect::<HashSet<_>>();
|
||||
}
|
||||
}
|
||||
|
||||
/// update the hostname of the given client
|
||||
/// this automatically clears the active ip address and ips from dns
|
||||
pub fn set_hostname(&self, handle: ClientHandle, hostname: Option<String>) -> bool {
|
||||
let mut clients = self.clients.borrow_mut();
|
||||
let Some((c, s)) = clients.get_mut(handle as usize) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
// hostname changed
|
||||
if c.hostname != hostname {
|
||||
c.hostname = hostname;
|
||||
s.active_addr = None;
|
||||
s.dns_ips.clear();
|
||||
drop(clients);
|
||||
self.update_ips(handle);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// update the port of the client
|
||||
pub(crate) fn set_port(&self, handle: ClientHandle, port: u16) {
|
||||
match self.clients.borrow_mut().get_mut(handle as usize) {
|
||||
Some((c, s)) if c.port != port => {
|
||||
c.port = port;
|
||||
s.active_addr = s.active_addr.map(|a| SocketAddr::new(a.ip(), port));
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
|
||||
/// update the position of the client
|
||||
/// returns true, if a change in capture position is required (pos changed & client is active)
|
||||
pub(crate) fn set_pos(&self, handle: ClientHandle, pos: Position) -> bool {
|
||||
match self.clients.borrow_mut().get_mut(handle as usize) {
|
||||
Some((c, s)) if c.pos != pos => {
|
||||
log::info!("update pos {handle} {} -> {}", c.pos, pos);
|
||||
c.pos = pos;
|
||||
s.active
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// set resolving status of the client
|
||||
pub(crate) fn set_resolving(&self, handle: ClientHandle, status: bool) {
|
||||
if let Some((_, s)) = self.clients.borrow_mut().get_mut(handle as usize) {
|
||||
s.resolving = status;
|
||||
}
|
||||
}
|
||||
|
||||
/// get the enter hook command
|
||||
pub(crate) fn get_enter_cmd(&self, handle: ClientHandle) -> Option<String> {
|
||||
self.clients
|
||||
.borrow()
|
||||
.get(handle as usize)
|
||||
.and_then(|(c, _)| c.cmd.clone())
|
||||
}
|
||||
|
||||
/// returns all clients that are currently active
|
||||
pub(crate) fn active_clients(&self) -> Vec<ClientHandle> {
|
||||
self.clients
|
||||
.borrow()
|
||||
.iter()
|
||||
.filter(|(_, (_, s))| s.active)
|
||||
.map(|(h, _)| h as ClientHandle)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn set_active_addr(&self, handle: u64, addr: Option<SocketAddr>) {
|
||||
if let Some((_, s)) = self.clients.borrow_mut().get_mut(handle as usize) {
|
||||
s.active_addr = addr;
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn active_addr(&self, handle: u64) -> Option<SocketAddr> {
|
||||
self.clients
|
||||
.borrow()
|
||||
.get(handle as usize)
|
||||
.and_then(|(_, s)| s.active_addr)
|
||||
}
|
||||
|
||||
pub(crate) fn get_port(&self, handle: u64) -> Option<u16> {
|
||||
self.clients
|
||||
.borrow()
|
||||
.get(handle as usize)
|
||||
.map(|(c, _)| c.port)
|
||||
}
|
||||
|
||||
pub(crate) fn get_ips(&self, handle: u64) -> Option<HashSet<IpAddr>> {
|
||||
self.clients
|
||||
.borrow()
|
||||
.get(handle as usize)
|
||||
.map(|(_, s)| s.ips.clone())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user