#![deny(unsafe_code)]
#![allow(dead_code)]
use log::{error, info};
use koibumi_common_sync::{boxes::Boxes, param::Params};
use koibumi_core::{address::Address, message};
use koibumi_node_sync::{self as node, Command, Event, Response};
fn handle_msg(boxes: &Boxes, user_id: Vec<u8>, address: Address, object: message::Object) {
let identity = boxes.user().private_identity_by_address(&address);
if identity.is_none() {
error!("identity not found for address: {}", address);
return;
}
let identity = identity.unwrap();
match boxes.manager().insert_msg(user_id, identity, object) {
Ok(message) => {
println!("From: {}", message.from_address().to_string());
println!("{}", String::from_utf8_lossy(message.content()).to_string());
}
Err(err) => {
error!("{}", err);
}
}
}
fn handle_broadcast(boxes: &Boxes, user_id: Vec<u8>, address: Address, object: message::Object) {
match boxes.manager().insert_broadcast(user_id, address, object) {
Ok(message) => {
println!("From: {}", message.from_address().to_string());
println!("{}", String::from_utf8_lossy(message.content()).to_string());
}
Err(err) => {
error!("{}", err);
}
}
}
fn main() {
let params = Params::new();
koibumi_common_sync::log::init(¶ms).unwrap_or_else(|err| {
println!("Warning: Failed to initialize logger.");
println!("{}", err);
});
let config = koibumi_common_sync::config::load(¶ms).unwrap_or_else(|err| {
error!("Failed to load config file: {}", err);
std::process::exit(1)
});
let boxes = match koibumi_common_sync::boxes::prepare(¶ms) {
Ok(boxes) => Some(boxes),
Err(err) => {
error!("{}", err);
None
}
};
let (command_sender, response_receiver, node_handle) = node::spawn();
info!("Start");
if boxes.is_none() {
error!("No boxes");
std::process::exit(1)
}
#[cfg(feature = "ctrlc")]
{
use std::sync::{
atomic::{AtomicUsize, Ordering},
Arc,
};
let sender = command_sender.clone();
let ctrlc_count = Arc::new(AtomicUsize::new(0));
let cc = Arc::clone(&ctrlc_count);
ctrlc::set_handler(move || match cc.fetch_add(1, Ordering::SeqCst) {
0 => {
let mut sender = sender.clone();
sender.send(Command::Stop).unwrap_or_else(|err| {
error!("{}", err);
});
}
1 => {
let mut sender = sender.clone();
sender.send(Command::Abort).unwrap_or_else(|err| {
error!("{}", err);
});
}
_ => std::process::exit(0),
})
.unwrap_or_else(|err| {
error!("{}", err);
});
}
let sender = command_sender;
let response = {
let path = koibumi_common_sync::node::prepare(¶ms).unwrap_or_else(|err| {
error!("{}", err);
std::process::exit(1);
});
let users = vec![boxes.as_ref().unwrap().user().clone().into()];
if let Err(err) = sender.send(Command::Start(config.into(), path, users)) {
error!("{}", err);
return;
}
response_receiver.recv()
};
if response.is_err() {
error!("Could not start node.");
std::process::exit(1)
}
let Response::Started(receiver) = response.unwrap();
while let Ok(event) = receiver.recv() {
match event {
Event::ConnectionCounts { .. } => (),
Event::AddrCount(_count) => (),
Event::Established {
addr,
user_agent,
rating,
} => {
info!("established: {} {} rating:{}", addr, user_agent, rating);
}
Event::Disconnected { addr } => {
info!("disconnected: {}", addr);
}
Event::Objects { .. } => (),
Event::Stopped => {
std::process::exit(0);
}
Event::Msg {
user_id,
address,
object,
} => {
if let Some(boxes) = &boxes {
handle_msg(boxes, user_id, address, object);
}
}
Event::Broadcast {
user_id,
address,
object,
} => {
if let Some(boxes) = &boxes {
handle_broadcast(boxes, user_id, address, object);
}
}
}
}
if let Err(err) = node_handle.join() {
error!("{:?}", err);
}
}