11#include "../strings_func.h"
12#include "core/network_game_info.h"
17#include "../console_func.h"
18#include "../company_base.h"
19#include "../command_func.h"
20#include "../saveload/saveload.h"
21#include "../saveload/saveload_filter.h"
22#include "../station_base.h"
23#include "../genworld.h"
24#include "../company_func.h"
25#include "../company_gui.h"
26#include "../company_cmd.h"
27#include "../roadveh.h"
28#include "../order_backup.h"
29#include "../core/pool_func.hpp"
30#include "../core/random_func.hpp"
31#include "../company_cmd.h"
33#include "../timer/timer.h"
34#include "../timer/timer_game_calendar.h"
35#include "../timer/timer_game_economy.h"
36#include "../timer/timer_game_realtime.h"
38#include <condition_variable>
40#include "table/strings.h"
42#include "../safeguards.h"
71 std::deque<std::unique_ptr<Packet>>
packets;
86 std::unique_lock<std::mutex>
lock(this->mutex);
88 while (this->cs !=
nullptr) this->exit_sig.wait(
lock);
92 this->packets.clear();
93 this->current =
nullptr;
108 std::unique_lock<std::mutex>
lock(this->mutex);
112 this->exit_sig.notify_all();
129 if (this->packets.empty())
return false;
131 std::lock_guard<std::mutex>
lock(this->mutex);
133 while (!this->packets.empty()) {
135 this->cs->
SendPacket(std::move(this->packets.front()));
136 this->packets.pop_front();
138 if (last_packet)
return true;
144 void Write(uint8_t *buf,
size_t size)
override
146 std::lock_guard<std::mutex>
lock(this->mutex);
149 if (this->cs ==
nullptr)
SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
153 std::span<const uint8_t> to_write(buf, size);
154 while (!to_write.empty()) {
155 to_write = this->current->Send_bytes(to_write);
157 if (!this->current->CanWriteToPacket(1)) {
158 this->packets.push_back(std::move(this->current));
163 this->total_size += size;
144 void Write(uint8_t *buf,
size_t size)
override {
…}
168 std::lock_guard<std::mutex>
lock(this->mutex);
171 if (this->cs ==
nullptr)
SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
174 if (this->current !=
nullptr) this->packets.push_back(std::move(this->current));
181 p->Send_uint32((uint32_t)this->total_size);
182 this->packets.push_front(std::move(p));
245 if (this->IsPendingDeletion() || this->
sock == INVALID_SOCKET)
return status;
251 NetworkTextMessage(NETWORK_ACTION_LEAVE,
CC_DEFAULT,
false, client_name,
"", STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST);
256 new_cs->SendErrorQuit(this->
client_id, NETWORK_ERROR_CONNECTION_LOST);
268 this->CheckNextClientToSendMap(
this);
281 this->DeferDeletion();
347 SerializeNetworkGameInfo(*p, GetCurrentNetworkServerGameInfo());
361 Debug(net, 9,
"client[{}] SendError(): error={}", this->
client_id, error);
365 p->Send_uint8(error);
366 if (!reason.empty()) p->Send_string(reason);
375 Debug(net, 1,
"'{}' made an error and has been disconnected: {}", client_name,
GetString(strid));
377 if (error == NETWORK_ERROR_KICKED && !reason.empty()) {
378 NetworkTextMessage(NETWORK_ACTION_KICKED,
CC_DEFAULT,
false, client_name, reason, strid);
380 NetworkTextMessage(NETWORK_ACTION_LEAVE,
CC_DEFAULT,
false, client_name,
"", strid);
387 if (error == NETWORK_ERROR_NOT_AUTHORIZED || error == NETWORK_ERROR_NOT_EXPECTED || error == NETWORK_ERROR_WRONG_REVISION) {
388 error = NETWORK_ERROR_ILLEGAL_PACKET;
390 new_cs->SendErrorQuit(this->
client_id, error);
411 Debug(net, 9,
"client[{}] status = NEWGRFS_CHECK", this->
client_id);
422 p->Send_uint8 (grf_count);
460 Debug(net, 9,
"client[{}] SendEnableEncryption()", this->
client_id);
515 p->Send_uint8(waiting);
520void ServerNetworkGameSocketHandler::CheckNextClientToSendMap(NetworkClientSocket *ignore_cs)
522 Debug(net, 9,
"client[{}] CheckNextClientToSendMap()", this->
client_id);
525 NetworkClientSocket *best =
nullptr;
526 for (NetworkClientSocket *new_cs : NetworkClientSocket::
Iterate()) {
527 if (ignore_cs == new_cs)
continue;
530 if (best ==
nullptr || best->GetInfo()->join_date > new_cs->GetInfo()->join_date || (best->GetInfo()->join_date == new_cs->GetInfo()->join_date && best->client_id > new_cs->client_id)) {
537 if (best !=
nullptr) {
543 for (NetworkClientSocket *new_cs : NetworkClientSocket::
Iterate()) {
554 return this->
SendError(NETWORK_ERROR_NOT_AUTHORIZED);
558 Debug(net, 9,
"client[{}] SendMap(): first_packet", this->
client_id);
561 this->
savegame = std::make_shared<PacketWriter>(
this);
582 Debug(net, 9,
"client[{}] SendMap(): last_packet", this->
client_id);
593 this->CheckNextClientToSendMap();
605 Debug(net, 9,
"client[{}] SendJoin(): client_id={}", this->client_id,
client_id);
621#ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
623#ifdef NETWORK_SEND_DOUBLE_SEED
624 p->Send_uint32(_sync_seed_2);
630 this->
last_token = InteractiveRandomRange(UINT8_MAX - 1) + 1;
647#ifdef NETWORK_SEND_DOUBLE_SEED
648 p->Send_uint32(_sync_seed_2);
665 p->Send_uint32(cp.
frame);
682 Debug(net, 9,
"client[{}] SendChat(): action={}, client_id={}, self_send={}", this->client_id, action,
client_id, self_send);
688 p->Send_uint8 (action);
690 p->Send_bool (self_send);
692 p->Send_uint64(data);
707 Debug(net, 9,
"client[{}] SendExternalChat(): source={}", this->
client_id, source);
713 p->Send_string(source);
714 p->Send_uint16(colour);
715 p->Send_string(user);
729 Debug(net, 9,
"client[{}] SendErrorQuit(): client_id={}, errorno={}", this->client_id,
client_id, errorno);
734 p->Send_uint8 (errorno);
746 Debug(net, 9,
"client[{}] SendQuit(): client_id={}", this->client_id,
client_id);
787 p->Send_uint16(colour);
788 p->Send_string(command);
800 Debug(net, 9,
"client[{}] SendMove(): client_id={}", this->client_id,
client_id);
805 p->Send_uint8(company_id);
829 Debug(net, 9,
"client[{}] Receive_CLIENT_GAME_INFO()", this->
client_id);
838 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
841 Debug(net, 9,
"client[{}] Receive_CLIENT_NEWGRFS_CHECKED()", this->
client_id);
850 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
855 return this->
SendError(NETWORK_ERROR_FULL);
861 Debug(net, 9,
"client[{}] Receive_CLIENT_JOIN(): client_revision={}, newgrf_version={}", this->
client_id, client_revision, newgrf_version);
864 if (!IsNetworkCompatibleVersion(client_revision) || _openttd_newgrf_version != newgrf_version) {
866 return this->
SendError(NETWORK_ERROR_WRONG_REVISION);
876 Debug(net, 9,
"client[{}] Receive_CLIENT_IDENTIFY()", this->
client_id);
884 switch (playas.base()) {
887 return this->
SendError(NETWORK_ERROR_FULL);
894 return this->
SendError(NETWORK_ERROR_COMPANY_MISMATCH);
897 if (!
Company::Get(playas)->allow_list.Contains(this->peer_public_key)) {
908 return this->
SendError(NETWORK_ERROR_INVALID_CLIENT_NAME);
913 return this->
SendError(NETWORK_ERROR_NAME_IN_USE);
936 return NETWORK_ERROR_WRONG_PASSWORD;
938 return NETWORK_ERROR_NOT_ON_ALLOW_LIST;
948 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
951 Debug(net, 9,
"client[{}] Receive_CLIENT_AUTH_RESPONSE()", this->
client_id);
963 return this->
SendError(GetErrorForAuthenticationMethod(authentication_method));
987 if (this->status < STATUS_AUTHORIZED || this->
HasClientQuit()) {
988 return this->
SendError(NETWORK_ERROR_NOT_AUTHORIZED);
991 Debug(net, 9,
"client[{}] Receive_CLIENT_GETMAP()", this->
client_id);
1011 Debug(net, 9,
"client[{}] Receive_CLIENT_MAP_OK()", this->
client_id);
1015 NetworkTextMessage(NETWORK_ACTION_JOIN,
CC_DEFAULT,
false, client_name,
"", this->
client_id);
1022 Debug(net, 9,
"client[{}] status = PRE_ACTIVE", this->
client_id);
1035 new_cs->SendClientInfo(this->
GetInfo());
1047 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1058 if (this->status < STATUS_DONE_MAP || this->
HasClientQuit()) {
1059 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1063 return this->
SendError(NETWORK_ERROR_TOO_MANY_COMMANDS);
1066 Debug(net, 9,
"client[{}] Receive_CLIENT_COMMAND()", this->
client_id);
1075 if (err.has_value()) {
1077 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1082 return this->
SendError(NETWORK_ERROR_KICKED);
1087 return this->
SendError(NETWORK_ERROR_KICKED);
1099 return this->
SendError(NETWORK_ERROR_COMPANY_MISMATCH);
1104 return this->
SendError(NETWORK_ERROR_CHEATER);
1144 Debug(net, 9,
"client[{}] Receive_CLIENT_ERROR(): errorno={}", this->
client_id, errorno);
1147 if (this->status < STATUS_DONE_MAP || this->
HasClientQuit()) {
1154 Debug(net, 1,
"'{}' reported an error and is closing its connection: {}", client_name,
GetString(strid));
1156 NetworkTextMessage(NETWORK_ACTION_LEAVE,
CC_DEFAULT,
false, client_name,
"", strid);
1160 new_cs->SendErrorQuit(this->
client_id, errorno);
1172 if (this->status < STATUS_DONE_MAP || this->
HasClientQuit()) {
1176 Debug(net, 9,
"client[{}] Receive_CLIENT_QUIT()", this->
client_id);
1180 NetworkTextMessage(NETWORK_ACTION_LEAVE,
CC_DEFAULT,
false, client_name,
"", STR_NETWORK_MESSAGE_CLIENT_LEAVING);
1197 return this->
SendError(NETWORK_ERROR_NOT_AUTHORIZED);
1202 Debug(net, 9,
"client[{}] Receive_CLIENT_ACK(): frame={}", this->
client_id, frame);
1262 if (ci !=
nullptr) {
1271 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1273 cs->SendChat(action, from_id,
false, msg, data);
1284 if (ci !=
nullptr && ci_to !=
nullptr) {
1288 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1290 cs->SendChat(action, (
ClientID)dest,
true, msg, data);
1299 bool show_local =
true;
1302 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1305 cs->SendChat(action, from_id,
false, msg, data);
1306 if (cs->client_id == from_id) show_local =
false;
1318 if (ci !=
nullptr && ci_own !=
nullptr && ci_own->
client_playas == dest) {
1325 if (ci_to ==
nullptr)
break;
1328 if (ci !=
nullptr && show_local) {
1334 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1336 cs->SendChat(action, ci_to->
client_id,
true, msg, data);
1344 Debug(net, 1,
"Received unknown chat destination type {}; doing broadcast instead", desttype);
1348 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1355 if (ci !=
nullptr) {
1371 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1374 NetworkTextMessage(NETWORK_ACTION_EXTERNAL_CHAT, colour,
false, user, msg, source);
1381 return this->
SendError(NETWORK_ERROR_NOT_AUTHORIZED);
1388 Debug(net, 9,
"client[{}] Receive_CLIENT_CHAT(): action={}, desttype={}, dest={}", this->
client_id, action, desttype, dest);
1395 case NETWORK_ACTION_CHAT:
1396 case NETWORK_ACTION_CHAT_CLIENT:
1397 case NETWORK_ACTION_CHAT_COMPANY:
1402 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1411 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1414 Debug(net, 9,
"client[{}] Receive_CLIENT_SET_NAME()", this->
client_id);
1423 if (ci !=
nullptr) {
1428 return this->
SendError(NETWORK_ERROR_INVALID_CLIENT_NAME);
1445 Debug(net, 9,
"client[{}] Receive_CLIENT_RCON()", this->
client_id);
1455 Debug(net, 1,
"[rcon] Wrong password from client-id {}", this->
client_id);
1459 Debug(net, 3,
"[rcon] Client-id {} executed: {}", this->
client_id, command);
1473 Debug(net, 9,
"client[{}] Receive_CLIENT_MOVE(): company_id={}", this->
client_id, company_id);
1479 Debug(net, 2,
"Wrong public key from client-id #{} for company #{}", this->
client_id, company_id + 1);
1500 case VEH_TRAIN: type = NETWORK_VEH_TRAIN;
break;
1503 case VEH_SHIP: type = NETWORK_VEH_SHIP;
break;
1506 stats[v->owner].num_vehicle[type]++;
1533 if (ci ==
nullptr)
return;
1537 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1539 cs->SendClientInfo(ci);
1565 assert(ci !=
nullptr);
1571 if (std::any_of(std::begin(c->group_all), std::end(c->group_all), [](
const GroupStatistics &gs) { return gs.num_vehicle != 0; })) has_vehicles.Set(c->index);
1578 if (c->is_ai)
continue;
1580 if (!has_clients.Test(c->index)) {
1582 if (c->months_empty != std::numeric_limits<
decltype(c->months_empty)>::max()) c->months_empty++;
1598 c->months_empty = 0;
1610 bool is_name_unique =
false;
1611 std::string original_name = name;
1613 for (uint number = 1; !is_name_unique && number <=
MAX_CLIENTS; number++) {
1614 is_name_unique =
true;
1616 if (ci->client_name == name) {
1618 is_name_unique =
false;
1624 if (ci !=
nullptr) {
1625 if (ci->
client_name == name) is_name_unique =
false;
1628 if (!is_name_unique) {
1630 name = fmt::format(
"{} #{}", original_name, number);
1638 return is_name_unique;
1651 if (ci->client_name.compare(new_name) == 0)
return false;
1655 if (ci ==
nullptr)
return false;
1671 for (
auto &cp : cs->outgoing_queue) cs->SendCommand(cp);
1672 cs->outgoing_queue.clear();
1681#ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
1682 bool send_sync =
false;
1685#ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
1694 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1701 uint lag = NetworkCalculateLag(cs);
1702 switch (cs->status) {
1703 case NetworkClientSocket::STATUS_ACTIVE:
1707 if (cs->last_packet + std::chrono::milliseconds(lag *
MILLISECONDS_PER_TICK) > std::chrono::steady_clock::now()) {
1709 IConsolePrint(
CC_WARNING,
"Client #{} (IP: {}) is dropped because the client's game state is more than {} ticks behind.", cs->client_id, cs->GetClientIP(), lag);
1712 IConsolePrint(
CC_WARNING,
"Client #{} (IP: {}) is dropped because the client did not respond for more than {} ticks.", cs->client_id, cs->GetClientIP(), lag);
1714 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
1723 if (lag > (uint)
Ticks::DAY_TICKS && cs->lag_test == 0 && cs->last_packet + std::chrono::seconds(2) > std::chrono::steady_clock::now()) {
1730 IConsolePrint(
CC_WARNING,
"Client #{} (IP: {}) is dropped because it fails to send valid acks.", cs->client_id, cs->GetClientIP());
1731 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
1736 case NetworkClientSocket::STATUS_INACTIVE:
1737 case NetworkClientSocket::STATUS_IDENTIFY:
1738 case NetworkClientSocket::STATUS_NEWGRFS_CHECK:
1739 case NetworkClientSocket::STATUS_AUTHORIZED:
1744 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
1749 case NetworkClientSocket::STATUS_MAP_WAIT:
1753 if (std::chrono::steady_clock::now() > cs->last_packet + std::chrono::seconds(2)) {
1760 cs->last_packet = std::chrono::steady_clock::now();
1764 case NetworkClientSocket::STATUS_MAP:
1768 cs->SendError(NETWORK_ERROR_TIMEOUT_MAP);
1773 case NetworkClientSocket::STATUS_DONE_MAP:
1774 case NetworkClientSocket::STATUS_PRE_ACTIVE:
1778 cs->SendError(NETWORK_ERROR_TIMEOUT_JOIN);
1783 case NetworkClientSocket::STATUS_AUTH_GAME:
1787 cs->SendError(NETWORK_ERROR_TIMEOUT_PASSWORD);
1792 case NetworkClientSocket::STATUS_END:
1797 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) {
1802 if (send_frame) cs->SendFrame();
1804#ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
1806 if (send_sync) cs->SendSync();
1927 static const std::string_view stat_str[] = {
1930 "identifying client",
1939 static_assert(
lengthof(stat_str) == NetworkClientSocket::STATUS_END);
1941 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1943 if (ci ==
nullptr)
continue;
1944 uint lag = NetworkCalculateLag(cs);
1946 std::string_view status = (cs->status < (ptrdiff_t)
lengthof(stat_str) ? stat_str[cs->status] :
"unknown");
1959 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1960 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendConfigUpdate();
1982 assert(ci !=
nullptr);
1992 NetworkClientSocket *cs = NetworkClientSocket::GetByClientID(client_id);
1994 if (cs->status < NetworkClientSocket::STATUS_AUTHORIZED)
return;
1995 cs->SendMove(client_id, company_id);
2006 std::string company_name =
GetString(STR_COMPANY_NAME, company_id);
2021 NetworkClientSocket::GetByClientID(client_id)->SendRConResult(colour_code,
string);
2032 NetworkClientSocket::GetByClientID(client_id)->SendError(NETWORK_ERROR_KICKED, reason);
2056 bool contains =
false;
2073 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
2076 if (cs->client_address.IsInNetmask(ip)) {
2093 if (ci->client_playas == company)
return true;
2109 return fmt::format(
"Client #{}", this->
client_id);
2123 ci->client_id ==
CLIENT_ID_SERVER ?
"server" : NetworkClientSocket::GetByClientID(ci->client_id)->GetClientIP());
2140 auto socket = NetworkClientSocket::GetByClientID(client_id);
2141 return socket ==
nullptr ?
"" : socket->GetPeerPublicKey();
2152 assert(c !=
nullptr);
2156 if (ci !=
nullptr) {
std::map< SOCKET, NetworkAddress > SocketList
Type for a mapping between address and socket.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Timpl & Set()
Set all bits.
An interval timer will fire every interval, and will continue to fire until it is deleted.
void SetInterval(const TPeriod interval, bool reset=true)
Set a new interval for the timer.
const std::string & GetHostname()
Get the hostname; in case it wasn't given the IPv4 dotted representation is given.
Default implementation for the authorized key handler.
bool IsAllowed(std::string_view peer_public_key) const override
Check whether the given public key of the peer is allowed in.
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.
Base socket handler for all TCP sockets.
uint32_t last_frame
Last frame we have executed.
NetworkClientInfo * GetInfo() const
Gets the client info of this socket handler.
std::optional< std::string_view > ReceiveCommand(Packet &p, CommandPacket &cp)
Receives a command from the network.
ClientID client_id
Client identifier.
CommandQueue incoming_queue
The command-queue awaiting handling.
std::chrono::steady_clock::time_point last_packet
Time we received the last frame.
void SetInfo(NetworkClientInfo *info)
Sets the client info for this socket handler.
uint32_t last_frame_server
Last frame the server has executed.
NetworkClientInfo * info
Client info related to this socket.
void SendCommand(Packet &p, const CommandPacket &cp)
Sends a command over the network.
bool HasClientQuit() const
Whether the current client connected to the socket has quit.
std::unique_ptr< class NetworkEncryptionHandler > send_encryption_handler
The handler for encrypting sent packets.
std::unique_ptr< class NetworkEncryptionHandler > receive_encryption_handler
The handler for decrypting received packets.
virtual std::unique_ptr< Packet > ReceivePacket()
Receives a packet for the given client.
SOCKET sock
The socket currently connected to.
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.
SendPacketsState SendPackets(bool closing_down=false)
Sends all the buffered packets out for this client.
A sort-of mixin that adds 'at(pos)' and 'operator[](pos)' implementations for 'ConvertibleThroughBase...
Class for handling the server side of the game connection.
NetworkRecvStatus Receive_CLIENT_SET_NAME(Packet &p) override
Gives the client a new name: string New name of the client.
static std::string_view GetName()
Get the name used by the listener.
size_t receive_limit
Amount of bytes that we can receive at this moment.
std::shared_ptr< struct PacketWriter > savegame
Writer used to write the savegame.
static void Send()
Send the packets for the server sockets.
NetworkRecvStatus Receive_CLIENT_MOVE(Packet &p) override
Request the server to move this client into another company: uint8_t ID of the company the client wan...
NetworkRecvStatus SendQuit(ClientID client_id)
Tell the client another client quit.
NetworkRecvStatus Receive_CLIENT_ACK(Packet &p) override
Tell the server we are done with this frame: uint32_t Current frame counter of the client.
NetworkRecvStatus Receive_CLIENT_AUTH_RESPONSE(Packet &p) override
Send the response to the authentication request: 32 * uint8_t Public key of the client.
std::unique_ptr< Packet > ReceivePacket() override
Receives a packet for the given client.
@ STATUS_PRE_ACTIVE
The client is catching up the delayed frames.
@ STATUS_IDENTIFY
The client is identifying itself.
@ STATUS_AUTH_GAME
The client is authorizing with game (server) password.
@ STATUS_NEWGRFS_CHECK
The client is checking NewGRFs.
@ STATUS_AUTHORIZED
The client is authorized.
@ STATUS_INACTIVE
The client is not connected nor active.
@ STATUS_MAP
The client is downloading the map.
@ STATUS_DONE_MAP
The client has downloaded the map.
@ STATUS_ACTIVE
The client is active within in the game.
@ STATUS_MAP_WAIT
The client is waiting as someone else is downloading the map.
NetworkRecvStatus Receive_CLIENT_COMMAND(Packet &p) override
The client has done a command and wants us to handle it.
NetworkRecvStatus SendRConResult(uint16_t colour, std::string_view command)
Send the result of a console action.
NetworkRecvStatus Receive_CLIENT_QUIT(Packet &p) override
The client is quitting the game.
NetworkRecvStatus SendChat(NetworkAction action, ClientID client_id, bool self_send, std::string_view msg, int64_t data)
Send a chat message.
NetworkRecvStatus SendWelcome()
Send the client a welcome message with some basic information.
NetworkRecvStatus SendAuthRequest()
Request the game password.
~ServerNetworkGameSocketHandler()
Clear everything related to this client.
std::string GetClientName() const
Get the name of the client, if the user did not send it yet, Client ID is used.
uint8_t last_token
The last random token we did send to verify the client is listening.
NetworkRecvStatus SendFrame()
Tell the client that they may run to a particular frame.
NetworkRecvStatus Receive_CLIENT_ERROR(Packet &p) override
The client made an error and is quitting the game.
NetworkRecvStatus SendGameInfo()
Send the client information about the server.
NetworkRecvStatus SendJoin(ClientID client_id)
Tell that a client joined.
std::string peer_public_key
The public key of our client.
NetworkRecvStatus Receive_CLIENT_CHAT(Packet &p) override
Sends a chat-packet to the server: uint8_t ID of the action (see NetworkAction).
NetworkRecvStatus SendClientInfo(NetworkClientInfo *ci)
Send the client information about a client.
static bool AllowConnection()
Whether an connection is allowed or not at this moment.
NetworkRecvStatus SendEnableEncryption()
Notify the client that the authentication has completed and tell that for the remainder of this socke...
NetworkRecvStatus Receive_CLIENT_JOIN(Packet &p) override
Try to join the server: string OpenTTD revision (norev0000 if no revision).
NetworkRecvStatus Receive_CLIENT_GAME_INFO(Packet &p) override
Request game information.
NetworkRecvStatus SendExternalChat(std::string_view source, TextColour colour, std::string_view user, std::string_view msg)
Send a chat message from external source.
NetworkRecvStatus SendErrorQuit(ClientID client_id, NetworkErrorCode errorno)
Tell the client another client quit with an error.
NetworkAddress client_address
IP-address of the client (so they can be banned)
NetworkRecvStatus SendNewGame()
Tell the client we're starting a new game.
NetworkRecvStatus Receive_CLIENT_GETMAP(Packet &p) override
Request the map from the server.
NetworkRecvStatus SendSync()
Request the client to sync.
std::unique_ptr< class NetworkAuthenticationServerHandler > authentication_handler
The handler for the authentication.
NetworkRecvStatus SendMove(ClientID client_id, CompanyID company_id)
Tell that a client moved to another company.
NetworkRecvStatus Receive_CLIENT_RCON(Packet &p) override
Send an RCon command to the server: string RCon password.
NetworkRecvStatus SendError(NetworkErrorCode error, std::string_view reason={})
Send an error to the client, and close its connection.
ServerNetworkGameSocketHandler(SOCKET s)
Create a new socket for the server side of the game connection.
NetworkRecvStatus Receive_CLIENT_IDENTIFY(Packet &p) override
The client tells the server about the identity of the client: string Name of the client (max NETWORK_...
NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override
Close the network connection due to the given status.
NetworkRecvStatus SendMap()
This sends the map to the client.
NetworkRecvStatus Receive_CLIENT_NEWGRFS_CHECKED(Packet &p) override
Tell the server that we have the required GRFs.
uint32_t last_token_frame
The last frame we received the right token.
NetworkRecvStatus Receive_CLIENT_MAP_OK(Packet &p) override
Tell the server that we are done receiving/loading the map.
NetworkRecvStatus SendShutdown()
Tell the client we're shutting down.
ClientStatus status
Status of this client.
NetworkRecvStatus SendNewGRFCheck()
Send the check for the NewGRFs.
std::string_view GetClientIP()
Get the IP address/hostname of the connected client.
NetworkRecvStatus SendConfigUpdate()
Send an update about the max company/spectator counts.
NetworkRecvStatus SendWait()
Tell the client that its put in a waiting queue.
NetworkRecvStatus SendCommand(const CommandPacket &cp)
Send a command to the client to execute.
Template for TCP listeners.
static constexpr TimerGameTick::Ticks DAY_TICKS
1 day is 74 ticks; TimerGameCalendar::date_fract used to be uint16_t and incremented by 885.
static Year year
Current year, starting at 0.
static Date date
Current date in days (day counter).
static DateFract date_fract
Fractional part of the day.
@ UNPAUSED
Only run when not paused.
CommandFlags GetCommandFlags(Commands cmd)
This function mask the parameter with CMD_ID_MASK and returns the flags which belongs to the given co...
@ Spectator
the command may be initiated by a spectator
@ Server
the command can only be initiated by the server
@ ClientID
set p2 with the ClientID of the sending client.
@ CMD_COMPANY_CTRL
used in multiplayer to create a new companies etc.
@ CMD_COMPANY_ALLOW_LIST_CTRL
Used in multiplayer to add/remove a client's public key to/from the company's allow list.
TextColour GetDrawStringCompanyColour(CompanyID company)
Get the colour for DrawString-subroutines which matches the colour of the company.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
void SetLocalCompany(CompanyID new_company)
Sets the local company and updates the settings that are set on a per-company basis to reflect the co...
CompanyCtrlAction
The action to do with CMD_COMPANY_CTRL.
@ CCA_DELETE
Delete a company.
@ CCA_NEW
Create a new company.
static constexpr CompanyID COMPANY_SPECTATOR
The client is spectating.
@ CALCA_ADD
Create a public key.
static constexpr CompanyID COMPANY_NEW_COMPANY
The client wants a new company.
@ CRR_AUTOCLEAN
The company is removed due to autoclean.
static const size_t TCP_MTU
Number of bytes we can pack in a single TCP packet.
static const uint NETWORK_CLIENT_NAME_LENGTH
The maximum length of a client's name, in bytes including '\0'.
static const uint NETWORK_CHAT_LENGTH
The maximum length of a chat message, in bytes including '\0'.
static const uint NETWORK_REVISION_LENGTH
The maximum length of the revision, in bytes including '\0'.
static const uint NETWORK_RCONCOMMAND_LENGTH
The maximum length of a rconsole command, in bytes including '\0'.
static const uint NETWORK_PASSWORD_LENGTH
The maximum length of the password, in bytes including '\0'.
void IConsoleCmdExec(std::string_view command_string, const uint recurse_count)
Execute a given command passed to us.
void IConsolePrint(TextColour colour_code, const std::string &string)
Handle the printing of text entered into the console or redirected there by any other means.
static const TextColour CC_INFO
Colour for information lines.
static const TextColour CC_WARNING
Colour for warning lines.
static const TextColour CC_DEFAULT
Default colour of the console.
NetworkRecvStatus
Status of a network client; reasons why a client has quit.
@ NETWORK_RECV_STATUS_CLIENT_QUIT
The connection is lost gracefully. Other clients are already informed of this leaving client.
@ NETWORK_RECV_STATUS_SERVER_ERROR
The server told us we made an error.
@ NETWORK_RECV_STATUS_OKAY
Everything is okay.
@ NETWORK_RECV_STATUS_MALFORMED_PACKET
We apparently send a malformed packet.
#define Debug(category, level, format_string,...)
Output a line of debugging information.
#define DECLARE_INCREMENT_DECREMENT_OPERATORS(enum_type)
For some enums it is useful to have pre/post increment/decrement operators.
@ FT_SCENARIO
old or new scenario
@ FT_HEIGHTMAP
heightmap file
@ FT_SAVEGAME
old or new savegame
static const uint32_t GENERATE_NEW_SEED
Create a new random seed.
SwitchMode _switch_mode
The next mainloop command.
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
static const uint MILLISECONDS_PER_TICK
The number of milliseconds per game tick.
uint32_t _last_sync_frame
Used in the server to store the last time a sync packet was sent to clients.
StringID GetNetworkErrorMsg(NetworkErrorCode err)
Retrieve the string id of an internal error number.
ClientID _redirect_console_to_client
If not invalid, redirect the console output to a client.
uint32_t _frame_counter
The current frame.
StringList _network_ban_list
The banned clients.
bool _network_dedicated
are we a dedicated server?
bool _network_server
network-server is active
uint32_t _sync_seed_1
Seed to compare during sync checks.
uint8_t _network_clients_connected
The amount of clients connected.
uint32_t _frame_counter_max
To where we may go with our clients.
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 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 NetworkAdminClientError(ClientID client_id, NetworkErrorCode error_code)
Notify the admin network of a client error (if they have opt in for the respective update).
Server part of the admin network protocol.
Base core network types and some helper functions to access them.
bool NetworkIsValidClientName(std::string_view client_name)
Check whether the given client name is deemed valid for use in network games.
void NetworkSyncCommandQueue(NetworkClientSocket *cs)
Sync our local command queue to the command queue of the given socket.
void NetworkReplaceCommandClientId(CommandPacket &cp, ClientID client_id)
Insert a client ID into the command data in a command packet.
NetworkAuthenticationMethod
The authentication method that can be used.
@ X25519_PAKE
Authentication using x25519 password-authenticated key agreement.
@ X25519_AuthorizedKey
Authentication using x22519 key exchange and authorized keys.
void NetworkUpdateClientInfo(ClientID client_id)
Send updated client info of a particular client.
void NetworkServerDoMove(ClientID client_id, CompanyID company_id)
Handle the tid-bits of moving a client from one company to another.
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.
bool NetworkMakeClientNameUnique(std::string &new_name)
Check whether a name is unique, and otherwise try to make it unique.
bool NetworkServerChangeClientName(ClientID client_id, const std::string &new_name)
Change the client name of the given client.
void NetworkServerSendExternalChat(std::string_view source, TextColour colour, std::string_view user, std::string_view msg)
Send a chat message from external source.
void NetworkPrintClients()
Print all the clients to the console.
void NetworkServerUpdateGameInfo()
Update the server's NetworkServerGameInfo due to changes in settings.
NetworkCompanyStatsArray NetworkGetCompanyStats()
Get the company stats.
void NetworkUpdateClientInfo(ClientID client_id)
Send updated client info of a particular client.
void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, std::string_view msg, ClientID from_id, int64_t data, bool from_admin)
Send an actual chat message.
static NetworkAuthenticationDefaultAuthorizedKeyHandler _rcon_authorized_key_handler(_settings_client.network.rcon_authorized_keys)
Provides the authorized key validation for rcon.
static NetworkAuthenticationDefaultPasswordProvider _password_provider(_settings_client.network.server_password)
Provides the password validation for the game's password.
void NetworkServerSendConfigUpdate()
Send Config Update.
static const IntervalTimer< TimerGameEconomy > _network_weekly({TimerGameEconomy::WEEK, TimerGameEconomy::Priority::NONE}, [](auto) { if(!_network_server) return;NetworkAdminUpdate(AdminUpdateFrequency::Weekly);})
Economy weekly "callback".
void NetworkServerDoMove(ClientID client_id, CompanyID company_id)
Handle the tid-bits of moving a client from one company to another.
void ChangeNetworkRestartTime(bool reset)
Reset the automatic network restart time interval.
bool NetworkCompanyHasClients(CompanyID company)
Check whether a particular company has clients.
static void NetworkRestartMap()
Helper function to restart the map.
void NetworkServerKickClient(ClientID client_id, std::string_view reason)
Kick a single client.
static void NetworkCheckRestartMapYear()
Check if we want to restart the map based on the year.
bool NetworkMakeClientNameUnique(std::string &name)
Check whether a name is unique, and otherwise try to make it unique.
static ClientID _network_client_id
The identifier counter for new clients (is never decreased)
std::string_view NetworkGetPublicKeyOfClient(ClientID client_id)
Get the public key of the client with the given id.
static NetworkAuthenticationDefaultAuthorizedKeyHandler _authorized_key_handler(_settings_client.network.server_authorized_keys)
Provides the authorized key handling for the game authentication.
static const IntervalTimer< TimerGameEconomy > _economy_network_daily({TimerGameEconomy::DAY, TimerGameEconomy::Priority::NONE}, [](auto) { if(!_network_server) return;NetworkAdminUpdate(AdminUpdateFrequency::Daily);})
Daily "callback".
static void NetworkHandleCommandQueue(NetworkClientSocket *cs)
Handle the command-queue of a socket.
static const IntervalTimer< TimerGameCalendar > _calendar_network_yearly({ TimerGameCalendar::YEAR, TimerGameCalendar::Priority::NONE }, [](auto) { if(!_network_server) return;NetworkCheckRestartMapYear();})
Calendar yearly "callback".
static const IntervalTimer< TimerGameEconomy > _network_quarterly({TimerGameEconomy::QUARTER, TimerGameEconomy::Priority::NONE}, [](auto) { if(!_network_server) return;NetworkAutoCleanCompanies();NetworkAdminUpdate(AdminUpdateFrequency::Quarterly);})
Quarterly "callback".
void NetworkServerShowStatusToConsole()
Show the status message of all clients on the console.
void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci)
Perform all the server specific administration of a new company.
void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, std::string_view string)
Send an rcon reply to the client.
uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, std::string_view reason)
Ban, or kick, everyone joined from the given client's IP.
void NetworkServer_Tick(bool send_frame)
This is called every tick if this is a _network_server.
NetworkClientSocketPool _networkclientsocket_pool("NetworkClientSocket")
Make very sure the preconditions given in network_type.h are actually followed.
static IntervalTimer< TimerGameRealtime > _network_restart_map_timer({std::chrono::hours::zero(), TimerGameRealtime::UNPAUSED}, [](auto) { if(!_network_server) return;if(_settings_client.network.restart_hours==0) return;Debug(net, 3, "Auto-restarting map: {} hours played", _settings_client.network.restart_hours);NetworkRestartMap();})
Timer to restart a network server automatically based on real-time hours played.
static const IntervalTimer< TimerGameEconomy > _network_monthly({TimerGameEconomy::MONTH, TimerGameEconomy::Priority::NONE}, [](auto) { if(!_network_server) return;NetworkAutoCleanCompanies();NetworkAdminUpdate(AdminUpdateFrequency::Monthly);})
Economy monthly "callback".
static void NetworkAutoCleanCompanies()
Remove companies that have not been used depending on the autoclean_companies setting and values for ...
static const IntervalTimer< TimerGameEconomy > _economy_network_yearly({TimerGameEconomy::YEAR, TimerGameEconomy::Priority::NONE}, [](auto) { if(!_network_server) return;NetworkAdminUpdate(AdminUpdateFrequency::Annually);})
Economy yearly "callback".
Server part of the network protocol.
DestType
Destination of our chat messages.
@ DESTTYPE_CLIENT
Send message/notice to only a certain client (Private)
@ DESTTYPE_TEAM
Send message/notice to everyone playing the same company (Team)
@ DESTTYPE_BROADCAST
Send message/notice to all clients (All)
NetworkErrorCode
The error codes we send around in the protocols.
NetworkAction
Actions that can be used for NetworkTextMessage.
static const uint MAX_CLIENTS
How many clients can we have.
ClientID
'Unique' identifier to be given to clients
@ INVALID_CLIENT_ID
Client is not part of anything.
@ CLIENT_ID_SERVER
Servers always have this ID.
@ CLIENT_ID_FIRST
The first client ID.
Sending and receiving UDP messages.
GRFConfigList _grfconfig
First item in list of current GRF set up.
@ Static
GRF file is used statically (can be used in any MP game)
@ SM_START_HEIGHTMAP
Load a heightmap and start a new game from it.
@ SM_LOAD_GAME
Load game, Play Scenario.
@ SM_NEWGAME
New Game --> 'Random game'.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
void SlError(StringID string, const std::string &extra_msg)
Error handler.
SaveOrLoadResult SaveWithFilter(std::shared_ptr< SaveFilter > writer, bool threaded)
Save the game using a (writer) filter.
FileToSaveLoad _file_to_saveload
File to save or load in the openttd loop.
@ SL_OK
completed successfully
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
ClientSettings _settings_client
The current settings for this game.
@ Dock
Station with a dock.
@ TruckStop
Station with truck stops.
@ Train
Station with train station.
@ Airport
Station with an airport.
@ BusStop
Station with bus stops.
#define lengthof(array)
Return the length of an fixed size array.
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
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
bool my_cmd
did the command originate from "me"
Commands cmd
command being executed.
Defines the traits of a command.
uint8_t months_empty
NOSAVE: Number of months this company has not had a client in multiplayer.
static bool IsValidHumanID(auto index)
Is this company a valid company, not controlled by a NoAI program?
AbstractFileType abstract
Abstract file type.
uint32_t generation_seed
noise seed for world generation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Statistics and caches on the vehicles in a group.
Container for all information known about a client.
static NetworkClientInfo * GetByClientID(ClientID client_id)
Return the CI given it's client-identifier.
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.
std::string public_key
The public key of the client.
Simple calculated statistics of a company.
uint16_t num_station[NETWORK_VEH_END]
How many stations are there of this type?
uint8_t clients_on
Current count of clients on server.
uint8_t max_clients
maximum amount of clients
uint16_t bytes_per_frame_burst
how many bytes may, over a short period, be received?
bool autoclean_companies
automatically remove companies that are not in use
bool server_admin_chat
allow private chat for the server to be distributed to the admin network
TimerGameCalendar::Year restart_game_year
year the server restarts
uint8_t max_companies
maximum amount of companies
uint8_t autoclean_protected
Remove companies after this many months.
uint16_t max_password_time
maximum amount of time, in game ticks, a client may take to enter the password
uint16_t max_join_time
maximum amount of time, in game ticks, a client may take to sync up during joining
uint16_t bytes_per_frame
how many bytes may, over a long period, be received per frame?
uint16_t max_init_time
maximum amount of time, in game ticks, a client may take to initiate joining
uint16_t max_lag_time
maximum amount of time, in game ticks, a client may be lagging behind the server
uint8_t autoclean_novehicles
remove companies with no vehicles after this many months
uint16_t max_commands_in_queue
how many commands may there be in the incoming queue before dropping the connection?
std::string server_name
name of the server
uint16_t restart_hours
number of hours to run the server before automatic restart
uint16_t max_download_time
maximum amount of time, in game ticks, a client may take to download the map
uint16_t sync_freq
how often do we check whether we are still in-sync
std::string rcon_password
password for rconsole (server side)
static void ResetUser(uint32_t user)
Reset an user's OrderBackup if needed.
Writing a savegame directly to a number of packets.
void Write(uint8_t *buf, size_t size) override
Write a given number of bytes into the savegame.
std::unique_ptr< Packet > current
The packet we're currently writing to.
PacketWriter(ServerNetworkGameSocketHandler *cs)
Create the packet writer.
size_t total_size
Total size of the compressed savegame.
std::condition_variable exit_sig
Signal for threaded destruction of this packet writer.
void Finish() override
Prepare everything to finish writing the savegame.
ServerNetworkGameSocketHandler * cs
Socket we are associated with.
std::mutex mutex
Mutex for making threaded saving safe.
void Destroy()
Begin the destruction of this packet writer.
bool TransferToNetworkQueue()
Transfer all packets from here to the network's queue while holding the lock on our mutex.
~PacketWriter()
Make sure everything is cleaned up.
std::deque< std::unique_ptr< Packet > > packets
Packet queue of the savegame; send these "slowly" to the client. Cannot be a std::queue as we want to...
Internal entity of a packet.
uint64_t Recv_uint64()
Read a 64 bits integer from the packet.
uint32_t Recv_uint32()
Read a 32 bits integer from the packet.
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...
uint8_t Recv_uint8()
Read a 8 bits integer from the packet.
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.
static size_t GetNumItems()
Returns number of valid items in the pool.
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 bool IsValidID(auto index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
static Titem * GetIfValid(auto index)
Returns Titem with given index.
Base class for all pools.
static constexpr size_t MAX_SIZE
Make template parameter accessible from outside.
Interface for filtering a savegame till it is written.
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
static T * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
@ SPS_CLOSED
The connection got closed.
@ Annually
The admin gets information about this on a yearly basis.
@ Weekly
The admin gets information about this on a weekly basis.
@ Monthly
The admin gets information about this on a monthly basis.
@ Quarterly
The admin gets information about this on a quarterly basis.
@ Daily
The admin gets information about this on a daily basis.
@ PACKET_SERVER_JOIN
Tells clients that a new client has joined.
@ PACKET_SERVER_MAP_SIZE
Server tells the client what the (compressed) size of the map is.
@ PACKET_SERVER_RCON
Response of the executed command on the server.
@ PACKET_SERVER_MAP_BEGIN
Server tells the client that it is beginning to send the map.
@ PACKET_SERVER_SYNC
Server tells the client what the random state should be.
@ PACKET_SERVER_WAIT
Server tells the client there are some people waiting for the map as well.
@ PACKET_SERVER_CONFIG_UPDATE
Some network configuration important to the client changed.
@ PACKET_SERVER_ENABLE_ENCRYPTION
The server tells that authentication has completed and requests to enable encryption with the keys of...
@ PACKET_SERVER_GAME_INFO
Information about the server.
@ PACKET_SERVER_ERROR_QUIT
A server tells that a client has hit an error and did quit.
@ PACKET_SERVER_CLIENT_INFO
Server sends you information about a client.
@ PACKET_SERVER_WELCOME
Server welcomes you and gives you your ClientID.
@ PACKET_SERVER_BANNED
The server has banned you.
@ PACKET_SERVER_FRAME
Server tells the client what frame it is in, and thus to where the client may progress.
@ PACKET_SERVER_EXTERNAL_CHAT
Server distributing the message from external source.
@ PACKET_SERVER_CHAT
Server distributing the message of a client (or itself).
@ PACKET_SERVER_COMMAND
Server distributes a command to (all) the clients.
@ PACKET_SERVER_SHUTDOWN
The server is shutting down.
@ PACKET_SERVER_AUTH_REQUEST
The server requests the client to authenticate using a number of methods.
@ PACKET_SERVER_NEWGAME
The server is preparing to start a new game.
@ PACKET_SERVER_MOVE
Server tells everyone that someone is moved to another company.
@ PACKET_SERVER_MAP_DATA
Server sends bits of the map to the client.
@ PACKET_SERVER_FULL
The server is full and has no place for you.
@ PACKET_SERVER_QUIT
A server tells that a client has quit.
@ PACKET_SERVER_ERROR
Server sending an error message to the client.
@ PACKET_SERVER_CHECK_NEWGRFS
Server sends NewGRF IDs and MD5 checksums for the client to check.
@ PACKET_SERVER_MAP_DONE
Server tells it has just sent the last bits of the map to the client.
@ VEH_ROAD
Road vehicle type.
@ VEH_AIRCRAFT
Aircraft vehicle type.
@ VEH_SHIP
Ship vehicle type.
@ VEH_TRAIN
Train vehicle type.
std::mutex lock
synchronization for playback status fields
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
@ WC_CLIENT_LIST
Client list; Window numbers: