[Friends] Steam avatars

This commit is contained in:
momo5502 2017-06-05 00:00:46 +02:00
parent 171cdcf0fd
commit 6f7ebb43b1
6 changed files with 178 additions and 0 deletions

View File

@ -554,6 +554,13 @@ namespace Components
Command::Execute("openmenu popup_friends", true);
}, HOOK_JUMP).install()->quick();
// Avatar callback
// Steam::Proxy::RegisterCallback(333, [](void* data)
// {
// MessageBoxA(0, 0, 0, 0);
//
// });
// Callback to update user information
Steam::Proxy::RegisterCallback(336, [](void* data)
{
@ -687,6 +694,64 @@ namespace Components
Friends::UpdateFriends();
});
Command::Add("testavatar", [](Command::Params*)
{
std::lock_guard<std::recursive_mutex> _(Friends::Mutex);
for(auto user : Friends::FriendsList)
{
Logger::Print("Fetching %s...\n", user.name.data());
int index = Steam::Proxy::SteamFriends->GetSmallFriendAvatar(user.userId);
if (!Steam::Proxy::SteamUtils) return;
static Game::GfxImage image = { nullptr };
if (image.map) Game::Image_Release(&image);
static Game::Material* material = nullptr;
unsigned int width, height;
Steam::Proxy::SteamUtils->GetImageSize(index, &width, &height);
Game::Image_Setup(&image, static_cast<short>(width), static_cast<short>(height), 1, 0x1000003, D3DFMT_A8R8G8B8);
D3DLOCKED_RECT lockedRect;
image.map->LockRect(0, &lockedRect, nullptr, 0);
unsigned char* buffer = static_cast<unsigned char*>(lockedRect.pBits);
Steam::Proxy::SteamUtils->GetImageRGBA(index, buffer, width * height * 4);
for (unsigned int i = 0; i < width * height * 4; i += 4)
{
unsigned char r = buffer[i + 0];
unsigned char g = buffer[i + 1];
unsigned char b = buffer[i + 2];
unsigned char a = buffer[i + 3];
buffer[i + 0] = a;
buffer[i + 1] = r;
buffer[i + 2] = g;
buffer[i + 3] = b;
}
image.map->UnlockRect(0);
if (!material)
{
material = Materials::Create("avatar", &image);
Scheduler::OnFrame([]()
{
float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
Game::CL_DrawStretchPicPhysical(10.0f, 10.0f, 100.0f, 100.0f, 0, 0, 1.0f, 1.0f, color, material);
});
}
break;
}
});
}
Friends::~Friends()
@ -695,6 +760,7 @@ namespace Components
Friends::StoreFriendsList();
//Steam::Proxy::UnregisterCallback(333);
Steam::Proxy::UnregisterCallback(336);
Steam::Proxy::UnregisterCallback(304);

View File

@ -32,6 +32,14 @@ namespace Components
};
#pragma pack(pop)
struct AvatarImageLoaded
{
SteamID m_steamID; // steamid the avatar has been loaded for
int m_iImage; // the image index of the now loaded image
int m_iWide; // width of the loaded image
int m_iTall; // height of the loaded image
};
struct PersonaStateChange
{
SteamID m_ulSteamID; // steamID of the friend who changed

View File

@ -5,6 +5,75 @@ namespace Components
int Materials::ImageNameLength;
Utils::Hook Materials::ImageVersionCheckHook;
std::vector<Game::Material*> Materials::MaterialTable;
Game::Material* Materials::Create(std::string name, Game::GfxImage* image)
{
Game::Material* material = Utils::Memory::GetAllocator()->allocate<Game::Material>();
Game::MaterialTextureDef* texture = Utils::Memory::GetAllocator()->allocate<Game::MaterialTextureDef>();
material->textureCount = 1;
material->textureTable = texture;
material->name = Utils::Memory::GetAllocator()->duplicateString(name);
material->sortKey = 0x22;
material->textureAtlasColumnCount = 1;
material->textureAtlasRowCount = 1;
for(int i = 0; i < 48; ++i)
{
if(i != 4) material->stateBitsEntry[i] = -1;
}
material->stateFlags = 3;
material->cameraRegion = 4;
material->techniqueSet = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_TECHNIQUE_SET, "2d").techniqueSet;
material->textureTable->nameHash = Game::R_HashString("colorMap");
material->textureTable->nameStart = 'c';
material->textureTable->nameEnd = 'p';
material->textureTable->sampleState = -30;
material->textureTable->info.image = image;
Game::Material* cursor = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_MATERIAL, "ui_cursor").material;
if(cursor)
{
material->stateBitTable = cursor->stateBitTable;
material->stateBitsCount = cursor->stateBitsCount;
}
Materials::MaterialTable.push_back(material);
return material;
}
void Materials::Delete(Game::Material* material)
{
if (!material) return;
auto mat = std::find(Materials::MaterialTable.begin(), Materials::MaterialTable.end(), material);
if(mat != Materials::MaterialTable.end())
{
Materials::MaterialTable.erase(mat);
}
Utils::Memory::GetAllocator()->free(material->textureTable);
Utils::Memory::GetAllocator()->free(material->name);
Utils::Memory::GetAllocator()->free(material);
}
void Materials::DeleteAll()
{
std::vector<Game::Material*> materials;
Utils::Merge(&materials, Materials::MaterialTable);
Materials::MaterialTable.clear();
for(auto& material : materials)
{
Materials::Delete(material);
}
}
__declspec(naked) void Materials::ImageVersionCheck()
{
__asm
@ -198,6 +267,8 @@ namespace Components
Materials::~Materials()
{
Materials::DeleteAll();
Materials::ImageVersionCheckHook.uninstall();
}
}

View File

@ -10,7 +10,11 @@ namespace Components
static int FormatImagePath(char* buffer, size_t size, int, int, const char* image);
static Game::Material* Create(std::string name, Game::GfxImage* image);
static void Delete(Game::Material* material);
private:
static std::vector<Game::Material*> MaterialTable;
static int ImageNameLength;
static Utils::Hook ImageVersionCheckHook;
@ -29,5 +33,7 @@ namespace Components
#endif
static int MaterialComparePrint(Game::Material* m1, Game::Material* m2);
static void DeleteAll();
};
}

View File

@ -870,6 +870,31 @@ namespace Game
return atoi(StringTable_Lookup(rankTable, 0, maxrank, 7));
}
__declspec(naked) void Image_Setup(GfxImage* /*image*/, unsigned int /*width*/, unsigned int /*height*/, unsigned int /*depth*/, unsigned int /*flags*/, int /*format*/)
{
__asm
{
pushad
xor edi, edi
mov eax, [esp + 24h] // image
mov di, word ptr [esp + 28h] // width
push [esp + 38h] // format
push [esp + 38h] // flags
push 0
push [esp + 3Ch] // depth
push [esp + 3Ch] // height
mov ecx, 54AF50h
call ecx
add esp, 14h
popad
retn
}
}
void SortWorldSurfaces(GfxWorld* world)
{
DWORD* specular1 = reinterpret_cast<DWORD*>(0x69F105C);

View File

@ -845,6 +845,8 @@ namespace Game
int CL_GetMaxXP();
void Image_Setup(GfxImage* image, unsigned int width, unsigned int height, unsigned int depth, unsigned int flags, int format);
void SortWorldSurfaces(GfxWorld* world);
void R_AddDebugLine(float* color, float* v1, float* v2);
void R_AddDebugString(float *color, float *pos, float scale, const char *str);