transfer ship
This commit is contained in:
parent
ae7ba9e3fe
commit
ffce662c95
@ -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) {
|
||||
|
@ -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
Normal file
29
src/ship/packet/builder/ship.rs
Normal file
@ -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)
|
||||
}
|
@ -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
Normal file
23
src/ship/packet/handler/ship.rs
Normal file
@ -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()))
|
||||
}
|
@ -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…
x
Reference in New Issue
Block a user