diff options
author | rubidium <rubidium@openttd.org> | 2010-10-17 17:31:03 +0000 |
---|---|---|
committer | rubidium <rubidium@openttd.org> | 2010-10-17 17:31:03 +0000 |
commit | 33ed4ddbfbdcd269c7234ea6093acc21e7a63e7c (patch) | |
tree | 528f610d0ebafba248bd2c9ebf962990afa30676 /src/network/network_admin.cpp | |
parent | 12a7e2fde0b53f8d3042f3ee248522e921b80d72 (diff) | |
download | openttd-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.cpp | 202 |
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 */ |