2020-05-02 22:08:37 -03:00
#![ allow(dead_code, unused_must_use) ]
2020-08-19 23:18:04 -06:00
use std ::net ::Ipv4Addr ;
2019-11-04 20:33:51 -08:00
use std ::collections ::HashMap ;
2019-10-09 22:45:51 -07:00
2019-11-04 20:33:51 -08:00
use rand ::Rng ;
2020-04-25 22:16:40 -06:00
use thiserror ::Error ;
2019-11-04 20:33:51 -08:00
use libpso ::packet ::ship ::* ;
2020-11-21 23:45:27 -07:00
use libpso ::packet ::login ::{ RedirectClient , Login , LoginResponse , Session , ShipList } ;
2019-11-24 21:11:52 -08:00
use libpso ::packet ::messages ::* ;
2019-11-04 20:33:51 -08:00
use libpso ::{ PacketParseError , PSOPacket } ;
use libpso ::crypto ::bb ::PSOBBCipher ;
2020-05-02 22:08:37 -03:00
2020-04-21 07:28:14 -06:00
use libpso ::packet ::ship ::{ BLOCK_MENU_ID , ROOM_MENU_ID } ;
2020-05-02 22:08:37 -03:00
2019-11-04 20:33:51 -08:00
use crate ::common ::cipherkeys ::{ ELSEWHERE_PRIVATE_KEY , ELSEWHERE_PARRAY } ;
2019-10-09 22:45:51 -07:00
use crate ::common ::serverstate ::{ SendServerPacket , RecvServerPacket , ServerState , OnConnect , ClientId } ;
2019-12-03 21:45:16 -08:00
use crate ::common ::leveltable ::CharacterLevelTable ;
2020-08-19 23:18:04 -06:00
use crate ::common ::interserver ::{ AuthToken , Ship , ServerId , InterserverActor , LoginMessage , ShipMessage } ;
2019-11-04 20:33:51 -08:00
2020-11-21 23:45:27 -07:00
use crate ::login ::character ::SHIP_MENU_ID ;
2020-10-24 17:45:59 -06:00
use crate ::entity ::gateway ::{ EntityGateway , GatewayError } ;
2020-05-02 22:08:37 -03:00
use crate ::entity ::account ::{ UserAccountEntity , UserSettingsEntity } ;
2020-09-27 18:16:27 -06:00
use crate ::entity ::character ::{ CharacterEntity , SectionID } ;
2020-12-03 15:04:48 -07:00
use crate ::entity ::item ;
2020-05-02 22:08:37 -03:00
2020-10-30 23:09:01 -06:00
use crate ::ship ::location ::{ ClientLocation , RoomLobby , MAX_ROOMS , ClientLocationError , GetNeighborError , GetClientsError , GetAreaError } ;
2020-05-02 22:08:37 -03:00
2020-01-18 23:36:28 -08:00
use crate ::ship ::items ;
2020-01-02 20:29:28 -08:00
use crate ::ship ::room ;
2020-05-14 23:38:18 -06:00
use crate ::ship ::map ::{ MapsError , MapAreaError , MapArea } ;
2020-04-21 21:47:41 -06:00
use crate ::ship ::packet ::handler ;
2020-10-26 00:02:48 -06:00
use crate ::ship ::shops ::{ WeaponShop , ToolShop , ArmorShop , WeaponShopItem , ToolShopItem , ArmorShopItem } ;
2021-12-10 13:24:59 -07:00
use crate ::ship ::trade ::TradeState ;
2019-10-09 22:45:51 -07:00
2019-11-04 20:33:51 -08:00
pub const SHIP_PORT : u16 = 23423 ;
2020-05-24 15:59:48 -06:00
pub const QUEST_CATEGORY_MENU_ID : u32 = 0xA2 ;
pub const QUEST_SELECT_MENU_ID : u32 = 0xA3 ;
2020-04-21 23:15:11 -06:00
pub type Rooms = [ Option < room ::RoomState > ; MAX_ROOMS ] ;
2020-04-22 23:49:49 -06:00
pub type Clients = HashMap < ClientId , ClientState > ;
2019-10-09 22:45:51 -07:00
2020-04-25 22:16:40 -06:00
#[ derive(Error, Debug) ]
2021-12-10 23:41:17 -07:00
#[ error( " shiperror {0:?} " ) ]
2019-10-09 22:45:51 -07:00
pub enum ShipError {
2019-11-04 20:33:51 -08:00
ClientNotFound ( ClientId ) ,
2019-11-20 22:43:02 -08:00
NoCharacterInSlot ( ClientId , u32 ) ,
InvalidSlot ( ClientId , u32 ) ,
2021-12-10 23:41:17 -07:00
#[ error( " " ) ]
2020-04-06 23:40:39 -07:00
TooManyClients ,
2020-04-25 22:16:40 -06:00
ClientLocationError ( #[ from ] ClientLocationError ) ,
2020-10-30 23:09:01 -06:00
GetNeighborError ( #[ from ] GetNeighborError ) ,
GetClientsError ( #[ from ] GetClientsError ) ,
GetAreaError ( #[ from ] GetAreaError ) ,
2020-04-26 21:57:19 -06:00
MapsError ( #[ from ] MapsError ) ,
2020-05-13 22:32:30 -06:00
MapAreaError ( #[ from ] MapAreaError ) ,
2020-04-21 07:28:14 -06:00
InvalidRoom ( u32 ) ,
2020-04-26 22:01:05 -06:00
MonsterAlreadyDroppedItem ( ClientId , u16 ) ,
SliceError ( #[ from ] std ::array ::TryFromSliceError ) ,
2021-12-10 23:41:17 -07:00
#[ error( " " ) ]
2020-04-26 22:23:59 -06:00
ItemError , // TODO: refine this
2020-05-05 21:53:04 -06:00
PickUpInvalidItemId ( u32 ) ,
2020-05-13 22:32:30 -06:00
DropInvalidItemId ( u32 ) ,
2020-05-14 23:38:18 -06:00
ItemManagerError ( #[ from ] items ::ItemManagerError ) ,
2022-04-30 11:39:12 -06:00
ItemStateError ( #[ from ] items ::state ::ItemStateError ) ,
2021-12-10 23:41:17 -07:00
#[ error( " " ) ]
2020-05-14 23:38:18 -06:00
ItemDropLocationNotSet ,
2020-05-15 13:37:44 -03:00
BoxAlreadyDroppedItem ( ClientId , u16 ) ,
2020-05-24 15:59:48 -06:00
InvalidQuestCategory ( u32 ) ,
InvalidQuest ( u32 ) ,
InvalidQuestFilename ( String ) ,
IoError ( #[ from ] std ::io ::Error ) ,
2020-06-29 22:40:26 -04:00
NotEnoughMeseta ( ClientId , u32 ) ,
2021-12-10 23:41:17 -07:00
#[ error( " " ) ]
2020-09-27 18:16:27 -06:00
ShopError ,
2020-10-24 17:45:59 -06:00
GatewayError ( #[ from ] GatewayError ) ,
2020-10-31 19:13:45 -06:00
UnknownMonster ( crate ::ship ::monster ::MonsterType ) ,
2020-11-21 23:45:27 -07:00
InvalidShip ( usize ) ,
2020-11-24 23:17:42 -07:00
InvalidBlock ( usize ) ,
2020-12-03 15:04:48 -07:00
InvalidItem ( items ::ClientItemId ) ,
2022-07-18 18:42:44 -06:00
#[ error( " trade error {0} " ) ]
2021-12-10 13:24:59 -07:00
TradeError ( #[ from ] crate ::ship ::packet ::handler ::trade ::TradeError ) ,
2022-07-18 18:42:44 -06:00
#[ error( " trade state error {0} " ) ]
TradeStateError ( #[ from ] crate ::ship ::trade ::TradeStateError ) ,
2019-10-09 22:45:51 -07:00
}
#[ derive(Debug) ]
pub enum RecvShipPacket {
2019-11-04 20:33:51 -08:00
Login ( Login ) ,
2019-11-16 23:15:25 -08:00
MenuSelect ( MenuSelect ) ,
2020-04-27 21:59:15 -03:00
RoomPasswordReq ( RoomPasswordReq ) ,
2019-11-16 23:15:25 -08:00
CharData ( CharData ) ,
2019-11-24 21:11:52 -08:00
Message ( Message ) ,
2019-12-15 23:20:12 -08:00
DirectMessage ( DirectMessage ) ,
2019-12-26 18:47:00 -04:00
PlayerChat ( PlayerChat ) ,
2020-01-02 20:29:28 -08:00
CreateRoom ( CreateRoom ) ,
2020-01-13 20:20:47 -08:00
RoomNameRequest ( RoomNameRequest ) ,
2020-03-01 02:57:18 -04:00
ViewInfoboardRequest ( ViewInfoboardRequest ) ,
2020-02-27 23:58:00 -04:00
WriteInfoboard ( WriteInfoboard ) ,
2020-03-17 08:02:17 -03:00
RoomListRequest ( RoomListRequest ) ,
2020-04-21 07:28:14 -06:00
Like62ButCooler ( Like62ButCooler ) ,
ClientCharacterData ( ClientCharacterData ) ,
DoneBursting ( DoneBursting ) ,
2020-05-24 15:59:48 -06:00
DoneBursting2 ( DoneBursting2 ) ,
2020-04-27 20:17:35 -04:00
LobbySelect ( LobbySelect ) ,
2020-05-24 15:59:48 -06:00
RequestQuestList ( RequestQuestList ) ,
MenuDetail ( MenuDetail ) ,
QuestDetailRequest ( QuestDetailRequest ) ,
QuestMenuSelect ( QuestMenuSelect ) ,
QuestFileRequest ( QuestFileRequest ) ,
QuestChunkAck ( QuestChunkAck ) ,
DoneLoadingQuest ( DoneLoadingQuest ) ,
2020-10-01 16:58:16 -06:00
FullCharacterData ( Box < FullCharacterData > ) ,
2020-10-02 21:24:32 -03:00
SaveOptions ( SaveOptions ) ,
2020-11-21 23:45:27 -07:00
RequestShipList ( RequestShipList ) ,
RequestShipBlockList ( RequestShipBlockList ) ,
2020-12-12 19:55:27 -07:00
ItemsToTrade ( ItemsToTrade ) ,
TradeConfirmed ( TradeConfirmed ) ,
2021-05-30 19:02:56 +00:00
KeyboardConfig ( KeyboardConfig ) ,
2022-01-05 22:57:15 +00:00
GamepadConfig ( GamepadConfig ) ,
UpdateConfig ( UpdateConfig ) ,
2019-10-09 22:45:51 -07:00
}
impl RecvServerPacket for RecvShipPacket {
fn from_bytes ( data : & [ u8 ] ) -> Result < RecvShipPacket , PacketParseError > {
2019-11-04 20:33:51 -08:00
match u16 ::from_le_bytes ( [ data [ 2 ] , data [ 3 ] ] ) {
0x93 = > Ok ( RecvShipPacket ::Login ( Login ::from_bytes ( data ) ? ) ) ,
2020-05-24 15:59:48 -06:00
0x09 = > match data [ 8 ] as u32 {
QUEST_SELECT_MENU_ID = > Ok ( RecvShipPacket ::QuestDetailRequest ( QuestDetailRequest ::from_bytes ( data ) ? ) ) ,
_ = > Ok ( RecvShipPacket ::MenuDetail ( MenuDetail ::from_bytes ( data ) ? ) ) ,
}
0x10 = > match ( data [ 0 ] , data [ 8 ] as u32 ) {
( 16 , QUEST_SELECT_MENU_ID ) = > Ok ( RecvShipPacket ::QuestMenuSelect ( QuestMenuSelect ::from_bytes ( data ) ? ) ) ,
( 16 , _ ) = > Ok ( RecvShipPacket ::MenuSelect ( MenuSelect ::from_bytes ( data ) ? ) ) ,
( 48 , _ ) = > Ok ( RecvShipPacket ::RoomPasswordReq ( RoomPasswordReq ::from_bytes ( data ) ? ) ) ,
2020-04-27 22:57:08 -03:00
_ = > Err ( PacketParseError ::WrongPacketForServerType ( u16 ::from_le_bytes ( [ data [ 2 ] , data [ 3 ] ] ) , data . to_vec ( ) ) ) ,
2020-04-27 21:59:15 -03:00
} ,
2020-05-24 15:59:48 -06:00
0x13 = > Ok ( RecvShipPacket ::QuestChunkAck ( QuestChunkAck ::from_bytes ( data ) ? ) ) ,
0x44 = > Ok ( RecvShipPacket ::QuestFileRequest ( QuestFileRequest ::from_bytes ( data ) ? ) ) ,
2019-11-16 23:15:25 -08:00
0x61 = > Ok ( RecvShipPacket ::CharData ( CharData ::from_bytes ( data ) ? ) ) ,
2019-11-24 21:11:52 -08:00
0x60 = > Ok ( RecvShipPacket ::Message ( Message ::from_bytes ( data ) ? ) ) ,
2019-12-15 23:20:12 -08:00
0x62 = > Ok ( RecvShipPacket ::DirectMessage ( DirectMessage ::from_bytes ( data ) ? ) ) ,
2019-12-26 18:47:00 -04:00
0x06 = > Ok ( RecvShipPacket ::PlayerChat ( PlayerChat ::from_bytes ( data ) ? ) ) ,
2020-01-02 20:29:28 -08:00
0xC1 = > Ok ( RecvShipPacket ::CreateRoom ( CreateRoom ::from_bytes ( data ) ? ) ) ,
2020-01-13 20:20:47 -08:00
0x8A = > Ok ( RecvShipPacket ::RoomNameRequest ( RoomNameRequest ::from_bytes ( data ) ? ) ) ,
2020-03-01 02:57:18 -04:00
0xD8 = > Ok ( RecvShipPacket ::ViewInfoboardRequest ( ViewInfoboardRequest ::from_bytes ( data ) ? ) ) ,
2020-02-27 23:58:00 -04:00
0xD9 = > Ok ( RecvShipPacket ::WriteInfoboard ( WriteInfoboard ::from_bytes ( data ) ? ) ) ,
2020-03-17 08:02:17 -03:00
0x08 = > Ok ( RecvShipPacket ::RoomListRequest ( RoomListRequest ::from_bytes ( data ) ? ) ) ,
2020-04-21 07:28:14 -06:00
0x6D = > Ok ( RecvShipPacket ::Like62ButCooler ( Like62ButCooler ::from_bytes ( data ) ? ) ) ,
0x98 = > Ok ( RecvShipPacket ::ClientCharacterData ( ClientCharacterData ::from_bytes ( data ) ? ) ) ,
0x6F = > Ok ( RecvShipPacket ::DoneBursting ( DoneBursting ::from_bytes ( data ) ? ) ) ,
2020-05-24 15:59:48 -06:00
0x16F = > Ok ( RecvShipPacket ::DoneBursting2 ( DoneBursting2 ::from_bytes ( data ) ? ) ) ,
2020-04-27 20:17:35 -04:00
0x84 = > Ok ( RecvShipPacket ::LobbySelect ( LobbySelect ::from_bytes ( data ) ? ) ) ,
2020-11-21 23:45:27 -07:00
0xA0 = > Ok ( RecvShipPacket ::RequestShipList ( RequestShipList ::from_bytes ( data ) ? ) ) ,
0xA1 = > Ok ( RecvShipPacket ::RequestShipBlockList ( RequestShipBlockList ::from_bytes ( data ) ? ) ) ,
2020-05-24 15:59:48 -06:00
0xA2 = > Ok ( RecvShipPacket ::RequestQuestList ( RequestQuestList ::from_bytes ( data ) ? ) ) ,
0xAC = > Ok ( RecvShipPacket ::DoneLoadingQuest ( DoneLoadingQuest ::from_bytes ( data ) ? ) ) ,
2020-12-12 19:55:27 -07:00
0xD0 = > Ok ( RecvShipPacket ::ItemsToTrade ( ItemsToTrade ::from_bytes ( data ) ? ) ) ,
0xD2 = > Ok ( RecvShipPacket ::TradeConfirmed ( TradeConfirmed ::from_bytes ( data ) ? ) ) ,
2020-10-01 16:58:16 -06:00
0xE7 = > Ok ( RecvShipPacket ::FullCharacterData ( Box ::new ( FullCharacterData ::from_bytes ( data ) ? ) ) ) ,
2020-10-02 21:24:32 -03:00
0x1ED = > Ok ( RecvShipPacket ::SaveOptions ( SaveOptions ::from_bytes ( data ) ? ) ) ,
2021-05-30 19:02:56 +00:00
0x4ED = > Ok ( RecvShipPacket ::KeyboardConfig ( KeyboardConfig ::from_bytes ( data ) ? ) ) ,
2022-01-05 22:57:15 +00:00
0x5ED = > Ok ( RecvShipPacket ::GamepadConfig ( GamepadConfig ::from_bytes ( data ) ? ) ) ,
0x7ED = > Ok ( RecvShipPacket ::UpdateConfig ( UpdateConfig ::from_bytes ( data ) ? ) ) ,
2019-11-09 22:58:13 -08:00
_ = > Err ( PacketParseError ::WrongPacketForServerType ( u16 ::from_le_bytes ( [ data [ 2 ] , data [ 3 ] ] ) , data . to_vec ( ) ) )
2019-11-04 20:33:51 -08:00
}
2019-10-09 22:45:51 -07:00
}
}
2020-01-11 01:08:05 -08:00
#[ derive(Debug, Clone) ]
2019-10-09 22:45:51 -07:00
pub enum SendShipPacket {
2019-11-04 20:33:51 -08:00
ShipWelcome ( ShipWelcome ) ,
LoginResponse ( LoginResponse ) ,
2020-11-21 23:45:27 -07:00
ShipList ( ShipList ) ,
2019-11-04 20:33:51 -08:00
ShipBlockList ( ShipBlockList ) ,
2020-11-09 16:04:42 -07:00
FullCharacter ( Box < FullCharacter > ) ,
2019-11-16 23:15:25 -08:00
CharDataRequest ( CharDataRequest ) ,
JoinLobby ( JoinLobby ) ,
2019-12-15 23:23:18 -08:00
AddToLobby ( AddToLobby ) ,
2019-11-24 21:11:52 -08:00
Message ( Message ) ,
2019-12-15 23:20:12 -08:00
DirectMessage ( DirectMessage ) ,
2019-12-26 18:47:00 -04:00
PlayerChat ( PlayerChat ) ,
2020-01-02 20:29:28 -08:00
SmallDialog ( SmallDialog ) ,
2022-07-06 22:41:30 +00:00
SmallLeftDialog ( SmallLeftDialog ) ,
2020-01-02 20:29:28 -08:00
JoinRoom ( JoinRoom ) ,
AddToRoom ( AddToRoom ) ,
2020-01-11 01:08:05 -08:00
LeaveLobby ( LeaveLobby ) ,
LeaveRoom ( LeaveRoom ) ,
2020-01-13 20:20:47 -08:00
RoomNameResponse ( RoomNameResponse ) ,
2020-03-01 02:57:18 -04:00
ViewInfoboardResponse ( ViewInfoboardResponse ) ,
2020-03-17 08:02:17 -03:00
RoomListResponse ( RoomListResponse ) ,
2020-04-21 07:28:14 -06:00
Like62ButCooler ( Like62ButCooler ) ,
BurstDone72 ( BurstDone72 ) ,
DoneBursting ( DoneBursting ) ,
2020-05-24 15:59:48 -06:00
DoneBursting2 ( DoneBursting2 ) ,
2020-04-27 20:17:35 -04:00
LobbyList ( LobbyList ) ,
2020-05-24 15:59:48 -06:00
QuestCategoryList ( QuestCategoryList ) ,
QuestOptionList ( QuestOptionList ) ,
QuestDetail ( QuestDetail ) ,
QuestHeader ( QuestHeader ) ,
QuestChunk ( QuestChunk ) ,
DoneLoadingQuest ( DoneLoadingQuest ) ,
2020-07-19 14:14:07 -06:00
BankItemList ( BankItemList ) ,
2020-11-21 23:45:27 -07:00
RedirectClient ( RedirectClient ) ,
2021-02-20 22:29:40 +00:00
RareMonsterList ( RareMonsterList ) ,
2020-12-12 19:55:27 -07:00
AcknowledgeTrade ( AcknowledgeTrade ) ,
CancelTrade ( CancelTrade ) ,
2021-12-10 13:24:59 -07:00
TradeSuccessful ( TradeSuccessful ) ,
2019-10-09 22:45:51 -07:00
}
impl SendServerPacket for SendShipPacket {
fn as_bytes ( & self ) -> Vec < u8 > {
2019-11-04 20:33:51 -08:00
match self {
SendShipPacket ::ShipWelcome ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::LoginResponse ( pkt ) = > pkt . as_bytes ( ) ,
2020-11-21 23:45:27 -07:00
SendShipPacket ::ShipList ( pkt ) = > pkt . as_bytes ( ) ,
2019-11-04 20:33:51 -08:00
SendShipPacket ::ShipBlockList ( pkt ) = > pkt . as_bytes ( ) ,
2019-11-16 23:15:25 -08:00
SendShipPacket ::FullCharacter ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::CharDataRequest ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::JoinLobby ( pkt ) = > pkt . as_bytes ( ) ,
2019-12-15 23:23:18 -08:00
SendShipPacket ::AddToLobby ( pkt ) = > pkt . as_bytes ( ) ,
2019-11-24 21:11:52 -08:00
SendShipPacket ::Message ( pkt ) = > pkt . as_bytes ( ) ,
2019-12-15 23:20:12 -08:00
SendShipPacket ::DirectMessage ( pkt ) = > pkt . as_bytes ( ) ,
2019-12-26 18:47:00 -04:00
SendShipPacket ::PlayerChat ( pkt ) = > pkt . as_bytes ( ) ,
2020-01-02 20:29:28 -08:00
SendShipPacket ::SmallDialog ( pkt ) = > pkt . as_bytes ( ) ,
2022-07-06 22:41:30 +00:00
SendShipPacket ::SmallLeftDialog ( pkt ) = > pkt . as_bytes ( ) ,
2020-01-02 20:29:28 -08:00
SendShipPacket ::JoinRoom ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::AddToRoom ( pkt ) = > pkt . as_bytes ( ) ,
2020-01-11 01:08:05 -08:00
SendShipPacket ::LeaveLobby ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::LeaveRoom ( pkt ) = > pkt . as_bytes ( ) ,
2020-01-13 20:20:47 -08:00
SendShipPacket ::RoomNameResponse ( pkt ) = > pkt . as_bytes ( ) ,
2020-03-01 02:57:18 -04:00
SendShipPacket ::ViewInfoboardResponse ( pkt ) = > pkt . as_bytes ( ) ,
2020-03-17 08:02:17 -03:00
SendShipPacket ::RoomListResponse ( pkt ) = > pkt . as_bytes ( ) ,
2020-04-21 07:28:14 -06:00
SendShipPacket ::Like62ButCooler ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::BurstDone72 ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::DoneBursting ( pkt ) = > pkt . as_bytes ( ) ,
2020-05-24 15:59:48 -06:00
SendShipPacket ::DoneBursting2 ( pkt ) = > pkt . as_bytes ( ) ,
2020-04-27 20:17:35 -04:00
SendShipPacket ::LobbyList ( pkt ) = > pkt . as_bytes ( ) ,
2020-05-24 15:59:48 -06:00
SendShipPacket ::QuestCategoryList ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::QuestOptionList ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::QuestDetail ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::QuestHeader ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::QuestChunk ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::DoneLoadingQuest ( pkt ) = > pkt . as_bytes ( ) ,
2020-07-19 14:14:07 -06:00
SendShipPacket ::BankItemList ( pkt ) = > pkt . as_bytes ( ) ,
2020-11-21 23:45:27 -07:00
SendShipPacket ::RedirectClient ( pkt ) = > pkt . as_bytes ( ) ,
2021-02-20 22:29:40 +00:00
SendShipPacket ::RareMonsterList ( pkt ) = > pkt . as_bytes ( ) ,
2020-12-12 19:55:27 -07:00
SendShipPacket ::AcknowledgeTrade ( pkt ) = > pkt . as_bytes ( ) ,
SendShipPacket ::CancelTrade ( pkt ) = > pkt . as_bytes ( ) ,
2021-12-10 13:24:59 -07:00
SendShipPacket ::TradeSuccessful ( pkt ) = > pkt . as_bytes ( ) ,
2019-11-04 20:33:51 -08:00
}
}
}
2020-05-14 23:38:18 -06:00
#[ derive(Debug, Clone, Copy) ]
pub struct ItemDropLocation {
pub map_area : MapArea ,
pub x : f32 ,
pub z : f32 ,
pub item_id : items ::ClientItemId ,
}
2020-05-24 15:59:48 -06:00
pub struct LoadingQuest {
pub header_bin : Option < QuestHeader > ,
pub header_dat : Option < QuestHeader > ,
//pub quest_chunk_bin: Option<Box<dyn Iterator<Item = >>>,
}
2020-12-12 19:55:27 -07:00
2021-10-14 00:18:51 -06:00
2021-12-10 13:24:59 -07:00
2020-12-12 19:55:27 -07:00
2020-04-21 21:47:41 -06:00
pub struct ClientState {
pub user : UserAccountEntity ,
2020-04-22 07:30:59 -06:00
pub settings : UserSettingsEntity ,
2020-04-21 21:47:41 -06:00
pub character : CharacterEntity ,
2019-11-04 20:33:51 -08:00
session : Session ,
2020-03-29 13:27:23 -07:00
//guildcard: GuildCard,
2020-11-24 23:17:42 -07:00
pub block : usize ,
2020-05-14 23:38:18 -06:00
pub item_drop_location : Option < ItemDropLocation > ,
2020-05-24 15:59:48 -06:00
pub done_loading_quest : bool ,
//pub loading_quest: Option<LoadingQuest>,
2020-06-07 18:33:36 -03:00
pub area : Option < MapArea > ,
pub x : f32 ,
pub y : f32 ,
pub z : f32 ,
2020-09-27 18:16:27 -06:00
pub weapon_shop : Vec < WeaponShopItem > ,
pub tool_shop : Vec < ToolShopItem > ,
pub armor_shop : Vec < ArmorShopItem > ,
2020-12-03 15:04:48 -07:00
pub tek : Option < ( items ::ClientItemId , item ::weapon ::TekSpecialModifier , item ::weapon ::TekPercentModifier , i32 ) > ,
2019-11-04 20:33:51 -08:00
}
impl ClientState {
2020-05-13 22:32:30 -06:00
pub fn new ( user : UserAccountEntity , settings : UserSettingsEntity , character : CharacterEntity , session : Session ) -> ClientState {
2019-11-04 20:33:51 -08:00
ClientState {
2021-06-18 17:38:36 -06:00
user ,
settings ,
character ,
session ,
2020-11-25 22:09:00 -07:00
block : 0 ,
2020-05-14 23:38:18 -06:00
item_drop_location : None ,
2020-05-24 15:59:48 -06:00
done_loading_quest : false ,
2020-06-07 18:33:36 -03:00
area : None ,
x : 0.0 ,
y : 0.0 ,
z : 0.0 ,
2020-09-27 18:16:27 -06:00
weapon_shop : Vec ::new ( ) ,
tool_shop : Vec ::new ( ) ,
armor_shop : Vec ::new ( ) ,
2020-12-03 15:04:48 -07:00
tek : None ,
2019-11-04 20:33:51 -08:00
}
2019-10-09 22:45:51 -07:00
}
}
2020-09-27 18:16:27 -06:00
pub struct ItemShops {
pub weapon_shop : HashMap < ( room ::Difficulty , SectionID ) , WeaponShop < rand_chacha ::ChaCha20Rng > > ,
pub tool_shop : ToolShop < rand_chacha ::ChaCha20Rng > ,
pub armor_shop : ArmorShop < rand_chacha ::ChaCha20Rng > ,
}
2021-06-18 17:38:36 -06:00
impl Default for ItemShops {
fn default ( ) -> ItemShops {
2020-09-27 18:16:27 -06:00
let difficulty = [ room ::Difficulty ::Normal , room ::Difficulty ::Hard , room ::Difficulty ::VeryHard , room ::Difficulty ::Ultimate ] ;
let section_id = [ SectionID ::Viridia , SectionID ::Greenill , SectionID ::Skyly , SectionID ::Bluefull , SectionID ::Purplenum ,
SectionID ::Pinkal , SectionID ::Redria , SectionID ::Oran , SectionID ::Yellowboze , SectionID ::Whitill ] ;
let mut weapon_shop = HashMap ::new ( ) ;
for d in difficulty . iter ( ) {
for id in section_id . iter ( ) {
weapon_shop . insert ( ( * d , * id ) , WeaponShop ::new ( * d , * id ) ) ;
}
}
ItemShops {
2021-06-18 17:38:36 -06:00
weapon_shop ,
2021-06-18 11:12:09 -06:00
tool_shop : ToolShop ::default ( ) ,
2021-06-18 10:32:44 -06:00
armor_shop : ArmorShop ::default ( ) ,
2020-09-27 18:16:27 -06:00
}
}
}
2020-08-19 23:18:04 -06:00
pub struct ShipServerStateBuilder < EG : EntityGateway > {
entity_gateway : Option < EG > ,
name : Option < String > ,
ip : Option < Ipv4Addr > ,
port : Option < u16 > ,
2020-11-01 07:49:04 -07:00
auth_token : Option < AuthToken > ,
2020-11-24 23:17:42 -07:00
num_blocks : usize ,
2020-08-19 23:18:04 -06:00
}
2021-06-18 17:38:36 -06:00
impl < EG : EntityGateway > Default for ShipServerStateBuilder < EG > {
fn default ( ) -> ShipServerStateBuilder < EG > {
2020-08-19 23:18:04 -06:00
ShipServerStateBuilder {
entity_gateway : None ,
name : None ,
ip : None ,
port : None ,
2020-11-01 07:49:04 -07:00
auth_token : None ,
2020-11-24 23:17:42 -07:00
num_blocks : 2 ,
2020-08-19 23:18:04 -06:00
}
}
2021-06-18 17:38:36 -06:00
}
2020-08-19 23:18:04 -06:00
2021-06-18 17:38:36 -06:00
impl < EG : EntityGateway > ShipServerStateBuilder < EG > {
2021-12-29 15:46:22 -07:00
#[ must_use ]
2020-08-19 23:18:04 -06:00
pub fn gateway ( mut self , entity_gateway : EG ) -> ShipServerStateBuilder < EG > {
self . entity_gateway = Some ( entity_gateway ) ;
self
}
2021-12-29 15:46:22 -07:00
#[ must_use ]
2020-08-19 23:18:04 -06:00
pub fn name ( mut self , name : String ) -> ShipServerStateBuilder < EG > {
self . name = Some ( name ) ;
self
}
2021-12-29 15:46:22 -07:00
#[ must_use ]
2020-08-19 23:18:04 -06:00
pub fn ip ( mut self , ip : Ipv4Addr ) -> ShipServerStateBuilder < EG > {
self . ip = Some ( ip ) ;
self
}
2021-12-29 15:46:22 -07:00
#[ must_use ]
2020-08-19 23:18:04 -06:00
pub fn port ( mut self , port : u16 ) -> ShipServerStateBuilder < EG > {
self . port = Some ( port ) ;
self
}
2021-12-29 15:46:22 -07:00
#[ must_use ]
2020-11-01 07:49:04 -07:00
pub fn auth_token ( mut self , auth_token : AuthToken ) -> ShipServerStateBuilder < EG > {
self . auth_token = Some ( auth_token ) ;
self
}
2021-12-29 15:46:22 -07:00
#[ must_use ]
2020-11-24 23:17:42 -07:00
pub fn blocks ( mut self , num_blocks : usize ) -> ShipServerStateBuilder < EG > {
self . num_blocks = num_blocks ;
self
}
2020-08-19 23:18:04 -06:00
pub fn build ( self ) -> ShipServerState < EG > {
2020-11-24 23:17:42 -07:00
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
2020-08-19 23:18:04 -06:00
ShipServerState {
entity_gateway : self . entity_gateway . unwrap ( ) ,
clients : HashMap ::new ( ) ,
2021-06-18 20:01:05 -06:00
level_table : CharacterLevelTable ::default ( ) ,
2021-06-18 17:38:36 -06:00
name : self . name . unwrap_or_else ( | | " NAMENOTSET " . into ( ) ) ,
2021-06-18 14:08:23 -06:00
item_manager : items ::ItemManager ::default ( ) ,
2022-04-30 11:39:12 -06:00
item_state : items ::state ::ItemState ::default ( ) ,
2021-06-18 17:38:36 -06:00
ip : self . ip . unwrap_or_else ( | | Ipv4Addr ::new ( 127 , 0 , 0 , 1 ) ) ,
2020-08-20 11:52:12 -06:00
port : self . port . unwrap_or ( SHIP_PORT ) ,
2021-06-18 17:38:36 -06:00
shops : Box ::new ( ItemShops ::default ( ) ) ,
2020-11-24 23:17:42 -07:00
blocks : Blocks ( blocks ) ,
2021-06-18 17:38:36 -06:00
auth_token : self . auth_token . unwrap_or_else ( | | AuthToken ( " " . into ( ) ) ) ,
2020-11-18 18:56:04 -07:00
ship_list : Vec ::new ( ) ,
2020-11-17 18:25:01 -07:00
shipgate_sender : None ,
2021-12-10 13:24:59 -07:00
trades : Default ::default ( ) ,
2020-08-19 23:18:04 -06:00
}
}
}
2020-03-21 17:47:28 -07:00
2020-11-25 22:09:00 -07:00
pub struct Block {
2020-11-24 23:17:42 -07:00
client_location : Box < ClientLocation > ,
2020-11-25 22:09:00 -07:00
pub rooms : Box < Rooms > ,
2020-11-24 23:17:42 -07:00
}
impl Default for Block {
fn default ( ) -> Block {
2021-06-15 20:43:07 -06:00
const SNONE : Option < room ::RoomState > = None ;
const NONE : Rooms = [ SNONE ; MAX_ROOMS ] ;
2020-11-24 23:17:42 -07:00
Block {
client_location : Box ::new ( ClientLocation ::default ( ) ) ,
2021-06-15 20:43:07 -06:00
rooms : Box ::new ( NONE ) ,
2020-11-24 23:17:42 -07:00
}
}
}
2020-11-25 22:09:00 -07:00
pub struct Blocks ( pub Vec < Block > ) ;
2020-11-24 23:17:42 -07:00
impl Blocks {
fn with_client ( & mut self , id : ClientId , clients : & Clients ) -> Result < & mut Block , ShipError > {
let client = clients . get ( & id ) . ok_or ( ShipError ::ClientNotFound ( id ) ) ? ;
self . 0. get_mut ( client . block ) . ok_or ( ShipError ::InvalidBlock ( client . block ) )
}
}
2019-10-09 22:45:51 -07:00
pub struct ShipServerState < EG : EntityGateway > {
entity_gateway : EG ,
2020-05-30 10:30:39 -06:00
pub clients : Clients ,
2019-12-03 21:45:16 -08:00
level_table : CharacterLevelTable ,
2019-12-03 22:51:21 -08:00
name : String ,
2020-06-29 19:26:35 -06:00
item_manager : items ::ItemManager ,
2022-04-30 11:39:12 -06:00
item_state : items ::state ::ItemState ,
2020-11-24 23:17:42 -07:00
shops : Box < ItemShops > ,
2020-11-25 22:09:00 -07:00
pub blocks : Blocks ,
2020-11-24 23:17:42 -07:00
2020-08-19 23:18:04 -06:00
ip : Ipv4Addr ,
port : u16 ,
2020-11-17 18:25:01 -07:00
2020-11-24 23:17:42 -07:00
auth_token : AuthToken ,
2020-11-18 18:56:04 -07:00
ship_list : Vec < Ship > ,
shipgate_sender : Option < Box < dyn Fn ( ShipMessage ) + Send + Sync > > ,
2021-12-10 13:24:59 -07:00
trades : TradeState ,
2019-10-09 22:45:51 -07:00
}
impl < EG : EntityGateway > ShipServerState < EG > {
2020-08-20 11:52:12 -06:00
pub fn builder ( ) -> ShipServerStateBuilder < EG > {
2021-06-18 17:38:36 -06:00
ShipServerStateBuilder ::default ( )
2019-10-09 22:45:51 -07:00
}
2019-11-04 20:33:51 -08:00
2020-11-18 18:56:04 -07:00
pub fn set_sender ( & mut self , sender : Box < dyn Fn ( ShipMessage ) + Send + Sync > ) {
2020-11-17 18:25:01 -07:00
self . shipgate_sender = Some ( sender ) ;
}
2020-11-01 09:04:37 -07:00
async fn message ( & mut self , id : ClientId , msg : & Message ) -> Result < Box < dyn Iterator < Item = ( ClientId , SendShipPacket ) > + Send > , anyhow ::Error > {
Ok ( match & msg . msg {
2020-04-22 07:14:59 -06:00
GameMessage ::RequestExp ( request_exp ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
handler ::message ::request_exp ( id , request_exp , & mut self . entity_gateway , & block . client_location , & mut self . clients , & mut block . rooms , & self . level_table ) . await ?
2020-04-22 07:14:59 -06:00
} ,
2020-05-14 09:45:05 -06:00
GameMessage ::PlayerDropItem ( player_drop_item ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2022-04-30 11:41:24 -06:00
handler ::message ::player_drop_item ( id , player_drop_item , & mut self . entity_gateway , & block . client_location , & mut self . clients , & mut block . rooms , & mut self . item_state ) . await ?
2020-05-13 22:32:30 -06:00
} ,
2020-05-14 23:38:18 -06:00
GameMessage ::DropCoordinates ( drop_coordinates ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
handler ::message ::drop_coordinates ( id , drop_coordinates , & block . client_location , & mut self . clients , & block . rooms ) ?
2020-05-14 23:38:18 -06:00
} ,
2020-07-23 17:18:20 -06:00
GameMessage ::PlayerNoLongerHasItem ( no_longer_has_item ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2022-04-30 21:40:46 -06:00
handler ::message ::no_longer_has_item ( id , no_longer_has_item , & mut self . entity_gateway , & block . client_location , & mut self . clients , & mut self . item_state ) . await ?
2020-05-14 23:38:18 -06:00
} ,
2020-06-07 18:33:36 -03:00
GameMessage ::PlayerChangedMap ( _ ) | GameMessage ::PlayerChangedMap2 ( _ ) | GameMessage ::TellOtherPlayerMyLocation ( _ ) |
GameMessage ::PlayerWarpingToFloor ( _ ) | GameMessage ::PlayerTeleported ( _ ) | GameMessage ::PlayerStopped ( _ ) |
GameMessage ::PlayerLoadedIn ( _ ) | GameMessage ::PlayerWalking ( _ ) | GameMessage ::PlayerRunning ( _ ) |
GameMessage ::PlayerWarped ( _ ) | GameMessage ::PlayerChangedFloor ( _ ) | GameMessage ::InitializeSpeechNpc ( _ ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2021-06-18 17:38:36 -06:00
handler ::message ::update_player_position ( id , msg , & mut self . clients , & block . client_location , & block . rooms ) ?
2020-06-07 18:33:36 -03:00
} ,
2020-06-29 22:40:26 -04:00
GameMessage ::ChargeAttack ( charge_attack ) = > {
2022-07-18 19:25:47 -06:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
handler ::message ::charge_attack ( id , charge_attack , & mut self . entity_gateway , & block . client_location , & mut self . clients , & mut self . item_state ) . await ?
2020-06-29 22:40:26 -04:00
} ,
2020-06-29 19:26:35 -06:00
GameMessage ::PlayerUseItem ( player_use_item ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2022-05-27 01:38:49 -06:00
handler ::message ::player_uses_item ( id , player_use_item , & mut self . entity_gateway , & block . client_location , & mut self . clients , & mut self . item_state ) . await ?
2020-06-29 19:26:35 -06:00
} ,
2020-08-11 17:17:24 -03:00
GameMessage ::PlayerUsedMedicalCenter ( player_used_medical_center ) = > {
2022-07-18 19:25:47 -06:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
handler ::message ::player_used_medical_center ( id , player_used_medical_center , & mut self . entity_gateway , & block . client_location , & mut self . clients , & mut self . item_state ) . await ?
2020-08-11 17:17:24 -03:00
} ,
2020-08-31 23:46:15 -06:00
GameMessage ::PlayerFeedMag ( player_feed_mag ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2022-06-20 15:40:30 -06:00
handler ::message ::player_feed_mag ( id , player_feed_mag , & mut self . entity_gateway , & block . client_location , & self . clients , & mut self . item_state ) . await ?
2020-08-31 23:46:15 -06:00
} ,
2020-10-06 21:35:20 -03:00
GameMessage ::PlayerEquipItem ( player_equip_item ) = > {
2022-05-15 00:34:06 -06:00
handler ::message ::player_equips_item ( id , player_equip_item , & mut self . entity_gateway , & self . clients , & mut self . item_state ) . await ?
2020-10-06 21:35:20 -03:00
} ,
GameMessage ::PlayerUnequipItem ( player_unequip_item ) = > {
2022-05-15 00:34:06 -06:00
handler ::message ::player_unequips_item ( id , player_unequip_item , & mut self . entity_gateway , & self . clients , & mut self . item_state ) . await ?
2020-10-06 21:35:20 -03:00
} ,
2020-10-31 01:25:18 -03:00
GameMessage ::SortItems ( sort_items ) = > {
2022-05-15 18:59:49 -06:00
handler ::message ::player_sorts_items ( id , sort_items , & mut self . entity_gateway , & self . clients , & mut self . item_state ) . await ?
2020-10-31 01:25:18 -03:00
} ,
2021-04-20 03:04:54 +00:00
GameMessage ::PlayerSoldItem ( player_sold_item ) = > {
2022-06-21 00:09:52 -06:00
handler ::message ::player_sells_item ( id , player_sold_item , & mut self . entity_gateway , & mut self . clients , & mut self . item_state ) . await ?
2021-04-20 03:04:54 +00:00
} ,
2020-04-22 07:14:59 -06:00
_ = > {
let cmsg = msg . clone ( ) ;
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
Box ::new ( block . client_location . get_client_neighbors ( id ) . unwrap ( ) . into_iter ( )
2020-04-22 07:14:59 -06:00
. map ( move | client | {
( client . client , SendShipPacket ::Message ( cmsg . clone ( ) ) )
2020-11-01 09:04:37 -07:00
} ) )
2020-04-06 23:40:39 -07:00
} ,
2020-11-01 09:04:37 -07:00
} )
2019-12-15 23:20:12 -08:00
}
2020-11-01 09:04:37 -07:00
async fn direct_message ( & mut self , id : ClientId , msg : & DirectMessage ) -> Result < Box < dyn Iterator < Item = ( ClientId , SendShipPacket ) > + Send > , anyhow ::Error > {
2020-04-22 07:14:59 -06:00
let target = msg . flag ;
2020-12-03 15:03:58 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2020-11-01 09:04:37 -07:00
Ok ( match & msg . msg {
2020-03-29 13:27:23 -07:00
GameMessage ::GuildcardSend ( guildcard_send ) = > {
2020-11-24 23:17:42 -07:00
handler ::direct_message ::guildcard_send ( id , guildcard_send , target , & block . client_location , & self . clients )
2020-03-22 22:40:40 -03:00
} ,
2020-04-26 22:01:05 -06:00
GameMessage ::RequestItem ( request_item ) = > {
2022-07-18 20:51:35 -06:00
handler ::direct_message ::request_item ( id , request_item , & mut self . entity_gateway , & block . client_location , & mut self . clients , & mut block . rooms , & mut self . item_state ) . await ?
2020-04-26 22:01:05 -06:00
} ,
2020-05-05 21:53:04 -06:00
GameMessage ::PickupItem ( pickup_item ) = > {
2022-05-01 21:59:34 -06:00
handler ::direct_message ::pickup_item ( id , pickup_item , & mut self . entity_gateway , & block . client_location , & mut self . clients , & mut self . item_state ) . await ?
2020-05-05 21:53:04 -06:00
} ,
2020-05-15 13:37:44 -03:00
GameMessage ::BoxDropRequest ( box_drop_request ) = > {
2022-07-18 20:51:35 -06:00
handler ::direct_message ::request_box_item ( id , box_drop_request , & mut self . entity_gateway , & block . client_location , & mut self . clients , & mut block . rooms , & mut self . item_state ) . await ?
2020-07-19 14:14:07 -06:00
} ,
GameMessage ::BankRequest ( _bank_request ) = > {
2022-05-14 13:06:40 -06:00
handler ::direct_message ::send_bank_list ( id , & self . clients , & mut self . item_state ) . await ?
2020-07-19 14:14:07 -06:00
} ,
GameMessage ::BankInteraction ( bank_interaction ) = > {
2022-05-14 13:06:40 -06:00
handler ::direct_message ::bank_interaction ( id , bank_interaction , & mut self . entity_gateway , & block . client_location , & mut self . clients , & mut self . item_state ) . await ?
2020-09-27 18:16:27 -06:00
} ,
GameMessage ::ShopRequest ( shop_request ) = > {
2020-11-24 23:17:42 -07:00
handler ::direct_message ::shop_request ( id , shop_request , & block . client_location , & mut self . clients , & block . rooms , & self . level_table , & mut self . shops ) . await ?
2020-09-27 18:16:27 -06:00
} ,
GameMessage ::BuyItem ( buy_item ) = > {
2022-06-21 00:09:52 -06:00
handler ::direct_message ::buy_item ( id , buy_item , & mut self . entity_gateway , & block . client_location , & mut self . clients , & mut self . item_state ) . await ?
2020-07-19 14:14:07 -06:00
} ,
2020-12-03 15:04:48 -07:00
GameMessage ::TekRequest ( tek_request ) = > {
handler ::direct_message ::request_tek_item ( id , tek_request , & mut self . entity_gateway , & mut self . clients , & mut self . item_manager ) . await ?
} ,
GameMessage ::TekAccept ( tek_accept ) = > {
handler ::direct_message ::accept_tek_item ( id , tek_accept , & mut self . entity_gateway , & block . client_location , & mut self . clients , & mut self . item_manager ) . await ?
} ,
2021-12-10 13:24:59 -07:00
GameMessage ::TradeRequest ( trade_request ) = > {
2022-07-18 18:42:44 -06:00
handler ::trade ::trade_request ( id , trade_request , target , & block . client_location , & mut self . clients , & mut self . item_state , & mut self . trades ) . await ?
2021-12-10 13:24:59 -07:00
} ,
2020-03-22 22:40:40 -03:00
_ = > {
2020-04-22 07:14:59 -06:00
let cmsg = msg . clone ( ) ;
2020-11-24 23:17:42 -07:00
Box ::new ( block . client_location . get_all_clients_by_client ( id ) . unwrap ( ) . into_iter ( )
2020-04-22 07:14:59 -06:00
. filter ( move | client | client . local_client . id ( ) = = target as u8 )
2020-04-06 23:40:39 -07:00
. map ( move | client | {
( client . client , SendShipPacket ::DirectMessage ( cmsg . clone ( ) ) )
2020-11-01 09:04:37 -07:00
} ) )
2020-03-22 22:40:40 -03:00
} ,
2020-11-01 09:04:37 -07:00
} )
2019-11-24 21:11:52 -08:00
}
2020-03-17 08:02:17 -03:00
}
2019-10-09 22:45:51 -07:00
2020-06-02 18:51:18 -06:00
#[ async_trait::async_trait ]
2019-10-09 22:45:51 -07:00
impl < EG : EntityGateway > ServerState for ShipServerState < EG > {
type SendPacket = SendShipPacket ;
type RecvPacket = RecvShipPacket ;
2020-11-01 09:04:37 -07:00
type PacketError = anyhow ::Error ;
2019-10-09 22:45:51 -07:00
2020-11-01 09:04:37 -07:00
async fn on_connect ( & mut self , _id : ClientId ) -> Result < Vec < OnConnect < Self ::SendPacket > > , anyhow ::Error > {
2019-11-04 20:33:51 -08:00
let mut rng = rand ::thread_rng ( ) ;
let mut server_key = [ 0 u8 ; 48 ] ;
let mut client_key = [ 0 u8 ; 48 ] ;
rng . fill ( & mut server_key [ .. ] ) ;
rng . fill ( & mut client_key [ .. ] ) ;
2020-10-30 21:20:03 -06:00
Ok ( vec! [ OnConnect ::Packet ( SendShipPacket ::ShipWelcome ( ShipWelcome ::new ( server_key , client_key ) ) ) ,
2019-11-04 20:33:51 -08:00
OnConnect ::Cipher ( ( Box ::new ( PSOBBCipher ::new ( ELSEWHERE_PARRAY , ELSEWHERE_PRIVATE_KEY , client_key ) ) ,
Box ::new ( PSOBBCipher ::new ( ELSEWHERE_PARRAY , ELSEWHERE_PRIVATE_KEY , server_key ) ) ) )
2020-10-30 21:20:03 -06:00
] )
2019-10-09 22:45:51 -07:00
}
2020-06-02 18:51:18 -06:00
async fn handle ( & mut self , id : ClientId , pkt : & RecvShipPacket )
2020-11-01 09:04:37 -07:00
-> Result < Box < dyn Iterator < Item = ( ClientId , SendShipPacket ) > + Send > , anyhow ::Error > {
2019-11-04 20:33:51 -08:00
Ok ( match pkt {
RecvShipPacket ::Login ( login ) = > {
2022-05-14 13:06:40 -06:00
Box ::new ( handler ::auth ::validate_login ( id , login , & mut self . entity_gateway , & mut self . clients , & mut self . item_state , & self . shipgate_sender , & self . name , self . blocks . 0. len ( ) )
2020-11-24 23:17:42 -07:00
. await ? . into_iter ( ) . map ( move | pkt | ( id , pkt ) ) )
2019-11-04 20:33:51 -08:00
} ,
2020-05-24 15:59:48 -06:00
RecvShipPacket ::QuestDetailRequest ( questdetailrequest ) = > {
2022-01-27 01:07:19 +00:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2020-05-24 15:59:48 -06:00
match questdetailrequest . menu {
2022-01-27 01:07:19 +00:00
QUEST_SELECT_MENU_ID = > handler ::quest ::quest_detail ( id , questdetailrequest , & block . client_location , & mut block . rooms ) ? ,
2020-05-24 15:59:48 -06:00
_ = > unreachable! ( ) ,
}
} ,
2019-11-16 23:15:25 -08:00
RecvShipPacket ::MenuSelect ( menuselect ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2019-11-16 23:15:25 -08:00
match menuselect . menu {
2020-11-25 22:08:41 -07:00
SHIP_MENU_ID = > {
let leave_lobby = handler ::lobby ::remove_from_lobby ( id , & mut block . client_location ) . into_iter ( ) . into_iter ( ) . flatten ( ) ;
let select_ship = handler ::ship ::selected_ship ( id , menuselect , & self . ship_list ) ? ;
Box ::new ( leave_lobby . chain ( select_ship ) )
}
BLOCK_MENU_ID = > {
let leave_lobby = handler ::lobby ::remove_from_lobby ( id , & mut block . client_location ) . into_iter ( ) . into_iter ( ) . flatten ( ) ;
2022-05-01 21:59:34 -06:00
let select_block = handler ::lobby ::block_selected ( id , menuselect , & mut self . clients , & self . item_state , & self . level_table ) ? . into_iter ( ) ;
2020-11-25 22:08:41 -07:00
Box ::new ( leave_lobby . chain ( select_block ) )
}
2022-05-14 13:06:40 -06:00
ROOM_MENU_ID = > handler ::room ::join_room ( id , menuselect , & mut block . client_location , & mut self . clients , & mut self . item_state , & self . level_table , & mut block . rooms ) ? ,
2022-01-27 01:07:19 +00:00
QUEST_CATEGORY_MENU_ID = > handler ::quest ::select_quest_category ( id , menuselect , & block . client_location , & mut block . rooms ) ? ,
2019-11-16 23:15:25 -08:00
_ = > unreachable! ( ) ,
}
} ,
2020-05-24 15:59:48 -06:00
RecvShipPacket ::QuestMenuSelect ( questmenuselect ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2022-01-27 01:07:19 +00:00
handler ::quest ::player_chose_quest ( id , questmenuselect , & mut self . clients , & block . client_location , & mut block . rooms ) ?
2020-05-24 15:59:48 -06:00
} ,
2022-07-06 22:41:30 +00:00
RecvShipPacket ::MenuDetail ( menudetail ) = > {
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2022-07-07 00:13:33 +00:00
Box ::new ( handler ::lobby ::get_room_tab_info ( id , menudetail , & mut block . client_location , & self . clients , & mut block . rooms ) ? . into_iter ( ) )
2020-05-24 15:59:48 -06:00
} ,
2020-04-27 21:59:15 -03:00
RecvShipPacket ::RoomPasswordReq ( room_password_req ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
if room_password_req . password = = block . rooms [ room_password_req . item as usize ] . as_ref ( )
2020-04-29 00:45:48 -03:00
. ok_or ( ShipError ::InvalidRoom ( room_password_req . item ) ) ?
. password {
2020-11-24 23:17:42 -07:00
let menuselect = MenuSelect {
menu : room_password_req . menu ,
item : room_password_req . item ,
} ;
2022-05-14 13:06:40 -06:00
handler ::room ::join_room ( id , & menuselect , & mut block . client_location , & mut self . clients , & mut self . item_state , & self . level_table , & mut block . rooms ) ?
2020-11-24 23:17:42 -07:00
}
2020-04-27 21:59:15 -03:00
else {
Box ::new ( vec! [ ( id , SendShipPacket ::SmallDialog ( SmallDialog ::new ( " Incorrect password " . into ( ) ) ) ) ] . into_iter ( ) )
}
} ,
2019-11-16 23:15:25 -08:00
RecvShipPacket ::CharData ( chardata ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2022-05-14 13:06:40 -06:00
Box ::new ( handler ::lobby ::send_player_to_lobby ( id , chardata , & mut block . client_location , & self . clients , & self . item_state , & self . level_table ) ? . into_iter ( ) )
2019-11-24 21:11:52 -08:00
} ,
RecvShipPacket ::Message ( msg ) = > {
2020-06-02 18:51:18 -06:00
self . message ( id , msg ) . await ?
2019-12-15 23:20:12 -08:00
} ,
RecvShipPacket ::DirectMessage ( msg ) = > {
2020-06-02 18:51:18 -06:00
self . direct_message ( id , msg ) . await ?
2019-12-15 23:20:12 -08:00
} ,
2019-12-26 18:47:00 -04:00
RecvShipPacket ::PlayerChat ( msg ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2021-06-18 17:38:36 -06:00
Box ::new ( handler ::communication ::player_chat ( id , msg , & block . client_location , & self . clients ) ? )
2019-12-26 18:47:00 -04:00
} ,
2020-01-02 20:29:28 -08:00
RecvShipPacket ::CreateRoom ( create_room ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2022-05-14 13:06:40 -06:00
handler ::room ::create_room ( id , create_room , & mut block . client_location , & mut self . clients , & mut self . item_state , & self . level_table , & mut block . rooms ) ?
2020-01-13 20:20:47 -08:00
} ,
RecvShipPacket ::RoomNameRequest ( _req ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
handler ::room ::room_name_request ( id , & block . client_location , & block . rooms )
2020-02-24 21:17:59 -04:00
} ,
RecvShipPacket ::UpdateConfig ( pkt ) = > {
2020-06-02 18:51:18 -06:00
handler ::settings ::update_config ( id , pkt , & mut self . clients , & mut self . entity_gateway ) . await
2020-02-24 21:17:59 -04:00
} ,
2020-05-03 14:30:10 -03:00
RecvShipPacket ::ViewInfoboardRequest ( _pkt ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
handler ::communication ::request_infoboard ( id , & block . client_location , & self . clients )
2020-03-01 02:57:18 -04:00
} ,
2020-02-27 23:58:00 -04:00
RecvShipPacket ::WriteInfoboard ( pkt ) = > {
2020-06-02 18:51:18 -06:00
handler ::communication ::write_infoboard ( id , pkt , & mut self . clients , & mut self . entity_gateway ) . await
2020-02-27 23:58:00 -04:00
} ,
2020-03-18 21:46:13 -03:00
RecvShipPacket ::RoomListRequest ( _req ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
handler ::room ::request_room_list ( id , & block . client_location , & block . rooms )
2020-03-17 08:02:17 -03:00
} ,
2020-04-21 07:28:14 -06:00
RecvShipPacket ::Like62ButCooler ( cool62 ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
handler ::room ::cool_62 ( id , cool62 , & block . client_location )
2020-04-21 07:28:14 -06:00
} ,
RecvShipPacket ::ClientCharacterData ( _ ) = > {
// TOOD: validate this in some way?
Box ::new ( None . into_iter ( ) )
} ,
RecvShipPacket ::DoneBursting ( _ ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
handler ::room ::done_bursting ( id , & block . client_location , & mut block . rooms )
2020-04-27 20:17:35 -04:00
} ,
2020-05-24 15:59:48 -06:00
RecvShipPacket ::DoneBursting2 ( _ ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
handler ::room ::done_bursting ( id , & block . client_location , & mut block . rooms )
2020-05-24 15:59:48 -06:00
} ,
2020-04-27 20:17:35 -04:00
RecvShipPacket ::LobbySelect ( pkt ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2022-05-14 13:06:40 -06:00
Box ::new ( handler ::lobby ::change_lobby ( id , pkt . lobby , & mut block . client_location , & self . clients , & mut self . item_state , & self . level_table , & mut block . rooms , & mut self . entity_gateway ) . await ? . into_iter ( ) )
2020-05-24 15:59:48 -06:00
} ,
2022-02-06 21:53:11 +00:00
RecvShipPacket ::RequestQuestList ( rql ) = > {
2022-01-27 01:07:19 +00:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2022-02-06 21:53:11 +00:00
handler ::quest ::send_quest_category_list ( id , rql , & block . client_location , & mut block . rooms ) ?
2020-05-24 15:59:48 -06:00
} ,
RecvShipPacket ::QuestFileRequest ( quest_file_request ) = > {
2022-01-27 01:07:19 +00:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
handler ::quest ::quest_file_request ( id , quest_file_request , & block . client_location , & mut block . rooms ) ?
2020-05-24 15:59:48 -06:00
} ,
RecvShipPacket ::QuestChunkAck ( quest_chunk_ack ) = > {
2022-01-27 01:07:19 +00:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
handler ::quest ::quest_chunk_ack ( id , quest_chunk_ack , & block . client_location , & mut block . rooms ) ?
2020-05-24 15:59:48 -06:00
} ,
RecvShipPacket ::DoneLoadingQuest ( _ ) = > {
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
handler ::quest ::done_loading_quest ( id , & mut self . clients , & block . client_location ) ?
2020-05-24 15:59:48 -06:00
} ,
2020-10-26 00:02:48 -06:00
RecvShipPacket ::FullCharacterData ( _full_character_data ) = > {
2020-10-01 16:58:16 -06:00
Box ::new ( None . into_iter ( ) )
} ,
2020-10-02 21:24:32 -03:00
RecvShipPacket ::SaveOptions ( save_options ) = > {
handler ::settings ::save_options ( id , save_options , & mut self . clients , & mut self . entity_gateway ) . await
} ,
2020-11-21 23:45:27 -07:00
RecvShipPacket ::RequestShipList ( _ ) = > {
handler ::ship ::ship_list ( id , & self . ship_list )
} ,
RecvShipPacket ::RequestShipBlockList ( _ ) = > {
2020-11-25 22:08:41 -07:00
handler ::ship ::block_list ( id , & self . name , self . blocks . 0. len ( ) )
2020-12-12 19:55:27 -07:00
} ,
RecvShipPacket ::ItemsToTrade ( items_to_trade ) = > {
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2022-07-18 18:42:44 -06:00
handler ::trade ::items_to_trade ( id , items_to_trade , & block . client_location , & mut self . clients , & mut self . item_state , & mut self . trades ) . await ?
2020-12-12 19:55:27 -07:00
} ,
RecvShipPacket ::TradeConfirmed ( _ ) = > {
let block = self . blocks . with_client ( id , & self . clients ) ? ;
2022-07-18 18:42:44 -06:00
handler ::trade ::trade_confirmed ( id , & mut self . entity_gateway , & block . client_location , & mut self . clients , & mut self . item_state , & mut self . trades ) . await ?
2020-12-12 19:55:27 -07:00
} ,
2022-01-05 22:57:15 +00:00
RecvShipPacket ::KeyboardConfig ( keyboard_config ) = > {
handler ::settings ::keyboard_config ( id , keyboard_config , & mut self . clients , & mut self . entity_gateway ) . await
} ,
RecvShipPacket ::GamepadConfig ( gamepad_config ) = > {
handler ::settings ::gamepad_config ( id , gamepad_config , & mut self . clients , & mut self . entity_gateway ) . await
} ,
2019-11-04 20:33:51 -08:00
} )
2019-10-09 22:45:51 -07:00
}
2020-01-08 22:02:51 -08:00
2020-11-01 09:04:37 -07:00
async fn on_disconnect ( & mut self , id : ClientId ) -> Result < Vec < ( ClientId , SendShipPacket ) > , anyhow ::Error > {
2020-10-30 23:09:01 -06:00
let client = self . clients . get ( & id ) . ok_or ( ShipError ::ClientNotFound ( id ) ) ? ;
2020-11-24 23:17:42 -07:00
let block = self . blocks . with_client ( id , & self . clients ) ? ;
let area_client = block . client_location . get_local_client ( id ) ? ;
let neighbors = block . client_location . get_client_neighbors ( id ) ? ;
2020-04-06 23:40:39 -07:00
2020-11-24 23:17:42 -07:00
let pkt = match block . client_location . get_area ( id ) ? {
2020-04-06 23:40:39 -07:00
RoomLobby ::Room ( room ) = > {
2021-06-18 17:38:36 -06:00
if neighbors . is_empty ( ) {
2020-11-24 23:17:42 -07:00
block . rooms [ room . 0 ] = None ;
2020-04-30 19:30:17 -03:00
}
2020-11-24 23:17:42 -07:00
let leader = block . client_location . get_room_leader ( room ) ? ;
2020-05-13 22:32:30 -06:00
SendShipPacket ::LeaveRoom ( LeaveRoom ::new ( area_client . local_client . id ( ) , leader . local_client . id ( ) ) )
2020-04-06 23:40:39 -07:00
} ,
RoomLobby ::Lobby ( lobby ) = > {
2020-11-24 23:17:42 -07:00
let leader = block . client_location . get_lobby_leader ( lobby ) ? ;
2020-05-13 22:32:30 -06:00
SendShipPacket ::LeaveLobby ( LeaveLobby ::new ( area_client . local_client . id ( ) , leader . local_client . id ( ) ) )
2020-04-06 23:40:39 -07:00
}
2020-01-11 01:08:05 -08:00
} ;
2020-11-18 18:56:04 -07:00
if let Some ( shipgate_sender ) = self . shipgate_sender . as_ref ( ) {
2021-06-18 17:38:36 -06:00
shipgate_sender ( ShipMessage ::RemoveUser ( client . user . id ) ) ;
2020-11-18 18:56:04 -07:00
}
2020-11-24 23:17:42 -07:00
block . client_location . remove_client_from_area ( id ) ;
2022-05-14 13:06:40 -06:00
self . item_state . remove_character_from_room ( & client . character ) ;
2020-04-06 23:40:39 -07:00
2020-10-27 22:31:54 -06:00
if let Some ( mut client ) = self . clients . remove ( & id ) {
client . user . at_ship = false ;
self . entity_gateway . save_user ( & client . user ) . await ;
}
2020-10-30 21:20:03 -06:00
Ok ( neighbors . into_iter ( ) . map ( | n | {
2020-04-06 23:40:39 -07:00
( n . client , pkt . clone ( ) )
2020-10-30 21:20:03 -06:00
} ) . collect ( ) )
2020-01-08 22:02:51 -08:00
}
2019-11-04 20:33:51 -08:00
}
2020-08-19 21:21:09 -06:00
#[ async_trait::async_trait ]
impl < EG : EntityGateway > InterserverActor for ShipServerState < EG > {
type SendMessage = ShipMessage ;
type RecvMessage = LoginMessage ;
type Error = ( ) ;
async fn on_connect ( & mut self , id : ServerId ) -> Vec < ( ServerId , Self ::SendMessage ) > {
2020-11-01 07:49:04 -07:00
vec! [
( id , ShipMessage ::Authenticate ( self . auth_token . clone ( ) ) ) ,
( id , ShipMessage ::NewShip ( Ship {
name : self . name . clone ( ) ,
2021-06-18 17:38:36 -06:00
ip : self . ip ,
2020-11-01 07:49:04 -07:00
port : self . port ,
block_count : 2 ,
2020-11-21 23:45:27 -07:00
} ) ) ,
( id , ShipMessage ::RequestShipList )
]
2020-08-19 21:21:09 -06:00
}
2020-11-18 18:56:04 -07:00
async fn action ( & mut self , id : ServerId , msg : Self ::RecvMessage ) -> Result < Vec < ( ServerId , Self ::SendMessage ) > , Self ::Error > {
match msg {
LoginMessage ::SendMail { .. } = > {
Ok ( Vec ::new ( ) )
} ,
LoginMessage ::ShipList { ships } = > {
self . ship_list = ships ;
Ok ( Vec ::new ( ) )
} ,
LoginMessage ::RequestUsers = > {
Ok ( self . clients . iter ( )
. map ( | ( _ , client ) | {
2021-06-18 17:38:36 -06:00
( id , ShipMessage ::AddUser ( client . user . id ) )
2020-11-18 18:56:04 -07:00
} )
. collect ( ) )
}
}
2020-08-19 21:21:09 -06:00
}
2020-10-26 00:02:48 -06:00
async fn on_disconnect ( & mut self , _id : ServerId ) -> Vec < ( ServerId , Self ::SendMessage ) > {
2020-08-19 21:21:09 -06:00
Vec ::new ( )
}
}