diff --git a/Cargo.toml b/Cargo.toml index 16c0850..ae1f141 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,4 +38,5 @@ fern = { version = "0.5", features = ["colored"] } byteorder = "1" enum-utils = "0.1.2" derive_more = { version = "0.99.3", features = ["display"]} +thiserror = "1.0.15" diff --git a/src/ship/location.rs b/src/ship/location.rs index 95e4134..e3b1c78 100644 --- a/src/ship/location.rs +++ b/src/ship/location.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; use std::sync::{Arc, RwLock}; use std::convert::Into; - use std::time::SystemTime; +use thiserror::Error; use crate::common::serverstate::ClientId; pub const MAX_ROOMS: usize = 128; @@ -25,27 +25,79 @@ impl LobbyId { } -#[derive(Debug, PartialEq)] +#[derive(Error, Debug, PartialEq)] +#[error("")] pub enum CreateRoomError { NoOpenSlots, ClientInAreaAlready, JoinError, } -#[derive(Debug, PartialEq)] +#[derive(Error, Debug, PartialEq)] +#[error("")] pub enum JoinRoomError { RoomDoesNotExist, RoomFull, ClientInAreaAlready, } -#[derive(Debug, PartialEq)] +#[derive(Error, Debug, PartialEq)] +#[error("")] pub enum JoinLobbyError { LobbyDoesNotExist, LobbyFull, ClientInAreaAlready, } +#[derive(Error, Debug, PartialEq)] +#[error("")] +pub enum GetAreaError { + InvalidClient, +} + +#[derive(Error, Debug, PartialEq)] +#[error("")] +pub enum ClientRemovalError { + ClientNotInArea, + InvalidArea, +} + +#[derive(Error, Debug, PartialEq)] +#[error("")] +pub enum GetClientsError { + InvalidClient, + InvalidArea, +} + +#[derive(Error, Debug, PartialEq)] +#[error("")] +pub enum GetNeighborError { + InvalidClient, + InvalidArea, +} + +#[derive(Error, Debug, PartialEq)] +#[error("")] +pub enum GetLeaderError { + InvalidClient, + InvalidArea, + NoClientInArea, +} + +#[derive(Error, Debug, PartialEq)] +#[error("")] +pub enum ClientLocationError { + CreateRoomError(#[from] CreateRoomError), + JoinRoomError(#[from] JoinRoomError), + JoinLobbyError(#[from] JoinLobbyError), + GetAreaError(#[from] GetAreaError), + ClientRemovalError(#[from] ClientRemovalError), + GetClientsError(#[from] GetClientsError), + GetNeighborError(#[from] GetNeighborError), + GetLeaderError(#[from] GetLeaderError) +} + + #[derive(Debug, Copy, Clone, PartialEq)] pub struct LocalClientId(usize); @@ -73,36 +125,6 @@ pub enum RoomLobby { Lobby(LobbyId), } -#[derive(Debug, PartialEq)] -pub enum GetAreaError { - InvalidClient, -} - -#[derive(Debug, PartialEq)] -pub enum ClientRemovalError { - ClientNotInArea, - InvalidArea, -} - -#[derive(Debug, PartialEq)] -pub enum GetClientsError { - InvalidClient, - InvalidArea, -} - -#[derive(Debug, PartialEq)] -pub enum GetNeighborError { - InvalidClient, - InvalidArea, -} - -#[derive(Debug, PartialEq)] -pub enum GetLeaderError { - InvalidClient, - InvalidArea, - NoClientInArea, -} - pub struct ClientLocation { lobbies: [Lobby; 15], rooms: [Option; MAX_ROOMS], diff --git a/src/ship/packet/builder/lobby.rs b/src/ship/packet/builder/lobby.rs index 29a1b8b..c595a6f 100644 --- a/src/ship/packet/builder/lobby.rs +++ b/src/ship/packet/builder/lobby.rs @@ -4,7 +4,7 @@ use crate::common::serverstate::ClientId; use crate::common::leveltable::CharacterLevelTable; use crate::ship::ship::{SendShipPacket, ShipError, ClientState, Clients}; use crate::ship::character::{CharacterBytesBuilder, FullCharacterBytesBuilder}; -use crate::ship::location::{ClientLocation, LobbyId, AreaClient}; +use crate::ship::location::{ClientLocation, LobbyId, AreaClient, ClientLocationError}; use crate::entity::character::CharacterEntity; use crate::ship::items::ActiveInventory; use crate::ship::packet::builder::{player_header, player_info}; @@ -18,7 +18,7 @@ pub fn join_lobby(id: ClientId, clients: &Clients, level_table: &CharacterLevelTable) -> Result { - let lobby_clients = client_location.get_clients_in_lobby(lobby).map_err(|err| ShipError::ClientError(format!("{:?}", err)))?; + let lobby_clients = client_location.get_clients_in_lobby(lobby).map_err(|err| -> ClientLocationError { err.into() })?; let playerinfo = lobby_clients.iter() .map(|area_client| { let client = clients.get(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client)).unwrap(); @@ -26,8 +26,8 @@ pub fn join_lobby(id: ClientId, }); let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); - 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 area_client = client_location.get_local_client(id).map_err(|err| -> ClientLocationError { err.into() })?; + let leader = client_location.get_lobby_leader(lobby).map_err(|err| -> ClientLocationError { err.into() })?; Ok(JoinLobby { client: area_client.local_client.id(), leader: leader.local_client.id(), @@ -47,8 +47,8 @@ pub fn add_to_lobby(id: ClientId, level_table: &CharacterLevelTable) -> Result { let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); - 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 area_client = client_location.get_local_client(id).map_err(|err| -> ClientLocationError { err.into() })?; + let leader = client_location.get_lobby_leader(lobby).map_err(|err| -> ClientLocationError { err.into() })?; Ok(AddToLobby { flag: 1, client: area_client.local_client.id(), diff --git a/src/ship/packet/builder/room.rs b/src/ship/packet/builder/room.rs index 26abdb3..ba45824 100644 --- a/src/ship/packet/builder/room.rs +++ b/src/ship/packet/builder/room.rs @@ -4,7 +4,7 @@ use crate::common::serverstate::ClientId; use crate::common::leveltable::CharacterLevelTable; use crate::ship::ship::{SendShipPacket, ShipError, ClientState, Clients}; use crate::ship::character::{CharacterBytesBuilder, FullCharacterBytesBuilder}; -use crate::ship::location::{ClientLocation, RoomId, AreaClient}; +use crate::ship::location::{ClientLocation, RoomId, AreaClient, ClientLocationError}; use crate::entity::character::CharacterEntity; use crate::ship::items::ActiveInventory; use crate::ship::room::RoomState; @@ -18,20 +18,20 @@ pub fn join_room(id: ClientId, room_id: RoomId, room: &RoomState) -> Result { - let all_clients = client_location.get_clients_in_room(room_id).map_err(|err| ShipError::ClientError(format!("{:?}", err)))?; + let all_clients = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?; let players = all_clients.iter() .enumerate() - .fold(Ok([PlayerHeader::default(); 4]), |acc, (i, c)| { + .fold(Ok([PlayerHeader::default(); 4]), |acc, (i, c)| -> Result<_, ShipError> { let header_client = clients.get(&c.client).ok_or(ShipError::ClientNotFound(id))?; - let header_area_client = client_location.get_local_client(id).map_err(|err| ShipError::ClientError(format!("{:?}", err)))?; + let header_area_client = client_location.get_local_client(id).map_err(|err| -> ClientLocationError { err.into() })?; acc.map(|mut a| { a[i] = player_header(0x10000, &header_client, &header_area_client); a }) })?; - let area_client = client_location.get_local_client(id).map_err(|err| ShipError::ClientError(format!("{:?}", err)))?; - let leader = client_location.get_room_leader(room_id).map_err(|err| ShipError::ClientError(format!("{:?}", err)))?; + let area_client = client_location.get_local_client(id).map_err(|err| -> ClientLocationError { err.into() })?; + let leader = client_location.get_room_leader(room_id).map_err(|err| -> ClientLocationError { err.into() })?; Ok(JoinRoom { flag: all_clients.len() as u32, maps: room.maps.map_headers(), diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index ff82422..11503a6 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -4,7 +4,7 @@ use crate::common::serverstate::ClientId; use crate::common::leveltable::CharacterLevelTable; use crate::ship::ship::{SendShipPacket, ShipError, ClientState, Rooms, Clients}; use crate::ship::character::{CharacterBytesBuilder, FullCharacterBytesBuilder}; -use crate::ship::location::{ClientLocation, LobbyId, RoomId, RoomLobby, MAX_ROOMS}; +use crate::ship::location::{ClientLocation, LobbyId, RoomId, RoomLobby, MAX_ROOMS, ClientLocationError}; use crate::ship::packet::builder; use libpso::character::character; use crate::ship::room; @@ -69,12 +69,12 @@ pub fn join_room(id: ClientId, return Ok(Box::new(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("player is bursting\nplease wait".into())))].into_iter())) } let room_id = RoomId(pkt.item as usize); - let original_room_clients = client_location.get_clients_in_room(room_id).map_err(|err| ShipError::ClientError(format!("{:?}", err)))?; + let original_room_clients = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?; client_location.add_client_to_room(id, room_id).unwrap(); // TODO: show room full error or whatever let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?; - let area_client = client_location.get_local_client(id).map_err(|err| ShipError::ClientError(format!("{:?}", err)))?; - let leader = client_location.get_room_leader(room_id).map_err(|err| ShipError::ClientError(format!("{:?}", err)))?; + let area_client = client_location.get_local_client(id).map_err(|err| -> ClientLocationError { err.into() })?; + let leader = client_location.get_room_leader(room_id).map_err(|err| -> ClientLocationError { err.into() })?; let join_room = builder::room::join_room(id, clients, client_location, room_id, &room)?; let add_to = builder::room::add_to_room(id, &client, &area_client, &leader, level_table, room_id)?; diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 595dc64..8936afd 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use log::warn; use rand::Rng; +use thiserror::Error; use libpso::packet::ship::*; use libpso::packet::login::{Login, LoginResponse, AccountStatus, Session}; @@ -20,7 +21,7 @@ use crate::entity::gateway::EntityGateway; use crate::entity::account::{UserAccountEntity, UserSettingsEntity, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; use crate::entity::character::CharacterEntity; use crate::entity::item::{ItemLocation, ItemEntity}; -use crate::ship::location::{ClientLocation, LobbyId, RoomId, RoomLobby, MAX_ROOMS}; +use crate::ship::location::{ClientLocation, LobbyId, RoomId, RoomLobby, MAX_ROOMS, ClientLocationError}; use crate::ship::character::{CharacterBytesBuilder, FullCharacterBytesBuilder}; use crate::ship::items; use crate::ship::room; @@ -30,13 +31,14 @@ pub const SHIP_PORT: u16 = 23423; pub type Rooms = [Option; MAX_ROOMS]; pub type Clients = HashMap; -#[derive(Debug)] +#[derive(Error, Debug)] +#[error("")] pub enum ShipError { ClientNotFound(ClientId), NoCharacterInSlot(ClientId, u32), InvalidSlot(ClientId, u32), TooManyClients, - ClientError(String), + ClientLocationError(#[from] ClientLocationError), InvalidRoom(u32), }