Browse Source

transfer ship

pbs
jake 4 years ago
parent
commit
ffce662c95
  1. 15
      src/login/character.rs
  2. 1
      src/ship/packet/builder/mod.rs
  3. 29
      src/ship/packet/builder/ship.rs
  4. 1
      src/ship/packet/handler/mod.rs
  5. 23
      src/ship/packet/handler/ship.rs
  6. 24
      src/ship/ship.rs

15
src/login/character.rs

@ -32,7 +32,7 @@ use crate::login::login::{get_login_status, check_if_already_online};
use crate::common::interserver::AuthToken; use crate::common::interserver::AuthToken;
pub const CHARACTER_PORT: u16 = 12001; pub const CHARACTER_PORT: u16 = 12001;
const SHIP_MENU_ID: u32 = 1;
pub const SHIP_MENU_ID: u32 = 1;
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
#[error("")] #[error("")]
@ -173,7 +173,7 @@ impl ClientState {
} }
} }
#[derive(Clone)]
#[derive(Debug, Clone)]
struct ConnectedClient { struct ConnectedClient {
ship_id: Option<ServerId>, ship_id: Option<ServerId>,
expires: Option<chrono::DateTime<chrono::Utc>>, expires: Option<chrono::DateTime<chrono::Utc>>,
@ -591,7 +591,7 @@ impl<EG: EntityGateway> ServerState for CharacterServerState<EG> {
Box::new(self.character_preview(id, preview).await?.into_iter().map(move |pkt| (id, pkt))) Box::new(self.character_preview(id, preview).await?.into_iter().map(move |pkt| (id, pkt)))
}, },
RecvCharacterPacket::MenuSelect(menuselect) => { RecvCharacterPacket::MenuSelect(menuselect) => {
Box::new(self.select_ship(menuselect)?.into_iter().map(move |pkt| (id, pkt)))
Box::new(self.select_ship(id, menuselect)?.into_iter().map(move |pkt| (id, pkt)))
}, },
RecvCharacterPacket::MenuDetail(menudetail) => { RecvCharacterPacket::MenuDetail(menudetail) => {
match menudetail.menu { match menudetail.menu {
@ -635,7 +635,14 @@ impl<EG: EntityGateway> InterserverActor for CharacterServerState<EG> {
if self.authenticated_ships.contains(&id) { if self.authenticated_ships.contains(&id) {
self.ships.insert(id, new_ship); self.ships.insert(id, new_ship);
} }
Ok(Vec::new())
let ships = self.ships.iter().map(|(_, s)| s).cloned().collect::<Vec<_>>();
Ok(self.ships
.iter()
.map(|(id, _)| {
(*id, LoginMessage::ShipList{ ships: ships.clone() })
})
.collect())
}, },
ShipMessage::AddUser(new_user) => { ShipMessage::AddUser(new_user) => {
if self.authenticated_ships.contains(&id) { if self.authenticated_ships.contains(&id) {

1
src/ship/packet/builder/mod.rs

@ -2,6 +2,7 @@ pub mod lobby;
pub mod message; pub mod message;
pub mod room; pub mod room;
pub mod quest; pub mod quest;
pub mod ship;
use libpso::character::character::Inventory; use libpso::character::character::Inventory;
use libpso::packet::ship::{PlayerHeader, PlayerInfo}; use libpso::packet::ship::{PlayerHeader, PlayerInfo};

29
src/ship/packet/builder/ship.rs

@ -0,0 +1,29 @@
use libpso::packet::login::{ShipList, ShipListEntry};
use libpso::packet::ship::*;
use crate::common::serverstate::ClientId;
use crate::common::leveltable::CharacterLevelTable;
use crate::ship::ship::{ShipError, ClientState, Clients};
use crate::ship::location::{ClientLocation, RoomId, AreaClient, ClientLocationError};
use crate::ship::room::RoomState;
use crate::ship::items::ItemManager;
use crate::ship::packet::builder::{player_header, player_info};
use libpso::utf8_to_utf16_array;
use crate::common::interserver::Ship;
use libpso::packet::ship::BLOCK_MENU_ID;
use crate::login::character::SHIP_MENU_ID;
pub fn ship_list(ships: &Vec<Ship>) -> ShipList {
let ships = ships.iter()
.enumerate()
.map(|(i, ship)| {
ShipListEntry {
menu: SHIP_MENU_ID,
item: i as u32,
flags: 0,
name: utf8_to_utf16_array!(ship.name, 0x11)
}
})
.collect();
ShipList::new(ships)
}

1
src/ship/packet/handler/mod.rs

@ -6,3 +6,4 @@ pub mod message;
pub mod room; pub mod room;
pub mod settings; pub mod settings;
pub mod quest; pub mod quest;
pub mod ship;

23
src/ship/packet/handler/ship.rs

@ -0,0 +1,23 @@
use libpso::packet::ship::*;
use libpso::packet::login::RedirectClient;
use crate::common::serverstate::ClientId;
use crate::common::interserver::Ship;
use crate::ship::ship::{SendShipPacket, ShipError, Clients};
use crate::ship::packet::builder;
pub fn ship_list(id: ClientId, ship_list: &Vec<Ship>)
-> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> {
Box::new(vec![(id, SendShipPacket::ShipList(builder::ship::ship_list(ship_list)))].into_iter())
}
pub fn block_list(id: ClientId, shipname: &str, num_blocks: usize)
-> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> {
Box::new(vec![(id, SendShipPacket::ShipBlockList(ShipBlockList::new(shipname, num_blocks)))].into_iter())
}
pub fn selected_ship(id: ClientId, menuselect: &MenuSelect, ship_list: &Vec<Ship>)
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> {
let ship = ship_list.get(menuselect.item as usize).ok_or(ShipError::InvalidShip(menuselect.item as usize))?;
let ip = u32::from_ne_bytes(ship.ip.octets());
Ok(Box::new(vec![(id, SendShipPacket::RedirectClient(RedirectClient::new(ip, ship.port)))].into_iter()))
}

24
src/ship/ship.rs

@ -6,7 +6,7 @@ use rand::Rng;
use thiserror::Error; use thiserror::Error;
use libpso::packet::ship::*; use libpso::packet::ship::*;
use libpso::packet::login::{Login, LoginResponse, Session};
use libpso::packet::login::{RedirectClient, Login, LoginResponse, Session, ShipList};
use libpso::packet::messages::*; use libpso::packet::messages::*;
use libpso::{PacketParseError, PSOPacket}; use libpso::{PacketParseError, PSOPacket};
use libpso::crypto::bb::PSOBBCipher; use libpso::crypto::bb::PSOBBCipher;
@ -18,6 +18,8 @@ use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState
use crate::common::leveltable::CharacterLevelTable; use crate::common::leveltable::CharacterLevelTable;
use crate::common::interserver::{AuthToken, Ship, ServerId, InterserverActor, LoginMessage, ShipMessage}; use crate::common::interserver::{AuthToken, Ship, ServerId, InterserverActor, LoginMessage, ShipMessage};
use crate::login::character::SHIP_MENU_ID;
use crate::entity::gateway::{EntityGateway, GatewayError}; use crate::entity::gateway::{EntityGateway, GatewayError};
use crate::entity::account::{UserAccountEntity, UserSettingsEntity}; use crate::entity::account::{UserAccountEntity, UserSettingsEntity};
use crate::entity::character::{CharacterEntity, SectionID}; use crate::entity::character::{CharacterEntity, SectionID};
@ -67,6 +69,7 @@ pub enum ShipError {
ShopError, ShopError,
GatewayError(#[from] GatewayError), GatewayError(#[from] GatewayError),
UnknownMonster(crate::ship::monster::MonsterType), UnknownMonster(crate::ship::monster::MonsterType),
InvalidShip(usize),
} }
#[derive(Debug)] #[derive(Debug)]
@ -98,6 +101,8 @@ pub enum RecvShipPacket {
DoneLoadingQuest(DoneLoadingQuest), DoneLoadingQuest(DoneLoadingQuest),
FullCharacterData(Box<FullCharacterData>), FullCharacterData(Box<FullCharacterData>),
SaveOptions(SaveOptions), SaveOptions(SaveOptions),
RequestShipList(RequestShipList),
RequestShipBlockList(RequestShipBlockList),
} }
impl RecvServerPacket for RecvShipPacket { impl RecvServerPacket for RecvShipPacket {
@ -131,6 +136,8 @@ impl RecvServerPacket for RecvShipPacket {
0x6F => Ok(RecvShipPacket::DoneBursting(DoneBursting::from_bytes(data)?)), 0x6F => Ok(RecvShipPacket::DoneBursting(DoneBursting::from_bytes(data)?)),
0x16F => Ok(RecvShipPacket::DoneBursting2(DoneBursting2::from_bytes(data)?)), 0x16F => Ok(RecvShipPacket::DoneBursting2(DoneBursting2::from_bytes(data)?)),
0x84 => Ok(RecvShipPacket::LobbySelect(LobbySelect::from_bytes(data)?)), 0x84 => Ok(RecvShipPacket::LobbySelect(LobbySelect::from_bytes(data)?)),
0xA0 => Ok(RecvShipPacket::RequestShipList(RequestShipList::from_bytes(data)?)),
0xA1 => Ok(RecvShipPacket::RequestShipBlockList(RequestShipBlockList::from_bytes(data)?)),
0xA2 => Ok(RecvShipPacket::RequestQuestList(RequestQuestList::from_bytes(data)?)), 0xA2 => Ok(RecvShipPacket::RequestQuestList(RequestQuestList::from_bytes(data)?)),
0xAC => Ok(RecvShipPacket::DoneLoadingQuest(DoneLoadingQuest::from_bytes(data)?)), 0xAC => Ok(RecvShipPacket::DoneLoadingQuest(DoneLoadingQuest::from_bytes(data)?)),
0xE7 => Ok(RecvShipPacket::FullCharacterData(Box::new(FullCharacterData::from_bytes(data)?))), 0xE7 => Ok(RecvShipPacket::FullCharacterData(Box::new(FullCharacterData::from_bytes(data)?))),
@ -144,6 +151,7 @@ impl RecvServerPacket for RecvShipPacket {
pub enum SendShipPacket { pub enum SendShipPacket {
ShipWelcome(ShipWelcome), ShipWelcome(ShipWelcome),
LoginResponse(LoginResponse), LoginResponse(LoginResponse),
ShipList(ShipList),
ShipBlockList(ShipBlockList), ShipBlockList(ShipBlockList),
FullCharacter(Box<FullCharacter>), FullCharacter(Box<FullCharacter>),
CharDataRequest(CharDataRequest), CharDataRequest(CharDataRequest),
@ -172,6 +180,7 @@ pub enum SendShipPacket {
QuestChunk(QuestChunk), QuestChunk(QuestChunk),
DoneLoadingQuest(DoneLoadingQuest), DoneLoadingQuest(DoneLoadingQuest),
BankItemList(BankItemList), BankItemList(BankItemList),
RedirectClient(RedirectClient),
} }
impl SendServerPacket for SendShipPacket { impl SendServerPacket for SendShipPacket {
@ -179,6 +188,7 @@ impl SendServerPacket for SendShipPacket {
match self { match self {
SendShipPacket::ShipWelcome(pkt) => pkt.as_bytes(), SendShipPacket::ShipWelcome(pkt) => pkt.as_bytes(),
SendShipPacket::LoginResponse(pkt) => pkt.as_bytes(), SendShipPacket::LoginResponse(pkt) => pkt.as_bytes(),
SendShipPacket::ShipList(pkt) => pkt.as_bytes(),
SendShipPacket::ShipBlockList(pkt) => pkt.as_bytes(), SendShipPacket::ShipBlockList(pkt) => pkt.as_bytes(),
SendShipPacket::FullCharacter(pkt) => pkt.as_bytes(), SendShipPacket::FullCharacter(pkt) => pkt.as_bytes(),
SendShipPacket::CharDataRequest(pkt) => pkt.as_bytes(), SendShipPacket::CharDataRequest(pkt) => pkt.as_bytes(),
@ -207,6 +217,7 @@ impl SendServerPacket for SendShipPacket {
SendShipPacket::QuestChunk(pkt) => pkt.as_bytes(), SendShipPacket::QuestChunk(pkt) => pkt.as_bytes(),
SendShipPacket::DoneLoadingQuest(pkt) => pkt.as_bytes(), SendShipPacket::DoneLoadingQuest(pkt) => pkt.as_bytes(),
SendShipPacket::BankItemList(pkt) => pkt.as_bytes(), SendShipPacket::BankItemList(pkt) => pkt.as_bytes(),
SendShipPacket::RedirectClient(pkt) => pkt.as_bytes(),
} }
} }
} }
@ -508,6 +519,7 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> {
}, },
RecvShipPacket::MenuSelect(menuselect) => { RecvShipPacket::MenuSelect(menuselect) => {
match menuselect.menu { match menuselect.menu {
SHIP_MENU_ID => handler::ship::selected_ship(id, menuselect, &self.ship_list)?,
BLOCK_MENU_ID => Box::new(handler::lobby::block_selected(id, menuselect, &mut self.clients, &self.item_manager, &self.level_table)?.into_iter().map(move |pkt| (id, pkt))), BLOCK_MENU_ID => Box::new(handler::lobby::block_selected(id, menuselect, &mut self.clients, &self.item_manager, &self.level_table)?.into_iter().map(move |pkt| (id, pkt))),
ROOM_MENU_ID => handler::room::join_room(id, menuselect, &mut self.client_location, &mut self.clients, &mut self.item_manager, &self.level_table, &mut self.rooms)?, ROOM_MENU_ID => handler::room::join_room(id, menuselect, &mut self.client_location, &mut self.clients, &mut self.item_manager, &self.level_table, &mut self.rooms)?,
QUEST_CATEGORY_MENU_ID => handler::quest::select_quest_category(id, menuselect, &self.quests)?, QUEST_CATEGORY_MENU_ID => handler::quest::select_quest_category(id, menuselect, &self.quests)?,
@ -599,6 +611,12 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> {
RecvShipPacket::SaveOptions(save_options) => { RecvShipPacket::SaveOptions(save_options) => {
handler::settings::save_options(id, save_options, &mut self.clients, &mut self.entity_gateway).await handler::settings::save_options(id, save_options, &mut self.clients, &mut self.entity_gateway).await
}, },
RecvShipPacket::RequestShipList(_) => {
handler::ship::ship_list(id, &self.ship_list)
},
RecvShipPacket::RequestShipBlockList(_) => {
handler::ship::block_list(id, &self.name, 1)
}
}) })
} }
@ -654,7 +672,9 @@ impl<EG: EntityGateway> InterserverActor for ShipServerState<EG> {
ip: self.ip.clone(), ip: self.ip.clone(),
port: self.port, port: self.port,
block_count: 2, block_count: 2,
})) ]
})),
(id, ShipMessage::RequestShipList)
]
} }
async fn action(&mut self, id: ServerId, msg: Self::RecvMessage) -> Result<Vec<(ServerId, Self::SendMessage)>, Self::Error> { async fn action(&mut self, id: ServerId, msg: Self::RecvMessage) -> Result<Vec<(ServerId, Self::SendMessage)>, Self::Error> {

Loading…
Cancel
Save