2025-02-05 20:28:08 +01:00
# include "Emu/Cell/Modules/sceNp.h"
# include "Emu/Cell/Modules/sceNp2.h"
# include "Emu/NP/rpcn_types.h"
# include "Utilities/StrFmt.h"
2021-10-28 06:36:57 +02:00
# include "stdafx.h"
2025-02-11 03:00:37 +01:00
# include "Emu/Cell/PPUCallback.h"
2022-10-23 15:35:19 +02:00
# include "Emu/Cell/lv2/sys_sync.h"
2021-10-28 06:36:57 +02:00
# include "Emu/system_config.h"
# include "Emu/Cell/Modules/cellSysutil.h"
# include "Emu/Memory/vm_ptr.h"
# include "Emu/IdManager.h"
# include "np_handler.h"
# include "np_contexts.h"
2022-05-18 17:44:21 +02:00
# include "np_helpers.h"
2021-10-28 06:36:57 +02:00
# include "np_structs_extra.h"
2024-05-14 00:12:50 +02:00
# include "fb_helpers.h"
2025-02-11 03:00:37 +01:00
# include "Emu/NP/signaling_handler.h"
2025-02-05 20:28:08 +01:00
# include "Emu/NP/ip_address.h"
2021-10-28 06:36:57 +02:00
LOG_CHANNEL ( rpcn_log , " rpcn " ) ;
namespace np
{
std : : vector < SceNpMatching2ServerId > np_handler : : get_match2_server_list ( SceNpMatching2ContextId ctx_id )
{
std : : vector < SceNpMatching2ServerId > server_list { } ;
if ( g_cfg . net . psn_status ! = np_psn_status : : psn_rpcn )
{
return server_list ;
}
2023-04-01 21:52:07 +02:00
if ( ! get_rpcn ( ) - > get_server_list ( get_req_id ( REQUEST_ID_HIGH : : MISC ) , get_match2_context ( ctx_id ) - > communicationId , server_list ) )
2021-10-28 06:36:57 +02:00
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
return server_list ;
}
2023-04-01 21:52:07 +02:00
u64 np_handler : : get_network_time ( )
{
// If network time hasn't been set we need to sync time with the rpcn server
auto get_local_timestamp = [ ] ( ) - > u64
{
return std : : chrono : : duration_cast < std : : chrono : : microseconds > ( steady_clock : : now ( ) . time_since_epoch ( ) ) . count ( ) ;
} ;
if ( ! network_time_offset )
{
// Could be improved with multiple requests to increase latency determination accuracy
const u64 req_timestamp = get_local_timestamp ( ) ;
const u64 server_timestamp = get_rpcn ( ) - > get_network_time ( get_req_id ( REQUEST_ID_HIGH : : MISC ) ) ;
if ( ! server_timestamp )
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
return 0 ;
}
const u64 reply_timestamp = get_local_timestamp ( ) ;
const u64 latency = ( reply_timestamp - req_timestamp ) / 2 ;
network_time_offset = reply_timestamp - ( server_timestamp + latency ) ;
}
return get_local_timestamp ( ) - network_time_offset ;
}
2021-10-28 06:36:57 +02:00
u32 np_handler : : get_server_status ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , u16 server_id )
{
// TODO: actually implement interaction with server for this?
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_GetServerInfo ) ;
2024-09-20 20:24:59 +02:00
const u32 event_key = get_event_key ( ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
auto & edata = allocate_req_result ( event_key , SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetServerInfo , sizeof ( SceNpMatching2GetServerInfoResponse ) ) ;
2021-10-28 06:36:57 +02:00
SceNpMatching2GetServerInfoResponse * serv_info = reinterpret_cast < SceNpMatching2GetServerInfoResponse * > ( edata . data ( ) ) ;
2023-01-12 04:05:05 +01:00
serv_info - > server . serverId = server_id ;
serv_info - > server . status = SCE_NP_MATCHING2_SERVER_STATUS_AVAILABLE ;
2021-10-28 06:36:57 +02:00
np_memory . shrink_allocation ( edata . addr ( ) , edata . size ( ) ) ;
2023-01-12 04:05:05 +01:00
const auto cb_info_opt = take_pending_request ( req_id ) ;
ensure ( cb_info_opt ) ;
cb_info_opt - > queue_callback ( req_id , event_key , 0 , edata . size ( ) ) ;
2021-10-28 06:36:57 +02:00
return req_id ;
}
u32 np_handler : : create_server_context ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , u16 /*server_id*/ )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_CreateServerContext ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
const auto cb_info_opt = take_pending_request ( req_id ) ;
ensure ( cb_info_opt ) ;
cb_info_opt - > queue_callback ( req_id , 0 , 0 , 0 ) ;
2021-10-28 06:36:57 +02:00
return req_id ;
}
2021-11-07 17:26:30 +01:00
u32 np_handler : : delete_server_context ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , u16 /*server_id*/ )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_DeleteServerContext ) ;
2021-11-07 17:26:30 +01:00
2023-01-12 04:05:05 +01:00
const auto cb_info_opt = take_pending_request ( req_id ) ;
ensure ( cb_info_opt ) ;
cb_info_opt - > queue_callback ( req_id , 0 , 0 , 0 ) ;
2021-11-07 17:26:30 +01:00
return req_id ;
}
2021-10-28 06:36:57 +02:00
u32 np_handler : : get_world_list ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , u16 server_id )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_GetWorldInfoList ) ;
2021-10-28 06:36:57 +02:00
2023-03-03 10:45:29 +01:00
if ( ! get_rpcn ( ) - > get_world_list ( req_id , get_match2_context ( ctx_id ) - > communicationId , server_id ) )
2021-10-28 06:36:57 +02:00
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
return req_id ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_get_world_list ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2021-10-28 06:36:57 +02:00
{
2023-01-12 04:05:05 +01:00
auto cb_info_opt = take_pending_request ( req_id ) ;
if ( ! cb_info_opt )
2025-02-05 20:28:08 +01:00
return ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
ensure ( error = = rpcn : : ErrorType : : NoError , " Unexpected error in GetWorldList reply " ) ;
2021-10-28 06:36:57 +02:00
std : : vector < u32 > world_list ;
u32 num_worlds = reply . get < u32 > ( ) ;
for ( u32 i = 0 ; i < num_worlds ; i + + )
{
world_list . push_back ( reply . get < u32 > ( ) ) ;
}
2025-02-05 20:28:08 +01:00
ensure ( ! reply . is_error ( ) , " Malformed reply to GetWorldList command " ) ;
2021-10-28 06:36:57 +02:00
2024-09-20 20:24:59 +02:00
const u32 event_key = get_event_key ( ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
auto & edata = allocate_req_result ( event_key , SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetWorldInfoList , sizeof ( SceNpMatching2GetWorldInfoListResponse ) ) ;
auto * world_info = reinterpret_cast < SceNpMatching2GetWorldInfoListResponse * > ( edata . data ( ) ) ;
2023-12-29 18:33:29 +01:00
world_info - > worldNum = : : size32 ( world_list ) ;
2021-10-28 06:36:57 +02:00
if ( ! world_list . empty ( ) )
{
2023-12-29 18:33:29 +01:00
auto * worlds = edata . allocate < SceNpMatching2World > ( : : narrow < u32 > ( sizeof ( SceNpMatching2World ) * world_list . size ( ) ) , world_info - > world ) ;
2021-10-28 06:36:57 +02:00
for ( usz i = 0 ; i < world_list . size ( ) ; i + + )
{
2023-01-12 04:05:05 +01:00
worlds [ i ] . worldId = world_list [ i ] ;
2021-10-28 06:36:57 +02:00
}
}
np_memory . shrink_allocation ( edata . addr ( ) , edata . size ( ) ) ;
2023-01-12 04:05:05 +01:00
cb_info_opt - > queue_callback ( req_id , event_key , 0 , edata . size ( ) ) ;
2021-10-28 06:36:57 +02:00
}
u32 np_handler : : create_join_room ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , const SceNpMatching2CreateJoinRoomRequest * req )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_CreateJoinRoom ) ;
2021-10-28 06:36:57 +02:00
2024-09-20 20:24:59 +02:00
extra_nps : : print_SceNpMatching2CreateJoinRoomRequest ( req ) ;
2022-05-18 17:44:21 +02:00
2023-03-03 10:45:29 +01:00
if ( ! get_rpcn ( ) - > createjoin_room ( req_id , get_match2_context ( ctx_id ) - > communicationId , req ) )
2021-10-28 06:36:57 +02:00
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
2021-11-03 00:53:57 +01:00
// More elegant solution would be to send back password with creation reply
cached_cj_password = req - > roomPassword ? std : : optional < SceNpMatching2SessionPassword > { * req - > roomPassword } : std : : nullopt ;
2021-10-28 06:36:57 +02:00
return req_id ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_create_join_room ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2021-10-28 06:36:57 +02:00
{
2023-01-12 04:05:05 +01:00
auto cb_info_opt = take_pending_request ( req_id ) ;
if ( ! cb_info_opt )
2025-02-05 20:28:08 +01:00
return ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
s32 error_code = CELL_OK ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
switch ( error )
{
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : RoomGroupMaxSlotMismatch : error_code = SCE_NP_MATCHING2_SERVER_ERROR_MAX_OVER_SLOT_GROUP ; break ;
case rpcn : : ErrorType : : RoomPasswordMissing : error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_PASSWORD ; break ;
case rpcn : : ErrorType : : RoomGroupNoJoinLabel : error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_JOIN_GROUP_LABEL ; break ;
default : fmt : : throw_exception ( " Unexpected error in reply to CreateRoom: %d " , static_cast < u8 > ( error ) ) ;
}
if ( error_code ! = CELL_OK )
{
cb_info_opt - > queue_callback ( req_id , 0 , error_code , 0 ) ;
return ;
}
const auto * resp = reply . get_flatbuffer < RoomDataInternal > ( ) ;
ensure ( ! reply . is_error ( ) , " Malformed reply to CreateRoom command " ) ;
2021-10-28 06:36:57 +02:00
2024-09-20 20:24:59 +02:00
const u32 event_key = get_event_key ( ) ;
2024-05-16 04:52:15 +02:00
auto [ include_onlinename , include_avatarurl ] = get_match2_context_options ( cb_info_opt - > ctx_id ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
auto & edata = allocate_req_result ( event_key , SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_CreateJoinRoom , sizeof ( SceNpMatching2CreateJoinRoomResponse ) ) ;
2021-10-28 06:36:57 +02:00
auto * room_resp = reinterpret_cast < SceNpMatching2CreateJoinRoomResponse * > ( edata . data ( ) ) ;
auto * room_info = edata . allocate < SceNpMatching2RoomDataInternal > ( sizeof ( SceNpMatching2RoomDataInternal ) , room_resp - > roomDataInternal ) ;
2024-05-16 04:52:15 +02:00
RoomDataInternal_to_SceNpMatching2RoomDataInternal ( edata , resp , room_info , npid , include_onlinename , include_avatarurl ) ;
2021-10-28 06:36:57 +02:00
np_memory . shrink_allocation ( edata . addr ( ) , edata . size ( ) ) ;
2021-11-03 00:53:57 +01:00
np_cache . insert_room ( room_info ) ;
np_cache . update_password ( room_resp - > roomDataInternal - > roomId , cached_cj_password ) ;
2024-09-20 20:24:59 +02:00
extra_nps : : print_SceNpMatching2CreateJoinRoomResponse ( room_resp ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
cb_info_opt - > queue_callback ( req_id , event_key , 0 , edata . size ( ) ) ;
2021-10-28 06:36:57 +02:00
}
u32 np_handler : : join_room ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , const SceNpMatching2JoinRoomRequest * req )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_JoinRoom ) ;
2021-10-28 06:36:57 +02:00
2024-09-20 20:24:59 +02:00
extra_nps : : print_SceNpMatching2JoinRoomRequest ( req ) ;
2022-05-18 17:44:21 +02:00
2023-03-03 10:45:29 +01:00
if ( ! get_rpcn ( ) - > join_room ( req_id , get_match2_context ( ctx_id ) - > communicationId , req ) )
2021-10-28 06:36:57 +02:00
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
return req_id ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_join_room ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2021-10-28 06:36:57 +02:00
{
2023-01-12 04:05:05 +01:00
auto cb_info_opt = take_pending_request ( req_id ) ;
if ( ! cb_info_opt )
2025-02-05 20:28:08 +01:00
return ;
2023-01-12 04:05:05 +01:00
2022-10-01 14:40:16 +02:00
s32 error_code = 0 ;
2025-02-05 20:28:08 +01:00
switch ( error )
2022-10-01 14:40:16 +02:00
{
2025-02-05 20:28:08 +01:00
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : RoomMissing : error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM ; break ;
case rpcn : : ErrorType : : RoomAlreadyJoined : error_code = SCE_NP_MATCHING2_SERVER_ERROR_ALREADY_JOINED ; break ;
case rpcn : : ErrorType : : RoomFull : error_code = SCE_NP_MATCHING2_SERVER_ERROR_ROOM_FULL ; break ;
case rpcn : : ErrorType : : RoomPasswordMismatch : error_code = SCE_NP_MATCHING2_SERVER_ERROR_PASSWORD_MISMATCH ; break ;
case rpcn : : ErrorType : : RoomGroupFull : error_code = SCE_NP_MATCHING2_SERVER_ERROR_GROUP_FULL ; break ;
case rpcn : : ErrorType : : RoomGroupJoinLabelNotFound : error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_GROUP ; break ;
2025-02-19 21:40:01 +01:00
default : fmt : : throw_exception ( " Unexpected error in reply to JoinRoom: %d " , static_cast < u8 > ( error ) ) ;
2022-10-01 14:40:16 +02:00
}
if ( error_code ! = 0 )
{
2023-01-12 04:05:05 +01:00
cb_info_opt - > queue_callback ( req_id , 0 , error_code , 0 ) ;
2025-02-05 20:28:08 +01:00
return ;
2022-10-01 14:40:16 +02:00
}
2025-02-05 20:28:08 +01:00
const auto * resp = reply . get_flatbuffer < JoinRoomResponse > ( ) ;
ensure ( ! reply . is_error ( ) , " Malformed reply to JoinRoom command " ) ;
ensure ( resp - > room_data ( ) ) ;
2021-10-28 06:36:57 +02:00
2024-09-20 20:24:59 +02:00
const u32 event_key = get_event_key ( ) ;
2025-02-05 20:28:08 +01:00
const auto [ include_onlinename , include_avatarurl ] = get_match2_context_options ( cb_info_opt - > ctx_id ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
auto & edata = allocate_req_result ( event_key , SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_JoinRoom , sizeof ( SceNpMatching2JoinRoomResponse ) ) ;
2021-10-28 06:36:57 +02:00
auto * room_resp = reinterpret_cast < SceNpMatching2JoinRoomResponse * > ( edata . data ( ) ) ;
auto * room_info = edata . allocate < SceNpMatching2RoomDataInternal > ( sizeof ( SceNpMatching2RoomDataInternal ) , room_resp - > roomDataInternal ) ;
2025-02-05 20:28:08 +01:00
RoomDataInternal_to_SceNpMatching2RoomDataInternal ( edata , resp - > room_data ( ) , room_info , npid , include_onlinename , include_avatarurl ) ;
2021-10-28 06:36:57 +02:00
np_memory . shrink_allocation ( edata . addr ( ) , edata . size ( ) ) ;
2021-11-03 00:53:57 +01:00
np_cache . insert_room ( room_info ) ;
2024-09-20 20:24:59 +02:00
extra_nps : : print_SceNpMatching2RoomDataInternal ( room_info ) ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
// We initiate signaling if necessary
if ( const auto * signaling_data = resp - > signaling_data ( ) )
{
const u64 room_id = resp - > room_data ( ) - > roomId ( ) ;
for ( unsigned int i = 0 ; i < signaling_data - > size ( ) ; i + + )
{
const auto * signaling_info = signaling_data - > Get ( i ) ;
ensure ( signaling_info - > addr ( ) ) ;
const u32 addr_p2p = register_ip ( signaling_info - > addr ( ) - > ip ( ) ) ;
const u16 port_p2p = signaling_info - > addr ( ) - > port ( ) ;
const u16 member_id = signaling_info - > member_id ( ) ;
const auto [ npid_res , npid_p2p ] = np_cache . get_npid ( room_id , member_id ) ;
if ( npid_res ! = CELL_OK )
continue ;
rpcn_log . notice ( " JoinRoomResult told to connect to member(%d=%s) of room(%d): %s:%d " , member_id , reinterpret_cast < const char * > ( npid_p2p - > handle . data ) , room_id , ip_to_string ( addr_p2p ) , port_p2p ) ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
// Attempt Signaling
auto & sigh = g_fxo - > get < named_thread < signaling_handler > > ( ) ;
const u32 conn_id = sigh . init_sig2 ( * npid_p2p , room_id , member_id ) ;
sigh . start_sig ( conn_id , addr_p2p , port_p2p ) ;
}
}
cb_info_opt - > queue_callback ( req_id , event_key , 0 , edata . size ( ) ) ;
2021-10-28 06:36:57 +02:00
}
u32 np_handler : : leave_room ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , const SceNpMatching2LeaveRoomRequest * req )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_LeaveRoom ) ;
2021-10-28 06:36:57 +02:00
2023-03-03 10:45:29 +01:00
if ( ! get_rpcn ( ) - > leave_room ( req_id , get_match2_context ( ctx_id ) - > communicationId , req ) )
2021-10-28 06:36:57 +02:00
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
return req_id ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_leave_room ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2021-10-28 06:36:57 +02:00
{
2023-01-12 04:05:05 +01:00
auto cb_info_opt = take_pending_request ( req_id ) ;
if ( ! cb_info_opt )
2025-02-05 20:28:08 +01:00
return ;
s32 error_code = CELL_OK ;
switch ( error )
{
case rpcn : : ErrorType : : NoError : break ;
2025-02-19 21:40:01 +01:00
case rpcn : : ErrorType : : NotFound : error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM ; break ; // Unsure if this should return another error(missing user in room has no appropriate error code)
2025-02-05 20:28:08 +01:00
case rpcn : : ErrorType : : RoomMissing : error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM ; break ;
2025-02-19 21:40:01 +01:00
default : fmt : : throw_exception ( " Unexpected error in reply to LeaveRoom: %d " , static_cast < u8 > ( error ) ) ;
2025-02-05 20:28:08 +01:00
}
if ( error_code ! = CELL_OK )
{
cb_info_opt - > queue_callback ( req_id , 0 , error_code , 0 ) ;
return ;
}
2021-10-28 06:36:57 +02:00
u64 room_id = reply . get < u64 > ( ) ;
2025-02-05 20:28:08 +01:00
ensure ( ! reply . is_error ( ) , " Malformed reply to LeaveRoom command " ) ;
2021-10-28 06:36:57 +02:00
// Disconnect all users from that room
auto & sigh = g_fxo - > get < named_thread < signaling_handler > > ( ) ;
sigh . disconnect_sig2_users ( room_id ) ;
2023-01-12 04:05:05 +01:00
cb_info_opt - > queue_callback ( req_id , 0 , 0 , 0 ) ;
2021-10-28 06:36:57 +02:00
}
u32 np_handler : : search_room ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , const SceNpMatching2SearchRoomRequest * req )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_SearchRoom ) ;
2021-10-28 06:36:57 +02:00
2024-09-20 20:24:59 +02:00
extra_nps : : print_SceNpMatching2SearchRoomRequest ( req ) ;
2022-05-18 17:44:21 +02:00
2023-03-03 10:45:29 +01:00
if ( ! get_rpcn ( ) - > search_room ( req_id , get_match2_context ( ctx_id ) - > communicationId , req ) )
2021-10-28 06:36:57 +02:00
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
return req_id ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_search_room ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2021-10-28 06:36:57 +02:00
{
2023-01-12 04:05:05 +01:00
auto cb_info_opt = take_pending_request ( req_id ) ;
if ( ! cb_info_opt )
2025-02-05 20:28:08 +01:00
return ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
ensure ( error = = rpcn : : ErrorType : : NoError , " Unexpected error in SearchRoom reply " ) ;
2022-10-01 14:40:16 +02:00
2025-02-05 20:28:08 +01:00
const auto * resp = reply . get_flatbuffer < SearchRoomResponse > ( ) ;
ensure ( ! reply . is_error ( ) , " Malformed reply to SearchRoom command " ) ;
2021-10-28 06:36:57 +02:00
2024-09-20 20:24:59 +02:00
const u32 event_key = get_event_key ( ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
auto & edata = allocate_req_result ( event_key , SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_SearchRoom , sizeof ( SceNpMatching2SearchRoomResponse ) ) ;
2021-10-28 06:36:57 +02:00
auto * search_resp = reinterpret_cast < SceNpMatching2SearchRoomResponse * > ( edata . data ( ) ) ;
2024-05-16 04:52:15 +02:00
// The online_name and avatar_url are naturally filtered by the reply from the server
2021-10-28 06:36:57 +02:00
SearchRoomResponse_to_SceNpMatching2SearchRoomResponse ( edata , resp , search_resp ) ;
np_memory . shrink_allocation ( edata . addr ( ) , edata . size ( ) ) ;
2024-09-20 20:24:59 +02:00
extra_nps : : print_SceNpMatching2SearchRoomResponse ( search_resp ) ;
2023-01-12 04:05:05 +01:00
cb_info_opt - > queue_callback ( req_id , event_key , 0 , edata . size ( ) ) ;
2021-10-28 06:36:57 +02:00
}
u32 np_handler : : get_roomdata_external_list ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , const SceNpMatching2GetRoomDataExternalListRequest * req )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_GetRoomDataExternalList ) ;
2021-10-28 06:36:57 +02:00
2024-09-20 20:24:59 +02:00
extra_nps : : print_SceNpMatching2GetRoomDataExternalListRequest ( req ) ;
2022-05-18 17:44:21 +02:00
2023-03-03 10:45:29 +01:00
if ( ! get_rpcn ( ) - > get_roomdata_external_list ( req_id , get_match2_context ( ctx_id ) - > communicationId , req ) )
2021-10-28 06:36:57 +02:00
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
return req_id ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_get_roomdata_external_list ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2021-10-28 06:36:57 +02:00
{
2023-01-12 04:05:05 +01:00
auto cb_info_opt = take_pending_request ( req_id ) ;
if ( ! cb_info_opt )
2025-02-05 20:28:08 +01:00
return ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
ensure ( error = = rpcn : : ErrorType : : NoError , " Unexpected error in GetRoomDataExternalList reply " ) ;
2022-10-01 14:40:16 +02:00
2025-02-05 20:28:08 +01:00
const auto * resp = reply . get_flatbuffer < GetRoomDataExternalListResponse > ( ) ;
ensure ( ! reply . is_error ( ) , " Malformed reply to GetRoomDataExternalList command " ) ;
2021-10-28 06:36:57 +02:00
2024-09-20 20:24:59 +02:00
const u32 event_key = get_event_key ( ) ;
2024-05-16 04:52:15 +02:00
auto [ include_onlinename , include_avatarurl ] = get_match2_context_options ( cb_info_opt - > ctx_id ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
auto & edata = allocate_req_result ( event_key , SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetRoomDataExternalList , sizeof ( SceNpMatching2GetRoomDataExternalListResponse ) ) ;
2021-10-28 06:36:57 +02:00
auto * sce_get_room_ext_resp = reinterpret_cast < SceNpMatching2GetRoomDataExternalListResponse * > ( edata . data ( ) ) ;
2024-05-16 04:52:15 +02:00
GetRoomDataExternalListResponse_to_SceNpMatching2GetRoomDataExternalListResponse ( edata , resp , sce_get_room_ext_resp , include_onlinename , include_avatarurl ) ;
2021-10-28 06:36:57 +02:00
np_memory . shrink_allocation ( edata . addr ( ) , edata . size ( ) ) ;
2024-09-20 20:24:59 +02:00
extra_nps : : print_SceNpMatching2GetRoomDataExternalListResponse ( sce_get_room_ext_resp ) ;
2022-05-18 17:44:21 +02:00
2023-01-12 04:05:05 +01:00
cb_info_opt - > queue_callback ( req_id , event_key , 0 , edata . size ( ) ) ;
2021-10-28 06:36:57 +02:00
}
u32 np_handler : : set_roomdata_external ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , const SceNpMatching2SetRoomDataExternalRequest * req )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomDataExternal ) ;
2021-10-28 06:36:57 +02:00
2024-09-20 20:24:59 +02:00
extra_nps : : print_SceNpMatching2SetRoomDataExternalRequest ( req ) ;
2021-10-28 06:36:57 +02:00
2023-03-03 10:45:29 +01:00
if ( ! get_rpcn ( ) - > set_roomdata_external ( req_id , get_match2_context ( ctx_id ) - > communicationId , req ) )
2021-10-28 06:36:57 +02:00
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
return req_id ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_set_roomdata_external ( u32 req_id , rpcn : : ErrorType error )
2021-10-28 06:36:57 +02:00
{
2023-01-12 04:05:05 +01:00
auto cb_info_opt = take_pending_request ( req_id ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
if ( ! cb_info_opt )
2025-02-05 20:28:08 +01:00
return ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
s32 error_code = CELL_OK ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
switch ( error )
{
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : RoomMissing : error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM ; break ;
case rpcn : : ErrorType : : Unauthorized : error_code = SCE_NP_MATCHING2_SERVER_ERROR_FORBIDDEN ; break ;
default : fmt : : throw_exception ( " Unexpected error in reply to SetRoomDataExternal: %d " , static_cast < u8 > ( error ) ) ;
}
cb_info_opt - > queue_callback ( req_id , 0 , error_code , 0 ) ;
2021-10-28 06:36:57 +02:00
}
u32 np_handler : : get_roomdata_internal ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , const SceNpMatching2GetRoomDataInternalRequest * req )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_GetRoomDataInternal ) ;
2021-10-28 06:36:57 +02:00
2023-03-03 10:45:29 +01:00
if ( ! get_rpcn ( ) - > get_roomdata_internal ( req_id , get_match2_context ( ctx_id ) - > communicationId , req ) )
2021-10-28 06:36:57 +02:00
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
return req_id ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_get_roomdata_internal ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2021-10-28 06:36:57 +02:00
{
2023-01-12 04:05:05 +01:00
auto cb_info_opt = take_pending_request ( req_id ) ;
if ( ! cb_info_opt )
2025-02-05 20:28:08 +01:00
return ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
s32 error_code = CELL_OK ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
switch ( error )
{
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : RoomMissing : error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM ; break ;
default : fmt : : throw_exception ( " Unexpected error in reply to GetRoomDataInternal: %d " , static_cast < u8 > ( error ) ) ;
}
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
if ( error_code ! = CELL_OK )
{
cb_info_opt - > queue_callback ( req_id , 0 , error_code , 0 ) ;
return ;
}
const auto * resp = reply . get_flatbuffer < RoomDataInternal > ( ) ;
ensure ( ! reply . is_error ( ) , " Malformed reply to GetRoomDataInternal command " ) ;
2021-10-28 06:36:57 +02:00
2024-09-20 20:24:59 +02:00
const u32 event_key = get_event_key ( ) ;
2024-05-16 04:52:15 +02:00
auto [ include_onlinename , include_avatarurl ] = get_match2_context_options ( cb_info_opt - > ctx_id ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
auto & edata = allocate_req_result ( event_key , SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetRoomDataInternal , sizeof ( SceNpMatching2GetRoomDataInternalResponse ) ) ;
2021-10-28 06:36:57 +02:00
auto * room_resp = reinterpret_cast < SceNpMatching2GetRoomDataInternalResponse * > ( edata . data ( ) ) ;
auto * room_info = edata . allocate < SceNpMatching2RoomDataInternal > ( sizeof ( SceNpMatching2RoomDataInternal ) , room_resp - > roomDataInternal ) ;
2024-05-16 04:52:15 +02:00
RoomDataInternal_to_SceNpMatching2RoomDataInternal ( edata , resp , room_info , npid , include_onlinename , include_avatarurl ) ;
2021-10-28 06:36:57 +02:00
np_memory . shrink_allocation ( edata . addr ( ) , edata . size ( ) ) ;
2021-11-03 00:53:57 +01:00
np_cache . insert_room ( room_info ) ;
2024-09-20 20:24:59 +02:00
extra_nps : : print_SceNpMatching2RoomDataInternal ( room_info ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
cb_info_opt - > queue_callback ( req_id , event_key , 0 , edata . size ( ) ) ;
2021-10-28 06:36:57 +02:00
}
u32 np_handler : : set_roomdata_internal ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , const SceNpMatching2SetRoomDataInternalRequest * req )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomDataInternal ) ;
2021-10-28 06:36:57 +02:00
2024-09-20 20:24:59 +02:00
extra_nps : : print_SceNpMatching2SetRoomDataInternalRequest ( req ) ;
2021-10-28 06:36:57 +02:00
2023-03-03 10:45:29 +01:00
if ( ! get_rpcn ( ) - > set_roomdata_internal ( req_id , get_match2_context ( ctx_id ) - > communicationId , req ) )
2021-10-28 06:36:57 +02:00
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
return req_id ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_set_roomdata_internal ( u32 req_id , rpcn : : ErrorType error )
2021-10-28 06:36:57 +02:00
{
2023-01-12 04:05:05 +01:00
auto cb_info_opt = take_pending_request ( req_id ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
if ( ! cb_info_opt )
2025-02-05 20:28:08 +01:00
return ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
s32 error_code = CELL_OK ;
switch ( error )
{
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : RoomMissing : error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM ; break ;
2025-02-19 21:40:01 +01:00
default : fmt : : throw_exception ( " Unexpected error in reply to GetRoomDataInternal: %d " , static_cast < u8 > ( error ) ) ;
2025-02-05 20:28:08 +01:00
}
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
cb_info_opt - > queue_callback ( req_id , 0 , error_code , 0 ) ;
2021-10-28 06:36:57 +02:00
}
2024-01-14 12:36:23 +01:00
u32 np_handler : : get_roommemberdata_internal ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , const SceNpMatching2GetRoomMemberDataInternalRequest * req )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_GetRoomMemberDataInternal ) ;
2024-09-20 20:24:59 +02:00
extra_nps : : print_SceNpMatching2GetRoomMemberDataInternalRequest ( req ) ;
2024-01-14 12:36:23 +01:00
if ( ! get_rpcn ( ) - > get_roommemberdata_internal ( req_id , get_match2_context ( ctx_id ) - > communicationId , req ) )
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
return req_id ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_get_roommemberdata_internal ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2024-01-14 12:36:23 +01:00
{
auto cb_info_opt = take_pending_request ( req_id ) ;
if ( ! cb_info_opt )
2025-02-05 20:28:08 +01:00
return ;
2024-01-14 12:36:23 +01:00
2025-02-05 20:28:08 +01:00
s32 error_code = CELL_OK ;
switch ( error )
2024-01-14 12:36:23 +01:00
{
2025-02-05 20:28:08 +01:00
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : RoomMissing : error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM ; break ;
case rpcn : : ErrorType : : NotFound : error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_USER ; break ;
2025-02-19 21:40:01 +01:00
default : fmt : : throw_exception ( " Unexpected error in reply to GetRoomMemberDataInternal: %d " , static_cast < u8 > ( error ) ) ;
2024-01-14 12:36:23 +01:00
}
2025-02-05 20:28:08 +01:00
if ( error_code ! = CELL_OK )
{
cb_info_opt - > queue_callback ( req_id , 0 , error_code , 0 ) ;
return ;
}
2024-01-14 12:36:23 +01:00
2024-05-14 00:12:50 +02:00
const auto * resp = reply . get_flatbuffer < RoomMemberDataInternal > ( ) ;
2025-02-05 20:28:08 +01:00
ensure ( ! reply . is_error ( ) , " Malformed reply to GetRoomMemberDataInternal command " ) ;
2024-01-14 12:36:23 +01:00
2024-09-20 20:24:59 +02:00
const u32 event_key = get_event_key ( ) ;
2024-05-16 04:52:15 +02:00
auto [ include_onlinename , include_avatarurl ] = get_match2_context_options ( cb_info_opt - > ctx_id ) ;
2024-01-14 12:36:23 +01:00
auto & edata = allocate_req_result ( event_key , SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetRoomMemberDataInternal , sizeof ( SceNpMatching2GetRoomMemberDataInternalResponse ) ) ;
auto * mdata_resp = reinterpret_cast < SceNpMatching2GetRoomMemberDataInternalResponse * > ( edata . data ( ) ) ;
auto * mdata_info = edata . allocate < SceNpMatching2RoomMemberDataInternal > ( sizeof ( SceNpMatching2RoomMemberDataInternal ) , mdata_resp - > roomMemberDataInternal ) ;
2024-05-16 04:52:15 +02:00
RoomMemberDataInternal_to_SceNpMatching2RoomMemberDataInternal ( edata , resp , nullptr , mdata_info , include_onlinename , include_avatarurl ) ;
2024-01-14 12:36:23 +01:00
np_memory . shrink_allocation ( edata . addr ( ) , edata . size ( ) ) ;
cb_info_opt - > queue_callback ( req_id , event_key , 0 , edata . size ( ) ) ;
}
2021-10-28 06:36:57 +02:00
u32 np_handler : : set_roommemberdata_internal ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , const SceNpMatching2SetRoomMemberDataInternalRequest * req )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomMemberDataInternal ) ;
2021-10-28 06:36:57 +02:00
2024-09-20 20:24:59 +02:00
extra_nps : : print_SceNpMatching2SetRoomMemberDataInternalRequest ( req ) ;
2022-05-18 17:44:21 +02:00
2023-03-03 10:45:29 +01:00
if ( ! get_rpcn ( ) - > set_roommemberdata_internal ( req_id , get_match2_context ( ctx_id ) - > communicationId , req ) )
2021-10-28 06:36:57 +02:00
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
return req_id ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_set_roommemberdata_internal ( u32 req_id , rpcn : : ErrorType error )
2021-10-28 06:36:57 +02:00
{
2023-01-12 04:05:05 +01:00
auto cb_info_opt = take_pending_request ( req_id ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
if ( ! cb_info_opt )
2025-02-05 20:28:08 +01:00
return ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
s32 error_code = CELL_OK ;
switch ( error )
{
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : RoomMissing : error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM ; break ;
case rpcn : : ErrorType : : NotFound : error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_USER ; break ;
case rpcn : : ErrorType : : Unauthorized : error_code = SCE_NP_MATCHING2_SERVER_ERROR_FORBIDDEN ; break ;
default : fmt : : throw_exception ( " Unexpected error in reply to SetRoomMemberDataInternal: %d " , static_cast < u8 > ( error ) ) ;
}
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
cb_info_opt - > queue_callback ( req_id , 0 , error_code , 0 ) ;
2021-10-28 06:36:57 +02:00
}
2024-01-14 12:36:23 +01:00
u32 np_handler : : set_userinfo ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , const SceNpMatching2SetUserInfoRequest * req )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_SetUserInfo ) ;
2024-01-14 12:36:23 +01:00
if ( ! get_rpcn ( ) - > set_userinfo ( req_id , get_match2_context ( ctx_id ) - > communicationId , req ) )
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
return req_id ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_set_userinfo ( u32 req_id , rpcn : : ErrorType error )
2024-01-14 12:36:23 +01:00
{
auto cb_info_opt = take_pending_request ( req_id ) ;
if ( ! cb_info_opt )
2025-02-05 20:28:08 +01:00
return ;
2024-01-14 12:36:23 +01:00
2025-02-05 20:28:08 +01:00
switch ( error )
2024-01-14 12:36:23 +01:00
{
2025-02-05 20:28:08 +01:00
case rpcn : : ErrorType : : NoError : break ;
default : fmt : : throw_exception ( " Unexpected error in reply to SetUserInfo: %d " , static_cast < u8 > ( error ) ) ;
2024-01-14 12:36:23 +01:00
}
cb_info_opt - > queue_callback ( req_id , 0 , 0 , 0 ) ;
}
2021-10-28 06:36:57 +02:00
u32 np_handler : : get_ping_info ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , const SceNpMatching2SignalingGetPingInfoRequest * req )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_SignalingGetPingInfo ) ;
2021-10-28 06:36:57 +02:00
2023-03-03 10:45:29 +01:00
if ( ! get_rpcn ( ) - > ping_room_owner ( req_id , get_match2_context ( ctx_id ) - > communicationId , req - > roomId ) )
2021-10-28 06:36:57 +02:00
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
return req_id ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_get_ping_info ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2021-10-28 06:36:57 +02:00
{
2023-01-12 04:05:05 +01:00
auto cb_info_opt = take_pending_request ( req_id ) ;
if ( ! cb_info_opt )
2025-02-05 20:28:08 +01:00
return ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
s32 error_code = CELL_OK ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
switch ( error )
{
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : RoomMissing : error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM ; break ;
default : fmt : : throw_exception ( " Unexpected error in reply to PingRoomOwner: %d " , static_cast < u8 > ( error ) ) ;
}
if ( error_code ! = CELL_OK )
{
cb_info_opt - > queue_callback ( req_id , 0 , error_code , 0 ) ;
return ;
}
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
const auto * resp = reply . get_flatbuffer < GetPingInfoResponse > ( ) ;
ensure ( ! reply . is_error ( ) , " Malformed reply to PingRoomOwner command " ) ;
2021-10-28 06:36:57 +02:00
2024-09-20 20:24:59 +02:00
const u32 event_key = get_event_key ( ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
auto & edata = allocate_req_result ( event_key , SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_SignalingGetPingInfo , sizeof ( SceNpMatching2SignalingGetPingInfoResponse ) ) ;
2021-10-28 06:36:57 +02:00
auto * final_ping_resp = reinterpret_cast < SceNpMatching2SignalingGetPingInfoResponse * > ( edata . data ( ) ) ;
GetPingInfoResponse_to_SceNpMatching2SignalingGetPingInfoResponse ( resp , final_ping_resp ) ;
np_memory . shrink_allocation ( edata . addr ( ) , edata . size ( ) ) ;
2023-01-12 04:05:05 +01:00
cb_info_opt - > queue_callback ( req_id , event_key , 0 , edata . size ( ) ) ;
2021-10-28 06:36:57 +02:00
}
u32 np_handler : : send_room_message ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , const SceNpMatching2SendRoomMessageRequest * req )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_SendRoomMessage ) ;
2021-10-28 06:36:57 +02:00
2023-03-03 10:45:29 +01:00
if ( ! get_rpcn ( ) - > send_room_message ( req_id , get_match2_context ( ctx_id ) - > communicationId , req ) )
2021-10-28 06:36:57 +02:00
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
return req_id ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_send_room_message ( u32 req_id , rpcn : : ErrorType error )
2021-10-28 06:36:57 +02:00
{
2023-01-12 04:05:05 +01:00
auto cb_info_opt = take_pending_request ( req_id ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
if ( ! cb_info_opt )
2025-02-05 20:28:08 +01:00
return ;
2023-01-12 04:05:05 +01:00
2025-02-05 20:28:08 +01:00
s32 error_code = CELL_OK ;
2021-10-28 06:36:57 +02:00
2025-02-05 20:28:08 +01:00
switch ( error )
{
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : RoomMissing : error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM ; break ;
case rpcn : : ErrorType : : Unauthorized : error_code = SCE_NP_MATCHING2_SERVER_ERROR_FORBIDDEN ; break ;
default : fmt : : throw_exception ( " Unexpected error in reply to SendRoomMessage: %d " , static_cast < u8 > ( error ) ) ;
}
cb_info_opt - > queue_callback ( req_id , 0 , error_code , 0 ) ;
2021-10-28 06:36:57 +02:00
}
void np_handler : : req_sign_infos ( const std : : string & npid , u32 conn_id )
{
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : MISC ) ;
2021-10-28 06:36:57 +02:00
{
std : : lock_guard lock ( mutex_pending_sign_infos_requests ) ;
pending_sign_infos_requests [ req_id ] = conn_id ;
}
2023-03-03 10:45:29 +01:00
if ( ! get_rpcn ( ) - > req_sign_infos ( req_id , npid ) )
2021-10-28 06:36:57 +02:00
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_req_sign_infos ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2021-10-28 06:36:57 +02:00
{
u32 conn_id ;
{
std : : lock_guard lock ( mutex_pending_sign_infos_requests ) ;
2022-09-19 14:57:51 +02:00
conn_id = : : at32 ( pending_sign_infos_requests , req_id ) ;
2021-10-28 06:36:57 +02:00
pending_sign_infos_requests . erase ( req_id ) ;
}
2025-02-05 20:28:08 +01:00
switch ( error )
2023-03-08 12:24:15 +01:00
{
2025-02-05 20:28:08 +01:00
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : NotFound :
{
rpcn_log . error ( " Signaling information was requested for a user that doesn't exist or is not online " ) ;
return ;
}
default : fmt : : throw_exception ( " Unexpected error in reply to RequestSignalingInfos: %d " , static_cast < u8 > ( error ) ) ;
2023-03-08 12:24:15 +01:00
}
2025-02-05 20:28:08 +01:00
const auto * resp = reply . get_flatbuffer < SignalingAddr > ( ) ;
ensure ( ! reply . is_error ( ) & & resp - > ip ( ) , " Malformed reply to RequestSignalingInfos command " ) ;
u32 addr = register_ip ( resp - > ip ( ) ) ;
2021-10-28 06:36:57 +02:00
auto & sigh = g_fxo - > get < named_thread < signaling_handler > > ( ) ;
2025-02-05 20:28:08 +01:00
sigh . start_sig ( conn_id , addr , resp - > port ( ) ) ;
2021-10-28 06:36:57 +02:00
}
2024-09-20 20:24:59 +02:00
u32 np_handler : : get_lobby_info_list ( SceNpMatching2ContextId ctx_id , vm : : cptr < SceNpMatching2RequestOptParam > optParam , const SceNpMatching2GetLobbyInfoListRequest * req )
{
// Hack
// Note that this is fake and needs to be properly implemented both on server and on rpcs3
extra_nps : : print_SceNpMatching2GetLobbyInfoListRequest ( req ) ;
const u32 req_id = generate_callback_info ( ctx_id , optParam , SCE_NP_MATCHING2_REQUEST_EVENT_GetLobbyInfoList ) ;
auto cb_info_opt = take_pending_request ( req_id ) ;
if ( ! cb_info_opt )
return true ;
const u32 event_key = get_event_key ( ) ;
auto & edata = allocate_req_result ( event_key , SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetLobbyInfoList , sizeof ( SceNpMatching2GetLobbyInfoListResponse ) ) ;
auto * resp = reinterpret_cast < SceNpMatching2GetLobbyInfoListResponse * > ( edata . data ( ) ) ;
resp - > range . size = 1 ;
resp - > range . startIndex = 1 ;
resp - > range . total = 1 ;
auto lobby_data = edata . allocate < SceNpMatching2LobbyDataExternal > ( sizeof ( SceNpMatching2LobbyDataExternal ) , resp - > lobbyDataExternal ) ;
lobby_data - > serverId = 1 ;
lobby_data - > worldId = req - > worldId ;
lobby_data - > lobbyId = 1 ;
lobby_data - > maxSlot = 64 ;
lobby_data - > curMemberNum = 0 ;
lobby_data - > flagAttr = SCE_NP_MATCHING2_LOBBY_FLAG_ATTR_PERMANENT ;
np_memory . shrink_allocation ( edata . addr ( ) , edata . size ( ) ) ;
cb_info_opt - > queue_callback ( req_id , event_key , 0 , edata . size ( ) ) ;
return req_id ;
}
2022-02-03 10:56:36 +01:00
void np_handler : : req_ticket ( [[maybe_unused]] u32 version, [[maybe_unused]] const SceNpId* npid, const char* service_id, const u8* cookie, u32 cookie_size, [[maybe_unused]] const char* entitlement_id, [[maybe_unused]] u32 consumed_count )
2021-10-28 06:36:57 +02:00
{
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : MISC ) ;
2021-10-28 06:36:57 +02:00
std : : string service_id_str ( service_id ) ;
2022-02-03 10:56:36 +01:00
std : : vector < u8 > cookie_vec ;
if ( cookie & & cookie_size )
{
cookie_vec . assign ( cookie , cookie + cookie_size ) ;
}
2023-03-03 10:45:29 +01:00
if ( ! get_rpcn ( ) - > req_ticket ( req_id , service_id_str , cookie_vec ) )
2021-10-28 06:36:57 +02:00
{
rpcn_log . error ( " Disconnecting from RPCN! " ) ;
is_psn_active = false ;
}
return ;
}
2022-05-10 17:25:45 +02:00
const ticket & np_handler : : get_ticket ( ) const
{
return current_ticket ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_req_ticket ( u32 /* req_id */ , rpcn : : ErrorType error , vec_stream & reply )
2021-10-28 06:36:57 +02:00
{
2025-02-05 20:28:08 +01:00
ensure ( error = = rpcn : : ErrorType : : NoError , " Unexpected error in reply to RequestTicket " ) ;
2021-10-28 06:36:57 +02:00
auto ticket_raw = reply . get_rawdata ( ) ;
2025-02-05 20:28:08 +01:00
ensure ( ! reply . is_error ( ) , " Malformed reply to RequestTicket command " ) ;
2021-10-28 06:36:57 +02:00
2023-01-12 04:05:05 +01:00
current_ticket = ticket ( std : : move ( ticket_raw ) ) ;
2021-10-28 06:36:57 +02:00
auto ticket_size = static_cast < s32 > ( current_ticket . size ( ) ) ;
if ( manager_cb )
{
sysutil_register_cb ( [ manager_cb = this - > manager_cb , ticket_size , manager_cb_arg = this - > manager_cb_arg ] ( ppu_thread & cb_ppu ) - > s32
{
manager_cb ( cb_ppu , SCE_NP_MANAGER_EVENT_GOT_TICKET , ticket_size , manager_cb_arg ) ;
return 0 ;
} ) ;
}
}
2024-12-22 19:59:48 +01:00
void np_handler : : transaction_async_handler ( std : : unique_lock < shared_mutex > lock , const shared_ptr < generic_async_transaction_context > & trans_ctx , u32 req_id , bool async )
2022-05-18 17:44:21 +02:00
{
auto worker_function = [ trans_ctx = trans_ctx , req_id , this ] ( std : : unique_lock < shared_mutex > lock )
{
2024-01-27 20:33:54 +01:00
thread_base : : set_name ( " NP Trans Worker " ) ;
2022-05-18 17:44:21 +02:00
auto res = trans_ctx - > wake_cond . wait_for ( lock , std : : chrono : : microseconds ( trans_ctx - > timeout ) ) ;
{
2023-04-01 21:52:07 +02:00
std : : lock_guard lock_threads ( this - > mutex_async_transactions ) ;
this - > async_transactions . erase ( req_id ) ;
2022-05-18 17:44:21 +02:00
}
if ( res = = std : : cv_status : : timeout )
{
trans_ctx - > result = SCE_NP_COMMUNITY_ERROR_TIMEOUT ;
return ;
}
// Only 2 cases should be timeout or caller setting result
2024-05-14 00:12:50 +02:00
ensure ( trans_ctx - > result , " transaction_async_handler: trans_ctx->result is not set " ) ;
2022-05-18 17:44:21 +02:00
trans_ctx - > completion_cond . notify_one ( ) ;
} ;
{
2023-04-01 21:52:07 +02:00
std : : lock_guard lock_score ( mutex_async_transactions ) ;
2024-02-26 21:43:15 +01:00
ensure ( async_transactions . insert ( { req_id , trans_ctx } ) . second , " transaction_async_handler: async_transactions insert failed " ) ;
2022-05-18 17:44:21 +02:00
}
if ( async )
{
trans_ctx - > thread = std : : thread ( worker_function , std : : move ( lock ) ) ;
return ;
}
2022-10-23 15:35:19 +02:00
auto & cpu_thread = * get_current_cpu_thread ( ) ;
lv2_obj : : sleep ( cpu_thread ) ;
worker_function ( std : : move ( lock ) ) ;
cpu_thread . check_state ( ) ;
2022-05-18 17:44:21 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : get_board_infos ( shared_ptr < score_transaction_ctx > & trans_ctx , SceNpScoreBoardId boardId , vm : : ptr < SceNpScoreBoardInfo > boardInfo , bool async )
2022-05-18 17:44:21 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : SCORE ) ;
2022-10-01 14:40:16 +02:00
trans_ctx - > tdata = tdata_get_board_infos { . boardInfo = boardInfo } ;
2023-03-03 10:45:29 +01:00
get_rpcn ( ) - > get_board_infos ( req_id , trans_ctx - > communicationId , boardId ) ;
2022-05-18 17:44:21 +02:00
2023-04-01 21:52:07 +02:00
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
2022-05-18 17:44:21 +02:00
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_get_board_infos ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2022-05-18 17:44:21 +02:00
{
2025-02-05 20:28:08 +01:00
std : : lock_guard lock_trans ( mutex_async_transactions ) ;
if ( ! async_transactions . count ( req_id ) )
{
rpcn_log . error ( " Couldn't find transaction(%d) in trans_id! " , req_id ) ;
return ;
}
2022-05-18 17:44:21 +02:00
2025-02-05 20:28:08 +01:00
auto score_trans = idm : : get_unlocked < score_transaction_ctx > ( : : at32 ( async_transactions , req_id ) - > idm_id ) ;
ensure ( score_trans ) ;
2022-10-01 14:40:16 +02:00
2025-02-05 20:28:08 +01:00
s32 error_code = CELL_OK ;
switch ( error )
{
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : NotFound : error_code = SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_BOARD_MASTER_NOT_FOUND ; break ;
default : fmt : : throw_exception ( " Unexpected error in reply to GetBoardInfos: %d " , static_cast < u8 > ( error ) ) ;
}
if ( error_code ! = CELL_OK )
{
std : : lock_guard lock ( score_trans - > mutex ) ;
score_trans - > result = error_code ;
score_trans - > wake_cond . notify_one ( ) ;
return ;
}
const auto * resp = reply . get_flatbuffer < BoardInfo > ( ) ;
ensure ( ! reply . is_error ( ) , " Malformed reply to GetBoardInfos command " ) ;
2022-05-18 17:44:21 +02:00
2023-12-29 18:33:29 +01:00
const SceNpScoreBoardInfo board_info {
. rankLimit = resp - > rankLimit ( ) ,
. updateMode = resp - > updateMode ( ) ,
. sortMode = resp - > sortMode ( ) ,
. uploadNumLimit = resp - > uploadNumLimit ( ) ,
. uploadSizeLimit = resp - > uploadSizeLimit ( )
} ;
2022-05-18 17:44:21 +02:00
2023-04-01 21:52:07 +02:00
std : : lock_guard lock ( score_trans - > mutex ) ;
2022-10-01 14:40:16 +02:00
2023-04-01 21:52:07 +02:00
const auto * tdata = std : : get_if < tdata_get_board_infos > ( & score_trans - > tdata ) ;
2022-10-01 14:40:16 +02:00
ensure ( tdata ) ;
memcpy ( reinterpret_cast < u8 * > ( tdata - > boardInfo . get_ptr ( ) ) , & board_info , sizeof ( SceNpScoreBoardInfo ) ) ;
2023-04-01 21:52:07 +02:00
score_trans - > result = CELL_OK ;
score_trans - > wake_cond . notify_one ( ) ;
2022-05-18 17:44:21 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : record_score ( shared_ptr < score_transaction_ctx > & trans_ctx , SceNpScoreBoardId boardId , SceNpScoreValue score , vm : : cptr < SceNpScoreComment > scoreComment , const u8 * data , u32 data_size , vm : : ptr < SceNpScoreRankNumber > tmpRank , bool async )
2022-05-18 17:44:21 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : SCORE ) ;
2023-01-12 04:05:05 +01:00
std : : optional < std : : string > str_comment = scoreComment ? std : : optional ( std : : string ( reinterpret_cast < const char * > ( scoreComment - > data ) ) ) : std : : nullopt ;
2022-10-01 14:40:16 +02:00
std : : optional < std : : vector < u8 > > vec_data ;
if ( data )
2022-05-18 17:44:21 +02:00
{
2022-10-01 14:40:16 +02:00
vec_data = std : : vector < u8 > ( data , data + data_size ) ;
2022-05-18 17:44:21 +02:00
}
2022-10-01 14:40:16 +02:00
trans_ctx - > tdata = tdata_record_score { . tmpRank = tmpRank } ;
2022-05-18 17:44:21 +02:00
2023-03-03 10:45:29 +01:00
get_rpcn ( ) - > record_score ( req_id , trans_ctx - > communicationId , boardId , trans_ctx - > pcId , score , str_comment , vec_data ) ;
2022-10-01 14:40:16 +02:00
2023-04-01 21:52:07 +02:00
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
2022-05-18 17:44:21 +02:00
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_record_score ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2022-05-18 17:44:21 +02:00
{
2023-04-01 21:52:07 +02:00
std : : lock_guard lock_trans ( mutex_async_transactions ) ;
if ( ! async_transactions . count ( req_id ) )
2022-05-18 17:44:21 +02:00
{
rpcn_log . error ( " Couldn't find transaction(%d) in trans_id! " , req_id ) ;
2025-02-05 20:28:08 +01:00
return ;
2022-05-18 17:44:21 +02:00
}
2024-12-22 19:59:48 +01:00
auto score_trans = idm : : get_unlocked < score_transaction_ctx > ( : : at32 ( async_transactions , req_id ) - > idm_id ) ;
2023-04-01 21:52:07 +02:00
ensure ( score_trans ) ;
std : : lock_guard lock ( score_trans - > mutex ) ;
2022-05-18 17:44:21 +02:00
2025-02-05 20:28:08 +01:00
switch ( error )
2022-05-18 17:44:21 +02:00
{
2025-02-05 20:28:08 +01:00
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : ScoreNotBest :
{
score_trans - > result = SCE_NP_COMMUNITY_SERVER_ERROR_NOT_BEST_SCORE ;
score_trans - > wake_cond . notify_one ( ) ;
return ;
}
default : fmt : : throw_exception ( " Unexpected error in reply_record_score: %d " , static_cast < u8 > ( error ) ) ;
2022-05-18 17:44:21 +02:00
}
auto tmp_rank = reply . get < u32 > ( ) ;
2025-02-05 20:28:08 +01:00
ensure ( ! reply . is_error ( ) , " Error parsing response in reply_record_score " ) ;
2022-05-18 17:44:21 +02:00
2023-04-01 21:52:07 +02:00
const auto * tdata = std : : get_if < tdata_record_score > ( & score_trans - > tdata ) ;
2022-10-01 14:40:16 +02:00
ensure ( tdata ) ;
if ( tdata - > tmpRank )
2022-05-18 17:44:21 +02:00
{
2022-10-01 14:40:16 +02:00
* tdata - > tmpRank = tmp_rank ;
2022-05-18 17:44:21 +02:00
}
2023-04-01 21:52:07 +02:00
score_trans - > result = CELL_OK ;
score_trans - > wake_cond . notify_one ( ) ;
2022-05-18 17:44:21 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : record_score_data ( shared_ptr < score_transaction_ctx > & trans_ctx , SceNpScoreBoardId boardId , SceNpScoreValue score , u32 totalSize , u32 sendSize , const u8 * score_data , bool async )
2022-05-18 17:44:21 +02:00
{
2022-10-01 14:40:16 +02:00
std : : unique_lock lock ( trans_ctx - > mutex ) ;
auto * tdata = std : : get_if < tdata_record_score_data > ( & trans_ctx - > tdata ) ;
if ( ! tdata )
{
trans_ctx - > tdata = tdata_record_score_data { . game_data_size = totalSize } ;
2023-01-12 04:05:05 +01:00
tdata = std : : get_if < tdata_record_score_data > ( & trans_ctx - > tdata ) ;
2022-10-01 14:40:16 +02:00
tdata - > game_data . reserve ( totalSize ) ;
}
std : : copy ( score_data , score_data + sendSize , std : : back_inserter ( tdata - > game_data ) ) ;
if ( tdata - > game_data . size ( ) = = tdata - > game_data_size )
{
trans_ctx - > result = std : : nullopt ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : SCORE ) ;
2023-03-03 10:45:29 +01:00
get_rpcn ( ) - > record_score_data ( req_id , trans_ctx - > communicationId , trans_ctx - > pcId , boardId , score , tdata - > game_data ) ;
2023-04-01 21:52:07 +02:00
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
2022-10-01 14:40:16 +02:00
}
else
{
trans_ctx - > result = CELL_OK ;
}
2022-05-18 17:44:21 +02:00
}
2022-10-01 14:40:16 +02:00
2025-02-05 20:28:08 +01:00
void np_handler : : reply_record_score_data ( u32 req_id , rpcn : : ErrorType error )
2022-05-18 17:44:21 +02:00
{
2023-04-01 21:52:07 +02:00
std : : lock_guard lock_trans ( mutex_async_transactions ) ;
if ( ! async_transactions . count ( req_id ) )
2022-10-01 14:40:16 +02:00
{
rpcn_log . error ( " Couldn't find transaction(%d) in trans_id! " , req_id ) ;
2025-02-05 20:28:08 +01:00
return ;
2022-10-01 14:40:16 +02:00
}
2023-04-01 21:52:07 +02:00
auto trans = : : at32 ( async_transactions , req_id ) ;
2022-10-01 14:40:16 +02:00
std : : lock_guard lock ( trans - > mutex ) ;
2025-02-05 20:28:08 +01:00
switch ( error )
2022-10-01 14:40:16 +02:00
{
2025-02-05 20:28:08 +01:00
case rpcn : : ErrorType : : NoError : trans - > set_result_and_wake ( CELL_OK ) ; break ;
case rpcn : : ErrorType : : NotFound : trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_STORE_NOT_FOUND ) ; break ;
case rpcn : : ErrorType : : ScoreInvalid : trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_INVALID_SCORE ) ; break ;
case rpcn : : ErrorType : : ScoreHasData : trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_GAME_DATA_ALREADY_EXISTS ) ; break ;
2025-02-19 21:40:01 +01:00
default : fmt : : throw_exception ( " Unexpected error in reply to RecordScoreData: %d " , static_cast < u8 > ( error ) ) ;
2022-10-01 14:40:16 +02:00
}
2022-05-18 17:44:21 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : get_score_data ( shared_ptr < score_transaction_ctx > & trans_ctx , SceNpScoreBoardId boardId , const SceNpId & npId , vm : : ptr < u32 > totalSize , u32 recvSize , vm : : ptr < void > score_data , bool async )
2022-10-01 14:40:16 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
auto * tdata = std : : get_if < tdata_get_score_data > ( & trans_ctx - > tdata ) ;
if ( ! tdata )
{
trans_ctx - > tdata = tdata_get_score_data { . totalSize = totalSize , . recvSize = recvSize , . score_data = score_data } ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : SCORE ) ;
2023-03-03 10:45:29 +01:00
get_rpcn ( ) - > get_score_data ( req_id , trans_ctx - > communicationId , trans_ctx - > pcId , boardId , npId ) ;
2023-04-01 21:52:07 +02:00
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
2022-10-01 14:40:16 +02:00
return ;
}
2022-10-23 15:35:19 +02:00
// Check if the transaction has actually completed, otherwise adjust tdata parameters
if ( ! trans_ctx - > result )
{
tdata - > totalSize = totalSize ;
tdata - > recvSize = recvSize ;
tdata - > score_data = score_data ;
return ;
}
2022-10-01 14:40:16 +02:00
2022-10-23 15:35:19 +02:00
// If here the data has already been acquired and the client is just asking for part of it
2022-10-01 14:40:16 +02:00
usz to_copy = std : : min ( tdata - > game_data . size ( ) , static_cast < usz > ( recvSize ) ) ;
std : : memcpy ( score_data . get_ptr ( ) , tdata - > game_data . data ( ) , to_copy ) ;
tdata - > game_data . erase ( tdata - > game_data . begin ( ) , tdata - > game_data . begin ( ) + to_copy ) ;
2023-01-12 04:05:05 +01:00
* totalSize = tdata - > game_data_size ;
2022-10-01 14:40:16 +02:00
trans_ctx - > result = not_an_error ( to_copy ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_get_score_data ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2022-10-01 14:40:16 +02:00
{
2023-04-01 21:52:07 +02:00
std : : lock_guard lock_trans ( mutex_async_transactions ) ;
if ( ! async_transactions . count ( req_id ) )
2022-10-01 14:40:16 +02:00
{
rpcn_log . error ( " Couldn't find transaction(%d) in trans_id! " , req_id ) ;
2025-02-05 20:28:08 +01:00
return ;
2022-10-01 14:40:16 +02:00
}
2024-12-22 19:59:48 +01:00
auto score_trans = idm : : get_unlocked < score_transaction_ctx > ( : : at32 ( async_transactions , req_id ) - > idm_id ) ;
2023-04-01 21:52:07 +02:00
ensure ( score_trans ) ;
std : : lock_guard lock ( score_trans - > mutex ) ;
2022-10-01 14:40:16 +02:00
2025-02-05 20:28:08 +01:00
switch ( error )
2022-10-01 14:40:16 +02:00
{
2025-02-05 20:28:08 +01:00
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : NotFound : score_trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_GAME_DATA_MASTER_NOT_FOUND ) ; return ;
2025-02-19 21:40:01 +01:00
default : fmt : : throw_exception ( " Unexpected error in reply to GetScoreData: %d " , static_cast < u8 > ( error ) ) ;
2022-10-01 14:40:16 +02:00
}
2023-04-01 21:52:07 +02:00
auto * tdata = std : : get_if < tdata_get_score_data > ( & score_trans - > tdata ) ;
2022-10-01 14:40:16 +02:00
ensure ( tdata ) ;
tdata - > game_data = reply . get_rawdata ( ) ;
2025-02-05 20:28:08 +01:00
ensure ( ! reply . is_error ( ) , " Error parsing response in reply_get_score_data " ) ;
2022-10-01 14:40:16 +02:00
2023-12-29 18:33:29 +01:00
tdata - > game_data_size = : : size32 ( tdata - > game_data ) ;
2022-10-01 14:40:16 +02:00
usz to_copy = std : : min ( tdata - > game_data . size ( ) , static_cast < usz > ( tdata - > recvSize ) ) ;
std : : memcpy ( tdata - > score_data . get_ptr ( ) , tdata - > game_data . data ( ) , to_copy ) ;
tdata - > game_data . erase ( tdata - > game_data . begin ( ) , tdata - > game_data . begin ( ) + to_copy ) ;
* tdata - > totalSize = tdata - > game_data_size ;
2025-02-05 20:28:08 +01:00
score_trans - > set_result_and_wake ( not_an_error ( to_copy ) ) ;
2022-10-01 14:40:16 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : get_score_range ( shared_ptr < score_transaction_ctx > & trans_ctx , SceNpScoreBoardId boardId , SceNpScoreRankNumber startSerialRank , vm : : ptr < SceNpScoreRankData > rankArray , u32 rankArraySize , vm : : ptr < SceNpScoreComment > commentArray , [[maybe_unused]] u32 commentArraySize , vm : : ptr < void > infoArray , u32 infoArraySize , u32 arrayNum , vm : : ptr < CellRtcTick > lastSortDate , vm : : ptr < SceNpScoreRankNumber > totalRecord , bool async , bool deprecated )
2022-05-18 17:44:21 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : SCORE ) ;
2022-10-01 14:40:16 +02:00
trans_ctx - > tdata = tdata_get_score_generic {
2023-01-12 04:05:05 +01:00
. rankArray = rankArray ,
2022-10-01 14:40:16 +02:00
. rankArraySize = rankArraySize ,
2023-01-12 04:05:05 +01:00
. commentArray = commentArray ,
. infoArray = infoArray ,
2022-10-01 14:40:16 +02:00
. infoArraySize = infoArraySize ,
2023-01-12 04:05:05 +01:00
. arrayNum = arrayNum ,
. lastSortDate = lastSortDate ,
. totalRecord = totalRecord ,
2024-07-15 08:13:58 +02:00
. player_rank_data = false ,
. deprecated = deprecated ,
2022-10-01 14:40:16 +02:00
} ;
2022-05-18 17:44:21 +02:00
bool with_comments = ! ! commentArray ;
bool with_gameinfo = ! ! infoArray ;
2023-03-03 10:45:29 +01:00
get_rpcn ( ) - > get_score_range ( req_id , trans_ctx - > communicationId , boardId , startSerialRank , arrayNum , with_comments , with_gameinfo ) ;
2022-05-18 17:44:21 +02:00
2023-04-01 21:52:07 +02:00
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
2022-05-18 17:44:21 +02:00
}
2024-07-15 08:13:58 +02:00
template < typename T >
void set_rankdata_values ( T & cur_rank , const ScoreRankData * fb_rankdata )
{
string_to_npid ( fb_rankdata - > npId ( ) - > string_view ( ) , cur_rank . npId ) ;
string_to_online_name ( fb_rankdata - > onlineName ( ) - > string_view ( ) , cur_rank . onlineName ) ;
static_assert ( std : : is_same_v < T , SceNpScoreRankData > | | std : : is_same_v < T , SceNpScoreRankData_deprecated > ) ;
if constexpr ( std : : is_same_v < T , SceNpScoreRankData > )
cur_rank . pcId = fb_rankdata - > pcId ( ) ;
cur_rank . serialRank = fb_rankdata - > rank ( ) ;
cur_rank . rank = fb_rankdata - > rank ( ) ;
cur_rank . highestRank = fb_rankdata - > rank ( ) ;
cur_rank . scoreValue = fb_rankdata - > score ( ) ;
cur_rank . hasGameData = fb_rankdata - > hasGameData ( ) ;
cur_rank . recordDate . tick = fb_rankdata - > recordDate ( ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : handle_GetScoreResponse ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply , bool simple_result )
2022-05-18 17:44:21 +02:00
{
2023-04-01 21:52:07 +02:00
std : : lock_guard lock_trans ( mutex_async_transactions ) ;
if ( ! async_transactions . count ( req_id ) )
2022-05-18 17:44:21 +02:00
{
rpcn_log . error ( " Couldn't find transaction(%d) in trans_id! " , req_id ) ;
2025-02-05 20:28:08 +01:00
return ;
2022-05-18 17:44:21 +02:00
}
2024-12-22 19:59:48 +01:00
auto score_trans = idm : : get_unlocked < score_transaction_ctx > ( : : at32 ( async_transactions , req_id ) - > idm_id ) ;
2023-04-01 21:52:07 +02:00
ensure ( score_trans ) ;
std : : lock_guard lock ( score_trans - > mutex ) ;
2022-05-18 17:44:21 +02:00
2025-02-05 20:28:08 +01:00
switch ( error )
2022-05-18 17:44:21 +02:00
{
2025-02-05 20:28:08 +01:00
case rpcn : : ErrorType : : NoError : break ;
default : fmt : : throw_exception ( " Unexpected error in GetScoreResponse: %d " , static_cast < u8 > ( error ) ) ;
2022-05-18 17:44:21 +02:00
}
2024-05-14 00:12:50 +02:00
const auto * resp = reply . get_flatbuffer < GetScoreResponse > ( ) ;
2025-02-05 20:28:08 +01:00
ensure ( ! reply . is_error ( ) , " Error parsing response in handle_GetScoreResponse " ) ;
2022-05-18 17:44:21 +02:00
2023-04-01 21:52:07 +02:00
const auto * tdata = std : : get_if < tdata_get_score_generic > ( & score_trans - > tdata ) ;
2022-10-01 14:40:16 +02:00
ensure ( tdata ) ;
ensure ( resp - > rankArray ( ) & & resp - > rankArray ( ) - > size ( ) < = tdata - > arrayNum ) ;
2022-05-18 17:44:21 +02:00
2022-10-01 14:40:16 +02:00
memset ( tdata - > rankArray . get_ptr ( ) , 0 , tdata - > rankArraySize ) ;
2022-05-18 17:44:21 +02:00
auto * fb_rankarray = resp - > rankArray ( ) ;
2022-10-01 14:40:16 +02:00
vm : : ptr < SceNpScorePlayerRankData > rankPlayerArray = vm : : static_ptr_cast < SceNpScorePlayerRankData > ( tdata - > rankArray ) ;
2024-07-15 08:13:58 +02:00
vm : : ptr < SceNpScorePlayerRankData_deprecated > rankPlayerArray_deprecated = vm : : static_ptr_cast < SceNpScorePlayerRankData_deprecated > ( tdata - > rankArray ) ;
vm : : ptr < SceNpScoreRankData > rankArray = vm : : static_ptr_cast < SceNpScoreRankData > ( tdata - > rankArray ) ;
vm : : ptr < SceNpScoreRankData_deprecated > rankArray_deprecated = vm : : static_ptr_cast < SceNpScoreRankData_deprecated > ( tdata - > rankArray ) ;
2022-10-01 14:40:16 +02:00
2024-11-05 18:08:28 +01:00
u32 num_scores_registered = 0 ;
2022-05-18 17:44:21 +02:00
for ( flatbuffers : : uoffset_t i = 0 ; i < fb_rankarray - > size ( ) ; i + + )
{
const auto * fb_rankdata = fb_rankarray - > Get ( i ) ;
ensure ( fb_rankdata - > npId ( ) & & fb_rankdata - > onlineName ( ) ) ;
2022-10-01 14:40:16 +02:00
if ( fb_rankdata - > recordDate ( ) = = 0 )
continue ;
2024-11-05 18:08:28 +01:00
num_scores_registered + + ;
2024-07-15 08:13:58 +02:00
if ( tdata - > player_rank_data )
2022-10-01 14:40:16 +02:00
{
2024-07-15 08:13:58 +02:00
if ( tdata - > deprecated )
{
rankPlayerArray_deprecated [ i ] . hasData = 1 ;
set_rankdata_values ( rankPlayerArray_deprecated [ i ] . rankData , fb_rankdata ) ;
}
else
{
rankPlayerArray [ i ] . hasData = 1 ;
set_rankdata_values ( rankPlayerArray [ i ] . rankData , fb_rankdata ) ;
}
2022-10-01 14:40:16 +02:00
}
else
{
2024-07-15 08:13:58 +02:00
if ( tdata - > deprecated )
{
set_rankdata_values ( rankArray_deprecated [ i ] , fb_rankdata ) ;
}
else
{
set_rankdata_values ( rankArray [ i ] , fb_rankdata ) ;
}
2022-10-01 14:40:16 +02:00
}
2022-05-18 17:44:21 +02:00
}
2022-10-01 14:40:16 +02:00
if ( tdata - > commentArray )
2022-05-18 17:44:21 +02:00
{
2022-10-01 14:40:16 +02:00
ensure ( resp - > commentArray ( ) & & resp - > commentArray ( ) - > size ( ) < = tdata - > arrayNum ) ;
memset ( tdata - > commentArray . get_ptr ( ) , 0 , sizeof ( SceNpScoreComment ) * tdata - > arrayNum ) ;
2022-05-18 17:44:21 +02:00
auto * fb_commentarray = resp - > commentArray ( ) ;
for ( flatbuffers : : uoffset_t i = 0 ; i < fb_commentarray - > size ( ) ; i + + )
{
const auto * fb_comment = fb_commentarray - > Get ( i ) ;
2022-10-01 14:40:16 +02:00
strcpy_trunc ( tdata - > commentArray [ i ] . data , fb_comment - > string_view ( ) ) ;
2022-05-18 17:44:21 +02:00
}
}
2022-10-01 14:40:16 +02:00
if ( tdata - > infoArray )
2022-05-18 17:44:21 +02:00
{
2022-10-01 14:40:16 +02:00
ensure ( resp - > infoArray ( ) & & resp - > infoArray ( ) - > size ( ) < = tdata - > arrayNum ) ;
2022-05-18 17:44:21 +02:00
auto * fb_infoarray = resp - > infoArray ( ) ;
2022-10-01 14:40:16 +02:00
if ( ( tdata - > arrayNum * sizeof ( SceNpScoreGameInfo ) ) = = tdata - > infoArraySize )
2022-05-18 17:44:21 +02:00
{
2022-10-01 14:40:16 +02:00
vm : : ptr < SceNpScoreGameInfo > ptr_gameinfo = vm : : static_ptr_cast < SceNpScoreGameInfo > ( tdata - > infoArray ) ;
memset ( ptr_gameinfo . get_ptr ( ) , 0 , sizeof ( SceNpScoreGameInfo ) * tdata - > arrayNum ) ;
2022-05-18 17:44:21 +02:00
for ( flatbuffers : : uoffset_t i = 0 ; i < fb_infoarray - > size ( ) ; i + + )
{
const auto * fb_info = fb_infoarray - > Get ( i ) ;
ensure ( fb_info - > data ( ) - > size ( ) < = SCE_NP_SCORE_GAMEINFO_SIZE ) ;
memcpy ( ptr_gameinfo [ i ] . nativeData , fb_info - > data ( ) - > data ( ) , fb_info - > data ( ) - > size ( ) ) ;
}
}
else
{
2022-10-01 14:40:16 +02:00
vm : : ptr < SceNpScoreVariableSizeGameInfo > ptr_vargameinfo = vm : : static_ptr_cast < SceNpScoreVariableSizeGameInfo > ( tdata - > infoArray ) ;
memset ( ptr_vargameinfo . get_ptr ( ) , 0 , sizeof ( SceNpScoreVariableSizeGameInfo ) * tdata - > arrayNum ) ;
2022-05-18 17:44:21 +02:00
for ( flatbuffers : : uoffset_t i = 0 ; i < fb_infoarray - > size ( ) ; i + + )
{
const auto * fb_info = fb_infoarray - > Get ( i ) ;
ensure ( fb_info - > data ( ) - > size ( ) < = SCE_NP_SCORE_VARIABLE_SIZE_GAMEINFO_MAXSIZE ) ;
ptr_vargameinfo [ i ] . infoSize = fb_info - > data ( ) - > size ( ) ;
memcpy ( ptr_vargameinfo [ i ] . data , fb_info - > data ( ) , fb_info - > data ( ) - > size ( ) ) ;
}
}
}
2022-10-01 14:40:16 +02:00
tdata - > lastSortDate - > tick = resp - > lastSortDate ( ) ;
2023-01-12 04:05:05 +01:00
* tdata - > totalRecord = resp - > totalRecord ( ) ;
2022-05-18 17:44:21 +02:00
2024-11-05 18:08:28 +01:00
if ( num_scores_registered )
2024-03-12 01:17:11 +01:00
score_trans - > result = simple_result ? CELL_OK : not_an_error ( fb_rankarray - > size ( ) ) ;
2022-09-28 12:07:33 +02:00
else
2023-04-01 21:52:07 +02:00
score_trans - > result = SCE_NP_COMMUNITY_SERVER_ERROR_GAME_RANKING_NOT_FOUND ;
2022-09-28 12:07:33 +02:00
2023-04-01 21:52:07 +02:00
score_trans - > wake_cond . notify_one ( ) ;
2022-05-18 17:44:21 +02:00
}
2023-04-01 21:52:07 +02:00
2025-02-05 20:28:08 +01:00
void np_handler : : reply_get_score_range ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2022-05-18 17:44:21 +02:00
{
2025-02-05 20:28:08 +01:00
handle_GetScoreResponse ( req_id , error , reply ) ;
2022-05-18 17:44:21 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : get_score_friend ( shared_ptr < score_transaction_ctx > & trans_ctx , SceNpScoreBoardId boardId , bool include_self , vm : : ptr < SceNpScoreRankData > rankArray , u32 rankArraySize , vm : : ptr < SceNpScoreComment > commentArray , [[maybe_unused]] u32 commentArraySize , vm : : ptr < void > infoArray , u32 infoArraySize , u32 arrayNum , vm : : ptr < CellRtcTick > lastSortDate , vm : : ptr < SceNpScoreRankNumber > totalRecord , bool async , bool deprecated )
2022-05-18 17:44:21 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : SCORE ) ;
2022-10-01 14:40:16 +02:00
trans_ctx - > tdata = tdata_get_score_generic {
2023-01-12 04:05:05 +01:00
. rankArray = rankArray ,
2022-10-01 14:40:16 +02:00
. rankArraySize = rankArraySize ,
2023-01-12 04:05:05 +01:00
. commentArray = commentArray ,
. infoArray = infoArray ,
2022-10-01 14:40:16 +02:00
. infoArraySize = infoArraySize ,
2023-01-12 04:05:05 +01:00
. arrayNum = arrayNum ,
. lastSortDate = lastSortDate ,
. totalRecord = totalRecord ,
2024-07-15 08:13:58 +02:00
. player_rank_data = false ,
. deprecated = deprecated ,
2022-10-01 14:40:16 +02:00
} ;
2022-05-18 17:44:21 +02:00
bool with_comments = ! ! commentArray ;
bool with_gameinfo = ! ! infoArray ;
2023-03-03 10:45:29 +01:00
get_rpcn ( ) - > get_score_friend ( req_id , trans_ctx - > communicationId , boardId , include_self , with_comments , with_gameinfo , arrayNum ) ;
2022-05-18 17:44:21 +02:00
2023-04-01 21:52:07 +02:00
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
2022-05-18 17:44:21 +02:00
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_get_score_friends ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2022-05-18 17:44:21 +02:00
{
2025-02-05 20:28:08 +01:00
handle_GetScoreResponse ( req_id , error , reply ) ;
2022-05-18 17:44:21 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : get_score_npid ( shared_ptr < score_transaction_ctx > & trans_ctx , SceNpScoreBoardId boardId , const std : : vector < std : : pair < SceNpId , s32 > > & npid_vec , vm : : ptr < SceNpScorePlayerRankData > rankArray , u32 rankArraySize , vm : : ptr < SceNpScoreComment > commentArray , [[maybe_unused]] u32 commentArraySize , vm : : ptr < void > infoArray , u32 infoArraySize , u32 arrayNum , vm : : ptr < CellRtcTick > lastSortDate , vm : : ptr < SceNpScoreRankNumber > totalRecord , bool async , bool deprecated )
2022-05-18 17:44:21 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : SCORE ) ;
2022-10-01 14:40:16 +02:00
trans_ctx - > tdata = tdata_get_score_generic {
2023-01-12 04:05:05 +01:00
. rankArray = rankArray ,
2022-10-01 14:40:16 +02:00
. rankArraySize = rankArraySize ,
2023-01-12 04:05:05 +01:00
. commentArray = commentArray ,
. infoArray = infoArray ,
2022-10-01 14:40:16 +02:00
. infoArraySize = infoArraySize ,
2023-01-12 04:05:05 +01:00
. arrayNum = arrayNum ,
. lastSortDate = lastSortDate ,
. totalRecord = totalRecord ,
2024-07-15 08:13:58 +02:00
. player_rank_data = true ,
. deprecated = deprecated ,
2022-10-01 14:40:16 +02:00
} ;
2022-05-18 17:44:21 +02:00
bool with_comments = ! ! commentArray ;
bool with_gameinfo = ! ! infoArray ;
2023-03-03 10:45:29 +01:00
get_rpcn ( ) - > get_score_npid ( req_id , trans_ctx - > communicationId , boardId , npid_vec , with_comments , with_gameinfo ) ;
2022-05-18 17:44:21 +02:00
2023-04-01 21:52:07 +02:00
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
2022-05-18 17:44:21 +02:00
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_get_score_npid ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2022-05-18 17:44:21 +02:00
{
2025-02-05 20:28:08 +01:00
handle_GetScoreResponse ( req_id , error , reply , true ) ;
2022-05-18 17:44:21 +02:00
}
2025-02-05 20:28:08 +01:00
void np_handler : : handle_tus_no_data ( u32 req_id , rpcn : : ErrorType error )
2023-04-01 21:52:07 +02:00
{
std : : lock_guard lock_trans ( mutex_async_transactions ) ;
if ( ! async_transactions . count ( req_id ) )
{
rpcn_log . error ( " Couldn't find transaction(%d) in trans_id! " , req_id ) ;
2025-02-05 20:28:08 +01:00
return ;
2023-04-01 21:52:07 +02:00
}
auto trans = : : at32 ( async_transactions , req_id ) ;
std : : lock_guard lock ( trans - > mutex ) ;
2025-02-05 20:28:08 +01:00
switch ( error )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
case rpcn : : ErrorType : : NoError : trans - > set_result_and_wake ( CELL_OK ) ; break ;
case rpcn : : ErrorType : : NotFound : trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED ) ; break ;
case rpcn : : ErrorType : : Unauthorized : trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN ) ; break ;
case rpcn : : ErrorType : : CondFail : trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED ) ; break ;
default : fmt : : throw_exception ( " Unexpected error in handle_tus_no_data: %d " , static_cast < u8 > ( error ) ) ;
2023-04-01 21:52:07 +02:00
}
}
2025-02-05 20:28:08 +01:00
void np_handler : : handle_TusVarResponse ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2023-04-01 21:52:07 +02:00
{
std : : lock_guard lock_trans ( mutex_async_transactions ) ;
if ( ! async_transactions . count ( req_id ) )
{
rpcn_log . error ( " Couldn't find transaction(%d) in trans_id! " , req_id ) ;
2025-02-05 20:28:08 +01:00
return ;
2023-04-01 21:52:07 +02:00
}
2024-12-22 19:59:48 +01:00
auto tus_trans = idm : : get_unlocked < tus_transaction_ctx > ( : : at32 ( async_transactions , req_id ) - > idm_id ) ;
2023-04-01 21:52:07 +02:00
ensure ( tus_trans ) ;
std : : lock_guard lock ( tus_trans - > mutex ) ;
2025-02-05 20:28:08 +01:00
switch ( error )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : NotFound : return tus_trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED ) ;
case rpcn : : ErrorType : : Unauthorized : return tus_trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN ) ;
case rpcn : : ErrorType : : CondFail : return tus_trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED ) ;
default : fmt : : throw_exception ( " Unexpected error in handle_TusVarResponse: %d " , static_cast < u8 > ( error ) ) ;
2023-04-01 21:52:07 +02:00
}
2024-05-14 00:12:50 +02:00
const auto * resp = reply . get_flatbuffer < TusVarResponse > ( ) ;
2025-02-05 20:28:08 +01:00
ensure ( ! reply . is_error ( ) , " Error parsing response in handle_TusVarResponse " ) ;
2023-04-01 21:52:07 +02:00
const auto * tdata = std : : get_if < tdata_tus_get_variables_generic > ( & tus_trans - > tdata ) ;
ensure ( tdata ) ;
ensure ( resp - > vars ( ) & & resp - > vars ( ) - > size ( ) < = static_cast < usz > ( tdata - > arrayNum ) ) ;
const auto * fb_vars = resp - > vars ( ) ;
memset ( tdata - > variableArray . get_ptr ( ) , 0 , sizeof ( SceNpTusVariable ) * tdata - > arrayNum ) ;
for ( flatbuffers : : uoffset_t i = 0 ; i < fb_vars - > size ( ) ; i + + )
{
auto * cur_var = & tdata - > variableArray [ i ] ;
const auto * cur_fb_var = fb_vars - > Get ( i ) ;
ensure ( cur_fb_var - > ownerId ( ) ) ;
string_to_npid ( cur_fb_var - > ownerId ( ) - > string_view ( ) , cur_var - > ownerId ) ;
if ( ! cur_fb_var - > hasData ( ) )
{
continue ;
}
ensure ( cur_fb_var - > lastChangedAuthorId ( ) ) ;
cur_var - > hasData = 1 ;
cur_var - > lastChangedDate . tick = cur_fb_var - > lastChangedDate ( ) ;
string_to_npid ( cur_fb_var - > lastChangedAuthorId ( ) - > string_view ( ) , cur_var - > lastChangedAuthorId ) ;
cur_var - > variable = cur_fb_var - > variable ( ) ;
cur_var - > oldVariable = cur_fb_var - > oldVariable ( ) ;
}
tus_trans - > result = not_an_error ( fb_vars - > size ( ) ) ;
tus_trans - > wake_cond . notify_one ( ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : handle_TusVariable ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2023-04-01 21:52:07 +02:00
{
std : : lock_guard lock_trans ( mutex_async_transactions ) ;
if ( ! async_transactions . count ( req_id ) )
{
rpcn_log . error ( " Couldn't find transaction(%d) in trans_id! " , req_id ) ;
2025-02-05 20:28:08 +01:00
return ;
2023-04-01 21:52:07 +02:00
}
2024-12-22 19:59:48 +01:00
auto tus_trans = idm : : get_unlocked < tus_transaction_ctx > ( : : at32 ( async_transactions , req_id ) - > idm_id ) ;
2023-04-01 21:52:07 +02:00
ensure ( tus_trans ) ;
std : : lock_guard lock ( tus_trans - > mutex ) ;
2025-02-05 20:28:08 +01:00
switch ( error )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : NotFound : return tus_trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED ) ;
case rpcn : : ErrorType : : Unauthorized : return tus_trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN ) ;
case rpcn : : ErrorType : : CondFail : return tus_trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED ) ;
default : fmt : : throw_exception ( " Unexpected error in handle_TusVariable: %d " , static_cast < u8 > ( error ) ) ;
2023-04-01 21:52:07 +02:00
}
const auto * fb_var = reply . get_flatbuffer < TusVariable > ( ) ;
2025-02-05 20:28:08 +01:00
ensure ( ! reply . is_error ( ) , " Error parsing response in handle_TusVariable " ) ;
2023-04-01 21:52:07 +02:00
const auto * tdata = std : : get_if < tdata_tus_get_variable_generic > ( & tus_trans - > tdata ) ;
ensure ( tdata ) ;
auto * var = tdata - > outVariable . get_ptr ( ) ;
memset ( var , 0 , sizeof ( SceNpTusVariable ) ) ;
ensure ( fb_var - > ownerId ( ) ) ;
string_to_npid ( fb_var - > ownerId ( ) - > string_view ( ) , var - > ownerId ) ;
if ( fb_var - > hasData ( ) )
{
ensure ( fb_var - > lastChangedAuthorId ( ) ) ;
var - > hasData = 1 ;
var - > lastChangedDate . tick = fb_var - > lastChangedDate ( ) ;
string_to_npid ( fb_var - > lastChangedAuthorId ( ) - > string_view ( ) , var - > lastChangedAuthorId ) ;
var - > variable = fb_var - > variable ( ) ;
var - > oldVariable = fb_var - > oldVariable ( ) ;
}
tus_trans - > result = CELL_OK ;
tus_trans - > wake_cond . notify_one ( ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : handle_TusDataStatusResponse ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2023-04-01 21:52:07 +02:00
{
std : : lock_guard lock_trans ( mutex_async_transactions ) ;
if ( ! async_transactions . count ( req_id ) )
{
rpcn_log . error ( " Couldn't find transaction(%d) in trans_id! " , req_id ) ;
2025-02-05 20:28:08 +01:00
return ;
2023-04-01 21:52:07 +02:00
}
2024-12-22 19:59:48 +01:00
auto tus_trans = idm : : get_unlocked < tus_transaction_ctx > ( : : at32 ( async_transactions , req_id ) - > idm_id ) ;
2023-04-01 21:52:07 +02:00
ensure ( tus_trans ) ;
std : : lock_guard lock ( tus_trans - > mutex ) ;
2025-02-05 20:28:08 +01:00
switch ( error )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : NotFound : return tus_trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED ) ;
case rpcn : : ErrorType : : Unauthorized : return tus_trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN ) ;
case rpcn : : ErrorType : : CondFail : return tus_trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED ) ;
default : fmt : : throw_exception ( " Unexpected error in handle_TusDataStatusResponse: %d " , static_cast < u8 > ( error ) ) ;
2023-04-01 21:52:07 +02:00
}
2024-05-14 00:12:50 +02:00
const auto * resp = reply . get_flatbuffer < TusDataStatusResponse > ( ) ;
2025-02-05 20:28:08 +01:00
ensure ( ! reply . is_error ( ) , " Error parsing response in handle_TusDataStatusReponse " ) ;
2023-04-01 21:52:07 +02:00
const auto * tdata = std : : get_if < tdata_tus_get_datastatus_generic > ( & tus_trans - > tdata ) ;
ensure ( tdata ) ;
ensure ( resp - > status ( ) & & resp - > status ( ) - > size ( ) < = static_cast < usz > ( tdata - > arrayNum ) ) ;
const auto * fb_status = resp - > status ( ) ;
memset ( tdata - > statusArray . get_ptr ( ) , 0 , sizeof ( SceNpTusDataStatus ) * tdata - > arrayNum ) ;
for ( flatbuffers : : uoffset_t i = 0 ; i < fb_status - > size ( ) ; i + + )
{
auto * cur_status = & tdata - > statusArray [ i ] ;
const auto * cur_fb_status = fb_status - > Get ( i ) ;
ensure ( cur_fb_status - > ownerId ( ) ) ;
string_to_npid ( cur_fb_status - > ownerId ( ) - > string_view ( ) , cur_status - > ownerId ) ;
if ( ! cur_fb_status - > hasData ( ) )
{
continue ;
}
ensure ( cur_fb_status - > lastChangedAuthorId ( ) ) ;
cur_status - > hasData = 1 ;
cur_status - > lastChangedDate . tick = cur_fb_status - > lastChangedDate ( ) ;
string_to_npid ( cur_fb_status - > lastChangedAuthorId ( ) - > string_view ( ) , cur_status - > lastChangedAuthorId ) ;
cur_status - > info . infoSize = cur_fb_status - > info ( ) ? cur_fb_status - > info ( ) - > size ( ) : 0 ;
2023-12-29 18:33:29 +01:00
for ( flatbuffers : : uoffset_t i = 0 ; i < cur_status - > info . infoSize ; i + + )
2023-04-01 21:52:07 +02:00
{
cur_status - > info . data [ i ] = cur_fb_status - > info ( ) - > Get ( i ) ;
}
}
tus_trans - > result = not_an_error ( fb_status - > size ( ) ) ;
tus_trans - > wake_cond . notify_one ( ) ;
}
2024-12-22 19:59:48 +01:00
void np_handler : : tus_set_multislot_variable ( shared_ptr < tus_transaction_ctx > & trans_ctx , const SceNpOnlineId & targetNpId , vm : : cptr < SceNpTusSlotId > slotIdArray , vm : : cptr < s64 > variableArray , s32 arrayNum , bool vuser , bool async )
2023-04-01 21:52:07 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : TUS ) ;
2023-04-01 21:52:07 +02:00
get_rpcn ( ) - > tus_set_multislot_variable ( req_id , trans_ctx - > communicationId , targetNpId , slotIdArray , variableArray , arrayNum , vuser ) ;
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_tus_set_multislot_variable ( u32 req_id , rpcn : : ErrorType error )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
return handle_tus_no_data ( req_id , error ) ;
2023-04-01 21:52:07 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : tus_get_multislot_variable ( shared_ptr < tus_transaction_ctx > & trans_ctx , const SceNpOnlineId & targetNpId , vm : : cptr < SceNpTusSlotId > slotIdArray , vm : : ptr < SceNpTusVariable > variableArray , s32 arrayNum , bool vuser , bool async )
2023-04-01 21:52:07 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : TUS ) ;
2023-04-01 21:52:07 +02:00
trans_ctx - > tdata = tdata_tus_get_variables_generic {
. variableArray = variableArray ,
. arrayNum = arrayNum ,
} ;
get_rpcn ( ) - > tus_get_multislot_variable ( req_id , trans_ctx - > communicationId , targetNpId , slotIdArray , arrayNum , vuser ) ;
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_tus_get_multislot_variable ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
return handle_TusVarResponse ( req_id , error , reply ) ;
2023-04-01 21:52:07 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : tus_get_multiuser_variable ( shared_ptr < tus_transaction_ctx > & trans_ctx , std : : vector < SceNpOnlineId > targetNpIdArray , SceNpTusSlotId slotId , vm : : ptr < SceNpTusVariable > variableArray , s32 arrayNum , bool vuser , bool async )
2023-04-01 21:52:07 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : TUS ) ;
2023-04-01 21:52:07 +02:00
trans_ctx - > tdata = tdata_tus_get_variables_generic {
. variableArray = variableArray ,
. arrayNum = arrayNum ,
} ;
get_rpcn ( ) - > tus_get_multiuser_variable ( req_id , trans_ctx - > communicationId , targetNpIdArray , slotId , arrayNum , vuser ) ;
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_tus_get_multiuser_variable ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
return handle_TusVarResponse ( req_id , error , reply ) ;
2023-04-01 21:52:07 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : tus_get_friends_variable ( shared_ptr < tus_transaction_ctx > & trans_ctx , SceNpTusSlotId slotId , s32 includeSelf , s32 sortType , vm : : ptr < SceNpTusVariable > variableArray , s32 arrayNum , bool async )
2023-04-01 21:52:07 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : TUS ) ;
2023-04-01 21:52:07 +02:00
trans_ctx - > tdata = tdata_tus_get_variables_generic {
. variableArray = variableArray ,
. arrayNum = arrayNum ,
} ;
get_rpcn ( ) - > tus_get_friends_variable ( req_id , trans_ctx - > communicationId , slotId , ! ! includeSelf , sortType , arrayNum ) ;
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_tus_get_friends_variable ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
return handle_TusVarResponse ( req_id , error , reply ) ;
2023-04-01 21:52:07 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : tus_add_and_get_variable ( shared_ptr < tus_transaction_ctx > & trans_ctx , const SceNpOnlineId & targetNpId , SceNpTusSlotId slotId , s64 inVariable , vm : : ptr < SceNpTusVariable > outVariable , vm : : ptr < SceNpTusAddAndGetVariableOptParam > option , bool vuser , bool async )
2023-04-01 21:52:07 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : TUS ) ;
2023-04-01 21:52:07 +02:00
trans_ctx - > tdata = tdata_tus_get_variable_generic {
. outVariable = outVariable ,
} ;
get_rpcn ( ) - > tus_add_and_get_variable ( req_id , trans_ctx - > communicationId , targetNpId , slotId , inVariable , option , vuser ) ;
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_tus_add_and_get_variable ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
return handle_TusVariable ( req_id , error , reply ) ;
2023-04-01 21:52:07 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : tus_try_and_set_variable ( shared_ptr < tus_transaction_ctx > & trans_ctx , const SceNpOnlineId & targetNpId , SceNpTusSlotId slotId , s32 opeType , s64 variable , vm : : ptr < SceNpTusVariable > resultVariable , vm : : ptr < SceNpTusTryAndSetVariableOptParam > option , bool vuser , bool async )
2023-04-01 21:52:07 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : TUS ) ;
2023-04-01 21:52:07 +02:00
trans_ctx - > tdata = tdata_tus_get_variable_generic {
. outVariable = resultVariable ,
} ;
get_rpcn ( ) - > tus_try_and_set_variable ( req_id , trans_ctx - > communicationId , targetNpId , slotId , opeType , variable , option , vuser ) ;
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_tus_try_and_set_variable ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
return handle_TusVariable ( req_id , error , reply ) ;
2023-04-01 21:52:07 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : tus_delete_multislot_variable ( shared_ptr < tus_transaction_ctx > & trans_ctx , const SceNpOnlineId & targetNpId , vm : : cptr < SceNpTusSlotId > slotIdArray , s32 arrayNum , bool vuser , bool async )
2023-04-01 21:52:07 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : TUS ) ;
2023-04-01 21:52:07 +02:00
get_rpcn ( ) - > tus_delete_multislot_variable ( req_id , trans_ctx - > communicationId , targetNpId , slotIdArray , arrayNum , vuser ) ;
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_tus_delete_multislot_variable ( u32 req_id , rpcn : : ErrorType error )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
return handle_tus_no_data ( req_id , error ) ;
2023-04-01 21:52:07 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : tus_set_data ( shared_ptr < tus_transaction_ctx > & trans_ctx , const SceNpOnlineId & targetNpId , SceNpTusSlotId slotId , u32 totalSize , u32 sendSize , vm : : cptr < void > data , vm : : cptr < SceNpTusDataInfo > info , vm : : ptr < SceNpTusSetDataOptParam > option , bool vuser , bool async )
2023-04-01 21:52:07 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
auto * tdata = std : : get_if < tdata_tus_set_data > ( & trans_ctx - > tdata ) ;
if ( ! tdata )
{
trans_ctx - > tdata = tdata_tus_set_data { . tus_data_size = totalSize } ;
tdata = std : : get_if < tdata_tus_set_data > ( & trans_ctx - > tdata ) ;
tdata - > tus_data . reserve ( totalSize ) ;
}
const u8 * ptr = static_cast < const u8 * > ( data . get_ptr ( ) ) ;
std : : copy ( ptr , ptr + sendSize , std : : back_inserter ( tdata - > tus_data ) ) ;
if ( tdata - > tus_data . size ( ) = = tdata - > tus_data_size )
{
trans_ctx - > result = std : : nullopt ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : TUS ) ;
2023-04-01 21:52:07 +02:00
get_rpcn ( ) - > tus_set_data ( req_id , trans_ctx - > communicationId , targetNpId , slotId , tdata - > tus_data , info , option , vuser ) ;
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
}
else
{
trans_ctx - > result = CELL_OK ;
}
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_tus_set_data ( u32 req_id , rpcn : : ErrorType error )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
return handle_tus_no_data ( req_id , error ) ;
2023-04-01 21:52:07 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : tus_get_data ( shared_ptr < tus_transaction_ctx > & trans_ctx , const SceNpOnlineId & targetNpId , SceNpTusSlotId slotId , vm : : ptr < SceNpTusDataStatus > dataStatus , vm : : ptr < void > data , u32 recvSize , bool vuser , bool async )
2023-04-01 21:52:07 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
auto * tdata = std : : get_if < tdata_tus_get_data > ( & trans_ctx - > tdata ) ;
if ( ! tdata )
{
trans_ctx - > tdata = tdata_tus_get_data { . recvSize = recvSize , . dataStatus = dataStatus , . data = data } ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : SCORE ) ;
2023-04-01 21:52:07 +02:00
get_rpcn ( ) - > tus_get_data ( req_id , trans_ctx - > communicationId , targetNpId , slotId , vuser ) ;
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
return ;
}
// Check if the transaction has actually completed, otherwise adjust tdata parameters
if ( ! trans_ctx - > result )
{
tdata - > recvSize = recvSize ;
tdata - > dataStatus = dataStatus ;
tdata - > data = data ;
return ;
}
// If here the data has already been acquired and the client is just asking for part of it
usz to_copy = std : : min ( tdata - > tus_data . size ( ) , static_cast < usz > ( recvSize ) ) ;
std : : memcpy ( data . get_ptr ( ) , tdata - > tus_data . data ( ) , to_copy ) ;
tdata - > tus_data . erase ( tdata - > tus_data . begin ( ) , tdata - > tus_data . begin ( ) + to_copy ) ;
trans_ctx - > result = not_an_error ( to_copy ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_tus_get_data ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2023-04-01 21:52:07 +02:00
{
std : : lock_guard lock_trans ( mutex_async_transactions ) ;
if ( ! async_transactions . count ( req_id ) )
{
rpcn_log . error ( " Couldn't find transaction(%d) in trans_id! " , req_id ) ;
2025-02-05 20:28:08 +01:00
return ;
2023-04-01 21:52:07 +02:00
}
2024-12-22 19:59:48 +01:00
auto tus_trans = idm : : get_unlocked < tus_transaction_ctx > ( : : at32 ( async_transactions , req_id ) - > idm_id ) ;
2023-04-01 21:52:07 +02:00
ensure ( tus_trans ) ;
std : : lock_guard lock ( tus_trans - > mutex ) ;
2025-02-05 20:28:08 +01:00
switch ( error )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
case rpcn : : ErrorType : : NoError : break ;
case rpcn : : ErrorType : : NotFound : return tus_trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED ) ;
case rpcn : : ErrorType : : Unauthorized : return tus_trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN ) ;
case rpcn : : ErrorType : : CondFail : return tus_trans - > set_result_and_wake ( SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED ) ;
default : fmt : : throw_exception ( " Unexpected error in reply to TusGetData: %d " , static_cast < u8 > ( error ) ) ;
2023-04-01 21:52:07 +02:00
}
const auto * fb_data = reply . get_flatbuffer < TusData > ( ) ;
2025-02-05 20:28:08 +01:00
ensure ( ! reply . is_error ( ) , " Error parsing response in reply_tus_get_data " ) ;
2023-04-01 21:52:07 +02:00
auto * tdata = std : : get_if < tdata_tus_get_data > ( & tus_trans - > tdata ) ;
ensure ( tdata ) ;
const auto * fb_status = fb_data - > status ( ) ;
ensure ( fb_status & & fb_status - > ownerId ( ) ) ;
2025-02-05 20:28:08 +01:00
if ( ! fb_status )
return ; // Sanity check to make compiler happy
2023-04-01 21:52:07 +02:00
auto * data_status = tdata - > dataStatus . get_ptr ( ) ;
auto * data = static_cast < u8 * > ( tdata - > data . get_ptr ( ) ) ;
memset ( data_status , 0 , sizeof ( SceNpTusDataStatus ) ) ;
string_to_npid ( fb_status - > ownerId ( ) - > string_view ( ) , data_status - > ownerId ) ;
if ( fb_status - > hasData ( ) )
{
data_status - > hasData = 1 ;
data_status - > lastChangedDate . tick = fb_status - > lastChangedDate ( ) ;
string_to_npid ( fb_status - > lastChangedAuthorId ( ) - > string_view ( ) , data_status - > lastChangedAuthorId ) ;
data_status - > data = tdata - > data ;
data_status - > dataSize = fb_data - > data ( ) ? fb_data - > data ( ) - > size ( ) : 0 ;
data_status - > info . infoSize = fb_status - > info ( ) ? fb_status - > info ( ) - > size ( ) : 0 ;
2023-12-29 18:33:29 +01:00
const u32 to_copy = std : : min < u32 > ( data_status - > dataSize , tdata - > recvSize ) ;
for ( flatbuffers : : uoffset_t i = 0 ; i < to_copy ; i + + )
2023-04-01 21:52:07 +02:00
{
data [ i ] = fb_data - > data ( ) - > Get ( i ) ;
}
2023-12-29 18:33:29 +01:00
const u32 bytes_left = data_status - > dataSize - to_copy ;
2023-04-01 21:52:07 +02:00
tdata - > tus_data . reserve ( bytes_left ) ;
2023-12-29 18:33:29 +01:00
for ( flatbuffers : : uoffset_t i = to_copy ; i < bytes_left ; i + + )
2023-04-01 21:52:07 +02:00
{
tdata - > tus_data . push_back ( fb_data - > data ( ) - > Get ( i ) ) ;
}
2023-12-29 18:33:29 +01:00
for ( flatbuffers : : uoffset_t i = 0 ; i < data_status - > info . infoSize ; i + + )
2023-04-01 21:52:07 +02:00
{
fb_status - > info ( ) - > Get ( i ) ;
}
tus_trans - > result = not_an_error ( to_copy ) ;
}
else
{
tus_trans - > result = SCE_NP_COMMUNITY_SERVER_ERROR_USER_STORAGE_DATA_NOT_FOUND ;
}
tus_trans - > wake_cond . notify_one ( ) ;
}
2024-12-22 19:59:48 +01:00
void np_handler : : tus_get_multislot_data_status ( shared_ptr < tus_transaction_ctx > & trans_ctx , const SceNpOnlineId & targetNpId , vm : : cptr < SceNpTusSlotId > slotIdArray , vm : : ptr < SceNpTusDataStatus > statusArray , s32 arrayNum , bool vuser , bool async )
2023-04-01 21:52:07 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : TUS ) ;
2023-04-01 21:52:07 +02:00
trans_ctx - > tdata = tdata_tus_get_datastatus_generic {
. statusArray = statusArray ,
. arrayNum = arrayNum ,
} ;
get_rpcn ( ) - > tus_get_multislot_data_status ( req_id , trans_ctx - > communicationId , targetNpId , slotIdArray , arrayNum , vuser ) ;
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_tus_get_multislot_data_status ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
return handle_TusDataStatusResponse ( req_id , error , reply ) ;
2023-04-01 21:52:07 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : tus_get_multiuser_data_status ( shared_ptr < tus_transaction_ctx > & trans_ctx , std : : vector < SceNpOnlineId > targetNpIdArray , SceNpTusSlotId slotId , vm : : ptr < SceNpTusDataStatus > statusArray , s32 arrayNum , bool vuser , bool async )
2023-04-01 21:52:07 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : TUS ) ;
2023-04-01 21:52:07 +02:00
trans_ctx - > tdata = tdata_tus_get_datastatus_generic {
. statusArray = statusArray ,
. arrayNum = arrayNum ,
} ;
get_rpcn ( ) - > tus_get_multiuser_data_status ( req_id , trans_ctx - > communicationId , targetNpIdArray , slotId , arrayNum , vuser ) ;
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_tus_get_multiuser_data_status ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
return handle_TusDataStatusResponse ( req_id , error , reply ) ;
2023-04-01 21:52:07 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : tus_get_friends_data_status ( shared_ptr < tus_transaction_ctx > & trans_ctx , SceNpTusSlotId slotId , s32 includeSelf , s32 sortType , vm : : ptr < SceNpTusDataStatus > statusArray , s32 arrayNum , bool async )
2023-04-01 21:52:07 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : TUS ) ;
2023-04-01 21:52:07 +02:00
trans_ctx - > tdata = tdata_tus_get_datastatus_generic {
. statusArray = statusArray ,
. arrayNum = arrayNum ,
} ;
get_rpcn ( ) - > tus_get_friends_data_status ( req_id , trans_ctx - > communicationId , slotId , ! ! includeSelf , sortType , arrayNum ) ;
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_tus_get_friends_data_status ( u32 req_id , rpcn : : ErrorType error , vec_stream & reply )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
return handle_TusDataStatusResponse ( req_id , error , reply ) ;
2023-04-01 21:52:07 +02:00
}
2024-12-22 19:59:48 +01:00
void np_handler : : tus_delete_multislot_data ( shared_ptr < tus_transaction_ctx > & trans_ctx , const SceNpOnlineId & targetNpId , vm : : cptr < SceNpTusSlotId > slotIdArray , s32 arrayNum , bool vuser , bool async )
2023-04-01 21:52:07 +02:00
{
std : : unique_lock lock ( trans_ctx - > mutex ) ;
2024-05-14 00:12:50 +02:00
const u32 req_id = get_req_id ( REQUEST_ID_HIGH : : TUS ) ;
2023-04-01 21:52:07 +02:00
get_rpcn ( ) - > tus_delete_multislot_data ( req_id , trans_ctx - > communicationId , targetNpId , slotIdArray , arrayNum , vuser ) ;
transaction_async_handler ( std : : move ( lock ) , trans_ctx , req_id , async ) ;
}
2025-02-05 20:28:08 +01:00
void np_handler : : reply_tus_delete_multislot_data ( u32 req_id , rpcn : : ErrorType error )
2023-04-01 21:52:07 +02:00
{
2025-02-05 20:28:08 +01:00
return handle_tus_no_data ( req_id , error ) ;
2023-04-01 21:52:07 +02:00
}
2021-10-28 06:36:57 +02:00
} // namespace np