RPCN Client (#8663)

This commit is contained in:
RipleyTom 2020-08-27 21:47:04 +02:00 committed by GitHub
parent d000d648b0
commit 190822c2b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 8365 additions and 431 deletions

5
.gitmodules vendored
View File

@ -71,4 +71,7 @@
path = 3rdparty/wolfssl
url = https://github.com/RipleyTom/wolfssl.git
ignore = dirty
[submodule "3rdparty/flatbuffers"]
path = 3rdparty/flatbuffers
url = https://github.com/google/flatbuffers.git
ignore = dirty

View File

@ -74,6 +74,9 @@ else()
add_library(3rdparty_7z INTERFACE)
endif()
add_library(3rdparty_flatbuffers INTERFACE)
target_include_directories(3rdparty_flatbuffers INTERFACE flatbuffers/include)
# libPNG
# Select the version of libpng to use, default is builtin
if (NOT USE_SYSTEM_LIBPNG)
@ -413,16 +416,17 @@ endif()
# LLVM
include(llvm.cmake)
# WOLFSSL
add_subdirectory(wolfssl EXCLUDE_FROM_ALL)
# CURL
if(USE_SYSTEM_CURL)
message("-- RPCS3: using shared libcurl")
find_package(CURL REQUIRED)
add_library(wolfssl-3-static INTERFACE)
add_library(libcurl INTERFACE)
target_link_libraries(libcurl INTERFACE CURL::libcurl)
else()
message("-- RPCS3: building libcurl + wolfssl submodules")
add_subdirectory(wolfssl EXCLUDE_FROM_ALL)
add_subdirectory(curl EXCLUDE_FROM_ALL)
endif()
@ -430,6 +434,7 @@ endif()
add_library(3rdparty::libusb ALIAS usb-1.0-static)
add_library(3rdparty::zlib ALIAS 3rdparty_zlib)
add_library(3rdparty::7z ALIAS 3rdparty_7z)
add_library(3rdparty::flatbuffers ALIAS 3rdparty_flatbuffers)
add_library(3rdparty::pugixml ALIAS pugixml)
add_library(3rdparty::yaml-cpp ALIAS yaml-cpp)
add_library(3rdparty::xxhash ALIAS xxhash)

1
3rdparty/flatbuffers vendored Submodule

@ -0,0 +1 @@
Subproject commit 9e7e8cbe9f675123dd41b7c62868acad39188cae

2
3rdparty/wolfssl vendored

@ -1 +1 @@
Subproject commit f7130a4e43170ac2bb1046a65d10c01e6ec1d698
Subproject commit d0749c65498672462b88fc8be5ea066cf65067f1

View File

@ -384,7 +384,7 @@ namespace cfg
using uint64 = uint<0, UINT64_MAX>;
// Simple string entry with mutex
class string final : public _base
class string : public _base
{
const std::string m_name;

View File

@ -83,7 +83,7 @@ set_target_properties(rpcs3
AUTOUIC ON)
target_link_libraries(rpcs3 rpcs3_emu rpcs3_ui)
target_link_libraries(rpcs3 3rdparty::discord-rpc 3rdparty::qt5 3rdparty::hidapi 3rdparty::libusb)
target_link_libraries(rpcs3 3rdparty::discord-rpc 3rdparty::qt5 3rdparty::hidapi 3rdparty::libusb 3rdparty::wolfssl)
target_link_libraries(rpcs3 ${ADDITIONAL_LIBS})
# Win resource file

View File

@ -12,7 +12,7 @@ target_link_libraries(rpcs3_emu
PRIVATE
3rdparty::zlib 3rdparty::yaml-cpp
PUBLIC
3rdparty::libevdev)
3rdparty::libevdev 3rdparty::flatbuffers)
find_package(Threads REQUIRED)
@ -362,7 +362,11 @@ target_sources(rpcs3_emu PRIVATE
# Np
target_sources(rpcs3_emu PRIVATE
NP/fb_helpers.cpp
NP/np_handler.cpp
NP/np_structs_extra.cpp
NP/rpcn_client.cpp
NP/rpcn_config.cpp
)
# Memory
@ -452,7 +456,7 @@ target_link_libraries(rpcs3_emu
3rdparty::ffmpeg 3rdparty::cereal
3rdparty::opengl 3rdparty::stblib
3rdparty::vulkan 3rdparty::glew
3rdparty::libusb
3rdparty::libusb 3rdparty::wolfssl
PRIVATE
3rdparty::span 3rdparty::xxhash
)

View File

@ -177,7 +177,7 @@ error_code cellNetCtlDelHandler(s32 hid)
error_code cellNetCtlGetInfo(s32 code, vm::ptr<CellNetCtlInfo> info)
{
cellNetCtl.todo("cellNetCtlGetInfo(code=0x%x (%s), info=*0x%x)", code, InfoCodeToName(code), info);
cellNetCtl.warning("cellNetCtlGetInfo(code=0x%x (%s), info=*0x%x)", code, InfoCodeToName(code), info);
const auto nph = g_fxo->get<named_thread<np_handler>>();
@ -213,7 +213,7 @@ error_code cellNetCtlGetInfo(s32 code, vm::ptr<CellNetCtlInfo> info)
}
else if (code == CELL_NET_CTL_INFO_IP_ADDRESS)
{
strcpy_trunc(info->ip_address, nph->get_ip());
strcpy_trunc(info->ip_address, np_handler::ip_to_string(nph->get_local_ip_addr()));
}
else if (code == CELL_NET_CTL_INFO_NETMASK)
{
@ -306,7 +306,6 @@ error_code cellNetCtlNetStartDialogUnloadAsync(vm::ptr<CellNetCtlNetStartDialogR
result->result = nph->get_net_status() == CELL_NET_CTL_STATE_IPObtained ? 0 : CELL_NET_CTL_ERROR_DIALOG_CANCELED;
sysutil_send_system_cmd(CELL_SYSUTIL_NET_CTL_NETSTART_UNLOADED, 0);
return CELL_OK;
}
@ -331,6 +330,10 @@ error_code cellNetCtlGetNatInfo(vm::ptr<CellNetCtlNatInfo> natInfo)
return CELL_NET_CTL_ERROR_INVALID_SIZE;
}
natInfo->nat_type = CELL_NET_CTL_NATINFO_NAT_TYPE_2;
natInfo->stun_status = CELL_NET_CTL_NATINFO_STUN_OK;
natInfo->upnp_status = CELL_NET_CTL_NATINFO_UPNP_NO;
return CELL_OK;
}
@ -467,7 +470,6 @@ error_code cellGameUpdateCheckStartWithoutDialogAsyncEx(vm::ptr<CellGameUpdateCa
return CELL_OK;
}
DECLARE(ppu_module_manager::cellNetCtl)("cellNetCtl", []()
{
REG_FUNC(cellNetCtl, cellNetCtlInit);

View File

@ -459,7 +459,7 @@ error_code cellSysutilDisableBgmPlaybackEx(vm::ptr<CellSysutilBgmPlaybackExtraPa
error_code cellSysutilGetBgmPlaybackStatus(vm::ptr<CellSysutilBgmPlaybackStatus> status)
{
cellSysutil.warning("cellSysutilGetBgmPlaybackStatus(status=*0x%x)", status);
cellSysutil.trace("cellSysutilGetBgmPlaybackStatus(status=*0x%x)", status);
// TODO
status->playerState = CELL_SYSUTIL_BGMPLAYBACK_STATUS_STOP;
@ -473,7 +473,7 @@ error_code cellSysutilGetBgmPlaybackStatus(vm::ptr<CellSysutilBgmPlaybackStatus>
error_code cellSysutilGetBgmPlaybackStatus2(vm::ptr<CellSysutilBgmPlaybackStatus2> status2)
{
cellSysutil.warning("cellSysutilGetBgmPlaybackStatus2(status2=*0x%x)", status2);
cellSysutil.trace("cellSysutilGetBgmPlaybackStatus2(status2=*0x%x)", status2);
// TODO
status2->playerState = CELL_SYSUTIL_BGMPLAYBACK_STATUS_STOP;

View File

@ -4,6 +4,7 @@
#include "sceNp.h"
#include "sceNp2.h"
#include "cellSysutilAvc2.h"
#include "cellSysutil.h"
LOG_CHANNEL(cellSysutilAvc2);
@ -34,9 +35,18 @@ void fmt_class_string<CellSysutilAvc2Error>::format(std::string& out, u64 arg)
});
}
vm::ptr<CellSysutilAvc2Callback> avc2_cb{};
vm::ptr<void> avc2_cb_arg{};
error_code cellSysutilAvc2GetPlayerInfo(vm::cptr<SceNpMatching2RoomMemberId> player_id, vm::ptr<CellSysutilAvc2PlayerInfo> player_info)
{
cellSysutilAvc2.todo("cellSysutilAvc2GetPlayerInfo(player_id=*0x%x, player_info=*0x%x)", player_id, player_info);
player_info->connected = 1;
player_info->joined = 1;
player_info->mic_attached = 0;
player_info->member_id = *player_id;
return CELL_OK;
}
@ -117,7 +127,19 @@ error_code cellSysutilAvc2GetAttribute(vm::ptr<CellSysutilAvc2Attribute> attr)
error_code cellSysutilAvc2LoadAsync(SceNpMatching2ContextId ctx_id, u32 container, vm::ptr<CellSysutilAvc2Callback> callback_func, vm::ptr<void> user_data, vm::cptr<CellSysutilAvc2InitParam> init_param)
{
cellSysutilAvc2.todo("cellSysutilAvc2LoadAsync(ctx_id=0x%x, container=0x%x, callback_func=*0x%x, user_data=*0x%x, init_param=*0x%x)", ctx_id, container, callback_func, user_data, init_param);
cellSysutilAvc2.warning("cellSysutilAvc2LoadAsync(ctx_id=0x%x, container=0x%x, callback_func=*0x%x, user_data=*0x%x, init_param=*0x%x)", ctx_id, container, callback_func, user_data, init_param);
avc2_cb = callback_func;
avc2_cb_arg = user_data;
if (avc2_cb)
{
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 {
avc2_cb(cb_ppu, CELL_AVC2_EVENT_LOAD_SUCCEEDED, 0, avc2_cb_arg);
return 0;
});
}
return CELL_OK;
}
@ -204,7 +226,16 @@ error_code cellSysutilAvc2GetPlayerVoiceMuting(SceNpMatching2RoomMemberId member
error_code cellSysutilAvc2JoinChatRequest(vm::cptr<SceNpMatching2RoomId> room_id)
{
cellSysutilAvc2.todo("cellSysutilAvc2JoinChatRequest(room_id=*0x%x)", room_id);
cellSysutilAvc2.warning("cellSysutilAvc2JoinChatRequest(room_id=*0x%x)", room_id);
if (avc2_cb)
{
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 {
avc2_cb(cb_ppu, CELL_AVC2_EVENT_JOIN_SUCCEEDED, 0, avc2_cb_arg);
return 0;
});
}
return CELL_OK;
}
@ -309,6 +340,7 @@ error_code cellSysutilAvc2CreateWindow(SceNpMatching2RoomMemberId member_id)
error_code cellSysutilAvc2GetSpeakerMuting(vm::ptr<u8> muting)
{
cellSysutilAvc2.todo("cellSysutilAvc2GetSpeakerMuting(muting=*0x%x)", muting);
*muting = 1;
return CELL_OK;
}
@ -327,6 +359,13 @@ error_code cellSysutilAvc2SetWindowSize(SceNpMatching2RoomMemberId member_id, f3
error_code cellSysutilAvc2EnumPlayers(vm::ptr<s32> players_num, vm::ptr<SceNpMatching2RoomMemberId> players_id)
{
cellSysutilAvc2.todo("cellSysutilAvc2EnumPlayers(players_num=*0x%x, players_id=*0x%x)", players_num, players_id);
if (players_num)
*players_num = 1;
if (players_id)
*players_id = 1;
return CELL_OK;
}

View File

@ -123,6 +123,18 @@ enum
CELL_AVC2_MIC_STATUS_UNKNOWN = 3,
};
enum
{
CELL_AVC2_EVENT_LOAD_SUCCEEDED = 0x00000001,
CELL_AVC2_EVENT_LOAD_FAILED = 0x00000002,
CELL_AVC2_EVENT_UNLOAD_SUCCEEDED = 0x00000003,
CELL_AVC2_EVENT_UNLOAD_FAILED = 0x00000004,
CELL_AVC2_EVENT_JOIN_SUCCEEDED = 0x00000005,
CELL_AVC2_EVENT_JOIN_FAILED = 0x00000006,
CELL_AVC2_EVENT_LEAVE_SUCCEEDED = 0x00000007,
CELL_AVC2_EVENT_LEAVE_FAILED = 0x00000008,
};
typedef u32 CellSysutilAvc2AttributeId;
typedef u32 CellSysutilAvc2WindowAttributeId;

View File

@ -15,7 +15,7 @@
LOG_CHANNEL(sceNp);
template<>
template <>
void fmt_class_string<SceNpError>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](auto error)
@ -639,6 +639,9 @@ error_code sceNpBasicRegisterHandler(vm::cptr<SceNpCommunicationId> context, vm:
return SCE_NP_BASIC_ERROR_INVALID_ARGUMENT;
}
nph->basic_handler = handler;
nph->basic_handler_arg = arg;
return CELL_OK;
}
@ -1140,6 +1143,13 @@ error_code sceNpBasicAddPlayersHistoryAsync(vm::cptr<SceNpId> npids, u32 count,
return SCE_NP_BASIC_ERROR_EXCEEDS_MAX;
}
auto req_id = nph->add_players_to_history(npids, count);
if (reqId)
{
*reqId = req_id;
}
return CELL_OK;
}
@ -1888,7 +1898,7 @@ error_code sceNpFriendlistAbortGui()
error_code sceNpLookupInit()
{
sceNp.todo("sceNpLookupInit()");
sceNp.warning("sceNpLookupInit()");
const auto nph = g_fxo->get<named_thread<np_handler>>();
@ -1930,7 +1940,7 @@ error_code sceNpLookupTerm()
error_code sceNpLookupCreateTitleCtx(vm::cptr<SceNpCommunicationId> communicationId, vm::cptr<SceNpId> selfNpId)
{
sceNp.todo("sceNpLookupCreateTitleCtx(communicationId=*0x%x, selfNpId=0x%x)", communicationId, selfNpId);
sceNp.warning("sceNpLookupCreateTitleCtx(communicationId=*0x%x, selfNpId=0x%x)", communicationId, selfNpId);
const auto nph = g_fxo->get<named_thread<np_handler>>();
@ -1944,12 +1954,12 @@ error_code sceNpLookupCreateTitleCtx(vm::cptr<SceNpCommunicationId> communicatio
return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT;
}
return not_an_error(nph->create_lookup_context(communicationId));
return not_an_error(nph->create_lookup_title_context(communicationId));
}
error_code sceNpLookupDestroyTitleCtx(s32 titleCtxId)
{
sceNp.todo("sceNpLookupDestroyTitleCtx(titleCtxId=%d)", titleCtxId);
sceNp.warning("sceNpLookupDestroyTitleCtx(titleCtxId=%d)", titleCtxId);
const auto nph = g_fxo->get<named_thread<np_handler>>();
@ -1958,7 +1968,7 @@ error_code sceNpLookupDestroyTitleCtx(s32 titleCtxId)
return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED;
}
if (!nph->destroy_lookup_context(titleCtxId))
if (!nph->destroy_lookup_title_context(titleCtxId))
return SCE_NP_COMMUNITY_ERROR_INVALID_ID;
return CELL_OK;
@ -1966,7 +1976,7 @@ error_code sceNpLookupDestroyTitleCtx(s32 titleCtxId)
error_code sceNpLookupCreateTransactionCtx(s32 titleCtxId)
{
sceNp.todo("sceNpLookupCreateTransactionCtx(titleCtxId=%d)", titleCtxId);
sceNp.warning("sceNpLookupCreateTransactionCtx(titleCtxId=%d)", titleCtxId);
const auto nph = g_fxo->get<named_thread<np_handler>>();
@ -1980,12 +1990,12 @@ error_code sceNpLookupCreateTransactionCtx(s32 titleCtxId)
return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID;
}
return CELL_OK;
return not_an_error(nph->create_lookup_transaction_context(titleCtxId));
}
error_code sceNpLookupDestroyTransactionCtx(s32 transId)
{
sceNp.todo("sceNpLookupDestroyTransactionCtx(transId=%d)", transId);
sceNp.warning("sceNpLookupDestroyTransactionCtx(transId=%d)", transId);
const auto nph = g_fxo->get<named_thread<np_handler>>();
@ -1994,6 +2004,11 @@ error_code sceNpLookupDestroyTransactionCtx(s32 transId)
return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED;
}
if (!nph->destroy_lookup_transaction_context(transId))
{
return SCE_NP_COMMUNITY_ERROR_INVALID_ID;
}
return CELL_OK;
}
@ -2008,7 +2023,7 @@ error_code sceNpLookupSetTimeout(s32 ctxId, usecond_t timeout)
return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED;
}
if (timeout > 10000000) // 10 seconds
if (timeout < 10000000) // 10 seconds
{
return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT;
}
@ -2046,7 +2061,7 @@ error_code sceNpLookupWaitAsync(s32 transId, vm::ptr<s32> result)
error_code sceNpLookupPollAsync(s32 transId, vm::ptr<s32> result)
{
sceNp.todo("sceNpLookupPollAsync(transId=%d, result=%d)", transId, result);
sceNp.todo("sceNpLookupPollAsync(transId=%d, result=*0x%x)", transId, result);
const auto nph = g_fxo->get<named_thread<np_handler>>();
@ -2055,6 +2070,8 @@ error_code sceNpLookupPollAsync(s32 transId, vm::ptr<s32> result)
return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED;
}
*result = 0;
return CELL_OK;
}
@ -2394,6 +2411,8 @@ error_code sceNpLookupTitleSmallStorageAsync(s32 transId, vm::ptr<void> data, u6
return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID;
}
std::memset(data.get_ptr(), 0, maxSize);
return CELL_OK;
}
@ -2413,6 +2432,9 @@ error_code sceNpManagerRegisterCallback(vm::ptr<SceNpManagerCallback> callback,
return SCE_NP_ERROR_INVALID_ARGUMENT;
}
nph->manager_cb = callback;
nph->manager_cb_arg = arg;
return CELL_OK;
}
@ -2427,6 +2449,8 @@ error_code sceNpManagerUnregisterCallback()
return SCE_NP_ERROR_NOT_INITIALIZED;
}
nph->manager_cb.set(0);
return CELL_OK;
}
@ -2438,7 +2462,7 @@ error_code sceNpManagerGetStatus(vm::ptr<s32> status)
if (!nph->is_NP_init)
{
return SCE_NP_ERROR_NOT_INITIALIZED;
//return SCE_NP_ERROR_NOT_INITIALIZED;
}
if (!status)
@ -2459,7 +2483,7 @@ error_code sceNpManagerGetNetworkTime(vm::ptr<CellRtcTick> pTick)
if (!nph->is_NP_init)
{
return SCE_NP_ERROR_NOT_INITIALIZED;
//return SCE_NP_ERROR_NOT_INITIALIZED;
}
if (!pTick)
@ -2486,13 +2510,13 @@ error_code sceNpManagerGetNetworkTime(vm::ptr<CellRtcTick> pTick)
error_code sceNpManagerGetOnlineId(vm::ptr<SceNpOnlineId> onlineId)
{
sceNp.todo("sceNpManagerGetOnlineId(onlineId=*0x%x)", onlineId);
sceNp.warning("sceNpManagerGetOnlineId(onlineId=*0x%x)", onlineId);
const auto nph = g_fxo->get<named_thread<np_handler>>();
if (!nph->is_NP_init)
{
return SCE_NP_ERROR_NOT_INITIALIZED;
//return SCE_NP_ERROR_NOT_INITIALIZED;
}
if (!onlineId)
@ -2517,14 +2541,14 @@ error_code sceNpManagerGetOnlineId(vm::ptr<SceNpOnlineId> onlineId)
error_code sceNpManagerGetNpId(ppu_thread& ppu, vm::ptr<SceNpId> npId)
{
sceNp.todo("sceNpManagerGetNpId(npId=*0x%x)", npId);
sceNp.warning("sceNpManagerGetNpId(npId=*0x%x)", npId);
const auto nph = g_fxo->get<named_thread<np_handler>>();
if (!nph->is_NP_init)
{
return SCE_NP_ERROR_NOT_INITIALIZED;
}
// if (!nph->is_NP_init)
// {
// return SCE_NP_ERROR_NOT_INITIALIZED;
// }
if (!npId)
{
@ -4320,6 +4344,8 @@ error_code sceNpSignalingCreateCtx(vm::ptr<SceNpId> npId, vm::ptr<SceNpSignaling
// return SCE_NP_SIGNALING_ERROR_CTX_MAX;
//}
*ctx_id = nph->create_signaling_context(npId, handler, arg);
return CELL_OK;
}
@ -4334,6 +4360,11 @@ error_code sceNpSignalingDestroyCtx(u32 ctx_id)
return SCE_NP_SIGNALING_ERROR_NOT_INITIALIZED;
}
if (!nph->destroy_signaling_context(ctx_id))
{
return SCE_NP_SIGNALING_ERROR_CTX_NOT_FOUND;
}
return CELL_OK;
}
@ -4529,6 +4560,15 @@ error_code sceNpSignalingGetLocalNetInfo(u32 ctx_id, vm::ptr<SceNpSignalingNetIn
return SCE_NP_SIGNALING_ERROR_INVALID_ARGUMENT;
}
info->local_addr = nph->get_local_ip_addr();
info->mapped_addr = nph->get_public_ip_addr();
// Pure speculation below
info->nat_status = 0;
info->upnp_status = 0;
info->npport_status = 0;
info->npport = 3658;
return CELL_OK;
}
@ -4607,24 +4647,24 @@ error_code sceNpUtilCmpNpId(vm::ptr<SceNpId> id1, vm::ptr<SceNpId> id2)
}
// Unknown what this constant means
if (id1->reserved[0] != 1 || id2->reserved[0] != 1)
{
return SCE_NP_UTIL_ERROR_INVALID_NP_ID;
}
// if (id1->reserved[0] != 1 || id2->reserved[0] != 1)
// {
// return SCE_NP_UTIL_ERROR_INVALID_NP_ID;
// }
if (strncmp(id1->handle.data, id2->handle.data, 16) || id1->unk1[0] != id2->unk1[0])
if (strncmp(id1->handle.data, id2->handle.data, 16))// || id1->unk1[0] != id2->unk1[0])
{
return SCE_NP_UTIL_ERROR_NOT_MATCH;
}
if (id1->unk1[1] != id2->unk1[1])
{
// If either is zero they match
if (id1->opt[4] && id2->opt[4])
{
return SCE_NP_UTIL_ERROR_NOT_MATCH;
}
}
// if (id1->unk1[1] != id2->unk1[1])
// {
// // If either is zero they match
// if (id1->opt[4] && id2->opt[4])
// {
// return SCE_NP_UTIL_ERROR_NOT_MATCH;
// }
// }
return CELL_OK;
}

View File

@ -311,7 +311,7 @@ error_code sceNpMatching2LeaveLobby(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -350,6 +350,8 @@ error_code sceNpMatching2GetWorldInfoList(
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
*assignedReqId = nph->get_world_list(ctxId, optParam, reqParam->serverId);
return CELL_OK;
}
@ -379,7 +381,7 @@ error_code sceNpMatching2GetLobbyMemberDataInternalList(SceNpMatching2ContextId
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -404,13 +406,15 @@ error_code sceNpMatching2SearchRoom(
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
*assignedReqId = nph->search_room(ctxId, optParam, reqParam.get_ptr());
return CELL_OK;
}
error_code sceNpMatching2SignalingGetConnectionStatus(
SceNpMatching2ContextId ctxId, SceNpMatching2RoomId roomId, SceNpMatching2RoomMemberId memberId, vm::ptr<int> connStatus, vm::ptr<np_in_addr> peerAddr, vm::ptr<np_in_port_t> peerPort)
{
sceNp2.todo("sceNpMatching2SignalingGetConnectionStatus(ctxId=%d, roomId=%d, memberId=%d, connStatus=*0x%x, peerAddr=*0x%x, peerPort=*0x%x)", ctxId, roomId, memberId, connStatus, peerAddr, peerPort);
sceNp2.warning("sceNpMatching2SignalingGetConnectionStatus(ctxId=%d, roomId=%d, memberId=%d, connStatus=*0x%x, peerAddr=*0x%x, peerPort=*0x%x)", ctxId, roomId, memberId, connStatus, peerAddr, peerPort);
const auto nph = g_fxo->get<named_thread<np_handler>>();
@ -419,6 +423,12 @@ error_code sceNpMatching2SignalingGetConnectionStatus(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
const auto& infos = nph->get_peer_infos(ctxId, roomId, memberId);
*connStatus = infos.connStatus;
(*peerAddr).np_s_addr = infos.addr; // infos.addr is already BE
*peerPort = std::bit_cast<u16, be_t<u16>>(infos.port); // infos.port is already BE
return CELL_OK;
}
@ -434,7 +444,7 @@ error_code sceNpMatching2SetUserInfo(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -468,7 +478,7 @@ error_code sceNpMatching2GetLobbyMemberDataInternal(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -478,7 +488,7 @@ error_code sceNpMatching2GetLobbyMemberDataInternal(
error_code sceNpMatching2ContextStart(SceNpMatching2ContextId ctxId)
{
sceNp2.todo("sceNpMatching2ContextStart(ctxId=%d)", ctxId);
sceNp2.warning("sceNpMatching2ContextStart(ctxId=%d)", ctxId);
const auto nph = g_fxo->get<named_thread<np_handler>>();
@ -487,13 +497,26 @@ error_code sceNpMatching2ContextStart(SceNpMatching2ContextId ctxId)
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
const auto ctx = nph->get_match2_context(ctxId);
if (!ctx)
return SCE_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID;
if (ctx->context_callback)
{
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 {
ctx->context_callback(cb_ppu, ctxId, SCE_NP_MATCHING2_CONTEXT_EVENT_Start, SCE_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ACTION, 0, ctx->context_callback_param);
return 0;
});
}
return CELL_OK;
}
error_code sceNpMatching2CreateServerContext(
SceNpMatching2ContextId ctxId, vm::cptr<SceNpMatching2CreateServerContextRequest> reqParam, vm::cptr<SceNpMatching2RequestOptParam> optParam, vm::ptr<SceNpMatching2RequestId> assignedReqId)
{
sceNp2.todo("sceNpMatching2CreateServerContext(ctxId=%d, reqParam=*0x%x, optParam=*0x%x, assignedReqId=*0x%x)", ctxId, reqParam, optParam, assignedReqId);
sceNp2.warning("sceNpMatching2CreateServerContext(ctxId=%d, reqParam=*0x%x, optParam=*0x%x, assignedReqId=*0x%x)", ctxId, reqParam, optParam, assignedReqId);
const auto nph = g_fxo->get<named_thread<np_handler>>();
@ -502,11 +525,13 @@ error_code sceNpMatching2CreateServerContext(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
*assignedReqId = nph->create_server_context(ctxId, optParam, reqParam->serverId);
return CELL_OK;
}
@ -527,7 +552,7 @@ error_code sceNpMatching2GetMemoryInfo(vm::ptr<SceNpMatching2MemoryInfo> memInfo
error_code sceNpMatching2LeaveRoom(
SceNpMatching2ContextId ctxId, vm::cptr<SceNpMatching2LeaveRoomRequest> reqParam, vm::cptr<SceNpMatching2RequestOptParam> optParam, vm::ptr<SceNpMatching2RequestId> assignedReqId)
{
sceNp2.todo("sceNpMatching2LeaveRoom(ctxId=%d, reqParam=*0x%x, optParam=*0x%x, assignedReqId=*0x%x)", ctxId, reqParam, optParam, assignedReqId);
sceNp2.warning("sceNpMatching2LeaveRoom(ctxId=%d, reqParam=*0x%x, optParam=*0x%x, assignedReqId=*0x%x)", ctxId, reqParam, optParam, assignedReqId);
const auto nph = g_fxo->get<named_thread<np_handler>>();
@ -541,6 +566,8 @@ error_code sceNpMatching2LeaveRoom(
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
*assignedReqId = nph->leave_room(ctxId, optParam, reqParam.get_ptr());
return CELL_OK;
}
@ -561,6 +588,8 @@ error_code sceNpMatching2SetRoomDataExternal(
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
*assignedReqId = nph->set_roomdata_external(ctxId, optParam, reqParam.get_ptr());
return CELL_OK;
}
@ -576,6 +605,37 @@ error_code sceNpMatching2SignalingGetConnectionInfo(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
switch (code)
{
case 1:
{
connInfo->rtt = 20000; // HACK
break;
}
case 2:
{
connInfo->bandwidth = 10'000'000; // 10 MBPS HACK
break;
}
case 5:
{
const auto& infos = nph->get_peer_infos(ctxId, roomId, memberId);
connInfo->address.port = infos.port;
connInfo->address.addr.np_s_addr = infos.addr;
break;
}
case 6:
{
connInfo->packet_loss = 1; // HACK
break;
}
default:
{
sceNp2.fatal("sceNpMatching2SignalingGetConnectionInfo Unimplemented code: %d", code);
return CELL_OK;
}
}
return CELL_OK;
}
@ -591,11 +651,13 @@ error_code sceNpMatching2SendRoomMessage(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
*assignedReqId = nph->send_room_message(ctxId, optParam, reqParam.get_ptr());
return CELL_OK;
}
@ -611,7 +673,7 @@ error_code sceNpMatching2JoinLobby(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -631,7 +693,7 @@ error_code sceNpMatching2GetRoomMemberDataExternalList(SceNpMatching2ContextId c
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -670,6 +732,8 @@ error_code sceNpMatching2GetServerInfo(
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
*assignedReqId = nph->get_server_status(ctxId, optParam, reqParam->serverId);
return CELL_OK;
}
@ -689,7 +753,7 @@ error_code sceNpMatching2GetEventData(SceNpMatching2ContextId ctxId, SceNpMatchi
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
return CELL_OK;
return not_an_error(nph->get_match2_event(eventKey, static_cast<u8 *>(buf.get_ptr()), bufLen));
}
error_code sceNpMatching2GetRoomSlotInfoLocal(SceNpMatching2ContextId ctxId, const SceNpMatching2RoomId roomId, vm::ptr<SceNpMatching2RoomSlotInfo> roomSlotInfo)
@ -718,7 +782,7 @@ error_code sceNpMatching2SendLobbyChatMessage(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -771,6 +835,8 @@ error_code sceNpMatching2JoinRoom(
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
*assignedReqId = nph->join_room(ctxId, optParam, reqParam.get_ptr());
return CELL_OK;
}
@ -816,7 +882,7 @@ error_code sceNpMatching2KickoutRoomMember(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -826,7 +892,7 @@ error_code sceNpMatching2KickoutRoomMember(
error_code sceNpMatching2ContextStartAsync(SceNpMatching2ContextId ctxId, u32 timeout)
{
sceNp2.todo("sceNpMatching2ContextStartAsync(ctxId=%d, timeout=%d)", ctxId, timeout);
sceNp2.warning("sceNpMatching2ContextStartAsync(ctxId=%d, timeout=%d)", ctxId, timeout);
const auto nph = g_fxo->get<named_thread<np_handler>>();
@ -835,6 +901,18 @@ error_code sceNpMatching2ContextStartAsync(SceNpMatching2ContextId ctxId, u32 ti
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
const auto ctx = nph->get_match2_context(ctxId);
if (!ctx)
return SCE_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID;
if (ctx->context_callback)
{
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 {
ctx->context_callback(cb_ppu, ctxId, SCE_NP_MATCHING2_CONTEXT_EVENT_Start, SCE_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ACTION, 0, ctx->context_callback_param);
return 0;
});
}
return CELL_OK;
}
@ -850,7 +928,7 @@ error_code sceNpMatching2SetSignalingOptParam(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -860,7 +938,7 @@ error_code sceNpMatching2SetSignalingOptParam(
error_code sceNpMatching2RegisterContextCallback(SceNpMatching2ContextId ctxId, vm::ptr<SceNpMatching2ContextCallback> cbFunc, vm::ptr<void> cbFuncArg)
{
sceNp2.todo("sceNpMatching2RegisterContextCallback(ctxId=%d, cbFunc=*0x%x, cbFuncArg=*0x%x)", ctxId, cbFunc, cbFuncArg);
sceNp2.warning("sceNpMatching2RegisterContextCallback(ctxId=%d, cbFunc=*0x%x, cbFuncArg=*0x%x)", ctxId, cbFunc, cbFuncArg);
const auto nph = g_fxo->get<named_thread<np_handler>>();
@ -869,6 +947,13 @@ error_code sceNpMatching2RegisterContextCallback(SceNpMatching2ContextId ctxId,
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
const auto ctx = nph->get_match2_context(ctxId);
if (!ctx)
return SCE_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID;
ctx->context_callback = cbFunc;
ctx->context_callback_param = cbFuncArg;
return CELL_OK;
}
@ -884,7 +969,7 @@ error_code sceNpMatching2SendRoomChatMessage(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -909,6 +994,8 @@ error_code sceNpMatching2SetRoomDataInternal(
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
*assignedReqId = nph->set_roomdata_internal(ctxId, optParam, reqParam.get_ptr());
return CELL_OK;
}
@ -929,6 +1016,8 @@ error_code sceNpMatching2GetRoomDataInternal(
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
*assignedReqId = nph->get_roomdata_internal(ctxId, optParam, reqParam.get_ptr());
return CELL_OK;
}
@ -949,6 +1038,8 @@ error_code sceNpMatching2SignalingGetPingInfo(
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
*assignedReqId = nph->get_ping_info(ctxId, optParam, reqParam.get_ptr());
return CELL_OK;
}
@ -963,7 +1054,16 @@ error_code sceNpMatching2GetServerIdListLocal(SceNpMatching2ContextId ctxId, vm:
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
return not_an_error(0); // Number of servers
const auto slist = nph->get_match2_server_list(ctxId);
u32 num_servs = std::min(static_cast<u32>(slist.size()), serverIdNum);
for (u32 i = 0; i < num_servs; i++)
{
serverId[i] = slist[i];
}
return not_an_error(static_cast<s32>(num_servs));
}
error_code sceNpUtilBuildCdnUrl(vm::cptr<char> url, vm::ptr<char> buf, u64 bufSize, vm::ptr<u64> required, vm::ptr<void> option)
@ -996,7 +1096,7 @@ error_code sceNpMatching2GrantRoomOwner(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -1021,6 +1121,8 @@ error_code sceNpMatching2CreateContext(
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
*ctxId = nph->create_match2_context(commId, passPhrase);
return CELL_OK;
}
@ -1049,6 +1151,10 @@ error_code sceNpMatching2RegisterSignalingCallback(SceNpMatching2ContextId ctxId
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
nph->signal_event_cb = cbFunc;
nph->signal_event_cb_ctx = ctxId;
nph->signal_event_cb_arg = cbFuncArg;
return CELL_OK;
}
@ -1078,7 +1184,7 @@ error_code sceNpMatching2GetUserInfoList(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -1098,7 +1204,7 @@ error_code sceNpMatching2GetRoomMemberDataInternal(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -1118,7 +1224,7 @@ error_code sceNpMatching2SetRoomMemberDataInternal(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -1138,7 +1244,7 @@ error_code sceNpMatching2JoinProhibitiveRoom(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -1172,7 +1278,7 @@ error_code sceNpMatching2DeleteServerContext(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -1182,7 +1288,7 @@ error_code sceNpMatching2DeleteServerContext(
error_code sceNpMatching2SetDefaultRequestOptParam(SceNpMatching2ContextId ctxId, vm::cptr<SceNpMatching2RequestOptParam> optParam)
{
sceNp2.todo("sceNpMatching2SetDefaultRequestOptParam(ctxId=%d, optParam=*0x%x)", ctxId, optParam);
sceNp2.warning("sceNpMatching2SetDefaultRequestOptParam(ctxId=%d, optParam=*0x%x)", ctxId, optParam);
const auto nph = g_fxo->get<named_thread<np_handler>>();
@ -1196,6 +1302,12 @@ error_code sceNpMatching2SetDefaultRequestOptParam(SceNpMatching2ContextId ctxId
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
const auto ctx = nph->get_match2_context(ctxId);
if (!ctx)
return SCE_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID;
memcpy(&ctx->default_match2_optparam, optParam.get_ptr(), sizeof(SceNpMatching2RequestOptParam));
return CELL_OK;
}
@ -1210,6 +1322,10 @@ error_code sceNpMatching2RegisterRoomEventCallback(SceNpMatching2ContextId ctxId
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
nph->room_event_cb = cbFunc;
nph->room_event_cb_ctx = ctxId;
nph->room_event_cb_arg = cbFuncArg;
return CELL_OK;
}
@ -1239,7 +1355,7 @@ error_code sceNpMatching2GetRoomDataExternalList(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -1264,6 +1380,8 @@ error_code sceNpMatching2CreateJoinRoom(
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
*assignedReqId = nph->create_join_room(ctxId, optParam, reqParam.get_ptr());
return CELL_OK;
}
@ -1293,7 +1411,7 @@ error_code sceNpMatching2GetLobbyInfoList(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -1328,7 +1446,7 @@ error_code sceNpMatching2SendLobbyInvitation(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -1347,6 +1465,21 @@ error_code sceNpMatching2ContextStop(SceNpMatching2ContextId ctxId)
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
const auto ctx = nph->get_match2_context(ctxId);
if (!ctx)
{
return SCE_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID;
}
if (ctx->context_callback)
{
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 {
ctx->context_callback(cb_ppu, ctxId, SCE_NP_MATCHING2_CONTEXT_EVENT_Stop, SCE_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ACTION, 0, ctx->context_callback_param);
return 0;
});
}
return CELL_OK;
}
@ -1362,7 +1495,7 @@ error_code sceNpMatching2SetLobbyMemberDataInternal(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
if (!reqParam || !optParam || !assignedReqId)
if (!reqParam || !assignedReqId)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}
@ -1381,6 +1514,10 @@ error_code sceNpMatching2RegisterRoomMessageCallback(SceNpMatching2ContextId ctx
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}
nph->room_msg_cb = cbFunc;
nph->room_msg_cb_ctx = ctxId;
nph->room_msg_cb_arg = cbFuncArg;
return CELL_OK;
}

View File

@ -850,7 +850,7 @@ union SceNpMatching2RoomMessageDestination
{
vm::bptr<SceNpMatching2RoomMemberId> memberId;
be_t<u32> memberIdNum;
};
} multicastTarget;
SceNpMatching2TeamId multicastTargetTeamId;
};
@ -1117,7 +1117,7 @@ struct SceNpMatching2SendRoomMessageRequest
SceNpMatching2CastType castType;
u8 padding[3];
SceNpMatching2RoomMessageDestination dst;
vm::cptr<void> msg;
vm::bcptr<void> msg;
be_t<u32> msgLen;
be_t<s32> option;
};
@ -1129,7 +1129,7 @@ struct SceNpMatching2SendRoomChatMessageRequest
SceNpMatching2CastType castType;
u8 padding[3];
SceNpMatching2RoomMessageDestination dst;
vm::cptr<void> msg;
vm::bcptr<void> msg;
be_t<u32> msgLen;
be_t<s32> option;
};
@ -1255,7 +1255,7 @@ struct SceNpMatching2SendLobbyChatMessageRequest
SceNpMatching2CastType castType;
u8 padding[3];
SceNpMatching2LobbyMessageDestination dst;
vm::cptr<void> msg;
vm::bcptr<void> msg;
be_t<u32> msgLen;
be_t<s32> option;
};
@ -1415,7 +1415,7 @@ struct SceNpMatching2RoomMessageInfo
u8 padding[2];
vm::bptr<SceNpMatching2RoomMessageDestination> dst;
vm::bptr<SceNpUserInfo2> srcMember;
vm::cptr<void> msg;
vm::bcptr<void> msg;
be_t<u32> msgLen;
};
@ -1458,7 +1458,7 @@ struct SceNpMatching2LobbyMessageInfo
u8 padding[2];
vm::bptr<SceNpMatching2LobbyMessageDestination> dst;
vm::bptr<SceNpUserInfo2> srcMember;
vm::cptr<void> msg;
vm::bcptr<void> msg;
be_t<u32> msgLen;
};

View File

@ -1,8 +1,12 @@
#include "stdafx.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/IdManager.h"
#include "sceNpCommerce2.h"
#include "sceNp.h"
#include "cellSysutil.h"
#include "Emu/NP/np_handler.h"
LOG_CHANNEL(sceNpCommerce2);
@ -91,19 +95,40 @@ error_code sceNpCommerce2Term()
error_code sceNpCommerce2CreateCtx(u32 version, vm::cptr<SceNpId> npId, vm::ptr<SceNpCommerce2Handler> handler, vm::ptr<void> arg, vm::ptr<u32> ctx_id)
{
sceNpCommerce2.todo("sceNpCommerce2CreateCtx(version=%d, npId=*0x%x, handler=*0x%x, arg=*0x%x, ctx_id=*0x%x)", version, npId, handler, arg, ctx_id);
sceNpCommerce2.warning("sceNpCommerce2CreateCtx(version=%d, npId=*0x%x, handler=*0x%x, arg=*0x%x, ctx_id=*0x%x)", version, npId, handler, arg, ctx_id);
const auto nph = g_fxo->get<named_thread<np_handler>>();
*ctx_id = nph->create_commerce2_context(version, npId, handler, arg);
return CELL_OK;
}
error_code sceNpCommerce2DestroyCtx(u32 ctx_id)
s32 sceNpCommerce2DestroyCtx(u32 ctx_id)
{
sceNpCommerce2.todo("sceNpCommerce2DestroyCtx(ctx_id=%d)", ctx_id);
sceNpCommerce2.warning("sceNpCommerce2DestroyCtx(ctx_id=%d)", ctx_id);
const auto nph = g_fxo->get<named_thread<np_handler>>();
nph->destroy_commerce2_context(ctx_id);
return CELL_OK;
}
error_code sceNpCommerce2EmptyStoreCheckStart(u32 ctx_id, s32 store_check_type, vm::cptr<char> target_id)
s32 sceNpCommerce2EmptyStoreCheckStart(u32 ctx_id, s32 store_check_type, vm::cptr<char> target_id)
{
sceNpCommerce2.todo("sceNpCommerce2EmptyStoreCheckStart(ctx_id=%d, store_check_type=%d, target_id=%s)", ctx_id, store_check_type, target_id);
sceNpCommerce2.warning("sceNpCommerce2EmptyStoreCheckStart(ctx_id=%d, store_check_type=%d, target_id=*0x%x(%s))", ctx_id, store_check_type, target_id, target_id);
const auto nph = g_fxo->get<named_thread<np_handler>>();
const auto ctx = nph->get_commerce2_context(ctx_id);
if (ctx->context_callback)
{
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 {
ctx->context_callback(cb_ppu, ctx_id, 0, SCE_NP_COMMERCE2_EVENT_EMPTY_STORE_CHECK_DONE, 0, ctx->context_callback_param);
return 0;
});
}
return CELL_OK;
}
@ -113,15 +138,28 @@ error_code sceNpCommerce2EmptyStoreCheckAbort(u32 ctx_id)
return CELL_OK;
}
error_code sceNpCommerce2EmptyStoreCheckFinish(u32 ctx_id, vm::ptr<int> is_empty)
s32 sceNpCommerce2EmptyStoreCheckFinish(u32 ctx_id, vm::ptr<s32> is_empty)
{
sceNpCommerce2.todo("sceNpCommerce2EmptyStoreCheckFinish(ctx_id=%d, is_empty=*0x%x)", ctx_id, is_empty);
sceNpCommerce2.warning("sceNpCommerce2EmptyStoreCheckFinish(ctx_id=%d, is_empty=*0x%x)", ctx_id, is_empty);
*is_empty = SCE_NP_COMMERCE2_STORE_IS_NOT_EMPTY;
return CELL_OK;
}
error_code sceNpCommerce2CreateSessionStart(u32 ctx_id)
s32 sceNpCommerce2CreateSessionStart(u32 ctx_id)
{
sceNpCommerce2.todo("sceNpCommerce2CreateSessionStart(ctx_id=%d)", ctx_id);
sceNpCommerce2.warning("sceNpCommerce2CreateSessionStart(ctx_id=%d)", ctx_id);
const auto nph = g_fxo->get<named_thread<np_handler>>();
const auto ctx = nph->get_commerce2_context(ctx_id);
if (ctx->context_callback)
{
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 {
ctx->context_callback(cb_ppu, ctx_id, 0, SCE_NP_COMMERCE2_EVENT_CREATE_SESSION_DONE, 0, ctx->context_callback_param);
return 0;
});
}
return CELL_OK;
}
@ -131,9 +169,10 @@ error_code sceNpCommerce2CreateSessionAbort(u32 ctx_id)
return CELL_OK;
}
error_code sceNpCommerce2CreateSessionFinish(u32 ctx_id, vm::ptr<SceNpCommerce2SessionInfo> sessionInfo)
s32 sceNpCommerce2CreateSessionFinish(u32 ctx_id, vm::ptr<SceNpCommerce2SessionInfo> sessionInfo)
{
sceNpCommerce2.todo("sceNpCommerce2CreateSessionFinish(ctx_id=%d, sessionInfo=*0x%x)", ctx_id, sessionInfo);
sceNpCommerce2.warning("sceNpCommerce2CreateSessionFinish(ctx_id=%d, sessionInfo=*0x%x)", ctx_id, sessionInfo);
memset(sessionInfo.get_ptr(), 0, sizeof(sessionInfo));
return CELL_OK;
}

View File

@ -77,6 +77,10 @@ enum
SCE_NP_COMMERCE2_EVENT_DO_PRODUCT_CODE_FINISHED = 0x0054,
SCE_NP_COMMERCE2_EVENT_EMPTY_STORE_CHECK_DONE = 0x0061,
SCE_NP_COMMERCE2_EVENT_EMPTY_STORE_CHECK_ABORT = 0x0062,
SCE_NP_COMMERCE2_EVENT_RESERVED01_STARTED = 0x0071,
SCE_NP_COMMERCE2_EVENT_RESERVED01_SUCCESS = 0x0072,
SCE_NP_COMMERCE2_EVENT_RESERVED01_BACK = 0x0073,
SCE_NP_COMMERCE2_EVENT_RESERVED01_FINISHED = 0x0074,
};
// Category data type
@ -103,33 +107,81 @@ enum SceNpCommerce2GameSkuDataType
SCE_NP_COMMERCE2_GAME_SKU_DATA_TYPE_MAX
};
// Constanc for commerce functions and structures
// Store stuff
enum
{
SCE_NP_COMMERCE2_CURRENCY_CODE_LEN = 3,
SCE_NP_COMMERCE2_CURRENCY_SYMBOL_LEN = 3,
SCE_NP_COMMERCE2_THOUSAND_SEPARATOR_LEN = 4,
SCE_NP_COMMERCE2_DECIMAL_LETTER_LEN = 4,
SCE_NP_COMMERCE2_SP_NAME_LEN = 256,
SCE_NP_COMMERCE2_CATEGORY_ID_LEN = 56,
SCE_NP_COMMERCE2_CATEGORY_NAME_LEN = 256,
SCE_NP_COMMERCE2_CATEGORY_DESCRIPTION_LEN = 1024,
SCE_NP_COMMERCE2_PRODUCT_ID_LEN = 48,
SCE_NP_COMMERCE2_PRODUCT_NAME_LEN = 256,
SCE_NP_COMMERCE2_PRODUCT_SHORT_DESCRIPTION_LEN = 1024,
SCE_NP_COMMERCE2_PRODUCT_LONG_DESCRIPTION_LEN = 4000,
SCE_NP_COMMERCE2_SKU_ID_LEN = 56,
SCE_NP_COMMERCE2_SKU_NAME_LEN = 180,
SCE_NP_COMMERCE2_URL_LEN = 256,
SCE_NP_COMMERCE2_RATING_SYSTEM_ID_LEN = 16,
SCE_NP_COMMERCE2_RATING_DESCRIPTION_LEN = 60,
SCE_NP_COMMERCE2_RECV_BUF_SIZE = 262144,
SCE_NP_COMMERCE2_PRODUCT_CODE_BLOCK_LEN = 4,
SCE_NP_COMMERCE2_GETCAT_MAX_COUNT = 60,
SCE_NP_COMMERCE2_DO_CHECKOUT_MEMORY_CONTAINER_SIZE = 10485760,
SCE_NP_COMMERCE2_DO_PROD_BROWSE_MEMORY_CONTAINER_SIZE = 16777216,
SCE_NP_COMMERCE2_DO_DL_LIST_MEMORY_CONTAINER_SIZE = 10485760,
SCE_NP_COMMERCE2_DO_PRODUCT_CODE_MEMORY_CONTAINER_SIZE = 16777216,
SCE_NP_COMMERCE2_STORE_IS_NOT_EMPTY = 0,
SCE_NP_COMMERCE2_STORE_IS_EMPTY = 1,
SCE_NP_COMMERCE2_STORE_CHECK_TYPE_CATEGORY = 1,
SCE_NP_COMMERCE2_STORE_BROWSE_TYPE_CATEGORY = 1,
SCE_NP_COMMERCE2_STORE_BROWSE_TYPE_PRODUCT = 2,
SCE_NP_COMMERCE2_STORE_BROWSE_TYPE_PRODUCT_CODE = 3,
};
// Content Stuff
enum
{
SCE_NP_COMMERCE2_CONTENT_TYPE_CATEGORY = 1,
SCE_NP_COMMERCE2_CONTENT_TYPE_PRODUCT = 2,
SCE_NP_COMMERCE2_CONTENT_RATING_DESC_TYPE_ICON = 1,
SCE_NP_COMMERCE2_CONTENT_RATING_DESC_TYPE_TEXT = 2,
};
// Game SKU
enum
{
SCE_NP_COMMERCE2_SKU_CHECKOUT_MAX = 16,
SCE_NP_COMMERCE2_SKU_DL_LIST_MAX = 16,
SCE_NP_COMMERCE2_SKU_PURCHASABILITY_FLAG_ON = 1,
SCE_NP_COMMERCE2_SKU_PURCHASABILITY_FLAG_OFF = 0,
SCE_NP_COMMERCE2_SKU_ANN_PURCHASED_CANNOT_PURCHASE_AGAIN = 0x80000000,
SCE_NP_COMMERCE2_SKU_ANN_PURCHASED_CAN_PURCHASE_AGAIN = 0x40000000,
SCE_NP_COMMERCE2_SKU_ANN_IN_THE_CART = 0x20000000,
SCE_NP_COMMERCE2_SKU_ANN_CONTENTLINK_SKU = 0x10000000,
SCE_NP_COMMERCE2_SKU_ANN_CREDIT_CARD_REQUIRED = 0x08000000,
SCE_NP_COMMERCE2_SKU_ANN_CHARGE_IMMEDIATELY = 0x04000000,
};
// Constants for commerce functions and structures
enum
{
SCE_NP_COMMERCE2_VERSION = 2,
SCE_NP_COMMERCE2_CTX_MAX = 1,
SCE_NP_COMMERCE2_REQ_MAX = 1,
SCE_NP_COMMERCE2_CURRENCY_CODE_LEN = 3,
SCE_NP_COMMERCE2_CURRENCY_SYMBOL_LEN = 3,
SCE_NP_COMMERCE2_THOUSAND_SEPARATOR_LEN = 4,
SCE_NP_COMMERCE2_DECIMAL_LETTER_LEN = 4,
SCE_NP_COMMERCE2_SP_NAME_LEN = 256,
SCE_NP_COMMERCE2_CATEGORY_ID_LEN = 56,
SCE_NP_COMMERCE2_CATEGORY_NAME_LEN = 256,
SCE_NP_COMMERCE2_CATEGORY_DESCRIPTION_LEN = 1024,
SCE_NP_COMMERCE2_PRODUCT_ID_LEN = 48,
SCE_NP_COMMERCE2_PRODUCT_NAME_LEN = 256,
SCE_NP_COMMERCE2_PRODUCT_SHORT_DESCRIPTION_LEN = 1024,
SCE_NP_COMMERCE2_PRODUCT_LONG_DESCRIPTION_LEN = 4000,
SCE_NP_COMMERCE2_SKU_ID_LEN = 56,
SCE_NP_COMMERCE2_SKU_NAME_LEN = 180,
SCE_NP_COMMERCE2_URL_LEN = 256,
SCE_NP_COMMERCE2_RATING_SYSTEM_ID_LEN = 16,
SCE_NP_COMMERCE2_RATING_DESCRIPTION_LEN = 60,
SCE_NP_COMMERCE2_RECV_BUF_SIZE = 262144,
SCE_NP_COMMERCE2_PRODUCT_CODE_BLOCK_LEN = 4,
SCE_NP_COMMERCE2_PRODUCT_CODE_INPUT_MODE_USER_INPUT = 0,
SCE_NP_COMMERCE2_PRODUCT_CODE_INPUT_MODE_CODE_SPECIFIED = 1,
SCE_NP_COMMERCE2_GETCAT_MAX_COUNT = 60,
SCE_NP_COMMERCE2_GETPRODLIST_MAX_COUNT = 60,
SCE_NP_COMMERCE2_DO_CHECKOUT_MEMORY_CONTAINER_SIZE = 10485760,
SCE_NP_COMMERCE2_DO_PROD_BROWSE_MEMORY_CONTAINER_SIZE = 16777216,
SCE_NP_COMMERCE2_DO_DL_LIST_MEMORY_CONTAINER_SIZE = 10485760,
SCE_NP_COMMERCE2_DO_PRODUCT_CODE_MEMORY_CONTAINER_SIZE = 16777216,
SCE_NP_COMMERCE2_SYM_POS_PRE = 0,
SCE_NP_COMMERCE2_SYM_POS_POST = 1,
};
// Common structure used when receiving data

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,7 @@
#include <vector>
#include <utility>
#include <functional>
#include <queue>
// Error codes
enum sys_net_error : s32
@ -356,6 +357,69 @@ struct lv2_socket final
const lv2_socket_type type;
const lv2_socket_family family;
// SYS_NET_SOCK_DGRAM_P2P and SYS_NET_SOCK_STREAM_P2P socket specific information
struct p2p_i
{
// Port(actual bound port) and Virtual Port(indicated by u16 at the start of the packet)
u16 port = 0, vport = 0;
// Queue containing received packets from network_thread for SYS_NET_SOCK_DGRAM_P2P sockets
std::queue<std::pair<sys_net_sockaddr_in_p2p, std::vector<u8>>> data{};
} p2p;
struct p2ps_i
{
enum tcp_flags : u8
{
FIN = (1 << 0),
SYN = (1 << 1),
RST = (1 << 2),
PSH = (1 << 3),
ACK = (1 << 4),
URG = (1 << 5),
ECE = (1 << 6),
CWR = (1 << 7),
};
static constexpr be_t<u32> U2S_sig = static_cast<u8>('U') << 24 | static_cast<u8>('2') << 16 | static_cast<u8>('S') << 8 | static_cast<u8>('0');
static constexpr std::size_t MAX_RECEIVED_BUFFER = (1024*1024*10);
// P2P stream socket specific
struct encapsulated_tcp
{
be_t<u32> signature = lv2_socket::p2ps_i::U2S_sig; // Signature to verify it's P2P Stream data
be_t<u32> length = 0; // Length of data
be_t<u64> seq = 0; // This should be u32 but changed to u64 for simplicity
be_t<u64> ack = 0;
be_t<u16> src_port = 0; // fake source tcp port
be_t<u16> dst_port = 0; // fake dest tcp port(should be == vport)
be_t<u16> checksum = 0;
u8 flags = 0;
};
enum stream_status
{
stream_closed, // Default when port is not listening nor connected
stream_listening, // Stream is listening, accepting SYN packets
stream_handshaking, // Currently handshaking
stream_connected, // This is an established connection(after tcp handshake)
};
stream_status status = stream_status::stream_closed;
std::size_t max_backlog = 0; // set on listen
std::queue<s32> backlog;
u16 op_port = 0, op_vport = 0;
u32 op_addr = 0;
std::vector<u8> received_data; // resized if needed, on recv will give all continuous data available and move data to beginning of vector
u64 data_beg_seq = 0; // Seq of first byte of received_data
u32 data_available = 0; // Amount of continuous data available(calculated on ACK send)
std::map<u64, u64> data_mapping; // holds seq/size of data received
u32 cur_seq = 0; // SEQ of next packet to be sent
} p2ps;
// Value keepers
#ifdef _WIN32
s32 so_reuseaddr = 0;

406
rpcs3/Emu/NP/fb_helpers.cpp Normal file
View File

@ -0,0 +1,406 @@
#include "stdafx.h"
#include "np_handler.h"
LOG_CHANNEL(rpcn_log, "rpcn");
void np_handler::BinAttr_to_SceNpMatching2BinAttr(const flatbuffers::Vector<flatbuffers::Offset<BinAttr>>* fb_attr, vm::ptr<SceNpMatching2BinAttr> binattr_info)
{
for (flatbuffers::uoffset_t i = 0; i < fb_attr->size(); i++)
{
auto bin_attr = fb_attr->Get(i);
binattr_info[i].id = bin_attr->id();
binattr_info[i].size = bin_attr->data()->size();
binattr_info[i].ptr = allocate(binattr_info[i].size);
for (flatbuffers::uoffset_t tmp_index = 0; tmp_index < bin_attr->data()->size(); tmp_index++)
{
binattr_info[i].ptr[tmp_index] = bin_attr->data()->Get(tmp_index);
}
}
}
void np_handler::RoomGroup_to_SceNpMatching2RoomGroup(const flatbuffers::Vector<flatbuffers::Offset<RoomGroup>>* fb_group, vm::ptr<SceNpMatching2RoomGroup> group_info)
{
for (flatbuffers::uoffset_t i = 0; i < fb_group->size(); i++)
{
auto group = fb_group->Get(i);
group_info[i].groupId = group->groupId();
group_info[i].withPassword = group->withPassword();
group_info[i].withLabel = group->withLabel();
if (group->label())
{
for (flatbuffers::uoffset_t l_index = 0; l_index < group->label()->size(); l_index++)
{
group_info[i].label.data[l_index] = group->label()->Get(l_index);
}
}
group_info[i].slotNum = group->slotNum();
group_info[i].curGroupMemberNum = group->curGroupMemberNum();
}
}
void np_handler::UserInfo2_to_SceNpUserInfo2(const UserInfo2* user, SceNpUserInfo2* user_info)
{
if (user->npId())
memcpy(user_info->npId.handle.data, user->npId()->c_str(), std::min(sizeof(user_info->npId.handle.data), static_cast<std::size_t>(user->npId()->size())));
if (user->onlineName())
{
user_info->onlineName.set(allocate(sizeof(SceNpOnlineName)));
memcpy(user_info->onlineName->data, user->onlineName()->c_str(), std::min(sizeof(user_info->onlineName->data), static_cast<std::size_t>(user->onlineName()->size())));
}
if (user->avatarUrl())
{
user_info->avatarUrl.set(allocate(sizeof(SceNpAvatarUrl)));
memcpy(user_info->avatarUrl->data, user->avatarUrl()->c_str(), std::min(sizeof(user_info->avatarUrl->data), static_cast<std::size_t>(user->avatarUrl()->size())));
}
}
void np_handler::SearchRoomReponse_to_SceNpMatching2SearchRoomResponse(const SearchRoomResponse* resp, SceNpMatching2SearchRoomResponse* search_resp)
{
search_resp->range.size = resp->size();
search_resp->range.startIndex = resp->startIndex();
search_resp->range.total = resp->total();
if (resp->rooms() && resp->rooms()->size() != 0)
{
vm::addr_t previous_next = vm::cast<u32>(0);
for (flatbuffers::uoffset_t i = 0; i < resp->rooms()->size(); i++)
{
auto room = resp->rooms()->Get(i);
vm::ptr<SceNpMatching2RoomDataExternal> room_info(allocate(sizeof(SceNpMatching2RoomDataExternal)));
if (i > 0)
{
vm::ptr<SceNpMatching2RoomDataExternal> prev_room(previous_next);
prev_room->next.set(room_info.addr());
}
else
{
search_resp->roomDataExternal = room_info;
}
previous_next = vm::cast(room_info.addr());
room_info->serverId = room->serverId();
room_info->worldId = room->worldId();
room_info->publicSlotNum = room->publicSlotNum();
room_info->privateSlotNum = room->privateSlotNum();
room_info->lobbyId = room->lobbyId();
room_info->roomId = room->roomId();
room_info->openPublicSlotNum = room->openPublicSlotNum();
room_info->maxSlot = room->maxSlot();
room_info->openPrivateSlotNum = room->openPrivateSlotNum();
room_info->curMemberNum = room->curMemberNum();
room_info->passwordSlotMask = room->curMemberNum();
if (auto owner = room->owner())
{
vm::ptr<SceNpUserInfo2> owner_info(allocate(sizeof(SceNpUserInfo2)));
UserInfo2_to_SceNpUserInfo2(owner, owner_info.get_ptr());
room_info->owner = owner_info;
}
if (room->roomGroup() && room->roomGroup()->size() != 0)
{
room_info->roomGroupNum = room->roomGroup()->size();
vm::ptr<SceNpMatching2RoomGroup> group_info(allocate(sizeof(SceNpMatching2RoomGroup) * room_info->roomGroupNum));
RoomGroup_to_SceNpMatching2RoomGroup(room->roomGroup(), group_info);
room_info->roomGroup = group_info;
}
room_info->flagAttr = room->flagAttr();
if (room->roomSearchableIntAttrExternal() && room->roomSearchableIntAttrExternal()->size() != 0)
{
room_info->roomSearchableIntAttrExternalNum = room->roomSearchableIntAttrExternal()->size();
vm::ptr<SceNpMatching2IntAttr> intattr_info(allocate(sizeof(SceNpMatching2IntAttr) * room_info->roomSearchableIntAttrExternalNum));
for (flatbuffers::uoffset_t a_index = 0; a_index < room->roomSearchableIntAttrExternal()->size(); a_index++)
{
auto int_attr = room->roomSearchableIntAttrExternal()->Get(a_index);
intattr_info[a_index].id = int_attr->id();
intattr_info[a_index].num = int_attr->num();
}
room_info->roomSearchableIntAttrExternal = intattr_info;
}
if (room->roomSearchableBinAttrExternal() && room->roomSearchableBinAttrExternal()->size() != 0)
{
room_info->roomSearchableBinAttrExternalNum = room->roomSearchableBinAttrExternal()->size();
vm::ptr<SceNpMatching2BinAttr> binattr_info(allocate(sizeof(SceNpMatching2BinAttr) * room_info->roomSearchableBinAttrExternalNum));
BinAttr_to_SceNpMatching2BinAttr(room->roomSearchableBinAttrExternal(), binattr_info);
room_info->roomSearchableBinAttrExternal = binattr_info;
}
if (room->roomBinAttrExternal() && room->roomBinAttrExternal()->size() != 0)
{
room_info->roomBinAttrExternalNum = room->roomBinAttrExternal()->size();
vm::ptr<SceNpMatching2BinAttr> binattr_info(allocate(sizeof(SceNpMatching2BinAttr) * room_info->roomBinAttrExternalNum));
BinAttr_to_SceNpMatching2BinAttr(room->roomBinAttrExternal(), binattr_info);
room_info->roomBinAttrExternal = binattr_info;
}
}
}
else
{
search_resp->roomDataExternal.set(0);
}
}
u16 np_handler::RoomDataInternal_to_SceNpMatching2RoomDataInternal(const RoomDataInternal* resp, SceNpMatching2RoomDataInternal* room_info, const SceNpId& npid)
{
u16 member_id = 0;
room_info->serverId = resp->serverId();
room_info->worldId = resp->worldId();
room_info->lobbyId = resp->lobbyId();
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)
{
room_info->roomGroupNum = resp->roomGroup()->size();
vm::ptr<SceNpMatching2RoomGroup> group_info(allocate(sizeof(SceNpMatching2RoomGroup) * room_info->roomGroupNum));
RoomGroup_to_SceNpMatching2RoomGroup(resp->roomGroup(), group_info);
room_info->roomGroup = group_info;
}
vm::ptr<SceNpMatching2RoomMemberDataInternal> prev_member;
for (flatbuffers::uoffset_t i = 0; i < resp->memberList()->size(); i++)
{
auto member = resp->memberList()->Get(i);
vm::ptr<SceNpMatching2RoomMemberDataInternal> member_info(allocate(sizeof(SceNpMatching2RoomMemberDataInternal)));
if (i > 0)
{
prev_member->next = member_info;
}
else
{
room_info->memberList.members = member_info;
room_info->memberList.membersNum = static_cast<u32>(resp->memberList()->size());
}
prev_member = member_info;
UserInfo2_to_SceNpUserInfo2(member->userInfo(), &member_info->userInfo);
member_info->joinDate.tick = member->joinDate();
member_info->memberId = member->memberId();
member_info->teamId = member->teamId();
// Look for id
if (member->roomGroup() != 0)
{
bool found = false;
for (u32 g_index = 0; g_index < room_info->roomGroupNum; g_index++)
{
if (room_info->roomGroup[g_index].groupId == member->roomGroup())
{
member_info->roomGroup = vm::cast(room_info->roomGroup.addr() + (sizeof(SceNpMatching2RoomGroup) * g_index));
found = true;
}
}
ASSERT(found);
}
member_info->natType = member->natType();
member_info->flagAttr = member->flagAttr();
if (member->roomMemberBinAttrInternal() && member->roomMemberBinAttrInternal()->size() != 0)
{
member_info->roomMemberBinAttrInternalNum = member->roomMemberBinAttrInternal()->size();
vm::ptr<SceNpMatching2RoomMemberBinAttrInternal> binattr_info(allocate(sizeof(SceNpMatching2RoomMemberBinAttrInternal) * member_info->roomMemberBinAttrInternalNum));
for (u32 b_index = 0; b_index < member_info->roomMemberBinAttrInternalNum; b_index++)
{
const auto battr = member->roomMemberBinAttrInternal()->Get(b_index);
binattr_info[b_index].updateDate.tick = battr->updateDate();
binattr_info[b_index].data.id = battr->data()->id();
binattr_info[b_index].data.size = battr->data()->data()->size();
binattr_info[b_index].data.ptr = allocate(binattr_info[b_index].data.size);
for (flatbuffers::uoffset_t tmp_index = 0; tmp_index < binattr_info[b_index].data.size; tmp_index++)
{
binattr_info[b_index].data.ptr[tmp_index] = battr->data()->data()->Get(tmp_index);
}
}
member_info->roomMemberBinAttrInternal = binattr_info;
}
}
vm::ptr<SceNpMatching2RoomMemberDataInternal> ptr = room_info->memberList.members;
while (ptr)
{
if (strcmp(ptr->userInfo.npId.handle.data, npid.handle.data) == 0)
{
room_info->memberList.me = ptr;
member_id = ptr->memberId;
break;
}
ptr = ptr->next;
}
ptr = room_info->memberList.members;
while (ptr)
{
if (ptr->memberId == resp->ownerId())
{
room_info->memberList.owner = ptr;
break;
}
ptr = ptr->next;
}
room_info->flagAttr = resp->flagAttr();
if (resp->roomBinAttrInternal() && resp->roomBinAttrInternal()->size() != 0)
{
room_info->roomBinAttrInternalNum = resp->roomBinAttrInternal()->size();
vm::ptr<SceNpMatching2RoomBinAttrInternal> binattrint_info(allocate(sizeof(SceNpMatching2RoomBinAttrInternal) * room_info->roomBinAttrInternalNum));
for (u32 b_index = 0; b_index < room_info->roomBinAttrInternalNum; b_index++)
{
auto battr = resp->roomBinAttrInternal()->Get(b_index);
binattrint_info[b_index].updateDate.tick = battr->updateDate();
binattrint_info[b_index].updateMemberId = battr->updateMemberId();
binattrint_info[b_index].data.id = battr->data()->id();
binattrint_info[b_index].data.size = battr->data()->data()->size();
binattrint_info[b_index].data.ptr = allocate(binattrint_info[b_index].data.size);
for (flatbuffers::uoffset_t tmp_index = 0; tmp_index < binattrint_info[b_index].data.size; tmp_index++)
{
binattrint_info[b_index].data.ptr[tmp_index] = battr->data()->data()->Get(tmp_index);
}
}
room_info->roomBinAttrInternal = binattrint_info;
}
return member_id;
}
void np_handler::RoomMemberUpdateInfo_to_SceNpMatching2RoomMemberUpdateInfo(const RoomMemberUpdateInfo* update_info, SceNpMatching2RoomMemberUpdateInfo* sce_update_info)
{
sce_update_info->eventCause = 0;
if (update_info->optData())
{
sce_update_info->optData.length = update_info->optData()->data()->size();
for (size_t i = 0; i < 16; i++)
{
sce_update_info->optData.data[i] = update_info->optData()->data()->Get(i);
}
}
if (update_info->roomMemberDataInternal())
{
auto member = update_info->roomMemberDataInternal();
vm::ptr<SceNpMatching2RoomMemberDataInternal> member_info(allocate(sizeof(SceNpMatching2RoomMemberDataInternal)));
sce_update_info->roomMemberDataInternal = member_info;
UserInfo2_to_SceNpUserInfo2(member->userInfo(), &member_info->userInfo);
member_info->joinDate.tick = member->joinDate();
member_info->memberId = member->memberId();
member_info->teamId = member->teamId();
// Look for id
// TODO
member_info->natType = member->natType();
member_info->flagAttr = member->flagAttr();
if (member->roomMemberBinAttrInternal() && member->roomMemberBinAttrInternal()->size() != 0)
{
member_info->roomMemberBinAttrInternalNum = member->roomMemberBinAttrInternal()->size();
vm::ptr<SceNpMatching2RoomMemberBinAttrInternal> binattr_info(allocate(sizeof(SceNpMatching2RoomMemberBinAttrInternal) * member_info->roomMemberBinAttrInternalNum));
for (u32 b_index = 0; b_index < member_info->roomMemberBinAttrInternalNum; b_index++)
{
const auto battr = member->roomMemberBinAttrInternal()->Get(b_index);
binattr_info[b_index].updateDate.tick = battr->updateDate();
binattr_info[b_index].data.id = battr->data()->id();
binattr_info[b_index].data.size = battr->data()->data()->size();
binattr_info[b_index].data.ptr = allocate(binattr_info[b_index].data.size);
for (flatbuffers::uoffset_t tmp_index = 0; tmp_index < binattr_info[b_index].data.size; tmp_index++)
{
binattr_info[b_index].data.ptr[tmp_index] = battr->data()->data()->Get(tmp_index);
}
}
member_info->roomMemberBinAttrInternal = binattr_info;
}
}
}
void np_handler::RoomUpdateInfo_to_SceNpMatching2RoomUpdateInfo(const RoomUpdateInfo* update_info, SceNpMatching2RoomUpdateInfo* sce_update_info)
{
sce_update_info->errorCode = 0;
sce_update_info->eventCause = 0;
if (update_info->optData())
{
sce_update_info->optData.length = update_info->optData()->data()->size();
for (size_t i = 0; i < 16; i++)
{
sce_update_info->optData.data[i] = update_info->optData()->data()->Get(i);
}
}
}
void np_handler::GetPingInfoResponse_to_SceNpMatching2SignalingGetPingInfoResponse(const GetPingInfoResponse* resp, SceNpMatching2SignalingGetPingInfoResponse* sce_resp)
{
sce_resp->serverId = resp->serverId();
sce_resp->worldId = resp->worldId();
sce_resp->roomId = resp->roomId();
sce_resp->rtt = resp->rtt();
}
void np_handler::RoomMessageInfo_to_SceNpMatching2RoomMessageInfo(const RoomMessageInfo* mi, SceNpMatching2RoomMessageInfo* sce_mi)
{
sce_mi->filtered = mi->filtered();
sce_mi->castType = mi->castType();
if (sce_mi->castType != SCE_NP_MATCHING2_CASTTYPE_BROADCAST)
{
vm::ptr<SceNpMatching2RoomMessageDestination> dst_info(allocate(sizeof(SceNpMatching2RoomMessageDestination)));
sce_mi->dst = dst_info;
}
switch(sce_mi->castType)
{
case SCE_NP_MATCHING2_CASTTYPE_BROADCAST:
break;
case SCE_NP_MATCHING2_CASTTYPE_UNICAST:
sce_mi->dst->unicastTarget = mi->dst()->Get(0);
break;
case SCE_NP_MATCHING2_CASTTYPE_MULTICAST:
{
sce_mi->dst->multicastTarget.memberIdNum = mi->dst()->size();
vm::ptr<be_t<u16>> member_list(allocate(sizeof(u16) * mi->dst()->size()));
sce_mi->dst->multicastTarget.memberId = member_list;
for (u32 i = 0; i < mi->dst()->size(); i++)
{
sce_mi->dst->multicastTarget.memberId[i] = mi->dst()->Get(i);
}
break;
}
case SCE_NP_MATCHING2_CASTTYPE_MULTICAST_TEAM:
sce_mi->dst->multicastTargetTeamId = mi->dst()->Get(0);
break;
default:
ASSERT(false);
}
if (auto src_member = mi->srcMember())
{
vm::ptr<SceNpUserInfo2> src_info(allocate(sizeof(SceNpUserInfo2)));
UserInfo2_to_SceNpUserInfo2(src_member, src_info.get_ptr());
sce_mi->srcMember = src_info;
}
if (auto msg = mi->msg())
{
sce_mi->msgLen = msg->size();
vm::ptr<u8> msg_data(allocate(msg->size()));
for (u32 i = 0; i < msg->size(); i++)
{
msg_data[i] = msg->Get(i);
}
sce_mi->msg = msg_data;
}
}

View File

@ -0,0 +1,225 @@
table BinAttr {
id:uint16;
data:[uint8];
}
table IntAttr {
id:uint16;
num:uint32;
}
table MemberBinAttrInternal {
updateDate:uint64;
data:BinAttr;
}
table BinAttrInternal {
updateDate:uint64;
updateMemberId:uint16;
data:BinAttr;
}
table OptParam {
type:uint8;
flag:uint8;
hubMemberId:uint16 ;
}
table GroupConfig {
slotNum:uint32;
withLabel:bool;
label:[uint8];
withPassword:bool;
}
table UserInfo2 {
npId:string;
onlineName:string;
avatarUrl:string;
}
table RoomMemberDataInternal {
userInfo:UserInfo2;
joinDate:uint64;
memberId:uint16;
teamId:uint8;
roomGroup:uint8;
natType:uint8;
flagAttr:uint32;
roomMemberBinAttrInternal:[MemberBinAttrInternal];
}
table RoomGroup {
groupId:uint8;
withPassword:bool;
withLabel:bool;
label:[uint8];
slotNum:uint32;
curGroupMemberNum:uint32;
}
table RoomDataInternal {
serverId:uint16;
worldId:uint32;
lobbyId:uint64;
roomId:uint64;
passwordSlotMask:uint64;
maxSlot:uint32;
memberList:[RoomMemberDataInternal];
ownerId:uint16;
roomGroup:[RoomGroup];
flagAttr:uint32;
roomBinAttrInternal:[BinAttrInternal];
}
table RoomDataExternal {
serverId:uint16;
worldId:uint32;
publicSlotNum:uint16;
privateSlotNum:uint16;
lobbyId:uint64;
roomId:uint64;
openPublicSlotNum:uint16;
maxSlot:uint16;
openPrivateSlotNum:uint16;
curMemberNum:uint16;
passwordSlotMask:uint64;
owner:UserInfo2;
roomGroup:[RoomGroup];
flagAttr:uint32;
roomSearchableIntAttrExternal:[IntAttr];
roomSearchableBinAttrExternal:[BinAttr];
roomBinAttrExternal:[BinAttr];
}
table IntSearchFilter {
searchOperator:uint8;
attr:IntAttr;
}
table BinSearchFilter {
searchOperator:uint8;
attr:BinAttr;
}
table PresenceOptionData {
data:[uint8];
len:uint32;
}
table RoomGroupPasswordConfig {
groupId:[uint8];
withPassword:bool;
}
table SearchRoomRequest {
option:int32;
worldId:uint32;
lobbyId:uint64;
rangeFilter_startIndex:uint32;
rangeFilter_max:uint32;
flagFilter:uint32;
flagAttr:uint32;
intFilter:[IntSearchFilter];
binFilter:[BinSearchFilter];
attrId:[uint16];
}
table SearchRoomResponse {
startIndex:uint32;
total:uint32;
size:uint32;
rooms:[RoomDataExternal];
}
table CreateJoinRoomRequest {
worldId:uint32;
lobbyId:uint64;
maxSlot:uint32;
flagAttr:uint32;
roomBinAttrInternal:[BinAttr];
roomSearchableIntAttrExternal:[IntAttr];
roomSearchableBinAttrExternal:[BinAttr];
roomBinAttrExternal:[BinAttr];
roomPassword:[uint8];
groupConfig:[GroupConfig];
passwordSlotMask:uint64;
allowedUser:[string];
blockedUser:[string];
joinRoomGroupLabel:[uint8];
roomMemberBinAttrInternal:[BinAttr];
teamId:uint8;
sigOptParam:OptParam;
}
table JoinRoomRequest {
roomId:uint64;
roomPassword:[uint8];
joinRoomGroupLabel:[uint8];
roomMemberBinAttrInternal:[BinAttr];
optData:PresenceOptionData;
teamId:uint8;
}
table LeaveRoomRequest {
roomId:uint64;
optData:PresenceOptionData;
}
table SetRoomDataExternalRequest {
roomId:uint64;
roomSearchableIntAttrExternal:[IntAttr];
roomSearchableBinAttrExternal:[BinAttr];
roomBinAttrExternal:[BinAttr];
}
table SetRoomDataInternalRequest {
roomId:uint64;
flagFilter:uint32;
flagAttr:uint32;
roomBinAttrInternal:[BinAttr];
passwordConfig:[RoomGroupPasswordConfig];
passwordSlotMask:uint64;
ownerPrivilegeRank:[uint16];
}
table GetRoomDataInternalRequest {
roomId:uint64;
attrId:[uint16];
}
table RoomMemberUpdateInfo {
roomMemberDataInternal:RoomMemberDataInternal;
eventCause:uint8;
optData:PresenceOptionData;
}
table RoomUpdateInfo {
eventCause:uint8;
errorCode:int32;
optData:PresenceOptionData;
}
table GetPingInfoResponse {
serverId:uint16;
worldId:uint32;
roomId:uint64;
rtt:uint32;
}
table SendRoomMessageRequest {
roomId:uint64;
castType:uint8;
dst:[uint16];
msg:[uint8];
option:uint8;
}
table RoomMessageInfo {
filtered:bool;
castType:uint8;
dst:[uint16];
srcMember:UserInfo2;
msg:[uint8];
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +1,47 @@
#pragma once
#include <queue>
#include <map>
#include "Emu/Memory/vm_ptr.h"
#include "Emu/Cell/Modules/sceNp.h"
#include "Emu/Cell/Modules/sceNp2.h"
#include "Emu/Cell/Modules/sceNpCommerce2.h"
#include <queue>
#include <map>
#include "Emu/NP/rpcn_client.h"
#include "generated/np2_structs_generated.h"
struct signaling_info
{
int connStatus = SCE_NP_SIGNALING_CONN_STATUS_INACTIVE;
u32 addr = 0;
u16 port = 0;
};
class np_handler
{
public:
np_handler();
u32 get_local_ip_addr() const;
u32 get_public_ip_addr() const;
u32 get_dns_ip() const;
s32 get_psn_status() const;
s32 get_net_status() const;
const std::string& get_ip() const;
u32 get_dns() const;
const SceNpId& get_npid() const;
const SceNpOnlineId& get_online_id() const;
const SceNpOnlineName& get_online_name() const;
const SceNpAvatarUrl& get_avatar_url() const;
// Public helpers
static std::string ip_to_string(u32 addr);
// Helpers for setting various structures from string
static void string_to_npid(const char* str, SceNpId* npid);
static void string_to_online_name(const char* str, SceNpOnlineName* online_name);
static void string_to_avatar_url(const char* str, SceNpAvatarUrl* avatar_url);
// DNS hooking functions
void add_dns_spy(u32 sock);
void remove_dns_spy(u32 sock);
@ -31,6 +50,17 @@ public:
std::vector<u8> get_dns_packet(u32 sock);
s32 analyze_dns_packet(s32 s, const u8* buf, u32 len);
enum NotificationType : u16
{
UserJoinedRoom,
UserLeftRoom,
RoomDestroyed,
SignalP2PEstablished,
_SignalP2PDisconnected,
RoomMessageReceived,
};
// handles async messages from server(only needed for RPCN)
void operator()();
void init_NP(u32 poolsize, vm::ptr<void> poolptr);
@ -44,6 +74,26 @@ public:
bool is_NP2_Match2_init = false;
bool is_NP_Auth_init = false;
// NP Handlers/Callbacks
// Seems to be global
vm::ptr<SceNpManagerCallback> manager_cb{}; // Connection status and tickets
vm::ptr<void> manager_cb_arg{};
// Registered by SceNpCommunicationId
vm::ptr<SceNpBasicEventHandler> basic_handler;
vm::ptr<void> basic_handler_arg;
// Those should probably be under match2 ctx
vm::ptr<SceNpMatching2RoomEventCallback> room_event_cb{}; // Room events
u16 room_event_cb_ctx = 0;
vm::ptr<void> room_event_cb_arg{};
vm::ptr<SceNpMatching2SignalingCallback> signal_event_cb{}; // Room events
u16 signal_event_cb_ctx = 0;
vm::ptr<void> signal_event_cb_arg{};
vm::ptr<SceNpMatching2RoomMessageCallback> room_msg_cb{};
u16 room_msg_cb_ctx = 0;
vm::ptr<void> room_msg_cb_arg{};
// Score related
struct score_ctx
{
@ -56,9 +106,8 @@ public:
static const u32 id_base = 1;
static const u32 id_step = 1;
static const u32 id_count = 32;
SceNpCommunicationId communicationId;
SceNpCommunicationPassphrase passphrase;
SceNpCommunicationId communicationId{};
SceNpCommunicationPassphrase passphrase{};
};
s32 create_score_context(vm::cptr<SceNpCommunicationId> communicationId, vm::cptr<SceNpCommunicationPassphrase> passphrase);
bool destroy_score_context(s32 ctx_id);
@ -76,15 +125,21 @@ public:
static const u32 id_step = 1;
static const u32 id_count = 255;
SceNpCommunicationId communicationId;
SceNpCommunicationPassphrase passphrase;
SceNpCommunicationId communicationId{};
SceNpCommunicationPassphrase passphrase{};
vm::ptr<SceNpMatching2ContextCallback> context_callback{};
vm::ptr<void> context_callback_param{};
SceNpMatching2RequestOptParam default_match2_optparam{};
};
u16 create_match2_context(vm::cptr<SceNpCommunicationId> communicationId, vm::cptr<SceNpCommunicationPassphrase> passphrase);
std::shared_ptr<match2_ctx> get_match2_context(u16 ctx_id);
bool destroy_match2_context(u16 ctx_id);
struct lookup_ctx
struct lookup_title_ctx
{
lookup_ctx(vm::cptr<SceNpCommunicationId> communicationId)
lookup_title_ctx(vm::cptr<SceNpCommunicationId> communicationId)
{
memcpy(&this->communicationId, communicationId.get_ptr(), sizeof(SceNpCommunicationId));
}
@ -93,22 +148,147 @@ public:
static const u32 id_step = 1;
static const u32 id_count = 32;
SceNpCommunicationId communicationId;
SceNpCommunicationPassphrase passphrase;
SceNpCommunicationId communicationId{};
SceNpCommunicationPassphrase passphrase{};
};
s32 create_lookup_context(vm::cptr<SceNpCommunicationId> communicationId);
bool destroy_lookup_context(s32 ctx_id);
s32 create_lookup_title_context(vm::cptr<SceNpCommunicationId> communicationId);
bool destroy_lookup_title_context(s32 ctx_id);
struct lookup_transaction_ctx
{
lookup_transaction_ctx(s32 lt_ctx)
{
this->lt_ctx = lt_ctx;
}
static const u32 id_base = 1;
static const u32 id_step = 1;
static const u32 id_count = 32;
s32 lt_ctx = 0;
};
s32 create_lookup_transaction_context(s32 lt_ctx);
bool destroy_lookup_transaction_context(s32 ctx_id);
struct commerce2_ctx
{
commerce2_ctx(u32 version, vm::cptr<SceNpId> npid, vm::ptr<SceNpCommerce2Handler> handler, vm::ptr<void> arg)
{
this->version = version;
memcpy(&this->npid, npid.get_ptr(), sizeof(SceNpId));
this->context_callback = handler;
this->context_callback_param = arg;
}
static const u32 id_base = 1;
static const u32 id_step = 1;
static const u32 id_count = 32;
u32 version{};
SceNpId npid{};
vm::ptr<SceNpCommerce2Handler> context_callback{};
vm::ptr<void> context_callback_param{};
};
s32 create_commerce2_context(u32 version, vm::cptr<SceNpId> npid, vm::ptr<SceNpCommerce2Handler> handler, vm::ptr<void> arg);
std::shared_ptr<commerce2_ctx> get_commerce2_context(u16 ctx_id);
bool destroy_commerce2_context(s32 ctx_id);
struct signaling_ctx
{
signaling_ctx(vm::ptr<SceNpId> npid, vm::ptr<SceNpSignalingHandler> handler, vm::ptr<void> arg)
{
memcpy(&this->npid, npid.get_ptr(), sizeof(SceNpId));
this->handler = handler;
this->arg = arg;
}
static const u32 id_base = 1;
static const u32 id_step = 1;
static const u32 id_count = 32;
SceNpId npid{};
vm::ptr<SceNpSignalingHandler> handler{};
vm::ptr<void> arg{};
};
s32 create_signaling_context(vm::ptr<SceNpId> npid, vm::ptr<SceNpSignalingHandler> handler, vm::ptr<void> arg);
bool destroy_signaling_context(s32 ctx_id);
// Synchronous requests
std::vector<SceNpMatching2ServerId> get_match2_server_list(SceNpMatching2ContextId);
// Asynchronous requests
u32 get_server_status(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, u16 server_id);
u32 create_server_context(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, u16 server_id);
u32 get_world_list(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, u16 server_id);
u32 create_join_room(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2CreateJoinRoomRequest* req);
u32 join_room(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2JoinRoomRequest* req);
u32 leave_room(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2LeaveRoomRequest* req);
u32 search_room(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2SearchRoomRequest* req);
u32 set_roomdata_external(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2SetRoomDataExternalRequest* req);
u32 get_roomdata_internal(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2GetRoomDataInternalRequest* req);
u32 set_roomdata_internal(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2SetRoomDataInternalRequest* req);
u32 get_ping_info(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2SignalingGetPingInfoRequest* req);
u32 send_room_message(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2SendRoomMessageRequest* req);
u32 get_match2_event(SceNpMatching2EventKey event_key, u8* dest, u32 size);
const signaling_info& get_peer_infos(u16 context_id, u64 room_id, u16 member_id);
// Misc stuff
u32 add_players_to_history(vm::cptr<SceNpId> npids, u32 count);
static constexpr std::string_view thread_name = "NP Handler Thread";
protected:
// Various generic helpers
bool discover_ip_address();
bool error_and_disconnect(const std::string& error_msg);
// Notification handlers
void notif_user_joined_room(std::vector<u8>& data);
void notif_user_left_room(std::vector<u8>& data);
void notif_room_destroyed(std::vector<u8>& data);
void notif_p2p_established(std::vector<u8>& data);
void notif_room_message_received(std::vector<u8>& data);
// Reply handlers
bool reply_get_world_list(u32 req_id, std::vector<u8>& reply_data);
bool reply_create_join_room(u32 req_id, std::vector<u8>& reply_data);
bool reply_join_room(u32 req_id, std::vector<u8>& reply_data);
bool reply_leave_room(u32 req_id, std::vector<u8>& reply_data);
bool reply_search_room(u32 req_id, std::vector<u8>& reply_data);
bool reply_set_roomdata_external(u32 req_id, std::vector<u8>& reply_data);
bool reply_get_roomdata_internal(u32 req_id, std::vector<u8>& reply_data);
bool reply_set_roomdata_internal(u32 req_id, std::vector<u8>& reply_data);
bool reply_get_ping_info(u32 req_id, std::vector<u8>& reply_data);
bool reply_send_room_message(u32 req_id, std::vector<u8>& reply_data);
// Helper functions(fb=>np2)
void BinAttr_to_SceNpMatching2BinAttr(const flatbuffers::Vector<flatbuffers::Offset<BinAttr>>* fb_attr, vm::ptr<SceNpMatching2BinAttr> binattr_info);
void RoomGroup_to_SceNpMatching2RoomGroup(const flatbuffers::Vector<flatbuffers::Offset<RoomGroup>>* fb_group, vm::ptr<SceNpMatching2RoomGroup> group_info);
void UserInfo2_to_SceNpUserInfo2(const UserInfo2* user, SceNpUserInfo2* user_info);
void SearchRoomReponse_to_SceNpMatching2SearchRoomResponse(const SearchRoomResponse* resp, SceNpMatching2SearchRoomResponse* search_resp);
u16 RoomDataInternal_to_SceNpMatching2RoomDataInternal(const RoomDataInternal* resp, SceNpMatching2RoomDataInternal* room_resp, const SceNpId& npid);
void RoomMemberUpdateInfo_to_SceNpMatching2RoomMemberUpdateInfo(const RoomMemberUpdateInfo* resp, SceNpMatching2RoomMemberUpdateInfo* room_info);
void RoomUpdateInfo_to_SceNpMatching2RoomUpdateInfo(const RoomUpdateInfo* update_info, SceNpMatching2RoomUpdateInfo* sce_update_info);
void GetPingInfoResponse_to_SceNpMatching2SignalingGetPingInfoResponse(const GetPingInfoResponse* resp, SceNpMatching2SignalingGetPingInfoResponse* sce_resp);
void RoomMessageInfo_to_SceNpMatching2RoomMessageInfo(const RoomMessageInfo* mi, SceNpMatching2RoomMessageInfo* sce_mi);
struct callback_info {
SceNpMatching2ContextId ctx_id;
vm::ptr<SceNpMatching2RequestCallback> cb;
vm::ptr<void> cb_arg;
};
u32 generate_callback_info(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam);
std::map<u32, callback_info> pending_requests;
protected:
bool is_connected = false;
bool is_psn_active = false;
// Net infos
std::string cur_ip{};
u32 cur_addr = 0;
u32 dns = 0x08080808;
// IP & DNS info
be_t<u32> local_ip_addr{};
be_t<u32> public_ip_addr{};
be_t<u32> dns_ip = 0x08080808;
// User infos
SceNpId npid{};
@ -125,4 +305,28 @@ protected:
u32 mpool_avail = 0;
std::map<u32, u32> mpool_allocs{}; // offset/size
vm::addr_t allocate(u32 size);
// Memory pool static objects( room_id , internals )
std::map<u64, vm::ptr<SceNpMatching2RoomDataInternal>> room_infos;
// Signal P2P infos (room_id / user_id)
std::map<u64, std::map<u16, signaling_info>> p2p_info{};
// Requests(reqEventKey : data)
std::map<u32, std::vector<u8>> match2_req_results{};
atomic_t<u16> match2_low_reqid_cnt = 1;
atomic_t<u32> match2_event_cnt = 1;
u32 get_req_id(u16 app_req)
{
return ((app_req << 16) | match2_low_reqid_cnt.fetch_add(1));
}
u32 get_event_key()
{
return match2_event_cnt.fetch_add(1);
}
shared_mutex mutex_req_results;
u8* allocate_req_result(u32 event_key, size_t size);
// RPCN
rpcn_client rpcn;
};

View File

@ -0,0 +1,212 @@
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/NP/rpcn_client.h"
#include "np_structs_extra.h"
LOG_CHANNEL(sceNp2);
// Helper functions for printing
namespace extra_nps
{
void print_sigoptparam(const SceNpMatching2SignalingOptParam* opt)
{
sceNp2.warning("type: %d", opt->type);
sceNp2.warning("flag: %d", opt->flag);
sceNp2.warning("hubMemberId: %d", opt->hubMemberId);
}
void print_bin_attr(const SceNpMatching2BinAttr* bin)
{
sceNp2.warning("Id: %d, Size: %d, ptr: 0x%x", bin->id, bin->size, bin->ptr);
std::string dadata{};
for (u32 i = 0; i < bin->size; i++)
{
dadata = fmt::format("%s %02X", dadata, bin->ptr[i]);
}
sceNp2.warning("Data: %s", dadata);
}
void print_bin_attr_internal(const SceNpMatching2RoomBinAttrInternal* bin)
{
sceNp2.warning("updateDate: %llu updateMemberId: %d", bin->updateDate.tick, bin->updateMemberId);
print_bin_attr(&bin->data);
}
void print_member_bin_attr_internal(const SceNpMatching2RoomMemberBinAttrInternal* bin)
{
sceNp2.warning("updateDate: %llu", bin->updateDate.tick);
print_bin_attr(&bin->data);
}
void print_presence_data(const SceNpMatching2PresenceOptionData* opt)
{
std::string dadata{};
for (int i = 0; i < 16; i++)
{
dadata = fmt::format("%s %02X", dadata, opt->data[i]);
}
sceNp2.warning("Data: %s", dadata);
}
void print_range_filter(const SceNpMatching2RangeFilter* filt)
{
sceNp2.warning("startIndex: %d", filt->startIndex);
sceNp2.warning("max: %d", filt->max);
}
void print_createjoinroom(const SceNpMatching2CreateJoinRoomRequest* req)
{
sceNp2.warning("SceNpMatching2CreateJoinRoomRequest:");
sceNp2.warning("worldId: %d", req->worldId);
sceNp2.warning("lobbyId: %d", req->lobbyId);
sceNp2.warning("maxSlot: %d", req->maxSlot);
sceNp2.warning("flagAttr: 0x%x", req->flagAttr);
sceNp2.warning("roomBinAttrInternal: *0x%x", req->roomBinAttrInternal);
sceNp2.warning("roomBinAttrInternalNum: %d", req->roomBinAttrInternalNum);
sceNp2.warning("roomSearchableIntAttrExternal: *0x%x", req->roomSearchableIntAttrExternal);
sceNp2.warning("roomSearchableIntAttrExternalNum: %d", req->roomSearchableIntAttrExternalNum);
sceNp2.warning("roomSearchableBinAttrExternal: *0x%x", req->roomSearchableBinAttrExternal);
sceNp2.warning("roomSearchableBinAttrExternalNum: %d", req->roomSearchableBinAttrExternalNum);
sceNp2.warning("roomBinAttrExternal: *0x%x", req->roomBinAttrExternal);
sceNp2.warning("roomBinAttrExternalNum: %d", req->roomBinAttrExternalNum);
sceNp2.warning("roomPassword: *0x%x", req->roomPassword);
sceNp2.warning("groupConfig: *0x%x", req->groupConfig);
sceNp2.warning("groupConfigNum: %d", req->groupConfigNum);
sceNp2.warning("passwordSlotMask: *0x%x", req->passwordSlotMask);
sceNp2.warning("allowedUser: *0x%x", req->allowedUser);
sceNp2.warning("allowedUserNum: %d", req->allowedUserNum);
sceNp2.warning("blockedUser: *0x%x", req->blockedUser);
sceNp2.warning("blockedUserNum: %d", req->blockedUserNum);
sceNp2.warning("joinRoomGroupLabel: *0x%x", req->joinRoomGroupLabel);
sceNp2.warning("roomMemberBinAttrInternal: *0x%x", req->roomMemberBinAttrInternal);
sceNp2.warning("roomMemberBinAttrInternalNum: %d", req->roomMemberBinAttrInternalNum);
for (u32 i = 0; i < req->roomMemberBinAttrInternalNum; i++)
print_bin_attr(&req->roomMemberBinAttrInternal[i]);
sceNp2.warning("teamId: %d", req->teamId);
sceNp2.warning("sigOptParam: *0x%x", req->sigOptParam);
if (req->sigOptParam)
print_sigoptparam(req->sigOptParam.get_ptr());
for (u32 i = 0; i < req->roomSearchableIntAttrExternalNum; i++)
{
sceNp2.warning("roomSearchableIntAttrExternal(%d) = %d", req->roomSearchableIntAttrExternal[i].id, req->roomSearchableIntAttrExternal[i].num);
}
}
void print_joinroom(const SceNpMatching2JoinRoomRequest* req)
{
sceNp2.warning("SceNpMatching2JoinRoomRequest:");
sceNp2.warning("roomId: %d", req->roomId);
sceNp2.warning("roomPassword: *0x%x", req->roomPassword);
sceNp2.warning("joinRoomGroupLabel: *0x%x", req->joinRoomGroupLabel);
sceNp2.warning("roomMemberBinAttrInternal: *0x%x", req->roomMemberBinAttrInternal);
sceNp2.warning("roomMemberBinAttrInternalNum: %d", req->roomMemberBinAttrInternalNum);
print_presence_data(&req->optData);
sceNp2.warning("teamId: %d", req->teamId);
for (u32 i = 0; i < req->roomMemberBinAttrInternalNum; i++)
print_bin_attr(&req->roomMemberBinAttrInternal[i]);
}
void print_search_room(const SceNpMatching2SearchRoomRequest* req)
{
sceNp2.warning("SceNpMatching2SearchRoomRequest:");
sceNp2.warning("option: 0x%x", req->option);
sceNp2.warning("worldId: %d", req->worldId);
sceNp2.warning("lobbyId: %lld", req->lobbyId);
print_range_filter(&req->rangeFilter);
sceNp2.warning("flagFilter: 0x%x", req->flagFilter);
sceNp2.warning("flagAttr: 0x%x", req->flagAttr);
sceNp2.warning("intFilter: *0x%x", req->intFilter);
sceNp2.warning("intFilterNum: %d", req->intFilterNum);
sceNp2.warning("binFilter: *0x%x", req->binFilter);
sceNp2.warning("binFilterNum: %d", req->binFilterNum);
sceNp2.warning("attrId: *0x%x", req->attrId);
sceNp2.warning("attrIdNum: %d", req->attrIdNum);
}
void print_room_member_data_internal(const SceNpMatching2RoomMemberDataInternal* member)
{
sceNp2.warning("SceNpMatching2RoomMemberDataInternal:");
sceNp2.warning("next: *0x%x", member->next);
sceNp2.warning("npId: %s", member->userInfo.npId.handle.data);
sceNp2.warning("onlineName: %s", member->userInfo.onlineName->data);
sceNp2.warning("avatarUrl: %s", member->userInfo.avatarUrl->data);
sceNp2.warning("joinDate: %lld", member->joinDate.tick);
sceNp2.warning("memberId: %d", member->memberId);
sceNp2.warning("teamId: %d", member->teamId);
sceNp2.warning("roomGroup: *0x%x", member->roomGroup);
sceNp2.warning("natType: %d", member->natType);
sceNp2.warning("flagAttr: 0x%x", member->flagAttr);
sceNp2.warning("roomMemberBinAttrInternal: *0x%x", member->roomMemberBinAttrInternal);
sceNp2.warning("roomMemberBinAttrInternalNum: %d", member->roomMemberBinAttrInternalNum);
for (u32 i = 0; i < member->roomMemberBinAttrInternalNum; i++)
print_member_bin_attr_internal(&member->roomMemberBinAttrInternal[i]);
}
void print_room_data_internal(const SceNpMatching2RoomDataInternal* room)
{
sceNp2.warning("SceNpMatching2RoomDataInternal:");
sceNp2.warning("serverId: %d", room->serverId);
sceNp2.warning("worldId: %d", room->worldId);
sceNp2.warning("lobbyId: %lld", room->lobbyId);
sceNp2.warning("roomId: %lld", room->roomId);
sceNp2.warning("passwordSlotMask: %lld", room->passwordSlotMask);
sceNp2.warning("maxSlot: %d", room->maxSlot);
sceNp2.warning("members: *0x%x", room->memberList.members);
print_room_member_data_internal(room->memberList.members.get_ptr());
sceNp2.warning("membersNum: %d", room->memberList.membersNum);
sceNp2.warning("me: *0x%x", room->memberList.me);
sceNp2.warning("owner: *0x%x", room->memberList.owner);
sceNp2.warning("roomGroup: *0x%x", room->roomGroup);
sceNp2.warning("roomGroupNum: %d", room->roomGroupNum);
sceNp2.warning("flagAttr: 0x%x", room->flagAttr);
sceNp2.warning("roomBinAttrInternal: *0x%x", room->roomBinAttrInternal);
sceNp2.warning("roomBinAttrInternalNum: %d", room->roomBinAttrInternalNum);
for (u32 i = 0; i < room->roomBinAttrInternalNum; i++)
print_bin_attr_internal(&room->roomBinAttrInternal[i]);
}
void print_create_room_resp(const SceNpMatching2CreateJoinRoomResponse *resp)
{
sceNp2.warning("SceNpMatching2CreateJoinRoomResponse:");
sceNp2.warning("roomDataInternal: *0x%x", resp->roomDataInternal);
if(resp->roomDataInternal)
print_room_data_internal(resp->roomDataInternal.get_ptr());
}
void print_set_roomdata_ext_req(const SceNpMatching2SetRoomDataExternalRequest* req)
{
sceNp2.warning("SceNpMatching2SetRoomDataExternalRequest:");
sceNp2.warning("roomId: %d", req->roomId);
sceNp2.warning("roomSearchableIntAttrExternal: *0x%x", req->roomSearchableIntAttrExternal);
sceNp2.warning("roomSearchableIntAttrExternalNum: %d", req->roomSearchableIntAttrExternalNum);
sceNp2.warning("roomSearchableBinAttrExternal: *0x%x", req->roomSearchableBinAttrExternal);
sceNp2.warning("roomSearchableBinAttrExternalNum: %d", req->roomSearchableBinAttrExternalNum);
sceNp2.warning("roomBinAttrExternal: *0x%x", req->roomBinAttrExternal);
sceNp2.warning("roomBinAttrExternalNum: %d", req->roomBinAttrExternalNum);
}
void print_set_roomdata_int_req(const SceNpMatching2SetRoomDataInternalRequest* req)
{
sceNp2.warning("SceNpMatching2SetRoomDataInternalRequest:");
sceNp2.warning("roomId: %d", req->roomId);
sceNp2.warning("flagFilter: 0x%x", req->flagFilter);
sceNp2.warning("flagAttr: 0x%x", req->flagAttr);
sceNp2.warning("roomBinAttrInternal: *0x%x", req->roomBinAttrInternal);
sceNp2.warning("roomBinAttrInternalNum: %d", req->roomBinAttrInternalNum);
sceNp2.warning("passwordConfig: *0x%x", req->passwordConfig);
sceNp2.warning("passwordConfigNum: %d", req->passwordConfigNum);
sceNp2.warning("passwordSlotMask: *0x%x", req->passwordSlotMask);
sceNp2.warning("ownerPrivilegeRank: *0x%x", req->ownerPrivilegeRank);
sceNp2.warning("ownerPrivilegeRankNum: %d", req->ownerPrivilegeRankNum);
}
} // namespace extra_nps

View File

@ -0,0 +1,23 @@
#pragma once
#include "Emu/Memory/vm_ptr.h"
#include "Emu/Cell/Modules/sceNp.h"
#include "Emu/Cell/Modules/sceNp2.h"
#include "Emu/NP/rpcn_client.h"
namespace extra_nps
{
void print_sigoptparam(const SceNpMatching2SignalingOptParam* opt);
void print_bin_attr(const SceNpMatching2BinAttr* bin);
void print_presence_data(const SceNpMatching2PresenceOptionData* opt);
void print_range_filter(const SceNpMatching2RangeFilter* filt);
void print_room_data_internal(const SceNpMatching2RoomDataInternal* room);
void print_room_member_data_internal(const SceNpMatching2RoomMemberDataInternal* member);
void print_createjoinroom(const SceNpMatching2CreateJoinRoomRequest* req);
void print_create_room_resp(const SceNpMatching2CreateJoinRoomResponse* resp);
void print_joinroom(const SceNpMatching2JoinRoomRequest* req);
void print_search_room(const SceNpMatching2SearchRoomRequest* req);
void print_set_roomdata_ext_req(const SceNpMatching2SetRoomDataExternalRequest* req);
void print_set_roomdata_int_req(const SceNpMatching2SetRoomDataInternalRequest* req);
} // namespace extra_nps

1125
rpcs3/Emu/NP/rpcn_client.cpp Normal file

File diff suppressed because it is too large Load Diff

253
rpcs3/Emu/NP/rpcn_client.h Normal file
View File

@ -0,0 +1,253 @@
#pragma once
#include <map>
#include <unordered_map>
#include <chrono>
#include "Utilities/mutex.h"
#ifdef _WIN32
#include <winsock2.h>
#include <WS2tcpip.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include "Emu/Memory/vm.h"
#include "Emu/Memory/vm_ptr.h"
#include "Emu/Cell/Modules/sceNp.h"
#include "Emu/Cell/Modules/sceNp2.h"
#include "generated/np2_structs_generated.h"
#include <wolfssl/ssl.h>
class vec_stream
{
public:
vec_stream() = delete;
vec_stream(std::vector<u8>& _vec, size_t initial_index = 0)
: vec(_vec)
, i(initial_index){};
bool is_error() const
{
return error;
}
// Getters
template <typename T>
T get()
{
if (sizeof(T) + i > vec.size())
{
error = true;
return 0;
}
T res = reinterpret_cast<le_t<T>&>(vec[i]);
i += sizeof(T);
return res;
}
std::string get_string(bool empty)
{
std::string res{};
while (i < vec.size() && vec[i] != 0)
{
res.push_back(vec[i]);
i++;
}
i++;
if (!empty && res.size() == 0)
{
error = true;
}
return res;
}
std::vector<u8> get_rawdata()
{
std::vector<u8> ret;
u32 size = get<u32>();
if ((vec.begin() + i + size) <= vec.end())
std::copy(vec.begin() + i, vec.begin() + i + size, std::back_inserter(ret));
else
error = true;
return ret;
}
// Setters
template <typename T>
void insert(T value)
{
value = reinterpret_cast<le_t<T>>(value);
// resize + memcpy instead?
for (size_t index = 0; index < sizeof(T); index++)
{
vec.push_back(*(reinterpret_cast<u8*>(&value) + index));
}
}
void insert_string(const std::string& str)
{
std::copy(str.begin(), str.end(), std::back_inserter(vec));
vec.push_back(0);
}
protected:
std::vector<u8>& vec;
size_t i = 0;
bool error = false;
};
enum CommandType : u16
{
Login,
Terminate,
Create,
SendToken,
GetServerList,
GetWorldList,
CreateRoom,
JoinRoom,
LeaveRoom,
SearchRoom,
SetRoomDataExternal,
GetRoomDataInternal,
SetRoomDataInternal,
PingRoomOwner,
SendRoomMessage,
};
class rpcn_client
{
enum PacketType : u8
{
Request,
Reply,
Notification,
ServerInfo,
};
enum ErrorType : u8
{
NoError,
Malformed,
Invalid,
InvalidInput,
ErrorLogin,
ErrorCreate,
AlreadyLoggedIn,
DbFail,
NotFound,
Unsupported,
__error_last
};
public:
rpcn_client(bool in_config = false);
~rpcn_client();
bool connect(const std::string& host);
bool login(const std::string& npid, const std::string& password, const std::string& token);
bool create_user(const std::string& npid, const std::string& password, const std::string& online_name, const std::string& avatar_url, const std::string& email);
void disconnect();
bool manage_connection();
std::vector<std::pair<u16, std::vector<u8>>> get_notifications();
std::unordered_map<u32, std::pair<u16, std::vector<u8>>> get_replies();
void abort();
// Synchronous requests
bool get_server_list(u32 req_id, const std::string& communication_id, std::vector<u16>& server_list);
// Asynchronous requests
bool get_world_list(u32 req_id, u16 server_id);
bool createjoin_room(u32 req_id, const SceNpMatching2CreateJoinRoomRequest* req);
bool join_room(u32 req_id, const SceNpMatching2JoinRoomRequest* req);
bool leave_room(u32 req_id, const SceNpMatching2LeaveRoomRequest* req);
bool search_room(u32 req_id, const SceNpMatching2SearchRoomRequest* req);
bool set_roomdata_external(u32 req_id, const SceNpMatching2SetRoomDataExternalRequest* req);
bool get_roomdata_internal(u32 req_id, const SceNpMatching2GetRoomDataInternalRequest* req);
bool set_roomdata_internal(u32 req_id, const SceNpMatching2SetRoomDataInternalRequest* req);
bool ping_room_owner(u32 req_id, u64 room_id);
bool send_room_message(u32 req_id, const SceNpMatching2SendRoomMessageRequest* req);
const std::string& get_online_name() const
{
return online_name;
}
const std::string& get_avatar_url() const
{
return avatar_url;
};
u32 get_addr_sig() const
{
return addr_sig.load();
}
u16 get_port_sig() const
{
return port_sig.load();
}
protected:
enum class recvn_result
{
recvn_success,
recvn_nodata,
recvn_timeout,
recvn_noconn,
recvn_fatal,
};
recvn_result recvn(u8* buf, std::size_t n);
bool get_reply(u32 expected_id, std::vector<u8>& data);
std::vector<u8> forge_request(u16 command, u32 packet_id, const std::vector<u8>& data) const;
bool send_packet(const std::vector<u8>& packet);
bool forge_send(u16 command, u32 packet_id, const std::vector<u8>& data);
bool forge_send_reply(u16 command, u32 packet_id, const std::vector<u8>& data, std::vector<u8>& reply_data);
bool is_error(ErrorType err) const;
bool error_and_disconnect(const std::string& error_mgs);
bool is_abort();
std::string get_wolfssl_error(int error);
protected:
atomic_t<bool> connected = false;
atomic_t<bool> authentified = false;
WOLFSSL_CTX* wssl_ctx = nullptr;
WOLFSSL* wssl = nullptr;
bool in_config = false;
bool abort_config = false;
atomic_t<bool> server_info_received = false;
u32 received_version = 0;
// UDP Signaling related
std::chrono::time_point<std::chrono::system_clock> last_ping_time{}, last_pong_time{};
sockaddr_in addr_rpcn{};
sockaddr_in addr_rpcn_udp{};
int sockfd = 0;
shared_mutex mutex_socket;
shared_mutex mutex_notifs, mutex_replies, mutex_replies_sync;
std::vector<std::pair<u16, std::vector<u8>>> notifications; // notif type / data
std::unordered_map<u32, std::pair<u16, std::vector<u8>>> replies; // req id / (command / data)
std::unordered_map<u32, std::pair<u16, std::vector<u8>>> replies_sync; // same but for sync replies(Login, Create, GetServerList)
std::string online_name{};
std::string avatar_url{};
s64 user_id = 0;
atomic_t<u32> addr_sig{};
atomic_t<u16> port_sig{};
};

View File

@ -0,0 +1,110 @@
#include "stdafx.h"
#include "rpcn_config.h"
#include "Emu/System.h"
cfg_rpcn g_cfg_rpcn;
LOG_CHANNEL(rpcn_cfg_log, "rpcn config");
void cfg_rpcn::load()
{
fs::file cfg_file(cfg_rpcn::get_path(), fs::read);
if (cfg_file)
{
from_string(cfg_file.to_string());
}
}
void cfg_rpcn::save() const
{
#ifdef _WIN32
const std::string path_to_cfg = fs::get_config_dir() + "config/";
if (!fs::create_path(path_to_cfg))
{
rpcn_cfg_log.error("Could not create path: %s", path_to_cfg);
}
#endif
fs::file cfg_file(cfg_rpcn::get_path(), fs::rewrite);
if (cfg_file)
{
cfg_file.write(to_string());
}
else
{
rpcn_cfg_log.error("Could not save config: %s", cfg_rpcn::get_path());
}
}
std::string cfg_rpcn::get_path()
{
#ifdef _WIN32
return fs::get_config_dir() + "config/rpcn.yml";
#else
return fs::get_config_dir() + "rpcn.yml";
#endif
}
std::string cfg_rpcn::generate_npid()
{
std::string gen_npid = "RPCS3_";
const char list_chars[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
std::srand(time(nullptr));
for (int i = 0; i < 10; i++)
{
gen_npid += list_chars[std::rand() % (sizeof(list_chars))];
}
return gen_npid;
}
std::string cfg_rpcn::get_host() const
{
return host.to_string();
}
std::string cfg_rpcn::get_npid()
{
std::string final_npid = npid.to_string();
if (final_npid == "")
{
final_npid = cfg_rpcn::generate_npid();
save();
}
return final_npid;
}
std::string cfg_rpcn::get_password() const
{
return password.to_string();
}
std::string cfg_rpcn::get_token() const
{
return token.to_string();
}
void cfg_rpcn::set_host(const std::string& host)
{
this->host.from_string(host);
}
void cfg_rpcn::set_npid(const std::string& npid)
{
this->npid.from_string(npid);
}
void cfg_rpcn::set_password(const std::string& password)
{
this->password.from_string(password);
}
void cfg_rpcn::set_token(const std::string& token)
{
this->token.from_string(token);
}

View File

@ -0,0 +1,32 @@
#pragma once
#include "Utilities/Config.h"
LOG_CHANNEL(rpcn_cfg, "RPCN Config");
struct cfg_rpcn : cfg::node
{
cfg::string host{this, "Host", "np.rpcs3.net"};
cfg::string npid{this, "NPID", ""};
cfg::string password{this, "Password", ""};
cfg::string token{this, "Token", ""};
void load();
void save() const;
std::string get_host() const;
std::string get_npid(); // not const because it can save if npid is requested and it has never been set
std::string get_password() const;
std::string get_token() const;
void set_host(const std::string& host);
void set_npid(const std::string& npid);
void set_password(const std::string& password);
void set_token(const std::string& token);
private:
static std::string get_path();
static std::string generate_npid();
};
extern cfg_rpcn g_cfg_rpcn;

View File

@ -262,7 +262,6 @@ struct cfg_root : cfg::node
cfg::string swap_list{this, "IP swap list", ""};
cfg::_enum<np_psn_status> psn_status{this, "PSN status", np_psn_status::disabled};
cfg::string psn_npid{this, "NPID", ""};
} net{this};
struct node_misc : cfg::node

View File

@ -230,6 +230,7 @@ void fmt_class_string<np_psn_status>::format(std::string& out, u64 arg)
{
case np_psn_status::disabled: return "Disconnected";
case np_psn_status::fake: return "Simulated";
case np_psn_status::rpcn: return "RPCN";
}
return unknown;

View File

@ -186,6 +186,7 @@ enum np_psn_status
{
disabled,
fake,
rpcn,
};
enum class shader_mode

View File

@ -64,7 +64,7 @@
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>..\3rdparty\libusb\libusb;..\3rdparty\zlib;..\llvm\include;..\llvm_build\include;$(VULKAN_SDK)\Include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\3rdparty\wolfssl\;..\3rdparty\flatbuffers\include;..\3rdparty\libusb\libusb;..\3rdparty\zlib;..\llvm\include;..\llvm_build\include;$(VULKAN_SDK)\Include</AdditionalIncludeDirectories>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">MaxSpeed</Optimization>
</ClCompile>
<PreBuildEvent>
@ -100,6 +100,7 @@
<ClCompile Include="Emu\Io\KeyboardHandler.cpp" />
<ClCompile Include="Emu\Io\pad_config.cpp" />
<ClCompile Include="Emu\Io\pad_config_types.cpp" />
<ClCompile Include="Emu\NP\rpcn_config.cpp" />
<ClCompile Include="Emu\RSX\Overlays\overlay_osk_panel.cpp" />
<ClCompile Include="Emu\RSX\Overlays\overlay_utils.cpp" />
<ClCompile Include="Emu\RSX\Overlays\Shaders\shader_loading_dialog.cpp" />
@ -107,7 +108,10 @@
<ClCompile Include="Emu\system_config_types.cpp" />
<ClCompile Include="Emu\title.cpp" />
<ClCompile Include="Emu\system_config.cpp" />
<ClCompile Include="Emu\NP\fb_helpers.cpp" />
<ClCompile Include="Emu\NP\np_handler.cpp" />
<ClCompile Include="Emu\NP\np_structs_extra.cpp" />
<ClCompile Include="Emu\NP\rpcn_client.cpp" />
<ClCompile Include="util\atomic.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
@ -483,7 +487,11 @@
<ClInclude Include="Emu\Io\Keyboard.h" />
<ClInclude Include="Emu\Io\pad_config.h" />
<ClInclude Include="Emu\Io\pad_config_types.h" />
<ClInclude Include="Emu\NP\generated\np2_structs_generated.h" />
<ClInclude Include="Emu\NP\np_handler.h" />
<ClInclude Include="Emu\NP\np_structs_extra.h" />
<ClInclude Include="Emu\NP\rpcn_client.h" />
<ClInclude Include="Emu\NP\rpcn_config.h" />
<ClInclude Include="Emu\RSX\Common\ShaderInterpreter.h" />
<ClInclude Include="Emu\RSX\Common\texture_cache_helpers.h" />
<ClInclude Include="Emu\RSX\Overlays\overlay_fonts.h" />

View File

@ -926,6 +926,9 @@
<ClCompile Include="Emu\RSX\Overlays\overlay_utils.cpp">
<Filter>Emu\GPU\RSX\Overlays</Filter>
</ClCompile>
<ClCompile Include="Emu\NP\fb_helpers.cpp">
<Filter>Emu\NP</Filter>
</ClCompile>
<ClCompile Include="Emu\NP\np_handler.cpp">
<Filter>Emu\NP</Filter>
</ClCompile>
@ -953,6 +956,15 @@
<ClCompile Include="..\Utilities\cheat_info.cpp">
<Filter>Utilities</Filter>
</ClCompile>
<ClCompile Include="Emu\NP\np_structs_extra.cpp">
<Filter>Emu\NP</Filter>
</ClCompile>
<ClCompile Include="Emu\NP\rpcn_client.cpp">
<Filter>Emu\NP</Filter>
</ClCompile>
<ClCompile Include="Emu\NP\rpcn_config.cpp">
<Filter>Emu\NP</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Crypto\aes.h">
@ -1828,6 +1840,18 @@
<ClInclude Include="..\Utilities\cheat_info.h">
<Filter>Utilities</Filter>
</ClInclude>
<ClInclude Include="Emu\NP\np_structs_extra.h">
<Filter>Emu\NP</Filter>
</ClInclude>
<ClInclude Include="Emu\NP\rpcn_client.h">
<Filter>Emu\NP</Filter>
</ClInclude>
<ClInclude Include="Emu\NP\generated\np2_structs_generated.h">
<Filter>Emu\NP</Filter>
</ClInclude>
<ClInclude Include="Emu\NP\rpcn_config.h">
<Filter>Emu\NP</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="Emu\RSX\Common\Interpreter\FragmentInterpreter.glsl">

View File

@ -175,7 +175,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">
<ClCompile>
<AdditionalIncludeDirectories>..\3rdparty\wolfssl;..\3rdparty\curl\include;..\3rdparty\libusb\libusb;$(VULKAN_SDK)\Include;..\3rdparty\XAudio2Redist\include;$(QTDIR)\include;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtCore;.\release;$(QTDIR)\mkspecs\win32-msvc2015;.\QTGeneratedFiles\$(ConfigurationName);.\QTGeneratedFiles;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtConcurrent;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\3rdparty\flatbuffers\include;..\3rdparty\wolfssl;..\3rdparty\curl\include;..\3rdparty\libusb\libusb;$(VULKAN_SDK)\Include;..\3rdparty\XAudio2Redist\include;$(QTDIR)\include;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtCore;.\release;$(QTDIR)\mkspecs\win32-msvc2015;.\QTGeneratedFiles\$(ConfigurationName);.\QTGeneratedFiles;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtConcurrent;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>-Zc:strictStrings -Zc:throwingNew -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
<AssemblerListingLocation>release\</AssemblerListingLocation>
<BrowseInformation>false</BrowseInformation>
@ -226,7 +226,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<AdditionalIncludeDirectories>..\3rdparty\wolfssl;..\3rdparty\curl\include;..\3rdparty\libusb\libusb;$(VULKAN_SDK)\Include;..\3rdparty\XAudio2Redist\include;$(QTDIR)\include;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtCore;.\debug;$(QTDIR)\mkspecs\win32-msvc2015;.\QTGeneratedFiles\$(ConfigurationName);.\QTGeneratedFiles;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtConcurrent;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\3rdparty\flatbuffers\include;..\3rdparty\wolfssl;..\3rdparty\curl\include;..\3rdparty\libusb\libusb;$(VULKAN_SDK)\Include;..\3rdparty\XAudio2Redist\include;$(QTDIR)\include;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtCore;.\debug;$(QTDIR)\mkspecs\win32-msvc2015;.\QTGeneratedFiles\$(ConfigurationName);.\QTGeneratedFiles;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtConcurrent;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>-Zc:strictStrings -Zc:throwingNew -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
<AssemblerListingLocation>debug\</AssemblerListingLocation>
<BrowseInformation>false</BrowseInformation>
@ -278,7 +278,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">
<ClCompile>
<AdditionalIncludeDirectories>..\3rdparty\wolfssl;..\3rdparty\curl\include;..\3rdparty\libusb\libusb;$(VULKAN_SDK)\Include;..\3rdparty\XAudio2Redist\include;$(QTDIR)\include;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtCore;.\debug;$(QTDIR)\mkspecs\win32-msvc2015;.\QTGeneratedFiles\$(ConfigurationName);.\QTGeneratedFiles;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtConcurrent;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\3rdparty\flatbuffers\include;..\3rdparty\wolfssl;..\3rdparty\curl\include;..\3rdparty\libusb\libusb;$(VULKAN_SDK)\Include;..\3rdparty\XAudio2Redist\include;$(QTDIR)\include;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtCore;.\debug;$(QTDIR)\mkspecs\win32-msvc2015;.\QTGeneratedFiles\$(ConfigurationName);.\QTGeneratedFiles;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtConcurrent;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>-Zc:strictStrings -Zc:throwingNew -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
<AssemblerListingLocation>debug\</AssemblerListingLocation>
<BrowseInformation>false</BrowseInformation>
@ -541,6 +541,11 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_rpcn_settings_dialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_rsx_debugger.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@ -831,6 +836,11 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_rpcn_settings_dialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_rsx_debugger.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
@ -1141,6 +1151,11 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_rpcn_settings_dialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_rsx_debugger.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
@ -1431,6 +1446,11 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_rpcn_settings_dialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_rsx_debugger.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@ -1542,6 +1562,7 @@
<ClCompile Include="rpcs3qt\pkg_install_dialog.cpp" />
<ClCompile Include="rpcs3qt\persistent_settings.cpp" />
<ClCompile Include="rpcs3qt\render_creator.cpp" />
<ClCompile Include="rpcs3qt\rpcn_settings_dialog.cpp" />
<ClCompile Include="rpcs3qt\screenshot_manager_dialog.cpp" />
<ClCompile Include="rpcs3qt\screenshot_preview.cpp" />
<ClCompile Include="rpcs3qt\settings.cpp" />
@ -2349,6 +2370,24 @@
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\wolfssl" "-I.\..\3rdparty\curl\include" "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent"</Command>
</CustomBuild>
<CustomBuild Include="rpcs3qt\rpcn_settings_dialog.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">Moc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl" "-I.\..\3rdparty\curl\include" "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl" "-I.\..\3rdparty\curl\include" "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\wolfssl" "-I.\..\3rdparty\curl\include" "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">Moc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl" "-I.\..\3rdparty\curl\include" "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent"</Command>
</CustomBuild>
<ClInclude Include="rpcs3qt\stylesheets.h" />
<CustomBuild Include="rpcs3qt\skylander_dialog.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>

View File

@ -1075,6 +1075,21 @@
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_downloader.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\rpcn_settings_dialog.cpp">
<Filter>Gui\settings</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_rpcn_settings_dialog.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_rpcn_settings_dialog.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_rpcn_settings_dialog.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_rpcn_settings_dialog.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Input\ds4_pad_handler.h">
@ -1397,6 +1412,9 @@
<CustomBuild Include="rpcs3qt\downloader.h">
<Filter>Gui\network</Filter>
</CustomBuild>
<CustomBuild Include="rpcs3qt\rpcn_settings_dialog.h">
<Filter>Gui\settings</Filter>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<Image Include="rpcs3.ico" />

View File

@ -44,6 +44,7 @@
qt_utils.cpp
register_editor_dialog.cpp
render_creator.cpp
rpcn_settings_dialog.cpp
rsx_debugger.cpp
save_data_dialog.cpp
save_data_info_dialog.cpp

View File

@ -127,7 +127,6 @@ enum class emu_settings_type
DNSAddress,
IpSwapList,
PSNStatus,
PSNNPID,
// System
Language,
@ -268,7 +267,6 @@ static const QMap<emu_settings_type, cfg_location> settings_location =
{ emu_settings_type::DNSAddress, { "Net", "DNS address"}},
{ emu_settings_type::IpSwapList, { "Net", "IP swap list"}},
{ emu_settings_type::PSNStatus, { "Net", "PSN status"}},
{ emu_settings_type::PSNNPID, { "Net", "NPID"}},
// System
{ emu_settings_type::Language, { "System", "Language"}},

View File

@ -12,6 +12,7 @@
#include "debugger_frame.h"
#include "log_frame.h"
#include "settings_dialog.h"
#include "rpcn_settings_dialog.h"
#include "auto_pause_settings_dialog.h"
#include "cg_disasm_window.h"
#include "memory_string_searcher.h"
@ -1590,6 +1591,12 @@ void main_window::CreateConnects()
connect(ui->confPadsAct, &QAction::triggered, open_pad_settings);
connect(ui->confRPCNAct, &QAction::triggered, [this]()
{
rpcn_settings_dialog dlg(this);
dlg.exec();
});
connect(ui->confAutopauseManagerAct, &QAction::triggered, [this]()
{
auto_pause_settings_dialog dlg(this);

View File

@ -141,7 +141,7 @@
<x>0</x>
<y>0</y>
<width>1058</width>
<height>26</height>
<height>30</height>
</rect>
</property>
<property name="contextMenuPolicy">
@ -226,6 +226,7 @@
<addaction name="confEmuAct"/>
<addaction name="confGuiAct"/>
<addaction name="separator"/>
<addaction name="confRPCNAct"/>
<addaction name="confAutopauseManagerAct"/>
</widget>
<widget class="QMenu" name="menuManage">
@ -1101,6 +1102,14 @@
<string>Game Patches</string>
</property>
</action>
<action name="confRPCNAct">
<property name="text">
<string>RPCN</string>
</property>
<property name="toolTip">
<string>Configure RPCN</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>

View File

@ -0,0 +1,229 @@
#include <QMessageBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QRegExpValidator>
#include <QInputDialog>
#include <thread>
#include "rpcn_settings_dialog.h"
#include "Emu/NP/rpcn_config.h"
#include "Emu/NP/rpcn_client.h"
#include <wolfssl/ssl.h>
#include <wolfssl/openssl/evp.h>
rpcn_settings_dialog::rpcn_settings_dialog(QWidget* parent)
: QDialog(parent)
{
setWindowTitle(tr("RPCN Configuration"));
setObjectName("rpcn_settings_dialog");
setMinimumSize(QSize(400, 200));
QVBoxLayout* vbox_global = new QVBoxLayout();
QHBoxLayout* hbox_labels_and_edits = new QHBoxLayout();
QVBoxLayout* vbox_labels = new QVBoxLayout();
QVBoxLayout* vbox_edits = new QVBoxLayout();
QHBoxLayout* hbox_buttons = new QHBoxLayout();
QLabel* label_host = new QLabel(tr("Host:"));
m_edit_host = new QLineEdit();
QLabel* label_npid = new QLabel(tr("NPID (username):"));
m_edit_npid = new QLineEdit();
m_edit_npid->setMaxLength(16);
m_edit_npid->setValidator(new QRegExpValidator(QRegExp("^[a-zA-Z0-9_\\-]*$"), this));
QLabel* label_pass = new QLabel(tr("Password:"));
QPushButton* btn_chg_pass = new QPushButton(tr("Set Password"));
QLabel *label_token = new QLabel(tr("Token:"));
m_edit_token = new QLineEdit();
QPushButton* btn_create = new QPushButton(tr("Create Account"), this);
QPushButton* btn_save = new QPushButton(tr("Save"), this);
vbox_labels->addWidget(label_host);
vbox_labels->addWidget(label_npid);
vbox_labels->addWidget(label_pass);
vbox_labels->addWidget(label_token);
vbox_edits->addWidget(m_edit_host);
vbox_edits->addWidget(m_edit_npid);
vbox_edits->addWidget(btn_chg_pass);
vbox_edits->addWidget(m_edit_token);
hbox_buttons->addWidget(btn_create);
hbox_buttons->addStretch();
hbox_buttons->addWidget(btn_save);
hbox_labels_and_edits->addLayout(vbox_labels);
hbox_labels_and_edits->addLayout(vbox_edits);
vbox_global->addLayout(hbox_labels_and_edits);
vbox_global->addLayout(hbox_buttons);
setLayout(vbox_global);
connect(btn_chg_pass, &QAbstractButton::clicked, [this]()
{
QString password;
while (true)
{
bool clicked_ok = false;
password = QInputDialog::getText(this, "Set/Change Password", "Set your password", QLineEdit::Password, "", &clicked_ok);
if (!clicked_ok)
return;
if (password.isEmpty())
{
QMessageBox::critical(this, tr("Wrong input"), tr("You need to enter a password!"), QMessageBox::Ok);
}
else
{
break;
}
}
std::string pass_str = password.toStdString();
std::string salt_str = "No matter where you go, everybody's connected.";
u8 salted_pass[SHA_DIGEST_SIZE];
wolfSSL_PKCS5_PBKDF2_HMAC_SHA1(pass_str.c_str(), pass_str.size(), reinterpret_cast<const u8*>(salt_str.c_str()), salt_str.size(), 1000, SHA_DIGEST_SIZE, salted_pass);
std::string hash("0000000000000000000000000000000000000000");
for (u32 i = 0; i < 20; i++)
{
constexpr auto pal = "0123456789abcdef";
hash[i * 2] = pal[salted_pass[i] >> 4];
hash[1 + i * 2] = pal[salted_pass[i] & 15];
}
g_cfg_rpcn.set_password(hash);
g_cfg_rpcn.save();
});
connect(btn_save, &QAbstractButton::clicked, [this]()
{
if (this->save_config())
this->close();
});
connect(btn_create, &QAbstractButton::clicked, [this]() { this->create_account(); });
g_cfg_rpcn.load();
m_edit_host->setText(QString::fromStdString(g_cfg_rpcn.get_host()));
m_edit_npid->setText(QString::fromStdString(g_cfg_rpcn.get_npid()));
m_edit_token->setText(QString::fromStdString(g_cfg_rpcn.get_token()));
}
bool rpcn_settings_dialog::save_config()
{
const auto host = m_edit_host->text().toStdString();
const auto npid = m_edit_npid->text().toStdString();
const auto token = m_edit_token->text().toStdString();
auto validate = [](const std::string& input) -> bool
{
if (input.length() < 3 || input.length() > 16)
return false;
for (const auto c : input)
{
if (!std::isalnum(c) && c != '-' && c != '_')
return false;
}
return true;
};
if (host.empty())
{
QMessageBox::critical(this, tr("Missing host"), tr("You need to enter a host for rpcn!"), QMessageBox::Ok);
return false;
}
if (npid.empty() || g_cfg_rpcn.get_password().empty())
{
QMessageBox::critical(this, tr("Wrong input"), tr("You need to enter a username and a password!"), QMessageBox::Ok);
return false;
}
if (!validate(npid))
{
QMessageBox::critical(this, tr("Invalid character"), tr("NPID must be between 3 and 16 characters and can only contain '-', '_' or alphanumeric characters."), QMessageBox::Ok);
return false;
}
g_cfg_rpcn.set_host(host);
g_cfg_rpcn.set_npid(npid);
g_cfg_rpcn.set_token(token);
g_cfg_rpcn.save();
return true;
}
bool rpcn_settings_dialog::create_account()
{
// Validate and save
if (!save_config())
return false;
QString email;
QRegExpValidator simple_email_validator(QRegExp("^[a-zA-Z0-9.!#$%&*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$"));
while (true)
{
bool clicked_ok = false;
email = QInputDialog::getText(this, "Email address", "An email address is required, please note:\n*A valid email is needed to validate your account.\n*Your email won't be used for anything beyond sending you the token.\n*Upon successful creation a token will be sent to your email which you'll need to login.\n\n", QLineEdit::Normal, "", &clicked_ok);
if (!clicked_ok)
return false;
int pos = 0;
if (email.isEmpty() || simple_email_validator.validate(email, pos) != QValidator::Acceptable)
{
QMessageBox::critical(this, tr("Wrong input"), tr("You need to enter a valid email!"), QMessageBox::Ok);
}
else
{
break;
}
}
const auto rpcn = std::make_shared<rpcn_client>(true);
const auto host = g_cfg_rpcn.get_host();
const auto npid = g_cfg_rpcn.get_npid();
const auto online_name = npid;
const auto avatar_url = "https://rpcs3.net/cdn/netplay/DefaultAvatar.png";
const auto password = g_cfg_rpcn.get_password();
std::thread(
[](const std::shared_ptr<rpcn_client> rpcn)
{
while (rpcn.use_count() != 1)
rpcn->manage_connection();
rpcn->disconnect();
},
rpcn)
.detach();
if (!rpcn->connect(host))
{
QMessageBox::critical(this, tr("Error Connecting"), tr("Failed to connect to RPCN server"), QMessageBox::Ok);
rpcn->abort();
return false;
}
if (!rpcn->create_user(npid, password, online_name, avatar_url, email.toStdString()))
{
QMessageBox::critical(this, tr("Error Creating Account"), tr("Failed to create the account"), QMessageBox::Ok);
rpcn->abort();
return false;
}
QMessageBox::information(this, tr("Account created!"), tr("Your account has been created successfully!\nCheck your email for your token!"), QMessageBox::Ok);
rpcn->abort();
return true;
}

View File

@ -0,0 +1,20 @@
#pragma once
#include <QDialog>
#include <QLineEdit>
class rpcn_settings_dialog : public QDialog
{
Q_OBJECT
public:
rpcn_settings_dialog(QWidget* parent = nullptr);
bool save_config();
bool create_account();
protected:
QLineEdit *m_edit_host, *m_edit_npid, *m_edit_token;
std::string generate_npid();
};

View File

@ -875,9 +875,6 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
m_emu_settings->EnhanceLineEdit(ui->edit_dns, emu_settings_type::DNSAddress);
SubscribeTooltip(ui->gb_edit_dns, tooltips.settings.dns);
m_emu_settings->EnhanceLineEdit(ui->edit_npid, emu_settings_type::PSNNPID);
SubscribeTooltip(ui->gb_edit_npid, tooltips.settings.psn_npid);
m_emu_settings->EnhanceLineEdit(ui->edit_swaps, emu_settings_type::IpSwapList);
SubscribeTooltip(ui->gb_edit_swaps, tooltips.settings.dns_swap);
@ -892,28 +889,6 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
});
ui->edit_dns->setEnabled(ui->netStatusBox->currentIndex() > 0);
connect(ui->psnStatusBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index)
{
ui->edit_npid->setEnabled(index > 0);
if (index > 0 && ui->edit_npid->text() == "")
{
QString gen_npid = "RPCS3_";
constexpr char list_chars[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
std::srand(time(0));
for (int i = 0; i < 10; i++)
{
gen_npid += list_chars[std::rand() % (sizeof(list_chars) - 1)];
}
ui->edit_npid->setText(gen_npid);
}
});
m_emu_settings->EnhanceComboBox(ui->psnStatusBox, emu_settings_type::PSNStatus);
SubscribeTooltip(ui->gb_psnStatusBox, tooltips.settings.psn_status);

View File

@ -1676,39 +1676,6 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gb_edit_npid">
<property name="title">
<string>PSN settings</string>
</property>
<layout class="QVBoxLayout" name="gb_edit_npid_layout">
<item>
<layout class="QHBoxLayout" name="edit_npid_layout">
<item>
<widget class="QLabel" name="edit_npid_label">
<property name="text">
<string>NPID:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="edit_npid">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maxLength">
<number>16</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="networkTabSpacerRight">
<property name="orientation">

View File

@ -180,11 +180,10 @@ public:
// network
const QString net_status = tr("If set to Connected, RPCS3 will allow programs to use your internet connection.");
const QString psn_status = tr("If set to Simulated, RPCS3 will fake PSN connection as best as it can.");
const QString dns = tr("DNS used to resolve hostnames by applications.");
const QString psn_npid = tr("Identifier representing your PSN account.");
const QString dns_swap = tr("DNS Swap List.");
const QString net_status = tr("If set to Connected, RPCS3 will allow programs to use your internet connection.");
const QString psn_status = tr("If set to Simulated, RPCS3 will fake PSN connection as best as it can.");
const QString dns = tr("DNS used to resolve hostnames by applications.");
const QString dns_swap = tr("DNS Swap List.");
// system