100 lines
2.6 KiB
GDScript
100 lines
2.6 KiB
GDScript
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
|