diff --git a/src/ship/packet/handler/lobby.rs b/src/ship/packet/handler/lobby.rs index 9d7ca08..d5506c4 100644 --- a/src/ship/packet/handler/lobby.rs +++ b/src/ship/packet/handler/lobby.rs @@ -8,6 +8,7 @@ use crate::ship::location::{ClientLocation, LobbyId, RoomLobby, ClientLocationEr use crate::ship::packet; use crate::ship::items::state::ItemState; use crate::entity::gateway::EntityGateway; +use crate::entity::room::RoomNote; use crate::ship::map::MapArea; use futures::future::join_all; @@ -89,14 +90,25 @@ where } }, RoomLobby::Room(old_room) => { + let room_entity_id = rooms.with(old_room, |room| Box::pin(async { + room.room_id + })).await?; if client_location.get_client_neighbors(id).await?.is_empty() { rooms.remove(old_room).await; } + + let character_id = clients.with(id, |client| Box::pin(async { + client.character.id + })).await?; clients.with(id, |client| { let mut item_state = item_state.clone(); + let mut entity_gateway = entity_gateway.clone(); Box::pin(async move { item_state.remove_character_from_room(&client.character).await; - })}).await?; + entity_gateway.add_room_note(room_entity_id, RoomNote::PlayerLeave { + character_id + }).await + })}).await??; }, } let leave_lobby = packet::builder::lobby::remove_from_lobby(id, client_location).await?; diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index ca9ea5b..466a58a 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -9,7 +9,7 @@ use crate::common::serverstate::ClientId; use crate::common::leveltable::LEVEL_TABLE; use crate::entity::gateway::EntityGateway; use crate::entity::character::SectionID; -use crate::entity::room::{RoomEntity, RoomEntityId, NewRoomEntity, RoomEntityMode}; +use crate::entity::room::{RoomEntity, RoomEntityId, NewRoomEntity, RoomEntityMode, RoomNote}; use crate::ship::drops::DropTable; use crate::ship::ship::{SendShipPacket, Clients, ShipEvent}; use crate::ship::room::{Rooms, Episode, Difficulty, RoomState, RoomMode}; @@ -57,7 +57,6 @@ where let room_id = client_location.create_new_room(id).await?; let new_area_client = client_location.get_local_client(id).await?; - let name = String::from_utf16_lossy(&create_room.name).trim_matches(char::from(0)).to_string(); let mode = match (create_room.battle, create_room.challenge, create_room.single_player) { (1, 0, 0) => RoomEntityMode::Battle, @@ -81,6 +80,10 @@ where difficulty, }).await?; + entity_gateway.add_room_note(room_entity.id, RoomNote::Create { + character_id: client.character.id, + }).await?; + let mut room = RoomState::new(room_entity.id, mode, episode, difficulty, client.character.section_id, name, create_room.password, event, map_builder, drop_table_builder)?; @@ -121,14 +124,18 @@ pub async fn room_name_request(id: ClientId, } } -pub async fn join_room(id: ClientId, - pkt: MenuSelect, - client_location: &mut ClientLocation, - clients: &Clients, - item_state: &mut ItemState, - rooms: &Rooms, - event: ShipEvent) - -> Result, anyhow::Error> { +pub async fn join_room(id: ClientId, + pkt: MenuSelect, + entity_gateway: &mut EG, + client_location: &mut ClientLocation, + clients: &Clients, + item_state: &mut ItemState, + rooms: &Rooms, + event: ShipEvent) + -> Result, anyhow::Error> +where + EG: EntityGateway + Clone + 'static, +{ let room_id = RoomId(pkt.item as usize); if !rooms.exists(room_id).await { return Ok(vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("This room no longer exists!".into())))]) @@ -136,8 +143,8 @@ pub async fn join_room(id: ClientId, let level = clients.with(id, |client| Box::pin(async move { LEVEL_TABLE.get_level_from_exp(client.character.char_class, client.character.exp) })).await?; - let (difficulty, bursting) = rooms.with(room_id, |room| Box::pin(async move { - (room.mode.difficulty(), room.bursting) + let (difficulty, bursting, room_entity_id) = rooms.with(room_id, |room| Box::pin(async move { + (room.mode.difficulty(), room.bursting, room.room_id) })).await?; match difficulty { @@ -166,9 +173,14 @@ pub async fn join_room(id: ClientId, clients.with(id, |client| { let mut item_state = item_state.clone(); + let mut entity_gateway = entity_gateway.clone(); Box::pin(async move { + entity_gateway.add_room_note(room_entity_id, RoomNote::PlayerJoin { + character_id: client.character.id, + }).await?; item_state.add_character_to_room(room_id, &client.character, area_client).await; - })}).await?; + Ok::<_, anyhow::Error>(()) + })}).await??; let join_room = rooms.with(room_id, |room| { let clients = clients.clone(); @@ -185,7 +197,7 @@ pub async fn join_room(id: ClientId, rooms.with_mut(room_id, |room| Box::pin(async move { room.bursting = true; })).await?; - + Ok(vec![(id, SendShipPacket::JoinRoom(join_room))] .into_iter() .chain(original_room_clients.into_iter() diff --git a/src/ship/ship.rs b/src/ship/ship.rs index e4d94c8..8d9e4e0 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -20,6 +20,7 @@ use crate::common::interserver::{AuthToken, Ship, ServerId, InterserverActor, Lo use crate::login::character::SHIP_MENU_ID; use crate::entity::gateway::{EntityGateway, GatewayError}; use crate::entity::character::SectionID; +use crate::entity::room::RoomNote; use crate::ship::location::{ClientLocation, RoomLobby, ClientLocationError, RoomId}; use crate::ship::drops::DropTable; use crate::ship::items; @@ -700,7 +701,7 @@ impl ServerState for ShipServerState { let select_block = handler::lobby::block_selected(id, menuselect, &self.clients, &self.item_state).await?.into_iter(); leave_lobby.chain(select_block).collect() } - ROOM_MENU_ID => handler::room::join_room(id, menuselect, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await?, + ROOM_MENU_ID => handler::room::join_room(id, menuselect, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await?, QUEST_CATEGORY_MENU_ID => handler::quest::select_quest_category(id, menuselect, &block.client_location, &block.rooms).await?, _ => unreachable!(), } @@ -725,7 +726,7 @@ impl ServerState for ShipServerState { menu: room_password_req.menu, item: room_password_req.item, }; - handler::room::join_room(id, menuselect, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await? + handler::room::join_room(id, menuselect, &mut self.entity_gateway, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await? } else { vec![(id, SendShipPacket::SmallDialog(SmallDialog::new("Incorrect password".into())))] @@ -853,6 +854,16 @@ impl ServerState for ShipServerState { let pkt = match block.client_location.get_area(id).await? { RoomLobby::Room(room) => { + let character_id = self.clients.with(id, |client| Box::pin(async { + client.character.id + })).await?; + block.rooms.with(room, |room| { + let mut entity_gateway = self.entity_gateway.clone(); + Box::pin(async move { + entity_gateway.add_room_note(room.room_id, RoomNote::PlayerJoin { + character_id: character_id, + }).await + })}).await; if neighbors.is_empty() { block.rooms.remove(room).await; }