extends Node class_name ServerDiscovery const PORT := 26566 const PORT_RANGE := 10 # cannot listen to the same port on one device signal server_added(id: String, ip: String, port: int) signal server_removed(id: String, ip: String) var server: UDPServer = null var client: PacketPeerUDP = null var port_offset: int var id: String var servers: Array[String] = [] var enabled := false func enable_server(server_port: int): enabled = true var data = "%s|AVAILABLE|%d" %[id,server_port] _broadcast_packet(data.to_utf8_buffer()) func disable_server(): enabled = false var data = "%s|NOT_AVAILABLE" %id _broadcast_packet(data.to_utf8_buffer()) func _ready(): id = _generate_id() _init_server() _init_client() func _process(_delta): server.poll() while(server.is_connection_available()): var peer = server.take_connection() while(peer.get_available_packet_count() > 0): var packet = peer.get_packet() var packet_str = packet.get_string_from_utf8() if (packet_str.begins_with(id)): continue var ip = peer.get_packet_ip() var port = peer.get_packet_port() print(id, " | Received data from ", ip, ":", port, " => ", packet_str) var data = packet_str.split("|") var conn_id = data[0] var conn_detail = data[1] var key = "%s:%s" %[ip, port] if (conn_detail == "AVAILABLE" and key not in servers): var conn_actual_server_port = int(data[2]) servers.append(key) server_added.emit(conn_id, ip, conn_actual_server_port) elif (conn_detail == "NOT_AVAILABLE" and key in servers): servers.erase(key) server_removed.emit(conn_id, ip) elif (conn_detail == "DISCOVERY" and enabled): var available_data = "%s|AVAILABLE" %id _broadcast_packet(available_data.to_utf8_buffer()) func _exit_tree(): var data = "%s|NOT_AVAILABLE" %id _broadcast_packet(data.to_utf8_buffer()) func _init_server(): server = UDPServer.new() for offset in range(PORT_RANGE): var err = server.listen(PORT + offset) if !err: port_offset = offset break print("Server ", id, " initialized on port ", PORT + port_offset) func _init_client(): client = PacketPeerUDP.new() client.set_broadcast_enabled(true) var data = "%s|DISCOVERY" %id _broadcast_packet(data.to_utf8_buffer()) func _broadcast_packet(buffer: PackedByteArray): for offset in range(PORT_RANGE): client.connect_to_host("255.255.255.255", PORT + offset) client.put_packet(buffer) func _generate_id() -> String: var id_len = 5 var from = 'A'.unicode_at(0) var to = 'Z'.unicode_at(0) var result:= "" for i in range(id_len): var rand_char = char(randi_range(from, to)) result += rand_char return result