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 char unique_id[NETWORK_UNIQUE_ID_LENGTH];
00662 NetworkClientInfo *ci;
00663 CompanyID playas;
00664 NetworkLanguage client_lang;
00665 char client_revision[NETWORK_REVISION_LENGTH];
00666
00667 p->Recv_string(client_revision, sizeof(client_revision));
00668
00669
00670 if (!IsNetworkCompatibleVersion(client_revision)) {
00671
00672 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_REVISION);
00673 return NETWORK_RECV_STATUS_OKAY;
00674 }
00675
00676 p->Recv_string(name, sizeof(name));
00677 playas = (Owner)p->Recv_uint8();
00678 client_lang = (NetworkLanguage)p->Recv_uint8();
00679 p->Recv_string(unique_id, sizeof(unique_id));
00680
00681 if (cs->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
00682
00683
00684 switch (playas) {
00685 case COMPANY_NEW_COMPANY:
00686 if (Company::GetNumItems() >= _settings_client.network.max_companies) {
00687 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_FULL);
00688 return NETWORK_RECV_STATUS_OKAY;
00689 }
00690 break;
00691 case COMPANY_SPECTATOR:
00692 if (NetworkSpectatorCount() >= _settings_client.network.max_spectators) {
00693 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_FULL);
00694 return NETWORK_RECV_STATUS_OKAY;
00695 }
00696 break;
00697 default:
00698 if (!Company::IsValidHumanID(playas)) {
00699 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_COMPANY_MISMATCH);
00700 return NETWORK_RECV_STATUS_OKAY;
00701 }
00702 break;
00703 }
00704
00705
00706 if (StrEmpty(name)) strecpy(name, "Player", lastof(name));
00707
00708 if (!NetworkFindName(name)) {
00709
00710 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NAME_IN_USE);
00711 return NETWORK_RECV_STATUS_OKAY;
00712 }
00713
00714 ci = cs->GetInfo();
00715
00716 strecpy(ci->client_name, name, lastof(ci->client_name));
00717 strecpy(ci->unique_id, unique_id, lastof(ci->unique_id));
00718 ci->client_playas = playas;
00719 ci->client_lang = client_lang;
00720
00721
00722 if (Company::IsValidID(playas)) _network_company_states[playas].months_empty = 0;
00723
00724 if (_grfconfig == NULL) {
00725 RECEIVE_COMMAND(PACKET_CLIENT_NEWGRFS_CHECKED)(cs, NULL);
00726 } else {
00727 SEND_COMMAND(PACKET_SERVER_CHECK_NEWGRFS)(cs);
00728 }
00729 return NETWORK_RECV_STATUS_OKAY;
00730 }
00731
00732 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD)
00733 {
00734 NetworkPasswordType type;
00735 char password[NETWORK_PASSWORD_LENGTH];
00736 const NetworkClientInfo *ci;
00737
00738 type = (NetworkPasswordType)p->Recv_uint8();
00739 p->Recv_string(password, sizeof(password));
00740
00741 if (cs->status == STATUS_AUTHORIZING && type == NETWORK_GAME_PASSWORD) {
00742
00743 if (strcmp(password, _settings_client.network.server_password) != 0) {
00744
00745 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD);
00746 return NETWORK_RECV_STATUS_OKAY;
00747 }
00748
00749 ci = cs->GetInfo();
00750
00751 if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) {
00752 SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD);
00753 return NETWORK_RECV_STATUS_OKAY;
00754 }
00755
00756
00757 SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
00758 return NETWORK_RECV_STATUS_OKAY;
00759 } else if (cs->status == STATUS_AUTHORIZING && type == NETWORK_COMPANY_PASSWORD) {
00760 ci = cs->GetInfo();
00761
00762 if (strcmp(password, _network_company_states[ci->client_playas].password) != 0) {
00763
00764 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD);
00765 return NETWORK_RECV_STATUS_OKAY;
00766 }
00767
00768 SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
00769 return NETWORK_RECV_STATUS_OKAY;
00770 }
00771
00772
00773 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
00774 return NETWORK_RECV_STATUS_OKAY;
00775 }
00776
00777 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_GETMAP)
00778 {
00779 NetworkClientSocket *new_cs;
00780
00781
00782
00783
00784
00785
00786
00787
00788 if (HasBit(_openttd_newgrf_version, 19)) {
00789 if (_openttd_newgrf_version != p->Recv_uint32()) {
00790
00791
00792 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
00793 return NETWORK_RECV_STATUS_OKAY;
00794 }
00795 } else if (p->size != 3) {
00796
00797
00798 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
00799 return NETWORK_RECV_STATUS_OKAY;
00800 }
00801
00802
00803
00804 if (cs->status < STATUS_AUTH || cs->HasClientQuit()) {
00805 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED);
00806 return NETWORK_RECV_STATUS_OKAY;
00807 }
00808
00809
00810 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00811 if (new_cs->status == STATUS_MAP) {
00812
00813 cs->status = STATUS_MAP_WAIT;
00814 SEND_COMMAND(PACKET_SERVER_WAIT)(cs);
00815 return NETWORK_RECV_STATUS_OKAY;
00816 }
00817 }
00818
00819
00820 SEND_COMMAND(PACKET_SERVER_MAP)(cs);
00821 return NETWORK_RECV_STATUS_OKAY;
00822 }
00823
00824 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK)
00825 {
00826
00827 if (cs->status == STATUS_DONE_MAP && !cs->HasClientQuit()) {
00828 char client_name[NETWORK_CLIENT_NAME_LENGTH];
00829 NetworkClientSocket *new_cs;
00830
00831 NetworkGetClientName(client_name, sizeof(client_name), cs);
00832
00833 NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, client_name, NULL, cs->client_id);
00834
00835
00836
00837 cs->status = STATUS_PRE_ACTIVE;
00838 NetworkHandleCommandQueue(cs);
00839 SEND_COMMAND(PACKET_SERVER_FRAME)(cs);
00840 SEND_COMMAND(PACKET_SERVER_SYNC)(cs);
00841
00842
00843
00844 cs->last_frame = _frame_counter;
00845 cs->last_frame_server = _frame_counter;
00846
00847 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00848 if (new_cs->status > STATUS_AUTH) {
00849 SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(new_cs, cs->GetInfo());
00850 SEND_COMMAND(PACKET_SERVER_JOIN)(new_cs, cs->client_id);
00851 }
00852 }
00853
00854
00855 SEND_COMMAND(PACKET_SERVER_CONFIG_UPDATE)(cs);
00856
00857
00858 SEND_COMMAND(PACKET_SERVER_COMPANY_UPDATE)(cs);
00859 } else {
00860
00861 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
00862 }
00863 return NETWORK_RECV_STATUS_OKAY;
00864 }
00865
00870 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
00871 {
00872 NetworkClientSocket *new_cs;
00873
00874
00875
00876 if (cs->status < STATUS_DONE_MAP || cs->HasClientQuit()) {
00877 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
00878 return NETWORK_RECV_STATUS_OKAY;
00879 }
00880
00881 CommandPacket cp;
00882 const char *err = cs->Recv_Command(p, &cp);
00883
00884 if (cs->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
00885
00886 NetworkClientInfo *ci = cs->GetInfo();
00887
00888 if (err != NULL) {
00889 IConsolePrintF(CC_ERROR, "WARNING: %s from client %d (IP: %s).", err, ci->client_id, GetClientIP(ci));
00890 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
00891 return NETWORK_RECV_STATUS_OKAY;
00892 }
00893
00894
00895 if ((GetCommandFlags(cp.cmd) & CMD_SERVER) && ci->client_id != CLIENT_ID_SERVER) {
00896 IConsolePrintF(CC_ERROR, "WARNING: server only command from: client %d (IP: %s), kicking...", ci->client_id, GetClientIP(ci));
00897 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_KICKED);
00898 return NETWORK_RECV_STATUS_OKAY;
00899 }
00900
00901 if ((GetCommandFlags(cp.cmd) & CMD_SPECTATOR) == 0 && !Company::IsValidID(cp.company) && ci->client_id != CLIENT_ID_SERVER) {
00902 IConsolePrintF(CC_ERROR, "WARNING: spectator issueing command from client %d (IP: %s), kicking...", ci->client_id, GetClientIP(ci));
00903 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_KICKED);
00904 return NETWORK_RECV_STATUS_OKAY;
00905 }
00906
00911 if (!(cp.cmd == CMD_COMPANY_CTRL && cp.p1 == 0 && ci->client_playas == COMPANY_NEW_COMPANY) && ci->client_playas != cp.company) {
00912 IConsolePrintF(CC_ERROR, "WARNING: client %d (IP: %s) tried to execute a command as company %d, kicking...",
00913 ci->client_playas + 1, GetClientIP(ci), cp.company + 1);
00914 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_COMPANY_MISMATCH);
00915 return NETWORK_RECV_STATUS_OKAY;
00916 }
00917
00923 if (cp.cmd == CMD_COMPANY_CTRL) {
00924 if (cp.p1 != 0 || cp.company != COMPANY_SPECTATOR) {
00925 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_CHEATER);
00926 return NETWORK_RECV_STATUS_OKAY;
00927 }
00928
00929
00930 if (Company::GetNumItems() >= _settings_client.network.max_companies) {
00931 NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_CLIENT, ci->client_id, "cannot create new company, server full", CLIENT_ID_SERVER);
00932 return NETWORK_RECV_STATUS_OKAY;
00933 }
00934
00935 cp.p2 = cs->client_id;
00936 }
00937
00938
00939
00940 cp.frame = _frame_counter_max + 1;
00941 cp.next = NULL;
00942
00943 CommandCallback *callback = cp.callback;
00944
00945
00946
00947 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00948 if (new_cs->status >= STATUS_MAP) {
00949
00950
00951 cp.callback = (new_cs != cs) ? NULL : callback;
00952 cp.my_cmd = (new_cs == cs);
00953 NetworkAddCommandQueue(cp, new_cs);
00954 }
00955 }
00956
00957 cp.callback = NULL;
00958 cp.my_cmd = false;
00959 NetworkAddCommandQueue(cp);
00960 return NETWORK_RECV_STATUS_OKAY;
00961 }
00962
00963 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ERROR)
00964 {
00965
00966
00967 NetworkClientSocket *new_cs;
00968 char str[100];
00969 char client_name[NETWORK_CLIENT_NAME_LENGTH];
00970 NetworkErrorCode errorno = (NetworkErrorCode)p->Recv_uint8();
00971
00972
00973 if (cs->status < STATUS_DONE_MAP || cs->HasClientQuit()) {
00974 cs->CloseConnection();
00975 return NETWORK_RECV_STATUS_CONN_LOST;
00976 }
00977
00978 NetworkGetClientName(client_name, sizeof(client_name), cs);
00979
00980 StringID strid = GetNetworkErrorMsg(errorno);
00981 GetString(str, strid, lastof(str));
00982
00983 DEBUG(net, 2, "'%s' reported an error and is closing its connection (%s)", client_name, str);
00984
00985 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, strid);
00986
00987 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00988 if (new_cs->status > STATUS_AUTH) {
00989 SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->client_id, errorno);
00990 }
00991 }
00992
00993 cs->CloseConnection(false);
00994 return NETWORK_RECV_STATUS_CONN_LOST;
00995 }
00996
00997 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_QUIT)
00998 {
00999
01000
01001 NetworkClientSocket *new_cs;
01002 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01003
01004
01005 if (cs->status < STATUS_DONE_MAP || cs->HasClientQuit()) {
01006 cs->CloseConnection();
01007 return NETWORK_RECV_STATUS_CONN_LOST;
01008 }
01009
01010 NetworkGetClientName(client_name, sizeof(client_name), cs);
01011
01012 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, STR_NETWORK_MESSAGE_CLIENT_LEAVING);
01013
01014 FOR_ALL_CLIENT_SOCKETS(new_cs) {
01015 if (new_cs->status > STATUS_AUTH) {
01016 SEND_COMMAND(PACKET_SERVER_QUIT)(new_cs, cs->client_id);
01017 }
01018 }
01019
01020 cs->CloseConnection(false);
01021 return NETWORK_RECV_STATUS_CONN_LOST;
01022 }
01023
01024 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ACK)
01025 {
01026 if (cs->status < STATUS_AUTH) {
01027
01028 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED);
01029 return NETWORK_RECV_STATUS_OKAY;
01030 }
01031
01032 uint32 frame = p->Recv_uint32();
01033
01034
01035 if (cs->status == STATUS_PRE_ACTIVE) {
01036
01037 if (frame + DAY_TICKS < _frame_counter) return NETWORK_RECV_STATUS_OKAY;
01038
01039
01040 cs->status = STATUS_ACTIVE;
01041
01042
01043 IConsoleCmdExec("exec scripts/on_server_connect.scr 0");
01044 }
01045
01046
01047 cs->last_frame = frame;
01048
01049 cs->last_frame_server = _frame_counter;
01050 return NETWORK_RECV_STATUS_OKAY;
01051 }
01052
01053
01054
01055 void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, const char *msg, ClientID from_id, int64 data)
01056 {
01057 NetworkClientSocket *cs;
01058 const NetworkClientInfo *ci, *ci_own, *ci_to;
01059
01060 switch (desttype) {
01061 case DESTTYPE_CLIENT:
01062
01063 if ((ClientID)dest == CLIENT_ID_SERVER) {
01064 ci = NetworkFindClientInfoFromClientID(from_id);
01065
01066 if (ci != NULL)
01067 NetworkTextMessage(action, (ConsoleColour)GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
01068 } else {
01069
01070 FOR_ALL_CLIENT_SOCKETS(cs) {
01071 if (cs->client_id == (ClientID)dest) {
01072 SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_id, false, msg, data);
01073 break;
01074 }
01075 }
01076 }
01077
01078
01079 if (from_id != (ClientID)dest) {
01080 if (from_id == CLIENT_ID_SERVER) {
01081 ci = NetworkFindClientInfoFromClientID(from_id);
01082 ci_to = NetworkFindClientInfoFromClientID((ClientID)dest);
01083 if (ci != NULL && ci_to != NULL)
01084 NetworkTextMessage(action, (ConsoleColour)GetDrawStringCompanyColour(ci->client_playas), true, ci_to->client_name, msg, data);
01085 } else {
01086 FOR_ALL_CLIENT_SOCKETS(cs) {
01087 if (cs->client_id == from_id) {
01088 SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, (ClientID)dest, true, msg, data);
01089 break;
01090 }
01091 }
01092 }
01093 }
01094 break;
01095 case DESTTYPE_TEAM: {
01096 bool show_local = true;
01097
01098
01099 ci_to = NULL;
01100 FOR_ALL_CLIENT_SOCKETS(cs) {
01101 ci = cs->GetInfo();
01102 if (ci->client_playas == (CompanyID)dest) {
01103 SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_id, false, msg, data);
01104 if (cs->client_id == from_id) show_local = false;
01105 ci_to = ci;
01106 }
01107 }
01108
01109 ci = NetworkFindClientInfoFromClientID(from_id);
01110 ci_own = NetworkFindClientInfoFromClientID(CLIENT_ID_SERVER);
01111 if (ci != NULL && ci_own != NULL && ci_own->client_playas == dest) {
01112 NetworkTextMessage(action, (ConsoleColour)GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
01113 if (from_id == CLIENT_ID_SERVER) show_local = false;
01114 ci_to = ci_own;
01115 }
01116
01117
01118 if (ci_to == NULL) break;
01119
01120
01121 if (ci != NULL && show_local) {
01122 if (from_id == CLIENT_ID_SERVER) {
01123 char name[NETWORK_NAME_LENGTH];
01124 StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;
01125 SetDParam(0, ci_to->client_playas);
01126 GetString(name, str, lastof(name));
01127 NetworkTextMessage(action, (ConsoleColour)GetDrawStringCompanyColour(ci_own->client_playas), true, name, msg, data);
01128 } else {
01129 FOR_ALL_CLIENT_SOCKETS(cs) {
01130 if (cs->client_id == from_id) {
01131 SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, ci_to->client_id, true, msg, data);
01132 }
01133 }
01134 }
01135 }
01136 }
01137 break;
01138 default:
01139 DEBUG(net, 0, "[server] received unknown chat destination type %d. Doing broadcast instead", desttype);
01140
01141 case DESTTYPE_BROADCAST:
01142 FOR_ALL_CLIENT_SOCKETS(cs) {
01143 SEND_COMMAND(PACKET_SERVER_CHAT)(cs, action, from_id, false, msg, data);
01144 }
01145 ci = NetworkFindClientInfoFromClientID(from_id);
01146 if (ci != NULL)
01147 NetworkTextMessage(action, (ConsoleColour)GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
01148 break;
01149 }
01150 }
01151
01152 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_CHAT)
01153 {
01154 if (cs->status < STATUS_AUTH) {
01155
01156 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED);
01157 return NETWORK_RECV_STATUS_OKAY;
01158 }
01159
01160 NetworkAction action = (NetworkAction)p->Recv_uint8();
01161 DestType desttype = (DestType)p->Recv_uint8();
01162 int dest = p->Recv_uint32();
01163 char msg[NETWORK_CHAT_LENGTH];
01164
01165 p->Recv_string(msg, NETWORK_CHAT_LENGTH);
01166 int64 data = p->Recv_uint64();
01167
01168 NetworkClientInfo *ci = cs->GetInfo();
01169 switch (action) {
01170 case NETWORK_ACTION_GIVE_MONEY:
01171 if (!Company::IsValidID(ci->client_playas)) break;
01172
01173 case NETWORK_ACTION_CHAT:
01174 case NETWORK_ACTION_CHAT_CLIENT:
01175 case NETWORK_ACTION_CHAT_COMPANY:
01176 NetworkServerSendChat(action, desttype, dest, msg, cs->client_id, data);
01177 break;
01178 default:
01179 IConsolePrintF(CC_ERROR, "WARNING: invalid chat action from client %d (IP: %s).", ci->client_id, GetClientIP(ci));
01180 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
01181 break;
01182 }
01183 return NETWORK_RECV_STATUS_OKAY;
01184 }
01185
01186 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_SET_PASSWORD)
01187 {
01188 if (cs->status != STATUS_ACTIVE) {
01189
01190 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
01191 return NETWORK_RECV_STATUS_OKAY;
01192 }
01193
01194 char password[NETWORK_PASSWORD_LENGTH];
01195 const NetworkClientInfo *ci;
01196
01197 p->Recv_string(password, sizeof(password));
01198 ci = cs->GetInfo();
01199
01200 if (Company::IsValidID(ci->client_playas)) {
01201 strecpy(_network_company_states[ci->client_playas].password, password, lastof(_network_company_states[ci->client_playas].password));
01202 NetworkServerUpdateCompanyPassworded(ci->client_playas, !StrEmpty(_network_company_states[ci->client_playas].password));
01203 }
01204 return NETWORK_RECV_STATUS_OKAY;
01205 }
01206
01207 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_SET_NAME)
01208 {
01209 if (cs->status != STATUS_ACTIVE) {
01210
01211 SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
01212 return NETWORK_RECV_STATUS_OKAY;
01213 }
01214
01215 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01216 NetworkClientInfo *ci;
01217
01218 p->Recv_string(client_name, sizeof(client_name));
01219 ci = cs->GetInfo();
01220
01221 if (cs->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
01222
01223 if (ci != NULL) {
01224
01225 if (NetworkFindName(client_name)) {
01226 NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, client_name);
01227 strecpy(ci->client_name, client_name, lastof(ci->client_name));
01228 NetworkUpdateClientInfo(ci->client_id);
01229 }
01230 }
01231 return NETWORK_RECV_STATUS_OKAY;
01232 }
01233
01234 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_RCON)
01235 {
01236 char pass[NETWORK_PASSWORD_LENGTH];
01237 char command[NETWORK_RCONCOMMAND_LENGTH];
01238
01239 if (StrEmpty(_settings_client.network.rcon_password)) return NETWORK_RECV_STATUS_OKAY;
01240
01241 p->Recv_string(pass, sizeof(pass));
01242 p->Recv_string(command, sizeof(command));
01243
01244 if (strcmp(pass, _settings_client.network.rcon_password) != 0) {
01245 DEBUG(net, 0, "[rcon] wrong password from client-id %d", cs->client_id);
01246 return NETWORK_RECV_STATUS_OKAY;
01247 }
01248
01249 DEBUG(net, 0, "[rcon] client-id %d executed: '%s'", cs->client_id, command);
01250
01251 _redirect_console_to_client = cs->client_id;
01252 IConsoleCmdExec(command);
01253 _redirect_console_to_client = INVALID_CLIENT_ID;
01254 return NETWORK_RECV_STATUS_OKAY;
01255 }
01256
01257 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_MOVE)
01258 {
01259 CompanyID company_id = (Owner)p->Recv_uint8();
01260
01261
01262 if (company_id != COMPANY_SPECTATOR && !Company::IsValidHumanID(company_id)) return NETWORK_RECV_STATUS_OKAY;
01263
01264
01265 if (company_id != COMPANY_SPECTATOR && !StrEmpty(_network_company_states[company_id].password)) {
01266
01267 char password[NETWORK_PASSWORD_LENGTH];
01268 p->Recv_string(password, sizeof(password));
01269
01270
01271 if (strcmp(password, _network_company_states[company_id].password) != 0) {
01272 DEBUG(net, 2, "[move] wrong password from client-id #%d for company #%d", cs->client_id, company_id + 1);
01273 return NETWORK_RECV_STATUS_OKAY;
01274 }
01275 }
01276
01277
01278 NetworkServerDoMove(cs->client_id, company_id);
01279 return NETWORK_RECV_STATUS_OKAY;
01280 }
01281
01282
01283 typedef NetworkRecvStatus NetworkServerPacket(NetworkClientSocket *cs, Packet *p);
01284
01285
01286
01287
01288
01289
01290 static NetworkServerPacket * const _network_server_packet[] = {
01291 NULL,
01292 NULL,
01293 RECEIVE_COMMAND(PACKET_CLIENT_JOIN),
01294 NULL,
01295 RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_INFO),
01296 NULL,
01297 NULL,
01298 NULL,
01299 RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD),
01300 NULL,
01301 RECEIVE_COMMAND(PACKET_CLIENT_GETMAP),
01302 NULL,
01303 NULL,
01304 RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK),
01305 NULL,
01306 NULL,
01307 NULL,
01308 RECEIVE_COMMAND(PACKET_CLIENT_ACK),
01309 RECEIVE_COMMAND(PACKET_CLIENT_COMMAND),
01310 NULL,
01311 RECEIVE_COMMAND(PACKET_CLIENT_CHAT),
01312 NULL,
01313 RECEIVE_COMMAND(PACKET_CLIENT_SET_PASSWORD),
01314 RECEIVE_COMMAND(PACKET_CLIENT_SET_NAME),
01315 RECEIVE_COMMAND(PACKET_CLIENT_QUIT),
01316 RECEIVE_COMMAND(PACKET_CLIENT_ERROR),
01317 NULL,
01318 NULL,
01319 NULL,
01320 NULL,
01321 NULL,
01322 RECEIVE_COMMAND(PACKET_CLIENT_RCON),
01323 NULL,
01324 RECEIVE_COMMAND(PACKET_CLIENT_NEWGRFS_CHECKED),
01325 NULL,
01326 RECEIVE_COMMAND(PACKET_CLIENT_MOVE),
01327 NULL,
01328 NULL,
01329 };
01330
01331
01332 assert_compile(lengthof(_network_server_packet) == PACKET_END);
01333
01334 void NetworkSocketHandler::Send_CompanyInformation(Packet *p, const Company *c, const NetworkCompanyStats *stats)
01335 {
01336
01337 char company_name[NETWORK_COMPANY_NAME_LENGTH];
01338 SetDParam(0, c->index);
01339 GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
01340
01341
01342 Money income = 0;
01343 if (_cur_year - 1 == c->inaugurated_year) {
01344
01345 for (uint i = 0; i < lengthof(c->yearly_expenses[2]); i++) {
01346 income -= c->yearly_expenses[2][i];
01347 }
01348 } else {
01349 for (uint i = 0; i < lengthof(c->yearly_expenses[1]); i++) {
01350 income -= c->yearly_expenses[1][i];
01351 }
01352 }
01353
01354
01355 p->Send_uint8 (c->index);
01356 p->Send_string(company_name);
01357 p->Send_uint32(c->inaugurated_year);
01358 p->Send_uint64(c->old_economy[0].company_value);
01359 p->Send_uint64(c->money);
01360 p->Send_uint64(income);
01361 p->Send_uint16(c->old_economy[0].performance_history);
01362
01363
01364 p->Send_bool (!StrEmpty(_network_company_states[c->index].password));
01365
01366 for (int i = 0; i < NETWORK_VEHICLE_TYPES; i++) {
01367 p->Send_uint16(stats->num_vehicle[i]);
01368 }
01369
01370 for (int i = 0; i < NETWORK_STATION_TYPES; i++) {
01371 p->Send_uint16(stats->num_station[i]);
01372 }
01373
01374 p->Send_bool(c->is_ai);
01375 }
01376
01381 void NetworkPopulateCompanyStats(NetworkCompanyStats *stats)
01382 {
01383 const Vehicle *v;
01384 const Station *s;
01385
01386 memset(stats, 0, sizeof(*stats) * MAX_COMPANIES);
01387
01388
01389 FOR_ALL_VEHICLES(v) {
01390 if (!Company::IsValidID(v->owner) || !v->IsPrimaryVehicle()) continue;
01391 byte type = 0;
01392 switch (v->type) {
01393 case VEH_TRAIN: type = 0; break;
01394 case VEH_ROAD: type = RoadVehicle::From(v)->IsBus() ? 2 : 1; break;
01395 case VEH_AIRCRAFT: type = 3; break;
01396 case VEH_SHIP: type = 4; break;
01397 default: continue;
01398 }
01399 stats[v->owner].num_vehicle[type]++;
01400 }
01401
01402
01403 FOR_ALL_STATIONS(s) {
01404 if (Company::IsValidID(s->owner)) {
01405 NetworkCompanyStats *npi = &stats[s->owner];
01406
01407 if (s->facilities & FACIL_TRAIN) npi->num_station[0]++;
01408 if (s->facilities & FACIL_TRUCK_STOP) npi->num_station[1]++;
01409 if (s->facilities & FACIL_BUS_STOP) npi->num_station[2]++;
01410 if (s->facilities & FACIL_AIRPORT) npi->num_station[3]++;
01411 if (s->facilities & FACIL_DOCK) npi->num_station[4]++;
01412 }
01413 }
01414 }
01415
01416
01417 void NetworkUpdateClientInfo(ClientID client_id)
01418 {
01419 NetworkClientSocket *cs;
01420 NetworkClientInfo *ci = NetworkFindClientInfoFromClientID(client_id);
01421
01422 if (ci == NULL) return;
01423
01424 FOR_ALL_CLIENT_SOCKETS(cs) {
01425 SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(cs, ci);
01426 }
01427 }
01428
01429
01430 static void NetworkCheckRestartMap()
01431 {
01432 if (_settings_client.network.restart_game_year != 0 && _cur_year >= _settings_client.network.restart_game_year) {
01433 DEBUG(net, 0, "Auto-restarting map. Year %d reached", _cur_year);
01434
01435 StartNewGameWithoutGUI(GENERATE_NEW_SEED);
01436 }
01437 }
01438
01439
01440
01441
01442
01443
01444 static void NetworkAutoCleanCompanies()
01445 {
01446 const NetworkClientInfo *ci;
01447 const Company *c;
01448 bool clients_in_company[MAX_COMPANIES];
01449 int vehicles_in_company[MAX_COMPANIES];
01450
01451 if (!_settings_client.network.autoclean_companies) return;
01452
01453 memset(clients_in_company, 0, sizeof(clients_in_company));
01454
01455
01456 FOR_ALL_CLIENT_INFOS(ci) {
01457 if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true;
01458 }
01459
01460 if (!_network_dedicated) {
01461 ci = NetworkFindClientInfoFromClientID(CLIENT_ID_SERVER);
01462 if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true;
01463 }
01464
01465 if (_settings_client.network.autoclean_novehicles != 0) {
01466 memset(vehicles_in_company, 0, sizeof(vehicles_in_company));
01467
01468 const Vehicle *v;
01469 FOR_ALL_VEHICLES(v) {
01470 if (!Company::IsValidID(v->owner) || !v->IsPrimaryVehicle()) continue;
01471 vehicles_in_company[v->owner]++;
01472 }
01473 }
01474
01475
01476 FOR_ALL_COMPANIES(c) {
01477
01478 if (c->is_ai) continue;
01479
01480 if (!clients_in_company[c->index]) {
01481
01482 _network_company_states[c->index].months_empty++;
01483
01484
01485 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)) {
01486
01487 DoCommandP(0, 2, c->index, CMD_COMPANY_CTRL);
01488 IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no password", c->index + 1);
01489 }
01490
01491 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)) {
01492
01493 _network_company_states[c->index].password[0] = '\0';
01494 IConsolePrintF(CC_DEFAULT, "Auto-removed protection from company #%d", c->index + 1);
01495 _network_company_states[c->index].months_empty = 0;
01496 NetworkServerUpdateCompanyPassworded(c->index, false);
01497 }
01498
01499 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) {
01500
01501 DoCommandP(0, 2, c->index, CMD_COMPANY_CTRL);
01502 IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no vehicles", c->index + 1);
01503 }
01504 } else {
01505
01506 _network_company_states[c->index].months_empty = 0;
01507 }
01508 }
01509 }
01510
01511
01512
01513 bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH])
01514 {
01515 bool found_name = false;
01516 uint number = 0;
01517 char original_name[NETWORK_CLIENT_NAME_LENGTH];
01518
01519
01520 ttd_strlcpy(original_name, new_name, NETWORK_CLIENT_NAME_LENGTH);
01521
01522 while (!found_name) {
01523 const NetworkClientInfo *ci;
01524
01525 found_name = true;
01526 FOR_ALL_CLIENT_INFOS(ci) {
01527 if (strcmp(ci->client_name, new_name) == 0) {
01528
01529 found_name = false;
01530 break;
01531 }
01532 }
01533
01534 ci = NetworkFindClientInfoFromClientID(CLIENT_ID_SERVER);
01535 if (ci != NULL) {
01536 if (strcmp(ci->client_name, new_name) == 0) found_name = false;
01537 }
01538
01539 if (!found_name) {
01540
01541
01542
01543 if (number++ > MAX_CLIENTS) break;
01544 snprintf(new_name, NETWORK_CLIENT_NAME_LENGTH, "%s #%d", original_name, number);
01545 }
01546 }
01547
01548 return found_name;
01549 }
01550
01557 bool NetworkServerChangeClientName(ClientID client_id, const char *new_name)
01558 {
01559 NetworkClientInfo *ci;
01560
01561 FOR_ALL_CLIENT_INFOS(ci) {
01562 if (strcmp(ci->client_name, new_name) == 0) return false;
01563 }
01564
01565 ci = NetworkFindClientInfoFromClientID(client_id);
01566 if (ci == NULL) return false;
01567
01568 NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, true, ci->client_name, new_name);
01569
01570 strecpy(ci->client_name, new_name, lastof(ci->client_name));
01571
01572 NetworkUpdateClientInfo(client_id);
01573 return true;
01574 }
01575
01576
01577 void NetworkServer_ReadPackets(NetworkClientSocket *cs)
01578 {
01579 Packet *p;
01580 NetworkRecvStatus res = NETWORK_RECV_STATUS_OKAY;
01581
01582 while (res == NETWORK_RECV_STATUS_OKAY && (p = cs->Recv_Packet()) != NULL) {
01583 byte type = p->Recv_uint8();
01584 if (type < PACKET_END && _network_server_packet[type] != NULL && !cs->HasClientQuit()) {
01585 res = _network_server_packet[type](cs, p);
01586 } else {
01587 cs->CloseConnection();
01588 res = NETWORK_RECV_STATUS_MALFORMED_PACKET;
01589 DEBUG(net, 0, "[server] received invalid packet type %d", type);
01590 }
01591
01592 delete p;
01593 }
01594 }
01595
01596
01597 static void NetworkHandleCommandQueue(NetworkClientSocket *cs)
01598 {
01599 CommandPacket *cp;
01600
01601 while ( (cp = cs->command_queue) != NULL) {
01602 SEND_COMMAND(PACKET_SERVER_COMMAND)(cs, cp);
01603
01604 cs->command_queue = cp->next;
01605 free(cp);
01606 }
01607 }
01608
01609
01610 void NetworkServer_Tick(bool send_frame)
01611 {
01612 NetworkClientSocket *cs;
01613 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
01614 bool send_sync = false;
01615 #endif
01616
01617 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
01618 if (_frame_counter >= _last_sync_frame + _settings_client.network.sync_freq) {
01619 _last_sync_frame = _frame_counter;
01620 send_sync = true;
01621 }
01622 #endif
01623
01624
01625
01626 FOR_ALL_CLIENT_SOCKETS(cs) {
01627
01628 if (cs->status == STATUS_ACTIVE) {
01629
01630 int lag = NetworkCalculateLag(cs) / DAY_TICKS;
01631 if (lag > 0) {
01632 if (lag > 3) {
01633
01634
01635 IConsolePrintF(CC_ERROR,"Client #%d is dropped because the client did not respond for more than 4 game-days", cs->client_id);
01636 NetworkCloseClient(cs, true);
01637 continue;
01638 }
01639
01640
01641 if (cs->lag_test == 0) {
01642 IConsolePrintF(CC_WARNING,"[%d] Client #%d is slow, try increasing *net_frame_freq to a higher value!", _frame_counter, cs->client_id);
01643 cs->lag_test = 1;
01644 }
01645 } else {
01646 cs->lag_test = 0;
01647 }
01648 } else if (cs->status == STATUS_PRE_ACTIVE) {
01649 int lag = NetworkCalculateLag(cs);
01650 if (lag > _settings_client.network.max_join_time) {
01651 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);
01652 NetworkCloseClient(cs, true);
01653 }
01654 } else if (cs->status == STATUS_INACTIVE) {
01655 int lag = NetworkCalculateLag(cs);
01656 if (lag > 4 * DAY_TICKS) {
01657 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);
01658 NetworkCloseClient(cs, true);
01659 }
01660 }
01661
01662 if (cs->status >= STATUS_PRE_ACTIVE) {
01663
01664 NetworkHandleCommandQueue(cs);
01665
01666
01667 if (send_frame) SEND_COMMAND(PACKET_SERVER_FRAME)(cs);
01668
01669 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
01670
01671 if (send_sync) SEND_COMMAND(PACKET_SERVER_SYNC)(cs);
01672 #endif
01673 }
01674 }
01675
01676
01677 NetworkUDPAdvertise();
01678 }
01679
01680 void NetworkServerYearlyLoop()
01681 {
01682 NetworkCheckRestartMap();
01683 }
01684
01685 void NetworkServerMonthlyLoop()
01686 {
01687 NetworkAutoCleanCompanies();
01688 }
01689
01690 void NetworkServerChangeOwner(Owner current_owner, Owner new_owner)
01691 {
01692
01693
01694 NetworkClientInfo *ci = NetworkFindClientInfoFromClientID(CLIENT_ID_SERVER);
01695
01696
01697 if (current_owner == ci->client_playas) {
01698 ci->client_playas = new_owner;
01699 NetworkUpdateClientInfo(CLIENT_ID_SERVER);
01700 }
01701
01702
01703 FOR_ALL_CLIENT_INFOS(ci) {
01704 if (current_owner == ci->client_playas) {
01705 ci->client_playas = new_owner;
01706 NetworkUpdateClientInfo(ci->client_id);
01707 }
01708 }
01709 }
01710
01711 const char *GetClientIP(NetworkClientInfo *ci)
01712 {
01713 return ci->client_address.GetHostname();
01714 }
01715
01716 void NetworkServerShowStatusToConsole()
01717 {
01718 static const char * const stat_str[] = {
01719 "inactive",
01720 "authorizing",
01721 "authorized",
01722 "waiting",
01723 "loading map",
01724 "map done",
01725 "ready",
01726 "active"
01727 };
01728
01729 NetworkClientSocket *cs;
01730 FOR_ALL_CLIENT_SOCKETS(cs) {
01731 int lag = NetworkCalculateLag(cs);
01732 NetworkClientInfo *ci = cs->GetInfo();
01733 const char *status;
01734
01735 status = (cs->status < (ptrdiff_t)lengthof(stat_str) ? stat_str[cs->status] : "unknown");
01736 IConsolePrintF(CC_INFO, "Client #%1d name: '%s' status: '%s' frame-lag: %3d company: %1d IP: %s unique-id: '%s'",
01737 cs->client_id, ci->client_name, status, lag,
01738 ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0),
01739 GetClientIP(ci), ci->unique_id);
01740 }
01741 }
01742
01746 void NetworkServerSendConfigUpdate()
01747 {
01748 NetworkClientSocket *cs;
01749
01750 FOR_ALL_CLIENT_SOCKETS(cs) {
01751 SEND_COMMAND(PACKET_SERVER_CONFIG_UPDATE)(cs);
01752 }
01753 }
01754
01755 void NetworkServerUpdateCompanyPassworded(CompanyID company_id, bool passworded)
01756 {
01757 if (NetworkCompanyIsPassworded(company_id) == passworded) return;
01758
01759 SB(_network_company_passworded, company_id, 1, !!passworded);
01760 SetWindowClassesDirty(WC_COMPANY);
01761
01762 NetworkClientSocket *cs;
01763 FOR_ALL_CLIENT_SOCKETS(cs) {
01764 SEND_COMMAND(PACKET_SERVER_COMPANY_UPDATE)(cs);
01765 }
01766 }
01767
01774 void NetworkServerDoMove(ClientID client_id, CompanyID company_id)
01775 {
01776
01777 if (client_id == CLIENT_ID_SERVER && _network_dedicated) return;
01778
01779 NetworkClientInfo *ci = NetworkFindClientInfoFromClientID(client_id);
01780
01781
01782 if (ci->client_playas == company_id) return;
01783
01784 ci->client_playas = company_id;
01785
01786 if (client_id == CLIENT_ID_SERVER) {
01787 SetLocalCompany(company_id);
01788 } else {
01789 SEND_COMMAND(PACKET_SERVER_MOVE)(NetworkFindClientStateFromClientID(client_id), client_id, company_id);
01790 }
01791
01792
01793 NetworkUpdateClientInfo(client_id);
01794
01795 NetworkAction action = (company_id == COMPANY_SPECTATOR) ? NETWORK_ACTION_COMPANY_SPECTATOR : NETWORK_ACTION_COMPANY_JOIN;
01796 NetworkServerSendChat(action, DESTTYPE_BROADCAST, 0, "", client_id, company_id + 1);
01797 }
01798
01799 void NetworkServerSendRcon(ClientID client_id, ConsoleColour colour_code, const char *string)
01800 {
01801 SEND_COMMAND(PACKET_SERVER_RCON)(NetworkFindClientStateFromClientID(client_id), colour_code, string);
01802 }
01803
01804 void NetworkServerSendError(ClientID client_id, NetworkErrorCode error)
01805 {
01806 SEND_COMMAND(PACKET_SERVER_ERROR)(NetworkFindClientStateFromClientID(client_id), error);
01807 }
01808
01809 void NetworkServerKickClient(ClientID client_id)
01810 {
01811 if (client_id == CLIENT_ID_SERVER) return;
01812 NetworkServerSendError(client_id, NETWORK_ERROR_KICKED);
01813 }
01814
01815 void NetworkServerBanIP(const char *banip)
01816 {
01817 NetworkClientInfo *ci;
01818
01819
01820 FOR_ALL_CLIENT_INFOS(ci) {
01821 if (ci->client_address.IsInNetmask(const_cast<char *>(banip))) {
01822 NetworkServerKickClient(ci->client_id);
01823 }
01824 }
01825
01826
01827 *_network_ban_list.Append() = strdup(banip);
01828 }
01829
01830 bool NetworkCompanyHasClients(CompanyID company)
01831 {
01832 const NetworkClientInfo *ci;
01833 FOR_ALL_CLIENT_INFOS(ci) {
01834 if (ci->client_playas == company) return true;
01835 }
01836 return false;
01837 }
01838
01839 #endif