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;
pub const CHARACTER_PORT: u16 = 12001;
const SHIP_MENU_ID: u32 = 1;
pub const SHIP_MENU_ID: u32 = 1;
#[derive(thiserror::Error, Debug)]
#[error("")]
@ -173,7 +173,7 @@ impl ClientState {
}
}
#[derive(Clone)]
#[derive(Debug, Clone)]
struct ConnectedClient {
ship_id: Option<ServerId>,
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)))
},
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) => {
match menudetail.menu {
@ -635,7 +635,14 @@ impl<EG: EntityGateway> InterserverActor for CharacterServerState<EG> {
if self.authenticated_ships.contains(&id) {
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) => {
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 room;
pub mod quest;
pub mod ship;
use libpso::character::character::Inventory;
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 settings;
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 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::{PacketParseError, PSOPacket};
use libpso::crypto::bb::PSOBBCipher;
@ -18,6 +18,8 @@ use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState
use crate::common::leveltable::CharacterLevelTable;
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::account::{UserAccountEntity, UserSettingsEntity};
use crate::entity::character::{CharacterEntity, SectionID};
@ -67,6 +69,7 @@ pub enum ShipError {
ShopError,
GatewayError(#[from] GatewayError),
UnknownMonster(crate::ship::monster::MonsterType),
InvalidShip(usize),
}
#[derive(Debug)]
@ -98,6 +101,8 @@ pub enum RecvShipPacket {
DoneLoadingQuest(DoneLoadingQuest),
FullCharacterData(Box<FullCharacterData>),
SaveOptions(SaveOptions),
RequestShipList(RequestShipList),
RequestShipBlockList(RequestShipBlockList),
}
impl RecvServerPacket for RecvShipPacket {
@ -131,6 +136,8 @@ impl RecvServerPacket for RecvShipPacket {
0x6F => Ok(RecvShipPacket::DoneBursting(DoneBursting::from_bytes(data)?)),
0x16F => Ok(RecvShipPacket::DoneBursting2(DoneBursting2::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)?)),
0xAC => Ok(RecvShipPacket::DoneLoadingQuest(DoneLoadingQuest::from_bytes(data)?)),
0xE7 => Ok(RecvShipPacket::FullCharacterData(Box::new(FullCharacterData::from_bytes(data)?))),
@ -144,6 +151,7 @@ impl RecvServerPacket for RecvShipPacket {
pub enum SendShipPacket {
ShipWelcome(ShipWelcome),
LoginResponse(LoginResponse),
ShipList(ShipList),
ShipBlockList(ShipBlockList),
FullCharacter(Box<FullCharacter>),
CharDataRequest(CharDataRequest),
@ -172,6 +180,7 @@ pub enum SendShipPacket {
QuestChunk(QuestChunk),
DoneLoadingQuest(DoneLoadingQuest),
BankItemList(BankItemList),
RedirectClient(RedirectClient),
}
impl SendServerPacket for SendShipPacket {
@ -179,6 +188,7 @@ impl SendServerPacket for SendShipPacket {
match self {
SendShipPacket::ShipWelcome(pkt) => pkt.as_bytes(),
SendShipPacket::LoginResponse(pkt) => pkt.as_bytes(),
SendShipPacket::ShipList(pkt) => pkt.as_bytes(),
SendShipPacket::ShipBlockList(pkt) => pkt.as_bytes(),
SendShipPacket::FullCharacter(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::DoneLoadingQuest(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) => {
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))),
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)?,
@ -599,6 +611,12 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> {
RecvShipPacket::SaveOptions(save_options) => {
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(),
port: self.port,
block_count: 2,
})) ]
})),
(id, ShipMessage::RequestShipList)
]
}
async fn action(&mut self, id: ServerId, msg: Self::RecvMessage) -> Result<Vec<(ServerId, Self::SendMessage)>, Self::Error> {

Loading…
Cancel
Save