|
@@ -170,50 +170,51 @@ DEF_CONSOLE_CMD(ConScrollToTile)
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
extern bool SafeSaveOrLoad(const char *filename, int mode, int newgm);
|
|
|
extern void BuildFileList(void);
|
|
|
extern void SetFiosType(const byte fiostype);
|
|
|
|
|
|
/* Save the map to a file */
|
|
|
DEF_CONSOLE_CMD(ConSave)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Save the current game. Usage: 'save <filename>'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc == 2) {
|
|
|
char buf[200];
|
|
|
|
|
|
snprintf(buf, lengthof(buf), "%s%s%s.sav", _path.save_dir, PATHSEP, argv[1]);
|
|
|
IConsolePrint(_icolour_def, "Saving map...");
|
|
|
|
|
|
if (SaveOrLoad(buf, SL_SAVE) != SL_OK) {
|
|
|
IConsolePrint(_icolour_err, "SaveMap failed");
|
|
|
} else
|
|
|
} else {
|
|
|
IConsolePrintF(_icolour_def, "Map sucessfully saved to %s", buf);
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
static const FiosItem* GetFiosItem(const char* file)
|
|
|
{
|
|
|
int i;
|
|
|
|
|
|
_saveload_mode = SLD_LOAD_GAME;
|
|
|
BuildFileList();
|
|
|
|
|
|
for (i = 0; i < _fios_num; i++) {
|
|
|
if (strcmp(file, _fios_list[i].name) == 0) break;
|
|
|
if (strcmp(file, _fios_list[i].title) == 0) break;
|
|
|
}
|
|
|
|
|
|
if (i == _fios_num) { /* If no name matches, try to parse it as number */
|
|
|
char* endptr;
|
|
|
|
|
|
i = strtol(file, &endptr, 10);
|
|
|
if (file == endptr || *endptr != '\0') i = -1;
|
|
|
}
|
|
@@ -226,75 +227,77 @@ DEF_CONSOLE_CMD(ConLoad)
|
|
|
{
|
|
|
const FiosItem *item;
|
|
|
const char *file;
|
|
|
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Load a game by name or index. Usage: 'load <file | number>'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc != 2) return false;
|
|
|
|
|
|
file = argv[1];
|
|
|
item = GetFiosItem(file);
|
|
|
if (item != NULL) {
|
|
|
switch (item->type) {
|
|
|
case FIOS_TYPE_FILE: case FIOS_TYPE_OLDFILE: {
|
|
|
_switch_mode = SM_LOAD;
|
|
|
SetFiosType(item->type);
|
|
|
|
|
|
ttd_strlcpy(_file_to_saveload.name, FiosBrowseTo(item), sizeof(_file_to_saveload.name));
|
|
|
ttd_strlcpy(_file_to_saveload.title, item->title, sizeof(_file_to_saveload.title));
|
|
|
} break;
|
|
|
default: IConsolePrintF(_icolour_err, "%s: Not a savegame.", file);
|
|
|
}
|
|
|
} else
|
|
|
} else {
|
|
|
IConsolePrintF(_icolour_err, "%s: No such file or directory.", file);
|
|
|
}
|
|
|
|
|
|
FiosFreeSavegameList();
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConRemove)
|
|
|
{
|
|
|
const FiosItem* item;
|
|
|
const char* file;
|
|
|
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Remove a savegame by name or index. Usage: 'rm <file | number>'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc != 2) return false;
|
|
|
|
|
|
file = argv[1];
|
|
|
item = GetFiosItem(file);
|
|
|
if (item != NULL) {
|
|
|
if (!FiosDelete(item->name))
|
|
|
IConsolePrintF(_icolour_err, "%s: Failed to delete file", file);
|
|
|
} else
|
|
|
} else {
|
|
|
IConsolePrintF(_icolour_err, "%s: No such file or directory.", file);
|
|
|
}
|
|
|
|
|
|
FiosFreeSavegameList();
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
|
|
|
/* List all the files in the current dir via console */
|
|
|
DEF_CONSOLE_CMD(ConListFiles)
|
|
|
{
|
|
|
int i;
|
|
|
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("List all loadable savegames and directories in the current dir via console. Usage: 'ls | dir'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
BuildFileList();
|
|
|
|
|
|
for (i = 0; i < _fios_num; i++) {
|
|
|
const FiosItem *item = &_fios_list[i];
|
|
|
IConsolePrintF(_icolour_def, "%d) %s", i, item->title);
|
|
|
}
|
|
|
|
|
|
FiosFreeSavegameList();
|
|
@@ -302,50 +305,51 @@ DEF_CONSOLE_CMD(ConListFiles)
|
|
|
}
|
|
|
|
|
|
/* Change the dir via console */
|
|
|
DEF_CONSOLE_CMD(ConChangeDirectory)
|
|
|
{
|
|
|
const FiosItem *item;
|
|
|
const char *file;
|
|
|
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Change the dir via console. Usage: 'cd <directory | number>'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc != 2) return false;
|
|
|
|
|
|
file = argv[1];
|
|
|
item = GetFiosItem(file);
|
|
|
if (item != NULL) {
|
|
|
switch (item->type) {
|
|
|
case FIOS_TYPE_DIR: case FIOS_TYPE_DRIVE: case FIOS_TYPE_PARENT:
|
|
|
FiosBrowseTo(item);
|
|
|
break;
|
|
|
default: IConsolePrintF(_icolour_err, "%s: Not a directory.", file);
|
|
|
}
|
|
|
} else
|
|
|
} else {
|
|
|
IConsolePrintF(_icolour_err, "%s: No such file or directory.", file);
|
|
|
}
|
|
|
|
|
|
FiosFreeSavegameList();
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConPrintWorkingDirectory)
|
|
|
{
|
|
|
const char *path;
|
|
|
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Print out the current working directory. Usage: 'pwd'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
// XXX - Workaround for broken file handling
|
|
|
FiosGetSavegameList(&_fios_num, SLD_LOAD_GAME);
|
|
|
FiosFreeSavegameList();
|
|
|
|
|
|
FiosGetDescText(&path, NULL);
|
|
|
IConsolePrint(_icolour_def, path);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConClearBuffer)
|
|
@@ -387,50 +391,51 @@ DEF_CONSOLE_CMD(ConBan)
|
|
|
} else { // banning IP
|
|
|
ci = NetworkFindClientInfoFromIP(argv[1]);
|
|
|
if (ci == NULL) {
|
|
|
banip = argv[1];
|
|
|
index = (uint32)-1;
|
|
|
} else {
|
|
|
index = ci->client_index;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (index == NETWORK_SERVER_INDEX) {
|
|
|
IConsoleError("Silly boy, you can not ban yourself!");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (index == 0 || (ci == NULL && index != (uint32)-1)) {
|
|
|
IConsoleError("Invalid client");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (ci != NULL) {
|
|
|
banip = inet_ntoa(*(struct in_addr *)&ci->client_ip);
|
|
|
SEND_COMMAND(PACKET_SERVER_ERROR)(NetworkFindClientStateFromIndex(index), NETWORK_ERROR_KICKED);
|
|
|
IConsolePrint(_icolour_def, "Client banned");
|
|
|
} else
|
|
|
} else {
|
|
|
IConsolePrint(_icolour_def, "Client not online, banned IP");
|
|
|
}
|
|
|
|
|
|
/* Add user to ban-list */
|
|
|
for (index = 0; index < lengthof(_network_ban_list); index++) {
|
|
|
if (_network_ban_list[index] == NULL) {
|
|
|
_network_ban_list[index] = strdup(banip);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConUnBan)
|
|
|
{
|
|
|
uint i, index;
|
|
|
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Unban a player from a network game. Usage: 'unban <ip | client-id>'");
|
|
|
IConsoleHelp("For a list of banned IP's, see the command 'banlist'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc != 2) return false;
|
|
|
|
|
@@ -460,190 +465,205 @@ DEF_CONSOLE_CMD(ConBanList)
|
|
|
IConsoleHelp("List the IP's of banned clients: Usage 'banlist'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
IConsolePrint(_icolour_def, "Banlist: ");
|
|
|
|
|
|
for (i = 0; i < lengthof(_network_ban_list); i++) {
|
|
|
if (_network_ban_list[i] != NULL)
|
|
|
IConsolePrintF(_icolour_def, " %d) %s", i + 1, _network_ban_list[i]);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConPauseGame)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Pause a network game. Usage: 'pause'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (_pause == 0) {
|
|
|
DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
|
|
|
IConsolePrint(_icolour_def, "Game paused.");
|
|
|
} else
|
|
|
} else {
|
|
|
IConsolePrint(_icolour_def, "Game is already paused.");
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConUnPauseGame)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Unpause a network game. Usage: 'unpause'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (_pause != 0) {
|
|
|
DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
|
|
|
IConsolePrint(_icolour_def, "Game unpaused.");
|
|
|
} else
|
|
|
} else {
|
|
|
IConsolePrint(_icolour_def, "Game is already unpaused.");
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConRcon)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Remote control the server from another client. Usage: 'rcon <password> <command>'");
|
|
|
IConsoleHelp("Remember to enclose the command in quotes, otherwise only the first parameter is sent");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc < 3) return false;
|
|
|
|
|
|
SEND_COMMAND(PACKET_CLIENT_RCON)(argv[1], argv[2]);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConStatus)
|
|
|
{
|
|
|
static const char *stat_str[] = {"inactive", "authorized", "waiting", "loading map", "map done", "ready", "active"};
|
|
|
const char *status;
|
|
|
static const char* const stat_str[] = {
|
|
|
"inactive",
|
|
|
"authorized",
|
|
|
"waiting",
|
|
|
"loading map",
|
|
|
"map done",
|
|
|
"ready",
|
|
|
"active"
|
|
|
};
|
|
|
|
|
|
const NetworkClientState *cs;
|
|
|
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("List the status of all clients connected to the server. Usage 'status'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
FOR_ALL_CLIENTS(cs) {
|
|
|
int lag = NetworkCalculateLag(cs);
|
|
|
const NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
|
|
|
const char* status;
|
|
|
|
|
|
status = (cs->status <= STATUS_ACTIVE) ? stat_str[cs->status] : "unknown";
|
|
|
status = (cs->status <= lengthof(stat_str) ? stat_str[cs->status] : "unknown");
|
|
|
IConsolePrintF(8, "Client #%1d name: '%s' status: '%s' frame-lag: %3d company: %1d IP: %s unique-id: '%s'",
|
|
|
cs->index, ci->client_name, status, lag, ci->client_playas, GetPlayerIP(ci), ci->unique_id);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConServerInfo)
|
|
|
{
|
|
|
const NetworkGameInfo *gi;
|
|
|
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("List current and maximum client/player limits. Usage 'server_info'");
|
|
|
IConsoleHelp("You can change these values by setting the variables 'max_clients', 'max_companies' and 'max_spectators'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
gi = &_network_game_info;
|
|
|
IConsolePrintF(_icolour_def, "Current/maximum clients: %2d/%2d", gi->clients_on, gi->clients_max);
|
|
|
IConsolePrintF(_icolour_def, "Current/maximum companies: %2d/%2d", ActivePlayerCount(), gi->companies_max);
|
|
|
IConsolePrintF(_icolour_def, "Current/maximum spectators: %2d/%2d", NetworkSpectatorCount(), gi->spectators_max);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_HOOK(ConHookValidateMaxClientsCount) {
|
|
|
DEF_CONSOLE_HOOK(ConHookValidateMaxClientsCount)
|
|
|
{
|
|
|
/* XXX - hardcoded, string limiation -- TrueLight
|
|
|
* XXX - also see network.c:NetworkStartup ~1356 */
|
|
|
if (_network_game_info.clients_max > 10) {
|
|
|
_network_game_info.clients_max = 10;
|
|
|
IConsoleError("Maximum clients out of bounds, truncating to limit.");
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_HOOK(ConHookValidateMaxCompaniesCount) {
|
|
|
DEF_CONSOLE_HOOK(ConHookValidateMaxCompaniesCount)
|
|
|
{
|
|
|
if (_network_game_info.companies_max > MAX_PLAYERS) {
|
|
|
_network_game_info.companies_max = MAX_PLAYERS;
|
|
|
IConsoleError("Maximum companies out of bounds, truncating to limit.");
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_HOOK(ConHookValidateMaxSpectatorsCount) {
|
|
|
DEF_CONSOLE_HOOK(ConHookValidateMaxSpectatorsCount)
|
|
|
{
|
|
|
/* XXX @see ConHookValidateMaxClientsCount */
|
|
|
if (_network_game_info.spectators_max > 10) {
|
|
|
_network_game_info.spectators_max = 10;
|
|
|
IConsoleError("Maximum spectators out of bounds, truncating to limit.");
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConKick)
|
|
|
{
|
|
|
NetworkClientInfo *ci;
|
|
|
uint32 index;
|
|
|
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Kick a player from a network game. Usage: 'kick <ip | client-id>'");
|
|
|
IConsoleHelp("For client-id's, see the command 'clients'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc != 2) return false;
|
|
|
|
|
|
if (strchr(argv[1], '.') == NULL) {
|
|
|
index = atoi(argv[1]);
|
|
|
ci = NetworkFindClientInfoFromIndex(index);
|
|
|
} else {
|
|
|
ci = NetworkFindClientInfoFromIP(argv[1]);
|
|
|
index = (ci == NULL) ? 0 : ci->client_index;
|
|
|
}
|
|
|
|
|
|
if (index == NETWORK_SERVER_INDEX) {
|
|
|
IConsoleError("Silly boy, you can not kick yourself!");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (index == 0) {
|
|
|
IConsoleError("Invalid client");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (ci != NULL) {
|
|
|
SEND_COMMAND(PACKET_SERVER_ERROR)(NetworkFindClientStateFromIndex(index), NETWORK_ERROR_KICKED);
|
|
|
} else
|
|
|
} else {
|
|
|
IConsoleError("Client not found");
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConResetCompany)
|
|
|
{
|
|
|
Player *p;
|
|
|
NetworkClientState *cs;
|
|
|
NetworkClientInfo *ci;
|
|
|
byte index;
|
|
|
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Remove an idle company from the game. Usage: 'reset_company <company-id>'");
|
|
|
IConsoleHelp("For company-id's, see the list of companies from the dropdown menu. Player 1 is 1, etc.");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc != 2) return false;
|
|
|
|
|
|
index = atoi(argv[1]);
|
|
|
|
|
|
/* Check valid range */
|
|
|
if (index < 1 || index > MAX_PLAYERS) {
|
|
|
IConsolePrintF(_icolour_err, "Company does not exist. Company-id must be between 1 and %d.", MAX_PLAYERS);
|
|
@@ -953,49 +973,51 @@ DEF_CONSOLE_CMD(ConInfoCmd)
|
|
|
}
|
|
|
|
|
|
IConsolePrintF(_icolour_def, "command name: %s", cmd->name);
|
|
|
IConsolePrintF(_icolour_def, "command proc: 0x%X", cmd->proc);
|
|
|
|
|
|
if (cmd->hook.access) IConsoleWarning("command is access hooked");
|
|
|
if (cmd->hook.pre) IConsoleWarning("command is pre hooked");
|
|
|
if (cmd->hook.post) IConsoleWarning("command is post hooked");
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
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(_icolour_def, "Current debug-level: '%s'", GetDebugString());
|
|
|
} else SetDebugString(argv[1]);
|
|
|
} else {
|
|
|
SetDebugString(argv[1]);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConExit)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Exit the game. Usage: 'exit'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
_exit_game = true;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConPart)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Leave the currently joined/running game (only ingame). Usage: 'part'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (_game_mode != GM_NORMAL) return false;
|
|
|
|
|
@@ -1105,118 +1127,121 @@ DEF_CONSOLE_CMD(ConListAliases)
|
|
|
|
|
|
if (argv[1] != NULL) l = strlen(argv[1]);
|
|
|
|
|
|
for (alias = _iconsole_aliases; alias != NULL; alias = alias->next) {
|
|
|
if (argv[1] == NULL || strncmp(alias->name, argv[1], l) == 0)
|
|
|
IConsolePrintF(_icolour_def, "%s => %s", alias->name, alias->cmdline);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
#ifdef ENABLE_NETWORK
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConSay)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Chat to your fellow players in a multiplayer game. Usage: 'say \"<msg>\"'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc != 2) return false;
|
|
|
|
|
|
if (!_network_server) {
|
|
|
SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0 /* param does not matter */, argv[1]);
|
|
|
} else
|
|
|
} else {
|
|
|
NetworkServer_HandleChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0, argv[1], NETWORK_SERVER_INDEX);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConPlayers)
|
|
|
{
|
|
|
Player *p;
|
|
|
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("List the in-game details of all clients connected to the server. Usage 'players'");
|
|
|
return true;
|
|
|
}
|
|
|
NetworkPopulateCompanyInfo();
|
|
|
|
|
|
FOR_ALL_PLAYERS(p) {
|
|
|
char buffer[512];
|
|
|
|
|
|
if (!p->is_active) continue;
|
|
|
|
|
|
GetString(buffer, STR_00D1_DARK_BLUE + _player_colors[p->index]);
|
|
|
IConsolePrintF(8, "#:%d(%s) Company Name: '%s' Year Founded: %d Money: %d Loan: %d Value: %" OTTD_PRINTF64 "d (T:%d, R:%d, P:%d, S:%d)",
|
|
|
p->index + 1, buffer, _network_player_info[p->index].company_name, p->inaugurated_year + MAX_YEAR_BEGIN_REAL, p->player_money, p->current_loan, CalculateCompanyValue(p),
|
|
|
/* trains */ _network_player_info[p->index].num_vehicle[0],
|
|
|
/* lorry + bus */ _network_player_info[p->index].num_vehicle[1] + _network_player_info[p->index].num_vehicle[2],
|
|
|
/* planes */ _network_player_info[p->index].num_vehicle[3],
|
|
|
/* ships */ _network_player_info[p->index].num_vehicle[4]);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConSayPlayer)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Chat to a certain player in a multiplayer game. Usage: 'say_player <player-no> \"<msg>\"'");
|
|
|
IConsoleHelp("PlayerNo is the player that plays as company <playerno>, 1 through max_players");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc != 3) return false;
|
|
|
|
|
|
if (atoi(argv[1]) < 1 || atoi(argv[1]) > MAX_PLAYERS) {
|
|
|
IConsolePrintF(_icolour_def, "Unknown player. Player range is between 1 and %d.", MAX_PLAYERS);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (!_network_server) {
|
|
|
SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT_PLAYER, DESTTYPE_PLAYER, atoi(argv[1]), argv[2]);
|
|
|
} else
|
|
|
} else {
|
|
|
NetworkServer_HandleChat(NETWORK_ACTION_CHAT_PLAYER, DESTTYPE_PLAYER, atoi(argv[1]), argv[2], NETWORK_SERVER_INDEX);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConSayClient)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Chat to a certain player in a multiplayer game. Usage: 'say_client <client-no> \"<msg>\"'");
|
|
|
IConsoleHelp("For client-id's, see the command 'clients'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc != 3) return false;
|
|
|
|
|
|
if (!_network_server) {
|
|
|
SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2]);
|
|
|
} else
|
|
|
} else {
|
|
|
NetworkServer_HandleChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2], NETWORK_SERVER_INDEX);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_HOOK(ConHookServerPW)
|
|
|
{
|
|
|
if (strcmp(_network_server_password, "*") == 0) {
|
|
|
_network_server_password[0] = '\0';
|
|
|
_network_game_info.use_password = 0;
|
|
|
} else {
|
|
|
ttd_strlcpy(_network_game_info.server_password, _network_server_password, sizeof(_network_server_password));
|
|
|
_network_game_info.use_password = 1;
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_HOOK(ConHookRconPW)
|
|
|
{
|
|
|
if (strcmp(_network_rcon_password, "*") == 0)
|
|
|
_network_rcon_password[0] = '\0';
|
|
|
|
|
|
ttd_strlcpy(_network_game_info.rcon_password, _network_rcon_password, sizeof(_network_game_info.rcon_password));
|
|
|
|
|
@@ -1293,50 +1318,51 @@ DEF_CONSOLE_CMD(ConProcServerIP)
|
|
|
IConsolePrintF(_icolour_warn, "Current value for 'server_ip': %s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc != 1) return false;
|
|
|
|
|
|
_network_server_bind_ip = (strcmp(argv[0], "all") == 0) ? inet_addr("0.0.0.0") : inet_addr(argv[0]);
|
|
|
snprintf(_network_server_bind_ip_host, sizeof(_network_server_bind_ip_host), "%s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
|
|
|
IConsolePrintF(_icolour_warn, "'server_ip' changed to: %s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConPatch)
|
|
|
{
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("Change patch variables for all players. Usage: 'patch <name> [<value>]'");
|
|
|
IConsoleHelp("Omitting <value> will print out the current value of the patch-setting.");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argc == 1 || argc > 3) return false;
|
|
|
|
|
|
if (argc == 2) {
|
|
|
IConsoleGetPatchSetting(argv[1]);
|
|
|
} else
|
|
|
} else {
|
|
|
IConsoleSetPatchSetting(argv[1], argv[2]);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
#endif /* ENABLE_NETWORK */
|
|
|
|
|
|
DEF_CONSOLE_CMD(ConListDumpVariables)
|
|
|
{
|
|
|
const IConsoleVar *var;
|
|
|
size_t l = 0;
|
|
|
|
|
|
if (argc == 0) {
|
|
|
IConsoleHelp("List all variables with their value. Usage: 'dump_vars [<pre-filter>]'");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (argv[1] != NULL) l = strlen(argv[1]);
|
|
|
|
|
|
for (var = _iconsole_vars; var != NULL; var = var->next) {
|
|
|
if (argv[1] == NULL || strncmp(var->name, argv[1], l) == 0)
|
|
|
IConsoleVarPrintGetValue(var);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|