From 0cddfe93bb569a248112bfc5b6aeb69d6481ad80 Mon Sep 17 00:00:00 2001 From: Sofia Date: Tue, 4 Aug 2026 21:13:48 +0300 Subject: [PATCH] Add kick button and make it work --- godot/scenes/misc/ball.tscn | 2 +- godot/scenes/misc/replay_ball.tscn | 2 +- godot/scenes/ui/lobby_player_listing.tscn | 17 +++++++--- rust/src/ui/lobby_player_listing.rs | 41 +++++++++++++++++++++-- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/godot/scenes/misc/ball.tscn b/godot/scenes/misc/ball.tscn index 9d45286..9104e68 100644 --- a/godot/scenes/misc/ball.tscn +++ b/godot/scenes/misc/ball.tscn @@ -31,7 +31,7 @@ stream_9/stream = ExtResource("10_p4exv") [node name="ball" type="Ball" unique_id=816748600 node_paths=PackedStringArray("bounce_sfx")] bounce_sfx = NodePath("bounce_sfx") collision_layer = 8 -collision_mask = 7 +collision_mask = 39 contact_monitor = true max_contacts_reported = 10 diff --git a/godot/scenes/misc/replay_ball.tscn b/godot/scenes/misc/replay_ball.tscn index cf4682e..e90edfe 100644 --- a/godot/scenes/misc/replay_ball.tscn +++ b/godot/scenes/misc/replay_ball.tscn @@ -6,7 +6,7 @@ [node name="replay_ball" type="Ball" unique_id=816748600] collision_layer = 8 -collision_mask = 4 +collision_mask = 36 contact_monitor = true max_contacts_reported = 10 diff --git a/godot/scenes/ui/lobby_player_listing.tscn b/godot/scenes/ui/lobby_player_listing.tscn index 79c958d..d035b7c 100644 --- a/godot/scenes/ui/lobby_player_listing.tscn +++ b/godot/scenes/ui/lobby_player_listing.tscn @@ -1,16 +1,18 @@ [gd_scene format=3 uid="uid://ccd0wj2usx5os"] [ext_resource type="Theme" uid="uid://drydbnrcdv4pk" path="res://default_theme.tres" id="1_f2dvx"] +[ext_resource type="Texture2D" uid="uid://crhexmmf6si2k" path="res://raw_assets/icons/PNG/White/1x/door.png" id="2_iceu0"] -[node name="lobby_player_listing" type="LobbyPlayerListing" unique_id=887620055 node_paths=PackedStringArray("name_label", "ping_label", "ready_label", "team_dropdown")] +[node name="lobby_player_listing" type="LobbyPlayerListing" unique_id=887620055 node_paths=PackedStringArray("name_label", "ping_label", "ready_label", "team_dropdown", "kick_button")] name_label = NodePath("name") ping_label = NodePath("ping") ready_label = NodePath("ready") team_dropdown = NodePath("option_button") +kick_button = NodePath("kick_button") offset_right = 673.0 offset_bottom = 23.0 theme = ExtResource("1_f2dvx") -columns = 4 +columns = 5 [node name="option_button" type="OptionButton" parent="." unique_id=199328927] custom_minimum_size = Vector2(150, 0) @@ -19,8 +21,8 @@ clip_contents = true layout_mode = 2 [node name="name" type="Label" parent="." unique_id=635700663] -custom_minimum_size = Vector2(350, 0) -custom_maximum_size = Vector2(350, -1) +custom_minimum_size = Vector2(300, 0) +custom_maximum_size = Vector2(300, -1) layout_mode = 2 text = "Name" clip_text = true @@ -35,3 +37,10 @@ text = "Ready" layout_mode = 2 text = "(200ms)" horizontal_alignment = 2 + +[node name="kick_button" type="Button" parent="." unique_id=1215502618] +custom_minimum_size = Vector2(60, 0) +layout_mode = 2 +text = "kick" +icon = ExtResource("2_iceu0") +expand_icon = true diff --git a/rust/src/ui/lobby_player_listing.rs b/rust/src/ui/lobby_player_listing.rs index 1a95543..14fc8f5 100644 --- a/rust/src/ui/lobby_player_listing.rs +++ b/rust/src/ui/lobby_player_listing.rs @@ -1,5 +1,5 @@ use godot::{ - classes::{GridContainer, IGridContainer, Label, OptionButton}, + classes::{Button, GridContainer, IGridContainer, Label, OptionButton}, prelude::*, }; @@ -8,7 +8,7 @@ use crate::{ Game, opts::{GameOption, GameOptions}, }, - net::network_manager::NetworkManager, + net::network_manager::{NetworkManager, PeerKind}, team_resource::TeamResource, }; @@ -23,6 +23,8 @@ pub struct LobbyPlayerListing { pub ready_label: Option>, #[export] pub team_dropdown: Option>, + #[export] + pub kick_button: Option>, pub player_id: Option, @@ -65,10 +67,45 @@ impl IGridContainer for LobbyPlayerListing { self.update_game_options(&game.bind().opts, game.bind().self_id); } + + if let Some(mut kick_btn) = self.kick_button.clone() { + if let Some(peer) = &NetworkManager::singleton().bind().peer { + match peer { + PeerKind::Client(..) => kick_btn.hide(), + PeerKind::Server(..) => { + if let Some(player_id) = self.player_id + && let Some(game) = Game::singleton() + { + // Hide kick button for self even if host + if player_id == game.bind().self_id.unwrap_or(0) { + kick_btn.hide(); + } + } + } + } + } + + kick_btn + .signals() + .pressed() + .connect_other(self, |s| s.kick()); + } } } +#[godot_api] impl LobbyPlayerListing { + pub fn kick(&mut self) { + if let Some(player_id) = self.player_id + && let Some(game) = Game::singleton() + && let Some(player) = game.bind().find_player(player_id) + { + NetworkManager::singleton() + .bind_mut() + .kick(&player.connection_addr); + } + } + pub fn update_game_options(&mut self, opts: &GameOptions, self_id: Option) { let is_host = NetworkManager::singleton().bind().is_host();