From ea9dc9317d5421e014674f94c4e6460fd1a5531f Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Tue, 17 Nov 2020 02:19:17 +0100 Subject: [PATCH] rpcn v0.4.0 --- 3rdparty/flatbuffers | 2 +- 3rdparty/wolfssl/CMakeLists.txt | 2 +- 3rdparty/wolfssl/wolfssl.vcxproj | 4 +- rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp | 9 + rpcs3/Emu/Cell/Modules/sceNp.cpp | 235 +- rpcs3/Emu/Cell/Modules/sceNp.h | 40 +- rpcs3/Emu/Cell/Modules/sceNp2.cpp | 24 +- rpcs3/Emu/Cell/lv2/sys_net.cpp | 2 +- rpcs3/Emu/NP/fb_helpers.cpp | 149 +- rpcs3/Emu/NP/generated/np2_structs.fbs | 25 + .../Emu/NP/generated/np2_structs_generated.h | 1735 +++++++---- rpcs3/Emu/NP/np_handler.cpp | 581 ++-- rpcs3/Emu/NP/np_handler.h | 71 +- rpcs3/Emu/NP/rpcn_client.cpp | 2719 +++++++++++------ rpcs3/Emu/NP/rpcn_client.h | 404 ++- rpcs3/Emu/NP/signaling_handler.cpp | 26 + rpcs3/Emu/NP/signaling_handler.h | 7 + rpcs3/Emu/System.h | 2 + rpcs3/Emu/system_config_types.cpp | 4 +- rpcs3/Emu/system_config_types.h | 4 +- rpcs3/rpcs3.vcxproj | 34 + rpcs3/rpcs3.vcxproj.filters | 39 +- rpcs3/rpcs3qt/CMakeLists.txt | 2 + rpcs3/rpcs3qt/emu_settings.cpp | 4 +- rpcs3/rpcs3qt/game_compatibility.h | 16 - rpcs3/rpcs3qt/game_list_frame.cpp | 2 +- rpcs3/rpcs3qt/gui_application.cpp | 9 + rpcs3/rpcs3qt/qt_utils.h | 18 + rpcs3/rpcs3qt/recvmessage_dialog_frame.cpp | 125 + rpcs3/rpcs3qt/recvmessage_dialog_frame.h | 41 + rpcs3/rpcs3qt/rpcn_settings_dialog.cpp | 544 +++- rpcs3/rpcs3qt/rpcn_settings_dialog.h | 61 +- rpcs3/rpcs3qt/sendmessage_dialog_frame.cpp | 164 + rpcs3/rpcs3qt/sendmessage_dialog_frame.h | 37 + 34 files changed, 4907 insertions(+), 2234 deletions(-) create mode 100644 rpcs3/rpcs3qt/recvmessage_dialog_frame.cpp create mode 100644 rpcs3/rpcs3qt/recvmessage_dialog_frame.h create mode 100644 rpcs3/rpcs3qt/sendmessage_dialog_frame.cpp create mode 100644 rpcs3/rpcs3qt/sendmessage_dialog_frame.h diff --git a/3rdparty/flatbuffers b/3rdparty/flatbuffers index 9e7e8cbe9f..a9a295fecf 160000 --- a/3rdparty/flatbuffers +++ b/3rdparty/flatbuffers @@ -1 +1 @@ -Subproject commit 9e7e8cbe9f675123dd41b7c62868acad39188cae +Subproject commit a9a295fecf3fbd5a4f571f53b01f63202a3e2113 diff --git a/3rdparty/wolfssl/CMakeLists.txt b/3rdparty/wolfssl/CMakeLists.txt index 74a941d0b8..037628551b 100644 --- a/3rdparty/wolfssl/CMakeLists.txt +++ b/3rdparty/wolfssl/CMakeLists.txt @@ -7,7 +7,7 @@ else() # TODO(cjj19970505@live.cn) # OPENSSL_EXTRA, WOLFSSL_DES_ECB and HAVE_SNI are unconfigurable from CMake cache. # but they do have it in a TODO list (wolfssl/CMakeList, 1021) - add_compile_definitions(OPENSSL_EXTRA WOLFSSL_DES_ECB HAVE_SNI) + add_compile_definitions(OPENSSL_EXTRA WOLFSSL_DES_ECB HAVE_SNI HAVE_WRITE_DUP) set(WOLFSSL_TLS13 "no" CACHE INTERNAL "") set(WOLFSSL_SHA224 "yes" CACHE INTERNAL "") diff --git a/3rdparty/wolfssl/wolfssl.vcxproj b/3rdparty/wolfssl/wolfssl.vcxproj index f9cbcdcafa..34fe6f03b1 100644 --- a/3rdparty/wolfssl/wolfssl.vcxproj +++ b/3rdparty/wolfssl/wolfssl.vcxproj @@ -48,7 +48,7 @@ Disabled ./wolfssl;./wolfssl/IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_LIB;WOLFSSL_DES_ECB;HAVE_FFDHE_2048;TFM_TIMING_RESISTANT;ECC_TIMING_RESISTANT;WC_RSA_BLINDING;HAVE_AESGCM;WOLFSSL_SHA512;WOLFSSL_SHA384;NO_DSA;HAVE_ECC;TFM_ECC256;ECC_SHAMIR;NO_RC4;NO_HC128;NO_RABBIT;WOLFSSL_SHA224;WOLFSSL_SHA3;WOLFSSL_SHAKE256;HAVE_POLY1305;HAVE_ONE_TIME_AUTH;HAVE_CHACHA;HAVE_HASHDRBG;HAVE_TLS_EXTENSIONS;HAVE_SNI;HAVE_SUPPORTED_CURVES;HAVE_EXTENDED_MASTER;NO_RC4;HAVE_ENCRYPT_THEN_MAC;NO_PSK;NO_MD4;WC_NO_ASYNC_THREADING;OPENSSL_EXTRA;WOLFSSL_USER_SETTINGS;CYASSL_USER_SETTINGS;%(PreprocessorDefinitions) + WOLFSSL_LIB;WOLFSSL_DES_ECB;HAVE_FFDHE_2048;TFM_TIMING_RESISTANT;NO_DSA;TFM_ECC256;NO_RC4;NO_HC128;NO_RABBIT;WOLFSSL_SHA224;WOLFSSL_SHA3;WOLFSSL_SHAKE256;HAVE_POLY1305;HAVE_ONE_TIME_AUTH;HAVE_CHACHA;HAVE_HASHDRBG;HAVE_SNI;HAVE_ENCRYPT_THEN_MAC;NO_MD4;WC_NO_ASYNC_THREADING;CYASSL_USER_SETTINGS;WC_NO_HARDEN;HAVE_WRITE_DUP;WC_RSA_BLINDING;NO_MULTIBYTE_PRINT;OPENSSL_EXTRA;WOLFSSL_RIPEMD;NO_PSK;HAVE_EXTENDED_MASTER;WOLFSSL_SNIFFER;HAVE_AESGCM;WOLFSSL_SHA384;WOLFSSL_SHA512;HAVE_SUPPORTED_CURVES;HAVE_TLS_EXTENSIONS;HAVE_ECC;ECC_SHAMIR;ECC_TIMING_RESISTANT;%(PreprocessorDefinitions) EnableFastChecks @@ -62,7 +62,7 @@ MaxSpeed true ./wolfssl;./wolfssl/IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_LIB;WOLFSSL_DES_ECB;HAVE_FFDHE_2048;TFM_TIMING_RESISTANT;NO_DSA;TFM_ECC256;NO_RC4;NO_HC128;NO_RABBIT;WOLFSSL_SHA224;WOLFSSL_SHA3;WOLFSSL_SHAKE256;HAVE_POLY1305;HAVE_ONE_TIME_AUTH;HAVE_CHACHA;HAVE_HASHDRBG;HAVE_SNI;HAVE_ENCRYPT_THEN_MAC;NO_MD4;WC_NO_ASYNC_THREADING;WOLFSSL_USER_SETTINGS;CYASSL_USER_SETTINGS;WC_NO_HARDEN;%(PreprocessorDefinitions) + WOLFSSL_LIB;WOLFSSL_DES_ECB;HAVE_FFDHE_2048;TFM_TIMING_RESISTANT;NO_DSA;TFM_ECC256;NO_RC4;NO_HC128;NO_RABBIT;WOLFSSL_SHA224;WOLFSSL_SHA3;WOLFSSL_SHAKE256;HAVE_POLY1305;HAVE_ONE_TIME_AUTH;HAVE_CHACHA;HAVE_HASHDRBG;HAVE_SNI;HAVE_ENCRYPT_THEN_MAC;NO_MD4;WC_NO_ASYNC_THREADING;CYASSL_USER_SETTINGS;WC_NO_HARDEN;HAVE_WRITE_DUP;WC_RSA_BLINDING;NO_MULTIBYTE_PRINT;OPENSSL_EXTRA;WOLFSSL_RIPEMD;NO_PSK;HAVE_EXTENDED_MASTER;WOLFSSL_SNIFFER;HAVE_AESGCM;WOLFSSL_SHA384;WOLFSSL_SHA512;HAVE_SUPPORTED_CURVES;HAVE_TLS_EXTENSIONS;HAVE_ECC;ECC_SHAMIR;ECC_TIMING_RESISTANT;%(PreprocessorDefinitions) true diff --git a/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp b/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp index 728b3acbdd..4b876c653b 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp @@ -110,6 +110,15 @@ error_code cellSysutilAvc2StartVoiceDetection() error_code cellSysutilAvc2UnloadAsync() { cellSysutilAvc2.todo("cellSysutilAvc2UnloadAsync()"); + + if (avc2_cb) + { + sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 { + avc2_cb(cb_ppu, CELL_AVC2_EVENT_UNLOAD_SUCCEEDED, 0, avc2_cb_arg); + return 0; + }); + } + return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index 53bcf85620..c586ce3d7b 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -3,6 +3,8 @@ #include "Emu/system_utils.hpp" #include "Emu/VFS.h" #include "Emu/Cell/PPUModule.h" +#include "Emu/Io/interception.h" +#include "Utilities/StrUtil.h" #include "sysPrxForUser.h" #include "Emu/IdManager.h" @@ -396,6 +398,11 @@ void fmt_class_string::format(std::string& out, u64 arg) }); } +void message_data::print() const +{ + sceNp.notice("commId: %s, msgId: %d, mainType: %d, subType: %d, subject: %s, body: %s, data_size: %d", static_cast(commId.data), msgId, mainType, subType, subject, body, data.size()); +} + error_code sceNpInit(u32 poolsize, vm::ptr poolptr) { sceNp.warning("sceNpInit(poolsize=0x%x, poolptr=*0x%x)", poolsize, poolptr); @@ -629,7 +636,7 @@ error_code sceNpDrmProcessExitSpawn2(ppu_thread& ppu, vm::cptr klicensee, vm error_code sceNpBasicRegisterHandler(vm::cptr context, vm::ptr handler, vm::ptr arg) { - sceNp.warning("sceNpBasicRegisterHandler(context=*0x%x, handler=*0x%x, arg=*0x%x)", context, handler, arg); + sceNp.warning("sceNpBasicRegisterHandler(context=*0x%x(%s), handler=*0x%x, arg=*0x%x)", context, context ? static_cast(context->data) : "", handler, arg); auto& nph = g_fxo->get>(); @@ -638,13 +645,21 @@ error_code sceNpBasicRegisterHandler(vm::cptr context, vm: return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; } + if (nph.basic_handler.registered) + { + return SCE_NP_BASIC_ERROR_EXCEEDS_MAX; + } + if (!context || !handler) { return SCE_NP_BASIC_ERROR_INVALID_ARGUMENT; } - nph.basic_handler = handler; - nph.basic_handler_arg = arg; + memcpy(&nph.basic_handler.context, context.get_ptr(), sizeof(nph.basic_handler.context)); + nph.basic_handler.handler_func = handler; + nph.basic_handler.handler_arg = arg; + nph.basic_handler.registered = true; + nph.basic_handler.context_sensitive = false; return CELL_OK; } @@ -660,11 +675,22 @@ error_code sceNpBasicRegisterContextSensitiveHandler(vm::cptr to, vm::cptr data, u64 error_code sceNpBasicSendMessageGui(vm::cptr msg, sys_memory_container_t containerId) { - sceNp.todo("sceNpBasicSendMessageGui(msg=*0x%x, containerId=%d)", msg, containerId); + sceNp.warning("sceNpBasicSendMessageGui(msg=*0x%x, containerId=%d)", msg, containerId); + + if (msg) + { + sceNp.notice("sceNpBasicSendMessageGui: msgId: %d, mainType: %d, subType: %d, msgFeatures: %d, count: %d", msg->msgId, msg->mainType, msg->subType, msg->msgFeatures, msg->count); + for (u32 i = 0; i < msg->count; i++) + { + sceNp.trace("sceNpBasicSendMessageGui: NpId[%d] = %s", i, static_cast(&msg->npids[i].handle.data[0])); + } + sceNp.notice("sceNpBasicSendMessageGui: subject: %s", msg->subject); + sceNp.notice("sceNpBasicSendMessageGui: body: %s", msg->body); + } auto& nph = g_fxo->get>(); @@ -784,7 +828,13 @@ error_code sceNpBasicSendMessageGui(vm::cptr msg, sys_ return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; } - if (!msg || msg->count > SCE_NP_BASIC_SEND_MESSAGE_MAX_RECIPIENTS || msg->npids.handle.data[0] == '\0' || !(msg->msgFeatures & SCE_NP_BASIC_MESSAGE_FEATURES_ALL_FEATURES)) + if (!nph.basic_handler.registered) + { + return SCE_NP_BASIC_ERROR_NOT_REGISTERED; + } + + if (!msg || msg->count > SCE_NP_BASIC_SEND_MESSAGE_MAX_RECIPIENTS || (msg->msgFeatures & ~SCE_NP_BASIC_MESSAGE_FEATURES_ALL_FEATURES) || + msg->mainType > SCE_NP_BASIC_MESSAGE_MAIN_TYPE_URL_ATTACHMENT || msg->msgId != 0ull) { return SCE_NP_BASIC_ERROR_INVALID_ARGUMENT; } @@ -799,6 +849,82 @@ error_code sceNpBasicSendMessageGui(vm::cptr msg, sys_ return not_an_error(SCE_NP_BASIC_ERROR_NOT_CONNECTED); } + // Prepare message data + message_data msg_data = { + .commId = nph.basic_handler.context, + .msgId = msg->msgId, + .mainType = msg->mainType, + .subType = msg->subType, + .msgFeatures = msg->msgFeatures}; + std::set npids; + + for (u32 i = 0; i < msg->count; i++) + { + npids.insert(std::string(msg->npids[i].handle.data)); + } + + if (msg->subject) + { + msg_data.subject = std::string(msg->subject.get_ptr()); + } + + if (msg->body) + { + msg_data.body = std::string(msg->body.get_ptr()); + } + + if (msg->size) + { + msg_data.data.assign(msg->data.get_ptr(), msg->data.get_ptr() + msg->size); + } + + atomic_t wake_up = false; + bool result = false; + + input::SetIntercepted(true); + + Emu.CallAfter([=, &wake_up, &result, msg_data = std::move(msg_data), npids = std::move(npids)]() mutable + { + auto send_dlg = Emu.GetCallbacks().get_sendmessage_dialog(); + result = send_dlg->Exec(msg_data, npids); + wake_up = true; + wake_up.notify_one(); + }); + + while (!wake_up && !Emu.IsStopped()) + { + thread_ctrl::wait_on(wake_up, false); + } + + input::SetIntercepted(false); + + s32 callback_result = result ? 0 : -1; + s32 event = 0; + + switch (msg->mainType) + { + case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_DATA_ATTACHMENT: + event = SCE_NP_BASIC_EVENT_SEND_ATTACHMENT_RESULT; + break; + case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_GENERAL: + event = SCE_NP_BASIC_EVENT_SEND_MESSAGE_RESULT; + break; + case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_ADD_FRIEND: + event = SCE_NP_BASIC_EVENT_ADD_FRIEND_RESULT; + break; + case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_INVITE: + event = SCE_NP_BASIC_EVENT_SEND_INVITATION_RESULT; + break; + case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_CUSTOM_DATA: + event = SCE_NP_BASIC_EVENT_SEND_CUSTOM_DATA_RESULT; + break; + case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_URL_ATTACHMENT: + event = SCE_NP_BASIC_EVENT_SEND_URL_ATTACHMENT_RESULT; + break; + } + + nph.send_basic_event(event, callback_result, 0); + return CELL_OK; } @@ -845,9 +971,9 @@ error_code sceNpBasicRecvMessageAttachment(sys_memory_container_t containerId) return CELL_OK; } -error_code sceNpBasicRecvMessageAttachmentLoad(u32 id, vm::ptr buffer, vm::ptr size) +error_code sceNpBasicRecvMessageAttachmentLoad(u32 id, vm::ptr buffer, vm::ptr size) { - sceNp.todo("sceNpBasicRecvMessageAttachmentLoad(id=%d, buffer=*0x%x, size=*0x%x)", id, buffer, size); + sceNp.warning("sceNpBasicRecvMessageAttachmentLoad(id=%d, buffer=*0x%x, size=*0x%x)", id, buffer, size); auto& nph = g_fxo->get>(); @@ -856,22 +982,41 @@ error_code sceNpBasicRecvMessageAttachmentLoad(u32 id, vm::ptr buffer, vm: return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; } + if (!nph.basic_handler.registered) + { + return SCE_NP_BASIC_ERROR_NOT_REGISTERED; + } + if (!buffer || !size) { return SCE_NP_BASIC_ERROR_INVALID_ARGUMENT; } - if (id > SCE_NP_BASIC_SELECTED_MESSAGE_DATA) + const auto opt_msg = nph.get_message(id); + if (!opt_msg) { return SCE_NP_BASIC_ERROR_INVALID_DATA_ID; } + const auto msg_pair = opt_msg.value(); + const auto msg = msg_pair->second; + + const u32 orig_size = *size; + const u32 size_to_copy = std::min(static_cast(msg.data.size()), orig_size); + memcpy(buffer.get_ptr(), msg.data.data(), size_to_copy); + + *size = size_to_copy; + if (size_to_copy < msg.data.size()) + { + return SCE_NP_BASIC_ERROR_DATA_LOST; + } + return CELL_OK; } error_code sceNpBasicRecvMessageCustom(u16 mainType, u32 recvOptions, sys_memory_container_t containerId) { - sceNp.todo("sceNpBasicRecvMessageCustom(mainType=%d, recvOptions=%d, containerId=%d)", mainType, recvOptions, containerId); + sceNp.warning("sceNpBasicRecvMessageCustom(mainType=%d, recvOptions=%d, containerId=%d)", mainType, recvOptions, containerId); auto& nph = g_fxo->get>(); @@ -880,11 +1025,66 @@ error_code sceNpBasicRecvMessageCustom(u16 mainType, u32 recvOptions, sys_memory return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; } - if (!(recvOptions & SCE_NP_BASIC_RECV_MESSAGE_OPTIONS_ALL_OPTIONS)) + if (!nph.basic_handler.registered) + { + return SCE_NP_BASIC_ERROR_NOT_REGISTERED; + } + + if ((recvOptions & ~SCE_NP_BASIC_RECV_MESSAGE_OPTIONS_ALL_OPTIONS)) { return SCE_NP_BASIC_ERROR_INVALID_ARGUMENT; } + // TODO: SCE_NP_BASIC_ERROR_NOT_SUPPORTED + + atomic_t wake_up = false; + bool result = false; + + input::SetIntercepted(true); + + SceNpBasicMessageRecvAction recv_result; + u64 chosen_msg_id; + + Emu.CallAfter([=, &wake_up, &result, &recv_result, &chosen_msg_id]() + { + auto recv_dlg = Emu.GetCallbacks().get_recvmessage_dialog(); + result = recv_dlg->Exec(static_cast(mainType), static_cast(recvOptions), recv_result, chosen_msg_id); + wake_up = true; + wake_up.notify_one(); + }); + + while (!wake_up && !Emu.IsStopped()) + { + thread_ctrl::wait_on(wake_up, false); + } + + input::SetIntercepted(false); + + if (!result) + { + return SCE_NP_BASIC_ERROR_CANCEL; + } + + const auto msg_pair = nph.get_message(chosen_msg_id).value(); + const auto& msg = msg_pair->second; + + const u32 event_to_send = (mainType == SCE_NP_BASIC_MESSAGE_MAIN_TYPE_INVITE) ? SCE_NP_BASIC_EVENT_RECV_INVITATION_RESULT : SCE_NP_BASIC_EVENT_RECV_CUSTOM_DATA_RESULT; + np_handler::basic_event to_add{}; + to_add.event = event_to_send; + strcpy_trunc(to_add.from.userId.handle.data, msg_pair->first); + strcpy_trunc(to_add.from.name.data, msg_pair->first); + to_add.data.resize(sizeof(SceNpBasicExtendedAttachmentData)); + SceNpBasicExtendedAttachmentData* att_data = reinterpret_cast(to_add.data.data()); + att_data->flags = 0; // ? + att_data->msgId = chosen_msg_id; + att_data->data.id = static_cast(chosen_msg_id); + att_data->data.size = static_cast(msg.data.size()); + att_data->userAction = recv_result; + att_data->markedAsUsed = (recvOptions & SCE_NP_BASIC_RECV_MESSAGE_OPTIONS_PRESERVE) ? 0 : 1; + + nph.queue_basic_event(to_add); + nph.send_basic_event(event_to_send, 0, 0); + return CELL_OK; } @@ -972,8 +1172,7 @@ error_code sceNpBasicGetFriendListEntryCount(vm::ptr count) return SCE_NP_ERROR_ID_NOT_FOUND; } - // TODO: Check if there are any friends - *count = 0; + *count = nph.get_num_friends(); return CELL_OK; } @@ -1258,7 +1457,7 @@ error_code sceNpBasicGetBlockListEntryCount(vm::ptr count) } // TODO: Check if there are block lists - *count = 0; + *count = nph.get_num_blocks(); return CELL_OK; } @@ -1560,15 +1759,19 @@ error_code sceNpBasicGetEvent(vm::ptr event, vm::ptr from, v return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; } + if (!nph.basic_handler.registered) + { + return SCE_NP_BASIC_ERROR_NOT_REGISTERED; + } + if (!event || !from || !data || !size) { return SCE_NP_BASIC_ERROR_INVALID_ARGUMENT; } - // TODO: Check for other error and pass other events //*event = SCE_NP_BASIC_EVENT_OFFLINE; // This event only indicates a contact is offline, not the current status of the connection - return not_an_error(SCE_NP_BASIC_ERROR_NO_EVENT); + return nph.get_basic_event(event, from, data, size); } error_code sceNpCommerceCreateCtx(u32 version, vm::ptr npId, vm::ptr handler, vm::ptr arg, vm::ptr ctx_id) @@ -2913,10 +3116,10 @@ error_code sceNpManagerGetTicket(vm::ptr buffer, vm::ptr bufferSize) } const auto& ticket = nph.get_ticket(); + *bufferSize = static_cast(ticket.size()); if (!buffer) { - *bufferSize = static_cast(ticket.size()); return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/sceNp.h b/rpcs3/Emu/Cell/Modules/sceNp.h index 3e6282284d..f3d9e04289 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.h +++ b/rpcs3/Emu/Cell/Modules/sceNp.h @@ -3,6 +3,8 @@ #include "cellRtc.h" #include "Emu/Cell/ErrorCodes.h" +#include + error_code sceNpInit(u32 poolsize, vm::ptr poolptr); error_code sceNpTerm(); @@ -1022,11 +1024,11 @@ struct SceNpBasicMessageDetails be_t mainType; be_t subType; be_t msgFeatures; - const SceNpId npids; + vm::bptr npids; be_t count; - const s8 subject; - const s8 body; - const be_t data; + vm::bptr subject; + vm::bptr body; + vm::bptr data; be_t size; }; @@ -1359,3 +1361,33 @@ using SceNpMatchingGUIHandler = void(u32 ctx_id, s32 event, s32 error_code, vm:: using SceNpProfileResultHandler = s32(s32 result, vm::ptr arg); using SceNpManagerSubSigninCallback = void(s32 result, vm::ptr npId, vm::ptr cb_arg); + +// Used to pass data to UI/RPCN +struct message_data +{ + SceNpCommunicationId commId{}; + u64 msgId = 0; + u16 mainType = 0; + u16 subType = 0; + u32 msgFeatures = 0; + std::string subject; + std::string body; + std::vector data; + void print() const; +}; + +class SendMessageDialogBase +{ +public: + virtual ~SendMessageDialogBase() = default; + + virtual bool Exec(message_data& msg_data, std::set& npids) = 0; +}; + +class RecvMessageDialogBase +{ +public: + virtual ~RecvMessageDialogBase() = default; + + virtual bool Exec(SceNpBasicMessageMainType type, SceNpBasicMessageRecvOptions options, SceNpBasicMessageRecvAction& recv_result, u64& chosen_msg_id) = 0; +}; diff --git a/rpcs3/Emu/Cell/Modules/sceNp2.cpp b/rpcs3/Emu/Cell/Modules/sceNp2.cpp index 8cb1023be9..572ab74c67 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp2.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp2.cpp @@ -613,17 +613,23 @@ error_code sceNpMatching2SignalingGetConnectionInfo( switch (code) { - case 1: + case SCE_NP_SIGNALING_CONN_INFO_RTT: { connInfo->rtt = 20000; // HACK break; } - case 2: + case SCE_NP_SIGNALING_CONN_INFO_BANDWIDTH: { connInfo->bandwidth = 10'000'000; // 10 MBPS HACK break; } - case 5: + case SCE_NP_SIGNALING_CONN_INFO_PEER_NPID: + { + // TODO: need an update to whole signaling as matching2 signaling ignores npids atm + sceNp2.fatal("sceNpMatching2SignalingGetConnectionInfo Unimplemented SCE_NP_SIGNALING_CONN_INFO_PEER_NPID"); + break; + } + case SCE_NP_SIGNALING_CONN_INFO_PEER_ADDRESS: { auto& sigh = g_fxo->get>(); const auto si = sigh.get_sig2_infos(roomId, memberId); @@ -631,7 +637,15 @@ error_code sceNpMatching2SignalingGetConnectionInfo( connInfo->address.addr.np_s_addr = si.addr; break; } - case 6: + case SCE_NP_SIGNALING_CONN_INFO_MAPPED_ADDRESS: + { + auto& sigh = g_fxo->get>(); + const auto si = sigh.get_sig2_infos(roomId, memberId); + connInfo->address.port = std::bit_cast>(si.mapped_port); + connInfo->address.addr.np_s_addr = si.mapped_addr; + break; + } + case SCE_NP_SIGNALING_CONN_INFO_PACKET_LOSS: { connInfo->packet_loss = 1; // HACK break; @@ -1274,6 +1288,8 @@ error_code sceNpMatching2GetRoomDataExternalList( return res; } + *assignedReqId = nph.get_roomdata_external_list(ctxId, optParam, reqParam.get_ptr()); + return CELL_OK; } diff --git a/rpcs3/Emu/Cell/lv2/sys_net.cpp b/rpcs3/Emu/Cell/lv2/sys_net.cpp index 2a2daca998..bd1852d13b 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net.cpp @@ -978,7 +978,7 @@ struct network_thread WSADATA wsa_data; WSAStartup(MAKEWORD(2, 2), &wsa_data); #endif - if (g_cfg.net.psn_status == np_psn_status::rpcn) + if (g_cfg.net.psn_status == np_psn_status::psn_rpcn) list_p2p_ports.emplace(std::piecewise_construct, std::forward_as_tuple(3658), std::forward_as_tuple(3658)); } diff --git a/rpcs3/Emu/NP/fb_helpers.cpp b/rpcs3/Emu/NP/fb_helpers.cpp index 33f89b64c0..3911661b6c 100644 --- a/rpcs3/Emu/NP/fb_helpers.cpp +++ b/rpcs3/Emu/NP/fb_helpers.cpp @@ -55,7 +55,68 @@ void np_handler::UserInfo2_to_SceNpUserInfo2(const UserInfo2* user, SceNpUserInf } } -void np_handler::SearchRoomReponse_to_SceNpMatching2SearchRoomResponse(const SearchRoomResponse* resp, SceNpMatching2SearchRoomResponse* search_resp) +void np_handler::RoomDataExternal_to_SceNpMatching2RoomDataExternal(const RoomDataExternal* room, SceNpMatching2RoomDataExternal* room_info) +{ + room_info->serverId = room->serverId(); + room_info->worldId = room->worldId(); + room_info->publicSlotNum = room->publicSlotNum(); + room_info->privateSlotNum = room->privateSlotNum(); + room_info->lobbyId = room->lobbyId(); + room_info->roomId = room->roomId(); + room_info->openPublicSlotNum = room->openPublicSlotNum(); + room_info->maxSlot = room->maxSlot(); + room_info->openPrivateSlotNum = room->openPrivateSlotNum(); + room_info->curMemberNum = room->curMemberNum(); + room_info->passwordSlotMask = room->passwordSlotMask(); + + if (auto owner = room->owner()) + { + vm::ptr owner_info(allocate(sizeof(SceNpUserInfo2))); + UserInfo2_to_SceNpUserInfo2(owner, owner_info.get_ptr()); + room_info->owner = owner_info; + } + + if (room->roomGroup() && room->roomGroup()->size() != 0) + { + room_info->roomGroupNum = room->roomGroup()->size(); + vm::ptr group_info(allocate(sizeof(SceNpMatching2RoomGroup) * room_info->roomGroupNum)); + RoomGroup_to_SceNpMatching2RoomGroup(room->roomGroup(), group_info); + room_info->roomGroup = group_info; + } + + room_info->flagAttr = room->flagAttr(); + + if (room->roomSearchableIntAttrExternal() && room->roomSearchableIntAttrExternal()->size() != 0) + { + room_info->roomSearchableIntAttrExternalNum = room->roomSearchableIntAttrExternal()->size(); + vm::ptr intattr_info(allocate(sizeof(SceNpMatching2IntAttr) * room_info->roomSearchableIntAttrExternalNum)); + for (flatbuffers::uoffset_t a_index = 0; a_index < room->roomSearchableIntAttrExternal()->size(); a_index++) + { + auto int_attr = room->roomSearchableIntAttrExternal()->Get(a_index); + intattr_info[a_index].id = int_attr->id(); + intattr_info[a_index].num = int_attr->num(); + } + room_info->roomSearchableIntAttrExternal = intattr_info; + } + + if (room->roomSearchableBinAttrExternal() && room->roomSearchableBinAttrExternal()->size() != 0) + { + room_info->roomSearchableBinAttrExternalNum = room->roomSearchableBinAttrExternal()->size(); + vm::ptr binattr_info(allocate(sizeof(SceNpMatching2BinAttr) * room_info->roomSearchableBinAttrExternalNum)); + BinAttr_to_SceNpMatching2BinAttr(room->roomSearchableBinAttrExternal(), binattr_info); + room_info->roomSearchableBinAttrExternal = binattr_info; + } + + if (room->roomBinAttrExternal() && room->roomBinAttrExternal()->size() != 0) + { + room_info->roomBinAttrExternalNum = room->roomBinAttrExternal()->size(); + vm::ptr binattr_info(allocate(sizeof(SceNpMatching2BinAttr) * room_info->roomBinAttrExternalNum)); + BinAttr_to_SceNpMatching2BinAttr(room->roomBinAttrExternal(), binattr_info); + room_info->roomBinAttrExternal = binattr_info; + } +} + +void np_handler::SearchRoomResponse_to_SceNpMatching2SearchRoomResponse(const SearchRoomResponse* resp, SceNpMatching2SearchRoomResponse* search_resp) { search_resp->range.size = resp->size(); search_resp->range.startIndex = resp->startIndex(); @@ -66,7 +127,7 @@ void np_handler::SearchRoomReponse_to_SceNpMatching2SearchRoomResponse(const Sea vm::addr_t previous_next = vm::cast(0); for (flatbuffers::uoffset_t i = 0; i < resp->rooms()->size(); i++) { - auto room = resp->rooms()->Get(i); + auto* room = resp->rooms()->Get(i); vm::ptr room_info(allocate(sizeof(SceNpMatching2RoomDataExternal))); if (i > 0) @@ -81,62 +142,7 @@ void np_handler::SearchRoomReponse_to_SceNpMatching2SearchRoomResponse(const Sea previous_next = vm::cast(room_info.addr()); - room_info->serverId = room->serverId(); - room_info->worldId = room->worldId(); - room_info->publicSlotNum = room->publicSlotNum(); - room_info->privateSlotNum = room->privateSlotNum(); - room_info->lobbyId = room->lobbyId(); - room_info->roomId = room->roomId(); - room_info->openPublicSlotNum = room->openPublicSlotNum(); - room_info->maxSlot = room->maxSlot(); - room_info->openPrivateSlotNum = room->openPrivateSlotNum(); - room_info->curMemberNum = room->curMemberNum(); - room_info->passwordSlotMask = room->curMemberNum(); - if (auto owner = room->owner()) - { - vm::ptr owner_info(allocate(sizeof(SceNpUserInfo2))); - UserInfo2_to_SceNpUserInfo2(owner, owner_info.get_ptr()); - room_info->owner = owner_info; - } - - if (room->roomGroup() && room->roomGroup()->size() != 0) - { - room_info->roomGroupNum = room->roomGroup()->size(); - vm::ptr group_info(allocate(sizeof(SceNpMatching2RoomGroup) * room_info->roomGroupNum)); - RoomGroup_to_SceNpMatching2RoomGroup(room->roomGroup(), group_info); - room_info->roomGroup = group_info; - } - - room_info->flagAttr = room->flagAttr(); - - if (room->roomSearchableIntAttrExternal() && room->roomSearchableIntAttrExternal()->size() != 0) - { - room_info->roomSearchableIntAttrExternalNum = room->roomSearchableIntAttrExternal()->size(); - vm::ptr intattr_info(allocate(sizeof(SceNpMatching2IntAttr) * room_info->roomSearchableIntAttrExternalNum)); - for (flatbuffers::uoffset_t a_index = 0; a_index < room->roomSearchableIntAttrExternal()->size(); a_index++) - { - auto int_attr = room->roomSearchableIntAttrExternal()->Get(a_index); - intattr_info[a_index].id = int_attr->id(); - intattr_info[a_index].num = int_attr->num(); - } - room_info->roomSearchableIntAttrExternal = intattr_info; - } - - if (room->roomSearchableBinAttrExternal() && room->roomSearchableBinAttrExternal()->size() != 0) - { - room_info->roomSearchableBinAttrExternalNum = room->roomSearchableBinAttrExternal()->size(); - vm::ptr binattr_info(allocate(sizeof(SceNpMatching2BinAttr) * room_info->roomSearchableBinAttrExternalNum)); - BinAttr_to_SceNpMatching2BinAttr(room->roomSearchableBinAttrExternal(), binattr_info); - room_info->roomSearchableBinAttrExternal = binattr_info; - } - - if (room->roomBinAttrExternal() && room->roomBinAttrExternal()->size() != 0) - { - room_info->roomBinAttrExternalNum = room->roomBinAttrExternal()->size(); - vm::ptr binattr_info(allocate(sizeof(SceNpMatching2BinAttr) * room_info->roomBinAttrExternalNum)); - BinAttr_to_SceNpMatching2BinAttr(room->roomBinAttrExternal(), binattr_info); - room_info->roomBinAttrExternal = binattr_info; - } + RoomDataExternal_to_SceNpMatching2RoomDataExternal(room, room_info.get_ptr()); } } else @@ -145,6 +151,33 @@ void np_handler::SearchRoomReponse_to_SceNpMatching2SearchRoomResponse(const Sea } } +void np_handler::GetRoomDataExternalListResponse_to_SceNpMatching2GetRoomDataExternalListResponse(const GetRoomDataExternalListResponse* resp, SceNpMatching2GetRoomDataExternalListResponse* get_resp) +{ + get_resp->roomDataExternalNum = resp->rooms() ? resp->rooms()->size() : 0; + get_resp->roomDataExternal.set(0); + + vm::addr_t previous_next = vm::cast(0); + for (std::size_t i = 0; i < get_resp->roomDataExternalNum; i++) + { + auto* room = resp->rooms()->Get(i); + vm::ptr room_info(allocate(sizeof(SceNpMatching2RoomDataExternal))); + + if (i > 0) + { + vm::ptr prev_room(previous_next); + prev_room->next.set(room_info.addr()); + } + else + { + get_resp->roomDataExternal = room_info; + } + + previous_next = vm::cast(room_info.addr()); + + RoomDataExternal_to_SceNpMatching2RoomDataExternal(room, room_info.get_ptr()); + } +} + u16 np_handler::RoomDataInternal_to_SceNpMatching2RoomDataInternal(const RoomDataInternal* resp, SceNpMatching2RoomDataInternal* room_info, const SceNpId& npid) { u16 member_id = 0; diff --git a/rpcs3/Emu/NP/generated/np2_structs.fbs b/rpcs3/Emu/NP/generated/np2_structs.fbs index c1e016234e..c173b61419 100644 --- a/rpcs3/Emu/NP/generated/np2_structs.fbs +++ b/rpcs3/Emu/NP/generated/np2_structs.fbs @@ -167,6 +167,15 @@ table LeaveRoomRequest { optData:PresenceOptionData; } +table GetRoomDataExternalListRequest { + roomIds:[uint64]; + attrIds:[uint16]; +} + +table GetRoomDataExternalListResponse { + rooms:[RoomDataExternal]; +} + table SetRoomDataExternalRequest { roomId:uint64; roomSearchableIntAttrExternal:[IntAttr]; @@ -223,3 +232,19 @@ table RoomMessageInfo { srcMember:UserInfo2; msg:[uint8]; } + +table MessageDetails { + communicationId:string; + msgId:uint64; + mainType:uint16; + subType:uint16; + msgFeatures:uint32; + subject:string; + body:string; + data:[uint8]; +} + +table SendMessageRequest { + message:[uint8] (nested_flatbuffer: "MessageDetails"); + npids:[string]; +} diff --git a/rpcs3/Emu/NP/generated/np2_structs_generated.h b/rpcs3/Emu/NP/generated/np2_structs_generated.h index 826be310be..1e1cd8754e 100644 --- a/rpcs3/Emu/NP/generated/np2_structs_generated.h +++ b/rpcs3/Emu/NP/generated/np2_structs_generated.h @@ -7,75 +7,116 @@ #include "flatbuffers/flatbuffers.h" struct BinAttr; +struct BinAttrBuilder; struct IntAttr; +struct IntAttrBuilder; struct MemberBinAttrInternal; +struct MemberBinAttrInternalBuilder; struct BinAttrInternal; +struct BinAttrInternalBuilder; struct OptParam; +struct OptParamBuilder; struct GroupConfig; +struct GroupConfigBuilder; struct UserInfo2; +struct UserInfo2Builder; struct RoomMemberDataInternal; +struct RoomMemberDataInternalBuilder; struct RoomGroup; +struct RoomGroupBuilder; struct RoomDataInternal; +struct RoomDataInternalBuilder; struct RoomDataExternal; +struct RoomDataExternalBuilder; struct IntSearchFilter; +struct IntSearchFilterBuilder; struct BinSearchFilter; +struct BinSearchFilterBuilder; struct PresenceOptionData; +struct PresenceOptionDataBuilder; struct RoomGroupPasswordConfig; +struct RoomGroupPasswordConfigBuilder; struct SearchRoomRequest; +struct SearchRoomRequestBuilder; struct SearchRoomResponse; +struct SearchRoomResponseBuilder; struct CreateJoinRoomRequest; +struct CreateJoinRoomRequestBuilder; struct JoinRoomRequest; +struct JoinRoomRequestBuilder; struct LeaveRoomRequest; +struct LeaveRoomRequestBuilder; + +struct GetRoomDataExternalListRequest; +struct GetRoomDataExternalListRequestBuilder; + +struct GetRoomDataExternalListResponse; +struct GetRoomDataExternalListResponseBuilder; struct SetRoomDataExternalRequest; +struct SetRoomDataExternalRequestBuilder; struct SetRoomDataInternalRequest; +struct SetRoomDataInternalRequestBuilder; struct GetRoomDataInternalRequest; +struct GetRoomDataInternalRequestBuilder; struct RoomMemberUpdateInfo; +struct RoomMemberUpdateInfoBuilder; struct RoomUpdateInfo; +struct RoomUpdateInfoBuilder; struct GetPingInfoResponse; +struct GetPingInfoResponseBuilder; struct SendRoomMessageRequest; +struct SendRoomMessageRequestBuilder; struct RoomMessageInfo; +struct RoomMessageInfoBuilder; + +struct MessageDetails; +struct MessageDetailsBuilder; + +struct SendMessageRequest; +struct SendMessageRequestBuilder; struct BinAttr FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BinAttrBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_ID = 4, VT_DATA = 6 }; - u16 id() const { - return GetField(VT_ID, 0); + uint16_t id() const { + return GetField(VT_ID, 0); } - const flatbuffers::Vector *data() const { - return GetPointer *>(VT_DATA); + const flatbuffers::Vector *data() const { + return GetPointer *>(VT_DATA); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_ID) && + VerifyField(verifier, VT_ID) && VerifyOffset(verifier, VT_DATA) && verifier.VerifyVector(data()) && verifier.EndTable(); @@ -83,19 +124,19 @@ struct BinAttr FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct BinAttrBuilder { + typedef BinAttr Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_id(u16 id) { - fbb_.AddElement(BinAttr::VT_ID, id, 0); + void add_id(uint16_t id) { + fbb_.AddElement(BinAttr::VT_ID, id, 0); } - void add_data(flatbuffers::Offset> data) { + void add_data(flatbuffers::Offset> data) { fbb_.AddOffset(BinAttr::VT_DATA, data); } explicit BinAttrBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - BinAttrBuilder &operator=(const BinAttrBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -105,8 +146,8 @@ struct BinAttrBuilder { inline flatbuffers::Offset CreateBinAttr( flatbuffers::FlatBufferBuilder &_fbb, - u16 id = 0, - flatbuffers::Offset> data = 0) { + uint16_t id = 0, + flatbuffers::Offset> data = 0) { BinAttrBuilder builder_(_fbb); builder_.add_data(data); builder_.add_id(id); @@ -115,9 +156,9 @@ inline flatbuffers::Offset CreateBinAttr( inline flatbuffers::Offset CreateBinAttrDirect( flatbuffers::FlatBufferBuilder &_fbb, - u16 id = 0, - const std::vector *data = nullptr) { - auto data__ = data ? _fbb.CreateVector(*data) : 0; + uint16_t id = 0, + const std::vector *data = nullptr) { + auto data__ = data ? _fbb.CreateVector(*data) : 0; return CreateBinAttr( _fbb, id, @@ -125,38 +166,39 @@ inline flatbuffers::Offset CreateBinAttrDirect( } struct IntAttr FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef IntAttrBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_ID = 4, VT_NUM = 6 }; - u16 id() const { - return GetField(VT_ID, 0); + uint16_t id() const { + return GetField(VT_ID, 0); } - u32 num() const { - return GetField(VT_NUM, 0); + uint32_t num() const { + return GetField(VT_NUM, 0); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_ID) && - VerifyField(verifier, VT_NUM) && + VerifyField(verifier, VT_ID) && + VerifyField(verifier, VT_NUM) && verifier.EndTable(); } }; struct IntAttrBuilder { + typedef IntAttr Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_id(u16 id) { - fbb_.AddElement(IntAttr::VT_ID, id, 0); + void add_id(uint16_t id) { + fbb_.AddElement(IntAttr::VT_ID, id, 0); } - void add_num(u32 num) { - fbb_.AddElement(IntAttr::VT_NUM, num, 0); + void add_num(uint32_t num) { + fbb_.AddElement(IntAttr::VT_NUM, num, 0); } explicit IntAttrBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - IntAttrBuilder &operator=(const IntAttrBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -166,8 +208,8 @@ struct IntAttrBuilder { inline flatbuffers::Offset CreateIntAttr( flatbuffers::FlatBufferBuilder &_fbb, - u16 id = 0, - u32 num = 0) { + uint16_t id = 0, + uint32_t num = 0) { IntAttrBuilder builder_(_fbb); builder_.add_num(num); builder_.add_id(id); @@ -175,19 +217,20 @@ inline flatbuffers::Offset CreateIntAttr( } struct MemberBinAttrInternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef MemberBinAttrInternalBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_UPDATEDATE = 4, VT_DATA = 6 }; - u64 updateDate() const { - return GetField(VT_UPDATEDATE, 0); + uint64_t updateDate() const { + return GetField(VT_UPDATEDATE, 0); } const BinAttr *data() const { return GetPointer(VT_DATA); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_UPDATEDATE) && + VerifyField(verifier, VT_UPDATEDATE) && VerifyOffset(verifier, VT_DATA) && verifier.VerifyTable(data()) && verifier.EndTable(); @@ -195,10 +238,11 @@ struct MemberBinAttrInternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Tabl }; struct MemberBinAttrInternalBuilder { + typedef MemberBinAttrInternal Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_updateDate(u64 updateDate) { - fbb_.AddElement(MemberBinAttrInternal::VT_UPDATEDATE, updateDate, 0); + void add_updateDate(uint64_t updateDate) { + fbb_.AddElement(MemberBinAttrInternal::VT_UPDATEDATE, updateDate, 0); } void add_data(flatbuffers::Offset data) { fbb_.AddOffset(MemberBinAttrInternal::VT_DATA, data); @@ -207,7 +251,6 @@ struct MemberBinAttrInternalBuilder { : fbb_(_fbb) { start_ = fbb_.StartTable(); } - MemberBinAttrInternalBuilder &operator=(const MemberBinAttrInternalBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -217,7 +260,7 @@ struct MemberBinAttrInternalBuilder { inline flatbuffers::Offset CreateMemberBinAttrInternal( flatbuffers::FlatBufferBuilder &_fbb, - u64 updateDate = 0, + uint64_t updateDate = 0, flatbuffers::Offset data = 0) { MemberBinAttrInternalBuilder builder_(_fbb); builder_.add_updateDate(updateDate); @@ -226,24 +269,25 @@ inline flatbuffers::Offset CreateMemberBinAttrInternal( } struct BinAttrInternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BinAttrInternalBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_UPDATEDATE = 4, VT_UPDATEMEMBERID = 6, VT_DATA = 8 }; - u64 updateDate() const { - return GetField(VT_UPDATEDATE, 0); + uint64_t updateDate() const { + return GetField(VT_UPDATEDATE, 0); } - u16 updateMemberId() const { - return GetField(VT_UPDATEMEMBERID, 0); + uint16_t updateMemberId() const { + return GetField(VT_UPDATEMEMBERID, 0); } const BinAttr *data() const { return GetPointer(VT_DATA); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_UPDATEDATE) && - VerifyField(verifier, VT_UPDATEMEMBERID) && + VerifyField(verifier, VT_UPDATEDATE) && + VerifyField(verifier, VT_UPDATEMEMBERID) && VerifyOffset(verifier, VT_DATA) && verifier.VerifyTable(data()) && verifier.EndTable(); @@ -251,13 +295,14 @@ struct BinAttrInternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct BinAttrInternalBuilder { + typedef BinAttrInternal Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_updateDate(u64 updateDate) { - fbb_.AddElement(BinAttrInternal::VT_UPDATEDATE, updateDate, 0); + void add_updateDate(uint64_t updateDate) { + fbb_.AddElement(BinAttrInternal::VT_UPDATEDATE, updateDate, 0); } - void add_updateMemberId(u16 updateMemberId) { - fbb_.AddElement(BinAttrInternal::VT_UPDATEMEMBERID, updateMemberId, 0); + void add_updateMemberId(uint16_t updateMemberId) { + fbb_.AddElement(BinAttrInternal::VT_UPDATEMEMBERID, updateMemberId, 0); } void add_data(flatbuffers::Offset data) { fbb_.AddOffset(BinAttrInternal::VT_DATA, data); @@ -266,7 +311,6 @@ struct BinAttrInternalBuilder { : fbb_(_fbb) { start_ = fbb_.StartTable(); } - BinAttrInternalBuilder &operator=(const BinAttrInternalBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -276,8 +320,8 @@ struct BinAttrInternalBuilder { inline flatbuffers::Offset CreateBinAttrInternal( flatbuffers::FlatBufferBuilder &_fbb, - u64 updateDate = 0, - u16 updateMemberId = 0, + uint64_t updateDate = 0, + uint16_t updateMemberId = 0, flatbuffers::Offset data = 0) { BinAttrInternalBuilder builder_(_fbb); builder_.add_updateDate(updateDate); @@ -287,46 +331,47 @@ inline flatbuffers::Offset CreateBinAttrInternal( } struct OptParam FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef OptParamBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_TYPE = 4, VT_FLAG = 6, VT_HUBMEMBERID = 8 }; - u8 type() const { - return GetField(VT_TYPE, 0); + uint8_t type() const { + return GetField(VT_TYPE, 0); } - u8 flag() const { - return GetField(VT_FLAG, 0); + uint8_t flag() const { + return GetField(VT_FLAG, 0); } - u16 hubMemberId() const { - return GetField(VT_HUBMEMBERID, 0); + uint16_t hubMemberId() const { + return GetField(VT_HUBMEMBERID, 0); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_TYPE) && - VerifyField(verifier, VT_FLAG) && - VerifyField(verifier, VT_HUBMEMBERID) && + VerifyField(verifier, VT_TYPE) && + VerifyField(verifier, VT_FLAG) && + VerifyField(verifier, VT_HUBMEMBERID) && verifier.EndTable(); } }; struct OptParamBuilder { + typedef OptParam Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_type(u8 type) { - fbb_.AddElement(OptParam::VT_TYPE, type, 0); + void add_type(uint8_t type) { + fbb_.AddElement(OptParam::VT_TYPE, type, 0); } - void add_flag(u8 flag) { - fbb_.AddElement(OptParam::VT_FLAG, flag, 0); + void add_flag(uint8_t flag) { + fbb_.AddElement(OptParam::VT_FLAG, flag, 0); } - void add_hubMemberId(u16 hubMemberId) { - fbb_.AddElement(OptParam::VT_HUBMEMBERID, hubMemberId, 0); + void add_hubMemberId(uint16_t hubMemberId) { + fbb_.AddElement(OptParam::VT_HUBMEMBERID, hubMemberId, 0); } explicit OptParamBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - OptParamBuilder &operator=(const OptParamBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -336,9 +381,9 @@ struct OptParamBuilder { inline flatbuffers::Offset CreateOptParam( flatbuffers::FlatBufferBuilder &_fbb, - u8 type = 0, - u8 flag = 0, - u16 hubMemberId = 0) { + uint8_t type = 0, + uint8_t flag = 0, + uint16_t hubMemberId = 0) { OptParamBuilder builder_(_fbb); builder_.add_hubMemberId(hubMemberId); builder_.add_flag(flag); @@ -347,55 +392,56 @@ inline flatbuffers::Offset CreateOptParam( } struct GroupConfig FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef GroupConfigBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_SLOTNUM = 4, VT_WITHLABEL = 6, VT_LABEL = 8, VT_WITHPASSWORD = 10 }; - u32 slotNum() const { - return GetField(VT_SLOTNUM, 0); + uint32_t slotNum() const { + return GetField(VT_SLOTNUM, 0); } bool withLabel() const { - return GetField(VT_WITHLABEL, 0) != 0; + return GetField(VT_WITHLABEL, 0) != 0; } - const flatbuffers::Vector *label() const { - return GetPointer *>(VT_LABEL); + const flatbuffers::Vector *label() const { + return GetPointer *>(VT_LABEL); } bool withPassword() const { - return GetField(VT_WITHPASSWORD, 0) != 0; + return GetField(VT_WITHPASSWORD, 0) != 0; } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_SLOTNUM) && - VerifyField(verifier, VT_WITHLABEL) && + VerifyField(verifier, VT_SLOTNUM) && + VerifyField(verifier, VT_WITHLABEL) && VerifyOffset(verifier, VT_LABEL) && verifier.VerifyVector(label()) && - VerifyField(verifier, VT_WITHPASSWORD) && + VerifyField(verifier, VT_WITHPASSWORD) && verifier.EndTable(); } }; struct GroupConfigBuilder { + typedef GroupConfig Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_slotNum(u32 slotNum) { - fbb_.AddElement(GroupConfig::VT_SLOTNUM, slotNum, 0); + void add_slotNum(uint32_t slotNum) { + fbb_.AddElement(GroupConfig::VT_SLOTNUM, slotNum, 0); } void add_withLabel(bool withLabel) { - fbb_.AddElement(GroupConfig::VT_WITHLABEL, static_cast(withLabel), 0); + fbb_.AddElement(GroupConfig::VT_WITHLABEL, static_cast(withLabel), 0); } - void add_label(flatbuffers::Offset> label) { + void add_label(flatbuffers::Offset> label) { fbb_.AddOffset(GroupConfig::VT_LABEL, label); } void add_withPassword(bool withPassword) { - fbb_.AddElement(GroupConfig::VT_WITHPASSWORD, static_cast(withPassword), 0); + fbb_.AddElement(GroupConfig::VT_WITHPASSWORD, static_cast(withPassword), 0); } explicit GroupConfigBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - GroupConfigBuilder &operator=(const GroupConfigBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -405,9 +451,9 @@ struct GroupConfigBuilder { inline flatbuffers::Offset CreateGroupConfig( flatbuffers::FlatBufferBuilder &_fbb, - u32 slotNum = 0, + uint32_t slotNum = 0, bool withLabel = false, - flatbuffers::Offset> label = 0, + flatbuffers::Offset> label = 0, bool withPassword = false) { GroupConfigBuilder builder_(_fbb); builder_.add_label(label); @@ -419,11 +465,11 @@ inline flatbuffers::Offset CreateGroupConfig( inline flatbuffers::Offset CreateGroupConfigDirect( flatbuffers::FlatBufferBuilder &_fbb, - u32 slotNum = 0, + uint32_t slotNum = 0, bool withLabel = false, - const std::vector *label = nullptr, + const std::vector *label = nullptr, bool withPassword = false) { - auto label__ = label ? _fbb.CreateVector(*label) : 0; + auto label__ = label ? _fbb.CreateVector(*label) : 0; return CreateGroupConfig( _fbb, slotNum, @@ -433,6 +479,7 @@ inline flatbuffers::Offset CreateGroupConfigDirect( } struct UserInfo2 FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef UserInfo2Builder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_NPID = 4, VT_ONLINENAME = 6, @@ -460,6 +507,7 @@ struct UserInfo2 FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct UserInfo2Builder { + typedef UserInfo2 Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; void add_npId(flatbuffers::Offset npId) { @@ -475,7 +523,6 @@ struct UserInfo2Builder { : fbb_(_fbb) { start_ = fbb_.StartTable(); } - UserInfo2Builder &operator=(const UserInfo2Builder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -511,6 +558,7 @@ inline flatbuffers::Offset CreateUserInfo2Direct( } struct RoomMemberDataInternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RoomMemberDataInternalBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_USERINFO = 4, VT_JOINDATE = 6, @@ -524,23 +572,23 @@ struct RoomMemberDataInternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Tab const UserInfo2 *userInfo() const { return GetPointer(VT_USERINFO); } - u64 joinDate() const { - return GetField(VT_JOINDATE, 0); + uint64_t joinDate() const { + return GetField(VT_JOINDATE, 0); } - u16 memberId() const { - return GetField(VT_MEMBERID, 0); + uint16_t memberId() const { + return GetField(VT_MEMBERID, 0); } - u8 teamId() const { - return GetField(VT_TEAMID, 0); + uint8_t teamId() const { + return GetField(VT_TEAMID, 0); } - u8 roomGroup() const { - return GetField(VT_ROOMGROUP, 0); + uint8_t roomGroup() const { + return GetField(VT_ROOMGROUP, 0); } - u8 natType() const { - return GetField(VT_NATTYPE, 0); + uint8_t natType() const { + return GetField(VT_NATTYPE, 0); } - u32 flagAttr() const { - return GetField(VT_FLAGATTR, 0); + uint32_t flagAttr() const { + return GetField(VT_FLAGATTR, 0); } const flatbuffers::Vector> *roomMemberBinAttrInternal() const { return GetPointer> *>(VT_ROOMMEMBERBINATTRINTERNAL); @@ -549,12 +597,12 @@ struct RoomMemberDataInternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Tab return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_USERINFO) && verifier.VerifyTable(userInfo()) && - VerifyField(verifier, VT_JOINDATE) && - VerifyField(verifier, VT_MEMBERID) && - VerifyField(verifier, VT_TEAMID) && - VerifyField(verifier, VT_ROOMGROUP) && - VerifyField(verifier, VT_NATTYPE) && - VerifyField(verifier, VT_FLAGATTR) && + VerifyField(verifier, VT_JOINDATE) && + VerifyField(verifier, VT_MEMBERID) && + VerifyField(verifier, VT_TEAMID) && + VerifyField(verifier, VT_ROOMGROUP) && + VerifyField(verifier, VT_NATTYPE) && + VerifyField(verifier, VT_FLAGATTR) && VerifyOffset(verifier, VT_ROOMMEMBERBINATTRINTERNAL) && verifier.VerifyVector(roomMemberBinAttrInternal()) && verifier.VerifyVectorOfTables(roomMemberBinAttrInternal()) && @@ -563,28 +611,29 @@ struct RoomMemberDataInternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Tab }; struct RoomMemberDataInternalBuilder { + typedef RoomMemberDataInternal Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; void add_userInfo(flatbuffers::Offset userInfo) { fbb_.AddOffset(RoomMemberDataInternal::VT_USERINFO, userInfo); } - void add_joinDate(u64 joinDate) { - fbb_.AddElement(RoomMemberDataInternal::VT_JOINDATE, joinDate, 0); + void add_joinDate(uint64_t joinDate) { + fbb_.AddElement(RoomMemberDataInternal::VT_JOINDATE, joinDate, 0); } - void add_memberId(u16 memberId) { - fbb_.AddElement(RoomMemberDataInternal::VT_MEMBERID, memberId, 0); + void add_memberId(uint16_t memberId) { + fbb_.AddElement(RoomMemberDataInternal::VT_MEMBERID, memberId, 0); } - void add_teamId(u8 teamId) { - fbb_.AddElement(RoomMemberDataInternal::VT_TEAMID, teamId, 0); + void add_teamId(uint8_t teamId) { + fbb_.AddElement(RoomMemberDataInternal::VT_TEAMID, teamId, 0); } - void add_roomGroup(u8 roomGroup) { - fbb_.AddElement(RoomMemberDataInternal::VT_ROOMGROUP, roomGroup, 0); + void add_roomGroup(uint8_t roomGroup) { + fbb_.AddElement(RoomMemberDataInternal::VT_ROOMGROUP, roomGroup, 0); } - void add_natType(u8 natType) { - fbb_.AddElement(RoomMemberDataInternal::VT_NATTYPE, natType, 0); + void add_natType(uint8_t natType) { + fbb_.AddElement(RoomMemberDataInternal::VT_NATTYPE, natType, 0); } - void add_flagAttr(u32 flagAttr) { - fbb_.AddElement(RoomMemberDataInternal::VT_FLAGATTR, flagAttr, 0); + void add_flagAttr(uint32_t flagAttr) { + fbb_.AddElement(RoomMemberDataInternal::VT_FLAGATTR, flagAttr, 0); } void add_roomMemberBinAttrInternal(flatbuffers::Offset>> roomMemberBinAttrInternal) { fbb_.AddOffset(RoomMemberDataInternal::VT_ROOMMEMBERBINATTRINTERNAL, roomMemberBinAttrInternal); @@ -593,7 +642,6 @@ struct RoomMemberDataInternalBuilder { : fbb_(_fbb) { start_ = fbb_.StartTable(); } - RoomMemberDataInternalBuilder &operator=(const RoomMemberDataInternalBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -604,12 +652,12 @@ struct RoomMemberDataInternalBuilder { inline flatbuffers::Offset CreateRoomMemberDataInternal( flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::Offset userInfo = 0, - u64 joinDate = 0, - u16 memberId = 0, - u8 teamId = 0, - u8 roomGroup = 0, - u8 natType = 0, - u32 flagAttr = 0, + uint64_t joinDate = 0, + uint16_t memberId = 0, + uint8_t teamId = 0, + uint8_t roomGroup = 0, + uint8_t natType = 0, + uint32_t flagAttr = 0, flatbuffers::Offset>> roomMemberBinAttrInternal = 0) { RoomMemberDataInternalBuilder builder_(_fbb); builder_.add_joinDate(joinDate); @@ -626,12 +674,12 @@ inline flatbuffers::Offset CreateRoomMemberDataInternal( inline flatbuffers::Offset CreateRoomMemberDataInternalDirect( flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::Offset userInfo = 0, - u64 joinDate = 0, - u16 memberId = 0, - u8 teamId = 0, - u8 roomGroup = 0, - u8 natType = 0, - u32 flagAttr = 0, + uint64_t joinDate = 0, + uint16_t memberId = 0, + uint8_t teamId = 0, + uint8_t roomGroup = 0, + uint8_t natType = 0, + uint32_t flagAttr = 0, const std::vector> *roomMemberBinAttrInternal = nullptr) { auto roomMemberBinAttrInternal__ = roomMemberBinAttrInternal ? _fbb.CreateVector>(*roomMemberBinAttrInternal) : 0; return CreateRoomMemberDataInternal( @@ -647,6 +695,7 @@ inline flatbuffers::Offset CreateRoomMemberDataInternalD } struct RoomGroup FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RoomGroupBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_GROUPID = 4, VT_WITHPASSWORD = 6, @@ -655,63 +704,63 @@ struct RoomGroup FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_SLOTNUM = 12, VT_CURGROUPMEMBERNUM = 14 }; - u8 groupId() const { - return GetField(VT_GROUPID, 0); + uint8_t groupId() const { + return GetField(VT_GROUPID, 0); } bool withPassword() const { - return GetField(VT_WITHPASSWORD, 0) != 0; + return GetField(VT_WITHPASSWORD, 0) != 0; } bool withLabel() const { - return GetField(VT_WITHLABEL, 0) != 0; + return GetField(VT_WITHLABEL, 0) != 0; } - const flatbuffers::Vector *label() const { - return GetPointer *>(VT_LABEL); + const flatbuffers::Vector *label() const { + return GetPointer *>(VT_LABEL); } - u32 slotNum() const { - return GetField(VT_SLOTNUM, 0); + uint32_t slotNum() const { + return GetField(VT_SLOTNUM, 0); } - u32 curGroupMemberNum() const { - return GetField(VT_CURGROUPMEMBERNUM, 0); + uint32_t curGroupMemberNum() const { + return GetField(VT_CURGROUPMEMBERNUM, 0); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_GROUPID) && - VerifyField(verifier, VT_WITHPASSWORD) && - VerifyField(verifier, VT_WITHLABEL) && + VerifyField(verifier, VT_GROUPID) && + VerifyField(verifier, VT_WITHPASSWORD) && + VerifyField(verifier, VT_WITHLABEL) && VerifyOffset(verifier, VT_LABEL) && verifier.VerifyVector(label()) && - VerifyField(verifier, VT_SLOTNUM) && - VerifyField(verifier, VT_CURGROUPMEMBERNUM) && + VerifyField(verifier, VT_SLOTNUM) && + VerifyField(verifier, VT_CURGROUPMEMBERNUM) && verifier.EndTable(); } }; struct RoomGroupBuilder { + typedef RoomGroup Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_groupId(u8 groupId) { - fbb_.AddElement(RoomGroup::VT_GROUPID, groupId, 0); + void add_groupId(uint8_t groupId) { + fbb_.AddElement(RoomGroup::VT_GROUPID, groupId, 0); } void add_withPassword(bool withPassword) { - fbb_.AddElement(RoomGroup::VT_WITHPASSWORD, static_cast(withPassword), 0); + fbb_.AddElement(RoomGroup::VT_WITHPASSWORD, static_cast(withPassword), 0); } void add_withLabel(bool withLabel) { - fbb_.AddElement(RoomGroup::VT_WITHLABEL, static_cast(withLabel), 0); + fbb_.AddElement(RoomGroup::VT_WITHLABEL, static_cast(withLabel), 0); } - void add_label(flatbuffers::Offset> label) { + void add_label(flatbuffers::Offset> label) { fbb_.AddOffset(RoomGroup::VT_LABEL, label); } - void add_slotNum(u32 slotNum) { - fbb_.AddElement(RoomGroup::VT_SLOTNUM, slotNum, 0); + void add_slotNum(uint32_t slotNum) { + fbb_.AddElement(RoomGroup::VT_SLOTNUM, slotNum, 0); } - void add_curGroupMemberNum(u32 curGroupMemberNum) { - fbb_.AddElement(RoomGroup::VT_CURGROUPMEMBERNUM, curGroupMemberNum, 0); + void add_curGroupMemberNum(uint32_t curGroupMemberNum) { + fbb_.AddElement(RoomGroup::VT_CURGROUPMEMBERNUM, curGroupMemberNum, 0); } explicit RoomGroupBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - RoomGroupBuilder &operator=(const RoomGroupBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -721,12 +770,12 @@ struct RoomGroupBuilder { inline flatbuffers::Offset CreateRoomGroup( flatbuffers::FlatBufferBuilder &_fbb, - u8 groupId = 0, + uint8_t groupId = 0, bool withPassword = false, bool withLabel = false, - flatbuffers::Offset> label = 0, - u32 slotNum = 0, - u32 curGroupMemberNum = 0) { + flatbuffers::Offset> label = 0, + uint32_t slotNum = 0, + uint32_t curGroupMemberNum = 0) { RoomGroupBuilder builder_(_fbb); builder_.add_curGroupMemberNum(curGroupMemberNum); builder_.add_slotNum(slotNum); @@ -739,13 +788,13 @@ inline flatbuffers::Offset CreateRoomGroup( inline flatbuffers::Offset CreateRoomGroupDirect( flatbuffers::FlatBufferBuilder &_fbb, - u8 groupId = 0, + uint8_t groupId = 0, bool withPassword = false, bool withLabel = false, - const std::vector *label = nullptr, - u32 slotNum = 0, - u32 curGroupMemberNum = 0) { - auto label__ = label ? _fbb.CreateVector(*label) : 0; + const std::vector *label = nullptr, + uint32_t slotNum = 0, + uint32_t curGroupMemberNum = 0) { + auto label__ = label ? _fbb.CreateVector(*label) : 0; return CreateRoomGroup( _fbb, groupId, @@ -757,6 +806,7 @@ inline flatbuffers::Offset CreateRoomGroupDirect( } struct RoomDataInternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RoomDataInternalBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_SERVERID = 4, VT_WORLDID = 6, @@ -770,55 +820,55 @@ struct RoomDataInternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_FLAGATTR = 22, VT_ROOMBINATTRINTERNAL = 24 }; - u16 serverId() const { - return GetField(VT_SERVERID, 0); + uint16_t serverId() const { + return GetField(VT_SERVERID, 0); } - u32 worldId() const { - return GetField(VT_WORLDID, 0); + uint32_t worldId() const { + return GetField(VT_WORLDID, 0); } - u64 lobbyId() const { - return GetField(VT_LOBBYID, 0); + uint64_t lobbyId() const { + return GetField(VT_LOBBYID, 0); } - u64 roomId() const { - return GetField(VT_ROOMID, 0); + uint64_t roomId() const { + return GetField(VT_ROOMID, 0); } - u64 passwordSlotMask() const { - return GetField(VT_PASSWORDSLOTMASK, 0); + uint64_t passwordSlotMask() const { + return GetField(VT_PASSWORDSLOTMASK, 0); } - u32 maxSlot() const { - return GetField(VT_MAXSLOT, 0); + uint32_t maxSlot() const { + return GetField(VT_MAXSLOT, 0); } const flatbuffers::Vector> *memberList() const { return GetPointer> *>(VT_MEMBERLIST); } - u16 ownerId() const { - return GetField(VT_OWNERID, 0); + uint16_t ownerId() const { + return GetField(VT_OWNERID, 0); } const flatbuffers::Vector> *roomGroup() const { return GetPointer> *>(VT_ROOMGROUP); } - u32 flagAttr() const { - return GetField(VT_FLAGATTR, 0); + uint32_t flagAttr() const { + return GetField(VT_FLAGATTR, 0); } const flatbuffers::Vector> *roomBinAttrInternal() const { return GetPointer> *>(VT_ROOMBINATTRINTERNAL); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_SERVERID) && - VerifyField(verifier, VT_WORLDID) && - VerifyField(verifier, VT_LOBBYID) && - VerifyField(verifier, VT_ROOMID) && - VerifyField(verifier, VT_PASSWORDSLOTMASK) && - VerifyField(verifier, VT_MAXSLOT) && + VerifyField(verifier, VT_SERVERID) && + VerifyField(verifier, VT_WORLDID) && + VerifyField(verifier, VT_LOBBYID) && + VerifyField(verifier, VT_ROOMID) && + VerifyField(verifier, VT_PASSWORDSLOTMASK) && + VerifyField(verifier, VT_MAXSLOT) && VerifyOffset(verifier, VT_MEMBERLIST) && verifier.VerifyVector(memberList()) && verifier.VerifyVectorOfTables(memberList()) && - VerifyField(verifier, VT_OWNERID) && + VerifyField(verifier, VT_OWNERID) && VerifyOffset(verifier, VT_ROOMGROUP) && verifier.VerifyVector(roomGroup()) && verifier.VerifyVectorOfTables(roomGroup()) && - VerifyField(verifier, VT_FLAGATTR) && + VerifyField(verifier, VT_FLAGATTR) && VerifyOffset(verifier, VT_ROOMBINATTRINTERNAL) && verifier.VerifyVector(roomBinAttrInternal()) && verifier.VerifyVectorOfTables(roomBinAttrInternal()) && @@ -827,37 +877,38 @@ struct RoomDataInternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct RoomDataInternalBuilder { + typedef RoomDataInternal Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_serverId(u16 serverId) { - fbb_.AddElement(RoomDataInternal::VT_SERVERID, serverId, 0); + void add_serverId(uint16_t serverId) { + fbb_.AddElement(RoomDataInternal::VT_SERVERID, serverId, 0); } - void add_worldId(u32 worldId) { - fbb_.AddElement(RoomDataInternal::VT_WORLDID, worldId, 0); + void add_worldId(uint32_t worldId) { + fbb_.AddElement(RoomDataInternal::VT_WORLDID, worldId, 0); } - void add_lobbyId(u64 lobbyId) { - fbb_.AddElement(RoomDataInternal::VT_LOBBYID, lobbyId, 0); + void add_lobbyId(uint64_t lobbyId) { + fbb_.AddElement(RoomDataInternal::VT_LOBBYID, lobbyId, 0); } - void add_roomId(u64 roomId) { - fbb_.AddElement(RoomDataInternal::VT_ROOMID, roomId, 0); + void add_roomId(uint64_t roomId) { + fbb_.AddElement(RoomDataInternal::VT_ROOMID, roomId, 0); } - void add_passwordSlotMask(u64 passwordSlotMask) { - fbb_.AddElement(RoomDataInternal::VT_PASSWORDSLOTMASK, passwordSlotMask, 0); + void add_passwordSlotMask(uint64_t passwordSlotMask) { + fbb_.AddElement(RoomDataInternal::VT_PASSWORDSLOTMASK, passwordSlotMask, 0); } - void add_maxSlot(u32 maxSlot) { - fbb_.AddElement(RoomDataInternal::VT_MAXSLOT, maxSlot, 0); + void add_maxSlot(uint32_t maxSlot) { + fbb_.AddElement(RoomDataInternal::VT_MAXSLOT, maxSlot, 0); } void add_memberList(flatbuffers::Offset>> memberList) { fbb_.AddOffset(RoomDataInternal::VT_MEMBERLIST, memberList); } - void add_ownerId(u16 ownerId) { - fbb_.AddElement(RoomDataInternal::VT_OWNERID, ownerId, 0); + void add_ownerId(uint16_t ownerId) { + fbb_.AddElement(RoomDataInternal::VT_OWNERID, ownerId, 0); } void add_roomGroup(flatbuffers::Offset>> roomGroup) { fbb_.AddOffset(RoomDataInternal::VT_ROOMGROUP, roomGroup); } - void add_flagAttr(u32 flagAttr) { - fbb_.AddElement(RoomDataInternal::VT_FLAGATTR, flagAttr, 0); + void add_flagAttr(uint32_t flagAttr) { + fbb_.AddElement(RoomDataInternal::VT_FLAGATTR, flagAttr, 0); } void add_roomBinAttrInternal(flatbuffers::Offset>> roomBinAttrInternal) { fbb_.AddOffset(RoomDataInternal::VT_ROOMBINATTRINTERNAL, roomBinAttrInternal); @@ -866,7 +917,6 @@ struct RoomDataInternalBuilder { : fbb_(_fbb) { start_ = fbb_.StartTable(); } - RoomDataInternalBuilder &operator=(const RoomDataInternalBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -876,16 +926,16 @@ struct RoomDataInternalBuilder { inline flatbuffers::Offset CreateRoomDataInternal( flatbuffers::FlatBufferBuilder &_fbb, - u16 serverId = 0, - u32 worldId = 0, - u64 lobbyId = 0, - u64 roomId = 0, - u64 passwordSlotMask = 0, - u32 maxSlot = 0, + uint16_t serverId = 0, + uint32_t worldId = 0, + uint64_t lobbyId = 0, + uint64_t roomId = 0, + uint64_t passwordSlotMask = 0, + uint32_t maxSlot = 0, flatbuffers::Offset>> memberList = 0, - u16 ownerId = 0, + uint16_t ownerId = 0, flatbuffers::Offset>> roomGroup = 0, - u32 flagAttr = 0, + uint32_t flagAttr = 0, flatbuffers::Offset>> roomBinAttrInternal = 0) { RoomDataInternalBuilder builder_(_fbb); builder_.add_passwordSlotMask(passwordSlotMask); @@ -904,16 +954,16 @@ inline flatbuffers::Offset CreateRoomDataInternal( inline flatbuffers::Offset CreateRoomDataInternalDirect( flatbuffers::FlatBufferBuilder &_fbb, - u16 serverId = 0, - u32 worldId = 0, - u64 lobbyId = 0, - u64 roomId = 0, - u64 passwordSlotMask = 0, - u32 maxSlot = 0, + uint16_t serverId = 0, + uint32_t worldId = 0, + uint64_t lobbyId = 0, + uint64_t roomId = 0, + uint64_t passwordSlotMask = 0, + uint32_t maxSlot = 0, const std::vector> *memberList = nullptr, - u16 ownerId = 0, + uint16_t ownerId = 0, const std::vector> *roomGroup = nullptr, - u32 flagAttr = 0, + uint32_t flagAttr = 0, const std::vector> *roomBinAttrInternal = nullptr) { auto memberList__ = memberList ? _fbb.CreateVector>(*memberList) : 0; auto roomGroup__ = roomGroup ? _fbb.CreateVector>(*roomGroup) : 0; @@ -934,6 +984,7 @@ inline flatbuffers::Offset CreateRoomDataInternalDirect( } struct RoomDataExternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RoomDataExternalBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_SERVERID = 4, VT_WORLDID = 6, @@ -953,38 +1004,38 @@ struct RoomDataExternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_ROOMSEARCHABLEBINATTREXTERNAL = 34, VT_ROOMBINATTREXTERNAL = 36 }; - u16 serverId() const { - return GetField(VT_SERVERID, 0); + uint16_t serverId() const { + return GetField(VT_SERVERID, 0); } - u32 worldId() const { - return GetField(VT_WORLDID, 0); + uint32_t worldId() const { + return GetField(VT_WORLDID, 0); } - u16 publicSlotNum() const { - return GetField(VT_PUBLICSLOTNUM, 0); + uint16_t publicSlotNum() const { + return GetField(VT_PUBLICSLOTNUM, 0); } - u16 privateSlotNum() const { - return GetField(VT_PRIVATESLOTNUM, 0); + uint16_t privateSlotNum() const { + return GetField(VT_PRIVATESLOTNUM, 0); } - u64 lobbyId() const { - return GetField(VT_LOBBYID, 0); + uint64_t lobbyId() const { + return GetField(VT_LOBBYID, 0); } - u64 roomId() const { - return GetField(VT_ROOMID, 0); + uint64_t roomId() const { + return GetField(VT_ROOMID, 0); } - u16 openPublicSlotNum() const { - return GetField(VT_OPENPUBLICSLOTNUM, 0); + uint16_t openPublicSlotNum() const { + return GetField(VT_OPENPUBLICSLOTNUM, 0); } - u16 maxSlot() const { - return GetField(VT_MAXSLOT, 0); + uint16_t maxSlot() const { + return GetField(VT_MAXSLOT, 0); } - u16 openPrivateSlotNum() const { - return GetField(VT_OPENPRIVATESLOTNUM, 0); + uint16_t openPrivateSlotNum() const { + return GetField(VT_OPENPRIVATESLOTNUM, 0); } - u16 curMemberNum() const { - return GetField(VT_CURMEMBERNUM, 0); + uint16_t curMemberNum() const { + return GetField(VT_CURMEMBERNUM, 0); } - u64 passwordSlotMask() const { - return GetField(VT_PASSWORDSLOTMASK, 0); + uint64_t passwordSlotMask() const { + return GetField(VT_PASSWORDSLOTMASK, 0); } const UserInfo2 *owner() const { return GetPointer(VT_OWNER); @@ -992,8 +1043,8 @@ struct RoomDataExternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::Vector> *roomGroup() const { return GetPointer> *>(VT_ROOMGROUP); } - u32 flagAttr() const { - return GetField(VT_FLAGATTR, 0); + uint32_t flagAttr() const { + return GetField(VT_FLAGATTR, 0); } const flatbuffers::Vector> *roomSearchableIntAttrExternal() const { return GetPointer> *>(VT_ROOMSEARCHABLEINTATTREXTERNAL); @@ -1006,23 +1057,23 @@ struct RoomDataExternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_SERVERID) && - VerifyField(verifier, VT_WORLDID) && - VerifyField(verifier, VT_PUBLICSLOTNUM) && - VerifyField(verifier, VT_PRIVATESLOTNUM) && - VerifyField(verifier, VT_LOBBYID) && - VerifyField(verifier, VT_ROOMID) && - VerifyField(verifier, VT_OPENPUBLICSLOTNUM) && - VerifyField(verifier, VT_MAXSLOT) && - VerifyField(verifier, VT_OPENPRIVATESLOTNUM) && - VerifyField(verifier, VT_CURMEMBERNUM) && - VerifyField(verifier, VT_PASSWORDSLOTMASK) && + VerifyField(verifier, VT_SERVERID) && + VerifyField(verifier, VT_WORLDID) && + VerifyField(verifier, VT_PUBLICSLOTNUM) && + VerifyField(verifier, VT_PRIVATESLOTNUM) && + VerifyField(verifier, VT_LOBBYID) && + VerifyField(verifier, VT_ROOMID) && + VerifyField(verifier, VT_OPENPUBLICSLOTNUM) && + VerifyField(verifier, VT_MAXSLOT) && + VerifyField(verifier, VT_OPENPRIVATESLOTNUM) && + VerifyField(verifier, VT_CURMEMBERNUM) && + VerifyField(verifier, VT_PASSWORDSLOTMASK) && VerifyOffset(verifier, VT_OWNER) && verifier.VerifyTable(owner()) && VerifyOffset(verifier, VT_ROOMGROUP) && verifier.VerifyVector(roomGroup()) && verifier.VerifyVectorOfTables(roomGroup()) && - VerifyField(verifier, VT_FLAGATTR) && + VerifyField(verifier, VT_FLAGATTR) && VerifyOffset(verifier, VT_ROOMSEARCHABLEINTATTREXTERNAL) && verifier.VerifyVector(roomSearchableIntAttrExternal()) && verifier.VerifyVectorOfTables(roomSearchableIntAttrExternal()) && @@ -1037,40 +1088,41 @@ struct RoomDataExternal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct RoomDataExternalBuilder { + typedef RoomDataExternal Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_serverId(u16 serverId) { - fbb_.AddElement(RoomDataExternal::VT_SERVERID, serverId, 0); + void add_serverId(uint16_t serverId) { + fbb_.AddElement(RoomDataExternal::VT_SERVERID, serverId, 0); } - void add_worldId(u32 worldId) { - fbb_.AddElement(RoomDataExternal::VT_WORLDID, worldId, 0); + void add_worldId(uint32_t worldId) { + fbb_.AddElement(RoomDataExternal::VT_WORLDID, worldId, 0); } - void add_publicSlotNum(u16 publicSlotNum) { - fbb_.AddElement(RoomDataExternal::VT_PUBLICSLOTNUM, publicSlotNum, 0); + void add_publicSlotNum(uint16_t publicSlotNum) { + fbb_.AddElement(RoomDataExternal::VT_PUBLICSLOTNUM, publicSlotNum, 0); } - void add_privateSlotNum(u16 privateSlotNum) { - fbb_.AddElement(RoomDataExternal::VT_PRIVATESLOTNUM, privateSlotNum, 0); + void add_privateSlotNum(uint16_t privateSlotNum) { + fbb_.AddElement(RoomDataExternal::VT_PRIVATESLOTNUM, privateSlotNum, 0); } - void add_lobbyId(u64 lobbyId) { - fbb_.AddElement(RoomDataExternal::VT_LOBBYID, lobbyId, 0); + void add_lobbyId(uint64_t lobbyId) { + fbb_.AddElement(RoomDataExternal::VT_LOBBYID, lobbyId, 0); } - void add_roomId(u64 roomId) { - fbb_.AddElement(RoomDataExternal::VT_ROOMID, roomId, 0); + void add_roomId(uint64_t roomId) { + fbb_.AddElement(RoomDataExternal::VT_ROOMID, roomId, 0); } - void add_openPublicSlotNum(u16 openPublicSlotNum) { - fbb_.AddElement(RoomDataExternal::VT_OPENPUBLICSLOTNUM, openPublicSlotNum, 0); + void add_openPublicSlotNum(uint16_t openPublicSlotNum) { + fbb_.AddElement(RoomDataExternal::VT_OPENPUBLICSLOTNUM, openPublicSlotNum, 0); } - void add_maxSlot(u16 maxSlot) { - fbb_.AddElement(RoomDataExternal::VT_MAXSLOT, maxSlot, 0); + void add_maxSlot(uint16_t maxSlot) { + fbb_.AddElement(RoomDataExternal::VT_MAXSLOT, maxSlot, 0); } - void add_openPrivateSlotNum(u16 openPrivateSlotNum) { - fbb_.AddElement(RoomDataExternal::VT_OPENPRIVATESLOTNUM, openPrivateSlotNum, 0); + void add_openPrivateSlotNum(uint16_t openPrivateSlotNum) { + fbb_.AddElement(RoomDataExternal::VT_OPENPRIVATESLOTNUM, openPrivateSlotNum, 0); } - void add_curMemberNum(u16 curMemberNum) { - fbb_.AddElement(RoomDataExternal::VT_CURMEMBERNUM, curMemberNum, 0); + void add_curMemberNum(uint16_t curMemberNum) { + fbb_.AddElement(RoomDataExternal::VT_CURMEMBERNUM, curMemberNum, 0); } - void add_passwordSlotMask(u64 passwordSlotMask) { - fbb_.AddElement(RoomDataExternal::VT_PASSWORDSLOTMASK, passwordSlotMask, 0); + void add_passwordSlotMask(uint64_t passwordSlotMask) { + fbb_.AddElement(RoomDataExternal::VT_PASSWORDSLOTMASK, passwordSlotMask, 0); } void add_owner(flatbuffers::Offset owner) { fbb_.AddOffset(RoomDataExternal::VT_OWNER, owner); @@ -1078,8 +1130,8 @@ struct RoomDataExternalBuilder { void add_roomGroup(flatbuffers::Offset>> roomGroup) { fbb_.AddOffset(RoomDataExternal::VT_ROOMGROUP, roomGroup); } - void add_flagAttr(u32 flagAttr) { - fbb_.AddElement(RoomDataExternal::VT_FLAGATTR, flagAttr, 0); + void add_flagAttr(uint32_t flagAttr) { + fbb_.AddElement(RoomDataExternal::VT_FLAGATTR, flagAttr, 0); } void add_roomSearchableIntAttrExternal(flatbuffers::Offset>> roomSearchableIntAttrExternal) { fbb_.AddOffset(RoomDataExternal::VT_ROOMSEARCHABLEINTATTREXTERNAL, roomSearchableIntAttrExternal); @@ -1094,7 +1146,6 @@ struct RoomDataExternalBuilder { : fbb_(_fbb) { start_ = fbb_.StartTable(); } - RoomDataExternalBuilder &operator=(const RoomDataExternalBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -1104,20 +1155,20 @@ struct RoomDataExternalBuilder { inline flatbuffers::Offset CreateRoomDataExternal( flatbuffers::FlatBufferBuilder &_fbb, - u16 serverId = 0, - u32 worldId = 0, - u16 publicSlotNum = 0, - u16 privateSlotNum = 0, - u64 lobbyId = 0, - u64 roomId = 0, - u16 openPublicSlotNum = 0, - u16 maxSlot = 0, - u16 openPrivateSlotNum = 0, - u16 curMemberNum = 0, - u64 passwordSlotMask = 0, + uint16_t serverId = 0, + uint32_t worldId = 0, + uint16_t publicSlotNum = 0, + uint16_t privateSlotNum = 0, + uint64_t lobbyId = 0, + uint64_t roomId = 0, + uint16_t openPublicSlotNum = 0, + uint16_t maxSlot = 0, + uint16_t openPrivateSlotNum = 0, + uint16_t curMemberNum = 0, + uint64_t passwordSlotMask = 0, flatbuffers::Offset owner = 0, flatbuffers::Offset>> roomGroup = 0, - u32 flagAttr = 0, + uint32_t flagAttr = 0, flatbuffers::Offset>> roomSearchableIntAttrExternal = 0, flatbuffers::Offset>> roomSearchableBinAttrExternal = 0, flatbuffers::Offset>> roomBinAttrExternal = 0) { @@ -1144,20 +1195,20 @@ inline flatbuffers::Offset CreateRoomDataExternal( inline flatbuffers::Offset CreateRoomDataExternalDirect( flatbuffers::FlatBufferBuilder &_fbb, - u16 serverId = 0, - u32 worldId = 0, - u16 publicSlotNum = 0, - u16 privateSlotNum = 0, - u64 lobbyId = 0, - u64 roomId = 0, - u16 openPublicSlotNum = 0, - u16 maxSlot = 0, - u16 openPrivateSlotNum = 0, - u16 curMemberNum = 0, - u64 passwordSlotMask = 0, + uint16_t serverId = 0, + uint32_t worldId = 0, + uint16_t publicSlotNum = 0, + uint16_t privateSlotNum = 0, + uint64_t lobbyId = 0, + uint64_t roomId = 0, + uint16_t openPublicSlotNum = 0, + uint16_t maxSlot = 0, + uint16_t openPrivateSlotNum = 0, + uint16_t curMemberNum = 0, + uint64_t passwordSlotMask = 0, flatbuffers::Offset owner = 0, const std::vector> *roomGroup = nullptr, - u32 flagAttr = 0, + uint32_t flagAttr = 0, const std::vector> *roomSearchableIntAttrExternal = nullptr, const std::vector> *roomSearchableBinAttrExternal = nullptr, const std::vector> *roomBinAttrExternal = nullptr) { @@ -1187,19 +1238,20 @@ inline flatbuffers::Offset CreateRoomDataExternalDirect( } struct IntSearchFilter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef IntSearchFilterBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_SEARCHOPERATOR = 4, VT_ATTR = 6 }; - u8 searchOperator() const { - return GetField(VT_SEARCHOPERATOR, 0); + uint8_t searchOperator() const { + return GetField(VT_SEARCHOPERATOR, 0); } const IntAttr *attr() const { return GetPointer(VT_ATTR); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_SEARCHOPERATOR) && + VerifyField(verifier, VT_SEARCHOPERATOR) && VerifyOffset(verifier, VT_ATTR) && verifier.VerifyTable(attr()) && verifier.EndTable(); @@ -1207,10 +1259,11 @@ struct IntSearchFilter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct IntSearchFilterBuilder { + typedef IntSearchFilter Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_searchOperator(u8 searchOperator) { - fbb_.AddElement(IntSearchFilter::VT_SEARCHOPERATOR, searchOperator, 0); + void add_searchOperator(uint8_t searchOperator) { + fbb_.AddElement(IntSearchFilter::VT_SEARCHOPERATOR, searchOperator, 0); } void add_attr(flatbuffers::Offset attr) { fbb_.AddOffset(IntSearchFilter::VT_ATTR, attr); @@ -1219,7 +1272,6 @@ struct IntSearchFilterBuilder { : fbb_(_fbb) { start_ = fbb_.StartTable(); } - IntSearchFilterBuilder &operator=(const IntSearchFilterBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -1229,7 +1281,7 @@ struct IntSearchFilterBuilder { inline flatbuffers::Offset CreateIntSearchFilter( flatbuffers::FlatBufferBuilder &_fbb, - u8 searchOperator = 0, + uint8_t searchOperator = 0, flatbuffers::Offset attr = 0) { IntSearchFilterBuilder builder_(_fbb); builder_.add_attr(attr); @@ -1238,19 +1290,20 @@ inline flatbuffers::Offset CreateIntSearchFilter( } struct BinSearchFilter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BinSearchFilterBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_SEARCHOPERATOR = 4, VT_ATTR = 6 }; - u8 searchOperator() const { - return GetField(VT_SEARCHOPERATOR, 0); + uint8_t searchOperator() const { + return GetField(VT_SEARCHOPERATOR, 0); } const BinAttr *attr() const { return GetPointer(VT_ATTR); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_SEARCHOPERATOR) && + VerifyField(verifier, VT_SEARCHOPERATOR) && VerifyOffset(verifier, VT_ATTR) && verifier.VerifyTable(attr()) && verifier.EndTable(); @@ -1258,10 +1311,11 @@ struct BinSearchFilter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct BinSearchFilterBuilder { + typedef BinSearchFilter Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_searchOperator(u8 searchOperator) { - fbb_.AddElement(BinSearchFilter::VT_SEARCHOPERATOR, searchOperator, 0); + void add_searchOperator(uint8_t searchOperator) { + fbb_.AddElement(BinSearchFilter::VT_SEARCHOPERATOR, searchOperator, 0); } void add_attr(flatbuffers::Offset attr) { fbb_.AddOffset(BinSearchFilter::VT_ATTR, attr); @@ -1270,7 +1324,6 @@ struct BinSearchFilterBuilder { : fbb_(_fbb) { start_ = fbb_.StartTable(); } - BinSearchFilterBuilder &operator=(const BinSearchFilterBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -1280,7 +1333,7 @@ struct BinSearchFilterBuilder { inline flatbuffers::Offset CreateBinSearchFilter( flatbuffers::FlatBufferBuilder &_fbb, - u8 searchOperator = 0, + uint8_t searchOperator = 0, flatbuffers::Offset attr = 0) { BinSearchFilterBuilder builder_(_fbb); builder_.add_attr(attr); @@ -1289,39 +1342,40 @@ inline flatbuffers::Offset CreateBinSearchFilter( } struct PresenceOptionData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef PresenceOptionDataBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_DATA = 4, VT_LEN = 6 }; - const flatbuffers::Vector *data() const { - return GetPointer *>(VT_DATA); + const flatbuffers::Vector *data() const { + return GetPointer *>(VT_DATA); } - u32 len() const { - return GetField(VT_LEN, 0); + uint32_t len() const { + return GetField(VT_LEN, 0); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_DATA) && verifier.VerifyVector(data()) && - VerifyField(verifier, VT_LEN) && + VerifyField(verifier, VT_LEN) && verifier.EndTable(); } }; struct PresenceOptionDataBuilder { + typedef PresenceOptionData Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_data(flatbuffers::Offset> data) { + void add_data(flatbuffers::Offset> data) { fbb_.AddOffset(PresenceOptionData::VT_DATA, data); } - void add_len(u32 len) { - fbb_.AddElement(PresenceOptionData::VT_LEN, len, 0); + void add_len(uint32_t len) { + fbb_.AddElement(PresenceOptionData::VT_LEN, len, 0); } explicit PresenceOptionDataBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - PresenceOptionDataBuilder &operator=(const PresenceOptionDataBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -1331,8 +1385,8 @@ struct PresenceOptionDataBuilder { inline flatbuffers::Offset CreatePresenceOptionData( flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset> data = 0, - u32 len = 0) { + flatbuffers::Offset> data = 0, + uint32_t len = 0) { PresenceOptionDataBuilder builder_(_fbb); builder_.add_len(len); builder_.add_data(data); @@ -1341,9 +1395,9 @@ inline flatbuffers::Offset CreatePresenceOptionData( inline flatbuffers::Offset CreatePresenceOptionDataDirect( flatbuffers::FlatBufferBuilder &_fbb, - const std::vector *data = nullptr, - u32 len = 0) { - auto data__ = data ? _fbb.CreateVector(*data) : 0; + const std::vector *data = nullptr, + uint32_t len = 0) { + auto data__ = data ? _fbb.CreateVector(*data) : 0; return CreatePresenceOptionData( _fbb, data__, @@ -1351,39 +1405,40 @@ inline flatbuffers::Offset CreatePresenceOptionDataDirect( } struct RoomGroupPasswordConfig FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RoomGroupPasswordConfigBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_GROUPID = 4, VT_WITHPASSWORD = 6 }; - const flatbuffers::Vector *groupId() const { - return GetPointer *>(VT_GROUPID); + const flatbuffers::Vector *groupId() const { + return GetPointer *>(VT_GROUPID); } bool withPassword() const { - return GetField(VT_WITHPASSWORD, 0) != 0; + return GetField(VT_WITHPASSWORD, 0) != 0; } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_GROUPID) && verifier.VerifyVector(groupId()) && - VerifyField(verifier, VT_WITHPASSWORD) && + VerifyField(verifier, VT_WITHPASSWORD) && verifier.EndTable(); } }; struct RoomGroupPasswordConfigBuilder { + typedef RoomGroupPasswordConfig Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_groupId(flatbuffers::Offset> groupId) { + void add_groupId(flatbuffers::Offset> groupId) { fbb_.AddOffset(RoomGroupPasswordConfig::VT_GROUPID, groupId); } void add_withPassword(bool withPassword) { - fbb_.AddElement(RoomGroupPasswordConfig::VT_WITHPASSWORD, static_cast(withPassword), 0); + fbb_.AddElement(RoomGroupPasswordConfig::VT_WITHPASSWORD, static_cast(withPassword), 0); } explicit RoomGroupPasswordConfigBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - RoomGroupPasswordConfigBuilder &operator=(const RoomGroupPasswordConfigBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -1393,7 +1448,7 @@ struct RoomGroupPasswordConfigBuilder { inline flatbuffers::Offset CreateRoomGroupPasswordConfig( flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset> groupId = 0, + flatbuffers::Offset> groupId = 0, bool withPassword = false) { RoomGroupPasswordConfigBuilder builder_(_fbb); builder_.add_groupId(groupId); @@ -1403,9 +1458,9 @@ inline flatbuffers::Offset CreateRoomGroupPasswordConfi inline flatbuffers::Offset CreateRoomGroupPasswordConfigDirect( flatbuffers::FlatBufferBuilder &_fbb, - const std::vector *groupId = nullptr, + const std::vector *groupId = nullptr, bool withPassword = false) { - auto groupId__ = groupId ? _fbb.CreateVector(*groupId) : 0; + auto groupId__ = groupId ? _fbb.CreateVector(*groupId) : 0; return CreateRoomGroupPasswordConfig( _fbb, groupId__, @@ -1413,6 +1468,7 @@ inline flatbuffers::Offset CreateRoomGroupPasswordConfi } struct SearchRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SearchRoomRequestBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_OPTION = 4, VT_WORLDID = 6, @@ -1425,26 +1481,26 @@ struct SearchRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_BINFILTER = 20, VT_ATTRID = 22 }; - s32 option() const { - return GetField(VT_OPTION, 0); + int32_t option() const { + return GetField(VT_OPTION, 0); } - u32 worldId() const { - return GetField(VT_WORLDID, 0); + uint32_t worldId() const { + return GetField(VT_WORLDID, 0); } - u64 lobbyId() const { - return GetField(VT_LOBBYID, 0); + uint64_t lobbyId() const { + return GetField(VT_LOBBYID, 0); } - u32 rangeFilter_startIndex() const { - return GetField(VT_RANGEFILTER_STARTINDEX, 0); + uint32_t rangeFilter_startIndex() const { + return GetField(VT_RANGEFILTER_STARTINDEX, 0); } - u32 rangeFilter_max() const { - return GetField(VT_RANGEFILTER_MAX, 0); + uint32_t rangeFilter_max() const { + return GetField(VT_RANGEFILTER_MAX, 0); } - u32 flagFilter() const { - return GetField(VT_FLAGFILTER, 0); + uint32_t flagFilter() const { + return GetField(VT_FLAGFILTER, 0); } - u32 flagAttr() const { - return GetField(VT_FLAGATTR, 0); + uint32_t flagAttr() const { + return GetField(VT_FLAGATTR, 0); } const flatbuffers::Vector> *intFilter() const { return GetPointer> *>(VT_INTFILTER); @@ -1452,18 +1508,18 @@ struct SearchRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::Vector> *binFilter() const { return GetPointer> *>(VT_BINFILTER); } - const flatbuffers::Vector *attrId() const { - return GetPointer *>(VT_ATTRID); + const flatbuffers::Vector *attrId() const { + return GetPointer *>(VT_ATTRID); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_OPTION) && - VerifyField(verifier, VT_WORLDID) && - VerifyField(verifier, VT_LOBBYID) && - VerifyField(verifier, VT_RANGEFILTER_STARTINDEX) && - VerifyField(verifier, VT_RANGEFILTER_MAX) && - VerifyField(verifier, VT_FLAGFILTER) && - VerifyField(verifier, VT_FLAGATTR) && + VerifyField(verifier, VT_OPTION) && + VerifyField(verifier, VT_WORLDID) && + VerifyField(verifier, VT_LOBBYID) && + VerifyField(verifier, VT_RANGEFILTER_STARTINDEX) && + VerifyField(verifier, VT_RANGEFILTER_MAX) && + VerifyField(verifier, VT_FLAGFILTER) && + VerifyField(verifier, VT_FLAGATTR) && VerifyOffset(verifier, VT_INTFILTER) && verifier.VerifyVector(intFilter()) && verifier.VerifyVectorOfTables(intFilter()) && @@ -1477,28 +1533,29 @@ struct SearchRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct SearchRoomRequestBuilder { + typedef SearchRoomRequest Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_option(s32 option) { - fbb_.AddElement(SearchRoomRequest::VT_OPTION, option, 0); + void add_option(int32_t option) { + fbb_.AddElement(SearchRoomRequest::VT_OPTION, option, 0); } - void add_worldId(u32 worldId) { - fbb_.AddElement(SearchRoomRequest::VT_WORLDID, worldId, 0); + void add_worldId(uint32_t worldId) { + fbb_.AddElement(SearchRoomRequest::VT_WORLDID, worldId, 0); } - void add_lobbyId(u64 lobbyId) { - fbb_.AddElement(SearchRoomRequest::VT_LOBBYID, lobbyId, 0); + void add_lobbyId(uint64_t lobbyId) { + fbb_.AddElement(SearchRoomRequest::VT_LOBBYID, lobbyId, 0); } - void add_rangeFilter_startIndex(u32 rangeFilter_startIndex) { - fbb_.AddElement(SearchRoomRequest::VT_RANGEFILTER_STARTINDEX, rangeFilter_startIndex, 0); + void add_rangeFilter_startIndex(uint32_t rangeFilter_startIndex) { + fbb_.AddElement(SearchRoomRequest::VT_RANGEFILTER_STARTINDEX, rangeFilter_startIndex, 0); } - void add_rangeFilter_max(u32 rangeFilter_max) { - fbb_.AddElement(SearchRoomRequest::VT_RANGEFILTER_MAX, rangeFilter_max, 0); + void add_rangeFilter_max(uint32_t rangeFilter_max) { + fbb_.AddElement(SearchRoomRequest::VT_RANGEFILTER_MAX, rangeFilter_max, 0); } - void add_flagFilter(u32 flagFilter) { - fbb_.AddElement(SearchRoomRequest::VT_FLAGFILTER, flagFilter, 0); + void add_flagFilter(uint32_t flagFilter) { + fbb_.AddElement(SearchRoomRequest::VT_FLAGFILTER, flagFilter, 0); } - void add_flagAttr(u32 flagAttr) { - fbb_.AddElement(SearchRoomRequest::VT_FLAGATTR, flagAttr, 0); + void add_flagAttr(uint32_t flagAttr) { + fbb_.AddElement(SearchRoomRequest::VT_FLAGATTR, flagAttr, 0); } void add_intFilter(flatbuffers::Offset>> intFilter) { fbb_.AddOffset(SearchRoomRequest::VT_INTFILTER, intFilter); @@ -1506,14 +1563,13 @@ struct SearchRoomRequestBuilder { void add_binFilter(flatbuffers::Offset>> binFilter) { fbb_.AddOffset(SearchRoomRequest::VT_BINFILTER, binFilter); } - void add_attrId(flatbuffers::Offset> attrId) { + void add_attrId(flatbuffers::Offset> attrId) { fbb_.AddOffset(SearchRoomRequest::VT_ATTRID, attrId); } explicit SearchRoomRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - SearchRoomRequestBuilder &operator=(const SearchRoomRequestBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -1523,16 +1579,16 @@ struct SearchRoomRequestBuilder { inline flatbuffers::Offset CreateSearchRoomRequest( flatbuffers::FlatBufferBuilder &_fbb, - s32 option = 0, - u32 worldId = 0, - u64 lobbyId = 0, - u32 rangeFilter_startIndex = 0, - u32 rangeFilter_max = 0, - u32 flagFilter = 0, - u32 flagAttr = 0, + int32_t option = 0, + uint32_t worldId = 0, + uint64_t lobbyId = 0, + uint32_t rangeFilter_startIndex = 0, + uint32_t rangeFilter_max = 0, + uint32_t flagFilter = 0, + uint32_t flagAttr = 0, flatbuffers::Offset>> intFilter = 0, flatbuffers::Offset>> binFilter = 0, - flatbuffers::Offset> attrId = 0) { + flatbuffers::Offset> attrId = 0) { SearchRoomRequestBuilder builder_(_fbb); builder_.add_lobbyId(lobbyId); builder_.add_attrId(attrId); @@ -1549,19 +1605,19 @@ inline flatbuffers::Offset CreateSearchRoomRequest( inline flatbuffers::Offset CreateSearchRoomRequestDirect( flatbuffers::FlatBufferBuilder &_fbb, - s32 option = 0, - u32 worldId = 0, - u64 lobbyId = 0, - u32 rangeFilter_startIndex = 0, - u32 rangeFilter_max = 0, - u32 flagFilter = 0, - u32 flagAttr = 0, + int32_t option = 0, + uint32_t worldId = 0, + uint64_t lobbyId = 0, + uint32_t rangeFilter_startIndex = 0, + uint32_t rangeFilter_max = 0, + uint32_t flagFilter = 0, + uint32_t flagAttr = 0, const std::vector> *intFilter = nullptr, const std::vector> *binFilter = nullptr, - const std::vector *attrId = nullptr) { + const std::vector *attrId = nullptr) { auto intFilter__ = intFilter ? _fbb.CreateVector>(*intFilter) : 0; auto binFilter__ = binFilter ? _fbb.CreateVector>(*binFilter) : 0; - auto attrId__ = attrId ? _fbb.CreateVector(*attrId) : 0; + auto attrId__ = attrId ? _fbb.CreateVector(*attrId) : 0; return CreateSearchRoomRequest( _fbb, option, @@ -1577,29 +1633,30 @@ inline flatbuffers::Offset CreateSearchRoomRequestDirect( } struct SearchRoomResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SearchRoomResponseBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_STARTINDEX = 4, VT_TOTAL = 6, VT_SIZE = 8, VT_ROOMS = 10 }; - u32 startIndex() const { - return GetField(VT_STARTINDEX, 0); + uint32_t startIndex() const { + return GetField(VT_STARTINDEX, 0); } - u32 total() const { - return GetField(VT_TOTAL, 0); + uint32_t total() const { + return GetField(VT_TOTAL, 0); } - u32 size() const { - return GetField(VT_SIZE, 0); + uint32_t size() const { + return GetField(VT_SIZE, 0); } const flatbuffers::Vector> *rooms() const { return GetPointer> *>(VT_ROOMS); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_STARTINDEX) && - VerifyField(verifier, VT_TOTAL) && - VerifyField(verifier, VT_SIZE) && + VerifyField(verifier, VT_STARTINDEX) && + VerifyField(verifier, VT_TOTAL) && + VerifyField(verifier, VT_SIZE) && VerifyOffset(verifier, VT_ROOMS) && verifier.VerifyVector(rooms()) && verifier.VerifyVectorOfTables(rooms()) && @@ -1608,16 +1665,17 @@ struct SearchRoomResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct SearchRoomResponseBuilder { + typedef SearchRoomResponse Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_startIndex(u32 startIndex) { - fbb_.AddElement(SearchRoomResponse::VT_STARTINDEX, startIndex, 0); + void add_startIndex(uint32_t startIndex) { + fbb_.AddElement(SearchRoomResponse::VT_STARTINDEX, startIndex, 0); } - void add_total(u32 total) { - fbb_.AddElement(SearchRoomResponse::VT_TOTAL, total, 0); + void add_total(uint32_t total) { + fbb_.AddElement(SearchRoomResponse::VT_TOTAL, total, 0); } - void add_size(u32 size) { - fbb_.AddElement(SearchRoomResponse::VT_SIZE, size, 0); + void add_size(uint32_t size) { + fbb_.AddElement(SearchRoomResponse::VT_SIZE, size, 0); } void add_rooms(flatbuffers::Offset>> rooms) { fbb_.AddOffset(SearchRoomResponse::VT_ROOMS, rooms); @@ -1626,7 +1684,6 @@ struct SearchRoomResponseBuilder { : fbb_(_fbb) { start_ = fbb_.StartTable(); } - SearchRoomResponseBuilder &operator=(const SearchRoomResponseBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -1636,9 +1693,9 @@ struct SearchRoomResponseBuilder { inline flatbuffers::Offset CreateSearchRoomResponse( flatbuffers::FlatBufferBuilder &_fbb, - u32 startIndex = 0, - u32 total = 0, - u32 size = 0, + uint32_t startIndex = 0, + uint32_t total = 0, + uint32_t size = 0, flatbuffers::Offset>> rooms = 0) { SearchRoomResponseBuilder builder_(_fbb); builder_.add_rooms(rooms); @@ -1650,9 +1707,9 @@ inline flatbuffers::Offset CreateSearchRoomResponse( inline flatbuffers::Offset CreateSearchRoomResponseDirect( flatbuffers::FlatBufferBuilder &_fbb, - u32 startIndex = 0, - u32 total = 0, - u32 size = 0, + uint32_t startIndex = 0, + uint32_t total = 0, + uint32_t size = 0, const std::vector> *rooms = nullptr) { auto rooms__ = rooms ? _fbb.CreateVector>(*rooms) : 0; return CreateSearchRoomResponse( @@ -1664,6 +1721,7 @@ inline flatbuffers::Offset CreateSearchRoomResponseDirect( } struct CreateJoinRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef CreateJoinRoomRequestBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_WORLDID = 4, VT_LOBBYID = 6, @@ -1683,17 +1741,17 @@ struct CreateJoinRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Tabl VT_TEAMID = 34, VT_SIGOPTPARAM = 36 }; - u32 worldId() const { - return GetField(VT_WORLDID, 0); + uint32_t worldId() const { + return GetField(VT_WORLDID, 0); } - u64 lobbyId() const { - return GetField(VT_LOBBYID, 0); + uint64_t lobbyId() const { + return GetField(VT_LOBBYID, 0); } - u32 maxSlot() const { - return GetField(VT_MAXSLOT, 0); + uint32_t maxSlot() const { + return GetField(VT_MAXSLOT, 0); } - u32 flagAttr() const { - return GetField(VT_FLAGATTR, 0); + uint32_t flagAttr() const { + return GetField(VT_FLAGATTR, 0); } const flatbuffers::Vector> *roomBinAttrInternal() const { return GetPointer> *>(VT_ROOMBINATTRINTERNAL); @@ -1707,14 +1765,14 @@ struct CreateJoinRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Tabl const flatbuffers::Vector> *roomBinAttrExternal() const { return GetPointer> *>(VT_ROOMBINATTREXTERNAL); } - const flatbuffers::Vector *roomPassword() const { - return GetPointer *>(VT_ROOMPASSWORD); + const flatbuffers::Vector *roomPassword() const { + return GetPointer *>(VT_ROOMPASSWORD); } const flatbuffers::Vector> *groupConfig() const { return GetPointer> *>(VT_GROUPCONFIG); } - u64 passwordSlotMask() const { - return GetField(VT_PASSWORDSLOTMASK, 0); + uint64_t passwordSlotMask() const { + return GetField(VT_PASSWORDSLOTMASK, 0); } const flatbuffers::Vector> *allowedUser() const { return GetPointer> *>(VT_ALLOWEDUSER); @@ -1722,24 +1780,24 @@ struct CreateJoinRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Tabl const flatbuffers::Vector> *blockedUser() const { return GetPointer> *>(VT_BLOCKEDUSER); } - const flatbuffers::Vector *joinRoomGroupLabel() const { - return GetPointer *>(VT_JOINROOMGROUPLABEL); + const flatbuffers::Vector *joinRoomGroupLabel() const { + return GetPointer *>(VT_JOINROOMGROUPLABEL); } const flatbuffers::Vector> *roomMemberBinAttrInternal() const { return GetPointer> *>(VT_ROOMMEMBERBINATTRINTERNAL); } - u8 teamId() const { - return GetField(VT_TEAMID, 0); + uint8_t teamId() const { + return GetField(VT_TEAMID, 0); } const OptParam *sigOptParam() const { return GetPointer(VT_SIGOPTPARAM); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_WORLDID) && - VerifyField(verifier, VT_LOBBYID) && - VerifyField(verifier, VT_MAXSLOT) && - VerifyField(verifier, VT_FLAGATTR) && + VerifyField(verifier, VT_WORLDID) && + VerifyField(verifier, VT_LOBBYID) && + VerifyField(verifier, VT_MAXSLOT) && + VerifyField(verifier, VT_FLAGATTR) && VerifyOffset(verifier, VT_ROOMBINATTRINTERNAL) && verifier.VerifyVector(roomBinAttrInternal()) && verifier.VerifyVectorOfTables(roomBinAttrInternal()) && @@ -1757,7 +1815,7 @@ struct CreateJoinRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Tabl VerifyOffset(verifier, VT_GROUPCONFIG) && verifier.VerifyVector(groupConfig()) && verifier.VerifyVectorOfTables(groupConfig()) && - VerifyField(verifier, VT_PASSWORDSLOTMASK) && + VerifyField(verifier, VT_PASSWORDSLOTMASK) && VerifyOffset(verifier, VT_ALLOWEDUSER) && verifier.VerifyVector(allowedUser()) && verifier.VerifyVectorOfStrings(allowedUser()) && @@ -1769,7 +1827,7 @@ struct CreateJoinRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Tabl VerifyOffset(verifier, VT_ROOMMEMBERBINATTRINTERNAL) && verifier.VerifyVector(roomMemberBinAttrInternal()) && verifier.VerifyVectorOfTables(roomMemberBinAttrInternal()) && - VerifyField(verifier, VT_TEAMID) && + VerifyField(verifier, VT_TEAMID) && VerifyOffset(verifier, VT_SIGOPTPARAM) && verifier.VerifyTable(sigOptParam()) && verifier.EndTable(); @@ -1777,19 +1835,20 @@ struct CreateJoinRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Tabl }; struct CreateJoinRoomRequestBuilder { + typedef CreateJoinRoomRequest Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_worldId(u32 worldId) { - fbb_.AddElement(CreateJoinRoomRequest::VT_WORLDID, worldId, 0); + void add_worldId(uint32_t worldId) { + fbb_.AddElement(CreateJoinRoomRequest::VT_WORLDID, worldId, 0); } - void add_lobbyId(u64 lobbyId) { - fbb_.AddElement(CreateJoinRoomRequest::VT_LOBBYID, lobbyId, 0); + void add_lobbyId(uint64_t lobbyId) { + fbb_.AddElement(CreateJoinRoomRequest::VT_LOBBYID, lobbyId, 0); } - void add_maxSlot(u32 maxSlot) { - fbb_.AddElement(CreateJoinRoomRequest::VT_MAXSLOT, maxSlot, 0); + void add_maxSlot(uint32_t maxSlot) { + fbb_.AddElement(CreateJoinRoomRequest::VT_MAXSLOT, maxSlot, 0); } - void add_flagAttr(u32 flagAttr) { - fbb_.AddElement(CreateJoinRoomRequest::VT_FLAGATTR, flagAttr, 0); + void add_flagAttr(uint32_t flagAttr) { + fbb_.AddElement(CreateJoinRoomRequest::VT_FLAGATTR, flagAttr, 0); } void add_roomBinAttrInternal(flatbuffers::Offset>> roomBinAttrInternal) { fbb_.AddOffset(CreateJoinRoomRequest::VT_ROOMBINATTRINTERNAL, roomBinAttrInternal); @@ -1803,14 +1862,14 @@ struct CreateJoinRoomRequestBuilder { void add_roomBinAttrExternal(flatbuffers::Offset>> roomBinAttrExternal) { fbb_.AddOffset(CreateJoinRoomRequest::VT_ROOMBINATTREXTERNAL, roomBinAttrExternal); } - void add_roomPassword(flatbuffers::Offset> roomPassword) { + void add_roomPassword(flatbuffers::Offset> roomPassword) { fbb_.AddOffset(CreateJoinRoomRequest::VT_ROOMPASSWORD, roomPassword); } void add_groupConfig(flatbuffers::Offset>> groupConfig) { fbb_.AddOffset(CreateJoinRoomRequest::VT_GROUPCONFIG, groupConfig); } - void add_passwordSlotMask(u64 passwordSlotMask) { - fbb_.AddElement(CreateJoinRoomRequest::VT_PASSWORDSLOTMASK, passwordSlotMask, 0); + void add_passwordSlotMask(uint64_t passwordSlotMask) { + fbb_.AddElement(CreateJoinRoomRequest::VT_PASSWORDSLOTMASK, passwordSlotMask, 0); } void add_allowedUser(flatbuffers::Offset>> allowedUser) { fbb_.AddOffset(CreateJoinRoomRequest::VT_ALLOWEDUSER, allowedUser); @@ -1818,14 +1877,14 @@ struct CreateJoinRoomRequestBuilder { void add_blockedUser(flatbuffers::Offset>> blockedUser) { fbb_.AddOffset(CreateJoinRoomRequest::VT_BLOCKEDUSER, blockedUser); } - void add_joinRoomGroupLabel(flatbuffers::Offset> joinRoomGroupLabel) { + void add_joinRoomGroupLabel(flatbuffers::Offset> joinRoomGroupLabel) { fbb_.AddOffset(CreateJoinRoomRequest::VT_JOINROOMGROUPLABEL, joinRoomGroupLabel); } void add_roomMemberBinAttrInternal(flatbuffers::Offset>> roomMemberBinAttrInternal) { fbb_.AddOffset(CreateJoinRoomRequest::VT_ROOMMEMBERBINATTRINTERNAL, roomMemberBinAttrInternal); } - void add_teamId(u8 teamId) { - fbb_.AddElement(CreateJoinRoomRequest::VT_TEAMID, teamId, 0); + void add_teamId(uint8_t teamId) { + fbb_.AddElement(CreateJoinRoomRequest::VT_TEAMID, teamId, 0); } void add_sigOptParam(flatbuffers::Offset sigOptParam) { fbb_.AddOffset(CreateJoinRoomRequest::VT_SIGOPTPARAM, sigOptParam); @@ -1834,7 +1893,6 @@ struct CreateJoinRoomRequestBuilder { : fbb_(_fbb) { start_ = fbb_.StartTable(); } - CreateJoinRoomRequestBuilder &operator=(const CreateJoinRoomRequestBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -1844,22 +1902,22 @@ struct CreateJoinRoomRequestBuilder { inline flatbuffers::Offset CreateCreateJoinRoomRequest( flatbuffers::FlatBufferBuilder &_fbb, - u32 worldId = 0, - u64 lobbyId = 0, - u32 maxSlot = 0, - u32 flagAttr = 0, + uint32_t worldId = 0, + uint64_t lobbyId = 0, + uint32_t maxSlot = 0, + uint32_t flagAttr = 0, flatbuffers::Offset>> roomBinAttrInternal = 0, flatbuffers::Offset>> roomSearchableIntAttrExternal = 0, flatbuffers::Offset>> roomSearchableBinAttrExternal = 0, flatbuffers::Offset>> roomBinAttrExternal = 0, - flatbuffers::Offset> roomPassword = 0, + flatbuffers::Offset> roomPassword = 0, flatbuffers::Offset>> groupConfig = 0, - u64 passwordSlotMask = 0, + uint64_t passwordSlotMask = 0, flatbuffers::Offset>> allowedUser = 0, flatbuffers::Offset>> blockedUser = 0, - flatbuffers::Offset> joinRoomGroupLabel = 0, + flatbuffers::Offset> joinRoomGroupLabel = 0, flatbuffers::Offset>> roomMemberBinAttrInternal = 0, - u8 teamId = 0, + uint8_t teamId = 0, flatbuffers::Offset sigOptParam = 0) { CreateJoinRoomRequestBuilder builder_(_fbb); builder_.add_passwordSlotMask(passwordSlotMask); @@ -1884,32 +1942,32 @@ inline flatbuffers::Offset CreateCreateJoinRoomRequest( inline flatbuffers::Offset CreateCreateJoinRoomRequestDirect( flatbuffers::FlatBufferBuilder &_fbb, - u32 worldId = 0, - u64 lobbyId = 0, - u32 maxSlot = 0, - u32 flagAttr = 0, + uint32_t worldId = 0, + uint64_t lobbyId = 0, + uint32_t maxSlot = 0, + uint32_t flagAttr = 0, const std::vector> *roomBinAttrInternal = nullptr, const std::vector> *roomSearchableIntAttrExternal = nullptr, const std::vector> *roomSearchableBinAttrExternal = nullptr, const std::vector> *roomBinAttrExternal = nullptr, - const std::vector *roomPassword = nullptr, + const std::vector *roomPassword = nullptr, const std::vector> *groupConfig = nullptr, - u64 passwordSlotMask = 0, + uint64_t passwordSlotMask = 0, const std::vector> *allowedUser = nullptr, const std::vector> *blockedUser = nullptr, - const std::vector *joinRoomGroupLabel = nullptr, + const std::vector *joinRoomGroupLabel = nullptr, const std::vector> *roomMemberBinAttrInternal = nullptr, - u8 teamId = 0, + uint8_t teamId = 0, flatbuffers::Offset sigOptParam = 0) { auto roomBinAttrInternal__ = roomBinAttrInternal ? _fbb.CreateVector>(*roomBinAttrInternal) : 0; auto roomSearchableIntAttrExternal__ = roomSearchableIntAttrExternal ? _fbb.CreateVector>(*roomSearchableIntAttrExternal) : 0; auto roomSearchableBinAttrExternal__ = roomSearchableBinAttrExternal ? _fbb.CreateVector>(*roomSearchableBinAttrExternal) : 0; auto roomBinAttrExternal__ = roomBinAttrExternal ? _fbb.CreateVector>(*roomBinAttrExternal) : 0; - auto roomPassword__ = roomPassword ? _fbb.CreateVector(*roomPassword) : 0; + auto roomPassword__ = roomPassword ? _fbb.CreateVector(*roomPassword) : 0; auto groupConfig__ = groupConfig ? _fbb.CreateVector>(*groupConfig) : 0; auto allowedUser__ = allowedUser ? _fbb.CreateVector>(*allowedUser) : 0; auto blockedUser__ = blockedUser ? _fbb.CreateVector>(*blockedUser) : 0; - auto joinRoomGroupLabel__ = joinRoomGroupLabel ? _fbb.CreateVector(*joinRoomGroupLabel) : 0; + auto joinRoomGroupLabel__ = joinRoomGroupLabel ? _fbb.CreateVector(*joinRoomGroupLabel) : 0; auto roomMemberBinAttrInternal__ = roomMemberBinAttrInternal ? _fbb.CreateVector>(*roomMemberBinAttrInternal) : 0; return CreateCreateJoinRoomRequest( _fbb, @@ -1933,6 +1991,7 @@ inline flatbuffers::Offset CreateCreateJoinRoomRequestDir } struct JoinRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef JoinRoomRequestBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_ROOMID = 4, VT_ROOMPASSWORD = 6, @@ -1941,14 +2000,14 @@ struct JoinRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_OPTDATA = 12, VT_TEAMID = 14 }; - u64 roomId() const { - return GetField(VT_ROOMID, 0); + uint64_t roomId() const { + return GetField(VT_ROOMID, 0); } - const flatbuffers::Vector *roomPassword() const { - return GetPointer *>(VT_ROOMPASSWORD); + const flatbuffers::Vector *roomPassword() const { + return GetPointer *>(VT_ROOMPASSWORD); } - const flatbuffers::Vector *joinRoomGroupLabel() const { - return GetPointer *>(VT_JOINROOMGROUPLABEL); + const flatbuffers::Vector *joinRoomGroupLabel() const { + return GetPointer *>(VT_JOINROOMGROUPLABEL); } const flatbuffers::Vector> *roomMemberBinAttrInternal() const { return GetPointer> *>(VT_ROOMMEMBERBINATTRINTERNAL); @@ -1956,12 +2015,12 @@ struct JoinRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const PresenceOptionData *optData() const { return GetPointer(VT_OPTDATA); } - u8 teamId() const { - return GetField(VT_TEAMID, 0); + uint8_t teamId() const { + return GetField(VT_TEAMID, 0); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_ROOMID) && + VerifyField(verifier, VT_ROOMID) && VerifyOffset(verifier, VT_ROOMPASSWORD) && verifier.VerifyVector(roomPassword()) && VerifyOffset(verifier, VT_JOINROOMGROUPLABEL) && @@ -1971,21 +2030,22 @@ struct JoinRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { verifier.VerifyVectorOfTables(roomMemberBinAttrInternal()) && VerifyOffset(verifier, VT_OPTDATA) && verifier.VerifyTable(optData()) && - VerifyField(verifier, VT_TEAMID) && + VerifyField(verifier, VT_TEAMID) && verifier.EndTable(); } }; struct JoinRoomRequestBuilder { + typedef JoinRoomRequest Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_roomId(u64 roomId) { - fbb_.AddElement(JoinRoomRequest::VT_ROOMID, roomId, 0); + void add_roomId(uint64_t roomId) { + fbb_.AddElement(JoinRoomRequest::VT_ROOMID, roomId, 0); } - void add_roomPassword(flatbuffers::Offset> roomPassword) { + void add_roomPassword(flatbuffers::Offset> roomPassword) { fbb_.AddOffset(JoinRoomRequest::VT_ROOMPASSWORD, roomPassword); } - void add_joinRoomGroupLabel(flatbuffers::Offset> joinRoomGroupLabel) { + void add_joinRoomGroupLabel(flatbuffers::Offset> joinRoomGroupLabel) { fbb_.AddOffset(JoinRoomRequest::VT_JOINROOMGROUPLABEL, joinRoomGroupLabel); } void add_roomMemberBinAttrInternal(flatbuffers::Offset>> roomMemberBinAttrInternal) { @@ -1994,14 +2054,13 @@ struct JoinRoomRequestBuilder { void add_optData(flatbuffers::Offset optData) { fbb_.AddOffset(JoinRoomRequest::VT_OPTDATA, optData); } - void add_teamId(u8 teamId) { - fbb_.AddElement(JoinRoomRequest::VT_TEAMID, teamId, 0); + void add_teamId(uint8_t teamId) { + fbb_.AddElement(JoinRoomRequest::VT_TEAMID, teamId, 0); } explicit JoinRoomRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - JoinRoomRequestBuilder &operator=(const JoinRoomRequestBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -2011,12 +2070,12 @@ struct JoinRoomRequestBuilder { inline flatbuffers::Offset CreateJoinRoomRequest( flatbuffers::FlatBufferBuilder &_fbb, - u64 roomId = 0, - flatbuffers::Offset> roomPassword = 0, - flatbuffers::Offset> joinRoomGroupLabel = 0, + uint64_t roomId = 0, + flatbuffers::Offset> roomPassword = 0, + flatbuffers::Offset> joinRoomGroupLabel = 0, flatbuffers::Offset>> roomMemberBinAttrInternal = 0, flatbuffers::Offset optData = 0, - u8 teamId = 0) { + uint8_t teamId = 0) { JoinRoomRequestBuilder builder_(_fbb); builder_.add_roomId(roomId); builder_.add_optData(optData); @@ -2029,14 +2088,14 @@ inline flatbuffers::Offset CreateJoinRoomRequest( inline flatbuffers::Offset CreateJoinRoomRequestDirect( flatbuffers::FlatBufferBuilder &_fbb, - u64 roomId = 0, - const std::vector *roomPassword = nullptr, - const std::vector *joinRoomGroupLabel = nullptr, + uint64_t roomId = 0, + const std::vector *roomPassword = nullptr, + const std::vector *joinRoomGroupLabel = nullptr, const std::vector> *roomMemberBinAttrInternal = nullptr, flatbuffers::Offset optData = 0, - u8 teamId = 0) { - auto roomPassword__ = roomPassword ? _fbb.CreateVector(*roomPassword) : 0; - auto joinRoomGroupLabel__ = joinRoomGroupLabel ? _fbb.CreateVector(*joinRoomGroupLabel) : 0; + uint8_t teamId = 0) { + auto roomPassword__ = roomPassword ? _fbb.CreateVector(*roomPassword) : 0; + auto joinRoomGroupLabel__ = joinRoomGroupLabel ? _fbb.CreateVector(*joinRoomGroupLabel) : 0; auto roomMemberBinAttrInternal__ = roomMemberBinAttrInternal ? _fbb.CreateVector>(*roomMemberBinAttrInternal) : 0; return CreateJoinRoomRequest( _fbb, @@ -2049,19 +2108,20 @@ inline flatbuffers::Offset CreateJoinRoomRequestDirect( } struct LeaveRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef LeaveRoomRequestBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_ROOMID = 4, VT_OPTDATA = 6 }; - u64 roomId() const { - return GetField(VT_ROOMID, 0); + uint64_t roomId() const { + return GetField(VT_ROOMID, 0); } const PresenceOptionData *optData() const { return GetPointer(VT_OPTDATA); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_ROOMID) && + VerifyField(verifier, VT_ROOMID) && VerifyOffset(verifier, VT_OPTDATA) && verifier.VerifyTable(optData()) && verifier.EndTable(); @@ -2069,10 +2129,11 @@ struct LeaveRoomRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct LeaveRoomRequestBuilder { + typedef LeaveRoomRequest Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_roomId(u64 roomId) { - fbb_.AddElement(LeaveRoomRequest::VT_ROOMID, roomId, 0); + void add_roomId(uint64_t roomId) { + fbb_.AddElement(LeaveRoomRequest::VT_ROOMID, roomId, 0); } void add_optData(flatbuffers::Offset optData) { fbb_.AddOffset(LeaveRoomRequest::VT_OPTDATA, optData); @@ -2081,7 +2142,6 @@ struct LeaveRoomRequestBuilder { : fbb_(_fbb) { start_ = fbb_.StartTable(); } - LeaveRoomRequestBuilder &operator=(const LeaveRoomRequestBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -2091,7 +2151,7 @@ struct LeaveRoomRequestBuilder { inline flatbuffers::Offset CreateLeaveRoomRequest( flatbuffers::FlatBufferBuilder &_fbb, - u64 roomId = 0, + uint64_t roomId = 0, flatbuffers::Offset optData = 0) { LeaveRoomRequestBuilder builder_(_fbb); builder_.add_roomId(roomId); @@ -2099,15 +2159,133 @@ inline flatbuffers::Offset CreateLeaveRoomRequest( return builder_.Finish(); } +struct GetRoomDataExternalListRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef GetRoomDataExternalListRequestBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ROOMIDS = 4, + VT_ATTRIDS = 6 + }; + const flatbuffers::Vector *roomIds() const { + return GetPointer *>(VT_ROOMIDS); + } + const flatbuffers::Vector *attrIds() const { + return GetPointer *>(VT_ATTRIDS); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_ROOMIDS) && + verifier.VerifyVector(roomIds()) && + VerifyOffset(verifier, VT_ATTRIDS) && + verifier.VerifyVector(attrIds()) && + verifier.EndTable(); + } +}; + +struct GetRoomDataExternalListRequestBuilder { + typedef GetRoomDataExternalListRequest Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_roomIds(flatbuffers::Offset> roomIds) { + fbb_.AddOffset(GetRoomDataExternalListRequest::VT_ROOMIDS, roomIds); + } + void add_attrIds(flatbuffers::Offset> attrIds) { + fbb_.AddOffset(GetRoomDataExternalListRequest::VT_ATTRIDS, attrIds); + } + explicit GetRoomDataExternalListRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateGetRoomDataExternalListRequest( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset> roomIds = 0, + flatbuffers::Offset> attrIds = 0) { + GetRoomDataExternalListRequestBuilder builder_(_fbb); + builder_.add_attrIds(attrIds); + builder_.add_roomIds(roomIds); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateGetRoomDataExternalListRequestDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *roomIds = nullptr, + const std::vector *attrIds = nullptr) { + auto roomIds__ = roomIds ? _fbb.CreateVector(*roomIds) : 0; + auto attrIds__ = attrIds ? _fbb.CreateVector(*attrIds) : 0; + return CreateGetRoomDataExternalListRequest( + _fbb, + roomIds__, + attrIds__); +} + +struct GetRoomDataExternalListResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef GetRoomDataExternalListResponseBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ROOMS = 4 + }; + const flatbuffers::Vector> *rooms() const { + return GetPointer> *>(VT_ROOMS); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_ROOMS) && + verifier.VerifyVector(rooms()) && + verifier.VerifyVectorOfTables(rooms()) && + verifier.EndTable(); + } +}; + +struct GetRoomDataExternalListResponseBuilder { + typedef GetRoomDataExternalListResponse Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_rooms(flatbuffers::Offset>> rooms) { + fbb_.AddOffset(GetRoomDataExternalListResponse::VT_ROOMS, rooms); + } + explicit GetRoomDataExternalListResponseBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateGetRoomDataExternalListResponse( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset>> rooms = 0) { + GetRoomDataExternalListResponseBuilder builder_(_fbb); + builder_.add_rooms(rooms); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateGetRoomDataExternalListResponseDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector> *rooms = nullptr) { + auto rooms__ = rooms ? _fbb.CreateVector>(*rooms) : 0; + return CreateGetRoomDataExternalListResponse( + _fbb, + rooms__); +} + struct SetRoomDataExternalRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SetRoomDataExternalRequestBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_ROOMID = 4, VT_ROOMSEARCHABLEINTATTREXTERNAL = 6, VT_ROOMSEARCHABLEBINATTREXTERNAL = 8, VT_ROOMBINATTREXTERNAL = 10 }; - u64 roomId() const { - return GetField(VT_ROOMID, 0); + uint64_t roomId() const { + return GetField(VT_ROOMID, 0); } const flatbuffers::Vector> *roomSearchableIntAttrExternal() const { return GetPointer> *>(VT_ROOMSEARCHABLEINTATTREXTERNAL); @@ -2120,7 +2298,7 @@ struct SetRoomDataExternalRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers: } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_ROOMID) && + VerifyField(verifier, VT_ROOMID) && VerifyOffset(verifier, VT_ROOMSEARCHABLEINTATTREXTERNAL) && verifier.VerifyVector(roomSearchableIntAttrExternal()) && verifier.VerifyVectorOfTables(roomSearchableIntAttrExternal()) && @@ -2135,10 +2313,11 @@ struct SetRoomDataExternalRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers: }; struct SetRoomDataExternalRequestBuilder { + typedef SetRoomDataExternalRequest Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_roomId(u64 roomId) { - fbb_.AddElement(SetRoomDataExternalRequest::VT_ROOMID, roomId, 0); + void add_roomId(uint64_t roomId) { + fbb_.AddElement(SetRoomDataExternalRequest::VT_ROOMID, roomId, 0); } void add_roomSearchableIntAttrExternal(flatbuffers::Offset>> roomSearchableIntAttrExternal) { fbb_.AddOffset(SetRoomDataExternalRequest::VT_ROOMSEARCHABLEINTATTREXTERNAL, roomSearchableIntAttrExternal); @@ -2153,7 +2332,6 @@ struct SetRoomDataExternalRequestBuilder { : fbb_(_fbb) { start_ = fbb_.StartTable(); } - SetRoomDataExternalRequestBuilder &operator=(const SetRoomDataExternalRequestBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -2163,7 +2341,7 @@ struct SetRoomDataExternalRequestBuilder { inline flatbuffers::Offset CreateSetRoomDataExternalRequest( flatbuffers::FlatBufferBuilder &_fbb, - u64 roomId = 0, + uint64_t roomId = 0, flatbuffers::Offset>> roomSearchableIntAttrExternal = 0, flatbuffers::Offset>> roomSearchableBinAttrExternal = 0, flatbuffers::Offset>> roomBinAttrExternal = 0) { @@ -2177,7 +2355,7 @@ inline flatbuffers::Offset CreateSetRoomDataExternal inline flatbuffers::Offset CreateSetRoomDataExternalRequestDirect( flatbuffers::FlatBufferBuilder &_fbb, - u64 roomId = 0, + uint64_t roomId = 0, const std::vector> *roomSearchableIntAttrExternal = nullptr, const std::vector> *roomSearchableBinAttrExternal = nullptr, const std::vector> *roomBinAttrExternal = nullptr) { @@ -2193,6 +2371,7 @@ inline flatbuffers::Offset CreateSetRoomDataExternal } struct SetRoomDataInternalRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SetRoomDataInternalRequestBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_ROOMID = 4, VT_FLAGFILTER = 6, @@ -2202,14 +2381,14 @@ struct SetRoomDataInternalRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers: VT_PASSWORDSLOTMASK = 14, VT_OWNERPRIVILEGERANK = 16 }; - u64 roomId() const { - return GetField(VT_ROOMID, 0); + uint64_t roomId() const { + return GetField(VT_ROOMID, 0); } - u32 flagFilter() const { - return GetField(VT_FLAGFILTER, 0); + uint32_t flagFilter() const { + return GetField(VT_FLAGFILTER, 0); } - u32 flagAttr() const { - return GetField(VT_FLAGATTR, 0); + uint32_t flagAttr() const { + return GetField(VT_FLAGATTR, 0); } const flatbuffers::Vector> *roomBinAttrInternal() const { return GetPointer> *>(VT_ROOMBINATTRINTERNAL); @@ -2217,24 +2396,24 @@ struct SetRoomDataInternalRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers: const flatbuffers::Vector> *passwordConfig() const { return GetPointer> *>(VT_PASSWORDCONFIG); } - u64 passwordSlotMask() const { - return GetField(VT_PASSWORDSLOTMASK, 0); + uint64_t passwordSlotMask() const { + return GetField(VT_PASSWORDSLOTMASK, 0); } - const flatbuffers::Vector *ownerPrivilegeRank() const { - return GetPointer *>(VT_OWNERPRIVILEGERANK); + const flatbuffers::Vector *ownerPrivilegeRank() const { + return GetPointer *>(VT_OWNERPRIVILEGERANK); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_ROOMID) && - VerifyField(verifier, VT_FLAGFILTER) && - VerifyField(verifier, VT_FLAGATTR) && + VerifyField(verifier, VT_ROOMID) && + VerifyField(verifier, VT_FLAGFILTER) && + VerifyField(verifier, VT_FLAGATTR) && VerifyOffset(verifier, VT_ROOMBINATTRINTERNAL) && verifier.VerifyVector(roomBinAttrInternal()) && verifier.VerifyVectorOfTables(roomBinAttrInternal()) && VerifyOffset(verifier, VT_PASSWORDCONFIG) && verifier.VerifyVector(passwordConfig()) && verifier.VerifyVectorOfTables(passwordConfig()) && - VerifyField(verifier, VT_PASSWORDSLOTMASK) && + VerifyField(verifier, VT_PASSWORDSLOTMASK) && VerifyOffset(verifier, VT_OWNERPRIVILEGERANK) && verifier.VerifyVector(ownerPrivilegeRank()) && verifier.EndTable(); @@ -2242,16 +2421,17 @@ struct SetRoomDataInternalRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers: }; struct SetRoomDataInternalRequestBuilder { + typedef SetRoomDataInternalRequest Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_roomId(u64 roomId) { - fbb_.AddElement(SetRoomDataInternalRequest::VT_ROOMID, roomId, 0); + void add_roomId(uint64_t roomId) { + fbb_.AddElement(SetRoomDataInternalRequest::VT_ROOMID, roomId, 0); } - void add_flagFilter(u32 flagFilter) { - fbb_.AddElement(SetRoomDataInternalRequest::VT_FLAGFILTER, flagFilter, 0); + void add_flagFilter(uint32_t flagFilter) { + fbb_.AddElement(SetRoomDataInternalRequest::VT_FLAGFILTER, flagFilter, 0); } - void add_flagAttr(u32 flagAttr) { - fbb_.AddElement(SetRoomDataInternalRequest::VT_FLAGATTR, flagAttr, 0); + void add_flagAttr(uint32_t flagAttr) { + fbb_.AddElement(SetRoomDataInternalRequest::VT_FLAGATTR, flagAttr, 0); } void add_roomBinAttrInternal(flatbuffers::Offset>> roomBinAttrInternal) { fbb_.AddOffset(SetRoomDataInternalRequest::VT_ROOMBINATTRINTERNAL, roomBinAttrInternal); @@ -2259,17 +2439,16 @@ struct SetRoomDataInternalRequestBuilder { void add_passwordConfig(flatbuffers::Offset>> passwordConfig) { fbb_.AddOffset(SetRoomDataInternalRequest::VT_PASSWORDCONFIG, passwordConfig); } - void add_passwordSlotMask(u64 passwordSlotMask) { - fbb_.AddElement(SetRoomDataInternalRequest::VT_PASSWORDSLOTMASK, passwordSlotMask, 0); + void add_passwordSlotMask(uint64_t passwordSlotMask) { + fbb_.AddElement(SetRoomDataInternalRequest::VT_PASSWORDSLOTMASK, passwordSlotMask, 0); } - void add_ownerPrivilegeRank(flatbuffers::Offset> ownerPrivilegeRank) { + void add_ownerPrivilegeRank(flatbuffers::Offset> ownerPrivilegeRank) { fbb_.AddOffset(SetRoomDataInternalRequest::VT_OWNERPRIVILEGERANK, ownerPrivilegeRank); } explicit SetRoomDataInternalRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - SetRoomDataInternalRequestBuilder &operator=(const SetRoomDataInternalRequestBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -2279,13 +2458,13 @@ struct SetRoomDataInternalRequestBuilder { inline flatbuffers::Offset CreateSetRoomDataInternalRequest( flatbuffers::FlatBufferBuilder &_fbb, - u64 roomId = 0, - u32 flagFilter = 0, - u32 flagAttr = 0, + uint64_t roomId = 0, + uint32_t flagFilter = 0, + uint32_t flagAttr = 0, flatbuffers::Offset>> roomBinAttrInternal = 0, flatbuffers::Offset>> passwordConfig = 0, - u64 passwordSlotMask = 0, - flatbuffers::Offset> ownerPrivilegeRank = 0) { + uint64_t passwordSlotMask = 0, + flatbuffers::Offset> ownerPrivilegeRank = 0) { SetRoomDataInternalRequestBuilder builder_(_fbb); builder_.add_passwordSlotMask(passwordSlotMask); builder_.add_roomId(roomId); @@ -2299,16 +2478,16 @@ inline flatbuffers::Offset CreateSetRoomDataInternal inline flatbuffers::Offset CreateSetRoomDataInternalRequestDirect( flatbuffers::FlatBufferBuilder &_fbb, - u64 roomId = 0, - u32 flagFilter = 0, - u32 flagAttr = 0, + uint64_t roomId = 0, + uint32_t flagFilter = 0, + uint32_t flagAttr = 0, const std::vector> *roomBinAttrInternal = nullptr, const std::vector> *passwordConfig = nullptr, - u64 passwordSlotMask = 0, - const std::vector *ownerPrivilegeRank = nullptr) { + uint64_t passwordSlotMask = 0, + const std::vector *ownerPrivilegeRank = nullptr) { auto roomBinAttrInternal__ = roomBinAttrInternal ? _fbb.CreateVector>(*roomBinAttrInternal) : 0; auto passwordConfig__ = passwordConfig ? _fbb.CreateVector>(*passwordConfig) : 0; - auto ownerPrivilegeRank__ = ownerPrivilegeRank ? _fbb.CreateVector(*ownerPrivilegeRank) : 0; + auto ownerPrivilegeRank__ = ownerPrivilegeRank ? _fbb.CreateVector(*ownerPrivilegeRank) : 0; return CreateSetRoomDataInternalRequest( _fbb, roomId, @@ -2321,19 +2500,20 @@ inline flatbuffers::Offset CreateSetRoomDataInternal } struct GetRoomDataInternalRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef GetRoomDataInternalRequestBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_ROOMID = 4, VT_ATTRID = 6 }; - u64 roomId() const { - return GetField(VT_ROOMID, 0); + uint64_t roomId() const { + return GetField(VT_ROOMID, 0); } - const flatbuffers::Vector *attrId() const { - return GetPointer *>(VT_ATTRID); + const flatbuffers::Vector *attrId() const { + return GetPointer *>(VT_ATTRID); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_ROOMID) && + VerifyField(verifier, VT_ROOMID) && VerifyOffset(verifier, VT_ATTRID) && verifier.VerifyVector(attrId()) && verifier.EndTable(); @@ -2341,19 +2521,19 @@ struct GetRoomDataInternalRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers: }; struct GetRoomDataInternalRequestBuilder { + typedef GetRoomDataInternalRequest Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_roomId(u64 roomId) { - fbb_.AddElement(GetRoomDataInternalRequest::VT_ROOMID, roomId, 0); + void add_roomId(uint64_t roomId) { + fbb_.AddElement(GetRoomDataInternalRequest::VT_ROOMID, roomId, 0); } - void add_attrId(flatbuffers::Offset> attrId) { + void add_attrId(flatbuffers::Offset> attrId) { fbb_.AddOffset(GetRoomDataInternalRequest::VT_ATTRID, attrId); } explicit GetRoomDataInternalRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - GetRoomDataInternalRequestBuilder &operator=(const GetRoomDataInternalRequestBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -2363,8 +2543,8 @@ struct GetRoomDataInternalRequestBuilder { inline flatbuffers::Offset CreateGetRoomDataInternalRequest( flatbuffers::FlatBufferBuilder &_fbb, - u64 roomId = 0, - flatbuffers::Offset> attrId = 0) { + uint64_t roomId = 0, + flatbuffers::Offset> attrId = 0) { GetRoomDataInternalRequestBuilder builder_(_fbb); builder_.add_roomId(roomId); builder_.add_attrId(attrId); @@ -2373,9 +2553,9 @@ inline flatbuffers::Offset CreateGetRoomDataInternal inline flatbuffers::Offset CreateGetRoomDataInternalRequestDirect( flatbuffers::FlatBufferBuilder &_fbb, - u64 roomId = 0, - const std::vector *attrId = nullptr) { - auto attrId__ = attrId ? _fbb.CreateVector(*attrId) : 0; + uint64_t roomId = 0, + const std::vector *attrId = nullptr) { + auto attrId__ = attrId ? _fbb.CreateVector(*attrId) : 0; return CreateGetRoomDataInternalRequest( _fbb, roomId, @@ -2383,6 +2563,7 @@ inline flatbuffers::Offset CreateGetRoomDataInternal } struct RoomMemberUpdateInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RoomMemberUpdateInfoBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_ROOMMEMBERDATAINTERNAL = 4, VT_EVENTCAUSE = 6, @@ -2391,8 +2572,8 @@ struct RoomMemberUpdateInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table const RoomMemberDataInternal *roomMemberDataInternal() const { return GetPointer(VT_ROOMMEMBERDATAINTERNAL); } - u8 eventCause() const { - return GetField(VT_EVENTCAUSE, 0); + uint8_t eventCause() const { + return GetField(VT_EVENTCAUSE, 0); } const PresenceOptionData *optData() const { return GetPointer(VT_OPTDATA); @@ -2401,7 +2582,7 @@ struct RoomMemberUpdateInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_ROOMMEMBERDATAINTERNAL) && verifier.VerifyTable(roomMemberDataInternal()) && - VerifyField(verifier, VT_EVENTCAUSE) && + VerifyField(verifier, VT_EVENTCAUSE) && VerifyOffset(verifier, VT_OPTDATA) && verifier.VerifyTable(optData()) && verifier.EndTable(); @@ -2409,13 +2590,14 @@ struct RoomMemberUpdateInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table }; struct RoomMemberUpdateInfoBuilder { + typedef RoomMemberUpdateInfo Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; void add_roomMemberDataInternal(flatbuffers::Offset roomMemberDataInternal) { fbb_.AddOffset(RoomMemberUpdateInfo::VT_ROOMMEMBERDATAINTERNAL, roomMemberDataInternal); } - void add_eventCause(u8 eventCause) { - fbb_.AddElement(RoomMemberUpdateInfo::VT_EVENTCAUSE, eventCause, 0); + void add_eventCause(uint8_t eventCause) { + fbb_.AddElement(RoomMemberUpdateInfo::VT_EVENTCAUSE, eventCause, 0); } void add_optData(flatbuffers::Offset optData) { fbb_.AddOffset(RoomMemberUpdateInfo::VT_OPTDATA, optData); @@ -2424,7 +2606,6 @@ struct RoomMemberUpdateInfoBuilder { : fbb_(_fbb) { start_ = fbb_.StartTable(); } - RoomMemberUpdateInfoBuilder &operator=(const RoomMemberUpdateInfoBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -2435,7 +2616,7 @@ struct RoomMemberUpdateInfoBuilder { inline flatbuffers::Offset CreateRoomMemberUpdateInfo( flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::Offset roomMemberDataInternal = 0, - u8 eventCause = 0, + uint8_t eventCause = 0, flatbuffers::Offset optData = 0) { RoomMemberUpdateInfoBuilder builder_(_fbb); builder_.add_optData(optData); @@ -2445,24 +2626,25 @@ inline flatbuffers::Offset CreateRoomMemberUpdateInfo( } struct RoomUpdateInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RoomUpdateInfoBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_EVENTCAUSE = 4, VT_ERRORCODE = 6, VT_OPTDATA = 8 }; - u8 eventCause() const { - return GetField(VT_EVENTCAUSE, 0); + uint8_t eventCause() const { + return GetField(VT_EVENTCAUSE, 0); } - s32 errorCode() const { - return GetField(VT_ERRORCODE, 0); + int32_t errorCode() const { + return GetField(VT_ERRORCODE, 0); } const PresenceOptionData *optData() const { return GetPointer(VT_OPTDATA); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_EVENTCAUSE) && - VerifyField(verifier, VT_ERRORCODE) && + VerifyField(verifier, VT_EVENTCAUSE) && + VerifyField(verifier, VT_ERRORCODE) && VerifyOffset(verifier, VT_OPTDATA) && verifier.VerifyTable(optData()) && verifier.EndTable(); @@ -2470,13 +2652,14 @@ struct RoomUpdateInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct RoomUpdateInfoBuilder { + typedef RoomUpdateInfo Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_eventCause(u8 eventCause) { - fbb_.AddElement(RoomUpdateInfo::VT_EVENTCAUSE, eventCause, 0); + void add_eventCause(uint8_t eventCause) { + fbb_.AddElement(RoomUpdateInfo::VT_EVENTCAUSE, eventCause, 0); } - void add_errorCode(s32 errorCode) { - fbb_.AddElement(RoomUpdateInfo::VT_ERRORCODE, errorCode, 0); + void add_errorCode(int32_t errorCode) { + fbb_.AddElement(RoomUpdateInfo::VT_ERRORCODE, errorCode, 0); } void add_optData(flatbuffers::Offset optData) { fbb_.AddOffset(RoomUpdateInfo::VT_OPTDATA, optData); @@ -2485,7 +2668,6 @@ struct RoomUpdateInfoBuilder { : fbb_(_fbb) { start_ = fbb_.StartTable(); } - RoomUpdateInfoBuilder &operator=(const RoomUpdateInfoBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -2495,8 +2677,8 @@ struct RoomUpdateInfoBuilder { inline flatbuffers::Offset CreateRoomUpdateInfo( flatbuffers::FlatBufferBuilder &_fbb, - u8 eventCause = 0, - s32 errorCode = 0, + uint8_t eventCause = 0, + int32_t errorCode = 0, flatbuffers::Offset optData = 0) { RoomUpdateInfoBuilder builder_(_fbb); builder_.add_optData(optData); @@ -2506,54 +2688,55 @@ inline flatbuffers::Offset CreateRoomUpdateInfo( } struct GetPingInfoResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef GetPingInfoResponseBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_SERVERID = 4, VT_WORLDID = 6, VT_ROOMID = 8, VT_RTT = 10 }; - u16 serverId() const { - return GetField(VT_SERVERID, 0); + uint16_t serverId() const { + return GetField(VT_SERVERID, 0); } - u32 worldId() const { - return GetField(VT_WORLDID, 0); + uint32_t worldId() const { + return GetField(VT_WORLDID, 0); } - u64 roomId() const { - return GetField(VT_ROOMID, 0); + uint64_t roomId() const { + return GetField(VT_ROOMID, 0); } - u32 rtt() const { - return GetField(VT_RTT, 0); + uint32_t rtt() const { + return GetField(VT_RTT, 0); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_SERVERID) && - VerifyField(verifier, VT_WORLDID) && - VerifyField(verifier, VT_ROOMID) && - VerifyField(verifier, VT_RTT) && + VerifyField(verifier, VT_SERVERID) && + VerifyField(verifier, VT_WORLDID) && + VerifyField(verifier, VT_ROOMID) && + VerifyField(verifier, VT_RTT) && verifier.EndTable(); } }; struct GetPingInfoResponseBuilder { + typedef GetPingInfoResponse Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_serverId(u16 serverId) { - fbb_.AddElement(GetPingInfoResponse::VT_SERVERID, serverId, 0); + void add_serverId(uint16_t serverId) { + fbb_.AddElement(GetPingInfoResponse::VT_SERVERID, serverId, 0); } - void add_worldId(u32 worldId) { - fbb_.AddElement(GetPingInfoResponse::VT_WORLDID, worldId, 0); + void add_worldId(uint32_t worldId) { + fbb_.AddElement(GetPingInfoResponse::VT_WORLDID, worldId, 0); } - void add_roomId(u64 roomId) { - fbb_.AddElement(GetPingInfoResponse::VT_ROOMID, roomId, 0); + void add_roomId(uint64_t roomId) { + fbb_.AddElement(GetPingInfoResponse::VT_ROOMID, roomId, 0); } - void add_rtt(u32 rtt) { - fbb_.AddElement(GetPingInfoResponse::VT_RTT, rtt, 0); + void add_rtt(uint32_t rtt) { + fbb_.AddElement(GetPingInfoResponse::VT_RTT, rtt, 0); } explicit GetPingInfoResponseBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - GetPingInfoResponseBuilder &operator=(const GetPingInfoResponseBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -2563,10 +2746,10 @@ struct GetPingInfoResponseBuilder { inline flatbuffers::Offset CreateGetPingInfoResponse( flatbuffers::FlatBufferBuilder &_fbb, - u16 serverId = 0, - u32 worldId = 0, - u64 roomId = 0, - u32 rtt = 0) { + uint16_t serverId = 0, + uint32_t worldId = 0, + uint64_t roomId = 0, + uint32_t rtt = 0) { GetPingInfoResponseBuilder builder_(_fbb); builder_.add_roomId(roomId); builder_.add_rtt(rtt); @@ -2576,6 +2759,7 @@ inline flatbuffers::Offset CreateGetPingInfoResponse( } struct SendRoomMessageRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SendRoomMessageRequestBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_ROOMID = 4, VT_CASTTYPE = 6, @@ -2583,57 +2767,57 @@ struct SendRoomMessageRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Tab VT_MSG = 10, VT_OPTION = 12 }; - u64 roomId() const { - return GetField(VT_ROOMID, 0); + uint64_t roomId() const { + return GetField(VT_ROOMID, 0); } - u8 castType() const { - return GetField(VT_CASTTYPE, 0); + uint8_t castType() const { + return GetField(VT_CASTTYPE, 0); } - const flatbuffers::Vector *dst() const { - return GetPointer *>(VT_DST); + const flatbuffers::Vector *dst() const { + return GetPointer *>(VT_DST); } - const flatbuffers::Vector *msg() const { - return GetPointer *>(VT_MSG); + const flatbuffers::Vector *msg() const { + return GetPointer *>(VT_MSG); } - u8 option() const { - return GetField(VT_OPTION, 0); + uint8_t option() const { + return GetField(VT_OPTION, 0); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_ROOMID) && - VerifyField(verifier, VT_CASTTYPE) && + VerifyField(verifier, VT_ROOMID) && + VerifyField(verifier, VT_CASTTYPE) && VerifyOffset(verifier, VT_DST) && verifier.VerifyVector(dst()) && VerifyOffset(verifier, VT_MSG) && verifier.VerifyVector(msg()) && - VerifyField(verifier, VT_OPTION) && + VerifyField(verifier, VT_OPTION) && verifier.EndTable(); } }; struct SendRoomMessageRequestBuilder { + typedef SendRoomMessageRequest Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_roomId(u64 roomId) { - fbb_.AddElement(SendRoomMessageRequest::VT_ROOMID, roomId, 0); + void add_roomId(uint64_t roomId) { + fbb_.AddElement(SendRoomMessageRequest::VT_ROOMID, roomId, 0); } - void add_castType(u8 castType) { - fbb_.AddElement(SendRoomMessageRequest::VT_CASTTYPE, castType, 0); + void add_castType(uint8_t castType) { + fbb_.AddElement(SendRoomMessageRequest::VT_CASTTYPE, castType, 0); } - void add_dst(flatbuffers::Offset> dst) { + void add_dst(flatbuffers::Offset> dst) { fbb_.AddOffset(SendRoomMessageRequest::VT_DST, dst); } - void add_msg(flatbuffers::Offset> msg) { + void add_msg(flatbuffers::Offset> msg) { fbb_.AddOffset(SendRoomMessageRequest::VT_MSG, msg); } - void add_option(u8 option) { - fbb_.AddElement(SendRoomMessageRequest::VT_OPTION, option, 0); + void add_option(uint8_t option) { + fbb_.AddElement(SendRoomMessageRequest::VT_OPTION, option, 0); } explicit SendRoomMessageRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - SendRoomMessageRequestBuilder &operator=(const SendRoomMessageRequestBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -2643,11 +2827,11 @@ struct SendRoomMessageRequestBuilder { inline flatbuffers::Offset CreateSendRoomMessageRequest( flatbuffers::FlatBufferBuilder &_fbb, - u64 roomId = 0, - u8 castType = 0, - flatbuffers::Offset> dst = 0, - flatbuffers::Offset> msg = 0, - u8 option = 0) { + uint64_t roomId = 0, + uint8_t castType = 0, + flatbuffers::Offset> dst = 0, + flatbuffers::Offset> msg = 0, + uint8_t option = 0) { SendRoomMessageRequestBuilder builder_(_fbb); builder_.add_roomId(roomId); builder_.add_msg(msg); @@ -2659,13 +2843,13 @@ inline flatbuffers::Offset CreateSendRoomMessageRequest( inline flatbuffers::Offset CreateSendRoomMessageRequestDirect( flatbuffers::FlatBufferBuilder &_fbb, - u64 roomId = 0, - u8 castType = 0, - const std::vector *dst = nullptr, - const std::vector *msg = nullptr, - u8 option = 0) { - auto dst__ = dst ? _fbb.CreateVector(*dst) : 0; - auto msg__ = msg ? _fbb.CreateVector(*msg) : 0; + uint64_t roomId = 0, + uint8_t castType = 0, + const std::vector *dst = nullptr, + const std::vector *msg = nullptr, + uint8_t option = 0) { + auto dst__ = dst ? _fbb.CreateVector(*dst) : 0; + auto msg__ = msg ? _fbb.CreateVector(*msg) : 0; return CreateSendRoomMessageRequest( _fbb, roomId, @@ -2676,6 +2860,7 @@ inline flatbuffers::Offset CreateSendRoomMessageRequestD } struct RoomMessageInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RoomMessageInfoBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_FILTERED = 4, VT_CASTTYPE = 6, @@ -2684,24 +2869,24 @@ struct RoomMessageInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_MSG = 12 }; bool filtered() const { - return GetField(VT_FILTERED, 0) != 0; + return GetField(VT_FILTERED, 0) != 0; } - u8 castType() const { - return GetField(VT_CASTTYPE, 0); + uint8_t castType() const { + return GetField(VT_CASTTYPE, 0); } - const flatbuffers::Vector *dst() const { - return GetPointer *>(VT_DST); + const flatbuffers::Vector *dst() const { + return GetPointer *>(VT_DST); } const UserInfo2 *srcMember() const { return GetPointer(VT_SRCMEMBER); } - const flatbuffers::Vector *msg() const { - return GetPointer *>(VT_MSG); + const flatbuffers::Vector *msg() const { + return GetPointer *>(VT_MSG); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_FILTERED) && - VerifyField(verifier, VT_CASTTYPE) && + VerifyField(verifier, VT_FILTERED) && + VerifyField(verifier, VT_CASTTYPE) && VerifyOffset(verifier, VT_DST) && verifier.VerifyVector(dst()) && VerifyOffset(verifier, VT_SRCMEMBER) && @@ -2713,28 +2898,28 @@ struct RoomMessageInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { }; struct RoomMessageInfoBuilder { + typedef RoomMessageInfo Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; void add_filtered(bool filtered) { - fbb_.AddElement(RoomMessageInfo::VT_FILTERED, static_cast(filtered), 0); + fbb_.AddElement(RoomMessageInfo::VT_FILTERED, static_cast(filtered), 0); } - void add_castType(u8 castType) { - fbb_.AddElement(RoomMessageInfo::VT_CASTTYPE, castType, 0); + void add_castType(uint8_t castType) { + fbb_.AddElement(RoomMessageInfo::VT_CASTTYPE, castType, 0); } - void add_dst(flatbuffers::Offset> dst) { + void add_dst(flatbuffers::Offset> dst) { fbb_.AddOffset(RoomMessageInfo::VT_DST, dst); } void add_srcMember(flatbuffers::Offset srcMember) { fbb_.AddOffset(RoomMessageInfo::VT_SRCMEMBER, srcMember); } - void add_msg(flatbuffers::Offset> msg) { + void add_msg(flatbuffers::Offset> msg) { fbb_.AddOffset(RoomMessageInfo::VT_MSG, msg); } explicit RoomMessageInfoBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - RoomMessageInfoBuilder &operator=(const RoomMessageInfoBuilder &); flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); @@ -2745,10 +2930,10 @@ struct RoomMessageInfoBuilder { inline flatbuffers::Offset CreateRoomMessageInfo( flatbuffers::FlatBufferBuilder &_fbb, bool filtered = false, - u8 castType = 0, - flatbuffers::Offset> dst = 0, + uint8_t castType = 0, + flatbuffers::Offset> dst = 0, flatbuffers::Offset srcMember = 0, - flatbuffers::Offset> msg = 0) { + flatbuffers::Offset> msg = 0) { RoomMessageInfoBuilder builder_(_fbb); builder_.add_msg(msg); builder_.add_srcMember(srcMember); @@ -2761,12 +2946,12 @@ inline flatbuffers::Offset CreateRoomMessageInfo( inline flatbuffers::Offset CreateRoomMessageInfoDirect( flatbuffers::FlatBufferBuilder &_fbb, bool filtered = false, - u8 castType = 0, - const std::vector *dst = nullptr, + uint8_t castType = 0, + const std::vector *dst = nullptr, flatbuffers::Offset srcMember = 0, - const std::vector *msg = nullptr) { - auto dst__ = dst ? _fbb.CreateVector(*dst) : 0; - auto msg__ = msg ? _fbb.CreateVector(*msg) : 0; + const std::vector *msg = nullptr) { + auto dst__ = dst ? _fbb.CreateVector(*dst) : 0; + auto msg__ = msg ? _fbb.CreateVector(*msg) : 0; return CreateRoomMessageInfo( _fbb, filtered, @@ -2776,4 +2961,214 @@ inline flatbuffers::Offset CreateRoomMessageInfoDirect( msg__); } +struct MessageDetails FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef MessageDetailsBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_COMMUNICATIONID = 4, + VT_MSGID = 6, + VT_MAINTYPE = 8, + VT_SUBTYPE = 10, + VT_MSGFEATURES = 12, + VT_SUBJECT = 14, + VT_BODY = 16, + VT_DATA = 18 + }; + const flatbuffers::String *communicationId() const { + return GetPointer(VT_COMMUNICATIONID); + } + uint64_t msgId() const { + return GetField(VT_MSGID, 0); + } + uint16_t mainType() const { + return GetField(VT_MAINTYPE, 0); + } + uint16_t subType() const { + return GetField(VT_SUBTYPE, 0); + } + uint32_t msgFeatures() const { + return GetField(VT_MSGFEATURES, 0); + } + const flatbuffers::String *subject() const { + return GetPointer(VT_SUBJECT); + } + const flatbuffers::String *body() const { + return GetPointer(VT_BODY); + } + const flatbuffers::Vector *data() const { + return GetPointer *>(VT_DATA); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_COMMUNICATIONID) && + verifier.VerifyString(communicationId()) && + VerifyField(verifier, VT_MSGID) && + VerifyField(verifier, VT_MAINTYPE) && + VerifyField(verifier, VT_SUBTYPE) && + VerifyField(verifier, VT_MSGFEATURES) && + VerifyOffset(verifier, VT_SUBJECT) && + verifier.VerifyString(subject()) && + VerifyOffset(verifier, VT_BODY) && + verifier.VerifyString(body()) && + VerifyOffset(verifier, VT_DATA) && + verifier.VerifyVector(data()) && + verifier.EndTable(); + } +}; + +struct MessageDetailsBuilder { + typedef MessageDetails Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_communicationId(flatbuffers::Offset communicationId) { + fbb_.AddOffset(MessageDetails::VT_COMMUNICATIONID, communicationId); + } + void add_msgId(uint64_t msgId) { + fbb_.AddElement(MessageDetails::VT_MSGID, msgId, 0); + } + void add_mainType(uint16_t mainType) { + fbb_.AddElement(MessageDetails::VT_MAINTYPE, mainType, 0); + } + void add_subType(uint16_t subType) { + fbb_.AddElement(MessageDetails::VT_SUBTYPE, subType, 0); + } + void add_msgFeatures(uint32_t msgFeatures) { + fbb_.AddElement(MessageDetails::VT_MSGFEATURES, msgFeatures, 0); + } + void add_subject(flatbuffers::Offset subject) { + fbb_.AddOffset(MessageDetails::VT_SUBJECT, subject); + } + void add_body(flatbuffers::Offset body) { + fbb_.AddOffset(MessageDetails::VT_BODY, body); + } + void add_data(flatbuffers::Offset> data) { + fbb_.AddOffset(MessageDetails::VT_DATA, data); + } + explicit MessageDetailsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateMessageDetails( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset communicationId = 0, + uint64_t msgId = 0, + uint16_t mainType = 0, + uint16_t subType = 0, + uint32_t msgFeatures = 0, + flatbuffers::Offset subject = 0, + flatbuffers::Offset body = 0, + flatbuffers::Offset> data = 0) { + MessageDetailsBuilder builder_(_fbb); + builder_.add_msgId(msgId); + builder_.add_data(data); + builder_.add_body(body); + builder_.add_subject(subject); + builder_.add_msgFeatures(msgFeatures); + builder_.add_communicationId(communicationId); + builder_.add_subType(subType); + builder_.add_mainType(mainType); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateMessageDetailsDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const char *communicationId = nullptr, + uint64_t msgId = 0, + uint16_t mainType = 0, + uint16_t subType = 0, + uint32_t msgFeatures = 0, + const char *subject = nullptr, + const char *body = nullptr, + const std::vector *data = nullptr) { + auto communicationId__ = communicationId ? _fbb.CreateString(communicationId) : 0; + auto subject__ = subject ? _fbb.CreateString(subject) : 0; + auto body__ = body ? _fbb.CreateString(body) : 0; + auto data__ = data ? _fbb.CreateVector(*data) : 0; + return CreateMessageDetails( + _fbb, + communicationId__, + msgId, + mainType, + subType, + msgFeatures, + subject__, + body__, + data__); +} + +struct SendMessageRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SendMessageRequestBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_MESSAGE = 4, + VT_NPIDS = 6 + }; + const flatbuffers::Vector *message() const { + return GetPointer *>(VT_MESSAGE); + } + const MessageDetails *message_nested_root() const { + return flatbuffers::GetRoot(message()->Data()); + } + const flatbuffers::Vector> *npids() const { + return GetPointer> *>(VT_NPIDS); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_MESSAGE) && + verifier.VerifyVector(message()) && + VerifyOffset(verifier, VT_NPIDS) && + verifier.VerifyVector(npids()) && + verifier.VerifyVectorOfStrings(npids()) && + verifier.EndTable(); + } +}; + +struct SendMessageRequestBuilder { + typedef SendMessageRequest Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_message(flatbuffers::Offset> message) { + fbb_.AddOffset(SendMessageRequest::VT_MESSAGE, message); + } + void add_npids(flatbuffers::Offset>> npids) { + fbb_.AddOffset(SendMessageRequest::VT_NPIDS, npids); + } + explicit SendMessageRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSendMessageRequest( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset> message = 0, + flatbuffers::Offset>> npids = 0) { + SendMessageRequestBuilder builder_(_fbb); + builder_.add_npids(npids); + builder_.add_message(message); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateSendMessageRequestDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *message = nullptr, + const std::vector> *npids = nullptr) { + auto message__ = message ? _fbb.CreateVector(*message) : 0; + auto npids__ = npids ? _fbb.CreateVector>(*npids) : 0; + return CreateSendMessageRequest( + _fbb, + message__, + npids__); +} + #endif // FLATBUFFERS_GENERATED_NP2STRUCTS_H_ diff --git a/rpcs3/Emu/NP/np_handler.cpp b/rpcs3/Emu/NP/np_handler.cpp index 6929baae58..20d67fe5dd 100644 --- a/rpcs3/Emu/NP/np_handler.cpp +++ b/rpcs3/Emu/NP/np_handler.cpp @@ -44,24 +44,25 @@ np_handler::np_handler() { g_fxo->need>(); - g_cfg_rpcn.load(); + std::lock_guard lock(mutex_rpcn); + rpcn = rpcn::rpcn_client::get_instance(); is_connected = (g_cfg.net.net_active == np_internet_status::enabled); - is_psn_active = (g_cfg.net.psn_status >= np_psn_status::fake); + is_psn_active = (g_cfg.net.psn_status >= np_psn_status::psn_fake); if (get_net_status() == CELL_NET_CTL_STATE_IPObtained) { if (!discover_ip_address()) { nph_log.error("Failed to discover local IP!"); - is_connected = false; + is_connected = false; is_psn_active = false; } if (!discover_ether_address()) { nph_log.error("Failed to discover ethernet address!"); - is_connected = false; + is_connected = false; is_psn_active = false; } @@ -115,7 +116,7 @@ bool np_handler::discover_ip_address() nph_log.notice("Hostname was determined to be %s", hostname.c_str()); - hostent *host = gethostbyname(hostname.data()); + hostent* host = gethostbyname(hostname.data()); if (!host) { nph_log.error("gethostbyname failed in IP discovery!"); @@ -129,7 +130,7 @@ bool np_handler::discover_ip_address() } // First address is used for now, (TODO combobox with possible local addresses to use?) - local_ip_addr = *reinterpret_cast(host->h_addr_list[0]); + local_ip_addr = *reinterpret_cast(host->h_addr_list[0]); // Set public address to local discovered address for now, may be updated later; public_ip_addr = local_ip_addr; @@ -164,10 +165,10 @@ bool np_handler::discover_ether_address() std::vector adapter_infos(sizeof(IP_ADAPTER_INFO)); ULONG size_infos = sizeof(IP_ADAPTER_INFO); - if (GetAdaptersInfo(reinterpret_cast(adapter_infos.data()), &size_infos) == ERROR_BUFFER_OVERFLOW) + if (GetAdaptersInfo(reinterpret_cast(adapter_infos.data()), &size_infos) == ERROR_BUFFER_OVERFLOW) adapter_infos.resize(size_infos); - if (GetAdaptersInfo(reinterpret_cast(adapter_infos.data()), &size_infos) == NO_ERROR && size_infos) + if (GetAdaptersInfo(reinterpret_cast(adapter_infos.data()), &size_infos) == NO_ERROR && size_infos) { PIP_ADAPTER_INFO info = reinterpret_cast(adapter_infos.data()); memcpy(ether_address.data(), info[0].Address, 6); @@ -305,6 +306,11 @@ void np_handler::string_to_avatar_url(const std::string& str, SceNpAvatarUrl* av strcpy_trunc(avatar_url->data, str); } +void np_handler::string_to_communication_id(const std::string& str, SceNpCommunicationId* comm_id) +{ + strcpy_trunc(comm_id->data, str); +} + void np_handler::init_NP(u32 poolsize, vm::ptr poolptr) { // Init memory pool @@ -317,7 +323,7 @@ void np_handler::init_NP(u32 poolsize, vm::ptr poolptr) memset(&online_name, 0, sizeof(online_name)); memset(&avatar_url, 0, sizeof(avatar_url)); - if (g_cfg.net.psn_status >= np_psn_status::fake) + if (g_cfg.net.psn_status >= np_psn_status::psn_fake) { std::string s_npid = g_cfg_rpcn.get_npid(); ensure(!s_npid.empty()); // It should have been generated before this @@ -331,35 +337,39 @@ void np_handler::init_NP(u32 poolsize, vm::ptr poolptr) { case np_psn_status::disabled: break; - case np_psn_status::fake: + case np_psn_status::psn_fake: { np_handler::string_to_online_name("RPCS3's user", &online_name); np_handler::string_to_avatar_url("https://rpcs3.net/cdn/netplay/DefaultAvatar.png", &avatar_url); break; } - case np_psn_status::rpcn: + case np_psn_status::psn_rpcn: { if (!is_psn_active) break; - // Connect RPCN client - if (!rpcn.connect(g_cfg_rpcn.get_host())) + std::lock_guard lock(mutex_rpcn); + rpcn = rpcn::rpcn_client::get_instance(); + + // Make sure we're connected + + if (auto state = rpcn->wait_for_connection(); state != rpcn::rpcn_state::failure_no_failure) { rpcn_log.error("Connection to RPCN Failed!"); is_psn_active = false; return; } - if (!rpcn.login(g_cfg_rpcn.get_npid(), g_cfg_rpcn.get_password(), g_cfg_rpcn.get_token())) + if (auto state = rpcn->wait_for_authentified(); state != rpcn::rpcn_state::failure_no_failure) { rpcn_log.error("RPCN login attempt failed!"); is_psn_active = false; return; } - np_handler::string_to_online_name(rpcn.get_online_name(), &online_name); - np_handler::string_to_avatar_url(rpcn.get_avatar_url(), &avatar_url); - public_ip_addr = rpcn.get_addr_sig(); + np_handler::string_to_online_name(rpcn->get_online_name(), &online_name); + np_handler::string_to_avatar_url(rpcn->get_avatar_url(), &avatar_url); + public_ip_addr = rpcn->get_addr_sig(); break; } @@ -376,10 +386,11 @@ void np_handler::terminate_NP() mpool_avail = 0; mpool_allocs.clear(); - if (g_cfg.net.psn_status == np_psn_status::rpcn) + if (g_cfg.net.psn_status == np_psn_status::psn_rpcn) { - rpcn_log.error("Disconnecting from RPCN!"); - rpcn.disconnect(); + rpcn_log.notice("Disconnecting from RPCN!"); + std::lock_guard lock(mutex_rpcn); + rpcn.reset(); } } @@ -433,12 +444,12 @@ std::vector np_handler::get_match2_server_list(SceNpMatc { std::vector server_list{}; - if (g_cfg.net.psn_status != np_psn_status::rpcn) + if (g_cfg.net.psn_status != np_psn_status::psn_rpcn) { return server_list; } - if (!rpcn.get_server_list(get_req_id(0), get_match2_context(ctx_id)->communicationId, server_list)) + if (!rpcn->get_server_list(get_req_id(0), get_match2_context(ctx_id)->communicationId, server_list)) { rpcn_log.error("Disconnecting from RPCN!"); is_psn_active = false; @@ -457,14 +468,13 @@ u32 np_handler::get_server_status(SceNpMatching2ContextId ctx_id, vm::cptrserver.serverId = server_id; serv_info->server.status = SCE_NP_MATCHING2_SERVER_STATUS_AVAILABLE; - const auto cb_info = std::move(pending_requests.at(req_id)); - pending_requests.erase(req_id); + const auto cb_info = take_pending_request(req_id); sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 - { - cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetServerInfo, event_key, 0, sizeof(SceNpMatching2GetServerInfoResponse), cb_info.cb_arg); - return 0; - }); + { + cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetServerInfo, event_key, 0, sizeof(SceNpMatching2GetServerInfoResponse), cb_info.cb_arg); + return 0; + }); return req_id; } @@ -474,14 +484,13 @@ u32 np_handler::create_server_context(SceNpMatching2ContextId ctx_id, vm::cptr s32 - { - cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_CreateServerContext, event_key, 0, 0, cb_info.cb_arg); - return 0; - }); + { + cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_CreateServerContext, event_key, 0, 0, cb_info.cb_arg); + return 0; + }); return req_id; } @@ -490,7 +499,7 @@ u32 np_handler::get_world_list(SceNpMatching2ContextId ctx_id, vm::cptrcommunicationId, server_id)) + if (!rpcn->get_world_list(req_id, get_match2_context(ctx_id)->communicationId, server_id)) { rpcn_log.error("Disconnecting from RPCN!"); is_psn_active = false; @@ -503,7 +512,7 @@ u32 np_handler::create_join_room(SceNpMatching2ContextId ctx_id, vm::cptrcommunicationId, req)) + if (!rpcn->createjoin_room(req_id, get_match2_context(ctx_id)->communicationId, req)) { rpcn_log.error("Disconnecting from RPCN!"); is_psn_active = false; @@ -516,7 +525,7 @@ u32 np_handler::join_room(SceNpMatching2ContextId ctx_id, vm::cptrcommunicationId, req)) + if (!rpcn->join_room(req_id, get_match2_context(ctx_id)->communicationId, req)) { rpcn_log.error("Disconnecting from RPCN!"); is_psn_active = false; @@ -529,7 +538,7 @@ u32 np_handler::leave_room(SceNpMatching2ContextId ctx_id, vm::cptrcommunicationId, req)) + if (!rpcn->leave_room(req_id, get_match2_context(ctx_id)->communicationId, req)) { rpcn_log.error("Disconnecting from RPCN!"); is_psn_active = false; @@ -542,7 +551,20 @@ u32 np_handler::search_room(SceNpMatching2ContextId ctx_id, vm::cptrcommunicationId, req)) + if (!rpcn->search_room(req_id, get_match2_context(ctx_id)->communicationId, req)) + { + rpcn_log.error("Disconnecting from RPCN!"); + is_psn_active = false; + } + + return req_id; +} + +u32 np_handler::get_roomdata_external_list(SceNpMatching2ContextId ctx_id, vm::cptr optParam, const SceNpMatching2GetRoomDataExternalListRequest* req) +{ + u32 req_id = generate_callback_info(ctx_id, optParam); + + if (!rpcn->get_roomdata_external_list(req_id, get_match2_context(ctx_id)->communicationId, req)) { rpcn_log.error("Disconnecting from RPCN!"); is_psn_active = false; @@ -557,7 +579,7 @@ u32 np_handler::set_roomdata_external(SceNpMatching2ContextId ctx_id, vm::cptrcommunicationId, req)) + if (!rpcn->set_roomdata_external(req_id, get_match2_context(ctx_id)->communicationId, req)) { rpcn_log.error("Disconnecting from RPCN!"); is_psn_active = false; @@ -570,7 +592,7 @@ u32 np_handler::get_roomdata_internal(SceNpMatching2ContextId ctx_id, vm::cptrcommunicationId, req)) + if (!rpcn->get_roomdata_internal(req_id, get_match2_context(ctx_id)->communicationId, req)) { rpcn_log.error("Disconnecting from RPCN!"); is_psn_active = false; @@ -585,7 +607,7 @@ u32 np_handler::set_roomdata_internal(SceNpMatching2ContextId ctx_id, vm::cptrcommunicationId, req)) + if (!rpcn->set_roomdata_internal(req_id, get_match2_context(ctx_id)->communicationId, req)) { rpcn_log.error("Disconnecting from RPCN!"); is_psn_active = false; @@ -598,7 +620,7 @@ u32 np_handler::get_ping_info(SceNpMatching2ContextId ctx_id, vm::cptrcommunicationId, req->roomId)) + if (!rpcn->ping_room_owner(req_id, get_match2_context(ctx_id)->communicationId, req->roomId)) { rpcn_log.error("Disconnecting from RPCN!"); is_psn_active = false; @@ -611,7 +633,7 @@ u32 np_handler::send_room_message(SceNpMatching2ContextId ctx_id, vm::cptrcommunicationId, req)) + if (!rpcn->send_room_message(req_id, get_match2_context(ctx_id)->communicationId, req)) { rpcn_log.error("Disconnecting from RPCN!"); is_psn_active = false; @@ -623,9 +645,12 @@ u32 np_handler::send_room_message(SceNpMatching2ContextId ctx_id, vm::cptrreq_sign_infos(req_id, npid)) { rpcn_log.error("Disconnecting from RPCN!"); is_psn_active = false; @@ -640,7 +665,7 @@ void np_handler::req_ticket(u32 /*version*/, const SceNpId* /*npid*/, const char std::string service_id_str(service_id); - if (!rpcn.req_ticket(req_id, service_id_str)) + if (!rpcn->req_ticket(req_id, service_id_str)) { rpcn_log.error("Disconnecting from RPCN!"); is_psn_active = false; @@ -649,7 +674,6 @@ void np_handler::req_ticket(u32 /*version*/, const SceNpId* /*npid*/, const char return; } - u32 np_handler::get_match2_event(SceNpMatching2EventKey event_key, u8* dest, u32 size) { std::lock_guard lock(mutex_req_results); @@ -663,67 +687,181 @@ u32 np_handler::get_match2_event(SceNpMatching2EventKey event_key, u8* dest, u32 return size_copied; } +bool np_handler::send_basic_event(s32 event, s32 retCode, u32 reqId) +{ + if (basic_handler.registered) + { + sysutil_register_cb([handler_func = this->basic_handler.handler_func, handler_arg = this->basic_handler.handler_arg, event, retCode, reqId](ppu_thread& cb_ppu) -> s32 + { + handler_func(cb_ppu, event, retCode, reqId, handler_arg); + return 0; + }); + + return true; + } + + return false; +} + +void np_handler::queue_basic_event(basic_event to_queue) +{ + std::lock_guard lock(mutex_queue_basic_events); + queue_basic_events.push(std::move(to_queue)); +} + +error_code np_handler::get_basic_event(vm::ptr event, vm::ptr from, vm::ptr data, vm::ptr size) +{ + basic_event cur_event; + { + std::lock_guard lock(mutex_queue_basic_events); + if (queue_basic_events.empty()) + { + return not_an_error(SCE_NP_BASIC_ERROR_NO_EVENT); + } + + cur_event = std::move(queue_basic_events.front()); + queue_basic_events.pop(); + } + + const u32 size_avail = *size; + u32 res_size = std::min(static_cast(cur_event.data.size()), size_avail); + + *event = cur_event.event; + memcpy(from.get_ptr(), &cur_event.from, sizeof(cur_event.from)); + memcpy(data.get_ptr(), cur_event.data.data(), res_size); + *size = res_size; + + if (res_size < cur_event.data.size()) + { + return SCE_NP_BASIC_ERROR_DATA_LOST; + } + + return CELL_OK; +} + +std::optional>> np_handler::get_message(u64 id) +{ + return rpcn->get_message(id); +} + void np_handler::operator()() { - if (g_cfg.net.psn_status != np_psn_status::rpcn) + if (g_cfg.net.psn_status != np_psn_status::psn_rpcn) return; while (thread_ctrl::state() != thread_state::aborting && !Emu.IsStopped()) { - if (!rpcn.manage_connection()) + bool sleep = true; + if (rpcn) + { + std::lock_guard lock(mutex_rpcn); + if (!rpcn) + { + continue; + } + + auto replies = rpcn->get_replies(); + for (auto& reply : replies) + { + const u16 command = reply.second.first; + const u32 req_id = reply.first; + std::vector& data = reply.second.second; + + switch (command) + { + case rpcn::CommandType::GetWorldList: reply_get_world_list(req_id, data); break; + case rpcn::CommandType::CreateRoom: reply_create_join_room(req_id, data); break; + case rpcn::CommandType::JoinRoom: reply_join_room(req_id, data); break; + case rpcn::CommandType::LeaveRoom: reply_leave_room(req_id, data); break; + case rpcn::CommandType::SearchRoom: reply_search_room(req_id, data); break; + case rpcn::CommandType::GetRoomDataExternalList: reply_get_roomdata_external_list(req_id, data); break; + case rpcn::CommandType::SetRoomDataExternal: reply_set_roomdata_external(req_id, data); break; + case rpcn::CommandType::GetRoomDataInternal: reply_get_roomdata_internal(req_id, data); break; + case rpcn::CommandType::SetRoomDataInternal: reply_set_roomdata_internal(req_id, data); break; + case rpcn::CommandType::PingRoomOwner: reply_get_ping_info(req_id, data); break; + case rpcn::CommandType::SendRoomMessage: reply_send_room_message(req_id, data); break; + case rpcn::CommandType::RequestSignalingInfos: reply_req_sign_infos(req_id, data); break; + case rpcn::CommandType::RequestTicket: reply_req_ticket(req_id, data); break; + default: rpcn_log.error("Unknown reply(%d) received!", command); break; + } + } + + auto notifications = rpcn->get_notifications(); + for (auto& notif : notifications) + { + switch (notif.first) + { + case rpcn::NotificationType::UserJoinedRoom: notif_user_joined_room(notif.second); break; + case rpcn::NotificationType::UserLeftRoom: notif_user_left_room(notif.second); break; + case rpcn::NotificationType::RoomDestroyed: notif_room_destroyed(notif.second); break; + case rpcn::NotificationType::SignalP2PConnect: notif_p2p_connect(notif.second); break; + case rpcn::NotificationType::RoomMessageReceived: notif_room_message_received(notif.second); break; + default: rpcn_log.error("Unknown notification(%d) received!", notif.first); break; + } + } + + auto messages = rpcn->get_new_messages(); + if (basic_handler.registered) + { + for (const auto msg_id : messages) + { + const auto opt_msg = rpcn->get_message(msg_id); + if (!opt_msg) + { + continue; + } + const auto& msg = opt_msg.value(); + if (strncmp(msg->second.commId.data, basic_handler.context.data, sizeof(basic_handler.context.data) - 1) == 0) + { + u32 event; + switch (msg->second.mainType) + { + case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_DATA_ATTACHMENT: + event = SCE_NP_BASIC_EVENT_INCOMING_ATTACHMENT; + break; + case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_INVITE: + event = (msg->second.msgFeatures & SCE_NP_BASIC_MESSAGE_FEATURES_BOOTABLE) ? SCE_NP_BASIC_EVENT_INCOMING_BOOTABLE_INVITATION : SCE_NP_BASIC_EVENT_INCOMING_INVITATION; + break; + case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_CUSTOM_DATA: + event = (msg->second.msgFeatures & SCE_NP_BASIC_MESSAGE_FEATURES_BOOTABLE) ? SCE_NP_BASIC_EVENT_INCOMING_BOOTABLE_CUSTOM_DATA_MESSAGE : SCE_NP_BASIC_EVENT_INCOMING_CUSTOM_DATA_MESSAGE; + break; + case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_GENERAL: + case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_ADD_FRIEND: + case SCE_NP_BASIC_MESSAGE_MAIN_TYPE_URL_ATTACHMENT: + event = SCE_NP_BASIC_EVENT_MESSAGE; + default: + continue; + } + + basic_event to_add{}; + to_add.event = event; + strcpy_trunc(to_add.from.userId.handle.data, msg->first); + strcpy_trunc(to_add.from.name.data, msg->first); + + queue_basic_event(std::move(to_add)); + send_basic_event(event, 0, 0); + } + } + } + + if (!replies.empty() || !notifications.empty()) + { + sleep = false; + } + } + + // TODO: replace with an appropriate semaphore + if (sleep) { thread_ctrl::wait_for(200'000); continue; } - - auto replies = rpcn.get_replies(); - for (auto& reply : replies) - { - const u16 command = reply.second.first; - const u32 req_id = reply.first; - std::vector& data = reply.second.second; - - switch (command) - { - case CommandType::GetWorldList: reply_get_world_list(req_id, data); break; - case CommandType::CreateRoom: reply_create_join_room(req_id, data); break; - case CommandType::JoinRoom: reply_join_room(req_id, data); break; - case CommandType::LeaveRoom: reply_leave_room(req_id, data); break; - case CommandType::SearchRoom: reply_search_room(req_id, data); break; - case CommandType::SetRoomDataExternal: reply_set_roomdata_external(req_id, data); break; - case CommandType::GetRoomDataInternal: reply_get_roomdata_internal(req_id, data); break; - case CommandType::SetRoomDataInternal: reply_set_roomdata_internal(req_id, data); break; - case CommandType::PingRoomOwner: reply_get_ping_info(req_id, data); break; - case CommandType::SendRoomMessage: reply_send_room_message(req_id, data); break; - case CommandType::RequestSignalingInfos: reply_req_sign_infos(req_id, data); break; - case CommandType::RequestTicket: reply_req_ticket(req_id, data); break; - default: rpcn_log.error("Unknown reply(%d) received!", command); break; - } - } - - auto notifications = rpcn.get_notifications(); - for (auto& notif : notifications) - { - switch (notif.first) - { - case NotificationType::UserJoinedRoom: notif_user_joined_room(notif.second); break; - case NotificationType::UserLeftRoom: notif_user_left_room(notif.second); break; - case NotificationType::RoomDestroyed: notif_room_destroyed(notif.second); break; - case NotificationType::SignalP2PConnect: notif_p2p_connect(notif.second); break; - case NotificationType::RoomMessageReceived: notif_room_message_received(notif.second); break; - default: rpcn_log.error("Unknown notification(%d) received!", notif.first); break; - } - } } } bool np_handler::reply_get_world_list(u32 req_id, std::vector& reply_data) { - if (pending_requests.count(req_id) == 0) - return error_and_disconnect("Unexpected reply ID to GetWorldList"); - - const auto cb_info = std::move(pending_requests.at(req_id)); - pending_requests.erase(req_id); + const auto cb_info = take_pending_request(req_id); vec_stream reply(reply_data, 1); @@ -760,21 +898,17 @@ bool np_handler::reply_get_world_list(u32 req_id, std::vector& reply_data) } sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 - { - cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetWorldInfoList, event_key, 0, sizeof(SceNpMatching2GetWorldInfoListResponse), cb_info.cb_arg); - return 0; - }); + { + cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetWorldInfoList, event_key, 0, sizeof(SceNpMatching2GetWorldInfoListResponse), cb_info.cb_arg); + return 0; + }); return true; } bool np_handler::reply_create_join_room(u32 req_id, std::vector& reply_data) { - if (pending_requests.count(req_id) == 0) - return error_and_disconnect("Unexpected reply ID to CreateRoom"); - - const auto cb_info = std::move(pending_requests.at(req_id)); - pending_requests.erase(req_id); + const auto cb_info = take_pending_request(req_id); vec_stream reply(reply_data, 1); auto create_room_resp = reply.get_rawdata(); @@ -795,27 +929,23 @@ bool np_handler::reply_create_join_room(u32 req_id, std::vector& reply_data) // Establish Matching2 self signaling info auto& sigh = g_fxo->get>(); sigh.set_self_sig2_info(room_info->roomId, 1); - sigh.set_sig2_infos(room_info->roomId, 1, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, rpcn.get_addr_sig(), rpcn.get_port_sig(), true); + sigh.set_sig2_infos(room_info->roomId, 1, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, rpcn->get_addr_sig(), rpcn->get_port_sig(), true); // TODO? Should this send a message to Signaling CB? Is this even necessary? extra_nps::print_create_room_resp(room_resp); sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 - { - cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_CreateJoinRoom, event_key, 0, sizeof(SceNpMatching2CreateJoinRoomResponse), cb_info.cb_arg); - return 0; - }); + { + cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_CreateJoinRoom, event_key, 0, sizeof(SceNpMatching2CreateJoinRoomResponse), cb_info.cb_arg); + return 0; + }); return true; } bool np_handler::reply_join_room(u32 req_id, std::vector& reply_data) { - if (pending_requests.count(req_id) == 0) - return error_and_disconnect("Unexpected reply ID to JoinRoom"); - - const auto cb_info = std::move(pending_requests.at(req_id)); - pending_requests.erase(req_id); + const auto cb_info = take_pending_request(req_id); vec_stream reply(reply_data, 1); @@ -839,25 +969,21 @@ bool np_handler::reply_join_room(u32 req_id, std::vector& reply_data) // Establish Matching2 self signaling info auto& sigh = g_fxo->get>(); sigh.set_self_sig2_info(room_info->roomId, member_id); - sigh.set_sig2_infos(room_info->roomId, member_id, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, rpcn.get_addr_sig(), rpcn.get_port_sig(), true); + sigh.set_sig2_infos(room_info->roomId, member_id, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, rpcn->get_addr_sig(), rpcn->get_port_sig(), true); // TODO? Should this send a message to Signaling CB? Is this even necessary? sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 - { - cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_JoinRoom, event_key, 0, sizeof(SceNpMatching2JoinRoomResponse), cb_info.cb_arg); - return 0; - }); + { + cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_JoinRoom, event_key, 0, sizeof(SceNpMatching2JoinRoomResponse), cb_info.cb_arg); + return 0; + }); return true; } bool np_handler::reply_leave_room(u32 req_id, std::vector& reply_data) { - if (pending_requests.count(req_id) == 0) - return error_and_disconnect("Unexpected reply ID to LeaveRoom"); - - const auto cb_info = std::move(pending_requests.at(req_id)); - pending_requests.erase(req_id); + const auto cb_info = take_pending_request(req_id); vec_stream reply(reply_data, 1); u64 room_id = reply.get(); @@ -871,21 +997,17 @@ bool np_handler::reply_leave_room(u32 req_id, std::vector& reply_data) sigh.disconnect_sig2_users(room_id); sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 - { - cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_LeaveRoom, event_key, 0, 0, cb_info.cb_arg); - return 0; - }); + { + cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_LeaveRoom, event_key, 0, 0, cb_info.cb_arg); + return 0; + }); return true; } bool np_handler::reply_search_room(u32 req_id, std::vector& reply_data) { - if (pending_requests.count(req_id) == 0) - return error_and_disconnect("Unexpected reply ID to SearchRoom"); - - const auto cb_info = std::move(pending_requests.at(req_id)); - pending_requests.erase(req_id); + const auto cb_info = take_pending_request(req_id); vec_stream reply(reply_data, 1); auto search_room_resp = reply.get_rawdata(); @@ -897,43 +1019,60 @@ bool np_handler::reply_search_room(u32 req_id, std::vector& reply_data) auto resp = flatbuffers::GetRoot(search_room_resp.data()); SceNpMatching2SearchRoomResponse* search_resp = reinterpret_cast(allocate_req_result(event_key, sizeof(SceNpMatching2SearchRoomResponse))); - SearchRoomReponse_to_SceNpMatching2SearchRoomResponse(resp, search_resp); + SearchRoomResponse_to_SceNpMatching2SearchRoomResponse(resp, search_resp); sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 - { - cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SearchRoom, event_key, 0, sizeof(SceNpMatching2SearchRoomResponse), cb_info.cb_arg); - return 0; - }); + { + cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SearchRoom, event_key, 0, sizeof(SceNpMatching2SearchRoomResponse), cb_info.cb_arg); + return 0; + }); + + return true; +} + +bool np_handler::reply_get_roomdata_external_list(u32 req_id, std::vector& reply_data) +{ + const auto cb_info = take_pending_request(req_id); + + vec_stream reply(reply_data, 1); + auto get_room_ext_resp = reply.get_rawdata(); + if (reply.is_error()) + return error_and_disconnect("Malformed reply to GetRoomDataExternalList command"); + + u32 event_key = get_event_key(); + + auto resp = flatbuffers::GetRoot(get_room_ext_resp.data()); + SceNpMatching2GetRoomDataExternalListResponse* np_get_room_ext_resp = reinterpret_cast(allocate_req_result(event_key, sizeof(SceNpMatching2GetRoomDataExternalListResponse))); + + GetRoomDataExternalListResponse_to_SceNpMatching2GetRoomDataExternalListResponse(resp, np_get_room_ext_resp); + + sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 + { + cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SearchRoom, event_key, 0, sizeof(SceNpMatching2SearchRoomResponse), cb_info.cb_arg); + return 0; + }); return true; } bool np_handler::reply_set_roomdata_external(u32 req_id, std::vector& /*reply_data*/) { - if (pending_requests.count(req_id) == 0) - return error_and_disconnect("Unexpected reply ID to SetRoomDataExternal"); - - const auto cb_info = std::move(pending_requests.at(req_id)); - pending_requests.erase(req_id); + const auto cb_info = take_pending_request(req_id); u32 event_key = get_event_key(); // Unsure if necessary if there is no data sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 - { - cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomDataExternal, event_key, 0, 0, cb_info.cb_arg); - return 0; - }); + { + cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomDataExternal, event_key, 0, 0, cb_info.cb_arg); + return 0; + }); return true; } bool np_handler::reply_get_roomdata_internal(u32 req_id, std::vector& reply_data) { - if (pending_requests.count(req_id) == 0) - return error_and_disconnect("Unexpected reply ID to GetRoomDataInternal"); - - const auto cb_info = std::move(pending_requests.at(req_id)); - pending_requests.erase(req_id); + const auto cb_info = take_pending_request(req_id); vec_stream reply(reply_data, 1); @@ -953,40 +1092,32 @@ bool np_handler::reply_get_roomdata_internal(u32 req_id, std::vector& reply_ extra_nps::print_room_data_internal(room_resp->roomDataInternal.get_ptr()); sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 - { - cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetRoomDataInternal, event_key, 0, sizeof(SceNpMatching2GetRoomDataInternalResponse), cb_info.cb_arg); - return 0; - }); + { + cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetRoomDataInternal, event_key, 0, sizeof(SceNpMatching2GetRoomDataInternalResponse), cb_info.cb_arg); + return 0; + }); return true; } bool np_handler::reply_set_roomdata_internal(u32 req_id, std::vector& /*reply_data*/) { - if (pending_requests.count(req_id) == 0) - return error_and_disconnect("Unexpected reply ID to SetRoomDataInternal"); - - const auto cb_info = std::move(pending_requests.at(req_id)); - pending_requests.erase(req_id); + const auto cb_info = take_pending_request(req_id); u32 event_key = get_event_key(); // Unsure if necessary if there is no data sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 - { - cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomDataInternal, event_key, 0, 0, cb_info.cb_arg); - return 0; - }); + { + cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomDataInternal, event_key, 0, 0, cb_info.cb_arg); + return 0; + }); return true; } bool np_handler::reply_get_ping_info(u32 req_id, std::vector& reply_data) { - if (pending_requests.count(req_id) == 0) - return error_and_disconnect("Unexpected reply ID to PingRoomOwner"); - - const auto cb_info = std::move(pending_requests.at(req_id)); - pending_requests.erase(req_id); + const auto cb_info = take_pending_request(req_id); vec_stream reply(reply_data, 1); @@ -1002,38 +1133,35 @@ bool np_handler::reply_get_ping_info(u32 req_id, std::vector& reply_data) GetPingInfoResponse_to_SceNpMatching2SignalingGetPingInfoResponse(resp, final_ping_resp); sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 - { - cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SignalingGetPingInfo, event_key, 0, sizeof(SceNpMatching2SignalingGetPingInfoResponse), cb_info.cb_arg); - return 0; - }); + { + cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SignalingGetPingInfo, event_key, 0, sizeof(SceNpMatching2SignalingGetPingInfoResponse), cb_info.cb_arg); + return 0; + }); return true; } bool np_handler::reply_send_room_message(u32 req_id, std::vector& /*reply_data*/) { - if (pending_requests.count(req_id) == 0) - return error_and_disconnect("Unexpected reply ID to PingRoomOwner"); - - const auto cb_info = std::move(pending_requests.at(req_id)); - pending_requests.erase(req_id); + const auto cb_info = take_pending_request(req_id); sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 - { - cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SendRoomMessage, 0, 0, 0, cb_info.cb_arg); - return 0; - }); + { + cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SendRoomMessage, 0, 0, 0, cb_info.cb_arg); + return 0; + }); return true; } bool np_handler::reply_req_sign_infos(u32 req_id, std::vector& reply_data) { - if (!pending_sign_infos_requests.count(req_id)) - return error_and_disconnect("Unexpected reply ID to req RequestSignalingInfos"); - - u32 conn_id = pending_sign_infos_requests.at(req_id); - pending_sign_infos_requests.erase(req_id); + u32 conn_id; + { + std::lock_guard lock(mutex_pending_sign_infos_requests); + conn_id = pending_sign_infos_requests.at(req_id); + pending_sign_infos_requests.erase(req_id); + } vec_stream reply(reply_data, 1); u32 addr = reply.get(); @@ -1056,16 +1184,16 @@ bool np_handler::reply_req_ticket(u32 /*req_id*/, std::vector& reply_data) if (reply.is_error()) return error_and_disconnect("Malformed reply to RequestTicket command"); - current_ticket = std::move(ticket_raw); + current_ticket = std::move(ticket_raw); auto ticket_size = static_cast(current_ticket.size()); if (manager_cb) { sysutil_register_cb([manager_cb = this->manager_cb, ticket_size, manager_cb_arg = this->manager_cb_arg](ppu_thread& cb_ppu) -> s32 - { - manager_cb(cb_ppu, SCE_NP_MANAGER_EVENT_GOT_TICKET, ticket_size, manager_cb_arg); - return 0; - }); + { + manager_cb(cb_ppu, SCE_NP_MANAGER_EVENT_GOT_TICKET, ticket_size, manager_cb_arg); + return 0; + }); } return true; @@ -1093,10 +1221,10 @@ void np_handler::notif_user_joined_room(std::vector& data) extra_nps::print_room_member_data_internal(notif_data->roomMemberDataInternal.get_ptr()); sysutil_register_cb([room_event_cb = this->room_event_cb, room_id, event_key, room_event_cb_ctx = this->room_event_cb_ctx, room_event_cb_arg = this->room_event_cb_arg](ppu_thread& cb_ppu) -> s32 - { - room_event_cb(cb_ppu, room_event_cb_ctx, room_id, SCE_NP_MATCHING2_ROOM_EVENT_MemberJoined, event_key, 0, sizeof(SceNpMatching2RoomMemberUpdateInfo), room_event_cb_arg); - return 0; - }); + { + room_event_cb(cb_ppu, room_event_cb_ctx, room_id, SCE_NP_MATCHING2_ROOM_EVENT_MemberJoined, event_key, 0, sizeof(SceNpMatching2RoomMemberUpdateInfo), room_event_cb_arg); + return 0; + }); } void np_handler::notif_user_left_room(std::vector& data) @@ -1121,10 +1249,10 @@ void np_handler::notif_user_left_room(std::vector& data) extra_nps::print_room_member_data_internal(notif_data->roomMemberDataInternal.get_ptr()); sysutil_register_cb([room_event_cb = this->room_event_cb, room_event_cb_ctx = this->room_event_cb_ctx, room_id, event_key, room_event_cb_arg = this->room_event_cb_arg](ppu_thread& cb_ppu) -> s32 - { - room_event_cb(cb_ppu, room_event_cb_ctx, room_id, SCE_NP_MATCHING2_ROOM_EVENT_MemberLeft, event_key, 0, sizeof(SceNpMatching2RoomMemberUpdateInfo), room_event_cb_arg); - return 0; - }); + { + room_event_cb(cb_ppu, room_event_cb_ctx, room_id, SCE_NP_MATCHING2_ROOM_EVENT_MemberLeft, event_key, 0, sizeof(SceNpMatching2RoomMemberUpdateInfo), room_event_cb_arg); + return 0; + }); } void np_handler::notif_room_destroyed(std::vector& data) @@ -1151,10 +1279,10 @@ void np_handler::notif_room_destroyed(std::vector& data) sigh.disconnect_sig2_users(room_id); sysutil_register_cb([room_event_cb = this->room_event_cb, room_event_cb_ctx = this->room_event_cb_ctx, room_id, event_key, room_event_cb_arg = this->room_event_cb_arg](ppu_thread& cb_ppu) -> s32 - { - room_event_cb(cb_ppu, room_event_cb_ctx, room_id, SCE_NP_MATCHING2_ROOM_EVENT_RoomDestroyed, event_key, 0, sizeof(SceNpMatching2RoomUpdateInfo), room_event_cb_arg); - return 0; - }); + { + room_event_cb(cb_ppu, room_event_cb_ctx, room_id, SCE_NP_MATCHING2_ROOM_EVENT_RoomDestroyed, event_key, 0, sizeof(SceNpMatching2RoomUpdateInfo), room_event_cb_arg); + return 0; + }); } void np_handler::notif_p2p_connect(std::vector& data) @@ -1165,10 +1293,10 @@ void np_handler::notif_p2p_connect(std::vector& data) return; } - const u64 room_id = reinterpret_cast&>(data[0]); - const u16 member_id = reinterpret_cast&>(data[8]); - const u16 port_p2p = reinterpret_cast&>(data[10]); - const u32 addr_p2p = reinterpret_cast&>(data[12]); + const u64 room_id = reinterpret_cast&>(data[0]); + const u16 member_id = reinterpret_cast&>(data[8]); + const u16 port_p2p = reinterpret_cast&>(data[10]); + const u32 addr_p2p = reinterpret_cast&>(data[12]); rpcn_log.notice("Received notification to connect to member(%d) of room(%d): %s:%d", member_id, room_id, ip_to_string(addr_p2p), port_p2p); @@ -1193,7 +1321,7 @@ void np_handler::notif_room_message_received(std::vector& data) u32 event_key = get_event_key(); - auto message_info = flatbuffers::GetRoot(message_info_raw.data()); + auto message_info = flatbuffers::GetRoot(message_info_raw.data()); SceNpMatching2RoomMessageInfo* notif_data = reinterpret_cast(allocate_req_result(event_key, sizeof(SceNpMatching2RoomMessageInfo))); RoomMessageInfo_to_SceNpMatching2RoomMessageInfo(message_info, notif_data); @@ -1202,10 +1330,10 @@ void np_handler::notif_room_message_received(std::vector& data) if (room_msg_cb) { sysutil_register_cb([room_msg_cb = this->room_msg_cb, room_msg_cb_ctx = this->room_msg_cb_ctx, room_id, member_id, event_key, room_msg_cb_arg = this->room_msg_cb_arg](ppu_thread& cb_ppu) -> s32 - { - room_msg_cb(cb_ppu, room_msg_cb_ctx, room_id, member_id, SCE_NP_MATCHING2_ROOM_MSG_EVENT_Message, event_key, 0, sizeof(SceNpMatching2RoomUpdateInfo), room_msg_cb_arg); - return 0; - }); + { + room_msg_cb(cb_ppu, room_msg_cb_ctx, room_id, member_id, SCE_NP_MATCHING2_ROOM_MSG_EVENT_Message, event_key, 0, sizeof(SceNpMatching2RoomUpdateInfo), room_msg_cb_arg); + return 0; + }); } } @@ -1338,7 +1466,7 @@ s32 np_handler::analyze_dns_packet(s32 s, const u8* buf, u32 len) bool np_handler::error_and_disconnect(const std::string& error_msg) { rpcn_log.error("%s", error_msg); - rpcn.disconnect(); + rpcn.reset(); return false; } @@ -1358,11 +1486,24 @@ u32 np_handler::generate_callback_info(SceNpMatching2ContextId ctx_id, vm::cptr< nph_log.warning("Callback used is 0x%x", ret.cb); - pending_requests[req_id] = std::move(ret); + { + std::lock_guard lock(mutex_pending_requests); + pending_requests[req_id] = std::move(ret); + } return req_id; } +np_handler::callback_info np_handler::take_pending_request(u32 req_id) +{ + std::lock_guard lock(mutex_pending_requests); + + const auto cb_info = std::move(pending_requests.at(req_id)); + pending_requests.erase(req_id); + + return cb_info; +} + u8* np_handler::allocate_req_result(u32 event_key, usz size) { std::lock_guard lock(mutex_req_results); @@ -1385,3 +1526,13 @@ u32 np_handler::add_players_to_history(vm::cptr /*npids*/, u32 /*count* return req_id; } + +u32 np_handler::get_num_friends() +{ + return rpcn->get_num_friends(); +} + +u32 np_handler::get_num_blocks() +{ + return rpcn->get_num_blocks(); +} diff --git a/rpcs3/Emu/NP/np_handler.h b/rpcs3/Emu/NP/np_handler.h index 8efbeafef9..0a1d466c6e 100644 --- a/rpcs3/Emu/NP/np_handler.h +++ b/rpcs3/Emu/NP/np_handler.h @@ -35,9 +35,10 @@ public: static std::string ip_to_string(u32 addr); static std::string ether_to_string(std::array& ether); // Helpers for setting various structures from string - static void string_to_npid(const std::string&, SceNpId* npid); - static void string_to_online_name(const std::string&, SceNpOnlineName* online_name); - static void string_to_avatar_url(const std::string&, SceNpAvatarUrl* avatar_url); + static void string_to_npid(const std::string& str, SceNpId* npid); + static void string_to_online_name(const std::string& str, SceNpOnlineName* online_name); + static void string_to_avatar_url(const std::string& str, SceNpAvatarUrl* avatar_url); + static void string_to_communication_id(const std::string& str, SceNpCommunicationId* comm_id); // DNS hooking functions void add_dns_spy(u32 sock); @@ -47,16 +48,6 @@ public: std::vector get_dns_packet(u32 sock); s32 analyze_dns_packet(s32 s, const u8* buf, u32 len); - enum NotificationType : u16 - { - UserJoinedRoom, - UserLeftRoom, - RoomDestroyed, - SignalP2PConnect, - _SignalP2PDisconnect, - RoomMessageReceived, - }; - // handles async messages from server(only needed for RPCN) void operator()(); @@ -73,12 +64,28 @@ public: // NP Handlers/Callbacks // Seems to be global - vm::ptr manager_cb{}; // Connection status and tickets + vm::ptr manager_cb{}; // Connection status and tickets vm::ptr manager_cb_arg{}; - // Registered by SceNpCommunicationId - vm::ptr basic_handler; - vm::ptr basic_handler_arg; + // Basic event handler; + struct + { + SceNpCommunicationId context{}; + vm::ptr handler_func; + vm::ptr handler_arg; + bool registered = false; + bool context_sensitive = false; + } basic_handler; + struct basic_event + { + s32 event = 0; + SceNpUserInfo from{}; + std::vector data; + }; + void queue_basic_event(basic_event to_queue); + bool send_basic_event(s32 event, s32 retCode, u32 reqId); + error_code get_basic_event(vm::ptr event, vm::ptr from, vm::ptr data, vm::ptr size); + std::optional>> get_message(u64 id); // Those should probably be under match2 ctx vm::ptr room_event_cb{}; // Room events @@ -98,6 +105,7 @@ public: u32 join_room(SceNpMatching2ContextId ctx_id, vm::cptr optParam, const SceNpMatching2JoinRoomRequest* req); u32 leave_room(SceNpMatching2ContextId ctx_id, vm::cptr optParam, const SceNpMatching2LeaveRoomRequest* req); u32 search_room(SceNpMatching2ContextId ctx_id, vm::cptr optParam, const SceNpMatching2SearchRoomRequest* req); + u32 get_roomdata_external_list(SceNpMatching2ContextId ctx_id, vm::cptr optParam, const SceNpMatching2GetRoomDataExternalListRequest* req); u32 set_roomdata_external(SceNpMatching2ContextId ctx_id, vm::cptr optParam, const SceNpMatching2SetRoomDataExternalRequest* req); u32 get_roomdata_internal(SceNpMatching2ContextId ctx_id, vm::cptr optParam, const SceNpMatching2GetRoomDataInternalRequest* req); u32 set_roomdata_internal(SceNpMatching2ContextId ctx_id, vm::cptr optParam, const SceNpMatching2SetRoomDataInternalRequest* req); @@ -106,9 +114,16 @@ public: u32 get_match2_event(SceNpMatching2EventKey event_key, u8* dest, u32 size); + // Friend stuff + u32 get_num_friends(); + u32 get_num_blocks(); + // Misc stuff - void req_ticket(u32 version, const SceNpId *npid, const char *service_id, const u8 *cookie, u32 cookie_size, const char *entitlement_id, u32 consumed_count); - const std::vector& get_ticket() const { return current_ticket; } + void req_ticket(u32 version, const SceNpId* npid, const char* service_id, const u8* cookie, u32 cookie_size, const char* entitlement_id, u32 consumed_count); + const std::vector& get_ticket() const + { + return current_ticket; + } u32 add_players_to_history(vm::cptr npids, u32 count); // For signaling @@ -119,7 +134,7 @@ public: static constexpr std::string_view thread_name = "NP Handler Thread"; -protected: +private: // Various generic helpers bool discover_ip_address(); bool discover_ether_address(); @@ -138,6 +153,7 @@ protected: bool reply_join_room(u32 req_id, std::vector& reply_data); bool reply_leave_room(u32 req_id, std::vector& reply_data); bool reply_search_room(u32 req_id, std::vector& reply_data); + bool reply_get_roomdata_external_list(u32 req_id, std::vector& reply_data); bool reply_set_roomdata_external(u32 req_id, std::vector& reply_data); bool reply_get_roomdata_internal(u32 req_id, std::vector& reply_data); bool reply_set_roomdata_internal(u32 req_id, std::vector& reply_data); @@ -150,7 +166,9 @@ protected: void BinAttr_to_SceNpMatching2BinAttr(const flatbuffers::Vector>* fb_attr, vm::ptr binattr_info); void RoomGroup_to_SceNpMatching2RoomGroup(const flatbuffers::Vector>* fb_group, vm::ptr group_info); void UserInfo2_to_SceNpUserInfo2(const UserInfo2* user, SceNpUserInfo2* user_info); - void SearchRoomReponse_to_SceNpMatching2SearchRoomResponse(const SearchRoomResponse* resp, SceNpMatching2SearchRoomResponse* search_resp); + void RoomDataExternal_to_SceNpMatching2RoomDataExternal(const RoomDataExternal* room, SceNpMatching2RoomDataExternal* room_info); + void SearchRoomResponse_to_SceNpMatching2SearchRoomResponse(const SearchRoomResponse* resp, SceNpMatching2SearchRoomResponse* search_resp); + void GetRoomDataExternalListResponse_to_SceNpMatching2GetRoomDataExternalListResponse(const GetRoomDataExternalListResponse* resp, SceNpMatching2GetRoomDataExternalListResponse* get_resp); u16 RoomDataInternal_to_SceNpMatching2RoomDataInternal(const RoomDataInternal* resp, SceNpMatching2RoomDataInternal* room_resp, const SceNpId& npid); void RoomMemberUpdateInfo_to_SceNpMatching2RoomMemberUpdateInfo(const RoomMemberUpdateInfo* resp, SceNpMatching2RoomMemberUpdateInfo* room_info); void RoomUpdateInfo_to_SceNpMatching2RoomUpdateInfo(const RoomUpdateInfo* update_info, SceNpMatching2RoomUpdateInfo* sce_update_info); @@ -164,11 +182,17 @@ protected: vm::ptr cb_arg; }; u32 generate_callback_info(SceNpMatching2ContextId ctx_id, vm::cptr optParam); + callback_info take_pending_request(u32 req_id); + shared_mutex mutex_pending_requests; std::unordered_map pending_requests; + shared_mutex mutex_pending_sign_infos_requests; std::unordered_map pending_sign_infos_requests; -protected: + shared_mutex mutex_queue_basic_events; + std::queue queue_basic_events; + +private: bool is_connected = false; bool is_psn_active = false; @@ -213,5 +237,6 @@ protected: u8* allocate_req_result(u32 event_key, usz size); // RPCN - rpcn_client rpcn; + shared_mutex mutex_rpcn; + std::shared_ptr rpcn; }; diff --git a/rpcs3/Emu/NP/rpcn_client.cpp b/rpcs3/Emu/NP/rpcn_client.cpp index f937fc1a86..82bae99f2f 100644 --- a/rpcs3/Emu/NP/rpcn_client.cpp +++ b/rpcs3/Emu/NP/rpcn_client.cpp @@ -10,6 +10,7 @@ #include "Utilities/Thread.h" #include "Emu/IdManager.h" #include "Emu/System.h" +#include "Emu/NP/rpcn_config.h" #include "util/asm.hpp" @@ -34,1011 +35,1408 @@ LOG_CHANNEL(rpcn_log, "rpcn"); -#define RPCN_PROTOCOL_VERSION 10 -#define RPCN_HEADER_SIZE 9 -#define COMMUNICATION_ID_SIZE 9 - -rpcn_client::rpcn_client(bool in_config) - : in_config(in_config) -{ -#ifdef _WIN32 - WSADATA wsa_data; - WSAStartup(MAKEWORD(2, 2), &wsa_data); -#endif -} - -rpcn_client::~rpcn_client() -{ - disconnect(); -} - -std::string rpcn_client::get_wolfssl_error(int error) const -{ - char error_string[80]{}; - const auto wssl_err = wolfSSL_get_error(wssl, error); - wolfSSL_ERR_error_string(wssl_err, &error_string[0]); - return std::string(error_string); -} - -void rpcn_client::disconnect() -{ - std::lock_guard lock(mutex_socket); - - if (wssl) - { - wolfSSL_free(wssl); - wssl = nullptr; - } - - if (wssl_ctx) - { - wolfSSL_CTX_free(wssl_ctx); - wssl_ctx = nullptr; - } - - wolfSSL_Cleanup(); - - if (sockfd) - { -#ifdef _WIN32 - ::closesocket(sockfd); -#else - ::close(sockfd); -#endif - sockfd = 0; - } - - connected = false; - authentified = false; - server_info_received = false; -} - -rpcn_client::recvn_result rpcn_client::recvn(u8* buf, usz n) -{ - u32 num_timeouts = 0; - - usz n_recv = 0; - while (n_recv != n && !is_abort()) - { - std::lock_guard lock(mutex_socket); - - if (!connected) - return recvn_result::recvn_noconn; - - int res = wolfSSL_read(wssl, reinterpret_cast(buf) + n_recv, n - n_recv); - if (res <= 0) - { - if (wolfSSL_want_read(wssl)) - { - // If we received partially what we want try to wait longer - if (n_recv == 0) - return recvn_result::recvn_nodata; - - num_timeouts++; - if (num_timeouts >= 1000) - { - rpcn_log.error("recvn timeout with %d bytes received", n_recv); - return recvn_result::recvn_timeout; - } - } - else - { - rpcn_log.error("recvn failed with error: %s", get_wolfssl_error(res)); - return recvn_result::recvn_fatal; - } - - res = 0; - } - n_recv += res; - } - - return recvn_result::recvn_success; -} - -bool rpcn_client::send_packet(const std::vector& packet) -{ - u32 num_timeouts = 0; - usz n_sent = 0; - while (n_sent != packet.size()) - { - std::lock_guard lock(mutex_socket); - - if (!connected) - return false; - - int res = wolfSSL_write(wssl, reinterpret_cast(packet.data()), packet.size()); - if (res <= 0) - { - if (wolfSSL_want_write(wssl)) - { - num_timeouts++; - if (num_timeouts >= 1000) - { - rpcn_log.error("send_packet timeout with %d bytes sent", n_sent); - return error_and_disconnect("Failed to send all the bytes"); - } - } - else - { - rpcn_log.error("send_packet failed with error: %s", get_wolfssl_error(res)); - return error_and_disconnect("Failed to send all the bytes"); - } - - res = 0; - } - n_sent += res; - } - - return true; -} - -bool rpcn_client::forge_send(u16 command, u32 packet_id, const std::vector& data) -{ - const auto sent_packet = forge_request(command, packet_id, data); - if (!send_packet(sent_packet)) - return false; - - return true; -} - -bool rpcn_client::forge_send_reply(u16 command, u32 packet_id, const std::vector& data, std::vector& reply_data) -{ - if (!forge_send(command, packet_id, data)) - return false; - - if (!get_reply(packet_id, reply_data)) - return false; - - if (is_error(static_cast(reply_data[0]))) - { - disconnect(); - return false; - } - - return true; -} - -bool rpcn_client::connect(const std::string& host) -{ - rpcn_log.warning("Attempting to connect to RPCN!"); - - // Cleans previous data if any - disconnect(); - - { - std::lock_guard lock(mutex_socket); - - if (wolfSSL_Init() != WOLFSSL_SUCCESS) - { - rpcn_log.fatal("Failed to initialize wolfssl"); - return false; - } - - if ((wssl_ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == nullptr) - { - rpcn_log.fatal("Failed to create wolfssl context"); - return false; - } - - wolfSSL_CTX_set_verify(wssl_ctx, SSL_VERIFY_NONE, nullptr); - - if ((wssl = wolfSSL_new(wssl_ctx)) == nullptr) - { - rpcn_log.fatal("Failed to create wolfssl object"); - return false; - } - - memset(&addr_rpcn, 0, sizeof(addr_rpcn)); - - addr_rpcn.sin_port = std::bit_cast>(31313); // htons - addr_rpcn.sin_family = AF_INET; - auto splithost = fmt::split(host, {":"}); - - if (splithost.size() != 1 && splithost.size() != 2) - { - rpcn_log.fatal("RPCN host is invalid!"); - return false; - } - - if (splithost.size() == 2) - addr_rpcn.sin_port = std::bit_cast>(std::stoul(splithost[1])); // htons - - hostent* host_addr = gethostbyname(splithost[0].c_str()); - if (!host_addr) - { - rpcn_log.fatal("Failed to resolve %s", splithost[0]); - return false; - } - - addr_rpcn.sin_addr.s_addr = *reinterpret_cast(host_addr->h_addr_list[0]); - - memcpy(&addr_rpcn_udp, &addr_rpcn, sizeof(addr_rpcn_udp)); - addr_rpcn_udp.sin_port = std::bit_cast>(3657); // htons - - sockfd = socket(AF_INET, SOCK_STREAM, 0); - -#ifdef _WIN32 - u32 timeout = 5; -#else - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 5000; -#endif - - if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast(&timeout), sizeof(timeout)) < 0) - { - rpcn_log.fatal("Failed to setsockopt!"); - return false; - } - - if (::connect(sockfd, reinterpret_cast(&addr_rpcn), sizeof(addr_rpcn)) != 0) - { - rpcn_log.fatal("Failed to connect to RPCN server!"); - return false; - } - - if (wolfSSL_set_fd(wssl, sockfd) != WOLFSSL_SUCCESS) - { - rpcn_log.fatal("Failed to associate wolfssl to the socket"); - return false; - } - - int ret_connect; - while((ret_connect = wolfSSL_connect(wssl)) != SSL_SUCCESS) - { - if(wolfSSL_want_read(wssl)) - continue; - - rpcn_log.fatal("Handshake failed with RPCN Server: %s", get_wolfssl_error(ret_connect)); - return false; - } - } - - connected = true; - - while (!server_info_received && connected && !is_abort()) - { - if (in_config) - std::this_thread::sleep_for(5ms); - else - thread_ctrl::wait_for(5000); - } - - if (received_version != RPCN_PROTOCOL_VERSION) - { - rpcn_log.fatal("Server returned protocol version: %d, expected: %d", received_version, RPCN_PROTOCOL_VERSION); - disconnect(); - return false; - } - - last_ping_time = steady_clock::now() - 5s; - last_pong_time = last_ping_time; - - return true; -} - -bool rpcn_client::login(const std::string& npid, const std::string& password, const std::string& token) -{ - std::vector data{}; - std::copy(npid.begin(), npid.end(), std::back_inserter(data)); - data.push_back(0); - std::copy(password.begin(), password.end(), std::back_inserter(data)); - data.push_back(0); - std::copy(token.begin(), token.end(), std::back_inserter(data)); - data.push_back(0); - const auto sent_packet = forge_request(CommandType::Login, 1, data); - if (!send_packet(sent_packet)) - return false; - - std::vector packet_data{}; - if (!get_reply(1, packet_data)) - return false; - - vec_stream reply(packet_data); - u8 error = reply.get(); - online_name = reply.get_string(false); - avatar_url = reply.get_string(false); - user_id = reply.get(); - - if (is_error(static_cast(error))) - { - disconnect(); - return false; - } - - if (reply.is_error()) - return error_and_disconnect("Malformed reply to Login command"); - - rpcn_log.success("You are now logged in RPCN(%s | %s)!", npid, online_name); - authentified = true; - - // Make sure signaling works - if (!in_config) - { - auto start = steady_clock::now(); - - while (!get_addr_sig() && steady_clock::now() - start < 5s) - { - std::this_thread::sleep_for(5ms); - } - - if (!get_addr_sig()) - return error_and_disconnect("Failed to get Signaling going with the server!"); - } - - return true; -} - -bool rpcn_client::create_user(const std::string& npid, const std::string& password, const std::string& online_name, const std::string& avatar_url, const std::string& email) -{ - std::vector data{}; - std::copy(npid.begin(), npid.end(), std::back_inserter(data)); - data.push_back(0); - std::copy(password.begin(), password.end(), std::back_inserter(data)); - data.push_back(0); - std::copy(online_name.begin(), online_name.end(), std::back_inserter(data)); - data.push_back(0); - std::copy(avatar_url.begin(), avatar_url.end(), std::back_inserter(data)); - data.push_back(0); - std::copy(email.begin(), email.end(), std::back_inserter(data)); - data.push_back(0); - const auto sent_packet = forge_request(CommandType::Create, 1, data); - if (!send_packet(sent_packet)) - return false; - - std::vector packet_data{}; - if (!get_reply(1, packet_data)) - return false; - - vec_stream reply(packet_data); - u8 error = reply.get(); - - if (is_error(static_cast(error))) - { - disconnect(); - return false; - } - - rpcn_log.success("You have successfully created a RPCN account(%s | %s)!", npid, online_name); - - return true; -} - +// Those are defined here to avoid including sys_net.h s32 send_packet_from_p2p_port(const std::vector& data, const sockaddr_in& addr); std::vector> get_rpcn_msgs(); -bool rpcn_client::manage_connection() +namespace rpcn { - if (!connected) - return false; - if (authentified && !in_config) + constexpr u32 RPCN_PROTOCOL_VERSION = 13; + constexpr usz RPCN_HEADER_SIZE = 13; + constexpr usz COMMUNICATION_ID_SIZE = 9; + + // Constructor, destructor & singleton manager + + rpcn_client::rpcn_client() + : sem_connected(0), sem_authentified(0), sem_reader(0), sem_writer(0), sem_rpcn(0), + thread_rpcn(std::thread(&rpcn_client::rpcn_thread, this)), thread_rpcn_reader(std::thread(&rpcn_client::rpcn_reader_thread, this)), + thread_rpcn_writer(std::thread(&rpcn_client::rpcn_writer_thread, this)) { - // Ping the UDP Signaling Server - auto now = steady_clock::now(); +#ifdef _WIN32 + WSADATA wsa_data; + WSAStartup(MAKEWORD(2, 2), &wsa_data); +#endif + g_cfg_rpcn.load(); - auto rpcn_msgs = get_rpcn_msgs(); + sem_rpcn.release(); + } - for (const auto& msg : rpcn_msgs) + rpcn_client::~rpcn_client() + { + std::lock_guard lock(inst_mutex); + terminate = true; + sem_rpcn.release(); + sem_reader.release(); + sem_writer.release(); + + thread_rpcn.join(); + thread_rpcn_reader.join(); + thread_rpcn_writer.join(); + + disconnect(); + + sem_connected.release(); + sem_authentified.release(); + } + + std::shared_ptr rpcn_client::get_instance() + { + std::shared_ptr sptr; + + std::lock_guard lock(inst_mutex); + sptr = instance.lock(); + if (!sptr) { - if (msg.size() == 6) + sptr = std::shared_ptr(new rpcn_client()); + instance = sptr; + } + + return sptr; + } + + // inform rpcn that the server infos have been updated and signal rpcn_thread to try again + void rpcn_client::server_infos_updated() + { + if (connected) + { + disconnect(); + } + + sem_rpcn.release(); + } + + // RPCN thread + void rpcn_client::rpcn_reader_thread() + { + while (true) + { + sem_reader.acquire(); { - addr_sig = *utils::bless>(&msg[0]); - port_sig = *utils::bless>(&msg[4]); + std::lock_guard lock(mutex_read); + while (true) + { + if (terminate) + { + return; + } - [[maybe_unused]] in_addr orig{}; - orig.s_addr = addr_sig; + if (!handle_input()) + { + break; + } + } + } + } + } - last_pong_time = now; + void rpcn_client::rpcn_writer_thread() + { + while (true) + { + sem_writer.acquire(); + + { + std::lock_guard lock(mutex_write); + + if (terminate) + { + return; + } + + if (!handle_output()) + { + break; + } + } + } + } + + void rpcn_client::rpcn_thread() + { + while (true) + { + sem_rpcn.acquire(); + + while (true) + { + if (terminate) + { + return; + } + + // By default is the object is alive we should be connected + if (!connected) + { + bool result_connect; + { + std::lock_guard lock(mutex_connected); + result_connect = connect(g_cfg_rpcn.get_host()); + } + sem_connected.release(); + + if (!result_connect) + { + break; + } + continue; + } + + if (!authentified) + { + if (want_auth) + { + bool result_login; + { + std::lock_guard lock(mutex_authentified); + result_login = login(g_cfg_rpcn.get_npid(), g_cfg_rpcn.get_password(), g_cfg_rpcn.get_token()); + } + sem_authentified.release(); + + if (!result_login) + { + break; + } + continue; + } + else + { + // Nothing to do while waiting for auth request so wait for main sem + break; + } + } + + if (authentified && !Emu.IsStopped()) + { + // Ping the UDP Signaling Server if we're authentified & ingame + auto now = steady_clock::now(); + + auto rpcn_msgs = get_rpcn_msgs(); + + for (const auto& msg : rpcn_msgs) + { + if (msg.size() == 6) + { + addr_sig = *utils::bless>(&msg[0]); + port_sig = *utils::bless>(&msg[4]); + + last_pong_time = now; + } + else + { + rpcn_log.error("Received faulty RPCN UDP message!"); + } + } + + // Send a packet every 5 seconds and then every 500 ms until reply is received + if (now - last_pong_time >= 5s && now - last_ping_time > 500ms) + { + std::vector ping(9); + ping[0] = 1; + *utils::bless>(&ping[1]) = user_id; + if (send_packet_from_p2p_port(ping, addr_rpcn_udp) == -1) + { + rpcn_log.error("Failed to send ping to rpcn!"); + } + last_ping_time = now; + } + else + { + std::chrono::nanoseconds duration; + if ((now - last_pong_time) < 5s) + { + duration = 5s - (now - last_pong_time); + } + else + { + duration = 500ms - (now - last_ping_time); + } + sem_rpcn.try_acquire_for(duration); + } + } + } + } + } + + bool rpcn_client::handle_input() + { + u8 header[RPCN_HEADER_SIZE]; + auto res_recvn = recvn(header, RPCN_HEADER_SIZE); + + switch (res_recvn) + { + case recvn_result::recvn_noconn: return error_and_disconnect("Disconnected"); + case recvn_result::recvn_fatal: + case recvn_result::recvn_timeout: return error_and_disconnect("Failed to read a packet header on socket"); + case recvn_result::recvn_nodata: return true; + case recvn_result::recvn_success: break; + case recvn_result::recvn_terminate: return error_and_disconnect("Recvn was forcefully aborted"); + } + + const u8 packet_type = header[0]; + const u16 command = *utils::bless>(&header[1]); + const u16 packet_size = *utils::bless>(&header[3]); + const u64 packet_id = *utils::bless>(&header[5]); + + if (packet_size < RPCN_HEADER_SIZE) + return error_and_disconnect("Invalid packet size"); + + std::vector data; + if (packet_size > RPCN_HEADER_SIZE) + { + const u16 data_size = packet_size - RPCN_HEADER_SIZE; + data.resize(data_size); + if (recvn(data.data(), data_size) != recvn_result::recvn_success) + return error_and_disconnect("Failed to receive a whole packet"); + } + + switch (static_cast(packet_type)) + { + case PacketType::Request: return error_and_disconnect("Client shouldn't receive request packets!"); + case PacketType::Reply: + { + if (data.empty()) + return error_and_disconnect("Reply packet without result"); + + // Those commands are handled synchronously and won't be forwarded to NP Handler + if (command == CommandType::Login || command == CommandType::GetServerList || command == CommandType::Create || + command == CommandType::AddFriend || command == CommandType::RemoveFriend || + command == CommandType::AddBlock || command == CommandType::RemoveBlock || command == CommandType::SendMessage) + { + std::lock_guard lock(mutex_replies_sync); + replies_sync.insert(std::make_pair(packet_id, std::make_pair(command, std::move(data)))); } else { - rpcn_log.error("Received faulty RPCN UDP message!"); + if (packet_id < 0x100000000) + { + std::lock_guard lock(mutex_replies); + replies.insert(std::make_pair(static_cast(packet_id), std::make_pair(command, std::move(data)))); + } + else + { + rpcn_log.error("Tried to forward a reply whose packet_id marks it as internal to rpcn"); + } } - } - // Send a packet every 5 seconds and then every 500 ms until reply is received - if (now - last_pong_time > 5s && now - last_ping_time > 500ms) + break; + } + case PacketType::Notification: { - std::vector ping(9); - ping[0] = 1; - *utils::bless>(&ping[1]) = user_id; - if (send_packet_from_p2p_port(ping, addr_rpcn_udp) == -1) + switch (command) { - rpcn_log.error("Failed to send ping to rpcn!"); + case NotificationType::FriendNew: + case NotificationType::FriendLost: + case NotificationType::FriendQuery: + case NotificationType::FriendStatus: + { + handle_friend_notification(command, std::move(data)); + break; } - last_ping_time = now; + case NotificationType::MessageReceived: + { + handle_message(std::move(data)); + break; + } + default: + { + std::lock_guard lock(mutex_notifs); + notifications.emplace_back(std::make_pair(command, std::move(data))); + break; + } + } + break; } - } - - u8 header[RPCN_HEADER_SIZE]; - auto res_recvn = recvn(header, RPCN_HEADER_SIZE); - - switch (res_recvn) - { - case recvn_result::recvn_noconn: return error_and_disconnect("Disconnected"); - case recvn_result::recvn_fatal: - case recvn_result::recvn_timeout: return error_and_disconnect("Failed to read a packet header on socket"); - case recvn_result::recvn_nodata: return false; - case recvn_result::recvn_success: break; - } - - const u8 packet_type = header[0]; - const u16 command = *utils::bless>(&header[1]); - const u16 packet_size = *utils::bless>(&header[3]); - const u32 packet_id = *utils::bless>(&header[5]); - - if (packet_size < RPCN_HEADER_SIZE) - return error_and_disconnect("Invalid packet size"); - - std::vector data{}; - if (packet_size > RPCN_HEADER_SIZE) - { - const u16 data_size = packet_size - RPCN_HEADER_SIZE; - data.resize(data_size); - if (recvn(data.data(), data_size) != recvn_result::recvn_success) - return error_and_disconnect("Failed to receive a whole packet"); - } - - switch (static_cast(packet_type)) - { - case PacketType::Request: return error_and_disconnect("Client shouldn't receive request packets!"); - case PacketType::Reply: - { - if (data.empty()) - return error_and_disconnect("Reply packet without result"); - - // Those commands are handled synchronously and won't be forwarded to NP Handler - if (command == CommandType::Login || command == CommandType::GetServerList || command == CommandType::Create) + case PacketType::ServerInfo: { - std::lock_guard lock(mutex_replies_sync); - replies_sync.insert(std::make_pair(packet_id, std::make_pair(command, std::move(data)))); - } - else - { - std::lock_guard lock(mutex_replies); - replies.insert(std::make_pair(packet_id, std::make_pair(command, std::move(data)))); + if (data.size() != 4) + return error_and_disconnect("Invalid size of ServerInfo packet"); + + received_version = reinterpret_cast&>(data[0]); + server_info_received = true; + break; } - break; + default: return error_and_disconnect("Unknown packet received!"); + } + + return true; } - case PacketType::Notification: + + void rpcn_client::add_packet(const std::vector packet) { - std::lock_guard lock(mutex_notifs); - notifications.emplace_back(std::make_pair(command, std::move(data))); - break; + std::lock_guard lock(mutex_packets_to_send); + packets_to_send.push_back(std::move(packet)); + sem_writer.release(); } - case PacketType::ServerInfo: + + bool rpcn_client::handle_output() { - if (data.size() != 4) - return error_and_disconnect("Invalid size of ServerInfo packet"); - - received_version = reinterpret_cast&>(data[0]); - server_info_received = true; - break; - } - - default: return error_and_disconnect("Unknown packet received!"); - } - - return true; -} - -std::vector>> rpcn_client::get_notifications() -{ - std::vector>> notifs; - - { - std::lock_guard lock(mutex_notifs); - notifs = std::move(notifications); - notifications.clear(); - } - - return notifs; -} - -std::unordered_map>> rpcn_client::get_replies() -{ - std::unordered_map>> ret_replies; - - { - std::lock_guard lock(mutex_replies); - ret_replies = std::move(replies); - replies.clear(); - } - - return ret_replies; -} - -bool rpcn_client::get_reply(const u32 expected_id, std::vector& data) -{ - auto check_for_reply = [this, expected_id, &data]() -> bool - { - std::lock_guard lock(mutex_replies_sync); - if (auto r = replies_sync.find(expected_id); r != replies_sync.end()) + std::vector> packets; { - data = std::move(r->second.second); - replies_sync.erase(r); + std::lock_guard lock(mutex_packets_to_send); + packets = std::move(packets_to_send); + packets_to_send.clear(); + } + + for (const auto& packet : packets) + { + if (!send_packet(packet)) + { + return false; + } + } + + return true; + } + + // WolfSSL operations + + std::string rpcn_client::get_wolfssl_error(WOLFSSL* wssl, int error) const + { + char error_string[WOLFSSL_MAX_ERROR_SZ]{}; + const auto wssl_err = wolfSSL_get_error(wssl, error); + wolfSSL_ERR_error_string(wssl_err, &error_string[0]); + return std::string(error_string); + } + + rpcn_client::recvn_result rpcn_client::recvn(u8* buf, usz n) + { + u32 num_timeouts = 0; + + usz n_recv = 0; + while (n_recv != n) + { + if (!connected) + return recvn_result::recvn_noconn; + + if (terminate) + return recvn_result::recvn_terminate; + + int res = wolfSSL_read(read_wssl, reinterpret_cast(buf) + n_recv, n - n_recv); + if (res <= 0) + { + if (wolfSSL_want_read(read_wssl)) + { + // If we received partially what we want try to wait longer + if (n_recv == 0) + return recvn_result::recvn_nodata; + + num_timeouts++; + if (num_timeouts >= 1000) + { + rpcn_log.error("recvn timeout with %d bytes received", n_recv); + return recvn_result::recvn_timeout; + } + } + else + { + if (res == 0) + { + // Remote closed connection + return recvn_result::recvn_noconn; + } + + rpcn_log.error("recvn failed with error: %d:%s", res, get_wolfssl_error(read_wssl, res)); + return recvn_result::recvn_fatal; + } + + res = 0; + } + n_recv += res; + } + + return recvn_result::recvn_success; + } + + bool rpcn_client::send_packet(const std::vector& packet) + { + u32 num_timeouts = 0; + usz n_sent = 0; + while (n_sent != packet.size()) + { + if (!connected) + return false; + + int res = wolfSSL_write(write_wssl, reinterpret_cast(packet.data()), packet.size()); + if (res <= 0) + { + if (wolfSSL_want_write(write_wssl)) + { + num_timeouts++; + if (num_timeouts >= 1000) + { + rpcn_log.error("send_packet timeout with %d bytes sent", n_sent); + return error_and_disconnect("Failed to send all the bytes"); + } + } + else + { + rpcn_log.error("send_packet failed with error: %s", get_wolfssl_error(write_wssl, res)); + return error_and_disconnect("Failed to send all the bytes"); + } + + res = 0; + } + n_sent += res; + } + + return true; + } + + // Helper functions + + bool rpcn_client::forge_send(u16 command, u64 packet_id, const std::vector& data) + { + // TODO: add a check for status? + + const auto sent_packet = forge_request(command, packet_id, data); + add_packet(std::move(sent_packet)); + return true; + } + + bool rpcn_client::forge_send_reply(u16 command, u64 packet_id, const std::vector& data, std::vector& reply_data) + { + if (!forge_send(command, packet_id, data)) + return false; + + if (!get_reply(packet_id, reply_data)) + return false; + + if (is_error(static_cast(reply_data[0]))) + { + // disconnect(); + return false; + } + + return true; + } + + // Connect & disconnect functions + + void rpcn_client::disconnect() + { + if (read_wssl) + { + wolfSSL_free(read_wssl); + read_wssl = nullptr; + } + + if (write_wssl) + { + wolfSSL_free(write_wssl); + write_wssl = nullptr; + } + + if (wssl_ctx) + { + wolfSSL_CTX_free(wssl_ctx); + wssl_ctx = nullptr; + } + + wolfSSL_Cleanup(); + + if (sockfd) + { +#ifdef _WIN32 + ::closesocket(sockfd); +#else + ::close(sockfd); +#endif + sockfd = 0; + } + + connected = false; + authentified = false; + want_auth = false; + server_info_received = false; + } + + bool rpcn_client::connect(const std::string& host) + { + rpcn_log.warning("Attempting to connect to RPCN!"); + + state = rpcn_state::failure_no_failure; + + if (host.empty()) + { + rpcn_log.error("RPCN host is empty!"); + state = rpcn_state::failure_input; + return false; + } + + auto splithost = fmt::split(host, {":"}); + if (splithost.size() != 1 && splithost.size() != 2) + { + rpcn_log.error("RPCN host is invalid!"); + state = rpcn_state::failure_input; + return false; + } + + u16 port = 31313; + + if (splithost.size() == 2) + { + port = std::stoul(splithost[1]); + if (port == 0) + { + rpcn_log.error("RPCN port is invalid!"); + state = rpcn_state::failure_input; + return false; + } + } + + { + // Ensures both read & write threads are in waiting state + std::lock_guard lock_read(mutex_read), lock_write(mutex_write); + + // Cleans previous data if any + disconnect(); + + if (wolfSSL_Init() != WOLFSSL_SUCCESS) + { + rpcn_log.error("Failed to initialize wolfssl"); + state = rpcn_state::failure_wolfssl; + return false; + } + + if ((wssl_ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == nullptr) + { + rpcn_log.error("Failed to create wolfssl context"); + state = rpcn_state::failure_wolfssl; + return false; + } + + wolfSSL_CTX_set_verify(wssl_ctx, SSL_VERIFY_NONE, nullptr); + + if ((read_wssl = wolfSSL_new(wssl_ctx)) == nullptr) + { + rpcn_log.error("Failed to create wolfssl object"); + state = rpcn_state::failure_wolfssl; + return false; + } + + memset(&addr_rpcn, 0, sizeof(addr_rpcn)); + + addr_rpcn.sin_port = std::bit_cast>(port); // htons + addr_rpcn.sin_family = AF_INET; + + hostent* host_addr = gethostbyname(splithost[0].c_str()); + if (!host_addr) + { + rpcn_log.error("Failed to resolve %s", host); + state = rpcn_state::failure_resolve; + return false; + } + + addr_rpcn.sin_addr.s_addr = *reinterpret_cast(host_addr->h_addr_list[0]); + + memcpy(&addr_rpcn_udp, &addr_rpcn, sizeof(addr_rpcn_udp)); + addr_rpcn_udp.sin_port = std::bit_cast>(3657); // htons + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + +#ifdef _WIN32 + u32 timeout = 5; +#else + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 50000; // 50ms +#endif + + if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast(&timeout), sizeof(timeout)) < 0) + { + rpcn_log.error("Failed to setsockopt!"); + state = rpcn_state::failure_other; + return false; + } + + if (::connect(sockfd, reinterpret_cast(&addr_rpcn), sizeof(addr_rpcn)) != 0) + { + rpcn_log.error("Failed to connect to RPCN server!"); + state = rpcn_state::failure_connect; + return false; + } + + if (wolfSSL_set_fd(read_wssl, sockfd) != WOLFSSL_SUCCESS) + { + rpcn_log.error("Failed to associate wolfssl to the socket"); + state = rpcn_state::failure_wolfssl; + return false; + } + + int ret_connect; + while ((ret_connect = wolfSSL_connect(read_wssl)) != SSL_SUCCESS) + { + if (wolfSSL_want_read(read_wssl)) + continue; + + state = rpcn_state::failure_wolfssl; + rpcn_log.error("Handshake failed with RPCN Server: %s", get_wolfssl_error(read_wssl, ret_connect)); + return false; + } + + if ((write_wssl = wolfSSL_write_dup(read_wssl)) == NULL) + { + rpcn_log.error("Failed to create write dup for SSL"); + state = rpcn_state::failure_wolfssl; + return false; + } + } + + connected = true; + // Wake up both read & write threads + sem_reader.release(); + sem_writer.release(); + + while (!server_info_received && connected && !terminate) + { + std::this_thread::sleep_for(5ms); + } + + if (!connected || terminate) + { + state = rpcn_state::failure_other; return true; } - return false; - }; - while (connected && !is_abort()) + if (received_version != RPCN_PROTOCOL_VERSION) + { + state = rpcn_state::failure_protocol; + rpcn_log.error("Server returned protocol version: %d, expected: %d", received_version, RPCN_PROTOCOL_VERSION); + return false; + } + + last_ping_time = steady_clock::now() - 5s; + last_pong_time = last_ping_time; + + return true; + } + + bool rpcn_client::login(const std::string& npid, const std::string& password, const std::string& token) { + if (npid.empty() || password.empty()) + { + return false; + } + + std::vector data; + std::copy(npid.begin(), npid.end(), std::back_inserter(data)); + data.push_back(0); + std::copy(password.begin(), password.end(), std::back_inserter(data)); + data.push_back(0); + std::copy(token.begin(), token.end(), std::back_inserter(data)); + data.push_back(0); + + u64 req_id = rpcn_request_counter.fetch_add(1); + + std::vector packet_data; + if (!forge_send_reply(CommandType::Login, req_id, data, packet_data)) + { + return false; + } + + vec_stream reply(packet_data); + auto error = static_cast(reply.get()); + online_name = reply.get_string(false); + avatar_url = reply.get_string(false); + user_id = reply.get(); + + auto get_usernames_and_status = [](vec_stream& stream, std::map>& friends) + { + u32 num_friends = stream.get(); + for (u32 i = 0; i < num_friends; i++) + { + std::string friend_name = stream.get_string(false); + bool online = !!(stream.get()); + friends.insert(std::make_pair(std::move(friend_name), std::make_pair(online, 0))); + } + }; + + auto get_usernames = [](vec_stream& stream, std::set& usernames) + { + u32 num_usernames = stream.get(); + for (u32 i = 0; i < num_usernames; i++) + { + std::string username = stream.get_string(false); + usernames.insert(std::move(username)); + } + }; + + get_usernames_and_status(reply, friend_infos.friends); + get_usernames(reply, friend_infos.requests_sent); + get_usernames(reply, friend_infos.requests_received); + get_usernames(reply, friend_infos.blocked); + + if (is_error(error)) + { + switch (error) + { + case LoginError: state = rpcn_state::failure_id; break; + case LoginAlreadyLoggedIn: state = rpcn_state::failure_id_already_logged_in; break; + case LoginInvalidUsername: state = rpcn_state::failure_id_username; break; + case LoginInvalidPassword: state = rpcn_state::failure_id_password; break; + case LoginInvalidToken: state = rpcn_state::failure_id_token; break; + default: state = rpcn_state::failure_id; break; + } + + disconnect(); + return false; + } + + if (reply.is_error()) + return error_and_disconnect("Malformed reply to Login command"); + + rpcn_log.success("You are now logged in RPCN(%s | %s)!", npid, online_name); + authentified = true; + + return true; + } + + ErrorType rpcn_client::create_user(const std::string& npid, const std::string& password, const std::string& online_name, const std::string& avatar_url, const std::string& email) + { + std::vector data; + std::copy(npid.begin(), npid.end(), std::back_inserter(data)); + data.push_back(0); + std::copy(password.begin(), password.end(), std::back_inserter(data)); + data.push_back(0); + std::copy(online_name.begin(), online_name.end(), std::back_inserter(data)); + data.push_back(0); + std::copy(avatar_url.begin(), avatar_url.end(), std::back_inserter(data)); + data.push_back(0); + std::copy(email.begin(), email.end(), std::back_inserter(data)); + data.push_back(0); + + u64 req_id = rpcn_request_counter.fetch_add(1); + + std::vector packet_data; + if (!forge_send_reply(CommandType::Create, req_id, data, packet_data)) + { + return ErrorType::CreationError; + } + + vec_stream reply(packet_data); + auto error = static_cast(reply.get()); + + if (is_error(error)) + { + return error; + } + + rpcn_log.success("You have successfully created a RPCN account(%s | %s)!", npid, online_name); + + return ErrorType::NoError; + } + + bool rpcn_client::add_friend(const std::string& friend_username) + { + std::vector data; + std::copy(friend_username.begin(), friend_username.end(), std::back_inserter(data)); + data.push_back(0); + + u64 req_id = rpcn_request_counter.fetch_add(1); + + std::vector packet_data; + if (!forge_send_reply(CommandType::AddFriend, req_id, data, packet_data)) + { + return false; + } + + vec_stream reply(packet_data); + auto error = static_cast(reply.get()); + + if (error == ErrorType::NotFound) + { + return false; + } + + rpcn_log.success("You have successfully added \"%s\" as a friend", friend_username); + return true; + } + + bool rpcn_client::remove_friend(const std::string& friend_username) + { + std::vector data; + std::copy(friend_username.begin(), friend_username.end(), std::back_inserter(data)); + data.push_back(0); + + u64 req_id = rpcn_request_counter.fetch_add(1); + + std::vector packet_data; + if (!forge_send_reply(CommandType::RemoveFriend, req_id, data, packet_data)) + { + return false; + } + + vec_stream reply(packet_data); + auto error = static_cast(reply.get()); + + if (is_error(error)) + { + return false; + } + + rpcn_log.success("You have successfully removed \"%s\" from your friendlist", friend_username); + return true; + } + + std::vector>> rpcn_client::get_notifications() + { + std::vector>> notifs; + + { + std::lock_guard lock(mutex_notifs); + notifs = std::move(notifications); + notifications.clear(); + } + + return notifs; + } + + std::unordered_map>> rpcn_client::get_replies() + { + std::unordered_map>> ret_replies; + + { + std::lock_guard lock(mutex_replies); + ret_replies = std::move(replies); + replies.clear(); + } + + return ret_replies; + } + + std::vector rpcn_client::get_new_messages() + { + std::vector ret_new_messages; + { + std::lock_guard lock(mutex_messages); + ret_new_messages = std::move(new_messages); + new_messages.clear(); + } + + return ret_new_messages; + } + + bool rpcn_client::get_reply(const u64 expected_id, std::vector& data) + { + auto check_for_reply = [this, expected_id, &data]() -> bool + { + std::lock_guard lock(mutex_replies_sync); + if (auto r = replies_sync.find(expected_id); r != replies_sync.end()) + { + data = std::move(r->second.second); + replies_sync.erase(r); + return true; + } + return false; + }; + + while (connected && !terminate) + { + if (check_for_reply()) + return true; + + std::this_thread::sleep_for(5ms); + } + if (check_for_reply()) return true; - if (in_config) - std::this_thread::sleep_for(5ms); - else - thread_ctrl::wait_for(5000); - } - - if (check_for_reply()) - return true; - - return false; -} - -bool rpcn_client::get_server_list(u32 req_id, const SceNpCommunicationId& communication_id, std::vector& server_list) -{ - std::vector data(COMMUNICATION_ID_SIZE), reply_data{}; - memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); - - if (!forge_send_reply(CommandType::GetServerList, req_id, data, reply_data)) return false; - - vec_stream reply(reply_data, 1); - u16 num_servs = reply.get(); - server_list.clear(); - for (u16 i = 0; i < num_servs; i++) - { - server_list.push_back(reply.get()); } - if (reply.is_error()) + bool rpcn_client::get_server_list(u32 req_id, const SceNpCommunicationId& communication_id, std::vector& server_list) { + std::vector data(COMMUNICATION_ID_SIZE), reply_data; + memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); + + if (!forge_send_reply(CommandType::GetServerList, req_id, data, reply_data)) + return false; + + vec_stream reply(reply_data, 1); + u16 num_servs = reply.get(); server_list.clear(); - return error_and_disconnect("Malformed reply to GetServerList command"); - } - - return true; -} - -bool rpcn_client::get_world_list(u32 req_id, const SceNpCommunicationId& communication_id, u16 server_id) -{ - std::vector data(COMMUNICATION_ID_SIZE + sizeof(u16)); - memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); - reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = server_id; - - if (!forge_send(CommandType::GetWorldList, req_id, data)) - return false; - - return true; -} - -bool rpcn_client::createjoin_room(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2CreateJoinRoomRequest* req) -{ - std::vector data{}; - - extra_nps::print_createjoinroom(req); - - flatbuffers::FlatBufferBuilder builder(1024); - - flatbuffers::Offset>> final_binattrinternal_vec; - if (req->roomBinAttrInternalNum) - { - std::vector> davec; - for (u32 i = 0; i < req->roomBinAttrInternalNum; i++) + for (u16 i = 0; i < num_servs; i++) { - auto bin = CreateBinAttr(builder, req->roomBinAttrInternal[i].id, builder.CreateVector(req->roomBinAttrInternal[i].ptr.get_ptr(), req->roomBinAttrInternal[i].size)); - davec.push_back(bin); + server_list.push_back(reply.get()); } - final_binattrinternal_vec = builder.CreateVector(davec); - } - flatbuffers::Offset>> final_searchintattrexternal_vec; - if (req->roomSearchableIntAttrExternalNum) - { - std::vector> davec; - for (u32 i = 0; i < req->roomSearchableIntAttrExternalNum; i++) + + if (reply.is_error()) { - auto bin = CreateIntAttr(builder, req->roomSearchableIntAttrExternal[i].id, req->roomSearchableIntAttrExternal[i].num); - davec.push_back(bin); + server_list.clear(); + return error_and_disconnect("Malformed reply to GetServerList command"); } - final_searchintattrexternal_vec = builder.CreateVector(davec); + + return true; } - flatbuffers::Offset>> final_searchbinattrexternal_vec; - if (req->roomSearchableBinAttrExternalNum) + + bool rpcn_client::get_world_list(u32 req_id, const SceNpCommunicationId& communication_id, u16 server_id) { - std::vector> davec; - for (u32 i = 0; i < req->roomSearchableBinAttrExternalNum; i++) + std::vector data(COMMUNICATION_ID_SIZE + sizeof(u16)); + memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); + reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = server_id; + + if (!forge_send(CommandType::GetWorldList, req_id, data)) + return false; + + return true; + } + + bool rpcn_client::createjoin_room(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2CreateJoinRoomRequest* req) + { + std::vector data; + + extra_nps::print_createjoinroom(req); + + flatbuffers::FlatBufferBuilder builder(1024); + + flatbuffers::Offset>> final_binattrinternal_vec; + if (req->roomBinAttrInternalNum) { - auto bin = CreateBinAttr(builder, req->roomSearchableBinAttrExternal[i].id, builder.CreateVector(req->roomSearchableBinAttrExternal[i].ptr.get_ptr(), req->roomSearchableBinAttrExternal[i].size)); - davec.push_back(bin); + std::vector> davec; + for (u32 i = 0; i < req->roomBinAttrInternalNum; i++) + { + auto bin = CreateBinAttr(builder, req->roomBinAttrInternal[i].id, builder.CreateVector(req->roomBinAttrInternal[i].ptr.get_ptr(), req->roomBinAttrInternal[i].size)); + davec.push_back(bin); + } + final_binattrinternal_vec = builder.CreateVector(davec); } - final_searchbinattrexternal_vec = builder.CreateVector(davec); - } - flatbuffers::Offset>> final_binattrexternal_vec; - if (req->roomBinAttrExternalNum) - { - std::vector> davec; - for (u32 i = 0; i < req->roomBinAttrExternalNum; i++) + flatbuffers::Offset>> final_searchintattrexternal_vec; + if (req->roomSearchableIntAttrExternalNum) { - auto bin = CreateBinAttr(builder, req->roomBinAttrExternal[i].id, builder.CreateVector(req->roomBinAttrExternal[i].ptr.get_ptr(), req->roomBinAttrExternal[i].size)); - davec.push_back(bin); + std::vector> davec; + for (u32 i = 0; i < req->roomSearchableIntAttrExternalNum; i++) + { + auto bin = CreateIntAttr(builder, req->roomSearchableIntAttrExternal[i].id, req->roomSearchableIntAttrExternal[i].num); + davec.push_back(bin); + } + final_searchintattrexternal_vec = builder.CreateVector(davec); } - final_binattrexternal_vec = builder.CreateVector(davec); - } - flatbuffers::Offset> final_roompassword; - if (req->roomPassword) - final_roompassword = builder.CreateVector(req->roomPassword->data, 8); - flatbuffers::Offset>> final_groupconfigs_vec; - if (req->groupConfigNum) - { - std::vector> davec; - for (u32 i = 0; i < req->groupConfigNum; i++) + flatbuffers::Offset>> final_searchbinattrexternal_vec; + if (req->roomSearchableBinAttrExternalNum) { - auto bin = CreateGroupConfig(builder, req->groupConfig[i].slotNum, req->groupConfig[i].withLabel, builder.CreateVector(req->groupConfig[i].label.data, 8), req->groupConfig[i].withPassword); - davec.push_back(bin); + std::vector> davec; + for (u32 i = 0; i < req->roomSearchableBinAttrExternalNum; i++) + { + auto bin = CreateBinAttr(builder, req->roomSearchableBinAttrExternal[i].id, builder.CreateVector(req->roomSearchableBinAttrExternal[i].ptr.get_ptr(), req->roomSearchableBinAttrExternal[i].size)); + davec.push_back(bin); + } + final_searchbinattrexternal_vec = builder.CreateVector(davec); } - final_groupconfigs_vec = builder.CreateVector(davec); - } - flatbuffers::Offset>> final_allowedusers_vec; - if (req->allowedUserNum && req->allowedUser) - { - std::vector> davec; - for (u32 i = 0; i < req->allowedUserNum; i++) + flatbuffers::Offset>> final_binattrexternal_vec; + if (req->roomBinAttrExternalNum) { - auto bin = builder.CreateString(req->allowedUser[i].handle.data); - davec.push_back(bin); + std::vector> davec; + for (u32 i = 0; i < req->roomBinAttrExternalNum; i++) + { + auto bin = CreateBinAttr(builder, req->roomBinAttrExternal[i].id, builder.CreateVector(req->roomBinAttrExternal[i].ptr.get_ptr(), req->roomBinAttrExternal[i].size)); + davec.push_back(bin); + } + final_binattrexternal_vec = builder.CreateVector(davec); } - final_allowedusers_vec = builder.CreateVector(davec); - } - flatbuffers::Offset>> final_blockedusers_vec; - if (req->blockedUserNum) - { - std::vector> davec; - for (u32 i = 0; i < req->blockedUserNum; i++) + flatbuffers::Offset> final_roompassword; + if (req->roomPassword) + final_roompassword = builder.CreateVector(req->roomPassword->data, 8); + flatbuffers::Offset>> final_groupconfigs_vec; + if (req->groupConfigNum) { - auto bin = builder.CreateString(req->blockedUser[i].handle.data); - davec.push_back(bin); + std::vector> davec; + for (u32 i = 0; i < req->groupConfigNum; i++) + { + auto bin = CreateGroupConfig(builder, req->groupConfig[i].slotNum, req->groupConfig[i].withLabel, builder.CreateVector(req->groupConfig[i].label.data, 8), req->groupConfig[i].withPassword); + davec.push_back(bin); + } + final_groupconfigs_vec = builder.CreateVector(davec); } - final_blockedusers_vec = builder.CreateVector(davec); - } - flatbuffers::Offset> final_grouplabel; - if (req->joinRoomGroupLabel) - final_grouplabel = builder.CreateVector(req->joinRoomGroupLabel->data, 8); - flatbuffers::Offset>> final_memberbinattrinternal_vec; - if (req->roomMemberBinAttrInternalNum) - { - std::vector> davec; - for (u32 i = 0; i < req->roomMemberBinAttrInternalNum; i++) + flatbuffers::Offset>> final_allowedusers_vec; + if (req->allowedUserNum && req->allowedUser) { - auto bin = CreateBinAttr( - builder, req->roomMemberBinAttrInternal[i].id, builder.CreateVector(reinterpret_cast(req->roomMemberBinAttrInternal[i].ptr.get_ptr()), req->roomMemberBinAttrInternal[i].size)); - davec.push_back(bin); + std::vector> davec; + for (u32 i = 0; i < req->allowedUserNum; i++) + { + auto bin = builder.CreateString(req->allowedUser[i].handle.data); + davec.push_back(bin); + } + final_allowedusers_vec = builder.CreateVector(davec); } - final_memberbinattrinternal_vec = builder.CreateVector(davec); - } - flatbuffers::Offset final_optparam; - if (req->sigOptParam) - final_optparam = CreateOptParam(builder, req->sigOptParam->type, req->sigOptParam->flag, req->sigOptParam->hubMemberId); - u64 final_passwordSlotMask = 0; - if (req->passwordSlotMask) - final_passwordSlotMask = *req->passwordSlotMask; - - auto req_finished = CreateCreateJoinRoomRequest(builder, req->worldId, req->lobbyId, req->maxSlot, req->flagAttr, final_binattrinternal_vec, final_searchintattrexternal_vec, - final_searchbinattrexternal_vec, final_binattrexternal_vec, final_roompassword, final_groupconfigs_vec, final_passwordSlotMask, final_allowedusers_vec, final_blockedusers_vec, final_grouplabel, - final_memberbinattrinternal_vec, req->teamId, final_optparam); - - builder.Finish(req_finished); - u8* buf = builder.GetBufferPointer(); - usz bufsize = builder.GetSize(); - data.resize(COMMUNICATION_ID_SIZE + sizeof(u32) + bufsize); - - memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); - reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); - memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); - - if (!forge_send(CommandType::CreateRoom, req_id, data)) - return false; - - return true; -} - -bool rpcn_client::join_room(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2JoinRoomRequest* req) -{ - std::vector data{}; - - extra_nps::print_joinroom(req); - - flatbuffers::FlatBufferBuilder builder(1024); - - flatbuffers::Offset> final_roompassword; - if (req->roomPassword) - final_roompassword = builder.CreateVector(req->roomPassword->data, 8); - flatbuffers::Offset> final_grouplabel; - if (req->joinRoomGroupLabel) - final_grouplabel = builder.CreateVector(req->joinRoomGroupLabel->data, 8); - flatbuffers::Offset>> final_memberbinattrinternal_vec; - if (req->roomMemberBinAttrInternalNum) - { - std::vector> davec; - for (u32 i = 0; i < req->roomMemberBinAttrInternalNum; i++) + flatbuffers::Offset>> final_blockedusers_vec; + if (req->blockedUserNum) { - auto bin = CreateBinAttr(builder, req->roomMemberBinAttrInternal[i].id, builder.CreateVector(req->roomMemberBinAttrInternal[i].ptr.get_ptr(), req->roomMemberBinAttrInternal[i].size)); - davec.push_back(bin); + std::vector> davec; + for (u32 i = 0; i < req->blockedUserNum; i++) + { + auto bin = builder.CreateString(req->blockedUser[i].handle.data); + davec.push_back(bin); + } + final_blockedusers_vec = builder.CreateVector(davec); } - final_memberbinattrinternal_vec = builder.CreateVector(davec); - } - flatbuffers::Offset final_optdata = CreatePresenceOptionData(builder, builder.CreateVector(req->optData.data, 16), req->optData.length); - - auto req_finished = CreateJoinRoomRequest(builder, req->roomId, final_roompassword, final_grouplabel, final_memberbinattrinternal_vec, final_optdata, req->teamId); - - builder.Finish(req_finished); - u8* buf = builder.GetBufferPointer(); - usz bufsize = builder.GetSize(); - data.resize(COMMUNICATION_ID_SIZE + sizeof(u32) + bufsize); - - memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); - reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); - memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); - - if (!forge_send(CommandType::JoinRoom, req_id, data)) - return false; - - return true; -} - -bool rpcn_client::leave_room(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2LeaveRoomRequest* req) -{ - std::vector data{}; - - flatbuffers::FlatBufferBuilder builder(1024); - flatbuffers::Offset final_optdata = CreatePresenceOptionData(builder, builder.CreateVector(req->optData.data, 16), req->optData.length); - auto req_finished = CreateLeaveRoomRequest(builder, req->roomId, final_optdata); - builder.Finish(req_finished); - u8* buf = builder.GetBufferPointer(); - usz bufsize = builder.GetSize(); - data.resize(COMMUNICATION_ID_SIZE + sizeof(u32) + bufsize); - - memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); - reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); - memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); - - if (!forge_send(CommandType::LeaveRoom, req_id, data)) - return false; - - return true; -} - -bool rpcn_client::search_room(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2SearchRoomRequest* req) -{ - std::vector data{}; - - extra_nps::print_search_room(req); - - flatbuffers::FlatBufferBuilder builder(1024); - flatbuffers::Offset>> final_intfilter_vec; - if (req->intFilterNum) - { - std::vector> davec{}; - for (u32 i = 0; i < req->intFilterNum; i++) + flatbuffers::Offset> final_grouplabel; + if (req->joinRoomGroupLabel) + final_grouplabel = builder.CreateVector(req->joinRoomGroupLabel->data, 8); + flatbuffers::Offset>> final_memberbinattrinternal_vec; + if (req->roomMemberBinAttrInternalNum) { - auto int_attr = CreateIntAttr(builder, req->intFilter[i].attr.id, req->intFilter[i].attr.num); - auto bin = CreateIntSearchFilter(builder, req->intFilter[i].searchOperator, int_attr); - davec.push_back(bin); + std::vector> davec; + for (u32 i = 0; i < req->roomMemberBinAttrInternalNum; i++) + { + auto bin = CreateBinAttr( + builder, req->roomMemberBinAttrInternal[i].id, builder.CreateVector(reinterpret_cast(req->roomMemberBinAttrInternal[i].ptr.get_ptr()), req->roomMemberBinAttrInternal[i].size)); + davec.push_back(bin); + } + final_memberbinattrinternal_vec = builder.CreateVector(davec); } - final_intfilter_vec = builder.CreateVector(davec); + flatbuffers::Offset final_optparam; + if (req->sigOptParam) + final_optparam = CreateOptParam(builder, req->sigOptParam->type, req->sigOptParam->flag, req->sigOptParam->hubMemberId); + u64 final_passwordSlotMask = 0; + if (req->passwordSlotMask) + final_passwordSlotMask = *req->passwordSlotMask; + + auto req_finished = CreateCreateJoinRoomRequest(builder, req->worldId, req->lobbyId, req->maxSlot, req->flagAttr, final_binattrinternal_vec, final_searchintattrexternal_vec, + final_searchbinattrexternal_vec, final_binattrexternal_vec, final_roompassword, final_groupconfigs_vec, final_passwordSlotMask, final_allowedusers_vec, final_blockedusers_vec, final_grouplabel, + final_memberbinattrinternal_vec, req->teamId, final_optparam); + + builder.Finish(req_finished); + u8* buf = builder.GetBufferPointer(); + usz bufsize = builder.GetSize(); + data.resize(COMMUNICATION_ID_SIZE + sizeof(u32) + bufsize); + + memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); + reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); + memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); + + if (!forge_send(CommandType::CreateRoom, req_id, data)) + return false; + + return true; } - flatbuffers::Offset>> final_binfilter_vec; - if (req->binFilterNum) + + bool rpcn_client::join_room(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2JoinRoomRequest* req) { - std::vector> davec; - for (u32 i = 0; i < req->binFilterNum; i++) + std::vector data; + + extra_nps::print_joinroom(req); + + flatbuffers::FlatBufferBuilder builder(1024); + + flatbuffers::Offset> final_roompassword; + if (req->roomPassword) + final_roompassword = builder.CreateVector(req->roomPassword->data, 8); + flatbuffers::Offset> final_grouplabel; + if (req->joinRoomGroupLabel) + final_grouplabel = builder.CreateVector(req->joinRoomGroupLabel->data, 8); + flatbuffers::Offset>> final_memberbinattrinternal_vec; + if (req->roomMemberBinAttrInternalNum) { - auto bin_attr = CreateBinAttr(builder, req->binFilter[i].attr.id, builder.CreateVector(req->binFilter[i].attr.ptr.get_ptr(), req->binFilter[i].attr.size)); - auto bin = CreateBinSearchFilter(builder, req->binFilter[i].searchOperator, bin_attr); - davec.push_back(bin); + std::vector> davec; + for (u32 i = 0; i < req->roomMemberBinAttrInternalNum; i++) + { + auto bin = CreateBinAttr(builder, req->roomMemberBinAttrInternal[i].id, builder.CreateVector(req->roomMemberBinAttrInternal[i].ptr.get_ptr(), req->roomMemberBinAttrInternal[i].size)); + davec.push_back(bin); + } + final_memberbinattrinternal_vec = builder.CreateVector(davec); } - final_binfilter_vec = builder.CreateVector(davec); + flatbuffers::Offset final_optdata = CreatePresenceOptionData(builder, builder.CreateVector(req->optData.data, 16), req->optData.length); + + auto req_finished = CreateJoinRoomRequest(builder, req->roomId, final_roompassword, final_grouplabel, final_memberbinattrinternal_vec, final_optdata, req->teamId); + + builder.Finish(req_finished); + u8* buf = builder.GetBufferPointer(); + usz bufsize = builder.GetSize(); + data.resize(COMMUNICATION_ID_SIZE + sizeof(u32) + bufsize); + + memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); + reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); + memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); + + if (!forge_send(CommandType::JoinRoom, req_id, data)) + return false; + + return true; } - flatbuffers::Offset> attrid_vec; - if (req->attrIdNum) - attrid_vec = builder.CreateVector(utils::bless(req->attrId.get_ptr()), req->attrIdNum); - SearchRoomRequestBuilder s_req(builder); - s_req.add_option(req->option); - s_req.add_worldId(req->worldId); - s_req.add_lobbyId(req->lobbyId); - s_req.add_rangeFilter_startIndex(req->rangeFilter.startIndex); - s_req.add_rangeFilter_max(req->rangeFilter.max); - s_req.add_flagFilter(req->flagFilter); - s_req.add_flagAttr(req->flagAttr); - if (req->intFilterNum) - s_req.add_intFilter(final_intfilter_vec); - if (req->binFilterNum) - s_req.add_binFilter(final_binfilter_vec); - if (req->attrIdNum) - s_req.add_attrId(attrid_vec); - - auto req_finished = s_req.Finish(); - builder.Finish(req_finished); - u8* buf = builder.GetBufferPointer(); - usz bufsize = builder.GetSize(); - data.resize(COMMUNICATION_ID_SIZE + bufsize + sizeof(u32)); - - memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); - reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); - memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); - - if (!forge_send(CommandType::SearchRoom, req_id, data)) - return false; - - return true; -} - -bool rpcn_client::set_roomdata_external(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2SetRoomDataExternalRequest* req) -{ - std::vector data{}; - - flatbuffers::FlatBufferBuilder builder(1024); - flatbuffers::Offset>> final_searchintattrexternal_vec; - if (req->roomSearchableIntAttrExternalNum) + bool rpcn_client::leave_room(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2LeaveRoomRequest* req) { - std::vector> davec; - for (u32 i = 0; i < req->roomSearchableIntAttrExternalNum; i++) + std::vector data; + + flatbuffers::FlatBufferBuilder builder(1024); + flatbuffers::Offset final_optdata = CreatePresenceOptionData(builder, builder.CreateVector(req->optData.data, 16), req->optData.length); + auto req_finished = CreateLeaveRoomRequest(builder, req->roomId, final_optdata); + builder.Finish(req_finished); + u8* buf = builder.GetBufferPointer(); + usz bufsize = builder.GetSize(); + data.resize(COMMUNICATION_ID_SIZE + sizeof(u32) + bufsize); + + memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); + reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); + memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); + + if (!forge_send(CommandType::LeaveRoom, req_id, data)) + return false; + + return true; + } + + bool rpcn_client::search_room(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2SearchRoomRequest* req) + { + std::vector data; + + extra_nps::print_search_room(req); + + flatbuffers::FlatBufferBuilder builder(1024); + flatbuffers::Offset>> final_intfilter_vec; + if (req->intFilterNum) { - auto bin = CreateIntAttr(builder, req->roomSearchableIntAttrExternal[i].id, req->roomSearchableIntAttrExternal[i].num); - davec.push_back(bin); + std::vector> davec{}; + for (u32 i = 0; i < req->intFilterNum; i++) + { + auto int_attr = CreateIntAttr(builder, req->intFilter[i].attr.id, req->intFilter[i].attr.num); + auto bin = CreateIntSearchFilter(builder, req->intFilter[i].searchOperator, int_attr); + davec.push_back(bin); + } + final_intfilter_vec = builder.CreateVector(davec); } - final_searchintattrexternal_vec = builder.CreateVector(davec); - } - flatbuffers::Offset>> final_searchbinattrexternal_vec; - if (req->roomSearchableBinAttrExternalNum) - { - std::vector> davec; - for (u32 i = 0; i < req->roomSearchableBinAttrExternalNum; i++) + flatbuffers::Offset>> final_binfilter_vec; + if (req->binFilterNum) { - auto bin = CreateBinAttr(builder, req->roomSearchableBinAttrExternal[i].id, builder.CreateVector(req->roomSearchableBinAttrExternal[i].ptr.get_ptr(), req->roomSearchableBinAttrExternal[i].size)); - davec.push_back(bin); + std::vector> davec; + for (u32 i = 0; i < req->binFilterNum; i++) + { + auto bin_attr = CreateBinAttr(builder, req->binFilter[i].attr.id, builder.CreateVector(req->binFilter[i].attr.ptr.get_ptr(), req->binFilter[i].attr.size)); + auto bin = CreateBinSearchFilter(builder, req->binFilter[i].searchOperator, bin_attr); + davec.push_back(bin); + } + final_binfilter_vec = builder.CreateVector(davec); } - final_searchbinattrexternal_vec = builder.CreateVector(davec); + flatbuffers::Offset> attrid_vec; + if (req->attrIdNum) + attrid_vec = builder.CreateVector(utils::bless(req->attrId.get_ptr()), req->attrIdNum); + + SearchRoomRequestBuilder s_req(builder); + s_req.add_option(req->option); + s_req.add_worldId(req->worldId); + s_req.add_lobbyId(req->lobbyId); + s_req.add_rangeFilter_startIndex(req->rangeFilter.startIndex); + s_req.add_rangeFilter_max(req->rangeFilter.max); + s_req.add_flagFilter(req->flagFilter); + s_req.add_flagAttr(req->flagAttr); + if (req->intFilterNum) + s_req.add_intFilter(final_intfilter_vec); + if (req->binFilterNum) + s_req.add_binFilter(final_binfilter_vec); + if (req->attrIdNum) + s_req.add_attrId(attrid_vec); + + auto req_finished = s_req.Finish(); + builder.Finish(req_finished); + u8* buf = builder.GetBufferPointer(); + usz bufsize = builder.GetSize(); + data.resize(COMMUNICATION_ID_SIZE + bufsize + sizeof(u32)); + + memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); + reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); + memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); + + if (!forge_send(CommandType::SearchRoom, req_id, data)) + return false; + + return true; } - flatbuffers::Offset>> final_binattrexternal_vec; - if (req->roomBinAttrExternalNum) + + bool rpcn_client::get_roomdata_external_list(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2GetRoomDataExternalListRequest* req) { - std::vector> davec; - for (u32 i = 0; i < req->roomBinAttrExternalNum; i++) + std::vector data; + + flatbuffers::FlatBufferBuilder builder(1024); + std::vector roomIds; + for (u32 i = 0; i < req->roomIdNum; i++) { - auto bin = CreateBinAttr(builder, req->roomBinAttrExternal[i].id, builder.CreateVector(req->roomBinAttrExternal[i].ptr.get_ptr(), req->roomBinAttrExternal[i].size)); - davec.push_back(bin); + roomIds.push_back(req->roomId[i]); } - final_binattrexternal_vec = builder.CreateVector(davec); - } - auto req_finished = CreateSetRoomDataExternalRequest(builder, req->roomId, final_searchintattrexternal_vec, final_searchbinattrexternal_vec, final_binattrexternal_vec); - - builder.Finish(req_finished); - u8* buf = builder.GetBufferPointer(); - usz bufsize = builder.GetSize(); - data.resize(COMMUNICATION_ID_SIZE + bufsize + sizeof(u32)); - - memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); - reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); - memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); - - if (!forge_send(CommandType::SetRoomDataExternal, req_id, data)) - return false; - - return true; -} - -bool rpcn_client::get_roomdata_internal(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2GetRoomDataInternalRequest* req) -{ - std::vector data{}, reply_data{}; - - flatbuffers::FlatBufferBuilder builder(1024); - - flatbuffers::Offset> final_attr_ids_vec; - if (req->attrIdNum) - final_attr_ids_vec = builder.CreateVector(utils::bless(req->attrId.get_ptr()), req->attrIdNum); - - auto req_finished = CreateGetRoomDataInternalRequest(builder, req->roomId, final_attr_ids_vec); - - builder.Finish(req_finished); - u8* buf = builder.GetBufferPointer(); - usz bufsize = builder.GetSize(); - data.resize(COMMUNICATION_ID_SIZE + bufsize + sizeof(u32)); - - memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); - reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); - memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); - - if (!forge_send(CommandType::GetRoomDataInternal, req_id, data)) - return false; - - return true; -} - -bool rpcn_client::set_roomdata_internal(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2SetRoomDataInternalRequest* req) -{ - std::vector data{}; - - // extra_nps::print_set_roomdata_req(req); - - flatbuffers::FlatBufferBuilder builder(1024); - flatbuffers::Offset>> final_binattrinternal_vec; - if (req->roomBinAttrInternalNum) - { - std::vector> davec; - for (u32 i = 0; i < req->roomBinAttrInternalNum; i++) + std::vector attrIds; + for (u32 i = 0; i < req->attrIdNum; i++) { - auto bin = CreateBinAttr(builder, req->roomBinAttrInternal[i].id, builder.CreateVector(req->roomBinAttrInternal[i].ptr.get_ptr(), req->roomBinAttrInternal[i].size)); - davec.push_back(bin); + attrIds.push_back(req->attrId[i]); } - final_binattrinternal_vec = builder.CreateVector(davec); + + auto req_finished = CreateGetRoomDataExternalListRequestDirect(builder, &roomIds, &attrIds); + + builder.Finish(req_finished); + u8* buf = builder.GetBufferPointer(); + usz bufsize = builder.GetSize(); + data.resize(COMMUNICATION_ID_SIZE + bufsize + sizeof(u32)); + + memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); + reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); + memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); + + if (!forge_send(CommandType::GetRoomDataExternalList, req_id, data)) + return false; + + return true; } - flatbuffers::Offset>> final_grouppasswordconfig_vec; - if (req->passwordConfigNum) + + bool rpcn_client::set_roomdata_external(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2SetRoomDataExternalRequest* req) { - std::vector> davec; - for (u32 i = 0; i < req->passwordConfigNum; i++) + std::vector data; + + flatbuffers::FlatBufferBuilder builder(1024); + flatbuffers::Offset>> final_searchintattrexternal_vec; + if (req->roomSearchableIntAttrExternalNum) { - auto rg = CreateRoomGroupPasswordConfig(builder, req->passwordConfig[i].groupId, req->passwordConfig[i].withPassword); - davec.push_back(rg); + std::vector> davec; + for (u32 i = 0; i < req->roomSearchableIntAttrExternalNum; i++) + { + auto bin = CreateIntAttr(builder, req->roomSearchableIntAttrExternal[i].id, req->roomSearchableIntAttrExternal[i].num); + davec.push_back(bin); + } + final_searchintattrexternal_vec = builder.CreateVector(davec); } - final_grouppasswordconfig_vec = builder.CreateVector(davec); + flatbuffers::Offset>> final_searchbinattrexternal_vec; + if (req->roomSearchableBinAttrExternalNum) + { + std::vector> davec; + for (u32 i = 0; i < req->roomSearchableBinAttrExternalNum; i++) + { + auto bin = CreateBinAttr(builder, req->roomSearchableBinAttrExternal[i].id, builder.CreateVector(req->roomSearchableBinAttrExternal[i].ptr.get_ptr(), req->roomSearchableBinAttrExternal[i].size)); + davec.push_back(bin); + } + final_searchbinattrexternal_vec = builder.CreateVector(davec); + } + flatbuffers::Offset>> final_binattrexternal_vec; + if (req->roomBinAttrExternalNum) + { + std::vector> davec; + for (u32 i = 0; i < req->roomBinAttrExternalNum; i++) + { + auto bin = CreateBinAttr(builder, req->roomBinAttrExternal[i].id, builder.CreateVector(req->roomBinAttrExternal[i].ptr.get_ptr(), req->roomBinAttrExternal[i].size)); + davec.push_back(bin); + } + final_binattrexternal_vec = builder.CreateVector(davec); + } + auto req_finished = CreateSetRoomDataExternalRequest(builder, req->roomId, final_searchintattrexternal_vec, final_searchbinattrexternal_vec, final_binattrexternal_vec); + + builder.Finish(req_finished); + u8* buf = builder.GetBufferPointer(); + usz bufsize = builder.GetSize(); + data.resize(COMMUNICATION_ID_SIZE + bufsize + sizeof(u32)); + + memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); + reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); + memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); + + if (!forge_send(CommandType::SetRoomDataExternal, req_id, data)) + return false; + + return true; } - u64 final_passwordSlotMask = 0; - if (req->passwordSlotMask) - final_passwordSlotMask = *req->passwordSlotMask; - flatbuffers::Offset> final_ownerprivilege_vec; - if (req->ownerPrivilegeRankNum) - final_ownerprivilege_vec = builder.CreateVector(utils::bless(req->ownerPrivilegeRank.get_ptr()), req->ownerPrivilegeRankNum); - - auto req_finished = - CreateSetRoomDataInternalRequest(builder, req->roomId, req->flagFilter, req->flagAttr, final_binattrinternal_vec, final_grouppasswordconfig_vec, final_passwordSlotMask, final_ownerprivilege_vec); - - builder.Finish(req_finished); - u8* buf = builder.GetBufferPointer(); - usz bufsize = builder.GetSize(); - data.resize(COMMUNICATION_ID_SIZE + bufsize + sizeof(u32)); - - memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); - reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); - memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); - - if (!forge_send(CommandType::SetRoomDataInternal, req_id, data)) - return false; - - return true; -} - -bool rpcn_client::ping_room_owner(u32 req_id, const SceNpCommunicationId& communication_id, u64 room_id) -{ - std::vector data{}; - - data.resize(COMMUNICATION_ID_SIZE + sizeof(u64)); - - memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); - *utils::bless>(&data[COMMUNICATION_ID_SIZE]) = room_id; - - if (!forge_send(CommandType::PingRoomOwner, req_id, data)) - return false; - - return true; -} - -bool rpcn_client::send_room_message(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2SendRoomMessageRequest* req) -{ - std::vector data{}; - flatbuffers::FlatBufferBuilder builder(1024); - - std::vector dst; - switch(req->castType) + bool rpcn_client::get_roomdata_internal(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2GetRoomDataInternalRequest* req) { + std::vector data, reply_data; + + flatbuffers::FlatBufferBuilder builder(1024); + + flatbuffers::Offset> final_attr_ids_vec; + if (req->attrIdNum) + final_attr_ids_vec = builder.CreateVector(utils::bless(req->attrId.get_ptr()), req->attrIdNum); + + auto req_finished = CreateGetRoomDataInternalRequest(builder, req->roomId, final_attr_ids_vec); + + builder.Finish(req_finished); + u8* buf = builder.GetBufferPointer(); + usz bufsize = builder.GetSize(); + data.resize(COMMUNICATION_ID_SIZE + bufsize + sizeof(u32)); + + memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); + reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); + memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); + + if (!forge_send(CommandType::GetRoomDataInternal, req_id, data)) + return false; + + return true; + } + + bool rpcn_client::set_roomdata_internal(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2SetRoomDataInternalRequest* req) + { + std::vector data; + + // extra_nps::print_set_roomdata_req(req); + + flatbuffers::FlatBufferBuilder builder(1024); + flatbuffers::Offset>> final_binattrinternal_vec; + if (req->roomBinAttrInternalNum) + { + std::vector> davec; + for (u32 i = 0; i < req->roomBinAttrInternalNum; i++) + { + auto bin = CreateBinAttr(builder, req->roomBinAttrInternal[i].id, builder.CreateVector(req->roomBinAttrInternal[i].ptr.get_ptr(), req->roomBinAttrInternal[i].size)); + davec.push_back(bin); + } + final_binattrinternal_vec = builder.CreateVector(davec); + } + flatbuffers::Offset>> final_grouppasswordconfig_vec; + if (req->passwordConfigNum) + { + std::vector> davec; + for (u32 i = 0; i < req->passwordConfigNum; i++) + { + auto rg = CreateRoomGroupPasswordConfig(builder, req->passwordConfig[i].groupId, req->passwordConfig[i].withPassword); + davec.push_back(rg); + } + final_grouppasswordconfig_vec = builder.CreateVector(davec); + } + u64 final_passwordSlotMask = 0; + if (req->passwordSlotMask) + final_passwordSlotMask = *req->passwordSlotMask; + + flatbuffers::Offset> final_ownerprivilege_vec; + if (req->ownerPrivilegeRankNum) + final_ownerprivilege_vec = builder.CreateVector(utils::bless(req->ownerPrivilegeRank.get_ptr()), req->ownerPrivilegeRankNum); + + auto req_finished = + CreateSetRoomDataInternalRequest(builder, req->roomId, req->flagFilter, req->flagAttr, final_binattrinternal_vec, final_grouppasswordconfig_vec, final_passwordSlotMask, final_ownerprivilege_vec); + + builder.Finish(req_finished); + u8* buf = builder.GetBufferPointer(); + usz bufsize = builder.GetSize(); + data.resize(COMMUNICATION_ID_SIZE + bufsize + sizeof(u32)); + + memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); + reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); + memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); + + if (!forge_send(CommandType::SetRoomDataInternal, req_id, data)) + return false; + + return true; + } + + bool rpcn_client::ping_room_owner(u32 req_id, const SceNpCommunicationId& communication_id, u64 room_id) + { + std::vector data; + + data.resize(COMMUNICATION_ID_SIZE + sizeof(u64)); + + memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); + *utils::bless>(&data[COMMUNICATION_ID_SIZE]) = room_id; + + if (!forge_send(CommandType::PingRoomOwner, req_id, data)) + return false; + + return true; + } + + bool rpcn_client::send_room_message(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatching2SendRoomMessageRequest* req) + { + std::vector data; + flatbuffers::FlatBufferBuilder builder(1024); + + std::vector dst; + switch (req->castType) + { case SCE_NP_MATCHING2_CASTTYPE_BROADCAST: break; case SCE_NP_MATCHING2_CASTTYPE_UNICAST: @@ -1056,115 +1454,412 @@ bool rpcn_client::send_room_message(u32 req_id, const SceNpCommunicationId& comm default: ensure(false); break; - } + } - auto req_finished = CreateSendRoomMessageRequest(builder, req->roomId, req->castType, builder.CreateVector(dst.data(), dst.size()), builder.CreateVector(reinterpret_cast(req->msg.get_ptr()), req->msgLen), req->option); + auto req_finished = CreateSendRoomMessageRequest(builder, req->roomId, req->castType, builder.CreateVector(dst.data(), dst.size()), builder.CreateVector(reinterpret_cast(req->msg.get_ptr()), req->msgLen), req->option); - builder.Finish(req_finished); - u8* buf = builder.GetBufferPointer(); - usz bufsize = builder.GetSize(); - data.resize(COMMUNICATION_ID_SIZE + bufsize + sizeof(u32)); + builder.Finish(req_finished); + u8* buf = builder.GetBufferPointer(); + usz bufsize = builder.GetSize(); + data.resize(COMMUNICATION_ID_SIZE + bufsize + sizeof(u32)); - memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); - reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); - memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); + memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); + reinterpret_cast&>(data[COMMUNICATION_ID_SIZE]) = static_cast(bufsize); + memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize); - if (!forge_send(CommandType::SendRoomMessage, req_id, data)) - return false; + if (!forge_send(CommandType::SendRoomMessage, req_id, data)) + return false; - return true; -} - -bool rpcn_client::req_sign_infos(u32 req_id, const std::string& npid) -{ - std::vector data{}; - std::copy(npid.begin(), npid.end(), std::back_inserter(data)); - data.push_back(0); - - if (!forge_send(CommandType::RequestSignalingInfos, req_id, data)) - return false; - - return true; -} - -bool rpcn_client::req_ticket(u32 req_id, const std::string& service_id) -{ - std::vector data{}; - std::copy(service_id.begin(), service_id.end(), std::back_inserter(data)); - data.push_back(0); - - if (!forge_send(CommandType::RequestTicket, req_id, data)) - return false; - - return true; -} - -std::vector rpcn_client::forge_request(u16 command, u32 packet_id, const std::vector& data) const -{ - u16 packet_size = data.size() + RPCN_HEADER_SIZE; - - std::vector packet(packet_size); - packet[0] = PacketType::Request; - reinterpret_cast&>(packet[1]) = command; - reinterpret_cast&>(packet[3]) = packet_size; - reinterpret_cast&>(packet[5]) = packet_id; - - memcpy(packet.data() + RPCN_HEADER_SIZE, data.data(), data.size()); - return packet; -} - -bool rpcn_client::is_error(ErrorType err) const -{ - if (err >= ErrorType::__error_last) - { - rpcn_log.error("Invalid error returned!"); return true; } - switch (err) + bool rpcn_client::req_sign_infos(u32 req_id, const std::string& npid) { - case NoError: return false; - case Malformed: rpcn_log.error("Sent packet was malformed!"); break; - case Invalid: rpcn_log.error("Sent command was invalid!"); break; - case InvalidInput: rpcn_log.error("Sent data was invalid!"); break; - case ErrorLogin: rpcn_log.error("Sent password/token was incorrect!"); break; - case ErrorCreate: rpcn_log.error("Error creating an account!"); break; - case AlreadyLoggedIn: rpcn_log.error("User is already logged in!"); break; - case AlreadyJoined: rpcn_log.error("User has already joined!"); break; - case DbFail: rpcn_log.error("A db query failed on the server!"); break; - case NotFound: rpcn_log.error("A request replied not found!"); return false; - case Unsupported: rpcn_log.error("An unsupported operation was attempted!"); return false; - default: rpcn_log.fatal("Unhandled ErrorType reached the switch?"); break; + std::vector data; + std::copy(npid.begin(), npid.end(), std::back_inserter(data)); + data.push_back(0); + + if (!forge_send(CommandType::RequestSignalingInfos, req_id, data)) + return false; + + return true; } - return true; -} - -bool rpcn_client::error_and_disconnect(const std::string& error_msg) -{ - rpcn_log.error("%s", error_msg); - disconnect(); - return false; -} - -bool rpcn_client::is_abort() const -{ - if (in_config) + bool rpcn_client::req_ticket(u32 req_id, const std::string& service_id) { - if (abort_config) + std::vector data; + std::copy(service_id.begin(), service_id.end(), std::back_inserter(data)); + data.push_back(0); + + if (!forge_send(CommandType::RequestTicket, req_id, data)) + return false; + + return true; + } + + bool rpcn_client::sendmessage(const message_data& msg_data, const std::set& npids) + { + std::vector data; + flatbuffers::FlatBufferBuilder builder(1024); + + flatbuffers::FlatBufferBuilder nested_builder(1024); + auto fb_message = CreateMessageDetailsDirect(nested_builder, static_cast(msg_data.commId.data), msg_data.msgId, msg_data.mainType, msg_data.subType, msg_data.msgFeatures, msg_data.subject.c_str(), msg_data.body.c_str(), &msg_data.data); + nested_builder.Finish(fb_message); + builder.ForceVectorAlignment(nested_builder.GetSize(), sizeof(uint8_t), nested_builder.GetBufferMinAlignment()); + auto nested_flatbuffer_vector = builder.CreateVector(nested_builder.GetBufferPointer(), nested_builder.GetSize()); + + std::vector> davec; + for (const auto& npid : npids) + { + auto s_npid = builder.CreateString(npid); + davec.push_back(s_npid); + } + auto npids_vector = builder.CreateVector(davec); + + //auto npids = builder.Create + auto fb_sendmessage = CreateSendMessageRequest(builder, nested_flatbuffer_vector, npids_vector); + + builder.Finish(fb_sendmessage); + u8* buf = builder.GetBufferPointer(); + usz bufsize = builder.GetSize(); + data.resize(bufsize + sizeof(u32)); + + reinterpret_cast&>(data[0]) = static_cast(bufsize); + memcpy(data.data() + sizeof(u32), buf, bufsize); + + u64 req_id = rpcn_request_counter.fetch_add(1); + + if (!forge_send(CommandType::SendMessage, req_id, data)) + return false; + + return true; + } + + std::vector rpcn_client::forge_request(u16 command, u64 packet_id, const std::vector& data) const + { + u16 packet_size = data.size() + RPCN_HEADER_SIZE; + + std::vector packet(packet_size); + packet[0] = PacketType::Request; + reinterpret_cast&>(packet[1]) = command; + reinterpret_cast&>(packet[3]) = packet_size; + reinterpret_cast&>(packet[5]) = packet_id; + + memcpy(packet.data() + RPCN_HEADER_SIZE, data.data(), data.size()); + return packet; + } + + bool rpcn_client::is_error(ErrorType err) const + { + if (err >= ErrorType::__error_last) + { + rpcn_log.error("Invalid error returned!"); return true; + } + + switch (err) + { + case NoError: return false; + case Malformed: rpcn_log.error("Sent packet was malformed!"); break; + case Invalid: rpcn_log.error("Sent command was invalid!"); break; + case InvalidInput: rpcn_log.error("Sent data was invalid!"); break; + case TooSoon: rpcn_log.error("Request happened too soon!"); break; + case LoginError: rpcn_log.error("Unknown login error!"); break; + case LoginAlreadyLoggedIn: rpcn_log.error("User is already logged in!"); break; + case LoginInvalidUsername: rpcn_log.error("Login error: invalid username!"); break; + case LoginInvalidPassword: rpcn_log.error("Login error: invalid password!"); break; + case LoginInvalidToken: rpcn_log.error("Login error: invalid token!"); break; + case CreationError: rpcn_log.error("Error creating an account!"); break; + case CreationExistingUsername: rpcn_log.error("Error creating an account: existing username!"); + case CreationBannedEmailProvider: rpcn_log.error("Error creating an account: banned email provider!"); + case CreationExistingEmail: rpcn_log.error("Error creating an account: an account with that email already exist!"); + case AlreadyJoined: rpcn_log.error("User has already joined!"); break; + case DbFail: rpcn_log.error("A db query failed on the server!"); break; + case EmailFail: rpcn_log.error("An email action failed on the server!"); break; + case NotFound: rpcn_log.error("A request replied not found!"); return false; + case Blocked: rpcn_log.error("You're blocked!"); break; + case AlreadyFriend: rpcn_log.error("You're already friends!"); break; + case Unsupported: rpcn_log.error("An unsupported operation was attempted!"); return false; + default: rpcn_log.fatal("Unhandled ErrorType reached the switch?"); break; + } + + return true; } - else + + bool rpcn_client::error_and_disconnect(const std::string& error_msg) { - if (Emu.IsStopped() || thread_ctrl::state() == thread_state::aborting) - return true; + connected = false; + rpcn_log.error("%s", error_msg); + return false; } - return false; -} + rpcn_state rpcn_client::wait_for_connection() + { + { + std::lock_guard lock(mutex_connected); + if (connected) + { + return rpcn_state::failure_no_failure; + } -void rpcn_client::abort() -{ - ensure(in_config); - abort_config = true; -} + if (state != rpcn_state::failure_no_failure) + { + return state; + } + } + + sem_connected.acquire(); + + return state; + } + + rpcn_state rpcn_client::wait_for_authentified() + { + { + std::lock_guard lock(mutex_authentified); + + if (authentified) + { + return rpcn_state::failure_no_failure; + } + + if (state != rpcn_state::failure_no_failure) + { + return state; + } + want_auth = true; + sem_rpcn.release(); + } + + sem_authentified.acquire(); + + return state; + } + + void rpcn_client::get_friends_and_register_cb(friend_data& friend_infos, friend_cb_func cb_func, void* cb_param) + { + std::lock_guard lock(mutex_friends); + friend_infos = this->friend_infos; + friend_cbs.insert(std::make_pair(cb_func, cb_param)); + } + + void rpcn_client::remove_friend_cb(friend_cb_func cb_func, void* cb_param) + { + std::lock_guard lock(mutex_friends); + for (const auto& friend_cb : friend_cbs) + { + if (friend_cb.first == cb_func && friend_cb.second == cb_param) + { + friend_cbs.erase(friend_cb); + break; + } + } + } + + void rpcn_client::handle_friend_notification(u16 command, std::vector data) + { + std::lock_guard lock(mutex_friends); + + NotificationType ntype = static_cast(command); + vec_stream vdata(data); + + auto call_callbacks = [&](NotificationType ntype, std::string username, bool status) + { + for (auto& friend_cb : friend_cbs) + { + friend_cb.first(friend_cb.second, ntype, username, status); + } + }; + + switch (ntype) + { + case NotificationType::FriendQuery: // Other user sent a friend request + { + std::string username = vdata.get_string(false); + if (vdata.is_error()) + { + rpcn_log.error("Error parsing FriendQuery notification"); + break; + } + + friend_infos.requests_received.insert(username); + call_callbacks(ntype, username, 0); + break; + } + case NotificationType::FriendNew: // Add a friend to the friendlist(either accepted a friend request or friend accepted it) + { + bool status = !!vdata.get(); + std::string username = vdata.get_string(false); + if (vdata.is_error()) + { + rpcn_log.error("Error parsing FriendNew notification"); + break; + } + + friend_infos.requests_received.erase(username); + friend_infos.requests_sent.erase(username); + friend_infos.friends.insert(std::make_pair(username, std::make_pair(status, 0))); + call_callbacks(ntype, username, status); + + break; + } + case NotificationType::FriendLost: // Remove friend from the friendlist(user removed friend or friend removed friend) + { + std::string username = vdata.get_string(false); + if (vdata.is_error()) + { + rpcn_log.error("Error parsing FriendLost notification"); + break; + } + + friend_infos.friends.erase(username); + call_callbacks(ntype, username, 0); + break; + } + case NotificationType::FriendStatus: // Set status of friend to Offline or Online + { + bool status = !!vdata.get(); + u64 timestamp = vdata.get(); + std::string username = vdata.get_string(false); + if (vdata.is_error()) + { + rpcn_log.error("Error parsing FriendStatus notification"); + break; + } + + if (auto u = friend_infos.friends.find(username); u != friend_infos.friends.end()) + { + if (timestamp < u->second.second) + { + break; + } + + u->second.second = timestamp; + u->second.first = status; + call_callbacks(ntype, username, status); + } + break; + } + default: + { + rpcn_log.fatal("Unknown notification forwarded to handle_friend_notification"); + break; + } + } + } + + void rpcn_client::handle_message(std::vector data) + { + // Unserialize the message + vec_stream sdata(data); + std::string sender = sdata.get_string(false); + auto raw_msg_data = sdata.get_rawdata(); + + if (sdata.is_error()) + { + return; + } + + auto fb_mdata = flatbuffers::GetRoot(raw_msg_data.data()); + + if (!fb_mdata->communicationId() || fb_mdata->communicationId()->size() == 0 || fb_mdata->communicationId()->size() > 9 || + !fb_mdata->subject() || !fb_mdata->body() || !fb_mdata->data()) + { + rpcn_log.warning("Discarded invalid messaged!"); + return; + } + + message_data mdata = { + .msgId = message_counter, + .mainType = fb_mdata->mainType(), + .subType = fb_mdata->subType(), + .msgFeatures = fb_mdata->msgFeatures(), + .subject = fb_mdata->subject()->str(), + .body = fb_mdata->body()->str()}; + + strcpy_trunc(mdata.commId.data, fb_mdata->communicationId()->str()); + mdata.data.assign(fb_mdata->data()->Data(), fb_mdata->data()->Data() + fb_mdata->data()->size()); + + // Save the message and call callbacks + { + std::lock_guard lock(mutex_messages); + const u64 msg_id = message_counter++; + auto id_and_msg = std::make_shared>(std::make_pair(std::move(sender), std::move(mdata))); + messages.emplace(msg_id, id_and_msg); + new_messages.push_back(msg_id); + active_messages.insert(msg_id); + + const auto& msg = id_and_msg->second; + for (const auto& message_cb : message_cbs) + { + if (msg.mainType == message_cb.type_filter && (message_cb.inc_bootable || !(msg.msgFeatures & SCE_NP_BASIC_MESSAGE_FEATURES_BOOTABLE))) + { + message_cb.cb_func(message_cb.cb_param, id_and_msg, msg_id); + } + } + } + } + + std::optional>> rpcn_client::get_message(u64 id) + { + { + std::lock_guard lock(mutex_messages); + return messages.at(id); + } + } + + std::vector>>> rpcn_client::get_messages_and_register_cb(SceNpBasicMessageMainType type_filter, bool include_bootable, message_cb_func cb_func, void* cb_param) + { + std::vector>>> vec_messages; + { + std::lock_guard lock(mutex_messages); + for (auto id : active_messages) + { + const auto& entry = messages.at(id); + const auto& msg = entry->second; + if (msg.mainType == type_filter && (include_bootable || !(msg.msgFeatures & SCE_NP_BASIC_MESSAGE_FEATURES_BOOTABLE))) + { + vec_messages.push_back(std::make_pair(id, entry)); + } + } + + message_cbs.insert(message_cb_t{ + .cb_func = cb_func, + .cb_param = cb_param, + .type_filter = type_filter, + .inc_bootable = include_bootable, + }); + } + return vec_messages; + } + + void rpcn_client::remove_message_cb(message_cb_func cb_func, void* cb_param) + { + std::lock_guard lock(mutex_messages); + for (const auto& message_cb : message_cbs) + { + if (message_cb.cb_func == cb_func && message_cb.cb_param == cb_param) + { + message_cbs.erase(message_cb); + break; + } + } + } + + void rpcn_client::discard_active_message(u64 id) + { + std::lock_guard lock(mutex_messages); + active_messages.erase(id); + } + + u32 rpcn_client::get_num_friends() const + { + return friend_infos.friends.size(); + } + + u32 rpcn_client::get_num_blocks() const + { + return friend_infos.blocked.size(); + } + +} // namespace rpcn diff --git a/rpcs3/Emu/NP/rpcn_client.h b/rpcs3/Emu/NP/rpcn_client.h index 87d5881c23..01894c2d45 100644 --- a/rpcs3/Emu/NP/rpcn_client.h +++ b/rpcs3/Emu/NP/rpcn_client.h @@ -2,6 +2,8 @@ #include #include +#include +#include #include "Utilities/mutex.h" #include "util/asm.hpp" @@ -26,8 +28,7 @@ class vec_stream public: vec_stream() = delete; vec_stream(std::vector& _vec, usz initial_index = 0) - : vec(_vec) - , i(initial_index){} + : vec(_vec), i(initial_index) {} bool is_error() const { return error; @@ -97,33 +98,70 @@ public: protected: std::vector& vec; - usz i = 0; + usz i = 0; bool error = false; }; -enum CommandType : u16 +namespace rpcn { - Login, - Terminate, - Create, - SendToken, - GetServerList, - GetWorldList, - CreateRoom, - JoinRoom, - LeaveRoom, - SearchRoom, - SetRoomDataExternal, - GetRoomDataInternal, - SetRoomDataInternal, - PingRoomOwner, - SendRoomMessage, - RequestSignalingInfos, - RequestTicket, -}; + enum CommandType : u16 + { + Login, + Terminate, + Create, + SendToken, + AddFriend, + RemoveFriend, + AddBlock, + RemoveBlock, + GetServerList, + GetWorldList, + CreateRoom, + JoinRoom, + LeaveRoom, + SearchRoom, + GetRoomDataExternalList, + SetRoomDataExternal, + GetRoomDataInternal, + SetRoomDataInternal, + PingRoomOwner, + SendRoomMessage, + RequestSignalingInfos, + RequestTicket, + SendMessage, + }; + + enum NotificationType : u16 + { + UserJoinedRoom, + UserLeftRoom, + RoomDestroyed, + 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, + }; + + 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, + }; -class rpcn_client -{ enum PacketType : u8 { Request, @@ -134,123 +172,245 @@ class rpcn_client enum ErrorType : u8 { - NoError, - Malformed, - Invalid, - InvalidInput, - ErrorLogin, - ErrorCreate, - AlreadyLoggedIn, - AlreadyJoined, - DbFail, - NotFound, + 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 + CreationExistingUsername, // Specific + CreationBannedEmailProvider, // Specific to Account Creation: the email provider is banned + CreationExistingEmail, // Specific to Account Creation: that email is already registered to an account + AlreadyJoined, // User tried to join a room he's already part of + 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 Unsupported, __error_last }; -public: - rpcn_client(bool in_config = false); - ~rpcn_client(); + 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> new_msg, u64 msg_id); - bool connect(const std::string& host); - bool login(const std::string& npid, const std::string& password, const std::string& token); - bool create_user(const std::string& npid, const std::string& password, const std::string& online_name, const std::string& avatar_url, const std::string& email); - void disconnect(); - bool manage_connection(); - std::vector>> get_notifications(); - std::unordered_map>> get_replies(); - void abort(); - - // Synchronous requests - bool get_server_list(u32 req_id, const SceNpCommunicationId& communication_id, std::vector& server_list); - // 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 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); - 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); - bool req_ticket(u32 req_id, const std::string& service_id); - - const std::string& get_online_name() const + struct friend_data { - return online_name; - } - const std::string& get_avatar_url() const - { - return avatar_url; - } - - u32 get_addr_sig() const - { - return addr_sig.load(); - } - u16 get_port_sig() const - { - return port_sig.load(); - } - -protected: - enum class recvn_result - { - recvn_success, - recvn_nodata, - recvn_timeout, - recvn_noconn, - recvn_fatal, + std::map> friends; + std::set requests_sent; + std::set requests_received; + std::set blocked; }; - recvn_result recvn(u8* buf, usz n); + class rpcn_client + { + private: + static inline std::weak_ptr instance; + static inline shared_mutex inst_mutex; - bool get_reply(u32 expected_id, std::vector& data); + atomic_t connected = false; + atomic_t authentified = false; + atomic_t want_auth = false; + std::binary_semaphore sem_connected, sem_authentified; + std::mutex mutex_connected, mutex_authentified; - std::vector forge_request(u16 command, u32 packet_id, const std::vector& data) const; - bool send_packet(const std::vector& packet); - bool forge_send(u16 command, u32 packet_id, const std::vector& data); - bool forge_send_reply(u16 command, u32 packet_id, const std::vector& data, std::vector& reply_data); + std::binary_semaphore sem_reader, sem_writer, sem_rpcn; + std::mutex mutex_read, mutex_write; - bool is_error(ErrorType err) const; - bool error_and_disconnect(const std::string& error_mgs); - bool is_abort() const; + std::thread thread_rpcn, thread_rpcn_reader, thread_rpcn_writer; - std::string get_wolfssl_error(int error) const; + atomic_t terminate = false; -protected: - atomic_t connected = false; - atomic_t authentified = false; + atomic_t num_failures = 0; + atomic_t state = rpcn_state::failure_no_failure; - WOLFSSL_CTX* wssl_ctx = nullptr; - WOLFSSL* wssl = nullptr; + std::vector> packets_to_send; + std::mutex mutex_packets_to_send; - bool in_config = false; - bool abort_config = false; + // Friends related + shared_mutex mutex_friends; + std::set> friend_cbs; + friend_data friend_infos; - atomic_t server_info_received = false; - u32 received_version = 0; + void handle_friend_notification(u16 command, std::vector data); - // UDP Signaling related - steady_clock::time_point last_ping_time{}, last_pong_time{}; + void handle_message(std::vector data); - sockaddr_in addr_rpcn{}; - sockaddr_in addr_rpcn_udp{}; - int sockfd = 0; - shared_mutex mutex_socket; + private: + rpcn_client(); - shared_mutex mutex_notifs, mutex_replies, mutex_replies_sync; - std::vector>> notifications; // notif type / data - std::unordered_map>> replies; // req id / (command / data) - std::unordered_map>> replies_sync; // same but for sync replies(Login, Create, GetServerList) + void rpcn_reader_thread(); + void rpcn_writer_thread(); + void rpcn_thread(); - std::string online_name{}; - std::string avatar_url{}; + bool handle_input(); + bool handle_output(); - s64 user_id = 0; + void add_packet(const std::vector packet); - atomic_t addr_sig{}; - atomic_t port_sig{}; -}; + 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& 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(); + rpcn_client(rpcn_client& other) = delete; + void operator=(const rpcn_client&) = delete; + static std::shared_ptr get_instance(); + rpcn_state wait_for_connection(); + rpcn_state wait_for_authentified(); + + void get_friends_and_register_cb(friend_data& friend_infos, friend_cb_func cb_func, void* cb_param); + void remove_friend_cb(friend_cb_func, void* cb_param); + + ErrorType create_user(const std::string& npid, const std::string& password, const std::string& online_name, const std::string& avatar_url, const std::string& email); + bool add_friend(const std::string& friend_username); + bool remove_friend(const std::string& friend_username); + + u32 get_num_friends() const; + u32 get_num_blocks() const; + + std::vector>> get_notifications(); + std::unordered_map>> get_replies(); + + std::vector get_new_messages(); + std::optional>> get_message(u64 id); + std::vector>>> 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); + void discard_active_message(u64 id); + + bool is_connected() const + { + return connected; + } + bool is_authentified() const + { + return authentified; + } + rpcn_state get_rpcn_state() const + { + return state; + } + + void server_infos_updated(); + + // Synchronous requests + bool get_server_list(u32 req_id, const SceNpCommunicationId& communication_id, std::vector& server_list); + // 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); + 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); + bool req_ticket(u32 req_id, const std::string& service_id); + bool sendmessage(const message_data& msg_data, const std::set& npids); + + const std::string& get_online_name() const + { + return online_name; + } + const std::string& get_avatar_url() const + { + return avatar_url; + } + + u32 get_addr_sig() const + { + return addr_sig.load(); + } + u16 get_port_sig() const + { + return port_sig.load(); + } + + private: + bool get_reply(u64 expected_id, std::vector& data); + + std::vector forge_request(u16 command, u64 packet_id, const std::vector& data) const; + bool forge_send(u16 command, u64 packet_id, const std::vector& data); + bool forge_send_reply(u16 command, u64 packet_id, const std::vector& data, std::vector& reply_data); + + bool is_error(ErrorType err) const; + bool error_and_disconnect(const std::string& error_mgs); + + 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 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{}; + int sockfd = 0; + + atomic_t rpcn_request_counter = 0x100000001; // Counter used for commands whose result is not forwarded to NP handler(login, create, sendmessage, etc) + + shared_mutex mutex_notifs, mutex_replies, mutex_replies_sync; + std::vector>> notifications; // notif type / data + std::unordered_map>> replies; // req id / (command / data) + std::unordered_map>> replies_sync; // same but for sync replies(Login, Create, GetServerList) + + // 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 + { + return (cb_func < other.cb_func) || ((!(other.cb_func < cb_func)) && (cb_param < other.cb_param)); + } + }; + shared_mutex mutex_messages; + std::set message_cbs; + std::unordered_map>> messages; // msg id / (sender / message) + std::set active_messages; // msg id of messages that have not been discarded + std::vector 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; + + atomic_t addr_sig{}; + atomic_t port_sig{}; + }; + +} // namespace rpcn diff --git a/rpcs3/Emu/NP/signaling_handler.cpp b/rpcs3/Emu/NP/signaling_handler.cpp index 917d59df7f..b7d3f1e062 100644 --- a/rpcs3/Emu/NP/signaling_handler.cpp +++ b/rpcs3/Emu/NP/signaling_handler.cpp @@ -290,6 +290,7 @@ void signaling_handler::process_incoming_messages() retire_packet(si, signal_connect); // connection is active update_si_addr(si, op_addr, op_port); + update_si_mapped_addr(si, sp->sent_addr, sp->sent_port); update_si_status(si, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE); break; case signal_confirm: @@ -299,6 +300,7 @@ void signaling_handler::process_incoming_messages() retire_packet(si, signal_connect_ack); // connection is active update_si_addr(si, op_addr, op_port); + update_si_mapped_addr(si, sp->sent_addr, sp->sent_port); update_si_status(si, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, true); break; case signal_finished: @@ -418,6 +420,27 @@ void signaling_handler::update_si_addr(std::shared_ptr& si, u32 } } +void signaling_handler::update_si_mapped_addr(std::shared_ptr& si, u32 new_addr, u16 new_port) +{ + ensure(si); + + if (si->addr != new_addr || si->port != new_port) + { + in_addr addr_old, addr_new; + addr_old.s_addr = si->addr; + addr_new.s_addr = new_addr; + + char ip_str_old[16]; + char ip_str_new[16]; + inet_ntop(AF_INET, &addr_old, ip_str_old, sizeof(ip_str_old)); + inet_ntop(AF_INET, &addr_new, ip_str_new, sizeof(ip_str_new)); + + sign_log.trace("Updated Mapped Address from %s:%d to %s:%d", ip_str_old, si->port, ip_str_new, new_port); + si->mapped_addr = new_addr; + si->mapped_port = new_port; + } +} + void signaling_handler::update_si_status(std::shared_ptr& si, s32 new_status, bool confirm_packet) { if (!si) @@ -485,6 +508,9 @@ void signaling_handler::send_signaling_packet(signaling_packet& sp, u32 addr, u1 sign_log.trace("Sending %s packet to %s:%d", sp.command, ip_str, port); + sp.sent_addr = addr; + sp.sent_port = port; + if (send_packet_from_p2p_port(packet, dest) == -1) { sign_log.error("Failed to send signaling packet to %s:%d", ip_str, port); diff --git a/rpcs3/Emu/NP/signaling_handler.h b/rpcs3/Emu/NP/signaling_handler.h index bf674c62fe..22e4c9351b 100644 --- a/rpcs3/Emu/NP/signaling_handler.h +++ b/rpcs3/Emu/NP/signaling_handler.h @@ -21,6 +21,10 @@ struct signaling_info u32 addr = 0; u16 port = 0; + // User seen from that peer + u32 mapped_addr = 0; + u16 mapped_port = 0; + // For handler steady_clock::time_point time_last_msg_recvd = steady_clock::now(); @@ -84,6 +88,8 @@ private: be_t signature = SIGNALING_SIGNATURE; le_t version; le_t command; + le_t sent_addr; + le_t sent_port; union { struct { @@ -117,6 +123,7 @@ private: u32 create_sig_infos(const SceNpId* npid); static void update_si_addr(std::shared_ptr& si, u32 new_addr, u16 new_port); + static void update_si_mapped_addr(std::shared_ptr& si, u32 new_addr, u16 new_port); void update_si_status(std::shared_ptr& si, s32 new_status, bool confirm_packet = false); void signal_sig_callback(u32 conn_id, int event); void signal_ext_sig_callback(u32 conn_id, int event) const; diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index f75ca57522..783e68e111 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -74,6 +74,8 @@ struct EmuCallbacks std::function()> get_msg_dialog; std::function()> get_osk_dialog; std::function()> get_save_dialog; + std::function()> get_sendmessage_dialog; + std::function()> get_recvmessage_dialog; std::function()> get_trophy_notification_dialog; std::function get_localized_string; std::function get_localized_u32string; diff --git a/rpcs3/Emu/system_config_types.cpp b/rpcs3/Emu/system_config_types.cpp index 104a8940b6..cc70c4f1d1 100644 --- a/rpcs3/Emu/system_config_types.cpp +++ b/rpcs3/Emu/system_config_types.cpp @@ -247,8 +247,8 @@ void fmt_class_string::format(std::string& out, u64 arg) switch (value) { case np_psn_status::disabled: return "Disconnected"; - case np_psn_status::fake: return "Simulated"; - case np_psn_status::rpcn: return "RPCN"; + case np_psn_status::psn_fake: return "Simulated"; + case np_psn_status::psn_rpcn: return "RPCN"; } return unknown; diff --git a/rpcs3/Emu/system_config_types.h b/rpcs3/Emu/system_config_types.h index 32f0717beb..7d5650d30f 100644 --- a/rpcs3/Emu/system_config_types.h +++ b/rpcs3/Emu/system_config_types.h @@ -184,8 +184,8 @@ enum class np_internet_status enum np_psn_status { disabled, - fake, - rpcn, + psn_fake, + psn_rpcn, }; enum class shader_mode diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 7f8a50adab..ff1375b8d9 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -303,6 +303,9 @@ true + + true + true @@ -330,6 +333,9 @@ true + + true + true @@ -495,6 +501,9 @@ true + + true + true @@ -522,6 +531,9 @@ true + + true + true @@ -582,10 +594,12 @@ + + @@ -1064,7 +1078,27 @@ $(QTDIR)\bin\moc.exe;%(FullPath) $(QTDIR)\bin\moc.exe;%(FullPath) + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" + + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" + $(QTDIR)\bin\moc.exe;%(FullPath) diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index b07745130b..3fe6e350f6 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -130,6 +130,9 @@ {949cff6d-9cc5-4a8a-a453-a5144da8ecf4} + + {dfd401ec-dd22-4f8a-9dea-565a03efab6a} + @@ -711,9 +714,6 @@ Generated Files\Release - - Gui\settings - Generated Files\Debug @@ -756,6 +756,27 @@ Generated Files\Release + + Gui\rpcn + + + Gui\message dialog + + + Generated Files\Debug + + + Generated Files\Release + + + Gui\message dialog + + + Generated Files\Debug + + + Generated Files\Release + @@ -1096,9 +1117,6 @@ Gui\network - - Gui\settings - Gui\settings @@ -1111,6 +1129,15 @@ Gui\patch manager + + Gui\rpcn + + + Gui\message dialog + + + Gui\message dialog + diff --git a/rpcs3/rpcs3qt/CMakeLists.txt b/rpcs3/rpcs3qt/CMakeLists.txt index 15cf73983c..9bba87cde6 100644 --- a/rpcs3/rpcs3qt/CMakeLists.txt +++ b/rpcs3/rpcs3qt/CMakeLists.txt @@ -51,6 +51,7 @@ set(SRC_FILES progress_dialog.cpp qt_utils.cpp register_editor_dialog.cpp + recvmessage_dialog_frame.cpp render_creator.cpp rpcn_settings_dialog.cpp rsx_debugger.cpp @@ -60,6 +61,7 @@ set(SRC_FILES save_manager_dialog.cpp screenshot_manager_dialog.cpp screenshot_preview.cpp + sendmessage_dialog_frame.cpp settings.cpp settings_dialog.cpp skylander_dialog.cpp diff --git a/rpcs3/rpcs3qt/emu_settings.cpp b/rpcs3/rpcs3qt/emu_settings.cpp index 69a7974a31..e479f210b2 100644 --- a/rpcs3/rpcs3qt/emu_settings.cpp +++ b/rpcs3/rpcs3qt/emu_settings.cpp @@ -1041,8 +1041,8 @@ QString emu_settings::GetLocalizedSetting(const QString& original, emu_settings_ switch (static_cast(index)) { case np_psn_status::disabled: return tr("Disconnected", "PSN Status"); - case np_psn_status::fake: return tr("Simulated", "PSN Status"); - case np_psn_status::rpcn: return tr("RPCN", "PSN Status"); + case np_psn_status::psn_fake: return tr("Simulated", "PSN Status"); + case np_psn_status::psn_rpcn: return tr("RPCN", "PSN Status"); } break; case emu_settings_type::SleepTimersAccuracy: diff --git a/rpcs3/rpcs3qt/game_compatibility.h b/rpcs3/rpcs3qt/game_compatibility.h index 2572dcd4a3..9c89e94634 100644 --- a/rpcs3/rpcs3qt/game_compatibility.h +++ b/rpcs3/rpcs3qt/game_compatibility.h @@ -163,19 +163,3 @@ private Q_SLOTS: void handle_download_error(const QString& error); void handle_download_finished(const QByteArray& content); }; - -class compat_pixmap : public QPixmap -{ -public: - compat_pixmap(const QColor& color, qreal pixel_ratio) : QPixmap(pixel_ratio * 16, pixel_ratio * 16) - { - fill(Qt::transparent); - - QPainter painter(this); - setDevicePixelRatio(pixel_ratio); - painter.setRenderHint(QPainter::Antialiasing); - painter.setPen(Qt::NoPen); - painter.setBrush(color); - painter.drawEllipse(0, 0, width(), height()); - } -}; diff --git a/rpcs3/rpcs3qt/game_list_frame.cpp b/rpcs3/rpcs3qt/game_list_frame.cpp index 5fca66c4f3..cd6f3c0663 100644 --- a/rpcs3/rpcs3qt/game_list_frame.cpp +++ b/rpcs3/rpcs3qt/game_list_frame.cpp @@ -2350,7 +2350,7 @@ void game_list_frame::PopulateGameList() compat_item->setToolTip(game->compat.tooltip); if (!game->compat.color.isEmpty()) { - compat_item->setData(Qt::DecorationRole, compat_pixmap(game->compat.color, devicePixelRatioF() * 2)); + compat_item->setData(Qt::DecorationRole, gui::utils::circle_pixmap(game->compat.color, devicePixelRatioF() * 2)); } // Version diff --git a/rpcs3/rpcs3qt/gui_application.cpp b/rpcs3/rpcs3qt/gui_application.cpp index a44fee800c..a6c3d455fb 100644 --- a/rpcs3/rpcs3qt/gui_application.cpp +++ b/rpcs3/rpcs3qt/gui_application.cpp @@ -1,3 +1,8 @@ +#ifdef _WIN32 +// This is to avoid inclusion of winsock.h from windows.h header which creates conflicts with inclusion of winsock2.h later +#define _WINSOCKAPI_ +#endif + #include "gui_application.h" #include "qt_utils.h" @@ -23,6 +28,8 @@ #include "save_data_dialog.h" #include "msg_dialog_frame.h" #include "osk_dialog_frame.h" +#include "recvmessage_dialog_frame.h" +#include "sendmessage_dialog_frame.h" #include "stylesheets.h" #include @@ -346,6 +353,8 @@ void gui_application::InitializeCallbacks() callbacks.get_msg_dialog = [this]() -> std::shared_ptr { return m_show_gui ? std::make_shared() : nullptr; }; callbacks.get_osk_dialog = [this]() -> std::shared_ptr { return m_show_gui ? std::make_shared() : nullptr; }; callbacks.get_save_dialog = []() -> std::unique_ptr { return std::make_unique(); }; + callbacks.get_sendmessage_dialog = [this]() -> std::shared_ptr { return std::make_shared(); }; + callbacks.get_recvmessage_dialog = [this]() -> std::shared_ptr { return std::make_shared(); }; callbacks.get_trophy_notification_dialog = [this]() -> std::unique_ptr { return std::make_unique(m_game_window); }; callbacks.on_run = [this](bool start_playtime) { OnEmulatorRun(start_playtime); }; diff --git a/rpcs3/rpcs3qt/qt_utils.h b/rpcs3/rpcs3qt/qt_utils.h index 8efc3da535..acfe442550 100644 --- a/rpcs3/rpcs3qt/qt_utils.h +++ b/rpcs3/rpcs3qt/qt_utils.h @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -17,6 +18,23 @@ namespace gui { namespace utils { + class circle_pixmap : public QPixmap + { + public: + circle_pixmap(const QColor& color, qreal pixel_ratio) + : QPixmap(pixel_ratio * 16, pixel_ratio * 16) + { + fill(Qt::transparent); + + QPainter painter(this); + setDevicePixelRatio(pixel_ratio); + painter.setRenderHint(QPainter::Antialiasing); + painter.setPen(Qt::NoPen); + painter.setBrush(color); + painter.drawEllipse(0, 0, width(), height()); + } + }; + template static QSet list_to_set(const QList& list) { diff --git a/rpcs3/rpcs3qt/recvmessage_dialog_frame.cpp b/rpcs3/rpcs3qt/recvmessage_dialog_frame.cpp new file mode 100644 index 0000000000..8ab0e4709a --- /dev/null +++ b/rpcs3/rpcs3qt/recvmessage_dialog_frame.cpp @@ -0,0 +1,125 @@ +#include +#include +#include +#include +#include "recvmessage_dialog_frame.h" + +#include "util/logs.hpp" + +LOG_CHANNEL(recvmessage_dlg_log, "recvmessage dlg"); + +void recvmessage_callback(void* param, const std::shared_ptr> new_msg, u64 msg_id) +{ + auto* dlg = static_cast(param); + dlg->callback_handler(std::move(new_msg), msg_id); +} + +recvmessage_dialog_frame::~recvmessage_dialog_frame() +{ + if (m_dialog) + { + m_dialog->deleteLater(); + } +} + +bool recvmessage_dialog_frame::Exec(SceNpBasicMessageMainType type, SceNpBasicMessageRecvOptions options, SceNpBasicMessageRecvAction& recv_result, u64& chosen_msg_id) +{ + qRegisterMetaType(); + + if (m_dialog) + { + m_dialog->close(); + delete m_dialog; + } + + m_dialog = new custom_dialog(false); + m_dialog->setModal(true); + + m_dialog->setWindowTitle(tr("Choose message:")); + + m_rpcn = rpcn::rpcn_client::get_instance(); + + QVBoxLayout* vbox_global = new QVBoxLayout(); + + m_lst_messages = new QListWidget(); + vbox_global->addWidget(m_lst_messages); + + QHBoxLayout* hbox_btns = new QHBoxLayout(); + hbox_btns->addStretch(); + QPushButton* btn_accept = new QPushButton(tr("Accept")); + QPushButton* btn_deny = new QPushButton(tr("Deny")); + QPushButton* btn_cancel = new QPushButton(tr("Cancel")); + hbox_btns->addWidget(btn_accept); + hbox_btns->addWidget(btn_deny); + hbox_btns->addWidget(btn_cancel); + vbox_global->addLayout(hbox_btns); + + m_dialog->setLayout(vbox_global); + + bool result = false; + const bool preserve = options & SCE_NP_BASIC_RECV_MESSAGE_OPTIONS_PRESERVE; + const bool include_bootable = options & SCE_NP_BASIC_RECV_MESSAGE_OPTIONS_INCLUDE_BOOTABLE; + + auto accept_or_deny = [preserve, this, &result, &recv_result, &chosen_msg_id](SceNpBasicMessageRecvAction result_from_action) + { + auto selected = m_lst_messages->selectedItems(); + if (selected.empty()) + { + QMessageBox::critical(m_dialog, tr("Error receiving a message!"), tr("You must select a message!"), QMessageBox::Ok); + return; + } + + chosen_msg_id = selected[0]->data(Qt::UserRole).toULongLong(); + recv_result = result_from_action; + result = true; + + if (!preserve) + { + m_rpcn->discard_active_message(chosen_msg_id); + } + + m_dialog->close(); + }; + + connect(btn_accept, &QAbstractButton::clicked, this, [&accept_or_deny]() + { accept_or_deny(SCE_NP_BASIC_MESSAGE_ACTION_ACCEPT); }); + connect(btn_deny, &QAbstractButton::clicked, this, [&accept_or_deny]() + { accept_or_deny(SCE_NP_BASIC_MESSAGE_ACTION_DENY); }); + connect(this, &recvmessage_dialog_frame::signal_new_message, this, &recvmessage_dialog_frame::slot_new_message); + + // Get list of messages + const auto messages = m_rpcn->get_messages_and_register_cb(type, include_bootable, recvmessage_callback, this); + for (const auto& message : messages) + { + add_message(message.second, message.first); + } + + m_dialog->exec(); + + m_rpcn->remove_message_cb(recvmessage_callback, this); + + return result; +} + +void recvmessage_dialog_frame::add_message(const std::shared_ptr>& msg, u64 msg_id) +{ + ensure(msg); + auto new_item = new QListWidgetItem(QString::fromStdString(msg->first)); + new_item->setData(Qt::UserRole, static_cast(msg_id)); + m_lst_messages->addItem(new_item); +} + +void recvmessage_dialog_frame::slot_new_message(recvmessage_signal_struct msg_and_id) +{ + add_message(msg_and_id.msg, msg_and_id.msg_id); +} + +void recvmessage_dialog_frame::callback_handler(std::shared_ptr> new_msg, u64 msg_id) +{ + recvmessage_signal_struct signal_struct = { + .msg = new_msg, + .msg_id = msg_id, + }; + + Q_EMIT signal_new_message(signal_struct); +} diff --git a/rpcs3/rpcs3qt/recvmessage_dialog_frame.h b/rpcs3/rpcs3qt/recvmessage_dialog_frame.h new file mode 100644 index 0000000000..39991dbfc2 --- /dev/null +++ b/rpcs3/rpcs3qt/recvmessage_dialog_frame.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +#include "util/types.hpp" +#include "custom_dialog.h" +#include "Emu/NP/rpcn_client.h" + +struct recvmessage_signal_struct +{ + std::shared_ptr> msg; + u64 msg_id; +}; + +Q_DECLARE_METATYPE(recvmessage_signal_struct); + +class recvmessage_dialog_frame : public QObject, public RecvMessageDialogBase +{ + Q_OBJECT + +public: + recvmessage_dialog_frame() = default; + ~recvmessage_dialog_frame(); + bool Exec(SceNpBasicMessageMainType type, SceNpBasicMessageRecvOptions options, SceNpBasicMessageRecvAction& recv_result, u64& chosen_msg_id) override; + void callback_handler(const std::shared_ptr> new_msg, u64 msg_id); + +private: + void add_message(const std::shared_ptr>& msg, u64 msg_id); + +Q_SIGNALS: + void signal_new_message(const recvmessage_signal_struct msg_and_id); + +private Q_SLOTS: + void slot_new_message(const recvmessage_signal_struct msg_and_id); + +private: + custom_dialog* m_dialog = nullptr; + QListWidget* m_lst_messages = nullptr; + std::shared_ptr m_rpcn; +}; diff --git a/rpcs3/rpcs3qt/rpcn_settings_dialog.cpp b/rpcs3/rpcs3qt/rpcn_settings_dialog.cpp index 9ea5f26afa..76c92a6d2d 100644 --- a/rpcs3/rpcs3qt/rpcn_settings_dialog.cpp +++ b/rpcs3/rpcs3qt/rpcn_settings_dialog.cpp @@ -4,20 +4,90 @@ #include #include #include +#include +#include #include +#include "qt_utils.h" + #include "rpcn_settings_dialog.h" #include "Emu/NP/rpcn_config.h" -#include "Emu/NP/rpcn_client.h" #include #include -rpcn_settings_dialog::rpcn_settings_dialog(QWidget* parent) - : QDialog(parent) +LOG_CHANNEL(rpcn_settings_log, "rpcn settings dlg"); + +const QString rpcn_state_to_qstr(rpcn::rpcn_state state) { - setWindowTitle(tr("RPCN Configuration")); + switch (state) + { + case rpcn::rpcn_state::failure_no_failure: return QObject::tr("No Error"); + case rpcn::rpcn_state::failure_input: return QObject::tr("Invalid Input"); + case rpcn::rpcn_state::failure_wolfssl: return QObject::tr("WolfSSL Error"); + case rpcn::rpcn_state::failure_resolve: return QObject::tr("Resolve Error"); + case rpcn::rpcn_state::failure_connect: return QObject::tr("Connect Error"); + case rpcn::rpcn_state::failure_id: return QObject::tr("Identification Error"); + case rpcn::rpcn_state::failure_id_already_logged_in: return QObject::tr("Identification Error: User Already Logged In"); + case rpcn::rpcn_state::failure_id_username: return QObject::tr("Identification Error: Invalid Username"); + case rpcn::rpcn_state::failure_id_password: return QObject::tr("Identification Error: Invalid Password"); + case rpcn::rpcn_state::failure_id_token: return QObject::tr("Identification Error: Invalid Token"); + case rpcn::rpcn_state::failure_protocol: return QObject::tr("Protocol Version Error"); + case rpcn::rpcn_state::failure_other: return QObject::tr("Unknown Error"); + default: return QObject::tr("Unhandled rpcn state!"); + } +} + +bool validate_rpcn_username(const std::string& input) +{ + if (input.length() < 3 || input.length() > 16) + return false; + + return std::all_of(input.cbegin(), input.cend(), [](const char c) + { return std::isalnum(c) || c == '-' || c == '_'; }); +} + +rpcn_settings_dialog::rpcn_settings_dialog(QWidget* parent) + : QDialog(parent) +{ + setWindowTitle(tr("RPCN")); setObjectName("rpcn_settings_dialog"); + setMinimumSize(QSize(400, 100)); + + QVBoxLayout* vbox_global = new QVBoxLayout(); + + QGroupBox* group_btns = new QGroupBox(tr("RPCN")); + QHBoxLayout* hbox_group = new QHBoxLayout(); + + QPushButton* btn_account = new QPushButton(tr("Account")); + QPushButton* btn_friends = new QPushButton(tr("Friends")); + + hbox_group->addWidget(btn_account); + hbox_group->addWidget(btn_friends); + + group_btns->setLayout(hbox_group); + vbox_global->addWidget(group_btns); + setLayout(vbox_global); + + connect(btn_account, &QPushButton::clicked, this, [this]() + { + rpcn_account_dialog dlg(this); + dlg.exec(); + }); + + connect(btn_friends, &QPushButton::clicked, this, [this]() + { + rpcn_friends_dialog dlg(this); + if (dlg.is_ok()) + dlg.exec(); + }); +} + +rpcn_account_dialog::rpcn_account_dialog(QWidget* parent) + : QDialog(parent) +{ + setWindowTitle(tr("RPCN: Configuration")); + setObjectName("rpcn_account_dialog"); setMinimumSize(QSize(400, 200)); QVBoxLayout* vbox_global = new QVBoxLayout(); @@ -34,12 +104,16 @@ rpcn_settings_dialog::rpcn_settings_dialog(QWidget* parent) m_edit_npid->setValidator(new QRegExpValidator(QRegExp("^[a-zA-Z0-9_\\-]*$"), this)); QLabel* label_pass = new QLabel(tr("Password:")); QPushButton* btn_chg_pass = new QPushButton(tr("Set Password")); - QLabel *label_token = new QLabel(tr("Token:")); + QLabel* label_token = new QLabel(tr("Token:")); m_edit_token = new QLineEdit(); m_edit_token->setMaxLength(16); - QPushButton* btn_create = new QPushButton(tr("Create Account"), this); - QPushButton* btn_save = new QPushButton(tr("Save"), this); + QPushButton* btn_create = new QPushButton(tr("Create Account"), this); + QPushButton* btn_resendtoken = new QPushButton(tr("Resend Token"), this); + btn_resendtoken->setEnabled(false); + QPushButton* btn_changepass = new QPushButton(tr("Change Password"), this); + btn_changepass->setEnabled(false); + QPushButton* btn_save = new QPushButton(tr("Save"), this); vbox_labels->addWidget(label_host); vbox_labels->addWidget(label_npid); @@ -52,6 +126,8 @@ rpcn_settings_dialog::rpcn_settings_dialog(QWidget* parent) vbox_edits->addWidget(m_edit_token); hbox_buttons->addWidget(btn_create); + hbox_buttons->addWidget(btn_resendtoken); + hbox_buttons->addWidget(btn_changepass); hbox_buttons->addStretch(); hbox_buttons->addWidget(btn_save); @@ -63,52 +139,43 @@ rpcn_settings_dialog::rpcn_settings_dialog(QWidget* parent) setLayout(vbox_global); - connect(btn_chg_pass, &QAbstractButton::clicked, [this]() - { - QString password; - - while (true) + connect(btn_chg_pass, &QAbstractButton::clicked, this, [this]() { - bool clicked_ok = false; - password = QInputDialog::getText(this, "Set/Change Password", "Set your password", QLineEdit::Password, "", &clicked_ok); - if (!clicked_ok) + rpcn_ask_password_dialog ask_pass; + ask_pass.exec(); + + auto password = ask_pass.get_password(); + if (!password) return; - if (password.isEmpty()) + const std::string pass_str = password.value(); + const std::string salt_str = "No matter where you go, everybody's connected."; + + u8 salted_pass[SHA_DIGEST_SIZE]; + + wolfSSL_PKCS5_PBKDF2_HMAC_SHA1(pass_str.c_str(), pass_str.size(), reinterpret_cast(salt_str.c_str()), salt_str.size(), 1000, SHA_DIGEST_SIZE, salted_pass); + + std::string hash("0000000000000000000000000000000000000000"); + for (u32 i = 0; i < 20; i++) { - QMessageBox::critical(this, tr("Wrong input"), tr("You need to enter a password!"), QMessageBox::Ok); + constexpr auto pal = "0123456789abcdef"; + hash[i * 2] = pal[salted_pass[i] >> 4]; + hash[1 + i * 2] = pal[salted_pass[i] & 15]; } - else - { - break; - } - } - const std::string pass_str = password.toStdString(); - const std::string salt_str = "No matter where you go, everybody's connected."; + g_cfg_rpcn.set_password(hash); + g_cfg_rpcn.save(); - u8 salted_pass[SHA_DIGEST_SIZE]; + QMessageBox::information(this, tr("RPCN Password Saved"), tr("Your password was saved successfully!"), QMessageBox::Ok); + }); - wolfSSL_PKCS5_PBKDF2_HMAC_SHA1(pass_str.c_str(), pass_str.size(), reinterpret_cast(salt_str.c_str()), salt_str.size(), 1000, SHA_DIGEST_SIZE, salted_pass); - - std::string hash("0000000000000000000000000000000000000000"); - for (u32 i = 0; i < 20; i++) + connect(btn_save, &QAbstractButton::clicked, this, [this]() { - constexpr auto pal = "0123456789abcdef"; - hash[i * 2] = pal[salted_pass[i] >> 4]; - hash[1 + i * 2] = pal[salted_pass[i] & 15]; - } - - g_cfg_rpcn.set_password(hash); - g_cfg_rpcn.save(); - }); - - connect(btn_save, &QAbstractButton::clicked, [this]() - { - if (this->save_config()) - this->close(); - }); - connect(btn_create, &QAbstractButton::clicked, [this]() { this->create_account(); }); + if (this->save_config()) + this->close(); + }); + connect(btn_create, &QAbstractButton::clicked, this, [this]() + { this->create_account(); }); g_cfg_rpcn.load(); @@ -117,20 +184,12 @@ rpcn_settings_dialog::rpcn_settings_dialog(QWidget* parent) m_edit_token->setText(QString::fromStdString(g_cfg_rpcn.get_token())); } -bool rpcn_settings_dialog::save_config() +bool rpcn_account_dialog::save_config() { const auto host = m_edit_host->text().toStdString(); const auto npid = m_edit_npid->text().toStdString(); const auto token = m_edit_token->text().toStdString(); - auto validate = [](const std::string& input) -> bool - { - if (input.length() < 3 || input.length() > 16) - return false; - - return std::all_of(input.cbegin(), input.cend(), [](const char c) { return std::isalnum(c) || c == '-' || c == '_'; }); - }; - if (host.empty()) { QMessageBox::critical(this, tr("Missing host"), tr("You need to enter a host for rpcn!"), QMessageBox::Ok); @@ -143,7 +202,7 @@ bool rpcn_settings_dialog::save_config() return false; } - if (!validate(npid)) + if (!validate_rpcn_username(npid)) { QMessageBox::critical(this, tr("Invalid character"), tr("NPID must be between 3 and 16 characters and can only contain '-', '_' or alphanumeric characters."), QMessageBox::Ok); return false; @@ -164,7 +223,7 @@ bool rpcn_settings_dialog::save_config() return true; } -bool rpcn_settings_dialog::create_account() +bool rpcn_account_dialog::create_account() { // Validate and save if (!save_config()) @@ -176,7 +235,7 @@ bool rpcn_settings_dialog::create_account() while (true) { bool clicked_ok = false; - email = QInputDialog::getText(this, "Email address", "An email address is required, please note:\n*A valid email is needed to validate your account.\n*Your email won't be used for anything beyond sending you the token.\n*Upon successful creation a token will be sent to your email which you'll need to login.\n\n", QLineEdit::Normal, "", &clicked_ok); + email = QInputDialog::getText(this, tr("Email address"), tr("An email address is required, please note:\n*A valid email is needed to validate your account.\n*Your email won't be used for anything beyond sending you the token.\n*Upon successful creation a token will be sent to your email which you'll need to login.\n\n"), QLineEdit::Normal, "", &clicked_ok); if (!clicked_ok) return false; @@ -191,7 +250,7 @@ bool rpcn_settings_dialog::create_account() } } - const auto rpcn = std::make_shared(true); + const auto rpcn = rpcn::rpcn_client::get_instance(); const auto host = g_cfg_rpcn.get_host(); const auto npid = g_cfg_rpcn.get_npid(); @@ -199,32 +258,367 @@ bool rpcn_settings_dialog::create_account() const auto avatar_url = "https://rpcs3.net/cdn/netplay/DefaultAvatar.png"; const auto password = g_cfg_rpcn.get_password(); - std::thread( - [](const std::shared_ptr rpcn) - { - while (rpcn.use_count() != 1) - rpcn->manage_connection(); - - rpcn->disconnect(); - }, - rpcn) - .detach(); - - if (!rpcn->connect(host)) + if (auto result = rpcn->wait_for_connection(); result != rpcn::rpcn_state::failure_no_failure) { - QMessageBox::critical(this, tr("Error Connecting"), tr("Failed to connect to RPCN server"), QMessageBox::Ok); - rpcn->abort(); + const QString error_message = tr("Failed to connect to RPCN server:\n%0").arg(rpcn_state_to_qstr(result)); + QMessageBox::critical(this, tr("Error Connecting"), error_message, QMessageBox::Ok); return false; } - if (!rpcn->create_user(npid, password, online_name, avatar_url, email.toStdString())) + if (auto error = rpcn->create_user(npid, password, online_name, avatar_url, email.toStdString()); error != rpcn::ErrorType::NoError) { - QMessageBox::critical(this, tr("Error Creating Account"), tr("Failed to create the account"), QMessageBox::Ok); - rpcn->abort(); + QString error_message; + switch (error) + { + case rpcn::ErrorType::CreationExistingUsername: error_message = tr("An account with that username already exists!"); break; + case rpcn::ErrorType::CreationBannedEmailProvider: error_message = tr("This email provider is banned!"); break; + case rpcn::ErrorType::CreationExistingEmail: error_message = tr("An account with that email already exists!"); break; + case rpcn::ErrorType::CreationError: error_message = tr("Unknown creation error"); break; + default: error_message = tr("Unknown error"); break; + } + QMessageBox::critical(this, tr("Error Creating Account"), tr("Failed to create the account:\n%0").arg(error_message), QMessageBox::Ok); return false; } QMessageBox::information(this, tr("Account created!"), tr("Your account has been created successfully!\nCheck your email for your token!"), QMessageBox::Ok); - rpcn->abort(); return true; } + +rpcn_ask_password_dialog::rpcn_ask_password_dialog(QWidget* parent) + : QDialog(parent) +{ + QVBoxLayout* vbox_global = new QVBoxLayout(); + QHBoxLayout* hbox_buttons = new QHBoxLayout(); + + QLabel* label_pass1 = new QLabel(tr("Enter your password:")); + m_edit_pass1 = new QLineEdit(); + m_edit_pass1->setEchoMode(QLineEdit::Password); + QLabel* label_pass2 = new QLabel(tr("Enter your password a second time:")); + m_edit_pass2 = new QLineEdit(); + m_edit_pass2->setEchoMode(QLineEdit::Password); + + QPushButton* btn_ok = new QPushButton(tr("Ok")); + QPushButton* btn_cancel = new QPushButton(tr("Cancel")); + + vbox_global->addWidget(label_pass1); + vbox_global->addWidget(m_edit_pass1); + vbox_global->addWidget(label_pass2); + vbox_global->addWidget(m_edit_pass2); + + hbox_buttons->addStretch(); + hbox_buttons->addWidget(btn_ok); + hbox_buttons->addWidget(btn_cancel); + + vbox_global->addLayout(hbox_buttons); + + setLayout(vbox_global); + + connect(btn_ok, &QAbstractButton::clicked, this, [this]() + { + if (m_edit_pass1->text() != m_edit_pass2->text()) + { + QMessageBox::critical(this, tr("Wrong input"), tr("The two passwords you entered don't match!"), QMessageBox::Ok); + return; + } + + if (m_edit_pass1->text().isEmpty()) + { + QMessageBox::critical(this, tr("Wrong input"), tr("You need to enter a password!"), QMessageBox::Ok); + return; + } + + m_password = m_edit_pass1->text().toStdString(); + close(); + }); + connect(btn_cancel, &QAbstractButton::clicked, this, [this]() + { this->close(); }); +} + +std::optional rpcn_ask_password_dialog::get_password() +{ + return m_password; +} + +void friend_callback(void* param, rpcn::NotificationType ntype, const std::string& username, bool status) +{ + auto* dlg = static_cast(param); + dlg->callback_handler(ntype, username, status); +} + +rpcn_friends_dialog::rpcn_friends_dialog(QWidget* parent) + : QDialog(parent), + m_green_icon(gui::utils::circle_pixmap(QColorConstants::Svg::green, devicePixelRatioF() * 2)), + m_red_icon(gui::utils::circle_pixmap(QColorConstants::Svg::red, devicePixelRatioF() * 2)), + m_yellow_icon(gui::utils::circle_pixmap(QColorConstants::Svg::yellow, devicePixelRatioF() * 2)), + m_orange_icon(gui::utils::circle_pixmap(QColorConstants::Svg::orange, devicePixelRatioF() * 2)), + m_black_icon(gui::utils::circle_pixmap(QColorConstants::Svg::black, devicePixelRatioF() * 2)) +{ + setWindowTitle(tr("RPCN: Friends")); + setObjectName("rpcn_friends_dialog"); + setMinimumSize(QSize(400, 100)); + + QVBoxLayout* vbox_global = new QVBoxLayout(); + + QHBoxLayout* hbox_groupboxes = new QHBoxLayout(); + + QGroupBox* grp_list_friends = new QGroupBox(tr("Friends")); + QVBoxLayout* vbox_lst_friends = new QVBoxLayout(); + m_lst_friends = new QListWidget(this); + m_lst_friends->setContextMenuPolicy(Qt::CustomContextMenu); + vbox_lst_friends->addWidget(m_lst_friends); + QPushButton* btn_addfriend = new QPushButton(tr("Add Friend")); + vbox_lst_friends->addWidget(btn_addfriend); + grp_list_friends->setLayout(vbox_lst_friends); + hbox_groupboxes->addWidget(grp_list_friends); + + QGroupBox* grp_list_requests = new QGroupBox(tr("Friend Requests")); + QVBoxLayout* vbox_lst_requests = new QVBoxLayout(); + m_lst_requests = new QListWidget(this); + m_lst_requests->setContextMenuPolicy(Qt::CustomContextMenu); + vbox_lst_requests->addWidget(m_lst_requests); + QHBoxLayout* hbox_request_btns = new QHBoxLayout(); + vbox_lst_requests->addLayout(hbox_request_btns); + grp_list_requests->setLayout(vbox_lst_requests); + hbox_groupboxes->addWidget(grp_list_requests); + + QGroupBox* grp_list_blocks = new QGroupBox(tr("Blocked Users")); + QVBoxLayout* vbox_lst_blocks = new QVBoxLayout(); + m_lst_blocks = new QListWidget(this); + vbox_lst_blocks->addWidget(m_lst_blocks); + grp_list_blocks->setLayout(vbox_lst_blocks); + hbox_groupboxes->addWidget(grp_list_blocks); + + vbox_global->addLayout(hbox_groupboxes); + + setLayout(vbox_global); + + // Tries to connect to RPCN + m_rpcn = rpcn::rpcn_client::get_instance(); + + if (auto res = m_rpcn->wait_for_connection(); res != rpcn::rpcn_state::failure_no_failure) + { + const QString error_msg = tr("Failed to connect to RPCN:\n%0").arg(rpcn_state_to_qstr(res)); + QMessageBox::warning(parent, tr("Error connecting to RPCN!"), error_msg, QMessageBox::Ok); + return; + } + if (auto res = m_rpcn->wait_for_authentified(); res != rpcn::rpcn_state::failure_no_failure) + { + const QString error_msg = tr("Failed to authentify to RPCN:\n%0").arg(rpcn_state_to_qstr(res)); + QMessageBox::warning(parent, tr("Error authentifying to RPCN!"), error_msg, QMessageBox::Ok); + return; + } + + // Get friends, setup callback and setup comboboxes + rpcn::friend_data data; + m_rpcn->get_friends_and_register_cb(data, friend_callback, this); + + for (const auto& fr : data.friends) + { + add_update_list(m_lst_friends, QString::fromStdString(fr.first), fr.second.first ? m_green_icon : m_red_icon, fr.second.first); + } + + for (const auto& fr_req : data.requests_sent) + { + add_update_list(m_lst_requests, QString::fromStdString(fr_req), m_orange_icon, QVariant(false)); + } + + for (const auto& fr_req : data.requests_received) + { + add_update_list(m_lst_requests, QString::fromStdString(fr_req), m_yellow_icon, QVariant(true)); + } + + for (const auto& blck : data.blocked) + { + add_update_list(m_lst_blocks, QString::fromStdString(blck), m_red_icon, QVariant(false)); + } + + connect(this, &rpcn_friends_dialog::signal_add_update_friend, this, &rpcn_friends_dialog::add_update_friend); + connect(this, &rpcn_friends_dialog::signal_remove_friend, this, &rpcn_friends_dialog::remove_friend); + connect(this, &rpcn_friends_dialog::signal_add_query, this, &rpcn_friends_dialog::add_query); + + connect(m_lst_friends, &QListWidget::customContextMenuRequested, this, [this](const QPoint& pos) + { + if (!m_lst_friends->itemAt(pos) || m_lst_friends->selectedItems().count() != 1) + { + return; + } + + QListWidgetItem* selected_item = m_lst_friends->selectedItems().first(); + std::string str_sel_friend = selected_item->text().toStdString(); + + QMenu* context_menu = new QMenu(); + QAction* remove_friend_action = context_menu->addAction(tr("&Remove Friend")); + + connect(remove_friend_action, &QAction::triggered, this, [this, str_sel_friend]() + { + if (!m_rpcn->remove_friend(str_sel_friend)) + { + QMessageBox::critical(this, tr("Error removing a friend!"), tr("An error occured trying to remove a friend!"), QMessageBox::Ok); + } + else + { + QMessageBox::information(this, tr("Friend removed!"), tr("You've successfully removed a friend!"), QMessageBox::Ok); + } + }); + + context_menu->exec(m_lst_friends->viewport()->mapToGlobal(pos)); + context_menu->deleteLater(); + }); + + connect(m_lst_requests, &QListWidget::customContextMenuRequested, this, [this](const QPoint& pos) + { + if (!m_lst_requests->itemAt(pos) || m_lst_requests->selectedItems().count() != 1) + { + return; + } + + QListWidgetItem* selected_item = m_lst_requests->selectedItems().first(); + + // Only create context menu for incoming requests + if (selected_item->data(Qt::UserRole) == false) + { + return; + } + + std::string str_sel_friend = selected_item->text().toStdString(); + + QMenu* context_menu = new QMenu(); + QAction* remove_friend_action = context_menu->addAction(tr("&Accept Request")); + + connect(remove_friend_action, &QAction::triggered, this, [this, str_sel_friend]() + { + if (!m_rpcn->add_friend(str_sel_friend)) + { + QMessageBox::critical(this, tr("Error adding a friend!"), tr("An error occured trying to add a friend!"), QMessageBox::Ok); + } + else + { + QMessageBox::information(this, tr("Friend added!"), tr("You've successfully added a friend!"), QMessageBox::Ok); + } + }); + + context_menu->exec(m_lst_requests->viewport()->mapToGlobal(pos)); + context_menu->deleteLater(); + }); + + connect(btn_addfriend, &QAbstractButton::clicked, this, [this]() + { + std::string str_friend_username; + while (true) + { + bool ok = false; + QString friend_username = QInputDialog::getText(this, tr("Add a friend"), tr("Friend's username:"), QLineEdit::Normal, "", &ok); + if (!ok) + { + return; + } + + str_friend_username = friend_username.toStdString(); + + if (validate_rpcn_username(str_friend_username)) + { + break; + } + + QMessageBox::critical(this, tr("Error validating username"), tr("The username you entered is invalid"), QMessageBox::Ok); + } + + if (!m_rpcn->add_friend(str_friend_username)) + { + QMessageBox::critical(this, tr("Error adding friend"), tr("An error occured adding friend"), QMessageBox::Ok); + } + else + { + add_update_list(m_lst_requests, QString::fromStdString(str_friend_username), m_orange_icon, QVariant(false)); + QMessageBox::information(this, tr("Friend added"), tr("Friend was successfully added!"), QMessageBox::Ok); + } + }); + + m_rpcn_ok = true; +} + +rpcn_friends_dialog::~rpcn_friends_dialog() +{ + m_rpcn->remove_friend_cb(friend_callback, this); +} + +bool rpcn_friends_dialog::is_ok() const +{ + return m_rpcn_ok; +} + +void rpcn_friends_dialog::add_update_list(QListWidget* list, const QString& name, const QIcon& icon, const QVariant& data) +{ + QListWidgetItem* item = nullptr; + if (auto found = list->findItems(name, Qt::MatchExactly); !found.empty()) + { + item = found[0]; + item->setData(Qt::UserRole, data); + item->setIcon(icon); + } + else + { + item = new QListWidgetItem(name); + item->setIcon(icon); + item->setData(Qt::UserRole, data); + list->addItem(item); + } +} + +void rpcn_friends_dialog::remove_list(QListWidget* list, const QString& name) +{ + if (auto found = list->findItems(name, Qt::MatchExactly); !found.empty()) + { + delete list->takeItem(list->row(found[0])); + } +} + +void rpcn_friends_dialog::add_update_friend(QString name, bool status) +{ + add_update_list(m_lst_friends, name, status ? m_green_icon : m_red_icon, status); + remove_list(m_lst_requests, name); +} + +void rpcn_friends_dialog::remove_friend(QString name) +{ + remove_list(m_lst_friends, name); + remove_list(m_lst_requests, name); +} + +void rpcn_friends_dialog::add_query(QString name) +{ + add_update_list(m_lst_requests, name, m_yellow_icon, QVariant(true)); +} + +void rpcn_friends_dialog::callback_handler(rpcn::NotificationType ntype, std::string username, bool status) +{ + QString qtr_username = QString::fromStdString(username); + switch (ntype) + { + case rpcn::NotificationType::FriendQuery: // Other user sent a friend request + { + Q_EMIT signal_add_query(qtr_username); + break; + } + case rpcn::NotificationType::FriendNew: // Add a friend to the friendlist(either accepted a friend request or friend accepted it) + { + Q_EMIT signal_add_update_friend(qtr_username, status); + break; + } + case rpcn::NotificationType::FriendLost: // Remove friend from the friendlist(user removed friend or friend removed friend) + { + Q_EMIT signal_remove_friend(qtr_username); + break; + } + case rpcn::NotificationType::FriendStatus: // Set status of friend to Offline or Online + { + Q_EMIT signal_add_update_friend(qtr_username, status); + break; + } + default: + { + rpcn_settings_log.fatal("An unhandled notification type was received by the rpcn friends dialog callback!"); + break; + } + } +} diff --git a/rpcs3/rpcs3qt/rpcn_settings_dialog.h b/rpcs3/rpcs3qt/rpcn_settings_dialog.h index e3298ca3c5..faaa38af2e 100644 --- a/rpcs3/rpcs3qt/rpcn_settings_dialog.h +++ b/rpcs3/rpcs3qt/rpcn_settings_dialog.h @@ -1,14 +1,25 @@ #pragma once +#include + #include #include +#include + +#include "Emu/NP/rpcn_client.h" class rpcn_settings_dialog : public QDialog { Q_OBJECT - public: rpcn_settings_dialog(QWidget* parent = nullptr); +}; + +class rpcn_account_dialog : public QDialog +{ + Q_OBJECT +public: + rpcn_account_dialog(QWidget* parent = nullptr); bool save_config(); bool create_account(); @@ -16,3 +27,51 @@ public: protected: QLineEdit *m_edit_host, *m_edit_npid, *m_edit_token; }; + +class rpcn_ask_password_dialog : public QDialog +{ + Q_OBJECT +public: + rpcn_ask_password_dialog(QWidget* parent = nullptr); + std::optional get_password(); + +private: + QLineEdit *m_edit_pass1, *m_edit_pass2; + std::optional m_password; +}; + +class rpcn_friends_dialog : public QDialog +{ + Q_OBJECT +public: + rpcn_friends_dialog(QWidget* parent = nullptr); + ~rpcn_friends_dialog(); + void callback_handler(rpcn::NotificationType ntype, std::string username, bool status); + bool is_ok() const; + +private: + void add_update_list(QListWidget* list, const QString& name, const QIcon& icon, const QVariant& data); + void remove_list(QListWidget* list, const QString& name); + +private Q_SLOTS: + void add_update_friend(QString name, bool status); + void remove_friend(QString name); + void add_query(QString name); + +Q_SIGNALS: + void signal_add_update_friend(QString name, bool status); + void signal_remove_friend(QString name); + void signal_add_query(QString name); + +private: + const QIcon m_green_icon, m_red_icon, m_yellow_icon, m_orange_icon, m_black_icon; + // list of friends + QListWidget* m_lst_friends = nullptr; + // list of friend requests sent by/to the current user + QListWidget* m_lst_requests = nullptr; + // list of people blocked by the user + QListWidget* m_lst_blocks = nullptr; + + std::shared_ptr m_rpcn; + bool m_rpcn_ok = false; +}; diff --git a/rpcs3/rpcs3qt/sendmessage_dialog_frame.cpp b/rpcs3/rpcs3qt/sendmessage_dialog_frame.cpp new file mode 100644 index 0000000000..afef0b125b --- /dev/null +++ b/rpcs3/rpcs3qt/sendmessage_dialog_frame.cpp @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include "sendmessage_dialog_frame.h" + +#include "util/logs.hpp" + +LOG_CHANNEL(sendmessage_dlg_log, "sendmessage dlg"); + +void sendmessage_friend_callback(void* param, rpcn::NotificationType ntype, const std::string& username, bool status) +{ + auto* dlg = static_cast(param); + dlg->callback_handler(ntype, username, status); +} + +sendmessage_dialog_frame::~sendmessage_dialog_frame() +{ + if (m_dialog) + { + m_dialog->deleteLater(); + } +} + +bool sendmessage_dialog_frame::Exec(message_data& msg_data, std::set& npids) +{ + if (m_dialog) + { + m_dialog->close(); + delete m_dialog; + } + + m_dialog = new custom_dialog(false); + m_dialog->setModal(true); + + m_dialog->setWindowTitle(tr("Choose friend to message:")); + + m_rpcn = rpcn::rpcn_client::get_instance(); + + QVBoxLayout* vbox_global = new QVBoxLayout(); + + m_lst_friends = new QListWidget(); + vbox_global->addWidget(m_lst_friends); + + QHBoxLayout* hbox_btns = new QHBoxLayout(); + hbox_btns->addStretch(); + QPushButton* btn_ok = new QPushButton(tr("Ok")); + QPushButton* btn_cancel = new QPushButton(tr("Cancel")); + hbox_btns->addWidget(btn_ok); + hbox_btns->addWidget(btn_cancel); + vbox_global->addLayout(hbox_btns); + + m_dialog->setLayout(vbox_global); + + connect(this, &sendmessage_dialog_frame::signal_add_friend, this, &sendmessage_dialog_frame::slot_add_friend); + connect(this, &sendmessage_dialog_frame::signal_remove_friend, this, &sendmessage_dialog_frame::slot_remove_friend); + + bool result = false; + + connect(btn_ok, &QAbstractButton::clicked, this, [this, &msg_data, &npids, &result]() + { + // Check one target is selected + auto selected = m_lst_friends->selectedItems(); + if (selected.empty()) + { + QMessageBox::critical(m_dialog, tr("Error sending a message!"), tr("You must select a friend!"), QMessageBox::Ok); + return; + } + + npids.insert(selected[0]->text().toStdString()); + + // Send the message + result = m_rpcn->sendmessage(msg_data, npids); + m_dialog->close(); + }); + + connect(btn_cancel, &QAbstractButton::clicked, m_dialog, &custom_dialog::close); + + rpcn::friend_data data; + m_rpcn->get_friends_and_register_cb(data, sendmessage_friend_callback, this); + + for (const auto& fr : data.friends) + { + // Only add online friends to the list + if (fr.second.first) + { + add_friend(m_lst_friends, QString::fromStdString(fr.first)); + } + } + + m_dialog->exec(); + + m_rpcn->remove_friend_cb(sendmessage_friend_callback, this); + + return result; +} + +void sendmessage_dialog_frame::add_friend(QListWidget* list, const QString& name) +{ + if (auto found = list->findItems(name, Qt::MatchExactly); !found.empty()) + { + return; + } + + list->addItem(new QListWidgetItem(name)); +} + +void sendmessage_dialog_frame::remove_friend(QListWidget* list, const QString& name) +{ + if (auto found = list->findItems(name, Qt::MatchExactly); !found.empty()) + { + delete list->takeItem(list->row(found[0])); + } +} + +void sendmessage_dialog_frame::slot_add_friend(QString name) +{ + add_friend(m_lst_friends, name); +} + +void sendmessage_dialog_frame::slot_remove_friend(QString name) +{ + remove_friend(m_lst_friends, name); +} + +void sendmessage_dialog_frame::callback_handler(rpcn::NotificationType ntype, const std::string& username, bool status) +{ + QString qtr_username = QString::fromStdString(username); + switch (ntype) + { + case rpcn::NotificationType::FriendQuery: // Other user sent a friend request + break; + case rpcn::NotificationType::FriendNew: // Add a friend to the friendlist(either accepted a friend request or friend accepted it) + { + if (status) + { + Q_EMIT signal_add_friend(qtr_username); + } + break; + } + case rpcn::NotificationType::FriendLost: // Remove friend from the friendlist(user removed friend or friend removed friend) + { + Q_EMIT signal_remove_friend(qtr_username); + break; + } + case rpcn::NotificationType::FriendStatus: // Set status of friend to Offline or Online + { + if (status) + { + Q_EMIT signal_add_friend(qtr_username); + } + else + { + Q_EMIT signal_remove_friend(qtr_username); + } + break; + } + default: + { + sendmessage_dlg_log.fatal("An unhandled notification type was received by the sendmessage dialog callback!"); + break; + } + } +} diff --git a/rpcs3/rpcs3qt/sendmessage_dialog_frame.h b/rpcs3/rpcs3qt/sendmessage_dialog_frame.h new file mode 100644 index 0000000000..21599128a7 --- /dev/null +++ b/rpcs3/rpcs3qt/sendmessage_dialog_frame.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include + +#include "util/types.hpp" +#include "custom_dialog.h" +#include "Emu/NP/rpcn_client.h" + +class sendmessage_dialog_frame : public QObject, public SendMessageDialogBase +{ + Q_OBJECT + +public: + sendmessage_dialog_frame() = default; + ~sendmessage_dialog_frame(); + bool Exec(message_data& msg_data, std::set& npids) override; + void callback_handler(rpcn::NotificationType ntype, const std::string& username, bool status); + +private: + void add_friend(QListWidget* list, const QString& name); + void remove_friend(QListWidget* list, const QString& name); + +private: + custom_dialog* m_dialog = nullptr; + QListWidget* m_lst_friends = nullptr; + + std::shared_ptr m_rpcn; + +Q_SIGNALS: + void signal_add_friend(QString name); + void signal_remove_friend(QString name); + +private Q_SLOTS: + void slot_add_friend(QString name); + void slot_remove_friend(QString name); +};