From 6ced59a73077289c9d65f5592571557426fb30ee Mon Sep 17 00:00:00 2001 From: jake Date: Wed, 19 Oct 2022 19:10:15 -0600 Subject: [PATCH] holidays! (with rappies) --- src/bin/main.rs | 6 ++- src/ship/map/enemy.rs | 34 ++++++++------- src/ship/map/maps.rs | 18 +++++--- src/ship/packet/builder/lobby.rs | 12 ++--- src/ship/packet/builder/room.rs | 22 +++++----- src/ship/packet/handler/lobby.rs | 29 ++++++------ src/ship/packet/handler/quest.rs | 7 +-- src/ship/packet/handler/room.rs | 16 ++++--- src/ship/room.rs | 6 +-- src/ship/ship.rs | 75 +++++++++++++++++++++++++++++--- 10 files changed, 154 insertions(+), 71 deletions(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index 3195373..eb7c687 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -5,7 +5,7 @@ use elseware::common::interserver::AuthToken; use elseware::login::login::LoginServerState; use elseware::login::character::CharacterServerState; use elseware::patch::patch::{PatchServerState, generate_patch_tree, load_config, load_motd}; -use elseware::ship::ship::ShipServerStateBuilder; +use elseware::ship::ship::{ShipServerStateBuilder, ShipEvent}; #[allow(unused_imports)] use elseware::entity::gateway::{EntityGateway, InMemoryGateway, PostgresGateway}; @@ -364,6 +364,7 @@ fn main() { .name("US/Sona-Nyl".into()) .ip(Ipv4Addr::new(127,0,0,1)) .port(elseware::ship::ship::SHIP_PORT) + .event(ShipEvent::Halloween) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); @@ -378,7 +379,8 @@ fn main() { let ship_state = ShipServerStateBuilder::default() .name("EU/Dylath-Leen".into()) .ip(Ipv4Addr::new(127,0,0,1)) - .port(elseware::ship::ship::SHIP_PORT+200) + .port(elseware::ship::ship::SHIP_PORT+2000) + .event(ShipEvent::Christmas) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); diff --git a/src/ship/map/enemy.rs b/src/ship/map/enemy.rs index 0903c57..79dc3b8 100644 --- a/src/ship/map/enemy.rs +++ b/src/ship/map/enemy.rs @@ -5,6 +5,7 @@ use std::collections::HashMap; use byteorder::{LittleEndian, ReadBytesExt}; use thiserror::Error; +use crate::ship::ship::ShipEvent; use crate::ship::monster::MonsterType; use crate::ship::room::Episode; @@ -335,21 +336,24 @@ impl MapEnemy { guaranteed rare monsters don't count towards the limit */ #[must_use] - pub fn into_rare(self) -> MapEnemy { - match (self.monster, self.map_area.to_episode()) { - (MonsterType::RagRappy, Episode::One) => {MapEnemy {monster: MonsterType::AlRappy, shiny:true, ..self}}, - (MonsterType::RagRappy, Episode::Two) => {MapEnemy {monster: MonsterType::LoveRappy, shiny:true, ..self}}, - (MonsterType::Hildebear, _) => {MapEnemy {monster: MonsterType::Hildeblue, shiny:true, ..self}}, - (MonsterType::PoisonLily, _) => {MapEnemy {monster: MonsterType::NarLily, shiny:true, ..self}}, - (MonsterType::PofuillySlime, _) => {MapEnemy {monster: MonsterType::PouillySlime, shiny:true, ..self}}, - (MonsterType::SandRappyCrater, _) => {MapEnemy {monster: MonsterType::DelRappyCrater, shiny:true, ..self}}, - (MonsterType::ZuCrater, _) => {MapEnemy {monster: MonsterType::PazuzuCrater, shiny:true, ..self}}, - (MonsterType::Dorphon, _) => {MapEnemy {monster: MonsterType::DorphonEclair, shiny:true, ..self}}, - (MonsterType::SandRappyDesert, _) => {MapEnemy {monster: MonsterType::DelRappyDesert, shiny:true, ..self}}, - (MonsterType::ZuDesert, _) => {MapEnemy {monster: MonsterType::PazuzuDesert, shiny:true, ..self}}, - (MonsterType::MerissaA, _) => {MapEnemy {monster: MonsterType::MerissaAA, shiny:true, ..self}}, - (MonsterType::SaintMillion, _) => {MapEnemy {monster: MonsterType::Kondrieu, shiny:true, ..self}}, - (MonsterType::Shambertin, _) => {MapEnemy {monster: MonsterType::Kondrieu, shiny:true, ..self}}, + pub fn into_rare(self, event: ShipEvent) -> MapEnemy { + match (self.monster, self.map_area.to_episode(), event) { + (MonsterType::RagRappy, Episode::One, _) => {MapEnemy {monster: MonsterType::AlRappy, shiny:true, ..self}}, + (MonsterType::RagRappy, Episode::Two, ShipEvent::Easter) => {MapEnemy {monster: MonsterType::EasterRappy, shiny:true, ..self}}, + (MonsterType::RagRappy, Episode::Two, ShipEvent::Halloween) => {MapEnemy {monster: MonsterType::HalloRappy, shiny:true, ..self}}, + (MonsterType::RagRappy, Episode::Two, ShipEvent::Christmas) => {MapEnemy {monster: MonsterType::StRappy, shiny:true, ..self}}, + (MonsterType::RagRappy, Episode::Two, _) => {MapEnemy {monster: MonsterType::LoveRappy, shiny:true, ..self}}, + (MonsterType::Hildebear, _, _) => {MapEnemy {monster: MonsterType::Hildeblue, shiny:true, ..self}}, + (MonsterType::PoisonLily, _, _) => {MapEnemy {monster: MonsterType::NarLily, shiny:true, ..self}}, + (MonsterType::PofuillySlime, _, _) => {MapEnemy {monster: MonsterType::PouillySlime, shiny:true, ..self}}, + (MonsterType::SandRappyCrater, _, _) => {MapEnemy {monster: MonsterType::DelRappyCrater, shiny:true, ..self}}, + (MonsterType::ZuCrater, _, _) => {MapEnemy {monster: MonsterType::PazuzuCrater, shiny:true, ..self}}, + (MonsterType::Dorphon, _, _) => {MapEnemy {monster: MonsterType::DorphonEclair, shiny:true, ..self}}, + (MonsterType::SandRappyDesert, _, _) => {MapEnemy {monster: MonsterType::DelRappyDesert, shiny:true, ..self}}, + (MonsterType::ZuDesert, _, _) => {MapEnemy {monster: MonsterType::PazuzuDesert, shiny:true, ..self}}, + (MonsterType::MerissaA, _, _) => {MapEnemy {monster: MonsterType::MerissaAA, shiny:true, ..self}}, + (MonsterType::SaintMillion, _, _) => {MapEnemy {monster: MonsterType::Kondrieu, shiny:true, ..self}}, + (MonsterType::Shambertin, _, _) => {MapEnemy {monster: MonsterType::Kondrieu, shiny:true, ..self}}, _ => {self}, } } diff --git a/src/ship/map/maps.rs b/src/ship/map/maps.rs index febfa44..6eb5be3 100644 --- a/src/ship/map/maps.rs +++ b/src/ship/map/maps.rs @@ -6,6 +6,7 @@ use std::fs::File; use thiserror::Error; +use crate::ship::ship::ShipEvent; use crate::ship::monster::MonsterType; use crate::ship::room::{Episode, RoomMode}; @@ -186,7 +187,7 @@ pub struct Maps { } impl Maps { - pub fn new(room_mode: RoomMode, rare_monster_table: &enemy::RareMonsterAppearTable) -> Maps { + pub fn new(room_mode: RoomMode, rare_monster_table: &enemy::RareMonsterAppearTable, event: ShipEvent) -> Maps { let map_variants = match (room_mode.episode(), room_mode.single_player()) { (Episode::One, 0) => { vec![MapVariant::new(MapArea::Pioneer2Ep1, MapVariantMode::Online), @@ -284,7 +285,7 @@ impl Maps { enemy_data_from_map_data(map_variant, &room_mode.episode()) }) .flatten() - .map(|enemy| apply_rare_enemy(enemy, rare_monster_table)) + .map(|enemy| apply_rare_enemy(enemy, rare_monster_table, event)) .collect(), object_data: map_variants.iter() .flat_map(|map_variant| { @@ -314,10 +315,15 @@ impl Maps { }) } - pub fn set_quest_data(&mut self, enemies: Vec>, objects: Vec>, rare_monster_table: &RareMonsterAppearTable) { + pub fn set_quest_data(&mut self, + enemies: Vec>, + objects: Vec>, + rare_monster_table: &RareMonsterAppearTable, + event: ShipEvent) + { self.enemy_data = enemies .into_iter() - .map(|enemy| apply_rare_enemy(enemy, rare_monster_table)) + .map(|enemy| apply_rare_enemy(enemy, rare_monster_table, event)) .collect(); self.object_data = objects; } @@ -346,10 +352,10 @@ impl Maps { } } -fn apply_rare_enemy(enemy: Option, rare_enemy_table: &RareMonsterAppearTable) -> Option { +fn apply_rare_enemy(enemy: Option, rare_enemy_table: &RareMonsterAppearTable, event: ShipEvent) -> Option { enemy.map(|enemy| { if enemy.can_be_rare() && rare_enemy_table.roll_is_rare(&enemy.monster) { - enemy.into_rare() + enemy.into_rare(event) } else { enemy diff --git a/src/ship/packet/builder/lobby.rs b/src/ship/packet/builder/lobby.rs index 2571766..666d9be 100644 --- a/src/ship/packet/builder/lobby.rs +++ b/src/ship/packet/builder/lobby.rs @@ -1,6 +1,6 @@ use libpso::packet::ship::*; use crate::common::serverstate::ClientId; -use crate::ship::ship::{ShipError, Clients}; +use crate::ship::ship::{ShipError, Clients, ShipEvent}; use crate::ship::location::{ClientLocation, LobbyId, ClientLocationError}; use crate::ship::packet::builder::{player_info}; use crate::ship::items::state::ItemState; @@ -11,7 +11,8 @@ pub async fn join_lobby(id: ClientId, lobby: LobbyId, client_location: &ClientLocation, clients: &Clients, - item_state: &ItemState) + item_state: &ItemState, + event: ShipEvent) -> Result { let lobby_clients = client_location.get_clients_in_lobby(lobby).await.map_err(|err| -> ClientLocationError { err.into() })?; @@ -41,7 +42,7 @@ pub async fn join_lobby(id: ClientId, one: 1, lobby: lobby.id(), block: client_block, - event: 0, + event: event.into(), padding: 0, playerinfo, }) @@ -51,7 +52,8 @@ pub async fn add_to_lobby(id: ClientId, lobby: LobbyId, client_location: &ClientLocation, clients: &Clients, - item_state: &ItemState) + item_state: &ItemState, + event: ShipEvent) -> Result { let area_client = client_location.get_local_client(id).await.map_err(|err| -> ClientLocationError { err.into() })?; let leader = client_location.get_lobby_leader(lobby).await.map_err(|err| -> ClientLocationError { err.into() })?; @@ -66,7 +68,7 @@ pub async fn add_to_lobby(id: ClientId, one: 1, lobby: lobby.id(), block: client.block as u16, - event: 0, + event: event.into(), padding: 0, playerinfo: player_info(0x100, client, &area_client, &inventory).await, }) diff --git a/src/ship/packet/builder/room.rs b/src/ship/packet/builder/room.rs index 4ff4696..b50c7fb 100644 --- a/src/ship/packet/builder/room.rs +++ b/src/ship/packet/builder/room.rs @@ -1,6 +1,6 @@ use libpso::packet::ship::*; use crate::common::serverstate::ClientId; -use crate::ship::ship::{ShipError, ClientState, Clients}; +use crate::ship::ship::{ShipError, ClientState, Clients, ShipEvent}; use crate::ship::location::{ClientLocation, RoomId, AreaClient, ClientLocationError}; use crate::ship::room::RoomState; use crate::ship::items::state::ItemState; @@ -13,7 +13,8 @@ pub async fn join_room(id: ClientId, clients: &Clients, client_location: &ClientLocation, room_id: RoomId, - room: &RoomState) + room: &RoomState, + event: ShipEvent) -> Result { let all_clients = client_location.get_clients_in_room(room_id).await.map_err(|err| -> ClientLocationError { err.into() })?; let players = futures::stream::iter(all_clients.iter()) @@ -40,7 +41,7 @@ pub async fn join_room(id: ClientId, one: 1, difficulty: room.mode.difficulty().into(), battle: room.mode.battle(), - event: 0, + event: event.into(), section: room.section_id.into(), challenge: room.mode.challenge(), random_seed: room.random_seed, @@ -53,13 +54,12 @@ pub async fn join_room(id: ClientId, pub async fn add_to_room(_id: ClientId, - client: &ClientState, - area_client: &AreaClient, - leader: &AreaClient, - item_state: &ItemState, - _room_id: RoomId, -) - -> Result { + client: &ClientState, + area_client: &AreaClient, + leader: &AreaClient, + item_state: &ItemState, + event: ShipEvent) + -> Result { let inventory = item_state.get_character_inventory(&client.character).await?; Ok(AddToRoom { flag: 1, @@ -68,7 +68,7 @@ pub async fn add_to_room(_id: ClientId, one: 0, // TODO: ???????? lobby: 0xFF, block: 0, - event: 0, + event: event.into(), padding: 0, playerinfo: player_info(0x10000, client, area_client, &inventory).await, }) diff --git a/src/ship/packet/handler/lobby.rs b/src/ship/packet/handler/lobby.rs index 287ea41..f0caf23 100644 --- a/src/ship/packet/handler/lobby.rs +++ b/src/ship/packet/handler/lobby.rs @@ -1,7 +1,7 @@ use libpso::packet::ship::*; use crate::common::serverstate::ClientId; use crate::common::leveltable::LEVEL_TABLE; -use crate::ship::ship::{SendShipPacket, ShipError, Clients}; +use crate::ship::ship::{SendShipPacket, ShipError, Clients, ShipEvent}; use crate::ship::room::Rooms; use crate::ship::character::{FullCharacterBytesBuilder}; use crate::ship::location::{ClientLocation, LobbyId, RoomLobby, ClientLocationError, RoomId}; @@ -55,11 +55,12 @@ pub async fn send_player_to_lobby(id: ClientId, _pkt: CharData, client_location: &mut ClientLocation, clients: &Clients, - item_state: &ItemState) + item_state: &ItemState, + event: ShipEvent) -> Result, ShipError> { let lobby = client_location.add_client_to_next_available_lobby(id, LobbyId(0)).await.map_err(|_| ShipError::TooManyClients)?; - let join_lobby = packet::builder::lobby::join_lobby(id, lobby, client_location, clients, item_state).await?; - let addto = packet::builder::lobby::add_to_lobby(id, lobby, client_location, clients, item_state).await?; + let join_lobby = packet::builder::lobby::join_lobby(id, lobby, client_location, clients, item_state, event).await?; + let addto = packet::builder::lobby::add_to_lobby(id, lobby, client_location, clients, item_state, event).await?; let neighbors = client_location.get_client_neighbors(id).await.unwrap(); Ok(vec![(id, SendShipPacket::JoinLobby(join_lobby))] .into_iter() @@ -74,7 +75,8 @@ pub async fn change_lobby(id: ClientId, clients: &Clients, item_state: &mut ItemState, rooms: &Rooms, - entity_gateway: &mut EG) + entity_gateway: &mut EG, + event: ShipEvent) -> Result, ShipError> where EG: EntityGateway + Clone + 'static, @@ -117,16 +119,17 @@ where Box::pin(async move { item_state.load_character(&mut entity_gateway, &client.character).await })}).await??; - let join_lobby = packet::builder::lobby::join_lobby(id, lobby, client_location, clients, item_state).await?; - let addto = packet::builder::lobby::add_to_lobby(id, lobby, client_location, clients, item_state).await?; + let join_lobby = packet::builder::lobby::join_lobby(id, lobby, client_location, clients, item_state, event).await?; + let addto = packet::builder::lobby::add_to_lobby(id, lobby, client_location, clients, item_state, event).await?; let neighbors = client_location.get_client_neighbors(id).await?; Ok(vec![(id, SendShipPacket::JoinLobby(join_lobby))] - .into_iter() - .chain(neighbors.into_iter() - .map(|c| (c.client, SendShipPacket::AddToLobby(addto.clone())))) - .chain(old_neighbors.into_iter() - .map(|c| (c.client, SendShipPacket::LeaveLobby(leave_lobby.clone())))) - .collect()) + .into_iter() + .chain(neighbors.into_iter() + .map(|c| (c.client, SendShipPacket::AddToLobby(addto.clone())))) + .chain(old_neighbors.into_iter() + .map(|c| (c.client, SendShipPacket::LeaveLobby(leave_lobby.clone())))) + .chain(std::iter::once((id, SendShipPacket::LobbyEvent(LobbyEvent{ event: event.into()})))) + .collect()) } pub async fn remove_from_lobby(id: ClientId, diff --git a/src/ship/packet/handler/quest.rs b/src/ship/packet/handler/quest.rs index 9df89b9..a9a5cb2 100644 --- a/src/ship/packet/handler/quest.rs +++ b/src/ship/packet/handler/quest.rs @@ -2,7 +2,7 @@ use std::io::{Cursor, Read, Seek, SeekFrom}; use futures::stream::{FuturesOrdered, StreamExt}; use libpso::packet::ship::*; use crate::common::serverstate::ClientId; -use crate::ship::ship::{SendShipPacket, ShipError, Clients}; +use crate::ship::ship::{SendShipPacket, ShipError, Clients, ShipEvent}; use crate::ship::room::Rooms; use crate::ship::location::{ClientLocation, ClientLocationError}; use crate::ship::packet::builder::quest; @@ -94,7 +94,8 @@ pub async fn player_chose_quest(id: ClientId, questmenuselect: QuestMenuSelect, clients: &Clients, client_location: &ClientLocation, - rooms: &Rooms) + rooms: &Rooms, + event: ShipEvent) -> Result, ShipError> { let room_id = client_location.get_room(id).await.map_err(|err| -> ClientLocationError { err.into() })?; @@ -115,7 +116,7 @@ pub async fn player_chose_quest(id: ClientId, .clone(); let rare_monster_drops = room.rare_monster_table.clone(); - room.maps.set_quest_data(quest.enemies.clone(), quest.objects.clone(), &rare_monster_drops); + room.maps.set_quest_data(quest.enemies.clone(), quest.objects.clone(), &rare_monster_drops, event); room.map_areas = quest.map_areas.clone(); let bin = quest::quest_header(&questmenuselect, &quest.bin_blob, "bin"); diff --git a/src/ship/packet/handler/room.rs b/src/ship/packet/handler/room.rs index 7653abc..435d4b8 100644 --- a/src/ship/packet/handler/room.rs +++ b/src/ship/packet/handler/room.rs @@ -5,7 +5,7 @@ use libpso::packet::ship::*; use libpso::packet::messages::*; use crate::common::serverstate::ClientId; use crate::common::leveltable::LEVEL_TABLE; -use crate::ship::ship::{SendShipPacket, ShipError, Clients}; +use crate::ship::ship::{SendShipPacket, ShipError, Clients, ShipEvent}; use crate::ship::room::Rooms; use crate::ship::location::{ClientLocation, RoomId, RoomLobby, GetAreaError}; use crate::ship::packet::builder; @@ -17,7 +17,8 @@ pub async fn create_room(id: ClientId, client_location: &mut ClientLocation, clients: &Clients, item_state: &mut ItemState, - rooms: &Rooms) + rooms: &Rooms, + event: ShipEvent) -> Result, ShipError> { let level = clients.with(id, |client| Box::pin(async move { LEVEL_TABLE.get_level_from_exp(client.character.char_class, client.character.exp) @@ -44,12 +45,12 @@ pub async fn create_room(id: ClientId, let mut item_state = item_state.clone(); Box::pin(async move { item_state.add_character_to_room(room_id, &client.character, area_client).await; - let mut room = room::RoomState::from_create_room(&create_room, client.character.section_id)?; + let mut room = room::RoomState::from_create_room(&create_room, client.character.section_id, event)?; room.bursting = true; Ok::<_, ShipError>(room) })}).await??; - let join_room = builder::room::join_room(id, clients, client_location, room_id, &room).await?; + let join_room = builder::room::join_room(id, clients, client_location, room_id, &room, event).await?; rooms.add(room_id, room).await?; let mut result = vec![(id, SendShipPacket::JoinRoom(join_room))]; @@ -87,7 +88,8 @@ pub async fn join_room(id: ClientId, client_location: &mut ClientLocation, clients: &Clients, item_state: &mut ItemState, - rooms: &Rooms) + rooms: &Rooms, + event: ShipEvent) -> Result, ShipError> { let room_id = RoomId(pkt.item as usize); if !rooms.exists(room_id).await { @@ -134,12 +136,12 @@ pub async fn join_room(id: ClientId, let clients = clients.clone(); let client_location = client_location.clone(); Box::pin(async move { - builder::room::join_room(id, &clients, &client_location, room_id, room).await + builder::room::join_room(id, &clients, &client_location, room_id, room, event).await })}).await??; let add_to = clients.with(id, |client| { let item_state = item_state.clone(); Box::pin(async move { - builder::room::add_to_room(id, client, &area_client, &room_leader, &item_state, room_id).await + builder::room::add_to_room(id, client, &area_client, &room_leader, &item_state, event).await })}).await??; rooms.with_mut(room_id, |room| Box::pin(async move { diff --git a/src/ship/room.rs b/src/ship/room.rs index 9758064..ed41b8d 100644 --- a/src/ship/room.rs +++ b/src/ship/room.rs @@ -15,7 +15,7 @@ use crate::ship::monster::{load_monster_stats_table, MonsterType, MonsterStats}; use crate::ship::map::area::MapAreaLookup; use crate::ship::map::enemy::RareMonsterAppearTable; use crate::ship::quests; -use crate::ship::ship::ShipError; +use crate::ship::ship::{ShipError, ShipEvent}; use crate::ship::location::{MAX_ROOMS, RoomId}; @@ -343,7 +343,7 @@ impl RoomState { self.quest_group = QuestCategoryType::from(group); } - pub fn from_create_room(create_room: &libpso::packet::ship::CreateRoom, section_id: SectionID) -> Result { + pub fn from_create_room(create_room: &libpso::packet::ship::CreateRoom, section_id: SectionID, event: ShipEvent) -> Result { if [create_room.battle, create_room.challenge, create_room.single_player].iter().sum::() > 1 { return Err(RoomCreationError::InvalidMode) } @@ -410,7 +410,7 @@ impl RoomState { rare_monster_table: Box::new(rare_monster_table.clone()), name: String::from_utf16_lossy(&create_room.name).trim_matches(char::from(0)).into(), password: create_room.password, - maps: Maps::new(room_mode, &rare_monster_table), // TODO: rare_monster_table here feels janky. is there some way to call the the RoomState.rare_monster_table we already created? + maps: Maps::new(room_mode, &rare_monster_table, event), section_id, drop_table: Box::new(DropTable::new(room_mode.episode(), room_mode.difficulty(), section_id)), bursting: false, diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 50ddcad..d183ebf 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -42,6 +42,57 @@ pub const SHIP_PORT: u16 = 23423; pub const QUEST_CATEGORY_MENU_ID: u32 = 0xA2; pub const QUEST_SELECT_MENU_ID: u32 = 0xA3; +#[derive(Clone, Copy)] +pub enum ShipEvent { + None, + Christmas, + Valentines, + Easter, + Halloween, + Sonic, + NewYear, + Summer, + White, + Wedding, + Fall, + Spring, + Summer2, + Spring2, +} + +impl From for u32 { + fn from(other: ShipEvent) -> u32 { + u16::from(other) as u32 + } +} + +impl From for u16 { + fn from(other: ShipEvent) -> u16 { + u8::from(other) as u16 + } +} + +impl From for u8 { + fn from(other: ShipEvent) -> u8 { + match other { + ShipEvent::None => 0, + ShipEvent::Christmas => 1, + ShipEvent::Valentines => 3, + ShipEvent::Easter => 4, + ShipEvent::Halloween => 5, + ShipEvent::Sonic => 6, + ShipEvent::NewYear => 7, + ShipEvent::Summer => 8, + ShipEvent::White => 9, + ShipEvent::Wedding => 10, + ShipEvent::Fall => 11, + ShipEvent::Spring => 12, + ShipEvent::Summer2 => 13, + ShipEvent::Spring2 => 14, + } + } +} + #[derive(Error, Debug)] pub enum ShipError { @@ -240,6 +291,7 @@ pub enum SendShipPacket { AcknowledgeTrade(AcknowledgeTrade), CancelTrade(CancelTrade), TradeSuccessful(TradeSuccessful), + LobbyEvent(LobbyEvent), } impl SendServerPacket for SendShipPacket { @@ -282,6 +334,7 @@ impl SendServerPacket for SendShipPacket { SendShipPacket::AcknowledgeTrade(pkt) => pkt.as_bytes(), SendShipPacket::CancelTrade(pkt) => pkt.as_bytes(), SendShipPacket::TradeSuccessful(pkt) => pkt.as_bytes(), + SendShipPacket::LobbyEvent(pkt) => pkt.as_bytes(), } } } @@ -321,6 +374,7 @@ pub struct ShipServerStateBuilder { ip: Option, port: Option, auth_token: Option, + event: Option, num_blocks: usize, } @@ -332,6 +386,7 @@ impl Default for ShipServerStateBuilder ip: None, port: None, auth_token: None, + event: None, num_blocks: 2, } } @@ -368,6 +423,12 @@ impl ShipServerStateBuilder { self } + #[must_use] + pub fn event(mut self, event: ShipEvent) -> ShipServerStateBuilder { + self.event = Some(event); + self + } + #[must_use] pub fn blocks(mut self, num_blocks: usize) -> ShipServerStateBuilder { self.num_blocks = num_blocks; @@ -385,6 +446,7 @@ impl ShipServerStateBuilder { port: self.port.unwrap_or(SHIP_PORT), shops: ItemShops::default(), blocks: Blocks(blocks), + event: self.event.unwrap_or(ShipEvent::None), auth_token: self.auth_token.unwrap_or_else(|| AuthToken("".into())), ship_list: Vec::new(), @@ -424,6 +486,7 @@ pub struct ShipServerState { item_state: items::state::ItemState, shops: ItemShops, pub blocks: Blocks, + event: ShipEvent, ip: Ipv4Addr, port: u16, @@ -611,14 +674,14 @@ 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).await?, + ROOM_MENU_ID => handler::room::join_room(id, menuselect, &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!(), } }, RecvShipPacket::QuestMenuSelect(questmenuselect) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::quest::player_chose_quest(id, questmenuselect, &self.clients, &block.client_location, &block.rooms).await? + handler::quest::player_chose_quest(id, questmenuselect, &self.clients, &block.client_location, &block.rooms, self.event).await? }, RecvShipPacket::MenuDetail(menudetail) => { let block = self.blocks.get_from_client(id, &self.clients).await?; @@ -636,7 +699,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).await? + handler::room::join_room(id, menuselect, &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())))] @@ -644,7 +707,7 @@ impl ServerState for ShipServerState { }, RecvShipPacket::CharData(chardata) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::lobby::send_player_to_lobby(id, chardata, &mut block.client_location, &self.clients, &self.item_state).await? + handler::lobby::send_player_to_lobby(id, chardata, &mut block.client_location, &self.clients, &self.item_state, self.event).await? }, RecvShipPacket::Message(msg) => { self.message(id, msg).await? @@ -658,7 +721,7 @@ impl ServerState for ShipServerState { }, RecvShipPacket::CreateRoom(create_room) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::room::create_room(id, create_room, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms).await? + handler::room::create_room(id, create_room, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, self.event).await? }, RecvShipPacket::RoomNameRequest(_req) => { let block = self.blocks.get_from_client(id, &self.clients).await?; @@ -696,7 +759,7 @@ impl ServerState for ShipServerState { }, RecvShipPacket::LobbySelect(pkt) => { let block = self.blocks.get_from_client(id, &self.clients).await?; - handler::lobby::change_lobby(id, pkt.lobby, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, &mut self.entity_gateway).await? + handler::lobby::change_lobby(id, pkt.lobby, &mut block.client_location, &self.clients, &mut self.item_state, &block.rooms, &mut self.entity_gateway, self.event).await? }, RecvShipPacket::RequestQuestList(rql) => { let block = self.blocks.get_from_client(id, &self.clients).await?;