@ -19,7 +19,7 @@ use libpso::packet::ship::{BLOCK_MENU_ID, ROOM_MENU_ID};
use crate ::common ::cipherkeys ::{ ELSEWHERE_PRIVATE_KEY , ELSEWHERE_PARRAY } ;
use crate ::common ::serverstate ::{ SendServerPacket , RecvServerPacket , ServerState , OnConnect , ClientId } ;
use crate ::common ::interserver ::{ AuthToken , Ship , ServerId , InterserverActor , LoginMessage , ShipMessage } ;
use crate ::common ::interserver ::{ AuthToken , Ship , ServerId , InterserverActor , LoginMessage , ShipMessage , InterserverMessage } ;
use crate ::login ::character ::SHIP_MENU_ID ;
@ -34,6 +34,7 @@ use crate::ship::map::{MapsError, MapAreaError};
use crate ::ship ::packet ::handler ;
use crate ::ship ::shops ::{ WeaponShop , ToolShop , ArmorShop } ;
use crate ::ship ::trade ::TradeState ;
use crate ::ship ::teams ::Teams ;
// TODO: remove once stuff settles down
pub use crate ::ship ::client ::* ;
@ -160,6 +161,8 @@ pub enum ShipError {
RoomCreationError ( #[ from ] room ::RoomCreationError ) ,
#[ error( " channel send error {0} " ) ]
SendError ( #[ from ] async_std ::channel ::SendError < ShipMessage > ) ,
#[ error( " team {0} " ) ]
TeamError ( #[ from ] crate ::ship ::teams ::TeamError ) ,
}
impl < I : Into < ClientLocationError > > From < I > for ShipError {
@ -204,6 +207,7 @@ pub enum RecvShipPacket {
KeyboardConfig ( KeyboardConfig ) ,
GamepadConfig ( GamepadConfig ) ,
UpdateConfig ( UpdateConfig ) ,
CreateTeam ( CreateTeam ) ,
}
impl RecvServerPacket for RecvShipPacket {
@ -247,6 +251,7 @@ impl RecvServerPacket for RecvShipPacket {
0x4ED = > Ok ( RecvShipPacket ::KeyboardConfig ( KeyboardConfig ::from_bytes ( data ) ? ) ) ,
0x5ED = > Ok ( RecvShipPacket ::GamepadConfig ( GamepadConfig ::from_bytes ( data ) ? ) ) ,
0x7ED = > Ok ( RecvShipPacket ::UpdateConfig ( UpdateConfig ::from_bytes ( data ) ? ) ) ,
0x1EA = > Ok ( RecvShipPacket ::CreateTeam ( CreateTeam ::from_bytes ( data ) ? ) ) ,
_ = > Err ( PacketParseError ::WrongPacketForServerType ( u16 ::from_le_bytes ( [ data [ 2 ] , data [ 3 ] ] ) , data . to_vec ( ) ) )
}
}
@ -267,6 +272,7 @@ pub enum SendShipPacket {
PlayerChat ( PlayerChat ) ,
SmallDialog ( SmallDialog ) ,
SmallLeftDialog ( SmallLeftDialog ) ,
LargeDialog ( LargeDialog ) ,
JoinRoom ( JoinRoom ) ,
AddToRoom ( AddToRoom ) ,
LeaveLobby ( LeaveLobby ) ,
@ -292,6 +298,10 @@ pub enum SendShipPacket {
CancelTrade ( CancelTrade ) ,
TradeSuccessful ( TradeSuccessful ) ,
LobbyEvent ( LobbyEvent ) ,
//TeamActionResponse(TeamActionResponse),
CreateTeamResponse ( CreateTeamResponse ) ,
ClientTeamStateChanged ( ClientTeamStateChanged ) ,
TeamInfo ( Box < TeamInfo > ) ,
}
impl SendServerPacket for SendShipPacket {
@ -310,6 +320,7 @@ impl SendServerPacket for SendShipPacket {
SendShipPacket ::PlayerChat ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::SmallDialog ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::SmallLeftDialog ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::LargeDialog ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::JoinRoom ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::AddToRoom ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::LeaveLobby ( pkt ) = > pkt . as_bytes ( ) ,
@ -335,6 +346,9 @@ impl SendServerPacket for SendShipPacket {
SendShipPacket ::CancelTrade ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::TradeSuccessful ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::LobbyEvent ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::CreateTeamResponse ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::ClientTeamStateChanged ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::TeamInfo ( pkt ) = > pkt . as_bytes ( ) ,
}
}
}
@ -437,9 +451,11 @@ impl<EG: EntityGateway + Clone + 'static> ShipServerStateBuilder<EG> {
pub fn build ( self ) -> ShipServerState < EG > {
let blocks = std ::iter ::repeat_with ( Block ::default ) . take ( self . num_blocks ) . collect ( ) ; // Block doesn't have a Clone impl which limits the easy ways to init this
let entity_gateway = self . entity_gateway . unwrap ( ) ;
let clients = Clients ::default ( ) ;
ShipServerState {
entity_gateway : self . entity_gateway . unwrap ( ) ,
clients : Clients ::default ( ) ,
entity_gateway : entity_gateway . clone ( ) ,
clients : clients . clone ( ) ,
name : self . name . unwrap_or_else ( | | "NAMENOTSET" . into ( ) ) ,
item_state : items ::state ::ItemState ::default ( ) ,
ip : self . ip . unwrap_or_else ( | | Ipv4Addr ::new ( 127 , 0 , 0 , 1 ) ) ,
@ -447,10 +463,11 @@ impl<EG: EntityGateway + Clone + 'static> ShipServerStateBuilder<EG> {
shops : ItemShops ::default ( ) ,
blocks : Blocks ( blocks ) ,
event : self . event . unwrap_or ( ShipEvent ::None ) ,
teams : Teams ::new ( entity_gateway , clients ) ,
auth_token : self . auth_token . unwrap_or_else ( | | AuthToken ( "" . into ( ) ) ) ,
ship_list : Arc ::new ( RwLock ::new ( Vec ::new ( ) ) ) ,
shipgate_sender : None ,
shipgate_sender : Arc ::new ( RwLock ::new ( None ) ) ,
trades : Default ::default ( ) ,
}
}
@ -487,13 +504,14 @@ pub struct ShipServerState<EG: EntityGateway + Clone + 'static> {
shops : ItemShops ,
pub blocks : Blocks ,
event : ShipEvent ,
teams : Teams < EG > ,
ip : Ipv4Addr ,
port : u16 ,
auth_token : AuthToken ,
ship_list : Arc < RwLock < Vec < Ship > > > ,
shipgate_sender : Option < channel ::Sender < ShipMessage > > ,
shipgate_sender : Arc < RwLock < Option < channel ::Sender < ShipMessage > > > > ,
trades : TradeState ,
}
@ -803,6 +821,9 @@ impl<EG: EntityGateway + Clone> ServerState for ShipServerState<EG> {
RecvShipPacket ::GamepadConfig ( gamepad_config ) = > {
handler ::settings ::gamepad_config ( id , gamepad_config , & self . clients , & mut self . entity_gateway ) . await ?
} ,
RecvShipPacket ::CreateTeam ( create_team ) = > {
handler ::teams ::create_team ( id , create_team , & mut self . entity_gateway , & self . clients , & mut self . shipgate_sender ) . await ?
} ,
} )
}
@ -828,7 +849,7 @@ impl<EG: EntityGateway + Clone> ServerState for ShipServerState<EG> {
if let Some ( mut client ) = self . clients . remove ( & id ) . await {
client . user . at_ship = false ;
self . entity_gateway . save_user ( & client . user ) . await ;
if let Some ( shipgate_sender ) = self . shipgate_sender . as_ref ( ) {
if let Some ( shipgate_sender ) = self . shipgate_sender . read ( ) . await . as_ref ( ) {
shipgate_sender . send ( ShipMessage ::RemoveUser ( client . user . id ) ) . await ;
}
self . item_state . remove_character_from_room ( & client . character ) . await
@ -843,14 +864,15 @@ impl<EG: EntityGateway + Clone> ServerState for ShipServerState<EG> {
#[ async_trait::async_trait ]
impl < EG : EntityGateway + Clone > InterserverActor for ShipServerState < EG > {
type SendMessage = ShipMessage ;
type RecvMessage = LoginMessage ;
type Error = ( ) ;
type SendClientMessage = SendShipPacket ;
type SendServerMessage = ShipMessage ;
type RecvServerMessage = LoginMessage ;
type Error = ShipError ;
async fn on_connect ( & mut self , id : ServerId ) -> Vec < ( ServerId , Self ::SendMessage ) > {
async fn on_connect ( & mut self , id : ServerId ) -> Vec < ( ServerId , Self ::SendServer Message ) > {
vec ! [
( id , ShipMessage ::Authenticate ( self . auth_token . clone ( ) ) ) ,
( id , ShipMessage ::NewShip ( Ship {
( id , ShipMessage ::NewShip ( Ship {
name : self . name . clone ( ) ,
ip : self . ip ,
port : self . port ,
@ -860,7 +882,7 @@ impl<EG: EntityGateway + Clone> InterserverActor for ShipServerState<EG> {
]
}
async fn on_action ( & mut self , _id : ServerId , msg : Self ::RecvMessage ) -> Result < Vec < ( ServerId , Self ::SendMessage ) > , Self ::Error > {
async fn on_action ( & mut self , _id : ServerId , msg : Self ::RecvServer Message ) -> Result < Vec < InterserverMessage < Self ::SendServerMessage , Self ::SendClientMessage > > , Self ::Error > {
match msg {
LoginMessage ::SendMail { . . } = > {
Ok ( Vec ::new ( ) )
@ -883,15 +905,51 @@ impl<EG: EntityGateway + Clone> InterserverActor for ShipServerState<EG> {
* /
// TODO
Ok ( Vec ::new ( ) )
}
} ,
LoginMessage ::CreatedTeam ( user_id , team_id ) = > {
let client_id = self . clients . with_match_mut ( | c | c . user . id = = user_id , | client_id , client | Box ::pin ( async move {
client . user . team_id = Some ( team_id ) ;
client_id
} ) ) . await ? ;
let team_pkts = self . clients . with ( client_id , | client | {
let mut teams = self . teams . clone ( ) ;
Box ::pin ( async move {
let team_pkts = teams . get_team ( client_id ) . await
. and_then ( | team | {
let team = team . ok_or_else ( | | super ::teams ::TeamError ::ClientHasNoTeam ( client_id ) ) ? ;
Ok ( (
crate ::ship ::packet ::builder ::team ::team_info ( client_id , client , & team ) ,
crate ::ship ::packet ::builder ::team ::client_team_state_changed ( client_id , client , & team ) ,
) )
} ) ;
team_pkts
} )
} ) . await ? ;
match team_pkts {
Ok ( ( team_info , client_team_state_changed ) ) = > {
Ok ( vec ! [
InterserverMessage ::Client ( client_id , SendShipPacket ::CreateTeamResponse ( CreateTeamResponse ::success ( ) ) ) ,
InterserverMessage ::Client ( client_id , SendShipPacket ::TeamInfo ( Box ::new ( team_info ) ) ) , // TODO: send to neighbors
InterserverMessage ::Client ( client_id , SendShipPacket ::ClientTeamStateChanged ( client_team_state_changed ) ) ,
] )
} ,
Err ( err ) = > {
Ok ( vec ! [
InterserverMessage ::Client ( client_id , SendShipPacket ::CreateTeamResponse ( CreateTeamResponse ::failure ( ) ) ) ,
//InterserverMessage::Client(client_id, SendShipPacket::LargeDialog(LargeDialog::new(format!("failed to create team: {:?}", err)))),
] )
}
}
} ,
}
}
async fn on_disconnect ( & mut self , _id : ServerId ) -> Vec < ( ServerId , Self ::SendMessage ) > {
async fn on_disconnect ( & mut self , _id : ServerId ) -> Vec < ( ServerId , Self ::SendServer Message ) > {
Vec ::new ( )
}
async fn set_sender ( & mut self , _server_id : ServerId , sender : channel ::Sender < Self ::SendMessage > ) {
self . shipgate_sender = Some ( sender ) ;
async fn set_sender ( & mut self , _server_id : ServerId , sender : channel ::Sender < Self ::SendServer Message > ) {
* self . shipgate_sender . write ( ) . await = Some ( sender ) ;
}
}