Compare commits

...

9 Commits

  1. 4
      src/bin/patch.rs
  2. 8
      src/common/mainloop/interserver.rs
  3. 32
      src/entity/item/mag.rs
  4. 5
      src/lib.rs
  5. 4
      src/login/character.rs
  6. 2
      src/ship/drops/box_drop_table.rs
  7. 4
      src/ship/drops/generic_armor.rs
  8. 2
      src/ship/drops/generic_shield.rs
  9. 6
      src/ship/drops/generic_weapon.rs
  10. 2
      src/ship/items/apply_item.rs
  11. 2
      src/ship/items/bank.rs
  12. 4
      src/ship/items/floor.rs
  13. 1
      src/ship/packet/builder/room.rs
  14. 4
      src/ship/shops/armor.rs
  15. 13
      src/ship/shops/tool.rs
  16. 4
      src/ship/shops/weapon.rs
  17. 4
      tests/common.rs
  18. 4
      tests/test_character.rs
  19. 1
      tests/test_exp_gain.rs
  20. 6
      tests/test_item_drop.rs
  21. 2
      tests/test_item_id.rs
  22. 3
      tests/test_rooms.rs
  23. 2
      tests/test_shops.rs
  24. 2
      tests/test_trade.rs

4
src/bin/patch.rs

@ -12,7 +12,5 @@ fn main() {
elseware::common::mainloop::run_server(patch_state, patch_config.port).await;
});
async_std::task::block_on(async move {
patch_loop.await
});
async_std::task::block_on(patch_loop);
}

8
src/common/mainloop/interserver.rs

@ -220,12 +220,8 @@ where
let mut buf = [0u8; 1];
loop {
let peek = socket.peek(&mut buf).await;
match peek {
Ok(len) if len == 0 => {
break
},
_ => {
}
if let Ok(0) = peek {
break
}
}
}

32
src/entity/item/mag.rs

@ -1029,10 +1029,30 @@ impl Mag {
MAG_STATS.get(&self.mag).map(|stats| {
MAG_FEEDING_TABLES.get(stats.feed_table).map(|feeding_table| {
feeding_table.get(&tool).map(|feed_stats| {
self.def = std::cmp::max(std::cmp::max((self.def as i16) + feed_stats.def, 0) as u16, self.def()*100);
self.pow = std::cmp::max(std::cmp::max((self.pow as i16) + feed_stats.pow, 0) as u16, self.pow()*100);
self.dex = std::cmp::max(std::cmp::max((self.dex as i16) + feed_stats.dex, 0) as u16, self.dex()*100);
self.mnd = std::cmp::max(std::cmp::max((self.mnd as i16) + feed_stats.mnd, 0) as u16, self.mind()*100);
self.def = {
if (self.def as i16 + feed_stats.def) < ((self.def()*100) as i16) {
self.def
} else {
std::cmp::max(std::cmp::max((self.def as i16) + feed_stats.def, 0) as u16, self.def()*100)
}};
self.pow = {
if (self.pow as i16 + feed_stats.pow) < ((self.pow()*100) as i16) {
self.pow
} else {
std::cmp::max(std::cmp::max((self.pow as i16) + feed_stats.pow, 0) as u16, self.pow()*100)
}};
self.dex = {
if (self.dex as i16 + feed_stats.dex) < ((self.dex()*100) as i16) {
self.dex
} else {
std::cmp::max(std::cmp::max((self.dex as i16) + feed_stats.dex, 0) as u16, self.dex()*100)
}};
self.mnd = {
if (self.mnd as i16 + feed_stats.mnd) < ((self.mind()*100) as i16) {
self.mnd
} else {
std::cmp::max(std::cmp::max((self.mnd as i16) + feed_stats.mnd, 0) as u16, self.mind()*100)
}};
self.iq = std::cmp::min(((self.iq as i16) + feed_stats.iq as i16) as u8, 200);
self.synchro = std::cmp::min(((self.synchro as i8) + feed_stats.syn) as u8, 120);
})
@ -1188,7 +1208,7 @@ mod test {
f.read_to_string(&mut s).unwrap();
let mut feed: HashMap<String, Vec<HashMap<String, MagFeedTable>>> = toml::from_str(&s).unwrap();
let feed = feed.remove("feedtable".into()).unwrap();
let feed = feed.remove("feedtable").unwrap();
let _feed = feed.into_iter()
.map(|table| {
table.into_iter()
@ -1219,7 +1239,7 @@ mod test {
}
assert!(mag == Mag {
mag: MagType::Sato,
def: 507,
def: 509,
pow: 5019,
dex: 4505,
mnd: 0,

5
src/lib.rs

@ -1,12 +1,11 @@
#![allow(clippy::type_complexity)]
#![allow(incomplete_features)]
#![feature(inline_const)]
#![feature(drain_filter)]
#![feature(extract_if)]
#![feature(try_blocks)]
#![feature(once_cell)]
#![feature(test)]
#![feature(error_generic_member_access)]
#![feature(provide_any)]
#![feature(lazy_cell)]
extern crate test;

4
src/login/character.rs

@ -484,7 +484,7 @@ impl<EG: EntityGateway + Clone> CharacterServerState<EG> {
async fn set_flag(&mut self, id: ClientId, setflag: &SetFlag) -> Result<std::option::IntoIter<SendCharacterPacket>, anyhow::Error> {
let mut client = self.clients.write().await;
let client = client.get_mut(&id).ok_or_else(|| CharacterError::ClientNotFound(id))?;
let mut user = client.user.as_mut().unwrap();
let user = client.user.as_mut().unwrap();
user.flags = setflag.flags;
self.entity_gateway.save_user(user).await.unwrap();
Ok(None.into_iter())
@ -515,7 +515,7 @@ impl<EG: EntityGateway + Clone> CharacterServerState<EG> {
async fn character_preview(&mut self, id: ClientId, preview: &CharacterPreview) -> Result<Vec<SendCharacterPacket>, anyhow::Error> {
let mut client = self.clients.write().await;
let client = client.get_mut(&id).ok_or_else(|| CharacterError::ClientNotFound(id))?;
let mut user = client.user.as_mut().unwrap();
let user = client.user.as_mut().unwrap();
if user.flags == USERFLAG_NEWCHAR {
new_character(&mut self.entity_gateway, user, preview).await?
}

2
src/ship/drops/box_drop_table.rs

@ -176,7 +176,7 @@ impl BoxDropTable {
fn random_box_drop<R: Rng>(&self, map_area: &MapArea, rng: &mut R) -> Option<ItemDropType> {
self.rare_drop(map_area, rng).or_else(|| {
let rate = self.box_rates.rates_by_area(map_area);
let type_weights = WeightedIndex::new(&[rate.weapon_rate, rate.armor_rate, rate.shield_rate, rate.unit_rate,
let type_weights = WeightedIndex::new([rate.weapon_rate, rate.armor_rate, rate.shield_rate, rate.unit_rate,
rate.tool_rate, rate.meseta_rate, rate.nothing_rate]).unwrap();
let btype = type_weights.sample(rng);
match btype {

4
src/ship/drops/generic_armor.rs

@ -46,7 +46,7 @@ impl GenericArmorTable {
}
fn armor_type<R: Rng>(&self, area_map: &MapArea, rng: &mut R) -> ArmorType {
let rank_weights = WeightedIndex::new(&[self.rank_rates.rank0, self.rank_rates.rank1, self.rank_rates.rank2,
let rank_weights = WeightedIndex::new([self.rank_rates.rank0, self.rank_rates.rank1, self.rank_rates.rank2,
self.rank_rates.rank3, self.rank_rates.rank4]).unwrap();
let rank = rank_weights.sample(rng) as i32;
let armor_level = std::cmp::max(0i32, self.armor_set as i32 - 3i32 + rank + area_map.drop_area_value().unwrap_or(0) as i32);
@ -80,7 +80,7 @@ impl GenericArmorTable {
}
pub fn slots<R: Rng>(&self, _area_map: &MapArea, rng: &mut R) -> usize {
let slot_weights = WeightedIndex::new(&[self.slot_rates.slot0, self.slot_rates.slot1, self.slot_rates.slot2,
let slot_weights = WeightedIndex::new([self.slot_rates.slot0, self.slot_rates.slot1, self.slot_rates.slot2,
self.slot_rates.slot3, self.slot_rates.slot4]).unwrap();
slot_weights.sample(rng)
}

2
src/ship/drops/generic_shield.rs

@ -36,7 +36,7 @@ impl GenericShieldTable {
}
fn shield_type<R: Rng>(&self, area_map: &MapArea, rng: &mut R) -> ShieldType {
let rank_weights = WeightedIndex::new(&[self.rank_rates.rank0, self.rank_rates.rank1, self.rank_rates.rank2,
let rank_weights = WeightedIndex::new([self.rank_rates.rank0, self.rank_rates.rank1, self.rank_rates.rank2,
self.rank_rates.rank3, self.rank_rates.rank4]).unwrap();
let rank = rank_weights.sample(rng) as i32;
let shield_level = std::cmp::max(0i32, self.shield_set as i32 - 3i32 + rank + area_map.drop_area_value().unwrap_or(0) as i32);

6
src/ship/drops/generic_weapon.rs

@ -240,7 +240,7 @@ impl AttributeTable {
fn generate_attribute<R: Rng>(&self, pattern: &PercentPatternType, rates: &AttributeRate, rng: &mut R) -> Option<WeaponAttribute> {
let attribute_weights = WeightedIndex::new(&[rates.none, rates.native, rates.abeast, rates.machine, rates.dark, rates.hit]).unwrap();
let attribute_weights = WeightedIndex::new([rates.none, rates.native, rates.abeast, rates.machine, rates.dark, rates.hit]).unwrap();
let attr = match attribute_weights.sample(rng) {
0 => return None,
1 => Attribute::Native,
@ -253,7 +253,7 @@ impl AttributeTable {
let percents = self.percent_rates.get_by_pattern(pattern);
let value_weights = WeightedIndex::new(&percents.as_array()).unwrap();
let value_weights = WeightedIndex::new(percents.as_array()).unwrap();
let value = value_weights.sample(rng);
let percent = ((value + 1) * 5) as i8;
@ -477,7 +477,7 @@ impl GenericWeaponTable {
let pattern = std::cmp::min(area % ratio.inc, 3);
let weights = self.grind_rates.grind_rate[pattern as usize];
let grind_choice = WeightedIndex::new(&weights).unwrap();
let grind_choice = WeightedIndex::new(weights).unwrap();
grind_choice.sample(rng)
}

2
src/ship/items/apply_item.rs

@ -226,7 +226,7 @@ pub async fn liberta_kit<EG: EntityGateway>(entity_gateway: &mut EG, used_cell:
fn jack_o_lantern() -> Result<Vec<ApplyItemAction>, anyhow::Error>
{
let mag_rate = WeightedIndex::new(&[13, 13, 13, 13, 12, 12, 12, 12]).unwrap();
let mag_rate = WeightedIndex::new([13, 13, 13, 13, 12, 12, 12, 12]).unwrap();
let mag_type = match mag_rate.sample(&mut rand_chacha::ChaChaRng::from_entropy()) {
0 => ToolType::CellOfMag502,
1 => ToolType::CellOfMag213,

2
src/ship/items/bank.rs

@ -323,6 +323,7 @@ impl std::cmp::PartialEq for BankItemDetail {
impl std::cmp::Eq for BankItemDetail {}
#[allow(clippy::non_canonical_partial_ord_impl)]
impl std::cmp::PartialOrd for BankItemDetail {
fn partial_cmp(&self, other: &BankItemDetail) -> Option<std::cmp::Ordering> {
let mut self_bytes = [0u8; 4];
@ -360,6 +361,7 @@ impl std::cmp::PartialEq for BankItem {
impl std::cmp::Eq for BankItem {}
#[allow(clippy::non_canonical_partial_ord_impl)]
impl std::cmp::PartialOrd for BankItem {
fn partial_cmp(&self, other: &BankItem) -> Option<std::cmp::Ordering> {
self.item.partial_cmp(&other.item)

4
src/ship/items/floor.rs

@ -96,13 +96,13 @@ pub struct FloorState {
impl FloorState {
pub fn take_item(&mut self, item_id: &ClientItemId) -> Option<FloorItem> {
let item = self.local.0
.drain_filter(|item| {
.extract_if(|item| {
item.item_id == *item_id
})
.next();
item.or_else(|| {
self.shared.0
.drain_filter(|item| {
.extract_if(|item| {
item.item_id == *item_id
})
.next()

1
src/ship/packet/builder/room.rs

@ -9,6 +9,7 @@ use std::convert::TryInto;
use futures::stream::StreamExt;
#[allow(clippy::manual_try_fold)]
pub async fn join_room(id: ClientId,
clients: &Clients,
client_location: &ClientLocation,

4
src/ship/shops/armor.rs

@ -342,8 +342,8 @@ impl<R: Rng + SeedableRng> ArmorShop<R> {
pub fn generate_armor_list(&mut self, character_level: usize) -> Vec<ArmorShopItem> {
self.generate_frame_list(character_level).into_iter()
.chain(self.generate_barrier_list(character_level).into_iter())
.chain(self.generate_unit_list(character_level).into_iter())
.chain(self.generate_barrier_list(character_level))
.chain(self.generate_unit_list(character_level))
.collect()
}
}

13
src/ship/shops/tool.rs

@ -36,16 +36,7 @@ impl Ord for ToolShopItem {
impl PartialOrd for ToolShopItem {
fn partial_cmp(&self, other: &ToolShopItem) -> Option<std::cmp::Ordering> {
let a = match self {
ToolShopItem::Tool(t) => Tool{tool : *t}.as_individual_bytes(),
ToolShopItem::Tech(t) => t.as_bytes(),
};
let b = match other {
ToolShopItem::Tool(t) => Tool{tool : *t}.as_individual_bytes(),
ToolShopItem::Tech(t) => t.as_bytes(),
};
a.partial_cmp(&b)
Some(self.cmp(other))
}
}
@ -285,7 +276,7 @@ impl<R: Rng + SeedableRng> ToolShop<R> {
pub fn generate_tool_list(&mut self, character_level: usize) -> Vec<ToolShopItem> {
let mut tools = Vec::new().into_iter()
.chain(self.tools.0.clone().into_iter().map(ToolShopItem::Tool))
.chain(self.generate_techs(character_level).into_iter())
.chain(self.generate_techs(character_level))
.collect::<Vec<_>>();
tools.sort();
tools

4
src/ship/shops/weapon.rs

@ -412,7 +412,7 @@ impl<R: Rng + SeedableRng> WeaponShop<R> {
.last()
.unwrap();
let attr_choice = WeightedIndex::new(&[tier.none, tier.native, tier.abeast, tier.machine, tier.dark, tier.hit]).unwrap();
let attr_choice = WeightedIndex::new([tier.none, tier.native, tier.abeast, tier.machine, tier.dark, tier.hit]).unwrap();
let attr = match attr_choice.sample(&mut self.rng) {
0 => return None,
1 => Attribute::Native,
@ -439,7 +439,7 @@ impl<R: Rng + SeedableRng> WeaponShop<R> {
.last()
.unwrap();
let attr_choice = WeightedIndex::new(&[tier.none, tier.native, tier.abeast, tier.machine, tier.dark, tier.hit]).unwrap();
let attr_choice = WeightedIndex::new([tier.none, tier.native, tier.abeast, tier.machine, tier.dark, tier.hit]).unwrap();
let attr = match attr_choice.sample(&mut self.rng) {
0 => return None,
1 => Attribute::Native,

4
tests/common.rs

@ -4,7 +4,7 @@ use elseware::common::serverstate::{ClientId, ServerState};
use elseware::entity::gateway::EntityGateway;
use elseware::entity::account::{UserAccountEntity, NewUserAccountEntity, NewUserSettingsEntity};
use elseware::entity::character::{CharacterEntity, NewCharacterEntity};
use elseware::entity::item::{Meseta, BankName, BankIdentifier};
use elseware::entity::item::{Meseta, BankIdentifier};
use elseware::ship::ship::{ShipServerState, RecvShipPacket};
use elseware::ship::room::Difficulty;
@ -16,7 +16,7 @@ use libpso::{utf8_to_array, utf8_to_utf16_array};
//TODO: remove kb_conf_preset
pub async fn new_user_character<EG: EntityGateway + Clone>(entity_gateway: &mut EG, username: &str, password: &str, kb_conf_preset: usize) -> (UserAccountEntity, CharacterEntity) {
pub async fn new_user_character<EG: EntityGateway + Clone>(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(),

4
tests/test_character.rs

@ -2,7 +2,7 @@ use elseware::common::serverstate::{ClientId, ServerState};
use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
use elseware::ship::ship::{ShipServerState, RecvShipPacket};
use libpso::character::settings::{DEFAULT_KEYBOARD_CONFIG1, DEFAULT_KEYBOARD_CONFIG2, DEFAULT_KEYBOARD_CONFIG3, DEFAULT_KEYBOARD_CONFIG4};
use libpso::character::settings::{DEFAULT_KEYBOARD_CONFIG1, DEFAULT_KEYBOARD_CONFIG4};
use libpso::packet::ship::*;
#[path = "common.rs"]
@ -35,7 +35,7 @@ async fn test_save_options() {
async fn test_change_keyboard_mappings() {
let mut entity_gateway = InMemoryGateway::default();
let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 2).await;
let (user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 2).await;
let mut ship = Box::new(ShipServerState::builder()
.gateway(entity_gateway.clone())

1
tests/test_exp_gain.rs

@ -3,7 +3,6 @@ use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
use elseware::common::leveltable::CharacterLevelTable;
use elseware::ship::ship::{ShipServerState, SendShipPacket, RecvShipPacket};
use elseware::ship::monster::MonsterType;
use elseware::ship::location::RoomId;
use elseware::ship::map::variant::{MapVariant, MapVariantMode};
use elseware::ship::map::maps::Maps;
use elseware::ship::map::area::MapArea;

6
tests/test_item_drop.rs

@ -1,11 +1,7 @@
use elseware::common::serverstate::{ClientId, ServerState};
use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
use elseware::entity::character::SectionID;
use elseware::common::leveltable::CharacterLevelTable;
use elseware::entity::gateway::InMemoryGateway;
use elseware::ship::ship::{ShipServerState, SendShipPacket, RecvShipPacket};
use elseware::ship::room::{Episode, Difficulty};
use elseware::ship::monster::MonsterType;
use elseware::ship::location::RoomId;
use elseware::ship::drops::{DropTable, MonsterDropStats, MonsterDropType};
use elseware::ship::drops::rare_drop_table::{RareDropTable, RareDropRate, RareDropItem};
use elseware::ship::map::{Maps, MapVariant, MapArea, MapVariantMode, MapEnemy};

2
tests/test_item_id.rs

@ -2,8 +2,6 @@ use elseware::common::serverstate::{ClientId, ServerState};
use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
use elseware::entity::item;
use elseware::ship::ship::{ShipServerState, RecvShipPacket};
use elseware::entity::character::TechLevel;
//use elseware::ship::items::{ClientItemId, ActiveItemEntityId, HeldItemType, FloorItemType};
use libpso::packet::ship::*;
use libpso::packet::messages::*;

3
tests/test_rooms.rs

@ -1,11 +1,8 @@
use elseware::common::serverstate::{ClientId, ServerState};
use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
use elseware::entity::item;
use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket};
use elseware::ship::location::RoomId;
use libpso::packet::ship::*;
//use libpso::packet::messages::*;
#[path = "common.rs"]
mod common;

2
tests/test_shops.rs

@ -1,7 +1,7 @@
use elseware::common::serverstate::{ClientId, ServerState};
use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
use elseware::entity::item;
use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket, ShipError};
use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket};
use elseware::ship::room::Difficulty;
use elseware::ship::items::state::ItemStateError;

2
tests/test_trade.rs

@ -2,7 +2,7 @@ use std::convert::TryInto;
use elseware::common::serverstate::{ClientId, ServerState};
use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
use elseware::entity::item;
use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket, ShipError};
use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket};
use elseware::entity::item::{Meseta, ItemEntity};
use elseware::ship::packet::handler::trade::TradeError;

Loading…
Cancel
Save