mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-07-09 17:25:37 -06:00
Matching2 part 2: more types, structs, enums, context backend, init, term, createcontext / createcontextA. added ctxid to all shadnet notifications for matching2 and added matching2 events. (#4631)
This commit is contained in:
parent
38444639a5
commit
59d7c92e45
@ -632,6 +632,8 @@ set(NP_LIBS src/core/libraries/np/np_error.h
|
||||
src/core/libraries/np/np_manager.h
|
||||
src/core/libraries/np/np_matching2/np_matching2.cpp
|
||||
src/core/libraries/np/np_matching2/np_matching2.h
|
||||
src/core/libraries/np/np_matching2/np_matching2_internal.cpp
|
||||
src/core/libraries/np/np_matching2/np_matching2_internal.h
|
||||
src/core/libraries/np/np_matching2/np_matching2_types.h
|
||||
src/core/libraries/np/np_trophy.cpp
|
||||
src/core/libraries/np/np_trophy.h
|
||||
|
||||
@ -8,8 +8,10 @@
|
||||
#include "core/emulator_settings.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "core/libraries/np/np_handler.h"
|
||||
#include "core/libraries/np/np_manager.h"
|
||||
#include "core/libraries/np/np_matching2/np_matching2.h"
|
||||
#include "core/libraries/np/np_matching2/np_matching2_internal.h"
|
||||
#include "core/libraries/np/np_matching2/np_matching2_types.h"
|
||||
#include "core/libraries/np/np_types.h"
|
||||
#include "core/libraries/system/userservice.h"
|
||||
@ -38,9 +40,7 @@ int PS4_SYSV_ABI sceNpMatching2CreateContext(const OrbisNpMatching2CreateContext
|
||||
return ORBIS_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
*ctxId = contextId++;
|
||||
|
||||
return ORBIS_OK;
|
||||
return ContextManager::Instance().CreateContext(param->npId, param->serviceLabel, ctxId);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNpMatching2CreateContextA(const OrbisNpMatching2CreateContextParameterA* param,
|
||||
@ -55,9 +55,10 @@ int PS4_SYSV_ABI sceNpMatching2CreateContextA(const OrbisNpMatching2CreateContex
|
||||
return ORBIS_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
*ctxId = contextId++;
|
||||
const Libraries::Np::OrbisNpId np_id =
|
||||
Libraries::Np::NpHandler::GetInstance().GetNpId(param->userId);
|
||||
|
||||
return ORBIS_OK;
|
||||
return ContextManager::Instance().CreateContext(&np_id, param->serviceLabel, ctxId);
|
||||
}
|
||||
|
||||
static std::optional<OrbisNpMatching2RequestOptParam> defaultRequestOptParam = std::nullopt;
|
||||
@ -272,7 +273,20 @@ int PS4_SYSV_ABI sceNpMatching2Initialize(OrbisNpMatching2InitializeParameter* p
|
||||
return ORBIS_NP_MATCHING2_ERROR_ALREADY_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!param || (param->size != 0x30 && param->size != 0x28)) {
|
||||
return ORBIS_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
LOG_INFO(Lib_NpMatching2, "poolSize={:#x} stackSize={:#x} priority={} size={:#x}",
|
||||
param->poolSize, param->stackSize, param->priority, param->size);
|
||||
if (param->size == 0x30) {
|
||||
LOG_INFO(Lib_NpMatching2, "sslPoolSize={:#x}", param->sslPoolSize);
|
||||
}
|
||||
|
||||
InitEventDispatcher();
|
||||
|
||||
g_initialized = true;
|
||||
g_state.initialized.store(true);
|
||||
Libraries::Np::NpManager::RegisterNpCallback("NpMatching2", ProcessEvents);
|
||||
|
||||
return ORBIS_OK;
|
||||
@ -286,8 +300,12 @@ int PS4_SYSV_ABI sceNpMatching2Terminate() {
|
||||
}
|
||||
|
||||
g_initialized = false;
|
||||
g_state.initialized.store(false);
|
||||
Libraries::Np::NpManager::DeregisterNpCallback("NpMatching2");
|
||||
|
||||
TermEventDispatcher();
|
||||
ContextManager::Instance().Reset();
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -13,70 +13,94 @@ namespace Libraries::Np::NpMatching2 {
|
||||
|
||||
using OrbisNpMatching2AttributeId = u16;
|
||||
using OrbisNpMatching2ContextId = u16;
|
||||
using OrbisNpMatching2Event = u16;
|
||||
using OrbisNpMatching2EventCause = u8;
|
||||
using OrbisNpMatching2Flags = u32;
|
||||
using OrbisNpMatching2LobbyId = u64;
|
||||
using OrbisNpMatching2LobbyMemberId = u16;
|
||||
using OrbisNpMatching2NatType = u8;
|
||||
using OrbisNpMatching2RequestId = u32;
|
||||
using OrbisNpMatching2RoomGroupId = u8;
|
||||
using OrbisNpMatching2RoomId = u64;
|
||||
using OrbisNpMatching2RoomMemberId = u16;
|
||||
using OrbisNpMatching2RoomPasswordSlotMask = u64;
|
||||
using OrbisNpMatching2ServerId = u16;
|
||||
using OrbisNpMatching2SignalingFlag = u8;
|
||||
using OrbisNpMatching2SignalingRequestId = u32;
|
||||
using OrbisNpMatching2SignalingType = u8;
|
||||
using OrbisNpMatching2TeamId = u8;
|
||||
using OrbisNpMatching2WorldId = u32;
|
||||
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_GET_WORLD_INFO_LIST = 0x0002;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_SET_ROOM_DATA_EXTERNAL = 0x0004;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_SET_USER_INFO = 0x0007;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_CREATE_JOIN_ROOM = 0x0101;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_JOIN_ROOM = 0x0102;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_LEAVE_ROOM = 0x0103;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_KICKOUT_ROOM_MEMBER = 0x0104;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_GRANT_ROOM_OWNER = 0x0105;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_SEARCH_ROOM = 0x0106;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_SEND_ROOM_MESSAGE = 0x0108;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_SET_ROOM_DATA_INTERNAL = 0x0109;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_GET_ROOM_DATA_INTERNAL = 0x010A;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_JOIN_LOBBY = 0x0201;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_SIGNALING_GET_PING_INFO = 0x0E01;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_ROOM_EVENT_MEMBER_JOINED = 0x1101;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_ROOM_EVENT_MEMBER_LEFT = 0x1102;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_ROOM_EVENT_KICKEDOUT = 0x1103;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_ROOM_EVENT_ROOM_DESTROYED = 0x1104;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_ROOM_EVENT_ROOM_OWNER_CHANGED = 0x1105;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_ROOM_EVENT_UPDATED_ROOM_DATA_INTERNAL = 0x1106;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_ROOM_EVENT_UPDATED_ROOM_MEMBER_DATA_INTERNAL =
|
||||
0x1107;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_ROOM_EVENT_UPDATED_SIGNALING_OPT_PARAM = 0x1108;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_SIGNALING_EVENT_DEAD = 0x5101;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_SIGNALING_EVENT_ESTABLISHED = 0x5102;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_SIGNALING_EVENT_NETINFO_ERROR = 0x5103;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_CONTEXT_EVENT_START_OVER = 0x6F01;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_CONTEXT_EVENT_STARTED = 0x6F02;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_CONTEXT_EVENT_STOPPED = 0x6F03;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_CREATE_JOIN_ROOM_A = 0x7101;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_REQUEST_EVENT_SEARCH_ROOM_A = 0x7106;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_ROOM_EVENT_MEMBER_JOINED_A = 0x8101;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_ROOM_EVENT_MEMBER_LEFT_A = 0x8102;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_ROOM_EVENT_UPDATED_ROOM_MEMBER_DATA_INTERNAL_A =
|
||||
0x8107;
|
||||
constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_ROOM_MSG_EVENT_MESSAGE_A = 0x9102;
|
||||
enum OrbisNpMatching2Event : u16 {
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_GET_WORLD_INFO_LIST = 0x0002,
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_SET_ROOM_DATA_EXTERNAL = 0x0004,
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_SET_USER_INFO = 0x0007,
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_CREATE_JOIN_ROOM = 0x0101,
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_JOIN_ROOM = 0x0102,
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_LEAVE_ROOM = 0x0103,
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_KICKOUT_ROOM_MEMBER = 0x0104,
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_GRANT_ROOM_OWNER = 0x0105,
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_SEARCH_ROOM = 0x0106,
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_SEND_ROOM_MESSAGE = 0x0108,
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_SET_ROOM_DATA_INTERNAL = 0x0109,
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_GET_ROOM_DATA_INTERNAL = 0x010A,
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_JOIN_LOBBY = 0x0201,
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_SIGNALING_GET_PING_INFO = 0x0E01,
|
||||
ORBIS_NP_MATCHING2_ROOM_EVENT_MEMBER_JOINED = 0x1101,
|
||||
ORBIS_NP_MATCHING2_ROOM_EVENT_MEMBER_LEFT = 0x1102,
|
||||
ORBIS_NP_MATCHING2_ROOM_EVENT_KICKEDOUT = 0x1103,
|
||||
ORBIS_NP_MATCHING2_ROOM_EVENT_ROOM_DESTROYED = 0x1104,
|
||||
ORBIS_NP_MATCHING2_ROOM_EVENT_ROOM_OWNER_CHANGED = 0x1105,
|
||||
ORBIS_NP_MATCHING2_ROOM_EVENT_UPDATED_ROOM_DATA_INTERNAL = 0x1106,
|
||||
ORBIS_NP_MATCHING2_ROOM_EVENT_UPDATED_ROOM_MEMBER_DATA_INTERNAL = 0x1107,
|
||||
ORBIS_NP_MATCHING2_ROOM_EVENT_UPDATED_SIGNALING_OPT_PARAM = 0x1108,
|
||||
ORBIS_NP_MATCHING2_SIGNALING_EVENT_DEAD = 0x5101,
|
||||
ORBIS_NP_MATCHING2_SIGNALING_EVENT_ESTABLISHED = 0x5102,
|
||||
ORBIS_NP_MATCHING2_SIGNALING_EVENT_NETINFO_ERROR = 0x5103,
|
||||
ORBIS_NP_MATCHING2_CONTEXT_EVENT_START_OVER = 0x6F01,
|
||||
ORBIS_NP_MATCHING2_CONTEXT_EVENT_STARTED = 0x6F02,
|
||||
ORBIS_NP_MATCHING2_CONTEXT_EVENT_STOPPED = 0x6F03,
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_CREATE_JOIN_ROOM_A = 0x7101,
|
||||
ORBIS_NP_MATCHING2_REQUEST_EVENT_SEARCH_ROOM_A = 0x7106,
|
||||
ORBIS_NP_MATCHING2_ROOM_EVENT_MEMBER_JOINED_A = 0x8101,
|
||||
ORBIS_NP_MATCHING2_ROOM_EVENT_MEMBER_LEFT_A = 0x8102,
|
||||
ORBIS_NP_MATCHING2_ROOM_EVENT_UPDATED_ROOM_MEMBER_DATA_INTERNAL_A = 0x8107,
|
||||
ORBIS_NP_MATCHING2_ROOM_MSG_EVENT_MESSAGE_A = 0x9102,
|
||||
};
|
||||
|
||||
constexpr OrbisNpMatching2EventCause ORBIS_NP_MATCHING2_EVENT_CAUSE_LEAVE_ACTION = 1;
|
||||
constexpr OrbisNpMatching2EventCause ORBIS_NP_MATCHING2_EVENT_CAUSE_KICKOUT_ACTION = 2;
|
||||
constexpr OrbisNpMatching2EventCause ORBIS_NP_MATCHING2_EVENT_CAUSE_GRANT_OWNER_ACTION = 3;
|
||||
constexpr OrbisNpMatching2EventCause ORBIS_NP_MATCHING2_EVENT_CAUSE_MEMBER_DISAPPEARED = 5;
|
||||
constexpr OrbisNpMatching2EventCause ORBIS_NP_MATCHING2_EVENT_CAUSE_NP_SIGNED_OUT = 8;
|
||||
constexpr OrbisNpMatching2EventCause ORBIS_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ERROR = 10;
|
||||
constexpr OrbisNpMatching2EventCause ORBIS_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ACTION = 11;
|
||||
enum OrbisNpMatching2EventCause : u8 {
|
||||
ORBIS_NP_MATCHING2_EVENT_CAUSE_LEAVE_ACTION = 1,
|
||||
ORBIS_NP_MATCHING2_EVENT_CAUSE_KICKOUT_ACTION = 2,
|
||||
ORBIS_NP_MATCHING2_EVENT_CAUSE_GRANT_OWNER_ACTION = 3,
|
||||
ORBIS_NP_MATCHING2_EVENT_CAUSE_SERVER_OPERATION = 4,
|
||||
ORBIS_NP_MATCHING2_EVENT_CAUSE_MEMBER_DISAPPEARED = 5,
|
||||
ORBIS_NP_MATCHING2_EVENT_CAUSE_SERVER_INTERNAL = 6,
|
||||
ORBIS_NP_MATCHING2_EVENT_CAUSE_CONNECTION_ERROR = 7,
|
||||
ORBIS_NP_MATCHING2_EVENT_CAUSE_NP_SIGNED_OUT = 8,
|
||||
ORBIS_NP_MATCHING2_EVENT_CAUSE_SYSTEM_ERROR = 9,
|
||||
ORBIS_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ERROR = 10,
|
||||
ORBIS_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ACTION = 11,
|
||||
};
|
||||
|
||||
constexpr OrbisNpMatching2SignalingType ORBIS_NP_MATCHING2_SIGNALING_TYPE_NONE = 0;
|
||||
constexpr OrbisNpMatching2SignalingType ORBIS_NP_MATCHING2_SIGNALING_TYPE_MESH = 1;
|
||||
constexpr OrbisNpMatching2SignalingType ORBIS_NP_MATCHING2_SIGNALING_TYPE_STAR = 2;
|
||||
enum OrbisNpMatching2SignalingType : u8 {
|
||||
ORBIS_NP_MATCHING2_SIGNALING_TYPE_NONE = 0,
|
||||
ORBIS_NP_MATCHING2_SIGNALING_TYPE_MESH = 1,
|
||||
ORBIS_NP_MATCHING2_SIGNALING_TYPE_STAR = 2,
|
||||
};
|
||||
|
||||
enum OrbisNpMatching2InitDefault : u64 {
|
||||
ORBIS_NP_MATCHING2_THREAD_STACK_SIZE_DEFAULT = 32768,
|
||||
ORBIS_NP_MATCHING2_POOLSIZE_DEFAULT = 131072,
|
||||
ORBIS_NP_MATCHING2_SSL_POOLSIZE_DEFAULT = 196608,
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2InitializeParameter;
|
||||
struct OrbisNpMatching2CreateContextParameter;
|
||||
struct OrbisNpMatching2CreateContextParameterA;
|
||||
|
||||
int PS4_SYSV_ABI sceNpMatching2Initialize(OrbisNpMatching2InitializeParameter* param);
|
||||
int PS4_SYSV_ABI sceNpMatching2Terminate();
|
||||
int PS4_SYSV_ABI sceNpMatching2CreateContext(const OrbisNpMatching2CreateContextParameter* param,
|
||||
OrbisNpMatching2ContextId* ctxId);
|
||||
int PS4_SYSV_ABI sceNpMatching2CreateContextA(const OrbisNpMatching2CreateContextParameterA* param,
|
||||
OrbisNpMatching2ContextId* ctxId);
|
||||
|
||||
void RegisterLib(Core::Loader::SymbolsResolver* sym);
|
||||
} // namespace Libraries::Np::NpMatching2
|
||||
263
src/core/libraries/np/np_matching2/np_matching2_internal.cpp
Normal file
263
src/core/libraries/np/np_matching2/np_matching2_internal.cpp
Normal file
@ -0,0 +1,263 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/np/np_common.h"
|
||||
#include "core/libraries/np/np_error.h"
|
||||
#include "core/libraries/np/np_matching2/np_matching2_internal.h"
|
||||
|
||||
namespace Libraries::Np::NpMatching2 {
|
||||
|
||||
NpMatching2State g_state;
|
||||
|
||||
ContextManager& ContextManager::Instance() {
|
||||
static ContextManager instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
ContextObject* ContextManager::GetLocked(OrbisNpMatching2ContextId ctx_id) {
|
||||
if (ctx_id == 0 || ctx_id > kMaxContexts || !m_used[ctx_id]) {
|
||||
return nullptr;
|
||||
}
|
||||
return &m_contexts[ctx_id];
|
||||
}
|
||||
|
||||
s32 ContextManager::CreateContext(const OrbisNpId* owner_np_id, OrbisNpServiceLabel service_label,
|
||||
OrbisNpMatching2ContextId* out_ctx_id) {
|
||||
if (!out_ctx_id) {
|
||||
return ORBIS_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
OrbisNpMatching2ContextId id = 0;
|
||||
for (u32 i = 0; i < kMaxContexts; ++i) {
|
||||
const OrbisNpMatching2ContextId candidate =
|
||||
static_cast<OrbisNpMatching2ContextId>(((m_next_id - 1 + i) % kMaxContexts) + 1);
|
||||
if (!m_used[candidate]) {
|
||||
id = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (id == 0) {
|
||||
return ORBIS_NP_MATCHING2_ERROR_CONTEXT_MAX;
|
||||
}
|
||||
m_next_id = static_cast<OrbisNpMatching2ContextId>((id % kMaxContexts) + 1);
|
||||
|
||||
ContextObject& ctx = m_contexts[id];
|
||||
ctx = ContextObject{};
|
||||
ctx.ctx_id = id;
|
||||
ctx.service_label = service_label;
|
||||
if (owner_np_id) {
|
||||
ctx.owner_np_id = *owner_np_id;
|
||||
ctx.online_id =
|
||||
std::string(owner_np_id->handle.data,
|
||||
strnlen(owner_np_id->handle.data, sizeof(owner_np_id->handle.data)));
|
||||
}
|
||||
if (ctx.online_id.empty()) {
|
||||
ctx.online_id = "shadPS4_player";
|
||||
}
|
||||
m_used[id] = true;
|
||||
|
||||
*out_ctx_id = id;
|
||||
LOG_INFO(Lib_NpMatching2, "context created: id={} online_id={} serviceLabel={:#x}", id,
|
||||
ctx.online_id, service_label);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
bool ContextManager::Check(OrbisNpMatching2ContextId ctx_id) {
|
||||
std::lock_guard lock(m_mutex);
|
||||
return GetLocked(ctx_id) != nullptr;
|
||||
}
|
||||
|
||||
ContextObject* ContextManager::Get(OrbisNpMatching2ContextId ctx_id) {
|
||||
std::lock_guard lock(m_mutex);
|
||||
return GetLocked(ctx_id);
|
||||
}
|
||||
|
||||
bool ContextManager::Destroy(OrbisNpMatching2ContextId ctx_id) {
|
||||
std::lock_guard lock(m_mutex);
|
||||
if (!GetLocked(ctx_id)) {
|
||||
return false;
|
||||
}
|
||||
m_contexts[ctx_id] = ContextObject{};
|
||||
m_used[ctx_id] = false;
|
||||
LOG_INFO(Lib_NpMatching2, "context destroyed: id={}", ctx_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
s32 ContextManager::Start(OrbisNpMatching2ContextId ctx_id) {
|
||||
std::lock_guard lock(m_mutex);
|
||||
ContextObject* ctx = GetLocked(ctx_id);
|
||||
if (!ctx) {
|
||||
return ORBIS_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID;
|
||||
}
|
||||
if (ctx->started) {
|
||||
return ORBIS_NP_MATCHING2_ERROR_CONTEXT_ALREADY_STARTED;
|
||||
}
|
||||
ctx->started = true;
|
||||
LOG_INFO(Lib_NpMatching2, "context started: id={}", ctx_id);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 ContextManager::Stop(OrbisNpMatching2ContextId ctx_id) {
|
||||
std::lock_guard lock(m_mutex);
|
||||
ContextObject* ctx = GetLocked(ctx_id);
|
||||
if (!ctx) {
|
||||
return ORBIS_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID;
|
||||
}
|
||||
if (!ctx->started) {
|
||||
return ORBIS_NP_MATCHING2_ERROR_CONTEXT_NOT_STARTED;
|
||||
}
|
||||
ctx->started = false;
|
||||
LOG_INFO(Lib_NpMatching2, "context stopped: id={}", ctx_id);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
void ContextManager::Reset() {
|
||||
std::lock_guard lock(m_mutex);
|
||||
m_contexts = {};
|
||||
m_used = {};
|
||||
m_next_id = 1;
|
||||
}
|
||||
|
||||
OrbisNpMatching2RequestId AllocRequestId() {
|
||||
std::lock_guard lock(g_state.mutex);
|
||||
const OrbisNpMatching2RequestId id = g_state.next_request_id++;
|
||||
if (g_state.next_request_id == 0) {
|
||||
g_state.next_request_id = 1;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void FireEvent(const PendingEvent& ev) {
|
||||
ContextObject* ctx = ContextManager::Instance().Get(ev.ctx_id);
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
switch (ev.type) {
|
||||
case PendingEvent::CONTEXT_CB:
|
||||
if (ctx->context_callback) {
|
||||
ctx->context_callback(ev.ctx_id, ev.ctx_event, ev.ctx_event_cause, ev.error_code,
|
||||
ctx->context_callback_arg);
|
||||
}
|
||||
break;
|
||||
case PendingEvent::REQUEST_CB:
|
||||
if (ev.request_cb) {
|
||||
ev.request_cb(ev.ctx_id, ev.req_id, ev.req_event, ev.error_code, ev.request_data,
|
||||
ev.request_cb_arg);
|
||||
}
|
||||
break;
|
||||
case PendingEvent::SIGNALING_CB:
|
||||
if (ctx->signaling_callback) {
|
||||
ctx->signaling_callback(ev.ctx_id, ev.room_id, ev.member_id, ev.sig_event,
|
||||
ev.error_code, ctx->signaling_callback_arg);
|
||||
}
|
||||
break;
|
||||
case PendingEvent::ROOM_EVENT_CB:
|
||||
if (ctx->room_event_callback) {
|
||||
ctx->room_event_callback(ev.ctx_id, ev.room_id, ev.room_event, ev.room_event_data,
|
||||
ctx->room_event_callback_arg);
|
||||
}
|
||||
break;
|
||||
case PendingEvent::LOBBY_EVENT_CB:
|
||||
if (ctx->lobby_event_callback) {
|
||||
ctx->lobby_event_callback(ev.ctx_id, ev.lobby_id, ev.lobby_event, ev.lobby_event_data,
|
||||
ctx->lobby_event_callback_arg);
|
||||
}
|
||||
break;
|
||||
case PendingEvent::LOBBY_MESSAGE_CB:
|
||||
if (ctx->lobby_message_callback) {
|
||||
ctx->lobby_message_callback(ev.ctx_id, ev.lobby_id, ev.src_member_id, ev.msg_event,
|
||||
ev.message_data, ctx->lobby_message_callback_arg);
|
||||
}
|
||||
break;
|
||||
case PendingEvent::ROOM_MESSAGE_CB:
|
||||
if (ctx->room_message_callback) {
|
||||
ctx->room_message_callback(ev.ctx_id, ev.room_id, ev.src_member_id, ev.msg_event,
|
||||
ev.message_data, ctx->room_message_callback_arg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PS4_SYSV_ABI void* EventDispatcherThreadMain(void* /*arg*/) {
|
||||
std::unique_lock lock(g_state.queue_mutex);
|
||||
while (g_state.dispatch_running.load()) {
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
|
||||
std::vector<PendingEvent> ready;
|
||||
auto nearest = std::chrono::steady_clock::time_point::max();
|
||||
for (auto it = g_state.pending_events.begin(); it != g_state.pending_events.end();) {
|
||||
if (it->fire_at <= now) {
|
||||
ready.push_back(std::move(*it));
|
||||
it = g_state.pending_events.erase(it);
|
||||
} else {
|
||||
nearest = std::min(nearest, it->fire_at);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ready.empty()) {
|
||||
lock.unlock();
|
||||
for (const PendingEvent& ev : ready) {
|
||||
FireEvent(ev);
|
||||
}
|
||||
lock.lock();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nearest == std::chrono::steady_clock::time_point::max()) {
|
||||
g_state.queue_cv.wait(lock);
|
||||
} else {
|
||||
g_state.queue_cv.wait_until(lock, nearest);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void InitEventDispatcher() {
|
||||
if (g_state.dispatch_running.exchange(true)) {
|
||||
return;
|
||||
}
|
||||
const s32 rc = NpCommon::sceNpCreateThread(
|
||||
&g_state.dispatch_thread, EventDispatcherThreadMain, nullptr,
|
||||
Libraries::Kernel::ORBIS_KERNEL_PRIO_FIFO_DEFAULT,
|
||||
ORBIS_NP_MATCHING2_THREAD_STACK_SIZE_DEFAULT, 0, "SceNpMatching2Ex");
|
||||
if (rc < 0) {
|
||||
LOG_ERROR(Lib_NpMatching2, "failed to create event dispatcher thread: {:#x}", rc);
|
||||
g_state.dispatch_running.store(false);
|
||||
g_state.dispatch_thread = nullptr;
|
||||
return;
|
||||
}
|
||||
LOG_INFO(Lib_NpMatching2, "event dispatcher thread created");
|
||||
}
|
||||
|
||||
void TermEventDispatcher() {
|
||||
if (!g_state.dispatch_running.exchange(false)) {
|
||||
return;
|
||||
}
|
||||
g_state.queue_cv.notify_all();
|
||||
if (g_state.dispatch_thread) {
|
||||
NpCommon::sceNpJoinThread(g_state.dispatch_thread, nullptr);
|
||||
g_state.dispatch_thread = nullptr;
|
||||
}
|
||||
std::lock_guard lock(g_state.queue_mutex);
|
||||
g_state.pending_events.clear();
|
||||
}
|
||||
|
||||
void ScheduleEvent(PendingEvent ev) {
|
||||
{
|
||||
std::lock_guard lock(g_state.queue_mutex);
|
||||
g_state.pending_events.push_back(std::move(ev));
|
||||
}
|
||||
g_state.queue_cv.notify_all();
|
||||
}
|
||||
|
||||
} // namespace Libraries::Np::NpMatching2
|
||||
167
src/core/libraries/np/np_matching2/np_matching2_internal.h
Normal file
167
src/core/libraries/np/np_matching2/np_matching2_internal.h
Normal file
@ -0,0 +1,167 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "common/types.h"
|
||||
#include "core/libraries/kernel/threads.h"
|
||||
#include "core/libraries/np/np_matching2/np_matching2.h"
|
||||
#include "core/libraries/np/np_matching2/np_matching2_types.h"
|
||||
#include "core/libraries/np/np_types.h"
|
||||
|
||||
namespace Libraries::Np::NpMatching2 {
|
||||
|
||||
struct PeerInfo {
|
||||
u32 addr = 0;
|
||||
u16 port = 0;
|
||||
OrbisNpMatching2RoomMemberId member_id = 0;
|
||||
s32 conn_id = 0;
|
||||
s32 status = 0;
|
||||
std::string online_id;
|
||||
};
|
||||
|
||||
struct ContextObject {
|
||||
OrbisNpMatching2ContextId ctx_id = 0;
|
||||
bool started = false;
|
||||
|
||||
OrbisNpMatching2ServerId server_id = 1;
|
||||
OrbisNpServiceLabel service_label = 0;
|
||||
Libraries::Np::OrbisNpId owner_np_id{};
|
||||
std::string online_id;
|
||||
|
||||
std::string signaling_addr;
|
||||
u16 signaling_port = 0;
|
||||
|
||||
u64 handler_registration_generation = 1;
|
||||
|
||||
OrbisNpMatching2WorldId world_id = 0;
|
||||
OrbisNpMatching2LobbyId lobby_id = 0;
|
||||
OrbisNpMatching2RoomId room_id = 0;
|
||||
OrbisNpMatching2RoomMemberId my_member_id = 0;
|
||||
bool is_room_owner = false;
|
||||
u32 max_slot = 5;
|
||||
OrbisNpMatching2Flags flag_attr = 0;
|
||||
|
||||
std::map<OrbisNpMatching2RoomMemberId, PeerInfo> peers;
|
||||
|
||||
OrbisNpMatching2ContextCallback context_callback = nullptr;
|
||||
void* context_callback_arg = nullptr;
|
||||
OrbisNpMatching2RequestCallback default_request_callback = nullptr;
|
||||
void* default_request_callback_arg = nullptr;
|
||||
OrbisNpMatching2RequestCallback per_request_callback = nullptr;
|
||||
void* per_request_callback_arg = nullptr;
|
||||
OrbisNpMatching2RoomEventCallback room_event_callback = nullptr;
|
||||
void* room_event_callback_arg = nullptr;
|
||||
OrbisNpMatching2RoomMessageCallback room_message_callback = nullptr;
|
||||
void* room_message_callback_arg = nullptr;
|
||||
OrbisNpMatching2LobbyEventCallback lobby_event_callback = nullptr;
|
||||
void* lobby_event_callback_arg = nullptr;
|
||||
OrbisNpMatching2LobbyMessageCallback lobby_message_callback = nullptr;
|
||||
void* lobby_message_callback_arg = nullptr;
|
||||
OrbisNpMatching2SignalingCallback signaling_callback = nullptr;
|
||||
void* signaling_callback_arg = nullptr;
|
||||
};
|
||||
|
||||
class ContextManager {
|
||||
public:
|
||||
static constexpr u32 kMaxContexts = 255;
|
||||
|
||||
static ContextManager& Instance();
|
||||
|
||||
s32 CreateContext(const OrbisNpId* owner_np_id, OrbisNpServiceLabel service_label,
|
||||
OrbisNpMatching2ContextId* out_ctx_id);
|
||||
|
||||
bool Check(OrbisNpMatching2ContextId ctx_id);
|
||||
ContextObject* Get(OrbisNpMatching2ContextId ctx_id);
|
||||
bool Destroy(OrbisNpMatching2ContextId ctx_id);
|
||||
|
||||
s32 Start(OrbisNpMatching2ContextId ctx_id);
|
||||
s32 Stop(OrbisNpMatching2ContextId ctx_id);
|
||||
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
ContextManager() = default;
|
||||
ContextObject* GetLocked(OrbisNpMatching2ContextId ctx_id);
|
||||
|
||||
std::mutex m_mutex;
|
||||
std::array<ContextObject, kMaxContexts + 1> m_contexts{};
|
||||
std::array<bool, kMaxContexts + 1> m_used{};
|
||||
OrbisNpMatching2ContextId m_next_id = 1;
|
||||
};
|
||||
|
||||
struct PendingEvent {
|
||||
enum Type {
|
||||
CONTEXT_CB,
|
||||
REQUEST_CB,
|
||||
SIGNALING_CB,
|
||||
ROOM_EVENT_CB,
|
||||
LOBBY_EVENT_CB,
|
||||
LOBBY_MESSAGE_CB,
|
||||
ROOM_MESSAGE_CB,
|
||||
};
|
||||
Type type = CONTEXT_CB;
|
||||
OrbisNpMatching2ContextId ctx_id = 0;
|
||||
std::chrono::steady_clock::time_point fire_at;
|
||||
|
||||
OrbisNpMatching2Event ctx_event{};
|
||||
OrbisNpMatching2EventCause ctx_event_cause{};
|
||||
s32 error_code = 0;
|
||||
|
||||
OrbisNpMatching2RequestId req_id = 0;
|
||||
OrbisNpMatching2Event req_event{};
|
||||
OrbisNpMatching2RequestCallback request_cb = nullptr;
|
||||
void* request_cb_arg = nullptr;
|
||||
void* request_data = nullptr;
|
||||
|
||||
OrbisNpMatching2RoomId room_id = 0;
|
||||
OrbisNpMatching2RoomMemberId member_id = 0;
|
||||
OrbisNpMatching2Event sig_event{};
|
||||
u32 conn_id = 0;
|
||||
|
||||
OrbisNpMatching2Event room_event{};
|
||||
void* room_event_data = nullptr;
|
||||
|
||||
OrbisNpMatching2LobbyId lobby_id = 0;
|
||||
OrbisNpMatching2Event lobby_event{};
|
||||
void* lobby_event_data = nullptr;
|
||||
|
||||
OrbisNpMatching2RoomMemberId src_member_id = 0;
|
||||
OrbisNpMatching2Event msg_event{};
|
||||
void* message_data = nullptr;
|
||||
};
|
||||
|
||||
struct NpMatching2State {
|
||||
std::atomic<bool> initialized = false;
|
||||
|
||||
OrbisNpMatching2RequestId next_request_id = 1;
|
||||
std::mutex mutex;
|
||||
|
||||
Kernel::PthreadT dispatch_thread = nullptr;
|
||||
std::mutex queue_mutex;
|
||||
std::condition_variable queue_cv;
|
||||
std::vector<PendingEvent> pending_events;
|
||||
std::atomic<bool> dispatch_running{false};
|
||||
};
|
||||
|
||||
extern NpMatching2State g_state;
|
||||
|
||||
OrbisNpMatching2RequestId AllocRequestId();
|
||||
|
||||
void InitEventDispatcher();
|
||||
void TermEventDispatcher();
|
||||
|
||||
void ScheduleEvent(PendingEvent ev);
|
||||
|
||||
PS4_SYSV_ABI void* EventDispatcherThreadMain(void* arg);
|
||||
|
||||
} // namespace Libraries::Np::NpMatching2
|
||||
@ -11,6 +11,11 @@
|
||||
|
||||
namespace Libraries::Np::NpMatching2 {
|
||||
|
||||
struct OrbisNpMatching2RoomGroup;
|
||||
struct OrbisNpMatching2RoomGroupInfo;
|
||||
struct OrbisNpMatching2RoomBinAttrInternal;
|
||||
struct OrbisNpMatching2RoomMemberBinAttrInternal;
|
||||
|
||||
using OrbisNpMatching2ContextCallback = PS4_SYSV_ABI void (*)(OrbisNpMatching2ContextId contextId,
|
||||
OrbisNpMatching2Event event,
|
||||
OrbisNpMatching2EventCause cause,
|
||||
@ -18,7 +23,12 @@ using OrbisNpMatching2ContextCallback = PS4_SYSV_ABI void (*)(OrbisNpMatching2Co
|
||||
|
||||
using OrbisNpMatching2LobbyEventCallback =
|
||||
PS4_SYSV_ABI void (*)(OrbisNpMatching2ContextId contextId, OrbisNpMatching2LobbyId lobbyId,
|
||||
OrbisNpMatching2Event event, void* data, void* userdata);
|
||||
OrbisNpMatching2Event event, const void* data, void* userdata);
|
||||
|
||||
using OrbisNpMatching2LobbyMessageCallback =
|
||||
PS4_SYSV_ABI void (*)(OrbisNpMatching2ContextId contextId, OrbisNpMatching2LobbyId lobbyId,
|
||||
OrbisNpMatching2LobbyMemberId srcMemberId, OrbisNpMatching2Event event,
|
||||
const void* data, void* userdata);
|
||||
|
||||
using OrbisNpMatching2RequestCallback = PS4_SYSV_ABI void (*)(OrbisNpMatching2ContextId,
|
||||
OrbisNpMatching2RequestId,
|
||||
@ -100,6 +110,36 @@ struct OrbisNpMatching2SignalingOptParam {
|
||||
u8 padding[4];
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2CreateJoinRoomRequest {
|
||||
u16 maxSlot;
|
||||
OrbisNpMatching2TeamId teamId;
|
||||
u8 pad[5];
|
||||
OrbisNpMatching2Flags flags;
|
||||
OrbisNpMatching2WorldId worldId;
|
||||
OrbisNpMatching2LobbyId lobbyId;
|
||||
void* roomPasswd;
|
||||
OrbisNpMatching2RoomPasswordSlotMask* passwdSlotMask;
|
||||
void* groupConfig;
|
||||
u64 groupConfigs;
|
||||
void* joinGroupLabel;
|
||||
Libraries::Np::OrbisNpOnlineId* allowedUser;
|
||||
u64 allowedUsers;
|
||||
Libraries::Np::OrbisNpOnlineId* blockedUser;
|
||||
u64 blockedUsers;
|
||||
OrbisNpMatching2BinAttr* internalBinAttr;
|
||||
u64 internalBinAttrs;
|
||||
OrbisNpMatching2IntAttr* externalSearchIntAttr;
|
||||
u64 externalSearchIntAttrs;
|
||||
OrbisNpMatching2BinAttr* externalSearchBinAttr;
|
||||
u64 externalSearchBinAttrs;
|
||||
OrbisNpMatching2BinAttr* externalBinAttr;
|
||||
u64 externalBinAttrs;
|
||||
OrbisNpMatching2BinAttr* memberInternalBinAttr;
|
||||
u64 memberInternalBinAttrs;
|
||||
OrbisNpMatching2SignalingOptParam* signalingParam;
|
||||
};
|
||||
static_assert(sizeof(OrbisNpMatching2CreateJoinRoomRequest) == 184);
|
||||
|
||||
struct OrbisNpMatching2CreateJoinRoomRequestA {
|
||||
u16 maxSlot;
|
||||
OrbisNpMatching2TeamId teamId;
|
||||
@ -142,11 +182,11 @@ struct OrbisNpMatching2RoomDataInternal {
|
||||
OrbisNpMatching2RoomId roomId;
|
||||
OrbisNpMatching2RoomPasswordSlotMask passwdSlotMask;
|
||||
u64 joinedSlotMask;
|
||||
void* roomGroup;
|
||||
OrbisNpMatching2RoomGroup* roomGroup;
|
||||
u64 roomGroups;
|
||||
OrbisNpMatching2Flags flags;
|
||||
u8 pad[4];
|
||||
void* internalBinAttr;
|
||||
OrbisNpMatching2RoomBinAttrInternal* internalBinAttr;
|
||||
u64 internalBinAttrs;
|
||||
};
|
||||
|
||||
@ -160,8 +200,8 @@ struct OrbisNpMatching2RoomMemberDataInternalA {
|
||||
OrbisNpMatching2TeamId teamId;
|
||||
OrbisNpMatching2NatType natType;
|
||||
OrbisNpMatching2Flags flags;
|
||||
void* roomGroup;
|
||||
void* roomMemberInternalBinAttr;
|
||||
OrbisNpMatching2RoomGroup* roomGroup;
|
||||
OrbisNpMatching2RoomMemberBinAttrInternal* roomMemberInternalBinAttr;
|
||||
u64 roomMemberInternalBinAttrs;
|
||||
};
|
||||
|
||||
@ -197,6 +237,14 @@ struct OrbisNpMatching2GetWorldInfoListResponse {
|
||||
u64 worldNum;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2GroupLabel {
|
||||
u8 data[8];
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2SessionPassword {
|
||||
u8 data[8];
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2InitializeParameter {
|
||||
u64 poolSize;
|
||||
u64 unknown;
|
||||
@ -213,11 +261,48 @@ struct OrbisNpMatching2PresenceOptionData {
|
||||
u64 len;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2JoinRoomRequest {
|
||||
OrbisNpMatching2RoomId roomId;
|
||||
OrbisNpMatching2SessionPassword* roomPasswd;
|
||||
OrbisNpMatching2GroupLabel* joinGroupLabel;
|
||||
OrbisNpMatching2BinAttr* roomMemberBinInternalAttr;
|
||||
u64 roomMemberBinInternalAttrNum;
|
||||
OrbisNpMatching2PresenceOptionData optData;
|
||||
OrbisNpMatching2TeamId teamId;
|
||||
u8 pad[3];
|
||||
OrbisNpMatching2Flags flags;
|
||||
Libraries::Np::OrbisNpOnlineId* blockedUser;
|
||||
u64 blockedUsers;
|
||||
|
||||
int Validate() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(OrbisNpMatching2JoinRoomRequest) == 0x58);
|
||||
|
||||
struct OrbisNpMatching2KickoutRoomMemberRequest {
|
||||
OrbisNpMatching2RoomId roomId;
|
||||
OrbisNpMatching2RoomMemberId memberId;
|
||||
u8 pad0[6];
|
||||
u32 blockKickFlag;
|
||||
u8 pad1[12];
|
||||
u64 reserved;
|
||||
|
||||
int Validate() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(OrbisNpMatching2KickoutRoomMemberRequest) == 0x28);
|
||||
|
||||
struct OrbisNpMatching2LeaveRoomRequest {
|
||||
OrbisNpMatching2RoomId roomId;
|
||||
OrbisNpMatching2PresenceOptionData optData;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2LeaveRoomResponse {
|
||||
OrbisNpMatching2RoomId roomId;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2Range {
|
||||
u32 start;
|
||||
u32 total;
|
||||
@ -256,7 +341,99 @@ struct OrbisNpMatching2RoomDataExternalA {
|
||||
u16 openPrivateSlots;
|
||||
Libraries::Np::OrbisNpPeerAddressA owner;
|
||||
Libraries::Np::OrbisNpOnlineId ownerOnlineId;
|
||||
void* roomGroup;
|
||||
OrbisNpMatching2RoomGroupInfo* roomGroup;
|
||||
u64 roomGroups;
|
||||
OrbisNpMatching2IntAttr* externalSearchIntAttr;
|
||||
u64 externalSearchIntAttrs;
|
||||
OrbisNpMatching2BinAttr* externalSearchBinAttr;
|
||||
u64 externalSearchBinAttrs;
|
||||
OrbisNpMatching2BinAttr* externalBinAttr;
|
||||
u64 externalBinAttrs;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2RoomGroup {
|
||||
OrbisNpMatching2RoomGroupId id;
|
||||
bool hasPasswd;
|
||||
bool hasLabel;
|
||||
u8 pad;
|
||||
OrbisNpMatching2GroupLabel label;
|
||||
u32 slots;
|
||||
u32 groupMembers;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2RoomGroupConfig {
|
||||
u32 slots;
|
||||
bool hasLabel;
|
||||
OrbisNpMatching2GroupLabel label;
|
||||
bool hasPassword;
|
||||
u8 pad[2];
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2RoomGroupInfo {
|
||||
OrbisNpMatching2RoomGroupId id;
|
||||
bool hasPasswd;
|
||||
u8 pad[2];
|
||||
u32 slots;
|
||||
u32 groupMembers;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2RoomBinAttrInternal {
|
||||
Libraries::Rtc::OrbisRtcTick lastUpdate;
|
||||
OrbisNpMatching2RoomMemberId memberId;
|
||||
u8 pad[6];
|
||||
OrbisNpMatching2BinAttr binAttr;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2RoomMemberBinAttrInternal {
|
||||
Libraries::Rtc::OrbisRtcTick lastUpdate;
|
||||
OrbisNpMatching2BinAttr binAttr;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2RoomMemberDataInternal {
|
||||
OrbisNpMatching2RoomMemberDataInternal* next;
|
||||
u64 joinDate;
|
||||
Libraries::Np::OrbisNpId npId;
|
||||
u8 pad[4];
|
||||
OrbisNpMatching2RoomMemberId memberId;
|
||||
OrbisNpMatching2TeamId teamId;
|
||||
OrbisNpMatching2NatType natType;
|
||||
OrbisNpMatching2Flags flagAttr;
|
||||
OrbisNpMatching2RoomGroup* roomGroup;
|
||||
OrbisNpMatching2RoomMemberBinAttrInternal* roomMemberBinAttrInternal;
|
||||
u64 roomMemberBinAttrInternalNum;
|
||||
};
|
||||
static_assert(sizeof(OrbisNpMatching2RoomMemberDataInternal) == 0x58);
|
||||
|
||||
struct OrbisNpMatching2RoomMemberDataInternalList {
|
||||
OrbisNpMatching2RoomMemberDataInternal* members;
|
||||
u64 membersNum;
|
||||
OrbisNpMatching2RoomMemberDataInternal* me;
|
||||
OrbisNpMatching2RoomMemberDataInternal* owner;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2CreateJoinRoomResponse {
|
||||
const OrbisNpMatching2RoomDataInternal* roomData;
|
||||
OrbisNpMatching2RoomMemberDataInternalList members;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2RoomDataExternal {
|
||||
OrbisNpMatching2RoomDataExternal* next;
|
||||
u16 maxSlot;
|
||||
u16 curMembers;
|
||||
OrbisNpMatching2Flags flags;
|
||||
OrbisNpMatching2ServerId serverId;
|
||||
u8 pad[2];
|
||||
OrbisNpMatching2WorldId worldId;
|
||||
OrbisNpMatching2LobbyId lobbyId;
|
||||
OrbisNpMatching2RoomId roomId;
|
||||
u64 passwdSlotMask;
|
||||
u64 joinedSlotMask;
|
||||
u16 publicSlots;
|
||||
u16 privateSlots;
|
||||
u16 openPublicSlots;
|
||||
u16 openPrivateSlots;
|
||||
Libraries::Np::OrbisNpId* ownerNpId;
|
||||
OrbisNpMatching2RoomGroupInfo* roomGroup;
|
||||
u64 roomGroups;
|
||||
OrbisNpMatching2IntAttr* externalSearchIntAttr;
|
||||
u64 externalSearchIntAttrs;
|
||||
@ -281,11 +458,43 @@ struct OrbisNpMatching2SearchRoomRequest {
|
||||
u64 attrs;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2SearchRoomResponse {
|
||||
OrbisNpMatching2Range range;
|
||||
OrbisNpMatching2RoomDataExternal* roomDataExt;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2SearchRoomResponseA {
|
||||
OrbisNpMatching2Range range;
|
||||
OrbisNpMatching2RoomDataExternalA* roomDataExt;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2SetRoomDataExternalRequest {
|
||||
OrbisNpMatching2RoomId roomId;
|
||||
OrbisNpMatching2IntAttr* roomSearchableIntAttrExternal;
|
||||
u32 roomSearchableIntAttrExternalNum;
|
||||
u8 pad1[4];
|
||||
OrbisNpMatching2BinAttr* roomSearchableBinAttrExternal;
|
||||
u32 roomSearchableBinAttrExternalNum;
|
||||
u8 pad2[4];
|
||||
OrbisNpMatching2BinAttr* roomBinAttrExternal;
|
||||
u32 roomBinAttrExternalNum;
|
||||
u8 pad3[4];
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2SetRoomDataInternalRequest {
|
||||
OrbisNpMatching2RoomId roomId;
|
||||
OrbisNpMatching2Flags flagFilter;
|
||||
OrbisNpMatching2Flags flagAttr;
|
||||
OrbisNpMatching2BinAttr* roomBinAttrInternal;
|
||||
u32 roomBinAttrInternalNum;
|
||||
OrbisNpMatching2RoomGroupConfig* passwordConfig;
|
||||
u32 passwordConfigNum;
|
||||
u64* passwordSlotMask;
|
||||
OrbisNpMatching2RoomMemberId* ownerPrivilegeRank;
|
||||
u32 ownerPrivilegeRankNum;
|
||||
u8 padding[4];
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2SetUserInfoRequest {
|
||||
OrbisNpMatching2ServerId serverId;
|
||||
u8 padding[6];
|
||||
@ -293,6 +502,16 @@ struct OrbisNpMatching2SetUserInfoRequest {
|
||||
u64 userBinAttrs;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2SignalingConnectionInfoAddr {
|
||||
u32 addr;
|
||||
u16 port;
|
||||
u8 pad[2];
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2SignalingConnectionInfo {
|
||||
OrbisNpMatching2SignalingConnectionInfoAddr address;
|
||||
};
|
||||
|
||||
// internal - to be removed.
|
||||
struct OrbisNpMatching2SignalingEvent {
|
||||
OrbisNpMatching2ContextId contextId;
|
||||
@ -302,4 +521,29 @@ struct OrbisNpMatching2SignalingEvent {
|
||||
int errorCode;
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2SignalingGetPingInfoRequest {
|
||||
OrbisNpMatching2RoomId roomId;
|
||||
u8 pad[16];
|
||||
|
||||
int Validate() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2SignalingGetPingInfoResponse {
|
||||
OrbisNpMatching2ServerId serverId;
|
||||
u8 pad[2];
|
||||
OrbisNpMatching2WorldId worldId;
|
||||
OrbisNpMatching2RoomId roomId;
|
||||
u32 pingUs;
|
||||
u8 reserved[20];
|
||||
};
|
||||
|
||||
struct OrbisNpMatching2SignalingParam {
|
||||
int type;
|
||||
int flag;
|
||||
OrbisNpMatching2RoomMemberId mainMember;
|
||||
u8 pad[4];
|
||||
};
|
||||
|
||||
} // namespace Libraries::Np::NpMatching2
|
||||
|
||||
@ -178,3 +178,278 @@ message GetScoreResponse {
|
||||
uint64 lastSortDate = 4;
|
||||
uint32 totalRecord = 5;
|
||||
}
|
||||
|
||||
// ── Matching ──────────────────────────────────────────────────────────────────
|
||||
|
||||
// Shared attribute types
|
||||
|
||||
message MatchingBinAttr {
|
||||
uint32 attr_id = 1;
|
||||
bytes data = 2;
|
||||
}
|
||||
|
||||
message MatchingIntAttr {
|
||||
uint32 attr_id = 1;
|
||||
uint32 attr_value = 2;
|
||||
}
|
||||
|
||||
message MatchingRoomGroup {
|
||||
uint32 group_id = 1;
|
||||
bool has_passwd = 2;
|
||||
bool has_label = 3;
|
||||
bytes label = 4;
|
||||
uint32 slot_count = 5;
|
||||
uint32 num_members = 6;
|
||||
}
|
||||
|
||||
message MatchingCallbackEntry {
|
||||
bool enabled = 1;
|
||||
uint64 callback_addr = 2;
|
||||
uint64 callback_arg = 3;
|
||||
}
|
||||
|
||||
// Room data structures
|
||||
|
||||
message MatchingRoomDataInternal {
|
||||
uint32 public_slots = 1;
|
||||
uint32 private_slots = 2;
|
||||
uint32 open_public_slots = 3;
|
||||
uint32 open_private_slots = 4;
|
||||
uint32 max_slot = 5;
|
||||
uint32 server_id = 6;
|
||||
uint32 world_id = 7;
|
||||
uint32 lobby_id = 8;
|
||||
uint64 room_id = 9;
|
||||
uint64 passwd_slot_mask = 10;
|
||||
uint32 joined_slot_mask = 11;
|
||||
repeated MatchingRoomGroup groups = 12;
|
||||
uint32 flags = 13;
|
||||
repeated MatchingBinAttr bin_attrs_internal = 14;
|
||||
}
|
||||
|
||||
message MatchingRoomMemberData {
|
||||
string npid = 1;
|
||||
uint32 member_id = 2;
|
||||
uint32 team_id = 3;
|
||||
bool is_owner = 4;
|
||||
MatchingRoomGroup group = 5;
|
||||
repeated MatchingBinAttr bin_attrs_internal = 6;
|
||||
}
|
||||
|
||||
message MatchingRoomDataExternal {
|
||||
uint32 max_slot = 1;
|
||||
uint32 cur_members = 2;
|
||||
uint32 flags = 3;
|
||||
uint32 server_id = 4;
|
||||
uint32 world_id = 5;
|
||||
uint64 lobby_id = 6;
|
||||
uint64 room_id = 7;
|
||||
uint64 passwd_slot_mask = 8;
|
||||
uint64 joined_slot_mask = 9;
|
||||
uint32 public_slots = 10;
|
||||
uint32 private_slots = 11;
|
||||
uint32 open_public_slots = 12;
|
||||
uint32 open_private_slots = 13;
|
||||
repeated MatchingRoomGroup groups = 14;
|
||||
repeated MatchingIntAttr external_search_int_attrs = 15;
|
||||
repeated MatchingBinAttr external_search_bin_attrs = 16;
|
||||
repeated MatchingBinAttr external_bin_attrs = 17;
|
||||
string owner_npid = 18;
|
||||
}
|
||||
|
||||
message CreateJoinRoomResponse {
|
||||
MatchingRoomDataInternal room_data = 1;
|
||||
repeated MatchingRoomMemberData members = 2;
|
||||
uint32 me_member_id = 3;
|
||||
uint32 owner_member_id = 4;
|
||||
}
|
||||
|
||||
// Command requests
|
||||
|
||||
message RegisterHandlersRequest {
|
||||
string addr = 1;
|
||||
uint32 port = 2;
|
||||
uint32 ctx_id = 3;
|
||||
uint32 service_label = 4;
|
||||
repeated MatchingCallbackEntry callbacks = 5;
|
||||
}
|
||||
|
||||
message CreateRoomRequest {
|
||||
uint32 req_id = 1;
|
||||
uint32 max_slots = 2;
|
||||
uint32 team_id = 3;
|
||||
uint32 world_id = 4;
|
||||
uint32 lobby_id = 5;
|
||||
uint32 flags = 6;
|
||||
uint32 group_config_count = 7;
|
||||
uint32 allowed_user_count = 8;
|
||||
uint32 blocked_user_count = 9;
|
||||
uint32 internal_bin_attr_count = 10;
|
||||
repeated MatchingIntAttr external_search_int_attrs = 11;
|
||||
repeated MatchingBinAttr external_search_bin_attrs = 12;
|
||||
repeated MatchingBinAttr external_bin_attrs = 13;
|
||||
repeated MatchingBinAttr member_bin_attrs = 14;
|
||||
bool join_group_label_present = 15;
|
||||
bool room_password_present = 16;
|
||||
uint32 sig_type = 17;
|
||||
uint32 sig_flag = 18;
|
||||
uint32 sig_main_member = 19;
|
||||
}
|
||||
|
||||
message JoinRoomRequest {
|
||||
uint64 room_id = 1;
|
||||
uint32 req_id = 2;
|
||||
uint32 team_id = 3;
|
||||
uint32 join_flags = 4;
|
||||
uint32 blocked_user_count = 5;
|
||||
repeated MatchingBinAttr member_bin_attrs = 6;
|
||||
bool room_password_present = 7;
|
||||
bool join_group_label_present = 8;
|
||||
}
|
||||
|
||||
message LeaveRoomRequest {
|
||||
uint64 room_id = 1;
|
||||
uint32 req_id = 2;
|
||||
}
|
||||
|
||||
message RequestSignalingInfosRequest {
|
||||
string target_npid = 1;
|
||||
}
|
||||
|
||||
message SetRoomDataInternalRequest {
|
||||
uint32 req_id = 1;
|
||||
uint64 room_id = 2;
|
||||
uint32 flag_filter = 3;
|
||||
uint32 flag_attr = 4;
|
||||
repeated MatchingBinAttr bin_attrs = 5;
|
||||
bool has_passwd_mask = 6;
|
||||
uint64 passwd_slot_mask = 7;
|
||||
}
|
||||
|
||||
message SetRoomDataExternalRequest {
|
||||
uint32 req_id = 1;
|
||||
uint64 room_id = 2;
|
||||
repeated MatchingIntAttr search_int_attrs = 3;
|
||||
repeated MatchingBinAttr search_bin_attrs = 4;
|
||||
repeated MatchingBinAttr ext_bin_attrs = 5;
|
||||
}
|
||||
|
||||
message KickoutRoomMemberRequest {
|
||||
uint64 room_id = 1;
|
||||
uint32 req_id = 2;
|
||||
uint32 target_member_id = 3;
|
||||
uint32 block_kick_flag = 4;
|
||||
}
|
||||
|
||||
// Command replies
|
||||
|
||||
message CreateRoomReply {
|
||||
uint64 room_id = 1;
|
||||
uint32 server_id = 2;
|
||||
uint32 world_id = 3;
|
||||
uint32 lobby_id = 4;
|
||||
uint32 member_id = 5;
|
||||
uint32 max_slots = 6;
|
||||
uint32 flags = 7;
|
||||
uint32 cur_members = 8;
|
||||
CreateJoinRoomResponse details = 9;
|
||||
}
|
||||
|
||||
message JoinRoomReply {
|
||||
uint64 room_id = 1;
|
||||
uint32 member_id = 2;
|
||||
uint32 max_slots = 3;
|
||||
uint32 flags = 4;
|
||||
uint32 cur_members = 5;
|
||||
CreateJoinRoomResponse details = 6;
|
||||
}
|
||||
|
||||
message GetRoomListReply {
|
||||
repeated MatchingRoomDataExternal rooms = 1;
|
||||
}
|
||||
|
||||
message RequestSignalingInfosReply {
|
||||
string target_npid = 1;
|
||||
string target_ip = 2;
|
||||
uint32 target_port = 3;
|
||||
uint32 target_member_id = 4;
|
||||
}
|
||||
|
||||
message LeaveRoomReply { uint64 room_id = 1; }
|
||||
message SetRoomDataInternalReply { uint64 room_id = 1; }
|
||||
message SetRoomDataExternalReply { uint64 room_id = 1; }
|
||||
message KickoutRoomMemberReply { uint64 room_id = 1; }
|
||||
|
||||
// Notification payloads
|
||||
// Every notification carries ctx_id so the client can route it to the owning
|
||||
// context (the server tracks ctx_id per connection from RegisterHandlersRequest).
|
||||
|
||||
// NotificationType::RequestEvent (9)
|
||||
message NotifyRequestEvent {
|
||||
uint32 ctx_id = 1;
|
||||
uint32 server_id = 2;
|
||||
uint32 world_id = 3;
|
||||
uint32 lobby_id = 4;
|
||||
uint32 req_event = 5;
|
||||
uint32 req_id = 6;
|
||||
uint32 error_code = 7;
|
||||
uint64 room_id = 8;
|
||||
uint32 member_id = 9;
|
||||
uint32 max_slots = 10;
|
||||
uint32 flags = 11;
|
||||
bool is_owner = 12;
|
||||
bytes response_blob = 13;
|
||||
}
|
||||
|
||||
// NotificationType::MemberJoined (10)
|
||||
message NotifyMemberJoined {
|
||||
uint64 room_id = 1;
|
||||
uint32 member_id = 2;
|
||||
string npid = 3;
|
||||
string addr = 4;
|
||||
uint32 port = 5;
|
||||
repeated MatchingBinAttr bin_attrs = 6;
|
||||
uint32 ctx_id = 7;
|
||||
}
|
||||
|
||||
// NotificationType::MemberLeft (11)
|
||||
message NotifyMemberLeft {
|
||||
uint64 room_id = 1;
|
||||
uint32 member_id = 2;
|
||||
string npid = 3;
|
||||
uint32 ctx_id = 4;
|
||||
}
|
||||
|
||||
// NotificationType::SignalingHelper (12)
|
||||
message NotifySignalingHelper {
|
||||
string npid = 1;
|
||||
uint32 member_id = 2;
|
||||
string addr = 3;
|
||||
uint32 port = 4;
|
||||
uint32 ctx_id = 5;
|
||||
}
|
||||
|
||||
// NotificationType::SignalingEvent (13)
|
||||
message NotifySignalingEvent {
|
||||
uint32 event_type = 1;
|
||||
uint64 room_id = 2;
|
||||
uint32 member_id = 3;
|
||||
uint32 conn_id = 4;
|
||||
uint32 ctx_id = 5;
|
||||
}
|
||||
|
||||
// NotificationType::RoomDataInternalUpdated (15)
|
||||
message NotifyRoomDataInternalUpdated {
|
||||
uint64 room_id = 1;
|
||||
uint32 flags = 2;
|
||||
repeated MatchingBinAttr bin_attrs = 3;
|
||||
uint32 ctx_id = 4;
|
||||
}
|
||||
|
||||
// NotificationType::KickedOut (16)
|
||||
message NotifyKickedOut {
|
||||
uint64 room_id = 1;
|
||||
int32 status_code = 2;
|
||||
uint32 guard_value = 3;
|
||||
uint32 ctx_id = 4;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user