NP: Cache Manager + improvements

This commit is contained in:
RipleyTom 2021-11-03 00:53:57 +01:00 committed by kd-11
parent 516cb959cb
commit d41e405420
17 changed files with 845 additions and 218 deletions

View File

@ -375,7 +375,9 @@ target_sources(rpcs3_emu PRIVATE
# Np
target_sources(rpcs3_emu PRIVATE
NP/fb_helpers.cpp
NP/np_cache.cpp
NP/np_contexts.cpp
NP/np_dnshook.cpp
NP/np_handler.cpp
NP/np_helpers.cpp
NP/np_notifications.cpp

View File

@ -680,7 +680,7 @@ error_code sceNpBasicRegisterHandler(vm::cptr<SceNpCommunicationId> context, vm:
error_code sceNpBasicRegisterContextSensitiveHandler(vm::cptr<SceNpCommunicationId> context, vm::ptr<SceNpBasicEventHandler> handler, vm::ptr<void> arg)
{
sceNp.todo("sceNpBasicRegisterContextSensitiveHandler(context=*0x%x, handler=*0x%x, arg=*0x%x)", context, handler, arg);
sceNp.notice("sceNpBasicRegisterContextSensitiveHandler(context=*0x%x, handler=*0x%x, arg=*0x%x)", context, handler, arg);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();

View File

@ -755,7 +755,7 @@ error_code sceNpMatching2GetEventData(SceNpMatching2ContextId ctxId, SceNpMatchi
error_code sceNpMatching2GetRoomSlotInfoLocal(SceNpMatching2ContextId ctxId, const SceNpMatching2RoomId roomId, vm::ptr<SceNpMatching2RoomSlotInfo> roomSlotInfo)
{
sceNp2.todo("sceNpMatching2GetRoomSlotInfoLocal(ctxId=%d, roomId=%d, roomSlotInfo=*0x%x)", ctxId, roomId, roomSlotInfo);
sceNp2.notice("sceNpMatching2GetRoomSlotInfoLocal(ctxId=%d, roomId=%d, roomSlotInfo=*0x%x)", ctxId, roomId, roomSlotInfo);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
@ -764,6 +764,30 @@ error_code sceNpMatching2GetRoomSlotInfoLocal(SceNpMatching2ContextId ctxId, con
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!ctxId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID;
}
if (!roomId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ROOM_ID;
}
if (!check_match2_context(ctxId))
{
return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_FOUND;
}
const auto [error, slots] = nph.local_get_room_slots(roomId);
if (error)
{
return error;
}
memcpy(roomSlotInfo.get_ptr(), &slots.value(), sizeof(SceNpMatching2RoomSlotInfo));
return CELL_OK;
}
@ -797,7 +821,7 @@ error_code sceNpMatching2AbortContextStart(SceNpMatching2ContextId ctxId)
error_code sceNpMatching2GetRoomMemberIdListLocal(SceNpMatching2ContextId ctxId, SceNpMatching2RoomId roomId, s32 sortMethod, vm::ptr<SceNpMatching2RoomMemberId> memberId, u32 memberIdNum)
{
sceNp2.todo("sceNpMatching2GetRoomMemberIdListLocal(ctxId=%d, roomId=%d, sortMethod=%d, memberId=*0x%x, memberIdNum=%d)", ctxId, roomId, sortMethod, memberId, memberIdNum);
sceNp2.notice("sceNpMatching2GetRoomMemberIdListLocal(ctxId=%d, roomId=%d, sortMethod=%d, memberId=*0x%x, memberIdNum=%d)", ctxId, roomId, sortMethod, memberId, memberIdNum);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
@ -806,7 +830,41 @@ error_code sceNpMatching2GetRoomMemberIdListLocal(SceNpMatching2ContextId ctxId,
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
return CELL_OK;
if (!ctxId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID;
}
if (!roomId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ROOM_ID;
}
if (sortMethod != SCE_NP_MATCHING2_SORT_METHOD_JOIN_DATE && sortMethod != SCE_NP_MATCHING2_SORT_METHOD_SLOT_NUMBER)
{
return SCE_NP_MATCHING2_ERROR_INVALID_SORT_METHOD;
}
if (!check_match2_context(ctxId))
{
return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_FOUND;
}
const auto [error, vec_memberids] = nph.local_get_room_memberids(roomId, sortMethod);
if (error)
{
return error;
}
u32 num_members = std::min(memberIdNum, static_cast<u32>(vec_memberids.size()));
for (u32 i = 0; i < num_members; i++)
{
memberId[i] = vec_memberids[i];
}
return not_an_error(num_members);
}
error_code sceNpMatching2JoinRoom(
@ -828,7 +886,7 @@ error_code sceNpMatching2JoinRoom(
error_code sceNpMatching2GetRoomMemberDataInternalLocal(SceNpMatching2ContextId ctxId, SceNpMatching2RoomId roomId, SceNpMatching2RoomMemberId memberId, vm::cptr<SceNpMatching2AttributeId> attrId,
u32 attrIdNum, vm::ptr<SceNpMatching2RoomMemberDataInternal> member, vm::ptr<char> buf, u64 bufLen)
{
sceNp2.todo("sceNpMatching2GetRoomMemberDataInternalLocal(ctxId=%d, roomId=%d, memberId=%d, attrId=*0x%x, attrIdNum=%d, member=*0x%x, buf=*0x%x, bufLen=%d)", ctxId, roomId, memberId, attrId,
sceNp2.warning("sceNpMatching2GetRoomMemberDataInternalLocal(ctxId=%d, roomId=%d, memberId=%d, attrId=*0x%x, attrIdNum=%d, member=*0x%x, buf=*0x%x, bufLen=%d)", ctxId, roomId, memberId, attrId,
attrIdNum, member, buf, bufLen);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
@ -838,7 +896,37 @@ error_code sceNpMatching2GetRoomMemberDataInternalLocal(SceNpMatching2ContextId
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
return CELL_OK;
if (!ctxId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID;
}
if (!roomId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ROOM_ID;
}
if (!memberId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_MEMBER_ID;
}
std::vector<SceNpMatching2AttributeId> binattrs_list;
for (u32 i = 0; i < attrIdNum; i++)
{
if (attrId[i] < SCE_NP_MATCHING2_ROOMMEMBER_BIN_ATTR_INTERNAL_1_ID || attrId[i] >= SCE_NP_MATCHING2_USER_BIN_ATTR_1_ID)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ATTRIBUTE_ID;
}
binattrs_list.push_back(attrId[i]);
}
if (!check_match2_context(ctxId))
{
return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_FOUND;
}
return nph.local_get_room_member_data(roomId, memberId, binattrs_list, member ? member.get_ptr() : nullptr, buf.addr(), bufLen);
}
error_code sceNpMatching2GetCbQueueInfo(SceNpMatching2ContextId ctxId, vm::ptr<SceNpMatching2CbQueueInfo> queueInfo)
@ -1005,7 +1093,7 @@ error_code sceNpMatching2SignalingGetPingInfo(
error_code sceNpMatching2GetServerIdListLocal(SceNpMatching2ContextId ctxId, vm::ptr<SceNpMatching2ServerId> serverId, u32 serverIdNum)
{
sceNp2.todo("sceNpMatching2GetServerIdListLocal(ctxId=%d, serverId=*0x%x, serverIdNum=%d)", ctxId, serverId, serverIdNum);
sceNp2.notice("sceNpMatching2GetServerIdListLocal(ctxId=%d, serverId=*0x%x, serverIdNum=%d)", ctxId, serverId, serverIdNum);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
@ -1267,7 +1355,7 @@ error_code sceNpMatching2RegisterRoomEventCallback(SceNpMatching2ContextId ctxId
error_code sceNpMatching2GetRoomPasswordLocal(SceNpMatching2ContextId ctxId, SceNpMatching2RoomId roomId, vm::ptr<b8> withPassword, vm::ptr<SceNpMatching2SessionPassword> roomPassword)
{
sceNp2.todo("sceNpMatching2GetRoomPasswordLocal(ctxId=%d, roomId=%d, withPassword=*0x%x, roomPassword=*0x%x)", ctxId, roomId, withPassword, roomPassword);
sceNp2.notice("sceNpMatching2GetRoomPasswordLocal(ctxId=%d, roomId=%d, withPassword=*0x%x, roomPassword=*0x%x)", ctxId, roomId, withPassword, roomPassword);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
@ -1276,6 +1364,38 @@ error_code sceNpMatching2GetRoomPasswordLocal(SceNpMatching2ContextId ctxId, Sce
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!ctxId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID;
}
if (!roomId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ROOM_ID;
}
if (!check_match2_context(ctxId))
{
return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_FOUND;
}
const auto [error, password] = nph.local_get_room_password(roomId);
if (error)
{
return error;
}
if (password)
{
*withPassword = true;
memcpy(roomPassword.get_ptr(), &*password, sizeof(SceNpMatching2SessionPassword));
}
else
{
*withPassword = false;
}
return CELL_OK;
}

View File

@ -24,6 +24,7 @@
#endif
#include "Emu/NP/np_handler.h"
#include "Emu/NP/np_dnshook.h"
#include <chrono>
#include <shared_mutex>
@ -1695,6 +1696,7 @@ error_code sys_net_bnet_connect(ppu_thread& ppu, s32 s, vm::ptr<sys_net_sockaddr
if (psa_in->sin_port == 53)
{
auto& dnshook = g_fxo->get<np::dnshook>();
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
// Hack for DNS
@ -1703,7 +1705,7 @@ error_code sys_net_bnet_connect(ppu_thread& ppu, s32 s, vm::ptr<sys_net_sockaddr
sys_net.notice("sys_net_bnet_connect: using DNS...");
nph.add_dns_spy(s);
dnshook.add_dns_spy(s);
}
else if (_addr->sa_family != SYS_NET_AF_INET)
{
@ -2286,10 +2288,12 @@ error_code sys_net_bnet_recvfrom(ppu_thread& ppu, s32 s, vm::ptr<void> buf, u32
//if (!(sock.events & lv2_socket::poll::read))
{
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
if (nph.is_dns(s) && nph.is_dns_queue(s))
auto& dnshook = g_fxo->get<np::dnshook>();
if (dnshook.is_dns(s) && dnshook.is_dns_queue(s))
{
const auto packet = nph.get_dns_packet(s);
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
const auto packet = dnshook.get_dns_packet(s);
ensure(packet.size() < len);
memcpy(buf.get_ptr(), packet.data(), packet.size());
@ -2708,17 +2712,18 @@ error_code sys_net_bnet_sendto(ppu_thread& ppu, s32 s, vm::cptr<void> buf, u32 l
//if (!(sock.events & lv2_socket::poll::write))
{
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
auto& dnshook = g_fxo->get<np::dnshook>();
if (addr && type == SYS_NET_SOCK_DGRAM && psa_in->sin_port == 53)
{
nph.add_dns_spy(s);
dnshook.add_dns_spy(s);
}
if (nph.is_dns(s))
if (dnshook.is_dns(s))
{
const s32 ret_analyzer = nph.analyze_dns_packet(s, reinterpret_cast<const u8*>(_buf.data()), len);
const s32 ret_analyzer = dnshook.analyze_dns_packet(s, reinterpret_cast<const u8*>(_buf.data()), len);
// If we're not connected just never send the packet and pretend we did
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
if (!nph.get_net_status())
{
native_result = data_len;
@ -3217,8 +3222,8 @@ error_code sys_net_bnet_close(ppu_thread& ppu, s32 s)
}
}
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
nph.remove_dns_spy(s);
auto& dnshook = g_fxo->get<np::dnshook>();
dnshook.remove_dns_spy(s);
return CELL_OK;
}
@ -3309,8 +3314,8 @@ error_code sys_net_bnet_poll(ppu_thread& ppu, vm::ptr<sys_net_pollfd> fds, s32 n
else
{
// Check for fake packet for dns interceptions
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
if (fds_buf[i].events & SYS_NET_POLLIN && nph.is_dns(fds_buf[i].fd) && nph.is_dns_queue(fds_buf[i].fd))
auto& dnshook = g_fxo->get<np::dnshook>();
if (fds_buf[i].events & SYS_NET_POLLIN && dnshook.is_dns(fds_buf[i].fd) && dnshook.is_dns_queue(fds_buf[i].fd))
fds_buf[i].revents |= SYS_NET_POLLIN;
if (fds_buf[i].events & ~(SYS_NET_POLLIN | SYS_NET_POLLOUT | SYS_NET_POLLERR))

View File

@ -189,7 +189,6 @@ namespace np
room_info->roomId = resp->roomId();
room_info->passwordSlotMask = resp->passwordSlotMask();
room_info->maxSlot = resp->maxSlot();
room_info->memberList.membersNum = resp->memberList()->size();
if (resp->roomGroup() && resp->roomGroup()->size() != 0)
{
@ -199,32 +198,43 @@ namespace np
}
room_info->memberList.membersNum = static_cast<u32>(resp->memberList()->size());
edata.allocate<SceNpMatching2RoomMemberDataInternal>(sizeof(SceNpMatching2RoomMemberDataInternal) * room_info->memberList.membersNum, room_info->memberList.members);
SceNpMatching2RoomMemberDataInternal* prev_member = nullptr;
for (flatbuffers::uoffset_t i = 0; i < resp->memberList()->size(); i++)
{
auto fb_member = resp->memberList()->Get(i);
SceNpMatching2RoomMemberDataInternal* member_info;
SceNpMatching2RoomMemberDataInternal* sce_member = &room_info->memberList.members[i];
member_info = (i > 0) ? edata.allocate<SceNpMatching2RoomMemberDataInternal>(sizeof(SceNpMatching2RoomMemberDataInternal), prev_member->next) :
edata.allocate<SceNpMatching2RoomMemberDataInternal>(sizeof(SceNpMatching2RoomMemberDataInternal), room_info->memberList.members);
RoomMemberDataInternal_to_SceNpMatching2RoomMemberDataInternal(edata, fb_member, room_info, member_info);
if (strcmp(member_info->userInfo.npId.handle.data, npid.handle.data) == 0)
if (i < (resp->memberList()->size() - 1))
{
room_info->memberList.me = (i > 0) ? prev_member->next : room_info->memberList.members;
sce_member->next = room_info->memberList.members + i + 1;
edata.add_relocation<SceNpMatching2RoomMemberDataInternal>(sce_member->next);
}
RoomMemberDataInternal_to_SceNpMatching2RoomMemberDataInternal(edata, fb_member, room_info, sce_member);
}
for (u32 i = 0; i < room_info->memberList.membersNum; i++)
{
SceNpMatching2RoomMemberDataInternal* sce_member = &room_info->memberList.members[i];
if (strcmp(sce_member->userInfo.npId.handle.data, npid.handle.data) == 0)
{
room_info->memberList.me = room_info->memberList.members + i;
edata.add_relocation<SceNpMatching2RoomMemberDataInternal>(room_info->memberList.me);
member_id = member_info->memberId;
member_id = sce_member->memberId;
break;
}
}
if (member_info->memberId == resp->ownerId())
for (u32 i = 0; i < room_info->memberList.membersNum; i++)
{
room_info->memberList.owner = (i > 0) ? prev_member->next : room_info->memberList.members;
SceNpMatching2RoomMemberDataInternal* sce_member = &room_info->memberList.members[i];
if (sce_member->memberId == resp->ownerId())
{
room_info->memberList.owner = room_info->memberList.members + i;
edata.add_relocation<SceNpMatching2RoomMemberDataInternal>(room_info->memberList.owner);
break;
}
prev_member = member_info;
}
room_info->flagAttr = resp->flagAttr();

View File

@ -88,11 +88,14 @@ namespace np
void free(u32 addr)
{
std::lock_guard lock(m_mutex);
ensure(addr >= m_pool.addr() && addr < (m_pool.addr() + m_size), "memory_allocator::free: addr is out of bounds!");
const u32 offset = addr - m_pool.addr();
ensure(m_allocs.contains(offset), "memory_allocator::free: m_allocs doesn't contain the allocation!");
m_avail += m_allocs.at(offset);
m_allocs.erase(offset);
}
@ -106,6 +109,7 @@ namespace np
ensure(m_allocs.contains(offset), "memory_allocator::reduce_allocation: m_allocs doesn't contain the allocation!");
ensure(m_allocs[offset] >= new_size, "memory_allocator::reduce_allocation: New size is bigger than current allocation!");
m_avail += (m_allocs.at(offset) - new_size);
m_allocs[offset] = new_size;
}

302
rpcs3/Emu/NP/np_cache.cpp Normal file
View File

@ -0,0 +1,302 @@
#include "stdafx.h"
#include <bit>
#include "np_allocator.h"
#include "np_cache.h"
namespace np
{
memberbin_cache::memberbin_cache(SceNpMatching2RoomMemberBinAttrInternal* sce_memberbin)
{
id = sce_memberbin->data.id;
updateDate.tick = sce_memberbin->updateDate.tick;
data.resize(sce_memberbin->data.size);
memcpy(data.data(), sce_memberbin->data.ptr.get_ptr(), sce_memberbin->data.size);
}
member_cache::member_cache(const SceNpMatching2RoomMemberDataInternal* sce_member)
{
userInfo.npId = sce_member->userInfo.npId;
if (sce_member->userInfo.onlineName)
{
userInfo.onlineName = *sce_member->userInfo.onlineName;
}
if (sce_member->userInfo.avatarUrl)
{
userInfo.avatarUrl = *sce_member->userInfo.avatarUrl;
}
joinDate.tick = sce_member->joinDate.tick;
memberId = sce_member->memberId;
teamId = sce_member->teamId;
if (sce_member->roomGroup)
{
group_id = sce_member->roomGroup->groupId;
}
else
{
group_id = 0;
}
natType = sce_member->natType;
flagAttr = sce_member->flagAttr;
for (u32 i = 0; i < sce_member->roomMemberBinAttrInternalNum; i++)
{
bins.insert_or_assign(sce_member->roomMemberBinAttrInternal[i].data.id, memberbin_cache(&sce_member->roomMemberBinAttrInternal[i]));
}
}
void room_cache::update(const SceNpMatching2RoomDataInternal* sce_roomdata)
{
num_slots = sce_roomdata->maxSlot;
mask_password = sce_roomdata->passwordSlotMask;
groups.clear();
for (u32 i = 0; i < sce_roomdata->roomGroupNum; i++)
{
const SceNpMatching2RoomGroup* sce_group = &sce_roomdata->roomGroup[i];
memcpy(&groups[sce_group->groupId], sce_group, sizeof(SceNpMatching2RoomGroup));
}
members.clear();
vm::bptr<SceNpMatching2RoomMemberDataInternal> sce_member = sce_roomdata->memberList.members;
while (sce_member)
{
members.insert_or_assign(sce_member->memberId, member_cache(sce_member.get_ptr()));
sce_member = sce_member->next;
}
if (sce_roomdata->memberList.me == sce_roomdata->memberList.owner)
{
owner = true;
}
}
void cache_manager::insert_room(const SceNpMatching2RoomDataInternal* sce_roomdata)
{
std::lock_guard lock(mutex);
rooms[sce_roomdata->roomId].update(sce_roomdata);
}
void cache_manager::add_member(SceNpMatching2RoomId room_id, const SceNpMatching2RoomMemberDataInternal* sce_roommemberdata)
{
std::lock_guard lock(mutex);
ensure(rooms.contains(room_id), "cache_manager::add_member: Room not cached!");
rooms[room_id].members.insert_or_assign(sce_roommemberdata->memberId, member_cache(sce_roommemberdata));
}
void cache_manager::del_member(SceNpMatching2RoomId room_id, SceNpMatching2RoomMemberId member_id)
{
std::lock_guard lock(mutex);
ensure(rooms.contains(room_id), "cache_manager::del_member: Room not cached!");
rooms.erase(member_id);
}
void cache_manager::update_password(SceNpMatching2RoomId room_id, const std::optional<SceNpMatching2SessionPassword>& password)
{
std::lock_guard lock(mutex);
rooms[room_id].password = password;
}
std::pair<error_code, std::optional<SceNpMatching2RoomSlotInfo>> cache_manager::get_slots(SceNpMatching2RoomId room_id)
{
std::lock_guard lock(mutex);
if (!rooms.contains(room_id))
{
return {SCE_NP_MATCHING2_ERROR_ROOM_NOT_FOUND, {}};
}
const auto& room = rooms[room_id];
SceNpMatching2RoomSlotInfo slots;
slots.roomId = room_id;
SceNpMatching2RoomJoinedSlotMask join_mask = 0;
for (const auto& member : room.members)
{
join_mask |= (1 << (member.first - 1));
}
slots.joinedSlotMask = join_mask;
slots.passwordSlotMask = room.mask_password;
u64 joinable_slot_mask = (static_cast<u64>(1) << room.num_slots) - 1;
u16 num_private_slots = std::popcount(room.mask_password & joinable_slot_mask);
u16 num_public_slots = room.num_slots - num_private_slots;
slots.publicSlotNum = num_public_slots;
slots.privateSlotNum = num_private_slots;
u16 open_private_slots = num_private_slots - std::popcount(join_mask & room.mask_password);
u16 open_public_slots = num_public_slots - std::popcount(join_mask & (~room.mask_password));
slots.openPublicSlotNum = open_public_slots;
slots.openPrivateSlotNum = open_private_slots;
return {CELL_OK, slots};
}
std::pair<error_code, std::vector<SceNpMatching2RoomMemberId>> cache_manager::get_memberids(u64 room_id, s32 sort_method)
{
std::lock_guard lock(mutex);
if (!rooms.contains(room_id))
{
return {SCE_NP_MATCHING2_ERROR_ROOM_NOT_FOUND, {}};
}
const auto& room = rooms[room_id];
std::vector<SceNpMatching2RoomMemberId> vec_memberids;
switch (sort_method)
{
case SCE_NP_MATCHING2_SORT_METHOD_SLOT_NUMBER:
{
for (const auto& member : room.members)
{
vec_memberids.push_back(member.first);
}
break;
}
case SCE_NP_MATCHING2_SORT_METHOD_JOIN_DATE:
{
std::map<u64, u16> map_joindate_id;
for (const auto& member : room.members)
{
map_joindate_id.insert(std::make_pair(member.second.joinDate.tick, member.first));
}
for (const auto& member : map_joindate_id)
{
vec_memberids.push_back(member.second);
}
break;
}
default: fmt::throw_exception("Unreachable");
}
return {CELL_OK, vec_memberids};
}
std::pair<error_code, std::optional<SceNpMatching2SessionPassword>> cache_manager::get_password(SceNpMatching2RoomId room_id)
{
std::lock_guard lock(mutex);
if (!rooms.contains(room_id))
{
return {SCE_NP_MATCHING2_ERROR_ROOM_NOT_FOUND, {}};
}
if (!rooms[room_id].owner)
{
return {SCE_NP_MATCHING2_ERROR_NOT_ALLOWED, {}};
}
return {CELL_OK, rooms[room_id].password};
}
error_code cache_manager::get_member_and_attrs(SceNpMatching2RoomId room_id, SceNpMatching2RoomMemberId member_id, const std::vector<SceNpMatching2AttributeId>& binattrs_list, SceNpMatching2RoomMemberDataInternal* ptr_member, u32 addr_data, u32 size_data)
{
std::lock_guard lock(mutex);
if (!rooms.contains(room_id))
{
return SCE_NP_MATCHING2_ERROR_ROOM_NOT_FOUND;
}
if (!rooms[room_id].members.contains(member_id))
{
return SCE_NP_MATCHING2_ERROR_ROOM_MEMBER_NOT_FOUND;
}
const auto& room = rooms.at(room_id);
const auto& member = room.members.at(member_id);
if (ptr_member)
{
memset(ptr_member, 0, sizeof(SceNpMatching2RoomMemberDataInternal));
memcpy(&ptr_member->userInfo.npId, &member.userInfo.npId, sizeof(SceNpId));
ptr_member->joinDate.tick = member.joinDate.tick;
ptr_member->memberId = member.memberId;
ptr_member->teamId = member.teamId;
ptr_member->natType = member.natType;
ptr_member->flagAttr = member.flagAttr;
}
const u32 needed_data_size = sizeof(SceNpOnlineName) + sizeof(SceNpAvatarUrl) + sizeof(SceNpMatching2RoomGroup) +
(binattrs_list.size() * (sizeof(SceNpMatching2RoomMemberBinAttrInternal) + SCE_NP_MATCHING2_ROOMMEMBER_BIN_ATTR_INTERNAL_MAX_SIZE));
if (!addr_data || !ptr_member)
{
return needed_data_size;
}
if (size_data < needed_data_size)
{
return SCE_NP_MATCHING2_ERROR_INSUFFICIENT_BUFFER;
}
memory_allocator mem;
mem.setup(vm::ptr<void>(vm::cast(addr_data)), size_data);
if (member.userInfo.onlineName)
{
ptr_member->userInfo.onlineName.set(mem.allocate(sizeof(SceNpOnlineName)));
memcpy(ptr_member->userInfo.onlineName.get_ptr(), &member.userInfo.onlineName.value(), sizeof(SceNpOnlineName));
}
if (member.userInfo.avatarUrl)
{
ptr_member->userInfo.avatarUrl.set(mem.allocate(sizeof(SceNpAvatarUrl)));
memcpy(ptr_member->userInfo.avatarUrl.get_ptr(), &member.userInfo.avatarUrl.value(), sizeof(SceNpAvatarUrl));
}
if (member.group_id)
{
ptr_member->roomGroup.set(mem.allocate(sizeof(SceNpMatching2RoomGroup)));
memcpy(ptr_member->roomGroup.get_ptr(), &room.groups.at(member.group_id), sizeof(SceNpMatching2RoomGroup));
}
u32 num_binattrs = 0;
for (u32 i = 0; i < binattrs_list.size(); i++)
{
if (member.bins.contains(binattrs_list[i]))
{
num_binattrs++;
}
}
if (num_binattrs)
{
ptr_member->roomMemberBinAttrInternal.set(mem.allocate(sizeof(SceNpMatching2RoomMemberBinAttrInternal) * num_binattrs));
ptr_member->roomMemberBinAttrInternalNum = num_binattrs;
SceNpMatching2RoomMemberBinAttrInternal* bin_ptr = ptr_member->roomMemberBinAttrInternal.get_ptr();
u32 actual_cnt = 0;
for (u32 i = 0; i < binattrs_list.size(); i++)
{
if (member.bins.contains(binattrs_list[i]))
{
const auto& bin = member.bins.at(binattrs_list[i]);
bin_ptr[actual_cnt].updateDate.tick = bin.updateDate.tick;
bin_ptr[actual_cnt].data.id = bin.id;
bin_ptr[actual_cnt].data.size = bin.data.size();
bin_ptr[actual_cnt].data.ptr.set(mem.allocate(bin.data.size()));
memcpy(bin_ptr[actual_cnt].data.ptr.get_ptr(), bin.data.data(), bin.data.size());
actual_cnt++;
}
}
}
return needed_data_size;
}
} // namespace np

83
rpcs3/Emu/NP/np_cache.h Normal file
View File

@ -0,0 +1,83 @@
#pragma once
#include <map>
#include <optional>
#include "Utilities/mutex.h"
#include "Emu/Cell/Modules/sceNp.h"
#include "Emu/Cell/Modules/sceNp2.h"
namespace np
{
struct userinfo_cache
{
SceNpId npId;
std::optional<SceNpOnlineName> onlineName;
std::optional<SceNpAvatarUrl> avatarUrl;
};
struct memberbin_cache
{
memberbin_cache(SceNpMatching2RoomMemberBinAttrInternal* sce_memberbin);
SceNpMatching2AttributeId id;
CellRtcTick updateDate;
std::vector<u8> data;
};
struct member_cache
{
member_cache(const SceNpMatching2RoomMemberDataInternal* sce_member);
userinfo_cache userInfo;
CellRtcTick joinDate;
SceNpMatching2RoomMemberId memberId;
SceNpMatching2TeamId teamId;
SceNpMatching2RoomGroupId group_id;
SceNpMatching2NatType natType;
SceNpMatching2FlagAttr flagAttr;
std::map<SceNpMatching2AttributeId, memberbin_cache> bins;
};
struct password_info_cache
{
bool with_password = false;
SceNpMatching2SessionPassword password{};
};
struct room_cache
{
void update(const SceNpMatching2RoomDataInternal* sce_roomdata);
u32 num_slots = 0;
SceNpMatching2RoomPasswordSlotMask mask_password = 0;
std::optional<SceNpMatching2SessionPassword> password;
std::map<SceNpMatching2RoomGroupId, SceNpMatching2RoomGroup> groups;
std::map<SceNpMatching2RoomMemberId, member_cache> members;
bool owner = false;
};
class cache_manager
{
public:
cache_manager() = default;
void insert_room(const SceNpMatching2RoomDataInternal* sce_roomdata);
void add_member(SceNpMatching2RoomId room_id, const SceNpMatching2RoomMemberDataInternal* sce_roommemberdata);
void del_member(SceNpMatching2RoomId room_id, SceNpMatching2RoomMemberId member_id);
void update_password(SceNpMatching2RoomId room_id, const std::optional<SceNpMatching2SessionPassword>& password);
std::pair<error_code, std::optional<SceNpMatching2RoomSlotInfo>> get_slots(SceNpMatching2RoomId room_id);
std::pair<error_code, std::vector<SceNpMatching2RoomMemberId>> get_memberids(u64 room_id, s32 sort_method);
std::pair<error_code, std::optional<SceNpMatching2SessionPassword>> get_password(SceNpMatching2RoomId room_id);
error_code get_member_and_attrs(SceNpMatching2RoomId room_id, SceNpMatching2RoomMemberId member_id, const std::vector<SceNpMatching2AttributeId>& binattrs_list, SceNpMatching2RoomMemberDataInternal* ptr_member, u32 addr_data, u32 size_data);
private:
shared_mutex mutex;
std::map<SceNpMatching2RoomId, room_cache> rooms;
};
} // namespace np

174
rpcs3/Emu/NP/np_dnshook.cpp Normal file
View File

@ -0,0 +1,174 @@
#include "stdafx.h"
#include "np_dnshook.h"
#include "Emu/system_config.h"
#include "Utilities/StrUtil.h"
#include "util/logs.hpp"
#ifdef _WIN32
#include <WS2tcpip.h>
#else
#include <sys/socket.h>
#include <arpa/inet.h>
#endif
LOG_CHANNEL(dnshook_log, "DnsHook");
namespace np
{
dnshook::dnshook()
{
// Init switch map for dns
auto swaps = fmt::split(g_cfg.net.swap_list.to_string(), {"&&"});
for (usz i = 0; i < swaps.size(); i++)
{
auto host_and_ip = fmt::split(swaps[i], {"="});
if (host_and_ip.size() != 2)
{
dnshook_log.error("Pattern <%s> contains more than one '='", swaps[i]);
continue;
}
in_addr conv;
if (!inet_pton(AF_INET, host_and_ip[1].c_str(), &conv))
{
dnshook_log.error("IP(%s) provided for %s in the switch list is invalid!", host_and_ip[1], host_and_ip[0]);
}
else
{
switch_map[host_and_ip[0]] = conv.s_addr;
}
}
}
void dnshook::add_dns_spy(u32 sock)
{
std::lock_guard lock(mutex);
dns_spylist.emplace(std::make_pair(sock, std::queue<std::vector<u8>>()));
}
void dnshook::remove_dns_spy(u32 sock)
{
std::lock_guard lock(mutex);
dns_spylist.erase(sock);
}
bool dnshook::is_dns(u32 sock)
{
std::lock_guard lock(mutex);
return dns_spylist.contains(sock);
}
bool dnshook::is_dns_queue(u32 sock)
{
std::lock_guard lock(mutex);
return !dns_spylist.at(sock).empty();
}
std::vector<u8> dnshook::get_dns_packet(u32 sock)
{
std::lock_guard lock(mutex);
auto ret_vec = std::move(dns_spylist.at(sock).front());
dns_spylist.at(sock).pop();
return ret_vec;
}
s32 dnshook::analyze_dns_packet(s32 s, const u8* buf, u32 len)
{
std::lock_guard lock(mutex);
if (dnshook_log.enabled == logs::level::trace)
{
std::string datrace;
const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
for (u32 index = 0; index < len; index++)
{
if ((index % 16) == 0)
datrace += '\n';
datrace += hex[(buf[index] >> 4) & 15];
datrace += hex[(buf[index]) & 15];
datrace += ' ';
}
dnshook_log.trace("DNS REQUEST: %s", datrace);
}
struct dns_header
{
u16 id; // identification number
u8 rd : 1; // recursion desired
u8 tc : 1; // truncated message
u8 aa : 1; // authoritive answer
u8 opcode : 4; // purpose of message
u8 qr : 1; // query/response flag
u8 rcode : 4; // response code
u8 cd : 1; // checking disabled
u8 ad : 1; // authenticated data
u8 z : 1; // its z! reserved
u8 ra : 1; // recursion available
be_t<u16> q_count; // number of question entries
be_t<u16> ans_count; // number of answer entries
be_t<u16> auth_count; // number of authority entries
be_t<u16> add_count; // number of resource entries
};
if (len < sizeof(dns_header))
return -1;
const dns_header* dhead = reinterpret_cast<const dns_header*>(buf);
// We are only looking for queries not truncated(todo?), only handle one dns query at a time(todo?)
if (dhead->qr != 0 || dhead->tc != 0 || dhead->q_count != 1 || dhead->ans_count != 0 || dhead->auth_count != 0 || dhead->add_count != 0)
return -1;
// Get the actual address
u8 count = 0;
std::string host{};
for (u32 i = sizeof(dns_header); (i < len) && buf[i] != 0; i++)
{
if (count == 0)
{
count = buf[i];
if (i != sizeof(dns_header))
{
host += '.';
}
}
else
{
host += static_cast<char>(buf[i]);
count--;
}
}
dnshook_log.warning("DNS query for %s", host);
if (switch_map.contains(host))
{
// design fake packet
std::vector<u8> fake(len);
memcpy(fake.data(), buf, len);
dns_header* fake_header = reinterpret_cast<dns_header*>(fake.data());
fake_header->qr = 1;
fake_header->ra = 1;
fake_header->ans_count = 1;
fake.insert(fake.end(), {0xC0, 0x0C}); // Ref to name in header
fake.insert(fake.end(), {0x00, 0x01}); // IPv4
fake.insert(fake.end(), {0x00, 0x01}); // Class?
fake.insert(fake.end(), {0x00, 0x00, 0x00, 0x3B}); // TTL
fake.insert(fake.end(), {0x00, 0x04}); // Size of data
u32 ip = switch_map[host];
u8* ptr_ip = reinterpret_cast<u8*>(&ip);
fake.insert(fake.end(), ptr_ip, ptr_ip + 4); // IP
dnshook_log.warning("Solving %s to %d.%d.%d.%d", host, ptr_ip[0], ptr_ip[1], ptr_ip[2], ptr_ip[3]);
dns_spylist[s].push(std::move(fake));
return len;
}
return -1;
}
} // namespace np

31
rpcs3/Emu/NP/np_dnshook.h Normal file
View File

@ -0,0 +1,31 @@
#pragma once
#include <map>
#include <queue>
#include <vector>
#include "util/types.hpp"
#include "Utilities/mutex.h"
namespace np
{
class dnshook
{
public:
dnshook();
void add_dns_spy(u32 sock);
void remove_dns_spy(u32 sock);
bool is_dns(u32 sock);
bool is_dns_queue(u32 sock);
std::vector<u8> get_dns_packet(u32 sock);
s32 analyze_dns_packet(s32 s, const u8* buf, u32 len);
private:
shared_mutex mutex;
std::map<s32, std::queue<std::vector<u8>>> dns_spylist{};
std::map<std::string, u32> switch_map{};
};
} // namespace np

View File

@ -75,28 +75,6 @@ namespace np
{
dns_ip = conv.s_addr;
}
// Init switch map for dns
auto swaps = fmt::split(g_cfg.net.swap_list.to_string(), {"&&"});
for (usz i = 0; i < swaps.size(); i++)
{
auto host_and_ip = fmt::split(swaps[i], {"="});
if (host_and_ip.size() != 2)
{
nph_log.error("Pattern <%s> contains more than one '='", swaps[i]);
continue;
}
in_addr conv;
if (!inet_pton(AF_INET, host_and_ip[1].c_str(), &conv))
{
nph_log.error("IP(%s) provided for %s in the switch list is invalid!", host_and_ip[1], host_and_ip[0]);
}
else
{
switch_map[host_and_ip[0]] = conv.s_addr;
}
}
}
}
@ -551,132 +529,6 @@ namespace np
}
}
void np_handler::add_dns_spy(u32 sock)
{
dns_spylist.emplace(std::make_pair(sock, std::queue<std::vector<u8>>()));
}
void np_handler::remove_dns_spy(u32 sock)
{
dns_spylist.erase(sock);
}
bool np_handler::is_dns(u32 sock) const
{
return dns_spylist.contains(sock);
}
bool np_handler::is_dns_queue(u32 sock) const
{
return !dns_spylist.at(sock).empty();
}
std::vector<u8> np_handler::get_dns_packet(u32 sock)
{
auto ret_vec = std::move(dns_spylist.at(sock).front());
dns_spylist.at(sock).pop();
return ret_vec;
}
s32 np_handler::analyze_dns_packet(s32 s, const u8* buf, u32 len)
{
if (sys_net.enabled == logs::level::trace)
{
std::string datrace;
const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
for (u32 index = 0; index < len; index++)
{
if ((index % 16) == 0)
datrace += '\n';
datrace += hex[(buf[index] >> 4) & 15];
datrace += hex[(buf[index]) & 15];
datrace += ' ';
}
sys_net.trace("DNS REQUEST: %s", datrace);
}
struct dns_header
{
u16 id; // identification number
u8 rd : 1; // recursion desired
u8 tc : 1; // truncated message
u8 aa : 1; // authoritive answer
u8 opcode : 4; // purpose of message
u8 qr : 1; // query/response flag
u8 rcode : 4; // response code
u8 cd : 1; // checking disabled
u8 ad : 1; // authenticated data
u8 z : 1; // its z! reserved
u8 ra : 1; // recursion available
be_t<u16> q_count; // number of question entries
be_t<u16> ans_count; // number of answer entries
be_t<u16> auth_count; // number of authority entries
be_t<u16> add_count; // number of resource entries
};
if (len < sizeof(dns_header))
return -1;
const dns_header* dhead = reinterpret_cast<const dns_header*>(buf);
// We are only looking for queries not truncated(todo?), only handle one dns query at a time(todo?)
if (dhead->qr != 0 || dhead->tc != 0 || dhead->q_count != 1 || dhead->ans_count != 0 || dhead->auth_count != 0 || dhead->add_count != 0)
return -1;
// Get the actual address
u8 count = 0;
std::string host{};
for (u32 i = sizeof(dns_header); (i < len) && buf[i] != 0; i++)
{
if (count == 0)
{
count = buf[i];
if (i != sizeof(dns_header))
{
host += '.';
}
}
else
{
host += static_cast<char>(buf[i]);
count--;
}
}
sys_net.warning("DNS query for %s", host);
if (switch_map.contains(host))
{
// design fake packet
std::vector<u8> fake(len);
memcpy(fake.data(), buf, len);
dns_header* fake_header = reinterpret_cast<dns_header*>(fake.data());
fake_header->qr = 1;
fake_header->ra = 1;
fake_header->ans_count = 1;
fake.insert(fake.end(), {0xC0, 0x0C}); // Ref to name in header
fake.insert(fake.end(), {0x00, 0x01}); // IPv4
fake.insert(fake.end(), {0x00, 0x01}); // Class?
fake.insert(fake.end(), {0x00, 0x00, 0x00, 0x3B}); // TTL
fake.insert(fake.end(), {0x00, 0x04}); // Size of data
u32 ip = switch_map[host];
u8* ptr_ip = reinterpret_cast<u8*>(&ip);
fake.insert(fake.end(), ptr_ip, ptr_ip + 4); // IP
sys_net.warning("Solving %s to %d.%d.%d.%d", host, ptr_ip[0], ptr_ip[1], ptr_ip[2], ptr_ip[3]);
dns_spylist[s].push(std::move(fake));
return len;
}
return -1;
}
bool np_handler::error_and_disconnect(const std::string& error_msg)
{
rpcn_log.error("%s", error_msg);
@ -751,4 +603,23 @@ namespace np
return rpcn->get_num_blocks();
}
std::pair<error_code, std::optional<SceNpMatching2SessionPassword>> np_handler::local_get_room_password(SceNpMatching2RoomId room_id)
{
return np_cache.get_password(room_id);
}
std::pair<error_code, std::optional<SceNpMatching2RoomSlotInfo>> np_handler::local_get_room_slots(SceNpMatching2RoomId room_id)
{
return np_cache.get_slots(room_id);
}
std::pair<error_code, std::vector<SceNpMatching2RoomMemberId>> np_handler::local_get_room_memberids(SceNpMatching2RoomId room_id, s32 sort_method)
{
return np_cache.get_memberids(room_id, sort_method);
}
error_code np_handler::local_get_room_member_data(SceNpMatching2RoomId room_id, SceNpMatching2RoomMemberId member_id, const std::vector<SceNpMatching2AttributeId>& binattrs_list, SceNpMatching2RoomMemberDataInternal* ptr_member, u32 addr_data, u32 size_data)
{
return np_cache.get_member_and_attrs(room_id, member_id, binattrs_list, ptr_member, addr_data, size_data);
}
} // namespace np

View File

@ -11,8 +11,9 @@
#include "Emu/NP/rpcn_client.h"
#include "generated/np2_structs_generated.h"
#include "signaling_handler.h"
#include "np_event_data.h"
#include "np_allocator.h"
#include "np_cache.h"
#include "np_event_data.h"
namespace np
{
@ -51,14 +52,6 @@ namespace np
const SceNpOnlineName& get_online_name() const;
const SceNpAvatarUrl& get_avatar_url() const;
// DNS hooking functions
void add_dns_spy(u32 sock);
void remove_dns_spy(u32 sock);
bool is_dns(u32 sock) const;
bool is_dns_queue(u32 sock) const;
std::vector<u8> get_dns_packet(u32 sock);
s32 analyze_dns_packet(s32 s, const u8* buf, u32 len);
// handles async messages from server(only needed for RPCN)
void operator()();
@ -91,6 +84,8 @@ namespace np
void queue_basic_event(basic_event to_queue);
bool send_basic_event(s32 event, s32 retCode, u32 reqId);
error_code get_basic_event(vm::ptr<s32> event, vm::ptr<SceNpUserInfo> from, vm::ptr<s32> data, vm::ptr<u32> size);
// Messages-related functions
std::optional<std::shared_ptr<std::pair<std::string, message_data>>> get_message(u64 id);
// Those should probably be under match2 ctx
@ -121,6 +116,12 @@ namespace np
u32 get_match2_event(SceNpMatching2EventKey event_key, u32 dest_addr, u32 size);
// Local functions
std::pair<error_code, std::optional<SceNpMatching2RoomSlotInfo>> local_get_room_slots(SceNpMatching2RoomId room_id);
std::pair<error_code, std::optional<SceNpMatching2SessionPassword>> local_get_room_password(SceNpMatching2RoomId room_id);
std::pair<error_code, std::vector<SceNpMatching2RoomMemberId>> local_get_room_memberids(SceNpMatching2RoomId room_id, s32 sort_method);
error_code local_get_room_member_data(SceNpMatching2RoomId room_id, SceNpMatching2RoomMemberId member_id, const std::vector<SceNpMatching2AttributeId>& binattrs_list, SceNpMatching2RoomMemberDataInternal* ptr_member, u32 addr_data, u32 size_data);
// Friend stuff
u32 get_num_friends();
u32 get_num_blocks();
@ -227,13 +228,13 @@ namespace np
SceNpOnlineName online_name{};
SceNpAvatarUrl avatar_url{};
// DNS related
std::map<s32, std::queue<std::vector<u8>>> dns_spylist{};
std::map<std::string, u32> switch_map{};
// Memory pool for sceNp/sceNp2
memory_allocator np_memory;
// Cache related
std::optional<SceNpMatching2SessionPassword> cached_cj_password;
cache_manager np_cache;
// Requests(reqEventKey : data)
shared_mutex mutex_match2_req_results;
std::unordered_map<u32, event_data> match2_req_results;

View File

@ -29,6 +29,8 @@ namespace np
RoomMemberUpdateInfo_to_SceNpMatching2RoomMemberUpdateInfo(edata, update_info, notif_data);
np_memory.shrink_allocation(edata.addr(), edata.size());
np_cache.add_member(room_id, notif_data->roomMemberDataInternal.get_ptr());
rpcn_log.notice("Received notification that user %s(%d) joined the room(%d)", notif_data->roomMemberDataInternal->userInfo.npId.handle.data, notif_data->roomMemberDataInternal->memberId, room_id);
extra_nps::print_room_member_data_internal(notif_data->roomMemberDataInternal.get_ptr());
@ -59,6 +61,8 @@ namespace np
RoomMemberUpdateInfo_to_SceNpMatching2RoomMemberUpdateInfo(edata, update_info, notif_data);
np_memory.shrink_allocation(edata.addr(), edata.size());
np_cache.del_member(room_id, notif_data->roomMemberDataInternal->memberId);
rpcn_log.notice("Received notification that user %s(%d) left the room(%d)", notif_data->roomMemberDataInternal->userInfo.npId.handle.data, notif_data->roomMemberDataInternal->memberId, room_id);
extra_nps::print_room_member_data_internal(notif_data->roomMemberDataInternal.get_ptr());
@ -121,13 +125,12 @@ namespace np
RoomDataInternalUpdateInfo_to_SceNpMatching2RoomDataInternalUpdateInfo(edata, update_info, notif_data, npid);
np_memory.shrink_allocation(edata.addr(), edata.size());
np_cache.insert_room(notif_data->newRoomDataInternal.get_ptr());
extra_nps::print_room_data_internal(notif_data->newRoomDataInternal.get_ptr());
rpcn_log.notice("Received notification that room(%d)'s data was updated", room_id);
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
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, size = edata.size()](ppu_thread& cb_ppu) -> s32
{
room_event_cb(cb_ppu, room_event_cb_ctx, room_id, SCE_NP_MATCHING2_ROOM_EVENT_UpdatedRoomDataInternal, event_key, 0, size, room_event_cb_arg);
@ -155,6 +158,8 @@ namespace np
RoomMemberDataInternalUpdateInfo_to_SceNpMatching2RoomMemberDataInternalUpdateInfo(edata, update_info, notif_data);
np_memory.shrink_allocation(edata.addr(), edata.size());
np_cache.add_member(room_id, notif_data->newRoomMemberDataInternal.get_ptr());
rpcn_log.notice("Received notification that user's %s(%d) room (%d) data was updated", notif_data->newRoomMemberDataInternal->userInfo.npId.handle.data, notif_data->newRoomMemberDataInternal->memberId, room_id);
extra_nps::print_room_member_data_internal(notif_data->newRoomMemberDataInternal.get_ptr());

View File

@ -97,7 +97,6 @@ namespace np
if (reply.is_error())
{
world_list.clear();
return error_and_disconnect("Malformed reply to GetWorldList command");
}
@ -142,6 +141,9 @@ namespace np
is_psn_active = false;
}
// More elegant solution would be to send back password with creation reply
cached_cj_password = req->roomPassword ? std::optional<SceNpMatching2SessionPassword>{*req->roomPassword} : std::nullopt;
return req_id;
}
@ -164,6 +166,9 @@ namespace np
RoomDataInternal_to_SceNpMatching2RoomDataInternal(edata, resp, room_info, npid);
np_memory.shrink_allocation(edata.addr(), edata.size());
np_cache.insert_room(room_info);
np_cache.update_password(room_resp->roomDataInternal->roomId, cached_cj_password);
// Establish Matching2 self signaling info
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.set_self_sig2_info(room_info->roomId, 1);
@ -214,7 +219,9 @@ namespace np
u16 member_id = RoomDataInternal_to_SceNpMatching2RoomDataInternal(edata, resp, room_info, npid);
np_memory.shrink_allocation(edata.addr(), edata.size());
extra_nps::print_room_data_internal(room_resp->roomDataInternal.get_ptr());
np_cache.insert_room(room_info);
extra_nps::print_room_data_internal(room_info);
// Establish Matching2 self signaling info
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
@ -409,7 +416,9 @@ namespace np
RoomDataInternal_to_SceNpMatching2RoomDataInternal(edata, resp, room_info, npid);
np_memory.shrink_allocation(edata.addr(), edata.size());
extra_nps::print_room_data_internal(room_resp->roomDataInternal.get_ptr());
np_cache.insert_room(room_info);
extra_nps::print_room_data_internal(room_info);
sysutil_register_cb([=, size = edata.size()](ppu_thread& cb_ppu) -> s32
{

View File

@ -1667,7 +1667,7 @@ namespace rpcn
case CreationBannedEmailProvider: rpcn_log.error("Error creating an account: banned email provider!"); break;
case CreationExistingEmail: rpcn_log.error("Error creating an account: an account with that email already exist!"); break;
case AlreadyJoined: rpcn_log.error("User has already joined!"); break;
case Unauthorized: rpcn_log.error("User attempted an unauthorized operation!");
case Unauthorized: rpcn_log.error("User attempted an unauthorized operation!"); break;
case DbFail: rpcn_log.error("A db query failed on the server!"); break;
case EmailFail: rpcn_log.error("An email action failed on the server!"); break;
case NotFound: rpcn_log.error("A request replied not found!"); break;

View File

@ -91,7 +91,9 @@
<ClCompile Include="Emu\title.cpp" />
<ClCompile Include="Emu\system_config.cpp" />
<ClCompile Include="Emu\NP\fb_helpers.cpp" />
<ClCompile Include="Emu\NP\np_cache.cpp" />
<ClCompile Include="Emu\NP\np_contexts.cpp" />
<ClCompile Include="Emu\NP\np_dnshook.cpp" />
<ClCompile Include="Emu\NP\np_handler.cpp" />
<ClCompile Include="Emu\NP\np_helpers.cpp" />
<ClCompile Include="Emu\NP\np_notifications.cpp" />
@ -466,6 +468,8 @@
<ClInclude Include="Emu\NP\np_handler.h" />
<ClInclude Include="Emu\NP\signaling_handler.h" />
<ClInclude Include="Emu\NP\np_allocator.h" />
<ClInclude Include="Emu\NP\np_cache.h" />
<ClInclude Include="Emu\NP\np_dnshook.h" />
<ClInclude Include="Emu\NP\np_event_data.h" />
<ClInclude Include="Emu\NP\np_structs_extra.h" />
<ClInclude Include="Emu\NP\rpcn_client.h" />

View File

@ -891,9 +891,15 @@
<ClCompile Include="Emu\NP\fb_helpers.cpp">
<Filter>Emu\NP</Filter>
</ClCompile>
<ClCompile Include="Emu\NP\np_cache.cpp">
<Filter>Emu\NP</Filter>
</ClCompile>
<ClCompile Include="Emu\NP\np_contexts.cpp">
<Filter>Emu\NP</Filter>
</ClCompile>
<ClCompile Include="Emu\NP\np_dnshook.cpp">
<Filter>Emu\NP</Filter>
</ClCompile>
<ClCompile Include="Emu\NP\np_handler.cpp">
<Filter>Emu\NP</Filter>
</ClCompile>