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