diff options
Diffstat (limited to 'client/multiplayer.gd')
| -rw-r--r-- | client/multiplayer.gd | 67 |
1 files changed, 53 insertions, 14 deletions
diff --git a/client/multiplayer.gd b/client/multiplayer.gd index 5ce5bb93..d5d31322 100644 --- a/client/multiplayer.gd +++ b/client/multiplayer.gd @@ -23,25 +23,66 @@ static var VERSION_MAJOR: int = 12 static var VERSION_MINOR: int = 0 var connected := false -var socket := WebSocketPeer.new() +var socket: WebSocketPeer +var keep_alive := Timer.new() func _ready(): - print("Multiplayer connect") - socket.inbound_buffer_size = 1024 * 1024 * 4 - - var keep_alive := Timer.new() add_child(keep_alive) keep_alive.wait_time = 1. keep_alive.timeout.connect(send_keep_alive) - keep_alive.start() -func connect_to_url(url): - socket.connect_to_url(url) +func connect_to_urls(urls: Array[String]): + if urls.is_empty(): + connection_closed.emit("No connection address available.") + return + + var error_info: Dictionary[String, int] = {} + + # Create a WebSocketPeer for each url + var peers: Array[WebSocketPeer] = [] + for url: String in urls: + var ws := WebSocketPeer.new() + ws.inbound_buffer_size = 1024 * 1024 * 4 + var err := ws.connect_to_url(url) + if err == OK: peers.append(ws) + else: error_info[url] = err + + # Now keep polling until one of them is succesful, or we run out of peers. + # Peers are removed from the peers array when they fail to connect. + var open_peer_found := false + while not peers.is_empty() and not open_peer_found: + await get_tree().physics_frame + for peer: WebSocketPeer in peers: + peer.poll() + var state := peer.get_ready_state() + match state: + WebSocketPeer.STATE_CLOSED: + print("URL %s failed" % peer.get_requested_url()) + error_info[peer.get_requested_url()] = peer.get_close_code() + peers.erase(peer) + WebSocketPeer.STATE_OPEN: + # We found a connection that works. Close all others. + print("URL %s connected!" % peer.get_requested_url()) + socket = peer + var other_peers := peers.filter(func (p): return p != peer) + for p: WebSocketPeer in other_peers: + p.close() + open_peer_found = true + break + _: pass + + if not open_peer_found: + var err_msg: String = tr("c.error.could_not_connect") + for url: String in error_info.keys(): + err_msg += "\nURL %s failed with code %d" % [url, error_info[url]] + connection_closed.emit(err_msg) + return + connected = true + keep_alive.start() func _notification(what): - if what == NOTIFICATION_PREDELETE: - print("Multiplayer disconnect"); + if what == NOTIFICATION_PREDELETE and socket != null: socket.close() connected = false @@ -52,10 +93,8 @@ func _process(_delta): while socket.get_available_packet_count(): handle_packet(socket.get_packet()) if state == WebSocketPeer.STATE_CLOSED: - var code = socket.get_close_code() - var reason = socket.get_close_reason() if code == socket.STATE_CLOSED else tr("c.error.websocket.unavailable") - connection_closed.emit(tr("c.error.websocket").format([code, reason, code != -1])) - self.queue_free() + connection_closed.emit("c.error.connection_closed") + connected = false func fix_packet_types(val): match typeof(val): |