From f693bfb07377e399b6e655bfb147e0dde4466303 Mon Sep 17 00:00:00 2001 From: redpolline <11156324-redpolline@users.noreply.gitlab.com> Date: Sat, 14 Dec 2024 20:11:11 -0500 Subject: [PATCH] Implement sending and receiving friend avatars. Moves Steam_Friends::Callback into a cpp file. Generates callbacks for avatar changes. Requests avatars when asked for one that is unknown. --- dll/base.h | 2 +- dll/steam_friends.cpp | 425 ++++++++++++++++++++++++++++++++++++++++++ dll/steam_friends.h | 229 ++++++++++------------- 3 files changed, 523 insertions(+), 133 deletions(-) create mode 100644 dll/steam_friends.cpp diff --git a/dll/base.h b/dll/base.h index fe59cba..6fa5cfe 100644 --- a/dll/base.h +++ b/dll/base.h @@ -325,12 +325,12 @@ public: if (std::find(callbacks[iCallback].callbacks.begin(), callbacks[iCallback].callbacks.end(), cb) == callbacks[iCallback].callbacks.end()) { callbacks[iCallback].callbacks.push_back(cb); - CCallbackMgr::SetRegister(cb, iCallback); for (auto & res: callbacks[iCallback].results) { //TODO: timeout? SteamAPICall_t api_id = results->addCallResult(iCallback, &(res[0]), res.size(), 0.0, false); results->addCallBack(api_id, cb); } + CCallbackMgr::SetRegister(cb, iCallback); } } diff --git a/dll/steam_friends.cpp b/dll/steam_friends.cpp new file mode 100644 index 0000000..dc87d9f --- /dev/null +++ b/dll/steam_friends.cpp @@ -0,0 +1,425 @@ +/* Copyright (C) 2019 Mr Goldberg + This file is part of the Goldberg Emulator + + The Goldberg Emulator is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + The Goldberg Emulator is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the Goldberg Emulator; if not, see + . */ + +#include "steam_friends.h" +#include "dll.h" + +void Steam_Friends::Callback(Common_Message *msg) +{ + if (msg->has_low_level()) { + if (msg->low_level().type() == Low_Level::DISCONNECT) { + PRINT_DEBUG("Steam_Friends::Callback Disconnect\n"); + uint64 id = msg->source_id(); + auto f = std::find_if(friends.begin(), friends.end(), [&id](Friend const& item) { return item.id() == id; }); + if (friends.end() != f) { + persona_change((uint64)f->id(), k_EPersonaChangeStatus); + overlay->FriendDisconnect(*f); + if ((uint64)f->id() != settings->get_local_steam_id().ConvertToUint64()) { + auto nums = avatars.find((uint64)f->id()); + if (nums != avatars.end()) { + if (nums->second.smallest != 0) { + settings->remove_image(nums->second.smallest); + } + if (nums->second.medium != 0) { + settings->remove_image(nums->second.medium); + } + if (nums->second.large != 0) { + settings->remove_image(nums->second.large); + } + avatars.erase(nums); + } + friends.erase(f); + } + } + } + + if (msg->low_level().type() == Low_Level::CONNECT) { + PRINT_DEBUG("Steam_Friends::Callback Connect\n"); + Common_Message msg_; + msg_.set_source_id(settings->get_local_steam_id().ConvertToUint64()); + msg_.set_dest_id(msg->source_id()); + Friend *f = new Friend(us); + f->set_id(settings->get_local_steam_id().ConvertToUint64()); + f->set_name(settings->get_local_name()); + f->set_appid(settings->get_local_game_id().AppID()); + f->set_lobby_id(settings->get_lobby().ConvertToUint64()); + msg_.set_allocated_friend_(f); + network->sendTo(&msg_, true); + } + } + + if (msg->has_friend_()) { + PRINT_DEBUG("Steam_Friends::Callback Friend %llu %llu\n", msg->friend_().id(), msg->friend_().lobby_id()); + Friend *f = find_friend((uint64)msg->friend_().id()); + if (!f) { + if (msg->friend_().id() != settings->get_local_steam_id().ConvertToUint64()) { + friends.push_back(msg->friend_()); + overlay->FriendConnect(msg->friend_()); + persona_change((uint64)msg->friend_().id(), k_EPersonaChangeName); + } + } else { + std::map map1(f->rich_presence().begin(), f->rich_presence().end()); + std::map map2(msg->friend_().rich_presence().begin(), msg->friend_().rich_presence().end()); + + if (map1 != map2) { + //The App ID of the game. This should always be the current game. + if (isAppIdCompatible(f)) { + rich_presence_updated((uint64)msg->friend_().id(), (uint64)msg->friend_().appid()); + } + } + //TODO: callbacks? + *f = msg->friend_(); + } + } + + if (msg->has_friend_messages()) { + if (msg->friend_messages().type() == Friend_Messages::LOBBY_INVITE) { + PRINT_DEBUG("Steam_Friends::Callback Got Lobby Invite\n"); + Friend *f = find_friend((uint64)msg->source_id()); + if (f) { + LobbyInvite_t data; + data.m_ulSteamIDUser = msg->source_id(); + data.m_ulSteamIDLobby = msg->friend_messages().lobby_id(); + data.m_ulGameID = f->appid(); + callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); + + if (overlay->Ready()) + { + //TODO: the user should accept the invite first but we auto accept it because there's no gui yet + // Then we will handle it ! + overlay->SetLobbyInvite(*find_friend(static_cast(msg->source_id())), msg->friend_messages().lobby_id()); + } + else + { + GameLobbyJoinRequested_t data; + data.m_steamIDLobby = CSteamID((uint64)msg->friend_messages().lobby_id()); + data.m_steamIDFriend = CSteamID((uint64)msg->source_id()); + callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); + } + } + } + + if (msg->friend_messages().type() == Friend_Messages::GAME_INVITE) { + PRINT_DEBUG("Steam_Friends::Callback Got Game Invite\n"); + //TODO: I'm pretty sure that the user should accept the invite before this is posted but we do like above + if (overlay->Ready()) + { + // Then we will handle it ! + overlay->SetRichInvite(*find_friend(static_cast(msg->source_id())), msg->friend_messages().connect_str().c_str()); + } + else + { + std::string const& connect_str = msg->friend_messages().connect_str(); + GameRichPresenceJoinRequested_t data = {}; + data.m_steamIDFriend = CSteamID((uint64)msg->source_id()); + strncpy(data.m_rgchConnect, connect_str.c_str(), k_cchMaxRichPresenceValueLength - 1); + callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); + } + } + } + + if (msg->has_friend_avatar()) { + CSteamID userID((uint64)msg->source_id()); + Friend *f = find_friend(userID.ConvertToUint64()); + if (f) { + if (msg->friend_avatar().img().type() == Image::NOTIFY) { + PRINT_DEBUG("%s %"PRIu64".\n", "Steam_Friends::Callback Got Friend_Avatar NOTIFY for", userID.ConvertToUint64()); + + std::string raw_image = msg->friend_avatar().img().img_data(); + if (raw_image.length() > 0 && raw_image.length() < FRIEND_AVATAR_MAX_IMAGE_LENGTH) { + uint32_t width = (uint32_t)msg->friend_avatar().img().img_width(); + uint32_t height = (uint32_t)msg->friend_avatar().img().img_height(); + uint32_t img_type = (uint32_t)msg->friend_avatar().img().img_type(); + int eAvatarSize = k_EAvatarSizeMAX; + + auto nums = avatars.find(userID.ConvertToUint64()); + if (nums == avatars.end()) { + struct Avatar_Numbers n; + generate_avatar_numbers(n); + n.last_update_time = std::chrono::steady_clock::now(); + avatars[userID.ConvertToUint64()] = n; + nums = avatars.find(userID.ConvertToUint64()); + } + + int num_replace = 0; + if (nums != avatars.end()) { + if (width > 0 && width <= 32 && height > 0 && height <= 32) { + eAvatarSize = k_EAvatarSize32x32; + num_replace = nums->second.smallest; + } else { + if (width > 32 && width <= 64 && height > 32 && height <= 64) { + eAvatarSize = k_EAvatarSize64x64; + num_replace = nums->second.medium; + } else { + if (width > 64 && width <= 184 && height > 64 && height <= 184) { + eAvatarSize = k_EAvatarSize184x184; + num_replace = nums->second.large; + } + } + } + + if (eAvatarSize != k_EAvatarSizeMAX) { + + switch (img_type) { + case Image::RAW: + PRINT_DEBUG("%s %"PRIu64" %s %d %s.\n", + "Steam_Friends::Callback Got Friend_Avatar NOTIFY for", + userID.ConvertToUint64(), + "size", + eAvatarSize, + "image type RAW"); + break; + case Image::JPG: + { + std::string convert; + int n_width = 0; + int n_height = 0; + PRINT_DEBUG("%s %"PRIu64" %s %d %s.\n", + "Steam_Friends::Callback Got Friend_Avatar NOTIFY for", + userID.ConvertToUint64(), + "size", + eAvatarSize, + "image type JPG"); + convert = convert_jpg_buffer_std_string_to_std_string_uint8(raw_image, &n_width, &n_height, NULL, 4); + if (convert.length() > 0 && n_width == width && n_height == height) { + raw_image = convert; + convert.clear(); + } else { + raw_image.clear(); + } + } + break; + case Image::PNG: + { + std::string convert; + int n_width = 0; + int n_height = 0; + PRINT_DEBUG("%s %"PRIu64" %s %d %s.\n", + "Steam_Friends::Callback Got Friend_Avatar NOTIFY for", + userID.ConvertToUint64(), + "size", + eAvatarSize, + "image type PNG"); + convert = convert_png_buffer_std_string_to_std_string_uint8(raw_image, &n_width, &n_height, NULL, 4); + if (convert.length() > 0 && n_width == width && n_height == height) { + raw_image = convert; + convert.clear(); + } else { + raw_image.clear(); + } + } + break; + default: + raw_image.clear(); + PRINT_DEBUG("%s %"PRIu64" %s %d %s %d.\n", + "Steam_Friends::Callback Got Friend_Avatar NOTIFY for", + userID.ConvertToUint64(), + "size", + eAvatarSize, + "with unsupported image type", + img_type); + break; + }; + if (raw_image.length() > 0) { + int ref = settings->replace_image(num_replace, raw_image, width, height); + if (ref != 0) { + nums->second.last_update_time = std::chrono::steady_clock::now(); + + AvatarImageLoaded_t ail_data = {}; + ail_data.m_steamID = userID.ConvertToUint64(); + ail_data.m_iImage = ref; + ail_data.m_iWide = width; + ail_data.m_iTall = height; + callback_results->addCallResult(ail_data.k_iCallback, &ail_data, sizeof(ail_data)); + persona_change(userID, k_EPersonaChangeAvatar); + } + } + } + } + } + } + + if (msg->friend_avatar().img().type() == Image::REQUEST) { + CSteamID requestID((uint64)msg->dest_id()); + if (settings->get_local_steam_id() == requestID) { + PRINT_DEBUG("%s %"PRIu64".\n", "Steam_Friends::Callback Got Friend_Avatar REQUEST from", userID.ConvertToUint64()); + + uint32_t width = (uint32_t)msg->friend_avatar().img().img_width(); + uint32_t height = (uint32_t)msg->friend_avatar().img().img_height(); + uint32_t img_type = (uint32_t)msg->friend_avatar().img().img_type(); + + int eAvatarSize = k_EAvatarSizeMAX; + if (width > 0 && width <= 32 && height > 0 && height <= 32) { + eAvatarSize = k_EAvatarSize32x32; + } else { + if (width > 32 && width <= 64 && height > 32 && height <= 64) { + eAvatarSize = k_EAvatarSize64x64; + } else { + if (width > 64 && width <= 184 && height > 64 && height <= 184) { + eAvatarSize = k_EAvatarSize184x184; + } + } + } + + int ref = GetFriendAvatar(settings->get_local_steam_id(), eAvatarSize); + if (ref != 0) { + + uint32 n_width = 0; + uint32 n_height = 0; + Steam_Utils* steamUtils = get_steam_client()->steam_utils; + if ((steamUtils->GetImageSize(ref, &n_width, &n_height) == true) && + (n_width > 0) && (n_height > 0)) { + uint8 * raw_image = new uint8[(n_width * n_height * sizeof(uint32))]; + if (raw_image != NULL) { + if (steamUtils->GetImageRGBA(ref, + raw_image, + (n_width * n_height * sizeof(uint32))) == true) { + uint32_t img_type = (uint32_t)msg->friend_avatar().img().img_type(); + PRINT_DEBUG("%s %"PRIu64" %s %d %s %d.\n", + "Steam_Friends::Callback Got Friend_Avatar REQUEST from", + userID.ConvertToUint64(), + "for image type", + img_type, + "size", + eAvatarSize); + + std::string pixdata = ""; + if (img_type == Image::PNG) { + pixdata = convert_raw_uint8_to_png_std_string(raw_image, n_width, n_height, 4); + if (pixdata.length() <= 0 || pixdata.length() >= FRIEND_AVATAR_MAX_IMAGE_LENGTH) { + if (pixdata.length() >= FRIEND_AVATAR_MAX_IMAGE_LENGTH) { + PRINT_DEBUG("%s %"PRIu64" %s %d. %s %"PRI_ZU" %s.\n", + "Steam_Friends::Callback Cannot complete Friend_Avatar REQUEST from", + userID.ConvertToUint64(), + "for PNG image size", + eAvatarSize, + "Image is over maximum size by ", + pixdata.length() - FRIEND_AVATAR_MAX_IMAGE_LENGTH, + "bytes"); + } else { + PRINT_DEBUG("%s %"PRIu64" %s %d. %s.\n", + "Steam_Friends::Callback Cannot complete Friend_Avatar REQUEST from", + userID.ConvertToUint64(), + "for PNG image size", + eAvatarSize, + "Could not convert image to requested type"); + } + + // Try again using JPG. + img_type = Image::JPG; + pixdata.clear(); + } + } + + if (img_type == Image::JPG) { + pixdata = convert_raw_uint8_to_jpg_std_string(raw_image, n_width, n_height, 4); + if (pixdata.length() <= 0 || pixdata.length() >= FRIEND_AVATAR_MAX_IMAGE_LENGTH) { + // Try again using RAW. + if (pixdata.length() >= FRIEND_AVATAR_MAX_IMAGE_LENGTH) { + PRINT_DEBUG("%s %"PRIu64" %s %d. %s %"PRI_ZU" %s.\n", + "Steam_Friends::Callback Cannot complete Friend_Avatar REQUEST from", + userID.ConvertToUint64(), + "for JPG image size", + eAvatarSize, + "Image is over maximum size by ", + pixdata.length() - FRIEND_AVATAR_MAX_IMAGE_LENGTH, + "bytes"); + } else { + PRINT_DEBUG("%s %"PRIu64" %s %d. %s.\n", + "Steam_Friends::Callback Cannot complete Friend_Avatar REQUEST from", + userID.ConvertToUint64(), + "for JPG image size", + eAvatarSize, + "Could not convert image to requested type"); + } + img_type = Image::RAW; + pixdata.clear(); + } + } + + if (img_type == Image::RAW) { + for (size_t x = 0; x < (n_width * n_height * sizeof(uint32)); x++) { + char a = (char)(raw_image[x]); + pixdata += a; + } + if (pixdata.length() <= 0 || pixdata.length() >= FRIEND_AVATAR_MAX_IMAGE_LENGTH) { + // No more attempts. + if (pixdata.length() >= FRIEND_AVATAR_MAX_IMAGE_LENGTH) { + PRINT_DEBUG("%s %"PRIu64" %s %d. %s %"PRI_ZU" %s.\n", + "Steam_Friends::Callback Cannot complete Friend_Avatar REQUEST from", + userID.ConvertToUint64(), + "for RAW image size", + eAvatarSize, + "Image is over maximum size by ", + pixdata.length() - FRIEND_AVATAR_MAX_IMAGE_LENGTH, + "bytes"); + } else { + PRINT_DEBUG("%s %"PRIu64" %s %d. %s.\n", + "Steam_Friends::Callback Cannot complete Friend_Avatar REQUEST from", + userID.ConvertToUint64(), + "for RAW image size", + eAvatarSize, + "Could not convert image to requested type"); + } + pixdata.clear(); + } + } + + if (img_type != Image::PNG && img_type != Image::JPG && img_type != Image::RAW) { + pixdata.clear(); + PRINT_DEBUG("%s %"PRIu64" %s %d %s %d.\n", + "Steam_Friends::Callback Got Friend_Avatar REQUEST from", + userID.ConvertToUint64(), + "for unsupported image type", + img_type, + "size", + eAvatarSize); + } + + if (pixdata.length() > 0 && pixdata.length() < FRIEND_AVATAR_MAX_IMAGE_LENGTH) { + PRINT_DEBUG("Steam_Friends::Callback Sending Friend_Avatar NOTIFY size %d type %d\n", + eAvatarSize, + img_type); + Common_Message msg_; + msg_.set_source_id(settings->get_local_steam_id().ConvertToUint64()); + msg_.set_dest_id(msg->source_id()); + + Image *img = new Image(); + img->set_type(Image::NOTIFY); + img->set_img_type(static_cast(img_type)); + img->set_img_width(n_width); + img->set_img_height(n_height); + img->set_img_data(pixdata); + + Friend_Avatar *friend_avatar = new Friend_Avatar(); + friend_avatar->set_allocated_img(img); + + msg_.set_allocated_friend_avatar(friend_avatar); + network->sendTo(&msg_, true); + } + } + + delete raw_image; + raw_image = NULL; + } + } + } + } + } + } + } +} diff --git a/dll/steam_friends.h b/dll/steam_friends.h index 7bce28e..f0b6970 100644 --- a/dll/steam_friends.h +++ b/dll/steam_friends.h @@ -27,6 +27,7 @@ struct Avatar_Numbers { int smallest; int medium; int large; + std::chrono::steady_clock::time_point last_update_time; }; class Steam_Friends : @@ -94,39 +95,33 @@ bool isAppIdCompatible(Friend *f) return settings->get_local_game_id().AppID() == f->appid(); } +void generate_avatar_numbers(struct Avatar_Numbers & nums) { + std::string small_avatar(32 * 32 * 4, 0); + std::string medium_avatar(64 * 64 * 4, 0); + std::string large_avatar(184 * 184 * 4, 0); + + nums.smallest = settings->add_image(small_avatar, 32, 32); + nums.medium = settings->add_image(medium_avatar, 64, 64); + nums.large = settings->add_image(large_avatar, 184, 184); + return; +} + 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); 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) { + if (avatar_numbers.smallest != 0 && + avatar_numbers.medium != 0 && + avatar_numbers.large != 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()) { @@ -138,24 +133,77 @@ struct Avatar_Numbers add_friend_avatars(CSteamID id) } } } else { - //TODO: get real image data from other peers - if (avatar_ids != avatars.end()) { - //TODO: Check for updated entry. return avatar_ids->second; + } else { + // Request avatar data. + PRINT_DEBUG("Steam_Friends::add_friend_avatars sending Friend_Avatar small request for %"PRIu64".\n", steam_id); + Common_Message * msg_ = new Common_Message(); + msg_->set_source_id(settings->get_local_steam_id().ConvertToUint64()); + msg_->set_dest_id(steam_id); + + Image *img = new Image(); + img->set_type(Image::REQUEST); + img->set_img_type(static_cast(settings->get_preferred_network_image_type())); + img->set_img_width(32); + img->set_img_height(32); + img->set_img_data(""); + + Friend_Avatar *friend_avatar = new Friend_Avatar(); + friend_avatar->set_allocated_img(img); + + msg_->set_allocated_friend_avatar(friend_avatar); + network->sendTo(msg_, true); + + PRINT_DEBUG("Steam_Friends::add_friend_avatars sending Friend_Avatar medium request for %"PRIu64".\n", steam_id); + msg_ = new Common_Message(); + msg_->set_source_id(settings->get_local_steam_id().ConvertToUint64()); + msg_->set_dest_id(steam_id); + + img = new Image(); + img->set_type(Image::REQUEST); + img->set_img_type(static_cast(settings->get_preferred_network_image_type())); + img->set_img_width(64); + img->set_img_height(64); + img->set_img_data(""); + + friend_avatar = new Friend_Avatar(); + friend_avatar->set_allocated_img(img); + + msg_->set_allocated_friend_avatar(friend_avatar); + network->sendTo(msg_, true); + + PRINT_DEBUG("Steam_Friends::add_friend_avatars sending Friend_Avatar large request for %"PRIu64".\n", steam_id); + msg_ = new Common_Message(); + msg_->set_source_id(settings->get_local_steam_id().ConvertToUint64()); + msg_->set_dest_id(steam_id); + + img = new Image(); + img->set_type(Image::REQUEST); + img->set_img_type(static_cast(settings->get_preferred_network_image_type())); + img->set_img_width(184); + img->set_img_height(184); + img->set_img_data(""); + + friend_avatar = new Friend_Avatar(); + friend_avatar->set_allocated_img(img); + + msg_->set_allocated_friend_avatar(friend_avatar); + network->sendTo(msg_, true); } } + PRINT_DEBUG("%s %s %s %"PRIu64".\n", + "Steam_Friends::add_friend_avatars ", + (generate == true) ? "Generating empty" : "Notifying changed", + "avatar image for", + steam_id); 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); + generate_avatar_numbers(avatar_numbers); } + avatar_numbers.last_update_time = std::chrono::steady_clock::now(); + avatars[steam_id] = avatar_numbers; // Generate callbacks. @@ -254,6 +302,7 @@ Steam_Friends(Settings* settings, Networking* network, SteamCallResults* callbac overlay(overlay) { this->network->setCallback(CALLBACK_ID_FRIEND, settings->get_local_steam_id(), &Steam_Friends::steam_friends_callback, this); + this->network->setCallback(CALLBACK_ID_FRIEND_AVATAR, settings->get_local_steam_id(), &Steam_Friends::steam_friends_callback, this); this->network->setCallback(CALLBACK_ID_FRIEND_MESSAGES, settings->get_local_steam_id(), &Steam_Friends::steam_friends_callback, this); this->network->setCallback(CALLBACK_ID_USER_STATUS, settings->get_local_steam_id(), &Steam_Friends::steam_friends_callback, this); this->run_every_runcb->add(&Steam_Friends::steam_friends_run_every_runcb, this); @@ -264,6 +313,20 @@ Steam_Friends(Settings* settings, Networking* network, SteamCallResults* callbac { //TODO rm network callbacks this->run_every_runcb->remove(&Steam_Friends::steam_friends_run_every_runcb, this); + + for (auto x : avatars) { + if (x.first != settings->get_local_steam_id().ConvertToUint64()) { + if (x.second.smallest != 0) { + settings->remove_image(x.second.smallest); + } + if (x.second.medium != 0) { + settings->remove_image(x.second.medium); + } + if (x.second.large != 0) { + settings->remove_image(x.second.large); + } + } + } } static bool ok_friend_flags(int iFriendFlags) @@ -704,7 +767,7 @@ int GetSmallFriendAvatar( CSteamID steamIDFriend ) //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); + PRINT_DEBUG("Steam_Friends::GetSmallFriendAvatar %"PRIu64" -> %d.\n", steamIDFriend.ConvertToUint64(), numbers.smallest); return numbers.smallest; } @@ -714,7 +777,7 @@ int GetMediumFriendAvatar( CSteamID steamIDFriend ) { 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); + PRINT_DEBUG("Steam_Friends::GetMediumFriendAvatar %"PRIu64" -> %d.\n", steamIDFriend.ConvertToUint64(), numbers.medium); return numbers.medium; } @@ -725,7 +788,7 @@ int GetLargeFriendAvatar( CSteamID steamIDFriend ) { 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); + PRINT_DEBUG("Steam_Friends::GetLargeFriendAvatar %"PRIu64" -> %d.\n", steamIDFriend.ConvertToUint64(), numbers.large); return numbers.large; } @@ -1184,105 +1247,7 @@ void RunCallbacks() } } -void Callback(Common_Message *msg) -{ - if (msg->has_low_level()) { - if (msg->low_level().type() == Low_Level::DISCONNECT) { - PRINT_DEBUG("Steam_Friends Disconnect\n"); - uint64 id = msg->source_id(); - auto f = std::find_if(friends.begin(), friends.end(), [&id](Friend const& item) { return item.id() == id; }); - if (friends.end() != f) { - persona_change((uint64)f->id(), k_EPersonaChangeStatus); - overlay->FriendDisconnect(*f); - friends.erase(f); - } - } - - if (msg->low_level().type() == Low_Level::CONNECT) { - PRINT_DEBUG("Steam_Friends Connect\n"); - Common_Message msg_; - msg_.set_source_id(settings->get_local_steam_id().ConvertToUint64()); - msg_.set_dest_id(msg->source_id()); - Friend *f = new Friend(us); - f->set_id(settings->get_local_steam_id().ConvertToUint64()); - f->set_name(settings->get_local_name()); - f->set_appid(settings->get_local_game_id().AppID()); - f->set_lobby_id(settings->get_lobby().ConvertToUint64()); - msg_.set_allocated_friend_(f); - network->sendTo(&msg_, true); - } - } - - if (msg->has_friend_()) { - PRINT_DEBUG("Steam_Friends Friend %llu %llu\n", msg->friend_().id(), msg->friend_().lobby_id()); - Friend *f = find_friend((uint64)msg->friend_().id()); - if (!f) { - if (msg->friend_().id() != settings->get_local_steam_id().ConvertToUint64()) { - friends.push_back(msg->friend_()); - overlay->FriendConnect(msg->friend_()); - persona_change((uint64)msg->friend_().id(), k_EPersonaChangeName); - } - } else { - std::map map1(f->rich_presence().begin(), f->rich_presence().end()); - std::map map2(msg->friend_().rich_presence().begin(), msg->friend_().rich_presence().end()); - - if (map1 != map2) { - //The App ID of the game. This should always be the current game. - if (isAppIdCompatible(f)) { - rich_presence_updated((uint64)msg->friend_().id(), (uint64)msg->friend_().appid()); - } - } - //TODO: callbacks? - *f = msg->friend_(); - } - } - - if (msg->has_friend_messages()) { - if (msg->friend_messages().type() == Friend_Messages::LOBBY_INVITE) { - PRINT_DEBUG("Steam_Friends Got Lobby Invite\n"); - Friend *f = find_friend((uint64)msg->source_id()); - if (f) { - LobbyInvite_t data; - data.m_ulSteamIDUser = msg->source_id(); - data.m_ulSteamIDLobby = msg->friend_messages().lobby_id(); - data.m_ulGameID = f->appid(); - callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); - - if (overlay->Ready()) - { - //TODO: the user should accept the invite first but we auto accept it because there's no gui yet - // Then we will handle it ! - overlay->SetLobbyInvite(*find_friend(static_cast(msg->source_id())), msg->friend_messages().lobby_id()); - } - else - { - GameLobbyJoinRequested_t data; - data.m_steamIDLobby = CSteamID((uint64)msg->friend_messages().lobby_id()); - data.m_steamIDFriend = CSteamID((uint64)msg->source_id()); - callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); - } - } - } - - if (msg->friend_messages().type() == Friend_Messages::GAME_INVITE) { - PRINT_DEBUG("Steam_Friends Got Game Invite\n"); - //TODO: I'm pretty sure that the user should accept the invite before this is posted but we do like above - if (overlay->Ready()) - { - // Then we will handle it ! - overlay->SetRichInvite(*find_friend(static_cast(msg->source_id())), msg->friend_messages().connect_str().c_str()); - } - else - { - std::string const& connect_str = msg->friend_messages().connect_str(); - GameRichPresenceJoinRequested_t data = {}; - data.m_steamIDFriend = CSteamID((uint64)msg->source_id()); - strncpy(data.m_rgchConnect, connect_str.c_str(), k_cchMaxRichPresenceValueLength - 1); - callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); - } - } - } -} +void Callback(Common_Message *msg); };