Merge pull request 'room_lists' (#88) from room_lists into master
Reviewed-by: jake <jake@sharnoth.com>
This commit is contained in:
commit
ee82f920b6
@ -292,4 +292,14 @@ impl ClientLocation {
|
|||||||
.map(|lobby| lobby.write().unwrap().remove(id))
|
.map(|lobby| lobby.write().unwrap().remove(id))
|
||||||
.any(|k| k);
|
.any(|k| k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_client_count_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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ impl Into<u8> for Difficulty {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub enum RoomMode {
|
pub enum RoomMode {
|
||||||
Single {
|
Single {
|
||||||
episode: Episode,
|
episode: Episode,
|
||||||
@ -97,7 +97,7 @@ pub enum RoomMode {
|
|||||||
|
|
||||||
|
|
||||||
impl RoomMode {
|
impl RoomMode {
|
||||||
fn difficulty(&self) -> Difficulty {
|
pub fn difficulty(&self) -> Difficulty {
|
||||||
match self {
|
match self {
|
||||||
RoomMode::Single {difficulty, ..} => *difficulty,
|
RoomMode::Single {difficulty, ..} => *difficulty,
|
||||||
RoomMode::Multi {difficulty, ..} => *difficulty,
|
RoomMode::Multi {difficulty, ..} => *difficulty,
|
||||||
@ -106,7 +106,7 @@ impl RoomMode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn episode(&self) -> Episode {
|
pub fn episode(&self) -> Episode {
|
||||||
match self {
|
match self {
|
||||||
RoomMode::Single {episode, ..} => *episode,
|
RoomMode::Single {episode, ..} => *episode,
|
||||||
RoomMode::Multi {episode, ..} => *episode,
|
RoomMode::Multi {episode, ..} => *episode,
|
||||||
@ -119,9 +119,9 @@ impl RoomMode {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct RoomState {
|
pub struct RoomState {
|
||||||
mode: RoomMode,
|
pub mode: RoomMode,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
password: [u16; 16],
|
pub password: [u16; 16],
|
||||||
//pub maps: [u32; 0x20],
|
//pub maps: [u32; 0x20],
|
||||||
pub maps: Maps,
|
pub maps: Maps,
|
||||||
// drop_table
|
// drop_table
|
||||||
@ -136,6 +136,36 @@ impl RoomState {
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
pub fn get_flags_for_room_list(&self) -> u8 {
|
||||||
|
let mut flags = 0u8;
|
||||||
|
|
||||||
|
match self.mode {
|
||||||
|
RoomMode::Single {..} => {flags += 0x04}
|
||||||
|
RoomMode::Battle {..} => {flags += 0x10},
|
||||||
|
RoomMode::Challenge {..} => {flags += 0x20},
|
||||||
|
_ => {flags += 0x40},
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.password[0] > 0 {
|
||||||
|
flags += 0x02;
|
||||||
|
}
|
||||||
|
flags
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_episode_for_room_list(&self) -> u8 {
|
||||||
|
let episode: u8 = self.mode.episode().into();
|
||||||
|
|
||||||
|
match self.mode {
|
||||||
|
RoomMode::Single {..} => episode + 0x10,
|
||||||
|
_ => episode + 0x40,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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<RoomState, RoomCreationError> {
|
pub fn from_create_room(create_room: &libpso::packet::ship::CreateRoom) -> Result<RoomState, RoomCreationError> {
|
||||||
if [create_room.battle, create_room.challenge, create_room.single_player].iter().sum::<u8>() > 1 {
|
if [create_room.battle, create_room.challenge, create_room.single_player].iter().sum::<u8>() > 1 {
|
||||||
return Err(RoomCreationError::InvalidMode)
|
return Err(RoomCreationError::InvalidMode)
|
||||||
@ -165,13 +195,12 @@ impl RoomState {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let ep = room_mode.episode();
|
|
||||||
Ok(RoomState {
|
Ok(RoomState {
|
||||||
mode: room_mode,
|
mode: room_mode,
|
||||||
name: String::from_utf16_lossy(&create_room.name).trim_matches(char::from(0)).into(),
|
name: String::from_utf16_lossy(&create_room.name).trim_matches(char::from(0)).into(),
|
||||||
password: create_room.password,
|
password: create_room.password,
|
||||||
//maps: [0; 0x20],
|
//maps: [0; 0x20],
|
||||||
maps: Maps::new(ep),
|
maps: Maps::new(room_mode.episode()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ use libpso::packet::messages::*;
|
|||||||
use libpso::{PacketParseError, PSOPacket};
|
use libpso::{PacketParseError, PSOPacket};
|
||||||
use libpso::crypto::bb::PSOBBCipher;
|
use libpso::crypto::bb::PSOBBCipher;
|
||||||
use libpso::character::character;
|
use libpso::character::character;
|
||||||
|
use libpso::packet::ship::{ROOM_MENU_ID};
|
||||||
|
|
||||||
use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY};
|
use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY};
|
||||||
use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId};
|
use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId};
|
||||||
@ -46,6 +47,7 @@ pub enum RecvShipPacket {
|
|||||||
UpdateConfig(UpdateConfig),
|
UpdateConfig(UpdateConfig),
|
||||||
ViewInfoboardRequest(ViewInfoboardRequest),
|
ViewInfoboardRequest(ViewInfoboardRequest),
|
||||||
WriteInfoboard(WriteInfoboard),
|
WriteInfoboard(WriteInfoboard),
|
||||||
|
RoomListRequest(RoomListRequest),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RecvServerPacket for RecvShipPacket {
|
impl RecvServerPacket for RecvShipPacket {
|
||||||
@ -62,6 +64,7 @@ impl RecvServerPacket for RecvShipPacket {
|
|||||||
0x7ED => Ok(RecvShipPacket::UpdateConfig(UpdateConfig::from_bytes(data)?)),
|
0x7ED => Ok(RecvShipPacket::UpdateConfig(UpdateConfig::from_bytes(data)?)),
|
||||||
0xD8 => Ok(RecvShipPacket::ViewInfoboardRequest(ViewInfoboardRequest::from_bytes(data)?)),
|
0xD8 => Ok(RecvShipPacket::ViewInfoboardRequest(ViewInfoboardRequest::from_bytes(data)?)),
|
||||||
0xD9 => Ok(RecvShipPacket::WriteInfoboard(WriteInfoboard::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()))
|
_ => Err(PacketParseError::WrongPacketForServerType(u16::from_le_bytes([data[2], data[3]]), data.to_vec()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,6 +89,7 @@ pub enum SendShipPacket {
|
|||||||
LeaveRoom(LeaveRoom),
|
LeaveRoom(LeaveRoom),
|
||||||
RoomNameResponse(RoomNameResponse),
|
RoomNameResponse(RoomNameResponse),
|
||||||
ViewInfoboardResponse(ViewInfoboardResponse),
|
ViewInfoboardResponse(ViewInfoboardResponse),
|
||||||
|
RoomListResponse(RoomListResponse),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SendServerPacket for SendShipPacket {
|
impl SendServerPacket for SendShipPacket {
|
||||||
@ -108,11 +112,11 @@ impl SendServerPacket for SendShipPacket {
|
|||||||
SendShipPacket::LeaveRoom(pkt) => pkt.as_bytes(),
|
SendShipPacket::LeaveRoom(pkt) => pkt.as_bytes(),
|
||||||
SendShipPacket::RoomNameResponse(pkt) => pkt.as_bytes(),
|
SendShipPacket::RoomNameResponse(pkt) => pkt.as_bytes(),
|
||||||
SendShipPacket::ViewInfoboardResponse(pkt) => pkt.as_bytes(),
|
SendShipPacket::ViewInfoboardResponse(pkt) => pkt.as_bytes(),
|
||||||
|
SendShipPacket::RoomListResponse(pkt) => pkt.as_bytes(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct ClientState {
|
struct ClientState {
|
||||||
user: UserAccount,
|
user: UserAccount,
|
||||||
settings: UserSettings,
|
settings: UserSettings,
|
||||||
@ -137,12 +141,6 @@ impl ClientState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub struct ShipServerState<EG: EntityGateway> {
|
pub struct ShipServerState<EG: EntityGateway> {
|
||||||
entity_gateway: EG,
|
entity_gateway: EG,
|
||||||
clients: HashMap<ClientId, ClientState>,
|
clients: HashMap<ClientId, ClientState>,
|
||||||
@ -439,8 +437,39 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
|||||||
self.entity_gateway.set_character(&client.character);
|
self.entity_gateway.set_character(&client.character);
|
||||||
Box::new(None.into_iter())
|
Box::new(None.into_iter())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
fn request_room_list(&mut self, id: ClientId) -> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> {
|
||||||
|
let active_room_list = self.rooms.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(|(i, r)| {
|
||||||
|
r.as_ref().map(|room| {
|
||||||
|
RoomList {
|
||||||
|
menu_id: ROOM_MENU_ID,
|
||||||
|
item_id: i as u32,
|
||||||
|
difficulty: room.get_difficulty_for_room_list(),
|
||||||
|
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(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
let baseroom: RoomList = RoomList {
|
||||||
|
menu_id: ROOM_MENU_ID,
|
||||||
|
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 {
|
||||||
|
baseroom,
|
||||||
|
rooms: active_room_list.collect()
|
||||||
|
}))].into_iter())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<EG: EntityGateway> ServerState for ShipServerState<EG> {
|
impl<EG: EntityGateway> ServerState for ShipServerState<EG> {
|
||||||
type SendPacket = SendShipPacket;
|
type SendPacket = SendShipPacket;
|
||||||
@ -503,6 +532,10 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> {
|
|||||||
RecvShipPacket::WriteInfoboard(pkt) => {
|
RecvShipPacket::WriteInfoboard(pkt) => {
|
||||||
self.write_infoboard(id, pkt)
|
self.write_infoboard(id, pkt)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
RecvShipPacket::RoomListRequest(_req) => {
|
||||||
|
self.request_room_list(id)
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user