Browse Source

fix more tests + fix warnings

pbs
jake 4 years ago
parent
commit
b3e0674ca5
  1. 109
      src/bin/main.rs
  2. 1
      src/bin/ship.rs
  3. 59
      src/common/mainloop/client.rs
  4. 3
      src/entity/account.rs
  5. 7
      src/entity/gateway/postgres/models.rs
  6. 8
      src/entity/gateway/postgres/postgres.rs
  7. 30
      src/login/character.rs
  8. 29
      src/login/login.rs
  9. 2
      src/ship/drops/rare_drop_table.rs
  10. 40
      src/ship/items/manager.rs
  11. 30
      src/ship/items/use_tool.rs
  12. 2
      src/ship/packet/handler/auth.rs
  13. 2
      src/ship/packet/handler/communication.rs
  14. 8
      src/ship/packet/handler/direct_message.rs
  15. 2
      src/ship/packet/handler/lobby.rs
  16. 6
      src/ship/packet/handler/message.rs
  17. 4
      src/ship/packet/handler/settings.rs
  18. 8
      src/ship/ship.rs
  19. 4
      src/ship/shops/armor.rs
  20. 31
      src/ship/shops/tool.rs
  21. 1
      tests/common.rs
  22. 2
      tests/test_bank.rs
  23. 2
      tests/test_exp_gain.rs
  24. 2
      tests/test_shops.rs

109
src/bin/main.rs

@ -1,11 +1,9 @@
use std::net::Ipv4Addr; use std::net::Ipv4Addr;
use std::time::SystemTime;
use log::{info}; use log::{info};
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::login::login::LoginServerState; use elseware::login::login::LoginServerState;
use elseware::login::character::CharacterServerState; use elseware::login::character::CharacterServerState;
use elseware::ship::ship::ShipServerState;
use elseware::ship::ship::ShipServerStateBuilder; use elseware::ship::ship::ShipServerStateBuilder;
use elseware::entity::account::{NewUserAccountEntity, NewUserSettingsEntity}; use elseware::entity::account::{NewUserAccountEntity, NewUserSettingsEntity};
use elseware::entity::gateway::{EntityGateway, InMemoryGateway, PostgresGateway}; use elseware::entity::gateway::{EntityGateway, InMemoryGateway, PostgresGateway};
@ -64,10 +62,10 @@ fn main() {
flags: 0, flags: 0,
}; };
let fake_user = entity_gateway.create_user(fake_user).await.unwrap(); let fake_user = entity_gateway.create_user(fake_user).await.unwrap();
entity_gateway.create_user_settings(NewUserSettingsEntity::new(fake_user.id)).await;
entity_gateway.create_user_settings(NewUserSettingsEntity::new(fake_user.id)).await.unwrap();
let mut character = NewCharacterEntity::new(fake_user.id); let mut character = NewCharacterEntity::new(fake_user.id);
character.name = format!("Test Char {}", i*2); character.name = format!("Test Char {}", i*2);
entity_gateway.create_character(character).await;
entity_gateway.create_character(character).await.unwrap();
let mut character = NewCharacterEntity::new(fake_user.id); let mut character = NewCharacterEntity::new(fake_user.id);
character.slot = 2; character.slot = 2;
character.name = "ItemRefactor".into(); character.name = "ItemRefactor".into();
@ -75,6 +73,41 @@ fn main() {
character.meseta = 999999; character.meseta = 999999;
let character = entity_gateway.create_character(character).await.unwrap(); let character = entity_gateway.create_character(character).await.unwrap();
for _ in 0..3 {
entity_gateway.create_item(
item::NewItemEntity {
item: item::ItemDetail::Weapon(
item::weapon::Weapon {
weapon: item::weapon::WeaponType::Vulcan,
grind: 0,
special: None,
attrs: [None, None, None],
tekked: true,
modifiers: Vec::new(),
}
),
location: item::ItemLocation::Bank {
character_id: character.id,
name: item::BankName("".to_string())
}
}).await.unwrap();
}
for _ in 0..8 {
entity_gateway.create_item(
NewItemEntity {
item: ItemDetail::Tool (
item::tool::Tool {
tool: item::tool::ToolType::Monomate,
}
),
location: item::ItemLocation::Bank {
character_id: character.id,
name: item::BankName("".to_string())
}
}).await.unwrap();
}
entity_gateway.create_item( entity_gateway.create_item(
NewItemEntity { NewItemEntity {
item: ItemDetail::Weapon( item: ItemDetail::Weapon(
@ -94,7 +127,7 @@ fn main() {
slot: 0, slot: 0,
equipped: false, equipped: false,
} }
}).await;
}).await.unwrap();
entity_gateway.create_item( entity_gateway.create_item(
NewItemEntity { NewItemEntity {
item: ItemDetail::Weapon( item: ItemDetail::Weapon(
@ -114,7 +147,7 @@ fn main() {
slot: 1, slot: 1,
equipped: false, equipped: false,
} }
}).await;
}).await.unwrap();
entity_gateway.create_item( entity_gateway.create_item(
NewItemEntity { NewItemEntity {
item: ItemDetail::Weapon( item: ItemDetail::Weapon(
@ -134,7 +167,7 @@ fn main() {
slot: 2, slot: 2,
equipped: true, equipped: true,
} }
}).await;
}).await.unwrap();
entity_gateway.create_item( entity_gateway.create_item(
NewItemEntity { NewItemEntity {
item: ItemDetail::Weapon( item: ItemDetail::Weapon(
@ -154,7 +187,7 @@ fn main() {
slot: 3, slot: 3,
equipped: true, equipped: true,
} }
}).await;
}).await.unwrap();
entity_gateway.create_item( entity_gateway.create_item(
NewItemEntity { NewItemEntity {
item: ItemDetail::Weapon( item: ItemDetail::Weapon(
@ -174,7 +207,59 @@ fn main() {
slot: 4, slot: 4,
equipped: true, equipped: true,
} }
}).await;
}).await.unwrap();
let mag = entity_gateway.create_item(
item::NewItemEntity {
item: item::ItemDetail::Mag(item::mag::Mag::baby_mag(0)),
location: item::ItemLocation::Inventory {
character_id: character.id,
slot: 5,
equipped: true,
}
}).await.unwrap();
for _ in 0..10 {
let fed_tool = entity_gateway.create_item(
NewItemEntity {
item: ItemDetail::Tool (
item::tool::Tool {
tool: item::tool::ToolType::Monomate,
}
),
location: item::ItemLocation::FedToMag {
mag: mag.id,
}
}).await.unwrap();
entity_gateway.feed_mag(&mag.id, &fed_tool.id).await.unwrap();
}
//entity_gateway.bank(&mag.id).await;
entity_gateway.change_mag_owner(&mag.id, &character).await.unwrap();
entity_gateway.create_item(
item::NewItemEntity {
item: ItemDetail::Tool (
item::tool::Tool {
tool: item::tool::ToolType::CellOfMag502,
}
),
location: item::ItemLocation::Inventory {
character_id: character.id,
slot: 6,
equipped: true,
}
}).await.unwrap();
let cell = entity_gateway.create_item(
item::NewItemEntity {
item: ItemDetail::Tool (
item::tool::Tool {
tool: item::tool::ToolType::CellOfMag502,
}
),
location: item::ItemLocation::Consumed,
}).await.unwrap();
entity_gateway.use_mag_cell(&mag.id, &cell.id).await.unwrap();
entity_gateway.create_item( entity_gateway.create_item(
NewItemEntity { NewItemEntity {
item: ItemDetail::Weapon( item: ItemDetail::Weapon(
@ -326,7 +411,7 @@ fn main() {
let thread_entity_gateway = entity_gateway.clone(); let thread_entity_gateway = entity_gateway.clone();
info!("[ship] starting server"); info!("[ship] starting server");
let ship_state = ShipServerStateBuilder::new() let ship_state = ShipServerStateBuilder::new()
.name("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)
.gateway(thread_entity_gateway) .gateway(thread_entity_gateway)
@ -335,7 +420,7 @@ fn main() {
let thread_entity_gateway = entity_gateway.clone(); let thread_entity_gateway = entity_gateway.clone();
let ship_state = ShipServerStateBuilder::new() let ship_state = ShipServerStateBuilder::new()
.name("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+2000) .port(elseware::ship::ship::SHIP_PORT+2000)
.gateway(thread_entity_gateway) .gateway(thread_entity_gateway)
@ -344,7 +429,7 @@ fn main() {
let thread_entity_gateway = entity_gateway.clone(); let thread_entity_gateway = entity_gateway.clone();
let ship_state = ShipServerStateBuilder::new() let ship_state = ShipServerStateBuilder::new()
.name("Thalarion".into())
.name("JP/Thalarion".into())
.ip(Ipv4Addr::new(127,0,0,1)) .ip(Ipv4Addr::new(127,0,0,1))
.port(elseware::ship::ship::SHIP_PORT+3000) .port(elseware::ship::ship::SHIP_PORT+3000)
.gateway(thread_entity_gateway) .gateway(thread_entity_gateway)

1
src/bin/ship.rs

@ -1,6 +1,5 @@
use log::{info}; use log::{info};
use elseware::entity::gateway::postgres::PostgresGateway; use elseware::entity::gateway::postgres::PostgresGateway;
use elseware::ship::ship::ShipServerState;
use elseware::ship::ship::ShipServerStateBuilder; use elseware::ship::ship::ShipServerStateBuilder;
use elseware::common::mainloop::ship_mainloop; use elseware::common::mainloop::ship_mainloop;

59
src/common/mainloop/client.rs

@ -139,65 +139,6 @@ enum ServerStateAction<S> {
Disconnect, Disconnect,
} }
async fn server_state_loop<STATE, S, R, E>(mut state: STATE,
server_state_receiver: async_std::sync::Receiver<ClientAction<ServerStateAction<S>, R>>) where
STATE: ServerState<SendPacket=S, RecvPacket=R, PacketError=E> + Send + 'static,
S: SendServerPacket + std::fmt::Debug + Send + 'static,
R: RecvServerPacket + std::fmt::Debug + Send + 'static,
E: std::fmt::Debug + Send,
{
async_std::task::spawn(async move {
let mut clients = HashMap::new();
loop {
let action = server_state_receiver.recv().await.unwrap();
match action {
ClientAction::NewClient(client_id, sender) => {
clients.insert(client_id, sender.clone());
for action in state.on_connect(client_id) {
match action {
OnConnect::Cipher((inc, outc)) => {
sender.send(ServerStateAction::Cipher(inc, outc)).await;
},
OnConnect::Packet(pkt) => {
sender.send(ServerStateAction::Packet(pkt)).await;
}
}
}
},
ClientAction::Packet(client_id, pkt) => {
let pkts = state.handle(client_id, &pkt).await;
match pkts {
Ok(pkts) => {
for (client_id, pkt) in pkts {
if let Some(client) = clients.get_mut(&client_id) {
client.send(ServerStateAction::Packet(pkt)).await;
}
}
},
Err(err) => {
warn!("[client {:?} state handler error] {:?}", client_id, err);
}
}
},
ClientAction::Disconnect(client_id) => {
let pkts = state.on_disconnect(client_id);
for (client_id, pkt) in pkts {
if let Some(client) = clients.get_mut(&client_id) {
client.send(ServerStateAction::Packet(pkt)).await;
}
}
if let Some(client) = clients.get_mut(&client_id) {
client.send(ServerStateAction::Disconnect).await;
}
}
}
}
});
}
async fn client_recv_loop<S, R>(client_id: ClientId, async fn client_recv_loop<S, R>(client_id: ClientId,
socket: Arc<async_std::net::TcpStream>, socket: Arc<async_std::net::TcpStream>,
cipher: Arc<Mutex<Box<dyn PSOCipher + Send>>>, cipher: Arc<Mutex<Box<dyn PSOCipher + Send>>>,

3
src/entity/account.rs

@ -1,6 +1,3 @@
#![allow(dead_code)]
use std::time::SystemTime;
use libpso::character::settings; use libpso::character::settings;
use libpso::character::guildcard; use libpso::character::guildcard;

7
src/entity/gateway/postgres/models.rs

@ -1,18 +1,13 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::convert::Into; use std::convert::Into;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use futures::TryStreamExt;
use libpso::character::{settings, guildcard};
use libpso::character::settings;
use libpso::util::vec_to_array; use libpso::util::vec_to_array;
use crate::entity::account::*; use crate::entity::account::*;
use crate::entity::character::*; use crate::entity::character::*;
use crate::entity::gateway::EntityGateway;
use crate::entity::item::*; use crate::entity::item::*;
use crate::ship::map::MapArea; use crate::ship::map::MapArea;
use sqlx::postgres::PgPoolOptions;
use sqlx::Row;
use sqlx::Execute;
#[derive(Debug, sqlx::FromRow)] #[derive(Debug, sqlx::FromRow)]
pub struct PgUserAccount { pub struct PgUserAccount {
id: i32, id: i32,

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

@ -1,12 +1,8 @@
use std::convert::{From, TryFrom, Into, TryInto};
use serde::{Serialize, Deserialize};
use std::convert::{From, TryFrom, Into};
use futures::future::join_all; use futures::future::join_all;
use futures::TryStreamExt; use futures::TryStreamExt;
//use futures::StreamExt;
use async_std::stream::StreamExt; use async_std::stream::StreamExt;
//use futures::StreamExt;
use libpso::character::{settings, guildcard};
use libpso::util::vec_to_array;
use libpso::character::guildcard;
use crate::entity::account::*; use crate::entity::account::*;
use crate::entity::character::*; use crate::entity::character::*;
use crate::entity::gateway::{EntityGateway, GatewayError}; use crate::entity::gateway::{EntityGateway, GatewayError};

30
src/login/character.rs

@ -24,7 +24,7 @@ use crate::entity::item::weapon::Weapon;
use crate::entity::item::armor::Armor; use crate::entity::item::armor::Armor;
use crate::entity::item::tech::Technique; use crate::entity::item::tech::Technique;
use crate::entity::item::tool::Tool; use crate::entity::item::tool::Tool;
use crate::entity::item::mag::{Mag, MagType};
use crate::entity::item::mag::Mag;
use crate::entity::character::{CharacterEntity, NewCharacterEntity, CharacterClass, TechLevel}; use crate::entity::character::{CharacterEntity, NewCharacterEntity, CharacterClass, TechLevel};
use crate::login::login::get_login_status; use crate::login::login::get_login_status;
@ -184,7 +184,6 @@ async fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAc
} }
character.meseta = 300; character.meseta = 300;
let character = entity_gateway.create_character(character).await.unwrap(); let character = entity_gateway.create_character(character).await.unwrap();
let new_weapon = match character.char_class { let new_weapon = match character.char_class {
@ -209,7 +208,7 @@ async fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAc
character_id: character.id, character_id: character.id,
slot: 0, slot: 0,
equipped: true, equipped: true,
}}).await;
}}).await.unwrap();
entity_gateway.create_item( entity_gateway.create_item(
NewItemEntity { NewItemEntity {
@ -225,7 +224,7 @@ async fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAc
character_id: character.id, character_id: character.id,
slot: 1, slot: 1,
equipped: true, equipped: true,
}}).await;
}}).await.unwrap();
let mut mag = Mag::baby_mag(character.appearance.skin); let mut mag = Mag::baby_mag(character.appearance.skin);
mag.change_owner(character.char_class, character.section_id); mag.change_owner(character.char_class, character.section_id);
@ -236,7 +235,7 @@ async fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAc
character_id: character.id, character_id: character.id,
slot: 2, slot: 2,
equipped: true, equipped: true,
}}).await;
}}).await.unwrap();
for _ in 0..4 { for _ in 0..4 {
entity_gateway.create_item( entity_gateway.create_item(
@ -249,7 +248,7 @@ async fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAc
character_id: character.id, character_id: character.id,
slot: 3, slot: 3,
equipped: false, equipped: false,
}}).await;
}}).await.unwrap();
entity_gateway.create_item( entity_gateway.create_item(
NewItemEntity { NewItemEntity {
item: ItemDetail::Tool ( item: ItemDetail::Tool (
@ -260,7 +259,7 @@ async fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAc
character_id: character.id, character_id: character.id,
slot: 4, slot: 4,
equipped: false, equipped: false,
}}).await;
}}).await.unwrap();
} }
} }
@ -406,7 +405,7 @@ impl<EG: EntityGateway> CharacterServerState<EG> {
let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
let mut user = client.user.as_mut().unwrap(); let mut user = client.user.as_mut().unwrap();
user.flags = setflag.flags; user.flags = setflag.flags;
self.entity_gateway.save_user(&user).await;
self.entity_gateway.save_user(&user).await.unwrap();
Ok(None.into_iter()) Ok(None.into_iter())
} }
@ -444,7 +443,7 @@ impl<EG: EntityGateway> CharacterServerState<EG> {
client.session.action = SessionAction::SelectCharacter; client.session.action = SessionAction::SelectCharacter;
client.session.character_slot = preview.slot as u8; client.session.character_slot = preview.slot as u8;
user.flags = 0; user.flags = 0;
self.entity_gateway.save_user(&user).await;
self.entity_gateway.save_user(&user).await.unwrap();
Ok(vec![SendCharacterPacket::LoginResponse(LoginResponse::by_char_select(user.guildcard, Ok(vec![SendCharacterPacket::LoginResponse(LoginResponse::by_char_select(user.guildcard,
user.team_id.unwrap_or(1), user.team_id.unwrap_or(1),
client.session)), client.session)),
@ -543,7 +542,7 @@ impl<EG: EntityGateway> InterserverActor for CharacterServerState<EG> {
type RecvMessage = ShipMessage; type RecvMessage = ShipMessage;
type Error = (); type Error = ();
async fn on_connect(&mut self, id: ServerId) -> Vec<(ServerId, Self::SendMessage)> {
async fn on_connect(&mut self, _id: ServerId) -> Vec<(ServerId, Self::SendMessage)> {
Vec::new() Vec::new()
} }
@ -652,8 +651,7 @@ mod test {
use super::*; use super::*;
use crate::entity::account::*; use crate::entity::account::*;
use libpso::character::{settings, character}; use libpso::character::{settings, character};
use std::time::SystemTime;
use crate::entity::gateway::{InMemoryGateway};
use crate::entity::gateway::{InMemoryGateway, GatewayError};
#[async_std::test] #[async_std::test]
async fn test_option_send() { async fn test_option_send() {
@ -663,8 +661,8 @@ mod test {
#[async_trait::async_trait] #[async_trait::async_trait]
impl EntityGateway for TestData { impl EntityGateway for TestData {
async fn get_user_settings_by_user(&self, user: &UserAccountEntity) -> Option<UserSettingsEntity> {
Some(UserSettingsEntity {
async fn get_user_settings_by_user(&self, user: &UserAccountEntity) -> Result<UserSettingsEntity, GatewayError> {
Ok(UserSettingsEntity {
id: UserSettingsId(0), id: UserSettingsId(0),
user_id: user.id, user_id: user.id,
settings: settings::UserSettings::default() settings: settings::UserSettings::default()
@ -684,6 +682,7 @@ mod test {
created_at: chrono::Utc::now(), created_at: chrono::Utc::now(),
team_id: None, team_id: None,
flags: 0, flags: 0,
activated: true,
}); });
server.clients.insert(ClientId(5), clientstate); server.clients.insert(ClientId(5), clientstate);
@ -727,6 +726,7 @@ mod test {
muted_until: None, muted_until: None,
created_at: chrono::Utc::now(), created_at: chrono::Utc::now(),
flags: 0, flags: 0,
activated: true,
}); });
let mut server = CharacterServerState::new(test_data.clone()); let mut server = CharacterServerState::new(test_data.clone());
@ -762,7 +762,7 @@ mod test {
} })).await.unwrap().collect::<Vec<_>>(); } })).await.unwrap().collect::<Vec<_>>();
assert!(send.len() == 2); assert!(send.len() == 2);
let chars = test_data.get_characters_by_user(&fake_user.user.unwrap()).await;
let chars = test_data.get_characters_by_user(&fake_user.user.unwrap()).await.unwrap();
assert!(chars[1].as_ref().unwrap().name == "\tEtest name"); assert!(chars[1].as_ref().unwrap().name == "\tEtest name");
assert!(chars[0].is_none()); assert!(chars[0].is_none());
} }

29
src/login/login.rs

@ -144,9 +144,9 @@ impl<EG: EntityGateway> ServerState for LoginServerState<EG> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::time::SystemTime;
use super::*; use super::*;
use crate::entity::account::{UserAccountId}; use crate::entity::account::{UserAccountId};
use crate::entity::gateway::GatewayError;
const LOGIN_PACKET: RecvLoginPacket = RecvLoginPacket::Login(Login { const LOGIN_PACKET: RecvLoginPacket = RecvLoginPacket::Login(Login {
tag: 65536, tag: 65536,
@ -180,9 +180,9 @@ mod test {
#[async_trait::async_trait] #[async_trait::async_trait]
impl EntityGateway for TestData { impl EntityGateway for TestData {
async fn get_user_by_name(&self, name: String) -> Option<UserAccountEntity> {
async fn get_user_by_name(&self, name: String) -> Result<UserAccountEntity, GatewayError> {
assert!(name == "testuser"); assert!(name == "testuser");
Some(UserAccountEntity {
Ok(UserAccountEntity {
id: UserAccountId(1), id: UserAccountId(1),
username: "testuser".to_owned(), username: "testuser".to_owned(),
password: bcrypt::hash("mypassword", 5).unwrap(), password: bcrypt::hash("mypassword", 5).unwrap(),
@ -192,11 +192,12 @@ mod test {
muted_until: None, muted_until: None,
created_at: chrono::Utc::now(), created_at: chrono::Utc::now(),
flags: 0, flags: 0,
activated: true,
}) })
} }
}; };
let mut server = LoginServerState::new(TestData {});
let mut server = LoginServerState::new(TestData {}, "127.0.0.1".parse().unwrap());
let send = server.handle(ClientId(1), &LOGIN_PACKET).await.unwrap().collect::<Vec<_>>(); let send = server.handle(ClientId(1), &LOGIN_PACKET).await.unwrap().collect::<Vec<_>>();
assert!(send == vec![ assert!(send == vec![
@ -230,12 +231,12 @@ mod test {
#[async_trait::async_trait] #[async_trait::async_trait]
impl EntityGateway for TestData { impl EntityGateway for TestData {
async fn get_user_by_name(&self, _name: String) -> Option<UserAccountEntity> {
None
async fn get_user_by_name(&self, _name: String) -> Result<UserAccountEntity, GatewayError> {
Err(GatewayError::Error)
} }
} }
let mut server = LoginServerState::new(TestData {});
let mut server = LoginServerState::new(TestData {}, "127.0.0.1".parse().unwrap());
let send = server.handle(ClientId(1), &LOGIN_PACKET).await.unwrap().collect::<Vec<_>>(); let send = server.handle(ClientId(1), &LOGIN_PACKET).await.unwrap().collect::<Vec<_>>();
assert!(send == vec![ assert!(send == vec![
@ -264,9 +265,9 @@ mod test {
#[async_trait::async_trait] #[async_trait::async_trait]
impl EntityGateway for TestData { impl EntityGateway for TestData {
async fn get_user_by_name(&self, name: String) -> Option<UserAccountEntity> {
async fn get_user_by_name(&self, name: String) -> Result<UserAccountEntity, GatewayError> {
assert!(name == "testuser"); assert!(name == "testuser");
Some(UserAccountEntity {
Ok(UserAccountEntity {
id: UserAccountId(1), id: UserAccountId(1),
username: "testuser".to_owned(), username: "testuser".to_owned(),
password: bcrypt::hash("notpassword", 5).unwrap(), password: bcrypt::hash("notpassword", 5).unwrap(),
@ -276,11 +277,12 @@ mod test {
muted_until: None, muted_until: None,
created_at: chrono::Utc::now(), created_at: chrono::Utc::now(),
flags: 0, flags: 0,
activated: true,
}) })
} }
} }
let mut server = LoginServerState::new(TestData {});
let mut server = LoginServerState::new(TestData {}, "127.0.0.1".parse().unwrap());
let send = server.handle(ClientId(1), &LOGIN_PACKET).await.unwrap().collect::<Vec<_>>(); let send = server.handle(ClientId(1), &LOGIN_PACKET).await.unwrap().collect::<Vec<_>>();
assert!(send == vec![ assert!(send == vec![
@ -309,9 +311,9 @@ mod test {
#[async_trait::async_trait] #[async_trait::async_trait]
impl EntityGateway for TestData { impl EntityGateway for TestData {
async fn get_user_by_name(&self, name: String) -> Option<UserAccountEntity> {
async fn get_user_by_name(&self, name: String) -> Result<UserAccountEntity, GatewayError> {
assert!(name == "testuser"); assert!(name == "testuser");
Some(UserAccountEntity {
Ok(UserAccountEntity {
id: UserAccountId(1), id: UserAccountId(1),
username: "testuser".to_owned(), username: "testuser".to_owned(),
password: bcrypt::hash("mypassword", 5).unwrap(), password: bcrypt::hash("mypassword", 5).unwrap(),
@ -321,11 +323,12 @@ mod test {
muted_until: None, muted_until: None,
created_at: chrono::Utc::now(), created_at: chrono::Utc::now(),
flags: 0, flags: 0,
activated: true,
}) })
} }
} }
let mut server = LoginServerState::new(TestData {});
let mut server = LoginServerState::new(TestData {}, "127.0.0.1".parse().unwrap());
let send = server.handle(ClientId(1), &LOGIN_PACKET).await.unwrap().collect::<Vec<_>>(); let send = server.handle(ClientId(1), &LOGIN_PACKET).await.unwrap().collect::<Vec<_>>();
assert!(send == vec![ assert!(send == vec![

2
src/ship/drops/rare_drop_table.rs

@ -136,7 +136,7 @@ impl RareDropTable {
tool: tool, tool: tool,
}) })
}, },
RareDropItem::Mag(mag) => {
RareDropItem::Mag(_mag) => {
ItemDropType::Mag(Mag::baby_mag(rng.gen_range(0, 18))) ItemDropType::Mag(Mag::baby_mag(rng.gen_range(0, 18)))
} }
} }

40
src/ship/items/manager.rs

@ -305,9 +305,9 @@ impl ItemManager {
slot: slot.0, slot: slot.0,
equipped: false, equipped: false,
} }
).await;
).await?;
if let Some(_) = new_inventory_item.mag() { if let Some(_) = new_inventory_item.mag() {
entity_gateway.change_mag_owner(&new_inventory_item.entity_id, character).await;
entity_gateway.change_mag_owner(&new_inventory_item.entity_id, character).await?;
} }
}, },
None => { None => {
@ -329,7 +329,7 @@ impl ItemManager {
slot: slot.0, slot: slot.0,
equipped: false, equipped: false,
} }
).await;
).await?;
} }
if stacked_floor_item.count() != new_inventory_item.count() { if stacked_floor_item.count() != new_inventory_item.count() {
@ -349,7 +349,7 @@ impl ItemManager {
return Err(ItemManagerError::CouldNotAddToInventory(item_id)); return Err(ItemManagerError::CouldNotAddToInventory(item_id));
} }
character.meseta = std::cmp::min(character.meseta + meseta_floor_item.meseta.0, 999999); character.meseta = std::cmp::min(character.meseta + meseta_floor_item.meseta.0, 999999);
entity_gateway.save_character(&character).await;
entity_gateway.save_character(&character).await?;
TriggerCreateItem::No TriggerCreateItem::No
}, },
None => { None => {
@ -470,7 +470,7 @@ impl ItemManager {
y: item_drop_location.2, y: item_drop_location.2,
z: item_drop_location.3, z: item_drop_location.3,
} }
).await;
).await?;
}, },
InventoryItem::Stacked(stacked_inventory_item) => { InventoryItem::Stacked(stacked_inventory_item) => {
let stacked_floor_item = shared_floor.drop_stacked_inventory_item(stacked_inventory_item, item_drop_location); let stacked_floor_item = shared_floor.drop_stacked_inventory_item(stacked_inventory_item, item_drop_location);
@ -483,7 +483,7 @@ impl ItemManager {
y: item_drop_location.2, y: item_drop_location.2,
z: item_drop_location.3, z: item_drop_location.3,
} }
).await;
).await?;
} }
}, },
} }
@ -504,7 +504,7 @@ impl ItemManager {
return Err(ItemManagerError::CouldNotDropMeseta) return Err(ItemManagerError::CouldNotDropMeseta)
} }
character.meseta -= amount; character.meseta -= amount;
entity_gateway.save_character(&character).await;
entity_gateway.save_character(&character).await?;
let item_id = self.room_item_id_counter.get_mut(room_id).ok_or(ItemManagerError::NoCharacter(character.id))?(); let item_id = self.room_item_id_counter.get_mut(room_id).ok_or(ItemManagerError::NoCharacter(character.id))?();
let floor_item = FloorItem::Meseta(MesetaFloorItem { let floor_item = FloorItem::Meseta(MesetaFloorItem {
@ -547,7 +547,7 @@ impl ItemManager {
y: 0.0, y: 0.0,
z: drop_location.z, z: drop_location.z,
} }
).await;
).await?;
} }
Ok(stacked_floor_item) Ok(stacked_floor_item)
@ -565,10 +565,10 @@ impl ItemManager {
for entity_id in consumed_item.entity_ids() { for entity_id in consumed_item.entity_ids() {
entity_gateway.change_item_location(&entity_id, entity_gateway.change_item_location(&entity_id,
ItemLocation::Consumed).await;
ItemLocation::Consumed).await?;
} }
update_inventory_slots(entity_gateway, character, &inventory).await;
update_inventory_slots(entity_gateway, character, &inventory).await?;
Ok(consumed_item) Ok(consumed_item)
} }
@ -592,7 +592,7 @@ impl ItemManager {
ItemLocation::Bank { ItemLocation::Bank {
character_id: character.id, character_id: character.id,
name: BankName("".to_string()) name: BankName("".to_string())
}).await;
}).await?;
}, },
BankItem::Stacked(stacked_bank_item) => { BankItem::Stacked(stacked_bank_item) => {
for entity_id in &stacked_bank_item.entity_ids { for entity_id in &stacked_bank_item.entity_ids {
@ -600,12 +600,12 @@ impl ItemManager {
ItemLocation::Bank { ItemLocation::Bank {
character_id: character.id, character_id: character.id,
name: BankName("".to_string()) name: BankName("".to_string())
}).await;
}).await?;
} }
} }
} }
update_inventory_slots(entity_gateway, character, &inventory).await;
update_inventory_slots(entity_gateway, character, &inventory).await?;
Ok(()) Ok(())
} }
@ -631,7 +631,7 @@ impl ItemManager {
character_id: character.id, character_id: character.id,
slot: slot, slot: slot,
equipped: false, equipped: false,
}).await;
}).await?;
}, },
(InventoryItem::Stacked(stacked_inventory_item), slot) => { (InventoryItem::Stacked(stacked_inventory_item), slot) => {
for entity_id in &stacked_inventory_item.entity_ids { for entity_id in &stacked_inventory_item.entity_ids {
@ -640,7 +640,7 @@ impl ItemManager {
character_id: character.id, character_id: character.id,
slot: slot, slot: slot,
equipped: false, equipped: false,
}).await;
}).await?;
} }
} }
} }
@ -676,13 +676,13 @@ impl ItemManager {
mag.feed(consumed_tool_type); mag.feed(consumed_tool_type);
for entity_id in consumed_tool.entity_ids() { for entity_id in consumed_tool.entity_ids() {
entity_gateway.feed_mag(&individual_item.entity_id, &entity_id).await;
entity_gateway.feed_mag(&individual_item.entity_id, &entity_id).await?;
entity_gateway.change_item_location(&entity_id, ItemLocation::FedToMag { entity_gateway.change_item_location(&entity_id, ItemLocation::FedToMag {
mag: individual_item.entity_id, mag: individual_item.entity_id,
}).await;
}).await?;
} }
update_inventory_slots(entity_gateway, character, &inventory).await;
update_inventory_slots(entity_gateway, character, &inventory).await?;
Ok(()) Ok(())
} }
@ -796,7 +796,7 @@ impl ItemManager {
} }
_ => {} _ => {}
} }
update_inventory_slots(entity_gateway, character, &inventory).await;
update_inventory_slots(entity_gateway, character, &inventory).await?;
Ok(()) Ok(())
} }
@ -838,7 +838,7 @@ impl ItemManager {
character_id: character.id, character_id: character.id,
slot: slot.0, slot: slot.0,
equipped: false, equipped: false,
}).await;//.ok_or(ItemManagerError::EntityGatewayError)?;
}).await?;
} }
picked_up_item.item_id picked_up_item.item_id
}; };

30
src/ship/items/use_tool.rs

@ -1,14 +1,8 @@
use thiserror::Error; use thiserror::Error;
use crate::entity::gateway::EntityGateway; use crate::entity::gateway::EntityGateway;
use crate::entity::character::CharacterEntity; use crate::entity::character::CharacterEntity;
use crate::entity::item::{ItemEntityId, ItemDetail};
use crate::entity::item::tool::ToolType;
use crate::entity::item::mag::MagCell; use crate::entity::item::mag::MagCell;
use crate::ship::items::{ItemManager, ClientItemId, CharacterInventory, ConsumedItem};
use crate::ship::items::{CharacterInventory, ConsumedItem};
#[derive(Error, Debug)] #[derive(Error, Debug)]
#[error("")] #[error("")]
@ -18,45 +12,39 @@ pub enum UseItemError {
InvalidItem, InvalidItem,
} }
//pub fn use_tool()
pub async fn power_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) { pub async fn power_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) {
character.materials.power += 1; character.materials.power += 1;
entity_gateway.save_character(character).await;
entity_gateway.save_character(character).await.unwrap();
} }
pub async fn mind_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) { pub async fn mind_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) {
character.materials.mind += 1; character.materials.mind += 1;
entity_gateway.save_character(character).await;
entity_gateway.save_character(character).await.unwrap();
} }
pub async fn evade_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) { pub async fn evade_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) {
character.materials.evade += 1; character.materials.evade += 1;
entity_gateway.save_character(character).await;
entity_gateway.save_character(character).await.unwrap();
} }
pub async fn def_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) { pub async fn def_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) {
character.materials.def += 1; character.materials.def += 1;
entity_gateway.save_character(character).await;
entity_gateway.save_character(character).await.unwrap();
} }
pub async fn luck_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) { pub async fn luck_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) {
character.materials.luck += 1; character.materials.luck += 1;
entity_gateway.save_character(character).await;
entity_gateway.save_character(character).await.unwrap();
} }
pub async fn hp_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) { pub async fn hp_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) {
character.materials.hp += 1; character.materials.hp += 1;
entity_gateway.save_character(character).await;
entity_gateway.save_character(character).await.unwrap();
} }
pub async fn tp_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) { pub async fn tp_material<EG: EntityGateway>(entity_gateway: &mut EG, character: &mut CharacterEntity) {
character.materials.tp += 1; character.materials.tp += 1;
entity_gateway.save_character(character).await;
entity_gateway.save_character(character).await.unwrap();
} }
async fn mag_cell<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory, mag_cell_type: MagCell) -> Result<(), UseItemError> { async fn mag_cell<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory, mag_cell_type: MagCell) -> Result<(), UseItemError> {
@ -71,7 +59,7 @@ async fn mag_cell<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &Consum
actual_mag.apply_mag_cell(mag_cell_type); actual_mag.apply_mag_cell(mag_cell_type);
for mag_entity_id in mag_item.entity_ids() { for mag_entity_id in mag_item.entity_ids() {
for cell_entity_id in used_cell.entity_ids() { for cell_entity_id in used_cell.entity_ids() {
entity_gateway.use_mag_cell(&mag_entity_id, &cell_entity_id).await;
entity_gateway.use_mag_cell(&mag_entity_id, &cell_entity_id).await.unwrap();
} }
} }

2
src/ship/packet/handler/auth.rs

@ -27,7 +27,7 @@ pub async fn validate_login<EG: EntityGateway>(id: ClientId,
.clone(); .clone();
let settings = entity_gateway.get_user_settings_by_user(&user).await?; let settings = entity_gateway.get_user_settings_by_user(&user).await?;
item_manager.load_character(entity_gateway, &character).await;
item_manager.load_character(entity_gateway, &character).await?;
clients.insert(id, ClientState::new(user, settings, character, pkt.session)); clients.insert(id, ClientState::new(user, settings, character, pkt.session));
vec![SendShipPacket::LoginResponse(response), SendShipPacket::ShipBlockList(ShipBlockList::new(&&ship_name, 3))] vec![SendShipPacket::LoginResponse(response), SendShipPacket::ShipBlockList(ShipBlockList::new(&&ship_name, 3))]
} }

2
src/ship/packet/handler/communication.rs

@ -42,6 +42,6 @@ pub async fn write_infoboard<EG: EntityGateway>(id: ClientId,
-> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> { -> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> {
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap();
client.character.info_board.update_infoboard(new_infoboard); client.character.info_board.update_infoboard(new_infoboard);
entity_gateway.save_character(&client.character).await;
entity_gateway.save_character(&client.character).await.unwrap();
Box::new(None.into_iter()) Box::new(None.into_iter())
} }

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

@ -97,7 +97,7 @@ where
item: item_drop, item: item_drop,
}; };
let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?; let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?;
let floor_item = item_manager.enemy_drop_item_on_local_floor(entity_gateway, &client.character, item_drop).await.unwrap(); // TODO: unwrap
let floor_item = item_manager.enemy_drop_item_on_local_floor(entity_gateway, &client.character, item_drop).await?;
let item_drop_msg = builder::message::item_drop(request_item.client, request_item.target, &floor_item)?; let item_drop_msg = builder::message::item_drop(request_item.client, request_item.target, &floor_item)?;
item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))); item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg)))));
@ -236,7 +236,7 @@ where
if client.character.meseta > bank_interaction.meseta_amount && (bank_interaction.meseta_amount + client.character.bank_meseta) <= 999999 { if client.character.meseta > bank_interaction.meseta_amount && (bank_interaction.meseta_amount + client.character.bank_meseta) <= 999999 {
client.character.meseta -= bank_interaction.meseta_amount; client.character.meseta -= bank_interaction.meseta_amount;
client.character.bank_meseta += bank_interaction.meseta_amount; client.character.bank_meseta += bank_interaction.meseta_amount;
entity_gateway.save_character(&client.character).await;
entity_gateway.save_character(&client.character).await?;
} }
Vec::new() Vec::new()
} }
@ -251,7 +251,7 @@ where
if client.character.meseta + bank_interaction.meseta_amount <= 999999 { if client.character.meseta + bank_interaction.meseta_amount <= 999999 {
client.character.meseta += bank_interaction.meseta_amount; client.character.meseta += bank_interaction.meseta_amount;
client.character.bank_meseta -= bank_interaction.meseta_amount; client.character.bank_meseta -= bank_interaction.meseta_amount;
entity_gateway.save_character(&client.character).await;
entity_gateway.save_character(&client.character).await?;
} }
Vec::new() Vec::new()
} }
@ -361,7 +361,7 @@ where
} }
client.character.meseta -= item.price() as u32; client.character.meseta -= item.price() as u32;
entity_gateway.save_character(&client.character).await;
entity_gateway.save_character(&client.character).await?;
let inventory_item = item_manager.player_buys_item(entity_gateway, &client.character, item, ClientItemId(buy_item.item_id), buy_item.amount as usize).await?; let inventory_item = item_manager.player_buys_item(entity_gateway, &client.character, item, ClientItemId(buy_item.item_id), buy_item.amount as usize).await?;
let create = builder::message::create_withdrawn_inventory_item(area_client, inventory_item)?; let create = builder::message::create_withdrawn_inventory_item(area_client, inventory_item)?;

2
src/ship/packet/handler/lobby.rs

@ -101,7 +101,7 @@ pub async fn change_lobby<EG: EntityGateway>(id: ClientId,
} }
} }
} }
item_manager.load_character(entity_gateway, &client.character).await;
item_manager.load_character(entity_gateway, &client.character).await?;
let join_lobby = packet::builder::lobby::join_lobby(id, lobby, client_location, clients, item_manager, level_table)?; let join_lobby = packet::builder::lobby::join_lobby(id, lobby, client_location, clients, item_manager, level_table)?;
let addto = packet::builder::lobby::add_to_lobby(id, lobby, client_location, clients, item_manager, level_table)?; let addto = packet::builder::lobby::add_to_lobby(id, lobby, client_location, clients, item_manager, level_table)?;
let neighbors = client_location.get_client_neighbors(id).unwrap(); let neighbors = client_location.get_client_neighbors(id).unwrap();

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

@ -58,7 +58,7 @@ pub async fn request_exp<EG: EntityGateway>(id: ClientId,
} }
client.character.exp += exp_gain; client.character.exp += exp_gain;
entity_gateway.save_character(&client.character).await;
entity_gateway.save_character(&client.character).await?;
Ok(exp_pkts) Ok(exp_pkts)
} }
@ -243,7 +243,7 @@ where
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?; let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
if client.character.meseta >= charge.meseta { if client.character.meseta >= charge.meseta {
client.character.meseta -= charge.meseta; client.character.meseta -= charge.meseta;
entity_gateway.save_character(&client.character).await;
entity_gateway.save_character(&client.character).await?;
Ok(Box::new(None.into_iter())) Ok(Box::new(None.into_iter()))
} else { } else {
Err(ShipError::NotEnoughMeseta(id, client.character.meseta)) Err(ShipError::NotEnoughMeseta(id, client.character.meseta))
@ -278,7 +278,7 @@ where
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?; let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
if client.character.meseta >= 10 { if client.character.meseta >= 10 {
client.character.meseta -= 10; client.character.meseta -= 10;
entity_gateway.save_character(&client.character).await;
entity_gateway.save_character(&client.character).await?;
Ok(Box::new(None.into_iter())) Ok(Box::new(None.into_iter()))
} else { } else {
Err(ShipError::NotEnoughMeseta(id, client.character.meseta)) Err(ShipError::NotEnoughMeseta(id, client.character.meseta))

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

@ -10,7 +10,7 @@ pub async fn update_config<EG: EntityGateway>(id: ClientId,
-> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> { -> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> {
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap();
client.character.config.update(update_config); client.character.config.update(update_config);
entity_gateway.save_character(&client.character).await;
entity_gateway.save_character(&client.character).await.unwrap();
Box::new(None.into_iter()) Box::new(None.into_iter())
} }
@ -22,6 +22,6 @@ pub async fn save_options<EG: EntityGateway>(id: ClientId,
// // TODO: don't unwrap? // // TODO: don't unwrap?
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap();
client.character.option_flags = save_options.options; client.character.option_flags = save_options.options;
entity_gateway.save_character(&client.character).await;
entity_gateway.save_character(&client.character).await.unwrap();
Box::new(None.into_iter()) Box::new(None.into_iter())
} }

8
src/ship/ship.rs

@ -29,7 +29,7 @@ use crate::ship::room;
use crate::ship::quests; use crate::ship::quests;
use crate::ship::map::{MapsError, MapAreaError, MapArea}; use crate::ship::map::{MapsError, MapAreaError, MapArea};
use crate::ship::packet::handler; use crate::ship::packet::handler;
use crate::ship::shops::{ShopType, WeaponShop, ToolShop, ArmorShop, WeaponShopItem, ToolShopItem, ArmorShopItem};
use crate::ship::shops::{WeaponShop, ToolShop, ArmorShop, WeaponShopItem, ToolShopItem, ArmorShopItem};
pub const SHIP_PORT: u16 = 23423; pub const SHIP_PORT: u16 = 23423;
pub const QUEST_CATEGORY_MENU_ID: u32 = 0xA2; pub const QUEST_CATEGORY_MENU_ID: u32 = 0xA2;
@ -568,7 +568,7 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> {
RecvShipPacket::DoneLoadingQuest(_) => { RecvShipPacket::DoneLoadingQuest(_) => {
handler::quest::done_loading_quest(id, &mut self.clients, &self.client_location)? handler::quest::done_loading_quest(id, &mut self.clients, &self.client_location)?
}, },
RecvShipPacket::FullCharacterData(full_character_data) => {
RecvShipPacket::FullCharacterData(_full_character_data) => {
Box::new(None.into_iter()) Box::new(None.into_iter())
}, },
RecvShipPacket::SaveOptions(save_options) => { RecvShipPacket::SaveOptions(save_options) => {
@ -622,11 +622,11 @@ impl<EG: EntityGateway> InterserverActor for ShipServerState<EG> {
})) ] })) ]
} }
async fn action(&mut self, id: ServerId, msg: Self::RecvMessage) -> Result<Vec<(ServerId, Self::SendMessage)>, Self::Error> {
async fn action(&mut self, _id: ServerId, _msg: Self::RecvMessage) -> Result<Vec<(ServerId, Self::SendMessage)>, Self::Error> {
Ok(Vec::new()) Ok(Vec::new())
} }
async fn on_disconnect(&mut self, id: ServerId) -> Vec<(ServerId, Self::SendMessage)> {
async fn on_disconnect(&mut self, _id: ServerId) -> Vec<(ServerId, Self::SendMessage)> {
Vec::new() Vec::new()
} }
} }

4
src/ship/shops/armor.rs

@ -1,4 +1,3 @@
use std::collections::HashMap;
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use std::path::PathBuf; use std::path::PathBuf;
@ -6,9 +5,6 @@ use std::convert::TryInto;
use serde::Deserialize; use serde::Deserialize;
use rand::{Rng, SeedableRng}; use rand::{Rng, SeedableRng};
use rand::distributions::{WeightedIndex, Distribution}; use rand::distributions::{WeightedIndex, Distribution};
use rand::seq::{SliceRandom, IteratorRandom};
use crate::entity::character::SectionID;
use crate::ship::room::Difficulty;
use crate::entity::item::ItemDetail; use crate::entity::item::ItemDetail;
use crate::entity::item::armor::{Armor, ArmorType}; use crate::entity::item::armor::{Armor, ArmorType};
use crate::entity::item::shield::{Shield, ShieldType}; use crate::entity::item::shield::{Shield, ShieldType};

31
src/ship/shops/tool.rs

@ -6,9 +6,6 @@ use std::convert::TryInto;
use serde::Deserialize; use serde::Deserialize;
use rand::{Rng, SeedableRng}; use rand::{Rng, SeedableRng};
use rand::distributions::{WeightedIndex, Distribution}; use rand::distributions::{WeightedIndex, Distribution};
use rand::seq::{SliceRandom, IteratorRandom};
use crate::entity::character::SectionID;
use crate::ship::room::Difficulty;
use crate::entity::item::ItemDetail; use crate::entity::item::ItemDetail;
use crate::entity::item::tool::{Tool, ToolType}; use crate::entity::item::tool::{Tool, ToolType};
use crate::entity::item::tech::{Technique, TechniqueDisk}; use crate::entity::item::tech::{Technique, TechniqueDisk};
@ -206,34 +203,6 @@ impl<R: Rng + SeedableRng> ToolShop<R> {
} }
} }
fn generate_tech(&mut self, character_level: usize) -> ToolShopItem {
let tier = self.techs.0.iter()
.filter(|t| t.level <= character_level)
.last()
.unwrap();
let mut tier = tier.techs.iter()
.map(|(tech, entry)| {
(tech, entry)
});
let tech_choice = WeightedIndex::new(tier.clone().map(|(_, e)| e.probability)).unwrap();
let tech_detail = tier.nth(tech_choice.sample(&mut self.rng)).unwrap();
let tech_level = match tech_detail.1.level {
TechLevel::Set{set_level} => set_level,
TechLevel::Level{level_divisor} => std::cmp::max(std::cmp::min(character_level, 99)/level_divisor, 1),
TechLevel::Range{min, max} => self.rng.gen_range(min, max+1),
};
ToolShopItem::Tech(
TechniqueDisk {
tech: *tech_detail.0,
level: tech_level as u32,
}
)
}
fn generate_tech_types(&mut self, character_level: usize) -> Vec<Technique> { fn generate_tech_types(&mut self, character_level: usize) -> Vec<Technique> {
let tier = self.techs.0.iter() let tier = self.techs.0.iter()
.filter(|t| t.level <= character_level) .filter(|t| t.level <= character_level)

1
tests/common.rs

@ -1,5 +1,4 @@
#![allow(dead_code)] #![allow(dead_code)]
use std::time::SystemTime;
use elseware::common::serverstate::{ClientId, ServerState}; use elseware::common::serverstate::{ClientId, ServerState};
use elseware::entity::gateway::EntityGateway; use elseware::entity::gateway::EntityGateway;

2
tests/test_bank.rs

@ -1008,7 +1008,7 @@ async fn test_deposit_meseta_when_bank_is_maxed() {
let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
char1.meseta = 300; char1.meseta = 300;
char1.bank_meseta = 999999; char1.bank_meseta = 999999;
entity_gateway.save_character(&char1).await;
entity_gateway.save_character(&char1).await.unwrap();
let mut ship = ShipServerState::builder() let mut ship = ShipServerState::builder()
.gateway(entity_gateway.clone()) .gateway(entity_gateway.clone())

2
tests/test_exp_gain.rs

@ -54,7 +54,7 @@ async fn test_character_levels_up() {
let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
char1.exp = 49; char1.exp = 49;
entity_gateway.save_character(&char1).await;
entity_gateway.save_character(&char1).await.unwrap();
let mut ship = ShipServerState::builder() let mut ship = ShipServerState::builder()
.gateway(entity_gateway.clone()) .gateway(entity_gateway.clone())

2
tests/test_shops.rs

@ -321,7 +321,7 @@ async fn test_other_clients_see_stacked_purchase() {
slot: 0, slot: 0,
equipped: false, equipped: false,
} }
}).await;
}).await.unwrap();
let mut ship = ShipServerState::builder() let mut ship = ShipServerState::builder()
.gateway(entity_gateway.clone()) .gateway(entity_gateway.clone())

Loading…
Cancel
Save