From 3e5a961b68dee86ec4b1b1650e88ff39a6c7132d Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Sat, 3 Sep 2022 21:17:46 -0700 Subject: [PATCH] implement play time on BB --- src/Player.cc | 27 +++++++++++++++++++++++++-- src/Player.hh | 7 +++++-- src/ReceiveCommands.cc | 1 + 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/Player.cc b/src/Player.cc index 6e29fad7..60b84384 100644 --- a/src/Player.cc +++ b/src/Player.cc @@ -209,7 +209,7 @@ PlayerDispDataBBPreview PlayerDispDataBB::to_preview() const { pre.proportion_x = this->proportion_x; pre.proportion_y = this->proportion_y; pre.name = this->name; - pre.play_time = 0; // TODO: Store this somewhere and return it here + pre.play_time = this->play_time; return pre; } @@ -323,6 +323,13 @@ void PlayerBank::save(const string& filename, bool save_to_filesystem) const { //////////////////////////////////////////////////////////////////////////////// +ClientGameData::ClientGameData() + : last_play_time_update(0), + guild_card_number(0), + should_update_play_time(false), + bb_player_index(0), + should_save(true) { } + ClientGameData::~ClientGameData() { if (!this->bb_username.empty()) { if (this->account_data.get()) { @@ -442,6 +449,9 @@ void ClientGameData::load_account_data() { } void ClientGameData::save_account_data() const { + if (!this->account_data.get()) { + throw logic_error("save_account_data called when no account data loaded"); + } string filename = this->account_data_filename(); player_files_cache.replace(filename, this->account_data.get(), sizeof(SavedAccountDataBB)); if (this->should_save) { @@ -453,6 +463,7 @@ void ClientGameData::save_account_data() const { } void ClientGameData::load_player_data() { + this->last_play_time_update = now(); string filename = this->player_data_filename(); shared_ptr data(new SavedPlayerDataBB( player_files_cache.get_obj_or_load(filename).obj)); @@ -464,7 +475,19 @@ void ClientGameData::load_player_data() { player_data_log.info("Loaded player data file %s", filename.c_str()); } -void ClientGameData::save_player_data() const { +void ClientGameData::save_player_data() { + if (!this->player_data.get()) { + throw logic_error("save_player_data called when no player data loaded"); + } + if (this->should_update_play_time) { + // This is slightly inaccurate, since fractions of a second are truncated + // off each time we save. I'm lazy, so insert shrug emoji here. + uint64_t t = now(); + uint64_t seconds = (t - this->last_play_time_update) / 1000000; + this->player_data->disp.play_time += seconds; + player_data_log.info("Added %" PRIu64 " seconds to play time", seconds); + this->last_play_time_update = t; + } string filename = this->player_data_filename(); player_files_cache.replace(filename, this->player_data.get(), sizeof(SavedPlayerDataBB)); if (this->should_save) { diff --git a/src/Player.hh b/src/Player.hh index ad82e25a..c08f8420 100644 --- a/src/Player.hh +++ b/src/Player.hh @@ -481,9 +481,11 @@ class ClientGameData { private: std::shared_ptr account_data; std::shared_ptr player_data; + uint64_t last_play_time_update; public: uint32_t guild_card_number; + bool should_update_play_time; // The following fields are not saved, and are only used in certain situations @@ -500,7 +502,7 @@ public: std::vector shop_contents; bool should_save; - ClientGameData() : guild_card_number(0), bb_player_index(0), should_save(true) { } + ClientGameData(); ~ClientGameData(); std::shared_ptr account(bool should_load = true); @@ -519,7 +521,8 @@ public: void load_account_data(); void save_account_data() const; void load_player_data(); - void save_player_data() const; + // Note: This function is not const because it updates the player's play time. + void save_player_data(); void import_player(const PSOPlayerDataDCPC& pd); void import_player(const PSOPlayerDataV3& pd); diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index 8a3be352..c45bcdb5 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -129,6 +129,7 @@ void on_login_complete(shared_ptr s, shared_ptr c) { if (c->version() == GameVersion::BB) { // This implicitly loads the client's account and player data send_complete_player_bb(c); + c->game_data.should_update_play_time = true; } send_lobby_list(c, s);