mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
rpcn: signaling handler improvements & upnp
Simplify signaling by making Matching2 a layer over normal signaling. Implements UPNP port forwarding Implement sceNpMatching2AbortRequest Fix reported bw in sceNpUtil Hack for Fat Princess binding udp on 3658 Reenable CB for sceNpBasicAddPlayersHistoryAsync Misc fixes
This commit is contained in:
parent
364c33060b
commit
6186ac0245
3
.gitignore
vendored
3
.gitignore
vendored
@ -122,6 +122,9 @@ yaml-cpp.pc
|
||||
/3rdparty/libusb_cmake/config.h
|
||||
/3rdparty/libusb_cmake/libusb-1.0.pc
|
||||
|
||||
# miniupnp
|
||||
/3rdparty/miniupnp/x64/*
|
||||
|
||||
# ssl certificate
|
||||
cacert.pem
|
||||
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -80,3 +80,6 @@
|
||||
path = 3rdparty/libsdl-org/SDL
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
ignore = dirty
|
||||
[submodule "3rdparty/miniupnp/miniupnp"]
|
||||
path = 3rdparty/miniupnp/miniupnp
|
||||
url = https://github.com/miniupnp/miniupnp.git
|
||||
|
4
3rdparty/CMakeLists.txt
vendored
4
3rdparty/CMakeLists.txt
vendored
@ -358,6 +358,9 @@ if(USE_SDL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# MINIUPNP
|
||||
add_subdirectory(miniupnp EXCLUDE_FROM_ALL)
|
||||
|
||||
# add nice ALIAS targets for ease of use
|
||||
if(USE_SYSTEM_LIBUSB)
|
||||
add_library(3rdparty::libusb ALIAS usb-1.0-shared)
|
||||
@ -385,3 +388,4 @@ add_library(3rdparty::wolfssl ALIAS wolfssl)
|
||||
add_library(3rdparty::libcurl ALIAS libcurl)
|
||||
add_library(3rdparty::soundtouch ALIAS soundtouch)
|
||||
add_library(3rdparty::sdl2 ALIAS ${SDL2_TARGET})
|
||||
add_library(3rdparty::miniupnpc ALIAS libminiupnpc-static)
|
||||
|
8
3rdparty/miniupnp/CMakeLists.txt
vendored
Normal file
8
3rdparty/miniupnp/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
option (UPNPC_BUILD_STATIC "Build static library" TRUE)
|
||||
option (UPNPC_BUILD_SHARED "Build shared library" FALSE)
|
||||
option (UPNPC_BUILD_TESTS "Build test executables" FALSE)
|
||||
option (UPNPC_BUILD_SAMPLE "Build sample executables" FALSE)
|
||||
option (NO_GETADDRINFO "Define NO_GETADDRINFO" FALSE)
|
||||
option (UPNPC_NO_INSTALL "Disable installation" TRUE)
|
||||
|
||||
add_subdirectory(miniupnp/miniupnpc EXCLUDE_FROM_ALL)
|
1
3rdparty/miniupnp/miniupnp
vendored
Submodule
1
3rdparty/miniupnp/miniupnp
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit f4a739d73083bee207af30b8aa3e668383ee070e
|
138
3rdparty/miniupnp/miniupnpc_static.vcxproj
vendored
Normal file
138
3rdparty/miniupnp/miniupnpc_static.vcxproj
vendored
Normal file
@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{5228f863-e0dd-4de7-aa7b-5c52b14cd4d0}</ProjectGuid>
|
||||
<RootNamespace>miniupnpcstatic</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default_macros.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)lib\$(Configuration)-$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)lib\$(Configuration)-$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_WINSOCK_DEPRECATED_NO_WARNINGS; _CRT_SECURE_NO_WARNINGS;MINIUPNP_STATICLIB;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>generated;miniupnp\miniupnpc;miniupnp\miniupnpc\include</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>cd $(ProjectDir)miniupnp\miniupnpc\msvc
|
||||
cscript genminiupnpcstrings.vbs</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_WINSOCK_DEPRECATED_NO_WARNINGS; _CRT_SECURE_NO_WARNINGS;MINIUPNP_STATICLIB;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>generated;miniupnp\miniupnpc;miniupnp\miniupnpc\include</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>cd $(ProjectDir)miniupnp\miniupnpc\msvc
|
||||
cscript genminiupnpcstrings.vbs</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\addr_is_reserved.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\connecthostport.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\igd_desc_parse.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\minisoap.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\minissdpc.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\miniupnpc.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\miniwget.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\minixml.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\portlistingparse.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\receivedata.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\upnpcommands.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\upnpdev.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\upnperrors.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\upnpreplyparse.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\addr_is_reserved.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\connecthostport.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\igd_desc_parse.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\minisoap.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\minissdpc.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\miniupnpc.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\miniupnpcstrings.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\miniupnpctypes.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\miniupnpc_declspec.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\miniwget.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\miniwget_private.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\minixml.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\portlistingparse.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\receivedata.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\upnpcommands.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\upnpdev.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\upnperrors.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\upnpreplyparse.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\win32_snprintf.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\rc_version.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -74,7 +74,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcurl", "3rdparty\curl\li
|
||||
{73973223-5EE8-41CA-8E88-1D60E89A237B} = {73973223-5EE8-41CA-8E88-1D60E89A237B}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SPIRV", "3rdparty\SPIRV\spirv.vcxproj", "{4CBD3DDD-5555-49A4-A44D-DD3D8CB516A1}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spirv", "3rdparty\SPIRV\spirv.vcxproj", "{4CBD3DDD-5555-49A4-A44D-DD3D8CB516A1}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3rdParty", "3rdParty", "{6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}"
|
||||
EndProject
|
||||
@ -93,6 +93,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "pine", "pine", "{A55DA1B5-C
|
||||
3rdparty\pine\pine_server.h = 3rdparty\pine\pine_server.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc_static", "3rdparty\miniupnp\miniupnpc_static.vcxproj", "{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@ -187,6 +189,10 @@ Global
|
||||
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}.Debug|x64.Build.0 = Debug|x64
|
||||
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}.Release|x64.ActiveCfg = Release|x64
|
||||
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}.Release|x64.Build.0 = Release|x64
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}.Debug|x64.Build.0 = Debug|x64
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}.Release|x64.ActiveCfg = Release|x64
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -216,6 +222,7 @@ Global
|
||||
{508C291A-3D18-49F5-B25D-F7C8DB92CB21} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
|
||||
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
|
||||
{A55DA1B5-CC17-4525-BE7F-1659CE17BB56} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {06CC7920-E085-4B81-9582-8DE8AAD42510}
|
||||
|
@ -159,6 +159,10 @@ target_link_libraries(rpcs3_emu
|
||||
PUBLIC
|
||||
3rdparty::soundtouch)
|
||||
|
||||
target_link_libraries(rpcs3_emu
|
||||
PUBLIC
|
||||
3rdparty::miniupnpc)
|
||||
|
||||
# Cell
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
Cell/MFC.cpp
|
||||
@ -411,6 +415,8 @@ target_sources(rpcs3_emu PRIVATE
|
||||
NP/np_structs_extra.cpp
|
||||
NP/rpcn_client.cpp
|
||||
NP/rpcn_config.cpp
|
||||
NP/upnp_config.cpp
|
||||
NP/upnp_handler.cpp
|
||||
)
|
||||
|
||||
# Memory
|
||||
|
@ -221,16 +221,15 @@ error_code cellNetCtlGetInfo(s32 code, vm::ptr<CellNetCtlInfo> info)
|
||||
switch (code)
|
||||
{
|
||||
case CELL_NET_CTL_INFO_DEVICE: info->device = CELL_NET_CTL_DEVICE_WIRED; break;
|
||||
// case CELL_NET_CTL_INFO_ETHER_ADDR: std::memset(info->ether_addr.data, 0xFF, sizeof(info->ether_addr.data)); break;
|
||||
case CELL_NET_CTL_INFO_MTU: info->mtu = 1500; break;
|
||||
case CELL_NET_CTL_INFO_LINK: info->link = CELL_NET_CTL_LINK_CONNECTED; break;
|
||||
case CELL_NET_CTL_INFO_LINK_TYPE: info->link_type = CELL_NET_CTL_LINK_TYPE_10BASE_FULL; break;
|
||||
case CELL_NET_CTL_INFO_LINK_TYPE: info->link_type = CELL_NET_CTL_LINK_TYPE_100BASE_FULL; break;
|
||||
case CELL_NET_CTL_INFO_IP_CONFIG: info->ip_config = CELL_NET_CTL_IP_STATIC; break;
|
||||
case CELL_NET_CTL_INFO_DEFAULT_ROUTE: strcpy_trunc(info->default_route, "192.168.1.1"); break;
|
||||
case CELL_NET_CTL_INFO_PRIMARY_DNS: strcpy_trunc(info->primary_dns, np::ip_to_string(nph.get_dns_ip())); break;
|
||||
case CELL_NET_CTL_INFO_SECONDARY_DNS: strcpy_trunc(info->secondary_dns, np::ip_to_string(nph.get_dns_ip())); break;
|
||||
case CELL_NET_CTL_INFO_IP_ADDRESS: strcpy_trunc(info->ip_address, np::ip_to_string(nph.get_public_ip_addr())); break;
|
||||
case CELL_NET_CTL_INFO_NETMASK: strcpy_trunc(info->netmask, "255.255.255.255"); break;
|
||||
case CELL_NET_CTL_INFO_IP_ADDRESS: strcpy_trunc(info->ip_address, np::ip_to_string(nph.get_local_ip_addr())); break; // verified on HW
|
||||
case CELL_NET_CTL_INFO_NETMASK: strcpy_trunc(info->netmask, "255.255.255.0"); break;
|
||||
case CELL_NET_CTL_INFO_HTTP_PROXY_CONFIG: info->http_proxy_config = 0; break;
|
||||
case CELL_NET_CTL_INFO_DHCP_HOSTNAME: strcpy_trunc(info->dhcp_hostname, nph.get_hostname()); break;
|
||||
default: cellNetCtl.error("Unsupported request: %s", InfoCodeToName(code)); break;
|
||||
@ -348,7 +347,7 @@ error_code cellNetCtlGetNatInfo(vm::ptr<CellNetCtlNatInfo> natInfo)
|
||||
|
||||
natInfo->nat_type = CELL_NET_CTL_NATINFO_NAT_TYPE_2;
|
||||
natInfo->stun_status = CELL_NET_CTL_NATINFO_STUN_OK;
|
||||
natInfo->upnp_status = CELL_NET_CTL_NATINFO_UPNP_NO;
|
||||
natInfo->upnp_status = nph.get_upnp_status();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "Emu/Cell/lv2/sys_fs.h"
|
||||
#include "Emu/NP/np_handler.h"
|
||||
#include "Emu/NP/np_contexts.h"
|
||||
#include "Emu/NP/np_helpers.h"
|
||||
#include "Emu/system_config.h"
|
||||
|
||||
LOG_CHANNEL(sceNp);
|
||||
@ -5237,11 +5238,11 @@ error_code sceNpSignalingActivateConnection(u32 ctx_id, vm::ptr<SceNpId> npId, v
|
||||
return SCE_NP_SIGNALING_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (strncmp(nph.get_npid().handle.data, npId->handle.data, 16) == 0)
|
||||
if (np::is_same_npid(nph.get_npid(), *npId))
|
||||
return SCE_NP_SIGNALING_ERROR_OWN_NP_ID;
|
||||
|
||||
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
|
||||
*conn_id = sigh.init_sig_infos(npId.get_ptr());
|
||||
*conn_id = sigh.init_sig1(*npId);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -5298,19 +5299,15 @@ error_code sceNpSignalingGetConnectionStatus(u32 ctx_id, u32 conn_id, vm::ptr<s3
|
||||
|
||||
const auto si = sigh.get_sig_infos(conn_id);
|
||||
|
||||
if (si.connStatus == SCE_NP_SIGNALING_CONN_STATUS_ACTIVE && si.ext_status == ext_sign_peer)
|
||||
{
|
||||
*conn_status = SCE_NP_SIGNALING_CONN_STATUS_INACTIVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*conn_status = si.connStatus;
|
||||
}
|
||||
if (!si)
|
||||
return SCE_NP_SIGNALING_ERROR_CONN_NOT_FOUND;
|
||||
|
||||
*conn_status = si->conn_status;
|
||||
|
||||
if (peer_addr)
|
||||
(*peer_addr).np_s_addr = si.addr; // infos.addr is already BE
|
||||
(*peer_addr).np_s_addr = si->addr; // infos.addr is already BE
|
||||
if (peer_port)
|
||||
*peer_port = si.port;
|
||||
*peer_port = si->port;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -5334,33 +5331,36 @@ error_code sceNpSignalingGetConnectionInfo(u32 ctx_id, u32 conn_id, s32 code, vm
|
||||
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
|
||||
const auto si = sigh.get_sig_infos(conn_id);
|
||||
|
||||
if (!si)
|
||||
return SCE_NP_SIGNALING_ERROR_CONN_NOT_FOUND;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case SCE_NP_SIGNALING_CONN_INFO_RTT:
|
||||
{
|
||||
info->rtt = si.rtt;
|
||||
info->rtt = si->rtt;
|
||||
break;
|
||||
}
|
||||
case SCE_NP_SIGNALING_CONN_INFO_BANDWIDTH:
|
||||
{
|
||||
info->bandwidth = 10'000'000; // 10 MBPS HACK
|
||||
info->bandwidth = 100'000'000; // 100 MBPS HACK
|
||||
break;
|
||||
}
|
||||
case SCE_NP_SIGNALING_CONN_INFO_PEER_NPID:
|
||||
{
|
||||
info->npId = si.npid;
|
||||
info->npId = si->npid;
|
||||
break;
|
||||
}
|
||||
case SCE_NP_SIGNALING_CONN_INFO_PEER_ADDRESS:
|
||||
{
|
||||
info->address.port = std::bit_cast<u16, be_t<u16>>(si.port);
|
||||
info->address.addr.np_s_addr = si.addr;
|
||||
info->address.port = std::bit_cast<u16, be_t<u16>>(si->port);
|
||||
info->address.addr.np_s_addr = si->addr;
|
||||
break;
|
||||
}
|
||||
case SCE_NP_SIGNALING_CONN_INFO_MAPPED_ADDRESS:
|
||||
{
|
||||
info->address.port = std::bit_cast<u16, be_t<u16>>(si.mapped_port);
|
||||
info->address.addr.np_s_addr = si.mapped_addr;
|
||||
info->address.port = std::bit_cast<u16, be_t<u16>>(si->mapped_port);
|
||||
info->address.addr.np_s_addr = si->mapped_addr;
|
||||
break;
|
||||
}
|
||||
case SCE_NP_SIGNALING_CONN_INFO_PACKET_LOSS:
|
||||
@ -5393,8 +5393,13 @@ error_code sceNpSignalingGetConnectionFromNpId(u32 ctx_id, vm::ptr<SceNpId> npId
|
||||
return SCE_NP_SIGNALING_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (np::is_same_npid(*npId, nph.get_npid()))
|
||||
{
|
||||
return SCE_NP_SIGNALING_ERROR_OWN_NP_ID;
|
||||
}
|
||||
|
||||
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
|
||||
const auto found_conn_id = sigh.get_conn_id_from_npid(npId.get_ptr());
|
||||
const auto found_conn_id = sigh.get_conn_id_from_npid(*npId);
|
||||
|
||||
if (!found_conn_id)
|
||||
{
|
||||
@ -5455,9 +5460,9 @@ error_code sceNpSignalingGetLocalNetInfo(u32 ctx_id, vm::ptr<SceNpSignalingNetIn
|
||||
info->mapped_addr = nph.get_public_ip_addr();
|
||||
|
||||
// Pure speculation below
|
||||
info->nat_status = 0;
|
||||
info->upnp_status = 0;
|
||||
info->npport_status = 0;
|
||||
info->nat_status = SCE_NP_SIGNALING_NETINFO_NAT_STATUS_TYPE2;
|
||||
info->upnp_status = nph.get_upnp_status();
|
||||
info->npport_status = SCE_NP_SIGNALING_NETINFO_NPPORT_STATUS_OPEN;
|
||||
info->npport = SCE_NP_PORT;
|
||||
|
||||
return CELL_OK;
|
||||
@ -5537,25 +5542,8 @@ error_code sceNpUtilCmpNpId(vm::ptr<SceNpId> id1, vm::ptr<SceNpId> id2)
|
||||
return SCE_NP_UTIL_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
// Unknown what this constant means
|
||||
// if (id1->reserved[0] != 1 || id2->reserved[0] != 1)
|
||||
// {
|
||||
// return SCE_NP_UTIL_ERROR_INVALID_NP_ID;
|
||||
// }
|
||||
|
||||
if (strncmp(id1->handle.data, id2->handle.data, 16))// || id1->unk1[0] != id2->unk1[0])
|
||||
{
|
||||
if (!np::is_same_npid(*id1, *id2))
|
||||
return not_an_error(SCE_NP_UTIL_ERROR_NOT_MATCH);
|
||||
}
|
||||
|
||||
// if (id1->unk1[1] != id2->unk1[1])
|
||||
// {
|
||||
// // If either is zero they match
|
||||
// if (id1->opt[4] && id2->opt[4])
|
||||
// {
|
||||
// return SCE_NP_UTIL_ERROR_NOT_MATCH;
|
||||
// }
|
||||
// }
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "sceNp2.h"
|
||||
#include "Emu/NP/np_handler.h"
|
||||
#include "Emu/NP/np_contexts.h"
|
||||
#include "Emu/NP/np_helpers.h"
|
||||
#include "cellSysutil.h"
|
||||
|
||||
LOG_CHANNEL(sceNp2);
|
||||
@ -444,20 +445,35 @@ error_code sceNpMatching2SignalingGetConnectionStatus(
|
||||
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
auto [res, npid] = nph.local_get_npid(roomId, memberId);
|
||||
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
if (np::is_same_npid(nph.get_npid(), *npid))
|
||||
return SCE_NP_SIGNALING_ERROR_OWN_NP_ID;
|
||||
|
||||
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
|
||||
|
||||
const auto si = sigh.get_sig2_infos(roomId, memberId);
|
||||
auto conn_id = sigh.get_conn_id_from_npid(*npid);
|
||||
if (!conn_id)
|
||||
return SCE_NP_SIGNALING_ERROR_CONN_NOT_FOUND;
|
||||
|
||||
*connStatus = si.connStatus;
|
||||
const auto si = sigh.get_sig_infos(*conn_id);
|
||||
|
||||
if (!si)
|
||||
return SCE_NP_SIGNALING_ERROR_CONN_NOT_FOUND;
|
||||
|
||||
*connStatus = si->conn_status;
|
||||
|
||||
if (peerAddr)
|
||||
{
|
||||
(*peerAddr).np_s_addr = si.addr; // infos.addr is already BE
|
||||
(*peerAddr).np_s_addr = si->addr; // infos.addr is already BE
|
||||
}
|
||||
|
||||
if (peerPort)
|
||||
{
|
||||
*peerPort = si.port;
|
||||
*peerPort = si->port;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
@ -616,42 +632,58 @@ error_code sceNpMatching2SignalingGetConnectionInfo(
|
||||
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
auto [res, npid] = nph.local_get_npid(roomId, memberId);
|
||||
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
if (np::is_same_npid(nph.get_npid(), *npid))
|
||||
return SCE_NP_SIGNALING_ERROR_OWN_NP_ID;
|
||||
|
||||
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
|
||||
const auto si = sigh.get_sig2_infos(roomId, memberId);
|
||||
|
||||
auto conn_id = sigh.get_conn_id_from_npid(*npid);
|
||||
if (!conn_id)
|
||||
return SCE_NP_SIGNALING_ERROR_CONN_NOT_FOUND;
|
||||
|
||||
const auto si = sigh.get_sig_infos(*conn_id);
|
||||
|
||||
if (!si)
|
||||
return SCE_NP_SIGNALING_ERROR_CONN_NOT_FOUND;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case SCE_NP_SIGNALING_CONN_INFO_RTT:
|
||||
{
|
||||
connInfo->rtt = si.rtt;
|
||||
connInfo->rtt = si->rtt;
|
||||
sceNp2.warning("Returning a RTT of %d microseconds", connInfo->rtt);
|
||||
break;
|
||||
}
|
||||
case SCE_NP_SIGNALING_CONN_INFO_BANDWIDTH:
|
||||
{
|
||||
connInfo->bandwidth = 10'000'000; // 10 MBPS HACK
|
||||
connInfo->bandwidth = 100'000'000; // 100 MBPS HACK
|
||||
break;
|
||||
}
|
||||
case SCE_NP_SIGNALING_CONN_INFO_PEER_NPID:
|
||||
{
|
||||
connInfo->npId = si.npid;
|
||||
connInfo->npId = si->npid;
|
||||
break;
|
||||
}
|
||||
case SCE_NP_SIGNALING_CONN_INFO_PEER_ADDRESS:
|
||||
{
|
||||
connInfo->address.port = std::bit_cast<u16, be_t<u16>>(si.port);
|
||||
connInfo->address.addr.np_s_addr = si.addr;
|
||||
connInfo->address.port = std::bit_cast<u16, be_t<u16>>(si->port);
|
||||
connInfo->address.addr.np_s_addr = si->addr;
|
||||
break;
|
||||
}
|
||||
case SCE_NP_SIGNALING_CONN_INFO_MAPPED_ADDRESS:
|
||||
{
|
||||
connInfo->address.port = std::bit_cast<u16, be_t<u16>>(si.mapped_port);
|
||||
connInfo->address.addr.np_s_addr = si.mapped_addr;
|
||||
connInfo->address.port = std::bit_cast<u16, be_t<u16>>(si->mapped_port);
|
||||
connInfo->address.addr.np_s_addr = si->mapped_addr;
|
||||
break;
|
||||
}
|
||||
case SCE_NP_SIGNALING_CONN_INFO_PACKET_LOSS:
|
||||
{
|
||||
connInfo->packet_loss = 1; // HACK
|
||||
connInfo->packet_loss = 0; // HACK
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -709,7 +741,7 @@ error_code sceNpMatching2GetRoomMemberDataExternalList(SceNpMatching2ContextId c
|
||||
|
||||
error_code sceNpMatching2AbortRequest(SceNpMatching2ContextId ctxId, SceNpMatching2RequestId reqId)
|
||||
{
|
||||
sceNp2.todo("sceNpMatching2AbortRequest(ctxId=%d, reqId=%d)", ctxId, reqId);
|
||||
sceNp2.warning("sceNpMatching2AbortRequest(ctxId=%d, reqId=%d)", ctxId, reqId);
|
||||
|
||||
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||
|
||||
@ -728,6 +760,9 @@ error_code sceNpMatching2AbortRequest(SceNpMatching2ContextId ctxId, SceNpMatchi
|
||||
return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (!nph.abort_request(reqId))
|
||||
return SCE_NP_MATCHING2_ERROR_REQUEST_NOT_FOUND;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -1591,7 +1626,7 @@ error_code sceNpMatching2SignalingCancelPeerNetInfo(SceNpMatching2ContextId ctxI
|
||||
|
||||
error_code sceNpMatching2SignalingGetLocalNetInfo(vm::ptr<SceNpMatching2SignalingNetInfo> netinfo)
|
||||
{
|
||||
sceNp2.todo("sceNpMatching2SignalingGetLocalNetInfo(netinfo=*0x%x)", netinfo);
|
||||
sceNp2.warning("sceNpMatching2SignalingGetLocalNetInfo(netinfo=*0x%x)", netinfo);
|
||||
|
||||
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||
|
||||
@ -1600,12 +1635,17 @@ error_code sceNpMatching2SignalingGetLocalNetInfo(vm::ptr<SceNpMatching2Signalin
|
||||
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!netinfo)
|
||||
if (!netinfo || netinfo->size != sizeof(SceNpMatching2SignalingNetInfo))
|
||||
{
|
||||
// TODO: check netinfo->size
|
||||
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
netinfo->localAddr = nph.get_local_ip_addr();
|
||||
netinfo->mappedAddr = nph.get_public_ip_addr();
|
||||
|
||||
// Pure speculation below
|
||||
netinfo->natStatus = SCE_NP_SIGNALING_NETINFO_NAT_STATUS_TYPE2;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -1639,9 +1679,8 @@ error_code sceNpMatching2SignalingGetPeerNetInfoResult(SceNpMatching2ContextId c
|
||||
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!netinfo)
|
||||
if (!netinfo || netinfo->size != sizeof(SceNpMatching2SignalingNetInfo))
|
||||
{
|
||||
// TODO: check netinfo->size
|
||||
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
|
@ -1555,9 +1555,9 @@ struct SceNpMatching2CbQueueInfo
|
||||
u8 reserved[12];
|
||||
};
|
||||
|
||||
union SceNpMatching2SignalingNetInfo // TODO check values
|
||||
struct SceNpMatching2SignalingNetInfo
|
||||
{
|
||||
be_t<u64> size;
|
||||
be_t<u32> size;
|
||||
be_t<u32> localAddr;
|
||||
be_t<u32> mappedAddr;
|
||||
be_t<u32> natStatus;
|
||||
|
@ -39,8 +39,8 @@ struct bandwidth_test
|
||||
}
|
||||
}
|
||||
|
||||
test_result.upload_bps = 16000.0;
|
||||
test_result.download_bps = 16000.0;
|
||||
test_result.upload_bps = 100'000'000.0;
|
||||
test_result.download_bps = 100'000'000.0;
|
||||
test_result.result = CELL_OK;
|
||||
status = SCE_NP_UTIL_BANDWIDTH_TEST_STATUS_FINISHED;
|
||||
finished = true;
|
||||
|
@ -1769,7 +1769,7 @@ error_code sys_net_abort(ppu_thread& ppu, s32 type, u64 arg, s32 flags)
|
||||
{
|
||||
ppu.state += cpu_flag::wait;
|
||||
|
||||
sys_net.todo("sys_net_abort(type=%d, arg=0x%x, flags=0x%x)", type, arg, flags);
|
||||
sys_net.warning("sys_net_abort(type=%d, arg=0x%x, flags=0x%x)", type, arg, flags);
|
||||
|
||||
enum abort_type : s32
|
||||
{
|
||||
|
@ -50,6 +50,13 @@ lv2_socket_native::~lv2_socket_native()
|
||||
::close(socket);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (bound_port)
|
||||
{
|
||||
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||
nph.upnp_remove_port_mapping(bound_port, type == SYS_NET_SOCK_STREAM ? "TCP" : "UDP");
|
||||
bound_port = 0;
|
||||
}
|
||||
}
|
||||
|
||||
s32 lv2_socket_native::create_socket()
|
||||
@ -143,10 +150,36 @@ s32 lv2_socket_native::bind(const sys_net_sockaddr& addr)
|
||||
native_addr.sin_addr.s_addr = saddr;
|
||||
::socklen_t native_addr_len = sizeof(native_addr);
|
||||
|
||||
// Note that this is a hack(TODO)
|
||||
// ATM we don't support binding 3658 udp because we use it for the p2ps main socket
|
||||
// Only Fat Princess is known to do this to my knowledge
|
||||
if (psa_in->sin_port == 3658 && type == SYS_NET_SOCK_DGRAM)
|
||||
{
|
||||
native_addr.sin_port = std::bit_cast<u16, be_t<u16>>(3659);
|
||||
}
|
||||
|
||||
sys_net.warning("[Native] Trying to bind %s:%d", native_addr.sin_addr, std::bit_cast<be_t<u16>, u16>(native_addr.sin_port));
|
||||
|
||||
if (::bind(socket, reinterpret_cast<struct sockaddr*>(&native_addr), native_addr_len) == 0)
|
||||
{
|
||||
// Only UPNP port forward binds to 0.0.0.0
|
||||
if (saddr == 0)
|
||||
{
|
||||
if (native_addr.sin_port == 0)
|
||||
{
|
||||
sockaddr_in client_addr;
|
||||
socklen_t client_addr_size = sizeof(client_addr);
|
||||
ensure(::getsockname(socket, reinterpret_cast<struct sockaddr*>(&client_addr), &client_addr_size) == 0);
|
||||
bound_port = std::bit_cast<u16, be_t<u16>>(client_addr.sin_port);
|
||||
}
|
||||
else
|
||||
{
|
||||
bound_port = std::bit_cast<u16, be_t<u16>>(native_addr.sin_port);
|
||||
}
|
||||
|
||||
nph.upnp_add_port_mapping(bound_port, type == SYS_NET_SOCK_STREAM ? "TCP" : "UDP");
|
||||
}
|
||||
|
||||
last_bound_addr = addr;
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -1011,6 +1044,13 @@ void lv2_socket_native::close()
|
||||
|
||||
auto& dnshook = g_fxo->get<np::dnshook>();
|
||||
dnshook.remove_dns_spy(lv2_id);
|
||||
|
||||
if (bound_port)
|
||||
{
|
||||
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||
nph.upnp_remove_port_mapping(bound_port, type == SYS_NET_SOCK_STREAM ? "TCP" : "UDP");
|
||||
bound_port = 0;
|
||||
}
|
||||
}
|
||||
|
||||
s32 lv2_socket_native::shutdown(s32 how)
|
||||
|
@ -68,4 +68,5 @@ private:
|
||||
s32 so_reuseaddr = 0;
|
||||
s32 so_reuseport = 0;
|
||||
#endif
|
||||
u16 bound_port = 0;
|
||||
};
|
||||
|
@ -83,16 +83,12 @@ void need_network()
|
||||
initialize_tcp_timeout_monitor();
|
||||
}
|
||||
|
||||
network_thread::network_thread() noexcept
|
||||
void network_thread::bind_sce_np_port()
|
||||
{
|
||||
if (g_cfg.net.psn_status == np_psn_status::psn_rpcn)
|
||||
std::lock_guard list_lock(list_p2p_ports_mutex);
|
||||
list_p2p_ports.emplace(std::piecewise_construct, std::forward_as_tuple(SCE_NP_PORT), std::forward_as_tuple(SCE_NP_PORT));
|
||||
}
|
||||
|
||||
network_thread::~network_thread()
|
||||
{
|
||||
}
|
||||
|
||||
void network_thread::operator()()
|
||||
{
|
||||
std::vector<std::shared_ptr<lv2_socket>> socklist;
|
||||
|
@ -17,10 +17,7 @@ struct network_thread
|
||||
|
||||
static constexpr auto thread_name = "Network Thread";
|
||||
|
||||
network_thread() noexcept;
|
||||
|
||||
~network_thread();
|
||||
|
||||
void bind_sce_np_port();
|
||||
void operator()();
|
||||
};
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "Emu/NP/signaling_handler.h"
|
||||
#include "sys_net_helpers.h"
|
||||
#include "Emu/NP/vport0.h"
|
||||
#include "Emu/NP/np_handler.h"
|
||||
|
||||
LOG_CHANNEL(sys_net);
|
||||
|
||||
@ -69,6 +70,9 @@ nt_p2p_port::nt_p2p_port(u16 port)
|
||||
if (ret_bind == -1)
|
||||
fmt::throw_exception("Failed to bind DGRAM socket to %d for P2P: %s!", port, get_last_error(true));
|
||||
|
||||
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||
nph.upnp_add_port_mapping(port, "UDP");
|
||||
|
||||
sys_net.notice("P2P port %d was bound!", port);
|
||||
}
|
||||
|
||||
@ -82,6 +86,9 @@ nt_p2p_port::~nt_p2p_port()
|
||||
::close(p2p_socket);
|
||||
#endif
|
||||
}
|
||||
|
||||
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||
nph.upnp_remove_port_mapping(port, "UDP");
|
||||
}
|
||||
|
||||
void nt_p2p_port::dump_packet(p2ps_encapsulated_tcp* tcph)
|
||||
|
@ -3,6 +3,9 @@
|
||||
|
||||
#include "Emu/NP/np_allocator.h"
|
||||
#include "Emu/NP/np_cache.h"
|
||||
#include "Emu/NP/np_helpers.h"
|
||||
|
||||
LOG_CHANNEL(np_cache);
|
||||
|
||||
namespace np
|
||||
{
|
||||
@ -80,20 +83,32 @@ namespace np
|
||||
rooms[sce_roomdata->roomId].update(sce_roomdata);
|
||||
}
|
||||
|
||||
void cache_manager::add_member(SceNpMatching2RoomId room_id, const SceNpMatching2RoomMemberDataInternal* sce_roommemberdata)
|
||||
bool cache_manager::add_member(SceNpMatching2RoomId room_id, const SceNpMatching2RoomMemberDataInternal* sce_roommemberdata)
|
||||
{
|
||||
std::lock_guard lock(mutex);
|
||||
|
||||
ensure(rooms.contains(room_id), "cache_manager::add_member: Room not cached!");
|
||||
rooms[room_id].members.insert_or_assign(sce_roommemberdata->memberId, member_cache(sce_roommemberdata));
|
||||
if (!rooms.contains(room_id))
|
||||
{
|
||||
np_cache.error("np_cache::add_member cache miss: room_id(%d)", room_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
void cache_manager::del_member(SceNpMatching2RoomId room_id, SceNpMatching2RoomMemberId member_id)
|
||||
rooms[room_id].members.insert_or_assign(sce_roommemberdata->memberId, member_cache(sce_roommemberdata));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cache_manager::del_member(SceNpMatching2RoomId room_id, SceNpMatching2RoomMemberId member_id)
|
||||
{
|
||||
std::lock_guard lock(mutex);
|
||||
|
||||
ensure(rooms.contains(room_id), "cache_manager::del_member: Room not cached!");
|
||||
if (!rooms.contains(room_id))
|
||||
{
|
||||
np_cache.error("np_cache::del_member cache miss: room_id(%d)/member_id(%d)", room_id, member_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
rooms.erase(member_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
void cache_manager::update_password(SceNpMatching2RoomId room_id, const std::optional<SceNpMatching2SessionPassword>& password)
|
||||
@ -121,7 +136,7 @@ namespace np
|
||||
SceNpMatching2RoomJoinedSlotMask join_mask = 0;
|
||||
for (const auto& member : room.members)
|
||||
{
|
||||
join_mask |= (1 << (member.first - 1));
|
||||
join_mask |= (1 << ((member.first >> 4) - 1));
|
||||
}
|
||||
slots.joinedSlotMask = join_mask;
|
||||
slots.passwordSlotMask = room.mask_password;
|
||||
@ -307,14 +322,45 @@ namespace np
|
||||
return needed_data_size;
|
||||
}
|
||||
|
||||
SceNpId cache_manager::get_npid(u64 room_id, u16 member_id)
|
||||
std::pair<error_code, std::optional<SceNpId>> cache_manager::get_npid(u64 room_id, u16 member_id)
|
||||
{
|
||||
std::lock_guard lock(mutex);
|
||||
|
||||
ensure(rooms.contains(room_id), "cache_manager::get_npid: Room not cached!");
|
||||
ensure(::at32(rooms, room_id).members.contains(member_id), "cache_manager::get_npid: Member not cached!");
|
||||
if (!rooms.contains(room_id))
|
||||
{
|
||||
np_cache.error("np_cache::get_npid cache miss room_id: room_id(%d)/member_id(%d)", room_id, member_id);
|
||||
return {SCE_NP_MATCHING2_ERROR_INVALID_ROOM_ID, std::nullopt};
|
||||
}
|
||||
|
||||
return ::at32(::at32(rooms, room_id).members, member_id).userInfo.npId;
|
||||
if (!::at32(rooms, room_id).members.contains(member_id))
|
||||
{
|
||||
np_cache.error("np_cache::get_npid cache miss member_id: room_id(%d)/member_id(%d)", room_id, member_id);
|
||||
return {SCE_NP_MATCHING2_ERROR_INVALID_MEMBER_ID, std::nullopt};
|
||||
}
|
||||
|
||||
return {CELL_OK, ::at32(::at32(rooms, room_id).members, member_id).userInfo.npId};
|
||||
}
|
||||
|
||||
std::optional<u16> cache_manager::get_memberid(u64 room_id, const SceNpId& npid)
|
||||
{
|
||||
std::lock_guard lock(mutex);
|
||||
|
||||
if (!rooms.contains(room_id))
|
||||
{
|
||||
np_cache.error("np_cache::get_memberid cache miss room_id: room_id(%d)/npid(%s)", room_id, static_cast<const char*>(npid.handle.data));
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto& members = ::at32(rooms, room_id).members;
|
||||
|
||||
for (const auto& [id, member_cache] : members)
|
||||
{
|
||||
if (np::is_same_npid(member_cache.userInfo.npId, npid))
|
||||
return id;
|
||||
}
|
||||
|
||||
np_cache.error("np_cache::get_memberid cache miss member_id: room_id(%d)/npid(%s)", room_id, static_cast<const char*>(npid.handle.data));
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
} // namespace np
|
||||
|
@ -67,15 +67,16 @@ namespace np
|
||||
cache_manager() = default;
|
||||
|
||||
void insert_room(const SceNpMatching2RoomDataInternal* sce_roomdata);
|
||||
void add_member(SceNpMatching2RoomId room_id, const SceNpMatching2RoomMemberDataInternal* sce_roommemberdata);
|
||||
void del_member(SceNpMatching2RoomId room_id, SceNpMatching2RoomMemberId member_id);
|
||||
bool add_member(SceNpMatching2RoomId room_id, const SceNpMatching2RoomMemberDataInternal* sce_roommemberdata);
|
||||
bool del_member(SceNpMatching2RoomId room_id, SceNpMatching2RoomMemberId member_id);
|
||||
void update_password(SceNpMatching2RoomId room_id, const std::optional<SceNpMatching2SessionPassword>& password);
|
||||
|
||||
std::pair<error_code, std::optional<SceNpMatching2RoomSlotInfo>> get_slots(SceNpMatching2RoomId room_id);
|
||||
std::pair<error_code, std::vector<SceNpMatching2RoomMemberId>> get_memberids(u64 room_id, s32 sort_method);
|
||||
std::pair<error_code, std::optional<SceNpMatching2SessionPassword>> get_password(SceNpMatching2RoomId room_id);
|
||||
error_code get_member_and_attrs(SceNpMatching2RoomId room_id, SceNpMatching2RoomMemberId member_id, const std::vector<SceNpMatching2AttributeId>& binattrs_list, SceNpMatching2RoomMemberDataInternal* ptr_member, u32 addr_data, u32 size_data);
|
||||
SceNpId get_npid(u64 room_id, u16 member_id);
|
||||
std::pair<error_code, std::optional<SceNpId>> get_npid(u64 room_id, u16 member_id);
|
||||
std::optional<u16> get_memberid(u64 room_id, const SceNpId& npid);
|
||||
|
||||
private:
|
||||
shared_mutex mutex;
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "Emu/Cell/Modules/sceNp2.h"
|
||||
#include "Emu/Cell/Modules/cellNetCtl.h"
|
||||
#include "Utilities/StrUtil.h"
|
||||
#include "Emu/Cell/Modules/cellSysutil.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/NP/np_structs_extra.h"
|
||||
#include "Emu/System.h"
|
||||
@ -14,6 +13,8 @@
|
||||
#include "Emu/NP/np_contexts.h"
|
||||
#include "Emu/NP/np_helpers.h"
|
||||
#include "Emu/RSX/Overlays/overlay_message.h"
|
||||
#include "Emu/Cell/lv2/sys_net/network_context.h"
|
||||
#include "Emu/Cell/lv2/sys_net/sys_net_helpers.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
@ -342,21 +343,18 @@ namespace np
|
||||
{
|
||||
g_fxo->need<named_thread<signaling_handler>>();
|
||||
|
||||
std::lock_guard lock(mutex_rpcn);
|
||||
rpcn = rpcn::rpcn_client::get_instance();
|
||||
|
||||
is_connected = (g_cfg.net.net_active == np_internet_status::enabled);
|
||||
is_psn_active = (g_cfg.net.psn_status >= np_psn_status::psn_fake);
|
||||
is_psn_active = (g_cfg.net.psn_status >= np_psn_status::psn_fake) && is_connected;
|
||||
|
||||
if (get_net_status() == CELL_NET_CTL_STATE_IPObtained)
|
||||
{
|
||||
discover_ip_address();
|
||||
|
||||
if (!discover_ether_address())
|
||||
if (!discover_ether_address() || !discover_ip_address())
|
||||
{
|
||||
nph_log.error("Failed to discover ethernet address!");
|
||||
nph_log.error("Failed to discover ethernet or ip address!");
|
||||
is_connected = false;
|
||||
is_psn_active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert dns address
|
||||
@ -383,6 +381,19 @@ namespace np
|
||||
{
|
||||
bind_ip = conv.s_addr;
|
||||
}
|
||||
|
||||
if (g_cfg.net.upnp_enabled)
|
||||
upnp.upnp_enable();
|
||||
}
|
||||
|
||||
if (is_psn_active && g_cfg.net.psn_status == np_psn_status::psn_rpcn)
|
||||
{
|
||||
g_fxo->need<network_context>();
|
||||
auto& nc = g_fxo->get<network_context>();
|
||||
nc.bind_sce_np_port();
|
||||
|
||||
std::lock_guard lock(mutex_rpcn);
|
||||
rpcn = rpcn::rpcn_client::get_instance();
|
||||
}
|
||||
}
|
||||
|
||||
@ -449,46 +460,45 @@ namespace np
|
||||
ar(m_pool, m_size, m_allocs, m_avail);
|
||||
}
|
||||
|
||||
void np_handler::discover_ip_address()
|
||||
bool np_handler::discover_ip_address()
|
||||
{
|
||||
hostname.clear();
|
||||
hostname.resize(1024);
|
||||
auto sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
const auto use_default_ip_addr = [this](const std::string_view error_msg)
|
||||
auto close_socket = [&]()
|
||||
{
|
||||
nph_log.error("discover_ip_address: %s", error_msg);
|
||||
nph_log.error("discover_ip_address: Defaulting to 127.0.0.1!");
|
||||
local_ip_addr = 0x0100007f;
|
||||
public_ip_addr = local_ip_addr;
|
||||
#ifdef _WIN32
|
||||
closesocket(sockfd);
|
||||
#else
|
||||
close(sockfd);
|
||||
#endif
|
||||
};
|
||||
|
||||
if (gethostname(hostname.data(), hostname.size()) == -1)
|
||||
::sockaddr_in addr;
|
||||
std::memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = 53;
|
||||
addr.sin_addr.s_addr = 0x08080808;
|
||||
if (connect(sockfd, reinterpret_cast<const sockaddr *>(&addr), sizeof(addr)) != 0)
|
||||
{
|
||||
use_default_ip_addr("gethostname failed!");
|
||||
return;
|
||||
// If connect fails a route to the internet is not available
|
||||
nph_log.error("connect to discover local ip failed: %d", get_native_error());
|
||||
close_socket();
|
||||
return false; // offline
|
||||
}
|
||||
|
||||
// nph_log.notice("discover_ip_address: Hostname was determined to be %s", hostname.c_str());
|
||||
|
||||
hostent* host = gethostbyname(hostname.data());
|
||||
if (!host)
|
||||
sockaddr_in client_addr;
|
||||
socklen_t client_addr_size = sizeof(client_addr);
|
||||
if (getsockname(sockfd, reinterpret_cast<struct sockaddr*>(&client_addr), &client_addr_size) != 0)
|
||||
{
|
||||
use_default_ip_addr("gethostbyname failed!");
|
||||
return;
|
||||
rpcn_log.error("getsockname to discover local ip failed: %d", get_native_error());
|
||||
close_socket();
|
||||
return true; // still assume online
|
||||
}
|
||||
|
||||
if (host->h_addrtype != AF_INET)
|
||||
{
|
||||
use_default_ip_addr("Could only find IPv6 addresses for current host!");
|
||||
return;
|
||||
}
|
||||
|
||||
local_ip_addr = read_from_ptr<u32>(host->h_addr_list[0]);
|
||||
|
||||
// Set public address to local discovered address for now, may be updated later from RPCN socket
|
||||
public_ip_addr = local_ip_addr;
|
||||
|
||||
// nph_log.notice("discover_ip_address: IP was determined to be %s", ip_to_string(local_ip_addr));
|
||||
local_ip_addr = client_addr.sin_addr.s_addr;
|
||||
nph_log.trace("discover_ip_address: IP was determined to be %s", ip_to_string(local_ip_addr));
|
||||
close_socket();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool np_handler::discover_ether_address()
|
||||
@ -612,6 +622,14 @@ namespace np
|
||||
return is_psn_active ? SCE_NP_MANAGER_STATUS_ONLINE : SCE_NP_MANAGER_STATUS_OFFLINE;
|
||||
}
|
||||
|
||||
s32 np_handler::get_upnp_status() const
|
||||
{
|
||||
if (upnp.is_active())
|
||||
return SCE_NP_SIGNALING_NETINFO_UPNP_STATUS_VALID;
|
||||
|
||||
return SCE_NP_SIGNALING_NETINFO_UPNP_STATUS_INVALID;
|
||||
}
|
||||
|
||||
const SceNpId& np_handler::get_npid() const
|
||||
{
|
||||
return npid;
|
||||
@ -649,7 +667,7 @@ namespace np
|
||||
std::string s_npid = g_cfg_rpcn.get_npid();
|
||||
ensure(!s_npid.empty()); // It should have been generated before this
|
||||
|
||||
string_to_npid(s_npid, &npid);
|
||||
string_to_npid(s_npid, npid);
|
||||
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
|
||||
sigh.set_self_sig_info(npid);
|
||||
}
|
||||
@ -660,8 +678,8 @@ namespace np
|
||||
break;
|
||||
case np_psn_status::psn_fake:
|
||||
{
|
||||
string_to_online_name("RPCS3's user", &online_name);
|
||||
string_to_avatar_url("https://rpcs3.net/cdn/netplay/DefaultAvatar.png", &avatar_url);
|
||||
string_to_online_name("RPCS3's user", online_name);
|
||||
string_to_avatar_url("https://rpcs3.net/cdn/netplay/DefaultAvatar.png", avatar_url);
|
||||
break;
|
||||
}
|
||||
case np_psn_status::psn_rpcn:
|
||||
@ -692,8 +710,8 @@ namespace np
|
||||
|
||||
rsx::overlays::queue_message(localized_string_id::RPCN_SUCCESS_LOGGED_ON);
|
||||
|
||||
string_to_online_name(rpcn->get_online_name(), &online_name);
|
||||
string_to_avatar_url(rpcn->get_avatar_url(), &avatar_url);
|
||||
string_to_online_name(rpcn->get_online_name(), online_name);
|
||||
string_to_avatar_url(rpcn->get_avatar_url(), avatar_url);
|
||||
public_ip_addr = rpcn->get_addr_sig();
|
||||
local_ip_addr = std::bit_cast<u32, be_t<u32>>(rpcn->get_addr_local());
|
||||
|
||||
@ -930,7 +948,7 @@ namespace np
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 np_handler::generate_callback_info(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam)
|
||||
u32 np_handler::generate_callback_info(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, SceNpMatching2Event event_type)
|
||||
{
|
||||
callback_info ret;
|
||||
|
||||
@ -942,6 +960,7 @@ namespace np
|
||||
ret.ctx_id = ctx_id;
|
||||
ret.cb_arg = (optParam && optParam->cbFuncArg) ? optParam->cbFuncArg : ctx->default_match2_optparam.cbFuncArg;
|
||||
ret.cb = (optParam && optParam->cbFunc) ? optParam->cbFunc : ctx->default_match2_optparam.cbFunc;
|
||||
ret.event_type = event_type;
|
||||
|
||||
nph_log.warning("Callback used is 0x%x", ret.cb);
|
||||
|
||||
@ -953,16 +972,31 @@ namespace np
|
||||
return req_id;
|
||||
}
|
||||
|
||||
np_handler::callback_info np_handler::take_pending_request(u32 req_id)
|
||||
std::optional<np_handler::callback_info> np_handler::take_pending_request(u32 req_id)
|
||||
{
|
||||
std::lock_guard lock(mutex_pending_requests);
|
||||
|
||||
if (!pending_requests.contains(req_id))
|
||||
return std::nullopt;
|
||||
|
||||
const auto cb_info = std::move(::at32(pending_requests, req_id));
|
||||
pending_requests.erase(req_id);
|
||||
|
||||
return cb_info;
|
||||
}
|
||||
|
||||
bool np_handler::abort_request(u32 req_id)
|
||||
{
|
||||
auto cb_info_opt = take_pending_request(req_id);
|
||||
|
||||
if (!cb_info_opt)
|
||||
return false;
|
||||
|
||||
cb_info_opt->queue_callback(req_id, 0, SCE_NP_MATCHING2_ERROR_ABORTED, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
event_data& np_handler::allocate_req_result(u32 event_key, u32 max_size, u32 initial_size)
|
||||
{
|
||||
std::lock_guard lock(mutex_match2_req_results);
|
||||
@ -974,14 +1008,14 @@ namespace np
|
||||
{
|
||||
const u32 req_id = get_req_id(0);
|
||||
|
||||
// if (basic_handler)
|
||||
// {
|
||||
// sysutil_register_cb([basic_handler = this->basic_handler, req_id, basic_handler_arg = this->basic_handler_arg](ppu_thread& cb_ppu) -> s32
|
||||
// {
|
||||
// basic_handler(cb_ppu, SCE_NP_BASIC_EVENT_ADD_PLAYERS_HISTORY_RESULT, 0, req_id, basic_handler_arg);
|
||||
// return 0;
|
||||
// });
|
||||
// }
|
||||
if (basic_handler.handler_func)
|
||||
{
|
||||
sysutil_register_cb([req_id, cb = basic_handler.handler_func, cb_arg = basic_handler.handler_arg](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb(cb_ppu, SCE_NP_BASIC_EVENT_ADD_PLAYERS_HISTORY_RESULT, 0, req_id, cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
return req_id;
|
||||
}
|
||||
@ -1006,11 +1040,16 @@ namespace np
|
||||
}
|
||||
|
||||
SceNpId npid_friend;
|
||||
string_to_npid(str_friend.value(), &npid_friend);
|
||||
string_to_npid(str_friend.value(), npid_friend);
|
||||
|
||||
return {CELL_OK, npid_friend};
|
||||
}
|
||||
|
||||
std::pair<error_code, std::optional<SceNpId>> np_handler::local_get_npid(u64 room_id, u16 member_id)
|
||||
{
|
||||
return np_cache.get_npid(room_id, member_id);
|
||||
}
|
||||
|
||||
std::pair<error_code, std::optional<SceNpMatching2SessionPassword>> np_handler::local_get_room_password(SceNpMatching2RoomId room_id)
|
||||
{
|
||||
return np_cache.get_password(room_id);
|
||||
@ -1030,4 +1069,14 @@ namespace np
|
||||
{
|
||||
return np_cache.get_member_and_attrs(room_id, member_id, binattrs_list, ptr_member, addr_data, size_data);
|
||||
}
|
||||
|
||||
void np_handler::upnp_add_port_mapping(u16 internal_port, std::string_view protocol)
|
||||
{
|
||||
upnp.add_port_redir(np::ip_to_string(get_local_ip_addr()), internal_port, protocol);
|
||||
}
|
||||
|
||||
void np_handler::upnp_remove_port_mapping(u16 internal_port, std::string_view protocol)
|
||||
{
|
||||
upnp.remove_port_redir(internal_port, protocol);
|
||||
}
|
||||
} // namespace np
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "Emu/Memory/vm_ptr.h"
|
||||
#include "Emu/Cell/Modules/sceNp.h"
|
||||
#include "Emu/Cell/Modules/sceNp2.h"
|
||||
#include "Emu/Cell/Modules/cellSysutil.h"
|
||||
|
||||
#include "Emu/NP/rpcn_client.h"
|
||||
#include "Emu/NP/generated/np2_structs_generated.h"
|
||||
@ -15,6 +16,7 @@
|
||||
#include "Emu/NP/np_cache.h"
|
||||
#include "Emu/NP/np_event_data.h"
|
||||
#include "Emu/NP/np_contexts.h"
|
||||
#include "Emu/NP/upnp_handler.h"
|
||||
|
||||
namespace np
|
||||
{
|
||||
@ -83,6 +85,7 @@ namespace np
|
||||
|
||||
s32 get_psn_status() const;
|
||||
s32 get_net_status() const;
|
||||
s32 get_upnp_status() const;
|
||||
|
||||
const SceNpId& get_npid() const;
|
||||
const SceNpOnlineId& get_online_id() const;
|
||||
@ -165,6 +168,7 @@ namespace np
|
||||
void get_score_friend(std::shared_ptr<score_transaction_ctx>& trans_ctx, SceNpScoreBoardId boardId, bool include_self, vm::ptr<SceNpScoreRankData> rankArray, u32 rankArraySize, vm::ptr<SceNpScoreComment> commentArray, u32 commentArraySize, vm::ptr<void> infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr<CellRtcTick> lastSortDate, vm::ptr<SceNpScoreRankNumber> totalRecord, bool async);
|
||||
|
||||
// Local functions
|
||||
std::pair<error_code, std::optional<SceNpId>> local_get_npid(u64 room_id, u16 member_id);
|
||||
std::pair<error_code, std::optional<SceNpMatching2RoomSlotInfo>> local_get_room_slots(SceNpMatching2RoomId room_id);
|
||||
std::pair<error_code, std::optional<SceNpMatching2SessionPassword>> local_get_room_password(SceNpMatching2RoomId room_id);
|
||||
std::pair<error_code, std::vector<SceNpMatching2RoomMemberId>> local_get_room_memberids(SceNpMatching2RoomId room_id, s32 sort_method);
|
||||
@ -179,10 +183,15 @@ namespace np
|
||||
void req_ticket(u32 version, const SceNpId* npid, const char* service_id, const u8* cookie, u32 cookie_size, const char* entitlement_id, u32 consumed_count);
|
||||
const ticket& get_ticket() const;
|
||||
u32 add_players_to_history(vm::cptr<SceNpId> npids, u32 count);
|
||||
bool abort_request(u32 req_id);
|
||||
|
||||
// For signaling
|
||||
void req_sign_infos(const std::string& npid, u32 conn_id);
|
||||
|
||||
// For UPNP
|
||||
void upnp_add_port_mapping(u16 internal_port, std::string_view protocol);
|
||||
void upnp_remove_port_mapping(u16 internal_port, std::string_view protocol);
|
||||
|
||||
// For custom menu
|
||||
struct custom_menu_action
|
||||
{
|
||||
@ -205,7 +214,7 @@ namespace np
|
||||
|
||||
private:
|
||||
// Various generic helpers
|
||||
void discover_ip_address();
|
||||
bool discover_ip_address();
|
||||
bool discover_ether_address();
|
||||
bool error_and_disconnect(const std::string& error_msg);
|
||||
|
||||
@ -267,9 +276,23 @@ namespace np
|
||||
SceNpMatching2ContextId ctx_id;
|
||||
vm::ptr<SceNpMatching2RequestCallback> cb;
|
||||
vm::ptr<void> cb_arg;
|
||||
SceNpMatching2Event event_type;
|
||||
|
||||
void queue_callback(u32 req_id, u32 event_key, s32 error_code, u32 data_size) const
|
||||
{
|
||||
if (cb)
|
||||
{
|
||||
sysutil_register_cb([=, *this](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb(cb_ppu, ctx_id, req_id, event_type, event_key, error_code, data_size, cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
u32 generate_callback_info(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam);
|
||||
callback_info take_pending_request(u32 req_id);
|
||||
|
||||
u32 generate_callback_info(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, SceNpMatching2Event event_type);
|
||||
std::optional<callback_info> take_pending_request(u32 req_id);
|
||||
|
||||
shared_mutex mutex_pending_requests;
|
||||
std::unordered_map<u32, callback_info> pending_requests;
|
||||
@ -327,5 +350,8 @@ namespace np
|
||||
// RPCN
|
||||
shared_mutex mutex_rpcn;
|
||||
std::shared_ptr<rpcn::rpcn_client> rpcn;
|
||||
|
||||
// UPNP
|
||||
upnp_handler upnp;
|
||||
};
|
||||
} // namespace np
|
||||
|
@ -22,25 +22,65 @@ namespace np
|
||||
return fmt::format("%02X:%02X:%02X:%02X:%02X:%02X", ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]);
|
||||
}
|
||||
|
||||
void string_to_npid(std::string_view str, SceNpId* npid)
|
||||
void string_to_npid(std::string_view str, SceNpId& npid)
|
||||
{
|
||||
memset(npid, 0, sizeof(SceNpId));
|
||||
strcpy_trunc(npid->handle.data, str);
|
||||
memset(&npid, 0, sizeof(npid));
|
||||
strcpy_trunc(npid.handle.data, str);
|
||||
// npid->reserved[0] = 1;
|
||||
}
|
||||
|
||||
void string_to_online_name(std::string_view str, SceNpOnlineName* online_name)
|
||||
void string_to_online_name(std::string_view str, SceNpOnlineName& online_name)
|
||||
{
|
||||
strcpy_trunc(online_name->data, str);
|
||||
memset(&online_name, 0, sizeof(online_name));
|
||||
strcpy_trunc(online_name.data, str);
|
||||
}
|
||||
|
||||
void string_to_avatar_url(std::string_view str, SceNpAvatarUrl* avatar_url)
|
||||
void string_to_avatar_url(std::string_view str, SceNpAvatarUrl& avatar_url)
|
||||
{
|
||||
strcpy_trunc(avatar_url->data, str);
|
||||
memset(&avatar_url, 0, sizeof(avatar_url));
|
||||
strcpy_trunc(avatar_url.data, str);
|
||||
}
|
||||
|
||||
void string_to_communication_id(std::string_view str, SceNpCommunicationId* comm_id)
|
||||
void string_to_communication_id(std::string_view str, SceNpCommunicationId& comm_id)
|
||||
{
|
||||
strcpy_trunc(comm_id->data, str);
|
||||
memset(&comm_id, 0, sizeof(comm_id));
|
||||
strcpy_trunc(comm_id.data, str);
|
||||
}
|
||||
|
||||
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; } )
|
||||
|| npid.handle.data[16] != 0
|
||||
|| !std::all_of(npid.handle.dummy, npid.handle.dummy + 3, [](char val) { return val == 0; }) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_same_npid(const SceNpId& npid_1, const SceNpId& npid_2)
|
||||
{
|
||||
// Unknown what this constant means
|
||||
// if (id1->reserved[0] != 1 || id2->reserved[0] != 1)
|
||||
// {
|
||||
// return SCE_NP_UTIL_ERROR_INVALID_NP_ID;
|
||||
// }
|
||||
|
||||
if (strncmp(npid_1.handle.data, npid_2.handle.data, 16) == 0) // || id1->unk1[0] != id2->unk1[0])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// if (id1->unk1[1] != id2->unk1[1])
|
||||
// {
|
||||
// // If either is zero they match
|
||||
// if (id1->opt[4] && id2->opt[4])
|
||||
// {
|
||||
// return SCE_NP_UTIL_ERROR_NOT_MATCH;
|
||||
// }
|
||||
// }
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/types.hpp"
|
||||
#include "Emu/Cell/Modules/sceNp.h"
|
||||
#include "Emu/Cell/Modules/sceNp2.h"
|
||||
@ -7,8 +9,11 @@ namespace np
|
||||
std::string ip_to_string(u32 addr);
|
||||
std::string ether_to_string(std::array<u8, 6>& ether);
|
||||
|
||||
void string_to_npid(std::string_view str, SceNpId* npid);
|
||||
void string_to_online_name(std::string_view str, SceNpOnlineName* online_name);
|
||||
void string_to_avatar_url(std::string_view str, SceNpAvatarUrl* avatar_url);
|
||||
void string_to_communication_id(std::string_view str, SceNpCommunicationId* comm_id);
|
||||
void string_to_npid(std::string_view str, SceNpId& npid);
|
||||
void string_to_online_name(std::string_view str, SceNpOnlineName& online_name);
|
||||
void string_to_avatar_url(std::string_view str, SceNpAvatarUrl& avatar_url);
|
||||
void string_to_communication_id(std::string_view str, SceNpCommunicationId& comm_id);
|
||||
|
||||
bool is_valid_npid(const SceNpId& npid);
|
||||
bool is_same_npid(const SceNpId& npid_1, const SceNpId& npid_2);
|
||||
}
|
||||
|
@ -29,7 +29,8 @@ namespace np
|
||||
RoomMemberUpdateInfo_to_SceNpMatching2RoomMemberUpdateInfo(edata, update_info, notif_data);
|
||||
np_memory.shrink_allocation(edata.addr(), edata.size());
|
||||
|
||||
np_cache.add_member(room_id, notif_data->roomMemberDataInternal.get_ptr());
|
||||
if (!np_cache.add_member(room_id, notif_data->roomMemberDataInternal.get_ptr()))
|
||||
return;
|
||||
|
||||
rpcn_log.notice("Received notification that user %s(%d) joined the room(%d)", notif_data->roomMemberDataInternal->userInfo.npId.handle.data, notif_data->roomMemberDataInternal->memberId, room_id);
|
||||
extra_nps::print_room_member_data_internal(notif_data->roomMemberDataInternal.get_ptr());
|
||||
@ -60,7 +61,8 @@ namespace np
|
||||
RoomMemberUpdateInfo_to_SceNpMatching2RoomMemberUpdateInfo(edata, update_info, notif_data);
|
||||
np_memory.shrink_allocation(edata.addr(), edata.size());
|
||||
|
||||
np_cache.del_member(room_id, notif_data->roomMemberDataInternal->memberId);
|
||||
if (!np_cache.del_member(room_id, notif_data->roomMemberDataInternal->memberId))
|
||||
return;
|
||||
|
||||
rpcn_log.notice("Received notification that user %s(%d) left the room(%d)", notif_data->roomMemberDataInternal->userInfo.npId.handle.data, notif_data->roomMemberDataInternal->memberId, room_id);
|
||||
extra_nps::print_room_member_data_internal(notif_data->roomMemberDataInternal.get_ptr());
|
||||
@ -154,7 +156,8 @@ namespace np
|
||||
RoomMemberDataInternalUpdateInfo_to_SceNpMatching2RoomMemberDataInternalUpdateInfo(edata, update_info, notif_data);
|
||||
np_memory.shrink_allocation(edata.addr(), edata.size());
|
||||
|
||||
np_cache.add_member(room_id, notif_data->newRoomMemberDataInternal.get_ptr());
|
||||
if (!np_cache.add_member(room_id, notif_data->newRoomMemberDataInternal.get_ptr()))
|
||||
return;
|
||||
|
||||
rpcn_log.notice("Received notification that user's %s(%d) room (%d) data was updated", notif_data->newRoomMemberDataInternal->userInfo.npId.handle.data, notif_data->newRoomMemberDataInternal->memberId, room_id);
|
||||
extra_nps::print_room_member_data_internal(notif_data->newRoomMemberDataInternal.get_ptr());
|
||||
@ -200,22 +203,27 @@ namespace np
|
||||
|
||||
void np_handler::notif_p2p_connect(std::vector<u8>& data)
|
||||
{
|
||||
if (data.size() != 16)
|
||||
vec_stream noti(data);
|
||||
const u64 room_id = noti.get<u64>();
|
||||
const u16 member_id = noti.get<u16>();
|
||||
const u16 port_p2p = noti.get<u16>();
|
||||
const u32 addr_p2p = noti.get<u32>();
|
||||
|
||||
if (noti.is_error())
|
||||
{
|
||||
rpcn_log.error("Notification data for SignalP2PConnect != 14");
|
||||
rpcn_log.error("Received faulty SignalP2PConnect notification");
|
||||
return;
|
||||
}
|
||||
|
||||
const u64 room_id = read_from_ptr<le_t<u64>>(data);
|
||||
const u16 member_id = read_from_ptr<le_t<u16>>(data, 8);
|
||||
const u16 port_p2p = read_from_ptr<be_t<u16>>(data, 10);
|
||||
const u32 addr_p2p = read_from_ptr<le_t<u32>>(data, 12);
|
||||
auto [res, npid] = np_cache.get_npid(room_id, member_id);
|
||||
if (!npid)
|
||||
return;
|
||||
|
||||
rpcn_log.notice("Received notification to connect to member(%d) of room(%d): %s:%d", member_id, room_id, ip_to_string(addr_p2p), port_p2p);
|
||||
rpcn_log.notice("Received notification to connect to member(%d=%s) of room(%d): %s:%d", member_id, reinterpret_cast<const char*>((*npid).handle.data), room_id, ip_to_string(addr_p2p), port_p2p);
|
||||
|
||||
// Attempt Signaling
|
||||
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
|
||||
sigh.set_sig2_infos(room_id, member_id, SCE_NP_SIGNALING_CONN_STATUS_PENDING, addr_p2p, port_p2p, np_cache.get_npid(room_id, member_id));
|
||||
sigh.start_sig2(room_id, member_id);
|
||||
const u32 conn_id = sigh.init_sig2(*npid, room_id, member_id);
|
||||
sigh.start_sig(conn_id, addr_p2p, port_p2p);
|
||||
}
|
||||
} // namespace np
|
||||
|
@ -35,7 +35,7 @@ namespace np
|
||||
u32 np_handler::get_server_status(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, u16 server_id)
|
||||
{
|
||||
// TODO: actually implement interaction with server for this?
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam);
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_GetServerInfo);
|
||||
u32 event_key = get_event_key();
|
||||
|
||||
auto& edata = allocate_req_result(event_key, SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetServerInfo, sizeof(SceNpMatching2GetServerInfoResponse));
|
||||
@ -44,61 +44,38 @@ namespace np
|
||||
serv_info->server.status = SCE_NP_MATCHING2_SERVER_STATUS_AVAILABLE;
|
||||
np_memory.shrink_allocation(edata.addr(), edata.size());
|
||||
|
||||
const auto cb_info = take_pending_request(req_id);
|
||||
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=, size = edata.size()](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetServerInfo, event_key, 0, size, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
const auto cb_info_opt = take_pending_request(req_id);
|
||||
ensure(cb_info_opt);
|
||||
cb_info_opt->queue_callback(req_id, event_key, 0, edata.size());
|
||||
|
||||
return req_id;
|
||||
}
|
||||
|
||||
u32 np_handler::create_server_context(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, u16 /*server_id*/)
|
||||
{
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam);
|
||||
u32 event_key = get_event_key();
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_CreateServerContext);
|
||||
|
||||
const auto cb_info = take_pending_request(req_id);
|
||||
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_CreateServerContext, event_key, 0, 0, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
const auto cb_info_opt = take_pending_request(req_id);
|
||||
ensure(cb_info_opt);
|
||||
cb_info_opt->queue_callback(req_id, 0, 0, 0);
|
||||
|
||||
return req_id;
|
||||
}
|
||||
|
||||
u32 np_handler::delete_server_context(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, u16 /*server_id*/)
|
||||
{
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam);
|
||||
u32 event_key = get_event_key();
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_DeleteServerContext);
|
||||
|
||||
const auto cb_info = take_pending_request(req_id);
|
||||
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_DeleteServerContext, event_key, 0, 0, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
const auto cb_info_opt = take_pending_request(req_id);
|
||||
ensure(cb_info_opt);
|
||||
cb_info_opt->queue_callback(req_id, 0, 0, 0);
|
||||
|
||||
return req_id;
|
||||
}
|
||||
|
||||
u32 np_handler::get_world_list(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, u16 server_id)
|
||||
{
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam);
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_GetWorldInfoList);
|
||||
|
||||
if (!rpcn->get_world_list(req_id, get_match2_context(ctx_id)->communicationId, server_id))
|
||||
{
|
||||
@ -111,7 +88,10 @@ namespace np
|
||||
|
||||
bool np_handler::reply_get_world_list(u32 req_id, std::vector<u8>& reply_data)
|
||||
{
|
||||
const auto cb_info = take_pending_request(req_id);
|
||||
auto cb_info_opt = take_pending_request(req_id);
|
||||
|
||||
if (!cb_info_opt)
|
||||
return true;
|
||||
|
||||
vec_stream reply(reply_data, 1);
|
||||
|
||||
@ -139,31 +119,18 @@ namespace np
|
||||
for (usz i = 0; i < world_list.size(); i++)
|
||||
{
|
||||
worlds[i].worldId = world_list[i];
|
||||
worlds[i].numOfLobby = 1; // TODO
|
||||
worlds[i].maxNumOfTotalLobbyMember = 10000;
|
||||
worlds[i].curNumOfTotalLobbyMember = 1;
|
||||
worlds[i].curNumOfRoom = 1;
|
||||
worlds[i].curNumOfTotalRoomMember = 1;
|
||||
}
|
||||
}
|
||||
|
||||
np_memory.shrink_allocation(edata.addr(), edata.size());
|
||||
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=, size = edata.size()](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetWorldInfoList, event_key, 0, size, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
cb_info_opt->queue_callback(req_id, event_key, 0, edata.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 np_handler::create_join_room(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2CreateJoinRoomRequest* req)
|
||||
{
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam);
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_CreateJoinRoom);
|
||||
|
||||
extra_nps::print_createjoinroom(req);
|
||||
|
||||
@ -181,7 +148,10 @@ namespace np
|
||||
|
||||
bool np_handler::reply_create_join_room(u32 req_id, std::vector<u8>& reply_data)
|
||||
{
|
||||
const auto cb_info = take_pending_request(req_id);
|
||||
auto cb_info_opt = take_pending_request(req_id);
|
||||
|
||||
if (!cb_info_opt)
|
||||
return true;
|
||||
|
||||
vec_stream reply(reply_data, 1);
|
||||
auto* resp = reply.get_flatbuffer<RoomDataInternal>();
|
||||
@ -200,29 +170,16 @@ namespace np
|
||||
np_cache.insert_room(room_info);
|
||||
np_cache.update_password(room_resp->roomDataInternal->roomId, cached_cj_password);
|
||||
|
||||
// Establish Matching2 self signaling info
|
||||
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
|
||||
sigh.set_self_sig2_info(room_info->roomId, 1);
|
||||
sigh.set_sig2_infos(room_info->roomId, 1, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, rpcn->get_addr_sig(), rpcn->get_port_sig(), get_npid(), true);
|
||||
// TODO? Should this send a message to Signaling CB? Is this even necessary?
|
||||
|
||||
extra_nps::print_create_room_resp(room_resp);
|
||||
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=, size = edata.size()](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_CreateJoinRoom, event_key, 0, size, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
cb_info_opt->queue_callback(req_id, event_key, 0, edata.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 np_handler::join_room(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2JoinRoomRequest* req)
|
||||
{
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam);
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_JoinRoom);
|
||||
|
||||
extra_nps::print_joinroom(req);
|
||||
|
||||
@ -237,6 +194,11 @@ namespace np
|
||||
|
||||
bool np_handler::reply_join_room(u32 req_id, std::vector<u8>& reply_data)
|
||||
{
|
||||
auto cb_info_opt = take_pending_request(req_id);
|
||||
|
||||
if (!cb_info_opt)
|
||||
return true;
|
||||
|
||||
s32 error_code = 0;
|
||||
|
||||
if (rpcn::is_error(static_cast<rpcn::ErrorType>(reply_data[0])))
|
||||
@ -250,19 +212,9 @@ namespace np
|
||||
}
|
||||
}
|
||||
|
||||
const auto cb_info = take_pending_request(req_id);
|
||||
|
||||
if (error_code != 0)
|
||||
{
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_JoinRoom, 0, error_code, 0, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
cb_info_opt->queue_callback(req_id, 0, error_code, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -278,34 +230,21 @@ namespace np
|
||||
auto& edata = allocate_req_result(event_key, SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_JoinRoom, sizeof(SceNpMatching2JoinRoomResponse));
|
||||
auto* room_resp = reinterpret_cast<SceNpMatching2JoinRoomResponse*>(edata.data());
|
||||
auto* room_info = edata.allocate<SceNpMatching2RoomDataInternal>(sizeof(SceNpMatching2RoomDataInternal), room_resp->roomDataInternal);
|
||||
u16 member_id = RoomDataInternal_to_SceNpMatching2RoomDataInternal(edata, resp, room_info, npid);
|
||||
RoomDataInternal_to_SceNpMatching2RoomDataInternal(edata, resp, room_info, npid);
|
||||
np_memory.shrink_allocation(edata.addr(), edata.size());
|
||||
|
||||
np_cache.insert_room(room_info);
|
||||
|
||||
extra_nps::print_room_data_internal(room_info);
|
||||
|
||||
// Establish Matching2 self signaling info
|
||||
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
|
||||
sigh.set_self_sig2_info(room_info->roomId, member_id);
|
||||
sigh.set_sig2_infos(room_info->roomId, member_id, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, rpcn->get_addr_sig(), rpcn->get_port_sig(), get_npid(), true);
|
||||
// TODO? Should this send a message to Signaling CB? Is this even necessary?
|
||||
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=, size = edata.size()](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_JoinRoom, event_key, 0, size, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
cb_info_opt->queue_callback(req_id, event_key, 0, edata.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 np_handler::leave_room(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2LeaveRoomRequest* req)
|
||||
{
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam);
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_LeaveRoom);
|
||||
|
||||
if (!rpcn->leave_room(req_id, get_match2_context(ctx_id)->communicationId, req))
|
||||
{
|
||||
@ -318,34 +257,27 @@ namespace np
|
||||
|
||||
bool np_handler::reply_leave_room(u32 req_id, std::vector<u8>& reply_data)
|
||||
{
|
||||
const auto cb_info = take_pending_request(req_id);
|
||||
auto cb_info_opt = take_pending_request(req_id);
|
||||
|
||||
if (!cb_info_opt)
|
||||
return true;
|
||||
|
||||
vec_stream reply(reply_data, 1);
|
||||
u64 room_id = reply.get<u64>();
|
||||
if (reply.is_error())
|
||||
return error_and_disconnect("Malformed reply to LeaveRoom command");
|
||||
|
||||
u32 event_key = get_event_key(); // Unsure if necessary if there is no data
|
||||
|
||||
// Disconnect all users from that room
|
||||
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
|
||||
sigh.disconnect_sig2_users(room_id);
|
||||
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_LeaveRoom, event_key, 0, 0, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
cb_info_opt->queue_callback(req_id, 0, 0, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 np_handler::search_room(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2SearchRoomRequest* req)
|
||||
{
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam);
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_SearchRoom);
|
||||
|
||||
extra_nps::print_search_room(req);
|
||||
|
||||
@ -360,7 +292,10 @@ namespace np
|
||||
|
||||
bool np_handler::reply_search_room(u32 req_id, std::vector<u8>& reply_data)
|
||||
{
|
||||
const auto cb_info = take_pending_request(req_id);
|
||||
auto cb_info_opt = take_pending_request(req_id);
|
||||
|
||||
if (!cb_info_opt)
|
||||
return true;
|
||||
|
||||
vec_stream reply(reply_data, 1);
|
||||
auto* resp = reply.get_flatbuffer<SearchRoomResponse>();
|
||||
@ -376,22 +311,14 @@ namespace np
|
||||
np_memory.shrink_allocation(edata.addr(), edata.size());
|
||||
|
||||
extra_nps::print_search_room_resp(search_resp);
|
||||
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=, size = edata.size()](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SearchRoom, event_key, 0, size, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
cb_info_opt->queue_callback(req_id, event_key, 0, edata.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 np_handler::get_roomdata_external_list(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2GetRoomDataExternalListRequest* req)
|
||||
{
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam);
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_GetRoomDataExternalList);
|
||||
|
||||
extra_nps::print_get_roomdata_external_list_req(req);
|
||||
|
||||
@ -406,7 +333,10 @@ namespace np
|
||||
|
||||
bool np_handler::reply_get_roomdata_external_list(u32 req_id, std::vector<u8>& reply_data)
|
||||
{
|
||||
const auto cb_info = take_pending_request(req_id);
|
||||
auto cb_info_opt = take_pending_request(req_id);
|
||||
|
||||
if (!cb_info_opt)
|
||||
return true;
|
||||
|
||||
vec_stream reply(reply_data, 1);
|
||||
auto* resp = reply.get_flatbuffer<GetRoomDataExternalListResponse>();
|
||||
@ -423,21 +353,14 @@ namespace np
|
||||
|
||||
extra_nps::print_get_roomdata_external_list_resp(sce_get_room_ext_resp);
|
||||
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=, size = edata.size()](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetRoomDataExternalList, event_key, 0, size, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
cb_info_opt->queue_callback(req_id, event_key, 0, edata.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 np_handler::set_roomdata_external(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2SetRoomDataExternalRequest* req)
|
||||
{
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam);
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomDataExternal);
|
||||
|
||||
extra_nps::print_set_roomdata_ext_req(req);
|
||||
|
||||
@ -452,25 +375,19 @@ namespace np
|
||||
|
||||
bool np_handler::reply_set_roomdata_external(u32 req_id, std::vector<u8>& /*reply_data*/)
|
||||
{
|
||||
const auto cb_info = take_pending_request(req_id);
|
||||
auto cb_info_opt = take_pending_request(req_id);
|
||||
|
||||
u32 event_key = get_event_key(); // Unsure if necessary if there is no data
|
||||
if (!cb_info_opt)
|
||||
return true;
|
||||
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomDataExternal, event_key, 0, 0, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
cb_info_opt->queue_callback(req_id, 0, 0, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 np_handler::get_roomdata_internal(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2GetRoomDataInternalRequest* req)
|
||||
{
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam);
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_GetRoomDataInternal);
|
||||
|
||||
if (!rpcn->get_roomdata_internal(req_id, get_match2_context(ctx_id)->communicationId, req))
|
||||
{
|
||||
@ -483,7 +400,10 @@ namespace np
|
||||
|
||||
bool np_handler::reply_get_roomdata_internal(u32 req_id, std::vector<u8>& reply_data)
|
||||
{
|
||||
const auto cb_info = take_pending_request(req_id);
|
||||
auto cb_info_opt = take_pending_request(req_id);
|
||||
|
||||
if (!cb_info_opt)
|
||||
return true;
|
||||
|
||||
vec_stream reply(reply_data, 1);
|
||||
|
||||
@ -504,21 +424,14 @@ namespace np
|
||||
|
||||
extra_nps::print_room_data_internal(room_info);
|
||||
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=, size = edata.size()](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_GetRoomDataInternal, event_key, 0, size, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
cb_info_opt->queue_callback(req_id, event_key, 0, edata.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 np_handler::set_roomdata_internal(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2SetRoomDataInternalRequest* req)
|
||||
{
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam);
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomDataInternal);
|
||||
|
||||
// TODO: extra_nps::print_set_roomdata_req(req);
|
||||
|
||||
@ -535,25 +448,19 @@ namespace np
|
||||
|
||||
bool np_handler::reply_set_roomdata_internal(u32 req_id, std::vector<u8>& /*reply_data*/)
|
||||
{
|
||||
const auto cb_info = take_pending_request(req_id);
|
||||
auto cb_info_opt = take_pending_request(req_id);
|
||||
|
||||
u32 event_key = get_event_key(); // Unsure if necessary if there is no data
|
||||
if (!cb_info_opt)
|
||||
return true;
|
||||
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomDataInternal, event_key, 0, 0, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
cb_info_opt->queue_callback(req_id, 0, 0, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 np_handler::set_roommemberdata_internal(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2SetRoomMemberDataInternalRequest* req)
|
||||
{
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam);
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomMemberDataInternal);
|
||||
|
||||
extra_nps::print_set_roommemberdata_int_req(req);
|
||||
|
||||
@ -568,25 +475,19 @@ namespace np
|
||||
|
||||
bool np_handler::reply_set_roommemberdata_internal(u32 req_id, std::vector<u8>& /*reply_data*/)
|
||||
{
|
||||
const auto cb_info = take_pending_request(req_id);
|
||||
auto cb_info_opt = take_pending_request(req_id);
|
||||
|
||||
u32 event_key = get_event_key(); // Unsure if necessary if there is no data
|
||||
if (!cb_info_opt)
|
||||
return true;
|
||||
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SetRoomMemberDataInternal, event_key, 0, 0, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
cb_info_opt->queue_callback(req_id, 0, 0, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 np_handler::get_ping_info(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2SignalingGetPingInfoRequest* req)
|
||||
{
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam);
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_SignalingGetPingInfo);
|
||||
|
||||
if (!rpcn->ping_room_owner(req_id, get_match2_context(ctx_id)->communicationId, req->roomId))
|
||||
{
|
||||
@ -599,7 +500,10 @@ namespace np
|
||||
|
||||
bool np_handler::reply_get_ping_info(u32 req_id, std::vector<u8>& reply_data)
|
||||
{
|
||||
const auto cb_info = take_pending_request(req_id);
|
||||
auto cb_info_opt = take_pending_request(req_id);
|
||||
|
||||
if (!cb_info_opt)
|
||||
return true;
|
||||
|
||||
vec_stream reply(reply_data, 1);
|
||||
|
||||
@ -614,22 +518,14 @@ namespace np
|
||||
auto* final_ping_resp = reinterpret_cast<SceNpMatching2SignalingGetPingInfoResponse*>(edata.data());
|
||||
GetPingInfoResponse_to_SceNpMatching2SignalingGetPingInfoResponse(resp, final_ping_resp);
|
||||
np_memory.shrink_allocation(edata.addr(), edata.size());
|
||||
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=, size = edata.size()](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SignalingGetPingInfo, event_key, 0, size, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
cb_info_opt->queue_callback(req_id, event_key, 0, edata.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 np_handler::send_room_message(SceNpMatching2ContextId ctx_id, vm::cptr<SceNpMatching2RequestOptParam> optParam, const SceNpMatching2SendRoomMessageRequest* req)
|
||||
{
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam);
|
||||
u32 req_id = generate_callback_info(ctx_id, optParam, SCE_NP_MATCHING2_REQUEST_EVENT_SendRoomMessage);
|
||||
|
||||
if (!rpcn->send_room_message(req_id, get_match2_context(ctx_id)->communicationId, req))
|
||||
{
|
||||
@ -642,16 +538,12 @@ namespace np
|
||||
|
||||
bool np_handler::reply_send_room_message(u32 req_id, std::vector<u8>& /*reply_data*/)
|
||||
{
|
||||
const auto cb_info = take_pending_request(req_id);
|
||||
auto cb_info_opt = take_pending_request(req_id);
|
||||
|
||||
if (cb_info.cb)
|
||||
{
|
||||
sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
cb_info.cb(cb_ppu, cb_info.ctx_id, req_id, SCE_NP_MATCHING2_REQUEST_EVENT_SendRoomMessage, 0, 0, 0, cb_info.cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
if (!cb_info_opt)
|
||||
return true;
|
||||
|
||||
cb_info_opt->queue_callback(req_id, 0, 0, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1112,8 +1004,8 @@ namespace np
|
||||
cur_rank = &rankPlayerArray[i].rankData;
|
||||
}
|
||||
|
||||
string_to_npid(fb_rankdata->npId()->string_view(), &cur_rank->npId);
|
||||
string_to_online_name(fb_rankdata->onlineName()->string_view(), &cur_rank->onlineName);
|
||||
string_to_npid(fb_rankdata->npId()->string_view(), cur_rank->npId);
|
||||
string_to_online_name(fb_rankdata->onlineName()->string_view(), cur_rank->onlineName);
|
||||
|
||||
cur_rank->pcId = fb_rankdata->pcId();
|
||||
cur_rank->serialRank = fb_rankdata->rank();
|
||||
|
@ -18,6 +18,7 @@ namespace extra_nps
|
||||
|
||||
void print_sigoptparam(const SceNpMatching2SignalingOptParam* opt)
|
||||
{
|
||||
sceNp2.warning("SceNpMatching2SignalingOptParam:");
|
||||
sceNp2.warning("type: %d", opt->type);
|
||||
sceNp2.warning("flag: %d", opt->flag);
|
||||
sceNp2.warning("hubMemberId: %d", opt->hubMemberId);
|
||||
@ -227,7 +228,10 @@ namespace extra_nps
|
||||
sceNp2.warning("curMemberNum: %d", room->curMemberNum);
|
||||
sceNp2.warning("SceNpMatching2RoomPasswordSlotMask: 0x%x", room->passwordSlotMask);
|
||||
sceNp2.warning("owner: *0x%x", room->owner);
|
||||
|
||||
if (room->owner)
|
||||
print_userinfo2(room->owner.get_ptr());
|
||||
|
||||
sceNp2.warning("roomGroup: *0x%x", room->roomGroup);
|
||||
// TODO: print roomGroup
|
||||
sceNp2.warning("roomGroupNum: %d", room->roomGroupNum);
|
||||
|
@ -71,7 +71,7 @@ namespace rpcn
|
||||
return get_localized_string(rpcn_state_to_localized_string_id(state));
|
||||
}
|
||||
|
||||
constexpr u32 RPCN_PROTOCOL_VERSION = 18;
|
||||
constexpr u32 RPCN_PROTOCOL_VERSION = 19;
|
||||
constexpr usz RPCN_HEADER_SIZE = 15;
|
||||
constexpr usz COMMUNICATION_ID_SIZE = 9;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "rpcn_config.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Utilities/File.h"
|
||||
|
||||
cfg_rpcn g_cfg_rpcn;
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "Emu/Cell/Modules/cellSysutil.h"
|
||||
#include "np_handler.h"
|
||||
#include "Emu/NP/vport0.h"
|
||||
#include "Emu/NP/np_helpers.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
@ -102,17 +103,15 @@ void signaling_handler::signal_ext_sig_callback(u32 conn_id, int event) const
|
||||
|
||||
void signaling_handler::signal_sig2_callback(u64 room_id, u16 member_id, SceNpMatching2Event event) const
|
||||
{
|
||||
// Signal the callback
|
||||
if (sig2_cb)
|
||||
if (room_id && sig2_cb)
|
||||
{
|
||||
sysutil_register_cb([sig2_cb = this->sig2_cb, sig2_cb_ctx = this->sig2_cb_ctx, room_id, member_id, event, sig2_cb_arg = this->sig2_cb_arg](ppu_thread& cb_ppu) -> s32
|
||||
{
|
||||
sig2_cb(cb_ppu, sig2_cb_ctx, room_id, member_id, event, 0, sig2_cb_arg);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
sign_log.notice("Called sig2 CB: 0x%x (room_id: %d, member_id: %d)", event, room_id, member_id);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
@ -164,9 +163,21 @@ bool signaling_handler::validate_signaling_packet(const signaling_packet* sp)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sp->version != 1u && sp->version != 2u)
|
||||
if (sp->version != SIGNALING_VERSION)
|
||||
{
|
||||
sign_log.error("Invalid version in signaling packet");
|
||||
sign_log.error("Invalid version in signaling packet: %d, expected: %d", sp->version, SIGNALING_VERSION);
|
||||
|
||||
if (sp->version > SIGNALING_VERSION)
|
||||
sign_log.error("You are most likely using an outdated version of RPCS3");
|
||||
else
|
||||
sign_log.error("The other user is most likely using an outdated version of RPCS3");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!np::is_valid_npid(sp->npid))
|
||||
{
|
||||
sign_log.error("Invalid npid in signaling packet");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -187,57 +198,36 @@ void signaling_handler::process_incoming_messages()
|
||||
|
||||
auto op_addr = msg.src_addr;
|
||||
auto op_port = msg.src_port;
|
||||
auto* sp = reinterpret_cast<const signaling_packet*>(msg.data.data());
|
||||
const auto* sp = reinterpret_cast<const signaling_packet*>(msg.data.data());
|
||||
|
||||
if (!validate_signaling_packet(sp))
|
||||
continue;
|
||||
|
||||
if (sign_log.trace)
|
||||
{
|
||||
in_addr addr;
|
||||
in_addr addr{};
|
||||
addr.s_addr = op_addr;
|
||||
|
||||
if (sp->version == 1u)
|
||||
{
|
||||
char npid_buf[17]{};
|
||||
memcpy(npid_buf, sp->V1.npid.handle.data, 16);
|
||||
std::string npid(npid_buf);
|
||||
|
||||
char ip_str[16];
|
||||
inet_ntop(AF_INET, &addr, ip_str, sizeof(ip_str));
|
||||
std::string_view npid(sp->npid.handle.data);
|
||||
|
||||
sign_log.trace("sig1 %s from %s:%d(%s)", sp->command, ip_str, op_port, npid);
|
||||
}
|
||||
else
|
||||
{
|
||||
char inet_addr[16];
|
||||
const char* inet_addr_string = inet_ntop(AF_INET, &addr, inet_addr, sizeof(inet_addr));
|
||||
|
||||
sign_log.trace("sig2 %s from %s:%d(%d:%d)", sp->command, inet_addr_string, op_port, sp->V2.room_id, sp->V2.member_id);
|
||||
}
|
||||
sign_log.trace("SP %s from %s:%d(npid: %s)", sp->command, ip_str, op_port, npid);
|
||||
}
|
||||
|
||||
bool reply = false, schedule_repeat = false;
|
||||
auto& sent_packet = sp->version == 1u ? sig1_packet : sig2_packet;
|
||||
auto& sent_packet = sig_packet;
|
||||
|
||||
// Get signaling info for user to know if we should even bother looking further
|
||||
auto si = get_signaling_ptr(sp);
|
||||
|
||||
if (!si && sp->version == 1u && sp->command == signal_connect)
|
||||
if (!si && sp->command == signal_connect)
|
||||
{
|
||||
// Connection can be remotely established and not mutual
|
||||
const u32 conn_id = create_sig_infos(&sp->V1.npid);
|
||||
si = ::at32(sig1_peers, conn_id);
|
||||
// Activate the connection without triggering the main CB
|
||||
si->connStatus = SCE_NP_SIGNALING_CONN_STATUS_ACTIVE;
|
||||
si->addr = op_addr;
|
||||
si->port = op_port;
|
||||
si->ext_status = ext_sign_peer;
|
||||
// Notify extended callback that peer activated
|
||||
signal_ext_sig_callback(conn_id, SCE_NP_SIGNALING_EVENT_EXT_PEER_ACTIVATED);
|
||||
const u32 conn_id = get_always_conn_id(sp->npid);
|
||||
si = ::at32(sig_peers, conn_id);
|
||||
}
|
||||
|
||||
if (!si || (si->connStatus == SCE_NP_SIGNALING_CONN_STATUS_INACTIVE && sp->command != signal_finished))
|
||||
if (!si && sp->command != signal_finished)
|
||||
{
|
||||
// User is unknown to us or the connection is inactive
|
||||
// Ignore packet unless it's a finished packet in case the finished_ack wasn't received by opponent
|
||||
@ -300,7 +290,7 @@ void signaling_handler::process_incoming_messages()
|
||||
sent_packet.command = signal_connect_ack;
|
||||
sent_packet.timestamp_sender = sp->timestamp_sender;
|
||||
sent_packet.timestamp_receiver = now.time_since_epoch().count();
|
||||
// connection is established
|
||||
update_si_addr(si, op_addr, op_port);
|
||||
break;
|
||||
case signal_connect_ack:
|
||||
update_rtt(sp->timestamp_sender);
|
||||
@ -310,7 +300,6 @@ void signaling_handler::process_incoming_messages()
|
||||
sent_packet.command = signal_confirm;
|
||||
sent_packet.timestamp_receiver = now.time_since_epoch().count();
|
||||
retire_packet(si, signal_connect);
|
||||
// connection is active
|
||||
update_si_addr(si, op_addr, op_port);
|
||||
update_si_mapped_addr(si, sp->sent_addr, sp->sent_port);
|
||||
update_si_status(si, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE);
|
||||
@ -321,21 +310,20 @@ void signaling_handler::process_incoming_messages()
|
||||
schedule_repeat = false;
|
||||
setup_ping();
|
||||
retire_packet(si, signal_connect_ack);
|
||||
// connection is active
|
||||
update_si_addr(si, op_addr, op_port);
|
||||
update_si_mapped_addr(si, sp->sent_addr, sp->sent_port);
|
||||
update_si_status(si, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, true);
|
||||
update_ext_si_status(si, true);
|
||||
break;
|
||||
case signal_finished:
|
||||
reply = true;
|
||||
schedule_repeat = false;
|
||||
sent_packet.command = signal_finished_ack;
|
||||
// terminate connection
|
||||
update_si_status(si, SCE_NP_SIGNALING_CONN_STATUS_INACTIVE);
|
||||
update_ext_si_status(si, false);
|
||||
break;
|
||||
case signal_finished_ack:
|
||||
reply = false;
|
||||
schedule_repeat = false;
|
||||
update_si_status(si, SCE_NP_SIGNALING_CONN_STATUS_INACTIVE);
|
||||
retire_packet(si, signal_finished);
|
||||
break;
|
||||
default: sign_log.error("Invalid signaling command received"); continue;
|
||||
@ -369,37 +357,39 @@ void signaling_handler::operator()()
|
||||
|
||||
for (auto it = qpackets.begin(); it != qpackets.end();)
|
||||
{
|
||||
if (it->first > now)
|
||||
auto& [timestamp, sig] = *it;
|
||||
|
||||
if (timestamp > now)
|
||||
break;
|
||||
|
||||
if (it->second.sig_info->time_last_msg_recvd < now - 60s)
|
||||
if (sig.sig_info->time_last_msg_recvd < now - 60s)
|
||||
{
|
||||
// We had no connection to opponent for 60 seconds, consider the connection dead
|
||||
sign_log.trace("Timeout disconnection");
|
||||
update_si_status(it->second.sig_info, SCE_NP_SIGNALING_CONN_STATUS_INACTIVE);
|
||||
break; // qpackets will be emptied of all packets from this user so we're requeuing
|
||||
sign_log.notice("Timeout disconnection");
|
||||
update_si_status(sig.sig_info, SCE_NP_SIGNALING_CONN_STATUS_INACTIVE);
|
||||
break; // qpackets will be emptied of all packets for this user so we're requeuing
|
||||
}
|
||||
|
||||
// Update the timestamp if necessary
|
||||
switch (it->second.packet.command)
|
||||
switch (sig.packet.command)
|
||||
{
|
||||
case signal_connect:
|
||||
case signal_ping:
|
||||
it->second.packet.timestamp_sender = now.time_since_epoch().count();
|
||||
sig.packet.timestamp_sender = now.time_since_epoch().count();
|
||||
break;
|
||||
case signal_connect_ack:
|
||||
it->second.packet.timestamp_receiver = now.time_since_epoch().count();
|
||||
sig.packet.timestamp_receiver = now.time_since_epoch().count();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Resend the packet
|
||||
send_signaling_packet(it->second.packet, it->second.sig_info->addr, it->second.sig_info->port);
|
||||
send_signaling_packet(sig.packet, sig.sig_info->addr, sig.sig_info->port);
|
||||
|
||||
// Reschedule another packet
|
||||
SignalingCommand cmd = it->second.packet.command;
|
||||
auto& si = it->second.sig_info;
|
||||
SignalingCommand cmd = sig.packet.command;
|
||||
auto& si = sig.sig_info;
|
||||
|
||||
std::chrono::milliseconds delay(500);
|
||||
switch (cmd)
|
||||
@ -441,6 +431,8 @@ void signaling_handler::update_si_addr(std::shared_ptr<signaling_info>& si, u32
|
||||
ensure(si);
|
||||
|
||||
if (si->addr != new_addr || si->port != new_port)
|
||||
{
|
||||
if (sign_log.trace)
|
||||
{
|
||||
in_addr addr_old, addr_new;
|
||||
addr_old.s_addr = si->addr;
|
||||
@ -452,6 +444,8 @@ void signaling_handler::update_si_addr(std::shared_ptr<signaling_info>& si, u32
|
||||
inet_ntop(AF_INET, &addr_new, ip_str_new, sizeof(ip_str_new));
|
||||
|
||||
sign_log.trace("Updated Address from %s:%d to %s:%d", ip_str_old, si->port, ip_str_new, new_port);
|
||||
}
|
||||
|
||||
si->addr = new_addr;
|
||||
si->port = new_port;
|
||||
}
|
||||
@ -461,7 +455,9 @@ void signaling_handler::update_si_mapped_addr(std::shared_ptr<signaling_info>& s
|
||||
{
|
||||
ensure(si);
|
||||
|
||||
if (si->addr != new_addr || si->port != new_port)
|
||||
if (si->mapped_addr != new_addr || si->mapped_port != new_port)
|
||||
{
|
||||
if (sign_log.trace)
|
||||
{
|
||||
in_addr addr_old, addr_new;
|
||||
addr_old.s_addr = si->mapped_addr;
|
||||
@ -473,59 +469,60 @@ void signaling_handler::update_si_mapped_addr(std::shared_ptr<signaling_info>& s
|
||||
inet_ntop(AF_INET, &addr_new, ip_str_new, sizeof(ip_str_new));
|
||||
|
||||
sign_log.trace("Updated Mapped Address from %s:%d to %s:%d", ip_str_old, si->mapped_port, ip_str_new, new_port);
|
||||
}
|
||||
|
||||
si->mapped_addr = new_addr;
|
||||
si->mapped_port = new_port;
|
||||
}
|
||||
}
|
||||
|
||||
void signaling_handler::update_si_status(std::shared_ptr<signaling_info>& si, s32 new_status, bool confirm_packet)
|
||||
void signaling_handler::update_si_status(std::shared_ptr<signaling_info>& si, s32 new_status)
|
||||
{
|
||||
if (!si)
|
||||
return;
|
||||
|
||||
if (si->connStatus == SCE_NP_SIGNALING_CONN_STATUS_PENDING && new_status == SCE_NP_SIGNALING_CONN_STATUS_ACTIVE)
|
||||
if (si->conn_status == SCE_NP_SIGNALING_CONN_STATUS_PENDING && new_status == SCE_NP_SIGNALING_CONN_STATUS_ACTIVE)
|
||||
{
|
||||
si->connStatus = SCE_NP_SIGNALING_CONN_STATUS_ACTIVE;
|
||||
ensure(si->version == 1u || si->version == 2u);
|
||||
if (si->version == 1u)
|
||||
si->conn_status = SCE_NP_SIGNALING_CONN_STATUS_ACTIVE;
|
||||
|
||||
signal_sig_callback(si->conn_id, SCE_NP_SIGNALING_EVENT_ESTABLISHED);
|
||||
else
|
||||
signal_sig2_callback(si->room_id, si->member_id, SCE_NP_MATCHING2_SIGNALING_EVENT_Established);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((si->connStatus == SCE_NP_SIGNALING_CONN_STATUS_PENDING || si->connStatus == SCE_NP_SIGNALING_CONN_STATUS_ACTIVE) && new_status == SCE_NP_SIGNALING_CONN_STATUS_INACTIVE)
|
||||
{
|
||||
si->connStatus = SCE_NP_SIGNALING_CONN_STATUS_INACTIVE;
|
||||
ensure(si->version == 1u || si->version == 2u);
|
||||
if (si->version == 1u)
|
||||
signal_sig_callback(si->conn_id, SCE_NP_SIGNALING_EVENT_DEAD);
|
||||
else
|
||||
signal_sig2_callback(si->room_id, si->member_id, SCE_NP_MATCHING2_SIGNALING_EVENT_Dead);
|
||||
|
||||
retire_all_packets(si);
|
||||
return;
|
||||
}
|
||||
|
||||
if (confirm_packet && si->version == 1u && si->ext_status == ext_sign_none)
|
||||
{
|
||||
si->ext_status = ext_sign_mutual;
|
||||
if (si->op_activated)
|
||||
signal_ext_sig_callback(si->conn_id, SCE_NP_SIGNALING_EVENT_EXT_MUTUAL_ACTIVATED);
|
||||
}
|
||||
else if ((si->conn_status == SCE_NP_SIGNALING_CONN_STATUS_PENDING || si->conn_status == SCE_NP_SIGNALING_CONN_STATUS_ACTIVE) && new_status == SCE_NP_SIGNALING_CONN_STATUS_INACTIVE)
|
||||
{
|
||||
si->conn_status = SCE_NP_SIGNALING_CONN_STATUS_INACTIVE;
|
||||
signal_sig_callback(si->conn_id, SCE_NP_SIGNALING_EVENT_DEAD);
|
||||
signal_sig2_callback(si->room_id, si->member_id, SCE_NP_MATCHING2_SIGNALING_EVENT_Dead);
|
||||
retire_all_packets(si);
|
||||
}
|
||||
}
|
||||
|
||||
void signaling_handler::update_ext_si_status(std::shared_ptr<signaling_info>& si, bool op_activated)
|
||||
{
|
||||
if (op_activated && !si->op_activated)
|
||||
{
|
||||
si->op_activated = true;
|
||||
|
||||
if (si->conn_status != SCE_NP_SIGNALING_CONN_STATUS_ACTIVE)
|
||||
signal_ext_sig_callback(si->conn_id, SCE_NP_SIGNALING_EVENT_EXT_PEER_ACTIVATED);
|
||||
else
|
||||
signal_ext_sig_callback(si->conn_id, SCE_NP_SIGNALING_EVENT_EXT_MUTUAL_ACTIVATED);
|
||||
}
|
||||
else if (!op_activated && si->op_activated)
|
||||
{
|
||||
si->op_activated = false;
|
||||
|
||||
signal_ext_sig_callback(si->conn_id, SCE_NP_SIGNALING_EVENT_EXT_PEER_DEACTIVATED);
|
||||
}
|
||||
}
|
||||
|
||||
void signaling_handler::set_self_sig_info(SceNpId& npid)
|
||||
{
|
||||
std::lock_guard lock(data_mutex);
|
||||
sig1_packet.V1.npid = npid;
|
||||
}
|
||||
|
||||
void signaling_handler::set_self_sig2_info(u64 room_id, u16 member_id)
|
||||
{
|
||||
std::lock_guard lock(data_mutex);
|
||||
sig2_packet.V2.room_id = room_id;
|
||||
sig2_packet.V2.member_id = member_id;
|
||||
sig_packet.npid = npid;
|
||||
}
|
||||
|
||||
void signaling_handler::send_signaling_packet(signaling_packet& sp, u32 addr, u16 port) const
|
||||
@ -564,49 +561,35 @@ void signaling_handler::queue_signaling_packet(signaling_packet& sp, std::shared
|
||||
|
||||
std::shared_ptr<signaling_info> signaling_handler::get_signaling_ptr(const signaling_packet* sp)
|
||||
{
|
||||
// V1
|
||||
if (sp->version == 1u)
|
||||
{
|
||||
u32 conn_id;
|
||||
|
||||
char npid_buf[17]{};
|
||||
memcpy(npid_buf, sp->V1.npid.handle.data, 16);
|
||||
memcpy(npid_buf, sp->npid.handle.data, 16);
|
||||
std::string npid(npid_buf);
|
||||
|
||||
if (!npid_to_conn_id.contains(npid))
|
||||
return nullptr;
|
||||
|
||||
const u32 conn_id = ::at32(npid_to_conn_id, npid);
|
||||
if (!sig1_peers.contains(conn_id))
|
||||
conn_id = ::at32(npid_to_conn_id, npid);
|
||||
|
||||
if (!sig_peers.contains(conn_id))
|
||||
{
|
||||
sign_log.error("Discrepancy in signaling 1 data");
|
||||
sign_log.error("Discrepancy in signaling data");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ::at32(sig1_peers, conn_id);
|
||||
}
|
||||
|
||||
// V2
|
||||
auto room_id = sp->V2.room_id;
|
||||
auto member_id = sp->V2.member_id;
|
||||
if (!sig2_peers.contains(room_id) || !::at32(sig2_peers, room_id).contains(member_id))
|
||||
return nullptr;
|
||||
|
||||
return ::at32(::at32(sig2_peers, room_id), member_id);
|
||||
return ::at32(sig_peers, conn_id);
|
||||
}
|
||||
|
||||
void signaling_handler::start_sig(u32 conn_id, u32 addr, u16 port)
|
||||
{
|
||||
std::lock_guard lock(data_mutex);
|
||||
start_sig_nl(conn_id, addr, port);
|
||||
}
|
||||
|
||||
void signaling_handler::start_sig_nl(u32 conn_id, u32 addr, u16 port)
|
||||
{
|
||||
auto& sent_packet = sig1_packet;
|
||||
auto& sent_packet = sig_packet;
|
||||
sent_packet.command = signal_connect;
|
||||
sent_packet.timestamp_sender = steady_clock::now().time_since_epoch().count();
|
||||
|
||||
ensure(sig1_peers.contains(conn_id));
|
||||
std::shared_ptr<signaling_info> si = ::at32(sig1_peers, conn_id);
|
||||
ensure(sig_peers.contains(conn_id));
|
||||
std::shared_ptr<signaling_info> si = ::at32(sig_peers, conn_id);
|
||||
|
||||
si->addr = addr;
|
||||
si->port = port;
|
||||
@ -616,133 +599,113 @@ void signaling_handler::start_sig_nl(u32 conn_id, u32 addr, u16 port)
|
||||
wake_up();
|
||||
}
|
||||
|
||||
void signaling_handler::stop_sig_nl(u32 conn_id)
|
||||
{
|
||||
if (!sig_peers.contains(conn_id))
|
||||
return;
|
||||
|
||||
auto& sent_packet = sig_packet;
|
||||
sent_packet.command = signal_finished;
|
||||
|
||||
std::shared_ptr<signaling_info> si = ::at32(sig_peers, conn_id);
|
||||
|
||||
send_signaling_packet(sent_packet, si->addr, si->port);
|
||||
queue_signaling_packet(sent_packet, std::move(si), steady_clock::now() + REPEAT_FINISHED_DELAY);
|
||||
}
|
||||
|
||||
void signaling_handler::stop_sig(u32 conn_id)
|
||||
{
|
||||
std::lock_guard lock(data_mutex);
|
||||
|
||||
if (!sig1_peers.contains(conn_id))
|
||||
return;
|
||||
|
||||
auto& sent_packet = sig1_packet;
|
||||
sent_packet.command = signal_finished;
|
||||
|
||||
std::shared_ptr<signaling_info> si = ::at32(sig1_peers, conn_id);
|
||||
|
||||
send_signaling_packet(sent_packet, si->addr, si->port);
|
||||
queue_signaling_packet(sent_packet, si, steady_clock::now() + REPEAT_FINISHED_DELAY);
|
||||
}
|
||||
|
||||
void signaling_handler::start_sig2(u64 room_id, u16 member_id)
|
||||
{
|
||||
std::lock_guard lock(data_mutex);
|
||||
|
||||
auto& sent_packet = sig2_packet;
|
||||
sent_packet.command = signal_connect;
|
||||
sent_packet.timestamp_sender = steady_clock::now().time_since_epoch().count();
|
||||
|
||||
ensure(sig2_peers.contains(room_id));
|
||||
const auto& sp = ::at32(sig2_peers, room_id);
|
||||
|
||||
ensure(sp.contains(member_id));
|
||||
std::shared_ptr<signaling_info> si = ::at32(sp, member_id);
|
||||
|
||||
send_signaling_packet(sent_packet, si->addr, si->port);
|
||||
queue_signaling_packet(sent_packet, si, steady_clock::now() + REPEAT_CONNECT_DELAY);
|
||||
wake_up();
|
||||
stop_sig_nl(conn_id);
|
||||
}
|
||||
|
||||
void signaling_handler::disconnect_sig2_users(u64 room_id)
|
||||
{
|
||||
std::lock_guard lock(data_mutex);
|
||||
|
||||
if (!sig2_peers.contains(room_id))
|
||||
return;
|
||||
|
||||
auto& sent_packet = sig2_packet;
|
||||
|
||||
sent_packet.command = signal_finished;
|
||||
|
||||
for (const auto& member : ::at32(sig2_peers, room_id))
|
||||
for (auto& [conn_id, si] : sig_peers)
|
||||
{
|
||||
auto& si = member.second;
|
||||
if (si->connStatus != SCE_NP_SIGNALING_CONN_STATUS_INACTIVE && !si->self)
|
||||
if (si->room_id == room_id)
|
||||
{
|
||||
send_signaling_packet(sent_packet, si->addr, si->port);
|
||||
queue_signaling_packet(sent_packet, si, steady_clock::now() + REPEAT_FINISHED_DELAY);
|
||||
stop_sig_nl(conn_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 signaling_handler::create_sig_infos(const SceNpId* npid)
|
||||
u32 signaling_handler::get_always_conn_id(const SceNpId& npid)
|
||||
{
|
||||
ensure(npid->handle.data[16] == 0);
|
||||
std::string npid_str(reinterpret_cast<const char*>(npid->handle.data));
|
||||
|
||||
std::string npid_str(reinterpret_cast<const char*>(npid.handle.data));
|
||||
if (npid_to_conn_id.contains(npid_str))
|
||||
{
|
||||
return ::at32(npid_to_conn_id, npid_str);
|
||||
}
|
||||
|
||||
const u32 conn_id = cur_conn_id++;
|
||||
npid_to_conn_id.emplace(npid_str, conn_id);
|
||||
sig1_peers.emplace(conn_id, std::make_shared<signaling_info>());
|
||||
::at32(sig1_peers, conn_id)->version = 1;
|
||||
::at32(sig1_peers, conn_id)->conn_id = conn_id;
|
||||
::at32(sig1_peers, conn_id)->npid = *npid;
|
||||
npid_to_conn_id.emplace(std::move(npid_str), conn_id);
|
||||
sig_peers.emplace(conn_id, std::make_shared<signaling_info>());
|
||||
auto& si = ::at32(sig_peers, conn_id);
|
||||
si->conn_id = conn_id;
|
||||
si->npid = npid;
|
||||
|
||||
return conn_id;
|
||||
}
|
||||
|
||||
u32 signaling_handler::init_sig_infos(const SceNpId* npid)
|
||||
u32 signaling_handler::init_sig1(const SceNpId& npid)
|
||||
{
|
||||
std::lock_guard lock(data_mutex);
|
||||
|
||||
const u32 conn_id = create_sig_infos(npid);
|
||||
const u32 conn_id = get_always_conn_id(npid);
|
||||
|
||||
if (sig1_peers[conn_id]->connStatus == SCE_NP_SIGNALING_CONN_STATUS_INACTIVE)
|
||||
if (sig_peers[conn_id]->conn_status == SCE_NP_SIGNALING_CONN_STATUS_INACTIVE)
|
||||
{
|
||||
sign_log.trace("Creating new sig1 connection and requesting infos from RPCN");
|
||||
sig1_peers[conn_id]->connStatus = SCE_NP_SIGNALING_CONN_STATUS_PENDING;
|
||||
sig_peers[conn_id]->conn_status = SCE_NP_SIGNALING_CONN_STATUS_PENDING;
|
||||
|
||||
// Request peer infos from RPCN
|
||||
std::string npid_str(reinterpret_cast<const char*>(npid->handle.data));
|
||||
std::string npid_str(reinterpret_cast<const char*>(npid.handle.data));
|
||||
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||
nph.req_sign_infos(npid_str, conn_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Connection already exists(from passive connection)
|
||||
if (sig1_peers[conn_id]->connStatus == SCE_NP_SIGNALING_CONN_STATUS_ACTIVE && sig1_peers[conn_id]->ext_status == ext_sign_peer)
|
||||
{
|
||||
sign_log.trace("Activating already peer activated connection");
|
||||
sig1_peers[conn_id]->ext_status = ext_sign_mutual;
|
||||
start_sig_nl(conn_id, sig1_peers[conn_id]->addr, sig1_peers[conn_id]->port);
|
||||
signal_sig_callback(conn_id, SCE_NP_SIGNALING_EVENT_ESTABLISHED);
|
||||
signal_ext_sig_callback(conn_id, SCE_NP_SIGNALING_EVENT_EXT_MUTUAL_ACTIVATED);
|
||||
}
|
||||
}
|
||||
|
||||
return conn_id;
|
||||
}
|
||||
|
||||
signaling_info signaling_handler::get_sig_infos(u32 conn_id)
|
||||
u32 signaling_handler::init_sig2(const SceNpId& npid, u64 room_id, u16 member_id)
|
||||
{
|
||||
std::lock_guard lock(data_mutex);
|
||||
return *sig1_peers[conn_id];
|
||||
u32 conn_id = get_always_conn_id(npid);
|
||||
auto& si = ::at32(sig_peers, conn_id);
|
||||
si->room_id = room_id;
|
||||
si->member_id = member_id;
|
||||
si->conn_status = SCE_NP_SIGNALING_CONN_STATUS_PENDING;
|
||||
|
||||
return conn_id;
|
||||
}
|
||||
|
||||
std::optional<u32> signaling_handler::get_conn_id_from_npid(const SceNpId* npid)
|
||||
std::optional<u32> signaling_handler::get_conn_id_from_npid(const SceNpId& npid)
|
||||
{
|
||||
std::lock_guard lock(data_mutex);
|
||||
// Diff behaviour here depending on SDK version, 420+ always succeeds
|
||||
return create_sig_infos(npid);
|
||||
|
||||
std::string npid_str(reinterpret_cast<const char*>(npid.handle.data));
|
||||
if (npid_to_conn_id.contains(npid_str))
|
||||
return ::at32(npid_to_conn_id, npid_str);
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<signaling_info> signaling_handler::get_sig_infos(u32 conn_id)
|
||||
{
|
||||
std::lock_guard lock(data_mutex);
|
||||
if (sig_peers.contains(conn_id))
|
||||
return *::at32(sig_peers, conn_id);
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<u32> signaling_handler::get_conn_id_from_addr(u32 addr, u16 port)
|
||||
{
|
||||
std::lock_guard lock(data_mutex);
|
||||
|
||||
for (const auto& [conn_id, conn_info] : sig1_peers)
|
||||
for (const auto& [conn_id, conn_info] : sig_peers)
|
||||
{
|
||||
if (conn_info && std::bit_cast<u32, be_t<u32>>(conn_info->addr) == addr && conn_info->port == port)
|
||||
{
|
||||
@ -752,36 +715,3 @@ std::optional<u32> signaling_handler::get_conn_id_from_addr(u32 addr, u16 port)
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void signaling_handler::set_sig2_infos(u64 room_id, u16 member_id, s32 status, u32 addr, u16 port, const SceNpId& npid, bool self)
|
||||
{
|
||||
std::lock_guard lock(data_mutex);
|
||||
if (!sig2_peers[room_id][member_id])
|
||||
sig2_peers[room_id][member_id] = std::make_shared<signaling_info>();
|
||||
|
||||
auto& peer = sig2_peers[room_id][member_id];
|
||||
peer->connStatus = status;
|
||||
peer->addr = addr;
|
||||
peer->port = port;
|
||||
peer->self = self;
|
||||
peer->version = 2;
|
||||
peer->room_id = room_id;
|
||||
peer->member_id = member_id;
|
||||
peer->npid = npid;
|
||||
}
|
||||
|
||||
signaling_info signaling_handler::get_sig2_infos(u64 room_id, u16 member_id)
|
||||
{
|
||||
std::lock_guard lock(data_mutex);
|
||||
|
||||
if (!sig2_peers[room_id][member_id])
|
||||
{
|
||||
sig2_peers[room_id][member_id] = std::make_shared<signaling_info>();
|
||||
auto& peer = sig2_peers[room_id][member_id];
|
||||
peer->room_id = room_id;
|
||||
peer->member_id = member_id;
|
||||
peer->version = 2;
|
||||
}
|
||||
|
||||
return *sig2_peers[room_id][member_id];
|
||||
}
|
||||
|
@ -9,16 +9,9 @@
|
||||
#include <chrono>
|
||||
#include <optional>
|
||||
|
||||
enum ext_signaling_status : u8
|
||||
{
|
||||
ext_sign_none = 0,
|
||||
ext_sign_peer = 1,
|
||||
ext_sign_mutual = 2,
|
||||
};
|
||||
|
||||
struct signaling_info
|
||||
{
|
||||
s32 connStatus = SCE_NP_SIGNALING_CONN_STATUS_INACTIVE;
|
||||
s32 conn_status = SCE_NP_SIGNALING_CONN_STATUS_INACTIVE;
|
||||
u32 addr = 0;
|
||||
u16 port = 0;
|
||||
|
||||
@ -29,12 +22,11 @@ struct signaling_info
|
||||
// For handler
|
||||
steady_clock::time_point time_last_msg_recvd = steady_clock::now();
|
||||
bool self = false;
|
||||
u32 version = 0;
|
||||
SceNpId npid{};
|
||||
|
||||
// Signaling
|
||||
u32 conn_id = 0;
|
||||
ext_signaling_status ext_status = ext_sign_none;
|
||||
bool op_activated = false;
|
||||
|
||||
// Matching2
|
||||
u64 room_id = 0;
|
||||
@ -68,16 +60,13 @@ public:
|
||||
signaling_handler& operator=(thread_state);
|
||||
|
||||
void set_self_sig_info(SceNpId& npid);
|
||||
void set_self_sig2_info(u64 room_id, u16 member_id);
|
||||
|
||||
u32 init_sig_infos(const SceNpId* npid);
|
||||
signaling_info get_sig_infos(u32 conn_id);
|
||||
std::optional<u32> get_conn_id_from_npid(const SceNpId* npid);
|
||||
u32 init_sig1(const SceNpId& npid);
|
||||
u32 init_sig2(const SceNpId& npid, u64 room_id, u16 member_id);
|
||||
std::optional<signaling_info> get_sig_infos(u32 conn_id);
|
||||
std::optional<u32> get_conn_id_from_npid(const SceNpId& npid);
|
||||
std::optional<u32> get_conn_id_from_addr(u32 addr, u16 port);
|
||||
|
||||
void set_sig2_infos(u64 room_id, u16 member_id, s32 status, u32 addr, u16 port, const SceNpId& npid, bool self = false);
|
||||
signaling_info get_sig2_infos(u64 room_id, u16 member_id);
|
||||
|
||||
void set_sig_cb(u32 sig_cb_ctx, vm::ptr<SceNpSignalingHandler> sig_cb, vm::ptr<void> sig_cb_arg);
|
||||
void set_ext_sig_cb(u32 sig_ext_cb_ctx, vm::ptr<SceNpSignalingHandler> sig_ext_cb, vm::ptr<void> sig_ext_cb_arg);
|
||||
void set_sig2_cb(u16 sig2_cb_ctx, vm::ptr<SceNpMatching2SignalingCallback> sig2_cb, vm::ptr<void> sig2_cb_arg);
|
||||
@ -95,28 +84,18 @@ private:
|
||||
static constexpr auto REPEAT_PING_DELAY = std::chrono::milliseconds(500);
|
||||
static constexpr auto REPEAT_FINISHED_DELAY = std::chrono::milliseconds(500);
|
||||
static constexpr be_t<u32> SIGNALING_SIGNATURE = (static_cast<u32>('S') << 24 | static_cast<u32>('I') << 16 | static_cast<u32>('G') << 8 | static_cast<u32>('N'));
|
||||
static constexpr le_t<u32> SIGNALING_VERSION = 3;
|
||||
|
||||
struct signaling_packet
|
||||
{
|
||||
be_t<u32> signature = SIGNALING_SIGNATURE;
|
||||
le_t<u32> version;
|
||||
le_t<u32> version = SIGNALING_VERSION;
|
||||
le_t<u64> timestamp_sender;
|
||||
le_t<u64> timestamp_receiver;
|
||||
le_t<SignalingCommand> command;
|
||||
le_t<u32> sent_addr;
|
||||
le_t<u16> sent_port;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
SceNpId npid;
|
||||
} V1;
|
||||
struct
|
||||
{
|
||||
le_t<u64> room_id;
|
||||
le_t<u16> member_id;
|
||||
} V2;
|
||||
};
|
||||
};
|
||||
|
||||
struct queued_packet
|
||||
@ -137,33 +116,32 @@ private:
|
||||
vm::ptr<SceNpMatching2SignalingCallback> sig2_cb{};
|
||||
vm::ptr<void> sig2_cb_arg{};
|
||||
|
||||
u32 create_sig_infos(const SceNpId* npid);
|
||||
u32 get_always_conn_id(const SceNpId& npid);
|
||||
static void update_si_addr(std::shared_ptr<signaling_info>& si, u32 new_addr, u16 new_port);
|
||||
static void update_si_mapped_addr(std::shared_ptr<signaling_info>& si, u32 new_addr, u16 new_port);
|
||||
void update_si_status(std::shared_ptr<signaling_info>& si, s32 new_status, bool confirm_packet = false);
|
||||
static void update_room_info(std::shared_ptr<signaling_info>& si, u64 room_id, u16 member_id);
|
||||
void update_si_status(std::shared_ptr<signaling_info>& si, s32 new_status);
|
||||
void update_ext_si_status(std::shared_ptr<signaling_info>& si, bool op_activated);
|
||||
void signal_sig_callback(u32 conn_id, int event);
|
||||
void signal_ext_sig_callback(u32 conn_id, int event) const;
|
||||
void signal_sig2_callback(u64 room_id, u16 member_id, SceNpMatching2Event event) const;
|
||||
|
||||
void start_sig_nl(u32 conn_id, u32 addr, u16 port);
|
||||
|
||||
static bool validate_signaling_packet(const signaling_packet* sp);
|
||||
void reschedule_packet(std::shared_ptr<signaling_info>& si, SignalingCommand cmd, steady_clock::time_point new_timepoint);
|
||||
void retire_packet(std::shared_ptr<signaling_info>& si, SignalingCommand cmd);
|
||||
void retire_all_packets(std::shared_ptr<signaling_info>& si);
|
||||
void stop_sig_nl(u32 conn_id);
|
||||
|
||||
std::mutex data_mutex;
|
||||
std::condition_variable wakey;
|
||||
|
||||
signaling_packet sig1_packet{.version = 1u};
|
||||
signaling_packet sig2_packet{.version = 2u};
|
||||
signaling_packet sig_packet{};
|
||||
|
||||
std::map<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)
|
||||
std::unordered_map<u32, std::shared_ptr<signaling_info>> sig1_peers; // (conn_id, sig_info)
|
||||
std::unordered_map<u64, std::unordered_map<u16, std::shared_ptr<signaling_info>>> sig2_peers; // (room (member_id, sig_info))
|
||||
std::unordered_map<u32, std::shared_ptr<signaling_info>> sig_peers; // (conn_id, sig_info)
|
||||
|
||||
void process_incoming_messages();
|
||||
std::shared_ptr<signaling_info> get_signaling_ptr(const signaling_packet* sp);
|
||||
|
59
rpcs3/Emu/NP/upnp_config.cpp
Normal file
59
rpcs3/Emu/NP/upnp_config.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "stdafx.h"
|
||||
#include "upnp_config.h"
|
||||
#include "Utilities/File.h"
|
||||
|
||||
LOG_CHANNEL(upnp_cfg_log, "UPNP_CFG");
|
||||
|
||||
void cfg_upnp::load()
|
||||
{
|
||||
const std::string path = cfg_upnp::get_path();
|
||||
|
||||
fs::file cfg_file(path, fs::read);
|
||||
if (cfg_file)
|
||||
{
|
||||
upnp_cfg_log.notice("Loading UPNP config. Path: %s", path);
|
||||
from_string(cfg_file.to_string());
|
||||
}
|
||||
else
|
||||
{
|
||||
upnp_cfg_log.notice("UPNP config missing. Using default settings. Path: %s", path);
|
||||
from_default();
|
||||
}
|
||||
}
|
||||
|
||||
void cfg_upnp::save() const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const std::string path_to_cfg = fs::get_config_dir() + "config/";
|
||||
if (!fs::create_path(path_to_cfg))
|
||||
{
|
||||
upnp_cfg_log.error("Could not create path: %s", path_to_cfg);
|
||||
}
|
||||
#endif
|
||||
|
||||
fs::pending_file cfg_file(cfg_upnp::get_path());
|
||||
|
||||
if (!cfg_file.file || (cfg_file.file.write(to_string()), !cfg_file.commit()))
|
||||
{
|
||||
upnp_cfg_log.error("Could not save config: %s (error=%s)", cfg_upnp::get_path(), fs::g_tls_error);
|
||||
}
|
||||
}
|
||||
|
||||
std::string cfg_upnp::get_device_url() const
|
||||
{
|
||||
return device_url.to_string();
|
||||
}
|
||||
|
||||
void cfg_upnp::set_device_url(std::string_view url)
|
||||
{
|
||||
device_url.from_string(url);
|
||||
}
|
||||
|
||||
std::string cfg_upnp::get_path()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return fs::get_config_dir() + "config/upnp.yml";
|
||||
#else
|
||||
return fs::get_config_dir() + "upnp.yml";
|
||||
#endif
|
||||
}
|
18
rpcs3/Emu/NP/upnp_config.h
Normal file
18
rpcs3/Emu/NP/upnp_config.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utilities/Config.h"
|
||||
|
||||
struct cfg_upnp : cfg::node
|
||||
{
|
||||
cfg::string device_url{this, "DeviceUrl", ""};
|
||||
|
||||
void load();
|
||||
void save() const;
|
||||
|
||||
std::string get_device_url() const;
|
||||
|
||||
void set_device_url(std::string_view url);
|
||||
|
||||
private:
|
||||
static std::string get_path();
|
||||
};
|
186
rpcs3/Emu/NP/upnp_handler.cpp
Normal file
186
rpcs3/Emu/NP/upnp_handler.cpp
Normal file
@ -0,0 +1,186 @@
|
||||
#include "stdafx.h"
|
||||
#include "upnp_handler.h"
|
||||
#include "util/logs.hpp"
|
||||
|
||||
#include <miniwget.h>
|
||||
#include <upnpcommands.h>
|
||||
|
||||
LOG_CHANNEL(upnp_log, "UPNP");
|
||||
|
||||
upnp_handler::~upnp_handler()
|
||||
{
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
for (const auto& [protocol, prot_bindings] : m_bindings)
|
||||
{
|
||||
for (const auto& [internal_port, external_port] : prot_bindings)
|
||||
{
|
||||
remove_port_redir_external(external_port, protocol);
|
||||
}
|
||||
}
|
||||
|
||||
m_active = false;
|
||||
}
|
||||
|
||||
void upnp_handler::upnp_enable()
|
||||
{
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
m_cfg.load();
|
||||
|
||||
auto check_igd = [&](const char* url) -> bool
|
||||
{
|
||||
int desc_xml_size = 0;
|
||||
int status_code = 0;
|
||||
|
||||
m_igd_data = {};
|
||||
m_igd_urls = {};
|
||||
|
||||
char* desc_xml = static_cast<char*>(miniwget(url, &desc_xml_size, 1, &status_code));
|
||||
|
||||
if (!desc_xml)
|
||||
return false;
|
||||
|
||||
parserootdesc(desc_xml, desc_xml_size, &m_igd_data);
|
||||
free(desc_xml);
|
||||
desc_xml = nullptr;
|
||||
GetUPNPUrls(&m_igd_urls, &m_igd_data, url, 1);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
std::string dev_url = m_cfg.get_device_url();
|
||||
|
||||
if (!dev_url.empty())
|
||||
{
|
||||
if (check_igd(dev_url.c_str()))
|
||||
{
|
||||
upnp_log.notice("Saved UPNP(%s) enabled", dev_url);
|
||||
m_active = true;
|
||||
return;
|
||||
}
|
||||
|
||||
upnp_log.error("Saved UPNP(%s) isn't available anymore", dev_url);
|
||||
}
|
||||
|
||||
upnp_log.notice("Starting UPNP search");
|
||||
|
||||
int upnperror = 0;
|
||||
UPNPDev* devlist = upnpDiscover(2000, nullptr, nullptr, 0, 0, 2, &upnperror);
|
||||
|
||||
if (!devlist)
|
||||
{
|
||||
upnp_log.error("No UPNP device was found");
|
||||
return;
|
||||
}
|
||||
|
||||
const UPNPDev* dev = devlist;
|
||||
for (; dev; dev = dev->pNext)
|
||||
{
|
||||
if (strstr(dev->st, "InternetGatewayDevice"))
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev)
|
||||
{
|
||||
int desc_xml_size = 0;
|
||||
int status_code = 0;
|
||||
char* desc_xml = static_cast<char*>(miniwget(dev->descURL, &desc_xml_size, 1, &status_code));
|
||||
|
||||
if (desc_xml)
|
||||
{
|
||||
IGDdatas igd_data{};
|
||||
UPNPUrls igd_urls{};
|
||||
parserootdesc(desc_xml, desc_xml_size, &igd_data);
|
||||
free(desc_xml);
|
||||
desc_xml = nullptr;
|
||||
GetUPNPUrls(&igd_urls, &igd_data, dev->descURL, 1);
|
||||
|
||||
upnp_log.notice("Found UPnP device type:%s at %s", dev->st, dev->descURL);
|
||||
|
||||
m_cfg.set_device_url(dev->descURL);
|
||||
m_cfg.save();
|
||||
|
||||
m_active = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
upnp_log.error("Failed to retrieve UPNP xml for %s", dev->descURL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
upnp_log.error("No UPNP IGD device was found");
|
||||
}
|
||||
|
||||
freeUPNPDevlist(devlist);
|
||||
}
|
||||
|
||||
void upnp_handler::add_port_redir(std::string_view 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);
|
||||
int res = 0;
|
||||
|
||||
for (u16 external_port = internal_port; external_port < internal_port + 100; 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);
|
||||
if (res == UPNPCOMMAND_SUCCESS)
|
||||
{
|
||||
m_bindings[std::string(protocol)][internal_port] = external_port;
|
||||
upnp_log.notice("Successfully bound %s:%d(%s) to IGD:%d", addr, internal_port, protocol, external_port);
|
||||
return;
|
||||
}
|
||||
|
||||
// need more testing, may vary per router, etc, for now assume port conflict silently
|
||||
// else if (res != 718) // ConflictInMappingEntry
|
||||
// {
|
||||
// upnp_log.error("Failed to bind %s:%d(%s) to IGD:%d: %d", addr, internal_port, protocol, external_port, res);
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
|
||||
upnp_log.error("Failed to bind %s:%d(%s) to IGD:(%d=>%d): %d", addr, internal_port, protocol, internal_port, external_port, res);
|
||||
}
|
||||
|
||||
void upnp_handler::remove_port_redir(u16 internal_port, std::string_view protocol)
|
||||
{
|
||||
if (!m_active)
|
||||
return;
|
||||
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
const std::string str_protocol(protocol);
|
||||
|
||||
if (!m_bindings.contains(str_protocol) || !::at32(m_bindings, str_protocol).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);
|
||||
|
||||
remove_port_redir_external(external_port, protocol);
|
||||
|
||||
ensure(::at32(m_bindings, str_protocol).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);
|
||||
|
||||
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)
|
||||
upnp_log.error("Failed to delete port mapping IGD:%s(%s): %d", str_ext_port, protocol, res);
|
||||
}
|
||||
|
||||
bool upnp_handler::is_active() const
|
||||
{
|
||||
return m_active;
|
||||
}
|
32
rpcs3/Emu/NP/upnp_handler.h
Normal file
32
rpcs3/Emu/NP/upnp_handler.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include <miniupnpc.h>
|
||||
|
||||
#include "upnp_config.h"
|
||||
#include "Utilities/mutex.h"
|
||||
|
||||
class upnp_handler
|
||||
{
|
||||
public:
|
||||
~upnp_handler();
|
||||
|
||||
void upnp_enable();
|
||||
void add_port_redir(std::string_view addr, u16 internal_port, std::string_view protocol);
|
||||
void remove_port_redir(u16 internal_port, std::string_view protocol);
|
||||
|
||||
bool is_active() const;
|
||||
|
||||
private:
|
||||
void remove_port_redir_external(u16 external_port, std::string_view protocol, bool verbose = true);
|
||||
|
||||
private:
|
||||
atomic_t<bool> m_active = false;
|
||||
|
||||
shared_mutex m_mutex;
|
||||
cfg_upnp m_cfg;
|
||||
IGDdatas m_igd_data{};
|
||||
UPNPUrls m_igd_urls{};
|
||||
std::unordered_map<std::string, std::unordered_map<u16, u16>> m_bindings;
|
||||
};
|
@ -298,6 +298,7 @@ struct cfg_root : cfg::node
|
||||
cfg::string bind_address{this, "Bind address", "0.0.0.0"};
|
||||
cfg::string dns{this, "DNS address", "8.8.8.8"};
|
||||
cfg::string swap_list{this, "IP swap list", ""};
|
||||
cfg::_bool upnp_enabled{this, "UPNP Enabled", false};
|
||||
|
||||
cfg::_enum<np_psn_status> psn_status{this, "PSN status", np_psn_status::disabled};
|
||||
} net{this};
|
||||
|
@ -40,10 +40,10 @@
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<AdditionalIncludeDirectories>..\3rdparty\wolfssl\wolfssl;..\3rdparty\flatbuffers\include;..\3rdparty\libusb\libusb\libusb;..\3rdparty\yaml-cpp\yaml-cpp\include;..\3rdparty\SoundTouch\soundtouch\include;..\3rdparty\zlib\zlib;..\llvm\include;..\llvm_build\include;$(VULKAN_SDK)\Include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\3rdparty\miniupnp\miniupnp\miniupnpc\include;..\3rdparty\wolfssl\wolfssl;..\3rdparty\flatbuffers\include;..\3rdparty\libusb\libusb\libusb;..\3rdparty\yaml-cpp\yaml-cpp\include;..\3rdparty\SoundTouch\soundtouch\include;..\3rdparty\zlib\zlib;..\llvm\include;..\llvm_build\include;$(VULKAN_SDK)\Include</AdditionalIncludeDirectories>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">HAVE_VULKAN;HAVE_SDL2;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">HAVE_VULKAN;HAVE_SDL2;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">MINIUPNP_STATICLIB;HAVE_VULKAN;HAVE_SDL2;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MINIUPNP_STATICLIB;HAVE_VULKAN;HAVE_SDL2;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<PreBuildEvent>
|
||||
<Command>cmd.exe /c "$(SolutionDir)\Utilities\git-version-gen.cmd"</Command>
|
||||
@ -82,6 +82,8 @@
|
||||
<ClCompile Include="Emu\IPC_socket.cpp" />
|
||||
<ClCompile Include="Emu\localized_string.cpp" />
|
||||
<ClCompile Include="Emu\NP\rpcn_config.cpp" />
|
||||
<ClCompile Include="Emu\NP\upnp_config.cpp" />
|
||||
<ClCompile Include="Emu\NP\upnp_handler.cpp" />
|
||||
<ClCompile Include="Emu\perf_monitor.cpp" />
|
||||
<ClCompile Include="Emu\RSX\Common\texture_cache.cpp" />
|
||||
<ClCompile Include="Emu\RSX\Overlays\HomeMenu\overlay_home_menu.cpp" />
|
||||
@ -516,6 +518,8 @@
|
||||
<ClInclude Include="Emu\NP\generated\np2_structs_generated.h" />
|
||||
<ClInclude Include="Emu\NP\np_handler.h" />
|
||||
<ClInclude Include="Emu\NP\signaling_handler.h" />
|
||||
<ClInclude Include="Emu\NP\upnp_config.h" />
|
||||
<ClInclude Include="Emu\NP\upnp_handler.h" />
|
||||
<ClInclude Include="Emu\NP\vport0.h" />
|
||||
<ClInclude Include="Emu\NP\np_allocator.h" />
|
||||
<ClInclude Include="Emu\NP\np_cache.h" />
|
||||
|
@ -1138,6 +1138,12 @@
|
||||
<ClCompile Include="Emu\RSX\Overlays\HomeMenu\overlay_home_menu_message_box.cpp">
|
||||
<Filter>Emu\GPU\RSX\Overlays\HomeMenu</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\NP\upnp_handler.cpp">
|
||||
<Filter>Emu\NP</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\NP\upnp_config.cpp">
|
||||
<Filter>Emu\NP</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Crypto\aes.h">
|
||||
@ -2290,6 +2296,12 @@
|
||||
<ClInclude Include="Emu\RSX\Overlays\HomeMenu\overlay_home_menu_message_box.h">
|
||||
<Filter>Emu\GPU\RSX\Overlays\HomeMenu</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\NP\upnp_handler.h">
|
||||
<Filter>Emu\NP</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\NP\upnp_config.h">
|
||||
<Filter>Emu\NP</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\GPUDeswizzle.glsl">
|
||||
|
@ -79,7 +79,7 @@
|
||||
<DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;WIN32;WIN64;WIN32_LEAN_AND_MEAN;HAVE_VULKAN;HAVE_SDL2;WITH_DISCORD_RPC;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;NDEBUG;QT_WINEXTRAS_LIB;QT_CONCURRENT_LIB;QT_MULTIMEDIA_LIB;QT_MULTIMEDIAWIDGETS_LIB;QT_SVG_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;WIN32;WIN64;WIN32_LEAN_AND_MEAN;HAVE_VULKAN;MINIUPNP_STATICLIB;HAVE_SDL2;WITH_DISCORD_RPC;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;NDEBUG;QT_WINEXTRAS_LIB;QT_CONCURRENT_LIB;QT_MULTIMEDIA_LIB;QT_MULTIMEDIAWIDGETS_LIB;QT_SVG_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessToFile>false</PreprocessToFile>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
@ -88,7 +88,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>DbgHelp.lib;Ole32.lib;gdi32.lib;..\hidapi.lib;..\libusb-1.0.lib;winmm.lib;imm32.lib;ksuser.lib;version.lib;OpenAL32.lib;XAudio.lib;GLGSRender.lib;shlwapi.lib;VKGSRender.lib;vulkan-1.lib;wolfssl.lib;libcurl.lib;Wldap32.lib;glslang.lib;OSDependent.lib;OGLCompiler.lib;SPIRV.lib;MachineIndependent.lib;GenericCodeGen.lib;Advapi32.lib;user32.lib;zlib.lib;..\libpng16.lib;asmjit.lib;yaml-cpp.lib;discord-rpc.lib;emucore.lib;dxgi.lib;$(QTDIR)\lib\qtmain.lib;shell32.lib;$(QTDIR)\lib\Qt5Widgets.lib;$(QTDIR)\lib\Qt5Gui.lib;$(QTDIR)\lib\Qt5Core.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;Qt5WinExtras.lib;Qt5Concurrent.lib;7zlib.lib;SPIRV-Tools.lib;SPIRV-Tools-opt.lib;Qt5Multimedia.lib;Qt5MultimediaWidgets.lib;Qt5Svg.lib;libcubeb.lib;cubeb.lib;soundtouch.lib;Avrt.lib;SDL.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>DbgHelp.lib;Ole32.lib;gdi32.lib;..\hidapi.lib;..\libusb-1.0.lib;winmm.lib;miniupnpc_static.lib;imm32.lib;ksuser.lib;version.lib;OpenAL32.lib;XAudio.lib;GLGSRender.lib;shlwapi.lib;VKGSRender.lib;vulkan-1.lib;wolfssl.lib;libcurl.lib;Wldap32.lib;glslang.lib;OSDependent.lib;OGLCompiler.lib;SPIRV.lib;MachineIndependent.lib;GenericCodeGen.lib;Advapi32.lib;user32.lib;zlib.lib;..\libpng16.lib;asmjit.lib;yaml-cpp.lib;discord-rpc.lib;emucore.lib;dxgi.lib;$(QTDIR)\lib\qtmain.lib;shell32.lib;$(QTDIR)\lib\Qt5Widgets.lib;$(QTDIR)\lib\Qt5Gui.lib;$(QTDIR)\lib\Qt5Core.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;Qt5WinExtras.lib;Qt5Concurrent.lib;7zlib.lib;SPIRV-Tools.lib;SPIRV-Tools-opt.lib;Qt5Multimedia.lib;Qt5MultimediaWidgets.lib;Qt5Svg.lib;libcubeb.lib;cubeb.lib;soundtouch.lib;Avrt.lib;SDL.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\3rdparty\OpenAL\libs\Win64;..\3rdparty\glslang\build\hlsl\Release;..\3rdparty\glslang\build\SPIRV\Release;..\3rdparty\glslang\build\OGLCompilersDLL\Release;..\3rdparty\glslang\build\glslang\OSDependent\Windows\Release;..\3rdparty\glslang\build\glslang\Release;..\3rdparty\SPIRV\build\source\Release;..\3rdparty\SPIRV\build\source\opt\Release;..\lib\$(CONFIGURATION)-$(PLATFORM);..\3rdparty\XAudio2Redist\libs;..\3rdparty\discord-rpc\lib;$(QTDIR)\lib;%(AdditionalLibraryDirectories);$(VULKAN_SDK)\Lib</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
|
||||
<DataExecutionPrevention>true</DataExecutionPrevention>
|
||||
@ -130,7 +130,7 @@
|
||||
<DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;WIN32;WIN64;WIN32_LEAN_AND_MEAN;HAVE_VULKAN;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;QT_WINEXTRAS_LIB;QT_CONCURRENT_LIB;QT_MULTIMEDIA_LIB;QT_MULTIMEDIAWIDGETS_LIB;QT_SVG_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;WIN32;WIN64;WIN32_LEAN_AND_MEAN;HAVE_VULKAN;MINIUPNP_STATICLIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;QT_WINEXTRAS_LIB;QT_CONCURRENT_LIB;QT_MULTIMEDIA_LIB;QT_MULTIMEDIAWIDGETS_LIB;QT_SVG_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessToFile>false</PreprocessToFile>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
@ -139,7 +139,7 @@
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>DbgHelp.lib;Ole32.lib;gdi32.lib;..\hidapi.lib;..\libusb-1.0.lib;winmm.lib;ksuser.lib;OpenAL32.lib;XAudio.lib;GLGSRender.lib;shlwapi.lib;VKGSRender.lib;vulkan-1.lib;wolfssl.lib;libcurl.lib;Wldap32.lib;glslangd.lib;OSDependentd.lib;OGLCompilerd.lib;SPIRVd.lib;MachineIndependentd.lib;GenericCodeGend.lib;Advapi32.lib;user32.lib;zlib.lib;..\libpng16.lib;asmjit.lib;yaml-cpp.lib;discord-rpc.lib;emucore.lib;dxgi.lib;$(QTDIR)\lib\qtmaind.lib;shell32.lib;$(QTDIR)\lib\Qt5Widgetsd.lib;$(QTDIR)\lib\Qt5Guid.lib;$(QTDIR)\lib\Qt5Cored.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;Qt5WinExtrasd.lib;Qt5Concurrentd.lib;7zlib.lib;SPIRV-Tools.lib;SPIRV-Tools-opt.lib;Qt5Multimediad.lib;Qt5MultimediaWidgetsd.lib;Qt5Svgd.lib;libcubeb.lib;cubeb.lib;soundtouch.lib;Avrt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>DbgHelp.lib;Ole32.lib;gdi32.lib;..\hidapi.lib;..\libusb-1.0.lib;winmm.lib;miniupnpc_static.lib;ksuser.lib;OpenAL32.lib;XAudio.lib;GLGSRender.lib;shlwapi.lib;VKGSRender.lib;vulkan-1.lib;wolfssl.lib;libcurl.lib;Wldap32.lib;glslangd.lib;OSDependentd.lib;OGLCompilerd.lib;SPIRVd.lib;MachineIndependentd.lib;GenericCodeGend.lib;Advapi32.lib;user32.lib;zlib.lib;..\libpng16.lib;asmjit.lib;yaml-cpp.lib;discord-rpc.lib;emucore.lib;dxgi.lib;$(QTDIR)\lib\qtmaind.lib;shell32.lib;$(QTDIR)\lib\Qt5Widgetsd.lib;$(QTDIR)\lib\Qt5Guid.lib;$(QTDIR)\lib\Qt5Cored.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;Qt5WinExtrasd.lib;Qt5Concurrentd.lib;7zlib.lib;SPIRV-Tools.lib;SPIRV-Tools-opt.lib;Qt5Multimediad.lib;Qt5MultimediaWidgetsd.lib;Qt5Svgd.lib;libcubeb.lib;cubeb.lib;soundtouch.lib;Avrt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\3rdparty\OpenAL\libs\Win64;..\3rdparty\glslang\build\hlsl\Debug;..\3rdparty\glslang\build\SPIRV\Debug;..\3rdparty\glslang\build\OGLCompilersDLL\Debug;..\3rdparty\glslang\build\glslang\OSDependent\Windows\Debug;..\3rdparty\glslang\build\glslang\Debug;..\3rdparty\SPIRV\build\source\opt\Debug;..\3rdparty\XAudio2Redist\libs;..\3rdparty\discord-rpc\lib;..\lib\$(CONFIGURATION)-$(PLATFORM);$(QTDIR)\lib;%(AdditionalLibraryDirectories);$(VULKAN_SDK)\Lib</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /VERBOSE %(AdditionalOptions)</AdditionalOptions>
|
||||
<DataExecutionPrevention>true</DataExecutionPrevention>
|
||||
|
@ -173,7 +173,7 @@ usz downloader::update_buffer(char* data, usz size)
|
||||
|
||||
if (m_actual_download_size < 0)
|
||||
{
|
||||
if (curl_easy_getinfo(m_curl->get_curl(), CURLINFO_CONTENT_LENGTH_DOWNLOAD, &m_actual_download_size) == CURLE_OK && m_actual_download_size > 0)
|
||||
if (curl_easy_getinfo(m_curl->get_curl(), CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &m_actual_download_size) == CURLE_OK && m_actual_download_size > 0)
|
||||
{
|
||||
max = static_cast<int>(m_actual_download_size);
|
||||
}
|
||||
|
@ -173,6 +173,7 @@ enum class emu_settings_type
|
||||
IpSwapList,
|
||||
PSNStatus,
|
||||
BindAddress,
|
||||
EnableUpnp,
|
||||
|
||||
// System
|
||||
LicenseArea,
|
||||
@ -353,6 +354,7 @@ inline static const QMap<emu_settings_type, cfg_location> settings_location =
|
||||
{ emu_settings_type::IpSwapList, { "Net", "IP swap list"}},
|
||||
{ emu_settings_type::PSNStatus, { "Net", "PSN status"}},
|
||||
{ emu_settings_type::BindAddress, { "Net", "Bind address"}},
|
||||
{ emu_settings_type::EnableUpnp, { "Net", "UPNP Enabled"}},
|
||||
|
||||
// System
|
||||
{ emu_settings_type::LicenseArea, { "System", "License Area"}},
|
||||
|
@ -1304,6 +1304,9 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
||||
m_emu_settings->EnhanceLineEdit(ui->edit_swaps, emu_settings_type::IpSwapList);
|
||||
SubscribeTooltip(ui->gb_edit_swaps, tooltips.settings.dns_swap);
|
||||
|
||||
m_emu_settings->EnhanceCheckBox(ui->enable_upnp, emu_settings_type::EnableUpnp);
|
||||
SubscribeTooltip(ui->enable_upnp, tooltips.settings.enable_upnp);
|
||||
|
||||
// Comboboxes
|
||||
|
||||
m_emu_settings->EnhanceComboBox(ui->netStatusBox, emu_settings_type::InternetStatus);
|
||||
@ -1312,8 +1315,10 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
||||
connect(ui->netStatusBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index)
|
||||
{
|
||||
ui->edit_dns->setEnabled(index > 0);
|
||||
ui->enable_upnp->setEnabled(index > 0);
|
||||
});
|
||||
ui->edit_dns->setEnabled(ui->netStatusBox->currentIndex() > 0);
|
||||
ui->enable_upnp->setEnabled(ui->netStatusBox->currentIndex() > 0);
|
||||
|
||||
m_emu_settings->EnhanceComboBox(ui->psnStatusBox, emu_settings_type::PSNStatus);
|
||||
SubscribeTooltip(ui->gb_psnStatusBox, tooltips.settings.psn_status);
|
||||
|
@ -2077,7 +2077,7 @@
|
||||
<property name="title">
|
||||
<string>Network Configuration</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="gb_network_status_layout" stretch="0,0,0,0,0">
|
||||
<layout class="QVBoxLayout" name="gb_network_status_layout" stretch="0,0,0,0,0,0">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gb_netStatusBox">
|
||||
<property name="title">
|
||||
@ -2147,6 +2147,13 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enable_upnp">
|
||||
<property name="text">
|
||||
<string>Enable UPNP</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="networkTabSpacerLeft">
|
||||
<property name="orientation">
|
||||
|
@ -230,6 +230,7 @@ public:
|
||||
const QString dns = tr("DNS used to resolve hostnames by applications.");
|
||||
const QString dns_swap = tr("DNS Swap List.");
|
||||
const QString bind = tr("Interface IP Address to bind to.");
|
||||
const QString enable_upnp = tr("Enable UPNP.\nThis will automatically forward ports bound on 0.0.0.0 if your router has UPNP enabled.");
|
||||
|
||||
// system
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user