00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifdef ENABLE_NETWORK
00013
00014 #include "../stdafx.h"
00015 #include "../debug.h"
00016 #include "../strings_func.h"
00017 #include "../date_func.h"
00018 #include "network_server.h"
00019 #include "network_udp.h"
00020 #include "network.h"
00021 #include "network_base.h"
00022 #include "../console_func.h"
00023 #include "../company_base.h"
00024 #include "../command_func.h"
00025 #include "../saveload/saveload.h"
00026 #include "../station_base.h"
00027 #include "../genworld.h"
00028 #include "../fileio_func.h"
00029 #include "../company_func.h"
00030 #include "../company_gui.h"
00031 #include "../window_func.h"
00032 #include "../roadveh.h"
00033 #include "../rev.h"
00034
00035 #include "table/strings.h"
00036
00037
00038
00039 static void NetworkHandleCommandQueue(NetworkClientSocket *cs);
00040
00041
00042
00043
00044
00045
00046 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CLIENT_INFO)(NetworkClientSocket *cs, NetworkClientInfo *ci)
00047 {
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 if (ci->client_id != INVALID_CLIENT_ID) {
00058 Packet *p = new Packet(PACKET_SERVER_CLIENT_INFO);
00059 p->Send_uint32(ci->client_id);
00060 p->Send_uint8 (ci->client_playas);
00061 p->Send_string(ci->client_name);
00062
00063 cs->Send_Packet(p);
00064 }
00065 }
00066
00067 DEF_SERVER_SEND_COMMAND(PACKET_SERVER_COMPANY_INFO)
00068 {
00069
00070
00071
00072
00073
00074
00075
00076 NetworkCompanyStats company_stats[MAX_COMPANIES];
00077 NetworkPopulateCompanyStats(company_stats);
00078
00079
00080 char clients[MAX_COMPANIES][NETWORK_CLIENTS_LENGTH];
00081 NetworkClientSocket *csi;
00082 memset(clients, 0, sizeof(clients));
00083
00084
00085 const NetworkClientInfo *ci = NetworkFindClientInfoFromClientID(CLIENT_ID_SERVER);
00086 if (ci != NULL && Company::IsValidID(ci->client_playas)) {
00087 strecpy(clients[ci->client_playas], ci->client_name, lastof(clients[ci->client_playas]));
00088 }
00089
00090 FOR_ALL_CLIENT_SOCKETS(csi) {
00091 char client_name[NETWORK_CLIENT_NAME_LENGTH];
00092
00093 NetworkGetClientName(client_name, sizeof(client_name), csi);
00094
00095 ci = csi->GetInfo();
00096 if (ci != NULL && Company::IsValidID(ci->client_playas)) {
00097 if (!StrEmpty(clients[ci->client_playas])) {
00098 strecat(clients[ci->client_playas], ", ", lastof(clients[ci->client_playas]));
00099 }
00100
00101 strecat(clients[ci->client_playas], client_name, lastof(clients[ci->client_playas]));
00102 }
00103 }
00104
00105
00106
00107 Company *company;
00108 Packet *p;
00109
00110 FOR_ALL_COMPANIES(company) {
00111 p = new Packet(PACKET_SERVER_COMPANY_INFO);
00112
00113 p->Send_uint8 (NETWORK_COMPANY_INFO_VERSION);
00114 p->Send_bool (true);
00115 cs->Send_CompanyInformation(p, company, &company_stats[company->index]);
00116
00117 if (StrEmpty(clients[company->index])) {
00118 p->Send_string("<none>");
00119 } else {
00120 p->Send_string(clients[company->index]);
00121 }
00122
00123 cs->Send_Packet(p);
00124 }
00125
00126 p = new Packet(PACKET_SERVER_COMPANY_INFO);
00127
00128 p->Send_uint8 (NETWORK_COMPANY_INFO_VERSION);
00129 p->Send_bool (false);
00130
00131 cs->Send_Packet(p);
00132 }
00133
00134 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientSocket *cs, NetworkErrorCode error)
00135 {
00136
00137
00138
00139
00140
00141
00142
00143 char str[100];
00144 Packet *p = new Packet(PACKET_SERVER_ERROR);
00145
00146 p->Send_uint8(error);
00147 cs->Send_Packet(p);
00148
00149 StringID strid = GetNetworkErrorMsg(error);
00150 GetString(str, strid, lastof(str));
00151
00152
00153 if (cs->status > STATUS_AUTH) {
00154 NetworkClientSocket *new_cs;
00155 char client_name[NETWORK_CLIENT_NAME_LENGTH];
00156
00157 NetworkGetClientName(client_name, sizeof(client_name), cs);
00158
00159 DEBUG(net, 1, "'%s' made an error and has been disconnected. Reason: '%s'", client_name, str);
00160
00161 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, strid);
00162
00163 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00164 if (new_cs->status > STATUS_AUTH && new_cs != cs) {
00165
00166
00167 if (error == NETWORK_ERROR_NOT_AUTHORIZED || error == NETWORK_ERROR_NOT_EXPECTED || error == NETWORK_ERROR_WRONG_REVISION)
00168 error = NETWORK_ERROR_ILLEGAL_PACKET;
00169
00170 SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->client_id, error);
00171 }
00172 }
00173 } else {
00174 DEBUG(net, 1, "Client %d made an error and has been disconnected. Reason: '%s'", cs->client_id, str);
00175 }
00176
00177 cs->CloseConnection(false);
00178
00179
00180 cs->Send_Packets();
00181
00182
00183 NetworkCloseClient(cs, false);
00184 }
00185
00186 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHECK_NEWGRFS)(NetworkClientSocket *cs)
00187 {
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 Packet *p = new Packet(PACKET_SERVER_CHECK_NEWGRFS);
00199 const GRFConfig *c;
00200 uint grf_count = 0;
00201
00202 for (c = _grfconfig; c != NULL; c = c->next) {
00203 if (!HasBit(c->flags, GCF_STATIC)) grf_count++;
00204 }
00205
00206 p->Send_uint8 (grf_count);
00207 for (c = _grfconfig; c != NULL; c = c->next) {
00208 if (!HasBit(c->flags, GCF_STATIC)) cs->Send_GRFIdentifier(p, c);
00209 }
00210
00211 cs->Send_Packet(p);
00212 }
00213
00214 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_NEED_PASSWORD)(NetworkClientSocket *cs, NetworkPasswordType type)
00215 {
00216
00217
00218
00219
00220
00221
00222
00223
00224 if (cs->status >= STATUS_AUTH) return;
00225
00226 cs->status = STATUS_AUTHORIZING;
00227
00228 Packet *p = new Packet(PACKET_SERVER_NEED_PASSWORD);
00229 p->Send_uint8(type);
00230 p->Send_uint32(_settings_game.game_creation.generation_seed);
00231 p->Send_string(_settings_client.network.network_id);
00232 cs->Send_Packet(p);
00233 }
00234
00235 DEF_SERVER_SEND_COMMAND(PACKET_SERVER_WELCOME)
00236 {
00237
00238
00239
00240
00241
00242
00243
00244 Packet *p;
00245 NetworkClientSocket *new_cs;
00246
00247
00248 if (cs->status >= STATUS_AUTH) return;
00249
00250 cs->status = STATUS_AUTH;
00251 _network_game_info.clients_on++;
00252
00253 p = new Packet(PACKET_SERVER_WELCOME);
00254 p->Send_uint32(cs->client_id);
00255 p->Send_uint32(_settings_game.game_creation.generation_seed);
00256 p->Send_string(_settings_client.network.network_id);
00257 cs->Send_Packet(p);
00258
00259
00260 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00261 if (new_cs != cs && new_cs->status > STATUS_AUTH)
00262 SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(cs, new_cs->GetInfo());
00263 }
00264
00265 SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(cs, NetworkFindClientInfoFromClientID(CLIENT_ID_SERVER));
00266 }
00267
00268 DEF_SERVER_SEND_COMMAND(PACKET_SERVER_WAIT)
00269 {
00270
00271
00272
00273
00274
00275
00276
00277 int waiting = 0;
00278 NetworkClientSocket *new_cs;
00279 Packet *p;
00280
00281
00282 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00283 if (new_cs->status == STATUS_MAP_WAIT) waiting++;
00284 }
00285
00286 p = new Packet(PACKET_SERVER_WAIT);
00287 p->Send_uint8(waiting);
00288 cs->Send_Packet(p);
00289 }
00290
00291
00292 DEF_SERVER_SEND_COMMAND(PACKET_SERVER_MAP)
00293 {
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 static FILE *file_pointer;
00309 static uint sent_packets;
00310
00311 if (cs->status < STATUS_AUTH) {
00312
00313 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED);
00314 return;
00315 }
00316
00317 if (cs->status == STATUS_AUTH) {
00318 const char *filename = "network_server.tmp";
00319 Packet *p;
00320
00321
00322 if (SaveOrLoad(filename, SL_SAVE, AUTOSAVE_DIR) != SL_OK) usererror("network savedump failed");
00323
00324 file_pointer = FioFOpenFile(filename, "rb", AUTOSAVE_DIR);
00325 fseek(file_pointer, 0, SEEK_END);
00326
00327 if (ftell(file_pointer) == 0) usererror("network savedump failed - zero sized savegame?");
00328
00329
00330 p = new Packet(PACKET_SERVER_MAP);
00331 p->Send_uint8 (MAP_PACKET_START);
00332 p->Send_uint32(_frame_counter);
00333 p->Send_uint32(ftell(file_pointer));
00334 cs->Send_Packet(p);
00335
00336 fseek(file_pointer, 0, SEEK_SET);
00337
00338 sent_packets = 4;
00339
00340 cs->status = STATUS_MAP;
00341
00342 cs->last_frame = _frame_counter;
00343 cs->last_frame_server = _frame_counter;
00344 }
00345
00346 if (cs->status == STATUS_MAP) {
00347 uint i;
00348 int res;
00349 for (i = 0; i < sent_packets; i++) {
00350 Packet *p = new Packet(PACKET_SERVER_MAP);
00351 p->Send_uint8(MAP_PACKET_NORMAL);
00352 res = (int)fread(p->buffer + p->size, 1, SEND_MTU - p->size, file_pointer);
00353
00354 if (ferror(file_pointer)) usererror("Error reading temporary network savegame!");
00355
00356 p->size += res;
00357 cs->Send_Packet(p);
00358 if (feof(file_pointer)) {
00359
00360 Packet *p = new Packet(PACKET_SERVER_MAP);
00361 p->Send_uint8(MAP_PACKET_END);
00362 cs->Send_Packet(p);
00363
00364
00365
00366 cs->status = STATUS_DONE_MAP;
00367 fclose(file_pointer);
00368
00369 {
00370 NetworkClientSocket *new_cs;
00371 bool new_map_client = false;
00372
00373
00374 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00375 if (new_cs->status == STATUS_MAP_WAIT) {
00376
00377 if (!new_map_client) {
00378
00379 new_cs->status = STATUS_AUTH;
00380 new_map_client = true;
00381 SEND_COMMAND(PACKET_SERVER_MAP)(new_cs);
00382 } else {
00383
00384 SEND_COMMAND(PACKET_SERVER_WAIT)(new_cs);
00385 }
00386 }
00387 }
00388 }
00389
00390
00391 break;
00392 }
00393 }
00394
00395
00396 cs->Send_Packets();
00397 if (cs->IsPacketQueueEmpty()) {
00398
00399 sent_packets *= 2;
00400 } else {
00401
00402 if (sent_packets > 1) sent_packets /= 2;
00403 }
00404 }
00405 }
00406
00407 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_JOIN)(NetworkClientSocket *cs, ClientID client_id)
00408 {
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418 Packet *p = new Packet(PACKET_SERVER_JOIN);
00419
00420 p->Send_uint32(client_id);
00421
00422 cs->Send_Packet(p);
00423 }
00424
00425
00426 DEF_SERVER_SEND_COMMAND(PACKET_SERVER_FRAME)
00427 {
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 Packet *p = new Packet(PACKET_SERVER_FRAME);
00440 p->Send_uint32(_frame_counter);
00441 p->Send_uint32(_frame_counter_max);
00442 #ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
00443 p->Send_uint32(_sync_seed_1);
00444 #ifdef NETWORK_SEND_DOUBLE_SEED
00445 p->Send_uint32(_sync_seed_2);
00446 #endif
00447 #endif
00448 cs->Send_Packet(p);
00449 }
00450
00451 DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SYNC)
00452 {
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 Packet *p = new Packet(PACKET_SERVER_SYNC);
00464 p->Send_uint32(_frame_counter);
00465 p->Send_uint32(_sync_seed_1);
00466
00467 #ifdef NETWORK_SEND_DOUBLE_SEED
00468 p->Send_uint32(_sync_seed_2);
00469 #endif
00470 cs->Send_Packet(p);
00471 }
00472
00473 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_COMMAND)(NetworkClientSocket *cs, const CommandPacket *cp)
00474 {
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 Packet *p = new Packet(PACKET_SERVER_COMMAND);
00490
00491 cs->Send_Command(p, cp);
00492 p->Send_uint32(cp->frame);
00493 p->Send_bool (cp->my_cmd);
00494
00495 cs->Send_Packet(p);
00496 }
00497
00498 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHAT)(NetworkClientSocket *cs, NetworkAction action, ClientID client_id, bool self_send, const char *msg, int64 data)
00499 {
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510 Packet *p = new Packet(PACKET_SERVER_CHAT);
00511
00512 p->Send_uint8 (action);
00513 p->Send_uint32(client_id);
00514 p->Send_bool (self_send);
00515 p->Send_string(msg);
00516 p->Send_uint64(data);
00517
00518 cs->Send_Packet(p);
00519 }
00520
00521 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR_QUIT)(NetworkClientSocket *cs, ClientID client_id, NetworkErrorCode errorno)
00522 {
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532 Packet *p = new Packet(PACKET_SERVER_ERROR_QUIT);
00533
00534 p->Send_uint32(client_id);
00535 p->Send_uint8 (errorno);
00536
00537 cs->Send_Packet(p);
00538 }
00539
00540 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_QUIT)(NetworkClientSocket *cs, ClientID client_id)
00541 {
00542
00543
00544
00545
00546
00547
00548
00549
00550 Packet *p = new Packet(PACKET_SERVER_QUIT);
00551
00552 p->Send_uint32(client_id);
00553
00554 cs->Send_Packet(p);
00555 }
00556
00557 DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SHUTDOWN)
00558 {
00559
00560
00561
00562
00563
00564
00565
00566 Packet *p = new Packet(PACKET_SERVER_SHUTDOWN);
00567 cs->Send_Packet(p);
00568 }
00569
00570 DEF_SERVER_SEND_COMMAND(PACKET_SERVER_NEWGAME)
00571 {
00572
00573
00574
00575
00576
00577
00578
00579 Packet *p = new Packet(PACKET_SERVER_NEWGAME);
00580 cs->Send_Packet(p);
00581 }
00582
00583 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkClientSocket *cs, uint16 colour, const char *command)
00584 {
00585 Packet *p = new Packet(PACKET_SERVER_RCON);
00586
00587 p->Send_uint16(colour);
00588 p->Send_string(command);
00589 cs->Send_Packet(p);
00590 }
00591
00592 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_MOVE)(NetworkClientSocket *cs, ClientID client_id, CompanyID company_id)
00593 {
00594 Packet *p = new Packet(PACKET_SERVER_MOVE);
00595
00596 p->Send_uint32(client_id);
00597 p->Send_uint8(company_id);
00598 cs->Send_Packet(p);
00599 }
00600
00601 DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_COMPANY_UPDATE)(NetworkClientSocket *cs)
00602 {
00603 Packet *p = new Packet(PACKET_SERVER_COMPANY_UPDATE);
00604
00605 p->Send_uint16(_network_company_passworded);
00606 cs->Send_Packet(p);
00607 }
00608
00609 DEF_SERVER_SEND_COMMAND(PACKET_SERVER_CONFIG_UPDATE)
00610 {
00611 Packet *p = new Packet(PACKET_SERVER_CONFIG_UPDATE);
00612
00613 p->Send_uint8(_settings_client.network.max_companies);
00614 p->Send_uint8(_settings_client.network.max_spectators);
00615 cs->Send_Packet(p);
00616 }
00617
00618
00619
00620
00621
00622
00623 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_INFO)
00624 {
00625 SEND_COMMAND(PACKET_SERVER_COMPANY_INFO)(cs);
00626 return NETWORK_RECV_STATUS_OKAY;
00627 }
00628
00629 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_NEWGRFS_CHECKED)
00630 {
00631 if (cs->status != STATUS_INACTIVE) {
00632
00633 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
00634 return NETWORK_RECV_STATUS_OKAY;
00635 }
00636
00637 NetworkClientInfo *ci = cs->GetInfo();
00638
00639
00640 if (!StrEmpty(_settings_client.network.server_password)) {
00641 SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_GAME_PASSWORD);
00642 } else {
00643 if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) {
00644 SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD);
00645 } else {
00646 SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
00647 }
00648 }
00649 return NETWORK_RECV_STATUS_OKAY;
00650 }
00651
00652 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_JOIN)
00653 {
00654 if (cs->status != STATUS_INACTIVE) {
00655
00656 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
00657 return NETWORK_RECV_STATUS_OKAY;
00658 }
00659
00660 char name[NETWORK_CLIENT_NAME_LENGTH];
00661 NetworkClientInfo *ci;
00662 CompanyID playas;
00663 NetworkLanguage client_lang;
00664 char client_revision[NETWORK_REVISION_LENGTH];
00665
00666 p->Recv_string(client_revision, sizeof(client_revision));
00667
00668
00669 if (!IsNetworkCompatibleVersion(client_revision)) {
00670
00671 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_REVISION);
00672 return NETWORK_RECV_STATUS_OKAY;
00673 }
00674
00675 p->Recv_string(name, sizeof(name));
00676 playas = (Owner)p->Recv_uint8();
00677 client_lang = (NetworkLanguage)p->Recv_uint8();
00678
00679 if (cs->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
00680
00681
00682 switch (playas) {
00683 case COMPANY_NEW_COMPANY:
00684 if (Company::GetNumItems() >= _settings_client.network.max_companies) {
00685 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_FULL);
00686 return NETWORK_RECV_STATUS_OKAY;
00687 }
00688 break;
00689 case COMPANY_SPECTATOR:
00690 if (NetworkSpectatorCount() >= _settings_client.network.max_spectators) {
00691 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_FULL);
00692 return NETWORK_RECV_STATUS_OKAY;
00693 }
00694 break;
00695 default:
00696 if (!Company::IsValidHumanID(playas)) {
00697 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_COMPANY_MISMATCH);
00698 return NETWORK_RECV_STATUS_OKAY;
00699 }
00700 break;
00701 }
00702
00703
00704 if (StrEmpty(name)) strecpy(name, "Player", lastof(name));
00705
00706 if (!NetworkFindName(name)) {
00707
00708 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NAME_IN_USE);
00709 return NETWORK_RECV_STATUS_OKAY;
00710 }
00711
00712 ci = cs->GetInfo();
00713
00714 strecpy(ci->client_name, name, lastof(ci->client_name));
00715 ci->client_playas = playas;
00716 ci->client_lang = client_lang;
00717
00718
00719 if (Company::IsValidID(playas)) _network_company_states[playas].months_empty = 0;
00720
00721 if (_grfconfig == NULL) {
00722 RECEIVE_COMMAND(PACKET_CLIENT_NEWGRFS_CHECKED)(cs, NULL);
00723 } else {
00724 SEND_COMMAND(PACKET_SERVER_CHECK_NEWGRFS)(cs);
00725 }
00726 return NETWORK_RECV_STATUS_OKAY;
00727 }
00728
00729 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD)
00730 {
00731 NetworkPasswordType type;
00732 char password[NETWORK_PASSWORD_LENGTH];
00733 const NetworkClientInfo *ci;
00734
00735 type = (NetworkPasswordType)p->Recv_uint8();
00736 p->Recv_string(password, sizeof(password));
00737
00738 if (cs->status == STATUS_AUTHORIZING && type == NETWORK_GAME_PASSWORD) {
00739
00740 if (strcmp(password, _settings_client.network.server_password) != 0) {
00741
00742 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD);
00743 return NETWORK_RECV_STATUS_OKAY;
00744 }
00745
00746 ci = cs->GetInfo();
00747
00748 if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) {
00749 SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD);
00750 return NETWORK_RECV_STATUS_OKAY;
00751 }
00752
00753
00754 SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
00755 return NETWORK_RECV_STATUS_OKAY;
00756 } else if (cs->status == STATUS_AUTHORIZING && type == NETWORK_COMPANY_PASSWORD) {
00757 ci = cs->GetInfo();
00758
00759 if (strcmp(password, _network_company_states[ci->client_playas].password) != 0) {
00760
00761 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD);
00762 return NETWORK_RECV_STATUS_OKAY;
00763 }
00764
00765 SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
00766 return NETWORK_RECV_STATUS_OKAY;
00767 }
00768
00769
00770 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
00771 return NETWORK_RECV_STATUS_OKAY;
00772 }
00773
00774 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_GETMAP)
00775 {
00776 NetworkClientSocket *new_cs;
00777
00778
00779
00780
00781
00782
00783
00784
00785 if (HasBit(_openttd_newgrf_version, 19)) {
00786 if (_openttd_newgrf_version != p->Recv_uint32()) {
00787
00788
00789 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
00790 return NETWORK_RECV_STATUS_OKAY;
00791 }
00792 } else if (p->size != 3) {
00793
00794
00795 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
00796 return NETWORK_RECV_STATUS_OKAY;
00797 }
00798
00799
00800
00801 if (cs->status < STATUS_AUTH || cs->HasClientQuit()) {
00802 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED);
00803 return NETWORK_RECV_STATUS_OKAY;
00804 }
00805
00806
00807 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00808 if (new_cs->status == STATUS_MAP) {
00809
00810 cs->status = STATUS_MAP_WAIT;
00811 SEND_COMMAND(PACKET_SERVER_WAIT)(cs);
00812 return NETWORK_RECV_STATUS_OKAY;
00813 }
00814 }
00815
00816
00817 SEND_COMMAND(PACKET_SERVER_MAP)(cs);
00818 return NETWORK_RECV_STATUS_OKAY;
00819 }
00820
00821 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK)
00822 {
00823
00824 if (cs->status == STATUS_DONE_MAP && !cs->HasClientQuit()) {
00825 char client_name[NETWORK_CLIENT_NAME_LENGTH];
00826 NetworkClientSocket *new_cs;
00827
00828 NetworkGetClientName(client_name, sizeof(client_name), cs);
00829
00830 NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, client_name, NULL, cs->client_id);
00831
00832
00833
00834 cs->status = STATUS_PRE_ACTIVE;
00835 NetworkHandleCommandQueue(cs);
00836 SEND_COMMAND(PACKET_SERVER_FRAME)(cs);
00837 SEND_COMMAND(PACKET_SERVER_SYNC)(cs);
00838
00839
00840
00841 cs->last_frame = _frame_counter;
00842 cs->last_frame_server = _frame_counter;
00843
00844 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00845 if (new_cs->status > STATUS_AUTH) {
00846 SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(new_cs, cs->GetInfo());
00847 SEND_COMMAND(PACKET_SERVER_JOIN)(new_cs, cs->client_id);
00848 }
00849 }
00850
00851
00852 SEND_COMMAND(PACKET_SERVER_CONFIG_UPDATE)(cs);
00853
00854
00855 SEND_COMMAND(PACKET_SERVER_COMPANY_UPDATE)(cs);
00856 } else {
00857
00858 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
00859 }
00860 return NETWORK_RECV_STATUS_OKAY;
00861 }
00862
00867 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
00868 {
00869 NetworkClientSocket *new_cs;
00870
00871
00872
00873 if (cs->status < STATUS_DONE_MAP || cs->HasClientQuit()) {
00874 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
00875 return NETWORK_RECV_STATUS_OKAY;
00876 }
00877
00878 CommandPacket cp;
00879 const char *err = cs->Recv_Command(p, &cp);
00880
00881 if (cs->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
00882
00883 NetworkClientInfo *ci = cs->GetInfo();
00884
00885 if (err != NULL) {
00886 IConsolePrintF(CC_ERROR, "WARNING: %s from client %d (IP: %s).", err, ci->client_id, GetClientIP(ci));
00887 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
00888 return NETWORK_RECV_STATUS_OKAY;
00889 }
00890
00891
00892 if ((GetCommandFlags(cp.cmd) & CMD_SERVER) && ci->client_id != CLIENT_ID_SERVER) {
00893 IConsolePrintF(CC_ERROR, "WARNING: server only command from: client %d (IP: %s), kicking...", ci->client_id, GetClientIP(ci));
00894 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_KICKED);
00895 return NETWORK_RECV_STATUS_OKAY;
00896 }
00897
00898 if ((GetCommandFlags(cp.cmd) & CMD_SPECTATOR) == 0 && !Company::IsValidID(cp.company) && ci->client_id != CLIENT_ID_SERVER) {
00899 IConsolePrintF(CC_ERROR, "WARNING: spectator issueing command from client %d (IP: %s), kicking...", ci->client_id, GetClientIP(ci));
00900 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_KICKED);
00901 return NETWORK_RECV_STATUS_OKAY;
00902 }
00903
00908 if (!(cp.cmd == CMD_COMPANY_CTRL && cp.p1 == 0 && ci->client_playas == COMPANY_NEW_COMPANY) && ci->client_playas != cp.company) {
00909 IConsolePrintF(CC_ERROR, "WARNING: client %d (IP: %s) tried to execute a command as company %d, kicking...",
00910 ci->client_playas + 1, GetClientIP(ci), cp.company + 1);
00911 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_COMPANY_MISMATCH);
00912 return NETWORK_RECV_STATUS_OKAY;
00913 }
00914
00920 if (cp.cmd == CMD_COMPANY_CTRL) {
00921 if (cp.p1 != 0 || cp.company != COMPANY_SPECTATOR) {
00922 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_CHEATER);
00923 return NETWORK_RECV_STATUS_OKAY;
00924 }
00925
00926
00927 if (Company::GetNumItems() >= _settings_client.network.max_companies) {
00928 NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_CLIENT, ci->client_id, "cannot create new company, server full", CLIENT_ID_SERVER);
00929 return NETWORK_RECV_STATUS_OKAY;
00930 }
00931
00932 cp.p2 = cs->client_id;
00933 }
00934
00935
00936
00937 cp.frame = _frame_counter_max + 1;
00938 cp.next = NULL;
00939
00940 CommandCallback *callback = cp.callback;
00941
00942
00943
00944 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00945 if (new_cs->status >= STATUS_MAP) {
00946
00947
00948 cp.callback = (new_cs != cs) ? NULL : callback;
00949 cp.my_cmd = (new_cs == cs);
00950 NetworkAddCommandQueue(cp, new_cs);
00951 }
00952 }
00953
00954 cp.callback = NULL;
00955 cp.my_cmd = false;
00956 NetworkAddCommandQueue(cp);
00957 return NETWORK_RECV_STATUS_OKAY;
00958 }
00959
00960 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ERROR)
00961 {
00962
00963
00964 NetworkClientSocket *new_cs;
00965 char str[100];
00966 char client_name[NETWORK_CLIENT_NAME_LENGTH];
00967 NetworkErrorCode errorno = (NetworkErrorCode)p->Recv_uint8();
00968
00969
00970 if (cs->status < STATUS_DONE_MAP || cs->HasClientQuit()) {
00971 cs->CloseConnection();
00972 return NETWORK_RECV_STATUS_CONN_LOST;
00973 }
00974
00975 NetworkGetClientName(client_name, sizeof(client_name), cs);
00976
00977 StringID strid = GetNetworkErrorMsg(errorno);
00978 GetString(str, strid, lastof(str));
00979
00980 DEBUG(net, 2, "'%s' reported an error and is closing its connection (%s)", client_name, str);
00981
00982 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, strid);
00983
00984 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00985 if (new_cs->status > STATUS_AUTH) {
00986 SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->client_id, errorno);
00987 }
00988 }
00989
00990 cs->CloseConnection(false);
00991 return NETWORK_RECV_STATUS_CONN_LOST;
00992 }
00993
00994 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_QUIT)
00995 {
00996
00997
00998 NetworkClientSocket *new_cs;
00999 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01000
01001
01002 if (cs->status < STATUS_DONE_MAP || cs->HasClientQuit()) {
01003 cs->CloseConnection();
01004 return NETWORK_RECV_STATUS_CONN_LOST;
01005 }
01006
01007 NetworkGetClientName(client_name, sizeof(client_name), cs);
01008
01009 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, STR_NETWORK_MESSAGE_CLIENT_LEAVING);
01010
01011 FOR_ALL_CLIENT_SOCKETS(new_cs) {
01012 if (new_cs->status > STATUS_AUTH) {
01013 SEND_COMMAND(PACKET_SERVER_QUIT)(new_cs, cs->client_id);
01014 }
01015 }
01016
01017 cs->CloseConnection(false);
01018 return NETWORK_RECV_STATUS_CONN_LOST;
01019 }
01020
01021 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ACK)
01022 {
01023 if (cs->status < STATUS_AUTH) {
01024
01025 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED);
01026 return NETWORK_RECV_STATUS_OKAY;
01027 }
01028
01029 uint32 frame = p->Recv_uint32();
01030
01031
01032 if (cs->status == STATUS_PRE_ACTIVE) {
01033
01034 if (frame + DAY_TICKS < _frame_counter) return NETWORK_RECV_STATUS_OKAY;
01035
01036
01037 cs->status = STATUS_ACTIVE;
01038
01039
01040 IConsoleCmdExec("exec scripts/on_server_connect.scr 0");
01041 }
01042
01043
01044 cs->last_frame = frame;
01045
01046 cs->last_frame_server = _frame_counter;
01047 return NETWORK_RECV_STATUS_OKAY;
01048 }
01049
01050
01051
01052 void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, const char *msg, ClientID from_id, int64 data)
01053 {
01054 NetworkClientSocket *cs;
01055 const NetworkClientInfo *ci, *ci_own, *ci_to;
01056
01057 switch (desttype) {
01058 case DESTTYPE_CLIENT:
01059
01060 if ((ClientID)dest == CLIENT_ID_SERVER) {
01061 ci = NetworkFindClientInfoFromClientID(from_id);
01062
01063 if (ci != NULL)
01064 NetworkTextMessage(action, (ConsoleColour)GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
01065 } else {
01066
01067 FOR_ALL_CLIENT_SOCKETS(cs) {
01068 if (cs->client_id == (ClientID)dest) {
01069 SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_id, false, msg, data);
01070 break;
01071 }
01072 }
01073 }
01074
01075
01076 if (from_id != (ClientID)dest) {
01077 if (from_id == CLIENT_ID_SERVER) {
01078 ci = NetworkFindClientInfoFromClientID(from_id);
01079 ci_to = NetworkFindClientInfoFromClientID((ClientID)dest);
01080 if (ci != NULL && ci_to != NULL)
01081 NetworkTextMessage(action, (ConsoleColour)GetDrawStringCompanyColour(ci->client_playas), true, ci_to->client_name, msg, data);
01082 } else {
01083 FOR_ALL_CLIENT_SOCKETS(cs) {
01084 if (cs->client_id == from_id) {
01085 SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, (ClientID)dest, true, msg, data);
01086 break;
01087 }
01088 }
01089 }
01090 }
01091 break;
01092 case DESTTYPE_TEAM: {
01093 bool show_local = true;
01094
01095
01096 ci_to = NULL;
01097 FOR_ALL_CLIENT_SOCKETS(cs) {
01098 ci = cs->GetInfo();
01099 if (ci->client_playas == (CompanyID)dest) {
01100 SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_id, false, msg, data);
01101 if (cs->client_id == from_id) show_local = false;
01102 ci_to = ci;
01103 }
01104 }
01105
01106 ci = NetworkFindClientInfoFromClientID(from_id);
01107 ci_own = NetworkFindClientInfoFromClientID(CLIENT_ID_SERVER);
01108 if (ci != NULL && ci_own != NULL && ci_own->client_playas == dest) {
01109 NetworkTextMessage(action, (ConsoleColour)GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
01110 if (from_id == CLIENT_ID_SERVER) show_local = false;
01111 ci_to = ci_own;
01112 }
01113
01114
01115 if (ci_to == NULL) break;
01116
01117
01118 if (ci != NULL && show_local) {
01119 if (from_id == CLIENT_ID_SERVER) {
01120 char name[NETWORK_NAME_LENGTH];
01121 StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;
01122 SetDParam(0, ci_to->client_playas);
01123 GetString(name, str, lastof(name));
01124 NetworkTextMessage(action, (ConsoleColour)GetDrawStringCompanyColour(ci_own->client_playas), true, name, msg, data);
01125 } else {
01126 FOR_ALL_CLIENT_SOCKETS(cs) {
01127 if (cs->client_id == from_id) {
01128 SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, ci_to->client_id, true, msg, data);
01129 }
01130 }
01131 }
01132 }
01133 }
01134 break;
01135 default:
01136 DEBUG(net, 0, "[server] received unknown chat destination type %d. Doing broadcast instead", desttype);
01137
01138 case DESTTYPE_BROADCAST:
01139 FOR_ALL_CLIENT_SOCKETS(cs) {
01140 SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_id, false, msg, data);
01141 }
01142 ci = NetworkFindClientInfoFromClientID(from_id);
01143 if (ci != NULL)
01144 NetworkTextMessage(action, (ConsoleColour)GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
01145 break;
01146 }
01147 }
01148
01149 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_CHAT)
01150 {
01151 if (cs->status < STATUS_AUTH) {
01152
01153 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED);
01154 return NETWORK_RECV_STATUS_OKAY;
01155 }
01156
01157 NetworkAction action = (NetworkAction)p->Recv_uint8();
01158 DestType desttype = (DestType)p->Recv_uint8();
01159 int dest = p->Recv_uint32();
01160 char msg[NETWORK_CHAT_LENGTH];
01161
01162 p->Recv_string(msg, NETWORK_CHAT_LENGTH);
01163 int64 data = p->Recv_uint64();
01164
01165 NetworkClientInfo *ci = cs->GetInfo();
01166 switch (action) {
01167 case NETWORK_ACTION_GIVE_MONEY:
01168 if (!Company::IsValidID(ci->client_playas)) break;
01169
01170 case NETWORK_ACTION_CHAT:
01171 case NETWORK_ACTION_CHAT_CLIENT:
01172 case NETWORK_ACTION_CHAT_COMPANY:
01173 NetworkServerSendChat(action, desttype, dest, msg, cs->client_id, data);
01174 break;
01175 default:
01176 IConsolePrintF(CC_ERROR, "WARNING: invalid chat action from client %d (IP: %s).", ci->client_id, GetClientIP(ci));
01177 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
01178 break;
01179 }
01180 return NETWORK_RECV_STATUS_OKAY;
01181 }
01182
01183 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_SET_PASSWORD)
01184 {
01185 if (cs->status != STATUS_ACTIVE) {
01186
01187 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
01188 return NETWORK_RECV_STATUS_OKAY;
01189 }
01190
01191 char password[NETWORK_PASSWORD_LENGTH];
01192 const NetworkClientInfo *ci;
01193
01194 p->Recv_string(password, sizeof(password));
01195 ci = cs->GetInfo();
01196
01197 if (Company::IsValidID(ci->client_playas)) {
01198 strecpy(_network_company_states[ci->client_playas].password, password, lastof(_network_company_states[ci->client_playas].password));
01199 NetworkServerUpdateCompanyPassworded(ci->client_playas, !StrEmpty(_network_company_states[ci->client_playas].password));
01200 }
01201 return NETWORK_RECV_STATUS_OKAY;
01202 }
01203
01204 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_SET_NAME)
01205 {
01206 if (cs->status != STATUS_ACTIVE) {
01207
01208 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
01209 return NETWORK_RECV_STATUS_OKAY;
01210 }
01211
01212 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01213 NetworkClientInfo *ci;
01214
01215 p->Recv_string(client_name, sizeof(client_name));
01216 ci = cs->GetInfo();
01217
01218 if (cs->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
01219
01220 if (ci != NULL) {
01221
01222 if (NetworkFindName(client_name)) {
01223 NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, client_name);
01224 strecpy(ci->client_name, client_name, lastof(ci->client_name));
01225 NetworkUpdateClientInfo(ci->client_id);
01226 }
01227 }
01228 return NETWORK_RECV_STATUS_OKAY;
01229 }
01230
01231 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_RCON)
01232 {
01233 char pass[NETWORK_PASSWORD_LENGTH];
01234 char command[NETWORK_RCONCOMMAND_LENGTH];
01235
01236 if (StrEmpty(_settings_client.network.rcon_password)) return NETWORK_RECV_STATUS_OKAY;
01237
01238 p->Recv_string(pass, sizeof(pass));
01239 p->Recv_string(command, sizeof(command));
01240
01241 if (strcmp(pass, _settings_client.network.rcon_password) != 0) {
01242 DEBUG(net, 0, "[rcon] wrong password from client-id %d", cs->client_id);
01243 return NETWORK_RECV_STATUS_OKAY;
01244 }
01245
01246 DEBUG(net, 0, "[rcon] client-id %d executed: '%s'", cs->client_id, command);
01247
01248 _redirect_console_to_client = cs->client_id;
01249 IConsoleCmdExec(command);
01250 _redirect_console_to_client = INVALID_CLIENT_ID;
01251 return NETWORK_RECV_STATUS_OKAY;
01252 }
01253
01254 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_MOVE)
01255 {
01256 CompanyID company_id = (Owner)p->Recv_uint8();
01257
01258
01259 if (company_id != COMPANY_SPECTATOR && !Company::IsValidHumanID(company_id)) return NETWORK_RECV_STATUS_OKAY;
01260
01261
01262 if (company_id != COMPANY_SPECTATOR && !StrEmpty(_network_company_states[company_id].password)) {
01263
01264 char password[NETWORK_PASSWORD_LENGTH];
01265 p->Recv_string(password, sizeof(password));
01266
01267
01268 if (strcmp(password, _network_company_states[company_id].password) != 0) {
01269 DEBUG(net, 2, "[move] wrong password from client-id #%d for company #%d", cs->client_id, company_id + 1);
01270 return NETWORK_RECV_STATUS_OKAY;
01271 }
01272 }
01273
01274
01275 NetworkServerDoMove(cs->client_id, company_id);
01276 return NETWORK_RECV_STATUS_OKAY;
01277 }
01278
01279
01280 typedef NetworkRecvStatus NetworkServerPacket(NetworkClientSocket *cs, Packet *p);
01281
01282
01283
01284
01285
01286
01287 static NetworkServerPacket * const _network_server_packet[] = {
01288 NULL,
01289 NULL,
01290 RECEIVE_COMMAND(PACKET_CLIENT_JOIN),
01291 NULL,
01292 RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_INFO),
01293 NULL,
01294 NULL,
01295 NULL,
01296 RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD),
01297 NULL,
01298 RECEIVE_COMMAND(PACKET_CLIENT_GETMAP),
01299 NULL,
01300 NULL,
01301 RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK),
01302 NULL,
01303 NULL,
01304 NULL,
01305 RECEIVE_COMMAND(PACKET_CLIENT_ACK),
01306 RECEIVE_COMMAND(PACKET_CLIENT_COMMAND),
01307 NULL,
01308 RECEIVE_COMMAND(PACKET_CLIENT_CHAT),
01309 NULL,
01310 RECEIVE_COMMAND(PACKET_CLIENT_SET_PASSWORD),
01311 RECEIVE_COMMAND(PACKET_CLIENT_SET_NAME),
01312 RECEIVE_COMMAND(PACKET_CLIENT_QUIT),
01313 RECEIVE_COMMAND(PACKET_CLIENT_ERROR),
01314 NULL,
01315 NULL,
01316 NULL,
01317 NULL,
01318 NULL,
01319 RECEIVE_COMMAND(PACKET_CLIENT_RCON),
01320 NULL,
01321 RECEIVE_COMMAND(PACKET_CLIENT_NEWGRFS_CHECKED),
01322 NULL,
01323 RECEIVE_COMMAND(PACKET_CLIENT_MOVE),
01324 NULL,
01325 NULL,
01326 };
01327
01328
01329 assert_compile(lengthof(_network_server_packet) == PACKET_END);
01330
01331 void NetworkSocketHandler::Send_CompanyInformation(Packet *p, const Company *c, const NetworkCompanyStats *stats)
01332 {
01333
01334 char company_name[NETWORK_COMPANY_NAME_LENGTH];
01335 SetDParam(0, c->index);
01336 GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
01337
01338
01339 Money income = 0;
01340 if (_cur_year - 1 == c->inaugurated_year) {
01341
01342 for (uint i = 0; i < lengthof(c->yearly_expenses[2]); i++) {
01343 income -= c->yearly_expenses[2][i];
01344 }
01345 } else {
01346 for (uint i = 0; i < lengthof(c->yearly_expenses[1]); i++) {
01347 income -= c->yearly_expenses[1][i];
01348 }
01349 }
01350
01351
01352 p->Send_uint8 (c->index);
01353 p->Send_string(company_name);
01354 p->Send_uint32(c->inaugurated_year);
01355 p->Send_uint64(c->old_economy[0].company_value);
01356 p->Send_uint64(c->money);
01357 p->Send_uint64(income);
01358 p->Send_uint16(c->old_economy[0].performance_history);
01359
01360
01361 p->Send_bool (!StrEmpty(_network_company_states[c->index].password));
01362
01363 for (int i = 0; i < NETWORK_VEHICLE_TYPES; i++) {
01364 p->Send_uint16(stats->num_vehicle[i]);
01365 }
01366
01367 for (int i = 0; i < NETWORK_STATION_TYPES; i++) {
01368 p->Send_uint16(stats->num_station[i]);
01369 }
01370
01371 p->Send_bool(c->is_ai);
01372 }
01373
01378 void NetworkPopulateCompanyStats(NetworkCompanyStats *stats)
01379 {
01380 const Vehicle *v;
01381 const Station *s;
01382
01383 memset(stats, 0, sizeof(*stats) * MAX_COMPANIES);
01384
01385
01386 FOR_ALL_VEHICLES(v) {
01387 if (!Company::IsValidID(v->owner) || !v->IsPrimaryVehicle()) continue;
01388 byte type = 0;
01389 switch (v->type) {
01390 case VEH_TRAIN: type = 0; break;
01391 case VEH_ROAD: type = RoadVehicle::From(v)->IsBus() ? 2 : 1; break;
01392 case VEH_AIRCRAFT: type = 3; break;
01393 case VEH_SHIP: type = 4; break;
01394 default: continue;
01395 }
01396 stats[v->owner].num_vehicle[type]++;
01397 }
01398
01399
01400 FOR_ALL_STATIONS(s) {
01401 if (Company::IsValidID(s->owner)) {
01402 NetworkCompanyStats *npi = &stats[s->owner];
01403
01404 if (s->facilities & FACIL_TRAIN) npi->num_station[0]++;
01405 if (s->facilities & FACIL_TRUCK_STOP) npi->num_station[1]++;
01406 if (s->facilities & FACIL_BUS_STOP) npi->num_station[2]++;
01407 if (s->facilities & FACIL_AIRPORT) npi->num_station[3]++;
01408 if (s->facilities & FACIL_DOCK) npi->num_station[4]++;
01409 }
01410 }
01411 }
01412
01413
01414 void NetworkUpdateClientInfo(ClientID client_id)
01415 {
01416 NetworkClientSocket *cs;
01417 NetworkClientInfo *ci = NetworkFindClientInfoFromClientID(client_id);
01418
01419 if (ci == NULL) return;
01420
01421 FOR_ALL_CLIENT_SOCKETS(cs) {
01422 SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(cs, ci);
01423 }
01424 }
01425
01426
01427 static void NetworkCheckRestartMap()
01428 {
01429 if (_settings_client.network.restart_game_year != 0 && _cur_year >= _settings_client.network.restart_game_year) {
01430 DEBUG(net, 0, "Auto-restarting map. Year %d reached", _cur_year);
01431
01432 StartNewGameWithoutGUI(GENERATE_NEW_SEED);
01433 }
01434 }
01435
01436
01437
01438
01439
01440
01441 static void NetworkAutoCleanCompanies()
01442 {
01443 const NetworkClientInfo *ci;
01444 const Company *c;
01445 bool clients_in_company[MAX_COMPANIES];
01446 int vehicles_in_company[MAX_COMPANIES];
01447
01448 if (!_settings_client.network.autoclean_companies) return;
01449
01450 memset(clients_in_company, 0, sizeof(clients_in_company));
01451
01452
01453 FOR_ALL_CLIENT_INFOS(ci) {
01454 if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true;
01455 }
01456
01457 if (!_network_dedicated) {
01458 ci = NetworkFindClientInfoFromClientID(CLIENT_ID_SERVER);
01459 if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true;
01460 }
01461
01462 if (_settings_client.network.autoclean_novehicles != 0) {
01463 memset(vehicles_in_company, 0, sizeof(vehicles_in_company));
01464
01465 const Vehicle *v;
01466 FOR_ALL_VEHICLES(v) {
01467 if (!Company::IsValidID(v->owner) || !v->IsPrimaryVehicle()) continue;
01468 vehicles_in_company[v->owner]++;
01469 }
01470 }
01471
01472
01473 FOR_ALL_COMPANIES(c) {
01474
01475 if (c->is_ai) continue;
01476
01477 if (!clients_in_company[c->index]) {
01478
01479 _network_company_states[c->index].months_empty++;
01480
01481
01482 if (_settings_client.network.autoclean_unprotected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_unprotected && StrEmpty(_network_company_states[c->index].password)) {
01483
01484 DoCommandP(0, 2, c->index, CMD_COMPANY_CTRL);
01485 IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no password", c->index + 1);
01486 }
01487
01488 if (_settings_client.network.autoclean_protected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_protected && !StrEmpty(_network_company_states[c->index].password)) {
01489
01490 _network_company_states[c->index].password[0] = '\0';
01491 IConsolePrintF(CC_DEFAULT, "Auto-removed protection from company #%d", c->index + 1);
01492 _network_company_states[c->index].months_empty = 0;
01493 NetworkServerUpdateCompanyPassworded(c->index, false);
01494 }
01495
01496 if (_settings_client.network.autoclean_novehicles != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_novehicles && vehicles_in_company[c->index] == 0) {
01497
01498 DoCommandP(0, 2, c->index, CMD_COMPANY_CTRL);
01499 IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no vehicles", c->index + 1);
01500 }
01501 } else {
01502
01503 _network_company_states[c->index].months_empty = 0;
01504 }
01505 }
01506 }
01507
01508
01509
01510 bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH])
01511 {
01512 bool found_name = false;
01513 uint number = 0;
01514 char original_name[NETWORK_CLIENT_NAME_LENGTH];
01515
01516
01517 ttd_strlcpy(original_name, new_name, NETWORK_CLIENT_NAME_LENGTH);
01518
01519 while (!found_name) {
01520 const NetworkClientInfo *ci;
01521
01522 found_name = true;
01523 FOR_ALL_CLIENT_INFOS(ci) {
01524 if (strcmp(ci->client_name, new_name) == 0) {
01525
01526 found_name = false;
01527 break;
01528 }
01529 }
01530
01531 ci = NetworkFindClientInfoFromClientID(CLIENT_ID_SERVER);
01532 if (ci != NULL) {
01533 if (strcmp(ci->client_name, new_name) == 0) found_name = false;
01534 }
01535
01536 if (!found_name) {
01537
01538
01539
01540 if (number++ > MAX_CLIENTS) break;
01541 snprintf(new_name, NETWORK_CLIENT_NAME_LENGTH, "%s #%d", original_name, number);
01542 }
01543 }
01544
01545 return found_name;
01546 }
01547
01554 bool NetworkServerChangeClientName(ClientID client_id, const char *new_name)
01555 {
01556 NetworkClientInfo *ci;
01557
01558 FOR_ALL_CLIENT_INFOS(ci) {
01559 if (strcmp(ci->client_name, new_name) == 0) return false;
01560 }
01561
01562 ci = NetworkFindClientInfoFromClientID(client_id);
01563 if (ci == NULL) return false;
01564
01565 NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, true, ci->client_name, new_name);
01566
01567 strecpy(ci->client_name, new_name, lastof(ci->client_name));
01568
01569 NetworkUpdateClientInfo(client_id);
01570 return true;
01571 }
01572
01573
01574 void NetworkServer_ReadPackets(NetworkClientSocket *cs)
01575 {
01576 Packet *p;
01577 NetworkRecvStatus res = NETWORK_RECV_STATUS_OKAY;
01578
01579 while (res == NETWORK_RECV_STATUS_OKAY && (p = cs->Recv_Packet()) != NULL) {
01580 byte type = p->Recv_uint8();
01581 if (type < PACKET_END && _network_server_packet[type] != NULL && !cs->HasClientQuit()) {
01582 res = _network_server_packet[type](cs, p);
01583 } else {
01584 cs->CloseConnection();
01585 res = NETWORK_RECV_STATUS_MALFORMED_PACKET;
01586 DEBUG(net, 0, "[server] received invalid packet type %d", type);
01587 }
01588
01589 delete p;
01590 }
01591 }
01592
01593
01594 static void NetworkHandleCommandQueue(NetworkClientSocket *cs)
01595 {
01596 CommandPacket *cp;
01597
01598 while ( (cp = cs->command_queue) != NULL) {
01599 SEND_COMMAND(PACKET_SERVER_COMMAND)(cs, cp);
01600
01601 cs->command_queue = cp->next;
01602 free(cp);
01603 }
01604 }
01605
01606
01607 void NetworkServer_Tick(bool send_frame)
01608 {
01609 NetworkClientSocket *cs;
01610 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
01611 bool send_sync = false;
01612 #endif
01613
01614 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
01615 if (_frame_counter >= _last_sync_frame + _settings_client.network.sync_freq) {
01616 _last_sync_frame = _frame_counter;
01617 send_sync = true;
01618 }
01619 #endif
01620
01621
01622
01623 FOR_ALL_CLIENT_SOCKETS(cs) {
01624
01625 if (cs->status == STATUS_ACTIVE) {
01626
01627 int lag = NetworkCalculateLag(cs) / DAY_TICKS;
01628 if (lag > 0) {
01629 if (lag > 3) {
01630
01631
01632 IConsolePrintF(CC_ERROR,"Client #%d is dropped because the client did not respond for more than 4 game-days", cs->client_id);
01633 NetworkCloseClient(cs, true);
01634 continue;
01635 }
01636
01637
01638 if (cs->lag_test == 0) {
01639 IConsolePrintF(CC_WARNING,"[%d] Client #%d is slow, try increasing *net_frame_freq to a higher value!", _frame_counter, cs->client_id);
01640 cs->lag_test = 1;
01641 }
01642 } else {
01643 cs->lag_test = 0;
01644 }
01645 } else if (cs->status == STATUS_PRE_ACTIVE) {
01646 int lag = NetworkCalculateLag(cs);
01647 if (lag > _settings_client.network.max_join_time) {
01648 IConsolePrintF(CC_ERROR,"Client #%d is dropped because it took longer than %d ticks for him to join", cs->client_id, _settings_client.network.max_join_time);
01649 NetworkCloseClient(cs, true);
01650 }
01651 } else if (cs->status == STATUS_INACTIVE) {
01652 int lag = NetworkCalculateLag(cs);
01653 if (lag > 4 * DAY_TICKS) {
01654 IConsolePrintF(CC_ERROR,"Client #%d is dropped because it took longer than %d ticks to start the joining process", cs->client_id, 4 * DAY_TICKS);
01655 NetworkCloseClient(cs, true);
01656 }
01657 }
01658
01659 if (cs->status >= STATUS_PRE_ACTIVE) {
01660
01661 NetworkHandleCommandQueue(cs);
01662
01663
01664 if (send_frame) SEND_COMMAND(PACKET_SERVER_FRAME)(cs);
01665
01666 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
01667
01668 if (send_sync) SEND_COMMAND(PACKET_SERVER_SYNC)(cs);
01669 #endif
01670 }
01671 }
01672
01673
01674 NetworkUDPAdvertise();
01675 }
01676
01677 void NetworkServerYearlyLoop()
01678 {
01679 NetworkCheckRestartMap();
01680 }
01681
01682 void NetworkServerMonthlyLoop()
01683 {
01684 NetworkAutoCleanCompanies();
01685 }
01686
01687 void NetworkServerChangeOwner(Owner current_owner, Owner new_owner)
01688 {
01689
01690
01691 NetworkClientInfo *ci = NetworkFindClientInfoFromClientID(CLIENT_ID_SERVER);
01692
01693
01694 if (current_owner == ci->client_playas) {
01695 ci->client_playas = new_owner;
01696 NetworkUpdateClientInfo(CLIENT_ID_SERVER);
01697 }
01698
01699
01700 FOR_ALL_CLIENT_INFOS(ci) {
01701 if (current_owner == ci->client_playas) {
01702 ci->client_playas = new_owner;
01703 NetworkUpdateClientInfo(ci->client_id);
01704 }
01705 }
01706 }
01707
01708 const char *GetClientIP(NetworkClientInfo *ci)
01709 {
01710 return ci->client_address.GetHostname();
01711 }
01712
01713 void NetworkServerShowStatusToConsole()
01714 {
01715 static const char * const stat_str[] = {
01716 "inactive",
01717 "authorizing",
01718 "authorized",
01719 "waiting",
01720 "loading map",
01721 "map done",
01722 "ready",
01723 "active"
01724 };
01725
01726 NetworkClientSocket *cs;
01727 FOR_ALL_CLIENT_SOCKETS(cs) {
01728 int lag = NetworkCalculateLag(cs);
01729 NetworkClientInfo *ci = cs->GetInfo();
01730 const char *status;
01731
01732 status = (cs->status < (ptrdiff_t)lengthof(stat_str) ? stat_str[cs->status] : "unknown");
01733 IConsolePrintF(CC_INFO, "Client #%1d name: '%s' status: '%s' frame-lag: %3d company: %1d IP: %s",
01734 cs->client_id, ci->client_name, status, lag,
01735 ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0),
01736 GetClientIP(ci));
01737 }
01738 }
01739
01743 void NetworkServerSendConfigUpdate()
01744 {
01745 NetworkClientSocket *cs;
01746
01747 FOR_ALL_CLIENT_SOCKETS(cs) {
01748 SEND_COMMAND(PACKET_SERVER_CONFIG_UPDATE)(cs);
01749 }
01750 }
01751
01752 void NetworkServerUpdateCompanyPassworded(CompanyID company_id, bool passworded)
01753 {
01754 if (NetworkCompanyIsPassworded(company_id) == passworded) return;
01755
01756 SB(_network_company_passworded, company_id, 1, !!passworded);
01757 SetWindowClassesDirty(WC_COMPANY);
01758
01759 NetworkClientSocket *cs;
01760 FOR_ALL_CLIENT_SOCKETS(cs) {
01761 SEND_COMMAND(PACKET_SERVER_COMPANY_UPDATE)(cs);
01762 }
01763 }
01764
01771 void NetworkServerDoMove(ClientID client_id, CompanyID company_id)
01772 {
01773
01774 if (client_id == CLIENT_ID_SERVER && _network_dedicated) return;
01775
01776 NetworkClientInfo *ci = NetworkFindClientInfoFromClientID(client_id);
01777
01778
01779 if (ci->client_playas == company_id) return;
01780
01781 ci->client_playas = company_id;
01782
01783 if (client_id == CLIENT_ID_SERVER) {
01784 SetLocalCompany(company_id);
01785 } else {
01786 SEND_COMMAND(PACKET_SERVER_MOVE)(NetworkFindClientStateFromClientID(client_id), client_id, company_id);
01787 }
01788
01789
01790 NetworkUpdateClientInfo(client_id);
01791
01792 NetworkAction action = (company_id == COMPANY_SPECTATOR) ? NETWORK_ACTION_COMPANY_SPECTATOR : NETWORK_ACTION_COMPANY_JOIN;
01793 NetworkServerSendChat(action, DESTTYPE_BROADCAST, 0, "", client_id, company_id + 1);
01794 }
01795
01796 void NetworkServerSendRcon(ClientID client_id, ConsoleColour colour_code, const char *string)
01797 {
01798 SEND_COMMAND(PACKET_SERVER_RCON)(NetworkFindClientStateFromClientID(client_id), colour_code, string);
01799 }
01800
01801 void NetworkServerSendError(ClientID client_id, NetworkErrorCode error)
01802 {
01803 SEND_COMMAND(PACKET_SERVER_ERROR)(NetworkFindClientStateFromClientID(client_id), error);
01804 }
01805
01806 void NetworkServerKickClient(ClientID client_id)
01807 {
01808 if (client_id == CLIENT_ID_SERVER) return;
01809 NetworkServerSendError(client_id, NETWORK_ERROR_KICKED);
01810 }
01811
01812 void NetworkServerBanIP(const char *banip)
01813 {
01814 NetworkClientInfo *ci;
01815
01816
01817 FOR_ALL_CLIENT_INFOS(ci) {
01818 if (ci->client_address.IsInNetmask(const_cast<char *>(banip))) {
01819 NetworkServerKickClient(ci->client_id);
01820 }
01821 }
01822
01823
01824 *_network_ban_list.Append() = strdup(banip);
01825 }
01826
01827 bool NetworkCompanyHasClients(CompanyID company)
01828 {
01829 const NetworkClientInfo *ci;
01830 FOR_ALL_CLIENT_INFOS(ci) {
01831 if (ci->client_playas == company) return true;
01832 }
01833 return false;
01834 }
01835
01836 #endif