Fix #12973: Don't exclude high score after using sandbox
[openttd-github.git] / src / network / network_admin.cpp
blob8ac4a6e72bf6c6932a723eb6c95a1794fe40a772
1 /*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
8 /** @file network_admin.cpp Server part of the admin network protocol. */
10 #include "../stdafx.h"
11 #include "../strings_func.h"
12 #include "../timer/timer_game_calendar.h"
13 #include "../timer/timer_game_calendar.h"
14 #include "core/network_game_info.h"
15 #include "network_admin.h"
16 #include "network_base.h"
17 #include "network_server.h"
18 #include "../command_func.h"
19 #include "../company_base.h"
20 #include "../console_func.h"
21 #include "../core/pool_func.hpp"
22 #include "../map_func.h"
23 #include "../rev.h"
24 #include "../game/game.hpp"
26 #include "../safeguards.h"
29 /* This file handles all the admin network commands. */
31 /** Redirection of the (remote) console to the admin. */
32 AdminIndex _redirect_console_to_admin = INVALID_ADMIN_ID;
34 /** The amount of admins connected. */
35 uint8_t _network_admins_connected = 0;
37 /** The pool with sockets/clients. */
38 NetworkAdminSocketPool _networkadminsocket_pool("NetworkAdminSocket");
39 INSTANTIATE_POOL_METHODS(NetworkAdminSocket)
41 static NetworkAuthenticationDefaultPasswordProvider _admin_password_provider(_settings_client.network.admin_password); ///< Provides the password validation for the game's password.
42 static NetworkAuthenticationDefaultAuthorizedKeyHandler _admin_authorized_key_handler(_settings_client.network.admin_authorized_keys); ///< Provides the authorized key handling for the game authentication.
44 /** The timeout for authorisation of the client. */
45 static const std::chrono::seconds ADMIN_AUTHORISATION_TIMEOUT(10);
48 /** Frequencies, which may be registered for a certain update type. */
49 static const AdminUpdateFrequency _admin_update_type_frequencies[] = {
50 ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_DAILY | ADMIN_FREQUENCY_WEEKLY | ADMIN_FREQUENCY_MONTHLY | ADMIN_FREQUENCY_QUARTERLY | ADMIN_FREQUENCY_ANUALLY, ///< ADMIN_UPDATE_DATE
51 ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_CLIENT_INFO
52 ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_COMPANY_INFO
53 ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_WEEKLY | ADMIN_FREQUENCY_MONTHLY | ADMIN_FREQUENCY_QUARTERLY | ADMIN_FREQUENCY_ANUALLY, ///< ADMIN_UPDATE_COMPANY_ECONOMY
54 ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_WEEKLY | ADMIN_FREQUENCY_MONTHLY | ADMIN_FREQUENCY_QUARTERLY | ADMIN_FREQUENCY_ANUALLY, ///< ADMIN_UPDATE_COMPANY_STATS
55 ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_CHAT
56 ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_CONSOLE
57 ADMIN_FREQUENCY_POLL, ///< ADMIN_UPDATE_CMD_NAMES
58 ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_CMD_LOGGING
59 ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_GAMESCRIPT
61 /** Sanity check. */
62 static_assert(lengthof(_admin_update_type_frequencies) == ADMIN_UPDATE_END);
64 /**
65 * Create a new socket for the server side of the admin network.
66 * @param s The socket to connect with.
68 ServerNetworkAdminSocketHandler::ServerNetworkAdminSocketHandler(SOCKET s) : NetworkAdminSocketHandler(s)
70 _network_admins_connected++;
71 this->status = ADMIN_STATUS_INACTIVE;
72 this->connect_time = std::chrono::steady_clock::now();
75 /**
76 * Clear everything related to this admin.
78 ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler()
80 _network_admins_connected--;
81 Debug(net, 3, "[admin] '{}' ({}) has disconnected", this->admin_name, this->admin_version);
82 if (_redirect_console_to_admin == this->index) _redirect_console_to_admin = INVALID_ADMIN_ID;
84 if (this->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) {
85 this->update_frequency[ADMIN_UPDATE_CONSOLE] = (AdminUpdateFrequency)0;
86 DebugReconsiderSendRemoteMessages();
90 /**
91 * Whether a connection is allowed or not at this moment.
92 * @return Whether the connection is allowed.
94 /* static */ bool ServerNetworkAdminSocketHandler::AllowConnection()
96 bool accept = _settings_client.network.AdminAuthenticationConfigured() && _network_admins_connected < MAX_ADMINS;
97 /* We can't go over the MAX_ADMINS limit here. However, if we accept
98 * the connection, there has to be space in the pool. */
99 static_assert(NetworkAdminSocketPool::MAX_SIZE == MAX_ADMINS);
100 assert(!accept || ServerNetworkAdminSocketHandler::CanAllocateItem());
101 return accept;
104 /** Send the packets for the server sockets. */
105 /* static */ void ServerNetworkAdminSocketHandler::Send()
107 for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::Iterate()) {
108 if (as->status <= ADMIN_STATUS_AUTHENTICATE && std::chrono::steady_clock::now() > as->connect_time + ADMIN_AUTHORISATION_TIMEOUT) {
109 Debug(net, 2, "[admin] Admin did not send its authorisation within {} seconds", std::chrono::duration_cast<std::chrono::seconds>(ADMIN_AUTHORISATION_TIMEOUT).count());
110 as->CloseConnection(true);
111 continue;
113 if (as->writable) {
114 as->SendPackets();
120 * Handle the acception of a connection.
121 * @param s The socket of the new connection.
122 * @param address The address of the peer.
124 /* static */ void ServerNetworkAdminSocketHandler::AcceptConnection(SOCKET s, const NetworkAddress &address)
126 ServerNetworkAdminSocketHandler *as = new ServerNetworkAdminSocketHandler(s);
127 as->address = address; // Save the IP of the client
130 /***********
131 * Sending functions for admin network
132 ************/
135 * Send an error to the admin.
136 * @param error The error to send.
138 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendError(NetworkErrorCode error)
140 /* Whatever the error might be, authentication (keys) must be released as soon as possible. */
141 this->authentication_handler = nullptr;
143 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_ERROR);
145 p->Send_uint8(error);
146 this->SendPacket(std::move(p));
148 std::string error_message = GetString(GetNetworkErrorMsg(error));
150 Debug(net, 1, "[admin] The admin '{}' ({}) made an error and has been disconnected: '{}'", this->admin_name, this->admin_version, error_message);
152 return this->CloseConnection(true);
155 /** Send the protocol version to the admin. */
156 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendProtocol()
158 this->status = ADMIN_STATUS_ACTIVE;
160 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_PROTOCOL);
162 /* announce the protocol version */
163 p->Send_uint8(NETWORK_GAME_ADMIN_VERSION);
165 for (int i = 0; i < ADMIN_UPDATE_END; i++) {
166 p->Send_bool (true);
167 p->Send_uint16(i);
168 p->Send_uint16(_admin_update_type_frequencies[i]);
171 p->Send_bool(false);
172 this->SendPacket(std::move(p));
174 return this->SendWelcome();
177 /** Send a welcome message to the admin. */
178 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendWelcome()
180 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_WELCOME);
182 p->Send_string(_settings_client.network.server_name);
183 p->Send_string(GetNetworkRevisionString());
184 p->Send_bool (_network_dedicated);
186 p->Send_string(""); // Used to be map-name.
187 p->Send_uint32(_settings_game.game_creation.generation_seed);
188 p->Send_uint8 (_settings_game.game_creation.landscape);
189 p->Send_uint32(TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1).base());
190 p->Send_uint16(Map::SizeX());
191 p->Send_uint16(Map::SizeY());
193 this->SendPacket(std::move(p));
195 return NETWORK_RECV_STATUS_OKAY;
198 /** Tell the admin we started a new game. */
199 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendNewGame()
201 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_NEWGAME);
202 this->SendPacket(std::move(p));
203 return NETWORK_RECV_STATUS_OKAY;
206 /** Tell the admin we're shutting down. */
207 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendShutdown()
209 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_SHUTDOWN);
210 this->SendPacket(std::move(p));
211 return NETWORK_RECV_STATUS_OKAY;
214 /** Tell the admin the date. */
215 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendDate()
217 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_DATE);
219 p->Send_uint32(TimerGameCalendar::date.base());
220 this->SendPacket(std::move(p));
222 return NETWORK_RECV_STATUS_OKAY;
226 * Tell the admin that a client joined.
227 * @param client_id The client that joined.
229 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientJoin(ClientID client_id)
231 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CLIENT_JOIN);
233 p->Send_uint32(client_id);
234 this->SendPacket(std::move(p));
236 return NETWORK_RECV_STATUS_OKAY;
240 * Send an initial set of data from some client's information.
241 * @param cs The socket of the client.
242 * @param ci The information about the client.
244 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientInfo(const NetworkClientSocket *cs, const NetworkClientInfo *ci)
246 /* Only send data when we're a proper client, not just someone trying to query the server. */
247 if (ci == nullptr) return NETWORK_RECV_STATUS_OKAY;
249 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CLIENT_INFO);
251 p->Send_uint32(ci->client_id);
252 p->Send_string(cs == nullptr ? "" : const_cast<NetworkAddress &>(cs->client_address).GetHostname());
253 p->Send_string(ci->client_name);
254 p->Send_uint8 (0); // Used to be language
255 p->Send_uint32(ci->join_date.base());
256 p->Send_uint8 (ci->client_playas);
258 this->SendPacket(std::move(p));
260 return NETWORK_RECV_STATUS_OKAY;
265 * Send an update for some client's information.
266 * @param ci The information about a client.
268 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientUpdate(const NetworkClientInfo *ci)
270 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CLIENT_UPDATE);
272 p->Send_uint32(ci->client_id);
273 p->Send_string(ci->client_name);
274 p->Send_uint8 (ci->client_playas);
276 this->SendPacket(std::move(p));
278 return NETWORK_RECV_STATUS_OKAY;
282 * Tell the admin that a client quit.
283 * @param client_id The client that quit.
285 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientQuit(ClientID client_id)
287 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CLIENT_QUIT);
289 p->Send_uint32(client_id);
290 this->SendPacket(std::move(p));
292 return NETWORK_RECV_STATUS_OKAY;
296 * Tell the admin that a client made an error.
297 * @param client_id The client that made the error.
298 * @param error The error that was made.
300 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientError(ClientID client_id, NetworkErrorCode error)
302 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CLIENT_ERROR);
304 p->Send_uint32(client_id);
305 p->Send_uint8 (error);
306 this->SendPacket(std::move(p));
308 return NETWORK_RECV_STATUS_OKAY;
312 * Tell the admin that a new company was founded.
313 * @param company_id The company that was founded.
315 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyNew(CompanyID company_id)
317 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_NEW);
318 p->Send_uint8(company_id);
320 this->SendPacket(std::move(p));
322 return NETWORK_RECV_STATUS_OKAY;
326 * Send the admin some information about a company.
327 * @param c The company to send the information about.
329 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyInfo(const Company *c)
331 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_INFO);
333 p->Send_uint8 (c->index);
334 SetDParam(0, c->index);
335 p->Send_string(GetString(STR_COMPANY_NAME));
336 SetDParam(0, c->index);
337 p->Send_string(GetString(STR_PRESIDENT_NAME));
338 p->Send_uint8 (c->colour);
339 p->Send_bool (true);
340 p->Send_uint32(c->inaugurated_year.base());
341 p->Send_bool (c->is_ai);
342 p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy
344 this->SendPacket(std::move(p));
346 return NETWORK_RECV_STATUS_OKAY;
351 * Send an update about a company.
352 * @param c The company to send the update of.
354 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyUpdate(const Company *c)
356 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_UPDATE);
358 p->Send_uint8 (c->index);
359 SetDParam(0, c->index);
360 p->Send_string(GetString(STR_COMPANY_NAME));
361 SetDParam(0, c->index);
362 p->Send_string(GetString(STR_PRESIDENT_NAME));
363 p->Send_uint8 (c->colour);
364 p->Send_bool (true);
365 p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy
367 this->SendPacket(std::move(p));
369 return NETWORK_RECV_STATUS_OKAY;
373 * Tell the admin that a company got removed.
374 * @param company_id The company that got removed.
375 * @param acrr The reason for removal, e.g. bankruptcy or merger.
377 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason acrr)
379 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_REMOVE);
381 p->Send_uint8(company_id);
382 p->Send_uint8(acrr);
384 this->SendPacket(std::move(p));
386 return NETWORK_RECV_STATUS_OKAY;
389 /** Send economic information of all companies. */
390 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyEconomy()
392 for (const Company *company : Company::Iterate()) {
393 /* Get the income. */
394 Money income = -std::reduce(std::begin(company->yearly_expenses[0]), std::end(company->yearly_expenses[0]));
396 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_ECONOMY);
398 p->Send_uint8(company->index);
400 /* Current information. */
401 p->Send_uint64(company->money);
402 p->Send_uint64(company->current_loan);
403 p->Send_uint64(income);
404 p->Send_uint16(static_cast<uint16_t>(std::min<uint64_t>(UINT16_MAX, company->cur_economy.delivered_cargo.GetSum<OverflowSafeInt64>())));
406 /* Send stats for the last 2 quarters. */
407 for (uint i = 0; i < 2; i++) {
408 p->Send_uint64(company->old_economy[i].company_value);
409 p->Send_uint16(company->old_economy[i].performance_history);
410 p->Send_uint16(static_cast<uint16_t>(std::min<uint64_t>(UINT16_MAX, company->old_economy[i].delivered_cargo.GetSum<OverflowSafeInt64>())));
413 this->SendPacket(std::move(p));
417 return NETWORK_RECV_STATUS_OKAY;
420 /** Send statistics about the companies. */
421 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyStats()
423 /* Fetch the latest version of the stats. */
424 NetworkCompanyStats company_stats[MAX_COMPANIES];
425 NetworkPopulateCompanyStats(company_stats);
427 /* Go through all the companies. */
428 for (const Company *company : Company::Iterate()) {
429 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_STATS);
431 /* Send the information. */
432 p->Send_uint8(company->index);
434 for (uint i = 0; i < NETWORK_VEH_END; i++) {
435 p->Send_uint16(company_stats[company->index].num_vehicle[i]);
438 for (uint i = 0; i < NETWORK_VEH_END; i++) {
439 p->Send_uint16(company_stats[company->index].num_station[i]);
442 this->SendPacket(std::move(p));
445 return NETWORK_RECV_STATUS_OKAY;
449 * Send a chat message.
450 * @param action The action associated with the message.
451 * @param desttype The destination type.
452 * @param client_id The origin of the chat message.
453 * @param msg The actual message.
454 * @param data Arbitrary extra data.
456 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, int64_t data)
458 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CHAT);
460 p->Send_uint8 (action);
461 p->Send_uint8 (desttype);
462 p->Send_uint32(client_id);
463 p->Send_string(msg);
464 p->Send_uint64(data);
466 this->SendPacket(std::move(p));
467 return NETWORK_RECV_STATUS_OKAY;
471 * Send a notification indicating the rcon command has completed.
472 * @param command The original command sent.
474 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRconEnd(const std::string_view command)
476 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_RCON_END);
478 p->Send_string(command);
479 this->SendPacket(std::move(p));
481 return NETWORK_RECV_STATUS_OKAY;
485 * Send the reply of an rcon command.
486 * @param colour The colour of the text.
487 * @param result The result of the command.
489 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRcon(uint16_t colour, const std::string_view result)
491 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_RCON);
493 p->Send_uint16(colour);
494 p->Send_string(result);
495 this->SendPacket(std::move(p));
497 return NETWORK_RECV_STATUS_OKAY;
500 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_RCON(Packet &p)
502 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
504 std::string command = p.Recv_string(NETWORK_RCONCOMMAND_LENGTH);
506 Debug(net, 3, "[admin] Rcon command from '{}' ({}): {}", this->admin_name, this->admin_version, command);
508 _redirect_console_to_admin = this->index;
509 IConsoleCmdExec(command);
510 _redirect_console_to_admin = INVALID_ADMIN_ID;
511 return this->SendRconEnd(command);
514 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_GAMESCRIPT(Packet &p)
516 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
518 std::string json = p.Recv_string(NETWORK_GAMESCRIPT_JSON_LENGTH);
520 Debug(net, 6, "[admin] GameScript JSON from '{}' ({}): {}", this->admin_name, this->admin_version, json);
522 Game::NewEvent(new ScriptEventAdminPort(json));
523 return NETWORK_RECV_STATUS_OKAY;
526 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_PING(Packet &p)
528 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
530 uint32_t d1 = p.Recv_uint32();
532 Debug(net, 6, "[admin] Ping from '{}' ({}): {}", this->admin_name, this->admin_version, d1);
534 return this->SendPong(d1);
538 * Send console output of other clients.
539 * @param origin The origin of the string.
540 * @param string The string that's put on the console.
542 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const std::string_view origin, const std::string_view string)
544 /* If the length of both strings, plus the 2 '\0' terminations and 3 bytes of the packet
545 * are bigger than the MTU, just ignore the message. Better safe than sorry. It should
546 * never occur though as the longest strings are chat messages, which are still 30%
547 * smaller than COMPAT_MTU. */
548 if (origin.size() + string.size() + 2 + 3 >= COMPAT_MTU) return NETWORK_RECV_STATUS_OKAY;
550 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CONSOLE);
552 p->Send_string(origin);
553 p->Send_string(string);
554 this->SendPacket(std::move(p));
556 return NETWORK_RECV_STATUS_OKAY;
560 * Send GameScript JSON output.
561 * @param json The JSON string.
563 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendGameScript(const std::string_view json)
565 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_GAMESCRIPT);
567 p->Send_string(json);
568 this->SendPacket(std::move(p));
570 return NETWORK_RECV_STATUS_OKAY;
573 /** Send ping-reply (pong) to admin **/
574 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendPong(uint32_t d1)
576 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_PONG);
578 p->Send_uint32(d1);
579 this->SendPacket(std::move(p));
581 return NETWORK_RECV_STATUS_OKAY;
584 /** Send the names of the commands. */
585 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdNames()
587 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CMD_NAMES);
589 for (uint16_t i = 0; i < CMD_END; i++) {
590 const char *cmdname = GetCommandName(static_cast<Commands>(i));
592 /* Should COMPAT_MTU be exceeded, start a new packet
593 * (magic 5: 1 bool "more data" and one uint16_t "command id", one
594 * byte for string '\0' termination and 1 bool "no more data" */
595 if (!p->CanWriteToPacket(strlen(cmdname) + 5)) {
596 p->Send_bool(false);
597 this->SendPacket(std::move(p));
599 p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CMD_NAMES);
602 p->Send_bool(true);
603 p->Send_uint16(i);
604 p->Send_string(cmdname);
607 /* Marker to notify the end of the packet has been reached. */
608 p->Send_bool(false);
609 this->SendPacket(std::move(p));
611 return NETWORK_RECV_STATUS_OKAY;
615 * Send a command for logging purposes.
616 * @param client_id The client executing the command.
617 * @param cp The command that would be executed.
619 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdLogging(ClientID client_id, const CommandPacket &cp)
621 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CMD_LOGGING);
623 p->Send_uint32(client_id);
624 p->Send_uint8 (cp.company);
625 p->Send_uint16(cp.cmd);
626 p->Send_buffer(cp.data);
627 p->Send_uint32(cp.frame);
629 this->SendPacket(std::move(p));
631 return NETWORK_RECV_STATUS_OKAY;
634 /***********
635 * Receiving functions
636 ************/
638 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_JOIN(Packet &p)
640 if (this->status != ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
642 if (!_settings_client.network.allow_insecure_admin_login) {
643 /* You're not authorized to login using this method. */
644 return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
647 std::string password = p.Recv_string(NETWORK_PASSWORD_LENGTH);
649 if (_settings_client.network.admin_password.empty() ||
650 _settings_client.network.admin_password.compare(password) != 0) {
651 /* Password is invalid */
652 return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
655 this->admin_name = p.Recv_string(NETWORK_CLIENT_NAME_LENGTH);
656 this->admin_version = p.Recv_string(NETWORK_REVISION_LENGTH);
658 if (this->admin_name.empty() || this->admin_version.empty()) {
659 /* no name or version supplied */
660 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
663 Debug(net, 3, "[admin] '{}' ({}) has connected", this->admin_name, this->admin_version);
665 return this->SendProtocol();
668 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_QUIT(Packet &)
670 /* The admin is leaving nothing else to do */
671 return this->CloseConnection();
674 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_UPDATE_FREQUENCY(Packet &p)
676 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
678 AdminUpdateType type = (AdminUpdateType)p.Recv_uint16();
679 AdminUpdateFrequency freq = (AdminUpdateFrequency)p.Recv_uint16();
681 if (type >= ADMIN_UPDATE_END || (_admin_update_type_frequencies[type] & freq) != freq) {
682 /* The server does not know of this UpdateType. */
683 Debug(net, 1, "[admin] Not supported update frequency {} ({}) from '{}' ({})", type, freq, this->admin_name, this->admin_version);
684 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
687 this->update_frequency[type] = freq;
689 if (type == ADMIN_UPDATE_CONSOLE) DebugReconsiderSendRemoteMessages();
691 return NETWORK_RECV_STATUS_OKAY;
694 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_POLL(Packet &p)
696 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
698 AdminUpdateType type = (AdminUpdateType)p.Recv_uint8();
699 uint32_t d1 = p.Recv_uint32();
701 switch (type) {
702 case ADMIN_UPDATE_DATE:
703 /* The admin is requesting the current date. */
704 this->SendDate();
705 break;
707 case ADMIN_UPDATE_CLIENT_INFO:
708 /* The admin is requesting client info. */
709 if (d1 == UINT32_MAX) {
710 this->SendClientInfo(nullptr, NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER));
711 for (const NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
712 this->SendClientInfo(cs, cs->GetInfo());
714 } else {
715 if (d1 == CLIENT_ID_SERVER) {
716 this->SendClientInfo(nullptr, NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER));
717 } else {
718 const NetworkClientSocket *cs = NetworkClientSocket::GetByClientID((ClientID)d1);
719 if (cs != nullptr) this->SendClientInfo(cs, cs->GetInfo());
722 break;
724 case ADMIN_UPDATE_COMPANY_INFO:
725 /* The admin is asking for company info. */
726 if (d1 == UINT32_MAX) {
727 for (const Company *company : Company::Iterate()) {
728 this->SendCompanyInfo(company);
730 } else {
731 const Company *company = Company::GetIfValid(d1);
732 if (company != nullptr) this->SendCompanyInfo(company);
734 break;
736 case ADMIN_UPDATE_COMPANY_ECONOMY:
737 /* The admin is requesting economy info. */
738 this->SendCompanyEconomy();
739 break;
741 case ADMIN_UPDATE_COMPANY_STATS:
742 /* the admin is requesting company stats. */
743 this->SendCompanyStats();
744 break;
746 case ADMIN_UPDATE_CMD_NAMES:
747 /* The admin is requesting the names of DoCommands. */
748 this->SendCmdNames();
749 break;
751 default:
752 /* An unsupported "poll" update type. */
753 Debug(net, 1, "[admin] Not supported poll {} ({}) from '{}' ({}).", type, d1, this->admin_name, this->admin_version);
754 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
757 return NETWORK_RECV_STATUS_OKAY;
760 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_CHAT(Packet &p)
762 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
764 NetworkAction action = (NetworkAction)p.Recv_uint8();
765 DestType desttype = (DestType)p.Recv_uint8();
766 int dest = p.Recv_uint32();
768 std::string msg = p.Recv_string(NETWORK_CHAT_LENGTH);
770 switch (action) {
771 case NETWORK_ACTION_CHAT:
772 case NETWORK_ACTION_CHAT_CLIENT:
773 case NETWORK_ACTION_CHAT_COMPANY:
774 case NETWORK_ACTION_SERVER_MESSAGE:
775 NetworkServerSendChat(action, desttype, dest, msg, _network_own_client_id, 0, true);
776 break;
778 default:
779 Debug(net, 1, "[admin] Invalid chat action {} from admin '{}' ({}).", action, this->admin_name, this->admin_version);
780 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
783 return NETWORK_RECV_STATUS_OKAY;
786 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_EXTERNAL_CHAT(Packet &p)
788 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
790 std::string source = p.Recv_string(NETWORK_CHAT_LENGTH);
791 TextColour colour = (TextColour)p.Recv_uint16();
792 std::string user = p.Recv_string(NETWORK_CHAT_LENGTH);
793 std::string msg = p.Recv_string(NETWORK_CHAT_LENGTH);
795 if (!IsValidConsoleColour(colour)) {
796 Debug(net, 1, "[admin] Not supported chat colour {} ({}, {}, {}) from '{}' ({}).", (uint16_t)colour, source, user, msg, this->admin_name, this->admin_version);
797 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
800 NetworkServerSendExternalChat(source, colour, user, msg);
802 return NETWORK_RECV_STATUS_OKAY;
806 * Secure authentication send and receive methods.
809 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_JOIN_SECURE(Packet &p)
811 if (this->status != ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
813 this->admin_name = p.Recv_string(NETWORK_CLIENT_NAME_LENGTH);
814 this->admin_version = p.Recv_string(NETWORK_REVISION_LENGTH);
815 NetworkAuthenticationMethodMask method_mask = p.Recv_uint16();
817 /* Always exclude key exchange only, as that provides no credential checking. */
818 ClrBit(method_mask, NETWORK_AUTH_METHOD_X25519_KEY_EXCHANGE_ONLY);
820 if (this->admin_name.empty() || this->admin_version.empty()) {
821 /* No name or version supplied. */
822 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
825 auto handler = NetworkAuthenticationServerHandler::Create(&_admin_password_provider, &_admin_authorized_key_handler, method_mask);
826 if (!handler->CanBeUsed()) return this->SendError(NETWORK_ERROR_NO_AUTHENTICATION_METHOD_AVAILABLE);
828 this->authentication_handler = std::move(handler);
829 Debug(net, 3, "[admin] '{}' ({}) has connected", this->admin_name, this->admin_version);
831 return this->SendAuthRequest();
834 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendAuthRequest()
836 this->status = ADMIN_STATUS_AUTHENTICATE;
838 Debug(net, 6, "[admin] '{}' ({}) authenticating using {}", this->admin_name, this->admin_version, this->authentication_handler->GetName());
840 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_AUTH_REQUEST);
841 this->authentication_handler->SendRequest(*p);
843 this->SendPacket(std::move(p));
845 return NETWORK_RECV_STATUS_OKAY;
848 NetworkRecvStatus ServerNetworkAdminSocketHandler::SendEnableEncryption()
850 if (this->status != ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
852 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_ENABLE_ENCRYPTION);
853 this->authentication_handler->SendEnableEncryption(*p);
854 this->SendPacket(std::move(p));
856 return NETWORK_RECV_STATUS_OKAY;
859 NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_AUTH_RESPONSE(Packet &p)
861 if (this->status != ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
863 switch (this->authentication_handler->ReceiveResponse(p)) {
864 case NetworkAuthenticationServerHandler::AUTHENTICATED:
865 Debug(net, 3, "[admin] '{}' ({}) authenticated", this->admin_name, this->admin_version);
867 this->SendEnableEncryption();
869 this->receive_encryption_handler = this->authentication_handler->CreateClientToServerEncryptionHandler();
870 this->send_encryption_handler = this->authentication_handler->CreateServerToClientEncryptionHandler();
871 this->authentication_handler = nullptr;
872 return this->SendProtocol();
874 case NetworkAuthenticationServerHandler::RETRY_NEXT_METHOD:
875 Debug(net, 6, "[admin] '{}' ({}) authentication failed, trying next method", this->admin_name, this->admin_version);
876 return this->SendAuthRequest();
878 case NetworkAuthenticationServerHandler::NOT_AUTHENTICATED:
879 default:
880 Debug(net, 3, "[admin] '{}' ({}) authentication failed", this->admin_name, this->admin_version);
881 return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
886 * Useful wrapper functions
890 * Notify the admin network of a new client (if they did opt in for the respective update).
891 * @param cs the client info.
892 * @param new_client if this is a new client, send the respective packet too.
894 void NetworkAdminClientInfo(const NetworkClientSocket *cs, bool new_client)
896 for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
897 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
898 as->SendClientInfo(cs, cs->GetInfo());
899 if (new_client) {
900 as->SendClientJoin(cs->client_id);
907 * Notify the admin network of a client update (if they did opt in for the respective update).
908 * @param ci the client info.
910 void NetworkAdminClientUpdate(const NetworkClientInfo *ci)
912 for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
913 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
914 as->SendClientUpdate(ci);
920 * Notify the admin network that a client quit (if they have opt in for the respective update).
921 * @param client_id of the client that quit.
923 void NetworkAdminClientQuit(ClientID client_id)
925 for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
926 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
927 as->SendClientQuit(client_id);
933 * Notify the admin network of a client error (if they have opt in for the respective update).
934 * @param client_id the client that made the error.
935 * @param error_code the error that was caused.
937 void NetworkAdminClientError(ClientID client_id, NetworkErrorCode error_code)
939 for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
940 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
941 as->SendClientError(client_id, error_code);
947 * Notify the admin network of a new company.
948 * @param company the company of which details will be sent into the admin network.
950 void NetworkAdminCompanyNew(const Company *company)
952 if (company == nullptr) {
953 Debug(net, 1, "[admin] Empty company given for update");
954 return;
957 for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
958 if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != ADMIN_FREQUENCY_AUTOMATIC) continue;
960 as->SendCompanyNew(company->index);
961 as->SendCompanyInfo(company);
966 * Notify the admin network of company updates.
967 * @param company company of which updates are going to be sent into the admin network.
969 void NetworkAdminCompanyUpdate(const Company *company)
971 if (company == nullptr) return;
973 for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
974 if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != ADMIN_FREQUENCY_AUTOMATIC) continue;
976 as->SendCompanyUpdate(company);
981 * Notify the admin network of a company to be removed (including the reason why).
982 * @param company_id ID of the company that got removed.
983 * @param bcrr the reason why the company got removed (e.g. bankruptcy).
985 void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bcrr)
987 for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
988 as->SendCompanyRemove(company_id, bcrr);
994 * Send chat to the admin network (if they did opt in for the respective update).
996 void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, int64_t data, bool from_admin)
998 if (from_admin) return;
1000 for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
1001 if (as->update_frequency[ADMIN_UPDATE_CHAT] & ADMIN_FREQUENCY_AUTOMATIC) {
1002 as->SendChat(action, desttype, client_id, msg, data);
1008 * Pass the rcon reply to the admin.
1009 * @param admin_index The admin to give the reply.
1010 * @param colour_code The colour of the string.
1011 * @param string The string to show.
1013 void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const std::string_view string)
1015 ServerNetworkAdminSocketHandler::Get(admin_index)->SendRcon(colour_code, string);
1019 * Send console to the admin network (if they did opt in for the respective update).
1020 * @param origin the origin of the message.
1021 * @param string the message as printed on the console.
1023 void NetworkAdminConsole(const std::string_view origin, const std::string_view string)
1025 for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
1026 if (as->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) {
1027 as->SendConsole(origin, string);
1033 * Send GameScript JSON to the admin network (if they did opt in for the respective update).
1034 * @param json The JSON data as received from the GameScript.
1036 void NetworkAdminGameScript(const std::string_view json)
1038 for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
1039 if (as->update_frequency[ADMIN_UPDATE_GAMESCRIPT] & ADMIN_FREQUENCY_AUTOMATIC) {
1040 as->SendGameScript(json);
1046 * Distribute CommandPacket details over the admin network for logging purposes.
1047 * @param owner The owner of the CommandPacket (who sent us the CommandPacket).
1048 * @param cp The CommandPacket to be distributed.
1050 void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket &cp)
1052 ClientID client_id = owner == nullptr ? _network_own_client_id : owner->client_id;
1054 for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
1055 if (as->update_frequency[ADMIN_UPDATE_CMD_LOGGING] & ADMIN_FREQUENCY_AUTOMATIC) {
1056 as->SendCmdLogging(client_id, cp);
1062 * Send a Welcome packet to all connected admins
1064 void ServerNetworkAdminSocketHandler::WelcomeAll()
1066 for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
1067 as->SendWelcome();
1072 * Send (push) updates to the admin network as they have registered for these updates.
1073 * @param freq the frequency to be processed.
1075 void NetworkAdminUpdate(AdminUpdateFrequency freq)
1077 for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
1078 for (int i = 0; i < ADMIN_UPDATE_END; i++) {
1079 if (as->update_frequency[i] & freq) {
1080 /* Update the admin for the required details */
1081 switch (i) {
1082 case ADMIN_UPDATE_DATE:
1083 as->SendDate();
1084 break;
1086 case ADMIN_UPDATE_COMPANY_ECONOMY:
1087 as->SendCompanyEconomy();
1088 break;
1090 case ADMIN_UPDATE_COMPANY_STATS:
1091 as->SendCompanyStats();
1092 break;
1094 default: NOT_REACHED();