OpenTTD Source 20260218-master-g2123fca5ea
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(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 (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
454 for (uint i = 0; i < NETWORK_VEH_END; i++) {
455 p->Send_uint16(company_stats[company->index].num_vehicle[i]);
456 }
457
458 for (uint i = 0; i < NETWORK_VEH_END; i++) {
459 p->Send_uint16(company_stats[company->index].num_station[i]);
460 }
461
462 this->SendPacket(std::move(p));
463 }
464
466}
467
477NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action, DestType desttype, ClientID client_id, std::string_view msg, int64_t data)
478{
479 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CHAT);
480
481 p->Send_uint8 (action);
482 p->Send_uint8 (desttype);
483 p->Send_uint32(client_id);
484 p->Send_string(msg);
485 p->Send_uint64(data);
486
487 this->SendPacket(std::move(p));
489}
490
497{
498 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_RCON_END);
499
500 p->Send_string(command);
501 this->SendPacket(std::move(p));
502
504}
505
512NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRcon(uint16_t colour, std::string_view result)
513{
514 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_RCON);
515
516 p->Send_uint16(colour);
517 p->Send_string(result);
518 this->SendPacket(std::move(p));
519
521}
522
524{
525 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
526
527 std::string command = p.Recv_string(NETWORK_RCONCOMMAND_LENGTH);
528
529 Debug(net, 3, "[admin] Rcon command from '{}' ({}): {}", this->admin_name, this->admin_version, command);
530
532 IConsoleCmdExec(command);
533 _redirect_console_to_admin = AdminID::Invalid();
534 return this->SendRconEnd(command);
535}
536
538{
539 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
540
541 std::string json = p.Recv_string(NETWORK_GAMESCRIPT_JSON_LENGTH);
542
543 Debug(net, 6, "[admin] GameScript JSON from '{}' ({}): {}", this->admin_name, this->admin_version, json);
544
545 Game::NewEvent(new ScriptEventAdminPort(json));
547}
548
550{
551 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
552
553 uint32_t d1 = p.Recv_uint32();
554
555 Debug(net, 6, "[admin] Ping from '{}' ({}): {}", this->admin_name, this->admin_version, d1);
556
557 return this->SendPong(d1);
558}
559
566NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(std::string_view origin, std::string_view string)
567{
568 /* If the length of both strings, plus the 2 '\0' terminations and 3 bytes of the packet
569 * are bigger than the MTU, just ignore the message. Better safe than sorry. It should
570 * never occur though as the longest strings are chat messages, which are still 30%
571 * smaller than COMPAT_MTU. */
572 if (origin.size() + string.size() + 2 + 3 >= COMPAT_MTU) return NETWORK_RECV_STATUS_OKAY;
573
574 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CONSOLE);
575
576 p->Send_string(origin);
577 p->Send_string(string);
578 this->SendPacket(std::move(p));
579
581}
582
589{
590 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_GAMESCRIPT);
591
592 p->Send_string(json);
593 this->SendPacket(std::move(p));
594
596}
597
604{
605 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_PONG);
606
607 p->Send_uint32(d1);
608 this->SendPacket(std::move(p));
609
611}
612
618{
619 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CMD_NAMES);
620
621 for (uint16_t i = 0; i < to_underlying(Commands::End); i++) {
622 std::string_view cmdname = GetCommandName(static_cast<Commands>(i));
623
624 /* Should COMPAT_MTU be exceeded, start a new packet
625 * (magic 5: 1 bool "more data" and one uint16_t "command id", one
626 * byte for string '\0' termination and 1 bool "no more data" */
627 if (!p->CanWriteToPacket(cmdname.size() + 5)) {
628 p->Send_bool(false);
629 this->SendPacket(std::move(p));
630
631 p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CMD_NAMES);
632 }
633
634 p->Send_bool(true);
635 p->Send_uint16(i);
636 p->Send_string(cmdname);
637 }
638
639 /* Marker to notify the end of the packet has been reached. */
640 p->Send_bool(false);
641 this->SendPacket(std::move(p));
642
644}
645
653{
654 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CMD_LOGGING);
655
656 p->Send_uint32(client_id);
657 p->Send_uint8 (cp.company);
658 p->Send_uint16(to_underlying(cp.cmd));
659 p->Send_buffer(cp.data);
660 p->Send_uint32(cp.frame);
661
662 this->SendPacket(std::move(p));
663
665}
666
667/***********
668 * Receiving functions
669 ************/
670
672{
673 if (this->status != ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
674
675 if (!_settings_client.network.allow_insecure_admin_login) {
676 /* You're not authorized to login using this method. */
677 return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
678 }
679
680 std::string password = p.Recv_string(NETWORK_PASSWORD_LENGTH);
681
682 if (_settings_client.network.admin_password.empty() || _settings_client.network.admin_password != password) {
683 /* Password is invalid */
684 return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
685 }
686
689
690 if (this->admin_name.empty() || this->admin_version.empty()) {
691 /* no name or version supplied */
692 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
693 }
694
695 Debug(net, 3, "[admin] '{}' ({}) has connected", this->admin_name, this->admin_version);
696
697 return this->SendProtocol();
698}
699
701{
702 /* The admin is leaving nothing else to do */
703 return this->CloseConnection();
704}
705
707{
708 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
709
711 AdminUpdateFrequencies freq = static_cast<AdminUpdateFrequencies>(p.Recv_uint16());
712
713 if (type >= ADMIN_UPDATE_END || !_admin_update_type_frequencies[type].All(freq)) {
714 /* The server does not know of this UpdateType. */
715 Debug(net, 1, "[admin] Not supported update frequency {} ({}) from '{}' ({})", type, freq, this->admin_name, this->admin_version);
716 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
717 }
718
719 this->update_frequency[type] = freq;
720
722
724}
725
727{
728 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
729
731 uint32_t d1 = p.Recv_uint32();
732
733 switch (type) {
735 /* The admin is requesting the current date. */
736 this->SendDate();
737 break;
738
740 /* The admin is requesting client info. */
741 if (d1 == UINT32_MAX) {
743 for (const NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
744 this->SendClientInfo(cs, cs->GetInfo());
745 }
746 } else {
747 if (d1 == CLIENT_ID_SERVER) {
749 } else {
750 const NetworkClientSocket *cs = NetworkClientSocket::GetByClientID((ClientID)d1);
751 if (cs != nullptr) this->SendClientInfo(cs, cs->GetInfo());
752 }
753 }
754 break;
755
757 /* The admin is asking for company info. */
758 if (d1 == UINT32_MAX) {
759 for (const Company *company : Company::Iterate()) {
760 this->SendCompanyInfo(company);
761 }
762 } else {
763 const Company *company = Company::GetIfValid(d1);
764 if (company != nullptr) this->SendCompanyInfo(company);
765 }
766 break;
767
769 /* The admin is requesting economy info. */
770 this->SendCompanyEconomy();
771 break;
772
774 /* the admin is requesting company stats. */
775 this->SendCompanyStats();
776 break;
777
779 /* The admin is requesting the names of DoCommands. */
780 this->SendCmdNames();
781 break;
782
783 default:
784 /* An unsupported "poll" update type. */
785 Debug(net, 1, "[admin] Not supported poll {} ({}) from '{}' ({}).", type, d1, this->admin_name, this->admin_version);
786 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
787 }
788
790}
791
793{
794 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
795
797 DestType desttype = (DestType)p.Recv_uint8();
798 int dest = p.Recv_uint32();
799
800 std::string msg = p.Recv_string(NETWORK_CHAT_LENGTH);
801
802 switch (action) {
803 case NETWORK_ACTION_CHAT:
804 case NETWORK_ACTION_CHAT_CLIENT:
805 case NETWORK_ACTION_CHAT_COMPANY:
806 case NETWORK_ACTION_SERVER_MESSAGE:
807 NetworkServerSendChat(action, desttype, dest, msg, _network_own_client_id, 0, true);
808 break;
809
810 default:
811 Debug(net, 1, "[admin] Invalid chat action {} from admin '{}' ({}).", action, this->admin_name, this->admin_version);
812 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
813 }
814
816}
817
819{
820 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
821
822 std::string source = p.Recv_string(NETWORK_CHAT_LENGTH);
823 TextColour colour = (TextColour)p.Recv_uint16();
824 std::string user = p.Recv_string(NETWORK_CHAT_LENGTH);
825 std::string msg = p.Recv_string(NETWORK_CHAT_LENGTH);
826
827 if (!IsValidConsoleColour(colour)) {
828 Debug(net, 1, "[admin] Not supported chat colour {} ({}, {}, {}) from '{}' ({}).", (uint16_t)colour, source, user, msg, this->admin_name, this->admin_version);
829 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
830 }
831
832 NetworkServerSendExternalChat(source, colour, user, msg);
833
835}
836
837/*
838 * Secure authentication send and receive methods.
839 */
840
842{
843 if (this->status != ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
844
848
849 /* Always exclude key exchange only, as that provides no credential checking. */
851
852 if (this->admin_name.empty() || this->admin_version.empty()) {
853 /* No name or version supplied. */
854 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
855 }
856
858 if (!handler->CanBeUsed()) return this->SendError(NETWORK_ERROR_NO_AUTHENTICATION_METHOD_AVAILABLE);
859
860 this->authentication_handler = std::move(handler);
861 Debug(net, 3, "[admin] '{}' ({}) has connected", this->admin_name, this->admin_version);
862
863 return this->SendAuthRequest();
864}
865
866NetworkRecvStatus ServerNetworkAdminSocketHandler::SendAuthRequest()
867{
869
870 Debug(net, 6, "[admin] '{}' ({}) authenticating using {}", this->admin_name, this->admin_version, this->authentication_handler->GetName());
871
872 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_AUTH_REQUEST);
873 this->authentication_handler->SendRequest(*p);
874
875 this->SendPacket(std::move(p));
876
878}
879
880NetworkRecvStatus ServerNetworkAdminSocketHandler::SendEnableEncryption()
881{
882 if (this->status != ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
883
884 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_ENABLE_ENCRYPTION);
885 this->authentication_handler->SendEnableEncryption(*p);
886 this->SendPacket(std::move(p));
887
889}
890
892{
893 if (this->status != ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
894
895 switch (this->authentication_handler->ReceiveResponse(p)) {
897 Debug(net, 3, "[admin] '{}' ({}) authenticated", this->admin_name, this->admin_version);
898
899 this->SendEnableEncryption();
900
901 this->receive_encryption_handler = this->authentication_handler->CreateClientToServerEncryptionHandler();
902 this->send_encryption_handler = this->authentication_handler->CreateServerToClientEncryptionHandler();
903 this->authentication_handler = nullptr;
904 return this->SendProtocol();
905
907 Debug(net, 6, "[admin] '{}' ({}) authentication failed, trying next method", this->admin_name, this->admin_version);
908 return this->SendAuthRequest();
909
911 default:
912 Debug(net, 3, "[admin] '{}' ({}) authentication failed", this->admin_name, this->admin_version);
913 return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
914 }
915}
916
917/*
918 * Useful wrapper functions
919 */
920
926void NetworkAdminClientInfo(const NetworkClientSocket *cs, bool new_client)
927{
929 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO].Test(AdminUpdateFrequency::Automatic)) {
930 as->SendClientInfo(cs, cs->GetInfo());
931 if (new_client) {
932 as->SendClientJoin(cs->client_id);
933 }
934 }
935 }
936}
937
943{
945 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO].Test(AdminUpdateFrequency::Automatic)) {
946 as->SendClientUpdate(ci);
947 }
948 }
949}
950
956{
958 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO].Test(AdminUpdateFrequency::Automatic)) {
959 as->SendClientQuit(client_id);
960 }
961 }
962}
963
970{
972 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO].Test(AdminUpdateFrequency::Automatic)) {
973 as->SendClientError(client_id, error_code);
974 }
975 }
976}
977
982void NetworkAdminCompanyNew(const Company *company)
983{
984 if (company == nullptr) {
985 Debug(net, 1, "[admin] Empty company given for update");
986 return;
987 }
988
990 if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != AdminUpdateFrequency::Automatic) continue;
991
992 as->SendCompanyNew(company->index);
993 as->SendCompanyInfo(company);
994 }
995}
996
1002{
1003 if (company == nullptr) return;
1004
1006 if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != AdminUpdateFrequency::Automatic) continue;
1007
1008 as->SendCompanyUpdate(company);
1009 }
1010}
1011
1018{
1020 as->SendCompanyRemove(company_id, bcrr);
1021 }
1022}
1023
1024
1034void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, std::string_view msg, int64_t data, bool from_admin)
1035{
1036 if (from_admin) return;
1037
1039 if (as->update_frequency[ADMIN_UPDATE_CHAT].Test(AdminUpdateFrequency::Automatic)) {
1040 as->SendChat(action, desttype, client_id, msg, data);
1041 }
1042 }
1043}
1044
1051void NetworkServerSendAdminRcon(AdminID admin_index, TextColour colour_code, std::string_view string)
1052{
1053 ServerNetworkAdminSocketHandler::Get(admin_index)->SendRcon(colour_code, string);
1054}
1055
1061void NetworkAdminConsole(std::string_view origin, std::string_view string)
1062{
1064 if (as->update_frequency[ADMIN_UPDATE_CONSOLE].Test(AdminUpdateFrequency::Automatic)) {
1065 as->SendConsole(origin, string);
1066 }
1067 }
1068}
1069
1074void NetworkAdminGameScript(std::string_view json)
1075{
1077 if (as->update_frequency[ADMIN_UPDATE_GAMESCRIPT].Test(AdminUpdateFrequency::Automatic)) {
1078 as->SendGameScript(json);
1079 }
1080 }
1081}
1082
1088void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket &cp)
1089{
1090 ClientID client_id = owner == nullptr ? _network_own_client_id : owner->client_id;
1091
1093 if (as->update_frequency[ADMIN_UPDATE_CMD_LOGGING].Test(AdminUpdateFrequency::Automatic)) {
1094 as->SendCmdLogging(client_id, cp);
1095 }
1096 }
1097}
1098
1108
1114{
1116 for (int i = 0; i < ADMIN_UPDATE_END; i++) {
1117 if (as->update_frequency[i].Test(freq)) {
1118 /* Update the admin for the required details */
1119 switch (i) {
1120 case ADMIN_UPDATE_DATE:
1121 as->SendDate();
1122 break;
1123
1125 as->SendCompanyEconomy();
1126 break;
1127
1129 as->SendCompanyStats();
1130 break;
1131
1132 default: NOT_REACHED();
1133 }
1134 }
1135 }
1136 }
1137}
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:56
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 the string id of an internal error number.
Definition network.cpp:310
bool _network_dedicated
are we a dedicated server?
Definition network.cpp:69
ClientID _network_own_client_id
Our client identifier.
Definition network.cpp:71
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.
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:264
static uint SizeY()
Get the size of the map along the Y.
Definition map_func.h:273
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:117
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
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.