diff --git a/components/web_client_tcp.gd b/components/web_client_tcp.gd index 249ae0e..5b7c25d 100644 --- a/components/web_client_tcp.gd +++ b/components/web_client_tcp.gd @@ -70,10 +70,13 @@ func _handle_response(response: String) -> void: match data["response"]: "create_lobby": if data["status"] == "ok": + _lobby_id = data["lobby_id"] + _client_id = data["client_id"] connected_to_lobby.emit.call_deferred(_lobby_id) connection_status_changed.emit.call_deferred(ConnectionStatus.JOINED) "join_lobby": if data["status"] == "ok": + _client_id = data["client_id"] connected_to_lobby.emit.call_deferred(_lobby_id) connection_status_changed.emit.call_deferred(ConnectionStatus.JOINED) "client_joined_lobby": @@ -103,18 +106,15 @@ func disconnect_from_server() -> void: connection_status_changed.emit(ConnectionStatus.DISCONNECTED) func create_lobby(client_name: String) -> void: - _lobby_id = _generate_code() - _client_id = _generate_code() _client_name = client_name - _send_message(TCPMessages.create_lobby(_lobby_id, _client_id, client_name)) + _send_message(TCPMessages.create_lobby(client_name)) func join_lobby(lobby_id: String, client_name: String) -> void: _lobby_id = lobby_id - _client_id = _generate_code() _client_name = client_name - _send_message(TCPMessages.join_lobby(_lobby_id, _client_id, client_name)) + _send_message(TCPMessages.join_lobby(_lobby_id, client_name)) func leave_lobby() -> void: _send_message(TCPMessages.leave_lobby(_lobby_id, _client_id)) @@ -128,14 +128,3 @@ func leave_lobby() -> void: func _send_message(message: String) -> void: _tcp.put_data(message.to_utf8_buffer()) - -func _generate_code() -> String: - # use a local randomized RNG to keep the global RNG reproducible - var rng = RandomNumberGenerator.new() - rng.randomize() - var length = 6 - var result = '' - for _n in range(length): - var ascii = rng.randi_range(0, 25) + 65 - result += '%c' % ascii - return result diff --git a/game.tscn b/game.tscn index 8f3801a..1b4acbc 100644 --- a/game.tscn +++ b/game.tscn @@ -12,71 +12,64 @@ font_weight = 500 [node name="WebClientTCP" type="Node" parent="."] script = ExtResource("1_feb5d") -[node name="ClientInterface" type="Control" parent="." node_paths=PackedStringArray("client", "connect_button", "create_lobby_button", "join_lobby_button", "leave_lobby_button", "name_input", "lobby_code_input", "output")] -layout_mode = 3 -anchors_preset = 15 -anchor_right = 1.0 +[node name="ClientInterface" type="ColorRect" parent="." node_paths=PackedStringArray("client", "connect_button", "create_lobby_button", "join_lobby_button", "leave_lobby_button", "name_input", "lobby_code_input", "output")] +anchors_preset = 9 anchor_bottom = 1.0 -grow_horizontal = 2 +offset_right = 362.0 grow_vertical = 2 +color = Color(0.26, 0.2236, 0.230273, 1) script = ExtResource("2_e2o6t") client = NodePath("../WebClientTCP") -connect_button = NodePath("HBoxContainer/VBoxContainer/ConnectButton") -create_lobby_button = NodePath("HBoxContainer/VBoxContainer/CreateLobbyButton") -join_lobby_button = NodePath("HBoxContainer/VBoxContainer/JoinLobbyButton") -leave_lobby_button = NodePath("HBoxContainer/VBoxContainer/LeaveLobbyButton") -name_input = NodePath("HBoxContainer/VBoxContainer/NameInput") -lobby_code_input = NodePath("HBoxContainer/VBoxContainer/LobbyCodeInput") -output = NodePath("HBoxContainer/Output") +connect_button = NodePath("VBoxContainer/VBoxContainer/ConnectButton") +create_lobby_button = NodePath("VBoxContainer/VBoxContainer/CreateLobbyButton") +join_lobby_button = NodePath("VBoxContainer/VBoxContainer/JoinLobbyButton") +leave_lobby_button = NodePath("VBoxContainer/VBoxContainer/LeaveLobbyButton") +name_input = NodePath("VBoxContainer/VBoxContainer/NameInput") +lobby_code_input = NodePath("VBoxContainer/VBoxContainer/LobbyCodeInput") +output = NodePath("VBoxContainer/Output") -[node name="ColorRect" type="ColorRect" parent="ClientInterface"] +[node name="VBoxContainer" type="VBoxContainer" parent="ClientInterface"] layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 -color = Color(0.34, 0.33116, 0.2992, 1) -[node name="HBoxContainer" type="HBoxContainer" parent="ClientInterface"] -layout_mode = 0 -offset_right = 800.0 -offset_bottom = 1080.0 - -[node name="VBoxContainer" type="VBoxContainer" parent="ClientInterface/HBoxContainer"] +[node name="VBoxContainer" type="VBoxContainer" parent="ClientInterface/VBoxContainer"] custom_minimum_size = Vector2(300, 0) layout_mode = 2 -[node name="ConnectButton" type="Button" parent="ClientInterface/HBoxContainer/VBoxContainer"] +[node name="ConnectButton" type="Button" parent="ClientInterface/VBoxContainer/VBoxContainer"] layout_mode = 2 text = "Connect to Server" -[node name="NameInput" type="LineEdit" parent="ClientInterface/HBoxContainer/VBoxContainer"] +[node name="NameInput" type="LineEdit" parent="ClientInterface/VBoxContainer/VBoxContainer"] layout_mode = 2 placeholder_text = "Your Name" editable = false -[node name="CreateLobbyButton" type="Button" parent="ClientInterface/HBoxContainer/VBoxContainer"] +[node name="CreateLobbyButton" type="Button" parent="ClientInterface/VBoxContainer/VBoxContainer"] layout_mode = 2 disabled = true text = "Create Lobby" -[node name="LobbyCodeInput" type="LineEdit" parent="ClientInterface/HBoxContainer/VBoxContainer"] +[node name="LobbyCodeInput" type="LineEdit" parent="ClientInterface/VBoxContainer/VBoxContainer"] layout_mode = 2 placeholder_text = "Lobby Code" editable = false -[node name="JoinLobbyButton" type="Button" parent="ClientInterface/HBoxContainer/VBoxContainer"] +[node name="JoinLobbyButton" type="Button" parent="ClientInterface/VBoxContainer/VBoxContainer"] layout_mode = 2 disabled = true text = "Join Lobby" -[node name="LeaveLobbyButton" type="Button" parent="ClientInterface/HBoxContainer/VBoxContainer"] +[node name="LeaveLobbyButton" type="Button" parent="ClientInterface/VBoxContainer/VBoxContainer"] layout_mode = 2 disabled = true text = "Disconnect" -[node name="Output" type="Label" parent="ClientInterface/HBoxContainer"] +[node name="Output" type="Label" parent="ClientInterface/VBoxContainer"] custom_minimum_size = Vector2(64, 1) layout_mode = 2 size_flags_horizontal = 3 @@ -91,7 +84,7 @@ autowrap_mode = 2 [connection signal="connection_status_changed" from="WebClientTCP" to="ClientInterface" method="_on_web_client_tcp_connection_status_changed"] [connection signal="disconnected_from_lobby" from="WebClientTCP" to="ClientInterface" method="_on_web_client_tcp_disconnected_from_lobby"] [connection signal="disconnected_from_server" from="WebClientTCP" to="ClientInterface" method="_on_web_client_tcp_disconnected_from_server"] -[connection signal="pressed" from="ClientInterface/HBoxContainer/VBoxContainer/ConnectButton" to="ClientInterface" method="_on_connect_button_pressed"] -[connection signal="pressed" from="ClientInterface/HBoxContainer/VBoxContainer/CreateLobbyButton" to="ClientInterface" method="_on_create_lobby_button_pressed"] -[connection signal="pressed" from="ClientInterface/HBoxContainer/VBoxContainer/JoinLobbyButton" to="ClientInterface" method="_on_join_lobby_button_pressed"] -[connection signal="pressed" from="ClientInterface/HBoxContainer/VBoxContainer/LeaveLobbyButton" to="ClientInterface" method="_on_disconnect_lobby_button_pressed"] +[connection signal="pressed" from="ClientInterface/VBoxContainer/VBoxContainer/ConnectButton" to="ClientInterface" method="_on_connect_button_pressed"] +[connection signal="pressed" from="ClientInterface/VBoxContainer/VBoxContainer/CreateLobbyButton" to="ClientInterface" method="_on_create_lobby_button_pressed"] +[connection signal="pressed" from="ClientInterface/VBoxContainer/VBoxContainer/JoinLobbyButton" to="ClientInterface" method="_on_join_lobby_button_pressed"] +[connection signal="pressed" from="ClientInterface/VBoxContainer/VBoxContainer/LeaveLobbyButton" to="ClientInterface" method="_on_disconnect_lobby_button_pressed"] diff --git a/globals/tcp_messages.gd b/globals/tcp_messages.gd index ead319c..b370fcc 100644 --- a/globals/tcp_messages.gd +++ b/globals/tcp_messages.gd @@ -1,26 +1,20 @@ extends Node func create_lobby( - lobby_id: String, - client_id: String, client_name: String, ) -> String: return JSON.stringify({ "response": "create_lobby", - "lobby_id": lobby_id, - "client_id": client_id, "client_name": client_name, }) func join_lobby( lobby_id: String, - client_id: String, client_name: String, ) -> String: return JSON.stringify({ "response": "join_lobby", "lobby_id": lobby_id, - "client_id": client_id, "client_name": client_name, }) diff --git a/server_tcp.py b/server_tcp.py index def6121..50a62e6 100644 --- a/server_tcp.py +++ b/server_tcp.py @@ -1,10 +1,12 @@ import json +import random import socket import sys import threading # Establishes connections to TCP clients. def listen() -> None: + print(generate_code()) lobby_manager = LobbyManager() threads = [] while True: @@ -21,6 +23,13 @@ def listen() -> None: def start_listen_client(connection, address, lobby_manager): ClientConnection(connection, address, lobby_manager) +def generate_code() -> str: + result = "" + for i in range(6): + result += chr(random.randint(0, 25) + 65) + return result + + class Lobby: def __init__(self, lobby_id, host_client_id): @@ -44,6 +53,26 @@ class LobbyManager: def get_lobby(self, lobby_id) -> Lobby: return self.active_lobbies[lobby_id] + def lobby_id_exists(self, lobby_id) -> bool: + return lobby_id in self.active_lobbies + + def client_id_exists_in_lobby(self, lobby_id, client_id) -> bool: + if not self.lobby_id_exists(lobby_id): + return False + return client_id in self.active_lobbies[lobby_id].connected_clients + + def get_unique_lobby_id(self) -> str: + id = generate_code() + if self.lobby_id_exists(id): + return self.get_unique_lobby_id() + return id + + def get_unique_client_id(self, lobby_id) -> str: + id = generate_code() + if self.client_id_exists_in_lobby(lobby_id, id): + return self.get_unique_client_id(lobby_id) + return id + def create_lobby(self, lobby_id, host_client_id) -> None: self.active_lobbies[lobby_id] = Lobby(lobby_id, host_client_id) print(f"Created lobby {lobby_id}") @@ -122,8 +151,8 @@ class ClientConnection: while True: data = self.connection.recv(1) received_data += data.decode("utf-8") - print(received_data) if received_data[-1] == "}": + print(received_data) self.process_input(received_data) received_data = "" @@ -139,42 +168,51 @@ class ClientConnection: data_object = json.loads(data) if data_object["response"] == "create_lobby": - print(data_object["client_id"] + " is creating lobby " + data_object["lobby_id"]) + new_lobby_id = self.lobby_manager.get_unique_lobby_id() + new_client_id = self.lobby_manager.get_unique_client_id(new_lobby_id) + print(new_client_id + " is creating lobby " + new_lobby_id) + self.lobby_manager.create_lobby( - data_object["lobby_id"], - data_object["client_id"], + new_lobby_id, + new_client_id, ) self.lobby_manager.join_lobby( - data_object["lobby_id"], - data_object["client_id"], + new_lobby_id, + new_client_id, data_object["client_name"], self.address, self.connection, ) self.lobby_manager.send_message( - data_object["lobby_id"], - data_object["client_id"], + new_lobby_id, + new_client_id, json.dumps({ "response": "create_lobby", "status": "ok", + "lobby_id": new_lobby_id, + "client_id": new_client_id, }), ) elif data_object["response"] == "join_lobby": print("joining lobby") + lobby_id = data_object["lobby_id"] + new_client_id = self.lobby_manager.get_unique_client_id(lobby_id) + self.lobby_manager.join_lobby( - data_object["lobby_id"], - data_object["client_id"], + lobby_id, + new_client_id, data_object["client_name"], self.address, self.connection, ) self.lobby_manager.send_message( - data_object["lobby_id"], - data_object["client_id"], + lobby_id, + new_client_id, json.dumps({ "response": "join_lobby", "status": "ok", + "client_id": new_client_id, }), )