00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifdef ENABLE_NETWORK
00013
00014 #include "../stdafx.h"
00015 #include "../strings_func.h"
00016 #include "../date_func.h"
00017 #include "network_admin.h"
00018 #include "network_server.h"
00019 #include "network_udp.h"
00020 #include "network_base.h"
00021 #include "../console_func.h"
00022 #include "../company_base.h"
00023 #include "../command_func.h"
00024 #include "../saveload/saveload.h"
00025 #include "../saveload/saveload_filter.h"
00026 #include "../station_base.h"
00027 #include "../genworld.h"
00028 #include "../company_func.h"
00029 #include "../company_gui.h"
00030 #include "../roadveh.h"
00031 #include "../order_backup.h"
00032 #include "../core/pool_func.hpp"
00033 #include "../core/random_func.hpp"
00034 #include "../rev.h"
00035
00036
00037
00038
00039 DECLARE_POSTFIX_INCREMENT(ClientID)
00041 static ClientID _network_client_id = CLIENT_ID_FIRST;
00042
00044 assert_compile(MAX_CLIENT_SLOTS > MAX_CLIENTS);
00046 assert_compile(NetworkClientSocketPool::MAX_SIZE == MAX_CLIENT_SLOTS);
00047
00049 NetworkClientSocketPool _networkclientsocket_pool("NetworkClientSocket");
00050 INSTANTIATE_POOL_METHODS(NetworkClientSocket)
00051
00053 template SocketList TCPListenHandler<ServerNetworkGameSocketHandler, PACKET_SERVER_FULL, PACKET_SERVER_BANNED>::sockets;
00054
00056 struct PacketWriter : SaveFilter {
00057 ServerNetworkGameSocketHandler *cs;
00058 Packet *current;
00059 size_t total_size;
00060 Packet *packets;
00061 ThreadMutex *mutex;
00062
00067 PacketWriter(ServerNetworkGameSocketHandler *cs) : SaveFilter(NULL), cs(cs), current(NULL), total_size(0), packets(NULL)
00068 {
00069 this->mutex = ThreadMutex::New();
00070 }
00071
00073 ~PacketWriter()
00074 {
00075 if (this->mutex != NULL) this->mutex->BeginCritical();
00076
00077 if (this->cs != NULL && this->mutex != NULL) {
00078 this->mutex->WaitForSignal();
00079 }
00080
00081
00082
00083 while (this->packets != NULL) {
00084 Packet *p = this->packets->next;
00085 delete this->packets;
00086 this->packets = p;
00087 }
00088
00089 delete this->current;
00090
00091 if (this->mutex != NULL) this->mutex->EndCritical();
00092
00093 delete this->mutex;
00094 this->mutex = NULL;
00095 }
00096
00107 void Destroy()
00108 {
00109 if (this->mutex != NULL) this->mutex->BeginCritical();
00110
00111 this->cs = NULL;
00112
00113 if (this->mutex != NULL) this->mutex->SendSignal();
00114
00115 if (this->mutex != NULL) this->mutex->EndCritical();
00116
00117
00118
00119
00120 WaitTillSaved();
00121 ProcessAsyncSaveFinish();
00122 }
00123
00131 bool HasPackets()
00132 {
00133 return this->packets != NULL;
00134 }
00135
00139 Packet *PopPacket()
00140 {
00141 if (this->mutex != NULL) this->mutex->BeginCritical();
00142
00143 Packet *p = this->packets;
00144 this->packets = p->next;
00145 p->next = NULL;
00146
00147 if (this->mutex != NULL) this->mutex->EndCritical();
00148
00149 return p;
00150 }
00151
00153 void AppendQueue()
00154 {
00155 if (this->current == NULL) return;
00156
00157 Packet **p = &this->packets;
00158 while (*p != NULL) {
00159 p = &(*p)->next;
00160 }
00161 *p = this->current;
00162
00163 this->current = NULL;
00164 }
00165
00166 void Write(byte *buf, size_t size)
00167 {
00168
00169 if (this->cs == NULL) SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
00170
00171 if (this->current == NULL) this->current = new Packet(PACKET_SERVER_MAP_DATA);
00172
00173 if (this->mutex != NULL) this->mutex->BeginCritical();
00174
00175 byte *bufe = buf + size;
00176 while (buf != bufe) {
00177 size_t to_write = min(SEND_MTU - this->current->size, bufe - buf);
00178 memcpy(this->current->buffer + this->current->size, buf, to_write);
00179 this->current->size += (PacketSize)to_write;
00180 buf += to_write;
00181
00182 if (this->current->size == SEND_MTU) {
00183 this->AppendQueue();
00184 if (buf != bufe) this->current = new Packet(PACKET_SERVER_MAP_DATA);
00185 }
00186 }
00187
00188 if (this->mutex != NULL) this->mutex->EndCritical();
00189
00190 this->total_size += size;
00191 }
00192
00193 void Finish()
00194 {
00195
00196 if (this->cs == NULL) SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
00197
00198 if (this->mutex != NULL) this->mutex->BeginCritical();
00199
00200
00201 this->AppendQueue();
00202
00203
00204 this->current = new Packet(PACKET_SERVER_MAP_DONE);
00205 this->AppendQueue();
00206
00207
00208 Packet *p = new Packet(PACKET_SERVER_MAP_SIZE);
00209 p->Send_uint32((uint32)this->total_size);
00210 this->cs->NetworkTCPSocketHandler::SendPacket(p);
00211
00212 if (this->mutex != NULL) this->mutex->EndCritical();
00213 }
00214 };
00215
00216
00221 ServerNetworkGameSocketHandler::ServerNetworkGameSocketHandler(SOCKET s) : NetworkGameSocketHandler(s)
00222 {
00223 this->status = STATUS_INACTIVE;
00224 this->client_id = _network_client_id++;
00225 this->receive_limit = _settings_client.network.bytes_per_frame_burst;
00226
00227
00228
00229
00230 assert_compile(NetworkClientSocketPool::MAX_SIZE == NetworkClientInfoPool::MAX_SIZE);
00231 }
00232
00236 ServerNetworkGameSocketHandler::~ServerNetworkGameSocketHandler()
00237 {
00238 if (_redirect_console_to_client == this->client_id) _redirect_console_to_client = INVALID_CLIENT_ID;
00239 OrderBackup::ResetUser(this->client_id);
00240
00241 if (this->savegame != NULL) {
00242 this->savegame->Destroy();
00243 this->savegame = NULL;
00244 }
00245 }
00246
00247 Packet *ServerNetworkGameSocketHandler::ReceivePacket()
00248 {
00249
00250
00251 if (this->receive_limit <= 0) return NULL;
00252
00253
00254
00255 Packet *p = this->NetworkTCPSocketHandler::ReceivePacket();
00256 if (p != NULL) this->receive_limit -= p->size;
00257 return p;
00258 }
00259
00260 NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvStatus status)
00261 {
00262 assert(status != NETWORK_RECV_STATUS_OKAY);
00263
00264
00265
00266
00267
00268
00269
00270 if (this->sock == INVALID_SOCKET) return status;
00271
00272 if (status != NETWORK_RECV_STATUS_CONN_LOST && !this->HasClientQuit() && this->status >= STATUS_AUTHORIZED) {
00273
00274 char client_name[NETWORK_CLIENT_NAME_LENGTH];
00275 NetworkClientSocket *new_cs;
00276
00277 this->GetClientName(client_name, sizeof(client_name));
00278
00279 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST);
00280
00281
00282 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00283 if (new_cs->status > STATUS_AUTHORIZED && this != new_cs) {
00284 new_cs->SendErrorQuit(this->client_id, NETWORK_ERROR_CONNECTION_LOST);
00285 }
00286 }
00287 }
00288
00289 NetworkAdminClientError(this->client_id, NETWORK_ERROR_CONNECTION_LOST);
00290 DEBUG(net, 1, "Closed client connection %d", this->client_id);
00291
00292
00293 if (this->status >= STATUS_AUTHORIZED) _network_game_info.clients_on--;
00294 extern byte _network_clients_connected;
00295 _network_clients_connected--;
00296
00297 DeleteWindowById(WC_CLIENT_LIST_POPUP, this->client_id);
00298 SetWindowDirty(WC_CLIENT_LIST, 0);
00299
00300 this->SendPackets(true);
00301
00302 delete this->GetInfo();
00303 delete this;
00304
00305 return status;
00306 }
00307
00312 bool ServerNetworkGameSocketHandler::AllowConnection()
00313 {
00314 extern byte _network_clients_connected;
00315 bool accept = _network_clients_connected < MAX_CLIENTS && _network_game_info.clients_on < _settings_client.network.max_clients;
00316
00317
00318
00319 assert_compile(NetworkClientSocketPool::MAX_SIZE == MAX_CLIENTS + 1);
00320 assert(!accept || ServerNetworkGameSocketHandler::CanAllocateItem());
00321 return accept;
00322 }
00323
00325 void ServerNetworkGameSocketHandler::Send()
00326 {
00327 NetworkClientSocket *cs;
00328 FOR_ALL_CLIENT_SOCKETS(cs) {
00329 if (cs->writable) {
00330 if (cs->SendPackets() != SPS_CLOSED && cs->status == STATUS_MAP) {
00331
00332 cs->SendMap();
00333 }
00334 }
00335 }
00336 }
00337
00338 static void NetworkHandleCommandQueue(NetworkClientSocket *cs);
00339
00340
00341
00342
00343
00344
00349 NetworkRecvStatus ServerNetworkGameSocketHandler::SendClientInfo(NetworkClientInfo *ci)
00350 {
00351 if (ci->client_id != INVALID_CLIENT_ID) {
00352 Packet *p = new Packet(PACKET_SERVER_CLIENT_INFO);
00353 p->Send_uint32(ci->client_id);
00354 p->Send_uint8 (ci->client_playas);
00355 p->Send_string(ci->client_name);
00356
00357 this->SendPacket(p);
00358 }
00359 return NETWORK_RECV_STATUS_OKAY;
00360 }
00361
00363 NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo()
00364 {
00365
00366 NetworkCompanyStats company_stats[MAX_COMPANIES];
00367 NetworkPopulateCompanyStats(company_stats);
00368
00369
00370 char clients[MAX_COMPANIES][NETWORK_CLIENTS_LENGTH];
00371 NetworkClientSocket *csi;
00372 memset(clients, 0, sizeof(clients));
00373
00374
00375 const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
00376 if (ci != NULL && Company::IsValidID(ci->client_playas)) {
00377 strecpy(clients[ci->client_playas], ci->client_name, lastof(clients[ci->client_playas]));
00378 }
00379
00380 FOR_ALL_CLIENT_SOCKETS(csi) {
00381 char client_name[NETWORK_CLIENT_NAME_LENGTH];
00382
00383 ((ServerNetworkGameSocketHandler*)csi)->GetClientName(client_name, sizeof(client_name));
00384
00385 ci = csi->GetInfo();
00386 if (ci != NULL && Company::IsValidID(ci->client_playas)) {
00387 if (!StrEmpty(clients[ci->client_playas])) {
00388 strecat(clients[ci->client_playas], ", ", lastof(clients[ci->client_playas]));
00389 }
00390
00391 strecat(clients[ci->client_playas], client_name, lastof(clients[ci->client_playas]));
00392 }
00393 }
00394
00395
00396
00397 Company *company;
00398 Packet *p;
00399
00400 FOR_ALL_COMPANIES(company) {
00401 p = new Packet(PACKET_SERVER_COMPANY_INFO);
00402
00403 p->Send_uint8 (NETWORK_COMPANY_INFO_VERSION);
00404 p->Send_bool (true);
00405 this->SendCompanyInformation(p, company, &company_stats[company->index]);
00406
00407 if (StrEmpty(clients[company->index])) {
00408 p->Send_string("<none>");
00409 } else {
00410 p->Send_string(clients[company->index]);
00411 }
00412
00413 this->SendPacket(p);
00414 }
00415
00416 p = new Packet(PACKET_SERVER_COMPANY_INFO);
00417
00418 p->Send_uint8 (NETWORK_COMPANY_INFO_VERSION);
00419 p->Send_bool (false);
00420
00421 this->SendPacket(p);
00422 return NETWORK_RECV_STATUS_OKAY;
00423 }
00424
00429 NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode error)
00430 {
00431 char str[100];
00432 Packet *p = new Packet(PACKET_SERVER_ERROR);
00433
00434 p->Send_uint8(error);
00435 this->SendPacket(p);
00436
00437 StringID strid = GetNetworkErrorMsg(error);
00438 GetString(str, strid, lastof(str));
00439
00440
00441 if (this->status > STATUS_AUTHORIZED) {
00442 NetworkClientSocket *new_cs;
00443 char client_name[NETWORK_CLIENT_NAME_LENGTH];
00444
00445 this->GetClientName(client_name, sizeof(client_name));
00446
00447 DEBUG(net, 1, "'%s' made an error and has been disconnected. Reason: '%s'", client_name, str);
00448
00449 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, strid);
00450
00451 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00452 if (new_cs->status > STATUS_AUTHORIZED && new_cs != this) {
00453
00454
00455 if (error == NETWORK_ERROR_NOT_AUTHORIZED || error == NETWORK_ERROR_NOT_EXPECTED || error == NETWORK_ERROR_WRONG_REVISION) {
00456 error = NETWORK_ERROR_ILLEGAL_PACKET;
00457 }
00458 new_cs->SendErrorQuit(this->client_id, error);
00459 }
00460 }
00461
00462 NetworkAdminClientError(this->client_id, error);
00463 } else {
00464 DEBUG(net, 1, "Client %d made an error and has been disconnected. Reason: '%s'", this->client_id, str);
00465 }
00466
00467
00468 return this->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
00469 }
00470
00472 NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGRFCheck()
00473 {
00474 Packet *p = new Packet(PACKET_SERVER_CHECK_NEWGRFS);
00475 const GRFConfig *c;
00476 uint grf_count = 0;
00477
00478 for (c = _grfconfig; c != NULL; c = c->next) {
00479 if (!HasBit(c->flags, GCF_STATIC)) grf_count++;
00480 }
00481
00482 p->Send_uint8 (grf_count);
00483 for (c = _grfconfig; c != NULL; c = c->next) {
00484 if (!HasBit(c->flags, GCF_STATIC)) this->SendGRFIdentifier(p, &c->ident);
00485 }
00486
00487 this->SendPacket(p);
00488 return NETWORK_RECV_STATUS_OKAY;
00489 }
00490
00492 NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedGamePassword()
00493 {
00494
00495 if (this->status >= STATUS_AUTH_GAME) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
00496
00497 this->status = STATUS_AUTH_GAME;
00498
00499 this->last_frame = this->last_frame_server = _frame_counter;
00500
00501 Packet *p = new Packet(PACKET_SERVER_NEED_GAME_PASSWORD);
00502 this->SendPacket(p);
00503 return NETWORK_RECV_STATUS_OKAY;
00504 }
00505
00507 NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedCompanyPassword()
00508 {
00509
00510 if (this->status >= STATUS_AUTH_COMPANY) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
00511
00512 this->status = STATUS_AUTH_COMPANY;
00513
00514 this->last_frame = this->last_frame_server = _frame_counter;
00515
00516 Packet *p = new Packet(PACKET_SERVER_NEED_COMPANY_PASSWORD);
00517 p->Send_uint32(_settings_game.game_creation.generation_seed);
00518 p->Send_string(_settings_client.network.network_id);
00519 this->SendPacket(p);
00520 return NETWORK_RECV_STATUS_OKAY;
00521 }
00522
00524 NetworkRecvStatus ServerNetworkGameSocketHandler::SendWelcome()
00525 {
00526 Packet *p;
00527 NetworkClientSocket *new_cs;
00528
00529
00530 if (this->status >= STATUS_AUTHORIZED) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
00531
00532 this->status = STATUS_AUTHORIZED;
00533
00534 this->last_frame = this->last_frame_server = _frame_counter;
00535
00536 _network_game_info.clients_on++;
00537
00538 p = new Packet(PACKET_SERVER_WELCOME);
00539 p->Send_uint32(this->client_id);
00540 p->Send_uint32(_settings_game.game_creation.generation_seed);
00541 p->Send_string(_settings_client.network.network_id);
00542 this->SendPacket(p);
00543
00544
00545 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00546 if (new_cs != this && new_cs->status > STATUS_AUTHORIZED) {
00547 this->SendClientInfo(new_cs->GetInfo());
00548 }
00549 }
00550
00551 return this->SendClientInfo(NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER));
00552 }
00553
00555 NetworkRecvStatus ServerNetworkGameSocketHandler::SendWait()
00556 {
00557 int waiting = 0;
00558 NetworkClientSocket *new_cs;
00559 Packet *p;
00560
00561
00562 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00563 if (new_cs->status != STATUS_MAP_WAIT) continue;
00564 if (new_cs->GetInfo()->join_date < this->GetInfo()->join_date || (new_cs->GetInfo()->join_date == this->GetInfo()->join_date && new_cs->client_id < this->client_id)) waiting++;
00565 }
00566
00567 p = new Packet(PACKET_SERVER_WAIT);
00568 p->Send_uint8(waiting);
00569 this->SendPacket(p);
00570 return NETWORK_RECV_STATUS_OKAY;
00571 }
00572
00574 NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
00575 {
00576 static uint sent_packets;
00577
00578 if (this->status < STATUS_AUTHORIZED) {
00579
00580 return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
00581 }
00582
00583 if (this->status == STATUS_AUTHORIZED) {
00584 this->savegame = new PacketWriter(this);
00585
00586
00587 Packet *p = new Packet(PACKET_SERVER_MAP_BEGIN);
00588 p->Send_uint32(_frame_counter);
00589 this->SendPacket(p);
00590
00591 NetworkSyncCommandQueue(this);
00592 this->status = STATUS_MAP;
00593
00594 this->last_frame = _frame_counter;
00595 this->last_frame_server = _frame_counter;
00596
00597 sent_packets = 4;
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608 NetworkClientSocket *cs;
00609 FOR_ALL_CLIENT_SOCKETS(cs) {
00610 OrderBackup::ResetUser(cs->client_id);
00611 }
00612
00613
00614 if (SaveWithFilter(this->savegame, true) != SL_OK) usererror("network savedump failed");
00615 }
00616
00617 if (this->status == STATUS_MAP) {
00618 bool last_packet = false;
00619 bool has_packets = false;
00620
00621 for (uint i = 0; (has_packets = this->savegame->HasPackets()) && i < sent_packets; i++) {
00622 Packet *p = this->savegame->PopPacket();
00623 last_packet = p->buffer[2] == PACKET_SERVER_MAP_DONE;
00624
00625 this->SendPacket(p);
00626
00627 if (last_packet) {
00628
00629 break;
00630 }
00631 }
00632
00633 if (last_packet) {
00634
00635 this->savegame->Destroy();
00636 this->savegame = NULL;
00637
00638
00639
00640 this->status = STATUS_DONE_MAP;
00641
00642
00643 NetworkClientSocket *new_cs;
00644 NetworkClientSocket *best = NULL;
00645 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00646 if (new_cs->status == STATUS_MAP_WAIT) {
00647 if (best == NULL || best->GetInfo()->join_date > new_cs->GetInfo()->join_date || (best->GetInfo()->join_date == new_cs->GetInfo()->join_date && best->client_id > new_cs->client_id)) {
00648 best = new_cs;
00649 }
00650 }
00651 }
00652
00653
00654 if (best != NULL) {
00655
00656 best->status = STATUS_AUTHORIZED;
00657 best->SendMap();
00658
00659
00660 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00661 if (new_cs->status == STATUS_MAP_WAIT) new_cs->SendWait();
00662 }
00663 }
00664 }
00665
00666 switch (this->SendPackets()) {
00667 case SPS_CLOSED:
00668 return NETWORK_RECV_STATUS_CONN_LOST;
00669
00670 case SPS_ALL_SENT:
00671
00672 if (has_packets) sent_packets *= 2;
00673 break;
00674
00675 case SPS_PARTLY_SENT:
00676
00677 break;
00678
00679 case SPS_NONE_SENT:
00680
00681 if (sent_packets > 1) sent_packets /= 2;
00682 break;
00683 }
00684 }
00685 return NETWORK_RECV_STATUS_OKAY;
00686 }
00687
00692 NetworkRecvStatus ServerNetworkGameSocketHandler::SendJoin(ClientID client_id)
00693 {
00694 Packet *p = new Packet(PACKET_SERVER_JOIN);
00695
00696 p->Send_uint32(client_id);
00697
00698 this->SendPacket(p);
00699 return NETWORK_RECV_STATUS_OKAY;
00700 }
00701
00703 NetworkRecvStatus ServerNetworkGameSocketHandler::SendFrame()
00704 {
00705 Packet *p = new Packet(PACKET_SERVER_FRAME);
00706 p->Send_uint32(_frame_counter);
00707 p->Send_uint32(_frame_counter_max);
00708 #ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
00709 p->Send_uint32(_sync_seed_1);
00710 #ifdef NETWORK_SEND_DOUBLE_SEED
00711 p->Send_uint32(_sync_seed_2);
00712 #endif
00713 #endif
00714
00715
00716 if (this->last_token == 0) {
00717 this->last_token = InteractiveRandomRange(UINT8_MAX - 1) + 1;
00718 p->Send_uint8(this->last_token);
00719 }
00720
00721 this->SendPacket(p);
00722 return NETWORK_RECV_STATUS_OKAY;
00723 }
00724
00726 NetworkRecvStatus ServerNetworkGameSocketHandler::SendSync()
00727 {
00728 Packet *p = new Packet(PACKET_SERVER_SYNC);
00729 p->Send_uint32(_frame_counter);
00730 p->Send_uint32(_sync_seed_1);
00731
00732 #ifdef NETWORK_SEND_DOUBLE_SEED
00733 p->Send_uint32(_sync_seed_2);
00734 #endif
00735 this->SendPacket(p);
00736 return NETWORK_RECV_STATUS_OKAY;
00737 }
00738
00743 NetworkRecvStatus ServerNetworkGameSocketHandler::SendCommand(const CommandPacket *cp)
00744 {
00745 Packet *p = new Packet(PACKET_SERVER_COMMAND);
00746
00747 this->NetworkGameSocketHandler::SendCommand(p, cp);
00748 p->Send_uint32(cp->frame);
00749 p->Send_bool (cp->my_cmd);
00750
00751 this->SendPacket(p);
00752 return NETWORK_RECV_STATUS_OKAY;
00753 }
00754
00763 NetworkRecvStatus ServerNetworkGameSocketHandler::SendChat(NetworkAction action, ClientID client_id, bool self_send, const char *msg, int64 data)
00764 {
00765 if (this->status < STATUS_PRE_ACTIVE) return NETWORK_RECV_STATUS_OKAY;
00766
00767 Packet *p = new Packet(PACKET_SERVER_CHAT);
00768
00769 p->Send_uint8 (action);
00770 p->Send_uint32(client_id);
00771 p->Send_bool (self_send);
00772 p->Send_string(msg);
00773 p->Send_uint64(data);
00774
00775 this->SendPacket(p);
00776 return NETWORK_RECV_STATUS_OKAY;
00777 }
00778
00784 NetworkRecvStatus ServerNetworkGameSocketHandler::SendErrorQuit(ClientID client_id, NetworkErrorCode errorno)
00785 {
00786 Packet *p = new Packet(PACKET_SERVER_ERROR_QUIT);
00787
00788 p->Send_uint32(client_id);
00789 p->Send_uint8 (errorno);
00790
00791 this->SendPacket(p);
00792 return NETWORK_RECV_STATUS_OKAY;
00793 }
00794
00799 NetworkRecvStatus ServerNetworkGameSocketHandler::SendQuit(ClientID client_id)
00800 {
00801 Packet *p = new Packet(PACKET_SERVER_QUIT);
00802
00803 p->Send_uint32(client_id);
00804
00805 this->SendPacket(p);
00806 return NETWORK_RECV_STATUS_OKAY;
00807 }
00808
00810 NetworkRecvStatus ServerNetworkGameSocketHandler::SendShutdown()
00811 {
00812 Packet *p = new Packet(PACKET_SERVER_SHUTDOWN);
00813 this->SendPacket(p);
00814 return NETWORK_RECV_STATUS_OKAY;
00815 }
00816
00818 NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGame()
00819 {
00820 Packet *p = new Packet(PACKET_SERVER_NEWGAME);
00821 this->SendPacket(p);
00822 return NETWORK_RECV_STATUS_OKAY;
00823 }
00824
00830 NetworkRecvStatus ServerNetworkGameSocketHandler::SendRConResult(uint16 colour, const char *command)
00831 {
00832 Packet *p = new Packet(PACKET_SERVER_RCON);
00833
00834 p->Send_uint16(colour);
00835 p->Send_string(command);
00836 this->SendPacket(p);
00837 return NETWORK_RECV_STATUS_OKAY;
00838 }
00839
00845 NetworkRecvStatus ServerNetworkGameSocketHandler::SendMove(ClientID client_id, CompanyID company_id)
00846 {
00847 Packet *p = new Packet(PACKET_SERVER_MOVE);
00848
00849 p->Send_uint32(client_id);
00850 p->Send_uint8(company_id);
00851 this->SendPacket(p);
00852 return NETWORK_RECV_STATUS_OKAY;
00853 }
00854
00856 NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyUpdate()
00857 {
00858 Packet *p = new Packet(PACKET_SERVER_COMPANY_UPDATE);
00859
00860 p->Send_uint16(_network_company_passworded);
00861 this->SendPacket(p);
00862 return NETWORK_RECV_STATUS_OKAY;
00863 }
00864
00866 NetworkRecvStatus ServerNetworkGameSocketHandler::SendConfigUpdate()
00867 {
00868 Packet *p = new Packet(PACKET_SERVER_CONFIG_UPDATE);
00869
00870 p->Send_uint8(_settings_client.network.max_companies);
00871 p->Send_uint8(_settings_client.network.max_spectators);
00872 this->SendPacket(p);
00873 return NETWORK_RECV_STATUS_OKAY;
00874 }
00875
00876
00877
00878
00879
00880
00881 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMPANY_INFO(Packet *p)
00882 {
00883 return this->SendCompanyInfo();
00884 }
00885
00886 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_NEWGRFS_CHECKED(Packet *p)
00887 {
00888 if (this->status != STATUS_NEWGRFS_CHECK) {
00889
00890 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00891 }
00892
00893 NetworkClientInfo *ci = this->GetInfo();
00894
00895
00896 if (!StrEmpty(_settings_client.network.server_password)) {
00897 return this->SendNeedGamePassword();
00898 }
00899
00900 if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) {
00901 return this->SendNeedCompanyPassword();
00902 }
00903
00904 return this->SendWelcome();
00905 }
00906
00907 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
00908 {
00909 if (this->status != STATUS_INACTIVE) {
00910
00911 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00912 }
00913
00914 char name[NETWORK_CLIENT_NAME_LENGTH];
00915 CompanyID playas;
00916 NetworkLanguage client_lang;
00917 char client_revision[NETWORK_REVISION_LENGTH];
00918
00919 p->Recv_string(client_revision, sizeof(client_revision));
00920 uint32 newgrf_version = p->Recv_uint32();
00921
00922
00923 if (!IsNetworkCompatibleVersion(client_revision) || _openttd_newgrf_version != newgrf_version) {
00924
00925 return this->SendError(NETWORK_ERROR_WRONG_REVISION);
00926 }
00927
00928 p->Recv_string(name, sizeof(name));
00929 playas = (Owner)p->Recv_uint8();
00930 client_lang = (NetworkLanguage)p->Recv_uint8();
00931
00932 if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
00933
00934
00935 switch (playas) {
00936 case COMPANY_NEW_COMPANY:
00937 if (Company::GetNumItems() >= _settings_client.network.max_companies) {
00938 return this->SendError(NETWORK_ERROR_FULL);
00939 }
00940 break;
00941 case COMPANY_SPECTATOR:
00942 if (NetworkSpectatorCount() >= _settings_client.network.max_spectators) {
00943 return this->SendError(NETWORK_ERROR_FULL);
00944 }
00945 break;
00946 default:
00947 if (!Company::IsValidHumanID(playas)) {
00948 return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH);
00949 }
00950 break;
00951 }
00952
00953
00954 if (StrEmpty(name)) strecpy(name, "Player", lastof(name));
00955
00956 if (!NetworkFindName(name)) {
00957
00958 return this->SendError(NETWORK_ERROR_NAME_IN_USE);
00959 }
00960
00961 assert(NetworkClientInfo::CanAllocateItem());
00962 NetworkClientInfo *ci = new NetworkClientInfo(this->client_id);
00963 this->SetInfo(ci);
00964 ci->join_date = _date;
00965 strecpy(ci->client_name, name, lastof(ci->client_name));
00966 ci->client_playas = playas;
00967 ci->client_lang = client_lang;
00968 DEBUG(desync, 1, "client: %08x; %02x; %02x; %04x", _date, _date_fract, (int)ci->client_playas, ci->index);
00969
00970
00971 if (Company::IsValidID(playas)) _network_company_states[playas].months_empty = 0;
00972
00973 this->status = STATUS_NEWGRFS_CHECK;
00974
00975 if (_grfconfig == NULL) {
00976
00977 return this->Receive_CLIENT_NEWGRFS_CHECKED(NULL);
00978 }
00979
00980 return this->SendNewGRFCheck();
00981 }
00982
00983 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GAME_PASSWORD(Packet *p)
00984 {
00985 if (this->status != STATUS_AUTH_GAME) {
00986 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00987 }
00988
00989 char password[NETWORK_PASSWORD_LENGTH];
00990 p->Recv_string(password, sizeof(password));
00991
00992
00993 if (!StrEmpty(_settings_client.network.server_password) &&
00994 strcmp(password, _settings_client.network.server_password) != 0) {
00995
00996 return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
00997 }
00998
00999 const NetworkClientInfo *ci = this->GetInfo();
01000 if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) {
01001 return this->SendNeedCompanyPassword();
01002 }
01003
01004
01005 return this->SendWelcome();
01006 }
01007
01008 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMPANY_PASSWORD(Packet *p)
01009 {
01010 if (this->status != STATUS_AUTH_COMPANY) {
01011 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01012 }
01013
01014 char password[NETWORK_PASSWORD_LENGTH];
01015 p->Recv_string(password, sizeof(password));
01016
01017
01018
01019
01020 CompanyID playas = this->GetInfo()->client_playas;
01021 if (Company::IsValidID(playas) && !StrEmpty(_network_company_states[playas].password) &&
01022 strcmp(password, _network_company_states[playas].password) != 0) {
01023
01024 return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
01025 }
01026
01027 return this->SendWelcome();
01028 }
01029
01030 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GETMAP(Packet *p)
01031 {
01032 NetworkClientSocket *new_cs;
01033
01034
01035 if (this->status < STATUS_AUTHORIZED || this->HasClientQuit()) {
01036 return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
01037 }
01038
01039
01040 FOR_ALL_CLIENT_SOCKETS(new_cs) {
01041 if (new_cs->status == STATUS_MAP) {
01042
01043 this->status = STATUS_MAP_WAIT;
01044 return this->SendWait();
01045 }
01046 }
01047
01048
01049 return this->SendMap();
01050 }
01051
01052 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MAP_OK(Packet *p)
01053 {
01054
01055 if (this->status == STATUS_DONE_MAP && !this->HasClientQuit()) {
01056 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01057 NetworkClientSocket *new_cs;
01058
01059 this->GetClientName(client_name, sizeof(client_name));
01060
01061 NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, client_name, NULL, this->client_id);
01062
01063
01064
01065 this->status = STATUS_PRE_ACTIVE;
01066 NetworkHandleCommandQueue(this);
01067 this->SendFrame();
01068 this->SendSync();
01069
01070
01071
01072 this->last_frame = _frame_counter;
01073 this->last_frame_server = _frame_counter;
01074
01075 FOR_ALL_CLIENT_SOCKETS(new_cs) {
01076 if (new_cs->status > STATUS_AUTHORIZED) {
01077 new_cs->SendClientInfo(this->GetInfo());
01078 new_cs->SendJoin(this->client_id);
01079 }
01080 }
01081
01082 NetworkAdminClientInfo(this, true);
01083
01084
01085 this->SendConfigUpdate();
01086
01087
01088 return this->SendCompanyUpdate();
01089 }
01090
01091
01092 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01093 }
01094
01099 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet *p)
01100 {
01101
01102
01103 if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
01104 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01105 }
01106
01107 if (this->incoming_queue.Count() >= _settings_client.network.max_commands_in_queue) {
01108 return this->SendError(NETWORK_ERROR_TOO_MANY_COMMANDS);
01109 }
01110
01111 CommandPacket cp;
01112 const char *err = this->ReceiveCommand(p, &cp);
01113
01114 if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
01115
01116 NetworkClientInfo *ci = this->GetInfo();
01117
01118 if (err != NULL) {
01119 IConsolePrintF(CC_ERROR, "WARNING: %s from client %d (IP: %s).", err, ci->client_id, this->GetClientIP());
01120 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01121 }
01122
01123
01124 if ((GetCommandFlags(cp.cmd) & CMD_SERVER) && ci->client_id != CLIENT_ID_SERVER) {
01125 IConsolePrintF(CC_ERROR, "WARNING: server only command from: client %d (IP: %s), kicking...", ci->client_id, this->GetClientIP());
01126 return this->SendError(NETWORK_ERROR_KICKED);
01127 }
01128
01129 if ((GetCommandFlags(cp.cmd) & CMD_SPECTATOR) == 0 && !Company::IsValidID(cp.company) && ci->client_id != CLIENT_ID_SERVER) {
01130 IConsolePrintF(CC_ERROR, "WARNING: spectator issueing command from client %d (IP: %s), kicking...", ci->client_id, this->GetClientIP());
01131 return this->SendError(NETWORK_ERROR_KICKED);
01132 }
01133
01139 if (!(cp.cmd == CMD_COMPANY_CTRL && cp.p1 == 0 && ci->client_playas == COMPANY_NEW_COMPANY) && ci->client_playas != cp.company) {
01140 IConsolePrintF(CC_ERROR, "WARNING: client %d (IP: %s) tried to execute a command as company %d, kicking...",
01141 ci->client_playas + 1, this->GetClientIP(), cp.company + 1);
01142 return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH);
01143 }
01144
01145 if (cp.cmd == CMD_COMPANY_CTRL) {
01146 if (cp.p1 != 0 || cp.company != COMPANY_SPECTATOR) {
01147 return this->SendError(NETWORK_ERROR_CHEATER);
01148 }
01149
01150
01151 if (Company::GetNumItems() >= _settings_client.network.max_companies) {
01152 NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_CLIENT, ci->client_id, "cannot create new company, server full", CLIENT_ID_SERVER);
01153 return NETWORK_RECV_STATUS_OKAY;
01154 }
01155 }
01156
01157 if (GetCommandFlags(cp.cmd) & CMD_CLIENT_ID) cp.p2 = this->client_id;
01158
01159 this->incoming_queue.Append(&cp);
01160 return NETWORK_RECV_STATUS_OKAY;
01161 }
01162
01163 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p)
01164 {
01165
01166
01167 NetworkClientSocket *new_cs;
01168 char str[100];
01169 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01170 NetworkErrorCode errorno = (NetworkErrorCode)p->Recv_uint8();
01171
01172
01173 if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
01174 return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
01175 }
01176
01177 this->GetClientName(client_name, sizeof(client_name));
01178
01179 StringID strid = GetNetworkErrorMsg(errorno);
01180 GetString(str, strid, lastof(str));
01181
01182 DEBUG(net, 2, "'%s' reported an error and is closing its connection (%s)", client_name, str);
01183
01184 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, strid);
01185
01186 FOR_ALL_CLIENT_SOCKETS(new_cs) {
01187 if (new_cs->status > STATUS_AUTHORIZED) {
01188 new_cs->SendErrorQuit(this->client_id, errorno);
01189 }
01190 }
01191
01192 NetworkAdminClientError(this->client_id, errorno);
01193
01194 return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
01195 }
01196
01197 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet *p)
01198 {
01199
01200
01201 NetworkClientSocket *new_cs;
01202 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01203
01204
01205 if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
01206 return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
01207 }
01208
01209 this->GetClientName(client_name, sizeof(client_name));
01210
01211 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, STR_NETWORK_MESSAGE_CLIENT_LEAVING);
01212
01213 FOR_ALL_CLIENT_SOCKETS(new_cs) {
01214 if (new_cs->status > STATUS_AUTHORIZED && new_cs != this) {
01215 new_cs->SendQuit(this->client_id);
01216 }
01217 }
01218
01219 NetworkAdminClientQuit(this->client_id);
01220
01221 return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
01222 }
01223
01224 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ACK(Packet *p)
01225 {
01226 if (this->status < STATUS_AUTHORIZED) {
01227
01228 return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
01229 }
01230
01231 uint32 frame = p->Recv_uint32();
01232
01233
01234 if (this->status == STATUS_PRE_ACTIVE) {
01235
01236 if (frame + DAY_TICKS < _frame_counter) return NETWORK_RECV_STATUS_OKAY;
01237
01238
01239 this->status = STATUS_ACTIVE;
01240 this->last_token_frame = _frame_counter;
01241
01242
01243 IConsoleCmdExec("exec scripts/on_server_connect.scr 0");
01244 }
01245
01246
01247 uint8 token = p->Recv_uint8();
01248 if (token == this->last_token) {
01249
01250
01251
01252
01253
01254
01255
01256
01257 this->last_token_frame = _frame_counter;
01258
01259 this->last_token = 0;
01260 }
01261
01262
01263 this->last_frame = frame;
01264
01265 this->last_frame_server = _frame_counter;
01266 return NETWORK_RECV_STATUS_OKAY;
01267 }
01268
01269
01280 void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, const char *msg, ClientID from_id, int64 data, bool from_admin)
01281 {
01282 NetworkClientSocket *cs;
01283 const NetworkClientInfo *ci, *ci_own, *ci_to;
01284
01285 switch (desttype) {
01286 case DESTTYPE_CLIENT:
01287
01288 if ((ClientID)dest == CLIENT_ID_SERVER) {
01289 ci = NetworkClientInfo::GetByClientID(from_id);
01290
01291 if (ci != NULL) {
01292 NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
01293
01294 if (_settings_client.network.server_admin_chat) {
01295 NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
01296 }
01297 }
01298 } else {
01299
01300 FOR_ALL_CLIENT_SOCKETS(cs) {
01301 if (cs->client_id == (ClientID)dest) {
01302 cs->SendChat(action, from_id, false, msg, data);
01303 break;
01304 }
01305 }
01306 }
01307
01308
01309 if (from_id != (ClientID)dest) {
01310 if (from_id == CLIENT_ID_SERVER) {
01311 ci = NetworkClientInfo::GetByClientID(from_id);
01312 ci_to = NetworkClientInfo::GetByClientID((ClientID)dest);
01313 if (ci != NULL && ci_to != NULL) {
01314 NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), true, ci_to->client_name, msg, data);
01315 }
01316 } else {
01317 FOR_ALL_CLIENT_SOCKETS(cs) {
01318 if (cs->client_id == from_id) {
01319 cs->SendChat(action, (ClientID)dest, true, msg, data);
01320 break;
01321 }
01322 }
01323 }
01324 }
01325 break;
01326 case DESTTYPE_TEAM: {
01327
01328 bool show_local = true;
01329
01330 ci_to = NULL;
01331 FOR_ALL_CLIENT_SOCKETS(cs) {
01332 ci = cs->GetInfo();
01333 if (ci != NULL && ci->client_playas == (CompanyID)dest) {
01334 cs->SendChat(action, from_id, false, msg, data);
01335 if (cs->client_id == from_id) show_local = false;
01336 ci_to = ci;
01337 }
01338 }
01339
01340
01341 if (_local_company == (CompanyID)dest && _settings_client.network.server_admin_chat) {
01342 NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
01343 }
01344
01345 ci = NetworkClientInfo::GetByClientID(from_id);
01346 ci_own = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
01347 if (ci != NULL && ci_own != NULL && ci_own->client_playas == dest) {
01348 NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
01349 if (from_id == CLIENT_ID_SERVER) show_local = false;
01350 ci_to = ci_own;
01351 }
01352
01353
01354 if (ci_to == NULL) break;
01355
01356
01357 if (ci != NULL && show_local) {
01358 if (from_id == CLIENT_ID_SERVER) {
01359 char name[NETWORK_NAME_LENGTH];
01360 StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;
01361 SetDParam(0, ci_to->client_playas);
01362 GetString(name, str, lastof(name));
01363 NetworkTextMessage(action, GetDrawStringCompanyColour(ci_own->client_playas), true, name, msg, data);
01364 } else {
01365 FOR_ALL_CLIENT_SOCKETS(cs) {
01366 if (cs->client_id == from_id) {
01367 cs->SendChat(action, ci_to->client_id, true, msg, data);
01368 }
01369 }
01370 }
01371 }
01372 break;
01373 }
01374 default:
01375 DEBUG(net, 0, "[server] received unknown chat destination type %d. Doing broadcast instead", desttype);
01376
01377 case DESTTYPE_BROADCAST:
01378 FOR_ALL_CLIENT_SOCKETS(cs) {
01379 cs->SendChat(action, from_id, false, msg, data);
01380 }
01381
01382 NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
01383
01384 ci = NetworkClientInfo::GetByClientID(from_id);
01385 if (ci != NULL) {
01386 NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
01387 }
01388 break;
01389 }
01390 }
01391
01392 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_CHAT(Packet *p)
01393 {
01394 if (this->status < STATUS_PRE_ACTIVE) {
01395
01396 return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
01397 }
01398
01399 NetworkAction action = (NetworkAction)p->Recv_uint8();
01400 DestType desttype = (DestType)p->Recv_uint8();
01401 int dest = p->Recv_uint32();
01402 char msg[NETWORK_CHAT_LENGTH];
01403
01404 p->Recv_string(msg, NETWORK_CHAT_LENGTH);
01405 int64 data = p->Recv_uint64();
01406
01407 NetworkClientInfo *ci = this->GetInfo();
01408 switch (action) {
01409 case NETWORK_ACTION_GIVE_MONEY:
01410 if (!Company::IsValidID(ci->client_playas)) break;
01411
01412 case NETWORK_ACTION_CHAT:
01413 case NETWORK_ACTION_CHAT_CLIENT:
01414 case NETWORK_ACTION_CHAT_COMPANY:
01415 NetworkServerSendChat(action, desttype, dest, msg, this->client_id, data);
01416 break;
01417 default:
01418 IConsolePrintF(CC_ERROR, "WARNING: invalid chat action from client %d (IP: %s).", ci->client_id, this->GetClientIP());
01419 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01420 }
01421 return NETWORK_RECV_STATUS_OKAY;
01422 }
01423
01424 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_PASSWORD(Packet *p)
01425 {
01426 if (this->status != STATUS_ACTIVE) {
01427
01428 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01429 }
01430
01431 char password[NETWORK_PASSWORD_LENGTH];
01432 const NetworkClientInfo *ci;
01433
01434 p->Recv_string(password, sizeof(password));
01435 ci = this->GetInfo();
01436
01437 NetworkServerSetCompanyPassword(ci->client_playas, password);
01438 return NETWORK_RECV_STATUS_OKAY;
01439 }
01440
01441 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet *p)
01442 {
01443 if (this->status != STATUS_ACTIVE) {
01444
01445 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01446 }
01447
01448 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01449 NetworkClientInfo *ci;
01450
01451 p->Recv_string(client_name, sizeof(client_name));
01452 ci = this->GetInfo();
01453
01454 if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
01455
01456 if (ci != NULL) {
01457
01458 if (NetworkFindName(client_name)) {
01459 NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, client_name);
01460 strecpy(ci->client_name, client_name, lastof(ci->client_name));
01461 NetworkUpdateClientInfo(ci->client_id);
01462 }
01463 }
01464 return NETWORK_RECV_STATUS_OKAY;
01465 }
01466
01467 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_RCON(Packet *p)
01468 {
01469 if (this->status != STATUS_ACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01470
01471 char pass[NETWORK_PASSWORD_LENGTH];
01472 char command[NETWORK_RCONCOMMAND_LENGTH];
01473
01474 if (StrEmpty(_settings_client.network.rcon_password)) return NETWORK_RECV_STATUS_OKAY;
01475
01476 p->Recv_string(pass, sizeof(pass));
01477 p->Recv_string(command, sizeof(command));
01478
01479 if (strcmp(pass, _settings_client.network.rcon_password) != 0) {
01480 DEBUG(net, 0, "[rcon] wrong password from client-id %d", this->client_id);
01481 return NETWORK_RECV_STATUS_OKAY;
01482 }
01483
01484 DEBUG(net, 0, "[rcon] client-id %d executed: '%s'", this->client_id, command);
01485
01486 _redirect_console_to_client = this->client_id;
01487 IConsoleCmdExec(command);
01488 _redirect_console_to_client = INVALID_CLIENT_ID;
01489 return NETWORK_RECV_STATUS_OKAY;
01490 }
01491
01492 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MOVE(Packet *p)
01493 {
01494 if (this->status != STATUS_ACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01495
01496 CompanyID company_id = (Owner)p->Recv_uint8();
01497
01498
01499 if (company_id != COMPANY_SPECTATOR && !Company::IsValidHumanID(company_id)) return NETWORK_RECV_STATUS_OKAY;
01500
01501
01502 if (company_id != COMPANY_SPECTATOR && !StrEmpty(_network_company_states[company_id].password)) {
01503
01504 char password[NETWORK_PASSWORD_LENGTH];
01505 p->Recv_string(password, sizeof(password));
01506
01507
01508 if (strcmp(password, _network_company_states[company_id].password) != 0) {
01509 DEBUG(net, 2, "[move] wrong password from client-id #%d for company #%d", this->client_id, company_id + 1);
01510 return NETWORK_RECV_STATUS_OKAY;
01511 }
01512 }
01513
01514
01515 NetworkServerDoMove(this->client_id, company_id);
01516 return NETWORK_RECV_STATUS_OKAY;
01517 }
01518
01526 void NetworkSocketHandler::SendCompanyInformation(Packet *p, const Company *c, const NetworkCompanyStats *stats, uint max_len)
01527 {
01528
01529 char company_name[NETWORK_COMPANY_NAME_LENGTH];
01530 SetDParam(0, c->index);
01531
01532 assert(max_len <= lengthof(company_name));
01533 GetString(company_name, STR_COMPANY_NAME, company_name + max_len - 1);
01534
01535
01536 Money income = 0;
01537 if (_cur_year - 1 == c->inaugurated_year) {
01538
01539 for (uint i = 0; i < lengthof(c->yearly_expenses[2]); i++) {
01540 income -= c->yearly_expenses[2][i];
01541 }
01542 } else {
01543 for (uint i = 0; i < lengthof(c->yearly_expenses[1]); i++) {
01544 income -= c->yearly_expenses[1][i];
01545 }
01546 }
01547
01548
01549 p->Send_uint8 (c->index);
01550 p->Send_string(company_name);
01551 p->Send_uint32(c->inaugurated_year);
01552 p->Send_uint64(c->old_economy[0].company_value);
01553 p->Send_uint64(c->money);
01554 p->Send_uint64(income);
01555 p->Send_uint16(c->old_economy[0].performance_history);
01556
01557
01558 p->Send_bool (!StrEmpty(_network_company_states[c->index].password));
01559
01560 for (uint i = 0; i < NETWORK_VEH_END; i++) {
01561 p->Send_uint16(stats->num_vehicle[i]);
01562 }
01563
01564 for (uint i = 0; i < NETWORK_VEH_END; i++) {
01565 p->Send_uint16(stats->num_station[i]);
01566 }
01567
01568 p->Send_bool(c->is_ai);
01569 }
01570
01575 void NetworkPopulateCompanyStats(NetworkCompanyStats *stats)
01576 {
01577 const Vehicle *v;
01578 const Station *s;
01579
01580 memset(stats, 0, sizeof(*stats) * MAX_COMPANIES);
01581
01582
01583 FOR_ALL_VEHICLES(v) {
01584 if (!Company::IsValidID(v->owner) || !v->IsPrimaryVehicle()) continue;
01585 byte type = 0;
01586 switch (v->type) {
01587 case VEH_TRAIN: type = NETWORK_VEH_TRAIN; break;
01588 case VEH_ROAD: type = RoadVehicle::From(v)->IsBus() ? NETWORK_VEH_BUS : NETWORK_VEH_LORRY; break;
01589 case VEH_AIRCRAFT: type = NETWORK_VEH_PLANE; break;
01590 case VEH_SHIP: type = NETWORK_VEH_SHIP; break;
01591 default: continue;
01592 }
01593 stats[v->owner].num_vehicle[type]++;
01594 }
01595
01596
01597 FOR_ALL_STATIONS(s) {
01598 if (Company::IsValidID(s->owner)) {
01599 NetworkCompanyStats *npi = &stats[s->owner];
01600
01601 if (s->facilities & FACIL_TRAIN) npi->num_station[NETWORK_VEH_TRAIN]++;
01602 if (s->facilities & FACIL_TRUCK_STOP) npi->num_station[NETWORK_VEH_LORRY]++;
01603 if (s->facilities & FACIL_BUS_STOP) npi->num_station[NETWORK_VEH_BUS]++;
01604 if (s->facilities & FACIL_AIRPORT) npi->num_station[NETWORK_VEH_PLANE]++;
01605 if (s->facilities & FACIL_DOCK) npi->num_station[NETWORK_VEH_SHIP]++;
01606 }
01607 }
01608 }
01609
01614 void NetworkUpdateClientInfo(ClientID client_id)
01615 {
01616 NetworkClientSocket *cs;
01617 NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
01618
01619 if (ci == NULL) return;
01620
01621 DEBUG(desync, 1, "client: %08x; %02x; %02x; %04x", _date, _date_fract, (int)ci->client_playas, client_id);
01622
01623 FOR_ALL_CLIENT_SOCKETS(cs) {
01624 cs->SendClientInfo(ci);
01625 }
01626
01627 NetworkAdminClientUpdate(ci);
01628 }
01629
01631 static void NetworkCheckRestartMap()
01632 {
01633 if (_settings_client.network.restart_game_year != 0 && _cur_year >= _settings_client.network.restart_game_year) {
01634 DEBUG(net, 0, "Auto-restarting map. Year %d reached", _cur_year);
01635
01636 StartNewGameWithoutGUI(GENERATE_NEW_SEED);
01637 }
01638 }
01639
01646 static void NetworkAutoCleanCompanies()
01647 {
01648 const NetworkClientInfo *ci;
01649 const Company *c;
01650 bool clients_in_company[MAX_COMPANIES];
01651 int vehicles_in_company[MAX_COMPANIES];
01652
01653 if (!_settings_client.network.autoclean_companies) return;
01654
01655 memset(clients_in_company, 0, sizeof(clients_in_company));
01656
01657
01658 FOR_ALL_CLIENT_INFOS(ci) {
01659 if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true;
01660 }
01661
01662 if (!_network_dedicated) {
01663 ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
01664 if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true;
01665 }
01666
01667 if (_settings_client.network.autoclean_novehicles != 0) {
01668 memset(vehicles_in_company, 0, sizeof(vehicles_in_company));
01669
01670 const Vehicle *v;
01671 FOR_ALL_VEHICLES(v) {
01672 if (!Company::IsValidID(v->owner) || !v->IsPrimaryVehicle()) continue;
01673 vehicles_in_company[v->owner]++;
01674 }
01675 }
01676
01677
01678 FOR_ALL_COMPANIES(c) {
01679
01680 if (c->is_ai) continue;
01681
01682 if (!clients_in_company[c->index]) {
01683
01684 _network_company_states[c->index].months_empty++;
01685
01686
01687 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)) {
01688
01689 DoCommandP(0, 2 | c->index << 16, CRR_AUTOCLEAN, CMD_COMPANY_CTRL);
01690 IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no password", c->index + 1);
01691 }
01692
01693 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)) {
01694
01695 _network_company_states[c->index].password[0] = '\0';
01696 IConsolePrintF(CC_DEFAULT, "Auto-removed protection from company #%d", c->index + 1);
01697 _network_company_states[c->index].months_empty = 0;
01698 NetworkServerUpdateCompanyPassworded(c->index, false);
01699 }
01700
01701 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) {
01702
01703 DoCommandP(0, 2 | c->index << 16, CRR_AUTOCLEAN, CMD_COMPANY_CTRL);
01704 IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no vehicles", c->index + 1);
01705 }
01706 } else {
01707
01708 _network_company_states[c->index].months_empty = 0;
01709 }
01710 }
01711 }
01712
01718 bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH])
01719 {
01720 bool found_name = false;
01721 uint number = 0;
01722 char original_name[NETWORK_CLIENT_NAME_LENGTH];
01723
01724
01725 ttd_strlcpy(original_name, new_name, NETWORK_CLIENT_NAME_LENGTH);
01726
01727 while (!found_name) {
01728 const NetworkClientInfo *ci;
01729
01730 found_name = true;
01731 FOR_ALL_CLIENT_INFOS(ci) {
01732 if (strcmp(ci->client_name, new_name) == 0) {
01733
01734 found_name = false;
01735 break;
01736 }
01737 }
01738
01739 ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
01740 if (ci != NULL) {
01741 if (strcmp(ci->client_name, new_name) == 0) found_name = false;
01742 }
01743
01744 if (!found_name) {
01745
01746
01747
01748 if (number++ > MAX_CLIENTS) break;
01749 snprintf(new_name, NETWORK_CLIENT_NAME_LENGTH, "%s #%d", original_name, number);
01750 }
01751 }
01752
01753 return found_name;
01754 }
01755
01762 bool NetworkServerChangeClientName(ClientID client_id, const char *new_name)
01763 {
01764 NetworkClientInfo *ci;
01765
01766 FOR_ALL_CLIENT_INFOS(ci) {
01767 if (strcmp(ci->client_name, new_name) == 0) return false;
01768 }
01769
01770 ci = NetworkClientInfo::GetByClientID(client_id);
01771 if (ci == NULL) return false;
01772
01773 NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, true, ci->client_name, new_name);
01774
01775 strecpy(ci->client_name, new_name, lastof(ci->client_name));
01776
01777 NetworkUpdateClientInfo(client_id);
01778 return true;
01779 }
01780
01787 void NetworkServerSetCompanyPassword(CompanyID company_id, const char *password, bool already_hashed)
01788 {
01789 if (!Company::IsValidHumanID(company_id)) return;
01790
01791 if (!already_hashed) {
01792 password = GenerateCompanyPasswordHash(password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed);
01793 }
01794
01795 strecpy(_network_company_states[company_id].password, password, lastof(_network_company_states[company_id].password));
01796 NetworkServerUpdateCompanyPassworded(company_id, !StrEmpty(_network_company_states[company_id].password));
01797 }
01798
01803 static void NetworkHandleCommandQueue(NetworkClientSocket *cs)
01804 {
01805 CommandPacket *cp;
01806 while ((cp = cs->outgoing_queue.Pop()) != NULL) {
01807 cs->SendCommand(cp);
01808 free(cp);
01809 }
01810 }
01811
01816 void NetworkServer_Tick(bool send_frame)
01817 {
01818 NetworkClientSocket *cs;
01819 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
01820 bool send_sync = false;
01821 #endif
01822
01823 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
01824 if (_frame_counter >= _last_sync_frame + _settings_client.network.sync_freq) {
01825 _last_sync_frame = _frame_counter;
01826 send_sync = true;
01827 }
01828 #endif
01829
01830
01831
01832 FOR_ALL_CLIENT_SOCKETS(cs) {
01833
01834
01835 cs->receive_limit = min(cs->receive_limit + _settings_client.network.bytes_per_frame,
01836 _settings_client.network.bytes_per_frame_burst);
01837
01838
01839 uint lag = NetworkCalculateLag(cs);
01840 switch (cs->status) {
01841 case NetworkClientSocket::STATUS_ACTIVE:
01842 if (lag > _settings_client.network.max_lag_time) {
01843
01844 IConsolePrintF(CC_ERROR, cs->last_packet + lag * MILLISECONDS_PER_TICK > _realtime_tick ?
01845
01846 "Client #%d is dropped because the client's game state is more than %d ticks behind" :
01847
01848 "Client #%d is dropped because the client did not respond for more than %d ticks",
01849 cs->client_id, lag);
01850 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
01851 continue;
01852 }
01853
01854
01855
01856
01857
01858
01859 if (lag > (uint)DAY_TICKS && cs->lag_test == 0 && cs->last_packet + 2000 > _realtime_tick) {
01860 IConsolePrintF(CC_WARNING, "[%d] Client #%d is slow, try increasing [network.]frame_freq to a higher value!", _frame_counter, cs->client_id);
01861 cs->lag_test = 1;
01862 }
01863
01864 if (cs->last_frame_server - cs->last_token_frame >= _settings_client.network.max_lag_time) {
01865
01866 IConsolePrintF(CC_ERROR, "Client #%d is dropped because it fails to send valid acks", cs->client_id);
01867 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
01868 continue;
01869 }
01870 break;
01871
01872 case NetworkClientSocket::STATUS_INACTIVE:
01873 case NetworkClientSocket::STATUS_NEWGRFS_CHECK:
01874 case NetworkClientSocket::STATUS_AUTHORIZED:
01875
01876
01877 if (lag > _settings_client.network.max_init_time) {
01878 IConsolePrintF(CC_ERROR, "Client #%d is dropped because it took longer than %d ticks to start the joining process", cs->client_id, _settings_client.network.max_init_time);
01879 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
01880 continue;
01881 }
01882 break;
01883
01884 case NetworkClientSocket::STATUS_MAP:
01885
01886 if (lag > _settings_client.network.max_download_time) {
01887 IConsolePrintF(CC_ERROR, "Client #%d is dropped because it took longer than %d ticks to download the map", cs->client_id, _settings_client.network.max_download_time);
01888 cs->SendError(NETWORK_ERROR_TIMEOUT_MAP);
01889 continue;
01890 }
01891 break;
01892
01893 case NetworkClientSocket::STATUS_DONE_MAP:
01894 case NetworkClientSocket::STATUS_PRE_ACTIVE:
01895
01896 if (lag > _settings_client.network.max_join_time) {
01897 IConsolePrintF(CC_ERROR, "Client #%d is dropped because it took longer than %d ticks to join", cs->client_id, _settings_client.network.max_join_time);
01898 cs->SendError(NETWORK_ERROR_TIMEOUT_JOIN);
01899 continue;
01900 }
01901 break;
01902
01903 case NetworkClientSocket::STATUS_AUTH_GAME:
01904 case NetworkClientSocket::STATUS_AUTH_COMPANY:
01905
01906 if (lag > _settings_client.network.max_password_time) {
01907 IConsolePrintF(CC_ERROR, "Client #%d is dropped because it took longer than %d ticks to enter the password", cs->client_id, _settings_client.network.max_password_time);
01908 cs->SendError(NETWORK_ERROR_TIMEOUT_PASSWORD);
01909 continue;
01910 }
01911 break;
01912
01913 case NetworkClientSocket::STATUS_MAP_WAIT:
01914
01915
01916 break;
01917
01918 case NetworkClientSocket::STATUS_END:
01919
01920 NOT_REACHED();
01921 }
01922
01923 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) {
01924
01925 NetworkHandleCommandQueue(cs);
01926
01927
01928 if (send_frame) cs->SendFrame();
01929
01930 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
01931
01932 if (send_sync) cs->SendSync();
01933 #endif
01934 }
01935 }
01936
01937
01938 NetworkUDPAdvertise();
01939 }
01940
01942 void NetworkServerYearlyLoop()
01943 {
01944 NetworkCheckRestartMap();
01945 NetworkAdminUpdate(ADMIN_FREQUENCY_ANUALLY);
01946 }
01947
01949 void NetworkServerMonthlyLoop()
01950 {
01951 NetworkAutoCleanCompanies();
01952 NetworkAdminUpdate(ADMIN_FREQUENCY_MONTHLY);
01953 if ((_cur_month % 3) == 0) NetworkAdminUpdate(ADMIN_FREQUENCY_QUARTERLY);
01954 }
01955
01957 void NetworkServerDailyLoop()
01958 {
01959 NetworkAdminUpdate(ADMIN_FREQUENCY_DAILY);
01960 if ((_date % 7) == 3) NetworkAdminUpdate(ADMIN_FREQUENCY_WEEKLY);
01961 }
01962
01967 const char *ServerNetworkGameSocketHandler::GetClientIP()
01968 {
01969 return this->client_address.GetHostname();
01970 }
01971
01973 void NetworkServerShowStatusToConsole()
01974 {
01975 static const char * const stat_str[] = {
01976 "inactive",
01977 "checking NewGRFs",
01978 "authorizing (server password)",
01979 "authorizing (company password)",
01980 "authorized",
01981 "waiting",
01982 "loading map",
01983 "map done",
01984 "ready",
01985 "active"
01986 };
01987 assert_compile(lengthof(stat_str) == NetworkClientSocket::STATUS_END);
01988
01989 NetworkClientSocket *cs;
01990 FOR_ALL_CLIENT_SOCKETS(cs) {
01991 NetworkClientInfo *ci = cs->GetInfo();
01992 if (ci == NULL) continue;
01993 uint lag = NetworkCalculateLag(cs);
01994 const char *status;
01995
01996 status = (cs->status < (ptrdiff_t)lengthof(stat_str) ? stat_str[cs->status] : "unknown");
01997 IConsolePrintF(CC_INFO, "Client #%1d name: '%s' status: '%s' frame-lag: %3d company: %1d IP: %s",
01998 cs->client_id, ci->client_name, status, lag,
01999 ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0),
02000 cs->GetClientIP());
02001 }
02002 }
02003
02007 void NetworkServerSendConfigUpdate()
02008 {
02009 NetworkClientSocket *cs;
02010
02011 FOR_ALL_CLIENT_SOCKETS(cs) {
02012 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendConfigUpdate();
02013 }
02014 }
02015
02021 void NetworkServerUpdateCompanyPassworded(CompanyID company_id, bool passworded)
02022 {
02023 if (NetworkCompanyIsPassworded(company_id) == passworded) return;
02024
02025 SB(_network_company_passworded, company_id, 1, !!passworded);
02026 SetWindowClassesDirty(WC_COMPANY);
02027
02028 NetworkClientSocket *cs;
02029 FOR_ALL_CLIENT_SOCKETS(cs) {
02030 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendCompanyUpdate();
02031 }
02032
02033 NetworkAdminCompanyUpdate(Company::GetIfValid(company_id));
02034 }
02035
02042 void NetworkServerDoMove(ClientID client_id, CompanyID company_id)
02043 {
02044
02045 if (client_id == CLIENT_ID_SERVER && _network_dedicated) return;
02046
02047 NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
02048
02049
02050 if (ci->client_playas == company_id) return;
02051
02052 ci->client_playas = company_id;
02053
02054 if (client_id == CLIENT_ID_SERVER) {
02055 SetLocalCompany(company_id);
02056 } else {
02057 NetworkClientSocket *cs = NetworkClientSocket::GetByClientID(client_id);
02058
02059 if (cs->status < NetworkClientSocket::STATUS_AUTHORIZED) return;
02060 cs->SendMove(client_id, company_id);
02061 }
02062
02063
02064 NetworkUpdateClientInfo(client_id);
02065
02066 NetworkAction action = (company_id == COMPANY_SPECTATOR) ? NETWORK_ACTION_COMPANY_SPECTATOR : NETWORK_ACTION_COMPANY_JOIN;
02067 NetworkServerSendChat(action, DESTTYPE_BROADCAST, 0, "", client_id, company_id + 1);
02068 }
02069
02076 void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const char *string)
02077 {
02078 NetworkClientSocket::GetByClientID(client_id)->SendRConResult(colour_code, string);
02079 }
02080
02085 void NetworkServerKickClient(ClientID client_id)
02086 {
02087 if (client_id == CLIENT_ID_SERVER) return;
02088 NetworkClientSocket::GetByClientID(client_id)->SendError(NETWORK_ERROR_KICKED);
02089 }
02090
02096 uint NetworkServerKickOrBanIP(ClientID client_id, bool ban)
02097 {
02098 return NetworkServerKickOrBanIP(NetworkClientSocket::GetByClientID(client_id)->GetClientIP(), ban);
02099 }
02100
02106 uint NetworkServerKickOrBanIP(const char *ip, bool ban)
02107 {
02108
02109 if (ban) {
02110 bool contains = false;
02111 for (char **iter = _network_ban_list.Begin(); iter != _network_ban_list.End(); iter++) {
02112 if (strcmp(*iter, ip) == 0) {
02113 contains = true;
02114 break;
02115 }
02116 }
02117 if (!contains) *_network_ban_list.Append() = strdup(ip);
02118 }
02119
02120 uint n = 0;
02121
02122
02123 NetworkClientSocket *cs;
02124 FOR_ALL_CLIENT_SOCKETS(cs) {
02125 if (cs->client_id == CLIENT_ID_SERVER) continue;
02126 if (cs->client_address.IsInNetmask(const_cast<char *>(ip))) {
02127 NetworkServerKickClient(cs->client_id);
02128 n++;
02129 }
02130 }
02131
02132 return n;
02133 }
02134
02140 bool NetworkCompanyHasClients(CompanyID company)
02141 {
02142 const NetworkClientInfo *ci;
02143 FOR_ALL_CLIENT_INFOS(ci) {
02144 if (ci->client_playas == company) return true;
02145 }
02146 return false;
02147 }
02148
02149
02155 void ServerNetworkGameSocketHandler::GetClientName(char *client_name, size_t size) const
02156 {
02157 const NetworkClientInfo *ci = this->GetInfo();
02158
02159 if (ci == NULL || StrEmpty(ci->client_name)) {
02160 snprintf(client_name, size, "Client #%4d", this->client_id);
02161 } else {
02162 ttd_strlcpy(client_name, ci->client_name, size);
02163 }
02164 }
02165
02169 void NetworkPrintClients()
02170 {
02171 NetworkClientInfo *ci;
02172 FOR_ALL_CLIENT_INFOS(ci) {
02173 if (_network_server) {
02174 IConsolePrintF(CC_INFO, "Client #%1d name: '%s' company: %1d IP: %s",
02175 ci->client_id,
02176 ci->client_name,
02177 ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0),
02178 ci->client_id == CLIENT_ID_SERVER ? "server" : NetworkClientSocket::GetByClientID(ci->client_id)->GetClientIP());
02179 } else {
02180 IConsolePrintF(CC_INFO, "Client #%1d name: '%s' company: %1d",
02181 ci->client_id,
02182 ci->client_name,
02183 ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0));
02184 }
02185 }
02186 }
02187
02193 void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci)
02194 {
02195 assert(c != NULL);
02196
02197 if (!_network_server) return;
02198
02199 _network_company_states[c->index].months_empty = 0;
02200 _network_company_states[c->index].password[0] = '\0';
02201 NetworkServerUpdateCompanyPassworded(c->index, false);
02202
02203 if (ci != NULL) {
02204
02205 ci->client_playas = c->index;
02206 NetworkUpdateClientInfo(ci->client_id);
02207 NetworkSendCommand(0, 0, 0, CMD_RENAME_PRESIDENT, NULL, ci->client_name, c->index);
02208 }
02209
02210
02211 NetworkAdminCompanyInfo(c, true);
02212
02213 if (ci != NULL) {
02214
02215
02216
02217 NetworkServerSendChat(NETWORK_ACTION_COMPANY_NEW, DESTTYPE_BROADCAST, 0, "", ci->client_id, c->index + 1);
02218 }
02219 }
02220
02221 #endif