From c89751aa2255d2efc93ad9949491142298a4d7c9 Mon Sep 17 00:00:00 2001 From: andy Date: Sun, 23 May 2021 18:18:36 +0000 Subject: [PATCH 1/6] add level requirements for rooms and update tests --- src/ship/packet/handler/room.rs | 68 ++++++++++++++++++++++++++++++--- src/ship/room.rs | 5 ++- src/ship/ship.rs | 2 +- tests/test_shops.rs | 6 +-- 4 files changed, 69 insertions(+), 12 deletions(-) diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index c3be9dc..a058f9a 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -7,20 +7,47 @@ use crate::ship::location::{ClientLocation, RoomId, RoomLobby, ClientLocationErr use crate::ship::packet::builder; use crate::ship::room; use crate::ship::items::ItemManager; +use std::convert::{TryFrom}; pub fn create_room(id: ClientId, create_room: &CreateRoom, client_location: &mut ClientLocation, clients: &mut Clients, item_manager: &mut ItemManager, + level_table: &CharacterLevelTable, rooms: &mut Rooms) - -> Result + Send>, ShipError> { + -> Result + Send>, anyhow::Error> { + let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?; + let level = level_table.get_level_from_exp(client.character.char_class, client.character.exp); + match room::Difficulty::try_from(create_room.difficulty)? { + room::Difficulty::Ultimate => { + if level < 80 { + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 80 \nto create Ultimate rooms.".into())))].into_iter())) + } + }, + room::Difficulty::VeryHard => { + if level < 40 { + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 40 \nto create Very Hard rooms.".into())))].into_iter())) + } + }, + room::Difficulty::Hard => { + if level < 20 { + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 20 \nto create Hard rooms.".into())))].into_iter())) + } + }, + room::Difficulty::Normal => { + if level < 1 { + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 1 \nto create Normal rooms.".into())))].into_iter())) + } + }, + // i can't believe you've done this + _ => {unreachable!()}, + }; + let area = client_location.get_area(id).unwrap(); let area_client = client_location.get_local_client(id).unwrap(); let lobby_neighbors = client_location.get_client_neighbors(id).unwrap(); let room_id = client_location.create_new_room(id).unwrap(); - - let client = clients.get_mut(&id).unwrap();//.ok_or(ShipError::ClientNotFound(id)).unwrap(); let mut room = room::RoomState::from_create_room(create_room, client.character.section_id).unwrap(); room.bursting = true; @@ -63,11 +90,40 @@ pub fn join_room(id: ClientId, level_table: &CharacterLevelTable, rooms: &mut Rooms) -> Result + Send>, ShipError> { + let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?; + let level = level_table.get_level_from_exp(client.character.char_class, client.character.exp); + let room = rooms.get(pkt.item as usize) + .ok_or_else(|| ShipError::InvalidRoom(pkt.item))?.as_ref() + .ok_or_else(|| ShipError::InvalidRoom(pkt.item))?; + + match room.mode.difficulty() { + room::Difficulty::Ultimate => { + if level < 80 { + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 80 \nto join Ultimate rooms.".into())))].into_iter())) + } + }, + room::Difficulty::VeryHard => { + if level < 40 { + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 40 \nto join Very Hard rooms.".into())))].into_iter())) + } + }, + room::Difficulty::Hard => { + if level < 20 { + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 20 \nto join Hard rooms.".into())))].into_iter())) + } + }, + room::Difficulty::Normal => { + if level < 1 { + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 1 \nto join Normal rooms.".into())))].into_iter())) + } + }, + }; + let original_area = client_location.get_area(id).unwrap(); let original_neighbors = client_location.get_client_neighbors(id).unwrap(); - let room = rooms.get(pkt.item as usize) - .ok_or(ShipError::InvalidRoom(pkt.item))?.as_ref() - .ok_or(ShipError::InvalidRoom(pkt.item))?; + // let room = rooms.get(pkt.item as usize) + // .ok_or_else(|| ShipError::InvalidRoom(pkt.item))?.as_ref() + // .ok_or_else(|| ShipError::InvalidRoom(pkt.item))?; if room.bursting { return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("player is bursting\nplease wait".into())))].into_iter())) } diff --git a/src/ship/room.rs b/src/ship/room.rs index 3aae5da..991de54 100644 --- a/src/ship/room.rs +++ b/src/ship/room.rs @@ -7,14 +7,15 @@ use crate::ship::drops::DropTable; use crate::entity::character::SectionID; use crate::ship::monster::{load_monster_stats_table, MonsterType, MonsterStats}; use crate::ship::map::area::MapAreaLookup; +use thiserror::Error; -#[derive(Debug)] +#[derive(Debug, Error)] +#[error("")] pub enum RoomCreationError { InvalidMode, InvalidEpisode(u8), InvalidDifficulty(u8), CouldNotLoadMonsterStats(RoomMode), - } #[derive(Debug, Copy, Clone, derive_more::Display)] diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 8091647..11ffd55 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -632,7 +632,7 @@ impl ServerState for ShipServerState { }, RecvShipPacket::CreateRoom(create_room) => { let block = self.blocks.with_client(id, &self.clients)?; - handler::room::create_room(id, create_room, &mut block.client_location, &mut self.clients, &mut self.item_manager, &mut block.rooms)? + handler::room::create_room(id, create_room, &mut block.client_location, &mut self.clients, &mut self.item_manager, &self.level_table, &mut block.rooms)? }, RecvShipPacket::RoomNameRequest(_req) => { let block = self.blocks.with_client(id, &self.clients)?; diff --git a/tests/test_shops.rs b/tests/test_shops.rs index ade8ccf..c8ebb06 100644 --- a/tests/test_shops.rs +++ b/tests/test_shops.rs @@ -279,7 +279,7 @@ async fn test_other_clients_see_purchase() { log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; join_lobby(&mut ship, ClientId(2)).await; - create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; + create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Normal).await; join_room(&mut ship, ClientId(2), 0).await; ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest { @@ -333,7 +333,7 @@ async fn test_other_clients_see_stacked_purchase() { log_in_char(&mut ship, ClientId(2), "a2", "a").await; join_lobby(&mut ship, ClientId(1)).await; join_lobby(&mut ship, ClientId(2)).await; - create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; + create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Normal).await; join_room(&mut ship, ClientId(2), 0).await; ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest { @@ -370,7 +370,7 @@ async fn test_buying_item_without_enough_mseseta() { .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; - create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; + create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Normal).await; ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::ShopRequest(ShopRequest { client: 255, From baf5510c21b709b743c6be6c19aad52cd6e4246d Mon Sep 17 00:00:00 2001 From: andy Date: Tue, 22 Jun 2021 03:20:05 +0000 Subject: [PATCH 2/6] missing nuls is too advanced for the client? --- src/ship/packet/handler/room.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index a058f9a..8841d87 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -22,22 +22,22 @@ pub fn create_room(id: ClientId, match room::Difficulty::try_from(create_room.difficulty)? { room::Difficulty::Ultimate => { if level < 80 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 80 \nto create Ultimate rooms.".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 80 \nto create Ultimate rooms.\0".into())))].into_iter())) } }, room::Difficulty::VeryHard => { if level < 40 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 40 \nto create Very Hard rooms.".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 40 \nto create Very Hard rooms.\0".into())))].into_iter())) } }, room::Difficulty::Hard => { if level < 20 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 20 \nto create Hard rooms.".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 20 \nto create Hard rooms.\0".into())))].into_iter())) } }, room::Difficulty::Normal => { if level < 1 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 1 \nto create Normal rooms.".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 1 \nto create Normal rooms.\0".into())))].into_iter())) } }, // i can't believe you've done this @@ -99,22 +99,22 @@ pub fn join_room(id: ClientId, match room.mode.difficulty() { room::Difficulty::Ultimate => { if level < 80 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 80 \nto join Ultimate rooms.".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 80 \nto join Ultimate rooms.\0".into())))].into_iter())) } }, room::Difficulty::VeryHard => { if level < 40 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 40 \nto join Very Hard rooms.".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 40 \nto join Very Hard rooms.\0".into())))].into_iter())) } }, room::Difficulty::Hard => { if level < 20 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 20 \nto join Hard rooms.".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 20 \nto join Hard rooms.\0".into())))].into_iter())) } }, room::Difficulty::Normal => { if level < 1 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 1 \nto join Normal rooms.".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 1 \nto join Normal rooms.\0".into())))].into_iter())) } }, }; From 0e2d6cd3b10ef965ec3f6caa8831ddcfef081d28 Mon Sep 17 00:00:00 2001 From: andy Date: Tue, 22 Jun 2021 23:23:22 +0000 Subject: [PATCH 3/6] don't expect people to remember null in Rust --- src/ship/packet/handler/room.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index 8841d87..a058f9a 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -22,22 +22,22 @@ pub fn create_room(id: ClientId, match room::Difficulty::try_from(create_room.difficulty)? { room::Difficulty::Ultimate => { if level < 80 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 80 \nto create Ultimate rooms.\0".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 80 \nto create Ultimate rooms.".into())))].into_iter())) } }, room::Difficulty::VeryHard => { if level < 40 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 40 \nto create Very Hard rooms.\0".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 40 \nto create Very Hard rooms.".into())))].into_iter())) } }, room::Difficulty::Hard => { if level < 20 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 20 \nto create Hard rooms.\0".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 20 \nto create Hard rooms.".into())))].into_iter())) } }, room::Difficulty::Normal => { if level < 1 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 1 \nto create Normal rooms.\0".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 1 \nto create Normal rooms.".into())))].into_iter())) } }, // i can't believe you've done this @@ -99,22 +99,22 @@ pub fn join_room(id: ClientId, match room.mode.difficulty() { room::Difficulty::Ultimate => { if level < 80 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 80 \nto join Ultimate rooms.\0".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 80 \nto join Ultimate rooms.".into())))].into_iter())) } }, room::Difficulty::VeryHard => { if level < 40 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 40 \nto join Very Hard rooms.\0".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 40 \nto join Very Hard rooms.".into())))].into_iter())) } }, room::Difficulty::Hard => { if level < 20 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 20 \nto join Hard rooms.\0".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 20 \nto join Hard rooms.".into())))].into_iter())) } }, room::Difficulty::Normal => { if level < 1 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 1 \nto join Normal rooms.\0".into())))].into_iter())) + return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 1 \nto join Normal rooms.".into())))].into_iter())) } }, }; From 6980355c00c706c8b669e1d9e2fb39f071e76047 Mon Sep 17 00:00:00 2001 From: andy Date: Wed, 23 Jun 2021 00:00:46 +0000 Subject: [PATCH 4/6] imagine being level 0 --- src/ship/packet/handler/room.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index a058f9a..19a9296 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -35,11 +35,6 @@ pub fn create_room(id: ClientId, return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 20 \nto create Hard rooms.".into())))].into_iter())) } }, - room::Difficulty::Normal => { - if level < 1 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 1 \nto create Normal rooms.".into())))].into_iter())) - } - }, // i can't believe you've done this _ => {unreachable!()}, }; @@ -112,11 +107,6 @@ pub fn join_room(id: ClientId, return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 20 \nto join Hard rooms.".into())))].into_iter())) } }, - room::Difficulty::Normal => { - if level < 1 { - return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 1 \nto join Normal rooms.".into())))].into_iter())) - } - }, }; let original_area = client_location.get_area(id).unwrap(); From f0f65c70be9d4e4cc8d986be7c9d343a13a48ad5 Mon Sep 17 00:00:00 2001 From: andy Date: Wed, 23 Jun 2021 00:02:31 +0000 Subject: [PATCH 5/6] cleanup --- src/ship/packet/handler/room.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index 19a9296..f2ff793 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -107,13 +107,11 @@ pub fn join_room(id: ClientId, return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 20 \nto join Hard rooms.".into())))].into_iter())) } }, + _ => {}, }; let original_area = client_location.get_area(id).unwrap(); let original_neighbors = client_location.get_client_neighbors(id).unwrap(); - // let room = rooms.get(pkt.item as usize) - // .ok_or_else(|| ShipError::InvalidRoom(pkt.item))?.as_ref() - // .ok_or_else(|| ShipError::InvalidRoom(pkt.item))?; if room.bursting { return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("player is bursting\nplease wait".into())))].into_iter())) } From e6cf819bf4f776e227e46fc69c6b1cbf495bf2cd Mon Sep 17 00:00:00 2001 From: andy Date: Wed, 23 Jun 2021 01:03:54 +0000 Subject: [PATCH 6/6] andy vs. clippy round 3 --- src/ship/packet/handler/room.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index f2ff793..60339bb 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -35,8 +35,7 @@ pub fn create_room(id: ClientId, return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("You must be at least level 20 \nto create Hard rooms.".into())))].into_iter())) } }, - // i can't believe you've done this - _ => {unreachable!()}, + room::Difficulty::Normal => {}, }; let area = client_location.get_area(id).unwrap(); @@ -87,9 +86,7 @@ pub fn join_room(id: ClientId, -> Result + Send>, ShipError> { let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?; let level = level_table.get_level_from_exp(client.character.char_class, client.character.exp); - let room = rooms.get(pkt.item as usize) - .ok_or_else(|| ShipError::InvalidRoom(pkt.item))?.as_ref() - .ok_or_else(|| ShipError::InvalidRoom(pkt.item))?; + let room = rooms.get(pkt.item as usize).ok_or(ShipError::InvalidRoom(pkt.item))?.as_ref().unwrap(); // clippy look what you made me do match room.mode.difficulty() { room::Difficulty::Ultimate => {