Integrate miniupnpc.
This should bring it up to about the state of the patches and comments in ticket #1073, without the threaded device detection. Timeout is 500ms, that should be enough to detect a LAN device, and doesn't delay startup too much. Port r8447 plus the fixes for it in r8449, r8453, r8455 and r8456 to trunk. git-svn-id: https://warzone2100.svn.sourceforge.net/svnroot/warzone2100/trunk@8460 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
03607b0fb8
commit
a7ae06572d
|
@ -383,6 +383,7 @@ AC_CONFIG_FILES([Makefile
|
|||
lib/ivis_opengl/Makefile
|
||||
lib/ivis_common/Makefile
|
||||
lib/netplay/Makefile
|
||||
lib/netplay/miniupnpc/Makefile
|
||||
lib/script/Makefile
|
||||
lib/sequence/Makefile
|
||||
lib/sound/Makefile
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
SUBDIRS = miniupnpc
|
||||
|
||||
AM_CPPFLAGS = $(SDL_CFLAGS) $(WZ_CPPFLAGS)
|
||||
AM_CFLAGS = $(WZ_CFLAGS)
|
||||
|
||||
|
@ -13,4 +15,4 @@ libnetplay_a_SOURCES = \
|
|||
netplay.c \
|
||||
nettypes.c
|
||||
|
||||
libnetplay_a_LIBADD = $(top_builddir)/lib/framework/libframework.a
|
||||
libnetplay_a_LIBADD = $(top_builddir)/lib/framework/libframework.a $(top_builddir)/lib/netplay/miniupnpc/libminiupnpc.a
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
AM_CPPFLAGS = -DSTATICLIB $(SDL_CFLAGS) $(WZ_CPPFLAGS)
|
||||
AM_CFLAGS = -DSTATICLIB $(WZ_CFLAGS)
|
||||
|
||||
noinst_LIBRARIES = libminiupnpc.a
|
||||
noinst_HEADERS = \
|
||||
miniupnpc.h \
|
||||
miniupnpcstrings.h \
|
||||
miniwget.h \
|
||||
minixml.h \
|
||||
minisoap.h \
|
||||
minissdpc.h \
|
||||
codelength.h \
|
||||
upnpcommands.h \
|
||||
igd_desc_parse.h \
|
||||
upnpreplyparse.h \
|
||||
upnperrors.h \
|
||||
declspec.h
|
||||
|
||||
libminiupnpc_a_SOURCES = \
|
||||
miniwget.c \
|
||||
minixml.c \
|
||||
igd_desc_parse.c \
|
||||
minisoap.c \
|
||||
miniupnpc.c \
|
||||
upnpreplyparse.c \
|
||||
upnpcommands.c \
|
||||
minissdpc.c \
|
||||
upnperrors.c
|
|
@ -5,7 +5,9 @@
|
|||
#ifdef MINIUPNP_EXPORTS
|
||||
#define LIBSPEC __declspec(dllexport)
|
||||
#else
|
||||
#define LIBSPEC __declspec(dllimport)
|
||||
// NOTE: with the cross compiler, even if we have -DSTATICLIB, for some odd reason it still does this
|
||||
// #define LIBSPEC __declspec(dllimport) which is not what we want. So we hack the line like so.
|
||||
#define LIBSPEC
|
||||
#endif
|
||||
#else
|
||||
#define LIBSPEC
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "minisoap.h"
|
||||
#include "miniupnpcstrings.h"
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
/* only for malloc */
|
||||
#include <stdlib.h>
|
||||
|
||||
|
|
|
@ -8,12 +8,15 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <io.h>
|
||||
// Warzone additions
|
||||
#include "lib/framework/types.h"
|
||||
typedef SSIZE_T ssize_t;
|
||||
// end WZ
|
||||
/* Hack */
|
||||
#define UNIX_PATH_LEN 108
|
||||
struct sockaddr_un {
|
||||
|
@ -23,6 +26,7 @@ struct sockaddr_un {
|
|||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "minissdpc.h"
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "declspec.h"
|
||||
#include "igd_desc_parse.h"
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/* $Id: miniupnpcstrings.h.in,v 1.2 2009/10/30 09:18:18 nanard Exp $ */
|
||||
/* Project: miniupnp
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* Author: Thomas Bernard
|
||||
* Copyright (c) 2005-2009 Thomas Bernard
|
||||
* This software is subjects to the conditions detailed
|
||||
* in the LICENCE file provided within this distribution */
|
||||
#ifndef __MINIUPNPCSTRINGS_H__
|
||||
#define __MINIUPNPCSTRINGS_H__
|
||||
|
||||
#include "lib/framework/wzglobal.h"
|
||||
|
||||
#if defined(WZ_OS_WIN32)
|
||||
#define OS_STRING "Windows"
|
||||
#elif defined (WZ_OS_MAC)
|
||||
#define OS_STRING "Mac OS"
|
||||
#elif defined(WZ_OS_LINUX)
|
||||
#define OS_STRING "Linux"
|
||||
#else
|
||||
#define OS_STRING "Other/unknown"
|
||||
#endif
|
||||
|
||||
#define MINIUPNPC_VERSION_STRING "1.4"
|
||||
|
||||
#endif
|
||||
|
|
@ -35,6 +35,10 @@
|
|||
#include "netplay.h"
|
||||
#include "netlog.h"
|
||||
|
||||
#include "miniupnpc/miniwget.h"
|
||||
#include "miniupnpc/miniupnpc.h"
|
||||
#include "miniupnpc/upnpcommands.h"
|
||||
|
||||
#if defined(WZ_OS_UNIX)
|
||||
# include <arpa/inet.h>
|
||||
# include <errno.h>
|
||||
|
@ -223,6 +227,15 @@ static NETBUFSOCKET* bsocket = NULL; //buffered socket (holds tcp_socket) (clie
|
|||
static NETBUFSOCKET* connected_bsocket[MAX_CONNECTED_PLAYERS] = { NULL };
|
||||
static SocketSet* socket_set = NULL;
|
||||
|
||||
// UPnP
|
||||
static int upnp = false;
|
||||
|
||||
static struct UPNPUrls urls;
|
||||
static struct IGDdatas data;
|
||||
|
||||
// local ip address
|
||||
static char lanaddr[16];
|
||||
|
||||
/**
|
||||
* Used for connections with clients.
|
||||
*/
|
||||
|
@ -1793,6 +1806,104 @@ static bool NETrecvGAMESTRUCT(GAMESTRUCT* game)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int upnp_init(void *asdf)
|
||||
{
|
||||
struct UPNPDev *devlist;
|
||||
struct UPNPDev *dev;
|
||||
char *descXML;
|
||||
int descXMLsize = 0;
|
||||
|
||||
memset(&urls, 0, sizeof(struct UPNPUrls));
|
||||
memset(&data, 0, sizeof(struct IGDdatas));
|
||||
|
||||
debug(LOG_NET, "Searching for UPnP devices for automatic port forwarding...");
|
||||
devlist = upnpDiscover(500, NULL, NULL, 0);
|
||||
debug(LOG_NET, "UPnP device search finished.");
|
||||
if (devlist)
|
||||
{
|
||||
dev = devlist;
|
||||
while (dev)
|
||||
{
|
||||
if (strstr(dev->st, "InternetGatewayDevice"))
|
||||
break;
|
||||
dev = dev->pNext;
|
||||
}
|
||||
if (!dev)
|
||||
{
|
||||
dev = devlist; /* defaulting to first device */
|
||||
}
|
||||
|
||||
debug(LOG_NET, "UPnP device found: %s %s\n", dev->descURL, dev->st);
|
||||
|
||||
descXML = miniwget_getaddr(dev->descURL, &descXMLsize, lanaddr, sizeof(lanaddr));
|
||||
debug(LOG_NET, "LAN address: %s", lanaddr);
|
||||
if (descXML)
|
||||
{
|
||||
parserootdesc (descXML, descXMLsize, &data);
|
||||
free (descXML); descXML = 0;
|
||||
GetUPNPUrls (&urls, &data, dev->descURL);
|
||||
}
|
||||
freeUPNPDevlist(devlist);
|
||||
|
||||
if (urls.controlURL[0] == '\0')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
debug(LOG_NET, "No UPnP devices found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool upnp_add_redirect(int port)
|
||||
{
|
||||
char externalIP[16];
|
||||
char port_str[16];
|
||||
int r;
|
||||
|
||||
debug(LOG_NET, "upnp_add_redir(%d)\n", port);
|
||||
UPNP_GetExternalIPAddress(urls.controlURL, data.servicetype, externalIP);
|
||||
sprintf(port_str, "%d", port);
|
||||
r = UPNP_AddPortMapping(urls.controlURL, data.servicetype,
|
||||
port_str, port_str, lanaddr, "Warzone 2100", "TCP", 0);
|
||||
if (r != UPNPCOMMAND_SUCCESS)
|
||||
{
|
||||
debug(LOG_NET, "AddPortMapping(%s, %s, %s) failed\n", port_str, port_str, lanaddr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
static void upnp_rem_redirect(int port)
|
||||
{
|
||||
char port_str[16];
|
||||
debug(LOG_NET, "upnp_rem_redir(%d)", port);
|
||||
sprintf(port_str, "%d", port);
|
||||
UPNP_DeletePortMapping(urls.controlURL, data.servicetype, port_str, "TCP", 0);
|
||||
}
|
||||
|
||||
void NETaddRedirects(void)
|
||||
{
|
||||
debug(LOG_NET, "%s\n", __FUNCTION__);
|
||||
if (upnp) {
|
||||
upnp_add_redirect(2100);
|
||||
upnp_add_redirect(9990);
|
||||
}
|
||||
}
|
||||
|
||||
void NETremRedirects(void)
|
||||
{
|
||||
debug(LOG_NET, "%s\n", __FUNCTION__);
|
||||
if (upnp)
|
||||
{
|
||||
upnp_rem_redirect(2100);
|
||||
upnp_rem_redirect(9990);
|
||||
}
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
// setup stuff
|
||||
int NETinit(BOOL bFirstCall)
|
||||
|
@ -1805,6 +1916,30 @@ int NETinit(BOOL bFirstCall)
|
|||
{
|
||||
debug(LOG_NET, "NETPLAY: Init called, MORNIN'");
|
||||
|
||||
#if defined(WZ_OS_WIN)
|
||||
{
|
||||
static WSADATA stuff;
|
||||
WORD ver_required = (2 << 8) + 2;
|
||||
if (WSAStartup(ver_required, &stuff) != 0)
|
||||
{
|
||||
debug(LOG_ERROR, "Failed to initialize Winsock: %s", strSockError(getSockErr()));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
winsock2_dll = LoadLibraryA("ws2_32.dll");
|
||||
if (winsock2_dll)
|
||||
{
|
||||
getaddrinfo_dll_func = GetProcAddress(winsock2_dll, "getaddrinfo");
|
||||
freeaddrinfo_dll_func = GetProcAddress(winsock2_dll, "freeaddrinfo");
|
||||
}
|
||||
|
||||
// Determine major Windows version
|
||||
major_windows_version = LOBYTE(LOWORD(GetVersion()));
|
||||
#endif
|
||||
|
||||
upnp = upnp_init(NULL);
|
||||
|
||||
for(i = 0; i < MAX_PLAYERS; i++)
|
||||
{
|
||||
memset(&NetPlay.games[i], 0, sizeof(NetPlay.games[i]));
|
||||
|
@ -1818,28 +1953,6 @@ int NETinit(BOOL bFirstCall)
|
|||
NETstartLogging();
|
||||
}
|
||||
|
||||
#if defined(WZ_OS_WIN)
|
||||
{
|
||||
static WSADATA stuff;
|
||||
WORD ver_required = (2 << 8) + 2;
|
||||
if (WSAStartup(ver_required, &stuff) != 0)
|
||||
{
|
||||
debug(LOG_ERROR, "Failed to initialize Winsock: %s", strSockError(getSockErr()));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
winsock2_dll = LoadLibraryA("ws2_32.dll");
|
||||
if (winsock2_dll)
|
||||
{
|
||||
getaddrinfo_dll_func = GetProcAddress(winsock2_dll, "getaddrinfo");
|
||||
freeaddrinfo_dll_func = GetProcAddress(winsock2_dll, "freeaddrinfo");
|
||||
}
|
||||
|
||||
// Determine major Windows version
|
||||
major_windows_version = LOBYTE(LOWORD(GetVersion()));
|
||||
#endif
|
||||
|
||||
NetPlay.ShowedMOTD = false;
|
||||
NetPlay.GamePassworded = false;
|
||||
|
||||
|
@ -1867,6 +1980,8 @@ int NETshutdown(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
NETremRedirects();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3074,6 +3189,7 @@ BOOL NEThostGame(const char* SessionName, const char* PlayerName,
|
|||
debug(LOG_NET, "NEThostGame(%s, %s, %d, %d, %d, %d, %u)", SessionName, PlayerName,
|
||||
one, two, three, four, plyrs);
|
||||
|
||||
NETaddRedirects();
|
||||
NET_InitPlayers();
|
||||
NetPlay.maxPlayers = MAX_PLAYERS;
|
||||
if(!NetPlay.bComms)
|
||||
|
|
|
@ -238,6 +238,9 @@ extern UBYTE NETrecvFile(void); // recv file chunk
|
|||
extern int NETclose(void); // close current game
|
||||
extern int NETshutdown(void); // leave the game in play.
|
||||
|
||||
extern void NETaddRedirects(void);
|
||||
extern void NETremRedirects(void);
|
||||
|
||||
extern UDWORD NETgetBytesSent(void); // return bytes sent/recv. call regularly for good results
|
||||
extern UDWORD NETgetPacketsSent(void); // return packets sent/recv. call regularly for good results
|
||||
extern UDWORD NETgetBytesRecvd(void); // return bytes sent/recv. call regularly for good results
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
ProjectGUID="{C7698ECE-9255-4A60-8091-A9A76E8BE911}"
|
||||
RootNamespace="netplay"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
|
@ -42,7 +41,7 @@
|
|||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""$(SolutionDir)\..";"$(SolutionDir)\..\devpkg\include";"$(SolutionDir)\..\devpkg\include\SDL""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;STATICLIB"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
|
@ -105,7 +104,7 @@
|
|||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""$(SolutionDir)\..";"$(SolutionDir)\..\devpkg\include";"$(SolutionDir)\..\devpkg\include\SDL""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;STATICLIB"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
|
@ -165,6 +164,106 @@
|
|||
RelativePath=".\nettypes.c"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="miniUPnP"
|
||||
>
|
||||
<Filter
|
||||
Name="src files"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\igd_desc_parse.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\minisoap.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\minissdpc.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\miniupnpc.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\miniwget.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\minixml.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\upnpcommands.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\upnperrors.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\upnpreplyparse.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="header files"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\bsdqueue.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\codelength.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\declspec.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\igd_desc_parse.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\minisoap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\minissdpc.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\miniupnpc.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\miniupnpcstrings.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\miniwget.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\minixml.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\upnpcommands.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\upnperrors.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\miniupnpc\upnpreplyparse.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
|
|
|
@ -289,6 +289,7 @@ warzone2100_LDADD = \
|
|||
$(top_builddir)/lib/sound/libsound.a \
|
||||
$(top_builddir)/lib/script/libscript.a \
|
||||
$(top_builddir)/lib/netplay/libnetplay.a \
|
||||
$(top_builddir)/lib/netplay/miniupnpc/libminiupnpc.a \
|
||||
$(top_builddir)/lib/ivis_opengl/libivis_opengl.a \
|
||||
$(top_builddir)/lib/ivis_common/libivis_common.a \
|
||||
$(top_builddir)/lib/gamelib/libgamelib.a \
|
||||
|
|
|
@ -2101,6 +2101,7 @@ static void stopJoining(void)
|
|||
widgDelete(psWScreen,FRONTEND_BACKDROP); // refresh options screen.
|
||||
startMultiOptions(true);
|
||||
ingame.localJoiningInProgress = false;
|
||||
NETremRedirects();
|
||||
return;
|
||||
}
|
||||
else if(ingame.localJoiningInProgress) // cancel a joined game.
|
||||
|
|
|
@ -720,6 +720,7 @@ BOOL multiGameShutdown(void)
|
|||
|
||||
// close game
|
||||
NETclose();
|
||||
NETremRedirects();
|
||||
|
||||
if (ingame.numStructureLimits)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue