184 lines
5.4 KiB
GDScript
184 lines
5.4 KiB
GDScript
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.get(match_id):
|
|
return {}
|
|
|
|
var to_delete: Dictionary = match_pool[match_id].data
|
|
match_pool.erase(match_id)
|
|
|
|
return to_delete
|
|
|
|
func _signal_match_list_remove_entry(match_id: String) -> void:
|
|
lobby_ui.rpc_signals.rpc_id(1, "match_list_remove_entry", match_id)
|
|
|
|
for client in client_pool.values():
|
|
if client.in_match: continue
|
|
|
|
lobby_ui.rpc_signals.rpc_id(client.id, "match_list_remove_entry", match_id)
|
|
|
|
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
|
|
|
|
Globals.game_data.rpc_id(client1.id, "set_game_address", "127.0.0.1")
|
|
Globals.game_data.rpc_id(client2.id, "set_game_address", "127.0.0.1")
|
|
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")
|
|
|
|
@rpc("any_peer", "reliable")
|
|
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
|
|
|
|
lobby_ui.rpc_signals.rpc_id(1, "match_list_add_entry", match_entry)
|
|
for client in client_pool.values():
|
|
if client.in_match: continue
|
|
lobby_ui.rpc_signals.rpc_id(client.id, "match_list_add_entry", match_entry)
|
|
|
|
lobby_ui.rpc_signals.rpc_id(client1.id, "match_list_activate_entry", match_entry.match_id)
|
|
|
|
|
|
@rpc("any_peer", "reliable")
|
|
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)
|
|
_signal_match_list_remove_entry(match_id)
|
|
|
|
@rpc("any_peer", "reliable")
|
|
func match_list_join_entry(match_id: String) -> void:
|
|
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
|
|
|
|
match_pool.erase(match_id)
|
|
client_pool.erase(client1.id)
|
|
client_pool.erase(client2.id)
|
|
|
|
_signal_match_list_remove_entry(match_id)
|
|
_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", "call_local", "reliable")
|
|
func load_game_scene(_match_entry: Dictionary, _is_player_1: bool) -> void:
|
|
pass
|
|
|
|
@rpc("authority", "reliable")
|
|
func go_back_to_match_screen() -> void:
|
|
pass
|
|
|
|
|
|
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)
|
|
|
|
lobby_ui.rpc_signals.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 client2 = client_pool.get( client1.partner_id )
|
|
var match_entry = _delete_from_match_pool(client1.match_id)
|
|
|
|
if not client1.match_id.is_empty() and not match_entry.is_empty():
|
|
lobby_ui.rpc_signals.rpc_id(1, "match_list_remove_entry", match_entry.match_id)
|
|
|
|
for client in client_pool.values():
|
|
if client.in_match: continue
|
|
if client.id == id: continue
|
|
|
|
lobby_ui.rpc_signals.rpc_id(client.id, "match_list_remove_entry", match_entry.match_id)
|
|
|
|
match_pool.erase(client1.match_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
|
|
client2 = CLIENT_DICT.duplicate_deep()
|
|
client2.id = _id
|