mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-03-10 15:38:08 +01:00
NP code review
Some checks are pending
Generate Translation Template / Generate Translation Template (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (/rpcs3/.ci/build-linux-aarch64.sh, gcc, rpcs3/rpcs3-ci-jammy-aarch64:1.9, ubuntu-24.04-arm) (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (/rpcs3/.ci/build-linux.sh, gcc, rpcs3/rpcs3-ci-jammy:1.9, ubuntu-24.04) (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (a1d35836e8d45bfc6f63c26f0a3e5d46ef622fe1, rpcs3/rpcs3-binaries-linux-arm64, /rpcs3/.ci/build-linux-aarch64.sh, clang, rpcs3/rpcs3-ci-jammy-aarch64:1.9, ubuntu-24.04-arm) (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (d812f1254a1157c80fd402f94446310560f54e5f, rpcs3/rpcs3-binaries-linux, /rpcs3/.ci/build-linux.sh, clang, rpcs3/rpcs3-ci-jammy:1.9, ubuntu-24.04) (push) Waiting to run
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (0, 51ae32f468089a8169aaf1567de355ff4a3e0842, rpcs3/rpcs3-binaries-mac, Intel) (push) Waiting to run
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (1, 8e21bdbc40711a3fccd18fbf17b742348b0f4281, rpcs3/rpcs3-binaries-mac-arm64, Apple Silicon) (push) Waiting to run
Build RPCS3 / RPCS3 Windows (push) Waiting to run
Build RPCS3 / RPCS3 Windows Clang ${{ matrix.arch }} (aarch64, clang, clangarm64, ARM64, windows-11-arm) (push) Waiting to run
Build RPCS3 / RPCS3 Windows Clang ${{ matrix.arch }} (x86_64, clang, clang64, X64, windows-2025) (push) Waiting to run
Build RPCS3 / RPCS3 FreeBSD (push) Waiting to run
Some checks are pending
Generate Translation Template / Generate Translation Template (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (/rpcs3/.ci/build-linux-aarch64.sh, gcc, rpcs3/rpcs3-ci-jammy-aarch64:1.9, ubuntu-24.04-arm) (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (/rpcs3/.ci/build-linux.sh, gcc, rpcs3/rpcs3-ci-jammy:1.9, ubuntu-24.04) (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (a1d35836e8d45bfc6f63c26f0a3e5d46ef622fe1, rpcs3/rpcs3-binaries-linux-arm64, /rpcs3/.ci/build-linux-aarch64.sh, clang, rpcs3/rpcs3-ci-jammy-aarch64:1.9, ubuntu-24.04-arm) (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (d812f1254a1157c80fd402f94446310560f54e5f, rpcs3/rpcs3-binaries-linux, /rpcs3/.ci/build-linux.sh, clang, rpcs3/rpcs3-ci-jammy:1.9, ubuntu-24.04) (push) Waiting to run
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (0, 51ae32f468089a8169aaf1567de355ff4a3e0842, rpcs3/rpcs3-binaries-mac, Intel) (push) Waiting to run
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (1, 8e21bdbc40711a3fccd18fbf17b742348b0f4281, rpcs3/rpcs3-binaries-mac-arm64, Apple Silicon) (push) Waiting to run
Build RPCS3 / RPCS3 Windows (push) Waiting to run
Build RPCS3 / RPCS3 Windows Clang ${{ matrix.arch }} (aarch64, clang, clangarm64, ARM64, windows-11-arm) (push) Waiting to run
Build RPCS3 / RPCS3 Windows Clang ${{ matrix.arch }} (x86_64, clang, clang64, X64, windows-2025) (push) Waiting to run
Build RPCS3 / RPCS3 FreeBSD (push) Waiting to run
sceNpTrophy fixes - sceNpTrophyGetTrophyUnlockState: signed 1 was potentially shifted by 31(UB) - sceNpTrophyUnlockTrophy: used a reader_lock and was missing check for read only context cellGame fixes - cellHddGameCheck: missing log parameters - cellGameDataCheckCreate2: missing log parameter - cellGameThemeInstall: condition inverted checking for extension + added tolower just in case - cellGameThemeInstallFromBuffer: OOB access, buf is always filled from the start and then used as a parameter to the CB sceNp fixes - sceNpManagerGetTicket: Made accurate from RE - sceNpDrmGetTimelimit: Fix msec calculation sceNp2 fixes -sceNpMatching2ContextStartAsync: avoid capturing ctx -sceNpMatching2ContextStop: Minor error value swap rpcn_client fixes -add_friend: missing log parameter -handle_friend_notification: misc validation issue np_handler fixes -ticket: Missing move in move constructor -ticket::parse: Misc validation fix -get_player_history_entry: potential UB fix np_requests fixes -Wrong CB event_type set for get_room_member_data_external_list! -reply_tus_get_data was not copying status data! -Order of error check in reply_get_room_member_data_external_list was wrong -Improved logging np_requests_gui: -Added missing guards for gui_notifications upnp_handler fixes -Highest density of bugs per line of code in the west, let's pretend I never wrote this signaling_handler fixes -Swapped to multimap to avoid collisions on timestamps Misc fixes
This commit is contained in:
parent
198c2e9eb8
commit
5ca19eabd5
|
|
@ -329,7 +329,7 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, std::st
|
|||
is_valid = false;
|
||||
continue;
|
||||
}
|
||||
else if (serial.size() != 9 || !std::all_of(serial.begin(), serial.end(), [](char c) { return std::isalnum(c); }))
|
||||
else if (serial.size() != 9 || !std::all_of(serial.begin(), serial.end(), [](char c) { return std::isalnum(static_cast<unsigned char>(c)); }))
|
||||
{
|
||||
append_log_message(log_messages, fmt::format("Error: Serial '%s' invalid (patch: %s, key: %s, location: %s, file: %s)", serial, description, main_key, get_yaml_node_location(serial_node), path), &patch_log.error);
|
||||
is_valid = false;
|
||||
|
|
|
|||
|
|
@ -492,8 +492,8 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName
|
|||
strcpy_trunc(get->getParam.titleLang[i], psf::get_string(psf, fmt::format("TITLE_%02d", i)));
|
||||
}
|
||||
|
||||
cellGame.warning("cellHddGameCheck(): Data exists:\nATTRIBUTE: 0x%x, RESOLUTION: 0x%x, RESOLUTION: 0x%x, SOUND_FORMAT: 0x%x, dataVersion: %s"
|
||||
, get->getParam.attribute, get->getParam.resolution, get->getParam.soundFormat, get->getParam.soundFormat, std::span<const u8>(reinterpret_cast<const u8*>(get->getParam.dataVersion), 6));
|
||||
cellGame.warning("cellHddGameCheck(): Data exists:\nATTRIBUTE: 0x%x, RESOLUTION: 0x%x, SOUND_FORMAT: 0x%x, dataVersion: %s"
|
||||
, get->getParam.attribute, get->getParam.resolution, get->getParam.soundFormat, std::span<const u8>(reinterpret_cast<const u8*>(get->getParam.dataVersion), 6));
|
||||
}
|
||||
|
||||
// TODO ?
|
||||
|
|
@ -580,7 +580,7 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName
|
|||
break;
|
||||
|
||||
default:
|
||||
cellGame.error("cellHddGameCheck(): callback returned unknown error (code=0x%x). Error message: %s", result->invalidMsg);
|
||||
cellGame.error("cellHddGameCheck(): callback returned unknown error (code=0x%x). Error message: %s", result->result, result->invalidMsg);
|
||||
error_msg = get_localized_string(localized_string_id::CELL_HDD_GAME_CHECK_INVALID, "%s", result->invalidMsg);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1199,7 +1199,7 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
|
|||
break;
|
||||
|
||||
default:
|
||||
cellGame.error("cellGameDataCheckCreate2(): callback returned unknown error (code=0x%x). Error message: %s", cbResult->invalidMsg);
|
||||
cellGame.error("cellGameDataCheckCreate2(): callback returned unknown error (code=0x%x). Error message: %s", cbResult->result, cbResult->invalidMsg);
|
||||
error_msg = get_localized_string(localized_string_id::CELL_GAMEDATA_CHECK_INVALID, "%s", cbResult->invalidMsg);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1747,7 +1747,7 @@ error_code cellGameThemeInstall(vm::cptr<char> usrdirPath, vm::cptr<char> fileNa
|
|||
{
|
||||
u32 magic{};
|
||||
|
||||
if (src_path.ends_with(".p3t") || !theme.read(magic) || magic != "P3TF"_u32)
|
||||
if (!fmt::to_lower(src_path).ends_with(".p3t") || !theme.read(magic) || magic != "P3TF"_u32)
|
||||
{
|
||||
return CELL_GAME_ERROR_INVALID_THEME_FILE;
|
||||
}
|
||||
|
|
@ -1819,7 +1819,7 @@ error_code cellGameThemeInstallFromBuffer(ppu_thread& ppu, u32 fileSize, u32 buf
|
|||
const u32 read_size = std::min(bufSize, fileSize - file_offset);
|
||||
cellGame.notice("cellGameThemeInstallFromBuffer: writing %d bytes at pos %d", read_size, file_offset);
|
||||
|
||||
if (theme.write(reinterpret_cast<u8*>(buf.get_ptr()) + file_offset, read_size) != read_size)
|
||||
if (theme.write(reinterpret_cast<u8*>(buf.get_ptr()), read_size) != read_size)
|
||||
{
|
||||
cellGame.error("cellGameThemeInstallFromBuffer: failed to write to destination file '%s' (error=%s)", dst_path, fs::g_tls_error);
|
||||
|
||||
|
|
|
|||
|
|
@ -871,7 +871,7 @@ error_code sceNpDrmGetTimelimit(vm::cptr<char> path, vm::ptr<u64> time_remain)
|
|||
}
|
||||
|
||||
// Convert time to milliseconds
|
||||
s64 msec = *sec * 1000ll + *nsec / 1000ll;
|
||||
s64 msec = *sec * 1000ll + *nsec / 1'000'000ll;
|
||||
|
||||
// Return the remaining time in microseconds
|
||||
if (npd.activate_time != 0 && msec < npd.activate_time)
|
||||
|
|
@ -4242,19 +4242,16 @@ error_code sceNpManagerGetTicket(vm::ptr<void> buffer, vm::ptr<u32> bufferSize)
|
|||
}
|
||||
|
||||
const auto& ticket = nph.get_ticket();
|
||||
*bufferSize = static_cast<u32>(ticket.size());
|
||||
|
||||
if (!buffer)
|
||||
{
|
||||
*bufferSize = static_cast<u32>(ticket.size());
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (*bufferSize < ticket.size())
|
||||
{
|
||||
return SCE_NP_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
memcpy(buffer.get_ptr(), ticket.data(), ticket.size());
|
||||
const u32 size_read = std::min(::size32(ticket), static_cast<u32>(*bufferSize));
|
||||
std::memcpy(buffer.get_ptr(), ticket.data(), size_read);
|
||||
*bufferSize = size_read;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
@ -5676,7 +5673,7 @@ error_code scenp_score_record_score(s32 transId, SceNpScoreBoardId boardId, SceN
|
|||
else
|
||||
{
|
||||
data = &gameInfo->nativeData[0];
|
||||
data_size = 64;
|
||||
data_size = sizeof(gameInfo->nativeData);
|
||||
}
|
||||
|
||||
nph.record_score(trans_ctx, boardId, score, scoreComment, data, data_size, tmpRank, async);
|
||||
|
|
|
|||
|
|
@ -1135,7 +1135,7 @@ error_code sceNpMatching2ContextStartAsync(SceNpMatching2ContextId ctxId, u32 ti
|
|||
{
|
||||
sysutil_register_cb([=, context_callback = ctx->context_callback, context_callback_param = ctx->context_callback_param](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
context_callback(cb_ppu, ctxId, SCE_NP_MATCHING2_CONTEXT_EVENT_Start, SCE_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ACTION, 0, ctx->context_callback_param);
|
||||
context_callback(cb_ppu, ctxId, SCE_NP_MATCHING2_CONTEXT_EVENT_Start, SCE_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ACTION, 0, context_callback_param);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
|
@ -1760,7 +1760,7 @@ error_code sceNpMatching2ContextStop(SceNpMatching2ContextId ctxId)
|
|||
const auto ctx = get_match2_context(ctxId);
|
||||
|
||||
if (!ctx)
|
||||
return SCE_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID;
|
||||
return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_FOUND;
|
||||
|
||||
if (!ctx->started.compare_and_swap_test(1, 0))
|
||||
return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_STARTED;
|
||||
|
|
|
|||
|
|
@ -1026,14 +1026,14 @@ error_code sceNpTrophyUnlockTrophy(ppu_thread& ppu, u32 context, u32 handle, s32
|
|||
|
||||
auto& trophy_manager = g_fxo->get<sce_np_trophy_manager>();
|
||||
|
||||
reader_lock lock(trophy_manager.mtx);
|
||||
std::scoped_lock lock(trophy_manager.mtx);
|
||||
|
||||
if (!trophy_manager.is_initialized)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
const auto [ctxt, error] = trophy_manager.get_context_ex(context, handle);
|
||||
const auto [ctxt, error] = trophy_manager.get_context_ex(context, handle, true);
|
||||
|
||||
if (error)
|
||||
{
|
||||
|
|
@ -1184,9 +1184,9 @@ error_code sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, vm::ptr<SceN
|
|||
for (u32 id = 0; id < count_; id++)
|
||||
{
|
||||
if (tropusr->GetTrophyUnlockState(id))
|
||||
flags->flag_bits[id / 32] |= 1 << (id % 32);
|
||||
flags->flag_bits[id / 32] |= 1u << (id % 32);
|
||||
else
|
||||
flags->flag_bits[id / 32] &= ~(1 << (id % 32));
|
||||
flags->flag_bits[id / 32] &= ~(1u << (id % 32));
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ namespace np
|
|||
}
|
||||
|
||||
ticket::ticket(std::vector<u8>&& raw_data)
|
||||
: raw_data(raw_data)
|
||||
: raw_data(std::move(raw_data))
|
||||
{
|
||||
parse();
|
||||
}
|
||||
|
|
@ -387,7 +387,7 @@ namespace np
|
|||
return;
|
||||
}
|
||||
|
||||
if (nodes[0].id != 0x3000 && nodes[1].id != 0x3002)
|
||||
if (nodes[0].id != 0x3000 || nodes[1].id != 0x3002)
|
||||
{
|
||||
ticket_log.error("The 2 blobs ids are incorrect");
|
||||
return;
|
||||
|
|
@ -1467,14 +1467,13 @@ namespace np
|
|||
|
||||
if (all_history)
|
||||
{
|
||||
if (index >= players_history.size())
|
||||
return false;
|
||||
|
||||
auto it = players_history.begin();
|
||||
std::advance(it, index);
|
||||
|
||||
if (it != players_history.end())
|
||||
{
|
||||
string_to_npid(it->first, *npid);
|
||||
return true;
|
||||
}
|
||||
string_to_npid(it->first, *npid);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace np
|
|||
return std::string(ip_str);
|
||||
}
|
||||
|
||||
std::string ether_to_string(std::array<u8, 6>& ether)
|
||||
std::string ether_to_string(const std::array<u8, 6>& ether)
|
||||
{
|
||||
return fmt::format("%02X:%02X:%02X:%02X:%02X:%02X", ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]);
|
||||
}
|
||||
|
|
@ -110,7 +110,7 @@ namespace np
|
|||
|
||||
bool is_valid_npid(const SceNpId& npid)
|
||||
{
|
||||
if (!std::all_of(npid.handle.data, npid.handle.data + 16, [](char c) { return std::isalnum(c) || c == '-' || c == '_' || c == 0; } )
|
||||
if (!std::all_of(npid.handle.data, npid.handle.data + 16, [](char c) { return std::isalnum(static_cast<unsigned char>(c)) || c == '-' || c == '_' || c == 0; } )
|
||||
|| npid.handle.data[16] != 0
|
||||
|| !std::all_of(npid.handle.dummy, npid.handle.dummy + 3, [](char val) { return val == 0; }) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
namespace np
|
||||
{
|
||||
std::string ip_to_string(u32 addr);
|
||||
std::string ether_to_string(std::array<u8, 6>& ether);
|
||||
std::string ether_to_string(const std::array<u8, 6>& ether);
|
||||
bool validate_communication_id(const SceNpCommunicationId& com_id);
|
||||
std::string communication_id_to_string(const SceNpCommunicationId& communicationId);
|
||||
std::optional<SceNpCommunicationId> string_to_communication_id(std::string_view str);
|
||||
|
|
|
|||
|
|
@ -381,7 +381,10 @@ namespace np
|
|||
auto ctx = get_matching_context(ctx_id);
|
||||
|
||||
if (!ctx)
|
||||
{
|
||||
np_memory.free(edata.addr());
|
||||
return;
|
||||
}
|
||||
|
||||
gui_cache.add_room(room_info->room_status.id);
|
||||
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ namespace np
|
|||
case rpcn::ErrorType::RoomGroupMaxSlotMismatch: error_code = SCE_NP_MATCHING2_SERVER_ERROR_MAX_OVER_SLOT_GROUP; break;
|
||||
case rpcn::ErrorType::RoomPasswordMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_PASSWORD; break;
|
||||
case rpcn::ErrorType::RoomGroupNoJoinLabel: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_JOIN_GROUP_LABEL; break;
|
||||
default: fmt::throw_exception("Unexpected error in reply to CreateRoom: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to CreateRoom: %s", error);
|
||||
}
|
||||
|
||||
if (error_code != CELL_OK)
|
||||
|
|
@ -262,7 +262,7 @@ namespace np
|
|||
case rpcn::ErrorType::RoomPasswordMismatch: error_code = SCE_NP_MATCHING2_SERVER_ERROR_PASSWORD_MISMATCH; break;
|
||||
case rpcn::ErrorType::RoomGroupFull: error_code = SCE_NP_MATCHING2_SERVER_ERROR_GROUP_FULL; break;
|
||||
case rpcn::ErrorType::RoomGroupJoinLabelNotFound: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_GROUP; break;
|
||||
default: fmt::throw_exception("Unexpected error in reply to JoinRoom: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to JoinRoom: %s", error);
|
||||
}
|
||||
|
||||
if (error_code != 0)
|
||||
|
|
@ -348,7 +348,7 @@ namespace np
|
|||
case rpcn::ErrorType::NoError: break;
|
||||
case rpcn::ErrorType::NotFound: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break; // Unsure if this should return another error(missing user in room has no appropriate error code)
|
||||
case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break;
|
||||
default: fmt::throw_exception("Unexpected error in reply to LeaveRoom: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to LeaveRoom: %s", error);
|
||||
}
|
||||
|
||||
if (error_code != CELL_OK)
|
||||
|
|
@ -447,7 +447,7 @@ namespace np
|
|||
|
||||
u32 np_handler::get_room_member_data_external_list(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2GetRoomMemberDataExternalListRequest* req)
|
||||
{
|
||||
const u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_GetRoomDataExternalList, true);
|
||||
const u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_GetRoomMemberDataExternalList, true);
|
||||
|
||||
if (!get_rpcn()->get_room_member_data_external_list(req_id, get_match2_context(ctx_id)->communicationId, req->roomId))
|
||||
{
|
||||
|
|
@ -465,13 +465,18 @@ namespace np
|
|||
if (!cb_info_opt)
|
||||
return;
|
||||
|
||||
ensure(error == rpcn::ErrorType::NoError, "Unexpected error in GetRoomMemberDataExternalList reply");
|
||||
|
||||
if (error == rpcn::ErrorType::RoomMissing)
|
||||
switch (error)
|
||||
{
|
||||
case rpcn::ErrorType::NoError:
|
||||
break;
|
||||
case rpcn::ErrorType::RoomMissing:
|
||||
{
|
||||
cb_info_opt->queue_callback(req_id, 0, SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM, 0);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
fmt::throw_exception("Unexpected error in GetRoomMemberDataExternalList reply: %s", error);
|
||||
}
|
||||
|
||||
const auto resp = reply.get_protobuf<np2_structs::GetRoomMemberDataExternalListResponse>();
|
||||
ensure(!reply.is_error(), "Malformed reply to GetRoomMemberDataExternalList command");
|
||||
|
|
@ -518,7 +523,7 @@ namespace np
|
|||
case rpcn::ErrorType::NoError: break;
|
||||
case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break;
|
||||
case rpcn::ErrorType::Unauthorized: error_code = SCE_NP_MATCHING2_SERVER_ERROR_FORBIDDEN; break;
|
||||
default: fmt::throw_exception("Unexpected error in reply to SetRoomDataExternal: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to SetRoomDataExternal: %s", error);
|
||||
}
|
||||
|
||||
cb_info_opt->queue_callback(req_id, 0, error_code, 0);
|
||||
|
|
@ -550,7 +555,7 @@ namespace np
|
|||
{
|
||||
case rpcn::ErrorType::NoError: break;
|
||||
case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break;
|
||||
default: fmt::throw_exception("Unexpected error in reply to GetRoomDataInternal: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to GetRoomDataInternal: %s", error);
|
||||
}
|
||||
|
||||
if (error_code != CELL_OK)
|
||||
|
|
@ -606,7 +611,7 @@ namespace np
|
|||
{
|
||||
case rpcn::ErrorType::NoError: break;
|
||||
case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break;
|
||||
default: fmt::throw_exception("Unexpected error in reply to GetRoomDataInternal: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to SetRoomDataInternal: %s", error);
|
||||
}
|
||||
|
||||
cb_info_opt->queue_callback(req_id, 0, error_code, 0);
|
||||
|
|
@ -640,7 +645,7 @@ namespace np
|
|||
case rpcn::ErrorType::NoError: break;
|
||||
case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break;
|
||||
case rpcn::ErrorType::NotFound: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_USER; break;
|
||||
default: fmt::throw_exception("Unexpected error in reply to GetRoomMemberDataInternal: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to GetRoomMemberDataInternal: %s", error);
|
||||
}
|
||||
|
||||
if (error_code != CELL_OK)
|
||||
|
|
@ -694,7 +699,7 @@ namespace np
|
|||
case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break;
|
||||
case rpcn::ErrorType::NotFound: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_USER; break;
|
||||
case rpcn::ErrorType::Unauthorized: error_code = SCE_NP_MATCHING2_SERVER_ERROR_FORBIDDEN; break;
|
||||
default: fmt::throw_exception("Unexpected error in reply to SetRoomMemberDataInternal: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to SetRoomMemberDataInternal: %s", error);
|
||||
}
|
||||
|
||||
cb_info_opt->queue_callback(req_id, 0, error_code, 0);
|
||||
|
|
@ -723,7 +728,7 @@ namespace np
|
|||
switch (error)
|
||||
{
|
||||
case rpcn::ErrorType::NoError: break;
|
||||
default: fmt::throw_exception("Unexpected error in reply to SetUserInfo: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to SetUserInfo: %s", error);
|
||||
}
|
||||
|
||||
cb_info_opt->queue_callback(req_id, 0, 0, 0);
|
||||
|
|
@ -755,7 +760,7 @@ namespace np
|
|||
{
|
||||
case rpcn::ErrorType::NoError: break;
|
||||
case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break;
|
||||
default: fmt::throw_exception("Unexpected error in reply to PingRoomOwner: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to PingRoomOwner: %s", error);
|
||||
}
|
||||
|
||||
if (error_code != CELL_OK)
|
||||
|
|
@ -803,7 +808,7 @@ namespace np
|
|||
case rpcn::ErrorType::NoError: break;
|
||||
case rpcn::ErrorType::RoomMissing: error_code = SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM; break;
|
||||
case rpcn::ErrorType::Unauthorized: error_code = SCE_NP_MATCHING2_SERVER_ERROR_FORBIDDEN; break;
|
||||
default: fmt::throw_exception("Unexpected error in reply to SendRoomMessage: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to SendRoomMessage: %s", error);
|
||||
}
|
||||
|
||||
cb_info_opt->queue_callback(req_id, 0, error_code, 0);
|
||||
|
|
@ -841,7 +846,7 @@ namespace np
|
|||
rpcn_log.error("Signaling information was requested for a user that doesn't exist or is not online");
|
||||
return;
|
||||
}
|
||||
default: fmt::throw_exception("Unexpected error in reply to RequestSignalingInfos: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to RequestSignalingInfos: %s", error);
|
||||
}
|
||||
|
||||
const auto resp = reply.get_protobuf<np2_structs::SignalingAddr>();
|
||||
|
|
@ -861,9 +866,7 @@ namespace np
|
|||
|
||||
const u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_GetLobbyInfoList, false);
|
||||
auto cb_info_opt = take_pending_request(req_id);
|
||||
|
||||
if (!cb_info_opt)
|
||||
return true;
|
||||
ensure (cb_info_opt);
|
||||
|
||||
const u32 event_key = get_event_key();
|
||||
|
||||
|
|
@ -1017,7 +1020,7 @@ namespace np
|
|||
{
|
||||
case rpcn::ErrorType::NoError: break;
|
||||
case rpcn::ErrorType::NotFound: error_code = SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_BOARD_MASTER_NOT_FOUND; break;
|
||||
default: fmt::throw_exception("Unexpected error in reply to GetBoardInfos: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to GetBoardInfos: %s", error);
|
||||
}
|
||||
|
||||
if (error_code != CELL_OK)
|
||||
|
|
@ -1091,7 +1094,7 @@ namespace np
|
|||
score_trans->wake_cond.notify_one();
|
||||
return;
|
||||
}
|
||||
default: fmt::throw_exception("Unexpected error in reply_record_score: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply_record_score: %s", error);
|
||||
}
|
||||
|
||||
auto tmp_rank = reply.get<u32>();
|
||||
|
|
@ -1154,7 +1157,7 @@ namespace np
|
|||
case rpcn::ErrorType::NotFound: trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_STORE_NOT_FOUND); break;
|
||||
case rpcn::ErrorType::ScoreInvalid: trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_INVALID_SCORE); break;
|
||||
case rpcn::ErrorType::ScoreHasData: trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_GAME_DATA_ALREADY_EXISTS); break;
|
||||
default: fmt::throw_exception("Unexpected error in reply to RecordScoreData: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to RecordScoreData: %s", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1207,7 +1210,7 @@ namespace np
|
|||
{
|
||||
case rpcn::ErrorType::NoError: break;
|
||||
case rpcn::ErrorType::NotFound: score_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_GAME_DATA_MASTER_NOT_FOUND); return;
|
||||
default: fmt::throw_exception("Unexpected error in reply to GetScoreData: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to GetScoreData: %s", error);
|
||||
}
|
||||
|
||||
auto* tdata = std::get_if<tdata_get_score_data>(&score_trans->tdata);
|
||||
|
|
@ -1287,7 +1290,7 @@ namespace np
|
|||
switch (error)
|
||||
{
|
||||
case rpcn::ErrorType::NoError: break;
|
||||
default: fmt::throw_exception("Unexpected error in GetScoreResponse: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in GetScoreResponse: %s", error);
|
||||
}
|
||||
|
||||
const auto resp = reply.get_protobuf<np2_structs::GetScoreResponse>();
|
||||
|
|
@ -1476,7 +1479,7 @@ namespace np
|
|||
case rpcn::ErrorType::NotFound: trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED); break;
|
||||
case rpcn::ErrorType::Unauthorized: trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN); break;
|
||||
case rpcn::ErrorType::CondFail: trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED); break;
|
||||
default: fmt::throw_exception("Unexpected error in handle_tus_no_data: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in handle_tus_no_data: %s", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1499,7 +1502,7 @@ namespace np
|
|||
case rpcn::ErrorType::NotFound: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED);
|
||||
case rpcn::ErrorType::Unauthorized: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN);
|
||||
case rpcn::ErrorType::CondFail: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED);
|
||||
default: fmt::throw_exception("Unexpected error in handle_TusVarResponse: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in handle_TusVarResponse: %s", error);
|
||||
}
|
||||
|
||||
const auto resp = reply.get_protobuf<np2_structs::TusVarResponse>();
|
||||
|
|
@ -1555,7 +1558,7 @@ namespace np
|
|||
case rpcn::ErrorType::NotFound: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED);
|
||||
case rpcn::ErrorType::Unauthorized: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN);
|
||||
case rpcn::ErrorType::CondFail: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED);
|
||||
default: fmt::throw_exception("Unexpected error in handle_TusVariable: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in handle_TusVariable: %s", error);
|
||||
}
|
||||
|
||||
auto pb_var = reply.get_protobuf<np2_structs::TusVariable>();
|
||||
|
|
@ -1603,7 +1606,7 @@ namespace np
|
|||
case rpcn::ErrorType::NotFound: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED);
|
||||
case rpcn::ErrorType::Unauthorized: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN);
|
||||
case rpcn::ErrorType::CondFail: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED);
|
||||
default: fmt::throw_exception("Unexpected error in handle_TusDataStatusResponse: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in handle_TusDataStatusResponse: %s", error);
|
||||
}
|
||||
|
||||
const auto resp = reply.get_protobuf<np2_structs::TusDataStatusResponse>();
|
||||
|
|
@ -1803,7 +1806,7 @@ namespace np
|
|||
if (!tdata)
|
||||
{
|
||||
trans_ctx->tdata = tdata_tus_get_data{.recvSize = recvSize, .dataStatus = dataStatus, .data = data};
|
||||
const u32 req_id = get_req_id(REQUEST_ID_HIGH::SCORE);
|
||||
const u32 req_id = get_req_id(REQUEST_ID_HIGH::TUS);
|
||||
get_rpcn()->tus_get_data(req_id, trans_ctx->communicationId, targetNpId, slotId, vuser);
|
||||
transaction_async_handler(std::move(lock), trans_ctx, req_id, async);
|
||||
return;
|
||||
|
|
@ -1844,7 +1847,7 @@ namespace np
|
|||
case rpcn::ErrorType::NotFound: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED);
|
||||
case rpcn::ErrorType::Unauthorized: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN);
|
||||
case rpcn::ErrorType::CondFail: return tus_trans->set_result_and_wake(SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED);
|
||||
default: fmt::throw_exception("Unexpected error in reply to TusGetData: %d", static_cast<u8>(error));
|
||||
default: fmt::throw_exception("Unexpected error in reply to TusGetData: %s", error);
|
||||
}
|
||||
|
||||
auto pb_data = reply.get_protobuf<np2_structs::TusData>();
|
||||
|
|
@ -1870,6 +1873,7 @@ namespace np
|
|||
data_status->data = tdata->data;
|
||||
data_status->dataSize = ::narrow<u32>(pb_data->data().size());
|
||||
data_status->info.infoSize = ::narrow<u32>(pb_status.info().size());
|
||||
memcpy(data_status->info.data, pb_data->status().info().data(), std::min(pb_data->status().info().size(), sizeof(data_status->info.data)));
|
||||
|
||||
const u32 to_copy = std::min<u32>(data_status->dataSize, tdata->recvSize);
|
||||
memcpy(data, pb_data->data().data(), to_copy);
|
||||
|
|
|
|||
|
|
@ -303,7 +303,11 @@ namespace np
|
|||
|
||||
gui_cache.del_room(room_status->id);
|
||||
|
||||
gui_notifications.list.emplace(std::make_pair(gui_notifications.current_gui_ctx_id, req_id), gui_notification{.event = SCE_NP_MATCHING_EVENT_LEAVE_ROOM_DONE, .edata = std::move(edata)});
|
||||
{
|
||||
std::lock_guard lock(gui_notifications.mutex);
|
||||
gui_notifications.list.emplace(std::make_pair(gui_notifications.current_gui_ctx_id, req_id), gui_notification{.event = SCE_NP_MATCHING_EVENT_LEAVE_ROOM_DONE, .edata = std::move(edata)});
|
||||
}
|
||||
|
||||
ctx->queue_callback(req_id, SCE_NP_MATCHING_EVENT_LEAVE_ROOM_DONE, 0);
|
||||
}
|
||||
|
||||
|
|
@ -453,7 +457,11 @@ namespace np
|
|||
|
||||
extra_nps::print_SceNpMatchingRoom(room_info);
|
||||
|
||||
gui_notifications.list.emplace(std::make_pair(gui_notifications.current_gui_ctx_id, req_id), gui_notification{.event = SCE_NP_MATCHING_EVENT_GET_ROOM_SEARCH_FLAG_DONE, .edata = std::move(edata)});
|
||||
{
|
||||
std::lock_guard lock(gui_notifications.mutex);
|
||||
gui_notifications.list.emplace(std::make_pair(gui_notifications.current_gui_ctx_id, req_id), gui_notification{.event = SCE_NP_MATCHING_EVENT_GET_ROOM_SEARCH_FLAG_DONE, .edata = std::move(edata)});
|
||||
}
|
||||
|
||||
ctx->queue_callback(req_id, SCE_NP_MATCHING_EVENT_GET_ROOM_SEARCH_FLAG_DONE, 0);
|
||||
}
|
||||
|
||||
|
|
@ -548,7 +556,11 @@ namespace np
|
|||
|
||||
extra_nps::print_SceNpMatchingRoom(room_info);
|
||||
|
||||
gui_notifications.list.emplace(std::make_pair(gui_notifications.current_gui_ctx_id, req_id), gui_notification{.event = SCE_NP_MATCHING_EVENT_GET_ROOM_INFO_DONE, .edata = std::move(edata)});
|
||||
{
|
||||
std::lock_guard lock(gui_notifications.mutex);
|
||||
gui_notifications.list.emplace(std::make_pair(gui_notifications.current_gui_ctx_id, req_id), gui_notification{.event = SCE_NP_MATCHING_EVENT_GET_ROOM_INFO_DONE, .edata = std::move(edata)});
|
||||
}
|
||||
|
||||
ctx->queue_callback(req_id, SCE_NP_MATCHING_EVENT_GET_ROOM_INFO_DONE, 0);
|
||||
}
|
||||
|
||||
|
|
@ -581,9 +593,13 @@ namespace np
|
|||
|
||||
SceNpRoomId room_id{};
|
||||
ensure(!resp->id().empty() && resp->id().size() == sizeof(SceNpRoomId::opt));
|
||||
ctx->wakey = 0;
|
||||
std::memcpy(room_id.opt, resp->id().data(), sizeof(SceNpRoomId::opt));
|
||||
const auto [_, inserted] = pending_quickmatching.insert_or_assign(room_id, ctx->ctx_id);
|
||||
ensure(inserted);
|
||||
{
|
||||
std::lock_guard lock(this->mutex_quickmatching);
|
||||
const auto [_, inserted] = pending_quickmatching.insert_or_assign(room_id, ctx->ctx_id);
|
||||
ensure(inserted);
|
||||
}
|
||||
|
||||
// Now that the reply has been received, we start the wait for the notification
|
||||
ctx->thread = std::make_unique<named_thread<std::function<void(SceNpRoomId)>>>("NP GUI Timeout Worker", [ctx, req_id, this](SceNpRoomId room_id)
|
||||
|
|
@ -615,7 +631,6 @@ namespace np
|
|||
}
|
||||
});
|
||||
|
||||
ctx->wakey = 0;
|
||||
auto& thread = *ctx->thread;
|
||||
thread(room_id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1489,7 +1489,7 @@ namespace rpcn
|
|||
if (error == ErrorType::NoError)
|
||||
rpcn_log.success("add_friend(\"%s\") succeeded", friend_username);
|
||||
else
|
||||
rpcn_log.error("add_friend(\"%s\") failed with error: %s", error);
|
||||
rpcn_log.error("add_friend(\"%s\") failed with error: %s", friend_username, error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
@ -3085,7 +3085,7 @@ namespace rpcn
|
|||
}
|
||||
case NotificationType::FriendPresenceChanged:
|
||||
{
|
||||
const std::string username = vdata.get_string(true);
|
||||
const std::string username = vdata.get_string(false);
|
||||
SceNpCommunicationId pr_com_id = vdata.get_com_id();
|
||||
std::string pr_title = fmt::truncate(vdata.get_string(true), SCE_NP_BASIC_PRESENCE_TITLE_SIZE_MAX - 1);
|
||||
std::string pr_status = fmt::truncate(vdata.get_string(true), SCE_NP_BASIC_PRESENCE_EXTENDED_STATUS_SIZE_MAX - 1);
|
||||
|
|
|
|||
|
|
@ -774,6 +774,7 @@ void signaling_handler::send_information_packets(u32 addr, u16 port, const SceNp
|
|||
auto& sent_packet = sig_packet;
|
||||
sent_packet.command = signal_info;
|
||||
|
||||
retire_packet(si, signal_info);
|
||||
send_signaling_packet(sent_packet, addr, port);
|
||||
queue_signaling_packet(sent_packet, si, steady_clock::now() + REPEAT_INFO_DELAY);
|
||||
wake_up();
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ private:
|
|||
|
||||
signaling_packet sig_packet{};
|
||||
|
||||
std::map<steady_clock::time_point, queued_packet> qpackets; // (wakeup time, packet)
|
||||
std::multimap<steady_clock::time_point, queued_packet> qpackets; // (wakeup time, packet)
|
||||
|
||||
u32 cur_conn_id = 1;
|
||||
std::unordered_map<std::string, u32> npid_to_conn_id; // (npid, conn_id)
|
||||
|
|
|
|||
|
|
@ -89,12 +89,10 @@ void upnp_handler::upnp_enable()
|
|||
|
||||
if (desc_xml)
|
||||
{
|
||||
IGDdatas igd_data{};
|
||||
UPNPUrls igd_urls{};
|
||||
parserootdesc(desc_xml, desc_xml_size, &igd_data);
|
||||
parserootdesc(desc_xml, desc_xml_size, &m_igd_data);
|
||||
free(desc_xml);
|
||||
desc_xml = nullptr;
|
||||
GetUPNPUrls(&igd_urls, &igd_data, dev->descURL, 1);
|
||||
GetUPNPUrls(&m_igd_urls, &m_igd_data, dev->descURL, 1);
|
||||
|
||||
upnp_log.notice("Found UPnP device type:%s at %s", dev->st, dev->descURL);
|
||||
|
||||
|
|
@ -116,24 +114,28 @@ void upnp_handler::upnp_enable()
|
|||
freeUPNPDevlist(devlist);
|
||||
}
|
||||
|
||||
void upnp_handler::add_port_redir(std::string_view addr, u16 internal_port, std::string_view protocol)
|
||||
void upnp_handler::add_port_redir(const std::string& addr, u16 internal_port, std::string_view protocol)
|
||||
{
|
||||
if (!m_active)
|
||||
return;
|
||||
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
u16 external_port = internal_port;
|
||||
std::string internal_port_str = fmt::format("%d", internal_port);
|
||||
if (m_bindings[std::string(protocol)].contains(internal_port))
|
||||
return;
|
||||
|
||||
const std::string internal_port_str = fmt::format("%d", internal_port);
|
||||
const std::string protocol_str(protocol);
|
||||
const u32 max_port = std::min(static_cast<u32>(internal_port) + 100, 0xFFFFu);
|
||||
int res = 0;
|
||||
|
||||
for (u16 external_port = internal_port; external_port < internal_port + 100; external_port++)
|
||||
for (u32 external_port = internal_port; external_port <= max_port; external_port++)
|
||||
{
|
||||
std::string external_port_str = fmt::format("%d", external_port);
|
||||
res = UPNP_AddPortMapping(m_igd_urls.controlURL, m_igd_data.first.servicetype, external_port_str.c_str(), internal_port_str.c_str(), addr.data(), "RPCS3", protocol.data(), nullptr, nullptr);
|
||||
res = UPNP_AddPortMapping(m_igd_urls.controlURL, m_igd_data.first.servicetype, external_port_str.c_str(), internal_port_str.c_str(), addr.c_str(), "RPCS3", protocol_str.c_str(), nullptr, nullptr);
|
||||
if (res == UPNPCOMMAND_SUCCESS)
|
||||
{
|
||||
m_bindings[std::string(protocol)][internal_port] = external_port;
|
||||
m_bindings[protocol_str][static_cast<u16>(internal_port)] = external_port;
|
||||
upnp_log.notice("Successfully bound %s:%d(%s) to IGD:%d", addr, internal_port, protocol, external_port);
|
||||
return;
|
||||
}
|
||||
|
|
@ -146,7 +148,7 @@ void upnp_handler::add_port_redir(std::string_view addr, u16 internal_port, std:
|
|||
// }
|
||||
}
|
||||
|
||||
upnp_log.error("Failed to bind %s:%d(%s) to IGD:(%d=>%d): %d", addr, internal_port, protocol, internal_port, external_port, res);
|
||||
upnp_log.error("Failed to bind %s:%d(%s) to IGD:(%d=>%d): %d", addr, internal_port, protocol, internal_port, internal_port, res);
|
||||
}
|
||||
|
||||
void upnp_handler::remove_port_redir(u16 internal_port, std::string_view protocol)
|
||||
|
|
@ -156,27 +158,28 @@ void upnp_handler::remove_port_redir(u16 internal_port, std::string_view protoco
|
|||
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
const std::string str_protocol(protocol);
|
||||
const std::string protocol_str(protocol);
|
||||
|
||||
if (!m_bindings.contains(str_protocol) || !::at32(m_bindings, str_protocol).contains(internal_port))
|
||||
if (!m_bindings.contains(protocol_str) || !::at32(m_bindings, protocol_str).contains(internal_port))
|
||||
{
|
||||
upnp_log.error("tried to unbind port mapping %d to IGD(%s) but it isn't bound", internal_port, protocol);
|
||||
return;
|
||||
}
|
||||
|
||||
const u16 external_port = ::at32(::at32(m_bindings, str_protocol), internal_port);
|
||||
const u16 external_port = ::at32(::at32(m_bindings, protocol_str), internal_port);
|
||||
|
||||
remove_port_redir_external(external_port, protocol);
|
||||
|
||||
ensure(::at32(m_bindings, str_protocol).erase(internal_port));
|
||||
ensure(::at32(m_bindings, protocol_str).erase(internal_port));
|
||||
upnp_log.notice("Successfully deleted port mapping %d to IGD:%d(%s)", internal_port, external_port, protocol);
|
||||
}
|
||||
|
||||
void upnp_handler::remove_port_redir_external(u16 external_port, std::string_view protocol, bool verbose)
|
||||
{
|
||||
const std::string str_ext_port = fmt::format("%d", external_port);
|
||||
const std::string protocol_str(protocol);
|
||||
|
||||
if (int res = UPNP_DeletePortMapping(m_igd_urls.controlURL, m_igd_data.first.servicetype, str_ext_port.c_str(), protocol.data(), nullptr); res != 0 && verbose)
|
||||
if (int res = UPNP_DeletePortMapping(m_igd_urls.controlURL, m_igd_data.first.servicetype, str_ext_port.c_str(), protocol_str.c_str(), nullptr); res != 0 && verbose)
|
||||
upnp_log.error("Failed to delete port mapping IGD:%s(%s): %d", str_ext_port, protocol, res);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ public:
|
|||
~upnp_handler();
|
||||
|
||||
void upnp_enable();
|
||||
void add_port_redir(std::string_view addr, u16 internal_port, std::string_view protocol);
|
||||
void add_port_redir(const std::string& addr, u16 internal_port, std::string_view protocol);
|
||||
void remove_port_redir(u16 internal_port, std::string_view protocol);
|
||||
|
||||
bool is_active() const;
|
||||
|
|
|
|||
Loading…
Reference in a new issue