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.

787 lines
33 KiB

4 years ago
4 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. use std::collections::BTreeMap;
  2. use std::convert::TryInto;
  3. use futures::future::{Future, BoxFuture};
  4. use crate::entity::account::*;
  5. use crate::entity::character::*;
  6. use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction, GatewayError};
  7. use crate::entity::item::*;
  8. use crate::entity::room::*;
  9. use async_std::sync::{Arc, Mutex};
  10. #[derive(Clone)]
  11. pub struct InMemoryGatewayTransaction {
  12. working_gateway: InMemoryGateway,
  13. original_gateway: InMemoryGateway,
  14. }
  15. fn copy_if_needed<K, V>(working_table: &mut BTreeMap<K, V>, original_table: &BTreeMap<K, V>, key: K) -> Option<()>
  16. where
  17. K: Ord + Copy,
  18. V: Clone,
  19. {
  20. if let std::collections::btree_map::Entry::Vacant(e) = working_table.entry(key) {
  21. e.insert(original_table.get(&key)?.clone());
  22. }
  23. Some(())
  24. }
  25. // functions here have been skipped as they are not used in transactions, add as needed
  26. #[async_trait::async_trait]
  27. impl EntityGateway for InMemoryGatewayTransaction {
  28. type Transaction<'t> = InMemoryGatewayTransaction where Self: 't;
  29. async fn create_user(&mut self, user: NewUserAccountEntity) -> Result<UserAccountEntity, GatewayError> {
  30. self.working_gateway.create_user(user).await
  31. }
  32. async fn get_user_by_id(&mut self, id: UserAccountId) -> Result<UserAccountEntity, GatewayError> {
  33. match self.working_gateway.get_user_by_id(id).await {
  34. Ok(user) => Ok(user),
  35. Err(_) => {
  36. self.original_gateway.get_user_by_id(id).await
  37. }
  38. }
  39. }
  40. async fn get_user_by_name(&mut self, username: String) -> Result<UserAccountEntity, GatewayError> {
  41. match self.working_gateway.get_user_by_name(username.clone()).await {
  42. Ok(user) => Ok(user),
  43. Err(_) => {
  44. self.original_gateway.get_user_by_name(username).await
  45. }
  46. }
  47. }
  48. async fn save_user(&mut self, user: &UserAccountEntity) -> Result<(), GatewayError> {
  49. self.working_gateway.save_user(user).await
  50. }
  51. async fn create_user_settings(&mut self, settings: NewUserSettingsEntity) -> Result<UserSettingsEntity, GatewayError> {
  52. self.working_gateway.create_user_settings(settings).await
  53. }
  54. async fn get_user_settings_by_user(&mut self, user: &UserAccountEntity) -> Result<UserSettingsEntity, GatewayError> {
  55. match self.working_gateway.get_user_settings_by_user(user).await {
  56. Ok(user) => Ok(user),
  57. Err(_) => {
  58. self.original_gateway.get_user_settings_by_user(user).await
  59. }
  60. }
  61. }
  62. async fn save_user_settings(&mut self, settings: &UserSettingsEntity) -> Result<(), GatewayError> {
  63. self.original_gateway.save_user_settings(settings).await
  64. }
  65. async fn save_character(&mut self, char: &CharacterEntity) -> Result<(), GatewayError> {
  66. copy_if_needed(&mut *self.working_gateway.characters.lock().await,
  67. &*self.original_gateway.characters.lock().await,
  68. char.id
  69. );
  70. self.working_gateway.save_character(char).await
  71. }
  72. async fn create_item(&mut self, item: NewItemEntity) -> Result<ItemEntity, GatewayError> {
  73. self.working_gateway.create_item(item).await
  74. }
  75. async fn add_item_note(&mut self, item_id: &ItemEntityId, item_note: ItemNote) -> Result<(), GatewayError> {
  76. self.working_gateway.add_item_note(item_id, item_note).await
  77. }
  78. async fn feed_mag(&mut self, mag_item_id: &ItemEntityId, tool_item_id: &ItemEntityId) -> Result<(), GatewayError> {
  79. self.working_gateway.feed_mag(mag_item_id, tool_item_id).await
  80. }
  81. async fn change_mag_owner(&mut self, mag_item_id: &ItemEntityId, character: &CharacterEntity) -> Result<(), GatewayError> {
  82. self.working_gateway.change_mag_owner(mag_item_id, character).await
  83. }
  84. async fn use_mag_cell(&mut self, mag_item_id: &ItemEntityId, mag_cell_id: &ItemEntityId) -> Result<(), GatewayError> {
  85. self.working_gateway.use_mag_cell(mag_item_id, mag_cell_id).await
  86. }
  87. async fn add_weapon_modifier(&mut self, item_id: &ItemEntityId, modifier: &weapon::WeaponModifier) -> Result<(), GatewayError> {
  88. self.working_gateway.add_weapon_modifier(item_id, modifier).await
  89. }
  90. async fn get_character_inventory(&mut self, char_id: &CharacterEntityId) -> Result<InventoryEntity, GatewayError> {
  91. match self.working_gateway.get_character_inventory(char_id).await {
  92. Ok(inventory) => Ok(inventory),
  93. Err(_) => {
  94. self.original_gateway.get_character_inventory(char_id).await
  95. }
  96. }
  97. }
  98. async fn get_character_bank(&mut self, char_id: &CharacterEntityId, bank_identifier: &BankIdentifier) -> Result<BankEntity, GatewayError> {
  99. match self.working_gateway.get_character_bank(char_id, bank_identifier).await {
  100. Ok(bank) => Ok(bank),
  101. Err(_) => {
  102. self.original_gateway.get_character_bank(char_id, bank_identifier).await
  103. }
  104. }
  105. }
  106. async fn set_character_inventory(&mut self, char_id: &CharacterEntityId, inventory: &InventoryEntity) -> Result<(), GatewayError> {
  107. self.working_gateway.set_character_inventory(char_id, inventory).await
  108. }
  109. async fn set_character_bank(&mut self, char_id: &CharacterEntityId, bank: &BankEntity, bank_identifier: &BankIdentifier) -> Result<(), GatewayError> {
  110. self.working_gateway.set_character_bank(char_id, bank, bank_identifier).await
  111. }
  112. async fn get_character_equips(&mut self, char_id: &CharacterEntityId) -> Result<EquippedEntity, GatewayError> {
  113. match self.working_gateway.get_character_equips(char_id).await {
  114. Ok(equips) => Ok(equips),
  115. Err(_) => {
  116. self.original_gateway.get_character_equips(char_id).await
  117. }
  118. }
  119. }
  120. async fn set_character_equips(&mut self, char_id: &CharacterEntityId, equipped: &EquippedEntity) -> Result<(), GatewayError> {
  121. self.working_gateway.set_character_equips(char_id, equipped).await
  122. }
  123. async fn set_character_meseta(&mut self, char_id: &CharacterEntityId, meseta: Meseta) -> Result<(), GatewayError> {
  124. self.working_gateway.set_character_meseta(char_id, meseta).await
  125. }
  126. async fn get_character_meseta(&mut self, char_id: &CharacterEntityId) -> Result<Meseta, GatewayError> {
  127. match self.working_gateway.get_character_meseta(char_id).await {
  128. Ok(meseta) => Ok(meseta),
  129. Err(_) => {
  130. self.original_gateway.get_character_meseta(char_id).await
  131. }
  132. }
  133. }
  134. async fn set_bank_meseta(&mut self, char_id: &CharacterEntityId, bank_identifier: &BankIdentifier, meseta: Meseta) -> Result<(), GatewayError> {
  135. self.working_gateway.set_bank_meseta(char_id, bank_identifier, meseta).await
  136. }
  137. async fn get_bank_meseta(&mut self, char_id: &CharacterEntityId, bank_identifier: &BankIdentifier) -> Result<Meseta, GatewayError> {
  138. match self.working_gateway.get_bank_meseta(char_id, bank_identifier).await {
  139. Ok(meseta) => Ok(meseta),
  140. Err(_) => {
  141. self.original_gateway.get_bank_meseta(char_id, bank_identifier).await
  142. }
  143. }
  144. }
  145. async fn create_trade(&mut self, char_id1: &CharacterEntityId, char_id2: &CharacterEntityId) -> Result<TradeEntity, GatewayError> {
  146. self.working_gateway.create_trade(char_id1, char_id2).await
  147. }
  148. async fn set_character_playtime(&mut self, char_id: &CharacterEntityId, playtime: u32) -> Result<(), GatewayError> {
  149. copy_if_needed(&mut *self.working_gateway.characters.lock().await,
  150. &*self.original_gateway.characters.lock().await,
  151. *char_id
  152. );
  153. self.working_gateway.set_character_playtime(char_id, playtime).await
  154. }
  155. }
  156. #[async_trait::async_trait]
  157. impl EntityGatewayTransaction for InMemoryGatewayTransaction {
  158. type ParentGateway = InMemoryGatewayTransaction;
  159. fn gateway(&mut self) -> &mut Self::ParentGateway {
  160. self
  161. }
  162. async fn commit(mut self) -> Result<(), GatewayError> {
  163. self.original_gateway.users.lock().await.extend(self.working_gateway.users.lock().await.clone());
  164. self.original_gateway.user_settings.lock().await.extend(self.working_gateway.user_settings.lock().await.clone());
  165. self.original_gateway.characters.lock().await.extend(self.working_gateway.characters.lock().await.clone());
  166. self.original_gateway.character_meseta.lock().await.extend(self.working_gateway.character_meseta.lock().await.clone());
  167. self.original_gateway.bank_meseta.lock().await.extend(self.working_gateway.bank_meseta.lock().await.clone());
  168. self.original_gateway.shared_bank_meseta.lock().await.extend(self.working_gateway.shared_bank_meseta.lock().await.clone());
  169. self.original_gateway.items.lock().await.extend(self.working_gateway.items.lock().await.clone());
  170. self.original_gateway.inventories.lock().await.extend(self.working_gateway.inventories.lock().await.clone());
  171. self.original_gateway.character_banks.lock().await.extend(self.working_gateway.character_banks.lock().await.clone());
  172. self.original_gateway.shared_banks.lock().await.extend(self.working_gateway.shared_banks.lock().await.clone());
  173. self.original_gateway.equips.lock().await.extend(self.working_gateway.equips.lock().await.clone());
  174. self.original_gateway.mag_modifiers.lock().await.extend(self.working_gateway.mag_modifiers.lock().await.clone());
  175. self.original_gateway.weapon_modifiers.lock().await.extend(self.working_gateway.weapon_modifiers.lock().await.clone());
  176. self.original_gateway.trades.lock().await.extend(self.working_gateway.trades.lock().await.clone());
  177. Ok(())
  178. }
  179. }
  180. #[derive(Clone)]
  181. enum InventoryItemElement {
  182. Individual(ItemEntityId),
  183. Stacked(Vec<ItemEntityId>),
  184. }
  185. #[derive(Clone)]
  186. pub struct InMemoryGateway {
  187. users: Arc<Mutex<BTreeMap<UserAccountId, UserAccountEntity>>>,
  188. user_settings: Arc<Mutex<BTreeMap<UserSettingsId, UserSettingsEntity>>>,
  189. characters: Arc<Mutex<BTreeMap<CharacterEntityId, CharacterEntity>>>,
  190. character_meseta: Arc<Mutex<BTreeMap<CharacterEntityId, Meseta>>>,
  191. bank_meseta: Arc<Mutex<BTreeMap<CharacterEntityId, Meseta>>>,
  192. shared_bank_meseta: Arc<Mutex<BTreeMap<(UserAccountId, BankName), Meseta>>>,
  193. items: Arc<Mutex<BTreeMap<ItemEntityId, ItemEntity>>>,
  194. inventories: Arc<Mutex<BTreeMap<CharacterEntityId, Vec<InventoryItemElement>>>>,
  195. character_banks: Arc<Mutex<BTreeMap<CharacterEntityId, BankEntity>>>,
  196. shared_banks: Arc<Mutex<BTreeMap<(UserAccountId, BankName), BankEntity>>>,
  197. equips: Arc<Mutex<BTreeMap<CharacterEntityId, EquippedEntity>>>,
  198. mag_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<mag::MagModifier>>>>,
  199. weapon_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<weapon::WeaponModifier>>>>,
  200. trades: Arc<Mutex<Vec<TradeEntity>>>,
  201. }
  202. impl Default for InMemoryGateway {
  203. fn default() -> InMemoryGateway {
  204. InMemoryGateway {
  205. users: Arc::new(Mutex::new(BTreeMap::new())),
  206. user_settings: Arc::new(Mutex::new(BTreeMap::new())),
  207. characters: Arc::new(Mutex::new(BTreeMap::new())),
  208. character_meseta: Arc::new(Mutex::new(BTreeMap::new())),
  209. bank_meseta: Arc::new(Mutex::new(BTreeMap::new())),
  210. shared_bank_meseta: Arc::new(Mutex::new(BTreeMap::new())),
  211. items: Arc::new(Mutex::new(BTreeMap::new())),
  212. inventories: Arc::new(Mutex::new(BTreeMap::new())),
  213. character_banks: Arc::new(Mutex::new(BTreeMap::new())),
  214. shared_banks: Arc::new(Mutex::new(BTreeMap::new())),
  215. equips: Arc::new(Mutex::new(BTreeMap::new())),
  216. mag_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
  217. weapon_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
  218. trades: Arc::new(Mutex::new(Vec::new())),
  219. }
  220. }
  221. }
  222. fn apply_modifiers(items: &BTreeMap<ItemEntityId, ItemEntity>,
  223. weapon_modifiers: &BTreeMap<ItemEntityId, Vec<weapon::WeaponModifier>>,
  224. mag_modifiers: &BTreeMap<ItemEntityId, Vec<mag::MagModifier>>,
  225. inventory: InventoryEntity ) -> InventoryEntity {
  226. let inventory_items = inventory.items.into_iter()
  227. .map(|item| {
  228. item.map_individual(|mut item| {
  229. item.item = match item.item {
  230. ItemDetail::Weapon(mut weapon) => {
  231. if let Some(weapon_modifiers) = weapon_modifiers.get(&item.id) {
  232. for weapon_modifier in weapon_modifiers.iter() {
  233. weapon.apply_modifier(weapon_modifier);
  234. }
  235. }
  236. ItemDetail::Weapon(weapon)
  237. },
  238. ItemDetail::Mag(mag) => {
  239. let mut mag = mag::Mag::baby_mag(mag.color as u16);
  240. if let Some(mag_modifiers) = mag_modifiers.get(&item.id) {
  241. for mag_modifier in mag_modifiers.iter() {
  242. match mag_modifier {
  243. mag::MagModifier::FeedMag {food} => {
  244. if let Some(mag_feed) = items.get(food) {
  245. if let ItemDetail::Tool(mag_feed) = mag_feed.item {
  246. mag.feed(mag_feed.tool)
  247. }
  248. }
  249. },
  250. mag::MagModifier::OwnerChange(class, section_id) => {
  251. mag.change_owner(*class, *section_id)
  252. },
  253. mag::MagModifier::MagCell(mag_cell_id) => {
  254. if let Some(mag_cell) = items.get(mag_cell_id) {
  255. if let ItemDetail::Tool(mag_cell) = mag_cell.item {
  256. mag.apply_mag_cell(mag_cell.tool.try_into().unwrap()).unwrap()
  257. }
  258. }
  259. },
  260. _ => {}
  261. }
  262. }
  263. }
  264. ItemDetail::Mag(mag)
  265. }
  266. _ => {
  267. item.item
  268. }
  269. };
  270. item
  271. })
  272. })
  273. .collect();
  274. InventoryEntity::new(inventory_items)
  275. }
  276. #[async_trait::async_trait]
  277. impl EntityGateway for InMemoryGateway {
  278. type Transaction<'t> = InMemoryGatewayTransaction where Self: 't;
  279. fn with_transaction<'a, F, Fut, R>(&'a mut self, func: F) -> BoxFuture<'a, Result<R, anyhow::Error>>
  280. where
  281. Fut: Future<Output = Result<(Self::Transaction<'a>, R), anyhow::Error>> + Send + 'a,
  282. F: FnOnce(Self::Transaction<'a>) -> Fut + Send + 'a,
  283. R: Send,
  284. {
  285. Box::pin(async move {
  286. let users = self.users.lock().await.clone();
  287. let user_settings = self.user_settings.lock().await.clone();
  288. let characters = self.characters.lock().await.clone();
  289. let character_meseta = self.character_meseta.lock().await.clone();
  290. let bank_meseta = self.bank_meseta.lock().await.clone();
  291. let shared_bank_meseta = self.shared_bank_meseta.lock().await.clone();
  292. let items = self.items.lock().await.clone();
  293. let inventories = self.inventories.lock().await.clone();
  294. let character_banks = self.character_banks.lock().await.clone();
  295. let shared_banks = self.shared_banks.lock().await.clone();
  296. let equips = self.equips.lock().await.clone();
  297. let mag_modifiers = self.mag_modifiers.lock().await.clone();
  298. let weapon_modifiers = self.weapon_modifiers.lock().await.clone();
  299. let trades = self.trades.lock().await.clone();
  300. let working_gateway = InMemoryGateway {
  301. users: Arc::new(Mutex::new(users)),
  302. user_settings: Arc::new(Mutex::new(user_settings)),
  303. characters: Arc::new(Mutex::new(characters)),
  304. character_meseta: Arc::new(Mutex::new(character_meseta)),
  305. bank_meseta: Arc::new(Mutex::new(bank_meseta)),
  306. shared_bank_meseta: Arc::new(Mutex::new(shared_bank_meseta)),
  307. items: Arc::new(Mutex::new(items)),
  308. inventories: Arc::new(Mutex::new(inventories)),
  309. character_banks: Arc::new(Mutex::new(character_banks)),
  310. shared_banks: Arc::new(Mutex::new(shared_banks)),
  311. equips: Arc::new(Mutex::new(equips)),
  312. mag_modifiers: Arc::new(Mutex::new(mag_modifiers)),
  313. weapon_modifiers: Arc::new(Mutex::new(weapon_modifiers)),
  314. trades: Arc::new(Mutex::new(trades)),
  315. };
  316. let transaction = InMemoryGatewayTransaction {
  317. working_gateway,
  318. original_gateway: self.clone(),
  319. };
  320. let (transaction, result) = func(transaction).await?;
  321. transaction.commit().await?;
  322. Ok(result)
  323. })
  324. }
  325. async fn create_user(&mut self, user: NewUserAccountEntity) -> Result<UserAccountEntity, GatewayError> {
  326. let mut users = self.users.lock().await;
  327. let id = users
  328. .iter()
  329. .fold(0, |sum, (i, _)| std::cmp::max(sum, i.0))
  330. + 1;
  331. let user = UserAccountEntity {
  332. id: UserAccountId(id),
  333. username: user.username,
  334. password: user.password,
  335. guildcard: user.guildcard,
  336. team_id: user.team_id,
  337. banned_until: user.banned_until,
  338. muted_until: user.muted_until,
  339. created_at: chrono::Utc::now(),
  340. flags: user.flags,
  341. activated: user.activated,
  342. at_login: false,
  343. at_character: false,
  344. at_ship: false,
  345. };
  346. users.insert(user.id, user.clone());
  347. Ok(user)
  348. }
  349. async fn get_user_by_id(&mut self, id: UserAccountId) -> Result<UserAccountEntity, GatewayError> {
  350. let users = self.users.lock().await;
  351. users.get(&id).cloned().ok_or(GatewayError::Error)
  352. }
  353. async fn get_user_by_name(&mut self, username: String) -> Result<UserAccountEntity, GatewayError> {
  354. let users = self.users.lock().await;
  355. users
  356. .iter()
  357. .find(|(_, k)| k.username == username)
  358. .map(|(_, k)| k.clone())
  359. .ok_or(GatewayError::Error)
  360. }
  361. async fn save_user(&mut self, user: &UserAccountEntity) -> Result<(), GatewayError> {
  362. let mut users = self.users.lock().await;
  363. users.insert(user.id, user.clone());
  364. Ok(())
  365. }
  366. async fn create_user_settings(&mut self, settings: NewUserSettingsEntity) -> Result<UserSettingsEntity, GatewayError> {
  367. let mut user_settings = self.user_settings.lock().await;
  368. let id = user_settings
  369. .iter()
  370. .fold(0, |sum, (i, _)| std::cmp::max(sum, i.0))
  371. + 1;
  372. let new_settings = UserSettingsEntity {
  373. id: UserSettingsId(id),
  374. user_id: settings.user_id,
  375. settings: settings.settings,
  376. };
  377. user_settings.insert(new_settings.id, new_settings.clone());
  378. Ok(new_settings)
  379. }
  380. async fn get_user_settings_by_user(&mut self, user: &UserAccountEntity) -> Result<UserSettingsEntity, GatewayError> {
  381. let user_settings = self.user_settings.lock().await;
  382. user_settings
  383. .iter()
  384. .find(|(_, k)| k.user_id == user.id)
  385. .map(|(_, k)| k.clone())
  386. .ok_or(GatewayError::Error)
  387. }
  388. async fn save_user_settings(&mut self, settings: &UserSettingsEntity) -> Result<(), GatewayError> {
  389. let mut user_settings = self.user_settings.lock().await;
  390. user_settings.insert(settings.id, settings.clone());
  391. Ok(())
  392. }
  393. async fn get_characters_by_user(&mut self, user: &UserAccountEntity) -> Result<[Option<CharacterEntity>; 4], GatewayError> {
  394. let characters = self.characters.lock().await;
  395. const NONE: Option<CharacterEntity> = None;
  396. let mut chars = [NONE; 4];
  397. characters
  398. .iter()
  399. .filter(|(_, c)| c.user_id == user.id)
  400. .for_each(|(_, c)| chars[c.slot as usize] = Some(c.clone()));
  401. Ok(chars)
  402. }
  403. async fn create_character(&mut self, character: NewCharacterEntity) -> Result<CharacterEntity, GatewayError> {
  404. let mut characters = self.characters.lock().await;
  405. let id = characters
  406. .iter()
  407. .fold(0, |sum, (i, _)| std::cmp::max(sum, i.0))
  408. + 1;
  409. let new_character = CharacterEntity {
  410. id: CharacterEntityId(id),
  411. user_id: character.user_id,
  412. slot: character.slot,
  413. name: character.name,
  414. exp: character.exp,
  415. char_class: character.char_class,
  416. section_id: character.section_id,
  417. appearance: character.appearance,
  418. techs: character.techs,
  419. config: character.config,
  420. info_board: character.info_board,
  421. guildcard: character.guildcard,
  422. materials: character.materials,
  423. tech_menu: character.tech_menu,
  424. option_flags: character.option_flags,
  425. playtime: 0,
  426. };
  427. characters.insert(new_character.id, new_character.clone());
  428. Ok(new_character)
  429. }
  430. async fn save_character(&mut self, char: &CharacterEntity) -> Result<(), GatewayError> {
  431. let mut characters = self.characters.lock().await;
  432. characters.insert(char.id, char.clone());
  433. Ok(())
  434. }
  435. async fn get_guild_card_data_by_user(&mut self, user: &UserAccountEntity) -> Result<GuildCardDataEntity, GatewayError> {
  436. Ok(GuildCardDataEntity::new(user.id))
  437. }
  438. async fn create_item(&mut self, item: NewItemEntity) -> Result<ItemEntity, GatewayError> {
  439. let mut items = self.items.lock().await;
  440. let id = items
  441. .iter()
  442. .fold(0, |sum, (i, _)| std::cmp::max(sum, i.0))
  443. + 1;
  444. let new_item = ItemEntity {
  445. id: ItemEntityId(id),
  446. item: item.item,
  447. };
  448. items.insert(ItemEntityId(id), new_item.clone());
  449. Ok(new_item)
  450. }
  451. async fn add_item_note(&mut self, _item_id: &ItemEntityId, _item_note: ItemNote) -> Result<(), GatewayError> {
  452. Ok(())
  453. }
  454. async fn feed_mag(&mut self, mag_item_id: &ItemEntityId, tool_item_id: &ItemEntityId) -> Result<(), GatewayError> {
  455. self.mag_modifiers.lock().await
  456. .entry(*mag_item_id)
  457. .or_insert_with(Vec::new)
  458. .push(mag::MagModifier::FeedMag {
  459. food: *tool_item_id
  460. });
  461. Ok(())
  462. }
  463. async fn change_mag_owner(&mut self, mag_item_id: &ItemEntityId, character: &CharacterEntity) -> Result<(), GatewayError> {
  464. self.mag_modifiers.lock().await
  465. .entry(*mag_item_id)
  466. .or_insert_with(Vec::new)
  467. .push(mag::MagModifier::OwnerChange(character.char_class, character.section_id));
  468. Ok(())
  469. }
  470. async fn use_mag_cell(&mut self, mag_item_id: &ItemEntityId, mag_cell_id: &ItemEntityId) -> Result<(), GatewayError> {
  471. self.mag_modifiers.lock().await
  472. .entry(*mag_item_id)
  473. .or_insert_with(Vec::new)
  474. .push(mag::MagModifier::MagCell(*mag_cell_id));
  475. Ok(())
  476. }
  477. async fn add_weapon_modifier(&mut self, item_id: &ItemEntityId, modifier: &weapon::WeaponModifier) -> Result<(), GatewayError> {
  478. self.weapon_modifiers.lock().await
  479. .entry(*item_id)
  480. .or_insert_with(Vec::new)
  481. .push(modifier.clone());
  482. Ok(())
  483. }
  484. async fn get_character_inventory(&mut self, char_id: &CharacterEntityId) -> Result<InventoryEntity, GatewayError> {
  485. let inventories = self.inventories.lock().await;
  486. let items = self.items.lock().await;
  487. let weapon_modifiers = self.weapon_modifiers.lock().await;
  488. let mag_modifiers = self.mag_modifiers.lock().await;
  489. Ok(inventories
  490. .iter()
  491. .find(|(id, _)| **id == *char_id)
  492. .map(|(_, inv)| {
  493. InventoryEntity {
  494. items: inv
  495. .iter()
  496. .map(|inv_item_id| {
  497. match inv_item_id {
  498. InventoryItemElement::Individual(individual_id) => {
  499. InventoryItemEntity::Individual(items.get(individual_id).unwrap().clone())
  500. },
  501. InventoryItemElement::Stacked(stacked_ids) => {
  502. InventoryItemEntity::Stacked(
  503. stacked_ids.iter()
  504. .map(|stacked_id| {
  505. items.get(stacked_id).unwrap().clone()
  506. })
  507. .collect()
  508. )
  509. }
  510. }
  511. })
  512. .collect()
  513. }
  514. })
  515. .map(|inv| apply_modifiers(&items, &weapon_modifiers, &mag_modifiers, inv))
  516. .unwrap_or_default())
  517. }
  518. async fn get_character_bank(&mut self, char_id: &CharacterEntityId, bank_identifier: &BankIdentifier) -> Result<BankEntity, GatewayError> {
  519. match bank_identifier {
  520. BankIdentifier::Character => {
  521. let character_banks = self.character_banks.lock().await;
  522. Ok(character_banks
  523. .iter()
  524. .find(|(id, _)| **id == *char_id)
  525. .map(|(_, b)| b.clone())
  526. .unwrap_or_default())
  527. },
  528. BankIdentifier::Shared(bank_name) => {
  529. let user_id = self.characters
  530. .lock()
  531. .await
  532. .iter()
  533. .find(|(id, _)| **id == *char_id)
  534. .unwrap()
  535. .1
  536. .user_id;
  537. let shared_banks = self.shared_banks.lock().await;
  538. Ok(shared_banks
  539. .iter()
  540. .find(|((id, name), _)| *id == user_id && *name == *bank_name)
  541. .map(|(_, b)| b.clone())
  542. .unwrap_or_default())
  543. }
  544. }
  545. }
  546. async fn set_character_inventory(&mut self, char_id: &CharacterEntityId, inventory: &InventoryEntity) -> Result<(), GatewayError> {
  547. let mut inventories = self.inventories.lock().await;
  548. inventories.insert(*char_id, inventory.items
  549. .iter()
  550. .map(|inventory_item| {
  551. match inventory_item {
  552. InventoryItemEntity::Individual(individual) => {
  553. InventoryItemElement::Individual(individual.id)
  554. },
  555. InventoryItemEntity::Stacked(stacked) => {
  556. InventoryItemElement::Stacked(
  557. stacked.iter()
  558. .map(|stacked| {
  559. stacked.id
  560. })
  561. .collect()
  562. )
  563. }
  564. }
  565. })
  566. .collect());
  567. Ok(())
  568. }
  569. async fn set_character_bank(&mut self, char_id: &CharacterEntityId, bank: &BankEntity, bank_identifier: &BankIdentifier) -> Result<(), GatewayError> {
  570. match bank_identifier {
  571. BankIdentifier::Character => {
  572. let mut character_banks = self.character_banks.lock().await;
  573. character_banks.insert(*char_id, bank.clone());
  574. },
  575. BankIdentifier::Shared(bank_name) => {
  576. let user_id = self.characters
  577. .lock()
  578. .await
  579. .iter()
  580. .find(|(id, _)| **id == *char_id)
  581. .unwrap()
  582. .1
  583. .user_id;
  584. let mut shared_banks = self.shared_banks.lock().await;
  585. shared_banks.insert((user_id, bank_name.clone()), bank.clone());
  586. }
  587. }
  588. Ok(())
  589. }
  590. async fn get_character_equips(&mut self, char_id: &CharacterEntityId) -> Result<EquippedEntity, GatewayError> {
  591. let equips = self.equips.lock().await;
  592. Ok(equips
  593. .iter()
  594. .find(|(id, _)| **id == *char_id)
  595. .map(|(_, inv)| inv.clone())
  596. .unwrap_or_default())
  597. }
  598. async fn set_character_equips(&mut self, char_id: &CharacterEntityId, equipped: &EquippedEntity) -> Result<(), GatewayError> {
  599. let mut equips = self.equips.lock().await;
  600. equips.insert(*char_id, equipped.clone());
  601. Ok(())
  602. }
  603. async fn set_character_meseta(&mut self, char_id: &CharacterEntityId, meseta: Meseta) -> Result<(), GatewayError> {
  604. let mut character_meseta = self.character_meseta.lock().await;
  605. character_meseta.insert(*char_id, meseta);
  606. Ok(())
  607. }
  608. async fn get_character_meseta(&mut self, char_id: &CharacterEntityId) -> Result<Meseta, GatewayError> {
  609. let mut character_meseta = self.character_meseta.lock().await;
  610. if let Some(meseta) = character_meseta.get_mut(char_id) {
  611. Ok(*meseta)
  612. }
  613. else {
  614. Err(GatewayError::Error)
  615. }
  616. }
  617. async fn set_bank_meseta(&mut self, char_id: &CharacterEntityId, bank_identifier: &BankIdentifier, meseta: Meseta) -> Result<(), GatewayError> {
  618. match bank_identifier {
  619. BankIdentifier::Character => {
  620. let mut bank_meseta = self.bank_meseta.lock().await;
  621. bank_meseta.insert(*char_id, meseta);
  622. }
  623. BankIdentifier::Shared(bank_name) => {
  624. let user_id = self.characters
  625. .lock()
  626. .await
  627. .iter()
  628. .find(|(id, _)| **id == *char_id)
  629. .unwrap()
  630. .1
  631. .user_id;
  632. self.shared_bank_meseta
  633. .lock()
  634. .await
  635. .insert((user_id, bank_name.clone()), meseta);
  636. }
  637. }
  638. Ok(())
  639. }
  640. async fn get_bank_meseta(&mut self, char_id: &CharacterEntityId, bank_identifier: &BankIdentifier) -> Result<Meseta, GatewayError> {
  641. match bank_identifier {
  642. BankIdentifier::Character => {
  643. let mut bank_meseta = self.bank_meseta.lock().await;
  644. if let Some(meseta) = bank_meseta.get_mut(char_id) {
  645. Ok(*meseta)
  646. }
  647. else {
  648. Err(GatewayError::Error)
  649. }
  650. },
  651. BankIdentifier::Shared(bank_name) => {
  652. let mut shared_bank_meseta = self.shared_bank_meseta.lock().await;
  653. let user_id = self.characters
  654. .lock()
  655. .await
  656. .iter()
  657. .find(|(id, _)| **id == *char_id)
  658. .unwrap()
  659. .1
  660. .user_id;
  661. if let Some(meseta) = shared_bank_meseta.get_mut(&(user_id, bank_name.clone())) {
  662. Ok(*meseta)
  663. }
  664. else {
  665. Ok(Meseta(0))
  666. }
  667. }
  668. }
  669. }
  670. async fn create_trade(&mut self, char_id1: &CharacterEntityId, char_id2: &CharacterEntityId) -> Result<TradeEntity, GatewayError> {
  671. let mut trades = self.trades.lock().await;
  672. let id = trades.len() as u32;
  673. let new_trade = TradeEntity {
  674. id: TradeId(id),
  675. character1: *char_id1,
  676. character2: *char_id2,
  677. };
  678. trades.push(new_trade.clone());
  679. Ok(new_trade)
  680. }
  681. async fn set_character_playtime(&mut self, char_id: &CharacterEntityId, playtime: u32) -> Result<(), GatewayError> {
  682. let mut characters = self.characters.lock().await;
  683. if let Some(character) = characters.get_mut(char_id) {
  684. character.playtime = playtime;
  685. Ok(())
  686. }
  687. else {
  688. Err(GatewayError::Error)
  689. }
  690. }
  691. // I do not care to replicate this in testing
  692. async fn create_room(&mut self, room: NewRoomEntity) -> Result<RoomEntity, GatewayError> {
  693. Ok(RoomEntity {
  694. id: RoomEntityId(0),
  695. name: room.name,
  696. section_id: room.section_id,
  697. episode: room.episode,
  698. difficulty: room.difficulty,
  699. mode: room.mode,
  700. })
  701. }
  702. // I do not care to replicate this in testing
  703. async fn add_room_note(&mut self, _room_id: RoomEntityId, _note: RoomNote) -> Result<(), GatewayError> {
  704. Ok(())
  705. }
  706. }