tcg/server_discovery.gd

101 lines
2.6 KiB
GDScript3
Raw Normal View History

2025-01-25 11:45:55 +07:00
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