Implement old matching API

This commit is contained in:
RipleyTom 2024-05-14 00:12:50 +02:00 committed by Ani
parent cf65571be7
commit 3d9c8a670e
28 changed files with 3620 additions and 466 deletions

View file

@ -84,7 +84,7 @@ namespace rpcn
rpcn_log.notice("online: %s, pr_com_id: %s, pr_title: %s, pr_status: %s, pr_comment: %s, pr_data: %s", online ? "true" : "false", pr_com_id.data, pr_title, pr_status, pr_comment, fmt::buf_to_hexstring(pr_data.data(), pr_data.size()));
}
constexpr u32 RPCN_PROTOCOL_VERSION = 24;
constexpr u32 RPCN_PROTOCOL_VERSION = 25;
constexpr usz RPCN_HEADER_SIZE = 15;
bool is_error(ErrorType err)
@ -1305,7 +1305,7 @@ namespace rpcn
bool rpcn_client::get_server_list(u32 req_id, const SceNpCommunicationId& communication_id, std::vector<u16>& server_list)
{
std::vector<u8> data(COMMUNICATION_ID_SIZE), reply_data;
memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE);
rpcn_client::write_communication_id(communication_id, data);
if (!forge_send_reply(CommandType::GetServerList, req_id, data, reply_data))
{
@ -1368,7 +1368,7 @@ namespace rpcn
bool rpcn_client::get_world_list(u32 req_id, const SceNpCommunicationId& communication_id, u16 server_id)
{
std::vector<u8> data(COMMUNICATION_ID_SIZE + sizeof(u16));
memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE);
rpcn_client::write_communication_id(communication_id, data);
reinterpret_cast<le_t<u16>&>(data[COMMUNICATION_ID_SIZE]) = server_id;
return forge_send(CommandType::GetWorldList, req_id, data);
@ -1795,7 +1795,7 @@ namespace rpcn
{
std::vector<u8> data(COMMUNICATION_ID_SIZE + sizeof(u64));
memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE);
rpcn_client::write_communication_id(communication_id, data);
write_to_ptr<le_t<u64>>(data, COMMUNICATION_ID_SIZE, room_id);
return forge_send(CommandType::PingRoomOwner, req_id, data);
@ -1889,7 +1889,7 @@ namespace rpcn
bool rpcn_client::get_board_infos(u32 req_id, const SceNpCommunicationId& communication_id, SceNpScoreBoardId board_id)
{
std::vector<u8> data(COMMUNICATION_ID_SIZE + sizeof(u32));
memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE);
rpcn_client::write_communication_id(communication_id, data);
write_to_ptr<le_t<u32>>(data, COMMUNICATION_ID_SIZE, board_id);
return forge_send(CommandType::GetBoardInfos, req_id, data);
@ -1951,7 +1951,7 @@ namespace rpcn
const usz bufsize = builder.GetSize();
std::vector<u8> data(COMMUNICATION_ID_SIZE + sizeof(u32) + bufsize + sizeof(u32) + score_data.size());
memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE);
rpcn_client::write_communication_id(communication_id, data);
reinterpret_cast<le_t<u32>&>(data[COMMUNICATION_ID_SIZE]) = static_cast<u32>(bufsize);
memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize);
reinterpret_cast<le_t<u32>&>(data[COMMUNICATION_ID_SIZE + sizeof(u32) + bufsize]) = static_cast<u32>(score_data.size());
@ -2192,19 +2192,290 @@ namespace rpcn
return forge_request_with_com_id(builder, pr_com_id, CommandType::SetPresence, rpcn_request_counter.fetch_add(1));
}
bool rpcn_client::createjoin_room_gui(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatchingAttr* attr_list)
{
flatbuffers::FlatBufferBuilder builder(1024);
u32 total_slots = 0;
u32 private_slots = 0;
bool privilege_grant = false;
bool stealth = false;
std::vector<flatbuffers::Offset<MatchingAttr>> vec_attrs;
for (const SceNpMatchingAttr* cur_attr = attr_list; cur_attr != nullptr; cur_attr = cur_attr->next ? cur_attr->next.get_ptr() : nullptr)
{
switch (cur_attr->type)
{
case SCE_NP_MATCHING_ATTR_TYPE_BASIC_NUM:
{
switch (cur_attr->id)
{
case SCE_NP_MATCHING_ROOM_ATTR_ID_TOTAL_SLOT:
total_slots = cur_attr->value.num;
break;
case SCE_NP_MATCHING_ROOM_ATTR_ID_PRIVATE_SLOT:
private_slots = cur_attr->value.num;
break;
case SCE_NP_MATCHING_ROOM_ATTR_ID_PRIVILEGE_TYPE:
ensure(cur_attr->value.num == SCE_NP_MATCHING_ROOM_PRIVILEGE_TYPE_NO_AUTO_GRANT || cur_attr->value.num == SCE_NP_MATCHING_ROOM_PRIVILEGE_TYPE_AUTO_GRANT, "Invalid SCE_NP_MATCHING_ROOM_ATTR_ID_PRIVILEGE_TYPE value");
privilege_grant = (cur_attr->value.num == SCE_NP_MATCHING_ROOM_PRIVILEGE_TYPE_AUTO_GRANT);
break;
case SCE_NP_MATCHING_ROOM_ATTR_ID_ROOM_SEARCH_FLAG:
ensure(cur_attr->value.num == SCE_NP_MATCHING_ROOM_SEARCH_FLAG_OPEN || cur_attr->value.num == SCE_NP_MATCHING_ROOM_SEARCH_FLAG_STEALTH, "Invalid SCE_NP_MATCHING_ROOM_ATTR_ID_ROOM_SEARCH_FLAG value");
stealth = (cur_attr->value.num == SCE_NP_MATCHING_ROOM_SEARCH_FLAG_STEALTH);
break;
default:
fmt::throw_exception("Invalid basic num attribute id");
break;
}
break;
}
case SCE_NP_MATCHING_ATTR_TYPE_GAME_BIN:
{
ensure(cur_attr->id >= 1u && cur_attr->id <= 16u, "Invalid game bin attribute id");
ensure(cur_attr->value.data.size <= 64u || ((cur_attr->id == 1u || cur_attr->id == 2u) && cur_attr->value.data.size <= 256u), "Invalid game bin size");
const std::vector<u8> vec_data(static_cast<const u8*>(cur_attr->value.data.ptr.get_ptr()), static_cast<const u8*>(cur_attr->value.data.ptr.get_ptr()) + cur_attr->value.data.size);
auto attr = CreateMatchingAttrDirect(builder, cur_attr->type, cur_attr->id, 0, &vec_data);
vec_attrs.push_back(attr);
break;
}
case SCE_NP_MATCHING_ATTR_TYPE_GAME_NUM:
{
ensure(cur_attr->id >= 1u && cur_attr->id <= 16u, "Invalid game num attribute id");
auto attr = CreateMatchingAttrDirect(builder, cur_attr->type, cur_attr->id, cur_attr->value.num, nullptr);
vec_attrs.push_back(attr);
break;
}
default:
fmt::throw_exception("Invalid attribute type");
}
}
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MatchingAttr>>> final_attrs_vec;
if (!vec_attrs.empty())
{
final_attrs_vec = builder.CreateVector(vec_attrs);
}
auto req_finished = CreateCreateRoomGUIRequest(builder, total_slots, private_slots, privilege_grant, stealth, final_attrs_vec);
builder.Finish(req_finished);
return forge_request_with_com_id(builder, communication_id, CommandType::CreateRoomGUI, req_id);
}
bool rpcn_client::join_room_gui(u32 req_id, const SceNpRoomId& room_id)
{
flatbuffers::FlatBufferBuilder builder(1024);
const std::vector<u8> vec_room_id(room_id.opt, room_id.opt + sizeof(room_id.opt));
auto req_finished = CreateMatchingGuiRoomIdDirect(builder, &vec_room_id);
builder.Finish(req_finished);
return forge_request_with_data(builder, CommandType::JoinRoomGUI, req_id);
}
bool rpcn_client::leave_room_gui(u32 req_id, const SceNpRoomId& room_id)
{
flatbuffers::FlatBufferBuilder builder(1024);
const std::vector<u8> vec_room_id(room_id.opt, room_id.opt + sizeof(room_id.opt));
auto req_finished = CreateMatchingGuiRoomIdDirect(builder, &vec_room_id);
builder.Finish(req_finished);
return forge_request_with_data(builder, CommandType::LeaveRoomGUI, req_id);
}
bool rpcn_client::get_room_list_gui(u32 req_id, const SceNpCommunicationId& communication_id, const SceNpMatchingReqRange* range, vm::ptr<SceNpMatchingSearchCondition> cond, vm::ptr<SceNpMatchingAttr> attr)
{
flatbuffers::FlatBufferBuilder builder(1024);
const s32 range_start = range->start;
const u32 range_max = range->max;
std::vector<flatbuffers::Offset<MatchingSearchCondition>> vec_conds;
std::vector<flatbuffers::Offset<MatchingAttr>> vec_attrs;
for (auto cur_cond = cond; cur_cond; cur_cond = cur_cond->next)
{
auto fb_cond = CreateMatchingSearchCondition(builder, cur_cond->target_attr_type, cur_cond->target_attr_id, cur_cond->comp_op, cur_cond->compared.value.num);
vec_conds.push_back(fb_cond);
}
for (auto cur_attr = attr; cur_attr; cur_attr = cur_attr->next)
{
auto fb_attr = CreateMatchingAttr(builder, cur_attr->type, cur_attr->id);
vec_attrs.push_back(fb_attr);
}
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MatchingSearchCondition>>> final_conds_vec;
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MatchingAttr>>> final_attrs_vec;
if (!vec_conds.empty())
{
final_conds_vec = builder.CreateVector(vec_conds);
}
if (!vec_attrs.empty())
{
final_attrs_vec = builder.CreateVector(vec_attrs);
}
auto req_finished = CreateGetRoomListGUIRequest(builder, range_start, range_max, final_conds_vec, final_attrs_vec);
builder.Finish(req_finished);
return forge_request_with_com_id(builder, communication_id, CommandType::GetRoomListGUI, req_id);
}
bool rpcn_client::set_room_search_flag_gui(u32 req_id, const SceNpRoomId& room_id, bool stealth)
{
flatbuffers::FlatBufferBuilder builder(1024);
const std::vector<u8> vec_room_id(room_id.opt, room_id.opt + sizeof(room_id.opt));
auto req_finished = CreateSetRoomSearchFlagGUIDirect(builder, &vec_room_id, stealth);
builder.Finish(req_finished);
return forge_request_with_data(builder, CommandType::SetRoomSearchFlagGUI, req_id);
}
bool rpcn_client::get_room_search_flag_gui(u32 req_id, const SceNpRoomId& room_id)
{
flatbuffers::FlatBufferBuilder builder(1024);
const std::vector<u8> vec_room_id(room_id.opt, room_id.opt + sizeof(room_id.opt));
auto req_finished = CreateMatchingGuiRoomIdDirect(builder, &vec_room_id);
builder.Finish(req_finished);
return forge_request_with_data(builder, CommandType::GetRoomSearchFlagGUI, req_id);
}
bool rpcn_client::set_room_info_gui(u32 req_id, const SceNpRoomId& room_id, vm::ptr<SceNpMatchingAttr> attrs)
{
flatbuffers::FlatBufferBuilder builder(1024);
const std::vector<u8> vec_room_id(room_id.opt, room_id.opt + sizeof(room_id.opt));
std::vector<flatbuffers::Offset<MatchingAttr>> vec_attrs;
for (auto cur_attr = attrs; cur_attr; cur_attr = cur_attr->next)
{
u32 num = 0;
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> fb_vec_data = 0;
switch (cur_attr->type)
{
case SCE_NP_MATCHING_ATTR_TYPE_GAME_BIN:
{
const std::vector<u8> vec_data(static_cast<const u8*>(cur_attr->value.data.ptr.get_ptr()), static_cast<const u8*>(cur_attr->value.data.ptr.get_ptr()) + cur_attr->value.data.size);
fb_vec_data = builder.CreateVector(vec_data);
break;
}
case SCE_NP_MATCHING_ATTR_TYPE_GAME_NUM:
{
num = cur_attr->value.num;
break;
}
default:
{
fmt::throw_exception("Invalid attr type reached set_room_info_gui");
break;
}
}
auto fb_attr = CreateMatchingAttr(builder, cur_attr->type, cur_attr->id, num, fb_vec_data);
vec_attrs.push_back(fb_attr);
}
auto req_finished = CreateMatchingRoomDirect(builder, &vec_room_id, &vec_attrs);
builder.Finish(req_finished);
return forge_request_with_data(builder, CommandType::SetRoomInfoGUI, req_id);
}
bool rpcn_client::get_room_info_gui(u32 req_id, const SceNpRoomId& room_id, vm::ptr<SceNpMatchingAttr> attrs)
{
flatbuffers::FlatBufferBuilder builder(1024);
const std::vector<u8> vec_room_id(room_id.opt, room_id.opt + sizeof(room_id.opt));
std::vector<flatbuffers::Offset<MatchingAttr>> vec_attrs;
for (auto cur_attr = attrs; cur_attr; cur_attr = cur_attr->next)
{
auto fb_attr = CreateMatchingAttr(builder, cur_attr->type, cur_attr->id);
vec_attrs.push_back(fb_attr);
}
auto req_finished = CreateMatchingRoomDirect(builder, &vec_room_id, &vec_attrs);
builder.Finish(req_finished);
return forge_request_with_data(builder, CommandType::GetRoomInfoGUI, req_id);
}
bool rpcn_client::quickmatch_gui(u32 req_id, const SceNpCommunicationId& com_id, vm::cptr<SceNpMatchingSearchCondition> cond, s32 available_num)
{
flatbuffers::FlatBufferBuilder builder(1024);
std::vector<flatbuffers::Offset<MatchingSearchCondition>> vec_conds;
for (auto cur_cond = cond; cur_cond; cur_cond = cur_cond->next)
{
auto fb_cond = CreateMatchingSearchCondition(builder, cur_cond->target_attr_type, cur_cond->target_attr_id, cur_cond->comp_op, cur_cond->compared.value.num);
vec_conds.push_back(fb_cond);
}
auto req_finished = CreateQuickMatchGUIRequestDirect(builder, &vec_conds, available_num);
builder.Finish(req_finished);
return forge_request_with_com_id(builder, com_id, CommandType::QuickMatchGUI, req_id);
}
bool rpcn_client::searchjoin_gui(u32 req_id, const SceNpCommunicationId& com_id, vm::cptr<SceNpMatchingSearchCondition> cond, vm::cptr<SceNpMatchingAttr> attr)
{
flatbuffers::FlatBufferBuilder builder(1024);
std::vector<flatbuffers::Offset<MatchingSearchCondition>> vec_conds;
std::vector<flatbuffers::Offset<MatchingAttr>> vec_attrs;
for (auto cur_cond = cond; cur_cond; cur_cond = cur_cond->next)
{
auto fb_cond = CreateMatchingSearchCondition(builder, cur_cond->target_attr_type, cur_cond->target_attr_id, cur_cond->comp_op, cur_cond->compared.value.num);
vec_conds.push_back(fb_cond);
}
for (auto cur_attr = attr; cur_attr; cur_attr = cur_attr->next)
{
auto fb_attr = CreateMatchingAttr(builder, cur_attr->type, cur_attr->id);
vec_attrs.push_back(fb_attr);
}
auto req_finished = CreateSearchJoinRoomGUIRequestDirect(builder, vec_conds.empty() ? nullptr : &vec_conds, vec_attrs.empty() ? nullptr : &vec_attrs);
builder.Finish(req_finished);
return forge_request_with_com_id(builder, com_id, CommandType::SearchJoinRoomGUI, req_id);
}
void rpcn_client::write_communication_id(const SceNpCommunicationId& com_id, std::vector<u8>& data)
{
ensure(com_id.data[9] == 0 && com_id.num <= 99, "rpcn_client::write_communication_id: Invalid SceNpCommunicationId");
const std::string com_id_str = np::communication_id_to_string(com_id);
ensure(com_id_str.size() == 12, "rpcn_client::write_communication_id: Error formatting SceNpCommunicationId");
memcpy(data.data(), com_id_str.data(), COMMUNICATION_ID_SIZE);
}
bool rpcn_client::forge_request_with_com_id(const flatbuffers::FlatBufferBuilder& builder, const SceNpCommunicationId& com_id, CommandType command, u64 packet_id)
{
const u8* buf = builder.GetBufferPointer();
const usz bufsize = builder.GetSize();
std::vector<u8> data(COMMUNICATION_ID_SIZE + sizeof(u32) + bufsize);
memcpy(data.data(), com_id.data, COMMUNICATION_ID_SIZE);
rpcn_client::write_communication_id(com_id, data);
reinterpret_cast<le_t<u32>&>(data[COMMUNICATION_ID_SIZE]) = static_cast<u32>(bufsize);
memcpy(data.data() + COMMUNICATION_ID_SIZE + sizeof(u32), buf, bufsize);
return forge_send(command, packet_id, data);
}
bool rpcn_client::forge_request_with_data(const flatbuffers::FlatBufferBuilder& builder, CommandType command, u64 packet_id)
{
const u8* buf = builder.GetBufferPointer();
const usz bufsize = builder.GetSize();
std::vector<u8> data(sizeof(u32) + bufsize);
reinterpret_cast<le_t<u32>&>(data[0]) = static_cast<u32>(bufsize);
memcpy(data.data() + sizeof(u32), buf, bufsize);
return forge_send(command, packet_id, data);
}
std::vector<u8> rpcn_client::forge_request(u16 command, u64 packet_id, const std::vector<u8>& data) const
{
const usz packet_size = data.size() + RPCN_HEADER_SIZE;