Refactor message bus and lobby networking flow
* Add local message bus emission with optional argument expansion * Improve message type validation and callback dispatch * Simplify lobby match join/disconnect handling * Move lobby server networking toward an overridable `ServerNetworking` base class * Update lobby scene to use the dedicated lobby server script * Remove obsolete window configuration and unused RPC stubs
This commit is contained in:
@@ -11,8 +11,8 @@ func subscribe(id: String, callback: Callable) -> void:
|
|||||||
message_types.get(id).append(callback)
|
message_types.get(id).append(callback)
|
||||||
|
|
||||||
|
|
||||||
func emit(id: String, data: Variant) -> void:
|
func emit_local(id: String, data: Variant, expand: bool = false) -> void:
|
||||||
emit_propagation(id, data)
|
emit_propagation(id, data, expand)
|
||||||
|
|
||||||
|
|
||||||
# TODO: Need to actually validate client request. Also, message bus is more
|
# TODO: Need to actually validate client request. Also, message bus is more
|
||||||
@@ -21,36 +21,39 @@ func emit(id: String, data: Variant) -> void:
|
|||||||
@rpc("any_peer", "call_remote", "reliable")
|
@rpc("any_peer", "call_remote", "reliable")
|
||||||
func emit_request(id: String, data: Variant, expand: bool = false) -> void:
|
func emit_request(id: String, data: Variant, expand: bool = false) -> void:
|
||||||
if not multiplayer.is_server(): return
|
if not multiplayer.is_server(): return
|
||||||
|
if not message_types.has(id):
|
||||||
var listeners: Array = message_types.get(id)
|
push_error("'%s' not an existing message type to handle...", [id])
|
||||||
if not listeners:
|
|
||||||
push_error("'%s' not an existing message type to send...", [id])
|
|
||||||
return
|
return
|
||||||
|
|
||||||
emit_propagation(id, data, expand)
|
emit_propagation(id, data, expand)
|
||||||
|
|
||||||
@rpc("authority", "call_local", "reliable")
|
@rpc("authority", "call_local", "reliable")
|
||||||
func emit_propagation(id: String, data: Variant, expand: bool = false) -> void:
|
func emit_propagation(id: String, data: Variant, expand: bool = false) -> void:
|
||||||
var listeners: Array = message_types.get(id)
|
if not message_types.has(id):
|
||||||
if not listeners:
|
push_error("'%s' not an existing message type to handle...", [id])
|
||||||
push_error("'%s' not an existing message type to send...", [id])
|
|
||||||
return
|
return
|
||||||
|
|
||||||
for callback: Callable in listeners:
|
for callback: Callable in message_types.get(id):
|
||||||
|
if data == null:
|
||||||
|
callback.call()
|
||||||
|
continue
|
||||||
|
|
||||||
if not expand:
|
if not expand:
|
||||||
callback.call(data)
|
callback.call(data)
|
||||||
else:
|
else:
|
||||||
callback.callv(data)
|
callback.callv(data)
|
||||||
|
|
||||||
|
|
||||||
@rpc("authority", "call_remote", "reliable")
|
@rpc("authority", "call_remote", "reliable")
|
||||||
func emit_propagation_clients_only(id: String, data: Variant, expand: bool = false) -> void:
|
func emit_propagation_clients_only(id: String, data: Variant, expand: bool = false) -> void:
|
||||||
var listeners: Array = message_types.get(id)
|
if not message_types.has(id):
|
||||||
if not listeners:
|
push_error("'%s' not an existing message type to handle...", [id])
|
||||||
push_error("'%s' not an existing message type to send...", [id])
|
|
||||||
return
|
return
|
||||||
|
|
||||||
for callback: Callable in listeners:
|
for callback: Callable in message_types.get(id):
|
||||||
|
if data == null:
|
||||||
|
callback.call()
|
||||||
|
continue
|
||||||
|
|
||||||
if not expand:
|
if not expand:
|
||||||
callback.call(data)
|
callback.call(data)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -21,10 +21,6 @@ Globals="*res://globals/globals.gd"
|
|||||||
InstanceLauncher="*res://globals/instance_launcher.gd"
|
InstanceLauncher="*res://globals/instance_launcher.gd"
|
||||||
MessageBus="*res://globals/message_bus.gd"
|
MessageBus="*res://globals/message_bus.gd"
|
||||||
|
|
||||||
[display]
|
|
||||||
|
|
||||||
window/size/always_on_top=true
|
|
||||||
|
|
||||||
[rendering]
|
[rendering]
|
||||||
|
|
||||||
renderer/rendering_method="gl_compatibility"
|
renderer/rendering_method="gl_compatibility"
|
||||||
|
|||||||
@@ -81,6 +81,14 @@ func match_list_remove_entry(match_id: String) -> void:
|
|||||||
_delete_from_match_pool(match_id)
|
_delete_from_match_pool(match_id)
|
||||||
|
|
||||||
func match_list_join_entry(match_id: String) -> void:
|
func match_list_join_entry(match_id: String) -> void:
|
||||||
|
if active_match_pool.has(match_id):
|
||||||
|
push_error("Client Joining Match List Entry Failed. Already consumed. ", match_id)
|
||||||
|
|
||||||
|
# TODO: Need to signal to prospective client that match has been taken.
|
||||||
|
# Server is in the midst of cleanup for it once clients disconnect
|
||||||
|
# to join generated game server...
|
||||||
|
return
|
||||||
|
|
||||||
var match_entry = match_pool.get(match_id)
|
var match_entry = match_pool.get(match_id)
|
||||||
if not match_entry: return
|
if not match_entry: return
|
||||||
|
|
||||||
@@ -100,22 +108,14 @@ func match_list_join_entry(match_id: String) -> void:
|
|||||||
client2.partner_id = client1.id
|
client2.partner_id = client1.id
|
||||||
|
|
||||||
active_match_pool[match_id] = match_entry
|
active_match_pool[match_id] = match_entry
|
||||||
|
# NOTE: Cleanup of match info and client info
|
||||||
|
# will/should happen on their disconnect...
|
||||||
|
|
||||||
client_pool.erase(client1.id)
|
# TODO: Need to look into moving this out of here.
|
||||||
client_pool.erase(client2.id)
|
# Maybe just have clients drop and internally call on their own?
|
||||||
|
# Maybe just check here if we can even launch the game server?
|
||||||
_launch_game_server(match_entry, client1, client2)
|
_launch_game_server(match_entry, client1, client2)
|
||||||
|
|
||||||
# NOTE: Needed for hash check to pass between client and server but isn't used by server...
|
|
||||||
@rpc("authority", "reliable")
|
|
||||||
func connect_to_game() -> void:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@rpc("authority", "reliable")
|
|
||||||
func go_back_to_match_screen() -> void:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
func server_client_connected(id: int) -> void:
|
func server_client_connected(id: int) -> void:
|
||||||
push_warning("Client Connected... ID: ", id)
|
push_warning("Client Connected... ID: ", id)
|
||||||
|
|
||||||
@@ -134,32 +134,29 @@ func server_client_disconnected(id: int) -> void:
|
|||||||
push_warning("Client Disconnected... ID: ", id)
|
push_warning("Client Disconnected... ID: ", id)
|
||||||
|
|
||||||
var client1 = client_pool.get(id)
|
var client1 = client_pool.get(id)
|
||||||
if not client1: return
|
if not client1: return
|
||||||
|
|
||||||
var client2 = client_pool.get( client1.partner_id )
|
|
||||||
var match_entry = _delete_from_match_pool(client1.match_id)
|
var match_entry = _delete_from_match_pool(client1.match_id)
|
||||||
|
if not match_entry: return
|
||||||
|
|
||||||
if not client1.match_id.is_empty() and not match_entry.is_empty():
|
push_warning("Removing Match... Match: ", match_entry)
|
||||||
MessageBus.emit_propagation(
|
|
||||||
"match_list_remove_entry", match_entry.match_id
|
|
||||||
)
|
|
||||||
|
|
||||||
for client in client_pool.values():
|
MessageBus.emit_local(
|
||||||
if client.in_match: continue
|
"match_list_remove_entry", match_entry.match_id
|
||||||
if client.id == id: continue
|
)
|
||||||
|
|
||||||
MessageBus.emit_propagation_clients_only.rpc_id(
|
MessageBus.emit_propagation_clients_only.rpc(
|
||||||
client.id, "match_list_remove_entry", match_entry.match_id
|
"match_list_remove_entry", match_entry.match_id
|
||||||
)
|
)
|
||||||
|
|
||||||
match_pool.erase(client1.match_id)
|
|
||||||
|
|
||||||
client_pool.erase(client1.id)
|
client_pool.erase(client1.id)
|
||||||
if not client2: return
|
|
||||||
|
|
||||||
if active_match_pool.get(client2.match_id):
|
|
||||||
match_pool.erase(client2.match_id)
|
|
||||||
|
|
||||||
var _id = client2.id
|
# NOTE: Needed for hash check to pass between client and server but isn't used by server...
|
||||||
client2 = CLIENT_DICT.duplicate_deep()
|
@rpc("authority", "reliable")
|
||||||
client2.id = _id
|
func connect_to_game() -> void:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@rpc("authority", "reliable")
|
||||||
|
func go_back_to_match_screen() -> void:
|
||||||
|
pass
|
||||||
|
|||||||
@@ -56,12 +56,8 @@ func _on_match_list_entry_removed(match_id: String) -> void:
|
|||||||
match_entry.queue_free()
|
match_entry.queue_free()
|
||||||
|
|
||||||
func _on_match_list_join_entry(match_id: String) -> void:
|
func _on_match_list_join_entry(match_id: String) -> void:
|
||||||
Globals.lobby_data.match_list_join_entry(match_id)
|
|
||||||
push_warning("Client Joining Match List Entry... ", match_id)
|
push_warning("Client Joining Match List Entry... ", match_id)
|
||||||
|
Globals.lobby_data.match_list_join_entry(match_id)
|
||||||
if Globals.lobby_data.match_pool.has(match_id): return
|
|
||||||
|
|
||||||
_on_match_list_entry_removed(match_id)
|
|
||||||
|
|
||||||
func _create_match_entry(match_entry: Dictionary) -> void:
|
func _create_match_entry(match_entry: Dictionary) -> void:
|
||||||
var container = MATCH_ENTRY.instantiate()
|
var container = MATCH_ENTRY.instantiate()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
[ext_resource type="Script" uid="uid://dk7afnf7ol7dy" path="res://scenes/screens/lobby_screen/lobby.gd" id="1_hhiik"]
|
[ext_resource type="Script" uid="uid://dk7afnf7ol7dy" path="res://scenes/screens/lobby_screen/lobby.gd" id="1_hhiik"]
|
||||||
[ext_resource type="PackedScene" uid="uid://rb6av5eg4u0" path="res://scenes/ui_controls/lobby_screen/lobby_ui.tscn" id="2_lqt48"]
|
[ext_resource type="PackedScene" uid="uid://rb6av5eg4u0" path="res://scenes/ui_controls/lobby_screen/lobby_ui.tscn" id="2_lqt48"]
|
||||||
[ext_resource type="Script" uid="uid://6sfwe1hwgf0g" path="res://scenes/screens/lobby_screen/lobby_rpc.gd" id="3_rurl6"]
|
[ext_resource type="Script" uid="uid://6sfwe1hwgf0g" path="res://scenes/screens/lobby_screen/lobby_rpc.gd" id="3_rurl6"]
|
||||||
[ext_resource type="Script" uid="uid://bvqtgf3vbsoj4" path="res://scripts/server_networking.gd" id="4_glu7g"]
|
[ext_resource type="Script" uid="uid://crbm3v4td6du6" path="res://scenes/screens/lobby_screen/lobby_server.gd" id="4_glu7g"]
|
||||||
|
|
||||||
[node name="lobby_screen" type="Control"]
|
[node name="lobby_screen" type="Control"]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
|
|||||||
19
scenes/screens/lobby_screen/lobby_server.gd
Normal file
19
scenes/screens/lobby_screen/lobby_server.gd
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
class_name Lobbyserver extends ServerNetworking
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
pass
|
||||||
|
|
||||||
|
func _process(_delta: float) -> void:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
func server_client_connected(id: int) -> void:
|
||||||
|
Globals.lobby_data.server_client_connected(id)
|
||||||
|
|
||||||
|
func server_client_disconnected(id: int) -> void:
|
||||||
|
# NOTE: Wait for clients to fully disconnect...
|
||||||
|
var timer = get_tree().create_timer(1)
|
||||||
|
await timer.timeout
|
||||||
|
|
||||||
|
Globals.lobby_data.server_client_disconnected(id)
|
||||||
1
scenes/screens/lobby_screen/lobby_server.gd.uid
Normal file
1
scenes/screens/lobby_screen/lobby_server.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://crbm3v4td6du6
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
extends Node
|
class_name ServerNetworking extends Node
|
||||||
|
|
||||||
|
|
||||||
var peer: ENetMultiplayerPeer
|
var peer: ENetMultiplayerPeer
|
||||||
@@ -44,8 +44,8 @@ func close_connection() -> void:
|
|||||||
peer.close()
|
peer.close()
|
||||||
peer = null
|
peer = null
|
||||||
|
|
||||||
func server_client_connected(id: int) -> void:
|
func server_client_connected(_id: int) -> void:
|
||||||
Globals.lobby_data.server_client_connected(id)
|
assert(false, "This method needs to be overridden...")
|
||||||
|
|
||||||
func server_client_disconnected(id: int) -> void:
|
func server_client_disconnected(_id: int) -> void:
|
||||||
Globals.lobby_data.server_client_disconnected(id)
|
assert(false, "This method needs to be overridden...")
|
||||||
|
|||||||
Reference in New Issue
Block a user