mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-07-09 17:25:37 -06:00
ShadNet:Presence support (#4649)
* added serial and title to shadnet login for reporting for presense support * more presensce support * more presnse * live appear online * added appear offline setting * clang..
This commit is contained in:
parent
dacd29077a
commit
1d5447b74c
@ -174,6 +174,9 @@ bool NpHandler::ConnectUser(s32 user_id, const std::string& host, u16 port, cons
|
||||
OnLoginResult(user_id, res);
|
||||
};
|
||||
|
||||
// Seed the current Appear-Offline preference so the login packet carries it (the send
|
||||
// is suppressed pre-auth; it just caches on the client).
|
||||
client->SetAppearOffline(m_appear_offline.load());
|
||||
client->Start(host, port, npid, password, token);
|
||||
|
||||
const ShadNet::ShadNetState conn_state = client->WaitForConnection();
|
||||
@ -210,6 +213,15 @@ bool NpHandler::ConnectUser(s32 user_id, const std::string& host, u16 port, cons
|
||||
return true;
|
||||
}
|
||||
|
||||
void NpHandler::SetAppearOffline(bool enable) {
|
||||
m_appear_offline = enable;
|
||||
std::lock_guard lock(m_mutex_clients);
|
||||
for (auto& [uid, client] : m_clients) {
|
||||
if (client)
|
||||
client->SetAppearOffline(enable); // sends the toggle to connected sessions
|
||||
}
|
||||
}
|
||||
|
||||
void NpHandler::DisconnectUser(s32 user_id) {
|
||||
std::shared_ptr<ShadNet::ShadNetClient> client;
|
||||
{
|
||||
@ -474,6 +486,7 @@ void NpHandler::OnWebApiPushEvent(s32 user_id, const ShadNet::NotifyWebApiPushEv
|
||||
ev.hasTo = true;
|
||||
std::strncpy(ev.toOnlineId.data, n.toNpid.c_str(), sizeof(ev.toOnlineId.data) - 1);
|
||||
}
|
||||
ev.extdData = n.extdData; // extended-data (key,value) pairs -> dispatched as pExtdData
|
||||
NpWebApi::EnqueuePushEvent(ev);
|
||||
}
|
||||
|
||||
|
||||
@ -50,6 +50,13 @@ public:
|
||||
/// True if any user is currently signed in
|
||||
bool IsAnySignedIn() const;
|
||||
|
||||
// Set the Appear-Offline preference for all signed-in users (and future logins). While
|
||||
// enabled, shadNet handles the user as offline for everyone else. Call from the UI/config.
|
||||
void SetAppearOffline(bool enable);
|
||||
bool IsAppearOffline() const {
|
||||
return m_appear_offline.load();
|
||||
}
|
||||
|
||||
/// Full NP ID for this user, built once from shadnet_npid after login.
|
||||
OrbisNpId GetNpId(s32 user_id) const;
|
||||
|
||||
@ -226,6 +233,9 @@ private:
|
||||
// 12-byte NP Communication ID
|
||||
std::string GetNpCommId(s32 service_label) const;
|
||||
|
||||
// Appear-Offline preference, applied to every client at login and on change.
|
||||
std::atomic<bool> m_appear_offline{false};
|
||||
|
||||
// Per-user client map
|
||||
mutable std::mutex m_mutex_clients;
|
||||
std::map<s32, std::shared_ptr<ShadNet::ShadNetClient>> m_clients;
|
||||
|
||||
@ -53,6 +53,13 @@ void DrawFriendsTab() {
|
||||
const s32 user_id = users[g_user_index];
|
||||
const Libraries::Np::NpHandler::FriendListSnapshot fl = np.GetFriendList(user_id);
|
||||
|
||||
bool appear_offline = np.IsAppearOffline();
|
||||
if (ImGui::Checkbox("Appear offline", &appear_offline)) {
|
||||
np.SetAppearOffline(appear_offline);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::TextDisabled("(friends see you as offline)");
|
||||
|
||||
ImGui::SeparatorText("Add friend");
|
||||
ImGui::InputTextWithHint("##addnpid", "Online ID", g_add_buf, sizeof(g_add_buf));
|
||||
ImGui::SameLine();
|
||||
|
||||
@ -194,6 +194,9 @@ void ShadNetClient::ConnectThread() {
|
||||
if (!m_token.empty())
|
||||
req.set_token(m_token);
|
||||
req.set_title_id(std::string(Common::ElfInfo::Instance().GameSerial()));
|
||||
req.set_title_name(std::string(Common::ElfInfo::Instance().Title()));
|
||||
// Appear-Offline preference. shadNet handles us as offline for everyone else while set.
|
||||
req.set_appear_offline(m_appear_offline);
|
||||
|
||||
const u64 id = m_pkt_counter.fetch_add(1);
|
||||
if (!SendAll(BuildPacket(CommandType::Login, id, MakeProtoPayload(req)))) {
|
||||
@ -506,6 +509,15 @@ u64 ShadNetClient::RemoveBlock(const std::string& npid) {
|
||||
return SubmitRequest(CommandType::RemoveBlock, MakeProtoPayload(req));
|
||||
}
|
||||
|
||||
u64 ShadNetClient::SetAppearOffline(bool enable) {
|
||||
m_appear_offline = enable; // cache so the (re)login packet carries the current state
|
||||
if (!IsAuthenticated())
|
||||
return 0; // not connected yet -> login will carry the cached value
|
||||
shadnet::SetAppearOfflineRequest req;
|
||||
req.set_appear_offline(enable);
|
||||
return SubmitRequest(CommandType::SetAppearOffline, MakeProtoPayload(req));
|
||||
}
|
||||
|
||||
// Packet dispatch
|
||||
|
||||
void ShadNetClient::DispatchPacket(PacketType type, u16 cmd_raw, u64 pkt_id,
|
||||
@ -794,8 +806,28 @@ void ShadNetClient::HandleNotification(u16 cmd_raw, const std::vector<u8>& paylo
|
||||
n.fromNpid = ExtractBlob(payload, off);
|
||||
off += 4 + static_cast<int>(n.fromNpid.size());
|
||||
n.toNpid = ExtractBlob(payload, off);
|
||||
LOG_INFO(ShadNet, "WebApiPushEvent svc='{}' type='{}' from='{}' bytes={}", n.npServiceName,
|
||||
n.dataType, n.fromNpid, n.data.size());
|
||||
off += 4 + static_cast<int>(n.toNpid.size());
|
||||
// Optional extended-data section appended after toNpid: u32 LE count, then
|
||||
// (blob key, blob value) per pair. Absent on older servers -> no bytes left ->
|
||||
// zero pairs. Length-guarded throughout; count capped to avoid runaway on a
|
||||
// malformed packet.
|
||||
if (off + 4 <= static_cast<int>(payload.size())) {
|
||||
const u32 count = GetLE32(payload.data() + off);
|
||||
off += 4;
|
||||
for (u32 i = 0; i < count && i < 256; ++i) {
|
||||
if (off + 4 > static_cast<int>(payload.size()))
|
||||
break;
|
||||
std::string key = ExtractBlob(payload, off);
|
||||
off += 4 + static_cast<int>(key.size());
|
||||
if (off + 4 > static_cast<int>(payload.size()))
|
||||
break;
|
||||
std::string val = ExtractBlob(payload, off);
|
||||
off += 4 + static_cast<int>(val.size());
|
||||
n.extdData.emplace_back(std::move(key), std::move(val));
|
||||
}
|
||||
}
|
||||
LOG_INFO(ShadNet, "WebApiPushEvent svc='{}' type='{}' from='{}' bytes={} extd={}",
|
||||
n.npServiceName, n.dataType, n.fromNpid, n.data.size(), n.extdData.size());
|
||||
if (onWebApiPushEvent)
|
||||
onWebApiPushEvent(n);
|
||||
break;
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include <semaphore>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "common/types.h"
|
||||
#ifdef _WIN32
|
||||
@ -88,6 +89,7 @@ enum class CommandType : u16 {
|
||||
GetScoreAccountId = 37,
|
||||
GetScoreGameDataByAccId = 38,
|
||||
GetToken = 39,
|
||||
SetAppearOffline = 40,
|
||||
};
|
||||
|
||||
enum class NotificationType : u16 {
|
||||
@ -190,6 +192,9 @@ struct NotifyWebApiPushEvent {
|
||||
std::string data; // raw event body (typically PSN-format JSON)
|
||||
std::string fromNpid; // may be empty
|
||||
std::string toNpid; // may be empty
|
||||
// Optional extended-data (key,value) pairs (e.g. friendlist trigger/additionalTrigger,
|
||||
// presence gameStatus/gameData). Empty when the server sends none / is older.
|
||||
std::vector<std::pair<std::string, std::string>> extdData;
|
||||
};
|
||||
|
||||
struct MatchingBinAttr {
|
||||
@ -275,6 +280,8 @@ public:
|
||||
u64 RemoveFriend(const std::string& npid);
|
||||
u64 AddBlock(const std::string& npid);
|
||||
u64 RemoveBlock(const std::string& npid);
|
||||
// Set the Appear-Offline preference mid-session (server handles us as offline while set).
|
||||
u64 SetAppearOffline(bool enable);
|
||||
|
||||
private:
|
||||
void ConnectThread();
|
||||
@ -306,6 +313,7 @@ private:
|
||||
std::string m_npid;
|
||||
std::string m_password;
|
||||
std::string m_token;
|
||||
bool m_appear_offline = false; // user's Appear-Offline preference (sent at login)
|
||||
|
||||
std::atomic<bool> m_terminate{false};
|
||||
std::atomic<bool> m_connected{false};
|
||||
|
||||
@ -11,10 +11,17 @@ option optimize_for = LITE_RUNTIME;
|
||||
// Account
|
||||
|
||||
message LoginRequest {
|
||||
string npid = 1;
|
||||
string password = 2;
|
||||
string token = 3;
|
||||
string title_id = 4;
|
||||
string npid = 1;
|
||||
string password = 2;
|
||||
string token = 3;
|
||||
string title_id = 4;
|
||||
string title_name = 5;
|
||||
bool appear_offline = 6; // user's Appear-Offline preference
|
||||
}
|
||||
|
||||
// Mid-session Appear-Offline toggle.
|
||||
message SetAppearOfflineRequest {
|
||||
bool appear_offline = 1;
|
||||
}
|
||||
|
||||
message FriendEntry {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user