get UI updates working

This commit is contained in:
Michael Mikovsky
2025-06-08 19:17:23 -06:00
parent e2764edfae
commit 6ac1b5214e
7 changed files with 46 additions and 151 deletions
+2 -92
View File
@@ -1,10 +1,7 @@
use std::{
error::Error,
mem,
net::SocketAddr,
sync::{Arc, Mutex},
thread,
time::Duration,
};
use crossbeam_channel::{Receiver, Sender};
@@ -14,9 +11,10 @@ use unshell_rs_lib::{
};
pub struct UnshellClient {
#[allow(dead_code)]
addr: SocketAddr,
tx: Sender<C2Packet>,
rx: Receiver<C2Packet>,
pub rx: Receiver<C2Packet>,
parameters: Arc<Mutex<Parameters>>,
}
@@ -26,97 +24,13 @@ impl UnshellClient {
let (tx, rx) = TCPConnection::as_async(client);
// mpsc
// let poll = Poll::new()?;
// let events = Events::with_capacity(128);
// const SERVER: Token = Token(0);
// poll.registry()
// .register(&mut listener, SERVER, Interest::READABLE)?;
// let client = Arc::new(Mutex::new());
// let outgoing_packets = Arc::new(Mutex::new(Vec::<GuiPacket>::new()));
let parameters = Arc::new(Mutex::new(Parameters::new()));
// let tx_client = Arc::clone(&client);
// let tx_packets = Arc::clone(&outgoing_packets);
// // Recieve thread
// thread::spawn(move || {
// loop {
// info!("Lock 2");
// let mut packets_lock = tx_packets.lock().unwrap();
// info!("Lock 2");
// if !packets_lock.is_empty() {
// info!("Lock 3");
// if let Ok(packet) = packets_lock.pop().unwrap().encode() {
// info!("Lock 3");
// info!("Lock 4");
// let mut client_lock = tx_client.lock().unwrap();
// info!("Lock 4");
// info!("Wrote {}", packet.as_str());
// match client_lock.write(packet.as_str()) {
// Err(e) => {
// error!("Failed to send packet: {:?}", e);
// }
// _ => {}
// };
// }
// }
// std::mem::drop(packets_lock);
// thread::sleep(Duration::from_millis(10));
// }
// });
// let rx_client = Arc::clone(&client);
// let rx_params = Arc::clone(&parameters);
// thread::spawn(move || {
// loop {
// info!("Lock 5");
// let mut client = rx_client.lock().unwrap();
// info!("Lock 5");
// if !client.is_alive() {
// error!("Disconnected from {}!", client.get_info());
// }
// if let Ok(data) = client.read() {
// info!("Got {}", data);
// if let Ok(packet) = GuiPacket::decode(data.as_str()) {
// match packet {
// GuiPacket::ParameterUpate(name, parameter) => {
// rx_params.lock().unwrap().insert(name, parameter);
// }
// GuiPacket::Error(error_packet) => {
// error!("Got error: {}", print_type_of(&error_packet))
// }
// GuiPacket::SetAllParameters(parameters) => {
// let mut params_lock = rx_params.lock().unwrap();
// params_lock.clear();
// params_lock.extend(parameters);
// }
// _ => {
// error!("Unsupported packet: {}", data)
// }
// }
// }
// }
// // std::mem::drop(client);
// thread::sleep(Duration::from_millis(10));
// }
// });
Ok(Self {
addr,
tx,
rx,
// client,
parameters,
// outgoing_packets,
})
}
@@ -130,7 +44,3 @@ impl UnshellClient {
self.parameters.lock().unwrap().get(key).cloned()
}
}
fn print_type_of<T>(_: &T) -> &'static str {
std::any::type_name::<T>()
}
+38 -33
View File
@@ -1,22 +1,20 @@
use slint::{ComponentHandle, ModelRc, VecModel};
use slint::{ComponentHandle, Weak};
use std::{
error::Error,
sync::{Arc, Mutex},
thread,
};
use unshell_rs_lib::{config::campaign::CampaignConfig, connection::Parameter};
use unshell_rs_lib::connection::{C2Packet, Parameter};
use crate::client::UnshellClient;
pub struct UnshellGui {
client: UnshellClient,
ui: AppWindow,
campaign: Option<Arc<Mutex<CampaignConfig>>>,
}
pub struct UnshellGui {}
slint::include_modules!();
impl UnshellGui {
pub fn start(client: UnshellClient) -> Result<(), Box<dyn Error>> {
let ui = AppWindow::new()?;
let rx = client.rx.clone();
let client = Arc::new(Mutex::new(client));
let ui_handle = ui.as_weak();
@@ -24,9 +22,7 @@ impl UnshellGui {
ui.on_tab_clicked(move |index| {
let ui = ui_handle.unwrap();
ui.set_current_tab(index);
info!("Lock 1 ");
let mut client_lock = client_clone.lock().unwrap();
info!("Lock 1 ");
client_lock.set_parameter("Current Tab".to_string(), Parameter::CurrentTab(index));
trace!("Tab {} selected", index);
});
@@ -40,32 +36,41 @@ impl UnshellGui {
.into()
});
let ui_handle = ui.as_weak();
thread::spawn(move || {
fn on_param_update(ui_handle: Weak<AppWindow>, parameter: &Parameter) {
// info!("{}", name);
match parameter {
Parameter::Test1 => todo!(),
Parameter::CurrentTab(i) => {
let i = i.clone();
slint::invoke_from_event_loop(move || {
ui_handle.unwrap().set_current_tab(i)
})
.unwrap();
}
}
}
loop {
if let Ok(data) = rx.recv() {
match data {
C2Packet::SetAllParameters(parameters) => {
for key in parameters.keys() {
on_param_update(ui_handle.clone(), parameters.get(key).unwrap());
}
}
C2Packet::ParameterUpate(name, parameter) => {
on_param_update(ui_handle.clone(), &parameter);
}
_ => {}
}
}
}
});
ui.run()?;
Ok(())
}
fn update(&mut self) {
// self.ui.set_listeners(ModelRc::new(VecModel::from(
// self.campaign
// .listeners
// .iter()
// .map(|l| match l {
// ListenerConfig::Tcp {
// enabled,
// name,
// addr,
// layers,
// ..
// } => UITcpListener {
// enabled: *enabled,
// name: name.clone().into(),
// remote_host: addr.to_string().into(),
// },
// })
// .collect::<Vec<UITcpListener>>(),
// )));
}
}
// trait
-2
View File
@@ -2,8 +2,6 @@ use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
use unshell_rs_lib::config::campaign::CampaignConfig;
use std::collections::HashMap;
use unshell_rs_lib::connection::Parameters;
lazy_static! {
+2 -12
View File
@@ -1,23 +1,19 @@
use std::{
collections::HashMap,
error::Error,
fs::File,
io::Read,
net::SocketAddr,
sync::{Arc, Mutex},
thread,
time::Duration,
};
use crossbeam_channel::{Receiver, Sender};
use crossbeam_channel::Sender;
use serde::{Deserialize, Serialize};
use unshell_rs_lib::{
config::campaign::CampaignConfig,
connection::{C2Packet, ErrorPacket, Parameters},
networkers::{
AsyncConnection, Connection, ServerTrait, TCPConnection, TCPServer, run_listener_state,
},
networkers::{AsyncConnection, ServerTrait, TCPConnection, TCPServer, run_listener_state},
};
use crate::server::{DEFAULT_CAMPAIGN, DEFAULT_USERS, User, config::DEFAULT_PARAMETERS};
@@ -73,12 +69,6 @@ impl UnshellServer {
}
});
// let (broadcast_tx, broadcast_rx) = crossbeam_channel::unbounded::<String>();
// let mut config_lock = s.config.lock().unwrap();
// config_lock.broadcast_tx = Some(broadcast_tx);
// config_lock.broadcast_rx = Some(broadcast_rx);
// std::mem::drop(config_lock);
s
}
+1 -4
View File
@@ -1,7 +1,4 @@
use std::{
collections::HashMap,
fmt::{self, Display},
};
use std::{collections::HashMap, fmt};
use serde::{Deserialize, Serialize};
use serde_json::Result;
-2
View File
@@ -113,5 +113,3 @@ use serde::de::DeserializeOwned;
pub use tcp::TCPClient;
pub use tcp::TCPConnection;
pub use tcp::TCPServer;
use crate::connection;
+3 -6
View File
@@ -1,5 +1,4 @@
use std::{
error::Error,
io::{self, BufRead, BufReader, Write},
net::{SocketAddr, TcpListener, TcpStream},
thread,
@@ -62,13 +61,12 @@ impl AsyncConnection<TCPConnection> for TCPConnection {
let (send_tx, send_rx) = crossbeam_channel::unbounded::<T>();
let (recv_tx, recv_rx) = crossbeam_channel::unbounded::<T>();
let tx_clone = send_tx.clone();
thread::spawn(move || {
let mut reader = connection.reader;
let mut read = || -> Result<String, Self::Error> {
let mut line = String::new();
let n = reader.read_line(&mut line)?;
let _ = reader.read_line(&mut line)?;
Ok(line.trim_end().to_string())
};
@@ -80,7 +78,7 @@ impl AsyncConnection<TCPConnection> for TCPConnection {
}
info!("Got {}", data);
if let Ok(decoded) = serde_json::from_str::<T>(&data) {
if let Err(e) = tx_clone.send(decoded) {
if let Err(e) = send_tx.send(decoded) {
error!("Got error: {}", e);
}
}
@@ -88,7 +86,6 @@ impl AsyncConnection<TCPConnection> for TCPConnection {
}
});
let rx_clone = recv_rx.clone();
thread::spawn(move || {
let mut stream = connection.stream;
@@ -99,7 +96,7 @@ impl AsyncConnection<TCPConnection> for TCPConnection {
};
loop {
if let Ok(data) = rx_clone.recv() {
if let Ok(data) = recv_rx.recv() {
if let Ok(encoded) = serde_json::to_string(&data) {
info!("Write {}", encoded);
if let Err(e) = write(encoded) {