|
@@ -182,25 +182,25 @@ DEF_CONSOLE_HOOK(ConHookNewGRFDeveloperT
|
|
|
}
|
|
|
return ConHookNoNetwork(echo);
|
|
|
}
|
|
|
return CHR_HIDE;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Show help for the console.
|
|
|
* @param str String to print in the console.
|
|
|
*/
|
|
|
static void IConsoleHelp(const char *str)
|
|
|
{
|
|
|
IConsolePrintF(CC_HELP, "- {}", str);
|
|
|
IConsolePrint(CC_HELP, "- {}", str);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Reset status of all engines.
|
|
|
* @return Will always succeed.
|
|
|
*/
|
|
|
DEF_CONSOLE_CMD(ConResetEngines)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Reset status data of all engines. This might solve some issues with 'lost' engines. Usage: 'resetengines'");
|
|
|
return true;
|
|
|
}
|
|
@@ -316,27 +316,27 @@ DEF_CONSOLE_CMD(ConScrollToTile)
|
|
|
DEF_CONSOLE_CMD(ConSave)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Save the current game. Usage: 'save <filename>'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc == 2) {
|
|
|
char *filename = str_fmt("%s.sav", argv[1]);
|
|
|
IConsolePrint(CC_DEFAULT, "Saving map...");
|
|
|
|
|
|
if (SaveOrLoad(filename, SLO_SAVE, DFT_GAME_FILE, SAVE_DIR) != SL_OK) {
|
|
|
IConsolePrint(CC_ERROR, "Saving map failed");
|
|
|
IConsolePrint(CC_ERROR, "Saving map failed.");
|
|
|
} else {
|
|
|
IConsolePrintF(CC_DEFAULT, "Map successfully saved to %s", filename);
|
|
|
IConsolePrint(CC_INFO, "Map successfully saved to '{}'.", filename);
|
|
|
}
|
|
|
free(filename);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Explicitly save the configuration.
|
|
|
* @return True.
|
|
|
*/
|
|
@@ -408,25 +408,25 @@ DEF_CONSOLE_CMD(ConRemove)
|
|
|
|
|
|
|
|
|
/* List all the files in the current dir via console */
|
|
|
DEF_CONSOLE_CMD(ConListFiles)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("List all loadable savegames and directories in the current dir via console. Usage: 'ls | dir'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
_console_file_list.ValidateFileList(true);
|
|
|
for (uint i = 0; i < _console_file_list.size(); i++) {
|
|
|
IConsolePrintF(CC_DEFAULT, "%d) %s", i, _console_file_list[i].title);
|
|
|
IConsolePrint(CC_DEFAULT, "{}) {}", i, _console_file_list[i].title);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/* Change the dir via console */
|
|
|
DEF_CONSOLE_CMD(ConChangeDirectory)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Change the dir via console. Usage: 'cd <directory | number>'");
|
|
|
return true;
|
|
|
}
|
|
@@ -514,25 +514,25 @@ static bool ConKickOrBan(const char *arg
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/* When banning, kick+ban all clients with that IP */
|
|
|
n = NetworkServerKickOrBanIP(client_id, ban, reason);
|
|
|
} else {
|
|
|
n = NetworkServerKickOrBanIP(argv, ban, reason);
|
|
|
}
|
|
|
|
|
|
if (n == 0) {
|
|
|
IConsolePrint(CC_DEFAULT, ban ? "Client not online, address added to banlist." : "Client not found.");
|
|
|
} else {
|
|
|
IConsolePrintF(CC_DEFAULT, "%sed %u client(s).", ban ? "Bann" : "Kick", n);
|
|
|
IConsolePrint(CC_DEFAULT, "{}ed {} client(s).", ban ? "Bann" : "Kick", n);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConKick)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Kick a client from a network game. Usage: 'kick <ip | client-id> [<kick-reason>]'");
|
|
|
IConsoleHelp("For client-id's, see the command 'clients'");
|
|
|
return true;
|
|
|
}
|
|
@@ -589,48 +589,46 @@ DEF_CONSOLE_CMD(ConUnBan)
|
|
|
/* Try by IP. */
|
|
|
uint index;
|
|
|
for (index = 0; index < _network_ban_list.size(); index++) {
|
|
|
if (_network_ban_list[index] == argv[1]) break;
|
|
|
}
|
|
|
|
|
|
/* Try by index. */
|
|
|
if (index >= _network_ban_list.size()) {
|
|
|
index = atoi(argv[1]) - 1U; // let it wrap
|
|
|
}
|
|
|
|
|
|
if (index < _network_ban_list.size()) {
|
|
|
char msg[64];
|
|
|
seprintf(msg, lastof(msg), "Unbanned %s", _network_ban_list[index].c_str());
|
|
|
IConsolePrint(CC_DEFAULT, msg);
|
|
|
IConsolePrint(CC_DEFAULT, "Unbanned {}.", _network_ban_list[index]);
|
|
|
_network_ban_list.erase(_network_ban_list.begin() + index);
|
|
|
} else {
|
|
|
IConsolePrint(CC_DEFAULT, "Invalid list index or IP not in ban-list.");
|
|
|
IConsolePrint(CC_DEFAULT, "For a list of banned IP's, see the command 'banlist'");
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConBanList)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("List the IP's of banned clients: Usage 'banlist'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
IConsolePrint(CC_DEFAULT, "Banlist: ");
|
|
|
|
|
|
uint i = 1;
|
|
|
for (const auto &entry : _network_ban_list) {
|
|
|
IConsolePrintF(CC_DEFAULT, " %d) %s", i, entry.c_str());
|
|
|
IConsolePrint(CC_DEFAULT, " {}) {}", i, entry);
|
|
|
i++;
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConPauseGame)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Pause a network game. Usage: 'pause'");
|
|
|
return true;
|
|
|
}
|
|
@@ -704,27 +702,27 @@ DEF_CONSOLE_CMD(ConStatus)
|
|
|
NetworkServerShowStatusToConsole();
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConServerInfo)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("List current and maximum client/company limits. Usage 'server_info'");
|
|
|
IConsoleHelp("You can change these values by modifying settings 'network.max_clients', 'network.max_companies' and 'network.max_spectators'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
IConsolePrintF(CC_DEFAULT, "Current/maximum clients: %2d/%2d", _network_game_info.clients_on, _settings_client.network.max_clients);
|
|
|
IConsolePrintF(CC_DEFAULT, "Current/maximum companies: %2d/%2d", (int)Company::GetNumItems(), _settings_client.network.max_companies);
|
|
|
IConsolePrintF(CC_DEFAULT, "Current/maximum spectators: %2d/%2d", NetworkSpectatorCount(), _settings_client.network.max_spectators);
|
|
|
IConsolePrint(CC_DEFAULT, "Current/maximum clients: {:3d}/{:3d}", _network_game_info.clients_on, _settings_client.network.max_clients);
|
|
|
IConsolePrint(CC_DEFAULT, "Current/maximum companies: {:3d}/{:3d}", Company::GetNumItems(), _settings_client.network.max_companies);
|
|
|
IConsolePrint(CC_DEFAULT, "Current/maximum spectators: {:3d}/{:3d}", NetworkSpectatorCount(), _settings_client.network.max_spectators);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConClientNickChange)
|
|
|
{
|
|
|
if (argc != 3) {
|
|
|
IConsoleHelp("Change the nickname of a connected client. Usage: 'client_name <client-id> <new-name>'");
|
|
|
IConsoleHelp("For client-id's, see the command 'clients'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -913,25 +911,25 @@ DEF_CONSOLE_CMD(ConNetworkReconnect)
|
|
|
/* From a user pov 0 is a new company, internally it's different and all
|
|
|
* companies are offset by one to ease up on users (eg companies 1-8 not 0-7) */
|
|
|
if (playas < COMPANY_FIRST + 1 || playas > MAX_COMPANIES + 1) return false;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
if (_settings_client.network.last_joined.empty()) {
|
|
|
IConsolePrint(CC_DEFAULT, "No server for reconnecting.");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/* Don't resolve the address first, just print it directly as it comes from the config file. */
|
|
|
IConsolePrintF(CC_DEFAULT, "Reconnecting to %s ...", _settings_client.network.last_joined.c_str());
|
|
|
IConsolePrint(CC_DEFAULT, "Reconnecting to {} ...", _settings_client.network.last_joined);
|
|
|
|
|
|
return NetworkClientConnectGame(_settings_client.network.last_joined, playas);
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConNetworkConnect)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Connect to a remote OTTD server and join the game. Usage: 'connect <ip>'");
|
|
|
IConsoleHelp("IP can contain port and company: 'IP[:Port][#Company]', eg: 'server.ottd.org:443#2'");
|
|
|
IConsoleHelp("Company #255 is spectator all others are a certain company with Company 1 being #1");
|
|
|
return true;
|
|
|
}
|
|
@@ -1016,27 +1014,30 @@ DEF_CONSOLE_CMD(ConScript)
|
|
|
{
|
|
|
extern FILE *_iconsole_output_file;
|
|
|
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Start or stop logging console output to a file. Usage: 'script <filename>'");
|
|
|
IConsoleHelp("If filename is omitted, a running log is stopped if it is active");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (!CloseConsoleLogIfActive()) {
|
|
|
if (argc < 2) return false;
|
|
|
|
|
|
IConsolePrintF(CC_DEFAULT, "file output started to: %s", argv[1]);
|
|
|
_iconsole_output_file = fopen(argv[1], "ab");
|
|
|
if (_iconsole_output_file == nullptr) IConsolePrint(CC_ERROR, "Could not open file '{}'.", argv[1]);
|
|
|
if (_iconsole_output_file == nullptr) {
|
|
|
IConsolePrint(CC_ERROR, "Could not open console log file '{}'.", argv[1]);
|
|
|
} else {
|
|
|
IConsolePrint(CC_INFO, "Console log output started to: '{}'", argv[1]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConEcho)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Print back the first argument to the console. Usage: 'echo <arg>'");
|
|
|
return true;
|
|
|
}
|
|
@@ -1108,25 +1109,25 @@ DEF_CONSOLE_CMD(ConReload)
|
|
|
/**
|
|
|
* Print a text buffer line by line to the console. Lines are separated by '\n'.
|
|
|
* @param buf The buffer to print.
|
|
|
* @note All newlines are replace by '\0' characters.
|
|
|
*/
|
|
|
static void PrintLineByLine(char *buf)
|
|
|
{
|
|
|
char *p = buf;
|
|
|
/* Print output line by line */
|
|
|
for (char *p2 = buf; *p2 != '\0'; p2++) {
|
|
|
if (*p2 == '\n') {
|
|
|
*p2 = '\0';
|
|
|
IConsolePrintF(CC_DEFAULT, "%s", p);
|
|
|
IConsolePrint(CC_DEFAULT, p);
|
|
|
p = p2 + 1;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConListAILibs)
|
|
|
{
|
|
|
char buf[4096];
|
|
|
AI::GetConsoleLibraryList(buf, lastof(buf));
|
|
|
|
|
|
PrintLineByLine(buf);
|
|
|
|
|
@@ -1248,25 +1249,25 @@ DEF_CONSOLE_CMD(ConReloadAI)
|
|
|
if (_game_mode != GM_NORMAL) {
|
|
|
IConsolePrint(CC_ERROR, "AIs can only be managed in a game.");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (_networking && !_network_server) {
|
|
|
IConsolePrint(CC_ERROR, "Only the server can reload an AI.");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
CompanyID company_id = (CompanyID)(atoi(argv[1]) - 1);
|
|
|
if (!Company::IsValidID(company_id)) {
|
|
|
IConsolePrintF(CC_DEFAULT, "Unknown company. Company range is between 1 and %d.", MAX_COMPANIES);
|
|
|
IConsolePrint(CC_ERROR, "Unknown company. Company range is between 1 and {}.", MAX_COMPANIES);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/* In singleplayer mode the player can be in an AI company, after cheating or loading network save with an AI in first slot. */
|
|
|
if (Company::IsHumanID(company_id) || company_id == _local_company) {
|
|
|
IConsolePrint(CC_ERROR, "Company is not controlled by an AI.");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/* First kill the company of the AI, then start a new one. This should start the current AI again */
|
|
|
DoCommandP(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0, CMD_COMPANY_CTRL);
|
|
|
DoCommandP(0, CCA_NEW_AI | company_id << 16, 0, CMD_COMPANY_CTRL);
|
|
@@ -1286,25 +1287,25 @@ DEF_CONSOLE_CMD(ConStopAI)
|
|
|
if (_game_mode != GM_NORMAL) {
|
|
|
IConsolePrint(CC_ERROR, "AIs can only be managed in a game.");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (_networking && !_network_server) {
|
|
|
IConsolePrint(CC_ERROR, "Only the server can stop an AI.");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
CompanyID company_id = (CompanyID)(atoi(argv[1]) - 1);
|
|
|
if (!Company::IsValidID(company_id)) {
|
|
|
IConsolePrintF(CC_DEFAULT, "Unknown company. Company range is between 1 and %d.", MAX_COMPANIES);
|
|
|
IConsolePrint(CC_ERROR, "Unknown company. Company range is between 1 and {}.", MAX_COMPANIES);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/* In singleplayer mode the player can be in an AI company, after cheating or loading network save with an AI in first slot. */
|
|
|
if (Company::IsHumanID(company_id) || company_id == _local_company) {
|
|
|
IConsolePrint(CC_ERROR, "Company is not controlled by an AI.");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/* Now kill the company of the AI. */
|
|
|
DoCommandP(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0, CMD_COMPANY_CTRL);
|
|
|
IConsolePrint(CC_DEFAULT, "AI stopped, company deleted.");
|
|
@@ -1359,51 +1360,51 @@ DEF_CONSOLE_CMD(ConRescanNewGRF)
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConGetSeed)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Returns the seed used to create this game. Usage: 'getseed'");
|
|
|
IConsoleHelp("The seed can be used to reproduce the exact same map as the game started with.");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
IConsolePrintF(CC_DEFAULT, "Generation Seed: %u", _settings_game.game_creation.generation_seed);
|
|
|
IConsolePrint(CC_DEFAULT, "Generation Seed: {}", _settings_game.game_creation.generation_seed);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConGetDate)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Returns the current date (year-month-day) of the game. Usage: 'getdate'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
YearMonthDay ymd;
|
|
|
ConvertDateToYMD(_date, &ymd);
|
|
|
IConsolePrintF(CC_DEFAULT, "Date: %04d-%02d-%02d", ymd.year, ymd.month + 1, ymd.day);
|
|
|
IConsolePrint(CC_DEFAULT, "Date: {:04d}-{:02d}-{:02d}", ymd.year, ymd.month + 1, ymd.day);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConGetSysDate)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Returns the current date (year-month-day) of your system. Usage: 'getsysdate'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
char buffer[lengthof("2000-01-02 03:04:05")];
|
|
|
LocalTime::Format(buffer, lastof(buffer), "%Y-%m-%d %H:%M:%S");
|
|
|
IConsolePrintF(CC_DEFAULT, "System Date: %s", buffer);
|
|
|
IConsolePrint(CC_DEFAULT, "System Date: {}", buffer);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConAlias)
|
|
|
{
|
|
|
IConsoleAlias *alias;
|
|
|
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Add a new alias, or redefine the behaviour of an existing alias . Usage: 'alias <name> <command>'");
|
|
|
return true;
|
|
|
}
|
|
@@ -1523,25 +1524,25 @@ DEF_CONSOLE_CMD(ConInfoCmd)
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConDebugLevel)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Get/set the default debugging level for the game. Usage: 'debug_level [<level>]'");
|
|
|
IConsoleHelp("Level can be any combination of names, levels. Eg 'net=5 ms=4'. Remember to enclose it in \"'s");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc > 2) return false;
|
|
|
|
|
|
if (argc == 1) {
|
|
|
IConsolePrintF(CC_DEFAULT, "Current debug-level: '%s'", GetDebugString());
|
|
|
IConsolePrint(CC_DEFAULT, "Current debug-level: '{}'", GetDebugString());
|
|
|
} else {
|
|
|
SetDebugString(argv[1]);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConExit)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Exit the game. Usage: 'exit'");
|
|
|
return true;
|
|
@@ -1576,25 +1577,25 @@ DEF_CONSOLE_CMD(ConHelp)
|
|
|
if (cmd != nullptr) {
|
|
|
cmd->proc(0, nullptr);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
alias = IConsole::AliasGet(argv[1]);
|
|
|
if (alias != nullptr) {
|
|
|
cmd = IConsole::CmdGet(alias->cmdline);
|
|
|
if (cmd != nullptr) {
|
|
|
cmd->proc(0, nullptr);
|
|
|
return true;
|
|
|
}
|
|
|
IConsolePrintF(CC_ERROR, "ERROR: alias is of special type, please see its execution-line: '%s'", alias->cmdline.c_str());
|
|
|
IConsolePrint(CC_ERROR, "Alias is of special type, please see its execution-line: '{}'.", alias->cmdline);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
IConsolePrint(CC_ERROR, "Command not found");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
IConsolePrint(TC_LIGHT_BLUE, " ---- OpenTTD Console Help ---- ");
|
|
|
IConsolePrint(CC_DEFAULT, " - commands: [command to list all commands: list_cmds]");
|
|
|
IConsolePrint(CC_DEFAULT, " call commands with '<command> <arg2> <arg3>...'");
|
|
|
IConsolePrint(CC_DEFAULT, " - to assign strings, or use them as arguments, enclose it within quotes");
|
|
|
IConsolePrint(CC_DEFAULT, " like this: '<command> \"string argument with spaces\"'");
|
|
@@ -1606,42 +1607,42 @@ DEF_CONSOLE_CMD(ConHelp)
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConListCommands)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("List all registered commands. Usage: 'list_cmds [<pre-filter>]'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
for (auto &it : IConsole::Commands()) {
|
|
|
const IConsoleCmd *cmd = &it.second;
|
|
|
if (argv[1] == nullptr || cmd->name.find(argv[1]) != std::string::npos) {
|
|
|
if (cmd->hook == nullptr || cmd->hook(false) != CHR_HIDE) IConsolePrintF(CC_DEFAULT, "%s", cmd->name.c_str());
|
|
|
if (cmd->hook == nullptr || cmd->hook(false) != CHR_HIDE) IConsolePrint(CC_DEFAULT, cmd->name);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConListAliases)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("List all registered aliases. Usage: 'list_aliases [<pre-filter>]'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
for (auto &it : IConsole::Aliases()) {
|
|
|
const IConsoleAlias *alias = &it.second;
|
|
|
if (argv[1] == nullptr || alias->name.find(argv[1]) != std::string::npos) {
|
|
|
IConsolePrintF(CC_DEFAULT, "%s => %s", alias->name.c_str(), alias->cmdline.c_str());
|
|
|
IConsolePrint(CC_DEFAULT, "{} => {}", alias->name, alias->cmdline);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConCompanies)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("List the details of all companies in the game. Usage 'companies'");
|
|
|
return true;
|
|
|
}
|
|
@@ -1652,25 +1653,25 @@ DEF_CONSOLE_CMD(ConCompanies)
|
|
|
SetDParam(0, c->index);
|
|
|
GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
|
|
|
|
|
|
const char *password_state = "";
|
|
|
if (c->is_ai) {
|
|
|
password_state = "AI";
|
|
|
} else if (_network_server) {
|
|
|
password_state = _network_company_states[c->index].password.empty() ? "unprotected" : "protected";
|
|
|
}
|
|
|
|
|
|
char colour[512];
|
|
|
GetString(colour, STR_COLOUR_DARK_BLUE + _company_colours[c->index], lastof(colour));
|
|
|
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",
|
|
|
IConsolePrint(CC_INFO, "#:{}({}) Company Name: '{}' Year Founded: {} Money: {} Loan: {} Value: {} (T:{}, R:{}, P:{}, S:{}) {}",
|
|
|
c->index + 1, colour, company_name,
|
|
|
c->inaugurated_year, (int64)c->money, (int64)c->current_loan, (int64)CalculateCompanyValue(c),
|
|
|
c->group_all[VEH_TRAIN].num_vehicle,
|
|
|
c->group_all[VEH_ROAD].num_vehicle,
|
|
|
c->group_all[VEH_AIRCRAFT].num_vehicle,
|
|
|
c->group_all[VEH_SHIP].num_vehicle,
|
|
|
password_state);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -1696,25 +1697,25 @@ DEF_CONSOLE_CMD(ConSay)
|
|
|
DEF_CONSOLE_CMD(ConSayCompany)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Chat to a certain company in a multiplayer game. Usage: 'say_company <company-no> \"<msg>\"'");
|
|
|
IConsoleHelp("CompanyNo is the company that plays as company <companyno>, 1 through max_companies");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc != 3) return false;
|
|
|
|
|
|
CompanyID company_id = (CompanyID)(atoi(argv[1]) - 1);
|
|
|
if (!Company::IsValidID(company_id)) {
|
|
|
IConsolePrintF(CC_DEFAULT, "Unknown company. Company range is between 1 and %d.", MAX_COMPANIES);
|
|
|
IConsolePrint(CC_DEFAULT, "Unknown company. Company range is between 1 and {}.", MAX_COMPANIES);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (!_network_server) {
|
|
|
NetworkClientSendChat(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, company_id, argv[2]);
|
|
|
} else {
|
|
|
bool from_admin = (_redirect_console_to_admin < INVALID_ADMIN_ID);
|
|
|
NetworkServerSendChat(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, company_id, argv[2], CLIENT_ID_SERVER, from_admin);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
@@ -1733,36 +1734,33 @@ DEF_CONSOLE_CMD(ConSayClient)
|
|
|
NetworkClientSendChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2]);
|
|
|
} else {
|
|
|
bool from_admin = (_redirect_console_to_admin < INVALID_ADMIN_ID);
|
|
|
NetworkServerSendChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2], CLIENT_ID_SERVER, from_admin);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConCompanyPassword)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
const char *helpmsg;
|
|
|
|
|
|
if (_network_dedicated) {
|
|
|
helpmsg = "Change the password of a company. Usage: 'company_pw <company-no> \"<password>\"";
|
|
|
IConsolePrint(CC_HELP, "Change the password of a company. Usage: 'company_pw <company-no> \"<password>\".");
|
|
|
} else if (_network_server) {
|
|
|
helpmsg = "Change the password of your or any other company. Usage: 'company_pw [<company-no>] \"<password>\"'";
|
|
|
IConsolePrint(CC_HELP, "Change the password of your or any other company. Usage: 'company_pw [<company-no>] \"<password>\"'.");
|
|
|
} else {
|
|
|
helpmsg = "Change the password of your company. Usage: 'company_pw \"<password>\"'";
|
|
|
IConsolePrint(CC_HELP, "Change the password of your company. Usage: 'company_pw \"<password>\"'.");
|
|
|
}
|
|
|
|
|
|
IConsoleHelp(helpmsg);
|
|
|
IConsoleHelp("Use \"*\" to disable the password.");
|
|
|
IConsolePrint(CC_HELP, "Use \"*\" to disable the password.");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
CompanyID company_id;
|
|
|
std::string password;
|
|
|
const char *errormsg;
|
|
|
|
|
|
if (argc == 2) {
|
|
|
company_id = _local_company;
|
|
|
password = argv[1];
|
|
|
errormsg = "You have to own a company to make use of this command.";
|
|
|
} else if (argc == 3 && _network_server) {
|
|
@@ -1798,52 +1796,52 @@ static ContentType StringToContentType(c
|
|
|
{
|
|
|
static const char * const inv_lookup[] = { "", "base", "newgrf", "ai", "ailib", "scenario", "heightmap" };
|
|
|
for (uint i = 1 /* there is no type 0 */; i < lengthof(inv_lookup); i++) {
|
|
|
if (strcasecmp(str, inv_lookup[i]) == 0) return (ContentType)i;
|
|
|
}
|
|
|
return CONTENT_TYPE_END;
|
|
|
}
|
|
|
|
|
|
/** Asynchronous callback */
|
|
|
struct ConsoleContentCallback : public ContentCallback {
|
|
|
void OnConnect(bool success)
|
|
|
{
|
|
|
IConsolePrintF(CC_DEFAULT, "Content server connection %s", success ? "established" : "failed");
|
|
|
IConsolePrint(CC_DEFAULT, "Content server connection {}.", success ? "established" : "failed");
|
|
|
}
|
|
|
|
|
|
void OnDisconnect()
|
|
|
{
|
|
|
IConsolePrintF(CC_DEFAULT, "Content server connection closed");
|
|
|
IConsolePrint(CC_DEFAULT, "Content server connection closed.");
|
|
|
}
|
|
|
|
|
|
void OnDownloadComplete(ContentID cid)
|
|
|
{
|
|
|
IConsolePrintF(CC_DEFAULT, "Completed download of %d", cid);
|
|
|
IConsolePrint(CC_DEFAULT, "Completed download of {}.", cid);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* Outputs content state information to console
|
|
|
* @param ci the content info
|
|
|
*/
|
|
|
static void OutputContentState(const ContentInfo *const ci)
|
|
|
{
|
|
|
static const char * const types[] = { "Base graphics", "NewGRF", "AI", "AI library", "Scenario", "Heightmap", "Base sound", "Base music", "Game script", "GS library" };
|
|
|
static_assert(lengthof(types) == CONTENT_TYPE_END - CONTENT_TYPE_BEGIN);
|
|
|
static const char * const states[] = { "Not selected", "Selected", "Dep Selected", "Installed", "Unknown" };
|
|
|
static const TextColour state_to_colour[] = { CC_COMMAND, CC_INFO, CC_INFO, CC_WHITE, CC_ERROR };
|
|
|
|
|
|
char buf[sizeof(ci->md5sum) * 2 + 1];
|
|
|
md5sumToString(buf, lastof(buf), ci->md5sum);
|
|
|
IConsolePrintF(state_to_colour[ci->state], "%d, %s, %s, %s, %08X, %s", ci->id, types[ci->type - 1], states[ci->state], ci->name.c_str(), ci->unique_id, buf);
|
|
|
IConsolePrint(state_to_colour[ci->state], "{}, {}, {}, {}, {:08X}, {}", ci->id, types[ci->type - 1], states[ci->state], ci->name, ci->unique_id, buf);
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConContent)
|
|
|
{
|
|
|
static ContentCallback *cb = nullptr;
|
|
|
if (cb == nullptr) {
|
|
|
cb = new ConsoleContentCallback();
|
|
|
_network_content_client.AddCallback(cb);
|
|
|
}
|
|
|
|
|
|
if (argc <= 1) {
|
|
|
IConsoleHelp("Query, select and download content. Usage: 'content update|upgrade|select [id]|unselect [all|id]|state [filter]|download'");
|
|
@@ -1860,25 +1858,25 @@ DEF_CONSOLE_CMD(ConContent)
|
|
|
_network_content_client.RequestContentList((argc > 2) ? StringToContentType(argv[2]) : CONTENT_TYPE_END);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (strcasecmp(argv[1], "upgrade") == 0) {
|
|
|
_network_content_client.SelectUpgrade();
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (strcasecmp(argv[1], "select") == 0) {
|
|
|
if (argc <= 2) {
|
|
|
/* List selected content */
|
|
|
IConsolePrintF(CC_WHITE, "id, type, state, name");
|
|
|
IConsolePrint(CC_WHITE, "id, type, state, name");
|
|
|
for (ConstContentIterator iter = _network_content_client.Begin(); iter != _network_content_client.End(); iter++) {
|
|
|
if ((*iter)->state != ContentInfo::SELECTED && (*iter)->state != ContentInfo::AUTOSELECTED) continue;
|
|
|
OutputContentState(*iter);
|
|
|
}
|
|
|
} else if (strcasecmp(argv[2], "all") == 0) {
|
|
|
/* The intention of this function was that you could download
|
|
|
* everything after a filter was applied; but this never really
|
|
|
* took off. Instead, a select few people used this functionality
|
|
|
* to download every available package on BaNaNaS. This is not in
|
|
|
* the spirit of this service. Additionally, these few people were
|
|
|
* good for 70% of the consumed bandwidth of BaNaNaS. */
|
|
|
IConsolePrint(CC_ERROR, "'select all' is no longer supported since 1.11.");
|
|
@@ -1893,37 +1891,37 @@ DEF_CONSOLE_CMD(ConContent)
|
|
|
IConsolePrint(CC_ERROR, "You must enter the id.");
|
|
|
return false;
|
|
|
}
|
|
|
if (strcasecmp(argv[2], "all") == 0) {
|
|
|
_network_content_client.UnselectAll();
|
|
|
} else {
|
|
|
_network_content_client.Unselect((ContentID)atoi(argv[2]));
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (strcasecmp(argv[1], "state") == 0) {
|
|
|
IConsolePrintF(CC_WHITE, "id, type, state, name");
|
|
|
IConsolePrint(CC_WHITE, "id, type, state, name");
|
|
|
for (ConstContentIterator iter = _network_content_client.Begin(); iter != _network_content_client.End(); iter++) {
|
|
|
if (argc > 2 && strcasestr((*iter)->name.c_str(), argv[2]) == nullptr) continue;
|
|
|
OutputContentState(*iter);
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (strcasecmp(argv[1], "download") == 0) {
|
|
|
uint files;
|
|
|
uint bytes;
|
|
|
_network_content_client.DownloadSelectedContent(files, bytes);
|
|
|
IConsolePrintF(CC_DEFAULT, "Downloading %d file(s) (%d bytes)", files, bytes);
|
|
|
IConsolePrint(CC_DEFAULT, "Downloading {} file(s) ({} bytes).", files, bytes);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
#endif /* defined(WITH_ZLIB) */
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConSetting)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Change setting for all clients. Usage: 'setting <name> [<value>]'");
|
|
|
IConsoleHelp("Omitting <value> will print out the current value of the setting.");
|
|
@@ -2013,25 +2011,25 @@ DEF_CONSOLE_CMD(ConNewGRFProfile)
|
|
|
const std::vector<GRFFile *> &files = GetAllGRFFiles();
|
|
|
|
|
|
/* "list" sub-command */
|
|
|
if (argc == 1 || strncasecmp(argv[1], "lis", 3) == 0) {
|
|
|
IConsolePrint(CC_INFO, "Loaded GRF files:");
|
|
|
int i = 1;
|
|
|
for (GRFFile *grf : files) {
|
|
|
auto profiler = std::find_if(_newgrf_profilers.begin(), _newgrf_profilers.end(), [&](NewGRFProfiler &pr) { return pr.grffile == grf; });
|
|
|
bool selected = profiler != _newgrf_profilers.end();
|
|
|
bool active = selected && profiler->active;
|
|
|
TextColour tc = active ? TC_LIGHT_BLUE : selected ? TC_GREEN : CC_INFO;
|
|
|
const char *statustext = active ? " (active)" : selected ? " (selected)" : "";
|
|
|
IConsolePrintF(tc, "%d: [%08X] %s%s", i, BSWAP32(grf->grfid), grf->filename, statustext);
|
|
|
IConsolePrint(tc, "{}: [{:08X}] {}{}", i, BSWAP32(grf->grfid), grf->filename, statustext);
|
|
|
i++;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/* "select" sub-command */
|
|
|
if (strncasecmp(argv[1], "sel", 3) == 0 && argc >= 3) {
|
|
|
for (size_t argnum = 2; argnum < argc; ++argnum) {
|
|
|
int grfnum = atoi(argv[argnum]);
|
|
|
if (grfnum < 1 || grfnum > (int)files.size()) { // safe cast, files.size() should not be larger than a few hundred in the most extreme cases
|
|
|
IConsolePrint(CC_WARNING, "GRF number {} out of range, not added.", grfnum);
|
|
|
continue;
|
|
@@ -2072,33 +2070,33 @@ DEF_CONSOLE_CMD(ConNewGRFProfile)
|
|
|
for (NewGRFProfiler &pr : _newgrf_profilers) {
|
|
|
if (!pr.active) {
|
|
|
pr.Start();
|
|
|
started++;
|
|
|
|
|
|
if (!grfids.empty()) grfids += ", ";
|
|
|
char grfidstr[12]{ 0 };
|
|
|
seprintf(grfidstr, lastof(grfidstr), "[%08X]", BSWAP32(pr.grffile->grfid));
|
|
|
grfids += grfidstr;
|
|
|
}
|
|
|
}
|
|
|
if (started > 0) {
|
|
|
IConsolePrintF(CC_DEBUG, "Started profiling for GRFID%s %s", (started > 1) ? "s" : "", grfids.c_str());
|
|
|
IConsolePrint(CC_DEBUG, "Started profiling for GRFID{} {}", (started > 1) ? "s" : "", grfids);
|
|
|
if (argc >= 3) {
|
|
|
int days = std::max(atoi(argv[2]), 1);
|
|
|
_newgrf_profile_end_date = _date + days;
|
|
|
|
|
|
char datestrbuf[32]{ 0 };
|
|
|
SetDParam(0, _newgrf_profile_end_date);
|
|
|
GetString(datestrbuf, STR_JUST_DATE_ISO, lastof(datestrbuf));
|
|
|
IConsolePrintF(CC_DEBUG, "Profiling will automatically stop on game date %s", datestrbuf);
|
|
|
IConsolePrint(CC_DEBUG, "Profiling will automatically stop on game date {}.", datestrbuf);
|
|
|
} else {
|
|
|
_newgrf_profile_end_date = MAX_DAY;
|
|
|
}
|
|
|
} else if (_newgrf_profilers.empty()) {
|
|
|
IConsolePrint(CC_ERROR, "No GRFs selected for profiling, did not start.");
|
|
|
} else {
|
|
|
IConsolePrint(CC_ERROR, "Did not start profiling for any GRFs, all selected GRFs are already profiling.");
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/* "stop" sub-command */
|
|
@@ -2156,144 +2154,144 @@ DEF_CONSOLE_CMD(ConFramerateWindow)
|
|
|
|
|
|
if (_network_dedicated) {
|
|
|
IConsolePrint(CC_ERROR, "Can not open frame rate window on a dedicated server");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
ShowFramerateWindow();
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
static void ConDumpRoadTypes()
|
|
|
{
|
|
|
IConsolePrintF(CC_DEFAULT, " Flags:");
|
|
|
IConsolePrintF(CC_DEFAULT, " c = catenary");
|
|
|
IConsolePrintF(CC_DEFAULT, " l = no level crossings");
|
|
|
IConsolePrintF(CC_DEFAULT, " X = no houses");
|
|
|
IConsolePrintF(CC_DEFAULT, " h = hidden");
|
|
|
IConsolePrintF(CC_DEFAULT, " T = buildable by towns");
|
|
|
IConsolePrint(CC_DEFAULT, " Flags:");
|
|
|
IConsolePrint(CC_DEFAULT, " c = catenary");
|
|
|
IConsolePrint(CC_DEFAULT, " l = no level crossings");
|
|
|
IConsolePrint(CC_DEFAULT, " X = no houses");
|
|
|
IConsolePrint(CC_DEFAULT, " h = hidden");
|
|
|
IConsolePrint(CC_DEFAULT, " T = buildable by towns");
|
|
|
|
|
|
std::map<uint32, const GRFFile *> grfs;
|
|
|
for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) {
|
|
|
const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
|
|
|
if (rti->label == 0) continue;
|
|
|
uint32 grfid = 0;
|
|
|
const GRFFile *grf = rti->grffile[ROTSG_GROUND];
|
|
|
if (grf != nullptr) {
|
|
|
grfid = grf->grfid;
|
|
|
grfs.emplace(grfid, grf);
|
|
|
}
|
|
|
IConsolePrintF(CC_DEFAULT, " %02u %s %c%c%c%c, Flags: %c%c%c%c%c, GRF: %08X, %s",
|
|
|
IConsolePrint(CC_DEFAULT, " {:02d} {} {:c}{:c}{:c}{:c}, Flags: {}{}{}{}{}, GRF: {:08X}, {}",
|
|
|
(uint)rt,
|
|
|
RoadTypeIsTram(rt) ? "Tram" : "Road",
|
|
|
rti->label >> 24, rti->label >> 16, rti->label >> 8, rti->label,
|
|
|
HasBit(rti->flags, ROTF_CATENARY) ? 'c' : '-',
|
|
|
HasBit(rti->flags, ROTF_NO_LEVEL_CROSSING) ? 'l' : '-',
|
|
|
HasBit(rti->flags, ROTF_NO_HOUSES) ? 'X' : '-',
|
|
|
HasBit(rti->flags, ROTF_HIDDEN) ? 'h' : '-',
|
|
|
HasBit(rti->flags, ROTF_TOWN_BUILD) ? 'T' : '-',
|
|
|
BSWAP32(grfid),
|
|
|
GetStringPtr(rti->strings.name)
|
|
|
);
|
|
|
}
|
|
|
for (const auto &grf : grfs) {
|
|
|
IConsolePrintF(CC_DEFAULT, " GRF: %08X = %s", BSWAP32(grf.first), grf.second->filename);
|
|
|
IConsolePrint(CC_DEFAULT, " GRF: {:08X} = {}", BSWAP32(grf.first), grf.second->filename);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void ConDumpRailTypes()
|
|
|
{
|
|
|
IConsolePrintF(CC_DEFAULT, " Flags:");
|
|
|
IConsolePrintF(CC_DEFAULT, " c = catenary");
|
|
|
IConsolePrintF(CC_DEFAULT, " l = no level crossings");
|
|
|
IConsolePrintF(CC_DEFAULT, " h = hidden");
|
|
|
IConsolePrintF(CC_DEFAULT, " s = no sprite combine");
|
|
|
IConsolePrintF(CC_DEFAULT, " a = always allow 90 degree turns");
|
|
|
IConsolePrintF(CC_DEFAULT, " d = always disallow 90 degree turns");
|
|
|
IConsolePrint(CC_DEFAULT, " Flags:");
|
|
|
IConsolePrint(CC_DEFAULT, " c = catenary");
|
|
|
IConsolePrint(CC_DEFAULT, " l = no level crossings");
|
|
|
IConsolePrint(CC_DEFAULT, " h = hidden");
|
|
|
IConsolePrint(CC_DEFAULT, " s = no sprite combine");
|
|
|
IConsolePrint(CC_DEFAULT, " a = always allow 90 degree turns");
|
|
|
IConsolePrint(CC_DEFAULT, " d = always disallow 90 degree turns");
|
|
|
|
|
|
std::map<uint32, const GRFFile *> grfs;
|
|
|
for (RailType rt = RAILTYPE_BEGIN; rt < RAILTYPE_END; rt++) {
|
|
|
const RailtypeInfo *rti = GetRailTypeInfo(rt);
|
|
|
if (rti->label == 0) continue;
|
|
|
uint32 grfid = 0;
|
|
|
const GRFFile *grf = rti->grffile[RTSG_GROUND];
|
|
|
if (grf != nullptr) {
|
|
|
grfid = grf->grfid;
|
|
|
grfs.emplace(grfid, grf);
|
|
|
}
|
|
|
IConsolePrintF(CC_DEFAULT, " %02u %c%c%c%c, Flags: %c%c%c%c%c%c, GRF: %08X, %s",
|
|
|
IConsolePrint(CC_DEFAULT, " {:02d} {:c}{:c}{:c}{:c}, Flags: {}{}{}{}{}{}, GRF: {:08X}, {}",
|
|
|
(uint)rt,
|
|
|
rti->label >> 24, rti->label >> 16, rti->label >> 8, rti->label,
|
|
|
HasBit(rti->flags, RTF_CATENARY) ? 'c' : '-',
|
|
|
HasBit(rti->flags, RTF_NO_LEVEL_CROSSING) ? 'l' : '-',
|
|
|
HasBit(rti->flags, RTF_HIDDEN) ? 'h' : '-',
|
|
|
HasBit(rti->flags, RTF_NO_SPRITE_COMBINE) ? 's' : '-',
|
|
|
HasBit(rti->flags, RTF_ALLOW_90DEG) ? 'a' : '-',
|
|
|
HasBit(rti->flags, RTF_DISALLOW_90DEG) ? 'd' : '-',
|
|
|
BSWAP32(grfid),
|
|
|
GetStringPtr(rti->strings.name)
|
|
|
);
|
|
|
}
|
|
|
for (const auto &grf : grfs) {
|
|
|
IConsolePrintF(CC_DEFAULT, " GRF: %08X = %s", BSWAP32(grf.first), grf.second->filename);
|
|
|
IConsolePrint(CC_DEFAULT, " GRF: {:08X} = {}", BSWAP32(grf.first), grf.second->filename);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void ConDumpCargoTypes()
|
|
|
{
|
|
|
IConsolePrintF(CC_DEFAULT, " Cargo classes:");
|
|
|
IConsolePrintF(CC_DEFAULT, " p = passenger");
|
|
|
IConsolePrintF(CC_DEFAULT, " m = mail");
|
|
|
IConsolePrintF(CC_DEFAULT, " x = express");
|
|
|
IConsolePrintF(CC_DEFAULT, " a = armoured");
|
|
|
IConsolePrintF(CC_DEFAULT, " b = bulk");
|
|
|
IConsolePrintF(CC_DEFAULT, " g = piece goods");
|
|
|
IConsolePrintF(CC_DEFAULT, " l = liquid");
|
|
|
IConsolePrintF(CC_DEFAULT, " r = refrigerated");
|
|
|
IConsolePrintF(CC_DEFAULT, " h = hazardous");
|
|
|
IConsolePrintF(CC_DEFAULT, " c = covered/sheltered");
|
|
|
IConsolePrintF(CC_DEFAULT, " S = special");
|
|
|
IConsolePrint(CC_DEFAULT, " Cargo classes:");
|
|
|
IConsolePrint(CC_DEFAULT, " p = passenger");
|
|
|
IConsolePrint(CC_DEFAULT, " m = mail");
|
|
|
IConsolePrint(CC_DEFAULT, " x = express");
|
|
|
IConsolePrint(CC_DEFAULT, " a = armoured");
|
|
|
IConsolePrint(CC_DEFAULT, " b = bulk");
|
|
|
IConsolePrint(CC_DEFAULT, " g = piece goods");
|
|
|
IConsolePrint(CC_DEFAULT, " l = liquid");
|
|
|
IConsolePrint(CC_DEFAULT, " r = refrigerated");
|
|
|
IConsolePrint(CC_DEFAULT, " h = hazardous");
|
|
|
IConsolePrint(CC_DEFAULT, " c = covered/sheltered");
|
|
|
IConsolePrint(CC_DEFAULT, " S = special");
|
|
|
|
|
|
std::map<uint32, const GRFFile *> grfs;
|
|
|
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
|
|
const CargoSpec *spec = CargoSpec::Get(i);
|
|
|
if (!spec->IsValid()) continue;
|
|
|
uint32 grfid = 0;
|
|
|
const GRFFile *grf = spec->grffile;
|
|
|
if (grf != nullptr) {
|
|
|
grfid = grf->grfid;
|
|
|
grfs.emplace(grfid, grf);
|
|
|
}
|
|
|
IConsolePrintF(CC_DEFAULT, " %02u Bit: %2u, Label: %c%c%c%c, Callback mask: 0x%02X, Cargo class: %c%c%c%c%c%c%c%c%c%c%c, GRF: %08X, %s",
|
|
|
IConsolePrint(CC_DEFAULT, " {:02d} Bit: {:2d}, Label: {:c}{:c}{:c}{:c}, Callback mask: 0x{:02X}, Cargo class: {}{}{}{}{}{}{}{}{}{}{}, GRF: {:08X}, {}",
|
|
|
(uint)i,
|
|
|
spec->bitnum,
|
|
|
spec->label >> 24, spec->label >> 16, spec->label >> 8, spec->label,
|
|
|
spec->callback_mask,
|
|
|
(spec->classes & CC_PASSENGERS) != 0 ? 'p' : '-',
|
|
|
(spec->classes & CC_MAIL) != 0 ? 'm' : '-',
|
|
|
(spec->classes & CC_EXPRESS) != 0 ? 'x' : '-',
|
|
|
(spec->classes & CC_ARMOURED) != 0 ? 'a' : '-',
|
|
|
(spec->classes & CC_BULK) != 0 ? 'b' : '-',
|
|
|
(spec->classes & CC_PIECE_GOODS) != 0 ? 'g' : '-',
|
|
|
(spec->classes & CC_LIQUID) != 0 ? 'l' : '-',
|
|
|
(spec->classes & CC_REFRIGERATED) != 0 ? 'r' : '-',
|
|
|
(spec->classes & CC_HAZARDOUS) != 0 ? 'h' : '-',
|
|
|
(spec->classes & CC_COVERED) != 0 ? 'c' : '-',
|
|
|
(spec->classes & CC_SPECIAL) != 0 ? 'S' : '-',
|
|
|
BSWAP32(grfid),
|
|
|
GetStringPtr(spec->name)
|
|
|
);
|
|
|
}
|
|
|
for (const auto &grf : grfs) {
|
|
|
IConsolePrintF(CC_DEFAULT, " GRF: %08X = %s", BSWAP32(grf.first), grf.second->filename);
|
|
|
IConsolePrint(CC_DEFAULT, " GRF: {:08X} = {}", BSWAP32(grf.first), grf.second->filename);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConDumpInfo)
|
|
|
{
|
|
|
if (argc != 2) {
|
|
|
IConsoleHelp("Dump debugging information.");
|
|
|
IConsoleHelp("Usage: dump_info roadtypes|railtypes|cargotypes");
|
|
|
IConsoleHelp(" Show information about road/tram types, rail types or cargo types.");
|
|
|
return true;
|
|
|
}
|