diff --git a/src/console.cpp b/src/console.cpp index c7a1ffd749..a578008e5c 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -112,6 +112,7 @@ void IConsolePrint(ConsoleColour colour_code, const char *string) str_validate(str, str + strlen(str)); if (_network_dedicated) { + NetworkAdminConsole("console", str); fprintf(stdout, "%s%s\n", GetLogPrefix(), str); fflush(stdout); IConsoleWriteToLogFile(str); diff --git a/src/debug.cpp b/src/debug.cpp index dea87850fb..965ed5d1b1 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -20,7 +20,7 @@ #include #if defined(ENABLE_NETWORK) -#include "network/core/os_abstraction.h" +#include "network/network_admin.h" SOCKET _debug_socket = INVALID_SOCKET; #endif /* ENABLE_NETWORK */ @@ -94,6 +94,7 @@ static void debug_print(const char *dbg, const char *buf) #else fprintf(stderr, "%sdbg: [%s] %s\n", GetLogPrefix(), dbg, buf); #endif + NetworkAdminConsole(dbg, buf); IConsoleDebug(dbg, buf); } else { static FILE *f = FioFOpenFile("commands-out.log", "wb", AUTOSAVE_DIR); diff --git a/src/network/core/tcp_admin.cpp b/src/network/core/tcp_admin.cpp index 9de27d1834..e3235eebeb 100644 --- a/src/network/core/tcp_admin.cpp +++ b/src/network/core/tcp_admin.cpp @@ -79,6 +79,7 @@ NetworkRecvStatus NetworkAdminSocketHandler::HandlePacket(Packet *p) ADMIN_COMMAND(ADMIN_PACKET_SERVER_COMPANY_STATS) ADMIN_COMMAND(ADMIN_PACKET_SERVER_CHAT) ADMIN_COMMAND(ADMIN_PACKET_SERVER_RCON) + ADMIN_COMMAND(ADMIN_PACKET_SERVER_CONSOLE) default: if (this->HasClientQuit()) { @@ -153,5 +154,6 @@ 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) +DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CONSOLE) #endif /* ENABLE_NETWORK */ diff --git a/src/network/core/tcp_admin.h b/src/network/core/tcp_admin.h index d4b0d746cf..6c66d8d05c 100644 --- a/src/network/core/tcp_admin.h +++ b/src/network/core/tcp_admin.h @@ -55,6 +55,7 @@ enum PacketAdminType { 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. + ADMIN_PACKET_SERVER_CONSOLE, ///< The server gives the admin the data that got printed to its console. INVALID_ADMIN_PACKET = 0xFF, ///< An invalid marker for admin packets. }; @@ -74,6 +75,7 @@ enum AdminUpdateType { ADMIN_UPDATE_COMPANY_ECONOMY, ///< Updates about the economy of companies. ADMIN_UPDATE_COMPANY_STATS, ///< Updates about the statistics of companies. ADMIN_UPDATE_CHAT, ///< The admin would like to have chat messages. + ADMIN_UPDATE_CONSOLE, ///< The admin would like to have console messages. ADMIN_UPDATE_END ///< Must ALWAYS be on the end of this list!! (period) }; @@ -331,6 +333,13 @@ protected: */ DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_RCON); + /** + * Send what would be printed on the server's console also into the admin network. + * string The origin of the text, e.g. "console" for console, or "net" for network related (debug) messages. + * string Text as found on the console of the server. + */ + DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CONSOLE); + 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 081d59e124..faf663d7a0 100644 --- a/src/network/network_admin.cpp +++ b/src/network/network_admin.cpp @@ -49,6 +49,7 @@ static const AdminUpdateFrequency _admin_update_type_frequencies[] = { ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_WEEKLY | ADMIN_FREQUENCY_MONTHLY | ADMIN_FREQUENCY_QUARTERLY | ADMIN_FREQUENCY_ANUALLY, ///< ADMIN_UPDATE_COMPANY_ECONOMY ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_WEEKLY | ADMIN_FREQUENCY_MONTHLY | ADMIN_FREQUENCY_QUARTERLY | ADMIN_FREQUENCY_ANUALLY, ///< ADMIN_UPDATE_COMPANY_STATS ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_CHAT + ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_CONSOLE }; assert_compile(lengthof(_admin_update_type_frequencies) == ADMIN_UPDATE_END); @@ -430,6 +431,23 @@ DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_RCON) return NETWORK_RECV_STATUS_OKAY; } +NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const char *origin, const char *string) +{ + /* If the length of both strings, plus the 2 '\0' terminations and 3 bytes of the packet + * are bigger than the MTU, just ignore the message. Better safe than sorry. It should + * never occur though as the longest strings are chat messages, which are still 30% + * smaller than SEND_MTU. */ + if (strlen(origin) + strlen(string) + 2 + 3 >= SEND_MTU) return NETWORK_RECV_STATUS_OKAY; + + Packet *p = new Packet(ADMIN_PACKET_SERVER_CONSOLE); + + p->Send_string(origin); + p->Send_string(string); + this->Send_Packet(p); + + return NETWORK_RECV_STATUS_OKAY; +} + /*********** * Receiving functions ************/ @@ -713,6 +731,21 @@ void NetworkServerSendAdminRcon(AdminIndex admin_index, ConsoleColour colour_cod ServerNetworkAdminSocketHandler::Get(admin_index)->SendRcon(colour_code, string); } +/** + * Send console to the admin network (if they did opt in for the respective update). + * @param origin the origin of the message. + * @param string the message as printed on the console. + */ +void NetworkAdminConsole(const char *origin, const char *string) +{ + ServerNetworkAdminSocketHandler *as; + FOR_ALL_ADMIN_SOCKETS(as) { + if (as->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) { + as->SendConsole(origin, string); + } + } +} + /** * Send a Welcome packet to all connected admins */ diff --git a/src/network/network_admin.h b/src/network/network_admin.h index a2a177b900..4dad755f08 100644 --- a/src/network/network_admin.h +++ b/src/network/network_admin.h @@ -63,6 +63,7 @@ public: NetworkRecvStatus SendChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, int64 data); NetworkRecvStatus SendRcon(uint16 colour, const char *command); + NetworkRecvStatus SendConsole(const char *origin, const char *command); static void Send(); static void AcceptConnection(SOCKET s, const NetworkAddress &address); @@ -93,6 +94,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); +void NetworkAdminConsole(const char *origin, const char *string); #endif /* ENABLE_NETWORK */ #endif /* NETWORK_ADMIN_H */