OpenTTD Source 20260711-master-g3fb3006dff
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
12#include "../strings_func.h"
16#include "network_admin.h"
17#include "network_base.h"
18#include "network_server.h"
19#include "../command_func.h"
20#include "../company_base.h"
21#include "../console_func.h"
22#include "../core/pool_func.hpp"
23#include "../map_func.h"
24#include "../rev.h"
25#include "../game/game.hpp"
26
27#include "table/strings.h"
28
29#include "../safeguards.h"
30
31
32/* This file handles all the admin network commands. */
33
36
39INSTANTIATE_POOL_METHODS(NetworkAdminSocket)
40
43
45static const std::chrono::seconds ADMIN_AUTHORISATION_TIMEOUT{10};
46
47
61
73
87
93{
94 return _settings_client.network.AdminAuthenticationConfigured() && ServerNetworkAdminSocketHandler::CanAllocateItem();
95}
96
99{
101 if (as->status <= AdminStatus::Authenticate && std::chrono::steady_clock::now() > as->connect_time + ADMIN_AUTHORISATION_TIMEOUT) {
102 Debug(net, 2, "[admin] Admin did not send its authorisation within {} seconds", std::chrono::duration_cast<std::chrono::seconds>(ADMIN_AUTHORISATION_TIMEOUT).count());
103 as->CloseConnection(true);
104 continue;
105 }
106 if (as->writable) {
107 as->SendPackets();
108 }
109 }
110}
111
118{
120 as->address = address; // Save the IP of the client
121}
122
123/***********
124 * Sending functions for admin network
125 ************/
126
133{
134 /* Whatever the error might be, authentication (keys) must be released as soon as possible. */
135 this->authentication_handler = nullptr;
136
137 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerError);
138
139 p->Send_uint8(to_underlying(error));
140 this->SendPacket(std::move(p));
141
142 std::string error_message = GetString(GetNetworkErrorMsg(error));
143
144 Debug(net, 1, "[admin] The admin '{}' ({}) made an error and has been disconnected: '{}'", this->admin_name, this->admin_version, error_message);
145
146 return this->CloseConnection(true);
147}
148
154{
156
157 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerProtocol);
158
159 /* announce the protocol version */
160 p->Send_uint8(NETWORK_GAME_ADMIN_VERSION);
161
163 p->Send_bool (true);
164 p->Send_uint16(to_underlying(i));
165 p->Send_uint16(_admin_update_type_frequencies[i].base());
166 }
167
168 p->Send_bool(false);
169 this->SendPacket(std::move(p));
170
171 return this->SendWelcome();
172}
173
179{
180 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerWelcome);
181
182 p->Send_string(_settings_client.network.server_name);
183 p->Send_string(GetNetworkRevisionString());
184 p->Send_bool (_network_dedicated);
185
186 p->Send_string(""); // Used to be map-name.
187 p->Send_uint32(_settings_game.game_creation.generation_seed);
188 p->Send_uint8 (to_underlying(_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());
192
193 this->SendPacket(std::move(p));
194
196}
197
203{
204 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerNewGame);
205 this->SendPacket(std::move(p));
207}
208
214{
215 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerShutdown);
216 this->SendPacket(std::move(p));
218}
219
225{
226 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerDate);
227
228 p->Send_uint32(TimerGameCalendar::date.base());
229 this->SendPacket(std::move(p));
230
232}
233
240{
241 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerClientJoin);
242
243 p->Send_uint32(to_underlying(client_id));
244 this->SendPacket(std::move(p));
245
247}
248
256{
257 /* Only send data when we're a proper client, not just someone trying to query the server. */
258 if (ci == nullptr) return NetworkRecvStatus::Okay;
259
260 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerClientInfo);
261
262 p->Send_uint32(to_underlying(ci->client_id));
263 p->Send_string(cs == nullptr ? "" : const_cast<NetworkAddress &>(cs->client_address).GetHostname());
264 p->Send_string(ci->client_name);
265 p->Send_uint8 (0); // Used to be language
266 p->Send_uint32(ci->join_date.base());
267 p->Send_uint8 (ci->client_playas);
268
269 this->SendPacket(std::move(p));
270
272}
273
274
281{
282 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerClientUpdate);
283
284 p->Send_uint32(to_underlying(ci->client_id));
285 p->Send_string(ci->client_name);
286 p->Send_uint8 (ci->client_playas);
287
288 this->SendPacket(std::move(p));
289
291}
292
299{
300 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerClientQuit);
301
302 p->Send_uint32(to_underlying(client_id));
303 this->SendPacket(std::move(p));
304
306}
307
315{
316 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerClientError);
317
318 p->Send_uint32(to_underlying(client_id));
319 p->Send_uint8(to_underlying(error));
320 this->SendPacket(std::move(p));
321
323}
324
331{
332 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerCompanyNew);
333 p->Send_uint8(company_id);
334
335 this->SendPacket(std::move(p));
336
338}
339
346{
347 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerCompanyInfo);
348
349 p->Send_uint8 (c->index);
350 p->Send_string(GetString(STR_COMPANY_NAME, c->index));
351 p->Send_string(GetString(STR_PRESIDENT_NAME, c->index));
352 p->Send_uint8(to_underlying(c->colour));
353 p->Send_bool (true);
354 p->Send_uint32(c->inaugurated_year.base());
355 p->Send_bool (c->is_ai);
356 p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy
357
358 this->SendPacket(std::move(p));
359
361}
362
363
370{
371 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerCompanyUpdate);
372
373 p->Send_uint8 (c->index);
374 p->Send_string(GetString(STR_COMPANY_NAME, c->index));
375 p->Send_string(GetString(STR_PRESIDENT_NAME, c->index));
376 p->Send_uint8(to_underlying(c->colour));
377 p->Send_bool (true);
378 p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy
379
380 this->SendPacket(std::move(p));
381
383}
384
392{
393 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerCompanyRemove);
394
395 p->Send_uint8(company_id);
396 p->Send_uint8(to_underlying(acrr));
397
398 this->SendPacket(std::move(p));
399
401}
402
408{
409 for (const Company *company : Company::Iterate()) {
410 /* Get the income. */
411 Money income = -std::reduce(std::begin(company->yearly_expenses[0]), std::end(company->yearly_expenses[0]));
412
413 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerCompanyEconomy);
414
415 p->Send_uint8(company->index);
416
417 /* Current information. */
418 p->Send_uint64(company->money);
419 p->Send_uint64(company->current_loan);
420 p->Send_uint64(income);
421 p->Send_uint16(static_cast<uint16_t>(std::min<uint64_t>(UINT16_MAX, company->cur_economy.delivered_cargo.GetSum<OverflowSafeInt64>())));
422
423 /* Send stats for the last 2 quarters. */
424 for (uint i = 0; i < 2; i++) {
425 p->Send_uint64(company->old_economy[i].company_value);
426 p->Send_uint16(company->old_economy[i].performance_history);
427 p->Send_uint16(static_cast<uint16_t>(std::min<uint64_t>(UINT16_MAX, company->old_economy[i].delivered_cargo.GetSum<OverflowSafeInt64>())));
428 }
429
430 this->SendPacket(std::move(p));
431 }
432
433
435}
436
442{
443 /* Fetch the latest version of the stats. */
445
446 /* Go through all the companies. */
447 for (const Company *company : Company::Iterate()) {
448 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerCompanyStatistics);
449
450 /* Send the information. */
451 p->Send_uint8(company->index);
452 for (uint16_t value : company_stats[company->index].num_vehicle) p->Send_uint16(value);
453 for (uint16_t value : company_stats[company->index].num_station) p->Send_uint16(value);
454
455 this->SendPacket(std::move(p));
456 }
457
459}
460
471{
472 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerChat);
473
474 p->Send_uint8(to_underlying(action));
475 p->Send_uint8(to_underlying(desttype));
476 p->Send_uint32(to_underlying(client_id));
477 p->Send_string(msg);
478 p->Send_uint64(data);
479
480 this->SendPacket(std::move(p));
482}
483
490{
491 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerRemoteConsoleCommandEnd);
492
493 p->Send_string(command);
494 this->SendPacket(std::move(p));
495
497}
498
505NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRcon(uint16_t colour, std::string_view result)
506{
507 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerRemoteConsoleCommand);
508
509 p->Send_uint16(colour);
510 p->Send_string(result);
511 this->SendPacket(std::move(p));
512
514}
515
517{
519
520 std::string command = p.Recv_string(NETWORK_RCONCOMMAND_LENGTH);
521
522 Debug(net, 3, "[admin] Rcon command from '{}' ({}): {}", this->admin_name, this->admin_version, command);
523
525 IConsoleCmdExec(command);
526 _redirect_console_to_admin = AdminID::Invalid();
527 return this->SendRconEnd(command);
528}
529
531{
533
534 std::string json = p.Recv_string(NETWORK_GAMESCRIPT_JSON_LENGTH);
535
536 Debug(net, 6, "[admin] GameScript JSON from '{}' ({}): {}", this->admin_name, this->admin_version, json);
537
538 Game::NewEvent(new ScriptEventAdminPort(json));
540}
541
543{
545
546 uint32_t d1 = p.Recv_uint32();
547
548 Debug(net, 6, "[admin] Ping from '{}' ({}): {}", this->admin_name, this->admin_version, d1);
549
550 return this->SendPong(d1);
551}
552
559NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(std::string_view origin, std::string_view string)
560{
561 /* If the length of both strings, plus the 2 '\0' terminations and 3 bytes of the packet
562 * are bigger than the MTU, just ignore the message. Better safe than sorry. It should
563 * never occur though as the longest strings are chat messages, which are still 30%
564 * smaller than COMPAT_MTU. */
565 if (origin.size() + string.size() + 2 + 3 >= COMPAT_MTU) return NetworkRecvStatus::Okay;
566
567 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerConsole);
568
569 p->Send_string(origin);
570 p->Send_string(string);
571 this->SendPacket(std::move(p));
572
574}
575
582{
583 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerGameScript);
584
585 p->Send_string(json);
586 this->SendPacket(std::move(p));
587
589}
590
597{
598 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerPong);
599
600 p->Send_uint32(d1);
601 this->SendPacket(std::move(p));
602
604}
605
611{
612 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerCommandNames);
613
614 for (uint16_t i = 0; i < to_underlying(Commands::End); i++) {
615 std::string_view cmdname = GetCommandName(static_cast<Commands>(i));
616
617 /* Should COMPAT_MTU be exceeded, start a new packet
618 * (magic 5: 1 bool "more data" and one uint16_t "command id", one
619 * byte for string '\0' termination and 1 bool "no more data" */
620 if (!p->CanWriteToPacket(cmdname.size() + 5)) {
621 p->Send_bool(false);
622 this->SendPacket(std::move(p));
623
624 p = std::make_unique<Packet>(this, PacketAdminType::ServerCommandNames);
625 }
626
627 p->Send_bool(true);
628 p->Send_uint16(i);
629 p->Send_string(cmdname);
630 }
631
632 /* Marker to notify the end of the packet has been reached. */
633 p->Send_bool(false);
634 this->SendPacket(std::move(p));
635
637}
638
646{
647 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerCommandLogging);
648
649 p->Send_uint32(to_underlying(client_id));
650 p->Send_uint8 (cp.company);
651 p->Send_uint16(to_underlying(cp.cmd));
652 p->Send_buffer(cp.data);
653 p->Send_uint32(cp.frame);
654
655 this->SendPacket(std::move(p));
656
658}
659
660/***********
661 * Receiving functions
662 ************/
663
665{
667
668 if (!_settings_client.network.allow_insecure_admin_login) {
669 /* You're not authorized to login using this method. */
671 }
672
673 std::string password = p.Recv_string(NETWORK_PASSWORD_LENGTH);
674
675 if (_settings_client.network.admin_password.empty() || _settings_client.network.admin_password != password) {
676 /* Password is invalid */
678 }
679
682
683 if (this->admin_name.empty() || this->admin_version.empty()) {
684 /* no name or version supplied */
686 }
687
688 Debug(net, 3, "[admin] '{}' ({}) has connected", this->admin_name, this->admin_version);
689
690 return this->SendProtocol();
691}
692
694{
695 /* The admin is leaving nothing else to do */
696 return this->CloseConnection();
697}
698
700{
702
703 AdminUpdateType type = static_cast<AdminUpdateType>(p.Recv_uint16());
705
706 if (type >= AdminUpdateType::End || !_admin_update_type_frequencies[type].All(freq)) {
707 /* The server does not know of this UpdateType. */
708 Debug(net, 1, "[admin] Not supported update frequency {} ({}) from '{}' ({})", type, freq, this->admin_name, this->admin_version);
710 }
711
712 this->update_frequency[type] = freq;
713
715
717}
718
720{
722
723 AdminUpdateType type = static_cast<AdminUpdateType>(p.Recv_uint8());
724 uint32_t d1 = p.Recv_uint32();
725
726 switch (type) {
728 /* The admin is requesting the current date. */
729 this->SendDate();
730 break;
731
733 /* The admin is requesting client info. */
734 if (d1 == UINT32_MAX) {
736 for (const NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
737 this->SendClientInfo(cs, cs->GetInfo());
738 }
739 } else {
740 ClientID client{d1};
741 if (client == ClientID::Server) {
743 } else {
744 const NetworkClientSocket *cs = NetworkClientSocket::GetByClientID(client);
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
790 NetworkAction action = static_cast<NetworkAction>(p.Recv_uint8());
792 int dest = p.Recv_uint32();
793
794 std::string msg = p.Recv_string(NETWORK_CHAT_LENGTH);
795
796 switch (action) {
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);
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 '{}' ({}).", colour.ToNetwork(), 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
865{
867
868 Debug(net, 6, "[admin] '{}' ({}) authenticating using {}", this->admin_name, this->admin_version, this->authentication_handler->GetName());
869
870 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerAuthenticationRequest);
871 this->authentication_handler->SendRequest(*p);
872
873 this->SendPacket(std::move(p));
874
876}
877
883{
885
886 auto p = std::make_unique<Packet>(this, PacketAdminType::ServerEnableEncryption);
887 this->authentication_handler->SendEnableEncryption(*p);
888 this->SendPacket(std::move(p));
889
891}
892
894{
896
897 switch (this->authentication_handler->ReceiveResponse(p)) {
899 Debug(net, 3, "[admin] '{}' ({}) authenticated", this->admin_name, this->admin_version);
900
901 this->SendEnableEncryption();
902
903 this->receive_encryption_handler = this->authentication_handler->CreateClientToServerEncryptionHandler();
904 this->send_encryption_handler = this->authentication_handler->CreateServerToClientEncryptionHandler();
905 this->authentication_handler = nullptr;
906 return this->SendProtocol();
907
909 Debug(net, 6, "[admin] '{}' ({}) authentication failed, trying next method", this->admin_name, this->admin_version);
910 return this->SendAuthRequest();
911
913 default:
914 Debug(net, 3, "[admin] '{}' ({}) authentication failed", this->admin_name, this->admin_version);
916 }
917}
918
919/*
920 * Useful wrapper functions
921 */
922
928void NetworkAdminClientInfo(const NetworkClientSocket *cs, bool new_client)
929{
931 if (as->update_frequency[AdminUpdateType::ClientInfo].Test(AdminUpdateFrequency::Automatic)) {
932 as->SendClientInfo(cs, cs->GetInfo());
933 if (new_client) {
934 as->SendClientJoin(cs->client_id);
935 }
936 }
937 }
938}
939
945{
947 if (as->update_frequency[AdminUpdateType::ClientInfo].Test(AdminUpdateFrequency::Automatic)) {
948 as->SendClientUpdate(ci);
949 }
950 }
951}
952
958{
960 if (as->update_frequency[AdminUpdateType::ClientInfo].Test(AdminUpdateFrequency::Automatic)) {
961 as->SendClientQuit(client_id);
962 }
963 }
964}
965
972{
974 if (as->update_frequency[AdminUpdateType::ClientInfo].Test(AdminUpdateFrequency::Automatic)) {
975 as->SendClientError(client_id, error_code);
976 }
977 }
978}
979
984void NetworkAdminCompanyNew(const Company *company)
985{
986 if (company == nullptr) {
987 Debug(net, 1, "[admin] Empty company given for update");
988 return;
989 }
990
992 if (as->update_frequency[AdminUpdateType::CompanyInfo] != AdminUpdateFrequency::Automatic) continue;
993
994 as->SendCompanyNew(company->index);
995 as->SendCompanyInfo(company);
996 }
997}
998
1004{
1005 if (company == nullptr) return;
1006
1008 if (as->update_frequency[AdminUpdateType::CompanyInfo] != AdminUpdateFrequency::Automatic) continue;
1009
1010 as->SendCompanyUpdate(company);
1011 }
1012}
1013
1020{
1022 as->SendCompanyRemove(company_id, bcrr);
1023 }
1024}
1025
1026
1036void NetworkAdminChat(NetworkAction action, NetworkChatDestinationType desttype, ClientID client_id, std::string_view msg, int64_t data, bool from_admin)
1037{
1038 if (from_admin) return;
1039
1041 if (as->update_frequency[AdminUpdateType::Chat].Test(AdminUpdateFrequency::Automatic)) {
1042 as->SendChat(action, desttype, client_id, msg, data);
1043 }
1044 }
1045}
1046
1053void NetworkServerSendAdminRcon(AdminID admin_index, ExtendedTextColour colour_code, std::string_view string)
1054{
1055 ServerNetworkAdminSocketHandler::Get(admin_index)->SendRcon(colour_code.ToNetwork(), string);
1056}
1057
1063void NetworkAdminConsole(std::string_view origin, std::string_view string)
1064{
1066 if (as->update_frequency[AdminUpdateType::Console].Test(AdminUpdateFrequency::Automatic)) {
1067 as->SendConsole(origin, string);
1068 }
1069 }
1070}
1071
1076void NetworkAdminGameScript(std::string_view json)
1077{
1079 if (as->update_frequency[AdminUpdateType::Gamescript].Test(AdminUpdateFrequency::Automatic)) {
1080 as->SendGameScript(json);
1081 }
1082 }
1083}
1084
1091{
1092 ClientID client_id = owner == nullptr ? _network_own_client_id : owner->client_id;
1093
1095 if (as->update_frequency[AdminUpdateType::CmdLogging].Test(AdminUpdateFrequency::Automatic)) {
1096 as->SendCmdLogging(client_id, cp);
1097 }
1098 }
1099}
1100
1110
1116{
1119 if (as->update_frequency[i].Test(freq)) {
1120 /* Update the admin for the required details */
1121 switch (i) {
1123 as->SendDate();
1124 break;
1125
1127 as->SendCompanyEconomy();
1128 break;
1129
1131 as->SendCompanyStats();
1132 break;
1133
1134 default: NOT_REACHED();
1135 }
1136 }
1137 }
1138 }
1139}
constexpr Timpl & Reset()
Reset all bits.
Iterate a range of enum values.
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:549
AdminStatus status
Status of this admin.
Definition tcp_admin.h:120
std::string admin_version
Version string of the admin.
Definition tcp_admin.h:119
std::string admin_name
Name of the admin.
Definition tcp_admin.h:118
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.
~ServerNetworkAdminSocketHandler() override
Clear everything related to this admin.
NetworkRecvStatus SendChat(NetworkAction action, NetworkChatDestinationType desttype, ClientID client_id, std::string_view msg, int64_t data)
Send a chat message.
NetworkRecvStatus SendClientUpdate(const NetworkClientInfo *ci)
Send an update for some client's information.
NetworkRecvStatus ReceiveAdminAuthenticationResponse(Packet &p) override
Admin responds to PacketAdminType::ServerAuthenticationRequest with the appropriate data given the ag...
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 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 ReceiveAdminGameScript(Packet &p) override
Send a JSON string to the current active GameScript.
NetworkRecvStatus SendClientError(ClientID client_id, NetworkErrorCode error)
Tell the admin that a client made an error.
NetworkRecvStatus ReceiveAdminQuit(Packet &p) override
Notification to the server that this admin is quitting.
NetworkRecvStatus SendCmdNames()
Send the names of the commands.
NetworkRecvStatus ReceiveAdminExternalChat(Packet &p) override
Send chat from the external source: string Name of the source this message came from.
NetworkRecvStatus ReceiveAdminPoll(Packet &p) override
Poll the server for certain updates, an invalid poll (e.g.
NetworkRecvStatus SendShutdown()
Tell the admin we're shutting down.
NetworkRecvStatus SendCompanyStats()
Send statistics about the companies.
NetworkRecvStatus ReceiveAdminUpdateFrequency(Packet &p) override
Register updates to be sent at certain frequencies (as announced in the PROTOCOL packet): uint16_t Up...
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.
NetworkRecvStatus SendEnableEncryption()
Send the client the message to enable encryption.
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 ReceiveAdminJoinSecure(Packet &p) override
Join the admin network using a secure authentication method: string Name of the application being use...
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 ReceiveAdminJoin(Packet &p) override
Join the admin network using an unsecured password exchange: string Unsecured password the server is ...
NetworkRecvStatus SendCompanyEconomy()
Send economic information of all companies.
NetworkRecvStatus SendCompanyUpdate(const Company *c)
Send an update about a company.
NetworkRecvStatus ReceiveAdminRemoteConsoleCommand(Packet &p) override
Execute a command on the servers console: string Command to be executed.
NetworkRecvStatus SendAuthRequest()
Send the client a request to authenticate.
NetworkAddress address
Address of the admin.
ServerNetworkAdminSocketHandler(AdminID index, SOCKET s)
Create a new socket for the server side of the admin network.
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 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 ReceiveAdminChat(Packet &p) override
Send chat as the server: uint8_t Action such as NetworkAction::ChatClient (see NetworkAction).
NetworkRecvStatus ReceiveAdminPing(Packet &p) override
Ping the server, requiring the server to reply with a pong packet.
EnumIndexArray< AdminUpdateFrequencies, AdminUpdateType, AdminUpdateType::End > update_frequency
Admin requested update intervals.
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(ExtendedTextColour 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
@ 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
EnumClassIndexContainer< std::array< T, to_underlying(N)>, Index > EnumIndexArray
A typedef for EnumClassIndexContainer using std::array as the backing container type.
Base functions for all Games.
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:328
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 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 NetworkAdminChat(NetworkAction action, NetworkChatDestinationType 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 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.
void NetworkServerSendAdminRcon(AdminID admin_index, ExtendedTextColour colour_code, std::string_view string)
Pass the rcon reply to the admin.
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).
static const EnumIndexArray< AdminUpdateFrequencies, AdminUpdateType, AdminUpdateType::End > _admin_update_type_frequencies
Frequencies, which may be registered for a certain update type.
AdminID _redirect_console_to_admin
Redirection of the (remote) console to the admin.
Server part of the admin network protocol.
NetworkAdminSocketPool _networkadminsocket_pool
Pool with all admin connections.
Pool< ServerNetworkAdminSocketHandler, AdminID, 2, PoolType::NetworkAdmin > NetworkAdminSocketPool
Pool type for 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...
NetworkCompanyStatsArray NetworkGetCompanyStats()
Get the company stats.
void NetworkServerSendExternalChat(std::string_view source, ExtendedTextColour colour, std::string_view user, std::string_view msg)
Send a chat message from external source.
void NetworkServerSendChat(NetworkAction action, NetworkChatDestinationType type, int dest, std::string_view msg, ClientID from_id, int64_t data=0, bool from_admin=false)
Send an actual chat message.
TypedIndexContainer< std::array< NetworkCompanyStats, MAX_COMPANIES >, CompanyID > NetworkCompanyStatsArray
Container with statistics for all possible companies.
std::string_view GetNetworkRevisionString()
Get the network version string used by this build.
Convert NetworkGameInfo to Packet and back.
class ServerNetworkGameSocketHandler NetworkClientSocket
Class for handling the server side of the game connection.
Server part of the network protocol.
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.
@ ServerMessage
The server sent a message.
@ ChatTeam
A chat sent to all clients of a team/company.
@ ChatClient
A chat sent to a specific client.
@ ChatBroadcast
A chat broadcast to all clients.
NetworkChatDestinationType
Destination of our chat messages.
ClientID
'Unique' identifier to be given to clients
@ Server
Servers always have this ID.
@ All
Match if all bits are triggered.
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.
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.
Container for the text colour and some text colour related flags for drawing.
Definition gfx_type.h:349
constexpr uint16_t ToNetwork() const
Encode this text colour for sending over the network.
Definition gfx_type.h:383
static constexpr ExtendedTextColour FromNetwork(uint16_t tc)
Decode the network encoded text colour.
Definition gfx_type.h:377
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)
@ ServerCompanyNew
The server tells the admin that a new company has started.
Definition tcp_admin.h:49
@ ServerDate
The server tells the admin what the current game date is.
Definition tcp_admin.h:43
@ ServerAuthenticationRequest
The server gives the admin the used authentication method and required parameters.
Definition tcp_admin.h:64
@ ServerClientInfo
The server gives the admin information about a client.
Definition tcp_admin.h:45
@ ServerShutdown
The server tells the admin its shutting down.
Definition tcp_admin.h:41
@ ServerCompanyRemove
The server tells the admin that a company was removed.
Definition tcp_admin.h:52
@ ServerCommandNames
The server sends out the names of the DoCommands to the admins.
Definition tcp_admin.h:58
@ ServerCompanyEconomy
The server gives the admin some economy related company information.
Definition tcp_admin.h:53
@ ServerClientQuit
The server tells the admin that a client quit.
Definition tcp_admin.h:47
@ ServerPong
The server replies to a ping request from the admin.
Definition tcp_admin.h:62
@ ServerClientJoin
The server tells the admin that a client has joined.
Definition tcp_admin.h:44
@ ServerClientError
The server tells the admin that a client caused an error.
Definition tcp_admin.h:48
@ ServerCompanyInfo
The server gives the admin information about a company.
Definition tcp_admin.h:50
@ ServerError
The server tells the admin an error has occurred.
Definition tcp_admin.h:37
@ ServerGameScript
The server gives the admin information from the GameScript in JSON.
Definition tcp_admin.h:60
@ ServerConsole
The server gives the admin the data that got printed to its console.
Definition tcp_admin.h:57
@ ServerCommandLogging
The server gives the admin copies of incoming command packets.
Definition tcp_admin.h:63
@ ServerClientUpdate
The server gives the admin an information update on a client.
Definition tcp_admin.h:46
@ ServerCompanyStatistics
The server gives the admin some statistics about a company.
Definition tcp_admin.h:54
@ ServerRemoteConsoleCommandEnd
The server indicates that the remote console command has completed.
Definition tcp_admin.h:61
@ ServerRemoteConsoleCommand
The server's reply to a remote console command.
Definition tcp_admin.h:56
@ ServerWelcome
The server welcomes the admin to a game.
Definition tcp_admin.h:39
@ ServerCompanyUpdate
The server gives the admin an information update on a company.
Definition tcp_admin.h:51
@ ServerChat
The server received a chat message and relays it.
Definition tcp_admin.h:55
@ ServerProtocol
The server tells the admin its protocol version.
Definition tcp_admin.h:38
@ ServerEnableEncryption
The server tells that authentication has completed and requests to enable encryption with the keys of...
Definition tcp_admin.h:65
@ ServerNewGame
The server tells the admin its going to start a new game.
Definition tcp_admin.h:40
AdminUpdateType
Update types an admin can register a frequency for.
Definition tcp_admin.h:80
@ Gamescript
The admin would like to have gamescript messages.
Definition tcp_admin.h:90
@ CompanyInfo
Updates about the generic information of companies.
Definition tcp_admin.h:83
@ CompanyEconomy
Updates about the economy of companies.
Definition tcp_admin.h:84
@ Date
Updates about the date of the game.
Definition tcp_admin.h:81
@ Chat
The admin would like to have chat messages.
Definition tcp_admin.h:86
@ CmdLogging
The admin would like to have DoCommand information.
Definition tcp_admin.h:89
@ CmdNames
The admin would like a list of all DoCommand names.
Definition tcp_admin.h:88
@ End
Must ALWAYS be on the end of this list!! (period).
Definition tcp_admin.h:91
@ CompanyStats
Updates about the statistics of companies.
Definition tcp_admin.h:85
@ Console
The admin would like to have console messages.
Definition tcp_admin.h:87
@ ClientInfo
Updates about the information of clients.
Definition tcp_admin.h:82
EnumBitSet< AdminUpdateFrequency, uint8_t > AdminUpdateFrequencies
Bitset of chosen update frequencies.
Definition tcp_admin.h:104
AdminCompanyRemoveReason
Reasons for removing a company - communicated to admins.
Definition tcp_admin.h:107
AdminUpdateFrequency
Update frequencies an admin can register.
Definition tcp_admin.h:95
@ Automatic
The admin gets information about this when it changes.
Definition tcp_admin.h:102
@ Annually
The admin gets information about this on a yearly basis.
Definition tcp_admin.h:101
@ Weekly
The admin gets information about this on a weekly basis.
Definition tcp_admin.h:98
@ Poll
The admin can poll this.
Definition tcp_admin.h:96
@ Monthly
The admin gets information about this on a monthly basis.
Definition tcp_admin.h:99
@ Quarterly
The admin gets information about this on a quarterly basis.
Definition tcp_admin.h:100
@ Daily
The admin gets information about this on a daily basis.
Definition tcp_admin.h:97
@ Inactive
The admin is not connected nor active.
Definition tcp_admin.h:74
@ Active
The admin is active.
Definition tcp_admin.h:76
@ Authenticate
The admin is connected and working on authentication.
Definition tcp_admin.h:75
Definition of the game-calendar-timer.