mirror of https://github.com/OpenTTD/OpenTTD
(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!release/0.4.5
parent
e6d31cb89c
commit
24c9e6ff66
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
20
network.h
20
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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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},
|
||||
|
|
Loading…
Reference in New Issue