summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/network/network.cpp68
-rw-r--r--src/network/network_client.h2
-rw-r--r--src/network/network_func.h2
-rw-r--r--src/settings_type.h1
-rw-r--r--src/table/settings.h1
5 files changed, 59 insertions, 15 deletions
diff --git a/src/network/network.cpp b/src/network/network.cpp
index 309a9f025..b18c2732f 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -16,6 +16,7 @@
#include "../strings_func.h"
#include "../command_func.h"
#include "../date_func.h"
+#include "network_admin.h"
#include "network_client.h"
#include "network_server.h"
#include "network_content.h"
@@ -429,22 +430,37 @@ void ParseConnectionString(const char **company, const char **port, char *connec
cs->GetInfo()->client_address = address; // Save the IP of the client
}
-/** Resets both pools used for network clients */
-static void InitializeNetworkPools()
+/**
+ * Resets the pools used for network clients, and the admin pool if needed.
+ * @param close_admins Whether the admin pool has to be cleared as well.
+ */
+static void InitializeNetworkPools(bool close_admins = true)
{
_networkclientsocket_pool.CleanPool();
_networkclientinfo_pool.CleanPool();
+ if (close_admins) _networkadminsocket_pool.CleanPool();
}
-/* Close all current connections */
-void NetworkClose()
+/**
+ * Close current connections.
+ * @param close_admins Whether the admin connections have to be closed as well.
+ */
+void NetworkClose(bool close_admins)
{
if (_network_server) {
+ if (close_admins) {
+ ServerNetworkAdminSocketHandler *as;
+ FOR_ALL_ADMIN_SOCKETS(as) {
+ as->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
+ }
+ }
+
NetworkClientSocket *cs;
FOR_ALL_CLIENT_SOCKETS(cs) {
cs->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
}
ServerNetworkGameSocketHandler::CloseListeners();
+ ServerNetworkAdminSocketHandler::CloseListeners();
} else if (MyClient::my_client != NULL) {
MyClient::SendQuit();
MyClient::my_client->Send_Packets();
@@ -461,13 +477,13 @@ void NetworkClose()
free(_network_company_states);
_network_company_states = NULL;
- InitializeNetworkPools();
+ InitializeNetworkPools(close_admins);
}
/* Inits the network (cleans sockets and stuff) */
-static void NetworkInitialize()
+static void NetworkInitialize(bool close_admins = true)
{
- InitializeNetworkPools();
+ InitializeNetworkPools(close_admins);
NetworkUDPInitialize();
_sync_frame = 0;
@@ -629,10 +645,13 @@ bool NetworkServerStart()
IConsoleCmdExec("exec scripts/pre_server.scr 0");
if (_network_dedicated) IConsoleCmdExec("exec scripts/pre_dedicated.scr 0");
- NetworkDisconnect();
- NetworkInitialize();
+ NetworkDisconnect(false, false);
+ NetworkInitialize(false);
if (!ServerNetworkGameSocketHandler::Listen(_settings_client.network.server_port)) return false;
+ /* Only listen for admins when the password isn't empty. */
+ if (!StrEmpty(_settings_client.network.admin_password) && !ServerNetworkAdminSocketHandler::Listen(_settings_client.network.server_admin_port)) return false;
+
/* Try to start UDP-server */
_network_udp_server = _udp_server_socket->Listen();
@@ -659,6 +678,10 @@ bool NetworkServerStart()
_network_last_advertise_frame = 0;
_network_need_advertise = true;
NetworkUDPAdvertise();
+
+ /* welcome possibly still connected admins - this can only happen on a dedicated server. */
+ if (_network_dedicated) ServerNetworkAdminSocketHandler::WelcomeAll();
+
return true;
}
@@ -672,16 +695,25 @@ void NetworkReboot()
cs->SendNewGame();
cs->Send_Packets();
}
+
+ ServerNetworkAdminSocketHandler *as;
+ FOR_ALL_ADMIN_SOCKETS(as) {
+ as->SendNewGame();
+ as->Send_Packets();
+ }
}
- NetworkClose();
+ /* For non-dedicated servers we have to kick the admins as we are not
+ * certain that we will end up in a new network game. */
+ NetworkClose(!_network_dedicated);
}
/**
* We want to disconnect from the host/clients.
- * @param blocking whether to wait till everything has been closed
+ * @param blocking whether to wait till everything has been closed.
+ * @param close_admins Whether the admin sockets need to be closed as well.
*/
-void NetworkDisconnect(bool blocking)
+void NetworkDisconnect(bool blocking, bool close_admins)
{
if (_network_server) {
NetworkClientSocket *cs;
@@ -689,13 +721,21 @@ void NetworkDisconnect(bool blocking)
cs->SendShutdown();
cs->Send_Packets();
}
+
+ if (close_admins) {
+ ServerNetworkAdminSocketHandler *as;
+ FOR_ALL_ADMIN_SOCKETS(as) {
+ as->SendShutdown();
+ as->Send_Packets();
+ }
+ }
}
if (_settings_client.network.server_advertise) NetworkUDPRemoveAdvertise(blocking);
DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
- NetworkClose();
+ NetworkClose(close_admins);
/* Reinitialize the UDP stack, i.e. close all existing connections. */
NetworkUDPInitialize();
@@ -708,6 +748,7 @@ void NetworkDisconnect(bool blocking)
static bool NetworkReceive()
{
if (_network_server) {
+ ServerNetworkAdminSocketHandler::Receive();
return ServerNetworkGameSocketHandler::Receive();
} else {
return ClientNetworkGameSocketHandler::Receive();
@@ -718,6 +759,7 @@ static bool NetworkReceive()
static void NetworkSend()
{
if (_network_server) {
+ ServerNetworkAdminSocketHandler::Send();
ServerNetworkGameSocketHandler::Send();
} else {
ClientNetworkGameSocketHandler::Send();
diff --git a/src/network/network_client.h b/src/network/network_client.h
index b1edccae2..bdf8209a5 100644
--- a/src/network/network_client.h
+++ b/src/network/network_client.h
@@ -20,7 +20,7 @@
class ClientNetworkGameSocketHandler : public ZeroedMemoryAllocator, public NetworkGameSocketHandler {
protected:
friend void NetworkExecuteLocalCommandQueue();
- friend void NetworkClose();
+ friend void NetworkClose(bool close_admins);
static ClientNetworkGameSocketHandler *my_client;
DECLARE_GAME_RECEIVE_COMMAND(PACKET_SERVER_FULL);
diff --git a/src/network/network_func.h b/src/network/network_func.h
index 02ee1a327..da9499e81 100644
--- a/src/network/network_func.h
+++ b/src/network/network_func.h
@@ -38,7 +38,7 @@ void NetworkUpdateClientName();
bool NetworkCompanyHasClients(CompanyID company);
const char *NetworkChangeCompanyPassword(const char *);
void NetworkReboot();
-void NetworkDisconnect(bool blocking = false);
+void NetworkDisconnect(bool blocking = false, bool close_admins = true);
void NetworkGameLoop();
void NetworkUDPGameLoop();
void ParseConnectionString(const char **company, const char **port, char *connection_string);
diff --git a/src/settings_type.h b/src/settings_type.h
index 1dd662455..c6544043d 100644
--- a/src/settings_type.h
+++ b/src/settings_type.h
@@ -133,6 +133,7 @@ struct NetworkSettings {
uint16 max_join_time; ///< maximum amount of time, in game ticks, a client may take to join
bool pause_on_join; ///< pause the game when people join
uint16 server_port; ///< port the server listens on
+ uint16 server_admin_port; ///< port the server listens on for the admin network
char server_name[NETWORK_NAME_LENGTH]; ///< name of the server
char server_password[NETWORK_PASSWORD_LENGTH]; ///< password for joining this server
char rcon_password[NETWORK_PASSWORD_LENGTH]; ///< password for rconsole (server side)
diff --git a/src/table/settings.h b/src/table/settings.h
index d2416ad2f..0d263a85e 100644
--- a/src/table/settings.h
+++ b/src/table/settings.h
@@ -631,6 +631,7 @@ const SettingDesc _settings[] = {
SDTC_VAR(network.max_join_time, SLE_UINT16, S, NO, 500, 0, 32000, 0, STR_NULL, NULL),
SDTC_BOOL(network.pause_on_join, S, NO, true, STR_NULL, NULL),
SDTC_VAR(network.server_port, SLE_UINT16, S, NO,NETWORK_DEFAULT_PORT,0,65535,0,STR_NULL, NULL),
+ SDTC_VAR(network.server_admin_port, SLE_UINT16, S, NO, NETWORK_ADMIN_PORT,0,65535,0,STR_NULL, NULL),
SDTC_BOOL(network.server_advertise, S, NO, false, STR_NULL, NULL),
SDTC_VAR(network.lan_internet, SLE_UINT8, S, NO, 0, 0, 1, 0, STR_NULL, NULL),
SDTC_STR(network.client_name, SLE_STRB, S, 0, NULL, STR_NULL, UpdateClientName),