Clans: Emulator and server implementation (#17835)
This PR implements the Sony Clans subsystem for the RPCS3 emulator. Used in: - PlayStation Home [NPIA00005] - ? Addresses and closes [#16464](https://github.com/RPCS3/rpcs3/issues/16464). --- The source code for the server is available [here](https://github.com/ZephyrCodesStuff/clans-rs) and is licensed AGPLv3. - It's written in Rust, with my best efforts in readability and documentation. - Every feature not-pertaining to RPCS3 has been feature-gated at compile-time. - Fully Dockerized deployment - Ticket signature verification NOTE: The server is fully compatible with the PS3 console as well, as it follows the PS3 Clans Library specification. --- The emulator code tries its best to follow on the steps of the RPCN client code wherever possible; both in the Client as well as the Settings and Config components. Features: - Clans client implementation in `clans_client.[h,cpp]` - Syscalls implementation in `sceNpClans.[h,cpp]` - A couple of missing structs and/or enum members have been added in `sceNp.h` - Qt GUI for selecting the desired Clans server to use (default: [HTTPS] `clans.rpcs3.net`) - Implemented in `clans_settings_dialog.[h,cpp]` - Prevents modifying during emulator usage - `clans.yml` config file for persistence - Implemented in `clans_config.[h,cpp]` --------- Signed-off-by: zeph <35661622+ZephyrCodesStuff@users.noreply.github.com> Signed-off-by: zeph <zephyrzefa15@gmail.com>
This commit is contained in:
@@ -442,6 +442,8 @@ target_sources(rpcs3_emu PRIVATE
|
|||||||
NP/np_requests.cpp
|
NP/np_requests.cpp
|
||||||
NP/signaling_handler.cpp
|
NP/signaling_handler.cpp
|
||||||
NP/np_structs_extra.cpp
|
NP/np_structs_extra.cpp
|
||||||
|
NP/clans_client.cpp
|
||||||
|
NP/clans_config.cpp
|
||||||
NP/rpcn_client.cpp
|
NP/rpcn_client.cpp
|
||||||
NP/rpcn_config.cpp
|
NP/rpcn_config.cpp
|
||||||
NP/rpcn_countries.cpp
|
NP/rpcn_countries.cpp
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ using SceNpBasicMessageRecvAction = u32;
|
|||||||
|
|
||||||
using SceNpClanId = u32;
|
using SceNpClanId = u32;
|
||||||
using SceNpClansMessageId = u32;
|
using SceNpClansMessageId = u32;
|
||||||
|
using SceNpClansMemberRole = u32;
|
||||||
using SceNpClansMemberStatus = s32;
|
using SceNpClansMemberStatus = s32;
|
||||||
|
|
||||||
using SceNpCustomMenuIndexMask = u32;
|
using SceNpCustomMenuIndexMask = u32;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "Emu/Cell/ErrorCodes.h"
|
||||||
#include "Emu/Cell/PPUModule.h"
|
#include "Emu/Cell/PPUModule.h"
|
||||||
#include "Emu/IdManager.h"
|
#include "Emu/IdManager.h"
|
||||||
|
|
||||||
@@ -540,7 +541,9 @@ error_code sceNpMatching2GetClanLobbyId(SceNpMatching2ContextId ctxId, SceNpClan
|
|||||||
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
|
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
// Returning this rather than `CELL_OK` allows for games to
|
||||||
|
// not need Matching2 Clans support to connect, when Clans are enabled.
|
||||||
|
return SCE_NP_MATCHING2_SERVER_ERROR_SERVICE_UNAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpMatching2GetLobbyMemberDataInternal(
|
error_code sceNpMatching2GetLobbyMemberDataInternal(
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Emu/Cell/PPUModule.h"
|
#include "Emu/Cell/PPUModule.h"
|
||||||
#include "Emu/IdManager.h"
|
#include "Emu/IdManager.h"
|
||||||
|
#include "Emu/NP/np_handler.h"
|
||||||
|
#include "Emu/NP/clans_client.h"
|
||||||
|
|
||||||
#include "sceNp.h"
|
#include "sceNp.h"
|
||||||
|
#include <memory>
|
||||||
#include "sceNpClans.h"
|
#include "sceNpClans.h"
|
||||||
|
|
||||||
|
|
||||||
LOG_CHANNEL(sceNpClans);
|
LOG_CHANNEL(sceNpClans);
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
@@ -14,6 +18,7 @@ void fmt_class_string<SceNpClansError>::format(std::string& out, u64 arg)
|
|||||||
{
|
{
|
||||||
switch (error)
|
switch (error)
|
||||||
{
|
{
|
||||||
|
STR_CASE(SCE_NP_CLANS_SUCCESS);
|
||||||
STR_CASE(SCE_NP_CLANS_ERROR_ALREADY_INITIALIZED);
|
STR_CASE(SCE_NP_CLANS_ERROR_ALREADY_INITIALIZED);
|
||||||
STR_CASE(SCE_NP_CLANS_ERROR_NOT_INITIALIZED);
|
STR_CASE(SCE_NP_CLANS_ERROR_NOT_INITIALIZED);
|
||||||
STR_CASE(SCE_NP_CLANS_ERROR_NOT_SUPPORTED);
|
STR_CASE(SCE_NP_CLANS_ERROR_NOT_SUPPORTED);
|
||||||
@@ -94,6 +99,9 @@ error_code sceNpClansInit(vm::cptr<SceNpCommunicationId> commId, vm::cptr<SceNpC
|
|||||||
return SCE_NP_CLANS_ERROR_NOT_SUPPORTED;
|
return SCE_NP_CLANS_ERROR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allocate space for a client somewhere
|
||||||
|
std::shared_ptr<clan::clans_client> client = std::make_shared<clan::clans_client>();
|
||||||
|
clans_manager.client = client;
|
||||||
clans_manager.is_initialized = true;
|
clans_manager.is_initialized = true;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
@@ -110,6 +118,7 @@ error_code sceNpClansTerm()
|
|||||||
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clans_manager.client.reset();
|
||||||
clans_manager.is_initialized = false;
|
clans_manager.is_initialized = false;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
@@ -117,7 +126,7 @@ error_code sceNpClansTerm()
|
|||||||
|
|
||||||
error_code sceNpClansCreateRequest(vm::ptr<SceNpClansRequestHandle> handle, u64 flags)
|
error_code sceNpClansCreateRequest(vm::ptr<SceNpClansRequestHandle> handle, u64 flags)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansCreateRequest(handle=*0x%x, flags=0x%llx)", handle, flags);
|
sceNpClans.warning("sceNpClansCreateRequest(handle=*0x%x, flags=0x%x)", handle, flags);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -134,36 +143,58 @@ error_code sceNpClansCreateRequest(vm::ptr<SceNpClansRequestHandle> handle, u64
|
|||||||
return SCE_NP_CLANS_ERROR_NOT_SUPPORTED;
|
return SCE_NP_CLANS_ERROR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
s32 reqId = 0;
|
||||||
|
SceNpClansError res = clans_manager.client->create_request(&reqId);
|
||||||
|
if (res != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
*handle = reqId;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansDestroyRequest(vm::ptr<SceNpClansRequestHandle> handle)
|
error_code sceNpClansDestroyRequest(SceNpClansRequestHandle handle)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansDestroyRequest(handle=*0x%x)", handle);
|
sceNpClans.warning("sceNpClansDestroyRequest(handle=*0x%x)", handle);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpClansError res = clans_manager.client->destroy_request(handle);
|
||||||
|
if (res != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansAbortRequest(vm::ptr<SceNpClansRequestHandle> handle)
|
error_code sceNpClansAbortRequest(SceNpClansRequestHandle handle)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansAbortRequest(handle=*0x%x)", handle);
|
sceNpClans.warning("sceNpClansAbortRequest(handle=*0x%x)", handle);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
clans_manager.client->destroy_request(handle);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansCreateClan(vm::ptr<SceNpClansRequestHandle> handle, vm::cptr<char> name, vm::cptr<char> tag, vm::ptr<SceNpClanId> clanId)
|
error_code sceNpClansCreateClan(SceNpClansRequestHandle handle, vm::cptr<char> name, vm::cptr<char> tag, vm::ptr<SceNpClanId> clanId)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansCreateClan(handle=*0x%x, name=%s, tag=%s, clanId=*0x%x)", handle, name, tag, clanId);
|
sceNpClans.warning("sceNpClansCreateClan(handle=*0x%x, name=%s, tag=%s, clanId=*0x%x)", handle, name, tag, clanId);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -180,31 +211,60 @@ error_code sceNpClansCreateClan(vm::ptr<SceNpClansRequestHandle> handle, vm::cpt
|
|||||||
return SCE_NP_CLANS_ERROR_EXCEEDS_MAX;
|
return SCE_NP_CLANS_ERROR_EXCEEDS_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
std::string name_str;
|
||||||
|
vm::read_string(name.addr(), SCE_NP_CLANS_CLAN_NAME_MAX_LENGTH, name_str);
|
||||||
|
|
||||||
|
std::string tag_str;
|
||||||
|
vm::read_string(tag.addr(), SCE_NP_CLANS_CLAN_TAG_MAX_LENGTH, tag_str);
|
||||||
|
|
||||||
|
SceNpClansError res = clans_manager.client->create_clan(nph, handle, name_str, tag_str, clanId);
|
||||||
|
if (res != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansDisbandClan(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId)
|
error_code sceNpClansDisbandClan(SceNpClansRequestHandle handle, SceNpClanId clanId)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansDisbandClan(handle=*0x%x, clanId=*0x%x)", handle, clanId);
|
sceNpClans.warning("sceNpClansDisbandClan(handle=*0x%x, clanId=*0x%x)", handle, clanId);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!clanId)
|
||||||
|
{
|
||||||
|
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpClansError res = clans_manager.client->disband_dlan(nph, handle, clanId);
|
||||||
|
if (res != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansGetClanList(vm::ptr<SceNpClansRequestHandle> handle, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansEntry> clanList, vm::ptr<SceNpClansPagingResult> pageResult)
|
error_code sceNpClansGetClanList(SceNpClansRequestHandle handle, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansEntry> clanList, vm::ptr<SceNpClansPagingResult> pageResult)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansGetClanList(handle=*0x%x, paging=*0x%x, clanList=*0x%x, pageResult=*0x%x)", handle, paging, clanList, pageResult);
|
sceNpClans.warning("sceNpClansGetClanList(handle=*0x%x, paging=*0x%x, clanList=*0x%x, pageResult=*0x%x)", handle, paging, clanList, pageResult);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pageResult || (paging && !clanList)) // TODO: confirm
|
if (!pageResult || (paging && !clanList))
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
@@ -217,10 +277,35 @@ error_code sceNpClansGetClanList(vm::ptr<SceNpClansRequestHandle> handle, vm::cp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpClansPagingRequest host_paging = {};
|
||||||
|
if (paging)
|
||||||
|
{
|
||||||
|
std::memcpy(&host_paging, paging.get_ptr(), sizeof(SceNpClansPagingRequest));
|
||||||
|
}
|
||||||
|
|
||||||
|
SceNpClansEntry host_clanList[SCE_NP_CLANS_PAGING_REQUEST_PAGE_MAX] = {};
|
||||||
|
SceNpClansPagingResult host_pageResult = {};
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->get_clan_list(nph, handle, &host_paging, host_clanList, &host_pageResult);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clanList && host_pageResult.count > 0)
|
||||||
|
{
|
||||||
|
std::memcpy(clanList.get_ptr(), host_clanList, sizeof(SceNpClansEntry) * host_pageResult.count);
|
||||||
|
}
|
||||||
|
std::memcpy(pageResult.get_ptr(), &host_pageResult, sizeof(SceNpClansPagingResult));
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansGetClanListByNpId(vm::ptr<SceNpClansRequestHandle> handle, vm::cptr<SceNpClansPagingRequest> paging, vm::cptr<SceNpId> npid, vm::ptr<SceNpClansEntry> clanList, vm::ptr<SceNpClansPagingResult> pageResult)
|
// TODO: seems to not be needed, even by the PS3..?
|
||||||
|
error_code sceNpClansGetClanListByNpId(SceNpClansRequestHandle handle, vm::cptr<SceNpClansPagingRequest> paging, vm::cptr<SceNpId> npid, vm::ptr<SceNpClansEntry> clanList, vm::ptr<SceNpClansPagingResult> pageResult)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansGetClanListByNpId(handle=*0x%x, paging=*0x%x, npid=*0x%x, clanList=*0x%x, pageResult=*0x%x)", handle, paging, npid, clanList, pageResult);
|
sceNpClans.todo("sceNpClansGetClanListByNpId(handle=*0x%x, paging=*0x%x, npid=*0x%x, clanList=*0x%x, pageResult=*0x%x)", handle, paging, npid, clanList, pageResult);
|
||||||
|
|
||||||
@@ -245,7 +330,8 @@ error_code sceNpClansGetClanListByNpId(vm::ptr<SceNpClansRequestHandle> handle,
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansSearchByProfile(vm::ptr<SceNpClansRequestHandle> handle, vm::cptr<SceNpClansPagingRequest> paging, vm::cptr<SceNpClansSearchableProfile> search, vm::ptr<SceNpClansClanBasicInfo> results, vm::ptr<SceNpClansPagingResult> pageResult)
|
// TODO: seems to not be needed, even by the PS3..?
|
||||||
|
error_code sceNpClansSearchByProfile(SceNpClansRequestHandle handle, vm::cptr<SceNpClansPagingRequest> paging, vm::cptr<SceNpClansSearchableProfile> search, vm::ptr<SceNpClansClanBasicInfo> results, vm::ptr<SceNpClansPagingResult> pageResult)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansSearchByProfile(handle=*0x%x, paging=*0x%x, search=*0x%x, results=*0x%x, pageResult=*0x%x)", handle, paging, search, results, pageResult);
|
sceNpClans.todo("sceNpClansSearchByProfile(handle=*0x%x, paging=*0x%x, search=*0x%x, results=*0x%x, pageResult=*0x%x)", handle, paging, search, results, pageResult);
|
||||||
|
|
||||||
@@ -270,9 +356,9 @@ error_code sceNpClansSearchByProfile(vm::ptr<SceNpClansRequestHandle> handle, vm
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansSearchByName(vm::ptr<SceNpClansRequestHandle> handle, vm::cptr<SceNpClansPagingRequest> paging, vm::cptr<SceNpClansSearchableName> search, vm::ptr<SceNpClansClanBasicInfo> results, vm::ptr<SceNpClansPagingResult> pageResult)
|
error_code sceNpClansSearchByName(SceNpClansRequestHandle handle, vm::cptr<SceNpClansPagingRequest> paging, vm::cptr<SceNpClansSearchableName> search, vm::ptr<SceNpClansClanBasicInfo> results, vm::ptr<SceNpClansPagingResult> pageResult)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansSearchByName(handle=*0x%x, paging=*0x%x, search=*0x%x, results=*0x%x, pageResult=*0x%x)", handle, paging, search, results, pageResult);
|
sceNpClans.warning("sceNpClansSearchByName(handle=*0x%x, paging=*0x%x, search=*0x%x, results=*0x%x, pageResult=*0x%x)", handle, paging, search, results, pageResult);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -292,12 +378,38 @@ error_code sceNpClansSearchByName(vm::ptr<SceNpClansRequestHandle> handle, vm::c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpClansPagingRequest host_paging = {};
|
||||||
|
if (paging)
|
||||||
|
{
|
||||||
|
std::memcpy(&host_paging, paging.get_ptr(), sizeof(SceNpClansPagingRequest));
|
||||||
|
}
|
||||||
|
|
||||||
|
SceNpClansSearchableName host_search = {};
|
||||||
|
std::memcpy(&host_search, search.get_ptr(), sizeof(SceNpClansSearchableName));
|
||||||
|
|
||||||
|
SceNpClansClanBasicInfo host_results[SCE_NP_CLANS_PAGING_REQUEST_PAGE_MAX] = {};
|
||||||
|
SceNpClansPagingResult host_pageResult = {};
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->clan_search(handle, &host_paging, &host_search, host_results, &host_pageResult);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results && host_pageResult.count > 0)
|
||||||
|
{
|
||||||
|
std::memcpy(results.get_ptr(), host_results, sizeof(SceNpClansClanBasicInfo) * host_pageResult.count);
|
||||||
|
}
|
||||||
|
std::memcpy(pageResult.get_ptr(), &host_pageResult, sizeof(SceNpClansPagingResult));
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansGetClanInfo(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::ptr<SceNpClansClanInfo> info)
|
error_code sceNpClansGetClanInfo(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::ptr<SceNpClansClanInfo> info)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansGetClanInfo(handle=*0x%x, clanId=%d, info=*0x%x)", handle, clanId, info);
|
sceNpClans.warning("sceNpClansGetClanInfo(handle=*0x%x, clanId=*0x%x, info=*0x%x)", handle, clanId, info);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -310,12 +422,24 @@ error_code sceNpClansGetClanInfo(vm::ptr<SceNpClansRequestHandle> handle, SceNpC
|
|||||||
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpClansClanInfo host_info = {};
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->get_clan_info(handle, clanId, &host_info);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::memcpy(info.get_ptr(), &host_info, sizeof(SceNpClansClanInfo));
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansUpdateClanInfo(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansUpdatableClanInfo> info)
|
error_code sceNpClansUpdateClanInfo(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansUpdatableClanInfo> info)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansUpdateClanInfo(handle=*0x%x, clanId=%d, info=*0x%x)", handle, clanId, info);
|
sceNpClans.warning("sceNpClansUpdateClanInfo(handle=*0x%x, clanId=*0x%x, info=*0x%x)", handle, clanId, info);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -328,17 +452,24 @@ error_code sceNpClansUpdateClanInfo(vm::ptr<SceNpClansRequestHandle> handle, Sce
|
|||||||
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (info->something > X)
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
//{
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
// return SCE_NP_CLANS_ERROR_EXCEEDS_MAX;
|
|
||||||
//}
|
SceNpClansUpdatableClanInfo host_info = {};
|
||||||
|
std::memcpy(&host_info, info.get_ptr(), sizeof(SceNpClansUpdatableClanInfo));
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->update_clan_info(nph, handle, clanId, &host_info);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansGetMemberList(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, SceNpClansMemberStatus status, vm::ptr<SceNpClansMemberEntry> memList, vm::ptr<SceNpClansPagingResult> pageResult)
|
error_code sceNpClansGetMemberList(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, SceNpClansMemberStatus status, vm::ptr<SceNpClansMemberEntry> memList, vm::ptr<SceNpClansPagingResult> pageResult)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansGetMemberList(handle=*0x%x, clanId=%d, paging=*0x%x, status=%d, memList=*0x%x, pageResult=*0x%x)", handle, clanId, paging, status, memList, pageResult);
|
sceNpClans.warning("sceNpClansGetMemberList(handle=*0x%x, clanId=*0x%x, paging=*0x%x, status=0x%x, memList=*0x%x, pageResult=*0x%x)", handle, clanId, paging, status, memList, pageResult);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -358,12 +489,36 @@ error_code sceNpClansGetMemberList(vm::ptr<SceNpClansRequestHandle> handle, SceN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpClansPagingRequest host_paging = {};
|
||||||
|
if (paging)
|
||||||
|
{
|
||||||
|
std::memcpy(&host_paging, paging.get_ptr(), sizeof(SceNpClansPagingRequest));
|
||||||
|
}
|
||||||
|
|
||||||
|
SceNpClansMemberEntry host_memList_addr[SCE_NP_CLANS_PAGING_REQUEST_PAGE_MAX] = {};
|
||||||
|
SceNpClansPagingResult host_pageResult = {};
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->get_member_list(nph, handle, clanId, &host_paging, status, host_memList_addr, &host_pageResult);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memList && host_pageResult.count > 0)
|
||||||
|
{
|
||||||
|
std::memcpy(memList.get_ptr(), host_memList_addr, sizeof(SceNpClansMemberEntry) * host_pageResult.count);
|
||||||
|
}
|
||||||
|
std::memcpy(pageResult.get_ptr(), &host_pageResult, sizeof(SceNpClansPagingResult));
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansGetMemberInfo(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::ptr<SceNpClansMemberEntry> memInfo)
|
error_code sceNpClansGetMemberInfo(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::ptr<SceNpClansMemberEntry> memInfo)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansGetMemberInfo(handle=*0x%x, clanId=%d, npid=*0x%x, memInfo=*0x%x)", handle, clanId, npid, memInfo);
|
sceNpClans.warning("sceNpClansGetMemberInfo(handle=*0x%x, clanId=*0x%x, npid=*0x%x, memInfo=*0x%x)", handle, clanId, npid, memInfo);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -375,12 +530,28 @@ error_code sceNpClansGetMemberInfo(vm::ptr<SceNpClansRequestHandle> handle, SceN
|
|||||||
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpId host_npid = {};
|
||||||
|
std::memcpy(&host_npid, npid.get_ptr(), sizeof(SceNpId));
|
||||||
|
|
||||||
|
SceNpClansMemberEntry host_memInfo = {};
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->get_member_info(nph, handle, clanId, host_npid, &host_memInfo);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::memcpy(memInfo.get_ptr(), &host_memInfo, sizeof(SceNpClansMemberEntry));
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansUpdateMemberInfo(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansUpdatableMemberInfo> info)
|
error_code sceNpClansUpdateMemberInfo(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansUpdatableMemberInfo> info)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansUpdateMemberInfo(handle=*0x%x, clanId=%d, memInfo=*0x%x)", handle, clanId, info);
|
sceNpClans.warning("sceNpClansUpdateMemberInfo(handle=*0x%x, clanId=*0x%x, info=*0x%x)", handle, clanId, info);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -389,21 +560,27 @@ error_code sceNpClansUpdateMemberInfo(vm::ptr<SceNpClansRequestHandle> handle, S
|
|||||||
|
|
||||||
if (!info)
|
if (!info)
|
||||||
{
|
{
|
||||||
// TODO: add more checks for info
|
|
||||||
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (info->something > X)
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
//{
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
// return SCE_NP_CLANS_ERROR_EXCEEDS_MAX;
|
|
||||||
//}
|
SceNpClansUpdatableMemberInfo host_info = {};
|
||||||
|
std::memcpy(&host_info, info.get_ptr(), sizeof(SceNpClansUpdatableMemberInfo));
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->update_member_info(nph, handle, clanId, &host_info);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansChangeMemberRole(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, u32 role)
|
error_code sceNpClansChangeMemberRole(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, u32 role)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansChangeMemberRole(handle=*0x%x, clanId=%d, npid=*0x%x, role=%d)", handle, clanId, npid, role);
|
sceNpClans.warning("sceNpClansChangeMemberRole(handle=*0x%x, clanId=*0x%x, npid=*0x%x, role=0x%x)", handle, clanId, npid, role);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -415,10 +592,23 @@ error_code sceNpClansChangeMemberRole(vm::ptr<SceNpClansRequestHandle> handle, S
|
|||||||
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpId host_npid = {};
|
||||||
|
std::memcpy(&host_npid, npid.get_ptr(), sizeof(SceNpId));
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->change_member_role(nph, handle, clanId, host_npid, static_cast<SceNpClansMemberRole>(role));
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansGetAutoAcceptStatus(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::ptr<b8> enable)
|
// TODO: no struct currently implements `autoAccept` as a field
|
||||||
|
error_code sceNpClansGetAutoAcceptStatus(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::ptr<b8> enable)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansGetAutoAcceptStatus(handle=*0x%x, clanId=%d, enable=*0x%x)", handle, clanId, enable);
|
sceNpClans.todo("sceNpClansGetAutoAcceptStatus(handle=*0x%x, clanId=%d, enable=*0x%x)", handle, clanId, enable);
|
||||||
|
|
||||||
@@ -435,7 +625,8 @@ error_code sceNpClansGetAutoAcceptStatus(vm::ptr<SceNpClansRequestHandle> handle
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansUpdateAutoAcceptStatus(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, b8 enable)
|
// TODO: no struct currently implements `autoAccept` as a field
|
||||||
|
error_code sceNpClansUpdateAutoAcceptStatus(SceNpClansRequestHandle handle, SceNpClanId clanId, b8 enable)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansUpdateAutoAcceptStatus(handle=*0x%x, clanId=%d, enable=%d)", handle, clanId, enable);
|
sceNpClans.todo("sceNpClansUpdateAutoAcceptStatus(handle=*0x%x, clanId=%d, enable=%d)", handle, clanId, enable);
|
||||||
|
|
||||||
@@ -447,33 +638,51 @@ error_code sceNpClansUpdateAutoAcceptStatus(vm::ptr<SceNpClansRequestHandle> han
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansJoinClan(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId)
|
error_code sceNpClansJoinClan(SceNpClansRequestHandle handle, SceNpClanId clanId)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansJoinClan(handle=*0x%x, clanId=%d)", handle, clanId);
|
sceNpClans.warning("sceNpClansJoinClan(handle=*0x%x, clanId=*0x%x)", handle, clanId);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->join_clan(nph, handle, clanId);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansLeaveClan(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId)
|
error_code sceNpClansLeaveClan(SceNpClansRequestHandle handle, SceNpClanId clanId)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansLeaveClan(handle=*0x%x, clanId=%d)", handle, clanId);
|
sceNpClans.warning("sceNpClansLeaveClan(handle=*0x%x, clanId=*0x%x)", handle, clanId);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->leave_clan(nph, handle, clanId);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansKickMember(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::cptr<SceNpClansMessage> message)
|
error_code sceNpClansKickMember(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::cptr<SceNpClansMessage> message)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansKickMember(handle=*0x%x, clanId=%d, npid=*0x%x, message=*0x%x)", handle, clanId, npid, message);
|
sceNpClans.warning("sceNpClansKickMember(handle=*0x%x, clanId=*0x%x, npid=*0x%x, message=*0x%x)", handle, clanId, npid, message);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -493,12 +702,30 @@ error_code sceNpClansKickMember(vm::ptr<SceNpClansRequestHandle> handle, SceNpCl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpId host_npid = {};
|
||||||
|
std::memcpy(&host_npid, npid.get_ptr(), sizeof(SceNpId));
|
||||||
|
|
||||||
|
SceNpClansMessage host_message = {};
|
||||||
|
if (message)
|
||||||
|
{
|
||||||
|
std::memcpy(&host_message, message.get_ptr(), sizeof(SceNpClansMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->kick_member(nph, handle, clanId, host_npid, &host_message);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansSendInvitation(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::cptr<SceNpClansMessage> message)
|
error_code sceNpClansSendInvitation(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::cptr<SceNpClansMessage> message)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansSendInvitation(handle=*0x%x, clanId=%d, npid=*0x%x, message=*0x%x)", handle, clanId, npid, message);
|
sceNpClans.warning("sceNpClansSendInvitation(handle=*0x%x, clanId=*0x%x, npid=*0x%x, message=*0x%x)", handle, clanId, npid, message);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -518,12 +745,30 @@ error_code sceNpClansSendInvitation(vm::ptr<SceNpClansRequestHandle> handle, Sce
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpId host_npid = {};
|
||||||
|
std::memcpy(&host_npid, npid.get_ptr(), sizeof(SceNpId));
|
||||||
|
|
||||||
|
SceNpClansMessage host_message = {};
|
||||||
|
if (message)
|
||||||
|
{
|
||||||
|
std::memcpy(&host_message, message.get_ptr(), sizeof(SceNpClansMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->send_invitation(nph, handle, clanId, host_npid, &host_message);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansCancelInvitation(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid)
|
error_code sceNpClansCancelInvitation(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> npid)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansCancelInvitation(handle=*0x%x, clanId=%d, npid=*0x%x)", handle, clanId, npid);
|
sceNpClans.warning("sceNpClansCancelInvitation(handle=*0x%x, clanId=*0x%x, npid=*0x%x)", handle, clanId, npid);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -535,12 +780,24 @@ error_code sceNpClansCancelInvitation(vm::ptr<SceNpClansRequestHandle> handle, S
|
|||||||
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpId host_npid = {};
|
||||||
|
std::memcpy(&host_npid, npid.get_ptr(), sizeof(SceNpId));
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->cancel_invitation(nph, handle, clanId, host_npid);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansSendInvitationResponse(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansMessage> message, b8 accept)
|
error_code sceNpClansSendInvitationResponse(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansMessage> message, b8 accept)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansSendInvitationResponse(handle=*0x%x, clanId=%d, message=*0x%x, accept=%d)", handle, clanId, message, accept);
|
sceNpClans.warning("sceNpClansSendInvitationResponse(handle=*0x%x, clanId=*0x%x, message=*0x%x, accept=%d)", handle, clanId, message, accept);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -555,12 +812,32 @@ error_code sceNpClansSendInvitationResponse(vm::ptr<SceNpClansRequestHandle> han
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpClansMessage host_message = {};
|
||||||
|
if (message)
|
||||||
|
{
|
||||||
|
std::memcpy(&host_message, message.get_ptr(), sizeof(SceNpClansMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message)
|
||||||
|
{
|
||||||
|
std::memcpy(&host_message, message.get_ptr(), sizeof(SceNpClansMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->send_invitation_response(nph, handle, clanId, &host_message, accept);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansSendMembershipRequest(vm::ptr<SceNpClansRequestHandle> handle, u32 clanId, vm::cptr<SceNpClansMessage> message)
|
error_code sceNpClansSendMembershipRequest(SceNpClansRequestHandle handle, u32 clanId, vm::cptr<SceNpClansMessage> message)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansSendMembershipRequest(handle=*0x%x, clanId=%d, message=*0x%x)", handle, clanId, message);
|
sceNpClans.warning("sceNpClansSendMembershipRequest(handle=*0x%x, clanId=*0x%x, message=*0x%x)", handle, clanId, message);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -575,24 +852,49 @@ error_code sceNpClansSendMembershipRequest(vm::ptr<SceNpClansRequestHandle> hand
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpClansMessage host_message = {};
|
||||||
|
if (message)
|
||||||
|
{
|
||||||
|
std::memcpy(&host_message, message.get_ptr(), sizeof(SceNpClansMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->request_membership(nph, handle, clanId, &host_message);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansCancelMembershipRequest(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId)
|
error_code sceNpClansCancelMembershipRequest(SceNpClansRequestHandle handle, SceNpClanId clanId)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansCancelMembershipRequest(handle=*0x%x, clanId=%d)", handle, clanId);
|
sceNpClans.warning("sceNpClansCancelMembershipRequest(handle=*0x%x, clanId=*0x%x)", handle, clanId);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->cancel_request_membership(nph, handle, clanId);
|
||||||
|
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansSendMembershipResponse(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::cptr<SceNpClansMessage> message, b8 allow)
|
error_code sceNpClansSendMembershipResponse(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> npid, vm::cptr<SceNpClansMessage> message, b8 allow)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansSendMembershipResponse(handle=*0x%x, clanId=%d, npid=*0x%x, message=*0x%x, allow=%d)", handle, clanId, npid, message, allow);
|
sceNpClans.warning("sceNpClansSendMembershipResponse(handle=*0x%x, clanId=*0x%x, npid=*0x%x, message=*0x%x, allow=%d)", handle, clanId, npid, message, allow);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -612,12 +914,30 @@ error_code sceNpClansSendMembershipResponse(vm::ptr<SceNpClansRequestHandle> han
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpId host_npid = {};
|
||||||
|
std::memcpy(&host_npid, npid.get_ptr(), sizeof(SceNpId));
|
||||||
|
|
||||||
|
SceNpClansMessage host_message = {};
|
||||||
|
if (message)
|
||||||
|
{
|
||||||
|
std::memcpy(&host_message, message.get_ptr(), sizeof(SceNpClansMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->send_membership_response(nph, handle, clanId, host_npid, &host_message, allow);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansGetBlacklist(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansBlacklistEntry> bl, vm::ptr<SceNpClansPagingResult> pageResult)
|
error_code sceNpClansGetBlacklist(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansBlacklistEntry> bl, vm::ptr<SceNpClansPagingResult> pageResult)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansGetBlacklist(handle=*0x%x, clanId=%d, paging=*0x%x, bl=*0x%x, pageResult=*0x%x)", handle, clanId, paging, bl, pageResult);
|
sceNpClans.warning("sceNpClansGetBlacklist(handle=*0x%x, clanId=*0x%x, paging=*0x%x, bl=*0x%x, pageResult=*0x%x)", handle, clanId, paging, bl, pageResult);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -637,53 +957,101 @@ error_code sceNpClansGetBlacklist(vm::ptr<SceNpClansRequestHandle> handle, SceNp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpClansPagingRequest host_paging = {};
|
||||||
|
if (paging)
|
||||||
|
{
|
||||||
|
std::memcpy(&host_paging, paging.get_ptr(), sizeof(SceNpClansPagingRequest));
|
||||||
|
}
|
||||||
|
|
||||||
|
SceNpClansBlacklistEntry host_blacklist[SCE_NP_CLANS_PAGING_REQUEST_PAGE_MAX] = {};
|
||||||
|
SceNpClansPagingResult host_pageResult = {};
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->get_blacklist(nph, handle, clanId, &host_paging, host_blacklist, &host_pageResult);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bl && host_pageResult.count > 0)
|
||||||
|
{
|
||||||
|
std::memcpy(bl.get_ptr(), host_blacklist, sizeof(SceNpClansBlacklistEntry) * host_pageResult.count);
|
||||||
|
}
|
||||||
|
std::memcpy(pageResult.get_ptr(), &host_pageResult, sizeof(SceNpClansPagingResult));
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansAddBlacklistEntry(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid)
|
error_code sceNpClansAddBlacklistEntry(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> member)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansAddBlacklistEntry(handle=*0x%x, clanId=%d, npid=*0x%x)", handle, clanId, npid);
|
sceNpClans.warning("sceNpClansAddBlacklistEntry(handle=*0x%x, clanId=*0x%x, member=*0x%x)", handle, clanId, member);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!npid)
|
if (!member)
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpId host_member = {};
|
||||||
|
std::memcpy(&host_member, member.get_ptr(), sizeof(SceNpId));
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->add_blacklist_entry(nph, handle, clanId, host_member);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansRemoveBlacklistEntry(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpId> npid)
|
error_code sceNpClansRemoveBlacklistEntry(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpId> member)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansRemoveBlacklistEntry(handle=*0x%x, clanId=%d, npid=*0x%x)", handle, clanId, npid);
|
sceNpClans.warning("sceNpClansRemoveBlacklistEntry(handle=*0x%x, clanId=*0x%x, member=*0x%x)", handle, clanId, member);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!npid)
|
if (!member)
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
|
||||||
|
SceNpId host_member = {};
|
||||||
|
std::memcpy(&host_member, member.get_ptr(), sizeof(SceNpId));
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->remove_blacklist_entry(nph, handle, clanId, host_member);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansRetrieveAnnouncements(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansMessageEntry> mlist, vm::ptr<SceNpClansPagingResult> pageResult)
|
error_code sceNpClansRetrieveAnnouncements(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansMessageEntry> mlist, vm::ptr<SceNpClansPagingResult> pageResult)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansRetrieveAnnouncements(handle=*0x%x, clanId=%d, paging=*0x%x, mlist=*0x%x, pageResult=*0x%x)", handle, clanId, paging, mlist, pageResult);
|
sceNpClans.warning("sceNpClansRetrieveAnnouncements(handle=*0x%x, clanId=*0x%x, paging=*0x%x, mlist=*0x%x, pageResult=*0x%x)", handle, clanId, paging, mlist, pageResult);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pageResult || (paging && !mlist)) // TODO: confirm
|
if (!pageResult || (paging && !mlist) || clanId == UINT32_MAX) // TODO: confirm
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
@@ -696,12 +1064,36 @@ error_code sceNpClansRetrieveAnnouncements(vm::ptr<SceNpClansRequestHandle> hand
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
|
||||||
|
SceNpClansPagingRequest host_paging = {};
|
||||||
|
if (paging)
|
||||||
|
{
|
||||||
|
std::memcpy(&host_paging, paging.get_ptr(), sizeof(SceNpClansPagingRequest));
|
||||||
|
}
|
||||||
|
|
||||||
|
SceNpClansMessageEntry host_announcements[SCE_NP_CLANS_PAGING_REQUEST_PAGE_MAX] = {};
|
||||||
|
SceNpClansPagingResult host_pageResult = {};
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->retrieve_announcements(nph, handle, clanId, &host_paging, host_announcements, &host_pageResult);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mlist && host_pageResult.count > 0)
|
||||||
|
{
|
||||||
|
std::memcpy(mlist.get_ptr(), host_announcements, sizeof(SceNpClansMessageEntry) * host_pageResult.count);
|
||||||
|
}
|
||||||
|
std::memcpy(pageResult.get_ptr(), &host_pageResult, sizeof(SceNpClansPagingResult));
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansPostAnnouncement(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansMessage> message, vm::cptr<SceNpClansMessageData> data, u32 duration, vm::ptr<SceNpClansMessageId> mId)
|
error_code sceNpClansPostAnnouncement(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansMessage> message, vm::cptr<SceNpClansMessageData> data, u32 duration, vm::ptr<SceNpClansMessageId> mId)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansPostAnnouncement(handle=*0x%x, clanId=%d, message=*0x%x, data=*0x%x, duration=%d, mId=*0x%x)", handle, clanId, message, data, duration, mId);
|
sceNpClans.warning("sceNpClansPostAnnouncement(handle=*0x%x, clanId=*0x%x, message=*0x%x, data=*0x%x, duration=*0x%x, mId=*0x%x)", handle, clanId, message, data, duration, mId);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
@@ -713,32 +1105,57 @@ error_code sceNpClansPostAnnouncement(vm::ptr<SceNpClansRequestHandle> handle, S
|
|||||||
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
return SCE_NP_CLANS_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data) // TODO verify
|
|
||||||
{
|
|
||||||
return SCE_NP_CLANS_ERROR_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(message->body) > SCE_NP_CLANS_ANNOUNCEMENT_MESSAGE_BODY_MAX_LENGTH || strlen(message->subject) > SCE_NP_CLANS_MESSAGE_SUBJECT_MAX_LENGTH) // TODO: correct max?
|
if (strlen(message->body) > SCE_NP_CLANS_ANNOUNCEMENT_MESSAGE_BODY_MAX_LENGTH || strlen(message->subject) > SCE_NP_CLANS_MESSAGE_SUBJECT_MAX_LENGTH) // TODO: correct max?
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_EXCEEDS_MAX;
|
return SCE_NP_CLANS_ERROR_EXCEEDS_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
|
||||||
|
SceNpClansMessage host_announcement = {};
|
||||||
|
std::memcpy(&host_announcement, message.get_ptr(), sizeof(SceNpClansMessage));
|
||||||
|
|
||||||
|
SceNpClansMessageData host_data = {};
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
std::memcpy(&host_data, data.get_ptr(), sizeof(SceNpClansMessageData));
|
||||||
|
}
|
||||||
|
|
||||||
|
SceNpClansMessageId host_announcementId = 0;
|
||||||
|
SceNpClansError ret = clans_manager.client->post_announcement(nph, handle, clanId, &host_announcement, &host_data, duration, &host_announcementId);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
*mId = host_announcementId;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansRemoveAnnouncement(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, SceNpClansMessageId mId)
|
error_code sceNpClansRemoveAnnouncement(SceNpClansRequestHandle handle, SceNpClanId clanId, SceNpClansMessageId mId)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansPostAnnouncement(handle=*0x%x, clanId=%d, mId=%d)", handle, clanId, mId);
|
sceNpClans.warning("sceNpClansRemoveAnnouncement(handle=*0x%x, clanId=*0x%x, mId=*0x%x)", handle, clanId, mId);
|
||||||
|
|
||||||
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
if (!g_fxo->get<sce_np_clans_manager>().is_initialized)
|
||||||
{
|
{
|
||||||
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
return SCE_NP_CLANS_ERROR_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& clans_manager = g_fxo->get<sce_np_clans_manager>();
|
||||||
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
|
|
||||||
|
SceNpClansError ret = clans_manager.client->delete_announcement(nph, handle, clanId, mId);
|
||||||
|
if (ret != SCE_NP_CLANS_SUCCESS)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansPostChallenge(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, SceNpClanId targetClan, vm::cptr<SceNpClansMessage> message, vm::cptr<SceNpClansMessageData> data, u32 duration, vm::ptr<SceNpClansMessageId> mId)
|
error_code sceNpClansPostChallenge(SceNpClansRequestHandle handle, SceNpClanId clanId, SceNpClanId targetClan, vm::cptr<SceNpClansMessage> message, vm::cptr<SceNpClansMessageData> data, u32 duration, vm::ptr<SceNpClansMessageId> mId)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansPostChallenge(handle=*0x%x, clanId=%d, targetClan=%d, message=*0x%x, data=*0x%x, duration=%d, mId=*0x%x)", handle, clanId, targetClan, message, data, duration, mId);
|
sceNpClans.todo("sceNpClansPostChallenge(handle=*0x%x, clanId=%d, targetClan=%d, message=*0x%x, data=*0x%x, duration=%d, mId=*0x%x)", handle, clanId, targetClan, message, data, duration, mId);
|
||||||
|
|
||||||
@@ -765,7 +1182,7 @@ error_code sceNpClansPostChallenge(vm::ptr<SceNpClansRequestHandle> handle, SceN
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansRetrievePostedChallenges(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, SceNpClanId targetClan, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansMessageEntry> mList, vm::ptr<SceNpClansPagingResult> pageResult)
|
error_code sceNpClansRetrievePostedChallenges(SceNpClansRequestHandle handle, SceNpClanId clanId, SceNpClanId targetClan, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansMessageEntry> mList, vm::ptr<SceNpClansPagingResult> pageResult)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansRetrievePostedChallenges(handle=*0x%x, clanId=%d, targetClan=%d, paging=*0x%x, mList=*0x%x, pageResult=*0x%x)", handle, clanId, targetClan, paging, mList, pageResult);
|
sceNpClans.todo("sceNpClansRetrievePostedChallenges(handle=*0x%x, clanId=%d, targetClan=%d, paging=*0x%x, mList=*0x%x, pageResult=*0x%x)", handle, clanId, targetClan, paging, mList, pageResult);
|
||||||
|
|
||||||
@@ -790,7 +1207,7 @@ error_code sceNpClansRetrievePostedChallenges(vm::ptr<SceNpClansRequestHandle> h
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansRemovePostedChallenge(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, SceNpClanId targetClan, SceNpClansMessageId mId)
|
error_code sceNpClansRemovePostedChallenge(SceNpClansRequestHandle handle, SceNpClanId clanId, SceNpClanId targetClan, SceNpClansMessageId mId)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansRemovePostedChallenge(handle=*0x%x, clanId=%d, targetClan=%d, mId=%d)", handle, clanId, targetClan, mId);
|
sceNpClans.todo("sceNpClansRemovePostedChallenge(handle=*0x%x, clanId=%d, targetClan=%d, mId=%d)", handle, clanId, targetClan, mId);
|
||||||
|
|
||||||
@@ -802,7 +1219,7 @@ error_code sceNpClansRemovePostedChallenge(vm::ptr<SceNpClansRequestHandle> hand
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code sceNpClansRetrieveChallenges(vm::ptr<SceNpClansRequestHandle> handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansMessageEntry> mList, vm::ptr<SceNpClansPagingResult> pageResult)
|
error_code sceNpClansRetrieveChallenges(SceNpClansRequestHandle handle, SceNpClanId clanId, vm::cptr<SceNpClansPagingRequest> paging, vm::ptr<SceNpClansMessageEntry> mList, vm::ptr<SceNpClansPagingResult> pageResult)
|
||||||
{
|
{
|
||||||
sceNpClans.todo("sceNpClansRetrieveChallenges(handle=*0x%x, clanId=%d, paging=*0x%x, mList=*0x%x, pageResult=*0x%x)", handle, clanId, paging, mList, pageResult);
|
sceNpClans.todo("sceNpClansRetrieveChallenges(handle=*0x%x, clanId=%d, paging=*0x%x, mList=*0x%x, pageResult=*0x%x)", handle, clanId, paging, mList, pageResult);
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
// Return codes
|
// Return codes
|
||||||
enum SceNpClansError : u32
|
enum SceNpClansError : u32
|
||||||
{
|
{
|
||||||
|
SCE_NP_CLANS_SUCCESS = CELL_OK,
|
||||||
|
|
||||||
SCE_NP_CLANS_ERROR_ALREADY_INITIALIZED = 0x80022701,
|
SCE_NP_CLANS_ERROR_ALREADY_INITIALIZED = 0x80022701,
|
||||||
SCE_NP_CLANS_ERROR_NOT_INITIALIZED = 0x80022702,
|
SCE_NP_CLANS_ERROR_NOT_INITIALIZED = 0x80022702,
|
||||||
SCE_NP_CLANS_ERROR_NOT_SUPPORTED = 0x80022703,
|
SCE_NP_CLANS_ERROR_NOT_SUPPORTED = 0x80022703,
|
||||||
@@ -138,7 +140,7 @@ enum
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Request handle for clan API
|
// Request handle for clan API
|
||||||
using SceNpClansRequestHandle = vm::ptr<struct SceNpClansRequest>;
|
using SceNpClansRequestHandle = u32;
|
||||||
|
|
||||||
// Paging request structure
|
// Paging request structure
|
||||||
struct SceNpClansPagingRequest
|
struct SceNpClansPagingRequest
|
||||||
@@ -159,8 +161,8 @@ struct SceNpClansClanBasicInfo
|
|||||||
{
|
{
|
||||||
be_t<u32> clanId;
|
be_t<u32> clanId;
|
||||||
be_t<u32> numMembers;
|
be_t<u32> numMembers;
|
||||||
s8 name[SCE_NP_CLANS_CLAN_NAME_MAX_LENGTH + 1];
|
char name[SCE_NP_CLANS_CLAN_NAME_MAX_LENGTH + 1];
|
||||||
s8 tag[SCE_NP_CLANS_CLAN_TAG_MAX_LENGTH + 1];
|
char tag[SCE_NP_CLANS_CLAN_TAG_MAX_LENGTH + 1];
|
||||||
u8 reserved[2];
|
u8 reserved[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -197,7 +199,7 @@ struct SceNpClansSearchableProfile
|
|||||||
be_t<s32> intAttr2SearchOp;
|
be_t<s32> intAttr2SearchOp;
|
||||||
be_t<s32> intAttr3SearchOp;
|
be_t<s32> intAttr3SearchOp;
|
||||||
be_t<s32> binAttr1SearchOp;
|
be_t<s32> binAttr1SearchOp;
|
||||||
s8 tag[SCE_NP_CLANS_CLAN_TAG_MAX_LENGTH + 1];
|
char tag[SCE_NP_CLANS_CLAN_TAG_MAX_LENGTH + 1];
|
||||||
u8 reserved[3];
|
u8 reserved[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -205,7 +207,7 @@ struct SceNpClansSearchableProfile
|
|||||||
struct SceNpClansSearchableName
|
struct SceNpClansSearchableName
|
||||||
{
|
{
|
||||||
be_t<s32> nameSearchOp;
|
be_t<s32> nameSearchOp;
|
||||||
s8 name[SCE_NP_CLANS_CLAN_NAME_MAX_LENGTH + 1];
|
char name[SCE_NP_CLANS_CLAN_NAME_MAX_LENGTH + 1];
|
||||||
u8 reserved[3];
|
u8 reserved[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -213,7 +215,7 @@ struct SceNpClansSearchableName
|
|||||||
struct SceNpClansUpdatableClanInfo
|
struct SceNpClansUpdatableClanInfo
|
||||||
{
|
{
|
||||||
be_t<u32> fields;
|
be_t<u32> fields;
|
||||||
s8 description[SCE_NP_CLANS_CLAN_DESCRIPTION_MAX_LENGTH + 1];
|
char description[SCE_NP_CLANS_CLAN_DESCRIPTION_MAX_LENGTH + 1];
|
||||||
SceNpClansSearchableAttr attr;
|
SceNpClansSearchableAttr attr;
|
||||||
u8 binData1;
|
u8 binData1;
|
||||||
be_t<u32> binData1Size;
|
be_t<u32> binData1Size;
|
||||||
@@ -233,8 +235,8 @@ struct SceNpClansUpdatableMemberInfo
|
|||||||
be_t<u32> fields;
|
be_t<u32> fields;
|
||||||
u8 binData1;
|
u8 binData1;
|
||||||
be_t<u32> binData1Size;
|
be_t<u32> binData1Size;
|
||||||
u8 binAttr1[SCE_NP_CLANS_CLAN_BINARY_ATTRIBUTE1_MAX_SIZE + 1];
|
u8 binAttr1[SCE_NP_CLANS_MEMBER_BINARY_ATTRIBUTE1_MAX_SIZE];
|
||||||
s8 description[SCE_NP_CLANS_MEMBER_DESCRIPTION_MAX_LENGTH + 1];
|
char description[SCE_NP_CLANS_MEMBER_DESCRIPTION_MAX_LENGTH + 1];
|
||||||
b8 allowMsg;
|
b8 allowMsg;
|
||||||
u8 reserved[3];
|
u8 reserved[3];
|
||||||
};
|
};
|
||||||
@@ -271,7 +273,7 @@ struct SceNpClansMessageEntry
|
|||||||
SceNpClansMessage message;
|
SceNpClansMessage message;
|
||||||
SceNpClansMessageData data;
|
SceNpClansMessageData data;
|
||||||
SceNpId npid;
|
SceNpId npid;
|
||||||
u8 reserved[4];
|
SceNpClanId postedBy;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Blacklist entry structure
|
// Blacklist entry structure
|
||||||
@@ -280,10 +282,3 @@ struct SceNpClansBlacklistEntry
|
|||||||
SceNpId entry;
|
SceNpId entry;
|
||||||
SceNpId registeredBy;
|
SceNpId registeredBy;
|
||||||
};
|
};
|
||||||
|
|
||||||
// fxm objects
|
|
||||||
|
|
||||||
struct sce_np_clans_manager
|
|
||||||
{
|
|
||||||
atomic_t<bool> is_initialized = false;
|
|
||||||
};
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,129 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#include <pugixml.hpp>
|
||||||
|
|
||||||
|
#include <Emu/Cell/Modules/sceNpClans.h>
|
||||||
|
#include <Emu/NP/np_handler.h>
|
||||||
|
#include <Emu/IdManager.h>
|
||||||
|
|
||||||
|
inline const char* CLANS_ENTITLEMENT_ID = "NPWR00432_00";
|
||||||
|
inline const char* CLANS_SERVICE_ID = "IV0001-NPXS01001_00";
|
||||||
|
|
||||||
|
namespace clan
|
||||||
|
{
|
||||||
|
enum class ClanManagerOperationType
|
||||||
|
{
|
||||||
|
VIEW,
|
||||||
|
UPDATE
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ClanRequestType
|
||||||
|
{
|
||||||
|
FUNC,
|
||||||
|
SEC
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ClanSearchFilterOperator : u8
|
||||||
|
{
|
||||||
|
Equal,
|
||||||
|
NotEqual,
|
||||||
|
GreaterThan,
|
||||||
|
GreaterThanOrEqual,
|
||||||
|
LessThan,
|
||||||
|
LessThanOrEqual,
|
||||||
|
Like,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ClanRequestAction
|
||||||
|
{
|
||||||
|
GetClanList,
|
||||||
|
GetClanInfo,
|
||||||
|
GetMemberInfo,
|
||||||
|
GetMemberList,
|
||||||
|
GetBlacklist,
|
||||||
|
RecordBlacklistEntry,
|
||||||
|
DeleteBlacklistEntry,
|
||||||
|
ClanSearch,
|
||||||
|
CreateClan,
|
||||||
|
DisbandClan,
|
||||||
|
RequestMembership,
|
||||||
|
CancelRequestMembership,
|
||||||
|
AcceptMembershipRequest,
|
||||||
|
DeclineMembershipRequest,
|
||||||
|
SendInvitation,
|
||||||
|
CancelInvitation,
|
||||||
|
AcceptInvitation,
|
||||||
|
DeclineInvitation,
|
||||||
|
UpdateMemberInfo,
|
||||||
|
UpdateClanInfo,
|
||||||
|
JoinClan,
|
||||||
|
LeaveClan,
|
||||||
|
KickMember,
|
||||||
|
ChangeMemberRole,
|
||||||
|
RetrieveAnnouncements,
|
||||||
|
PostAnnouncement,
|
||||||
|
DeleteAnnouncement
|
||||||
|
};
|
||||||
|
|
||||||
|
class clans_client
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
static size_t curl_write_callback(void* data, size_t size, size_t nmemb, void* clientp);
|
||||||
|
SceNpClansError send_request(u32 reqId, ClanRequestAction action, ClanManagerOperationType type, pugi::xml_document* xml_body, pugi::xml_document* out_response);
|
||||||
|
|
||||||
|
/// @brief Forge and get a V2.1 Ticket for clan operations
|
||||||
|
std::string get_clan_ticket(np::np_handler& nph);
|
||||||
|
|
||||||
|
public:
|
||||||
|
clans_client();
|
||||||
|
~clans_client();
|
||||||
|
|
||||||
|
SceNpClansError create_request(s32* req_id);
|
||||||
|
SceNpClansError destroy_request(u32 req_id);
|
||||||
|
|
||||||
|
SceNpClansError clan_search(u32 req_id, SceNpClansPagingRequest* paging, SceNpClansSearchableName* search, SceNpClansClanBasicInfo* clan_list, SceNpClansPagingResult* page_result);
|
||||||
|
|
||||||
|
SceNpClansError create_clan(np::np_handler& nph, u32 req_id, std::string_view name, std::string_view tag, vm::ptr<SceNpClanId> clan_id);
|
||||||
|
SceNpClansError disband_dlan(np::np_handler& nph, u32 req_id, SceNpClanId clan_id);
|
||||||
|
|
||||||
|
SceNpClansError get_clan_list(np::np_handler& nph, u32 req_id, SceNpClansPagingRequest* paging, SceNpClansEntry* clan_list, SceNpClansPagingResult* page_result);
|
||||||
|
SceNpClansError get_clan_info(u32 req_id, SceNpClanId clan_id, SceNpClansClanInfo* clan_info);
|
||||||
|
|
||||||
|
SceNpClansError get_member_info(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpId np_id, SceNpClansMemberEntry* mem_info);
|
||||||
|
SceNpClansError get_member_list(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpClansPagingRequest* paging, SceNpClansMemberStatus status, SceNpClansMemberEntry* mem_list, SceNpClansPagingResult* page_result);
|
||||||
|
|
||||||
|
SceNpClansError get_blacklist(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpClansPagingRequest* paging, SceNpClansBlacklistEntry* bl, SceNpClansPagingResult* page_result);
|
||||||
|
SceNpClansError add_blacklist_entry(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpId np_id);
|
||||||
|
SceNpClansError remove_blacklist_entry(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpId np_id);
|
||||||
|
|
||||||
|
SceNpClansError request_membership(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpClansMessage* message);
|
||||||
|
SceNpClansError cancel_request_membership(np::np_handler& nph, u32 req_id, SceNpClanId clan_id);
|
||||||
|
SceNpClansError send_membership_response(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpId np_id, SceNpClansMessage* message, b8 allow);
|
||||||
|
|
||||||
|
SceNpClansError send_invitation(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpId np_id, SceNpClansMessage* message);
|
||||||
|
SceNpClansError cancel_invitation(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpId np_id);
|
||||||
|
SceNpClansError send_invitation_response(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpClansMessage* message, b8 accept);
|
||||||
|
|
||||||
|
SceNpClansError join_clan(np::np_handler& nph, u32 req_id, SceNpClanId clan_id);
|
||||||
|
SceNpClansError leave_clan(np::np_handler& nph, u32 req_id, SceNpClanId clan_id);
|
||||||
|
|
||||||
|
SceNpClansError update_member_info(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpClansUpdatableMemberInfo* info);
|
||||||
|
SceNpClansError update_clan_info(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpClansUpdatableClanInfo* info);
|
||||||
|
|
||||||
|
SceNpClansError kick_member(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpId np_id, SceNpClansMessage* message);
|
||||||
|
SceNpClansError change_member_role(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpId np_id, SceNpClansMemberRole role);
|
||||||
|
|
||||||
|
SceNpClansError retrieve_announcements(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpClansPagingRequest* paging, SceNpClansMessageEntry* announcements, SceNpClansPagingResult* page_result);
|
||||||
|
SceNpClansError post_announcement(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpClansMessage* announcement, SceNpClansMessageData* data, u32 duration, SceNpClansMessageId* announcement_id);
|
||||||
|
SceNpClansError delete_announcement(np::np_handler& nph, u32 req_id, SceNpClanId clan_id, SceNpClansMessageId announcement_id);
|
||||||
|
};
|
||||||
|
} // namespace clan
|
||||||
|
|
||||||
|
struct sce_np_clans_manager
|
||||||
|
{
|
||||||
|
atomic_t<bool> is_initialized = false;
|
||||||
|
std::shared_ptr<clan::clans_client> client;
|
||||||
|
};
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
#include "Utilities/StrUtil.h"
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "clans_config.h"
|
||||||
|
#include "Utilities/File.h"
|
||||||
|
|
||||||
|
cfg_clans g_cfg_clans;
|
||||||
|
|
||||||
|
LOG_CHANNEL(clans_config_log, "clans_config");
|
||||||
|
|
||||||
|
void cfg_clans::load()
|
||||||
|
{
|
||||||
|
const std::string path = cfg_clans::get_path();
|
||||||
|
|
||||||
|
fs::file cfg_file(path, fs::read);
|
||||||
|
if (cfg_file)
|
||||||
|
{
|
||||||
|
clans_config_log.notice("Loading Clans config. Path: %s", path);
|
||||||
|
from_string(cfg_file.to_string());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clans_config_log.notice("Clans config missing. Using default settings. Path: %s", path);
|
||||||
|
from_default();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cfg_clans::save() const
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
const std::string path_to_cfg = fs::get_config_dir(true);
|
||||||
|
if (!fs::create_path(path_to_cfg))
|
||||||
|
{
|
||||||
|
clans_config_log.error("Could not create path: %s", path_to_cfg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const std::string path = cfg_clans::get_path();
|
||||||
|
|
||||||
|
if (!cfg::node::save(path))
|
||||||
|
{
|
||||||
|
clans_config_log.error("Could not save config: %s (error=%s)", path, fs::g_tls_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string cfg_clans::get_path()
|
||||||
|
{
|
||||||
|
return fs::get_config_dir(true) + "clans.yml";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string cfg_clans::get_host() const
|
||||||
|
{
|
||||||
|
return host.to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cfg_clans::get_use_https() const
|
||||||
|
{
|
||||||
|
return use_https.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, std::string>> cfg_clans::get_hosts()
|
||||||
|
{
|
||||||
|
std::vector<std::pair<std::string, std::string>> vec_hosts;
|
||||||
|
const std::string host_str = hosts.to_string();
|
||||||
|
const auto hosts_list = fmt::split_sv(host_str, {"|||"});
|
||||||
|
|
||||||
|
for (const auto& cur_host : hosts_list)
|
||||||
|
{
|
||||||
|
const auto desc_and_host = fmt::split(cur_host, {"|"});
|
||||||
|
if (desc_and_host.size() != 2)
|
||||||
|
{
|
||||||
|
clans_config_log.error("Invalid host in the list of hosts: %s", cur_host);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
vec_hosts.push_back(std::make_pair(std::move(desc_and_host[0]), std::move(desc_and_host[1])));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vec_hosts.empty())
|
||||||
|
{
|
||||||
|
hosts.from_default();
|
||||||
|
save();
|
||||||
|
return get_hosts();
|
||||||
|
}
|
||||||
|
|
||||||
|
return vec_hosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cfg_clans::set_host(std::string_view host)
|
||||||
|
{
|
||||||
|
this->host.from_string(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cfg_clans::set_use_https(bool use_https)
|
||||||
|
{
|
||||||
|
this->use_https.set(use_https);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cfg_clans::set_hosts(const std::vector<std::pair<std::string, std::string>>& vec_hosts)
|
||||||
|
{
|
||||||
|
std::string final_string;
|
||||||
|
for (const auto& [cur_desc, cur_host] : vec_hosts)
|
||||||
|
{
|
||||||
|
fmt::append(final_string, "%s|%s|||", cur_desc, cur_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (final_string.empty())
|
||||||
|
{
|
||||||
|
hosts.from_default();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final_string.resize(final_string.size() - 3);
|
||||||
|
hosts.from_string(final_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cfg_clans::add_host(std::string_view new_description, std::string_view new_host)
|
||||||
|
{
|
||||||
|
auto cur_hosts = get_hosts();
|
||||||
|
|
||||||
|
for (const auto& [cur_desc, cur_host] : cur_hosts)
|
||||||
|
{
|
||||||
|
if (cur_desc == new_description && cur_host == new_host)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_hosts.push_back(std::make_pair(std::string(new_description), std::string(new_host)));
|
||||||
|
set_hosts(cur_hosts);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cfg_clans::del_host(std::string_view del_description, std::string_view del_host)
|
||||||
|
{
|
||||||
|
// Do not delete default servers
|
||||||
|
const auto def_desc_and_host = fmt::split_sv(hosts.def, {"|"});
|
||||||
|
ensure(def_desc_and_host.size() == 2);
|
||||||
|
if (del_description == def_desc_and_host[0] && del_host == def_desc_and_host[1])
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cur_hosts = get_hosts();
|
||||||
|
|
||||||
|
for (auto it = cur_hosts.begin(); it != cur_hosts.end(); it++)
|
||||||
|
{
|
||||||
|
if (it->first == del_description && it->second == del_host)
|
||||||
|
{
|
||||||
|
cur_hosts.erase(it);
|
||||||
|
set_hosts(cur_hosts);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Utilities/Config.h"
|
||||||
|
|
||||||
|
struct cfg_clans : cfg::node
|
||||||
|
{
|
||||||
|
cfg::uint32 version{this, "Version", 1};
|
||||||
|
cfg::string host{this, "Host", "clans.rpcs3.net"};
|
||||||
|
cfg::string hosts{this, "Hosts", "Official Clans Server|clans.rpcs3.net"};
|
||||||
|
cfg::_bool use_https{this, "Use HTTPS", true};
|
||||||
|
|
||||||
|
void load();
|
||||||
|
void save() const;
|
||||||
|
|
||||||
|
std::string get_host() const;
|
||||||
|
bool get_use_https() const;
|
||||||
|
std::vector<std::pair<std::string, std::string>> get_hosts();
|
||||||
|
|
||||||
|
void set_host(std::string_view host);
|
||||||
|
void set_use_https(bool use_https);
|
||||||
|
bool add_host(std::string_view description, std::string_view host);
|
||||||
|
bool del_host(std::string_view description, std::string_view host);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::string get_path();
|
||||||
|
void set_hosts(const std::vector<std::pair<std::string, std::string>>& vec_hosts);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern cfg_clans g_cfg_clans;
|
||||||
@@ -239,6 +239,25 @@ namespace np
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ticket::get_service_id() const
|
||||||
|
{
|
||||||
|
if (!parse_success)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& node = nodes[0].data.data_nodes[8];
|
||||||
|
if (node.len != SCE_NP_SERVICE_ID_SIZE)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim null characters
|
||||||
|
const auto& vec = node.data.data_vec;
|
||||||
|
auto it = std::find(vec.begin(), vec.end(), 0);
|
||||||
|
return std::string(vec.begin(), it);
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<ticket_data> ticket::parse_node(std::size_t index) const
|
std::optional<ticket_data> ticket::parse_node(std::size_t index) const
|
||||||
{
|
{
|
||||||
if ((index + MIN_TICKET_DATA_SIZE) > size())
|
if ((index + MIN_TICKET_DATA_SIZE) > size())
|
||||||
@@ -1352,6 +1371,24 @@ namespace np
|
|||||||
return history;
|
return history;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 np_handler::get_clan_ticket_ready()
|
||||||
|
{
|
||||||
|
return clan_ticket_ready.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
ticket np_handler::get_clan_ticket()
|
||||||
|
{
|
||||||
|
clan_ticket_ready.wait(0, atomic_wait_timeout{60'000'000'000}); // 60 seconds
|
||||||
|
|
||||||
|
if (!clan_ticket_ready.load())
|
||||||
|
{
|
||||||
|
rpcn_log.error("Failed to get clan ticket within timeout.");
|
||||||
|
return ticket{};
|
||||||
|
}
|
||||||
|
|
||||||
|
return clan_ticket;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr usz MAX_HISTORY_ENTRIES = 200;
|
constexpr usz MAX_HISTORY_ENTRIES = 200;
|
||||||
|
|
||||||
void np_handler::add_player_to_history(const SceNpId* npid, const char* description)
|
void np_handler::add_player_to_history(const SceNpId* npid, const char* description)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <queue>
|
#include <queue>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
#include "Emu/Memory/vm_ptr.h"
|
#include "Emu/Memory/vm_ptr.h"
|
||||||
#include "Emu/Cell/Modules/sceNp.h"
|
#include "Emu/Cell/Modules/sceNp.h"
|
||||||
@@ -69,6 +70,7 @@ namespace np
|
|||||||
bool empty() const;
|
bool empty() const;
|
||||||
|
|
||||||
bool get_value(s32 param_id, vm::ptr<SceNpTicketParam> param) const;
|
bool get_value(s32 param_id, vm::ptr<SceNpTicketParam> param) const;
|
||||||
|
std::string get_service_id() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::optional<ticket_data> parse_node(std::size_t index) const;
|
std::optional<ticket_data> parse_node(std::size_t index) const;
|
||||||
@@ -253,6 +255,8 @@ namespace np
|
|||||||
// Misc stuff
|
// 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);
|
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 ticket& get_ticket() const;
|
const ticket& get_ticket() const;
|
||||||
|
u32 get_clan_ticket_ready();
|
||||||
|
ticket get_clan_ticket();
|
||||||
void add_player_to_history(const SceNpId* npid, const char* description);
|
void add_player_to_history(const SceNpId* npid, const char* description);
|
||||||
u32 add_players_to_history(const SceNpId* npids, const char* description, u32 count);
|
u32 add_players_to_history(const SceNpId* npids, const char* description, u32 count);
|
||||||
u32 get_players_history_count(u32 options);
|
u32 get_players_history_count(u32 options);
|
||||||
@@ -406,6 +410,10 @@ namespace np
|
|||||||
|
|
||||||
ticket current_ticket;
|
ticket current_ticket;
|
||||||
|
|
||||||
|
// Clan ticket
|
||||||
|
atomic_t<u32> clan_ticket_ready = 0;
|
||||||
|
ticket clan_ticket;
|
||||||
|
|
||||||
// IP & DNS info
|
// IP & DNS info
|
||||||
std::string hostname = "localhost";
|
std::string hostname = "localhost";
|
||||||
std::array<u8, 6> ether_address{};
|
std::array<u8, 6> ether_address{};
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
#include "Emu/Cell/Modules/sceNp.h"
|
#include "Emu/Cell/Modules/sceNp.h"
|
||||||
#include "Emu/Cell/Modules/sceNp2.h"
|
#include "Emu/Cell/Modules/sceNp2.h"
|
||||||
|
#include "Emu/NP/clans_client.h"
|
||||||
#include "Emu/NP/rpcn_types.h"
|
#include "Emu/NP/rpcn_types.h"
|
||||||
#include "Utilities/StrFmt.h"
|
#include "Utilities/StrFmt.h"
|
||||||
#include "stdafx.h"
|
|
||||||
#include "Emu/Cell/PPUCallback.h"
|
#include "Emu/Cell/PPUCallback.h"
|
||||||
#include "Emu/Cell/lv2/sys_sync.h"
|
#include "Emu/Cell/lv2/sys_sync.h"
|
||||||
#include "Emu/system_config.h"
|
#include "Emu/system_config.h"
|
||||||
@@ -863,7 +864,20 @@ namespace np
|
|||||||
auto ticket_raw = reply.get_rawdata();
|
auto ticket_raw = reply.get_rawdata();
|
||||||
ensure(!reply.is_error(), "Malformed reply to RequestTicket command");
|
ensure(!reply.is_error(), "Malformed reply to RequestTicket command");
|
||||||
|
|
||||||
current_ticket = ticket(std::move(ticket_raw));
|
auto incoming_ticket = ticket(std::move(ticket_raw));
|
||||||
|
|
||||||
|
// Clans: check if ticket belongs to the clan service.
|
||||||
|
// If so, hijack the ticket and cache it for future use.
|
||||||
|
if (incoming_ticket.get_service_id() == CLANS_SERVICE_ID)
|
||||||
|
{
|
||||||
|
clan_ticket = incoming_ticket;
|
||||||
|
clan_ticket_ready.store(1);
|
||||||
|
clan_ticket_ready.notify_all();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_ticket = incoming_ticket;
|
||||||
auto ticket_size = static_cast<s32>(current_ticket.size());
|
auto ticket_size = static_cast<s32>(current_ticket.size());
|
||||||
|
|
||||||
if (manager_cb)
|
if (manager_cb)
|
||||||
|
|||||||
@@ -322,6 +322,7 @@ struct cfg_root : cfg::node
|
|||||||
|
|
||||||
cfg::_enum<np_psn_status> psn_status{this, "PSN status", np_psn_status::disabled};
|
cfg::_enum<np_psn_status> psn_status{this, "PSN status", np_psn_status::disabled};
|
||||||
cfg::string country{this, "PSN Country", "us"};
|
cfg::string country{this, "PSN Country", "us"};
|
||||||
|
cfg::_bool clans_enabled{this, "Clans Enabled", false};
|
||||||
} net{this};
|
} net{this};
|
||||||
|
|
||||||
struct node_savestate : cfg::node
|
struct node_savestate : cfg::node
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
<AdditionalIncludeDirectories>..\3rdparty\miniupnp\miniupnp\miniupnpc\include;..\3rdparty\wolfssl\wolfssl;..\3rdparty\flatbuffers\include;..\3rdparty\libusb\libusb\libusb;..\3rdparty\yaml-cpp\yaml-cpp\include;..\3rdparty\SoundTouch\soundtouch\include;..\3rdparty\rtmidi\rtmidi;..\3rdparty\zlib\zlib;$(SolutionDir)build\lib\$(Configuration)-$(Platform)\llvm_build\include;$(SolutionDir)build\lib_ext\$(Configuration)-$(Platform)\llvm_build\include;$(SolutionDir)build\lib_ext\$(Configuration)-$(Platform)\llvm\include;$(SolutionDir)build\lib_ext\$(Configuration)-$(Platform)\llvm_build\include;$(VULKAN_SDK)\Include;..\3rdparty\zstd\zstd\lib;$(SolutionDir)3rdparty\fusion\fusion\Fusion;$(SolutionDir)3rdparty\wolfssl\extra\win32;$(SolutionDir)3rdparty\libsdl-org\SDL\include;$(SolutionDir)3rdparty\glslang\glslang</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\3rdparty\miniupnp\miniupnp\miniupnpc\include;..\3rdparty\wolfssl\wolfssl;..\3rdparty\flatbuffers\include;..\3rdparty\libusb\libusb\libusb;..\3rdparty\yaml-cpp\yaml-cpp\include;..\3rdparty\SoundTouch\soundtouch\include;..\3rdparty\rtmidi\rtmidi;..\3rdparty\zlib\zlib;$(SolutionDir)build\lib\$(Configuration)-$(Platform)\llvm_build\include;$(SolutionDir)build\lib_ext\$(Configuration)-$(Platform)\llvm_build\include;$(SolutionDir)build\lib_ext\$(Configuration)-$(Platform)\llvm\include;$(SolutionDir)build\lib_ext\$(Configuration)-$(Platform)\llvm_build\include;$(VULKAN_SDK)\Include;..\3rdparty\zstd\zstd\lib;$(SolutionDir)3rdparty\fusion\fusion\Fusion;$(SolutionDir)3rdparty\wolfssl\extra\win32;$(SolutionDir)3rdparty\libsdl-org\SDL\include;$(SolutionDir)3rdparty\glslang\glslang;$(SolutionDir)3rdparty\curl\curl\include</AdditionalIncludeDirectories>
|
||||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
|
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AL_LIBTYPE_STATIC;MINIUPNP_STATICLIB;HAVE_VULKAN;HAVE_SDL3;ZLIB_CONST;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AL_LIBTYPE_STATIC;MINIUPNP_STATICLIB;HAVE_VULKAN;HAVE_SDL3;ZLIB_CONST;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AL_LIBTYPE_STATIC;MINIUPNP_STATICLIB;HAVE_VULKAN;HAVE_SDL3;ZLIB_CONST;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AL_LIBTYPE_STATIC;MINIUPNP_STATICLIB;HAVE_VULKAN;HAVE_SDL3;ZLIB_CONST;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
@@ -112,6 +112,7 @@
|
|||||||
<ClCompile Include="Emu\IPC_config.cpp" />
|
<ClCompile Include="Emu\IPC_config.cpp" />
|
||||||
<ClCompile Include="Emu\IPC_socket.cpp" />
|
<ClCompile Include="Emu\IPC_socket.cpp" />
|
||||||
<ClCompile Include="Emu\localized_string.cpp" />
|
<ClCompile Include="Emu\localized_string.cpp" />
|
||||||
|
<ClCompile Include="Emu\NP\clans_config.cpp" />
|
||||||
<ClCompile Include="Emu\NP\rpcn_config.cpp" />
|
<ClCompile Include="Emu\NP\rpcn_config.cpp" />
|
||||||
<ClCompile Include="Emu\NP\rpcn_countries.cpp" />
|
<ClCompile Include="Emu\NP\rpcn_countries.cpp" />
|
||||||
<ClCompile Include="Emu\NP\upnp_config.cpp" />
|
<ClCompile Include="Emu\NP\upnp_config.cpp" />
|
||||||
@@ -188,6 +189,7 @@
|
|||||||
<ClCompile Include="Emu\NP\np_requests.cpp" />
|
<ClCompile Include="Emu\NP\np_requests.cpp" />
|
||||||
<ClCompile Include="Emu\NP\signaling_handler.cpp" />
|
<ClCompile Include="Emu\NP\signaling_handler.cpp" />
|
||||||
<ClCompile Include="Emu\NP\np_structs_extra.cpp" />
|
<ClCompile Include="Emu\NP\np_structs_extra.cpp" />
|
||||||
|
<ClCompile Include="Emu\NP\clans_client.cpp" />
|
||||||
<ClCompile Include="Emu\NP\rpcn_client.cpp" />
|
<ClCompile Include="Emu\NP\rpcn_client.cpp" />
|
||||||
<ClCompile Include="Emu\NP\ip_address.cpp" />
|
<ClCompile Include="Emu\NP\ip_address.cpp" />
|
||||||
<ClCompile Include="Emu\vfs_config.cpp" />
|
<ClCompile Include="Emu\vfs_config.cpp" />
|
||||||
|
|||||||
@@ -406,6 +406,9 @@
|
|||||||
<ClCompile Include="QTGeneratedFiles\Debug\moc_render_creator.cpp">
|
<ClCompile Include="QTGeneratedFiles\Debug\moc_render_creator.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="QTGeneratedFiles\Debug\moc_clans_settings_dialog.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="QTGeneratedFiles\Debug\moc_rpcn_settings_dialog.cpp">
|
<ClCompile Include="QTGeneratedFiles\Debug\moc_rpcn_settings_dialog.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -697,6 +700,9 @@
|
|||||||
<ClCompile Include="QTGeneratedFiles\Release\moc_render_creator.cpp">
|
<ClCompile Include="QTGeneratedFiles\Release\moc_render_creator.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="QTGeneratedFiles\Release\moc_clans_settings_dialog.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="QTGeneratedFiles\Release\moc_rpcn_settings_dialog.cpp">
|
<ClCompile Include="QTGeneratedFiles\Release\moc_rpcn_settings_dialog.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -807,6 +813,7 @@
|
|||||||
<ClCompile Include="rpcs3qt\permissions.cpp" />
|
<ClCompile Include="rpcs3qt\permissions.cpp" />
|
||||||
<ClCompile Include="rpcs3qt\ps_move_tracker_dialog.cpp" />
|
<ClCompile Include="rpcs3qt\ps_move_tracker_dialog.cpp" />
|
||||||
<ClCompile Include="rpcs3qt\cheat_manager.cpp" />
|
<ClCompile Include="rpcs3qt\cheat_manager.cpp" />
|
||||||
|
<ClCompile Include="rpcs3qt\clans_settings_dialog.cpp" />
|
||||||
<ClCompile Include="rpcs3qt\config_adapter.cpp" />
|
<ClCompile Include="rpcs3qt\config_adapter.cpp" />
|
||||||
<ClCompile Include="rpcs3qt\config_checker.cpp" />
|
<ClCompile Include="rpcs3qt\config_checker.cpp" />
|
||||||
<ClCompile Include="rpcs3qt\curl_handle.cpp" />
|
<ClCompile Include="rpcs3qt\curl_handle.cpp" />
|
||||||
@@ -1488,6 +1495,16 @@
|
|||||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(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_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtConcurrent"</Command>
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(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_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtConcurrent"</Command>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="rpcs3qt\clans_settings_dialog.h">
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing %(Identity)...</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(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_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$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtConcurrent"</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing %(Identity)...</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(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_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtConcurrent"</Command>
|
||||||
|
</CustomBuild>
|
||||||
<CustomBuild Include="rpcs3qt\localized_emu.h">
|
<CustomBuild Include="rpcs3qt\localized_emu.h">
|
||||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing %(Identity)...</Message>
|
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing %(Identity)...</Message>
|
||||||
|
|||||||
@@ -864,6 +864,12 @@
|
|||||||
<ClCompile Include="QTGeneratedFiles\Release\moc_downloader.cpp">
|
<ClCompile Include="QTGeneratedFiles\Release\moc_downloader.cpp">
|
||||||
<Filter>Generated Files\Release</Filter>
|
<Filter>Generated Files\Release</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="QTGeneratedFiles\Debug\moc_clans_settings_dialog.cpp">
|
||||||
|
<Filter>Generated Files\Debug</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="QTGeneratedFiles\Release\moc_clans_settings_dialog.cpp">
|
||||||
|
<Filter>Generated Files\Release</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="QTGeneratedFiles\Debug\moc_rpcn_settings_dialog.cpp">
|
<ClCompile Include="QTGeneratedFiles\Debug\moc_rpcn_settings_dialog.cpp">
|
||||||
<Filter>Generated Files\Debug</Filter>
|
<Filter>Generated Files\Debug</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -909,6 +915,9 @@
|
|||||||
<ClCompile Include="rpcs3qt\rpcn_settings_dialog.cpp">
|
<ClCompile Include="rpcs3qt\rpcn_settings_dialog.cpp">
|
||||||
<Filter>Gui\rpcn</Filter>
|
<Filter>Gui\rpcn</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="rpcs3qt\clans_settings_dialog.cpp">
|
||||||
|
<Filter>Gui\clans</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="rpcs3qt\sendmessage_dialog_frame.cpp">
|
<ClCompile Include="rpcs3qt\sendmessage_dialog_frame.cpp">
|
||||||
<Filter>Gui\message dialog</Filter>
|
<Filter>Gui\message dialog</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -1699,6 +1708,9 @@
|
|||||||
<CustomBuild Include="rpcs3qt\rpcn_settings_dialog.h">
|
<CustomBuild Include="rpcs3qt\rpcn_settings_dialog.h">
|
||||||
<Filter>Gui\rpcn</Filter>
|
<Filter>Gui\rpcn</Filter>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="rpcs3qt\clans_settings_dialog.h">
|
||||||
|
<Filter>Gui\rpcn</Filter>
|
||||||
|
</CustomBuild>
|
||||||
<CustomBuild Include="rpcs3qt\sendmessage_dialog_frame.h">
|
<CustomBuild Include="rpcs3qt\sendmessage_dialog_frame.h">
|
||||||
<Filter>Gui\message dialog</Filter>
|
<Filter>Gui\message dialog</Filter>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ add_library(rpcs3_ui STATIC
|
|||||||
camera_settings_dialog.cpp
|
camera_settings_dialog.cpp
|
||||||
cg_disasm_window.cpp
|
cg_disasm_window.cpp
|
||||||
cheat_manager.cpp
|
cheat_manager.cpp
|
||||||
|
clans_settings_dialog.cpp
|
||||||
config_adapter.cpp
|
config_adapter.cpp
|
||||||
config_checker.cpp
|
config_checker.cpp
|
||||||
curl_handle.cpp
|
curl_handle.cpp
|
||||||
|
|||||||
@@ -0,0 +1,187 @@
|
|||||||
|
#include <QMessageBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QLineEdit>
|
||||||
|
|
||||||
|
#include "clans_settings_dialog.h"
|
||||||
|
#include "Emu/NP/clans_config.h"
|
||||||
|
|
||||||
|
clans_settings_dialog::clans_settings_dialog(QWidget* parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
{
|
||||||
|
g_cfg_clans.load();
|
||||||
|
|
||||||
|
setWindowTitle(tr("Clans Configuration"));
|
||||||
|
setObjectName("clans_settings_dialog");
|
||||||
|
|
||||||
|
QVBoxLayout* vbox_global = new QVBoxLayout();
|
||||||
|
|
||||||
|
QGroupBox* grp_server = new QGroupBox(tr("Server:"));
|
||||||
|
QVBoxLayout* vbox_server = new QVBoxLayout();
|
||||||
|
|
||||||
|
QHBoxLayout* hbox_lbl_combo = new QHBoxLayout();
|
||||||
|
QLabel* lbl_server = new QLabel(tr("Server:"));
|
||||||
|
m_cbx_servers = new QComboBox();
|
||||||
|
m_cbx_protocol = new QComboBox();
|
||||||
|
|
||||||
|
m_cbx_protocol->addItem("HTTPS");
|
||||||
|
m_cbx_protocol->addItem("HTTP");
|
||||||
|
m_cbx_protocol->setCurrentIndex(g_cfg_clans.get_use_https() ? 0 : 1);
|
||||||
|
|
||||||
|
refresh_combobox();
|
||||||
|
|
||||||
|
hbox_lbl_combo->addWidget(lbl_server);
|
||||||
|
hbox_lbl_combo->addWidget(m_cbx_servers);
|
||||||
|
hbox_lbl_combo->addWidget(m_cbx_protocol);
|
||||||
|
|
||||||
|
QHBoxLayout* hbox_buttons = new QHBoxLayout();
|
||||||
|
QPushButton* btn_add_server = new QPushButton(tr("Add"));
|
||||||
|
QPushButton* btn_del_server = new QPushButton(tr("Del"));
|
||||||
|
hbox_buttons->addStretch();
|
||||||
|
hbox_buttons->addWidget(btn_add_server);
|
||||||
|
hbox_buttons->addWidget(btn_del_server);
|
||||||
|
|
||||||
|
vbox_server->addLayout(hbox_lbl_combo);
|
||||||
|
vbox_server->addLayout(hbox_buttons);
|
||||||
|
|
||||||
|
grp_server->setLayout(vbox_server);
|
||||||
|
vbox_global->addWidget(grp_server);
|
||||||
|
|
||||||
|
setLayout(vbox_global);
|
||||||
|
|
||||||
|
connect(m_cbx_servers, &QComboBox::currentIndexChanged, this, [this](int index)
|
||||||
|
{
|
||||||
|
if (index < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QVariant host = m_cbx_servers->itemData(index);
|
||||||
|
|
||||||
|
if (!host.isValid() || !host.canConvert<QString>())
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_cfg_clans.set_host(host.toString().toStdString());
|
||||||
|
g_cfg_clans.save();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_cbx_protocol, &QComboBox::currentIndexChanged, this, [this](int index)
|
||||||
|
{
|
||||||
|
if (index < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_cfg_clans.set_use_https(index == 0);
|
||||||
|
g_cfg_clans.save();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(btn_add_server, &QAbstractButton::clicked, this, [this]()
|
||||||
|
{
|
||||||
|
clans_add_server_dialog dlg(this);
|
||||||
|
dlg.exec();
|
||||||
|
const auto& new_server = dlg.get_new_server();
|
||||||
|
if (new_server)
|
||||||
|
{
|
||||||
|
if (!g_cfg_clans.add_host(new_server->first, new_server->second))
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Existing Server"), tr("You already have a server with this description & hostname in the list."), QMessageBox::Ok);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_cfg_clans.save();
|
||||||
|
refresh_combobox();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(btn_del_server, &QAbstractButton::clicked, this, [this]()
|
||||||
|
{
|
||||||
|
const int index = m_cbx_servers->currentIndex();
|
||||||
|
|
||||||
|
if (index < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const std::string desc = m_cbx_servers->itemText(index).toStdString();
|
||||||
|
const std::string host = m_cbx_servers->itemData(index).toString().toStdString();
|
||||||
|
|
||||||
|
if (g_cfg_clans.del_host(desc, host))
|
||||||
|
{
|
||||||
|
g_cfg_clans.save();
|
||||||
|
refresh_combobox();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, tr("Cannot Delete"), tr("This server cannot be deleted."), QMessageBox::Ok);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void clans_settings_dialog::refresh_combobox()
|
||||||
|
{
|
||||||
|
g_cfg_clans.load();
|
||||||
|
const auto vec_hosts = g_cfg_clans.get_hosts();
|
||||||
|
const auto cur_host = g_cfg_clans.get_host();
|
||||||
|
int i = 0, index = 0;
|
||||||
|
|
||||||
|
m_cbx_servers->clear();
|
||||||
|
|
||||||
|
for (const auto& [desc, host] : vec_hosts)
|
||||||
|
{
|
||||||
|
m_cbx_servers->addItem(QString::fromStdString(desc), QString::fromStdString(host));
|
||||||
|
if (cur_host == host)
|
||||||
|
index = i;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_cbx_servers->setCurrentIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
clans_add_server_dialog::clans_add_server_dialog(QWidget* parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
{
|
||||||
|
setWindowTitle(tr("Clans: Add Server"));
|
||||||
|
setObjectName("clans_add_server_dialog");
|
||||||
|
setMinimumSize(QSize(400, 200));
|
||||||
|
|
||||||
|
QVBoxLayout* vbox_global = new QVBoxLayout();
|
||||||
|
|
||||||
|
QLabel* lbl_description = new QLabel(tr("Description:"));
|
||||||
|
QLineEdit* edt_description = new QLineEdit();
|
||||||
|
QLabel* lbl_host = new QLabel(tr("Host:"));
|
||||||
|
QLineEdit* edt_host = new QLineEdit();
|
||||||
|
QDialogButtonBox* btn_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||||
|
|
||||||
|
vbox_global->addWidget(lbl_description);
|
||||||
|
vbox_global->addWidget(edt_description);
|
||||||
|
vbox_global->addWidget(lbl_host);
|
||||||
|
vbox_global->addWidget(edt_host);
|
||||||
|
vbox_global->addWidget(btn_box);
|
||||||
|
|
||||||
|
setLayout(vbox_global);
|
||||||
|
|
||||||
|
connect(btn_box, &QDialogButtonBox::accepted, this, [this, edt_description, edt_host]()
|
||||||
|
{
|
||||||
|
const QString description = edt_description->text();
|
||||||
|
const QString host = edt_host->text();
|
||||||
|
|
||||||
|
if (description.isEmpty())
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Missing Description!"), tr("You must enter a description!"), QMessageBox::Ok);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (host.isEmpty())
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Missing Hostname!"), tr("You must enter a hostname for the server!"), QMessageBox::Ok);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_new_server = std::make_pair(description.toStdString(), host.toStdString());
|
||||||
|
QDialog::accept();
|
||||||
|
});
|
||||||
|
connect(btn_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::optional<std::pair<std::string, std::string>>& clans_add_server_dialog::get_new_server() const
|
||||||
|
{
|
||||||
|
return m_new_server;
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
class clans_settings_dialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
clans_settings_dialog(QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void refresh_combobox();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QComboBox* m_cbx_servers = nullptr;
|
||||||
|
QComboBox* m_cbx_protocol = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class clans_add_server_dialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
clans_add_server_dialog(QWidget* parent = nullptr);
|
||||||
|
const std::optional<std::pair<std::string, std::string>>& get_new_server() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::optional<std::pair<std::string, std::string>> m_new_server;
|
||||||
|
};
|
||||||
@@ -200,6 +200,7 @@ enum class emu_settings_type
|
|||||||
BindAddress,
|
BindAddress,
|
||||||
EnableUpnp,
|
EnableUpnp,
|
||||||
PSNCountry,
|
PSNCountry,
|
||||||
|
EnableClans,
|
||||||
|
|
||||||
// System
|
// System
|
||||||
LicenseArea,
|
LicenseArea,
|
||||||
@@ -411,6 +412,7 @@ inline static const std::map<emu_settings_type, cfg_location> settings_location
|
|||||||
{ emu_settings_type::BindAddress, { "Net", "Bind address"}},
|
{ emu_settings_type::BindAddress, { "Net", "Bind address"}},
|
||||||
{ emu_settings_type::EnableUpnp, { "Net", "UPNP Enabled"}},
|
{ emu_settings_type::EnableUpnp, { "Net", "UPNP Enabled"}},
|
||||||
{ emu_settings_type::PSNCountry, { "Net", "PSN Country"}},
|
{ emu_settings_type::PSNCountry, { "Net", "PSN Country"}},
|
||||||
|
{ emu_settings_type::EnableClans, { "Net", "Clans Enabled"}},
|
||||||
|
|
||||||
// System
|
// System
|
||||||
{ emu_settings_type::LicenseArea, { "System", "License Area"}},
|
{ emu_settings_type::LicenseArea, { "System", "License Area"}},
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "log_frame.h"
|
#include "log_frame.h"
|
||||||
#include "settings_dialog.h"
|
#include "settings_dialog.h"
|
||||||
#include "rpcn_settings_dialog.h"
|
#include "rpcn_settings_dialog.h"
|
||||||
|
#include "clans_settings_dialog.h"
|
||||||
#include "auto_pause_settings_dialog.h"
|
#include "auto_pause_settings_dialog.h"
|
||||||
#include "cg_disasm_window.h"
|
#include "cg_disasm_window.h"
|
||||||
#include "log_viewer.h"
|
#include "log_viewer.h"
|
||||||
@@ -2991,6 +2992,18 @@ void main_window::CreateConnects()
|
|||||||
dlg.exec();
|
dlg.exec();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(ui->confClansAct, &QAction::triggered, this, [this]()
|
||||||
|
{
|
||||||
|
if (!Emu.IsStopped())
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Error: Emulation Running"), tr("You need to stop the emulator before editing Clans connection information!"), QMessageBox::Ok);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clans_settings_dialog dlg(this);
|
||||||
|
dlg.exec();
|
||||||
|
});
|
||||||
|
|
||||||
connect(ui->confIPCAct, &QAction::triggered, this, [this]()
|
connect(ui->confIPCAct, &QAction::triggered, this, [this]()
|
||||||
{
|
{
|
||||||
ipc_settings_dialog dlg(this);
|
ipc_settings_dialog dlg(this);
|
||||||
|
|||||||
@@ -282,6 +282,7 @@
|
|||||||
<addaction name="confGuiAct"/>
|
<addaction name="confGuiAct"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="confRPCNAct"/>
|
<addaction name="confRPCNAct"/>
|
||||||
|
<addaction name="confClansAct"/>
|
||||||
<addaction name="confIPCAct"/>
|
<addaction name="confIPCAct"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="confShortcutsAct"/>
|
<addaction name="confShortcutsAct"/>
|
||||||
@@ -1252,6 +1253,14 @@
|
|||||||
<string>Configure RPCN</string>
|
<string>Configure RPCN</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="confClansAct">
|
||||||
|
<property name="text">
|
||||||
|
<string>Clans</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Configure Clans</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
<action name="confIPCAct">
|
<action name="confIPCAct">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>IPC</string>
|
<string>IPC</string>
|
||||||
|
|||||||
@@ -1435,10 +1435,12 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
|||||||
{
|
{
|
||||||
ui->psnStatusBox->setCurrentIndex(find_item(ui->psnStatusBox, static_cast<int>(g_cfg.net.psn_status.def)));
|
ui->psnStatusBox->setCurrentIndex(find_item(ui->psnStatusBox, static_cast<int>(g_cfg.net.psn_status.def)));
|
||||||
ui->psnStatusBox->setEnabled(false);
|
ui->psnStatusBox->setEnabled(false);
|
||||||
|
ui->enable_clans->setEnabled(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ui->psnStatusBox->setEnabled(true);
|
ui->psnStatusBox->setEnabled(true);
|
||||||
|
ui->enable_clans->setEnabled(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
m_emu_settings->EnhanceComboBox(ui->netStatusBox, emu_settings_type::InternetStatus);
|
m_emu_settings->EnhanceComboBox(ui->netStatusBox, emu_settings_type::InternetStatus);
|
||||||
@@ -1447,6 +1449,9 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
|||||||
m_emu_settings->EnhanceComboBox(ui->psnStatusBox, emu_settings_type::PSNStatus);
|
m_emu_settings->EnhanceComboBox(ui->psnStatusBox, emu_settings_type::PSNStatus);
|
||||||
SubscribeTooltip(ui->gb_psnStatusBox, tooltips.settings.psn_status);
|
SubscribeTooltip(ui->gb_psnStatusBox, tooltips.settings.psn_status);
|
||||||
|
|
||||||
|
m_emu_settings->EnhanceCheckBox(ui->enable_clans, emu_settings_type::EnableClans);
|
||||||
|
SubscribeTooltip(ui->enable_clans, tooltips.settings.enable_clans);
|
||||||
|
|
||||||
settings_dialog::refresh_countrybox();
|
settings_dialog::refresh_countrybox();
|
||||||
connect(ui->psnCountryBox, &QComboBox::currentIndexChanged, this, [this](int index)
|
connect(ui->psnCountryBox, &QComboBox::currentIndexChanged, this, [this](int index)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2319,6 +2319,13 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="enable_clans">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable Clans</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="networkTabSpacerRight">
|
<spacer name="networkTabSpacerRight">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|||||||
@@ -260,6 +260,7 @@ public:
|
|||||||
const QString bind = tr("Interface IP Address to bind to.\nOnly available in custom configurations.");
|
const QString bind = tr("Interface IP Address to bind to.\nOnly available in custom configurations.");
|
||||||
const QString enable_upnp = tr("Enable UPNP.\nThis will automatically forward ports bound on 0.0.0.0 if your router has UPNP enabled.");
|
const QString enable_upnp = tr("Enable UPNP.\nThis will automatically forward ports bound on 0.0.0.0 if your router has UPNP enabled.");
|
||||||
const QString psn_country = tr("Changes the RPCN country.");
|
const QString psn_country = tr("Changes the RPCN country.");
|
||||||
|
const QString enable_clans = tr("Enable connection to the Clans server.\nOnly affects games supporting the Clans feature.");
|
||||||
|
|
||||||
// system
|
// system
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user