feat: add missing message handlers

This commit is contained in:
michel
2024-09-13 20:58:04 +02:00
committed by Michel de Graaf
parent 6281b0c89e
commit 10f4a34ae4
34 changed files with 1889 additions and 564 deletions
-60
View File
@@ -1,60 +0,0 @@
use super::Message;
pub fn build_init_message() -> Message {
let mut message = Message::new();
message.write_int32(81); // need to send as first message?
message
}
pub fn build_login_message(username: &str, password: &str) -> Message {
let mut hasher = md5::Context::new();
hasher.consume(username);
hasher.consume(password);
let hash = format!("{:x}", hasher.compute());
let hash_str = hash.as_str();
let mut message = Message::new();
message
.write_int32(1)
.write_string(username)
.write_string(password)
.write_int32(160) // version
.write_string(hash_str)
.write_int32(17);
message
}
pub fn build_shared_folders_message(folder_count: i32, file_count: i32) -> Message {
let mut message = Message::new();
message
.write_int32(35)
.write_int32(folder_count)
.write_int32(file_count);
message
}
#[test]
fn test_build_init_message() {
let message = build_init_message();
let expect: Vec<u8> = [81, 0, 0, 0].to_vec();
assert_eq!(expect, message.get_data())
}
#[test]
fn test_build_login_message() {
let message = build_login_message("username", "password");
let expect: Vec<u8> = [
1, 0, 0, 0, 8, 0, 0, 0, 117, 115, 101, 114, 110, 97, 109, 101, 8, 0, 0, 0, 112, 97, 115,
115, 119, 111, 114, 100, 160, 0, 0, 0, 32, 0, 0, 0, 100, 53, 49, 99, 57, 97, 55, 101, 57,
51, 53, 51, 55, 52, 54, 97, 54, 48, 50, 48, 102, 57, 54, 48, 50, 100, 52, 53, 50, 57, 50,
57, 17, 0, 0, 0,
]
.to_vec();
assert_eq!(expect, message.get_data())
}
+56
View File
@@ -0,0 +1,56 @@
use std::collections::HashMap;
use crate::{message::Message, server::ServerOperation};
use std::sync::mpsc::Sender;
use super::server::{
ConnectToPeerHandler, ExcludedSearchPhrasesHandler, FileSearch, LoginHandler, MessageUser,
ParentMinSpeedHandler, ParentSpeedRatioHandler, PrivilegedUsersHandler, RoomListHandler,
WishListIntervalHandler,
};
pub trait MessageHandler {
fn get_code(&self) -> u8;
fn handle(&self, message: &mut Message, sender: Sender<ServerOperation>);
}
pub struct Handlers {
handlers: HashMap<u8, Box<dyn MessageHandler>>,
}
impl Handlers {
pub fn new() -> Self {
Self {
handlers: HashMap::new(),
}
}
pub fn new_with_server_handlers() -> Self {
let mut handlers = Self::new();
handlers.add_server_handlers();
handlers
}
fn add_server_handlers(&mut self) {
self.register_handler(LoginHandler);
self.register_handler(RoomListHandler);
self.register_handler(ExcludedSearchPhrasesHandler);
self.register_handler(PrivilegedUsersHandler);
self.register_handler(MessageUser);
self.register_handler(WishListIntervalHandler);
self.register_handler(ParentMinSpeedHandler);
self.register_handler(ParentSpeedRatioHandler);
self.register_handler(PrivilegedUsersHandler);
self.register_handler(FileSearch);
self.register_handler(ConnectToPeerHandler);
}
pub fn register_handler<H: 'static + MessageHandler + Send + Sync>(
&mut self,
handler: H,
) -> &mut Self {
self.handlers.insert(handler.get_code(), Box::new(handler));
self
}
pub fn get_handler(&self, code: u8) -> Option<&Box<dyn MessageHandler>> {
self.handlers.get(&code)
}
}
-24
View File
@@ -1,24 +0,0 @@
use std::sync::{Arc, Mutex};
use crate::{
dispatcher::MessageHandler,
message::{factory::build_shared_folders_message, Message},
server::Context,
};
pub struct LoginHandler;
impl MessageHandler for LoginHandler {
fn handle(&self, message: &mut Message, context: Arc<Mutex<Context>>) {
let response = message.read_int8();
if response == 1 {
println!("Login successful");
let greeting = message.read_string();
println!("Server geeting: {:?}", greeting);
// Build the shared folders message and queue it
let shared_message = build_shared_folders_message(1, 1);
context.lock().unwrap().queue_message(shared_message);
} else {
println!("Login failed");
}
}
}
-4
View File
@@ -1,4 +0,0 @@
pub mod excluded_search_phrases;
pub mod login;
pub mod privileged_users;
pub mod room_list;
-11
View File
@@ -1,11 +0,0 @@
use std::sync::{Arc, Mutex};
use crate::{dispatcher::MessageHandler, message::Message, server::Context};
pub struct PrivilegedUsersHandler;
impl MessageHandler for PrivilegedUsersHandler {
fn handle(&self, message: &mut Message, _context: Arc<Mutex<Context>>) {
let number = message.read_int32();
println!("Number of privilaged users: {}", number);
}
}
-60
View File
@@ -1,60 +0,0 @@
use crate::{
dispatcher::MessageHandler,
message::Message,
server::{Context, Room},
};
use std::sync::{Arc, Mutex};
pub struct RoomListHandler;
impl MessageHandler for RoomListHandler {
fn handle(&self, message: &mut Message, context: Arc<Mutex<Context>>) {
let mut binding = context.lock().unwrap();
let rooms = binding.get_rooms();
let num_public_rooms = message.read_int32();
for _ in 0..num_public_rooms {
rooms.public_rooms.push(Room::new(message.read_string(), 0));
}
let num_public_rooms = message.read_int32();
for i in 0..num_public_rooms {
rooms.public_rooms[i as usize].set_number_of_users(message.read_int32());
}
let num_owned_private_rooms = message.read_int32();
for _ in 0..num_owned_private_rooms {
rooms
.owned_private_rooms
.push(Room::new(message.read_string(), 0));
}
let num_owned_private_rooms = message.read_int32();
for i in 0..num_owned_private_rooms {
rooms.owned_private_rooms[i as usize].set_number_of_users(message.read_int32());
}
let num_private_rooms = message.read_int32();
for _ in 0..num_private_rooms {
rooms
.private_rooms
.push(Room::new(message.read_string(), 0));
}
let num_private_rooms = message.read_int32();
for i in 0..num_private_rooms {
rooms.private_rooms[i as usize].set_number_of_users(message.read_int32());
}
let num_operated_private_rooms = message.read_int32();
for _ in 0..num_operated_private_rooms {
rooms
.operated_private_rooms
.push(Room::new(message.read_string(), 0));
}
let num_operated_private_rooms = message.read_int32();
for i in 0..num_operated_private_rooms {
rooms.operated_private_rooms[i as usize].set_number_of_users(message.read_int32());
}
rooms.print();
}
}
+174 -29
View File
@@ -1,25 +1,5 @@
use std::str;
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum MessageType {
Login,
PrivilegedUsers,
ExcludedSearchPhrases,
RoomList,
Unknown(u8),
}
impl From<u8> for MessageType {
fn from(value: u8) -> Self {
match value {
1 => MessageType::Login,
69 => MessageType::PrivilegedUsers,
160 => MessageType::ExcludedSearchPhrases,
64 => MessageType::RoomList,
_ => MessageType::Unknown(value),
}
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct Message {
data: Vec<u8>,
@@ -34,8 +14,99 @@ impl Message {
}
}
pub fn get_message_type(&self) -> MessageType {
MessageType::from(self.data[4])
// pub fn print_hex(&self) {
// let data = &self.data;
// const BYTES_PER_LINE: usize = 16;
//
// let chunks = data.chunks(BYTES_PER_LINE);
// for (i, chunk) in chunks.enumerate() {
// // Print the offset
// print!("{:04x} ", i * BYTES_PER_LINE);
//
// // Print the hexadecimal part
// for j in 0..BYTES_PER_LINE {
// if j < chunk.len() {
// print!("{:02x} ", chunk[j]);
// } else {
// print!(" ");
// }
//
// // Add extra space in the middle
// if j == 7 {
// print!(" ");
// }
// }
//
// print!(" ");
//
// // Print the ASCII part
// let mut i = 0;
// for &byte in chunk {
// i = i + 1;
// if byte.is_ascii_graphic() || byte.is_ascii_whitespace() {
// print!("{}", byte as char);
// } else {
// print!(".");
// }
//
// if i == 8 {
// print!(" ");
// }
// }
//
// println!();
// }
// }
//
// pub fn print_hex2(&self) -> String {
// let data = &self.data;
// let mut out = String::from("");
// const BYTES_PER_LINE: usize = 16;
//
// let chunks = data.chunks(BYTES_PER_LINE);
// for (i, chunk) in chunks.enumerate() {
// // Print the offset
// // out += &format!("{:04x} ", i * BYTES_PER_LINE);
//
// // Print the hexadecimal part
// for j in 0..BYTES_PER_LINE {
// if j < chunk.len() {
// out += &format!("{:02x} ", chunk[j]);
// } else {
// // out += &format!(" ");
// }
//
// // Add extra space in the middle
// // if j == 7 {
// // out += &format!(" ");
// // }
// }
//
// // // Print the ASCII part
// // let mut i = 0;
// // for &byte in chunk {
// // i = i + 1;
// // if byte.is_ascii_graphic() || byte.is_ascii_whitespace() {
// // print!("{}", byte as char);
// // } else {messa
// // print!(".");
// // }
// //
// // if i == 8 {
// // print!(" ");
// // }
// // }
// //
// }
// println!("{:?}", out.trim());
// return out.trim().into();
// }
pub fn get_message_code_u32(&self) -> u32 {
u32::from_le_bytes(self.data[4..8].try_into().unwrap())
}
pub fn get_message_code(&self) -> u8 {
self.data[4]
}
pub fn new_with_data(data: Vec<u8>) -> Self {
@@ -48,10 +119,21 @@ impl Message {
self.pointer = pointer;
}
// get's the message data
pub fn get_data(&self) -> Vec<u8> {
self.data.clone()
}
/// gets buffer with the message length prepended
pub fn get_buffer(&self) -> Vec<u8> {
let mut b = vec![0u8; 4];
let length = self.data.len() as u32;
b[0..4].copy_from_slice(&length.to_le_bytes());
let mut combined = b;
combined.extend(&self.data);
combined
}
pub fn read_string(&mut self) -> String {
let size = u32::from_le_bytes([
self.data[self.pointer],
@@ -66,6 +148,14 @@ impl Message {
String::from_utf8(data.to_vec()).expect("Failed to read string")
}
pub fn read_raw_hex_str(&mut self, size: usize) -> String {
let hex_str = self.data[self.pointer..self.pointer + size]
.iter()
.map(|byte| format!("{:02x}", byte))
.collect::<String>();
self.pointer += size;
return hex_str;
}
pub fn read_int8(&mut self) -> i8 {
let val = self.data[self.pointer] as i8;
@@ -73,6 +163,7 @@ impl Message {
val
}
#[allow(dead_code)]
pub fn read_int64(&mut self) -> i64 {
let val = i64::from_le_bytes([
self.data[self.pointer],
@@ -103,6 +194,12 @@ impl Message {
val
}
pub fn read_bool(&mut self) -> bool {
let val = self.data[self.pointer] == 1;
self.pointer += 1;
val
}
pub fn write_string(&mut self, val: &str) -> &mut Self {
let length = val.len() as u32;
self.data.extend_from_slice(&length.to_le_bytes());
@@ -114,18 +211,66 @@ impl Message {
self.data.extend_from_slice(&value.to_le_bytes());
self
}
pub fn write_raw_bytes(&mut self, value: Vec<u8>) -> &mut Self {
self.data.extend_from_slice(&value);
self
}
pub fn write_raw_hex_string(&mut self, val: &str) -> &mut Self {
let mut b = Vec::new();
for i in (0..val.len()).step_by(2) {
let byte_str = &val[i..i + 2];
let byte = u8::from_str_radix(byte_str, 16).expect("Invalid hex string");
b.push(byte);
}
self.data.extend_from_slice(&b);
self.pointer += b.len();
self
}
// pub fn decode(&self) {
// let size =
// u32::from_le_bytes([self.data[0], self.data[1], self.data[2], self.data[3]]) as usize;
// println!("Size: {}", size);
// if size >= 4 {
// let code = u32::from_le_bytes([self.data[4], self.data[5], self.data[6], self.data[7]]);
// println!("Code: {}", code);
// }
// println!("{:?}", self.data);
// }
}
#[test]
fn test_get_buffer() {
let message = Message::new_with_data(
[
26, 0, 0, 0, 219, 178, 47, 28, 11, 0, 0, 0, 116, 104, 101, 32, 119, 101, 101, 107, 101,
110, 100,
]
.to_vec(),
);
assert_eq!(
message.get_buffer(),
[
23, 0, 0, 0, 26, 0, 0, 0, 219, 178, 47, 28, 11, 0, 0, 0, 116, 104, 101, 32, 119, 101,
101, 107, 101, 110, 100,
]
.to_vec()
);
let message = Message::new_with_data(
[
1, 0, 0, 0, 20, 0, 0, 0, 105, 110, 115, 97, 110, 101, 95, 105, 110, 95, 116, 104, 101,
95, 98, 114, 97, 105, 110, 50, 8, 0, 0, 0, 49, 51, 51, 55, 53, 49, 51, 55, 160, 0, 0,
0, 32, 0, 0, 0, 50, 101, 100, 102, 53, 49, 100, 48, 51, 55, 57, 52, 51, 55, 56, 102,
56, 98, 98, 54, 51, 49, 48, 100, 52, 54, 48, 99, 50, 50, 98, 49, 17, 0, 0, 0,
]
.to_vec(),
);
assert_eq!(
message.get_buffer(),
[
84, 0, 0, 0, 1, 0, 0, 0, 20, 0, 0, 0, 105, 110, 115, 97, 110, 101, 95, 105, 110, 95,
116, 104, 101, 95, 98, 114, 97, 105, 110, 50, 8, 0, 0, 0, 49, 51, 51, 55, 53, 49, 51,
55, 160, 0, 0, 0, 32, 0, 0, 0, 50, 101, 100, 102, 53, 49, 100, 48, 51, 55, 57, 52, 51,
55, 56, 102, 56, 98, 98, 54, 51, 49, 48, 100, 52, 54, 48, 99, 50, 50, 98, 49, 17, 0, 0,
0,
]
.to_vec()
);
}
#[test]
fn test_read_string() {
let data = vec![
@@ -34,6 +34,7 @@ impl MessageReader {
}
}
#[cfg(test)]
pub fn new_with_buffer(buffer: Vec<u8>) -> Self {
Self {
buffer: buffer.into(),
@@ -43,7 +44,9 @@ impl MessageReader {
pub fn read_from_socket(&mut self, stream: &mut TcpStream) -> io::Result<()> {
let mut temp_buffer = [0; 1024]; // Temporary buffer for reading from the socket
let bytes_read = stream.read(&mut temp_buffer)?;
// println!("Read {} bytes from the socket", bytes_read);
if bytes_read == 0 {
return Ok(());
}
// Add the read bytes to the internal buffer
self.buffer.extend(&temp_buffer[..bytes_read]);
@@ -75,35 +78,41 @@ impl MessageReader {
}
}
#[test]
fn test_extract_message() {
let buffer: Vec<u8> = [
8, 0, 0, 0, 117, 115, 101, 114, 110, 97, 109, 101, 8, 0, 0, 0, 112, 97, 115, 115, 119, 111,
114, 100, 160, 0, 0, 0, 32, 0, 0, 0, 100, 53, 49, 99, 57, 97, 55, 101, 57, 51, 53, 51, 55,
52, 54, 97, 54, 48, 50, 48, 102, 57, 54, 48, 50, 100, 52, 53, 50, 57, 50, 57, 17, 0, 0, 0,
]
.to_vec();
let mut buffered_reader = MessageReader::new_with_buffer(buffer);
let mut message = buffered_reader.extract_message().unwrap().unwrap();
assert_eq!(
message.get_data(),
vec![8, 0, 0, 0, 117, 115, 101, 114, 110, 97, 109, 101]
);
assert_eq!(message.read_string(), "username");
}
#[test]
fn test_extract_message_incomplete_message() {
let incomplete_buffer = vec![1, 2, 3];
let mut buffered_reader = MessageReader::new_with_buffer(incomplete_buffer);
#[cfg(test)]
mod tests {
use crate::message::MessageReader;
let result = buffered_reader.extract_message();
assert_eq!(None, result.unwrap());
#[test]
fn test_extract_message() {
let buffer: Vec<u8> = [
8, 0, 0, 0, 117, 115, 101, 114, 110, 97, 109, 101, 8, 0, 0, 0, 112, 97, 115, 115, 119,
111, 114, 100, 160, 0, 0, 0, 32, 0, 0, 0, 100, 53, 49, 99, 57, 97, 55, 101, 57, 51, 53,
51, 55, 52, 54, 97, 54, 48, 50, 48, 102, 57, 54, 48, 50, 100, 52, 53, 50, 57, 50, 57,
17, 0, 0, 0,
]
.to_vec();
let mut buffered_reader = MessageReader::new_with_buffer(buffer);
let mut message = buffered_reader.extract_message().unwrap().unwrap();
assert_eq!(
message.get_data(),
vec![8, 0, 0, 0, 117, 115, 101, 114, 110, 97, 109, 101]
);
assert_eq!(message.read_string(), "username");
}
#[test]
fn test_extract_message_incomplete_message() {
let incomplete_buffer = vec![1, 2, 3];
let mut buffered_reader = MessageReader::new_with_buffer(incomplete_buffer);
let rest: Vec<u8> = buffered_reader
.buffer
.drain(..buffered_reader.buffer.len())
.collect();
let result = buffered_reader.extract_message();
assert_eq!(None, result.unwrap());
assert!(buffered_reader.buffer.is_empty());
assert_eq!(vec![1, 2, 3], rest);
let rest: Vec<u8> = buffered_reader
.buffer
.drain(..buffered_reader.buffer.len())
.collect();
assert!(buffered_reader.buffer.is_empty());
assert_eq!(vec![1, 2, 3], rest);
}
}
+4 -3
View File
@@ -1,7 +1,8 @@
pub mod factory;
pub mod handlers;
pub mod message;
pub mod reader;
pub mod message_reader;
pub mod server;
pub use handlers::*;
pub use message::*;
pub use reader::*;
pub use message_reader::*;
+40
View File
@@ -0,0 +1,40 @@
use crate::message::{Message, MessageHandler};
use crate::server::ServerOperation;
use std::sync::mpsc::Sender;
pub struct ConnectToPeerHandler;
impl MessageHandler for ConnectToPeerHandler {
fn get_code(&self) -> u8 {
18
}
fn handle(&self, _message: &mut Message, _sender: Sender<ServerOperation>) {
println!("Handling ConnectToPeer message");
// let username = message.read_string();
// let connection_type = message.read_string();
// let mut ip: Vec<i8> = vec![];
// for _ in 0..4 {
// ip.push(message.read_int8());
// }
// let host: String = format!("{}.{}.{}.{}", ip[3], ip[2], ip[1], ip[0]);
//
// let (port, token, privileged, unknown, obfuscated_port) = (
// message.read_int32(),
// message.read_int32(),
// message.read_int8(),
// message.read_int8(),
// message.read_int8(),
// );
//
// let peer = Peer::new(
// username,
// connection_type,
// host,
// port,
// token,
// privileged,
// unknown,
// obfuscated_port,
// );
//
// sender.send(ServerOperation::ConnectToPeer(peer)).unwrap();
}
}
@@ -1,10 +1,17 @@
use std::sync::{Arc, Mutex};
use crate::{
message::{Message, MessageHandler},
server::ServerOperation,
};
use std::sync::mpsc::Sender;
use crate::{dispatcher::MessageHandler, message::Message, server::Context};
pub struct ExcludedSearchPhrasesHandler;
impl MessageHandler for ExcludedSearchPhrasesHandler {
fn handle(&self, message: &mut Message, _context: Arc<Mutex<Context>>) {
fn get_code(&self) -> u8 {
160
}
fn handle(&self, message: &mut Message, _sender: Sender<ServerOperation>) {
let item_count = message.read_int32();
let mut exluded_phrases: Vec<String> = Vec::new();
+24
View File
@@ -0,0 +1,24 @@
use std::sync::mpsc::Sender;
use crate::{
message::{handlers::MessageHandler, message::Message},
server::ServerOperation,
};
pub struct FileSearch;
impl MessageHandler for FileSearch {
fn get_code(&self) -> u8 {
26
}
fn handle(&self, message: &mut Message, _sender: Sender<ServerOperation>) {
println!("Handling file search message");
let username = message.read_string();
let token = message.read_int32();
let query = message.read_string();
println!(
"Message search username:{}, token: {}, query: {}",
username, token, query
);
}
}
+41
View File
@@ -0,0 +1,41 @@
use std::sync::mpsc::Sender;
use crate::{
message::{Message, MessageHandler},
server::ServerOperation,
};
pub struct LoginHandler;
impl MessageHandler for LoginHandler {
fn get_code(&self) -> u8 {
1
}
fn handle(&self, message: &mut Message, sender: Sender<ServerOperation>) {
let response = message.read_int8();
if response != 1 {
return sender.send(ServerOperation::LoginStatus(false)).unwrap();
}
println!("Login successful");
let greeting = message.read_string();
println!("Server geeting: {:?}", greeting);
sender.send(ServerOperation::LoginStatus(true)).unwrap();
}
}
// fn build_login_response_message() -> Message {
// return Message::new_with_data([
// 50, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 81, 170, 162, 77, 32, 0, 0, 0, 101, 102, 99, 97,
// 51, 52, 102, 99, 52, 99, 56, 98, 101, 56, 98, 55, 101, 102, 51, 56, 97, 102, 50, 54, 50,
// 52, 100, 101, 53, 52, 54, 52, 0,
// ]);
// }
// #[test]
// fn test_can_handle() {
// assert_eq!(true, LoginHandler.can_handle(build_login_response_message());
// );
// }
+119
View File
@@ -0,0 +1,119 @@
use crate::{message::message::Message, utils::md5};
pub struct MessageFactory;
impl MessageFactory {
pub fn build_login_message(username: &str, password: &str) -> Message {
// Message::new_with_data(
// [
// 1, 0, 0, 0, 20, 0, 0, 0, 105, 110, 115, 97, 110, 101, 95, 105, 110, 95, 116, 104, 101,
// 95, 98, 114, 97, 105, 110, 50, 8, 0, 0, 0, 49, 51, 51, 55, 53, 49, 51, 55, 160, 0, 0,
// 0, 32, 0, 0, 0, 50, 101, 100, 102, 53, 49, 100, 48, 51, 55, 57, 52, 51, 55, 56, 102,
// 56, 98, 98, 54, 51, 49, 48, 100, 52, 54, 48, 99, 50, 50, 98, 49, 17, 0, 0,
// 0,
// //0, // 84, 0, 0, 0, 1, 0, 0, 0, 20, 0, 0, 0, 105, 110, 115, 97, 110, 101, 95, 105, 110, 95,
// // 116, 104, 101, 95, 98, 114, 97, 105, 110, 50, 8, 0, 0, 0, 49, 51, 51, 55, 53, 49, 51,
// // 55, 160, 0, 0, 0, 32, 0, 0, 0, 50, 101, 100, 102, 53, 49, 100, 48, 51, 55, 57, 52, 51,
// // 55, 56, 102, 56, 98, 98, 54, 51, 49, 48, 100, 52, 54, 48, 99, 50, 50, 98, 49, 17, 0, 0,
// // 0,
// ]
// .to_vec(),
// )
// .clone()
let hash = md5([username, password].join("").as_str());
let mut message = Message::new();
message
.write_int32(1)
.write_string(username)
.write_string(password)
.write_int32(157) // version
.write_string(&hash)
.write_int32(100); //minor version
message
}
pub fn build_shared_folders_message(folder_count: i32, file_count: i32) -> Message {
Message::new()
.write_int32(35)
.write_int32(folder_count)
.write_int32(file_count)
.clone()
}
pub fn build_file_search_message(token: i32, query: &str) -> Message {
// Message::new_with_data(
// [
// 26, 0, 0, 0, 219, 178, 47, 28, 11, 0, 0, 0, 116, 104, 101, 32, 119, 101, 101, 107, 101,
// 110, 100, 0, 0,
// ]
// .to_vec(),
// )
// .clone()
Message::new()
.write_int32(26)
.write_int32(token)
.write_string(query)
.clone()
}
pub fn build_set_status_message(status_code: i32) -> Message {
Message::new()
.write_int32(28)
.write_int32(status_code)
.clone()
}
pub fn build_no_parent_message() -> Message {
Message::new().write_int32(71).write_int32(1).clone()
}
pub fn build_set_wait_port_message() -> Message {
Message::new().write_int32(2).write_int32(2234).clone()
}
pub fn build_watch_user(token: &str) -> Message {
Message::new()
.write_raw_bytes([5, 0, 0, 0, 0].to_vec())
.write_raw_hex_string(&token)
.clone()
}
}
#[test]
fn test_build_watch_user() {
let token = "5b581500";
let message = MessageFactory::build_watch_user(token);
let expect: Vec<u8> = [5, 0, 0, 0, 0, 91, 88, 21, 0].to_vec();
assert_eq!(expect, message.get_data())
}
#[test]
fn test_build_login_message() {
let message = MessageFactory::build_login_message("insane_in_the_brain2", "13375137");
let expect: Vec<u8> = [
1, 0, 0, 0, 20, 0, 0, 0, 105, 110, 115, 97, 110, 101, 95, 105, 110, 95, 116, 104, 101, 95,
98, 114, 97, 105, 110, 50, 8, 0, 0, 0, 49, 51, 51, 55, 53, 49, 51, 55, 160, 0, 0, 0, 32, 0,
0, 0, 50, 101, 100, 102, 53, 49, 100, 48, 51, 55, 57, 52, 51, 55, 56, 102, 56, 98, 98, 54,
51, 49, 48, 100, 52, 54, 48, 99, 50, 50, 98, 49, 17, 0, 0, 0,
]
.to_vec();
// println!("{:?}", print_hex(message.get_data()));
// assert_eq!(expect, message.get_data());
assert_eq!(expect, message.get_data())
}
#[test]
fn test_build_file_search_message() {
let message = MessageFactory::build_file_search_message(12, "trance wax");
let expect: Vec<u8> = [
26, 0, 0, 0, 199, 19, 251, 66, 10, 0, 0, 0, 116, 114, 97, 110, 99, 101, 32, 119, 97, 120,
]
.to_vec();
// [
// 26, 0, 0, 0, 116, 111, 107, 101, 110, 113, 117, 101, 114, 121, 0, 0, 0, 113, 117, 101, 114,
// 121,
// ]
// .to_vec();
assert_eq!(expect, message.get_data())
}
+65
View File
@@ -0,0 +1,65 @@
use crate::{
message::{Message, MessageHandler},
server::{ServerOperation, UserMessage},
};
use std::sync::mpsc::Sender;
pub struct MessageUser;
impl MessageHandler for MessageUser {
fn get_code(&self) -> u8 {
22
}
fn handle(&self, message: &mut Message, _sender: Sender<ServerOperation>) {
let id = message.read_int32();
let timestamp = message.read_int32();
let username = message.read_string();
let message_content = message.read_string();
let new_message = message.read_bool();
let user_message = UserMessage::new(
id,
timestamp,
username.clone(),
message_content,
new_message,
);
println!("User message received:",);
user_message.print()
}
}
// #[cfg(test)]
// use std::sync::mpsc;
// #[cfg(test)]
// use std::sync::mpsc::{Receiver, Sender};
//
// #[test]
// fn test_handle() {
// let (message_sender, _message_reader): (Sender<Message>, Receiver<Message>) = mpsc::channel();
//
// let context = Arc::new(Mutex::new(Context::new(Arc::new(Mutex::new(
// message_sender,
// )))));
// let mut message = Message::new_with_data(vec![
// 254, 0, 0, 0, 22, 0, 0, 0, 153, 102, 47, 0, 58, 65, 228, 102, 6, 0, 0, 0, 115, 101, 114,
// 118, 101, 114, 227, 0, 0, 0, 89, 111, 117, 114, 32, 99, 111, 110, 110, 101, 99, 116, 105,
// 111, 110, 32, 105, 115, 32, 114, 101, 115, 116, 114, 105, 99, 116, 101, 100, 58, 32, 89,
// 111, 117, 32, 99, 97, 110, 110, 111, 116, 32, 115, 101, 97, 114, 99, 104, 32, 111, 114, 32,
// 99, 104, 97, 116, 46, 32, 89, 111, 117, 114, 32, 99, 108, 105, 101, 110, 116, 32, 118, 101,
// 114, 115, 105, 111, 110, 32, 105, 115, 32, 116, 111, 111, 32, 111, 108, 100, 46, 32, 89,
// 111, 117, 32, 110, 101, 101, 100, 32, 116, 111, 32, 117, 112, 103, 114, 97, 100, 101, 32,
// 116, 111, 32, 116, 104, 101, 32, 108, 97, 116, 101, 115, 116, 32, 118, 101, 114, 115, 105,
// 111, 110, 46, 32, 67, 108, 111, 115, 101, 32, 116, 104, 105, 115, 32, 99, 108, 105, 101,
// 110, 116, 44, 32, 100, 111, 119, 110, 108, 111, 97, 100, 32, 110, 101, 119, 32, 118, 101,
// 114, 115, 105, 111, 110, 32, 102, 114, 111, 109, 32, 104, 116, 116, 112, 58, 47, 47, 119,
// 119, 119, 46, 115, 108, 115, 107, 110, 101, 116, 46, 111, 114, 103, 44, 32, 105, 110, 115,
// 116, 97, 108, 108, 32, 105, 116, 32, 97, 110, 100, 32, 114, 101, 99, 111, 110, 110, 101,
// 99, 116, 46, 1,
// ]);
// message.set_pointer(8);
// MessageUser.handle(&mut message.clone(), context.clone());
// assert_eq!(1, context.lock().unwrap().get_user_messages().len());
// }
// // }
+18
View File
@@ -0,0 +1,18 @@
pub mod connect_to_peer;
pub mod excluded_search_phrases;
pub mod file_search;
pub mod login;
pub mod message_factory;
pub mod message_user;
pub mod parent_min_speed;
pub mod parent_speed_ratio;
pub mod privileged_users;
pub mod room_list;
pub mod wish_list_interval;
pub use self::{
connect_to_peer::*, excluded_search_phrases::*, file_search::*, login::*, message_factory::*,
message_user::*, parent_min_speed::*, parent_speed_ratio::*, privileged_users::*, room_list::*,
wish_list_interval::*,
};
+20
View File
@@ -0,0 +1,20 @@
use std::sync::mpsc::Sender;
use crate::{
message::{Message, MessageHandler},
server::ServerOperation,
};
pub struct ParentMinSpeedHandler;
impl MessageHandler for ParentMinSpeedHandler {
fn get_code(&self) -> u8 {
83
}
fn handle(&self, message: &mut Message, sender: Sender<ServerOperation>) {
let _ = sender;
let number = message.read_int32();
println!("Parent min speed: {}", number);
}
}
+20
View File
@@ -0,0 +1,20 @@
use std::sync::mpsc::Sender;
use crate::{
message::{Message, MessageHandler},
server::ServerOperation,
};
pub struct ParentSpeedRatioHandler;
// The server sends us a speed ratio determining the number of children we can have in the distributed network. The maximum number of children is our upload speed divided by the speed ratio.
impl MessageHandler for ParentSpeedRatioHandler {
fn get_code(&self) -> u8 {
84
}
fn handle(&self, message: &mut Message, _sender: Sender<ServerOperation>) {
let number = message.read_int32();
println!("Parent min speed: {}", number);
}
}
+19
View File
@@ -0,0 +1,19 @@
use std::sync::mpsc::Sender;
use crate::{
message::{Message, MessageHandler},
server::ServerOperation,
};
pub struct PrivilegedUsersHandler;
impl MessageHandler for PrivilegedUsersHandler {
fn get_code(&self) -> u8 {
69
}
fn handle(&self, message: &mut Message, _sender: Sender<ServerOperation>) {
let number = message.read_int32();
println!("Number of privilaged users: {}", number);
}
}
+62
View File
@@ -0,0 +1,62 @@
use crate::{
message::{Message, MessageHandler},
server::ServerOperation,
};
use std::sync::mpsc::Sender;
pub struct RoomListHandler;
impl MessageHandler for RoomListHandler {
fn get_code(&self) -> u8 {
64
}
fn handle(&self, _message: &mut Message, _sender: Sender<ServerOperation>) {
// let num_public_rooms = message.read_int32();
// for _ in 0..num_public_rooms {
// rooms.public_rooms.push(Room::new(message.read_string(), 0));
// }
//
// let num_public_rooms = message.read_int32();
// for i in 0..num_public_rooms {
// rooms.public_rooms[i as usize].set_number_of_users(message.read_int32());
// }
//
// let num_owned_private_rooms = message.read_int32();
// for _ in 0..num_owned_private_rooms {
// rooms
// .owned_private_rooms
// .push(Room::new(message.read_string(), 0));
// }
//
// let num_owned_private_rooms = message.read_int32();
// for i in 0..num_owned_private_rooms {
// rooms.owned_private_rooms[i as usize].set_number_of_users(message.read_int32());
// }
//
// let num_private_rooms = message.read_int32();
// for _ in 0..num_private_rooms {
// rooms
// .private_rooms
// .push(Room::new(message.read_string(), 0));
// }
//
// let num_private_rooms = message.read_int32();
// for i in 0..num_private_rooms {
// rooms.private_rooms[i as usize].set_number_of_users(message.read_int32());
// }
//
// let num_operated_private_rooms = message.read_int32();
// for _ in 0..num_operated_private_rooms {
// rooms
// .operated_private_rooms
// .push(Room::new(message.read_string(), 0));
// }
// let num_operated_private_rooms = message.read_int32();
// for i in 0..num_operated_private_rooms {
// rooms.operated_private_rooms[i as usize].set_number_of_users(message.read_int32());
// }
// cvat.notify_all();
// rooms.print();
}
}
+21
View File
@@ -0,0 +1,21 @@
use std::sync::mpsc::Sender;
use crate::{
message::{Message, MessageHandler},
server::ServerOperation,
};
pub struct WishListIntervalHandler;
// The server tells us the wishlist search interval.
// This interval is almost always 12 minutes, or 2 minutes for privileged users.
impl MessageHandler for WishListIntervalHandler {
fn get_code(&self) -> u8 {
104
}
fn handle(&self, message: &mut Message, _sender: Sender<ServerOperation>) {
let number = message.read_int32();
println!("Wishlist search interval: {} in seconds", number);
}
}