Skip to content

Commit 415e002

Browse files
committed
Server: Allow hosting a simple HTTP server which serves an HTML about waiting lobbies
A new "enablehttp" option was added, which makes the server application create another listening socket on port 80 for a simple HTTP server. It only serves a root HTML page, which contains a table with the amount of waiting lobbies. The waiting lobbies page separates lobbies, based on match skill level, if "skiplevel" is not set. Otherwise, a single counter is only shown on version/game. This page aims to make it easy for players to find others to play with.
1 parent ca5037a commit 415e002

File tree

8 files changed

+369
-13
lines changed

8 files changed

+369
-13
lines changed

InternetGamesServer/Config.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Config::Config() :
1515
port(DEFAULT_PORT),
1616
logsDirectory(DEFAULT_LOGS_DIRECTORY),
1717
numConnectionsPerIP(0),
18+
enableHTTP(false),
1819
skipLevelMatching(false),
1920
allowSinglePlayer(true),
2021
disableXPAdBanner(false),
@@ -75,6 +76,11 @@ Config::Load(const std::string& file)
7576
}
7677
}
7778
}
79+
{
80+
tinyxml2::XMLElement* elEnableHTTP = elRoot->FirstChildElement("EnableHTTP");
81+
if (elEnableHTTP && elEnableHTTP->GetText())
82+
enableHTTP = *elEnableHTTP->GetText() == '1';
83+
}
7884
{
7985
tinyxml2::XMLElement* elSkipLevelMatching = elRoot->FirstChildElement("SkipLevelMatching");
8086
if (elSkipLevelMatching && elSkipLevelMatching->GetText())
@@ -115,6 +121,7 @@ Config::Save()
115121
NewElementWithText(elRoot, "Port", port);
116122
NewElementWithText(elRoot, "LogsDirectory", logsDirectory.c_str());
117123
NewElementWithText(elRoot, "NumConnectionsPerIP", numConnectionsPerIP);
124+
NewElementWithText(elRoot, "EnableHTTP", enableHTTP ? "1" : "0");
118125
NewElementWithText(elRoot, "SkipLevelMatching", skipLevelMatching ? "1" : "0");
119126
NewElementWithText(elRoot, "AllowSinglePlayer", allowSinglePlayer ? "1" : "0");
120127
NewElementWithText(elRoot, "DisableXPAdBanner", disableXPAdBanner ? "1" : "0");
@@ -136,6 +143,7 @@ const std::initializer_list<std::pair<std::string, std::string>> Config::s_optio
136143
{ "port", "The port the server should be hosted on. Requires restart to apply. (Default: 28805)" },
137144
{ "logdir", "The directory where log files are written to. Set to 0 to disable logging. Requires restart to fully apply. (Default: \"InternetGamesServer_logs\")" },
138145
{ "numconnsip", "Limits the number of connections allowed from a given IP address. Maximum is 65535. 0 signifies no limit. NOTE: Make this 0 or higher than 1 to keep XP ad banner functionality! (Default: 0)" },
146+
{ "enablehttp", "Create an HTTP server on startup (port 80). Only serves a root HTML page, which contains a table with the amount of waiting lobbies. Requires restart to apply. (Default: 0)" },
139147
{ "skiplevel", "Do not match players in matches based on skill level. Value can only be 0 or 1. (Default: 0)" },
140148
{ "singleplayer", "Allow matches, which support computer players, to exist with only one real player. (Default: 1)" },
141149
{ "disablead", "Prevent the server from responding to ad banner requests from Windows XP games with a custom \"Powered by ZoneInternetGamesServer\" banner. Value can only be 0 or 1. (Default: 0)" }
@@ -150,6 +158,8 @@ Config::GetValue(const std::string& key) const
150158
return logsDirectory;
151159
if (key == "numconnsip")
152160
return std::to_string(numConnectionsPerIP);
161+
if (key == "enablehttp")
162+
return enableHTTP ? "1" : "0";
153163
if (key == "skiplevel")
154164
return skipLevelMatching ? "1" : "0";
155165
if (key == "singleplayer")
@@ -196,6 +206,8 @@ Config::SetValue(const std::string& key, const std::string& value)
196206
throw std::runtime_error("Invalid \"numconnsip\" number: " + std::string(err.what()));
197207
}
198208
}
209+
else if (key == "enablehttp")
210+
CONFIG_SET_BOOL_VALUE(enableHTTP);
199211
else if (key == "skiplevel")
200212
CONFIG_SET_BOOL_VALUE(skipLevelMatching);
201213
else if (key == "singleplayer")

InternetGamesServer/Config.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class Config final
2727
std::string logsDirectory;
2828

2929
USHORT numConnectionsPerIP;
30+
bool enableHTTP;
3031

3132
bool skipLevelMatching; // When searching for a lobby, don't take the match level into account.
3233
bool allowSinglePlayer; // Allow matches, which support computer players, to exist with only one real player.

InternetGamesServer/InternetGamesServer.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@
153153
<ItemGroup>
154154
<ClCompile Include="Command.cpp" />
155155
<ClCompile Include="Config.cpp" />
156+
<ClCompile Include="SocketHttp.cpp" />
156157
<ClCompile Include="Win7\BackgammonMatch.cpp" />
157158
<ClCompile Include="Win7\CheckersMatch.cpp" />
158159
<ClCompile Include="external\tinyxml2\tinyxml2.cpp" />
@@ -179,6 +180,7 @@
179180
<ClInclude Include="Command.hpp" />
180181
<ClInclude Include="Config.hpp" />
181182
<ClInclude Include="Match.hpp" />
183+
<ClInclude Include="SocketHttp.hpp" />
182184
<ClInclude Include="Win7\BackgammonMatch.hpp" />
183185
<ClInclude Include="Win7\CheckersMatch.hpp" />
184186
<ClInclude Include="Win7\Match.hpp" />

InternetGamesServer/InternetGamesServer.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@
8484
<ClCompile Include="Config.cpp">
8585
<Filter>Source Files</Filter>
8686
</ClCompile>
87+
<ClCompile Include="SocketHttp.cpp">
88+
<Filter>Source Files</Filter>
89+
</ClCompile>
8790
</ItemGroup>
8891
<ItemGroup>
8992
<ClInclude Include="Util.hpp">
@@ -179,6 +182,9 @@
179182
<ClInclude Include="Config.hpp">
180183
<Filter>Header Files</Filter>
181184
</ClInclude>
185+
<ClInclude Include="SocketHttp.hpp">
186+
<Filter>Header Files</Filter>
187+
</ClInclude>
182188
</ItemGroup>
183189
<ItemGroup>
184190
<ClInclude Include="MatchManager.hpp">

InternetGamesServer/Main.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "Config.hpp"
1313
#include "MatchManager.hpp"
1414
#include "Socket.hpp"
15+
#include "SocketHttp.hpp"
1516
#include "Util.hpp"
1617

1718
#define DEFAULT_CONFIG_FILE "InternetGamesServer.config"
@@ -112,8 +113,11 @@ int main(int argc, char* argv[])
112113
return 1;
113114
}
114115

115-
struct addrinfo* result = NULL, * ptr = NULL, hints;
116+
// If enabled, set up a simple HTTP server on port 80
117+
if (g_config.enableHTTP)
118+
SetUpSocketHTTP();
116119

120+
struct addrinfo* result = NULL, * ptr = NULL, hints;
117121
ZeroMemory(&hints, sizeof(hints));
118122
hints.ai_family = AF_INET;
119123
hints.ai_socktype = SOCK_STREAM;

InternetGamesServer/Socket.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ Socket::SocketHandler(void* socket_)
111111
throw std::runtime_error("Invalid WinXP initial message!");
112112
}
113113
}
114-
else if (!strncmp("GET /windows/ad.asp", receivedBuf, strlen("GET /windows/ad.asp"))) // WINXP: Banner ad request
114+
else if (!strncmp("GET /windows/ad.asp HTTP/1.", receivedBuf, strlen("GET /windows/ad.asp"))) // WINXP: Banner ad request
115115
{
116116
socket.m_type = WINXP_BANNER_AD_REQUEST;
117117

@@ -122,16 +122,16 @@ Socket::SocketHandler(void* socket_)
122122
// The banner.png image will be returned by this server later. Look for it on the same host using '/', so that browsers can display it too (useful for testing).
123123
// We link to the GitHub repository on the Wayback Machine, as it can be somewhat loaded in IE6 via HTTP (ads strictly open with IE).
124124
const std::string adHtml = R"(
125-
<HTML>
126-
<HEAD></HEAD>
127-
<BODY MARGINWIDTH="0" MARGINHEIGHT="0" TOPMARGIN="0" LEFTMARGIN="0" BGCOLOR="#FFFFFF">
128-
<A HREF="http://web.archive.org/web/2/https://github.com/provigz/ZoneInternetGamesServer" TARGET="_new">
129-
<IMG SRC="/banner.png" ALT="Powered by ZoneInternetGamesServer" BORDER=0 WIDTH=380 HEIGHT=200>
130-
</A>
131-
<ZONEAD></ZONEAD>
132-
</BODY>
133-
</HTML>
134-
)";
125+
<HTML>
126+
<HEAD></HEAD>
127+
<BODY MARGINWIDTH="0" MARGINHEIGHT="0" TOPMARGIN="0" LEFTMARGIN="0" BGCOLOR="#FFFFFF">
128+
<A HREF="http://web.archive.org/web/2/https://github.com/provigz/ZoneInternetGamesServer" TARGET="_new">
129+
<IMG SRC="/banner.png" ALT="Powered by ZoneInternetGamesServer" BORDER=0 WIDTH=380 HEIGHT=200>
130+
</A>
131+
<ZONEAD></ZONEAD>
132+
</BODY>
133+
</HTML>
134+
)";
135135
const std::string adHttpHeader =
136136
"HTTP/1.1 200 OK\r\n"
137137
"Content-Type: text/html; charset=UTF-8\r\n"
@@ -143,7 +143,7 @@ Socket::SocketHandler(void* socket_)
143143

144144
throw DisconnectSocket("Banner ad sent over.");
145145
}
146-
else if (!strncmp("GET /banner.png", receivedBuf, strlen("GET /banner.png"))) // WINXP: Banner ad image request
146+
else if (!strncmp("GET /banner.png HTTP/1.", receivedBuf, strlen("GET /banner.png"))) // WINXP: Banner ad image request
147147
{
148148
socket.m_type = WINXP_BANNER_AD_IMAGE_REQUEST;
149149

0 commit comments

Comments
 (0)