OpenTTD Source  1.10.3
console_cmds.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * 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.
4  * 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.
5  * 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/>.
6  */
7 
10 #include "stdafx.h"
11 #include "console_internal.h"
12 #include "debug.h"
13 #include "engine_func.h"
14 #include "landscape.h"
15 #include "saveload/saveload.h"
16 #include "network/network.h"
17 #include "network/network_func.h"
18 #include "network/network_base.h"
19 #include "network/network_admin.h"
20 #include "network/network_client.h"
21 #include "command_func.h"
22 #include "settings_func.h"
23 #include "fios.h"
24 #include "fileio_func.h"
25 #include "screenshot.h"
26 #include "genworld.h"
27 #include "strings_func.h"
28 #include "viewport_func.h"
29 #include "window_func.h"
30 #include "date_func.h"
31 #include "company_func.h"
32 #include "gamelog.h"
33 #include "ai/ai.hpp"
34 #include "ai/ai_config.hpp"
35 #include "newgrf.h"
36 #include "newgrf_profiling.h"
37 #include "console_func.h"
38 #include "engine_base.h"
39 #include "game/game.hpp"
40 #include "table/strings.h"
41 #include <time.h>
42 
43 #include "safeguards.h"
44 
45 /* scriptfile handling */
46 static bool _script_running;
47 
49 class ConsoleFileList : public FileList {
50 public:
52  {
53  this->file_list_valid = false;
54  }
55 
58  {
59  this->Clear();
60  this->file_list_valid = false;
61  }
62 
67  void ValidateFileList(bool force_reload = false)
68  {
69  if (force_reload || !this->file_list_valid) {
71  this->file_list_valid = true;
72  }
73  }
74 
76 };
77 
79 
80 /* console command defines */
81 #define DEF_CONSOLE_CMD(function) static bool function(byte argc, char *argv[])
82 #define DEF_CONSOLE_HOOK(function) static ConsoleHookResult function(bool echo)
83 
84 
85 /****************
86  * command hooks
87  ****************/
88 
93 static inline bool NetworkAvailable(bool echo)
94 {
95  if (!_network_available) {
96  if (echo) IConsoleError("You cannot use this command because there is no network available.");
97  return false;
98  }
99  return true;
100 }
101 
106 DEF_CONSOLE_HOOK(ConHookServerOnly)
107 {
108  if (!NetworkAvailable(echo)) return CHR_DISALLOW;
109 
110  if (!_network_server) {
111  if (echo) IConsoleError("This command is only available to a network server.");
112  return CHR_DISALLOW;
113  }
114  return CHR_ALLOW;
115 }
116 
121 DEF_CONSOLE_HOOK(ConHookClientOnly)
122 {
123  if (!NetworkAvailable(echo)) return CHR_DISALLOW;
124 
125  if (_network_server) {
126  if (echo) IConsoleError("This command is not available to a network server.");
127  return CHR_DISALLOW;
128  }
129  return CHR_ALLOW;
130 }
131 
136 DEF_CONSOLE_HOOK(ConHookNeedNetwork)
137 {
138  if (!NetworkAvailable(echo)) return CHR_DISALLOW;
139 
141  if (echo) IConsoleError("Not connected. This command is only available in multiplayer.");
142  return CHR_DISALLOW;
143  }
144  return CHR_ALLOW;
145 }
146 
151 DEF_CONSOLE_HOOK(ConHookNoNetwork)
152 {
153  if (_networking) {
154  if (echo) IConsoleError("This command is forbidden in multiplayer.");
155  return CHR_DISALLOW;
156  }
157  return CHR_ALLOW;
158 }
159 
160 DEF_CONSOLE_HOOK(ConHookNewGRFDeveloperTool)
161 {
163  if (_game_mode == GM_MENU) {
164  if (echo) IConsoleError("This command is only available in game and editor.");
165  return CHR_DISALLOW;
166  }
167  return ConHookNoNetwork(echo);
168  }
169  return CHR_HIDE;
170 }
171 
176 static void IConsoleHelp(const char *str)
177 {
178  IConsolePrintF(CC_WARNING, "- %s", str);
179 }
180 
185 DEF_CONSOLE_CMD(ConResetEngines)
186 {
187  if (argc == 0) {
188  IConsoleHelp("Reset status data of all engines. This might solve some issues with 'lost' engines. Usage: 'resetengines'");
189  return true;
190  }
191 
192  StartupEngines();
193  return true;
194 }
195 
201 DEF_CONSOLE_CMD(ConResetEnginePool)
202 {
203  if (argc == 0) {
204  IConsoleHelp("Reset NewGRF allocations of engine slots. This will remove invalid engine definitions, and might make default engines available again.");
205  return true;
206  }
207 
208  if (_game_mode == GM_MENU) {
209  IConsoleError("This command is only available in game and editor.");
210  return true;
211  }
212 
214  IConsoleError("This can only be done when there are no vehicles in the game.");
215  return true;
216  }
217 
218  return true;
219 }
220 
221 #ifdef _DEBUG
222 
227 DEF_CONSOLE_CMD(ConResetTile)
228 {
229  if (argc == 0) {
230  IConsoleHelp("Reset a tile to bare land. Usage: 'resettile <tile>'");
231  IConsoleHelp("Tile can be either decimal (34161) or hexadecimal (0x4a5B)");
232  return true;
233  }
234 
235  if (argc == 2) {
236  uint32 result;
237  if (GetArgumentInteger(&result, argv[1])) {
238  DoClearSquare((TileIndex)result);
239  return true;
240  }
241  }
242 
243  return false;
244 }
245 #endif /* _DEBUG */
246 
256 DEF_CONSOLE_CMD(ConScrollToTile)
257 {
258  switch (argc) {
259  case 0:
260  IConsoleHelp("Center the screen on a given tile.");
261  IConsoleHelp("Usage: 'scrollto <tile>' or 'scrollto <x> <y>'");
262  IConsoleHelp("Numbers can be either decimal (34161) or hexadecimal (0x4a5B).");
263  return true;
264 
265  case 2: {
266  uint32 result;
267  if (GetArgumentInteger(&result, argv[1])) {
268  if (result >= MapSize()) {
269  IConsolePrint(CC_ERROR, "Tile does not exist");
270  return true;
271  }
273  return true;
274  }
275  break;
276  }
277 
278  case 3: {
279  uint32 x, y;
280  if (GetArgumentInteger(&x, argv[1]) && GetArgumentInteger(&y, argv[2])) {
281  if (x >= MapSizeX() || y >= MapSizeY()) {
282  IConsolePrint(CC_ERROR, "Tile does not exist");
283  return true;
284  }
286  return true;
287  }
288  break;
289  }
290  }
291 
292  return false;
293 }
294 
301 {
302  if (argc == 0) {
303  IConsoleHelp("Save the current game. Usage: 'save <filename>'");
304  return true;
305  }
306 
307  if (argc == 2) {
308  char *filename = str_fmt("%s.sav", argv[1]);
309  IConsolePrint(CC_DEFAULT, "Saving map...");
310 
311  if (SaveOrLoad(filename, SLO_SAVE, DFT_GAME_FILE, SAVE_DIR) != SL_OK) {
312  IConsolePrint(CC_ERROR, "Saving map failed");
313  } else {
314  IConsolePrintF(CC_DEFAULT, "Map successfully saved to %s", filename);
315  }
316  free(filename);
317  return true;
318  }
319 
320  return false;
321 }
322 
327 DEF_CONSOLE_CMD(ConSaveConfig)
328 {
329  if (argc == 0) {
330  IConsoleHelp("Saves the configuration for new games to the configuration file, typically 'openttd.cfg'.");
331  IConsoleHelp("It does not save the configuration of the current game to the configuration file.");
332  return true;
333  }
334 
335  SaveToConfig();
336  IConsolePrint(CC_DEFAULT, "Saved config.");
337  return true;
338 }
339 
340 DEF_CONSOLE_CMD(ConLoad)
341 {
342  if (argc == 0) {
343  IConsoleHelp("Load a game by name or index. Usage: 'load <file | number>'");
344  return true;
345  }
346 
347  if (argc != 2) return false;
348 
349  const char *file = argv[1];
350  _console_file_list.ValidateFileList();
351  const FiosItem *item = _console_file_list.FindItem(file);
352  if (item != nullptr) {
353  if (GetAbstractFileType(item->type) == FT_SAVEGAME) {
355  _file_to_saveload.SetMode(item->type);
357  _file_to_saveload.SetTitle(item->title);
358  } else {
359  IConsolePrintF(CC_ERROR, "%s: Not a savegame.", file);
360  }
361  } else {
362  IConsolePrintF(CC_ERROR, "%s: No such file or directory.", file);
363  }
364 
365  return true;
366 }
367 
368 
369 DEF_CONSOLE_CMD(ConRemove)
370 {
371  if (argc == 0) {
372  IConsoleHelp("Remove a savegame by name or index. Usage: 'rm <file | number>'");
373  return true;
374  }
375 
376  if (argc != 2) return false;
377 
378  const char *file = argv[1];
379  _console_file_list.ValidateFileList();
380  const FiosItem *item = _console_file_list.FindItem(file);
381  if (item != nullptr) {
382  if (!FiosDelete(item->name)) {
383  IConsolePrintF(CC_ERROR, "%s: Failed to delete file", file);
384  }
385  } else {
386  IConsolePrintF(CC_ERROR, "%s: No such file or directory.", file);
387  }
388 
389  _console_file_list.InvalidateFileList();
390  return true;
391 }
392 
393 
394 /* List all the files in the current dir via console */
395 DEF_CONSOLE_CMD(ConListFiles)
396 {
397  if (argc == 0) {
398  IConsoleHelp("List all loadable savegames and directories in the current dir via console. Usage: 'ls | dir'");
399  return true;
400  }
401 
402  _console_file_list.ValidateFileList(true);
403  for (uint i = 0; i < _console_file_list.Length(); i++) {
404  IConsolePrintF(CC_DEFAULT, "%d) %s", i, _console_file_list[i].title);
405  }
406 
407  return true;
408 }
409 
410 /* Change the dir via console */
411 DEF_CONSOLE_CMD(ConChangeDirectory)
412 {
413  if (argc == 0) {
414  IConsoleHelp("Change the dir via console. Usage: 'cd <directory | number>'");
415  return true;
416  }
417 
418  if (argc != 2) return false;
419 
420  const char *file = argv[1];
421  _console_file_list.ValidateFileList(true);
422  const FiosItem *item = _console_file_list.FindItem(file);
423  if (item != nullptr) {
424  switch (item->type) {
425  case FIOS_TYPE_DIR: case FIOS_TYPE_DRIVE: case FIOS_TYPE_PARENT:
426  FiosBrowseTo(item);
427  break;
428  default: IConsolePrintF(CC_ERROR, "%s: Not a directory.", file);
429  }
430  } else {
431  IConsolePrintF(CC_ERROR, "%s: No such file or directory.", file);
432  }
433 
434  _console_file_list.InvalidateFileList();
435  return true;
436 }
437 
438 DEF_CONSOLE_CMD(ConPrintWorkingDirectory)
439 {
440  const char *path;
441 
442  if (argc == 0) {
443  IConsoleHelp("Print out the current working directory. Usage: 'pwd'");
444  return true;
445  }
446 
447  /* XXX - Workaround for broken file handling */
448  _console_file_list.ValidateFileList(true);
449  _console_file_list.InvalidateFileList();
450 
451  FiosGetDescText(&path, nullptr);
452  IConsolePrint(CC_DEFAULT, path);
453  return true;
454 }
455 
456 DEF_CONSOLE_CMD(ConClearBuffer)
457 {
458  if (argc == 0) {
459  IConsoleHelp("Clear the console buffer. Usage: 'clear'");
460  return true;
461  }
462 
463  IConsoleClearBuffer();
465  return true;
466 }
467 
468 
469 /**********************************
470  * Network Core Console Commands
471  **********************************/
472 
473 static bool ConKickOrBan(const char *argv, bool ban, const char *reason)
474 {
475  uint n;
476 
477  if (strchr(argv, '.') == nullptr && strchr(argv, ':') == nullptr) { // banning with ID
478  ClientID client_id = (ClientID)atoi(argv);
479 
480  /* Don't kill the server, or the client doing the rcon. The latter can't be kicked because
481  * kicking frees closes and subsequently free the connection related instances, which we
482  * would be reading from and writing to after returning. So we would read or write data
483  * from freed memory up till the segfault triggers. */
484  if (client_id == CLIENT_ID_SERVER || client_id == _redirect_console_to_client) {
485  IConsolePrintF(CC_ERROR, "ERROR: Silly boy, you can not %s yourself!", ban ? "ban" : "kick");
486  return true;
487  }
488 
490  if (ci == nullptr) {
491  IConsoleError("Invalid client");
492  return true;
493  }
494 
495  if (!ban) {
496  /* Kick only this client, not all clients with that IP */
497  NetworkServerKickClient(client_id, reason);
498  return true;
499  }
500 
501  /* When banning, kick+ban all clients with that IP */
502  n = NetworkServerKickOrBanIP(client_id, ban, reason);
503  } else {
504  n = NetworkServerKickOrBanIP(argv, ban, reason);
505  }
506 
507  if (n == 0) {
508  IConsolePrint(CC_DEFAULT, ban ? "Client not online, address added to banlist" : "Client not found");
509  } else {
510  IConsolePrintF(CC_DEFAULT, "%sed %u client(s)", ban ? "Bann" : "Kick", n);
511  }
512 
513  return true;
514 }
515 
516 DEF_CONSOLE_CMD(ConKick)
517 {
518  if (argc == 0) {
519  IConsoleHelp("Kick a client from a network game. Usage: 'kick <ip | client-id> [<kick-reason>]'");
520  IConsoleHelp("For client-id's, see the command 'clients'");
521  return true;
522  }
523 
524  if (argc != 2 && argc != 3) return false;
525 
526  /* No reason supplied for kicking */
527  if (argc == 2) return ConKickOrBan(argv[1], false, nullptr);
528 
529  /* Reason for kicking supplied */
530  size_t kick_message_length = strlen(argv[2]);
531  if (kick_message_length >= 255) {
532  IConsolePrintF(CC_ERROR, "ERROR: Maximum kick message length is 254 characters. You entered " PRINTF_SIZE " characters.", kick_message_length);
533  return false;
534  } else {
535  return ConKickOrBan(argv[1], false, argv[2]);
536  }
537 }
538 
539 DEF_CONSOLE_CMD(ConBan)
540 {
541  if (argc == 0) {
542  IConsoleHelp("Ban a client from a network game. Usage: 'ban <ip | client-id> [<ban-reason>]'");
543  IConsoleHelp("For client-id's, see the command 'clients'");
544  IConsoleHelp("If the client is no longer online, you can still ban his/her IP");
545  return true;
546  }
547 
548  if (argc != 2 && argc != 3) return false;
549 
550  /* No reason supplied for kicking */
551  if (argc == 2) return ConKickOrBan(argv[1], true, nullptr);
552 
553  /* Reason for kicking supplied */
554  size_t kick_message_length = strlen(argv[2]);
555  if (kick_message_length >= 255) {
556  IConsolePrintF(CC_ERROR, "ERROR: Maximum kick message length is 254 characters. You entered " PRINTF_SIZE " characters.", kick_message_length);
557  return false;
558  } else {
559  return ConKickOrBan(argv[1], true, argv[2]);
560  }
561 }
562 
563 DEF_CONSOLE_CMD(ConUnBan)
564 {
565  if (argc == 0) {
566  IConsoleHelp("Unban a client from a network game. Usage: 'unban <ip | banlist-index>'");
567  IConsoleHelp("For a list of banned IP's, see the command 'banlist'");
568  return true;
569  }
570 
571  if (argc != 2) return false;
572 
573  /* Try by IP. */
574  uint index;
575  for (index = 0; index < _network_ban_list.size(); index++) {
576  if (_network_ban_list[index] == argv[1]) break;
577  }
578 
579  /* Try by index. */
580  if (index >= _network_ban_list.size()) {
581  index = atoi(argv[1]) - 1U; // let it wrap
582  }
583 
584  if (index < _network_ban_list.size()) {
585  char msg[64];
586  seprintf(msg, lastof(msg), "Unbanned %s", _network_ban_list[index].c_str());
588  _network_ban_list.erase(_network_ban_list.begin() + index);
589  } else {
590  IConsolePrint(CC_DEFAULT, "Invalid list index or IP not in ban-list.");
591  IConsolePrint(CC_DEFAULT, "For a list of banned IP's, see the command 'banlist'");
592  }
593 
594  return true;
595 }
596 
597 DEF_CONSOLE_CMD(ConBanList)
598 {
599  if (argc == 0) {
600  IConsoleHelp("List the IP's of banned clients: Usage 'banlist'");
601  return true;
602  }
603 
604  IConsolePrint(CC_DEFAULT, "Banlist: ");
605 
606  uint i = 1;
607  for (const auto &entry : _network_ban_list) {
608  IConsolePrintF(CC_DEFAULT, " %d) %s", i, entry.c_str());
609  i++;
610  }
611 
612  return true;
613 }
614 
615 DEF_CONSOLE_CMD(ConPauseGame)
616 {
617  if (argc == 0) {
618  IConsoleHelp("Pause a network game. Usage: 'pause'");
619  return true;
620  }
621 
623  DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
624  if (!_networking) IConsolePrint(CC_DEFAULT, "Game paused.");
625  } else {
626  IConsolePrint(CC_DEFAULT, "Game is already paused.");
627  }
628 
629  return true;
630 }
631 
632 DEF_CONSOLE_CMD(ConUnpauseGame)
633 {
634  if (argc == 0) {
635  IConsoleHelp("Unpause a network game. Usage: 'unpause'");
636  return true;
637  }
638 
640  DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE);
641  if (!_networking) IConsolePrint(CC_DEFAULT, "Game unpaused.");
642  } else if ((_pause_mode & PM_PAUSED_ERROR) != PM_UNPAUSED) {
643  IConsolePrint(CC_DEFAULT, "Game is in error state and cannot be unpaused via console.");
644  } else if (_pause_mode != PM_UNPAUSED) {
645  IConsolePrint(CC_DEFAULT, "Game cannot be unpaused manually; disable pause_on_join/min_active_clients.");
646  } else {
647  IConsolePrint(CC_DEFAULT, "Game is already unpaused.");
648  }
649 
650  return true;
651 }
652 
653 DEF_CONSOLE_CMD(ConRcon)
654 {
655  if (argc == 0) {
656  IConsoleHelp("Remote control the server from another client. Usage: 'rcon <password> <command>'");
657  IConsoleHelp("Remember to enclose the command in quotes, otherwise only the first parameter is sent");
658  return true;
659  }
660 
661  if (argc < 3) return false;
662 
663  if (_network_server) {
664  IConsoleCmdExec(argv[2]);
665  } else {
666  NetworkClientSendRcon(argv[1], argv[2]);
667  }
668  return true;
669 }
670 
671 DEF_CONSOLE_CMD(ConStatus)
672 {
673  if (argc == 0) {
674  IConsoleHelp("List the status of all clients connected to the server. Usage 'status'");
675  return true;
676  }
677 
679  return true;
680 }
681 
682 DEF_CONSOLE_CMD(ConServerInfo)
683 {
684  if (argc == 0) {
685  IConsoleHelp("List current and maximum client/company limits. Usage 'server_info'");
686  IConsoleHelp("You can change these values by modifying settings 'network.max_clients', 'network.max_companies' and 'network.max_spectators'");
687  return true;
688  }
689 
691  IConsolePrintF(CC_DEFAULT, "Current/maximum companies: %2d/%2d", (int)Company::GetNumItems(), _settings_client.network.max_companies);
692  IConsolePrintF(CC_DEFAULT, "Current/maximum spectators: %2d/%2d", NetworkSpectatorCount(), _settings_client.network.max_spectators);
693 
694  return true;
695 }
696 
697 DEF_CONSOLE_CMD(ConClientNickChange)
698 {
699  if (argc != 3) {
700  IConsoleHelp("Change the nickname of a connected client. Usage: 'client_name <client-id> <new-name>'");
701  IConsoleHelp("For client-id's, see the command 'clients'");
702  return true;
703  }
704 
705  ClientID client_id = (ClientID)atoi(argv[1]);
706 
707  if (client_id == CLIENT_ID_SERVER) {
708  IConsoleError("Please use the command 'name' to change your own name!");
709  return true;
710  }
711 
712  if (NetworkClientInfo::GetByClientID(client_id) == nullptr) {
713  IConsoleError("Invalid client");
714  return true;
715  }
716 
717  if (!NetworkServerChangeClientName(client_id, argv[2])) {
718  IConsoleError("Cannot give a client a duplicate name");
719  }
720 
721  return true;
722 }
723 
724 DEF_CONSOLE_CMD(ConJoinCompany)
725 {
726  if (argc < 2) {
727  IConsoleHelp("Request joining another company. Usage: join <company-id> [<password>]");
728  IConsoleHelp("For valid company-id see company list, use 255 for spectator");
729  return true;
730  }
731 
732  CompanyID company_id = (CompanyID)(atoi(argv[1]) <= MAX_COMPANIES ? atoi(argv[1]) - 1 : atoi(argv[1]));
733 
734  /* Check we have a valid company id! */
735  if (!Company::IsValidID(company_id) && company_id != COMPANY_SPECTATOR) {
736  IConsolePrintF(CC_ERROR, "Company does not exist. Company-id must be between 1 and %d.", MAX_COMPANIES);
737  return true;
738  }
739 
740  if (NetworkClientInfo::GetByClientID(_network_own_client_id)->client_playas == company_id) {
741  IConsoleError("You are already there!");
742  return true;
743  }
744 
745  if (company_id == COMPANY_SPECTATOR && NetworkMaxSpectatorsReached()) {
746  IConsoleError("Cannot join spectators, maximum number of spectators reached.");
747  return true;
748  }
749 
750  if (company_id != COMPANY_SPECTATOR && !Company::IsHumanID(company_id)) {
751  IConsoleError("Cannot join AI company.");
752  return true;
753  }
754 
755  /* Check if the company requires a password */
756  if (NetworkCompanyIsPassworded(company_id) && argc < 3) {
757  IConsolePrintF(CC_ERROR, "Company %d requires a password to join.", company_id + 1);
758  return true;
759  }
760 
761  /* non-dedicated server may just do the move! */
762  if (_network_server) {
764  } else {
765  NetworkClientRequestMove(company_id, NetworkCompanyIsPassworded(company_id) ? argv[2] : "");
766  }
767 
768  return true;
769 }
770 
771 DEF_CONSOLE_CMD(ConMoveClient)
772 {
773  if (argc < 3) {
774  IConsoleHelp("Move a client to another company. Usage: move <client-id> <company-id>");
775  IConsoleHelp("For valid client-id see 'clients', for valid company-id see 'companies', use 255 for moving to spectators");
776  return true;
777  }
778 
779  const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID((ClientID)atoi(argv[1]));
780  CompanyID company_id = (CompanyID)(atoi(argv[2]) <= MAX_COMPANIES ? atoi(argv[2]) - 1 : atoi(argv[2]));
781 
782  /* check the client exists */
783  if (ci == nullptr) {
784  IConsoleError("Invalid client-id, check the command 'clients' for valid client-id's.");
785  return true;
786  }
787 
788  if (!Company::IsValidID(company_id) && company_id != COMPANY_SPECTATOR) {
789  IConsolePrintF(CC_ERROR, "Company does not exist. Company-id must be between 1 and %d.", MAX_COMPANIES);
790  return true;
791  }
792 
793  if (company_id != COMPANY_SPECTATOR && !Company::IsHumanID(company_id)) {
794  IConsoleError("You cannot move clients to AI companies.");
795  return true;
796  }
797 
799  IConsoleError("Silly boy, you cannot move the server!");
800  return true;
801  }
802 
803  if (ci->client_playas == company_id) {
804  IConsoleError("You cannot move someone to where he/she already is!");
805  return true;
806  }
807 
808  /* we are the server, so force the update */
809  NetworkServerDoMove(ci->client_id, company_id);
810 
811  return true;
812 }
813 
814 DEF_CONSOLE_CMD(ConResetCompany)
815 {
816  if (argc == 0) {
817  IConsoleHelp("Remove an idle company from the game. Usage: 'reset_company <company-id>'");
818  IConsoleHelp("For company-id's, see the list of companies from the dropdown menu. Company 1 is 1, etc.");
819  return true;
820  }
821 
822  if (argc != 2) return false;
823 
824  CompanyID index = (CompanyID)(atoi(argv[1]) - 1);
825 
826  /* Check valid range */
827  if (!Company::IsValidID(index)) {
828  IConsolePrintF(CC_ERROR, "Company does not exist. Company-id must be between 1 and %d.", MAX_COMPANIES);
829  return true;
830  }
831 
832  if (!Company::IsHumanID(index)) {
833  IConsoleError("Company is owned by an AI.");
834  return true;
835  }
836 
837  if (NetworkCompanyHasClients(index)) {
838  IConsoleError("Cannot remove company: a client is connected to that company.");
839  return false;
840  }
842  if (ci->client_playas == index) {
843  IConsoleError("Cannot remove company: the server is connected to that company.");
844  return true;
845  }
846 
847  /* It is safe to remove this company */
848  DoCommandP(0, CCA_DELETE | index << 16 | CRR_MANUAL << 24, 0, CMD_COMPANY_CTRL);
849  IConsolePrint(CC_DEFAULT, "Company deleted.");
850 
851  return true;
852 }
853 
854 DEF_CONSOLE_CMD(ConNetworkClients)
855 {
856  if (argc == 0) {
857  IConsoleHelp("Get a list of connected clients including their ID, name, company-id, and IP. Usage: 'clients'");
858  return true;
859  }
860 
862 
863  return true;
864 }
865 
866 DEF_CONSOLE_CMD(ConNetworkReconnect)
867 {
868  if (argc == 0) {
869  IConsoleHelp("Reconnect to server to which you were connected last time. Usage: 'reconnect [<company>]'");
870  IConsoleHelp("Company 255 is spectator (default, if not specified), 0 means creating new company.");
871  IConsoleHelp("All others are a certain company with Company 1 being #1");
872  return true;
873  }
874 
875  CompanyID playas = (argc >= 2) ? (CompanyID)atoi(argv[1]) : COMPANY_SPECTATOR;
876  switch (playas) {
877  case 0: playas = COMPANY_NEW_COMPANY; break;
878  case COMPANY_SPECTATOR: /* nothing to do */ break;
879  default:
880  /* From a user pov 0 is a new company, internally it's different and all
881  * companies are offset by one to ease up on users (eg companies 1-8 not 0-7) */
882  if (playas < COMPANY_FIRST + 1 || playas > MAX_COMPANIES + 1) return false;
883  break;
884  }
885 
887  IConsolePrint(CC_DEFAULT, "No server for reconnecting.");
888  return true;
889  }
890 
891  /* Don't resolve the address first, just print it directly as it comes from the config file. */
893 
895  return true;
896 }
897 
898 DEF_CONSOLE_CMD(ConNetworkConnect)
899 {
900  if (argc == 0) {
901  IConsoleHelp("Connect to a remote OTTD server and join the game. Usage: 'connect <ip>'");
902  IConsoleHelp("IP can contain port and company: 'IP[:Port][#Company]', eg: 'server.ottd.org:443#2'");
903  IConsoleHelp("Company #255 is spectator all others are a certain company with Company 1 being #1");
904  return true;
905  }
906 
907  if (argc < 2) return false;
908  if (_networking) NetworkDisconnect(); // we are in network-mode, first close it!
909 
910  const char *port = nullptr;
911  const char *company = nullptr;
912  char *ip = argv[1];
913  /* Default settings: default port and new company */
914  uint16 rport = NETWORK_DEFAULT_PORT;
915  CompanyID join_as = COMPANY_NEW_COMPANY;
916 
917  ParseConnectionString(&company, &port, ip);
918 
919  IConsolePrintF(CC_DEFAULT, "Connecting to %s...", ip);
920  if (company != nullptr) {
921  join_as = (CompanyID)atoi(company);
922  IConsolePrintF(CC_DEFAULT, " company-no: %d", join_as);
923 
924  /* From a user pov 0 is a new company, internally it's different and all
925  * companies are offset by one to ease up on users (eg companies 1-8 not 0-7) */
926  if (join_as != COMPANY_SPECTATOR) {
927  if (join_as > MAX_COMPANIES) return false;
928  join_as--;
929  }
930  }
931  if (port != nullptr) {
932  rport = atoi(port);
933  IConsolePrintF(CC_DEFAULT, " port: %s", port);
934  }
935 
936  NetworkClientConnectGame(NetworkAddress(ip, rport), join_as);
937 
938  return true;
939 }
940 
941 /*********************************
942  * script file console commands
943  *********************************/
944 
945 DEF_CONSOLE_CMD(ConExec)
946 {
947  if (argc == 0) {
948  IConsoleHelp("Execute a local script file. Usage: 'exec <script> <?>'");
949  return true;
950  }
951 
952  if (argc < 2) return false;
953 
954  FILE *script_file = FioFOpenFile(argv[1], "r", BASE_DIR);
955 
956  if (script_file == nullptr) {
957  if (argc == 2 || atoi(argv[2]) != 0) IConsoleError("script file not found");
958  return true;
959  }
960 
961  _script_running = true;
962 
963  char cmdline[ICON_CMDLN_SIZE];
964  while (_script_running && fgets(cmdline, sizeof(cmdline), script_file) != nullptr) {
965  /* Remove newline characters from the executing script */
966  for (char *cmdptr = cmdline; *cmdptr != '\0'; cmdptr++) {
967  if (*cmdptr == '\n' || *cmdptr == '\r') {
968  *cmdptr = '\0';
969  break;
970  }
971  }
972  IConsoleCmdExec(cmdline);
973  }
974 
975  if (ferror(script_file)) {
976  IConsoleError("Encountered error while trying to read from script file");
977  }
978 
979  _script_running = false;
980  FioFCloseFile(script_file);
981  return true;
982 }
983 
984 DEF_CONSOLE_CMD(ConReturn)
985 {
986  if (argc == 0) {
987  IConsoleHelp("Stop executing a running script. Usage: 'return'");
988  return true;
989  }
990 
991  _script_running = false;
992  return true;
993 }
994 
995 /*****************************
996  * default console commands
997  ******************************/
998 extern bool CloseConsoleLogIfActive();
999 
1000 DEF_CONSOLE_CMD(ConScript)
1001 {
1002  extern FILE *_iconsole_output_file;
1003 
1004  if (argc == 0) {
1005  IConsoleHelp("Start or stop logging console output to a file. Usage: 'script <filename>'");
1006  IConsoleHelp("If filename is omitted, a running log is stopped if it is active");
1007  return true;
1008  }
1009 
1010  if (!CloseConsoleLogIfActive()) {
1011  if (argc < 2) return false;
1012 
1013  IConsolePrintF(CC_DEFAULT, "file output started to: %s", argv[1]);
1014  _iconsole_output_file = fopen(argv[1], "ab");
1015  if (_iconsole_output_file == nullptr) IConsoleError("could not open file");
1016  }
1017 
1018  return true;
1019 }
1020 
1021 
1022 DEF_CONSOLE_CMD(ConEcho)
1023 {
1024  if (argc == 0) {
1025  IConsoleHelp("Print back the first argument to the console. Usage: 'echo <arg>'");
1026  return true;
1027  }
1028 
1029  if (argc < 2) return false;
1030  IConsolePrint(CC_DEFAULT, argv[1]);
1031  return true;
1032 }
1033 
1034 DEF_CONSOLE_CMD(ConEchoC)
1035 {
1036  if (argc == 0) {
1037  IConsoleHelp("Print back the first argument to the console in a given colour. Usage: 'echoc <colour> <arg2>'");
1038  return true;
1039  }
1040 
1041  if (argc < 3) return false;
1042  IConsolePrint((TextColour)Clamp(atoi(argv[1]), TC_BEGIN, TC_END - 1), argv[2]);
1043  return true;
1044 }
1045 
1046 DEF_CONSOLE_CMD(ConNewGame)
1047 {
1048  if (argc == 0) {
1049  IConsoleHelp("Start a new game. Usage: 'newgame [seed]'");
1050  IConsoleHelp("The server can force a new game using 'newgame'; any client joined will rejoin after the server is done generating the new game.");
1051  return true;
1052  }
1053 
1054  StartNewGameWithoutGUI((argc == 2) ? strtoul(argv[1], nullptr, 10) : GENERATE_NEW_SEED);
1055  return true;
1056 }
1057 
1058 DEF_CONSOLE_CMD(ConRestart)
1059 {
1060  if (argc == 0) {
1061  IConsoleHelp("Restart game. Usage: 'restart'");
1062  IConsoleHelp("Restarts a game. It tries to reproduce the exact same map as the game started with.");
1063  IConsoleHelp("However:");
1064  IConsoleHelp(" * restarting games started in another version might create another map due to difference in map generation");
1065  IConsoleHelp(" * restarting games based on scenarios, loaded games or heightmaps will start a new game based on the settings stored in the scenario/savegame");
1066  return true;
1067  }
1068 
1069  /* Don't copy the _newgame pointers to the real pointers, so call SwitchToMode directly */
1073  return true;
1074 }
1075 
1081 static void PrintLineByLine(char *buf)
1082 {
1083  char *p = buf;
1084  /* Print output line by line */
1085  for (char *p2 = buf; *p2 != '\0'; p2++) {
1086  if (*p2 == '\n') {
1087  *p2 = '\0';
1088  IConsolePrintF(CC_DEFAULT, "%s", p);
1089  p = p2 + 1;
1090  }
1091  }
1092 }
1093 
1094 DEF_CONSOLE_CMD(ConListAILibs)
1095 {
1096  char buf[4096];
1097  AI::GetConsoleLibraryList(buf, lastof(buf));
1098 
1099  PrintLineByLine(buf);
1100 
1101  return true;
1102 }
1103 
1104 DEF_CONSOLE_CMD(ConListAI)
1105 {
1106  char buf[4096];
1107  AI::GetConsoleList(buf, lastof(buf));
1108 
1109  PrintLineByLine(buf);
1110 
1111  return true;
1112 }
1113 
1114 DEF_CONSOLE_CMD(ConListGameLibs)
1115 {
1116  char buf[4096];
1118 
1119  PrintLineByLine(buf);
1120 
1121  return true;
1122 }
1123 
1124 DEF_CONSOLE_CMD(ConListGame)
1125 {
1126  char buf[4096];
1127  Game::GetConsoleList(buf, lastof(buf));
1128 
1129  PrintLineByLine(buf);
1130 
1131  return true;
1132 }
1133 
1134 DEF_CONSOLE_CMD(ConStartAI)
1135 {
1136  if (argc == 0 || argc > 3) {
1137  IConsoleHelp("Start a new AI. Usage: 'start_ai [<AI>] [<settings>]'");
1138  IConsoleHelp("Start a new AI. If <AI> is given, it starts that specific AI (if found).");
1139  IConsoleHelp("If <settings> is given, it is parsed and the AI settings are set to that.");
1140  return true;
1141  }
1142 
1143  if (_game_mode != GM_NORMAL) {
1144  IConsoleWarning("AIs can only be managed in a game.");
1145  return true;
1146  }
1147 
1149  IConsoleWarning("Can't start a new AI (no more free slots).");
1150  return true;
1151  }
1152  if (_networking && !_network_server) {
1153  IConsoleWarning("Only the server can start a new AI.");
1154  return true;
1155  }
1157  IConsoleWarning("AIs are not allowed in multiplayer by configuration.");
1158  IConsoleWarning("Switch AI -> AI in multiplayer to True.");
1159  return true;
1160  }
1161  if (!AI::CanStartNew()) {
1162  IConsoleWarning("Can't start a new AI.");
1163  return true;
1164  }
1165 
1166  int n = 0;
1167  /* Find the next free slot */
1168  for (const Company *c : Company::Iterate()) {
1169  if (c->index != n) break;
1170  n++;
1171  }
1172 
1173  AIConfig *config = AIConfig::GetConfig((CompanyID)n);
1174  if (argc >= 2) {
1175  config->Change(argv[1], -1, true);
1176  if (!config->HasScript()) {
1177  IConsoleWarning("Failed to load the specified AI");
1178  return true;
1179  }
1180  if (argc == 3) {
1181  config->StringToSettings(argv[2]);
1182  }
1183  }
1184 
1185  /* Start a new AI company */
1187 
1188  return true;
1189 }
1190 
1191 DEF_CONSOLE_CMD(ConReloadAI)
1192 {
1193  if (argc != 2) {
1194  IConsoleHelp("Reload an AI. Usage: 'reload_ai <company-id>'");
1195  IConsoleHelp("Reload the AI with the given company id. For company-id's, see the list of companies from the dropdown menu. Company 1 is 1, etc.");
1196  return true;
1197  }
1198 
1199  if (_game_mode != GM_NORMAL) {
1200  IConsoleWarning("AIs can only be managed in a game.");
1201  return true;
1202  }
1203 
1204  if (_networking && !_network_server) {
1205  IConsoleWarning("Only the server can reload an AI.");
1206  return true;
1207  }
1208 
1209  CompanyID company_id = (CompanyID)(atoi(argv[1]) - 1);
1210  if (!Company::IsValidID(company_id)) {
1211  IConsolePrintF(CC_DEFAULT, "Unknown company. Company range is between 1 and %d.", MAX_COMPANIES);
1212  return true;
1213  }
1214 
1215  if (Company::IsHumanID(company_id)) {
1216  IConsoleWarning("Company is not controlled by an AI.");
1217  return true;
1218  }
1219 
1220  /* First kill the company of the AI, then start a new one. This should start the current AI again */
1221  DoCommandP(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0,CMD_COMPANY_CTRL);
1222  DoCommandP(0, CCA_NEW_AI | company_id << 16, 0, CMD_COMPANY_CTRL);
1223  IConsolePrint(CC_DEFAULT, "AI reloaded.");
1224 
1225  return true;
1226 }
1227 
1228 DEF_CONSOLE_CMD(ConStopAI)
1229 {
1230  if (argc != 2) {
1231  IConsoleHelp("Stop an AI. Usage: 'stop_ai <company-id>'");
1232  IConsoleHelp("Stop the AI with the given company id. For company-id's, see the list of companies from the dropdown menu. Company 1 is 1, etc.");
1233  return true;
1234  }
1235 
1236  if (_game_mode != GM_NORMAL) {
1237  IConsoleWarning("AIs can only be managed in a game.");
1238  return true;
1239  }
1240 
1241  if (_networking && !_network_server) {
1242  IConsoleWarning("Only the server can stop an AI.");
1243  return true;
1244  }
1245 
1246  CompanyID company_id = (CompanyID)(atoi(argv[1]) - 1);
1247  if (!Company::IsValidID(company_id)) {
1248  IConsolePrintF(CC_DEFAULT, "Unknown company. Company range is between 1 and %d.", MAX_COMPANIES);
1249  return true;
1250  }
1251 
1252  if (Company::IsHumanID(company_id) || company_id == _local_company) {
1253  IConsoleWarning("Company is not controlled by an AI.");
1254  return true;
1255  }
1256 
1257  /* Now kill the company of the AI. */
1258  DoCommandP(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0, CMD_COMPANY_CTRL);
1259  IConsolePrint(CC_DEFAULT, "AI stopped, company deleted.");
1260 
1261  return true;
1262 }
1263 
1264 DEF_CONSOLE_CMD(ConRescanAI)
1265 {
1266  if (argc == 0) {
1267  IConsoleHelp("Rescan the AI dir for scripts. Usage: 'rescan_ai'");
1268  return true;
1269  }
1270 
1271  if (_networking && !_network_server) {
1272  IConsoleWarning("Only the server can rescan the AI dir for scripts.");
1273  return true;
1274  }
1275 
1276  AI::Rescan();
1277 
1278  return true;
1279 }
1280 
1281 DEF_CONSOLE_CMD(ConRescanGame)
1282 {
1283  if (argc == 0) {
1284  IConsoleHelp("Rescan the Game Script dir for scripts. Usage: 'rescan_game'");
1285  return true;
1286  }
1287 
1288  if (_networking && !_network_server) {
1289  IConsoleWarning("Only the server can rescan the Game Script dir for scripts.");
1290  return true;
1291  }
1292 
1293  Game::Rescan();
1294 
1295  return true;
1296 }
1297 
1298 DEF_CONSOLE_CMD(ConRescanNewGRF)
1299 {
1300  if (argc == 0) {
1301  IConsoleHelp("Rescan the data dir for NewGRFs. Usage: 'rescan_newgrf'");
1302  return true;
1303  }
1304 
1305  ScanNewGRFFiles(nullptr);
1306 
1307  return true;
1308 }
1309 
1310 DEF_CONSOLE_CMD(ConGetSeed)
1311 {
1312  if (argc == 0) {
1313  IConsoleHelp("Returns the seed used to create this game. Usage: 'getseed'");
1314  IConsoleHelp("The seed can be used to reproduce the exact same map as the game started with.");
1315  return true;
1316  }
1317 
1319  return true;
1320 }
1321 
1322 DEF_CONSOLE_CMD(ConGetDate)
1323 {
1324  if (argc == 0) {
1325  IConsoleHelp("Returns the current date (year-month-day) of the game. Usage: 'getdate'");
1326  return true;
1327  }
1328 
1329  YearMonthDay ymd;
1330  ConvertDateToYMD(_date, &ymd);
1331  IConsolePrintF(CC_DEFAULT, "Date: %04d-%02d-%02d", ymd.year, ymd.month + 1, ymd.day);
1332  return true;
1333 }
1334 
1335 DEF_CONSOLE_CMD(ConGetSysDate)
1336 {
1337  if (argc == 0) {
1338  IConsoleHelp("Returns the current date (year-month-day) of your system. Usage: 'getsysdate'");
1339  return true;
1340  }
1341 
1342  time_t t;
1343  time(&t);
1344  auto timeinfo = localtime(&t);
1345  IConsolePrintF(CC_DEFAULT, "System Date: %04d-%02d-%02d %02d:%02d:%02d", timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
1346  return true;
1347 }
1348 
1349 
1350 DEF_CONSOLE_CMD(ConAlias)
1351 {
1352  IConsoleAlias *alias;
1353 
1354  if (argc == 0) {
1355  IConsoleHelp("Add a new alias, or redefine the behaviour of an existing alias . Usage: 'alias <name> <command>'");
1356  return true;
1357  }
1358 
1359  if (argc < 3) return false;
1360 
1361  alias = IConsoleAliasGet(argv[1]);
1362  if (alias == nullptr) {
1363  IConsoleAliasRegister(argv[1], argv[2]);
1364  } else {
1365  free(alias->cmdline);
1366  alias->cmdline = stredup(argv[2]);
1367  }
1368  return true;
1369 }
1370 
1371 DEF_CONSOLE_CMD(ConScreenShot)
1372 {
1373  if (argc == 0) {
1374  IConsoleHelp("Create a screenshot of the game. Usage: 'screenshot [big | giant | no_con | minimap] [file name]'");
1375  IConsoleHelp("'big' makes a zoomed-in screenshot of the visible area, 'giant' makes a screenshot of the "
1376  "whole map, 'no_con' hides the console to create the screenshot. 'big' or 'giant' "
1377  "screenshots are always drawn without console. "
1378  "'minimap' makes a top-viewed minimap screenshot of whole world which represents one tile by one pixel.");
1379  return true;
1380  }
1381 
1382  if (argc > 3) return false;
1383 
1384  ScreenshotType type = SC_VIEWPORT;
1385  const char *name = nullptr;
1386 
1387  if (argc > 1) {
1388  if (strcmp(argv[1], "big") == 0) {
1389  /* screenshot big [filename] */
1390  type = SC_ZOOMEDIN;
1391  if (argc > 2) name = argv[2];
1392  } else if (strcmp(argv[1], "giant") == 0) {
1393  /* screenshot giant [filename] */
1394  type = SC_WORLD;
1395  if (argc > 2) name = argv[2];
1396  } else if (strcmp(argv[1], "minimap") == 0) {
1397  /* screenshot minimap [filename] */
1398  type = SC_MINIMAP;
1399  if (argc > 2) name = argv[2];
1400  } else if (strcmp(argv[1], "no_con") == 0) {
1401  /* screenshot no_con [filename] */
1402  IConsoleClose();
1403  if (argc > 2) name = argv[2];
1404  } else if (argc == 2) {
1405  /* screenshot filename */
1406  name = argv[1];
1407  } else {
1408  /* screenshot argv[1] argv[2] - invalid */
1409  return false;
1410  }
1411  }
1412 
1413  MakeScreenshot(type, name);
1414  return true;
1415 }
1416 
1417 DEF_CONSOLE_CMD(ConInfoCmd)
1418 {
1419  if (argc == 0) {
1420  IConsoleHelp("Print out debugging information about a command. Usage: 'info_cmd <cmd>'");
1421  return true;
1422  }
1423 
1424  if (argc < 2) return false;
1425 
1426  const IConsoleCmd *cmd = IConsoleCmdGet(argv[1]);
1427  if (cmd == nullptr) {
1428  IConsoleError("the given command was not found");
1429  return true;
1430  }
1431 
1432  IConsolePrintF(CC_DEFAULT, "command name: %s", cmd->name);
1433  IConsolePrintF(CC_DEFAULT, "command proc: %p", cmd->proc);
1434 
1435  if (cmd->hook != nullptr) IConsoleWarning("command is hooked");
1436 
1437  return true;
1438 }
1439 
1440 DEF_CONSOLE_CMD(ConDebugLevel)
1441 {
1442  if (argc == 0) {
1443  IConsoleHelp("Get/set the default debugging level for the game. Usage: 'debug_level [<level>]'");
1444  IConsoleHelp("Level can be any combination of names, levels. Eg 'net=5 ms=4'. Remember to enclose it in \"'s");
1445  return true;
1446  }
1447 
1448  if (argc > 2) return false;
1449 
1450  if (argc == 1) {
1451  IConsolePrintF(CC_DEFAULT, "Current debug-level: '%s'", GetDebugString());
1452  } else {
1453  SetDebugString(argv[1]);
1454  }
1455 
1456  return true;
1457 }
1458 
1459 DEF_CONSOLE_CMD(ConExit)
1460 {
1461  if (argc == 0) {
1462  IConsoleHelp("Exit the game. Usage: 'exit'");
1463  return true;
1464  }
1465 
1466  if (_game_mode == GM_NORMAL && _settings_client.gui.autosave_on_exit) DoExitSave();
1467 
1468  _exit_game = true;
1469  return true;
1470 }
1471 
1472 DEF_CONSOLE_CMD(ConPart)
1473 {
1474  if (argc == 0) {
1475  IConsoleHelp("Leave the currently joined/running game (only ingame). Usage: 'part'");
1476  return true;
1477  }
1478 
1479  if (_game_mode != GM_NORMAL) return false;
1480 
1482  return true;
1483 }
1484 
1485 DEF_CONSOLE_CMD(ConHelp)
1486 {
1487  if (argc == 2) {
1488  const IConsoleCmd *cmd;
1489  const IConsoleAlias *alias;
1490 
1491  RemoveUnderscores(argv[1]);
1492  cmd = IConsoleCmdGet(argv[1]);
1493  if (cmd != nullptr) {
1494  cmd->proc(0, nullptr);
1495  return true;
1496  }
1497 
1498  alias = IConsoleAliasGet(argv[1]);
1499  if (alias != nullptr) {
1500  cmd = IConsoleCmdGet(alias->cmdline);
1501  if (cmd != nullptr) {
1502  cmd->proc(0, nullptr);
1503  return true;
1504  }
1505  IConsolePrintF(CC_ERROR, "ERROR: alias is of special type, please see its execution-line: '%s'", alias->cmdline);
1506  return true;
1507  }
1508 
1509  IConsoleError("command not found");
1510  return true;
1511  }
1512 
1513  IConsolePrint(CC_WARNING, " ---- OpenTTD Console Help ---- ");
1514  IConsolePrint(CC_DEFAULT, " - commands: [command to list all commands: list_cmds]");
1515  IConsolePrint(CC_DEFAULT, " call commands with '<command> <arg2> <arg3>...'");
1516  IConsolePrint(CC_DEFAULT, " - to assign strings, or use them as arguments, enclose it within quotes");
1517  IConsolePrint(CC_DEFAULT, " like this: '<command> \"string argument with spaces\"'");
1518  IConsolePrint(CC_DEFAULT, " - use 'help <command>' to get specific information");
1519  IConsolePrint(CC_DEFAULT, " - scroll console output with shift + (up | down | pageup | pagedown)");
1520  IConsolePrint(CC_DEFAULT, " - scroll console input history with the up or down arrows");
1522  return true;
1523 }
1524 
1525 DEF_CONSOLE_CMD(ConListCommands)
1526 {
1527  if (argc == 0) {
1528  IConsoleHelp("List all registered commands. Usage: 'list_cmds [<pre-filter>]'");
1529  return true;
1530  }
1531 
1532  for (const IConsoleCmd *cmd = _iconsole_cmds; cmd != nullptr; cmd = cmd->next) {
1533  if (argv[1] == nullptr || strstr(cmd->name, argv[1]) != nullptr) {
1534  if (cmd->hook == nullptr || cmd->hook(false) != CHR_HIDE) IConsolePrintF(CC_DEFAULT, "%s", cmd->name);
1535  }
1536  }
1537 
1538  return true;
1539 }
1540 
1541 DEF_CONSOLE_CMD(ConListAliases)
1542 {
1543  if (argc == 0) {
1544  IConsoleHelp("List all registered aliases. Usage: 'list_aliases [<pre-filter>]'");
1545  return true;
1546  }
1547 
1548  for (const IConsoleAlias *alias = _iconsole_aliases; alias != nullptr; alias = alias->next) {
1549  if (argv[1] == nullptr || strstr(alias->name, argv[1]) != nullptr) {
1550  IConsolePrintF(CC_DEFAULT, "%s => %s", alias->name, alias->cmdline);
1551  }
1552  }
1553 
1554  return true;
1555 }
1556 
1557 DEF_CONSOLE_CMD(ConCompanies)
1558 {
1559  if (argc == 0) {
1560  IConsoleHelp("List the details of all companies in the game. Usage 'companies'");
1561  return true;
1562  }
1563 
1564  for (const Company *c : Company::Iterate()) {
1565  /* Grab the company name */
1566  char company_name[512];
1567  SetDParam(0, c->index);
1568  GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
1569 
1570  const char *password_state = "";
1571  if (c->is_ai) {
1572  password_state = "AI";
1573  } else if (_network_server) {
1574  password_state = StrEmpty(_network_company_states[c->index].password) ? "unprotected" : "protected";
1575  }
1576 
1577  char colour[512];
1578  GetString(colour, STR_COLOUR_DARK_BLUE + _company_colours[c->index], lastof(colour));
1579  IConsolePrintF(CC_INFO, "#:%d(%s) Company Name: '%s' Year Founded: %d Money: " OTTD_PRINTF64 " Loan: " OTTD_PRINTF64 " Value: " OTTD_PRINTF64 " (T:%d, R:%d, P:%d, S:%d) %s",
1580  c->index + 1, colour, company_name,
1581  c->inaugurated_year, (int64)c->money, (int64)c->current_loan, (int64)CalculateCompanyValue(c),
1582  c->group_all[VEH_TRAIN].num_vehicle,
1583  c->group_all[VEH_ROAD].num_vehicle,
1584  c->group_all[VEH_AIRCRAFT].num_vehicle,
1585  c->group_all[VEH_SHIP].num_vehicle,
1586  password_state);
1587  }
1588 
1589  return true;
1590 }
1591 
1592 DEF_CONSOLE_CMD(ConSay)
1593 {
1594  if (argc == 0) {
1595  IConsoleHelp("Chat to your fellow players in a multiplayer game. Usage: 'say \"<msg>\"'");
1596  return true;
1597  }
1598 
1599  if (argc != 2) return false;
1600 
1601  if (!_network_server) {
1602  NetworkClientSendChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0 /* param does not matter */, argv[1]);
1603  } else {
1604  bool from_admin = (_redirect_console_to_admin < INVALID_ADMIN_ID);
1605  NetworkServerSendChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0, argv[1], CLIENT_ID_SERVER, from_admin);
1606  }
1607 
1608  return true;
1609 }
1610 
1611 DEF_CONSOLE_CMD(ConSayCompany)
1612 {
1613  if (argc == 0) {
1614  IConsoleHelp("Chat to a certain company in a multiplayer game. Usage: 'say_company <company-no> \"<msg>\"'");
1615  IConsoleHelp("CompanyNo is the company that plays as company <companyno>, 1 through max_companies");
1616  return true;
1617  }
1618 
1619  if (argc != 3) return false;
1620 
1621  CompanyID company_id = (CompanyID)(atoi(argv[1]) - 1);
1622  if (!Company::IsValidID(company_id)) {
1623  IConsolePrintF(CC_DEFAULT, "Unknown company. Company range is between 1 and %d.", MAX_COMPANIES);
1624  return true;
1625  }
1626 
1627  if (!_network_server) {
1628  NetworkClientSendChat(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, company_id, argv[2]);
1629  } else {
1630  bool from_admin = (_redirect_console_to_admin < INVALID_ADMIN_ID);
1631  NetworkServerSendChat(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, company_id, argv[2], CLIENT_ID_SERVER, from_admin);
1632  }
1633 
1634  return true;
1635 }
1636 
1637 DEF_CONSOLE_CMD(ConSayClient)
1638 {
1639  if (argc == 0) {
1640  IConsoleHelp("Chat to a certain client in a multiplayer game. Usage: 'say_client <client-no> \"<msg>\"'");
1641  IConsoleHelp("For client-id's, see the command 'clients'");
1642  return true;
1643  }
1644 
1645  if (argc != 3) return false;
1646 
1647  if (!_network_server) {
1648  NetworkClientSendChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2]);
1649  } else {
1650  bool from_admin = (_redirect_console_to_admin < INVALID_ADMIN_ID);
1651  NetworkServerSendChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2], CLIENT_ID_SERVER, from_admin);
1652  }
1653 
1654  return true;
1655 }
1656 
1657 DEF_CONSOLE_CMD(ConCompanyPassword)
1658 {
1659  if (argc == 0) {
1660  const char *helpmsg;
1661 
1662  if (_network_dedicated) {
1663  helpmsg = "Change the password of a company. Usage: 'company_pw <company-no> \"<password>\"";
1664  } else if (_network_server) {
1665  helpmsg = "Change the password of your or any other company. Usage: 'company_pw [<company-no>] \"<password>\"'";
1666  } else {
1667  helpmsg = "Change the password of your company. Usage: 'company_pw \"<password>\"'";
1668  }
1669 
1670  IConsoleHelp(helpmsg);
1671  IConsoleHelp("Use \"*\" to disable the password.");
1672  return true;
1673  }
1674 
1675  CompanyID company_id;
1676  const char *password;
1677  const char *errormsg;
1678 
1679  if (argc == 2) {
1680  company_id = _local_company;
1681  password = argv[1];
1682  errormsg = "You have to own a company to make use of this command.";
1683  } else if (argc == 3 && _network_server) {
1684  company_id = (CompanyID)(atoi(argv[1]) - 1);
1685  password = argv[2];
1686  errormsg = "You have to specify the ID of a valid human controlled company.";
1687  } else {
1688  return false;
1689  }
1690 
1691  if (!Company::IsValidHumanID(company_id)) {
1692  IConsoleError(errormsg);
1693  return false;
1694  }
1695 
1696  password = NetworkChangeCompanyPassword(company_id, password);
1697 
1698  if (StrEmpty(password)) {
1699  IConsolePrintF(CC_WARNING, "Company password cleared");
1700  } else {
1701  IConsolePrintF(CC_WARNING, "Company password changed to: %s", password);
1702  }
1703 
1704  return true;
1705 }
1706 
1707 /* Content downloading only is available with ZLIB */
1708 #if defined(WITH_ZLIB)
1709 #include "network/network_content.h"
1710 
1712 static ContentType StringToContentType(const char *str)
1713 {
1714  static const char * const inv_lookup[] = { "", "base", "newgrf", "ai", "ailib", "scenario", "heightmap" };
1715  for (uint i = 1 /* there is no type 0 */; i < lengthof(inv_lookup); i++) {
1716  if (strcasecmp(str, inv_lookup[i]) == 0) return (ContentType)i;
1717  }
1718  return CONTENT_TYPE_END;
1719 }
1720 
1723  void OnConnect(bool success)
1724  {
1725  IConsolePrintF(CC_DEFAULT, "Content server connection %s", success ? "established" : "failed");
1726  }
1727 
1729  {
1730  IConsolePrintF(CC_DEFAULT, "Content server connection closed");
1731  }
1732 
1734  {
1735  IConsolePrintF(CC_DEFAULT, "Completed download of %d", cid);
1736  }
1737 };
1738 
1743 static void OutputContentState(const ContentInfo *const ci)
1744 {
1745  static const char * const types[] = { "Base graphics", "NewGRF", "AI", "AI library", "Scenario", "Heightmap", "Base sound", "Base music", "Game script", "GS library" };
1746  assert_compile(lengthof(types) == CONTENT_TYPE_END - CONTENT_TYPE_BEGIN);
1747  static const char * const states[] = { "Not selected", "Selected", "Dep Selected", "Installed", "Unknown" };
1748  static const TextColour state_to_colour[] = { CC_COMMAND, CC_INFO, CC_INFO, CC_WHITE, CC_ERROR };
1749 
1750  char buf[sizeof(ci->md5sum) * 2 + 1];
1751  md5sumToString(buf, lastof(buf), ci->md5sum);
1752  IConsolePrintF(state_to_colour[ci->state], "%d, %s, %s, %s, %08X, %s", ci->id, types[ci->type - 1], states[ci->state], ci->name, ci->unique_id, buf);
1753 }
1754 
1755 DEF_CONSOLE_CMD(ConContent)
1756 {
1757  static ContentCallback *cb = nullptr;
1758  if (cb == nullptr) {
1759  cb = new ConsoleContentCallback();
1761  }
1762 
1763  if (argc <= 1) {
1764  IConsoleHelp("Query, select and download content. Usage: 'content update|upgrade|select [all|id]|unselect [all|id]|state [filter]|download'");
1765  IConsoleHelp(" update: get a new list of downloadable content; must be run first");
1766  IConsoleHelp(" upgrade: select all items that are upgrades");
1767  IConsoleHelp(" select: select a specific item given by its id or 'all' to select all. If no parameter is given, all selected content will be listed");
1768  IConsoleHelp(" unselect: unselect a specific item given by its id or 'all' to unselect all");
1769  IConsoleHelp(" state: show the download/select state of all downloadable content. Optionally give a filter string");
1770  IConsoleHelp(" download: download all content you've selected");
1771  return true;
1772  }
1773 
1774  if (strcasecmp(argv[1], "update") == 0) {
1776  return true;
1777  }
1778 
1779  if (strcasecmp(argv[1], "upgrade") == 0) {
1781  return true;
1782  }
1783 
1784  if (strcasecmp(argv[1], "select") == 0) {
1785  if (argc <= 2) {
1786  /* List selected content */
1787  IConsolePrintF(CC_WHITE, "id, type, state, name");
1789  if ((*iter)->state != ContentInfo::SELECTED && (*iter)->state != ContentInfo::AUTOSELECTED) continue;
1790  OutputContentState(*iter);
1791  }
1792  } else if (strcasecmp(argv[2], "all") == 0) {
1794  } else {
1795  _network_content_client.Select((ContentID)atoi(argv[2]));
1796  }
1797  return true;
1798  }
1799 
1800  if (strcasecmp(argv[1], "unselect") == 0) {
1801  if (argc <= 2) {
1802  IConsoleError("You must enter the id.");
1803  return false;
1804  }
1805  if (strcasecmp(argv[2], "all") == 0) {
1807  } else {
1808  _network_content_client.Unselect((ContentID)atoi(argv[2]));
1809  }
1810  return true;
1811  }
1812 
1813  if (strcasecmp(argv[1], "state") == 0) {
1814  IConsolePrintF(CC_WHITE, "id, type, state, name");
1816  if (argc > 2 && strcasestr((*iter)->name, argv[2]) == nullptr) continue;
1817  OutputContentState(*iter);
1818  }
1819  return true;
1820  }
1821 
1822  if (strcasecmp(argv[1], "download") == 0) {
1823  uint files;
1824  uint bytes;
1826  IConsolePrintF(CC_DEFAULT, "Downloading %d file(s) (%d bytes)", files, bytes);
1827  return true;
1828  }
1829 
1830  return false;
1831 }
1832 #endif /* defined(WITH_ZLIB) */
1833 
1834 DEF_CONSOLE_CMD(ConSetting)
1835 {
1836  if (argc == 0) {
1837  IConsoleHelp("Change setting for all clients. Usage: 'setting <name> [<value>]'");
1838  IConsoleHelp("Omitting <value> will print out the current value of the setting.");
1839  return true;
1840  }
1841 
1842  if (argc == 1 || argc > 3) return false;
1843 
1844  if (argc == 2) {
1845  IConsoleGetSetting(argv[1]);
1846  } else {
1847  IConsoleSetSetting(argv[1], argv[2]);
1848  }
1849 
1850  return true;
1851 }
1852 
1853 DEF_CONSOLE_CMD(ConSettingNewgame)
1854 {
1855  if (argc == 0) {
1856  IConsoleHelp("Change setting for the next game. Usage: 'setting_newgame <name> [<value>]'");
1857  IConsoleHelp("Omitting <value> will print out the current value of the setting.");
1858  return true;
1859  }
1860 
1861  if (argc == 1 || argc > 3) return false;
1862 
1863  if (argc == 2) {
1864  IConsoleGetSetting(argv[1], true);
1865  } else {
1866  IConsoleSetSetting(argv[1], argv[2], true);
1867  }
1868 
1869  return true;
1870 }
1871 
1872 DEF_CONSOLE_CMD(ConListSettings)
1873 {
1874  if (argc == 0) {
1875  IConsoleHelp("List settings. Usage: 'list_settings [<pre-filter>]'");
1876  return true;
1877  }
1878 
1879  if (argc > 2) return false;
1880 
1881  IConsoleListSettings((argc == 2) ? argv[1] : nullptr);
1882  return true;
1883 }
1884 
1885 DEF_CONSOLE_CMD(ConGamelogPrint)
1886 {
1888  return true;
1889 }
1890 
1891 DEF_CONSOLE_CMD(ConNewGRFReload)
1892 {
1893  if (argc == 0) {
1894  IConsoleHelp("Reloads all active NewGRFs from disk. Equivalent to reapplying NewGRFs via the settings, but without asking for confirmation. This might crash OpenTTD!");
1895  return true;
1896  }
1897 
1898  ReloadNewGRFData();
1899  return true;
1900 }
1901 
1902 DEF_CONSOLE_CMD(ConNewGRFProfile)
1903 {
1904  if (argc == 0) {
1905  IConsoleHelp("Collect performance data about NewGRF sprite requests and callbacks. Sub-commands can be abbreviated.");
1906  IConsoleHelp("Usage: newgrf_profile [list]");
1907  IConsoleHelp(" List all NewGRFs that can be profiled, and their status.");
1908  IConsoleHelp("Usage: newgrf_profile select <grf-num>...");
1909  IConsoleHelp(" Select one or more GRFs for profiling.");
1910  IConsoleHelp("Usage: newgrf_profile unselect <grf-num>...");
1911  IConsoleHelp(" Unselect one or more GRFs from profiling. Use the keyword \"all\" instead of a GRF number to unselect all. Removing an active profiler aborts data collection.");
1912  IConsoleHelp("Usage: newgrf_profile start [<num-days>]");
1913  IConsoleHelp(" Begin profiling all selected GRFs. If a number of days is provided, profiling stops after that many in-game days.");
1914  IConsoleHelp("Usage: newgrf_profile stop");
1915  IConsoleHelp(" End profiling and write the collected data to CSV files.");
1916  IConsoleHelp("Usage: newgrf_profile abort");
1917  IConsoleHelp(" End profiling and discard all collected data.");
1918  return true;
1919  }
1920 
1921  extern const std::vector<GRFFile *> &GetAllGRFFiles();
1922  const std::vector<GRFFile *> &files = GetAllGRFFiles();
1923 
1924  /* "list" sub-command */
1925  if (argc == 1 || strncasecmp(argv[1], "lis", 3) == 0) {
1926  IConsolePrint(CC_INFO, "Loaded GRF files:");
1927  int i = 1;
1928  for (GRFFile *grf : files) {
1929  auto profiler = std::find_if(_newgrf_profilers.begin(), _newgrf_profilers.end(), [&](NewGRFProfiler &pr) { return pr.grffile == grf; });
1930  bool selected = profiler != _newgrf_profilers.end();
1931  bool active = selected && profiler->active;
1932  TextColour tc = active ? TC_LIGHT_BLUE : selected ? TC_GREEN : CC_INFO;
1933  const char *statustext = active ? " (active)" : selected ? " (selected)" : "";
1934  IConsolePrintF(tc, "%d: [%08X] %s%s", i, BSWAP32(grf->grfid), grf->filename, statustext);
1935  i++;
1936  }
1937  return true;
1938  }
1939 
1940  /* "select" sub-command */
1941  if (strncasecmp(argv[1], "sel", 3) == 0 && argc >= 3) {
1942  for (size_t argnum = 2; argnum < argc; ++argnum) {
1943  int grfnum = atoi(argv[argnum]);
1944  if (grfnum < 1 || grfnum > (int)files.size()) { // safe cast, files.size() should not be larger than a few hundred in the most extreme cases
1945  IConsolePrintF(CC_WARNING, "GRF number %d out of range, not added.", grfnum);
1946  continue;
1947  }
1948  GRFFile *grf = files[grfnum - 1];
1949  if (std::any_of(_newgrf_profilers.begin(), _newgrf_profilers.end(), [&](NewGRFProfiler &pr) { return pr.grffile == grf; })) {
1950  IConsolePrintF(CC_WARNING, "GRF number %d [%08X] is already selected for profiling.", grfnum, BSWAP32(grf->grfid));
1951  continue;
1952  }
1953  _newgrf_profilers.emplace_back(grf);
1954  }
1955  return true;
1956  }
1957 
1958  /* "unselect" sub-command */
1959  if (strncasecmp(argv[1], "uns", 3) == 0 && argc >= 3) {
1960  for (size_t argnum = 2; argnum < argc; ++argnum) {
1961  if (strcasecmp(argv[argnum], "all") == 0) {
1962  _newgrf_profilers.clear();
1963  break;
1964  }
1965  int grfnum = atoi(argv[argnum]);
1966  if (grfnum < 1 || grfnum > (int)files.size()) {
1967  IConsolePrintF(CC_WARNING, "GRF number %d out of range, not removing.", grfnum);
1968  continue;
1969  }
1970  GRFFile *grf = files[grfnum - 1];
1971  auto pos = std::find_if(_newgrf_profilers.begin(), _newgrf_profilers.end(), [&](NewGRFProfiler &pr) { return pr.grffile == grf; });
1972  if (pos != _newgrf_profilers.end()) _newgrf_profilers.erase(pos);
1973  }
1974  return true;
1975  }
1976 
1977  /* "start" sub-command */
1978  if (strncasecmp(argv[1], "sta", 3) == 0) {
1979  std::string grfids;
1980  size_t started = 0;
1981  for (NewGRFProfiler &pr : _newgrf_profilers) {
1982  if (!pr.active) {
1983  pr.Start();
1984  started++;
1985 
1986  if (!grfids.empty()) grfids += ", ";
1987  char grfidstr[12]{ 0 };
1988  seprintf(grfidstr, lastof(grfidstr), "[%08X]", BSWAP32(pr.grffile->grfid));
1989  grfids += grfidstr;
1990  }
1991  }
1992  if (started > 0) {
1993  IConsolePrintF(CC_DEBUG, "Started profiling for GRFID%s %s", (started > 1) ? "s" : "", grfids.c_str());
1994  if (argc >= 3) {
1995  int days = max(atoi(argv[2]), 1);
1996  _newgrf_profile_end_date = _date + days;
1997 
1998  char datestrbuf[32]{ 0 };
1999  SetDParam(0, _newgrf_profile_end_date);
2000  GetString(datestrbuf, STR_JUST_DATE_ISO, lastof(datestrbuf));
2001  IConsolePrintF(CC_DEBUG, "Profiling will automatically stop on game date %s", datestrbuf);
2002  } else {
2003  _newgrf_profile_end_date = MAX_DAY;
2004  }
2005  } else if (_newgrf_profilers.empty()) {
2006  IConsolePrintF(CC_WARNING, "No GRFs selected for profiling, did not start.");
2007  } else {
2008  IConsolePrintF(CC_WARNING, "Did not start profiling for any GRFs, all selected GRFs are already profiling.");
2009  }
2010  return true;
2011  }
2012 
2013  /* "stop" sub-command */
2014  if (strncasecmp(argv[1], "sto", 3) == 0) {
2015  NewGRFProfiler::FinishAll();
2016  return true;
2017  }
2018 
2019  /* "abort" sub-command */
2020  if (strncasecmp(argv[1], "abo", 3) == 0) {
2021  for (NewGRFProfiler &pr : _newgrf_profilers) {
2022  pr.Abort();
2023  }
2024  _newgrf_profile_end_date = MAX_DAY;
2025  return true;
2026  }
2027 
2028  return false;
2029 }
2030 
2031 #ifdef _DEBUG
2032 /******************
2033  * debug commands
2034  ******************/
2035 
2036 static void IConsoleDebugLibRegister()
2037 {
2038  IConsoleCmdRegister("resettile", ConResetTile);
2039  IConsoleAliasRegister("dbg_echo", "echo %A; echo %B");
2040  IConsoleAliasRegister("dbg_echo2", "echo %!");
2041 }
2042 #endif
2043 
2044 DEF_CONSOLE_CMD(ConFramerate)
2045 {
2046  extern void ConPrintFramerate(); // framerate_gui.cpp
2047 
2048  if (argc == 0) {
2049  IConsoleHelp("Show frame rate and game speed information");
2050  return true;
2051  }
2052 
2054  return true;
2055 }
2056 
2057 DEF_CONSOLE_CMD(ConFramerateWindow)
2058 {
2059  extern void ShowFramerateWindow();
2060 
2061  if (argc == 0) {
2062  IConsoleHelp("Open the frame rate window");
2063  return true;
2064  }
2065 
2066  if (_network_dedicated) {
2067  IConsoleError("Can not open frame rate window on a dedicated server");
2068  return false;
2069  }
2070 
2072  return true;
2073 }
2074 
2075 /*******************************
2076  * console command registration
2077  *******************************/
2078 
2079 void IConsoleStdLibRegister()
2080 {
2081  IConsoleCmdRegister("debug_level", ConDebugLevel);
2082  IConsoleCmdRegister("echo", ConEcho);
2083  IConsoleCmdRegister("echoc", ConEchoC);
2084  IConsoleCmdRegister("exec", ConExec);
2085  IConsoleCmdRegister("exit", ConExit);
2086  IConsoleCmdRegister("part", ConPart);
2087  IConsoleCmdRegister("help", ConHelp);
2088  IConsoleCmdRegister("info_cmd", ConInfoCmd);
2089  IConsoleCmdRegister("list_cmds", ConListCommands);
2090  IConsoleCmdRegister("list_aliases", ConListAliases);
2091  IConsoleCmdRegister("newgame", ConNewGame);
2092  IConsoleCmdRegister("restart", ConRestart);
2093  IConsoleCmdRegister("getseed", ConGetSeed);
2094  IConsoleCmdRegister("getdate", ConGetDate);
2095  IConsoleCmdRegister("getsysdate", ConGetSysDate);
2096  IConsoleCmdRegister("quit", ConExit);
2097  IConsoleCmdRegister("resetengines", ConResetEngines, ConHookNoNetwork);
2098  IConsoleCmdRegister("reset_enginepool", ConResetEnginePool, ConHookNoNetwork);
2099  IConsoleCmdRegister("return", ConReturn);
2100  IConsoleCmdRegister("screenshot", ConScreenShot);
2101  IConsoleCmdRegister("script", ConScript);
2102  IConsoleCmdRegister("scrollto", ConScrollToTile);
2103  IConsoleCmdRegister("alias", ConAlias);
2104  IConsoleCmdRegister("load", ConLoad);
2105  IConsoleCmdRegister("rm", ConRemove);
2106  IConsoleCmdRegister("save", ConSave);
2107  IConsoleCmdRegister("saveconfig", ConSaveConfig);
2108  IConsoleCmdRegister("ls", ConListFiles);
2109  IConsoleCmdRegister("cd", ConChangeDirectory);
2110  IConsoleCmdRegister("pwd", ConPrintWorkingDirectory);
2111  IConsoleCmdRegister("clear", ConClearBuffer);
2112  IConsoleCmdRegister("setting", ConSetting);
2113  IConsoleCmdRegister("setting_newgame", ConSettingNewgame);
2114  IConsoleCmdRegister("list_settings",ConListSettings);
2115  IConsoleCmdRegister("gamelog", ConGamelogPrint);
2116  IConsoleCmdRegister("rescan_newgrf", ConRescanNewGRF);
2117 
2118  IConsoleAliasRegister("dir", "ls");
2119  IConsoleAliasRegister("del", "rm %+");
2120  IConsoleAliasRegister("newmap", "newgame");
2121  IConsoleAliasRegister("patch", "setting %+");
2122  IConsoleAliasRegister("set", "setting %+");
2123  IConsoleAliasRegister("set_newgame", "setting_newgame %+");
2124  IConsoleAliasRegister("list_patches", "list_settings %+");
2125  IConsoleAliasRegister("developer", "setting developer %+");
2126 
2127  IConsoleCmdRegister("list_ai_libs", ConListAILibs);
2128  IConsoleCmdRegister("list_ai", ConListAI);
2129  IConsoleCmdRegister("reload_ai", ConReloadAI);
2130  IConsoleCmdRegister("rescan_ai", ConRescanAI);
2131  IConsoleCmdRegister("start_ai", ConStartAI);
2132  IConsoleCmdRegister("stop_ai", ConStopAI);
2133 
2134  IConsoleCmdRegister("list_game", ConListGame);
2135  IConsoleCmdRegister("list_game_libs", ConListGameLibs);
2136  IConsoleCmdRegister("rescan_game", ConRescanGame);
2137 
2138  IConsoleCmdRegister("companies", ConCompanies);
2139  IConsoleAliasRegister("players", "companies");
2140 
2141  /* networking functions */
2142 
2143 /* Content downloading is only available with ZLIB */
2144 #if defined(WITH_ZLIB)
2145  IConsoleCmdRegister("content", ConContent);
2146 #endif /* defined(WITH_ZLIB) */
2147 
2148  /*** Networking commands ***/
2149  IConsoleCmdRegister("say", ConSay, ConHookNeedNetwork);
2150  IConsoleCmdRegister("say_company", ConSayCompany, ConHookNeedNetwork);
2151  IConsoleAliasRegister("say_player", "say_company %+");
2152  IConsoleCmdRegister("say_client", ConSayClient, ConHookNeedNetwork);
2153 
2154  IConsoleCmdRegister("connect", ConNetworkConnect, ConHookClientOnly);
2155  IConsoleCmdRegister("clients", ConNetworkClients, ConHookNeedNetwork);
2156  IConsoleCmdRegister("status", ConStatus, ConHookServerOnly);
2157  IConsoleCmdRegister("server_info", ConServerInfo, ConHookServerOnly);
2158  IConsoleAliasRegister("info", "server_info");
2159  IConsoleCmdRegister("reconnect", ConNetworkReconnect, ConHookClientOnly);
2160  IConsoleCmdRegister("rcon", ConRcon, ConHookNeedNetwork);
2161 
2162  IConsoleCmdRegister("join", ConJoinCompany, ConHookNeedNetwork);
2163  IConsoleAliasRegister("spectate", "join 255");
2164  IConsoleCmdRegister("move", ConMoveClient, ConHookServerOnly);
2165  IConsoleCmdRegister("reset_company", ConResetCompany, ConHookServerOnly);
2166  IConsoleAliasRegister("clean_company", "reset_company %A");
2167  IConsoleCmdRegister("client_name", ConClientNickChange, ConHookServerOnly);
2168  IConsoleCmdRegister("kick", ConKick, ConHookServerOnly);
2169  IConsoleCmdRegister("ban", ConBan, ConHookServerOnly);
2170  IConsoleCmdRegister("unban", ConUnBan, ConHookServerOnly);
2171  IConsoleCmdRegister("banlist", ConBanList, ConHookServerOnly);
2172 
2173  IConsoleCmdRegister("pause", ConPauseGame, ConHookServerOnly);
2174  IConsoleCmdRegister("unpause", ConUnpauseGame, ConHookServerOnly);
2175 
2176  IConsoleCmdRegister("company_pw", ConCompanyPassword, ConHookNeedNetwork);
2177  IConsoleAliasRegister("company_password", "company_pw %+");
2178 
2179  IConsoleAliasRegister("net_frame_freq", "setting frame_freq %+");
2180  IConsoleAliasRegister("net_sync_freq", "setting sync_freq %+");
2181  IConsoleAliasRegister("server_pw", "setting server_password %+");
2182  IConsoleAliasRegister("server_password", "setting server_password %+");
2183  IConsoleAliasRegister("rcon_pw", "setting rcon_password %+");
2184  IConsoleAliasRegister("rcon_password", "setting rcon_password %+");
2185  IConsoleAliasRegister("name", "setting client_name %+");
2186  IConsoleAliasRegister("server_name", "setting server_name %+");
2187  IConsoleAliasRegister("server_port", "setting server_port %+");
2188  IConsoleAliasRegister("server_advertise", "setting server_advertise %+");
2189  IConsoleAliasRegister("max_clients", "setting max_clients %+");
2190  IConsoleAliasRegister("max_companies", "setting max_companies %+");
2191  IConsoleAliasRegister("max_spectators", "setting max_spectators %+");
2192  IConsoleAliasRegister("max_join_time", "setting max_join_time %+");
2193  IConsoleAliasRegister("pause_on_join", "setting pause_on_join %+");
2194  IConsoleAliasRegister("autoclean_companies", "setting autoclean_companies %+");
2195  IConsoleAliasRegister("autoclean_protected", "setting autoclean_protected %+");
2196  IConsoleAliasRegister("autoclean_unprotected", "setting autoclean_unprotected %+");
2197  IConsoleAliasRegister("restart_game_year", "setting restart_game_year %+");
2198  IConsoleAliasRegister("min_players", "setting min_active_clients %+");
2199  IConsoleAliasRegister("reload_cfg", "setting reload_cfg %+");
2200 
2201  /* debugging stuff */
2202 #ifdef _DEBUG
2203  IConsoleDebugLibRegister();
2204 #endif
2205  IConsoleCmdRegister("fps", ConFramerate);
2206  IConsoleCmdRegister("fps_wnd", ConFramerateWindow);
2207 
2208  /* NewGRF development stuff */
2209  IConsoleCmdRegister("reload_newgrfs", ConNewGRFReload, ConHookNewGRFDeveloperTool);
2210  IConsoleCmdRegister("newgrf_profile", ConNewGRFProfile, ConHookNewGRFDeveloperTool);
2211 }
AISettings ai
what may the AI do?
World screenshot.
Definition: screenshot.h:23
Functions related to OTTD&#39;s strings.
Helper to mark the end of the types.
Definition: tcp_content.h:33
Owner
Enum for all companies/owners.
Definition: company_type.h:18
static void OutputContentState(const ContentInfo *const ci)
Outputs content state information to console.
Send message/notice to all clients (All)
Definition: network_type.h:82
const ContentInfo *const * ConstContentIterator
Iterator for the constant content vector.
static uint MapSizeX()
Get the size of the map along the X.
Definition: map_func.h:72
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:80
used in multiplayer to create a new companies etc.
Definition: command_type.h:280
void IConsoleGetSetting(const char *name, bool force_newgame)
Output value of a specific setting to the console.
Definition: settings.cpp:2144
IConsoleCmd * next
next command in list
void IConsoleWarning(const char *string)
It is possible to print warnings to the console.
Definition: console.cpp:158
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:461
bool _networking
are we in networking mode?
Definition: network.cpp:52
void DownloadSelectedContent(uint &files, uint &bytes, bool fallback=false)
Actually begin downloading the content we selected.
char *CDECL str_fmt(const char *str,...)
Format, "printf", into a newly allocated string.
Definition: string.cpp:149
ConstContentIterator Begin() const
Get the begin of the content inf iterator.
static void PrintLineByLine(char *buf)
Print a text buffer line by line to the console.
static uint MapSizeY()
Get the size of the map along the Y.
Definition: map_func.h:82
Profiling of NewGRF action 2 handling.
Container for all information known about a client.
Definition: network_base.h:23
IConsoleCmd * _iconsole_cmds
list of registered commands
Definition: console.cpp:27
uint32 unique_id
Unique ID; either GRF ID or shortname.
Definition: tcp_content.h:73
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3218
uint16 last_port
port of the last joined server
void FioFCloseFile(FILE *f)
Close a file in a safe way.
Definition: fileio.cpp:333
void NetworkServerShowStatusToConsole()
Show the status message of all clients on the console.
void Clear()
Remove all items from the list.
Definition: fios.h:186
Train vehicle type.
Definition: vehicle_type.h:24
Switch to game intro menu.
Definition: openttd.h:30
void SetName(const char *name)
Set the name of the file.
Definition: saveload.cpp:2892
Functions related to dates.
Day day
Day (1..31)
Definition: date_type.h:106
std::vector< FiosItem > files
The list of files.
Definition: fios.h:200
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
Definition: string.cpp:407
Load game, Play Scenario.
Definition: openttd.h:29
static uint MapLogX()
Logarithm of the map size along the X side.
Definition: map_func.h:51
Functions related to debugging.
bool NetworkCompanyHasClients(CompanyID company)
Check whether a particular company has clients.
Callbacks for notifying others about incoming data.
Ship vehicle type.
Definition: vehicle_type.h:26
static char * GetConsoleList(char *p, const char *last, bool newest_only=false)
Wrapper function for AIScanner::GetAIConsoleList.
Definition: ai_core.cpp:318
Functions to be called to log possibly unsafe game events.
ClientID client_id
Client identifier (same as ClientState->client_id)
Definition: network_base.h:24
size_t Length() const
Get the number of files in the list.
Definition: fios.h:130
FileToSaveLoad _file_to_saveload
File to save or load in the openttd loop.
Definition: saveload.cpp:58
The company is manually removed.
Definition: company_type.h:56
The client wants a new company.
Definition: company_type.h:34
Screenshot of viewport.
Definition: screenshot.h:19
char * md5sumToString(char *buf, const char *last, const uint8 md5sum[16])
Convert the md5sum to a hexadecimal string representation.
Definition: string.cpp:425
void IConsoleListSettings(const char *prefilter)
List all settings and their value to the console.
Definition: settings.cpp:2177
static bool IsHumanID(size_t index)
Is this company a company not controlled by a NoAI program?
Definition: company_base.h:163
Client part of the network protocol.
void Change(const char *name, int version=-1, bool force_exact_match=false, bool is_random=false)
Set another Script to be loaded in this slot.
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:60
void NetworkClientRequestMove(CompanyID company_id, const char *pass)
Notify the server of this client wanting to be moved to another company.
void OnDownloadComplete(ContentID cid)
We have finished downloading a file.
void NetworkServerDoMove(ClientID client_id, CompanyID company_id)
Handle the tid-bits of moving a client from one company to another.
void OnConnect(bool success)
Callback for when the connection has finished.
static const AdminIndex INVALID_ADMIN_ID
An invalid admin marker.
Definition: network_type.h:54
Functions for Standard In/Out file operations.
Send message/notice to only a certain client (Private)
Definition: network_type.h:84
The content has been selected as dependency.
Definition: tcp_content.h:59
void DoExitSave()
Do a save when exiting the game (_settings_client.gui.autosave_on_exit)
Definition: saveload.cpp:2820
IConsoleCmdProc * proc
process executed when command is typed
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:48
char * name
name of command
static ContentType StringToContentType(const char *str)
Resolve a string to a content type.
static const TextColour CC_DEFAULT
Default colour of the console.
Definition: console_type.h:23
IConsoleAlias * _iconsole_aliases
list of registered aliases
Definition: console.cpp:28
bool NetworkCompanyIsPassworded(CompanyID company_id)
Check if the company we want to join requires a password.
Definition: network.cpp:213
Functions related to world/map generation.
Functions to make screenshots.
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).
AdminIndex _redirect_console_to_admin
Redirection of the (remote) console to the admin.
ClientID
&#39;Unique&#39; identifier to be given to clients
Definition: network_type.h:39
static bool _script_running
Script is running (used to abort execution when #ConReturn is encountered).
void SaveToConfig()
Save the values to the configuration file.
Definition: settings.cpp:1750
uint8 map_x
X size of map.
static T max(const T a, const T b)
Returns the maximum of two values.
Definition: math_func.hpp:24
ContentID
Unique identifier for the content.
Definition: tcp_content.h:49
Fully zoomed in screenshot of the visible area.
Definition: screenshot.h:21
Asynchronous callback.
File is being saved.
Definition: fileio_type.h:50
Deals with finding savegames.
Definition: fios.h:103
Hide the existence of the command.
static const uint32 GENERATE_NEW_SEED
Create a new random seed.
Definition: genworld.h:24
StringID FiosGetDescText(const char **path, uint64 *total_free)
Get descriptive texts.
Definition: fios.cpp:139
void OnDisconnect()
Callback for when the connection got disconnected.
static bool IsValidHumanID(size_t index)
Is this company a valid company, not controlled by a NoAI program?
Definition: company_base.h:150
bool _network_available
is network mode available?
Definition: network.cpp:54
void Unselect(ContentID cid)
Unselect a specific content id.
bool _network_dedicated
are we a dedicated server?
Definition: network.cpp:55
Console; Window numbers:
Definition: window_type.h:631
const FiosItem * FindItem(const char *file)
Find file information of a file by its name from the file list.
Definition: fios.cpp:106
static char * GetConsoleList(char *p, const char *last, bool newest_only=false)
Wrapper function for GameScanner::GetConsoleList.
Definition: game_core.cpp:228
Functions related to (drawing on) viewports.
uint8 map_y
Y size of map.
void UnselectAll()
Unselect everything that we&#39;ve not downloaded so far.
Save game or scenario file.
Definition: fileio_type.h:31
static const size_t MAX_SIZE
Make template parameter accessible from outside.
Definition: pool_type.hpp:85
old or new savegame
Definition: fileio_type.h:18
static ConsoleFileList _console_file_list
File storage cache for the console.
void StartNewGameWithoutGUI(uint32 seed)
Start a normal game without the GUI.
char password[NETWORK_PASSWORD_LENGTH]
The password for the company.
Definition: network_type.h:65
static bool IsConnected()
Check whether the client is actually connected (and in the game).
char name[32]
Name of the content.
Definition: tcp_content.h:69
NetworkSettings network
settings related to the network
void AddCallback(ContentCallback *cb)
Add a callback to this class.
Internally used functions for the console.
void SetTitle(const char *title)
Set the title of the file.
Definition: saveload.cpp:2901
Functions/types related to saving and loading games.
CompanyID client_playas
As which company is this client playing (CompanyID)
Definition: network_base.h:27
ConstContentIterator End() const
Get the end of the content inf iterator.
void GamelogPrintConsole()
Print the gamelog data to the console.
Definition: gamelog.cpp:350
static char * GetConsoleLibraryList(char *p, const char *last)
Wrapper function for GameScanner::GetConsoleLibraryList.
Definition: game_core.cpp:233
IConsoleAlias * next
next alias in list
A normal unpaused game.
Definition: openttd.h:56
The client is spectating.
Definition: company_type.h:35
void SelectUpgrade()
Select everything that&#39;s an update for something we&#39;ve got.
Functions related to engines.
uint8 max_spectators
maximum amount of spectators
bool HasScript() const
Is this config attached to an Script? In other words, is there a Script that is assigned to this slot...
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:85
IConsoleCmd * IConsoleCmdGet(const char *name)
Find the command pointed to by its string.
Definition: console.cpp:265
File list storage for the console, for caching the last &#39;ls&#39; command.
Allow command execution.
Create a new AI company.
Definition: company_type.h:66
Functions related to setting/changing the settings.
ClientID _network_own_client_id
Our client identifier.
Definition: network.cpp:59
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:79
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:464
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:125
Definition of base types and functions in a cross-platform compatible way.
static const TextColour CC_DEBUG
Colour for debug output.
Definition: console_type.h:27
Data structure to convert between Date and triplet (year, month, and day).
Definition: date_type.h:103
A number of safeguards to prevent using unsafe methods.
ContentID id
Unique (server side) ID for the content.
Definition: tcp_content.h:66
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition: gfx_type.h:245
NetworkCompanyState * _network_company_states
Statistics about some companies.
Definition: network.cpp:58
void ShowFramerateWindow()
Open the general framerate window.
Base directory for all savegames.
Definition: fileio_type.h:110
Base directory for all subdirectories.
Definition: fileio_type.h:109
void BuildFileList(AbstractFileType abstract_filetype, SaveLoadOperation fop)
Construct a file list with the given kind of files, for the stated purpose.
Definition: fios.cpp:74
static AIConfig * GetConfig(CompanyID company, ScriptSettingSource source=SSS_DEFAULT)
Get the config of a company.
Definition: ai_config.cpp:45
void NetworkPrintClients()
Print all the clients to the console.
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
Definition: string.cpp:136
Console functions used outside of the console code.
void RequestContentList(ContentType type)
Request the content list for the given type.
State state
Whether the content info is selected (for download)
Definition: tcp_content.h:79
void ConPrintFramerate()
Print performance statistics to game console.
Money CalculateCompanyValue(const Company *c, bool including_loan=true)
Calculate the value of the company.
Definition: economy.cpp:111
static void IConsoleHelp(const char *str)
Show help for the console.
byte clients_on
Current count of clients on server.
Definition: game.h:26
bool autosave_on_exit
save an autosave when you quit the game, but do not ask "Do you really want to quit?"
Year year
Year (0...)
Definition: date_type.h:104
void InvalidateFileList()
Declare the file storage cache as being invalid, also clears all stored files.
A game normally paused.
Definition: openttd.h:57
const char * GetDebugString()
Print out the current debug-level.
Definition: debug.cpp:226
AbstractFileType GetAbstractFileType(FiosType fios_type)
Extract the abstract file type from a FiosType.
Definition: fileio_type.h:90
Basic functions/variables used all over the place.
Part of the network protocol handling content distribution.
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:2733
bool DoCommandP(const CommandContainer *container, bool my_cmd)
Shortcut for the long DoCommandP when having a container with the data.
Definition: command.cpp:536
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:40
NetworkServerGameInfo _network_game_info
Information about our game.
Definition: network.cpp:57
File is being loaded.
Definition: fileio_type.h:49
Callback profiler for NewGRF development.
PauseMode _pause_mode
The current pause mode.
Definition: gfx.cpp:47
Delete a company.
Definition: company_type.h:67
Month month
Month (0..11)
Definition: date_type.h:105
byte md5sum[16]
The MD5 checksum.
Definition: tcp_content.h:74
static const TextColour CC_COMMAND
Colour for the console&#39;s commands.
Definition: console_type.h:28
IConsoleAlias * IConsoleAliasGet(const char *name)
Find the alias pointed to by its string.
Definition: console.cpp:303
uint8 max_companies
maximum amount of companies
char * RemoveUnderscores(char *name)
Remove underscores from a string; the string will be modified!
Definition: console.cpp:234
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:137
bool MakeScreenshot(ScreenshotType t, const char *name)
Make an actual screenshot.
Definition: screenshot.cpp:840
uint8 FindFirstBit(uint32 x)
Search the first set bit in a 32 bit variable.
bool newgrf_developer_tools
activate NewGRF developer tools and allow modifying NewGRFs in an existing game
ContentType
The values in the enum are important; they are used as database &#39;keys&#39;.
Definition: tcp_content.h:21
bool NetworkServerChangeClientName(ClientID client_id, const char *new_name)
Change the client name of the given client.
void NetworkServerKickClient(ClientID client_id, const char *reason)
Kick a single client.
bool FiosDelete(const char *name)
Delete a file.
Definition: fios.cpp:253
void StartupEngines()
Start/initialise all our engines.
Definition: engine.cpp:693
void Select(ContentID cid)
Select a specific content id.
Functions related to companies.
An invalid company.
Definition: company_type.h:30
static uint MapSize()
Get the size of the map.
Definition: map_func.h:92
void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const char *msg, ClientID from_id, int64 data=0, bool from_admin=false)
Send an actual chat message.
static const uint16 NETWORK_DEFAULT_PORT
The default port of the game server (TCP & UDP)
Definition: config.h:29
Base class for engines.
void SelectAll()
Select everything we can select.
uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason)
Ban, or kick, everyone joined from the given client&#39;s IP.
uint32 generation_seed
noise seed for world generation
GUISettings gui
settings related to the GUI
–Aliases– Aliases are like shortcuts for complex functions, variable assignments, etc.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:378
static bool ResetToCurrentNewGRFConfig()
Tries to reset the engine mapping to match the current NewGRF configuration.
Definition: engine.cpp:527
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:57
Declarations for savegames operations.
void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
Execute a given command passed to us.
Definition: console.cpp:407
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
void IConsoleAliasRegister(const char *name, const char *cmd)
Register a an alias for an already existing command in the console.
Definition: console.cpp:280
static size_t GetNumItems()
Returns number of valid items in the pool.
Definition: pool_type.hpp:359
List of file information.
Definition: fios.h:112
Minimap screenshot.
Definition: screenshot.h:25
ContentType type
Type of content.
Definition: tcp_content.h:65
const char * FiosBrowseTo(const FiosItem *item)
Browse to a new path based on the passed item, starting at #_fios_path.
Definition: fios.cpp:150
uint8 max_clients
maximum amount of clients
Restart –> &#39;Random game&#39; with current settings.
Definition: openttd.h:27
void NetworkClientSendRcon(const char *password, const char *command)
Send a remote console command.
char * cmdline
command(s) that is/are being aliased
static void Rescan()
Rescans all searchpaths for available AIs.
Definition: ai_core.cpp:348
IConsoleHook * hook
any special trigger action that needs executing
void IConsoleError(const char *string)
It is possible to print error information to the console.
Definition: console.cpp:168
DEF_CONSOLE_CMD(ConResetEngines)
Reset status of all engines.
Helper to mark the begin of the types.
Definition: tcp_content.h:22
Maximum number of companies.
Definition: company_type.h:23
StringList _network_ban_list
The banned clients.
Definition: network.cpp:65
void ValidateFileList(bool force_reload=false)
(Re-)validate the file storage cache.
#define MAX_DAY
The number of days till the last day.
Definition: date_type.h:97
SwitchMode _switch_mode
The next mainloop command.
Definition: gfx.cpp:46
Functions related to OTTD&#39;s landscape.
bool ScrollMainWindowToTile(TileIndex tile, bool instant)
Scrolls the viewport of the main window to a given location.
Definition: viewport.cpp:2396
void ScanNewGRFFiles(NewGRFScanCallback *callback)
Scan for all NewGRFs.
Base functions for all Games.
Functions related to commands.
Network functions used by other parts of OpenTTD.
bool _network_server
network-server is active
Definition: network.cpp:53
static const uint ICON_CMDLN_SIZE
maximum length of a typed in command
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition: pool_type.hpp:318
Colours _company_colours[MAX_COMPANIES]
NOSAVE: can be determined from company structs.
Definition: company_cmd.cpp:46
static char * GetConsoleLibraryList(char *p, const char *last)
Wrapper function for AIScanner::GetAIConsoleLibraryList.
Definition: ai_core.cpp:323
static const TextColour CC_ERROR
Colour for error lines.
Definition: console_type.h:24
void NetworkDisconnect(bool blocking, bool close_admins)
We want to disconnect from the host/clients.
Definition: network.cpp:781
bool ai_in_multiplayer
so we allow AIs in multiplayer
Aircraft vehicle type.
Definition: vehicle_type.h:27
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:129
The content has been manually selected.
Definition: tcp_content.h:58
char last_host[NETWORK_HOSTNAME_LENGTH]
IP address of the last joined server.
static bool CanStartNew()
Is it possible to start a new AI company?
Definition: ai_core.cpp:30
completed successfully
Definition: saveload.h:311
Base functions for all AIs.
Servers always have this ID.
Definition: network_type.h:41
GameCreationSettings game_creation
settings used during the creation of a game (map)
void SetMode(FiosType ft)
Set the mode and file type of the file to save or load based on the type of file entry at the file sy...
Definition: saveload.cpp:2863
void SetDebugString(const char *s)
Set debugging levels by parsing the text in s.
Definition: debug.cpp:172
bool file_list_valid
If set, the file list is valid.
AIConfig stores the configuration settings of every AI.
static uint32 BSWAP32(uint32 x)
Perform a 32 bits endianness bitswap on x.
Window functions not directly related to making/drawing windows.
void ReloadNewGRFData()
Reload all NewGRF files during a running game.
Definition: afterload.cpp:3161
static NetworkClientInfo * GetByClientID(ClientID client_id)
Return the CI given it&#39;s client-identifier.
Definition: network.cpp:119
void StringToSettings(const char *value)
Convert a string which is stored in the config file or savegames to custom settings of this Script...
const char * NetworkChangeCompanyPassword(CompanyID company_id, const char *password)
Change the company password of a given company.
Definition: network.cpp:162
Disallow command execution.
Date _date
Current date in days (day counter)
Definition: date.cpp:27
static bool NetworkAvailable(bool echo)
Check network availability and inform in console about failure of detection.
void ConvertDateToYMD(Date date, YearMonthDay *ymd)
Converts a Date to a Year, Month & Day.
Definition: date.cpp:95
static const TextColour CC_WARNING
Colour for warning lines.
Definition: console_type.h:25
Send message/notice to everyone playing the same company (Team)
Definition: network_type.h:83
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:44
Container for all important information about a piece of content.
Definition: tcp_content.h:54
bool GetArgumentInteger(uint32 *value, const char *arg)
Change a string into its number representation.
Definition: console.cpp:180
Road vehicle type.
Definition: vehicle_type.h:25
static const TextColour CC_WHITE
White console lines for various things such as the welcome.
Definition: console_type.h:29
A game paused because a (critical) error.
Definition: openttd.h:60
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition: map_func.h:163
void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc, IConsoleHook *hook)
Register a new command to be used in the console.
Definition: console.cpp:249
ClientNetworkContentSocketHandler _network_content_client
The client we use to connect to the server.
static const TextColour CC_INFO
Colour for information lines.
Definition: console_type.h:26
DEF_CONSOLE_HOOK(ConHookServerOnly)
Check whether we are a server.
Server part of the admin network protocol.
void IConsoleClose()
Close the in-game console.
ScreenshotType
Type of requested screenshot.
Definition: screenshot.h:18
Dynamic data of a loaded NewGRF.
Definition: newgrf.h:105
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:199
Base for the NewGRF implementation.
pause the game
Definition: command_type.h:255