2020-08-27 21:47:04 +02:00
# pragma once
# include <unordered_map>
# include <chrono>
2020-11-17 02:19:17 +01:00
# include <thread>
# include <semaphore>
2020-08-27 21:47:04 +02:00
# include "Utilities/mutex.h"
2022-05-17 16:35:41 +02:00
# include "Emu/localized_string.h"
2020-08-27 21:47:04 +02:00
2021-03-13 18:02:37 +03:00
# include "util/asm.hpp"
2020-08-27 21:47:04 +02:00
# ifdef _WIN32
# include <winsock2.h>
# else
2021-12-30 19:39:18 +03:00
# ifdef __clang__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wold-style-cast"
# endif
2020-08-27 21:47:04 +02:00
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
2021-12-30 19:39:18 +03:00
# ifdef __clang__
# pragma GCC diagnostic pop
# endif
2020-08-27 21:47:04 +02:00
# endif
# include "Emu/Cell/Modules/sceNp.h"
# include "Emu/Cell/Modules/sceNp2.h"
2023-04-01 21:52:07 +02:00
# include "Emu/Cell/Modules/sceNpTus.h"
2020-08-27 21:47:04 +02:00
# include "generated/np2_structs_generated.h"
2023-07-11 20:40:30 +02:00
# ifdef __clang__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wold-style-cast"
# endif
2020-08-27 21:47:04 +02:00
# include <wolfssl/ssl.h>
2023-07-11 20:40:30 +02:00
# ifdef __clang__
# pragma GCC diagnostic pop
# endif
2020-08-27 21:47:04 +02:00
2024-05-14 00:12:50 +02:00
// COMID is sent as 9 chars - + '_' + 2 digits
constexpr usz COMMUNICATION_ID_COMID_COMPONENT_SIZE = 9 ;
constexpr usz COMMUNICATION_ID_SUBID_COMPONENT_SIZE = 2 ;
constexpr usz COMMUNICATION_ID_SIZE = COMMUNICATION_ID_COMID_COMPONENT_SIZE + COMMUNICATION_ID_SUBID_COMPONENT_SIZE + 1 ;
2020-08-27 21:47:04 +02:00
class vec_stream
{
public :
vec_stream ( ) = delete ;
2020-12-18 10:39:54 +03:00
vec_stream ( std : : vector < u8 > & _vec , usz initial_index = 0 )
2020-11-17 02:19:17 +01:00
: vec ( _vec ) , i ( initial_index ) { }
2020-08-27 21:47:04 +02:00
bool is_error ( ) const
{
return error ;
}
2024-01-05 09:43:26 +01:00
void dump ( ) const ;
2020-08-27 21:47:04 +02:00
// Getters
template < typename T >
T get ( )
{
2024-01-05 09:43:26 +01:00
if ( sizeof ( T ) + i > vec . size ( ) | | error )
2020-08-27 21:47:04 +02:00
{
error = true ;
2024-01-05 09:43:26 +01:00
return static_cast < T > ( 0 ) ;
2020-08-27 21:47:04 +02:00
}
2023-08-19 12:20:06 +03:00
T res = read_from_ptr < le_t < T > > ( & vec [ i ] ) ;
2020-08-27 21:47:04 +02:00
i + = sizeof ( T ) ;
return res ;
}
std : : string get_string ( bool empty )
{
std : : string res { } ;
while ( i < vec . size ( ) & & vec [ i ] ! = 0 )
{
res . push_back ( vec [ i ] ) ;
i + + ;
}
i + + ;
2021-04-09 21:12:47 +02:00
if ( ! empty & & res . empty ( ) )
2020-08-27 21:47:04 +02:00
{
error = true ;
}
return res ;
}
std : : vector < u8 > get_rawdata ( )
{
u32 size = get < u32 > ( ) ;
2024-01-05 09:43:26 +01:00
if ( i + size > vec . size ( ) )
{
2020-08-27 21:47:04 +02:00
error = true ;
2024-01-05 09:43:26 +01:00
return { } ;
}
2020-08-27 21:47:04 +02:00
2024-01-05 09:43:26 +01:00
std : : vector < u8 > ret ;
std : : copy ( vec . begin ( ) + i , vec . begin ( ) + i + size , std : : back_inserter ( ret ) ) ;
i + = size ;
2020-08-27 21:47:04 +02:00
return ret ;
}
2024-01-05 09:43:26 +01:00
SceNpCommunicationId get_com_id ( )
{
if ( i + COMMUNICATION_ID_SIZE > vec . size ( ) | | error )
{
error = true ;
return { } ;
}
SceNpCommunicationId com_id { } ;
2024-05-14 00:12:50 +02:00
std : : memcpy ( & com_id . data [ 0 ] , & vec [ i ] , COMMUNICATION_ID_COMID_COMPONENT_SIZE ) ;
const std : : string sub_id ( reinterpret_cast < const char * > ( & vec [ i + COMMUNICATION_ID_COMID_COMPONENT_SIZE + 1 ] ) , COMMUNICATION_ID_SUBID_COMPONENT_SIZE ) ;
const unsigned long result_num = std : : strtoul ( sub_id . c_str ( ) , nullptr , 10 ) ;
if ( result_num > 99 )
{
error = true ;
return { } ;
}
com_id . num = static_cast < u8 > ( result_num ) ;
2024-01-05 09:43:26 +01:00
i + = COMMUNICATION_ID_SIZE ;
return com_id ;
}
2022-10-01 14:40:16 +02:00
template < typename T >
const T * get_flatbuffer ( )
{
auto rawdata_vec = get_rawdata ( ) ;
if ( error )
return nullptr ;
if ( vec . empty ( ) )
{
error = true ;
return nullptr ;
}
const T * ret = flatbuffers : : GetRoot < T > ( rawdata_vec . data ( ) ) ;
flatbuffers : : Verifier verifier ( rawdata_vec . data ( ) , rawdata_vec . size ( ) ) ;
if ( ! ret - > Verify ( verifier ) )
{
error = true ;
return nullptr ;
}
aligned_bufs . push_back ( std : : move ( rawdata_vec ) ) ;
return ret ;
}
2020-08-27 21:47:04 +02:00
// Setters
template < typename T >
void insert ( T value )
{
2021-03-13 18:02:37 +03:00
value = std : : bit_cast < le_t < T > , T > ( value ) ;
2020-08-27 21:47:04 +02:00
// resize + memcpy instead?
2020-12-18 10:39:54 +03:00
for ( usz index = 0 ; index < sizeof ( T ) ; index + + )
2020-08-27 21:47:04 +02:00
{
vec . push_back ( * ( reinterpret_cast < u8 * > ( & value ) + index ) ) ;
}
}
2021-04-09 21:12:47 +02:00
void insert_string ( const std : : string & str ) const
2020-08-27 21:47:04 +02:00
{
std : : copy ( str . begin ( ) , str . end ( ) , std : : back_inserter ( vec ) ) ;
vec . push_back ( 0 ) ;
}
protected :
std : : vector < u8 > & vec ;
2022-10-01 14:40:16 +02:00
std : : vector < std : : vector < u8 > > aligned_bufs ;
2020-11-17 02:19:17 +01:00
usz i = 0 ;
2020-08-27 21:47:04 +02:00
bool error = false ;
} ;
2020-11-17 02:19:17 +01:00
namespace rpcn
2020-08-27 21:47:04 +02:00
{
2020-11-17 02:19:17 +01:00
enum CommandType : u16
{
Login ,
Terminate ,
Create ,
SendToken ,
2022-05-18 17:44:21 +02:00
SendResetToken ,
ResetPassword ,
2020-11-17 02:19:17 +01:00
AddFriend ,
RemoveFriend ,
AddBlock ,
RemoveBlock ,
GetServerList ,
GetWorldList ,
CreateRoom ,
JoinRoom ,
LeaveRoom ,
SearchRoom ,
GetRoomDataExternalList ,
SetRoomDataExternal ,
GetRoomDataInternal ,
SetRoomDataInternal ,
2024-01-14 12:36:23 +01:00
GetRoomMemberDataInternal ,
2021-07-25 21:40:35 +03:00
SetRoomMemberDataInternal ,
2024-01-14 12:36:23 +01:00
SetUserInfo ,
2020-11-17 02:19:17 +01:00
PingRoomOwner ,
SendRoomMessage ,
RequestSignalingInfos ,
RequestTicket ,
SendMessage ,
2022-05-18 17:44:21 +02:00
GetBoardInfos ,
RecordScore ,
2022-10-01 14:40:16 +02:00
RecordScoreData ,
2022-05-18 17:44:21 +02:00
GetScoreData ,
GetScoreRange ,
GetScoreFriends ,
GetScoreNpid ,
2023-04-01 21:52:07 +02:00
GetNetworkTime ,
TusSetMultiSlotVariable ,
TusGetMultiSlotVariable ,
TusGetMultiUserVariable ,
TusGetFriendsVariable ,
TusAddAndGetVariable ,
TusTryAndSetVariable ,
TusDeleteMultiSlotVariable ,
TusSetData ,
TusGetData ,
TusGetMultiSlotDataStatus ,
TusGetMultiUserDataStatus ,
TusGetFriendsDataStatus ,
TusDeleteMultiSlotData ,
2024-01-05 09:43:26 +01:00
ClearPresence ,
SetPresence ,
2024-05-14 00:12:50 +02:00
CreateRoomGUI ,
JoinRoomGUI ,
LeaveRoomGUI ,
GetRoomListGUI ,
SetRoomSearchFlagGUI ,
GetRoomSearchFlagGUI ,
SetRoomInfoGUI ,
GetRoomInfoGUI ,
QuickMatchGUI ,
SearchJoinRoomGUI ,
2020-11-17 02:19:17 +01:00
} ;
enum NotificationType : u16
{
UserJoinedRoom ,
UserLeftRoom ,
RoomDestroyed ,
2021-07-25 21:40:35 +03:00
UpdatedRoomDataInternal ,
UpdatedRoomMemberDataInternal ,
2020-11-17 02:19:17 +01:00
SignalP2PConnect ,
_SignalP2PDisconnect ,
FriendQuery , // Other user sent a friend request
FriendNew , // Add a friend to the friendlist(either accepted a friend request or friend accepted it)
FriendLost , // Remove friend from the friendlist(user removed friend or friend removed friend)
FriendStatus , // Set status of friend to Offline or Online
RoomMessageReceived ,
MessageReceived ,
2024-01-05 09:43:26 +01:00
FriendPresenceChanged ,
2024-01-31 05:25:26 +01:00
SignalingInfo ,
2024-05-14 00:12:50 +02:00
MemberJoinedRoomGUI ,
MemberLeftRoomGUI ,
RoomDisappearedGUI ,
RoomOwnerChangedGUI ,
UserKickedGUI ,
QuickMatchCompleteGUI ,
2020-11-17 02:19:17 +01:00
} ;
enum class rpcn_state
{
failure_no_failure ,
failure_input ,
failure_wolfssl ,
failure_resolve ,
failure_connect ,
failure_id ,
failure_id_already_logged_in ,
failure_id_username ,
failure_id_password ,
failure_id_token ,
failure_protocol ,
failure_other ,
} ;
2020-08-27 21:47:04 +02:00
enum PacketType : u8
{
Request ,
Reply ,
Notification ,
ServerInfo ,
} ;
enum ErrorType : u8
{
2020-11-17 02:19:17 +01:00
NoError , // No error
Malformed , // Query was malformed, critical error that should close the connection
Invalid , // The request type is invalid(wrong stage?)
InvalidInput , // The Input doesn't fit the constraints of the request
TooSoon , // Time limited operation attempted too soon
LoginError , // An error happened related to login
LoginAlreadyLoggedIn , // Can't log in because you're already logged in
LoginInvalidUsername , // Invalid username
LoginInvalidPassword , // Invalid password
LoginInvalidToken , // Invalid token
CreationError , // An error happened related to account creation
2022-10-01 14:40:16 +02:00
CreationExistingUsername , // Specific to Account Creation: username exists already
2020-11-17 02:19:17 +01:00
CreationBannedEmailProvider , // Specific to Account Creation: the email provider is banned
CreationExistingEmail , // Specific to Account Creation: that email is already registered to an account
2022-10-01 14:40:16 +02:00
RoomMissing , // User tried to join a non existing room
RoomAlreadyJoined , // User tried to join a room he's already part of
RoomFull , // User tried to join a full room
2021-10-26 12:00:17 +02:00
Unauthorized , // User attempted an unauthorized operation
2020-11-17 02:19:17 +01:00
DbFail , // Generic failure on db side
EmailFail , // Generic failure related to email
NotFound , // Object of the query was not found(room, user, etc)
Blocked , // The operation can't complete because you've been blocked
AlreadyFriend , // Can't add friend because already friend
2022-05-18 17:44:21 +02:00
ScoreNotBest , // A better score is already registered for that user/character_id
2022-10-01 14:40:16 +02:00
ScoreInvalid , // Score for player was found but wasn't what was expected
ScoreHasData , // Score already has data
2023-04-01 21:52:07 +02:00
CondFail , // Condition related to query failed
2020-08-27 21:47:04 +02:00
Unsupported ,
__error_last
} ;
2020-11-17 02:19:17 +01:00
using friend_cb_func = void ( * ) ( void * param , NotificationType ntype , const std : : string & username , bool status ) ;
using message_cb_func = void ( * ) ( void * param , const std : : shared_ptr < std : : pair < std : : string , message_data > > new_msg , u64 msg_id ) ;
2020-08-27 21:47:04 +02:00
2024-01-05 09:43:26 +01:00
struct friend_online_data
{
friend_online_data ( bool online , SceNpCommunicationId & & pr_com_id , std : : string & & pr_title , std : : string & & pr_status , std : : string & & pr_comment , std : : vector < u8 > & & pr_data )
: online ( online ) , timestamp ( 0 ) , pr_com_id ( pr_com_id ) , pr_title ( pr_title ) , pr_status ( pr_status ) , pr_comment ( pr_comment ) , pr_data ( pr_data ) { }
friend_online_data ( bool online , u64 timestamp )
: online ( online ) , timestamp ( timestamp ) { }
2024-01-10 16:46:02 +01:00
void dump ( ) const ;
2024-01-05 09:43:26 +01:00
bool online = false ;
u64 timestamp = 0 ;
SceNpCommunicationId pr_com_id { } ;
std : : string pr_title ;
std : : string pr_status ;
std : : string pr_comment ;
std : : vector < u8 > pr_data ;
} ;
2020-11-17 02:19:17 +01:00
struct friend_data
2020-08-27 21:47:04 +02:00
{
2024-01-05 09:43:26 +01:00
std : : map < std : : string , friend_online_data > friends ;
2020-11-17 02:19:17 +01:00
std : : set < std : : string > requests_sent ;
std : : set < std : : string > requests_received ;
std : : set < std : : string > blocked ;
} ;
2020-08-27 21:47:04 +02:00
2022-05-17 16:35:41 +02:00
localized_string_id rpcn_state_to_localized_string_id ( rpcn : : rpcn_state state ) ;
std : : string rpcn_state_to_string ( rpcn : : rpcn_state state ) ;
2022-05-18 17:44:21 +02:00
bool is_error ( ErrorType err ) ;
2022-05-17 16:35:41 +02:00
2020-11-17 02:19:17 +01:00
class rpcn_client
2020-08-27 21:47:04 +02:00
{
2020-11-17 02:19:17 +01:00
private :
static inline std : : weak_ptr < rpcn_client > instance ;
static inline shared_mutex inst_mutex ;
2020-08-27 21:47:04 +02:00
2020-11-17 02:19:17 +01:00
atomic_t < bool > connected = false ;
atomic_t < bool > authentified = false ;
2021-10-12 19:45:54 +02:00
atomic_t < bool > want_conn = false ;
2020-11-17 02:19:17 +01:00
atomic_t < bool > want_auth = false ;
std : : binary_semaphore sem_connected , sem_authentified ;
std : : mutex mutex_connected , mutex_authentified ;
2020-08-27 21:47:04 +02:00
2020-11-17 02:19:17 +01:00
std : : binary_semaphore sem_reader , sem_writer , sem_rpcn ;
std : : mutex mutex_read , mutex_write ;
2020-08-27 21:47:04 +02:00
2020-11-17 02:19:17 +01:00
std : : thread thread_rpcn , thread_rpcn_reader , thread_rpcn_writer ;
2020-08-27 21:47:04 +02:00
2020-11-17 02:19:17 +01:00
atomic_t < bool > terminate = false ;
2020-08-27 21:47:04 +02:00
2020-11-17 02:19:17 +01:00
atomic_t < u32 > num_failures = 0 ;
atomic_t < rpcn_state > state = rpcn_state : : failure_no_failure ;
2020-08-27 21:47:04 +02:00
2020-11-17 02:19:17 +01:00
std : : vector < std : : vector < u8 > > packets_to_send ;
std : : mutex mutex_packets_to_send ;
2020-08-27 21:47:04 +02:00
2020-11-17 02:19:17 +01:00
// Friends related
shared_mutex mutex_friends ;
std : : set < std : : pair < friend_cb_func , void * > > friend_cbs ;
friend_data friend_infos ;
2020-08-27 21:47:04 +02:00
2020-11-17 02:19:17 +01:00
void handle_friend_notification ( u16 command , std : : vector < u8 > data ) ;
2020-08-27 21:47:04 +02:00
2020-11-17 02:19:17 +01:00
void handle_message ( std : : vector < u8 > data ) ;
2020-08-27 21:47:04 +02:00
2020-11-17 02:19:17 +01:00
private :
rpcn_client ( ) ;
2020-08-27 21:47:04 +02:00
2020-11-17 02:19:17 +01:00
void rpcn_reader_thread ( ) ;
void rpcn_writer_thread ( ) ;
void rpcn_thread ( ) ;
2020-08-27 21:47:04 +02:00
2020-11-17 02:19:17 +01:00
bool handle_input ( ) ;
bool handle_output ( ) ;
2020-08-27 21:47:04 +02:00
2023-05-18 00:48:05 +02:00
void add_packet ( std : : vector < u8 > packet ) ;
2020-08-27 21:47:04 +02:00
2020-11-17 02:19:17 +01:00
private :
enum class recvn_result
{
recvn_success ,
recvn_nodata ,
recvn_timeout ,
recvn_noconn ,
recvn_terminate ,
recvn_fatal ,
} ;
recvn_result recvn ( u8 * buf , usz n ) ;
bool send_packet ( const std : : vector < u8 > & packet ) ;
private :
bool connect ( const std : : string & host ) ;
bool login ( const std : : string & npid , const std : : string & password , const std : : string & token ) ;
void disconnect ( ) ;
public :
~ rpcn_client ( ) ;
2022-05-18 17:44:21 +02:00
rpcn_client ( rpcn_client & other ) = delete ;
2020-11-17 02:19:17 +01:00
void operator = ( const rpcn_client & ) = delete ;
2023-03-03 10:45:29 +01:00
static std : : shared_ptr < rpcn_client > get_instance ( bool check_config = false ) ;
2020-11-17 02:19:17 +01:00
rpcn_state wait_for_connection ( ) ;
rpcn_state wait_for_authentified ( ) ;
2024-01-29 10:24:02 +01:00
bool terminate_connection ( ) ;
2020-11-17 02:19:17 +01:00
2024-10-01 01:44:39 +02:00
void get_friends ( friend_data & friend_infos ) ;
2020-11-17 02:19:17 +01:00
void get_friends_and_register_cb ( friend_data & friend_infos , friend_cb_func cb_func , void * cb_param ) ;
2024-10-03 19:38:56 +02:00
void register_friend_cb ( friend_cb_func , void * cb_param ) ;
2020-11-17 02:19:17 +01:00
void remove_friend_cb ( friend_cb_func , void * cb_param ) ;
2022-05-18 17:44:21 +02:00
ErrorType create_user ( std : : string_view npid , std : : string_view password , std : : string_view online_name , std : : string_view avatar_url , std : : string_view email ) ;
2021-10-13 07:26:57 +02:00
ErrorType resend_token ( const std : : string & npid , const std : : string & password ) ;
2022-05-18 17:44:21 +02:00
ErrorType send_reset_token ( std : : string_view npid , std : : string_view email ) ;
ErrorType reset_password ( std : : string_view npid , std : : string_view token , std : : string_view password ) ;
2020-11-17 02:19:17 +01:00
bool add_friend ( const std : : string & friend_username ) ;
bool remove_friend ( const std : : string & friend_username ) ;
2021-11-06 21:18:31 +01:00
u32 get_num_friends ( ) ;
u32 get_num_blocks ( ) ;
std : : optional < std : : string > get_friend_by_index ( u32 index ) ;
2024-01-05 09:43:26 +01:00
std : : optional < std : : pair < std : : string , friend_online_data > > get_friend_presence_by_index ( u32 index ) ;
std : : optional < std : : pair < std : : string , friend_online_data > > get_friend_presence_by_npid ( const std : : string & npid ) ;
2020-11-17 02:19:17 +01:00
std : : vector < std : : pair < u16 , std : : vector < u8 > > > get_notifications ( ) ;
std : : unordered_map < u32 , std : : pair < u16 , std : : vector < u8 > > > get_replies ( ) ;
2024-01-05 09:43:26 +01:00
std : : unordered_map < std : : string , friend_online_data > get_presence_updates ( ) ;
std : : map < std : : string , friend_online_data > get_presence_states ( ) ;
2020-11-17 02:19:17 +01:00
std : : vector < u64 > get_new_messages ( ) ;
std : : optional < std : : shared_ptr < std : : pair < std : : string , message_data > > > get_message ( u64 id ) ;
std : : vector < std : : pair < u64 , std : : shared_ptr < std : : pair < std : : string , message_data > > > > get_messages_and_register_cb ( SceNpBasicMessageMainType type , bool include_bootable , message_cb_func cb_func , void * cb_param ) ;
void remove_message_cb ( message_cb_func cb_func , void * cb_param ) ;
2023-03-15 02:37:49 +01:00
void mark_message_used ( u64 id ) ;
2020-11-17 02:19:17 +01:00
2024-04-24 19:27:50 +02:00
bool is_connected ( ) const ;
bool is_authentified ( ) const ;
rpcn_state get_rpcn_state ( ) const ;
2020-08-27 21:47:04 +02:00
2020-11-17 02:19:17 +01:00
void server_infos_updated ( ) ;
// Synchronous requests
bool get_server_list ( u32 req_id , const SceNpCommunicationId & communication_id , std : : vector < u16 > & server_list ) ;
2023-04-01 21:52:07 +02:00
u64 get_network_time ( u32 req_id ) ;
2020-11-17 02:19:17 +01:00
// Asynchronous requests
bool get_world_list ( u32 req_id , const SceNpCommunicationId & communication_id , u16 server_id ) ;
bool createjoin_room ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpMatching2CreateJoinRoomRequest * req ) ;
bool join_room ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpMatching2JoinRoomRequest * req ) ;
bool leave_room ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpMatching2LeaveRoomRequest * req ) ;
bool search_room ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpMatching2SearchRoomRequest * req ) ;
bool get_roomdata_external_list ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpMatching2GetRoomDataExternalListRequest * req ) ;
bool set_roomdata_external ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpMatching2SetRoomDataExternalRequest * req ) ;
bool get_roomdata_internal ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpMatching2GetRoomDataInternalRequest * req ) ;
bool set_roomdata_internal ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpMatching2SetRoomDataInternalRequest * req ) ;
2024-01-14 12:36:23 +01:00
bool get_roommemberdata_internal ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpMatching2GetRoomMemberDataInternalRequest * req ) ;
2021-07-25 21:40:35 +03:00
bool set_roommemberdata_internal ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpMatching2SetRoomMemberDataInternalRequest * req ) ;
2024-01-14 12:36:23 +01:00
bool set_userinfo ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpMatching2SetUserInfoRequest * req ) ;
2020-11-17 02:19:17 +01:00
bool ping_room_owner ( u32 req_id , const SceNpCommunicationId & communication_id , u64 room_id ) ;
bool send_room_message ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpMatching2SendRoomMessageRequest * req ) ;
bool req_sign_infos ( u32 req_id , const std : : string & npid ) ;
2022-02-03 10:56:36 +01:00
bool req_ticket ( u32 req_id , const std : : string & service_id , const std : : vector < u8 > & cookie ) ;
2024-01-06 22:32:12 +01:00
bool send_message ( const message_data & msg_data , const std : : set < std : : string > & npids ) ;
2022-05-18 17:44:21 +02:00
bool get_board_infos ( u32 req_id , const SceNpCommunicationId & communication_id , SceNpScoreBoardId board_id ) ;
bool record_score ( u32 req_id , const SceNpCommunicationId & communication_id , SceNpScoreBoardId board_id , SceNpScorePcId char_id , SceNpScoreValue score , const std : : optional < std : : string > comment , const std : : optional < std : : vector < u8 > > score_data ) ;
bool get_score_range ( u32 req_id , const SceNpCommunicationId & communication_id , SceNpScoreBoardId board_id , u32 start_rank , u32 num_rank , bool with_comment , bool with_gameinfo ) ;
bool get_score_npid ( u32 req_id , const SceNpCommunicationId & communication_id , SceNpScoreBoardId board_id , const std : : vector < std : : pair < SceNpId , s32 > > & npids , bool with_comment , bool with_gameinfo ) ;
2022-09-28 10:57:19 +02:00
bool get_score_friend ( u32 req_id , const SceNpCommunicationId & communication_id , SceNpScoreBoardId board_id , bool include_self , bool with_comment , bool with_gameinfo , u32 max_entries ) ;
2022-10-01 14:40:16 +02:00
bool record_score_data ( u32 req_id , const SceNpCommunicationId & communication_id , SceNpScorePcId pc_id , SceNpScoreBoardId board_id , s64 score , const std : : vector < u8 > & score_data ) ;
bool get_score_data ( u32 req_id , const SceNpCommunicationId & communication_id , SceNpScorePcId pc_id , SceNpScoreBoardId board_id , const SceNpId & npid ) ;
2023-04-01 21:52:07 +02:00
bool tus_set_multislot_variable ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpOnlineId & targetNpId , vm : : cptr < SceNpTusSlotId > slotIdArray , vm : : cptr < s64 > variableArray , s32 arrayNum , bool vuser ) ;
bool tus_get_multislot_variable ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpOnlineId & targetNpId , vm : : cptr < SceNpTusSlotId > slotIdArray , s32 arrayNum , bool vuser ) ;
bool tus_get_multiuser_variable ( u32 req_id , const SceNpCommunicationId & communication_id , const std : : vector < SceNpOnlineId > & targetNpIdArray , SceNpTusSlotId slotId , s32 arrayNum , bool vuser ) ;
bool tus_get_friends_variable ( u32 req_id , const SceNpCommunicationId & communication_id , SceNpTusSlotId slotId , bool includeSelf , s32 sortType , s32 arrayNum ) ;
bool tus_add_and_get_variable ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpOnlineId & targetNpId , SceNpTusSlotId slotId , s64 inVariable , vm : : ptr < SceNpTusAddAndGetVariableOptParam > option , bool vuser ) ;
bool tus_try_and_set_variable ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpOnlineId & targetNpId , SceNpTusSlotId slotId , s32 opeType , s64 variable , vm : : ptr < SceNpTusTryAndSetVariableOptParam > option , bool vuser ) ;
bool tus_delete_multislot_variable ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpOnlineId & targetNpId , vm : : cptr < SceNpTusSlotId > slotIdArray , s32 arrayNum , bool vuser ) ;
bool tus_set_data ( u32 req_id , SceNpCommunicationId & communication_id , const SceNpOnlineId & targetNpId , SceNpTusSlotId slotId , const std : : vector < u8 > & tus_data , vm : : cptr < SceNpTusDataInfo > info , vm : : ptr < SceNpTusSetDataOptParam > option , bool vuser ) ;
bool tus_get_data ( u32 req_id , SceNpCommunicationId & communication_id , const SceNpOnlineId & targetNpId , SceNpTusSlotId slotId , bool vuser ) ;
bool tus_get_multislot_data_status ( u32 req_id , SceNpCommunicationId & communication_id , const SceNpOnlineId & targetNpId , vm : : cptr < SceNpTusSlotId > slotIdArray , s32 arrayNum , bool vuser ) ;
bool tus_get_multiuser_data_status ( u32 req_id , SceNpCommunicationId & communication_id , const std : : vector < SceNpOnlineId > & targetNpIdArray , SceNpTusSlotId slotId , s32 arrayNum , bool vuser ) ;
bool tus_get_friends_data_status ( u32 req_id , SceNpCommunicationId & communication_id , SceNpTusSlotId slotId , bool includeSelf , s32 sortType , s32 arrayNum ) ;
bool tus_delete_multislot_data ( u32 req_id , SceNpCommunicationId & communication_id , const SceNpOnlineId & targetNpId , vm : : cptr < SceNpTusSlotId > slotIdArray , s32 arrayNum , bool vuser ) ;
2024-01-05 09:43:26 +01:00
bool send_presence ( const SceNpCommunicationId & pr_com_id , const std : : string & pr_title , const std : : string & pr_status , const std : : string & pr_comment , const std : : vector < u8 > & pr_data ) ;
2024-05-14 00:12:50 +02:00
bool createjoin_room_gui ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpMatchingAttr * attr_list ) ;
bool join_room_gui ( u32 req_id , const SceNpRoomId & room_id ) ;
bool leave_room_gui ( u32 req_id , const SceNpRoomId & room_id ) ;
bool get_room_list_gui ( u32 req_id , const SceNpCommunicationId & communication_id , const SceNpMatchingReqRange * range , vm : : ptr < SceNpMatchingSearchCondition > cond , vm : : ptr < SceNpMatchingAttr > attr ) ;
bool set_room_search_flag_gui ( u32 req_id , const SceNpRoomId & room_id , bool stealth ) ;
bool get_room_search_flag_gui ( u32 req_id , const SceNpRoomId & room_id ) ;
bool set_room_info_gui ( u32 req_id , const SceNpRoomId & room_id , vm : : ptr < SceNpMatchingAttr > attrs ) ;
bool get_room_info_gui ( u32 req_id , const SceNpRoomId & room_id , vm : : ptr < SceNpMatchingAttr > attrs ) ;
bool quickmatch_gui ( u32 req_id , const SceNpCommunicationId & com_id , vm : : cptr < SceNpMatchingSearchCondition > cond , s32 available_num ) ;
bool searchjoin_gui ( u32 req_id , const SceNpCommunicationId & com_id , vm : : cptr < SceNpMatchingSearchCondition > cond , vm : : cptr < SceNpMatchingAttr > attr ) ;
2020-11-17 02:19:17 +01:00
2024-04-24 19:27:50 +02:00
const std : : string & get_online_name ( ) const ;
const std : : string & get_avatar_url ( ) const ;
2024-01-05 09:43:26 +01:00
2024-04-24 19:27:50 +02:00
u32 get_addr_sig ( ) const ;
u16 get_port_sig ( ) const ;
u32 get_addr_local ( ) const ;
void update_local_addr ( u32 addr ) ;
2020-11-17 02:19:17 +01:00
private :
bool get_reply ( u64 expected_id , std : : vector < u8 > & data ) ;
2024-05-14 00:12:50 +02:00
static void write_communication_id ( const SceNpCommunicationId & com_id , std : : vector < u8 > & data ) ;
2020-11-17 02:19:17 +01:00
std : : vector < u8 > forge_request ( u16 command , u64 packet_id , const std : : vector < u8 > & data ) const ;
bool forge_send ( u16 command , u64 packet_id , const std : : vector < u8 > & data ) ;
2024-01-05 09:43:26 +01:00
bool forge_request_with_com_id ( const flatbuffers : : FlatBufferBuilder & builder , const SceNpCommunicationId & com_id , CommandType command , u64 packet_id ) ;
2024-05-14 00:12:50 +02:00
bool forge_request_with_data ( const flatbuffers : : FlatBufferBuilder & builder , CommandType command , u64 packet_id ) ;
2020-11-17 02:19:17 +01:00
bool forge_send_reply ( u16 command , u64 packet_id , const std : : vector < u8 > & data , std : : vector < u8 > & reply_data ) ;
bool error_and_disconnect ( const std : : string & error_mgs ) ;
2024-01-05 09:43:26 +01:00
bool error_and_disconnect_notice ( const std : : string & error_msg ) ;
2020-11-17 02:19:17 +01:00
std : : string get_wolfssl_error ( WOLFSSL * wssl , int error ) const ;
private :
WOLFSSL_CTX * wssl_ctx = nullptr ;
WOLFSSL * read_wssl = nullptr ;
WOLFSSL * write_wssl = nullptr ;
atomic_t < bool > server_info_received = false ;
u32 received_version = 0 ;
// UDP Signaling related
steady_clock : : time_point last_ping_time { } , last_pong_time { } ;
sockaddr_in addr_rpcn { } ;
sockaddr_in addr_rpcn_udp { } ;
2023-07-11 20:40:30 +02:00
# ifdef _WIN32
SOCKET sockfd = 0 ;
# else
2020-11-17 02:19:17 +01:00
int sockfd = 0 ;
2023-07-11 20:40:30 +02:00
# endif
2020-11-17 02:19:17 +01:00
atomic_t < u64 > rpcn_request_counter = 0x100000001 ; // Counter used for commands whose result is not forwarded to NP handler(login, create, sendmessage, etc)
2024-01-05 09:43:26 +01:00
shared_mutex mutex_notifs , mutex_replies , mutex_replies_sync , mutex_presence_updates ;
2020-11-17 02:19:17 +01:00
std : : vector < std : : pair < u16 , std : : vector < u8 > > > notifications ; // notif type / data
std : : unordered_map < u32 , std : : pair < u16 , std : : vector < u8 > > > replies ; // req id / (command / data)
2023-04-01 21:52:07 +02:00
std : : unordered_map < u64 , std : : pair < u16 , std : : vector < u8 > > > replies_sync ; // same but for sync replies(see handle_input())
2024-01-05 09:43:26 +01:00
std : : unordered_map < std : : string , friend_online_data > presence_updates ; // npid / presence data
2020-11-17 02:19:17 +01:00
// Messages
struct message_cb_t
{
message_cb_func cb_func ;
void * cb_param ;
SceNpBasicMessageMainType type_filter ;
bool inc_bootable ;
bool operator < ( const message_cb_t & other ) const
{
2021-11-11 05:06:47 +01:00
const void * void_cb_func = reinterpret_cast < const void * > ( cb_func ) ;
const void * void_other_cb_func = reinterpret_cast < const void * > ( other . cb_func ) ;
return ( void_cb_func < void_other_cb_func ) | | ( ( ! ( void_other_cb_func < void_cb_func ) ) & & ( cb_param < other . cb_param ) ) ;
2020-11-17 02:19:17 +01:00
}
} ;
shared_mutex mutex_messages ;
std : : set < message_cb_t > message_cbs ;
std : : unordered_map < u64 , std : : shared_ptr < std : : pair < std : : string , message_data > > > messages ; // msg id / (sender / message)
std : : set < u64 > active_messages ; // msg id of messages that have not been discarded
std : : vector < u64 > new_messages ; // list of msg_id used to inform np_handler of new messages
u64 message_counter = 3 ; // id counter
std : : string online_name { } ;
std : : string avatar_url { } ;
s64 user_id = 0 ;
2024-01-05 09:43:26 +01:00
atomic_t < u32 > addr_sig = 0 ;
atomic_t < u32 > port_sig = 0 ; // Stores an u16, u32 is used for atomic_t::wait convenience
atomic_t < u32 > local_addr_sig = 0 ;
2023-03-07 10:36:28 +01:00
static constexpr int RPCN_TIMEOUT_INTERVAL = 50 ; // 50ms
static constexpr int RPCN_TIMEOUT = 10 ' 000 ; // 10s
2020-11-17 02:19:17 +01:00
} ;
} // namespace rpcn