I have problems with Networking

Godot Version

Godot 4.4.1.

Question

ENetMultiplayerPeer
What I need to do to fix online connection/lobby ?
Buttons aren’t being created in the lobby for client.
Problems with the client connection and I have no idea how to transfer information from host to client ?

extends Node

@export var hint_txt: Label
@export var server_button_scene: PackedScene
@export var no_servers_label: Label
@export var container: VBoxContainer
@export var join_game_back: Button
@export var refresh_btn: Button
var player_model: Node3D = null
var servers: Array[Dictionary] = []
var is_hosting: bool = false
var save_system: Node = null
var SFX: Node = null
var peer: ENetMultiplayerPeer = null
var host_port: int = 9900
var host_ip: String = "127.0.0.1"
@export_group("Game")
@export var map_btn: Button
var online_game_scene: PackedScene
var current_map_index: int
var game_mode_index: int
@export var tex_map_im: TextureRect
@export var modes: Array[GameModeClass] = []

func _ready() -> void:
	SFX = Global.find_node_in_group("SFX")
	save_system = Global.find_node_in_group("save_system")
	save_system.load_options()
	save_system.system_s["online"] = true
	save_system.save_options(false)
	refresh_btn.pressed.connect(Callable(self, "_on_refresh_btn_pressed"))
	_update_server_list()
	current_map_index = 0
	update_map_ui()

func update_map_ui() -> void:
	if modes != null:
		for i in modes:
			i.load_images()
	tex_map_im.texture = modes[game_mode_index].map_im[current_map_index]
	var localized_string: String = tr("Map {n}").replace("{n}", str(current_map_index + 1))
	map_btn.text = localized_string
	online_game_scene = load(modes[game_mode_index].map_scene_path + str(current_map_index) + ".tscn")

func next_map() -> void:
	current_map_index = (current_map_index + 1) % modes[game_mode_index].map_im.size()
	update_map_ui()

func prev_map() -> void:
	current_map_index = (current_map_index - 1 + modes[game_mode_index].map_im.size()) % modes[game_mode_index].map_im.size()
	update_map_ui()

func _server_in_list(new_server: Dictionary) -> bool:
	for s in servers:
		if s["ip"] == new_server["ip"] and s["port"] == new_server["port"]:
			return true
	return false

func _on_Host_pressed() -> void:
	create_server(host_port, 6)

func _on_refresh_btn_pressed() -> void:
	_update_server_list()

func create_server(port: int = 9900, max_clients: int = 6) -> void:
	var mp := get_tree().get_multiplayer()

	if mp.multiplayer_peer != null:
		mp.multiplayer_peer = null

	peer = ENetMultiplayerPeer.new()
	var err := peer.create_server(port, max_clients)
	if err != OK:
		push_error("[DEBUG] PORT IS BUSY (err=%d)" % [port, err])
		peer = null
		return

	mp.multiplayer_peer = peer
	is_hosting = true
	host_port = port
	host_ip = "127.0.0.1"

	var server_entry: Dictionary = {"name": "Server", "ip": host_ip, "port": host_port}
	if not _server_in_list(server_entry):
		servers.append(server_entry)
		_update_server_list()
		rpc("rpc_add_server", server_entry)

	_connect_multiplayer_signals(mp)
	load_online_scene(online_game_scene)

func join_server(ip: String, port: int = 9900) -> void:
	var mp := get_tree().get_multiplayer()
	if mp.multiplayer_peer != null:
		mp.multiplayer_peer = null

	peer = ENetMultiplayerPeer.new()
	var err := peer.create_client(ip, port)
	if err != OK:
		push_error("No connection %s:%d (err=%d)" % [ip, port, err])
		peer = null
		return

	mp.multiplayer_peer = peer
	is_hosting = false

	_connect_multiplayer_signals(mp)

func _connect_multiplayer_signals(mp: MultiplayerAPI) -> void:
	if not mp.is_connected("peer_connected", Callable(self, "_on_peer_connected")):
		mp.peer_connected.connect(Callable(self, "_on_peer_connected"))
	if not mp.is_connected("peer_disconnected", Callable(self, "_on_peer_disconnected")):
		mp.peer_disconnected.connect(Callable(self, "_on_peer_disconnected"))
	if not mp.is_connected("connected_to_server", Callable(self, "_on_connected_to_server")):
		mp.connected_to_server.connect(Callable(self, "_on_connected_to_server"))
	if not mp.is_connected("connection_failed", Callable(self, "_on_connection_failed")):
		mp.connection_failed.connect(Callable(self, "_on_connection_failed"))
	if not mp.is_connected("server_disconnected", Callable(self, "_on_server_disconnected")):
		mp.server_disconnected.connect(Callable(self, "_on_server_disconnected"))

@rpc("any_peer")
func rpc_add_server(server: Dictionary) -> void:
	if not _server_in_list(server):
		servers.append(server)
		_update_server_list()

func _on_connected_to_server() -> void:
	load_online_scene(online_game_scene)

func _on_connection_failed() -> void:
	push_error("Соединение не удалось.")
	var mp := get_tree().get_multiplayer()
	mp.multiplayer_peer = null
	peer = null
	is_hosting = false

func _on_server_disconnected() -> void:
	print("Server disconnected")
	_leave_online_scene()

func _on_peer_connected(id: int) -> void:
	print("New client:", id)
	if is_hosting:
		
		for server_entry in servers:
			rpc_id(id, "rpc_add_server", server_entry)

func _on_peer_disconnected(id: int) -> void:
	print("peer_disconnected:", id)
	if id == 1 and not is_hosting:
		print("Host disconnected")
		_remove_local_server_entries()
		_leave_online_scene()

@rpc("any_peer", "call_local")
func rpc_player_joined(peer_id: int, player_name: String) -> void:
	print("Player connected:", player_name, "id:", peer_id)
	

func _remove_local_server_entries() -> void:
	var new_list: Array[Dictionary] = []
	for s in servers:
		if s.has("ip") and s.has("port"):
			if s["ip"] == host_ip and s["port"] == host_port:
				continue
		new_list.append(s)
	servers = new_list
	_update_server_list()

func load_online_scene(scene: PackedScene) -> void:
	self.visible = false
	var err := get_tree().change_scene_to_packed(scene)
	if err != OK:
		push_error("Cannot load online scene (err=%d)" % err)
		return

func _leave_online_scene() -> void:
	var mp := get_tree().get_multiplayer()
	if mp != null:
		mp.multiplayer_peer = null
	peer = null
	is_hosting = false
	_remove_local_server_entries()
	var err := get_tree().change_scene_to_file("res://Scene/Menu/4_online.tscn")
	if err != OK:
		push_error("Cannot load menu: err=%d" % err)
	self.visible = true

func _on_default_join_pressed() -> void:
	join_server("127.0.0.1", host_port)

func _update_server_list() -> void:
	for child in container.get_children():
		if child != refresh_btn and child != join_game_back and child != no_servers_label:
			child.queue_free()

	if servers.size() == 0:
		no_servers_label.text = "No Servers"
		print("[DEBUG] NO SERVERS")
	else:
		no_servers_label.text = "Servers: %d" % servers.size()
		for server in servers:

			var exists: bool = false
			for child in container.get_children():
				if child is Button and child.text.begins_with(server.get("name","Server")):
					exists = true
					break
			if exists:
				continue

			var btn: Button = server_button_scene.instantiate() as Button
			btn.text = "%s (%s:%d)" % [server.get("name","Server"), server.get("ip","?"), server.get("port",0)]
			btn.pressed.connect(Callable(self, "_on_server_button_pressed").bind(server))
			container.add_child(btn)
			print("Server button added: %s" % btn.text)


func _on_server_button_pressed(server: Dictionary) -> void:
	if server.has("ip") and server.has("port"):
		join_server(server["ip"], int(server["port"]))