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