Added UPnP Support

Fix i18n type
This commit is contained in:
ANR2ME 2020-01-18 02:32:09 +07:00 committed by Henrik Rydgård
parent 6280d1b11c
commit 33d3ac28de
17 changed files with 938 additions and 18 deletions

3
.gitmodules vendored
View File

@ -28,3 +28,6 @@
[submodule "ext/native/tools/prebuilt"]
path = ext/native/tools/prebuilt
url = https://github.com/hrydgard/ppsspp-freetype.git
[submodule "ext/miniupnp"]
path = ext/miniupnp
url = https://github.com/miniupnp/miniupnp.git

View File

@ -119,6 +119,7 @@ option(LIBRETRO "Set to ON to generate the libretro target" OFF)
# :: Options
option(USE_FFMPEG "Build with FFMPEG support" ON)
option(USE_DISCORD "Build with Discord support" ON)
option(USE_MINIUPNPC "Build with miniUPnPc support" ON)
option(USE_SYSTEM_SNAPPY "Dynamically link against system snappy" ${USE_SYSTEM_SNAPPY})
option(USE_SYSTEM_FFMPEG "Dynamically link against system FFMPEG" ${USE_SYSTEM_FFMPEG})
option(USE_SYSTEM_LIBZIP "Dynamically link against system libzip" ${USE_SYSTEM_LIBZIP})
@ -1768,6 +1769,8 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/Util/AudioFormatNEON.h
Core/Util/GameManager.cpp
Core/Util/GameManager.h
Core/Util/PortManager.cpp
Core/Util/PortManager.h
Core/Util/BlockAllocator.cpp
Core/Util/BlockAllocator.h
Core/Util/PPGeDraw.cpp
@ -1820,6 +1823,80 @@ if(USE_DISCORD AND NOT IOS AND NOT LIBRETRO)
target_link_libraries(${CoreLibName} discord-rpc)
endif()
# miniUPnPc integration (MiniUPnPc supposed to works on any POSIX system, not sure if some of these are redundant/not needed tho)
if(USE_MINIUPNPC)
set (MINIUPNPC_VERSION 2.1) # used by miniupnpcstrings.h.cmake
set (MINIUPNPC_API_VERSION 17)
option(UPNPC_BUILD_STATIC "Build static library" TRUE)
option(NO_GETADDRINFO "Define NO_GETADDRINFO" FALSE)
mark_as_advanced(NO_GETADDRINFO)
if (NO_GETADDRINFO)
add_definitions(-DNO_GETADDRINFO)
endif()
if (NOT WIN32)
add_definitions (-DMINIUPNPC_SET_SOCKET_TIMEOUT)
add_definitions (-D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112L)
else()
add_definitions (-D_WIN32_WINNT=0x0501) # XP or higher for getnameinfo and friends
endif()
if (MACOSX)
add_definitions (-D_DARWIN_C_SOURCE)
endif()
if(WIN32)
add_definitions(-DWIN32 -DMINIUPNP_EXPORTS )
else()
add_definitions(-fPIC)
endif()
add_definitions(-DMINIUPNP_STATICLIB)
set(MINIUPNP_DIR "ext/miniupnp/miniupnpc")
include_directories(${CMAKE_CURRENT_BINARY_DIR})
configure_file(${MINIUPNP_DIR}/miniupnpcstrings.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/miniupnpcstrings.h) # by default miniupnp repo doesn't contains miniupnpcstrings.h and need to be generated
set(MINIUPNPC_SOURCES
# the needed bits of miniupnpc (no python module, no tests, no cli)
${MINIUPNP_DIR}/connecthostport.c
${MINIUPNP_DIR}/igd_desc_parse.c
${MINIUPNP_DIR}/minisoap.c
${MINIUPNP_DIR}/minissdpc.c
${MINIUPNP_DIR}/miniupnpc.c
${MINIUPNP_DIR}/miniwget.c
${MINIUPNP_DIR}/minixml.c
${MINIUPNP_DIR}/minixmlvalid.c
${MINIUPNP_DIR}/portlistingparse.c
${MINIUPNP_DIR}/receivedata.c
#${MINIUPNP_DIR}/upnpc.c # causing an error due to already existing _main()
${MINIUPNP_DIR}/upnpcommands.c
${MINIUPNP_DIR}/upnpdev.c
${MINIUPNP_DIR}/upnperrors.c
${MINIUPNP_DIR}/upnpreplyparse.c
${CMAKE_CURRENT_BINARY_DIR}/miniupnpcstrings.h
)
if (NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS")
#set(MINIUPNPC_SOURCES ${MINIUPNPC_SOURCES} minissdpc.c) # causing an error due to duplication in MINIUPNPC_SOURCES?
endif()
if (WIN32)
set_source_files_properties(${MINIUPNPC_SOURCES} PROPERTIES COMPILE_DEFINITIONS "MINIUPNP_STATICLIB;MINIUPNP_EXPORTS")
find_library(WINSOCK2_LIBRARY NAMES ws2_32 WS2_32 Ws2_32)
find_library(IPHLPAPI_LIBRARY NAMES iphlpapi)
set(LDLIBS ${WINSOCK2_LIBRARY} ${IPHLPAPI_LIBRARY} ${LDLIBS})
#elseif (CMAKE_SYSTEM_NAME STREQUAL "Solaris")
# find_library (SOCKET_LIBRARY NAMES socket)
# find_library (NSL_LIBRARY NAMES nsl)
# find_library (RESOLV_LIBRARY NAMES resolv)
# set (LDLIBS ${SOCKET_LIBRARY} ${NSL_LIBRARY} ${RESOLV_LIBRARY} ${LDLIBS})
endif()
if (MSVC)
# Suppress noise warnings
target_compile_definitions(miniupnpc _CRT_SECURE_NO_WARNINGS _WINSOCK_DEPRECATED_NO_WARNINGS)
endif()
if (UPNPC_BUILD_STATIC)
add_library(miniupnpc STATIC ${MINIUPNPC_SOURCES})
target_link_libraries(${CoreLibName} miniupnpc ${LDLIBS})
set(UPNPC_LIBRARY miniupnpc)
endif()
endif()
setup_target_project(${CoreLibName} Core)
# Generate git-version.cpp at build time.

View File

@ -955,6 +955,8 @@ static ConfigSetting controlSettings[] = {
static ConfigSetting networkSettings[] = {
ConfigSetting("EnableWlan", &g_Config.bEnableWlan, false, true, true),
ConfigSetting("EnableAdhocServer", &g_Config.bEnableAdhocServer, false, true, true),
ConfigSetting("EnableUPnP", &g_Config.bEnableUPnP, false, true, true),
ConfigSetting("EnableNetworkChat", &g_Config.bEnableNetworkChat, false, true, true),
ConfigSetting("ChatButtonPosition",&g_Config.iChatButtonPosition,BOTTOM_LEFT,true,true),
ConfigSetting("ChatScreenPosition",&g_Config.iChatScreenPosition,BOTTOM_LEFT,true,true),
@ -964,6 +966,7 @@ static ConfigSetting networkSettings[] = {
ConfigSetting("QuickChat3", &g_Config.sQuickChat2, "Quick Chat 3", true, true),
ConfigSetting("QuickChat4", &g_Config.sQuickChat3, "Quick Chat 4", true, true),
ConfigSetting("QuickChat5", &g_Config.sQuickChat4, "Quick Chat 5", true, true),
ConfigSetting(false),
};

View File

@ -412,6 +412,7 @@ public:
// Networking
bool bEnableWlan;
bool bEnableAdhocServer;
bool bEnableUPnP;
int iWlanAdhocChannel;
bool bWlanPowerSave;
bool bEnableNetworkChat;

View File

@ -139,7 +139,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;MINIUPNP_STATICLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
@ -162,7 +162,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_64=1;_M_X64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_64=1;_M_X64=1;_DEBUG;_LIB;_UNICODE;UNICODE;MINIUPNP_STATICLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
<OmitFramePointers>false</OmitFramePointers>
@ -241,7 +241,7 @@
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_M_IX86=1;_LIB;NDEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_M_IX86=1;_LIB;NDEBUG;_UNICODE;UNICODE;MINIUPNP_STATICLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
@ -276,7 +276,7 @@
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>false</WholeProgramOptimization>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_64=1;_M_X64=1;_LIB;NDEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_64=1;_M_X64=1;_LIB;NDEBUG;_UNICODE;UNICODE;MINIUPNP_STATICLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<StringPooling>true</StringPooling>
@ -847,6 +847,7 @@
<ClCompile Include="Util\BlockAllocator.cpp" />
<ClCompile Include="Util\DisArm64.cpp" />
<ClCompile Include="Util\GameManager.cpp" />
<ClCompile Include="Util\PortManager.cpp" />
<ClCompile Include="Util\PPGeDraw.cpp" />
<ClCompile Include="..\ext\xxhash.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MaxSpeed</Optimization>
@ -1181,6 +1182,7 @@
<ClInclude Include="Util\BlockAllocator.h" />
<ClInclude Include="Util\DisArm64.h" />
<ClInclude Include="Util\GameManager.h" />
<ClInclude Include="Util\PortManager.h" />
<ClInclude Include="Util\PPGeDraw.h" />
<ClInclude Include="..\ext\xxhash.h" />
<ClInclude Include="WaveFile.h" />
@ -1198,6 +1200,9 @@
<ProjectReference Include="..\ext\libarmips.vcxproj">
<Project>{129e5e2b-39c1-4d84-96fe-dfd22dbb4a25}</Project>
</ProjectReference>
<ProjectReference Include="..\ext\miniupnpc.vcxproj">
<Project>{d8a71225-178b-424e-96c1-cc3be2c1b047}</Project>
</ProjectReference>
<ProjectReference Include="..\GPU\GPU.vcxproj">
<Project>{457f45d2-556f-47bc-a31d-aff0d15beaed}</Project>
</ProjectReference>

View File

@ -745,6 +745,9 @@
</ClCompile>
<ClCompile Include="MemFault.cpp">
<Filter>Core</Filter>
</ClCompile>
<ClCompile Include="Util\PortManager.cpp">
<Filter>Util</Filter>
</ClCompile>
<ClCompile Include="Instance.cpp">
<Filter>Core</Filter>
@ -1387,6 +1390,9 @@
</ClInclude>
<ClInclude Include="MemFault.h">
<Filter>Core</Filter>
</ClInclude>
<ClInclude Include="Util\PortManager.h">
<Filter>Util</Filter>
</ClInclude>
<ClInclude Include="Instance.h">
<Filter>Core</Filter>

View File

@ -1765,14 +1765,23 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){
product_code.type = adhoc_id->type;
memcpy(product_code.data, adhoc_id->data, ADHOCCTL_ADHOCID_LEN);
// Switch to Nonblocking Behaviour
changeBlockingMode(metasocket, 1);
// Connect to Adhoc Server
server_addr.sin_addr = serverIp;
iResult = connect(metasocket,(sockaddr *)&server_addr,sizeof(server_addr));
if (iResult == SOCKET_ERROR) {
int errorcode = 0;
int cnt = 0;
while ((iResult = connect(metasocket, (sockaddr*)&server_addr, sizeof(server_addr))) == SOCKET_ERROR && (errorcode = errno) != EISCONN && cnt < adhocDefaultTimeout) {
sleep_ms(1);
cnt++;
}
// Switch back to Blocking Behaviour
changeBlockingMode(metasocket, 0);
if (iResult == SOCKET_ERROR && errorcode != EISCONN) {
char buffer[512];
snprintf(buffer, sizeof(buffer), "Socket error (%i) when connecting to AdhocServer [%s/%s:%u]", errno, g_Config.proAdhocServer.c_str(), inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port));
snprintf(buffer, sizeof(buffer), "Socket error (%i) when connecting to AdhocServer [%s/%s:%u]", errorcode, g_Config.proAdhocServer.c_str(), inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port));
ERROR_LOG(SCENET, "%s", buffer);
host->NotifyUserMessage(buffer, 5.0f, 0x0000ff);
host->NotifyUserMessage(n->T("Failed to connect to Adhoc Server"), 6.0f, 0x0000ff);
return iResult;
}

View File

@ -44,6 +44,7 @@
//#include <sqlite3.h>
#include "thread/threadutil.h"
#include "Common/FileUtil.h"
#include "Core/Util/PortManager.h"
#include "Core/Core.h"
#include "Core/Host.h"
#include "Core/HLE/proAdhocServer.h"
@ -1675,14 +1676,20 @@ int proAdhocServerThread(int port) // (int argc, char * argv[])
int server = create_listen_socket(port); //SERVER_PORT
// Created Listening Socket
if(server != -1)
if(server != SOCKET_ERROR)
{
// Notify User
INFO_LOG(SCENET, "AdhocServer: Listening for Connections on TCP Port %u", port); //SERVER_PORT
// Port forward
g_PortManager.Add(port, IP_PROTOCOL_TCP);
// Enter Server Loop
result = server_loop(server);
// Remove Port mapping
g_PortManager.Remove(port, IP_PROTOCOL_TCP);
// Notify User
INFO_LOG(SCENET, "AdhocServer: Shutdown complete");
}

View File

@ -32,6 +32,7 @@
#include "Core/MIPS/MIPS.h"
#include "Core/Config.h"
#include "Core/MemMapHelpers.h"
#include "Core/Util/PortManager.h"
#include "sceKernel.h"
#include "sceKernelThread.h"
@ -121,7 +122,11 @@ void __NetInit() {
char tmpmac[18];
SceNetEtherAddr mac;
getLocalMac(&mac);
INFO_LOG(SCENET, "LocalHost IP will be %s [%s]", inet_ntoa(((sockaddr_in*)&LocalhostIP)->sin_addr), mac2str(&mac, tmpmac));
INFO_LOG(SCENET, "LocalHost IP will be %s [MAC: %s]", inet_ntoa(((sockaddr_in*)&LocalhostIP)->sin_addr), mac2str(&mac, tmpmac));
// Only initialize when UPnP is enabled since it takes a few seconds to detect UPnP device (may affect people who don't have UPnP device)
if (g_Config.bEnableUPnP) {
g_PortManager.Init();
}
__ResetInitNetLib();
}
@ -137,6 +142,14 @@ void __NetShutdown() {
if (netInited) sceNetTerm();
__ResetInitNetLib();
if (g_Config.bEnableUPnP) {
g_PortManager.Clear();
g_PortManager.Restore();
g_PortManager.Deinit();
}
//PPSSPPIDCleanup(); // To make the ID/IP persistent on every reset, we should just let the OS closes all open handles instead of calling PPSSPPIDCleanup() on every reset
}
static void __UpdateApctlHandlers(int oldState, int newState, int flag, int error) {

View File

@ -30,6 +30,7 @@
#include "Core/MemMapHelpers.h"
#include "Common/ChunkFile.h"
#include "Core/MIPS/MIPSCodeUtils.h"
#include "Core/Util/PortManager.h"
#include "Core/HLE/HLEHelperThread.h"
#include "Core/HLE/FunctionWrappers.h"
@ -55,7 +56,7 @@ bool networkInited;
static bool netAdhocMatchingInited;
int netAdhocMatchingStarted = 0;
int adhocDefaultTimeout = 2000;
int adhocDefaultTimeout = 2000; //5000
int adhocEventPollDelayMS = 10;
int adhocMatchingEventDelayMS = 100;
int adhocEventDelayMS = 500; // This will affect the duration of "Connecting..." dialog/message box in .Hack//Link and Naruto Ultimate Ninja Heroes 3
@ -340,7 +341,7 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u
getLocalIp(&addr);
}
addr.sin_port = htons(port + portOffset );
addr.sin_port = htons(port + portOffset);
// The port might be under 1024 (ie. GTA:VCS use port 1, Ford Street Racing use port 0 (UNUSED_PORT), etc) and already used by other application/host OS, should we add 1024 to the port whenever it tried to use an already used port?
// Bound Socket to local Port
@ -377,7 +378,8 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u
pdp[i] = internal;
// Forward Port on Router
//sceNetPortOpen("UDP", port); // I need to figure out how to use this in windows/linux
//sceNetPortOpen("UDP", port);
g_PortManager.Add(port + portOffset, IP_PROTOCOL_UDP);
// Success
return i + 1;
@ -927,9 +929,10 @@ static int sceNetAdhocPdpDelete(int id, int unknown) {
// Remove Port Forward from Router
//sceNetPortClose("UDP", sock->lport);
//g_PortManager.Remove(sock->lport + portOffset, IP_PROTOCOL_UDP); // Let's not remove mapping in real-time as it could cause lags/disconnection when joining a room with slow routers
// Free Memory
// free(sock);
free(sock);
// Free Translation Slot
pdp[id - 1] = NULL;
@ -1888,7 +1891,8 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac,
ptp[i] = internal;
// Add Port Forward to Router
// sceNetPortOpen("TCP", sport);
//sceNetPortOpen("TCP", sport);
g_PortManager.Add(sport + portOffset, IP_PROTOCOL_TCP);
// Return PTP Socket Pointer
return i + 1;
@ -2074,7 +2078,8 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int
ptp[i] = internal;
// Add Port Forward to Router
// sceNetPortOpen("TCP", internal->lport);
//sceNetPortOpen("TCP", internal->lport);
g_PortManager.Add(internal->lport + portOffset, IP_PROTOCOL_TCP);
INFO_LOG(SCENET, "sceNetAdhocPtpAccept[%i->%i:%u]: Established (%s:%u)", id, i+1, internal->lport, inet_ntoa(peeraddr.sin_addr), internal->pport);
@ -2264,7 +2269,8 @@ static int sceNetAdhocPtpClose(int id, int unknown) {
closesocket(socket->id);
// Remove Port Forward from Router
// sceNetPortClose("TCP", socket->lport);
//sceNetPortClose("TCP", socket->lport);
//g_PortManager.Remove(socket->lport + portOffset, IP_PROTOCOL_TCP); // Let's not remove mapping in real-time as it could cause lags/disconnection when joining a room with slow routers
// Free Memory
free(socket);
@ -2393,7 +2399,8 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int
ptp[i] = internal;
// Add Port Forward to Router
// sceNetPortOpen("TCP", sport);
//sceNetPortOpen("TCP", sport);
g_PortManager.Add(sport + portOffset, IP_PROTOCOL_TCP);
// Return PTP Socket Pointer
return i + 1;

379
Core/Util/PortManager.cpp Normal file
View File

@ -0,0 +1,379 @@
// Copyright (c) 2013- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// Copyright (c) 2012- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
// Most of the code are based on https://github.com/RJ/libportfwd and updated to the latest miniupnp library
// All credit goes to him and the official miniupnp project! http://miniupnp.free.fr/
#include <string>
#include <Core/System.h>
#include <Core/Host.h>
#include <Core/ELF/ParamSFO.h>
#include "Core/HLE/proAdhoc.h" // This import is only used to get product id that was used to connect to adhoc server
#include "Core/Util/PortManager.h"
#include "i18n/i18n.h"
PortManager g_PortManager;
PortManager::PortManager():
urls(0),
datas(0),
m_InitState(UPNP_INITSTATE_NONE),
m_LocalPort(UPNP_LOCAL_PORT_ANY) {
}
PortManager::~PortManager() {
Clear();
Restore();
Deinit();
}
void PortManager::Deinit() {
if (urls) {
FreeUPNPUrls(urls);
free(urls);
urls = NULL;
}
if (datas) {
free(datas);
datas = NULL;
}
m_otherPortList.clear(); m_otherPortList.shrink_to_fit();
m_portList.clear(); m_portList.shrink_to_fit();
m_lanip.clear();
m_defaultDesc.clear();
m_LocalPort = UPNP_LOCAL_PORT_ANY;
m_InitState = UPNP_INITSTATE_DONE;
}
bool PortManager::Init(const unsigned int timeout) {
// Windows: Assuming WSAStartup already called beforehand
struct UPNPDev* devlist;
struct UPNPDev* dev;
char* descXML;
int descXMLsize = 0;
int descXMLstatus = 0;
int localport = m_LocalPort; // UPNP_LOCAL_PORT_ANY (0), or UPNP_LOCAL_PORT_SAME (1) as an alias for 1900 for backwards compatability?
int ipv6 = 0; // 0 = IPv4, 1 = IPv6
unsigned char ttl = 2; // defaulting to 2
int error = 0;
INFO_LOG(SCENET, "PortManager::Init(%d)", timeout);
if (!g_Config.bEnableUPnP) {
ERROR_LOG(SCENET, "PortManager::Init - UPnP is Disabled on Networking Settings");
return false;
}
if (m_InitState != UPNP_INITSTATE_NONE) {
switch (m_InitState)
{
case UPNP_INITSTATE_BUSY: {
WARN_LOG(SCENET, "PortManager - Initialization already in progress");
return false;
}
// We should redetect UPnP just in case the player switched to a different network in the middle
/*case UPNP_INITSTATE_DONE: {
WARN_LOG(SCENET, "PortManager - Already Initialized");
return false;
}
*/
default:
break;
}
}
m_InitState = UPNP_INITSTATE_BUSY;
urls = (UPNPUrls*)malloc(sizeof(struct UPNPUrls));
datas = (IGDdatas*)malloc(sizeof(struct IGDdatas));
memset(urls, 0, sizeof(struct UPNPUrls));
memset(datas, 0, sizeof(struct IGDdatas));
devlist = upnpDiscover(timeout, NULL, NULL, localport, ipv6, ttl, &error);
if (devlist)
{
dev = devlist;
while (dev)
{
if (strstr(dev->st, "InternetGatewayDevice"))
break;
dev = dev->pNext;
}
if (!dev)
dev = devlist; // defaulting to first device
INFO_LOG(SCENET, "PortManager - UPnP device: [desc: %s] [st: %s]", dev->descURL, dev->st);
descXML = (char*)miniwget(dev->descURL, &descXMLsize, dev->scope_id, &descXMLstatus);
if (descXML)
{
parserootdesc(descXML, descXMLsize, datas);
free(descXML); descXML = 0;
GetUPNPUrls(urls, datas, dev->descURL, dev->scope_id);
}
// Get LAN IP address
char lanaddr[64] = "unset";
int status = UPNP_GetValidIGD(devlist, urls, datas, lanaddr, sizeof(lanaddr)); //possible "status" values, 0 = NO IGD found, 1 = A valid connected IGD has been found, 2 = A valid IGD has been found but it reported as not connected, 3 = an UPnP device has been found but was not recognized as an IGD
m_lanip = std::string(lanaddr);
INFO_LOG(SCENET, "PortManager - Detected LAN IP: %s", m_lanip.c_str());
// Additional Info
char connectionType[64] = "";
if (UPNP_GetConnectionTypeInfo(urls->controlURL, datas->first.servicetype, connectionType) != UPNPCOMMAND_SUCCESS) {
WARN_LOG(SCENET, "PortManager - GetConnectionTypeInfo failed");
}
else {
INFO_LOG(SCENET, "PortManager - Connection Type: %s", connectionType);
}
// Using Game ID & Player Name as default description for mapping (prioritizing the ID sent by the game to Adhoc server)
char productid[10] = { 0 };
memcpy(productid, product_code.data, sizeof(product_code.data));
std::string gameID = std::string(productid);
if (productid[0] == '\0') {
gameID = g_paramSFO.GetDiscID();
}
m_defaultDesc = "PPSSPP:" + gameID + ":" + g_Config.sNickName;
freeUPNPDevlist(devlist);
//m_LocalPort = localport; // We shouldn't keep the right port for the next game reset if we wanted to redetect UPnP
m_InitState = UPNP_INITSTATE_DONE;
RefreshPortList();
return true;
}
ERROR_LOG(SCENET, "PortManager - upnpDiscover failed (error: %d) or No UPnP device detected", error);
auto n = GetI18NCategory("Networking");
host->NotifyUserMessage(n->T("Unable to find UPnP device"), 6.0f, 0x0000ff);
m_InitState = UPNP_INITSTATE_NONE;
return false;
}
int PortManager::GetInitState() {
return m_InitState;
}
bool PortManager::Add(unsigned short port, const char* protocol) {
char port_str[16];
std::string leaseDuration = "43200"; // range(0-604800) in seconds (0 = Indefinite/permanent). Some routers doesn't support non-zero value
int r;
INFO_LOG(SCENET, "PortManager::Add(%d, %s)", port, protocol);
if (urls == NULL || urls->controlURL == NULL || urls->controlURL[0] == '\0')
{
if (g_Config.bEnableUPnP) WARN_LOG(SCENET, "PortManager::Add - the init was not done !");
return false;
}
sprintf(port_str, "%d", port);
// Only add new port map if it's not previously created by PPSSPP for current IP
auto el_it = std::find_if(m_portList.begin(), m_portList.end(),
[port_str, protocol](const std::pair<std::string, std::string> &el) { return el.first == port_str && el.second == protocol; });
if (el_it == m_portList.end()) {
auto el_it = std::find_if(m_otherPortList.begin(), m_otherPortList.end(),
[port_str, protocol](const PortMap& el) { return el.extPort_str == port_str && el.protocol == protocol; });
if (el_it != m_otherPortList.end()) {
// Try to delete the port mapping before we create it, just in case we have dangling port mapping from the daemon not being shut down correctly or the port was taken by other
r = UPNP_DeletePortMapping(urls->controlURL, datas->first.servicetype, port_str, protocol, NULL);
}
r = UPNP_AddPortMapping(urls->controlURL, datas->first.servicetype,
port_str, port_str, m_lanip.c_str(), m_defaultDesc.c_str(), protocol, NULL, leaseDuration.c_str());
if (r != 0)
{
ERROR_LOG(SCENET, "PortManager - AddPortMapping failed (error: %d)", r);
auto n = GetI18NCategory("Networking");
host->NotifyUserMessage(n->T("UPnP need to be reinitialized"), 6.0f, 0x0000ff);
Deinit(); // Most of the time errors occurred because the router is no longer reachable (ie. changed networks) so we should invalidate the state to prevent further lags due to timeouts
return false;
}
m_portList.push_front({ port_str, protocol });
// Keep tracks of it to be restored later if it belongs to others
if (el_it != m_otherPortList.end()) el_it->taken = true;
}
return true;
}
bool PortManager::Remove(unsigned short port, const char* protocol) {
char port_str[16];
INFO_LOG(SCENET, "PortManager::Remove(%d, %s)", port, protocol);
if (urls == NULL || urls->controlURL == NULL || urls->controlURL[0] == '\0')
{
if (g_Config.bEnableUPnP) WARN_LOG(SCENET, "PortManager::Remove - the init was not done !");
return false;
}
sprintf(port_str, "%d", port);
int r = UPNP_DeletePortMapping(urls->controlURL, datas->first.servicetype, port_str, protocol, NULL);
if (r != 0)
{
ERROR_LOG(SCENET, "PortManager - DeletePortMapping failed (error: %d)", r);
auto n = GetI18NCategory("Networking");
host->NotifyUserMessage(n->T("UPnP need to be reinitialized"), 6.0f, 0x0000ff);
Deinit(); // Most of the time errors occurred because the router is no longer reachable (ie. changed networks) so we should invalidate the state to prevent further lags due to timeouts
return false;
}
for (auto it = m_portList.begin(); it != m_portList.end(); ) {
(it->first == port_str && it->second == protocol) ? it = m_portList.erase(it) : ++it;
}
return true;
}
bool PortManager::Restore() {
int r;
INFO_LOG(SCENET, "PortManager::Restore()");
if (urls == NULL || urls->controlURL == NULL || urls->controlURL[0] == '\0')
{
if (g_Config.bEnableUPnP) WARN_LOG(SCENET, "PortManager::Remove - the init was not done !");
return false;
}
for (auto it = m_otherPortList.begin(); it != m_otherPortList.end(); ++it) {
if (it->taken) {
auto port_str = it->extPort_str;
auto protocol = it->protocol;
// Remove it first if it's still being taken by PPSSPP
auto el_it = std::find_if(m_portList.begin(), m_portList.end(),
[port_str, protocol](const std::pair<std::string, std::string>& el) { return el.first == port_str && el.second == protocol; });
if (el_it != m_portList.end()) {
r = UPNP_DeletePortMapping(urls->controlURL, datas->first.servicetype, port_str.c_str(), protocol.c_str(), NULL);
if (r == 0) {
m_portList.erase(el_it);
}
else {
ERROR_LOG(SCENET, "PortManager::Restore - DeletePortMapping failed (error: %d)", r);
return false; // Might be better not to exit here, but exiting a loop will avoid long timeouts in the case the router is no longer reachable
}
}
// Add the original owner back
r = UPNP_AddPortMapping(urls->controlURL, datas->first.servicetype,
it->extPort_str.c_str(), it->intPort_str.c_str(), it->lanip.c_str(), it->desc.c_str(), it->protocol.c_str(), it->remoteHost.c_str(), it->duration.c_str());
if (r == 0) {
it->taken = false;
}
else {
ERROR_LOG(SCENET, "PortManager::Restore - AddPortMapping failed (error: %d)", r);
return false; // Might be better not to exit here, but exiting a loop will avoid long timeouts in the case the router is no longer reachable
}
}
}
return true;
}
bool PortManager::Clear() {
int r;
int i = 0;
char index[6];
char intAddr[40];
char intPort[6];
char extPort[6];
char protocol[4];
char desc[80];
char enabled[6];
char rHost[64];
char duration[16];
INFO_LOG(SCENET, "PortManager::Clear()");
if (urls == NULL || urls->controlURL == NULL || urls->controlURL[0] == '\0')
{
if (g_Config.bEnableUPnP) WARN_LOG(SCENET, "PortManager::Clear - the init was not done !");
return false;
}
//unsigned int num = 0;
//UPNP_GetPortMappingNumberOfEntries(urls->controlURL, datas->first.servicetype, &num); // Not supported by many routers
do {
snprintf(index, 6, "%d", i);
rHost[0] = '\0'; enabled[0] = '\0';
duration[0] = '\0'; desc[0] = '\0';
extPort[0] = '\0'; intPort[0] = '\0'; intAddr[0] = '\0';
r = UPNP_GetGenericPortMappingEntry(urls->controlURL,
datas->first.servicetype,
index,
extPort, intAddr, intPort,
protocol, desc, enabled,
rHost, duration);
// Only removes port mappings created by PPSSPP for current LAN IP
if (r == 0 && intAddr == m_lanip && std::strncmp(desc, "PPSSPP", 6) == 0) {
int r2 = UPNP_DeletePortMapping(urls->controlURL, datas->first.servicetype, extPort, protocol, rHost);
if (r2 != 0)
{
ERROR_LOG(SCENET, "PortManager::Clear - DeletePortMapping(%s, %s) failed (error: %d)", extPort, protocol, r2);
return false;
}
else {
i--;
for (auto it = m_portList.begin(); it != m_portList.end(); ) {
(it->first == extPort && it->second == protocol) ? it = m_portList.erase(it) : ++it;
}
}
}
i++;
} while (r == 0);
return true;
}
bool PortManager::RefreshPortList() {
int r;
int i = 0;
char index[6];
char intAddr[40];
char intPort[6];
char extPort[6];
char protocol[4];
char desc[80];
char enabled[6];
char rHost[64];
char duration[16];
INFO_LOG(SCENET, "PortManager::RefreshPortList()");
if (urls == NULL || urls->controlURL == NULL || urls->controlURL[0] == '\0')
{
if (g_Config.bEnableUPnP) WARN_LOG(SCENET, "PortManager::RefreshPortList - the init was not done !");
return false;
}
m_portList.clear();
m_otherPortList.clear();
//unsigned int num = 0;
//UPNP_GetPortMappingNumberOfEntries(urls->controlURL, datas->first.servicetype, &num); // Not supported by many routers
do {
snprintf(index, 6, "%d", i);
rHost[0] = '\0'; enabled[0] = '\0';
duration[0] = '\0'; desc[0] = '\0';
extPort[0] = '\0'; intPort[0] = '\0'; intAddr[0] = '\0';
r = UPNP_GetGenericPortMappingEntry(urls->controlURL,
datas->first.servicetype,
index,
extPort, intAddr, intPort,
protocol, desc, enabled,
rHost, duration);
if (r == 0) {
// Only include port mappings created by PPSSPP for current LAN IP
if (intAddr == m_lanip && std::strncmp(desc, "PPSSPP", 6) == 0) {
m_portList.push_back({ extPort, protocol });
}
// Port mappings belong to others that might be taken by PPSSPP later
else {
m_otherPortList.push_back({ false, protocol, extPort, intPort, intAddr, rHost, desc, duration, enabled });
}
}
i++;
} while (r == 0);
return true;
}

99
Core/Util/PortManager.h Normal file
View File

@ -0,0 +1,99 @@
// Copyright (c) 2013- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
// Most of the code are based on https://github.com/RJ/libportfwd and updated to the latest miniupnp library
// All credit goes to him and the official miniupnp project! http://miniupnp.free.fr/
#pragma once
#ifndef MINIUPNP_STATICLIB
#define MINIUPNP_STATICLIB
#endif
#include "ext/miniupnp/miniupnpc/miniwget.h"
#include "ext/miniupnp/miniupnpc/miniupnpc.h"
#include "ext/miniupnp/miniupnpc/upnpcommands.h"
#include <string>
#include <deque>
#define IP_PROTOCOL_TCP "TCP"
#define IP_PROTOCOL_UDP "UDP"
#define UPNP_INITSTATE_NONE 0
#define UPNP_INITSTATE_BUSY 1
#define UPNP_INITSTATE_DONE 2
struct UPNPUrls;
struct IGDdatas;
struct PortMap {
bool taken;
std::string protocol;
std::string extPort_str;
std::string intPort_str;
std::string lanip;
std::string remoteHost;
std::string desc;
std::string duration;
std::string enabled;
};
class PortManager {
public:
PortManager();
~PortManager();
// Initialize UPnP
// timeout: milliseconds to wait for a router to respond (default = 2000 ms)
bool Init(const unsigned int timeout = 2000);
// Uninitialize/Reset the state
void Deinit();
// Get UPnP Initialization status
int GetInitState();
// Add a port & protocol (TCP, UDP or vendor-defined) to map for forwarding
bool Add(unsigned short port, const char* protocol);
// Remove a port mapping
bool Remove(unsigned short port, const char* protocol);
// Removes any lingering mapped ports from previous crashes
bool Clear();
// Restore ports mapped by others that were taken by PPSSPP, better used after Clear()
bool Restore();
// Get port list mapped by PPSSPP for current LAN IP & others
bool RefreshPortList();
protected:
struct UPNPUrls* urls = NULL;
struct IGDdatas* datas = NULL;
int m_InitState = UPNP_INITSTATE_NONE;
int m_LocalPort = UPNP_LOCAL_PORT_ANY;
std::string m_lanip;
std::string m_defaultDesc;
std::deque<std::pair<std::string, std::string>> m_portList;
std::deque<PortMap> m_otherPortList;
};
extern PortManager g_PortManager;

View File

@ -690,6 +690,7 @@ void GameSettingsScreen::CreateViews() {
networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.proAdhocServer, n->T("Change proAdhocServer Address"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeproAdhocServerAddress);
networkingSettings->Add(new CheckBox(&g_Config.bEnableAdhocServer, n->T("Enable built-in PRO Adhoc Server", "Enable built-in PRO Adhoc Server")));
networkingSettings->Add(new CheckBox(&g_Config.bEnableUPnP, n->T("Enable UPnP", "Enable UPnP (need a few seconds to detect)")));
networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sMACAddress, n->T("Change Mac Address"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeMacAddress);
networkingSettings->Add(new PopupSliderChoice(&g_Config.iPortOffset, 0, 60000, n->T("Port offset", "Port offset(0 = PSP compatibility)"), 100, screenManager()));

View File

@ -83,6 +83,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AtlasTool", "..\ext\native\
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZimTool", "..\ext\native\tools\ZimTool\ZimTool.vcxproj", "{B7DED405-40A2-48F8-9382-538F10D442F1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc", "..\ext\miniupnpc.vcxproj", "{D8A71225-178B-424E-96C1-CC3BE2C1B047}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
@ -337,6 +339,18 @@ Global
{B7DED405-40A2-48F8-9382-538F10D442F1}.Release|Win32.ActiveCfg = Release|x64
{B7DED405-40A2-48F8-9382-538F10D442F1}.Release|x64.ActiveCfg = Release|x64
{B7DED405-40A2-48F8-9382-538F10D442F1}.Release|x64.Build.0 = Release|x64
{D8A71225-178B-424E-96C1-CC3BE2C1B047}.Debug|ARM.ActiveCfg = Debug|Win32
{D8A71225-178B-424E-96C1-CC3BE2C1B047}.Debug|ARM64.ActiveCfg = Debug|Win32
{D8A71225-178B-424E-96C1-CC3BE2C1B047}.Debug|Win32.ActiveCfg = Debug|Win32
{D8A71225-178B-424E-96C1-CC3BE2C1B047}.Debug|Win32.Build.0 = Debug|Win32
{D8A71225-178B-424E-96C1-CC3BE2C1B047}.Debug|x64.ActiveCfg = Debug|x64
{D8A71225-178B-424E-96C1-CC3BE2C1B047}.Debug|x64.Build.0 = Debug|x64
{D8A71225-178B-424E-96C1-CC3BE2C1B047}.Release|ARM.ActiveCfg = Release|Win32
{D8A71225-178B-424E-96C1-CC3BE2C1B047}.Release|ARM64.ActiveCfg = Release|Win32
{D8A71225-178B-424E-96C1-CC3BE2C1B047}.Release|Win32.ActiveCfg = Release|Win32
{D8A71225-178B-424E-96C1-CC3BE2C1B047}.Release|Win32.Build.0 = Release|Win32
{D8A71225-178B-424E-96C1-CC3BE2C1B047}.Release|x64.ActiveCfg = Release|x64
{D8A71225-178B-424E-96C1-CC3BE2C1B047}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

1
ext/miniupnp Submodule

@ -0,0 +1 @@
Subproject commit 927e2f36666f543d59a8080686921069832a3393

251
ext/miniupnpc.vcxproj Normal file
View File

@ -0,0 +1,251 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="miniupnp\miniupnpc\connecthostport.h" />
<ClInclude Include="miniupnp\miniupnpc\igd_desc_parse.h" />
<ClInclude Include="miniupnp\miniupnpc\minisoap.h" />
<ClInclude Include="miniupnp\miniupnpc\minissdpc.h" />
<ClInclude Include="miniupnp\miniupnpc\miniupnpc.h" />
<ClInclude Include="miniupnp\miniupnpc\miniwget.h" />
<ClInclude Include="miniupnp\miniupnpc\minixml.h" />
<ClInclude Include="miniupnp\miniupnpc\portlistingparse.h" />
<ClInclude Include="miniupnp\miniupnpc\receivedata.h" />
<ClInclude Include="miniupnp\miniupnpc\upnpcommands.h" />
<ClInclude Include="miniupnp\miniupnpc\upnpdev.h" />
<ClInclude Include="miniupnp\miniupnpc\upnperrors.h" />
<ClInclude Include="miniupnp\miniupnpc\upnpreplyparse.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="miniupnp\miniupnpc\connecthostport.c" />
<ClCompile Include="miniupnp\miniupnpc\igd_desc_parse.c" />
<ClCompile Include="miniupnp\miniupnpc\minisoap.c" />
<ClCompile Include="miniupnp\miniupnpc\minissdpc.c" />
<ClCompile Include="miniupnp\miniupnpc\miniupnpc.c" />
<ClCompile Include="miniupnp\miniupnpc\miniwget.c" />
<ClCompile Include="miniupnp\miniupnpc\minixml.c" />
<ClCompile Include="miniupnp\miniupnpc\minixmlvalid.c" />
<ClCompile Include="miniupnp\miniupnpc\portlistingparse.c" />
<ClCompile Include="miniupnp\miniupnpc\receivedata.c" />
<ClCompile Include="miniupnp\miniupnpc\upnpcommands.c" />
<ClCompile Include="miniupnp\miniupnpc\upnpdev.c" />
<ClCompile Include="miniupnp\miniupnpc\upnperrors.c" />
<ClCompile Include="miniupnp\miniupnpc\upnpreplyparse.c" />
</ItemGroup>
<ItemGroup>
<None Include="miniupnp\miniupnpc\msvc\genminiupnpcstrings.vbs">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</None>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{D8A71225-178B-424E-96C1-CC3BE2C1B047}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>miniupnpc</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>false</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|Win32'">
<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|Win32'">
<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)'=='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|Win32'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IntDir>$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>
</SDLCheck>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<PreprocessorDefinitions>DEBUG;_DEBUG;WIN32;_LIB;MINIUPNP_STATICLIB;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PreBuildEvent>
<Command>cd miniupnp\miniupnpc\msvc
genminiupnpcstrings.vbs
cd..\..\..</Command>
</PreBuildEvent>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalDependencies>iphlpapi.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>DEBUG;_DEBUG;WIN32;_LIB;MINIUPNP_STATICLIB;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PreBuildEvent>
<Command>cd miniupnp\miniupnpc\msvc
genminiupnpcstrings.vbs
cd..\..\..</Command>
</PreBuildEvent>
<Lib>
<AdditionalDependencies>iphlpapi.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>
</SDLCheck>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<PreprocessorDefinitions>NDEBUG;WIN32;_LIB;MINIUPNP_STATICLIB;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PreBuildEvent>
<Command>cd miniupnp\miniupnpc\msvc
genminiupnpcstrings.vbs
cd..\..\..</Command>
</PreBuildEvent>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalDependencies>iphlpapi.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>NDEBUG;WIN32;_LIB;MINIUPNP_STATICLIB;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<AdditionalDependencies>iphlpapi.lib</AdditionalDependencies>
</Lib>
<PreBuildEvent>
<Command>cd miniupnp\miniupnpc\msvc
genminiupnpcstrings.vbs
cd..\..\..</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="miniupnp\miniupnpc\upnpcommands.h" />
<ClInclude Include="miniupnp\miniupnpc\upnperrors.h" />
<ClInclude Include="miniupnp\miniupnpc\upnpreplyparse.h" />
<ClInclude Include="miniupnp\miniupnpc\igd_desc_parse.h" />
<ClInclude Include="miniupnp\miniupnpc\minisoap.h" />
<ClInclude Include="miniupnp\miniupnpc\miniupnpc.h" />
<ClInclude Include="miniupnp\miniupnpc\miniwget.h" />
<ClInclude Include="miniupnp\miniupnpc\minixml.h" />
<ClInclude Include="miniupnp\miniupnpc\connecthostport.h" />
<ClInclude Include="miniupnp\miniupnpc\portlistingparse.h" />
<ClInclude Include="miniupnp\miniupnpc\receivedata.h" />
<ClInclude Include="miniupnp\miniupnpc\upnpdev.h" />
<ClInclude Include="miniupnp\miniupnpc\minissdpc.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="miniupnp\miniupnpc\igd_desc_parse.c" />
<ClCompile Include="miniupnp\miniupnpc\minisoap.c" />
<ClCompile Include="miniupnp\miniupnpc\miniupnpc.c" />
<ClCompile Include="miniupnp\miniupnpc\miniwget.c" />
<ClCompile Include="miniupnp\miniupnpc\minixml.c" />
<ClCompile Include="miniupnp\miniupnpc\minixmlvalid.c" />
<ClCompile Include="miniupnp\miniupnpc\upnpcommands.c" />
<ClCompile Include="miniupnp\miniupnpc\upnperrors.c" />
<ClCompile Include="miniupnp\miniupnpc\upnpreplyparse.c" />
<ClCompile Include="miniupnp\miniupnpc\connecthostport.c" />
<ClCompile Include="miniupnp\miniupnpc\portlistingparse.c" />
<ClCompile Include="miniupnp\miniupnpc\receivedata.c" />
<ClCompile Include="miniupnp\miniupnpc\upnpdev.c" />
<ClCompile Include="miniupnp\miniupnpc\minissdpc.c" />
</ItemGroup>
<ItemGroup>
<Filter Include="scripts">
<UniqueIdentifier>{c82edf03-bf88-478d-aaf5-2854df756cab}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="miniupnp\miniupnpc\msvc\genminiupnpcstrings.vbs">
<Filter>scripts</Filter>
</None>
</ItemGroup>
</Project>