[Friends] Transmit rank

This commit is contained in:
momo5502 2017-01-29 15:10:54 +01:00
parent 67d963a0c8
commit 7d24aa8fe0
9 changed files with 107 additions and 6 deletions

View File

@ -23,6 +23,34 @@ namespace Components
IPCHandler::SendWorker("friends", function.SerializeAsString());
}
void Friends::UpdateState()
{
Proto::IPC::Function function;
function.set_name("notifyChange");
IPCHandler::SendWorker("friends", function.SerializeAsString());
}
void Friends::UpdateRank()
{
static Utils::Value<int> levelVal;
int experience = Game::Live_GetXp(0);
int prestige = Game::Live_GetPrestige(0);
int level = (experience & 0xFFFFFF) | ((prestige & 0xFF) << 24);
if(!levelVal.isValid() || levelVal.get() != level)
{
levelVal.set(level);
Proto::IPC::Function function;
function.set_name("setPresence");
*function.add_params() = "iw4x_rank";
*function.add_params() = std::string(reinterpret_cast<char*>(&level), 4);
IPCHandler::SendWorker("friends", function.SerializeAsString());
}
}
void Friends::UpdateFriends()
{
Proto::IPC::Function function;
@ -55,6 +83,7 @@ namespace Components
Game::Material* rankIcon = nullptr;
int rank = Game::CL_GetRankForXP(user.experience);
Game::CL_GetRankIcon(rank, user.prestige, &rankIcon);
if (!rankIcon) rankIcon = Game::DB_FindXAssetDefaultHeaderInternal(Game::XAssetType::ASSET_TYPE_MATERIAL).material;
buffer[0] = '^';
buffer[1] = 2;
@ -68,7 +97,7 @@ namespace Components
buffer[4] = static_cast<char>(strlen(rankIcon->name));
strcat_s(buffer, rankIcon->name);
strcat_s(buffer, Utils::String::VA(" %i", rank));
strcat_s(buffer, Utils::String::VA(" %i", (rank + 1)));
return buffer;
}
@ -139,7 +168,6 @@ namespace Components
{
entry->server = value;
// TODO: Query server here?
if (entry->server.getType() != Game::NA_BAD)
{
Node::AddNode(entry->server);
@ -268,6 +296,14 @@ namespace Components
Friends::UpdateFriends();
});
QuickPatch::OnFrame([]()
{
if(*reinterpret_cast<bool*>(0x1AD5690)) // LiveStorage_DoWeHaveStats
{
Friends::UpdateRank();
}
});
UIFeeder::Add(6.0f, Friends::GetFriendCount, Friends::GetFriendText, Friends::SelectFriend);
fInterface = IPCHandler::NewInterface("friends");

View File

@ -13,6 +13,7 @@ namespace Components
#endif
static void UpdateFriends();
static void UpdateRank();
private:
#pragma pack(push, 4)
@ -46,6 +47,7 @@ namespace Components
static std::vector<Friend> FriendsList;
static void UpdateUserInfo(SteamID user);
static void UpdateState();
static unsigned int GetFriendCount();
static const char* GetFriendText(unsigned int index, int column);

View File

@ -164,6 +164,8 @@ namespace Game
Live_MPAcceptInvite_t Live_MPAcceptInvite = Live_MPAcceptInvite_t(0x420A6D);
Live_GetMapIndex_t Live_GetMapIndex = Live_GetMapIndex_t(0x4F6440);
Live_GetPrestige_t Live_GetPrestige = Live_GetPrestige_t(0x430F90);
Live_GetXp_t Live_GetXp = Live_GetXp_t(0x404C60);
LoadModdableRawfile_t LoadModdableRawfile = LoadModdableRawfile_t(0x61ABC0);
@ -461,6 +463,24 @@ namespace Game
return false;
}
XAssetHeader DB_FindXAssetDefaultHeaderInternal(XAssetType _type)
{
// ReSharper disable once CppEntityNeverUsed
static int func = 0x5BB210;
XAssetHeader result;
__asm
{
push edi
mov edi, _type
call func
pop edi
mov result, eax
}
return result;
}
void FS_AddLocalizedGameDirectory(const char *path, const char *dir)
{
__asm

View File

@ -412,6 +412,12 @@ namespace Game
typedef int(__cdecl * Live_GetMapIndex_t)(const char* mapname);
extern Live_GetMapIndex_t Live_GetMapIndex;
typedef int(__cdecl * Live_GetPrestige_t)(int controllerIndex);
extern Live_GetPrestige_t Live_GetPrestige;
typedef int(__cdecl * Live_GetXp_t)(int controllerIndex);
extern Live_GetXp_t Live_GetXp;
typedef char* (__cdecl * LoadModdableRawfile_t)(int a1, const char* filename);
extern LoadModdableRawfile_t LoadModdableRawfile;
@ -697,6 +703,7 @@ namespace Game
const char *DB_GetXAssetName(XAsset *asset);
XAssetType DB_GetXAssetNameType(const char* name);
bool DB_IsZoneLoaded(const char* zone);
XAssetHeader DB_FindXAssetDefaultHeaderInternal(XAssetType type);
void FS_AddLocalizedGameDirectory(const char *path, const char *dir);

View File

@ -105,4 +105,14 @@ namespace Steam
virtual uint64_t IsFollowing(SteamID steamID) = 0;
virtual uint64_t EnumerateFollowingList(uint32_t unStartIndex) = 0;
};
class Friends2
{
public:
virtual const char *GetPersonaName() = 0;
virtual void SetPersonaName(const char *pchPersonaName) = 0;
virtual int GetPersonaState() = 0;
virtual void SetPersonaState(int ePersonaState) = 0;
// [...]
};
}

View File

@ -13,6 +13,7 @@ namespace Steam
void* Proxy::SteamUser = nullptr;
Friends15* Proxy::SteamFriends = nullptr;
Friends2* Proxy::SteamLegacyFriends = nullptr;
Utils* Proxy::SteamUtils = nullptr;
uint32_t Proxy::AppId = 0;
@ -208,6 +209,9 @@ namespace Steam
Proxy::SteamFriends = reinterpret_cast<Friends15*>(Proxy::SteamClient->GetISteamFriends(Proxy::SteamUser, Proxy::SteamPipe, "SteamFriends015"));
if (!Proxy::SteamFriends) return false;
Proxy::SteamLegacyFriends = reinterpret_cast<Friends2*>(Proxy::SteamClient->GetISteamFriends(Proxy::SteamUser, Proxy::SteamPipe, "SteamFriends002"));
if (!Proxy::SteamLegacyFriends) return false;
Proxy::SteamUtils = reinterpret_cast<Utils*>(Proxy::SteamClient->GetISteamFriends(Proxy::SteamUser, Proxy::SteamPipe, "SteamUtils005"));
if (!Proxy::SteamUtils) return false;

View File

@ -353,6 +353,7 @@ namespace Steam
static void UnregisterCallback(int32_t callId);
static Friends15* SteamFriends;
static Friends2* SteamLegacyFriends;
static Utils* SteamUtils;
private:

View File

@ -110,6 +110,13 @@ namespace Handlers
}
}
void Friends::notifyChange(Worker::Endpoint /*endpoint*/, std::vector<std::string> params)
{
// Ugly, but for now it works
int state = Steam::Proxy::SteamLegacyFriends->GetPersonaState();
Steam::Proxy::SteamLegacyFriends->SetPersonaState((state == 1 ? 2 : 1));
}
void Friends::getInfo(Worker::Endpoint endpoint, std::vector<std::string> params)
{
if (params.size() >= 1 && Steam::Proxy::SteamFriends)
@ -134,14 +141,14 @@ namespace Handlers
{
*response.add_params() = Utils::String::VA("%d", Steam::Proxy::SteamFriends->GetFriendPersonaState(id));
}
else if (key == "iw4x_rank") // This is just a test
/*else if (key == "iw4x_rank") // This is just a test
{
int experience = Utils::Cryptography::Rand::GenerateInt() % (2516000 + 1);
int prestige = Utils::Cryptography::Rand::GenerateInt() % (10 + 1);
int data = (experience & 0xFFFFFF) | ((prestige << 24) & 0xFF);
int data = (experience & 0xFFFFFF) | ((prestige & 0xFF) << 24);
*response.add_params() = std::string(reinterpret_cast<char*>(&data), 4);
}
}*/
else
{
*response.add_params() = Steam::Proxy::SteamFriends->GetFriendRichPresence(id, key.data());
@ -152,7 +159,7 @@ namespace Handlers
}
}
Friends::Friends()
Friends::Friends() : personaState(1)
{
using namespace std::placeholders;
this->addFunction("getFriends", std::bind(&Friends::getFriends, this, _1, _2));
@ -161,6 +168,12 @@ namespace Handlers
this->addFunction("getPresence", std::bind(&Friends::getPresence, this, _1, _2));
this->addFunction("requestPresence", std::bind(&Friends::requestPresence, this, _1, _2));
this->addFunction("getInfo", std::bind(&Friends::getInfo, this, _1, _2));
this->addFunction("notifyChange", std::bind(&Friends::notifyChange, this, _1, _2));
if (Steam::Proxy::SteamLegacyFriends)
{
this->personaState = Steam::Proxy::SteamLegacyFriends->GetPersonaState();
}
}
Friends::~Friends()
@ -169,5 +182,10 @@ namespace Handlers
{
Steam::Proxy::SteamFriends->ClearRichPresence();
}
if(Steam::Proxy::SteamLegacyFriends)
{
Steam::Proxy::SteamLegacyFriends->SetPersonaState(this->personaState);
}
}
}

View File

@ -14,6 +14,8 @@ namespace Handlers
void handle(Worker::Endpoint endpoint, std::string data) override;
private:
int personaState;
std::unordered_map<std::string, Callback> functions;
void addFunction(std::string function, Callback callback);
@ -23,5 +25,6 @@ namespace Handlers
void getPresence(Worker::Endpoint endpoint, std::vector<std::string> params);
void requestPresence(Worker::Endpoint endpoint, std::vector<std::string> params);
void getInfo(Worker::Endpoint endpoint, std::vector<std::string> params);
void notifyChange(Worker::Endpoint /*endpoint*/, std::vector<std::string> params);
};
}