# network_admin.cpp

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * 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.
    00006  * 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.
    00007  * 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/>.
    00008  */
    00009
    00012 #ifdef ENABLE_NETWORK
    00013
    00014 #include "../stdafx.h"
    00015 #include "../strings_func.h"
    00016 #include "../date_func.h"
    00017 #include "network_admin.h"
    00018 #include "network_base.h"
    00019 #include "network_server.h"
    00020 #include "../command_func.h"
    00021 #include "../company_base.h"
    00022 #include "../console_func.h"
    00023 #include "../core/pool_func.hpp"
    00024 #include "../map_func.h"
    00025 #include "../rev.h"
    00026
    00027
    00028 /* This file handles all the admin network commands. */
    00029
    00031 AdminIndex _redirect_console_to_admin = INVALID_ADMIN_ID;
    00032
    00034 byte _network_admins_connected = 0;
    00035
    00037 NetworkAdminSocketPool _networkadminsocket_pool("NetworkAdminSocket");
    00038 INSTANTIATE_POOL_METHODS(NetworkAdminSocket)
    00039
    00040
    00041 static const int ADMIN_AUTHORISATION_TIMEOUT = 10000;
    00042
    00043
    00045 static const AdminUpdateFrequency _admin_update_type_frequencies[] = {
    00046   ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_DAILY | ADMIN_FREQUENCY_WEEKLY | ADMIN_FREQUENCY_MONTHLY | ADMIN_FREQUENCY_QUARTERLY | ADMIN_FREQUENCY_ANUALLY,
    00047   ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_AUTOMATIC,
    00048   ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_AUTOMATIC,
    00049   ADMIN_FREQUENCY_POLL |                         ADMIN_FREQUENCY_WEEKLY | ADMIN_FREQUENCY_MONTHLY | ADMIN_FREQUENCY_QUARTERLY | ADMIN_FREQUENCY_ANUALLY,
    00050   ADMIN_FREQUENCY_POLL |                         ADMIN_FREQUENCY_WEEKLY | ADMIN_FREQUENCY_MONTHLY | ADMIN_FREQUENCY_QUARTERLY | ADMIN_FREQUENCY_ANUALLY,
    00051                          ADMIN_FREQUENCY_AUTOMATIC,
    00052                          ADMIN_FREQUENCY_AUTOMATIC,
    00053   ADMIN_FREQUENCY_POLL,
    00054                          ADMIN_FREQUENCY_AUTOMATIC,
    00055 };
    00057 assert_compile(lengthof(_admin_update_type_frequencies) == ADMIN_UPDATE_END);
    00058
    00063 ServerNetworkAdminSocketHandler::ServerNetworkAdminSocketHandler(SOCKET s) : NetworkAdminSocketHandler(s)
    00064 {
    00065   _network_admins_connected++;
    00066   this->status = ADMIN_STATUS_INACTIVE;
    00067   this->realtime_connect = _realtime_tick;
    00068 }
    00069
    00073 ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler()
    00074 {
    00075   _network_admins_connected--;
    00076   DEBUG(net, 1, "[admin] '%s' (%s) has disconnected", this->admin_name, this->admin_version);
    00077   if (_redirect_console_to_admin == this->index) _redirect_console_to_admin = INVALID_ADMIN_ID;
    00078 }
    00079
    00084 /* static */ bool ServerNetworkAdminSocketHandler::AllowConnection()
    00085 {
    00086   bool accept = !StrEmpty(_settings_client.network.admin_password) && _network_admins_connected < MAX_ADMINS;
    00087   /* We can't go over the MAX_ADMINS limit here. However, if we accept
    00088    * the connection, there has to be space in the pool. */
    00089   assert_compile(NetworkAdminSocketPool::MAX_SIZE == MAX_ADMINS);
    00090   assert(!accept || ServerNetworkAdminSocketHandler::CanAllocateItem());
    00091   return accept;
    00092 }
    00093
    00095 /* static */ void ServerNetworkAdminSocketHandler::Send()
    00096 {
    00097   ServerNetworkAdminSocketHandler *as;
    00098   FOR_ALL_ADMIN_SOCKETS(as) {
    00099     if (as->status == ADMIN_STATUS_INACTIVE && as->realtime_connect + ADMIN_AUTHORISATION_TIMEOUT < _realtime_tick) {
    00100       DEBUG(net, 1, "[admin] Admin did not send its authorisation within %d seconds", ADMIN_AUTHORISATION_TIMEOUT / 1000);
    00101       as->CloseConnection(true);
    00102       continue;
    00103     }
    00104     if (as->writable) {
    00105       as->SendPackets();
    00106     }
    00107   }
    00108 }
    00109
    00115 /* static */ void ServerNetworkAdminSocketHandler::AcceptConnection(SOCKET s, const NetworkAddress &address)
    00116 {
    00117   ServerNetworkAdminSocketHandler *as = new ServerNetworkAdminSocketHandler(s);
    00118   as->address = address; // Save the IP of the client
    00119 }
    00120
    00121 /***********
    00122  * Sending functions for admin network
    00123  ************/
    00124
    00129 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendError(NetworkErrorCode error)
    00130 {
    00131   Packet *p = new Packet(ADMIN_PACKET_SERVER_ERROR);
    00132
    00133   p->Send_uint8(error);
    00134   this->SendPacket(p);
    00135
    00136   char str[100];
    00137   StringID strid = GetNetworkErrorMsg(error);
    00138   GetString(str, strid, lastof(str));
    00139
    00140   DEBUG(net, 1, "[admin] the admin '%s' (%s) made an error and has been disconnected. Reason: '%s'", this->admin_name, this->admin_version, str);
    00141
    00142   return this->CloseConnection(true);
    00143 }
    00144
    00146 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendProtocol()
    00147 {
    00148   Packet *p = new Packet(ADMIN_PACKET_SERVER_PROTOCOL);
    00149
    00150   /* announce the protocol version */
    00151   p->Send_uint8(NETWORK_GAME_ADMIN_VERSION);
    00152
    00153   for (int i = 0; i < ADMIN_UPDATE_END; i++) {
    00154     p->Send_bool  (true);
    00155     p->Send_uint16(i);
    00156     p->Send_uint16(_admin_update_type_frequencies[i]);
    00157   }
    00158
    00159   p->Send_bool(false);
    00160   this->SendPacket(p);
    00161
    00162   return this->SendWelcome();
    00163 }
    00164
    00166 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendWelcome()
    00167 {
    00168   this->status = ADMIN_STATUS_ACTIVE;
    00169
    00170   Packet *p = new Packet(ADMIN_PACKET_SERVER_WELCOME);
    00171
    00172   p->Send_string(_settings_client.network.server_name);
    00173   p->Send_string(_openttd_revision);
    00174   p->Send_bool  (_network_dedicated);
    00175
    00176   p->Send_string(_network_game_info.map_name);
    00177   p->Send_uint32(_settings_game.game_creation.generation_seed);
    00178   p->Send_uint8 (_settings_game.game_creation.landscape);
    00179   p->Send_uint32(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
    00180   p->Send_uint16(MapSizeX());
    00181   p->Send_uint16(MapSizeY());
    00182
    00183   this->SendPacket(p);
    00184
    00185   return NETWORK_RECV_STATUS_OKAY;
    00186 }
    00187
    00189 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendNewGame()
    00190 {
    00191   Packet *p = new Packet(ADMIN_PACKET_SERVER_NEWGAME);
    00192   this->SendPacket(p);
    00193   return NETWORK_RECV_STATUS_OKAY;
    00194 }
    00195
    00197 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendShutdown()
    00198 {
    00199   Packet *p = new Packet(ADMIN_PACKET_SERVER_SHUTDOWN);
    00200   this->SendPacket(p);
    00201   return NETWORK_RECV_STATUS_OKAY;
    00202 }
    00203
    00205 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendDate()
    00206 {
    00207   Packet *p = new Packet(ADMIN_PACKET_SERVER_DATE);
    00208
    00209   p->Send_uint32(_date);
    00210   this->SendPacket(p);
    00211
    00212   return NETWORK_RECV_STATUS_OKAY;
    00213 }
    00214
    00219 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientJoin(ClientID client_id)
    00220 {
    00221   Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_JOIN);
    00222
    00223   p->Send_uint32(client_id);
    00224   this->SendPacket(p);
    00225
    00226   return NETWORK_RECV_STATUS_OKAY;
    00227 }
    00228
    00233 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientInfo(const NetworkClientSocket *cs)
    00234 {
    00235   /* Only send data when we're a proper client, not just someone trying to query the server. */
    00236   const NetworkClientInfo *ci = cs->GetInfo();
    00237   if (ci == NULL) return NETWORK_RECV_STATUS_OKAY;
    00238
    00239   Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_INFO);
    00240
    00241   p->Send_uint32(ci->client_id);
    00242   p->Send_string(const_cast<NetworkAddress &>(cs->client_address).GetHostname());
    00243   p->Send_string(ci->client_name);
    00244   p->Send_uint8 (ci->client_lang);
    00245   p->Send_uint32(ci->join_date);
    00246   p->Send_uint8 (ci->client_playas);
    00247
    00248   this->SendPacket(p);
    00249
    00250   return NETWORK_RECV_STATUS_OKAY;
    00251 }
    00252
    00253
    00258 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientUpdate(const NetworkClientInfo *ci)
    00259 {
    00260   Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_UPDATE);
    00261
    00262   p->Send_uint32(ci->client_id);
    00263   p->Send_string(ci->client_name);
    00264   p->Send_uint8 (ci->client_playas);
    00265
    00266   this->SendPacket(p);
    00267
    00268   return NETWORK_RECV_STATUS_OKAY;
    00269 }
    00270
    00275 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientQuit(ClientID client_id)
    00276 {
    00277   Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_QUIT);
    00278
    00279   p->Send_uint32(client_id);
    00280   this->SendPacket(p);
    00281
    00282   return NETWORK_RECV_STATUS_OKAY;
    00283 }
    00284
    00290 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientError(ClientID client_id, NetworkErrorCode error)
    00291 {
    00292   Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_ERROR);
    00293
    00294   p->Send_uint32(client_id);
    00295   p->Send_uint8 (error);
    00296   this->SendPacket(p);
    00297
    00298   return NETWORK_RECV_STATUS_OKAY;
    00299 }
    00300
    00305 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyNew(CompanyID company_id)
    00306 {
    00307   Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_NEW);
    00308   p->Send_uint8(company_id);
    00309
    00310   this->SendPacket(p);
    00311
    00312   return NETWORK_RECV_STATUS_OKAY;
    00313 }
    00314
    00319 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyInfo(const Company *c)
    00320 {
    00321   char company_name[NETWORK_COMPANY_NAME_LENGTH];
    00322   char manager_name[NETWORK_COMPANY_NAME_LENGTH];
    00323
    00324   SetDParam(0, c->index);
    00325   GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
    00326
    00327   SetDParam(0, c->index);
    00328   GetString(manager_name, STR_PRESIDENT_NAME, lastof(manager_name));
    00329
    00330   Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_INFO);
    00331
    00332   p->Send_uint8 (c->index);
    00333   p->Send_string(company_name);
    00334   p->Send_string(manager_name);
    00335   p->Send_uint8 (c->colour);
    00336   p->Send_bool  (NetworkCompanyIsPassworded(c->index));
    00337   p->Send_uint32(c->inaugurated_year);
    00338   p->Send_bool  (c->is_ai);
    00339
    00340   this->SendPacket(p);
    00341
    00342   return NETWORK_RECV_STATUS_OKAY;
    00343 }
    00344
    00345
    00350 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyUpdate(const Company *c)
    00351 {
    00352   char company_name[NETWORK_COMPANY_NAME_LENGTH];
    00353   char manager_name[NETWORK_COMPANY_NAME_LENGTH];
    00354
    00355   SetDParam(0, c->index);
    00356   GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
    00357
    00358   SetDParam(0, c->index);
    00359   GetString(manager_name, STR_PRESIDENT_NAME, lastof(manager_name));
    00360
    00361   Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_UPDATE);
    00362
    00363   p->Send_uint8 (c->index);
    00364   p->Send_string(company_name);
    00365   p->Send_string(manager_name);
    00366   p->Send_uint8 (c->colour);
    00367   p->Send_bool  (NetworkCompanyIsPassworded(c->index));
    00368   p->Send_uint8 (c->quarters_of_bankruptcy);
    00369
    00370   for (size_t i = 0; i < lengthof(c->share_owners); i++) {
    00371     p->Send_uint8(c->share_owners[i]);
    00372   }
    00373
    00374   this->SendPacket(p);
    00375
    00376   return NETWORK_RECV_STATUS_OKAY;
    00377 }
    00378
    00384 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason acrr)
    00385 {
    00386   Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_REMOVE);
    00387
    00388   p->Send_uint8(company_id);
    00389   p->Send_uint8(acrr);
    00390
    00391   this->SendPacket(p);
    00392
    00393   return NETWORK_RECV_STATUS_OKAY;
    00394 }
    00395
    00397 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyEconomy()
    00398 {
    00399   const Company *company;
    00400   FOR_ALL_COMPANIES(company) {
    00401     /* Get the income. */
    00402     Money income = 0;
    00403     for (uint i = 0; i < lengthof(company->yearly_expenses[0]); i++) {
    00404       income -= company->yearly_expenses[0][i];
    00405     }
    00406
    00407     Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_ECONOMY);
    00408
    00409     p->Send_uint8(company->index);
    00410
    00411     /* Current information. */
    00412     p->Send_uint64(company->money);
    00413     p->Send_uint64(company->current_loan);
    00414     p->Send_uint64(income);
    00415     p->Send_uint16(company->cur_economy.delivered_cargo);
    00416
    00417     /* Send stats for the last 2 quarters. */
    00418     for (uint i = 0; i < 2; i++) {
    00419       p->Send_uint64(company->old_economy[i].company_value);
    00420       p->Send_uint16(company->old_economy[i].performance_history);
    00421       p->Send_uint16(company->old_economy[i].delivered_cargo);
    00422     }
    00423
    00424     this->SendPacket(p);
    00425   }
    00426
    00427
    00428   return NETWORK_RECV_STATUS_OKAY;
    00429 }
    00430
    00432 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyStats()
    00433 {
    00434   /* Fetch the latest version of the stats. */
    00435   NetworkCompanyStats company_stats[MAX_COMPANIES];
    00436   NetworkPopulateCompanyStats(company_stats);
    00437
    00438   const Company *company;
    00439
    00440   /* Go through all the companies. */
    00441   FOR_ALL_COMPANIES(company) {
    00442     Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_STATS);
    00443
    00444     /* Send the information. */
    00445     p->Send_uint8(company->index);
    00446
    00447     for (uint i = 0; i < NETWORK_VEH_END; i++) {
    00448       p->Send_uint16(company_stats[company->index].num_vehicle[i]);
    00449     }
    00450
    00451     for (uint i = 0; i < NETWORK_VEH_END; i++) {
    00452       p->Send_uint16(company_stats[company->index].num_station[i]);
    00453     }
    00454
    00455     this->SendPacket(p);
    00456   }
    00457
    00458   return NETWORK_RECV_STATUS_OKAY;
    00459 }
    00460
    00469 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, int64 data)
    00470 {
    00471   Packet *p = new Packet(ADMIN_PACKET_SERVER_CHAT);
    00472
    00473   p->Send_uint8 (action);
    00474   p->Send_uint8 (desttype);
    00475   p->Send_uint32(client_id);
    00476   p->Send_string(msg);
    00477   p->Send_uint64(data);
    00478
    00479   this->SendPacket(p);
    00480   return NETWORK_RECV_STATUS_OKAY;
    00481 }
    00482
    00488 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRcon(uint16 colour, const char *result)
    00489 {
    00490   Packet *p = new Packet(ADMIN_PACKET_SERVER_RCON);
    00491
    00492   p->Send_uint16(colour);
    00493   p->Send_string(result);
    00494   this->SendPacket(p);
    00495
    00496   return NETWORK_RECV_STATUS_OKAY;
    00497 }
    00498
    00499 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_RCON(Packet *p)
    00500 {
    00501   if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
    00502
    00503   char command[NETWORK_RCONCOMMAND_LENGTH];
    00504
    00505   p->Recv_string(command, sizeof(command));
    00506
    00507   DEBUG(net, 2, "[admin] Rcon command from '%s' (%s): '%s'", this->admin_name, this->admin_version, command);
    00508
    00509   _redirect_console_to_admin = this->index;
    00510   IConsoleCmdExec(command);
    00511   _redirect_console_to_admin = INVALID_ADMIN_ID;
    00512   return NETWORK_RECV_STATUS_OKAY;
    00513 }
    00514
    00520 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const char *origin, const char *string)
    00521 {
    00522   /* If the length of both strings, plus the 2 '\0' terminations and 3 bytes of the packet
    00523    * are bigger than the MTU, just ignore the message. Better safe than sorry. It should
    00524    * never occur though as the longest strings are chat messages, which are still 30%
    00525    * smaller than SEND_MTU. */
    00526   if (strlen(origin) + strlen(string) + 2 + 3 >= SEND_MTU) return NETWORK_RECV_STATUS_OKAY;
    00527
    00528   Packet *p = new Packet(ADMIN_PACKET_SERVER_CONSOLE);
    00529
    00530   p->Send_string(origin);
    00531   p->Send_string(string);
    00532   this->SendPacket(p);
    00533
    00534   return NETWORK_RECV_STATUS_OKAY;
    00535 }
    00536
    00538 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdNames()
    00539 {
    00540   Packet *p = new Packet(ADMIN_PACKET_SERVER_CMD_NAMES);
    00541
    00542   for (uint i = 0; i < CMD_END; i++) {
    00543     const char *cmdname = GetCommandName(i);
    00544
    00545     /* Should SEND_MTU be exceeded, start a new packet
    00546      * (magic 5: 1 bool "more data" and one uint16 "command id", one
    00547      * byte for string '\0' termination and 1 bool "no more data" */
    00548     if (p->size + strlen(cmdname) + 5 >= SEND_MTU) {
    00549       p->Send_bool(false);
    00550       this->SendPacket(p);
    00551
    00552       p = new Packet(ADMIN_PACKET_SERVER_CMD_NAMES);
    00553     }
    00554
    00555     p->Send_bool(true);
    00556     p->Send_uint16(i);
    00557     p->Send_string(cmdname);
    00558   }
    00559
    00560   /* Marker to notify the end of the packet has been reached. */
    00561   p->Send_bool(false);
    00562   this->SendPacket(p);
    00563
    00564   return NETWORK_RECV_STATUS_OKAY;
    00565 }
    00566
    00572 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdLogging(ClientID client_id, const CommandPacket *cp)
    00573 {
    00574   Packet *p = new Packet(ADMIN_PACKET_SERVER_CMD_LOGGING);
    00575
    00576   p->Send_uint32(client_id);
    00577   p->Send_uint8 (cp->company);
    00578   p->Send_uint16(cp->cmd & CMD_ID_MASK);
    00579   p->Send_uint32(cp->p1);
    00580   p->Send_uint32(cp->p2);
    00581   p->Send_uint32(cp->tile);
    00582   p->Send_string(cp->text);
    00583   p->Send_uint32(cp->frame);
    00584
    00585   this->SendPacket(p);
    00586
    00587   return NETWORK_RECV_STATUS_OKAY;
    00588 }
    00589
    00590 /***********
    00591  * Receiving functions
    00592  ************/
    00593
    00594 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_JOIN(Packet *p)
    00595 {
    00596   if (this->status != ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
    00597
    00598   char password[NETWORK_PASSWORD_LENGTH];
    00599   p->Recv_string(password, sizeof(password));
    00600
    00601   if (StrEmpty(_settings_client.network.admin_password) ||
    00602       strcmp(password, _settings_client.network.admin_password) != 0) {
    00603     /* Password is invalid */
    00604     return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
    00605   }
    00606
    00607   p->Recv_string(this->admin_name, sizeof(this->admin_name));
    00608   p->Recv_string(this->admin_version, sizeof(this->admin_version));
    00609
    00610   if (StrEmpty(this->admin_name) || StrEmpty(this->admin_version)) {
    00611     /* no name or version supplied */
    00612     return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
    00613   }
    00614
    00615   DEBUG(net, 1, "[admin] '%s' (%s) has connected", this->admin_name, this->admin_version);
    00616
    00617   return this->SendProtocol();
    00618 }
    00619
    00620 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_QUIT(Packet *p)
    00621 {
    00622   /* The admin is leaving nothing else to do */
    00623   return this->CloseConnection();
    00624 }
    00625
    00626 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_UPDATE_FREQUENCY(Packet *p)
    00627 {
    00628   if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
    00629
    00630   AdminUpdateType type = (AdminUpdateType)p->Recv_uint16();
    00631   AdminUpdateFrequency freq = (AdminUpdateFrequency)p->Recv_uint16();
    00632
    00633   if (type >= ADMIN_UPDATE_END || (_admin_update_type_frequencies[type] & freq) != freq) {
    00634     /* The server does not know of this UpdateType. */
    00635     DEBUG(net, 3, "[admin] Not supported update frequency %d (%d) from '%s' (%s).", type, freq, this->admin_name, this->admin_version);
    00636     return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
    00637   }
    00638
    00639   this->update_frequency[type] = freq;
    00640
    00641   return NETWORK_RECV_STATUS_OKAY;
    00642 }
    00643
    00644 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_POLL(Packet *p)
    00645 {
    00646   if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
    00647
    00648   AdminUpdateType type = (AdminUpdateType)p->Recv_uint8();
    00649   uint32 d1 = p->Recv_uint32();
    00650
    00651   switch (type) {
    00652     case ADMIN_UPDATE_DATE:
    00653       /* The admin is requesting the current date. */
    00654       this->SendDate();
    00655       break;
    00656
    00657     case ADMIN_UPDATE_CLIENT_INFO:
    00658       /* The admin is requesting client info. */
    00659       const NetworkClientSocket *cs;
    00660       if (d1 == UINT32_MAX) {
    00661         FOR_ALL_CLIENT_SOCKETS(cs) {
    00662           this->SendClientInfo(cs);
    00663         }
    00664       } else {
    00665         cs = NetworkClientSocket::GetByClientID((ClientID)d1);
    00666         if (cs != NULL) this->SendClientInfo(cs);
    00667       }
    00668       break;
    00669
    00670     case ADMIN_UPDATE_COMPANY_INFO:
    00671       /* The admin is asking for company info. */
    00672       const Company *company;
    00673       if (d1 == UINT32_MAX) {
    00674         FOR_ALL_COMPANIES(company) {
    00675           this->SendCompanyInfo(company);
    00676         }
    00677       } else {
    00678         company = Company::GetIfValid(d1);
    00679         if (company != NULL) this->SendCompanyInfo(company);
    00680       }
    00681       break;
    00682
    00683     case ADMIN_UPDATE_COMPANY_ECONOMY:
    00684       /* The admin is requesting economy info. */
    00685       this->SendCompanyEconomy();
    00686       break;
    00687
    00688     case ADMIN_UPDATE_COMPANY_STATS:
    00689       /* the admin is requesting company stats. */
    00690       this->SendCompanyStats();
    00691       break;
    00692
    00693     case ADMIN_UPDATE_CMD_NAMES:
    00694       /* The admin is requesting the names of DoCommands. */
    00695       this->SendCmdNames();
    00696       break;
    00697
    00698     default:
    00699       /* An unsupported "poll" update type. */
    00700       DEBUG(net, 3, "[admin] Not supported poll %d (%d) from '%s' (%s).", type, d1, this->admin_name, this->admin_version);
    00701       return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
    00702   }
    00703
    00704   return NETWORK_RECV_STATUS_OKAY;
    00705 }
    00706
    00707 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_CHAT(Packet *p)
    00708 {
    00709   if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
    00710
    00711   NetworkAction action = (NetworkAction)p->Recv_uint8();
    00712   DestType desttype = (DestType)p->Recv_uint8();
    00713   int dest = p->Recv_uint32();
    00714
    00715   char msg[NETWORK_CHAT_LENGTH];
    00716   p->Recv_string(msg, NETWORK_CHAT_LENGTH);
    00717
    00718   switch (action) {
    00719     case NETWORK_ACTION_CHAT:
    00720     case NETWORK_ACTION_CHAT_CLIENT:
    00721     case NETWORK_ACTION_CHAT_COMPANY:
    00722     case NETWORK_ACTION_SERVER_MESSAGE:
    00723       NetworkServerSendChat(action, desttype, dest, msg, _network_own_client_id, 0, true);
    00724       break;
    00725
    00726     default:
    00727       DEBUG(net, 3, "[admin] Invalid chat action %d from admin '%s' (%s).", action, this->admin_name, this->admin_version);
    00728       return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
    00729   }
    00730
    00731   return NETWORK_RECV_STATUS_OKAY;
    00732 }
    00733
    00734 /*
    00735  * Useful wrapper functions
    00736  */
    00737
    00743 void NetworkAdminClientInfo(const NetworkClientSocket *cs, bool new_client)
    00744 {
    00745   ServerNetworkAdminSocketHandler *as;
    00746   FOR_ALL_ADMIN_SOCKETS(as) {
    00747     if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
    00748       as->SendClientInfo(cs);
    00749       if (new_client) {
    00750         as->SendClientJoin(cs->client_id);
    00751       }
    00752     }
    00753   }
    00754 }
    00755
    00760 void NetworkAdminClientUpdate(const NetworkClientInfo *ci)
    00761 {
    00762   ServerNetworkAdminSocketHandler *as;
    00763   FOR_ALL_ADMIN_SOCKETS(as) {
    00764     if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
    00765       as->SendClientUpdate(ci);
    00766     }
    00767   }
    00768 }
    00769
    00774 void NetworkAdminClientQuit(ClientID client_id)
    00775 {
    00776   ServerNetworkAdminSocketHandler *as;
    00777   FOR_ALL_ADMIN_SOCKETS(as) {
    00778     if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
    00779       as->SendClientQuit(client_id);
    00780     }
    00781   }
    00782 }
    00783
    00789 void NetworkAdminClientError(ClientID client_id, NetworkErrorCode error_code)
    00790 {
    00791   ServerNetworkAdminSocketHandler *as;
    00792   FOR_ALL_ADMIN_SOCKETS(as) {
    00793     if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
    00794       as->SendClientError(client_id, error_code);
    00795     }
    00796   }
    00797 }
    00798
    00804 void NetworkAdminCompanyInfo(const Company *company, bool new_company)
    00805 {
    00806   if (company == NULL) {
    00807     DEBUG(net, 1, "[admin] Empty company given for update");
    00808     return;
    00809   }
    00810
    00811   ServerNetworkAdminSocketHandler *as;
    00812   FOR_ALL_ADMIN_SOCKETS(as) {
    00813     if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != ADMIN_FREQUENCY_AUTOMATIC) continue;
    00814
    00815     as->SendCompanyInfo(company);
    00816     if (new_company) {
    00817       as->SendCompanyNew(company->index);
    00818     }
    00819   }
    00820 }
    00821
    00826 void NetworkAdminCompanyUpdate(const Company *company)
    00827 {
    00828   if (company == NULL) return;
    00829
    00830   ServerNetworkAdminSocketHandler *as;
    00831   FOR_ALL_ADMIN_SOCKETS(as) {
    00832     if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != ADMIN_FREQUENCY_AUTOMATIC) continue;
    00833
    00834     as->SendCompanyUpdate(company);
    00835   }
    00836 }
    00837
    00843 void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bcrr)
    00844 {
    00845   ServerNetworkAdminSocketHandler *as;
    00846   FOR_ALL_ADMIN_SOCKETS(as) {
    00847     as->SendCompanyRemove(company_id, bcrr);
    00848   }
    00849 }
    00850
    00851
    00855 void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, int64 data, bool from_admin)
    00856 {
    00857   if (from_admin) return;
    00858
    00859   ServerNetworkAdminSocketHandler *as;
    00860   FOR_ALL_ADMIN_SOCKETS(as) {
    00861     if (as->update_frequency[ADMIN_UPDATE_CHAT] & ADMIN_FREQUENCY_AUTOMATIC) {
    00862       as->SendChat(action, desttype, client_id, msg, data);
    00863     }
    00864   }
    00865 }
    00866
    00873 void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const char *string)
    00874 {
    00875   ServerNetworkAdminSocketHandler::Get(admin_index)->SendRcon(colour_code, string);
    00876 }
    00877
    00883 void NetworkAdminConsole(const char *origin, const char *string)
    00884 {
    00885   ServerNetworkAdminSocketHandler *as;
    00886   FOR_ALL_ADMIN_SOCKETS(as) {
    00887     if (as->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) {
    00888       as->SendConsole(origin, string);
    00889     }
    00890   }
    00891 }
    00892
    00898 void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket *cp)
    00899 {
    00900   ClientID client_id = owner == NULL ? _network_own_client_id : owner->client_id;
    00901
    00902   ServerNetworkAdminSocketHandler *as;
    00903   FOR_ALL_ADMIN_SOCKETS(as) {
    00904     if (as->update_frequency[ADMIN_UPDATE_CMD_LOGGING] & ADMIN_FREQUENCY_AUTOMATIC) {
    00905       as->SendCmdLogging(client_id, cp);
    00906     }
    00907   }
    00908 }
    00909
    00913 void ServerNetworkAdminSocketHandler::WelcomeAll()
    00914 {
    00915   ServerNetworkAdminSocketHandler *as;
    00916   FOR_ALL_ADMIN_SOCKETS(as) {
    00917     as->SendWelcome();
    00918   }
    00919 }
    00920
    00925 void NetworkAdminUpdate(AdminUpdateFrequency freq)
    00926 {
    00927   ServerNetworkAdminSocketHandler *as;
    00928   FOR_ALL_ADMIN_SOCKETS(as) {
    00929     for (int i = 0; i < ADMIN_UPDATE_END; i++) {
    00930       if (as->update_frequency[i] & freq) {
    00931         /* Update the admin for the required details */
    00932         switch (i) {
    00933           case ADMIN_UPDATE_DATE:
    00934             as->SendDate();
    00935             break;
    00936
    00937           case ADMIN_UPDATE_COMPANY_ECONOMY:
    00938             as->SendCompanyEconomy();
    00939             break;
    00940
    00941           case ADMIN_UPDATE_COMPANY_STATS:
    00942             as->SendCompanyStats();
    00943             break;
    00944
    00945           default: NOT_REACHED();
    00946         }
    00947       }
    00948     }
    00949   }
    00950 }
    00951
    00952 #endif /* ENABLE_NETWORK */