Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Steam_User_Stats::GetAchievementIcon() #9

Merged
merged 15 commits into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dll/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const std::chrono::time_point<std::chrono::high_resolution_clock> startup_counte
const std::chrono::time_point<std::chrono::system_clock> startup_time = std::chrono::system_clock::now();

#ifndef EMU_RELEASE_BUILD
dbg_log dbg_logger(get_full_program_path() + "STEAM_LOG.txt");
dbg_log dbg_logger(get_full_program_path() + "STEAM_LOG_" + std::to_string(common_helpers::rand_number(UINT32_MAX)) + ".log");
#endif


Expand Down
10 changes: 8 additions & 2 deletions dll/dll/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,15 @@ class Settings {
std::map<std::string, Leaderboard_config> leaderboards{};
std::map<std::string, Stat_config> stats{};

std::map<size_t, struct Image_Data> images{};

//supported languages
std::set<std::string> supported_languages_set{};
std::string supported_languages{};

public:
constexpr const static int INVALID_IMAGE_HANDLE = 0;

//Depots
std::vector<DepotId_t> depots{};

Expand Down Expand Up @@ -253,6 +257,9 @@ class Settings {
// when a stat that's tied to an achievement gets a new value, should the emu save that progress only if it's higher?
// the stat itself is always saved regardless of that flag, only affects the achievement progress
bool save_only_higher_stat_achievement_progress = true;
// the emulator loads the achievements icons is memory mainly for `ISteamUserStats::GetAchievementIcon()`
// true means load icons lazily when they are requested, otherwise load icons as soon as the interface ISteamUserStats is initialized
bool lazy_load_achievements_icons = true;

// bypass to make SetAchievement() always return true, prevent some games from breaking
bool achievement_bypass = false;
Expand All @@ -265,8 +272,6 @@ class Settings {
// enable owning Steam Applications IDs (mostly builtin apps + dedicated servers)
bool enable_builtin_preowned_ids = false;

std::map<int, struct Image_Data> images{};

//subscribed lobby/group ids
std::set<uint64> subscribed_groups{};
std::vector<Group_Clans> subscribed_groups_clans{};
Expand Down Expand Up @@ -383,6 +388,7 @@ class Settings {

//images
int add_image(const std::string &data, uint32 width, uint32 height);
Image_Data* get_image(int handle);

// overlay auto accept stuff
void acceptAnyOverlayInvites(bool value);
Expand Down
10 changes: 9 additions & 1 deletion dll/dll/steam_user_stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public ISteamUserStats
{
public:
static constexpr auto achievements_user_file = "achievements.json";
static constexpr int UNLOADED_ACH_ICON = -1;

private:
template<typename T>
Expand All @@ -94,6 +95,8 @@ public ISteamUserStats
nlohmann::json defined_achievements{};
nlohmann::json user_achievements{};
std::vector<std::string> sorted_achievement_names{};
bool achievements_icons_loaded = false;

std::map<std::string, int32> stats_cache_int{};
std::map<std::string, float> stats_cache_float{};

Expand All @@ -109,6 +112,8 @@ public ISteamUserStats
void load_achievements();
void save_achievements();

int load_ach_icon(nlohmann::json &defined_ach, bool achieved);

nlohmann::detail::iter_impl<nlohmann::json> defined_achievements_find(const std::string &key);
std::string get_value_for_language(const nlohmann::json &json, std::string_view key, std::string_view language);

Expand All @@ -132,6 +137,7 @@ public ISteamUserStats
InternalSetResult<bool> clear_achievement_internal( const char *pchName );

void send_updated_stats();
void load_achievements_icons();
void steam_run_callback();

// requests from server
Expand Down Expand Up @@ -207,7 +213,9 @@ public ISteamUserStats
// specified achievement.
int GetAchievementIcon( const char *pchName );

std::string get_achievement_icon_name( const char *pchName, bool pbAchieved );
int get_achievement_icon_handle( const std::string &ach_name, bool pbAchieved );

std::string get_achievement_icon_name( const char *pchName, bool achieved );


// Get general attributes for an achievement. Accepts the following keys:
Expand Down
15 changes: 7 additions & 8 deletions dll/local_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -859,9 +859,9 @@ std::vector<image_pixel_t> Local_Storage::load_image(std::string const& image_pa
std::vector<image_pixel_t> res{};
int width{}, height{};
image_pixel_t* img = (image_pixel_t*)stbi_load(image_path.c_str(), &width, &height, nullptr, 4);
if (img != nullptr)
{
res.resize(width*height);
PRINT_DEBUG("stbi_load('%s') -> %s", image_path.c_str(), (img ? "loaded" : stbi_failure_reason()));
if (img) {
res.resize(width * height);
std::copy(img, img + width * height, res.begin());

stbi_image_free(img);
Expand All @@ -875,19 +875,18 @@ std::string Local_Storage::load_image_resized(std::string const& image_path, std
{
std::string resized_image{};
const size_t resized_img_size = resolution * resolution * 4;

if (image_path.length() > 0) {
if (image_path.size()) {
int width = 0;
int height = 0;
unsigned char *img = stbi_load(image_path.c_str(), &width, &height, nullptr, 4);
PRINT_DEBUG("stbi_load('%s') -> %s", image_path.c_str(), (img == nullptr ? stbi_failure_reason() : "loaded"));
if (img != nullptr) {
PRINT_DEBUG("stbi_load('%s') -> %s", image_path.c_str(), (img ? "loaded" : stbi_failure_reason()));
if (img) {
std::vector<char> out_resized(resized_img_size);
stbir_resize_uint8(img, width, height, 0, (unsigned char*)&out_resized[0], resolution, resolution, 0, 4);
resized_image = std::string((char*)&out_resized[0], out_resized.size());
stbi_image_free(img);
}
} else if (image_data.length() > 0) {
} else if (image_data.size()) {
std::vector<char> out_resized(resized_img_size);
stbir_resize_uint8((unsigned char*)image_data.c_str(), 184, 184, 0, (unsigned char*)&out_resized[0], resolution, resolution, 0, 4);
resized_image = std::string((char*)&out_resized[0], out_resized.size());
Expand Down
32 changes: 28 additions & 4 deletions dll/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,13 +353,37 @@ std::map<std::string, Stat_config>::const_iterator Settings::setStatDefiniton(co

int Settings::add_image(const std::string &data, uint32 width, uint32 height)
{
int last = static_cast<int>(images.size()) + 1;
struct Image_Data dt;
auto previous_it = std::find_if(images.begin(), images.end(), [&](const std::pair<const size_t, Image_Data> &item) {
return item.second.data == data
&& item.second.height == height
&& item.second.width == width;
});
if (images.end() != previous_it) {
return static_cast<int>(previous_it->first);
}

struct Image_Data dt{};
dt.width = width;
dt.height = height;
dt.data = data;
images[last] = dt;
return last;

auto new_handle = images.size() + 1; // never return 0, it is a bad handle for most ISteamUserStats APIs
images[new_handle] = dt;

return static_cast<int>(new_handle);
}

Image_Data* Settings::get_image(int handle)
{
if (INVALID_IMAGE_HANDLE == handle) {
return nullptr;
}

auto image_it = images.find(handle);
if (images.end() == image_it) {
return nullptr;
}
return &image_it->second;
}


Expand Down
32 changes: 20 additions & 12 deletions dll/settings_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1364,18 +1364,6 @@ static void parse_simple_features(class Settings *settings_client, class Setting
settings_client->steam_deck = ini.GetBoolValue("main::general", "steam_deck", settings_client->steam_deck);
settings_server->steam_deck = ini.GetBoolValue("main::general", "steam_deck", settings_server->steam_deck);

settings_client->disable_leaderboards_create_unknown = ini.GetBoolValue("main::general", "disable_leaderboards_create_unknown", settings_client->disable_leaderboards_create_unknown);
settings_server->disable_leaderboards_create_unknown = ini.GetBoolValue("main::general", "disable_leaderboards_create_unknown", settings_server->disable_leaderboards_create_unknown);

settings_client->allow_unknown_stats = ini.GetBoolValue("main::general", "allow_unknown_stats", settings_client->allow_unknown_stats);
settings_server->allow_unknown_stats = ini.GetBoolValue("main::general", "allow_unknown_stats", settings_server->allow_unknown_stats);

settings_client->stat_achievement_progress_functionality = ini.GetBoolValue("main::general", "stat_achievement_progress_functionality", settings_client->stat_achievement_progress_functionality);
settings_server->stat_achievement_progress_functionality = ini.GetBoolValue("main::general", "stat_achievement_progress_functionality", settings_server->stat_achievement_progress_functionality);

settings_client->save_only_higher_stat_achievement_progress = ini.GetBoolValue("main::general", "save_only_higher_stat_achievement_progress", settings_client->save_only_higher_stat_achievement_progress);
settings_server->save_only_higher_stat_achievement_progress = ini.GetBoolValue("main::general", "save_only_higher_stat_achievement_progress", settings_server->save_only_higher_stat_achievement_progress);

settings_client->immediate_gameserver_stats = ini.GetBoolValue("main::general", "immediate_gameserver_stats", settings_client->immediate_gameserver_stats);
settings_server->immediate_gameserver_stats = ini.GetBoolValue("main::general", "immediate_gameserver_stats", settings_server->immediate_gameserver_stats);

Expand Down Expand Up @@ -1420,6 +1408,25 @@ static void parse_simple_features(class Settings *settings_client, class Setting
settings_server->enable_builtin_preowned_ids = ini.GetBoolValue("main::misc", "enable_steam_preowned_ids", settings_server->enable_builtin_preowned_ids);
}

// [main::stats]
static void parse_stats_features(class Settings *settings_client, class Settings *settings_server)
{
settings_client->disable_leaderboards_create_unknown = ini.GetBoolValue("main::stats", "disable_leaderboards_create_unknown", settings_client->disable_leaderboards_create_unknown);
settings_server->disable_leaderboards_create_unknown = ini.GetBoolValue("main::stats", "disable_leaderboards_create_unknown", settings_server->disable_leaderboards_create_unknown);

settings_client->allow_unknown_stats = ini.GetBoolValue("main::stats", "allow_unknown_stats", settings_client->allow_unknown_stats);
settings_server->allow_unknown_stats = ini.GetBoolValue("main::stats", "allow_unknown_stats", settings_server->allow_unknown_stats);

settings_client->stat_achievement_progress_functionality = ini.GetBoolValue("main::stats", "stat_achievement_progress_functionality", settings_client->stat_achievement_progress_functionality);
settings_server->stat_achievement_progress_functionality = ini.GetBoolValue("main::stats", "stat_achievement_progress_functionality", settings_server->stat_achievement_progress_functionality);

settings_client->save_only_higher_stat_achievement_progress = ini.GetBoolValue("main::stats", "save_only_higher_stat_achievement_progress", settings_client->save_only_higher_stat_achievement_progress);
settings_server->save_only_higher_stat_achievement_progress = ini.GetBoolValue("main::stats", "save_only_higher_stat_achievement_progress", settings_server->save_only_higher_stat_achievement_progress);

settings_client->lazy_load_achievements_icons = ini.GetBoolValue("main::stats", "lazy_load_achievements_icons", settings_client->lazy_load_achievements_icons);
settings_server->lazy_load_achievements_icons = ini.GetBoolValue("main::stats", "lazy_load_achievements_icons", settings_server->lazy_load_achievements_icons);
}



static std::map<SettingsItf, std::string> old_itfs_map{};
Expand Down Expand Up @@ -1673,6 +1680,7 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s
settings_server->set_supported_languages(supported_languages);

parse_simple_features(settings_client, settings_server);
parse_stats_features(settings_client, settings_server);

parse_dlc(settings_client, settings_server);
parse_installed_app_Ids(settings_client, settings_server);
Expand Down
10 changes: 8 additions & 2 deletions dll/steam_friends.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1280,9 +1280,15 @@ void Steam_Friends::Callback(Common_Message *msg)
f->set_name(settings->get_local_name());
f->set_appid(settings->get_local_game_id().AppID());
f->set_lobby_id(settings->get_lobby().ConvertToUint64());

int avatar_number = GetLargeFriendAvatar(settings->get_local_steam_id());
if (settings->images[avatar_number].data.length() > 0) f->set_avatar(settings->images[avatar_number].data);
else f->set_avatar("");
auto avatar_info = settings->get_image(avatar_number);
if (avatar_info && avatar_info->data.size()) {
f->set_avatar(avatar_info->data);
} else {
f->set_avatar("");
}

msg_.set_allocated_friend_(f);
network->sendTo(&msg_, true);
}
Expand Down
Loading