[Friends] Display friends in blue
This commit is contained in:
parent
41c9ec9d32
commit
3d8a1010c2
@ -5,6 +5,8 @@ namespace Components
|
|||||||
Utils::Signal<Dedicated::Callback> Dedicated::FrameSignal;
|
Utils::Signal<Dedicated::Callback> Dedicated::FrameSignal;
|
||||||
Utils::Signal<Dedicated::Callback> Dedicated::FrameOnceSignal;
|
Utils::Signal<Dedicated::Callback> Dedicated::FrameOnceSignal;
|
||||||
|
|
||||||
|
SteamID Dedicated::PlayerGuids[18];
|
||||||
|
|
||||||
bool Dedicated::SendChat;
|
bool Dedicated::SendChat;
|
||||||
|
|
||||||
bool Dedicated::IsEnabled()
|
bool Dedicated::IsEnabled()
|
||||||
@ -129,6 +131,25 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Dedicated::TransmitGuids()
|
||||||
|
{
|
||||||
|
std::string list = Utils::String::VA("%c", 20);
|
||||||
|
|
||||||
|
for (int i = 0; i < 18; i++)
|
||||||
|
{
|
||||||
|
if (Game::svs_clients[i].state >= 3)
|
||||||
|
{
|
||||||
|
list.append(Utils::String::VA(" %llX", Game::svs_clients[i].steamid));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list.append(" 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::SV_GameSendServerCommand(-1, 0, list.data());
|
||||||
|
}
|
||||||
|
|
||||||
void Dedicated::TimeWrapStub(int code, const char* message)
|
void Dedicated::TimeWrapStub(int code, const char* message)
|
||||||
{
|
{
|
||||||
static bool partyEnable;
|
static bool partyEnable;
|
||||||
@ -152,6 +173,48 @@ namespace Components
|
|||||||
Game::Com_Error(code, message);
|
Game::Com_Error(code, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__declspec(naked) void Dedicated::OnServerCommandStub()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
push eax
|
||||||
|
pushad
|
||||||
|
|
||||||
|
call Dedicated::OnServerCommand
|
||||||
|
|
||||||
|
mov [esp + 20h], eax
|
||||||
|
popad
|
||||||
|
pop eax
|
||||||
|
|
||||||
|
test al, al
|
||||||
|
jnz returnSafe
|
||||||
|
|
||||||
|
push 5944AEh
|
||||||
|
retn
|
||||||
|
|
||||||
|
returnSafe:
|
||||||
|
push 594536h
|
||||||
|
retn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Dedicated::OnServerCommand()
|
||||||
|
{
|
||||||
|
Command::ClientParams params;
|
||||||
|
|
||||||
|
if (params.length() > 17 && params.get(0)[0] == 20)
|
||||||
|
{
|
||||||
|
for (int client = 0; client < 18; client++)
|
||||||
|
{
|
||||||
|
Dedicated::PlayerGuids[client].Bits = strtoull(params.get(client + 1), nullptr, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void Dedicated::MapRotate()
|
void Dedicated::MapRotate()
|
||||||
{
|
{
|
||||||
if (!Dedicated::IsEnabled() && Dvar::Var("sv_dontrotate").get<bool>())
|
if (!Dedicated::IsEnabled() && Dvar::Var("sv_dontrotate").get<bool>())
|
||||||
@ -470,6 +533,30 @@ namespace Components
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0; i < ARRAYSIZE(Dedicated::PlayerGuids); ++i)
|
||||||
|
{
|
||||||
|
Dedicated::PlayerGuids[i].Bits = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intercept server commands
|
||||||
|
Utils::Hook(0x59449F, Dedicated::OnServerCommandStub, HOOK_JUMP).install()->quick();
|
||||||
|
}
|
||||||
|
|
||||||
|
QuickPatch::OnFrame([]()
|
||||||
|
{
|
||||||
|
if(Dvar::Var("sv_running").get<bool>())
|
||||||
|
{
|
||||||
|
static Utils::Time::Interval interval;
|
||||||
|
|
||||||
|
if(interval.elapsed(15s))
|
||||||
|
{
|
||||||
|
interval.update();
|
||||||
|
Dedicated::TransmitGuids();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Dedicated::~Dedicated()
|
Dedicated::~Dedicated()
|
||||||
|
@ -14,6 +14,8 @@ namespace Components
|
|||||||
const char* getName() override { return "Dedicated"; };
|
const char* getName() override { return "Dedicated"; };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static SteamID PlayerGuids[18];
|
||||||
|
|
||||||
static bool IsEnabled();
|
static bool IsEnabled();
|
||||||
|
|
||||||
static void Heartbeat();
|
static void Heartbeat();
|
||||||
@ -27,6 +29,9 @@ namespace Components
|
|||||||
|
|
||||||
static bool SendChat;
|
static bool SendChat;
|
||||||
|
|
||||||
|
static void OnServerCommandStub();
|
||||||
|
static int OnServerCommand();
|
||||||
|
|
||||||
static void MapRotate();
|
static void MapRotate();
|
||||||
static void FrameHandler();
|
static void FrameHandler();
|
||||||
static void FrameStub();
|
static void FrameStub();
|
||||||
@ -40,6 +45,8 @@ namespace Components
|
|||||||
static void PreSayStub();
|
static void PreSayStub();
|
||||||
static void PostSayStub();
|
static void PostSayStub();
|
||||||
|
|
||||||
|
static void TransmitGuids();
|
||||||
|
|
||||||
static void TimeWrapStub(int code, const char* message);
|
static void TimeWrapStub(int code, const char* message);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,7 @@ namespace Components
|
|||||||
*function.add_params() = "iw4x_rank";
|
*function.add_params() = "iw4x_rank";
|
||||||
*function.add_params() = "iw4x_server";
|
*function.add_params() = "iw4x_server";
|
||||||
*function.add_params() = "iw4x_playing";
|
*function.add_params() = "iw4x_playing";
|
||||||
|
*function.add_params() = "iw4x_guid";
|
||||||
|
|
||||||
IPCHandler::SendWorker("friends", function.SerializeAsString());
|
IPCHandler::SendWorker("friends", function.SerializeAsString());
|
||||||
}
|
}
|
||||||
@ -107,29 +108,55 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Friends::SetServer()
|
void Friends::ClearPresence(std::string key)
|
||||||
{
|
{
|
||||||
Proto::IPC::Function function;
|
Proto::IPC::Function function;
|
||||||
function.set_name("setPresence");
|
function.set_name("setPresence");
|
||||||
*function.add_params() = "iw4x_server";
|
*function.add_params() = key;
|
||||||
*function.add_params() = Network::Address(*Game::connectedHost).getString();//reinterpret_cast<char*>(0x7ED3F8);
|
|
||||||
|
|
||||||
IPCHandler::SendWorker("friends", function.SerializeAsString());
|
IPCHandler::SendWorker("friends", function.SerializeAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Friends::SetPresence(std::string key, std::string value)
|
||||||
|
{
|
||||||
|
Proto::IPC::Function function;
|
||||||
|
function.set_name("setPresence");
|
||||||
|
*function.add_params() = key;
|
||||||
|
*function.add_params() = value;
|
||||||
|
|
||||||
|
IPCHandler::SendWorker("friends", function.SerializeAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Friends::SetServer()
|
||||||
|
{
|
||||||
|
Friends::SetPresence("iw4x_server", Network::Address(*Game::connectedHost).getString()); // reinterpret_cast<char*>(0x7ED3F8)
|
||||||
Friends::UpdateState();
|
Friends::UpdateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Friends::ClearServer()
|
void Friends::ClearServer()
|
||||||
{
|
{
|
||||||
Proto::IPC::Function function;
|
Friends::ClearPresence("iw4x_server");
|
||||||
function.set_name("setPresence");
|
|
||||||
*function.add_params() = "iw4x_server";
|
|
||||||
|
|
||||||
IPCHandler::SendWorker("friends", function.SerializeAsString());
|
|
||||||
|
|
||||||
Friends::UpdateState();
|
Friends::UpdateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Friends::IsClientInParty(int /*controller*/, int clientNum)
|
||||||
|
{
|
||||||
|
if (clientNum < 0 || clientNum >= ARRAYSIZE(Dedicated::PlayerGuids)) return false;
|
||||||
|
|
||||||
|
std::lock_guard<std::recursive_mutex> _(Friends::Mutex);
|
||||||
|
SteamID guid = Dedicated::PlayerGuids[clientNum];
|
||||||
|
|
||||||
|
for (auto entry : Friends::FriendsList)
|
||||||
|
{
|
||||||
|
if (entry.guid.Bits == guid.Bits && entry.playing && entry.online)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Friends::UpdateRank()
|
void Friends::UpdateRank()
|
||||||
{
|
{
|
||||||
static Utils::Value<int> levelVal;
|
static Utils::Value<int> levelVal;
|
||||||
@ -142,13 +169,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
levelVal.set(level);
|
levelVal.set(level);
|
||||||
|
|
||||||
Proto::IPC::Function function;
|
Friends::SetPresence("iw4x_rank", std::string(reinterpret_cast<char*>(&level), 4));
|
||||||
function.set_name("setPresence");
|
|
||||||
*function.add_params() = "iw4x_rank";
|
|
||||||
*function.add_params() = std::string(reinterpret_cast<char*>(&level), 4);
|
|
||||||
|
|
||||||
IPCHandler::SendWorker("friends", function.SerializeAsString());
|
|
||||||
|
|
||||||
Friends::UpdateState();
|
Friends::UpdateState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -299,6 +320,10 @@ namespace Components
|
|||||||
{
|
{
|
||||||
entry->playing = atoi(value.data()) == 1;
|
entry->playing = atoi(value.data()) == 1;
|
||||||
}
|
}
|
||||||
|
else if(key == "iw4x_guid")
|
||||||
|
{
|
||||||
|
entry->guid.Bits = strtoull(value.data(), nullptr, 16);
|
||||||
|
}
|
||||||
else if (key == "iw4x_server")
|
else if (key == "iw4x_server")
|
||||||
{
|
{
|
||||||
Network::Address oldAddress = entry->server;
|
Network::Address oldAddress = entry->server;
|
||||||
@ -439,6 +464,9 @@ namespace Components
|
|||||||
Utils::Hook(0x403582, Friends::DisconnectStub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x403582, Friends::DisconnectStub, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x4CD023, Friends::SetServer, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x4CD023, Friends::SetServer, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
|
// Show blue icons on the minimap
|
||||||
|
Utils::Hook(0x493130, Friends::IsClientInParty, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
auto fInterface = IPCHandler::NewInterface("steamCallbacks");
|
auto fInterface = IPCHandler::NewInterface("steamCallbacks");
|
||||||
|
|
||||||
// Callback to update user information
|
// Callback to update user information
|
||||||
@ -503,12 +531,8 @@ namespace Components
|
|||||||
fInterface->map("presenceResponse", Friends::PresenceResponse);
|
fInterface->map("presenceResponse", Friends::PresenceResponse);
|
||||||
fInterface->map("infoResponse", Friends::InfoResponse);
|
fInterface->map("infoResponse", Friends::InfoResponse);
|
||||||
|
|
||||||
Proto::IPC::Function function;
|
Friends::SetPresence("iw4x_playing", "1");
|
||||||
function.set_name("setPresence");
|
Friends::SetPresence("iw4x_guid", Utils::String::VA("%llX", Steam::SteamUser()->GetSteamID().Bits));
|
||||||
*function.add_params() = "iw4x_playing";
|
|
||||||
*function.add_params() = "1";
|
|
||||||
|
|
||||||
IPCHandler::SendWorker("friends", function.SerializeAsString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Friends::~Friends()
|
Friends::~Friends()
|
||||||
|
@ -16,6 +16,9 @@ namespace Components
|
|||||||
static void UpdateRank();
|
static void UpdateRank();
|
||||||
static void UpdateHostname(Network::Address server, std::string hostname);
|
static void UpdateHostname(Network::Address server, std::string hostname);
|
||||||
|
|
||||||
|
static void SetPresence(std::string key, std::string value);
|
||||||
|
static void ClearPresence(std::string key);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#pragma pack(push, 4)
|
#pragma pack(push, 4)
|
||||||
struct FriendRichPresenceUpdate
|
struct FriendRichPresenceUpdate
|
||||||
@ -35,6 +38,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SteamID userId;
|
SteamID userId;
|
||||||
|
SteamID guid;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string playerName;
|
std::string playerName;
|
||||||
Network::Address server;
|
Network::Address server;
|
||||||
@ -53,6 +57,8 @@ namespace Components
|
|||||||
static void ClearServer();
|
static void ClearServer();
|
||||||
static void SetServer();
|
static void SetServer();
|
||||||
|
|
||||||
|
static bool IsClientInParty(int controller, int clientNum);
|
||||||
|
|
||||||
static void UpdateUserInfo(SteamID user);
|
static void UpdateUserInfo(SteamID user);
|
||||||
static void UpdateState();
|
static void UpdateState();
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ namespace Components
|
|||||||
void Network::SendCommand(Game::netsrc_t type, Network::Address target, std::string command, std::string data)
|
void Network::SendCommand(Game::netsrc_t type, Network::Address target, std::string command, std::string data)
|
||||||
{
|
{
|
||||||
// Use space as separator (possible separators are '\n', ' ').
|
// Use space as separator (possible separators are '\n', ' ').
|
||||||
// Though, our handler only needs exactly 1 char as separator and doesn't which char it is
|
// Though, our handler only needs exactly 1 char as separator and doesn't care which char it is
|
||||||
std::string packet;
|
std::string packet;
|
||||||
packet.append(command);
|
packet.append(command);
|
||||||
packet.append(" ", 1);
|
packet.append(" ", 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user