use std::collections::HashMap; use libpso::packet::ship::*; use crate::common::serverstate::ClientId; use crate::common::leveltable::CharacterLevelTable; use crate::ship::ship::{SendShipPacket, ShipError, ClientState}; use crate::ship::character::{CharacterBytesBuilder, FullCharacterBytesBuilder}; use crate::ship::location::{ClientLocation, LobbyId, RoomId, RoomLobby, MAX_ROOMS}; use libpso::character::character; pub fn send_player_to_lobby(id: ClientId, _pkt: &CharData, client_location: &mut ClientLocation, clients: &HashMap, level_table: &CharacterLevelTable) -> Result, ShipError> { let lobby = client_location.add_client_to_next_available_lobby(id, LobbyId(0)).map_err(|_| ShipError::TooManyClients)?; let lobby_clients = client_location.get_clients_in_lobby(lobby).map_err(|err| ShipError::ClientError(format!("{:?}", err)))?; let playerinfo = lobby_clients.iter() .map(|room_client| { let client = clients.get(&room_client.client).ok_or(ShipError::ClientNotFound(id)).unwrap(); let (level, stats) = level_table.get_stats_from_exp(client.character.char_class, client.character.exp); let c = CharacterBytesBuilder::new() .character(&client.character) .stats(&stats) .level(level - 1) .build(); PlayerInfo { header: PlayerHeader { tag: 0x100, guildcard: client.user.id.0, _unknown1: [0; 5], client_id: room_client.local_client.id() as u32, name: c.name, _unknown2: 2, }, inventory: character::Inventory { item_count: 0, hp_mats_used: 0, tp_mats_used: 0, language: 0, items: [character::InventoryItem::default(); 30], }, character: c, } }); let area_client = client_location.get_local_client(id).map_err(|err| ShipError::ClientError(format!("{:?}", err)))?; let leader = client_location.get_lobby_leader(lobby).map_err(|err| ShipError::ClientError(format!("{:?}", err)))?; let join_lobby = JoinLobby { client: area_client.local_client.id(), leader: leader.local_client.id(), one: 1, lobby: lobby.id(), block: 1, event: 0, padding: 0, playerinfo: playerinfo.collect(), }; let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?; let (level, stats) = level_table.get_stats_from_exp(client.character.char_class, client.character.exp); let c = CharacterBytesBuilder::new() .character(&client.character) .stats(&stats) .level(level - 1) .build(); let addto = AddToLobby { flag: 1, client: area_client.local_client.id(), leader: leader.local_client.id(), one: 1, lobby: lobby.id(), block: 1, event: 0, padding: 0, playerinfo: PlayerInfo { header: PlayerHeader { tag: 0x100, guildcard: client.user.id.0, _unknown1: [0; 5], client_id: area_client.local_client.id() as u32, name: c.name, _unknown2: 2, }, inventory: character::Inventory { item_count: 0, hp_mats_used: 0, tp_mats_used: 0, language: 0, items: [character::InventoryItem::default(); 30], }, character: c, }, }; let neighbors = client_location.get_client_neighbors(id).unwrap(); Ok(vec![(id, SendShipPacket::JoinLobby(join_lobby))] .into_iter() .chain(neighbors.into_iter() .map(|c| (c.client, SendShipPacket::AddToLobby(addto.clone())))).collect()) }