#include "stdafx.h" #include "np_contexts.h" #include "Emu/Cell/PPUCallback.h" #include "Emu/IdManager.h" #include "Emu/Cell/Modules/cellSysutil.h" LOG_CHANNEL(sceNp2); generic_async_transaction_context::generic_async_transaction_context(const SceNpCommunicationId& communicationId, const SceNpCommunicationPassphrase& passphrase, u64 timeout) : communicationId(communicationId), passphrase(passphrase), timeout(timeout) { } generic_async_transaction_context::~generic_async_transaction_context() { if (thread.joinable()) thread.join(); } std::optional generic_async_transaction_context::get_transaction_status() { std::lock_guard lock(mutex); return result; } void generic_async_transaction_context::abort_transaction() { std::lock_guard lock(mutex); result = SCE_NP_COMMUNITY_ERROR_ABORTED; wake_cond.notify_one(); } error_code generic_async_transaction_context::wait_for_completion() { std::unique_lock lock(mutex); if (result) { return *result; } completion_cond.wait(lock); return *result; } bool generic_async_transaction_context::set_result_and_wake(error_code err) { result = err; wake_cond.notify_one(); return true; } tus_ctx::tus_ctx(vm::cptr communicationId, vm::cptr passphrase) { ensure(!communicationId->data[9] && strlen(communicationId->data) == 9); memcpy(&this->communicationId, communicationId.get_ptr(), sizeof(SceNpCommunicationId)); memcpy(&this->passphrase, passphrase.get_ptr(), sizeof(SceNpCommunicationPassphrase)); } s32 create_tus_context(vm::cptr communicationId, vm::cptr passphrase) { s32 tus_id = idm::make(communicationId, passphrase); if (tus_id == id_manager::id_traits::invalid) { return SCE_NP_COMMUNITY_ERROR_TOO_MANY_OBJECTS; } return static_cast(tus_id); } bool destroy_tus_context(s32 ctx_id) { return idm::remove(static_cast(ctx_id)); } tus_transaction_ctx::tus_transaction_ctx(const std::shared_ptr& tus) : generic_async_transaction_context(tus->communicationId, tus->passphrase, tus->timeout) { } s32 create_tus_transaction_context(const std::shared_ptr& tus) { s32 tus_id = idm::make(tus); if (tus_id == id_manager::id_traits::invalid) { return SCE_NP_COMMUNITY_ERROR_TOO_MANY_OBJECTS; } return static_cast(tus_id); } bool destroy_tus_transaction_context(s32 ctx_id) { return idm::remove(static_cast(ctx_id)); } score_ctx::score_ctx(vm::cptr communicationId, vm::cptr passphrase) { ensure(!communicationId->data[9] && strlen(communicationId->data) == 9); memcpy(&this->communicationId, communicationId.get_ptr(), sizeof(SceNpCommunicationId)); memcpy(&this->passphrase, passphrase.get_ptr(), sizeof(SceNpCommunicationPassphrase)); } s32 create_score_context(vm::cptr communicationId, vm::cptr passphrase) { s32 score_id = idm::make(communicationId, passphrase); if (score_id == id_manager::id_traits::invalid) { return SCE_NP_COMMUNITY_ERROR_TOO_MANY_OBJECTS; } return static_cast(score_id); } bool destroy_score_context(s32 ctx_id) { return idm::remove(static_cast(ctx_id)); } score_transaction_ctx::score_transaction_ctx(const std::shared_ptr& score) : generic_async_transaction_context(score->communicationId, score->passphrase, score->timeout) { pcId = score->pcId; } s32 create_score_transaction_context(const std::shared_ptr& score) { s32 trans_id = idm::make(score); if (trans_id == id_manager::id_traits::invalid) { return SCE_NP_COMMUNITY_ERROR_TOO_MANY_OBJECTS; } return static_cast(trans_id); } bool destroy_score_transaction_context(s32 ctx_id) { return idm::remove(static_cast(ctx_id)); } match2_ctx::match2_ctx(vm::cptr communicationId, vm::cptr passphrase, s32 option) { ensure(!communicationId->data[9] && strlen(communicationId->data) == 9); memcpy(&this->communicationId, communicationId.get_ptr(), sizeof(SceNpCommunicationId)); memcpy(&this->passphrase, passphrase.get_ptr(), sizeof(SceNpCommunicationPassphrase)); include_onlinename = option & SCE_NP_MATCHING2_CONTEXT_OPTION_USE_ONLINENAME; include_avatarurl = option & SCE_NP_MATCHING2_CONTEXT_OPTION_USE_AVATARURL; } u16 create_match2_context(vm::cptr communicationId, vm::cptr passphrase, s32 option) { sceNp2.notice("Creating match2 context with communicationId: <%s>", static_cast(communicationId->data)); return static_cast(idm::make(communicationId, passphrase, option)); } bool destroy_match2_context(u16 ctx_id) { return idm::remove(static_cast(ctx_id)); } bool check_match2_context(u16 ctx_id) { return (idm::check(ctx_id) != nullptr); } std::shared_ptr get_match2_context(u16 ctx_id) { return idm::get(ctx_id); } lookup_title_ctx::lookup_title_ctx(vm::cptr communicationId) { ensure(!communicationId->data[9] && strlen(communicationId->data) == 9); memcpy(&this->communicationId, communicationId.get_ptr(), sizeof(SceNpCommunicationId)); } s32 create_lookup_title_context(vm::cptr communicationId) { return static_cast(idm::make(communicationId)); } bool destroy_lookup_title_context(s32 ctx_id) { return idm::remove(static_cast(ctx_id)); } lookup_transaction_ctx::lookup_transaction_ctx(s32 lt_ctx) { this->lt_ctx = lt_ctx; } s32 create_lookup_transaction_context(s32 lt_ctx) { return static_cast(idm::make(lt_ctx)); } bool destroy_lookup_transaction_context(s32 ctx_id) { return idm::remove(static_cast(ctx_id)); } commerce2_ctx::commerce2_ctx(u32 version, vm::cptr npid, vm::ptr handler, vm::ptr arg) { this->version = version; memcpy(&this->npid, npid.get_ptr(), sizeof(SceNpId)); this->context_callback = handler; this->context_callback_param = arg; } s32 create_commerce2_context(u32 version, vm::cptr npid, vm::ptr handler, vm::ptr arg) { return static_cast(idm::make(version, npid, handler, arg)); } bool destroy_commerce2_context(u32 ctx_id) { return idm::remove(static_cast(ctx_id)); } std::shared_ptr get_commerce2_context(u16 ctx_id) { return idm::get(ctx_id); } signaling_ctx::signaling_ctx(vm::ptr npid, vm::ptr handler, vm::ptr arg) { memcpy(&this->npid, npid.get_ptr(), sizeof(SceNpId)); this->handler = handler; this->arg = arg; } s32 create_signaling_context(vm::ptr npid, vm::ptr handler, vm::ptr arg) { return static_cast(idm::make(npid, handler, arg)); } bool destroy_signaling_context(u32 ctx_id) { return idm::remove(static_cast(ctx_id)); } std::shared_ptr get_signaling_context(u32 ctx_id) { return idm::get(ctx_id); } matching_ctx::matching_ctx(vm::ptr npId, vm::ptr handler, vm::ptr arg) { memcpy(&this->npid, npId.get_ptr(), sizeof(SceNpId)); this->handler = handler; this->arg = arg; } void matching_ctx::queue_callback(u32 req_id, s32 event, s32 error_code) { if (handler) { sysutil_register_cb([=, handler = this->handler, ctx_id = this->ctx_id, arg = this->arg](ppu_thread& cb_ppu) -> s32 { handler(cb_ppu, ctx_id, req_id, event, error_code, arg); return 0; }); } } void matching_ctx::queue_gui_callback(s32 event, s32 error_code) { if (gui_handler) { sysutil_register_cb([=, gui_handler = this->gui_handler, ctx_id = this->ctx_id, gui_arg = this->gui_arg](ppu_thread& cb_ppu) -> s32 { gui_handler(cb_ppu, ctx_id, event, error_code, gui_arg); return 0; }); } } s32 create_matching_context(vm::ptr npId, vm::ptr handler, vm::ptr arg) { const u32 ctx_id = idm::make(npId, handler, arg); auto ctx = get_matching_context(ctx_id); ctx->ctx_id = ctx_id; return static_cast(ctx_id); } std::shared_ptr get_matching_context(u32 ctx_id) { return idm::get(ctx_id); } bool destroy_matching_context(u32 ctx_id) { return idm::remove(static_cast(ctx_id)); }