Browse Source

error handling. tests!

pull/86/head
andy 3 years ago
parent
commit
6d3588f656
  1. 12
      src/ship/packet/handler/quest.rs
  2. 28
      src/ship/room.rs
  3. 42
      tests/test_rooms.rs

12
src/ship/packet/handler/quest.rs

@ -41,7 +41,7 @@ pub fn send_quest_category_list(id: ClientId, rql: &RequestQuestList, client_loc
let room = rooms.get_mut(room_id.0)
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?.as_mut()
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?;
let qcl = quest::quest_category_list(&room.quests[rql.flag as usize]);
let qcl = quest::quest_category_list(&room.quests[rql.flag.clamp(0, (room.quests.len() - 1) as u32) as usize]);
room.set_quest_group(rql.flag as usize);
Ok(Box::new(vec![(id, SendShipPacket::QuestCategoryList(qcl))].into_iter()))
}
@ -51,7 +51,7 @@ pub fn select_quest_category(id: ClientId, menuselect: &MenuSelect, client_locat
let room = rooms.get_mut(room_id.0)
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?.as_mut()
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?;
let (_, category_quests) = room.quests[room.quest_group].iter() // TODO: error handling for invalid quest group
let (_, category_quests) = room.quests[room.quest_group.value()].iter()
.nth(menuselect.item as usize)
.ok_or(ShipError::InvalidQuestCategory(menuselect.item))?;
@ -68,7 +68,7 @@ pub fn quest_detail(id: ClientId, questdetailrequest: &QuestDetailRequest, clien
let room = rooms.get_mut(room_id.0)
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?.as_mut()
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?;
let (_, category_quests) = room.quests[room.quest_group].iter()
let (_, category_quests) = room.quests[room.quest_group.value()].iter()
.nth(questdetailrequest.category as usize)
.ok_or(ShipError::InvalidQuestCategory(questdetailrequest.category as u32))?;
@ -88,7 +88,7 @@ pub fn player_chose_quest(id: ClientId, questmenuselect: &QuestMenuSelect, clien
let room = rooms.get_mut(room_id.0)
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?.as_mut()
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?;
let (_, category_quests) = room.quests[room.quest_group].iter()
let (_, category_quests) = room.quests[room.quest_group.value()].iter()
.nth(questmenuselect.category as usize)
.ok_or(ShipError::InvalidQuestCategory(questmenuselect.category as u32))?;
@ -121,7 +121,7 @@ pub fn quest_file_request(id: ClientId, quest_file_request: &QuestFileRequest, c
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?;
let (category_id, quest_id, datatype) = parse_filename(&quest_file_request.filename)?;
let (_, category_quests) = room.quests[room.quest_group].iter()
let (_, category_quests) = room.quests[room.quest_group.value()].iter()
.nth(category_id as usize)
.ok_or(ShipError::InvalidQuestCategory(category_id as u32))?;
@ -150,7 +150,7 @@ pub fn quest_chunk_ack(id: ClientId, quest_chunk_ack: &QuestChunkAck, client_loc
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?;
let (category_id, quest_id, datatype) = parse_filename(&quest_chunk_ack.filename)?;
let (_, category_quests) = room.quests[room.quest_group].iter()
let (_, category_quests) = room.quests[room.quest_group.value()].iter()
.nth(category_id as usize)
.ok_or(ShipError::InvalidQuestCategory(category_id as u32))?;

28
src/ship/room.rs

@ -165,7 +165,29 @@ impl RoomMode {
}
}
}
pub enum QuestCategoryType {
Standard,
Government,
}
impl From<usize> for QuestCategoryType {
fn from(f: usize) -> QuestCategoryType {
match f {
0 => QuestCategoryType::Standard,
1 => QuestCategoryType::Government,
_ => QuestCategoryType::Standard, // TODO: panic?
}
}
}
impl QuestCategoryType {
pub fn value(&self) -> usize {
match self {
QuestCategoryType::Standard => 0,
QuestCategoryType::Government => 1,
}
}
}
pub struct RoomState {
pub mode: RoomMode,
@ -179,7 +201,7 @@ pub struct RoomState {
pub monster_stats: Box<HashMap<MonsterType, MonsterStats>>,
pub map_areas: MapAreaLookup,
pub rare_monster_table: Box<RareMonsterAppearTable>,
pub quest_group: usize,
pub quest_group: QuestCategoryType,
pub quests: Vec<quests::QuestList>,
// items on ground
// enemy info
@ -217,7 +239,7 @@ impl RoomState {
}
pub fn set_quest_group(&mut self, group: usize) {
self.quest_group = group;
self.quest_group = QuestCategoryType::from(group);
}
pub fn from_create_room(create_room: &libpso::packet::ship::CreateRoom, section_id: SectionID) -> Result<RoomState, RoomCreationError> {
@ -292,7 +314,7 @@ impl RoomState {
drop_table: Box::new(DropTable::new(room_mode.episode(), room_mode.difficulty(), section_id)),
bursting: false,
map_areas: MapAreaLookup::new(&room_mode.episode()),
quest_group: 0,
quest_group: QuestCategoryType::Standard,
quests: room_quests,
})
}

42
tests/test_rooms.rs

@ -115,3 +115,45 @@ async fn test_load_rare_monster_default_appear_rates() {
assert_eq!(rate, 0.001953125f32); // 1/512 = 0.001953125
}
}
#[async_std::test]
async fn test_set_valid_quest_group() {
let mut entity_gateway = InMemoryGateway::default();
let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
let mut ship = Box::new(ShipServerState::builder()
.gateway(entity_gateway.clone())
.build());
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
join_lobby(&mut ship, ClientId(1)).await;
create_room(&mut ship, ClientId(1), "room", "").await;
let packets = ship.handle(ClientId(1), &RecvShipPacket::RequestQuestList(RequestQuestList{flag: 0})).await.unwrap().collect::<Vec<_>>();
match &packets[0].1 {
SendShipPacket::QuestCategoryList(quest_cat) => {
assert!(String::from_utf16_lossy(&quest_cat.quest_categories[0].name).starts_with("Retrieval"));
},
_ => panic!("Wrong quest category"),
}
}
#[async_std::test]
async fn test_set_invalid_quest_group() {
let mut entity_gateway = InMemoryGateway::default();
let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
let mut ship = Box::new(ShipServerState::builder()
.gateway(entity_gateway.clone())
.build());
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
join_lobby(&mut ship, ClientId(1)).await;
create_room(&mut ship, ClientId(1), "room", "").await;
let packets = ship.handle(ClientId(1), &RecvShipPacket::RequestQuestList(RequestQuestList{flag: 100})).await.unwrap().collect::<Vec<_>>();
match &packets[0].1 {
SendShipPacket::QuestCategoryList(quest_cat) => {
// flag > quest category length should take the highest value allowed for quest category which is 1 in multimode (for govt quests) and 0 in other modes.
// assuming we create an ep1 room in multimode, we should load the government quests in this test case
assert!(String::from_utf16_lossy(&quest_cat.quest_categories[0].name).starts_with("Government"));
},
_ => panic!("Wrong quest category"),
}
}
Loading…
Cancel
Save