OpenTTD
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 "console_func.h"
37 #include "engine_base.h"
38 #include "game/game.hpp"
39 #include "table/strings.h"
40 #include <time.h>
41 
42 #include "safeguards.h"
43 
44 /* scriptfile handling */
45 static bool _script_running;
46 
48 class ConsoleFileList : public FileList {
49 public:
51  {
52  this->file_list_valid = false;
53  }
54 
57  {
58  this->Clear();
59  this->file_list_valid = false;
60  }
61 
66  void ValidateFileList(bool force_reload = false)
67  {
68  if (force_reload || !this->file_list_valid) {
70  this->file_list_valid = true;
71  }
72  }
73 
75 };
76 
78 
79 /* console command defines */
80 #define DEF_CONSOLE_CMD(function) static bool function(byte argc, char *argv[])
81 #define DEF_CONSOLE_HOOK(function) static ConsoleHookResult function(bool echo)
82 
83 
84 /****************
85  * command hooks
86  ****************/
87 
92 static inline bool NetworkAvailable(bool echo)
93 {
94  if (!_network_available) {
95  if (echo) IConsoleError("You cannot use this command because there is no network available.");
96  return false;
97  }
98  return true;
99 }
100 
105 DEF_CONSOLE_HOOK(ConHookServerOnly)
106 {
107  if (!NetworkAvailable(echo)) return CHR_DISALLOW;
108 
109  if (!_network_server) {
110  if (echo) IConsoleError("This command is only available to a network server.");
111  return CHR_DISALLOW;
112  }
113  return CHR_ALLOW;
114 }
115 
120 DEF_CONSOLE_HOOK(ConHookClientOnly)
121 {
122  if (!NetworkAvailable(echo)) return CHR_DISALLOW;
123 
124  if (_network_server) {
125  if (echo) IConsoleError("This command is not available to a network server.");
126  return CHR_DISALLOW;
127  }
128  return CHR_ALLOW;
129 }
130 
135 DEF_CONSOLE_HOOK(ConHookNeedNetwork)
136 {
137  if (!NetworkAvailable(echo)) return CHR_DISALLOW;
138 
140  if (echo) IConsoleError("Not connected. This command is only available in multiplayer.");
141  return CHR_DISALLOW;
142  }
143  return CHR_ALLOW;
144 }
145 
150 DEF_CONSOLE_HOOK(ConHookNoNetwork)
151 {
152  if (_networking) {
153  if (echo) IConsoleError("This command is forbidden in multiplayer.");
154  return CHR_DISALLOW;
155  }
156  return CHR_ALLOW;
157 }
158 
159 DEF_CONSOLE_HOOK(ConHookNewGRFDeveloperTool)
160 {
162  if (_game_mode == GM_MENU) {
163  if (echo) IConsoleError("This command is only available in game and editor.");
164  return CHR_DISALLOW;
165  }
166  return ConHookNoNetwork(echo);
167  }
168  return CHR_HIDE;
169 }
170 
175 static void IConsoleHelp(const char *str)
176 {
177  IConsolePrintF(CC_WARNING, "- %s", str);
178 }
179 
184 DEF_CONSOLE_CMD(ConResetEngines)
185 {
186  if (argc == 0) {
187  IConsoleHelp("Reset status data of all engines. This might solve some issues with 'lost' engines. Usage: 'resetengines'");
188  return true;
189  }
190 
191  StartupEngines();
192  return true;
193 }
194 
200 DEF_CONSOLE_CMD(ConResetEnginePool)
201 {
202  if (argc == 0) {
203  IConsoleHelp("Reset NewGRF allocations of engine slots. This will remove invalid engine definitions, and might make default engines available again.");
204  return true;
205  }
206 
207  if (_game_mode == GM_MENU) {
208  IConsoleError("This command is only available in game and editor.");
209  return true;
210  }
211 
213  IConsoleError("This can only be done when there are no vehicles in the game.");
214  return true;
215  }
216 
217  return true;
218 }
219 
220 #ifdef _DEBUG
221 
226 DEF_CONSOLE_CMD(ConResetTile)
227 {
228  if (argc == 0) {
229  IConsoleHelp("Reset a tile to bare land. Usage: 'resettile <tile>'");
230  IConsoleHelp("Tile can be either decimal (34161) or hexadecimal (0x4a5B)");
231  return true;
232  }
233 
234  if (argc == 2) {
235  uint32 result;
236  if (GetArgumentInteger(&result, argv[1])) {
237  DoClearSquare((TileIndex)result);
238  return true;
239  }
240  }
241 
242  return false;
243 }
244 #endif /* _DEBUG */
245 
255 DEF_CONSOLE_CMD(ConScrollToTile)
256 {
257  switch (argc) {
258  case 0:
259  IConsoleHelp("Center the screen on a given tile.");
260  IConsoleHelp("Usage: 'scrollto <tile>' or 'scrollto <x> <y>'");
261  IConsoleHelp("Numbers can be either decimal (34161) or hexadecimal (0x4a5B).");
262  return true;
263 
264  case 2: {
265  uint32 result;
266  if (GetArgumentInteger(&result, argv[1])) {
267  if (result >= MapSize()) {
268  IConsolePrint(CC_ERROR, "Tile does not exist");
269  return true;
270  }
272  return true;
273  }
274  break;
275  }
276 
277  case 3: {
278  uint32 x, y;
279  if (GetArgumentInteger(&x, argv[1]) && GetArgumentInteger(&y, argv[2])) {
280  if (x >= MapSizeX() || y >= MapSizeY()) {
281  IConsolePrint(CC_ERROR, "Tile does not exist");
282  return true;
283  }
285  return true;
286  }
287  break;
288  }
289  }
290 
291  return false;
292 }
293 
300 {
301  if (argc == 0) {
302  IConsoleHelp("Save the current game. Usage: 'save <filename>'");
303  return true;
304  }
305 
306  if (argc == 2) {
307  char *filename = str_fmt("%s.sav", argv[1]);
308  IConsolePrint(CC_DEFAULT, "Saving map...");
309 
310  if (SaveOrLoad(filename, SLO_SAVE, DFT_GAME_FILE, SAVE_DIR) != SL_OK) {
311  IConsolePrint(CC_ERROR, "Saving map failed");
312  } else {
313  IConsolePrintF(CC_DEFAULT, "Map successfully saved to %s", filename);
314  }
315  free(filename);
316  return true;
317  }
318 
319  return false;
320 }
321 
326 DEF_CONSOLE_CMD(ConSaveConfig)
327 {
328  if (argc == 0) {
329  IConsoleHelp("Saves the configuration for new games to the configuration file, typically 'openttd.cfg'.");
330  IConsoleHelp("It does not save the configuration of the current game to the configuration file.");
331  return true;
332  }
333 
334  SaveToConfig();
335  IConsolePrint(CC_DEFAULT, "Saved config.");
336  return true;
337 }
338 
339 DEF_CONSOLE_CMD(ConLoad)
340 {
341  if (argc == 0) {
342  IConsoleHelp("Load a game by name or index. Usage: 'load <file | number>'");
343  return true;
344  }
345 
346  if (argc != 2) return false;
347 
348  const char *file = argv[1];
349  _console_file_list.ValidateFileList();
350  const FiosItem *item = _console_file_list.FindItem(file);
351  if (item != nullptr) {
352  if (GetAbstractFileType(item->type) == FT_SAVEGAME) {
354  _file_to_saveload.SetMode(item->type);
356  _file_to_saveload.SetTitle(item->title);
357  } else {
358  IConsolePrintF(CC_ERROR, "%s: Not a savegame.", file);
359  }
360  } else {
361  IConsolePrintF(CC_ERROR, "%s: No such file or directory.", file);
362  }
363 
364  return true;
365 }
366 
367 
368 DEF_CONSOLE_CMD(ConRemove)
369 {
370  if (argc == 0) {
371  IConsoleHelp("Remove a savegame by name or index. Usage: 'rm <file | number>'");
372  return true;
373  }
374 
375  if (argc != 2) return false;
376 
377  const char *file = argv[1];
378  _console_file_list.ValidateFileList();
379  const FiosItem *item = _console_file_list.FindItem(file);
380  if (item != nullptr) {
381  if (!FiosDelete(item->name)) {
382  IConsolePrintF(CC_ERROR, "%s: Failed to delete file", file);
383  }
384  } else {
385  IConsolePrintF(CC_ERROR, "%s: No such file or directory.", file);
386  }
387 
388  _console_file_list.InvalidateFileList();
389  return true;
390 }
391 
392 
393 /* List all the files in the current dir via console */
394 DEF_CONSOLE_CMD(ConListFiles)
395 {
396  if (argc == 0) {
397  IConsoleHelp("List all loadable savegames and directories in the current dir via console. Usage: 'ls | dir'");
398  return true;
399  }
400 
401  _console_file_list.ValidateFileList(true);
402  for (uint i = 0; i < _console_file_list.Length(); i++) {
403  IConsolePrintF(CC_DEFAULT, "%d) %s", i, _console_file_list[i].title);
404  }
405 
406  return true;
407 }
408 
409 /* Change the dir via console */
410 DEF_CONSOLE_CMD(ConChangeDirectory)
411 {
412  if (argc == 0) {
413  IConsoleHelp("Change the dir via console. Usage: 'cd <directory | number>'");
414  return true;
415  }
416 
417  if (argc != 2) return false;
418 
419  const char *file = argv[1];
420  _console_file_list.ValidateFileList(true);
421  const FiosItem *item = _console_file_list.FindItem(file);
422  if (item != nullptr) {
423  switch (item->type) {
424  case FIOS_TYPE_DIR: case FIOS_TYPE_DRIVE: case FIOS_TYPE_PARENT:
425  FiosBrowseTo(item);
426  break;
427  default: IConsolePrintF(CC_ERROR, "%s: Not a directory.", file);
428  }
429  } else {
430  IConsolePrintF(CC_ERROR, "%s: No such file or directory.", file);
431  }
432 
433  _console_file_list.InvalidateFileList();
434  return true;
435 }
436 
437 DEF_CONSOLE_CMD(ConPrintWorkingDirectory)
438 {
439  const char *path;
440 
441  if (argc == 0) {
442  IConsoleHelp("Print out the current working directory. Usage: 'pwd'");
443  return true;
444  }
445 
446  /* XXX - Workaround for broken file handling */
447  _console_file_list.ValidateFileList(true);
448  _console_file_list.InvalidateFileList();
449 
450  FiosGetDescText(&path, nullptr);
451  IConsolePrint(CC_DEFAULT, path);
452  return true;
453 }
454 
455 DEF_CONSOLE_CMD(ConClearBuffer)
456 {
457  if (argc == 0) {
458  IConsoleHelp("Clear the console buffer. Usage: 'clear'");
459  return true;
460  }
461 
462  IConsoleClearBuffer();
464  return true;
465 }
466 
467 
468 /**********************************
469  * Network Core Console Commands
470  **********************************/
471 
472 static bool ConKickOrBan(const char *argv, bool ban)
473 {
474  uint n;
475 
476  if (strchr(argv, '.') == nullptr && strchr(argv, ':') == nullptr) { // banning with ID
477  ClientID client_id = (ClientID)atoi(argv);
478 
479  /* Don't kill the server, or the client doing the rcon. The latter can't be kicked because
480  * kicking frees closes and subsequently free the connection related instances, which we
481  * would be reading from and writing to after returning. So we would read or write data
482  * from freed memory up till the segfault triggers. */
483  if (client_id == CLIENT_ID_SERVER || client_id == _redirect_console_to_client) {
484  IConsolePrintF(CC_ERROR, "ERROR: Silly boy, you can not %s yourself!", ban ? "ban" : "kick");
485  return true;
486  }
487 
489  if (ci == nullptr) {
490  IConsoleError("Invalid client");
491  return true;
492  }
493 
494  if (!ban) {
495  /* Kick only this client, not all clients with that IP */
496  NetworkServerKickClient(client_id);
497  return true;
498  }
499 
500  /* When banning, kick+ban all clients with that IP */
501  n = NetworkServerKickOrBanIP(client_id, ban);
502  } else {
503  n = NetworkServerKickOrBanIP(argv, ban);
504  }
505 
506  if (n == 0) {
507  IConsolePrint(CC_DEFAULT, ban ? "Client not online, address added to banlist" : "Client not found");
508  } else {
509  IConsolePrintF(CC_DEFAULT, "%sed %u client(s)", ban ? "Bann" : "Kick", n);
510  }
511 
512  return true;
513 }
514 
515 DEF_CONSOLE_CMD(ConKick)
516 {
517  if (argc == 0) {
518  IConsoleHelp("Kick a client from a network game. Usage: 'kick <ip | client-id>'");
519  IConsoleHelp("For client-id's, see the command 'clients'");
520  return true;
521  }
522 
523  if (argc != 2) return false;
524 
525  return ConKickOrBan(argv[1], false);
526 }
527 
528 DEF_CONSOLE_CMD(ConBan)
529 {
530  if (argc == 0) {
531  IConsoleHelp("Ban a client from a network game. Usage: 'ban <ip | client-id>'");
532  IConsoleHelp("For client-id's, see the command 'clients'");
533  IConsoleHelp("If the client is no longer online, you can still ban his/her IP");
534  return true;
535  }
536 
537  if (argc != 2) return false;
538 
539  return ConKickOrBan(argv[1], true);
540 }
541 
542 DEF_CONSOLE_CMD(ConUnBan)
543 {
544  if (argc == 0) {
545  IConsoleHelp("Unban a client from a network game. Usage: 'unban <ip | banlist-index>'");
546  IConsoleHelp("For a list of banned IP's, see the command 'banlist'");
547  return true;
548  }
549 
550  if (argc != 2) return false;
551 
552  /* Try by IP. */
553  uint index;
554  for (index = 0; index < _network_ban_list.size(); index++) {
555  if (_network_ban_list[index] == argv[1]) break;
556  }
557 
558  /* Try by index. */
559  if (index >= _network_ban_list.size()) {
560  index = atoi(argv[1]) - 1U; // let it wrap
561  }
562 
563  if (index < _network_ban_list.size()) {
564  char msg[64];
565  seprintf(msg, lastof(msg), "Unbanned %s", _network_ban_list[index].c_str());
567  _network_ban_list.erase(_network_ban_list.begin() + index);
568  } else {
569  IConsolePrint(CC_DEFAULT, "Invalid list index or IP not in ban-list.");
570  IConsolePrint(CC_DEFAULT, "For a list of banned IP's, see the command 'banlist'");
571  }
572 
573  return true;
574 }
575 
576 DEF_CONSOLE_CMD(ConBanList)
577 {
578  if (argc == 0) {
579  IConsoleHelp("List the IP's of banned clients: Usage 'banlist'");
580  return true;
581  }
582 
583  IConsolePrint(CC_DEFAULT, "Banlist: ");
584 
585  uint i = 1;
586  for (const auto &entry : _network_ban_list) {
587  IConsolePrintF(CC_DEFAULT, " %d) %s", i, entry.c_str());
588  }
589 
590  return true;
591 }
592 
593 DEF_CONSOLE_CMD(ConPauseGame)
594 {
595  if (argc == 0) {
596  IConsoleHelp("Pause a network game. Usage: 'pause'");
597  return true;
598  }
599 
601  DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
602  if (!_networking) IConsolePrint(CC_DEFAULT, "Game paused.");
603  } else {
604  IConsolePrint(CC_DEFAULT, "Game is already paused.");
605  }
606 
607  return true;
608 }
609 
610 DEF_CONSOLE_CMD(ConUnpauseGame)
611 {
612  if (argc == 0) {
613  IConsoleHelp("Unpause a network game. Usage: 'unpause'");
614  return true;
615  }
616 
618  DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE);
619  if (!_networking) IConsolePrint(CC_DEFAULT, "Game unpaused.");
620  } else if ((_pause_mode & PM_PAUSED_ERROR) != PM_UNPAUSED) {
621  IConsolePrint(CC_DEFAULT, "Game is in error state and cannot be unpaused via console.");
622  } else if (_pause_mode != PM_UNPAUSED) {
623  IConsolePrint(CC_DEFAULT, "Game cannot be unpaused manually; disable pause_on_join/min_active_clients.");
624  } else {
625  IConsolePrint(CC_DEFAULT, "Game is already unpaused.");
626  }
627 
628  return true;
629 }
630 
631 DEF_CONSOLE_CMD(ConRcon)
632 {
633  if (argc == 0) {
634  IConsoleHelp("Remote control the server from another client. Usage: 'rcon <password> <command>'");
635  IConsoleHelp("Remember to enclose the command in quotes, otherwise only the first parameter is sent");
636  return true;
637  }
638 
639  if (argc < 3) return false;
640 
641  if (_network_server) {
642  IConsoleCmdExec(argv[2]);
643  } else {
644  NetworkClientSendRcon(argv[1], argv[2]);
645  }
646  return true;
647 }
648 
649 DEF_CONSOLE_CMD(ConStatus)
650 {
651  if (argc == 0) {
652  IConsoleHelp("List the status of all clients connected to the server. Usage 'status'");
653  return true;
654  }
655 
657  return true;
658 }
659 
660 DEF_CONSOLE_CMD(ConServerInfo)
661 {
662  if (argc == 0) {
663  IConsoleHelp("List current and maximum client/company limits. Usage 'server_info'");
664  IConsoleHelp("You can change these values by modifying settings 'network.max_clients', 'network.max_companies' and 'network.max_spectators'");
665  return true;
666  }
667 
669  IConsolePrintF(CC_DEFAULT, "Current/maximum companies: %2d/%2d", (int)Company::GetNumItems(), _settings_client.network.max_companies);
670  IConsolePrintF(CC_DEFAULT, "Current/maximum spectators: %2d/%2d", NetworkSpectatorCount(), _settings_client.network.max_spectators);
671 
672  return true;
673 }
674 
675 DEF_CONSOLE_CMD(ConClientNickChange)
676 {
677  if (argc != 3) {
678  IConsoleHelp("Change the nickname of a connected client. Usage: 'client_name <client-id> <new-name>'");
679  IConsoleHelp("For client-id's, see the command 'clients'");
680  return true;
681  }
682 
683  ClientID client_id = (ClientID)atoi(argv[1]);
684 
685  if (client_id == CLIENT_ID_SERVER) {
686  IConsoleError("Please use the command 'name' to change your own name!");
687  return true;
688  }
689 
690  if (NetworkClientInfo::GetByClientID(client_id) == nullptr) {
691  IConsoleError("Invalid client");
692  return true;
693  }
694 
695  if (!NetworkServerChangeClientName(client_id, argv[2])) {
696  IConsoleError("Cannot give a client a duplicate name");
697  }
698 
699  return true;
700 }
701 
702 DEF_CONSOLE_CMD(ConJoinCompany)
703 {
704  if (argc < 2) {
705  IConsoleHelp("Request joining another company. Usage: join <company-id> [<password>]");
706  IConsoleHelp("For valid company-id see company list, use 255 for spectator");
707  return true;
708  }
709 
710  CompanyID company_id = (CompanyID)(atoi(argv[1]) <= MAX_COMPANIES ? atoi(argv[1]) - 1 : atoi(argv[1]));
711 
712  /* Check we have a valid company id! */
713  if (!Company::IsValidID(company_id) && company_id != COMPANY_SPECTATOR) {
714  IConsolePrintF(CC_ERROR, "Company does not exist. Company-id must be between 1 and %d.", MAX_COMPANIES);
715  return true;
716  }
717 
718  if (NetworkClientInfo::GetByClientID(_network_own_client_id)->client_playas == company_id) {
719  IConsoleError("You are already there!");
720  return true;
721  }
722 
723  if (company_id == COMPANY_SPECTATOR && NetworkMaxSpectatorsReached()) {
724  IConsoleError("Cannot join spectators, maximum number of spectators reached.");
725  return true;
726  }
727 
728  if (company_id != COMPANY_SPECTATOR && !Company::IsHumanID(company_id)) {
729  IConsoleError("Cannot join AI company.");
730  return true;
731  }
732 
733  /* Check if the company requires a password */
734  if (NetworkCompanyIsPassworded(company_id) && argc < 3) {
735  IConsolePrintF(CC_ERROR, "Company %d requires a password to join.", company_id + 1);
736  return true;
737  }
738 
739  /* non-dedicated server may just do the move! */
740  if (_network_server) {
742  } else {
743  NetworkClientRequestMove(company_id, NetworkCompanyIsPassworded(company_id) ? argv[2] : "");
744  }
745 
746  return true;
747 }
748 
749 DEF_CONSOLE_CMD(ConMoveClient)
750 {
751  if (argc < 3) {
752  IConsoleHelp("Move a client to another company. Usage: move <client-id> <company-id>");
753  IConsoleHelp("For valid client-id see 'clients', for valid company-id see 'companies', use 255 for moving to spectators");
754  return true;
755  }
756 
757  const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID((ClientID)atoi(argv[1]));
758  CompanyID company_id = (CompanyID)(atoi(argv[2]) <= MAX_COMPANIES ? atoi(argv[2]) - 1 : atoi(argv[2]));
759 
760  /* check the client exists */
761  if (ci == nullptr) {
762  IConsoleError("Invalid client-id, check the command 'clients' for valid client-id's.");
763  return true;
764  }
765 
766  if (!Company::IsValidID(company_id) && company_id != COMPANY_SPECTATOR) {
767  IConsolePrintF(CC_ERROR, "Company does not exist. Company-id must be between 1 and %d.", MAX_COMPANIES);
768  return true;
769  }
770 
771  if (company_id != COMPANY_SPECTATOR && !Company::IsHumanID(company_id)) {
772  IConsoleError("You cannot move clients to AI companies.");
773  return true;
774  }
775 
777  IConsoleError("Silly boy, you cannot move the server!");
778  return true;
779  }
780 
781  if (ci->client_playas == company_id) {
782  IConsoleError("You cannot move someone to where he/she already is!");
783  return true;
784  }
785 
786  /* we are the server, so force the update */
787  NetworkServerDoMove(ci->client_id, company_id);
788 
789  return true;
790 }
791 
792 DEF_CONSOLE_CMD(ConResetCompany)
793 {
794  if (argc == 0) {
795  IConsoleHelp("Remove an idle company from the game. Usage: 'reset_company <company-id>'");
796  IConsoleHelp("For company-id's, see the list of companies from the dropdown menu. Company 1 is 1, etc.");
797  return true;
798  }
799 
800  if (argc != 2) return false;
801 
802  CompanyID index = (CompanyID)(atoi(argv[1]) - 1);
803 
804  /* Check valid range */
805  if (!Company::IsValidID(index)) {
806  IConsolePrintF(CC_ERROR, "Company does not exist. Company-id must be between 1 and %d.", MAX_COMPANIES);
807  return true;
808  }
809 
810  if (!Company::IsHumanID(index)) {
811  IConsoleError("Company is owned by an AI.");
812  return true;
813  }
814 
815  if (NetworkCompanyHasClients(index)) {
816  IConsoleError("Cannot remove company: a client is connected to that company.");
817  return false;
818  }
820  if (ci->client_playas == index) {
821  IConsoleError("Cannot remove company: the server is connected to that company.");
822  return true;
823  }
824 
825  /* It is safe to remove this company */
826  DoCommandP(0, CCA_DELETE | index << 16 | CRR_MANUAL << 24, 0, CMD_COMPANY_CTRL);
827  IConsolePrint(CC_DEFAULT, "Company deleted.");
828 
829  return true;
830 }
831 
832 DEF_CONSOLE_CMD(ConNetworkClients)
833 {
834  if (argc == 0) {
835  IConsoleHelp("Get a list of connected clients including their ID, name, company-id, and IP. Usage: 'clients'");
836  return true;
837  }
838 
840 
841  return true;
842 }
843 
844 DEF_CONSOLE_CMD(ConNetworkReconnect)
845 {
846  if (argc == 0) {
847  IConsoleHelp("Reconnect to server to which you were connected last time. Usage: 'reconnect [<company>]'");
848  IConsoleHelp("Company 255 is spectator (default, if not specified), 0 means creating new company.");
849  IConsoleHelp("All others are a certain company with Company 1 being #1");
850  return true;
851  }
852 
853  CompanyID playas = (argc >= 2) ? (CompanyID)atoi(argv[1]) : COMPANY_SPECTATOR;
854  switch (playas) {
855  case 0: playas = COMPANY_NEW_COMPANY; break;
856  case COMPANY_SPECTATOR: /* nothing to do */ break;
857  default:
858  /* From a user pov 0 is a new company, internally it's different and all
859  * companies are offset by one to ease up on users (eg companies 1-8 not 0-7) */
860  if (playas < COMPANY_FIRST + 1 || playas > MAX_COMPANIES + 1) return false;
861  break;
862  }
863 
865  IConsolePrint(CC_DEFAULT, "No server for reconnecting.");
866  return true;
867  }
868 
869  /* Don't resolve the address first, just print it directly as it comes from the config file. */
871 
873  return true;
874 }
875 
876 DEF_CONSOLE_CMD(ConNetworkConnect)
877 {
878  if (argc == 0) {
879  IConsoleHelp("Connect to a remote OTTD server and join the game. Usage: 'connect <ip>'");
880  IConsoleHelp("IP can contain port and company: 'IP[:Port][#Company]', eg: 'server.ottd.org:443#2'");
881  IConsoleHelp("Company #255 is spectator all others are a certain company with Company 1 being #1");
882  return true;
883  }
884 
885  if (argc < 2) return false;
886  if (_networking) NetworkDisconnect(); // we are in network-mode, first close it!
887 
888  const char *port = nullptr;
889  const char *company = nullptr;
890  char *ip = argv[1];
891  /* Default settings: default port and new company */
892  uint16 rport = NETWORK_DEFAULT_PORT;
893  CompanyID join_as = COMPANY_NEW_COMPANY;
894 
895  ParseConnectionString(&company, &port, ip);
896 
897  IConsolePrintF(CC_DEFAULT, "Connecting to %s...", ip);
898  if (company != nullptr) {
899  join_as = (CompanyID)atoi(company);
900  IConsolePrintF(CC_DEFAULT, " company-no: %d", join_as);
901 
902  /* From a user pov 0 is a new company, internally it's different and all
903  * companies are offset by one to ease up on users (eg companies 1-8 not 0-7) */
904  if (join_as != COMPANY_SPECTATOR) {
905  if (join_as > MAX_COMPANIES) return false;
906  join_as--;
907  }
908  }
909  if (port != nullptr) {
910  rport = atoi(port);
911  IConsolePrintF(CC_DEFAULT, " port: %s", port);
912  }
913 
914  NetworkClientConnectGame(NetworkAddress(ip, rport), join_as);
915 
916  return true;
917 }
918 
919 /*********************************
920  * script file console commands
921  *********************************/
922 
923 DEF_CONSOLE_CMD(ConExec)
924 {
925  if (argc == 0) {
926  IConsoleHelp("Execute a local script file. Usage: 'exec <script> <?>'");
927  return true;
928  }
929 
930  if (argc < 2) return false;
931 
932  FILE *script_file = FioFOpenFile(argv[1], "r", BASE_DIR);
933 
934  if (script_file == nullptr) {
935  if (argc == 2 || atoi(argv[2]) != 0) IConsoleError("script file not found");
936  return true;
937  }
938 
939  _script_running = true;
940 
941  char cmdline[ICON_CMDLN_SIZE];
942  while (_script_running && fgets(cmdline, sizeof(cmdline), script_file) != nullptr) {
943  /* Remove newline characters from the executing script */
944  for (char *cmdptr = cmdline; *cmdptr != '\0'; cmdptr++) {
945  if (*cmdptr == '\n' || *cmdptr == '\r') {
946  *cmdptr = '\0';
947  break;
948  }
949  }
950  IConsoleCmdExec(cmdline);
951  }
952 
953  if (ferror(script_file)) {
954  IConsoleError("Encountered error while trying to read from script file");
955  }
956 
957  _script_running = false;
958  FioFCloseFile(script_file);
959  return true;
960 }
961 
962 DEF_CONSOLE_CMD(ConReturn)
963 {
964  if (argc == 0) {
965  IConsoleHelp("Stop executing a running script. Usage: 'return'");
966  return true;
967  }
968 
969  _script_running = false;
970  return true;
971 }
972 
973 /*****************************
974  * default console commands
975  ******************************/
976 extern bool CloseConsoleLogIfActive();
977 
978 DEF_CONSOLE_CMD(ConScript)
979 {
980  extern FILE *_iconsole_output_file;
981 
982  if (argc == 0) {
983  IConsoleHelp("Start or stop logging console output to a file. Usage: 'script <filename>'");
984  IConsoleHelp("If filename is omitted, a running log is stopped if it is active");
985  return true;
986  }
987 
988  if (!CloseConsoleLogIfActive()) {
989  if (argc < 2) return false;
990 
991  IConsolePrintF(CC_DEFAULT, "file output started to: %s", argv[1]);
992  _iconsole_output_file = fopen(argv[1], "ab");
993  if (_iconsole_output_file == nullptr) IConsoleError("could not open file");
994  }
995 
996  return true;
997 }
998 
999 
1000 DEF_CONSOLE_CMD(ConEcho)
1001 {
1002  if (argc == 0) {
1003  IConsoleHelp("Print back the first argument to the console. Usage: 'echo <arg>'");
1004  return true;
1005  }
1006 
1007  if (argc < 2) return false;
1008  IConsolePrint(CC_DEFAULT, argv[1]);
1009  return true;
1010 }
1011 
1012 DEF_CONSOLE_CMD(ConEchoC)
1013 {
1014  if (argc == 0) {
1015  IConsoleHelp("Print back the first argument to the console in a given colour. Usage: 'echoc <colour> <arg2>'");
1016  return true;
1017  }
1018 
1019  if (argc < 3) return false;
1020  IConsolePrint((TextColour)Clamp(atoi(argv[1]), TC_BEGIN, TC_END - 1), argv[2]);
1021  return true;
1022 }
1023 
1024 DEF_CONSOLE_CMD(ConNewGame)
1025 {
1026  if (argc == 0) {
1027  IConsoleHelp("Start a new game. Usage: 'newgame [seed]'");
1028  IConsoleHelp("The server can force a new game using 'newgame'; any client joined will rejoin after the server is done generating the new game.");
1029  return true;
1030  }
1031 
1032  StartNewGameWithoutGUI((argc == 2) ? strtoul(argv[1], nullptr, 10) : GENERATE_NEW_SEED);
1033  return true;
1034 }
1035 
1036 DEF_CONSOLE_CMD(ConRestart)
1037 {
1038  if (argc == 0) {
1039  IConsoleHelp("Restart game. Usage: 'restart'");
1040  IConsoleHelp("Restarts a game. It tries to reproduce the exact same map as the game started with.");
1041  IConsoleHelp("However:");
1042  IConsoleHelp(" * restarting games started in another version might create another map due to difference in map generation");
1043  IConsoleHelp(" * restarting games based on scenarios, loaded games or heightmaps will start a new game based on the settings stored in the scenario/savegame");
1044  return true;
1045  }
1046 
1047  /* Don't copy the _newgame pointers to the real pointers, so call SwitchToMode directly */
1051  return true;
1052 }
1053 
1059 static void PrintLineByLine(char *buf)
1060 {
1061  char *p = buf;
1062  /* Print output line by line */
1063  for (char *p2 = buf; *p2 != '\0'; p2++) {
1064  if (*p2 == '\n') {
1065  *p2 = '\0';
1066  IConsolePrintF(CC_DEFAULT, "%s", p);
1067  p = p2 + 1;
1068  }
1069  }
1070 }
1071 
1072 DEF_CONSOLE_CMD(ConListAILibs)
1073 {
1074  char buf[4096];
1075  AI::GetConsoleLibraryList(buf, lastof(buf));
1076 
1077  PrintLineByLine(buf);
1078 
1079  return true;
1080 }
1081 
1082 DEF_CONSOLE_CMD(ConListAI)
1083 {
1084  char buf[4096];
1085  AI::GetConsoleList(buf, lastof(buf));
1086 
1087  PrintLineByLine(buf);
1088 
1089  return true;
1090 }
1091 
1092 DEF_CONSOLE_CMD(ConListGameLibs)
1093 {
1094  char buf[4096];
1096 
1097  PrintLineByLine(buf);
1098 
1099  return true;
1100 }
1101 
1102 DEF_CONSOLE_CMD(ConListGame)
1103 {
1104  char buf[4096];
1105  Game::GetConsoleList(buf, lastof(buf));
1106 
1107  PrintLineByLine(buf);
1108 
1109  return true;
1110 }
1111 
1112 DEF_CONSOLE_CMD(ConStartAI)
1113 {
1114  if (argc == 0 || argc > 3) {
1115  IConsoleHelp("Start a new AI. Usage: 'start_ai [<AI>] [<settings>]'");
1116  IConsoleHelp("Start a new AI. If <AI> is given, it starts that specific AI (if found).");
1117  IConsoleHelp("If <settings> is given, it is parsed and the AI settings are set to that.");
1118  return true;
1119  }
1120 
1121  if (_game_mode != GM_NORMAL) {
1122  IConsoleWarning("AIs can only be managed in a game.");
1123  return true;
1124  }
1125 
1127  IConsoleWarning("Can't start a new AI (no more free slots).");
1128  return true;
1129  }
1130  if (_networking && !_network_server) {
1131  IConsoleWarning("Only the server can start a new AI.");
1132  return true;
1133  }
1135  IConsoleWarning("AIs are not allowed in multiplayer by configuration.");
1136  IConsoleWarning("Switch AI -> AI in multiplayer to True.");
1137  return true;
1138  }
1139  if (!AI::CanStartNew()) {
1140  IConsoleWarning("Can't start a new AI.");
1141  return true;
1142  }
1143 
1144  int n = 0;
1145  /* Find the next free slot */
1146  for (const Company *c : Company::Iterate()) {
1147  if (c->index != n) break;
1148  n++;
1149  }
1150 
1151  AIConfig *config = AIConfig::GetConfig((CompanyID)n);
1152  if (argc >= 2) {
1153  config->Change(argv[1], -1, true);
1154  if (!config->HasScript()) {
1155  IConsoleWarning("Failed to load the specified AI");
1156  return true;
1157  }
1158  if (argc == 3) {
1159  config->StringToSettings(argv[2]);
1160  }
1161  }
1162 
1163  /* Start a new AI company */
1165 
1166  return true;
1167 }
1168 
1169 DEF_CONSOLE_CMD(ConReloadAI)
1170 {
1171  if (argc != 2) {
1172  IConsoleHelp("Reload an AI. Usage: 'reload_ai <company-id>'");
1173  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.");
1174  return true;
1175  }
1176 
1177  if (_game_mode != GM_NORMAL) {
1178  IConsoleWarning("AIs can only be managed in a game.");
1179  return true;
1180  }
1181 
1182  if (_networking && !_network_server) {
1183  IConsoleWarning("Only the server can reload an AI.");
1184  return true;
1185  }
1186 
1187  CompanyID company_id = (CompanyID)(atoi(argv[1]) - 1);
1188  if (!Company::IsValidID(company_id)) {
1189  IConsolePrintF(CC_DEFAULT, "Unknown company. Company range is between 1 and %d.", MAX_COMPANIES);
1190  return true;
1191  }
1192 
1193  if (Company::IsHumanID(company_id)) {
1194  IConsoleWarning("Company is not controlled by an AI.");
1195  return true;
1196  }
1197 
1198  /* First kill the company of the AI, then start a new one. This should start the current AI again */
1199  DoCommandP(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0,CMD_COMPANY_CTRL);
1200  DoCommandP(0, CCA_NEW_AI | company_id << 16, 0, CMD_COMPANY_CTRL);
1201  IConsolePrint(CC_DEFAULT, "AI reloaded.");
1202 
1203  return true;
1204 }
1205 
1206 DEF_CONSOLE_CMD(ConStopAI)
1207 {
1208  if (argc != 2) {
1209  IConsoleHelp("Stop an AI. Usage: 'stop_ai <company-id>'");
1210  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.");
1211  return true;
1212  }
1213 
1214  if (_game_mode != GM_NORMAL) {
1215  IConsoleWarning("AIs can only be managed in a game.");
1216  return true;
1217  }
1218 
1219  if (_networking && !_network_server) {
1220  IConsoleWarning("Only the server can stop an AI.");
1221  return true;
1222  }
1223 
1224  CompanyID company_id = (CompanyID)(atoi(argv[1]) - 1);
1225  if (!Company::IsValidID(company_id)) {
1226  IConsolePrintF(CC_DEFAULT, "Unknown company. Company range is between 1 and %d.", MAX_COMPANIES);
1227  return true;
1228  }
1229 
1230  if (Company::IsHumanID(company_id) || company_id == _local_company) {
1231  IConsoleWarning("Company is not controlled by an AI.");
1232  return true;
1233  }
1234 
1235  /* Now kill the company of the AI. */
1236  DoCommandP(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0, CMD_COMPANY_CTRL);
1237  IConsolePrint(CC_DEFAULT, "AI stopped, company deleted.");
1238 
1239  return true;
1240 }
1241 
1242 DEF_CONSOLE_CMD(ConRescanAI)
1243 {
1244  if (argc == 0) {
1245  IConsoleHelp("Rescan the AI dir for scripts. Usage: 'rescan_ai'");
1246  return true;
1247  }
1248 
1249  if (_networking && !_network_server) {
1250  IConsoleWarning("Only the server can rescan the AI dir for scripts.");
1251  return true;
1252  }
1253 
1254  AI::Rescan();
1255 
1256  return true;
1257 }
1258 
1259 DEF_CONSOLE_CMD(ConRescanGame)
1260 {
1261  if (argc == 0) {
1262  IConsoleHelp("Rescan the Game Script dir for scripts. Usage: 'rescan_game'");
1263  return true;
1264  }
1265 
1266  if (_networking && !_network_server) {
1267  IConsoleWarning("Only the server can rescan the Game Script dir for scripts.");
1268  return true;
1269  }
1270 
1271  Game::Rescan();
1272 
1273  return true;
1274 }
1275 
1276 DEF_CONSOLE_CMD(ConRescanNewGRF)
1277 {
1278  if (argc == 0) {
1279  IConsoleHelp("Rescan the data dir for NewGRFs. Usage: 'rescan_newgrf'");
1280  return true;
1281  }
1282 
1283  ScanNewGRFFiles(nullptr);
1284 
1285  return true;
1286 }
1287 
1288 DEF_CONSOLE_CMD(ConGetSeed)
1289 {
1290  if (argc == 0) {
1291  IConsoleHelp("Returns the seed used to create this game. Usage: 'getseed'");
1292  IConsoleHelp("The seed can be used to reproduce the exact same map as the game started with.");
1293  return true;
1294  }
1295 
1297  return true;
1298 }
1299 
1300 DEF_CONSOLE_CMD(ConGetDate)
1301 {
1302  if (argc == 0) {
1303  IConsoleHelp("Returns the current date (year-month-day) of the game. Usage: 'getdate'");
1304  return true;
1305  }
1306 
1307  YearMonthDay ymd;
1308  ConvertDateToYMD(_date, &ymd);
1309  IConsolePrintF(CC_DEFAULT, "Date: %04d-%02d-%02d", ymd.year, ymd.month + 1, ymd.day);
1310  return true;
1311 }
1312 
1313 DEF_CONSOLE_CMD(ConGetSysDate)
1314 {
1315  if (argc == 0) {
1316  IConsoleHelp("Returns the current date (year-month-day) of your system. Usage: 'getsysdate'");
1317  return true;
1318  }
1319 
1320  time_t t;
1321  time(&t);
1322  auto timeinfo = localtime(&t);
1323  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);
1324  return true;
1325 }
1326 
1327 
1328 DEF_CONSOLE_CMD(ConAlias)
1329 {
1330  IConsoleAlias *alias;
1331 
1332  if (argc == 0) {
1333  IConsoleHelp("Add a new alias, or redefine the behaviour of an existing alias . Usage: 'alias <name> <command>'");
1334  return true;
1335  }
1336 
1337  if (argc < 3) return false;
1338 
1339  alias = IConsoleAliasGet(argv[1]);
1340  if (alias == nullptr) {
1341  IConsoleAliasRegister(argv[1], argv[2]);
1342  } else {
1343  free(alias->cmdline);
1344  alias->cmdline = stredup(argv[2]);
1345  }
1346  return true;
1347 }
1348 
1349 DEF_CONSOLE_CMD(ConScreenShot)
1350 {
1351  if (argc == 0) {
1352  IConsoleHelp("Create a screenshot of the game. Usage: 'screenshot [big | giant | no_con] [file name]'");
1353  IConsoleHelp("'big' makes a zoomed-in screenshot of the visible area, 'giant' makes a screenshot of the "
1354  "whole map, 'no_con' hides the console to create the screenshot. 'big' or 'giant' "
1355  "screenshots are always drawn without console");
1356  return true;
1357  }
1358 
1359  if (argc > 3) return false;
1360 
1361  ScreenshotType type = SC_VIEWPORT;
1362  const char *name = nullptr;
1363 
1364  if (argc > 1) {
1365  if (strcmp(argv[1], "big") == 0) {
1366  /* screenshot big [filename] */
1367  type = SC_ZOOMEDIN;
1368  if (argc > 2) name = argv[2];
1369  } else if (strcmp(argv[1], "giant") == 0) {
1370  /* screenshot giant [filename] */
1371  type = SC_WORLD;
1372  if (argc > 2) name = argv[2];
1373  } else if (strcmp(argv[1], "no_con") == 0) {
1374  /* screenshot no_con [filename] */
1375  IConsoleClose();
1376  if (argc > 2) name = argv[2];
1377  } else if (argc == 2) {
1378  /* screenshot filename */
1379  name = argv[1];
1380  } else {
1381  /* screenshot argv[1] argv[2] - invalid */
1382  return false;
1383  }
1384  }
1385 
1386  MakeScreenshot(type, name);
1387  return true;
1388 }
1389 
1390 DEF_CONSOLE_CMD(ConInfoCmd)
1391 {
1392  if (argc == 0) {
1393  IConsoleHelp("Print out debugging information about a command. Usage: 'info_cmd <cmd>'");
1394  return true;
1395  }
1396 
1397  if (argc < 2) return false;
1398 
1399  const IConsoleCmd *cmd = IConsoleCmdGet(argv[1]);
1400  if (cmd == nullptr) {
1401  IConsoleError("the given command was not found");
1402  return true;
1403  }
1404 
1405  IConsolePrintF(CC_DEFAULT, "command name: %s", cmd->name);
1406  IConsolePrintF(CC_DEFAULT, "command proc: %p", cmd->proc);
1407 
1408  if (cmd->hook != nullptr) IConsoleWarning("command is hooked");
1409 
1410  return true;
1411 }
1412 
1413 DEF_CONSOLE_CMD(ConDebugLevel)
1414 {
1415  if (argc == 0) {
1416  IConsoleHelp("Get/set the default debugging level for the game. Usage: 'debug_level [<level>]'");
1417  IConsoleHelp("Level can be any combination of names, levels. Eg 'net=5 ms=4'. Remember to enclose it in \"'s");
1418  return true;
1419  }
1420 
1421  if (argc > 2) return false;
1422 
1423  if (argc == 1) {
1424  IConsolePrintF(CC_DEFAULT, "Current debug-level: '%s'", GetDebugString());
1425  } else {
1426  SetDebugString(argv[1]);
1427  }
1428 
1429  return true;
1430 }
1431 
1432 DEF_CONSOLE_CMD(ConExit)
1433 {
1434  if (argc == 0) {
1435  IConsoleHelp("Exit the game. Usage: 'exit'");
1436  return true;
1437  }
1438 
1439  if (_game_mode == GM_NORMAL && _settings_client.gui.autosave_on_exit) DoExitSave();
1440 
1441  _exit_game = true;
1442  return true;
1443 }
1444 
1445 DEF_CONSOLE_CMD(ConPart)
1446 {
1447  if (argc == 0) {
1448  IConsoleHelp("Leave the currently joined/running game (only ingame). Usage: 'part'");
1449  return true;
1450  }
1451 
1452  if (_game_mode != GM_NORMAL) return false;
1453 
1455  return true;
1456 }
1457 
1458 DEF_CONSOLE_CMD(ConHelp)
1459 {
1460  if (argc == 2) {
1461  const IConsoleCmd *cmd;
1462  const IConsoleAlias *alias;
1463 
1464  RemoveUnderscores(argv[1]);
1465  cmd = IConsoleCmdGet(argv[1]);
1466  if (cmd != nullptr) {
1467  cmd->proc(0, nullptr);
1468  return true;
1469  }
1470 
1471  alias = IConsoleAliasGet(argv[1]);
1472  if (alias != nullptr) {
1473  cmd = IConsoleCmdGet(alias->cmdline);
1474  if (cmd != nullptr) {
1475  cmd->proc(0, nullptr);
1476  return true;
1477  }
1478  IConsolePrintF(CC_ERROR, "ERROR: alias is of special type, please see its execution-line: '%s'", alias->cmdline);
1479  return true;
1480  }
1481 
1482  IConsoleError("command not found");
1483  return true;
1484  }
1485 
1486  IConsolePrint(CC_WARNING, " ---- OpenTTD Console Help ---- ");
1487  IConsolePrint(CC_DEFAULT, " - commands: [command to list all commands: list_cmds]");
1488  IConsolePrint(CC_DEFAULT, " call commands with '<command> <arg2> <arg3>...'");
1489  IConsolePrint(CC_DEFAULT, " - to assign strings, or use them as arguments, enclose it within quotes");
1490  IConsolePrint(CC_DEFAULT, " like this: '<command> \"string argument with spaces\"'");
1491  IConsolePrint(CC_DEFAULT, " - use 'help <command>' to get specific information");
1492  IConsolePrint(CC_DEFAULT, " - scroll console output with shift + (up | down | pageup | pagedown)");
1493  IConsolePrint(CC_DEFAULT, " - scroll console input history with the up or down arrows");
1495  return true;
1496 }
1497 
1498 DEF_CONSOLE_CMD(ConListCommands)
1499 {
1500  if (argc == 0) {
1501  IConsoleHelp("List all registered commands. Usage: 'list_cmds [<pre-filter>]'");
1502  return true;
1503  }
1504 
1505  for (const IConsoleCmd *cmd = _iconsole_cmds; cmd != nullptr; cmd = cmd->next) {
1506  if (argv[1] == nullptr || strstr(cmd->name, argv[1]) != nullptr) {
1507  if (cmd->hook == nullptr || cmd->hook(false) != CHR_HIDE) IConsolePrintF(CC_DEFAULT, "%s", cmd->name);
1508  }
1509  }
1510 
1511  return true;
1512 }
1513 
1514 DEF_CONSOLE_CMD(ConListAliases)
1515 {
1516  if (argc == 0) {
1517  IConsoleHelp("List all registered aliases. Usage: 'list_aliases [<pre-filter>]'");
1518  return true;
1519  }
1520 
1521  for (const IConsoleAlias *alias = _iconsole_aliases; alias != nullptr; alias = alias->next) {
1522  if (argv[1] == nullptr || strstr(alias->name, argv[1]) != nullptr) {
1523  IConsolePrintF(CC_DEFAULT, "%s => %s", alias->name, alias->cmdline);
1524  }
1525  }
1526 
1527  return true;
1528 }
1529 
1530 DEF_CONSOLE_CMD(ConCompanies)
1531 {
1532  if (argc == 0) {
1533  IConsoleHelp("List the details of all companies in the game. Usage 'companies'");
1534  return true;
1535  }
1536 
1537  for (const Company *c : Company::Iterate()) {
1538  /* Grab the company name */
1539  char company_name[512];
1540  SetDParam(0, c->index);
1541  GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
1542 
1543  const char *password_state = "";
1544  if (c->is_ai) {
1545  password_state = "AI";
1546  } else if (_network_server) {
1547  password_state = StrEmpty(_network_company_states[c->index].password) ? "unprotected" : "protected";
1548  }
1549 
1550  char colour[512];
1551  GetString(colour, STR_COLOUR_DARK_BLUE + _company_colours[c->index], lastof(colour));
1552  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",
1553  c->index + 1, colour, company_name,
1554  c->inaugurated_year, (int64)c->money, (int64)c->current_loan, (int64)CalculateCompanyValue(c),
1555  c->group_all[VEH_TRAIN].num_vehicle,
1556  c->group_all[VEH_ROAD].num_vehicle,
1557  c->group_all[VEH_AIRCRAFT].num_vehicle,
1558  c->group_all[VEH_SHIP].num_vehicle,
1559  password_state);
1560  }
1561 
1562  return true;
1563 }
1564 
1565 DEF_CONSOLE_CMD(ConSay)
1566 {
1567  if (argc == 0) {
1568  IConsoleHelp("Chat to your fellow players in a multiplayer game. Usage: 'say \"<msg>\"'");
1569  return true;
1570  }
1571 
1572  if (argc != 2) return false;
1573 
1574  if (!_network_server) {
1575  NetworkClientSendChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0 /* param does not matter */, argv[1]);
1576  } else {
1577  bool from_admin = (_redirect_console_to_admin < INVALID_ADMIN_ID);
1578  NetworkServerSendChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0, argv[1], CLIENT_ID_SERVER, from_admin);
1579  }
1580 
1581  return true;
1582 }
1583 
1584 DEF_CONSOLE_CMD(ConSayCompany)
1585 {
1586  if (argc == 0) {
1587  IConsoleHelp("Chat to a certain company in a multiplayer game. Usage: 'say_company <company-no> \"<msg>\"'");
1588  IConsoleHelp("CompanyNo is the company that plays as company <companyno>, 1 through max_companies");
1589  return true;
1590  }
1591 
1592  if (argc != 3) return false;
1593 
1594  CompanyID company_id = (CompanyID)(atoi(argv[1]) - 1);
1595  if (!Company::IsValidID(company_id)) {
1596  IConsolePrintF(CC_DEFAULT, "Unknown company. Company range is between 1 and %d.", MAX_COMPANIES);
1597  return true;
1598  }
1599 
1600  if (!_network_server) {
1601  NetworkClientSendChat(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, company_id, argv[2]);
1602  } else {
1603  bool from_admin = (_redirect_console_to_admin < INVALID_ADMIN_ID);
1604  NetworkServerSendChat(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, company_id, argv[2], CLIENT_ID_SERVER, from_admin);
1605  }
1606 
1607  return true;
1608 }
1609 
1610 DEF_CONSOLE_CMD(ConSayClient)
1611 {
1612  if (argc == 0) {
1613  IConsoleHelp("Chat to a certain client in a multiplayer game. Usage: 'say_client <client-no> \"<msg>\"'");
1614  IConsoleHelp("For client-id's, see the command 'clients'");
1615  return true;
1616  }
1617 
1618  if (argc != 3) return false;
1619 
1620  if (!_network_server) {
1621  NetworkClientSendChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2]);
1622  } else {
1623  bool from_admin = (_redirect_console_to_admin < INVALID_ADMIN_ID);
1624  NetworkServerSendChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2], CLIENT_ID_SERVER, from_admin);
1625  }
1626 
1627  return true;
1628 }
1629 
1630 DEF_CONSOLE_CMD(ConCompanyPassword)
1631 {
1632  if (argc == 0) {
1633  const char *helpmsg;
1634 
1635  if (_network_dedicated) {
1636  helpmsg = "Change the password of a company. Usage: 'company_pw <company-no> \"<password>\"";
1637  } else if (_network_server) {
1638  helpmsg = "Change the password of your or any other company. Usage: 'company_pw [<company-no>] \"<password>\"'";
1639  } else {
1640  helpmsg = "Change the password of your company. Usage: 'company_pw \"<password>\"'";
1641  }
1642 
1643  IConsoleHelp(helpmsg);
1644  IConsoleHelp("Use \"*\" to disable the password.");
1645  return true;
1646  }
1647 
1648  CompanyID company_id;
1649  const char *password;
1650  const char *errormsg;
1651 
1652  if (argc == 2) {
1653  company_id = _local_company;
1654  password = argv[1];
1655  errormsg = "You have to own a company to make use of this command.";
1656  } else if (argc == 3 && _network_server) {
1657  company_id = (CompanyID)(atoi(argv[1]) - 1);
1658  password = argv[2];
1659  errormsg = "You have to specify the ID of a valid human controlled company.";
1660  } else {
1661  return false;
1662  }
1663 
1664  if (!Company::IsValidHumanID(company_id)) {
1665  IConsoleError(errormsg);
1666  return false;
1667  }
1668 
1669  password = NetworkChangeCompanyPassword(company_id, password);
1670 
1671  if (StrEmpty(password)) {
1672  IConsolePrintF(CC_WARNING, "Company password cleared");
1673  } else {
1674  IConsolePrintF(CC_WARNING, "Company password changed to: %s", password);
1675  }
1676 
1677  return true;
1678 }
1679 
1680 /* Content downloading only is available with ZLIB */
1681 #if defined(WITH_ZLIB)
1682 #include "network/network_content.h"
1683 
1685 static ContentType StringToContentType(const char *str)
1686 {
1687  static const char * const inv_lookup[] = { "", "base", "newgrf", "ai", "ailib", "scenario", "heightmap" };
1688  for (uint i = 1 /* there is no type 0 */; i < lengthof(inv_lookup); i++) {
1689  if (strcasecmp(str, inv_lookup[i]) == 0) return (ContentType)i;
1690  }
1691  return CONTENT_TYPE_END;
1692 }
1693 
1696  void OnConnect(bool success)
1697  {
1698  IConsolePrintF(CC_DEFAULT, "Content server connection %s", success ? "established" : "failed");
1699  }
1700 
1702  {
1703  IConsolePrintF(CC_DEFAULT, "Content server connection closed");
1704  }
1705 
1707  {
1708  IConsolePrintF(CC_DEFAULT, "Completed download of %d", cid);
1709  }
1710 };
1711 
1716 static void OutputContentState(const ContentInfo *const ci)
1717 {
1718  static const char * const types[] = { "Base graphics", "NewGRF", "AI", "AI library", "Scenario", "Heightmap", "Base sound", "Base music", "Game script", "GS library" };
1719  assert_compile(lengthof(types) == CONTENT_TYPE_END - CONTENT_TYPE_BEGIN);
1720  static const char * const states[] = { "Not selected", "Selected", "Dep Selected", "Installed", "Unknown" };
1721  static const TextColour state_to_colour[] = { CC_COMMAND, CC_INFO, CC_INFO, CC_WHITE, CC_ERROR };
1722 
1723  char buf[sizeof(ci->md5sum) * 2 + 1];
1724  md5sumToString(buf, lastof(buf), ci->md5sum);
1725  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);
1726 }
1727 
1728 DEF_CONSOLE_CMD(ConContent)
1729 {
1730  static ContentCallback *cb = nullptr;
1731  if (cb == nullptr) {
1732  cb = new ConsoleContentCallback();
1734  }
1735 
1736  if (argc <= 1) {
1737  IConsoleHelp("Query, select and download content. Usage: 'content update|upgrade|select [all|id]|unselect [all|id]|state [filter]|download'");
1738  IConsoleHelp(" update: get a new list of downloadable content; must be run first");
1739  IConsoleHelp(" upgrade: select all items that are upgrades");
1740  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");
1741  IConsoleHelp(" unselect: unselect a specific item given by its id or 'all' to unselect all");
1742  IConsoleHelp(" state: show the download/select state of all downloadable content. Optionally give a filter string");
1743  IConsoleHelp(" download: download all content you've selected");
1744  return true;
1745  }
1746 
1747  if (strcasecmp(argv[1], "update") == 0) {
1749  return true;
1750  }
1751 
1752  if (strcasecmp(argv[1], "upgrade") == 0) {
1754  return true;
1755  }
1756 
1757  if (strcasecmp(argv[1], "select") == 0) {
1758  if (argc <= 2) {
1759  /* List selected content */
1760  IConsolePrintF(CC_WHITE, "id, type, state, name");
1762  if ((*iter)->state != ContentInfo::SELECTED && (*iter)->state != ContentInfo::AUTOSELECTED) continue;
1763  OutputContentState(*iter);
1764  }
1765  } else if (strcasecmp(argv[2], "all") == 0) {
1767  } else {
1768  _network_content_client.Select((ContentID)atoi(argv[2]));
1769  }
1770  return true;
1771  }
1772 
1773  if (strcasecmp(argv[1], "unselect") == 0) {
1774  if (argc <= 2) {
1775  IConsoleError("You must enter the id.");
1776  return false;
1777  }
1778  if (strcasecmp(argv[2], "all") == 0) {
1780  } else {
1781  _network_content_client.Unselect((ContentID)atoi(argv[2]));
1782  }
1783  return true;
1784  }
1785 
1786  if (strcasecmp(argv[1], "state") == 0) {
1787  IConsolePrintF(CC_WHITE, "id, type, state, name");
1789  if (argc > 2 && strcasestr((*iter)->name, argv[2]) == nullptr) continue;
1790  OutputContentState(*iter);
1791  }
1792  return true;
1793  }
1794 
1795  if (strcasecmp(argv[1], "download") == 0) {
1796  uint files;
1797  uint bytes;
1799  IConsolePrintF(CC_DEFAULT, "Downloading %d file(s) (%d bytes)", files, bytes);
1800  return true;
1801  }
1802 
1803  return false;
1804 }
1805 #endif /* defined(WITH_ZLIB) */
1806 
1807 DEF_CONSOLE_CMD(ConSetting)
1808 {
1809  if (argc == 0) {
1810  IConsoleHelp("Change setting for all clients. Usage: 'setting <name> [<value>]'");
1811  IConsoleHelp("Omitting <value> will print out the current value of the setting.");
1812  return true;
1813  }
1814 
1815  if (argc == 1 || argc > 3) return false;
1816 
1817  if (argc == 2) {
1818  IConsoleGetSetting(argv[1]);
1819  } else {
1820  IConsoleSetSetting(argv[1], argv[2]);
1821  }
1822 
1823  return true;
1824 }
1825 
1826 DEF_CONSOLE_CMD(ConSettingNewgame)
1827 {
1828  if (argc == 0) {
1829  IConsoleHelp("Change setting for the next game. Usage: 'setting_newgame <name> [<value>]'");
1830  IConsoleHelp("Omitting <value> will print out the current value of the setting.");
1831  return true;
1832  }
1833 
1834  if (argc == 1 || argc > 3) return false;
1835 
1836  if (argc == 2) {
1837  IConsoleGetSetting(argv[1], true);
1838  } else {
1839  IConsoleSetSetting(argv[1], argv[2], true);
1840  }
1841 
1842  return true;
1843 }
1844 
1845 DEF_CONSOLE_CMD(ConListSettings)
1846 {
1847  if (argc == 0) {
1848  IConsoleHelp("List settings. Usage: 'list_settings [<pre-filter>]'");
1849  return true;
1850  }
1851 
1852  if (argc > 2) return false;
1853 
1854  IConsoleListSettings((argc == 2) ? argv[1] : nullptr);
1855  return true;
1856 }
1857 
1858 DEF_CONSOLE_CMD(ConGamelogPrint)
1859 {
1861  return true;
1862 }
1863 
1864 DEF_CONSOLE_CMD(ConNewGRFReload)
1865 {
1866  if (argc == 0) {
1867  IConsoleHelp("Reloads all active NewGRFs from disk. Equivalent to reapplying NewGRFs via the settings, but without asking for confirmation. This might crash OpenTTD!");
1868  return true;
1869  }
1870 
1871  ReloadNewGRFData();
1872  return true;
1873 }
1874 
1875 #ifdef _DEBUG
1876 /******************
1877  * debug commands
1878  ******************/
1879 
1880 static void IConsoleDebugLibRegister()
1881 {
1882  IConsoleCmdRegister("resettile", ConResetTile);
1883  IConsoleAliasRegister("dbg_echo", "echo %A; echo %B");
1884  IConsoleAliasRegister("dbg_echo2", "echo %!");
1885 }
1886 #endif
1887 
1888 DEF_CONSOLE_CMD(ConFramerate)
1889 {
1890  extern void ConPrintFramerate(); // framerate_gui.cpp
1891 
1892  if (argc == 0) {
1893  IConsoleHelp("Show frame rate and game speed information");
1894  return true;
1895  }
1896 
1898  return true;
1899 }
1900 
1901 DEF_CONSOLE_CMD(ConFramerateWindow)
1902 {
1903  extern void ShowFramerateWindow();
1904 
1905  if (argc == 0) {
1906  IConsoleHelp("Open the frame rate window");
1907  return true;
1908  }
1909 
1910  if (_network_dedicated) {
1911  IConsoleError("Can not open frame rate window on a dedicated server");
1912  return false;
1913  }
1914 
1916  return true;
1917 }
1918 
1919 /*******************************
1920  * console command registration
1921  *******************************/
1922 
1923 void IConsoleStdLibRegister()
1924 {
1925  IConsoleCmdRegister("debug_level", ConDebugLevel);
1926  IConsoleCmdRegister("echo", ConEcho);
1927  IConsoleCmdRegister("echoc", ConEchoC);
1928  IConsoleCmdRegister("exec", ConExec);
1929  IConsoleCmdRegister("exit", ConExit);
1930  IConsoleCmdRegister("part", ConPart);
1931  IConsoleCmdRegister("help", ConHelp);
1932  IConsoleCmdRegister("info_cmd", ConInfoCmd);
1933  IConsoleCmdRegister("list_cmds", ConListCommands);
1934  IConsoleCmdRegister("list_aliases", ConListAliases);
1935  IConsoleCmdRegister("newgame", ConNewGame);
1936  IConsoleCmdRegister("restart", ConRestart);
1937  IConsoleCmdRegister("getseed", ConGetSeed);
1938  IConsoleCmdRegister("getdate", ConGetDate);
1939  IConsoleCmdRegister("getsysdate", ConGetSysDate);
1940  IConsoleCmdRegister("quit", ConExit);
1941  IConsoleCmdRegister("resetengines", ConResetEngines, ConHookNoNetwork);
1942  IConsoleCmdRegister("reset_enginepool", ConResetEnginePool, ConHookNoNetwork);
1943  IConsoleCmdRegister("return", ConReturn);
1944  IConsoleCmdRegister("screenshot", ConScreenShot);
1945  IConsoleCmdRegister("script", ConScript);
1946  IConsoleCmdRegister("scrollto", ConScrollToTile);
1947  IConsoleCmdRegister("alias", ConAlias);
1948  IConsoleCmdRegister("load", ConLoad);
1949  IConsoleCmdRegister("rm", ConRemove);
1950  IConsoleCmdRegister("save", ConSave);
1951  IConsoleCmdRegister("saveconfig", ConSaveConfig);
1952  IConsoleCmdRegister("ls", ConListFiles);
1953  IConsoleCmdRegister("cd", ConChangeDirectory);
1954  IConsoleCmdRegister("pwd", ConPrintWorkingDirectory);
1955  IConsoleCmdRegister("clear", ConClearBuffer);
1956  IConsoleCmdRegister("setting", ConSetting);
1957  IConsoleCmdRegister("setting_newgame", ConSettingNewgame);
1958  IConsoleCmdRegister("list_settings",ConListSettings);
1959  IConsoleCmdRegister("gamelog", ConGamelogPrint);
1960  IConsoleCmdRegister("rescan_newgrf", ConRescanNewGRF);
1961 
1962  IConsoleAliasRegister("dir", "ls");
1963  IConsoleAliasRegister("del", "rm %+");
1964  IConsoleAliasRegister("newmap", "newgame");
1965  IConsoleAliasRegister("patch", "setting %+");
1966  IConsoleAliasRegister("set", "setting %+");
1967  IConsoleAliasRegister("set_newgame", "setting_newgame %+");
1968  IConsoleAliasRegister("list_patches", "list_settings %+");
1969  IConsoleAliasRegister("developer", "setting developer %+");
1970 
1971  IConsoleCmdRegister("list_ai_libs", ConListAILibs);
1972  IConsoleCmdRegister("list_ai", ConListAI);
1973  IConsoleCmdRegister("reload_ai", ConReloadAI);
1974  IConsoleCmdRegister("rescan_ai", ConRescanAI);
1975  IConsoleCmdRegister("start_ai", ConStartAI);
1976  IConsoleCmdRegister("stop_ai", ConStopAI);
1977 
1978  IConsoleCmdRegister("list_game", ConListGame);
1979  IConsoleCmdRegister("list_game_libs", ConListGameLibs);
1980  IConsoleCmdRegister("rescan_game", ConRescanGame);
1981 
1982  IConsoleCmdRegister("companies", ConCompanies);
1983  IConsoleAliasRegister("players", "companies");
1984 
1985  /* networking functions */
1986 
1987 /* Content downloading is only available with ZLIB */
1988 #if defined(WITH_ZLIB)
1989  IConsoleCmdRegister("content", ConContent);
1990 #endif /* defined(WITH_ZLIB) */
1991 
1992  /*** Networking commands ***/
1993  IConsoleCmdRegister("say", ConSay, ConHookNeedNetwork);
1994  IConsoleCmdRegister("say_company", ConSayCompany, ConHookNeedNetwork);
1995  IConsoleAliasRegister("say_player", "say_company %+");
1996  IConsoleCmdRegister("say_client", ConSayClient, ConHookNeedNetwork);
1997 
1998  IConsoleCmdRegister("connect", ConNetworkConnect, ConHookClientOnly);
1999  IConsoleCmdRegister("clients", ConNetworkClients, ConHookNeedNetwork);
2000  IConsoleCmdRegister("status", ConStatus, ConHookServerOnly);
2001  IConsoleCmdRegister("server_info", ConServerInfo, ConHookServerOnly);
2002  IConsoleAliasRegister("info", "server_info");
2003  IConsoleCmdRegister("reconnect", ConNetworkReconnect, ConHookClientOnly);
2004  IConsoleCmdRegister("rcon", ConRcon, ConHookNeedNetwork);
2005 
2006  IConsoleCmdRegister("join", ConJoinCompany, ConHookNeedNetwork);
2007  IConsoleAliasRegister("spectate", "join 255");
2008  IConsoleCmdRegister("move", ConMoveClient, ConHookServerOnly);
2009  IConsoleCmdRegister("reset_company", ConResetCompany, ConHookServerOnly);
2010  IConsoleAliasRegister("clean_company", "reset_company %A");
2011  IConsoleCmdRegister("client_name", ConClientNickChange, ConHookServerOnly);
2012  IConsoleCmdRegister("kick", ConKick, ConHookServerOnly);
2013  IConsoleCmdRegister("ban", ConBan, ConHookServerOnly);
2014  IConsoleCmdRegister("unban", ConUnBan, ConHookServerOnly);
2015  IConsoleCmdRegister("banlist", ConBanList, ConHookServerOnly);
2016 
2017  IConsoleCmdRegister("pause", ConPauseGame, ConHookServerOnly);
2018  IConsoleCmdRegister("unpause", ConUnpauseGame, ConHookServerOnly);
2019 
2020  IConsoleCmdRegister("company_pw", ConCompanyPassword, ConHookNeedNetwork);
2021  IConsoleAliasRegister("company_password", "company_pw %+");
2022 
2023  IConsoleAliasRegister("net_frame_freq", "setting frame_freq %+");
2024  IConsoleAliasRegister("net_sync_freq", "setting sync_freq %+");
2025  IConsoleAliasRegister("server_pw", "setting server_password %+");
2026  IConsoleAliasRegister("server_password", "setting server_password %+");
2027  IConsoleAliasRegister("rcon_pw", "setting rcon_password %+");
2028  IConsoleAliasRegister("rcon_password", "setting rcon_password %+");
2029  IConsoleAliasRegister("name", "setting client_name %+");
2030  IConsoleAliasRegister("server_name", "setting server_name %+");
2031  IConsoleAliasRegister("server_port", "setting server_port %+");
2032  IConsoleAliasRegister("server_advertise", "setting server_advertise %+");
2033  IConsoleAliasRegister("max_clients", "setting max_clients %+");
2034  IConsoleAliasRegister("max_companies", "setting max_companies %+");
2035  IConsoleAliasRegister("max_spectators", "setting max_spectators %+");
2036  IConsoleAliasRegister("max_join_time", "setting max_join_time %+");
2037  IConsoleAliasRegister("pause_on_join", "setting pause_on_join %+");
2038  IConsoleAliasRegister("autoclean_companies", "setting autoclean_companies %+");
2039  IConsoleAliasRegister("autoclean_protected", "setting autoclean_protected %+");
2040  IConsoleAliasRegister("autoclean_unprotected", "setting autoclean_unprotected %+");
2041  IConsoleAliasRegister("restart_game_year", "setting restart_game_year %+");
2042  IConsoleAliasRegister("min_players", "setting min_active_clients %+");
2043  IConsoleAliasRegister("reload_cfg", "setting reload_cfg %+");
2044 
2045  /* debugging stuff */
2046 #ifdef _DEBUG
2047  IConsoleDebugLibRegister();
2048 #endif
2049  IConsoleCmdRegister("fps", ConFramerate);
2050  IConsoleCmdRegister("fps_wnd", ConFramerateWindow);
2051 
2052  /* NewGRF development stuff */
2053  IConsoleCmdRegister("reload_newgrfs", ConNewGRFReload, ConHookNewGRFDeveloperTool);
2054 }
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:79
uint NetworkServerKickOrBanIP(ClientID client_id, bool ban)
Ban, or kick, everyone joined from the given client&#39;s IP.
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:79
used in multiplayer to create a new companies etc.
Definition: command_type.h:278
void IConsoleGetSetting(const char *name, bool force_newgame)
Output value of a specific setting to the console.
Definition: settings.cpp:2136
IConsoleCmd * next
next command in list
void IConsoleWarning(const char *string)
It is possible to print warnings to the console.
Definition: console.cpp:157
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:460
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
Container for all information known about a client.
Definition: network_base.h:23
IConsoleCmd * _iconsole_cmds
list of registered commands
Definition: console.cpp:26
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:3215
uint16 last_port
port of the last joined server
void FioFCloseFile(FILE *f)
Close a file in a safe way.
Definition: fileio.cpp:332
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:2874
Functions related to dates.
Day day
Day (1..31)
Definition: date_type.h:104
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:2169
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:27
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:81
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:2802
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:27
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:1742
uint8 map_x
X size of map.
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:86
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:2883
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:345
static char * GetConsoleLibraryList(char *p, const char *last)
Wrapper function for GameScanner::GetConsoleLibraryList.
Definition: game_core.cpp:233
IConsoleAlias * next
next alias in list
void NetworkServerKickClient(ClientID client_id)
Kick a single client.
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:84
IConsoleCmd * IConsoleCmdGet(const char *name)
Find the command pointed to by its string.
Definition: console.cpp:264
File list storage for the console, for caching the last &#39;ls&#39; command.
void IConsoleCmdExec(const char *cmdstr)
Execute a given command passed to us.
Definition: console.cpp:401
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:78
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:463
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:124
Definition of base types and functions in a cross-platform compatible way.
Data structure to convert between Date and triplet (year, month, and day).
Definition: date_type.h:101
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:102
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:2717
bool DoCommandP(const CommandContainer *container, bool my_cmd)
Shortcut for the long DoCommandP when having a container with the data.
Definition: command.cpp:532
#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
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:103
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:302
uint8 max_companies
maximum amount of companies
char * RemoveUnderscores(char *name)
Remove underscores from a string; the string will be modified!
Definition: console.cpp:233
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:809
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.
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.
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:340
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.
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:279
static size_t GetNumItems()
Returns number of valid items in the pool.
Definition: pool_type.hpp:321
List of file information.
Definition: fios.h:112
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:167
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.
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:280
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:780
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:310
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:2845
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.
Window functions not directly related to making/drawing windows.
void ReloadNewGRFData()
Reload all NewGRF files during a running game.
Definition: afterload.cpp:3131
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:26
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:92
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:80
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:179
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:248
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
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:254