rpcn v0.4.0

This commit is contained in:
RipleyTom 2020-11-17 02:19:17 +01:00 committed by Megamouse
parent 15af1bca69
commit ea9dc9317d
34 changed files with 4907 additions and 2234 deletions

View file

@ -44,24 +44,25 @@ np_handler::np_handler()
{
g_fxo->need<named_thread<signaling_handler>>();
g_cfg_rpcn.load();
std::lock_guard lock(mutex_rpcn);
rpcn = rpcn::rpcn_client::get_instance();
is_connected = (g_cfg.net.net_active == np_internet_status::enabled);
is_psn_active = (g_cfg.net.psn_status >= np_psn_status::fake);
is_psn_active = (g_cfg.net.psn_status >= np_psn_status::psn_fake);
if (get_net_status() == CELL_NET_CTL_STATE_IPObtained)
{
if (!discover_ip_address())
{
nph_log.error("Failed to discover local IP!");
is_connected = false;
is_connected = false;
is_psn_active = false;
}
if (!discover_ether_address())
{
nph_log.error("Failed to discover ethernet address!");
is_connected = false;
is_connected = false;
is_psn_active = false;
}
@ -115,7 +116,7 @@ bool np_handler::discover_ip_address()
nph_log.notice("Hostname was determined to be %s", hostname.c_str());
hostent *host = gethostbyname(hostname.data());
hostent* host = gethostbyname(hostname.data());
if (!host)
{
nph_log.error("gethostbyname failed in IP discovery!");
@ -129,7 +130,7 @@ bool np_handler::discover_ip_address()
}
// First address is used for now, (TODO combobox with possible local addresses to use?)
local_ip_addr = *reinterpret_cast<u32 *>(host->h_addr_list[0]);
local_ip_addr = *reinterpret_cast<u32*>(host->h_addr_list[0]);
// Set public address to local discovered address for now, may be updated later;
public_ip_addr = local_ip_addr;
@ -164,10 +165,10 @@ bool np_handler::discover_ether_address()
std::vector<u8> adapter_infos(sizeof(IP_ADAPTER_INFO));
ULONG size_infos = sizeof(IP_ADAPTER_INFO);
if (GetAdaptersInfo(reinterpret_cast<PIP_ADAPTER_INFO>(adapter_infos.data()), &size_infos) == ERROR_BUFFER_OVERFLOW)
if (GetAdaptersInfo(reinterpret_cast<PIP_ADAPTER_INFO>(adapter_infos.data()), &size_infos) == ERROR_BUFFER_OVERFLOW)
adapter_infos.resize(size_infos);
if (GetAdaptersInfo(reinterpret_cast<PIP_ADAPTER_INFO>(adapter_infos.data()), &size_infos) == NO_ERROR && size_infos)
if (GetAdaptersInfo(reinterpret_cast<PIP_ADAPTER_INFO>(adapter_infos.data()), &size_infos) == NO_ERROR && size_infos)
{
PIP_ADAPTER_INFO info = reinterpret_cast<PIP_ADAPTER_INFO>(adapter_infos.data());
memcpy(ether_address.data(), info[0].Address, 6);
@ -305,6 +306,11 @@ void np_handler::string_to_avatar_url(const std::string& str, SceNpAvatarUrl* av
strcpy_trunc(avatar_url->data, str);
}
void np_handler::string_to_communication_id(const std::string& str, SceNpCommunicationId* comm_id)
{
strcpy_trunc(comm_id->data, str);
}
void np_handler::init_NP(u32 poolsize, vm::ptr<void> poolptr)
{
// Init memory pool
@ -317,7 +323,7 @@ void np_handler::init_NP(u32 poolsize, vm::ptr<void> poolptr)
memset(&online_name, 0, sizeof(online_name));
memset(&avatar_url, 0, sizeof(avatar_url));
if (g_cfg.net.psn_status >= np_psn_status::fake)
if (g_cfg.net.psn_status >= np_psn_status::psn_fake)
{
std::string s_npid = g_cfg_rpcn.get_npid();
ensure(!s_npid.empty()); // It should have been generated before this
@ -331,35 +337,39 @@ void np_handler::init_NP(u32 poolsize, vm::ptr<void> poolptr)
{
case np_psn_status::disabled:
break;
case np_psn_status::fake:
case np_psn_status::psn_fake:
{
np_handler::string_to_online_name("RPCS3's user", &online_name);
np_handler::string_to_avatar_url("https://rpcs3.net/cdn/netplay/DefaultAvatar.png", &avatar_url);
break;
}
case np_psn_status::rpcn:
case np_psn_status::psn_rpcn:
{
if (!is_psn_active)
break;
// Connect RPCN client
if (!rpcn.connect(g_cfg_rpcn.get_host()))
std::lock_guard lock(mutex_rpcn);
rpcn = rpcn::rpcn_client::get_instance();
// Make sure we're connected
if (auto state = rpcn->wait_for_connection(); state != rpcn::rpcn_state::failure_no_failure)
{
rpcn_log.error("Connection to RPCN Failed!");
is_psn_active = false;
return;
}
if (!rpcn.login(g_cfg_rpcn.get_npid(), g_cfg_rpcn.get_password(), g_cfg_rpcn.get_token()))
if (auto state = rpcn->wait_for_authentified(); state != rpcn::rpcn_state::failure_no_failure)
{
rpcn_log.error("RPCN login attempt failed!");
is_psn_active = false;
return;
}
np_handler::string_to_online_name(rpcn.get_online_name(), &online_name);
np_handler::string_to_avatar_url(rpcn.get_avatar_url(), &avatar_url);
public_ip_addr = rpcn.get_addr_sig();
np_handler::string_to_online_name(rpcn->get_online_name(), &online_name);
np_handler::string_to_avatar_url(rpcn->get_avatar_url(), &avatar_url);
public_ip_addr = rpcn->get_addr_sig();
break;
}
@ -376,10 +386,11 @@ void np_handler::terminate_NP()
mpool_avail = 0;
mpool_allocs.clear();
if (g_cfg.net.psn_status == np_psn_status::rpcn)
if (g_cfg.net.psn_status == np_psn_status::psn_rpcn)
{
rpcn_log.error("Disconnecting from RPCN!");
rpcn.disconnect();
rpcn_log.notice("Disconnecting from RPCN!");
std::lock_guard lock(mutex_rpcn);
rpcn.reset();
}
}
@ -433,12 +444,12 @@ std::vector<SceNpMatching2ServerId> np_handler::get_match2_server_list(SceNpMatc
{
std::vector<SceNpMatching2ServerId> server_list{};
if (g_cfg.net.psn_status != np_psn_status::rpcn)
if (g_cfg.net.psn_status != np_psn_status::psn_rpcn)
{
return server_list;
}
if (!rpcn.get_server_list(get_req_id(0), get_match2_context(ctx_id)->communicationId, server_list))
if (!rpcn->get_server_list(get_req_id(0), get_match2_context(ctx_id)->communicationId, server_list))
{
rpcn_log.error("Disconnecting from RPCN!");
is_psn_active = false;
@ -457,14 +468,13 @@ u32 np_handler::get_server_status(SceNpMatching2ContextId ctx_id, vm::cptr<SceNp
serv_info->server.serverId = server_id;
serv_info->server.status = SCE_NP_MATCHING2_SERVER_STATUS_AVAILABLE;
const auto cb_info = std::move(pending_requests.at(req_id));
pending_requests.erase(req_id);
const auto cb_info = take_pending_request(req_id);
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetServerInfo, event_key, 0, sizeof(SceNpMatching2GetServerInfoResponse), cb_info.cb_arg);
return 0;
});
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetServerInfo, event_key, 0, sizeof(SceNpMatching2GetServerInfoResponse), cb_info.cb_arg);
return 0;
});
return req_id;
}
@ -474,14 +484,13 @@ u32 np_handler::create_server_context(SceNpMatching2ContextId ctx_id, vm::cptr<S
u32 req_id = generate_callback_info(ctx_id, optParam);
u32 event_key = get_event_key();
const auto cb_info = std::move(pending_requests.at(req_id));
pending_requests.erase(req_id);
const auto cb_info = take_pending_request(req_id);
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_CreateServerContext, event_key, 0, 0, cb_info.cb_arg);
return 0;
});
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_CreateServerContext, event_key, 0, 0, cb_info.cb_arg);
return 0;
});
return req_id;
}
@ -490,7 +499,7 @@ u32 np_handler::get_world_list(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMat
{
u32 req_id = generate_callback_info(ctx_id, optParam);
if (!rpcn.get_world_list(req_id, get_match2_context(ctx_id)->communicationId, server_id))
if (!rpcn->get_world_list(req_id, get_match2_context(ctx_id)->communicationId, server_id))
{
rpcn_log.error("Disconnecting from RPCN!");
is_psn_active = false;
@ -503,7 +512,7 @@ u32 np_handler::create_join_room(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpM
{
u32 req_id = generate_callback_info(ctx_id, optParam);
if (!rpcn.createjoin_room(req_id, get_match2_context(ctx_id)->communicationId, req))
if (!rpcn->createjoin_room(req_id, get_match2_context(ctx_id)->communicationId, req))
{
rpcn_log.error("Disconnecting from RPCN!");
is_psn_active = false;
@ -516,7 +525,7 @@ u32 np_handler::join_room(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching
{
u32 req_id = generate_callback_info(ctx_id, optParam);
if (!rpcn.join_room(req_id, get_match2_context(ctx_id)->communicationId, req))
if (!rpcn->join_room(req_id, get_match2_context(ctx_id)->communicationId, req))
{
rpcn_log.error("Disconnecting from RPCN!");
is_psn_active = false;
@ -529,7 +538,7 @@ u32 np_handler::leave_room(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatchin
{
u32 req_id = generate_callback_info(ctx_id, optParam);
if (!rpcn.leave_room(req_id, get_match2_context(ctx_id)->communicationId, req))
if (!rpcn->leave_room(req_id, get_match2_context(ctx_id)->communicationId, req))
{
rpcn_log.error("Disconnecting from RPCN!");
is_psn_active = false;
@ -542,7 +551,20 @@ u32 np_handler::search_room(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatchi
{
u32 req_id = generate_callback_info(ctx_id, optParam);
if (!rpcn.search_room(req_id, get_match2_context(ctx_id)->communicationId, req))
if (!rpcn->search_room(req_id, get_match2_context(ctx_id)->communicationId, req))
{
rpcn_log.error("Disconnecting from RPCN!");
is_psn_active = false;
}
return req_id;
}
u32 np_handler::get_roomdata_external_list(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2GetRoomDataExternalListRequest* req)
{
u32 req_id = generate_callback_info(ctx_id, optParam);
if (!rpcn->get_roomdata_external_list(req_id, get_match2_context(ctx_id)->communicationId, req))
{
rpcn_log.error("Disconnecting from RPCN!");
is_psn_active = false;
@ -557,7 +579,7 @@ u32 np_handler::set_roomdata_external(SceNpMatching2ContextId ctx_id, vm::cptr<S
extra_nps::print_set_roomdata_ext_req(req);
if (!rpcn.set_roomdata_external(req_id, get_match2_context(ctx_id)->communicationId, req))
if (!rpcn->set_roomdata_external(req_id, get_match2_context(ctx_id)->communicationId, req))
{
rpcn_log.error("Disconnecting from RPCN!");
is_psn_active = false;
@ -570,7 +592,7 @@ u32 np_handler::get_roomdata_internal(SceNpMatching2ContextId ctx_id, vm::cptr<S
{
u32 req_id = generate_callback_info(ctx_id, optParam);
if (!rpcn.get_roomdata_internal(req_id, get_match2_context(ctx_id)->communicationId, req))
if (!rpcn->get_roomdata_internal(req_id, get_match2_context(ctx_id)->communicationId, req))
{
rpcn_log.error("Disconnecting from RPCN!");
is_psn_active = false;
@ -585,7 +607,7 @@ u32 np_handler::set_roomdata_internal(SceNpMatching2ContextId ctx_id, vm::cptr<S
extra_nps::print_set_roomdata_int_req(req);
if (!rpcn.set_roomdata_internal(req_id, get_match2_context(ctx_id)->communicationId, req))
if (!rpcn->set_roomdata_internal(req_id, get_match2_context(ctx_id)->communicationId, req))
{
rpcn_log.error("Disconnecting from RPCN!");
is_psn_active = false;
@ -598,7 +620,7 @@ u32 np_handler::get_ping_info(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatc
{
u32 req_id = generate_callback_info(ctx_id, optParam);
if (!rpcn.ping_room_owner(req_id, get_match2_context(ctx_id)->communicationId, req->roomId))
if (!rpcn->ping_room_owner(req_id, get_match2_context(ctx_id)->communicationId, req->roomId))
{
rpcn_log.error("Disconnecting from RPCN!");
is_psn_active = false;
@ -611,7 +633,7 @@ u32 np_handler::send_room_message(SceNpMatching2ContextId ctx_id, vm::cptr<SceNp
{
u32 req_id = generate_callback_info(ctx_id, optParam);
if (!rpcn.send_room_message(req_id, get_match2_context(ctx_id)->communicationId, req))
if (!rpcn->send_room_message(req_id, get_match2_context(ctx_id)->communicationId, req))
{
rpcn_log.error("Disconnecting from RPCN!");
is_psn_active = false;
@ -623,9 +645,12 @@ u32 np_handler::send_room_message(SceNpMatching2ContextId ctx_id, vm::cptr<SceNp
void np_handler::req_sign_infos(const std::string& npid, u32 conn_id)
{
u32 req_id = get_req_id(0x3333);
pending_sign_infos_requests[req_id] = conn_id;
{
std::lock_guard lock(mutex_pending_sign_infos_requests);
pending_sign_infos_requests[req_id] = conn_id;
}
if (!rpcn.req_sign_infos(req_id, npid))
if (!rpcn->req_sign_infos(req_id, npid))
{
rpcn_log.error("Disconnecting from RPCN!");
is_psn_active = false;
@ -640,7 +665,7 @@ void np_handler::req_ticket(u32 /*version*/, const SceNpId* /*npid*/, const char
std::string service_id_str(service_id);
if (!rpcn.req_ticket(req_id, service_id_str))
if (!rpcn->req_ticket(req_id, service_id_str))
{
rpcn_log.error("Disconnecting from RPCN!");
is_psn_active = false;
@ -649,7 +674,6 @@ void np_handler::req_ticket(u32 /*version*/, const SceNpId* /*npid*/, const char
return;
}
u32 np_handler::get_match2_event(SceNpMatching2EventKey event_key, u8* dest, u32 size)
{
std::lock_guard lock(mutex_req_results);
@ -663,67 +687,181 @@ u32 np_handler::get_match2_event(SceNpMatching2EventKey event_key, u8* dest, u32
return size_copied;
}
bool np_handler::send_basic_event(s32 event, s32 retCode, u32 reqId)
{
if (basic_handler.registered)
{
sysutil_register_cb([handler_func = this->basic_handler.handler_func, handler_arg = this->basic_handler.handler_arg, event, retCode, reqId](ppu_thread& cb_ppu) -> s32
{
handler_func(cb_ppu, event, retCode, reqId, handler_arg);
return 0;
});
return true;
}
return false;
}
void np_handler::queue_basic_event(basic_event to_queue)
{
std::lock_guard lock(mutex_queue_basic_events);
queue_basic_events.push(std::move(to_queue));
}
error_code np_handler::get_basic_event(vm::ptr<s32> event, vm::ptr<SceNpUserInfo> from, vm::ptr<s32> data, vm::ptr<u32> size)
{
basic_event cur_event;
{
std::lock_guard lock(mutex_queue_basic_events);
if (queue_basic_events.empty())
{
return not_an_error(SCE_NP_BASIC_ERROR_NO_EVENT);
}
cur_event = std::move(queue_basic_events.front());
queue_basic_events.pop();
}
const u32 size_avail = *size;
u32 res_size = std::min(static_cast<u32>(cur_event.data.size()), size_avail);
*event = cur_event.event;
memcpy(from.get_ptr(), &cur_event.from, sizeof(cur_event.from));
memcpy(data.get_ptr(), cur_event.data.data(), res_size);
*size = res_size;
if (res_size < cur_event.data.size())
{
return SCE_NP_BASIC_ERROR_DATA_LOST;
}
return CELL_OK;
}
std::optional<std::shared_ptr<std::pair<std::string, message_data>>> np_handler::get_message(u64 id)
{
return rpcn->get_message(id);
}
void np_handler::operator()()
{
if (g_cfg.net.psn_status != np_psn_status::rpcn)
if (g_cfg.net.psn_status != np_psn_status::psn_rpcn)
return;
while (thread_ctrl::state() != thread_state::aborting && !Emu.IsStopped())
{
if (!rpcn.manage_connection())
bool sleep = true;
if (rpcn)
{
std::lock_guard lock(mutex_rpcn);
if (!rpcn)
{
continue;
}
auto replies = rpcn->get_replies();
for (auto& reply : replies)
{
const u16 command = reply.second.first;
const u32 req_id = reply.first;
std::vector<u8>& data = reply.second.second;
switch (command)
{
case rpcn::CommandType::GetWorldList: reply_get_world_list(req_id, data); break;
case rpcn::CommandType::CreateRoom: reply_create_join_room(req_id, data); break;
case rpcn::CommandType::JoinRoom: reply_join_room(req_id, data); break;
case rpcn::CommandType::LeaveRoom: reply_leave_room(req_id, data); break;
case rpcn::CommandType::SearchRoom: reply_search_room(req_id, data); break;
case rpcn::CommandType::GetRoomDataExternalList: reply_get_roomdata_external_list(req_id, data); break;
case rpcn::CommandType::SetRoomDataExternal: reply_set_roomdata_external(req_id, data); break;
case rpcn::CommandType::GetRoomDataInternal: reply_get_roomdata_internal(req_id, data); break;
case rpcn::CommandType::SetRoomDataInternal: reply_set_roomdata_internal(req_id, data); break;
case rpcn::CommandType::PingRoomOwner: reply_get_ping_info(req_id, data); break;
case rpcn::CommandType::SendRoomMessage: reply_send_room_message(req_id, data); break;
case rpcn::CommandType::RequestSignalingInfos: reply_req_sign_infos(req_id, data); break;
case rpcn::CommandType::RequestTicket: reply_req_ticket(req_id, data); break;
default: rpcn_log.error("Unknown reply(%d) received!", command); break;
}
}
auto notifications = rpcn->get_notifications();
for (auto& notif : notifications)
{
switch (notif.first)
{
case rpcn::NotificationType::UserJoinedRoom: notif_user_joined_room(notif.second); break;
case rpcn::NotificationType::UserLeftRoom: notif_user_left_room(notif.second); break;
case rpcn::NotificationType::RoomDestroyed: notif_room_destroyed(notif.second); break;
case rpcn::NotificationType::SignalP2PConnect: notif_p2p_connect(notif.second); break;
case rpcn::NotificationType::RoomMessageReceived: notif_room_message_received(notif.second); break;
default: rpcn_log.error("Unknown notification(%d) received!", notif.first); break;
}
}
auto messages = rpcn->get_new_messages();
if (basic_handler.registered)
{
for (const auto msg_id : messages)
{
const auto opt_msg = rpcn->get_message(msg_id);
if (!opt_msg)
{
continue;
}
const auto& msg = opt_msg.value();
if (strncmp(msg->second.commId.data, basic_handler.context.data, sizeof(basic_handler.context.data) - 1) == 0)
{
u32 event;
switch (msg->second.mainType)
{
case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_DATA_ATTACHMENT:
event = SCE_NP_BASIC_EVENT_INCOMING_ATTACHMENT;
break;
case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_INVITE:
event = (msg->second.msgFeatures & SCE_NP_BASIC_MESSAGE_FEATURES_BOOTABLE) ? SCE_NP_BASIC_EVENT_INCOMING_BOOTABLE_INVITATION : SCE_NP_BASIC_EVENT_INCOMING_INVITATION;
break;
case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_CUSTOM_DATA:
event = (msg->second.msgFeatures & SCE_NP_BASIC_MESSAGE_FEATURES_BOOTABLE) ? SCE_NP_BASIC_EVENT_INCOMING_BOOTABLE_CUSTOM_DATA_MESSAGE : SCE_NP_BASIC_EVENT_INCOMING_CUSTOM_DATA_MESSAGE;
break;
case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_GENERAL:
case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_ADD_FRIEND:
case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_URL_ATTACHMENT:
event = SCE_NP_BASIC_EVENT_MESSAGE;
default:
continue;
}
basic_event to_add{};
to_add.event = event;
strcpy_trunc(to_add.from.userId.handle.data, msg->first);
strcpy_trunc(to_add.from.name.data, msg->first);
queue_basic_event(std::move(to_add));
send_basic_event(event, 0, 0);
}
}
}
if (!replies.empty() || !notifications.empty())
{
sleep = false;
}
}
// TODO: replace with an appropriate semaphore
if (sleep)
{
thread_ctrl::wait_for(200'000);
continue;
}
auto replies = rpcn.get_replies();
for (auto& reply : replies)
{
const u16 command = reply.second.first;
const u32 req_id = reply.first;
std::vector<u8>& data = reply.second.second;
switch (command)
{
case CommandType::GetWorldList: reply_get_world_list(req_id, data); break;
case CommandType::CreateRoom: reply_create_join_room(req_id, data); break;
case CommandType::JoinRoom: reply_join_room(req_id, data); break;
case CommandType::LeaveRoom: reply_leave_room(req_id, data); break;
case CommandType::SearchRoom: reply_search_room(req_id, data); break;
case CommandType::SetRoomDataExternal: reply_set_roomdata_external(req_id, data); break;
case CommandType::GetRoomDataInternal: reply_get_roomdata_internal(req_id, data); break;
case CommandType::SetRoomDataInternal: reply_set_roomdata_internal(req_id, data); break;
case CommandType::PingRoomOwner: reply_get_ping_info(req_id, data); break;
case CommandType::SendRoomMessage: reply_send_room_message(req_id, data); break;
case CommandType::RequestSignalingInfos: reply_req_sign_infos(req_id, data); break;
case CommandType::RequestTicket: reply_req_ticket(req_id, data); break;
default: rpcn_log.error("Unknown reply(%d) received!", command); break;
}
}
auto notifications = rpcn.get_notifications();
for (auto& notif : notifications)
{
switch (notif.first)
{
case NotificationType::UserJoinedRoom: notif_user_joined_room(notif.second); break;
case NotificationType::UserLeftRoom: notif_user_left_room(notif.second); break;
case NotificationType::RoomDestroyed: notif_room_destroyed(notif.second); break;
case NotificationType::SignalP2PConnect: notif_p2p_connect(notif.second); break;
case NotificationType::RoomMessageReceived: notif_room_message_received(notif.second); break;
default: rpcn_log.error("Unknown notification(%d) received!", notif.first); break;
}
}
}
}
bool np_handler::reply_get_world_list(u32 req_id, std::vector<u8>& reply_data)
{
if (pending_requests.count(req_id) == 0)
return error_and_disconnect("Unexpected reply ID to GetWorldList");
const auto cb_info = std::move(pending_requests.at(req_id));
pending_requests.erase(req_id);
const auto cb_info = take_pending_request(req_id);
vec_stream reply(reply_data, 1);
@ -760,21 +898,17 @@ bool np_handler::reply_get_world_list(u32 req_id, std::vector<u8>& reply_data)
}
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetWorldInfoList, event_key, 0, sizeof(SceNpMatching2GetWorldInfoListResponse), cb_info.cb_arg);
return 0;
});
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetWorldInfoList, event_key, 0, sizeof(SceNpMatching2GetWorldInfoListResponse), cb_info.cb_arg);
return 0;
});
return true;
}
bool np_handler::reply_create_join_room(u32 req_id, std::vector<u8>& reply_data)
{
if (pending_requests.count(req_id) == 0)
return error_and_disconnect("Unexpected reply ID to CreateRoom");
const auto cb_info = std::move(pending_requests.at(req_id));
pending_requests.erase(req_id);
const auto cb_info = take_pending_request(req_id);
vec_stream reply(reply_data, 1);
auto create_room_resp = reply.get_rawdata();
@ -795,27 +929,23 @@ bool np_handler::reply_create_join_room(u32 req_id, std::vector<u8>& reply_data)
// Establish Matching2 self signaling info
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.set_self_sig2_info(room_info->roomId, 1);
sigh.set_sig2_infos(room_info->roomId, 1, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, rpcn.get_addr_sig(), rpcn.get_port_sig(), true);
sigh.set_sig2_infos(room_info->roomId, 1, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, rpcn->get_addr_sig(), rpcn->get_port_sig(), true);
// TODO? Should this send a message to Signaling CB? Is this even necessary?
extra_nps::print_create_room_resp(room_resp);
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_CreateJoinRoom, event_key, 0, sizeof(SceNpMatching2CreateJoinRoomResponse), cb_info.cb_arg);
return 0;
});
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_CreateJoinRoom, event_key, 0, sizeof(SceNpMatching2CreateJoinRoomResponse), cb_info.cb_arg);
return 0;
});
return true;
}
bool np_handler::reply_join_room(u32 req_id, std::vector<u8>& reply_data)
{
if (pending_requests.count(req_id) == 0)
return error_and_disconnect("Unexpected reply ID to JoinRoom");
const auto cb_info = std::move(pending_requests.at(req_id));
pending_requests.erase(req_id);
const auto cb_info = take_pending_request(req_id);
vec_stream reply(reply_data, 1);
@ -839,25 +969,21 @@ bool np_handler::reply_join_room(u32 req_id, std::vector<u8>& reply_data)
// Establish Matching2 self signaling info
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.set_self_sig2_info(room_info->roomId, member_id);
sigh.set_sig2_infos(room_info->roomId, member_id, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, rpcn.get_addr_sig(), rpcn.get_port_sig(), true);
sigh.set_sig2_infos(room_info->roomId, member_id, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, rpcn->get_addr_sig(), rpcn->get_port_sig(), true);
// TODO? Should this send a message to Signaling CB? Is this even necessary?
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_JoinRoom, event_key, 0, sizeof(SceNpMatching2JoinRoomResponse), cb_info.cb_arg);
return 0;
});
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_JoinRoom, event_key, 0, sizeof(SceNpMatching2JoinRoomResponse), cb_info.cb_arg);
return 0;
});
return true;
}
bool np_handler::reply_leave_room(u32 req_id, std::vector<u8>& reply_data)
{
if (pending_requests.count(req_id) == 0)
return error_and_disconnect("Unexpected reply ID to LeaveRoom");
const auto cb_info = std::move(pending_requests.at(req_id));
pending_requests.erase(req_id);
const auto cb_info = take_pending_request(req_id);
vec_stream reply(reply_data, 1);
u64 room_id = reply.get<u64>();
@ -871,21 +997,17 @@ bool np_handler::reply_leave_room(u32 req_id, std::vector<u8>& reply_data)
sigh.disconnect_sig2_users(room_id);
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_LeaveRoom, event_key, 0, 0, cb_info.cb_arg);
return 0;
});
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_LeaveRoom, event_key, 0, 0, cb_info.cb_arg);
return 0;
});
return true;
}
bool np_handler::reply_search_room(u32 req_id, std::vector<u8>& reply_data)
{
if (pending_requests.count(req_id) == 0)
return error_and_disconnect("Unexpected reply ID to SearchRoom");
const auto cb_info = std::move(pending_requests.at(req_id));
pending_requests.erase(req_id);
const auto cb_info = take_pending_request(req_id);
vec_stream reply(reply_data, 1);
auto search_room_resp = reply.get_rawdata();
@ -897,43 +1019,60 @@ bool np_handler::reply_search_room(u32 req_id, std::vector<u8>& reply_data)
auto resp = flatbuffers::GetRoot<SearchRoomResponse>(search_room_resp.data());
SceNpMatching2SearchRoomResponse* search_resp = reinterpret_cast<SceNpMatching2SearchRoomResponse*>(allocate_req_result(event_key, sizeof(SceNpMatching2SearchRoomResponse)));
SearchRoomReponse_to_SceNpMatching2SearchRoomResponse(resp, search_resp);
SearchRoomResponse_to_SceNpMatching2SearchRoomResponse(resp, search_resp);
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SearchRoom, event_key, 0, sizeof(SceNpMatching2SearchRoomResponse), cb_info.cb_arg);
return 0;
});
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SearchRoom, event_key, 0, sizeof(SceNpMatching2SearchRoomResponse), cb_info.cb_arg);
return 0;
});
return true;
}
bool np_handler::reply_get_roomdata_external_list(u32 req_id, std::vector<u8>& reply_data)
{
const auto cb_info = take_pending_request(req_id);
vec_stream reply(reply_data, 1);
auto get_room_ext_resp = reply.get_rawdata();
if (reply.is_error())
return error_and_disconnect("Malformed reply to GetRoomDataExternalList command");
u32 event_key = get_event_key();
auto resp = flatbuffers::GetRoot<GetRoomDataExternalListResponse>(get_room_ext_resp.data());
SceNpMatching2GetRoomDataExternalListResponse* np_get_room_ext_resp = reinterpret_cast<SceNpMatching2GetRoomDataExternalListResponse*>(allocate_req_result(event_key, sizeof(SceNpMatching2GetRoomDataExternalListResponse)));
GetRoomDataExternalListResponse_to_SceNpMatching2GetRoomDataExternalListResponse(resp, np_get_room_ext_resp);
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SearchRoom, event_key, 0, sizeof(SceNpMatching2SearchRoomResponse), cb_info.cb_arg);
return 0;
});
return true;
}
bool np_handler::reply_set_roomdata_external(u32 req_id, std::vector<u8>& /*reply_data*/)
{
if (pending_requests.count(req_id) == 0)
return error_and_disconnect("Unexpected reply ID to SetRoomDataExternal");
const auto cb_info = std::move(pending_requests.at(req_id));
pending_requests.erase(req_id);
const auto cb_info = take_pending_request(req_id);
u32 event_key = get_event_key(); // Unsure if necessary if there is no data
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomDataExternal, event_key, 0, 0, cb_info.cb_arg);
return 0;
});
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomDataExternal, event_key, 0, 0, cb_info.cb_arg);
return 0;
});
return true;
}
bool np_handler::reply_get_roomdata_internal(u32 req_id, std::vector<u8>& reply_data)
{
if (pending_requests.count(req_id) == 0)
return error_and_disconnect("Unexpected reply ID to GetRoomDataInternal");
const auto cb_info = std::move(pending_requests.at(req_id));
pending_requests.erase(req_id);
const auto cb_info = take_pending_request(req_id);
vec_stream reply(reply_data, 1);
@ -953,40 +1092,32 @@ bool np_handler::reply_get_roomdata_internal(u32 req_id, std::vector<u8>& reply_
extra_nps::print_room_data_internal(room_resp->roomDataInternal.get_ptr());
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetRoomDataInternal, event_key, 0, sizeof(SceNpMatching2GetRoomDataInternalResponse), cb_info.cb_arg);
return 0;
});
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetRoomDataInternal, event_key, 0, sizeof(SceNpMatching2GetRoomDataInternalResponse), cb_info.cb_arg);
return 0;
});
return true;
}
bool np_handler::reply_set_roomdata_internal(u32 req_id, std::vector<u8>& /*reply_data*/)
{
if (pending_requests.count(req_id) == 0)
return error_and_disconnect("Unexpected reply ID to SetRoomDataInternal");
const auto cb_info = std::move(pending_requests.at(req_id));
pending_requests.erase(req_id);
const auto cb_info = take_pending_request(req_id);
u32 event_key = get_event_key(); // Unsure if necessary if there is no data
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomDataInternal, event_key, 0, 0, cb_info.cb_arg);
return 0;
});
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomDataInternal, event_key, 0, 0, cb_info.cb_arg);
return 0;
});
return true;
}
bool np_handler::reply_get_ping_info(u32 req_id, std::vector<u8>& reply_data)
{
if (pending_requests.count(req_id) == 0)
return error_and_disconnect("Unexpected reply ID to PingRoomOwner");
const auto cb_info = std::move(pending_requests.at(req_id));
pending_requests.erase(req_id);
const auto cb_info = take_pending_request(req_id);
vec_stream reply(reply_data, 1);
@ -1002,38 +1133,35 @@ bool np_handler::reply_get_ping_info(u32 req_id, std::vector<u8>& reply_data)
GetPingInfoResponse_to_SceNpMatching2SignalingGetPingInfoResponse(resp, final_ping_resp);
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SignalingGetPingInfo, event_key, 0, sizeof(SceNpMatching2SignalingGetPingInfoResponse), cb_info.cb_arg);
return 0;
});
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SignalingGetPingInfo, event_key, 0, sizeof(SceNpMatching2SignalingGetPingInfoResponse), cb_info.cb_arg);
return 0;
});
return true;
}
bool np_handler::reply_send_room_message(u32 req_id, std::vector<u8>& /*reply_data*/)
{
if (pending_requests.count(req_id) == 0)
return error_and_disconnect("Unexpected reply ID to PingRoomOwner");
const auto cb_info = std::move(pending_requests.at(req_id));
pending_requests.erase(req_id);
const auto cb_info = take_pending_request(req_id);
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SendRoomMessage, 0, 0, 0, cb_info.cb_arg);
return 0;
});
{
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SendRoomMessage, 0, 0, 0, cb_info.cb_arg);
return 0;
});
return true;
}
bool np_handler::reply_req_sign_infos(u32 req_id, std::vector<u8>& reply_data)
{
if (!pending_sign_infos_requests.count(req_id))
return error_and_disconnect("Unexpected reply ID to req RequestSignalingInfos");
u32 conn_id = pending_sign_infos_requests.at(req_id);
pending_sign_infos_requests.erase(req_id);
u32 conn_id;
{
std::lock_guard lock(mutex_pending_sign_infos_requests);
conn_id = pending_sign_infos_requests.at(req_id);
pending_sign_infos_requests.erase(req_id);
}
vec_stream reply(reply_data, 1);
u32 addr = reply.get<u32>();
@ -1056,16 +1184,16 @@ bool np_handler::reply_req_ticket(u32 /*req_id*/, std::vector<u8>& reply_data)
if (reply.is_error())
return error_and_disconnect("Malformed reply to RequestTicket command");
current_ticket = std::move(ticket_raw);
current_ticket = std::move(ticket_raw);
auto ticket_size = static_cast<s32>(current_ticket.size());
if (manager_cb)
{
sysutil_register_cb([manager_cb = this->manager_cb, ticket_size, manager_cb_arg = this->manager_cb_arg](ppu_thread& cb_ppu) -> s32
{
manager_cb(cb_ppu, SCE_NP_MANAGER_EVENT_GOT_TICKET, ticket_size, manager_cb_arg);
return 0;
});
{
manager_cb(cb_ppu, SCE_NP_MANAGER_EVENT_GOT_TICKET, ticket_size, manager_cb_arg);
return 0;
});
}
return true;
@ -1093,10 +1221,10 @@ void np_handler::notif_user_joined_room(std::vector<u8>& data)
extra_nps::print_room_member_data_internal(notif_data->roomMemberDataInternal.get_ptr());
sysutil_register_cb([room_event_cb = this->room_event_cb, room_id, event_key, room_event_cb_ctx = this->room_event_cb_ctx, room_event_cb_arg = this->room_event_cb_arg](ppu_thread& cb_ppu) -> s32
{
room_event_cb(cb_ppu, room_event_cb_ctx, room_id, SCE_NP_MATCHING2_ROOM_EVENT_MemberJoined, event_key, 0, sizeof(SceNpMatching2RoomMemberUpdateInfo), room_event_cb_arg);
return 0;
});
{
room_event_cb(cb_ppu, room_event_cb_ctx, room_id, SCE_NP_MATCHING2_ROOM_EVENT_MemberJoined, event_key, 0, sizeof(SceNpMatching2RoomMemberUpdateInfo), room_event_cb_arg);
return 0;
});
}
void np_handler::notif_user_left_room(std::vector<u8>& data)
@ -1121,10 +1249,10 @@ void np_handler::notif_user_left_room(std::vector<u8>& data)
extra_nps::print_room_member_data_internal(notif_data->roomMemberDataInternal.get_ptr());
sysutil_register_cb([room_event_cb = this->room_event_cb, room_event_cb_ctx = this->room_event_cb_ctx, room_id, event_key, room_event_cb_arg = this->room_event_cb_arg](ppu_thread& cb_ppu) -> s32
{
room_event_cb(cb_ppu, room_event_cb_ctx, room_id, SCE_NP_MATCHING2_ROOM_EVENT_MemberLeft, event_key, 0, sizeof(SceNpMatching2RoomMemberUpdateInfo), room_event_cb_arg);
return 0;
});
{
room_event_cb(cb_ppu, room_event_cb_ctx, room_id, SCE_NP_MATCHING2_ROOM_EVENT_MemberLeft, event_key, 0, sizeof(SceNpMatching2RoomMemberUpdateInfo), room_event_cb_arg);
return 0;
});
}
void np_handler::notif_room_destroyed(std::vector<u8>& data)
@ -1151,10 +1279,10 @@ void np_handler::notif_room_destroyed(std::vector<u8>& data)
sigh.disconnect_sig2_users(room_id);
sysutil_register_cb([room_event_cb = this->room_event_cb, room_event_cb_ctx = this->room_event_cb_ctx, room_id, event_key, room_event_cb_arg = this->room_event_cb_arg](ppu_thread& cb_ppu) -> s32
{
room_event_cb(cb_ppu, room_event_cb_ctx, room_id, SCE_NP_MATCHING2_ROOM_EVENT_RoomDestroyed, event_key, 0, sizeof(SceNpMatching2RoomUpdateInfo), room_event_cb_arg);
return 0;
});
{
room_event_cb(cb_ppu, room_event_cb_ctx, room_id, SCE_NP_MATCHING2_ROOM_EVENT_RoomDestroyed, event_key, 0, sizeof(SceNpMatching2RoomUpdateInfo), room_event_cb_arg);
return 0;
});
}
void np_handler::notif_p2p_connect(std::vector<u8>& data)
@ -1165,10 +1293,10 @@ void np_handler::notif_p2p_connect(std::vector<u8>& data)
return;
}
const u64 room_id = reinterpret_cast<le_t<u64>&>(data[0]);
const u16 member_id = reinterpret_cast<le_t<u16>&>(data[8]);
const u16 port_p2p = reinterpret_cast<be_t<u16>&>(data[10]);
const u32 addr_p2p = reinterpret_cast<le_t<u32>&>(data[12]);
const u64 room_id = reinterpret_cast<le_t<u64>&>(data[0]);
const u16 member_id = reinterpret_cast<le_t<u16>&>(data[8]);
const u16 port_p2p = reinterpret_cast<be_t<u16>&>(data[10]);
const u32 addr_p2p = reinterpret_cast<le_t<u32>&>(data[12]);
rpcn_log.notice("Received notification to connect to member(%d) of room(%d): %s:%d", member_id, room_id, ip_to_string(addr_p2p), port_p2p);
@ -1193,7 +1321,7 @@ void np_handler::notif_room_message_received(std::vector<u8>& data)
u32 event_key = get_event_key();
auto message_info = flatbuffers::GetRoot<RoomMessageInfo>(message_info_raw.data());
auto message_info = flatbuffers::GetRoot<RoomMessageInfo>(message_info_raw.data());
SceNpMatching2RoomMessageInfo* notif_data = reinterpret_cast<SceNpMatching2RoomMessageInfo*>(allocate_req_result(event_key, sizeof(SceNpMatching2RoomMessageInfo)));
RoomMessageInfo_to_SceNpMatching2RoomMessageInfo(message_info, notif_data);
@ -1202,10 +1330,10 @@ void np_handler::notif_room_message_received(std::vector<u8>& data)
if (room_msg_cb)
{
sysutil_register_cb([room_msg_cb = this->room_msg_cb, room_msg_cb_ctx = this->room_msg_cb_ctx, room_id, member_id, event_key, room_msg_cb_arg = this->room_msg_cb_arg](ppu_thread& cb_ppu) -> s32
{
room_msg_cb(cb_ppu, room_msg_cb_ctx, room_id, member_id, SCE_NP_MATCHING2_ROOM_MSG_EVENT_Message, event_key, 0, sizeof(SceNpMatching2RoomUpdateInfo), room_msg_cb_arg);
return 0;
});
{
room_msg_cb(cb_ppu, room_msg_cb_ctx, room_id, member_id, SCE_NP_MATCHING2_ROOM_MSG_EVENT_Message, event_key, 0, sizeof(SceNpMatching2RoomUpdateInfo), room_msg_cb_arg);
return 0;
});
}
}
@ -1338,7 +1466,7 @@ s32 np_handler::analyze_dns_packet(s32 s, const u8* buf, u32 len)
bool np_handler::error_and_disconnect(const std::string& error_msg)
{
rpcn_log.error("%s", error_msg);
rpcn.disconnect();
rpcn.reset();
return false;
}
@ -1358,11 +1486,24 @@ u32 np_handler::generate_callback_info(SceNpMatching2ContextId ctx_id, vm::cptr<
nph_log.warning("Callback used is 0x%x", ret.cb);
pending_requests[req_id] = std::move(ret);
{
std::lock_guard lock(mutex_pending_requests);
pending_requests[req_id] = std::move(ret);
}
return req_id;
}
np_handler::callback_info np_handler::take_pending_request(u32 req_id)
{
std::lock_guard lock(mutex_pending_requests);
const auto cb_info = std::move(pending_requests.at(req_id));
pending_requests.erase(req_id);
return cb_info;
}
u8* np_handler::allocate_req_result(u32 event_key, usz size)
{
std::lock_guard lock(mutex_req_results);
@ -1385,3 +1526,13 @@ u32 np_handler::add_players_to_history(vm::cptr<SceNpId> /*npids*/, u32 /*count*
return req_id;
}
u32 np_handler::get_num_friends()
{
return rpcn->get_num_friends();
}
u32 np_handler::get_num_blocks()
{
return rpcn->get_num_blocks();
}