adding clear account on server and remove on client side

This commit is contained in:
AleaJactaEst 2023-10-24 23:51:30 +02:00
parent 91e04a00a7
commit ceb4faa7d3
2 changed files with 146 additions and 62 deletions

View file

@ -8,6 +8,8 @@ var dataEnet:ENetPacketPeer
var errorEnet:Error var errorEnet:Error
var id = 0 var id = 0
var maxplayer = 0 var maxplayer = 0
var listen_ip:String
var listen_port:int
# Server confirm our account # Server confirm our account
var account_confirmed:bool = false var account_confirmed:bool = false
@ -18,14 +20,17 @@ var dtls := PacketPeerDTLS.new()
var udp := PacketPeerUDP.new() var udp := PacketPeerUDP.new()
func create_server_enet(address, port): func create_server_enet():
print("------ create_server_enet") print("------ create_server_enet")
errorEnet = enet.create_host(10) errorEnet = enet.create_host(10)
if errorEnet != OK: if errorEnet != OK:
print("ERROR ENET.create_host: ", errorEnet) print("ERROR ENET.create_host: ", errorEnet)
return 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) print(dataEnet)
if not dataEnet.is_active(): if not dataEnet.is_active():
print("ERROR enet.connect_to_host: ", dataEnet.is_active()) print("ERROR enet.connect_to_host: ", dataEnet.is_active())
@ -34,6 +39,7 @@ func create_server_enet(address, port):
func _ready(): func _ready():
enet = ENetConnection.new() enet = ENetConnection.new()
create_server_enet()
func decode_msg(data:PackedByteArray): func decode_msg(data:PackedByteArray):
@ -53,33 +59,20 @@ func decode_msg(data:PackedByteArray):
print("==========================") print("==========================")
func send_account(): func send_account():
var data:PackedByteArray = PackedByteArray() var data:PackedByteArray = PackedByteArray()
#data.encode_u8(1,0)
data.append(1) data.append(1)
data.append(len(player_name)) data.append(len(player_name))
var packed_array = player_name.to_ascii_buffer() var packed_array = player_name.to_ascii_buffer()
# var str:PackedStringArray = PackedStringArray()
# str.push_back(player_name)
data += packed_array 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) ) print(player_name, " -> size:", data.size(), " / " , len(player_name) )
errorEnet = dataEnet.send(1, data, 1) errorEnet = dataEnet.send(1, data, 1)
if errorEnet != OK: if errorEnet != OK:
print("ERROR ENET: ", errorEnet) print("ERROR ENET: ", errorEnet)
return return
#decode_msg(data)
func set_player_position(pos: Vector3): func set_player_position(pos: Vector3):
@ -89,7 +82,7 @@ func set_player_position(pos: Vector3):
func get_player_position(): func get_player_position():
if not account_confirmed: if not account_confirmed:
return return
print("perso: ", id, " ", self.get_node("CharacterBody3D").get_position()) #print("perso: ", id, " ", self.get_node("CharacterBody3D").get_position())
var pos:PackedFloat64Array = PackedFloat64Array() var pos:PackedFloat64Array = PackedFloat64Array()
var posRaw:Vector3 = self.get_node("CharacterBody3D").get_position() var posRaw:Vector3 = self.get_node("CharacterBody3D").get_position()
#posRaw.x = 123456789182729270e15 #posRaw.x = 123456789182729270e15
@ -108,7 +101,9 @@ func get_player_position():
#data += packed_array #data += packed_array
#print(player_name, " -> size:", data.size(), " / " , len(player_name) ) #print(player_name, " -> size:", data.size(), " / " , len(player_name) )
errorEnet = dataEnet.send(2, data, 1) errorEnet = dataEnet.send(2, data, 1)
if errorEnet != OK: if errorEnet == ERR_UNCONFIGURED:
connect_to_host()
elif errorEnet != OK:
print("ERROR ENET: ", errorEnet) print("ERROR ENET: ", errorEnet)
return return
@ -120,14 +115,14 @@ func bad_acocunt():
func get_event_received(): func get_event_received():
var data = dataEnet.get_packet() var data = dataEnet.get_packet()
print("get: ", data) #print("get: ", data)
if data[0] == 1: # Return connexion if data[0] == 1: # Return connexion
if data[1] == 0: # OK if data[1] == 0: # OK
id = data.decode_u64(2) id = data.decode_u64(2)
var x = data.decode_double(2+8) var x = data.decode_double(2+8)
var y = data.decode_double(2+16) var y = data.decode_double(2+16)
var z = data.decode_double(2+24) 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)) self.set_player_position(Vector3(x, y, z))
account_confirmed = true account_confirmed = true
self.get_node("CharacterBody3D").set_enable_event(true) self.get_node("CharacterBody3D").set_enable_event(true)
@ -145,12 +140,12 @@ func get_event_received():
var mz = data.decode_double(pos+24) var mz = data.decode_double(pos+24)
pos += 32 pos += 32
if mid == id: if mid == id:
print("Me id:", mid, " x:", mx, " y:", my, " z:", mz) #print("Me id:", mid, " x:", mx, " y:", my, " z:", mz)
continue 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) var child = $Players.find_child(str(mid), false, false)
if child == null: if child == null:
print("Not found") print("Add player : ", mid)
if maxplayer > 3: if maxplayer > 3:
continue continue
var scene = preload("res://scenes/player.tscn") var scene = preload("res://scenes/player.tscn")
@ -161,14 +156,24 @@ func get_event_received():
$Players.add_child(instance) $Players.add_child(instance)
#$Players.add_child(scene) #$Players.add_child(scene)
maxplayer += 1 maxplayer += 1
for child3 in $Players.get_children():
print(" -> ", child3.get_name())
var child2 = $Players.find_child(str(mid), false, false) var child2 = $Players.find_child(str(mid), false, false)
child2.set_global_position(Vector3(mx, my, mz)) child2.set_global_position(Vector3(mx, my, mz))
else: else:
child.set_global_position(Vector3(mx, my, mz)) 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. # Called every frame. 'delta' is the elapsed time since the previous frame.
@ -190,42 +195,35 @@ func _process(_delta):
pass pass
elif dataEnet.get_state() == ENetPacketPeer.STATE_DISCONNECTED: elif dataEnet.get_state() == ENetPacketPeer.STATE_DISCONNECTED:
var _event = enet.service() var _event = enet.service()
print("STATE_DISCONNECTED")
elif dataEnet.get_state() == ENetPacketPeer.STATE_ACKNOWLEDGING_CONNECT: elif dataEnet.get_state() == ENetPacketPeer.STATE_ACKNOWLEDGING_CONNECT:
var _event = enet.service() var _event = enet.service()
print("STATE_ACKNOWLEDGING_CONNECT")
elif dataEnet.get_state() == ENetPacketPeer.STATE_CONNECTION_PENDING: elif dataEnet.get_state() == ENetPacketPeer.STATE_CONNECTION_PENDING:
var _event = enet.service() var _event = enet.service()
print("STATE_CONNECTION_PENDING")
elif dataEnet.get_state() == ENetPacketPeer.STATE_CONNECTION_SUCCEEDED: elif dataEnet.get_state() == ENetPacketPeer.STATE_CONNECTION_SUCCEEDED:
var _event = enet.service() var _event = enet.service()
print("STATE_CONNECTION_SUCCEEDED")
elif dataEnet.get_state() == ENetPacketPeer.STATE_DISCONNECT_LATER: elif dataEnet.get_state() == ENetPacketPeer.STATE_DISCONNECT_LATER:
var _event = enet.service() var _event = enet.service()
print("STATE_DISCONNECT_LATER")
elif dataEnet.get_state() == ENetPacketPeer.STATE_DISCONNECTING: elif dataEnet.get_state() == ENetPacketPeer.STATE_DISCONNECTING:
var _event = enet.service() var _event = enet.service()
print("STATE_DISCONNECTING")
elif dataEnet.get_state() == ENetPacketPeer.STATE_ACKNOWLEDGING_DISCONNECT: elif dataEnet.get_state() == ENetPacketPeer.STATE_ACKNOWLEDGING_DISCONNECT:
var _event = enet.service() var _event = enet.service()
print("STATE_ACKNOWLEDGING_DISCONNECT")
elif dataEnet.get_state() == ENetPacketPeer.STATE_ZOMBIE: elif dataEnet.get_state() == ENetPacketPeer.STATE_ZOMBIE:
var _event = enet.service() var _event = enet.service()
print("STATE_ZOMBIE")
else: else:
var _event = enet.service() var _event = enet.service()
func _process_ter(_delta): func connect_enet(_name:String, _listen_ip:String, _listen_port:int):
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):
player_name = _name 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) print("My name:" + player_name)

View file

@ -17,10 +17,10 @@ extern crate enet;
use std::net::{Ipv4Addr}; use std::net::{Ipv4Addr};
use log::{debug, error, info, trace, warn, Level, LevelFilter, Metadata, Record, SetLoggerError}; use log::{debug, error, info, trace, warn, Level, LevelFilter, Metadata, Record, SetLoggerError};
use clap::Parser; use clap::Parser;
use anyhow::Context; use anyhow::Context;
use enet::*; use enet::*;
use std::*; use std::*;
use std::time::{Instant};
use chrono::Utc; use chrono::Utc;
use byteorder::{ByteOrder, LittleEndian, ReadBytesExt}; use byteorder::{ByteOrder, LittleEndian, ReadBytesExt};
@ -119,7 +119,15 @@ struct User {
x: f64, x: f64,
y: f64, y: f64,
z: 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 { impl User {
@ -134,6 +142,7 @@ impl User {
*/ */
pub fn set_inactive(&mut self) { pub fn set_inactive(&mut self) {
self.active = false; self.active = false;
self.lasttime = Instant::now();
} }
pub fn set_active(&mut self) { pub fn set_active(&mut self) {
self.active = true; self.active = true;
@ -175,12 +184,15 @@ impl User {
return pos; return pos;
} }
*/ */
pub fn push_packet(&self, data:&mut Vec<u8>) { pub fn push_packet_get_position(&self, data:&mut Vec<u8>) {
push_u64(data, self.id); push_u64(data, self.id);
push_f64(data, self.x); push_f64(data, self.x);
push_f64(data, self.y); push_f64(data, self.y);
push_f64(data, self.z); push_f64(data, self.z);
} }
pub fn push_packet_id(&self, data:&mut Vec<u8>) {
push_u64(data, self.id);
}
/* /*
pub fn get_packet(&mut self) -> Vec<u8> { pub fn get_packet(&mut self) -> Vec<u8> {
let mut data:Vec<u8> = Vec::new(); let mut data:Vec<u8> = Vec::new();
@ -195,7 +207,9 @@ impl User {
impl std::fmt::Display for User { impl std::fmt::Display for User {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 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 { pub fn add(&mut self, username:String, address: Address) -> u64 {
let id = self.get_new_id(); 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 id
} }
pub fn update_pos(&mut self, address: Address, x:f64, y:f64, z:f64) { 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()); error!("invalid address {}:{}", address.ip(), address.port());
Err("invalid address") Err("invalid address")
} }
pub fn push_packet(&self, data:&mut Vec<u8>) -> u8 { pub fn push_packet_get_position(&self, data:&mut Vec<u8>, getall: bool) -> u8 {
let mut nb:u8 = 0; let mut nb:u8 = 0;
for user in &self.users { for user in &self.users {
if user.active && user.position_updated { if user.active && (getall || user.position_updated ) {
user.push_packet(data); user.push_packet_get_position(data);
nb += 1;
}
}
nb
}
pub fn push_packet_user_will_remove(&mut self, data:&mut Vec<u8>, 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; 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 { 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<u8> = Vec::new(); let mut data:Vec<u8> = Vec::new();
data.push(1); // return connexion request data.push(1); // return connexion request
data.push(0); // return ok data.push(0); // return ok
user.push_packet(&mut data); user.push_packet_get_position(&mut data);
let c: &[u8] = &data; let c: &[u8] = &data;
send_message(sender, c) send_message(sender, c)
} }
@ -500,6 +542,8 @@ struct Cli {
fn main() -> anyhow::Result<()> { fn main() -> anyhow::Result<()> {
let cli = Cli::parse(); let cli = Cli::parse();
let enet = Enet::new().context("could not initialize ENet")?; let enet = Enet::new().context("could not initialize ENet")?;
let mut force_update : u8 = 0;
let mut launch_cleanup : u8 = 60;
if cli.trace { if cli.trace {
loginit(LevelFilter::Trace).unwrap(); loginit(LevelFilter::Trace).unwrap();
@ -535,6 +579,13 @@ fn main() -> anyhow::Result<()> {
Some(Event::Connect(_)) => debug!("new connection!"), Some(Event::Connect(_)) => debug!("new connection!"),
Some(Event::Disconnect(ref sender, _)) => { Some(Event::Disconnect(ref sender, _)) => {
users.set_inactive(sender.address()); 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!"); debug!("disconnect!");
}, },
Some(Event::Receive { Some(Event::Receive {
@ -569,37 +620,53 @@ fn main() -> anyhow::Result<()> {
match check { match check {
StateUsers::NotDefined => { StateUsers::NotDefined => {
debug!("NotDefined"); debug!("NotDefined");
force_update = 10;
let _id = users.add(s.to_string(), sender.address()); let _id = users.add(s.to_string(), sender.address());
let ret = users.get_user(sender.address()); let ret = users.get_user(sender.address());
match ret { 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) => {}, Err(_e) => {},
}; };
} }
StateUsers::Inactive => { StateUsers::Inactive => {
debug!("Inactive"); debug!("Inactive");
force_update = 10;
let _id = users.set_active(sender.address()); let _id = users.set_active(sender.address());
let ret = users.get_user(sender.address()); let ret = users.get_user(sender.address());
match ret { 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) => {}, Err(_e) => {},
}; };
} }
StateUsers::UpdateUser => { StateUsers::UpdateUser => {
debug!("UpdateUser"); debug!("UpdateUser");
force_update = 10;
let _id = users.update_username(s.to_string(), sender.address()); let _id = users.update_username(s.to_string(), sender.address());
let ret = users.get_user(sender.address()); let ret = users.get_user(sender.address());
match ret { 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) => {}, Err(_e) => {},
}; };
} }
StateUsers::UpdateAddress => { StateUsers::UpdateAddress => {
debug!("UpdateAddress"); debug!("UpdateAddress");
force_update = 10;
let _id = users.update_address(s.to_string(), sender.address()); let _id = users.update_address(s.to_string(), sender.address());
let ret = users.get_user(sender.address()); let ret = users.get_user(sender.address());
match ret { 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) => {}, Err(_e) => {},
}; };
} }
@ -609,6 +676,7 @@ fn main() -> anyhow::Result<()> {
} }
StateUsers::Done => { StateUsers::Done => {
debug!("Done"); debug!("Done");
force_update = 10;
let _id = users.get_id(sender.address()); let _id = users.get_id(sender.address());
let ret = users.get_user(sender.address()); let ret = users.get_user(sender.address());
match ret { match ret {
@ -628,12 +696,15 @@ fn main() -> anyhow::Result<()> {
users.update_pos(sender.address(), x, y, z); users.update_pos(sender.address(), x, y, z);
} }
_ => { _ => {
send_message_connect_ko(sender.clone()).unwrap();
/*
let mut peer = sender.clone(); let mut peer = sender.clone();
peer.send_packet ( peer.send_packet (
Packet::new(b"youpia", PacketMode::ReliableSequenced).unwrap(), Packet::new(b"youpia", PacketMode::ReliableSequenced).unwrap(),
1, 1,
) )
.context("sending packet failed")?; .context("sending packet failed")?;
*/
} }
} }
}, },
@ -643,12 +714,21 @@ fn main() -> anyhow::Result<()> {
{ {
let mut data:Vec<u8> = Vec::new(); let mut data:Vec<u8> = Vec::new();
let mut data2:Vec<u8> = Vec::new(); let mut data2:Vec<u8> = Vec::new();
let mut data3:Vec<u8> = Vec::new();
data.push(3); // return connexion request 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.push(nb); // number user
data.append(&mut data2); 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; let c: &[u8] = &data;
if nb > 0 { if nb > 0 || nbuserremove > 0 {
for peer in host.peers() { for peer in host.peers() {
if peer.state() == PeerState::Connected { if peer.state() == PeerState::Connected {
trace!("peer: {}:{}", peer.address().ip(), peer.address().port()); trace!("peer: {}:{}", peer.address().ip(), peer.address().port());
@ -658,6 +738,12 @@ fn main() -> anyhow::Result<()> {
users.clear_position_updated(); 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() { for peer in host.peers() {
if peer.state() == PeerState::Connected { if peer.state() == PeerState::Connected {