From f11ee7f53f42fad4eeba3692e9415706fb1337d6 Mon Sep 17 00:00:00 2001 From: Andy Newjack Date: Tue, 17 Mar 2020 08:02:17 -0300 Subject: [PATCH 1/5] wip. initial room list stuff --- src/ship/room.rs | 18 ++++++++++++++---- src/ship/ship.rs | 41 +++++++++++++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/ship/room.rs b/src/ship/room.rs index 825aec6..aa43382 100644 --- a/src/ship/room.rs +++ b/src/ship/room.rs @@ -97,7 +97,7 @@ pub enum RoomMode { impl RoomMode { - fn difficulty(&self) -> Difficulty { + pub fn difficulty(&self) -> Difficulty { match self { RoomMode::Single {difficulty, ..} => *difficulty, RoomMode::Multi {difficulty, ..} => *difficulty, @@ -106,7 +106,7 @@ impl RoomMode { } } - fn episode(&self) -> Episode { + pub fn episode(&self) -> Episode { match self { RoomMode::Single {episode, ..} => *episode, RoomMode::Multi {episode, ..} => *episode, @@ -114,19 +114,28 @@ impl RoomMode { RoomMode::Challenge {episode, ..} => *episode, } } + + pub fn get_flags(&self) -> u8 { + match self { + RoomMode::Battle {..} => 0x10, + RoomMode::Challenge {..} => 0x20, + _ => 0x0, + } + } } #[derive(Debug)] pub struct RoomState { - mode: RoomMode, + pub mode: RoomMode, pub name: String, - password: [u16; 16], + pub password: [u16; 16], //pub maps: [u32; 0x20], pub maps: Maps, // drop_table // items on ground // enemy info + pub players: u8, } impl RoomState { @@ -172,6 +181,7 @@ impl RoomState { password: create_room.password, //maps: [0; 0x20], maps: Maps::new(ep), + players: 1, }) } diff --git a/src/ship/ship.rs b/src/ship/ship.rs index ced4ba0..fa09c3b 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -46,6 +46,7 @@ pub enum RecvShipPacket { UpdateConfig(UpdateConfig), ViewInfoboardRequest(ViewInfoboardRequest), WriteInfoboard(WriteInfoboard), + RoomListRequest(RoomListRequest), } impl RecvServerPacket for RecvShipPacket { @@ -62,6 +63,7 @@ impl RecvServerPacket for RecvShipPacket { 0x7ED => Ok(RecvShipPacket::UpdateConfig(UpdateConfig::from_bytes(data)?)), 0xD8 => Ok(RecvShipPacket::ViewInfoboardRequest(ViewInfoboardRequest::from_bytes(data)?)), 0xD9 => Ok(RecvShipPacket::WriteInfoboard(WriteInfoboard::from_bytes(data)?)), + 0x08 => Ok(RecvShipPacket::RoomListRequest(RoomListRequest::from_bytes(data)?)), _ => Err(PacketParseError::WrongPacketForServerType(u16::from_le_bytes([data[2], data[3]]), data.to_vec())) } } @@ -86,6 +88,7 @@ pub enum SendShipPacket { LeaveRoom(LeaveRoom), RoomNameResponse(RoomNameResponse), ViewInfoboardResponse(ViewInfoboardResponse), + RoomListResponse(RoomListResponse), } impl SendServerPacket for SendShipPacket { @@ -108,11 +111,11 @@ impl SendServerPacket for SendShipPacket { SendShipPacket::LeaveRoom(pkt) => pkt.as_bytes(), SendShipPacket::RoomNameResponse(pkt) => pkt.as_bytes(), SendShipPacket::ViewInfoboardResponse(pkt) => pkt.as_bytes(), + SendShipPacket::RoomListResponse(pkt) => pkt.as_bytes(), } } } - struct ClientState { user: UserAccount, settings: UserSettings, @@ -137,12 +140,6 @@ impl ClientState { } } - - - - - - pub struct ShipServerState { entity_gateway: EG, clients: HashMap, @@ -439,8 +436,32 @@ impl ShipServerState { self.entity_gateway.set_character(&client.character); Box::new(None.into_iter()) } -} + fn request_room_list(&mut self, id: ClientId, request_roomlist: &RoomListRequest) -> Box + Send> { + let active_room_list = self.rooms.iter() + .enumerate() + .filter_map(|(i, r)| { + r.as_ref().map(|room| { + RoomList { + menu_id: 1, + item_id: i as u32, + difficulty: 0x22,//room.mode.difficulty().into(), + players: room.players, + name: libpso::utf8_to_utf16_array!(room.name, 16), + episode: 0x40,//room.mode.episode().into(), + flags: room.mode.get_flags(), + } + }) + }); + Box::new(vec![(id, SendShipPacket::RoomListResponse(RoomListResponse { + menu_id: 1, + title_id: 1, + zero: 0, + menu_title: libpso::utf8_to_utf16_array!("base_room", 17), + room_list: active_room_list.collect() + }))].into_iter()) + } +} impl ServerState for ShipServerState { type SendPacket = SendShipPacket; @@ -503,6 +524,10 @@ impl ServerState for ShipServerState { RecvShipPacket::WriteInfoboard(pkt) => { self.write_infoboard(id, pkt) }, + + RecvShipPacket::RoomListRequest(pkt) => { + self.request_room_list(id, pkt) + }, }) } From 7f95f7e7934f95e30572c9f9be8511722dcf85c8 Mon Sep 17 00:00:00 2001 From: Andy Newjack Date: Wed, 18 Mar 2020 01:36:46 -0300 Subject: [PATCH 2/5] room list req/resp functions --- src/ship/room.rs | 49 ++++++++++++++++++++++++++++++++++++------------ src/ship/ship.rs | 23 ++++++++++++++--------- 2 files changed, 51 insertions(+), 21 deletions(-) diff --git a/src/ship/room.rs b/src/ship/room.rs index aa43382..e40d0fc 100644 --- a/src/ship/room.rs +++ b/src/ship/room.rs @@ -76,7 +76,7 @@ impl Into for Difficulty { } } -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub enum RoomMode { Single { episode: Episode, @@ -114,14 +114,6 @@ impl RoomMode { RoomMode::Challenge {episode, ..} => *episode, } } - - pub fn get_flags(&self) -> u8 { - match self { - RoomMode::Battle {..} => 0x10, - RoomMode::Challenge {..} => 0x20, - _ => 0x0, - } - } } @@ -135,7 +127,10 @@ pub struct RoomState { // drop_table // items on ground // enemy info + pub difficulty: u8, pub players: u8, + pub episode: u8, + pub flags: u8, } impl RoomState { @@ -145,6 +140,34 @@ impl RoomState { } }*/ + pub fn get_flags(mode: &RoomMode, password: [u16; 16]) -> u8 { + let mut flags = 0u8; + + match mode { + RoomMode::Single {..} => {flags += 0x04} + RoomMode::Battle {..} => {flags += 0x10}, + RoomMode::Challenge {..} => {flags += 0x20}, + _ => {flags += 0x40}, + }; + + if password[0] > 0 { + flags += 0x02; + } + flags + } + + pub fn get_episode(mode: &RoomMode) -> u8 { + let mut episode = 0u8; + + episode = mode.episode().into(); + + match mode { + RoomMode::Single {..} => {episode += 0x10}, + _ => {episode += 0x40}, + } + episode + } + pub fn from_create_room(create_room: &libpso::packet::ship::CreateRoom) -> Result { if [create_room.battle, create_room.challenge, create_room.single_player].iter().sum::() > 1 { return Err(RoomCreationError::InvalidMode) @@ -174,14 +197,16 @@ impl RoomState { } }; - let ep = room_mode.episode(); Ok(RoomState { mode: room_mode, name: String::from_utf16_lossy(&create_room.name).trim_matches(char::from(0)).into(), password: create_room.password, //maps: [0; 0x20], - maps: Maps::new(ep), - players: 1, + maps: Maps::new(room_mode.episode()), + difficulty: create_room.difficulty + 0x22, + players: 0, + episode: RoomState::get_episode(&room_mode), + flags: RoomState::get_flags(&room_mode, create_room.password), }) } diff --git a/src/ship/ship.rs b/src/ship/ship.rs index fa09c3b..99313f4 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -9,6 +9,7 @@ use libpso::packet::messages::*; use libpso::{PacketParseError, PSOPacket}; use libpso::crypto::bb::PSOBBCipher; use libpso::character::character; +use libpso::packet::ship::{ROOM_MENU_ID}; use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; @@ -443,22 +444,26 @@ impl ShipServerState { .filter_map(|(i, r)| { r.as_ref().map(|room| { RoomList { - menu_id: 1, + menu_id: ROOM_MENU_ID, item_id: i as u32, - difficulty: 0x22,//room.mode.difficulty().into(), + difficulty: room.difficulty, players: room.players, name: libpso::utf8_to_utf16_array!(room.name, 16), - episode: 0x40,//room.mode.episode().into(), - flags: room.mode.get_flags(), + episode: room.episode, + flags: room.flags, } }) }); + let baseroom: BaseRoom = BaseRoom { + menu_id: ROOM_MENU_ID, + title_id: ROOM_MENU_ID, + zero: 0x0000, + menu_title: libpso::utf8_to_utf16_array!("Room list menu", 17), + }; + Box::new(vec![(id, SendShipPacket::RoomListResponse(RoomListResponse { - menu_id: 1, - title_id: 1, - zero: 0, - menu_title: libpso::utf8_to_utf16_array!("base_room", 17), - room_list: active_room_list.collect() + baseroom, + rooms: active_room_list.collect() }))].into_iter()) } } From eef2178df8aafd877f31105d6e37313f9f0d316d Mon Sep 17 00:00:00 2001 From: andy Date: Wed, 18 Mar 2020 21:46:13 -0300 Subject: [PATCH 3/5] cleanup and fix errors. still need to get room player counts --- src/ship/room.rs | 28 +++++++++++++--------------- src/ship/ship.rs | 25 ++++++++++++++----------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/ship/room.rs b/src/ship/room.rs index e40d0fc..9bf4338 100644 --- a/src/ship/room.rs +++ b/src/ship/room.rs @@ -140,32 +140,34 @@ impl RoomState { } }*/ - pub fn get_flags(mode: &RoomMode, password: [u16; 16]) -> u8 { + pub fn get_flags_for_room_list(&self) -> u8 { let mut flags = 0u8; - match mode { + match self.mode { RoomMode::Single {..} => {flags += 0x04} RoomMode::Battle {..} => {flags += 0x10}, RoomMode::Challenge {..} => {flags += 0x20}, _ => {flags += 0x40}, }; - if password[0] > 0 { + if self.password[0] > 0 { flags += 0x02; } flags } - pub fn get_episode(mode: &RoomMode) -> u8 { - let mut episode = 0u8; + pub fn get_episode_for_room_list(&self) -> u8 { + let episode: u8 = self.mode.episode().into(); - episode = mode.episode().into(); - - match mode { - RoomMode::Single {..} => {episode += 0x10}, - _ => {episode += 0x40}, + match self.mode { + RoomMode::Single {..} => episode + 0x10, + _ => episode + 0x40, } - episode + } + + pub fn get_difficulty_for_room_list(&self) -> u8 { + let difficulty: u8 = self.mode.difficulty().into(); + difficulty + 0x22 } pub fn from_create_room(create_room: &libpso::packet::ship::CreateRoom) -> Result { @@ -203,10 +205,6 @@ impl RoomState { password: create_room.password, //maps: [0; 0x20], maps: Maps::new(room_mode.episode()), - difficulty: create_room.difficulty + 0x22, - players: 0, - episode: RoomState::get_episode(&room_mode), - flags: RoomState::get_flags(&room_mode, create_room.password), }) } diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 99313f4..ae12b84 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -438,7 +438,7 @@ impl ShipServerState { Box::new(None.into_iter()) } - fn request_room_list(&mut self, id: ClientId, request_roomlist: &RoomListRequest) -> Box + Send> { + fn request_room_list(&mut self, id: ClientId) -> Box + Send> { let active_room_list = self.rooms.iter() .enumerate() .filter_map(|(i, r)| { @@ -446,19 +446,22 @@ impl ShipServerState { RoomList { menu_id: ROOM_MENU_ID, item_id: i as u32, - difficulty: room.difficulty, - players: room.players, + difficulty: room.get_difficulty_for_room_list(), + players: 0, // TODO name: libpso::utf8_to_utf16_array!(room.name, 16), - episode: room.episode, - flags: room.flags, + episode: room.get_episode_for_room_list(), + flags: room.get_flags_for_room_list(), } }) }); - let baseroom: BaseRoom = BaseRoom { + let baseroom: RoomList = RoomList { menu_id: ROOM_MENU_ID, - title_id: ROOM_MENU_ID, - zero: 0x0000, - menu_title: libpso::utf8_to_utf16_array!("Room list menu", 17), + item_id: ROOM_MENU_ID, + difficulty: 0x00, + players: 0x00, + name: libpso::utf8_to_utf16_array!("Room list menu", 16), + episode: 0, + flags: 0, }; Box::new(vec![(id, SendShipPacket::RoomListResponse(RoomListResponse { @@ -530,8 +533,8 @@ impl ServerState for ShipServerState { self.write_infoboard(id, pkt) }, - RecvShipPacket::RoomListRequest(pkt) => { - self.request_room_list(id, pkt) + RecvShipPacket::RoomListRequest(_req) => { + self.request_room_list(id) }, }) } From 38b0cac09b65803591f3b28405a9e64665300ef8 Mon Sep 17 00:00:00 2001 From: Andy Newjack Date: Thu, 19 Mar 2020 23:03:21 -0300 Subject: [PATCH 4/5] get player counts for room lists --- src/ship/location.rs | 10 ++++++++++ src/ship/room.rs | 4 ---- src/ship/ship.rs | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/ship/location.rs b/src/ship/location.rs index 04b78fa..7aa5541 100644 --- a/src/ship/location.rs +++ b/src/ship/location.rs @@ -292,4 +292,14 @@ impl ClientLocation { .map(|lobby| lobby.write().unwrap().remove(id)) .any(|k| k); } + + pub fn get_clients_in_room(&self, room_id: RoomId) -> u8 { + self.rooms[room_id.0].as_ref() + .unwrap() + .read() + .unwrap() + .clients() + .filter(|k| k.is_some()) + .count() as u8 + } } diff --git a/src/ship/room.rs b/src/ship/room.rs index 9bf4338..08e49ad 100644 --- a/src/ship/room.rs +++ b/src/ship/room.rs @@ -127,10 +127,6 @@ pub struct RoomState { // drop_table // items on ground // enemy info - pub difficulty: u8, - pub players: u8, - pub episode: u8, - pub flags: u8, } impl RoomState { diff --git a/src/ship/ship.rs b/src/ship/ship.rs index ae12b84..e3f9649 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -447,7 +447,7 @@ impl ShipServerState { menu_id: ROOM_MENU_ID, item_id: i as u32, difficulty: room.get_difficulty_for_room_list(), - players: 0, // TODO + players: self.client_location.get_clients_in_room(RoomId(i)), // TODO name: libpso::utf8_to_utf16_array!(room.name, 16), episode: room.get_episode_for_room_list(), flags: room.get_flags_for_room_list(), From 648fdfc0ecfedc9e4ca2206abb12a0b75e9a487f Mon Sep 17 00:00:00 2001 From: Andy Newjack Date: Sat, 21 Mar 2020 13:41:01 -0300 Subject: [PATCH 5/5] rename function --- src/ship/location.rs | 2 +- src/ship/ship.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ship/location.rs b/src/ship/location.rs index 7aa5541..666b797 100644 --- a/src/ship/location.rs +++ b/src/ship/location.rs @@ -293,7 +293,7 @@ impl ClientLocation { .any(|k| k); } - pub fn get_clients_in_room(&self, room_id: RoomId) -> u8 { + pub fn get_client_count_in_room(&self, room_id: RoomId) -> u8 { self.rooms[room_id.0].as_ref() .unwrap() .read() diff --git a/src/ship/ship.rs b/src/ship/ship.rs index e3f9649..89c73fb 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -447,7 +447,7 @@ impl ShipServerState { menu_id: ROOM_MENU_ID, item_id: i as u32, difficulty: room.get_difficulty_for_room_list(), - players: self.client_location.get_clients_in_room(RoomId(i)), // TODO + players: self.client_location.get_client_count_in_room(RoomId(i)), // TODO name: libpso::utf8_to_utf16_array!(room.name, 16), episode: room.get_episode_for_room_list(), flags: room.get_flags_for_room_list(),