diff --git a/Cargo.lock b/Cargo.lock index f343af7..e11484a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1040,6 +1040,7 @@ checksum = "739e9d7726dc32173fed2d69d17eef3c54682169e4e20ff1d0a45dcd37063cef" [[package]] name = "libpso" version = "0.1.0" +source = "git+http://git.sharnoth.com/jake/libpso#5051514fb1d3b39a7eb6ff97b624a9ceebd93e40" dependencies = [ "chrono", "psopacket", @@ -1398,6 +1399,7 @@ dependencies = [ [[package]] name = "psopacket" version = "1.0.0" +source = "git+http://git.sharnoth.com/jake/libpso#5051514fb1d3b39a7eb6ff97b624a9ceebd93e40" dependencies = [ "proc-macro2", "quote", diff --git a/src/entity/gateway/entitygateway.rs b/src/entity/gateway/entitygateway.rs index 75518e1..7ab6903 100644 --- a/src/entity/gateway/entitygateway.rs +++ b/src/entity/gateway/entitygateway.rs @@ -10,9 +10,10 @@ use crate::entity::item::*; // TODO: better granularity? //#[derive(Error, Debug)] #[derive(Error, Debug)] -#[error("")] pub enum GatewayError { + #[error("unknown error")] Error, + #[error("postgres error {0}")] PgError(#[from] sqlx::Error) } diff --git a/src/entity/gateway/postgres/migrations/V0004__meseta.sql b/src/entity/gateway/postgres/migrations/V0004__meseta.sql index 97f6b2e..efca1db 100644 --- a/src/entity/gateway/postgres/migrations/V0004__meseta.sql +++ b/src/entity/gateway/postgres/migrations/V0004__meseta.sql @@ -1,10 +1,10 @@ create table character_meseta ( - pchar integer references character (id) not null unique, - meseta integer not null, + pchar integer references player_character (id) not null unique, + meseta integer not null ); create table bank_meseta ( - pchar integer references character (id) not null, + pchar integer references player_character (id) not null, bank varchar(128) not null, meseta integer not null, unique (pchar, bank) @@ -12,4 +12,5 @@ create table bank_meseta ( alter table player_character - drop column meseta, bank_meseta; + drop column meseta, + drop column bank_meseta; diff --git a/src/entity/gateway/postgres/migrations/V0005__trade.sql b/src/entity/gateway/postgres/migrations/V0005__trade.sql index 16d3b84..4043c6b 100644 --- a/src/entity/gateway/postgres/migrations/V0005__trade.sql +++ b/src/entity/gateway/postgres/migrations/V0005__trade.sql @@ -1,5 +1,5 @@ create table trades ( id serial primary key not null, - character1 integer references character (id) not null, - character2 integer references character (id) not null, + character1 integer references player_character (id) not null, + character2 integer references player_character (id) not null ); diff --git a/src/entity/gateway/postgres/models.rs b/src/entity/gateway/postgres/models.rs index c7a378b..5350964 100644 --- a/src/entity/gateway/postgres/models.rs +++ b/src/entity/gateway/postgres/models.rs @@ -49,8 +49,8 @@ pub struct PgUserSettings { id: i32, user_account: i32, blocked_users: Vec, //[u32; 0x1E], - keyboard_config: Vec, //[u8; 0x16C], - gamepad_config: Vec, //[u8; 0x38], + key_config: Vec, //[u8; 0x16C], + joystick_config: Vec, //[u8; 0x38], option_flags: i32, shortcuts: Vec, //[u8; 0xA40], symbol_chats: Vec, //[u8; 0x4E0], @@ -64,8 +64,8 @@ impl From for UserSettingsEntity { user_id: UserAccountId(other.user_account as u32), settings: settings::UserSettings { blocked_users: vec_to_array(other.blocked_users.chunks(4).map(|b| u32::from_le_bytes([b[0], b[1], b[2], b[3]])).collect()), - keyboard_config: vec_to_array(other.keyboard_config), - gamepad_config: vec_to_array(other.gamepad_config), + keyboard_config: vec_to_array(other.key_config), + gamepad_config: vec_to_array(other.joystick_config), option_flags: other.option_flags as u32, shortcuts: vec_to_array(other.shortcuts), symbol_chats: vec_to_array(other.symbol_chats), diff --git a/src/entity/gateway/postgres/postgres.rs b/src/entity/gateway/postgres/postgres.rs index d6ab8ee..a3d4f14 100644 --- a/src/entity/gateway/postgres/postgres.rs +++ b/src/entity/gateway/postgres/postgres.rs @@ -224,10 +224,21 @@ async fn save_user_settings(conn: &mut sqlx::PgConnection, settings: &UserSettin async fn create_character(conn: &mut sqlx::PgConnection, char: NewCharacterEntity) -> Result { let q = r#"insert into player_character - (user_account, slot, name, exp, class, section_id, costume, skin, face, head, hair, hair_r, hair_g, hair_b, prop_x, prop_y, techs, - config, infoboard, guildcard, power, mind, def, evade, luck, hp, tp, tech_menu, option_flags) + (user_account, slot, name, exp, class, + section_id, costume, skin, face, head, + hair, hair_r, hair_g, hair_b, prop_x, + prop_y, techs, config, infoboard, guildcard, + power, mind, def, evade, luck, + hp, tp, tech_menu, option_flags, keyboard_config, + gamepad_config, playtime) values - ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31) + ($1, $2, $3, $4, $5, + $6, $7, $8, $9, $10, + $11, $12, $13, $14, $15, + $16, $17, $18, $19, $20, + $21, $22, $23, $24, $25, + $26, $27, $28, $29, $30, + $31, $32) returning *;"#; let character = sqlx::query_as::<_, PgCharacter>(q) .bind(char.user_id.0) @@ -259,6 +270,9 @@ async fn create_character(conn: &mut sqlx::PgConnection, char: NewCharacterEntit .bind(char.materials.tp as i16) .bind(char.tech_menu.tech_menu.to_vec()) .bind(char.option_flags as i32) + .bind(&char.keyboard_config.keyboard_config.to_vec()) + .bind(&char.gamepad_config.gamepad_config.to_vec()) + .bind(0) .fetch_one(conn).await?; Ok(character.into()) @@ -284,8 +298,8 @@ async fn save_character(conn: &mut sqlx::PgConnection, char: &CharacterEntity) - let q = r#"update player_character set user_account=$1, slot=$2, name=$3, exp=$4, class=$5, section_id=$6, costume=$7, skin=$8, face=$9, head=$10, hair=$11, hair_r=$12, hair_g=$13, hair_b=$14, prop_x=$15, prop_y=$16, techs=$17, config=$18, infoboard=$19, guildcard=$20, power=$21, mind=$22, def=$23, - evade=$24, luck=$25, hp=$26, tp=$27, tech_menu=$28, option_flags=$29, playtime=$30 - where id=$31;"#; + evade=$24, luck=$25, hp=$26, tp=$27, tech_menu=$28, option_flags=$29, keyboard_config=$30, gamepad_config=$31, playtime=$32, + where id=$33;"#; sqlx::query(q) .bind(char.user_id.0) // $1 .bind(char.slot as i16) // $2 @@ -316,8 +330,10 @@ async fn save_character(conn: &mut sqlx::PgConnection, char: &CharacterEntity) - .bind(char.materials.tp as i16) // $27 .bind(char.tech_menu.tech_menu.to_vec()) // $28 .bind(char.option_flags as i32) // $29 - .bind(char.playtime as i32) // $20 - .bind(char.id.0 as i32) // $31 + .bind(&char.keyboard_config.keyboard_config.to_vec()) // $30 + .bind(&char.gamepad_config.gamepad_config.to_vec()) // $31 + .bind(char.playtime as i32) // $32 + .bind(char.id.0 as i32) // $33 .execute(conn).await?; Ok(()) } @@ -530,7 +546,7 @@ async fn set_character_equips(conn: &mut sqlx::PgConnection, char_id: &Character async fn set_character_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntityId, meseta: Meseta) -> Result<(), GatewayError> { - sqlx::query("insert into character_meseta values ($1, $2) on conflict (pchar) do update set items = $2") + sqlx::query("insert into character_meseta values ($1, $2) on conflict (pchar) do update set meseta = $2") .bind(char_id.0) .bind(meseta.0 as i32) .execute(conn) @@ -542,7 +558,7 @@ async fn get_character_meseta(conn: &mut sqlx::PgConnection, char_id: &Character { #[derive(sqlx::FromRow)] struct PgMeseta(i32); - let meseta = sqlx::query_as::<_, PgMeseta>(r#"select meseta from character_meseta where id = $1"#) + let meseta = sqlx::query_as::<_, PgMeseta>(r#"select meseta from character_meseta where pchar = $1"#) .bind(char_id.0) .fetch_one(conn) .await?; @@ -551,10 +567,10 @@ async fn get_character_meseta(conn: &mut sqlx::PgConnection, char_id: &Character async fn set_bank_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntityId, bank: &BankName, meseta: Meseta) -> Result<(), GatewayError> { - sqlx::query("insert into bank_meseta values ($1, $2, $3) on conflict (pchar, bank) do update set items = $2") + sqlx::query("insert into bank_meseta values ($1, $2, $3) on conflict (pchar, bank) do update set meseta = $3") .bind(char_id.0) - .bind(meseta.0 as i32) .bind(bank.0.clone()) + .bind(meseta.0 as i32) .execute(conn) .await?; Ok(()) @@ -564,7 +580,7 @@ async fn get_bank_meseta(conn: &mut sqlx::PgConnection, char_id: &CharacterEntit { #[derive(sqlx::FromRow)] struct PgMeseta(i32); - let meseta = sqlx::query_as::<_, PgMeseta>(r#"select meseta from character_meseta where id = $1 and bank = $2"#) + let meseta = sqlx::query_as::<_, PgMeseta>(r#"select meseta from bank_meseta where pchar = $1 and bank = $2"#) .bind(char_id.0) .bind(bank.0.clone()) .fetch_one(conn) @@ -584,10 +600,10 @@ async fn create_trade(conn: &mut sqlx::PgConnection, char_id1: &CharacterEntityI async fn set_character_playtime(conn: &mut sqlx::PgConnection, char_id: &CharacterEntityId, playtime: u32) -> Result<(), GatewayError> { - sqlx::query_as::<_, PgTradeEntity>(r#"update player_character set playtime=$2 where id=$1;"#) + sqlx::query(r#"update player_character set playtime=$2 where id=$1;"#) .bind(char_id.0) .bind(playtime) - .fetch_one(conn) + .execute(conn) .await?; Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index 176a9fe..e9edf0e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,6 @@ #![feature(drain_filter)] #![feature(try_blocks)] #![feature(once_cell)] -#![feature(pin_macro)] #![feature(test)] extern crate test; diff --git a/src/login/character.rs b/src/login/character.rs index b6e28ab..928b4b2 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -38,13 +38,18 @@ pub const CHARACTER_PORT: u16 = 12001; pub const SHIP_MENU_ID: u32 = 1; #[derive(thiserror::Error, Debug)] -#[error("")] pub enum CharacterError { + #[error("invalid menu selection {0} {1}")] InvalidMenuSelection(u32, u32), + #[error("client not found {0}")] ClientNotFound(ClientId), - CouldNotLoadSettings, + #[error("could not load settings {0}")] + CouldNotLoadSettings(GatewayError), + #[error("could not load characters")] CouldNotLoadCharacters, + #[error("could not load guildcard")] CouldNotLoadGuildcard, + #[error("gateway error {0}")] GatewayError(#[from] GatewayError), } @@ -206,6 +211,7 @@ async fn new_character(entity_gateway: &mut EG, user: let character = entity_gateway.create_character(character).await?; entity_gateway.set_character_meseta(&character.id, Meseta(300)).await?; + entity_gateway.set_bank_meseta(&character.id, &BankName("".into()), Meseta(300)).await?; let new_weapon = match character.char_class { CharacterClass::HUmar | CharacterClass::HUnewearl | CharacterClass::HUcast | CharacterClass::HUcaseal => item::weapon::WeaponType::Saber, @@ -385,7 +391,7 @@ impl CharacterServerState { Ok(settings) => settings, Err(_) => { let user_settings = NewUserSettingsEntity::new(user.id); - self.entity_gateway.create_user_settings(user_settings).await.map_err(|_| CharacterError::CouldNotLoadSettings)? + self.entity_gateway.create_user_settings(user_settings).await.map_err(|err| CharacterError::CouldNotLoadSettings(err))? } }; diff --git a/src/login/login.rs b/src/login/login.rs index e37b0ff..bce909a 100644 --- a/src/login/login.rs +++ b/src/login/login.rs @@ -21,8 +21,8 @@ pub const LOGIN_PORT: u16 = 12000; pub const COMMUNICATION_PORT: u16 = 12123; #[derive(thiserror::Error, Debug)] -#[error("")] pub enum LoginError { + #[error("dberror")] DbError } diff --git a/src/ship/ship.rs b/src/ship/ship.rs index a71cc14..88cb2a4 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -834,6 +834,8 @@ impl ServerState for ShipServerState { self.item_state.remove_character_from_room(&client.character).await } + block.client_location.remove_client_from_area(id).await?; + Ok(neighbors.into_iter().map(|n| { (n.client, pkt.clone()) }).collect())