From 16a46533600f488cb3cec319224c8acf8db91ca3 Mon Sep 17 00:00:00 2001 From: jake Date: Sat, 30 Jul 2022 15:02:18 -0600 Subject: [PATCH] pass EntityGateway clones rather than letting functions borrow --- src/common/mainloop/interserver.rs | 4 +- src/common/mainloop/mod.rs | 6 +-- src/ship/packet/handler/auth.rs | 6 +-- src/ship/packet/handler/communication.rs | 2 +- src/ship/packet/handler/direct_message.rs | 49 ++++++----------- src/ship/packet/handler/lobby.rs | 4 +- src/ship/packet/handler/message.rs | 44 +++++++-------- src/ship/packet/handler/settings.rs | 10 ++-- src/ship/packet/handler/trade.rs | 4 +- src/ship/ship.rs | 66 +++++++++++------------ tests/common.rs | 14 ++--- tests/test_trade.rs | 6 +-- 12 files changed, 100 insertions(+), 115 deletions(-) diff --git a/src/common/mainloop/interserver.rs b/src/common/mainloop/interserver.rs index 3547f8b..ce1cb66 100644 --- a/src/common/mainloop/interserver.rs +++ b/src/common/mainloop/interserver.rs @@ -180,7 +180,7 @@ where -pub fn login_listen_mainloop(state: Arc>>, port: u16) -> Pin>> { +pub fn login_listen_mainloop(state: Arc>>, port: u16) -> Pin>> { Box::pin(async_std::task::spawn(async move { let listener = async_std::net::TcpListener::bind(&std::net::SocketAddr::from((std::net::Ipv4Addr::new(0,0,0,0), port))).await.unwrap(); let mut id = 0; @@ -210,7 +210,7 @@ pub fn login_listen_mainloop(state: Arc(state: Arc>>, ip: std::net::Ipv4Addr, port: u16) -> Pin>> { +pub fn ship_connect_mainloop(state: Arc>>, ip: std::net::Ipv4Addr, port: u16) -> Pin>> { Box::pin(async_std::task::spawn(async move { let mut id = 0; let (server_state_sender, server_state_receiver) = async_std::channel::bounded(1024); diff --git a/src/common/mainloop/mod.rs b/src/common/mainloop/mod.rs index 2a5b3ff..5e84d09 100644 --- a/src/common/mainloop/mod.rs +++ b/src/common/mainloop/mod.rs @@ -23,13 +23,13 @@ pub fn patch_mainloop(patch_state: PatchServerState, patch_port: u16) -> Pin(login_state: LoginServerState, login_port: u16) -> Pin>> { +pub fn login_mainloop(login_state: LoginServerState, login_port: u16) -> Pin>> { let login_state = Arc::new(Mutex::new(login_state)); let client_mainloop = client_accept_mainloop(login_state, login_port); Box::pin(client_mainloop) } -pub fn character_mainloop(character_state: CharacterServerState, character_port: u16, comm_port: u16) -> Pin>> { +pub fn character_mainloop(character_state: CharacterServerState, character_port: u16, comm_port: u16) -> Pin>> { let character_state = Arc::new(Mutex::new(character_state)); let client_mainloop = client_accept_mainloop(character_state.clone(), character_port); let ship_communication_mainloop = login_listen_mainloop(character_state, comm_port); @@ -37,7 +37,7 @@ pub fn character_mainloop(character_state: Characte } -pub fn ship_mainloop(ship_state: ShipServerState, ship_port: u16, comm_ip: std::net::Ipv4Addr, comm_port: u16) -> Pin>> { +pub fn ship_mainloop(ship_state: ShipServerState, ship_port: u16, comm_ip: std::net::Ipv4Addr, comm_port: u16) -> Pin>> { let ship_state = Arc::new(Mutex::new(ship_state)); let client_mainloop = client_accept_mainloop(ship_state.clone(), ship_port); let login_communication_mainloop = ship_connect_mainloop(ship_state, comm_ip, comm_port); diff --git a/src/ship/packet/handler/auth.rs b/src/ship/packet/handler/auth.rs index 50be751..e3ca60b 100644 --- a/src/ship/packet/handler/auth.rs +++ b/src/ship/packet/handler/auth.rs @@ -10,14 +10,14 @@ use crate::common::interserver::ShipMessage; #[allow(clippy::too_many_arguments)] pub async fn validate_login(id: ClientId, pkt: &Login, - entity_gateway: &mut EG, + mut entity_gateway: EG, clients: &mut Clients, item_state: &mut ItemState, shipgate_sender: &Option>, ship_name: &str, num_blocks: usize) -> Result, anyhow::Error> { - Ok(match get_login_status(entity_gateway, pkt).await { + Ok(match get_login_status(&mut entity_gateway, pkt).await { Ok(user) => { let mut response = LoginResponse::by_status(AccountStatus::Ok, Session::new()); response.guildcard = user.id.0 as u32; @@ -30,7 +30,7 @@ pub async fn validate_login(id: ClientId, .clone(); let settings = entity_gateway.get_user_settings_by_user(&user).await?; - item_state.load_character(entity_gateway, &character).await?; + item_state.load_character(&mut entity_gateway, &character).await?; if let Some(shipgate_sender) = shipgate_sender.as_ref() { shipgate_sender(ShipMessage::AddUser(user.id)); diff --git a/src/ship/packet/handler/communication.rs b/src/ship/packet/handler/communication.rs index 087913b..c8942ec 100644 --- a/src/ship/packet/handler/communication.rs +++ b/src/ship/packet/handler/communication.rs @@ -38,7 +38,7 @@ pub fn request_infoboard(id: ClientId, pub async fn write_infoboard(id: ClientId, new_infoboard: &WriteInfoboard, clients: &mut Clients, - entity_gateway: &mut EG) + mut entity_gateway: EG) -> Box + Send> { let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); client.character.info_board.update_infoboard(new_infoboard); diff --git a/src/ship/packet/handler/direct_message.rs b/src/ship/packet/handler/direct_message.rs index 4861b7b..1e196d5 100644 --- a/src/ship/packet/handler/direct_message.rs +++ b/src/ship/packet/handler/direct_message.rs @@ -70,7 +70,7 @@ pub fn guildcard_send(id: ClientId, pub async fn request_item(id: ClientId, request_item: &RequestItem, - entity_gateway: &mut EG, + mut entity_gateway: EG, client_location: &ClientLocation, clients: &mut Clients, rooms: &mut Rooms, @@ -109,7 +109,7 @@ where item: item_drop, }; let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?; - let floor_item = enemy_drops_item(item_state, entity_gateway, client.character.id, item_drop).await?; + let floor_item = enemy_drops_item(item_state, &mut entity_gateway, client.character.id, item_drop).await?; let item_drop_msg = builder::message::item_drop(request_item.client, request_item.target, &floor_item)?; item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))); @@ -120,7 +120,7 @@ where pub async fn pickup_item(id: ClientId, pickup_item: &PickupItem, - entity_gateway: &mut EG, + mut entity_gateway: EG, client_location: &ClientLocation, clients: &mut Clients, item_state: &mut ItemState) @@ -133,30 +133,15 @@ where let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?; let clients_in_area = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?; - // TODO: should not need to fetch the item here to construct this packet - //let (item, floor_type) = item_manager.get_floor_item_by_id(&client.character, ClientItemId(pickup_item.item_id))?; - /* - let (item, floor_type) = item_state.get_floor_item(&client.character, &ClientItemId(pickup_item.item_id))?; - let remove_item = builder::message::remove_item_from_floor(area_client, item)?; - let create_item = match item { - FloorItem::Individual(individual_floor_item) => Some(builder::message::create_individual_item(area_client, item.item_id(), &individual_floor_item.item)?), - FloorItem::Stacked(stacked_floor_item) => Some(builder::message::create_stacked_item(area_client, item.item_id(), &stacked_floor_item.tool, stacked_floor_item.count())?), - FloorItem::Meseta(_) => None, - //_ => Some(builder::message::create_item(area_client, &item)?), - }; - */ - let (item, floor_type) = item_state.get_floor_item(&client.character.id, &ClientItemId(pickup_item.item_id))?; let remove_item = builder::message::remove_item_from_floor(area_client, item)?; let create_item = match &item.item { FloorItemDetail::Individual(individual_floor_item) => Some(builder::message::create_individual_item(area_client, item.item_id, individual_floor_item)?), FloorItemDetail::Stacked(stacked_floor_item) => Some(builder::message::create_stacked_item(area_client, item.item_id, &stacked_floor_item.tool, stacked_floor_item.count())?), FloorItemDetail::Meseta(_) => None, - //_ => Some(builder::message::create_item(area_client, &item)?), }; - //match item_manager.character_picks_up_item(entity_gateway, &mut client.character, ClientItemId(pickup_item.item_id)).await { - match pick_up_item(item_state, entity_gateway, &client.character, &ClientItemId(pickup_item.item_id)).await { + match pick_up_item(item_state, &mut entity_gateway, &client.character, &ClientItemId(pickup_item.item_id)).await { Ok(trigger_create_item) => { let remove_packets: Box + Send> = match floor_type { FloorType::Local => { @@ -189,7 +174,7 @@ where pub async fn request_box_item(id: ClientId, box_drop_request: &BoxDropRequest, - entity_gateway: &mut EG, + mut entity_gateway: EG, client_location: &ClientLocation, clients: &mut Clients, rooms: &mut Rooms, @@ -228,7 +213,7 @@ EG: EntityGateway item: item_drop, }; let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?; - let floor_item = enemy_drops_item(item_state, entity_gateway, client.character.id, item_drop).await?; + let floor_item = enemy_drops_item(item_state, &mut entity_gateway, client.character.id, item_drop).await?; let item_drop_msg = builder::message::item_drop(box_drop_request.client, box_drop_request.target, &floor_item)?; item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))) } @@ -251,7 +236,7 @@ pub async fn send_bank_list(id: ClientId, pub async fn bank_interaction(id: ClientId, bank_interaction: &BankInteraction, - entity_gateway: &mut EG, + mut entity_gateway: EG, client_location: &ClientLocation, clients: &mut Clients, item_state: &mut ItemState) @@ -265,22 +250,22 @@ where let bank_action_pkts = match bank_interaction.action { BANK_ACTION_DEPOSIT => { if bank_interaction.item_id == 0xFFFFFFFF { - deposit_meseta(item_state, entity_gateway, &client.character, bank_interaction.meseta_amount).await?; + deposit_meseta(item_state, &mut entity_gateway, &client.character, bank_interaction.meseta_amount).await?; Vec::new() } else { - deposit_item(item_state, entity_gateway, &client.character, &ClientItemId(bank_interaction.item_id), bank_interaction.item_amount as u32).await?; + deposit_item(item_state, &mut entity_gateway, &client.character, &ClientItemId(bank_interaction.item_id), bank_interaction.item_amount as u32).await?; let player_no_longer_has_item = builder::message::player_no_longer_has_item(area_client, ClientItemId(bank_interaction.item_id), bank_interaction.item_amount as u32); vec![SendShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(player_no_longer_has_item)))] } }, BANK_ACTION_WITHDRAW => { if bank_interaction.item_id == 0xFFFFFFFF { - withdraw_meseta(item_state, entity_gateway, &client.character, bank_interaction.meseta_amount).await?; + withdraw_meseta(item_state, &mut entity_gateway, &client.character, bank_interaction.meseta_amount).await?; Vec::new() } else { - let item_added_to_inventory = withdraw_item(item_state, entity_gateway, &client.character, &ClientItemId(bank_interaction.item_id), bank_interaction.item_amount as u32).await?; + let item_added_to_inventory = withdraw_item(item_state, &mut entity_gateway, &client.character, &ClientItemId(bank_interaction.item_id), bank_interaction.item_amount as u32).await?; let item_created = builder::message::create_withdrawn_inventory_item2(area_client, &item_added_to_inventory)?; vec![SendShipPacket::Message(Message::new(GameMessage::CreateItem(item_created)))] } @@ -342,7 +327,7 @@ pub async fn shop_request(id: ClientId, pub async fn buy_item(id: ClientId, buy_item: &BuyItem, - entity_gateway: &mut EG, + mut entity_gateway: EG, client_location: &ClientLocation, clients: &mut Clients, item_state: &mut ItemState) @@ -372,7 +357,7 @@ where } }; - let inventory_item = buy_shop_item(item_state, entity_gateway, &client.character, item, ClientItemId(buy_item.item_id), buy_item.amount as u32).await?; + let inventory_item = buy_shop_item(item_state, &mut entity_gateway, &client.character, item, ClientItemId(buy_item.item_id), buy_item.amount as u32).await?; let create = builder::message::create_withdrawn_inventory_item(area_client, &inventory_item)?; if remove { @@ -407,7 +392,7 @@ const TEK_PERCENT_MODIFIER: [item::weapon::TekPercentModifier; 5] = [item::weapo pub async fn request_tek_item(id: ClientId, tek_request: &TekRequest, - entity_gateway: &mut EG, + mut entity_gateway: EG, clients: &mut Clients, item_state: &mut ItemState) -> Result + Send>, anyhow::Error> @@ -441,7 +426,7 @@ where grind: grind_mod, }); - take_meseta(item_state, entity_gateway, &client.character.id, item::Meseta(100)).await?; + take_meseta(item_state, &mut entity_gateway, &client.character.id, item::Meseta(100)).await?; let preview_pkt = builder::message::tek_preview(ClientItemId(tek_request.item_id), &weapon)?; @@ -450,7 +435,7 @@ where pub async fn accept_tek_item(id: ClientId, tek_accept: &TekAccept, - entity_gateway: &mut EG, + mut entity_gateway: EG, client_location: &ClientLocation, clients: &mut Clients, item_state: &mut ItemState) @@ -471,7 +456,7 @@ where percent: percent_mod, grind: grind_mod, }; - let weapon = apply_modifier(item_state, entity_gateway, &client.character, item_id, item::ItemModifier::WeaponModifier(modifier)).await?; + let weapon = apply_modifier(item_state, &mut entity_gateway, &client.character, item_id, item::ItemModifier::WeaponModifier(modifier)).await?; let create_item_pkt = builder::message::create_individual_item(area_client, item_id, &weapon)?; diff --git a/src/ship/packet/handler/lobby.rs b/src/ship/packet/handler/lobby.rs index 2e1625c..fcbff40 100644 --- a/src/ship/packet/handler/lobby.rs +++ b/src/ship/packet/handler/lobby.rs @@ -72,7 +72,7 @@ pub async fn change_lobby(id: ClientId, item_state: &mut ItemState, level_table: &CharacterLevelTable, ship_rooms: &mut Rooms, - entity_gateway: &mut EG) + mut entity_gateway: EG) -> Result, anyhow::Error> { let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?; let prev_area = client_location.get_area(id).map_err(|err| -> ClientLocationError {err.into()})?; @@ -103,7 +103,7 @@ pub async fn change_lobby(id: ClientId, } } } - item_state.load_character(entity_gateway, &client.character).await?; + item_state.load_character(&mut entity_gateway, &client.character).await?; let join_lobby = packet::builder::lobby::join_lobby(id, lobby, client_location, clients, item_state, level_table)?; let addto = packet::builder::lobby::add_to_lobby(id, lobby, client_location, clients, item_state, level_table)?; let neighbors = client_location.get_client_neighbors(id).unwrap(); diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index d0d4f44..456ed7d 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -13,7 +13,7 @@ use crate::ship::items::tasks::{drop_item, drop_partial_item, drop_meseta, equip pub async fn request_exp(id: ClientId, request_exp: &RequestExp, - entity_gateway: &mut EG, + mut entity_gateway: EG, client_location: &ClientLocation, clients: &mut Clients, rooms: &mut Rooms, @@ -67,7 +67,7 @@ pub async fn request_exp(id: ClientId, pub async fn player_drop_item(id: ClientId, player_drop_item: &PlayerDropItem, - entity_gateway: &mut EG, + mut entity_gateway: EG, client_location: &ClientLocation, clients: &mut Clients, rooms: &mut Rooms, @@ -83,7 +83,7 @@ where .as_mut() .ok_or(ShipError::InvalidRoom(room_id.0 as u32))?; let area = room.map_areas.get_area_map(player_drop_item.map_area)?; - drop_item(item_state, entity_gateway, &client.character, &ClientItemId(player_drop_item.item_id), *area, (player_drop_item.x, player_drop_item.y, player_drop_item.z)).await?; + drop_item(item_state, &mut entity_gateway, &client.character, &ClientItemId(player_drop_item.item_id), *area, (player_drop_item.x, player_drop_item.y, player_drop_item.z)).await?; let clients_in_area = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?; let pdi = player_drop_item.clone(); Ok(Box::new(clients_in_area.into_iter() @@ -118,7 +118,7 @@ pub fn drop_coordinates(id: ClientId, pub async fn no_longer_has_item(id: ClientId, no_longer_has_item: &PlayerNoLongerHasItem, - entity_gateway: &mut EG, + mut entity_gateway: EG, client_location: &ClientLocation, clients: &mut Clients, item_state: &mut ItemState) @@ -135,7 +135,7 @@ where } if no_longer_has_item.item_id == 0xFFFFFFFF { - let dropped_meseta = drop_meseta(item_state, entity_gateway, &client.character, drop_location.map_area, (drop_location.x, drop_location.z), no_longer_has_item.amount).await?; + let dropped_meseta = drop_meseta(item_state, &mut entity_gateway, &client.character, drop_location.map_area, (drop_location.x, drop_location.z), no_longer_has_item.amount).await?; let dropped_meseta_pkt = builder::message::drop_split_meseta_stack(area_client, &dropped_meseta)?; let no_longer_has_meseta_pkt = builder::message::player_no_longer_has_meseta(area_client, no_longer_has_item.amount as u32); @@ -159,7 +159,7 @@ where )) } else { - let dropped_item = drop_partial_item(item_state, entity_gateway, &client.character, &drop_location.item_id, drop_location.map_area, (drop_location.x, drop_location.z), no_longer_has_item.amount).await?; + let dropped_item = drop_partial_item(item_state, &mut entity_gateway, &client.character, &drop_location.item_id, drop_location.map_area, (drop_location.x, drop_location.z), no_longer_has_item.amount).await?; let dropped_item_pkt = builder::message::drop_split_stack(area_client, &dropped_item)?; client.item_drop_location = None; @@ -259,7 +259,7 @@ pub fn update_player_position(id: ClientId, pub async fn charge_attack(id: ClientId, charge: &ChargeAttack, - entity_gateway: &mut EG, + mut entity_gateway: EG, client_location: &ClientLocation, clients: &mut Clients, item_state: &mut ItemState) @@ -270,7 +270,7 @@ where let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?; // TODO: should probably validate this to be a legit number, I'd just hardcode 200 but vjaya - take_meseta(item_state, entity_gateway, &client.character.id, Meseta(charge.meseta)).await?; + take_meseta(item_state, &mut entity_gateway, &client.character.id, Meseta(charge.meseta)).await?; let charge = charge.clone(); Ok(Box::new(client_location.get_client_neighbors(id).unwrap().into_iter() @@ -281,7 +281,7 @@ where pub async fn player_uses_item(id: ClientId, player_use_tool: &PlayerUseItem, - entity_gateway: &mut EG, + mut entity_gateway: EG, _client_location: &ClientLocation, clients: &mut Clients, item_state: &mut ItemState) @@ -290,13 +290,13 @@ where EG: EntityGateway { let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?; - use_item(item_state, entity_gateway, &mut client.character, &ClientItemId(player_use_tool.item_id), 1).await?; + use_item(item_state, &mut entity_gateway, &mut client.character, &ClientItemId(player_use_tool.item_id), 1).await?; Ok(Box::new(None.into_iter())) // TODO: should probably tell other players we used an item } pub async fn player_used_medical_center(id: ClientId, pumc: &PlayerUsedMedicalCenter, - entity_gateway: &mut EG, + mut entity_gateway: EG, client_location: &ClientLocation, clients: &mut Clients, item_state: &mut ItemState) @@ -306,7 +306,7 @@ where { let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?; - take_meseta(item_state, entity_gateway, &client.character.id, Meseta(10)).await?; + take_meseta(item_state, &mut entity_gateway, &client.character.id, Meseta(10)).await?; let pumc = pumc.clone(); Ok(Box::new(client_location.get_client_neighbors(id).unwrap().into_iter() @@ -318,7 +318,7 @@ where pub async fn player_feed_mag(id: ClientId, mag_feed: &PlayerFeedMag, - entity_gateway: &mut EG, + mut entity_gateway: EG, client_location: &ClientLocation, clients: &Clients, item_state: &mut ItemState) @@ -327,7 +327,7 @@ where EG: EntityGateway { let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?; - feed_mag(item_state, entity_gateway, &client.character, &ClientItemId(mag_feed.mag_id), &ClientItemId(mag_feed.item_id)).await?; + feed_mag(item_state, &mut entity_gateway, &client.character, &ClientItemId(mag_feed.mag_id), &ClientItemId(mag_feed.item_id)).await?; let mag_feed = mag_feed.clone(); Ok(Box::new(client_location.get_client_neighbors(id).unwrap().into_iter() @@ -338,7 +338,7 @@ where pub async fn player_equips_item(id: ClientId, pkt: &PlayerEquipItem, - entity_gateway: &mut EG, + mut entity_gateway: EG, clients: &Clients, item_state: &mut ItemState) -> Result + Send>, anyhow::Error> @@ -352,13 +352,13 @@ where else { 0 }; - equip_item(item_state, entity_gateway, &client.character, &ClientItemId(pkt.item_id), equip_slot).await?; + equip_item(item_state, &mut entity_gateway, &client.character, &ClientItemId(pkt.item_id), equip_slot).await?; Ok(Box::new(None.into_iter())) // TODO: tell other players you equipped an item } pub async fn player_unequips_item(id: ClientId, pkt: &PlayerUnequipItem, - entity_gateway: &mut EG, + mut entity_gateway: EG, clients: &Clients, item_state: &mut ItemState) -> Result + Send>, anyhow::Error> @@ -366,13 +366,13 @@ where EG: EntityGateway { let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?; - unequip_item(item_state, entity_gateway, &client.character, &ClientItemId(pkt.item_id)).await?; + unequip_item(item_state, &mut entity_gateway, &client.character, &ClientItemId(pkt.item_id)).await?; Ok(Box::new(None.into_iter())) // TODO: tell other players if you unequip an item } pub async fn player_sorts_items(id: ClientId, pkt: &SortItems, - entity_gateway: &mut EG, + mut entity_gateway: EG, clients: &Clients, item_state: &mut ItemState) -> Result + Send>, anyhow::Error> @@ -391,13 +391,13 @@ where } }) .collect(); - sort_inventory(item_state, entity_gateway, &client.character, item_ids).await?; + sort_inventory(item_state, &mut entity_gateway, &client.character, item_ids).await?; Ok(Box::new(None.into_iter())) // TODO: clients probably care about each others item orders } pub async fn player_sells_item (id: ClientId, sold_item: &PlayerSoldItem, - entity_gateway: &mut EG, + mut entity_gateway: EG, clients: &mut Clients, item_state: &mut ItemState) -> Result + Send>, anyhow::Error> @@ -405,7 +405,7 @@ where EG: EntityGateway { let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?; - sell_item(item_state, entity_gateway, &client.character, ClientItemId(sold_item.item_id), sold_item.amount as u32).await?; + sell_item(item_state, &mut entity_gateway, &client.character, ClientItemId(sold_item.item_id), sold_item.amount as u32).await?; // TODO: send the packet to other clients Ok(Box::new(None.into_iter())) } diff --git a/src/ship/packet/handler/settings.rs b/src/ship/packet/handler/settings.rs index 17d0d64..52b0e8f 100644 --- a/src/ship/packet/handler/settings.rs +++ b/src/ship/packet/handler/settings.rs @@ -6,7 +6,7 @@ use crate::entity::gateway::EntityGateway; pub async fn update_config(id: ClientId, update_config: &UpdateConfig, clients: &mut Clients, - entity_gateway: &mut EG) + mut entity_gateway: EG) -> Box + Send> { let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); client.character.config.update(update_config); @@ -17,7 +17,7 @@ pub async fn update_config(id: ClientId, pub async fn save_options(id: ClientId, save_options: &SaveOptions, clients: &mut Clients, - entity_gateway: &mut EG) + mut entity_gateway: EG) -> Box + Send> { // TODO: don't unwrap? let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); @@ -29,7 +29,7 @@ pub async fn save_options(id: ClientId, pub async fn keyboard_config(id: ClientId, keyboard_config: &KeyboardConfig, clients: &mut Clients, - entity_gateway: &mut EG) + mut entity_gateway: EG) -> Box + Send> { let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); client.character.keyboard_config.update(keyboard_config); @@ -40,10 +40,10 @@ pub async fn keyboard_config(id: ClientId, pub async fn gamepad_config(id: ClientId, gamepad_config: &GamepadConfig, clients: &mut Clients, - entity_gateway: &mut EG) + mut entity_gateway: EG) -> Box + Send> { let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); client.character.gamepad_config.update(gamepad_config); entity_gateway.save_character(&client.character).await.unwrap(); Box::new(None.into_iter()) -} \ No newline at end of file +} diff --git a/src/ship/packet/handler/trade.rs b/src/ship/packet/handler/trade.rs index 7b01ed6..465b76d 100644 --- a/src/ship/packet/handler/trade.rs +++ b/src/ship/packet/handler/trade.rs @@ -429,7 +429,7 @@ pub async fn items_to_trade(id: ClientId, } pub async fn trade_confirmed(id: ClientId, - entity_gateway: &mut EG, + mut entity_gateway: EG, client_location: &ClientLocation, clients: &mut Clients, item_state: &mut ItemState, @@ -493,7 +493,7 @@ where }); let (this_new_items, other_new_items) = trade_items(item_state, - entity_gateway, + &mut entity_gateway, (&this_local_client, &this_client.character, &this.items, Meseta(this.meseta as u32)), (&other_local_client, &other_client.character, &other.items, Meseta(other.meseta as u32))).await?; diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 754ea7c..42bd0e5 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -373,7 +373,7 @@ impl Default for ItemShops { } -pub struct ShipServerStateBuilder { +pub struct ShipServerStateBuilder { entity_gateway: Option, name: Option, ip: Option, @@ -382,7 +382,7 @@ pub struct ShipServerStateBuilder { num_blocks: usize, } -impl Default for ShipServerStateBuilder { +impl Default for ShipServerStateBuilder { fn default() -> ShipServerStateBuilder { ShipServerStateBuilder { entity_gateway: None, @@ -395,7 +395,7 @@ impl Default for ShipServerStateBuilder { } } -impl ShipServerStateBuilder { +impl ShipServerStateBuilder { #[must_use] pub fn gateway(mut self, entity_gateway: EG) -> ShipServerStateBuilder { self.entity_gateway = Some(entity_gateway); @@ -478,7 +478,7 @@ impl Blocks { } } -pub struct ShipServerState { +pub struct ShipServerState { entity_gateway: EG, pub clients: Clients, level_table: CharacterLevelTable, @@ -496,7 +496,7 @@ pub struct ShipServerState { trades: TradeState, } -impl ShipServerState { +impl ShipServerState { pub fn builder() -> ShipServerStateBuilder { ShipServerStateBuilder::default() } @@ -509,11 +509,11 @@ impl ShipServerState { Ok(match &msg.msg { GameMessage::RequestExp(request_exp) => { let block = self.blocks.with_client(id, &self.clients)?; - handler::message::request_exp(id, request_exp, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut block.rooms, &self.level_table).await? + handler::message::request_exp(id, request_exp, self.entity_gateway.clone(), &block.client_location, &mut self.clients, &mut block.rooms, &self.level_table).await? }, GameMessage::PlayerDropItem(player_drop_item) => { let block = self.blocks.with_client(id, &self.clients)?; - handler::message::player_drop_item(id, player_drop_item, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut block.rooms, &mut self.item_state).await? + handler::message::player_drop_item(id, player_drop_item, self.entity_gateway.clone(), &block.client_location, &mut self.clients, &mut block.rooms, &mut self.item_state).await? }, GameMessage::DropCoordinates(drop_coordinates) => { let block = self.blocks.with_client(id, &self.clients)?; @@ -521,7 +521,7 @@ impl ShipServerState { }, GameMessage::PlayerNoLongerHasItem(no_longer_has_item) => { let block = self.blocks.with_client(id, &self.clients)?; - handler::message::no_longer_has_item(id, no_longer_has_item, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_state).await? + handler::message::no_longer_has_item(id, no_longer_has_item, self.entity_gateway.clone(), &block.client_location, &mut self.clients, &mut self.item_state).await? }, GameMessage::PlayerChangedMap(_) | GameMessage::PlayerChangedMap2(_) | GameMessage::TellOtherPlayerMyLocation(_) | GameMessage::PlayerWarpingToFloor(_) | GameMessage::PlayerTeleported(_) | GameMessage::PlayerStopped(_) | @@ -532,31 +532,31 @@ impl ShipServerState { }, GameMessage::ChargeAttack(charge_attack) => { let block = self.blocks.with_client(id, &self.clients)?; - handler::message::charge_attack(id, charge_attack, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_state).await? + handler::message::charge_attack(id, charge_attack, self.entity_gateway.clone(), &block.client_location, &mut self.clients, &mut self.item_state).await? }, GameMessage::PlayerUseItem(player_use_item) => { let block = self.blocks.with_client(id, &self.clients)?; - handler::message::player_uses_item(id, player_use_item, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_state).await? + handler::message::player_uses_item(id, player_use_item, self.entity_gateway.clone(), &block.client_location, &mut self.clients, &mut self.item_state).await? }, GameMessage::PlayerUsedMedicalCenter(player_used_medical_center) => { let block = self.blocks.with_client(id, &self.clients)?; - handler::message::player_used_medical_center(id, player_used_medical_center, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_state).await? + handler::message::player_used_medical_center(id, player_used_medical_center, self.entity_gateway.clone(), &block.client_location, &mut self.clients, &mut self.item_state).await? }, GameMessage::PlayerFeedMag(player_feed_mag) => { let block = self.blocks.with_client(id, &self.clients)?; - handler::message::player_feed_mag(id, player_feed_mag, &mut self.entity_gateway, &block.client_location, &self.clients, &mut self.item_state).await? + handler::message::player_feed_mag(id, player_feed_mag, self.entity_gateway.clone(), &block.client_location, &self.clients, &mut self.item_state).await? }, GameMessage::PlayerEquipItem(player_equip_item) => { - handler::message::player_equips_item(id, player_equip_item, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? + handler::message::player_equips_item(id, player_equip_item, self.entity_gateway.clone(), &self.clients, &mut self.item_state).await? }, GameMessage::PlayerUnequipItem(player_unequip_item) => { - handler::message::player_unequips_item(id, player_unequip_item, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? + handler::message::player_unequips_item(id, player_unequip_item, self.entity_gateway.clone(), &self.clients, &mut self.item_state).await? }, GameMessage::SortItems(sort_items) => { - handler::message::player_sorts_items(id, sort_items, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? + handler::message::player_sorts_items(id, sort_items, self.entity_gateway.clone(), &self.clients, &mut self.item_state).await? }, GameMessage::PlayerSoldItem(player_sold_item) => { - handler::message::player_sells_item(id, player_sold_item, &mut self.entity_gateway, &mut self.clients, &mut self.item_state).await? + handler::message::player_sells_item(id, player_sold_item, self.entity_gateway.clone(), &mut self.clients, &mut self.item_state).await? }, _ => { let cmsg = msg.clone(); @@ -577,31 +577,31 @@ impl ShipServerState { handler::direct_message::guildcard_send(id, guildcard_send, target, &block.client_location, &self.clients) }, GameMessage::RequestItem(request_item) => { - handler::direct_message::request_item(id, request_item, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut block.rooms, &mut self.item_state).await? + handler::direct_message::request_item(id, request_item, self.entity_gateway.clone(), &block.client_location, &mut self.clients, &mut block.rooms, &mut self.item_state).await? }, GameMessage::PickupItem(pickup_item) => { - handler::direct_message::pickup_item(id, pickup_item, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_state).await? + handler::direct_message::pickup_item(id, pickup_item, self.entity_gateway.clone(), &block.client_location, &mut self.clients, &mut self.item_state).await? }, GameMessage::BoxDropRequest(box_drop_request) => { - handler::direct_message::request_box_item(id, box_drop_request, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut block.rooms, &mut self.item_state).await? + handler::direct_message::request_box_item(id, box_drop_request, self.entity_gateway.clone(), &block.client_location, &mut self.clients, &mut block.rooms, &mut self.item_state).await? }, GameMessage::BankRequest(_bank_request) => { handler::direct_message::send_bank_list(id, &self.clients, &mut self.item_state).await? }, GameMessage::BankInteraction(bank_interaction) => { - handler::direct_message::bank_interaction(id, bank_interaction, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_state).await? + handler::direct_message::bank_interaction(id, bank_interaction, self.entity_gateway.clone(), &block.client_location, &mut self.clients, &mut self.item_state).await? }, GameMessage::ShopRequest(shop_request) => { handler::direct_message::shop_request(id, shop_request, &block.client_location, &mut self.clients, &block.rooms, &self.level_table, &mut self.shops).await? }, GameMessage::BuyItem(buy_item) => { - handler::direct_message::buy_item(id, buy_item, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_state).await? + handler::direct_message::buy_item(id, buy_item, self.entity_gateway.clone(), &block.client_location, &mut self.clients, &mut self.item_state).await? }, GameMessage::TekRequest(tek_request) => { - handler::direct_message::request_tek_item(id, tek_request, &mut self.entity_gateway, &mut self.clients, &mut self.item_state).await? + handler::direct_message::request_tek_item(id, tek_request, self.entity_gateway.clone(), &mut self.clients, &mut self.item_state).await? }, GameMessage::TekAccept(tek_accept) => { - handler::direct_message::accept_tek_item(id, tek_accept, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_state).await? + handler::direct_message::accept_tek_item(id, tek_accept, self.entity_gateway.clone(), &block.client_location, &mut self.clients, &mut self.item_state).await? }, GameMessage::TradeRequest(trade_request) => { handler::trade::trade_request(id, trade_request, target, &block.client_location, &mut self.clients, &mut self.item_state, &mut self.trades).await? @@ -619,7 +619,7 @@ impl ShipServerState { } #[async_trait::async_trait] -impl ServerState for ShipServerState { +impl ServerState for ShipServerState { type SendPacket = SendShipPacket; type RecvPacket = RecvShipPacket; type PacketError = anyhow::Error; @@ -647,7 +647,7 @@ impl ServerState for ShipServerState { Ok(match pkt { RecvShipPacket::Login(login) => { - Box::new(handler::auth::validate_login(id, login, &mut self.entity_gateway, &mut self.clients, &mut self.item_state, &self.shipgate_sender, &self.name, self.blocks.0.len()) + Box::new(handler::auth::validate_login(id, login, self.entity_gateway.clone(), &mut self.clients, &mut self.item_state, &self.shipgate_sender, &self.name, self.blocks.0.len()) .await?.into_iter().map(move |pkt| (id, pkt))) }, RecvShipPacket::QuestDetailRequest(questdetailrequest) => { @@ -721,14 +721,14 @@ impl ServerState for ShipServerState { handler::room::room_name_request(id, &block.client_location, &block.rooms) }, RecvShipPacket::UpdateConfig(pkt) => { - handler::settings::update_config(id, pkt, &mut self.clients, &mut self.entity_gateway).await + handler::settings::update_config(id, pkt, &mut self.clients, self.entity_gateway.clone()).await }, RecvShipPacket::ViewInfoboardRequest(_pkt) => { let block = self.blocks.with_client(id, &self.clients)?; handler::communication::request_infoboard(id, &block.client_location, &self.clients) }, RecvShipPacket::WriteInfoboard(pkt) => { - handler::communication::write_infoboard(id, pkt, &mut self.clients, &mut self.entity_gateway).await + handler::communication::write_infoboard(id, pkt, &mut self.clients, self.entity_gateway.clone()).await }, RecvShipPacket::RoomListRequest(_req) => { let block = self.blocks.with_client(id, &self.clients)?; @@ -752,7 +752,7 @@ impl ServerState for ShipServerState { }, RecvShipPacket::LobbySelect(pkt) => { let block = self.blocks.with_client(id, &self.clients)?; - Box::new(handler::lobby::change_lobby(id, pkt.lobby, &mut block.client_location, &self.clients, &mut self.item_state, &self.level_table, &mut block.rooms, &mut self.entity_gateway).await?.into_iter()) + Box::new(handler::lobby::change_lobby(id, pkt.lobby, &mut block.client_location, &self.clients, &mut self.item_state, &self.level_table, &mut block.rooms, self.entity_gateway.clone()).await?.into_iter()) }, RecvShipPacket::RequestQuestList(rql) => { let block = self.blocks.with_client(id, &self.clients)?; @@ -774,7 +774,7 @@ impl ServerState for ShipServerState { Box::new(None.into_iter()) }, RecvShipPacket::SaveOptions(save_options) => { - handler::settings::save_options(id, save_options, &mut self.clients, &mut self.entity_gateway).await + handler::settings::save_options(id, save_options, &mut self.clients, self.entity_gateway.clone()).await }, RecvShipPacket::RequestShipList(_) => { handler::ship::ship_list(id, &self.ship_list) @@ -788,13 +788,13 @@ impl ServerState for ShipServerState { }, RecvShipPacket::TradeConfirmed(_) => { let block = self.blocks.with_client(id, &self.clients)?; - handler::trade::trade_confirmed(id, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_state, &mut self.trades).await? + handler::trade::trade_confirmed(id, self.entity_gateway.clone(), &block.client_location, &mut self.clients, &mut self.item_state, &mut self.trades).await? }, RecvShipPacket::KeyboardConfig(keyboard_config) => { - handler::settings::keyboard_config(id, keyboard_config, &mut self.clients, &mut self.entity_gateway).await + handler::settings::keyboard_config(id, keyboard_config, &mut self.clients, self.entity_gateway.clone()).await }, RecvShipPacket::GamepadConfig(gamepad_config) => { - handler::settings::gamepad_config(id, gamepad_config, &mut self.clients, &mut self.entity_gateway).await + handler::settings::gamepad_config(id, gamepad_config, &mut self.clients, self.entity_gateway.clone()).await }, }) } @@ -839,7 +839,7 @@ impl ServerState for ShipServerState { #[async_trait::async_trait] -impl InterserverActor for ShipServerState { +impl InterserverActor for ShipServerState { type SendMessage = ShipMessage; type RecvMessage = LoginMessage; type Error = (); diff --git a/tests/common.rs b/tests/common.rs index cf958c8..0243945 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -13,7 +13,7 @@ use libpso::packet::login::{Login, Session}; use libpso::{utf8_to_array, utf8_to_utf16_array}; -pub async fn new_user_character(entity_gateway: &mut EG, username: &str, password: &str, kb_conf_preset: usize) -> (UserAccountEntity, CharacterEntity) { +pub async fn new_user_character(entity_gateway: &mut EG, username: &str, password: &str, kb_conf_preset: usize) -> (UserAccountEntity, CharacterEntity) { let new_user = NewUserAccountEntity { email: format!("{}@pso.com", username), username: username.into(), @@ -34,7 +34,7 @@ pub async fn new_user_character(entity_gateway: &mut EG, user (user, character) } -pub async fn log_in_char(ship: &mut ShipServerState, id: ClientId, username: &str, password: &str) { +pub async fn log_in_char(ship: &mut ShipServerState, id: ClientId, username: &str, password: &str) { let username = username.to_string(); let password = password.to_string(); ship.handle(id, &RecvShipPacket::Login(Login { @@ -52,24 +52,24 @@ pub async fn log_in_char(ship: &mut ShipServerState, id: })).await.unwrap().for_each(drop); } -pub async fn join_lobby(ship: &mut ShipServerState, id: ClientId) { +pub async fn join_lobby(ship: &mut ShipServerState, id: ClientId) { ship.handle(id, &RecvShipPacket::CharData(CharData { _unknown: [0; 0x828] })).await.unwrap().for_each(drop); } -pub async fn create_room(ship: &mut ShipServerState, id: ClientId, name: &str, password: &str) { +pub async fn create_room(ship: &mut ShipServerState, id: ClientId, name: &str, password: &str) { create_room_with_difficulty(ship, id, name, password, Difficulty::Normal).await; } -pub async fn leave_room(ship: &mut ShipServerState, id: ClientId) { +pub async fn leave_room(ship: &mut ShipServerState, id: ClientId) { ship.handle(id, &RecvShipPacket::LobbySelect(LobbySelect { menu: 3, lobby: 0, })).await.unwrap().for_each(drop); } -pub async fn create_room_with_difficulty(ship: &mut ShipServerState, id: ClientId, name: &str, password: &str, difficulty: Difficulty) { +pub async fn create_room_with_difficulty(ship: &mut ShipServerState, id: ClientId, name: &str, password: &str, difficulty: Difficulty) { ship.handle(id, &RecvShipPacket::CreateRoom(CreateRoom { unknown: [0; 2], name: utf8_to_utf16_array!(name, 16), @@ -84,7 +84,7 @@ pub async fn create_room_with_difficulty(ship: &mut ShipServe ship.handle(id, &RecvShipPacket::DoneBursting(DoneBursting {})).await.unwrap().for_each(drop); } -pub async fn join_room(ship: &mut ShipServerState, id: ClientId, room_id: u32) { +pub async fn join_room(ship: &mut ShipServerState, id: ClientId, room_id: u32) { ship.handle(id, &RecvShipPacket::MenuSelect(MenuSelect { menu: ROOM_MENU_ID, item: room_id, diff --git a/tests/test_trade.rs b/tests/test_trade.rs index fd2c1b7..0d97cd7 100644 --- a/tests/test_trade.rs +++ b/tests/test_trade.rs @@ -15,7 +15,7 @@ use libpso::packet::messages::*; mod common; use common::*; -async fn initialize_trade(ship: &mut ShipServerState, client1: ClientId, client2: ClientId) { +async fn initialize_trade(ship: &mut ShipServerState, client1: ClientId, client2: ClientId) { ship.handle(client1, &RecvShipPacket::DirectMessage(DirectMessage::new(client2.0 as u32 -1, GameMessage::TradeRequest(TradeRequest { client: client1.0 as u8 -1, target: 0, @@ -29,7 +29,7 @@ async fn initialize_trade(ship: &mut ShipServerState, cli })))).await.unwrap().for_each(drop); } -async fn confirm_trade(ship: &mut ShipServerState, client1: ClientId, client2: ClientId) { +async fn confirm_trade(ship: &mut ShipServerState, client1: ClientId, client2: ClientId) { ship.handle(client1, &RecvShipPacket::DirectMessage(DirectMessage::new(client2.0 as u32 -1, GameMessage::TradeRequest(TradeRequest { client: client1.0 as u8 -1, target: 0, @@ -43,7 +43,7 @@ async fn confirm_trade(ship: &mut ShipServerState, client })))).await.unwrap().for_each(drop); } -async fn finalconfirm_trade(ship: &mut ShipServerState, client1: ClientId, client2: ClientId) { +async fn finalconfirm_trade(ship: &mut ShipServerState, client1: ClientId, client2: ClientId) { ship.handle(client1, &RecvShipPacket::DirectMessage(DirectMessage::new(client2.0 as u32 -1, GameMessage::TradeRequest(TradeRequest { client: client1.0 as u8 -1, target: 0,