OpenTTD
network_server.cpp
Go to the documentation of this file.
1 /* $Id: network_server.cpp 27893 2017-08-13 18:38:42Z frosch $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #ifdef ENABLE_NETWORK
13 
14 #include "../stdafx.h"
15 #include "../strings_func.h"
16 #include "../date_func.h"
17 #include "network_admin.h"
18 #include "network_server.h"
19 #include "network_udp.h"
20 #include "network_base.h"
21 #include "../console_func.h"
22 #include "../company_base.h"
23 #include "../command_func.h"
24 #include "../saveload/saveload.h"
25 #include "../saveload/saveload_filter.h"
26 #include "../station_base.h"
27 #include "../genworld.h"
28 #include "../company_func.h"
29 #include "../company_gui.h"
30 #include "../roadveh.h"
31 #include "../order_backup.h"
32 #include "../core/pool_func.hpp"
33 #include "../core/random_func.hpp"
34 #include "../rev.h"
35 
36 #include "../safeguards.h"
37 
38 
39 /* This file handles all the server-commands */
40 
44 
46 assert_compile(MAX_CLIENT_SLOTS > MAX_CLIENTS);
48 assert_compile(NetworkClientSocketPool::MAX_SIZE == MAX_CLIENT_SLOTS);
49 
52 INSTANTIATE_POOL_METHODS(NetworkClientSocket)
53 
56 
59  ServerNetworkGameSocketHandler *cs;
61  size_t total_size;
64 
69  PacketWriter(ServerNetworkGameSocketHandler *cs) : SaveFilter(NULL), cs(cs), current(NULL), total_size(0), packets(NULL)
70  {
71  this->mutex = ThreadMutex::New();
72  }
73 
76  {
77  if (this->mutex != NULL) this->mutex->BeginCritical();
78 
79  if (this->cs != NULL && this->mutex != NULL) {
80  this->mutex->WaitForSignal();
81  }
82 
83  /* This must all wait until the Destroy function is called. */
84 
85  while (this->packets != NULL) {
86  Packet *p = this->packets->next;
87  delete this->packets;
88  this->packets = p;
89  }
90 
91  delete this->current;
92 
93  if (this->mutex != NULL) this->mutex->EndCritical();
94 
95  delete this->mutex;
96  this->mutex = NULL;
97  }
98 
109  void Destroy()
110  {
111  if (this->mutex != NULL) this->mutex->BeginCritical();
112 
113  this->cs = NULL;
114 
115  if (this->mutex != NULL) this->mutex->SendSignal();
116 
117  if (this->mutex != NULL) this->mutex->EndCritical();
118 
119  /* Make sure the saving is completely cancelled. Yes,
120  * we need to handle the save finish as well as the
121  * next connection might just be requesting a map. */
122  WaitTillSaved();
124  }
125 
133  bool HasPackets()
134  {
135  return this->packets != NULL;
136  }
137 
141  Packet *PopPacket()
142  {
143  if (this->mutex != NULL) this->mutex->BeginCritical();
144 
145  Packet *p = this->packets;
146  this->packets = p->next;
147  p->next = NULL;
148 
149  if (this->mutex != NULL) this->mutex->EndCritical();
150 
151  return p;
152  }
153 
155  void AppendQueue()
156  {
157  if (this->current == NULL) return;
158 
159  Packet **p = &this->packets;
160  while (*p != NULL) {
161  p = &(*p)->next;
162  }
163  *p = this->current;
164 
165  this->current = NULL;
166  }
167 
168  /* virtual */ void Write(byte *buf, size_t size)
169  {
170  /* We want to abort the saving when the socket is closed. */
171  if (this->cs == NULL) SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
172 
173  if (this->current == NULL) this->current = new Packet(PACKET_SERVER_MAP_DATA);
174 
175  if (this->mutex != NULL) this->mutex->BeginCritical();
176 
177  byte *bufe = buf + size;
178  while (buf != bufe) {
179  size_t to_write = min(SEND_MTU - this->current->size, bufe - buf);
180  memcpy(this->current->buffer + this->current->size, buf, to_write);
181  this->current->size += (PacketSize)to_write;
182  buf += to_write;
183 
184  if (this->current->size == SEND_MTU) {
185  this->AppendQueue();
186  if (buf != bufe) this->current = new Packet(PACKET_SERVER_MAP_DATA);
187  }
188  }
189 
190  if (this->mutex != NULL) this->mutex->EndCritical();
191 
192  this->total_size += size;
193  }
194 
195  /* virtual */ void Finish()
196  {
197  /* We want to abort the saving when the socket is closed. */
198  if (this->cs == NULL) SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
199 
200  if (this->mutex != NULL) this->mutex->BeginCritical();
201 
202  /* Make sure the last packet is flushed. */
203  this->AppendQueue();
204 
205  /* Add a packet stating that this is the end to the queue. */
206  this->current = new Packet(PACKET_SERVER_MAP_DONE);
207  this->AppendQueue();
208 
209  /* Fast-track the size to the client. */
211  p->Send_uint32((uint32)this->total_size);
212  this->cs->NetworkTCPSocketHandler::SendPacket(p);
213 
214  if (this->mutex != NULL) this->mutex->EndCritical();
215  }
216 };
217 
218 
224 {
225  this->status = STATUS_INACTIVE;
226  this->client_id = _network_client_id++;
228 
229  /* The Socket and Info pools need to be the same in size. After all,
230  * each Socket will be associated with at most one Info object. As
231  * such if the Socket was allocated the Info object can as well. */
233 }
234 
239 {
242 
243  if (this->savegame != NULL) {
244  this->savegame->Destroy();
245  this->savegame = NULL;
246  }
247 }
248 
250 {
251  /* Only allow receiving when we have some buffer free; this value
252  * can go negative, but eventually it will become positive again. */
253  if (this->receive_limit <= 0) return NULL;
254 
255  /* We can receive a packet, so try that and if needed account for
256  * the amount of received data. */
258  if (p != NULL) this->receive_limit -= p->size;
259  return p;
260 }
261 
263 {
264  assert(status != NETWORK_RECV_STATUS_OKAY);
265  /*
266  * Sending a message just before leaving the game calls cs->SendPackets.
267  * This might invoke this function, which means that when we close the
268  * connection after cs->SendPackets we will close an already closed
269  * connection. This handles that case gracefully without having to make
270  * that code any more complex or more aware of the validity of the socket.
271  */
272  if (this->sock == INVALID_SOCKET) return status;
273 
274  if (status != NETWORK_RECV_STATUS_CONN_LOST && !this->HasClientQuit() && this->status >= STATUS_AUTHORIZED) {
275  /* We did not receive a leave message from this client... */
276  char client_name[NETWORK_CLIENT_NAME_LENGTH];
277  NetworkClientSocket *new_cs;
278 
279  this->GetClientName(client_name, lastof(client_name));
280 
281  NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST);
282 
283  /* Inform other clients of this... strange leaving ;) */
284  FOR_ALL_CLIENT_SOCKETS(new_cs) {
285  if (new_cs->status > STATUS_AUTHORIZED && this != new_cs) {
286  new_cs->SendErrorQuit(this->client_id, NETWORK_ERROR_CONNECTION_LOST);
287  }
288  }
289  }
290 
291  NetworkAdminClientError(this->client_id, NETWORK_ERROR_CONNECTION_LOST);
292  DEBUG(net, 1, "Closed client connection %d", this->client_id);
293 
294  /* We just lost one client :( */
295  if (this->status >= STATUS_AUTHORIZED) _network_game_info.clients_on--;
296  extern byte _network_clients_connected;
297  _network_clients_connected--;
298 
301 
302  this->SendPackets(true);
303 
304  delete this->GetInfo();
305  delete this;
306 
307  return status;
308 }
309 
315 {
316  extern byte _network_clients_connected;
317  bool accept = _network_clients_connected < MAX_CLIENTS && _network_game_info.clients_on < _settings_client.network.max_clients;
318 
319  /* We can't go over the MAX_CLIENTS limit here. However, the
320  * pool must have place for all clients and ourself. */
321  assert_compile(NetworkClientSocketPool::MAX_SIZE == MAX_CLIENTS + 1);
323  return accept;
324 }
325 
328 {
329  NetworkClientSocket *cs;
331  if (cs->writable) {
332  if (cs->SendPackets() != SPS_CLOSED && cs->status == STATUS_MAP) {
333  /* This client is in the middle of a map-send, call the function for that */
334  cs->SendMap();
335  }
336  }
337  }
338 }
339 
340 static void NetworkHandleCommandQueue(NetworkClientSocket *cs);
341 
342 /***********
343  * Sending functions
344  * DEF_SERVER_SEND_COMMAND has parameter: NetworkClientSocket *cs
345  ************/
346 
352 {
353  if (ci->client_id != INVALID_CLIENT_ID) {
355  p->Send_uint32(ci->client_id);
356  p->Send_uint8 (ci->client_playas);
357  p->Send_string(ci->client_name);
358 
359  this->SendPacket(p);
360  }
362 }
363 
366 {
367  /* Fetch the latest version of the stats */
368  NetworkCompanyStats company_stats[MAX_COMPANIES];
369  NetworkPopulateCompanyStats(company_stats);
370 
371  /* Make a list of all clients per company */
372  char clients[MAX_COMPANIES][NETWORK_CLIENTS_LENGTH];
373  NetworkClientSocket *csi;
374  memset(clients, 0, sizeof(clients));
375 
376  /* Add the local player (if not dedicated) */
378  if (ci != NULL && Company::IsValidID(ci->client_playas)) {
379  strecpy(clients[ci->client_playas], ci->client_name, lastof(clients[ci->client_playas]));
380  }
381 
383  char client_name[NETWORK_CLIENT_NAME_LENGTH];
384 
385  ((ServerNetworkGameSocketHandler*)csi)->GetClientName(client_name, lastof(client_name));
386 
387  ci = csi->GetInfo();
388  if (ci != NULL && Company::IsValidID(ci->client_playas)) {
389  if (!StrEmpty(clients[ci->client_playas])) {
390  strecat(clients[ci->client_playas], ", ", lastof(clients[ci->client_playas]));
391  }
392 
393  strecat(clients[ci->client_playas], client_name, lastof(clients[ci->client_playas]));
394  }
395  }
396 
397  /* Now send the data */
398 
399  Company *company;
400  Packet *p;
401 
402  FOR_ALL_COMPANIES(company) {
404 
406  p->Send_bool (true);
407  this->SendCompanyInformation(p, company, &company_stats[company->index]);
408 
409  if (StrEmpty(clients[company->index])) {
410  p->Send_string("<none>");
411  } else {
412  p->Send_string(clients[company->index]);
413  }
414 
415  this->SendPacket(p);
416  }
417 
419 
421  p->Send_bool (false);
422 
423  this->SendPacket(p);
425 }
426 
432 {
433  char str[100];
435 
436  p->Send_uint8(error);
437  this->SendPacket(p);
438 
439  StringID strid = GetNetworkErrorMsg(error);
440  GetString(str, strid, lastof(str));
441 
442  /* Only send when the current client was in game */
443  if (this->status > STATUS_AUTHORIZED) {
444  NetworkClientSocket *new_cs;
445  char client_name[NETWORK_CLIENT_NAME_LENGTH];
446 
447  this->GetClientName(client_name, lastof(client_name));
448 
449  DEBUG(net, 1, "'%s' made an error and has been disconnected. Reason: '%s'", client_name, str);
450 
451  NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, strid);
452 
453  FOR_ALL_CLIENT_SOCKETS(new_cs) {
454  if (new_cs->status > STATUS_AUTHORIZED && new_cs != this) {
455  /* Some errors we filter to a more general error. Clients don't have to know the real
456  * reason a joining failed. */
457  if (error == NETWORK_ERROR_NOT_AUTHORIZED || error == NETWORK_ERROR_NOT_EXPECTED || error == NETWORK_ERROR_WRONG_REVISION) {
458  error = NETWORK_ERROR_ILLEGAL_PACKET;
459  }
460  new_cs->SendErrorQuit(this->client_id, error);
461  }
462  }
463 
464  NetworkAdminClientError(this->client_id, error);
465  } else {
466  DEBUG(net, 1, "Client %d made an error and has been disconnected. Reason: '%s'", this->client_id, str);
467  }
468 
469  /* The client made a mistake, so drop his connection now! */
471 }
472 
475 {
477  const GRFConfig *c;
478  uint grf_count = 0;
479 
480  for (c = _grfconfig; c != NULL; c = c->next) {
481  if (!HasBit(c->flags, GCF_STATIC)) grf_count++;
482  }
483 
484  p->Send_uint8 (grf_count);
485  for (c = _grfconfig; c != NULL; c = c->next) {
486  if (!HasBit(c->flags, GCF_STATIC)) this->SendGRFIdentifier(p, &c->ident);
487  }
488 
489  this->SendPacket(p);
491 }
492 
495 {
496  /* Invalid packet when status is STATUS_AUTH_GAME or higher */
498 
499  this->status = STATUS_AUTH_GAME;
500  /* Reset 'lag' counters */
502 
504  this->SendPacket(p);
506 }
507 
510 {
511  /* Invalid packet when status is STATUS_AUTH_COMPANY or higher */
513 
514  this->status = STATUS_AUTH_COMPANY;
515  /* Reset 'lag' counters */
517 
521  this->SendPacket(p);
523 }
524 
527 {
528  Packet *p;
529  NetworkClientSocket *new_cs;
530 
531  /* Invalid packet when status is AUTH or higher */
533 
534  this->status = STATUS_AUTHORIZED;
535  /* Reset 'lag' counters */
537 
539 
540  p = new Packet(PACKET_SERVER_WELCOME);
541  p->Send_uint32(this->client_id);
544  this->SendPacket(p);
545 
546  /* Transmit info about all the active clients */
547  FOR_ALL_CLIENT_SOCKETS(new_cs) {
548  if (new_cs != this && new_cs->status > STATUS_AUTHORIZED) {
549  this->SendClientInfo(new_cs->GetInfo());
550  }
551  }
552  /* Also send the info of the server */
554 }
555 
558 {
559  int waiting = 0;
560  NetworkClientSocket *new_cs;
561  Packet *p;
562 
563  /* Count how many clients are waiting in the queue, in front of you! */
564  FOR_ALL_CLIENT_SOCKETS(new_cs) {
565  if (new_cs->status != STATUS_MAP_WAIT) continue;
566  if (new_cs->GetInfo()->join_date < this->GetInfo()->join_date || (new_cs->GetInfo()->join_date == this->GetInfo()->join_date && new_cs->client_id < this->client_id)) waiting++;
567  }
568 
569  p = new Packet(PACKET_SERVER_WAIT);
570  p->Send_uint8(waiting);
571  this->SendPacket(p);
573 }
574 
577 {
578  static uint sent_packets; // How many packets we did send successfully last time
579 
580  if (this->status < STATUS_AUTHORIZED) {
581  /* Illegal call, return error and ignore the packet */
582  return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
583  }
584 
585  if (this->status == STATUS_AUTHORIZED) {
586  this->savegame = new PacketWriter(this);
587 
588  /* Now send the _frame_counter and how many packets are coming */
591  this->SendPacket(p);
592 
594  this->status = STATUS_MAP;
595  /* Mark the start of download */
596  this->last_frame = _frame_counter;
598 
599  sent_packets = 4; // We start with trying 4 packets
600 
601  /* Make a dump of the current game */
602  if (SaveWithFilter(this->savegame, true) != SL_OK) usererror("network savedump failed");
603  }
604 
605  if (this->status == STATUS_MAP) {
606  bool last_packet = false;
607  bool has_packets = false;
608 
609  for (uint i = 0; (has_packets = this->savegame->HasPackets()) && i < sent_packets; i++) {
610  Packet *p = this->savegame->PopPacket();
611  last_packet = p->buffer[2] == PACKET_SERVER_MAP_DONE;
612 
613  this->SendPacket(p);
614 
615  if (last_packet) {
616  /* There is no more data, so break the for */
617  break;
618  }
619  }
620 
621  if (last_packet) {
622  /* Done reading, make sure saving is done as well */
623  this->savegame->Destroy();
624  this->savegame = NULL;
625 
626  /* Set the status to DONE_MAP, no we will wait for the client
627  * to send it is ready (maybe that happens like never ;)) */
628  this->status = STATUS_DONE_MAP;
629 
630  /* Find the best candidate for joining, i.e. the first joiner. */
631  NetworkClientSocket *new_cs;
632  NetworkClientSocket *best = NULL;
633  FOR_ALL_CLIENT_SOCKETS(new_cs) {
634  if (new_cs->status == STATUS_MAP_WAIT) {
635  if (best == NULL || best->GetInfo()->join_date > new_cs->GetInfo()->join_date || (best->GetInfo()->join_date == new_cs->GetInfo()->join_date && best->client_id > new_cs->client_id)) {
636  best = new_cs;
637  }
638  }
639  }
640 
641  /* Is there someone else to join? */
642  if (best != NULL) {
643  /* Let the first start joining. */
644  best->status = STATUS_AUTHORIZED;
645  best->SendMap();
646 
647  /* And update the rest. */
648  FOR_ALL_CLIENT_SOCKETS(new_cs) {
649  if (new_cs->status == STATUS_MAP_WAIT) new_cs->SendWait();
650  }
651  }
652  }
653 
654  switch (this->SendPackets()) {
655  case SPS_CLOSED:
657 
658  case SPS_ALL_SENT:
659  /* All are sent, increase the sent_packets */
660  if (has_packets) sent_packets *= 2;
661  break;
662 
663  case SPS_PARTLY_SENT:
664  /* Only a part is sent; leave the transmission state. */
665  break;
666 
667  case SPS_NONE_SENT:
668  /* Not everything is sent, decrease the sent_packets */
669  if (sent_packets > 1) sent_packets /= 2;
670  break;
671  }
672  }
674 }
675 
681 {
682  Packet *p = new Packet(PACKET_SERVER_JOIN);
683 
684  p->Send_uint32(client_id);
685 
686  this->SendPacket(p);
688 }
689 
692 {
696 #ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
698 #ifdef NETWORK_SEND_DOUBLE_SEED
699  p->Send_uint32(_sync_seed_2);
700 #endif
701 #endif
702 
703  /* If token equals 0, we need to make a new token and send that. */
704  if (this->last_token == 0) {
705  this->last_token = InteractiveRandomRange(UINT8_MAX - 1) + 1;
706  p->Send_uint8(this->last_token);
707  }
708 
709  this->SendPacket(p);
711 }
712 
715 {
716  Packet *p = new Packet(PACKET_SERVER_SYNC);
719 
720 #ifdef NETWORK_SEND_DOUBLE_SEED
721  p->Send_uint32(_sync_seed_2);
722 #endif
723  this->SendPacket(p);
725 }
726 
732 {
734 
736  p->Send_uint32(cp->frame);
737  p->Send_bool (cp->my_cmd);
738 
739  this->SendPacket(p);
741 }
742 
751 NetworkRecvStatus ServerNetworkGameSocketHandler::SendChat(NetworkAction action, ClientID client_id, bool self_send, const char *msg, int64 data)
752 {
754 
755  Packet *p = new Packet(PACKET_SERVER_CHAT);
756 
757  p->Send_uint8 (action);
758  p->Send_uint32(client_id);
759  p->Send_bool (self_send);
760  p->Send_string(msg);
761  p->Send_uint64(data);
762 
763  this->SendPacket(p);
765 }
766 
773 {
775 
776  p->Send_uint32(client_id);
777  p->Send_uint8 (errorno);
778 
779  this->SendPacket(p);
781 }
782 
788 {
789  Packet *p = new Packet(PACKET_SERVER_QUIT);
790 
791  p->Send_uint32(client_id);
792 
793  this->SendPacket(p);
795 }
796 
799 {
801  this->SendPacket(p);
803 }
804 
807 {
809  this->SendPacket(p);
811 }
812 
819 {
820  Packet *p = new Packet(PACKET_SERVER_RCON);
821 
822  p->Send_uint16(colour);
823  p->Send_string(command);
824  this->SendPacket(p);
826 }
827 
834 {
835  Packet *p = new Packet(PACKET_SERVER_MOVE);
836 
837  p->Send_uint32(client_id);
838  p->Send_uint8(company_id);
839  this->SendPacket(p);
841 }
842 
845 {
847 
849  this->SendPacket(p);
851 }
852 
855 {
857 
860  this->SendPacket(p);
862 }
863 
864 /***********
865  * Receiving functions
866  * DEF_SERVER_RECEIVE_COMMAND has parameter: NetworkClientSocket *cs, Packet *p
867  ************/
868 
870 {
871  return this->SendCompanyInfo();
872 }
873 
875 {
876  if (this->status != STATUS_NEWGRFS_CHECK) {
877  /* Illegal call, return error and ignore the packet */
878  return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
879  }
880 
881  NetworkClientInfo *ci = this->GetInfo();
882 
883  /* We now want a password from the client else we do not allow him in! */
885  return this->SendNeedGamePassword();
886  }
887 
889  return this->SendNeedCompanyPassword();
890  }
891 
892  return this->SendWelcome();
893 }
894 
896 {
897  if (this->status != STATUS_INACTIVE) {
898  /* Illegal call, return error and ignore the packet */
899  return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
900  }
901 
902  char name[NETWORK_CLIENT_NAME_LENGTH];
903  CompanyID playas;
904  NetworkLanguage client_lang;
905  char client_revision[NETWORK_REVISION_LENGTH];
906 
907  p->Recv_string(client_revision, sizeof(client_revision));
908  uint32 newgrf_version = p->Recv_uint32();
909 
910  /* Check if the client has revision control enabled */
911  if (!IsNetworkCompatibleVersion(client_revision) || _openttd_newgrf_version != newgrf_version) {
912  /* Different revisions!! */
913  return this->SendError(NETWORK_ERROR_WRONG_REVISION);
914  }
915 
916  p->Recv_string(name, sizeof(name));
917  playas = (Owner)p->Recv_uint8();
918  client_lang = (NetworkLanguage)p->Recv_uint8();
919 
920  if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
921 
922  /* join another company does not affect these values */
923  switch (playas) {
924  case COMPANY_NEW_COMPANY: // New company
926  return this->SendError(NETWORK_ERROR_FULL);
927  }
928  break;
929  case COMPANY_SPECTATOR: // Spectator
930  if (NetworkSpectatorCount() >= _settings_client.network.max_spectators) {
931  return this->SendError(NETWORK_ERROR_FULL);
932  }
933  break;
934  default: // Join another company (companies 1-8 (index 0-7))
935  if (!Company::IsValidHumanID(playas)) {
936  return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH);
937  }
938  break;
939  }
940 
941  /* We need a valid name.. make it Player */
942  if (StrEmpty(name)) strecpy(name, "Player", lastof(name));
943 
944  if (!NetworkFindName(name, lastof(name))) { // Change name if duplicate
945  /* We could not create a name for this client */
946  return this->SendError(NETWORK_ERROR_NAME_IN_USE);
947  }
948 
951  this->SetInfo(ci);
952  ci->join_date = _date;
953  strecpy(ci->client_name, name, lastof(ci->client_name));
954  ci->client_playas = playas;
955  ci->client_lang = client_lang;
956  DEBUG(desync, 1, "client: %08x; %02x; %02x; %02x", _date, _date_fract, (int)ci->client_playas, (int)ci->index);
957 
958  /* Make sure companies to which people try to join are not autocleaned */
960 
962 
963  if (_grfconfig == NULL) {
964  /* Behave as if we received PACKET_CLIENT_NEWGRFS_CHECKED */
965  return this->Receive_CLIENT_NEWGRFS_CHECKED(NULL);
966  }
967 
968  return this->SendNewGRFCheck();
969 }
970 
972 {
973  if (this->status != STATUS_AUTH_GAME) {
974  return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
975  }
976 
977  char password[NETWORK_PASSWORD_LENGTH];
978  p->Recv_string(password, sizeof(password));
979 
980  /* Check game password. Allow joining if we cleared the password meanwhile */
982  strcmp(password, _settings_client.network.server_password) != 0) {
983  /* Password is invalid */
984  return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
985  }
986 
987  const NetworkClientInfo *ci = this->GetInfo();
989  return this->SendNeedCompanyPassword();
990  }
991 
992  /* Valid password, allow user */
993  return this->SendWelcome();
994 }
995 
997 {
998  if (this->status != STATUS_AUTH_COMPANY) {
999  return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
1000  }
1001 
1002  char password[NETWORK_PASSWORD_LENGTH];
1003  p->Recv_string(password, sizeof(password));
1004 
1005  /* Check company password. Allow joining if we cleared the password meanwhile.
1006  * Also, check the company is still valid - client could be moved to spectators
1007  * in the middle of the authorization process */
1008  CompanyID playas = this->GetInfo()->client_playas;
1009  if (Company::IsValidID(playas) && !StrEmpty(_network_company_states[playas].password) &&
1010  strcmp(password, _network_company_states[playas].password) != 0) {
1011  /* Password is invalid */
1012  return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
1013  }
1014 
1015  return this->SendWelcome();
1016 }
1017 
1019 {
1020  NetworkClientSocket *new_cs;
1021  /* The client was never joined.. so this is impossible, right?
1022  * Ignore the packet, give the client a warning, and close his connection */
1023  if (this->status < STATUS_AUTHORIZED || this->HasClientQuit()) {
1024  return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
1025  }
1026 
1027  /* Check if someone else is receiving the map */
1028  FOR_ALL_CLIENT_SOCKETS(new_cs) {
1029  if (new_cs->status == STATUS_MAP) {
1030  /* Tell the new client to wait */
1031  this->status = STATUS_MAP_WAIT;
1032  return this->SendWait();
1033  }
1034  }
1035 
1036  /* We receive a request to upload the map.. give it to the client! */
1037  return this->SendMap();
1038 }
1039 
1041 {
1042  /* Client has the map, now start syncing */
1043  if (this->status == STATUS_DONE_MAP && !this->HasClientQuit()) {
1044  char client_name[NETWORK_CLIENT_NAME_LENGTH];
1045  NetworkClientSocket *new_cs;
1046 
1047  this->GetClientName(client_name, lastof(client_name));
1048 
1049  NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, client_name, NULL, this->client_id);
1050 
1051  /* Mark the client as pre-active, and wait for an ACK
1052  * so we know he is done loading and in sync with us */
1053  this->status = STATUS_PRE_ACTIVE;
1055  this->SendFrame();
1056  this->SendSync();
1057 
1058  /* This is the frame the client receives
1059  * we need it later on to make sure the client is not too slow */
1060  this->last_frame = _frame_counter;
1062 
1063  FOR_ALL_CLIENT_SOCKETS(new_cs) {
1064  if (new_cs->status > STATUS_AUTHORIZED) {
1065  new_cs->SendClientInfo(this->GetInfo());
1066  new_cs->SendJoin(this->client_id);
1067  }
1068  }
1069 
1070  NetworkAdminClientInfo(this, true);
1071 
1072  /* also update the new client with our max values */
1073  this->SendConfigUpdate();
1074 
1075  /* quickly update the syncing client with company details */
1076  return this->SendCompanyUpdate();
1077  }
1078 
1079  /* Wrong status for this packet, give a warning to client, and close connection */
1080  return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
1081 }
1082 
1088 {
1089  /* The client was never joined.. so this is impossible, right?
1090  * Ignore the packet, give the client a warning, and close his connection */
1091  if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
1092  return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
1093  }
1094 
1096  return this->SendError(NETWORK_ERROR_TOO_MANY_COMMANDS);
1097  }
1098 
1099  CommandPacket cp;
1100  const char *err = this->ReceiveCommand(p, &cp);
1101 
1102  if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
1103 
1104  NetworkClientInfo *ci = this->GetInfo();
1105 
1106  if (err != NULL) {
1107  IConsolePrintF(CC_ERROR, "WARNING: %s from client %d (IP: %s).", err, ci->client_id, this->GetClientIP());
1108  return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
1109  }
1110 
1111 
1112  if ((GetCommandFlags(cp.cmd) & CMD_SERVER) && ci->client_id != CLIENT_ID_SERVER) {
1113  IConsolePrintF(CC_ERROR, "WARNING: server only command from: client %d (IP: %s), kicking...", ci->client_id, this->GetClientIP());
1114  return this->SendError(NETWORK_ERROR_KICKED);
1115  }
1116 
1118  IConsolePrintF(CC_ERROR, "WARNING: spectator issueing command from client %d (IP: %s), kicking...", ci->client_id, this->GetClientIP());
1119  return this->SendError(NETWORK_ERROR_KICKED);
1120  }
1121 
1127  if (!(cp.cmd == CMD_COMPANY_CTRL && cp.p1 == 0 && ci->client_playas == COMPANY_NEW_COMPANY) && ci->client_playas != cp.company) {
1128  IConsolePrintF(CC_ERROR, "WARNING: client %d (IP: %s) tried to execute a command as company %d, kicking...",
1129  ci->client_playas + 1, this->GetClientIP(), cp.company + 1);
1130  return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH);
1131  }
1132 
1133  if (cp.cmd == CMD_COMPANY_CTRL) {
1134  if (cp.p1 != 0 || cp.company != COMPANY_SPECTATOR) {
1135  return this->SendError(NETWORK_ERROR_CHEATER);
1136  }
1137 
1138  /* Check if we are full - else it's possible for spectators to send a CMD_COMPANY_CTRL and the company is created regardless of max_companies! */
1140  NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_CLIENT, ci->client_id, "cannot create new company, server full", CLIENT_ID_SERVER);
1141  return NETWORK_RECV_STATUS_OKAY;
1142  }
1143  }
1144 
1145  if (GetCommandFlags(cp.cmd) & CMD_CLIENT_ID) cp.p2 = this->client_id;
1146 
1147  this->incoming_queue.Append(&cp);
1148  return NETWORK_RECV_STATUS_OKAY;
1149 }
1150 
1152 {
1153  /* This packets means a client noticed an error and is reporting this
1154  * to us. Display the error and report it to the other clients */
1155  NetworkClientSocket *new_cs;
1156  char str[100];
1157  char client_name[NETWORK_CLIENT_NAME_LENGTH];
1159 
1160  /* The client was never joined.. thank the client for the packet, but ignore it */
1161  if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
1163  }
1164 
1165  this->GetClientName(client_name, lastof(client_name));
1166 
1167  StringID strid = GetNetworkErrorMsg(errorno);
1168  GetString(str, strid, lastof(str));
1169 
1170  DEBUG(net, 2, "'%s' reported an error and is closing its connection (%s)", client_name, str);
1171 
1172  NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, strid);
1173 
1174  FOR_ALL_CLIENT_SOCKETS(new_cs) {
1175  if (new_cs->status > STATUS_AUTHORIZED) {
1176  new_cs->SendErrorQuit(this->client_id, errorno);
1177  }
1178  }
1179 
1180  NetworkAdminClientError(this->client_id, errorno);
1181 
1183 }
1184 
1186 {
1187  /* The client wants to leave. Display this and report it to the other
1188  * clients. */
1189  NetworkClientSocket *new_cs;
1190  char client_name[NETWORK_CLIENT_NAME_LENGTH];
1191 
1192  /* The client was never joined.. thank the client for the packet, but ignore it */
1193  if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
1195  }
1196 
1197  this->GetClientName(client_name, lastof(client_name));
1198 
1199  NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, STR_NETWORK_MESSAGE_CLIENT_LEAVING);
1200 
1201  FOR_ALL_CLIENT_SOCKETS(new_cs) {
1202  if (new_cs->status > STATUS_AUTHORIZED && new_cs != this) {
1203  new_cs->SendQuit(this->client_id);
1204  }
1205  }
1206 
1208 
1210 }
1211 
1213 {
1214  if (this->status < STATUS_AUTHORIZED) {
1215  /* Illegal call, return error and ignore the packet */
1216  return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
1217  }
1218 
1219  uint32 frame = p->Recv_uint32();
1220 
1221  /* The client is trying to catch up with the server */
1222  if (this->status == STATUS_PRE_ACTIVE) {
1223  /* The client is not yet catched up? */
1224  if (frame + DAY_TICKS < _frame_counter) return NETWORK_RECV_STATUS_OKAY;
1225 
1226  /* Now he is! Unpause the game */
1227  this->status = STATUS_ACTIVE;
1229 
1230  /* Execute script for, e.g. MOTD */
1231  IConsoleCmdExec("exec scripts/on_server_connect.scr 0");
1232  }
1233 
1234  /* Get, and validate the token. */
1235  uint8 token = p->Recv_uint8();
1236  if (token == this->last_token) {
1237  /* We differentiate between last_token_frame and last_frame so the lag
1238  * test uses the actual lag of the client instead of the lag for getting
1239  * the token back and forth; after all, the token is only sent every
1240  * time we receive a PACKET_CLIENT_ACK, after which we will send a new
1241  * token to the client. If the lag would be one day, then we would not
1242  * be sending the new token soon enough for the new daily scheduled
1243  * PACKET_CLIENT_ACK. This would then register the lag of the client as
1244  * two days, even when it's only a single day. */
1246  /* Request a new token. */
1247  this->last_token = 0;
1248  }
1249 
1250  /* The client received the frame, make note of it */
1251  this->last_frame = frame;
1252  /* With those 2 values we can calculate the lag realtime */
1254  return NETWORK_RECV_STATUS_OKAY;
1255 }
1256 
1257 
1268 void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, const char *msg, ClientID from_id, int64 data, bool from_admin)
1269 {
1270  NetworkClientSocket *cs;
1271  const NetworkClientInfo *ci, *ci_own, *ci_to;
1272 
1273  switch (desttype) {
1274  case DESTTYPE_CLIENT:
1275  /* Are we sending to the server? */
1276  if ((ClientID)dest == CLIENT_ID_SERVER) {
1277  ci = NetworkClientInfo::GetByClientID(from_id);
1278  /* Display the text locally, and that is it */
1279  if (ci != NULL) {
1280  NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
1281 
1283  NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
1284  }
1285  }
1286  } else {
1287  /* Else find the client to send the message to */
1289  if (cs->client_id == (ClientID)dest) {
1290  cs->SendChat(action, from_id, false, msg, data);
1291  break;
1292  }
1293  }
1294  }
1295 
1296  /* Display the message locally (so you know you have sent it) */
1297  if (from_id != (ClientID)dest) {
1298  if (from_id == CLIENT_ID_SERVER) {
1299  ci = NetworkClientInfo::GetByClientID(from_id);
1301  if (ci != NULL && ci_to != NULL) {
1302  NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), true, ci_to->client_name, msg, data);
1303  }
1304  } else {
1306  if (cs->client_id == from_id) {
1307  cs->SendChat(action, (ClientID)dest, true, msg, data);
1308  break;
1309  }
1310  }
1311  }
1312  }
1313  break;
1314  case DESTTYPE_TEAM: {
1315  /* If this is false, the message is already displayed on the client who sent it. */
1316  bool show_local = true;
1317  /* Find all clients that belong to this company */
1318  ci_to = NULL;
1320  ci = cs->GetInfo();
1321  if (ci != NULL && ci->client_playas == (CompanyID)dest) {
1322  cs->SendChat(action, from_id, false, msg, data);
1323  if (cs->client_id == from_id) show_local = false;
1324  ci_to = ci; // Remember a client that is in the company for company-name
1325  }
1326  }
1327 
1328  /* if the server can read it, let the admin network read it, too. */
1330  NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
1331  }
1332 
1333  ci = NetworkClientInfo::GetByClientID(from_id);
1335  if (ci != NULL && ci_own != NULL && ci_own->client_playas == dest) {
1336  NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
1337  if (from_id == CLIENT_ID_SERVER) show_local = false;
1338  ci_to = ci_own;
1339  }
1340 
1341  /* There is no such client */
1342  if (ci_to == NULL) break;
1343 
1344  /* Display the message locally (so you know you have sent it) */
1345  if (ci != NULL && show_local) {
1346  if (from_id == CLIENT_ID_SERVER) {
1347  char name[NETWORK_NAME_LENGTH];
1348  StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;
1349  SetDParam(0, ci_to->client_playas);
1350  GetString(name, str, lastof(name));
1351  NetworkTextMessage(action, GetDrawStringCompanyColour(ci_own->client_playas), true, name, msg, data);
1352  } else {
1354  if (cs->client_id == from_id) {
1355  cs->SendChat(action, ci_to->client_id, true, msg, data);
1356  }
1357  }
1358  }
1359  }
1360  break;
1361  }
1362  default:
1363  DEBUG(net, 0, "[server] received unknown chat destination type %d. Doing broadcast instead", desttype);
1364  FALLTHROUGH;
1365 
1366  case DESTTYPE_BROADCAST:
1368  cs->SendChat(action, from_id, false, msg, data);
1369  }
1370 
1371  NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
1372 
1373  ci = NetworkClientInfo::GetByClientID(from_id);
1374  if (ci != NULL) {
1375  NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
1376  }
1377  break;
1378  }
1379 }
1380 
1382 {
1383  if (this->status < STATUS_PRE_ACTIVE) {
1384  /* Illegal call, return error and ignore the packet */
1385  return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
1386  }
1387 
1388  NetworkAction action = (NetworkAction)p->Recv_uint8();
1389  DestType desttype = (DestType)p->Recv_uint8();
1390  int dest = p->Recv_uint32();
1391  char msg[NETWORK_CHAT_LENGTH];
1392 
1394  int64 data = p->Recv_uint64();
1395 
1396  NetworkClientInfo *ci = this->GetInfo();
1397  switch (action) {
1398  case NETWORK_ACTION_GIVE_MONEY:
1399  if (!Company::IsValidID(ci->client_playas)) break;
1400  FALLTHROUGH;
1401  case NETWORK_ACTION_CHAT:
1402  case NETWORK_ACTION_CHAT_CLIENT:
1403  case NETWORK_ACTION_CHAT_COMPANY:
1404  NetworkServerSendChat(action, desttype, dest, msg, this->client_id, data);
1405  break;
1406  default:
1407  IConsolePrintF(CC_ERROR, "WARNING: invalid chat action from client %d (IP: %s).", ci->client_id, this->GetClientIP());
1408  return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
1409  }
1410  return NETWORK_RECV_STATUS_OKAY;
1411 }
1412 
1414 {
1415  if (this->status != STATUS_ACTIVE) {
1416  /* Illegal call, return error and ignore the packet */
1417  return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
1418  }
1419 
1420  char password[NETWORK_PASSWORD_LENGTH];
1421  const NetworkClientInfo *ci;
1422 
1423  p->Recv_string(password, sizeof(password));
1424  ci = this->GetInfo();
1425 
1427  return NETWORK_RECV_STATUS_OKAY;
1428 }
1429 
1431 {
1432  if (this->status != STATUS_ACTIVE) {
1433  /* Illegal call, return error and ignore the packet */
1434  return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
1435  }
1436 
1437  char client_name[NETWORK_CLIENT_NAME_LENGTH];
1438  NetworkClientInfo *ci;
1439 
1440  p->Recv_string(client_name, sizeof(client_name));
1441  ci = this->GetInfo();
1442 
1443  if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
1444 
1445  if (ci != NULL) {
1446  /* Display change */
1447  if (NetworkFindName(client_name, lastof(client_name))) {
1448  NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, client_name);
1449  strecpy(ci->client_name, client_name, lastof(ci->client_name));
1451  }
1452  }
1453  return NETWORK_RECV_STATUS_OKAY;
1454 }
1455 
1457 {
1458  if (this->status != STATUS_ACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
1459 
1460  char pass[NETWORK_PASSWORD_LENGTH];
1461  char command[NETWORK_RCONCOMMAND_LENGTH];
1462 
1464 
1465  p->Recv_string(pass, sizeof(pass));
1466  p->Recv_string(command, sizeof(command));
1467 
1468  if (strcmp(pass, _settings_client.network.rcon_password) != 0) {
1469  DEBUG(net, 0, "[rcon] wrong password from client-id %d", this->client_id);
1470  return NETWORK_RECV_STATUS_OKAY;
1471  }
1472 
1473  DEBUG(net, 0, "[rcon] client-id %d executed: '%s'", this->client_id, command);
1474 
1476  IConsoleCmdExec(command);
1478  return NETWORK_RECV_STATUS_OKAY;
1479 }
1480 
1482 {
1483  if (this->status != STATUS_ACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
1484 
1485  CompanyID company_id = (Owner)p->Recv_uint8();
1486 
1487  /* Check if the company is valid, we don't allow moving to AI companies */
1488  if (company_id != COMPANY_SPECTATOR && !Company::IsValidHumanID(company_id)) return NETWORK_RECV_STATUS_OKAY;
1489 
1490  /* Check if we require a password for this company */
1491  if (company_id != COMPANY_SPECTATOR && !StrEmpty(_network_company_states[company_id].password)) {
1492  /* we need a password from the client - should be in this packet */
1493  char password[NETWORK_PASSWORD_LENGTH];
1494  p->Recv_string(password, sizeof(password));
1495 
1496  /* Incorrect password sent, return! */
1497  if (strcmp(password, _network_company_states[company_id].password) != 0) {
1498  DEBUG(net, 2, "[move] wrong password from client-id #%d for company #%d", this->client_id, company_id + 1);
1499  return NETWORK_RECV_STATUS_OKAY;
1500  }
1501  }
1502 
1503  /* if we get here we can move the client */
1504  NetworkServerDoMove(this->client_id, company_id);
1505  return NETWORK_RECV_STATUS_OKAY;
1506 }
1507 
1516 {
1517  /* Grab the company name */
1518  char company_name[NETWORK_COMPANY_NAME_LENGTH];
1519  SetDParam(0, c->index);
1520 
1521  assert(max_len <= lengthof(company_name));
1522  GetString(company_name, STR_COMPANY_NAME, company_name + max_len - 1);
1523 
1524  /* Get the income */
1525  Money income = 0;
1526  if (_cur_year - 1 == c->inaugurated_year) {
1527  /* The company is here just 1 year, so display [2], else display[1] */
1528  for (uint i = 0; i < lengthof(c->yearly_expenses[2]); i++) {
1529  income -= c->yearly_expenses[2][i];
1530  }
1531  } else {
1532  for (uint i = 0; i < lengthof(c->yearly_expenses[1]); i++) {
1533  income -= c->yearly_expenses[1][i];
1534  }
1535  }
1536 
1537  /* Send the information */
1538  p->Send_uint8 (c->index);
1539  p->Send_string(company_name);
1542  p->Send_uint64(c->money);
1543  p->Send_uint64(income);
1545 
1546  /* Send 1 if there is a password for the company else send 0 */
1548 
1549  for (uint i = 0; i < NETWORK_VEH_END; i++) {
1550  p->Send_uint16(stats->num_vehicle[i]);
1551  }
1552 
1553  for (uint i = 0; i < NETWORK_VEH_END; i++) {
1554  p->Send_uint16(stats->num_station[i]);
1555  }
1556 
1557  p->Send_bool(c->is_ai);
1558 }
1559 
1565 {
1566  const Vehicle *v;
1567  const Station *s;
1568 
1569  memset(stats, 0, sizeof(*stats) * MAX_COMPANIES);
1570 
1571  /* Go through all vehicles and count the type of vehicles */
1572  FOR_ALL_VEHICLES(v) {
1573  if (!Company::IsValidID(v->owner) || !v->IsPrimaryVehicle()) continue;
1574  byte type = 0;
1575  switch (v->type) {
1576  case VEH_TRAIN: type = NETWORK_VEH_TRAIN; break;
1577  case VEH_ROAD: type = RoadVehicle::From(v)->IsBus() ? NETWORK_VEH_BUS : NETWORK_VEH_LORRY; break;
1578  case VEH_AIRCRAFT: type = NETWORK_VEH_PLANE; break;
1579  case VEH_SHIP: type = NETWORK_VEH_SHIP; break;
1580  default: continue;
1581  }
1582  stats[v->owner].num_vehicle[type]++;
1583  }
1584 
1585  /* Go through all stations and count the types of stations */
1586  FOR_ALL_STATIONS(s) {
1587  if (Company::IsValidID(s->owner)) {
1588  NetworkCompanyStats *npi = &stats[s->owner];
1589 
1590  if (s->facilities & FACIL_TRAIN) npi->num_station[NETWORK_VEH_TRAIN]++;
1591  if (s->facilities & FACIL_TRUCK_STOP) npi->num_station[NETWORK_VEH_LORRY]++;
1592  if (s->facilities & FACIL_BUS_STOP) npi->num_station[NETWORK_VEH_BUS]++;
1593  if (s->facilities & FACIL_AIRPORT) npi->num_station[NETWORK_VEH_PLANE]++;
1594  if (s->facilities & FACIL_DOCK) npi->num_station[NETWORK_VEH_SHIP]++;
1595  }
1596  }
1597 }
1598 
1604 {
1605  NetworkClientSocket *cs;
1607 
1608  if (ci == NULL) return;
1609 
1610  DEBUG(desync, 1, "client: %08x; %02x; %02x; %04x", _date, _date_fract, (int)ci->client_playas, client_id);
1611 
1613  cs->SendClientInfo(ci);
1614  }
1615 
1617 }
1618 
1621 {
1623  DEBUG(net, 0, "Auto-restarting map. Year %d reached", _cur_year);
1624 
1626  }
1627 }
1628 
1636 {
1637  const NetworkClientInfo *ci;
1638  const Company *c;
1639  bool clients_in_company[MAX_COMPANIES];
1640  int vehicles_in_company[MAX_COMPANIES];
1641 
1643 
1644  memset(clients_in_company, 0, sizeof(clients_in_company));
1645 
1646  /* Detect the active companies */
1647  FOR_ALL_CLIENT_INFOS(ci) {
1648  if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true;
1649  }
1650 
1651  if (!_network_dedicated) {
1653  if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true;
1654  }
1655 
1657  memset(vehicles_in_company, 0, sizeof(vehicles_in_company));
1658 
1659  const Vehicle *v;
1660  FOR_ALL_VEHICLES(v) {
1661  if (!Company::IsValidID(v->owner) || !v->IsPrimaryVehicle()) continue;
1662  vehicles_in_company[v->owner]++;
1663  }
1664  }
1665 
1666  /* Go through all the companies */
1667  FOR_ALL_COMPANIES(c) {
1668  /* Skip the non-active once */
1669  if (c->is_ai) continue;
1670 
1671  if (!clients_in_company[c->index]) {
1672  /* The company is empty for one month more */
1674 
1675  /* Is the company empty for autoclean_unprotected-months, and is there no protection? */
1677  /* Shut the company down */
1678  DoCommandP(0, 2 | c->index << 16, CRR_AUTOCLEAN, CMD_COMPANY_CTRL);
1679  IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no password", c->index + 1);
1680  }
1681  /* Is the company empty for autoclean_protected-months, and there is a protection? */
1683  /* Unprotect the company */
1684  _network_company_states[c->index].password[0] = '\0';
1685  IConsolePrintF(CC_DEFAULT, "Auto-removed protection from company #%d", c->index + 1);
1688  }
1689  /* Is the company empty for autoclean_novehicles-months, and has no vehicles? */
1691  /* Shut the company down */
1692  DoCommandP(0, 2 | c->index << 16, CRR_AUTOCLEAN, CMD_COMPANY_CTRL);
1693  IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no vehicles", c->index + 1);
1694  }
1695  } else {
1696  /* It is not empty, reset the date */
1698  }
1699  }
1700 }
1701 
1708 bool NetworkFindName(char *new_name, const char *last)
1709 {
1710  bool found_name = false;
1711  uint number = 0;
1712  char original_name[NETWORK_CLIENT_NAME_LENGTH];
1713 
1714  strecpy(original_name, new_name, lastof(original_name));
1715 
1716  while (!found_name) {
1717  const NetworkClientInfo *ci;
1718 
1719  found_name = true;
1720  FOR_ALL_CLIENT_INFOS(ci) {
1721  if (strcmp(ci->client_name, new_name) == 0) {
1722  /* Name already in use */
1723  found_name = false;
1724  break;
1725  }
1726  }
1727  /* Check if it is the same as the server-name */
1729  if (ci != NULL) {
1730  if (strcmp(ci->client_name, new_name) == 0) found_name = false; // name already in use
1731  }
1732 
1733  if (!found_name) {
1734  /* Try a new name (<name> #1, <name> #2, and so on) */
1735 
1736  /* Something's really wrong when there're more names than clients */
1737  if (number++ > MAX_CLIENTS) break;
1738  seprintf(new_name, last, "%s #%d", original_name, number);
1739  }
1740  }
1741 
1742  return found_name;
1743 }
1744 
1751 bool NetworkServerChangeClientName(ClientID client_id, const char *new_name)
1752 {
1753  NetworkClientInfo *ci;
1754  /* Check if the name's already in use */
1755  FOR_ALL_CLIENT_INFOS(ci) {
1756  if (strcmp(ci->client_name, new_name) == 0) return false;
1757  }
1758 
1759  ci = NetworkClientInfo::GetByClientID(client_id);
1760  if (ci == NULL) return false;
1761 
1762  NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, true, ci->client_name, new_name);
1763 
1764  strecpy(ci->client_name, new_name, lastof(ci->client_name));
1765 
1766  NetworkUpdateClientInfo(client_id);
1767  return true;
1768 }
1769 
1776 void NetworkServerSetCompanyPassword(CompanyID company_id, const char *password, bool already_hashed)
1777 {
1778  if (!Company::IsValidHumanID(company_id)) return;
1779 
1780  if (!already_hashed) {
1782  }
1783 
1784  strecpy(_network_company_states[company_id].password, password, lastof(_network_company_states[company_id].password));
1785  NetworkServerUpdateCompanyPassworded(company_id, !StrEmpty(_network_company_states[company_id].password));
1786 }
1787 
1792 static void NetworkHandleCommandQueue(NetworkClientSocket *cs)
1793 {
1794  CommandPacket *cp;
1795  while ((cp = cs->outgoing_queue.Pop()) != NULL) {
1796  cs->SendCommand(cp);
1797  free(cp);
1798  }
1799 }
1800 
1805 void NetworkServer_Tick(bool send_frame)
1806 {
1807  NetworkClientSocket *cs;
1808 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
1809  bool send_sync = false;
1810 #endif
1811 
1812 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
1815  send_sync = true;
1816  }
1817 #endif
1818 
1819  /* Now we are done with the frame, inform the clients that they can
1820  * do their frame! */
1822  /* We allow a number of bytes per frame, but only to the burst amount
1823  * to be available for packet receiving at any particular time. */
1824  cs->receive_limit = min(cs->receive_limit + _settings_client.network.bytes_per_frame,
1826 
1827  /* Check if the speed of the client is what we can expect from a client */
1828  uint lag = NetworkCalculateLag(cs);
1829  switch (cs->status) {
1830  case NetworkClientSocket::STATUS_ACTIVE:
1832  /* Client did still not report in within the specified limit. */
1833  IConsolePrintF(CC_ERROR, cs->last_packet + lag * MILLISECONDS_PER_TICK > _realtime_tick ?
1834  /* A packet was received in the last three game days, so the client is likely lagging behind. */
1835  "Client #%d is dropped because the client's game state is more than %d ticks behind" :
1836  /* No packet was received in the last three game days; sounds like a lost connection. */
1837  "Client #%d is dropped because the client did not respond for more than %d ticks",
1838  cs->client_id, lag);
1839  cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
1840  continue;
1841  }
1842 
1843  /* Report once per time we detect the lag, and only when we
1844  * received a packet in the last 2000 milliseconds. If we
1845  * did not receive a packet, then the client is not just
1846  * slow, but the connection is likely severed. Mentioning
1847  * frame_freq is not useful in this case. */
1848  if (lag > (uint)DAY_TICKS && cs->lag_test == 0 && cs->last_packet + 2000 > _realtime_tick) {
1849  IConsolePrintF(CC_WARNING, "[%d] Client #%d is slow, try increasing [network.]frame_freq to a higher value!", _frame_counter, cs->client_id);
1850  cs->lag_test = 1;
1851  }
1852 
1853  if (cs->last_frame_server - cs->last_token_frame >= _settings_client.network.max_lag_time) {
1854  /* This is a bad client! It didn't send the right token back within time. */
1855  IConsolePrintF(CC_ERROR, "Client #%d is dropped because it fails to send valid acks", cs->client_id);
1856  cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
1857  continue;
1858  }
1859  break;
1860 
1861  case NetworkClientSocket::STATUS_INACTIVE:
1862  case NetworkClientSocket::STATUS_NEWGRFS_CHECK:
1863  case NetworkClientSocket::STATUS_AUTHORIZED:
1864  /* NewGRF check and authorized states should be handled almost instantly.
1865  * So give them some lee-way, likewise for the query with inactive. */
1867  IConsolePrintF(CC_ERROR, "Client #%d is dropped because it took longer than %d ticks to start the joining process", cs->client_id, _settings_client.network.max_init_time);
1868  cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
1869  continue;
1870  }
1871  break;
1872 
1873  case NetworkClientSocket::STATUS_MAP:
1874  /* Downloading the map... this is the amount of time since starting the saving. */
1876  IConsolePrintF(CC_ERROR, "Client #%d is dropped because it took longer than %d ticks to download the map", cs->client_id, _settings_client.network.max_download_time);
1877  cs->SendError(NETWORK_ERROR_TIMEOUT_MAP);
1878  continue;
1879  }
1880  break;
1881 
1882  case NetworkClientSocket::STATUS_DONE_MAP:
1883  case NetworkClientSocket::STATUS_PRE_ACTIVE:
1884  /* The map has been sent, so this is for loading the map and syncing up. */
1886  IConsolePrintF(CC_ERROR, "Client #%d is dropped because it took longer than %d ticks to join", cs->client_id, _settings_client.network.max_join_time);
1887  cs->SendError(NETWORK_ERROR_TIMEOUT_JOIN);
1888  continue;
1889  }
1890  break;
1891 
1892  case NetworkClientSocket::STATUS_AUTH_GAME:
1893  case NetworkClientSocket::STATUS_AUTH_COMPANY:
1894  /* These don't block? */
1896  IConsolePrintF(CC_ERROR, "Client #%d is dropped because it took longer than %d ticks to enter the password", cs->client_id, _settings_client.network.max_password_time);
1897  cs->SendError(NETWORK_ERROR_TIMEOUT_PASSWORD);
1898  continue;
1899  }
1900  break;
1901 
1902  case NetworkClientSocket::STATUS_MAP_WAIT:
1903  /* This is an internal state where we do not wait
1904  * on the client to move to a different state. */
1905  break;
1906 
1907  case NetworkClientSocket::STATUS_END:
1908  /* Bad server/code. */
1909  NOT_REACHED();
1910  }
1911 
1912  if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) {
1913  /* Check if we can send command, and if we have anything in the queue */
1915 
1916  /* Send an updated _frame_counter_max to the client */
1917  if (send_frame) cs->SendFrame();
1918 
1919 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
1920  /* Send a sync-check packet */
1921  if (send_sync) cs->SendSync();
1922 #endif
1923  }
1924  }
1925 
1926  /* See if we need to advertise */
1928 }
1929 
1932 {
1935 }
1936 
1939 {
1943 }
1944 
1947 {
1950 }
1951 
1957 {
1958  return this->client_address.GetHostname();
1959 }
1960 
1963 {
1964  static const char * const stat_str[] = {
1965  "inactive",
1966  "checking NewGRFs",
1967  "authorizing (server password)",
1968  "authorizing (company password)",
1969  "authorized",
1970  "waiting",
1971  "loading map",
1972  "map done",
1973  "ready",
1974  "active"
1975  };
1976  assert_compile(lengthof(stat_str) == NetworkClientSocket::STATUS_END);
1977 
1978  NetworkClientSocket *cs;
1980  NetworkClientInfo *ci = cs->GetInfo();
1981  if (ci == NULL) continue;
1982  uint lag = NetworkCalculateLag(cs);
1983  const char *status;
1984 
1985  status = (cs->status < (ptrdiff_t)lengthof(stat_str) ? stat_str[cs->status] : "unknown");
1986  IConsolePrintF(CC_INFO, "Client #%1d name: '%s' status: '%s' frame-lag: %3d company: %1d IP: %s",
1987  cs->client_id, ci->client_name, status, lag,
1988  ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0),
1989  cs->GetClientIP());
1990  }
1991 }
1992 
1997 {
1998  NetworkClientSocket *cs;
1999 
2001  if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendConfigUpdate();
2002  }
2003 }
2004 
2010 void NetworkServerUpdateCompanyPassworded(CompanyID company_id, bool passworded)
2011 {
2012  if (NetworkCompanyIsPassworded(company_id) == passworded) return;
2013 
2014  SB(_network_company_passworded, company_id, 1, !!passworded);
2016 
2017  NetworkClientSocket *cs;
2019  if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendCompanyUpdate();
2020  }
2021 
2023 }
2024 
2031 void NetworkServerDoMove(ClientID client_id, CompanyID company_id)
2032 {
2033  /* Only allow non-dedicated servers and normal clients to be moved */
2034  if (client_id == CLIENT_ID_SERVER && _network_dedicated) return;
2035 
2037 
2038  /* No need to waste network resources if the client is in the company already! */
2039  if (ci->client_playas == company_id) return;
2040 
2041  ci->client_playas = company_id;
2042 
2043  if (client_id == CLIENT_ID_SERVER) {
2044  SetLocalCompany(company_id);
2045  } else {
2046  NetworkClientSocket *cs = NetworkClientSocket::GetByClientID(client_id);
2047  /* When the company isn't authorized we can't move them yet. */
2048  if (cs->status < NetworkClientSocket::STATUS_AUTHORIZED) return;
2049  cs->SendMove(client_id, company_id);
2050  }
2051 
2052  /* announce the client's move */
2053  NetworkUpdateClientInfo(client_id);
2054 
2055  NetworkAction action = (company_id == COMPANY_SPECTATOR) ? NETWORK_ACTION_COMPANY_SPECTATOR : NETWORK_ACTION_COMPANY_JOIN;
2056  NetworkServerSendChat(action, DESTTYPE_BROADCAST, 0, "", client_id, company_id + 1);
2057 }
2058 
2065 void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const char *string)
2066 {
2067  NetworkClientSocket::GetByClientID(client_id)->SendRConResult(colour_code, string);
2068 }
2069 
2075 {
2076  if (client_id == CLIENT_ID_SERVER) return;
2077  NetworkClientSocket::GetByClientID(client_id)->SendError(NETWORK_ERROR_KICKED);
2078 }
2079 
2085 uint NetworkServerKickOrBanIP(ClientID client_id, bool ban)
2086 {
2087  return NetworkServerKickOrBanIP(NetworkClientSocket::GetByClientID(client_id)->GetClientIP(), ban);
2088 }
2089 
2095 uint NetworkServerKickOrBanIP(const char *ip, bool ban)
2096 {
2097  /* Add address to ban-list */
2098  if (ban) {
2099  bool contains = false;
2100  for (char **iter = _network_ban_list.Begin(); iter != _network_ban_list.End(); iter++) {
2101  if (strcmp(*iter, ip) == 0) {
2102  contains = true;
2103  break;
2104  }
2105  }
2106  if (!contains) *_network_ban_list.Append() = stredup(ip);
2107  }
2108 
2109  uint n = 0;
2110 
2111  /* There can be multiple clients with the same IP, kick them all */
2112  NetworkClientSocket *cs;
2114  if (cs->client_id == CLIENT_ID_SERVER) continue;
2115  if (cs->client_address.IsInNetmask(const_cast<char *>(ip))) {
2116  NetworkServerKickClient(cs->client_id);
2117  n++;
2118  }
2119  }
2120 
2121  return n;
2122 }
2123 
2130 {
2131  const NetworkClientInfo *ci;
2132  FOR_ALL_CLIENT_INFOS(ci) {
2133  if (ci->client_playas == company) return true;
2134  }
2135  return false;
2136 }
2137 
2138 
2144 void ServerNetworkGameSocketHandler::GetClientName(char *client_name, const char *last) const
2145 {
2146  const NetworkClientInfo *ci = this->GetInfo();
2147 
2148  if (ci == NULL || StrEmpty(ci->client_name)) {
2149  seprintf(client_name, last, "Client #%4d", this->client_id);
2150  } else {
2151  strecpy(client_name, ci->client_name, last);
2152  }
2153 }
2154 
2159 {
2160  NetworkClientInfo *ci;
2161  FOR_ALL_CLIENT_INFOS(ci) {
2162  if (_network_server) {
2163  IConsolePrintF(CC_INFO, "Client #%1d name: '%s' company: %1d IP: %s",
2164  ci->client_id,
2165  ci->client_name,
2166  ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0),
2167  ci->client_id == CLIENT_ID_SERVER ? "server" : NetworkClientSocket::GetByClientID(ci->client_id)->GetClientIP());
2168  } else {
2169  IConsolePrintF(CC_INFO, "Client #%1d name: '%s' company: %1d",
2170  ci->client_id,
2171  ci->client_name,
2172  ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0));
2173  }
2174  }
2175 }
2176 
2183 {
2184  assert(c != NULL);
2185 
2186  if (!_network_server) return;
2187 
2189  _network_company_states[c->index].password[0] = '\0';
2191 
2192  if (ci != NULL) {
2193  /* ci is NULL when replaying, or for AIs. In neither case there is a client. */
2194  ci->client_playas = c->index;
2196  NetworkSendCommand(0, 0, 0, CMD_RENAME_PRESIDENT, NULL, ci->client_name, c->index);
2197  }
2198 
2199  /* Announce new company on network. */
2200  NetworkAdminCompanyInfo(c, true);
2201 
2202  if (ci != NULL) {
2203  /* ci is NULL when replaying, or for AIs. In neither case there is a client.
2204  We need to send Admin port update here so that they first know about the new company
2205  and then learn about a possibly joining client (see FS#6025) */
2206  NetworkServerSendChat(NETWORK_ACTION_COMPANY_NEW, DESTTYPE_BROADCAST, 0, "", ci->client_id, c->index + 1);
2207  }
2208 }
2209 
2210 #endif /* ENABLE_NETWORK */