Im having troubles, cant seem to find it in docs. I need to know what IP and PORT client is connected to.

Started with this: https://docs.godotengine.org/en/stable/tutorials/networking/high_level_multiplayer.html

# Create client.
var peer = ENetMultiplayerPeer.new()
peer.create_client(IP_ADDRESS, PORT)
multiplayer.multiplayer_peer = peer

# Create server.
var peer = ENetMultiplayerPeer.new()
peer.create_server(PORT, MAX_CLIENTS)
multiplayer.multiplayer_peer = peer

Ok so here you can see, when you create host or client, you specify the IP and PORT.

But it seems to me that you have to keep track of what IP and PORT client was connected to. There is no way to probe "peer" when it is client to get the "HOST" ip and port that this peer is connected to.

Is this the case or am i missing something?

Why would i need this information later after client has joined the game? For server browser, so that it shows player/user which server you is currently joined to.

I thought i could probe the "peer" object to get the IP and port, but according to docs it doesnt have these properties.

https://docs.godotengine.org/en/stable/classes/class_multiplayerpeer.html#class-multiplayerpeer

https://docs.godotengine.org/en/stable/classes/class_enetmultiplayerpeer.html#class-enetmultiplayerpeer

https://docs.godotengine.org/en/stable/classes/class_multiplayerpeerextension.html#class-multiplayerpeerextension

  • xyz replied to this.
  • kuligs2 When you call create_server() or create_client() on ENetMultiplayerPeer object, its host property will get initialized. This property is an object of type ENetConnection. You can call get_peers() on it. This will return an array of ENetPacketPeer objects. I'm leaving to you as a homework to find the methods in this object that return the address and the port 😉

    kuligs2 When you call create_server() or create_client() on ENetMultiplayerPeer object, its host property will get initialized. This property is an object of type ENetConnection. You can call get_peers() on it. This will return an array of ENetPacketPeer objects. I'm leaving to you as a homework to find the methods in this object that return the address and the port 😉

      xyz a bit convoluted but i guess it gets the job done, unless godot devs decide to change the host peer to be some random id.

      • xyz replied to this.

        kuligs2 The whole thing is just a wrapper around ENet library so class architecture and functionality are coming from there.

          xyz also, multiplayer object can only be manipulated from main thread.

          E 0:00:08:0714   server_info_requester.gd:255 @ is_joined(): Multiplayer can only be manipulated from the main thread.
            <C++ Error>    Condition "!Thread::is_main_thread()" is true. Returning: Ref<MultiplayerAPI>()
            <C++ Source>   scene/main/scene_tree.cpp:1509 @ get_multiplayer()
            <Stack Trace>  server_info_requester.gd:255 @ is_joined()
                           server_info_requester.gd:125 @ parse_reply()
                           server_info_requester.gd:54 @ get_packet_loop()
          func is_joined(ip:String,port:int) -> bool:
          	
          	if multiplayer == null:
          		return false
          	if multiplayer.multiplayer_peer == null:
          		return false
          		
          	var host:ENetConnection = multiplayer.multiplayer_peer.host
          	var host_peers = host.get_peers()
          	
          	if host_peers.size() < 1:
          		return false
          	
          	var host_peer:ENetPacketPeer = host_peers[0]
          	var host_ip:String = host_peer.get_remote_address()
          	var host_port:int = host_peer.get_remote_port()
          	
          	if ip == host_ip and port == host_port:
          		return true
          	else:
          		return false

          This then breaks my whole idea of using it, because i was intendet to use it in the refresher thread that refreshes the server datas.
          Instead i will have to keep track of the host ip myself, setting it into some sort of "multiplayer/player" variable and then accessing it from other threads.

          xyz also i cant seem to get host IP when the game is created.

          	var host:ENetConnection = multiplayer.multiplayer_peer.host
          	var host_peers = host.get_peers()

          returns empty array.

          How am i supposed to know on what IP the host is hosting the game on before someone joins in?

          • xyz replied to this.

            kuligs2 By "host IP" you mean the local ip address? IP.get_local_addresses()

              xyz yes the local or either public, of the peer that create_server(). IP class just throws you all the interfaces ip addresses that computer has. I have like 10, so good luck knowing wich one is the real one 😃

              • xyz replied to this.

                xyz there are dyslexic people on the godot official forums aswell

                	var ip_adress :String
                
                	if OS.has_feature("windows"):
                		if OS.has_environment("COMPUTERNAME"):
                			ip_adress =  IP.resolve_hostname(str(OS.get_environment("COMPUTERNAME")),1)
                	elif OS.has_feature("x11"):
                		if OS.has_environment("HOSTNAME"):
                			ip_adress =  IP.resolve_hostname(str(OS.get_environment("HOSTNAME")),1)
                	elif OS.has_feature("OSX"):
                		if OS.has_environment("HOSTNAME"):
                			ip_adress =  IP.resolve_hostname(str(OS.get_environment("HOSTNAME")),1)

                This works, but... im not sure how to use this to determine... the problem im facing is how to cross reference the server that is hosted on your machine with a server list that gets sent to you on the request from masterlist server.

                The masterlist records the IP from which the valid packet was received from and uses that to add to serverlist. Then serves this list to anyone that requests it.

                So if i create game, i make req to master list to update th elist with my game. Masterlist see my public IP and add it to list then from the same host machine i make req to masterlist as client and i get a serverlist with a server that has my public IP, but the host has no idea what public IP it has 😃.

                For a local game sure, resolve hostname and bobs your unkie.

                EDIT:

                Ok so a quick maths lead me to make a http request to a well-known IP API.

                var http_request = HTTPRequest.new()
                
                func _ready():
                
                	add_child(http_request)
                	http_request.request_completed.connect(_on_http_completed)
                	var error = http_request.request("https://api.ipify.org")
                	if error:
                		print("Http error: ", error)
                func _on_http_completed(result, response_code, headers, body):
                	var json = JSON.new()
                	var lol = body.get_string_from_utf8()
                	
                	var response = json.parse_string(lol)
                	pass

                But im not sure if this is the best way to determine if im connected to the server that im hosting when served the server list from masterlist

                • xyz replied to this.

                  kuligs2 but the host has no idea what public IP it has 😃

                  How so if you got it via IP.resolve_hostname()?

                    xyz this returns only local IP based on the network the computer is on with the given hostname.

                    I thought about this problem in my dreams, i think ive come up with something. Instead of relying on IP garbage, maybe i could generate unique key for the lobby/server instance when the game is hosted, then crosscheck this against the serverinformation that i get when probing other servers, and based on that determine if this server (in server browser) is the one i created or not.

                    But how do i generate unique key? something that not repeatable. Not too long so that it wont fit in the allowed bits in the variable types that godot has and allows for millions billion gazillion variations?

                    Need to look up some algos..

                    So idk but ive come up with this. not the best but its the best i could think of:

                    	var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
                    	var arr = chars.to_utf8_buffer()
                    	var key_len = 24
                    	var result_key = ""
                    	for i in range(key_len):
                    		var c = ''
                    		c = chars.length()-1 - randi_range(0 , chars.length()-1)
                    		result_key += String.chr(arr[c])
                    
                    	print("Result: %s" % result_key)
                    Result: pTED2RvEJIlsGUJT8X08CHIU