You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

912 lines
43 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
2 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
4 years ago
4 years ago
2 years ago
2 years ago
2 years ago
5 years ago
2 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
3 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
3 years ago
5 years ago
4 years ago
3 years ago
2 years ago
3 years ago
2 years ago
2 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
2 years ago
2 years ago
3 years ago
5 years ago
4 years ago
3 years ago
5 years ago
5 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
3 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
2 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
4 years ago
5 years ago
5 years ago
2 years ago
2 years ago
2 years ago
3 years ago
5 years ago
5 years ago
3 years ago
4 years ago
3 years ago
  1. #![allow(clippy::type_complexity)]
  2. mod auth;
  3. mod communication;
  4. mod direct_message;
  5. mod lobby;
  6. mod message;
  7. mod room;
  8. mod settings;
  9. mod quest;
  10. mod ship;
  11. pub mod trade;
  12. mod chatcommand;
  13. use std::net::Ipv4Addr;
  14. use async_std::channel;
  15. use async_std::sync::{Arc, RwLock};
  16. use rand::Rng;
  17. use thiserror::Error;
  18. use libpso::packet::ship::*;
  19. use libpso::packet::login::{RedirectClient, Login, LoginResponse, ShipList};
  20. use libpso::packet::messages::*;
  21. use libpso::{PacketParseError, PSOPacket};
  22. use libpso::crypto::bb::PSOBBCipher;
  23. use libpso::packet::ship::{BLOCK_MENU_ID, ROOM_MENU_ID};
  24. use networking::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY};
  25. use networking::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId};
  26. use networking::interserver::{AuthToken, Ship, ServerId, InterserverActor, LoginMessage, ShipMessage};
  27. use pktbuilder::ship::SHIP_MENU_ID;
  28. use entity::gateway::{EntityGateway, GatewayError};
  29. use entity::character::SectionID;
  30. use entity::room::RoomNote;
  31. use location::{ClientLocation, RoomLobby, ClientLocationError, RoomId};
  32. use drops::{DropTable, StandardDropTable};
  33. use ::room::{Rooms, RoomCreationError};
  34. use maps::room::{RoomMode, Episode, Difficulty};
  35. use quests::{load_standard_quests, load_government_quests};
  36. use quests::{QuestList, QuestLoadError};
  37. use maps::Holiday;
  38. use maps::area::MapAreaError;
  39. use maps::maps::{Maps, MapsError, generate_free_roam_maps};
  40. use shops::{ItemShops, StandardItemShops};
  41. use ::trade::{TradeState, TradeStateError};
  42. use pktbuilder::quest::{QUEST_CATEGORY_MENU_ID, QUEST_SELECT_MENU_ID};
  43. pub use client::{Clients, ClientState};
  44. pub const SHIP_PORT: u16 = 23423;
  45. #[derive(Error, Debug)]
  46. pub enum ShipError {
  47. #[error("client not found {0}")]
  48. ClientNotFound(ClientId),
  49. #[error("no character in slot {0} {1}")]
  50. NoCharacterInSlot(ClientId, u32),
  51. #[error("invalid slot {0} {1}")]
  52. InvalidSlot(ClientId, u32),
  53. #[error("too many clients")]
  54. TooManyClients,
  55. #[error("client location {0}")]
  56. ClientLocationError(ClientLocationError),
  57. #[error("maps error {0}")]
  58. MapsError(#[from] MapsError),
  59. #[error("map area error {0}")]
  60. MapAreaError(#[from] MapAreaError),
  61. #[error("invalid room {0}")]
  62. InvalidRoom(u32),
  63. #[error("monster already droppped item {0} {1}")]
  64. MonsterAlreadyDroppedItem(ClientId, u16),
  65. #[error("slice error {0}")]
  66. SliceError(#[from] std::array::TryFromSliceError),
  67. #[error("item error")]
  68. ItemError, // TODO: refine this
  69. #[error("pick up invalid item id {0}")]
  70. PickUpInvalidItemId(u32),
  71. #[error("drop invalid item id {0}")]
  72. DropInvalidItemId(u32),
  73. #[error("item state error {0}")]
  74. ItemStateError(#[from] items::state::ItemStateError),
  75. #[error("item drop location not set")]
  76. ItemDropLocationNotSet,
  77. #[error("box already dropped item {0} {1}")]
  78. BoxAlreadyDroppedItem(ClientId, u16),
  79. #[error("invalid quest category {0}")]
  80. InvalidQuestCategory(u16),
  81. #[error("invalid quest {0}")]
  82. InvalidQuest(u16),
  83. #[error("invalid quest filename {0}")]
  84. InvalidQuestFilename(String),
  85. #[error("io error {0}")]
  86. IoError(#[from] std::io::Error),
  87. #[error("not enough meseta {0} {1}")]
  88. NotEnoughMeseta(ClientId, u32),
  89. #[error("shop error")]
  90. ShopError,
  91. #[error("gateway error {0}")]
  92. GatewayError(#[from] GatewayError),
  93. #[error("unknown monster {0}")]
  94. UnknownMonster(maps::monster::MonsterType),
  95. #[error("invalid ship {0}")]
  96. InvalidShip(usize),
  97. #[error("invalid block {0}")]
  98. InvalidBlock(usize),
  99. #[error("invalid item {0}")]
  100. InvalidItem(items::ClientItemId),
  101. #[error("trade error {0}")]
  102. TradeError(#[from] trade::TradeError),
  103. #[error("trade state error {0}")]
  104. TradeStateError(#[from] TradeStateError),
  105. #[error("message error {0}")]
  106. MessageError(#[from] crate::direct_message::MessageError),
  107. #[error("room creation error {0}")]
  108. RoomCreationError(#[from] RoomCreationError),
  109. #[error("channel send error {0}")]
  110. SendError(#[from] async_std::channel::SendError<ShipMessage>),
  111. }
  112. /*
  113. impl<I: Into<ClientLocationError>> From<I> for ShipError {
  114. fn from(other: I) -> ShipError {
  115. ShipError::ClientLocationError(other.into())
  116. }
  117. }
  118. */
  119. #[derive(Debug)]
  120. pub enum RecvShipPacket {
  121. Login(Login),
  122. MenuSelect(MenuSelect),
  123. RoomPasswordReq(RoomPasswordReq),
  124. CharData(CharData),
  125. Message(Message),
  126. DirectMessage(DirectMessage),
  127. PlayerChat(PlayerChat),
  128. CreateRoom(CreateRoom),
  129. RoomNameRequest(RoomNameRequest),
  130. ViewInfoboardRequest(ViewInfoboardRequest),
  131. WriteInfoboard(WriteInfoboard),
  132. RoomListRequest(RoomListRequest),
  133. Like62ButCooler(Like62ButCooler),
  134. ClientCharacterData(ClientCharacterData),
  135. DoneBursting(DoneBursting),
  136. DoneBursting2(DoneBursting2),
  137. LobbySelect(LobbySelect),
  138. RequestQuestList(RequestQuestList),
  139. MenuDetail(MenuDetail),
  140. QuestDetailRequest(QuestDetailRequest),
  141. QuestMenuSelect(QuestMenuSelect),
  142. QuestFileRequest(QuestFileRequest),
  143. QuestChunkAck(QuestChunkAck),
  144. DoneLoadingQuest(DoneLoadingQuest),
  145. FullCharacterData(Box<FullCharacterData>),
  146. SaveOptions(SaveOptions),
  147. RequestShipList(RequestShipList),
  148. RequestShipBlockList(RequestShipBlockList),
  149. ItemsToTrade(ItemsToTrade),
  150. TradeConfirmed(TradeConfirmed),
  151. KeyboardConfig(KeyboardConfig),
  152. GamepadConfig(GamepadConfig),
  153. UpdateConfig(UpdateConfig),
  154. UpdateTechMenu(UpdateTechMenu),
  155. }
  156. impl RecvServerPacket for RecvShipPacket {
  157. fn from_bytes(data: &[u8]) -> Result<RecvShipPacket, PacketParseError> {
  158. match u16::from_le_bytes([data[2], data[3]]) {
  159. 0x93 => Ok(RecvShipPacket::Login(Login::from_bytes(data)?)),
  160. 0x09 => match data[8] as u32 {
  161. QUEST_SELECT_MENU_ID => Ok(RecvShipPacket::QuestDetailRequest(QuestDetailRequest::from_bytes(data)?)),
  162. _ => Ok(RecvShipPacket::MenuDetail(MenuDetail::from_bytes(data)?)),
  163. }
  164. 0x10 => match (data[0], data[8] as u32) {
  165. (16, QUEST_SELECT_MENU_ID) => Ok(RecvShipPacket::QuestMenuSelect(QuestMenuSelect::from_bytes(data)?)),
  166. (16, _) => Ok(RecvShipPacket::MenuSelect(MenuSelect::from_bytes(data)?)),
  167. (48, _) => Ok(RecvShipPacket::RoomPasswordReq(RoomPasswordReq::from_bytes(data)?)),
  168. _ => Err(PacketParseError::WrongPacketForServerType(u16::from_le_bytes([data[2], data[3]]), data.to_vec())),
  169. },
  170. 0x13 => Ok(RecvShipPacket::QuestChunkAck(QuestChunkAck::from_bytes(data)?)),
  171. 0x44 => Ok(RecvShipPacket::QuestFileRequest(QuestFileRequest::from_bytes(data)?)),
  172. 0x61 => Ok(RecvShipPacket::CharData(CharData::from_bytes(data)?)),
  173. 0x60 => Ok(RecvShipPacket::Message(Message::from_bytes(data)?)),
  174. 0x62 => Ok(RecvShipPacket::DirectMessage(DirectMessage::from_bytes(data)?)),
  175. 0x06 => Ok(RecvShipPacket::PlayerChat(PlayerChat::from_bytes(data)?)),
  176. 0xC1 => Ok(RecvShipPacket::CreateRoom(CreateRoom::from_bytes(data)?)),
  177. 0x8A => Ok(RecvShipPacket::RoomNameRequest(RoomNameRequest::from_bytes(data)?)),
  178. 0xD8 => Ok(RecvShipPacket::ViewInfoboardRequest(ViewInfoboardRequest::from_bytes(data)?)),
  179. 0xD9 => Ok(RecvShipPacket::WriteInfoboard(WriteInfoboard::from_bytes(data)?)),
  180. 0x08 => Ok(RecvShipPacket::RoomListRequest(RoomListRequest::from_bytes(data)?)),
  181. 0x6D => Ok(RecvShipPacket::Like62ButCooler(Like62ButCooler::from_bytes(data)?)),
  182. 0x98 => Ok(RecvShipPacket::ClientCharacterData(ClientCharacterData::from_bytes(data)?)),
  183. 0x6F => Ok(RecvShipPacket::DoneBursting(DoneBursting::from_bytes(data)?)),
  184. 0x16F => Ok(RecvShipPacket::DoneBursting2(DoneBursting2::from_bytes(data)?)),
  185. 0x84 => Ok(RecvShipPacket::LobbySelect(LobbySelect::from_bytes(data)?)),
  186. 0xA0 => Ok(RecvShipPacket::RequestShipList(RequestShipList::from_bytes(data)?)),
  187. 0xA1 => Ok(RecvShipPacket::RequestShipBlockList(RequestShipBlockList::from_bytes(data)?)),
  188. 0xA2 => Ok(RecvShipPacket::RequestQuestList(RequestQuestList::from_bytes(data)?)),
  189. 0xAC => Ok(RecvShipPacket::DoneLoadingQuest(DoneLoadingQuest::from_bytes(data)?)),
  190. 0xD0 => Ok(RecvShipPacket::ItemsToTrade(ItemsToTrade::from_bytes(data)?)),
  191. 0xD2 => Ok(RecvShipPacket::TradeConfirmed(TradeConfirmed::from_bytes(data)?)),
  192. 0xE7 => Ok(RecvShipPacket::FullCharacterData(Box::new(FullCharacterData::from_bytes(data)?))),
  193. 0x1ED => Ok(RecvShipPacket::SaveOptions(SaveOptions::from_bytes(data)?)),
  194. 0x4ED => Ok(RecvShipPacket::KeyboardConfig(KeyboardConfig::from_bytes(data)?)),
  195. 0x5ED => Ok(RecvShipPacket::GamepadConfig(GamepadConfig::from_bytes(data)?)),
  196. 0x6ED => Ok(RecvShipPacket::UpdateTechMenu(UpdateTechMenu::from_bytes(data)?)),
  197. 0x7ED => Ok(RecvShipPacket::UpdateConfig(UpdateConfig::from_bytes(data)?)),
  198. _ => Err(PacketParseError::WrongPacketForServerType(u16::from_le_bytes([data[2], data[3]]), data.to_vec()))
  199. }
  200. }
  201. }
  202. #[derive(Debug, Clone, PartialEq)]
  203. pub enum SendShipPacket {
  204. ShipWelcome(ShipWelcome),
  205. LoginResponse(LoginResponse),
  206. ShipList(ShipList),
  207. ShipBlockList(ShipBlockList),
  208. FullCharacter(Box<FullCharacter>),
  209. CharDataRequest(CharDataRequest),
  210. JoinLobby(JoinLobby),
  211. AddToLobby(AddToLobby),
  212. Message(Message),
  213. DirectMessage(DirectMessage),
  214. PlayerChat(PlayerChat),
  215. SmallDialog(SmallDialog),
  216. SmallLeftDialog(SmallLeftDialog),
  217. JoinRoom(JoinRoom),
  218. AddToRoom(AddToRoom),
  219. LeaveLobby(LeaveLobby),
  220. LeaveRoom(LeaveRoom),
  221. RoomNameResponse(RoomNameResponse),
  222. ViewInfoboardResponse(ViewInfoboardResponse),
  223. RoomListResponse(RoomListResponse),
  224. Like62ButCooler(Like62ButCooler),
  225. BurstDone72(BurstDone72),
  226. DoneBursting(DoneBursting),
  227. DoneBursting2(DoneBursting2),
  228. LobbyList(LobbyList),
  229. QuestCategoryList(QuestCategoryList),
  230. QuestOptionList(QuestOptionList),
  231. QuestDetail(QuestDetail),
  232. QuestHeader(QuestHeader),
  233. QuestChunk(QuestChunk),
  234. DoneLoadingQuest(DoneLoadingQuest),
  235. BankItemList(BankItemList),
  236. RedirectClient(RedirectClient),
  237. RareMonsterList(RareMonsterList),
  238. AcknowledgeTrade(AcknowledgeTrade),
  239. CancelTrade(CancelTrade),
  240. TradeSuccessful(TradeSuccessful),
  241. LobbyEvent(LobbyEvent),
  242. LargeDialog(LargeDialog),
  243. RightText(RightText),
  244. }
  245. impl SendServerPacket for SendShipPacket {
  246. fn as_bytes(&self) -> Vec<u8> {
  247. match self {
  248. SendShipPacket::ShipWelcome(pkt) => pkt.as_bytes(),
  249. SendShipPacket::LoginResponse(pkt) => pkt.as_bytes(),
  250. SendShipPacket::ShipList(pkt) => pkt.as_bytes(),
  251. SendShipPacket::ShipBlockList(pkt) => pkt.as_bytes(),
  252. SendShipPacket::FullCharacter(pkt) => pkt.as_bytes(),
  253. SendShipPacket::CharDataRequest(pkt) => pkt.as_bytes(),
  254. SendShipPacket::JoinLobby(pkt) => pkt.as_bytes(),
  255. SendShipPacket::AddToLobby(pkt) => pkt.as_bytes(),
  256. SendShipPacket::Message(pkt) => pkt.as_bytes(),
  257. SendShipPacket::DirectMessage(pkt) => pkt.as_bytes(),
  258. SendShipPacket::PlayerChat(pkt) => pkt.as_bytes(),
  259. SendShipPacket::SmallDialog(pkt) => pkt.as_bytes(),
  260. SendShipPacket::SmallLeftDialog(pkt) => pkt.as_bytes(),
  261. SendShipPacket::JoinRoom(pkt) => pkt.as_bytes(),
  262. SendShipPacket::AddToRoom(pkt) => pkt.as_bytes(),
  263. SendShipPacket::LeaveLobby(pkt) => pkt.as_bytes(),
  264. SendShipPacket::LeaveRoom(pkt) => pkt.as_bytes(),
  265. SendShipPacket::RoomNameResponse(pkt) => pkt.as_bytes(),
  266. SendShipPacket::ViewInfoboardResponse(pkt) => pkt.as_bytes(),
  267. SendShipPacket::RoomListResponse(pkt) => pkt.as_bytes(),
  268. SendShipPacket::Like62ButCooler(pkt) => pkt.as_bytes(),
  269. SendShipPacket::BurstDone72(pkt) => pkt.as_bytes(),
  270. SendShipPacket::DoneBursting(pkt) => pkt.as_bytes(),
  271. SendShipPacket::DoneBursting2(pkt) => pkt.as_bytes(),
  272. SendShipPacket::LobbyList(pkt) => pkt.as_bytes(),
  273. SendShipPacket::QuestCategoryList(pkt) => pkt.as_bytes(),
  274. SendShipPacket::QuestOptionList(pkt) => pkt.as_bytes(),
  275. SendShipPacket::QuestDetail(pkt) => pkt.as_bytes(),
  276. SendShipPacket::QuestHeader(pkt) => pkt.as_bytes(),
  277. SendShipPacket::QuestChunk(pkt) => pkt.as_bytes(),
  278. SendShipPacket::DoneLoadingQuest(pkt) => pkt.as_bytes(),
  279. SendShipPacket::BankItemList(pkt) => pkt.as_bytes(),
  280. SendShipPacket::RedirectClient(pkt) => pkt.as_bytes(),
  281. SendShipPacket::RareMonsterList(pkt) => pkt.as_bytes(),
  282. SendShipPacket::AcknowledgeTrade(pkt) => pkt.as_bytes(),
  283. SendShipPacket::CancelTrade(pkt) => pkt.as_bytes(),
  284. SendShipPacket::TradeSuccessful(pkt) => pkt.as_bytes(),
  285. SendShipPacket::LobbyEvent(pkt) => pkt.as_bytes(),
  286. SendShipPacket::LargeDialog(pkt) => pkt.as_bytes(),
  287. SendShipPacket::RightText(pkt) => pkt.as_bytes(),
  288. }
  289. }
  290. }
  291. pub struct ShipServerStateBuilder<EG: EntityGateway + Clone + 'static> {
  292. entity_gateway: Option<EG>,
  293. name: Option<String>,
  294. ip: Option<Ipv4Addr>,
  295. port: Option<u16>,
  296. auth_token: Option<AuthToken>,
  297. event: Option<Holiday>,
  298. shops: Option<Box<dyn ItemShops + Send + Sync>>,
  299. map_builder: Option<Box<dyn Fn(RoomMode, Holiday) -> Maps + Send + Sync>>,
  300. drop_table_builder: Option<Box<dyn Fn(Episode, Difficulty, SectionID) -> Box<dyn DropTable + Send + Sync> + Send + Sync>>,
  301. standard_quest_builder: Option<Box<dyn Fn(RoomMode) -> Result<quests::QuestList, QuestLoadError> + Send + Sync>>,
  302. government_quest_builder: Option<Box<dyn Fn(RoomMode) -> Result<quests::QuestList, QuestLoadError> + Send + Sync>>,
  303. num_blocks: usize,
  304. }
  305. impl<EG: EntityGateway + Clone + 'static> Default for ShipServerStateBuilder<EG> {
  306. fn default() -> ShipServerStateBuilder<EG> {
  307. ShipServerStateBuilder {
  308. entity_gateway: None,
  309. name: None,
  310. ip: None,
  311. port: None,
  312. auth_token: None,
  313. event: None,
  314. shops: None,
  315. map_builder: None,
  316. drop_table_builder: None,
  317. standard_quest_builder: None,
  318. government_quest_builder: None,
  319. num_blocks: 2,
  320. }
  321. }
  322. }
  323. impl<EG: EntityGateway + Clone + 'static> ShipServerStateBuilder<EG> {
  324. #[must_use]
  325. pub fn gateway(mut self, entity_gateway: EG) -> ShipServerStateBuilder<EG> {
  326. self.entity_gateway = Some(entity_gateway);
  327. self
  328. }
  329. #[must_use]
  330. pub fn name(mut self, name: String) -> ShipServerStateBuilder<EG> {
  331. self.name = Some(name);
  332. self
  333. }
  334. #[must_use]
  335. pub fn ip(mut self, ip: Ipv4Addr) -> ShipServerStateBuilder<EG> {
  336. self.ip = Some(ip);
  337. self
  338. }
  339. #[must_use]
  340. pub fn port(mut self, port: u16) -> ShipServerStateBuilder<EG> {
  341. self.port = Some(port);
  342. self
  343. }
  344. #[must_use]
  345. pub fn auth_token(mut self, auth_token: AuthToken) -> ShipServerStateBuilder<EG> {
  346. self.auth_token = Some(auth_token);
  347. self
  348. }
  349. #[must_use]
  350. pub fn event(mut self, event: Holiday) -> ShipServerStateBuilder<EG> {
  351. self.event = Some(event);
  352. self
  353. }
  354. #[must_use]
  355. pub fn map_builder(mut self, map_builder: Box<dyn Fn(RoomMode, Holiday) -> Maps + Send + Sync>) -> ShipServerStateBuilder<EG> {
  356. self.map_builder = Some(map_builder);
  357. self
  358. }
  359. #[must_use]
  360. pub fn drop_table_builder(mut self, drop_table_builder: Box<dyn Fn(Episode, Difficulty, SectionID) -> Box<dyn DropTable + Send + Sync> + Send + Sync>) -> ShipServerStateBuilder<EG> {
  361. self.drop_table_builder = Some(drop_table_builder);
  362. self
  363. }
  364. #[must_use]
  365. pub fn standard_quest_builder(mut self, standard_quest_builder: Box<dyn Fn(RoomMode) -> Result<QuestList, QuestLoadError> + Send + Sync>) -> ShipServerStateBuilder<EG> {
  366. self.standard_quest_builder = Some(standard_quest_builder);
  367. self
  368. }
  369. #[must_use]
  370. pub fn government_quest_builder(mut self, government_quest_builder: Box<dyn Fn(RoomMode) -> Result<QuestList, QuestLoadError> + Send + Sync>) -> ShipServerStateBuilder<EG> {
  371. self.government_quest_builder = Some(government_quest_builder);
  372. self
  373. }
  374. #[must_use]
  375. pub fn item_shops(mut self, item_shops: impl ItemShops + Send + Sync + 'static) -> ShipServerStateBuilder<EG> {
  376. self.shops = Some(Box::new(item_shops));
  377. self
  378. }
  379. #[must_use]
  380. pub fn blocks(mut self, num_blocks: usize) -> ShipServerStateBuilder<EG> {
  381. self.num_blocks = num_blocks;
  382. self
  383. }
  384. pub fn build(self) -> ShipServerState<EG> {
  385. 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
  386. ShipServerState {
  387. entity_gateway: self.entity_gateway.unwrap(),
  388. clients: Clients::default(),
  389. name: self.name.unwrap_or_else(|| "NAMENOTSET".into()),
  390. item_state: items::state::ItemState::default(),
  391. ip: self.ip.unwrap_or_else(|| Ipv4Addr::new(127,0,0,1)),
  392. port: self.port.unwrap_or(SHIP_PORT),
  393. shops: Arc::new(self.shops.unwrap_or_else(|| Box::<StandardItemShops>::default())),
  394. blocks: Blocks(blocks),
  395. event: self.event.unwrap_or(Holiday::None),
  396. map_builder: Arc::new(self.map_builder.unwrap_or_else(|| Box::new(generate_free_roam_maps))),
  397. drop_table_builder: Arc::new(self.drop_table_builder.unwrap_or_else(|| Box::new(StandardDropTable::new))),
  398. standard_quest_builder: Arc::new(self.standard_quest_builder.unwrap_or_else(|| Box::new(load_standard_quests))),
  399. government_quest_builder: Arc::new(self.government_quest_builder.unwrap_or_else(|| Box::new(load_government_quests))),
  400. auth_token: self.auth_token.unwrap_or_else(|| AuthToken("".into())),
  401. ship_list: Arc::new(RwLock::new(Vec::new())),
  402. shipgate_sender: None,
  403. trades: Default::default(),
  404. }
  405. }
  406. }
  407. #[derive(Clone, Default)]
  408. pub struct Block {
  409. client_location: ClientLocation,
  410. pub rooms: Rooms,
  411. }
  412. #[derive(Clone)]
  413. pub struct Blocks(pub Vec<Block>);
  414. impl Blocks {
  415. async fn get_from_client(&mut self, id: ClientId, clients: &Clients) -> Result<&mut Block, anyhow::Error> {
  416. let block = clients.with(id, |client| Box::pin(async move {
  417. client.block
  418. })).await?;
  419. self.0
  420. .get_mut(block)
  421. .ok_or_else(|| ShipError::InvalidBlock(block).into())
  422. }
  423. }
  424. #[derive(Clone)]
  425. pub struct ShipServerState<EG: EntityGateway + Clone + 'static> {
  426. pub(crate) entity_gateway: EG,
  427. pub clients: Clients,
  428. name: String,
  429. pub(crate) item_state: items::state::ItemState,
  430. shops: Arc<Box<dyn ItemShops + Send + Sync>>,
  431. pub blocks: Blocks,
  432. event: Holiday,
  433. ip: Ipv4Addr,
  434. port: u16,
  435. auth_token: AuthToken,
  436. ship_list: Arc<RwLock<Vec<Ship>>>,
  437. shipgate_sender: Option<channel::Sender<ShipMessage>>,
  438. trades: TradeState,
  439. map_builder: Arc<Box<dyn Fn(RoomMode, Holiday) -> Maps + Send + Sync>>,
  440. drop_table_builder: Arc<Box<dyn Fn(Episode, Difficulty, SectionID) -> Box<dyn DropTable + Send + Sync> + Send + Sync>>,
  441. standard_quest_builder: Arc<Box<dyn Fn(RoomMode) -> Result<QuestList, QuestLoadError> + Send + Sync>>,
  442. government_quest_builder: Arc<Box<dyn Fn(RoomMode) -> Result<QuestList, QuestLoadError> + Send + Sync>>,
  443. }
  444. impl<EG: EntityGateway + Clone + 'static> ShipServerState<EG> {
  445. pub fn builder() -> ShipServerStateBuilder<EG> {
  446. ShipServerStateBuilder::default()
  447. }
  448. async fn message(&mut self, id: ClientId, msg: Message) -> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
  449. Ok(match msg.msg {
  450. GameMessage::RequestExp(request_exp) => {
  451. let block = self.blocks.get_from_client(id, &self.clients).await?;
  452. message::request_exp(id, request_exp, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms).await?
  453. },
  454. GameMessage::PlayerDropItem(player_drop_item) => {
  455. let block = self.blocks.get_from_client(id, &self.clients).await?;
  456. message::player_drop_item(id, player_drop_item, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms, &mut self.item_state).await?
  457. },
  458. GameMessage::DropCoordinates(drop_coordinates) => {
  459. let block = self.blocks.get_from_client(id, &self.clients).await?;
  460. message::drop_coordinates(id, drop_coordinates, &block.client_location, &self.clients, &block.rooms).await?
  461. },
  462. GameMessage::PlayerNoLongerHasItem(no_longer_has_item) => {
  463. let block = self.blocks.get_from_client(id, &self.clients).await?;
  464. message::no_longer_has_item(id, no_longer_has_item, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await?
  465. },
  466. GameMessage::PlayerChangedMap(_) | GameMessage::PlayerChangedMap2(_) | GameMessage::TellOtherPlayerMyLocation(_) |
  467. GameMessage::PlayerWarpingToFloor(_) | GameMessage::PlayerTeleported(_) | GameMessage::PlayerStopped(_) |
  468. GameMessage::PlayerLoadedIn(_) | GameMessage::PlayerWalking(_) | GameMessage::PlayerRunning(_) |
  469. GameMessage::PlayerWarped(_) | GameMessage::PlayerChangedFloor(_) | GameMessage::InitializeSpeechNpc(_) => {
  470. let block = self.blocks.get_from_client(id, &self.clients).await?;
  471. message::update_player_position(id, msg, &self.clients, &block.client_location, &block.rooms).await?
  472. },
  473. GameMessage::ChargeAttack(charge_attack) => {
  474. let block = self.blocks.get_from_client(id, &self.clients).await?;
  475. message::charge_attack(id, charge_attack, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await?
  476. },
  477. GameMessage::PlayerUseItem(player_use_item) => {
  478. let block = self.blocks.get_from_client(id, &self.clients).await?;
  479. message::player_uses_item(id, player_use_item, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await?
  480. },
  481. GameMessage::PlayerUsedMedicalCenter(player_used_medical_center) => {
  482. let block = self.blocks.get_from_client(id, &self.clients).await?;
  483. message::player_used_medical_center(id, player_used_medical_center, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await?
  484. },
  485. GameMessage::PlayerFeedMag(player_feed_mag) => {
  486. let block = self.blocks.get_from_client(id, &self.clients).await?;
  487. message::player_feed_mag(id, player_feed_mag, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await?
  488. },
  489. GameMessage::PlayerEquipItem(player_equip_item) => {
  490. message::player_equips_item(id, player_equip_item, &mut self.entity_gateway, &self.clients, &mut self.item_state).await?
  491. },
  492. GameMessage::PlayerUnequipItem(player_unequip_item) => {
  493. message::player_unequips_item(id, player_unequip_item, &mut self.entity_gateway, &self.clients, &mut self.item_state).await?
  494. },
  495. GameMessage::SortItems(sort_items) => {
  496. message::player_sorts_items(id, sort_items, &mut self.entity_gateway, &self.clients, &mut self.item_state).await?
  497. },
  498. GameMessage::PlayerSoldItem(player_sold_item) => {
  499. message::player_sells_item(id, player_sold_item, &mut self.entity_gateway, &self.clients, &mut self.item_state).await?
  500. },
  501. GameMessage::FloorItemLimitItemDeletion(floor_item_limit_delete) => {
  502. let block = self.blocks.get_from_client(id, &self.clients).await?;
  503. message::floor_item_limit_deletion(id, floor_item_limit_delete, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms, &mut self.item_state).await?
  504. },
  505. _ => {
  506. let cmsg = msg.clone();
  507. let block = self.blocks.get_from_client(id, &self.clients).await?;
  508. block.client_location.get_client_neighbors(id).await.unwrap().into_iter()
  509. .map(move |client| {
  510. (client.client, SendShipPacket::Message(cmsg.clone()))
  511. })
  512. .collect()
  513. },
  514. })
  515. }
  516. async fn direct_message(&mut self, id: ClientId, msg: DirectMessage) -> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
  517. let target = msg.flag;
  518. let block = self.blocks.get_from_client(id, &self.clients).await?;
  519. Ok(match msg.msg {
  520. GameMessage::GuildcardSend(guildcard_send) => {
  521. direct_message::guildcard_send(id, guildcard_send, target, &block.client_location, &self.clients).await?
  522. },
  523. GameMessage::RequestItem(request_item) => {
  524. direct_message::request_item(id, request_item, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms, &mut self.item_state).await?
  525. },
  526. GameMessage::PickupItem(pickup_item) => {
  527. direct_message::pickup_item(id, pickup_item, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await?
  528. },
  529. GameMessage::BoxDropRequest(box_drop_request) => {
  530. direct_message::request_box_item(id, box_drop_request, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms, &mut self.item_state).await?
  531. },
  532. GameMessage::BankRequest(_bank_request) => {
  533. direct_message::send_bank_list(id, &self.clients, &mut self.item_state).await?
  534. },
  535. GameMessage::BankInteraction(bank_interaction) => {
  536. direct_message::bank_interaction(id, bank_interaction, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await?
  537. },
  538. GameMessage::ShopRequest(shop_request) => {
  539. direct_message::shop_request(id, shop_request, &block.client_location, &self.clients, &block.rooms, &self.shops).await?
  540. },
  541. GameMessage::BuyItem(buy_item) => {
  542. direct_message::buy_item(id, buy_item, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await?
  543. },
  544. GameMessage::TekRequest(tek_request) => {
  545. direct_message::request_tek_item(id, tek_request, &mut self.entity_gateway, &self.clients, &mut self.item_state).await?
  546. },
  547. GameMessage::TekAccept(tek_accept) => {
  548. direct_message::accept_tek_item(id, tek_accept, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await?
  549. },
  550. GameMessage::TradeRequest(trade_request) => {
  551. trade::trade_request(id, trade_request, target, &block.client_location, &self.clients, &mut self.item_state, &mut self.trades).await?
  552. },
  553. _ => {
  554. let cmsg = msg.clone();
  555. block.client_location.get_all_clients_by_client(id).await.unwrap().into_iter()
  556. .filter(move |client| client.local_client.id() == target as u8)
  557. .map(move |client| {
  558. (client.client, SendShipPacket::DirectMessage(cmsg.clone()))
  559. })
  560. .collect()
  561. },
  562. })
  563. }
  564. }
  565. #[async_trait::async_trait]
  566. impl<EG: EntityGateway + Clone> ServerState for ShipServerState<EG> {
  567. type SendPacket = SendShipPacket;
  568. type RecvPacket = RecvShipPacket;
  569. type Cipher = PSOBBCipher;
  570. type PacketError = anyhow::Error;
  571. async fn on_connect(&mut self, _id: ClientId) -> Result<Vec<OnConnect<Self::SendPacket, Self::Cipher>>, anyhow::Error> {
  572. let mut rng = rand::thread_rng();
  573. let mut server_key = [0u8; 48];
  574. let mut client_key = [0u8; 48];
  575. rng.fill(&mut server_key[..]);
  576. rng.fill(&mut client_key[..]);
  577. Ok(vec![OnConnect::Packet(SendShipPacket::ShipWelcome(ShipWelcome::new(server_key, client_key))),
  578. OnConnect::Cipher(PSOBBCipher::new(ELSEWHERE_PARRAY, ELSEWHERE_PRIVATE_KEY, client_key),
  579. PSOBBCipher::new(ELSEWHERE_PARRAY, ELSEWHERE_PRIVATE_KEY, server_key))
  580. ])
  581. }
  582. async fn handle(&mut self, id: ClientId, pkt: RecvShipPacket) -> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
  583. if let Ok((char_id, char_playtime)) = self.clients.with_mut(id, |client| Box::pin(async move {
  584. client.update_playtime();
  585. (client.character.id, client.character.playtime)
  586. })).await {
  587. self.entity_gateway.set_character_playtime(&char_id, char_playtime).await?;
  588. }
  589. Ok(match pkt {
  590. RecvShipPacket::Login(login) => {
  591. 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())
  592. .await?
  593. .into_iter()
  594. .map(move |pkt| (id, pkt))
  595. .collect()
  596. },
  597. RecvShipPacket::QuestDetailRequest(questdetailrequest) => {
  598. let block = self.blocks.get_from_client(id, &self.clients).await?;
  599. match questdetailrequest.menu {
  600. QUEST_SELECT_MENU_ID => quest::quest_detail(id, questdetailrequest, &block.client_location, &block.rooms).await?,
  601. _ => unreachable!(),
  602. }
  603. },
  604. RecvShipPacket::MenuSelect(menuselect) => {
  605. let block = self.blocks.get_from_client(id, &self.clients).await?;
  606. match menuselect.menu {
  607. SHIP_MENU_ID => {
  608. let leave_lobby = lobby::remove_from_lobby(id, &mut block.client_location).await.into_iter().flatten();
  609. let select_ship = ship::selected_ship(id, menuselect, &self.ship_list).await?;
  610. leave_lobby.chain(select_ship).collect()
  611. }
  612. BLOCK_MENU_ID => {
  613. let leave_lobby = lobby::remove_from_lobby(id, &mut block.client_location).await.into_iter().flatten();
  614. let select_block = lobby::block_selected(id, menuselect, &self.clients, &self.item_state).await?.into_iter();
  615. leave_lobby.chain(select_block).collect()
  616. }
  617. ROOM_MENU_ID => room::join_room(id, menuselect, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await?,
  618. QUEST_CATEGORY_MENU_ID => quest::select_quest_category(id, menuselect, &block.client_location, &block.rooms).await?,
  619. _ => unreachable!(),
  620. }
  621. },
  622. RecvShipPacket::QuestMenuSelect(questmenuselect) => {
  623. let block = self.blocks.get_from_client(id, &self.clients).await?;
  624. quest::player_chose_quest(id, questmenuselect, &self.clients, &block.client_location, &block.rooms, self.event).await?
  625. },
  626. RecvShipPacket::MenuDetail(menudetail) => {
  627. let block = self.blocks.get_from_client(id, &self.clients).await?;
  628. lobby::get_room_tab_info(id, menudetail, &mut block.client_location, &self.clients).await?
  629. },
  630. RecvShipPacket::RoomPasswordReq(room_password_req) => {
  631. let block = self.blocks.get_from_client(id, &self.clients).await?;
  632. let room_password = block.rooms.with(RoomId(room_password_req.item as usize), |room| Box::pin(async move {
  633. room.password
  634. })).await?;
  635. if room_password_req.password == room_password {
  636. let menuselect = MenuSelect {
  637. menu: room_password_req.menu,
  638. item: room_password_req.item,
  639. };
  640. room::join_room(id, menuselect, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await?
  641. }
  642. else {
  643. vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("Incorrect password".into())))]
  644. }
  645. },
  646. RecvShipPacket::CharData(chardata) => {
  647. let block = self.blocks.get_from_client(id, &self.clients).await?;
  648. lobby::send_player_to_lobby(id, chardata, &mut block.client_location, &self.clients, &self.item_state, self.event).await?
  649. },
  650. RecvShipPacket::Message(msg) => {
  651. self.message(id, msg).await?
  652. },
  653. RecvShipPacket::DirectMessage(msg) => {
  654. self.direct_message(id, msg).await?
  655. },
  656. RecvShipPacket::PlayerChat(msg) => {
  657. match chatcommand::handle_chat_command(id, msg.clone(), self).await {
  658. Some(ccmd) => {
  659. match ccmd {
  660. Ok(pkts) => pkts,
  661. Err(msg) => vec![(id, SendShipPacket::LargeDialog(LargeDialog::new(msg)))]
  662. }
  663. },
  664. None => {
  665. let block = self.blocks.get_from_client(id, &self.clients).await?;
  666. communication::player_chat(id, msg, &block.client_location, &self.clients).await?
  667. }
  668. }
  669. },
  670. RecvShipPacket::CreateRoom(create_room) => {
  671. let block = self.blocks.get_from_client(id, &self.clients).await?;
  672. room::create_room(id, create_room, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state,
  673. &block.rooms, self.map_builder.clone(), self.drop_table_builder.clone(),
  674. self.standard_quest_builder.clone(), self.government_quest_builder.clone(), self.event).await?
  675. },
  676. RecvShipPacket::RoomNameRequest(_req) => {
  677. let block = self.blocks.get_from_client(id, &self.clients).await?;
  678. room::room_name_request(id, &block.client_location, &block.rooms).await?
  679. },
  680. RecvShipPacket::UpdateTechMenu(pkt) => {
  681. settings::update_tech_menu(id, pkt, &self.clients, &mut self.entity_gateway).await?
  682. },
  683. RecvShipPacket::UpdateConfig(pkt) => {
  684. settings::update_config(id, pkt, &self.clients, &mut self.entity_gateway).await?
  685. },
  686. RecvShipPacket::ViewInfoboardRequest(_pkt) => {
  687. let block = self.blocks.get_from_client(id, &self.clients).await?;
  688. communication::request_infoboard(id, &block.client_location, &self.clients).await?
  689. },
  690. RecvShipPacket::WriteInfoboard(pkt) => {
  691. communication::write_infoboard(id, pkt, &self.clients, &mut self.entity_gateway).await?
  692. },
  693. RecvShipPacket::RoomListRequest(_req) => {
  694. let block = self.blocks.get_from_client(id, &self.clients).await?;
  695. room::request_room_list(id, &block.client_location, &block.rooms).await
  696. },
  697. RecvShipPacket::Like62ButCooler(cool62) => {
  698. let block = self.blocks.get_from_client(id, &self.clients).await?;
  699. room::cool_62(id, cool62, &block.client_location).await?
  700. },
  701. RecvShipPacket::ClientCharacterData(_) => {
  702. // TOOD: validate this in some way?
  703. Vec::new()
  704. },
  705. RecvShipPacket::DoneBursting(_) => {
  706. let block = self.blocks.get_from_client(id, &self.clients).await?;
  707. room::done_bursting(id, &block.client_location, &block.rooms).await?
  708. },
  709. RecvShipPacket::DoneBursting2(_) => {
  710. let block = self.blocks.get_from_client(id, &self.clients).await?;
  711. room::done_bursting(id, &block.client_location, &block.rooms).await?
  712. },
  713. RecvShipPacket::LobbySelect(pkt) => {
  714. let block = self.blocks.get_from_client(id, &self.clients).await?;
  715. lobby::change_lobby(id, pkt.lobby, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, &mut self.entity_gateway, self.event).await?
  716. },
  717. RecvShipPacket::RequestQuestList(rql) => {
  718. let block = self.blocks.get_from_client(id, &self.clients).await?;
  719. quest::send_quest_category_list(id, rql, &block.client_location, &block.rooms).await?
  720. },
  721. RecvShipPacket::QuestFileRequest(quest_file_request) => {
  722. let block = self.blocks.get_from_client(id, &self.clients).await?;
  723. quest::quest_file_request(id, quest_file_request, &block.client_location, &mut block.rooms).await?
  724. },
  725. RecvShipPacket::QuestChunkAck(quest_chunk_ack) => {
  726. let block = self.blocks.get_from_client(id, &self.clients).await?;
  727. quest::quest_chunk_ack(id, quest_chunk_ack, &block.client_location, &block.rooms).await?
  728. },
  729. RecvShipPacket::DoneLoadingQuest(_) => {
  730. let block = self.blocks.get_from_client(id, &self.clients).await?;
  731. quest::done_loading_quest(id, &self.clients, &block.client_location).await?
  732. },
  733. RecvShipPacket::FullCharacterData(_full_character_data) => {
  734. Vec::new()
  735. },
  736. RecvShipPacket::SaveOptions(save_options) => {
  737. settings::save_options(id, save_options, &self.clients, &mut self.entity_gateway).await?
  738. },
  739. RecvShipPacket::RequestShipList(_) => {
  740. ship::ship_list(id, &self.ship_list).await
  741. },
  742. RecvShipPacket::RequestShipBlockList(_) => {
  743. ship::block_list(id, &self.name, self.blocks.0.len())
  744. },
  745. RecvShipPacket::ItemsToTrade(items_to_trade) => {
  746. let block = self.blocks.get_from_client(id, &self.clients).await?;
  747. trade::items_to_trade(id, items_to_trade, &block.client_location, &self.clients, &mut self.item_state, &mut self.trades).await?
  748. },
  749. RecvShipPacket::TradeConfirmed(_) => {
  750. let block = self.blocks.get_from_client(id, &self.clients).await?;
  751. trade::trade_confirmed(id, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state, &mut self.trades).await?
  752. },
  753. RecvShipPacket::KeyboardConfig(keyboard_config) => {
  754. settings::keyboard_config(id, keyboard_config, &self.clients, &mut self.entity_gateway).await?
  755. },
  756. RecvShipPacket::GamepadConfig(gamepad_config) => {
  757. settings::gamepad_config(id, gamepad_config, &self.clients, &mut self.entity_gateway).await?
  758. },
  759. })
  760. }
  761. async fn on_disconnect(&mut self, id: ClientId) -> Result<Vec<(ClientId, SendShipPacket)>, anyhow::Error> {
  762. let block = self.blocks.get_from_client(id, &self.clients).await?;
  763. let area_client = block.client_location.get_local_client(id).await?;
  764. let neighbors = block.client_location.get_client_neighbors(id).await?;
  765. let pkt = match block.client_location.get_area(id).await? {
  766. RoomLobby::Room(room) => {
  767. let character_id = self.clients.with(id, |client| Box::pin(async {
  768. client.character.id
  769. })).await?;
  770. block.rooms.with(room, |room| {
  771. let mut entity_gateway = self.entity_gateway.clone();
  772. Box::pin(async move {
  773. entity_gateway.add_room_note(room.room_id, RoomNote::PlayerJoin {
  774. character_id,
  775. }).await
  776. })}).await??;
  777. if neighbors.is_empty() {
  778. block.rooms.remove(room).await;
  779. }
  780. let leader = block.client_location.get_room_leader(room).await?;
  781. SendShipPacket::LeaveRoom(LeaveRoom::new(area_client.local_client.id(), leader.local_client.id()))
  782. },
  783. RoomLobby::Lobby(lobby) => {
  784. let leader = block.client_location.get_lobby_leader(lobby).await?;
  785. SendShipPacket::LeaveLobby(LeaveLobby::new(area_client.local_client.id(), leader.local_client.id()))
  786. }
  787. };
  788. if let Some(mut client) = self.clients.remove(&id).await {
  789. client.user.at_ship = false;
  790. self.entity_gateway.save_user(&client.user).await?;
  791. if let Some(shipgate_sender) = self.shipgate_sender.as_ref() {
  792. shipgate_sender.send(ShipMessage::RemoveUser(client.user.id)).await?;
  793. }
  794. self.item_state.remove_character_from_room(&client.character).await
  795. }
  796. block.client_location.remove_client_from_area(id).await?;
  797. Ok(neighbors.into_iter().map(|n| {
  798. (n.client, pkt.clone())
  799. }).collect())
  800. }
  801. }
  802. #[async_trait::async_trait]
  803. impl<EG: EntityGateway + Clone> InterserverActor for ShipServerState<EG> {
  804. type SendMessage = ShipMessage;
  805. type RecvMessage = LoginMessage;
  806. type Error = ();
  807. async fn on_connect(&mut self, id: ServerId) -> Vec<(ServerId, Self::SendMessage)> {
  808. vec![
  809. (id, ShipMessage::Authenticate(self.auth_token.clone())),
  810. (id, ShipMessage::NewShip(Ship {
  811. name: self.name.clone(),
  812. ip: self.ip,
  813. port: self.port,
  814. block_count: 2,
  815. })),
  816. (id, ShipMessage::RequestShipList)
  817. ]
  818. }
  819. async fn on_action(&mut self, _id: ServerId, msg: Self::RecvMessage) -> Result<Vec<(ServerId, Self::SendMessage)>, Self::Error> {
  820. match msg {
  821. LoginMessage::SendMail{..} => {
  822. Ok(Vec::new())
  823. },
  824. LoginMessage::ShipList{mut ships} => {
  825. let mut ship_list = self.ship_list
  826. .write()
  827. .await;
  828. ship_list.clear();
  829. ship_list.append(&mut ships);
  830. Ok(Vec::new())
  831. },
  832. LoginMessage::RequestUsers => {
  833. /*
  834. Ok(self.clients.iter()
  835. .map(|(_, client)| {
  836. (id, ShipMessage::AddUser(client.user.id))
  837. })
  838. .collect())
  839. */
  840. // TODO
  841. Ok(Vec::new())
  842. }
  843. }
  844. }
  845. async fn on_disconnect(&mut self, _id: ServerId) -> Vec<(ServerId, Self::SendMessage)> {
  846. Vec::new()
  847. }
  848. async fn set_sender(&mut self, _server_id: ServerId, sender: channel::Sender<Self::SendMessage>) {
  849. self.shipgate_sender = Some(sender);
  850. }
  851. }