You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
3.2 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. use std::convert::TryInto;
  2. use libpso::packet::ship::*;
  3. use networking::serverstate::ClientId;
  4. use maps::Holiday;
  5. use client::{ClientState, Clients};
  6. use location::{ClientLocation, RoomId, AreaClient, ClientLocationError};
  7. use room::RoomState;
  8. use items::state::ItemState;
  9. use crate::{player_header, player_info};
  10. use futures::stream::StreamExt;
  11. pub async fn join_room(id: ClientId,
  12. clients: &Clients,
  13. client_location: &ClientLocation,
  14. room_id: RoomId,
  15. room: &RoomState,
  16. event: Holiday)
  17. -> Result<JoinRoom, anyhow::Error> {
  18. let all_clients = client_location.get_clients_in_room(room_id).await.map_err(|err| -> ClientLocationError { err.into() })?;
  19. #[allow(clippy::manual_try_fold)] // I don't think its even possible to make this work here
  20. let players = futures::stream::iter(all_clients.iter())
  21. .enumerate()
  22. .fold::<Result<_, anyhow::Error>, _, _>(Ok([PlayerHeader::default(); 4]), |acc, (i, c)| async move {
  23. let header_area_client = client_location.get_local_client(id).await.map_err(|err| -> ClientLocationError {err.into() })?;
  24. clients.with(c.client, |client| Box::pin(async move {
  25. acc.map(|mut a| {
  26. a[i] = player_header(0x10000, client, &header_area_client);
  27. a
  28. })
  29. })).await?
  30. }).await?;
  31. let area_client = client_location.get_local_client(id).await.map_err(|err| -> ClientLocationError { err.into() })?;
  32. let leader = client_location.get_room_leader(room_id).await.map_err(|err| -> ClientLocationError { err.into() })?;
  33. Ok(JoinRoom {
  34. flag: all_clients.len() as u32,
  35. maps: room.maps.map_headers(),
  36. players,
  37. client: area_client.local_client.id(),
  38. leader: leader.local_client.id(),
  39. one: 1,
  40. difficulty: room.mode.difficulty().into(),
  41. battle: room.mode.battle() as u8,
  42. event: event.into(),
  43. section: room.section_id.into(),
  44. challenge: room.mode.challenge() as u8,
  45. random_seed: room.random_seed,
  46. episode: room.mode.episode().into(),
  47. one2: 1,
  48. single_player: room.mode.player_mode().value(),
  49. unknown: 0,
  50. })
  51. }
  52. pub async fn add_to_room(_id: ClientId,
  53. client: &ClientState,
  54. area_client: &AreaClient,
  55. leader: &AreaClient,
  56. item_state: &ItemState,
  57. event: Holiday)
  58. -> Result<AddToRoom, anyhow::Error> {
  59. let inventory = item_state.get_character_inventory(&client.character).await?;
  60. Ok(AddToRoom {
  61. flag: 1,
  62. client: area_client.local_client.id(),
  63. leader: leader.local_client.id(),
  64. one: 0, // TODO: ????????
  65. lobby: 0xFF,
  66. block: 0,
  67. event: event.into(),
  68. padding: 0,
  69. playerinfo: player_info(0x10000, client, area_client, &inventory).await,
  70. })
  71. }
  72. pub fn build_rare_monster_list(rare_monster_vec: Vec<u16>) -> RareMonsterList {
  73. RareMonsterList {
  74. ids: rare_monster_vec.try_into().unwrap_or([0xFFFFu16; 16]),
  75. }
  76. }