adding statistics & send disconnect to client if not connected

This commit is contained in:
AleaJactaEst 2023-10-25 22:29:45 +02:00
parent ceb4faa7d3
commit 85b92e7871
2 changed files with 212 additions and 31 deletions

View file

@ -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<u8> = Vec::new();
let mut data2:Vec<u8> = Vec::new();
let mut data3:Vec<u8> = 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() {

View file

@ -136,6 +136,7 @@ then
msg_error "Error to load envi rust"
exit 2
fi
msg_info "Build finished"
fi
#echo "OPTIONS:$OPTIONS"