summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/console.cpp7
-rw-r--r--src/console_cmds.cpp10
-rw-r--r--src/network/core/tcp_admin.cpp4
-rw-r--r--src/network/core/tcp_admin.h15
-rw-r--r--src/network/network_admin.cpp42
-rw-r--r--src/network/network_admin.h5
6 files changed, 80 insertions, 3 deletions
diff --git a/src/console.cpp b/src/console.cpp
index ab131b135..c7a1ffd74 100644
--- a/src/console.cpp
+++ b/src/console.cpp
@@ -13,6 +13,7 @@
#include "console_internal.h"
#include "network/network.h"
#include "network/network_func.h"
+#include "network/network_admin.h"
#include "debug.h"
#include "console_func.h"
#include "settings_type.h"
@@ -38,6 +39,7 @@ void IConsoleInit()
_iconsole_output_file = NULL;
#ifdef ENABLE_NETWORK /* Initialize network only variables */
_redirect_console_to_client = INVALID_CLIENT_ID;
+ _redirect_console_to_admin = INVALID_ADMIN_ID;
#endif
IConsoleGUIInit();
@@ -96,6 +98,11 @@ void IConsolePrint(ConsoleColour colour_code, const char *string)
NetworkServerSendRcon(_redirect_console_to_client, colour_code, string);
return;
}
+
+ if (_redirect_console_to_admin != INVALID_ADMIN_ID) {
+ NetworkServerSendAdminRcon(_redirect_console_to_admin, colour_code, string);
+ return;
+ }
#endif
/* Create a copy of the string, strip if of colours and invalid
diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp
index c047340dd..8f976b48f 100644
--- a/src/console_cmds.cpp
+++ b/src/console_cmds.cpp
@@ -18,6 +18,7 @@
#include "network/network.h"
#include "network/network_func.h"
#include "network/network_base.h"
+#include "network/network_admin.h"
#include "command_func.h"
#include "settings_func.h"
#include "fios.h"
@@ -1416,7 +1417,8 @@ DEF_CONSOLE_CMD(ConSay)
if (!_network_server) {
NetworkClientSendChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0 /* param does not matter */, argv[1]);
} else {
- NetworkServerSendChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0, argv[1], CLIENT_ID_SERVER);
+ bool from_admin = (_redirect_console_to_admin < INVALID_ADMIN_ID);
+ NetworkServerSendChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0, argv[1], CLIENT_ID_SERVER, from_admin);
}
return true;
@@ -1473,7 +1475,8 @@ DEF_CONSOLE_CMD(ConSayCompany)
if (!_network_server) {
NetworkClientSendChat(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, company_id, argv[2]);
} else {
- NetworkServerSendChat(NETWORK_ACTION_CHAT_COMPANY, DESTTYPE_TEAM, company_id, argv[2], CLIENT_ID_SERVER);
+ 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;
@@ -1492,7 +1495,8 @@ DEF_CONSOLE_CMD(ConSayClient)
if (!_network_server) {
NetworkClientSendChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2]);
} else {
- NetworkServerSendChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, atoi(argv[1]), argv[2], CLIENT_ID_SERVER);
+ 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;
diff --git a/src/network/core/tcp_admin.cpp b/src/network/core/tcp_admin.cpp
index b2da7475f..9de27d183 100644
--- a/src/network/core/tcp_admin.cpp
+++ b/src/network/core/tcp_admin.cpp
@@ -55,6 +55,7 @@ NetworkRecvStatus NetworkAdminSocketHandler::HandlePacket(Packet *p)
ADMIN_COMMAND(ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY)
ADMIN_COMMAND(ADMIN_PACKET_ADMIN_POLL)
ADMIN_COMMAND(ADMIN_PACKET_ADMIN_CHAT)
+ ADMIN_COMMAND(ADMIN_PACKET_ADMIN_RCON)
ADMIN_COMMAND(ADMIN_PACKET_SERVER_FULL)
ADMIN_COMMAND(ADMIN_PACKET_SERVER_BANNED)
@@ -77,6 +78,7 @@ NetworkRecvStatus NetworkAdminSocketHandler::HandlePacket(Packet *p)
ADMIN_COMMAND(ADMIN_PACKET_SERVER_COMPANY_ECONOMY)
ADMIN_COMMAND(ADMIN_PACKET_SERVER_COMPANY_STATS)
ADMIN_COMMAND(ADMIN_PACKET_SERVER_CHAT)
+ ADMIN_COMMAND(ADMIN_PACKET_SERVER_RCON)
default:
if (this->HasClientQuit()) {
@@ -127,6 +129,7 @@ DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_QUIT)
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY)
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_POLL)
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_CHAT)
+DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_RCON)
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_FULL)
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_BANNED)
@@ -149,5 +152,6 @@ DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_REMOVE)
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_ECONOMY)
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_STATS)
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CHAT)
+DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_RCON)
#endif /* ENABLE_NETWORK */
diff --git a/src/network/core/tcp_admin.h b/src/network/core/tcp_admin.h
index e73d0202e..d4b0d746c 100644
--- a/src/network/core/tcp_admin.h
+++ b/src/network/core/tcp_admin.h
@@ -31,6 +31,7 @@ enum PacketAdminType {
ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY, ///< The admin tells the server the update frequency of a particular piece of information.
ADMIN_PACKET_ADMIN_POLL, ///< The admin explicitly polls for a piece of information.
ADMIN_PACKET_ADMIN_CHAT, ///< The admin sends a chat message to be distributed.
+ ADMIN_PACKET_ADMIN_RCON, ///< The admin sends a remote console command.
ADMIN_PACKET_SERVER_FULL = 100, ///< The server tells the admin it cannot accept the admin.
ADMIN_PACKET_SERVER_BANNED, ///< The server tells the admin it is banned.
@@ -53,6 +54,7 @@ enum PacketAdminType {
ADMIN_PACKET_SERVER_COMPANY_ECONOMY, ///< The server gives the admin some economy related company information.
ADMIN_PACKET_SERVER_COMPANY_STATS, ///< The server gives the admin some statistics about a company.
ADMIN_PACKET_SERVER_CHAT, ///< The server received a chat message and relays it.
+ ADMIN_PACKET_SERVER_RCON, ///< The server's reply to a remove console command.
INVALID_ADMIN_PACKET = 0xFF, ///< An invalid marker for admin packets.
};
@@ -143,6 +145,12 @@ protected:
DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_CHAT);
/**
+ * Execute a command on the servers console:
+ * string Command to be executed.
+ */
+ DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_RCON);
+
+ /**
* The server is full (connection gets closed).
*/
DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_FULL);
@@ -316,6 +324,13 @@ protected:
*/
DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CHAT);
+ /**
+ * Result of an rcon command:
+ * uint16 Colour as it would be used on the server or a client.
+ * string Output of the executed command.
+ */
+ DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_RCON);
+
NetworkRecvStatus HandlePacket(Packet *p);
public:
NetworkRecvStatus CloseConnection(bool error = true);
diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp
index 565976c70..081d59e12 100644
--- a/src/network/network_admin.cpp
+++ b/src/network/network_admin.cpp
@@ -28,6 +28,9 @@
/* This file handles all the admin network commands. */
+/** Redirection of the (remote) console to the admin. */
+AdminIndex _redirect_console_to_admin = INVALID_ADMIN_ID;
+
/** The amount of admins connected. */
byte _network_admins_connected = 0;
@@ -67,6 +70,7 @@ ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler()
{
_network_admins_connected--;
DEBUG(net, 1, "[admin] '%s' (%s) has disconnected", this->admin_name, this->admin_version);
+ if (_redirect_console_to_admin == this->index) _redirect_console_to_admin = INVALID_ADMIN_ID;
}
/**
@@ -399,6 +403,33 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action
return NETWORK_RECV_STATUS_OKAY;
}
+NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRcon(uint16 colour, const char *result)
+{
+ Packet *p = new Packet(ADMIN_PACKET_SERVER_RCON);
+
+ p->Send_uint16(colour);
+ p->Send_string(result);
+ this->Send_Packet(p);
+
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
+DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_RCON)
+{
+ if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
+
+ char command[NETWORK_RCONCOMMAND_LENGTH];
+
+ p->Recv_string(command, sizeof(command));
+
+ DEBUG(net, 2, "[admin] Rcon command from '%s' (%s): '%s'", this->admin_name, this->admin_version, command);
+
+ _redirect_console_to_admin = this->index;
+ IConsoleCmdExec(command);
+ _redirect_console_to_admin = INVALID_ADMIN_ID;
+ return NETWORK_RECV_STATUS_OKAY;
+}
+
/***********
* Receiving functions
************/
@@ -672,6 +703,17 @@ void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_i
}
/**
+ * Pass the rcon reply to the admin.
+ * @param admin_index The admin to give the reply.
+ * @param colour_code The colour of the string.
+ * @param string The string to show.
+ */
+void NetworkServerSendAdminRcon(AdminIndex admin_index, ConsoleColour colour_code, const char *string)
+{
+ ServerNetworkAdminSocketHandler::Get(admin_index)->SendRcon(colour_code, string);
+}
+
+/**
* Send a Welcome packet to all connected admins
*/
void ServerNetworkAdminSocketHandler::WelcomeAll()
diff --git a/src/network/network_admin.h b/src/network/network_admin.h
index 7174a191a..a2a177b90 100644
--- a/src/network/network_admin.h
+++ b/src/network/network_admin.h
@@ -18,6 +18,8 @@
#include "core/tcp_listen.h"
#include "core/tcp_admin.h"
+extern AdminIndex _redirect_console_to_admin;
+
class ServerNetworkAdminSocketHandler;
typedef Pool<ServerNetworkAdminSocketHandler, AdminIndex, 2, MAX_ADMINS> NetworkAdminSocketPool;
extern NetworkAdminSocketPool _networkadminsocket_pool;
@@ -30,6 +32,7 @@ protected:
DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY);
DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_POLL);
DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_CHAT);
+ DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_RCON);
NetworkRecvStatus SendProtocol();
public:
@@ -59,6 +62,7 @@ public:
NetworkRecvStatus SendCompanyStats();
NetworkRecvStatus SendChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, int64 data);
+ NetworkRecvStatus SendRcon(uint16 colour, const char *command);
static void Send();
static void AcceptConnection(SOCKET s, const NetworkAddress &address);
@@ -88,6 +92,7 @@ void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bc
void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, int64 data = 0, bool from_admin = false);
void NetworkAdminUpdate(AdminUpdateFrequency freq);
+void NetworkServerSendAdminRcon(AdminIndex admin_index, ConsoleColour colour_code, const char *string);
#endif /* ENABLE_NETWORK */
#endif /* NETWORK_ADMIN_H */