fix console and other stuff

This commit is contained in:
MeexReay 2025-02-09 14:28:34 +03:00
parent 881b253e07
commit 8b64a2e1c3
7 changed files with 449 additions and 143 deletions

2
.gitignore vendored
View File

@ -1,3 +1 @@
main
main.exe
/target /target

282
Cargo.lock generated
View File

@ -5,3 +5,285 @@ version = 4
[[package]] [[package]]
name = "bRAC" name = "bRAC"
version = "1.99.2" version = "1.99.2"
dependencies = [
"rand",
"termion",
]
[[package]]
name = "bitflags"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "getrandom"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
dependencies = [
"cfg-if",
"libc",
"wasi",
"windows-targets",
]
[[package]]
name = "libc"
version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "libredox"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags",
"libc",
"redox_syscall",
]
[[package]]
name = "numtoa"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aa2c4e539b869820a2b82e1aef6ff40aa85e65decdd5185e83fb4b1249cd00f"
[[package]]
name = "ppv-lite86"
version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
dependencies = [
"zerocopy 0.7.35",
]
[[package]]
name = "proc-macro2"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
dependencies = [
"rand_chacha",
"rand_core",
"zerocopy 0.8.17",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
dependencies = [
"getrandom",
"zerocopy 0.8.17",
]
[[package]]
name = "redox_syscall"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_termios"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20145670ba436b55d91fc92d25e71160fbfbdd57831631c8d7d36377a476f1cb"
[[package]]
name = "syn"
version = "2.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "termion"
version = "4.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eaa98560e51a2cf4f0bb884d8b2098a9ea11ecf3b7078e9c68242c74cc923a7"
dependencies = [
"libc",
"libredox",
"numtoa",
"redox_termios",
]
[[package]]
name = "unicode-ident"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
[[package]]
name = "wasi"
version = "0.13.3+wasi-0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
dependencies = [
"wit-bindgen-rt",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "wit-bindgen-rt"
version = "0.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
dependencies = [
"bitflags",
]
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"byteorder",
"zerocopy-derive 0.7.35",
]
[[package]]
name = "zerocopy"
version = "0.8.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa91407dacce3a68c56de03abe2760159582b846c6a4acd2f456618087f12713"
dependencies = [
"zerocopy-derive 0.8.17",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06718a168365cad3d5ff0bb133aad346959a2074bd4a85c121255a11304a8626"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View File

@ -4,7 +4,5 @@ version = "1.99.2"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
rand = "0.9.0"
[[bin]] termion = "4.0.3"
name = "bRAC"
path = "main.rs"

View File

@ -4,8 +4,6 @@ better RAC client
## how to use ## how to use
```bash ```bash
rustc main.rs # build cargo build # build
./main # run cargo run # run
cargo build # build with cargo
cargo run # run with cargo
``` ```

133
main.rs
View File

@ -1,133 +0,0 @@
use std::{error::Error, fmt::format, io::{stdin, stdout, BufRead, Read, Write}, net::TcpStream, thread, time::{self, SystemTime, UNIX_EPOCH}};
const MAX_MESSAGES: usize = 100;
const DEFAULT_HOST: &str = "meex.lol:11234";
fn send_message(host: &str, message: &str) -> Result<(), Box<dyn Error>> {
let mut stream = TcpStream::connect(host)?;
stream.write_all(&[0x01])?;
stream.write_all(message.as_bytes())?;
stream.write_all("\0".repeat(1023 - message.len()).as_bytes())?;
Ok(())
}
fn read_messages(host: &str, skip: usize) -> Result<String, Box<dyn Error>> {
let mut stream = TcpStream::connect(host)?;
stream.write_all(&[0x00])?;
let packet_size = {
let mut data = Vec::new();
loop {
let mut buf = vec![0; 1];
stream.read_exact(&mut buf)?;
let ch = buf[0];
if ch == 0 {
break
}
data.push(ch);
}
String::from_utf8(data)?
.trim_matches(char::from(0))
.parse()?
};
// println!("{} {}", skip, packet_size);
if packet_size <= skip {
return Ok(String::new())
}
let to_read = if skip == 0 {
stream.write_all(&[0x01])?;
packet_size
} else {
stream.write_all(&[0x02])?;
stream.write_all(skip.to_string().as_bytes())?;
packet_size - skip
};
let packet_data = {
let mut data = vec![0; to_read];
stream.read_exact(&mut data)?;
data.retain(|x| *x != 0);
while String::from_utf8_lossy(&data).len() != to_read {
let mut buf = vec![0; to_read - data.len()];
stream.read_exact(&mut buf)?;
data.append(&mut buf);
data.retain(|x| *x != 0);
}
String::from_utf8_lossy(&data).to_string()
};
// println!("{}", packet_data);
Ok(packet_data)
}
fn print_console(messages: Vec<&str>) -> Result<(), Box<dyn Error>> {
let mut messages = messages.clone();
messages.reverse();
messages.truncate(MAX_MESSAGES);
messages.reverse();
let mut out = stdout().lock();
let text = format!("{}{}\n> ", "\n".repeat(MAX_MESSAGES - messages.len()), messages.join("\n"));
out.write_all(text.as_bytes())?;
out.flush()?;
Ok(())
}
fn recv_loop(host: &str) -> Result<(), Box<dyn Error>> {
let mut cache = String::new();
while let Ok(messages) = read_messages(host, cache.len()) {
if messages.len() == 0 { continue }
cache.push_str(&messages);
print_console(cache.split("\n").collect())?;
}
Ok(())
}
fn get_input(prompt: &str, default: &str) -> String {
let input = || -> Option<String> {
let mut out = stdout().lock();
out.write_all(prompt.as_bytes()).ok()?;
out.flush().ok()?;
stdin().lock().lines().next()
.map(|o| o.ok())
.flatten()
}();
if let Some(input) = &input {
if input.is_empty() {
default
} else {
input
}
} else {
default
}.to_string()
}
fn main() {
let host = get_input(&format!("Host (default: {}) > ", DEFAULT_HOST), DEFAULT_HOST);
let anon_name = format!("Anon#{:X}", SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs());
let name = get_input(&format!("Name (default: {}) > ", anon_name), &anon_name);
thread::spawn({
let host = host.clone();
move || {
let _ = recv_loop(&host);
println!("Connection closed");
}
});
let mut lines = stdin().lock().lines();
while let Some(Ok(message)) = lines.next() {
send_message(&host, &format!("<{}> {}", &name, &message)).expect("Error sending message");
}
}

162
src/main.rs Normal file
View File

@ -0,0 +1,162 @@
use std::{error::Error, fmt::format, fs, io::{stdin, stdout, BufRead, Read, Write}, net::TcpStream, sync::{Arc, RwLock}, thread, time::{self, Duration, SystemTime, UNIX_EPOCH}};
use rand::random;
use termion::{event::Key, input::TermRead, raw::IntoRawMode};
const MAX_MESSAGES: usize = 100;
const DEFAULT_HOST: &str = "meex.lol:11234";
fn send_message(host: &str, message: &str) -> Result<(), Box<dyn Error>> {
let mut stream = TcpStream::connect(host)?;
stream.write_all(&[0x01])?;
stream.write_all(message.as_bytes())?;
stream.write_all("\0".repeat(1023 - message.len()).as_bytes())?;
Ok(())
}
fn skip_null(stream: &mut TcpStream) -> Result<Vec<u8>, Box<dyn Error>> {
loop {
let mut buf = vec![0; 1];
stream.read_exact(&mut buf)?;
if buf[0] != 0 {
break Ok(buf)
}
}
}
fn read_messages(host: &str) -> Result<String, Box<dyn Error>> {
let mut stream = TcpStream::connect(host)?;
stream.write_all(&[0x00])?;
let packet_size = {
let mut data = skip_null(&mut stream)?;
loop {
let mut buf = vec![0; 1];
stream.read_exact(&mut buf)?;
let ch = buf[0];
if ch == 0 {
break
}
data.push(ch);
}
String::from_utf8(data)?
.trim_matches(char::from(0))
.parse()?
};
// println!("{} {}", skip, packet_size);
stream.write_all(&[0x01])?;
let packet_data = {
let mut data = skip_null(&mut stream)?;
while data.len() < packet_size {
let mut buf = vec![0; packet_size - data.len()];
let read_bytes = stream.read(&mut buf)?;
buf.truncate(read_bytes);
data.append(&mut buf);
}
String::from_utf8_lossy(&data).to_string()
};
Ok(packet_data)
}
fn recv_loop(host: &str, cache: Arc<RwLock<String>>, input: Arc<RwLock<String>>) -> Result<(), Box<dyn Error>> {
while let Ok(data) = read_messages(host) {
if data == cache.read().unwrap().clone() {
continue
}
*cache.write().unwrap() = data;
print_console(&cache.read().unwrap(), &input.read().unwrap())?;
}
Ok(())
}
fn get_input(prompt: &str, default: &str) -> String {
let input = || -> Option<String> {
let mut out = stdout().lock();
out.write_all(prompt.as_bytes()).ok()?;
out.flush().ok()?;
stdin().lock().lines().next()
.map(|o| o.ok())
.flatten()
}();
if let Some(input) = &input {
if input.is_empty() {
default
} else {
input
}
} else {
default
}.to_string()
}
fn print_console(messages: &str, input: &str) -> Result<(), Box<dyn Error>> {
let mut messages = messages.split("\n")
.map(|o| o.to_string())
.collect::<Vec<String>>();
messages.reverse();
messages.truncate(MAX_MESSAGES);
messages.reverse();
let mut out = stdout().into_raw_mode()?;
let text = format!("{}{}\n> {}", "\n".repeat(MAX_MESSAGES - messages.len()), messages.join("\n"), input);
for line in text.lines() {
write!(out, "\r\n{}", line)?;
out.flush()?;
}
Ok(())
}
fn main() {
let host = get_input(&format!("Host (default: {}) > ", DEFAULT_HOST), DEFAULT_HOST);
let anon_name = format!("Anon#{:X}", random::<u16>());
let name = get_input(&format!("Name (default: {}) > ", anon_name), &anon_name);
let messages = Arc::new(RwLock::new(String::new()));
let input = Arc::new(RwLock::new(String::new()));
thread::spawn({
let host = host.clone();
let messages = messages.clone();
let input = input.clone();
move || {
let _ = recv_loop(&host, messages, input);
println!("Connection closed");
}
});
let stdout = stdout().into_raw_mode().unwrap();
let stdin = stdin();
for key in stdin.keys() {
match key.unwrap() {
Key::Char('\n') => {
let message = input.read().unwrap().clone();
if !message.is_empty() {
send_message(&host, &format!("<{}> {}", name, message)).expect("Error sending message");
input.write().unwrap().clear();
}
}
Key::Backspace => {
input.write().unwrap().pop();
}
Key::Char(c) => {
input.write().unwrap().push(c);
}
Key::Esc => break,
Key::Ctrl('c') => break,
Key::Ctrl('z') => break,
Key::Ctrl('x') => break,
_ => {}
}
print_console(&messages.read().unwrap(), &input.read().unwrap()).expect("Error printing console");
}
}

1
test.txt Normal file
View File

@ -0,0 +1 @@
[2025-02-09 10:40:02] {192.168.0.201} <MrSugoma> Извините, я при ап<D0B0>