Skip to content

Commit

Permalink
reject start reason for invalid rolelists
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsSammyM committed Dec 18, 2023
1 parent 0e568ac commit 53427cb
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 55 deletions.
28 changes: 20 additions & 8 deletions client/src/game/messageListener.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@ export default function messageListener(packet: ToClientPacket){
break;
case "rejectJoin":
switch(packet.reason) {
case "INVALID_ROOM_CODE":
case "invalidRoomCode":
Anchor.pushInfo("Couldn't join", "No lobby has that room code!");
break;
case "GAME_ALREADY_STARTED":
case "gameAlreadyStarted":
Anchor.pushInfo("Couldn't join", "That game has already begun!");
break;
case "ROOM_FULL":
case "roomFull":
Anchor.pushInfo("Couldn't join", "That lobby is full!");
break;
case "SERVER_BUSY":
case "serverBusy":
Anchor.pushInfo("Couldn't join", "The server is busy. Try again later!");
break;
default:
Expand All @@ -52,12 +52,24 @@ export default function messageListener(packet: ToClientPacket){
Anchor.setContent(<StartMenu/>);
break;
case "rejectStart":
/*
GameEndsInstantly,
RoleListTooSmall,
RoleListCannotCreateRoles,
ZeroTimeGame,
*/
switch(packet.reason) {
case "GameEndsInstantly":
case "gameEndsInstantly":
Anchor.pushInfo("Couldn't start", "Game would end instantly! Make sure your role list is valid.");
break;
case "ZeroTimeGame":
Anchor.pushInfo("Couldn't start", "Make sure your phase time settings are valid!");
case "roleListTooSmall":
Anchor.pushInfo("Couldn't start", "Role list is too small!");
break;
case "roleListCannotCreateRoles":
Anchor.pushInfo("Couldn't start", "Role list is invalid! Excluded roles could be the problem.");
break;
case "zeroTimeGame":
Anchor.pushInfo("Couldn't start", "Game has zero time.");
break;
default:
Anchor.pushInfo("Couldn't start", "Failed to start lobby. Try again later!");
Expand Down Expand Up @@ -257,7 +269,7 @@ export default function messageListener(packet: ToClientPacket){
if(GAME_MANAGER.state.stateType === "game"){
GAME_MANAGER.state.ticking = false;
switch(packet.reason) {
case "ReachedMaxDay":
case "reachedMaxDay":
// alert("Game Over: Reached the maximum day!");
console.log("incoming message response not implemented " + packet.type + ": " + packet.reason);
console.log(packet);
Expand Down
50 changes: 36 additions & 14 deletions server/src/game/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ pub mod recruit;
use std::time::Duration;
use rand::seq::SliceRandom;
use rand::thread_rng;
use serde::Serialize;

use crate::lobby::LobbyPlayer;
use crate::log;
use crate::packet::{ToClientPacket, GameOverReason};
use crate::packet::ToClientPacket;
use chat::{ChatMessage, ChatGroup};
use player::PlayerReference;
use role_list::{RoleOutline, create_random_roles};
use role_list::create_random_roles;
use player::Player;
use phase::PhaseStateMachine;
use settings::Settings;
Expand All @@ -48,20 +48,43 @@ pub struct Game {
pub ticking: bool
}

#[derive(Serialize, Debug, Clone, Copy)]
#[serde(rename_all = "camelCase")]
pub enum RejectStartReason {
GameEndsInstantly,
RoleListTooSmall,
RoleListCannotCreateRoles,
ZeroTimeGame,
}

#[derive(Serialize, Debug, Clone, Copy)]
#[serde(rename_all = "camelCase")]
pub enum GameOverReason {
ReachedMaxDay,
Winner,
Draw
/*TODO Winner { who won? }*/
}

impl Game {
pub fn new(mut settings: Settings, lobby_players: Vec<LobbyPlayer>) -> Self{
pub fn new(settings: Settings, lobby_players: Vec<LobbyPlayer>) -> Result<Self, RejectStartReason>{
//check settings are not completly off the rails
if [
settings.phase_times.evening, settings.phase_times.morning,
settings.phase_times.discussion, settings.phase_times.voting,
settings.phase_times.judgement, settings.phase_times.testimony,
settings.phase_times.night,
].iter().all(|t| *t == 0) {
return Err(RejectStartReason::ZeroTimeGame);
}


let mut roles = match create_random_roles(&settings.excluded_roles, &settings.role_list){
Some(roles) => {
roles
},
None => {
let mut new_list = vec![];
for _ in 0..lobby_players.len(){
new_list.push(RoleOutline::Any);
}
settings.role_list = new_list;
settings.excluded_roles = vec![];
create_random_roles(&settings.excluded_roles, &settings.role_list).expect("All any with no exclusions should have open roles")
return Err(RejectStartReason::RoleListCannotCreateRoles);
}
};
roles.shuffle(&mut thread_rng());
Expand All @@ -74,8 +97,7 @@ impl Game {
match roles.get(player_index){
Some(role) => *role,
None => {
log!(error "Game::new"; "Failed to generate role. rolelist wasnt big enough for number of players");
RoleOutline::Any.get_random_role(&settings.excluded_roles, &roles).expect("Any should have open roles")
return Err(RejectStartReason::RoleListTooSmall);
},
}
);
Expand Down Expand Up @@ -104,7 +126,7 @@ impl Game {

Teams::on_team_creation(&mut game);

game
Ok(game)
}

/// Returns a tuple containing the number of guilty votes and the number of innocent votes
Expand Down
2 changes: 1 addition & 1 deletion server/src/game/player/player_send_packet.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::time::Duration;

use crate::{game::{Game, available_buttons::AvailableButtons, phase::PhaseState}, packet::{ToClientPacket, GameOverReason}, websocket_connections::connection::ClientSender};
use crate::{game::{Game, available_buttons::AvailableButtons, phase::PhaseState, GameOverReason}, packet::ToClientPacket, websocket_connections::connection::ClientSender};

use super::{PlayerReference, ClientConnection, DISCONNECT_TIMER_SECS};

Expand Down
9 changes: 9 additions & 0 deletions server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ pub mod log {
/// log!(error "Game::new"; "Failed to generate role. rolelist wasnt big enough for number of players");
/// log!(info "Listener"; "{}: {}", "Received message", "message");
/// ```
///
/// # Markers
/// - `fatal`: Prints the word FATAL
/// - `error`: Prints red and writes "WARN"
/// - `important`:
/// - `info`:
///
/// if none are put then it defaults to info
///
macro_rules! log {
// Each case in this macro definition is for a different log marker.
// None
Expand Down
26 changes: 12 additions & 14 deletions server/src/lobby.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
role_list::RoleOutline,
phase::PhaseType
},
listener::{PlayerID, RoomCode}, packet::{ToClientPacket, RejectJoinReason, ToServerPacket, RejectStartReason}, websocket_connections::connection::ClientSender, log
listener::{PlayerID, RoomCode}, packet::{ToClientPacket, RejectJoinReason, ToServerPacket}, websocket_connections::connection::ClientSender, log
};

pub struct Lobby {
Expand Down Expand Up @@ -88,29 +88,18 @@ impl Lobby {
Self::send_players_lobby(players);
},
ToServerPacket::StartGame => {
let LobbyState::Lobby { settings, players } = &mut self.lobby_state else {
let LobbyState::Lobby { settings: _, players } = &mut self.lobby_state else {
log!(error "Lobby"; "{} {}", "ToServerPacket::StartGame can not be used outside of LobbyState::Lobby", player_id);
return;
};
if let Some(player) = players.get(&player_id){
if !player.host {return;}
}

if [
settings.phase_times.evening, settings.phase_times.morning,
settings.phase_times.discussion, settings.phase_times.voting,
settings.phase_times.judgement, settings.phase_times.testimony,
settings.phase_times.night,
].iter().all(|t| *t == 0) {
send.send(ToClientPacket::RejectStart { reason: RejectStartReason::ZeroTimeGame });
return;
}

let mut player_indices: HashMap<PlayerID,GamePlayer> = HashMap::new();
let mut game_players = Vec::new();


self.send_to_all(ToClientPacket::StartGame);

let LobbyState::Lobby { settings, players} = &mut self.lobby_state else {
unreachable!("LobbyState::Lobby was checked to be to LobbyState::Lobby in the previous line")
Expand All @@ -121,10 +110,19 @@ impl Lobby {
game_players.push(lobby_player);
}

let game = match Game::new(settings.clone(), game_players){
Ok(game) => game,
Err(err) => {
send.send(ToClientPacket::RejectStart { reason: err });
log!(info "Lobby"; "Failed to start game: {:?}", err);
return;
}
};

self.send_to_all(ToClientPacket::StartGame);

self.lobby_state = LobbyState::Game{
game: Game::new(settings.clone(), game_players),
game,
players: player_indices,
};
let LobbyState::Game { game, players: _player } = &mut self.lobby_state else {
Expand Down
20 changes: 2 additions & 18 deletions server/src/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::{game::{
verdict::Verdict, phase::PhaseType,
chat::ChatMessage,
role::{Role, RoleState, doomsayer::DoomsayerGuess},
Game, grave::Grave, available_buttons::AvailableButtons, tag::Tag, settings::PhaseTimeSettings
Game, grave::Grave, available_buttons::AvailableButtons, tag::Tag, settings::PhaseTimeSettings, RejectStartReason, GameOverReason
}, listener::{RoomCode, PlayerID}, log};

#[derive(Serialize, Debug, Clone)]
Expand Down Expand Up @@ -128,30 +128,14 @@ impl ToClientPacket {
}

#[derive(Serialize, Debug, Clone, Copy)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
#[serde(rename_all = "camelCase")]
pub enum RejectJoinReason {
GameAlreadyStarted,
RoomFull,
InvalidRoomCode,
ServerBusy,
}

#[derive(Serialize, Debug, Clone, Copy)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum RejectStartReason {
GameEndsInstantly,
ZeroTimeGame,
}

#[derive(Serialize, Debug, Clone, Copy)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum GameOverReason {
ReachedMaxDay,
Winner,
Draw
/*TODO Winner { who won? }*/
}

#[derive(Deserialize, Debug, Clone)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum ToServerPacket{
Expand Down

1 comment on commit 53427cb

@vercel
Copy link

@vercel vercel bot commented on 53427cb Dec 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

mafia-game – ./

mafia-game-git-00x-main-itssammym.vercel.app
mafia-game.vercel.app
mafia-game-itssammym.vercel.app

Please sign in to comment.