Browse Source

satiate the clip's hunger for properness

pull/65/head
jake 2 years ago
parent
commit
ea4c085dfd
  1. 8
      src/entity/gateway/postgres/postgres.rs
  2. 1
      src/entity/item/mod.rs
  3. 3
      src/entity/item/weapon.rs
  4. 15
      src/ship/character.rs
  5. 6
      src/ship/items/manager.rs
  6. 1
      src/ship/map/area.rs
  7. 4
      src/ship/map/maps.rs
  8. 15
      src/ship/packet/handler/direct_message.rs
  9. 19
      src/ship/packet/handler/message.rs
  10. 8
      src/ship/packet/handler/quest.rs
  11. 4
      src/ship/packet/handler/room.rs
  12. 8
      src/ship/packet/handler/trade.rs
  13. 6
      src/ship/ship.rs
  14. 2
      src/ship/trade.rs

8
src/entity/gateway/postgres/postgres.rs

@ -147,13 +147,13 @@ impl EntityGateway for PostgresGateway {
let new_settings = sqlx::query_as::<_, PgUserSettings>("insert into user_settings (user_account, blocked_users, key_config, joystick_config, option_flags, shortcuts, symbol_chats, team_name)
values ($1, $2, $3, $4, $5, $6, $7, $8) returning *;")
.bind(settings.user_id.0)
.bind(settings.settings.blocked_users.to_vec().into_iter().map(|i| i.to_le_bytes().to_vec()).flatten().collect::<Vec<u8>>())
.bind(settings.settings.blocked_users.iter().copied().flat_map(|i| i.to_le_bytes().to_vec()).collect::<Vec<u8>>())
.bind(settings.settings.key_config.to_vec())
.bind(settings.settings.joystick_config.to_vec())
.bind(settings.settings.option_flags as i32)
.bind(settings.settings.shortcuts.to_vec())
.bind(settings.settings.symbol_chats.to_vec())
.bind(settings.settings.team_name.to_vec().into_iter().map(|i| i.to_le_bytes().to_vec()).flatten().collect::<Vec<u8>>())
.bind(settings.settings.team_name.iter().copied().flat_map(|i| i.to_le_bytes().to_vec()).collect::<Vec<u8>>())
.fetch_one(&self.pool).await?;
Ok(new_settings.into())
}
@ -167,13 +167,13 @@ impl EntityGateway for PostgresGateway {
async fn save_user_settings(&mut self, settings: &UserSettingsEntity) -> Result<(), GatewayError> {
sqlx::query("update user_settings set blocked_users=$1, key_config=$2, joystick_config=$3, option_flags=$4, shortcuts=$5, symbol_chats=$6, team_name=$7 where id=$8")
.bind(settings.settings.blocked_users.to_vec().into_iter().map(|i| i.to_le_bytes().to_vec()).flatten().collect::<Vec<u8>>())
.bind(settings.settings.blocked_users.iter().copied().flat_map(|i| i.to_le_bytes().to_vec()).collect::<Vec<u8>>())
.bind(&settings.settings.key_config.to_vec())
.bind(&settings.settings.joystick_config.to_vec())
.bind(&settings.settings.option_flags)
.bind(&settings.settings.shortcuts.to_vec())
.bind(&settings.settings.symbol_chats.to_vec())
.bind(settings.settings.team_name.to_vec().into_iter().map(|i| i.to_le_bytes().to_vec()).flatten().collect::<Vec<u8>>())
.bind(settings.settings.team_name.iter().copied().flat_map(|i| i.to_le_bytes().to_vec()).collect::<Vec<u8>>())
.bind(&settings.id.0)
.fetch_one(&self.pool).await?;
Ok(())

1
src/entity/item/mod.rs

@ -202,6 +202,7 @@ impl std::convert::From<Vec<ItemEntity>> for InventoryItemEntity {
}
impl InventoryItemEntity {
#[must_use]
pub fn map_individual<F: Fn(ItemEntity) -> ItemEntity>(self, func: F) -> InventoryItemEntity {
match self {
InventoryItemEntity::Individual(item) => InventoryItemEntity::Individual(func(item)),

3
src/entity/item/weapon.rs

@ -93,6 +93,8 @@ impl WeaponSpecial {
pub fn value(&self) -> u8 {
*self as u8
}
#[must_use]
pub fn rank_up(&self) -> WeaponSpecial {
match self {
WeaponSpecial::Draw => WeaponSpecial::Drain,
@ -138,6 +140,7 @@ impl WeaponSpecial {
}
}
#[must_use]
pub fn rank_down(&self) -> WeaponSpecial {
match self {
WeaponSpecial::Draw => WeaponSpecial::Draw,

15
src/ship/character.rs

@ -14,6 +14,7 @@ pub struct CharacterBytesBuilder<'a> {
}
impl<'a> CharacterBytesBuilder<'a> {
#[must_use]
pub fn character(self, character: &'a CharacterEntity) -> CharacterBytesBuilder<'a> {
CharacterBytesBuilder {
character: Some(character),
@ -21,6 +22,7 @@ impl<'a> CharacterBytesBuilder<'a> {
}
}
#[must_use]
pub fn stats(self, stats: &'a CharacterStats) -> CharacterBytesBuilder<'a> {
CharacterBytesBuilder {
stats: Some(stats),
@ -28,6 +30,7 @@ impl<'a> CharacterBytesBuilder<'a> {
}
}
#[must_use]
pub fn level(self, level: u32) -> CharacterBytesBuilder<'a> {
CharacterBytesBuilder {
level: Some(level),
@ -35,6 +38,7 @@ impl<'a> CharacterBytesBuilder<'a> {
}
}
#[must_use]
pub fn meseta(self, meseta: Meseta) -> CharacterBytesBuilder<'a> {
CharacterBytesBuilder {
meseta: Some(meseta),
@ -95,6 +99,7 @@ pub struct FullCharacterBytesBuilder<'a> {
}
impl<'a> FullCharacterBytesBuilder<'a> {
#[must_use]
pub fn character(self, character: &'a CharacterEntity) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
character: Some(character),
@ -102,6 +107,7 @@ impl<'a> FullCharacterBytesBuilder<'a> {
}
}
#[must_use]
pub fn stats(self, stats: &'a CharacterStats) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
stats: Some(stats),
@ -109,6 +115,7 @@ impl<'a> FullCharacterBytesBuilder<'a> {
}
}
#[must_use]
pub fn level(self, level: u32) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
level: Some(level),
@ -116,6 +123,7 @@ impl<'a> FullCharacterBytesBuilder<'a> {
}
}
#[must_use]
pub fn meseta(self, meseta: Meseta) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
meseta: Some(meseta),
@ -123,6 +131,7 @@ impl<'a> FullCharacterBytesBuilder<'a> {
}
}
#[must_use]
pub fn inventory(self, inventory: &'a CharacterInventory) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
inventory: Some(inventory),
@ -130,6 +139,7 @@ impl<'a> FullCharacterBytesBuilder<'a> {
}
}
#[must_use]
pub fn bank(self, bank: &'a CharacterBank) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
bank: Some(bank),
@ -137,6 +147,7 @@ impl<'a> FullCharacterBytesBuilder<'a> {
}
}
#[must_use]
pub fn key_config(self, key_config: &'a [u8; 0x16C]) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
key_config: Some(key_config),
@ -144,6 +155,7 @@ impl<'a> FullCharacterBytesBuilder<'a> {
}
}
#[must_use]
pub fn joystick_config(self, joystick_config: &'a [u8; 0x38]) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
joystick_config: Some(joystick_config),
@ -151,6 +163,7 @@ impl<'a> FullCharacterBytesBuilder<'a> {
}
}
#[must_use]
pub fn symbol_chat(self, symbol_chat: &'a [u8; 1248]) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
symbol_chat: Some(symbol_chat),
@ -158,6 +171,7 @@ impl<'a> FullCharacterBytesBuilder<'a> {
}
}
#[must_use]
pub fn tech_menu(self, tech_menu: &'a [u8; 40]) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
tech_menu: Some(tech_menu),
@ -165,6 +179,7 @@ impl<'a> FullCharacterBytesBuilder<'a> {
}
}
#[must_use]
pub fn option_flags(self, option_flags: u32) -> FullCharacterBytesBuilder<'a> {
FullCharacterBytesBuilder {
option_flags: Some(option_flags),

6
src/ship/items/manager.rs

@ -1003,7 +1003,7 @@ impl ItemManager {
inventory.add_item(InventoryItem::Individual(IndividualInventoryItem {
entity_id,
item_id,
item: ItemDetail::Weapon(weapon.clone()),
item: ItemDetail::Weapon(weapon),
}));
entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?;
@ -1066,9 +1066,9 @@ impl ItemManager {
TradeItem::Stacked(item_id, amount) => {
let stacked_inventory_item = src_inventory
.get_item_by_id(*item_id)
.ok_or_else(|| TradeError::InvalidItemId(*item_id))?
.ok_or(TradeError::InvalidItemId(*item_id))?
.stacked()
.ok_or_else(|| TradeError::InvalidItemId(*item_id))?;
.ok_or(TradeError::InvalidItemId(*item_id))?;
match dest_inventory.space_for_stacked_item(&stacked_inventory_item.tool, *amount) {
SpaceForStack::Yes(YesThereIsSpace::ExistingStack) => {
Ok(acc)

1
src/ship/map/area.rs

@ -293,6 +293,7 @@ pub struct MapAreaLookupBuilder {
}
impl MapAreaLookupBuilder {
#[must_use]
pub fn add(mut self, value: u16, map_area: MapArea) -> MapAreaLookupBuilder {
self.map_areas.insert(value, map_area);
self

4
src/ship/map/maps.rs

@ -277,9 +277,9 @@ impl Maps {
enemy_data.append(&mut enemy_data_from_map_data(map_variant, &room_mode.episode()));
enemy_data
}),
object_data: map_variants.iter().map(|map_variant| {
object_data: map_variants.iter().flat_map(|map_variant| {
objects_from_map_data(map_variant.obj_file().into(), &room_mode.episode(), &map_variant.map)
}).flatten().collect(),
}).collect(),
map_variants,
};
maps

15
src/ship/packet/handler/direct_message.rs

@ -81,9 +81,9 @@ where
{
let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?;
let room = rooms.get_mut(room_id.0)
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?
.as_mut()
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?;
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?;
let monster = room.maps.enemy_by_id(request_item.enemy_id as usize)?;
if monster.dropped_item {
@ -187,9 +187,9 @@ EG: EntityGateway
{
let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?;
let room = rooms.get_mut(room_id.0)
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?
.as_mut()
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?;
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?;
let box_object = room.maps.object_by_id(box_drop_request.object_id as usize)?;
if box_object.dropped_item {
@ -297,13 +297,12 @@ where
};
Ok(Box::new(other_clients_in_area.into_iter()
.map(move |c| {
.flat_map(move |c| {
bank_action_pkts.clone().into_iter()
.map(move |pkt| {
(c.client, pkt)
})
})
.flatten()
))
}
@ -319,9 +318,9 @@ pub async fn shop_request(id: ClientId,
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?;
let room = rooms.get(room_id.0)
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?
.as_ref()
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?;
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?;
let level = level_table.get_level_from_exp(client.character.char_class, client.character.exp) as usize;
let shop_list = match shop_request.shop_type {
SHOP_OPTION_WEAPON => {

19
src/ship/packet/handler/message.rs

@ -20,9 +20,9 @@ pub async fn request_exp<EG: EntityGateway>(id: ClientId,
let area_client = client_location.get_local_client(id).map_err(|err| -> ClientLocationError { err.into() })?;
let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?;
let room = rooms.get_mut(room_id.0)
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?
.as_mut()
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?;
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?;
let monster = room.maps.enemy_by_id(request_exp.enemy_id as usize)?;
let monster_stats = room.monster_stats.get(&monster.monster).ok_or(ShipError::UnknownMonster(monster.monster))?;
@ -76,9 +76,9 @@ where
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?;
let room = rooms.get_mut(room_id.0)
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?
.as_mut()
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?;
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?;
let area = room.map_areas.get_area_map(player_drop_item.map_area)?;
item_manager.player_drop_item_on_shared_floor(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() })?;
@ -99,9 +99,9 @@ pub fn drop_coordinates(id: ClientId,
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?;
let room = rooms.get(room_id.0)
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?
.as_ref()
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?;
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?;
client.item_drop_location = Some(ItemDropLocation {
map_area: *room.map_areas.get_area_map(drop_coordinates.map_area)?,
@ -140,7 +140,7 @@ where
let clients_in_area = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?;
Ok(Box::new(clients_in_area.into_iter()
.map(move |c| {
.flat_map(move |c| {
std::iter::once((c.client, SendShipPacket::Message(Message::new(GameMessage::DropSplitStack(dropped_meseta_pkt.clone())))))
.chain(
if c.client != id {
@ -153,7 +153,6 @@ where
}
)
})
.flatten()
))
}
else {
@ -191,9 +190,9 @@ pub fn update_player_position(id: ClientId,
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
if let Ok(room_id) = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() }) {
let room = rooms.get(room_id.0)
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?
.as_ref()
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?;
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?;
match &message.msg {
GameMessage::PlayerChangedMap(p) => {

8
src/ship/packet/handler/quest.rs

@ -81,8 +81,8 @@ pub fn load_quest(id: ClientId, questmenuselect: &QuestMenuSelect, quests: &Ques
let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?;
let room = rooms.get_mut(room_id.0)
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?.as_mut()
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?;
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?.as_mut()
.ok_or(ShipError::InvalidRoom(room_id.0 as u32))?;
room.maps.set_quest_data(quest.enemies.clone(), quest.objects.clone());
room.map_areas = quest.map_areas.clone();
@ -95,9 +95,9 @@ pub fn load_quest(id: ClientId, questmenuselect: &QuestMenuSelect, quests: &Ques
client.done_loading_quest = false;
}
});
Ok(Box::new(area_clients.into_iter().map(move |c| {
Ok(Box::new(area_clients.into_iter().flat_map(move |c| {
vec![(c.client, SendShipPacket::QuestHeader(bin.clone())), (c.client, SendShipPacket::QuestHeader(dat.clone()))]
}).flatten()))
})))
}
pub fn quest_file_request(id: ClientId, quest_file_request: &QuestFileRequest, quests: &QuestList) -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> {

4
src/ship/packet/handler/room.rs

@ -156,14 +156,14 @@ pub fn done_bursting(id: ClientId,
}
let area_client = client_location.get_local_client(id).unwrap(); // TODO: unwrap
Box::new(client_location.get_client_neighbors(id).unwrap().into_iter() // TODO: unwrap
.map(move |client| {
.flat_map(move |client| {
vec![
(client.client, SendShipPacket::Message(Message::new(GameMessage::BurstDone(BurstDone {
client: area_client.local_client.id(),
target: 0
})))),
]
}).flatten())
}))
}
pub fn request_room_list(id: ClientId,

8
src/ship/packet/handler/trade.rs

@ -481,7 +481,7 @@ where
let clients_in_room = client_location.get_all_clients_by_client(id)?;
let traded_item_packets = traded_items
.into_iter()
.map(|item| {
.flat_map(|item| {
match item.item_detail {
ItemToTradeDetail::Individual(item_detail) => {
[
@ -503,8 +503,7 @@ where
},
}
})
.flatten()
.map(move |packet| {
.flat_map(move |packet| {
clients_in_room
.clone()
.into_iter()
@ -521,8 +520,7 @@ where
_ => Some((client.client, SendShipPacket::Message(Message::new(packet.clone()))))
}
})
})
.flatten();
});
let close_trade = vec![
(this.client(), SendShipPacket::TradeSuccessful(TradeSuccessful::default())),
(other.client(), SendShipPacket::TradeSuccessful(TradeSuccessful::default()))

6
src/ship/ship.rs

@ -355,31 +355,37 @@ impl<EG: EntityGateway> Default for ShipServerStateBuilder<EG> {
}
impl<EG: EntityGateway> ShipServerStateBuilder<EG> {
#[must_use]
pub fn gateway(mut self, entity_gateway: EG) -> ShipServerStateBuilder<EG> {
self.entity_gateway = Some(entity_gateway);
self
}
#[must_use]
pub fn name(mut self, name: String) -> ShipServerStateBuilder<EG> {
self.name = Some(name);
self
}
#[must_use]
pub fn ip(mut self, ip: Ipv4Addr) -> ShipServerStateBuilder<EG> {
self.ip = Some(ip);
self
}
#[must_use]
pub fn port(mut self, port: u16) -> ShipServerStateBuilder<EG> {
self.port = Some(port);
self
}
#[must_use]
pub fn auth_token(mut self, auth_token: AuthToken) -> ShipServerStateBuilder<EG> {
self.auth_token = Some(auth_token);
self
}
#[must_use]
pub fn blocks(mut self, num_blocks: usize) -> ShipServerStateBuilder<EG> {
self.num_blocks = num_blocks;
self

2
src/ship/trade.rs

@ -107,7 +107,7 @@ impl TradeState {
where
F: Fn(&mut ClientTradeState, &mut ClientTradeState) -> T
{
let mut c1 = self.trades.get(client).ok_or_else(|| TradeStateError::ClientNotInTrade(*client))?.borrow_mut();
let mut c1 = self.trades.get(client).ok_or(TradeStateError::ClientNotInTrade(*client))?.borrow_mut();
let mut c2 = self.trades.get(&c1.other_client).ok_or(TradeStateError::ClientNotInTrade(c1.other_client))?.borrow_mut();
// sanity check

Loading…
Cancel
Save