aboutsummaryrefslogtreecommitdiff
path: root/client/multiplayer.gd
diff options
context:
space:
mode:
Diffstat (limited to 'client/multiplayer.gd')
-rw-r--r--client/multiplayer.gd67
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):