diff --git a/client/scenes/main.gd b/client/scenes/main.gd index a153266..b64a980 100644 --- a/client/scenes/main.gd +++ b/client/scenes/main.gd @@ -8,6 +8,8 @@ var dataEnet:ENetPacketPeer var errorEnet:Error var id = 0 var maxplayer = 0 +var listen_ip:String +var listen_port:int # Server confirm our account var account_confirmed:bool = false @@ -18,14 +20,17 @@ var dtls := PacketPeerDTLS.new() var udp := PacketPeerUDP.new() -func create_server_enet(address, port): +func create_server_enet(): print("------ create_server_enet") errorEnet = enet.create_host(10) if errorEnet != OK: print("ERROR ENET.create_host: ", errorEnet) return - print("Connect to : " + address + " : " + str(port)) - dataEnet = enet.connect_to_host(address, port, 10) + + +func connect_to_host(): + print("Connect to : " + listen_ip + " : " + str(listen_port)) + dataEnet = enet.connect_to_host(listen_ip, listen_port, 10) print(dataEnet) if not dataEnet.is_active(): print("ERROR enet.connect_to_host: ", dataEnet.is_active()) @@ -34,6 +39,7 @@ func create_server_enet(address, port): func _ready(): enet = ENetConnection.new() + create_server_enet() func decode_msg(data:PackedByteArray): @@ -53,33 +59,20 @@ func decode_msg(data:PackedByteArray): print("==========================") + func send_account(): var data:PackedByteArray = PackedByteArray() - #data.encode_u8(1,0) data.append(1) data.append(len(player_name)) var packed_array = player_name.to_ascii_buffer() -# var str:PackedStringArray = PackedStringArray() -# str.push_back(player_name) data += packed_array - #data.append_array(str.to_byte_array()) - -# print("-------------------------") -# print(len(packed_array)) -# print("player_name: ", player_name) -# print("packed_array: ", packed_array) -# print("str: ", str) -# print("str -> bytes: ", str.to_byte_array()) -# print("data: ", data) -# print("-------------------------") print(player_name, " -> size:", data.size(), " / " , len(player_name) ) errorEnet = dataEnet.send(1, data, 1) if errorEnet != OK: print("ERROR ENET: ", errorEnet) return - #decode_msg(data) func set_player_position(pos: Vector3): @@ -89,7 +82,7 @@ func set_player_position(pos: Vector3): func get_player_position(): if not account_confirmed: return - print("perso: ", id, " ", self.get_node("CharacterBody3D").get_position()) + #print("perso: ", id, " ", self.get_node("CharacterBody3D").get_position()) var pos:PackedFloat64Array = PackedFloat64Array() var posRaw:Vector3 = self.get_node("CharacterBody3D").get_position() #posRaw.x = 123456789182729270e15 @@ -108,7 +101,9 @@ func get_player_position(): #data += packed_array #print(player_name, " -> size:", data.size(), " / " , len(player_name) ) errorEnet = dataEnet.send(2, data, 1) - if errorEnet != OK: + if errorEnet == ERR_UNCONFIGURED: + connect_to_host() + elif errorEnet != OK: print("ERROR ENET: ", errorEnet) return @@ -120,14 +115,14 @@ func bad_acocunt(): func get_event_received(): var data = dataEnet.get_packet() - print("get: ", data) + #print("get: ", data) if data[0] == 1: # Return connexion if data[1] == 0: # OK id = data.decode_u64(2) var x = data.decode_double(2+8) var y = data.decode_double(2+16) var z = data.decode_double(2+24) - print("id:", id, " x:", x, " y:", y, " z:", z) + # print("id:", id, " x:", x, " y:", y, " z:", z) self.set_player_position(Vector3(x, y, z)) account_confirmed = true self.get_node("CharacterBody3D").set_enable_event(true) @@ -145,12 +140,12 @@ func get_event_received(): var mz = data.decode_double(pos+24) pos += 32 if mid == id: - print("Me id:", mid, " x:", mx, " y:", my, " z:", mz) + #print("Me id:", mid, " x:", mx, " y:", my, " z:", mz) continue - print("-- id:", mid, " x:", mx, " y:", my, " z:", mz) + #print("-- id:", mid, " x:", mx, " y:", my, " z:", mz) var child = $Players.find_child(str(mid), false, false) if child == null: - print("Not found") + print("Add player : ", mid) if maxplayer > 3: continue var scene = preload("res://scenes/player.tscn") @@ -161,14 +156,24 @@ func get_event_received(): $Players.add_child(instance) #$Players.add_child(scene) maxplayer += 1 - for child3 in $Players.get_children(): - print(" -> ", child3.get_name()) var child2 = $Players.find_child(str(mid), false, false) child2.set_global_position(Vector3(mx, my, mz)) - else: child.set_global_position(Vector3(mx, my, mz)) - print("Found:", $Players.get_child_count()) + #print("Found:", $Players.get_child_count()) + var nbuserremove = data[pos] + pos += 1 + for i in nbuserremove: + var mid = data.decode_u64(pos) + pos += 8 + if mid == id: + print("Try to remove me :", mid) + continue + #print("Remove player : ", mid) + var child = $Players.find_child(str(mid), false, false) + if child != null: + print("Remove player : ", mid) + $Players.get_node(str(mid)).queue_free() # Called every frame. 'delta' is the elapsed time since the previous frame. @@ -190,42 +195,35 @@ func _process(_delta): pass elif dataEnet.get_state() == ENetPacketPeer.STATE_DISCONNECTED: var _event = enet.service() + print("STATE_DISCONNECTED") elif dataEnet.get_state() == ENetPacketPeer.STATE_ACKNOWLEDGING_CONNECT: var _event = enet.service() + print("STATE_ACKNOWLEDGING_CONNECT") elif dataEnet.get_state() == ENetPacketPeer.STATE_CONNECTION_PENDING: var _event = enet.service() + print("STATE_CONNECTION_PENDING") elif dataEnet.get_state() == ENetPacketPeer.STATE_CONNECTION_SUCCEEDED: var _event = enet.service() + print("STATE_CONNECTION_SUCCEEDED") elif dataEnet.get_state() == ENetPacketPeer.STATE_DISCONNECT_LATER: var _event = enet.service() + print("STATE_DISCONNECT_LATER") elif dataEnet.get_state() == ENetPacketPeer.STATE_DISCONNECTING: var _event = enet.service() + print("STATE_DISCONNECTING") elif dataEnet.get_state() == ENetPacketPeer.STATE_ACKNOWLEDGING_DISCONNECT: var _event = enet.service() + print("STATE_ACKNOWLEDGING_DISCONNECT") elif dataEnet.get_state() == ENetPacketPeer.STATE_ZOMBIE: var _event = enet.service() + print("STATE_ZOMBIE") else: var _event = enet.service() -func _process_ter(_delta): - var res = enet.service(1) - #print(res) - if res[0] == ENetConnection.EVENT_RECEIVE: - #print("EVENT_RECEIVE") - print(dataEnet.get_packet()) - #if res[1] - var data:PackedByteArray = PackedByteArray() - data.append(len(player_name)) - data.append(123) - errorEnet = dataEnet.send(1, data, 1) - if errorEnet != OK: - print("ERROR ENET: ", errorEnet) - return - - -func connect_enet(_name:String, listen_ip:String, listen_port:int): +func connect_enet(_name:String, _listen_ip:String, _listen_port:int): player_name = _name - create_server_enet(listen_ip, listen_port) + listen_ip = _listen_ip + listen_port = _listen_port + connect_to_host() print("My name:" + player_name) - diff --git a/server/src/main.rs b/server/src/main.rs index 9e8ddbf..92b6458 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -17,10 +17,10 @@ extern crate enet; use std::net::{Ipv4Addr}; use log::{debug, error, info, trace, warn, Level, LevelFilter, Metadata, Record, SetLoggerError}; use clap::Parser; - use anyhow::Context; use enet::*; use std::*; +use std::time::{Instant}; use chrono::Utc; use byteorder::{ByteOrder, LittleEndian, ReadBytesExt}; @@ -119,7 +119,15 @@ struct User { x: f64, y: f64, z: f64, - position_updated: bool + position_updated: bool, + lasttime: Instant, + sendfull: u8, +} + +impl PartialEq for User { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + } } impl User { @@ -134,6 +142,7 @@ impl User { */ pub fn set_inactive(&mut self) { self.active = false; + self.lasttime = Instant::now(); } pub fn set_active(&mut self) { self.active = true; @@ -175,12 +184,15 @@ impl User { return pos; } */ - pub fn push_packet(&self, data:&mut Vec) { + pub fn push_packet_get_position(&self, data:&mut Vec) { push_u64(data, self.id); push_f64(data, self.x); push_f64(data, self.y); push_f64(data, self.z); } + pub fn push_packet_id(&self, data:&mut Vec) { + push_u64(data, self.id); + } /* pub fn get_packet(&mut self) -> Vec { let mut data:Vec = Vec::new(); @@ -195,7 +207,9 @@ impl User { impl std::fmt::Display for User { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "id:{} user:{} active:{} address:{}:{} ({}:{}:{})", self.id, self.username, self.active, self.address.ip(), self.address.port(), self.x, self.y, self.z) + 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) } } @@ -299,7 +313,7 @@ impl Users { } pub fn add(&mut self, username:String, address: Address) -> u64 { let id = self.get_new_id(); - self.users.push( User { active: true, username:username, address: address, id: id, x: 0.0, y: 10.0, z:0.0, position_updated:true} ); + self.users.push( User { active: true, username:username, address: address, id: id, x: 0.0, y: 10.0, z:0.0, position_updated:true, lasttime: Instant::now(), sendfull:10} ); id } pub fn update_pos(&mut self, address: Address, x:f64, y:f64, z:f64) { @@ -368,11 +382,21 @@ impl Users { error!("invalid address {}:{}", address.ip(), address.port()); Err("invalid address") } - pub fn push_packet(&self, data:&mut Vec) -> u8 { + pub fn push_packet_get_position(&self, data:&mut Vec, getall: bool) -> u8 { let mut nb:u8 = 0; for user in &self.users { - if user.active && user.position_updated { - user.push_packet(data); + if user.active && (getall || user.position_updated ) { + user.push_packet_get_position(data); + nb += 1; + } + } + nb + } + pub fn push_packet_user_will_remove(&mut self, data:&mut Vec, maxdelay: u64) -> u8 { + let mut nb:u8 = 0; + for user in &self.users { + if ! user.active && user.lasttime.elapsed().as_secs() > maxdelay { + user.push_packet_id(data); nb += 1; } } @@ -385,6 +409,24 @@ impl Users { } } } + pub fn clear_old_user(&mut self, maxdelay: u64) { + let mut toclean:bool = true; + let mut index:usize = 0; + while toclean { + toclean = false; + for user in &self.users { + if ! user.active && user.lasttime.elapsed().as_secs() > maxdelay { + index = self.users.iter().position(|x| x == user).unwrap(); + info!("Clear player : {} ({})", user.username, user.id); + toclean = true; + break; + } + } + if toclean { + self.users.remove(index); + } + } + } } impl std::fmt::Display for Users { @@ -447,7 +489,7 @@ fn send_message_connect_ok(sender:Peer<()>, user: &User) -> Result<(), Error> { let mut data:Vec = Vec::new(); data.push(1); // return connexion request data.push(0); // return ok - user.push_packet(&mut data); + user.push_packet_get_position(&mut data); let c: &[u8] = &data; send_message(sender, c) } @@ -500,6 +542,8 @@ struct Cli { fn main() -> anyhow::Result<()> { let cli = Cli::parse(); let enet = Enet::new().context("could not initialize ENet")?; + let mut force_update : u8 = 0; + let mut launch_cleanup : u8 = 60; if cli.trace { loginit(LevelFilter::Trace).unwrap(); @@ -535,6 +579,13 @@ fn main() -> anyhow::Result<()> { Some(Event::Connect(_)) => debug!("new connection!"), Some(Event::Disconnect(ref sender, _)) => { users.set_inactive(sender.address()); + let ret = users.get_user(sender.address()); + match ret { + Ok(user) => { + info!("Disconnect player : {} (id:{})", user.username, user.id); + }, + Err(_e) => {}, + }; debug!("disconnect!"); }, Some(Event::Receive { @@ -569,37 +620,53 @@ fn main() -> anyhow::Result<()> { match check { StateUsers::NotDefined => { debug!("NotDefined"); + force_update = 10; let _id = users.add(s.to_string(), sender.address()); let ret = users.get_user(sender.address()); match ret { - Ok(user) => send_message_connect_ok(sender.clone(), user).unwrap(), + Ok(user) => { + info!("Add player : {} (id:{})", user.username, user.id); + send_message_connect_ok(sender.clone(), user).unwrap() + }, Err(_e) => {}, }; } StateUsers::Inactive => { debug!("Inactive"); + force_update = 10; let _id = users.set_active(sender.address()); let ret = users.get_user(sender.address()); match ret { - Ok(user) => send_message_connect_ok(sender.clone(), user).unwrap(), + Ok(user) => { + info!("Inactive player : {} (id:{})", user.username, user.id); + send_message_connect_ok(sender.clone(), user).unwrap() + }, Err(_e) => {}, }; } StateUsers::UpdateUser => { debug!("UpdateUser"); + force_update = 10; let _id = users.update_username(s.to_string(), sender.address()); let ret = users.get_user(sender.address()); match ret { - Ok(user) => send_message_connect_ok(sender.clone(), user).unwrap(), + Ok(user) => { + info!("Add player : {} (id:{})", user.username, user.id); + send_message_connect_ok(sender.clone(), user).unwrap() + }, Err(_e) => {}, }; } StateUsers::UpdateAddress => { debug!("UpdateAddress"); + force_update = 10; let _id = users.update_address(s.to_string(), sender.address()); let ret = users.get_user(sender.address()); match ret { - Ok(user) => send_message_connect_ok(sender.clone(), user).unwrap(), + Ok(user) => { + info!("Add player : {} (id:{})", user.username, user.id); + send_message_connect_ok(sender.clone(), user).unwrap() + }, Err(_e) => {}, }; } @@ -609,6 +676,7 @@ fn main() -> anyhow::Result<()> { } StateUsers::Done => { debug!("Done"); + force_update = 10; let _id = users.get_id(sender.address()); let ret = users.get_user(sender.address()); match ret { @@ -628,12 +696,15 @@ fn main() -> anyhow::Result<()> { users.update_pos(sender.address(), x, y, z); } _ => { + send_message_connect_ko(sender.clone()).unwrap(); + /* let mut peer = sender.clone(); peer.send_packet ( Packet::new(b"youpia", PacketMode::ReliableSequenced).unwrap(), 1, ) .context("sending packet failed")?; + */ } } }, @@ -643,12 +714,21 @@ fn main() -> anyhow::Result<()> { { let mut data:Vec = Vec::new(); let mut data2:Vec = Vec::new(); + let mut data3:Vec = Vec::new(); data.push(3); // return connexion request - let nb:u8 = users.push_packet(&mut data2); + // get list user position + let nb:u8 = users.push_packet_get_position(&mut data2, force_update > 0); + if force_update > 0 { + force_update -= 1; + } data.push(nb); // number user data.append(&mut data2); + // Get list user removed + let nbuserremove:u8 = users.push_packet_user_will_remove(&mut data3, 10); + data.push(nbuserremove); // number user removed + data.append(&mut data3); let c: &[u8] = &data; - if nb > 0 { + if nb > 0 || nbuserremove > 0 { for peer in host.peers() { if peer.state() == PeerState::Connected { trace!("peer: {}:{}", peer.address().ip(), peer.address().port()); @@ -658,6 +738,12 @@ fn main() -> anyhow::Result<()> { users.clear_position_updated(); } } + if launch_cleanup >= 1 { + launch_cleanup -= 1; + } else { + users.clear_old_user(60); + launch_cleanup = 60; + } /* for peer in host.peers() { if peer.state() == PeerState::Connected {