mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-12 00:40:14 +00:00
Add player history
This commit is contained in:
parent
c04cd2228e
commit
c589001dff
@ -1814,7 +1814,7 @@ error_code sceNpBasicGetFriendPresenceByNpId2(vm::cptr<SceNpId> npid, vm::ptr<Sc
|
|||||||
return nph.get_friend_presence_by_npid(*npid, pres.get_ptr());
|
return nph.get_friend_presence_by_npid(*npid, pres.get_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpBasicAddPlayersHistory(vm::cptr<SceNpId> npid, vm::ptr<char> description)
|
error_code sceNpBasicAddPlayersHistory(vm::cptr<SceNpId> npid, vm::cptr<char> description)
|
||||||
{
|
{
|
||||||
sceNp.todo("sceNpBasicAddPlayersHistory(npid=*0x%x, description=*0x%x)", npid, description);
|
sceNp.todo("sceNpBasicAddPlayersHistory(npid=*0x%x, description=*0x%x)", npid, description);
|
||||||
|
|
||||||
@ -1835,10 +1835,12 @@ error_code sceNpBasicAddPlayersHistory(vm::cptr<SceNpId> npid, vm::ptr<char> des
|
|||||||
return SCE_NP_BASIC_ERROR_EXCEEDS_MAX;
|
return SCE_NP_BASIC_ERROR_EXCEEDS_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nph.add_player_to_history(npid.get_ptr(), description ? description.get_ptr() : nullptr);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpBasicAddPlayersHistoryAsync(vm::cptr<SceNpId> npids, u32 count, vm::ptr<char> description, vm::ptr<u32> reqId)
|
error_code sceNpBasicAddPlayersHistoryAsync(vm::cptr<SceNpId> npids, u32 count, vm::cptr<char> description, vm::ptr<u32> reqId)
|
||||||
{
|
{
|
||||||
sceNp.todo("sceNpBasicAddPlayersHistoryAsync(npids=*0x%x, count=%d, description=*0x%x, reqId=*0x%x)", npids, count, description, reqId);
|
sceNp.todo("sceNpBasicAddPlayersHistoryAsync(npids=*0x%x, count=%d, description=*0x%x, reqId=*0x%x)", npids, count, description, reqId);
|
||||||
|
|
||||||
@ -1877,7 +1879,7 @@ error_code sceNpBasicAddPlayersHistoryAsync(vm::cptr<SceNpId> npids, u32 count,
|
|||||||
return SCE_NP_BASIC_ERROR_EXCEEDS_MAX;
|
return SCE_NP_BASIC_ERROR_EXCEEDS_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto req_id = nph.add_players_to_history(npids, count);
|
auto req_id = nph.add_players_to_history(npids.get_ptr(), description ? description.get_ptr() : nullptr, count);
|
||||||
|
|
||||||
if (reqId)
|
if (reqId)
|
||||||
{
|
{
|
||||||
@ -1919,8 +1921,7 @@ error_code sceNpBasicGetPlayersHistoryEntryCount(u32 options, vm::ptr<u32> count
|
|||||||
return SCE_NP_ERROR_ID_NOT_FOUND;
|
return SCE_NP_ERROR_ID_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Check if there are players histories
|
*count = nph.get_players_history_count(options);
|
||||||
*count = 0;
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
@ -1958,6 +1959,11 @@ error_code sceNpBasicGetPlayersHistoryEntry(u32 options, u32 index, vm::ptr<SceN
|
|||||||
return SCE_NP_ERROR_ID_NOT_FOUND;
|
return SCE_NP_ERROR_ID_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!nph.get_player_history_entry(options, index, npid.get_ptr()))
|
||||||
|
{
|
||||||
|
return SCE_NP_ERROR_ID_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "util/asm.hpp"
|
#include "util/asm.hpp"
|
||||||
|
#include "util/yaml.hpp"
|
||||||
|
|
||||||
#include <span>
|
#include <span>
|
||||||
|
|
||||||
@ -55,6 +56,63 @@ LOG_CHANNEL(ticket_log, "Ticket");
|
|||||||
|
|
||||||
namespace np
|
namespace np
|
||||||
{
|
{
|
||||||
|
std::string get_players_history_path()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return fs::get_config_dir() + "config/players_history.yml";
|
||||||
|
#else
|
||||||
|
return fs::get_config_dir() + "players_history.yml";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, player_history> load_players_history()
|
||||||
|
{
|
||||||
|
const auto parsing_error = [](std::string_view error) -> std::map<std::string, player_history>
|
||||||
|
{
|
||||||
|
nph_log.error("Error parsing %s: %s", get_players_history_path(), error);
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<std::string, player_history> history;
|
||||||
|
|
||||||
|
if (fs::file history_file{get_players_history_path(), fs::read + fs::create})
|
||||||
|
{
|
||||||
|
auto [yml_players_history, error] = yaml_load(history_file.to_string());
|
||||||
|
|
||||||
|
if (!error.empty())
|
||||||
|
return parsing_error(error);
|
||||||
|
|
||||||
|
for (const auto& player : yml_players_history)
|
||||||
|
{
|
||||||
|
std::string username = player.first.Scalar();
|
||||||
|
const auto& seq = player.second;
|
||||||
|
|
||||||
|
if (!seq.IsSequence() || seq.size() != 3)
|
||||||
|
return parsing_error("Player history is not a proper sequence!");
|
||||||
|
|
||||||
|
const u64 timestamp = get_yaml_node_value<u64>(seq[0], error);
|
||||||
|
if (!error.empty())
|
||||||
|
return parsing_error(error);
|
||||||
|
|
||||||
|
std::string description = seq[1].Scalar();
|
||||||
|
|
||||||
|
if (!seq[2].IsSequence())
|
||||||
|
return parsing_error("Expected communication ids sequence");
|
||||||
|
|
||||||
|
std::set<std::string> com_ids;
|
||||||
|
|
||||||
|
for (usz i = 0; i < seq[2].size(); i++)
|
||||||
|
{
|
||||||
|
com_ids.insert(seq[2][i].Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
|
history.insert(std::make_pair(std::move(username), player_history{.timestamp = timestamp, .communication_ids = std::move(com_ids), .description = std::move(description)}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
ticket::ticket(std::vector<u8>&& raw_data)
|
ticket::ticket(std::vector<u8>&& raw_data)
|
||||||
: raw_data(raw_data)
|
: raw_data(raw_data)
|
||||||
{
|
{
|
||||||
@ -363,6 +421,13 @@ namespace np
|
|||||||
|
|
||||||
np_handler::np_handler()
|
np_handler::np_handler()
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
auto history = load_players_history();
|
||||||
|
|
||||||
|
std::lock_guard lock(mutex_history);
|
||||||
|
players_history = std::move(history);
|
||||||
|
}
|
||||||
|
|
||||||
g_fxo->need<named_thread<signaling_handler>>();
|
g_fxo->need<named_thread<signaling_handler>>();
|
||||||
|
|
||||||
is_connected = (g_cfg.net.net_active == np_internet_status::enabled);
|
is_connected = (g_cfg.net.net_active == np_internet_status::enabled);
|
||||||
@ -1217,13 +1282,169 @@ namespace np
|
|||||||
return ::at32(match2_req_results, event_key);
|
return ::at32(match2_req_results, event_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 np_handler::add_players_to_history(vm::cptr<SceNpId> /*npids*/, u32 /*count*/)
|
player_history& np_handler::get_player_and_set_timestamp(const SceNpId& npid, u64 timestamp)
|
||||||
{
|
{
|
||||||
|
std::string npid_str = std::string(npid.handle.data);
|
||||||
|
|
||||||
|
if (!players_history.contains(npid_str))
|
||||||
|
{
|
||||||
|
auto [it, success] = players_history.insert(std::make_pair(std::move(npid_str), player_history{.timestamp = timestamp}));
|
||||||
|
ensure(success);
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& history = ::at32(players_history, npid_str);
|
||||||
|
history.timestamp = timestamp;
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr usz MAX_HISTORY_ENTRIES = 200;
|
||||||
|
|
||||||
|
void np_handler::add_player_to_history(const SceNpId* npid, const char* description)
|
||||||
|
{
|
||||||
|
std::lock_guard lock(mutex_history);
|
||||||
|
auto& history = get_player_and_set_timestamp(*npid, get_system_time());
|
||||||
|
|
||||||
|
if (description)
|
||||||
|
history.description = description;
|
||||||
|
|
||||||
|
while (players_history.size() > MAX_HISTORY_ENTRIES)
|
||||||
|
{
|
||||||
|
auto it = std::min_element(players_history.begin(), players_history.end(), [](const auto& a, const auto& b) { return a.second.timestamp < b.second.timestamp; } );
|
||||||
|
players_history.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
save_players_history();
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 np_handler::add_players_to_history(const SceNpId* npids, const char* description, u32 count)
|
||||||
|
{
|
||||||
|
std::lock_guard lock(mutex_history);
|
||||||
|
|
||||||
|
const std::string communication_id_str = std::string(basic_handler.context.data);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
auto& history = get_player_and_set_timestamp(npids[i], get_system_time());
|
||||||
|
|
||||||
|
if (description)
|
||||||
|
history.description = description;
|
||||||
|
|
||||||
|
history.communication_ids.insert(communication_id_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (players_history.size() > MAX_HISTORY_ENTRIES)
|
||||||
|
{
|
||||||
|
auto it = std::min_element(players_history.begin(), players_history.end(), [](const auto& a, const auto& b) { return a.second.timestamp < b.second.timestamp; } );
|
||||||
|
players_history.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
save_players_history();
|
||||||
|
|
||||||
const u32 req_id = get_req_id(REQUEST_ID_HIGH::MISC);
|
const u32 req_id = get_req_id(REQUEST_ID_HIGH::MISC);
|
||||||
send_basic_event(SCE_NP_BASIC_EVENT_ADD_PLAYERS_HISTORY_RESULT, 0, req_id);
|
send_basic_event(SCE_NP_BASIC_EVENT_ADD_PLAYERS_HISTORY_RESULT, 0, req_id);
|
||||||
return req_id;
|
return req_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 np_handler::get_players_history_count(u32 options)
|
||||||
|
{
|
||||||
|
const bool all_history = (options == SCE_NP_BASIC_PLAYERS_HISTORY_OPTIONS_ALL);
|
||||||
|
|
||||||
|
std::lock_guard lock(mutex_history);
|
||||||
|
|
||||||
|
if (all_history)
|
||||||
|
{
|
||||||
|
return ::size32(players_history);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string communication_id_str = std::string(basic_handler.context.data);
|
||||||
|
u32 count = 0;
|
||||||
|
|
||||||
|
for (auto it = players_history.begin(); it != players_history.end(); it++)
|
||||||
|
{
|
||||||
|
if (it->second.communication_ids.contains(communication_id_str))
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool np_handler::get_player_history_entry(u32 options, u32 index, SceNpId* npid)
|
||||||
|
{
|
||||||
|
const bool all_history = (options == SCE_NP_BASIC_PLAYERS_HISTORY_OPTIONS_ALL);
|
||||||
|
|
||||||
|
std::lock_guard lock(mutex_history);
|
||||||
|
|
||||||
|
if (all_history)
|
||||||
|
{
|
||||||
|
auto it = players_history.begin();
|
||||||
|
std::advance(it, index);
|
||||||
|
|
||||||
|
if (it != players_history.end())
|
||||||
|
{
|
||||||
|
string_to_npid(it->first, *npid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const std::string communication_id_str = std::string(basic_handler.context.data);
|
||||||
|
|
||||||
|
for (auto it = players_history.begin(); it != players_history.end(); it++)
|
||||||
|
{
|
||||||
|
if (it->second.communication_ids.contains(communication_id_str))
|
||||||
|
{
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
string_to_npid(it->first, *npid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void np_handler::save_players_history()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
const std::string path_to_cfg = fs::get_config_dir() + "config/";
|
||||||
|
if (!fs::create_path(path_to_cfg))
|
||||||
|
{
|
||||||
|
nph_log.error("Could not create path: %s", path_to_cfg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
fs::file history_file(get_players_history_path(), fs::rewrite);
|
||||||
|
if (!history_file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
YAML::Emitter out;
|
||||||
|
|
||||||
|
out << YAML::BeginMap;
|
||||||
|
for (const auto& [player_npid, player_info] : players_history)
|
||||||
|
{
|
||||||
|
out << player_npid;
|
||||||
|
out << YAML::BeginSeq;
|
||||||
|
out << player_info.timestamp;
|
||||||
|
out << player_info.description;
|
||||||
|
out << YAML::BeginSeq;
|
||||||
|
for (const auto& com_id : player_info.communication_ids)
|
||||||
|
{
|
||||||
|
out << com_id;
|
||||||
|
}
|
||||||
|
out << YAML::EndSeq;
|
||||||
|
out << YAML::EndSeq;
|
||||||
|
}
|
||||||
|
out << YAML::EndMap;
|
||||||
|
|
||||||
|
history_file.write(out.c_str(), out.size());
|
||||||
|
}
|
||||||
|
|
||||||
u32 np_handler::get_num_friends()
|
u32 np_handler::get_num_friends()
|
||||||
{
|
{
|
||||||
return get_rpcn()->get_num_friends();
|
return get_rpcn()->get_num_friends();
|
||||||
|
@ -40,6 +40,13 @@ namespace np
|
|||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct player_history
|
||||||
|
{
|
||||||
|
u64 timestamp;
|
||||||
|
std::set<std::string> communication_ids;
|
||||||
|
std::string description;
|
||||||
|
};
|
||||||
|
|
||||||
class ticket
|
class ticket
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -215,7 +222,10 @@ namespace np
|
|||||||
// Misc stuff
|
// Misc stuff
|
||||||
void req_ticket(u32 version, const SceNpId* npid, const char* service_id, const u8* cookie, u32 cookie_size, const char* entitlement_id, u32 consumed_count);
|
void req_ticket(u32 version, const SceNpId* npid, const char* service_id, const u8* cookie, u32 cookie_size, const char* entitlement_id, u32 consumed_count);
|
||||||
const ticket& get_ticket() const;
|
const ticket& get_ticket() const;
|
||||||
u32 add_players_to_history(vm::cptr<SceNpId> npids, u32 count);
|
void add_player_to_history(const SceNpId* npid, const char* description);
|
||||||
|
u32 add_players_to_history(const SceNpId* npids, const char* description, u32 count);
|
||||||
|
u32 get_players_history_count(u32 options);
|
||||||
|
bool get_player_history_entry(u32 options, u32 index, SceNpId* npid);
|
||||||
bool abort_request(u32 req_id);
|
bool abort_request(u32 req_id);
|
||||||
|
|
||||||
// For signaling
|
// For signaling
|
||||||
@ -346,6 +356,7 @@ namespace np
|
|||||||
u32 generate_callback_info(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, SceNpMatching2Event event_type);
|
u32 generate_callback_info(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, SceNpMatching2Event event_type);
|
||||||
std::optional<callback_info> take_pending_request(u32 req_id);
|
std::optional<callback_info> take_pending_request(u32 req_id);
|
||||||
|
|
||||||
|
private:
|
||||||
shared_mutex mutex_pending_requests;
|
shared_mutex mutex_pending_requests;
|
||||||
std::unordered_map<u32, callback_info> pending_requests;
|
std::unordered_map<u32, callback_info> pending_requests;
|
||||||
shared_mutex mutex_pending_sign_infos_requests;
|
shared_mutex mutex_pending_sign_infos_requests;
|
||||||
@ -356,7 +367,6 @@ namespace np
|
|||||||
|
|
||||||
bool m_inited_np_handler_dependencies = false;
|
bool m_inited_np_handler_dependencies = false;
|
||||||
|
|
||||||
private:
|
|
||||||
// Basic event handler;
|
// Basic event handler;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -441,5 +451,11 @@ namespace np
|
|||||||
std::string pr_comment;
|
std::string pr_comment;
|
||||||
std::vector<u8> pr_data;
|
std::vector<u8> pr_data;
|
||||||
} presence_self;
|
} presence_self;
|
||||||
|
|
||||||
|
player_history& get_player_and_set_timestamp(const SceNpId& npid, u64 timestamp);
|
||||||
|
void save_players_history();
|
||||||
|
|
||||||
|
shared_mutex mutex_history;
|
||||||
|
std::map<std::string, player_history> players_history; // npid / history
|
||||||
};
|
};
|
||||||
} // namespace np
|
} // namespace np
|
||||||
|
@ -884,6 +884,19 @@ void friend_callback(void* param, rpcn::NotificationType ntype, const std::strin
|
|||||||
dlg->callback_handler(ntype, username, status);
|
dlg->callback_handler(ntype, username, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Avoid including np_handler.h
|
||||||
|
namespace np
|
||||||
|
{
|
||||||
|
struct player_history
|
||||||
|
{
|
||||||
|
u64 timestamp;
|
||||||
|
std::set<std::string> communication_ids;
|
||||||
|
std::string description;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<std::string, player_history> load_players_history();
|
||||||
|
}
|
||||||
|
|
||||||
rpcn_friends_dialog::rpcn_friends_dialog(QWidget* parent)
|
rpcn_friends_dialog::rpcn_friends_dialog(QWidget* parent)
|
||||||
: QDialog(parent),
|
: QDialog(parent),
|
||||||
m_green_icon(gui::utils::circle_pixmap(QColorConstants::Svg::green, devicePixelRatioF() * 2)),
|
m_green_icon(gui::utils::circle_pixmap(QColorConstants::Svg::green, devicePixelRatioF() * 2)),
|
||||||
@ -944,6 +957,14 @@ rpcn_friends_dialog::rpcn_friends_dialog(QWidget* parent)
|
|||||||
grp_list_blocks->setLayout(vbox_lst_blocks);
|
grp_list_blocks->setLayout(vbox_lst_blocks);
|
||||||
hbox_groupboxes->addWidget(grp_list_blocks);
|
hbox_groupboxes->addWidget(grp_list_blocks);
|
||||||
|
|
||||||
|
QGroupBox* grp_list_history = new QGroupBox(tr("Recent Players"));
|
||||||
|
QVBoxLayout* vbox_lst_history = new QVBoxLayout();
|
||||||
|
m_lst_history = new QListWidget(this);
|
||||||
|
m_lst_history->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
vbox_lst_history->addWidget(m_lst_history);
|
||||||
|
grp_list_history->setLayout(vbox_lst_history);
|
||||||
|
hbox_groupboxes->addWidget(grp_list_history);
|
||||||
|
|
||||||
vbox_global->addLayout(hbox_groupboxes);
|
vbox_global->addLayout(hbox_groupboxes);
|
||||||
|
|
||||||
setLayout(vbox_global);
|
setLayout(vbox_global);
|
||||||
@ -990,6 +1011,20 @@ rpcn_friends_dialog::rpcn_friends_dialog(QWidget* parent)
|
|||||||
add_update_list(m_lst_blocks, QString::fromStdString(blck), m_red_icon, QVariant(false));
|
add_update_list(m_lst_blocks, QString::fromStdString(blck), m_red_icon, QVariant(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto history = np::load_players_history();
|
||||||
|
std::map<u64, std::string, std::greater<u64>> sorted_history;
|
||||||
|
|
||||||
|
for (const auto& [username, user_info] : history)
|
||||||
|
{
|
||||||
|
if (!data.friends.contains(username) && !data.requests_sent.contains(username) && !data.requests_received.contains(username))
|
||||||
|
sorted_history.insert(std::make_pair(user_info.timestamp, std::move(username)));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& [_, username] : sorted_history)
|
||||||
|
{
|
||||||
|
m_lst_history->addItem(new QListWidgetItem(QString::fromStdString(username)));
|
||||||
|
}
|
||||||
|
|
||||||
connect(this, &rpcn_friends_dialog::signal_add_update_friend, this, &rpcn_friends_dialog::add_update_friend);
|
connect(this, &rpcn_friends_dialog::signal_add_update_friend, this, &rpcn_friends_dialog::add_update_friend);
|
||||||
connect(this, &rpcn_friends_dialog::signal_remove_friend, this, &rpcn_friends_dialog::remove_friend);
|
connect(this, &rpcn_friends_dialog::signal_remove_friend, this, &rpcn_friends_dialog::remove_friend);
|
||||||
connect(this, &rpcn_friends_dialog::signal_add_query, this, &rpcn_friends_dialog::add_query);
|
connect(this, &rpcn_friends_dialog::signal_add_query, this, &rpcn_friends_dialog::add_query);
|
||||||
@ -1041,9 +1076,9 @@ rpcn_friends_dialog::rpcn_friends_dialog(QWidget* parent)
|
|||||||
std::string str_sel_friend = selected_item->text().toStdString();
|
std::string str_sel_friend = selected_item->text().toStdString();
|
||||||
|
|
||||||
QMenu* context_menu = new QMenu();
|
QMenu* context_menu = new QMenu();
|
||||||
QAction* remove_friend_action = context_menu->addAction(tr("&Accept Request"));
|
QAction* accept_request_action = context_menu->addAction(tr("&Accept Request"));
|
||||||
|
|
||||||
connect(remove_friend_action, &QAction::triggered, this, [this, str_sel_friend]()
|
connect(accept_request_action, &QAction::triggered, this, [this, str_sel_friend]()
|
||||||
{
|
{
|
||||||
if (!m_rpcn->add_friend(str_sel_friend))
|
if (!m_rpcn->add_friend(str_sel_friend))
|
||||||
{
|
{
|
||||||
@ -1059,6 +1094,38 @@ rpcn_friends_dialog::rpcn_friends_dialog(QWidget* parent)
|
|||||||
context_menu->deleteLater();
|
context_menu->deleteLater();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(m_lst_history, &QListWidget::customContextMenuRequested, this, [this](const QPoint& pos)
|
||||||
|
{
|
||||||
|
if (!m_lst_history->itemAt(pos) || m_lst_history->selectedItems().count() != 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QListWidgetItem* selected_item = m_lst_history->selectedItems().first();
|
||||||
|
|
||||||
|
std::string str_sel_friend = selected_item->text().toStdString();
|
||||||
|
|
||||||
|
QMenu* context_menu = new QMenu();
|
||||||
|
QAction* send_friend_request_action = context_menu->addAction(tr("&Send Friend Request"));
|
||||||
|
|
||||||
|
connect(send_friend_request_action, &QAction::triggered, this, [this, str_sel_friend]()
|
||||||
|
{
|
||||||
|
if (!m_rpcn->add_friend(str_sel_friend))
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Error sending a friend request!"), tr("An error occurred while trying to send a friend request!"), QMessageBox::Ok);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QString qstr_friend = QString::fromStdString(str_sel_friend);
|
||||||
|
add_update_list(m_lst_requests, qstr_friend, m_orange_icon, QVariant(false));
|
||||||
|
remove_list(m_lst_history, qstr_friend);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
context_menu->exec(m_lst_history->viewport()->mapToGlobal(pos));
|
||||||
|
context_menu->deleteLater();
|
||||||
|
});
|
||||||
|
|
||||||
connect(btn_addfriend, &QAbstractButton::clicked, this, [this]()
|
connect(btn_addfriend, &QAbstractButton::clicked, this, [this]()
|
||||||
{
|
{
|
||||||
std::string str_friend_username;
|
std::string str_friend_username;
|
||||||
@ -1146,6 +1213,7 @@ void rpcn_friends_dialog::remove_friend(QString name)
|
|||||||
void rpcn_friends_dialog::add_query(QString name)
|
void rpcn_friends_dialog::add_query(QString name)
|
||||||
{
|
{
|
||||||
add_update_list(m_lst_requests, name, m_yellow_icon, QVariant(true));
|
add_update_list(m_lst_requests, name, m_yellow_icon, QVariant(true));
|
||||||
|
remove_list(m_lst_history, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpcn_friends_dialog::callback_handler(rpcn::NotificationType ntype, std::string username, bool status)
|
void rpcn_friends_dialog::callback_handler(rpcn::NotificationType ntype, std::string username, bool status)
|
||||||
|
@ -131,6 +131,8 @@ private:
|
|||||||
QListWidget* m_lst_requests = nullptr;
|
QListWidget* m_lst_requests = nullptr;
|
||||||
// list of people blocked by the user
|
// list of people blocked by the user
|
||||||
QListWidget* m_lst_blocks = nullptr;
|
QListWidget* m_lst_blocks = nullptr;
|
||||||
|
// list of players in history
|
||||||
|
QListWidget* m_lst_history = nullptr;
|
||||||
|
|
||||||
std::shared_ptr<rpcn::rpcn_client> m_rpcn;
|
std::shared_ptr<rpcn::rpcn_client> m_rpcn;
|
||||||
bool m_rpcn_ok = false;
|
bool m_rpcn_ok = false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user