OpenTTD Source: src/network/network_client.cpp Source File

OpenTTD Source 14.0-beta1

network_client.cpp
Go to the documentation of this file.
1 /*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10 #include "../stdafx.h"
11 #include "network_gui.h"
12 #include "../saveload/saveload.h"
13 #include "../saveload/saveload_filter.h"
14 #include "../command_func.h"
15 #include "../console_func.h"
16 #include "../strings_func.h"
17 #include "../window_func.h"
18 #include "../company_func.h"
19 #include "../company_base.h"
20 #include "../company_gui.h"
21 #include "../company_cmd.h"
22 #include "../core/random_func.hpp"
23 #include "../timer/timer_game_tick.h"
24 #include "../timer/timer_game_calendar.h"
25 #include "../gfx_func.h"
26 #include "../error.h"
27 #include "../rev.h"
28 #include "network.h"
29 #include "network_base.h"
30 #include "network_client.h"
31 #include "network_gamelist.h"
32 #include "../core/backup_type.hpp"
33 #include "../thread.h"
34 #include "../social_integration.h"
35
36 #include "table/strings.h"
37
38 #include "../safeguards.h"
39
40 /* This file handles all the client-commands */
41
43 struct PacketReader : LoadFilter {
44 static const size_t CHUNK = 32 * 1024;
45
46 std::vector<byte *> blocks;
47 byte *buf;
48 byte *bufe;
49 byte **block;
50 size_t written_bytes;
51 size_t read_bytes;
52
54 PacketReader() : LoadFilter(nullptr), buf(nullptr), bufe(nullptr), block(nullptr), written_bytes(0), read_bytes(0)
55 {
56 }
57
58 ~PacketReader() override
59 {
60 for (auto p : this->blocks) {
61 free(p);
62 }
63 }
64
72 static inline ssize_t TransferOutMemCopy(PacketReader *destination, const char *source, size_t amount)
73 {
74 memcpy(destination->buf, source, amount);
75 destination->buf += amount;
76 destination->written_bytes += amount;
77 return amount;
78 }
79
84 void AddPacket(Packet *p)
85 {
86 assert(this->read_bytes == 0);
87 p->TransferOutWithLimit(TransferOutMemCopy, this->bufe - this->buf, this);
88
89 /* Did everything fit in the current chunk, then we're done. */
90 if (p->RemainingBytesToTransfer() == 0) return;
91
92 /* Allocate a new chunk and add the remaining data. */
93 this->blocks.push_back(this->buf = CallocT<byte>(CHUNK));
94 this->bufe = this->buf + CHUNK;
95
96 p->TransferOutWithLimit(TransferOutMemCopy, this->bufe - this->buf, this);
97 }
98
99 size_t Read(byte *rbuf, size_t size) override
100 {
101 /* Limit the amount to read to whatever we still have. */
102 size_t ret_size = size = std::min(this->written_bytes - this->read_bytes, size);
103 this->read_bytes += ret_size;
104 const byte *rbufe = rbuf + ret_size;
105
106 while (rbuf != rbufe) {
107 if (this->buf == this->bufe) {
108 this->buf = *this->block++;
109 this->bufe = this->buf + CHUNK;
110 }
111
112 size_t to_write = std::min(this->bufe - this->buf, rbufe - rbuf);
113 memcpy(rbuf, this->buf, to_write);
114 rbuf += to_write;
115 this->buf += to_write;
116 }
117
118 return ret_size;
119 }
120
121 void Reset() override
122 {
123 this->read_bytes = 0;
124
125 this->block = this->blocks.data();
126 this->buf = *this->block++;
127 this->bufe = this->buf + CHUNK;
128 }
129 };
130
131
135 void ClientNetworkEmergencySave()
136 {
137 static FiosNumberedSaveName _netsave_ctr("netsave");
138 DoAutoOrNetsave(_netsave_ctr);
139 }
140
141
146 ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler(SOCKET s, const std::string &connection_string) : NetworkGameSocketHandler(s), connection_string(connection_string), savegame(nullptr), status(STATUS_INACTIVE)
147 {
148 assert(ClientNetworkGameSocketHandler::my_client == nullptr);
149 ClientNetworkGameSocketHandler::my_client = this;
150 }
151
153 ClientNetworkGameSocketHandler::~ClientNetworkGameSocketHandler()
154 {
155 assert(ClientNetworkGameSocketHandler::my_client == this);
156 ClientNetworkGameSocketHandler::my_client = nullptr;
157
158 delete this->savegame;
159 delete this->GetInfo();
160 }
161
162 NetworkRecvStatus ClientNetworkGameSocketHandler::CloseConnection(NetworkRecvStatus status)
163 {
164 assert(status != NETWORK_RECV_STATUS_OKAY);
165 if (this->IsPendingDeletion()) return status;
166
167 assert(this->sock != INVALID_SOCKET);
168
169 if (!this->HasClientQuit()) {
170 Debug(net, 3, "Closed client connection {}", this->client_id);
171
172 this->SendPackets(true);
173
174 /* Wait a number of ticks so our leave message can reach the server.
175 * This is especially needed for Windows servers as they seem to get
176 * the "socket is closed" message before receiving our leave message,
177 * which would trigger the server to close the connection as well. */
178 CSleep(3 * MILLISECONDS_PER_TICK);
179 }
180
181 this->DeferDeletion();
182
183 return status;
184 }
185
190 void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
191 {
192 if (this->IsPendingDeletion()) return;
193
194 /* First, send a CLIENT_ERROR to the server, so it knows we are
195 * disconnected (and why!) */
196 NetworkErrorCode errorno;
197
198 /* We just want to close the connection.. */
199 if (res == NETWORK_RECV_STATUS_CLOSE_QUERY) {
200 this->NetworkSocketHandler::MarkClosed();
201 this->CloseConnection(res);
202 _networking = false;
203
204 CloseWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
205 return;
206 }
207
208 switch (res) {
209 case NETWORK_RECV_STATUS_DESYNC: errorno = NETWORK_ERROR_DESYNC; break;
210 case NETWORK_RECV_STATUS_SAVEGAME: errorno = NETWORK_ERROR_SAVEGAME_FAILED; break;
211 case NETWORK_RECV_STATUS_NEWGRF_MISMATCH: errorno = NETWORK_ERROR_NEWGRF_MISMATCH; break;
212 default: errorno = NETWORK_ERROR_GENERAL; break;
213 }
214
215 if (res == NETWORK_RECV_STATUS_SERVER_ERROR || res == NETWORK_RECV_STATUS_SERVER_FULL ||
216 res == NETWORK_RECV_STATUS_SERVER_BANNED) {
217 /* This means the server closed the connection. Emergency save is
218 * already created if this was appropriate during handling of the
219 * disconnect. */
220 this->CloseConnection(res);
221 } else {
222 /* This means we as client made a boo-boo. */
223 SendError(errorno);
224
225 /* Close connection before we make an emergency save, as the save can
226 * take a bit of time; better that the server doesn't stall while we
227 * are doing the save, and already disconnects us. */
228 this->CloseConnection(res);
229 ClientNetworkEmergencySave();
230 }
231
232 CloseWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
233
234 if (_game_mode != GM_MENU) _switch_mode = SM_MENU;
235 _networking = false;
236 }
237
238
244 /* static */ bool ClientNetworkGameSocketHandler::Receive()
245 {
246 if (my_client->CanSendReceive()) {
247 NetworkRecvStatus res = my_client->ReceivePackets();
248 if (res != NETWORK_RECV_STATUS_OKAY) {
249 /* The client made an error of which we can not recover.
250 * Close the connection and drop back to the main menu. */
251 my_client->ClientError(res);
252 return false;
253 }
254 }
255 return _networking;
256 }
257
259 /* static */ void ClientNetworkGameSocketHandler::Send()
260 {
261 my_client->SendPackets();
262 if (my_client != nullptr) my_client->CheckConnection();
263 }
264
269 /* static */ bool ClientNetworkGameSocketHandler::GameLoop()
270 {
271 _frame_counter++;
272
273 NetworkExecuteLocalCommandQueue();
274
275 StateGameLoop();
276
277 /* Check if we are in sync! */
278 if (_sync_frame != 0) {
279 if (_sync_frame == _frame_counter) {
280 #ifdef NETWORK_SEND_DOUBLE_SEED
281 if (_sync_seed_1 != _random.state[0] || _sync_seed_2 != _random.state[1]) {
282 #else
283 if (_sync_seed_1 != _random.state[0]) {
284 #endif
285 ShowNetworkError(STR_NETWORK_ERROR_DESYNC);
286 Debug(desync, 1, "sync_err: {:08x}; {:02x}", TimerGameEconomy::date, TimerGameEconomy::date_fract);
287 Debug(net, 0, "Sync error detected");
288 my_client->ClientError(NETWORK_RECV_STATUS_DESYNC);
289 return false;
290 }
291
292 /* If this is the first time we have a sync-frame, we
293 * need to let the server know that we are ready and at the same
294 * frame as it is.. so we can start playing! */
295 if (_network_first_time) {
296 _network_first_time = false;
297 SendAck();
298 }
299
300 _sync_frame = 0;
301 } else if (_sync_frame < _frame_counter) {
302 Debug(net, 1, "Missed frame for sync-test: {} / {}", _sync_frame, _frame_counter);
303 _sync_frame = 0;
304 }
305 }
306
307 return true;
308 }
309
310
312 ClientNetworkGameSocketHandler * ClientNetworkGameSocketHandler::my_client = nullptr;
313
315 static uint32_t last_ack_frame;
316
318 static uint32_t _password_game_seed;
320 static std::string _password_server_id;
321
323 static uint8_t _network_server_max_companies;
325 std::string _network_server_name;
326
328 NetworkJoinInfo _network_join;
329
331 static_assert(NETWORK_SERVER_ID_LENGTH == MD5_HASH_BYTES * 2 + 1);
332
333 /***********
334 * Sending functions
335 * DEF_CLIENT_SEND_COMMAND has no parameters
336 ************/
337
339 NetworkRecvStatus ClientNetworkGameSocketHandler::SendJoin()
340 {
341 Debug(net, 9, "Client::SendJoin()");
342
343 Debug(net, 9, "Client::status = JOIN");
344 my_client->status = STATUS_JOIN;
345 Debug(net, 9, "Client::join_status = AUTHORIZING");
346 _network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING;
347 SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
348
349 Packet *p = new Packet(PACKET_CLIENT_JOIN);
350 p->Send_string(GetNetworkRevisionString());
351 p->Send_uint32(_openttd_newgrf_version);
352 p->Send_string(_settings_client.network.client_name); // Client name
353 p->Send_uint8 (_network_join.company); // PlayAs
354 p->Send_uint8 (0); // Used to be language
355 my_client->SendPacket(p);
356 return NETWORK_RECV_STATUS_OKAY;
357 }
358
360 NetworkRecvStatus ClientNetworkGameSocketHandler::SendNewGRFsOk()
361 {
362 Debug(net, 9, "Client::SendNewGRFsOk()");
363
364 Packet *p = new Packet(PACKET_CLIENT_NEWGRFS_CHECKED);
365 my_client->SendPacket(p);
366 return NETWORK_RECV_STATUS_OKAY;
367 }
368
373 NetworkRecvStatus ClientNetworkGameSocketHandler::SendGamePassword(const std::string &password)
374 {
375 Debug(net, 9, "Client::SendGamePassword()");
376
377 Packet *p = new Packet(PACKET_CLIENT_GAME_PASSWORD);
378 p->Send_string(password);
379 my_client->SendPacket(p);
380 return NETWORK_RECV_STATUS_OKAY;
381 }
382
387 NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyPassword(const std::string &password)
388 {
389 Debug(net, 9, "Client::SendCompanyPassword()");
390
391 Packet *p = new Packet(PACKET_CLIENT_COMPANY_PASSWORD);
392 p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _password_game_seed));
393 my_client->SendPacket(p);
394 return NETWORK_RECV_STATUS_OKAY;
395 }
396
398 NetworkRecvStatus ClientNetworkGameSocketHandler::SendGetMap()
399 {
400 Debug(net, 9, "Client::SendGetMap()");
401
402 Debug(net, 9, "Client::status = MAP_WAIT");
403 my_client->status = STATUS_MAP_WAIT;
404
405 Packet *p = new Packet(PACKET_CLIENT_GETMAP);
406 my_client->SendPacket(p);
407 return NETWORK_RECV_STATUS_OKAY;
408 }
409
411 NetworkRecvStatus ClientNetworkGameSocketHandler::SendMapOk()
412 {
413 Debug(net, 9, "Client::SendMapOk()");
414
415 Debug(net, 9, "Client::status = ACTIVE");
416 my_client->status = STATUS_ACTIVE;
417
418 Packet *p = new Packet(PACKET_CLIENT_MAP_OK);
419 my_client->SendPacket(p);
420 return NETWORK_RECV_STATUS_OKAY;
421 }
422
424 NetworkRecvStatus ClientNetworkGameSocketHandler::SendAck()
425 {
426 Debug(net, 9, "Client::SendAck()");
427
428 Packet *p = new Packet(PACKET_CLIENT_ACK);
429
430 p->Send_uint32(_frame_counter);
431 p->Send_uint8 (my_client->token);
432 my_client->SendPacket(p);
433 return NETWORK_RECV_STATUS_OKAY;
434 }
435
440 NetworkRecvStatus ClientNetworkGameSocketHandler::SendCommand(const CommandPacket *cp)
441 {
442 Debug(net, 9, "Client::SendCommand(): cmd={}", cp->cmd);
443
444 Packet *p = new Packet(PACKET_CLIENT_COMMAND);
445 my_client->NetworkGameSocketHandler::SendCommand(p, cp);
446
447 my_client->SendPacket(p);
448 return NETWORK_RECV_STATUS_OKAY;
449 }
450
452 NetworkRecvStatus ClientNetworkGameSocketHandler::SendChat(NetworkAction action, DestType type, int dest, const std::string &msg, int64_t data)
453 {
454 Debug(net, 9, "Client::SendChat(): action={}, type={}, dest={}", action, type, dest);
455
456 Packet *p = new Packet(PACKET_CLIENT_CHAT);
457
458 p->Send_uint8 (action);
459 p->Send_uint8 (type);
460 p->Send_uint32(dest);
461 p->Send_string(msg);
462 p->Send_uint64(data);
463
464 my_client->SendPacket(p);
465 return NETWORK_RECV_STATUS_OKAY;
466 }
467
469 NetworkRecvStatus ClientNetworkGameSocketHandler::SendError(NetworkErrorCode errorno)
470 {
471 Debug(net, 9, "Client::SendError(): errorno={}", errorno);
472
473 Packet *p = new Packet(PACKET_CLIENT_ERROR);
474
475 p->Send_uint8(errorno);
476 my_client->SendPacket(p);
477 return NETWORK_RECV_STATUS_OKAY;
478 }
479
484 NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetPassword(const std::string &password)
485 {
486 Debug(net, 9, "Client::SendSetPassword()");
487
488 Packet *p = new Packet(PACKET_CLIENT_SET_PASSWORD);
489
490 p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _password_game_seed));
491 my_client->SendPacket(p);
492 return NETWORK_RECV_STATUS_OKAY;
493 }
494
499 NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetName(const std::string &name)
500 {
501 Debug(net, 9, "Client::SendSetName()");
502
503 Packet *p = new Packet(PACKET_CLIENT_SET_NAME);
504
505 p->Send_string(name);
506 my_client->SendPacket(p);
507 return NETWORK_RECV_STATUS_OKAY;
508 }
509
513 NetworkRecvStatus ClientNetworkGameSocketHandler::SendQuit()
514 {
515 Debug(net, 9, "Client::SendSetName()");
516
517 Packet *p = new Packet(PACKET_CLIENT_QUIT);
518
519 my_client->SendPacket(p);
520 return NETWORK_RECV_STATUS_OKAY;
521 }
522
528 NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const std::string &pass, const std::string &command)
529 {
530 Debug(net, 9, "Client::SendRCon()");
531
532 Packet *p = new Packet(PACKET_CLIENT_RCON);
533 p->Send_string(pass);
534 p->Send_string(command);
535 my_client->SendPacket(p);
536 return NETWORK_RECV_STATUS_OKAY;
537 }
538
544 NetworkRecvStatus ClientNetworkGameSocketHandler::SendMove(CompanyID company, const std::string &password)
545 {
546 Debug(net, 9, "Client::SendMove(): company={}", company);
547
548 Packet *p = new Packet(PACKET_CLIENT_MOVE);
549 p->Send_uint8(company);
550 p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _password_game_seed));
551 my_client->SendPacket(p);
552 return NETWORK_RECV_STATUS_OKAY;
553 }
554
559 bool ClientNetworkGameSocketHandler::IsConnected()
560 {
561 return my_client != nullptr && my_client->status == STATUS_ACTIVE;
562 }
563
564
565 /***********
566 * Receiving functions
567 * DEF_CLIENT_RECEIVE_COMMAND has parameter: Packet *p
568 ************/
569
570 extern bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = nullptr);
571
572 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_FULL(Packet *)
573 {
574 Debug(net, 9, "Client::Receive_SERVER_FULL()");
575
576 /* We try to join a server which is full */
577 ShowErrorMessage(STR_NETWORK_ERROR_SERVER_FULL, INVALID_STRING_ID, WL_CRITICAL);
578
579 return NETWORK_RECV_STATUS_SERVER_FULL;
580 }
581
582 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_BANNED(Packet *)
583 {
584 Debug(net, 9, "Client::Receive_SERVER_BANNED()");
585
586 /* We try to join a server where we are banned */
587 ShowErrorMessage(STR_NETWORK_ERROR_SERVER_BANNED, INVALID_STRING_ID, WL_CRITICAL);
588
589 return NETWORK_RECV_STATUS_SERVER_BANNED;
590 }
591
592 /* This packet contains info about the client (playas and name)
593 * as client we save this in NetworkClientInfo, linked via 'client_id'
594 * which is always an unique number on a server. */
595 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Packet *p)
596 {
597 NetworkClientInfo *ci;
598 ClientID client_id = (ClientID)p->Recv_uint32();
599 CompanyID playas = (CompanyID)p->Recv_uint8();
600
601 Debug(net, 9, "Client::Receive_SERVER_CLIENT_INFO(): client_id={}, playas={}", client_id, playas);
602
603 std::string name = p->Recv_string(NETWORK_NAME_LENGTH);
604
605 if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
606 if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT;
607 /* The server validates the name when receiving it from clients, so when it is wrong
608 * here something went really wrong. In the best case the packet got malformed on its
609 * way too us, in the worst case the server is broken or compromised. */
610 if (!NetworkIsValidClientName(name)) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
611
612 ci = NetworkClientInfo::GetByClientID(client_id);
613 if (ci != nullptr) {
614 if (playas == ci->client_playas && name.compare(ci->client_name) != 0) {
615 /* Client name changed, display the change */
616 NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, name);
617 } else if (playas != ci->client_playas) {
618 /* The client changed from client-player..
619 * Do not display that for now */
620 }
621
622 /* Make sure we're in the company the server tells us to be in,
623 * for the rare case that we get moved while joining. */
624 if (client_id == _network_own_client_id) SetLocalCompany(!Company::IsValidID(playas) ? COMPANY_SPECTATOR : playas);
625
626 ci->client_playas = playas;
627 ci->client_name = name;
628
629 InvalidateWindowData(WC_CLIENT_LIST, 0);
630
631 return NETWORK_RECV_STATUS_OKAY;
632 }
633
634 /* There are at most as many ClientInfo as ClientSocket objects in a
635 * server. Having more info than a server can have means something
636 * has gone wrong somewhere, i.e. the server has more info than it
637 * has actual clients. That means the server is feeding us an invalid
638 * state. So, bail out! This server is broken. */
639 if (!NetworkClientInfo::CanAllocateItem()) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
640
641 /* We don't have this client_id yet, find an empty client_id, and put the data there */
642 ci = new NetworkClientInfo(client_id);
643 ci->client_playas = playas;
644 if (client_id == _network_own_client_id) this->SetInfo(ci);
645
646 ci->client_name = name;
647
648 InvalidateWindowData(WC_CLIENT_LIST, 0);
649
650 return NETWORK_RECV_STATUS_OKAY;
651 }
652
653 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet *p)
654 {
655 static const StringID network_error_strings[] = {
656 STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_GENERAL
657 STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_DESYNC
658 STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_SAVEGAME_FAILED
659 STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_CONNECTION_LOST
660 STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_ILLEGAL_PACKET
661 STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_NEWGRF_MISMATCH
662 STR_NETWORK_ERROR_SERVER_ERROR, // NETWORK_ERROR_NOT_AUTHORIZED
663 STR_NETWORK_ERROR_SERVER_ERROR, // NETWORK_ERROR_NOT_EXPECTED
664 STR_NETWORK_ERROR_WRONG_REVISION, // NETWORK_ERROR_WRONG_REVISION
665 STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_NAME_IN_USE
666 STR_NETWORK_ERROR_WRONG_PASSWORD, // NETWORK_ERROR_WRONG_PASSWORD
667 STR_NETWORK_ERROR_SERVER_ERROR, // NETWORK_ERROR_COMPANY_MISMATCH
668 STR_NETWORK_ERROR_KICKED, // NETWORK_ERROR_KICKED
669 STR_NETWORK_ERROR_CHEATER, // NETWORK_ERROR_CHEATER
670 STR_NETWORK_ERROR_SERVER_FULL, // NETWORK_ERROR_FULL
671 STR_NETWORK_ERROR_TOO_MANY_COMMANDS, // NETWORK_ERROR_TOO_MANY_COMMANDS
672 STR_NETWORK_ERROR_TIMEOUT_PASSWORD, // NETWORK_ERROR_TIMEOUT_PASSWORD
673 STR_NETWORK_ERROR_TIMEOUT_COMPUTER, // NETWORK_ERROR_TIMEOUT_COMPUTER
674 STR_NETWORK_ERROR_TIMEOUT_MAP, // NETWORK_ERROR_TIMEOUT_MAP
675 STR_NETWORK_ERROR_TIMEOUT_JOIN, // NETWORK_ERROR_TIMEOUT_JOIN
676 STR_NETWORK_ERROR_INVALID_CLIENT_NAME, // NETWORK_ERROR_INVALID_CLIENT_NAME
677 };
678 static_assert(lengthof(network_error_strings) == NETWORK_ERROR_END);
679
680 NetworkErrorCode error = (NetworkErrorCode)p->Recv_uint8();
681
682 Debug(net, 9, "Client::Receive_SERVER_ERROR(): error={}", error);
683
684 StringID err = STR_NETWORK_ERROR_LOSTCONNECTION;
685 if (error < (ptrdiff_t)lengthof(network_error_strings)) err = network_error_strings[error];
686 /* In case of kicking a client, we assume there is a kick message in the packet if we can read one byte */
687 if (error == NETWORK_ERROR_KICKED && p->CanReadFromPacket(1)) {
688 SetDParamStr(0, p->Recv_string(NETWORK_CHAT_LENGTH));
689 ShowErrorMessage(err, STR_NETWORK_ERROR_KICK_MESSAGE, WL_CRITICAL);
690 } else {
691 ShowErrorMessage(err, INVALID_STRING_ID, WL_CRITICAL);
692 }
693
694 /* Perform an emergency save if we had already entered the game */
695 if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave();
696
697 return NETWORK_RECV_STATUS_SERVER_ERROR;
698 }
699
700 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHECK_NEWGRFS(Packet *p)
701 {
702 if (this->status != STATUS_JOIN) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
703
704 uint grf_count = p->Recv_uint8();
705 NetworkRecvStatus ret = NETWORK_RECV_STATUS_OKAY;
706
707 Debug(net, 9, "Client::Receive_SERVER_CHECK_NEWGRFS(): grf_count={}", grf_count);
708
709 /* Check all GRFs */
710 for (; grf_count > 0; grf_count--) {
711 GRFIdentifier c;
712 DeserializeGRFIdentifier(p, &c);
713
714 /* Check whether we know this GRF */
715 const GRFConfig *f = FindGRFConfig(c.grfid, FGCM_EXACT, &c.md5sum);
716 if (f == nullptr) {
717 /* We do not know this GRF, bail out of initialization */
718 Debug(grf, 0, "NewGRF {:08X} not found; checksum {}", BSWAP32(c.grfid), FormatArrayAsHex(c.md5sum));
719 ret = NETWORK_RECV_STATUS_NEWGRF_MISMATCH;
720 }
721 }
722
723 if (ret == NETWORK_RECV_STATUS_OKAY) {
724 /* Start receiving the map */
725 return SendNewGRFsOk();
726 }
727
728 /* NewGRF mismatch, bail out */
729 ShowErrorMessage(STR_NETWORK_ERROR_NEWGRF_MISMATCH, INVALID_STRING_ID, WL_CRITICAL);
730 return ret;
731 }
732
733 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_NEED_GAME_PASSWORD(Packet *)
734 {
735 if (this->status < STATUS_JOIN || this->status >= STATUS_AUTH_GAME) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
736 Debug(net, 9, "Client::status = AUTH_GAME");
737 this->status = STATUS_AUTH_GAME;
738
739 Debug(net, 9, "Client::Receive_SERVER_NEED_GAME_PASSWORD()");
740
741 if (!_network_join.server_password.empty()) {
742 return SendGamePassword(_network_join.server_password);
743 }
744
745 ShowNetworkNeedPassword(NETWORK_GAME_PASSWORD);
746
747 return NETWORK_RECV_STATUS_OKAY;
748 }
749
750 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_NEED_COMPANY_PASSWORD(Packet *p)
751 {
752 if (this->status < STATUS_JOIN || this->status >= STATUS_AUTH_COMPANY) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
753 Debug(net, 9, "Client::status = AUTH_COMPANY");
754 this->status = STATUS_AUTH_COMPANY;
755
756 Debug(net, 9, "Client::Receive_SERVER_NEED_COMPANY_PASSWORD()");
757
758 _password_game_seed = p->Recv_uint32();
759 _password_server_id = p->Recv_string(NETWORK_SERVER_ID_LENGTH);
760 if (this->HasClientQuit()) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
761
762 if (!_network_join.company_password.empty()) {
763 return SendCompanyPassword(_network_join.company_password);
764 }
765
766 ShowNetworkNeedPassword(NETWORK_COMPANY_PASSWORD);
767
768 return NETWORK_RECV_STATUS_OKAY;
769 }
770
771 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_WELCOME(Packet *p)
772 {
773 if (this->status < STATUS_JOIN || this->status >= STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
774 Debug(net, 9, "Client::status = AUTHORIZED");
775 this->status = STATUS_AUTHORIZED;
776
777 _network_own_client_id = (ClientID)p->Recv_uint32();
778
779 Debug(net, 9, "Client::Receive_SERVER_WELCOME(): client_id={}", _network_own_client_id);
780
781 /* Initialize the password hash salting variables, even if they were previously. */
782 _password_game_seed = p->Recv_uint32();
783 _password_server_id = p->Recv_string(NETWORK_SERVER_ID_LENGTH);
784
785 /* Start receiving the map */
786 return SendGetMap();
787 }
788
789 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_WAIT(Packet *p)
790 {
791 /* We set the internal wait state when requesting the map. */
792 if (this->status != STATUS_MAP_WAIT) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
793
794 Debug(net, 9, "Client::Receive_SERVER_WAIT()");
795
796 /* But... only now we set the join status to waiting, instead of requesting. */
797 Debug(net, 9, "Client::join_status = WAITING");
798 _network_join_status = NETWORK_JOIN_STATUS_WAITING;
799 _network_join_waiting = p->Recv_uint8();
800 SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
801
802 return NETWORK_RECV_STATUS_OKAY;
803 }
804
805 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_BEGIN(Packet *p)
806 {
807 if (this->status < STATUS_AUTHORIZED || this->status >= STATUS_MAP) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
808 Debug(net, 9, "Client::status = MAP");
809 this->status = STATUS_MAP;
810
811 if (this->savegame != nullptr) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
812
813 this->savegame = new PacketReader();
814
815 _frame_counter = _frame_counter_server = _frame_counter_max = p->Recv_uint32();
816
817 Debug(net, 9, "Client::Receive_SERVER_MAP_BEGIN(): frame_counter={}", _frame_counter);
818
819 _network_join_bytes = 0;
820 _network_join_bytes_total = 0;
821
822 Debug(net, 9, "Client::join_status = DOWNLOADING");
823 _network_join_status = NETWORK_JOIN_STATUS_DOWNLOADING;
824 SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
825
826 return NETWORK_RECV_STATUS_OKAY;
827 }
828
829 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_SIZE(Packet *p)
830 {
831 if (this->status != STATUS_MAP) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
832 if (this->savegame == nullptr) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
833
834 _network_join_bytes_total = p->Recv_uint32();
835 SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
836
837 Debug(net, 9, "Client::Receive_SERVER_MAP_SIZE(): bytes_total={}", _network_join_bytes_total);
838
839 return NETWORK_RECV_STATUS_OKAY;
840 }
841
842 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DATA(Packet *p)
843 {
844 if (this->status != STATUS_MAP) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
845 if (this->savegame == nullptr) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
846
847 /* We are still receiving data, put it to the file */
848 this->savegame->AddPacket(p);
849
850 _network_join_bytes = (uint32_t)this->savegame->written_bytes;
851 SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
852
853 return NETWORK_RECV_STATUS_OKAY;
854 }
855
856 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet *)
857 {
858 if (this->status != STATUS_MAP) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
859 if (this->savegame == nullptr) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
860
861 Debug(net, 9, "Client::Receive_SERVER_MAP_DONE()");
862
863 Debug(net, 9, "Client::join_status = PROCESSING");
864 _network_join_status = NETWORK_JOIN_STATUS_PROCESSING;
865 SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
866
867 /*
868 * Make sure everything is set for reading.
869 *
870 * We need the local copy and reset this->savegame because when
871 * loading fails the network gets reset upon loading the intro
872 * game, which would cause us to free this->savegame twice.
873 */
874 LoadFilter *lf = this->savegame;
875 this->savegame = nullptr;
876 lf->Reset();
877
878 /* The map is done downloading, load it */
879 ClearErrorMessages();
880 bool load_success = SafeLoad({}, SLO_LOAD, DFT_GAME_FILE, GM_NORMAL, NO_DIRECTORY, lf);
881
882 /* Long savegame loads shouldn't affect the lag calculation! */
883 this->last_packet = std::chrono::steady_clock::now();
884
885 if (!load_success) {
886 ShowErrorMessage(STR_NETWORK_ERROR_SAVEGAMEERROR, INVALID_STRING_ID, WL_CRITICAL);
887 return NETWORK_RECV_STATUS_SAVEGAME;
888 }
889 /* If the savegame has successfully loaded, ALL windows have been removed,
890 * only toolbar/statusbar and gamefield are visible */
891
892 /* Say we received the map and loaded it correctly! */
893 SendMapOk();
894
895 ShowClientList();
896
897 /* New company/spectator (invalid company) or company we want to join is not active
898 * Switch local company to spectator and await the server's judgement */
899 if (_network_join.company == COMPANY_NEW_COMPANY || !Company::IsValidID(_network_join.company)) {
900 SetLocalCompany(COMPANY_SPECTATOR);
901
902 if (_network_join.company != COMPANY_SPECTATOR) {
903 /* We have arrived and ready to start playing; send a command to make a new company;
904 * the server will give us a client-id and let us in */
905 Debug(net, 9, "Client::join_status = REGISTERING");
906 _network_join_status = NETWORK_JOIN_STATUS_REGISTERING;
907 ShowJoinStatusWindow();
908 Command<CMD_COMPANY_CTRL>::SendNet(STR_NULL, _local_company, CCA_NEW, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID);
909 }
910 } else {
911 /* take control over an existing company */
912 SetLocalCompany(_network_join.company);
913 }
914
915 SocialIntegration::EventEnterMultiplayer(Map::SizeX(), Map::SizeY());
916
917 return NETWORK_RECV_STATUS_OKAY;
918 }
919
920 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_FRAME(Packet *p)
921 {
922 if (this->status != STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
923
924 _frame_counter_server = p->Recv_uint32();
925 _frame_counter_max = p->Recv_uint32();
926 #ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
927 /* Test if the server supports this option
928 * and if we are at the frame the server is */
929 #ifdef NETWORK_SEND_DOUBLE_SEED
930 if (p->CanReadFromPacket(sizeof(uint32_t) + sizeof(uint32_t))) {
931 #else
932 if (p->CanReadFromPacket(sizeof(uint32_t))) {
933 #endif
934 _sync_frame = _frame_counter_server;
935 _sync_seed_1 = p->Recv_uint32();
936 #ifdef NETWORK_SEND_DOUBLE_SEED
937 _sync_seed_2 = p->Recv_uint32();
938 #endif
939 }
940 #endif
941 /* Receive the token. */
942 if (p->CanReadFromPacket(sizeof(uint8_t))) this->token = p->Recv_uint8();
943
944 /* Let the server know that we received this frame correctly
945 * We do this only once per day, to save some bandwidth ;) */
946 if (!_network_first_time && last_ack_frame < _frame_counter) {
947 last_ack_frame = _frame_counter + Ticks::DAY_TICKS;
948 Debug(net, 7, "Sent ACK at {}", _frame_counter);
949 SendAck();
950 }
951
952 return NETWORK_RECV_STATUS_OKAY;
953 }
954
955 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_SYNC(Packet *p)
956 {
957 if (this->status != STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
958
959 _sync_frame = p->Recv_uint32();
960 _sync_seed_1 = p->Recv_uint32();
961 #ifdef NETWORK_SEND_DOUBLE_SEED
962 _sync_seed_2 = p->Recv_uint32();
963 #endif
964
965 Debug(net, 9, "Client::Receive_SERVER_SYNC(): sync_frame={}, sync_seed_1={}", _sync_frame, _sync_seed_1);
966
967 return NETWORK_RECV_STATUS_OKAY;
968 }
969
970 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_COMMAND(Packet *p)
971 {
972 if (this->status != STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
973
974 CommandPacket cp;
975 const char *err = this->ReceiveCommand(p, &cp);
976 cp.frame = p->Recv_uint32();
977 cp.my_cmd = p->Recv_bool();
978
979 Debug(net, 9, "Client::Receive_SERVER_COMMAND(): cmd={}, frame={}", cp.cmd, cp.frame);
980
981 if (err != nullptr) {
982 IConsolePrint(CC_WARNING, "Dropping server connection due to {}.", err);
983 return NETWORK_RECV_STATUS_MALFORMED_PACKET;
984 }
985
986 this->incoming_queue.Append(&cp);
987
988 return NETWORK_RECV_STATUS_OKAY;
989 }
990
991 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p)
992 {
993 if (this->status != STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
994
995 std::string name;
996 const NetworkClientInfo *ci = nullptr, *ci_to;
997
998 NetworkAction action = (NetworkAction)p->Recv_uint8();
999 ClientID client_id = (ClientID)p->Recv_uint32();
1000 bool self_send = p->Recv_bool();
1001 std::string msg = p->Recv_string(NETWORK_CHAT_LENGTH);
1002 int64_t data = p->Recv_uint64();
1003
1004 Debug(net, 9, "Client::Receive_SERVER_CHAT(): action={}, client_id={}, self_send={}", action, client_id, self_send);
1005
1006 ci_to = NetworkClientInfo::GetByClientID(client_id);
1007 if (ci_to == nullptr) return NETWORK_RECV_STATUS_OKAY;
1008
1009 /* Did we initiate the action locally? */
1010 if (self_send) {
1011 switch (action) {
1012 case NETWORK_ACTION_CHAT_CLIENT:
1013 /* For speaking to client we need the client-name */
1014 name = ci_to->client_name;
1015 ci = NetworkClientInfo::GetByClientID(_network_own_client_id);
1016 break;
1017
1018 /* For speaking to company, we need the company-name */
1019 case NETWORK_ACTION_CHAT_COMPANY: {
1020 StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;
1021 SetDParam(0, ci_to->client_playas);
1022
1023 name = GetString(str);
1024 ci = NetworkClientInfo::GetByClientID(_network_own_client_id);
1025 break;
1026 }
1027
1028 default: return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1029 }
1030 } else {
1031 /* Display message from somebody else */
1032 name = ci_to->client_name;
1033 ci = ci_to;
1034 }
1035
1036 if (ci != nullptr) {
1037 NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), self_send, name, msg, data);
1038 }
1039 return NETWORK_RECV_STATUS_OKAY;
1040 }
1041
1042 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_EXTERNAL_CHAT(Packet *p)
1043 {
1044 if (this->status != STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1045
1046 std::string source = p->Recv_string(NETWORK_CHAT_LENGTH);
1047 TextColour colour = (TextColour)p->Recv_uint16();
1048 std::string user = p->Recv_string(NETWORK_CHAT_LENGTH);
1049 std::string msg = p->Recv_string(NETWORK_CHAT_LENGTH);
1050
1051 Debug(net, 9, "Client::Receive_SERVER_EXTERNAL_CHAT(): source={}", source);
1052
1053 if (!IsValidConsoleColour(colour)) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1054
1055 NetworkTextMessage(NETWORK_ACTION_EXTERNAL_CHAT, colour, false, user, msg, 0, source);
1056
1057 return NETWORK_RECV_STATUS_OKAY;
1058 }
1059
1060 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR_QUIT(Packet *p)
1061 {
1062 if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1063
1064 ClientID client_id = (ClientID)p->Recv_uint32();
1065
1066 Debug(net, 9, "Client::Receive_SERVER_ERROR_QUIT(): client_id={}", client_id);
1067
1068 NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
1069 if (ci != nullptr) {
1070 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, "", GetNetworkErrorMsg((NetworkErrorCode)p->Recv_uint8()));
1071 delete ci;
1072 }
1073
1074 InvalidateWindowData(WC_CLIENT_LIST, 0);
1075
1076 return NETWORK_RECV_STATUS_OKAY;
1077 }
1078
1079 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_QUIT(Packet *p)
1080 {
1081 if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1082
1083 ClientID client_id = (ClientID)p->Recv_uint32();
1084
1085 Debug(net, 9, "Client::Receive_SERVER_QUIT(): client_id={}", client_id);
1086
1087 NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
1088 if (ci != nullptr) {
1089 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, "", STR_NETWORK_MESSAGE_CLIENT_LEAVING);
1090 delete ci;
1091 } else {
1092 Debug(net, 1, "Unknown client ({}) is leaving the game", client_id);
1093 }
1094
1095 InvalidateWindowData(WC_CLIENT_LIST, 0);
1096
1097 /* If we come here it means we could not locate the client.. strange :s */
1098 return NETWORK_RECV_STATUS_OKAY;
1099 }
1100
1101 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_JOIN(Packet *p)
1102 {
1103 if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1104
1105 ClientID client_id = (ClientID)p->Recv_uint32();
1106
1107 Debug(net, 9, "Client::Receive_SERVER_JOIN(): client_id={}", client_id);
1108
1109 NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
1110 if (ci != nullptr) {
1111 NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, ci->client_name);
1112 }
1113
1114 InvalidateWindowData(WC_CLIENT_LIST, 0);
1115
1116 return NETWORK_RECV_STATUS_OKAY;
1117 }
1118
1119 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_SHUTDOWN(Packet *)
1120 {
1121 Debug(net, 9, "Client::Receive_SERVER_SHUTDOWN()");
1122
1123 /* Only when we're trying to join we really
1124 * care about the server shutting down. */
1125 if (this->status >= STATUS_JOIN) {
1126 ShowErrorMessage(STR_NETWORK_MESSAGE_SERVER_SHUTDOWN, INVALID_STRING_ID, WL_CRITICAL);
1127 }
1128
1129 if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave();
1130
1131 return NETWORK_RECV_STATUS_SERVER_ERROR;
1132 }
1133
1134 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_NEWGAME(Packet *)
1135 {
1136 Debug(net, 9, "Client::Receive_SERVER_NEWGAME()");
1137
1138 /* Only when we're trying to join we really
1139 * care about the server shutting down. */
1140 if (this->status >= STATUS_JOIN) {
1141 /* To throttle the reconnects a bit, every clients waits its
1142 * Client ID modulo 16 + 1 (value 0 means no reconnect).
1143 * This way reconnects should be spread out a bit. */
1144 _network_reconnect = _network_own_client_id % 16 + 1;
1145 ShowErrorMessage(STR_NETWORK_MESSAGE_SERVER_REBOOT, INVALID_STRING_ID, WL_CRITICAL);
1146 }
1147
1148 if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave();
1149
1150 return NETWORK_RECV_STATUS_SERVER_ERROR;
1151 }
1152
1153 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_RCON(Packet *p)
1154 {
1155 if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1156
1157 Debug(net, 9, "Client::Receive_SERVER_RCON()");
1158
1159 TextColour colour_code = (TextColour)p->Recv_uint16();
1160 if (!IsValidConsoleColour(colour_code)) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1161
1162 std::string rcon_out = p->Recv_string(NETWORK_RCONCOMMAND_LENGTH);
1163
1164 IConsolePrint(colour_code, rcon_out);
1165
1166 return NETWORK_RECV_STATUS_OKAY;
1167 }
1168
1169 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MOVE(Packet *p)
1170 {
1171 if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1172
1173 /* Nothing more in this packet... */
1174 ClientID client_id = (ClientID)p->Recv_uint32();
1175 CompanyID company_id = (CompanyID)p->Recv_uint8();
1176
1177 Debug(net, 9, "Client::Receive_SERVER_MOVE(): client_id={}, comapny_id={}", client_id, company_id);
1178
1179 if (client_id == 0) {
1180 /* definitely an invalid client id, debug message and do nothing. */
1181 Debug(net, 1, "Received invalid client index = 0");
1182 return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1183 }
1184
1185 const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
1186 /* Just make sure we do not try to use a client_index that does not exist */
1187 if (ci == nullptr) return NETWORK_RECV_STATUS_OKAY;
1188
1189 /* if not valid player, force spectator, else check player exists */
1190 if (!Company::IsValidID(company_id)) company_id = COMPANY_SPECTATOR;
1191
1192 if (client_id == _network_own_client_id) {
1193 SetLocalCompany(company_id);
1194 }
1195
1196 return NETWORK_RECV_STATUS_OKAY;
1197 }
1198
1199 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CONFIG_UPDATE(Packet *p)
1200 {
1201 if (this->status < STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1202
1203 _network_server_max_companies = p->Recv_uint8();
1204 _network_server_name = p->Recv_string(NETWORK_NAME_LENGTH);
1205 SetWindowClassesDirty(WC_CLIENT_LIST);
1206
1207 Debug(net, 9, "Client::Receive_SERVER_CONFIG_UPDATE(): max_companies={}", _network_server_max_companies);
1208
1209 return NETWORK_RECV_STATUS_OKAY;
1210 }
1211
1212 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_COMPANY_UPDATE(Packet *p)
1213 {
1214 if (this->status < STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1215
1216 static_assert(sizeof(_network_company_passworded) <= sizeof(uint16_t));
1217 _network_company_passworded = p->Recv_uint16();
1218 SetWindowClassesDirty(WC_COMPANY);
1219
1220 Debug(net, 9, "Client::Receive_SERVER_COMPANY_UPDATE()");
1221
1222 return NETWORK_RECV_STATUS_OKAY;
1223 }
1224
1228 void ClientNetworkGameSocketHandler::CheckConnection()
1229 {
1230 /* Only once we're authorized we can expect a steady stream of packets. */
1231 if (this->status < STATUS_AUTHORIZED) return;
1232
1233 /* 5 seconds are roughly twice the server's "you're slow" threshold (1 game day). */
1234 std::chrono::steady_clock::duration lag = std::chrono::steady_clock::now() - this->last_packet;
1235 if (lag < std::chrono::seconds(5)) return;
1236
1237 /* 20 seconds are (way) more than 4 game days after which
1238 * the server will forcefully disconnect you. */
1239 if (lag > std::chrono::seconds(20)) {
1240 this->NetworkGameSocketHandler::CloseConnection();
1241 return;
1242 }
1243
1244 /* Prevent showing the lag message every tick; just update it when needed. */
1245 static std::chrono::steady_clock::duration last_lag = {};
1246 if (std::chrono::duration_cast<std::chrono::seconds>(last_lag) == std::chrono::duration_cast<std::chrono::seconds>(lag)) return;
1247
1248 last_lag = lag;
1249 SetDParam(0, std::chrono::duration_cast<std::chrono::seconds>(lag).count());
1250 ShowErrorMessage(STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION, STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION, WL_INFO);
1251 }
1252
1253
1255 void NetworkClient_Connected()
1256 {
1257 /* Set the frame-counter to 0 so nothing happens till we are ready */
1258 _frame_counter = 0;
1259 _frame_counter_server = 0;
1260 last_ack_frame = 0;
1261
1262 Debug(net, 9, "Client::NetworkClient_Connected()");
1263
1264 /* Request the game-info */
1265 MyClient::SendJoin();
1266 }
1267
1273 void NetworkClientSendRcon(const std::string &password, const std::string &command)
1274 {
1275 MyClient::SendRCon(password, command);
1276 }
1277
1284 void NetworkClientRequestMove(CompanyID company_id, const std::string &pass)
1285 {
1286 MyClient::SendMove(company_id, pass);
1287 }
1288
1293 void NetworkClientsToSpectators(CompanyID cid)
1294 {
1295 Backup<CompanyID> cur_company(_current_company, FILE_LINE);
1296 /* If our company is changing owner, go to spectators */
1297 if (cid == _local_company) SetLocalCompany(COMPANY_SPECTATOR);
1298
1299 for (NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
1300 if (ci->client_playas != cid) continue;
1301 NetworkTextMessage(NETWORK_ACTION_COMPANY_SPECTATOR, CC_DEFAULT, false, ci->client_name);
1302 ci->client_playas = COMPANY_SPECTATOR;
1303 }
1304
1305 cur_company.Restore();
1306 }
1307
1315 bool NetworkIsValidClientName(const std::string_view client_name)
1316 {
1317 if (client_name.empty()) return false;
1318 if (client_name[0] == ' ') return false;
1319 return true;
1320 }
1321
1337 bool NetworkValidateClientName(std::string &client_name)
1338 {
1339 StrTrimInPlace(client_name);
1340 if (NetworkIsValidClientName(client_name)) return true;
1341
1342 ShowErrorMessage(STR_NETWORK_ERROR_BAD_PLAYER_NAME, INVALID_STRING_ID, WL_ERROR);
1343 return false;
1344 }
1345
1353 bool NetworkValidateOurClientName()
1354 {
1355 return NetworkValidateClientName(_settings_client.network.client_name);
1356 }
1357
1362 void NetworkUpdateClientName(const std::string &client_name)
1363 {
1364 NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(_network_own_client_id);
1365 if (ci == nullptr) return;
1366
1367 /* Don't change the name if it is the same as the old name */
1368 if (client_name.compare(ci->client_name) != 0) {
1369 if (!_network_server) {
1370 MyClient::SendSetName(client_name);
1371 } else {
1372 /* Copy to a temporary buffer so no #n gets added after our name in the settings when there are duplicate names. */
1373 std::string temporary_name = client_name;
1374 if (NetworkMakeClientNameUnique(temporary_name)) {
1375 NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, temporary_name);
1376 ci->client_name = temporary_name;
1377 NetworkUpdateClientInfo(CLIENT_ID_SERVER);
1378 }
1379 }
1380 }
1381 }
1382
1391 void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, int64_t data)
1392 {
1393 MyClient::SendChat(action, type, dest, msg, data);
1394 }
1395
1400 void NetworkClientSetCompanyPassword(const std::string &password)
1401 {
1402 MyClient::SendSetPassword(password);
1403 }
1404
1410 bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio)
1411 {
1412 /* Only companies actually playing can speak to team. Eg spectators cannot */
1413 if (!_settings_client.gui.prefer_teamchat || !Company::IsValidID(cio->client_playas)) return false;
1414
1415 for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
1416 if (ci->client_playas == cio->client_playas && ci != cio) return true;
1417 }
1418
1419 return false;
1420 }
1421
1426 uint NetworkMaxCompaniesAllowed()
1427 {
1428 return _network_server ? _settings_client.network.max_companies : _network_server_max_companies;
1429 }
1430
1435 bool NetworkMaxCompaniesReached()
1436 {
1437 return Company::GetNumItems() >= NetworkMaxCompaniesAllowed();
1438 }
Packet::Recv_uint64
uint64_t Recv_uint64()
Read a 64 bits integer from the packet.
Definition: packet.cpp:363
NetworkClientSendRcon
void NetworkClientSendRcon(const std::string &password, const std::string &command)
Send a remote console command.
Definition: network_client.cpp:1273
ClientNetworkGameSocketHandler::Receive_SERVER_FRAME
NetworkRecvStatus Receive_SERVER_FRAME(Packet *p) override
Sends the current frame counter to the client: uint32_t Frame counter uint32_t Frame counter max (how...
Definition: network_client.cpp:920
PacketReader::AddPacket
void AddPacket(Packet *p)
Add a packet to this buffer.
Definition: network_client.cpp:84
ClientNetworkGameSocketHandler::SendNewGRFsOk
static NetworkRecvStatus SendNewGRFsOk()
Tell the server we got all the NewGRFs.
Definition: network_client.cpp:360
InvalidateWindowData
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-...
Definition: window.cpp:3200
ClientNetworkGameSocketHandler::Receive_SERVER_CHAT
NetworkRecvStatus Receive_SERVER_CHAT(Packet *p) override
Sends a chat-packet to the client: uint8_t ID of the action (see NetworkAction).
Definition: network_client.cpp:991
NETWORK_RECV_STATUS_CLIENT_QUIT
@ NETWORK_RECV_STATUS_CLIENT_QUIT
The connection is lost gracefully. Other clients are already informed of this leaving client.
Definition: core.h:27
Packet::Send_uint64
void Send_uint64(uint64_t data)
Package a 64 bits integer in the packet.
Definition: packet.cpp:163
FormatArrayAsHex
std::string FormatArrayAsHex(std::span< const byte > data)
Format a byte array into a continuous hex string.
Definition: string.cpp:88
PACKET_CLIENT_ERROR
@ PACKET_CLIENT_ERROR
A client reports an error to the server.
Definition: tcp_game.h:125
SetWindowDirty
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3082
NetworkValidateOurClientName
bool NetworkValidateOurClientName()
Convenience method for NetworkValidateClientName on _settings_client.network.client_name.
Definition: network_client.cpp:1353
NetworkGameSocketHandler::ReceivePackets
NetworkRecvStatus ReceivePackets()
Do the actual receiving of packets.
Definition: tcp_game.cpp:136
CSleep
void CSleep(int milliseconds)
Sleep on the current thread for a defined time.
Definition: thread.h:23
NetworkValidateClientName
bool NetworkValidateClientName(std::string &client_name)
Trim the given client name in place, i.e.
Definition: network_client.cpp:1337
NETWORK_RECV_STATUS_DESYNC
@ NETWORK_RECV_STATUS_DESYNC
A desync did occur.
Definition: core.h:24
ShowErrorMessage
void ShowErrorMessage(StringID summary_msg, int x, int y, CommandCost cc)
Display an error message in a window.
Definition: error_gui.cpp:367
ClientNetworkGameSocketHandler::STATUS_AUTH_COMPANY
@ STATUS_AUTH_COMPANY
Last action was requesting company password.
Definition: network_client.h:28
NetworkClientInfo::client_name
std::string client_name
Name of the client.
Definition: network_base.h:26
NetworkJoinInfo::company_password
std::string company_password
The password of the company to join.
Definition: network_client.h:116
Backup
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:21
ClientNetworkGameSocketHandler::Receive_SERVER_BANNED
NetworkRecvStatus Receive_SERVER_BANNED(Packet *p) override
Notification that the client trying to join is banned.
Definition: network_client.cpp:582
CommandPacket::frame
uint32_t frame
the frame in which this packet is executed
Definition: network_internal.h:114
NETWORK_NAME_LENGTH
static const uint NETWORK_NAME_LENGTH
The maximum length of the server name and map name, in bytes including '\0'.
Definition: config.h:53
NetworkClientInfo::client_playas
CompanyID client_playas
As which company is this client playing (CompanyID)
Definition: network_base.h:27
ClientNetworkEmergencySave
void ClientNetworkEmergencySave()
Create an emergency savegame when the network connection is lost.
Definition: network_client.cpp:135
NetworkClientRequestMove
void NetworkClientRequestMove(CompanyID company_id, const std::string &pass)
Notify the server of this client wanting to be moved to another company.
Definition: network_client.cpp:1284
StringID
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
_network_server
bool _network_server
network-server is active
Definition: network.cpp:60
SaveLoadOperation
SaveLoadOperation
Operation performed on the file.
Definition: fileio_type.h:47
ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler
ClientNetworkGameSocketHandler(SOCKET s, const std::string &connection_string)
Create a new socket for the client side of the game connection.
Definition: network_client.cpp:146
_network_company_passworded
CompanyMask _network_company_passworded
Bitmask of the password status of all companies.
Definition: network.cpp:82
CloseWindowById
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition: window.cpp:1141
NetworkAction
NetworkAction
Actions that can be used for NetworkTextMessage.
Definition: network_type.h:102
NetworkClientPreferTeamChat
bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio)
Tell whether the client has team members who they can chat to.
Definition: network_client.cpp:1410
NetworkGameSocketHandler::last_packet
std::chrono::steady_clock::time_point last_packet
Time we received the last frame.
Definition: tcp_game.h:513
WC_CLIENT_LIST
@ WC_CLIENT_LIST
Client list; Window numbers:
Definition: window_type.h:478
ClientNetworkGameSocketHandler::Receive_SERVER_COMPANY_UPDATE
NetworkRecvStatus Receive_SERVER_COMPANY_UPDATE(Packet *p) override
Update the clients knowledge of which company is password protected: uint16_t Bitwise representation ...
Definition: network_client.cpp:1212
ClientNetworkGameSocketHandler::CheckConnection
void CheckConnection()
Check the connection's state, i.e.
Definition: network_client.cpp:1228
NetworkJoinInfo::server_password
std::string server_password
The password of the server to join.
Definition: network_client.h:115
NetworkGameSocketHandler::SetInfo
void SetInfo(NetworkClientInfo *info)
Sets the client info for this socket handler.
Definition: tcp_game.h:528
NetworkUpdateClientInfo
void NetworkUpdateClientInfo(ClientID client_id)
Send updated client info of a particular client.
Definition: network_server.cpp:1569
ClientNetworkGameSocketHandler::GameLoop
static bool GameLoop()
Actual game loop for the client.
Definition: network_client.cpp:269
PacketReader::block
byte ** block
The block we're reading from/writing to.
Definition: network_client.cpp:49
NETWORK_CHAT_LENGTH
static const uint NETWORK_CHAT_LENGTH
The maximum length of a chat message, in bytes including '\0'.
Definition: config.h:63
ClientNetworkGameSocketHandler::SendChat
static NetworkRecvStatus SendChat(NetworkAction action, DestType type, int dest, const std::string &msg, int64_t data)
Send a chat-packet over the network.
Definition: network_client.cpp:452
PACKET_CLIENT_COMMAND
@ PACKET_CLIENT_COMMAND
Client executed a command and sends it to the server.
Definition: tcp_game.h:96
SetLocalCompany
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...
Definition: company_cmd.cpp:114
DFT_GAME_FILE
@ DFT_GAME_FILE
Save game or scenario file.
Definition: fileio_type.h:31
NetworkTCPSocketHandler::sock
SOCKET sock
The socket currently connected to.
Definition: tcp.h:38
TextColour
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition: gfx_type.h:253
PacketReader::written_bytes
size_t written_bytes
The total number of bytes we've written.
Definition: network_client.cpp:50
_random
Randomizer _random
Random used in the game state calculations.
Definition: random_func.cpp:37
TimerGameEconomy::date_fract
static DateFract date_fract
Fractional part of the day.
Definition: timer_game_economy.h:38
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:54
PACKET_CLIENT_QUIT
@ PACKET_CLIENT_QUIT
A client tells the server it is going to quit.
Definition: tcp_game.h:123
network_gui.h
_network_join_status
NetworkJoinStatus _network_join_status
The status of joining.
Definition: network_gui.cpp:2101
PACKET_CLIENT_GETMAP
@ PACKET_CLIENT_GETMAP
Client requests the actual map.
Definition: tcp_game.h:74
ClientNetworkGameSocketHandler::Receive_SERVER_ERROR
NetworkRecvStatus Receive_SERVER_ERROR(Packet *p) override
The client made an error: uint8_t Error code caused (see NetworkErrorCode).
Definition: network_client.cpp:653
WC_COMPANY
@ WC_COMPANY
Company view; Window numbers:
Definition: window_type.h:369
GetNetworkErrorMsg
StringID GetNetworkErrorMsg(NetworkErrorCode err)
Retrieve the string id of an internal error number.
Definition: network.cpp:298
_network_server_name
std::string _network_server_name
The current name of the server you are on.
Definition: network_client.cpp:325
ClientNetworkGameSocketHandler::my_client
static ClientNetworkGameSocketHandler * my_client
This is us!
Definition: network_client.h:41
ClientNetworkGameSocketHandler::Receive_SERVER_MAP_BEGIN
NetworkRecvStatus Receive_SERVER_MAP_BEGIN(Packet *p) override
Sends that the server will begin with sending the map to the client: uint32_t Current frame.
Definition: network_client.cpp:805
Owner
Owner
Enum for all companies/owners.
Definition: company_type.h:18
ClientNetworkGameSocketHandler::CloseConnection
NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override
Close the network connection due to the given status.
Definition: network_client.cpp:162
NetworkGameSocketHandler
Base socket handler for all TCP sockets.
Definition: tcp_game.h:154
LoadFilter::Reset
virtual void Reset()
Reset this filter to read from the beginning of the file.
Definition: saveload_filter.h:43
PacketReader::Read
size_t Read(byte *rbuf, size_t size) override
Read a given number of bytes from the savegame.
Definition: network_client.cpp:99
ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO
NetworkRecvStatus Receive_SERVER_CLIENT_INFO(Packet *p) override
Send information about a client: uint32_t ID of the client (always unique on a server.
Definition: network_client.cpp:595
CC_DEFAULT
static const TextColour CC_DEFAULT
Default colour of the console.
Definition: console_type.h:23
PacketReader
Read some packets, and when do use that data as initial load filter.
Definition: network_client.cpp:43
_network_first_time
bool _network_first_time
Whether we have finished joining or not.
Definition: network.cpp:81
Debug
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
PACKET_CLIENT_CHAT
@ PACKET_CLIENT_CHAT
Client said something that should be distributed.
Definition: tcp_game.h:100
ClientNetworkGameSocketHandler::Receive_SERVER_NEWGAME
NetworkRecvStatus Receive_SERVER_NEWGAME(Packet *p) override
Let the clients know that the server is loading a new map.
Definition: network_client.cpp:1134
network_base.h
PacketReader::read_bytes
size_t read_bytes
The total number of read bytes.
Definition: network_client.cpp:51
PACKET_CLIENT_JOIN
@ PACKET_CLIENT_JOIN
The client telling the server it wants to join.
Definition: tcp_game.h:38
Packet::CanReadFromPacket
bool CanReadFromPacket(size_t bytes_to_read, bool close_connection=false)
Is it safe to read from the packet, i.e.
Definition: packet.cpp:229
Packet::Recv_string
std::string Recv_string(size_t length, StringValidationSettings settings=SVS_REPLACE_WITH_QUESTION_MARK)
Reads characters (bytes) from the packet until it finds a '\0', or reaches a maximum of length charac...
Definition: packet.cpp:408
ClientNetworkGameSocketHandler::Receive_SERVER_NEED_COMPANY_PASSWORD
NetworkRecvStatus Receive_SERVER_NEED_COMPANY_PASSWORD(Packet *p) override
Indication to the client that the server needs a company password: uint32_t Generation seed.
Definition: network_client.cpp:750
CommandQueue::Append
void Append(CommandPacket *p)
Append a CommandPacket at the end of the queue.
Definition: network_command.cpp:174
ClientNetworkGameSocketHandler::Receive_SERVER_NEED_GAME_PASSWORD
NetworkRecvStatus Receive_SERVER_NEED_GAME_PASSWORD(Packet *p) override
Indication to the client that the server needs a game password.
Definition: network_client.cpp:733
ClientNetworkGameSocketHandler::SendJoin
static NetworkRecvStatus SendJoin()
Make sure the server ID length is the same as a md5 hash.
Definition: network_client.cpp:339
_sync_seed_1
uint32_t _sync_seed_1
Seed to compare during sync checks.
Definition: network.cpp:76
_password_game_seed
static uint32_t _password_game_seed
One bit of 'entropy' used to generate a salt for the company passwords.
Definition: network_client.cpp:318
NetworkClientInfo::GetByClientID
static NetworkClientInfo * GetByClientID(ClientID client_id)
Return the CI given it's client-identifier.
Definition: network.cpp:114
NetworkJoinInfo::company
CompanyID company
The company to join.
Definition: network_client.h:114
GRFIdentifier
Basic data to distinguish a GRF.
Definition: newgrf_config.h:83
Packet::TransferOutWithLimit
ssize_t TransferOutWithLimit(F transfer_function, size_t limit, D destination, Args &&... args)
Transfer data from the packet to the given function.
Definition: packet.h:111
ClientNetworkGameSocketHandler::SendMove
static NetworkRecvStatus SendMove(CompanyID company, const std::string &password)
Ask the server to move us.
Definition: network_client.cpp:544
ClientNetworkGameSocketHandler::STATUS_MAP
@ STATUS_MAP
The client is downloading the map.
Definition: network_client.h:31
ClientNetworkGameSocketHandler::SendCompanyPassword
static NetworkRecvStatus SendCompanyPassword(const std::string &password)
Set the company password as requested.
Definition: network_client.cpp:387
ClearErrorMessages
void ClearErrorMessages()
Clear all errors from the queue.
Definition: error_gui.cpp:328
ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DATA
NetworkRecvStatus Receive_SERVER_MAP_DATA(Packet *p) override
Sends the data of the map to the client: Contains a part of the map (until max size of packet).
Definition: network_client.cpp:842
COMPANY_NEW_COMPANY
@ COMPANY_NEW_COMPANY
The client wants a new company.
Definition: company_type.h:34
Packet::Send_uint32
void Send_uint32(uint32_t data)
Package a 32 bits integer in the packet.
Definition: packet.cpp:150
SLO_LOAD
@ SLO_LOAD
File is being loaded.
Definition: fileio_type.h:49
ClientNetworkGameSocketHandler::Receive_SERVER_FULL
NetworkRecvStatus Receive_SERVER_FULL(Packet *p) override
Notification that the server is full.
Definition: network_client.cpp:572
PacketReader::CHUNK
static const size_t CHUNK
32 KiB chunks of memory.
Definition: network_client.cpp:44
ClientNetworkGameSocketHandler::SendSetName
static NetworkRecvStatus SendSetName(const std::string &name)
Tell the server that we like to change the name of the client.
Definition: network_client.cpp:499
Packet::Send_uint8
void Send_uint8(uint8_t data)
Package a 8 bits integer in the packet.
Definition: packet.cpp:129
BSWAP32
static uint32_t BSWAP32(uint32_t x)
Perform a 32 bits endianness bitswap on x.
Definition: bitmath_func.hpp:345
CommandPacket
Everything we need to know about a command to be able to execute it.
Definition: network_internal.h:109
ClientNetworkGameSocketHandler::Receive_SERVER_CHECK_NEWGRFS
NetworkRecvStatus Receive_SERVER_CHECK_NEWGRFS(Packet *p) override
Sends information about all used GRFs to the client: uint8_t Amount of GRFs (the following data is re...
Definition: network_client.cpp:700
GRFConfig
Information about GRF, used in the game and (part of it) in savegames.
Definition: newgrf_config.h:147
PacketReader::blocks
std::vector< byte * > blocks
Buffer with blocks of allocated memory.
Definition: network_client.cpp:46
NETWORK_RECV_STATUS_NEWGRF_MISMATCH
@ NETWORK_RECV_STATUS_NEWGRF_MISMATCH
We did not have the required NewGRFs.
Definition: core.h:25
NetworkMaxCompaniesReached
bool NetworkMaxCompaniesReached()
Check if max_companies has been reached on the server (local check only).
Definition: network_client.cpp:1435
NETWORK_RECV_STATUS_SERVER_FULL
@ NETWORK_RECV_STATUS_SERVER_FULL
The server is full.
Definition: core.h:30
Packet::Recv_uint32
uint32_t Recv_uint32()
Read a 32 bits integer from the packet.
Definition: packet.cpp:346
ClientNetworkGameSocketHandler::IsConnected
static bool IsConnected()
Check whether the client is actually connected (and in the game).
Definition: network_client.cpp:559
free
void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: stdafx.h:379
StrTrimInPlace
void StrTrimInPlace(std::string &str)
Trim the spaces from given string in place, i.e.
Definition: string.cpp:288
NETWORK_RECV_STATUS_SERVER_ERROR
@ NETWORK_RECV_STATUS_SERVER_ERROR
The server told us we made an error.
Definition: core.h:29
GRFIdentifier::md5sum
MD5Hash md5sum
MD5 checksum of file to distinguish files with the same GRF ID (eg. newer version of GRF)
Definition: newgrf_config.h:85
ClientNetworkGameSocketHandler::Receive_SERVER_WELCOME
NetworkRecvStatus Receive_SERVER_WELCOME(Packet *p) override
The client is joined and ready to receive their map: uint32_t Own client ID.
Definition: network_client.cpp:771
ClientNetworkGameSocketHandler::Receive_SERVER_JOIN
NetworkRecvStatus Receive_SERVER_JOIN(Packet *p) override
A client joined (PACKET_CLIENT_MAP_OK), what usually directly follows is a PACKET_SERVER_CLIENT_INFO:...
Definition: network_client.cpp:1101
_password_server_id
static std::string _password_server_id
The other bit of 'entropy' used to generate a salt for the company passwords.
Definition: network_client.cpp:320
NETWORK_RECV_STATUS_SERVER_BANNED
@ NETWORK_RECV_STATUS_SERVER_BANNED
The server has banned us.
Definition: core.h:31
last_ack_frame
static uint32_t last_ack_frame
Last frame we performed an ack.
Definition: network_client.cpp:315
NetworkUpdateClientName
void NetworkUpdateClientName(const std::string &client_name)
Send the server our name as callback from the setting.
Definition: network_client.cpp:1362
NetworkClient_Connected
void NetworkClient_Connected()
Is called after a client is connected to the server.
Definition: network_client.cpp:1255
PACKET_CLIENT_NEWGRFS_CHECKED
@ PACKET_CLIENT_NEWGRFS_CHECKED
Client acknowledges that it has all required NewGRFs.
Definition: tcp_game.h:61
PacketReader::Reset
void Reset() override
Reset this filter to read from the beginning of the file.
Definition: network_client.cpp:121
NetworkClientsToSpectators
void NetworkClientsToSpectators(CompanyID cid)
Move the clients of a company to the spectators.
Definition: network_client.cpp:1293
WL_INFO
@ WL_INFO
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
Definition: error.h:24
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:49
ClientNetworkGameSocketHandler::STATUS_JOIN
@ STATUS_JOIN
We are trying to join a server.
Definition: network_client.h:25
NetworkSocketHandler::MarkClosed
void MarkClosed()
Mark the connection as closed.
Definition: core.h:60
NETWORK_COMPANY_PASSWORD
@ NETWORK_COMPANY_PASSWORD
The password of the company.
Definition: network_type.h:84
NetworkSettings::client_name
std::string client_name
name of the player (as client)
Definition: settings_type.h:318
IsValidConsoleColour
bool IsValidConsoleColour(TextColour c)
Check whether the given TextColour is valid for console usage.
Definition: console_gui.cpp:488
NETWORK_RECV_STATUS_CLOSE_QUERY
@ NETWORK_RECV_STATUS_CLOSE_QUERY
Done querying the server.
Definition: core.h:32
NetworkTCPSocketHandler::SendPacket
virtual void SendPacket(Packet *packet)
This function puts the packet in the send-queue and it is send as soon as possible.
Definition: tcp.cpp:81
ClientNetworkGameSocketHandler::SendRCon
static NetworkRecvStatus SendRCon(const std::string &password, const std::string &command)
Send a console command.
Definition: network_client.cpp:528
NETWORK_SERVER_ID_LENGTH
static const uint NETWORK_SERVER_ID_LENGTH
The maximum length of the network id of the servers, in bytes including '\0'.
Definition: config.h:57
_networking
bool _networking
are we in networking mode?
Definition: network.cpp:59
ClientNetworkGameSocketHandler::STATUS_MAP_WAIT
@ STATUS_MAP_WAIT
The client is waiting as someone else is downloading the map.
Definition: network_client.h:30
network_client.h
CommandPacket::my_cmd
bool my_cmd
did the command originate from "me"
Definition: network_internal.h:115
DoAutoOrNetsave
void DoAutoOrNetsave(FiosNumberedSaveName &counter)
Create an autosave or netsave.
Definition: saveload.cpp:3141
PACKET_CLIENT_MAP_OK
@ PACKET_CLIENT_MAP_OK
Client tells the server that it received the whole map.
Definition: tcp_game.h:80
Packet
Internal entity of a packet.
Definition: packet.h:42
ClientNetworkGameSocketHandler::Receive_SERVER_EXTERNAL_CHAT
NetworkRecvStatus Receive_SERVER_EXTERNAL_CHAT(Packet *p) override
Sends a chat-packet for external source to the client: string Name of the source this message came fr...
Definition: network_client.cpp:1042
GameMode
GameMode
Mode which defines the state of the game.
Definition: openttd.h:18
NetworkGameSocketHandler::ReceiveCommand
const char * ReceiveCommand(Packet *p, CommandPacket *cp)
Receives a command from the network.
Definition: network_command.cpp:427
PacketReader::buf
byte * buf
Buffer we're going to write to/read from.
Definition: network_client.cpp:47
SocialIntegration::EventEnterMultiplayer
static void EventEnterMultiplayer(uint map_width, uint map_height)
Event: user entered a multiplayer game.
Definition: social_integration.cpp:234
GUISettings::prefer_teamchat
bool prefer_teamchat
choose the chat message target with <ENTER>, true=all clients, false=your team
Definition: settings_type.h:149
_network_own_client_id
ClientID _network_own_client_id
Our client identifier.
Definition: network.cpp:65
Map::SizeX
static debug_inline uint SizeX()
Get the size of the map along the X.
Definition: map_func.h:270
PACKET_CLIENT_SET_NAME
@ PACKET_CLIENT_SET_NAME
A client changes its name.
Definition: tcp_game.h:114
ClientNetworkGameSocketHandler::Receive
static bool Receive()
Check whether we received/can send some data from/to the server and when that's the case handle it ap...
Definition: network_client.cpp:244
CCA_NEW
@ CCA_NEW
Create a new company.
Definition: company_type.h:68
NetworkGameSocketHandler::GetInfo
NetworkClientInfo * GetInfo() const
Gets the client info of this socket handler.
Definition: tcp_game.h:538
ClientNetworkGameSocketHandler::Receive_SERVER_CONFIG_UPDATE
NetworkRecvStatus Receive_SERVER_CONFIG_UPDATE(Packet *p) override
Update the clients knowledge of the max settings: uint8_t Maximum number of companies allowed.
Definition: network_client.cpp:1199
_switch_mode
SwitchMode _switch_mode
The next mainloop command.
Definition: gfx.cpp:48
NetworkSocketHandler::HasClientQuit
bool HasClientQuit() const
Whether the current client connected to the socket has quit.
Definition: core.h:68
_frame_counter_server
uint32_t _frame_counter_server
The frame_counter of the server, if in network-mode.
Definition: network.cpp:71
NetworkTCPSocketHandler::SendPackets
SendPacketsState SendPackets(bool closing_down=false)
Sends all the buffered packets out for this client.
Definition: tcp.cpp:99
_current_company
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:50
NETWORK_RCONCOMMAND_LENGTH
static const uint NETWORK_RCONCOMMAND_LENGTH
The maximum length of a rconsole command, in bytes including '\0'.
Definition: config.h:61
NetworkTCPSocketHandler::CanSendReceive
bool CanSendReceive()
Check whether this socket can send or receive something.
Definition: tcp.cpp:218
Pool::PoolItem<&_networkclientinfo_pool >::Iterate
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:384
FiosNumberedSaveName
A savegame name automatically numbered.
Definition: fios.h:129
DetailedFileType
DetailedFileType
Kinds of files in each AbstractFileType.
Definition: fileio_type.h:28
ClientID
ClientID
'Unique' identifier to be given to clients
Definition: network_type.h:49
Pool::PoolItem<&_company_pool >::GetNumItems
static size_t GetNumItems()
Returns number of valid items in the pool.
Definition: pool_type.hpp:365
ClientNetworkGameSocketHandler::SendCommand
static NetworkRecvStatus SendCommand(const CommandPacket *cp)
Send a command to the server.
Definition: network_client.cpp:440
PacketReader::TransferOutMemCopy
static ssize_t TransferOutMemCopy(PacketReader *destination, const char *source, size_t amount)
Simple wrapper around fwrite to be able to pass it to Packet's TransferOut.
Definition: network_client.cpp:72
Backup::Restore
void Restore()
Restore the variable.
Definition: backup_type.hpp:112
Packet::Recv_bool
bool Recv_bool()
Read a boolean from the packet.
Definition: packet.cpp:308
ClientNetworkGameSocketHandler::Receive_SERVER_ERROR_QUIT
NetworkRecvStatus Receive_SERVER_ERROR_QUIT(Packet *p) override
Inform all clients that one client made an error and thus has quit/been disconnected: uint32_t ID of ...
Definition: network_client.cpp:1060
GetDrawStringCompanyColour
TextColour GetDrawStringCompanyColour(CompanyID company)
Get the colour for DrawString-subroutines which matches the colour of the company.
Definition: company_cmd.cpp:146
NetworkClientSetCompanyPassword
void NetworkClientSetCompanyPassword(const std::string &password)
Set/Reset company password on the client side.
Definition: network_client.cpp:1400
_frame_counter
uint32_t _frame_counter
The current frame.
Definition: network.cpp:73
CRR_NONE
@ CRR_NONE
Dummy reason for actions that don't need one.
Definition: company_type.h:63
DestType
DestType
Destination of our chat messages.
Definition: network_type.h:91
NO_DIRECTORY
@ NO_DIRECTORY
A path without any base directory.
Definition: fileio_type.h:126
ClientNetworkGameSocketHandler::STATUS_AUTHORIZED
@ STATUS_AUTHORIZED
The client is authorized at the server.
Definition: network_client.h:29
SetDParam
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings.cpp:104
COMPANY_SPECTATOR
@ COMPANY_SPECTATOR
The client is spectating.
Definition: company_type.h:35
PACKET_CLIENT_GAME_PASSWORD
@ PACKET_CLIENT_GAME_PASSWORD
Clients sends the (hashed) game password.
Definition: tcp_game.h:65
_network_join_waiting
uint8_t _network_join_waiting
The number of clients waiting in front of us.
Definition: network_gui.cpp:2102
NetworkJoinInfo
Information required to join a server.
Definition: network_client.h:111
NetworkRecvStatus
NetworkRecvStatus
Status of a network client; reasons why a client has quit.
Definition: core.h:22
ClientNetworkGameSocketHandler::SendError
static NetworkRecvStatus SendError(NetworkErrorCode errorno)
Send an error-packet over the network.
Definition: network_client.cpp:469
WC_NETWORK_STATUS_WINDOW
@ WC_NETWORK_STATUS_WINDOW
Network status window; Window numbers:
Definition: window_type.h:485
ClientNetworkGameSocketHandler::Receive_SERVER_SYNC
NetworkRecvStatus Receive_SERVER_SYNC(Packet *p) override
Sends a sync-check to the client: uint32_t Frame counter.
Definition: network_client.cpp:955
ClientNetworkGameSocketHandler::ClientError
void ClientError(NetworkRecvStatus res)
Handle an error coming from the client side.
Definition: network_client.cpp:190
ClientNetworkGameSocketHandler::token
byte token
The token we need to send back to the server to prove we're the right client.
Definition: network_client.h:20
_network_join_bytes_total
uint32_t _network_join_bytes_total
The total number of bytes to download.
Definition: network_gui.cpp:2104
GetString
std::string GetString(StringID string)
Resolve the given StringID into a std::string with all the associated DParam lookups and formatting.
Definition: strings.cpp:327
NetworkSettings::max_companies
uint8_t max_companies
maximum amount of companies
Definition: settings_type.h:326
Pool::PoolItem<&_networkclientinfo_pool >::CanAllocateItem
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
Definition: pool_type.hpp:305
ClientNetworkGameSocketHandler::STATUS_AUTH_GAME
@ STATUS_AUTH_GAME
Last action was requesting game (server) password.
Definition: network_client.h:27
PacketReader::bufe
byte * bufe
End of the buffer we write to/read from.
Definition: network_client.cpp:48
Subdirectory
Subdirectory
The different kinds of subdirectories OpenTTD uses.
Definition: fileio_type.h:108
SetDParamStr
void SetDParamStr(size_t n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition: strings.cpp:352
ClientNetworkGameSocketHandler::NetworkExecuteLocalCommandQueue
friend void NetworkExecuteLocalCommandQueue()
Execute all commands on the local command queue that ought to be executed this frame.
Definition: network_command.cpp:316
PACKET_CLIENT_RCON
@ PACKET_CLIENT_RCON
Client asks the server to execute some command.
Definition: tcp_game.h:105
INVALID_CLIENT_ID
@ INVALID_CLIENT_ID
Client is not part of anything.
Definition: network_type.h:50
ClientNetworkGameSocketHandler::~ClientNetworkGameSocketHandler
~ClientNetworkGameSocketHandler()
Clear whatever we assigned.
Definition: network_client.cpp:153
WL_ERROR
@ WL_ERROR
Errors (eg. saving/loading failed)
Definition: error.h:26
ClientNetworkGameSocketHandler::Receive_SERVER_COMMAND
NetworkRecvStatus Receive_SERVER_COMMAND(Packet *p) override
Sends a DoCommand to the client: uint8_t ID of the company (0..MAX_COMPANIES-1).
Definition: network_client.cpp:970
NetworkMaxCompaniesAllowed
uint NetworkMaxCompaniesAllowed()
Get the maximum number of companies that are allowed by the server.
Definition: network_client.cpp:1426
SM_MENU
@ SM_MENU
Switch to game intro menu.
Definition: openttd.h:33
ClientNetworkGameSocketHandler
Class for handling the client side of the game connection.
Definition: network_client.h:16
ClientNetworkGameSocketHandler::Receive_SERVER_SHUTDOWN
NetworkRecvStatus Receive_SERVER_SHUTDOWN(Packet *p) override
Let the clients know that the server is closing.
Definition: network_client.cpp:1119
NetworkGameSocketHandler::incoming_queue
CommandQueue incoming_queue
The command-queue awaiting handling.
Definition: tcp_game.h:512
network.h
NetworkGameSocketHandler::client_id
ClientID client_id
Client identifier.
Definition: tcp_game.h:509
CommandHelper
Definition: command_func.h:93
Packet::Send_string
void Send_string(const std::string_view data)
Sends a string over the network.
Definition: packet.cpp:181
MILLISECONDS_PER_TICK
static const uint MILLISECONDS_PER_TICK
The number of milliseconds per game tick.
Definition: gfx_type.h:320
ClientNetworkGameSocketHandler::SendGetMap
static NetworkRecvStatus SendGetMap()
Request the map from the server.
Definition: network_client.cpp:398
LoadFilter
Interface for filtering a savegame till it is loaded.
Definition: saveload_filter.h:14
lengthof
#define lengthof(x)
Return the length of an fixed size array.
Definition: stdafx.h:300
ClientNetworkGameSocketHandler::Receive_SERVER_RCON
NetworkRecvStatus Receive_SERVER_RCON(Packet *p) override
Send the result of an issues RCon command back to the client: uint16_t Colour code.
Definition: network_client.cpp:1153
ClientSettings::network
NetworkSettings network
settings related to the network
Definition: settings_type.h:637
GRFIdentifier::grfid
uint32_t grfid
GRF ID (defined by Action 0x08)
Definition: newgrf_config.h:84
Randomizer::state
uint32_t state[2]
The state of the randomizer.
Definition: random_func.hpp:23
ClientNetworkGameSocketHandler::SendMapOk
static NetworkRecvStatus SendMapOk()
Tell the server we received the complete map.
Definition: network_client.cpp:411
_sync_frame
uint32_t _sync_frame
The frame to perform the sync check.
Definition: network.cpp:80
NetworkGameSocketHandler::CloseConnection
NetworkRecvStatus CloseConnection(bool error=true) override
Functions to help ReceivePacket/SendPacket a bit A socket can make errors.
Definition: tcp_game.cpp:43
PACKET_CLIENT_ACK
@ PACKET_CLIENT_ACK
The client tells the server which frame it has executed.
Definition: tcp_game.h:92
PACKET_CLIENT_MOVE
@ PACKET_CLIENT_MOVE
A client would like to be moved to another company.
Definition: tcp_game.h:109
INVALID_COMPANY
@ INVALID_COMPANY
An invalid company.
Definition: company_type.h:30
GenerateCompanyPasswordHash
std::string GenerateCompanyPasswordHash(const std::string &password, const std::string &password_server_id, uint32_t password_game_seed)
Hash the given password using server ID and game seed.
Definition: network.cpp:177
ClientNetworkGameSocketHandler::savegame
struct PacketReader * savegame
Packet reader for reading the savegame.
Definition: network_client.h:19
ClientNetworkGameSocketHandler::SendAck
static NetworkRecvStatus SendAck()
Send an acknowledgement from the server's ticks.
Definition: network_client.cpp:424
NETWORK_RECV_STATUS_OKAY
@ NETWORK_RECV_STATUS_OKAY
Everything is okay.
Definition: core.h:23
NetworkClientSendChat
void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, int64_t data)
Send a chat message.
Definition: network_client.cpp:1391
network_gamelist.h
SafeLoad
bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf=nullptr)
Load the specified savegame but on error do different things.
Definition: openttd.cpp:969
ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE
NetworkRecvStatus Receive_SERVER_MAP_DONE(Packet *p) override
Sends that all data of the map are sent to the client:
Definition: network_client.cpp:856
PacketReader::PacketReader
PacketReader()
Initialise everything.
Definition: network_client.cpp:54
ClientNetworkGameSocketHandler::SendQuit
static NetworkRecvStatus SendQuit()
Tell the server we would like to quit.
Definition: network_client.cpp:513
Ticks::DAY_TICKS
static constexpr TimerGameTick::Ticks DAY_TICKS
1 day is 74 ticks; TimerGameCalendar::date_fract used to be uint16_t and incremented by 885.
Definition: timer_game_tick.h:48
Pool::PoolItem<&_company_pool >::IsValidID
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition: pool_type.hpp:324
ClientNetworkGameSocketHandler::STATUS_ACTIVE
@ STATUS_ACTIVE
The client is active within in the game.
Definition: network_client.h:32
ClientNetworkGameSocketHandler::status
ServerStatus status
Status of the connection with the server.
Definition: network_client.h:36
StateGameLoop
void StateGameLoop()
State controlling game loop.
Definition: openttd.cpp:1427
FGCM_EXACT
@ FGCM_EXACT
Only find Grfs matching md5sum.
Definition: newgrf_config.h:192
Packet::Recv_uint16
uint16_t Recv_uint16()
Read a 16 bits integer from the packet.
Definition: packet.cpp:331
NETWORK_RECV_STATUS_SAVEGAME
@ NETWORK_RECV_STATUS_SAVEGAME
Something went wrong (down)loading the savegame.
Definition: core.h:26
ClientNetworkGameSocketHandler::SendGamePassword
static NetworkRecvStatus SendGamePassword(const std::string &password)
Set the game password as requested.
Definition: network_client.cpp:373
_network_server_max_companies
static uint8_t _network_server_max_companies
Maximum number of companies of the currently joined server.
Definition: network_client.cpp:323
ClientNetworkGameSocketHandler::Receive_SERVER_MAP_SIZE
NetworkRecvStatus Receive_SERVER_MAP_SIZE(Packet *p) override
Sends the size of the map to the client.
Definition: network_client.cpp:829
WN_NETWORK_STATUS_WINDOW_JOIN
@ WN_NETWORK_STATUS_WINDOW_JOIN
Network join status.
Definition: window_type.h:39
CC_WARNING
static const TextColour CC_WARNING
Colour for warning lines.
Definition: console_type.h:25
NetworkMakeClientNameUnique
bool NetworkMakeClientNameUnique(std::string &new_name)
Check whether a name is unique, and otherwise try to make it unique.
Definition: network_server.cpp:1657
ClientNetworkGameSocketHandler::Receive_SERVER_QUIT
NetworkRecvStatus Receive_SERVER_QUIT(Packet *p) override
Notification that a client left the game: uint32_t ID of the client.
Definition: network_client.cpp:1079
Packet::RemainingBytesToTransfer
size_t RemainingBytesToTransfer() const
Get the amount of bytes that are still available for the Transfer functions.
Definition: packet.cpp:430
_network_join
NetworkJoinInfo _network_join
Information about the game to join to.
Definition: network_client.cpp:328
SetWindowClassesDirty
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition: window.cpp:3108
FindGRFConfig
const GRFConfig * FindGRFConfig(uint32_t grfid, FindGRFConfigMode mode, const MD5Hash *md5sum, uint32_t desired_version)
Find a NewGRF in the scanned list.
Definition: newgrf_config.cpp:690
_network_join_bytes
uint32_t _network_join_bytes
The number of bytes we already downloaded.
Definition: network_gui.cpp:2103
ClientNetworkGameSocketHandler::Receive_SERVER_MOVE
NetworkRecvStatus Receive_SERVER_MOVE(Packet *p) override
Move a client from one company into another: uint32_t ID of the client.
Definition: network_client.cpp:1169
CLIENT_ID_SERVER
@ CLIENT_ID_SERVER
Servers always have this ID.
Definition: network_type.h:51
ClientNetworkGameSocketHandler::SendSetPassword
static NetworkRecvStatus SendSetPassword(const std::string &password)
Tell the server that we like to change the password of the company.
Definition: network_client.cpp:484
ClientNetworkGameSocketHandler::Send
static void Send()
Send the packets of this socket handler.
Definition: network_client.cpp:259
NetworkErrorCode
NetworkErrorCode
The error codes we send around in the protocols.
Definition: network_type.h:122
NetworkClientInfo
Container for all information known about a client.
Definition: network_base.h:24
NetworkIsValidClientName
bool NetworkIsValidClientName(const std::string_view client_name)
Check whether the given client name is deemed valid for use in network games.
Definition: network_client.cpp:1315
_frame_counter_max
uint32_t _frame_counter_max
To where we may go with our clients.
Definition: network.cpp:72
PACKET_CLIENT_SET_PASSWORD
@ PACKET_CLIENT_SET_PASSWORD
A client (re)sets its company's password.
Definition: tcp_game.h:113
_network_reconnect
uint8_t _network_reconnect
Reconnect timeout.
Definition: network.cpp:67
Packet::Recv_uint8
uint8_t Recv_uint8()
Read a 8 bits integer from the packet.
Definition: packet.cpp:317
PACKET_CLIENT_COMPANY_PASSWORD
@ PACKET_CLIENT_COMPANY_PASSWORD
Client sends the (hashed) company password.
Definition: tcp_game.h:67
INVALID_STRING_ID
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Definition: strings_type.h:17
Map::SizeY
static uint SizeY()
Get the size of the map along the Y.
Definition: map_func.h:279
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition: settings_type.h:636
WL_CRITICAL
@ WL_CRITICAL
Critical errors, the MessageBox is shown in all cases.
Definition: error.h:27
NETWORK_GAME_PASSWORD
@ NETWORK_GAME_PASSWORD
The password of the game.
Definition: network_type.h:83
ClientNetworkGameSocketHandler::Receive_SERVER_WAIT
NetworkRecvStatus Receive_SERVER_WAIT(Packet *p) override
Notification that another client is currently receiving the map: uint8_t Number of clients waiting in...
Definition: network_client.cpp:789
NETWORK_RECV_STATUS_MALFORMED_PACKET
@ NETWORK_RECV_STATUS_MALFORMED_PACKET
We apparently send a malformed packet.
Definition: core.h:28
CommandPacket::cmd
Commands cmd
command being executed.
Definition: network_internal.h:117
TimerGameEconomy::date
static Date date
Current date in days (day counter).
Definition: timer_game_economy.h:37
IConsolePrint
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.
Definition: console.cpp:91