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