class_name LobbyData extends Node var uuid = null var lobby_ui: Node = null var IS_VALID_CHARS_REGEX: RegEx = RegEx.create_from_string("^[a-zA-Z0-9]+$") const MATCH_TYPES: Array = ["8ball", "9ball", "snooker"] const CLIENT_DICT: Dictionary = { "id": "", "partner_id": "", "in_match": false, "match_id": "" } const MATCH_POOL_ENTRY: Dictionary = { "player1": "", "player2": "", "data": {} } var active_match_pool: Dictionary = {} var match_pool: Dictionary = {} var client_pool: Dictionary = {} func _init() -> void: Globals.lobby_data = self uuid = load('res://addons/uuid/uuid.gd') func _delete_from_match_pool(match_id: String) -> Dictionary: if not match_pool.has(match_id): return {} var to_delete: Dictionary = match_pool[match_id].data match_pool.erase(match_id) return to_delete func _launch_game_server( match_entry: Dictionary, client1: Dictionary, client2: Dictionary ) -> void: var port: String = InstanceLauncher.launch_game_server(match_entry.data.type) if port == "-1": # TODO: Alert clients that the game wont be created due to # server reaching number of allowed instances. return # TODO: Set address dynamically; I.E. if game on different server than lobby. # As is, clients use the lobby address since games launch on new ports. # Will have to change how we watch game server death if on diff server. #Globals.game_data.rpc_id(client1.id, "set_game_address", "51.222.85.126") #Globals.game_data.rpc_id(client2.id, "set_game_address", "51.222.85.126") Globals.game_data.rpc_id(client1.id, "set_game_port", port) Globals.game_data.rpc_id(client2.id, "set_game_port", port) rpc_id(client1.id, "connect_to_game") rpc_id(client2.id, "connect_to_game") func match_list_add_entry(match_entry: Dictionary) -> void: var client1 = client_pool.get( multiplayer.get_remote_sender_id() ) if not client1: return if not client1.match_id.is_empty(): return if match_entry.name.length() < 1 or match_entry.name.length() > 12: return if not IS_VALID_CHARS_REGEX.search(match_entry.name): return if not match_entry.type in MATCH_TYPES: return match_entry["match_id"] = uuid.v4() match_pool[match_entry.match_id] = MATCH_POOL_ENTRY.duplicate_deep() match_pool[match_entry.match_id].player1 = client1.id match_pool[match_entry.match_id].data = match_entry client1.match_id = match_entry.match_id func match_list_remove_entry(match_id: String) -> void: var client1 = client_pool.get( multiplayer.get_remote_sender_id() ) if not client1: return if not client1.match_id == match_id: return client1.match_id = "" _delete_from_match_pool(match_id) 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) if not match_entry: return var client1 = client_pool.get( match_entry.player1 ) var client2 = client_pool.get( multiplayer.get_remote_sender_id() ) if not client1: return if not client2: return match_entry.player2 = client2.id client1.in_match = true client1.partner_id = client2.id client2.match_id = match_id client2.in_match = true client2.partner_id = client1.id active_match_pool[match_id] = match_entry # NOTE: Cleanup of match info and client info # will/should happen on their disconnect... # TODO: Need to look into moving this out of here. # 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) func server_client_connected(id: int) -> void: push_warning("Client Connected... ID: ", id) client_pool[id] = CLIENT_DICT.duplicate_deep() client_pool[id].id = id var matches: Array = [] for match_entry in match_pool.values(): matches.append(match_entry.data) MessageBus.emit_propagation_clients_only.rpc_id( id, "receive_match_list", matches ) func server_client_disconnected(id: int) -> void: push_warning("Client Disconnected... ID: ", id) var client1 = client_pool.get(id) if not client1: return var match_entry = _delete_from_match_pool(client1.match_id) if not match_entry: return push_warning("Removing Match... Match: ", match_entry) MessageBus.emit_local( "match_list_remove_entry", match_entry.match_id ) MessageBus.emit_propagation_clients_only.rpc( "match_list_remove_entry", match_entry.match_id ) client_pool.erase(client1.id) # 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