track character playtime
This commit is contained in:
parent
a26fbe1c68
commit
4788f707ed
@ -413,4 +413,6 @@ pub struct CharacterEntity {
|
|||||||
pub option_flags: u32,
|
pub option_flags: u32,
|
||||||
pub keyboard_config: CharacterKeyboardConfig,
|
pub keyboard_config: CharacterKeyboardConfig,
|
||||||
pub gamepad_config: CharacterGamepadConfig,
|
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> {
|
async fn create_trade(&mut self, _char_id1: &CharacterEntityId, _char_id2: &CharacterEntityId) -> Result<TradeEntity, GatewayError> {
|
||||||
unimplemented!();
|
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,
|
option_flags: character.option_flags,
|
||||||
keyboard_config: character.keyboard_config,
|
keyboard_config: character.keyboard_config,
|
||||||
gamepad_config: character.gamepad_config,
|
gamepad_config: character.gamepad_config,
|
||||||
|
playtime: 0,
|
||||||
};
|
};
|
||||||
characters.insert(new_character.id, new_character.clone());
|
characters.insert(new_character.id, new_character.clone());
|
||||||
Ok(new_character)
|
Ok(new_character)
|
||||||
@ -503,4 +504,15 @@ impl EntityGateway for InMemoryGateway {
|
|||||||
trades.push(new_trade.clone());
|
trades.push(new_trade.clone());
|
||||||
Ok(new_trade)
|
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>,
|
tech_menu: Vec<u8>,
|
||||||
keyboard_config: Vec<u8>,
|
keyboard_config: Vec<u8>,
|
||||||
gamepad_config: Vec<u8>,
|
gamepad_config: Vec<u8>,
|
||||||
|
|
||||||
|
playtime: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PgCharacter> for CharacterEntity {
|
impl From<PgCharacter> for CharacterEntity {
|
||||||
@ -274,6 +276,7 @@ impl From<PgCharacter> for CharacterEntity {
|
|||||||
gamepad_config: CharacterGamepadConfig {
|
gamepad_config: CharacterGamepadConfig {
|
||||||
gamepad_config: vec_to_array(other.gamepad_config)
|
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
|
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,
|
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,
|
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
|
evade=$24, luck=$25, hp=$26, tp=$27, tech_menu=$28, option_flags=$29, playtime=$30
|
||||||
where id=$32;"#;
|
where id=$31;"#;
|
||||||
sqlx::query(q)
|
sqlx::query(q)
|
||||||
.bind(char.user_id.0)
|
.bind(char.user_id.0) // $1
|
||||||
.bind(char.slot as i16)
|
.bind(char.slot as i16) // $2
|
||||||
.bind(&char.name)
|
.bind(&char.name) // $3
|
||||||
.bind(char.exp as i32)
|
.bind(char.exp as i32) // $4
|
||||||
.bind(char.char_class.to_string())
|
.bind(char.char_class.to_string()) // $5
|
||||||
.bind(char.section_id.to_string())
|
.bind(char.section_id.to_string()) // $6
|
||||||
.bind(char.appearance.costume as i16)
|
.bind(char.appearance.costume as i16) // $7
|
||||||
.bind(char.appearance.skin as i16)
|
.bind(char.appearance.skin as i16) // $8
|
||||||
.bind(char.appearance.face as i16)
|
.bind(char.appearance.face as i16) // $9
|
||||||
.bind(char.appearance.head as i16)
|
.bind(char.appearance.head as i16) // $10
|
||||||
.bind(char.appearance.hair as i16)
|
.bind(char.appearance.hair as i16) // $11
|
||||||
.bind(char.appearance.hair_r as i16)
|
.bind(char.appearance.hair_r as i16) // $12
|
||||||
.bind(char.appearance.hair_g as i16)
|
.bind(char.appearance.hair_g as i16) // $13
|
||||||
.bind(char.appearance.hair_b as i16)
|
.bind(char.appearance.hair_b as i16) // $14
|
||||||
.bind(char.appearance.prop_x)
|
.bind(char.appearance.prop_x) // $15
|
||||||
.bind(char.appearance.prop_y)
|
.bind(char.appearance.prop_y) // $16
|
||||||
.bind(&char.techs.as_bytes().to_vec())
|
.bind(&char.techs.as_bytes().to_vec()) // $17
|
||||||
.bind(&char.config.as_bytes().to_vec())
|
.bind(&char.config.as_bytes().to_vec()) // $18
|
||||||
.bind(String::from_utf16_lossy(&char.info_board.board).trim_matches(char::from(0)))
|
.bind(String::from_utf16_lossy(&char.info_board.board).trim_matches(char::from(0))) // $19
|
||||||
.bind(&char.guildcard.description)
|
.bind(&char.guildcard.description) // $20
|
||||||
.bind(char.materials.power as i16)
|
.bind(char.materials.power as i16) // $21
|
||||||
.bind(char.materials.mind as i16)
|
.bind(char.materials.mind as i16) // $22
|
||||||
.bind(char.materials.def as i16)
|
.bind(char.materials.def as i16) // $23
|
||||||
.bind(char.materials.evade as i16)
|
.bind(char.materials.evade as i16) // $24
|
||||||
.bind(char.materials.luck as i16)
|
.bind(char.materials.luck as i16) // $25
|
||||||
.bind(char.materials.hp as i16)
|
.bind(char.materials.hp as i16) // $26
|
||||||
.bind(char.materials.tp as i16)
|
.bind(char.materials.tp as i16) // $27
|
||||||
.bind(char.tech_menu.tech_menu.to_vec())
|
.bind(char.tech_menu.tech_menu.to_vec()) // $28
|
||||||
.bind(char.option_flags as i32)
|
.bind(char.option_flags as i32) // $29
|
||||||
.bind(char.id.0 as i32)
|
.bind(char.playtime as i32) // $20
|
||||||
|
.bind(char.id.0 as i32) // $31
|
||||||
.execute(conn).await?;
|
.execute(conn).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -566,6 +567,16 @@ async fn create_trade(conn: &mut sqlx::PgConnection, char_id1: &CharacterEntityI
|
|||||||
Ok(trade.into())
|
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]
|
#[async_trait::async_trait]
|
||||||
impl EntityGateway for PostgresGateway {
|
impl EntityGateway for PostgresGateway {
|
||||||
async fn transaction<'a>(&'a mut self) -> Result<Box<dyn EntityGatewayTransaction + 'a>, GatewayError>
|
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> {
|
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
|
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> {
|
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
|
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_x: character.appearance.prop_x,
|
||||||
prop_y: character.appearance.prop_y,
|
prop_y: character.appearance.prop_y,
|
||||||
name: utf8_to_utf16_array!(character.name, 16),
|
name: utf8_to_utf16_array!(character.name, 16),
|
||||||
//play_time: character.play_time,
|
play_time: character.playtime,
|
||||||
..character::SelectScreenCharacter::default()
|
..character::SelectScreenCharacter::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,10 +290,6 @@ pub struct LoadingQuest {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub struct ClientState {
|
pub struct ClientState {
|
||||||
pub user: UserAccountEntity,
|
pub user: UserAccountEntity,
|
||||||
pub settings: UserSettingsEntity,
|
pub settings: UserSettingsEntity,
|
||||||
@ -312,10 +308,13 @@ pub struct ClientState {
|
|||||||
pub tool_shop: Vec<ToolShopItem>,
|
pub tool_shop: Vec<ToolShopItem>,
|
||||||
pub armor_shop: Vec<ArmorShopItem>,
|
pub armor_shop: Vec<ArmorShopItem>,
|
||||||
pub tek: Option<(items::ClientItemId, item::weapon::TekSpecialModifier, item::weapon::TekPercentModifier, i32)>,
|
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 {
|
impl ClientState {
|
||||||
pub fn new(user: UserAccountEntity, settings: UserSettingsEntity, character: CharacterEntity, session: Session) -> ClientState {
|
pub fn new(user: UserAccountEntity, settings: UserSettingsEntity, character: CharacterEntity, session: Session) -> ClientState {
|
||||||
|
let character_playtime = chrono::Duration::seconds(character.playtime as i64);
|
||||||
ClientState {
|
ClientState {
|
||||||
user,
|
user,
|
||||||
settings,
|
settings,
|
||||||
@ -332,10 +331,18 @@ impl ClientState {
|
|||||||
tool_shop: Vec::new(),
|
tool_shop: Vec::new(),
|
||||||
armor_shop: Vec::new(),
|
armor_shop: Vec::new(),
|
||||||
tek: None,
|
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 struct ItemShops {
|
||||||
pub weapon_shop: HashMap<(room::Difficulty, SectionID), WeaponShop<rand_chacha::ChaCha20Rng>>,
|
pub weapon_shop: HashMap<(room::Difficulty, SectionID), WeaponShop<rand_chacha::ChaCha20Rng>>,
|
||||||
pub tool_shop: ToolShop<rand_chacha::ChaCha20Rng>,
|
pub tool_shop: ToolShop<rand_chacha::ChaCha20Rng>,
|
||||||
@ -631,6 +638,11 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> {
|
|||||||
|
|
||||||
async fn handle(&mut self, id: ClientId, pkt: &RecvShipPacket)
|
async fn handle(&mut self, id: ClientId, pkt: &RecvShipPacket)
|
||||||
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error> {
|
-> 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 {
|
Ok(match pkt {
|
||||||
RecvShipPacket::Login(login) => {
|
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())
|
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