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

OpenTTD Source 1.11.0-RC1

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 "../core/random_func.hpp"
22 #include "../date_func.h"
23 #include "../gfx_func.h"
24 #include "../error.h"
25 #include "../rev.h"
26 #include "network.h"
27 #include "network_base.h"
28 #include "network_client.h"
29 #include "../core/backup_type.hpp"
30 #include "../thread.h"
31
32 #include "table/strings.h"
33
34 #include "../safeguards.h"
35
36 /* This file handles all the client-commands */
37
38
40 struct PacketReader : LoadFilter {
41 static const size_t CHUNK = 32 * 1024;
42
43 std::vector<byte *> blocks;
44 byte *buf;
45 byte *bufe;
46 byte **block;
47 size_t written_bytes;
48 size_t read_bytes;
49
51 PacketReader() : LoadFilter(nullptr), buf(nullptr), bufe(nullptr), block(nullptr), written_bytes(0), read_bytes(0)
52 {
53 }
54
55 ~PacketReader() override
56 {
57 for (auto p : this->blocks) {
58 free(p);
59 }
60 }
61
66 void AddPacket(const Packet *p)
67 {
68 assert(this->read_bytes == 0);
69
70 size_t in_packet = p->size - p->pos;
71 size_t to_write = std::min<size_t>(this->bufe - this->buf, in_packet);
72 const byte *pbuf = p->buffer + p->pos;
73
74 this->written_bytes += in_packet;
75 if (to_write != 0) {
76 memcpy(this->buf, pbuf, to_write);
77 this->buf += to_write;
78 }
79
80 /* Did everything fit in the current chunk, then we're done. */
81 if (to_write == in_packet) return;
82
83 /* Allocate a new chunk and add the remaining data. */
84 pbuf += to_write;
85 to_write = in_packet - to_write;
86 this->blocks.push_back(this->buf = CallocT<byte>(CHUNK));
87 this->bufe = this->buf + CHUNK;
88
89 memcpy(this->buf, pbuf, to_write);
90 this->buf += to_write;
91 }
92
93 size_t Read(byte *rbuf, size_t size) override
94 {
95 /* Limit the amount to read to whatever we still have. */
96 size_t ret_size = size = std::min(this->written_bytes - this->read_bytes, size);
97 this->read_bytes += ret_size;
98 const byte *rbufe = rbuf + ret_size;
99
100 while (rbuf != rbufe) {
101 if (this->buf == this->bufe) {
102 this->buf = *this->block++;
103 this->bufe = this->buf + CHUNK;
104 }
105
106 size_t to_write = std::min(this->bufe - this->buf, rbufe - rbuf);
107 memcpy(rbuf, this->buf, to_write);
108 rbuf += to_write;
109 this->buf += to_write;
110 }
111
112 return ret_size;
113 }
114
115 void Reset() override
116 {
117 this->read_bytes = 0;
118
119 this->block = this->blocks.data();
120 this->buf = *this->block++;
121 this->bufe = this->buf + CHUNK;
122 }
123 };
124
125
129 void ClientNetworkEmergencySave()
130 {
131 if (!_settings_client.gui.autosave_on_network_disconnect) return;
132 if (!_networking) return;
133
134 const char *filename = "netsave.sav";
135 DEBUG(net, 0, "Client: Performing emergency save (%s)", filename);
136 SaveOrLoad(filename, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR, false);
137 }
138
139
144 ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler(SOCKET s) : NetworkGameSocketHandler(s), savegame(nullptr), status(STATUS_INACTIVE)
145 {
146 assert(ClientNetworkGameSocketHandler::my_client == nullptr);
147 ClientNetworkGameSocketHandler::my_client = this;
148 }
149
151 ClientNetworkGameSocketHandler::~ClientNetworkGameSocketHandler()
152 {
153 assert(ClientNetworkGameSocketHandler::my_client == this);
154 ClientNetworkGameSocketHandler::my_client = nullptr;
155
156 delete this->savegame;
157 }
158
159 NetworkRecvStatus ClientNetworkGameSocketHandler::CloseConnection(NetworkRecvStatus status)
160 {
161 assert(status != NETWORK_RECV_STATUS_OKAY);
162 /*
163 * Sending a message just before leaving the game calls cs->SendPackets.
164 * This might invoke this function, which means that when we close the
165 * connection after cs->SendPackets we will close an already closed
166 * connection. This handles that case gracefully without having to make
167 * that code any more complex or more aware of the validity of the socket.
168 */
169 if (this->sock == INVALID_SOCKET) return status;
170
171 DEBUG(net, 1, "Closed client connection %d", this->client_id);
172
173 this->SendPackets(true);
174
175 /* Wait a number of ticks so our leave message can reach the server.
176 * This is especially needed for Windows servers as they seem to get
177 * the "socket is closed" message before receiving our leave message,
178 * which would trigger the server to close the connection as well. */
179 CSleep(3 * MILLISECONDS_PER_TICK);
180
181 delete this->GetInfo();
182 delete this;
183
184 return status;
185 }
186
191 void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
192 {
193 /* First, send a CLIENT_ERROR to the server, so he knows we are
194 * disconnection (and why!) */
195 NetworkErrorCode errorno;
196
197 /* We just want to close the connection.. */
198 if (res == NETWORK_RECV_STATUS_CLOSE_QUERY) {
199 this->NetworkSocketHandler::CloseConnection();
200 this->CloseConnection(res);
201 _networking = false;
202
203 DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
204 return;
205 }
206
207 switch (res) {
208 case NETWORK_RECV_STATUS_DESYNC: errorno = NETWORK_ERROR_DESYNC; break;
209 case NETWORK_RECV_STATUS_SAVEGAME: errorno = NETWORK_ERROR_SAVEGAME_FAILED; break;
210 case NETWORK_RECV_STATUS_NEWGRF_MISMATCH: errorno = NETWORK_ERROR_NEWGRF_MISMATCH; break;
211 default: errorno = NETWORK_ERROR_GENERAL; break;
212 }
213
214 if (res == NETWORK_RECV_STATUS_SERVER_ERROR || res == NETWORK_RECV_STATUS_SERVER_FULL ||
215 res == NETWORK_RECV_STATUS_SERVER_BANNED) {
216 /* This means the server closed the connection. Emergency save is
217 * already created if this was appropriate during handling of the
218 * disconnect. */
219 this->CloseConnection(res);
220 } else {
221 /* This means we as client made a boo-boo. */
222 SendError(errorno);
223
224 /* Close connection before we make an emergency save, as the save can
225 * take a bit of time; better that the server doesn't stall while we
226 * are doing the save, and already disconnects us. */
227 this->CloseConnection(res);
228 ClientNetworkEmergencySave();
229 }
230
231 _switch_mode = SM_MENU;
232 _networking = false;
233 }
234
235
241 /* static */ bool ClientNetworkGameSocketHandler::Receive()
242 {
243 if (my_client->CanSendReceive()) {
244 NetworkRecvStatus res = my_client->ReceivePackets();
245 if (res != NETWORK_RECV_STATUS_OKAY) {
246 /* The client made an error of which we can not recover.
247 * Close the connection and drop back to the main menu. */
248 my_client->ClientError(res);
249 return false;
250 }
251 }
252 return _networking;
253 }
254
256 /* static */ void ClientNetworkGameSocketHandler::Send()
257 {
258 my_client->SendPackets();
259 my_client->CheckConnection();
260 }
261
266 /* static */ bool ClientNetworkGameSocketHandler::GameLoop()
267 {
268 _frame_counter++;
269
270 NetworkExecuteLocalCommandQueue();
271
272 extern void StateGameLoop();
273 StateGameLoop();
274
275 /* Check if we are in sync! */
276 if (_sync_frame != 0) {
277 if (_sync_frame == _frame_counter) {
278 #ifdef NETWORK_SEND_DOUBLE_SEED
279 if (_sync_seed_1 != _random.state[0] || _sync_seed_2 != _random.state[1]) {
280 #else
281 if (_sync_seed_1 != _random.state[0]) {
282 #endif
283 NetworkError(STR_NETWORK_ERROR_DESYNC);
284 DEBUG(desync, 1, "sync_err: %08x; %02x", _date, _date_fract);
285 DEBUG(net, 0, "Sync error detected!");
286 my_client->ClientError(NETWORK_RECV_STATUS_DESYNC);
287 return false;
288 }
289
290 /* If this is the first time we have a sync-frame, we
291 * need to let the server know that we are ready and at the same
292 * frame as he is.. so we can start playing! */
293 if (_network_first_time) {
294 _network_first_time = false;
295 SendAck();
296 }
297
298 _sync_frame = 0;
299 } else if (_sync_frame < _frame_counter) {
300 DEBUG(net, 1, "Missed frame for sync-test (%d / %d)", _sync_frame, _frame_counter);
301 _sync_frame = 0;
302 }
303 }
304
305 return true;
306 }
307
308
310 ClientNetworkGameSocketHandler * ClientNetworkGameSocketHandler::my_client = nullptr;
311
313 static uint32 last_ack_frame;
314
316 static uint32 _password_game_seed;
318 static char _password_server_id[NETWORK_SERVER_ID_LENGTH];
319
321 static uint8 _network_server_max_companies;
323 static uint8 _network_server_max_spectators;
324
326 CompanyID _network_join_as;
327
329 const char *_network_join_server_password = nullptr;
331 const char *_network_join_company_password = nullptr;
332
334 static_assert(NETWORK_SERVER_ID_LENGTH == 16 * 2 + 1);
335
336 /***********
337 * Sending functions
338 * DEF_CLIENT_SEND_COMMAND has no parameters
339 ************/
340
342 NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyInformationQuery()
343 {
344 my_client->status = STATUS_COMPANY_INFO;
345 _network_join_status = NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO;
346 SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
347
348 Packet *p = new Packet(PACKET_CLIENT_COMPANY_INFO);
349 my_client->SendPacket(p);
350 return NETWORK_RECV_STATUS_OKAY;
351 }
352
354 NetworkRecvStatus ClientNetworkGameSocketHandler::SendJoin()
355 {
356 my_client->status = STATUS_JOIN;
357 _network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING;
358 SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
359
360 Packet *p = new Packet(PACKET_CLIENT_JOIN);
361 p->Send_string(GetNetworkRevisionString());
362 p->Send_uint32(_openttd_newgrf_version);
363 p->Send_string(_settings_client.network.client_name); // Client name
364 p->Send_uint8 (_network_join_as); // PlayAs
365 p->Send_uint8 (NETLANG_ANY); // Language
366 my_client->SendPacket(p);
367 return NETWORK_RECV_STATUS_OKAY;
368 }
369
371 NetworkRecvStatus ClientNetworkGameSocketHandler::SendNewGRFsOk()
372 {
373 Packet *p = new Packet(PACKET_CLIENT_NEWGRFS_CHECKED);
374 my_client->SendPacket(p);
375 return NETWORK_RECV_STATUS_OKAY;
376 }
377
382 NetworkRecvStatus ClientNetworkGameSocketHandler::SendGamePassword(const char *password)
383 {
384 Packet *p = new Packet(PACKET_CLIENT_GAME_PASSWORD);
385 p->Send_string(password);
386 my_client->SendPacket(p);
387 return NETWORK_RECV_STATUS_OKAY;
388 }
389
394 NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyPassword(const char *password)
395 {
396 Packet *p = new Packet(PACKET_CLIENT_COMPANY_PASSWORD);
397 p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _password_game_seed));
398 my_client->SendPacket(p);
399 return NETWORK_RECV_STATUS_OKAY;
400 }
401
403 NetworkRecvStatus ClientNetworkGameSocketHandler::SendGetMap()
404 {
405 my_client->status = STATUS_MAP_WAIT;
406
407 Packet *p = new Packet(PACKET_CLIENT_GETMAP);
408 my_client->SendPacket(p);
409 return NETWORK_RECV_STATUS_OKAY;
410 }
411
413 NetworkRecvStatus ClientNetworkGameSocketHandler::SendMapOk()
414 {
415 my_client->status = STATUS_ACTIVE;
416
417 Packet *p = new Packet(PACKET_CLIENT_MAP_OK);
418 my_client->SendPacket(p);
419 return NETWORK_RECV_STATUS_OKAY;
420 }
421
423 NetworkRecvStatus ClientNetworkGameSocketHandler::SendAck()
424 {
425 Packet *p = new Packet(PACKET_CLIENT_ACK);
426
427 p->Send_uint32(_frame_counter);
428 p->Send_uint8 (my_client->token);
429 my_client->SendPacket(p);
430 return NETWORK_RECV_STATUS_OKAY;
431 }
432
437 NetworkRecvStatus ClientNetworkGameSocketHandler::SendCommand(const CommandPacket *cp)
438 {
439 Packet *p = new Packet(PACKET_CLIENT_COMMAND);
440 my_client->NetworkGameSocketHandler::SendCommand(p, cp);
441
442 my_client->SendPacket(p);
443 return NETWORK_RECV_STATUS_OKAY;
444 }
445
447 NetworkRecvStatus ClientNetworkGameSocketHandler::SendChat(NetworkAction action, DestType type, int dest, const char *msg, int64 data)
448 {
449 Packet *p = new Packet(PACKET_CLIENT_CHAT);
450
451 p->Send_uint8 (action);
452 p->Send_uint8 (type);
453 p->Send_uint32(dest);
454 p->Send_string(msg);
455 p->Send_uint64(data);
456
457 my_client->SendPacket(p);
458 return NETWORK_RECV_STATUS_OKAY;
459 }
460
462 NetworkRecvStatus ClientNetworkGameSocketHandler::SendError(NetworkErrorCode errorno)
463 {
464 Packet *p = new Packet(PACKET_CLIENT_ERROR);
465
466 p->Send_uint8(errorno);
467 my_client->SendPacket(p);
468 return NETWORK_RECV_STATUS_OKAY;
469 }
470
475 NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetPassword(const char *password)
476 {
477 Packet *p = new Packet(PACKET_CLIENT_SET_PASSWORD);
478
479 p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _password_game_seed));
480 my_client->SendPacket(p);
481 return NETWORK_RECV_STATUS_OKAY;
482 }
483
488 NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetName(const char *name)
489 {
490 Packet *p = new Packet(PACKET_CLIENT_SET_NAME);
491
492 p->Send_string(name);
493 my_client->SendPacket(p);
494 return NETWORK_RECV_STATUS_OKAY;
495 }
496
500 NetworkRecvStatus ClientNetworkGameSocketHandler::SendQuit()
501 {
502 Packet *p = new Packet(PACKET_CLIENT_QUIT);
503
504 my_client->SendPacket(p);
505 return NETWORK_RECV_STATUS_OKAY;
506 }
507
513 NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const char *pass, const char *command)
514 {
515 Packet *p = new Packet(PACKET_CLIENT_RCON);
516 p->Send_string(pass);
517 p->Send_string(command);
518 my_client->SendPacket(p);
519 return NETWORK_RECV_STATUS_OKAY;
520 }
521
527 NetworkRecvStatus ClientNetworkGameSocketHandler::SendMove(CompanyID company, const char *password)
528 {
529 Packet *p = new Packet(PACKET_CLIENT_MOVE);
530 p->Send_uint8(company);
531 p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _password_game_seed));
532 my_client->SendPacket(p);
533 return NETWORK_RECV_STATUS_OKAY;
534 }
535
540 bool ClientNetworkGameSocketHandler::IsConnected()
541 {
542 return my_client != nullptr && my_client->status == STATUS_ACTIVE;
543 }
544
545
546 /***********
547 * Receiving functions
548 * DEF_CLIENT_RECEIVE_COMMAND has parameter: Packet *p
549 ************/
550
551 extern bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = nullptr);
552
553 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_FULL(Packet *p)
554 {
555 /* We try to join a server which is full */
556 ShowErrorMessage(STR_NETWORK_ERROR_SERVER_FULL, INVALID_STRING_ID, WL_CRITICAL);
557 DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
558
559 return NETWORK_RECV_STATUS_SERVER_FULL;
560 }
561
562 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_BANNED(Packet *p)
563 {
564 /* We try to join a server where we are banned */
565 ShowErrorMessage(STR_NETWORK_ERROR_SERVER_BANNED, INVALID_STRING_ID, WL_CRITICAL);
566 DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
567
568 return NETWORK_RECV_STATUS_SERVER_BANNED;
569 }
570
571 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_COMPANY_INFO(Packet *p)
572 {
573 if (this->status != STATUS_COMPANY_INFO) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
574
575 byte company_info_version = p->Recv_uint8();
576
577 if (!this->HasClientQuit() && company_info_version == NETWORK_COMPANY_INFO_VERSION) {
578 /* We have received all data... (there are no more packets coming) */
579 if (!p->Recv_bool()) return NETWORK_RECV_STATUS_CLOSE_QUERY;
580
581 CompanyID current = (Owner)p->Recv_uint8();
582 if (current >= MAX_COMPANIES) return NETWORK_RECV_STATUS_CLOSE_QUERY;
583
584 NetworkCompanyInfo *company_info = GetLobbyCompanyInfo(current);
585 if (company_info == nullptr) return NETWORK_RECV_STATUS_CLOSE_QUERY;
586
587 p->Recv_string(company_info->company_name, sizeof(company_info->company_name));
588 company_info->inaugurated_year = p->Recv_uint32();
589 company_info->company_value = p->Recv_uint64();
590 company_info->money = p->Recv_uint64();
591 company_info->income = p->Recv_uint64();
592 company_info->performance = p->Recv_uint16();
593 company_info->use_password = p->Recv_bool();
594 for (uint i = 0; i < NETWORK_VEH_END; i++) {
595 company_info->num_vehicle[i] = p->Recv_uint16();
596 }
597 for (uint i = 0; i < NETWORK_VEH_END; i++) {
598 company_info->num_station[i] = p->Recv_uint16();
599 }
600 company_info->ai = p->Recv_bool();
601
602 p->Recv_string(company_info->clients, sizeof(company_info->clients));
603
604 SetWindowDirty(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_LOBBY);
605
606 return NETWORK_RECV_STATUS_OKAY;
607 }
608
609 return NETWORK_RECV_STATUS_CLOSE_QUERY;
610 }
611
612 /* This packet contains info about the client (playas and name)
613 * as client we save this in NetworkClientInfo, linked via 'client_id'
614 * which is always an unique number on a server. */
615 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Packet *p)
616 {
617 NetworkClientInfo *ci;
618 ClientID client_id = (ClientID)p->Recv_uint32();
619 CompanyID playas = (CompanyID)p->Recv_uint8();
620 char name[NETWORK_NAME_LENGTH];
621
622 p->Recv_string(name, sizeof(name));
623
624 if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
625 if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
626
627 ci = NetworkClientInfo::GetByClientID(client_id);
628 if (ci != nullptr) {
629 if (playas == ci->client_playas && strcmp(name, ci->client_name) != 0) {
630 /* Client name changed, display the change */
631 NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, name);
632 } else if (playas != ci->client_playas) {
633 /* The client changed from client-player..
634 * Do not display that for now */
635 }
636
637 /* Make sure we're in the company the server tells us to be in,
638 * for the rare case that we get moved while joining. */
639 if (client_id == _network_own_client_id) SetLocalCompany(!Company::IsValidID(playas) ? COMPANY_SPECTATOR : playas);
640
641 ci->client_playas = playas;
642 strecpy(ci->client_name, name, lastof(ci->client_name));
643
644 SetWindowDirty(WC_CLIENT_LIST, 0);
645
646 return NETWORK_RECV_STATUS_OKAY;
647 }
648
649 /* There are at most as many ClientInfo as ClientSocket objects in a
650 * server. Having more info than a server can have means something
651 * has gone wrong somewhere, i.e. the server has more info than it
652 * has actual clients. That means the server is feeding us an invalid
653 * state. So, bail out! This server is broken. */
654 if (!NetworkClientInfo::CanAllocateItem()) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
655
656 /* We don't have this client_id yet, find an empty client_id, and put the data there */
657 ci = new NetworkClientInfo(client_id);
658 ci->client_playas = playas;
659 if (client_id == _network_own_client_id) this->SetInfo(ci);
660
661 strecpy(ci->client_name, name, lastof(ci->client_name));
662
663 SetWindowDirty(WC_CLIENT_LIST, 0);
664
665 return NETWORK_RECV_STATUS_OKAY;
666 }
667
668 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet *p)
669 {
670 static const StringID network_error_strings[] = {
671 STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_GENERAL
672 STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_DESYNC
673 STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_SAVEGAME_FAILED
674 STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_CONNECTION_LOST
675 STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_ILLEGAL_PACKET
676 STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_NEWGRF_MISMATCH
677 STR_NETWORK_ERROR_SERVER_ERROR, // NETWORK_ERROR_NOT_AUTHORIZED
678 STR_NETWORK_ERROR_SERVER_ERROR, // NETWORK_ERROR_NOT_EXPECTED
679 STR_NETWORK_ERROR_WRONG_REVISION, // NETWORK_ERROR_WRONG_REVISION
680 STR_NETWORK_ERROR_LOSTCONNECTION, // NETWORK_ERROR_NAME_IN_USE
681 STR_NETWORK_ERROR_WRONG_PASSWORD, // NETWORK_ERROR_WRONG_PASSWORD
682 STR_NETWORK_ERROR_SERVER_ERROR, // NETWORK_ERROR_COMPANY_MISMATCH
683 STR_NETWORK_ERROR_KICKED, // NETWORK_ERROR_KICKED
684 STR_NETWORK_ERROR_CHEATER, // NETWORK_ERROR_CHEATER
685 STR_NETWORK_ERROR_SERVER_FULL, // NETWORK_ERROR_FULL
686 STR_NETWORK_ERROR_TOO_MANY_COMMANDS, // NETWORK_ERROR_TOO_MANY_COMMANDS
687 STR_NETWORK_ERROR_TIMEOUT_PASSWORD, // NETWORK_ERROR_TIMEOUT_PASSWORD
688 STR_NETWORK_ERROR_TIMEOUT_COMPUTER, // NETWORK_ERROR_TIMEOUT_COMPUTER
689 STR_NETWORK_ERROR_TIMEOUT_MAP, // NETWORK_ERROR_TIMEOUT_MAP
690 STR_NETWORK_ERROR_TIMEOUT_JOIN, // NETWORK_ERROR_TIMEOUT_JOIN
691 };
692 static_assert(lengthof(network_error_strings) == NETWORK_ERROR_END);
693
694 NetworkErrorCode error = (NetworkErrorCode)p->Recv_uint8();
695
696 StringID err = STR_NETWORK_ERROR_LOSTCONNECTION;
697 if (error < (ptrdiff_t)lengthof(network_error_strings)) err = network_error_strings[error];
698 /* In case of kicking a client, we assume there is a kick message in the packet if we can read one byte */
699 if (error == NETWORK_ERROR_KICKED && p->CanReadFromPacket(1)) {
700 char kick_msg[255];
701 p->Recv_string(kick_msg, sizeof(kick_msg));
702 SetDParamStr(0, kick_msg);
703 ShowErrorMessage(err, STR_NETWORK_ERROR_KICK_MESSAGE, WL_CRITICAL);
704 } else {
705 ShowErrorMessage(err, INVALID_STRING_ID, WL_CRITICAL);
706 }
707
708 /* Perform an emergency save if we had already entered the game */
709 if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave();
710
711 DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
712
713 return NETWORK_RECV_STATUS_SERVER_ERROR;
714 }
715
716 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHECK_NEWGRFS(Packet *p)
717 {
718 if (this->status != STATUS_JOIN) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
719
720 uint grf_count = p->Recv_uint8();
721 NetworkRecvStatus ret = NETWORK_RECV_STATUS_OKAY;
722
723 /* Check all GRFs */
724 for (; grf_count > 0; grf_count--) {
725 GRFIdentifier c;
726 this->ReceiveGRFIdentifier(p, &c);
727
728 /* Check whether we know this GRF */
729 const GRFConfig *f = FindGRFConfig(c.grfid, FGCM_EXACT, c.md5sum);
730 if (f == nullptr) {
731 /* We do not know this GRF, bail out of initialization */
732 char buf[sizeof(c.md5sum) * 2 + 1];
733 md5sumToString(buf, lastof(buf), c.md5sum);
734 DEBUG(grf, 0, "NewGRF %08X not found; checksum %s", BSWAP32(c.grfid), buf);
735 ret = NETWORK_RECV_STATUS_NEWGRF_MISMATCH;
736 }
737 }
738
739 if (ret == NETWORK_RECV_STATUS_OKAY) {
740 /* Start receiving the map */
741 return SendNewGRFsOk();
742 }
743
744 /* NewGRF mismatch, bail out */
745 ShowErrorMessage(STR_NETWORK_ERROR_NEWGRF_MISMATCH, INVALID_STRING_ID, WL_CRITICAL);
746 return ret;
747 }
748
749 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_NEED_GAME_PASSWORD(Packet *p)
750 {
751 if (this->status < STATUS_JOIN || this->status >= STATUS_AUTH_GAME) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
752 this->status = STATUS_AUTH_GAME;
753
754 const char *password = _network_join_server_password;
755 if (!StrEmpty(password)) {
756 return SendGamePassword(password);
757 }
758
759 ShowNetworkNeedPassword(NETWORK_GAME_PASSWORD);
760
761 return NETWORK_RECV_STATUS_OKAY;
762 }
763
764 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_NEED_COMPANY_PASSWORD(Packet *p)
765 {
766 if (this->status < STATUS_JOIN || this->status >= STATUS_AUTH_COMPANY) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
767 this->status = STATUS_AUTH_COMPANY;
768
769 _password_game_seed = p->Recv_uint32();
770 p->Recv_string(_password_server_id, sizeof(_password_server_id));
771 if (this->HasClientQuit()) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
772
773 const char *password = _network_join_company_password;
774 if (!StrEmpty(password)) {
775 return SendCompanyPassword(password);
776 }
777
778 ShowNetworkNeedPassword(NETWORK_COMPANY_PASSWORD);
779
780 return NETWORK_RECV_STATUS_OKAY;
781 }
782
783 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_WELCOME(Packet *p)
784 {
785 if (this->status < STATUS_JOIN || this->status >= STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
786 this->status = STATUS_AUTHORIZED;
787
788 _network_own_client_id = (ClientID)p->Recv_uint32();
789
790 /* Initialize the password hash salting variables, even if they were previously. */
791 _password_game_seed = p->Recv_uint32();
792 p->Recv_string(_password_server_id, sizeof(_password_server_id));
793
794 /* Start receiving the map */
795 return SendGetMap();
796 }
797
798 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_WAIT(Packet *p)
799 {
800 /* We set the internal wait state when requesting the map. */
801 if (this->status != STATUS_MAP_WAIT) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
802
803 /* But... only now we set the join status to waiting, instead of requesting. */
804 _network_join_status = NETWORK_JOIN_STATUS_WAITING;
805 _network_join_waiting = p->Recv_uint8();
806 SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
807
808 return NETWORK_RECV_STATUS_OKAY;
809 }
810
811 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_BEGIN(Packet *p)
812 {
813 if (this->status < STATUS_AUTHORIZED || this->status >= STATUS_MAP) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
814 this->status = STATUS_MAP;
815
816 if (this->savegame != nullptr) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
817
818 this->savegame = new PacketReader();
819
820 _frame_counter = _frame_counter_server = _frame_counter_max = p->Recv_uint32();
821
822 _network_join_bytes = 0;
823 _network_join_bytes_total = 0;
824
825 _network_join_status = NETWORK_JOIN_STATUS_DOWNLOADING;
826 SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
827
828 return NETWORK_RECV_STATUS_OKAY;
829 }
830
831 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_SIZE(Packet *p)
832 {
833 if (this->status != STATUS_MAP) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
834 if (this->savegame == nullptr) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
835
836 _network_join_bytes_total = p->Recv_uint32();
837 SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
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)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 *p)
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 _network_join_status = NETWORK_JOIN_STATUS_PROCESSING;
862 SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
863
864 /*
865 * Make sure everything is set for reading.
866 *
867 * We need the local copy and reset this->savegame because when
868 * loading fails the network gets reset upon loading the intro
869 * game, which would cause us to free this->savegame twice.
870 */
871 LoadFilter *lf = this->savegame;
872 this->savegame = nullptr;
873 lf->Reset();
874
875 /* The map is done downloading, load it */
876 ClearErrorMessages();
877 bool load_success = SafeLoad({}, SLO_LOAD, DFT_GAME_FILE, GM_NORMAL, NO_DIRECTORY, lf);
878
879 /* Long savegame loads shouldn't affect the lag calculation! */
880 this->last_packet = std::chrono::steady_clock::now();
881
882 if (!load_success) {
883 DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
884 ShowErrorMessage(STR_NETWORK_ERROR_SAVEGAMEERROR, INVALID_STRING_ID, WL_CRITICAL);
885 return NETWORK_RECV_STATUS_SAVEGAME;
886 }
887 /* If the savegame has successfully loaded, ALL windows have been removed,
888 * only toolbar/statusbar and gamefield are visible */
889
890 /* Say we received the map and loaded it correctly! */
891 SendMapOk();
892
893 /* New company/spectator (invalid company) or company we want to join is not active
894 * Switch local company to spectator and await the server's judgement */
895 if (_network_join_as == COMPANY_NEW_COMPANY || !Company::IsValidID(_network_join_as)) {
896 SetLocalCompany(COMPANY_SPECTATOR);
897
898 if (_network_join_as != COMPANY_SPECTATOR) {
899 /* We have arrived and ready to start playing; send a command to make a new company;
900 * the server will give us a client-id and let us in */
901 _network_join_status = NETWORK_JOIN_STATUS_REGISTERING;
902 ShowJoinStatusWindow();
903 NetworkSendCommand(0, CCA_NEW, 0, CMD_COMPANY_CTRL, nullptr, nullptr, _local_company);
904 }
905 } else {
906 /* take control over an existing company */
907 SetLocalCompany(_network_join_as);
908 }
909
910 return NETWORK_RECV_STATUS_OKAY;
911 }
912
913 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_FRAME(Packet *p)
914 {
915 if (this->status != STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
916
917 _frame_counter_server = p->Recv_uint32();
918 _frame_counter_max = p->Recv_uint32();
919 #ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
920 /* Test if the server supports this option
921 * and if we are at the frame the server is */
922 if (p->pos + 1 < p->size) {
923 _sync_frame = _frame_counter_server;
924 _sync_seed_1 = p->Recv_uint32();
925 #ifdef NETWORK_SEND_DOUBLE_SEED
926 _sync_seed_2 = p->Recv_uint32();
927 #endif
928 }
929 #endif
930 /* Receive the token. */
931 if (p->pos != p->size) this->token = p->Recv_uint8();
932
933 DEBUG(net, 5, "Received FRAME %d", _frame_counter_server);
934
935 /* Let the server know that we received this frame correctly
936 * We do this only once per day, to save some bandwidth ;) */
937 if (!_network_first_time && last_ack_frame < _frame_counter) {
938 last_ack_frame = _frame_counter + DAY_TICKS;
939 DEBUG(net, 4, "Sent ACK at %d", _frame_counter);
940 SendAck();
941 }
942
943 return NETWORK_RECV_STATUS_OKAY;
944 }
945
946 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_SYNC(Packet *p)
947 {
948 if (this->status != STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
949
950 _sync_frame = p->Recv_uint32();
951 _sync_seed_1 = p->Recv_uint32();
952 #ifdef NETWORK_SEND_DOUBLE_SEED
953 _sync_seed_2 = p->Recv_uint32();
954 #endif
955
956 return NETWORK_RECV_STATUS_OKAY;
957 }
958
959 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_COMMAND(Packet *p)
960 {
961 if (this->status != STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
962
963 CommandPacket cp;
964 const char *err = this->ReceiveCommand(p, &cp);
965 cp.frame = p->Recv_uint32();
966 cp.my_cmd = p->Recv_bool();
967
968 if (err != nullptr) {
969 IConsolePrintF(CC_ERROR, "WARNING: %s from server, dropping...", err);
970 return NETWORK_RECV_STATUS_MALFORMED_PACKET;
971 }
972
973 this->incoming_queue.Append(&cp);
974
975 return NETWORK_RECV_STATUS_OKAY;
976 }
977
978 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p)
979 {
980 if (this->status != STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
981
982 char name[NETWORK_NAME_LENGTH], msg[NETWORK_CHAT_LENGTH];
983 const NetworkClientInfo *ci = nullptr, *ci_to;
984
985 NetworkAction action = (NetworkAction)p->Recv_uint8();
986 ClientID client_id = (ClientID)p->Recv_uint32();
987 bool self_send = p->Recv_bool();
988 p->Recv_string(msg, NETWORK_CHAT_LENGTH);
989 int64 data = p->Recv_uint64();
990
991 ci_to = NetworkClientInfo::GetByClientID(client_id);
992 if (ci_to == nullptr) return NETWORK_RECV_STATUS_OKAY;
993
994 /* Did we initiate the action locally? */
995 if (self_send) {
996 switch (action) {
997 case NETWORK_ACTION_CHAT_CLIENT:
998 /* For speaking to client we need the client-name */
999 seprintf(name, lastof(name), "%s", ci_to->client_name);
1000 ci = NetworkClientInfo::GetByClientID(_network_own_client_id);
1001 break;
1002
1003 /* For speaking to company, we need the company-name */
1004 case NETWORK_ACTION_CHAT_COMPANY: {
1005 StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;
1006 SetDParam(0, ci_to->client_playas);
1007
1008 GetString(name, str, lastof(name));
1009 ci = NetworkClientInfo::GetByClientID(_network_own_client_id);
1010 break;
1011 }
1012
1013 default: return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1014 }
1015 } else {
1016 /* Display message from somebody else */
1017 seprintf(name, lastof(name), "%s", ci_to->client_name);
1018 ci = ci_to;
1019 }
1020
1021 if (ci != nullptr) {
1022 NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), self_send, name, msg, data);
1023 }
1024 return NETWORK_RECV_STATUS_OKAY;
1025 }
1026
1027 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR_QUIT(Packet *p)
1028 {
1029 if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1030
1031 ClientID client_id = (ClientID)p->Recv_uint32();
1032
1033 NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
1034 if (ci != nullptr) {
1035 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, nullptr, GetNetworkErrorMsg((NetworkErrorCode)p->Recv_uint8()));
1036 delete ci;
1037 }
1038
1039 SetWindowDirty(WC_CLIENT_LIST, 0);
1040
1041 return NETWORK_RECV_STATUS_OKAY;
1042 }
1043
1044 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_QUIT(Packet *p)
1045 {
1046 if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1047
1048 ClientID client_id = (ClientID)p->Recv_uint32();
1049
1050 NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
1051 if (ci != nullptr) {
1052 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, nullptr, STR_NETWORK_MESSAGE_CLIENT_LEAVING);
1053 delete ci;
1054 } else {
1055 DEBUG(net, 0, "Unknown client (%d) is leaving the game", client_id);
1056 }
1057
1058 SetWindowDirty(WC_CLIENT_LIST, 0);
1059
1060 /* If we come here it means we could not locate the client.. strange :s */
1061 return NETWORK_RECV_STATUS_OKAY;
1062 }
1063
1064 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_JOIN(Packet *p)
1065 {
1066 if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1067
1068 ClientID client_id = (ClientID)p->Recv_uint32();
1069
1070 NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
1071 if (ci != nullptr) {
1072 NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, ci->client_name);
1073 }
1074
1075 SetWindowDirty(WC_CLIENT_LIST, 0);
1076
1077 return NETWORK_RECV_STATUS_OKAY;
1078 }
1079
1080 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_SHUTDOWN(Packet *p)
1081 {
1082 /* Only when we're trying to join we really
1083 * care about the server shutting down. */
1084 if (this->status >= STATUS_JOIN) {
1085 ShowErrorMessage(STR_NETWORK_MESSAGE_SERVER_SHUTDOWN, INVALID_STRING_ID, WL_CRITICAL);
1086 }
1087
1088 if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave();
1089
1090 return NETWORK_RECV_STATUS_SERVER_ERROR;
1091 }
1092
1093 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_NEWGAME(Packet *p)
1094 {
1095 /* Only when we're trying to join we really
1096 * care about the server shutting down. */
1097 if (this->status >= STATUS_JOIN) {
1098 /* To throttle the reconnects a bit, every clients waits its
1099 * Client ID modulo 16. This way reconnects should be spread
1100 * out a bit. */
1101 _network_reconnect = _network_own_client_id % 16;
1102 ShowErrorMessage(STR_NETWORK_MESSAGE_SERVER_REBOOT, INVALID_STRING_ID, WL_CRITICAL);
1103 }
1104
1105 if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave();
1106
1107 return NETWORK_RECV_STATUS_SERVER_ERROR;
1108 }
1109
1110 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_RCON(Packet *p)
1111 {
1112 if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1113
1114 TextColour colour_code = (TextColour)p->Recv_uint16();
1115 if (!IsValidConsoleColour(colour_code)) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1116
1117 char rcon_out[NETWORK_RCONCOMMAND_LENGTH];
1118 p->Recv_string(rcon_out, sizeof(rcon_out));
1119
1120 IConsolePrint(colour_code, rcon_out);
1121
1122 return NETWORK_RECV_STATUS_OKAY;
1123 }
1124
1125 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MOVE(Packet *p)
1126 {
1127 if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1128
1129 /* Nothing more in this packet... */
1130 ClientID client_id = (ClientID)p->Recv_uint32();
1131 CompanyID company_id = (CompanyID)p->Recv_uint8();
1132
1133 if (client_id == 0) {
1134 /* definitely an invalid client id, debug message and do nothing. */
1135 DEBUG(net, 0, "[move] received invalid client index = 0");
1136 return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1137 }
1138
1139 const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
1140 /* Just make sure we do not try to use a client_index that does not exist */
1141 if (ci == nullptr) return NETWORK_RECV_STATUS_OKAY;
1142
1143 /* if not valid player, force spectator, else check player exists */
1144 if (!Company::IsValidID(company_id)) company_id = COMPANY_SPECTATOR;
1145
1146 if (client_id == _network_own_client_id) {
1147 SetLocalCompany(company_id);
1148 }
1149
1150 return NETWORK_RECV_STATUS_OKAY;
1151 }
1152
1153 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CONFIG_UPDATE(Packet *p)
1154 {
1155 if (this->status < STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1156
1157 _network_server_max_companies = p->Recv_uint8();
1158 _network_server_max_spectators = p->Recv_uint8();
1159
1160 return NETWORK_RECV_STATUS_OKAY;
1161 }
1162
1163 NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_COMPANY_UPDATE(Packet *p)
1164 {
1165 if (this->status < STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
1166
1167 _network_company_passworded = p->Recv_uint16();
1168 SetWindowClassesDirty(WC_COMPANY);
1169
1170 return NETWORK_RECV_STATUS_OKAY;
1171 }
1172
1176 void ClientNetworkGameSocketHandler::CheckConnection()
1177 {
1178 /* Only once we're authorized we can expect a steady stream of packets. */
1179 if (this->status < STATUS_AUTHORIZED) return;
1180
1181 /* 5 seconds are roughly twice the server's "you're slow" threshold (1 game day). */
1182 std::chrono::steady_clock::duration lag = std::chrono::steady_clock::now() - this->last_packet;
1183 if (lag < std::chrono::seconds(5)) return;
1184
1185 /* 20 seconds are (way) more than 4 game days after which
1186 * the server will forcefully disconnect you. */
1187 if (lag > std::chrono::seconds(20)) {
1188 this->NetworkGameSocketHandler::CloseConnection();
1189 return;
1190 }
1191
1192 /* Prevent showing the lag message every tick; just update it when needed. */
1193 static std::chrono::steady_clock::duration last_lag = {};
1194 if (std::chrono::duration_cast<std::chrono::seconds>(last_lag) == std::chrono::duration_cast<std::chrono::seconds>(lag)) return;
1195
1196 last_lag = lag;
1197 SetDParam(0, std::chrono::duration_cast<std::chrono::seconds>(lag).count());
1198 ShowErrorMessage(STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION, STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION, WL_INFO);
1199 }
1200
1201
1203 void NetworkClient_Connected()
1204 {
1205 /* Set the frame-counter to 0 so nothing happens till we are ready */
1206 _frame_counter = 0;
1207 _frame_counter_server = 0;
1208 last_ack_frame = 0;
1209 /* Request the game-info */
1210 MyClient::SendJoin();
1211 }
1212
1218 void NetworkClientSendRcon(const char *password, const char *command)
1219 {
1220 MyClient::SendRCon(password, command);
1221 }
1222
1229 void NetworkClientRequestMove(CompanyID company_id, const char *pass)
1230 {
1231 MyClient::SendMove(company_id, pass);
1232 }
1233
1238 void NetworkClientsToSpectators(CompanyID cid)
1239 {
1240 Backup<CompanyID> cur_company(_current_company, FILE_LINE);
1241 /* If our company is changing owner, go to spectators */
1242 if (cid == _local_company) SetLocalCompany(COMPANY_SPECTATOR);
1243
1244 for (NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
1245 if (ci->client_playas != cid) continue;
1246 NetworkTextMessage(NETWORK_ACTION_COMPANY_SPECTATOR, CC_DEFAULT, false, ci->client_name);
1247 ci->client_playas = COMPANY_SPECTATOR;
1248 }
1249
1250 cur_company.Restore();
1251 }
1252
1256 void NetworkUpdateClientName()
1257 {
1258 NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(_network_own_client_id);
1259
1260 if (ci == nullptr) return;
1261
1262 /* Don't change the name if it is the same as the old name */
1263 if (strcmp(ci->client_name, _settings_client.network.client_name) != 0) {
1264 if (!_network_server) {
1265 MyClient::SendSetName(_settings_client.network.client_name);
1266 } else {
1267 if (NetworkFindName(_settings_client.network.client_name, lastof(_settings_client.network.client_name))) {
1268 NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, _settings_client.network.client_name);
1269 strecpy(ci->client_name, _settings_client.network.client_name, lastof(ci->client_name));
1270 NetworkUpdateClientInfo(CLIENT_ID_SERVER);
1271 }
1272 }
1273 }
1274 }
1275
1284 void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, int64 data)
1285 {
1286 MyClient::SendChat(action, type, dest, msg, data);
1287 }
1288
1293 void NetworkClientSetCompanyPassword(const char *password)
1294 {
1295 MyClient::SendSetPassword(password);
1296 }
1297
1303 bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio)
1304 {
1305 /* Only companies actually playing can speak to team. Eg spectators cannot */
1306 if (!_settings_client.gui.prefer_teamchat || !Company::IsValidID(cio->client_playas)) return false;
1307
1308 for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
1309 if (ci->client_playas == cio->client_playas && ci != cio) return true;
1310 }
1311
1312 return false;
1313 }
1314
1319 bool NetworkMaxCompaniesReached()
1320 {
1321 return Company::GetNumItems() >= (_network_server ? _settings_client.network.max_companies : _network_server_max_companies);
1322 }
1323
1328 bool NetworkMaxSpectatorsReached()
1329 {
1330 return NetworkSpectatorCount() >= (_network_server ? _settings_client.network.max_spectators : _network_server_max_spectators);
1331 }
ClientNetworkGameSocketHandler::Receive_SERVER_FRAME
NetworkRecvStatus Receive_SERVER_FRAME(Packet *p) override
Sends the current frame counter to the client: uint32 Frame counter uint32 Frame counter max (how far...
Definition: network_client.cpp:913
NetworkCompanyStats::num_station
uint16 num_station[NETWORK_VEH_END]
How many stations are there of this type?
Definition: network_type.h:59
_network_join_bytes_total
uint32 _network_join_bytes_total
The total number of bytes to download.
Definition: network_gui.cpp:1979
NetworkClientSendRcon
void NetworkClientSendRcon(const char *password, const char *command)
Send a remote console command.
Definition: network_client.cpp:1218
NetworkCompanyInfo::inaugurated_year
Year inaugurated_year
What year the company started in.
Definition: network_gui.h:29
DestType
DestType
Destination of our chat messages.
Definition: network_type.h:81
NetworkSettings::client_name
char client_name[NETWORK_CLIENT_NAME_LENGTH]
name of the player (as client)
Definition: settings_type.h:270
ClientNetworkGameSocketHandler::SendNewGRFsOk
static NetworkRecvStatus SendNewGRFsOk()
Tell the server we got all the NewGRFs.
Definition: network_client.cpp:371
ClientNetworkGameSocketHandler::Receive_SERVER_CHAT
NetworkRecvStatus Receive_SERVER_CHAT(Packet *p) override
Sends a chat-packet to the client: uint8 ID of the action (see NetworkAction).
Definition: network_client.cpp:978
_frame_counter
uint32 _frame_counter
The current frame.
Definition: network.cpp:68
PACKET_CLIENT_ERROR
@ PACKET_CLIENT_ERROR
A client reports an error to the server.
Definition: tcp_game.h:120
NetworkClientSetCompanyPassword
void NetworkClientSetCompanyPassword(const char *password)
Set/Reset company password on the client side.
Definition: network_client.cpp:1293
ClientNetworkGameSocketHandler::SendSetName
static NetworkRecvStatus SendSetName(const char *name)
Tell the server that we like to change the name of the client.
Definition: network_client.cpp:488
ClientNetworkGameSocketHandler::Receive_SERVER_COMPANY_INFO
NetworkRecvStatus Receive_SERVER_COMPANY_INFO(Packet *p) override
Sends information about the companies (one packet per company): uint8 Version of the structure of thi...
Definition: network_client.cpp:571
SetWindowDirty
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3220
Packet::Recv_string
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.
Definition: packet.cpp:286
NetworkSettings::max_spectators
uint8 max_spectators
maximum amount of spectators
Definition: settings_type.h:280
FindGRFConfig
const GRFConfig * FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8 *md5sum, uint32 desired_version)
Find a NewGRF in the scanned list.
Definition: newgrf_config.cpp:737
NetworkGameSocketHandler::ReceivePackets
NetworkRecvStatus ReceivePackets()
Do the actual receiving of packets.
Definition: tcp_game.cpp:133
CSleep
void CSleep(int milliseconds)
Sleep on the current thread for a defined time.
Definition: thread.h:22
NETWORK_RECV_STATUS_DESYNC
@ NETWORK_RECV_STATUS_DESYNC
A desync did occur.
Definition: core.h:24
ClientNetworkGameSocketHandler::STATUS_AUTH_COMPANY
@ STATUS_AUTH_COMPANY
Last action was requesting company password.
Definition: network_client.h:28
_network_server_max_spectators
static uint8 _network_server_max_spectators
Maximum number of spectators of the currently joined server.
Definition: network_client.cpp:323
_password_game_seed
static uint32 _password_game_seed
One bit of 'entropy' used to generate a salt for the company passwords.
Definition: network_client.cpp:316
ClientNetworkGameSocketHandler::SendChat
static NetworkRecvStatus SendChat(NetworkAction action, DestType type, int dest, const char *msg, int64 data)
Send a chat-packet over the network.
Definition: network_client.cpp:447
NetworkMaxSpectatorsReached
bool NetworkMaxSpectatorsReached()
Check if max_spectatos has been reached on the server (local check only).
Definition: network_client.cpp:1328
_network_join_waiting
uint8 _network_join_waiting
The number of clients waiting in front of us.
Definition: network_gui.cpp:1977
Packet::buffer
byte * buffer
The buffer of this packet, of basically variable length up to SEND_MTU.
Definition: packet.h:52
Backup
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:21
NetworkCompanyInfo::company_value
Money company_value
The company value.
Definition: network_gui.h:30
ClientNetworkGameSocketHandler::Receive_SERVER_BANNED
NetworkRecvStatus Receive_SERVER_BANNED(Packet *p) override
Notification that the client trying to join is banned.
Definition: network_client.cpp:562
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:40
NetworkClientInfo::client_playas
CompanyID client_playas
As which company is this client playing (CompanyID)
Definition: network_base.h:27
PacketReader::AddPacket
void AddPacket(const Packet *p)
Add a packet to this buffer.
Definition: network_client.cpp:66
ClientNetworkEmergencySave
void ClientNetworkEmergencySave()
Create an emergency savegame when the network connection is lost.
Definition: network_client.cpp:129
_network_join_as
CompanyID _network_join_as
Who would we like to join as.
Definition: network_client.cpp:326
SaveOrLoad
SaveOrLoadResult SaveOrLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded)
Main Save or Load function where the high-level saveload functions are handled.
Definition: saveload.cpp:2764
_date_fract
DateFract _date_fract
Fractional part of the day.
Definition: date.cpp:29
_network_server
bool _network_server
network-server is active
Definition: network.cpp:53
SaveLoadOperation
SaveLoadOperation
Operation performed on the file.
Definition: fileio_type.h:47
_network_company_passworded
CompanyMask _network_company_passworded
Bitmask of the password status of all companies.
Definition: network.cpp:80
NetworkAction
NetworkAction
Actions that can be used for NetworkTextMessage.
Definition: network_type.h:91
NetworkClientPreferTeamChat
bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio)
Tell whether the client has team members where he/she can chat to.
Definition: network_client.cpp:1303
ClientNetworkGameSocketHandler::SendMove
static NetworkRecvStatus SendMove(CompanyID company, const char *password)
Ask the server to move us.
Definition: network_client.cpp:527
NetworkClientInfo::client_name
char client_name[NETWORK_CLIENT_NAME_LENGTH]
Name of the client.
Definition: network_base.h:25
CommandPacket::frame
uint32 frame
the frame in which this packet is executed
Definition: network_internal.h:154
NetworkGameSocketHandler::last_packet
std::chrono::steady_clock::time_point last_packet
Time we received the last frame.
Definition: tcp_game.h:522
WC_CLIENT_LIST
@ WC_CLIENT_LIST
Client list; Window numbers:
Definition: window_type.h:472
ClientNetworkGameSocketHandler::Receive_SERVER_COMPANY_UPDATE
NetworkRecvStatus Receive_SERVER_COMPANY_UPDATE(Packet *p) override
Update the clients knowledge of which company is password protected: uint16 Bitwise representation of...
Definition: network_client.cpp:1163
ClientNetworkGameSocketHandler::CheckConnection
void CheckConnection()
Check the connection's state, i.e.
Definition: network_client.cpp:1176
NetworkGameSocketHandler::SetInfo
void SetInfo(NetworkClientInfo *info)
Sets the client info for this socket handler.
Definition: tcp_game.h:537
NetworkUpdateClientInfo
void NetworkUpdateClientInfo(ClientID client_id)
Send updated client info of a particular client.
Definition: network_server.cpp:1601
ClientNetworkGameSocketHandler::GameLoop
static bool GameLoop()
Actual game loop for the client.
Definition: network_client.cpp:266
PacketReader::block
byte ** block
The block we're reading from/writing to.
Definition: network_client.cpp:46
NETWORK_CHAT_LENGTH
static const uint NETWORK_CHAT_LENGTH
The maximum length of a chat message, in bytes including '\0'.
Definition: config.h:50
PACKET_CLIENT_COMMAND
@ PACKET_CLIENT_COMMAND
Client executed a command and sends it to the server.
Definition: tcp_game.h:92
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:102
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:34
NetworkFindName
bool NetworkFindName(char *new_name, const char *last)
Check whether a name is unique, and otherwise try to make it unique.
Definition: network_server.cpp:1715
TextColour
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition: gfx_type.h:250
PacketReader::written_bytes
size_t written_bytes
The total number of bytes we've written.
Definition: network_client.cpp:47
NetworkUpdateClientName
void NetworkUpdateClientName()
Send the server our name.
Definition: network_client.cpp:1256
_random
Randomizer _random
Random used in the game state calculations.
Definition: random_func.cpp:25
AUTOSAVE_DIR
@ AUTOSAVE_DIR
Subdirectory of save for autosaves.
Definition: fileio_type.h:111
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:79
PACKET_CLIENT_QUIT
@ PACKET_CLIENT_QUIT
A client tells the server it is going to quit.
Definition: tcp_game.h:118
network_gui.h
_network_join_status
NetworkJoinStatus _network_join_status
The status of joining.
Definition: network_gui.cpp:1976
PACKET_CLIENT_GETMAP
@ PACKET_CLIENT_GETMAP
Client requests the actual map.
Definition: tcp_game.h:70
ClientNetworkGameSocketHandler::Receive_SERVER_ERROR
NetworkRecvStatus Receive_SERVER_ERROR(Packet *p) override
The client made an error: uint8 Error code caused (see NetworkErrorCode).
Definition: network_client.cpp:668
WC_COMPANY
@ WC_COMPANY
Company view; Window numbers:
Definition: window_type.h:362
GetNetworkErrorMsg
StringID GetNetworkErrorMsg(NetworkErrorCode err)
Retrieve the string id of an internal error number.
Definition: network.cpp:299
ClientNetworkGameSocketHandler::my_client
static ClientNetworkGameSocketHandler * my_client
This is us!
Definition: network_client.h:41
NetworkSocketHandler::CloseConnection
virtual NetworkRecvStatus CloseConnection(bool error=true)
Close the current connection; for TCP this will be mostly equivalent to Close(), but for UDP it just ...
Definition: core.h:59
_network_join_company_password
const char * _network_join_company_password
Company password from -P argument.
Definition: network_client.cpp:331
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 Current frame.
Definition: network_client.cpp:811
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:159
NetworkGameSocketHandler
Base socket handler for all TCP sockets.
Definition: tcp_game.h:149
GenerateCompanyPasswordHash
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.
Definition: network.cpp:182
Packet::Send_uint8
void Send_uint8(uint8 data)
Package a 8 bits integer in the packet.
Definition: packet.cpp:96
LoadFilter::Reset
virtual void Reset()
Reset this filter to read from the beginning of the file.
Definition: saveload_filter.h:43
GRFIdentifier::md5sum
uint8 md5sum[16]
MD5 checksum of file to distinguish files with the same GRF ID (eg. newer version of GRF)
Definition: newgrf_config.h:85
PacketReader::Read
size_t Read(byte *rbuf, size_t size) override
Read a given number of bytes from the savegame.
Definition: network_client.cpp:93
ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO
NetworkRecvStatus Receive_SERVER_CLIENT_INFO(Packet *p) override
Send information about a client: uint32 ID of the client (always unique on a server.
Definition: network_client.cpp:615
SetDParam
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings_func.h:199
CC_DEFAULT
static const TextColour CC_DEFAULT
Default colour of the console.
Definition: console_type.h:23
_frame_counter_max
uint32 _frame_counter_max
To where we may go with our clients.
Definition: network.cpp:67
PacketReader
Read some packets, and when do use that data as initial load filter.
Definition: network_client.cpp:40
GRFIdentifier::grfid
uint32 grfid
GRF ID (defined by Action 0x08)
Definition: newgrf_config.h:84
_network_first_time
bool _network_first_time
Whether we have finished joining or not.
Definition: network.cpp:76
PACKET_CLIENT_CHAT
@ PACKET_CLIENT_CHAT
Client said something that should be distributed.
Definition: tcp_game.h:96
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:1093
network_base.h
ShowErrorMessage
void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x=0, int y=0, const GRFFile *textref_stack_grffile=nullptr, uint textref_stack_size=0, const uint32 *textref_stack=nullptr)
Display an error message in a window.
Definition: error_gui.cpp:372
PacketReader::read_bytes
size_t read_bytes
The total number of read bytes.
Definition: network_client.cpp:48
Packet::Send_uint32
void Send_uint32(uint32 data)
Package a 32 bits integer in the packet.
Definition: packet.cpp:117
PACKET_CLIENT_JOIN
@ PACKET_CLIENT_JOIN
The client telling the server it wants to join.
Definition: tcp_game.h:38
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 Generation seed.
Definition: network_client.cpp:764
CommandQueue::Append
void Append(CommandPacket *p)
Append a CommandPacket at the end of the queue.
Definition: network_command.cpp:57
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:749
ClientNetworkGameSocketHandler::SendJoin
static NetworkRecvStatus SendJoin()
Tell the server we would like to join.
Definition: network_client.cpp:354
last_ack_frame
static uint32 last_ack_frame
Last frame we performed an ack.
Definition: network_client.cpp:313
NetworkClientInfo::GetByClientID
static NetworkClientInfo * GetByClientID(ClientID client_id)
Return the CI given it's client-identifier.
Definition: network.cpp:119
_frame_counter_server
uint32 _frame_counter_server
The frame_counter of the server, if in network-mode.
Definition: network.cpp:66
GRFIdentifier
Basic data to distinguish a GRF.
Definition: newgrf_config.h:83
ClientNetworkGameSocketHandler::STATUS_MAP
@ STATUS_MAP
The client is downloading the map.
Definition: network_client.h:31
ClearErrorMessages
void ClearErrorMessages()
Clear all errors from the queue.
Definition: error_gui.cpp:330
NetworkCompanyInfo::clients
char clients[NETWORK_CLIENTS_LENGTH]
The clients that control this company (Name1, name2, ..)
Definition: network_gui.h:35
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
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:553
_network_join_server_password
const char * _network_join_server_password
Login password from -p argument.
Definition: network_client.cpp:329
NetworkCompanyStats::num_vehicle
uint16 num_vehicle[NETWORK_VEH_END]
How many vehicles are there of this type?
Definition: network_type.h:58
PacketReader::CHUNK
static const size_t CHUNK
32 KiB chunks of memory.
Definition: network_client.cpp:41
Packet::Recv_uint32
uint32 Recv_uint32()
Read a 32 bits integer from the packet.
Definition: packet.cpp:246
NETWORK_RECV_STATUS_CONN_LOST
@ NETWORK_RECV_STATUS_CONN_LOST
The connection is 'just' lost.
Definition: core.h:27
CommandPacket
Everything we need to know about a command to be able to execute it.
Definition: network_internal.h:149
_date
Date _date
Current date in days (day counter)
Definition: date.cpp:28
SLO_SAVE
@ SLO_SAVE
File is being saved.
Definition: fileio_type.h:50
ClientNetworkGameSocketHandler::Receive_SERVER_CHECK_NEWGRFS
NetworkRecvStatus Receive_SERVER_CHECK_NEWGRFS(Packet *p) override
Sends information about all used GRFs to the client: uint8 Amount of GRFs (the following data is repe...
Definition: network_client.cpp:716
GRFConfig
Information about GRF, used in the game and (part of it) in savegames.
Definition: newgrf_config.h:152
PacketReader::blocks
std::vector< byte * > blocks
Buffer with blocks of allocated memory.
Definition: network_client.cpp:43
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:1319
NETWORK_RECV_STATUS_SERVER_FULL
@ NETWORK_RECV_STATUS_SERVER_FULL
The server is full.
Definition: core.h:30
ClientNetworkGameSocketHandler::IsConnected
static bool IsConnected()
Check whether the client is actually connected (and in the game).
Definition: network_client.cpp:540
DEBUG
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:35
Packet::Send_string
void Send_string(const char *data)
Sends a string over the network.
Definition: packet.cpp:148
NETWORK_RECV_STATUS_SERVER_ERROR
@ NETWORK_RECV_STATUS_SERVER_ERROR
The server told us we made an error.
Definition: core.h:29
PACKET_CLIENT_COMPANY_INFO
@ PACKET_CLIENT_COMPANY_INFO
Request information about all companies.
Definition: tcp_game.h:42
ClientNetworkGameSocketHandler::Receive_SERVER_WELCOME
NetworkRecvStatus Receive_SERVER_WELCOME(Packet *p) override
The client is joined and ready to receive his map: uint32 Own client ID.
Definition: network_client.cpp:783
ClientID
ClientID
'Unique' identifier to be given to clients
Definition: network_type.h:39
Packet::size
PacketSize size
The size of the whole packet for received packets.
Definition: packet.h:48
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:1064
NETWORK_RECV_STATUS_SERVER_BANNED
@ NETWORK_RECV_STATUS_SERVER_BANNED
The server has banned us.
Definition: core.h:31
NetworkCompanyInfo::company_name
char company_name[NETWORK_COMPANY_NAME_LENGTH]
Company name.
Definition: network_gui.h:28
NetworkClient_Connected
void NetworkClient_Connected()
Is called after a client is connected to the server.
Definition: network_client.cpp:1203
ClientNetworkGameSocketHandler::STATUS_COMPANY_INFO
@ STATUS_COMPANY_INFO
We are trying to get company information.
Definition: network_client.h:24
PACKET_CLIENT_NEWGRFS_CHECKED
@ PACKET_CLIENT_NEWGRFS_CHECKED
Client acknowledges that it has all required NewGRFs.
Definition: tcp_game.h:57
CCA_NEW
@ CCA_NEW
Create a new company.
Definition: company_type.h:65
_sync_seed_1
uint32 _sync_seed_1
Seed to compare during sync checks.
Definition: network.cpp:71
PacketReader::Reset
void Reset() override
Reset this filter to read from the beginning of the file.
Definition: network_client.cpp:115
NetworkClientsToSpectators
void NetworkClientsToSpectators(CompanyID cid)
Move the clients of a company to the spectators.
Definition: network_client.cpp:1238
GUISettings::autosave_on_network_disconnect
bool autosave_on_network_disconnect
save an autosave when you get disconnected from a network game with an error?
Definition: settings_type.h:125
WL_INFO
@ WL_INFO
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
Definition: error.h:22
MAX_COMPANIES
@ MAX_COMPANIES
Maximum number of companies.
Definition: company_type.h:23
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:46
ClientNetworkGameSocketHandler::STATUS_JOIN
@ STATUS_JOIN
We are trying to join a server.
Definition: network_client.h:25
NETWORK_COMPANY_PASSWORD
@ NETWORK_COMPANY_PASSWORD
The password of the company.
Definition: network_type.h:74
IsValidConsoleColour
bool IsValidConsoleColour(TextColour c)
Check whether the given TextColour is valid for console usage.
Definition: console_gui.cpp:523
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:61
CLIENT_ID_SERVER
@ CLIENT_ID_SERVER
Servers always have this ID.
Definition: network_type.h:41
StrEmpty
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:60
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:43
_networking
bool _networking
are we in networking mode?
Definition: network.cpp:52
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:155
Packet::CanReadFromPacket
bool CanReadFromPacket(uint bytes_to_read)
Is it safe to read from the packet, i.e.
Definition: packet.cpp:169
_password_server_id
static char _password_server_id[NETWORK_SERVER_ID_LENGTH]
The other bit of 'entropy' used to generate a salt for the company passwords.
Definition: network_client.cpp:318
_network_reconnect
uint8 _network_reconnect
Reconnect timeout.
Definition: network.cpp:62
PACKET_CLIENT_MAP_OK
@ PACKET_CLIENT_MAP_OK
Client tells the server that it received the whole map.
Definition: tcp_game.h:76
Packet
Internal entity of a packet.
Definition: packet.h:40
NETWORK_COMPANY_INFO_VERSION
static const byte NETWORK_COMPANY_INFO_VERSION
What version of company info is this?
Definition: config.h:37
GameMode
GameMode
Mode which defines the state of the game.
Definition: openttd.h:16
IConsolePrint
void IConsolePrint(TextColour colour_code, const char *string)
Handle the printing of text entered into the console or redirected there by any other means.
Definition: console.cpp:85
NetworkGameSocketHandler::ReceiveCommand
const char * ReceiveCommand(Packet *p, CommandPacket *cp)
Receives a command from the network.
Definition: network_command.cpp:296
Randomizer::state
uint32 state[2]
The state of the randomizer.
Definition: random_func.hpp:23
PacketReader::buf
byte * buf
Buffer we're going to write to/read from.
Definition: network_client.cpp:44
BSWAP32
static uint32 BSWAP32(uint32 x)
Perform a 32 bits endianness bitswap on x.
Definition: bitmath_func.hpp:380
GUISettings::prefer_teamchat
bool prefer_teamchat
choose the chat message target with <ENTER>, true=all clients, false=your team
Definition: settings_type.h:110
_network_server_max_companies
static uint8 _network_server_max_companies
Maximum number of companies of the currently joined server.
Definition: network_client.cpp:321
StateGameLoop
void StateGameLoop()
State controlling game loop.
Definition: openttd.cpp:1344
_network_own_client_id
ClientID _network_own_client_id
Our client identifier.
Definition: network.cpp:59
ClientNetworkGameSocketHandler::SendCompanyInformationQuery
static NetworkRecvStatus SendCompanyInformationQuery()
Make sure the server ID length is the same as a md5 hash.
Definition: network_client.cpp:342
ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler
ClientNetworkGameSocketHandler(SOCKET s)
Create a new socket for the client side of the game connection.
Definition: network_client.cpp:144
PACKET_CLIENT_SET_NAME
@ PACKET_CLIENT_SET_NAME
A client changes its name.
Definition: tcp_game.h:109
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:241
NetworkGameSocketHandler::GetInfo
NetworkClientInfo * GetInfo() const
Gets the client info of this socket handler.
Definition: tcp_game.h:547
ClientNetworkGameSocketHandler::Receive_SERVER_CONFIG_UPDATE
NetworkRecvStatus Receive_SERVER_CONFIG_UPDATE(Packet *p) override
Update the clients knowledge of the max settings: uint8 Maximum number of companies allowed.
Definition: network_client.cpp:1153
_switch_mode
SwitchMode _switch_mode
The next mainloop command.
Definition: gfx.cpp:46
StringID
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
NetworkSocketHandler::HasClientQuit
bool HasClientQuit() const
Whether the current client connected to the socket has quit.
Definition: core.h:67
NetworkTCPSocketHandler::SendPackets
SendPacketsState SendPackets(bool closing_down=false)
Sends all the buffered packets out for this client.
Definition: tcp.cpp:95
_current_company
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
NETWORK_RCONCOMMAND_LENGTH
static const uint NETWORK_RCONCOMMAND_LENGTH
The maximum length of a rconsole command, in bytes including '\0'.
Definition: config.h:48
NetworkTCPSocketHandler::CanSendReceive
bool CanSendReceive()
Check whether this socket can send or receive something.
Definition: tcp.cpp:225
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:378
DeleteWindowById
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
Definition: window.cpp:1165
ClientNetworkGameSocketHandler::SendSetPassword
static NetworkRecvStatus SendSetPassword(const char *password)
Tell the server that we like to change the password of the company.
Definition: network_client.cpp:475
DetailedFileType
DetailedFileType
Kinds of files in each AbstractFileType.
Definition: fileio_type.h:28
ClientNetworkGameSocketHandler::SendRCon
static NetworkRecvStatus SendRCon(const char *password, const char *command)
Send a console command.
Definition: network_client.cpp:513
Pool::PoolItem<&_company_pool >::GetNumItems
static size_t GetNumItems()
Returns number of valid items in the pool.
Definition: pool_type.hpp:359
ClientNetworkGameSocketHandler::SendCommand
static NetworkRecvStatus SendCommand(const CommandPacket *cp)
Send a command to the server.
Definition: network_client.cpp:437
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:208
Packet::Send_uint64
void Send_uint64(uint64 data)
Package a 64 bits integer in the packet.
Definition: packet.cpp:130
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 ID of th...
Definition: network_client.cpp:1027
NetworkSendCommand
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.
Definition: network_command.cpp:136
GetDrawStringCompanyColour
TextColour GetDrawStringCompanyColour(CompanyID company)
Get the colour for DrawString-subroutines which matches the colour of the company.
Definition: company_cmd.cpp:131
NO_DIRECTORY
@ NO_DIRECTORY
A path without any base directory.
Definition: fileio_type.h:125
ClientNetworkGameSocketHandler::STATUS_AUTHORIZED
@ STATUS_AUTHORIZED
The client is authorized at the server.
Definition: network_client.h:29
COMPANY_SPECTATOR
@ COMPANY_SPECTATOR
The client is spectating.
Definition: company_type.h:35
WC_NETWORK_WINDOW
@ WC_NETWORK_WINDOW
Network window; Window numbers:
Definition: window_type.h:466
PACKET_CLIENT_GAME_PASSWORD
@ PACKET_CLIENT_GAME_PASSWORD
Clients sends the (hashed) game password.
Definition: tcp_game.h:61
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:462
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 Frame counter.
Definition: network_client.cpp:946
ClientNetworkGameSocketHandler::ClientError
void ClientError(NetworkRecvStatus res)
Handle an error coming from the client side.
Definition: network_client.cpp:191
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:19
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:299
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:45
ClientNetworkGameSocketHandler::SendCompanyPassword
static NetworkRecvStatus SendCompanyPassword(const char *password)
Set the company password as requested.
Definition: network_client.cpp:394
NetworkCompanyInfo::money
Money money
The amount of money the company has.
Definition: network_gui.h:31
seprintf
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
Definition: string.cpp:442
Subdirectory
Subdirectory
The different kinds of subdirectories OpenTTD uses.
Definition: fileio_type.h:108
NetworkCompanyInfo::performance
uint16 performance
What was his performance last month?
Definition: network_gui.h:33
NetworkCompanyStats::ai
bool ai
Is this company an AI.
Definition: network_type.h:60
ClientNetworkGameSocketHandler::NetworkExecuteLocalCommandQueue
friend void NetworkExecuteLocalCommandQueue()
Execute all commands on the local command queue that ought to be executed this frame.
Definition: network_command.cpp:191
PACKET_CLIENT_RCON
@ PACKET_CLIENT_RCON
Client asks the server to execute some command.
Definition: tcp_game.h:100
Packet::Recv_uint8
uint8 Recv_uint8()
Read a 8 bits integer from the packet.
Definition: packet.cpp:217
ClientNetworkGameSocketHandler::~ClientNetworkGameSocketHandler
~ClientNetworkGameSocketHandler()
Clear whatever we assigned.
Definition: network_client.cpp:151
CC_ERROR
static const TextColour CC_ERROR
Colour for error lines.
Definition: console_type.h:24
ClientNetworkGameSocketHandler::Receive_SERVER_COMMAND
NetworkRecvStatus Receive_SERVER_COMMAND(Packet *p) override
Sends a DoCommand to the client: uint8 ID of the company (0..MAX_COMPANIES-1).
Definition: network_client.cpp:959
SM_MENU
@ SM_MENU
Switch to game intro menu.
Definition: openttd.h:31
ClientNetworkGameSocketHandler
Class for handling the client side of the game connection.
Definition: network_client.h:16
CMD_COMPANY_CTRL
@ CMD_COMPANY_CTRL
used in multiplayer to create a new companies etc.
Definition: command_type.h:281
ClientNetworkGameSocketHandler::Receive_SERVER_SHUTDOWN
NetworkRecvStatus Receive_SERVER_SHUTDOWN(Packet *p) override
Let the clients know that the server is closing.
Definition: network_client.cpp:1080
NetworkGameSocketHandler::incoming_queue
CommandQueue incoming_queue
The command-queue awaiting handling.
Definition: tcp_game.h:521
_sync_frame
uint32 _sync_frame
The frame to perform the sync check.
Definition: network.cpp:75
error
void CDECL error(const char *s,...)
Error handling for fatal non-user errors.
Definition: openttd.cpp:131
network.h
NetworkSocketHandler::ReceiveGRFIdentifier
void ReceiveGRFIdentifier(Packet *p, GRFIdentifier *grf)
Deserializes the GRFIdentifier (GRF ID and MD5 checksum) from the packet.
Definition: core.cpp:71
NetworkGameSocketHandler::client_id
ClientID client_id
Client identifier.
Definition: tcp_game.h:518
MILLISECONDS_PER_TICK
static const uint MILLISECONDS_PER_TICK
The number of milliseconds per game tick.
Definition: gfx_type.h:310
ClientNetworkGameSocketHandler::SendGetMap
static NetworkRecvStatus SendGetMap()
Request the map from the server.
Definition: network_client.cpp:403
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:367
ClientNetworkGameSocketHandler::Receive_SERVER_RCON
NetworkRecvStatus Receive_SERVER_RCON(Packet *p) override
Send the result of an issues RCon command back to the client: uint16 Colour code.
Definition: network_client.cpp:1110
ClientSettings::network
NetworkSettings network
settings related to the network
Definition: settings_type.h:578
WN_NETWORK_WINDOW_LOBBY
@ WN_NETWORK_WINDOW_LOBBY
Network lobby window.
Definition: window_type.h:28
Packet::Recv_uint64
uint64 Recv_uint64()
Read a 64 bits integer from the packet.
Definition: packet.cpp:263
NetworkClientRequestMove
void NetworkClientRequestMove(CompanyID company_id, const char *pass)
Notify the server of this client wanting to be moved to another company.
Definition: network_client.cpp:1229
ClientNetworkGameSocketHandler::SendMapOk
static NetworkRecvStatus SendMapOk()
Tell the server we received the complete map.
Definition: network_client.cpp:413
NetworkGameSocketHandler::CloseConnection
NetworkRecvStatus CloseConnection(bool error=true) override
Functions to help ReceivePacket/SendPacket a bit A socket can make errors.
Definition: tcp_game.cpp:41
NetworkCompanyInfo::income
Money income
How much did the company earned last year.
Definition: network_gui.h:32
PACKET_CLIENT_ACK
@ PACKET_CLIENT_ACK
The client tells the server which frame it has executed.
Definition: tcp_game.h:88
PACKET_CLIENT_MOVE
@ PACKET_CLIENT_MOVE
A client would like to be moved to another company.
Definition: tcp_game.h:104
ClientNetworkGameSocketHandler::savegame
struct PacketReader * savegame
Packet reader for reading the savegame.
Definition: network_client.h:18
ClientNetworkGameSocketHandler::SendAck
static NetworkRecvStatus SendAck()
Send an acknowledgement from the server's ticks.
Definition: network_client.cpp:423
NETWORK_RECV_STATUS_OKAY
@ NETWORK_RECV_STATUS_OKAY
Everything is okay.
Definition: core.h:23
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:953
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:51
md5sumToString
char * md5sumToString(char *buf, const char *last, const uint8 md5sum[16])
Convert the md5sum to a hexadecimal string representation.
Definition: string.cpp:460
ClientNetworkGameSocketHandler::SendQuit
static NetworkRecvStatus SendQuit()
Tell the server we would like to quit.
Definition: network_client.cpp:500
NetworkClientSendChat
void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, int64 data)
Send a chat message.
Definition: network_client.cpp:1284
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:318
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
FGCM_EXACT
@ FGCM_EXACT
Only find Grfs matching md5sum.
Definition: newgrf_config.h:193
NETWORK_RECV_STATUS_SAVEGAME
@ NETWORK_RECV_STATUS_SAVEGAME
Something went wrong (down)loading the savegame.
Definition: core.h:26
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:831
strecpy
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
Definition: string.cpp:112
WN_NETWORK_STATUS_WINDOW_JOIN
@ WN_NETWORK_STATUS_WINDOW_JOIN
Network join status.
Definition: window_type.h:32
free
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: stdafx.h:454
ClientNetworkGameSocketHandler::Receive_SERVER_QUIT
NetworkRecvStatus Receive_SERVER_QUIT(Packet *p) override
Notification that a client left the game: uint32 ID of the client.
Definition: network_client.cpp:1044
GetNetworkRevisionString
const char * GetNetworkRevisionString()
Get the network version string used by this build.
Definition: network.cpp:1098
NetworkCompanyInfo
Company information stored at the client side.
Definition: network_gui.h:27
SetWindowClassesDirty
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition: window.cpp:3248
lastof
#define lastof(x)
Get the last element of an fixed size array.
Definition: stdafx.h:383
ClientNetworkGameSocketHandler::Receive_SERVER_MOVE
NetworkRecvStatus Receive_SERVER_MOVE(Packet *p) override
Move a client from one company into another: uint32 ID of the client.
Definition: network_client.cpp:1125
ClientNetworkGameSocketHandler::Send
static void Send()
Send the packets of this socket handler.
Definition: network_client.cpp:256
_network_join_bytes
uint32 _network_join_bytes
The number of bytes we already downloaded.
Definition: network_gui.cpp:1978
DAY_TICKS
static const int DAY_TICKS
1 day is 74 ticks; _date_fract used to be uint16 and incremented by 885.
Definition: date_type.h:28
NetworkErrorCode
NetworkErrorCode
The error codes we send around in the protocols.
Definition: network_type.h:110
NetworkClientInfo
Container for all information known about a client.
Definition: network_base.h:23
PACKET_CLIENT_SET_PASSWORD
@ PACKET_CLIENT_SET_PASSWORD
A client (re)sets its company's password.
Definition: tcp_game.h:108
IConsolePrintF
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.
Definition: console.cpp:125
SetDParamStr
void SetDParamStr(uint n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition: strings.cpp:286
PACKET_CLIENT_COMPANY_PASSWORD
@ PACKET_CLIENT_COMPANY_PASSWORD
Client sends the (hashed) company password.
Definition: tcp_game.h:63
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
GetLobbyCompanyInfo
NetworkCompanyInfo * GetLobbyCompanyInfo(CompanyID company)
Get the company information of a given company to fill for the lobby.
Definition: network_gui.cpp:1630
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition: settings_type.h:577
WL_CRITICAL
@ WL_CRITICAL
Critical errors, the MessageBox is shown in all cases.
Definition: error.h:25
NETWORK_GAME_PASSWORD
@ NETWORK_GAME_PASSWORD
The password of the game.
Definition: network_type.h:73
Packet::Recv_uint16
uint16 Recv_uint16()
Read a 16 bits integer from the packet.
Definition: packet.cpp:231
ClientNetworkGameSocketHandler::SendGamePassword
static NetworkRecvStatus SendGamePassword(const char *password)
Set the game password as requested.
Definition: network_client.cpp:382
NetworkSettings::max_companies
uint8 max_companies
maximum amount of companies
Definition: settings_type.h:278
Packet::pos
PacketSize pos
The current read/write position in the packet.
Definition: packet.h:50
ClientNetworkGameSocketHandler::Receive_SERVER_WAIT
NetworkRecvStatus Receive_SERVER_WAIT(Packet *p) override
Notification that another client is currently receiving the map: uint8 Number of clients waiting in f...
Definition: network_client.cpp:798
NETWORK_RECV_STATUS_MALFORMED_PACKET
@ NETWORK_RECV_STATUS_MALFORMED_PACKET
We apparently send a malformed packet.
Definition: core.h:28
NetworkCompanyInfo::use_password
bool use_password
Is there a password.
Definition: network_gui.h:34