Last active
March 7, 2021 02:41
-
-
Save nisovin/83881d8e95dd5fdc145936ac4b11ccef to your computer and use it in GitHub Desktop.
Use Godot's UDP multicast feature to find host games on the LAN. Largely untested.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends Node | |
class_name LANFinder | |
const MULTICAST_ADDRESS = "239.10.10.10" | |
const MULTICAST_PORT = 33221 | |
signal host_found(ip, info) | |
signal stopped() | |
var udp := PacketPeerUDP.new() | |
var thread := Thread.new() | |
var mutex := Mutex.new() | |
var stop_request := false | |
var host := false | |
var host_info := {} | |
var client := false | |
func set_as_host(info: Dictionary) -> void: | |
if host or client: return | |
host = true | |
host_info = info | |
_init_udp() | |
func update_host_info(info: Dictionary) -> void: | |
mutex.lock() | |
host_info = info | |
mutex.unlock() | |
func search_for_hosts(timeout: float = 10) -> void: | |
if host or client: return | |
client = true | |
_init_udp() | |
udp.put_var({"msg": "ping"}) | |
if timeout > 0: | |
yield(Engine.get_main_loop().create_timer(timeout), "timeout") | |
if client: | |
stop() | |
func stop() -> void: | |
mutex.lock() | |
stop_request = true | |
mutex.unlock() | |
udp.close() | |
func _received_host_info(ip: String, info: Dictionary) -> void: | |
emit_signal("host_found", ip, info) | |
func _init_udp() -> void: | |
udp.listen(MULTICAST_PORT) | |
udp.set_dest_address(MULTICAST_ADDRESS, MULTICAST_PORT) | |
for i in IP.get_local_interfaces(): | |
udp.join_multicast_group(MULTICAST_ADDRESS, i.name) | |
thread.start(self, "_listen_thread") | |
func _end_thread() -> void: | |
thread.wait_to_finish() | |
stop_request = false | |
emit_signal("stopped") | |
host = false | |
client = false | |
func _listen_thread(x) -> void: | |
var loop = true | |
while loop: | |
udp.wait() | |
if udp.get_available_packet_count() > 0: | |
var data := udp.get_var() as Dictionary | |
if data and data.has("msg"): | |
var ip := udp.get_packet_ip() | |
if data.msg == "ping" and host: | |
mutex.lock() | |
udp.put_var({"msg": "pong", "info": host_info}) | |
mutex.unlock() | |
elif data.msg == "pong" and client: | |
call_deferred("_received_host_info", ip, data.info) | |
mutex.lock() | |
if stop_request: | |
loop = false | |
mutex.unlock() | |
call_deferred("_end_thread") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment