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