refactor client to lib code; abstract default port
This commit is contained in:
parent
c67f358d4a
commit
60b5013337
@ -1,44 +1,12 @@
|
|||||||
use prompted::input;
|
use prompted::input;
|
||||||
use rust_irc::{clear, codes};
|
use rust_irc::{clear, codes, one_op_buf, one_param_buf, two_param_buf, DEFAULT_PORT};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
fn no_param_op(opcode: u8, stream: &mut TcpStream) {
|
const DEFAULT_HOST: &str = "localhost";
|
||||||
stream.write_all(&[opcode]).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn one_param_op(opcode: u8, stream: &mut TcpStream, param: &str) {
|
|
||||||
let size: usize = param.to_string().capacity() + 1;
|
|
||||||
let mut out_buf: Vec<u8> = vec![0; size];
|
|
||||||
out_buf[0] = opcode;
|
|
||||||
|
|
||||||
for i in 1..param.len() + 1 {
|
|
||||||
out_buf[i] = *param.as_bytes().get(i - 1).unwrap();
|
|
||||||
}
|
|
||||||
stream.write_all(&out_buf).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn two_param_op(opcode: u8, stream: &mut TcpStream, param0: &str, param1: &str) {
|
|
||||||
let size: usize = param0.to_string().capacity() + param1.to_string().capacity() + 2;
|
|
||||||
let mut out_buf: Vec<u8> = vec![0; size];
|
|
||||||
let mut byte: usize = 0;
|
|
||||||
out_buf[byte] = opcode;
|
|
||||||
byte += 1;
|
|
||||||
for i in 0..param0.len() {
|
|
||||||
out_buf[byte] = *param0.as_bytes().get(i).unwrap();
|
|
||||||
byte += 1;
|
|
||||||
}
|
|
||||||
out_buf[byte] = 0x20;
|
|
||||||
byte += 1;
|
|
||||||
for i in 0..param1.len() {
|
|
||||||
out_buf[byte] = *param1.as_bytes().get(i).unwrap();
|
|
||||||
byte += 1;
|
|
||||||
}
|
|
||||||
stream.write_all(&out_buf).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_messages(mut stream: TcpStream, nick: &str, timestamp: &mut Arc<Mutex<Instant>>) {
|
fn read_messages(mut stream: TcpStream, nick: &str, timestamp: &mut Arc<Mutex<Instant>>) {
|
||||||
let mut buffer: [u8; 1024] = [0; 1024];
|
let mut buffer: [u8; 1024] = [0; 1024];
|
||||||
@ -49,7 +17,7 @@ fn read_messages(mut stream: TcpStream, nick: &str, timestamp: &mut Arc<Mutex<In
|
|||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
Ok(size) => {
|
Ok(size) => {
|
||||||
let mut lock = timestamp.lock().unwrap();
|
let mut lock: std::sync::MutexGuard<'_, Instant> = timestamp.lock().unwrap();
|
||||||
*lock = Instant::now();
|
*lock = Instant::now();
|
||||||
let msg_bytes: &[u8] = &buffer[..size];
|
let msg_bytes: &[u8] = &buffer[..size];
|
||||||
process_message(msg_bytes, nick);
|
process_message(msg_bytes, nick);
|
||||||
@ -94,7 +62,7 @@ fn process_message(msg_bytes: &[u8], nick: &str) {
|
|||||||
println!("[server]:{}", message);
|
println!("[server]:{}", message);
|
||||||
}
|
}
|
||||||
codes::MESSAGE_ROOM => {
|
codes::MESSAGE_ROOM => {
|
||||||
let params = String::from_utf8(msg_bytes[1..msg_bytes.len()].to_vec()).unwrap();
|
let params: String = String::from_utf8(msg_bytes[1..msg_bytes.len()].to_vec()).unwrap();
|
||||||
match params.split_once(' ') {
|
match params.split_once(' ') {
|
||||||
Some((room, remainder)) => match remainder.split_once(' ') {
|
Some((room, remainder)) => match remainder.split_once(' ') {
|
||||||
Some((user, msg)) => {
|
Some((user, msg)) => {
|
||||||
@ -122,8 +90,7 @@ fn process_message(msg_bytes: &[u8], nick: &str) {
|
|||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
#[cfg(debug_assertions)]
|
eprintln!("BAD RESPONSE = {:x?} ", msg_bytes[0]);
|
||||||
println!("BAD RESPONSE = {:x?} ", msg_bytes[0]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,10 +127,14 @@ pub fn start() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let host: String = input!("Enter the server host: ");
|
let mut host: String = input!("Enter the server host (empty for {}): ", DEFAULT_HOST);
|
||||||
|
if host.is_empty() {
|
||||||
if let Ok(mut stream) = TcpStream::connect(host.to_owned() + ":6667") {
|
host = DEFAULT_HOST.to_owned();
|
||||||
println!("Connected to {}. /help to see available commands", host);
|
}
|
||||||
|
host.push(':');
|
||||||
|
host.push_str(&DEFAULT_PORT.to_string());
|
||||||
|
if let Ok(mut stream) = TcpStream::connect(host.to_owned()) {
|
||||||
|
println!("Connected to {}.\n/help to see available commands", host);
|
||||||
|
|
||||||
//another stream for reading messages
|
//another stream for reading messages
|
||||||
let reader_clone: TcpStream = stream.try_clone().expect("Failed to clone stream");
|
let reader_clone: TcpStream = stream.try_clone().expect("Failed to clone stream");
|
||||||
@ -192,8 +163,8 @@ pub fn start() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//try to register the nickname
|
//try to register the nickname
|
||||||
one_param_op(codes::REGISTER_NICK, &mut stream, &nick);
|
let nick_reg_buff: Vec<u8> = one_param_buf(codes::REGISTER_NICK, &nick);
|
||||||
|
stream.write_all(&nick_reg_buff).unwrap();
|
||||||
loop {
|
loop {
|
||||||
let inp: String = input!("");
|
let inp: String = input!("");
|
||||||
|
|
||||||
@ -204,7 +175,8 @@ pub fn start() {
|
|||||||
eprintln!("Malformaed. Try /list [room-name]");
|
eprintln!("Malformaed. Try /list [room-name]");
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
one_param_op(codes::LIST_USERS_IN_ROOM, &mut stream, param);
|
let out_buf: Vec<u8> = one_param_buf(codes::LIST_USERS_IN_ROOM, param);
|
||||||
|
stream.write_all(&out_buf).unwrap();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/join" => match param.split_once(' ') {
|
"/join" => match param.split_once(' ') {
|
||||||
@ -212,7 +184,8 @@ pub fn start() {
|
|||||||
eprintln!("Malformed. Try /join [room-name]");
|
eprintln!("Malformed. Try /join [room-name]");
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
one_param_op(codes::JOIN_ROOM, &mut stream, param);
|
let out_buf: Vec<u8> = one_param_buf(codes::JOIN_ROOM, param);
|
||||||
|
stream.write_all(&out_buf).unwrap();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -221,18 +194,23 @@ pub fn start() {
|
|||||||
eprintln!("Malformed. Try /leave [room-name]");
|
eprintln!("Malformed. Try /leave [room-name]");
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
one_param_op(codes::LEAVE_ROOM, &mut stream, param);
|
let out_buf: Vec<u8> = one_param_buf(codes::LEAVE_ROOM, param);
|
||||||
|
stream.write_all(&out_buf).unwrap();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/msg" => match param.split_once(' ') {
|
"/msg" => match param.split_once(' ') {
|
||||||
Some((room, msg)) => {
|
Some((room, msg)) => {
|
||||||
two_param_op(codes::MESSAGE_ROOM, &mut stream, room, msg);
|
let out_buf = two_param_buf(codes::MESSAGE_ROOM, room, msg);
|
||||||
|
stream.write_all(&out_buf).unwrap();
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
eprintln!("Usage: /msg [room] [message]");
|
eprintln!("Usage: /msg [room] [message]");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => one_param_op(codes::MESSAGE, &mut stream, &inp),
|
_ => {
|
||||||
|
let out_buf: Vec<u8> = one_param_buf(codes::MESSAGE, &inp);
|
||||||
|
stream.write_all(&out_buf).unwrap();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_ => match inp.as_str() {
|
_ => match inp.as_str() {
|
||||||
@ -240,15 +218,24 @@ pub fn start() {
|
|||||||
disconnect(&mut stream);
|
disconnect(&mut stream);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
"/rooms" => no_param_op(codes::LIST_ROOMS, &mut stream),
|
"/rooms" => {
|
||||||
"/users" => no_param_op(codes::LIST_USERS, &mut stream),
|
let out_buf: [u8; 1] = one_op_buf(codes::LIST_ROOMS);
|
||||||
|
stream.write_all(&out_buf).unwrap();
|
||||||
|
}
|
||||||
|
"/users" => {
|
||||||
|
let out_buf: [u8; 1] = one_op_buf(codes::LIST_USERS);
|
||||||
|
stream.write_all(&out_buf).unwrap();
|
||||||
|
}
|
||||||
"/help" => {
|
"/help" => {
|
||||||
help();
|
help();
|
||||||
}
|
}
|
||||||
"/" => {
|
"/" => {
|
||||||
println!("Invalid command");
|
eprintln!("Invalid command");
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let out_buf: Vec<u8> = one_param_buf(codes::MESSAGE, &inp);
|
||||||
|
stream.write_all(&out_buf).unwrap();
|
||||||
}
|
}
|
||||||
_ => one_param_op(codes::MESSAGE, &mut stream, &inp),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,8 @@ pub mod codes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const DEFAULT_PORT: u16 = 6667;
|
||||||
|
|
||||||
pub fn clear() {
|
pub fn clear() {
|
||||||
print!("\x1B[2J");
|
print!("\x1B[2J");
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,9 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use prompted::input;
|
use prompted::input;
|
||||||
use rust_irc::{clear, codes, one_op_buf, one_param_buf, three_param_buf, two_op_buf};
|
use rust_irc::{
|
||||||
|
clear, codes, one_op_buf, one_param_buf, three_param_buf, two_op_buf, DEFAULT_PORT,
|
||||||
const SERVER_ADDRESS: &str = "0.0.0.0:6667";
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Server {
|
struct Server {
|
||||||
@ -66,7 +66,6 @@ fn message_room(room: &str, msg: &str, sender: &str, server: &Arc<Mutex<Server>>
|
|||||||
let recipient_stream: Option<&mut TcpStream> = server.users.get_mut(user);
|
let recipient_stream: Option<&mut TcpStream> = server.users.get_mut(user);
|
||||||
match recipient_stream {
|
match recipient_stream {
|
||||||
Some(str) => {
|
Some(str) => {
|
||||||
println!("Sending msg {:?}", out_buf.to_ascii_lowercase());
|
|
||||||
str.write_all(&out_buf).unwrap();
|
str.write_all(&out_buf).unwrap();
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
@ -227,7 +226,7 @@ fn message_all_senders_rooms(
|
|||||||
let mut guard: std::sync::MutexGuard<'_, Server> = server.lock().unwrap();
|
let mut guard: std::sync::MutexGuard<'_, Server> = server.lock().unwrap();
|
||||||
for room in rooms {
|
for room in rooms {
|
||||||
let users: Vec<String> = guard.rooms.get(&room).unwrap().clone();
|
let users: Vec<String> = guard.rooms.get(&room).unwrap().clone();
|
||||||
let out_buf: Vec<u8> = three_param_buf(codes::MESSAGE_ROOM, &room, &sender, &message);
|
let out_buf: Vec<u8> = three_param_buf(codes::MESSAGE_ROOM, &room, sender, message);
|
||||||
for user in users {
|
for user in users {
|
||||||
if !user.eq(sender) {
|
if !user.eq(sender) {
|
||||||
let stream: Option<&mut TcpStream> = guard.users.get_mut(&user);
|
let stream: Option<&mut TcpStream> = guard.users.get_mut(&user);
|
||||||
@ -339,8 +338,8 @@ fn get_rooms_of_user(server: &Arc<Mutex<Server>>, user: &str) -> Vec<String> {
|
|||||||
let mut result: Vec<String> = vec![];
|
let mut result: Vec<String> = vec![];
|
||||||
let guard: std::sync::MutexGuard<'_, Server> = server.lock().unwrap();
|
let guard: std::sync::MutexGuard<'_, Server> = server.lock().unwrap();
|
||||||
let rooms: std::collections::hash_map::Keys<'_, String, Vec<String>> = guard.rooms.keys();
|
let rooms: std::collections::hash_map::Keys<'_, String, Vec<String>> = guard.rooms.keys();
|
||||||
rooms.for_each(|room| {
|
rooms.for_each(|room: &String| {
|
||||||
let user_vec = guard.rooms.get(room).unwrap();
|
let user_vec: &Vec<String> = guard.rooms.get(room).unwrap();
|
||||||
for usr in user_vec {
|
for usr in user_vec {
|
||||||
if usr.eq(user) {
|
if usr.eq(user) {
|
||||||
result.push(room.to_string());
|
result.push(room.to_string());
|
||||||
@ -352,13 +351,15 @@ fn get_rooms_of_user(server: &Arc<Mutex<Server>>, user: &str) -> Vec<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn start() {
|
pub fn start() {
|
||||||
let listener_result: Result<TcpListener, std::io::Error> = TcpListener::bind(SERVER_ADDRESS);
|
let mut host: String = "0.0.0.0:".to_string();
|
||||||
|
host.push_str(&DEFAULT_PORT.to_string());
|
||||||
|
let listener_result: Result<TcpListener, std::io::Error> = TcpListener::bind(host.to_owned());
|
||||||
match listener_result {
|
match listener_result {
|
||||||
Ok(listener) => {
|
Ok(listener) => {
|
||||||
let server: Arc<Mutex<Server>> = Arc::new(Mutex::new(Server::new()));
|
let server: Arc<Mutex<Server>> = Arc::new(Mutex::new(Server::new()));
|
||||||
let server_outer: Arc<Mutex<Server>> = Arc::clone(&server);
|
let server_outer: Arc<Mutex<Server>> = Arc::clone(&server);
|
||||||
clear();
|
clear();
|
||||||
println!("Server listening on {}", SERVER_ADDRESS);
|
println!("Server listening on {}", host);
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
for tcpstream in listener.incoming() {
|
for tcpstream in listener.incoming() {
|
||||||
|
Reference in New Issue
Block a user