diff --git a/server/src/main.rs b/server/src/main.rs index 92b6458..be9e395 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -207,8 +207,8 @@ impl User { impl std::fmt::Display for User { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "id:{} user:{} active:{} address:{}:{} ({}:{}:{}) sendfull:{}", - self.id, self.username, self.active, self.address.ip(), self.address.port(), + write!(f, "id:{} user:{} active:{} address:{}:{} ({}:{}:{}) sendfull:{}", + self.id, self.username, self.active, self.address.ip(), self.address.port(), self.x, self.y, self.z, self.sendfull) } } @@ -266,9 +266,9 @@ impl Users { StateUsers::Inactive } } - _ => { + _ => { trace!("User:Ok, Address:Ok, But already checked ?"); - StateUsers::Error + StateUsers::Error } }; } @@ -284,15 +284,16 @@ impl Users { if nb_user == 0 && nb_address == 0 { trace!("NotDefined: User: not define, Address: not define"); return StateUsers::NotDefined; - } else if nb_user == 1 && nb_address == 0 { + } else if nb_user == 1 && nb_address == 0 && user_active == false { trace!("UpdateAddress: User: {}, Address: {}", nb_user, nb_address); return StateUsers::UpdateAddress; - } else if nb_user == 0 && nb_address == 1 { + } else if nb_user == 0 && nb_address == 1 && address_active == false { trace!("UpdateUser: User: {}, Address: {}", nb_user, nb_address); return StateUsers::UpdateUser; } else if nb_user == 1 && nb_address == 1 { if user_address { - return cur; + trace!("user_address !"); + return cur; } else if user_active && ! address_active { trace!("UpdateUser: User: not define, Address: Ok"); return StateUsers::UpdateUser; @@ -423,7 +424,7 @@ impl Users { } } if toclean { - self.users.remove(index); + self.users.remove(index); } } } @@ -454,7 +455,7 @@ impl Users { pub fn print(&self) { println!("len: {}", self.users.len()); for user in self.users { - println!("active:{} (user:{} address:{}:{})",user.active, user.username, user.address.ip(), user.address.port()); + println!("active:{} (user:{} address:{}:{})",user.active, user.username, user.address.ip(), user.address.port()); } } } @@ -507,6 +508,127 @@ fn show(data: &[u8]) -> String { } */ +// Statistics + +struct Statistics { + last: Instant, + count_loop: u64, + count_connect: u64, + count_disconnect: u64, + count_recv: u64, + count_recv_forbidden: u64, + count_recv_notdefined: u64, + count_recv_inactive: u64, + count_recv_updateuser: u64, + count_recv_updateaddress: u64, + count_recv_error: u64, + count_recv_done: u64, + count_recv_invaliduser: u64, + send_update: u64, + send_remove: u64, +} + +impl Statistics { + pub fn new() -> Statistics { + Self { + last: Instant::now(), + count_loop: 0, + count_connect: 0, + count_disconnect: 0, + count_recv: 0, + count_recv_forbidden: 0, + count_recv_notdefined: 0, + count_recv_inactive: 0, + count_recv_updateuser: 0, + count_recv_updateaddress: 0, + count_recv_error: 0, + count_recv_done: 0, + count_recv_invaliduser: 0, + send_update: 0, + send_remove: 0, + } + } + pub fn clear(&mut self) { + self.last = Instant::now(); + self.count_loop = 0; + self.count_connect = 0; + self.count_disconnect = 0; + self.count_recv = 0; + self.count_recv_forbidden = 0; + self.count_recv_notdefined = 0; + self.count_recv_inactive = 0; + self.count_recv_updateuser = 0; + self.count_recv_updateaddress = 0; + self.count_recv_error = 0; + self.count_recv_done = 0; + self.count_recv_invaliduser = 0; + self.send_update = 0; + self.send_remove = 0; + } + pub fn inc_loop(&mut self) { + self.count_loop += 1; + } + pub fn inc_connect(&mut self) { + self.count_connect += 1; + } + pub fn inc_disconnect(&mut self) { + self.count_disconnect += 1; + } + pub fn inc_recv(&mut self) { + self.count_recv += 1; + } + pub fn inc_recv_forbidden(&mut self) { + self.count_recv_forbidden += 1; + } + pub fn inc_recv_notdefined(&mut self) { + self.count_recv_notdefined += 1; + } + pub fn inc_recv_inactive(&mut self) { + self.count_recv_inactive += 1; + } + pub fn inc_recv_updateuser(&mut self) { + self.count_recv_updateuser += 1; + } + pub fn inc_recv_updateaddress(&mut self) { + self.count_recv_updateaddress += 1; + } + pub fn inc_recv_error(&mut self) { + self.count_recv_error += 1; + } + pub fn inc_recv_done(&mut self) { + self.count_recv_done += 1; + } + pub fn inc_recv_invaliduser(&mut self) { + self.count_recv_invaliduser += 1; + } + pub fn inc_send_update(&mut self) { + self.send_update += 1; + } + pub fn inc_send_remove(&mut self) { + self.send_remove += 1; + } + pub fn is_completed(&self, maxsecond:u64) -> bool { + self.last.elapsed().as_secs() > maxsecond + } +} + +impl Default for Statistics { + fn default() -> Self { + Self::new() + } +} + +impl std::fmt::Display for Statistics { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "loop:{}, connect:{}, disconnect:{}, recv [all:{}, notdefined:{}, inactive:{}, updateuser:{}, udpateaddress:{}, error:{}, done:{}, forbidden:{} invaliduser:{}] send:[update:{}, remove:{}] ", + self.count_loop, self.count_connect, self.count_disconnect, self.count_recv, self.count_recv_notdefined, + self.count_recv_inactive, self.count_recv_updateuser, self.count_recv_updateaddress, self.count_recv_error, self.count_recv_done, + self.count_recv_forbidden, self.count_recv_invaliduser, + self.send_update, self.send_remove + ) + } +} + /* * Argument #[arg(short, long, default_value_t = "127.0.0.1")] @@ -534,6 +656,18 @@ struct Cli { /// Show info message #[arg(short, long)] verbose: bool, + + /// Delay on each statistics (in second) + #[arg(short, long, default_value_t = 60)] + statistics: u64, + + /// Delay before clear disconnected user (in second) + #[arg(short, long, default_value_t = 60)] + clearuser: u64, + + /// Loop to force update + #[arg(short, long, default_value_t = 10)] + forceupdate: u8, } /* @@ -544,7 +678,9 @@ fn main() -> anyhow::Result<()> { let enet = Enet::new().context("could not initialize ENet")?; let mut force_update : u8 = 0; let mut launch_cleanup : u8 = 60; - + let mut last_update:Instant = Instant::now(); + let mut stat:Statistics = Statistics::new(); + if cli.trace { loginit(LevelFilter::Trace).unwrap(); } else if cli.debug { @@ -575,9 +711,14 @@ fn main() -> anyhow::Result<()> { info!("Started"); loop { trace!("users: {}", users); + stat.inc_loop(); match host.service(1000).context("service failed")? { - Some(Event::Connect(_)) => debug!("new connection!"), + Some(Event::Connect(_)) => { + stat.inc_connect(); + debug!("new connection!") + }, Some(Event::Disconnect(ref sender, _)) => { + stat.inc_disconnect(); users.set_inactive(sender.address()); let ret = users.get_user(sender.address()); match ret { @@ -600,12 +741,13 @@ fn main() -> anyhow::Result<()> { sender.address().ip(), sender.address().port() ); + stat.inc_recv(); match channel_id { 1 => { let cmd = packet.data()[0]; let size = packet.data()[1] as usize; let player_name = &packet.data()[2..=size+1]; - + let s = match str::from_utf8(player_name) { Ok(v) => v, Err(_e) => "", @@ -613,6 +755,7 @@ fn main() -> anyhow::Result<()> { trace!("cmd: {} size:{} name:{} '{}'", cmd, size, player_name.len(), s); if s.to_string() == "Interdit" || s.to_string() == "" { warn!("Received forbidden account '{}'", s); + stat.inc_recv_forbidden(); send_message_connect_ko(sender.clone()).unwrap(); continue; } @@ -620,68 +763,91 @@ fn main() -> anyhow::Result<()> { match check { StateUsers::NotDefined => { debug!("NotDefined"); - force_update = 10; + force_update = cli.forceupdate; let _id = users.add(s.to_string(), sender.address()); let ret = users.get_user(sender.address()); match ret { Ok(user) => { info!("Add player : {} (id:{})", user.username, user.id); + stat.inc_recv_notdefined(); send_message_connect_ok(sender.clone(), user).unwrap() }, - Err(_e) => {}, + Err(_e) => { + send_message_connect_ko(sender.clone()).unwrap(); + stat.inc_recv_invaliduser(); + }, }; } StateUsers::Inactive => { debug!("Inactive"); - force_update = 10; + force_update = cli.forceupdate; let _id = users.set_active(sender.address()); let ret = users.get_user(sender.address()); match ret { Ok(user) => { info!("Inactive player : {} (id:{})", user.username, user.id); + stat.inc_recv_inactive(); send_message_connect_ok(sender.clone(), user).unwrap() }, - Err(_e) => {}, + Err(_e) => { + send_message_connect_ko(sender.clone()).unwrap(); + stat.inc_recv_invaliduser(); + }, }; } StateUsers::UpdateUser => { debug!("UpdateUser"); - force_update = 10; + force_update = cli.forceupdate; let _id = users.update_username(s.to_string(), sender.address()); let ret = users.get_user(sender.address()); match ret { Ok(user) => { info!("Add player : {} (id:{})", user.username, user.id); + stat.inc_recv_updateuser(); send_message_connect_ok(sender.clone(), user).unwrap() }, - Err(_e) => {}, + Err(_e) => { + send_message_connect_ko(sender.clone()).unwrap(); + stat.inc_recv_invaliduser(); + }, }; } StateUsers::UpdateAddress => { debug!("UpdateAddress"); - force_update = 10; + force_update = cli.forceupdate; let _id = users.update_address(s.to_string(), sender.address()); let ret = users.get_user(sender.address()); match ret { Ok(user) => { info!("Add player : {} (id:{})", user.username, user.id); + stat.inc_recv_updateaddress(); send_message_connect_ok(sender.clone(), user).unwrap() }, - Err(_e) => {}, + Err(_e) => { + send_message_connect_ko(sender.clone()).unwrap(); + stat.inc_recv_invaliduser(); + }, }; } StateUsers::Error => { error!("Bad request from {}:{}", sender.address().ip(),sender.address().port()); + stat.inc_recv_error(); send_message_connect_ko(sender.clone()).unwrap(); } StateUsers::Done => { debug!("Done"); - force_update = 10; + force_update = cli.forceupdate; let _id = users.get_id(sender.address()); let ret = users.get_user(sender.address()); match ret { - Ok(user) => send_message_connect_ok(sender.clone(), user).unwrap(), - Err(_e) => {}, + Ok(user) => { + stat.inc_recv_done(); + send_message_connect_ok(sender.clone(), user).unwrap() + }, + Err(_e) => { + send_message_connect_ko(sender.clone()).unwrap(); + stat.inc_recv_invaliduser(); + }, }; } } @@ -710,8 +876,10 @@ fn main() -> anyhow::Result<()> { }, _ => (), } - // Send all player, position other player - { + /* + Send all player, position other player + */ + if last_update.elapsed().as_millis() > 100 { let mut data:Vec = Vec::new(); let mut data2:Vec = Vec::new(); let mut data3:Vec = Vec::new(); @@ -729,6 +897,12 @@ fn main() -> anyhow::Result<()> { data.append(&mut data3); let c: &[u8] = &data; if nb > 0 || nbuserremove > 0 { + if nb > 0 { + stat.inc_send_update(); + } + if nbuserremove > 0 { + stat.inc_send_remove(); + } for peer in host.peers() { if peer.state() == PeerState::Connected { trace!("peer: {}:{}", peer.address().ip(), peer.address().port()); @@ -737,12 +911,18 @@ fn main() -> anyhow::Result<()> { } users.clear_position_updated(); } - } - if launch_cleanup >= 1 { - launch_cleanup -= 1; - } else { - users.clear_old_user(60); - launch_cleanup = 60; + last_update = Instant::now(); + if launch_cleanup >= 1 { + launch_cleanup -= 1; + } else { + users.clear_old_user(cli.clearuser); + launch_cleanup = 60; + } + if stat.is_completed(cli.statistics) { + + info!("{}", stat); + stat.clear(); + } } /* for peer in host.peers() { diff --git a/start-bazar-server.sh b/start-bazar-server.sh index f09e38c..3428e91 100755 --- a/start-bazar-server.sh +++ b/start-bazar-server.sh @@ -136,6 +136,7 @@ then msg_error "Error to load envi rust" exit 2 fi + msg_info "Build finished" fi #echo "OPTIONS:$OPTIONS"