diff --git a/dll/settings.cpp b/dll/settings.cpp index f347c0a..7d59938 100644 --- a/dll/settings.cpp +++ b/dll/settings.cpp @@ -224,3 +224,45 @@ int Settings::add_image(std::string data, uint32 width, uint32 height) images[last] = dt; return last; } + +int Settings::get_profile_image(int eAvatarSize) +{ + int ret = 0; + for (auto i : profile_images) { + if (i.first == eAvatarSize) { + ret = i.second; + break; + } + } + return ret; +} + +int Settings::set_profile_image(int eAvatarSize, Image_Data * image) +{ + bool size_ok = false; + int ref = 0; + + if (image != NULL) { + if (eAvatarSize == k_EAvatarSize32x32 && image->width > 0 && image->width <= 32 && image->height > 0 && image->height <= 32) + size_ok = true; + if (eAvatarSize == k_EAvatarSize64x64 && image->width > 32 && image->width <= 64 && image->height > 32 && image->height <= 64) + size_ok = true; + if (eAvatarSize == k_EAvatarSize184x184 && image->width > 64 && image->width <= 184 && image->height > 64 && image->height <= 184) + size_ok = true; + + if (size_ok == true && image->data.length() > 0) { + ref = this->add_image(image->data, image->width, image->height); + PRINT_DEBUG("set_profile_image %d -> %d.\n", eAvatarSize, ref); + profile_images[eAvatarSize] = ref; + } else { + PRINT_DEBUG("%s %d %dx%d %"PRI_ZU".\n", + "set_profile_image failed", + eAvatarSize, + image->width, + image->height, + image->data.length()); + } + } + + return ref; +} diff --git a/dll/settings.h b/dll/settings.h index 8528895..202c68c 100644 --- a/dll/settings.h +++ b/dll/settings.h @@ -80,6 +80,7 @@ class Settings { std::map app_paths; std::map leaderboards; std::map stats; + std::map profile_images; bool create_unknown_leaderboards; uint16 port; @@ -147,6 +148,8 @@ public: //images std::map images; int add_image(std::string data, uint32 width, uint32 height); + int get_profile_image(int eAvatarSize); + int set_profile_image(int eAvatarSize, Image_Data * image); //controller struct Controller_Settings controller_settings; diff --git a/dll/steam_friends.h b/dll/steam_friends.h index 5f28c95..7bce28e 100644 --- a/dll/steam_friends.h +++ b/dll/steam_friends.h @@ -94,25 +94,132 @@ bool isAppIdCompatible(Friend *f) return settings->get_local_game_id().AppID() == f->appid(); } +STEAM_CALL_RESULT( AvatarImageLoaded_t ) struct Avatar_Numbers add_friend_avatars(CSteamID id) { uint64 steam_id = id.ConvertToUint64(); auto avatar_ids = avatars.find(steam_id); - if (avatar_ids != avatars.end()) { - return avatar_ids->second; + bool generate = true; + int base_image = 0; + struct Avatar_Numbers avatar_numbers; + if (settings->get_local_steam_id().ConvertToUint64() == steam_id) { + avatar_numbers.smallest = settings->get_profile_image(k_EAvatarSize32x32); + if (avatar_numbers.smallest != 0) { + base_image = avatar_numbers.smallest; + } + avatar_numbers.medium = settings->get_profile_image(k_EAvatarSize64x64); + if (avatar_numbers.medium != 0) { + base_image = avatar_numbers.medium; + } + avatar_numbers.large = settings->get_profile_image(k_EAvatarSize184x184); + if (avatar_numbers.large != 0) { + base_image = avatar_numbers.large; + } + + if (base_image != 0) { + generate = false; + if (avatar_numbers.smallest == 0) { + avatar_numbers.smallest = base_image; + } + if (avatar_numbers.medium == 0) { + avatar_numbers.medium = base_image; + } + if (avatar_numbers.large == 0) { + avatar_numbers.large = base_image; + } + } + + if (avatar_ids != avatars.end()) { + // Check for updated entry. + if (avatar_numbers.smallest == avatar_ids->second.smallest && + avatar_numbers.medium == avatar_ids->second.medium && + avatar_numbers.large == avatar_ids->second.large) { + return avatar_ids->second; + } + } + } else { + //TODO: get real image data from other peers + + if (avatar_ids != avatars.end()) { + //TODO: Check for updated entry. + return avatar_ids->second; + } } - //TODO: get real image data from self/other peers - struct Avatar_Numbers avatar_numbers; - std::string small_avatar(32 * 32 * 4, 0); - std::string medium_avatar(64 * 64 * 4, 0); - std::string large_avatar(184 * 184 * 4, 0); + if (generate == true) { + std::string small_avatar(32 * 32 * 4, 0); + std::string medium_avatar(64 * 64 * 4, 0); + std::string large_avatar(184 * 184 * 4, 0); - avatar_numbers.smallest = settings->add_image(small_avatar, 32, 32); - avatar_numbers.medium = settings->add_image(medium_avatar, 64, 64); - avatar_numbers.large = settings->add_image(large_avatar, 184, 184); + avatar_numbers.smallest = settings->add_image(small_avatar, 32, 32); + avatar_numbers.medium = settings->add_image(medium_avatar, 64, 64); + avatar_numbers.large = settings->add_image(large_avatar, 184, 184); + } avatars[steam_id] = avatar_numbers; + + // Generate callbacks. + uint32 width = 0; + uint32 height = 0; + AvatarImageLoaded_t ail_data = {}; + bool sent_ail = false; + + auto image = settings->images.find(avatar_numbers.smallest); + if (image != settings->images.end()) { + width = image->second.width; + height = image->second.height; + } else { + width = 0; + height = 0; + } + + if (avatar_numbers.smallest) { + ail_data.m_steamID = steam_id; + ail_data.m_iImage = avatar_numbers.smallest; + ail_data.m_iWide = width; + ail_data.m_iTall = height; + callback_results->addCallResult(ail_data.k_iCallback, &ail_data, sizeof(ail_data)); + sent_ail = true; + } + + image = settings->images.find(avatar_numbers.medium); + if (image != settings->images.end()) { + width = image->second.width; + height = image->second.height; + } else { + width = 0; + height = 0; + } + + if (avatar_numbers.medium) { + ail_data.m_steamID = steam_id; + ail_data.m_iImage = avatar_numbers.medium; + ail_data.m_iWide = width; + ail_data.m_iTall = height; + callback_results->addCallResult(ail_data.k_iCallback, &ail_data, sizeof(ail_data)); + sent_ail = true; + } + + image = settings->images.find(avatar_numbers.large); + if (image != settings->images.end()) { + width = image->second.width; + height = image->second.height; + } else { + width = 0; + height = 0; + } + + if (avatar_numbers.large) { + ail_data.m_steamID = steam_id; + ail_data.m_iImage = avatar_numbers.large; + ail_data.m_iWide = width; + ail_data.m_iTall = height; + callback_results->addCallResult(ail_data.k_iCallback, &ail_data, sizeof(ail_data)); + sent_ail = true; + } + if (sent_ail) { + persona_change(id, k_EPersonaChangeAvatar); + } return avatar_numbers; } @@ -594,10 +701,10 @@ void ActivateGameOverlayInviteDialog( CSteamID steamIDLobby ) // gets the small (32x32) avatar of the current user, which is a handle to be used in IClientUtils::GetImageRGBA(), or 0 if none set int GetSmallFriendAvatar( CSteamID steamIDFriend ) { - PRINT_DEBUG("Steam_Friends::GetSmallFriendAvatar\n"); //IMPORTANT NOTE: don't change friend avatar numbers for the same friend or else some games endlessly allocate stuff. std::lock_guard lock(global_mutex); struct Avatar_Numbers numbers = add_friend_avatars(steamIDFriend); + PRINT_DEBUG("Steam_Friends::GetSmallFriendAvatar%"PRIu64" %d.\n", steamIDFriend.ConvertToUint64(), numbers.smallest); return numbers.smallest; } @@ -605,9 +712,9 @@ int GetSmallFriendAvatar( CSteamID steamIDFriend ) // gets the medium (64x64) avatar of the current user, which is a handle to be used in IClientUtils::GetImageRGBA(), or 0 if none set int GetMediumFriendAvatar( CSteamID steamIDFriend ) { - PRINT_DEBUG("Steam_Friends::GetMediumFriendAvatar\n"); std::lock_guard lock(global_mutex); struct Avatar_Numbers numbers = add_friend_avatars(steamIDFriend); + PRINT_DEBUG("Steam_Friends::GetMediumFriendAvatar%"PRIu64" %d.\n", steamIDFriend.ConvertToUint64(), numbers.medium); return numbers.medium; } @@ -616,9 +723,9 @@ int GetMediumFriendAvatar( CSteamID steamIDFriend ) // returns -1 if this image has yet to be loaded, in this case wait for a AvatarImageLoaded_t callback and then call this again int GetLargeFriendAvatar( CSteamID steamIDFriend ) { - PRINT_DEBUG("Steam_Friends::GetLargeFriendAvatar\n"); std::lock_guard lock(global_mutex); struct Avatar_Numbers numbers = add_friend_avatars(steamIDFriend); + PRINT_DEBUG("Steam_Friends::GetLargeFriendAvatar %"PRIu64" %d.\n", steamIDFriend.ConvertToUint64(), numbers.large); return numbers.large; }