fix(network): prevent null multiplayer peer crashes offline/teardown and fix Nakama RPC session validation
This commit is contained in:
+23
-17
@@ -63,7 +63,7 @@ func _ready():
|
||||
# Auto-start game if coming from lobby (already connected to match)
|
||||
# Works for both Nakama mode and LAN direct mode (ENet).
|
||||
var is_lan_connected = LobbyManager.is_lan_mode and multiplayer.has_multiplayer_peer() and multiplayer.multiplayer_peer.get_connection_status() == MultiplayerPeer.CONNECTION_CONNECTED
|
||||
if (NakamaManager.is_connected_to_nakama() or is_lan_connected) and multiplayer.get_unique_id() != 0:
|
||||
if multiplayer.has_multiplayer_peer() and (NakamaManager.is_connected_to_nakama() or is_lan_connected) and multiplayer.get_unique_id() != 0:
|
||||
print("Coming from lobby - auto-starting game...")
|
||||
await get_tree().process_frame
|
||||
_auto_start_from_lobby()
|
||||
@@ -221,7 +221,7 @@ func _setup_effect_elevation():
|
||||
|
||||
func _on_goal_count_updated(peer_id: int, count: int):
|
||||
# Only update for local player
|
||||
if peer_id == multiplayer.get_unique_id():
|
||||
if multiplayer.has_multiplayer_peer() and peer_id == multiplayer.get_unique_id():
|
||||
ui_manager.update_goal_count_label(count)
|
||||
|
||||
func _init_managers():
|
||||
@@ -564,15 +564,16 @@ func _process(delta):
|
||||
func _on_match_joined(match_id: String):
|
||||
var network_panel = get_node_or_null("PauseMenu/Panel/NetworkPanel")
|
||||
if network_panel:
|
||||
network_panel.get_node("NetworkInfo/UniquePeerID").text = str(multiplayer.get_unique_id())
|
||||
if multiplayer.is_server():
|
||||
network_panel.get_node("NetworkInfo/UniquePeerID").text = str(multiplayer.get_unique_id() if multiplayer and multiplayer.has_multiplayer_peer() else 0)
|
||||
if multiplayer and multiplayer.has_multiplayer_peer() and multiplayer.is_server():
|
||||
network_panel.get_node("NetworkInfo/NetworkSideDisplay").text = "Server (Match: %s)" % match_id
|
||||
_setup_host_game()
|
||||
else:
|
||||
network_panel.get_node("NetworkInfo/NetworkSideDisplay").text = "Client"
|
||||
_setup_client_game()
|
||||
else:
|
||||
if multiplayer.is_server():
|
||||
# If the UI isn't ready yet, still need to setup logic based on mode
|
||||
if multiplayer.has_multiplayer_peer() and multiplayer.is_server():
|
||||
_setup_host_game()
|
||||
else:
|
||||
_setup_client_game()
|
||||
@@ -683,7 +684,9 @@ func _spawn_lobby_client_sync(peer_id: int):
|
||||
|
||||
func _setup_client_game():
|
||||
"""Setup client when transitioning from lobby."""
|
||||
var my_id = multiplayer.get_unique_id()
|
||||
var my_id = 0
|
||||
if multiplayer and multiplayer.has_multiplayer_peer():
|
||||
my_id = multiplayer.get_unique_id()
|
||||
print("Client setup - my peer ID: ", my_id)
|
||||
|
||||
# INITIALIZE ARENA SIZE for Stop n Go locally to prevent out-of-bounds before sync arrives
|
||||
@@ -766,8 +769,8 @@ func _auto_start_from_lobby():
|
||||
# Update NetworkPanel in PauseMenu (if exists)
|
||||
var network_panel = get_node_or_null("PauseMenu/Panel/NetworkPanel")
|
||||
if network_panel:
|
||||
network_panel.get_node("NetworkInfo/UniquePeerID").text = str(multiplayer.get_unique_id())
|
||||
if multiplayer.is_server():
|
||||
network_panel.get_node("NetworkInfo/UniquePeerID").text = str(multiplayer.get_unique_id() if multiplayer and multiplayer.has_multiplayer_peer() else 0)
|
||||
if multiplayer and multiplayer.has_multiplayer_peer() and multiplayer.is_server():
|
||||
network_panel.get_node("NetworkInfo/NetworkSideDisplay").text = "Host (Match: %s)" % short_id
|
||||
else:
|
||||
network_panel.get_node("NetworkInfo/NetworkSideDisplay").text = "Client (Match: %s)" % short_id
|
||||
@@ -1385,7 +1388,7 @@ func add_player_character(peer_id: int, is_bot: bool = false):
|
||||
print("[Main] Set player %d name to %s from Lobby data" % [peer_id, p_name])
|
||||
break
|
||||
|
||||
if peer_id == multiplayer.get_unique_id():
|
||||
if multiplayer.has_multiplayer_peer() and peer_id == multiplayer.get_unique_id():
|
||||
GameStateManager.local_player_character = player_character
|
||||
ui_manager.set_local_player(player_character)
|
||||
if touch_controls:
|
||||
@@ -1608,7 +1611,7 @@ func sync_playerboard(player_id: int, new_playerboard: Array):
|
||||
player.playerboard = new_playerboard.duplicate()
|
||||
|
||||
# Update UI for local player
|
||||
if player_id == multiplayer.get_unique_id() and GameStateManager.local_player_character:
|
||||
if multiplayer.has_multiplayer_peer() and player_id == multiplayer.get_unique_id() and GameStateManager.local_player_character:
|
||||
ui_manager.update_playerboard_ui()
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
@@ -1628,7 +1631,7 @@ func sync_playerboard_slot(player_id: int, slot_index: int, item_id: int):
|
||||
return
|
||||
|
||||
# Update UI for local player only
|
||||
if player_id == multiplayer.get_unique_id() and GameStateManager.local_player_character:
|
||||
if multiplayer.has_multiplayer_peer() and player_id == multiplayer.get_unique_id() and GameStateManager.local_player_character:
|
||||
ui_manager.update_playerboard_ui()
|
||||
|
||||
|
||||
@@ -1649,7 +1652,7 @@ func verify_all_connections():
|
||||
@rpc
|
||||
func connection_verify(expected_players: Array):
|
||||
for peer_id in expected_players:
|
||||
if peer_id != multiplayer.get_unique_id() and not has_node(str(peer_id)):
|
||||
if multiplayer.has_multiplayer_peer() and peer_id != multiplayer.get_unique_id() and not has_node(str(peer_id)):
|
||||
rpc_id(1, "request_specific_player_data", peer_id)
|
||||
|
||||
@rpc("any_peer")
|
||||
@@ -1721,9 +1724,9 @@ func create_specific_player(data: Dictionary):
|
||||
# Force collision update
|
||||
if player_character.has_node("CollisionShape3D"):
|
||||
player_character.get_node("CollisionShape3D").disabled = false
|
||||
|
||||
# Wait for player managers to initialize (player.gd has 0.1s await in _ready)
|
||||
# Check if this is the local player (client's own player)
|
||||
var is_local_player = (peer_id == multiplayer.get_unique_id())
|
||||
var is_local_player = multiplayer.has_multiplayer_peer() and (peer_id == multiplayer.get_unique_id())
|
||||
if is_local_player and GameStateManager.local_player_character == null:
|
||||
GameStateManager.local_player_character = player_character
|
||||
ui_manager.set_local_player(player_character)
|
||||
@@ -2326,7 +2329,7 @@ func _show_game_over_panel():
|
||||
canvas_layer.add_child(panel)
|
||||
|
||||
# Populate data
|
||||
var local_peer_id = multiplayer.get_unique_id()
|
||||
var local_peer_id = multiplayer.get_unique_id() if multiplayer.has_multiplayer_peer() else 0
|
||||
panel.setup(all_player_scores, local_peer_id)
|
||||
|
||||
# --- REPORT NAKAMA MATCH STATS ---
|
||||
@@ -2351,7 +2354,8 @@ func _show_game_over_panel():
|
||||
# Connect signals
|
||||
panel.back_pressed.connect(_on_back_to_menu_pressed)
|
||||
panel.rematch_pressed.connect(func():
|
||||
LobbyManager.request_rematch.rpc(multiplayer.get_unique_id())
|
||||
if multiplayer.has_multiplayer_peer():
|
||||
LobbyManager.request_rematch.rpc(multiplayer.get_unique_id())
|
||||
)
|
||||
|
||||
LobbyManager.rematch_votes_updated.connect(func(count, required):
|
||||
@@ -2479,7 +2483,9 @@ func _render_leaderboard_entries(sorted_player_data: Array):
|
||||
if not vbox: vbox = leaderboard_panel.get_node_or_null("VBox")
|
||||
if not vbox: return
|
||||
|
||||
var my_id = multiplayer.get_unique_id()
|
||||
var my_id = 0
|
||||
if multiplayer and multiplayer.has_multiplayer_peer():
|
||||
my_id = multiplayer.get_unique_id()
|
||||
var my_index = -1
|
||||
for i in range(sorted_player_data.size()):
|
||||
if sorted_player_data[i].peer_id == my_id:
|
||||
|
||||
Reference in New Issue
Block a user