bugfix: more reliable role reveal

This commit is contained in:
emilis 2025-12-04 00:12:44 +00:00
parent 391e4ea6d7
commit ab401ce65c
No known key found for this signature in database
2 changed files with 44 additions and 16 deletions

View File

@ -12,7 +12,7 @@
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use core::ops::Not;
use core::{ops::Not, time::Duration};
use std::sync::Arc;
use crate::{
@ -132,23 +132,43 @@ impl GameRunner {
.log_err();
};
(update_host)(&acks, &mut self.comms);
let notify_of_role = |player_id: PlayerId, village: &Village, sender: &LobbyPlayers| {
if let Some(char) = village.character_by_player_id(player_id) {
sender
.send_if_present(
player_id,
ServerMessage::GameStart {
let notify_of_role =
async |player_id: PlayerId, village: &Village, sender: &JoinedPlayers| {
if let Some(char) = village.character_by_player_id(player_id)
&& let Some(sender) = sender.get_sender(player_id).await
{
sender
.send(ServerMessage::GameStart {
role: char.initial_shown_role(),
},
)
.log_debug();
}
};
})
.log_debug();
}
};
let notify_non_ackd =
async |acks: &[(Character, bool)], village: &Village, sender: &JoinedPlayers| {
for pid in acks
.iter()
.filter_map(|(c, ack)| ack.not().then_some(c.player_id()))
{
(notify_of_role)(pid, village, sender).await;
}
};
let mut last_err_log = tokio::time::Instant::now() - tokio::time::Duration::from_secs(60);
let mut connect_list: Arc<[PlayerId]> = Arc::new([]);
while acks.iter().any(|(_, ackd)| !*ackd) {
let msg = match self.comms.message().await {
const PING_TIME: Duration = Duration::from_secs(1);
let sleep_fut = tokio::time::sleep(PING_TIME);
let msg = tokio::select! {
_ = sleep_fut => {
(notify_non_ackd)(&acks, self.game.village(), &self.joined_players).await;
continue;
}
msg = self.comms.message() => {
msg
}
};
let msg = match msg {
Ok(msg) => msg,
Err(err) => {
if (tokio::time::Instant::now() - last_err_log).as_secs() >= 30 {
@ -164,7 +184,8 @@ impl GameRunner {
acks.iter_mut().find(|(c, _)| c.character_id() == char_id)
{
*ackd = true;
(notify_of_role)(c.player_id(), self.game.village(), &self.player_sender);
(notify_of_role)(c.player_id(), self.game.village(), &self.joined_players)
.await;
}
(update_host)(&acks, &mut self.comms);
}
@ -233,11 +254,12 @@ impl GameRunner {
public: _,
},
message: _,
}) => (notify_of_role)(player_id, self.game.village(), &self.player_sender),
}) => (notify_of_role)(player_id, self.game.village(), &self.joined_players).await,
Message::ConnectedList(c) => {
let newly_connected = c.iter().filter(|c| connect_list.contains(*c));
for connected in newly_connected {
(notify_of_role)(*connected, self.game.village(), &self.player_sender)
(notify_of_role)(*connected, self.game.village(), &self.joined_players)
.await
}
connect_list = c;
}

View File

@ -980,6 +980,12 @@ input {
text-align: center;
align-items: center;
width: 100%;
height: 80vh;
justify-content: center;
&>p {
font-size: 1.5em;
}
&>button {
font-size: 1.5rem;