OpenTTD
network.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 #include "../stdafx.h"
13 
14 #include "../strings_func.h"
15 #include "../command_func.h"
16 #include "../date_func.h"
17 #include "network_admin.h"
18 #include "network_client.h"
19 #include "network_server.h"
20 #include "network_content.h"
21 #include "network_udp.h"
22 #include "network_gamelist.h"
23 #include "network_base.h"
24 #include "core/udp.h"
25 #include "core/host.h"
26 #include "network_gui.h"
27 #include "../console_func.h"
28 #include "../3rdparty/md5/md5.h"
29 #include "../core/random_func.hpp"
30 #include "../window_func.h"
31 #include "../company_func.h"
32 #include "../company_base.h"
33 #include "../landscape_type.h"
34 #include "../rev.h"
35 #include "../core/pool_func.hpp"
36 #include "../gfx_func.h"
37 #include "../error.h"
38 
39 #include "../safeguards.h"
40 
41 #ifdef DEBUG_DUMP_COMMANDS
42 #include "../fileio_func.h"
44 bool _ddc_fastforward = true;
45 #endif /* DEBUG_DUMP_COMMANDS */
46 
49 
53 
73 uint32 _sync_seed_1;
74 #ifdef NETWORK_SEND_DOUBLE_SEED
75 uint32 _sync_seed_2;
76 #endif
77 uint32 _sync_frame;
83 
84 /* Check whether NETWORK_NUM_LANDSCAPES is still in sync with NUM_LANDSCAPE */
85 assert_compile((int)NETWORK_NUM_LANDSCAPES == (int)NUM_LANDSCAPE);
87 
91 
94 
95 /* Some externs / forwards */
96 extern void StateGameLoop();
97 
103 {
104  NetworkClientSocket *cs;
105  FOR_ALL_CLIENT_SOCKETS(cs) return true;
106 
107  return false;
108 }
109 
114 {
115  /* Delete the chat window, if you were chatting with this client. */
117 }
118 
125 {
126  NetworkClientInfo *ci;
127 
129  if (ci->client_id == client_id) return ci;
130  }
131 
132  return nullptr;
133 }
134 
141 {
142  NetworkClientSocket *cs;
143 
145  if (cs->client_id == client_id) return cs;
146  }
147 
148  return nullptr;
149 }
150 
151 byte NetworkSpectatorCount()
152 {
153  const NetworkClientInfo *ci;
154  byte count = 0;
155 
157  if (ci->client_playas == COMPANY_SPECTATOR) count++;
158  }
159 
160  /* Don't count a dedicated server as spectator */
161  if (_network_dedicated) count--;
162 
163  return count;
164 }
165 
172 const char *NetworkChangeCompanyPassword(CompanyID company_id, const char *password)
173 {
174  if (strcmp(password, "*") == 0) password = "";
175 
176  if (_network_server) {
177  NetworkServerSetCompanyPassword(company_id, password, false);
178  } else {
180  }
181 
182  return password;
183 }
184 
192 const char *GenerateCompanyPasswordHash(const char *password, const char *password_server_id, uint32 password_game_seed)
193 {
194  if (StrEmpty(password)) return password;
195 
196  char salted_password[NETWORK_SERVER_ID_LENGTH];
197 
198  memset(salted_password, 0, sizeof(salted_password));
199  seprintf(salted_password, lastof(salted_password), "%s", password);
200  /* Add the game seed and the server's ID as the salt. */
201  for (uint i = 0; i < NETWORK_SERVER_ID_LENGTH - 1; i++) {
202  salted_password[i] ^= password_server_id[i] ^ (password_game_seed >> (i % 32));
203  }
204 
205  Md5 checksum;
206  uint8 digest[16];
207  static char hashed_password[NETWORK_SERVER_ID_LENGTH];
208 
209  /* Generate the MD5 hash */
210  checksum.Append(salted_password, sizeof(salted_password) - 1);
211  checksum.Finish(digest);
212 
213  for (int di = 0; di < 16; di++) seprintf(hashed_password + di * 2, lastof(hashed_password), "%02x", digest[di]);
214 
215  return hashed_password;
216 }
217 
224 {
225  return HasBit(_network_company_passworded, company_id);
226 }
227 
228 /* This puts a text-message to the console, or in the future, the chat-box,
229  * (to keep it all a bit more general)
230  * If 'self_send' is true, this is the client who is sending the message */
231 void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, const char *name, const char *str, int64 data)
232 {
233  StringID strid;
234  switch (action) {
235  case NETWORK_ACTION_SERVER_MESSAGE:
236  /* Ignore invalid messages */
237  strid = STR_NETWORK_SERVER_MESSAGE;
238  colour = CC_DEFAULT;
239  break;
240  case NETWORK_ACTION_COMPANY_SPECTATOR:
241  colour = CC_DEFAULT;
242  strid = STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE;
243  break;
244  case NETWORK_ACTION_COMPANY_JOIN:
245  colour = CC_DEFAULT;
246  strid = STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN;
247  break;
248  case NETWORK_ACTION_COMPANY_NEW:
249  colour = CC_DEFAULT;
250  strid = STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW;
251  break;
252  case NETWORK_ACTION_JOIN:
253  /* Show the Client ID for the server but not for the client. */
254  strid = _network_server ? STR_NETWORK_MESSAGE_CLIENT_JOINED_ID : STR_NETWORK_MESSAGE_CLIENT_JOINED;
255  break;
256  case NETWORK_ACTION_LEAVE: strid = STR_NETWORK_MESSAGE_CLIENT_LEFT; break;
257  case NETWORK_ACTION_NAME_CHANGE: strid = STR_NETWORK_MESSAGE_NAME_CHANGE; break;
258  case NETWORK_ACTION_GIVE_MONEY: strid = self_send ? STR_NETWORK_MESSAGE_GAVE_MONEY_AWAY : STR_NETWORK_MESSAGE_GIVE_MONEY; break;
259  case NETWORK_ACTION_CHAT_COMPANY: strid = self_send ? STR_NETWORK_CHAT_TO_COMPANY : STR_NETWORK_CHAT_COMPANY; break;
260  case NETWORK_ACTION_CHAT_CLIENT: strid = self_send ? STR_NETWORK_CHAT_TO_CLIENT : STR_NETWORK_CHAT_CLIENT; break;
261  default: strid = STR_NETWORK_CHAT_ALL; break;
262  }
263 
264  char message[1024];
265  SetDParamStr(0, name);
266  SetDParamStr(1, str);
267  SetDParam(2, data);
268 
269  /* All of these strings start with "***". These characters are interpreted as both left-to-right and
270  * right-to-left characters depending on the context. As the next text might be an user's name, the
271  * user name's characters will influence the direction of the "***" instead of the language setting
272  * of the game. Manually set the direction of the "***" by inserting a text-direction marker. */
273  char *msg_ptr = message + Utf8Encode(message, _current_text_dir == TD_LTR ? CHAR_TD_LRM : CHAR_TD_RLM);
274  GetString(msg_ptr, strid, lastof(message));
275 
276  DEBUG(desync, 1, "msg: %08x; %02x; %s", _date, _date_fract, message);
277  IConsolePrintF(colour, "%s", message);
279 }
280 
281 /* Calculate the frame-lag of a client */
282 uint NetworkCalculateLag(const NetworkClientSocket *cs)
283 {
284  int lag = cs->last_frame_server - cs->last_frame;
285  /* This client has missed his ACK packet after 1 DAY_TICKS..
286  * so we increase his lag for every frame that passes!
287  * The packet can be out by a max of _net_frame_freq */
288  if (cs->last_frame_server + DAY_TICKS + _settings_client.network.frame_freq < _frame_counter) {
289  lag += _frame_counter - (cs->last_frame_server + DAY_TICKS + _settings_client.network.frame_freq);
290  }
291  return lag;
292 }
293 
294 
295 /* There was a non-recoverable error, drop back to the main menu with a nice
296  * error */
297 void NetworkError(StringID error_string)
298 {
301 }
302 
309 {
310  /* List of possible network errors, used by
311  * PACKET_SERVER_ERROR and PACKET_CLIENT_ERROR */
312  static const StringID network_error_strings[] = {
313  STR_NETWORK_ERROR_CLIENT_GENERAL,
314  STR_NETWORK_ERROR_CLIENT_DESYNC,
315  STR_NETWORK_ERROR_CLIENT_SAVEGAME,
316  STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST,
317  STR_NETWORK_ERROR_CLIENT_PROTOCOL_ERROR,
318  STR_NETWORK_ERROR_CLIENT_NEWGRF_MISMATCH,
319  STR_NETWORK_ERROR_CLIENT_NOT_AUTHORIZED,
320  STR_NETWORK_ERROR_CLIENT_NOT_EXPECTED,
321  STR_NETWORK_ERROR_CLIENT_WRONG_REVISION,
322  STR_NETWORK_ERROR_CLIENT_NAME_IN_USE,
323  STR_NETWORK_ERROR_CLIENT_WRONG_PASSWORD,
324  STR_NETWORK_ERROR_CLIENT_COMPANY_MISMATCH,
325  STR_NETWORK_ERROR_CLIENT_KICKED,
326  STR_NETWORK_ERROR_CLIENT_CHEATER,
327  STR_NETWORK_ERROR_CLIENT_SERVER_FULL,
328  STR_NETWORK_ERROR_CLIENT_TOO_MANY_COMMANDS,
329  STR_NETWORK_ERROR_CLIENT_TIMEOUT_PASSWORD,
330  STR_NETWORK_ERROR_CLIENT_TIMEOUT_COMPUTER,
331  STR_NETWORK_ERROR_CLIENT_TIMEOUT_MAP,
332  STR_NETWORK_ERROR_CLIENT_TIMEOUT_JOIN,
333  };
334  assert_compile(lengthof(network_error_strings) == NETWORK_ERROR_END);
335 
336  if (err >= (ptrdiff_t)lengthof(network_error_strings)) err = NETWORK_ERROR_GENERAL;
337 
338  return network_error_strings[err];
339 }
340 
346 void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode)
347 {
348  if (!_networking) return;
349 
350  switch (changed_mode) {
351  case PM_PAUSED_NORMAL:
352  case PM_PAUSED_JOIN:
355  bool changed = ((_pause_mode == PM_UNPAUSED) != (prev_mode == PM_UNPAUSED));
356  bool paused = (_pause_mode != PM_UNPAUSED);
357  if (!paused && !changed) return;
358 
359  StringID str;
360  if (!changed) {
361  int i = -1;
362 
363  if ((_pause_mode & PM_PAUSED_NORMAL) != PM_UNPAUSED) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_MANUAL);
364  if ((_pause_mode & PM_PAUSED_JOIN) != PM_UNPAUSED) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_CONNECTING_CLIENTS);
365  if ((_pause_mode & PM_PAUSED_GAME_SCRIPT) != PM_UNPAUSED) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT);
366  if ((_pause_mode & PM_PAUSED_ACTIVE_CLIENTS) != PM_UNPAUSED) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_NOT_ENOUGH_PLAYERS);
367  str = STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_1 + i;
368  } else {
369  switch (changed_mode) {
370  case PM_PAUSED_NORMAL: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_MANUAL); break;
371  case PM_PAUSED_JOIN: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_CONNECTING_CLIENTS); break;
372  case PM_PAUSED_GAME_SCRIPT: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT); break;
373  case PM_PAUSED_ACTIVE_CLIENTS: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_NOT_ENOUGH_PLAYERS); break;
374  default: NOT_REACHED();
375  }
376  str = paused ? STR_NETWORK_SERVER_MESSAGE_GAME_PAUSED : STR_NETWORK_SERVER_MESSAGE_GAME_UNPAUSED;
377  }
378 
379  char buffer[DRAW_STRING_BUFFER];
380  GetString(buffer, str, lastof(buffer));
381  NetworkTextMessage(NETWORK_ACTION_SERVER_MESSAGE, CC_DEFAULT, false, nullptr, buffer);
382  break;
383  }
384 
385  default:
386  return;
387  }
388 }
389 
390 
399 static void CheckPauseHelper(bool pause, PauseMode pm)
400 {
401  if (pause == ((_pause_mode & pm) != PM_UNPAUSED)) return;
402 
403  DoCommandP(0, pm, pause ? 1 : 0, CMD_PAUSE);
404 }
405 
412 {
413  const NetworkClientSocket *cs;
414  uint count = 0;
415 
417  if (cs->status != NetworkClientSocket::STATUS_ACTIVE) continue;
418  if (!Company::IsValidID(cs->GetInfo()->client_playas)) continue;
419  count++;
420  }
421 
422  return count;
423 }
424 
429 {
431  !_network_dedicated ||
433  return;
434  }
436 }
437 
443 {
444  const NetworkClientSocket *cs;
446  if (cs->status >= NetworkClientSocket::STATUS_AUTHORIZED && cs->status < NetworkClientSocket::STATUS_ACTIVE) return true;
447  }
448 
449  return false;
450 }
451 
455 static void CheckPauseOnJoin()
456 {
459  return;
460  }
461  CheckPauseHelper(NetworkHasJoiningClient(), PM_PAUSED_JOIN);
462 }
463 
472 void ParseConnectionString(const char **company, const char **port, char *connection_string)
473 {
474  bool ipv6 = (strchr(connection_string, ':') != strrchr(connection_string, ':'));
475  char *p;
476  for (p = connection_string; *p != '\0'; p++) {
477  switch (*p) {
478  case '[':
479  ipv6 = true;
480  break;
481 
482  case ']':
483  ipv6 = false;
484  break;
485 
486  case '#':
487  *company = p + 1;
488  *p = '\0';
489  break;
490 
491  case ':':
492  if (ipv6) break;
493  *port = p + 1;
494  *p = '\0';
495  break;
496  }
497  }
498 }
499 
505 /* static */ void ServerNetworkGameSocketHandler::AcceptConnection(SOCKET s, const NetworkAddress &address)
506 {
507  /* Register the login */
508  _network_clients_connected++;
509 
512  cs->client_address = address; // Save the IP of the client
513 }
514 
519 static void InitializeNetworkPools(bool close_admins = true)
520 {
521  PoolBase::Clean(PT_NCLIENT | (close_admins ? PT_NADMIN : PT_NONE));
522 }
523 
528 void NetworkClose(bool close_admins)
529 {
530  if (_network_server) {
531  if (close_admins) {
534  as->CloseConnection(true);
535  }
536  }
537 
538  NetworkClientSocket *cs;
540  cs->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
541  }
544  } else if (MyClient::my_client != nullptr) {
547  }
548 
550 
551  _networking = false;
552  _network_server = false;
553 
555 
557  _network_company_states = nullptr;
558 
559  InitializeNetworkPools(close_admins);
560 }
561 
562 /* Initializes the network (cleans sockets and stuff) */
563 static void NetworkInitialize(bool close_admins = true)
564 {
565  InitializeNetworkPools(close_admins);
567 
568  _sync_frame = 0;
569  _network_first_time = true;
570 
571  _network_reconnect = 0;
572 }
573 
576 public:
577  TCPQueryConnecter(const NetworkAddress &address) : TCPConnecter(address) {}
578 
579  void OnFailure() override
580  {
582  }
583 
584  void OnConnect(SOCKET s) override
585  {
586  _networking = true;
589  }
590 };
591 
592 /* Query a server to fetch his game-info
593  * If game_info is true, only the gameinfo is fetched,
594  * else only the client_info is fetched */
595 void NetworkTCPQueryServer(NetworkAddress address)
596 {
597  if (!_network_available) return;
598 
600  NetworkInitialize();
601 
602  new TCPQueryConnecter(address);
603 }
604 
605 /* Validates an address entered as a string and adds the server to
606  * the list. If you use this function, the games will be marked
607  * as manually added. */
608 void NetworkAddServer(const char *b)
609 {
610  if (*b != '\0') {
611  const char *port = nullptr;
612  const char *company = nullptr;
613  char host[NETWORK_HOSTNAME_LENGTH];
614  uint16 rport;
615 
616  strecpy(host, b, lastof(host));
617 
619  rport = NETWORK_DEFAULT_PORT;
620 
621  ParseConnectionString(&company, &port, host);
622  if (port != nullptr) rport = atoi(port);
623 
624  NetworkUDPQueryServer(NetworkAddress(host, rport), true);
625  }
626 }
627 
633 void GetBindAddresses(NetworkAddressList *addresses, uint16 port)
634 {
635  for (const auto &iter : _network_bind_list) {
636  addresses->emplace_back(iter.c_str(), port);
637  }
638 
639  /* No address, so bind to everything. */
640  if (addresses->size() == 0) {
641  addresses->emplace_back("", port);
642  }
643 }
644 
645 /* Generates the list of manually added hosts from NetworkGameList and
646  * dumps them into the array _network_host_list. This array is needed
647  * by the function that generates the config file. */
648 void NetworkRebuildHostList()
649 {
650  _network_host_list.clear();
651 
652  for (NetworkGameList *item = _network_game_list; item != nullptr; item = item->next) {
653  if (item->manually) _network_host_list.emplace_back(item->address.GetAddressAsString(false));
654  }
655 }
656 
659 public:
660  TCPClientConnecter(const NetworkAddress &address) : TCPConnecter(address) {}
661 
662  void OnFailure() override
663  {
664  NetworkError(STR_NETWORK_ERROR_NOCONNECTION);
665  }
666 
667  void OnConnect(SOCKET s) override
668  {
669  _networking = true;
671  IConsoleCmdExec("exec scripts/on_client.scr 0");
673  }
674 };
675 
676 
677 /* Used by clients, to connect to a server */
678 void NetworkClientConnectGame(NetworkAddress address, CompanyID join_as, const char *join_server_password, const char *join_company_password)
679 {
680  if (!_network_available) return;
681 
682  if (address.GetPort() == 0) return;
683 
686  _network_join_as = join_as;
687  _network_join_server_password = join_server_password;
688  _network_join_company_password = join_company_password;
689 
691  NetworkInitialize();
692 
693  _network_join_status = NETWORK_JOIN_STATUS_CONNECTING;
694  ShowJoinStatusWindow();
695 
696  new TCPClientConnecter(address);
697 }
698 
699 static void NetworkInitGameInfo()
700 {
703  }
704 
705  /* The server is a client too */
706  _network_game_info.clients_on = _network_dedicated ? 0 : 1;
707 
708  /* There should be always space for the server. */
711  ci->client_playas = _network_dedicated ? COMPANY_SPECTATOR : COMPANY_FIRST;
712 
714 }
715 
716 bool NetworkServerStart()
717 {
718  if (!_network_available) return false;
719 
720  /* Call the pre-scripts */
721  IConsoleCmdExec("exec scripts/pre_server.scr 0");
722  if (_network_dedicated) IConsoleCmdExec("exec scripts/pre_dedicated.scr 0");
723 
724  NetworkDisconnect(false, false);
725  NetworkInitialize(false);
726  DEBUG(net, 1, "starting listeners for clients");
728 
729  /* Only listen for admins when the password isn't empty. */
731  DEBUG(net, 1, "starting listeners for admins");
733  }
734 
735  /* Try to start UDP-server */
736  DEBUG(net, 1, "starting listeners for incoming server queries");
737  _network_udp_server = _udp_server_socket->Listen();
738 
739  _network_company_states = CallocT<NetworkCompanyState>(MAX_COMPANIES);
740  _network_server = true;
741  _networking = true;
742  _frame_counter = 0;
743  _frame_counter_server = 0;
744  _frame_counter_max = 0;
745  _last_sync_frame = 0;
746  _network_own_client_id = CLIENT_ID_SERVER;
747 
748  _network_clients_connected = 0;
749  _network_company_passworded = 0;
750 
751  NetworkInitGameInfo();
752 
753  /* execute server initialization script */
754  IConsoleCmdExec("exec scripts/on_server.scr 0");
755  /* if the server is dedicated ... add some other script */
756  if (_network_dedicated) IConsoleCmdExec("exec scripts/on_dedicated.scr 0");
757 
758  /* Try to register us to the master server */
759  _network_need_advertise = true;
761 
762  /* welcome possibly still connected admins - this can only happen on a dedicated server. */
763  if (_network_dedicated) ServerNetworkAdminSocketHandler::WelcomeAll();
764 
765  return true;
766 }
767 
768 /* The server is rebooting...
769  * The only difference with NetworkDisconnect, is the packets that is sent */
770 void NetworkReboot()
771 {
772  if (_network_server) {
773  NetworkClientSocket *cs;
775  cs->SendNewGame();
776  cs->SendPackets();
777  }
778 
781  as->SendNewGame();
782  as->SendPackets();
783  }
784  }
785 
786  /* For non-dedicated servers we have to kick the admins as we are not
787  * certain that we will end up in a new network game. */
788  NetworkClose(!_network_dedicated);
789 }
790 
796 void NetworkDisconnect(bool blocking, bool close_admins)
797 {
798  if (_network_server) {
799  NetworkClientSocket *cs;
801  cs->SendShutdown();
802  cs->SendPackets();
803  }
804 
805  if (close_admins) {
808  as->SendShutdown();
809  as->SendPackets();
810  }
811  }
812  }
813 
815 
817 
818  NetworkClose(close_admins);
819 
820  /* Reinitialize the UDP stack, i.e. close all existing connections. */
822 }
823 
828 static bool NetworkReceive()
829 {
830  if (_network_server) {
833  } else {
835  }
836 }
837 
838 /* This sends all buffered commands (if possible) */
839 static void NetworkSend()
840 {
841  if (_network_server) {
844  } else {
846  }
847 }
848 
855 {
859 
861 }
862 
863 /* The main loop called from ttd.c
864  * Here we also have to do StateGameLoop if needed! */
865 void NetworkGameLoop()
866 {
867  if (!_networking) return;
868 
869  if (!NetworkReceive()) return;
870 
871  if (_network_server) {
872  /* Log the sync state to check for in-syncedness of replays. */
873  if (_date_fract == 0) {
874  /* We don't want to log multiple times if paused. */
875  static Date last_log;
876  if (last_log != _date) {
877  DEBUG(desync, 1, "sync: %08x; %02x; %08x; %08x", _date, _date_fract, _random.state[0], _random.state[1]);
878  last_log = _date;
879  }
880  }
881 
882 #ifdef DEBUG_DUMP_COMMANDS
883  /* Loading of the debug commands from -ddesync>=1 */
884  static FILE *f = FioFOpenFile("commands.log", "rb", SAVE_DIR);
885  static Date next_date = 0;
886  static uint32 next_date_fract;
887  static CommandPacket *cp = nullptr;
888  static bool check_sync_state = false;
889  static uint32 sync_state[2];
890  if (f == nullptr && next_date == 0) {
891  DEBUG(net, 0, "Cannot open commands.log");
892  next_date = 1;
893  }
894 
895  while (f != nullptr && !feof(f)) {
896  if (_date == next_date && _date_fract == next_date_fract) {
897  if (cp != nullptr) {
898  NetworkSendCommand(cp->tile, cp->p1, cp->p2, cp->cmd & ~CMD_FLAGS_MASK, nullptr, cp->text, cp->company);
899  DEBUG(net, 0, "injecting: %08x; %02x; %02x; %06x; %08x; %08x; %08x; \"%s\" (%s)", _date, _date_fract, (int)_current_company, cp->tile, cp->p1, cp->p2, cp->cmd, cp->text, GetCommandName(cp->cmd));
900  free(cp);
901  cp = nullptr;
902  }
903  if (check_sync_state) {
904  if (sync_state[0] == _random.state[0] && sync_state[1] == _random.state[1]) {
905  DEBUG(net, 0, "sync check: %08x; %02x; match", _date, _date_fract);
906  } else {
907  DEBUG(net, 0, "sync check: %08x; %02x; mismatch expected {%08x, %08x}, got {%08x, %08x}",
908  _date, _date_fract, sync_state[0], sync_state[1], _random.state[0], _random.state[1]);
909  NOT_REACHED();
910  }
911  check_sync_state = false;
912  }
913  }
914 
915  if (cp != nullptr || check_sync_state) break;
916 
917  char buff[4096];
918  if (fgets(buff, lengthof(buff), f) == nullptr) break;
919 
920  char *p = buff;
921  /* Ignore the "[date time] " part of the message */
922  if (*p == '[') {
923  p = strchr(p, ']');
924  if (p == nullptr) break;
925  p += 2;
926  }
927 
928  if (strncmp(p, "cmd: ", 5) == 0
929 #ifdef DEBUG_FAILED_DUMP_COMMANDS
930  || strncmp(p, "cmdf: ", 6) == 0
931 #endif
932  ) {
933  p += 5;
934  if (*p == ' ') p++;
935  cp = CallocT<CommandPacket>(1);
936  int company;
937  int ret = sscanf(p, "%x; %x; %x; %x; %x; %x; %x; \"%[^\"]\"", &next_date, &next_date_fract, &company, &cp->tile, &cp->p1, &cp->p2, &cp->cmd, cp->text);
938  /* There are 8 pieces of data to read, however the last is a
939  * string that might or might not exist. Ignore it if that
940  * string misses because in 99% of the time it's not used. */
941  assert(ret == 8 || ret == 7);
942  cp->company = (CompanyID)company;
943  } else if (strncmp(p, "join: ", 6) == 0) {
944  /* Manually insert a pause when joining; this way the client can join at the exact right time. */
945  int ret = sscanf(p + 6, "%x; %x", &next_date, &next_date_fract);
946  assert(ret == 2);
947  DEBUG(net, 0, "injecting pause for join at %08x:%02x; please join when paused", next_date, next_date_fract);
948  cp = CallocT<CommandPacket>(1);
950  cp->cmd = CMD_PAUSE;
951  cp->p1 = PM_PAUSED_NORMAL;
952  cp->p2 = 1;
953  _ddc_fastforward = false;
954  } else if (strncmp(p, "sync: ", 6) == 0) {
955  int ret = sscanf(p + 6, "%x; %x; %x; %x", &next_date, &next_date_fract, &sync_state[0], &sync_state[1]);
956  assert(ret == 4);
957  check_sync_state = true;
958  } else if (strncmp(p, "msg: ", 5) == 0 || strncmp(p, "client: ", 8) == 0 ||
959  strncmp(p, "load: ", 6) == 0 || strncmp(p, "save: ", 6) == 0) {
960  /* A message that is not very important to the log playback, but part of the log. */
961 #ifndef DEBUG_FAILED_DUMP_COMMANDS
962  } else if (strncmp(p, "cmdf: ", 6) == 0) {
963  DEBUG(net, 0, "Skipping replay of failed command: %s", p + 6);
964 #endif
965  } else {
966  /* Can't parse a line; what's wrong here? */
967  DEBUG(net, 0, "trying to parse: %s", p);
968  NOT_REACHED();
969  }
970  }
971  if (f != nullptr && feof(f)) {
972  DEBUG(net, 0, "End of commands.log");
973  fclose(f);
974  f = nullptr;
975  }
976 #endif /* DEBUG_DUMP_COMMANDS */
977  if (_frame_counter >= _frame_counter_max) {
978  /* Only check for active clients just before we're going to send out
979  * the commands so we don't send multiple pause/unpause commands when
980  * the frame_freq is more than 1 tick. Same with distributing commands. */
984  }
985 
986  bool send_frame = false;
987 
988  /* We first increase the _frame_counter */
989  _frame_counter++;
990  /* Update max-frame-counter */
991  if (_frame_counter > _frame_counter_max) {
992  _frame_counter_max = _frame_counter + _settings_client.network.frame_freq;
993  send_frame = true;
994  }
995 
997 
998  /* Then we make the frame */
999  StateGameLoop();
1000 
1001  _sync_seed_1 = _random.state[0];
1002 #ifdef NETWORK_SEND_DOUBLE_SEED
1003  _sync_seed_2 = _random.state[1];
1004 #endif
1005 
1006  NetworkServer_Tick(send_frame);
1007  } else {
1008  /* Client */
1009 
1010  /* Make sure we are at the frame were the server is (quick-frames) */
1011  if (_frame_counter_server > _frame_counter) {
1012  /* Run a number of frames; when things go bad, get out. */
1013  while (_frame_counter_server > _frame_counter) {
1015  }
1016  } else {
1017  /* Else, keep on going till _frame_counter_max */
1018  if (_frame_counter_max > _frame_counter) {
1019  /* Run one frame; if things went bad, get out. */
1021  }
1022  }
1023  }
1024 
1025  NetworkSend();
1026 }
1027 
1028 static void NetworkGenerateServerId()
1029 {
1030  Md5 checksum;
1031  uint8 digest[16];
1032  char hex_output[16 * 2 + 1];
1033  char coding_string[NETWORK_NAME_LENGTH];
1034  int di;
1035 
1036  seprintf(coding_string, lastof(coding_string), "%d%s", (uint)Random(), "OpenTTD Server ID");
1037 
1038  /* Generate the MD5 hash */
1039  checksum.Append((const uint8*)coding_string, strlen(coding_string));
1040  checksum.Finish(digest);
1041 
1042  for (di = 0; di < 16; ++di) {
1043  seprintf(hex_output + di * 2, lastof(hex_output), "%02x", digest[di]);
1044  }
1045 
1046  /* _settings_client.network.network_id is our id */
1048 }
1049 
1050 void NetworkStartDebugLog(NetworkAddress address)
1051 {
1052  extern SOCKET _debug_socket; // Comes from debug.c
1053 
1054  DEBUG(net, 0, "Redirecting DEBUG() to %s:%d", address.GetHostname(), address.GetPort());
1055 
1056  SOCKET s = address.Connect();
1057  if (s == INVALID_SOCKET) {
1058  DEBUG(net, 0, "Failed to open socket for redirection DEBUG()");
1059  return;
1060  }
1061 
1062  _debug_socket = s;
1063 
1064  DEBUG(net, 0, "DEBUG() is now redirected");
1065 }
1066 
1069 {
1070  DEBUG(net, 3, "[core] starting network...");
1071 
1072  /* Network is available */
1073  _network_available = NetworkCoreInitialize();
1074  _network_dedicated = false;
1075  _network_need_advertise = true;
1076  _network_advertise_retries = 0;
1077 
1078  /* Generate an server id when there is none yet */
1079  if (StrEmpty(_settings_client.network.network_id)) NetworkGenerateServerId();
1080 
1081  memset(&_network_game_info, 0, sizeof(_network_game_info));
1082 
1083  NetworkInitialize();
1084  DEBUG(net, 3, "[core] network online, multiplayer available");
1085  NetworkFindBroadcastIPs(&_broadcast_list);
1086 }
1087 
1090 {
1091  NetworkDisconnect(true);
1092  NetworkUDPClose();
1093 
1094  DEBUG(net, 3, "[core] shutting down network");
1095 
1096  _network_available = false;
1097 
1099 }
1100 
1105 static const uint GITHASH_SUFFIX_LEN = 12;
1106 
1112 {
1113  /* This will be allocated on heap and never free'd, but only once so not a "real" leak. */
1114  static char *network_revision = nullptr;
1115 
1116  if (!network_revision) {
1117  /* Start by taking a chance on the full revision string. */
1118  network_revision = stredup(_openttd_revision);
1119  /* Ensure it's not longer than the packet buffer length. */
1120  if (strlen(network_revision) >= NETWORK_REVISION_LENGTH) network_revision[NETWORK_REVISION_LENGTH - 1] = '\0';
1121 
1122  /* Tag names are not mangled further. */
1123  if (_openttd_revision_tagged) {
1124  DEBUG(net, 1, "Network revision name is '%s'", network_revision);
1125  return network_revision;
1126  }
1127 
1128  /* Prepare a prefix of the git hash.
1129  * Size is length + 1 for terminator, +2 for -g prefix. */
1130  assert(_openttd_revision_modified < 3);
1131  char githash_suffix[GITHASH_SUFFIX_LEN + 1] = "-";
1132  githash_suffix[1] = "gum"[_openttd_revision_modified];
1133  for (uint i = 2; i < GITHASH_SUFFIX_LEN; i++) {
1134  githash_suffix[i] = _openttd_revision_hash[i-2];
1135  }
1136 
1137  /* Where did the hash start in the original string?
1138  * Overwrite from that position, unless that would go past end of packet buffer length. */
1139  ptrdiff_t hashofs = strrchr(_openttd_revision, '-') - _openttd_revision;
1140  if (hashofs + strlen(githash_suffix) + 1 > NETWORK_REVISION_LENGTH) hashofs = strlen(network_revision) - strlen(githash_suffix);
1141  /* Replace the git hash in revision string. */
1142  strecpy(network_revision + hashofs, githash_suffix, network_revision + NETWORK_REVISION_LENGTH);
1143  assert(strlen(network_revision) < NETWORK_REVISION_LENGTH); // strlen does not include terminator, constant does, hence strictly less than
1144  DEBUG(net, 1, "Network revision name is '%s'", network_revision);
1145  }
1146 
1147  return network_revision;
1148 }
1149 
1150 static const char *ExtractNetworkRevisionHash(const char *revstr)
1151 {
1152  return strrchr(revstr, '-');
1153 }
1154 
1160 bool IsNetworkCompatibleVersion(const char *other)
1161 {
1162  if (strncmp(GetNetworkRevisionString(), other, NETWORK_REVISION_LENGTH - 1) == 0) return true;
1163 
1164  /* If this version is tagged, then the revision string must be a complete match,
1165  * since there is no git hash suffix in it.
1166  * This is needed to avoid situations like "1.9.0-beta1" comparing equal to "2.0.0-beta1". */
1167  if (_openttd_revision_tagged) return false;
1168 
1169  const char *hash1 = ExtractNetworkRevisionHash(GetNetworkRevisionString());
1170  const char *hash2 = ExtractNetworkRevisionHash(other);
1171  return hash1 && hash2 && (strncmp(hash1, hash2, GITHASH_SUFFIX_LEN) == 0);
1172 }
Owner
Enum for all companies/owners.
Definition: company_type.h:20
void NetworkServer_Tick(bool send_frame)
This is called every tick if this is a _network_server.
A game paused for &#39;min_active_clients&#39;.
Definition: openttd.h:63
void OnFailure() override
Callback for when the connection attempt failed.
Definition: network.cpp:579
static bool NetworkReceive()
Receives something from the network.
Definition: network.cpp:828
void ParseConnectionString(const char **company, const char **port, char *connection_string)
Converts a string to ip/port/company Format: IP:port::company.
Definition: network.cpp:472
bool _networking
are we in networking mode?
Definition: network.cpp:54
static const WChar CHAR_TD_LRM
The next character acts like a left-to-right character.
Definition: string_type.h:41
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.
const char * GetCommandName(uint32 cmd)
Definition: command.cpp:400
bool IsNetworkCompatibleVersion(const char *other)
Checks whether the given version string is compatible with our version.
Definition: network.cpp:1160
#define FOR_ALL_ACTIVE_ADMIN_SOCKETS(var)
Iterate over all the active sockets.
Container for all information known about a client.
Definition: network_base.h:25
uint32 _sync_seed_1
Seed to compare during sync checks.
Definition: network.cpp:73
bool server_advertise
advertise the server to the masterserver
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3199
static void WelcomeAll()
Send a Welcome packet to all connected admins.
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...
void GetBindAddresses(NetworkAddressList *addresses, uint16 port)
Get the addresses to bind to.
Definition: network.cpp:633
static void KillAll()
Kill all connection attempts.
Definition: tcp_connect.cpp:94
uint16 last_port
port of the last joined server
Client list; Window numbers:
Definition: window_type.h:474
bool NetworkCoreInitialize()
Initializes the network core (as that is needed for some platforms.
Definition: core.cpp:26
"Helper" class for creating TCP connections in a non-blocking manner
Definition: tcp.h:64
char server_name[NETWORK_NAME_LENGTH]
name of the server
NetworkUDPSocketHandler * _udp_client_socket
udp client socket
Definition: network_udp.cpp:48
const char * _network_join_server_password
Login password from -p argument.
The game information that is not generated on-the-fly and has to be sent to the clients.
Definition: game.h:26
Switch to game intro menu.
Definition: openttd.h:32
const char * _network_join_company_password
Company password from -P argument.
NetworkGameList * next
Next pointer to make a linked game list.
~NetworkClientInfo()
Basically a client is leaving us right now.
Definition: network.cpp:113
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 NetworkExecuteLocalCommandQueue()
Execute all commands on the local command queue that ought to be executed this frame.
NetworkRecvStatus CloseConnection(bool error=true) override
Close the current connection; for TCP this will be mostly equivalent to Close(), but for UDP it just ...
Definition: tcp_admin.cpp:43
NetworkErrorCode
The error codes we send around in the protocols.
Definition: network_type.h:102
NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override
Close the network connection due to the given status.
ClientID client_id
Client identifier (same as ClientState->client_id)
Definition: network_base.h:26
NetworkJoinStatus _network_join_status
The status of joining.
uint16 _network_udp_broadcast
Timeout for the UDP broadcasts.
Definition: network.cpp:80
uint32 p2
parameter p2.
Definition: command_type.h:480
Sending and receiving UDP messages.
Client part of the network protocol.
static void Send()
Send the packets for the server sockets.
void SendReceive()
Check whether we received/can send some data from/to the content server and when that&#39;s the case hand...
#define _ddc_fastforward
Helper variable to make the dedicated server go fast until the (first) join.
Wrapper for (un)resolved network addresses; there&#39;s no reason to transform a numeric IP to a string a...
Definition: address.h:29
ClientID _redirect_console_to_client
If not invalid, redirect the console output to a client.
Definition: network.cpp:62
static void Clean(PoolType)
Clean all pools of given type.
Definition: pool_func.cpp:32
void NetworkStartUp()
This tries to launch the network for a given OS.
Definition: network.cpp:1068
void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x=0, int y=0, const GRFFile *textref_stack_grffile=nullptr, uint textref_stack_size=0, const uint32 *textref_stack=nullptr)
Display an error message in a window.
Definition: error_gui.cpp:382
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
static const int DRAW_STRING_BUFFER
Size of the buffer used for drawing strings.
Definition: gfx_func.h:85
void NetworkFindBroadcastIPs(NetworkAddressList *broadcast)
Find the IPv4 broadcast addresses; IPv6 uses a completely different strategy for broadcasting.
Definition: host.cpp:196
Send message/notice to only a certain client (Private)
Definition: network_type.h:83
Base socket handler for all UDP sockets.
Definition: udp.h:48
#define lastof(x)
Get the last element of an fixed size array.
Definition: depend.cpp:50
static const TextColour CC_DEFAULT
Default colour of the console.
Definition: console_type.h:25
bool NetworkCompanyIsPassworded(CompanyID company_id)
Check if the company we want to join requires a password.
Definition: network.cpp:223
Base core network types and some helper functions to access them.
Structure with information shown in the game list (GUI)
void NetworkUDPQueryServer(NetworkAddress address, bool manually)
Query a specific server.
Definition: network_udp.cpp:80
Class for handling the client side of the game connection.
ClientID
&#39;Unique&#39; identifier to be given to clients
Definition: network_type.h:41
static void HTTPReceive()
Do the receiving for all HTTP connections.
Definition: tcp_http.cpp:297
NetworkClientInfoPool _networkclientinfo_pool("NetworkClientInfo")
The pool with client information.
uint32 _sync_frame
The frame to perform the sync check.
Definition: network.cpp:77
void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode)
Handle the pause mode change so we send the right messages to the chat.
Definition: network.cpp:346
char text[32 *MAX_CHAR_LENGTH]
possible text sent for name changes etc, in bytes including &#39;\0&#39;.
Definition: command_type.h:483
SendPacketsState SendPackets(bool closing_down=false)
Sends all the buffered packets out for this client.
Definition: tcp.cpp:97
bool _network_udp_server
Is the UDP server started?
Definition: network.cpp:79
void OnConnect(SOCKET s) override
Callback when the connection succeeded.
Definition: network.cpp:584
Class for handling the server side of the game connection.
void NetworkUDPAdvertise()
Register us to the master server This function checks if it needs to send an advertise.
StringID GetNetworkErrorMsg(NetworkErrorCode err)
Retrieve the string id of an internal error number.
Definition: network.cpp:308
bool _network_available
is network mode available?
Definition: network.cpp:56
bool _network_dedicated
are we a dedicated server?
Definition: network.cpp:57
Network client pools.
Definition: pool_type.hpp:22
assert_compile(NetworkClientInfoPool::MAX_SIZE==NetworkClientSocketPool::MAX_SIZE)
Make sure both pools have the same size.
static const size_t MAX_SIZE
Make template parameter accessible from outside.
Definition: pool_type.hpp:87
std::vector< NetworkAddress > NetworkAddressList
Type for a list of addresses.
Definition: address.h:20
Critical errors, the MessageBox is shown in all cases.
Definition: error.h:26
NetworkAddressList _broadcast_list
List of broadcast addresses.
Definition: network.cpp:72
void SetDParamStr(uint n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition: strings.cpp:281
void StateGameLoop()
State controlling game loop.
Definition: openttd.cpp:1335
NetworkSettings network
settings related to the network
static const int MAX_CHAR_LENGTH
Max. length of UTF-8 encoded unicode character.
Definition: strings_type.h:20
bool _is_network_server
Does this client wants to be a network-server?
Definition: network.cpp:58
CompanyID client_playas
As which company is this client playing (CompanyID)
Definition: network_base.h:29
mask for all command flags
Definition: command_type.h:379
DateFract _date_fract
Fractional part of the day.
Definition: date.cpp:29
NetworkAddress client_address
IP-address of the client (so he can be banned)
A normal unpaused game.
Definition: openttd.h:58
The client is spectating.
Definition: company_type.h:37
static uint NetworkCountActiveClients()
Counts the number of active clients connected.
Definition: network.cpp:411
char client_name[NETWORK_CLIENT_NAME_LENGTH]
Name of the client.
Definition: network_base.h:27
Chatbox; Window numbers:
Definition: window_type.h:493
Server part of the network protocol.
bool _network_need_advertise
Whether we need to advertise.
Definition: network.cpp:63
static ServerNetworkGameSocketHandler * GetByClientID(ClientID client_id)
Return the client state given it&#39;s client-identifier.
Definition: network.cpp:140
uint32 p1
parameter p1.
Definition: command_type.h:479
void IConsoleCmdExec(const char *cmdstr)
Execute a given command passed to us.
Definition: console.cpp:403
static void CheckCallbacks()
Check whether we need to call the callback, i.e.
Definition: tcp_connect.cpp:67
Non blocking connection create to query servers.
Definition: network.cpp:575
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:80
ClientID _network_own_client_id
Our client identifier.
Definition: network.cpp:61
FILE * FioFOpenFile(const char *filename, const char *mode, Subdirectory subdir, size_t *filesize)
Opens a OpenTTD file somewhere in a personal or global directory.
Definition: fileio.cpp:465
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:126
void NetworkCoreShutdown()
Shuts down the network core (as that is needed for some platforms.
Definition: core.cpp:46
void NetworkServerSetCompanyPassword(CompanyID company_id, const char *password, bool already_hashed)
Set/Reset a company password on the server end.
Resolving of hostnames/IPs.
static const uint MAX_LENGTH_COMPANY_NAME_CHARS
The maximum length of a company name in characters including &#39;\0&#39;.
Definition: company_type.h:42
static void InitializeNetworkPools(bool close_admins=true)
Resets the pools used for network clients, and the admin pool if needed.
Definition: network.cpp:519
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition: gfx_type.h:247
char connect_to_ip[NETWORK_HOSTNAME_LENGTH]
default for the "Add server" query
static void AcceptConnection(SOCKET s, const NetworkAddress &address)
Handle the accepting of a connection to the server.
Definition: network.cpp:505
NetworkCompanyState * _network_company_states
Statistics about some companies.
Definition: network.cpp:60
uint16 server_admin_port
port the server listens on for the admin network
NetworkRecvStatus SendNewGame()
Tell the admin we started a new game.
const char * GetNetworkRevisionString()
Get the network version string used by this build.
Definition: network.cpp:1111
uint8 _network_reconnect
Reconnect timeout.
Definition: network.cpp:64
static void CheckPauseHelper(bool pause, PauseMode pm)
Helper function for the pause checkers.
Definition: network.cpp:399
static ClientNetworkGameSocketHandler * my_client
This is us!
Base directory for all savegames.
Definition: fileio_type.h:112
void OnConnect(SOCKET s) override
Callback when the connection succeeded.
Definition: network.cpp:667
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
Definition: string.cpp:138
#define FOR_ALL_CLIENT_INFOS(var)
Iterate over all the clients.
Definition: network_base.h:53
const char * GetHostname()
Get the hostname; in case it wasn&#39;t given the IPv4 dotted representation is given.
Definition: address.cpp:24
byte clients_on
Current count of clients on server.
Definition: game.h:28
NetworkGameList * _network_game_list
Game list of this client.
A game normally paused.
Definition: openttd.h:59
static void CheckPauseOnJoin()
Check whether we should pause on join.
Definition: network.cpp:455
Part of the network protocol handling content distribution.
void NetworkShutDown()
This shuts the network down.
Definition: network.cpp:1089
bool DoCommandP(const CommandContainer *container, bool my_cmd)
Shortcut for the long DoCommandP when having a container with the data.
Definition: command.cpp:534
CompanyID company
company that is executing the command
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
NetworkServerGameInfo _network_game_info
Information about our game.
Definition: network.cpp:59
PauseMode _pause_mode
The current pause mode.
Definition: gfx.cpp:49
#define FOR_ALL_CLIENT_SOCKETS(var)
Iterate over all the sockets.
static const uint NETWORK_HOSTNAME_LENGTH
The maximum length of the host name, in bytes including &#39;\0&#39;.
Definition: config.h:44
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:18
Text is written left-to-right by default.
Definition: strings_type.h:25
PauseMode
Modes of pausing we&#39;ve got.
Definition: openttd.h:57
bool Listen()
Start listening on the given host and port.
Definition: udp.cpp:45
void NetworkClient_Connected()
Is called after a client is connected to the server.
static bool NetworkHasJoiningClient()
Checks whether there is a joining client.
Definition: network.cpp:442
void OnFailure() override
Callback for when the connection attempt failed.
Definition: network.cpp:662
Base class for all pools.
Definition: pool_type.hpp:83
The connection is &#39;just&#39; lost.
Definition: core.h:29
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:37
void NetworkUDPInitialize()
Initialize the whole UDP bit.
Network status window; Window numbers:
Definition: window_type.h:487
void NetworkFreeLocalCommandQueue()
Free the local command queues.
StringList _network_host_list
The servers we know.
Definition: network.cpp:66
uint16 server_port
port the server listens on
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don&#39;t get linker errors.
Definition: pool_func.hpp:226
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
Definition: window.cpp:1146
uint16 network_chat_timeout
timeout of chat messages in seconds
static NetworkRecvStatus SendCompanyInformationQuery()
Query the server for company information.
bool HasClients()
Return whether there is any client connected or trying to connect at all.
Definition: network.cpp:102
bool pause_on_join
pause the game when people join
SOCKET Connect()
Connect to the given address.
Definition: address.cpp:322
Network join status.
Definition: window_type.h:34
byte _network_clients_connected
The amount of clients connected.
Definition: network.cpp:93
static const uint16 NETWORK_DEFAULT_PORT
The default port of the game server (TCP & UDP)
Definition: config.h:31
char client_name[NETWORK_CLIENT_NAME_LENGTH]
name of the player (as client)
GUISettings gui
settings related to the GUI
uint32 _frame_counter
The current frame.
Definition: network.cpp:70
Non blocking connection create to actually connect to servers.
Definition: network.cpp:658
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:59
Randomizer _random
Random used in the game state calculations.
Definition: random_func.cpp:27
Handling of the list of games.
No pool is selected.
Definition: pool_type.hpp:20
char network_id[NETWORK_SERVER_ID_LENGTH]
network ID for servers
First company, same as owner.
Definition: company_type.h:24
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition: strings.cpp:50
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:82
void NetworkClientSetCompanyPassword(const char *password)
Set/Reset company password on the client side.
void NetworkBackgroundUDPLoop()
Receive the UDP packets.
uint8 frame_freq
how often do we send commands to the clients
std::vector< std::string > StringList
Type for a list of strings.
Definition: string_type.h:60
static const uint NETWORK_COMPANY_NAME_LENGTH
The maximum length of the company name, in bytes including &#39;\0&#39;.
Definition: config.h:43
NetworkClientInfo(ClientID client_id=INVALID_CLIENT_ID)
Create a new client.
Definition: network_base.h:36
void NetworkClose(bool close_admins)
Close current connections.
Definition: network.cpp:528
uint32 _frame_counter_server
The frame_counter of the server, if in network-mode.
Definition: network.cpp:68
static const WChar CHAR_TD_RLM
The next character acts like a right-to-left character.
Definition: string_type.h:42
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
Class for handling the server side of the game connection.
Definition: network_admin.h:27
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
Definition: depend.cpp:68
Maximum number of companies.
Definition: company_type.h:25
StringList _network_ban_list
The banned clients.
Definition: network.cpp:67
void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const char *message,...)
Add a text message to the &#39;chat window&#39; to be shown.
SwitchMode _switch_mode
The next mainloop command.
Definition: gfx.cpp:48
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:192
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
char admin_password[NETWORK_PASSWORD_LENGTH]
password for the admin network
bool _network_server
network-server is active
Definition: network.cpp:55
static NetworkRecvStatus SendQuit()
Tell the server we would like to quit.
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
void NetworkUDPRemoveAdvertise(bool blocking)
Remove our advertise from the master-server.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition: pool_type.hpp:235
void NetworkBackgroundLoop()
We have to do some (simple) background stuff that runs normally, even when we are not in multiplayer...
Definition: network.cpp:854
TileIndex tile
tile command being executed on.
Definition: command_type.h:478
uint32 _last_sync_frame
Used in the server to store the last time a sync packet was sent to clients.
Definition: network.cpp:71
uint16 GetPort() const
Get the port.
Definition: address.cpp:37
void NetworkDisconnect(bool blocking, bool close_admins)
We want to disconnect from the host/clients.
Definition: network.cpp:796
Everything we need to know about a command to be able to execute it.
static void Send()
Send the packets of this socket handler.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Definition: strings_type.h:19
size_t Utf8Encode(char *buf, WChar c)
Encode a unicode character and place it in the buffer.
Definition: string.cpp:488
int32 Date
The type to store our dates in.
Definition: date_type.h:16
NetworkRecvStatus SendShutdown()
Tell the admin we&#39;re shutting down.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:131
char last_host[NETWORK_HOSTNAME_LENGTH]
IP address of the last joined server.
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
uint8 _network_advertise_retries
The number of advertisement retries we did.
Definition: network.cpp:81
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Servers always have this ID.
Definition: network_type.h:43
A game paused by a game script.
Definition: openttd.h:64
Some state information of a company, especially for servers.
Definition: network_type.h:66
StringList _network_bind_list
The addresses to bind on.
Definition: network.cpp:65
#define FOR_ALL_ADMIN_SOCKETS(var)
Iterate over all the sockets.
static const uint NETWORK_NUM_LANDSCAPES
The number of landscapes in OpenTTD.
Definition: config.h:72
NetworkUDPSocketHandler * _udp_master_socket
udp master socket
Definition: network_udp.cpp:50
static NetworkClientInfo * GetByClientID(ClientID client_id)
Return the CI given it&#39;s client-identifier.
Definition: network.cpp:124
uint32 state[2]
The state of the randomizer.
Definition: random_func.hpp:25
Network admin pool.
Definition: pool_type.hpp:23
static void CheckMinActiveClients()
Check if the minimum number of active clients has been reached and pause or unpause the game as appro...
Definition: network.cpp:428
const char * NetworkChangeCompanyPassword(CompanyID company_id, const char *password)
Change the company password of a given company.
Definition: network.cpp:172
static const uint NETWORK_REVISION_LENGTH
The maximum length of the revision, in bytes including &#39;\0&#39;.
Definition: config.h:46
NetworkUDPSocketHandler * _udp_server_socket
udp server socket
Definition: network_udp.cpp:49
void NetworkUDPClose()
Close all UDP related stuff.
Date _date
Current date in days (day counter)
Definition: date.cpp:28
A game paused for &#39;pause_on_join&#39;.
Definition: openttd.h:61
void NetworkDistributeCommands()
Distribute the commands of ourself and the clients.
uint32 _frame_counter_max
To where we may go with our clients.
Definition: network.cpp:69
static bool GameLoop()
Actual game loop for the client.
bool _network_first_time
Whether we have finished joining or not.
Definition: network.cpp:78
static void Send()
Send the packets for the server sockets.
uint32 cmd
command being executed.
Definition: command_type.h:481
Basic functions to receive and send UDP packets.
A game paused because a (critical) error.
Definition: openttd.h:62
NetworkAction
Actions that can be used for NetworkTextMessage.
Definition: network_type.h:87
static const uint GITHASH_SUFFIX_LEN
How many hex digits of the git hash to include in network revision string.
Definition: network.cpp:1105
ClientNetworkContentSocketHandler _network_content_client
The client we use to connect to the server.
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition: window.cpp:3300
Server part of the admin network protocol.
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
uint8 min_active_clients
minimum amount of active clients to unpause the game
pause the game
Definition: command_type.h:256