OpenTTD Source 20250312-master-gcdcc6b491d
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 <http://www.gnu.org/licenses/>.
6 */
7
10#include "../stdafx.h"
11#include "../strings_func.h"
12#include "../timer/timer_game_calendar.h"
13#include "../timer/timer_game_calendar.h"
14#include "core/network_game_info.h"
15#include "network_admin.h"
16#include "network_base.h"
17#include "network_server.h"
18#include "../command_func.h"
19#include "../company_base.h"
20#include "../console_func.h"
21#include "../core/pool_func.hpp"
22#include "../map_func.h"
23#include "../rev.h"
24#include "../game/game.hpp"
25
26#include "../safeguards.h"
27
28
29/* This file handles all the admin network commands. */
30
33
36INSTANTIATE_POOL_METHODS(NetworkAdminSocket)
37
40
42static const std::chrono::seconds ADMIN_AUTHORISATION_TIMEOUT(10);
43
44
60
70
75{
76 Debug(net, 3, "[admin] '{}' ({}) has disconnected", this->admin_name, this->admin_version);
77 if (_redirect_console_to_admin == this->index) _redirect_console_to_admin = AdminID::Invalid();
78
82 }
83}
84
93
96{
98 if (as->status <= ADMIN_STATUS_AUTHENTICATE && std::chrono::steady_clock::now() > as->connect_time + ADMIN_AUTHORISATION_TIMEOUT) {
99 Debug(net, 2, "[admin] Admin did not send its authorisation within {} seconds", std::chrono::duration_cast<std::chrono::seconds>(ADMIN_AUTHORISATION_TIMEOUT).count());
100 as->CloseConnection(true);
101 continue;
102 }
103 if (as->writable) {
104 as->SendPackets();
105 }
106 }
107}
108
114/* static */ void ServerNetworkAdminSocketHandler::AcceptConnection(SOCKET s, const NetworkAddress &address)
115{
117 as->address = address; // Save the IP of the client
118}
119
120/***********
121 * Sending functions for admin network
122 ************/
123
129{
130 /* Whatever the error might be, authentication (keys) must be released as soon as possible. */
131 this->authentication_handler = nullptr;
132
133 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_ERROR);
134
135 p->Send_uint8(error);
136 this->SendPacket(std::move(p));
137
138 std::string error_message = GetString(GetNetworkErrorMsg(error));
139
140 Debug(net, 1, "[admin] The admin '{}' ({}) made an error and has been disconnected: '{}'", this->admin_name, this->admin_version, error_message);
141
142 return this->CloseConnection(true);
143}
144
147{
149
150 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_PROTOCOL);
151
152 /* announce the protocol version */
153 p->Send_uint8(NETWORK_GAME_ADMIN_VERSION);
154
155 for (int i = 0; i < ADMIN_UPDATE_END; i++) {
156 p->Send_bool (true);
157 p->Send_uint16(i);
158 p->Send_uint16(_admin_update_type_frequencies[i]);
159 }
160
161 p->Send_bool(false);
162 this->SendPacket(std::move(p));
163
164 return this->SendWelcome();
165}
166
169{
170 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_WELCOME);
171
172 p->Send_string(_settings_client.network.server_name);
173 p->Send_string(GetNetworkRevisionString());
174 p->Send_bool (_network_dedicated);
175
176 p->Send_string(""); // Used to be map-name.
180 p->Send_uint16(Map::SizeX());
181 p->Send_uint16(Map::SizeY());
182
183 this->SendPacket(std::move(p));
184
186}
187
190{
191 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_NEWGAME);
192 this->SendPacket(std::move(p));
194}
195
198{
199 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_SHUTDOWN);
200 this->SendPacket(std::move(p));
202}
203
206{
207 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_DATE);
208
209 p->Send_uint32(TimerGameCalendar::date.base());
210 this->SendPacket(std::move(p));
211
213}
214
220{
221 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CLIENT_JOIN);
222
223 p->Send_uint32(client_id);
224 this->SendPacket(std::move(p));
225
227}
228
235{
236 /* Only send data when we're a proper client, not just someone trying to query the server. */
237 if (ci == nullptr) return NETWORK_RECV_STATUS_OKAY;
238
239 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CLIENT_INFO);
240
241 p->Send_uint32(ci->client_id);
242 p->Send_string(cs == nullptr ? "" : const_cast<NetworkAddress &>(cs->client_address).GetHostname());
243 p->Send_string(ci->client_name);
244 p->Send_uint8 (0); // Used to be language
245 p->Send_uint32(ci->join_date.base());
246 p->Send_uint8 (ci->client_playas);
247
248 this->SendPacket(std::move(p));
249
251}
252
253
259{
260 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CLIENT_UPDATE);
261
262 p->Send_uint32(ci->client_id);
263 p->Send_string(ci->client_name);
264 p->Send_uint8 (ci->client_playas);
265
266 this->SendPacket(std::move(p));
267
269}
270
276{
277 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CLIENT_QUIT);
278
279 p->Send_uint32(client_id);
280 this->SendPacket(std::move(p));
281
283}
284
291{
292 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CLIENT_ERROR);
293
294 p->Send_uint32(client_id);
295 p->Send_uint8 (error);
296 this->SendPacket(std::move(p));
297
299}
300
306{
307 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_NEW);
308 p->Send_uint8(company_id);
309
310 this->SendPacket(std::move(p));
311
313}
314
320{
321 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_INFO);
322
323 p->Send_uint8 (c->index);
324 p->Send_string(GetString(STR_COMPANY_NAME, c->index));
325 p->Send_string(GetString(STR_PRESIDENT_NAME, c->index));
326 p->Send_uint8 (c->colour);
327 p->Send_bool (true);
328 p->Send_uint32(c->inaugurated_year.base());
329 p->Send_bool (c->is_ai);
330 p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy
331
332 this->SendPacket(std::move(p));
333
335}
336
337
343{
344 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_UPDATE);
345
346 p->Send_uint8 (c->index);
347 p->Send_string(GetString(STR_COMPANY_NAME, c->index));
348 p->Send_string(GetString(STR_PRESIDENT_NAME, c->index));
349 p->Send_uint8 (c->colour);
350 p->Send_bool (true);
351 p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy
352
353 this->SendPacket(std::move(p));
354
356}
357
364{
365 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_REMOVE);
366
367 p->Send_uint8(company_id);
368 p->Send_uint8(acrr);
369
370 this->SendPacket(std::move(p));
371
373}
374
377{
378 for (const Company *company : Company::Iterate()) {
379 /* Get the income. */
380 Money income = -std::reduce(std::begin(company->yearly_expenses[0]), std::end(company->yearly_expenses[0]));
381
382 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_ECONOMY);
383
384 p->Send_uint8(company->index);
385
386 /* Current information. */
387 p->Send_uint64(company->money);
388 p->Send_uint64(company->current_loan);
389 p->Send_uint64(income);
390 p->Send_uint16(static_cast<uint16_t>(std::min<uint64_t>(UINT16_MAX, company->cur_economy.delivered_cargo.GetSum<OverflowSafeInt64>())));
391
392 /* Send stats for the last 2 quarters. */
393 for (uint i = 0; i < 2; i++) {
394 p->Send_uint64(company->old_economy[i].company_value);
395 p->Send_uint16(company->old_economy[i].performance_history);
396 p->Send_uint16(static_cast<uint16_t>(std::min<uint64_t>(UINT16_MAX, company->old_economy[i].delivered_cargo.GetSum<OverflowSafeInt64>())));
397 }
398
399 this->SendPacket(std::move(p));
400 }
401
402
404}
405
408{
409 /* Fetch the latest version of the stats. */
411
412 /* Go through all the companies. */
413 for (const Company *company : Company::Iterate()) {
414 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_COMPANY_STATS);
415
416 /* Send the information. */
417 p->Send_uint8(company->index);
418
419 for (uint i = 0; i < NETWORK_VEH_END; i++) {
420 p->Send_uint16(company_stats[company->index].num_vehicle[i]);
421 }
422
423 for (uint i = 0; i < NETWORK_VEH_END; i++) {
424 p->Send_uint16(company_stats[company->index].num_station[i]);
425 }
426
427 this->SendPacket(std::move(p));
428 }
429
431}
432
441NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, int64_t data)
442{
443 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CHAT);
444
445 p->Send_uint8 (action);
446 p->Send_uint8 (desttype);
447 p->Send_uint32(client_id);
448 p->Send_string(msg);
449 p->Send_uint64(data);
450
451 this->SendPacket(std::move(p));
453}
454
460{
461 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_RCON_END);
462
463 p->Send_string(command);
464 this->SendPacket(std::move(p));
465
467}
468
474NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRcon(uint16_t colour, const std::string_view result)
475{
476 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_RCON);
477
478 p->Send_uint16(colour);
479 p->Send_string(result);
480 this->SendPacket(std::move(p));
481
483}
484
486{
487 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
488
489 std::string command = p.Recv_string(NETWORK_RCONCOMMAND_LENGTH);
490
491 Debug(net, 3, "[admin] Rcon command from '{}' ({}): {}", this->admin_name, this->admin_version, command);
492
494 IConsoleCmdExec(command);
495 _redirect_console_to_admin = AdminID::Invalid();
496 return this->SendRconEnd(command);
497}
498
500{
501 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
502
503 std::string json = p.Recv_string(NETWORK_GAMESCRIPT_JSON_LENGTH);
504
505 Debug(net, 6, "[admin] GameScript JSON from '{}' ({}): {}", this->admin_name, this->admin_version, json);
506
507 Game::NewEvent(new ScriptEventAdminPort(json));
509}
510
512{
513 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
514
515 uint32_t d1 = p.Recv_uint32();
516
517 Debug(net, 6, "[admin] Ping from '{}' ({}): {}", this->admin_name, this->admin_version, d1);
518
519 return this->SendPong(d1);
520}
521
527NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const std::string_view origin, const std::string_view string)
528{
529 /* If the length of both strings, plus the 2 '\0' terminations and 3 bytes of the packet
530 * are bigger than the MTU, just ignore the message. Better safe than sorry. It should
531 * never occur though as the longest strings are chat messages, which are still 30%
532 * smaller than COMPAT_MTU. */
533 if (origin.size() + string.size() + 2 + 3 >= COMPAT_MTU) return NETWORK_RECV_STATUS_OKAY;
534
535 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CONSOLE);
536
537 p->Send_string(origin);
538 p->Send_string(string);
539 this->SendPacket(std::move(p));
540
542}
543
549{
550 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_GAMESCRIPT);
551
552 p->Send_string(json);
553 this->SendPacket(std::move(p));
554
556}
557
560{
561 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_PONG);
562
563 p->Send_uint32(d1);
564 this->SendPacket(std::move(p));
565
567}
568
571{
572 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CMD_NAMES);
573
574 for (uint16_t i = 0; i < CMD_END; i++) {
575 const char *cmdname = GetCommandName(static_cast<Commands>(i));
576
577 /* Should COMPAT_MTU be exceeded, start a new packet
578 * (magic 5: 1 bool "more data" and one uint16_t "command id", one
579 * byte for string '\0' termination and 1 bool "no more data" */
580 if (!p->CanWriteToPacket(strlen(cmdname) + 5)) {
581 p->Send_bool(false);
582 this->SendPacket(std::move(p));
583
584 p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CMD_NAMES);
585 }
586
587 p->Send_bool(true);
588 p->Send_uint16(i);
589 p->Send_string(cmdname);
590 }
591
592 /* Marker to notify the end of the packet has been reached. */
593 p->Send_bool(false);
594 this->SendPacket(std::move(p));
595
597}
598
605{
606 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_CMD_LOGGING);
607
608 p->Send_uint32(client_id);
609 p->Send_uint8 (cp.company);
610 p->Send_uint16(cp.cmd);
611 p->Send_buffer(cp.data);
612 p->Send_uint32(cp.frame);
613
614 this->SendPacket(std::move(p));
615
617}
618
619/***********
620 * Receiving functions
621 ************/
622
624{
625 if (this->status != ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
626
628 /* You're not authorized to login using this method. */
629 return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
630 }
631
632 std::string password = p.Recv_string(NETWORK_PASSWORD_LENGTH);
633
635 _settings_client.network.admin_password.compare(password) != 0) {
636 /* Password is invalid */
637 return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
638 }
639
642
643 if (this->admin_name.empty() || this->admin_version.empty()) {
644 /* no name or version supplied */
645 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
646 }
647
648 Debug(net, 3, "[admin] '{}' ({}) has connected", this->admin_name, this->admin_version);
649
650 return this->SendProtocol();
651}
652
654{
655 /* The admin is leaving nothing else to do */
656 return this->CloseConnection();
657}
658
660{
661 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
662
665
666 if (type >= ADMIN_UPDATE_END || (_admin_update_type_frequencies[type] & freq) != freq) {
667 /* The server does not know of this UpdateType. */
668 Debug(net, 1, "[admin] Not supported update frequency {} ({}) from '{}' ({})", type, freq, this->admin_name, this->admin_version);
669 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
670 }
671
672 this->update_frequency[type] = freq;
673
675
677}
678
680{
681 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
682
684 uint32_t d1 = p.Recv_uint32();
685
686 switch (type) {
688 /* The admin is requesting the current date. */
689 this->SendDate();
690 break;
691
693 /* The admin is requesting client info. */
694 if (d1 == UINT32_MAX) {
696 for (const NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
697 this->SendClientInfo(cs, cs->GetInfo());
698 }
699 } else {
700 if (d1 == CLIENT_ID_SERVER) {
702 } else {
703 const NetworkClientSocket *cs = NetworkClientSocket::GetByClientID((ClientID)d1);
704 if (cs != nullptr) this->SendClientInfo(cs, cs->GetInfo());
705 }
706 }
707 break;
708
710 /* The admin is asking for company info. */
711 if (d1 == UINT32_MAX) {
712 for (const Company *company : Company::Iterate()) {
713 this->SendCompanyInfo(company);
714 }
715 } else {
716 const Company *company = Company::GetIfValid(d1);
717 if (company != nullptr) this->SendCompanyInfo(company);
718 }
719 break;
720
722 /* The admin is requesting economy info. */
723 this->SendCompanyEconomy();
724 break;
725
727 /* the admin is requesting company stats. */
728 this->SendCompanyStats();
729 break;
730
732 /* The admin is requesting the names of DoCommands. */
733 this->SendCmdNames();
734 break;
735
736 default:
737 /* An unsupported "poll" update type. */
738 Debug(net, 1, "[admin] Not supported poll {} ({}) from '{}' ({}).", type, d1, this->admin_name, this->admin_version);
739 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
740 }
741
743}
744
746{
747 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
748
750 DestType desttype = (DestType)p.Recv_uint8();
751 int dest = p.Recv_uint32();
752
753 std::string msg = p.Recv_string(NETWORK_CHAT_LENGTH);
754
755 switch (action) {
756 case NETWORK_ACTION_CHAT:
757 case NETWORK_ACTION_CHAT_CLIENT:
758 case NETWORK_ACTION_CHAT_COMPANY:
759 case NETWORK_ACTION_SERVER_MESSAGE:
760 NetworkServerSendChat(action, desttype, dest, msg, _network_own_client_id, 0, true);
761 break;
762
763 default:
764 Debug(net, 1, "[admin] Invalid chat action {} from admin '{}' ({}).", action, this->admin_name, this->admin_version);
765 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
766 }
767
769}
770
772{
773 if (this->status <= ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
774
775 std::string source = p.Recv_string(NETWORK_CHAT_LENGTH);
776 TextColour colour = (TextColour)p.Recv_uint16();
777 std::string user = p.Recv_string(NETWORK_CHAT_LENGTH);
778 std::string msg = p.Recv_string(NETWORK_CHAT_LENGTH);
779
780 if (!IsValidConsoleColour(colour)) {
781 Debug(net, 1, "[admin] Not supported chat colour {} ({}, {}, {}) from '{}' ({}).", (uint16_t)colour, source, user, msg, this->admin_name, this->admin_version);
782 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
783 }
784
785 NetworkServerSendExternalChat(source, colour, user, msg);
786
788}
789
790/*
791 * Secure authentication send and receive methods.
792 */
793
795{
796 if (this->status != ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
797
801
802 /* Always exclude key exchange only, as that provides no credential checking. */
804
805 if (this->admin_name.empty() || this->admin_version.empty()) {
806 /* No name or version supplied. */
807 return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
808 }
809
811 if (!handler->CanBeUsed()) return this->SendError(NETWORK_ERROR_NO_AUTHENTICATION_METHOD_AVAILABLE);
812
813 this->authentication_handler = std::move(handler);
814 Debug(net, 3, "[admin] '{}' ({}) has connected", this->admin_name, this->admin_version);
815
816 return this->SendAuthRequest();
817}
818
819NetworkRecvStatus ServerNetworkAdminSocketHandler::SendAuthRequest()
820{
822
823 Debug(net, 6, "[admin] '{}' ({}) authenticating using {}", this->admin_name, this->admin_version, this->authentication_handler->GetName());
824
825 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_AUTH_REQUEST);
826 this->authentication_handler->SendRequest(*p);
827
828 this->SendPacket(std::move(p));
829
831}
832
833NetworkRecvStatus ServerNetworkAdminSocketHandler::SendEnableEncryption()
834{
835 if (this->status != ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
836
837 auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_ENABLE_ENCRYPTION);
838 this->authentication_handler->SendEnableEncryption(*p);
839 this->SendPacket(std::move(p));
840
842}
843
845{
846 if (this->status != ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
847
848 switch (this->authentication_handler->ReceiveResponse(p)) {
850 Debug(net, 3, "[admin] '{}' ({}) authenticated", this->admin_name, this->admin_version);
851
852 this->SendEnableEncryption();
853
854 this->receive_encryption_handler = this->authentication_handler->CreateClientToServerEncryptionHandler();
855 this->send_encryption_handler = this->authentication_handler->CreateServerToClientEncryptionHandler();
856 this->authentication_handler = nullptr;
857 return this->SendProtocol();
858
860 Debug(net, 6, "[admin] '{}' ({}) authentication failed, trying next method", this->admin_name, this->admin_version);
861 return this->SendAuthRequest();
862
864 default:
865 Debug(net, 3, "[admin] '{}' ({}) authentication failed", this->admin_name, this->admin_version);
866 return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
867 }
868}
869
870/*
871 * Useful wrapper functions
872 */
873
879void NetworkAdminClientInfo(const NetworkClientSocket *cs, bool new_client)
880{
882 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
883 as->SendClientInfo(cs, cs->GetInfo());
884 if (new_client) {
885 as->SendClientJoin(cs->client_id);
886 }
887 }
888 }
889}
890
896{
898 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
899 as->SendClientUpdate(ci);
900 }
901 }
902}
903
909{
911 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
912 as->SendClientQuit(client_id);
913 }
914 }
915}
916
923{
925 if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
926 as->SendClientError(client_id, error_code);
927 }
928 }
929}
930
935void NetworkAdminCompanyNew(const Company *company)
936{
937 if (company == nullptr) {
938 Debug(net, 1, "[admin] Empty company given for update");
939 return;
940 }
941
943 if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != ADMIN_FREQUENCY_AUTOMATIC) continue;
944
945 as->SendCompanyNew(company->index);
946 as->SendCompanyInfo(company);
947 }
948}
949
955{
956 if (company == nullptr) return;
957
959 if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != ADMIN_FREQUENCY_AUTOMATIC) continue;
960
961 as->SendCompanyUpdate(company);
962 }
963}
964
971{
973 as->SendCompanyRemove(company_id, bcrr);
974 }
975}
976
977
981void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, int64_t data, bool from_admin)
982{
983 if (from_admin) return;
984
986 if (as->update_frequency[ADMIN_UPDATE_CHAT] & ADMIN_FREQUENCY_AUTOMATIC) {
987 as->SendChat(action, desttype, client_id, msg, data);
988 }
989 }
990}
991
998void NetworkServerSendAdminRcon(AdminID admin_index, TextColour colour_code, const std::string_view string)
999{
1000 ServerNetworkAdminSocketHandler::Get(admin_index)->SendRcon(colour_code, string);
1001}
1002
1008void NetworkAdminConsole(const std::string_view origin, const std::string_view string)
1009{
1011 if (as->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) {
1012 as->SendConsole(origin, string);
1013 }
1014 }
1015}
1016
1021void NetworkAdminGameScript(const std::string_view json)
1022{
1024 if (as->update_frequency[ADMIN_UPDATE_GAMESCRIPT] & ADMIN_FREQUENCY_AUTOMATIC) {
1025 as->SendGameScript(json);
1026 }
1027 }
1028}
1029
1035void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket &cp)
1036{
1037 ClientID client_id = owner == nullptr ? _network_own_client_id : owner->client_id;
1038
1040 if (as->update_frequency[ADMIN_UPDATE_CMD_LOGGING] & ADMIN_FREQUENCY_AUTOMATIC) {
1041 as->SendCmdLogging(client_id, cp);
1042 }
1043 }
1044}
1045
1055
1061{
1063 for (int i = 0; i < ADMIN_UPDATE_END; i++) {
1064 if (as->update_frequency[i] & freq) {
1065 /* Update the admin for the required details */
1066 switch (i) {
1067 case ADMIN_UPDATE_DATE:
1068 as->SendDate();
1069 break;
1070
1072 as->SendCompanyEconomy();
1073 break;
1074
1076 as->SendCompanyStats();
1077 break;
1078
1079 default: NOT_REACHED();
1080 }
1081 }
1082 }
1083 }
1084}
Enum-as-bit-set wrapper.
static void NewEvent(class ScriptEvent *event)
Queue a new event for a 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
Main socket handler for admin related connections.
Definition tcp_admin.h:117
NetworkRecvStatus CloseConnection(bool error=true) override
This will put this socket handler in a close state.
Definition tcp_admin.cpp:26
AdminStatus status
Status of this admin.
Definition tcp_admin.h:121
std::string admin_version
Version string of the admin.
Definition tcp_admin.h:120
std::string admin_name
Name of the admin.
Definition tcp_admin.h:119
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:50
std::unique_ptr< class NetworkEncryptionHandler > receive_encryption_handler
The handler for decrypting received packets.
Definition core.h:49
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:58
A sort-of mixin that adds 'at(pos)' and 'operator[](pos)' implementations for 'ConvertibleThroughBase...
Class for handling the server side of the game connection.
static void Send()
Send the packets for the server sockets.
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...
NetworkRecvStatus SendClientUpdate(const NetworkClientInfo *ci)
Send an update for some client's information.
NetworkRecvStatus SendGameScript(const std::string_view json)
Send GameScript JSON output.
NetworkRecvStatus SendClientInfo(const NetworkClientSocket *cs, const NetworkClientInfo *ci)
Send an initial set of data from some client's information.
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.
NetworkRecvStatus SendClientError(ClientID client_id, NetworkErrorCode error)
Tell the admin that a client made an error.
NetworkRecvStatus SendCmdNames()
Send the names of the commands.
std::array< AdminUpdateFrequency, ADMIN_UPDATE_END > update_frequency
Admin requested update intervals.
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 SendRconEnd(const std::string_view command)
Send a notification indicating the rcon command has completed.
NetworkRecvStatus SendConsole(const std::string_view origin, const std::string_view command)
Send console output of other clients.
NetworkRecvStatus SendChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, int64_t data)
Send a chat message.
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 acception 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 SendRcon(uint16_t colour, const std::string_view command)
Send the reply of an rcon command.
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 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 SendCompanyUpdate(const Company *c)
Send an update about a company.
NetworkAddress address
Address of the admin.
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.
~ServerNetworkAdminSocketHandler()
Clear everything related to this admin.
ServerNetworkAdminSocketHandler(SOCKET s)
Sanity check.
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).
const char * GetCommandName(Commands cmd)
This function mask the parameter with CMD_ID_MASK and returns the name which belongs to the given com...
Definition command.cpp:132
Commands
List of commands.
@ CMD_END
Must ALWAYS be on the end of this list!! (period)
static const uint NETWORK_GAMESCRIPT_JSON_LENGTH
The maximum length of a receiving gamescript json string, in bytes including '\0'.
Definition config.h:60
static const uint NETWORK_CLIENT_NAME_LENGTH
The maximum length of a client's name, in bytes including '\0'.
Definition config.h:58
static const uint NETWORK_CHAT_LENGTH
The maximum length of a chat message, in bytes including '\0'.
Definition config.h:61
static const size_t COMPAT_MTU
Number of bytes we can pack in a single packet for backward compatibility.
Definition config.h:46
static const uint NETWORK_REVISION_LENGTH
The maximum length of the revision, in bytes including '\0'.
Definition config.h:56
static const uint NETWORK_RCONCOMMAND_LENGTH
The maximum length of a rconsole command, in bytes including '\0'.
Definition config.h:59
static const uint NETWORK_PASSWORD_LENGTH
The maximum length of the password, in bytes including '\0'.
Definition config.h:57
static const uint8_t NETWORK_GAME_ADMIN_VERSION
What version of the admin network do we use?
Definition config.h:48
void IConsoleCmdExec(const std::string &command_string, const uint recurse_count)
Execute a given command passed to us.
Definition console.cpp:291
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:23
@ NETWORK_RECV_STATUS_OKAY
Everything is okay.
Definition core.h:24
void DebugReconsiderSendRemoteMessages()
Reconsider whether we need to send debug messages to either NetworkAdminConsole or IConsolePrint.
Definition debug.cpp:264
#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:17
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition gfx_type.h:294
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:68
ClientID _network_own_client_id
Our client identifier.
Definition network.cpp:70
void NetworkAdminClientUpdate(const NetworkClientInfo *ci)
Notify the admin network of a client update (if they did opt in for the respective update).
void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, int64_t data, bool from_admin)
Send chat to the admin network (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.
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).
void NetworkAdminGameScript(const std::string_view json)
Send GameScript JSON to the admin network (if they did opt in for the respective update).
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, const std::string_view string)
Pass the rcon reply to the admin.
static const AdminUpdateFrequency _admin_update_type_frequencies[]
Frequencies, which may be registered for a certain update type.
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(const std::string_view origin, const std::string_view string)
Send console 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 NetworkAuthenticationDefaultAuthorizedKeyHandler _admin_authorized_key_handler(_settings_client.network.admin_authorized_keys)
Provides the authorized key handling for the game authentication.
static NetworkAuthenticationDefaultPasswordProvider _admin_password_provider(_settings_client.network.admin_password)
Provides the password validation for the game's password.
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.
static const std::chrono::seconds ADMIN_AUTHORISATION_TIMEOUT(10)
The timeout for authorisation of the client.
Server part of the admin network protocol.
AdminID _redirect_console_to_admin
Redirection of the (remote) console to the admin.
Base core network types and some helper functions to access them.
@ X25519_KeyExchangeOnly
No actual authentication is taking place, just perform a x25519 key exchange. This method is not supp...
void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, ClientID from_id, int64_t data=0, bool from_admin=false)
Send an actual chat message.
NetworkCompanyStatsArray NetworkGetCompanyStats()
Get the company stats.
void NetworkServerSendExternalChat(const std::string &source, TextColour colour, const std::string &user, const std::string &msg)
Send a chat message from external source.
Server part of the network protocol.
DestType
Destination of our chat messages.
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.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:58
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:57
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:277
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:426
NetworkSettings network
settings related to the network
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.
LandscapeType landscape
the landscape we're currently in
TimerGameCalendar::Year starting_year
starting date
uint32_t generation_seed
noise seed for world generation
GameCreationSettings game_creation
settings used during the creation of a game (map)
static uint SizeY()
Get the size of the map along the Y.
Definition map_func.h:278
static debug_inline uint SizeX()
Get the size of the map along the X.
Definition map_func.h:269
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:116
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.
bool allow_insecure_admin_login
Whether to allow logging in as admin using the insecure old JOIN packet.
std::string admin_password
password for the admin network
std::string server_name
name of the server
Internal entity of a packet.
Definition packet.h:43
uint16_t Recv_uint16()
Read a 16 bits integer from the packet.
Definition packet.cpp:332
uint32_t Recv_uint32()
Read a 32 bits integer from the packet.
Definition packet.cpp:347
uint8_t Recv_uint8()
Read a 8 bits integer from the packet.
Definition packet.cpp:318
std::string Recv_string(size_t length, StringValidationSettings settings=SVS_REPLACE_WITH_QUESTION_MARK)
Reads characters (bytes) from the packet until it finds a '\0', or reaches a maximum of length charac...
Definition packet.cpp:425
Templated helper to make a PoolID a single POD value.
Definition pool_type.hpp:43
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static Titem * Get(auto index)
Returns Titem with given index.
Tindex index
Index of this pool item.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
static Titem * GetIfValid(auto index)
Returns Titem with given index.
Base class for all pools.
@ ADMIN_PACKET_SERVER_CONSOLE
The server gives the admin the data that got printed to its console.
Definition tcp_admin.h:59
@ 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:67
@ ADMIN_PACKET_SERVER_CLIENT_UPDATE
The server gives the admin an information update on a client.
Definition tcp_admin.h:48
@ ADMIN_PACKET_SERVER_COMPANY_STATS
The server gives the admin some statistics about a company.
Definition tcp_admin.h:56
@ ADMIN_PACKET_SERVER_COMPANY_ECONOMY
The server gives the admin some economy related company information.
Definition tcp_admin.h:55
@ ADMIN_PACKET_SERVER_GAMESCRIPT
The server gives the admin information from the GameScript in JSON.
Definition tcp_admin.h:62
@ ADMIN_PACKET_SERVER_CLIENT_INFO
The server gives the admin information about a client.
Definition tcp_admin.h:47
@ ADMIN_PACKET_SERVER_CLIENT_ERROR
The server tells the admin that a client caused an error.
Definition tcp_admin.h:50
@ ADMIN_PACKET_SERVER_AUTH_REQUEST
The server gives the admin the used authentication method and required parameters.
Definition tcp_admin.h:66
@ ADMIN_PACKET_SERVER_CHAT
The server received a chat message and relays it.
Definition tcp_admin.h:57
@ ADMIN_PACKET_SERVER_SHUTDOWN
The server tells the admin its shutting down.
Definition tcp_admin.h:43
@ ADMIN_PACKET_SERVER_RCON_END
The server indicates that the remote console command has completed.
Definition tcp_admin.h:63
@ ADMIN_PACKET_SERVER_WELCOME
The server welcomes the admin to a game.
Definition tcp_admin.h:41
@ ADMIN_PACKET_SERVER_COMPANY_REMOVE
The server tells the admin that a company was removed.
Definition tcp_admin.h:54
@ ADMIN_PACKET_SERVER_ERROR
The server tells the admin an error has occurred.
Definition tcp_admin.h:39
@ ADMIN_PACKET_SERVER_NEWGAME
The server tells the admin its going to start a new game.
Definition tcp_admin.h:42
@ ADMIN_PACKET_SERVER_COMPANY_UPDATE
The server gives the admin an information update on a company.
Definition tcp_admin.h:53
@ ADMIN_PACKET_SERVER_PONG
The server replies to a ping request from the admin.
Definition tcp_admin.h:64
@ ADMIN_PACKET_SERVER_CLIENT_JOIN
The server tells the admin that a client has joined.
Definition tcp_admin.h:46
@ ADMIN_PACKET_SERVER_CMD_LOGGING
The server gives the admin copies of incoming command packets.
Definition tcp_admin.h:65
@ ADMIN_PACKET_SERVER_PROTOCOL
The server tells the admin its protocol version.
Definition tcp_admin.h:40
@ ADMIN_PACKET_SERVER_CLIENT_QUIT
The server tells the admin that a client quit.
Definition tcp_admin.h:49
@ ADMIN_PACKET_SERVER_COMPANY_INFO
The server gives the admin information about a company.
Definition tcp_admin.h:52
@ ADMIN_PACKET_SERVER_CMD_NAMES
The server sends out the names of the DoCommands to the admins.
Definition tcp_admin.h:60
@ ADMIN_PACKET_SERVER_DATE
The server tells the admin what the current game date is.
Definition tcp_admin.h:45
@ ADMIN_PACKET_SERVER_COMPANY_NEW
The server tells the admin that a new company has started.
Definition tcp_admin.h:51
@ ADMIN_PACKET_SERVER_RCON
The server's reply to a remove console command.
Definition tcp_admin.h:58
AdminUpdateType
Update types an admin can register a frequency for.
Definition tcp_admin.h:81
@ ADMIN_UPDATE_DATE
Updates about the date of the game.
Definition tcp_admin.h:82
@ ADMIN_UPDATE_GAMESCRIPT
The admin would like to have gamescript messages.
Definition tcp_admin.h:91
@ ADMIN_UPDATE_COMPANY_INFO
Updates about the generic information of companies.
Definition tcp_admin.h:84
@ ADMIN_UPDATE_CONSOLE
The admin would like to have console messages.
Definition tcp_admin.h:88
@ ADMIN_UPDATE_CHAT
The admin would like to have chat messages.
Definition tcp_admin.h:87
@ ADMIN_UPDATE_COMPANY_STATS
Updates about the statistics of companies.
Definition tcp_admin.h:86
@ ADMIN_UPDATE_COMPANY_ECONOMY
Updates about the economy of companies.
Definition tcp_admin.h:85
@ ADMIN_UPDATE_END
Must ALWAYS be on the end of this list!! (period)
Definition tcp_admin.h:92
@ ADMIN_UPDATE_CLIENT_INFO
Updates about the information of clients.
Definition tcp_admin.h:83
@ ADMIN_UPDATE_CMD_NAMES
The admin would like a list of all DoCommand names.
Definition tcp_admin.h:89
@ ADMIN_UPDATE_CMD_LOGGING
The admin would like to have DoCommand information.
Definition tcp_admin.h:90
AdminCompanyRemoveReason
Reasons for removing a company - communicated to admins.
Definition tcp_admin.h:108
AdminUpdateFrequency
Update frequencies an admin can register.
Definition tcp_admin.h:96
@ ADMIN_FREQUENCY_MONTHLY
The admin gets information about this on a monthly basis.
Definition tcp_admin.h:100
@ ADMIN_FREQUENCY_QUARTERLY
The admin gets information about this on a quarterly basis.
Definition tcp_admin.h:101
@ ADMIN_FREQUENCY_AUTOMATIC
The admin gets information about this when it changes.
Definition tcp_admin.h:103
@ ADMIN_FREQUENCY_ANUALLY
The admin gets information about this on a yearly basis.
Definition tcp_admin.h:102
@ ADMIN_FREQUENCY_WEEKLY
The admin gets information about this on a weekly basis.
Definition tcp_admin.h:99
@ ADMIN_FREQUENCY_DAILY
The admin gets information about this on a daily basis.
Definition tcp_admin.h:98
@ ADMIN_FREQUENCY_POLL
The admin can poll this.
Definition tcp_admin.h:97
@ ADMIN_STATUS_INACTIVE
The admin is not connected nor active.
Definition tcp_admin.h:74
@ ADMIN_STATUS_ACTIVE
The admin is active.
Definition tcp_admin.h:76
@ ADMIN_STATUS_AUTHENTICATE
The admin is connected and working on authentication.
Definition tcp_admin.h:75