diff --git a/rpcs3/Emu/Cell/Modules/sceNpTus.cpp b/rpcs3/Emu/Cell/Modules/sceNpTus.cpp index 026e3ce57d..d5e8188f80 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpTus.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpTus.cpp @@ -7,11 +7,149 @@ LOG_CHANNEL(sceNpTus); +// Helper functions + +static bool validateSlotIds(vm::cptr slotIdArray) +{ + if (!slotIdArray) + { + return false; + } + + // TODO: how to properly iterate? + //for (size_t i = 0; i < slotIdArray.size(); ++i) + //{ + // if (slotIdArray[i] < 0) + // { + // return false; + // } + //} + + return true; +} + +s32 sce_np_tus_manager::add_title_context() +{ + if (title_contexts.size() < SCE_NP_TUS_MAX_CTX_NUM) + { + sce_np_tus_title_context new_title_context; + const auto pair = std::make_pair(next_title_context_id, new_title_context); + + if (title_contexts.emplace(pair).second) + { + return next_title_context_id++; + } + } + + return 0; +} + +bool sce_np_tus_manager::check_title_context_id(s32 titleCtxId) +{ + return title_contexts.find(titleCtxId) != title_contexts.end(); +} + +bool sce_np_tus_manager::remove_title_context_id(s32 titleCtxId) +{ + return title_contexts.erase(titleCtxId) > 0; +} + +sce_np_tus_title_context* sce_np_tus_manager::get_title_context(s32 titleCtxId) +{ + if (title_contexts.find(titleCtxId) != title_contexts.end()) + { + return &title_contexts.at(titleCtxId); + } + + return nullptr; +} + +s32 sce_np_tus_manager::add_transaction_context(s32 titleCtxId) +{ + size_t transaction_count = 0; + + for (const auto& title_context : title_contexts) + { + const auto& transactions = title_context.second.transaction_contexts; + transaction_count += transactions.size(); + } + + if (transaction_count < SCE_NP_TUS_MAX_CTX_NUM) + { + if (title_contexts.find(titleCtxId) != title_contexts.end()) + { + sce_np_tus_transaction_context new_transaction; + new_transaction.id = next_transaction_context_id; + + if (title_contexts.at(titleCtxId).transaction_contexts.emplace(next_transaction_context_id, new_transaction).second) + { + return next_transaction_context_id++; + } + } + } + + return 0; +} + +bool sce_np_tus_manager::check_transaction_context_id(s32 transId) +{ + for (const auto& title_context : title_contexts) + { + const auto& transactions = title_context.second.transaction_contexts; + + if (transactions.find(transId) != transactions.end()) + { + return true; + } + } + + return false; +} + +bool sce_np_tus_manager::remove_transaction_context_id(s32 transId) +{ + for (auto& title_context : title_contexts) + { + auto& transactions = title_context.second.transaction_contexts; + + if (transactions.find(transId) != transactions.end()) + { + return transactions.erase(transId) > 0; + } + } + + return false; +} + +sce_np_tus_transaction_context* sce_np_tus_manager::get_transaction_context(s32 transId) +{ + for (auto& title_context : title_contexts) + { + auto& transactions = title_context.second.transaction_contexts; + + if (transactions.find(transId) != transactions.end()) + { + return &transactions.at(transId); + } + } + + return nullptr; +} + +void sce_np_tus_manager::terminate() +{ + title_contexts.clear(); + is_initialized = false; +} + +// Module Functions + error_code sceNpTusInit(s32 prio) { sceNpTus.warning("sceNpTusInit(prio=%d)", prio); const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); if (tus_manager->is_initialized) { @@ -28,372 +166,1863 @@ error_code sceNpTusTerm() sceNpTus.warning("sceNpTusTerm()"); const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); if (!tus_manager->is_initialized) { return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; } - tus_manager->is_initialized = false; + tus_manager->terminate(); return CELL_OK; } -s32 sceNpTusCreateTitleCtx() +error_code sceNpTusCreateTitleCtx(vm::cptr communicationId, vm::cptr passphrase, vm::cptr selfNpId) +{ + sceNpTus.todo("sceNpTusCreateTitleCtx(communicationId=*0x%x, passphrase=*0x%x, selfNpId=*0x%x)", communicationId, passphrase, selfNpId); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!communicationId || !passphrase || !selfNpId) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + const auto id = tus_manager->add_title_context(); + + if (id <= 0) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_OBJECTS; + } + + return not_an_error(id);; +} + +error_code sceNpTusDestroyTitleCtx(s32 titleCtxId) +{ + sceNpTus.todo("sceNpTusDestroyTitleCtx(titleCtxId=%d)", titleCtxId); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_title_context_id(titleCtxId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + return CELL_OK; +} + +error_code sceNpTusCreateTransactionCtx(s32 titleCtxId) +{ + sceNpTus.todo("sceNpTusCreateTransactionCtx(titleCtxId=%d)", titleCtxId); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_title_context_id(titleCtxId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + const auto id = tus_manager->add_transaction_context(titleCtxId); + + if (id <= 0) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_OBJECTS; + } + + return not_an_error(id); +} + +error_code sceNpTusDestroyTransactionCtx(s32 transId) +{ + sceNpTus.todo("sceNpTusDestroyTransactionCtx(transId=%d)", transId); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->remove_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + return CELL_OK; +} + +error_code sceNpTusSetTimeout(s32 ctxId, u32 timeout) +{ + sceNpTus.todo("sceNpTusSetTimeout(ctxId=%d, timeout=%d)", ctxId, timeout); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + auto title_context = tus_manager->get_title_context(ctxId); + auto transaction_context = title_context ? tus_manager->get_transaction_context(ctxId) : nullptr; + + if (!title_context && !transaction_context) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (timeout < 10000000) // 10 seconds + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (title_context) + { + for (auto& [key, val] : title_context->transaction_contexts) + { + val.timeout = timeout; + } + } + else if (transaction_context) + { + transaction_context->timeout = timeout; + } + + return CELL_OK; +} + +error_code sceNpTusAbortTransaction(s32 transId) +{ + sceNpTus.todo("sceNpTusAbortTransaction(transId=%d)", transId); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + auto transaction_context = tus_manager->get_transaction_context(transId); + + if (!transaction_context) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + transaction_context->abort = true; + + return CELL_OK; +} + +error_code sceNpTusWaitAsync(s32 transId, vm::ptr result) +{ + sceNpTus.todo("sceNpTusWaitAsync(transId=%d, result=*0x%x)", transId, result); + + const bool processing_completed = true; + return not_an_error(processing_completed ? 0 : 1); +} + +error_code sceNpTusPollAsync(s32 transId, vm::ptr result) +{ + sceNpTus.todo("sceNpTusPollAsync(transId=%d, result=*0x%x)", transId, result); + + const bool processing_completed = true; + return not_an_error(processing_completed ? 0 : 1); +} + +error_code sceNpTusSetMultiSlotVariable(s32 transId, vm::cptr targetNpId, vm::cptr slotIdArray, vm::cptr variableArray, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusSetMultiSlotVariable(transId=%d, targetNpId=*0x%x, slotIdArray=*0x%x, variableArray=*0x%x, arrayNum=%d, option=*0x%x)", transId, targetNpId, slotIdArray, variableArray, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId || !slotIdArray || !variableArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTusSetMultiSlotVariableVUser(s32 transId, vm::cptr targetVirtualUserId, vm::cptr slotIdArray, vm::cptr variableArray, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusSetMultiSlotVariableVUser(transId=%d, targetVirtualUserId=*0x%x, slotIdArray=*0x%x, variableArray=*0x%x, arrayNum=%d, option=*0x%x)", transId, targetVirtualUserId, slotIdArray, variableArray, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId || !slotIdArray || !variableArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTusSetMultiSlotVariableAsync(s32 transId, vm::cptr targetNpId, vm::cptr slotIdArray, vm::cptr variableArray, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusSetMultiSlotVariableAsync(transId=%d, targetNpId=*0x%x, slotIdArray=*0x%x, variableArray=*0x%x, arrayNum=%d, option=*0x%x)", transId, targetNpId, slotIdArray, variableArray, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId || !slotIdArray || !variableArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTusSetMultiSlotVariableVUserAsync(s32 transId, vm::cptr targetVirtualUserId, vm::cptr slotIdArray, vm::cptr variableArray, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusSetMultiSlotVariableVUserAsync(transId=%d, targetVirtualUserId=*0x%x, slotIdArray=*0x%x, variableArray=*0x%x, arrayNum=%d, option=*0x%x)", transId, targetVirtualUserId, slotIdArray, variableArray, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId || !slotIdArray || !variableArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTusGetMultiSlotVariable(s32 transId, vm::cptr targetNpId, vm::cptr slotIdArray, vm::cptr variableArray, u64 variableArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiSlotVariable(transId=%d, targetNpId=*0x%x, slotIdArray=*0x%x, variableArray=*0x%x, variableArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetNpId, slotIdArray, variableArray, variableArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId || !slotIdArray || !variableArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + const s32 variables_read = 0; + return not_an_error(variables_read); +} + +error_code sceNpTusGetMultiSlotVariableVUser(s32 transId, vm::cptr targetVirtualUserId, vm::cptr slotIdArray, vm::cptr variableArray, u64 variableArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiSlotVariableVUser(transId=%d, targetVirtualUserId=*0x%x, slotIdArray=*0x%x, variableArray=*0x%x, variableArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetVirtualUserId, slotIdArray, variableArray, variableArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + const s32 variables_read = 0; + return not_an_error(variables_read); +} + +error_code sceNpTusGetMultiSlotVariableAsync(s32 transId, vm::cptr targetNpId, vm::cptr slotIdArray, vm::cptr variableArray, u64 variableArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiSlotVariableAsync(transId=%d, targetNpId=*0x%x, slotIdArray=*0x%x, variableArray=*0x%x, variableArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetNpId, slotIdArray, variableArray, variableArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTusGetMultiSlotVariableVUserAsync(s32 transId, vm::cptr targetVirtualUserId, vm::cptr slotIdArray, vm::cptr variableArray, u64 variableArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiSlotVariableVUserAsync(transId=%d, targetVirtualUserId=*0x%x, slotIdArray=*0x%x, variableArray=*0x%x, variableArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetVirtualUserId, slotIdArray, variableArray, variableArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTusGetMultiUserVariable(s32 transId, vm::cptr targetNpIdArray, SceNpTusSlotId slotId, vm::ptr variableArray, u64 variableArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiUserVariable(transId=%d, targetNpIdArray=*0x%x, slotId=%d, variableArray=*0x%x, variableArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetNpIdArray, slotId, variableArray, variableArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpIdArray || !variableArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_USER_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_NPID; + } + + const s32 variables_read = 0; + return not_an_error(variables_read); +} + +error_code sceNpTusGetMultiUserVariableVUser(s32 transId, vm::cptr targetVirtualUserIdArray, SceNpTusSlotId slotId, vm::ptr variableArray, u64 variableArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiUserVariableVUser(transId=%d, targetVirtualUserIdArray=*0x%x, slotId=%d, variableArray=*0x%x, variableArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetVirtualUserIdArray, slotId, variableArray, variableArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserIdArray || !variableArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_USER_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_NPID; + } + + const s32 variables_read = 0; + return not_an_error(variables_read); +} + +error_code sceNpTusGetMultiUserVariableAsync(s32 transId, vm::cptr targetNpIdArray, SceNpTusSlotId slotId, vm::ptr variableArray, u64 variableArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiUserVariableAsync(transId=%d, targetNpIdArray=*0x%x, slotId=%d, variableArray=*0x%x, variableArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetNpIdArray, slotId, variableArray, variableArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpIdArray || !variableArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_USER_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_NPID; + } + + return CELL_OK; +} + +error_code sceNpTusGetMultiUserVariableVUserAsync(s32 transId, vm::cptr targetVirtualUserIdArray, SceNpTusSlotId slotId, vm::ptr variableArray, u64 variableArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiUserVariableVUserAsync(transId=%d, targetVirtualUserIdArray=*0x%x, slotId=%d, variableArray=*0x%x, variableArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetVirtualUserIdArray, slotId, variableArray, variableArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserIdArray || !variableArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_USER_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_NPID; + } + + return CELL_OK; +} + +error_code sceNpTusGetFriendsVariable(s32 transId, SceNpTusSlotId slotId, s32 includeSelf, s32 sortType, vm::ptr variableArray, u64 variableArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetFriendsVariable(transId=%d, slotId=%d, includeSelf=%d, sortType=%d, variableArray=*0x%x, variableArraySize=%d, arrayNum=%d, option=*0x%x)", transId, slotId, includeSelf, sortType, variableArray, variableArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!variableArray) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || arrayNum <= 0 || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SELECTED_FRIENDS_NUM) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_NPID; + } + + const s32 variables_read = 0; + return not_an_error(variables_read); +} + +error_code sceNpTusGetFriendsVariableAsync(s32 transId, SceNpTusSlotId slotId, s32 includeSelf, s32 sortType, vm::ptr variableArray, u64 variableArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetFriendsVariableAsync(transId=%d, slotId=%d, includeSelf=%d, sortType=%d, variableArray=*0x%x, variableArraySize=%d, arrayNum=%d, option=*0x%x)", transId, slotId, includeSelf, sortType, variableArray, variableArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!variableArray) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || arrayNum <= 0 || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SELECTED_FRIENDS_NUM) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_NPID; + } + + return CELL_OK; +} + +error_code sceNpTusAddAndGetVariable(s32 transId, vm::cptr targetNpId, SceNpTusSlotId slotId, s64 inVariable, vm::ptr outVariable, u64 outVariableSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusAddAndGetVariable(transId=%d, targetNpId=*0x%x, slotId=%d, inVariable=%d, outVariable=*0x%x, outVariableSize=%d, option=*0x%x)", transId, targetNpId, slotId, inVariable, outVariable, outVariableSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + return CELL_OK; +} + +error_code sceNpTusAddAndGetVariableVUser(s32 transId, vm::cptr targetVirtualUserId, SceNpTusSlotId slotId, s64 inVariable, vm::ptr outVariable, u64 outVariableSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusAddAndGetVariableVUser(transId=%d, targetVirtualUserId=*0x%x, slotId=%d, inVariable=%d, outVariable=*0x%x, outVariableSize=%d, option=*0x%x)", transId, targetVirtualUserId, slotId, inVariable, outVariable, outVariableSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + return CELL_OK; +} + +error_code sceNpTusAddAndGetVariableAsync(s32 transId, vm::cptr targetNpId, SceNpTusSlotId slotId, s64 inVariable, vm::ptr outVariable, u64 outVariableSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusAddAndGetVariableAsync(transId=%d, targetNpId=*0x%x, slotId=%d, inVariable=%d, outVariable=*0x%x, outVariableSize=%d, option=*0x%x)", transId, targetNpId, slotId, inVariable, outVariable, outVariableSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + return CELL_OK; +} + +error_code sceNpTusAddAndGetVariableVUserAsync(s32 transId, vm::cptr targetVirtualUserId, SceNpTusSlotId slotId, s64 inVariable, vm::ptr outVariable, u64 outVariableSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusAddAndGetVariableVUserAsync(transId=%d, targetVirtualUserId=*0x%x, slotId=%d, inVariable=%d, outVariable=*0x%x, outVariableSize=%d, option=*0x%x)", transId, targetVirtualUserId, slotId, inVariable, outVariable, outVariableSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + return CELL_OK; +} + +error_code sceNpTusTryAndSetVariable(s32 transId, vm::cptr targetNpId, SceNpTusSlotId slotId, s32 opeType, s64 variable, vm::ptr resultVariable, u64 resultVariableSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusTryAndSetVariable(transId=%d, targetNpId=*0x%x, slotId=%d, opeType=%d, variable=%d, resultVariable=*0x%x, resultVariableSize=%d, option=*0x%x)", transId, targetNpId, slotId, opeType, variable, resultVariable, resultVariableSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId || !resultVariable) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + return CELL_OK; +} + +error_code sceNpTusTryAndSetVariableVUser(s32 transId, vm::cptr targetVirtualUserId, SceNpTusSlotId slotId, s32 opeType, s64 variable, vm::ptr resultVariable, u64 resultVariableSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusTryAndSetVariableVUser(transId=%d, targetVirtualUserId=*0x%x, slotId=%d, opeType=%d, variable=%d, resultVariable=*0x%x, resultVariableSize=%d, option=*0x%x)", transId, targetVirtualUserId, slotId, opeType, variable, resultVariable, resultVariableSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId || !resultVariable) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + return CELL_OK; +} + +error_code sceNpTusTryAndSetVariableAsync(s32 transId, vm::cptr targetNpId, SceNpTusSlotId slotId, s32 opeType, s64 variable, vm::ptr resultVariable, u64 resultVariableSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusTryAndSetVariableAsync(transId=%d, targetNpId=*0x%x, slotId=%d, opeType=%d, variable=%d, resultVariable=*0x%x, resultVariableSize=%d, option=*0x%x)", transId, targetNpId, slotId, opeType, variable, resultVariable, resultVariableSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId || !resultVariable) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + return CELL_OK; +} + +error_code sceNpTusTryAndSetVariableVUserAsync(s32 transId, vm::cptr targetVirtualUserId, SceNpTusSlotId slotId, s32 opeType, s64 variable, vm::ptr resultVariable, u64 resultVariableSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusTryAndSetVariableVUserAsync(transId=%d, targetVirtualUserId=*0x%x, slotId=%d, opeType=%d, variable=%d, resultVariable=*0x%x, resultVariableSize=%d, option=*0x%x)", transId, targetVirtualUserId, slotId, opeType, variable, resultVariable, resultVariableSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId || !resultVariable) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + return CELL_OK; +} + +error_code sceNpTusDeleteMultiSlotVariable(s32 transId, vm::cptr targetNpId, vm::cptr slotIdArray, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusDeleteMultiSlotVariable(transId=%d, targetNpId=*0x%x, slotIdArray=*0x%x, arrayNum=%d, option=*0x%x)", transId, targetNpId, slotIdArray, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId || !slotIdArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTusDeleteMultiSlotVariableVUser(s32 transId, vm::cptr targetVirtualUserId, vm::cptr slotIdArray, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusDeleteMultiSlotVariableVUser(transId=%d, targetVirtualUserId=*0x%x, slotIdArray=*0x%x, arrayNum=%d, option=*0x%x)", transId, targetVirtualUserId, slotIdArray, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId || !slotIdArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTusDeleteMultiSlotVariableAsync(s32 transId, vm::cptr targetNpId, vm::cptr slotIdArray, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusDeleteMultiSlotVariableAsync(transId=%d, targetNpId=*0x%x, slotIdArray=*0x%x, arrayNum=%d, option=*0x%x)", transId, targetNpId, slotIdArray, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId || !slotIdArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTusDeleteMultiSlotVariableVUserAsync(s32 transId, vm::cptr targetVirtualUserId, vm::cptr slotIdArray, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusDeleteMultiSlotVariableVUserAsync(transId=%d, targetVirtualUserId=*0x%x, slotIdArray=*0x%x, arrayNum=%d, option=*0x%x)", transId, targetVirtualUserId, slotIdArray, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId || !slotIdArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTusSetData(s32 transId, vm::cptr targetNpId, SceNpTusSlotId slotId, u64 totalSize, u64 sendSize, vm::cptr data, vm::cptr info, u64 infoStructSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusSetData(transId=%d, targetNpId=*0x%x, slotId=%d, totalSize=%d, sendSize=%d, data=*0x%x, info=*0x%x, infoStructSize=%d, option=*0x%x)", transId, targetNpId, slotId, totalSize, sendSize, data, info, infoStructSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId || !data || totalSize == 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + const s32 data_size = 0; + return not_an_error(data_size); +} + +error_code sceNpTusSetDataVUser(s32 transId, vm::cptr targetVirtualUserId, SceNpTusSlotId slotId, u64 totalSize, u64 sendSize, vm::cptr data, vm::cptr info, u64 infoStructSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusSetDataAsync(transId=%d, targetVirtualUserId=*0x%x, slotId=%d, totalSize=%d, sendSize=%d, data=*0x%x, info=*0x%x, infoStructSize=%d, option=*0x%x)", transId, targetVirtualUserId, slotId, totalSize, sendSize, data, info, infoStructSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId || !data || totalSize == 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + const s32 data_size = 0; + return not_an_error(data_size); +} + +error_code sceNpTusSetDataAsync(s32 transId, vm::cptr targetNpId, SceNpTusSlotId slotId, u64 totalSize, u64 sendSize, vm::cptr data, vm::cptr info, u64 infoStructSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusSetDataAsync(transId=%d, targetNpId=*0x%x, slotId=%d, totalSize=%d, sendSize=%d, data=*0x%x, info=*0x%x, infoStructSize=%d, option=*0x%x)", transId, targetNpId, slotId, totalSize, sendSize, data, info, infoStructSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId || !data || totalSize == 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + return CELL_OK; +} + +error_code sceNpTusSetDataVUserAsync(s32 transId, vm::cptr targetVirtualUserId, SceNpTusSlotId slotId, u64 totalSize, u64 sendSize, vm::cptr data, vm::cptr info, u64 infoStructSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusSetDataAsync(transId=%d, targetVirtualUserId=*0x%x, slotId=%d, totalSize=%d, sendSize=%d, data=*0x%x, info=*0x%x, infoStructSize=%d, option=*0x%x)", transId, targetVirtualUserId, slotId, totalSize, sendSize, data, info, infoStructSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId || !data || totalSize == 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + return CELL_OK; +} + +error_code sceNpTusGetData(s32 transId, vm::cptr targetNpId, SceNpTusSlotId slotId, vm::ptr dataStatus, u64 dataStatusSize, vm::ptr data, u64 recvSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetData(transId=%d, targetNpId=*0x%x, slotId=%d, dataStatus=*0x%x, dataStatusSize=%d, data=*0x%x, recvSize=%d, option=*0x%x)", transId, targetNpId, slotId, dataStatus, dataStatusSize, data, recvSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + const s32 data_size = 0; + return not_an_error(data_size); +} + +error_code sceNpTusGetDataVUser(s32 transId, vm::cptr targetVirtualUserId, SceNpTusSlotId slotId, vm::ptr dataStatus, u64 dataStatusSize, vm::ptr data, u64 recvSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetDataVUser(transId=%d, targetVirtualUserId=*0x%x, slotId=%d, dataStatus=*0x%x, dataStatusSize=%d, data=*0x%x, recvSize=%d, option=*0x%x)", transId, targetVirtualUserId, slotId, dataStatus, dataStatusSize, data, recvSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + const s32 data_size = 0; + return not_an_error(data_size); +} + +error_code sceNpTusGetDataAsync(s32 transId, vm::cptr targetNpId, SceNpTusSlotId slotId, vm::ptr dataStatus, u64 dataStatusSize, vm::ptr data, u64 recvSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetDataAsync(transId=%d, targetNpId=*0x%x, slotId=%d, dataStatus=*0x%x, dataStatusSize=%d, data=*0x%x, recvSize=%d, option=*0x%x)", transId, targetNpId, slotId, dataStatus, dataStatusSize, data, recvSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + return CELL_OK; +} + +error_code sceNpTusGetDataVUserAsync(s32 transId, vm::cptr targetVirtualUserId, SceNpTusSlotId slotId, vm::ptr dataStatus, u64 dataStatusSize, vm::ptr data, u64 recvSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetDataVUser(transId=%d, targetVirtualUserId=*0x%x, slotId=%d, dataStatus=*0x%x, dataStatusSize=%d, data=*0x%x, recvSize=%d, option=*0x%x)", transId, targetVirtualUserId, slotId, dataStatus, dataStatusSize, data, recvSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + return CELL_OK; +} + +error_code sceNpTusGetMultiSlotDataStatus(s32 transId, vm::cptr targetNpId, vm::cptr slotIdArray, vm::ptr statusArray, u64 statusArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiSlotDataStatus(transId=%d, targetNpId=*0x%x, slotIdArray=*0x%x, statusArray=*0x%x, statusArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetNpId, slotIdArray, statusArray, statusArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId || !statusArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + const s32 status_count = 0; + return not_an_error(status_count); +} + +error_code sceNpTusGetMultiSlotDataStatusVUser(s32 transId, vm::cptr targetVirtualUserId, vm::cptr slotIdArray, vm::ptr statusArray, u64 statusArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiSlotDataStatusVUser(transId=%d, targetVirtualUserId=*0x%x, slotIdArray=*0x%x, statusArray=*0x%x, statusArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetVirtualUserId, slotIdArray, statusArray, statusArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId || !statusArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + const s32 status_count = 0; + return not_an_error(status_count); +} + +error_code sceNpTusGetMultiSlotDataStatusAsync(s32 transId, vm::cptr targetNpId, vm::cptr slotIdArray, vm::ptr statusArray, u64 statusArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiSlotDataStatusAsync(transId=%d, targetNpId=*0x%x, slotIdArray=*0x%x, statusArray=*0x%x, statusArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetNpId, slotIdArray, statusArray, statusArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId || !statusArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTusGetMultiSlotDataStatusVUserAsync(s32 transId, vm::cptr targetVirtualUserId, vm::cptr slotIdArray, vm::ptr statusArray, u64 statusArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiSlotDataStatusVUser(transId=%d, targetVirtualUserId=*0x%x, slotIdArray=*0x%x, statusArray=*0x%x, statusArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetVirtualUserId, slotIdArray, statusArray, statusArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId || !statusArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTusGetMultiUserDataStatus(s32 transId, vm::cptr targetNpIdArray, SceNpTusSlotId slotId, vm::ptr statusArray, u64 statusArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiUserDataStatus(transId=%d, targetNpIdArray=*0x%x, slotId=%d, statusArray=*0x%x, statusArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetNpIdArray, slotId, statusArray, statusArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpIdArray || !statusArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_USER_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_NPID; + } + + const s32 status_count = 0; + return not_an_error(status_count); +} + +error_code sceNpTusGetMultiUserDataStatusVUser(s32 transId, vm::cptr targetVirtualUserIdArray, SceNpTusSlotId slotId, vm::ptr statusArray, u64 statusArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiUserDataStatusVUser(transId=%d, targetVirtualUserIdArray=*0x%x, slotId=%d, statusArray=*0x%x, statusArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetVirtualUserIdArray, slotId, statusArray, statusArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserIdArray || !statusArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_USER_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_NPID; + } + + const s32 status_count = 0; + return not_an_error(status_count); +} + +error_code sceNpTusGetMultiUserDataStatusAsync(s32 transId, vm::cptr targetNpIdArray, SceNpTusSlotId slotId, vm::ptr statusArray, u64 statusArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiUserDataStatusAsync(transId=%d, targetNpIdArray=*0x%x, slotId=%d, statusArray=*0x%x, statusArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetNpIdArray, slotId, statusArray, statusArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpIdArray || !statusArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_USER_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_NPID; + } + + return CELL_OK; +} + +error_code sceNpTusGetMultiUserDataStatusVUserAsync(s32 transId, vm::cptr targetVirtualUserIdArray, SceNpTusSlotId slotId, vm::ptr statusArray, u64 statusArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetMultiUserDataStatusVUserAsync(transId=%d, targetVirtualUserIdArray=*0x%x, slotId=%d, statusArray=*0x%x, statusArraySize=%d, arrayNum=%d, option=*0x%x)", transId, targetVirtualUserIdArray, slotId, statusArray, statusArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserIdArray || !statusArray || arrayNum <= 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_USER_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_NPID; + } + + return CELL_OK; +} + +error_code sceNpTusGetFriendsDataStatus(s32 transId, SceNpTusSlotId slotId, s32 includeSelf, s32 sortType, vm::ptr statusArray, u64 statusArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetFriendsDataStatus(transId=%d, slotId=%d, includeSelf=%d, sortType=%d, statusArray=*0x%x, statusArraySize=%d, arrayNum=%d, option=*0x%x)", transId, slotId, includeSelf, sortType, statusArray, statusArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!statusArray) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || arrayNum < 0 || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SELECTED_FRIENDS_NUM) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_NPID; + } + + const s32 status_count = 0; + return not_an_error(status_count); +} + +error_code sceNpTusGetFriendsDataStatusAsync(s32 transId, SceNpTusSlotId slotId, s32 includeSelf, s32 sortType, vm::ptr statusArray, u64 statusArraySize, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusGetFriendsDataStatusAsync(transId=%d, slotId=%d, includeSelf=%d, sortType=%d, statusArray=*0x%x, statusArraySize=%d, arrayNum=%d, option=*0x%x)", transId, slotId, includeSelf, sortType, statusArray, statusArraySize, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!statusArray) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || arrayNum < 0 || slotId < 0) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SELECTED_FRIENDS_NUM) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_NPID; + } + + return CELL_OK; +} + +error_code sceNpTusDeleteMultiSlotData(s32 transId, vm::cptr targetNpId, vm::cptr slotIdArray, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusDeleteMultiSlotData(transId=%d, targetNpId=*0x%x, slotIdArray=*0x%x, arrayNum=%d, option=*0x%x)", transId, targetNpId, slotIdArray, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId || !slotIdArray || arrayNum < 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTusDeleteMultiSlotDataVUser(s32 transId, vm::cptr targetVirtualUserId, vm::cptr slotIdArray, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusDeleteMultiSlotDataVUser(transId=%d, targetVirtualUserId=*0x%x, slotIdArray=*0x%x, arrayNum=%d, option=*0x%x)", transId, targetVirtualUserId, slotIdArray, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId || !slotIdArray || arrayNum < 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTusDeleteMultiSlotDataAsync(s32 transId, vm::cptr targetNpId, vm::cptr slotIdArray, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusDeleteMultiSlotDataAsync(transId=%d, targetNpId=*0x%x, slotIdArray=*0x%x, arrayNum=%d, option=*0x%x)", transId, targetNpId, slotIdArray, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetNpId || !slotIdArray || arrayNum < 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTusDeleteMultiSlotDataVUserAsync(s32 transId, vm::cptr targetVirtualUserId, vm::cptr slotIdArray, s32 arrayNum, vm::ptr option) +{ + sceNpTus.todo("sceNpTusDeleteMultiSlotDataVUserAsync(transId=%d, targetVirtualUserId=*0x%x, slotIdArray=*0x%x, arrayNum=%d, option=*0x%x)", transId, targetVirtualUserId, slotIdArray, arrayNum, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!targetVirtualUserId || !slotIdArray || arrayNum < 0) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + if (option || !validateSlotIds(slotIdArray)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT; + } + + if (arrayNum > SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS) + { + return SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID; + } + + return CELL_OK; +} + +error_code sceNpTssGetData(s32 transId, SceNpTssSlotId slotId, vm::ptr dataStatus, u64 dataStatusSize, vm::ptr data, u64 recvSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTssGetData(transId=%d, slotId=%d, dataStatus=*0x%x, dataStatusSize=%d, data=*0x%x, recvSize=%d, option=*0x%x)", transId, slotId, dataStatus, dataStatusSize, data, recvSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!dataStatus) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + return CELL_OK; +} + +error_code sceNpTssGetDataAsync(s32 transId, SceNpTssSlotId slotId, vm::ptr dataStatus, u64 dataStatusSize, vm::ptr data, u64 recvSize, vm::ptr option) +{ + sceNpTus.todo("sceNpTssGetDataAsync(transId=%d, slotId=%d, dataStatus=*0x%x, dataStatusSize=%d, data=*0x%x, recvSize=%d, option=*0x%x)", transId, slotId, dataStatus, dataStatusSize, data, recvSize, option); + + const auto tus_manager = g_fxo->get(); + std::scoped_lock lock(tus_manager->mtx); + + if (!tus_manager->is_initialized) + { + return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; + } + + if (!tus_manager->check_transaction_context_id(transId)) + { + return SCE_NP_COMMUNITY_ERROR_INVALID_ID; + } + + if (!dataStatus) + { + return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT; + } + + return CELL_OK; +} + +error_code sceNpTssGetDataNoLimit() { UNIMPLEMENTED_FUNC(sceNpTus); return CELL_OK; } -s32 sceNpTusDestroyTitleCtx() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusCreateTransactionCtx() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusDestroyTransactionCtx() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusSetTimeout() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusAbortTransaction() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusWaitAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusPollAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusSetMultiSlotVariable() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusSetMultiSlotVariableVUser() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusSetMultiSlotVariableAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusSetMultiSlotVariableVUserAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiSlotVariable() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiSlotVariableVUser() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiSlotVariableAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiSlotVariableVUserAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiUserVariable() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiUserVariableVUser() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiUserVariableAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiUserVariableVUserAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetFriendsVariable() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetFriendsVariableAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusAddAndGetVariable() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusAddAndGetVariableVUser() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusAddAndGetVariableAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusAddAndGetVariableVUserAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusTryAndSetVariable() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusTryAndSetVariableVUser() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusTryAndSetVariableAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusTryAndSetVariableVUserAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusDeleteMultiSlotVariable() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusDeleteMultiSlotVariableVUser() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusDeleteMultiSlotVariableAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusDeleteMultiSlotVariableVUserAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusSetData() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusSetDataVUser() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusSetDataAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusSetDataVUserAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetData() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetDataVUser() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetDataAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetDataVUserAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiSlotDataStatus() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiSlotDataStatusVUser() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiSlotDataStatusAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiSlotDataStatusVUserAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiUserDataStatus() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiUserDataStatusVUser() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiUserDataStatusAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetMultiUserDataStatusVUserAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetFriendsDataStatus() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusGetFriendsDataStatusAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusDeleteMultiSlotData() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusDeleteMultiSlotDataVUser() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusDeleteMultiSlotDataAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTusDeleteMultiSlotDataVUserAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTssGetData() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTssGetDataAsync() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTssGetDataNoLimit() -{ - UNIMPLEMENTED_FUNC(sceNpTus); - return CELL_OK; -} - -s32 sceNpTssGetDataNoLimitAsync() +error_code sceNpTssGetDataNoLimitAsync() { UNIMPLEMENTED_FUNC(sceNpTus); return CELL_OK; diff --git a/rpcs3/Emu/Cell/Modules/sceNpTus.h b/rpcs3/Emu/Cell/Modules/sceNpTus.h index ca5340cdf8..cd1e49f8fd 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpTus.h +++ b/rpcs3/Emu/Cell/Modules/sceNpTus.h @@ -6,6 +6,7 @@ #include "sceNp.h" #include +#include // Constants for TUS functions and structures enum @@ -14,9 +15,25 @@ enum SCE_NP_TUS_MAX_CTX_NUM = 32, SCE_NP_TUS_MAX_SLOT_NUM_PER_TRANS = 64, SCE_NP_TUS_MAX_USER_NUM_PER_TRANS = 101, + SCE_NP_TUS_MAX_SELECTED_FRIENDS_NUM = 100, }; -SceNpOnlineId SceNpTusVirtualUserId; +enum SceNpTssStatusCodeType +{ + SCE_NP_TSS_STATUS_TYPE_OK, + SCE_NP_TSS_STATUS_TYPE_PARTIAL, + SCE_NP_TSS_STATUS_TYPE_NOT_MODIFIED +}; + +enum SceNpTssIfType +{ + SCE_NP_TSS_IFTYPE_IF_MODIFIED_SINCE, + SCE_NP_TSS_IFTYPE_IF_RANGE +}; + +using SceNpTssSlotId = s32; +using SceNpTusSlotId = s32; +using SceNpTusVirtualUserId = SceNpOnlineId; // Structure for representing a TUS variable struct SceNpTusVariable @@ -52,9 +69,84 @@ struct SceNpTusDataStatus SceNpTusDataInfo info; }; +struct SceNpTusAddAndGetVariableOptParam +{ + u64 size; // TODO: correct type? + vm::ptr isLastChangedDate; + vm::ptr isLastChangedAuthorId; +}; + +struct SceNpTusTryAndSetVariableOptParam +{ + u64 size; // TODO: correct type? + vm::ptr isLastChangedDate; + vm::ptr isLastChangedAuthorId; + vm::ptr compareValue; +}; + +struct SceNpTusSetDataOptParam +{ + u64 size; // TODO: correct type? + vm::ptr isLastChangedDate; + vm::ptr isLastChangedAuthorId; +}; + +struct SceNpTssDataStatus +{ + CellRtcTick lastModified; + s32 statusCodeType; + u64 contentLength; +}; + +struct SceNpTssIfModifiedSinceParam +{ + s32 ifType; + u8 padding[4]; + CellRtcTick lastModified; +}; + +struct SceNpTssGetDataOptParam +{ + u64 size; // TODO: correct type? + vm::ptr offset; + vm::ptr lastByte; + vm::ptr ifParam; +}; + // fxm objects +struct sce_np_tus_transaction_context +{ + s32 id = 0; + u32 timeout = 0; + bool abort = false; +}; + +struct sce_np_tus_title_context +{ + std::map transaction_contexts; +}; + struct sce_np_tus_manager { +private: + s32 next_title_context_id = 1; + s32 next_transaction_context_id = 1; + std::map title_contexts; + +public: + std::mutex mtx; std::atomic is_initialized = false; + + s32 add_title_context(); + bool check_title_context_id(s32 titleCtxId); + bool remove_title_context_id(s32 titleCtxId); + sce_np_tus_title_context* get_title_context(s32 titleCtxId); + + s32 add_transaction_context(s32 titleCtxId); + bool check_transaction_context_id(s32 transId); + bool remove_transaction_context_id(s32 transId); + sce_np_tus_transaction_context* get_transaction_context(s32 transId); + + void terminate(); };