extends Node @export var listen_ip:String = "127.0.0.1": set = set_ip func set_ip(value): listen_ip = value disconnect_server() @export var listen_port:int = 33333: set = set_port func set_port(value:int): listen_port = value disconnect_server() @export var username:String = "": set = set_username func set_username(value): username = value disconnect_server() @export var player_position:Node3D = null : set = set_player_position func set_player_position(value:Node3D): player_position = value enum Connexion{ NONE, ACCOUNT_REFUSED, CONNECTING, CONNECTED, } @export var state_connexion:Connexion = Connexion.NONE @export var id:int = 0: get: return id set(value): id = value signal connexion_updated(new_state) signal update_my_position(pos, rot) signal update_player_position(id, pos, rot) signal remove_player(id) var enet:ENetConnection var dataEnet:ENetPacketPeer var errorEnet:Error func get_id() -> int: return id func is_offline() -> bool: return state_connexion != Connexion.CONNECTED func update_state(value): state_connexion = value connexion_updated.emit(state_connexion) func disconnect_server(): update_state(Connexion.NONE) func create_server_enet(): print("------ create_server_enet") enet = ENetConnection.new() errorEnet = enet.create_host(10) if errorEnet != OK: print("ERROR ENET.create_host: ", errorEnet) return 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: print("ERROR dataEnet == null: ") return elif not dataEnet.is_active(): print("ERROR enet.connect_to_host: ", dataEnet.is_active()) return update_state(Connexion.CONNECTING) func connect_server(): if username == "": return if player_position == null: return create_server_enet() connect_to_host() func _ready(): print("------ Multi initialized") update_state(Connexion.NONE) func bad_account(): set_username("") update_state(Connexion.ACCOUNT_REFUSED) func get_event_received(): var data = dataEnet.get_packet() #print("get: ", data) if data[0] == 1: # Return connexion if data[1] == 0: # OK id = data.decode_u64(2) var x:float = data.decode_double(2+8) var y:float = data.decode_double(2+16) var z:float = data.decode_double(2+24) var rx:float = data.decode_double(2+32) var ry:float = data.decode_double(2+40) var rz:float = data.decode_double(2+48) var _tick:int = data.decode_double(2+1) print("MyID:", id) #print("id:", id, " x:", x, " y:", y, " z:", z) update_my_position.emit(Vector3(x, y, z), Vector3(rx, ry, rz)) #self.set_player_position(Vector3(x, y, z)) update_state(Connexion.CONNECTED) else: # KO bad_account() elif data[0] == 3: # Get position if id == 0: return var nb:int = data[1] var pos:int = 2 for i in nb: var mid:int = data.decode_u64(pos) var mx:float = data.decode_double(pos+8) var my:float = data.decode_double(pos+16) var mz:float = data.decode_double(pos+24) var rx:float = data.decode_double(pos+32) var ry:float = data.decode_double(pos+40) var rz:float = data.decode_double(pos+48) var tick:int = data.decode_u8(pos+56) pos += 57 if mid == id: #print("Me id:", mid, " x:", mx, " y:", my, " z:", mz) continue print("pos:", pos, " id:", mid, " tick:", tick, " x:", mx, " y:", my, " z:", mz, " rx:", rx, " ry:", ry, " rz:", rz) update_player_position.emit(mid, Vector3(mx, my, mz), Vector3(rx, ry, rz)) var nbuserremove:int = 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 remove_player.emit(mid) func send_account(): var data:PackedByteArray = PackedByteArray() data.append(1) data.append(len(username)) var packed_array = username.to_ascii_buffer() data += packed_array print(username, " -> size:", data.size(), " / " , len(username) ) errorEnet = dataEnet.send(1, data, 1) if errorEnet != OK: print("ERROR ENET: ", errorEnet) return func get_player_position(): if state_connexion != Connexion.CONNECTED: return var pos:PackedFloat64Array = PackedFloat64Array() var posRaw:Vector3 = player_position.get_my_position() #get_position() pos.append(posRaw.x) pos.append(posRaw.y) pos.append(posRaw.z) var rotRaw:Vector3 = player_position.get_my_rotation() pos.append(rotRaw.x) pos.append(rotRaw.y) pos.append(rotRaw.z) var data:PackedByteArray = PackedByteArray() data += pos.to_byte_array() errorEnet = dataEnet.send(2, data, 1) if errorEnet == ERR_UNCONFIGURED: update_state(Connexion.NONE) elif errorEnet != OK: print("ERROR ENET: ", errorEnet) return func _process(_delta): if state_connexion == Connexion.ACCOUNT_REFUSED: return elif state_connexion == Connexion.NONE: connect_server() return get_player_position() if state_connexion == Connexion.CONNECTING: send_account() if dataEnet.get_state() == ENetPacketPeer.STATE_CONNECTED: var event = enet.service() if event[0] == ENetConnection.EVENT_RECEIVE: get_event_received() elif dataEnet.get_state() == ENetPacketPeer.STATE_CONNECTING: var event = enet.service() if event[0] == ENetConnection.EVENT_RECEIVE: 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() print("STATE_UNKNOWN")