diff --git a/src/login/character.rs b/src/login/character.rs index 60fcf7e..59b2603 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -310,6 +310,68 @@ impl CharacterServerState { }) } + fn set_flag(&mut self, id: ClientId, setflag: &SetFlag) -> Result, CharacterError> { + let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; + let mut user = client.user.as_mut().unwrap(); + user.flags = setflag.flags; + self.entity_gateway.set_user(&user); + Ok(None.into_iter()) + } + + fn param_data_chunk_request(&mut self, id: ClientId, _request: &ParamDataChunkRequest) -> Result, CharacterError> { + let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; + let chunk = client.param_index; + client.param_index += 1; + + let start = chunk * 0x6800; + let end = std::cmp::min((chunk+1)*0x6800, self.param_data.len()); + + let mut data = [0u8; 0x6800]; + data[..end-start].copy_from_slice(&self.param_data[start..end]); + + Ok(vec![SendCharacterPacket::ParamDataChunk( + ParamDataChunk { + chunk: chunk as u32, + data: data, + } + )]) + } + + + // TODO: move USERFLAGS over to SessionAction + fn character_preview(&mut self, id: ClientId, preview: &CharacterPreview) -> Result, CharacterError> { + let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; + let mut user = client.user.as_mut().unwrap(); + if user.flags == USERFLAG_NEWCHAR { + let mut char = self.entity_gateway.new_character_by_user(&user); + char.slot = preview.slot; + char.character = preview.character.as_character(); + let char = Character { + id: 9, + slot: preview.slot, + user_id: user.id, + character: preview.character.as_character() + }; + self.entity_gateway.set_character(&char); + } + if user.flags == USERFLAG_DRESSINGROOM { + // TODO: dressing room stuff + } + + client.session.action = SessionAction::SelectCharacter; + client.session.character_slot = preview.slot as u8; + user.flags = 0; + self.entity_gateway.set_user(&user); + Ok(vec![SendCharacterPacket::LoginResponse(LoginResponse::by_char_select(user.guildcard.unwrap_or(0), + user.team_id.unwrap_or(1), + client.session)), + SendCharacterPacket::CharAck(CharAck { + slot: preview.slot, + code: 0 + }) + ]) + } + fn select_ship(&mut self, menuselect: &MenuSelect) -> Result, CharacterError> { if menuselect.menu != SHIP_MENU_ID { return Err(CharacterError::InvalidMenuSelection(menuselect.menu, menuselect.item)); @@ -371,63 +433,14 @@ impl ServerState for CharacterServerState { RecvCharacterPacket::ParamDataRequest(_request) => { Box::new(vec![SendCharacterPacket::ParamDataHeader(self.param_header.clone())].into_iter().map(move |pkt| (id, pkt))) }, - RecvCharacterPacket::SetFlag(flags) => { - let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; - let mut user = client.user.as_mut().unwrap(); - user.flags = flags.flags; - self.entity_gateway.set_user(&user); - Box::new(None.into_iter()) + RecvCharacterPacket::SetFlag(flag) => { + Box::new(self.set_flag(id, flag)?.map(move |pkt| (id, pkt))) }, - RecvCharacterPacket::ParamDataChunkRequest(_request) => { - let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; - let chunk = client.param_index; - client.param_index += 1; - - let start = chunk * 0x6800; - let end = std::cmp::min((chunk+1)*0x6800, self.param_data.len()); - - let mut data = [0u8; 0x6800]; - data[..end-start].copy_from_slice(&self.param_data[start..end]); - - Box::new(vec![SendCharacterPacket::ParamDataChunk( - ParamDataChunk { - chunk: chunk as u32, - data: data, - } - )].into_iter().map(move |pkt| (id, pkt))) + RecvCharacterPacket::ParamDataChunkRequest(request) => { + Box::new(self.param_data_chunk_request(id, request)?.into_iter().map(move |pkt| (id, pkt))) }, - // TODO: move USERFLAGS over to SessionAction RecvCharacterPacket::CharacterPreview(preview) => { - let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; - let mut user = client.user.as_mut().unwrap(); - if user.flags == USERFLAG_NEWCHAR { - let mut char = self.entity_gateway.new_character_by_user(&user); - char.slot = preview.slot; - char.character = preview.character.as_character(); - let char = Character { - id: 9, - slot: preview.slot, - user_id: user.id, - character: preview.character.as_character() - }; - self.entity_gateway.set_character(&char); - } - if user.flags == USERFLAG_DRESSINGROOM { - // TODO: dressing room stuff - } - - client.session.action = SessionAction::SelectCharacter; - client.session.character_slot = preview.slot as u8; - user.flags = 0; - self.entity_gateway.set_user(&user); - Box::new(vec![SendCharacterPacket::LoginResponse(LoginResponse::by_char_select(user.guildcard.unwrap_or(0), - user.team_id.unwrap_or(1), - client.session)), - SendCharacterPacket::CharAck(CharAck { - slot: preview.slot, - code: 0 - }) - ].into_iter().map(move |pkt| (id, pkt))) + Box::new(self.character_preview(id, preview)?.into_iter().map(move |pkt| (id, pkt))) }, RecvCharacterPacket::MenuSelect(menuselect) => { Box::new(self.select_ship(menuselect)?.into_iter().map(move |pkt| (id, pkt)))