track character playtime
This commit is contained in:
parent
a26fbe1c68
commit
4788f707ed
@ -413,4 +413,6 @@ pub struct CharacterEntity {
|
||||
pub option_flags: u32,
|
||||
pub keyboard_config: CharacterKeyboardConfig,
|
||||
pub gamepad_config: CharacterGamepadConfig,
|
||||
|
||||
pub playtime: u32,
|
||||
}
|
||||
|
@ -147,6 +147,10 @@ pub trait EntityGateway: Send + Sync {
|
||||
async fn create_trade(&mut self, _char_id1: &CharacterEntityId, _char_id2: &CharacterEntityId) -> Result<TradeEntity, GatewayError> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
async fn set_character_playtime(&mut self, _char_id: &CharacterEntityId, _playtime: u32) -> Result<(), GatewayError> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -346,6 +346,7 @@ impl EntityGateway for InMemoryGateway {
|
||||
option_flags: character.option_flags,
|
||||
keyboard_config: character.keyboard_config,
|
||||
gamepad_config: character.gamepad_config,
|
||||
playtime: 0,
|
||||
};
|
||||
characters.insert(new_character.id, new_character.clone());
|
||||
Ok(new_character)
|
||||
@ -503,4 +504,15 @@ impl EntityGateway for InMemoryGateway {
|
||||
trades.push(new_trade.clone());
|
||||
Ok(new_trade)
|
||||
}
|
||||
|
||||
async fn set_character_playtime(&mut self, char_id: &CharacterEntityId, playtime: u32) -> Result<(), GatewayError> {
|
||||
let mut characters = self.characters.lock().unwrap();
|
||||
if let Some(character) = characters.get_mut(char_id) {
|
||||
character.playtime = playtime;
|
||||
Ok(())
|
||||
}
|
||||
else {
|
||||
Err(GatewayError::Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,2 @@
|
||||
alter table player_character
|
||||
add playtime integer;
|
@ -219,6 +219,8 @@ pub struct PgCharacter {
|
||||
tech_menu: Vec<u8>,
|
||||
keyboard_config: Vec<u8>,
|
||||
gamepad_config: Vec<u8>,
|
||||
|
||||
playtime: i32,
|
||||
}
|
||||
|
||||
impl From<PgCharacter> for CharacterEntity {
|
||||
@ -274,6 +276,7 @@ impl From<PgCharacter> for CharacterEntity {
|
||||
gamepad_config: CharacterGamepadConfig {
|
||||
gamepad_config: vec_to_array(other.gamepad_config)
|
||||
},
|
||||
playtime: other.playtime as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -269,39 +269,40 @@ 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
|
||||
where id=$32;"#;
|
||||
evade=$24, luck=$25, hp=$26, tp=$27, tech_menu=$28, option_flags=$29, playtime=$30
|
||||
where id=$31;"#;
|
||||
sqlx::query(q)
|
||||
.bind(char.user_id.0)
|
||||
.bind(char.slot as i16)
|
||||
.bind(&char.name)
|
||||
.bind(char.exp as i32)
|
||||
.bind(char.char_class.to_string())
|
||||
.bind(char.section_id.to_string())
|
||||
.bind(char.appearance.costume as i16)
|
||||
.bind(char.appearance.skin as i16)
|
||||
.bind(char.appearance.face as i16)
|
||||
.bind(char.appearance.head as i16)
|
||||
.bind(char.appearance.hair as i16)
|
||||
.bind(char.appearance.hair_r as i16)
|
||||
.bind(char.appearance.hair_g as i16)
|
||||
.bind(char.appearance.hair_b as i16)
|
||||
.bind(char.appearance.prop_x)
|
||||
.bind(char.appearance.prop_y)
|
||||
.bind(&char.techs.as_bytes().to_vec())
|
||||
.bind(&char.config.as_bytes().to_vec())
|
||||
.bind(String::from_utf16_lossy(&char.info_board.board).trim_matches(char::from(0)))
|
||||
.bind(&char.guildcard.description)
|
||||
.bind(char.materials.power as i16)
|
||||
.bind(char.materials.mind as i16)
|
||||
.bind(char.materials.def as i16)
|
||||
.bind(char.materials.evade as i16)
|
||||
.bind(char.materials.luck as i16)
|
||||
.bind(char.materials.hp as i16)
|
||||
.bind(char.materials.tp as i16)
|
||||
.bind(char.tech_menu.tech_menu.to_vec())
|
||||
.bind(char.option_flags as i32)
|
||||
.bind(char.id.0 as i32)
|
||||
.bind(char.user_id.0) // $1
|
||||
.bind(char.slot as i16) // $2
|
||||
.bind(&char.name) // $3
|
||||
.bind(char.exp as i32) // $4
|
||||
.bind(char.char_class.to_string()) // $5
|
||||
.bind(char.section_id.to_string()) // $6
|
||||
.bind(char.appearance.costume as i16) // $7
|
||||
.bind(char.appearance.skin as i16) // $8
|
||||
.bind(char.appearance.face as i16) // $9
|
||||
.bind(char.appearance.head as i16) // $10
|
||||
.bind(char.appearance.hair as i16) // $11
|
||||
.bind(char.appearance.hair_r as i16) // $12
|
||||
.bind(char.appearance.hair_g as i16) // $13
|
||||
.bind(char.appearance.hair_b as i16) // $14
|
||||
.bind(char.appearance.prop_x) // $15
|
||||
.bind(char.appearance.prop_y) // $16
|
||||
.bind(&char.techs.as_bytes().to_vec()) // $17
|
||||
.bind(&char.config.as_bytes().to_vec()) // $18
|
||||
.bind(String::from_utf16_lossy(&char.info_board.board).trim_matches(char::from(0))) // $19
|
||||
.bind(&char.guildcard.description) // $20
|
||||
.bind(char.materials.power as i16) // $21
|
||||
.bind(char.materials.mind as i16) // $22
|
||||
.bind(char.materials.def as i16) // $23
|
||||
.bind(char.materials.evade as i16) // $24
|
||||
.bind(char.materials.luck as i16) // $25
|
||||
.bind(char.materials.hp as i16) // $26
|
||||
.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
|
||||
.execute(conn).await?;
|
||||
Ok(())
|
||||
}
|
||||
@ -566,6 +567,16 @@ async fn create_trade(conn: &mut sqlx::PgConnection, char_id1: &CharacterEntityI
|
||||
Ok(trade.into())
|
||||
}
|
||||
|
||||
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;"#)
|
||||
.bind(char_id.0)
|
||||
.bind(playtime)
|
||||
.fetch_one(conn)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl EntityGateway for PostgresGateway {
|
||||
async fn transaction<'a>(&'a mut self) -> Result<Box<dyn EntityGatewayTransaction + 'a>, GatewayError>
|
||||
@ -705,6 +716,10 @@ impl EntityGateway for PostgresGateway {
|
||||
async fn create_trade(&mut self, char_id1: &CharacterEntityId, char_id2: &CharacterEntityId) -> Result<TradeEntity, GatewayError> {
|
||||
create_trade(&mut *self.pool.acquire().await?, char_id1, char_id2).await
|
||||
}
|
||||
|
||||
async fn set_character_playtime(&mut self, char_id: &CharacterEntityId, playtime: u32) -> Result<(), GatewayError> {
|
||||
set_character_playtime(&mut *self.pool.acquire().await?, char_id, playtime).await
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -825,5 +840,9 @@ impl<'c> EntityGateway for PostgresTransaction<'c> {
|
||||
async fn create_trade(&mut self, char_id1: &CharacterEntityId, char_id2: &CharacterEntityId) -> Result<TradeEntity, GatewayError> {
|
||||
create_trade(&mut *self.pgtransaction, char_id1, char_id2).await
|
||||
}
|
||||
|
||||
async fn set_character_playtime(&mut self, char_id: &CharacterEntityId, playtime: u32) -> Result<(), GatewayError> {
|
||||
set_character_playtime(&mut *self.pgtransaction, char_id, playtime).await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -790,7 +790,7 @@ impl<'a> SelectScreenCharacterBuilder<'a> {
|
||||
prop_x: character.appearance.prop_x,
|
||||
prop_y: character.appearance.prop_y,
|
||||
name: utf8_to_utf16_array!(character.name, 16),
|
||||
//play_time: character.play_time,
|
||||
play_time: character.playtime,
|
||||
..character::SelectScreenCharacter::default()
|
||||
}
|
||||
}
|
||||
|
@ -290,10 +290,6 @@ pub struct LoadingQuest {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
pub struct ClientState {
|
||||
pub user: UserAccountEntity,
|
||||
pub settings: UserSettingsEntity,
|
||||
@ -312,10 +308,13 @@ pub struct ClientState {
|
||||
pub tool_shop: Vec<ToolShopItem>,
|
||||
pub armor_shop: Vec<ArmorShopItem>,
|
||||
pub tek: Option<(items::ClientItemId, item::weapon::TekSpecialModifier, item::weapon::TekPercentModifier, i32)>,
|
||||
pub character_playtime: chrono::Duration,
|
||||
pub log_on_time: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl ClientState {
|
||||
pub fn new(user: UserAccountEntity, settings: UserSettingsEntity, character: CharacterEntity, session: Session) -> ClientState {
|
||||
let character_playtime = chrono::Duration::seconds(character.playtime as i64);
|
||||
ClientState {
|
||||
user,
|
||||
settings,
|
||||
@ -332,9 +331,17 @@ impl ClientState {
|
||||
tool_shop: Vec::new(),
|
||||
armor_shop: Vec::new(),
|
||||
tek: None,
|
||||
character_playtime,
|
||||
log_on_time: chrono::Utc::now(),
|
||||
}
|
||||
}
|
||||
|
||||
fn update_playtime(&mut self) {
|
||||
let additional_playtime = chrono::Utc::now() - self.log_on_time;
|
||||
self.character.playtime = (self.character_playtime + additional_playtime).num_seconds() as u32;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct ItemShops {
|
||||
pub weapon_shop: HashMap<(room::Difficulty, SectionID), WeaponShop<rand_chacha::ChaCha20Rng>>,
|
||||
@ -631,6 +638,11 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> {
|
||||
|
||||
async fn handle(&mut self, id: ClientId, pkt: &RecvShipPacket)
|
||||
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error> {
|
||||
if let Some(client) = self.clients.get_mut(&id) {
|
||||
client.update_playtime();
|
||||
self.entity_gateway.set_character_playtime(&client.character.id, client.character.playtime).await?;
|
||||
}
|
||||
|
||||
Ok(match pkt {
|
||||
RecvShipPacket::Login(login) => {
|
||||
Box::new(handler::auth::validate_login(id, login, &mut self.entity_gateway, &mut self.clients, &mut self.item_state, &self.shipgate_sender, &self.name, self.blocks.0.len())
|
||||
|
Loading…
x
Reference in New Issue
Block a user