network_admin.cpp

Go to the documentation of this file.
00001 /* $Id: network_admin.cpp 21890 2011-01-22 14:52:20Z rubidium $ */
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 
00036 NetworkAdminSocketPool _networkadminsocket_pool("NetworkAdminSocket");
00037 INSTANTIATE_POOL_METHODS(NetworkAdminSocket)
00038 
00039 
00040 static const int ADMIN_AUTHORISATION_TIMEOUT = 10000;
00041 
00042 
00044 static const AdminUpdateFrequency _admin_update_type_frequencies[] = {
00045   ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_DAILY | ADMIN_FREQUENCY_WEEKLY | ADMIN_FREQUENCY_MONTHLY | ADMIN_FREQUENCY_QUARTERLY | ADMIN_FREQUENCY_ANUALLY, 
00046   ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_AUTOMATIC,                                                                                                      
00047   ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_AUTOMATIC,                                                                                                      
00048   ADMIN_FREQUENCY_POLL |                         ADMIN_FREQUENCY_WEEKLY | ADMIN_FREQUENCY_MONTHLY | ADMIN_FREQUENCY_QUARTERLY | ADMIN_FREQUENCY_ANUALLY, 
00049   ADMIN_FREQUENCY_POLL |                         ADMIN_FREQUENCY_WEEKLY | ADMIN_FREQUENCY_MONTHLY | ADMIN_FREQUENCY_QUARTERLY | ADMIN_FREQUENCY_ANUALLY, 
00050                          ADMIN_FREQUENCY_AUTOMATIC,                                                                                                      
00051                          ADMIN_FREQUENCY_AUTOMATIC,                                                                                                      
00052   ADMIN_FREQUENCY_POLL,                                                                                                                                  
00053                          ADMIN_FREQUENCY_AUTOMATIC,                                                                                                      
00054 };
00055 assert_compile(lengthof(_admin_update_type_frequencies) == ADMIN_UPDATE_END);
00056 
00061 ServerNetworkAdminSocketHandler::ServerNetworkAdminSocketHandler(SOCKET s) : NetworkAdminSocketHandler(s)
00062 {
00063   _network_admins_connected++;
00064   this->status = ADMIN_STATUS_INACTIVE;
00065   this->realtime_connect = _realtime_tick;
00066 }
00067 
00071 ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler()
00072 {
00073   _network_admins_connected--;
00074   DEBUG(net, 1, "[admin] '%s' (%s) has disconnected", this->admin_name, this->admin_version);
00075   if (_redirect_console_to_admin == this->index) _redirect_console_to_admin = INVALID_ADMIN_ID;
00076 }
00077 
00082 /* static */ bool ServerNetworkAdminSocketHandler::AllowConnection()
00083 {
00084   return !StrEmpty(_settings_client.network.admin_password) && _network_admins_connected < MAX_ADMINS;
00085 }
00086 
00088 /* static */ void ServerNetworkAdminSocketHandler::Send()
00089 {
00090   ServerNetworkAdminSocketHandler *as;
00091   FOR_ALL_ADMIN_SOCKETS(as) {
00092     if (as->status == ADMIN_STATUS_INACTIVE && as->realtime_connect + ADMIN_AUTHORISATION_TIMEOUT < _realtime_tick) {
00093       DEBUG(net, 1, "[admin] Admin did not send its authorisation within %d seconds", ADMIN_AUTHORISATION_TIMEOUT / 1000);
00094       as->CloseConnection(true);
00095       continue;
00096     }
00097     if (as->writable) {
00098       as->SendPackets();
00099     }
00100   }
00101 }
00102 
00103 /* static */ void ServerNetworkAdminSocketHandler::AcceptConnection(SOCKET s, const NetworkAddress &address)
00104 {
00105   ServerNetworkAdminSocketHandler *as = new ServerNetworkAdminSocketHandler(s);
00106   as->address = address; // Save the IP of the client
00107 }
00108 
00109 /***********
00110  * Sending functions for admin network
00111  ************/
00112 
00113 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendError(NetworkErrorCode error)
00114 {
00115   Packet *p = new Packet(ADMIN_PACKET_SERVER_ERROR);
00116 
00117   p->Send_uint8(error);
00118   this->SendPacket(p);
00119 
00120   char str[100];
00121   StringID strid = GetNetworkErrorMsg(error);
00122   GetString(str, strid, lastof(str));
00123 
00124   DEBUG(net, 1, "[admin] the admin '%s' (%s) made an error and has been disconnected. Reason: '%s'", this->admin_name, this->admin_version, str);
00125 
00126   return this->CloseConnection(true);
00127 }
00128 
00129 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendProtocol()
00130 {
00131   Packet *p = new Packet(ADMIN_PACKET_SERVER_PROTOCOL);
00132 
00133   /* announce the protocol version */
00134   p->Send_uint8(NETWORK_GAME_ADMIN_VERSION);
00135 
00136   for (int i = 0; i < ADMIN_UPDATE_END; i++) {
00137     p->Send_bool  (true);
00138     p->Send_uint16(i);
00139     p->Send_uint16(_admin_update_type_frequencies[i]);
00140   }
00141 
00142   p->Send_bool(false);
00143   this->SendPacket(p);
00144 
00145   return this->SendWelcome();
00146 }
00147 
00148 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendWelcome()
00149 {
00150   this->status = ADMIN_STATUS_ACTIVE;
00151 
00152   Packet *p = new Packet(ADMIN_PACKET_SERVER_WELCOME);
00153 
00154   p->Send_string(_settings_client.network.server_name);
00155   p->Send_string(_openttd_revision);
00156   p->Send_bool  (_network_dedicated);
00157 
00158   p->Send_string(_network_game_info.map_name);
00159   p->Send_uint32(_settings_game.game_creation.generation_seed);
00160   p->Send_uint8 (_settings_game.game_creation.landscape);
00161   p->Send_uint32(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
00162   p->Send_uint16(MapSizeX());
00163   p->Send_uint16(MapSizeY());
00164 
00165   this->SendPacket(p);
00166 
00167   return NETWORK_RECV_STATUS_OKAY;
00168 }
00169 
00170 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendNewGame()
00171 {
00172   Packet *p = new Packet(ADMIN_PACKET_SERVER_NEWGAME);
00173   this->SendPacket(p);
00174   return NETWORK_RECV_STATUS_OKAY;
00175 }
00176 
00177 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendShutdown()
00178 {
00179   Packet *p = new Packet(ADMIN_PACKET_SERVER_SHUTDOWN);
00180   this->SendPacket(p);
00181   return NETWORK_RECV_STATUS_OKAY;
00182 }
00183 
00184 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendDate()
00185 {
00186   Packet *p = new Packet(ADMIN_PACKET_SERVER_DATE);
00187 
00188   p->Send_uint32(_date);
00189   this->SendPacket(p);
00190 
00191   return NETWORK_RECV_STATUS_OKAY;
00192 }
00193 
00194 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientJoin(ClientID client_id)
00195 {
00196   Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_JOIN);
00197 
00198   p->Send_uint32(client_id);
00199   this->SendPacket(p);
00200 
00201   return NETWORK_RECV_STATUS_OKAY;
00202 }
00203 
00204 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientInfo(const NetworkClientInfo *ci)
00205 {
00206   Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_INFO);
00207 
00208   p->Send_uint32(ci->client_id);
00209   p->Send_string(const_cast<NetworkAddress &>(ci->client_address).GetHostname());
00210   p->Send_string(ci->client_name);
00211   p->Send_uint8 (ci->client_lang);
00212   p->Send_uint32(ci->join_date);
00213   p->Send_uint8 (ci->client_playas);
00214 
00215   this->SendPacket(p);
00216 
00217   return NETWORK_RECV_STATUS_OKAY;
00218 }
00219 
00220 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientUpdate(const NetworkClientInfo *ci)
00221 {
00222   Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_UPDATE);
00223 
00224   p->Send_uint32(ci->client_id);
00225   p->Send_string(ci->client_name);
00226   p->Send_uint8 (ci->client_playas);
00227 
00228   this->SendPacket(p);
00229 
00230   return NETWORK_RECV_STATUS_OKAY;
00231 }
00232 
00233 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientQuit(ClientID client_id)
00234 {
00235   Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_QUIT);
00236 
00237   p->Send_uint32(client_id);
00238   this->SendPacket(p);
00239 
00240   return NETWORK_RECV_STATUS_OKAY;
00241 }
00242 
00243 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientError(ClientID client_id, NetworkErrorCode error)
00244 {
00245   Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_ERROR);
00246 
00247   p->Send_uint32(client_id);
00248   p->Send_uint8 (error);
00249   this->SendPacket(p);
00250 
00251   return NETWORK_RECV_STATUS_OKAY;
00252 }
00253 
00254 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyNew(CompanyID company_id)
00255 {
00256   Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_NEW);
00257   p->Send_uint8(company_id);
00258 
00259   this->SendPacket(p);
00260 
00261   return NETWORK_RECV_STATUS_OKAY;
00262 }
00263 
00264 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyInfo(const Company *c)
00265 {
00266   char company_name[NETWORK_COMPANY_NAME_LENGTH];
00267   char manager_name[NETWORK_COMPANY_NAME_LENGTH];
00268 
00269   SetDParam(0, c->index);
00270   GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
00271 
00272   SetDParam(0, c->index);
00273   GetString(manager_name, STR_PRESIDENT_NAME, lastof(manager_name));
00274 
00275   Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_INFO);
00276 
00277   p->Send_uint8 (c->index);
00278   p->Send_string(company_name);
00279   p->Send_string(manager_name);
00280   p->Send_uint8 (c->colour);
00281   p->Send_bool  (NetworkCompanyIsPassworded(c->index));
00282   p->Send_uint32(c->inaugurated_year);
00283   p->Send_bool  (c->is_ai);
00284 
00285   this->SendPacket(p);
00286 
00287   return NETWORK_RECV_STATUS_OKAY;
00288 }
00289 
00290 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyUpdate(const Company *c)
00291 {
00292   char company_name[NETWORK_COMPANY_NAME_LENGTH];
00293   char manager_name[NETWORK_COMPANY_NAME_LENGTH];
00294 
00295   SetDParam(0, c->index);
00296   GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
00297 
00298   SetDParam(0, c->index);
00299   GetString(manager_name, STR_PRESIDENT_NAME, lastof(manager_name));
00300 
00301   Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_UPDATE);
00302 
00303   p->Send_uint8 (c->index);
00304   p->Send_string(company_name);
00305   p->Send_string(manager_name);
00306   p->Send_uint8 (c->colour);
00307   p->Send_bool  (NetworkCompanyIsPassworded(c->index));
00308   p->Send_uint8 (c->quarters_of_bankruptcy);
00309 
00310   for (size_t i = 0; i < lengthof(c->share_owners); i++) {
00311     p->Send_uint8(c->share_owners[i]);
00312   }
00313 
00314   this->SendPacket(p);
00315 
00316   return NETWORK_RECV_STATUS_OKAY;
00317 }
00318 
00319 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason acrr)
00320 {
00321   Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_REMOVE);
00322 
00323   p->Send_uint8(company_id);
00324   p->Send_uint8(acrr);
00325 
00326   this->SendPacket(p);
00327 
00328   return NETWORK_RECV_STATUS_OKAY;
00329 }
00330 
00331 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyEconomy()
00332 {
00333   const Company *company;
00334   FOR_ALL_COMPANIES(company) {
00335     /* Get the income. */
00336     Money income = 0;
00337     for (uint i = 0; i < lengthof(company->yearly_expenses[0]); i++) {
00338       income -= company->yearly_expenses[0][i];
00339     }
00340 
00341     Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_ECONOMY);
00342 
00343     p->Send_uint8(company->index);
00344 
00345     /* Current information. */
00346     p->Send_uint64(company->money);
00347     p->Send_uint64(company->current_loan);
00348     p->Send_uint64(income);
00349     p->Send_uint16(company->cur_economy.delivered_cargo);
00350 
00351     /* Send stats for the last 2 quarters. */
00352     for (uint i = 0; i < 2; i++) {
00353       p->Send_uint64(company->old_economy[i].company_value);
00354       p->Send_uint16(company->old_economy[i].performance_history);
00355       p->Send_uint16(company->old_economy[i].delivered_cargo);
00356     }
00357 
00358     this->SendPacket(p);
00359   }
00360 
00361 
00362   return NETWORK_RECV_STATUS_OKAY;
00363 }
00364 
00365 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyStats()
00366 {
00367   /* Fetch the latest version of the stats. */
00368   NetworkCompanyStats company_stats[MAX_COMPANIES];
00369   NetworkPopulateCompanyStats(company_stats);
00370 
00371   const Company *company;
00372 
00373   /* Go through all the companies. */
00374   FOR_ALL_COMPANIES(company) {
00375     Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_STATS);
00376 
00377     /* Send the information. */
00378     p->Send_uint8(company->index);
00379 
00380     for (uint i = 0; i < NETWORK_VEH_END; i++) {
00381       p->Send_uint16(company_stats[company->index].num_vehicle[i]);
00382     }
00383 
00384     for (uint i = 0; i < NETWORK_VEH_END; i++) {
00385       p->Send_uint16(company_stats[company->index].num_station[i]);
00386     }
00387 
00388     this->SendPacket(p);
00389   }
00390 
00391   return NETWORK_RECV_STATUS_OKAY;
00392 }
00393 
00394 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, int64 data)
00395 {
00396   Packet *p = new Packet(ADMIN_PACKET_SERVER_CHAT);
00397 
00398   p->Send_uint8 (action);
00399   p->Send_uint8 (desttype);
00400   p->Send_uint32(client_id);
00401   p->Send_string(msg);
00402   p->Send_uint64(data);
00403 
00404   this->SendPacket(p);
00405   return NETWORK_RECV_STATUS_OKAY;
00406 }
00407 
00408 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRcon(uint16 colour, const char *result)
00409 {
00410   Packet *p = new Packet(ADMIN_PACKET_SERVER_RCON);
00411 
00412   p->Send_uint16(colour);
00413   p->Send_string(result);
00414   this->SendPacket(p);
00415 
00416   return NETWORK_RECV_STATUS_OKAY;
00417 }
00418 
00419 DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_RCON)
00420 {
00421   if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00422 
00423   char command[NETWORK_RCONCOMMAND_LENGTH];
00424 
00425   p->Recv_string(command, sizeof(command));
00426 
00427   DEBUG(net, 2, "[admin] Rcon command from '%s' (%s): '%s'", this->admin_name, this->admin_version, command);
00428 
00429   _redirect_console_to_admin = this->index;
00430   IConsoleCmdExec(command);
00431   _redirect_console_to_admin = INVALID_ADMIN_ID;
00432   return NETWORK_RECV_STATUS_OKAY;
00433 }
00434 
00435 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const char *origin, const char *string)
00436 {
00437   /* If the length of both strings, plus the 2 '\0' terminations and 3 bytes of the packet
00438    * are bigger than the MTU, just ignore the message. Better safe than sorry. It should
00439    * never occur though as the longest strings are chat messages, which are still 30%
00440    * smaller than SEND_MTU. */
00441   if (strlen(origin) + strlen(string) + 2 + 3 >= SEND_MTU) return NETWORK_RECV_STATUS_OKAY;
00442 
00443   Packet *p = new Packet(ADMIN_PACKET_SERVER_CONSOLE);
00444 
00445   p->Send_string(origin);
00446   p->Send_string(string);
00447   this->SendPacket(p);
00448 
00449   return NETWORK_RECV_STATUS_OKAY;
00450 }
00451 
00452 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdNames()
00453 {
00454   Packet *p = new Packet(ADMIN_PACKET_SERVER_CMD_NAMES);
00455 
00456   for (uint i = 0; i < CMD_END; i++) {
00457     const char *cmdname = GetCommandName(i);
00458 
00459     /* Should SEND_MTU be exceeded, start a new packet
00460      * (magic 5: 1 bool "more data" and one uint16 "command id", one
00461      * byte for string '\0' termination and 1 bool "no more data" */
00462     if (p->size + strlen(cmdname) + 5 >= SEND_MTU) {
00463       p->Send_bool(false);
00464       this->SendPacket(p);
00465 
00466       p = new Packet(ADMIN_PACKET_SERVER_CMD_NAMES);
00467     }
00468 
00469     p->Send_bool(true);
00470     p->Send_uint16(i);
00471     p->Send_string(cmdname);
00472   }
00473 
00474   /* Marker to notify the end of the packet has been reached. */
00475   p->Send_bool(false);
00476   this->SendPacket(p);
00477 
00478   return NETWORK_RECV_STATUS_OKAY;
00479 }
00480 
00481 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdLogging(ClientID client_id, const CommandPacket *cp)
00482 {
00483   Packet *p = new Packet(ADMIN_PACKET_SERVER_CMD_LOGGING);
00484 
00485   p->Send_uint32(client_id);
00486   p->Send_uint8 (cp->company);
00487   p->Send_uint16(cp->cmd & CMD_ID_MASK);
00488   p->Send_uint32(cp->p1);
00489   p->Send_uint32(cp->p2);
00490   p->Send_uint32(cp->tile);
00491   p->Send_string(cp->text);
00492   p->Send_uint32(cp->frame);
00493 
00494   this->SendPacket(p);
00495 
00496   return NETWORK_RECV_STATUS_OKAY;
00497 }
00498 
00499 /***********
00500  * Receiving functions
00501  ************/
00502 
00503 DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_JOIN)
00504 {
00505   if (this->status != ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00506 
00507   char password[NETWORK_PASSWORD_LENGTH];
00508   p->Recv_string(password, sizeof(password));
00509 
00510   if (StrEmpty(_settings_client.network.admin_password) ||
00511       strcmp(password, _settings_client.network.admin_password) != 0) {
00512     /* Password is invalid */
00513     return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
00514   }
00515 
00516   p->Recv_string(this->admin_name, sizeof(this->admin_name));
00517   p->Recv_string(this->admin_version, sizeof(this->admin_version));
00518 
00519   if (StrEmpty(this->admin_name) || StrEmpty(this->admin_version)) {
00520     /* no name or version supplied */
00521     return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
00522   }
00523 
00524   DEBUG(net, 1, "[admin] '%s' (%s) has connected", this->admin_name, this->admin_version);
00525 
00526   return this->SendProtocol();
00527 }
00528 
00529 DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_QUIT)
00530 {
00531   /* The admin is leaving nothing else to do */
00532   return this->CloseConnection();
00533 }
00534 
00535 DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY)
00536 {
00537   if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00538 
00539   AdminUpdateType type = (AdminUpdateType)p->Recv_uint16();
00540   AdminUpdateFrequency freq = (AdminUpdateFrequency)p->Recv_uint16();
00541 
00542   if (type >= ADMIN_UPDATE_END || (_admin_update_type_frequencies[type] & freq) != freq) {
00543     /* The server does not know of this UpdateType. */
00544     DEBUG(net, 3, "[admin] Not supported update frequency %d (%d) from '%s' (%s).", type, freq, this->admin_name, this->admin_version);
00545     return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
00546   }
00547 
00548   this->update_frequency[type] = freq;
00549 
00550   return NETWORK_RECV_STATUS_OKAY;
00551 }
00552 
00553 DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_POLL)
00554 {
00555   if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00556 
00557   AdminUpdateType type = (AdminUpdateType)p->Recv_uint8();
00558   uint32 d1 = p->Recv_uint32();
00559 
00560   switch (type) {
00561     case ADMIN_UPDATE_DATE:
00562       /* The admin is requesting the current date. */
00563       this->SendDate();
00564       break;
00565 
00566     case ADMIN_UPDATE_CLIENT_INFO:
00567       /* The admin is requesting client info. */
00568       const NetworkClientInfo *ci;
00569       if (d1 == UINT32_MAX) {
00570         FOR_ALL_CLIENT_INFOS(ci) {
00571           this->SendClientInfo(ci);
00572         }
00573       } else {
00574         ci = NetworkFindClientInfoFromClientID((ClientID)d1);
00575         if (ci != NULL) this->SendClientInfo(ci);
00576       }
00577       break;
00578 
00579     case ADMIN_UPDATE_COMPANY_INFO:
00580       /* The admin is asking for company info. */
00581       const Company *company;
00582       if (d1 == UINT32_MAX) {
00583         FOR_ALL_COMPANIES(company) {
00584           this->SendCompanyInfo(company);
00585         }
00586       } else {
00587         company = Company::GetIfValid(d1);
00588         if (company != NULL) this->SendCompanyInfo(company);
00589       }
00590       break;
00591 
00592     case ADMIN_UPDATE_COMPANY_ECONOMY:
00593       /* The admin is requesting economy info. */
00594       this->SendCompanyEconomy();
00595       break;
00596 
00597     case ADMIN_UPDATE_COMPANY_STATS:
00598       /* the admin is requesting company stats. */
00599       this->SendCompanyStats();
00600       break;
00601 
00602     case ADMIN_UPDATE_CMD_NAMES:
00603       /* The admin is requesting the names of DoCommands. */
00604       this->SendCmdNames();
00605       break;
00606 
00607     default:
00608       /* An unsupported "poll" update type. */
00609       DEBUG(net, 3, "[admin] Not supported poll %d (%d) from '%s' (%s).", type, d1, this->admin_name, this->admin_version);
00610       return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
00611   }
00612 
00613   return NETWORK_RECV_STATUS_OKAY;
00614 }
00615 
00616 DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_CHAT)
00617 {
00618   if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00619 
00620   NetworkAction action = (NetworkAction)p->Recv_uint8();
00621   DestType desttype = (DestType)p->Recv_uint8();
00622   int dest = p->Recv_uint32();
00623 
00624   char msg[NETWORK_CHAT_LENGTH];
00625   p->Recv_string(msg, NETWORK_CHAT_LENGTH);
00626 
00627   switch (action) {
00628     case NETWORK_ACTION_CHAT:
00629     case NETWORK_ACTION_CHAT_CLIENT:
00630     case NETWORK_ACTION_CHAT_COMPANY:
00631     case NETWORK_ACTION_SERVER_MESSAGE:
00632       NetworkServerSendChat(action, desttype, dest, msg, _network_own_client_id, 0, true);
00633       break;
00634 
00635     default:
00636       DEBUG(net, 3, "[admin] Invalid chat action %d from admin '%s' (%s).", action, this->admin_name, this->admin_version);
00637       return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
00638   }
00639 
00640   return NETWORK_RECV_STATUS_OKAY;
00641 }
00642 
00643 /*
00644  * Useful wrapper functions
00645  */
00646 
00652 void NetworkAdminClientInfo(const NetworkClientInfo *ci, bool new_client)
00653 {
00654   ServerNetworkAdminSocketHandler *as;
00655   FOR_ALL_ADMIN_SOCKETS(as) {
00656     if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
00657       as->SendClientInfo(ci);
00658       if (new_client) {
00659         as->SendClientJoin(ci->client_id);
00660       }
00661     }
00662   }
00663 }
00664 
00669 void NetworkAdminClientUpdate(const NetworkClientInfo *ci)
00670 {
00671   ServerNetworkAdminSocketHandler *as;
00672   FOR_ALL_ADMIN_SOCKETS(as) {
00673     if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
00674       as->SendClientUpdate(ci);
00675     }
00676   }
00677 }
00678 
00683 void NetworkAdminClientQuit(ClientID client_id)
00684 {
00685   ServerNetworkAdminSocketHandler *as;
00686   FOR_ALL_ADMIN_SOCKETS(as) {
00687     if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
00688       as->SendClientQuit(client_id);
00689     }
00690   }
00691 }
00692 
00698 void NetworkAdminClientError(ClientID client_id, NetworkErrorCode error_code)
00699 {
00700   ServerNetworkAdminSocketHandler *as;
00701   FOR_ALL_ADMIN_SOCKETS(as) {
00702     if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
00703       as->SendClientError(client_id, error_code);
00704     }
00705   }
00706 }
00707 
00713 void NetworkAdminCompanyInfo(const Company *company, bool new_company)
00714 {
00715   if (company == NULL) {
00716     DEBUG(net, 1, "[admin] Empty company given for update");
00717     return;
00718   }
00719 
00720   ServerNetworkAdminSocketHandler *as;
00721   FOR_ALL_ADMIN_SOCKETS(as) {
00722     if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != ADMIN_FREQUENCY_AUTOMATIC) continue;
00723 
00724     as->SendCompanyInfo(company);
00725     if (new_company) {
00726       as->SendCompanyNew(company->index);
00727     }
00728   }
00729 }
00730 
00735 void NetworkAdminCompanyUpdate(const Company *company)
00736 {
00737   if (company == NULL) return;
00738 
00739   ServerNetworkAdminSocketHandler *as;
00740   FOR_ALL_ADMIN_SOCKETS(as) {
00741     if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != ADMIN_FREQUENCY_AUTOMATIC) continue;
00742 
00743     as->SendCompanyUpdate(company);
00744   }
00745 }
00746 
00752 void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bcrr)
00753 {
00754   ServerNetworkAdminSocketHandler *as;
00755   FOR_ALL_ADMIN_SOCKETS(as) {
00756     as->SendCompanyRemove(company_id, bcrr);
00757   }
00758 }
00759 
00760 
00764 void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, int64 data, bool from_admin)
00765 {
00766   if (from_admin) return;
00767 
00768   ServerNetworkAdminSocketHandler *as;
00769   FOR_ALL_ADMIN_SOCKETS(as) {
00770     if (as->update_frequency[ADMIN_UPDATE_CHAT] & ADMIN_FREQUENCY_AUTOMATIC) {
00771       as->SendChat(action, desttype, client_id, msg, data);
00772     }
00773   }
00774 }
00775 
00782 void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const char *string)
00783 {
00784   ServerNetworkAdminSocketHandler::Get(admin_index)->SendRcon(colour_code, string);
00785 }
00786 
00792 void NetworkAdminConsole(const char *origin, const char *string)
00793 {
00794   ServerNetworkAdminSocketHandler *as;
00795   FOR_ALL_ADMIN_SOCKETS(as) {
00796     if (as->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) {
00797       as->SendConsole(origin, string);
00798     }
00799   }
00800 }
00801 
00807 void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket *cp)
00808 {
00809   ClientID client_id = owner == NULL ? _network_own_client_id : owner->client_id;
00810 
00811   ServerNetworkAdminSocketHandler *as;
00812   FOR_ALL_ADMIN_SOCKETS(as) {
00813     if (as->update_frequency[ADMIN_UPDATE_CMD_LOGGING] & ADMIN_FREQUENCY_AUTOMATIC) {
00814       as->SendCmdLogging(client_id, cp);
00815     }
00816   }
00817 }
00818 
00822 void ServerNetworkAdminSocketHandler::WelcomeAll()
00823 {
00824   ServerNetworkAdminSocketHandler *as;
00825   FOR_ALL_ADMIN_SOCKETS(as) {
00826     as->SendWelcome();
00827   }
00828 }
00829 
00834 void NetworkAdminUpdate(AdminUpdateFrequency freq)
00835 {
00836   ServerNetworkAdminSocketHandler *as;
00837   FOR_ALL_ADMIN_SOCKETS(as) {
00838     for (int i = 0; i < ADMIN_UPDATE_END; i++) {
00839       if (as->update_frequency[i] & freq) {
00840         /* Update the admin for the required details */
00841         switch (i) {
00842           case ADMIN_UPDATE_DATE:
00843             as->SendDate();
00844             break;
00845 
00846           case ADMIN_UPDATE_COMPANY_ECONOMY:
00847             as->SendCompanyEconomy();
00848             break;
00849 
00850           case ADMIN_UPDATE_COMPANY_STATS:
00851             as->SendCompanyStats();
00852             break;
00853 
00854           default: NOT_REACHED();
00855         }
00856       }
00857     }
00858   }
00859 }
00860 
00861 #endif /* ENABLE_NETWORK */

Generated on Fri Mar 18 23:17:37 2011 for OpenTTD by  doxygen 1.6.1