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 if (SaveWithFilter(this->savegame, true) != SL_OK) usererror("network savedump failed");
00601 }
00602
00603 if (this->status == STATUS_MAP) {
00604 bool last_packet = false;
00605 bool has_packets = false;
00606
00607 for (uint i = 0; (has_packets = this->savegame->HasPackets()) && i < sent_packets; i++) {
00608 Packet *p = this->savegame->PopPacket();
00609 last_packet = p->buffer[2] == PACKET_SERVER_MAP_DONE;
00610
00611 this->SendPacket(p);
00612
00613 if (last_packet) {
00614
00615 break;
00616 }
00617 }
00618
00619 if (last_packet) {
00620
00621 this->savegame->Destroy();
00622 this->savegame = NULL;
00623
00624
00625
00626 this->status = STATUS_DONE_MAP;
00627
00628
00629 NetworkClientSocket *new_cs;
00630 NetworkClientSocket *best = NULL;
00631 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00632 if (new_cs->status == STATUS_MAP_WAIT) {
00633 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)) {
00634 best = new_cs;
00635 }
00636 }
00637 }
00638
00639
00640 if (best != NULL) {
00641
00642 best->status = STATUS_AUTHORIZED;
00643 best->SendMap();
00644
00645
00646 FOR_ALL_CLIENT_SOCKETS(new_cs) {
00647 if (new_cs->status == STATUS_MAP_WAIT) new_cs->SendWait();
00648 }
00649 }
00650 }
00651
00652 switch (this->SendPackets()) {
00653 case SPS_CLOSED:
00654 return NETWORK_RECV_STATUS_CONN_LOST;
00655
00656 case SPS_ALL_SENT:
00657
00658 if (has_packets) sent_packets *= 2;
00659 break;
00660
00661 case SPS_PARTLY_SENT:
00662
00663 break;
00664
00665 case SPS_NONE_SENT:
00666
00667 if (sent_packets > 1) sent_packets /= 2;
00668 break;
00669 }
00670 }
00671 return NETWORK_RECV_STATUS_OKAY;
00672 }
00673
00678 NetworkRecvStatus ServerNetworkGameSocketHandler::SendJoin(ClientID client_id)
00679 {
00680 Packet *p = new Packet(PACKET_SERVER_JOIN);
00681
00682 p->Send_uint32(client_id);
00683
00684 this->SendPacket(p);
00685 return NETWORK_RECV_STATUS_OKAY;
00686 }
00687
00689 NetworkRecvStatus ServerNetworkGameSocketHandler::SendFrame()
00690 {
00691 Packet *p = new Packet(PACKET_SERVER_FRAME);
00692 p->Send_uint32(_frame_counter);
00693 p->Send_uint32(_frame_counter_max);
00694 #ifdef ENABLE_NETWORK_SYNC_EVERY_FRAME
00695 p->Send_uint32(_sync_seed_1);
00696 #ifdef NETWORK_SEND_DOUBLE_SEED
00697 p->Send_uint32(_sync_seed_2);
00698 #endif
00699 #endif
00700
00701
00702 if (this->last_token == 0) {
00703 this->last_token = InteractiveRandomRange(UINT8_MAX - 1) + 1;
00704 p->Send_uint8(this->last_token);
00705 }
00706
00707 this->SendPacket(p);
00708 return NETWORK_RECV_STATUS_OKAY;
00709 }
00710
00712 NetworkRecvStatus ServerNetworkGameSocketHandler::SendSync()
00713 {
00714 Packet *p = new Packet(PACKET_SERVER_SYNC);
00715 p->Send_uint32(_frame_counter);
00716 p->Send_uint32(_sync_seed_1);
00717
00718 #ifdef NETWORK_SEND_DOUBLE_SEED
00719 p->Send_uint32(_sync_seed_2);
00720 #endif
00721 this->SendPacket(p);
00722 return NETWORK_RECV_STATUS_OKAY;
00723 }
00724
00729 NetworkRecvStatus ServerNetworkGameSocketHandler::SendCommand(const CommandPacket *cp)
00730 {
00731 Packet *p = new Packet(PACKET_SERVER_COMMAND);
00732
00733 this->NetworkGameSocketHandler::SendCommand(p, cp);
00734 p->Send_uint32(cp->frame);
00735 p->Send_bool (cp->my_cmd);
00736
00737 this->SendPacket(p);
00738 return NETWORK_RECV_STATUS_OKAY;
00739 }
00740
00749 NetworkRecvStatus ServerNetworkGameSocketHandler::SendChat(NetworkAction action, ClientID client_id, bool self_send, const char *msg, int64 data)
00750 {
00751 if (this->status < STATUS_PRE_ACTIVE) return NETWORK_RECV_STATUS_OKAY;
00752
00753 Packet *p = new Packet(PACKET_SERVER_CHAT);
00754
00755 p->Send_uint8 (action);
00756 p->Send_uint32(client_id);
00757 p->Send_bool (self_send);
00758 p->Send_string(msg);
00759 p->Send_uint64(data);
00760
00761 this->SendPacket(p);
00762 return NETWORK_RECV_STATUS_OKAY;
00763 }
00764
00770 NetworkRecvStatus ServerNetworkGameSocketHandler::SendErrorQuit(ClientID client_id, NetworkErrorCode errorno)
00771 {
00772 Packet *p = new Packet(PACKET_SERVER_ERROR_QUIT);
00773
00774 p->Send_uint32(client_id);
00775 p->Send_uint8 (errorno);
00776
00777 this->SendPacket(p);
00778 return NETWORK_RECV_STATUS_OKAY;
00779 }
00780
00785 NetworkRecvStatus ServerNetworkGameSocketHandler::SendQuit(ClientID client_id)
00786 {
00787 Packet *p = new Packet(PACKET_SERVER_QUIT);
00788
00789 p->Send_uint32(client_id);
00790
00791 this->SendPacket(p);
00792 return NETWORK_RECV_STATUS_OKAY;
00793 }
00794
00796 NetworkRecvStatus ServerNetworkGameSocketHandler::SendShutdown()
00797 {
00798 Packet *p = new Packet(PACKET_SERVER_SHUTDOWN);
00799 this->SendPacket(p);
00800 return NETWORK_RECV_STATUS_OKAY;
00801 }
00802
00804 NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGame()
00805 {
00806 Packet *p = new Packet(PACKET_SERVER_NEWGAME);
00807 this->SendPacket(p);
00808 return NETWORK_RECV_STATUS_OKAY;
00809 }
00810
00816 NetworkRecvStatus ServerNetworkGameSocketHandler::SendRConResult(uint16 colour, const char *command)
00817 {
00818 Packet *p = new Packet(PACKET_SERVER_RCON);
00819
00820 p->Send_uint16(colour);
00821 p->Send_string(command);
00822 this->SendPacket(p);
00823 return NETWORK_RECV_STATUS_OKAY;
00824 }
00825
00831 NetworkRecvStatus ServerNetworkGameSocketHandler::SendMove(ClientID client_id, CompanyID company_id)
00832 {
00833 Packet *p = new Packet(PACKET_SERVER_MOVE);
00834
00835 p->Send_uint32(client_id);
00836 p->Send_uint8(company_id);
00837 this->SendPacket(p);
00838 return NETWORK_RECV_STATUS_OKAY;
00839 }
00840
00842 NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyUpdate()
00843 {
00844 Packet *p = new Packet(PACKET_SERVER_COMPANY_UPDATE);
00845
00846 p->Send_uint16(_network_company_passworded);
00847 this->SendPacket(p);
00848 return NETWORK_RECV_STATUS_OKAY;
00849 }
00850
00852 NetworkRecvStatus ServerNetworkGameSocketHandler::SendConfigUpdate()
00853 {
00854 Packet *p = new Packet(PACKET_SERVER_CONFIG_UPDATE);
00855
00856 p->Send_uint8(_settings_client.network.max_companies);
00857 p->Send_uint8(_settings_client.network.max_spectators);
00858 this->SendPacket(p);
00859 return NETWORK_RECV_STATUS_OKAY;
00860 }
00861
00862
00863
00864
00865
00866
00867 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMPANY_INFO(Packet *p)
00868 {
00869 return this->SendCompanyInfo();
00870 }
00871
00872 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_NEWGRFS_CHECKED(Packet *p)
00873 {
00874 if (this->status != STATUS_NEWGRFS_CHECK) {
00875
00876 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00877 }
00878
00879 NetworkClientInfo *ci = this->GetInfo();
00880
00881
00882 if (!StrEmpty(_settings_client.network.server_password)) {
00883 return this->SendNeedGamePassword();
00884 }
00885
00886 if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) {
00887 return this->SendNeedCompanyPassword();
00888 }
00889
00890 return this->SendWelcome();
00891 }
00892
00893 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
00894 {
00895 if (this->status != STATUS_INACTIVE) {
00896
00897 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00898 }
00899
00900 char name[NETWORK_CLIENT_NAME_LENGTH];
00901 CompanyID playas;
00902 NetworkLanguage client_lang;
00903 char client_revision[NETWORK_REVISION_LENGTH];
00904
00905 p->Recv_string(client_revision, sizeof(client_revision));
00906 uint32 newgrf_version = p->Recv_uint32();
00907
00908
00909 if (!IsNetworkCompatibleVersion(client_revision) || _openttd_newgrf_version != newgrf_version) {
00910
00911 return this->SendError(NETWORK_ERROR_WRONG_REVISION);
00912 }
00913
00914 p->Recv_string(name, sizeof(name));
00915 playas = (Owner)p->Recv_uint8();
00916 client_lang = (NetworkLanguage)p->Recv_uint8();
00917
00918 if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
00919
00920
00921 switch (playas) {
00922 case COMPANY_NEW_COMPANY:
00923 if (Company::GetNumItems() >= _settings_client.network.max_companies) {
00924 return this->SendError(NETWORK_ERROR_FULL);
00925 }
00926 break;
00927 case COMPANY_SPECTATOR:
00928 if (NetworkSpectatorCount() >= _settings_client.network.max_spectators) {
00929 return this->SendError(NETWORK_ERROR_FULL);
00930 }
00931 break;
00932 default:
00933 if (!Company::IsValidHumanID(playas)) {
00934 return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH);
00935 }
00936 break;
00937 }
00938
00939
00940 if (StrEmpty(name)) strecpy(name, "Player", lastof(name));
00941
00942 if (!NetworkFindName(name)) {
00943
00944 return this->SendError(NETWORK_ERROR_NAME_IN_USE);
00945 }
00946
00947 assert(NetworkClientInfo::CanAllocateItem());
00948 NetworkClientInfo *ci = new NetworkClientInfo(this->client_id);
00949 this->SetInfo(ci);
00950 ci->join_date = _date;
00951 strecpy(ci->client_name, name, lastof(ci->client_name));
00952 ci->client_playas = playas;
00953 ci->client_lang = client_lang;
00954 DEBUG(desync, 1, "client: %08x; %02x; %02x; %04x", _date, _date_fract, (int)ci->client_playas, ci->index);
00955
00956
00957 if (Company::IsValidID(playas)) _network_company_states[playas].months_empty = 0;
00958
00959 this->status = STATUS_NEWGRFS_CHECK;
00960
00961 if (_grfconfig == NULL) {
00962
00963 return this->Receive_CLIENT_NEWGRFS_CHECKED(NULL);
00964 }
00965
00966 return this->SendNewGRFCheck();
00967 }
00968
00969 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GAME_PASSWORD(Packet *p)
00970 {
00971 if (this->status != STATUS_AUTH_GAME) {
00972 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00973 }
00974
00975 char password[NETWORK_PASSWORD_LENGTH];
00976 p->Recv_string(password, sizeof(password));
00977
00978
00979 if (!StrEmpty(_settings_client.network.server_password) &&
00980 strcmp(password, _settings_client.network.server_password) != 0) {
00981
00982 return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
00983 }
00984
00985 const NetworkClientInfo *ci = this->GetInfo();
00986 if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) {
00987 return this->SendNeedCompanyPassword();
00988 }
00989
00990
00991 return this->SendWelcome();
00992 }
00993
00994 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMPANY_PASSWORD(Packet *p)
00995 {
00996 if (this->status != STATUS_AUTH_COMPANY) {
00997 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
00998 }
00999
01000 char password[NETWORK_PASSWORD_LENGTH];
01001 p->Recv_string(password, sizeof(password));
01002
01003
01004
01005
01006 CompanyID playas = this->GetInfo()->client_playas;
01007 if (Company::IsValidID(playas) && !StrEmpty(_network_company_states[playas].password) &&
01008 strcmp(password, _network_company_states[playas].password) != 0) {
01009
01010 return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
01011 }
01012
01013 return this->SendWelcome();
01014 }
01015
01016 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GETMAP(Packet *p)
01017 {
01018 NetworkClientSocket *new_cs;
01019
01020
01021 if (this->status < STATUS_AUTHORIZED || this->HasClientQuit()) {
01022 return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
01023 }
01024
01025
01026 FOR_ALL_CLIENT_SOCKETS(new_cs) {
01027 if (new_cs->status == STATUS_MAP) {
01028
01029 this->status = STATUS_MAP_WAIT;
01030 return this->SendWait();
01031 }
01032 }
01033
01034
01035 return this->SendMap();
01036 }
01037
01038 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MAP_OK(Packet *p)
01039 {
01040
01041 if (this->status == STATUS_DONE_MAP && !this->HasClientQuit()) {
01042 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01043 NetworkClientSocket *new_cs;
01044
01045 this->GetClientName(client_name, sizeof(client_name));
01046
01047 NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, client_name, NULL, this->client_id);
01048
01049
01050
01051 this->status = STATUS_PRE_ACTIVE;
01052 NetworkHandleCommandQueue(this);
01053 this->SendFrame();
01054 this->SendSync();
01055
01056
01057
01058 this->last_frame = _frame_counter;
01059 this->last_frame_server = _frame_counter;
01060
01061 FOR_ALL_CLIENT_SOCKETS(new_cs) {
01062 if (new_cs->status > STATUS_AUTHORIZED) {
01063 new_cs->SendClientInfo(this->GetInfo());
01064 new_cs->SendJoin(this->client_id);
01065 }
01066 }
01067
01068 NetworkAdminClientInfo(this, true);
01069
01070
01071 this->SendConfigUpdate();
01072
01073
01074 return this->SendCompanyUpdate();
01075 }
01076
01077
01078 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01079 }
01080
01085 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet *p)
01086 {
01087
01088
01089 if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
01090 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01091 }
01092
01093 if (this->incoming_queue.Count() >= _settings_client.network.max_commands_in_queue) {
01094 return this->SendError(NETWORK_ERROR_TOO_MANY_COMMANDS);
01095 }
01096
01097 CommandPacket cp;
01098 const char *err = this->ReceiveCommand(p, &cp);
01099
01100 if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
01101
01102 NetworkClientInfo *ci = this->GetInfo();
01103
01104 if (err != NULL) {
01105 IConsolePrintF(CC_ERROR, "WARNING: %s from client %d (IP: %s).", err, ci->client_id, this->GetClientIP());
01106 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01107 }
01108
01109
01110 if ((GetCommandFlags(cp.cmd) & CMD_SERVER) && ci->client_id != CLIENT_ID_SERVER) {
01111 IConsolePrintF(CC_ERROR, "WARNING: server only command from: client %d (IP: %s), kicking...", ci->client_id, this->GetClientIP());
01112 return this->SendError(NETWORK_ERROR_KICKED);
01113 }
01114
01115 if ((GetCommandFlags(cp.cmd) & CMD_SPECTATOR) == 0 && !Company::IsValidID(cp.company) && ci->client_id != CLIENT_ID_SERVER) {
01116 IConsolePrintF(CC_ERROR, "WARNING: spectator issueing command from client %d (IP: %s), kicking...", ci->client_id, this->GetClientIP());
01117 return this->SendError(NETWORK_ERROR_KICKED);
01118 }
01119
01125 if (!(cp.cmd == CMD_COMPANY_CTRL && cp.p1 == 0 && ci->client_playas == COMPANY_NEW_COMPANY) && ci->client_playas != cp.company) {
01126 IConsolePrintF(CC_ERROR, "WARNING: client %d (IP: %s) tried to execute a command as company %d, kicking...",
01127 ci->client_playas + 1, this->GetClientIP(), cp.company + 1);
01128 return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH);
01129 }
01130
01131 if (cp.cmd == CMD_COMPANY_CTRL) {
01132 if (cp.p1 != 0 || cp.company != COMPANY_SPECTATOR) {
01133 return this->SendError(NETWORK_ERROR_CHEATER);
01134 }
01135
01136
01137 if (Company::GetNumItems() >= _settings_client.network.max_companies) {
01138 NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_CLIENT, ci->client_id, "cannot create new company, server full", CLIENT_ID_SERVER);
01139 return NETWORK_RECV_STATUS_OKAY;
01140 }
01141 }
01142
01143 if (GetCommandFlags(cp.cmd) & CMD_CLIENT_ID) cp.p2 = this->client_id;
01144
01145 this->incoming_queue.Append(&cp);
01146 return NETWORK_RECV_STATUS_OKAY;
01147 }
01148
01149 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p)
01150 {
01151
01152
01153 NetworkClientSocket *new_cs;
01154 char str[100];
01155 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01156 NetworkErrorCode errorno = (NetworkErrorCode)p->Recv_uint8();
01157
01158
01159 if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
01160 return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
01161 }
01162
01163 this->GetClientName(client_name, sizeof(client_name));
01164
01165 StringID strid = GetNetworkErrorMsg(errorno);
01166 GetString(str, strid, lastof(str));
01167
01168 DEBUG(net, 2, "'%s' reported an error and is closing its connection (%s)", client_name, str);
01169
01170 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, strid);
01171
01172 FOR_ALL_CLIENT_SOCKETS(new_cs) {
01173 if (new_cs->status > STATUS_AUTHORIZED) {
01174 new_cs->SendErrorQuit(this->client_id, errorno);
01175 }
01176 }
01177
01178 NetworkAdminClientError(this->client_id, errorno);
01179
01180 return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
01181 }
01182
01183 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet *p)
01184 {
01185
01186
01187 NetworkClientSocket *new_cs;
01188 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01189
01190
01191 if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
01192 return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
01193 }
01194
01195 this->GetClientName(client_name, sizeof(client_name));
01196
01197 NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, STR_NETWORK_MESSAGE_CLIENT_LEAVING);
01198
01199 FOR_ALL_CLIENT_SOCKETS(new_cs) {
01200 if (new_cs->status > STATUS_AUTHORIZED && new_cs != this) {
01201 new_cs->SendQuit(this->client_id);
01202 }
01203 }
01204
01205 NetworkAdminClientQuit(this->client_id);
01206
01207 return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
01208 }
01209
01210 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ACK(Packet *p)
01211 {
01212 if (this->status < STATUS_AUTHORIZED) {
01213
01214 return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
01215 }
01216
01217 uint32 frame = p->Recv_uint32();
01218
01219
01220 if (this->status == STATUS_PRE_ACTIVE) {
01221
01222 if (frame + DAY_TICKS < _frame_counter) return NETWORK_RECV_STATUS_OKAY;
01223
01224
01225 this->status = STATUS_ACTIVE;
01226 this->last_token_frame = _frame_counter;
01227
01228
01229 IConsoleCmdExec("exec scripts/on_server_connect.scr 0");
01230 }
01231
01232
01233 uint8 token = p->Recv_uint8();
01234 if (token == this->last_token) {
01235
01236
01237
01238
01239
01240
01241
01242
01243 this->last_token_frame = _frame_counter;
01244
01245 this->last_token = 0;
01246 }
01247
01248
01249 this->last_frame = frame;
01250
01251 this->last_frame_server = _frame_counter;
01252 return NETWORK_RECV_STATUS_OKAY;
01253 }
01254
01255
01266 void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, const char *msg, ClientID from_id, int64 data, bool from_admin)
01267 {
01268 NetworkClientSocket *cs;
01269 const NetworkClientInfo *ci, *ci_own, *ci_to;
01270
01271 switch (desttype) {
01272 case DESTTYPE_CLIENT:
01273
01274 if ((ClientID)dest == CLIENT_ID_SERVER) {
01275 ci = NetworkClientInfo::GetByClientID(from_id);
01276
01277 if (ci != NULL) {
01278 NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
01279
01280 if (_settings_client.network.server_admin_chat) {
01281 NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
01282 }
01283 }
01284 } else {
01285
01286 FOR_ALL_CLIENT_SOCKETS(cs) {
01287 if (cs->client_id == (ClientID)dest) {
01288 cs->SendChat(action, from_id, false, msg, data);
01289 break;
01290 }
01291 }
01292 }
01293
01294
01295 if (from_id != (ClientID)dest) {
01296 if (from_id == CLIENT_ID_SERVER) {
01297 ci = NetworkClientInfo::GetByClientID(from_id);
01298 ci_to = NetworkClientInfo::GetByClientID((ClientID)dest);
01299 if (ci != NULL && ci_to != NULL) {
01300 NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), true, ci_to->client_name, msg, data);
01301 }
01302 } else {
01303 FOR_ALL_CLIENT_SOCKETS(cs) {
01304 if (cs->client_id == from_id) {
01305 cs->SendChat(action, (ClientID)dest, true, msg, data);
01306 break;
01307 }
01308 }
01309 }
01310 }
01311 break;
01312 case DESTTYPE_TEAM: {
01313
01314 bool show_local = true;
01315
01316 ci_to = NULL;
01317 FOR_ALL_CLIENT_SOCKETS(cs) {
01318 ci = cs->GetInfo();
01319 if (ci != NULL && ci->client_playas == (CompanyID)dest) {
01320 cs->SendChat(action, from_id, false, msg, data);
01321 if (cs->client_id == from_id) show_local = false;
01322 ci_to = ci;
01323 }
01324 }
01325
01326
01327 if (_local_company == (CompanyID)dest && _settings_client.network.server_admin_chat) {
01328 NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
01329 }
01330
01331 ci = NetworkClientInfo::GetByClientID(from_id);
01332 ci_own = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
01333 if (ci != NULL && ci_own != NULL && ci_own->client_playas == dest) {
01334 NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
01335 if (from_id == CLIENT_ID_SERVER) show_local = false;
01336 ci_to = ci_own;
01337 }
01338
01339
01340 if (ci_to == NULL) break;
01341
01342
01343 if (ci != NULL && show_local) {
01344 if (from_id == CLIENT_ID_SERVER) {
01345 char name[NETWORK_NAME_LENGTH];
01346 StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;
01347 SetDParam(0, ci_to->client_playas);
01348 GetString(name, str, lastof(name));
01349 NetworkTextMessage(action, GetDrawStringCompanyColour(ci_own->client_playas), true, name, msg, data);
01350 } else {
01351 FOR_ALL_CLIENT_SOCKETS(cs) {
01352 if (cs->client_id == from_id) {
01353 cs->SendChat(action, ci_to->client_id, true, msg, data);
01354 }
01355 }
01356 }
01357 }
01358 break;
01359 }
01360 default:
01361 DEBUG(net, 0, "[server] received unknown chat destination type %d. Doing broadcast instead", desttype);
01362
01363 case DESTTYPE_BROADCAST:
01364 FOR_ALL_CLIENT_SOCKETS(cs) {
01365 cs->SendChat(action, from_id, false, msg, data);
01366 }
01367
01368 NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
01369
01370 ci = NetworkClientInfo::GetByClientID(from_id);
01371 if (ci != NULL) {
01372 NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
01373 }
01374 break;
01375 }
01376 }
01377
01378 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_CHAT(Packet *p)
01379 {
01380 if (this->status < STATUS_PRE_ACTIVE) {
01381
01382 return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
01383 }
01384
01385 NetworkAction action = (NetworkAction)p->Recv_uint8();
01386 DestType desttype = (DestType)p->Recv_uint8();
01387 int dest = p->Recv_uint32();
01388 char msg[NETWORK_CHAT_LENGTH];
01389
01390 p->Recv_string(msg, NETWORK_CHAT_LENGTH);
01391 int64 data = p->Recv_uint64();
01392
01393 NetworkClientInfo *ci = this->GetInfo();
01394 switch (action) {
01395 case NETWORK_ACTION_GIVE_MONEY:
01396 if (!Company::IsValidID(ci->client_playas)) break;
01397
01398 case NETWORK_ACTION_CHAT:
01399 case NETWORK_ACTION_CHAT_CLIENT:
01400 case NETWORK_ACTION_CHAT_COMPANY:
01401 NetworkServerSendChat(action, desttype, dest, msg, this->client_id, data);
01402 break;
01403 default:
01404 IConsolePrintF(CC_ERROR, "WARNING: invalid chat action from client %d (IP: %s).", ci->client_id, this->GetClientIP());
01405 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01406 }
01407 return NETWORK_RECV_STATUS_OKAY;
01408 }
01409
01410 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_PASSWORD(Packet *p)
01411 {
01412 if (this->status != STATUS_ACTIVE) {
01413
01414 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01415 }
01416
01417 char password[NETWORK_PASSWORD_LENGTH];
01418 const NetworkClientInfo *ci;
01419
01420 p->Recv_string(password, sizeof(password));
01421 ci = this->GetInfo();
01422
01423 NetworkServerSetCompanyPassword(ci->client_playas, password);
01424 return NETWORK_RECV_STATUS_OKAY;
01425 }
01426
01427 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet *p)
01428 {
01429 if (this->status != STATUS_ACTIVE) {
01430
01431 return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01432 }
01433
01434 char client_name[NETWORK_CLIENT_NAME_LENGTH];
01435 NetworkClientInfo *ci;
01436
01437 p->Recv_string(client_name, sizeof(client_name));
01438 ci = this->GetInfo();
01439
01440 if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST;
01441
01442 if (ci != NULL) {
01443
01444 if (NetworkFindName(client_name)) {
01445 NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, client_name);
01446 strecpy(ci->client_name, client_name, lastof(ci->client_name));
01447 NetworkUpdateClientInfo(ci->client_id);
01448 }
01449 }
01450 return NETWORK_RECV_STATUS_OKAY;
01451 }
01452
01453 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_RCON(Packet *p)
01454 {
01455 if (this->status != STATUS_ACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01456
01457 char pass[NETWORK_PASSWORD_LENGTH];
01458 char command[NETWORK_RCONCOMMAND_LENGTH];
01459
01460 if (StrEmpty(_settings_client.network.rcon_password)) return NETWORK_RECV_STATUS_OKAY;
01461
01462 p->Recv_string(pass, sizeof(pass));
01463 p->Recv_string(command, sizeof(command));
01464
01465 if (strcmp(pass, _settings_client.network.rcon_password) != 0) {
01466 DEBUG(net, 0, "[rcon] wrong password from client-id %d", this->client_id);
01467 return NETWORK_RECV_STATUS_OKAY;
01468 }
01469
01470 DEBUG(net, 0, "[rcon] client-id %d executed: '%s'", this->client_id, command);
01471
01472 _redirect_console_to_client = this->client_id;
01473 IConsoleCmdExec(command);
01474 _redirect_console_to_client = INVALID_CLIENT_ID;
01475 return NETWORK_RECV_STATUS_OKAY;
01476 }
01477
01478 NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MOVE(Packet *p)
01479 {
01480 if (this->status != STATUS_ACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
01481
01482 CompanyID company_id = (Owner)p->Recv_uint8();
01483
01484
01485 if (company_id != COMPANY_SPECTATOR && !Company::IsValidHumanID(company_id)) return NETWORK_RECV_STATUS_OKAY;
01486
01487
01488 if (company_id != COMPANY_SPECTATOR && !StrEmpty(_network_company_states[company_id].password)) {
01489
01490 char password[NETWORK_PASSWORD_LENGTH];
01491 p->Recv_string(password, sizeof(password));
01492
01493
01494 if (strcmp(password, _network_company_states[company_id].password) != 0) {
01495 DEBUG(net, 2, "[move] wrong password from client-id #%d for company #%d", this->client_id, company_id + 1);
01496 return NETWORK_RECV_STATUS_OKAY;
01497 }
01498 }
01499
01500
01501 NetworkServerDoMove(this->client_id, company_id);
01502 return NETWORK_RECV_STATUS_OKAY;
01503 }
01504
01512 void NetworkSocketHandler::SendCompanyInformation(Packet *p, const Company *c, const NetworkCompanyStats *stats, uint max_len)
01513 {
01514
01515 char company_name[NETWORK_COMPANY_NAME_LENGTH];
01516 SetDParam(0, c->index);
01517
01518 assert(max_len <= lengthof(company_name));
01519 GetString(company_name, STR_COMPANY_NAME, company_name + max_len - 1);
01520
01521
01522 Money income = 0;
01523 if (_cur_year - 1 == c->inaugurated_year) {
01524
01525 for (uint i = 0; i < lengthof(c->yearly_expenses[2]); i++) {
01526 income -= c->yearly_expenses[2][i];
01527 }
01528 } else {
01529 for (uint i = 0; i < lengthof(c->yearly_expenses[1]); i++) {
01530 income -= c->yearly_expenses[1][i];
01531 }
01532 }
01533
01534
01535 p->Send_uint8 (c->index);
01536 p->Send_string(company_name);
01537 p->Send_uint32(c->inaugurated_year);
01538 p->Send_uint64(c->old_economy[0].company_value);
01539 p->Send_uint64(c->money);
01540 p->Send_uint64(income);
01541 p->Send_uint16(c->old_economy[0].performance_history);
01542
01543
01544 p->Send_bool (!StrEmpty(_network_company_states[c->index].password));
01545
01546 for (uint i = 0; i < NETWORK_VEH_END; i++) {
01547 p->Send_uint16(stats->num_vehicle[i]);
01548 }
01549
01550 for (uint i = 0; i < NETWORK_VEH_END; i++) {
01551 p->Send_uint16(stats->num_station[i]);
01552 }
01553
01554 p->Send_bool(c->is_ai);
01555 }
01556
01561 void NetworkPopulateCompanyStats(NetworkCompanyStats *stats)
01562 {
01563 const Vehicle *v;
01564 const Station *s;
01565
01566 memset(stats, 0, sizeof(*stats) * MAX_COMPANIES);
01567
01568
01569 FOR_ALL_VEHICLES(v) {
01570 if (!Company::IsValidID(v->owner) || !v->IsPrimaryVehicle()) continue;
01571 byte type = 0;
01572 switch (v->type) {
01573 case VEH_TRAIN: type = NETWORK_VEH_TRAIN; break;
01574 case VEH_ROAD: type = RoadVehicle::From(v)->IsBus() ? NETWORK_VEH_BUS : NETWORK_VEH_LORRY; break;
01575 case VEH_AIRCRAFT: type = NETWORK_VEH_PLANE; break;
01576 case VEH_SHIP: type = NETWORK_VEH_SHIP; break;
01577 default: continue;
01578 }
01579 stats[v->owner].num_vehicle[type]++;
01580 }
01581
01582
01583 FOR_ALL_STATIONS(s) {
01584 if (Company::IsValidID(s->owner)) {
01585 NetworkCompanyStats *npi = &stats[s->owner];
01586
01587 if (s->facilities & FACIL_TRAIN) npi->num_station[NETWORK_VEH_TRAIN]++;
01588 if (s->facilities & FACIL_TRUCK_STOP) npi->num_station[NETWORK_VEH_LORRY]++;
01589 if (s->facilities & FACIL_BUS_STOP) npi->num_station[NETWORK_VEH_BUS]++;
01590 if (s->facilities & FACIL_AIRPORT) npi->num_station[NETWORK_VEH_PLANE]++;
01591 if (s->facilities & FACIL_DOCK) npi->num_station[NETWORK_VEH_SHIP]++;
01592 }
01593 }
01594 }
01595
01600 void NetworkUpdateClientInfo(ClientID client_id)
01601 {
01602 NetworkClientSocket *cs;
01603 NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
01604
01605 if (ci == NULL) return;
01606
01607 DEBUG(desync, 1, "client: %08x; %02x; %02x; %04x", _date, _date_fract, (int)ci->client_playas, client_id);
01608
01609 FOR_ALL_CLIENT_SOCKETS(cs) {
01610 cs->SendClientInfo(ci);
01611 }
01612
01613 NetworkAdminClientUpdate(ci);
01614 }
01615
01617 static void NetworkCheckRestartMap()
01618 {
01619 if (_settings_client.network.restart_game_year != 0 && _cur_year >= _settings_client.network.restart_game_year) {
01620 DEBUG(net, 0, "Auto-restarting map. Year %d reached", _cur_year);
01621
01622 StartNewGameWithoutGUI(GENERATE_NEW_SEED);
01623 }
01624 }
01625
01632 static void NetworkAutoCleanCompanies()
01633 {
01634 const NetworkClientInfo *ci;
01635 const Company *c;
01636 bool clients_in_company[MAX_COMPANIES];
01637 int vehicles_in_company[MAX_COMPANIES];
01638
01639 if (!_settings_client.network.autoclean_companies) return;
01640
01641 memset(clients_in_company, 0, sizeof(clients_in_company));
01642
01643
01644 FOR_ALL_CLIENT_INFOS(ci) {
01645 if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true;
01646 }
01647
01648 if (!_network_dedicated) {
01649 ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
01650 if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true;
01651 }
01652
01653 if (_settings_client.network.autoclean_novehicles != 0) {
01654 memset(vehicles_in_company, 0, sizeof(vehicles_in_company));
01655
01656 const Vehicle *v;
01657 FOR_ALL_VEHICLES(v) {
01658 if (!Company::IsValidID(v->owner) || !v->IsPrimaryVehicle()) continue;
01659 vehicles_in_company[v->owner]++;
01660 }
01661 }
01662
01663
01664 FOR_ALL_COMPANIES(c) {
01665
01666 if (c->is_ai) continue;
01667
01668 if (!clients_in_company[c->index]) {
01669
01670 _network_company_states[c->index].months_empty++;
01671
01672
01673 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)) {
01674
01675 DoCommandP(0, 2 | c->index << 16, CRR_AUTOCLEAN, CMD_COMPANY_CTRL);
01676 IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no password", c->index + 1);
01677 }
01678
01679 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)) {
01680
01681 _network_company_states[c->index].password[0] = '\0';
01682 IConsolePrintF(CC_DEFAULT, "Auto-removed protection from company #%d", c->index + 1);
01683 _network_company_states[c->index].months_empty = 0;
01684 NetworkServerUpdateCompanyPassworded(c->index, false);
01685 }
01686
01687 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) {
01688
01689 DoCommandP(0, 2 | c->index << 16, CRR_AUTOCLEAN, CMD_COMPANY_CTRL);
01690 IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no vehicles", c->index + 1);
01691 }
01692 } else {
01693
01694 _network_company_states[c->index].months_empty = 0;
01695 }
01696 }
01697 }
01698
01704 bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH])
01705 {
01706 bool found_name = false;
01707 uint number = 0;
01708 char original_name[NETWORK_CLIENT_NAME_LENGTH];
01709
01710
01711 ttd_strlcpy(original_name, new_name, NETWORK_CLIENT_NAME_LENGTH);
01712
01713 while (!found_name) {
01714 const NetworkClientInfo *ci;
01715
01716 found_name = true;
01717 FOR_ALL_CLIENT_INFOS(ci) {
01718 if (strcmp(ci->client_name, new_name) == 0) {
01719
01720 found_name = false;
01721 break;
01722 }
01723 }
01724
01725 ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
01726 if (ci != NULL) {
01727 if (strcmp(ci->client_name, new_name) == 0) found_name = false;
01728 }
01729
01730 if (!found_name) {
01731
01732
01733
01734 if (number++ > MAX_CLIENTS) break;
01735 snprintf(new_name, NETWORK_CLIENT_NAME_LENGTH, "%s #%d", original_name, number);
01736 }
01737 }
01738
01739 return found_name;
01740 }
01741
01748 bool NetworkServerChangeClientName(ClientID client_id, const char *new_name)
01749 {
01750 NetworkClientInfo *ci;
01751
01752 FOR_ALL_CLIENT_INFOS(ci) {
01753 if (strcmp(ci->client_name, new_name) == 0) return false;
01754 }
01755
01756 ci = NetworkClientInfo::GetByClientID(client_id);
01757 if (ci == NULL) return false;
01758
01759 NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, true, ci->client_name, new_name);
01760
01761 strecpy(ci->client_name, new_name, lastof(ci->client_name));
01762
01763 NetworkUpdateClientInfo(client_id);
01764 return true;
01765 }
01766
01773 void NetworkServerSetCompanyPassword(CompanyID company_id, const char *password, bool already_hashed)
01774 {
01775 if (!Company::IsValidHumanID(company_id)) return;
01776
01777 if (!already_hashed) {
01778 password = GenerateCompanyPasswordHash(password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed);
01779 }
01780
01781 strecpy(_network_company_states[company_id].password, password, lastof(_network_company_states[company_id].password));
01782 NetworkServerUpdateCompanyPassworded(company_id, !StrEmpty(_network_company_states[company_id].password));
01783 }
01784
01789 static void NetworkHandleCommandQueue(NetworkClientSocket *cs)
01790 {
01791 CommandPacket *cp;
01792 while ((cp = cs->outgoing_queue.Pop()) != NULL) {
01793 cs->SendCommand(cp);
01794 free(cp);
01795 }
01796 }
01797
01802 void NetworkServer_Tick(bool send_frame)
01803 {
01804 NetworkClientSocket *cs;
01805 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
01806 bool send_sync = false;
01807 #endif
01808
01809 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
01810 if (_frame_counter >= _last_sync_frame + _settings_client.network.sync_freq) {
01811 _last_sync_frame = _frame_counter;
01812 send_sync = true;
01813 }
01814 #endif
01815
01816
01817
01818 FOR_ALL_CLIENT_SOCKETS(cs) {
01819
01820
01821 cs->receive_limit = min(cs->receive_limit + _settings_client.network.bytes_per_frame,
01822 _settings_client.network.bytes_per_frame_burst);
01823
01824
01825 uint lag = NetworkCalculateLag(cs);
01826 switch (cs->status) {
01827 case NetworkClientSocket::STATUS_ACTIVE:
01828 if (lag > _settings_client.network.max_lag_time) {
01829
01830 IConsolePrintF(CC_ERROR, cs->last_packet + lag * MILLISECONDS_PER_TICK > _realtime_tick ?
01831
01832 "Client #%d is dropped because the client's game state is more than %d ticks behind" :
01833
01834 "Client #%d is dropped because the client did not respond for more than %d ticks",
01835 cs->client_id, lag);
01836 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
01837 continue;
01838 }
01839
01840
01841
01842
01843
01844
01845 if (lag > (uint)DAY_TICKS && cs->lag_test == 0 && cs->last_packet + 2000 > _realtime_tick) {
01846 IConsolePrintF(CC_WARNING, "[%d] Client #%d is slow, try increasing [network.]frame_freq to a higher value!", _frame_counter, cs->client_id);
01847 cs->lag_test = 1;
01848 }
01849
01850 if (cs->last_frame_server - cs->last_token_frame >= _settings_client.network.max_lag_time) {
01851
01852 IConsolePrintF(CC_ERROR, "Client #%d is dropped because it fails to send valid acks", cs->client_id);
01853 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
01854 continue;
01855 }
01856 break;
01857
01858 case NetworkClientSocket::STATUS_INACTIVE:
01859 case NetworkClientSocket::STATUS_NEWGRFS_CHECK:
01860 case NetworkClientSocket::STATUS_AUTHORIZED:
01861
01862
01863 if (lag > _settings_client.network.max_init_time) {
01864 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);
01865 cs->SendError(NETWORK_ERROR_TIMEOUT_COMPUTER);
01866 continue;
01867 }
01868 break;
01869
01870 case NetworkClientSocket::STATUS_MAP:
01871
01872 if (lag > _settings_client.network.max_download_time) {
01873 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);
01874 cs->SendError(NETWORK_ERROR_TIMEOUT_MAP);
01875 continue;
01876 }
01877 break;
01878
01879 case NetworkClientSocket::STATUS_DONE_MAP:
01880 case NetworkClientSocket::STATUS_PRE_ACTIVE:
01881
01882 if (lag > _settings_client.network.max_join_time) {
01883 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);
01884 cs->SendError(NETWORK_ERROR_TIMEOUT_JOIN);
01885 continue;
01886 }
01887 break;
01888
01889 case NetworkClientSocket::STATUS_AUTH_GAME:
01890 case NetworkClientSocket::STATUS_AUTH_COMPANY:
01891
01892 if (lag > _settings_client.network.max_password_time) {
01893 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);
01894 cs->SendError(NETWORK_ERROR_TIMEOUT_PASSWORD);
01895 continue;
01896 }
01897 break;
01898
01899 case NetworkClientSocket::STATUS_MAP_WAIT:
01900
01901
01902 break;
01903
01904 case NetworkClientSocket::STATUS_END:
01905
01906 NOT_REACHED();
01907 }
01908
01909 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) {
01910
01911 NetworkHandleCommandQueue(cs);
01912
01913
01914 if (send_frame) cs->SendFrame();
01915
01916 #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME
01917
01918 if (send_sync) cs->SendSync();
01919 #endif
01920 }
01921 }
01922
01923
01924 NetworkUDPAdvertise();
01925 }
01926
01928 void NetworkServerYearlyLoop()
01929 {
01930 NetworkCheckRestartMap();
01931 NetworkAdminUpdate(ADMIN_FREQUENCY_ANUALLY);
01932 }
01933
01935 void NetworkServerMonthlyLoop()
01936 {
01937 NetworkAutoCleanCompanies();
01938 NetworkAdminUpdate(ADMIN_FREQUENCY_MONTHLY);
01939 if ((_cur_month % 3) == 0) NetworkAdminUpdate(ADMIN_FREQUENCY_QUARTERLY);
01940 }
01941
01943 void NetworkServerDailyLoop()
01944 {
01945 NetworkAdminUpdate(ADMIN_FREQUENCY_DAILY);
01946 if ((_date % 7) == 3) NetworkAdminUpdate(ADMIN_FREQUENCY_WEEKLY);
01947 }
01948
01953 const char *ServerNetworkGameSocketHandler::GetClientIP()
01954 {
01955 return this->client_address.GetHostname();
01956 }
01957
01959 void NetworkServerShowStatusToConsole()
01960 {
01961 static const char * const stat_str[] = {
01962 "inactive",
01963 "checking NewGRFs",
01964 "authorizing (server password)",
01965 "authorizing (company password)",
01966 "authorized",
01967 "waiting",
01968 "loading map",
01969 "map done",
01970 "ready",
01971 "active"
01972 };
01973 assert_compile(lengthof(stat_str) == NetworkClientSocket::STATUS_END);
01974
01975 NetworkClientSocket *cs;
01976 FOR_ALL_CLIENT_SOCKETS(cs) {
01977 NetworkClientInfo *ci = cs->GetInfo();
01978 if (ci == NULL) continue;
01979 uint lag = NetworkCalculateLag(cs);
01980 const char *status;
01981
01982 status = (cs->status < (ptrdiff_t)lengthof(stat_str) ? stat_str[cs->status] : "unknown");
01983 IConsolePrintF(CC_INFO, "Client #%1d name: '%s' status: '%s' frame-lag: %3d company: %1d IP: %s",
01984 cs->client_id, ci->client_name, status, lag,
01985 ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0),
01986 cs->GetClientIP());
01987 }
01988 }
01989
01993 void NetworkServerSendConfigUpdate()
01994 {
01995 NetworkClientSocket *cs;
01996
01997 FOR_ALL_CLIENT_SOCKETS(cs) {
01998 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendConfigUpdate();
01999 }
02000 }
02001
02007 void NetworkServerUpdateCompanyPassworded(CompanyID company_id, bool passworded)
02008 {
02009 if (NetworkCompanyIsPassworded(company_id) == passworded) return;
02010
02011 SB(_network_company_passworded, company_id, 1, !!passworded);
02012 SetWindowClassesDirty(WC_COMPANY);
02013
02014 NetworkClientSocket *cs;
02015 FOR_ALL_CLIENT_SOCKETS(cs) {
02016 if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendCompanyUpdate();
02017 }
02018
02019 NetworkAdminCompanyUpdate(Company::GetIfValid(company_id));
02020 }
02021
02028 void NetworkServerDoMove(ClientID client_id, CompanyID company_id)
02029 {
02030
02031 if (client_id == CLIENT_ID_SERVER && _network_dedicated) return;
02032
02033 NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
02034
02035
02036 if (ci->client_playas == company_id) return;
02037
02038 ci->client_playas = company_id;
02039
02040 if (client_id == CLIENT_ID_SERVER) {
02041 SetLocalCompany(company_id);
02042 } else {
02043 NetworkClientSocket *cs = NetworkClientSocket::GetByClientID(client_id);
02044
02045 if (cs->status < NetworkClientSocket::STATUS_AUTHORIZED) return;
02046 cs->SendMove(client_id, company_id);
02047 }
02048
02049
02050 NetworkUpdateClientInfo(client_id);
02051
02052 NetworkAction action = (company_id == COMPANY_SPECTATOR) ? NETWORK_ACTION_COMPANY_SPECTATOR : NETWORK_ACTION_COMPANY_JOIN;
02053 NetworkServerSendChat(action, DESTTYPE_BROADCAST, 0, "", client_id, company_id + 1);
02054 }
02055
02062 void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const char *string)
02063 {
02064 NetworkClientSocket::GetByClientID(client_id)->SendRConResult(colour_code, string);
02065 }
02066
02071 void NetworkServerKickClient(ClientID client_id)
02072 {
02073 if (client_id == CLIENT_ID_SERVER) return;
02074 NetworkClientSocket::GetByClientID(client_id)->SendError(NETWORK_ERROR_KICKED);
02075 }
02076
02082 uint NetworkServerKickOrBanIP(ClientID client_id, bool ban)
02083 {
02084 return NetworkServerKickOrBanIP(NetworkClientSocket::GetByClientID(client_id)->GetClientIP(), ban);
02085 }
02086
02092 uint NetworkServerKickOrBanIP(const char *ip, bool ban)
02093 {
02094
02095 if (ban) {
02096 bool contains = false;
02097 for (char **iter = _network_ban_list.Begin(); iter != _network_ban_list.End(); iter++) {
02098 if (strcmp(*iter, ip) == 0) {
02099 contains = true;
02100 break;
02101 }
02102 }
02103 if (!contains) *_network_ban_list.Append() = strdup(ip);
02104 }
02105
02106 uint n = 0;
02107
02108
02109 NetworkClientSocket *cs;
02110 FOR_ALL_CLIENT_SOCKETS(cs) {
02111 if (cs->client_id == CLIENT_ID_SERVER) continue;
02112 if (cs->client_address.IsInNetmask(const_cast<char *>(ip))) {
02113 NetworkServerKickClient(cs->client_id);
02114 n++;
02115 }
02116 }
02117
02118 return n;
02119 }
02120
02126 bool NetworkCompanyHasClients(CompanyID company)
02127 {
02128 const NetworkClientInfo *ci;
02129 FOR_ALL_CLIENT_INFOS(ci) {
02130 if (ci->client_playas == company) return true;
02131 }
02132 return false;
02133 }
02134
02135
02141 void ServerNetworkGameSocketHandler::GetClientName(char *client_name, size_t size) const
02142 {
02143 const NetworkClientInfo *ci = this->GetInfo();
02144
02145 if (ci == NULL || StrEmpty(ci->client_name)) {
02146 snprintf(client_name, size, "Client #%4d", this->client_id);
02147 } else {
02148 ttd_strlcpy(client_name, ci->client_name, size);
02149 }
02150 }
02151
02155 void NetworkPrintClients()
02156 {
02157 NetworkClientInfo *ci;
02158 FOR_ALL_CLIENT_INFOS(ci) {
02159 if (_network_server) {
02160 IConsolePrintF(CC_INFO, "Client #%1d name: '%s' company: %1d IP: %s",
02161 ci->client_id,
02162 ci->client_name,
02163 ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0),
02164 ci->client_id == CLIENT_ID_SERVER ? "server" : NetworkClientSocket::GetByClientID(ci->client_id)->GetClientIP());
02165 } else {
02166 IConsolePrintF(CC_INFO, "Client #%1d name: '%s' company: %1d",
02167 ci->client_id,
02168 ci->client_name,
02169 ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0));
02170 }
02171 }
02172 }
02173
02179 void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci)
02180 {
02181 assert(c != NULL);
02182
02183 if (!_network_server) return;
02184
02185 _network_company_states[c->index].months_empty = 0;
02186 _network_company_states[c->index].password[0] = '\0';
02187 NetworkServerUpdateCompanyPassworded(c->index, false);
02188
02189 if (ci != NULL) {
02190
02191 ci->client_playas = c->index;
02192 NetworkUpdateClientInfo(ci->client_id);
02193 NetworkSendCommand(0, 0, 0, CMD_RENAME_PRESIDENT, NULL, ci->client_name, c->index);
02194 }
02195
02196
02197 NetworkAdminCompanyInfo(c, true);
02198
02199 if (ci != NULL) {
02200
02201
02202
02203 NetworkServerSendChat(NETWORK_ACTION_COMPANY_NEW, DESTTYPE_BROADCAST, 0, "", ci->client_id, c->index + 1);
02204 }
02205 }
02206
02207 #endif