chat messages are now sent and relayed. server: handling host client leaving correctly

This commit is contained in:
2025-07-04 11:29:25 +02:00
parent f4a7fb722e
commit 4b4285ca99
5 changed files with 116 additions and 25 deletions
+25
View File
@@ -8,6 +8,9 @@ extends Control
@export var join_lobby_button: Button
@export var leave_lobby_button: Button
@export var chat_message_input: LineEdit
@export var send_chat_message_button: Button
@export var name_input: LineEdit
@export var lobby_code_input: LineEdit
@@ -41,6 +44,12 @@ func _on_disconnect_lobby_button_pressed() -> void:
leave_lobby_button.disabled = true
client.leave_lobby()
func _on_send_message_button_pressed() -> void:
var msg: String = chat_message_input.text.strip_edges()
if not msg.is_empty():
client.send_chat_message(msg)
chat_message_input.text = ""
func _on_web_client_tcp_connected_to_server() -> void:
create_lobby_button.disabled = false
join_lobby_button.disabled = false
@@ -73,6 +82,12 @@ func _on_web_client_tcp_client_joined_lobby(client_name: String) -> void:
"you": " (that's you!)" if client_name == name_input.text.strip_edges() else ""
}))
func _on_web_client_tcp_received_chat_message(client_name: String, message: String) -> void:
_write_line("<{client_name}> {message}".format({
"client_name": client_name,
"message": message,
}))
func _on_web_client_tcp_connection_status_changed(new_status: WebClientTCP.ConnectionStatus) -> void:
match new_status:
@@ -84,6 +99,8 @@ func _on_web_client_tcp_connection_status_changed(new_status: WebClientTCP.Conne
name_input.editable = true
lobby_code_input.editable = false
lobby_code_input.text = ""
chat_message_input.editable = false
send_chat_message_button.disabled = true
WebClientTCP.ConnectionStatus.ATTEMPTING_CONNECTION:
connect_button.disabled = true
@@ -93,6 +110,8 @@ func _on_web_client_tcp_connection_status_changed(new_status: WebClientTCP.Conne
name_input.editable = true
lobby_code_input.editable = false
lobby_code_input.text = ""
chat_message_input.editable = false
send_chat_message_button.disabled = true
WebClientTCP.ConnectionStatus.LOBBYLESS:
connect_button.disabled = true
@@ -102,6 +121,8 @@ func _on_web_client_tcp_connection_status_changed(new_status: WebClientTCP.Conne
name_input.editable = true
lobby_code_input.editable = true
lobby_code_input.text = ""
chat_message_input.editable = false
send_chat_message_button.disabled = true
WebClientTCP.ConnectionStatus.ATTEMPTING_JOIN:
connect_button.disabled = true
@@ -110,6 +131,8 @@ func _on_web_client_tcp_connection_status_changed(new_status: WebClientTCP.Conne
leave_lobby_button.disabled = true
name_input.editable = false
lobby_code_input.editable = false
chat_message_input.editable = false
send_chat_message_button.disabled = true
WebClientTCP.ConnectionStatus.JOINED:
connect_button.disabled = true
@@ -118,3 +141,5 @@ func _on_web_client_tcp_connection_status_changed(new_status: WebClientTCP.Conne
leave_lobby_button.disabled = false
name_input.editable = false
lobby_code_input.editable = false
chat_message_input.editable = true
send_chat_message_button.disabled = false
+9 -4
View File
@@ -24,6 +24,8 @@ signal disconnected_from_lobby()
signal client_joined_lobby(client_name: String)
signal received_chat_message(client_name: String, message: String)
signal connection_status_changed(new_status: ConnectionStatus)
enum ConnectionStatus {
@@ -86,8 +88,8 @@ func _handle_response(response: String) -> void:
"leave_lobby":
if data["status"] == "ok":
print(data["client_id"] + " left")
#if data["client_id"] == _client_id:
#connection_status_changed.emit.call_deferred(ConnectionStatus.LOBBYLESS)
"receive_chat_message":
received_chat_message.emit.call_deferred(data["client_name"], data["message"])
func _exit_tree() -> void:
disconnect_from_server()
@@ -123,8 +125,11 @@ func leave_lobby() -> void:
_client_id = ""
_client_name = ""
disconnected_from_lobby.emit()
connection_status_changed.emit(ConnectionStatus.LOBBYLESS)
disconnected_from_lobby.emit.call_deferred()
connection_status_changed.emit.call_deferred(ConnectionStatus.LOBBYLESS)
func send_chat_message(message: String) -> void:
_send_message(TCPMessages.send_chat_message(_lobby_id, _client_id, message))
func _send_message(message: String) -> void:
_tcp.put_data(message.to_utf8_buffer())
+58 -21
View File
@@ -12,7 +12,7 @@ font_weight = 500
[node name="WebClientTCP" type="Node" parent="."]
script = ExtResource("1_feb5d")
[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")]
[node name="ClientInterface" type="ColorRect" parent="." node_paths=PackedStringArray("client", "connect_button", "create_lobby_button", "join_lobby_button", "leave_lobby_button", "chat_message_input", "send_chat_message_button", "name_input", "lobby_code_input", "output")]
anchors_preset = 9
anchor_bottom = 1.0
offset_right = 362.0
@@ -20,62 +20,97 @@ grow_vertical = 2
color = Color(0.26, 0.2236, 0.230273, 1)
script = ExtResource("2_e2o6t")
client = NodePath("../WebClientTCP")
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")
connect_button = NodePath("MarginContainer/VBoxContainer/VBoxContainer/ConnectButton")
create_lobby_button = NodePath("MarginContainer/VBoxContainer/VBoxContainer/CreateLobbyButton")
join_lobby_button = NodePath("MarginContainer/VBoxContainer/VBoxContainer/JoinLobbyButton")
leave_lobby_button = NodePath("MarginContainer/VBoxContainer/VBoxContainer/LeaveLobbyButton")
chat_message_input = NodePath("MarginContainer/VBoxContainer/ChatContainer/MessageInput")
send_chat_message_button = NodePath("MarginContainer/VBoxContainer/ChatContainer/SendMessageButton")
name_input = NodePath("MarginContainer/VBoxContainer/VBoxContainer/NameInput")
lobby_code_input = NodePath("MarginContainer/VBoxContainer/VBoxContainer/LobbyCodeInput")
output = NodePath("MarginContainer/VBoxContainer/ScrollContainer/Output")
[node name="VBoxContainer" type="VBoxContainer" parent="ClientInterface"]
[node name="MarginContainer" type="MarginContainer" parent="ClientInterface"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 8
theme_override_constants/margin_bottom = 8
[node name="VBoxContainer" type="VBoxContainer" parent="ClientInterface/VBoxContainer"]
[node name="VBoxContainer" type="VBoxContainer" parent="ClientInterface/MarginContainer"]
layout_mode = 2
[node name="Label" type="RichTextLabel" parent="ClientInterface/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_font_sizes/italics_font_size = 24
theme_override_font_sizes/normal_font_size = 24
bbcode_enabled = true
text = "[i]Magician Online![/i]"
fit_content = true
[node name="VBoxContainer" type="VBoxContainer" parent="ClientInterface/MarginContainer/VBoxContainer"]
custom_minimum_size = Vector2(300, 0)
layout_mode = 2
[node name="ConnectButton" type="Button" parent="ClientInterface/VBoxContainer/VBoxContainer"]
[node name="ConnectButton" type="Button" parent="ClientInterface/MarginContainer/VBoxContainer/VBoxContainer"]
layout_mode = 2
text = "Connect to Server"
[node name="NameInput" type="LineEdit" parent="ClientInterface/VBoxContainer/VBoxContainer"]
[node name="NameInput" type="LineEdit" parent="ClientInterface/MarginContainer/VBoxContainer/VBoxContainer"]
layout_mode = 2
placeholder_text = "Your Name"
editable = false
[node name="CreateLobbyButton" type="Button" parent="ClientInterface/VBoxContainer/VBoxContainer"]
[node name="CreateLobbyButton" type="Button" parent="ClientInterface/MarginContainer/VBoxContainer/VBoxContainer"]
layout_mode = 2
disabled = true
text = "Create Lobby"
[node name="LobbyCodeInput" type="LineEdit" parent="ClientInterface/VBoxContainer/VBoxContainer"]
[node name="LobbyCodeInput" type="LineEdit" parent="ClientInterface/MarginContainer/VBoxContainer/VBoxContainer"]
layout_mode = 2
placeholder_text = "Lobby Code"
editable = false
[node name="JoinLobbyButton" type="Button" parent="ClientInterface/VBoxContainer/VBoxContainer"]
[node name="JoinLobbyButton" type="Button" parent="ClientInterface/MarginContainer/VBoxContainer/VBoxContainer"]
layout_mode = 2
disabled = true
text = "Join Lobby"
[node name="LeaveLobbyButton" type="Button" parent="ClientInterface/VBoxContainer/VBoxContainer"]
[node name="LeaveLobbyButton" type="Button" parent="ClientInterface/MarginContainer/VBoxContainer/VBoxContainer"]
layout_mode = 2
disabled = true
text = "Disconnect"
[node name="Output" type="Label" parent="ClientInterface/VBoxContainer"]
[node name="ScrollContainer" type="ScrollContainer" parent="ClientInterface/MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
horizontal_scroll_mode = 0
vertical_scroll_mode = 4
[node name="Output" type="Label" parent="ClientInterface/MarginContainer/VBoxContainer/ScrollContainer"]
custom_minimum_size = Vector2(64, 1)
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
theme_override_fonts/font = SubResource("SystemFont_80nbo")
autowrap_mode = 2
metadata/_edit_lock_ = true
[node name="ChatContainer" type="HBoxContainer" parent="ClientInterface/MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="MessageInput" type="LineEdit" parent="ClientInterface/MarginContainer/VBoxContainer/ChatContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="SendMessageButton" type="Button" parent="ClientInterface/MarginContainer/VBoxContainer/ChatContainer"]
layout_mode = 2
text = "Send"
[connection signal="client_joined_lobby" from="WebClientTCP" to="ClientInterface" method="_on_web_client_tcp_client_joined_lobby"]
[connection signal="connected_to_lobby" from="WebClientTCP" to="ClientInterface" method="_on_web_client_tcp_connected_to_lobby"]
@@ -84,7 +119,9 @@ 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/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"]
[connection signal="received_chat_message" from="WebClientTCP" to="ClientInterface" method="_on_web_client_tcp_received_chat_message"]
[connection signal="pressed" from="ClientInterface/MarginContainer/VBoxContainer/VBoxContainer/ConnectButton" to="ClientInterface" method="_on_connect_button_pressed"]
[connection signal="pressed" from="ClientInterface/MarginContainer/VBoxContainer/VBoxContainer/CreateLobbyButton" to="ClientInterface" method="_on_create_lobby_button_pressed"]
[connection signal="pressed" from="ClientInterface/MarginContainer/VBoxContainer/VBoxContainer/JoinLobbyButton" to="ClientInterface" method="_on_join_lobby_button_pressed"]
[connection signal="pressed" from="ClientInterface/MarginContainer/VBoxContainer/VBoxContainer/LeaveLobbyButton" to="ClientInterface" method="_on_disconnect_lobby_button_pressed"]
[connection signal="pressed" from="ClientInterface/MarginContainer/VBoxContainer/ChatContainer/SendMessageButton" to="ClientInterface" method="_on_send_message_button_pressed"]
+12
View File
@@ -27,3 +27,15 @@ func leave_lobby(
"lobby_id": lobby_id,
"client_id": client_id,
})
func send_chat_message(
lobby_id: String,
client_id: String,
message: String,
) -> String:
return JSON.stringify({
"response": "send_chat_message",
"lobby_id": lobby_id,
"client_id": client_id,
"message": message,
})
+12
View File
@@ -227,6 +227,7 @@ class ClientConnection:
# client is host; close lobby
lobby_clients = self.lobby_manager.get_lobby(lobby_id).connected_clients.copy()
# for client_id in lobby_clients:
self.lobby_manager.leave_lobby(lobby_id, data_object["client_id"])
self.lobby_manager.broadcast_message(
lobby_id,
json.dumps({
@@ -239,6 +240,17 @@ class ClientConnection:
# client is not host; client leaves only
self.lobby_manager.leave_lobby(lobby_id, data_object["client_id"])
elif data_object["response"] == "send_chat_message":
print("relaying chat message")
self.lobby_manager.broadcast_message(
data_object["lobby_id"],
json.dumps({
"response": "receive_chat_message",
"message": data_object["message"],
"client_name": self.lobby_manager.active_lobbies[data_object["lobby_id"]].connected_clients[data_object["client_id"]].client_name,
})
)
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Usage: ./server.py PORT")