Add ready lobby and reconnect support
This commit is contained in:
1 parent
19b1a67773
commit
32594c7f81
8 files changed
+215
-36
No files matched your search
+62
-7
@@ -32,6 +32,9 @@ var current_host := ""
|
||||
var current_match = null
|
||||
var matchmaker_ticket := ""
|
||||
var private_room_code := ""
|
||||
var lobby_ready := false
|
||||
var intentional_disconnect := false
|
||||
var reconnect_in_progress := false
|
||||
var account_manager: AccountManager
|
||||
var auto_connect_enabled := true
|
||||
|
||||
@@ -83,21 +86,27 @@ func _authenticate_on(host: String, port: int, scheme: String) -> bool:
|
||||
|
||||
func _after_authentication() -> void:
|
||||
socket = Nakama.create_socket_from(client)
|
||||
socket.received_matchmaker_matched.connect(_on_matchmaker_matched)
|
||||
socket.received_match_state.connect(_on_match_state)
|
||||
socket.closed.connect(_on_socket_closed)
|
||||
_bind_socket_signals()
|
||||
var result = await socket.connect_async(session, true, 5)
|
||||
if result == null or result.is_exception():
|
||||
last_error = "Echtzeitverbindung konnte nicht aufgebaut werden"
|
||||
socket = null
|
||||
_set_connection_state("authenticated")
|
||||
else:
|
||||
intentional_disconnect = false
|
||||
_set_connection_state("online")
|
||||
authenticated.emit(session.user_id, session.username)
|
||||
await flush_pending_scores()
|
||||
|
||||
|
||||
func _bind_socket_signals() -> void:
|
||||
socket.received_matchmaker_matched.connect(_on_matchmaker_matched)
|
||||
socket.received_match_state.connect(_on_match_state)
|
||||
socket.closed.connect(_on_socket_closed)
|
||||
|
||||
|
||||
func disconnect_from_server() -> void:
|
||||
intentional_disconnect = true
|
||||
if socket:
|
||||
socket.close()
|
||||
socket = null
|
||||
@@ -105,6 +114,7 @@ func disconnect_from_server() -> void:
|
||||
current_match = null
|
||||
matchmaker_ticket = ""
|
||||
private_room_code = ""
|
||||
lobby_ready = false
|
||||
_set_connection_state("offline")
|
||||
|
||||
|
||||
@@ -119,7 +129,7 @@ func submit_run(record: Dictionary) -> bool:
|
||||
if not is_authenticated():
|
||||
return false
|
||||
var payload := record.duplicate(true)
|
||||
payload["client_version"] = "0.20"
|
||||
payload["client_version"] = "0.21"
|
||||
var result = await client.rpc_async(session, "submit_run", JSON.stringify(payload))
|
||||
var parsed := _parse_rpc_result(result)
|
||||
if parsed.is_empty() or not bool(parsed.get("accepted", false)):
|
||||
@@ -160,6 +170,7 @@ func load_leaderboard(map_index: int, difficulty_index: int, endless: bool, limi
|
||||
|
||||
|
||||
func begin_matchmaking(mode := "quick", difficulty := 1) -> bool:
|
||||
intentional_disconnect = false
|
||||
if not is_online() or socket == null:
|
||||
matchmaking_state_changed.emit("offline")
|
||||
return false
|
||||
@@ -178,6 +189,7 @@ func begin_matchmaking(mode := "quick", difficulty := 1) -> bool:
|
||||
|
||||
|
||||
func cancel_matchmaking() -> void:
|
||||
intentional_disconnect = true
|
||||
if socket and not matchmaker_ticket.is_empty():
|
||||
await socket.remove_matchmaker_async(matchmaker_ticket)
|
||||
matchmaker_ticket = ""
|
||||
@@ -189,6 +201,7 @@ func cancel_matchmaking() -> void:
|
||||
|
||||
|
||||
func create_private_room(difficulty := 1) -> bool:
|
||||
intentional_disconnect = false
|
||||
if not is_online() or socket == null:
|
||||
matchmaking_state_changed.emit("offline")
|
||||
return false
|
||||
@@ -209,11 +222,13 @@ func create_private_room(difficulty := 1) -> bool:
|
||||
return false
|
||||
private_room_created.emit(private_room_code)
|
||||
matchmaking_state_changed.emit("hosting")
|
||||
await send_match_command(OP_READY, {})
|
||||
lobby_ready = false
|
||||
await set_lobby_ready(false)
|
||||
return true
|
||||
|
||||
|
||||
func join_private_room(room_code: String) -> bool:
|
||||
intentional_disconnect = false
|
||||
if not is_online() or socket == null:
|
||||
matchmaking_state_changed.emit("offline")
|
||||
return false
|
||||
@@ -233,11 +248,13 @@ func join_private_room(room_code: String) -> bool:
|
||||
matchmaking_state_changed.emit("room_not_found")
|
||||
return false
|
||||
matchmaking_state_changed.emit("matched")
|
||||
await send_match_command(OP_READY, {})
|
||||
lobby_ready = false
|
||||
await set_lobby_ready(false)
|
||||
return true
|
||||
|
||||
|
||||
func _on_matchmaker_matched(matched) -> void:
|
||||
intentional_disconnect = false
|
||||
matchmaker_ticket = ""
|
||||
current_match = await socket.join_matched_async(matched)
|
||||
if current_match == null or current_match.is_exception():
|
||||
@@ -245,7 +262,14 @@ func _on_matchmaker_matched(matched) -> void:
|
||||
return
|
||||
matchmaking_state_changed.emit("matched")
|
||||
match_found.emit(current_match)
|
||||
await send_match_command(OP_READY, {})
|
||||
lobby_ready = false
|
||||
await set_lobby_ready(false)
|
||||
|
||||
|
||||
func set_lobby_ready(value: bool) -> bool:
|
||||
lobby_ready = value
|
||||
var player_name := account_manager.display_name if account_manager else session.username
|
||||
return await send_match_command(OP_READY, {"ready": value, "name": player_name})
|
||||
|
||||
|
||||
func send_match_command(op_code: int, payload: Dictionary) -> bool:
|
||||
@@ -276,6 +300,7 @@ func leave_current_match() -> void:
|
||||
await socket.leave_match_async(current_match.match_id)
|
||||
current_match = null
|
||||
private_room_code = ""
|
||||
lobby_ready = false
|
||||
|
||||
|
||||
func _on_match_state(data) -> void:
|
||||
@@ -291,8 +316,38 @@ func _on_match_state(data) -> void:
|
||||
|
||||
|
||||
func _on_socket_closed() -> void:
|
||||
var reconnect_match_id := ""
|
||||
if not intentional_disconnect and current_match != null:
|
||||
reconnect_match_id = String(current_match.match_id)
|
||||
current_match = null
|
||||
if connection_state != "offline":
|
||||
_set_connection_state("authenticated")
|
||||
if not reconnect_match_id.is_empty() and not reconnect_in_progress:
|
||||
reconnect_in_progress = true
|
||||
matchmaking_state_changed.emit("reconnecting")
|
||||
_recover_match.call_deferred(reconnect_match_id)
|
||||
|
||||
|
||||
func _recover_match(match_id: String) -> void:
|
||||
for attempt in 5:
|
||||
await get_tree().create_timer(1.5 + attempt).timeout
|
||||
if intentional_disconnect or not is_authenticated():
|
||||
break
|
||||
socket = Nakama.create_socket_from(client)
|
||||
_bind_socket_signals()
|
||||
var connected = await socket.connect_async(session, true, 5)
|
||||
if connected == null or connected.is_exception():
|
||||
continue
|
||||
var rejoined = await socket.join_match_async(match_id)
|
||||
if rejoined != null and not rejoined.is_exception():
|
||||
current_match = rejoined
|
||||
intentional_disconnect = false
|
||||
reconnect_in_progress = false
|
||||
_set_connection_state("online")
|
||||
matchmaking_state_changed.emit("reconnected")
|
||||
return
|
||||
reconnect_in_progress = false
|
||||
matchmaking_state_changed.emit("connection_lost")
|
||||
|
||||
|
||||
func _device_id() -> String:
|
||||
|
||||
Reference in new issue
Block a user