From 592874680c867c71a506c21da88fc8124d52a446 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Fri, 18 Apr 2025 23:08:10 +0300 Subject: [PATCH] config refactor and some fixes like always --- Cargo.lock | 60 +++++++++++++++ Cargo.toml | 1 + README.md | 2 +- flake.nix | 12 +-- src/chat/config.rs | 182 ++++++++++++++++----------------------------- src/chat/ctx.rs | 89 ++++++++++++---------- src/chat/gui.rs | 68 +++++------------ src/chat/mod.rs | 97 ++++++------------------ src/main.rs | 29 ++++---- 9 files changed, 239 insertions(+), 301 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7d4ea46..dd9cfda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,6 +101,7 @@ dependencies = [ "rand", "regex", "serde", + "serde_default", "serde_yml", ] @@ -252,6 +253,41 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -284,6 +320,12 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "foreign-types" version = "0.3.2" @@ -670,6 +712,12 @@ dependencies = [ "cc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "indexmap" version = "2.7.1" @@ -1057,6 +1105,18 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde_default" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "486b028b311aaaea83e0ba65a3e6e3cbef381e74e9d0bd6263faefd1fb503c1d" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde_derive" version = "1.0.219" diff --git a/Cargo.toml b/Cargo.toml index 8174372..bedf867 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,4 @@ clap = { version = "4.5.36", features = ["derive"] } serde = { version = "1.0.219", features = ["serde_derive"] } gtk4 = { version = "0.9.6", features = [ "v4_10" ] } chrono = "0.4.40" +serde_default = "0.2.0" \ No newline at end of file diff --git a/README.md b/README.md index 74c3fe8..f838bba 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ cargo run -r # build and run If you have Nix package manager installed, you can use: ```bash -nix build github:MeexReay/bRAC # build release (result/bin/bRAC)) +nix build github:MeexReay/bRAC # build release (result/bin/bRAC) nix run github:MeexReay/bRAC # build and run ``` diff --git a/flake.nix b/flake.nix index 73352ee..fd35ab1 100644 --- a/flake.nix +++ b/flake.nix @@ -35,7 +35,7 @@ devShells.default = self'.devShells.stable; packages.bRAC = let - deps = [ + deps = with pkgs; [ pkg-config openssl gtk4 @@ -45,17 +45,11 @@ cargo = pkgs.rust-bin.stable.latest.minimal; rustc = pkgs.rust-bin.stable.latest.minimal; }).buildRustPackage { - inherit (cargoToml.package) name; + inherit (cargoToml.package) name version; src = ./.; cargoLock.lockFile = ./Cargo.lock; - version = lib.concatStrings [ cargoToml.package.version version ]; buildInputs = deps; nativeBuildInputs = deps; - patchPhase = '' - substituteInPlace Cargo.toml --replace \ - 'version = "${cargoToml.package.version}"' \ - 'version = "${lib.concatStrings [ cargoToml.package.version version ]}"' - ''; }; devShells.nightly = (mkDevShell (pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.default))); @@ -63,4 +57,4 @@ devShells.msrv = (mkDevShell pkgs.rust-bin.stable.${msrv}.default); }; }; -} \ No newline at end of file +} diff --git a/src/chat/config.rs b/src/chat/config.rs index 47878d2..e7a7c68 100644 --- a/src/chat/config.rs +++ b/src/chat/config.rs @@ -1,88 +1,31 @@ use std::str::FromStr; -use std::{fs, path::PathBuf, thread, time::Duration}; +use std::{fs, path::PathBuf}; use serde_yml; +use serde_default::DefaultFromSerde; use clap::Parser; -use super::gui::{ask_bool, ask_string, ask_string_option, ask_usize, show_message}; - const MESSAGE_FORMAT: &str = "\u{B9AC}\u{3E70}<{name}> {text}"; -#[derive(serde::Serialize, serde::Deserialize)] -pub struct Config { - #[serde(default = "default_host")] - pub host: String, - #[serde(default)] - pub name: Option, - #[serde(default = "default_message_format")] - pub message_format: String, - #[serde(default = "default_update_time")] - pub update_time: usize, - #[serde(default = "default_max_messages")] - pub max_messages: usize, - #[serde(default)] - pub enable_ip_viewing: bool, - #[serde(default)] - pub disable_ip_hiding: bool, - #[serde(default)] - pub enable_auth: bool, - #[serde(default)] - pub enable_ssl: bool, - #[serde(default)] - pub enable_chunked: bool, -} - +fn default_true() -> bool { true } fn default_max_messages() -> usize { 200 } fn default_update_time() -> usize { 50 } fn default_host() -> String { "meex.lol:11234".to_string() } fn default_message_format() -> String { MESSAGE_FORMAT.to_string() } -pub fn configure(path: PathBuf) -> Config { - show_message("Client setup", format!("To configure the client, please answer a few questions. It won't take long. -You can reconfigure client in any moment via `bRAC --configure` -Config stores in path `{}`", path.to_string_lossy())); - - let host = ask_string("Host", default_host()); - let name = ask_string_option("Name", "ask every time"); - let update_time = ask_usize("Update interval", default_update_time()); - let max_messages = ask_usize("Max messages", default_max_messages()); - let message_format = ask_string("Message format", default_message_format()); - let enable_ip_viewing = ask_bool("Enable users IP viewing?", true); - let disable_ip_hiding = ask_bool("Enable your IP viewing?", false); - let enable_auth = ask_bool("Enable auth-mode?", false); - let enable_ssl = ask_bool("Enable SSL?", false); - let enable_chunked = ask_bool("Enable chunked reading?", true); - - let config = Config { - host, - name, - message_format, - update_time, - max_messages, - enable_ip_viewing, - disable_ip_hiding, - enable_auth, - enable_ssl, - enable_chunked - }; - - let config_text = serde_yml::to_string(&config).expect("Config save error"); - fs::create_dir_all(&path.parent().expect("Config save error")).expect("Config save error"); - fs::write(&path, config_text).expect("Config save error"); - - show_message("Config saved!", "You can reconfigure it in any moment via `bRAC --configure`"); - - config -} - -pub fn load_config(path: PathBuf) -> Config { - if !fs::exists(&path).unwrap_or_default() { - let config = configure(path.clone()); - thread::sleep(Duration::from_secs(4)); - config - } else { - let config = &fs::read_to_string(&path).expect("Config load error"); - serde_yml::from_str(config).expect("Config load error") - } +#[derive(serde::Serialize, serde::Deserialize, DefaultFromSerde, Clone)] +pub struct Config { + #[serde(default = "default_host")] pub host: String, + #[serde(default)] pub name: Option, + #[serde(default = "default_message_format")] pub message_format: String, + #[serde(default = "default_update_time")] pub update_time: usize, + #[serde(default = "default_max_messages")] pub max_messages: usize, + #[serde(default)] pub hide_my_ip: bool, + #[serde(default)] pub show_other_ip: bool, + #[serde(default)] pub auth_enabled: bool, + #[serde(default)] pub ssl_enabled: bool, + #[serde(default)] pub chunked_enabled: bool, + #[serde(default = "default_true")] pub formatting_enabled: bool, + #[serde(default = "default_true")] pub commands_enabled: bool, } pub fn get_config_path() -> PathBuf { @@ -124,6 +67,25 @@ pub fn get_config_path() -> PathBuf { config_dir.join("config.yml") } +pub fn load_config(path: PathBuf) -> Config { + if !fs::exists(&path).unwrap_or_default() { + let config = Config::default(); + let config_text = serde_yml::to_string(&config).expect("Config save error"); + fs::create_dir_all(&path.parent().expect("Config save error")).expect("Config save error"); + fs::write(&path, config_text).expect("Config save error"); + config + } else { + let config = &fs::read_to_string(&path).expect("Config load error"); + serde_yml::from_str(config).expect("Config load error") + } +} + +pub fn save_config(path: PathBuf, config: Config) { + let config_text = serde_yml::to_string(&config).expect("Config save error"); + fs::create_dir_all(&path.parent().expect("Config save error")).expect("Config save error"); + fs::write(&path, config_text).expect("Config save error"); +} + #[derive(Parser, Debug)] #[command(version, about, long_about = None)] pub struct Args { @@ -131,18 +93,6 @@ pub struct Args { #[arg(short='p', long)] pub config_path: bool, - /// Use specified host - #[arg(short='H', long)] - pub host: Option, - - /// Use specified name - #[arg(short='n', long)] - pub name: Option, - - /// Use specified message format - #[arg(short='F', long)] - pub message_format: Option, - /// Print unformatted messages from chat and exit #[arg(short='r', long)] pub read_messages: bool, @@ -150,36 +100,34 @@ pub struct Args { /// Send unformatted message to chat and exit #[arg(short='s', long, value_name="MESSAGE")] pub send_message: Option, + + #[arg(short='H', long)] pub host: Option, + #[arg(short='n', long)] pub name: Option, + #[arg(long)] pub message_format: Option, + #[arg(long)] pub update_time: Option, + #[arg(long)] pub max_messages: Option, + #[arg(long)] pub hide_my_ip: Option, + #[arg(long)] pub show_other_ip: Option, + #[arg(long)] pub auth_enabled:Option , + #[arg(long)] pub ssl_enabled: Option, + #[arg(long)] pub chunked_enabled: Option, + #[arg(long)] pub formatting_enabled: Option, + #[arg(long)] pub commands_enabled: Option, +} - /// Disable message formatting and sanitizing - #[arg(short='f', long)] - pub disable_formatting: bool, - - /// Disable slash commands - #[arg(short='c', long)] - pub disable_commands: bool, - - /// Disable ip hiding - #[arg(short='i', long)] - pub disable_ip_hiding: bool, - - /// Enable users IP viewing - #[arg(short='v', long)] - pub enable_users_ip_viewing: bool, - - /// Configure client - #[arg(short='C', long)] - pub configure: bool, - - /// Enable authentication - #[arg(short='a', long)] - pub enable_auth: bool, - - /// Enable SSL - #[arg(short='S', long)] - pub enable_ssl: bool, - - /// Enable chunked reading - #[arg(short='u', long)] - pub enable_chunked: bool, +impl Args { + pub fn patch_config(&self, config: &mut Config) { + if let Some(v) = self.host.clone() { config.host = v } + if let Some(v) = self.name.clone() { config.name = Some(v) } + if let Some(v) = self.message_format.clone() { config.message_format = v } + if let Some(v) = self.update_time.clone() { config.update_time = v } + if let Some(v) = self.max_messages.clone() { config.max_messages = v } + if let Some(v) = self.hide_my_ip.clone() { config.hide_my_ip = v } + if let Some(v) = self.show_other_ip.clone() { config.show_other_ip = v } + if let Some(v) = self.auth_enabled.clone() { config.auth_enabled = v } + if let Some(v) = self.ssl_enabled.clone() { config.ssl_enabled = v } + if let Some(v) = self.chunked_enabled.clone() { config.chunked_enabled = v } + if let Some(v) = self.formatting_enabled.clone() { config.formatting_enabled = v } + if let Some(v) = self.commands_enabled.clone() { config.commands_enabled = v } + } } \ No newline at end of file diff --git a/src/chat/ctx.rs b/src/chat/ctx.rs index a6beb48..4fdc1f1 100644 --- a/src/chat/ctx.rs +++ b/src/chat/ctx.rs @@ -1,50 +1,63 @@ -use std::sync::{Arc, RwLock}; +use std::sync::{atomic::{AtomicUsize, Ordering}, mpsc::Sender, Arc, RwLock}; -use rand::random; - -use super::{config::{Args, Config}, gui::ask_string, ChatContext}; +use super::config::Config; pub struct Context { - pub chat: Arc>>>, - pub host: String, - pub name: String, - pub disable_formatting: bool, - pub disable_commands: bool, - pub disable_hiding_ip: bool, - pub message_format: String, - pub update_time: usize, - pub max_messages: usize, - pub enable_ip_viewing: bool, - pub enable_auth: bool, - pub enable_ssl: bool, - pub enable_chunked: bool, + pub registered: Arc>>, + pub config: Arc>, + pub sender: Arc>>>>, + pub messages: RwLock>, + pub packet_size: AtomicUsize, + pub name: String } impl Context { - pub fn new(config: &Config, args: &Args) -> Context { + pub fn new(config: &Config) -> Context { Context { - chat: Arc::new(RwLock::new(None)), - message_format: args.message_format.clone().unwrap_or(config.message_format.clone()), - host: args.host.clone().unwrap_or(config.host.clone()), - name: args.name.clone() - .or(config.name.clone()) - .unwrap_or_else(|| ask_string( - "Name", - format!("Anon#{:X}", random::()) - )), - disable_formatting: args.disable_formatting, - disable_commands: args.disable_commands, - disable_hiding_ip: args.disable_ip_hiding, - update_time: config.update_time, - max_messages: config.max_messages, - enable_ip_viewing: args.enable_users_ip_viewing || config.enable_ip_viewing, - enable_auth: args.enable_auth || config.enable_auth, - enable_ssl: args.enable_ssl || config.enable_ssl, - enable_chunked: args.enable_chunked || config.enable_chunked, + registered: Arc::new(RwLock::new(None)), + config: Arc::new(RwLock::new(config.clone())), + sender: Arc::new(RwLock::new(None)), + messages: RwLock::new(Vec::new()), + packet_size: AtomicUsize::default(), + name: config.name.clone().expect("not implemented"), // TODO: ask for name } } - pub fn chat(&self) -> Arc { - self.chat.read().unwrap().clone().unwrap() + pub fn config(&self, map: fn (&Config) -> T) -> T { + map(&self.config.read().unwrap()) } + + pub fn packet_size(&self) -> usize { + self.packet_size.load(Ordering::SeqCst) + } + + pub fn messages(&self) -> Vec { + self.messages.read().unwrap().clone() + } + + pub fn update(&self, max_length: usize, messages: Vec, packet_size: usize) { + self.packet_size.store(packet_size, Ordering::SeqCst); + let mut messages = messages; + if messages.len() > max_length { + messages.drain(max_length..); + } + *self.messages.write().unwrap() = messages; + } + + pub fn append_and_store(&self, max_length: usize, messages: Vec, packet_size: usize) { + self.packet_size.store(packet_size, Ordering::SeqCst); + self.append(max_length, messages); + } + + pub fn append(&self, max_length: usize, messages: Vec) { + self.messages.write().unwrap().append(&mut messages.clone()); + if self.messages.read().unwrap().len() > max_length { + self.messages.write().unwrap().drain(max_length..); + } + } +} + +#[macro_export] +macro_rules! connect_rac { + ($ctx:ident) => { &mut connect(&$ctx.config(|o| o.host.clone()), $ctx.config(|o| o.ssl_enabled))? }; } \ No newline at end of file diff --git a/src/chat/gui.rs b/src/chat/gui.rs index 9c232a8..fd0d4d0 100644 --- a/src/chat/gui.rs +++ b/src/chat/gui.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, RwLock, mpsc::{channel, Sender, Receiver}}; +use std::sync::{Arc, mpsc::{channel, Receiver}}; use std::cell::RefCell; use std::time::{Duration, SystemTime}; use std::error::Error; @@ -17,15 +17,9 @@ use gtk4::{ Button, Calendar, CssProvider, Entry, Fixed, Justification, Label, ListBox, Orientation, Overlay, Picture, ScrolledWindow, Settings }; -use crate::proto::{connect, read_messages}; +use crate::{connect_rac, proto::{connect, read_messages}}; -use super::{on_send_message, parse_message, set_chat, ChatStorage, ctx::Context}; - -pub struct ChatContext { - pub messages: Arc, - pub registered: Arc>>, - pub sender: Sender -} +use super::{on_send_message, parse_message, ctx::Context}; struct UiModel { chat_box: GtkBox, @@ -37,31 +31,31 @@ thread_local!( ); pub fn add_chat_message(ctx: Arc, message: String) { - let _ = ctx.chat().sender.send(message); + let _ = ctx.sender.read().unwrap().clone().unwrap().send(message); } pub fn print_message(ctx: Arc, message: String) -> Result<(), Box> { - ctx.chat().messages.append(ctx.max_messages, vec![message.clone()]); + ctx.append(ctx.config(|o| o.max_messages), vec![message.clone()]); add_chat_message(ctx.clone(), message); Ok(()) } pub fn recv_tick(ctx: Arc) -> Result<(), Box> { match read_messages( - &mut connect(&ctx.host, ctx.enable_ssl)?, - ctx.max_messages, - ctx.chat().messages.packet_size(), - !ctx.enable_ssl, - ctx.enable_chunked + connect_rac!(ctx), + ctx.config(|o| o.max_messages), + ctx.packet_size(), + !ctx.config(|o| o.ssl_enabled), + ctx.config(|o| o.chunked_enabled) ) { Ok(Some((messages, size))) => { - if ctx.enable_chunked { - ctx.chat().messages.append_and_store(ctx.max_messages, messages.clone(), size); + if ctx.config(|o| o.chunked_enabled) { + ctx.append_and_store(ctx.config(|o| o.max_messages), messages.clone(), size); for msg in messages { add_chat_message(ctx.clone(), msg.clone()); } } else { - ctx.chat().messages.update(ctx.max_messages, messages.clone(), size); + ctx.update(ctx.config(|o| o.max_messages), messages.clone(), size); for msg in messages { add_chat_message(ctx.clone(), msg.clone()); } @@ -69,37 +63,15 @@ pub fn recv_tick(ctx: Arc) -> Result<(), Box> { }, Err(e) => { let msg = format!("Read messages error: {}", e.to_string()).to_string(); - ctx.chat().messages.append(ctx.max_messages, vec![msg.clone()]); + ctx.append(ctx.config(|o| o.max_messages), vec![msg.clone()]); add_chat_message(ctx.clone(), msg.clone()); } _ => {} } - thread::sleep(Duration::from_millis(ctx.update_time as u64)); + thread::sleep(Duration::from_millis(ctx.config(|o| o.update_time) as u64)); Ok(()) } -pub fn ask_usize(name: impl ToString, default: usize) -> usize { - todo!() -} - -pub fn ask_string(name: impl ToString, default: impl ToString + Clone) -> String { - todo!() -} - -pub fn ask_string_option(name: impl ToString, default: impl ToString) -> Option { - let default = default.to_string(); - - todo!() -} - -pub fn ask_bool(name: impl ToString, default: bool) -> bool { - todo!() -} - -pub fn show_message(title: impl ToString, message: impl ToString) { - todo!() -} - fn load_pixbuf(data: &[u8]) -> Pixbuf { let loader = PixbufLoader::new(); loader.write(data).unwrap(); @@ -384,7 +356,7 @@ fn build_ui(ctx: Arc, app: &Application) -> UiModel { let window = ApplicationWindow::builder() .application(app) - .title(format!("bRAC - Connected to {} as {}", &ctx.host, &ctx.name)) + .title(format!("bRAC - Connected to {} as {}", ctx.config(|o| o.host.clone()), &ctx.name)) .default_width(500) .default_height(500) .resizable(false) @@ -418,11 +390,7 @@ fn build_ui(ctx: Arc, app: &Application) -> UiModel { fn setup(ctx: Arc, ui: UiModel) { let (sender, receiver) = channel(); - set_chat(ctx.clone(), ChatContext { - messages: Arc::new(ChatStorage::new()), - registered: Arc::new(RwLock::new(None)), - sender - }); + *ctx.sender.write().unwrap() = Some(Arc::new(sender)); thread::spawn({ let ctx = ctx.clone(); @@ -494,7 +462,7 @@ fn on_add_message(ctx: Arc, ui: &UiModel, message: String) { if let Some((date, ip, content, nick)) = parse_message(message.clone()) { if let Some(ip) = ip { - if ctx.enable_ip_viewing { + if ctx.config(|o| o.show_other_ip) { let ip = Label::builder() .label(ip) .margin_end(10) diff --git a/src/chat/mod.rs b/src/chat/mod.rs index 69d7cbd..d2179ef 100644 --- a/src/chat/mod.rs +++ b/src/chat/mod.rs @@ -1,10 +1,10 @@ use std::{ error::Error, - sync::{atomic::{AtomicUsize, Ordering}, Arc, RwLock}, + sync::Arc, time::{SystemTime, UNIX_EPOCH} }; -use crate::proto::{register_user, send_message_auth}; +use crate::{connect_rac, proto::{register_user, send_message_auth}}; use super::{ proto::{connect, read_messages, send_message, send_message_spoof_auth}, @@ -17,7 +17,6 @@ use regex::Regex; use ctx::Context; pub use gui::{ - ChatContext, print_message, run_main_loop }; @@ -41,50 +40,6 @@ pub mod config; pub mod ctx; -pub struct ChatStorage { - messages: RwLock>, - packet_size: AtomicUsize -} - -impl ChatStorage { - pub fn new() -> Self { - ChatStorage { - messages: RwLock::new(Vec::new()), - packet_size: AtomicUsize::default() - } - } - - pub fn packet_size(&self) -> usize { - self.packet_size.load(Ordering::SeqCst) - } - - pub fn messages(&self) -> Vec { - self.messages.read().unwrap().clone() - } - - pub fn update(&self, max_length: usize, messages: Vec, packet_size: usize) { - self.packet_size.store(packet_size, Ordering::SeqCst); - let mut messages = messages; - if messages.len() > max_length { - messages.drain(max_length..); - } - *self.messages.write().unwrap() = messages; - } - - pub fn append_and_store(&self, max_length: usize, messages: Vec, packet_size: usize) { - self.packet_size.store(packet_size, Ordering::SeqCst); - self.append(max_length, messages); - } - - pub fn append(&self, max_length: usize, messages: Vec) { - self.messages.write().unwrap().append(&mut messages.clone()); - if self.messages.read().unwrap().len() > max_length { - self.messages.write().unwrap().drain(max_length..); - } - } -} - - const HELP_MESSAGE: &str = "Help message: /help - show help message /register password - register user @@ -111,14 +66,14 @@ pub fn on_command(ctx: Arc, command: &str) -> Result<(), Box let Some(times) = args.get(0) else { return Ok(()) }; let times = times.parse()?; for _ in 0..times { - send_message(&mut connect(&ctx.host, ctx.enable_ssl)?, "\r")?; + send_message(connect_rac!(ctx), "\r")?; } } else if command == "spam" { let Some(times) = args.get(0) else { return Ok(()) }; let times = times.parse()?; let msg = args[1..].join(" "); for _ in 0..times { - send_message(&mut connect(&ctx.host, ctx.enable_ssl)?, &("\r".to_string()+&msg))?; + send_message(connect_rac!(ctx), &("\r".to_string()+&msg))?; } } else if command == "help" { add_message(ctx.clone(), HELP_MESSAGE)?; @@ -128,10 +83,10 @@ pub fn on_command(ctx: Arc, command: &str) -> Result<(), Box return Ok(()) }; - match register_user(&mut connect(&ctx.host, ctx.enable_ssl)?, &ctx.name, pass) { + match register_user(connect_rac!(ctx), &ctx.name, pass) { Ok(true) => { add_message(ctx.clone(), "you was registered successfully bro")?; - *ctx.chat().registered.write().unwrap() = Some(pass.to_string()); + *ctx.registered.write().unwrap() = Some(pass.to_string()); }, Ok(false) => add_message(ctx.clone(), "user with this account already exists bruh")?, Err(e) => add_message(ctx.clone(), &format!("ERROR while registrationing: {}", e))? @@ -143,22 +98,22 @@ pub fn on_command(ctx: Arc, command: &str) -> Result<(), Box }; add_message(ctx.clone(), "ye bro you was logged in")?; - *ctx.chat().registered.write().unwrap() = Some(pass.to_string()); + *ctx.registered.write().unwrap() = Some(pass.to_string()); } else if command == "ping" { - let mut before = ctx.chat().messages.packet_size(); + let mut before = ctx.packet_size(); let message = format!("Checking ping... {:X}", SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis()); - send_message(&mut connect(&ctx.host, ctx.enable_ssl)?, &message)?; + send_message(connect_rac!(ctx), &message)?; let start = SystemTime::now(); loop { let data = read_messages( - &mut connect(&ctx.host, ctx.enable_ssl)?, - ctx.max_messages, + connect_rac!(ctx), + ctx.config(|o| o.max_messages), before, - !ctx.enable_ssl, - ctx.enable_chunked + !ctx.config(|o| o.ssl_enabled), + ctx.config(|o| o.chunked_enabled) ).ok().flatten(); if let Some((data, size)) = data { @@ -182,16 +137,16 @@ pub fn on_command(ctx: Arc, command: &str) -> Result<(), Box Ok(()) } -pub fn prepare_message(context: Arc, message: &str) -> String { +pub fn prepare_message(ctx: Arc, message: &str) -> String { format!("{}{}{}", - if !context.disable_hiding_ip { + if ctx.config(|o| o.hide_my_ip) { "\r\x07" } else { "" }, message, - if !context.disable_hiding_ip { - let spaces = if context.enable_auth { + if !ctx.config(|o| o.hide_my_ip) { + let spaces = if ctx.config(|o| o.auth_enabled) { 39 } else { 54 @@ -209,22 +164,22 @@ pub fn prepare_message(context: Arc, message: &str) -> String { } pub fn on_send_message(ctx: Arc, message: &str) -> Result<(), Box> { - if message.starts_with("/") && !ctx.disable_commands { + if message.starts_with("/") && ctx.config(|o| o.commands_enabled) { on_command(ctx.clone(), &message)?; } else { let message = prepare_message( ctx.clone(), - &ctx.message_format + &ctx.config(|o| o.message_format.clone()) .replace("{name}", &ctx.name) .replace("{text}", &message) ); - if let Some(password) = ctx.chat().registered.read().unwrap().clone() { - send_message_auth(&mut connect(&ctx.host, ctx.enable_ssl)?, &ctx.name, &password, &message)?; - } else if ctx.enable_auth { - send_message_spoof_auth(&mut connect(&ctx.host, ctx.enable_ssl)?, &message)?; + if let Some(password) = ctx.registered.read().unwrap().clone() { + send_message_auth(connect_rac!(ctx), &ctx.name, &password, &message)?; + } else if ctx.config(|o| o.auth_enabled) { + send_message_spoof_auth(connect_rac!(ctx), &message)?; } else { - send_message(&mut connect(&ctx.host, ctx.enable_ssl)?, &message)?; + send_message(connect_rac!(ctx), &message)?; } } @@ -274,8 +229,4 @@ pub fn find_username_color(message: &str) -> Option<(String, String, String)> { } } None -} - -pub fn set_chat(ctx: Arc, chat: ChatContext) { - *ctx.chat.write().unwrap() = Some(Arc::new(chat)); } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 8cc7d13..9b1fbae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use bRAC::proto::{connect, read_messages, send_message}; -use bRAC::chat::{config::{configure, get_config_path, load_config, Args}, ctx::Context, run_main_loop}; +use bRAC::chat::{config::{get_config_path, load_config, Args}, ctx::Context, run_main_loop}; use clap::Parser; @@ -15,22 +15,16 @@ fn main() { return; } - if args.configure { - configure(config_path); - return; - } - - let config = load_config(config_path); - - let ctx = Arc::new(Context::new(&config, &args)); + let mut config = load_config(config_path); if args.read_messages { - let mut stream = connect(&ctx.host, ctx.enable_ssl).expect("Error reading message"); + let mut stream = connect(&config.host, config.ssl_enabled).expect("Error reading message"); + print!("{}", read_messages( &mut stream, - ctx.max_messages, + config.max_messages, 0, - !ctx.enable_ssl, + !config.ssl_enabled, false ) .ok().flatten() @@ -39,12 +33,21 @@ fn main() { } if let Some(message) = &args.send_message { - send_message(&mut connect(&ctx.host, ctx.enable_ssl).expect("Error sending message"), message).expect("Error sending message"); + let mut stream = connect(&config.host, config.ssl_enabled).expect("Error sending message"); + + send_message( + &mut stream, + message + ).expect("Error sending message"); } if args.send_message.is_some() || args.read_messages { return; } + args.patch_config(&mut config); + + let ctx = Arc::new(Context::new(&config)); + run_main_loop(ctx.clone()); }