summaryrefslogtreecommitdiff
path: root/src/network/network_admin.cpp
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2010-10-17 17:31:03 +0000
committerrubidium <rubidium@openttd.org>2010-10-17 17:31:03 +0000
commit33ed4ddbfbdcd269c7234ea6093acc21e7a63e7c (patch)
tree528f610d0ebafba248bd2c9ebf962990afa30676 /src/network/network_admin.cpp
parent12a7e2fde0b53f8d3042f3ee248522e921b80d72 (diff)
downloadopenttd-33ed4ddbfbdcd269c7234ea6093acc21e7a63e7c.tar.xz
(svn r20963) -Add: stubs for a remote administration connection
Diffstat (limited to 'src/network/network_admin.cpp')
-rw-r--r--src/network/network_admin.cpp202
1 files changed, 202 insertions, 0 deletions
diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp
new file mode 100644
index 000000000..90da9ac6a
--- /dev/null
+++ b/src/network/network_admin.cpp
@@ -0,0 +1,202 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD 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.
+ * OpenTTD 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 for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file network_admin.cpp Server part of the admin network protocol. */
+
+#ifdef ENABLE_NETWORK
+
+#include "../stdafx.h"
+#include "../debug.h"
+#include "../strings_func.h"
+#include "../date_func.h"
+#include "network_admin.h"
+#include "network.h"
+#include "network_base.h"
+#include "../company_base.h"
+#include "../console_func.h"
+#include "../core/pool_func.hpp"
+#include "../map_func.h"
+#include "../rev.h"
+
+#include "table/strings.h"
+
+/* This file handles all the admin network commands. */
+
+/** The amount of admins connected. */
+byte _network_admins_connected = 0;
+
+NetworkAdminSocketPool _networkadminsocket_pool("NetworkAdminSocket");
+INSTANTIATE_POOL_METHODS(NetworkAdminSocket)
+
+/**
+ * Create a new socket for the server side of the admin network.
+ * @param s The socket to connect with.
+ */
+ServerNetworkAdminSocketHandler::ServerNetworkAdminSocketHandler(SOCKET s) : NetworkAdminSocketHandler(s)
+{
+ _network_admins_connected++;
+ this->status = ADMIN_STATUS_INACTIVE;
+}
+
+/**
+ * Clear everything related to this admin.
+ */
+ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler()
+{
+ _network_admins_connected--;
+ DEBUG(net, 1, "[admin] '%s' (%s) has disconnected", this->admin_name, this->admin_version);
+}
+
+/**
+ * Whether a connection is allowed or not at this moment.
+ * @return Whether the connection is allowed.
+ */
+/* static */ bool ServerNetworkAdminSocketHandler::AllowConnection()
+{
+ return !StrEmpty(_settings_client.network.admin_password) && _network_admins_connected < MAX_ADMINS;
+}
+
+/** Send the packets for the server sockets. */
+/* static */ void ServerNetworkAdminSocketHandler::Send()
+{
+ ServerNetworkAdminSocketHandler *as;
+ FOR_ALL_ADMIN_SOCKETS(as) {
+ if (as->writable) {
+ as->Send_Packets();
+ }
+ }
+}
+
+/* static */ void ServerNetworkAdminSocketHandler::AcceptConnection(SOCKET s, const NetworkAddress &address)
+{
+ ServerNetworkAdminSocketHandler *as = new ServerNetworkAdminSocketHandler(s);
+ as->address = address; // Save the IP of the client
+}
+
+/***********
+ * Sending functions for admin network
+ ************/
+
+NetworkRecvStatus ServerNetworkAdminSocketHandler::SendError(NetworkErrorCode error)
+{
+ Packet *p = new Packet(ADMIN_PACKET_SERVER_ERROR);
+
+ p->Send_uint8(error);
+ this->Send_Packet(p);
+
+ char str[100];
+ StringID strid = GetNetworkErrorMsg(error);
+ GetString(str, strid, lastof(str));
+
+ DEBUG(net, 1, "[admin] the admin '%s' (%s) made an error and has been disconnected. Reason: '%s'", this->admin_name, this->admin_version, str);
+
+ return this->CloseConnection(true);
+}
+
+NetworkRecvStatus ServerNetworkAdminSocketHandler::SendProtocol()
+{
+ Packet *p = new Packet(ADMIN_PACKET_SERVER_PROTOCOL);
+
+ /* announce the protocol version */
+ p->Send_uint8(NETWORK_GAME_ADMIN_VERSION);
+
+ p->Send_bool(false);
+ this->Send_Packet(p);
+
+ return this->SendWelcome();
+}
+
+NetworkRecvStatus ServerNetworkAdminSocketHandler::SendWelcome()
+{
+ this->status = ADMIN_STATUS_ACTIVE;
+
+ Packet *p = new Packet(ADMIN_PACKET_SERVER_WELCOME);
+
+ p->Send_string(_settings_client.network.server_name);
+ p->Send_string(_openttd_revision);
+ p->Send_bool (_network_dedicated);
+
+ p->Send_string(_network_game_info.map_name);
+ p->Send_uint32(_settings_game.game_creation.generation_seed);
+ p->Send_uint8 (_settings_game.game_creation.landscape);
+ p->Send_uint32(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
+ p->Send_uint16(MapSizeX());
+ p->Send_uint16(MapSizeY());
+
+ this->Send_Packet(p);
+
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+NetworkRecvStatus ServerNetworkAdminSocketHandler::SendNewGame()
+{
+ Packet *p = new Packet(ADMIN_PACKET_SERVER_NEWGAME);
+ this->Send_Packet(p);
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+NetworkRecvStatus ServerNetworkAdminSocketHandler::SendShutdown()
+{
+ Packet *p = new Packet(ADMIN_PACKET_SERVER_SHUTDOWN);
+ this->Send_Packet(p);
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+/***********
+ * Receiving functions
+ ************/
+
+DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_JOIN)
+{
+ if (this->status != ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
+
+ char password[NETWORK_PASSWORD_LENGTH];
+ p->Recv_string(password, sizeof(password));
+
+ if (StrEmpty(_settings_client.network.admin_password) ||
+ strcmp(password, _settings_client.network.admin_password) != 0) {
+ /* Password is invalid */
+ return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
+ }
+
+ p->Recv_string(this->admin_name, sizeof(this->admin_name));
+ p->Recv_string(this->admin_version, sizeof(this->admin_version));
+
+ if (StrEmpty(this->admin_name) || StrEmpty(this->admin_version)) {
+ /* no name or version supplied */
+ return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
+ }
+
+ DEBUG(net, 1, "[admin] '%s' (%s) has connected", this->admin_name, this->admin_version);
+
+ return this->SendProtocol();
+}
+
+DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_QUIT)
+{
+ /* The admin is leaving nothing else to do */
+ return this->CloseConnection();
+}
+
+/*
+ * Useful wrapper functions
+ */
+
+/**
+ * Send a Welcome packet to all connected admins
+ */
+void ServerNetworkAdminSocketHandler::WelcomeAll()
+{
+ ServerNetworkAdminSocketHandler *as;
+ FOR_ALL_ADMIN_SOCKETS(as) {
+ as->SendWelcome();
+ }
+}
+
+#endif /* ENABLE_NETWORK */