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