Go to the documentation of this file.
10 #include "../stdafx.h"
11 #include "../strings_func.h"
12 #include "../date_func.h"
18 #include "../console_func.h"
19 #include "../company_base.h"
20 #include "../command_func.h"
21 #include "../saveload/saveload.h"
22 #include "../saveload/saveload_filter.h"
23 #include "../station_base.h"
24 #include "../genworld.h"
25 #include "../company_func.h"
26 #include "../company_gui.h"
27 #include "../roadveh.h"
28 #include "../order_backup.h"
29 #include "../core/pool_func.hpp"
30 #include "../core/random_func.hpp"
33 #include <condition_variable>
35 #include "../safeguards.h"
76 std::unique_lock<std::mutex>
lock(this->mutex);
78 if (this->cs !=
nullptr) this->exit_sig.wait(
lock);
82 while (this->packets !=
nullptr) {
103 std::unique_lock<std::mutex>
lock(this->mutex);
107 this->exit_sig.notify_all();
126 return this->packets !=
nullptr;
134 std::lock_guard<std::mutex>
lock(this->mutex);
136 Packet *p = this->packets;
137 this->packets = p->
next;
146 if (this->current ==
nullptr)
return;
148 Packet **p = &this->packets;
149 while (*p !=
nullptr) {
154 this->current =
nullptr;
160 if (this->current ==
nullptr)
return;
162 this->current->
next = this->packets;
163 this->packets = this->current;
164 this->current =
nullptr;
167 void Write(
byte *buf,
size_t size)
override
170 if (this->cs ==
nullptr)
SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
174 std::lock_guard<std::mutex>
lock(this->mutex);
176 byte *bufe = buf + size;
177 while (buf != bufe) {
178 size_t to_write = std::min<size_t>(
SEND_MTU - this->current->
size, bufe - buf);
179 memcpy(this->current->
buffer + this->current->size, buf, to_write);
189 this->total_size += size;
195 if (this->cs ==
nullptr)
SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
197 std::lock_guard<std::mutex>
lock(this->mutex);
208 this->current->
Send_uint32((uint32)this->total_size);
209 this->PrependQueue();
267 if (this->
sock == INVALID_SOCKET)
return status;
275 NetworkTextMessage(NETWORK_ACTION_LEAVE,
CC_DEFAULT,
false, client_name,
nullptr, STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST);
278 for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
280 new_cs->SendErrorQuit(this->
client_id, NETWORK_ERROR_CONNECTION_LOST);
292 this->CheckNextClientToSendMap(
this);
333 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
390 memset(clients, 0,
sizeof(clients));
398 for (NetworkClientSocket *csi : NetworkClientSocket::Iterate()) {
424 if (
StrEmpty(clients[company->index])) {
457 GetString(str, strid,
lastof(str));
465 DEBUG(net, 1,
"'%s' made an error and has been disconnected. Reason: '%s'", client_name, str);
467 if (
error == NETWORK_ERROR_KICKED && reason !=
nullptr) {
468 NetworkTextMessage(NETWORK_ACTION_KICKED,
CC_DEFAULT,
false, client_name, reason, strid);
470 NetworkTextMessage(NETWORK_ACTION_LEAVE,
CC_DEFAULT,
false, client_name,
nullptr, strid);
473 for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
477 if (
error == NETWORK_ERROR_NOT_AUTHORIZED ||
error == NETWORK_ERROR_NOT_EXPECTED ||
error == NETWORK_ERROR_WRONG_REVISION) {
478 error = NETWORK_ERROR_ILLEGAL_PACKET;
480 new_cs->SendErrorQuit(this->
client_id, error);
486 DEBUG(net, 1,
"Client %d made an error and has been disconnected. Reason: '%s'", this->
client_id, str);
566 for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
582 for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
584 if (new_cs->GetInfo()->join_date < this->GetInfo()->join_date || (new_cs->GetInfo()->join_date == this->GetInfo()->join_date && new_cs->client_id < this->client_id)) waiting++;
593 void ServerNetworkGameSocketHandler::CheckNextClientToSendMap(NetworkClientSocket *ignore_cs)
596 NetworkClientSocket *best =
nullptr;
597 for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
598 if (ignore_cs == new_cs)
continue;
601 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)) {
608 if (best !=
nullptr) {
614 for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
623 static uint16 sent_packets;
627 return this->
SendError(NETWORK_ERROR_NOT_AUTHORIZED);
652 bool has_packets =
false;
654 for (uint i = 0; (has_packets = this->
savegame->
HasPackets()) && i < sent_packets; i++) {
675 this->CheckNextClientToSendMap();
684 if (has_packets && sent_packets < std::numeric_limits<decltype(sent_packets)>::max() / 2) {
695 if (sent_packets > 1) sent_packets /= 2;
722 #ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
724 #ifdef NETWORK_SEND_DOUBLE_SEED
731 this->
last_token = InteractiveRandomRange(UINT8_MAX - 1) + 1;
746 #ifdef NETWORK_SEND_DOUBLE_SEED
909 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
930 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
938 p->
Recv_string(client_revision,
sizeof(client_revision));
944 return this->
SendError(NETWORK_ERROR_WRONG_REVISION);
957 return this->
SendError(NETWORK_ERROR_FULL);
962 return this->
SendError(NETWORK_ERROR_FULL);
967 return this->
SendError(NETWORK_ERROR_COMPANY_MISMATCH);
977 return this->
SendError(NETWORK_ERROR_NAME_IN_USE);
1005 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1015 return this->
SendError(NETWORK_ERROR_WRONG_PASSWORD);
1030 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1043 return this->
SendError(NETWORK_ERROR_WRONG_PASSWORD);
1053 if (this->status < STATUS_AUTHORIZED || this->
HasClientQuit()) {
1054 return this->
SendError(NETWORK_ERROR_NOT_AUTHORIZED);
1058 for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
1078 NetworkTextMessage(NETWORK_ACTION_JOIN,
CC_DEFAULT,
false, client_name,
nullptr, this->
client_id);
1092 for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
1094 new_cs->SendClientInfo(this->
GetInfo());
1109 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1120 if (this->status < STATUS_DONE_MAP || this->
HasClientQuit()) {
1121 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1125 return this->
SendError(NETWORK_ERROR_TOO_MANY_COMMANDS);
1135 if (err !=
nullptr) {
1137 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1143 return this->
SendError(NETWORK_ERROR_KICKED);
1148 return this->
SendError(NETWORK_ERROR_KICKED);
1157 IConsolePrintF(
CC_ERROR,
"WARNING: client %d (IP: %s) tried to execute a command as company %d, kicking...",
1159 return this->
SendError(NETWORK_ERROR_COMPANY_MISMATCH);
1164 return this->
SendError(NETWORK_ERROR_CHEATER);
1189 if (this->status < STATUS_DONE_MAP || this->
HasClientQuit()) {
1196 GetString(str, strid,
lastof(str));
1198 DEBUG(net, 2,
"'%s' reported an error and is closing its connection (%s)", client_name, str);
1200 NetworkTextMessage(NETWORK_ACTION_LEAVE,
CC_DEFAULT,
false, client_name,
nullptr, strid);
1202 for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
1204 new_cs->SendErrorQuit(this->
client_id, errorno);
1220 if (this->status < STATUS_DONE_MAP || this->
HasClientQuit()) {
1226 NetworkTextMessage(NETWORK_ACTION_LEAVE,
CC_DEFAULT,
false, client_name,
nullptr, STR_NETWORK_MESSAGE_CLIENT_LEAVING);
1228 for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
1243 return this->
SendError(NETWORK_ERROR_NOT_AUTHORIZED);
1305 if (ci !=
nullptr) {
1314 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1315 if (cs->client_id == (
ClientID)dest) {
1316 cs->SendChat(action, from_id,
false, msg, data);
1327 if (ci !=
nullptr && ci_to !=
nullptr) {
1331 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1332 if (cs->client_id == from_id) {
1333 cs->SendChat(action, (
ClientID)dest,
true, msg, data);
1342 bool show_local =
true;
1345 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1348 cs->SendChat(action, from_id,
false, msg, data);
1349 if (cs->client_id == from_id) show_local =
false;
1361 if (ci !=
nullptr && ci_own !=
nullptr && ci_own->
client_playas == dest) {
1368 if (ci_to ==
nullptr)
break;
1371 if (ci !=
nullptr && show_local) {
1376 GetString(name, str,
lastof(name));
1379 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1380 if (cs->client_id == from_id) {
1381 cs->SendChat(action, ci_to->
client_id,
true, msg, data);
1389 DEBUG(net, 0,
"[server] received unknown chat destination type %d. Doing broadcast instead", desttype);
1393 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1394 cs->SendChat(action, from_id,
false, msg, data);
1400 if (ci !=
nullptr) {
1411 return this->
SendError(NETWORK_ERROR_NOT_AUTHORIZED);
1424 case NETWORK_ACTION_CHAT:
1425 case NETWORK_ACTION_CHAT_CLIENT:
1426 case NETWORK_ACTION_CHAT_COMPANY:
1431 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1440 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1457 return this->
SendError(NETWORK_ERROR_NOT_EXPECTED);
1468 if (ci !=
nullptr) {
1492 DEBUG(net, 0,
"[rcon] wrong password from client-id %d", this->
client_id);
1496 DEBUG(net, 0,
"[rcon] client-id %d executed: '%s'", this->
client_id, command);
1521 DEBUG(net, 2,
"[move] wrong password from client-id #%d for company #%d", this->
client_id, company_id + 1);
1544 assert(max_len <=
lengthof(company_name));
1545 GetString(company_name, STR_COMPANY_NAME, company_name + max_len - 1);
1572 for (uint i = 0; i < NETWORK_VEH_END; i++) {
1576 for (uint i = 0; i < NETWORK_VEH_END; i++) {
1596 case VEH_TRAIN: type = NETWORK_VEH_TRAIN;
break;
1599 case VEH_SHIP: type = NETWORK_VEH_SHIP;
break;
1627 if (ci ==
nullptr)
return;
1631 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1633 cs->SendClientInfo(ci);
1644 DEBUG(net, 0,
"Auto-restarting map. Year %d reached",
_cur_year);
1676 memset(clients_in_company, 0,
sizeof(clients_in_company));
1680 if (
Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] =
true;
1689 memset(vehicles_in_company, 0,
sizeof(vehicles_in_company));
1693 vehicles_in_company[v->owner]++;
1700 if (c->is_ai)
continue;
1702 if (!clients_in_company[c->index]) {
1741 bool found_name =
false;
1747 while (!found_name) {
1750 if (strcmp(ci->client_name, new_name) == 0) {
1758 if (ci !=
nullptr) {
1759 if (strcmp(ci->
client_name, new_name) == 0) found_name =
false;
1767 seprintf(new_name, last,
"%s #%d", original_name, number);
1784 if (strcmp(ci->client_name, new_name) == 0)
return false;
1788 if (ci ==
nullptr)
return false;
1808 if (!already_hashed) {
1823 while ((cp = cs->outgoing_queue.Pop()) !=
nullptr) {
1824 cs->SendCommand(cp);
1835 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
1836 bool send_sync =
false;
1839 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
1848 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
1855 uint lag = NetworkCalculateLag(cs);
1856 switch (cs->status) {
1857 case NetworkClientSocket::STATUS_ACTIVE:
1862 "Client #%d is dropped because the client's game state is more than %d ticks behind" :
1864 "Client #%d is dropped because the client did not respond for more than %d ticks",
1865 cs->client_id, lag);
1866 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
1875 if (lag > (uint)
DAY_TICKS && cs->lag_test == 0 && cs->last_packet + std::chrono::seconds(2) > std::chrono::steady_clock::now()) {
1883 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
1888 case NetworkClientSocket::STATUS_INACTIVE:
1889 case NetworkClientSocket::STATUS_NEWGRFS_CHECK:
1890 case NetworkClientSocket::STATUS_AUTHORIZED:
1895 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
1900 case NetworkClientSocket::STATUS_MAP_WAIT:
1904 if (std::chrono::steady_clock::now() > cs->last_packet + std::chrono::seconds(2)) {
1911 cs->last_packet = std::chrono::steady_clock::now();
1915 case NetworkClientSocket::STATUS_MAP:
1919 cs->SendError(NETWORK_ERROR_TIMEOUT_MAP);
1924 case NetworkClientSocket::STATUS_DONE_MAP:
1925 case NetworkClientSocket::STATUS_PRE_ACTIVE:
1929 cs->SendError(NETWORK_ERROR_TIMEOUT_JOIN);
1934 case NetworkClientSocket::STATUS_AUTH_GAME:
1935 case NetworkClientSocket::STATUS_AUTH_COMPANY:
1939 cs->SendError(NETWORK_ERROR_TIMEOUT_PASSWORD);
1944 case NetworkClientSocket::STATUS_END:
1949 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) {
1954 if (send_frame) cs->SendFrame();
1956 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
1958 if (send_sync) cs->SendSync();
2001 static const char *
const stat_str[] = {
2004 "authorizing (server password)",
2005 "authorizing (company password)",
2013 static_assert(
lengthof(stat_str) == NetworkClientSocket::STATUS_END);
2015 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
2017 if (ci ==
nullptr)
continue;
2018 uint lag = NetworkCalculateLag(cs);
2021 status = (cs->status < (ptrdiff_t)
lengthof(stat_str) ? stat_str[cs->status] :
"unknown");
2034 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
2035 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendConfigUpdate();
2051 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
2052 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendCompanyUpdate();
2079 NetworkClientSocket *cs = NetworkClientSocket::GetByClientID(client_id);
2081 if (cs->status < NetworkClientSocket::STATUS_AUTHORIZED)
return;
2082 cs->SendMove(client_id, company_id);
2100 NetworkClientSocket::GetByClientID(client_id)->SendRConResult(colour_code,
string);
2111 NetworkClientSocket::GetByClientID(client_id)->SendError(NETWORK_ERROR_KICKED, reason);
2135 bool contains =
false;
2152 for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
2155 if (cs->client_address.IsInNetmask(ip)) {
2172 if (ci->client_playas == company)
return true;
2205 ci->client_id ==
CLIENT_ID_SERVER ?
"server" : NetworkClientSocket::GetByClientID(ci->client_id)->GetClientIP());
2222 assert(c !=
nullptr);
2230 if (ci !=
nullptr) {
2240 if (ci !=
nullptr) {
NetworkRecvStatus Receive_CLIENT_QUIT(Packet *p) override
The client is quitting the game.
@ VEH_AIRCRAFT
Aircraft vehicle type.
char rcon_password[NETWORK_PASSWORD_LENGTH]
password for rconsole (server side)
uint16 num_station[NETWORK_VEH_END]
How many stations are there of this type?
bool is_ai
If true, the company is (also) controlled by the computer (a NoAI program).
The game information that is sent from the server to the clients.
Simple calculated statistics of a company.
uint32 cmd
command being executed.
@ PACKET_SERVER_GAME_INFO
Information about the server.
DestType
Destination of our chat messages.
static const TextColour CC_INFO
Colour for information lines.
uint16 max_password_time
maximum amount of time, in game ticks, a client may take to enter the password
uint32 _frame_counter
The current frame.
uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason)
Ban, or kick, everyone joined from the given client's IP.
uint32 generation_seed
noise seed for world generation
Money company_value
The value of the company.
@ FT_SCENARIO
old or new scenario
@ PACKET_SERVER_ERROR
Server sending an error message to the client.
void NetworkServerSendConfigUpdate()
Send Config Update.
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
void NetworkAdminUpdate(AdminUpdateFrequency freq)
Send (push) updates to the admin network as they have registered for these updates.
void Recv_string(char *buffer, size_t size, StringValidationSettings settings=SVS_REPLACE_WITH_QUESTION_MARK)
Reads a string till it finds a '\0' in the stream.
@ INVALID_CLIENT_ID
Client is not part of anything.
uint8 max_spectators
maximum amount of spectators
@ SM_START_HEIGHTMAP
Load a heightmap and start a new game from it.
void CDECL usererror(const char *s,...)
Error handling for fatal user errors.
bool NetworkFindName(char *new_name, const char *last)
Check whether a name is unique, and otherwise try to make it unique.
void SerializeGRFIdentifier(Packet *p, const GRFIdentifier *grf)
Serializes the GRFIdentifier (GRF ID and MD5 checksum) to the packet.
void NetworkServerSetCompanyPassword(CompanyID company_id, const char *password, bool already_hashed)
Set/Reset a company password on the server end.
@ SM_LOAD_GAME
Load game, Play Scenario.
void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, const char *msg, ClientID from_id, int64 data, bool from_admin)
Send an actual chat message.
uint8 autoclean_unprotected
remove passwordless companies after this many months
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
void NetworkServerShowStatusToConsole()
Show the status message of all clients on the console.
static void NetworkCheckRestartMap()
Check if we want to restart the map.
byte * buffer
The buffer of this packet, of basically variable length up to SEND_MTU.
ServerNetworkGameSocketHandler * cs
Socket we are associated with.
uint8 max_clients
maximum amount of clients
bool HasPackets()
Checks whether there are packets.
Year _cur_year
Current year, starting at 0.
NetworkRecvStatus SendGameInfo()
Send the client information about the server.
static const uint NETWORK_NAME_LENGTH
The maximum length of the server name and map name, in bytes including '\0'.
std::mutex lock
synchronization for playback status fields
CompanyID client_playas
As which company is this client playing (CompanyID)
@ FACIL_TRUCK_STOP
Station with truck stops.
@ STATUS_PRE_ACTIVE
The client is catching up the delayed frames.
Year inaugurated_year
Year of starting the company.
uint Count() const
Get the number of items in the queue.
DateFract _date_fract
Fractional part of the day.
@ PACKET_SERVER_CONFIG_UPDATE
Some network configuration important to the client changed.
bool _network_server
network-server is active
CompanyMask _network_company_passworded
Bitmask of the password status of all companies.
@ CRR_AUTOCLEAN
The company is removed due to autoclean.
NetworkAction
Actions that can be used for NetworkTextMessage.
char client_name[NETWORK_CLIENT_NAME_LENGTH]
Name of the client.
uint32 frame
the frame in which this packet is executed
@ SPS_CLOSED
The connection got closed.
std::chrono::steady_clock::time_point last_packet
Time we received the last frame.
@ WC_CLIENT_LIST
Client list; Window numbers:
void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, int64 data, bool from_admin)
Send chat to the admin network (if they did opt in for the respective update).
Tindex index
Index of this pool item.
NetworkRecvStatus Receive_CLIENT_COMPANY_INFO(Packet *p) override
Request company information (in detail).
void SetInfo(NetworkClientInfo *info)
Sets the client info for this socket handler.
char network_id[NETWORK_SERVER_ID_LENGTH]
network ID for servers
NetworkRecvStatus Receive_CLIENT_SET_PASSWORD(Packet *p) override
Set the password for the clients current company: string The password.
static const uint NETWORK_CHAT_LENGTH
The maximum length of a chat message, in bytes including '\0'.
@ WC_CLIENT_LIST_POPUP
Popup for the client list; Window numbers:
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Date join_date
Gamedate the client has joined.
static void NetworkAutoCleanCompanies()
Check if the server has autoclean_companies activated Two things happen: 1) If a company is not prote...
@ ADMIN_FREQUENCY_DAILY
The admin gets information about this on a daily basis.
@ PACKET_SERVER_NEWGAME
The server is preparing to start a new game.
char password[NETWORK_PASSWORD_LENGTH]
The password for the company.
void NetworkPrintClients()
Print all the clients to the console.
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...
SOCKET sock
The socket currently connected to.
void Write(byte *buf, size_t size) override
Write a given number of bytes into the savegame.
uint32 last_token_frame
The last frame we received the right token.
static const uint MAX_CLIENTS
How many clients can we have.
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
virtual Packet * ReceivePacket() override
Receives a packet for the given client.
uint32 last_frame_server
Last frame the server has executed.
@ DESTTYPE_TEAM
Send message/notice to everyone playing the same company (Team)
GRFIdentifier ident
grfid and md5sum to uniquely identify newgrfs
ClientSettings _settings_client
The current settings for this game.
void NetworkUDPAdvertise()
Register us to the master server This function checks if it needs to send an advertise.
@ PACKET_SERVER_WAIT
Server tells the client there are some people waiting for the map as well.
@ STATUS_MAP
The client is downloading the map.
@ PACKET_SERVER_JOIN
Tells clients that a new client has joined.
static bool IsValidHumanID(size_t index)
Is this company a valid company, not controlled by a NoAI program?
void NetworkSyncCommandQueue(NetworkClientSocket *cs)
Sync our local command queue to the command queue of the given socket.
@ ADMIN_FREQUENCY_MONTHLY
The admin gets information about this on a monthly basis.
@ STATUS_MAP_WAIT
The client is waiting as someone else is downloading the map.
void NetworkServerMonthlyLoop()
Monthly "callback".
uint8 autoclean_protected
remove the password from passworded companies after this many months
int receive_limit
Amount of bytes that we can receive at this moment.
@ WC_COMPANY
Company view; Window numbers:
StringID GetNetworkErrorMsg(NetworkErrorCode err)
Retrieve the string id of an internal error number.
@ VEH_ROAD
Road vehicle type.
NetworkServerGameInfo _network_game_info
Information about our game.
uint16 months_empty
How many months the company is empty.
ClientID _redirect_console_to_client
If not invalid, redirect the console output to a client.
static const uint NETWORK_CLIENT_NAME_LENGTH
The maximum length of a client's name, in bytes including '\0'.
Owner
Enum for all companies/owners.
Base socket handler for all TCP sockets.
const char * GenerateCompanyPasswordHash(const char *password, const char *password_server_id, uint32 password_game_seed)
Hash the given password using server ID and game seed.
void Send_uint8(uint8 data)
Package a 8 bits integer in the packet.
NetworkLanguage
Language ids for server_lang and client_lang.
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
@ SPS_ALL_SENT
All packets in the queue are sent.
static const uint32 GENERATE_NEW_SEED
Create a new random seed.
NetworkRecvStatus Receive_CLIENT_MAP_OK(Packet *p) override
Tell the server that we are done receiving/loading the map.
void NetworkAdminClientQuit(ClientID client_id)
Notify the admin network that a client quit (if they have opt in for the respective update).
static const TextColour CC_DEFAULT
Default colour of the console.
uint32 _frame_counter_max
To where we may go with our clients.
@ STATUS_ACTIVE
The client is active within in the game.
void NetworkServer_Tick(bool send_frame)
This is called every tick if this is a _network_server.
NetworkRecvStatus SendCommand(const CommandPacket *cp)
Send a command to the client to execute.
@ PACKET_SERVER_MAP_SIZE
Server tells the client what the (compressed) size of the map is.
NetworkRecvStatus SendRConResult(uint16 colour, const char *command)
Send the result of a console action.
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).
GameCreationSettings game_creation
settings used during the creation of a game (map)
void Finish() override
Prepare everything to finish writing the savegame.
void Send_uint32(uint32 data)
Package a 32 bits integer in the packet.
@ PACKET_SERVER_MAP_DONE
Server tells it has just sent the last bits of the map to the client.
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
virtual Packet * ReceivePacket()
Receives a packet for the given client.
uint16 max_download_time
maximum amount of time, in game ticks, a client may take to download the map
void Append(CommandPacket *p)
Append a CommandPacket at the end of the queue.
static constexpr size_t MAX_SIZE
Make template parameter accessible from outside.
#define DECLARE_POSTFIX_INCREMENT(enum_type)
Some enums need to have allowed incrementing (i.e.
static NetworkClientInfo * GetByClientID(ClientID client_id)
Return the CI given it's client-identifier.
@ ADMIN_FREQUENCY_QUARTERLY
The admin gets information about this on a quarterly basis.
NetworkRecvStatus Receive_CLIENT_COMPANY_PASSWORD(Packet *p) override
Send a password to the server to authorize uint8 Password type (see NetworkPasswordType).
void PrependQueue()
Prepend the current packet to the queue.
CompanyID company
company that is executing the command
AbstractFileType abstract_ftype
Abstract type of file (scenario, heightmap, etc).
byte client_lang
The language of the client.
@ FACIL_BUS_STOP
Station with bus stops.
NetworkRecvStatus Receive_CLIENT_NEWGRFS_CHECKED(Packet *p) override
Tell the server that we have the required GRFs.
void FillNetworkGameInfo(NetworkGameInfo &ngi)
Fill a NetworkGameInfo structure with the latest information of the server.
Template for TCP listeners.
~ServerNetworkGameSocketHandler()
Clear everything related to this client.
@ COMPANY_NEW_COMPANY
The client wants a new company.
bool server_admin_chat
allow private chat for the server to be distributed to the admin network
@ STATUS_INACTIVE
The client is not connected nor active.
static void Send()
Send the packets for the server sockets.
uint16 num_vehicle[NETWORK_VEH_END]
How many vehicles are there of this type?
uint32 Recv_uint32()
Read a 32 bits integer from the packet.
char server_password[NETWORK_PASSWORD_LENGTH]
password for joining this server
@ NETWORK_RECV_STATUS_CONN_LOST
The connection is 'just' lost.
@ PACKET_SERVER_NEED_GAME_PASSWORD
Server requests the (hashed) game password.
static const uint NETWORK_CLIENTS_LENGTH
The maximum length for the list of clients that controls a company, in bytes including '\0'.
Writing a savegame directly to a number of packets.
void NetworkServerUpdateCompanyPassworded(CompanyID company_id, bool passworded)
Tell that a particular company is (not) passworded.
int32 performance_history
Company score (scale 0-1000)
Everything we need to know about a command to be able to execute it.
Date _date
Current date in days (day counter)
NetworkRecvStatus SendSync()
Request the client to sync.
bool IsNetworkCompatibleVersion(const char *other)
Checks whether the given version string is compatible with our version.
Information about GRF, used in the game and (part of it) in savegames.
@ PACKET_SERVER_SHUTDOWN
The server is shutting down.
bool DoCommandP(const CommandContainer *container, bool my_cmd)
Shortcut for the long DoCommandP when having a container with the data.
@ PACKET_SERVER_NEED_COMPANY_PASSWORD
Server requests the (hashed) company password.
NetworkRecvStatus SendConfigUpdate()
Send an update about the max company/spectator counts.
@ SM_NEWGAME
New Game --> 'Random game'.
#define DEBUG(name, level,...)
Output a line of debugging information.
NetworkRecvStatus Receive_CLIENT_GAME_INFO(Packet *p) override
Request game information.
static void NetworkHandleCommandQueue(NetworkClientSocket *cs)
Handle the command-queue of a socket.
uint16 bytes_per_frame
how many bytes may, over a long period, be received per frame?
void Send_string(const char *data)
Sends a string over the network.
const char * GetHostname()
Get the hostname; in case it wasn't given the IPv4 dotted representation is given.
@ NETWORK_RECV_STATUS_SERVER_ERROR
The server told us we made an error.
@ PACKET_SERVER_COMPANY_UPDATE
Information (password) of a company changed.
uint8 flags
NOSAVE: GCF_Flags, bitset.
Year restart_game_year
year the server restarts
static T SB(T &x, const uint8 s, const uint8 n, const U d)
Set n bits in x starting at bit s to d.
ClientID
'Unique' identifier to be given to clients
Money money
Money owned by the company.
PacketSize size
The size of the whole packet for received packets.
@ PACKET_SERVER_BANNED
The server has banned you.
static const uint16 SEND_MTU
Number of bytes we can pack in a single packet.
NetworkRecvStatus SendMove(ClientID client_id, CompanyID company_id)
Tell that a client moved to another company.
NetworkRecvStatus Receive_CLIENT_JOIN(Packet *p) override
Try to join the server: string OpenTTD revision (norev000 if no revision).
NetworkRecvStatus SendJoin(ClientID client_id)
Tell that a client joined.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
uint32 _sync_seed_1
Seed to compare during sync checks.
NetworkRecvStatus SendFrame()
Tell the client that they may run to a particular frame.
@ MAX_COMPANIES
Maximum number of companies.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Packet * PopPacket()
Pop a single created packet from the queue with packets.
void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const char *string)
Send an rcon reply to the client.
@ CMD_CLIENT_ID
set p2 with the ClientID of the sending client.
size_t total_size
Total size of the compressed savegame.
void Send_uint16(uint16 data)
Package a 16 bits integer in the packet.
virtual void SendPacket(Packet *packet)
This function puts the packet in the send-queue and it is send as soon as possible.
@ CLIENT_ID_SERVER
Servers always have this ID.
NetworkCompanyState * _network_company_states
Statistics about some companies.
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
NetworkRecvStatus SendCompanyUpdate()
Send an update about the company password states.
NetworkRecvStatus SendWelcome()
Send the client a welcome message with some basic information.
static ClientID _network_client_id
The identifier counter for new clients (is never decreased)
NetworkRecvStatus Receive_CLIENT_MOVE(Packet *p) override
Request the server to move this client into another company: uint8 ID of the company the client wants...
Packet * next
The next packet.
bool my_cmd
did the command originate from "me"
Money yearly_expenses[3][EXPENSES_END]
Expenses of the company for the last three years, in every ExpensesType category.
ClientStatus status
Status of this client.
void NetworkPopulateCompanyStats(NetworkCompanyStats *stats)
Populate the company stats.
@ FACIL_DOCK
Station with a dock.
bool _network_dedicated
are we a dedicated server?
struct PacketWriter * savegame
Writer used to write the savegame.
Internal entity of a packet.
uint16 max_join_time
maximum amount of time, in game ticks, a client may take to sync up during joining
static const byte NETWORK_COMPANY_INFO_VERSION
What version of company info is this?
@ FT_SAVEGAME
old or new savegame
NetworkRecvStatus SendClientInfo(NetworkClientInfo *ci)
Send the client information about a client.
const char * ReceiveCommand(Packet *p, CommandPacket *cp)
Receives a command from the network.
CommandFlags GetCommandFlags(uint32 cmd)
@ ADMIN_FREQUENCY_ANUALLY
The admin gets information about this on a yearly basis.
static const uint NETWORK_REVISION_LENGTH
The maximum length of the revision, in bytes including '\0'.
@ PACKET_SERVER_COMPANY_INFO
Information about a single company.
@ STATUS_DONE_MAP
The client has downloaded the map.
const char * GetClientIP()
Get the IP address/hostname of the connected client.
bool NetworkCompanyIsPassworded(CompanyID company_id)
Check if the company we want to join requires a password.
NetworkRecvStatus SendQuit(ClientID client_id)
Tell the client another client quit.
ClientID client_id
Client identifier (same as ClientState->client_id)
@ PACKET_SERVER_MOVE
Server tells everyone that someone is moved to another company.
void NetworkServerDailyLoop()
Daily "callback".
static const uint NETWORK_PASSWORD_LENGTH
The maximum length of the password, in bytes including '\0' (must be >= NETWORK_SERVER_ID_LENGTH)
@ PACKET_SERVER_FULL
The server is full and has no place for you.
bool NetworkServerChangeClientName(ClientID client_id, const char *new_name)
Change the client name of the given client.
void Send_bool(bool data)
Package a boolean in the packet.
void NORETURN SlError(StringID string, const char *extra_msg)
Error handler.
void NetworkAdminCompanyUpdate(const Company *company)
Notify the admin network of company updates.
@ SPS_NONE_SENT
The buffer is still full, so no (parts of) packets could be sent.
NetworkRecvStatus SendErrorQuit(ClientID client_id, NetworkErrorCode errorno)
Tell the client another client quit with an error.
void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci)
Perform all the server specific administration of a new company.
Class for handling the server side of the game connection.
NetworkClientInfo * GetInfo() const
Gets the client info of this socket handler.
SwitchMode _switch_mode
The next mainloop command.
uint32 StringID
Numeric value that represents a string, independent of the selected language.
void AppendQueue()
Append the current packet to the queue.
bool HasClientQuit() const
Whether the current client connected to the socket has quit.
NetworkRecvStatus Receive_CLIENT_COMMAND(Packet *p) override
The client has done a command and wants us to handle it.
SendPacketsState SendPackets(bool closing_down=false)
Sends all the buffered packets out for this client.
static const uint NETWORK_RCONCOMMAND_LENGTH
The maximum length of a rconsole command, in bytes including '\0'.
void NetworkServerDoMove(ClientID client_id, CompanyID company_id)
Handle the tid-bits of moving a client from one company to another.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Base class for all pools.
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
NetworkRecvStatus Receive_CLIENT_SET_NAME(Packet *p) override
Gives the client a new name: string New name of the client.
@ PACKET_SERVER_ERROR_QUIT
A server tells that a client has hit an error and did quit.
static size_t GetNumItems()
Returns number of valid items in the pool.
NetworkRecvStatus SendNewGame()
Tell the client we're starting a new game.
@ FACIL_TRAIN
Station with train station.
@ CMD_ID_MASK
mask for the command ID
~PacketWriter()
Make sure everything is cleaned up.
uint16 PacketSize
Size of the whole packet.
static RoadVehicle * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
void Send_uint64(uint64 data)
Package a 64 bits integer in the packet.
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company)
Prepare a DoCommand to be send over the network.
Interface for filtering a savegame till it is written.
TextColour GetDrawStringCompanyColour(CompanyID company)
Get the colour for DrawString-subroutines which matches the colour of the company.
uint16 bytes_per_frame_burst
how many bytes may, over a short period, be received?
@ COMPANY_SPECTATOR
The client is spectating.
NetworkRecvStatus
Status of a network client; reasons why a client has quit.
byte _network_clients_connected
The amount of clients connected.
FileToSaveLoad _file_to_saveload
File to save or load in the openttd loop.
struct GRFConfig * next
NOSAVE: Next item in the linked list.
NetworkRecvStatus SendChat(NetworkAction action, ClientID client_id, bool self_send, const char *msg, int64 data)
Send a chat message.
@ STATUS_NEWGRFS_CHECK
The client is checking NewGRFs.
SaveOrLoadResult SaveWithFilter(SaveFilter *writer, bool threaded)
Save the game using a (writer) filter.
static bool AllowConnection()
Whether an connection is allowed or not at this moment.
NetworkRecvStatus Receive_CLIENT_GETMAP(Packet *p) override
Request the map from the server.
uint16 max_init_time
maximum amount of time, in game ticks, a client may take to initiate joining
@ PACKET_SERVER_SYNC
Server tells the client what the random state should be.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
NetworkRecvStatus SendMap()
This sends the map to the client.
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
@ FT_HEIGHTMAP
heightmap file
@ PACKET_SERVER_MAP_BEGIN
Server tells the client that it is beginning to send the map.
uint8 Recv_uint8()
Read a 8 bits integer from the packet.
void SerializeNetworkGameInfo(Packet *p, const NetworkGameInfo *info)
Serializes the NetworkGameInfo struct to the packet.
NetworkRecvStatus SendNewGRFCheck()
Send the check for the NewGRFs.
static const TextColour CC_ERROR
Colour for error lines.
@ STATUS_AUTH_COMPANY
The client is authorizing with company password.
@ CMD_COMPANY_CTRL
used in multiplayer to create a new companies etc.
@ PACKET_SERVER_CHAT
Server distributing the message of a client (or itself).
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
@ PACKET_SERVER_RCON
Response of the executed command on the server.
@ PACKET_SERVER_QUIT
A server tells that a client has quit.
NetworkRecvStatus SendNeedGamePassword()
Request the game password.
CommandQueue incoming_queue
The command-queue awaiting handling.
void CDECL error(const char *s,...)
Error handling for fatal non-user errors.
ClientID client_id
Client identifier.
GRFConfig * _grfconfig
First item in list of current GRF set up.
PacketWriter(ServerNetworkGameSocketHandler *cs)
Create the packet writer.
static const uint MILLISECONDS_PER_TICK
The number of milliseconds per game tick.
@ PACKET_SERVER_COMMAND
Server distributes a command to (all) the clients.
NetworkRecvStatus Receive_CLIENT_ACK(Packet *p) override
Tell the server we are done with this frame: uint32 Current frame counter of the client.
void NetworkAdminClientUpdate(const NetworkClientInfo *ci)
Notify the admin network of a client update (if they did opt in for the respective update).
@ PACKET_SERVER_FRAME
Server tells the client what frame it is in, and thus to where the client may progress.
#define lengthof(x)
Return the length of an fixed size array.
StringList _network_ban_list
The banned clients.
NetworkSettings network
settings related to the network
@ SPS_PARTLY_SENT
The packets are partly sent; there are more packets to be sent in the queue.
uint64 Recv_uint64()
Read a 64 bits integer from the packet.
static void ResetUser(uint32 user)
Reset an user's OrderBackup if needed.
void SendCompanyInformation(Packet *p, const struct Company *c, const struct NetworkCompanyStats *stats, uint max_len=NETWORK_COMPANY_NAME_LENGTH)
Package some generic company information into a packet.
uint8 autoclean_novehicles
remove companies with no vehicles after this many months
@ DESTTYPE_BROADCAST
Send message/notice to all clients (All)
std::mutex mutex
Mutex for making threaded saving safe.
ServerNetworkGameSocketHandler(SOCKET s)
Create a new socket for the server side of the game connection.
NetworkRecvStatus Receive_CLIENT_RCON(Packet *p) override
Send an RCon command to the server: string RCon password.
bool IsBus() const
Check whether a roadvehicle is a bus.
NetworkAddress client_address
IP-address of the client (so he can be banned)
void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
Execute a given command passed to us.
void ProcessAsyncSaveFinish()
Handle async save finishes.
void Destroy()
Begin the destruction of this packet writer.
uint16 max_lag_time
maximum amount of time, in game ticks, a client may be lagging behind the server
NetworkRecvStatus Receive_CLIENT_CHAT(Packet *p) override
Sends a chat-packet to the server: uint8 ID of the action (see NetworkAction).
@ PACKET_SERVER_CLIENT_INFO
Server sends you information about a client.
@ NETWORK_RECV_STATUS_OKAY
Everything is okay.
void SendCommand(Packet *p, const CommandPacket *cp)
Sends a command over the network.
@ CCA_DELETE
Delete a company.
NetworkRecvStatus Receive_CLIENT_GAME_PASSWORD(Packet *p) override
Send a password to the server to authorize: uint8 Password type (see NetworkPasswordType).
@ ADMIN_FREQUENCY_WEEKLY
The admin gets information about this on a weekly basis.
@ DESTTYPE_CLIENT
Send message/notice to only a certain client (Private)
@ PACKET_SERVER_WELCOME
Server welcomes you and gives you your ClientID.
NetworkRecvStatus SendShutdown()
Tell the client we're shutting down.
@ VEH_TRAIN
Train vehicle type.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
@ FACIL_AIRPORT
Station with an airport.
@ CMD_SERVER
the command can only be initiated by the server
@ CMD_SPECTATOR
the command may be initiated by a spectator
byte last_token
The last random token we did send to verify the client is listening.
std::condition_variable exit_sig
Signal for threaded destruction of this packet writer.
NetworkRecvStatus SendError(NetworkErrorCode error, const char *reason=nullptr)
Send an error to the client, and close its connection.
byte clients_on
Current count of clients on server.
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
uint16 max_commands_in_queue
how many commands may there be in the incoming queue before dropping the connection?
static const TextColour CC_WARNING
Colour for warning lines.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
NetworkRecvStatus SendCompanyInfo()
Send the client information about the companies.
char * strecat(char *dst, const char *src, const char *last)
Appends characters from one string to another.
void NetworkServerKickClient(ClientID client_id, const char *reason)
Kick a single client.
static const uint MAX_CLIENT_SLOTS
The number of slots; must be at least 1 more than MAX_CLIENTS.
@ VEH_SHIP
Ship vehicle type.
Month _cur_month
Current month (0..11)
NetworkRecvStatus SendNeedCompanyPassword()
Request the company password.
@ PACKET_SERVER_CHECK_NEWGRFS
Server sends NewGRF IDs and MD5 checksums for the client to check.
void NetworkServerYearlyLoop()
Yearly "callback".
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
@ CMD_RENAME_PRESIDENT
change the president name
CompanyEconomyEntry old_economy[MAX_HISTORY_QUARTERS]
Economic data of the company of the last MAX_HISTORY_QUARTERS quarters.
#define lastof(x)
Get the last element of an fixed size array.
@ SL_OK
completed successfully
uint32 last_frame
Last frame we have executed.
NetworkClientSocketPool _networkclientsocket_pool("NetworkClientSocket")
Make very sure the preconditions given in network_type.h are actually followed.
static const int DAY_TICKS
1 day is 74 ticks; _date_fract used to be uint16 and incremented by 885.
Packet * current
The packet we're currently writing to.
void GetClientName(char *client_name, const char *last) const
Get the name of the client, if the user did not send it yet, Client ID is used.
uint32 _last_sync_frame
Used in the server to store the last time a sync packet was sent to clients.
void NetworkAdminCompanyInfo(const Company *company, bool new_company)
Notify the admin network of company details.
NetworkErrorCode
The error codes we send around in the protocols.
Container for all information known about a client.
NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override
Close the network connection due to the given status.
void CDECL IConsolePrintF(TextColour colour_code, const char *format,...)
Handle the printing of text entered into the console or redirected there by any other means.
@ STATUS_AUTH_GAME
The client is authorizing with game (server) password.
bool NetworkCompanyHasClients(CompanyID company)
Check whether a particular company has clients.
Packet * packets
Packet queue of the savegame; send these "slowly" to the client.
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
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).
@ GCF_STATIC
GRF file is used statically (can be used in any MP game)
uint16 sync_freq
how often do we check whether we are still in-sync
NetworkRecvStatus SendWait()
Tell the client that its put in a waiting queue.
bool autoclean_companies
automatically remove companies that are not in use
@ PACKET_SERVER_MAP_DATA
Server sends bits of the map to the client.
uint8 max_companies
maximum amount of companies
@ STATUS_AUTHORIZED
The client is authorized.
@ CLIENT_ID_FIRST
The first client ID.
@ NETWORK_RECV_STATUS_MALFORMED_PACKET
We apparently send a malformed packet.
static const uint NETWORK_COMPANY_NAME_LENGTH
The maximum length of the company name, in bytes including '\0'.
void NetworkUpdateClientInfo(ClientID client_id)
Send updated client info of a particular client.
NetworkRecvStatus Receive_CLIENT_ERROR(Packet *p) override
The client made an error and is quitting the game.