OpenTTD
network_client.cpp
Go to the documentation of this file.
1 /* $Id$ */
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 "network_gui.h"
16 #include "../saveload/saveload.h"
17 #include "../saveload/saveload_filter.h"
18 #include "../command_func.h"
19 #include "../console_func.h"
20 #include "../strings_func.h"
21 #include "../window_func.h"
22 #include "../company_func.h"
23 #include "../company_base.h"
24 #include "../company_gui.h"
25 #include "../core/random_func.hpp"
26 #include "../date_func.h"
27 #include "../gfx_func.h"
28 #include "../error.h"
29 #include "../rev.h"
30 #include "network.h"
31 #include "network_base.h"
32 #include "network_client.h"
33 #include "../core/backup_type.hpp"
34 
35 #include "table/strings.h"
36 
37 #include "../safeguards.h"
38 
39 /* This file handles all the client-commands */
40 
41 
44  static const size_t CHUNK = 32 * 1024;
45 
47  byte *buf;
48  byte *bufe;
49  byte **block;
50  size_t written_bytes;
51  size_t read_bytes;
52 
54  PacketReader() : LoadFilter(NULL), buf(NULL), bufe(NULL), block(NULL), written_bytes(0), read_bytes(0)
55  {
56  }
57 
62  void AddPacket(const Packet *p)
63  {
64  assert(this->read_bytes == 0);
65 
66  size_t in_packet = p->size - p->pos;
67  size_t to_write = min((size_t)(this->bufe - this->buf), in_packet);
68  const byte *pbuf = p->buffer + p->pos;
69 
70  this->written_bytes += in_packet;
71  if (to_write != 0) {
72  memcpy(this->buf, pbuf, to_write);
73  this->buf += to_write;
74  }
75 
76  /* Did everything fit in the current chunk, then we're done. */
77  if (to_write == in_packet) return;
78 
79  /* Allocate a new chunk and add the remaining data. */
80  pbuf += to_write;
81  to_write = in_packet - to_write;
82  this->buf = *this->blocks.Append() = CallocT<byte>(CHUNK);
83  this->bufe = this->buf + CHUNK;
84 
85  memcpy(this->buf, pbuf, to_write);
86  this->buf += to_write;
87  }
88 
89  /* virtual */ size_t Read(byte *rbuf, size_t size)
90  {
91  /* Limit the amount to read to whatever we still have. */
92  size_t ret_size = size = min(this->written_bytes - this->read_bytes, size);
93  this->read_bytes += ret_size;
94  const byte *rbufe = rbuf + ret_size;
95 
96  while (rbuf != rbufe) {
97  if (this->buf == this->bufe) {
98  this->buf = *this->block++;
99  this->bufe = this->buf + CHUNK;
100  }
101 
102  size_t to_write = min(this->bufe - this->buf, rbufe - rbuf);
103  memcpy(rbuf, this->buf, to_write);
104  rbuf += to_write;
105  this->buf += to_write;
106  }
107 
108  return ret_size;
109  }
110 
111  /* virtual */ void Reset()
112  {
113  this->read_bytes = 0;
114 
115  this->block = this->blocks.Begin();
116  this->buf = *this->block++;
117  this->bufe = this->buf + CHUNK;
118  }
119 };
120 
121 
126 {
128 
129  const char *filename = "netsave.sav";
130  DEBUG(net, 0, "Client: Performing emergency save (%s)", filename);
131  SaveOrLoad(filename, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR, false);
132 }
133 
134 
140 {
143 }
144 
147 {
150 
151  delete this->savegame;
152 }
153 
155 {
156  assert(status != NETWORK_RECV_STATUS_OKAY);
157  /*
158  * Sending a message just before leaving the game calls cs->SendPackets.
159  * This might invoke this function, which means that when we close the
160  * connection after cs->SendPackets we will close an already closed
161  * connection. This handles that case gracefully without having to make
162  * that code any more complex or more aware of the validity of the socket.
163  */
164  if (this->sock == INVALID_SOCKET) return status;
165 
166  DEBUG(net, 1, "Closed client connection %d", this->client_id);
167 
168  this->SendPackets(true);
169 
170  /* Wait a number of ticks so our leave message can reach the server.
171  * This is especially needed for Windows servers as they seem to get
172  * the "socket is closed" message before receiving our leave message,
173  * which would trigger the server to close the connection as well. */
174  CSleep(3 * MILLISECONDS_PER_TICK);
175 
176  delete this->GetInfo();
177  delete this;
178 
179  return status;
180 }
181 
187 {
188  /* First, send a CLIENT_ERROR to the server, so he knows we are
189  * disconnection (and why!) */
190  NetworkErrorCode errorno;
191 
192  /* We just want to close the connection.. */
193  if (res == NETWORK_RECV_STATUS_CLOSE_QUERY) {
195  this->CloseConnection(res);
196  _networking = false;
197 
199  return;
200  }
201 
202  switch (res) {
203  case NETWORK_RECV_STATUS_DESYNC: errorno = NETWORK_ERROR_DESYNC; break;
204  case NETWORK_RECV_STATUS_SAVEGAME: errorno = NETWORK_ERROR_SAVEGAME_FAILED; break;
205  case NETWORK_RECV_STATUS_NEWGRF_MISMATCH: errorno = NETWORK_ERROR_NEWGRF_MISMATCH; break;
206  default: errorno = NETWORK_ERROR_GENERAL; break;
207  }
208 
209  /* This means we fucked up and the server closed the connection */
212  SendError(errorno);
213  }
214 
216  this->CloseConnection(res);
217  _networking = false;
218 }
219 
220 
227 {
228  if (my_client->CanSendReceive()) {
230  if (res != NETWORK_RECV_STATUS_OKAY) {
231  /* The client made an error of which we can not recover.
232  * Close the connection and drop back to the main menu. */
233  my_client->ClientError(res);
234  return false;
235  }
236  }
237  return _networking;
238 }
239 
242 {
245 }
246 
252 {
253  _frame_counter++;
254 
256 
257  extern void StateGameLoop();
258  StateGameLoop();
259 
260  /* Check if we are in sync! */
261  if (_sync_frame != 0) {
262  if (_sync_frame == _frame_counter) {
263 #ifdef NETWORK_SEND_DOUBLE_SEED
264  if (_sync_seed_1 != _random.state[0] || _sync_seed_2 != _random.state[1]) {
265 #else
266  if (_sync_seed_1 != _random.state[0]) {
267 #endif
268  NetworkError(STR_NETWORK_ERROR_DESYNC);
269  DEBUG(desync, 1, "sync_err: %08x; %02x", _date, _date_fract);
270  DEBUG(net, 0, "Sync error detected!");
272  return false;
273  }
274 
275  /* If this is the first time we have a sync-frame, we
276  * need to let the server know that we are ready and at the same
277  * frame as he is.. so we can start playing! */
278  if (_network_first_time) {
279  _network_first_time = false;
280  SendAck();
281  }
282 
283  _sync_frame = 0;
284  } else if (_sync_frame < _frame_counter) {
285  DEBUG(net, 1, "Missed frame for sync-test (%d / %d)", _sync_frame, _frame_counter);
286  _sync_frame = 0;
287  }
288  }
289 
290  return true;
291 }
292 
293 
296 
298 static uint32 last_ack_frame;
299 
301 static uint32 _password_game_seed;
304 
309 
312 
314 const char *_network_join_server_password = NULL;
317 
320 
321 /***********
322  * Sending functions
323  * DEF_CLIENT_SEND_COMMAND has no parameters
324  ************/
325 
328 {
330  _network_join_status = NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO;
332 
334  my_client->SendPacket(p);
336 }
337 
340 {
342  _network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING;
344 
345  Packet *p = new Packet(PACKET_CLIENT_JOIN);
347  p->Send_uint32(_openttd_newgrf_version);
348  p->Send_string(_settings_client.network.client_name); // Client name
349  p->Send_uint8 (_network_join_as); // PlayAs
350  p->Send_uint8 (NETLANG_ANY); // Language
351  my_client->SendPacket(p);
353 }
354 
357 {
359  my_client->SendPacket(p);
361 }
362 
368 {
370  p->Send_string(password);
371  my_client->SendPacket(p);
373 }
374 
380 {
382  p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _password_game_seed));
383  my_client->SendPacket(p);
385 }
386 
389 {
391 
393  my_client->SendPacket(p);
395 }
396 
399 {
401 
403  my_client->SendPacket(p);
405 }
406 
409 {
410  Packet *p = new Packet(PACKET_CLIENT_ACK);
411 
413  p->Send_uint8 (my_client->token);
414  my_client->SendPacket(p);
416 }
417 
423 {
425  my_client->NetworkGameSocketHandler::SendCommand(p, cp);
426 
427  my_client->SendPacket(p);
429 }
430 
432 NetworkRecvStatus ClientNetworkGameSocketHandler::SendChat(NetworkAction action, DestType type, int dest, const char *msg, int64 data)
433 {
434  Packet *p = new Packet(PACKET_CLIENT_CHAT);
435 
436  p->Send_uint8 (action);
437  p->Send_uint8 (type);
438  p->Send_uint32(dest);
439  p->Send_string(msg);
440  p->Send_uint64(data);
441 
442  my_client->SendPacket(p);
444 }
445 
448 {
450 
451  p->Send_uint8(errorno);
452  my_client->SendPacket(p);
454 }
455 
461 {
463 
464  p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _password_game_seed));
465  my_client->SendPacket(p);
467 }
468 
474 {
476 
477  p->Send_string(name);
478  my_client->SendPacket(p);
480 }
481 
486 {
487  Packet *p = new Packet(PACKET_CLIENT_QUIT);
488 
489  my_client->SendPacket(p);
491 }
492 
498 NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const char *pass, const char *command)
499 {
500  Packet *p = new Packet(PACKET_CLIENT_RCON);
501  p->Send_string(pass);
502  p->Send_string(command);
503  my_client->SendPacket(p);
505 }
506 
513 {
514  Packet *p = new Packet(PACKET_CLIENT_MOVE);
515  p->Send_uint8(company);
516  p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _password_game_seed));
517  my_client->SendPacket(p);
519 }
520 
526 {
527  return my_client != NULL && my_client->status == STATUS_ACTIVE;
528 }
529 
530 
531 /***********
532  * Receiving functions
533  * DEF_CLIENT_RECEIVE_COMMAND has parameter: Packet *p
534  ************/
535 
536 extern bool SafeLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = NULL);
537 
539 {
540  /* We try to join a server which is full */
541  ShowErrorMessage(STR_NETWORK_ERROR_SERVER_FULL, INVALID_STRING_ID, WL_CRITICAL);
543 
545 }
546 
548 {
549  /* We try to join a server where we are banned */
550  ShowErrorMessage(STR_NETWORK_ERROR_SERVER_BANNED, INVALID_STRING_ID, WL_CRITICAL);
552 
554 }
555 
557 {
559 
560  byte company_info_version = p->Recv_uint8();
561 
562  if (!this->HasClientQuit() && company_info_version == NETWORK_COMPANY_INFO_VERSION) {
563  /* We have received all data... (there are no more packets coming) */
564  if (!p->Recv_bool()) return NETWORK_RECV_STATUS_CLOSE_QUERY;
565 
566  CompanyID current = (Owner)p->Recv_uint8();
567  if (current >= MAX_COMPANIES) return NETWORK_RECV_STATUS_CLOSE_QUERY;
568 
569  NetworkCompanyInfo *company_info = GetLobbyCompanyInfo(current);
570  if (company_info == NULL) return NETWORK_RECV_STATUS_CLOSE_QUERY;
571 
572  p->Recv_string(company_info->company_name, sizeof(company_info->company_name));
573  company_info->inaugurated_year = p->Recv_uint32();
574  company_info->company_value = p->Recv_uint64();
575  company_info->money = p->Recv_uint64();
576  company_info->income = p->Recv_uint64();
577  company_info->performance = p->Recv_uint16();
578  company_info->use_password = p->Recv_bool();
579  for (uint i = 0; i < NETWORK_VEH_END; i++) {
580  company_info->num_vehicle[i] = p->Recv_uint16();
581  }
582  for (uint i = 0; i < NETWORK_VEH_END; i++) {
583  company_info->num_station[i] = p->Recv_uint16();
584  }
585  company_info->ai = p->Recv_bool();
586 
587  p->Recv_string(company_info->clients, sizeof(company_info->clients));
588 
590 
592  }
593 
595 }
596 
597 /* This packet contains info about the client (playas and name)
598  * as client we save this in NetworkClientInfo, linked via 'client_id'
599  * which is always an unique number on a server. */
601 {
602  NetworkClientInfo *ci;
604  CompanyID playas = (CompanyID)p->Recv_uint8();
605  char name[NETWORK_NAME_LENGTH];
606 
607  p->Recv_string(name, sizeof(name));
608 
610  if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
611 
612  ci = NetworkClientInfo::GetByClientID(client_id);
613  if (ci != NULL) {
614  if (playas == ci->client_playas && strcmp(name, ci->client_name) != 0) {
615  /* Client name changed, display the change */
616  NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, name);
617  } else if (playas != ci->client_playas) {
618  /* The client changed from client-player..
619  * Do not display that for now */
620  }
621 
622  /* Make sure we're in the company the server tells us to be in,
623  * for the rare case that we get moved while joining. */
624  if (client_id == _network_own_client_id) SetLocalCompany(!Company::IsValidID(playas) ? COMPANY_SPECTATOR : playas);
625 
626  ci->client_playas = playas;
627  strecpy(ci->client_name, name, lastof(ci->client_name));
628 
630 
632  }
633 
634  /* There are at most as many ClientInfo as ClientSocket objects in a
635  * server. Having more info than a server can have means something
636  * has gone wrong somewhere, i.e. the server has more info than it
637  * has actual clients. That means the server is feeding us an invalid
638  * state. So, bail out! This server is broken. */
640 
641  /* We don't have this client_id yet, find an empty client_id, and put the data there */
642  ci = new NetworkClientInfo(client_id);
643  ci->client_playas = playas;
644  if (client_id == _network_own_client_id) this->SetInfo(ci);
645 
646  strecpy(ci->client_name, name, lastof(ci->client_name));
647 
649 
651 }
652 
654 {
655  static const StringID network_error_strings[] = {
656  STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_GENERAL
657  STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_DESYNC
658  STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_SAVEGAME_FAILED
659  STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_CONNECTION_LOST
660  STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_ILLEGAL_PACKET
661  STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_NEWGRF_MISMATCH
662  STR_NETWORK_ERROR_SERVER_ERROR, // NETWORK_ERROR_NOT_AUTHORIZED
663  STR_NETWORK_ERROR_SERVER_ERROR, // NETWORK_ERROR_NOT_EXPECTED
664  STR_NETWORK_ERROR_WRONG_REVISION, // NETWORK_ERROR_WRONG_REVISION
665  STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_NAME_IN_USE
666  STR_NETWORK_ERROR_WRONG_PASSWORD, // NETWORK_ERROR_WRONG_PASSWORD
667  STR_NETWORK_ERROR_SERVER_ERROR, // NETWORK_ERROR_COMPANY_MISMATCH
668  STR_NETWORK_ERROR_KICKED, // NETWORK_ERROR_KICKED
669  STR_NETWORK_ERROR_CHEATER, // NETWORK_ERROR_CHEATER
670  STR_NETWORK_ERROR_SERVER_FULL, // NETWORK_ERROR_FULL
671  STR_NETWORK_ERROR_TOO_MANY_COMMANDS, // NETWORK_ERROR_TOO_MANY_COMMANDS
672  STR_NETWORK_ERROR_TIMEOUT_PASSWORD, // NETWORK_ERROR_TIMEOUT_PASSWORD
673  STR_NETWORK_ERROR_TIMEOUT_COMPUTER, // NETWORK_ERROR_TIMEOUT_COMPUTER
674  STR_NETWORK_ERROR_TIMEOUT_MAP, // NETWORK_ERROR_TIMEOUT_MAP
675  STR_NETWORK_ERROR_TIMEOUT_JOIN, // NETWORK_ERROR_TIMEOUT_JOIN
676  };
677  assert_compile(lengthof(network_error_strings) == NETWORK_ERROR_END);
678 
680 
681  StringID err = STR_NETWORK_ERROR_LOSTCONNECTION;
682  if (error < (ptrdiff_t)lengthof(network_error_strings)) err = network_error_strings[error];
683 
685 
686  /* Perform an emergency save if we had already entered the game */
688 
690 
692 }
693 
695 {
697 
698  uint grf_count = p->Recv_uint8();
700 
701  /* Check all GRFs */
702  for (; grf_count > 0; grf_count--) {
703  GRFIdentifier c;
704  this->ReceiveGRFIdentifier(p, &c);
705 
706  /* Check whether we know this GRF */
707  const GRFConfig *f = FindGRFConfig(c.grfid, FGCM_EXACT, c.md5sum);
708  if (f == NULL) {
709  /* We do not know this GRF, bail out of initialization */
710  char buf[sizeof(c.md5sum) * 2 + 1];
711  md5sumToString(buf, lastof(buf), c.md5sum);
712  DEBUG(grf, 0, "NewGRF %08X not found; checksum %s", BSWAP32(c.grfid), buf);
714  }
715  }
716 
717  if (ret == NETWORK_RECV_STATUS_OKAY) {
718  /* Start receiving the map */
719  return SendNewGRFsOk();
720  }
721 
722  /* NewGRF mismatch, bail out */
723  ShowErrorMessage(STR_NETWORK_ERROR_NEWGRF_MISMATCH, INVALID_STRING_ID, WL_CRITICAL);
724  return ret;
725 }
726 
728 {
729  if (this->status < STATUS_JOIN || this->status >= STATUS_AUTH_GAME) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
730  this->status = STATUS_AUTH_GAME;
731 
732  const char *password = _network_join_server_password;
733  if (!StrEmpty(password)) {
734  return SendGamePassword(password);
735  }
736 
737  ShowNetworkNeedPassword(NETWORK_GAME_PASSWORD);
738 
740 }
741 
743 {
744  if (this->status < STATUS_JOIN || this->status >= STATUS_AUTH_COMPANY) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
745  this->status = STATUS_AUTH_COMPANY;
746 
747  _password_game_seed = p->Recv_uint32();
748  p->Recv_string(_password_server_id, sizeof(_password_server_id));
750 
751  const char *password = _network_join_company_password;
752  if (!StrEmpty(password)) {
753  return SendCompanyPassword(password);
754  }
755 
756  ShowNetworkNeedPassword(NETWORK_COMPANY_PASSWORD);
757 
759 }
760 
762 {
763  if (this->status < STATUS_JOIN || this->status >= STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
764  this->status = STATUS_AUTHORIZED;
765 
767 
768  /* Initialize the password hash salting variables, even if they were previously. */
769  _password_game_seed = p->Recv_uint32();
770  p->Recv_string(_password_server_id, sizeof(_password_server_id));
771 
772  /* Start receiving the map */
773  return SendGetMap();
774 }
775 
777 {
778  /* We set the internal wait state when requesting the map. */
780 
781  /* But... only now we set the join status to waiting, instead of requesting. */
782  _network_join_status = NETWORK_JOIN_STATUS_WAITING;
785 
787 }
788 
790 {
791  if (this->status < STATUS_AUTHORIZED || this->status >= STATUS_MAP) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
792  this->status = STATUS_MAP;
793 
794  if (this->savegame != NULL) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
795 
796  this->savegame = new PacketReader();
797 
799 
802 
803  _network_join_status = NETWORK_JOIN_STATUS_DOWNLOADING;
805 
807 }
808 
810 {
812  if (this->savegame == NULL) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
813 
816 
818 }
819 
821 {
823  if (this->savegame == NULL) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
824 
825  /* We are still receiving data, put it to the file */
826  this->savegame->AddPacket(p);
827 
828  _network_join_bytes = (uint32)this->savegame->written_bytes;
830 
832 }
833 
835 {
837  if (this->savegame == NULL) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
838 
839  _network_join_status = NETWORK_JOIN_STATUS_PROCESSING;
841 
842  /*
843  * Make sure everything is set for reading.
844  *
845  * We need the local copy and reset this->savegame because when
846  * loading fails the network gets reset upon loading the intro
847  * game, which would cause us to free this->savegame twice.
848  */
849  LoadFilter *lf = this->savegame;
850  this->savegame = NULL;
851  lf->Reset();
852 
853  /* The map is done downloading, load it */
855  bool load_success = SafeLoad(NULL, SLO_LOAD, DFT_GAME_FILE, GM_NORMAL, NO_DIRECTORY, lf);
856 
857  /* Long savegame loads shouldn't affect the lag calculation! */
858  this->last_packet = _realtime_tick;
859 
860  if (!load_success) {
862  ShowErrorMessage(STR_NETWORK_ERROR_SAVEGAMEERROR, INVALID_STRING_ID, WL_CRITICAL);
864  }
865  /* If the savegame has successfully loaded, ALL windows have been removed,
866  * only toolbar/statusbar and gamefield are visible */
867 
868  /* Say we received the map and loaded it correctly! */
869  SendMapOk();
870 
871  /* New company/spectator (invalid company) or company we want to join is not active
872  * Switch local company to spectator and await the server's judgement */
873  if (_network_join_as == COMPANY_NEW_COMPANY || !Company::IsValidID(_network_join_as)) {
875 
876  if (_network_join_as != COMPANY_SPECTATOR) {
877  /* We have arrived and ready to start playing; send a command to make a new company;
878  * the server will give us a client-id and let us in */
879  _network_join_status = NETWORK_JOIN_STATUS_REGISTERING;
880  ShowJoinStatusWindow();
882  }
883  } else {
884  /* take control over an existing company */
885  SetLocalCompany(_network_join_as);
886  }
887 
889 }
890 
892 {
894 
897 #ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
898  /* Test if the server supports this option
899  * and if we are at the frame the server is */
900  if (p->pos + 1 < p->size) {
902  _sync_seed_1 = p->Recv_uint32();
903 #ifdef NETWORK_SEND_DOUBLE_SEED
904  _sync_seed_2 = p->Recv_uint32();
905 #endif
906  }
907 #endif
908  /* Receive the token. */
909  if (p->pos != p->size) this->token = p->Recv_uint8();
910 
911  DEBUG(net, 5, "Received FRAME %d", _frame_counter_server);
912 
913  /* Let the server know that we received this frame correctly
914  * We do this only once per day, to save some bandwidth ;) */
915  if (!_network_first_time && last_ack_frame < _frame_counter) {
916  last_ack_frame = _frame_counter + DAY_TICKS;
917  DEBUG(net, 4, "Sent ACK at %d", _frame_counter);
918  SendAck();
919  }
920 
922 }
923 
925 {
927 
928  _sync_frame = p->Recv_uint32();
929  _sync_seed_1 = p->Recv_uint32();
930 #ifdef NETWORK_SEND_DOUBLE_SEED
931  _sync_seed_2 = p->Recv_uint32();
932 #endif
933 
935 }
936 
938 {
940 
941  CommandPacket cp;
942  const char *err = this->ReceiveCommand(p, &cp);
943  cp.frame = p->Recv_uint32();
944  cp.my_cmd = p->Recv_bool();
945 
946  if (err != NULL) {
947  IConsolePrintF(CC_ERROR, "WARNING: %s from server, dropping...", err);
949  }
950 
951  this->incoming_queue.Append(&cp);
952 
954 }
955 
957 {
959 
960  char name[NETWORK_NAME_LENGTH], msg[NETWORK_CHAT_LENGTH];
961  const NetworkClientInfo *ci = NULL, *ci_to;
962 
963  NetworkAction action = (NetworkAction)p->Recv_uint8();
965  bool self_send = p->Recv_bool();
967  int64 data = p->Recv_uint64();
968 
969  ci_to = NetworkClientInfo::GetByClientID(client_id);
970  if (ci_to == NULL) return NETWORK_RECV_STATUS_OKAY;
971 
972  /* Did we initiate the action locally? */
973  if (self_send) {
974  switch (action) {
975  case NETWORK_ACTION_CHAT_CLIENT:
976  /* For speaking to client we need the client-name */
977  seprintf(name, lastof(name), "%s", ci_to->client_name);
979  break;
980 
981  /* For speaking to company or giving money, we need the company-name */
982  case NETWORK_ACTION_GIVE_MONEY:
983  if (!Company::IsValidID(ci_to->client_playas)) return NETWORK_RECV_STATUS_OKAY;
984  FALLTHROUGH;
985 
986  case NETWORK_ACTION_CHAT_COMPANY: {
987  StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;
988  SetDParam(0, ci_to->client_playas);
989 
990  GetString(name, str, lastof(name));
992  break;
993  }
994 
995  default: return NETWORK_RECV_STATUS_MALFORMED_PACKET;
996  }
997  } else {
998  /* Display message from somebody else */
999  seprintf(name, lastof(name), "%s", ci_to->client_name);
1000  ci = ci_to;
1001  }
1002 
1003  if (ci != NULL) {
1004  NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), self_send, name, msg, data);
1005  }
1006  return NETWORK_RECV_STATUS_OKAY;
1007 }
1008 
1010 {
1012 
1014 
1016  if (ci != NULL) {
1017  NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, NULL, GetNetworkErrorMsg((NetworkErrorCode)p->Recv_uint8()));
1018  delete ci;
1019  }
1020 
1022 
1023  return NETWORK_RECV_STATUS_OKAY;
1024 }
1025 
1027 {
1029 
1031 
1033  if (ci != NULL) {
1034  NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, NULL, STR_NETWORK_MESSAGE_CLIENT_LEAVING);
1035  delete ci;
1036  } else {
1037  DEBUG(net, 0, "Unknown client (%d) is leaving the game", client_id);
1038  }
1039 
1041 
1042  /* If we come here it means we could not locate the client.. strange :s */
1043  return NETWORK_RECV_STATUS_OKAY;
1044 }
1045 
1047 {
1049 
1051 
1053  if (ci != NULL) {
1054  NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, ci->client_name);
1055  }
1056 
1058 
1059  return NETWORK_RECV_STATUS_OKAY;
1060 }
1061 
1063 {
1064  /* Only when we're trying to join we really
1065  * care about the server shutting down. */
1066  if (this->status >= STATUS_JOIN) {
1067  ShowErrorMessage(STR_NETWORK_MESSAGE_SERVER_SHUTDOWN, INVALID_STRING_ID, WL_CRITICAL);
1068  }
1069 
1071 
1073 }
1074 
1076 {
1077  /* Only when we're trying to join we really
1078  * care about the server shutting down. */
1079  if (this->status >= STATUS_JOIN) {
1080  /* To throttle the reconnects a bit, every clients waits its
1081  * Client ID modulo 16. This way reconnects should be spread
1082  * out a bit. */
1084  ShowErrorMessage(STR_NETWORK_MESSAGE_SERVER_REBOOT, INVALID_STRING_ID, WL_CRITICAL);
1085  }
1086 
1088 
1090 }
1091 
1093 {
1095 
1096  TextColour colour_code = (TextColour)p->Recv_uint16();
1098 
1099  char rcon_out[NETWORK_RCONCOMMAND_LENGTH];
1100  p->Recv_string(rcon_out, sizeof(rcon_out));
1101 
1102  IConsolePrint(colour_code, rcon_out);
1103 
1104  return NETWORK_RECV_STATUS_OKAY;
1105 }
1106 
1108 {
1110 
1111  /* Nothing more in this packet... */
1113  CompanyID company_id = (CompanyID)p->Recv_uint8();
1114 
1115  if (client_id == 0) {
1116  /* definitely an invalid client id, debug message and do nothing. */
1117  DEBUG(net, 0, "[move] received invalid client index = 0");
1119  }
1120 
1121  const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
1122  /* Just make sure we do not try to use a client_index that does not exist */
1123  if (ci == NULL) return NETWORK_RECV_STATUS_OKAY;
1124 
1125  /* if not valid player, force spectator, else check player exists */
1126  if (!Company::IsValidID(company_id)) company_id = COMPANY_SPECTATOR;
1127 
1128  if (client_id == _network_own_client_id) {
1129  SetLocalCompany(company_id);
1130  }
1131 
1132  return NETWORK_RECV_STATUS_OKAY;
1133 }
1134 
1136 {
1138 
1139  _network_server_max_companies = p->Recv_uint8();
1140  _network_server_max_spectators = p->Recv_uint8();
1141 
1142  return NETWORK_RECV_STATUS_OKAY;
1143 }
1144 
1146 {
1148 
1151 
1152  return NETWORK_RECV_STATUS_OKAY;
1153 }
1154 
1159 {
1160  /* Only once we're authorized we can expect a steady stream of packets. */
1161  if (this->status < STATUS_AUTHORIZED) return;
1162 
1163  /* It might... sometimes occur that the realtime ticker overflows. */
1164  if (_realtime_tick < this->last_packet) this->last_packet = _realtime_tick;
1165 
1166  /* Lag is in milliseconds; 5 seconds are roughly twice the
1167  * server's "you're slow" threshold (1 game day). */
1168  uint lag = (_realtime_tick - this->last_packet) / 1000;
1169  if (lag < 5) return;
1170 
1171  /* 20 seconds are (way) more than 4 game days after which
1172  * the server will forcefully disconnect you. */
1173  if (lag > 20) {
1175  ShowErrorMessage(STR_NETWORK_ERROR_LOSTCONNECTION, INVALID_STRING_ID, WL_CRITICAL);
1177  return;
1178  }
1179 
1180  /* Prevent showing the lag message every tick; just update it when needed. */
1181  static uint last_lag = 0;
1182  if (last_lag == lag) return;
1183 
1184  last_lag = lag;
1185  SetDParam(0, lag);
1186  ShowErrorMessage(STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION, STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION, WL_INFO);
1187 }
1188 
1189 
1192 {
1193  /* Set the frame-counter to 0 so nothing happens till we are ready */
1194  _frame_counter = 0;
1196  last_ack_frame = 0;
1197  /* Request the game-info */
1199 }
1200 
1206 void NetworkClientSendRcon(const char *password, const char *command)
1207 {
1208  MyClient::SendRCon(password, command);
1209 }
1210 
1217 void NetworkClientRequestMove(CompanyID company_id, const char *pass)
1218 {
1219  MyClient::SendMove(company_id, pass);
1220 }
1221 
1227 {
1228  Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
1229  /* If our company is changing owner, go to spectators */
1231 
1232  NetworkClientInfo *ci;
1233  FOR_ALL_CLIENT_INFOS(ci) {
1234  if (ci->client_playas != cid) continue;
1235  NetworkTextMessage(NETWORK_ACTION_COMPANY_SPECTATOR, CC_DEFAULT, false, ci->client_name);
1237  }
1238 
1239  cur_company.Restore();
1240 }
1241 
1246 {
1248 
1249  if (ci == NULL) return;
1250 
1251  /* Don't change the name if it is the same as the old name */
1252  if (strcmp(ci->client_name, _settings_client.network.client_name) != 0) {
1253  if (!_network_server) {
1255  } else {
1257  NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, _settings_client.network.client_name);
1260  }
1261  }
1262  }
1263 }
1264 
1273 void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, int64 data)
1274 {
1275  MyClient::SendChat(action, type, dest, msg, data);
1276 }
1277 
1282 void NetworkClientSetCompanyPassword(const char *password)
1283 {
1284  MyClient::SendSetPassword(password);
1285 }
1286 
1293 {
1294  /* Only companies actually playing can speak to team. Eg spectators cannot */
1296 
1297  const NetworkClientInfo *ci;
1298  FOR_ALL_CLIENT_INFOS(ci) {
1299  if (ci->client_playas == cio->client_playas && ci != cio) return true;
1300  }
1301 
1302  return false;
1303 }
1304 
1310 {
1312 }
1313 
1319 {
1321 }
1322 
1323 #endif /* ENABLE_NETWORK */
Everything is okay.
Definition: core.h:27
Client acknowledges that it has all required NewGRFs.
Definition: tcp_game.h:60
We are trying to get company information.
used in multiplayer to create a new companies etc.
Definition: command_type.h:279
bool _networking
are we in networking mode?
Definition: network.cpp:56
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company)
Prepare a DoCommand to be send over the network.
char clients[NETWORK_CLIENTS_LENGTH]
The clients that control this company (Name1, name2, ..)
Definition: network_gui.h:40
bool HasClientQuit() const
Whether the current client connected to the socket has quit.
Definition: core.h:71
Container for all information known about a client.
Definition: network_base.h:27
SOCKET sock
The socket currently connected to.
Definition: tcp.h:36
virtual NetworkRecvStatus Receive_SERVER_WAIT(Packet *p)
Notification that another client is currently receiving the map: uint8 Number of clients waiting in f...
uint32 _sync_seed_1
Seed to compare during sync checks.
Definition: network.cpp:75
struct PacketReader * savegame
Packet reader for reading the savegame.
uint32 _realtime_tick
The real time in the game.
Definition: debug.cpp:52
Internal entity of a packet.
Definition: packet.h:44
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3199
TextColour GetDrawStringCompanyColour(CompanyID company)
Get the colour for DrawString-subroutines which matches the colour of the company.
A client changes its name.
Definition: tcp_game.h:112
static NetworkRecvStatus SendJoin()
Tell the server we would like to join.
size_t written_bytes
The total number of bytes we&#39;ve written.
static bool Receive()
Check whether we received/can send some data from/to the server and when that&#39;s the case handle it ap...
Subdirectory
The different kinds of subdirectories OpenTTD uses.
Definition: fileio_type.h:110
uint32 Recv_uint32()
Read a 32 bits integer from the packet.
Definition: packet.cpp:250
The client is authorized at the server.
virtual NetworkRecvStatus Receive_SERVER_JOIN(Packet *p)
A client joined (PACKET_CLIENT_MAP_OK), what usually directly follows is a PACKET_SERVER_CLIENT_INFO:...
NetworkRecvStatus ReceivePackets()
Do the actual receiving of packets.
Definition: tcp_game.cpp:136
Client list; Window numbers:
Definition: window_type.h:474
PacketSize pos
The current read/write position in the packet.
Definition: packet.h:54
const char * _network_join_server_password
Login password from -p argument.
virtual NetworkRecvStatus Receive_SERVER_SHUTDOWN(Packet *p)
Let the clients know that the server is closing.
static NetworkRecvStatus SendGamePassword(const char *password)
Set the game password as requested.
Switch to game intro menu.
Definition: openttd.h:32
const char * _network_join_company_password
Company password from -P argument.
virtual NetworkRecvStatus Receive_SERVER_CHAT(Packet *p)
Sends a chat-packet to the client: uint8 ID of the action (see NetworkAction).
bool ai
Is this company an AI.
Definition: network_type.h:64
virtual NetworkRecvStatus Receive_SERVER_NEWGAME(Packet *p)
Let the clients know that the server is loading a new map.
static uint8 _network_server_max_spectators
Maximum number of spectators of the currently joined server.
GUIs related to networking.
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
Definition: string.cpp:409
void Send_string(const char *data)
Sends a string over the network.
Definition: packet.cpp:152
void ClientError(NetworkRecvStatus res)
Handle an error coming from the client side.
static NetworkRecvStatus SendMapOk()
Tell the server we received the complete map.
Something went wrong (down)loading the savegame.
Definition: core.h:30
byte ** block
The block we&#39;re reading from/writing to.
void ClientNetworkEmergencySave()
Create an emergency savegame when the network connection is lost.
NetworkErrorCode
The error codes we send around in the protocols.
Definition: network_type.h:104
char company_name[NETWORK_COMPANY_NAME_LENGTH]
Company name.
Definition: network_gui.h:33
Clients sends the (hashed) game password.
Definition: tcp_game.h:64
NetworkJoinStatus _network_join_status
The status of joining.
void Send_uint8(uint8 data)
Package a 8 bits integer in the packet.
Definition: packet.cpp:100
char * md5sumToString(char *buf, const char *last, const uint8 md5sum[16])
Convert the md5sum to a hexadecimal string representation.
Definition: string.cpp:427
virtual NetworkRecvStatus Receive_SERVER_FULL(Packet *p)
Notification that the server is full.
Client part of the network protocol.
void NetworkUpdateClientInfo(ClientID client_id)
Send updated client info of a particular client.
static uint8 _network_server_max_companies
Maximum number of companies of the currently joined server.
const T * Begin() const
Get the pointer to the first item (const)
void NetworkClientRequestMove(CompanyID company_id, const char *pass)
Notify the server of this client wanting to be moved to another company.
static NetworkRecvStatus SendNewGRFsOk()
Tell the server we got all the NewGRFs.
static const int DAY_TICKS
1 day is 74 ticks; _date_fract used to be uint16 and incremented by 885.
Definition: date_type.h:30
virtual NetworkRecvStatus Receive_SERVER_CLIENT_INFO(Packet *p)
Send information about a client: uint32 ID of the client (always unique on a server.
void Send_uint32(uint32 data)
Package a 32 bits integer in the packet.
Definition: packet.cpp:121
void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, int64 data)
Send a chat message.
#define lastof(x)
Get the last element of an fixed size array.
Definition: depend.cpp:50
The client is spectating.
Definition: company_type.h:37
The client wants a new company.
Definition: company_type.h:36
static const TextColour CC_DEFAULT
Default colour of the console.
Definition: console_type.h:25
Money company_value
The company value.
Definition: network_gui.h:35
bool IsValidConsoleColour(TextColour c)
Check whether the given TextColour is valid for console usage.
Base core network types and some helper functions to access them.
bool NetworkMaxSpectatorsReached()
Check if max_spectatos has been reached on the server (local check only).
ClientNetworkGameSocketHandler(SOCKET s)
Create a new socket for the client side of the game connection.
static NetworkRecvStatus SendSetPassword(const char *password)
Tell the server that we like to change the password of the company.
const char * GetNetworkRevisionString()
Get the network version string used by this build.
Definition: network.cpp:1113
void Append(CommandPacket *p)
Append a CommandPacket at the end of the queue.
const GRFConfig * FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8 *md5sum, uint32 desired_version)
Find a NewGRF in the scanned list.
void AddPacket(const Packet *p)
Add a packet to this buffer.
virtual NetworkRecvStatus Receive_SERVER_QUIT(Packet *p)
Notification that a client left the game: uint32 ID of the client.
Class for handling the client side of the game connection.
virtual NetworkRecvStatus Receive_SERVER_CHECK_NEWGRFS(Packet *p)
Sends information about all used GRFs to the client: uint8 Amount of GRFs (the following data is repe...
uint32 _sync_frame
The frame to perform the sync check.
Definition: network.cpp:79
The server told us we made an error.
Definition: core.h:33
The client tells the server which frame it has executed.
Definition: tcp_game.h:91
Basic data to distinguish a GRF.
Definition: newgrf_config.h:84
SendPacketsState SendPackets(bool closing_down=false)
Sends all the buffered packets out for this client.
Definition: tcp.cpp:99
virtual NetworkRecvStatus Receive_SERVER_WELCOME(Packet *p)
The client is joined and ready to receive his map: uint32 Own client ID.
File is being saved.
Definition: fileio_type.h:52
StringID GetNetworkErrorMsg(NetworkErrorCode err)
Retrieve the string id of an internal error number.
Definition: network.cpp:310
Servers always have this ID.
Definition: network_type.h:45
Client asks the server to execute some command.
Definition: tcp_game.h:103
Network lobby window.
Definition: window_type.h:30
The password of the company.
Definition: network_type.h:78
T * Append(uint to_add=1)
Append an item and return it.
CommandQueue incoming_queue
The command-queue awaiting handling.
Definition: tcp_game.h:524
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:23
CompanyByte _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:46
virtual NetworkRecvStatus Receive_SERVER_ERROR(Packet *p)
The client made an error: uint8 Error code caused (see NetworkErrorCode).
virtual NetworkRecvStatus Receive_SERVER_COMMAND(Packet *p)
Sends a DoCommand to the client: uint8 ID of the company (0..MAX_COMPANIES-1).
static const size_t CHUNK
32 KiB chunks of memory.
uint16 num_vehicle[NETWORK_VEH_END]
How many vehicles are there of this type?
Definition: network_type.h:62
Save game or scenario file.
Definition: fileio_type.h:33
Done querying the server.
Definition: core.h:36
Interface for filtering a savegame till it is loaded.
A desync did occur.
Definition: core.h:28
Year inaugurated_year
What year the company started in.
Definition: network_gui.h:34
~ClientNetworkGameSocketHandler()
Clear whatever we assigned.
Critical errors, the MessageBox is shown in all cases.
Definition: error.h:26
void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x=0, int y=0, const GRFFile *textref_stack_grffile=NULL, uint textref_stack_size=0, const uint32 *textref_stack=NULL)
Display an error message in a window.
Definition: error_gui.cpp:378
void StateGameLoop()
State controlling game loop.
Definition: openttd.cpp:1352
static bool IsConnected()
Check whether the client is actually connected (and in the game).
bool prefer_teamchat
choose the chat message target with <ENTER>, true=all clients, false=your team
static NetworkRecvStatus SendAck()
Send an acknowledgement from the server&#39;s ticks.
NetworkSettings network
settings related to the network
CompanyID client_playas
As which company is this client playing (CompanyID)
Definition: network_base.h:31
static const uint NETWORK_RCONCOMMAND_LENGTH
The maximum length of a rconsole command, in bytes including &#39;\0&#39;.
Definition: config.h:50
void Send_uint64(uint64 data)
Package a 64 bits integer in the packet.
Definition: packet.cpp:134
A client would like to be moved to another company.
Definition: tcp_game.h:107
static NetworkRecvStatus SendCompanyPassword(const char *password)
Set the company password as requested.
DateFract _date_fract
Fractional part of the day.
Definition: date.cpp:29
byte * buffer
The buffer of this packet, of basically variable length up to SEND_MTU.
Definition: packet.h:56
Information about GRF, used in the game and (part of it) in savegames.
friend void NetworkExecuteLocalCommandQueue()
Execute all commands on the local command queue that ought to be executed this frame.
char client_name[NETWORK_CLIENT_NAME_LENGTH]
Name of the client.
Definition: network_base.h:29
GameMode
Mode which defines the state of the game.
Definition: openttd.h:18
NetworkRecvStatus CloseConnection(bool error=true)
Functions to help ReceivePacket/SendPacket a bit A socket can make errors.
Definition: tcp_game.cpp:44
Client sends the (hashed) company password.
Definition: tcp_game.h:66
uint8 max_spectators
maximum amount of spectators
Company information stored at the client side.
Definition: network_gui.h:32
void IConsolePrint(TextColour colour_code, const char *string)
Handle the printing of text entered into the console or redirected there by any other means...
Definition: console.cpp:88
Read some packets, and when do use that data as initial load filter.
AutoFreeSmallVector< byte *, 16 > blocks
Buffer with blocks of allocated memory.
size_t read_bytes
The total number of read bytes.
void CheckConnection()
Check the connection&#39;s state, i.e.
ClientID _network_own_client_id
Our client identifier.
Definition: network.cpp:63
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:76
static NetworkRecvStatus SendError(NetworkErrorCode errorno)
Send an error-packet over the network.
void CDECL IConsolePrintF(TextColour colour_code, const char *format,...)
Handle the printing of text entered into the console or redirected there by any other means...
Definition: console.cpp:132
A path without any base directory.
Definition: fileio_type.h:127
The client is waiting as someone else is downloading the map.
void NetworkClientsToSpectators(CompanyID cid)
Move the clients of a company to the spectators.
void SetLocalCompany(CompanyID new_company)
Sets the local company and updates the settings that are set on a per-company basis to reflect the co...
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition: gfx_type.h:247
virtual void Reset()
Reset this filter to read from the beginning of the file.
void NetworkUpdateClientName()
Send the server our name.
static const uint MILLISECONDS_PER_TICK
The number of milliseconds per game tick.
Definition: gfx_type.h:306
uint8 _network_reconnect
Reconnect timeout.
Definition: network.cpp:66
static ClientNetworkGameSocketHandler * my_client
This is us!
Subdirectory of save for autosaves.
Definition: fileio_type.h:113
NetworkRecvStatus
Status of a network client; reasons why a client has quit.
Definition: core.h:26
A client (re)sets its company&#39;s password.
Definition: tcp_game.h:111
assert_compile(NETWORK_SERVER_ID_LENGTH==16 *2+1)
Make sure the server ID length is the same as a md5 hash.
#define FOR_ALL_CLIENT_INFOS(var)
Iterate over all the clients.
Definition: network_base.h:55
byte * buf
Buffer we&#39;re going to write to/read from.
static const uint NETWORK_CHAT_LENGTH
The maximum length of a chat message, in bytes including &#39;\0&#39;.
Definition: config.h:52
virtual NetworkRecvStatus Receive_SERVER_COMPANY_INFO(Packet *p)
Sends information about the companies (one packet per company): uint8 Version of the structure of thi...
We did not have the required NewGRFs.
Definition: core.h:29
Basic functions/variables used all over the place.
virtual NetworkRecvStatus Receive_SERVER_COMPANY_UPDATE(Packet *p)
Update the clients knowledge of which company is password protected: uint16 Bitwise representation of...
PacketSize size
The size of the whole packet for received packets.
Definition: packet.h:52
SaveOrLoadResult SaveOrLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded)
Main Save or Load function where the high-level saveload functions are handled.
Definition: saveload.cpp:2721
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
virtual NetworkRecvStatus Receive_SERVER_MAP_DATA(Packet *p)
Sends the data of the map to the client: Contains a part of the map (until max size of packet)...
uint last_packet
Time we received the last frame.
Definition: tcp_game.h:525
File is being loaded.
Definition: fileio_type.h:51
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:42
NetworkClientInfo * GetInfo() const
Gets the client info of this socket handler.
Definition: tcp_game.h:550
uint32 frame
the frame in which this packet is executed
ServerStatus status
Status of the connection with the server.
NetworkRecvStatus CloseConnection(NetworkRecvStatus status)
Close the network connection due to the given status.
static NetworkRecvStatus SendRCon(const char *password, const char *command)
Send a console command.
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:18
static NetworkRecvStatus SendMove(CompanyID company, const char *password)
Ask the server to move us.
A client reports an error to the server.
Definition: tcp_game.h:123
bool Recv_bool()
Read a boolean from the packet.
Definition: packet.cpp:212
uint32 _network_join_bytes
The number of bytes we already downloaded.
SaveLoadOperation
Operation performed on the file.
Definition: fileio_type.h:49
Maximum number of companies.
Definition: company_type.h:25
void Reset()
Reset this filter to read from the beginning of the file.
void NetworkClient_Connected()
Is called after a client is connected to the server.
uint16 performance
What was his performance last month?
Definition: network_gui.h:38
uint8 max_companies
maximum amount of companies
bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio)
Tell whether the client has team members where he/she can chat to.
virtual NetworkRecvStatus Receive_SERVER_NEED_COMPANY_PASSWORD(Packet *p)
Indication to the client that the server needs a company password: uint32 Generation seed...
The connection is &#39;just&#39; lost.
Definition: core.h:31
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:36
virtual NetworkRecvStatus Receive_SERVER_BANNED(Packet *p)
Notification that the client trying to join is banned.
Network status window; Window numbers:
Definition: window_type.h:487
ClientID client_id
Client identifier.
Definition: tcp_game.h:521
virtual NetworkRecvStatus Receive_SERVER_MOVE(Packet *p)
Move a client from one company into another: uint32 ID of the client.
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
Definition: window.cpp:1144
The server is full.
Definition: core.h:34
static NetworkRecvStatus SendCompanyInformationQuery()
Query the server for company information.
The password of the game.
Definition: network_type.h:77
Network join status.
Definition: window_type.h:34
bool NetworkFindName(char *new_name, const char *last)
Check whether a name is unique, and otherwise try to make it unique.
virtual NetworkRecvStatus Receive_SERVER_SYNC(Packet *p)
Sends a sync-check to the client: uint32 Frame counter.
uint8 Recv_uint8()
Read a 8 bits integer from the packet.
Definition: packet.cpp:221
bool use_password
Is there a password.
Definition: network_gui.h:39
char client_name[NETWORK_CLIENT_NAME_LENGTH]
name of the player (as client)
virtual NetworkRecvStatus Receive_SERVER_ERROR_QUIT(Packet *p)
Inform all clients that one client made an error and thus has quit/been disconnected: uint32 ID of th...
GUISettings gui
settings related to the GUI
Client requests the actual map.
Definition: tcp_game.h:73
void SetInfo(NetworkClientInfo *info)
Sets the client info for this socket handler.
Definition: tcp_game.h:540
uint32 _frame_counter
The current frame.
Definition: network.cpp:72
The server has banned us.
Definition: core.h:35
uint64 Recv_uint64()
Read a 64 bits integer from the packet.
Definition: packet.cpp:267
void ClearErrorMessages()
Clear all errors from the queue.
Definition: error_gui.cpp:336
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:59
CompanyByte _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
Randomizer _random
Random used in the game state calculations.
Definition: random_func.cpp:27
static size_t GetNumItems()
Returns number of valid items in the pool.
Definition: pool_type.hpp:276
PacketReader()
Initialise everything.
virtual NetworkRecvStatus Receive_SERVER_NEED_GAME_PASSWORD(Packet *p)
Indication to the client that the server needs a game password.
CompanyID _network_join_as
Who would we like to join as.
CompanyMask _network_company_passworded
Bitmask of the password status of all companies.
Definition: network.cpp:84
void NetworkClientSetCompanyPassword(const char *password)
Set/Reset company password on the client side.
Client executed a command and sends it to the server.
Definition: tcp_game.h:95
ClientID
&#39;Unique&#39; identifier to be given to clients
Definition: network_type.h:43
virtual NetworkRecvStatus CloseConnection(bool error=true)
Close the current connection; for TCP this will be mostly equivalent to Close(), but for UDP it just ...
Definition: core.h:63
void NetworkClientSendRcon(const char *password, const char *command)
Send a remote console command.
void CDECL error(const char *s,...)
Error handling for fatal non-user errors.
Definition: openttd.cpp:111
The client telling the server it wants to join.
Definition: tcp_game.h:41
virtual NetworkRecvStatus Receive_SERVER_MAP_BEGIN(Packet *p)
Sends that the server will begin with sending the map to the client: uint32 Current frame...
uint32 _frame_counter_server
The frame_counter of the server, if in network-mode.
Definition: network.cpp:70
uint16 num_station[NETWORK_VEH_END]
How many stations are there of this type?
Definition: network_type.h:63
static const uint NETWORK_SERVER_ID_LENGTH
The maximum length of the network id of the servers, in bytes including &#39;\0&#39;.
Definition: config.h:45
Network window; Window numbers:
Definition: window_type.h:468
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
Definition: depend.cpp:68
The client is active within in the game.
byte * bufe
End of the buffer we write to/read from.
SwitchMode _switch_mode
The next mainloop command.
Definition: gfx.cpp:47
const char * GenerateCompanyPasswordHash(const char *password, const char *password_server_id, uint32 password_game_seed)
Hash the given password using server ID and game seed.
Definition: network.cpp:194
const char * ReceiveCommand(Packet *p, CommandPacket *cp)
Receives a command from the network.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() ...
Definition: pool_type.hpp:216
virtual NetworkRecvStatus Receive_SERVER_RCON(Packet *p)
Send the result of an issues RCon command back to the client: uint16 Colour code. ...
static uint32 _password_game_seed
One bit of &#39;entropy&#39; used to generate a salt for the company passwords.
A client tells the server it is going to quit.
Definition: tcp_game.h:121
bool NetworkMaxCompaniesReached()
Check if max_companies has been reached on the server (local check only).
bool _network_server
network-server is active
Definition: network.cpp:57
static NetworkRecvStatus SendQuit()
Tell the server we would like to quit.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-NULL) Titem.
Definition: pool_type.hpp:235
static const TextColour CC_ERROR
Colour for error lines.
Definition: console_type.h:26
We are trying to join a server.
Everything we need to know about a command to be able to execute it.
static void Send()
Send the packets of this socket handler.
virtual NetworkRecvStatus Receive_SERVER_MAP_DONE(Packet *p)
Sends that all data of the map are sent to the client:
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Definition: strings_type.h:19
static NetworkRecvStatus SendSetName(const char *name)
Tell the server that we like to change the name of the client.
uint32 grfid
GRF ID (defined by Action 0x08)
Definition: newgrf_config.h:85
We apparently send a malformed packet.
Definition: core.h:32
uint32 _network_join_bytes_total
The total number of bytes to download.
The client is downloading the map.
Client said something that should be distributed.
Definition: tcp_game.h:99
static const uint NETWORK_NAME_LENGTH
The maximum length of the server name and map name, in bytes including &#39;\0&#39;.
Definition: config.h:42
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
Definition: error.h:23
virtual void SendPacket(Packet *packet)
This function puts the packet in the send-queue and it is send as soon as possible.
Definition: tcp.cpp:65
static NetworkRecvStatus SendGetMap()
Request the map from the server.
Create a new company.
Definition: company_type.h:69
void Restore()
Restore the variable.
static NetworkRecvStatus SendCommand(const CommandPacket *cp)
Send a command to the server.
Money money
The amount of money the company has.
Definition: network_gui.h:36
void ReceiveGRFIdentifier(Packet *p, GRFIdentifier *grf)
Deserializes the GRFIdentifier (GRF ID and MD5 checksum) from the packet.
Definition: core.cpp:122
Last action was requesting game (server) password.
uint16 Recv_uint16()
Read a 16 bits integer from the packet.
Definition: packet.cpp:235
bool CanSendReceive()
Check whether this socket can send or receive something.
Definition: tcp.cpp:229
Base socket handler for all TCP sockets.
Definition: tcp_game.h:152
static uint32 BSWAP32(uint32 x)
Perform a 32 bits endianness bitswap on x.
Owner
Enum for all companies/owners.
Definition: company_type.h:20
virtual NetworkRecvStatus Receive_SERVER_FRAME(Packet *p)
Sends the current frame counter to the client: uint32 Frame counter uint32 Frame counter max (how far...
Last action was requesting company password.
uint8 md5sum[16]
MD5 checksum of file to distinguish files with the same GRF ID (eg. newer version of GRF) ...
Definition: newgrf_config.h:86
static NetworkClientInfo * GetByClientID(ClientID client_id)
Return the CI given it&#39;s client-identifier.
Definition: network.cpp:126
static uint32 last_ack_frame
Last frame we performed an ack.
Only find Grfs matching md5sum.
uint32 state[2]
The state of the randomizer.
Definition: random_func.hpp:25
static const byte NETWORK_COMPANY_INFO_VERSION
What version of company info is this?
Definition: config.h:39
uint8 _network_join_waiting
The number of clients waiting in front of us.
static NetworkRecvStatus SendChat(NetworkAction action, DestType type, int dest, const char *msg, int64 data)
Send a chat-packet over the network.
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition: window.cpp:3227
bool my_cmd
did the command originate from "me"
size_t Read(byte *rbuf, size_t size)
Read a given number of bytes from the savegame.
Date _date
Current date in days (day counter)
Definition: date.cpp:28
Company view; Window numbers:
Definition: window_type.h:364
DetailedFileType
Kinds of files in each AbstractFileType.
Definition: fileio_type.h:30
virtual NetworkRecvStatus Receive_SERVER_MAP_SIZE(Packet *p)
Sends the size of the map to the client.
uint32 _frame_counter_max
To where we may go with our clients.
Definition: network.cpp:71
static bool GameLoop()
Actual game loop for the client.
bool _network_first_time
Whether we have finished joining or not.
Definition: network.cpp:80
byte token
The token we need to send back to the server to prove we&#39;re the right client.
DestType
Destination of our chat messages.
Definition: network_type.h:82
Money income
How much did the company earned last year.
Definition: network_gui.h:37
static char _password_server_id[NETWORK_SERVER_ID_LENGTH]
The other bit of &#39;entropy&#39; used to generate a salt for the company passwords.
NetworkAction
Actions that can be used for NetworkTextMessage.
Definition: network_type.h:89
bool SafeLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf=NULL)
Load the specified savegame but on error do different things.
Definition: openttd.cpp:1011
void Recv_string(char *buffer, size_t size, StringValidationSettings settings=SVS_REPLACE_WITH_QUESTION_MARK)
Reads a string till it finds a &#39;\0&#39; in the stream.
Definition: packet.cpp:290
virtual NetworkRecvStatus Receive_SERVER_CONFIG_UPDATE(Packet *p)
Update the clients knowledge of the max settings: uint8 Maximum number of companies allowed...
Request information about all companies.
Definition: tcp_game.h:45
bool autosave_on_network_disconnect
save an autosave when you get disconnected from a network game with an error?
NetworkCompanyInfo * GetLobbyCompanyInfo(CompanyID company)
Get the company information of a given company to fill for the lobby.
Client tells the server that it received the whole map.
Definition: tcp_game.h:79
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings_func.h:201