From 68514da56288f2d529b81802521ada41299aeffa Mon Sep 17 00:00:00 2001 From: b1n Date: Sat, 22 Jun 2024 20:03:13 +0800 Subject: [PATCH] feat(ui): restore message after 3 secs --- Cargo.lock | 1 + Cargo.toml | 1 + src/bin/maker.rs | 66 ++++++++++++++-------------- src/lib.rs | 109 +++++++++++++++++++++++------------------------ 4 files changed, 90 insertions(+), 87 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 86da87c..1d1ebf1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2251,6 +2251,7 @@ dependencies = [ "open", "rand", "rfd", + "tokio", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0ba68db..99fcb43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ anyhow = "1.0.86" rand = "0.8.5" memchr = "2.7.4" aes-gcm = "0.10.3" +tokio = { version = "1.38.0", default-features = false , features = ["time"]} [dependencies.iced] version = "0.13.0-dev" diff --git a/src/bin/maker.rs b/src/bin/maker.rs index b9736f3..5474b0d 100644 --- a/src/bin/maker.rs +++ b/src/bin/maker.rs @@ -1,4 +1,4 @@ -use std::{fs, path::PathBuf, usize}; +use std::{fs, path::PathBuf, time::Duration, usize}; use dirs::{desktop_dir, home_dir}; use iced::{ @@ -66,6 +66,14 @@ impl Default for Maker { } impl Maker { + fn show_message(&mut self, message: String) -> Task { + self.message = message; + let wait = async { + tokio::time::sleep(Duration::from_secs(3)).await; + }; + Task::perform(wait, MakerMessage::ClearMessage) + } + fn plugin_name(&self) -> &str { &self.plugin_name } @@ -181,6 +189,7 @@ enum MakerMessage { B1nClicked, GithubClicked, ThemeChanged(Theme), + ClearMessage(()), } impl Application for Maker { @@ -281,19 +290,16 @@ impl Application for Maker { } MakerMessage::GenerateClicked => { if self.plugin_name().is_empty() { - self.message = "Plugin Name is empty.".to_string(); - return Task::none(); + return self.show_message("Plugin Name is empty.".to_string()); } if self.prefix().is_empty() { - self.message = "Prefix is empty.".to_string(); - return Task::none(); + return self.show_message("Prefix is empty.".to_string()); } if let ShellcodeSaveType::Local = self.shellcode_save_type() { if self.size_holder().is_empty() { - self.message = "Size Holder is empty.".to_string(); - return Task::none(); + return self.show_message("Size Holder is empty.".to_string()); } } @@ -302,25 +308,21 @@ impl Application for Maker { if let Ok(max) = self.max_len().parse::() { max_len = max; } else { - self.message = "MaxLen numeric only.".to_string(); - return Task::none(); + return self.show_message("MaxLen numeric only.".to_string()); } match self.encrypt_type() { EncryptType::None => (), EncryptType::Xor(x) => { if x.is_empty() { - self.message = "Xor Pass is empty.".to_string(); - return Task::none(); + return self.show_message("Xor Pass is empty.".to_string()); } } EncryptType::AesGcm(x) => { if x.key_holder().is_empty() { - self.message = "AesGcm Key is empty.".to_string(); - return Task::none(); + return self.show_message("AesGcm Key is empty.".to_string()); } else if x.nonce_holder().is_empty() { - self.message = "AesGcm Nonce is empty.".to_string(); - return Task::none(); + return self.show_message("AesGcm Nonce is empty.".to_string()); } } } @@ -436,14 +438,10 @@ impl Application for Maker { Task::perform(make_plugin, MakerMessage::GenerateDone) } - MakerMessage::GenerateDone(x) => { - self.message = match x { - Ok(_) => "Generate done.".to_string(), - Err(e) => e, - }; - - Task::none() - } + MakerMessage::GenerateDone(x) => self.show_message(match x { + Ok(_) => "Generate done.".to_string(), + Err(e) => e, + }), MakerMessage::ChooseFileClicked(x) => { let choose_file = async move { AsyncFileDialog::new() @@ -470,54 +468,54 @@ impl Application for Maker { MakerMessage::WindowsExeChooseDone(x) => { match x { Ok(x) => self.windows_exe = x, - Err(x) => self.message = x, + Err(x) => return self.show_message(x), } Task::none() } MakerMessage::WindowsLibChooseDone(x) => { match x { Ok(x) => self.windows_lib = x, - Err(x) => self.message = x, + Err(x) => return self.show_message(x), } Task::none() } MakerMessage::LinuxExeChooseDone(x) => { match x { Ok(x) => self.linux_exe = x, - Err(x) => self.message = x, + Err(x) => return self.show_message(x), } Task::none() } MakerMessage::LinuxLibChooseDone(x) => { match x { Ok(x) => self.linux_lib = x, - Err(x) => self.message = x, + Err(x) => return self.show_message(x), } Task::none() } MakerMessage::DarwinExeChooseDone(x) => { match x { Ok(x) => self.darwin_exe = x, - Err(x) => self.message = x, + Err(x) => return self.show_message(x), } Task::none() } MakerMessage::DarwinLibChooseDone(x) => { match x { Ok(x) => self.darwin_lib = x, - Err(x) => self.message = x, + Err(x) => return self.show_message(x), } Task::none() } MakerMessage::B1nClicked => { if open::that(env!("CARGO_PKG_HOMEPAGE")).is_err() { - self.message = "Open home failed.".into(); + return self.show_message("Open home failed.".into()); } Task::none() } MakerMessage::GithubClicked => { if open::that(env!("CARGO_PKG_REPOSITORY")).is_err() { - self.message = "Open repo failed.".into(); + return self.show_message("Open repo failed.".into()); } Task::none() } @@ -525,6 +523,10 @@ impl Application for Maker { self.selected_theme = x; Task::none() } + MakerMessage::ClearMessage(_) => { + self.message = "Welcom to PumpBin Maker.".to_string(); + Task::none() + } } } @@ -757,7 +759,7 @@ impl Application for Maker { .width(Length::FillPortion(1)) .align_items(Alignment::Start), column![row![b1n, github].align_items(Alignment::Center)] - .width(Length::FillPortion(1)) + .width(Length::Shrink) .align_items(Alignment::Center), column![theme_list] .width(Length::FillPortion(1)) diff --git a/src/lib.rs b/src/lib.rs index 8fe1a06..988abda 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,7 @@ mod button_style; pub mod plugin; pub mod svg_style; -use std::{fmt::Display, fs, iter, ops::Not, path::PathBuf}; +use std::{fmt::Display, fs, iter, ops::Not, path::PathBuf, time::Duration}; use dirs::{desktop_dir, home_dir}; use iced::{ @@ -109,8 +109,12 @@ impl Pumpbin { } } - fn show_message(&mut self, message: String) { + fn show_message(&mut self, message: String) -> Task { self.message = message; + let wait = async { + tokio::time::sleep(Duration::from_secs(3)).await; + }; + Task::perform(wait, Message::ClearMessage) } pub fn shellcode_src(&self) -> &str { @@ -182,6 +186,7 @@ pub enum Message { B1nClicked, GithubClicked, ThemeChanged(Theme), + ClearMessage(()), } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -274,7 +279,7 @@ impl Application for Pumpbin { if let Some(path) = x { self.shellcode_src = path.to_string_lossy().to_string(); } else { - self.show_message("Canceled shellcode selection.".into()) + return self.show_message("Canceled shellcode selection.".into()); } Task::none() } @@ -355,28 +360,21 @@ impl Application for Pumpbin { }; Task::perform(write_encrypted, Message::EncryptShellcodeDone) } else { - self.show_message("Canceled shellcode selection.".into()); - Task::none() + self.show_message("Canceled shellcode selection.".into()) } } - Message::EncryptShellcodeDone(x) => { - self.show_message(match x { - Ok(_) => "Saved encrypted shellcode.".into(), - Err(e) => e, - }); - - Task::none() - } + Message::EncryptShellcodeDone(x) => self.show_message(match x { + Ok(_) => "Saved encrypted shellcode.".into(), + Err(e) => e, + }), Message::GenerateClicked => { // verify path if local mode let path = PathBuf::from(self.shellcode_src()); if self.shellcode_save_type() == ShellcodeSaveType::Local { if path.exists().not() { - self.show_message("Shellcode path not exists.".into()); - return Task::none(); + return self.show_message("Shellcode path not exists.".into()); } else if path.is_file().not() { - self.show_message("Shellcode path is not a file.".into()); - return Task::none(); + return self.show_message("Shellcode path is not a file.".into()); } } @@ -546,14 +544,10 @@ impl Application for Pumpbin { Task::perform(generate, Message::GenerateDone) } - Message::GenerateDone(x) => { - self.show_message(match x { - Ok(_) => "Saved generated binary.".into(), - Err(e) => e, - }); - - Task::none() - } + Message::GenerateDone(x) => self.show_message(match x { + Ok(_) => "Saved generated binary.".into(), + Err(e) => e, + }), Message::BinaryTypeChanged(x) => { self.selected_binary_type = Some(x); Task::none() @@ -605,12 +599,10 @@ impl Application for Pumpbin { self.update(Message::PluginItemClicked(selected_plugin)); } self.plugins = plugins; - self.show_message(format!("Added {} plugins, {} failed.", success, failed)); + self.show_message(format!("Added {} plugins, {} failed.", success, failed)) } Err(e) => self.show_message(e), } - - Task::none() } Message::RemovePlugin(x) => { let mut plugins = self.plugins().clone(); @@ -628,31 +620,28 @@ impl Application for Pumpbin { }; Task::perform(remove_plugin, Message::RemovePluginDone) } - Message::RemovePluginDone(x) => { - match x { - Ok((plugin_name, plugins)) => { - self.plugins = plugins; + Message::RemovePluginDone(x) => match x { + Ok((plugin_name, plugins)) => { + self.plugins = plugins; - let mut names: Vec = - self.plugins().0.keys().map(|x| x.to_owned()).collect(); - names.sort(); + let mut names: Vec = + self.plugins().0.keys().map(|x| x.to_owned()).collect(); + names.sort(); - if let Some(name) = names.first() { - _ = self.update(Message::PluginItemClicked(name.to_owned())); - } else { - self.supported_binary_types = Default::default(); - self.selected_binary_type = None; - self.supported_platforms = Default::default(); - self.selected_platform = None; - self.selected_plugin = None; - self.shellcode_save_type = ShellcodeSaveType::Local; - } - self.show_message(format!("Removed plugin {}", plugin_name)); + if let Some(name) = names.first() { + _ = self.update(Message::PluginItemClicked(name.to_owned())); + } else { + self.supported_binary_types = Default::default(); + self.selected_binary_type = None; + self.supported_platforms = Default::default(); + self.selected_platform = None; + self.selected_plugin = None; + self.shellcode_save_type = ShellcodeSaveType::Local; } - Err(e) => self.show_message(e), + self.show_message(format!("Removed plugin {}", plugin_name)) } - Task::none() - } + Err(e) => self.show_message(e), + }, Message::PluginItemClicked(x) => { // unwrap is safe. // UI implemented strict restrictions. @@ -662,9 +651,9 @@ impl Application for Pumpbin { if plugin.plugin_name() == selected_plugin { // random encryption pass self.random_encrypt_pass(); - self.show_message("Generated new random encryption passwords.".to_string()); - - return Task::none(); + return self.show_message( + "Generated new random encryption passwords.".to_string(), + ); } } @@ -711,13 +700,13 @@ impl Application for Pumpbin { } Message::B1nClicked => { if open::that(env!("CARGO_PKG_HOMEPAGE")).is_err() { - self.show_message("Open home failed.".into()); + return self.show_message("Open home failed.".into()); } Task::none() } Message::GithubClicked => { if open::that(env!("CARGO_PKG_REPOSITORY")).is_err() { - self.show_message("Open repo failed.".into()); + return self.show_message("Open repo failed.".into()); } Task::none() } @@ -725,6 +714,10 @@ impl Application for Pumpbin { self.selected_theme = x; Task::none() } + Message::ClearMessage(_) => { + self.message = "Welcome to PumpBin!".to_string(); + Task::none() + } } } @@ -1120,7 +1113,13 @@ impl Application for Pumpbin { .width(Length::Fill) .height(Length::Fill); - let message = row![text(" ").size(25), text(&self.message)].align_items(Alignment::Center); + let message = row![ + text(" ") + .color(self.theme().extended_palette().primary.base.color) + .size(25), + text(&self.message).color(self.theme().extended_palette().primary.base.color) + ] + .align_items(Alignment::Center); let b1n = button( Svg::new(Handle::from_memory(include_bytes!(