OpenTTD Source 20260311-master-g511d3794ce
network_admin.cpp
Go to the documentation of this file.
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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#include "../stdafx.h"
11#include "../strings_func.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"
25
26#include "table/strings.h"
27
28#include "../safeguards.h"
29
30
31/* This file handles all the admin network commands. */
32
35
38INSTANTIATE_POOL_METHODS(NetworkAdminSocket)
39
42
44static const std::chrono::seconds ADMIN_AUTHORISATION_TIMEOUT{10};
45
46
60
62
69 NetworkAdminSocketPool::PoolItem<&_networkadminsocket_pool>(index), NetworkAdminSocketHandler(s)
70{
72 this->connect_time = std::chrono::steady_clock::now();
73}
74
88
94{
95 return _settings_client.network.AdminAuthenticationConfigured() && ServerNetworkAdminSocketHandler::CanAllocateItem();
96}
97
100{
102 if (as->status <= ADMIN_STATUS_AUTHENTICATE && std::chrono::steady_clock::now() > as->connect_time + ADMIN_AUTHORISATION_TIMEOUT) {
103 Debug(net, 2, "[admin] Admin did not send its authorisation within {} seconds", std::chrono::duration_cast<std::chrono::seconds>(ADMIN_AUTHORISATION_TIMEOUT).count());
104 as->CloseConnection(true);
105 continue;
106 }
107 if (as->writable) {
108 as->SendPackets();
109 }
110 }
111}
112
119{
121 as->address = address; // Save the IP of the client
122}
123
124/***********
125 * Sending functions for admin network
126 ************/
127
134{
135 /* Whatever the error might be, authentication (keys) must be released as soon as possible. */
136 this->authentication_handler = nullptr;
137
138 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_ERROR);
139
140 p->Send_uint8(to_underlying(error));
141 this->SendPacket(std::move(p));
142
143 std::string error_message = GetString(GetNetworkErrorMsg(error));
144
145 Debug(net, 1, "[admin] The admin '{}' ({}) made an error and has been disconnected: '{}'", this->admin_name, this->admin_version, error_message);
146
147 return this->CloseConnection(true);
148}
149
155{
157
158 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_PROTOCOL);
159
160 /* announce the protocol version */
161 p->Send_uint8(NETWORK_GAME_ADMIN_VERSION);
162
163 for (int i = 0; i < ADMIN_UPDATE_END; i++) {
164 p->Send_bool (true);
165 p->Send_uint16(i);
166 p->Send_uint16(_admin_update_type_frequencies[i].base());
167 }
168
169 p->Send_bool(false);
170 this->SendPacket(std::move(p));
171
172 return this->SendWelcome();
173}
174
180{
181 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_WELCOME);
182
183 p->Send_string(_settings_client.network.server_name);
184 p->Send_string(GetNetworkRevisionString());
185 p->Send_bool (_network_dedicated);
186
187 p->Send_string(""); // Used to be map-name.
188 p->Send_uint32(_settings_game.game_creation.generation_seed);
189 p->Send_uint8 (to_underlying(_settings_game.game_creation.landscape));
190 p->Send_uint32(TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1).base());
191 p->Send_uint16(Map::SizeX());
192 p->Send_uint16(Map::SizeY());
193
194 this->SendPacket(std::move(p));
195
197}
198
204{
205 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_NEWGAME);
206 this->SendPacket(std::move(p));
208}
209
215{
216 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_SHUTDOWN);
217 this->SendPacket(std::move(p));
219}
220
226{
227 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_DATE);
228
229 p->Send_uint32(TimerGameCalendar::date.base());
230 this->SendPacket(std::move(p));
231
233}
234
241{
242 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CLIENT_JOIN);
243
244 p->Send_uint32(client_id);
245 this->SendPacket(std::move(p));
246
248}
249
257{
258 /* Only send data when we're a proper client, not just someone trying to query the server. */
259 if (ci == nullptr) return NETWORK_RECV_STATUS_OKAY;
260
261 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CLIENT_INFO);
262
263 p->Send_uint32(ci->client_id);
264 p->Send_string(cs == nullptr ? "" : const_cast<NetworkAddress &>(cs->client_address).GetHostname());
265 p->Send_string(ci->client_name);
266 p->Send_uint8 (0); // Used to be language
267 p->Send_uint32(ci->join_date.base());
268 p->Send_uint8 (ci->client_playas);
269
270 this->SendPacket(std::move(p));
271
273}
274
275
282{
283 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CLIENT_UPDATE);
284
285 p->Send_uint32(ci->client_id);
286 p->Send_string(ci->client_name);
287 p->Send_uint8 (ci->client_playas);
288
289 this->SendPacket(std::move(p));
290
292}
293
300{
301 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CLIENT_QUIT);
302
303 p->Send_uint32(client_id);
304 this->SendPacket(std::move(p));
305
307}
308
316{
317 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CLIENT_ERROR);
318
319 p->Send_uint32(client_id);
320 p->Send_uint8(to_underlying(error));
321 this->SendPacket(std::move(p));
322
324}
325
332{
333 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_NEW);
334 p->Send_uint8(company_id);
335
336 this->SendPacket(std::move(p));
337
339}
340
347{
348 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_INFO);
349
350 p->Send_uint8 (c->index);
351 p->Send_string(GetString(STR_COMPANY_NAME, c->index));
352 p->Send_string(GetString(STR_PRESIDENT_NAME, c->index));
353 p->Send_uint8 (c->colour);
354 p->Send_bool (true);
355 p->Send_uint32(c->inaugurated_year.base());
356 p->Send_bool (c->is_ai);
357 p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy
358
359 this->SendPacket(std::move(p));
360
362}
363
364
371{
372 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_UPDATE);
373
374 p->Send_uint8 (c->index);
375 p->Send_string(GetString(STR_COMPANY_NAME, c->index));
376 p->Send_string(GetString(STR_PRESIDENT_NAME, c->index));
377 p->Send_uint8 (c->colour);
378 p->Send_bool (true);
379 p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy
380
381 this->SendPacket(std::move(p));
382
384}
385
393{
394 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_REMOVE);
395
396 p->Send_uint8(company_id);
397 p->Send_uint8(acrr);
398
399 this->SendPacket(std::move(p));
400
402}
403
409{
410 for (const Company *company : Company::Iterate()) {
411 /* Get the income. */
412 Money income = -std::reduce(std::begin(company->yearly_expenses[0]), std::end(company->yearly_expenses[0]));
413
414 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_ECONOMY);
415
416 p->Send_uint8(company->index);
417
418 /* Current information. */
419 p->Send_uint64(company->money);
420 p->Send_uint64(company->current_loan);
421 p->Send_uint64(income);
422 p->Send_uint16(static_cast<uint16_t>(std::min<uint64_t>(UINT16_MAX, company->cur_economy.delivered_cargo.GetSum<OverflowSafeInt64>())));
423
424 /* Send stats for the last 2 quarters. */
425 for (uint i = 0; i < 2; i++) {
426 p->Send_uint64(company->old_economy[i].company_value);
427 p->Send_uint16(company->old_economy[i].performance_history);
428 p->Send_uint16(static_cast<uint16_t>(std::min<uint64_t>(UINT16_MAX, company->old_economy[i].delivered_cargo.GetSum<OverflowSafeInt64>())));
429 }
430
431 this->SendPacket(std::move(p));
432 }
433
434
436}
437
443{
444 /* Fetch the latest version of the stats. */
445 NetworkCompanyStatsArray company_stats = NetworkGetCompanyStats();
446
447 /* Go through all the companies. */
448 for (const Company *company : Company::Iterate()) {
449 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_STATS);
450
451 /* Send the information. */
452 p->Send_uint8(company->index);
453 for (uint16_t value : company_stats[company->index].num_vehicle) p->Send_uint16(value);
454 for (uint16_t value : company_stats[company->index].num_station) p->Send_uint16(value);
455
456 this->SendPacket(std::move(p));
457 }
458
460}
461
471NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action, DestType desttype, ClientID client_id, std::string_view msg, int64_t data)
472{
473 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CHAT);
474
475 p->Send_uint8 (action);
476 p->Send_uint8 (desttype);
477 p->Send_uint32(client_id);
478 p->Send_string(msg);
479 p->Send_uint64(data);
480
481 this->SendPacket(std::move(p));
483}
484
491{
492 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_RCON_END);
493
494 p->Send_string(command);
495 this->SendPacket(std::move(p));
496
498}
499
506NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRcon(uint16_t colour, std::string_view result)
507{
508 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_RCON);
509
510 p->Send_uint16(colour);
511 p->Send_string(result);
512 this->SendPacket(std::move(p));
513
515}
516
518{
520
521 std::string command = p.Recv_string(NETWORK_RCONCOMMAND_LENGTH);
522
523 Debug(net, 3, "[admin] Rcon command from '{}' ({}): {}", this->admin_name, this->admin_version, command);
524
526 IConsoleCmdExec(command);
527 _redirect_console_to_admin = AdminID::Invalid();
528 return this->SendRconEnd(command);
529}
530
532{
534
535 std::string json = p.Recv_string(NETWORK_GAMESCRIPT_JSON_LENGTH);
536
537 Debug(net, 6, "[admin] GameScript JSON from '{}' ({}): {}", this->admin_name, this->admin_version, json);
538
539 Game::NewEvent(new ScriptEventAdminPort(json));
541}
542
544{
546
547 uint32_t d1 = p.Recv_uint32();
548
549 Debug(net, 6, "[admin] Ping from '{}' ({}): {}", this->admin_name, this->admin_version, d1);
550
551 return this->SendPong(d1);
552}
553
560NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(std::string_view origin, std::string_view string)
561{
562 /* If the length of both strings, plus the 2 '\0' terminations and 3 bytes of the packet
563 * are bigger than the MTU, just ignore the message. Better safe than sorry. It should
564 * never occur though as the longest strings are chat messages, which are still 30%
565 * smaller than COMPAT_MTU. */
566 if (origin.size() + string.size() + 2 + 3 >= COMPAT_MTU) return NETWORK_RECV_STATUS_OKAY;
567
568 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CONSOLE);
569
570 p->Send_string(origin);
571 p->Send_string(string);
572 this->SendPacket(std::move(p));
573
575}
576
583{
584 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_GAMESCRIPT);
585
586 p->Send_string(json);
587 this->SendPacket(std::move(p));
588
590}
591
598{
599 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_PONG);
600
601 p->Send_uint32(d1);
602 this->SendPacket(std::move(p));
603
605}
606
612{
613 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CMD_NAMES);
614
615 for (uint16_t i = 0; i < to_underlying(Commands::End); i++) {
616 std::string_view cmdname = GetCommandName(static_cast<Commands>(i));
617
618 /* Should COMPAT_MTU be exceeded, start a new packet
619 * (magic 5: 1 bool "more data" and one uint16_t "command id", one
620 * byte for string '\0' termination and 1 bool "no more data" */
621 if (!p->CanWriteToPacket(cmdname.size() + 5)) {
622 p->Send_bool(false);
623 this->SendPacket(std::move(p));
624
625 p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CMD_NAMES);
626 }
627
628 p->Send_bool(true);
629 p->Send_uint16(i);
630 p->Send_string(cmdname);
631 }
632
633 /* Marker to notify the end of the packet has been reached. */
634 p->Send_bool(false);
635 this->SendPacket(std::move(p));
636
638}
639
647{
648 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CMD_LOGGING);
649
650 p->Send_uint32(client_id);
651 p->Send_uint8 (cp.company);
652 p->Send_uint16(to_underlying(cp.cmd));
653 p->Send_buffer(cp.data);
654 p->Send_uint32(cp.frame);
655
656 this->SendPacket(std::move(p));
657
659}
660
661/***********
662 * Receiving functions
663 ************/
664
666{
668
669 if (!_settings_client.network.allow_insecure_admin_login) {
670 /* You're not authorized to login using this method. */
672 }
673
674 std::string password = p.Recv_string(NETWORK_PASSWORD_LENGTH);
675
676 if (_settings_client.network.admin_password.empty() || _settings_client.network.admin_password != password) {
677 /* Password is invalid */
679 }
680
683
684 if (this->admin_name.empty() || this->admin_version.empty()) {
685 /* no name or version supplied */
687 }
688
689 Debug(net, 3, "[admin] '{}' ({}) has connected", this->admin_name, this->admin_version);
690
691 return this->SendProtocol();
692}
693
695{
696 /* The admin is leaving nothing else to do */
697 return this->CloseConnection();
698}
699
701{
703
706
707 if (type >= ADMIN_UPDATE_END || !_admin_update_type_frequencies[type].All(freq)) {
708 /* The server does not know of this UpdateType. */
709 Debug(net, 1, "[admin] Not supported update frequency {} ({}) from '{}' ({})", type, freq, this->admin_name, this->admin_version);
711 }
712
713 this->update_frequency[type] = freq;
714
716
718}
719
721{
723
725 uint32_t d1 = p.Recv_uint32();
726
727 switch (type) {
729 /* The admin is requesting the current date. */
730 this->SendDate();
731 break;
732
734 /* The admin is requesting client info. */
735 if (d1 == UINT32_MAX) {
737 for (const NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
738 this->SendClientInfo(cs, cs->GetInfo());
739 }
740 } else {
741 if (d1 == CLIENT_ID_SERVER) {
743 } else {
744 const NetworkClientSocket *cs = NetworkClientSocket::GetByClientID((ClientID)d1);
745 if (cs != nullptr) this->SendClientInfo(cs, cs->GetInfo());
746 }
747 }
748 break;
749
751 /* The admin is asking for company info. */
752 if (d1 == UINT32_MAX) {
753 for (const Company *company : Company::Iterate()) {
754 this->SendCompanyInfo(company);
755 }
756 } else {
757 const Company *company = Company::GetIfValid(d1);
758 if (company != nullptr) this->SendCompanyInfo(company);
759 }
760 break;
761
763 /* The admin is requesting economy info. */
764 this->SendCompanyEconomy();
765 break;
766
768 /* the admin is requesting company stats. */
769 this->SendCompanyStats();
770 break;
771
773 /* The admin is requesting the names of DoCommands. */
774 this->SendCmdNames();
775 break;
776
777 default:
778 /* An unsupported "poll" update type. */
779 Debug(net, 1, "[admin] Not supported poll {} ({}) from '{}' ({}).", type, d1, this->admin_name, this->admin_version);
781 }
782
784}
785
787{
789
791 DestType desttype = (DestType)p.Recv_uint8();
792 int dest = p.Recv_uint32();
793
794 std::string msg = p.Recv_string(NETWORK_CHAT_LENGTH);
795
796 switch (action) {
797 case NETWORK_ACTION_CHAT:
798 case NETWORK_ACTION_CHAT_CLIENT:
799 case NETWORK_ACTION_CHAT_COMPANY:
800 case NETWORK_ACTION_SERVER_MESSAGE:
801 NetworkServerSendChat(action, desttype, dest, msg, _network_own_client_id, 0, true);
802 break;
803
804 default:
805 Debug(net, 1, "[admin] Invalid chat action {} from admin '{}' ({}).", action, this->admin_name, this->admin_version);
807 }
808
810}
811
813{
815
816 std::string source = p.Recv_string(NETWORK_CHAT_LENGTH);
817 TextColour colour = (TextColour)p.Recv_uint16();
818 std::string user = p.Recv_string(NETWORK_CHAT_LENGTH);
819 std::string msg = p.Recv_string(NETWORK_CHAT_LENGTH);
820
821 if (!IsValidConsoleColour(colour)) {
822 Debug(net, 1, "[admin] Not supported chat colour {} ({}, {}, {}) from '{}' ({}).", (uint16_t)colour, source, user, msg, this->admin_name, this->admin_version);
824 }
825
826 NetworkServerSendExternalChat(source, colour, user, msg);
827
829}
830
831/*
832 * Secure authentication send and receive methods.
833 */
834
836{
838
842
843 /* Always exclude key exchange only, as that provides no credential checking. */
845
846 if (this->admin_name.empty() || this->admin_version.empty()) {
847 /* No name or version supplied. */
849 }
850
852 if (!handler->CanBeUsed()) return this->SendError(NetworkErrorCode::NoAuthenticationMethodAvailable);
853
854 this->authentication_handler = std::move(handler);
855 Debug(net, 3, "[admin] '{}' ({}) has connected", this->admin_name, this->admin_version);
856
857 return this->SendAuthRequest();
858}
859
860NetworkRecvStatus ServerNetworkAdminSocketHandler::SendAuthRequest()
861{
863
864 Debug(net, 6, "[admin] '{}' ({}) authenticating using {}", this->admin_name, this->admin_version, this->authentication_handler->GetName());
865
866 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_AUTH_REQUEST);
867 this->authentication_handler->SendRequest(*p);
868
869 this->SendPacket(std::move(p));
870
872}
873
874NetworkRecvStatus ServerNetworkAdminSocketHandler::SendEnableEncryption()
875{
877
878 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_ENABLE_ENCRYPTION);
879 this->authentication_handler->SendEnableEncryption(*p);
880 this->SendPacket(std::move(p));
881
883}
884
886{
888
889 switch (this->authentication_handler->ReceiveResponse(p)) {
891 Debug(net, 3, "[admin] '{}' ({}) authenticated", this->admin_name, this->admin_version);
892
893 this->SendEnableEncryption();
894
895 this->receive_encryption_handler = this->authentication_handler->CreateClientToServerEncryptionHandler();
896 this->send_encryption_handler = this->authentication_handler->CreateServerToClientEncryptionHandler();
897 this->authentication_handler = nullptr;
898 return this->SendProtocol();
899
901 Debug(net, 6, "[admin] '{}' ({}) authentication failed, trying next method", this->admin_name, this->admin_version);
902 return this->SendAuthRequest();
903
905 default:
906 Debug(net, 3, "[admin] '{}' ({}) authentication failed", this->admin_name, this->admin_version);
908 }
909}
910
911/*
912 * Useful wrapper functions
913 */
914
920void NetworkAdminClientInfo(const NetworkClientSocket *cs, bool new_client)
921{
923 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO].Test(AdminUpdateFrequency::Automatic)) {
924 as->SendClientInfo(cs, cs->GetInfo());
925 if (new_client) {
926 as->SendClientJoin(cs->client_id);
927 }
928 }
929 }
930}
931
937{
939 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO].Test(AdminUpdateFrequency::Automatic)) {
940 as->SendClientUpdate(ci);
941 }
942 }
943}
944
950{
952 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO].Test(AdminUpdateFrequency::Automatic)) {
953 as->SendClientQuit(client_id);
954 }
955 }
956}
957
964{
966 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO].Test(AdminUpdateFrequency::Automatic)) {
967 as->SendClientError(client_id, error_code);
968 }
969 }
970}
971
976void NetworkAdminCompanyNew(const Company *company)
977{
978 if (company == nullptr) {
979 Debug(net, 1, "[admin] Empty company given for update");
980 return;
981 }
982
984 if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != AdminUpdateFrequency::Automatic) continue;
985
986 as->SendCompanyNew(company->index);
987 as->SendCompanyInfo(company);
988 }
989}
990
996{
997 if (company == nullptr) return;
998
1000 if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != AdminUpdateFrequency::Automatic) continue;
1001
1002 as->SendCompanyUpdate(company);
1003 }
1004}
1005
1012{
1014 as->SendCompanyRemove(company_id, bcrr);
1015 }
1016}
1017
1018
1028void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, std::string_view msg, int64_t data, bool from_admin)
1029{
1030 if (from_admin) return;
1031
1033 if (as->update_frequency[ADMIN_UPDATE_CHAT].Test(AdminUpdateFrequency::Automatic)) {
1034 as->SendChat(action, desttype, client_id, msg, data);
1035 }
1036 }
1037}
1038
1045void NetworkServerSendAdminRcon(AdminID admin_index, TextColour colour_code, std::string_view string)
1046{
1047 ServerNetworkAdminSocketHandler::Get(admin_index)->SendRcon(colour_code, string);
1048}
1049
1055void NetworkAdminConsole(std::string_view origin, std::string_view string)
1056{
1058 if (as->update_frequency[ADMIN_UPDATE_CONSOLE].Test(AdminUpdateFrequency::Automatic)) {
1059 as->SendConsole(origin, string);
1060 }
1061 }
1062}
1063
1068void NetworkAdminGameScript(std::string_view json)
1069{
1071 if (as->update_frequency[ADMIN_UPDATE_GAMESCRIPT].Test(AdminUpdateFrequency::Automatic)) {
1072 as->SendGameScript(json);
1073 }
1074 }
1075}
1076
1082void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket &cp)
1083{
1084 ClientID client_id = owner == nullptr ? _network_own_client_id : owner->client_id;
1085
1087 if (as->update_frequency[ADMIN_UPDATE_CMD_LOGGING].Test(AdminUpdateFrequency::Automatic)) {
1088 as->SendCmdLogging(client_id, cp);
1089 }
1090 }
1091}
1092
1102
1108{
1110 for (int i = 0; i < ADMIN_UPDATE_END; i++) {
1111 if (as->update_frequency[i].Test(freq)) {
1112 /* Update the admin for the required details */
1113 switch (i) {
1114 case ADMIN_UPDATE_DATE:
1115 as->SendDate();
1116 break;
1117
1119 as->SendCompanyEconomy();
1120 break;
1121
1123 as->SendCompanyStats();
1124 break;
1125
1126 default: NOT_REACHED();
1127 }
1128 }
1129 }
1130 }
1131}
constexpr Timpl & Reset()
Reset all bits.
static void NewEvent(class ScriptEvent *event)
Queue a new event for the game script.
Wrapper for (un)resolved network addresses; there's no reason to transform a numeric IP to a string a...
Definition address.h:28
const std::string & GetHostname()
Get the hostname; in case it wasn't given the IPv4 dotted representation is given.
Definition address.cpp:24
NetworkRecvStatus CloseConnection(bool error=true) override
This will put this socket handler in a close state.
Definition tcp_admin.cpp:24
NetworkAdminSocketHandler(SOCKET s)
Create the admin handler for the given socket.
Definition tcp_admin.h:547
AdminStatus status
Status of this admin.
Definition tcp_admin.h:118
std::string admin_version
Version string of the admin.
Definition tcp_admin.h:117
std::string admin_name
Name of the admin.
Definition tcp_admin.h:116
Default implementation for the authorized key handler.
Default implementation of the password provider.
static std::unique_ptr< NetworkAuthenticationServerHandler > Create(const NetworkAuthenticationPasswordProvider *password_provider, const NetworkAuthenticationAuthorizedKeyHandler *authorized_key_handler, NetworkAuthenticationMethodMask client_supported_method_mask={NetworkAuthenticationMethod::X25519_KeyExchangeOnly, NetworkAuthenticationMethod::X25519_PAKE, NetworkAuthenticationMethod::X25519_AuthorizedKey})
Create a NetworkAuthenticationServerHandler.
@ RetryNextMethod
The client failed to authenticate, but there is another method to try.
@ NotAuthenticated
All authentications for this handler have been exhausted.
@ Authenticated
The client was authenticated successfully.
std::unique_ptr< class NetworkEncryptionHandler > send_encryption_handler
The handler for encrypting sent packets.
Definition core.h:48
std::unique_ptr< class NetworkEncryptionHandler > receive_encryption_handler
The handler for decrypting received packets.
Definition core.h:47
virtual void SendPacket(std::unique_ptr< Packet > &&packet)
This function puts the packet in the send-queue and it is send as soon as possible.
Definition tcp.cpp:57
Class for handling the server side of the game connection.
static void Send()
Send the packets for the server sockets.
NetworkRecvStatus SendGameScript(std::string_view json)
Send GameScript JSON output.
NetworkRecvStatus SendPong(uint32_t d1)
Send ping-reply (pong) to admin.
NetworkRecvStatus SendDate()
Tell the admin the date.
NetworkRecvStatus Receive_ADMIN_JOIN_SECURE(Packet &p) override
Join the admin network using a secure authentication method: string Name of the application being use...
~ServerNetworkAdminSocketHandler() override
Clear everything related to this admin.
NetworkRecvStatus SendClientUpdate(const NetworkClientInfo *ci)
Send an update for some client's information.
NetworkRecvStatus SendClientInfo(const NetworkClientSocket *cs, const NetworkClientInfo *ci)
Send an initial set of data from some client's information.
NetworkRecvStatus SendRconEnd(std::string_view command)
Send a notification indicating the rcon command has completed.
NetworkRecvStatus Receive_ADMIN_UPDATE_FREQUENCY(Packet &p) override
Register updates to be sent at certain frequencies (as announced in the PROTOCOL packet): uint16_t Up...
NetworkRecvStatus SendNewGame()
Tell the admin we started a new game.
NetworkRecvStatus SendCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bcrr)
Tell the admin that a company got removed.
NetworkRecvStatus Receive_ADMIN_RCON(Packet &p) override
Execute a command on the servers console: string Command to be executed.
std::array< AdminUpdateFrequencies, ADMIN_UPDATE_END > update_frequency
Admin requested update intervals.
NetworkRecvStatus SendClientError(ClientID client_id, NetworkErrorCode error)
Tell the admin that a client made an error.
NetworkRecvStatus SendCmdNames()
Send the names of the commands.
NetworkRecvStatus Receive_ADMIN_POLL(Packet &p) override
Poll the server for certain updates, an invalid poll (e.g.
NetworkRecvStatus Receive_ADMIN_JOIN(Packet &p) override
Join the admin network using an unsecured password exchange: string Unsecured password the server is ...
NetworkRecvStatus SendShutdown()
Tell the admin we're shutting down.
NetworkRecvStatus SendCompanyStats()
Send statistics about the companies.
NetworkRecvStatus SendWelcome()
Send a welcome message to the admin.
NetworkRecvStatus SendCompanyInfo(const Company *c)
Send the admin some information about a company.
static void WelcomeAll()
Send a Welcome packet to all connected admins.
static void AcceptConnection(SOCKET s, const NetworkAddress &address)
Handle the acceptance of a connection.
NetworkRecvStatus SendCmdLogging(ClientID client_id, const CommandPacket &cp)
Send a command for logging purposes.
std::unique_ptr< NetworkAuthenticationServerHandler > authentication_handler
The handler for the authentication.
static bool AllowConnection()
Whether a connection is allowed or not at this moment.
NetworkRecvStatus Receive_ADMIN_CHAT(Packet &p) override
Send chat as the server: uint8_t Action such as NETWORK_ACTION_CHAT_CLIENT (see NetworkAction).
static Pool::IterateWrapperFiltered< ServerNetworkAdminSocketHandler, ServerNetworkAdminSocketHandlerFilter > IterateActive(size_t from=0)
Returns an iterable ensemble of all active admin sockets.
NetworkRecvStatus SendRcon(uint16_t colour, std::string_view command)
Send the reply of an rcon command.
NetworkRecvStatus SendConsole(std::string_view origin, std::string_view command)
Send console output of other clients.
NetworkRecvStatus SendCompanyEconomy()
Send economic information of all companies.
NetworkRecvStatus Receive_ADMIN_AUTH_RESPONSE(Packet &p) override
Admin responds to ADMIN_PACKET_SERVER_AUTH_REQUEST with the appropriate data given the agreed upon Ne...
NetworkRecvStatus SendChat(NetworkAction action, DestType desttype, ClientID client_id, std::string_view msg, int64_t data)
Send a chat message.
NetworkRecvStatus SendCompanyUpdate(const Company *c)
Send an update about a company.
NetworkAddress address
Address of the admin.
ServerNetworkAdminSocketHandler(AdminID index, SOCKET s)
Sanity check.
NetworkRecvStatus SendClientQuit(ClientID client_id)
Tell the admin that a client quit.
NetworkRecvStatus SendCompanyNew(CompanyID company_id)
Tell the admin that a new company was founded.
NetworkRecvStatus Receive_ADMIN_GAMESCRIPT(Packet &p) override
Send a JSON string to the current active GameScript.
NetworkRecvStatus SendProtocol()
Send the protocol version to the admin.
NetworkRecvStatus SendClientJoin(ClientID client_id)
Tell the admin that a client joined.
std::chrono::steady_clock::time_point connect_time
Time of connection.
NetworkRecvStatus Receive_ADMIN_PING(Packet &p) override
Ping the server, requiring the server to reply with a pong packet.
NetworkRecvStatus Receive_ADMIN_EXTERNAL_CHAT(Packet &p) override
Send chat from the external source: string Name of the source this message came from.
NetworkRecvStatus Receive_ADMIN_QUIT(Packet &p) override
Notification to the server that this admin is quitting.
NetworkRecvStatus SendError(NetworkErrorCode error)
Send an error to the admin.
static Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
static Date date
Current date in days (day counter).
std::string_view GetCommandName(Commands cmd)
Get the name of the given command.
Definition command.cpp:125
Functions related to commands.
Commands
List of commands.
Definition of stuff that is very close to a company, like the company struct itself.
static const uint NETWORK_GAMESCRIPT_JSON_LENGTH
The maximum length of a receiving gamescript json string, in bytes including '\0'.
Definition config.h:58
static const uint NETWORK_CLIENT_NAME_LENGTH
The maximum length of a client's name, in bytes including '\0'.
Definition config.h:56
static const uint NETWORK_CHAT_LENGTH
The maximum length of a chat message, in bytes including '\0'.
Definition config.h:59
static const size_t COMPAT_MTU
Number of bytes we can pack in a single packet for backward compatibility.
Definition config.h:44
static const uint NETWORK_REVISION_LENGTH
The maximum length of the revision, in bytes including '\0'.
Definition config.h:54
static const uint NETWORK_RCONCOMMAND_LENGTH
The maximum length of a rconsole command, in bytes including '\0'.
Definition config.h:57
static const uint NETWORK_PASSWORD_LENGTH
The maximum length of the password, in bytes including '\0'.
Definition config.h:55
static const uint8_t NETWORK_GAME_ADMIN_VERSION
What version of the admin network do we use?
Definition config.h:46
void IConsoleCmdExec(std::string_view command_string, const uint recurse_count)
Execute a given command passed to us.
Definition console.cpp:271
Console functions used outside of the console code.
bool IsValidConsoleColour(TextColour c)
Check whether the given TextColour is valid for console usage.
NetworkRecvStatus
Status of a network client; reasons why a client has quit.
Definition core.h:21
@ NETWORK_RECV_STATUS_OKAY
Everything is okay.
Definition core.h:22
void DebugReconsiderSendRemoteMessages()
Reconsider whether we need to send debug messages to either NetworkAdminConsole or IConsolePrint.
Definition debug.cpp:261
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp:21
Base functions for all Games.
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition gfx_type.h:307
Functions related to maps.
constexpr uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
StringID GetNetworkErrorMsg(NetworkErrorCode err)
Retrieve a short translateable string of the error code.
Definition network.cpp:312
bool _network_dedicated
are we a dedicated server?
Definition network.cpp:70
ClientID _network_own_client_id
Our client identifier.
Definition network.cpp:72
static NetworkAuthenticationDefaultAuthorizedKeyHandler _admin_authorized_key_handler
Provides the authorized key handling for the game authentication.
void NetworkAdminClientUpdate(const NetworkClientInfo *ci)
Notify the admin network of a client update (if they did opt in for the respective update).
void NetworkAdminClientQuit(ClientID client_id)
Notify the admin network that a client quit (if they have opt in for the respective update).
void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, std::string_view msg, int64_t data, bool from_admin)
Send chat to the admin network (if they did opt in for the respective update).
void NetworkAdminCompanyUpdate(const Company *company)
Notify the admin network of company updates.
static NetworkAuthenticationDefaultPasswordProvider _admin_password_provider
Provides the password validation for the game's password.
void NetworkAdminUpdate(AdminUpdateFrequency freq)
Send (push) updates to the admin network as they have registered for these updates.
void NetworkAdminClientInfo(const NetworkClientSocket *cs, bool new_client)
Notify the admin network of a new client (if they did opt in for the respective update).
static const std::chrono::seconds ADMIN_AUTHORISATION_TIMEOUT
The timeout for authorisation of the client.
void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket &cp)
Distribute CommandPacket details over the admin network for logging purposes.
void NetworkServerSendAdminRcon(AdminID admin_index, TextColour colour_code, std::string_view string)
Pass the rcon reply to the admin.
void NetworkAdminClientError(ClientID client_id, NetworkErrorCode error_code)
Notify the admin network of a client error (if they have opt in for the respective update).
void NetworkAdminConsole(std::string_view origin, std::string_view string)
Send console to the admin network (if they did opt in for the respective update).
void NetworkAdminGameScript(std::string_view json)
Send GameScript JSON to the admin network (if they did opt in for the respective update).
void NetworkAdminCompanyNew(const Company *company)
Notify the admin network of a new company.
static const AdminUpdateFrequencies _admin_update_type_frequencies[]
Frequencies, which may be registered for a certain update type.
NetworkAdminSocketPool _networkadminsocket_pool("NetworkAdminSocket")
The pool with sockets/clients.
void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bcrr)
Notify the admin network of a company to be removed (including the reason why).
AdminID _redirect_console_to_admin
Redirection of the (remote) console to the admin.
Server part of the admin network protocol.
Pool< ServerNetworkAdminSocketHandler, AdminID, 2, PoolType::NetworkAdmin > NetworkAdminSocketPool
Pool with all admin connections.
AdminID _redirect_console_to_admin
Redirection of the (remote) console to the admin.
Base core network types and some helper functions to access them.
EnumBitSet< NetworkAuthenticationMethod, uint16_t > NetworkAuthenticationMethodMask
The mask of authentication methods that can be used.
@ X25519_KeyExchangeOnly
No actual authentication is taking place, just perform a x25519 key exchange. This method is not supp...
void NetworkServerSendExternalChat(std::string_view source, TextColour colour, std::string_view user, std::string_view msg)
Send a chat message from external source.
NetworkCompanyStatsArray NetworkGetCompanyStats()
Get the company stats.
void NetworkServerSendChat(NetworkAction action, DestType type, int dest, std::string_view msg, ClientID from_id, int64_t data=0, bool from_admin=false)
Send an actual chat message.
std::string_view GetNetworkRevisionString()
Get the network version string used by this build.
Convert NetworkGameInfo to Packet and back.
Server part of the network protocol.
DestType
Destination of our chat messages.
PoolID< uint8_t, struct AdminIDTag, 16, 0xFF > AdminID
Indices into the admin tables.
NetworkErrorCode
The error codes we send around in the protocols.
@ NotAuthorized
The client tried to do something there are not authorized to.
@ WrongPassword
The client entered a wrong password.
@ NotExpected
The request/packet was not expected in the current state.
@ IllegalPacket
A packet was received that has invalid content.
@ NoAuthenticationMethodAvailable
The client and server could not find a common authentication method.
NetworkAction
Actions that can be used for NetworkTextMessage.
ClientID
'Unique' identifier to be given to clients
@ CLIENT_ID_SERVER
Servers always have this ID.
Some methods of Pool are placed here in order to reduce compilation time and binary size.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
Declaration of OTTD revision dependent variables.
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:271
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:424
Functions related to OTTD's strings.
Everything we need to know about a command to be able to execute it.
CommandDataBuffer data
command parameters.
uint32_t frame
the frame in which this packet is executed
CompanyID company
company that is executing the command
Commands cmd
command being executed.
uint8_t months_of_bankruptcy
Number of months that the company is unable to pay its debts.
bool is_ai
If true, the company is (also) controlled by the computer (a NoAI program).
TimerGameEconomy::Year inaugurated_year
Economy year of starting the company.
Colours colour
Company colour.
static uint SizeX()
Get the size of the map along the X.
Definition map_func.h:262
static uint SizeY()
Get the size of the map along the Y.
Definition map_func.h:271
Container for all information known about a client.
static NetworkClientInfo * GetByClientID(ClientID client_id)
Return the CI given it's client-identifier.
Definition network.cpp:118
TimerGameEconomy::Date join_date
Gamedate the client has joined.
CompanyID client_playas
As which company is this client playing (CompanyID).
ClientID client_id
Client identifier (same as ClientState->client_id).
std::string client_name
Name of the client.
uint16_t Recv_uint16()
Read a 16 bits integer from the packet.
Definition packet.cpp:330
uint32_t Recv_uint32()
Read a 32 bits integer from the packet.
Definition packet.cpp:345
std::string Recv_string(size_t length, StringValidationSettings settings=StringValidationSetting::ReplaceWithQuestionMark)
Reads characters (bytes) from the packet until it finds a '\0', or reaches a maximum of length charac...
Definition packet.cpp:423
uint8_t Recv_uint8()
Read a 8 bits integer from the packet.
Definition packet.cpp:316
static Pool::IterateWrapper< ServerNetworkAdminSocketHandler > Iterate(size_t from=0)
static Company * GetIfValid(auto index)
@ ADMIN_PACKET_SERVER_CONSOLE
The server gives the admin the data that got printed to its console.
Definition tcp_admin.h:56
@ ADMIN_PACKET_SERVER_ENABLE_ENCRYPTION
The server tells that authentication has completed and requests to enable encryption with the keys of...
Definition tcp_admin.h:64
@ ADMIN_PACKET_SERVER_CLIENT_UPDATE
The server gives the admin an information update on a client.
Definition tcp_admin.h:45
@ ADMIN_PACKET_SERVER_COMPANY_STATS
The server gives the admin some statistics about a company.
Definition tcp_admin.h:53
@ ADMIN_PACKET_SERVER_COMPANY_ECONOMY
The server gives the admin some economy related company information.
Definition tcp_admin.h:52
@ ADMIN_PACKET_SERVER_GAMESCRIPT
The server gives the admin information from the GameScript in JSON.
Definition tcp_admin.h:59
@ ADMIN_PACKET_SERVER_CLIENT_INFO
The server gives the admin information about a client.
Definition tcp_admin.h:44
@ ADMIN_PACKET_SERVER_CLIENT_ERROR
The server tells the admin that a client caused an error.
Definition tcp_admin.h:47
@ ADMIN_PACKET_SERVER_AUTH_REQUEST
The server gives the admin the used authentication method and required parameters.
Definition tcp_admin.h:63
@ ADMIN_PACKET_SERVER_CHAT
The server received a chat message and relays it.
Definition tcp_admin.h:54
@ ADMIN_PACKET_SERVER_SHUTDOWN
The server tells the admin its shutting down.
Definition tcp_admin.h:40
@ ADMIN_PACKET_SERVER_RCON_END
The server indicates that the remote console command has completed.
Definition tcp_admin.h:60
@ ADMIN_PACKET_SERVER_WELCOME
The server welcomes the admin to a game.
Definition tcp_admin.h:38
@ ADMIN_PACKET_SERVER_COMPANY_REMOVE
The server tells the admin that a company was removed.
Definition tcp_admin.h:51
@ ADMIN_PACKET_SERVER_ERROR
The server tells the admin an error has occurred.
Definition tcp_admin.h:36
@ ADMIN_PACKET_SERVER_NEWGAME
The server tells the admin its going to start a new game.
Definition tcp_admin.h:39
@ ADMIN_PACKET_SERVER_COMPANY_UPDATE
The server gives the admin an information update on a company.
Definition tcp_admin.h:50
@ ADMIN_PACKET_SERVER_PONG
The server replies to a ping request from the admin.
Definition tcp_admin.h:61
@ ADMIN_PACKET_SERVER_CLIENT_JOIN
The server tells the admin that a client has joined.
Definition tcp_admin.h:43
@ ADMIN_PACKET_SERVER_CMD_LOGGING
The server gives the admin copies of incoming command packets.
Definition tcp_admin.h:62
@ ADMIN_PACKET_SERVER_PROTOCOL
The server tells the admin its protocol version.
Definition tcp_admin.h:37
@ ADMIN_PACKET_SERVER_CLIENT_QUIT
The server tells the admin that a client quit.
Definition tcp_admin.h:46
@ ADMIN_PACKET_SERVER_COMPANY_INFO
The server gives the admin information about a company.
Definition tcp_admin.h:49
@ ADMIN_PACKET_SERVER_CMD_NAMES
The server sends out the names of the DoCommands to the admins.
Definition tcp_admin.h:57
@ ADMIN_PACKET_SERVER_DATE
The server tells the admin what the current game date is.
Definition tcp_admin.h:42
@ ADMIN_PACKET_SERVER_COMPANY_NEW
The server tells the admin that a new company has started.
Definition tcp_admin.h:48
@ ADMIN_PACKET_SERVER_RCON
The server's reply to a remove console command.
Definition tcp_admin.h:55
AdminUpdateType
Update types an admin can register a frequency for.
Definition tcp_admin.h:78
@ ADMIN_UPDATE_DATE
Updates about the date of the game.
Definition tcp_admin.h:79
@ ADMIN_UPDATE_GAMESCRIPT
The admin would like to have gamescript messages.
Definition tcp_admin.h:88
@ ADMIN_UPDATE_COMPANY_INFO
Updates about the generic information of companies.
Definition tcp_admin.h:81
@ ADMIN_UPDATE_CONSOLE
The admin would like to have console messages.
Definition tcp_admin.h:85
@ ADMIN_UPDATE_CHAT
The admin would like to have chat messages.
Definition tcp_admin.h:84
@ ADMIN_UPDATE_COMPANY_STATS
Updates about the statistics of companies.
Definition tcp_admin.h:83
@ ADMIN_UPDATE_COMPANY_ECONOMY
Updates about the economy of companies.
Definition tcp_admin.h:82
@ ADMIN_UPDATE_END
Must ALWAYS be on the end of this list!! (period).
Definition tcp_admin.h:89
@ ADMIN_UPDATE_CLIENT_INFO
Updates about the information of clients.
Definition tcp_admin.h:80
@ ADMIN_UPDATE_CMD_NAMES
The admin would like a list of all DoCommand names.
Definition tcp_admin.h:86
@ ADMIN_UPDATE_CMD_LOGGING
The admin would like to have DoCommand information.
Definition tcp_admin.h:87
EnumBitSet< AdminUpdateFrequency, uint8_t > AdminUpdateFrequencies
Bitset of chosen update frequencies.
Definition tcp_admin.h:102
AdminCompanyRemoveReason
Reasons for removing a company - communicated to admins.
Definition tcp_admin.h:105
AdminUpdateFrequency
Update frequencies an admin can register.
Definition tcp_admin.h:93
@ Automatic
The admin gets information about this when it changes.
Definition tcp_admin.h:100
@ Annually
The admin gets information about this on a yearly basis.
Definition tcp_admin.h:99
@ Weekly
The admin gets information about this on a weekly basis.
Definition tcp_admin.h:96
@ Poll
The admin can poll this.
Definition tcp_admin.h:94
@ Monthly
The admin gets information about this on a monthly basis.
Definition tcp_admin.h:97
@ Quarterly
The admin gets information about this on a quarterly basis.
Definition tcp_admin.h:98
@ Daily
The admin gets information about this on a daily basis.
Definition tcp_admin.h:95
@ ADMIN_STATUS_INACTIVE
The admin is not connected nor active.
Definition tcp_admin.h:71
@ ADMIN_STATUS_ACTIVE
The admin is active.
Definition tcp_admin.h:73
@ ADMIN_STATUS_AUTHENTICATE
The admin is connected and working on authentication.
Definition tcp_admin.h:72
Definition of the game-calendar-timer.