summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortruelight <truelight@openttd.org>2005-01-15 20:09:16 +0000
committertruelight <truelight@openttd.org>2005-01-15 20:09:16 +0000
commit24c9e6ff66c6386a182b0fe5eef5f371793b468e (patch)
treebe21df9ed89b0080e4d32a5e54c3f2dffd9f3437
parente6d31cb89c43feebcd114d197166588e7ede72d3 (diff)
downloadopenttd-24c9e6ff66c6386a182b0fe5eef5f371793b468e.tar.xz
(svn r1527) -Add: RCon (Remote Connection). A server can set:
'set rcon_pw <password>' Which enables rcon. A client can now do: 'rcon <password> "<command>"' The command will be executed on the server. (guru3) -Fix: 'kick 1' did crash dedicated servers -Fix: server password is now correctly saved !!Warning!!: do not give your rcon password to people you do not thrust!
-rw-r--r--console.c8
-rw-r--r--console_cmds.c47
-rw-r--r--network.c2
-rw-r--r--network.h20
-rw-r--r--network_client.c23
-rw-r--r--network_client.h1
-rw-r--r--network_data.h2
-rw-r--r--network_server.c35
-rw-r--r--network_server.h1
-rw-r--r--settings.c3
10 files changed, 131 insertions, 11 deletions
diff --git a/console.c b/console.c
index b66cbdf9d..223a6f641 100644
--- a/console.c
+++ b/console.c
@@ -11,6 +11,8 @@
#include <string.h>
#include "console.h"
#include "network.h"
+#include "network_data.h"
+#include "network_server.h"
#ifdef WIN32
#include <windows.h>
@@ -372,6 +374,12 @@ void IConsolePrint(uint16 color_code, const char* string)
char* i;
int j;
+ if (_redirect_console_to_client != 0) {
+ /* Redirect the string to the client */
+ SEND_COMMAND(PACKET_SERVER_RCON)(NetworkFindClientStateFromIndex(_redirect_console_to_client), color_code, string);
+ return;
+ }
+
if (_network_dedicated) {
printf("%s\n", string);
return;
diff --git a/console_cmds.c b/console_cmds.c
index cf58e0b1b..342fae159 100644
--- a/console_cmds.c
+++ b/console_cmds.c
@@ -379,6 +379,18 @@ DEF_CONSOLE_CMD(ConBanList)
return NULL;
}
+DEF_CONSOLE_CMD(ConRcon)
+{
+ if (argc < 3) {
+ IConsolePrint(_iconsole_color_default, "Usage: rcon <password> <command>");
+ return NULL;
+ }
+
+ SEND_COMMAND(PACKET_CLIENT_RCON)(argv[1], argv[2]);
+
+ return NULL;
+}
+
DEF_CONSOLE_CMD(ConStatus)
{
const char *status;
@@ -425,7 +437,7 @@ DEF_CONSOLE_CMD(ConKick)
if (argc == 2) {
uint32 index = atoi(argv[1]);
- if (index == NETWORK_SERVER_INDEX && !_network_dedicated) {
+ if (index == NETWORK_SERVER_INDEX) {
IConsolePrint(_iconsole_color_default, "Silly boy, you can not kick yourself!");
return NULL;
}
@@ -900,13 +912,14 @@ DEF_CONSOLE_CMD(ConSet) {
if (argc == 3) {
// Change server password
if (strncmp(argv[2], "*", NETWORK_PASSWORD_LENGTH) == 0) {
- _network_game_info.server_password[0] = '\0';
+ _network_server_password[0] = '\0';
_network_game_info.use_password = 0;
} else {
- ttd_strlcpy(_network_game_info.server_password, argv[2], sizeof(_network_game_info.server_password));
+ ttd_strlcpy(_network_server_password, argv[2], sizeof(_network_server_password));
_network_game_info.use_password = 1;
}
- IConsolePrintF(_iconsole_color_warning, "Game-password changed to '%s'", _network_game_info.server_password);
+ IConsolePrintF(_iconsole_color_warning, "Game-password changed to '%s'", _network_server_password);
+ ttd_strlcpy(_network_game_info.server_password, _network_server_password, sizeof(_network_game_info.server_password));
} else {
IConsolePrintF(_iconsole_color_default, "Current game-password is set to '%s'", _network_game_info.server_password);
IConsolePrint(_iconsole_color_warning, "Usage: set server_pw \"<password>\". Use * as <password> to set no password.");
@@ -914,6 +927,28 @@ DEF_CONSOLE_CMD(ConSet) {
return NULL;
}
+ // setting the rcon password
+ if ((strcmp(argv[1], "rcon_pw") == 0) || (strcmp(argv[1], "rcon_password") == 0)) {
+ if (!_network_server) {
+ IConsolePrintF(_iconsole_color_error, "You are not the server");
+ return NULL;
+ }
+ if (argc == 3) {
+ // Change server password
+ if (strncmp(argv[2], "*", NETWORK_PASSWORD_LENGTH) == 0) {
+ _network_rcon_password[0] = '\0';
+ } else {
+ ttd_strlcpy(_network_rcon_password, argv[2], sizeof(_network_rcon_password));
+ }
+ IConsolePrintF(_iconsole_color_warning, "Rcon-password changed to '%s'", _network_rcon_password);
+ ttd_strlcpy(_network_game_info.rcon_password, _network_rcon_password, sizeof(_network_game_info.rcon_password));
+ } else {
+ IConsolePrintF(_iconsole_color_default, "Current rcon-password is set to '%s'", _network_game_info.rcon_password);
+ IConsolePrint(_iconsole_color_warning, "Usage: set rcon_pw \"<password>\". Use * as <password> to disable rcon.");
+ }
+ return NULL;
+ }
+
// setting the company password
if ((strcmp(argv[1],"company_pw") == 0) || (strcmp(argv[1],"company_password") == 0)) {
if (!_networking) {
@@ -1123,6 +1158,7 @@ DEF_CONSOLE_CMD(ConSet) {
IConsolePrint(_iconsole_color_error, " - autoclean_unprotected <months>");
IConsolePrint(_iconsole_color_error, " - company_pw \"<password>\"");
IConsolePrint(_iconsole_color_error, " - name \"<playername>\"");
+ IConsolePrint(_iconsole_color_error, " - rcon_pw \"<password>\"");
IConsolePrint(_iconsole_color_error, " - server_name \"<name>\"");
IConsolePrint(_iconsole_color_error, " - server_advertise on/off");
IConsolePrint(_iconsole_color_error, " - server_bind_ip <ip>");
@@ -1229,6 +1265,9 @@ void IConsoleStdLibRegister(void)
IConsoleCmdHook("status", ICONSOLE_HOOK_ACCESS, ConCmdHookNoNetClient);
IConsoleCmdHook("resetengines", ICONSOLE_HOOK_ACCESS, ConCmdHookNoNetwork);
+ IConsoleCmdRegister("rcon", ConRcon);
+ IConsoleCmdHook("rcon", ICONSOLE_HOOK_ACCESS, ConCmdHookNeedNetwork);
+
IConsoleCmdRegister("ban", ConBan);
IConsoleCmdHook("ban", ICONSOLE_HOOK_ACCESS, ConCmdHookNoNetClient);
IConsoleCmdRegister("unban", ConUnBan);
diff --git a/network.c b/network.c
index ebbc8d2f9..c5157842d 100644
--- a/network.c
+++ b/network.c
@@ -927,6 +927,8 @@ static void NetworkInitGameInfo(void)
NetworkClientInfo *ci;
ttd_strlcpy(_network_game_info.server_name, _network_server_name, sizeof(_network_game_info.server_name));
+ ttd_strlcpy(_network_game_info.server_password, _network_server_password, sizeof(_network_server_password));
+ ttd_strlcpy(_network_game_info.rcon_password, _network_rcon_password, sizeof(_network_rcon_password));
if (_network_game_info.server_name[0] == '\0')
snprintf(_network_game_info.server_name, sizeof(_network_game_info.server_name), "Unnamed Server");
diff --git a/network.h b/network.h
index c03aedcca..808437730 100644
--- a/network.h
+++ b/network.h
@@ -42,12 +42,15 @@
#define NETWORK_VEHICLE_TYPES 5
#define NETWORK_STATION_TYPES 5
-#define NETWORK_NAME_LENGTH 80
-#define NETWORK_HOSTNAME_LENGTH 80
-#define NETWORK_REVISION_LENGTH 10
-#define NETWORK_PASSWORD_LENGTH 20
-#define NETWORK_PLAYERS_LENGTH 200
-#define NETWORK_CLIENT_NAME_LENGTH 25
+enum {
+ NETWORK_NAME_LENGTH = 80,
+ NETWORK_HOSTNAME_LENGTH = 80,
+ NETWORK_REVISION_LENGTH = 10,
+ NETWORK_PASSWORD_LENGTH = 20,
+ NETWORK_PLAYERS_LENGTH = 200,
+ NETWORK_CLIENT_NAME_LENGTH = 25,
+ NETWORK_RCONCOMMAND_LENGTH = 500,
+};
// This is the struct used by both client and server
// some fields will be empty on the client (like game_password) by default
@@ -71,6 +74,7 @@ typedef struct NetworkGameInfo {
uint16 map_height; // Map height
byte map_set; // Graphical set
bool dedicated; // Is this a dedicated server?
+ char rcon_password[NETWORK_PASSWORD_LENGTH]; // RCon password for the server. "" if rcon is disabled
} NetworkGameInfo;
typedef struct NetworkPlayerInfo {
@@ -155,6 +159,10 @@ VARDEF uint32 _network_server_bind_ip;
VARDEF char _network_server_bind_ip_host[NETWORK_HOSTNAME_LENGTH];
VARDEF bool _is_network_server; // Does this client wants to be a network-server?
VARDEF char _network_server_name[NETWORK_NAME_LENGTH];
+VARDEF char _network_server_password[NETWORK_PASSWORD_LENGTH];
+VARDEF char _network_rcon_password[NETWORK_PASSWORD_LENGTH];
+
+VARDEF uint16 _redirect_console_to_client;
VARDEF uint16 _network_sync_freq;
VARDEF uint8 _network_frame_freq;
diff --git a/network_client.c b/network_client.c
index cf64e1485..29821a5a5 100644
--- a/network_client.c
+++ b/network_client.c
@@ -10,6 +10,7 @@
#include "gfx.h"
#include "window.h"
#include "settings.h"
+#include "console.h"
// This file handles all the client-commands
@@ -246,6 +247,14 @@ DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_QUIT)(const char *leavemsg)
NetworkSend_Packet(p, MY_CLIENT);
}
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_RCON)(const char *pass, const char *command)
+{
+ Packet *p = NetworkSend_Init(PACKET_CLIENT_RCON);
+ NetworkSend_string(p, pass);
+ NetworkSend_string(p, command);
+ NetworkSend_Packet(p, MY_CLIENT);
+}
+
// **********
// Receiving functions
@@ -741,6 +750,18 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEWGAME)
return NETWORK_RECV_STATUS_SERVER_ERROR;
}
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_RCON)
+{
+ char rcon_out[NETWORK_RCONCOMMAND_LENGTH];
+ uint16 color_code;
+
+ color_code = NetworkRecv_uint16(MY_CLIENT, p);
+ NetworkRecv_string(MY_CLIENT, p, rcon_out, sizeof(rcon_out));
+
+ IConsolePrint(color_code, rcon_out);
+
+ return NETWORK_RECV_STATUS_OKAY;
+}
@@ -782,6 +803,8 @@ static NetworkClientPacket* const _network_client_packet[] = {
RECEIVE_COMMAND(PACKET_SERVER_ERROR_QUIT),
RECEIVE_COMMAND(PACKET_SERVER_SHUTDOWN),
RECEIVE_COMMAND(PACKET_SERVER_NEWGAME),
+ RECEIVE_COMMAND(PACKET_SERVER_RCON),
+ NULL, /*PACKET_CLIENT_RCON,*/
};
// If this fails, check the array above with network_data.h
diff --git a/network_client.h b/network_client.h
index dd839a1f5..7e665e351 100644
--- a/network_client.h
+++ b/network_client.h
@@ -13,6 +13,7 @@ DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_PASSWORD)(NetworkPasswordType type,
DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_PASSWORD)(const char *password);
DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_NAME)(const char *name);
DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_ACK);
+DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_RCON)(const char *pass, const char *command);
NetworkRecvStatus NetworkClient_ReadPackets(NetworkClientState *cs);
void NetworkClient_Connected(void);
diff --git a/network_data.h b/network_data.h
index b01115041..d8a9956d5 100644
--- a/network_data.h
+++ b/network_data.h
@@ -160,6 +160,8 @@ typedef enum {
PACKET_SERVER_ERROR_QUIT,
PACKET_SERVER_SHUTDOWN,
PACKET_SERVER_NEWGAME,
+ PACKET_SERVER_RCON,
+ PACKET_CLIENT_RCON,
PACKET_END // Should ALWAYS be on the end of this list!! (period)
} PacketType;
diff --git a/network_server.c b/network_server.c
index c746de12b..0e37fc8ff 100644
--- a/network_server.c
+++ b/network_server.c
@@ -566,6 +566,15 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_NEWGAME)
NetworkSend_Packet(p, cs);
}
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkClientState *cs, uint16 color, const char *command)
+{
+ Packet *p = NetworkSend_Init(PACKET_SERVER_RCON);
+
+ NetworkSend_uint16(p, color);
+ NetworkSend_string(p, command);
+ NetworkSend_Packet(p, cs);
+}
+
// **********
// Receiving functions
// DEF_SERVER_RECEIVE_COMMAND has parameter: NetworkClientState *cs, Packet *p
@@ -1082,6 +1091,30 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_SET_NAME)
}
}
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_RCON)
+{
+ char pass[NETWORK_PASSWORD_LENGTH];
+ char command[NETWORK_RCONCOMMAND_LENGTH];
+
+ if (_network_game_info.rcon_password[0] == '\0')
+ return;
+
+ NetworkRecv_string(cs, p, pass, sizeof(pass));
+ NetworkRecv_string(cs, p, command, sizeof(command));
+
+ if (strncmp(pass, _network_game_info.rcon_password, sizeof(pass)) != 0) {
+ DEBUG(net, 0)("[RCon] Wrong password from client-id %d", cs->index);
+ return;
+ }
+
+ DEBUG(net, 0)("[RCon] Client-id %d executed: %s", cs->index, command);
+
+ _redirect_console_to_client = cs->index;
+ IConsoleCmdExec(command);
+ _redirect_console_to_client = 0;
+ return;
+}
+
// The layout for the receive-functions by the server
typedef void NetworkServerPacket(NetworkClientState *cs, Packet *p);
@@ -1121,6 +1154,8 @@ static NetworkServerPacket* const _network_server_packet[] = {
NULL, /*PACKET_SERVER_ERROR_QUIT,*/
NULL, /*PACKET_SERVER_SHUTDOWN,*/
NULL, /*PACKET_SERVER_NEWGAME,*/
+ NULL, /*PACKET_SERVER_RCON,*/
+ RECEIVE_COMMAND(PACKET_CLIENT_RCON),
};
// If this fails, check the array above with network_data.h
diff --git a/network_server.h b/network_server.h
index 976f85784..e79948340 100644
--- a/network_server.h
+++ b/network_server.h
@@ -8,6 +8,7 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR_QUIT)(NetworkClientState *cs,
DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientState *cs, NetworkErrorCode error);
DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SHUTDOWN);
DEF_SERVER_SEND_COMMAND(PACKET_SERVER_NEWGAME);
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkClientState *cs, uint16 color, const char *command);
bool NetworkFindName(char new_name[NETWORK_NAME_LENGTH]);
void NetworkServer_HandleChat(NetworkAction action, DestType desttype, int dest, const char *msg, uint16 from_index);
diff --git a/settings.c b/settings.c
index 3ebce5e17..f880d15ff 100644
--- a/settings.c
+++ b/settings.c
@@ -759,7 +759,8 @@ static const SettingDesc network_settings[] = {
{"server_advertise",SDT_BOOL, (void*)false, &_network_advertise, NULL},
{"lan_internet", SDT_UINT8, (void*)0, &_network_lan_internet, NULL},
{"player_name", SDT_STRINGBUF | (lengthof(_network_player_name) << 16), NULL, &_network_player_name, NULL},
- {"server_password", SDT_STRINGBUF | (lengthof(_network_game_info.server_password) << 16), NULL, &_network_game_info.server_password, NULL},
+ {"server_password", SDT_STRINGBUF | (lengthof(_network_server_password) << 16), NULL, &_network_server_password, NULL},
+ {"rcon_password", SDT_STRINGBUF | (lengthof(_network_rcon_password) << 16), NULL, &_network_rcon_password, NULL},
{"server_name", SDT_STRINGBUF | (lengthof(_network_server_name) << 16), NULL, &_network_server_name, NULL},
{"connect_to_ip", SDT_STRINGBUF | (lengthof(_network_default_ip) << 16), NULL, &_network_default_ip, NULL},
{"network_id", SDT_STRINGBUF | (lengthof(_network_unique_id) << 16), NULL, &_network_unique_id, NULL},