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.

683 lines
23 KiB

  1. use std::time::SystemTime;
  2. use elseware::common::serverstate::{ClientId, ServerState};
  3. use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
  4. use elseware::entity::account::{UserAccountEntity, NewUserAccountEntity, NewUserSettingsEntity};
  5. use elseware::entity::character::{CharacterEntity, NewCharacterEntity};
  6. //use elseware::entity::item::{NewItemEntity, ItemDetail, ItemLocation};
  7. use elseware::entity::item;
  8. use elseware::ship::ship::{ShipServerState, RecvShipPacket};
  9. use elseware::ship::items::{ClientItemId, ActiveItemEntityId, HeldItemType, FloorItemType};
  10. use libpso::packet::ship::*;
  11. use libpso::packet::messages::*;
  12. use libpso::packet::login::{Login, Session};
  13. use libpso::{utf8_to_array, utf8_to_utf16_array};
  14. pub fn new_user_character<EG: EntityGateway>(entity_gateway: &mut EG, username: &str, password: &str) -> (UserAccountEntity, CharacterEntity) {
  15. let new_user = NewUserAccountEntity {
  16. username: username.into(),
  17. password: bcrypt::hash(password, 5).unwrap(),
  18. guildcard: 1,
  19. team_id: None,
  20. banned: false,
  21. muted_until: SystemTime::now(),
  22. created_at: SystemTime::now(),
  23. flags: 0,
  24. };
  25. let user = entity_gateway.create_user(new_user).unwrap();
  26. let new_settings = NewUserSettingsEntity::new(user.id);
  27. let _settings = entity_gateway.create_user_settings(new_settings).unwrap();
  28. let new_character = NewCharacterEntity::new(user.id);
  29. let character = entity_gateway.create_character(new_character).unwrap();
  30. (user, character)
  31. }
  32. pub fn log_in_char<EG: EntityGateway>(ship: &mut ShipServerState<EG>, id: ClientId, username: &str, password: &str) {
  33. let username = username.to_string();
  34. let password = password.to_string();
  35. ship.handle(id, &RecvShipPacket::Login(Login {
  36. tag: 0,
  37. guildcard: 0,
  38. version: 0,
  39. unknown1: [0; 6],
  40. team: 0,
  41. username: utf8_to_array!(username, 16),
  42. unknown2: [0; 32],
  43. password: utf8_to_array!(password, 16),
  44. unknown3: [0; 40],
  45. hwinfo: [0; 8],
  46. session: Session::new(),
  47. })).unwrap().for_each(drop);
  48. }
  49. pub fn join_lobby<EG: EntityGateway>(ship: &mut ShipServerState<EG>, id: ClientId) {
  50. ship.handle(id, &RecvShipPacket::CharData(CharData {
  51. _unknown: [0; 0x828]
  52. })).unwrap().for_each(drop);
  53. }
  54. pub fn create_room<EG: EntityGateway>(ship: &mut ShipServerState<EG>, id: ClientId, name: &str, password: &str) {
  55. ship.handle(id, &RecvShipPacket::CreateRoom(CreateRoom {
  56. unknown: [0; 2],
  57. name: utf8_to_utf16_array!(name, 16),
  58. password: utf8_to_utf16_array!(password, 16),
  59. difficulty: 0,
  60. battle: 0,
  61. challenge: 0,
  62. episode: 1,
  63. single_player: 0,
  64. padding: [0; 3],
  65. })).unwrap().for_each(drop);
  66. ship.handle(id, &RecvShipPacket::DoneBursting(DoneBursting {})).unwrap().for_each(drop);
  67. }
  68. pub fn join_room<EG: EntityGateway>(ship: &mut ShipServerState<EG>, id: ClientId, room_id: u32) {
  69. ship.handle(id, &RecvShipPacket::MenuSelect(MenuSelect {
  70. menu: ROOM_MENU_ID,
  71. item: room_id,
  72. })).unwrap().for_each(drop);
  73. }
  74. #[test]
  75. fn test_pick_up_item_stack_of_items_already_in_inventory() {
  76. let mut entity_gateway = InMemoryGateway::new();
  77. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a");
  78. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a");
  79. entity_gateway.create_item(
  80. item::NewItemEntity {
  81. item: item::ItemDetail::Tool(
  82. item::tool::Tool {
  83. tool: item::tool::ToolType::Monomate
  84. }
  85. ),
  86. location: item::ItemLocation::Inventory {
  87. character_id: char1.id,
  88. slot: 0,
  89. equipped: false,
  90. }
  91. });
  92. for (slot, tool) in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter().enumerate() {
  93. for _ in 0..5 {
  94. entity_gateway.create_item(
  95. item::NewItemEntity {
  96. item: item::ItemDetail::Tool(
  97. item::tool::Tool {
  98. tool: tool
  99. }
  100. ),
  101. location: item::ItemLocation::Inventory {
  102. character_id: char2.id,
  103. slot: slot,
  104. equipped: false,
  105. }
  106. });
  107. }
  108. }
  109. let mut ship = ShipServerState::new(entity_gateway.clone());
  110. log_in_char(&mut ship, ClientId(1), "a1", "a");
  111. log_in_char(&mut ship, ClientId(2), "a2", "a");
  112. join_lobby(&mut ship, ClientId(1));
  113. join_lobby(&mut ship, ClientId(2));
  114. create_room(&mut ship, ClientId(1), "room", "");
  115. join_room(&mut ship, ClientId(2), 0);
  116. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  117. client: 0,
  118. target: 0,
  119. unknown1: 0,
  120. area: 0,
  121. item_id: 0x210000,
  122. x: 0.0,
  123. y: 0.0,
  124. z: 0.0,
  125. })))).unwrap().for_each(drop);
  126. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  127. client: 0,
  128. target: 0,
  129. item_id: 0x210000,
  130. area: 0,
  131. unknown: [0; 3]
  132. })))).unwrap().for_each(drop);
  133. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  134. assert!(p1_inventory.count() == 1);
  135. let inventory_item = p1_inventory.slot(0).unwrap();
  136. assert!(inventory_item.entity_id == ActiveItemEntityId::Stacked(vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4), item::ItemEntityId(5), item::ItemEntityId(6)]));
  137. assert!(inventory_item.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 6));
  138. }
  139. #[test]
  140. fn test_pick_up_item_stack_of_items_not_already_held() {
  141. let mut entity_gateway = InMemoryGateway::new();
  142. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a");
  143. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a");
  144. entity_gateway.create_item(
  145. item::NewItemEntity {
  146. item: item::ItemDetail::Tool(
  147. item::tool::Tool {
  148. tool: item::tool::ToolType::Monomate
  149. }
  150. ),
  151. location: item::ItemLocation::Inventory {
  152. character_id: char2.id,
  153. slot: 0,
  154. equipped: false,
  155. }
  156. });
  157. let mut ship = ShipServerState::new(entity_gateway.clone());
  158. log_in_char(&mut ship, ClientId(1), "a1", "a");
  159. log_in_char(&mut ship, ClientId(2), "a2", "a");
  160. join_lobby(&mut ship, ClientId(1));
  161. join_lobby(&mut ship, ClientId(2));
  162. create_room(&mut ship, ClientId(1), "room", "");
  163. join_room(&mut ship, ClientId(2), 0);
  164. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  165. client: 0,
  166. target: 0,
  167. unknown1: 0,
  168. area: 0,
  169. item_id: 0x210000,
  170. x: 0.0,
  171. y: 0.0,
  172. z: 0.0,
  173. })))).unwrap().for_each(drop);
  174. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  175. client: 0,
  176. target: 0,
  177. item_id: 0x210000,
  178. area: 0,
  179. unknown: [0; 3]
  180. })))).unwrap().for_each(drop);
  181. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  182. assert!(p1_inventory.count() == 1);
  183. let inventory_item = p1_inventory.slot(0).unwrap();
  184. assert!(inventory_item.entity_id == ActiveItemEntityId::Stacked(vec![item::ItemEntityId(1)]));
  185. assert!(inventory_item.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 1));
  186. }
  187. #[test]
  188. fn test_pick_up_meseta_when_inventory_full() {
  189. let mut entity_gateway = InMemoryGateway::new();
  190. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a");
  191. let (_user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a");
  192. for slot in 0..30 {
  193. entity_gateway.create_item(
  194. item::NewItemEntity {
  195. item: item::ItemDetail::Weapon(
  196. item::weapon::Weapon {
  197. weapon: item::weapon::WeaponType::Saber,
  198. grind: 0,
  199. special: None,
  200. attrs: [None, None, None],
  201. tekked: true,
  202. }
  203. ),
  204. location: item::ItemLocation::Inventory {
  205. character_id: char1.id,
  206. slot: slot,
  207. equipped: false,
  208. }
  209. });
  210. }
  211. char2.meseta = 300;
  212. entity_gateway.save_character(&char2);
  213. let mut ship = ShipServerState::new(entity_gateway.clone());
  214. log_in_char(&mut ship, ClientId(1), "a1", "a");
  215. log_in_char(&mut ship, ClientId(2), "a2", "a");
  216. join_lobby(&mut ship, ClientId(1));
  217. join_lobby(&mut ship, ClientId(2));
  218. create_room(&mut ship, ClientId(1), "room", "");
  219. join_room(&mut ship, ClientId(2), 0);
  220. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  221. client: 0,
  222. target: 0,
  223. item_id: 0xFFFFFFFF,
  224. map_area: 0,
  225. x: 0.0,
  226. z: 0.0,
  227. })))).unwrap().for_each(drop);
  228. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  229. client: 0,
  230. target: 0,
  231. item_id: 0xFFFFFFFF,
  232. amount: 23,
  233. })))).unwrap().for_each(drop);
  234. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  235. client: 0,
  236. target: 0,
  237. item_id: 0xF0000001,
  238. area: 0,
  239. unknown: [0; 3]
  240. })))).unwrap().for_each(drop);
  241. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  242. assert!(p1_inventory.count() == 30);
  243. let c1 = ship.clients.get(&ClientId(1)).unwrap();
  244. let c2 = ship.clients.get(&ClientId(2)).unwrap();
  245. assert!(c1.character.meseta == 23);
  246. assert!(c2.character.meseta == 277);
  247. }
  248. #[test]
  249. fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() {
  250. let mut entity_gateway = InMemoryGateway::new();
  251. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a");
  252. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a");
  253. for slot in 0..29 {
  254. entity_gateway.create_item(
  255. item::NewItemEntity {
  256. item: item::ItemDetail::Weapon(
  257. item::weapon::Weapon {
  258. weapon: item::weapon::WeaponType::Saber,
  259. grind: 0,
  260. special: None,
  261. attrs: [None, None, None],
  262. tekked: true,
  263. }
  264. ),
  265. location: item::ItemLocation::Inventory {
  266. character_id: char1.id,
  267. slot: slot,
  268. equipped: false,
  269. }
  270. });
  271. }
  272. entity_gateway.create_item(
  273. item::NewItemEntity {
  274. item: item::ItemDetail::Tool(
  275. item::tool::Tool {
  276. tool: item::tool::ToolType::Monomate,
  277. }
  278. ),
  279. location: item::ItemLocation::Inventory {
  280. character_id: char1.id,
  281. slot: 29,
  282. equipped: false,
  283. }
  284. });
  285. entity_gateway.create_item(
  286. item::NewItemEntity {
  287. item: item::ItemDetail::Tool(
  288. item::tool::Tool {
  289. tool: item::tool::ToolType::Monomate,
  290. }
  291. ),
  292. location: item::ItemLocation::Inventory {
  293. character_id: char2.id,
  294. slot: 0,
  295. equipped: false,
  296. }
  297. });
  298. let mut ship = ShipServerState::new(entity_gateway.clone());
  299. log_in_char(&mut ship, ClientId(1), "a1", "a");
  300. log_in_char(&mut ship, ClientId(2), "a2", "a");
  301. join_lobby(&mut ship, ClientId(1));
  302. join_lobby(&mut ship, ClientId(2));
  303. create_room(&mut ship, ClientId(1), "room", "");
  304. join_room(&mut ship, ClientId(2), 0);
  305. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  306. client: 0,
  307. target: 0,
  308. unknown1: 0,
  309. area: 0,
  310. item_id: 0x210000,
  311. x: 0.0,
  312. y: 0.0,
  313. z: 0.0,
  314. })))).unwrap().for_each(drop);
  315. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  316. client: 0,
  317. target: 0,
  318. item_id: 0x210000,
  319. area: 0,
  320. unknown: [0; 3]
  321. })))).unwrap().for_each(drop);
  322. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  323. assert!(p1_inventory.count() == 30);
  324. let monomates = p1_inventory.slot(29).unwrap();
  325. assert!(monomates.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 2));
  326. }
  327. #[test]
  328. fn test_can_not_pick_up_item_when_inventory_full() {
  329. let mut entity_gateway = InMemoryGateway::new();
  330. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a");
  331. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a");
  332. for slot in 0..30 {
  333. entity_gateway.create_item(
  334. item::NewItemEntity {
  335. item: item::ItemDetail::Weapon(
  336. item::weapon::Weapon {
  337. weapon: item::weapon::WeaponType::Saber,
  338. grind: 0,
  339. special: None,
  340. attrs: [None, None, None],
  341. tekked: true,
  342. }
  343. ),
  344. location: item::ItemLocation::Inventory {
  345. character_id: char1.id,
  346. slot: slot,
  347. equipped: false,
  348. }
  349. });
  350. }
  351. entity_gateway.create_item(
  352. item::NewItemEntity {
  353. item: item::ItemDetail::Weapon(
  354. item::weapon::Weapon {
  355. weapon: item::weapon::WeaponType::Handgun,
  356. grind: 0,
  357. special: None,
  358. attrs: [None, None, None],
  359. tekked: true,
  360. }
  361. ),
  362. location: item::ItemLocation::Inventory {
  363. character_id: char2.id,
  364. slot: 0,
  365. equipped: false,
  366. }
  367. }
  368. );
  369. let mut ship = ShipServerState::new(entity_gateway.clone());
  370. log_in_char(&mut ship, ClientId(1), "a1", "a");
  371. log_in_char(&mut ship, ClientId(2), "a2", "a");
  372. join_lobby(&mut ship, ClientId(1));
  373. join_lobby(&mut ship, ClientId(2));
  374. create_room(&mut ship, ClientId(1), "room", "");
  375. join_room(&mut ship, ClientId(2), 0);
  376. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  377. client: 0,
  378. target: 0,
  379. unknown1: 0,
  380. area: 0,
  381. item_id: 0x210000,
  382. x: 0.0,
  383. y: 0.0,
  384. z: 0.0,
  385. })))).unwrap().for_each(drop);
  386. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  387. client: 0,
  388. target: 0,
  389. item_id: 0x210000,
  390. area: 0,
  391. unknown: [0; 3]
  392. })))).unwrap().for_each(drop);
  393. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  394. assert!(p1_inventory.count() == 30);
  395. let floor_item = ship.item_manager.get_floor_item_by_id(&char1, ClientItemId(0x210000)).unwrap();
  396. assert!(floor_item.item_id == ClientItemId(0x210000));
  397. }
  398. #[test]
  399. fn test_can_not_drop_more_meseta_than_is_held() {
  400. let mut entity_gateway = InMemoryGateway::new();
  401. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a");
  402. char1.meseta = 300;
  403. entity_gateway.save_character(&char1);
  404. let mut ship = ShipServerState::new(entity_gateway.clone());
  405. log_in_char(&mut ship, ClientId(1), "a1", "a");
  406. join_lobby(&mut ship, ClientId(1));
  407. create_room(&mut ship, ClientId(1), "room", "");
  408. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  409. client: 0,
  410. target: 0,
  411. item_id: 0xFFFFFFFF,
  412. map_area: 0,
  413. x: 0.0,
  414. z: 0.0,
  415. })))).unwrap().for_each(drop);
  416. let split_attempt = ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  417. client: 0,
  418. target: 0,
  419. item_id: 0xFFFFFFFF,
  420. amount: 301,
  421. }))));
  422. assert!(split_attempt.is_err());
  423. let c1 = ship.clients.get(&ClientId(1)).unwrap();
  424. assert!(c1.character.meseta == 300);
  425. assert!(ship.item_manager.get_floor_item_by_id(&char1, ClientItemId(0xF0000001)).is_err())
  426. }
  427. #[test]
  428. fn test_pick_up_stack_that_would_exceed_stack_limit() {
  429. let mut entity_gateway = InMemoryGateway::new();
  430. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a");
  431. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a");
  432. for _ in 0..6 {
  433. entity_gateway.create_item(
  434. item::NewItemEntity {
  435. item: item::ItemDetail::Tool(
  436. item::tool::Tool {
  437. tool: item::tool::ToolType::Monomate,
  438. }
  439. ),
  440. location: item::ItemLocation::Inventory {
  441. character_id: char1.id,
  442. slot: 0,
  443. equipped: false,
  444. }
  445. });
  446. }
  447. for _ in 0..6 {
  448. entity_gateway.create_item(
  449. item::NewItemEntity {
  450. item: item::ItemDetail::Tool(
  451. item::tool::Tool {
  452. tool: item::tool::ToolType::Monomate,
  453. }
  454. ),
  455. location: item::ItemLocation::Inventory {
  456. character_id: char2.id,
  457. slot: 0,
  458. equipped: false,
  459. }
  460. });
  461. }
  462. let mut ship = ShipServerState::new(entity_gateway.clone());
  463. log_in_char(&mut ship, ClientId(1), "a1", "a");
  464. log_in_char(&mut ship, ClientId(2), "a2", "a");
  465. join_lobby(&mut ship, ClientId(1));
  466. join_lobby(&mut ship, ClientId(2));
  467. create_room(&mut ship, ClientId(1), "room", "");
  468. join_room(&mut ship, ClientId(2), 0);
  469. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  470. client: 0,
  471. target: 0,
  472. unknown1: 0,
  473. area: 0,
  474. item_id: 0x210000,
  475. x: 0.0,
  476. y: 0.0,
  477. z: 0.0,
  478. })))).unwrap().for_each(drop);
  479. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  480. client: 0,
  481. target: 0,
  482. item_id: 0x210000,
  483. area: 0,
  484. unknown: [0; 3]
  485. })))).unwrap().for_each(drop);
  486. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  487. let monomates = p1_inventory.slot(0).unwrap();
  488. assert!(monomates.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 6));
  489. let floor_monomates = ship.item_manager.get_floor_item_by_id(&char1, ClientItemId(0x210000)).unwrap();
  490. assert!(floor_monomates.item == FloorItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 6));
  491. }
  492. #[test]
  493. fn test_can_not_pick_up_meseta_when_full() {
  494. let mut entity_gateway = InMemoryGateway::new();
  495. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a");
  496. let (_user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a");
  497. char1.meseta = 999999;
  498. entity_gateway.save_character(&char1);
  499. char2.meseta = 300;
  500. entity_gateway.save_character(&char2);
  501. let mut ship = ShipServerState::new(entity_gateway.clone());
  502. log_in_char(&mut ship, ClientId(1), "a1", "a");
  503. log_in_char(&mut ship, ClientId(2), "a2", "a");
  504. join_lobby(&mut ship, ClientId(1));
  505. join_lobby(&mut ship, ClientId(2));
  506. create_room(&mut ship, ClientId(1), "room", "");
  507. join_room(&mut ship, ClientId(2), 0);
  508. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  509. client: 0,
  510. target: 0,
  511. item_id: 0xFFFFFFFF,
  512. map_area: 0,
  513. x: 0.0,
  514. z: 0.0,
  515. })))).unwrap().for_each(drop);
  516. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  517. client: 0,
  518. target: 0,
  519. item_id: 0xFFFFFFFF,
  520. amount: 23,
  521. })))).unwrap().for_each(drop);
  522. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  523. client: 0,
  524. target: 0,
  525. item_id: 0xF0000001,
  526. area: 0,
  527. unknown: [0; 3]
  528. })))).unwrap().for_each(drop);
  529. let c1 = ship.clients.get(&ClientId(1)).unwrap();
  530. let c2 = ship.clients.get(&ClientId(2)).unwrap();
  531. assert!(c1.character.meseta == 999999);
  532. assert!(c2.character.meseta == 277);
  533. let floor_meseta = ship.item_manager.get_floor_item_by_id(&char1, ClientItemId(0xF0000001)).unwrap();
  534. assert!(floor_meseta.item == FloorItemType::Meseta(item::Meseta(23)));
  535. }
  536. #[test]
  537. fn test_meseta_caps_at_999999_when_trying_to_pick_up_more() {
  538. let mut entity_gateway = InMemoryGateway::new();
  539. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a");
  540. let (_user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a");
  541. char1.meseta = 999998;
  542. entity_gateway.save_character(&char1);
  543. char2.meseta = 300;
  544. entity_gateway.save_character(&char2);
  545. let mut ship = ShipServerState::new(entity_gateway.clone());
  546. log_in_char(&mut ship, ClientId(1), "a1", "a");
  547. log_in_char(&mut ship, ClientId(2), "a2", "a");
  548. join_lobby(&mut ship, ClientId(1));
  549. join_lobby(&mut ship, ClientId(2));
  550. create_room(&mut ship, ClientId(1), "room", "");
  551. join_room(&mut ship, ClientId(2), 0);
  552. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  553. client: 0,
  554. target: 0,
  555. item_id: 0xFFFFFFFF,
  556. map_area: 0,
  557. x: 0.0,
  558. z: 0.0,
  559. })))).unwrap().for_each(drop);
  560. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  561. client: 0,
  562. target: 0,
  563. item_id: 0xFFFFFFFF,
  564. amount: 23,
  565. })))).unwrap().for_each(drop);
  566. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  567. client: 0,
  568. target: 0,
  569. item_id: 0xF0000001,
  570. area: 0,
  571. unknown: [0; 3]
  572. })))).unwrap().for_each(drop);
  573. let c1 = ship.clients.get(&ClientId(1)).unwrap();
  574. let c2 = ship.clients.get(&ClientId(2)).unwrap();
  575. assert!(c1.character.meseta == 999999);
  576. assert!(c2.character.meseta == 277);
  577. let floor_meseta = ship.item_manager.get_floor_item_by_id(&char1, ClientItemId(0xF0000001));
  578. assert!(floor_meseta.is_err());
  579. }